summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2008-07-27 20:30:34 +0000
committermav <mav@FreeBSD.org>2008-07-27 20:30:34 +0000
commit8a791bfa67adaa4e1400a16d0da9a28131f53bcf (patch)
treede909f772b2245ec1cd0c44d233a92f71afede9d /sys/netinet6
parent369f4790430f7c109a75e4a7f5e9e92d7c0cc8c1 (diff)
downloadFreeBSD-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.c17
-rw-r--r--sys/netinet6/raw_ip6.c17
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);
}
OpenPOWER on IntegriCloud