From: Sepherosa Ziehau Date: Mon, 22 Sep 2014 11:27:07 +0000 (+0800) Subject: inpcb: Add in_pcb{link,unlink}_flags() to bypass INP_WILDCARD check X-Git-Tag: v4.1.0~107 X-Git-Url: https://gitweb.dragonflybsd.org/~tuxillo/dragonfly.git/commitdiff_plain/b55ecf7e9153a6f09e19ba912f0837f75bd4c108 inpcb: Add in_pcb{link,unlink}_flags() to bypass INP_WILDCARD check It is safe to change the inpcb's pcblist while the it is still referenced by the wildcard hash. --- diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index c79ef8bd3a..99aef0dafc 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -315,30 +315,42 @@ in_pcballoc(struct socket *so, struct inpcbinfo *pcbinfo) * inp_pcbinfo, NULL it out so we assert if it does. */ void -in_pcbunlink(struct inpcb *inp, struct inpcbinfo *pcbinfo) +in_pcbunlink_flags(struct inpcb *inp, struct inpcbinfo *pcbinfo, int flags) { KASSERT(inp->inp_pcbinfo == pcbinfo, ("pcbinfo mismatch")); - KASSERT((inp->inp_flags & (INP_WILDCARD | INP_CONNECTED)) == 0, + KASSERT((inp->inp_flags & (flags | INP_CONNECTED)) == 0, ("already linked")); in_pcbofflist(inp); inp->inp_pcbinfo = NULL; } +void +in_pcbunlink(struct inpcb *inp, struct inpcbinfo *pcbinfo) +{ + in_pcbunlink_flags(inp, pcbinfo, INP_WILDCARD); +} + /* * Relink a pcb into a new pcbinfo. */ void -in_pcblink(struct inpcb *inp, struct inpcbinfo *pcbinfo) +in_pcblink_flags(struct inpcb *inp, struct inpcbinfo *pcbinfo, int flags) { KASSERT(inp->inp_pcbinfo == NULL, ("has pcbinfo")); - KASSERT((inp->inp_flags & (INP_WILDCARD | INP_CONNECTED)) == 0, + KASSERT((inp->inp_flags & (flags | INP_CONNECTED)) == 0, ("already linked")); inp->inp_pcbinfo = pcbinfo; in_pcbonlist(inp); } +void +in_pcblink(struct inpcb *inp, struct inpcbinfo *pcbinfo) +{ + return in_pcblink_flags(inp, pcbinfo, INP_WILDCARD); +} + static int in_pcbsetlport(struct inpcb *inp, int wild, struct ucred *cred) { diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 11c70aea4b..7b4eadb89c 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -482,7 +482,9 @@ void in_pcbinfo_init (struct inpcbinfo *, int, boolean_t); void in_pcbportinfo_init (struct inpcbportinfo *, int, boolean_t, u_short); int in_pcballoc (struct socket *, struct inpcbinfo *); void in_pcbunlink (struct inpcb *, struct inpcbinfo *); +void in_pcbunlink_flags (struct inpcb *, struct inpcbinfo *, int); void in_pcblink (struct inpcb *, struct inpcbinfo *); +void in_pcblink_flags (struct inpcb *, struct inpcbinfo *, int); void in_pcbonlist (struct inpcb *); void in_pcbofflist (struct inpcb *); int in_pcbbind (struct inpcb *, struct sockaddr *, struct thread *);