* Attach descriptor to the bpf interface, i.e. make d listen on bp, * then reset its buffers and counters with reset_d(). */
| 711 | * then reset its buffers and counters with reset_d(). |
| 712 | */ |
| 713 | static void |
| 714 | bpf_attachd(struct bpf_d *d, struct bpf_if *bp) |
| 715 | { |
| 716 | int op_w; |
| 717 | |
| 718 | BPF_LOCK_ASSERT(); |
| 719 | |
| 720 | /* |
| 721 | * Save sysctl value to protect from sysctl change |
| 722 | * between reads |
| 723 | */ |
| 724 | op_w = V_bpf_optimize_writers || d->bd_writer; |
| 725 | |
| 726 | if (d->bd_bif != NULL) |
| 727 | bpf_detachd_locked(d, false); |
| 728 | /* |
| 729 | * Point d at bp, and add d to the interface's list. |
| 730 | * Since there are many applications using BPF for |
| 731 | * sending raw packets only (dhcpd, cdpd are good examples) |
| 732 | * we can delay adding d to the list of active listeners until |
| 733 | * some filter is configured. |
| 734 | */ |
| 735 | |
| 736 | BPFD_LOCK(d); |
| 737 | /* |
| 738 | * Hold reference to bpif while descriptor uses this interface. |
| 739 | */ |
| 740 | bpfif_ref(bp); |
| 741 | d->bd_bif = bp; |
| 742 | if (op_w != 0) { |
| 743 | /* Add to writers-only list */ |
| 744 | CK_LIST_INSERT_HEAD(&bp->bif_wlist, d, bd_next); |
| 745 | /* |
| 746 | * We decrement bd_writer on every filter set operation. |
| 747 | * First BIOCSETF is done by pcap_open_live() to set up |
| 748 | * snap length. After that appliation usually sets its own |
| 749 | * filter. |
| 750 | */ |
| 751 | d->bd_writer = 2; |
| 752 | } else |
| 753 | CK_LIST_INSERT_HEAD(&bp->bif_dlist, d, bd_next); |
| 754 | |
| 755 | reset_d(d); |
| 756 | BPFD_UNLOCK(d); |
| 757 | bpf_bpfd_cnt++; |
| 758 | |
| 759 | CTR3(KTR_NET, "%s: bpf_attach called by pid %d, adding to %s list", |
| 760 | __func__, d->bd_pid, d->bd_writer ? "writer" : "active"); |
| 761 | |
| 762 | if (op_w == 0) |
| 763 | EVENTHANDLER_INVOKE(bpf_track, bp->bif_ifp, bp->bif_dlt, 1); |
| 764 | } |
| 765 | |
| 766 | /* |
| 767 | * Check if we need to upgrade our descriptor @d from write-only mode. |
no test coverage detected