static void in_pcbwild_update_internal(struct inpcb *inp) { int wildcard_needed; wildcard_needed = in_pcbwild_needed(inp); if (wildcard_needed && !(inp->inp_flags2 & INP_PCBGROUPWILD)) in_pcbwild_add(inp); else if (!wildcard_needed && (inp->inp_flags2 & INP_PCBGROUPWILD)) in_pcbwild_remove(inp); }
/* * Update the pcbgroup of an inpcb, which might include removing an old * pcbgroup reference and/or adding a new one. Wildcard processing is not * performed here, although ideally we'll never install a pcbgroup for a * wildcard inpcb (asserted below). */ static void in_pcbgroup_update_internal(struct inpcbinfo *pcbinfo, struct inpcbgroup *newpcbgroup, struct inpcb *inp) { struct inpcbgroup *oldpcbgroup; struct inpcbhead *pcbhash; uint32_t hashkey_faddr; INP_WLOCK_ASSERT(inp); oldpcbgroup = inp->inp_pcbgroup; if (oldpcbgroup != NULL && oldpcbgroup != newpcbgroup) { INP_GROUP_LOCK(oldpcbgroup); LIST_REMOVE(inp, inp_pcbgrouphash); inp->inp_pcbgroup = NULL; INP_GROUP_UNLOCK(oldpcbgroup); } if (newpcbgroup != NULL && oldpcbgroup != newpcbgroup) { #ifdef INET6 if (inp->inp_vflag & INP_IPV6) hashkey_faddr = INP6_PCBHASHKEY(&inp->in6p_faddr); else #endif hashkey_faddr = inp->inp_faddr.s_addr; INP_GROUP_LOCK(newpcbgroup); /* * If the inp is an RSS bucket wildcard entry, ensure * that the PCB hash is calculated correctly. * * The wildcard hash calculation differs from the * non-wildcard definition. The source address is * INADDR_ANY and the far port is 0. */ if (inp->inp_flags2 & INP_RSS_BUCKET_SET) { pcbhash = &newpcbgroup->ipg_hashbase[ INP_PCBHASH(INADDR_ANY, inp->inp_lport, 0, newpcbgroup->ipg_hashmask)]; } else { pcbhash = &newpcbgroup->ipg_hashbase[ INP_PCBHASH(hashkey_faddr, inp->inp_lport, inp->inp_fport, newpcbgroup->ipg_hashmask)]; } LIST_INSERT_HEAD(pcbhash, inp, inp_pcbgrouphash); inp->inp_pcbgroup = newpcbgroup; INP_GROUP_UNLOCK(newpcbgroup); } KASSERT(!(newpcbgroup != NULL && in_pcbwild_needed(inp)), ("%s: pcbgroup and wildcard!", __func__)); }
/* * Update the pcbgroup of an inpcb, which might include removing an old * pcbgroup reference and/or adding a new one. Wildcard processing is not * performed here, although ideally we'll never install a pcbgroup for a * wildcard inpcb (asserted below). */ static void in_pcbgroup_update_internal(struct inpcbinfo *pcbinfo, struct inpcbgroup *newpcbgroup, struct inpcb *inp) { struct inpcbgroup *oldpcbgroup; struct inpcbhead *pcbhash; uint32_t hashkey_faddr; INP_WLOCK_ASSERT(inp); oldpcbgroup = inp->inp_pcbgroup; if (oldpcbgroup != NULL && oldpcbgroup != newpcbgroup) { INP_GROUP_LOCK(oldpcbgroup); LIST_REMOVE(inp, inp_pcbgrouphash); inp->inp_pcbgroup = NULL; INP_GROUP_UNLOCK(oldpcbgroup); } if (newpcbgroup != NULL && oldpcbgroup != newpcbgroup) { #ifdef INET6 if (inp->inp_vflag & INP_IPV6) hashkey_faddr = inp->in6p_faddr.s6_addr32[3]; /* XXX */ else #endif hashkey_faddr = inp->inp_faddr.s_addr; INP_GROUP_LOCK(newpcbgroup); pcbhash = &newpcbgroup->ipg_hashbase[ INP_PCBHASH(hashkey_faddr, inp->inp_lport, inp->inp_fport, newpcbgroup->ipg_hashmask)]; LIST_INSERT_HEAD(pcbhash, inp, inp_pcbgrouphash); inp->inp_pcbgroup = newpcbgroup; INP_GROUP_UNLOCK(newpcbgroup); } KASSERT(!(newpcbgroup != NULL && in_pcbwild_needed(inp)), ("%s: pcbgroup and wildcard!", __func__)); }