According to in_pcb.h protocol binding information has double locking.
It allows access it while list travercing holding only global pcbinfo lock.
This commit is contained in:
parent
369f479043
commit
8a791bfa67
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
|
||||
INP_RUNLOCK(last);
|
||||
}
|
||||
last = in6p;
|
||||
INP_RLOCK(last);
|
||||
}
|
||||
INP_INFO_RUNLOCK(&ripcbinfo);
|
||||
#ifdef IPSEC
|
||||
/*
|
||||
* Check AH/ESP integrity.
|
||||
@ -252,7 +250,6 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
|
||||
}
|
||||
ip6stat.ip6s_delivered--;
|
||||
}
|
||||
INP_INFO_RUNLOCK(&ripcbinfo);
|
||||
return (IPPROTO_DONE);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user