Reference

dummymbuf(4)

mbuf alteration pfil hooks

NAME

dummymbuf – mbuf alteration pfil hooks

SYNOPSIS

To compile the driver into the kernel, place the following line in the kernel configuration file:

device dummymbuf

Alternatively, to load the driver as a module at boot time, place the following line in loader.conf(5):

dummymbuf_load="YES"

DESCRIPTION

This module is intended to test networking code in the face of unusual mbuf layouts. The special pfil(9) hooks are provided for mbuf alteration and can be listed with pfilctl(8) as follows:

            Hook                      Type
       dummymbuf:ethernet         Ethernet
       dummymbuf:inet6                IPv6
       dummymbuf:inet                 IPv4

To activate a hook it must be linked to the respective pfil(9) head. pfilctl(8) can be used for the linking.

Each time a hook is invoked it reads a single shared set of RULES from net.dummymbuf.rules sysctl. The rules are evaluated sequentially and each matching rule performs the specified operation over the mbuf.

After every successfully applied operation the net.dummymbuf.hits sysctl counter is increased.

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.

The module is VNET(9) based, hence every jail(2) provides its own set of hooks and sysctl variables.

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:

{inet | inet6 | ethernet} {in | out} <ifname> <opname>[ <opargs>];

Filter

The first word of a rule matches pfil(9) type. The second matches packet's direction, and the third matches the network interface a packet is coming from.

Operation

An operation may have arguments separated from its name by space. The available operations are:

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.

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 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.

As a result, only the layout of a mbuf chain is altered, its content logically is left intact.

enlarge <number-of-bytes>

Unconditionally replace the mbuf with an mbuf of the specified size.

SYSCTL VARIABLES

The following variables are available:

net.dummymbuf.rules

A string representing a single set of RULES shared among all dummymbuf hooks.

net.dummymbuf.hits

Number of times a rule has been applied. It is reset to zero upon writing.

EXAMPLES

As it was intended, dummymbuf 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 pfilctl(8) should be used to link dummymbuf hook(s) to put them in front of a firewall.

The following links dummymbuf:inet6 hook for inbound and puts it in front of other hooks:

pfilctl link -i dummymbuf:inet6 inet6

And this does the same for outbound:

pfilctl link -o -a dummymbuf:inet6 inet6

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:

sysctl net.dummymbuf.rules="inet6 in em0 pull-head 0; inet6 out em0 pull-head 0;"

It is encouraged to verify net.dummymbuf.hits sysctl counter along with other test assertions to make sure that dummymbuf really does its work and there is no false positive due to misconfiguration. It is a good idea to reset it before the action:

sysctl net.dummymbuf.hits=0

It is equally important to cleanup the things after the test case:

pfilctl unlink -i dummymbuf:inet6 inet6
pfilctl unlink -o dummymbuf:inet6 inet6
sysctl net.dummymbuf.rules=""

If a test case operates within a temporary vnet then explicit cleanup can be omitted, the dummymbuf facilities will vanish along with its vnet instance.

DIAGNOSTICS

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.

dummymbuf: <filter match>: mbuf operation failed: <the rule in question>

Incorrect operation argument has been found, mbuf allocation has failed, etc.

SEE ALSO

jail(2), pfilctl(8), mbuf(9), pfil(9), VNET(9)

AUTHORS

The module and this manual page were written by Igor Ostapenko ⟨[email protected]⟩.