* Set the TCP log ID for a TCPCB. * Called with INPCB locked. Returns with it unlocked. */
| 558 | * Called with INPCB locked. Returns with it unlocked. |
| 559 | */ |
| 560 | int |
| 561 | tcp_log_set_id(struct tcpcb *tp, char *id) |
| 562 | { |
| 563 | struct tcp_log_id_bucket *tlb, *tmp_tlb; |
| 564 | struct tcp_log_id_node *tln; |
| 565 | struct inpcb *inp; |
| 566 | int tree_locked, rv; |
| 567 | bool bucket_locked; |
| 568 | |
| 569 | tlb = NULL; |
| 570 | tln = NULL; |
| 571 | inp = tp->t_inpcb; |
| 572 | tree_locked = TREE_UNLOCKED; |
| 573 | bucket_locked = false; |
| 574 | |
| 575 | restart: |
| 576 | INP_WLOCK_ASSERT(inp); |
| 577 | |
| 578 | /* See if the ID is unchanged. */ |
| 579 | if ((tp->t_lib != NULL && !strcmp(tp->t_lib->tlb_id, id)) || |
| 580 | (tp->t_lib == NULL && *id == 0)) { |
| 581 | if (tp->t_lib != NULL) { |
| 582 | tcp_log_increment_reqcnt(tp->t_lib); |
| 583 | if ((tp->t_lib->tlb_logstate) && |
| 584 | (tp->t_log_state_set == 0)) { |
| 585 | /* Clone in any logging */ |
| 586 | |
| 587 | tp->t_logstate = tp->t_lib->tlb_logstate; |
| 588 | } |
| 589 | if ((tp->t_lib->tlb_loglimit) && |
| 590 | (tp->t_log_state_set == 0)) { |
| 591 | /* We also have a limit set */ |
| 592 | |
| 593 | tp->t_loglimit = tp->t_lib->tlb_loglimit; |
| 594 | } |
| 595 | } |
| 596 | rv = 0; |
| 597 | goto done; |
| 598 | } |
| 599 | |
| 600 | /* |
| 601 | * If the TCPCB had a previous ID, we need to extricate it from |
| 602 | * the previous list. |
| 603 | * |
| 604 | * Drop the TCPCB lock and lock the tree and the bucket. |
| 605 | * Because this is called in the socket context, we (theoretically) |
| 606 | * don't need to worry about the INPCB completely going away |
| 607 | * while we are gone. |
| 608 | */ |
| 609 | if (tp->t_lib != NULL) { |
| 610 | tlb = tp->t_lib; |
| 611 | TCPID_BUCKET_REF(tlb); |
| 612 | INP_WUNLOCK(inp); |
| 613 | |
| 614 | if (tree_locked == TREE_UNLOCKED) { |
| 615 | TCPID_TREE_RLOCK(); |
| 616 | tree_locked = TREE_RLOCKED; |
| 617 | } |
no test coverage detected