version 1.178.2.4, 2018/01/30 18:21:09 |
version 1.178.2.9, 2019/09/24 18:27:09 |
|
|
KASSERT(inet6_pfil_hook != NULL); |
KASSERT(inet6_pfil_hook != NULL); |
|
|
ip6stat_percpu = percpu_alloc(sizeof(uint64_t) * IP6_NSTATS); |
ip6stat_percpu = percpu_alloc(sizeof(uint64_t) * IP6_NSTATS); |
ip6_forward_rt_percpu = percpu_alloc(sizeof(struct route)); |
ip6_forward_rt_percpu = rtcache_percpu_alloc(); |
} |
} |
|
|
static void |
static void |
Line 228 ip6intr(void *arg __unused) |
|
Line 228 ip6intr(void *arg __unused) |
|
{ |
{ |
struct mbuf *m; |
struct mbuf *m; |
|
|
SOFTNET_LOCK_UNLESS_NET_MPSAFE(); |
SOFTNET_KERNEL_LOCK_UNLESS_NET_MPSAFE(); |
while ((m = pktq_dequeue(ip6_pktq)) != NULL) { |
while ((m = pktq_dequeue(ip6_pktq)) != NULL) { |
struct psref psref; |
struct psref psref; |
struct ifnet *rcvif = m_get_rcvif_psref(m, &psref); |
struct ifnet *rcvif = m_get_rcvif_psref(m, &psref); |
Line 248 ip6intr(void *arg __unused) |
|
Line 248 ip6intr(void *arg __unused) |
|
ip6_input(m, rcvif); |
ip6_input(m, rcvif); |
m_put_rcvif_psref(rcvif, &psref); |
m_put_rcvif_psref(rcvif, &psref); |
} |
} |
SOFTNET_UNLOCK_UNLESS_NET_MPSAFE(); |
SOFTNET_KERNEL_UNLOCK_UNLESS_NET_MPSAFE(); |
} |
} |
|
|
void |
void |
Line 258 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 258 ip6_input(struct mbuf *m, struct ifnet * |
|
int hit, off = sizeof(struct ip6_hdr), nest; |
int hit, off = sizeof(struct ip6_hdr), nest; |
u_int32_t plen; |
u_int32_t plen; |
u_int32_t rtalert = ~0; |
u_int32_t rtalert = ~0; |
int nxt, ours = 0, rh_present = 0; |
int nxt, ours = 0, rh_present = 0, frg_present; |
struct ifnet *deliverifp = NULL; |
struct ifnet *deliverifp = NULL; |
int srcrt = 0; |
int srcrt = 0; |
struct rtentry *rt = NULL; |
struct rtentry *rt = NULL; |
Line 358 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 358 ip6_input(struct mbuf *m, struct ifnet * |
|
return; |
return; |
if (m == NULL) |
if (m == NULL) |
return; |
return; |
|
if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { |
|
if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { |
|
IP6_STATINC(IP6_STAT_TOOSMALL); |
|
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
|
return; |
|
} |
|
} |
ip6 = mtod(m, struct ip6_hdr *); |
ip6 = mtod(m, struct ip6_hdr *); |
srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst); |
srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst); |
} |
} |
Line 446 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 453 ip6_input(struct mbuf *m, struct ifnet * |
|
goto bad; |
goto bad; |
} |
} |
|
|
ro = percpu_getref(ip6_forward_rt_percpu); |
ro = rtcache_percpu_getref(ip6_forward_rt_percpu); |
/* |
/* |
* Multicast check |
* Multicast check |
*/ |
*/ |
Line 632 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 639 ip6_input(struct mbuf *m, struct ifnet * |
|
in6_ifstat_inc(rcvif, ifs6_in_discard); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
#endif |
#endif |
rtcache_unref(rt, ro); |
rtcache_unref(rt, ro); |
percpu_putref(ip6_forward_rt_percpu); |
rtcache_percpu_putref(ip6_forward_rt_percpu); |
return; /* m have already been freed */ |
return; /* m have already been freed */ |
} |
} |
|
|
Line 657 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 664 ip6_input(struct mbuf *m, struct ifnet * |
|
ICMP6_PARAMPROB_HEADER, |
ICMP6_PARAMPROB_HEADER, |
(char *)&ip6->ip6_plen - (char *)ip6); |
(char *)&ip6->ip6_plen - (char *)ip6); |
rtcache_unref(rt, ro); |
rtcache_unref(rt, ro); |
percpu_putref(ip6_forward_rt_percpu); |
rtcache_percpu_putref(ip6_forward_rt_percpu); |
return; |
return; |
} |
} |
IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), |
IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), |
Line 665 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 672 ip6_input(struct mbuf *m, struct ifnet * |
|
if (hbh == NULL) { |
if (hbh == NULL) { |
IP6_STATINC(IP6_STAT_TOOSHORT); |
IP6_STATINC(IP6_STAT_TOOSHORT); |
rtcache_unref(rt, ro); |
rtcache_unref(rt, ro); |
percpu_putref(ip6_forward_rt_percpu); |
rtcache_percpu_putref(ip6_forward_rt_percpu); |
return; |
return; |
} |
} |
KASSERT(IP6_HDR_ALIGNED_P(hbh)); |
KASSERT(IP6_HDR_ALIGNED_P(hbh)); |
Line 720 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 727 ip6_input(struct mbuf *m, struct ifnet * |
|
|
|
if (error != 0) { |
if (error != 0) { |
rtcache_unref(rt, ro); |
rtcache_unref(rt, ro); |
percpu_putref(ip6_forward_rt_percpu); |
rtcache_percpu_putref(ip6_forward_rt_percpu); |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
goto bad; |
goto bad; |
} |
} |
Line 729 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 736 ip6_input(struct mbuf *m, struct ifnet * |
|
goto bad_unref; |
goto bad_unref; |
} else if (!ours) { |
} else if (!ours) { |
rtcache_unref(rt, ro); |
rtcache_unref(rt, ro); |
percpu_putref(ip6_forward_rt_percpu); |
rtcache_percpu_putref(ip6_forward_rt_percpu); |
ip6_forward(m, srcrt); |
ip6_forward(m, srcrt); |
return; |
return; |
} |
} |
Line 773 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 780 ip6_input(struct mbuf *m, struct ifnet * |
|
rtcache_unref(rt, ro); |
rtcache_unref(rt, ro); |
rt = NULL; |
rt = NULL; |
} |
} |
percpu_putref(ip6_forward_rt_percpu); |
rtcache_percpu_putref(ip6_forward_rt_percpu); |
|
|
rh_present = 0; |
rh_present = 0; |
|
frg_present = 0; |
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); |
Line 799 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 807 ip6_input(struct mbuf *m, struct ifnet * |
|
IP6_STATINC(IP6_STAT_BADOPTIONS); |
IP6_STATINC(IP6_STAT_BADOPTIONS); |
goto bad; |
goto bad; |
} |
} |
|
} else if (nxt == IPPROTO_FRAGMENT) { |
|
if (frg_present++) { |
|
in6_ifstat_inc(rcvif, ifs6_in_hdrerr); |
|
IP6_STATINC(IP6_STAT_BADOPTIONS); |
|
goto bad; |
|
} |
} |
} |
|
|
#ifdef IPSEC |
#ifdef IPSEC |
Line 825 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 839 ip6_input(struct mbuf *m, struct ifnet * |
|
|
|
bad_unref: |
bad_unref: |
rtcache_unref(rt, ro); |
rtcache_unref(rt, ro); |
percpu_putref(ip6_forward_rt_percpu); |
rtcache_percpu_putref(ip6_forward_rt_percpu); |
bad: |
bad: |
m_freem(m); |
m_freem(m); |
return; |
return; |
Line 1345 ip6_notify_pmtu(struct in6pcb *in6p, con |
|
Line 1359 ip6_notify_pmtu(struct in6pcb *in6p, con |
|
|
|
if (sbappendaddr(&so->so_rcv, (const struct sockaddr *)dst, NULL, m_mtu) |
if (sbappendaddr(&so->so_rcv, (const struct sockaddr *)dst, NULL, m_mtu) |
== 0) { |
== 0) { |
|
soroverflow(so); |
m_freem(m_mtu); |
m_freem(m_mtu); |
/* XXX: should count statistics */ |
|
} else |
} else |
sorwakeup(so); |
sorwakeup(so); |
|
|