Zephyr API Documentation 4.1.99
A Scalable Open Source RTOS
 4.1.99
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
net_pkt_filter.h
Go to the documentation of this file.
1
8/*
9 * Copyright (c) 2021 BayLibre SAS
10 *
11 * SPDX-License-Identifier: Apache-2.0
12 */
13
14#ifndef ZEPHYR_INCLUDE_NET_PKT_FILTER_H_
15#define ZEPHYR_INCLUDE_NET_PKT_FILTER_H_
16
17#include <limits.h>
18#include <stdbool.h>
19#include <zephyr/sys/slist.h>
20#include <zephyr/net/net_core.h>
21#include <zephyr/net/ethernet.h>
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
38struct npf_test;
39
40typedef bool (npf_test_fn_t)(struct npf_test *test, struct net_pkt *pkt);
41
42enum npf_test_type {
43 NPF_TEST_TYPE_UNKNOWN = 0,
44 NPF_TEST_TYPE_IFACE_MATCH,
45 NPF_TEST_TYPE_IFACE_UNMATCH,
46 NPF_TEST_TYPE_ORIG_IFACE_MATCH,
47 NPF_TEST_TYPE_ORIG_IFACE_UNMATCH,
48 NPF_TEST_TYPE_SIZE_MIN,
49 NPF_TEST_TYPE_SIZE_MAX,
50 NPF_TEST_TYPE_SIZE_BOUNDS,
51 NPF_TEST_TYPE_IP_SRC_ADDR_ALLOWLIST,
52 NPF_TEST_TYPE_IP_SRC_ADDR_BLOCKLIST,
53 NPF_TEST_TYPE_ETH_SRC_ADDR_MATCH,
54 NPF_TEST_TYPE_ETH_SRC_ADDR_UNMATCH,
55 NPF_TEST_TYPE_ETH_DST_ADDR_MATCH,
56 NPF_TEST_TYPE_ETH_DST_ADDR_UNMATCH,
57 NPF_TEST_TYPE_ETH_SRC_ADDR_MASK_MATCH,
58 NPF_TEST_TYPE_ETH_DST_ADDR_MASK_MATCH,
59 NPF_TEST_TYPE_ETH_TYPE_MATCH,
60 NPF_TEST_TYPE_ETH_TYPE_UNMATCH,
61 NPF_TEST_TYPE_ETH_VLAN_TYPE_MATCH,
62 NPF_TEST_TYPE_ETH_VLAN_TYPE_UNMATCH,
63};
64
65#if defined(CONFIG_NET_PKT_FILTER_LOG_LEVEL_DBG) || \
66 defined(CONFIG_NET_SHELL_PKT_FILTER_SUPPORTED)
67#define NPF_TEST_ENABLE_NAME 1
68#elif defined(NPF_TEST_ENABLE_NAME)
69#undef NPF_TEST_ENABLE_NAME
70#endif
71
75struct npf_test {
76 npf_test_fn_t *fn;
79 IF_ENABLED(NPF_TEST_ENABLE_NAME,
80 (const char *name;))
81 IF_ENABLED(NPF_TEST_ENABLE_NAME,
82 (enum npf_test_type type;))
84};
85
93
95extern struct npf_rule npf_default_ok;
97extern struct npf_rule npf_default_drop;
98
104
106extern struct npf_rule_list npf_send_rules;
108extern struct npf_rule_list npf_recv_rules;
115
122void npf_insert_rule(struct npf_rule_list *rules, struct npf_rule *rule);
123
130void npf_append_rule(struct npf_rule_list *rules, struct npf_rule *rule);
131
139bool npf_remove_rule(struct npf_rule_list *rules, struct npf_rule *rule);
140
148
151/* convenience shortcuts */
152#define npf_insert_send_rule(rule) npf_insert_rule(&npf_send_rules, rule)
153#define npf_insert_recv_rule(rule) npf_insert_rule(&npf_recv_rules, rule)
154#define npf_append_send_rule(rule) npf_append_rule(&npf_send_rules, rule)
155#define npf_append_recv_rule(rule) npf_append_rule(&npf_recv_rules, rule)
156#define npf_remove_send_rule(rule) npf_remove_rule(&npf_send_rules, rule)
157#define npf_remove_recv_rule(rule) npf_remove_rule(&npf_recv_rules, rule)
158#define npf_remove_all_send_rules() npf_remove_all_rules(&npf_send_rules)
159#define npf_remove_all_recv_rules() npf_remove_all_rules(&npf_recv_rules)
160
161#ifdef CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK
162#define npf_insert_local_in_recv_rule(rule) npf_insert_rule(&npf_local_in_recv_rules, rule)
163#define npf_append_local_in_recv_rule(rule) npf_append_rule(&npf_local_in_recv_rules, rule)
164#define npf_remove_local_in_recv_rule(rule) npf_remove_rule(&npf_local_in_recv_rules, rule)
165#define npf_remove_all_local_in_recv_rules() npf_remove_all_rules(&npf_local_in_recv_rules)
166#endif /* CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK */
167
168#ifdef CONFIG_NET_PKT_FILTER_IPV4_HOOK
169#define npf_insert_ipv4_recv_rule(rule) npf_insert_rule(&npf_ipv4_recv_rules, rule)
170#define npf_append_ipv4_recv_rule(rule) npf_append_rule(&npf_ipv4_recv_rules, rule)
171#define npf_remove_ipv4_recv_rule(rule) npf_remove_rule(&npf_ipv4_recv_rules, rule)
172#define npf_remove_all_ipv4_recv_rules() npf_remove_all_rules(&npf_ipv4_recv_rules)
173#endif /* CONFIG_NET_PKT_FILTER_IPV4_HOOK */
174
175#ifdef CONFIG_NET_PKT_FILTER_IPV6_HOOK
176#define npf_insert_ipv6_recv_rule(rule) npf_insert_rule(&npf_ipv6_recv_rules, rule)
177#define npf_append_ipv6_recv_rule(rule) npf_append_rule(&npf_ipv6_recv_rules, rule)
178#define npf_remove_ipv6_recv_rule(rule) npf_remove_rule(&npf_ipv6_recv_rules, rule)
179#define npf_remove_all_ipv6_recv_rules() npf_remove_all_rules(&npf_ipv6_recv_rules)
180#endif /* CONFIG_NET_PKT_FILTER_IPV6_HOOK */
181
238#define NPF_RULE(_name, _result, ...) \
239 struct npf_rule _name = { \
240 .result = (_result), \
241 .nb_tests = NUM_VA_ARGS_LESS_1(__VA_ARGS__) + 1, \
242 .tests = { FOR_EACH(Z_NPF_TEST_ADDR, (,), __VA_ARGS__) }, \
243 }
244
245#define Z_NPF_TEST_ADDR(arg) &arg.test
246
259struct npf_test_iface {
260 struct npf_test test;
261 struct net_if *iface;
262};
263
264extern npf_test_fn_t npf_iface_match;
265extern npf_test_fn_t npf_iface_unmatch;
266extern npf_test_fn_t npf_orig_iface_match;
267extern npf_test_fn_t npf_orig_iface_unmatch;
268
277#define NPF_IFACE_MATCH(_name, _iface) \
278 struct npf_test_iface _name = { \
279 .iface = (_iface), \
280 .test.fn = npf_iface_match, \
281 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
282 (.test.name = "iface", \
283 .test.type = NPF_TEST_TYPE_IFACE_MATCH,)) \
284 }
285
292#define NPF_IFACE_UNMATCH(_name, _iface) \
293 struct npf_test_iface _name = { \
294 .iface = (_iface), \
295 .test.fn = npf_iface_unmatch, \
296 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
297 (.test.name = "!iface", \
298 .test.type = NPF_TEST_TYPE_IFACE_UNMATCH,)) \
299 }
300
307#define NPF_ORIG_IFACE_MATCH(_name, _iface) \
308 struct npf_test_iface _name = { \
309 .iface = (_iface), \
310 .test.fn = npf_orig_iface_match, \
311 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
312 (.test.name = "orig iface", \
313 .test.type = NPF_TEST_TYPE_ORIG_IFACE_MATCH,)) \
314 }
315
322#define NPF_ORIG_IFACE_UNMATCH(_name, _iface) \
323 struct npf_test_iface _name = { \
324 .iface = (_iface), \
325 .test.fn = npf_orig_iface_unmatch, \
326 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
327 (.test.name = "!orig iface", \
328 .test.type = NPF_TEST_TYPE_ORIG_IFACE_UNMATCH,)) \
329 }
330
333struct npf_test_size_bounds {
334 struct npf_test test;
335 size_t min;
336 size_t max;
337};
338
339extern npf_test_fn_t npf_size_inbounds;
340
349#define NPF_SIZE_MIN(_name, _size) \
350 struct npf_test_size_bounds _name = { \
351 .min = (_size), \
352 .max = SIZE_MAX, \
353 .test.fn = npf_size_inbounds, \
354 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
355 (.test.name = "size min", \
356 .test.type = NPF_TEST_TYPE_SIZE_MIN,)) \
357 }
358
365#define NPF_SIZE_MAX(_name, _size) \
366 struct npf_test_size_bounds _name = { \
367 .min = 0, \
368 .max = (_size), \
369 .test.fn = npf_size_inbounds, \
370 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
371 (.test.name = "size max", \
372 .test.type = NPF_TEST_TYPE_SIZE_MAX,)) \
373 }
374
382#define NPF_SIZE_BOUNDS(_name, _min_size, _max_size) \
383 struct npf_test_size_bounds _name = { \
384 .min = (_min_size), \
385 .max = (_max_size), \
386 .test.fn = npf_size_inbounds, \
387 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
388 (.test.name = "size bounds", \
389 .test.type = NPF_TEST_TYPE_SIZE_BOUNDS,)) \
390 }
391
394struct npf_test_ip {
395 struct npf_test test;
396 uint8_t addr_family;
397 void *ipaddr;
398 uint32_t ipaddr_num;
399};
400
401extern npf_test_fn_t npf_ip_src_addr_match;
402extern npf_test_fn_t npf_ip_src_addr_unmatch;
403
418#define NPF_IP_SRC_ADDR_ALLOWLIST(_name, _ip_addr_array, _ip_addr_num, _af) \
419 struct npf_test_ip _name = { \
420 .addr_family = _af, \
421 .ipaddr = (_ip_addr_array), \
422 .ipaddr_num = _ip_addr_num, \
423 .test.fn = npf_ip_src_addr_match, \
424 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
425 (.test.name = "ip src allow", \
426 .test.type = NPF_TEST_TYPE_IP_SRC_ADDR_ALLOWLIST,)) \
427 }
428
441#define NPF_IP_SRC_ADDR_BLOCKLIST(_name, _ip_addr_array, _ip_addr_num, _af) \
442 struct npf_test_ip _name = { \
443 .addr_family = _af, \
444 .ipaddr = (_ip_addr_array), \
445 .ipaddr_num = _ip_addr_num, \
446 .test.fn = npf_ip_src_addr_unmatch, \
447 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
448 (.test.name = "ip src block", \
449 .test.type = NPF_TEST_TYPE_IP_SRC_ADDR_BLOCKLIST,)) \
450 }
451
464struct npf_test_eth_addr {
465 struct npf_test test;
466 unsigned int nb_addresses;
467 struct net_eth_addr *addresses;
468 struct net_eth_addr mask;
469};
470
471extern npf_test_fn_t npf_eth_src_addr_match;
472extern npf_test_fn_t npf_eth_src_addr_unmatch;
473extern npf_test_fn_t npf_eth_dst_addr_match;
474extern npf_test_fn_t npf_eth_dst_addr_unmatch;
475
487#define NPF_ETH_SRC_ADDR_MATCH(_name, _addr_array) \
488 struct npf_test_eth_addr _name = { \
489 .addresses = (_addr_array), \
490 .nb_addresses = ARRAY_SIZE(_addr_array), \
491 .test.fn = npf_eth_src_addr_match, \
492 .mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
493 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
494 (.test.name = "eth src", \
495 .test.type = NPF_TEST_TYPE_ETH_SRC_ADDR_MATCH,)) \
496 }
497
507#define NPF_ETH_SRC_ADDR_UNMATCH(_name, _addr_array) \
508 struct npf_test_eth_addr _name = { \
509 .addresses = (_addr_array), \
510 .nb_addresses = ARRAY_SIZE(_addr_array), \
511 .test.fn = npf_eth_src_addr_unmatch, \
512 .mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
513 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
514 (.test.name = "!eth src", \
515 .test.type = NPF_TEST_TYPE_ETH_SRC_ADDR_UNMATCH,)) \
516 }
517
527#define NPF_ETH_DST_ADDR_MATCH(_name, _addr_array) \
528 struct npf_test_eth_addr _name = { \
529 .addresses = (_addr_array), \
530 .nb_addresses = ARRAY_SIZE(_addr_array), \
531 .test.fn = npf_eth_dst_addr_match, \
532 .mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
533 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
534 (.test.name = "eth dst", \
535 .test.type = NPF_TEST_TYPE_ETH_DST_ADDR_MATCH,)) \
536 }
537
547#define NPF_ETH_DST_ADDR_UNMATCH(_name, _addr_array) \
548 struct npf_test_eth_addr _name = { \
549 .addresses = (_addr_array), \
550 .nb_addresses = ARRAY_SIZE(_addr_array), \
551 .test.fn = npf_eth_dst_addr_unmatch, \
552 .mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
553 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
554 (.test.name = "!eth dst", \
555 .test.type = NPF_TEST_TYPE_ETH_DST_ADDR_UNMATCH,)) \
556 }
557
568#define NPF_ETH_SRC_ADDR_MASK_MATCH(_name, _addr_array, ...) \
569 struct npf_test_eth_addr _name = { \
570 .addresses = (_addr_array), \
571 .nb_addresses = ARRAY_SIZE(_addr_array), \
572 .mask.addr = { __VA_ARGS__ }, \
573 .test.fn = npf_eth_src_addr_match, \
574 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
575 (.test.name = "eth src mask", \
576 .test.type = NPF_TEST_TYPE_ETH_SRC_ADDR_MASK_MATCH,)) \
577 }
578
589#define NPF_ETH_DST_ADDR_MASK_MATCH(_name, _addr_array, ...) \
590 struct npf_test_eth_addr _name = { \
591 .addresses = (_addr_array), \
592 .nb_addresses = ARRAY_SIZE(_addr_array), \
593 .mask.addr = { __VA_ARGS__ }, \
594 .test.fn = npf_eth_dst_addr_match, \
595 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
596 (.test.name = "eth dst mask", \
597 .test.type = NPF_TEST_TYPE_ETH_DST_ADDR_MASK_MATCH,)) \
598 }
599
602struct npf_test_eth_type {
603 struct npf_test test;
604 uint16_t type; /* type in network order */
605};
606
607extern npf_test_fn_t npf_eth_type_match;
608extern npf_test_fn_t npf_eth_type_unmatch;
609extern npf_test_fn_t npf_eth_vlan_type_match;
610extern npf_test_fn_t npf_eth_vlan_type_unmatch;
611
620#define NPF_ETH_TYPE_MATCH(_name, _type) \
621 struct npf_test_eth_type _name = { \
622 .type = htons(_type), \
623 .test.fn = npf_eth_type_match, \
624 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
625 (.test.name = "eth type", \
626 .test.type = NPF_TEST_TYPE_ETH_TYPE_MATCH,)) \
627 }
628
635#define NPF_ETH_TYPE_UNMATCH(_name, _type) \
636 struct npf_test_eth_type _name = { \
637 .type = htons(_type), \
638 .test.fn = npf_eth_type_unmatch, \
639 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
640 (.test.name = "!eth type", \
641 .test.type = NPF_TEST_TYPE_ETH_TYPE_UNMATCH,)) \
642 }
643
651#define NPF_ETH_VLAN_TYPE_MATCH(_name, _type) \
652 struct npf_test_eth_type _name = { \
653 .type = htons(_type), \
654 .test.fn = npf_eth_vlan_type_match, \
655 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
656 (.test.name = "eth vlan type", \
657 .test.type = NPF_TEST_TYPE_ETH_VLAN_TYPE_MATCH,)) \
658 }
659
667#define NPF_ETH_VLAN_TYPE_UNMATCH(_name, _type) \
668 struct npf_test_eth_type _name = { \
669 .type = htons(_type), \
670 .test.fn = npf_eth_vlan_type_unmatch, \
671 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
672 (.test.name = "!eth vlan type", \
673 .test.type = NPF_TEST_TYPE_ETH_VLAN_TYPE_UNMATCH,)) \
674 }
675
685
694typedef void (*npf_rule_cb_t)(struct npf_rule *rule,
695 enum npf_rule_type type,
696 void *user_data);
697
705void npf_rules_foreach(npf_rule_cb_t cb, void *user_data);
706
708const char *npf_test_get_str(struct npf_test *test, char *buf,
709 size_t len);
714#ifdef __cplusplus
715}
716#endif
717
718#endif /* ZEPHYR_INCLUDE_NET_PKT_FILTER_H_ */
Ethernet.
net_verdict
Net Verdict.
Definition net_core.h:103
void npf_insert_rule(struct npf_rule_list *rules, struct npf_rule *rule)
Insert a rule at the front of given rule list.
bool npf_remove_rule(struct npf_rule_list *rules, struct npf_rule *rule)
Remove a rule from the given rule list.
bool npf_remove_all_rules(struct npf_rule_list *rules)
Remove all rules from the given rule list.
struct npf_rule_list npf_local_in_recv_rules
rule list applied for local incoming packets
struct npf_rule_list npf_send_rules
rule list applied to outgoing packets
struct npf_rule npf_default_drop
Default rule list termination for rejecting a packet.
struct npf_rule_list npf_recv_rules
rule list applied to incoming packets
struct npf_rule npf_default_ok
Default rule list termination for accepting a packet.
struct npf_rule_list npf_ipv6_recv_rules
rule list applied for IPv6 incoming packets
struct npf_rule_list npf_ipv4_recv_rules
rule list applied for IPv4 incoming packets
void npf_append_rule(struct npf_rule_list *rules, struct npf_rule *rule)
Append a rule at the end of given rule list.
void npf_rules_foreach(npf_rule_cb_t cb, void *user_data)
Go through all the network packet filter rules and call callback for each of them.
void(* npf_rule_cb_t)(struct npf_rule *rule, enum npf_rule_type type, void *user_data)
Callback used while iterating over network packet filter rules.
Definition net_pkt_filter.h:694
npf_rule_type
Type of the packet filter rule.
Definition net_pkt_filter.h:677
@ NPF_RULE_TYPE_UNKNOWN
Unknown rule type.
Definition net_pkt_filter.h:678
@ NPF_RULE_TYPE_RECV
Rule for incoming packets.
Definition net_pkt_filter.h:680
@ NPF_RULE_TYPE_LOCAL_IN_RECV
Rule for local incoming packets.
Definition net_pkt_filter.h:681
@ NPF_RULE_TYPE_SEND
Rule for outgoing packets.
Definition net_pkt_filter.h:679
@ NPF_RULE_TYPE_IPV4_RECV
Rule for IPv4 incoming packets.
Definition net_pkt_filter.h:682
@ NPF_RULE_TYPE_IPV6_RECV
Rule for IPv6 incoming packets.
Definition net_pkt_filter.h:683
struct _slist sys_slist_t
Single-linked list structure.
Definition slist.h:49
struct _snode sys_snode_t
Single-linked list node structure.
Definition slist.h:39
#define IF_ENABLED(_flag, _code)
Insert code if _flag is defined and equals 1.
Definition util_macro.h:247
Network core definitions.
#define bool
Definition stdbool.h:13
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__UINT16_TYPE__ uint16_t
Definition stdint.h:89
Kernel Spin Lock.
Definition spinlock.h:45
Ethernet address.
Definition ethernet.h:55
Network Interface structure.
Definition net_if.h:714
Network packet.
Definition net_pkt.h:91
rule set for a given test location
Definition net_pkt_filter.h:100
sys_slist_t rule_head
List head.
Definition net_pkt_filter.h:101
struct k_spinlock lock
Lock protecting the list access.
Definition net_pkt_filter.h:102
filter rule structure
Definition net_pkt_filter.h:87
uint32_t nb_tests
number of tests for this rule
Definition net_pkt_filter.h:90
struct npf_test * tests[]
pointers to npf_test instances
Definition net_pkt_filter.h:91
enum net_verdict result
result if all tests pass
Definition net_pkt_filter.h:89
sys_snode_t node
Slist rule list node.
Definition net_pkt_filter.h:88
common filter test structure to be embedded into larger structures
Definition net_pkt_filter.h:75
npf_test_fn_t * fn
packet condition test function
Definition net_pkt_filter.h:76