bpf.c (6a068746777241722b2b32c5d0bc443a2a64d80b) | bpf.c (6c74ff0ea6eb5eb3a21d05486740c9488721a8b5) |
---|---|
1/*- 2 * Copyright (c) 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from the Stanford/CMU enet packet filter, 6 * (net/enet.c) distributed as part of 4.3BSD, and code contributed 7 * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 8 * Berkeley Laboratory. --- 133 unchanged lines hidden (view full) --- 142 * frames, ethernet frames, etc). 143 */ 144static LIST_HEAD(, bpf_if) bpf_iflist; 145static struct mtx bpf_mtx; /* bpf global lock */ 146static int bpf_bpfd_cnt; 147 148static void bpf_attachd(struct bpf_d *, struct bpf_if *); 149static void bpf_detachd(struct bpf_d *); | 1/*- 2 * Copyright (c) 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from the Stanford/CMU enet packet filter, 6 * (net/enet.c) distributed as part of 4.3BSD, and code contributed 7 * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 8 * Berkeley Laboratory. --- 133 unchanged lines hidden (view full) --- 142 * frames, ethernet frames, etc). 143 */ 144static LIST_HEAD(, bpf_if) bpf_iflist; 145static struct mtx bpf_mtx; /* bpf global lock */ 146static int bpf_bpfd_cnt; 147 148static void bpf_attachd(struct bpf_d *, struct bpf_if *); 149static void bpf_detachd(struct bpf_d *); |
150static void bpf_detachd_locked(struct bpf_d *); |
|
150static void bpf_freed(struct bpf_d *); 151static int bpf_movein(struct uio *, int, struct ifnet *, struct mbuf **, 152 struct sockaddr *, int *, struct bpf_insn *); 153static int bpf_setif(struct bpf_d *, struct ifreq *); 154static void bpf_timed_out(void *); 155static __inline void 156 bpf_wakeup(struct bpf_d *); 157static void catchpacket(struct bpf_d *, u_char *, u_int, u_int, --- 44 unchanged lines hidden (view full) --- 202 203static struct filterops bpfread_filtops = { 204 .f_isfd = 1, 205 .f_detach = filt_bpfdetach, 206 .f_event = filt_bpfread, 207}; 208 209/* | 151static void bpf_freed(struct bpf_d *); 152static int bpf_movein(struct uio *, int, struct ifnet *, struct mbuf **, 153 struct sockaddr *, int *, struct bpf_insn *); 154static int bpf_setif(struct bpf_d *, struct ifreq *); 155static void bpf_timed_out(void *); 156static __inline void 157 bpf_wakeup(struct bpf_d *); 158static void catchpacket(struct bpf_d *, u_char *, u_int, u_int, --- 44 unchanged lines hidden (view full) --- 203 204static struct filterops bpfread_filtops = { 205 .f_isfd = 1, 206 .f_detach = filt_bpfdetach, 207 .f_event = filt_bpfread, 208}; 209 210/* |
211 * LOCKING MODEL USED BY BPF: 212 * Locks: 213 * 1) global lock (BPF_LOCK). Mutex, used to protect interface addition/removal, 214 * some global counters and every bpf_if reference. 215 * 2) Interface lock. Rwlock, used to protect list of BPF descriptors and their filters. 216 * 3) Descriptor lock. Rwlock, used to protect BPF buffers and various structure fields 217 * used by bpf_mtap code. 218 * 219 * Lock order: 220 * 221 * Global lock, interface lock, descriptor lock 222 * 223 * We have to acquire interface lock before descriptor main lock due to BPF_MTAP[2] 224 * working model. In many places (like bpf_detachd) we start with BPF descriptor 225 * (and we need to at least rlock it to get reliable interface pointer). This 226 * gives us potential LOR. As a result, we use global lock to protect from bpf_if 227 * change in every such place. 228 * 229 * Changing d->bd_bif is protected by 1) global lock, 2) interface lock and 230 * 3) descriptor main wlock. 231 * Reading bd_bif can be protected by any of these locks, typically global lock. 232 * 233 * Changing read/write BPF filter is protected by the same three locks, 234 * the same applies for reading. 235 * 236 * Sleeping in global lock is not allowed due to bpfdetach() using it. 237 */ 238 239/* |
|
210 * Wrapper functions for various buffering methods. If the set of buffer 211 * modes expands, we will probably want to introduce a switch data structure 212 * similar to protosw, et. 213 */ 214static void 215bpf_append_bytes(struct bpf_d *d, caddr_t buf, u_int offset, void *src, 216 u_int len) 217{ --- 354 unchanged lines hidden (view full) --- 572} 573 574/* 575 * Attach file to the bpf interface, i.e. make d listen on bp. 576 */ 577static void 578bpf_attachd(struct bpf_d *d, struct bpf_if *bp) 579{ | 240 * Wrapper functions for various buffering methods. If the set of buffer 241 * modes expands, we will probably want to introduce a switch data structure 242 * similar to protosw, et. 243 */ 244static void 245bpf_append_bytes(struct bpf_d *d, caddr_t buf, u_int offset, void *src, 246 u_int len) 247{ --- 354 unchanged lines hidden (view full) --- 602} 603 604/* 605 * Attach file to the bpf interface, i.e. make d listen on bp. 606 */ 607static void 608bpf_attachd(struct bpf_d *d, struct bpf_if *bp) 609{ |
610 int op_w; 611 612 BPF_LOCK_ASSERT(); 613 |
|
580 /* | 614 /* |
615 * Save sysctl value to protect from sysctl change 616 * between reads 617 */ 618 op_w = V_bpf_optimize_writers; 619 620 if (d->bd_bif != NULL) 621 bpf_detachd_locked(d); 622 /* |
|
581 * Point d at bp, and add d to the interface's list. 582 * Since there are many applicaiotns using BPF for 583 * sending raw packets only (dhcpd, cdpd are good examples) 584 * we can delay adding d to the list of active listeners until 585 * some filter is configured. 586 */ | 623 * Point d at bp, and add d to the interface's list. 624 * Since there are many applicaiotns using BPF for 625 * sending raw packets only (dhcpd, cdpd are good examples) 626 * we can delay adding d to the list of active listeners until 627 * some filter is configured. 628 */ |
587 d->bd_bif = bp; | |
588 589 BPFIF_WLOCK(bp); | 629 630 BPFIF_WLOCK(bp); |
631 BPFD_WLOCK(d); |
|
590 | 632 |
591 if (V_bpf_optimize_writers != 0) { | 633 d->bd_bif = bp; 634 635 if (op_w != 0) { |
592 /* Add to writers-only list */ 593 LIST_INSERT_HEAD(&bp->bif_wlist, d, bd_next); 594 /* 595 * We decrement bd_writer on every filter set operation. 596 * First BIOCSETF is done by pcap_open_live() to set up 597 * snap length. After that appliation usually sets its own filter 598 */ 599 d->bd_writer = 2; 600 } else 601 LIST_INSERT_HEAD(&bp->bif_dlist, d, bd_next); 602 | 636 /* Add to writers-only list */ 637 LIST_INSERT_HEAD(&bp->bif_wlist, d, bd_next); 638 /* 639 * We decrement bd_writer on every filter set operation. 640 * First BIOCSETF is done by pcap_open_live() to set up 641 * snap length. After that appliation usually sets its own filter 642 */ 643 d->bd_writer = 2; 644 } else 645 LIST_INSERT_HEAD(&bp->bif_dlist, d, bd_next); 646 |
647 BPFD_WUNLOCK(d); |
|
603 BPFIF_WUNLOCK(bp); 604 | 648 BPFIF_WUNLOCK(bp); 649 |
605 BPF_LOCK(); | |
606 bpf_bpfd_cnt++; | 650 bpf_bpfd_cnt++; |
607 BPF_UNLOCK(); | |
608 609 CTR3(KTR_NET, "%s: bpf_attach called by pid %d, adding to %s list", 610 __func__, d->bd_pid, d->bd_writer ? "writer" : "active"); 611 | 651 652 CTR3(KTR_NET, "%s: bpf_attach called by pid %d, adding to %s list", 653 __func__, d->bd_pid, d->bd_writer ? "writer" : "active"); 654 |
612 if (V_bpf_optimize_writers == 0) | 655 if (op_w == 0) |
613 EVENTHANDLER_INVOKE(bpf_track, bp->bif_ifp, bp->bif_dlt, 1); 614} 615 616/* 617 * Add d to the list of active bp filters. 618 * Reuqires bpf_attachd() to be called before 619 */ 620static void 621bpf_upgraded(struct bpf_d *d) 622{ 623 struct bpf_if *bp; 624 | 656 EVENTHANDLER_INVOKE(bpf_track, bp->bif_ifp, bp->bif_dlt, 1); 657} 658 659/* 660 * Add d to the list of active bp filters. 661 * Reuqires bpf_attachd() to be called before 662 */ 663static void 664bpf_upgraded(struct bpf_d *d) 665{ 666 struct bpf_if *bp; 667 |
668 BPF_LOCK_ASSERT(); 669 |
|
625 bp = d->bd_bif; 626 | 670 bp = d->bd_bif; 671 |
672 /* 673 * Filter can be set several times without specifying interface. 674 * Mark d as reader and exit. 675 */ 676 if (bp == NULL) { 677 BPFD_WLOCK(d); 678 d->bd_writer = 0; 679 BPFD_WUNLOCK(d); 680 return; 681 } 682 |
|
627 BPFIF_WLOCK(bp); 628 BPFD_WLOCK(d); 629 630 /* Remove from writers-only list */ 631 LIST_REMOVE(d, bd_next); 632 LIST_INSERT_HEAD(&bp->bif_dlist, d, bd_next); 633 /* Mark d as reader */ 634 d->bd_writer = 0; --- 7 unchanged lines hidden (view full) --- 642} 643 644/* 645 * Detach a file from its interface. 646 */ 647static void 648bpf_detachd(struct bpf_d *d) 649{ | 683 BPFIF_WLOCK(bp); 684 BPFD_WLOCK(d); 685 686 /* Remove from writers-only list */ 687 LIST_REMOVE(d, bd_next); 688 LIST_INSERT_HEAD(&bp->bif_dlist, d, bd_next); 689 /* Mark d as reader */ 690 d->bd_writer = 0; --- 7 unchanged lines hidden (view full) --- 698} 699 700/* 701 * Detach a file from its interface. 702 */ 703static void 704bpf_detachd(struct bpf_d *d) 705{ |
706 BPF_LOCK(); 707 bpf_detachd_locked(d); 708 BPF_UNLOCK(); 709} 710 711static void 712bpf_detachd_locked(struct bpf_d *d) 713{ |
|
650 int error; 651 struct bpf_if *bp; 652 struct ifnet *ifp; 653 654 CTR2(KTR_NET, "%s: detach required by pid %d", __func__, d->bd_pid); 655 656 BPF_LOCK_ASSERT(); 657 | 714 int error; 715 struct bpf_if *bp; 716 struct ifnet *ifp; 717 718 CTR2(KTR_NET, "%s: detach required by pid %d", __func__, d->bd_pid); 719 720 BPF_LOCK_ASSERT(); 721 |
658 bp = d->bd_bif; | 722 /* Check if descriptor is attached */ 723 if ((bp = d->bd_bif) == NULL) 724 return; 725 |
659 BPFIF_WLOCK(bp); 660 BPFD_WLOCK(d); 661 662 /* Save bd_writer value */ 663 error = d->bd_writer; 664 665 /* 666 * Remove d from the interface's descriptor list. 667 */ 668 LIST_REMOVE(d, bd_next); 669 670 ifp = bp->bif_ifp; 671 d->bd_bif = NULL; 672 BPFD_WUNLOCK(d); 673 BPFIF_WUNLOCK(bp); 674 | 726 BPFIF_WLOCK(bp); 727 BPFD_WLOCK(d); 728 729 /* Save bd_writer value */ 730 error = d->bd_writer; 731 732 /* 733 * Remove d from the interface's descriptor list. 734 */ 735 LIST_REMOVE(d, bd_next); 736 737 ifp = bp->bif_ifp; 738 d->bd_bif = NULL; 739 BPFD_WUNLOCK(d); 740 BPFIF_WUNLOCK(bp); 741 |
675 /* We're already protected by global lock. */ | |
676 bpf_bpfd_cnt--; 677 678 /* Call event handler iff d is attached */ 679 if (error == 0) 680 EVENTHANDLER_INVOKE(bpf_track, ifp, bp->bif_dlt, 0); 681 682 /* 683 * Check if this descriptor had requested promiscuous mode. --- 27 unchanged lines hidden (view full) --- 711 struct bpf_d *d = data; 712 713 BPFD_WLOCK(d); 714 if (d->bd_state == BPF_WAITING) 715 callout_stop(&d->bd_callout); 716 d->bd_state = BPF_IDLE; 717 BPFD_WUNLOCK(d); 718 funsetown(&d->bd_sigio); | 742 bpf_bpfd_cnt--; 743 744 /* Call event handler iff d is attached */ 745 if (error == 0) 746 EVENTHANDLER_INVOKE(bpf_track, ifp, bp->bif_dlt, 0); 747 748 /* 749 * Check if this descriptor had requested promiscuous mode. --- 27 unchanged lines hidden (view full) --- 777 struct bpf_d *d = data; 778 779 BPFD_WLOCK(d); 780 if (d->bd_state == BPF_WAITING) 781 callout_stop(&d->bd_callout); 782 d->bd_state = BPF_IDLE; 783 BPFD_WUNLOCK(d); 784 funsetown(&d->bd_sigio); |
719 BPF_LOCK(); 720 if (d->bd_bif) 721 bpf_detachd(d); 722 BPF_UNLOCK(); | 785 bpf_detachd(d); |
723#ifdef MAC 724 mac_bpfdesc_destroy(d); 725#endif /* MAC */ 726 seldrain(&d->bd_sel); 727 knlist_destroy(&d->bd_sel.si_note); 728 callout_drain(&d->bd_callout); 729 bpf_freed(d); 730 free(d, M_BPF); --- 223 unchanged lines hidden (view full) --- 954 int error, hlen; 955 956 error = devfs_get_cdevpriv((void **)&d); 957 if (error != 0) 958 return (error); 959 960 BPF_PID_REFRESH_CUR(d); 961 d->bd_wcount++; | 786#ifdef MAC 787 mac_bpfdesc_destroy(d); 788#endif /* MAC */ 789 seldrain(&d->bd_sel); 790 knlist_destroy(&d->bd_sel.si_note); 791 callout_drain(&d->bd_callout); 792 bpf_freed(d); 793 free(d, M_BPF); --- 223 unchanged lines hidden (view full) --- 1017 int error, hlen; 1018 1019 error = devfs_get_cdevpriv((void **)&d); 1020 if (error != 0) 1021 return (error); 1022 1023 BPF_PID_REFRESH_CUR(d); 1024 d->bd_wcount++; |
1025 /* XXX: locking required */ |
|
962 if (d->bd_bif == NULL) { 963 d->bd_wdcount++; 964 return (ENXIO); 965 } 966 967 ifp = d->bd_bif->bif_ifp; 968 969 if ((ifp->if_flags & IFF_UP) == 0) { --- 4 unchanged lines hidden (view full) --- 974 if (uio->uio_resid == 0) { 975 d->bd_wdcount++; 976 return (0); 977 } 978 979 bzero(&dst, sizeof(dst)); 980 m = NULL; 981 hlen = 0; | 1026 if (d->bd_bif == NULL) { 1027 d->bd_wdcount++; 1028 return (ENXIO); 1029 } 1030 1031 ifp = d->bd_bif->bif_ifp; 1032 1033 if ((ifp->if_flags & IFF_UP) == 0) { --- 4 unchanged lines hidden (view full) --- 1038 if (uio->uio_resid == 0) { 1039 d->bd_wdcount++; 1040 return (0); 1041 } 1042 1043 bzero(&dst, sizeof(dst)); 1044 m = NULL; 1045 hlen = 0; |
1046 /* XXX: bpf_movein() can sleep */ |
|
982 error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, ifp, 983 &m, &dst, &hlen, d->bd_wfilter); 984 if (error) { 985 d->bd_wdcount++; 986 return (error); 987 } 988 d->bd_wfcount++; 989 if (d->bd_hdrcmplt) --- 303 unchanged lines hidden (view full) --- 1293 else 1294 error = bpf_getdltlist(d, (struct bpf_dltlist *)addr); 1295 break; 1296 1297 /* 1298 * Set data link type. 1299 */ 1300 case BIOCSDLT: | 1047 error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, ifp, 1048 &m, &dst, &hlen, d->bd_wfilter); 1049 if (error) { 1050 d->bd_wdcount++; 1051 return (error); 1052 } 1053 d->bd_wfcount++; 1054 if (d->bd_hdrcmplt) --- 303 unchanged lines hidden (view full) --- 1358 else 1359 error = bpf_getdltlist(d, (struct bpf_dltlist *)addr); 1360 break; 1361 1362 /* 1363 * Set data link type. 1364 */ 1365 case BIOCSDLT: |
1366 BPF_LOCK(); |
|
1301 if (d->bd_bif == NULL) 1302 error = EINVAL; 1303 else 1304 error = bpf_setdlt(d, *(u_int *)addr); | 1367 if (d->bd_bif == NULL) 1368 error = EINVAL; 1369 else 1370 error = bpf_setdlt(d, *(u_int *)addr); |
1371 BPF_UNLOCK(); |
|
1305 break; 1306 1307 /* 1308 * Get interface name. 1309 */ 1310 case BIOCGETIF: 1311 if (d->bd_bif == NULL) 1312 error = EINVAL; --- 5 unchanged lines hidden (view full) --- 1318 sizeof(ifr->ifr_name)); 1319 } 1320 break; 1321 1322 /* 1323 * Set interface. 1324 */ 1325 case BIOCSETIF: | 1372 break; 1373 1374 /* 1375 * Get interface name. 1376 */ 1377 case BIOCGETIF: 1378 if (d->bd_bif == NULL) 1379 error = EINVAL; --- 5 unchanged lines hidden (view full) --- 1385 sizeof(ifr->ifr_name)); 1386 } 1387 break; 1388 1389 /* 1390 * Set interface. 1391 */ 1392 case BIOCSETIF: |
1393 BPF_LOCK(); |
|
1326 error = bpf_setif(d, (struct ifreq *)addr); | 1394 error = bpf_setif(d, (struct ifreq *)addr); |
1395 BPF_UNLOCK(); |
|
1327 break; 1328 1329 /* 1330 * Set read timeout. 1331 */ 1332 case BIOCSRTIMEOUT: 1333#if defined(COMPAT_FREEBSD32) && !defined(__mips__) 1334 case BIOCSRTIMEOUT32: --- 269 unchanged lines hidden (view full) --- 1604 fp32 = (struct bpf_program32 *)fp; 1605 fp_swab.bf_len = fp32->bf_len; 1606 fp_swab.bf_insns = (struct bpf_insn *)(uintptr_t)fp32->bf_insns; 1607 fp = &fp_swab; 1608 if (cmd == BIOCSETWF32) 1609 cmd = BIOCSETWF; 1610 } 1611#endif | 1396 break; 1397 1398 /* 1399 * Set read timeout. 1400 */ 1401 case BIOCSRTIMEOUT: 1402#if defined(COMPAT_FREEBSD32) && !defined(__mips__) 1403 case BIOCSRTIMEOUT32: --- 269 unchanged lines hidden (view full) --- 1673 fp32 = (struct bpf_program32 *)fp; 1674 fp_swab.bf_len = fp32->bf_len; 1675 fp_swab.bf_insns = (struct bpf_insn *)(uintptr_t)fp32->bf_insns; 1676 fp = &fp_swab; 1677 if (cmd == BIOCSETWF32) 1678 cmd = BIOCSETWF; 1679 } 1680#endif |
1681 /* 1682 * Check new filter validness before acquiring any locks. 1683 * Allocate memory for new filter, if needed. 1684 */ 1685 flen = fp->bf_len; 1686 if ((flen > bpf_maxinsns) || ((fp->bf_insns == NULL) && (flen != 0))) 1687 return (EINVAL); 1688 1689 need_upgrade = 0; 1690 size = flen * sizeof(*fp->bf_insns); 1691 if (size > 0) 1692 fcode = (struct bpf_insn *)malloc(size, M_BPF, M_WAITOK); 1693 else 1694 fcode = NULL; /* Make compiler happy */ 1695 1696 BPF_LOCK(); 1697 |
|
1612 if (cmd == BIOCSETWF) { 1613 old = d->bd_wfilter; 1614 wfilter = 1; 1615#ifdef BPF_JITTER 1616 ofunc = NULL; 1617#endif 1618 } else { 1619 wfilter = 0; 1620 old = d->bd_rfilter; 1621#ifdef BPF_JITTER 1622 ofunc = d->bd_bfilter; 1623#endif 1624 } 1625 if (fp->bf_insns == NULL) { | 1698 if (cmd == BIOCSETWF) { 1699 old = d->bd_wfilter; 1700 wfilter = 1; 1701#ifdef BPF_JITTER 1702 ofunc = NULL; 1703#endif 1704 } else { 1705 wfilter = 0; 1706 old = d->bd_rfilter; 1707#ifdef BPF_JITTER 1708 ofunc = d->bd_bfilter; 1709#endif 1710 } 1711 if (fp->bf_insns == NULL) { |
1626 if (fp->bf_len != 0) 1627 return (EINVAL); | |
1628 /* | 1712 /* |
1629 * Protect filter change by interface lock, too. 1630 * The same lock order is used by bpf_detachd(). | 1713 * Protect filter removal by interface lock. 1714 * Additionally, we are protected by global lock here. |
1631 */ | 1715 */ |
1632 BPFIF_WLOCK(d->bd_bif); | 1716 if (d->bd_bif != NULL) 1717 BPFIF_WLOCK(d->bd_bif); |
1633 BPFD_WLOCK(d); 1634 if (wfilter) 1635 d->bd_wfilter = NULL; 1636 else { 1637 d->bd_rfilter = NULL; 1638#ifdef BPF_JITTER 1639 d->bd_bfilter = NULL; 1640#endif 1641 if (cmd == BIOCSETF) 1642 reset_d(d); 1643 } 1644 BPFD_WUNLOCK(d); | 1718 BPFD_WLOCK(d); 1719 if (wfilter) 1720 d->bd_wfilter = NULL; 1721 else { 1722 d->bd_rfilter = NULL; 1723#ifdef BPF_JITTER 1724 d->bd_bfilter = NULL; 1725#endif 1726 if (cmd == BIOCSETF) 1727 reset_d(d); 1728 } 1729 BPFD_WUNLOCK(d); |
1645 BPFIF_WUNLOCK(d->bd_bif); | 1730 if (d->bd_bif != NULL) 1731 BPFIF_WUNLOCK(d->bd_bif); |
1646 if (old != NULL) 1647 free((caddr_t)old, M_BPF); 1648#ifdef BPF_JITTER 1649 if (ofunc != NULL) 1650 bpf_destroy_jit_filter(ofunc); 1651#endif | 1732 if (old != NULL) 1733 free((caddr_t)old, M_BPF); 1734#ifdef BPF_JITTER 1735 if (ofunc != NULL) 1736 bpf_destroy_jit_filter(ofunc); 1737#endif |
1738 BPF_UNLOCK(); |
|
1652 return (0); 1653 } | 1739 return (0); 1740 } |
1654 flen = fp->bf_len; 1655 if (flen > bpf_maxinsns) 1656 return (EINVAL); | |
1657 | 1741 |
1658 need_upgrade = 0; 1659 size = flen * sizeof(*fp->bf_insns); 1660 fcode = (struct bpf_insn *)malloc(size, M_BPF, M_WAITOK); | |
1661 if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 && 1662 bpf_validate(fcode, (int)flen)) { 1663 /* | 1742 if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 && 1743 bpf_validate(fcode, (int)flen)) { 1744 /* |
1664 * Protect filter change by interface lock, too 1665 * The same lock order is used by bpf_detachd(). | 1745 * Protect filter change by interface lock 1746 * Additionally, we are protected by global lock here. |
1666 */ | 1747 */ |
1667 BPFIF_WLOCK(d->bd_bif); | 1748 if (d->bd_bif != NULL) 1749 BPFIF_WLOCK(d->bd_bif); |
1668 BPFD_WLOCK(d); 1669 if (wfilter) 1670 d->bd_wfilter = fcode; 1671 else { 1672 d->bd_rfilter = fcode; 1673#ifdef BPF_JITTER 1674 d->bd_bfilter = bpf_jitter(fcode, flen); 1675#endif --- 6 unchanged lines hidden (view full) --- 1682 */ 1683 if ((d->bd_writer != 0) && (--d->bd_writer == 0)) 1684 need_upgrade = 1; 1685 CTR4(KTR_NET, "%s: filter function set by pid %d, " 1686 "bd_writer counter %d, need_upgrade %d", 1687 __func__, d->bd_pid, d->bd_writer, need_upgrade); 1688 } 1689 BPFD_WUNLOCK(d); | 1750 BPFD_WLOCK(d); 1751 if (wfilter) 1752 d->bd_wfilter = fcode; 1753 else { 1754 d->bd_rfilter = fcode; 1755#ifdef BPF_JITTER 1756 d->bd_bfilter = bpf_jitter(fcode, flen); 1757#endif --- 6 unchanged lines hidden (view full) --- 1764 */ 1765 if ((d->bd_writer != 0) && (--d->bd_writer == 0)) 1766 need_upgrade = 1; 1767 CTR4(KTR_NET, "%s: filter function set by pid %d, " 1768 "bd_writer counter %d, need_upgrade %d", 1769 __func__, d->bd_pid, d->bd_writer, need_upgrade); 1770 } 1771 BPFD_WUNLOCK(d); |
1690 BPFIF_WUNLOCK(d->bd_bif); | 1772 if (d->bd_bif != NULL) 1773 BPFIF_WUNLOCK(d->bd_bif); |
1691 if (old != NULL) 1692 free((caddr_t)old, M_BPF); 1693#ifdef BPF_JITTER 1694 if (ofunc != NULL) 1695 bpf_destroy_jit_filter(ofunc); 1696#endif 1697 1698 /* Move d to active readers list */ 1699 if (need_upgrade != 0) 1700 bpf_upgraded(d); 1701 | 1774 if (old != NULL) 1775 free((caddr_t)old, M_BPF); 1776#ifdef BPF_JITTER 1777 if (ofunc != NULL) 1778 bpf_destroy_jit_filter(ofunc); 1779#endif 1780 1781 /* Move d to active readers list */ 1782 if (need_upgrade != 0) 1783 bpf_upgraded(d); 1784 |
1785 BPF_UNLOCK(); |
|
1702 return (0); 1703 } 1704 free((caddr_t)fcode, M_BPF); | 1786 return (0); 1787 } 1788 free((caddr_t)fcode, M_BPF); |
1789 BPF_UNLOCK(); |
|
1705 return (EINVAL); 1706} 1707 1708/* 1709 * Detach a file from its current interface (if attached at all) and attach 1710 * to the interface indicated by the name stored in ifr. 1711 * Return an errno or 0. 1712 */ 1713static int 1714bpf_setif(struct bpf_d *d, struct ifreq *ifr) 1715{ 1716 struct bpf_if *bp; 1717 struct ifnet *theywant; 1718 | 1790 return (EINVAL); 1791} 1792 1793/* 1794 * Detach a file from its current interface (if attached at all) and attach 1795 * to the interface indicated by the name stored in ifr. 1796 * Return an errno or 0. 1797 */ 1798static int 1799bpf_setif(struct bpf_d *d, struct ifreq *ifr) 1800{ 1801 struct bpf_if *bp; 1802 struct ifnet *theywant; 1803 |
1804 BPF_LOCK_ASSERT(); 1805 |
|
1719 theywant = ifunit(ifr->ifr_name); 1720 if (theywant == NULL || theywant->if_bpf == NULL) 1721 return (ENXIO); 1722 1723 bp = theywant->if_bpf; 1724 1725 /* 1726 * Behavior here depends on the buffering model. If we're using --- 14 unchanged lines hidden (view full) --- 1741 case BPF_BUFMODE_ZBUF: 1742 if (d->bd_sbuf == NULL) 1743 return (EINVAL); 1744 break; 1745 1746 default: 1747 panic("bpf_setif: bufmode %d", d->bd_bufmode); 1748 } | 1806 theywant = ifunit(ifr->ifr_name); 1807 if (theywant == NULL || theywant->if_bpf == NULL) 1808 return (ENXIO); 1809 1810 bp = theywant->if_bpf; 1811 1812 /* 1813 * Behavior here depends on the buffering model. If we're using --- 14 unchanged lines hidden (view full) --- 1828 case BPF_BUFMODE_ZBUF: 1829 if (d->bd_sbuf == NULL) 1830 return (EINVAL); 1831 break; 1832 1833 default: 1834 panic("bpf_setif: bufmode %d", d->bd_bufmode); 1835 } |
1749 if (bp != d->bd_bif) { 1750 if (d->bd_bif) 1751 /* 1752 * Detach if attached to something else. 1753 */ 1754 bpf_detachd(d); 1755 | 1836 if (bp != d->bd_bif) |
1756 bpf_attachd(d, bp); | 1837 bpf_attachd(d, bp); |
1757 } | |
1758 BPFD_WLOCK(d); 1759 reset_d(d); 1760 BPFD_WUNLOCK(d); 1761 return (0); 1762} 1763 1764/* 1765 * Support for select() and poll() system calls --- 590 unchanged lines hidden (view full) --- 2356 2357 bp->bif_hdrlen = hdrlen; 2358 2359 if (bootverbose) 2360 if_printf(ifp, "bpf attached\n"); 2361} 2362 2363/* | 1838 BPFD_WLOCK(d); 1839 reset_d(d); 1840 BPFD_WUNLOCK(d); 1841 return (0); 1842} 1843 1844/* 1845 * Support for select() and poll() system calls --- 590 unchanged lines hidden (view full) --- 2436 2437 bp->bif_hdrlen = hdrlen; 2438 2439 if (bootverbose) 2440 if_printf(ifp, "bpf attached\n"); 2441} 2442 2443/* |
2364 * Detach bpf from an interface. This involves detaching each descriptor 2365 * associated with the interface, and leaving bd_bif NULL. Notify each 2366 * descriptor as it's detached so that any sleepers wake up and get 2367 * ENXIO. | 2444 * Detach bpf from an interface. This involves detaching each descriptor 2445 * associated with the interface. Notify each descriptor as it's detached 2446 * so that any sleepers wake up and get ENXIO. |
2368 */ 2369void 2370bpfdetach(struct ifnet *ifp) 2371{ 2372 struct bpf_if *bp; 2373 struct bpf_d *d; 2374#ifdef INVARIANTS 2375 int ndetached; --- 17 unchanged lines hidden (view full) --- 2393 ndetached++; 2394#endif 2395 while ((d = LIST_FIRST(&bp->bif_dlist)) != NULL) { 2396 bpf_detachd(d); 2397 BPFD_WLOCK(d); 2398 bpf_wakeup(d); 2399 BPFD_WUNLOCK(d); 2400 } | 2447 */ 2448void 2449bpfdetach(struct ifnet *ifp) 2450{ 2451 struct bpf_if *bp; 2452 struct bpf_d *d; 2453#ifdef INVARIANTS 2454 int ndetached; --- 17 unchanged lines hidden (view full) --- 2472 ndetached++; 2473#endif 2474 while ((d = LIST_FIRST(&bp->bif_dlist)) != NULL) { 2475 bpf_detachd(d); 2476 BPFD_WLOCK(d); 2477 bpf_wakeup(d); 2478 BPFD_WUNLOCK(d); 2479 } |
2480 /* Free writer-only descriptors */ 2481 while ((d = LIST_FIRST(&bp->bif_wlist)) != NULL) { 2482 bpf_detachd(d); 2483 BPFD_WLOCK(d); 2484 bpf_wakeup(d); 2485 BPFD_WUNLOCK(d); 2486 } |
|
2401 rw_destroy(&bp->bif_lock); 2402 free(bp, M_BPF); 2403 } 2404 } while (bp != NULL); 2405 2406#ifdef INVARIANTS 2407 if (ndetached == 0) 2408 printf("bpfdetach: %s was not attached\n", ifp->if_xname); --- 37 unchanged lines hidden (view full) --- 2446 */ 2447static int 2448bpf_setdlt(struct bpf_d *d, u_int dlt) 2449{ 2450 int error, opromisc; 2451 struct ifnet *ifp; 2452 struct bpf_if *bp; 2453 | 2487 rw_destroy(&bp->bif_lock); 2488 free(bp, M_BPF); 2489 } 2490 } while (bp != NULL); 2491 2492#ifdef INVARIANTS 2493 if (ndetached == 0) 2494 printf("bpfdetach: %s was not attached\n", ifp->if_xname); --- 37 unchanged lines hidden (view full) --- 2532 */ 2533static int 2534bpf_setdlt(struct bpf_d *d, u_int dlt) 2535{ 2536 int error, opromisc; 2537 struct ifnet *ifp; 2538 struct bpf_if *bp; 2539 |
2540 BPF_LOCK_ASSERT(); 2541 |
|
2454 if (d->bd_bif->bif_dlt == dlt) 2455 return (0); 2456 ifp = d->bd_bif->bif_ifp; | 2542 if (d->bd_bif->bif_dlt == dlt) 2543 return (0); 2544 ifp = d->bd_bif->bif_ifp; |
2457 BPF_LOCK(); | 2545 |
2458 LIST_FOREACH(bp, &bpf_iflist, bif_next) { 2459 if (bp->bif_ifp == ifp && bp->bif_dlt == dlt) 2460 break; 2461 } | 2546 LIST_FOREACH(bp, &bpf_iflist, bif_next) { 2547 if (bp->bif_ifp == ifp && bp->bif_dlt == dlt) 2548 break; 2549 } |
2462 BPF_UNLOCK(); | 2550 |
2463 if (bp != NULL) { 2464 opromisc = d->bd_promisc; | 2551 if (bp != NULL) { 2552 opromisc = d->bd_promisc; |
2465 bpf_detachd(d); | |
2466 bpf_attachd(d, bp); 2467 BPFD_WLOCK(d); 2468 reset_d(d); 2469 BPFD_WUNLOCK(d); 2470 if (opromisc) { 2471 error = ifpromisc(bp->bif_ifp, 1); 2472 if (error) 2473 if_printf(bp->bif_ifp, --- 43 unchanged lines hidden (view full) --- 2517 bd->bd_zcopy = 0; 2518 BPFD_WUNLOCK(bd); 2519 } 2520 BPFIF_RUNLOCK(bp); 2521 } 2522 BPF_UNLOCK(); 2523} 2524 | 2553 bpf_attachd(d, bp); 2554 BPFD_WLOCK(d); 2555 reset_d(d); 2556 BPFD_WUNLOCK(d); 2557 if (opromisc) { 2558 error = ifpromisc(bp->bif_ifp, 1); 2559 if (error) 2560 if_printf(bp->bif_ifp, --- 43 unchanged lines hidden (view full) --- 2604 bd->bd_zcopy = 0; 2605 BPFD_WUNLOCK(bd); 2606 } 2607 BPFIF_RUNLOCK(bp); 2608 } 2609 BPF_UNLOCK(); 2610} 2611 |
2612/* 2613 * Fill filter statistics 2614 */ |
|
2525static void 2526bpfstats_fill_xbpf(struct xbpf_d *d, struct bpf_d *bd) 2527{ 2528 2529 bzero(d, sizeof(*d)); 2530 BPFD_LOCK_ASSERT(bd); 2531 d->bd_structsize = sizeof(*d); | 2615static void 2616bpfstats_fill_xbpf(struct xbpf_d *d, struct bpf_d *bd) 2617{ 2618 2619 bzero(d, sizeof(*d)); 2620 BPFD_LOCK_ASSERT(bd); 2621 d->bd_structsize = sizeof(*d); |
2622 /* XXX: reading should be protected by global lock */ |
|
2532 d->bd_immediate = bd->bd_immediate; 2533 d->bd_promisc = bd->bd_promisc; 2534 d->bd_hdrcmplt = bd->bd_hdrcmplt; 2535 d->bd_direction = bd->bd_direction; 2536 d->bd_feedback = bd->bd_feedback; 2537 d->bd_async = bd->bd_async; 2538 d->bd_rcount = bd->bd_rcount; 2539 d->bd_dcount = bd->bd_dcount; --- 8 unchanged lines hidden (view full) --- 2548 d->bd_locked = bd->bd_locked; 2549 d->bd_wcount = bd->bd_wcount; 2550 d->bd_wdcount = bd->bd_wdcount; 2551 d->bd_wfcount = bd->bd_wfcount; 2552 d->bd_zcopy = bd->bd_zcopy; 2553 d->bd_bufmode = bd->bd_bufmode; 2554} 2555 | 2623 d->bd_immediate = bd->bd_immediate; 2624 d->bd_promisc = bd->bd_promisc; 2625 d->bd_hdrcmplt = bd->bd_hdrcmplt; 2626 d->bd_direction = bd->bd_direction; 2627 d->bd_feedback = bd->bd_feedback; 2628 d->bd_async = bd->bd_async; 2629 d->bd_rcount = bd->bd_rcount; 2630 d->bd_dcount = bd->bd_dcount; --- 8 unchanged lines hidden (view full) --- 2639 d->bd_locked = bd->bd_locked; 2640 d->bd_wcount = bd->bd_wcount; 2641 d->bd_wdcount = bd->bd_wdcount; 2642 d->bd_wfcount = bd->bd_wfcount; 2643 d->bd_zcopy = bd->bd_zcopy; 2644 d->bd_bufmode = bd->bd_bufmode; 2645} 2646 |
2647/* 2648 * Handle `netstat -B' stats request 2649 */ |
|
2556static int 2557bpf_stats_sysctl(SYSCTL_HANDLER_ARGS) 2558{ 2559 struct xbpf_d *xbdbuf, *xbd, zerostats; 2560 int index, error; 2561 struct bpf_if *bp; 2562 struct bpf_d *bd; 2563 --- 117 unchanged lines hidden --- | 2650static int 2651bpf_stats_sysctl(SYSCTL_HANDLER_ARGS) 2652{ 2653 struct xbpf_d *xbdbuf, *xbd, zerostats; 2654 int index, error; 2655 struct bpf_if *bp; 2656 struct bpf_d *bd; 2657 --- 117 unchanged lines hidden --- |