Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102155613
D45928.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
D45928.diff
View Options
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -135,6 +135,7 @@
ds1307.4 \
ds3231.4 \
${_dtrace_provs} \
+ dummymbuf.4 \
dummynet.4 \
edsc.4 \
ehci.4 \
diff --git a/share/man/man4/dummymbuf.4 b/share/man/man4/dummymbuf.4
new file mode 100644
--- /dev/null
+++ b/share/man/man4/dummymbuf.4
@@ -0,0 +1,209 @@
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.\" Copyright (c) 2024 Igor Ostapenko <pm@igoro.pro>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" Note: The date here should be updated whenever a non-trivial
+.\" change is made to the manual page.
+.Dd August 2, 2024
+.Dt DUMMYMBUF 4
+.Os
+.Sh NAME
+.Nm dummymbuf
+.Nd "mbuf alteration pfil hooks"
+.Sh SYNOPSIS
+To compile the driver into the kernel,
+place the following line in the
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device dummymbuf"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+dummymbuf_load="YES"
+.Ed
+.Sh DESCRIPTION
+This module is intended to test networking code in the face of unusual mbuf
+layouts.
+The special
+.Xr pfil 9
+hooks are provided for mbuf alteration and can be listed with
+.Xr pfilctl 8
+as follows:
+.Bd -literal -offset indent
+ Hook Type
+ dummymbuf:ethernet Ethernet
+ dummymbuf:inet6 IPv6
+ dummymbuf:inet IPv4
+.Ed
+.Pp
+To activate a hook it must be linked to the respective
+.Xr pfil 9
+head.
+.Xr pfilctl 8
+can be used for the linking.
+.Pp
+Each time a hook is invoked it reads a single shared set of
+.Sx RULES
+from
+.Va net.dummymbuf.rules
+sysctl.
+The rules are evaluated sequentially and each matching rule performs the
+specified operation over the mbuf.
+.Pp
+After every successfully applied operation the
+.Va net.dummymbuf.hits
+sysctl counter is increased.
+.Pp
+A hook returns an altered mbuf for further processing, but it drops a packet
+if rules parsing or an operation fails.
+Also, the first mbuf of the original chain may be changed.
+.Pp
+The module is
+.Xr VNET 9
+based, hence every
+.Xr jail 2
+provides its own set of hooks and sysctl variables.
+.Sh RULES
+The set of rules is a semicolon separated list.
+An empty string is treated as a parsing failure.
+A rule conceptually has two parts, filter and operation, with the following
+syntax:
+.Bd -literal -offset indent
+{inet | inet6 | ethernet} {in | out} <ifname> <opname>[ <opargs>];
+.Ed
+.Ss Filter
+The first word of a rule matches
+.Xr pfil 9
+type.
+The second matches packet's direction, and the third matches the network
+interface a packet is coming from.
+.Ss Operation
+An operation may have arguments separated from its name by space.
+The available operations are:
+.Bl -tag -width indent
+.It pull-head <number-of-bytes>
+Unconditionally creates a brand new cluster-based mbuf and links it to be the
+first mbuf of the original mbuf chain, with respective packet header moving.
+After, the given number of bytes are pulled from the original mbuf chain.
+.Pp
+If it is asked to pull 0 bytes then the first mbuf of the resulting chain will
+be left empty.
+Asking to pull more than
+.Dv MCLBYTES
+is treated as an operation failure.
+If a mbuf chain has less data than asked then the entire packet is pulled with
+tail mbuf(s) left empty.
+.Pp
+As a result, only the layout of a mbuf chain is altered, its content logically
+is left intact.
+.El
+.Sh SYSCTL VARIABLES
+The following variables are available:
+.Bl -tag -width indent
+.It Va net.dummymbuf.rules
+A string representing a single set of
+.Sx RULES
+shared among all
+.Nm
+hooks.
+.It Va net.dummymbuf.hits
+Number of times a rule has been applied.
+It is reset to zero upon writing.
+.El
+.Sh EXAMPLES
+As it was intended,
+.Nm
+can be found useful for firewall testing.
+A mbuf chain could be altered before it hits a firewall to test that the latter
+can handle a case respectively.
+Thus, it is important to have correct sequence of hooks.
+A test case should prepare and enable a firewall first to get its hooks linked.
+After, the
+.Xr pfilctl 8
+should be used to link
+.Nm
+hook(s) to put them in front of a firewall.
+.Pp
+The following links
+.Va dummymbuf:inet6
+hook for inbound and puts it in front of other hooks:
+.Bd -literal -offset indent
+pfilctl link -i dummymbuf:inet6 inet6
+.Ed
+.Pp
+And this does the same for outbound:
+.Bd -literal -offset indent
+pfilctl link -o -a dummymbuf:inet6 inet6
+.Ed
+.Pp
+For instance, we want to test a scenario in which the very first mbuf in a
+chain has zero m_len, to verify that a firewall can correctly read the
+packet data despite that.
+The following set of rules does it for inbound and outbound:
+.Bd -literal -offset indent
+sysctl net.dummymbuf.rules="inet6 in em0 pull-head 0; inet6 out em0 pull-head 0;"
+.Ed
+.Pp
+It is encouraged to verify
+.Va net.dummymbuf.hits
+sysctl counter along with other test assertions to make sure that
+.Nm
+really does its work and there is no false positive due to misconfiguration.
+It is a good idea to reset it before the action:
+.Bd -literal -offset indent
+sysctl net.dummymbuf.hits=0
+.Ed
+.Pp
+It is equally important to cleanup the things after the test case:
+.Bd -literal -offset indent
+pfilctl unlink -i dummymbuf:inet6 inet6
+pfilctl unlink -o dummymbuf:inet6 inet6
+sysctl net.dummymbuf.rules=""
+.Ed
+.Pp
+If a test case operates within a temporary vnet then explicit cleanup can be
+omitted, the
+.Nm
+facilities will vanish along with its vnet instance.
+.Sh DIAGNOSTICS
+.Bl -diag
+.It "dummymbuf: <filter match>: rule parsing failed: <the rule in question>"
+If everything looks fine then extra spaces removal may help due to the parser
+is kept very simple.
+.It "dummymbuf: <filter match>: mbuf operation failed: <the rule in question>"
+Incorrect operation argument has been found, mbuf allocation has failed, etc.
+.El
+.Sh SEE ALSO
+.Xr jail 2 ,
+.Xr pfilctl 8 ,
+.Xr mbuf 9 ,
+.Xr pfil 9 ,
+.Xr VNET 9
+.Sh AUTHORS
+The module and this manual page were written by
+.An Igor Ostapenko Aq Mt pm@igoro.pro .
diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -4151,6 +4151,7 @@
net/bpf_filter.c optional bpf | netgraph_bpf
net/bpf_zerocopy.c optional bpf
net/bridgestp.c optional bridge | if_bridge
+net/dummymbuf.c optional dummymbuf
net/ieee8023ad_lacp.c optional lagg
net/if.c standard
net/ifq.c standard
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -100,6 +100,7 @@
${_dpdk_lpm4} \
${_dpdk_lpm6} \
${_dpms} \
+ dummymbuf \
dummynet \
${_dwwdt} \
${_e6000sw} \
diff --git a/sys/modules/dummymbuf/Makefile b/sys/modules/dummymbuf/Makefile
new file mode 100644
--- /dev/null
+++ b/sys/modules/dummymbuf/Makefile
@@ -0,0 +1,9 @@
+.PATH: ${SRCTOP}/sys/net
+
+KMOD= dummymbuf
+SRCS= dummymbuf.c
+SRCS+= opt_inet.h opt_inet6.h
+
+EXPORT_SYMS= YES
+
+.include <bsd.kmod.mk>
diff --git a/sys/net/dummymbuf.c b/sys/net/dummymbuf.c
new file mode 100644
--- /dev/null
+++ b/sys/net/dummymbuf.c
@@ -0,0 +1,436 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 Igor Ostapenko <pm@igoro.pro>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "opt_inet.h"
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/vnet.h>
+#include <net/pfil.h>
+
+/*
+ * Separate sysctl sub-tree
+ */
+
+SYSCTL_NODE(_net, OID_AUTO, dummymbuf, 0, NULL,
+ "Dummy mbuf sysctl");
+
+/*
+ * Rules
+ */
+
+static MALLOC_DEFINE(M_DUMMYMBUF_RULES, "dummymbuf_rules",
+ "dummymbuf rules string buffer");
+
+#define RULES_MAXLEN 1024
+VNET_DEFINE_STATIC(char *, dmb_rules) = NULL;
+#define V_dmb_rules VNET(dmb_rules)
+
+VNET_DEFINE_STATIC(struct sx, dmb_rules_lock);
+#define V_dmb_rules_lock VNET(dmb_rules_lock)
+
+#define DMB_RULES_SLOCK() sx_slock(&V_dmb_rules_lock)
+#define DMB_RULES_SUNLOCK() sx_sunlock(&V_dmb_rules_lock)
+#define DMB_RULES_XLOCK() sx_xlock(&V_dmb_rules_lock)
+#define DMB_RULES_XUNLOCK() sx_xunlock(&V_dmb_rules_lock)
+
+static int
+dmb_sysctl_handle_rules(SYSCTL_HANDLER_ARGS)
+{
+ int error = 0;
+ char empty = '\0';
+ char **rulesp = (char **)arg1;
+
+ if (req->newptr == NULL) {
+ // read only
+ DMB_RULES_SLOCK();
+ arg1 = *rulesp;
+ if (arg1 == NULL) {
+ arg1 = ∅
+ arg2 = 0;
+ }
+ error = sysctl_handle_string(oidp, arg1, arg2, req);
+ DMB_RULES_SUNLOCK();
+ } else {
+ // read and write
+ DMB_RULES_XLOCK();
+ if (*rulesp == NULL)
+ *rulesp = malloc(arg2, M_DUMMYMBUF_RULES, M_WAITOK);
+ arg1 = *rulesp;
+ error = sysctl_handle_string(oidp, arg1, arg2, req);
+ DMB_RULES_XUNLOCK();
+ }
+
+ return (error);
+}
+
+SYSCTL_PROC(_net_dummymbuf, OID_AUTO, rules,
+ CTLTYPE_STRING | CTLFLAG_MPSAFE | CTLFLAG_RW | CTLFLAG_VNET,
+ &VNET_NAME(dmb_rules), RULES_MAXLEN, dmb_sysctl_handle_rules, "A",
+ "{inet | inet6 | ethernet} {in | out} <ifname> <opname>[ <opargs>];"
+ " ...;");
+
+/*
+ * Statistics
+ */
+
+VNET_DEFINE_STATIC(counter_u64_t, dmb_hits);
+#define V_dmb_hits VNET(dmb_hits)
+SYSCTL_PROC(_net_dummymbuf, OID_AUTO, hits,
+ CTLTYPE_U64 | CTLFLAG_MPSAFE | CTLFLAG_STATS | CTLFLAG_RW | CTLFLAG_VNET,
+ &VNET_NAME(dmb_hits), 0, sysctl_handle_counter_u64,
+ "QU", "Number of times a rule has been applied");
+
+/*
+ * pfil(9) context
+ */
+
+VNET_DEFINE_STATIC(pfil_hook_t, dmb_pfil_inet_hook);
+#define V_dmb_pfil_inet_hook VNET(dmb_pfil_inet_hook)
+
+VNET_DEFINE_STATIC(pfil_hook_t, dmb_pfil_inet6_hook);
+#define V_dmb_pfil_inet6_hook VNET(dmb_pfil_inet6_hook)
+
+VNET_DEFINE_STATIC(pfil_hook_t, dmb_pfil_ethernet_hook);
+#define V_dmb_pfil_ethernet_hook VNET(dmb_pfil_ethernet_hook)
+
+/*
+ * Logging
+ */
+
+#define FEEDBACK(pfil_type, pfil_flags, ifp, rule, msg) \
+ printf("dummymbuf: %s %b %s: %s: %.*s\n", \
+ (pfil_type == PFIL_TYPE_IP4 ? "PFIL_TYPE_IP4" : \
+ pfil_type == PFIL_TYPE_IP6 ? "PFIL_TYPE_IP6" : \
+ pfil_type == PFIL_TYPE_ETHERNET ? "PFIL_TYPE_ETHERNET" : \
+ "PFIL_TYPE_UNKNOWN"), \
+ (pfil_flags), "\20\21PFIL_IN\22PFIL_OUT", \
+ (ifp)->if_xname, \
+ (msg), \
+ (rule).syntax_len, (rule).syntax_begin \
+ )
+
+/*
+ * Internals
+ */
+
+struct rule;
+typedef struct mbuf * (*op_t)(struct mbuf *, struct rule *);
+struct rule {
+ const char *syntax_begin;
+ int syntax_len;
+ int pfil_type;
+ int pfil_dir;
+ char ifname[IFNAMSIZ];
+ op_t op;
+ const char *opargs;
+};
+
+static struct mbuf *
+dmb_m_pull_head(struct mbuf *m, struct rule *rule)
+{
+ struct mbuf *n;
+ int count;
+
+ count = (int)strtol(rule->opargs, NULL, 10);
+ if (count < 0 || count > MCLBYTES)
+ goto bad;
+
+ if (!(m->m_flags & M_PKTHDR))
+ goto bad;
+ if (m->m_pkthdr.len <= 0)
+ return (m);
+ if (count > m->m_pkthdr.len)
+ count = m->m_pkthdr.len;
+
+ if ((n = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR)) == NULL)
+ goto bad;
+
+ m_move_pkthdr(n, m);
+ m_copydata(m, 0, count, n->m_ext.ext_buf);
+ n->m_len = count;
+
+ m_adj(m, count);
+ n->m_next = m;
+
+ return (n);
+
+bad:
+ m_freem(m);
+ return (NULL);
+}
+
+static bool
+read_rule(const char **cur, struct rule *rule)
+{
+ // {inet | inet6 | ethernet} {in | out} <ifname> <opname>[ <opargs>];
+
+ rule->syntax_begin = NULL;
+ rule->syntax_len = 0;
+
+ if (*cur == NULL)
+ return (false);
+
+ // syntax_begin
+ while (**cur == ' ')
+ (*cur)++;
+ rule->syntax_begin = *cur;
+
+ // syntax_len
+ char *delim = strchr(*cur, ';');
+ if (delim == NULL)
+ return (false);
+ rule->syntax_len = (int)(delim - *cur + 1);
+
+ // pfil_type
+ if (strstr(*cur, "inet6") == *cur) {
+ rule->pfil_type = PFIL_TYPE_IP6;
+ *cur += strlen("inet6");
+ } else if (strstr(*cur, "inet") == *cur) {
+ rule->pfil_type = PFIL_TYPE_IP4;
+ *cur += strlen("inet");
+ } else if (strstr(*cur, "ethernet")) {
+ rule->pfil_type = PFIL_TYPE_ETHERNET;
+ *cur += strlen("ethernet");
+ } else {
+ return (false);
+ }
+ while (**cur == ' ')
+ (*cur)++;
+
+ // pfil_dir
+ if (strstr(*cur, "in") == *cur) {
+ rule->pfil_dir = PFIL_IN;
+ *cur += strlen("in");
+ } else if (strstr(*cur, "out") == *cur) {
+ rule->pfil_dir = PFIL_OUT;
+ *cur += strlen("out");
+ } else {
+ return (false);
+ }
+ while (**cur == ' ')
+ (*cur)++;
+
+ // ifname
+ char *sp = strchr(*cur, ' ');
+ if (sp == NULL || sp > delim)
+ return (false);
+ size_t len = sp - *cur;
+ if (len >= sizeof(rule->ifname))
+ return (false);
+ strncpy(rule->ifname, *cur, len);
+ rule->ifname[len] = 0;
+ *cur = sp;
+ while (**cur == ' ')
+ (*cur)++;
+
+ // opname
+ if (strstr(*cur, "pull-head") == *cur) {
+ rule->op = dmb_m_pull_head;
+ *cur += strlen("pull-head");
+ } else {
+ return (false);
+ }
+ while (**cur == ' ')
+ (*cur)++;
+
+ // opargs
+ if (*cur > delim)
+ return (false);
+ rule->opargs = *cur;
+
+ *cur = delim + 1;
+
+ return (true);
+}
+
+static pfil_return_t
+dmb_pfil_mbuf_chk(int pfil_type, struct mbuf **mp, struct ifnet *ifp,
+ int flags, void *ruleset, void *unused)
+{
+ struct mbuf *m = *mp;
+ const char *cursor;
+ bool parsed;
+ struct rule rule;
+
+ DMB_RULES_SLOCK();
+ cursor = V_dmb_rules;
+ while ((parsed = read_rule(&cursor, &rule))) {
+ if (rule.pfil_type == pfil_type &&
+ rule.pfil_dir == (flags & rule.pfil_dir) &&
+ strcmp(rule.ifname, ifp->if_xname) == 0) {
+ m = rule.op(m, &rule);
+ if (m == NULL) {
+ FEEDBACK(pfil_type, flags, ifp, rule,
+ "mbuf operation failed");
+ break;
+ }
+ counter_u64_add(V_dmb_hits, 1);
+ }
+ if (strlen(cursor) == 0)
+ break;
+ }
+ if (!parsed) {
+ FEEDBACK(pfil_type, flags, ifp, rule, "rule parsing failed");
+ m_freem(m);
+ m = NULL;
+ }
+ DMB_RULES_SUNLOCK();
+
+ if (m == NULL) {
+ *mp = NULL;
+ return (PFIL_DROPPED);
+ }
+ if (m != *mp) {
+ *mp = m;
+ return (PFIL_REALLOCED);
+ }
+
+ return (PFIL_PASS);
+}
+
+static pfil_return_t
+dmb_pfil_inet_mbuf_chk(struct mbuf **mp, struct ifnet *ifp, int flags,
+ void *ruleset, struct inpcb *inp)
+{
+ return (dmb_pfil_mbuf_chk(PFIL_TYPE_IP4, mp, ifp, flags,
+ ruleset, inp));
+}
+
+static pfil_return_t
+dmb_pfil_inet6_mbuf_chk(struct mbuf **mp, struct ifnet *ifp, int flags,
+ void *ruleset, struct inpcb *inp)
+{
+ return (dmb_pfil_mbuf_chk(PFIL_TYPE_IP6, mp, ifp, flags,
+ ruleset, inp));
+}
+
+static pfil_return_t
+dmb_pfil_ethernet_mbuf_chk(struct mbuf **mp, struct ifnet *ifp, int flags,
+ void *ruleset, struct inpcb *inp)
+{
+ return (dmb_pfil_mbuf_chk(PFIL_TYPE_ETHERNET, mp, ifp, flags,
+ ruleset, inp));
+}
+
+static void
+dmb_pfil_init(void)
+{
+ struct pfil_hook_args pha = {
+ .pa_version = PFIL_VERSION,
+ .pa_modname = "dummymbuf",
+ .pa_flags = PFIL_IN | PFIL_OUT,
+ };
+
+#ifdef INET
+ pha.pa_type = PFIL_TYPE_IP4;
+ pha.pa_mbuf_chk = dmb_pfil_inet_mbuf_chk;
+ pha.pa_rulname = "inet";
+ V_dmb_pfil_inet_hook = pfil_add_hook(&pha);
+#endif
+
+#ifdef INET6
+ pha.pa_type = PFIL_TYPE_IP6;
+ pha.pa_mbuf_chk = dmb_pfil_inet6_mbuf_chk;
+ pha.pa_rulname = "inet6";
+ V_dmb_pfil_inet6_hook = pfil_add_hook(&pha);
+#endif
+
+ pha.pa_type = PFIL_TYPE_ETHERNET;
+ pha.pa_mbuf_chk = dmb_pfil_ethernet_mbuf_chk;
+ pha.pa_rulname = "ethernet";
+ V_dmb_pfil_ethernet_hook = pfil_add_hook(&pha);
+}
+
+static void
+dmb_pfil_uninit(void)
+{
+#ifdef INET
+ pfil_remove_hook(V_dmb_pfil_inet_hook);
+#endif
+
+#ifdef INET6
+ pfil_remove_hook(V_dmb_pfil_inet6_hook);
+#endif
+
+ pfil_remove_hook(V_dmb_pfil_ethernet_hook);
+}
+
+static void
+vnet_dmb_init(void *unused __unused)
+{
+ sx_init(&V_dmb_rules_lock, "dummymbuf rules");
+ V_dmb_hits = counter_u64_alloc(M_WAITOK);
+ dmb_pfil_init();
+}
+VNET_SYSINIT(vnet_dmb_init, SI_SUB_PROTO_PFIL, SI_ORDER_ANY,
+ vnet_dmb_init, NULL);
+
+static void
+vnet_dmb_uninit(void *unused __unused)
+{
+ dmb_pfil_uninit();
+ counter_u64_free(V_dmb_hits);
+ sx_destroy(&V_dmb_rules_lock);
+ free(V_dmb_rules, M_DUMMYMBUF_RULES);
+}
+VNET_SYSUNINIT(vnet_dmb_uninit, SI_SUB_PROTO_PFIL, SI_ORDER_ANY,
+ vnet_dmb_uninit, NULL);
+
+static int
+dmb_modevent(module_t mod __unused, int event, void *arg __unused)
+{
+ int error = 0;
+
+ switch (event) {
+ case MOD_LOAD:
+ case MOD_UNLOAD:
+ break;
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+
+ return (error);
+}
+
+static moduledata_t dmb_mod = {
+ "dummymbuf",
+ dmb_modevent,
+ NULL
+};
+
+DECLARE_MODULE(dummymbuf, dmb_mod, SI_SUB_PROTO_PFIL, SI_ORDER_ANY);
+MODULE_VERSION(dummymbuf, 1);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 9, 7:35 AM (21 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14553335
Default Alt Text
D45928.diff (18 KB)
Attached To
Mode
D45928: Add dummymbuf module for testing purposes
Attached
Detach File
Event Timeline
Log In to Comment