aboutsummaryrefslogtreecommitdiff
path: root/sys/netpfil
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2025-12-15 20:51:42 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2025-12-15 21:17:23 +0000
commitddf4f9eda9c295082f17e7f26963666b72c97bb9 (patch)
tree8cc1d84404118fba9370711f2c9031c0186273a4 /sys/netpfil
parent94b76ea9d136723d6f05c42f450c802fb4a91600 (diff)
Diffstat (limited to 'sys/netpfil')
-rw-r--r--sys/netpfil/ipfw/ip_fw_bpf.c146
1 files changed, 26 insertions, 120 deletions
diff --git a/sys/netpfil/ipfw/ip_fw_bpf.c b/sys/netpfil/ipfw/ip_fw_bpf.c
index 155e269214ec..68f31ca59b2e 100644
--- a/sys/netpfil/ipfw/ip_fw_bpf.c
+++ b/sys/netpfil/ipfw/ip_fw_bpf.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 2016 Yandex LLC
* Copyright (c) 2016 Andrey V. Elsukov <ae@FreeBSD.org>
+ * Copyright (c) 2025 Gleb Smirnoff <glebius@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -29,14 +30,11 @@
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/lock.h>
+#include <sys/rwlock.h>
#include <sys/socket.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_pflog.h>
-#include <net/if_var.h>
-#include <net/if_clone.h>
-#include <net/if_private.h>
-#include <net/if_types.h>
#include <net/vnet.h>
#include <net/bpf.h>
@@ -45,158 +43,66 @@
#include <netinet/ip_var.h>
#include <netpfil/ipfw/ip_fw_private.h>
-VNET_DEFINE_STATIC(struct ifnet *, log_if);
-VNET_DEFINE_STATIC(struct ifnet *, pflog_if);
-VNET_DEFINE_STATIC(struct if_clone *, ipfw_cloner);
-VNET_DEFINE_STATIC(struct if_clone *, ipfwlog_cloner);
-#define V_ipfw_cloner VNET(ipfw_cloner)
-#define V_ipfwlog_cloner VNET(ipfwlog_cloner)
-#define V_log_if VNET(log_if)
-#define V_pflog_if VNET(pflog_if)
-
-static const char ipfwname[] = "ipfw";
-static const char ipfwlogname[] = "ipfwlog";
-
-static int
-ipfw_bpf_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
-{
-
- return (EINVAL);
-}
-
-static int
-ipfw_bpf_output(struct ifnet *ifp, struct mbuf *m,
- const struct sockaddr *dst, struct route *ro)
+static bool
+bpf_ipfw_chkdir(void *arg __unused, const struct mbuf *m, int dir)
{
-
- if (m != NULL)
- FREE_PKT(m);
- return (0);
+ return ((dir == BPF_D_IN && m_rcvif(m) == NULL) ||
+ (dir == BPF_D_OUT && m_rcvif(m) != NULL));
}
-static void
-ipfw_clone_destroy(struct ifnet *ifp)
-{
-
- if (ifp->if_hdrlen == ETHER_HDR_LEN)
- V_log_if = NULL;
- else
- V_pflog_if = NULL;
+static const struct bif_methods bpf_ipfw_methods = {
+ .bif_chkdir = bpf_ipfw_chkdir,
+};
- NET_EPOCH_WAIT();
- bpfdetach(ifp);
- if_detach(ifp);
- if_free(ifp);
-}
+static const char ipfwname[] = "ipfw0";
+static const char ipfwlogname[] = "ipfwlog0";
-static int
-ipfw_clone_create(struct if_clone *ifc, int unit, caddr_t params)
-{
- struct ifnet *ifp;
-
- ifp = if_alloc(IFT_PFLOG);
- if_initname(ifp, ipfwname, unit);
- ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_mtu = 65536;
- ifp->if_ioctl = ipfw_bpf_ioctl;
- ifp->if_output = ipfw_bpf_output;
- ifp->if_hdrlen = ETHER_HDR_LEN;
- if_attach(ifp);
- bpfattach(ifp, DLT_EN10MB, ETHER_HDR_LEN);
- if (V_log_if != NULL) {
- bpfdetach(ifp);
- if_detach(ifp);
- if_free(ifp);
- return (EEXIST);
- }
- V_log_if = ifp;
- return (0);
-}
-
-static int
-ipfwlog_clone_create(struct if_clone *ifc, int unit, caddr_t params)
-{
- struct ifnet *ifp;
-
- ifp = if_alloc(IFT_PFLOG);
- if_initname(ifp, ipfwlogname, unit);
- ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_mtu = 65536;
- ifp->if_ioctl = ipfw_bpf_ioctl;
- ifp->if_output = ipfw_bpf_output;
- ifp->if_hdrlen = PFLOG_HDRLEN;
- if_attach(ifp);
- bpfattach(ifp, DLT_PFLOG, PFLOG_HDRLEN);
- if (V_pflog_if != NULL) {
- bpfdetach(ifp);
- if_detach(ifp);
- if_free(ifp);
- return (EEXIST);
- }
- V_pflog_if = ifp;
- return (0);
-}
+VNET_DEFINE_STATIC(struct bpf_if *, bpf_en10mb);
+VNET_DEFINE_STATIC(struct bpf_if *, bpf_pflog);
+#define V_bpf_en10mb VNET(bpf_en10mb)
+#define V_bpf_pflog VNET(bpf_pflog)
void
ipfw_bpf_tap(u_char *pkt, u_int pktlen)
{
- struct ifnet *ifp = V_log_if;
-
- NET_EPOCH_ASSERT();
- if (ifp != NULL)
- BPF_TAP(ifp, pkt, pktlen);
+ bpf_tap(V_bpf_en10mb, pkt, pktlen);
}
void
ipfw_bpf_mtap(struct mbuf *m)
{
- struct ifnet *ifp = V_log_if;
-
- NET_EPOCH_ASSERT();
- if (ifp != NULL)
- BPF_MTAP(ifp, m);
+ bpf_mtap(V_bpf_en10mb, m);
}
void
ipfw_bpf_mtap2(void *data, u_int dlen, struct mbuf *m)
{
- struct ifnet *logif;
-
- NET_EPOCH_ASSERT();
switch (dlen) {
case (ETHER_HDR_LEN):
- logif = V_log_if;
+ bpf_mtap2(V_bpf_en10mb, data, dlen, m);
break;
case (PFLOG_HDRLEN):
- logif = V_pflog_if;
+ bpf_mtap2(V_bpf_pflog, data, dlen, m);
break;
default:
-#ifdef INVARIANTS
- panic("%s: unsupported len %d", __func__, dlen);
-#endif
- logif = NULL;
+ MPASS(0);
}
-
- if (logif != NULL)
- BPF_MTAP2(logif, data, dlen, m);
}
void
ipfw_bpf_init(int first __unused)
{
- V_log_if = NULL;
- V_pflog_if = NULL;
- V_ipfw_cloner = if_clone_simple(ipfwname, ipfw_clone_create,
- ipfw_clone_destroy, 0);
- V_ipfwlog_cloner = if_clone_simple(ipfwlogname, ipfwlog_clone_create,
- ipfw_clone_destroy, 0);
+ V_bpf_en10mb = bpf_attach(ipfwname, DLT_EN10MB, ETHER_HDR_LEN,
+ &bpf_ipfw_methods, NULL);
+ V_bpf_pflog = bpf_attach(ipfwlogname, DLT_PFLOG, PFLOG_HDRLEN,
+ &bpf_ipfw_methods, NULL);
}
void
ipfw_bpf_uninit(int last __unused)
{
- if_clone_detach(V_ipfw_cloner);
- if_clone_detach(V_ipfwlog_cloner);
+ bpf_detach(V_bpf_en10mb);
+ bpf_detach(V_bpf_pflog);
}