diff options
Diffstat (limited to 'freebsd/sys/netinet6/icmp6.c')
-rw-r--r-- | freebsd/sys/netinet6/icmp6.c | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/freebsd/sys/netinet6/icmp6.c b/freebsd/sys/netinet6/icmp6.c index 54758cd4..f73dee04 100644 --- a/freebsd/sys/netinet6/icmp6.c +++ b/freebsd/sys/netinet6/icmp6.c @@ -361,7 +361,7 @@ icmp6_error(struct mbuf *m, int type, int code, int param) m_adj(m, ICMPV6_PLD_MAXLEN - m->m_pkthdr.len); preplen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr); - M_PREPEND(m, preplen, M_DONTWAIT); + M_PREPEND(m, preplen, M_DONTWAIT); /* FIB is also copied over. */ if (m && m->m_len < preplen) m = m_pullup(m, preplen); if (m == NULL) { @@ -583,7 +583,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) MGETHDR(n, M_DONTWAIT, n0->m_type); n0len = n0->m_pkthdr.len; /* save for use below */ if (n) - M_MOVE_PKTHDR(n, n0); + M_MOVE_PKTHDR(n, n0); /* FIB copied. */ if (n && maxlen >= MHLEN) { MCLGET(n, M_DONTWAIT); if ((n->m_flags & M_EXT) == 0) { @@ -1429,7 +1429,7 @@ ni6_input(struct mbuf *m, int off) m_freem(m); return (NULL); } - M_MOVE_PKTHDR(n, m); /* just for recvif */ + M_MOVE_PKTHDR(n, m); /* just for recvif and FIB */ if (replylen > MHLEN) { if (replylen > MCLBYTES) { /* @@ -1711,9 +1711,9 @@ ni6_addrs(struct icmp6_nodeinfo *ni6, struct mbuf *m, struct ifnet **ifpp, } IFNET_RLOCK_NOSLEEP(); - for (ifp = TAILQ_FIRST(&V_ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { + TAILQ_FOREACH(ifp, &V_ifnet, if_list) { addrsofif = 0; - IF_ADDR_LOCK(ifp); + IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { if (ifa->ifa_addr->sa_family != AF_INET6) continue; @@ -1764,7 +1764,7 @@ ni6_addrs(struct icmp6_nodeinfo *ni6, struct mbuf *m, struct ifnet **ifpp, } addrsofif++; /* count the address */ } - IF_ADDR_UNLOCK(ifp); + IF_ADDR_RUNLOCK(ifp); if (iffound) { *ifpp = ifp; IFNET_RUNLOCK_NOSLEEP(); @@ -1782,7 +1782,7 @@ static int ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6, struct ifnet *ifp0, int resid) { - struct ifnet *ifp = ifp0 ? ifp0 : TAILQ_FIRST(&V_ifnet); + struct ifnet *ifp; struct in6_ifaddr *ifa6; struct ifaddr *ifa; struct ifnet *ifp_dep = NULL; @@ -1795,10 +1795,11 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6, return (0); /* needless to copy */ IFNET_RLOCK_NOSLEEP(); + ifp = ifp0 ? ifp0 : TAILQ_FIRST(&V_ifnet); again: for (; ifp; ifp = TAILQ_NEXT(ifp, if_list)) { - IF_ADDR_LOCK(ifp); + IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { if (ifa->ifa_addr->sa_family != AF_INET6) continue; @@ -1853,7 +1854,7 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6, /* now we can copy the address */ if (resid < sizeof(struct in6_addr) + sizeof(u_int32_t)) { - IF_ADDR_UNLOCK(ifp); + IF_ADDR_RUNLOCK(ifp); /* * We give up much more copy. * Set the truncate flag and return. @@ -1900,7 +1901,7 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6, resid -= (sizeof(struct in6_addr) + sizeof(u_int32_t)); copied += (sizeof(struct in6_addr) + sizeof(u_int32_t)); } - IF_ADDR_UNLOCK(ifp); + IF_ADDR_RUNLOCK(ifp); if (ifp0) /* we need search only on the specified IF */ break; } @@ -2175,10 +2176,6 @@ icmp6_reflect(struct mbuf *m, size_t off) } } - if ((srcp != NULL) && - (in6_addrscope(srcp) != in6_addrscope(&ip6->ip6_src))) - srcp = NULL; - if (srcp == NULL) { int e; struct sockaddr_in6 sin6; @@ -2284,8 +2281,6 @@ icmp6_redirect_input(struct mbuf *m, int off) int icmp6len = ntohs(ip6->ip6_plen); char *lladdr = NULL; int lladdrlen = 0; - u_char *redirhdr = NULL; - int redirhdrlen = 0; struct rtentry *rt = NULL; int is_router; int is_onlink; @@ -2351,7 +2346,7 @@ icmp6_redirect_input(struct mbuf *m, int off) sin6.sin6_family = AF_INET6; sin6.sin6_len = sizeof(struct sockaddr_in6); bcopy(&reddst6, &sin6.sin6_addr, sizeof(reddst6)); - rt = rtalloc1((struct sockaddr *)&sin6, 0, 0UL); + rt = in6_rtalloc1((struct sockaddr *)&sin6, 0, 0UL, RT_DEFAULT_FIB); if (rt) { if (rt->rt_gateway == NULL || rt->rt_gateway->sa_family != AF_INET6) { @@ -2421,11 +2416,6 @@ icmp6_redirect_input(struct mbuf *m, int off) lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3; } - if (ndopts.nd_opts_rh) { - redirhdrlen = ndopts.nd_opts_rh->nd_opt_rh_len; - redirhdr = (u_char *)(ndopts.nd_opts_rh + 1); /* xxx */ - } - if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { nd6log((LOG_INFO, "icmp6_redirect_input: lladdrlen mismatch for %s " @@ -2445,6 +2435,7 @@ icmp6_redirect_input(struct mbuf *m, int off) struct sockaddr_in6 sdst; struct sockaddr_in6 sgw; struct sockaddr_in6 ssrc; + u_int fibnum; bzero(&sdst, sizeof(sdst)); bzero(&sgw, sizeof(sgw)); @@ -2455,9 +2446,11 @@ icmp6_redirect_input(struct mbuf *m, int off) bcopy(&redtgt6, &sgw.sin6_addr, sizeof(struct in6_addr)); bcopy(&reddst6, &sdst.sin6_addr, sizeof(struct in6_addr)); bcopy(&src6, &ssrc.sin6_addr, sizeof(struct in6_addr)); - rtredirect((struct sockaddr *)&sdst, (struct sockaddr *)&sgw, - (struct sockaddr *)NULL, RTF_GATEWAY | RTF_HOST, - (struct sockaddr *)&ssrc); + for (fibnum = 0; fibnum < rt_numfibs; fibnum++) + in6_rtredirect((struct sockaddr *)&sdst, + (struct sockaddr *)&sgw, (struct sockaddr *)NULL, + RTF_GATEWAY | RTF_HOST, (struct sockaddr *)&ssrc, + fibnum); } /* finally update cached route in each socket via pfctlinput */ { @@ -2541,6 +2534,7 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt) MCLGET(m, M_DONTWAIT); if (!m) goto fail; + M_SETFIB(m, rt->rt_fibnum); m->m_pkthdr.rcvif = NULL; m->m_len = 0; maxlen = M_TRAILINGSPACE(m); @@ -2620,9 +2614,9 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt) struct nd_opt_hdr *nd_opt; char *lladdr; - IF_AFDATA_LOCK(ifp); + IF_AFDATA_RLOCK(ifp); ln = nd6_lookup(router_ll6, 0, ifp); - IF_AFDATA_UNLOCK(ifp); + IF_AFDATA_RUNLOCK(ifp); if (ln == NULL) goto nolladdropt; |