Skip to content

Commit faa0b2a

Browse files
Nicolas Pitrecarlescufi
authored andcommitted
net: introduce a network packet filter framework
This provides the infrastructure to create network packet filter rules and to apply them to the RX and TX packet paths. Rules are made of simple condition tests that can be linked together, creating a facility similarly to the Linux iptables functionality. A couple of generic and Ethernet-specific condition tests are also provided. Additional tests can be easily created on top of this. Signed-off-by: Nicolas Pitre <[email protected]>
1 parent 44585b7 commit faa0b2a

File tree

17 files changed

+1186
-1
lines changed

17 files changed

+1186
-1
lines changed

CODEOWNERS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@
568568
/include/net/coap*.h @rlubos
569569
/include/net/lwm2m*.h @rlubos
570570
/include/net/mqtt.h @rlubos
571+
/include/net/net_pkt_filter.h @npitre
571572
/include/posix/ @pfalcon
572573
/include/pm/pm.h @nashif @ceolin
573574
/include/drivers/ptp_clock.h @tbursztyka
@@ -719,6 +720,7 @@
719720
/subsys/net/lib/tls_credentials/ @rlubos
720721
/subsys/net/l2/ @rlubos @tbursztyka
721722
/subsys/net/l2/canbus/ @alexanderwachter
723+
/subsys/net/pkt_filter/ @npitre
722724
/subsys/net/*/openthread/ @rlubos
723725
/subsys/pm/ @nashif @ceolin
724726
/subsys/random/ @dleach02
@@ -760,6 +762,7 @@
760762
/tests/net/lib/http_header_fields/ @rlubos @tbursztyka
761763
/tests/net/lib/mqtt_packet/ @rlubos
762764
/tests/net/lib/coap/ @rlubos
765+
/tests/net/npf/ @npitre
763766
/tests/net/socket/socketpair/ @cfriedt
764767
/tests/net/socket/ @rlubos @tbursztyka @pfalcon
765768
/tests/subsys/debug/coredump/ @dcpleung
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
.. _net_pkt_filter_interface:
2+
3+
Network Packet Filtering
4+
########################
5+
6+
.. contents::
7+
:local:
8+
:depth: 2
9+
10+
Overview
11+
********
12+
13+
The Network Packet Filtering facility provides the infrastructure to
14+
construct custom rules for accepting and/or denying packet transmission
15+
and reception. This can be used to create a basic firewall, control
16+
network traffic, etc.
17+
18+
The :kconfig:`CONFIG_NET_PKT_FILTER` must be set in order to enable the
19+
relevant APIs.
20+
21+
Both the transmission and reception paths may have a list of filter rules.
22+
Each rule is made of a set of conditions and a packet outcome. Every packet
23+
is subjected to the conditions attached to a rule. When all the conditions
24+
for a given rule are true then the packet outcome is immediately determined
25+
as specified by the current rule and no more rules are considered. If one
26+
condition is false then the next rule in the list is considered.
27+
28+
Packet outcome is either ``NET_OK`` to accept the packet or ``NET_DROP`` to
29+
drop it.
30+
31+
A rule is represented by a :c:struct:`npf_rule` object. It can be inserted to,
32+
appended to or removed from a rule list contained in a
33+
:c:struct:`npf_rule_list` object using :c:func:`npf_insert_rule()`,
34+
:c:func:`npf_append_rule()`, and :c:func:`npf_remove_rule()`.
35+
Currently, two such rule lists exist: ``npf_send_rules`` for outgoing packets,
36+
and ``npf_recv_rules`` for incoming packets.
37+
38+
If a filter rule list is empty then ``NET_OK`` is assumed. If a non-empty
39+
rule list runs to the end then ``NET_DROP`` is assumed. However it is
40+
recommended to always terminate a non-empty rule list with an explicit
41+
default termination rule, either ``npf_default_ok`` or ``npf_default_drop``.
42+
43+
Rule conditions are represented by a :c:struct:`npf_test`. This structure
44+
can be embedded into a larger structure when a specific condition requires
45+
extra test data. It is up to the test function for such conditions to
46+
retrieve the outer structure from the provided ``npf_test`` structure pointer.
47+
48+
Convenience macros are provided in :zephyr_file:`include/net/net_pkt_filter.h`
49+
to statically define condition instances for various conditions, and
50+
:c:macro:`NPF_RULE()` to create a rule instance to tie them.
51+
52+
Examples
53+
********
54+
55+
Here's an example usage:
56+
57+
.. code-block:: c
58+
59+
static NPF_SIZE_MAX(maxsize_200, 200);
60+
static NPF_ETH_TYPE_MATCH(ip_packet, NET_ETH_PTYPE_IP);
61+
62+
static NPF_RULE(small_ip_pkt, NET_OK, ip_packet, maxsize_200);
63+
64+
void install_my_filter(void)
65+
{
66+
npf_insert_recv_rule(&npf_default_drop);
67+
npf_insert_recv_rule(&small_ip_pkt);
68+
}
69+
70+
The above would accept IP packets that are 200 bytes or smaller, and drop
71+
all other packets.
72+
73+
Another (less efficient) way to achieve the same result could be:
74+
75+
.. code-block:: c
76+
77+
static NPF_SIZE_MIN(minsize_201, 201);
78+
static NPF_ETH_TYPE_UNMATCH(not_ip_packet, NET_ETH_PTYPE_IP);
79+
80+
static NPF_RULE(reject_big_pkts, NET_DROP, minsize_201);
81+
static NPF_RULE(reject_non_ip, NET_DROP, not_ip_packet);
82+
83+
void install_my_filter(void) {
84+
npf_append_recv_rule(&reject_big_pkts);
85+
npf_append_recv_rule(&reject_non_ip);
86+
npf_append_recv_rule(&npf_default_ok);
87+
}
88+
89+
API Reference
90+
*************
91+
92+
.. doxygengroup:: net_pkt_filter
93+
94+
.. doxygengroup:: npf_basic_cond
95+
96+
.. doxygengroup:: npf_eth_cond

doc/reference/networking/system_mgmt.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ Network System Management
1616
net_linkaddr.rst
1717
ethernet_mgmt.rst
1818
traffic-class.rst
19+
net_pkt_filter.rst
1920
net_shell.rst

include/net/net_pkt.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,29 @@ static inline bool net_pkt_is_being_overwritten(struct net_pkt *pkt)
12121212
return pkt->overwrite;
12131213
}
12141214

1215+
#ifdef CONFIG_NET_PKT_FILTER
1216+
1217+
bool net_pkt_filter_send_ok(struct net_pkt *pkt);
1218+
bool net_pkt_filter_recv_ok(struct net_pkt *pkt);
1219+
1220+
#else
1221+
1222+
static inline bool net_pkt_filter_send_ok(struct net_pkt *pkt)
1223+
{
1224+
ARG_UNUSED(pkt);
1225+
1226+
return true;
1227+
}
1228+
1229+
static inline bool net_pkt_filter_recv_ok(struct net_pkt *pkt)
1230+
{
1231+
ARG_UNUSED(pkt);
1232+
1233+
return true;
1234+
}
1235+
1236+
#endif /* CONFIG_NET_PKT_FILTER */
1237+
12151238
/* @endcond */
12161239

12171240
/**

0 commit comments

Comments
 (0)