summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/in6_gif.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6/in6_gif.c')
-rw-r--r--sys/netinet6/in6_gif.c73
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;
}
OpenPOWER on IntegriCloud