version 1.164.2.2, 2016/11/04 14:49:21 |
version 1.164.2.3, 2017/01/07 08:56:51 |
Line 264 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 264 ip6_input(struct mbuf *m, struct ifnet * |
|
int nxt, ours = 0, rh_present = 0; |
int nxt, ours = 0, rh_present = 0; |
struct ifnet *deliverifp = NULL; |
struct ifnet *deliverifp = NULL; |
int srcrt = 0; |
int srcrt = 0; |
const struct rtentry *rt; |
struct rtentry *rt = NULL; |
union { |
union { |
struct sockaddr dst; |
struct sockaddr dst; |
struct sockaddr_in6 dst6; |
struct sockaddr_in6 dst6; |
Line 448 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 448 ip6_input(struct mbuf *m, struct ifnet * |
|
goto bad; |
goto bad; |
} |
} |
|
|
|
ro = percpu_getref(ip6_forward_rt_percpu); |
/* |
/* |
* Multicast check |
* Multicast check |
*/ |
*/ |
Line 468 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 469 ip6_input(struct mbuf *m, struct ifnet * |
|
ip6s[IP6_STAT_CANTFORWARD]++; |
ip6s[IP6_STAT_CANTFORWARD]++; |
IP6_STAT_PUTREF(); |
IP6_STAT_PUTREF(); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
goto bad; |
goto bad_unref; |
} |
} |
deliverifp = rcvif; |
deliverifp = rcvif; |
goto hbhcheck; |
goto hbhcheck; |
Line 479 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 480 ip6_input(struct mbuf *m, struct ifnet * |
|
/* |
/* |
* Unicast check |
* Unicast check |
*/ |
*/ |
rt = rtcache_lookup2(&ip6_forward_rt, &u.dst, 1, &hit); |
rt = rtcache_lookup2(ro, &u.dst, 1, &hit); |
if (hit) |
if (hit) |
IP6_STATINC(IP6_STAT_FORWARD_CACHEHIT); |
IP6_STATINC(IP6_STAT_FORWARD_CACHEHIT); |
else |
else |
Line 525 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 526 ip6_input(struct mbuf *m, struct ifnet * |
|
ip6_sprintf(&ip6->ip6_src), |
ip6_sprintf(&ip6->ip6_src), |
ip6_sprintf(&ip6->ip6_dst)); |
ip6_sprintf(&ip6->ip6_dst)); |
|
|
goto bad; |
goto bad_unref; |
} |
} |
} |
} |
|
|
Line 571 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 572 ip6_input(struct mbuf *m, struct ifnet * |
|
if (!ip6_forwarding) { |
if (!ip6_forwarding) { |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
goto bad; |
goto bad_unref; |
} |
} |
|
|
hbhcheck: |
hbhcheck: |
Line 610 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 611 ip6_input(struct mbuf *m, struct ifnet * |
|
#if 0 /*touches NULL pointer*/ |
#if 0 /*touches NULL pointer*/ |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
in6_ifstat_inc(rcvif, ifs6_in_discard); |
#endif |
#endif |
|
rtcache_unref(rt, ro); |
|
percpu_putref(ip6_forward_rt_percpu); |
return; /* m have already been freed */ |
return; /* m have already been freed */ |
} |
} |
|
|
Line 633 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 636 ip6_input(struct mbuf *m, struct ifnet * |
|
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); |
|
rtcache_unref(rt, ro); |
|
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), |
sizeof(struct ip6_hbh)); |
sizeof(struct ip6_hbh)); |
if (hbh == NULL) { |
if (hbh == NULL) { |
IP6_STATINC(IP6_STAT_TOOSHORT); |
IP6_STATINC(IP6_STAT_TOOSHORT); |
|
rtcache_unref(rt, ro); |
|
percpu_putref(ip6_forward_rt_percpu); |
return; |
return; |
} |
} |
KASSERT(IP6_HDR_ALIGNED_P(hbh)); |
KASSERT(IP6_HDR_ALIGNED_P(hbh)); |
Line 662 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 669 ip6_input(struct mbuf *m, struct ifnet * |
|
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(rcvif, ifs6_in_truncated); |
in6_ifstat_inc(rcvif, ifs6_in_truncated); |
goto bad; |
goto bad_unref; |
} |
} |
if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) { |
if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) { |
if (m->m_len == m->m_pkthdr.len) { |
if (m->m_len == m->m_pkthdr.len) { |
Line 692 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 699 ip6_input(struct mbuf *m, struct ifnet * |
|
SOFTNET_UNLOCK(); |
SOFTNET_UNLOCK(); |
|
|
if (error != 0) { |
if (error != 0) { |
|
rtcache_unref(rt, ro); |
|
percpu_putref(ip6_forward_rt_percpu); |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
IP6_STATINC(IP6_STAT_CANTFORWARD); |
goto bad; |
goto bad; |
} |
} |
} |
} |
if (!ours) |
if (!ours) |
goto bad; |
goto bad_unref; |
} else if (!ours) { |
} else if (!ours) { |
|
rtcache_unref(rt, ro); |
|
percpu_putref(ip6_forward_rt_percpu); |
ip6_forward(m, srcrt); |
ip6_forward(m, srcrt); |
return; |
return; |
} |
} |
Line 718 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 729 ip6_input(struct mbuf *m, struct ifnet * |
|
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(rcvif, ifs6_in_addrerr); |
in6_ifstat_inc(rcvif, ifs6_in_addrerr); |
goto bad; |
goto bad_unref; |
} |
} |
|
|
/* |
/* |
Line 738 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 749 ip6_input(struct mbuf *m, struct ifnet * |
|
in6_ifstat_inc(deliverifp, ifs6_in_deliver); |
in6_ifstat_inc(deliverifp, ifs6_in_deliver); |
nest = 0; |
nest = 0; |
|
|
|
if (rt != NULL) { |
|
rtcache_unref(rt, ro); |
|
rt = NULL; |
|
} |
|
percpu_putref(ip6_forward_rt_percpu); |
|
|
rh_present = 0; |
rh_present = 0; |
while (nxt != IPPROTO_DONE) { |
while (nxt != IPPROTO_DONE) { |
if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { |
if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { |
Line 789 ip6_input(struct mbuf *m, struct ifnet * |
|
Line 806 ip6_input(struct mbuf *m, struct ifnet * |
|
SOFTNET_UNLOCK(); |
SOFTNET_UNLOCK(); |
} |
} |
return; |
return; |
|
|
|
bad_unref: |
|
rtcache_unref(rt, ro); |
|
percpu_putref(ip6_forward_rt_percpu); |
bad: |
bad: |
m_freem(m); |
m_freem(m); |
|
return; |
} |
} |
|
|
/* |
/* |