* 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). */
| 403 | * wildcard inpcb (asserted below). |
| 404 | */ |
| 405 | static void |
| 406 | in_pcbgroup_update_internal(struct inpcbinfo *pcbinfo, |
| 407 | struct inpcbgroup *newpcbgroup, struct inpcb *inp) |
| 408 | { |
| 409 | struct inpcbgroup *oldpcbgroup; |
| 410 | struct inpcbhead *pcbhash; |
| 411 | uint32_t hashkey_faddr; |
| 412 | |
| 413 | INP_WLOCK_ASSERT(inp); |
| 414 | |
| 415 | oldpcbgroup = inp->inp_pcbgroup; |
| 416 | if (oldpcbgroup != NULL && oldpcbgroup != newpcbgroup) { |
| 417 | INP_GROUP_LOCK(oldpcbgroup); |
| 418 | CK_LIST_REMOVE(inp, inp_pcbgrouphash); |
| 419 | inp->inp_pcbgroup = NULL; |
| 420 | INP_GROUP_UNLOCK(oldpcbgroup); |
| 421 | } |
| 422 | if (newpcbgroup != NULL && oldpcbgroup != newpcbgroup) { |
| 423 | #ifdef INET6 |
| 424 | if (inp->inp_vflag & INP_IPV6) |
| 425 | hashkey_faddr = INP6_PCBHASHKEY(&inp->in6p_faddr); |
| 426 | else |
| 427 | #endif |
| 428 | hashkey_faddr = inp->inp_faddr.s_addr; |
| 429 | INP_GROUP_LOCK(newpcbgroup); |
| 430 | /* |
| 431 | * If the inp is an RSS bucket wildcard entry, ensure |
| 432 | * that the PCB hash is calculated correctly. |
| 433 | * |
| 434 | * The wildcard hash calculation differs from the |
| 435 | * non-wildcard definition. The source address is |
| 436 | * INADDR_ANY and the far port is 0. |
| 437 | */ |
| 438 | if (inp->inp_flags2 & INP_RSS_BUCKET_SET) { |
| 439 | pcbhash = &newpcbgroup->ipg_hashbase[ |
| 440 | INP_PCBHASH(INADDR_ANY, inp->inp_lport, 0, |
| 441 | newpcbgroup->ipg_hashmask)]; |
| 442 | } else { |
| 443 | pcbhash = &newpcbgroup->ipg_hashbase[ |
| 444 | INP_PCBHASH(hashkey_faddr, inp->inp_lport, |
| 445 | inp->inp_fport, |
| 446 | newpcbgroup->ipg_hashmask)]; |
| 447 | } |
| 448 | CK_LIST_INSERT_HEAD(pcbhash, inp, inp_pcbgrouphash); |
| 449 | inp->inp_pcbgroup = newpcbgroup; |
| 450 | INP_GROUP_UNLOCK(newpcbgroup); |
| 451 | } |
| 452 | |
| 453 | KASSERT(!(newpcbgroup != NULL && in_pcbwild_needed(inp)), |
| 454 | ("%s: pcbgroup and wildcard!", __func__)); |
| 455 | } |
| 456 | |
| 457 | /* |
| 458 | * Two update paths: one in which the 4-tuple on an inpcb has been updated |
no test coverage detected