version 1.158, 2016/04/04 07:37:07 |
version 1.161, 2016/06/22 07:48:17 |
Line 217 ip6intr(void *arg __unused) |
|
Line 217 ip6intr(void *arg __unused) |
|
|
|
mutex_enter(softnet_lock); |
mutex_enter(softnet_lock); |
while ((m = pktq_dequeue(ip6_pktq)) != NULL) { |
while ((m = pktq_dequeue(ip6_pktq)) != NULL) { |
const ifnet_t *ifp = m->m_pkthdr.rcvif; |
struct psref psref; |
|
struct ifnet *rcvif = m_get_rcvif_psref(m, &psref); |
|
|
|
if (rcvif == NULL) { |
|
m_freem(m); |
|
continue; |
|
} |
/* |
/* |
* Drop the packet if IPv6 is disabled on the interface. |
* Drop the packet if IPv6 is disabled on the interface. |
*/ |
*/ |
if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) { |
if ((ND_IFINFO(rcvif)->flags & ND6_IFF_IFDISABLED)) { |
|
m_put_rcvif_psref(rcvif, &psref); |
m_freem(m); |
m_freem(m); |
continue; |
continue; |
} |
} |
ip6_input(m); |
ip6_input(m, rcvif); |
|
m_put_rcvif_psref(rcvif, &psref); |
} |
} |
mutex_exit(softnet_lock); |
mutex_exit(softnet_lock); |
} |
} |
Line 234 ip6intr(void *arg __unused) |
|
Line 241 ip6intr(void *arg __unused) |
|
extern struct route ip6_forward_rt; |
extern struct route ip6_forward_rt; |
|
|
void |
void |
ip6_input(struct mbuf *m) |
ip6_input(struct mbuf *m, struct ifnet *rcvif) |
{ |
{ |
struct ip6_hdr *ip6; |
struct ip6_hdr *ip6; |
int hit, off = sizeof(struct ip6_hdr), nest; |
int hit, off = sizeof(struct ip6_hdr), nest; |
Line 265 ip6_input(struct mbuf *m) |
|
Line 272 ip6_input(struct mbuf *m) |
|
} else { |
} else { |
#define M2MMAX 32 |
#define M2MMAX 32 |
if (m->m_next) { |
if (m->m_next) { |
if (m->m_flags & M_LOOP) { |
if (m->m_flags & M_LOOP) |
/*XXX*/ IP6_STATINC(IP6_STAT_M2M + lo0ifp->if_index); |
/*XXX*/ IP6_STATINC(IP6_STAT_M2M + lo0ifp->if_index); |
} else if (m->m_pkthdr.rcvif->if_index < M2MMAX) { |
else if (rcvif->if_index < M2MMAX) |
IP6_STATINC(IP6_STAT_M2M + |
IP6_STATINC(IP6_STAT_M2M + rcvif->if_index); |
m->m_pkthdr.rcvif->if_index); |
else |
} else |
|
IP6_STATINC(IP6_STAT_M2M); |
IP6_STATINC(IP6_STAT_M2M); |
} else |
} else |
IP6_STATINC(IP6_STAT_M1); |
IP6_STATINC(IP6_STAT_M1); |
#undef M2MMAX |
#undef M2MMAX |
} |
} |
|
|
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive); |
in6_ifstat_inc(rcvif, ifs6_in_receive); |
IP6_STATINC(IP6_STAT_TOTAL); |
IP6_STATINC(IP6_STAT_TOTAL); |
|
|
/* |
/* |
Line 287 ip6_input(struct mbuf *m) |
|
Line 293 ip6_input(struct mbuf *m) |
|
* IPv6 header is in the first mbuf of the chain. |
* IPv6 header is in the first mbuf of the chain. |
*/ |
*/ |
if (IP6_HDR_ALIGNED_P(mtod(m, void *)) == 0) { |
if (IP6_HDR_ALIGNED_P(mtod(m, void *)) == 0) { |
struct ifnet *inifp = m->m_pkthdr.rcvif; |
|
if ((m = m_copyup(m, sizeof(struct ip6_hdr), |
if ((m = m_copyup(m, sizeof(struct ip6_hdr), |
(max_linkhdr + 3) & ~3)) == NULL) { |
(max_linkhdr + 3) & ~3)) == NULL) { |
/* XXXJRT new stat, please */ |
/* XXXJRT new stat, please */ |
IP6_STATINC(IP6_STAT_TOOSMALL); |
IP6_STATINC(IP6_STAT_TOOSMALL); |
in6_ifstat_inc(inifp, ifs6_in_hdrerr); |
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
return; |
return; |
} |
} |
} else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { |
} else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { |
struct ifnet *inifp = m->m_pkthdr.rcvif; |
|
if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { |
if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { |
IP6_STATINC(IP6_STAT_TOOSMALL); |
IP6_STATINC(IP6_STAT_TOOSMALL); |
in6_ifstat_inc(inifp, ifs6_in_hdrerr); |
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
return; |
return; |
} |
} |
} |
} |
Line 308 ip6_input(struct mbuf *m) |
|
Line 312 ip6_input(struct mbuf *m) |
|
|
|
if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { |
if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { |
IP6_STATINC(IP6_STAT_BADVERS); |
IP6_STATINC(IP6_STAT_BADVERS); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); |
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
goto bad; |
goto bad; |
} |
} |
|
|
Line 338 ip6_input(struct mbuf *m) |
|
Line 342 ip6_input(struct mbuf *m) |
|
struct in6_addr odst; |
struct in6_addr odst; |
|
|
odst = ip6->ip6_dst; |
odst = ip6->ip6_dst; |
if (pfil_run_hooks(inet6_pfil_hook, &m, m->m_pkthdr.rcvif, |
if (pfil_run_hooks(inet6_pfil_hook, &m, rcvif, PFIL_IN) != 0) |
PFIL_IN) != 0) |
|
return; |
return; |
if (m == NULL) |
if (m == NULL) |
return; |
return; |
Line 365 ip6_input(struct mbuf *m) |
|
Line 368 ip6_input(struct mbuf *m) |
|
* XXX: "badscope" is not very suitable for a multicast source. |
* XXX: "badscope" is not very suitable for a multicast source. |
*/ |
*/ |
IP6_STATINC(IP6_STAT_BADSCOPE); |
IP6_STATINC(IP6_STAT_BADSCOPE); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); |
in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
goto bad; |
goto bad; |
} |
} |
/* |
/* |
Line 383 ip6_input(struct mbuf *m) |
|
Line 386 ip6_input(struct mbuf *m) |
|
if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || |
if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || |
IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { |
IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { |
IP6_STATINC(IP6_STAT_BADSCOPE); |
IP6_STATINC(IP6_STAT_BADSCOPE); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); |
in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
goto bad; |
goto bad; |
} |
} |
#if 0 |
#if 0 |
Line 397 ip6_input(struct mbuf *m) |
|
Line 400 ip6_input(struct mbuf *m) |
|
if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) || |
if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) || |
IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { |
IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { |
IP6_STATINC(IP6_STAT_BADSCOPE); |
IP6_STATINC(IP6_STAT_BADSCOPE); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); |
in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
goto bad; |
goto bad; |
} |
} |
#endif |
#endif |
Line 420 ip6_input(struct mbuf *m) |
|
Line 423 ip6_input(struct mbuf *m) |
|
IP6_STATINC(IP6_STAT_BADSCOPE); /* XXX */ |
IP6_STATINC(IP6_STAT_BADSCOPE); /* XXX */ |
goto bad; |
goto bad; |
} |
} |
if (in6_setscope(&ip6->ip6_src, m->m_pkthdr.rcvif, NULL) || |
if (in6_setscope(&ip6->ip6_src, rcvif, NULL) || |
in6_setscope(&ip6->ip6_dst, m->m_pkthdr.rcvif, NULL)) { |
in6_setscope(&ip6->ip6_dst, rcvif, NULL)) { |
IP6_STATINC(IP6_STAT_BADSCOPE); |
IP6_STATINC(IP6_STAT_BADSCOPE); |
goto bad; |
goto bad; |
} |
} |
Line 432 ip6_input(struct mbuf *m) |
|
Line 435 ip6_input(struct mbuf *m) |
|
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { |
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { |
struct in6_multi *in6m = 0; |
struct in6_multi *in6m = 0; |
|
|
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast); |
in6_ifstat_inc(rcvif, ifs6_in_mcast); |
/* |
/* |
* See if we belong to the destination multicast group on the |
* See if we belong to the destination multicast group on the |
* arrival interface. |
* arrival interface. |
*/ |
*/ |
IN6_LOOKUP_MULTI(ip6->ip6_dst, m->m_pkthdr.rcvif, in6m); |
IN6_LOOKUP_MULTI(ip6->ip6_dst, rcvif, in6m); |
if (in6m) |
if (in6m) |
ours = 1; |
ours = 1; |
else if (!ip6_mrouter) { |
else if (!ip6_mrouter) { |
Line 445 ip6_input(struct mbuf *m) |
|
Line 448 ip6_input(struct mbuf *m) |
|
ip6s[IP6_STAT_NOTMEMBER]++; |
ip6s[IP6_STAT_NOTMEMBER]++; |
ip6s[IP6_STAT_CANTFORWARD]++; |
ip6s[IP6_STAT_CANTFORWARD]++; |
IP6_STAT_PUTREF(); |
IP6_STAT_PUTREF(); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
goto bad; |
goto bad; |
} |
} |
deliverifp = m->m_pkthdr.rcvif; |
deliverifp = rcvif; |
goto hbhcheck; |
goto hbhcheck; |
} |
} |
|
|
Line 530 ip6_input(struct mbuf *m) |
|
Line 533 ip6_input(struct mbuf *m) |
|
* working right. |
* working right. |
*/ |
*/ |
struct ifaddr *ifa; |
struct ifaddr *ifa; |
IFADDR_FOREACH(ifa, m->m_pkthdr.rcvif) { |
IFADDR_FOREACH(ifa, rcvif) { |
if (ifa->ifa_addr == NULL) |
|
continue; /* just for safety */ |
|
if (ifa->ifa_addr->sa_family != AF_INET6) |
if (ifa->ifa_addr->sa_family != AF_INET6) |
continue; |
continue; |
if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ip6->ip6_dst)) { |
if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ip6->ip6_dst)) { |
Line 550 ip6_input(struct mbuf *m) |
|
Line 551 ip6_input(struct mbuf *m) |
|
*/ |
*/ |
if (!ip6_forwarding) { |
if (!ip6_forwarding) { |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
goto bad; |
goto bad; |
} |
} |
|
|
Line 585 ip6_input(struct mbuf *m) |
|
Line 586 ip6_input(struct mbuf *m) |
|
|
|
if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) { |
if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) { |
#if 0 /*touches NULL pointer*/ |
#if 0 /*touches NULL pointer*/ |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
#endif |
#endif |
return; /* m have already been freed */ |
return; /* m have already been freed */ |
} |
} |
Line 605 ip6_input(struct mbuf *m) |
|
Line 606 ip6_input(struct mbuf *m) |
|
* (non-zero) payload length to the variable plen. |
* (non-zero) payload length to the variable plen. |
*/ |
*/ |
IP6_STATINC(IP6_STAT_BADOPTIONS); |
IP6_STATINC(IP6_STAT_BADOPTIONS); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); |
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
icmp6_error(m, ICMP6_PARAM_PROB, |
icmp6_error(m, ICMP6_PARAM_PROB, |
ICMP6_PARAMPROB_HEADER, |
ICMP6_PARAMPROB_HEADER, |
(char *)&ip6->ip6_plen - (char *)ip6); |
(char *)&ip6->ip6_plen - (char *)ip6); |
Line 638 ip6_input(struct mbuf *m) |
|
Line 639 ip6_input(struct mbuf *m) |
|
*/ |
*/ |
if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) { |
if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) { |
IP6_STATINC(IP6_STAT_TOOSHORT); |
IP6_STATINC(IP6_STAT_TOOSHORT); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); |
in6_ifstat_inc(rcvif, ifs6_in_truncated); |
goto bad; |
goto bad; |
} |
} |
if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) { |
if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) { |
Line 661 ip6_input(struct mbuf *m) |
|
Line 662 ip6_input(struct mbuf *m) |
|
* ip6_mforward() returns a non-zero value, the packet |
* ip6_mforward() returns a non-zero value, the packet |
* must be discarded, else it may be accepted below. |
* must be discarded, else it may be accepted below. |
*/ |
*/ |
if (ip6_mrouter && ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) { |
if (ip6_mrouter && ip6_mforward(ip6, rcvif, m)) { |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
m_freem(m); |
m_freem(m); |
return; |
return; |
Line 689 ip6_input(struct mbuf *m) |
|
Line 690 ip6_input(struct mbuf *m) |
|
if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || |
if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || |
IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { |
IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { |
IP6_STATINC(IP6_STAT_BADSCOPE); |
IP6_STATINC(IP6_STAT_BADSCOPE); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); |
in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
goto bad; |
goto bad; |
} |
} |
|
|
Line 712 ip6_input(struct mbuf *m) |
|
Line 713 ip6_input(struct mbuf *m) |
|
while (nxt != IPPROTO_DONE) { |
while (nxt != IPPROTO_DONE) { |
if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { |
if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { |
IP6_STATINC(IP6_STAT_TOOMANYHDR); |
IP6_STATINC(IP6_STAT_TOOMANYHDR); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); |
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
goto bad; |
goto bad; |
} |
} |
|
|
Line 722 ip6_input(struct mbuf *m) |
|
Line 723 ip6_input(struct mbuf *m) |
|
*/ |
*/ |
if (m->m_pkthdr.len < off) { |
if (m->m_pkthdr.len < off) { |
IP6_STATINC(IP6_STAT_TOOSHORT); |
IP6_STATINC(IP6_STAT_TOOSHORT); |
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); |
in6_ifstat_inc(rcvif, ifs6_in_truncated); |
goto bad; |
goto bad; |
} |
} |
|
|
if (nxt == IPPROTO_ROUTING) { |
if (nxt == IPPROTO_ROUTING) { |
if (rh_present++) { |
if (rh_present++) { |
in6_ifstat_inc(m->m_pkthdr.rcvif, |
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
ifs6_in_hdrerr); |
|
IP6_STATINC(IP6_STAT_BADOPTIONS); |
IP6_STATINC(IP6_STAT_BADOPTIONS); |
goto bad; |
goto bad; |
} |
} |
Line 1062 ip6_savecontrol(struct in6pcb *in6p, str |
|
Line 1062 ip6_savecontrol(struct in6pcb *in6p, str |
|
|
|
memcpy(&pi6.ipi6_addr, &ip6->ip6_dst, sizeof(struct in6_addr)); |
memcpy(&pi6.ipi6_addr, &ip6->ip6_dst, sizeof(struct in6_addr)); |
in6_clearscope(&pi6.ipi6_addr); /* XXX */ |
in6_clearscope(&pi6.ipi6_addr); /* XXX */ |
pi6.ipi6_ifindex = m->m_pkthdr.rcvif ? |
pi6.ipi6_ifindex = m->m_pkthdr.rcvif_index; |
m->m_pkthdr.rcvif->if_index : 0; |
|
*mp = sbcreatecontrol((void *) &pi6, |
*mp = sbcreatecontrol((void *) &pi6, |
sizeof(struct in6_pktinfo), |
sizeof(struct in6_pktinfo), |
IS2292(IPV6_2292PKTINFO, IPV6_PKTINFO), IPPROTO_IPV6); |
IS2292(IPV6_2292PKTINFO, IPV6_PKTINFO), IPPROTO_IPV6); |