diff options
author | mav <mav@FreeBSD.org> | 2008-07-27 20:30:34 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2008-07-27 20:30:34 +0000 |
commit | 8a791bfa67adaa4e1400a16d0da9a28131f53bcf (patch) | |
tree | de909f772b2245ec1cd0c44d233a92f71afede9d /sys/netinet6 | |
parent | 369f4790430f7c109a75e4a7f5e9e92d7c0cc8c1 (diff) | |
download | FreeBSD-src-8a791bfa67adaa4e1400a16d0da9a28131f53bcf.zip FreeBSD-src-8a791bfa67adaa4e1400a16d0da9a28131f53bcf.tar.gz |
According to in_pcb.h protocol binding information has double locking.
It allows access it while list travercing holding only global pcbinfo lock.
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/icmp6.c | 17 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.c | 17 |
2 files changed, 14 insertions, 20 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index e926c49..cdbc040 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1897,24 +1897,20 @@ icmp6_rip6_input(struct mbuf **mp, int off) INP_INFO_RLOCK(&ripcbinfo); LIST_FOREACH(in6p, &ripcb, inp_list) { - INP_RLOCK(in6p); - if ((in6p->inp_vflag & INP_IPV6) == 0) { - docontinue: - INP_RUNLOCK(in6p); + if ((in6p->inp_vflag & INP_IPV6) == 0) continue; - } if (in6p->in6p_ip6_nxt != IPPROTO_ICMPV6) - goto docontinue; + continue; if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) && !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst)) - goto docontinue; + continue; if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) && !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src)) - goto docontinue; + continue; if (in6p->in6p_icmp6filt && ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type, in6p->in6p_icmp6filt)) - goto docontinue; + continue; if (last) { struct mbuf *n = NULL; @@ -1974,7 +1970,9 @@ icmp6_rip6_input(struct mbuf **mp, int off) INP_RUNLOCK(last); } last = in6p; + INP_RLOCK(last); } + INP_INFO_RUNLOCK(&ripcbinfo); if (last) { if (last->in6p_flags & IN6P_CONTROLOPTS) ip6_savecontrol(last, m, &opts); @@ -2014,7 +2012,6 @@ icmp6_rip6_input(struct mbuf **mp, int off) m_freem(m); ip6stat.ip6s_delivered--; } - INP_INFO_RUNLOCK(&ripcbinfo); return IPPROTO_DONE; } diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index f9a7993..5e9ab49 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -154,27 +154,23 @@ rip6_input(struct mbuf **mp, int *offp, int proto) INP_INFO_RLOCK(&ripcbinfo); LIST_FOREACH(in6p, &ripcb, inp_list) { - INP_RLOCK(in6p); - if ((in6p->in6p_vflag & INP_IPV6) == 0) { -docontinue: - INP_RUNLOCK(in6p); + if ((in6p->in6p_vflag & INP_IPV6) == 0) continue; - } if (in6p->in6p_ip6_nxt && in6p->in6p_ip6_nxt != proto) - goto docontinue; + continue; if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) && !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &ip6->ip6_dst)) - goto docontinue; + continue; if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) && !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src)) - goto docontinue; + continue; if (in6p->in6p_cksum != -1) { rip6stat.rip6s_isum++; if (in6_cksum(m, proto, *offp, m->m_pkthdr.len - *offp)) { rip6stat.rip6s_badsum++; - goto docontinue; + continue; } } if (last) { @@ -210,7 +206,9 @@ docontinue: INP_RUNLOCK(last); } last = in6p; + INP_RLOCK(last); } + INP_INFO_RUNLOCK(&ripcbinfo); #ifdef IPSEC /* * Check AH/ESP integrity. @@ -252,7 +250,6 @@ docontinue: } ip6stat.ip6s_delivered--; } - INP_INFO_RUNLOCK(&ripcbinfo); return (IPPROTO_DONE); } |