The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=1615eff94cda8619561b73186ec8098cc8b14c5c
commit 1615eff94cda8619561b73186ec8098cc8b14c5c Author: Gleb Smirnoff <[email protected]> AuthorDate: 2025-12-15 20:51:58 +0000 Commit: Gleb Smirnoff <[email protected]> CommitDate: 2025-12-15 21:17:23 +0000 usb: don't create ifnet(9) for usbus devices Differential Revision: https://reviews.freebsd.org/D54063 --- sys/dev/usb/usb_bus.h | 2 +- sys/dev/usb/usb_pf.c | 189 ++++----------------------------------------- sys/netinet6/in6.c | 1 - usr.sbin/usbdump/usbdump.c | 23 ------ 4 files changed, 14 insertions(+), 201 deletions(-) diff --git a/sys/dev/usb/usb_bus.h b/sys/dev/usb/usb_bus.h index ad7b661c2ac0..53b911e86d4e 100644 --- a/sys/dev/usb/usb_bus.h +++ b/sys/dev/usb/usb_bus.h @@ -106,7 +106,7 @@ struct usb_bus { const struct usb_bus_methods *methods; /* filled by HC driver */ struct usb_device **devices; - struct ifnet *ifp; /* only for USB Packet Filter */ + struct bpf_if *bpf; /* USB Packet Filter */ usb_power_mask_t hw_power_state; /* see USB_HW_POWER_XXX */ usb_size_t uframe_usage[USB_HS_MICRO_FRAMES_MAX]; diff --git a/sys/dev/usb/usb_pf.c b/sys/dev/usb/usb_pf.c index 0e7a75d04d6a..4d2dff1ad704 100644 --- a/sys/dev/usb/usb_pf.c +++ b/sys/dev/usb/usb_pf.c @@ -43,15 +43,11 @@ #include <sys/fcntl.h> #include <sys/malloc.h> #include <sys/proc.h> +#include <sys/epoch.h> #include <sys/socket.h> #include <sys/sockio.h> -#include <net/if.h> -#include <net/if_var.h> -#include <net/if_types.h> -#include <net/if_clone.h> #include <net/bpf.h> #include <sys/sysctl.h> -#include <net/route.h> #include <dev/usb/usb.h> #include <dev/usb/usbdi.h> @@ -65,182 +61,25 @@ #include <dev/usb/usb_transfer.h> #endif /* USB_GLOBAL_INCLUDE_FILE */ -static void usbpf_init(void *); -static void usbpf_uninit(void *); -static int usbpf_ioctl(if_t, u_long, caddr_t); -static int usbpf_clone_match(struct if_clone *, const char *); -static int usbpf_clone_create(struct if_clone *, char *, size_t, - struct ifc_data *, if_t *); -static int usbpf_clone_destroy(struct if_clone *, if_t, uint32_t); -static struct usb_bus *usbpf_ifname2ubus(const char *); static uint32_t usbpf_aggregate_xferflags(struct usb_xfer_flags *); static uint32_t usbpf_aggregate_status(struct usb_xfer_flags_int *); static int usbpf_xfer_frame_is_read(struct usb_xfer *, uint32_t); static uint32_t usbpf_xfer_precompute_size(struct usb_xfer *, int); -static struct if_clone *usbpf_cloner; -static const char usbusname[] = "usbus"; - -SYSINIT(usbpf_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_init, NULL); -SYSUNINIT(usbpf_uninit, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, usbpf_uninit, NULL); - -static void -usbpf_init(void *arg) -{ - struct if_clone_addreq req = { - .match_f = usbpf_clone_match, - .create_f = usbpf_clone_create, - .destroy_f = usbpf_clone_destroy, - }; - - usbpf_cloner = ifc_attach_cloner(usbusname, &req); -} - -static void -usbpf_uninit(void *arg) -{ - int devlcnt; - device_t *devlp; - devclass_t dc; - struct usb_bus *ubus; - int error; - int i; - - if_clone_detach(usbpf_cloner); - - dc = devclass_find(usbusname); - if (dc == NULL) - return; - error = devclass_get_devices(dc, &devlp, &devlcnt); - if (error) - return; - for (i = 0; i < devlcnt; i++) { - ubus = device_get_softc(devlp[i]); - if (ubus != NULL && ubus->ifp != NULL) - usbpf_clone_destroy(usbpf_cloner, ubus->ifp, 0); - } - free(devlp, M_TEMP); -} - -static int -usbpf_ioctl(if_t ifp, u_long cmd, caddr_t data) -{ - - /* No configuration allowed. */ - return (EINVAL); -} - -static struct usb_bus * -usbpf_ifname2ubus(const char *ifname) -{ - device_t dev; - devclass_t dc; - int unit; - int error; - - if (strncmp(ifname, usbusname, sizeof(usbusname) - 1) != 0) - return (NULL); - error = ifc_name2unit(ifname, &unit); - if (error || unit < 0) - return (NULL); - dc = devclass_find(usbusname); - if (dc == NULL) - return (NULL); - dev = devclass_get_device(dc, unit); - if (dev == NULL) - return (NULL); - - return (device_get_softc(dev)); -} - -static int -usbpf_clone_match(struct if_clone *ifc, const char *name) -{ - struct usb_bus *ubus; - - ubus = usbpf_ifname2ubus(name); - if (ubus == NULL) - return (0); - if (ubus->ifp != NULL) - return (0); - - return (1); -} - -static int -usbpf_clone_create(struct if_clone *ifc, char *name, size_t len, - struct ifc_data *ifd, if_t *ifpp) -{ - int error; - int unit; - if_t ifp; - struct usb_bus *ubus; - - error = ifc_name2unit(name, &unit); - if (error) - return (error); - if (unit < 0) - return (EINVAL); - - ubus = usbpf_ifname2ubus(name); - if (ubus == NULL) - return (1); - if (ubus->ifp != NULL) - return (1); - - error = ifc_alloc_unit(ifc, &unit); - if (error) { - device_printf(ubus->parent, "usbpf: Could not allocate " - "instance\n"); - return (error); - } - ifp = ubus->ifp = if_alloc(IFT_USB); - if_setsoftc(ifp, ubus); - if_initname(ifp, usbusname, unit); - if_setname(ifp, name); - if_setioctlfn(ifp, usbpf_ioctl); - if_attach(ifp); - if_setflagbits(ifp, IFF_UP, 0); - rt_ifmsg(ifp, IFF_UP); +static const struct bif_methods bpf_usb_methods = { /* - * XXX According to the specification of DLT_USB, it indicates - * packets beginning with USB setup header. But not sure all - * packets would be. + * XXXGL: bpf_tap() doesn't check direction, but we actually can + * report it and make USB dumping able to match direction. */ - bpfattach(ifp, DLT_USB, USBPF_HDR_LEN); - *ifpp = ifp; - - return (0); -} - -static int -usbpf_clone_destroy(struct if_clone *ifc, if_t ifp, uint32_t flags) -{ - struct usb_bus *ubus; - int unit; - - ubus = if_getsoftc(ifp); - unit = if_getdunit(ifp); - - /* - * Lock USB before clearing the "ifp" pointer, to avoid - * clearing the pointer in the middle of a TAP operation: - */ - USB_BUS_LOCK(ubus); - ubus->ifp = NULL; - USB_BUS_UNLOCK(ubus); - bpfdetach(ifp); - if_detach(ifp); - if_free(ifp); - ifc_free_unit(ifc, unit); - - return (0); -} + .bif_chkdir = NULL +}; void usbpf_attach(struct usb_bus *ubus) { + ubus->bpf = bpf_attach(device_get_nameunit(ubus->bdev), DLT_USB, + USBPF_HDR_LEN, &bpf_usb_methods, ubus); if (bootverbose) device_printf(ubus->parent, "usbpf: Attached\n"); } @@ -249,8 +88,7 @@ void usbpf_detach(struct usb_bus *ubus) { - if (ubus->ifp != NULL) - usbpf_clone_destroy(usbpf_cloner, ubus->ifp, 0); + bpf_detach(ubus->bpf); if (bootverbose) device_printf(ubus->parent, "usbpf: Detached\n"); } @@ -387,6 +225,7 @@ usbpf_xfer_precompute_size(struct usb_xfer *xfer, int type) void usbpf_xfertap(struct usb_xfer *xfer, int type) { + struct epoch_tracker et; struct usb_bus *bus; struct usbpf_pkthdr *up; struct usbpf_framehdr *uf; @@ -401,10 +240,6 @@ usbpf_xfertap(struct usb_xfer *xfer, int type) bus = xfer->xroot->bus; - /* sanity checks */ - if (bus->ifp == NULL || !bpf_peers_present_if(bus->ifp)) - return; - totlen = usbpf_xfer_precompute_size(xfer, type); if (type == USBPF_XFERTAP_SUBMIT) @@ -525,7 +360,9 @@ usbpf_xfertap(struct usb_xfer *xfer, int type) } } - bpf_tap_if(bus->ifp, buf, totlen); + NET_EPOCH_ENTER(et); + bpf_tap(bus->bpf, buf, totlen); + NET_EPOCH_EXIT(et); free(buf, M_TEMP); } diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index f64b9292e4b5..158129258587 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -2584,7 +2584,6 @@ in6_domifattach(struct ifnet *ifp) switch (ifp->if_type) { case IFT_PFLOG: case IFT_PFSYNC: - case IFT_USB: return (NULL); } ext = (struct in6_ifextra *)malloc(sizeof(*ext), M_IFADDR, M_WAITOK); diff --git a/usr.sbin/usbdump/usbdump.c b/usr.sbin/usbdump/usbdump.c index 887e2baeed26..40956e11a450 100644 --- a/usr.sbin/usbdump/usbdump.c +++ b/usr.sbin/usbdump/usbdump.c @@ -824,7 +824,6 @@ main(int argc, char *argv[]) int o; int filt_unit; int filt_ep; - int s; int ifindex; const char *optstring; char *pp; @@ -959,17 +958,6 @@ main(int argc, char *argv[]) /* clear ifr structure */ memset(&ifr, 0, sizeof(ifr)); - /* Try to create usbusN interface if it is not available. */ - s = socket(AF_LOCAL, SOCK_DGRAM, 0); - if (s < 0) - errx(EXIT_FAILURE, "Could not open a socket"); - ifindex = if_nametoindex(i_arg); - if (ifindex == 0) { - (void)strlcpy(ifr.ifr_name, i_arg, sizeof(ifr.ifr_name)); - if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) - errx(EXIT_FAILURE, "Invalid bus interface: %s", i_arg); - } - for ( ; v >= USBPF_HDR_LEN; v >>= 1) { (void)ioctl(fd, BIOCSBLEN, (caddr_t)&v); (void)strlcpy(ifr.ifr_name, i_arg, sizeof(ifr.ifr_name)); @@ -1013,17 +1001,6 @@ main(int argc, char *argv[]) printf("%d packets received by filter\n", us.bs_recv); printf("%d packets dropped by kernel\n", us.bs_drop); - /* - * Destroy the usbusN interface only if it was created by - * usbdump(8). Ignore when it was already destroyed. - */ - if (ifindex == 0 && if_nametoindex(i_arg) > 0) { - (void)strlcpy(ifr.ifr_name, i_arg, sizeof(ifr.ifr_name)); - if (ioctl(s, SIOCIFDESTROY, &ifr) < 0) - warn("SIOCIFDESTROY ioctl failed"); - } - close(s); - if (p->fd > 0) close(p->fd); if (p->rfd > 0)
