Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet6/ip6_input.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet6/ip6_input.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.98.2.5 retrieving revision 1.113.8.2 diff -u -p -r1.98.2.5 -r1.113.8.2 --- src/sys/netinet6/ip6_input.c 2007/08/20 21:28:05 1.98.2.5 +++ src/sys/netinet6/ip6_input.c 2008/03/24 07:16:24 1.113.8.2 @@ -1,4 +1,4 @@ -/* $NetBSD: ip6_input.c,v 1.98.2.5 2007/08/20 21:28:05 ad Exp $ */ +/* $NetBSD: ip6_input.c,v 1.113.8.2 2008/03/24 07:16:24 keiichi Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -62,7 +62,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.98.2.5 2007/08/20 21:28:05 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.113.8.2 2008/03/24 07:16:24 keiichi Exp $"); #include "opt_inet.h" #include "opt_inet6.h" @@ -148,18 +148,18 @@ struct pfil_head inet6_pfil_hook; struct ip6stat ip6stat; -static void ip6_init2 __P((void *)); -static struct m_tag *ip6_setdstifaddr __P((struct mbuf *, struct in6_ifaddr *)); +static void ip6_init2(void *); +static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *); -static int ip6_hopopts_input __P((u_int32_t *, u_int32_t *, struct mbuf **, int *)); -static struct mbuf *ip6_pullexthdr __P((struct mbuf *, size_t, int)); +static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *); +static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); /* * IP6 initialization: fill in IP6 protocol switch table. * All protocols not implemented in kernel go to raw IP6 protocol handler. */ void -ip6_init() +ip6_init(void) { const struct ip6protosw *pr; int i; @@ -217,7 +217,7 @@ ip6_init2(void *dummy) * IP6 input interrupt handling. Just pass the packet to ip6_input. */ void -ip6intr() +ip6intr(void) { int s; struct mbuf *m; @@ -512,10 +512,38 @@ ip6_input(struct mbuf *m) */ IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &rt6_getkey(rt)->sin6_addr) && #endif - rt->rt_ifp->if_type == IFT_LOOP) { +#ifdef MOBILE_IPV6 + ((rt->rt_flags & RTF_ANNOUNCE) || + rt->rt_ifp->if_type == IFT_LOOP) +#else + rt->rt_ifp->if_type == IFT_LOOP +#endif /* MOBILE_IPV6 */ + ) { struct in6_ifaddr *ia6 = (struct in6_ifaddr *)rt->rt_ifa; if (ia6->ia6_flags & IN6_IFF_ANYCAST) m->m_flags |= M_ANYCAST6; +#ifdef MOBILE_IPV6 + /* check unicast NS */ + if ((rtcache_validate(&ip6_forward_rt)->rt_flags & RTF_ANNOUNCE) != 0) { + /* This route shows proxy nd. thus the packet was + * captured. this packet should be tunneled to + * actual coa with tunneling unless this is NS. + */ + int nh, loff; + struct icmp6_hdr *icp; + loff = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nh); + if (loff < 0 || nh != IPPROTO_ICMPV6) + goto mip6_forwarding; + IP6_EXTHDR_GET(icp, struct icmp6_hdr *, m, loff, + sizeof(*icp)); + if (icp == NULL) { + icmp6stat.icp6s_tooshort++; + return; + } + if (icp->icmp6_type != ND_NEIGHBOR_SOLICIT) + goto mip6_forwarding; + } +#endif /* MOBILE_IPV6 */ /* * packets to a tentative, duplicated, or somehow invalid * address must not be accepted. @@ -536,6 +564,10 @@ ip6_input(struct mbuf *m) } } +#ifdef MOBILE_IPV6 + mip6_forwarding: +#endif /* MOBILE_IPV6 */ + /* * FAITH (Firewall Aided Internet Translator) */ @@ -559,7 +591,7 @@ ip6_input(struct mbuf *m) * working right. */ struct ifaddr *ifa; - TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrlist, ifa_list) { + IFADDR_FOREACH(ifa, m->m_pkthdr.rcvif) { if (ifa->ifa_addr == NULL) continue; /* just for safety */ if (ifa->ifa_addr->sa_family != AF_INET6) @@ -590,18 +622,16 @@ ip6_input(struct mbuf *m) * as our interface address (e.g. multicast addresses, addresses * within FAITH prefixes and such). */ - if (deliverifp && !ip6_getdstifaddr(m)) { + if (deliverifp && ip6_getdstifaddr(m) == NULL) { struct in6_ifaddr *ia6; ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst); - if (ia6) { - if (!ip6_setdstifaddr(m, ia6)) { - /* - * XXX maybe we should drop the packet here, - * as we could not provide enough information - * to the upper layers. - */ - } + if (ia6 != NULL && ip6_setdstifaddr(m, ia6) == NULL) { + /* + * XXX maybe we should drop the packet here, + * as we could not provide enough information + * to the upper layers. + */ } } @@ -810,7 +840,6 @@ ip6_input(struct mbuf *m) /* XXX error stat??? */ error = EINVAL; DPRINTF(("ip6_input: no SP, packet discarded\n"));/*XXX*/ - goto bad; } splx(s); if (error) @@ -818,6 +847,8 @@ ip6_input(struct mbuf *m) } #endif /* FAST_IPSEC */ + if (dest6_mip6_hao(m, off, nxt) < 0) + goto bad; nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); } @@ -830,24 +861,30 @@ ip6_input(struct mbuf *m) * set/grab in6_ifaddr correspond to IPv6 destination address. */ static struct m_tag * -ip6_setdstifaddr(struct mbuf *m, struct in6_ifaddr *ia6) +ip6_setdstifaddr(struct mbuf *m, const struct in6_ifaddr *ia) { struct m_tag *mtag; mtag = ip6_addaux(m); - if (mtag) - ((struct ip6aux *)(mtag + 1))->ip6a_dstia6 = ia6; + if (mtag != NULL) { + struct ip6aux *ip6a; + + ip6a = (struct ip6aux *)(mtag + 1); + in6_setscope(&ip6a->ip6a_src, ia->ia_ifp, &ip6a->ip6a_src_scope_id); + ip6a->ip6a_src = ia->ia_addr.sin6_addr; + ip6a->ip6a_src_flags = ia->ia6_flags; + } return mtag; /* NULL if failed to set */ } -struct in6_ifaddr * +const struct ip6aux * ip6_getdstifaddr(struct mbuf *m) { struct m_tag *mtag; mtag = ip6_findaux(m); - if (mtag) - return ((struct ip6aux *)(mtag + 1))->ip6a_dstia6; + if (mtag != NULL) + return (struct ip6aux *)(mtag + 1); else return NULL; }