diff options
Diffstat (limited to 'sys/netinet6/in6_gif.c')
-rw-r--r-- | sys/netinet6/in6_gif.c | 73 |
1 files changed, 31 insertions, 42 deletions
diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c index c8c1450..57bec0e 100644 --- a/sys/netinet6/in6_gif.c +++ b/sys/netinet6/in6_gif.c @@ -1,5 +1,5 @@ /* $FreeBSD$ */ -/* $KAME: in6_gif.c,v 1.37 2000/06/17 20:34:25 itojun Exp $ */ +/* $KAME: in6_gif.c,v 1.49 2001/05/14 14:02:17 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -30,10 +30,6 @@ * SUCH DAMAGE. */ -/* - * in6_gif.c - */ - #include "opt_inet.h" #include "opt_inet6.h" @@ -43,6 +39,10 @@ #include <sys/sockio.h> #include <sys/mbuf.h> #include <sys/errno.h> +#include <sys/queue.h> +#include <sys/syslog.h> + +#include <sys/malloc.h> #include <net/if.h> #include <net/route.h> @@ -148,34 +148,19 @@ in6_gif_output(ifp, family, m, rt) ip6->ip6_nxt = proto; ip6->ip6_hlim = ip6_gif_hlim; ip6->ip6_src = sin6_src->sin6_addr; - if (ifp->if_flags & IFF_LINK0) { - /* multi-destination mode */ - if (!IN6_IS_ADDR_UNSPECIFIED(&sin6_dst->sin6_addr)) - ip6->ip6_dst = sin6_dst->sin6_addr; - else if (rt) { - if (family != AF_INET6) { - m_freem(m); - return EINVAL; /*XXX*/ - } - ip6->ip6_dst = ((struct sockaddr_in6 *)(rt->rt_gateway))->sin6_addr; - } else { - m_freem(m); - return ENETUNREACH; - } - } else { - /* bidirectional configured tunnel mode */ - if (!IN6_IS_ADDR_UNSPECIFIED(&sin6_dst->sin6_addr)) - ip6->ip6_dst = sin6_dst->sin6_addr; - else { - m_freem(m); - return ENETUNREACH; - } + /* bidirectional configured tunnel mode */ + if (!IN6_IS_ADDR_UNSPECIFIED(&sin6_dst->sin6_addr)) + ip6->ip6_dst = sin6_dst->sin6_addr; + else { + m_freem(m); + return ENETUNREACH; } - if (ifp->if_flags & IFF_LINK1) { - otos = 0; + if (ifp->if_flags & IFF_LINK1) ip_ecn_ingress(ECN_ALLOWED, &otos, &itos); - ip6->ip6_flow |= htonl((u_int32_t)otos << 20); - } + else + ip_ecn_ingress(ECN_NOCARE, &otos, &itos); + ip6->ip6_flow &= ~ntohl(0xff00000); + ip6->ip6_flow |= htonl((u_int32_t)otos << 20); if (dst->sin6_family != sin6_dst->sin6_family || !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &sin6_dst->sin6_addr)) { @@ -262,6 +247,8 @@ int in6_gif_input(mp, offp, proto) ip = mtod(m, struct ip *); if (gifp->if_flags & IFF_LINK1) ip_ecn_egress(ECN_ALLOWED, &otos8, &ip->ip_tos); + else + ip_ecn_egress(ECN_NOCARE, &otos8, &ip->ip_tos); break; } #endif /* INET */ @@ -278,6 +265,8 @@ int in6_gif_input(mp, offp, proto) ip6 = mtod(m, struct ip6_hdr *); if (gifp->if_flags & IFF_LINK1) ip6_ecn_egress(ECN_ALLOWED, &otos, &ip6->ip6_flow); + else + ip6_ecn_egress(ECN_NOCARE, &otos, &ip6->ip6_flow); break; } #endif @@ -321,17 +310,14 @@ gif_encapcheck6(m, off, proto, arg) addrmatch |= 1; if (IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6.ip6_src)) addrmatch |= 2; - else if ((sc->gif_if.if_flags & IFF_LINK0) != 0 && - IN6_IS_ADDR_UNSPECIFIED(&dst->sin6_addr)) { - addrmatch |= 2; /* we accept any source */ - } if (addrmatch != 3) return 0; /* martian filters on outer source - done in ip6_input */ /* ingress filters on outer source */ - if ((m->m_flags & M_PKTHDR) != 0 && m->m_pkthdr.rcvif) { + if ((sc->gif_if.if_flags & IFF_LINK2) == 0 && + (m->m_flags & M_PKTHDR) != 0 && m->m_pkthdr.rcvif) { struct sockaddr_in6 sin6; struct rtentry *rt; @@ -341,15 +327,18 @@ gif_encapcheck6(m, off, proto, arg) sin6.sin6_addr = ip6.ip6_src; /* XXX scopeid */ rt = rtalloc1((struct sockaddr *)&sin6, 0, 0UL); - if (!rt) - return 0; - if (rt->rt_ifp != m->m_pkthdr.rcvif) { - rtfree(rt); + if (!rt || rt->rt_ifp != m->m_pkthdr.rcvif) { +#if 0 + log(LOG_WARNING, "%s: packet from %s dropped " + "due to ingress filter\n", if_name(&sc->gif_if), + ip6_sprintf(&sin6.sin6_addr)); +#endif + if (rt) + rtfree(rt); return 0; } rtfree(rt); } - /* prioritize: IFF_LINK0 mode is less preferred */ - return (sc->gif_if.if_flags & IFF_LINK0) ? 128 : 128 * 2; + return 128 * 2; } |