Zephyr API Documentation 4.3.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
net_pkt_filter.h
Go to the documentation of this file.
1
7
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
35
37
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 NPF_TEST_TYPE_LOCAL_IN_MATCH,
64};
65
66#if defined(CONFIG_NET_PKT_FILTER_LOG_LEVEL_DBG) || \
67 defined(CONFIG_NET_SHELL_PKT_FILTER_SUPPORTED)
68#define NPF_TEST_ENABLE_NAME 1
69#elif defined(NPF_TEST_ENABLE_NAME)
70#undef NPF_TEST_ENABLE_NAME
71#endif
72
74
76struct npf_test {
77 npf_test_fn_t *fn;
78
80 IF_ENABLED(NPF_TEST_ENABLE_NAME,
81 (const char *name;))
82 IF_ENABLED(NPF_TEST_ENABLE_NAME,
83 (enum npf_test_type type;))
85};
86
95
97extern struct npf_rule npf_default_ok;
99extern struct npf_rule npf_default_drop;
100
106
108extern struct npf_rule_list npf_send_rules;
110extern struct npf_rule_list npf_recv_rules;
117
124void npf_insert_rule(struct npf_rule_list *rules, struct npf_rule *rule);
125
132void npf_append_rule(struct npf_rule_list *rules, struct npf_rule *rule);
133
141bool npf_remove_rule(struct npf_rule_list *rules, struct npf_rule *rule);
142
150
152
153/* convenience shortcuts */
154#define npf_insert_send_rule(rule) npf_insert_rule(&npf_send_rules, rule)
155#define npf_insert_recv_rule(rule) npf_insert_rule(&npf_recv_rules, rule)
156#define npf_append_send_rule(rule) npf_append_rule(&npf_send_rules, rule)
157#define npf_append_recv_rule(rule) npf_append_rule(&npf_recv_rules, rule)
158#define npf_remove_send_rule(rule) npf_remove_rule(&npf_send_rules, rule)
159#define npf_remove_recv_rule(rule) npf_remove_rule(&npf_recv_rules, rule)
160#define npf_remove_all_send_rules() npf_remove_all_rules(&npf_send_rules)
161#define npf_remove_all_recv_rules() npf_remove_all_rules(&npf_recv_rules)
162
163#ifdef CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK
164#define npf_insert_local_in_recv_rule(rule) npf_insert_rule(&npf_local_in_recv_rules, rule)
165#define npf_append_local_in_recv_rule(rule) npf_append_rule(&npf_local_in_recv_rules, rule)
166#define npf_remove_local_in_recv_rule(rule) npf_remove_rule(&npf_local_in_recv_rules, rule)
167#define npf_remove_all_local_in_recv_rules() npf_remove_all_rules(&npf_local_in_recv_rules)
168#endif /* CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK */
169
170#ifdef CONFIG_NET_PKT_FILTER_IPV4_HOOK
171#define npf_insert_ipv4_recv_rule(rule) npf_insert_rule(&npf_ipv4_recv_rules, rule)
172#define npf_append_ipv4_recv_rule(rule) npf_append_rule(&npf_ipv4_recv_rules, rule)
173#define npf_remove_ipv4_recv_rule(rule) npf_remove_rule(&npf_ipv4_recv_rules, rule)
174#define npf_remove_all_ipv4_recv_rules() npf_remove_all_rules(&npf_ipv4_recv_rules)
175#endif /* CONFIG_NET_PKT_FILTER_IPV4_HOOK */
176
177#ifdef CONFIG_NET_PKT_FILTER_IPV6_HOOK
178#define npf_insert_ipv6_recv_rule(rule) npf_insert_rule(&npf_ipv6_recv_rules, rule)
179#define npf_append_ipv6_recv_rule(rule) npf_append_rule(&npf_ipv6_recv_rules, rule)
180#define npf_remove_ipv6_recv_rule(rule) npf_remove_rule(&npf_ipv6_recv_rules, rule)
181#define npf_remove_all_ipv6_recv_rules() npf_remove_all_rules(&npf_ipv6_recv_rules)
182#endif /* CONFIG_NET_PKT_FILTER_IPV6_HOOK */
183
185
240#define NPF_RULE(_name, _result, ...) \
241 struct npf_rule _name = { \
242 .result = (_result), \
243 .nb_tests = NUM_VA_ARGS_LESS_1(__VA_ARGS__) + 1, \
244 .tests = { FOR_EACH(Z_NPF_TEST_ADDR, (,), __VA_ARGS__) }, \
245 }
246
247#define NPF_PRIORITY(_name, _priority, ...) \
248 struct npf_rule _name = { \
249 .result = NET_CONTINUE, \
250 .priority = (_priority), \
251 .nb_tests = NUM_VA_ARGS_LESS_1(__VA_ARGS__) + 1, \
252 .tests = {FOR_EACH(Z_NPF_TEST_ADDR, (,), __VA_ARGS__)}, \
253 }
254
255#define Z_NPF_TEST_ADDR(arg) &arg.test
256
258
266
268
269struct npf_test_iface {
270 struct npf_test test;
271 struct net_if *iface;
272};
273
274extern npf_test_fn_t npf_iface_match;
275extern npf_test_fn_t npf_iface_unmatch;
276extern npf_test_fn_t npf_orig_iface_match;
277extern npf_test_fn_t npf_orig_iface_unmatch;
278
280
287#define NPF_IFACE_MATCH(_name, _iface) \
288 struct npf_test_iface _name = { \
289 .iface = (_iface), \
290 .test.fn = npf_iface_match, \
291 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
292 (.test.name = "iface", \
293 .test.type = NPF_TEST_TYPE_IFACE_MATCH,)) \
294 }
295
302#define NPF_IFACE_UNMATCH(_name, _iface) \
303 struct npf_test_iface _name = { \
304 .iface = (_iface), \
305 .test.fn = npf_iface_unmatch, \
306 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
307 (.test.name = "!iface", \
308 .test.type = NPF_TEST_TYPE_IFACE_UNMATCH,)) \
309 }
310
317#define NPF_ORIG_IFACE_MATCH(_name, _iface) \
318 struct npf_test_iface _name = { \
319 .iface = (_iface), \
320 .test.fn = npf_orig_iface_match, \
321 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
322 (.test.name = "orig iface", \
323 .test.type = NPF_TEST_TYPE_ORIG_IFACE_MATCH,)) \
324 }
325
332#define NPF_ORIG_IFACE_UNMATCH(_name, _iface) \
333 struct npf_test_iface _name = { \
334 .iface = (_iface), \
335 .test.fn = npf_orig_iface_unmatch, \
336 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
337 (.test.name = "!orig iface", \
338 .test.type = NPF_TEST_TYPE_ORIG_IFACE_UNMATCH,)) \
339 }
340
342
343struct npf_test_size_bounds {
344 struct npf_test test;
345 size_t min;
346 size_t max;
347};
348
349extern npf_test_fn_t npf_size_inbounds;
350
352
359#define NPF_SIZE_MIN(_name, _size) \
360 struct npf_test_size_bounds _name = { \
361 .min = (_size), \
362 .max = SIZE_MAX, \
363 .test.fn = npf_size_inbounds, \
364 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
365 (.test.name = "size min", \
366 .test.type = NPF_TEST_TYPE_SIZE_MIN,)) \
367 }
368
375#define NPF_SIZE_MAX(_name, _size) \
376 struct npf_test_size_bounds _name = { \
377 .min = 0, \
378 .max = (_size), \
379 .test.fn = npf_size_inbounds, \
380 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
381 (.test.name = "size max", \
382 .test.type = NPF_TEST_TYPE_SIZE_MAX,)) \
383 }
384
392#define NPF_SIZE_BOUNDS(_name, _min_size, _max_size) \
393 struct npf_test_size_bounds _name = { \
394 .min = (_min_size), \
395 .max = (_max_size), \
396 .test.fn = npf_size_inbounds, \
397 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
398 (.test.name = "size bounds", \
399 .test.type = NPF_TEST_TYPE_SIZE_BOUNDS,)) \
400 }
401
403
404struct npf_test_ip {
405 struct npf_test test;
406 uint8_t addr_family;
407 void *ipaddr;
408 uint32_t ipaddr_num;
409};
410
411extern npf_test_fn_t npf_ip_src_addr_match;
412extern npf_test_fn_t npf_ip_src_addr_unmatch;
413
415
428#define NPF_IP_SRC_ADDR_ALLOWLIST(_name, _ip_addr_array, _ip_addr_num, _af) \
429 struct npf_test_ip _name = { \
430 .addr_family = _af, \
431 .ipaddr = (_ip_addr_array), \
432 .ipaddr_num = _ip_addr_num, \
433 .test.fn = npf_ip_src_addr_match, \
434 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
435 (.test.name = "ip src allow", \
436 .test.type = NPF_TEST_TYPE_IP_SRC_ADDR_ALLOWLIST,)) \
437 }
438
451#define NPF_IP_SRC_ADDR_BLOCKLIST(_name, _ip_addr_array, _ip_addr_num, _af) \
452 struct npf_test_ip _name = { \
453 .addr_family = _af, \
454 .ipaddr = (_ip_addr_array), \
455 .ipaddr_num = _ip_addr_num, \
456 .test.fn = npf_ip_src_addr_unmatch, \
457 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
458 (.test.name = "ip src block", \
459 .test.type = NPF_TEST_TYPE_IP_SRC_ADDR_BLOCKLIST,)) \
460 }
461
463
471
473
474struct npf_test_eth_addr {
475 struct npf_test test;
476 unsigned int nb_addresses;
477 struct net_eth_addr *addresses;
478 struct net_eth_addr mask;
479};
480
481extern npf_test_fn_t npf_eth_src_addr_match;
482extern npf_test_fn_t npf_eth_src_addr_unmatch;
483extern npf_test_fn_t npf_eth_dst_addr_match;
484extern npf_test_fn_t npf_eth_dst_addr_unmatch;
485
487
497#define NPF_ETH_SRC_ADDR_MATCH(_name, _addr_array) \
498 struct npf_test_eth_addr _name = { \
499 .addresses = (_addr_array), \
500 .nb_addresses = ARRAY_SIZE(_addr_array), \
501 .test.fn = npf_eth_src_addr_match, \
502 .mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
503 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
504 (.test.name = "eth src", \
505 .test.type = NPF_TEST_TYPE_ETH_SRC_ADDR_MATCH,)) \
506 }
507
517#define NPF_ETH_SRC_ADDR_UNMATCH(_name, _addr_array) \
518 struct npf_test_eth_addr _name = { \
519 .addresses = (_addr_array), \
520 .nb_addresses = ARRAY_SIZE(_addr_array), \
521 .test.fn = npf_eth_src_addr_unmatch, \
522 .mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
523 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
524 (.test.name = "!eth src", \
525 .test.type = NPF_TEST_TYPE_ETH_SRC_ADDR_UNMATCH,)) \
526 }
527
537#define NPF_ETH_DST_ADDR_MATCH(_name, _addr_array) \
538 struct npf_test_eth_addr _name = { \
539 .addresses = (_addr_array), \
540 .nb_addresses = ARRAY_SIZE(_addr_array), \
541 .test.fn = npf_eth_dst_addr_match, \
542 .mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
543 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
544 (.test.name = "eth dst", \
545 .test.type = NPF_TEST_TYPE_ETH_DST_ADDR_MATCH,)) \
546 }
547
557#define NPF_ETH_DST_ADDR_UNMATCH(_name, _addr_array) \
558 struct npf_test_eth_addr _name = { \
559 .addresses = (_addr_array), \
560 .nb_addresses = ARRAY_SIZE(_addr_array), \
561 .test.fn = npf_eth_dst_addr_unmatch, \
562 .mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
563 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
564 (.test.name = "!eth dst", \
565 .test.type = NPF_TEST_TYPE_ETH_DST_ADDR_UNMATCH,)) \
566 }
567
578#define NPF_ETH_SRC_ADDR_MASK_MATCH(_name, _addr_array, ...) \
579 struct npf_test_eth_addr _name = { \
580 .addresses = (_addr_array), \
581 .nb_addresses = ARRAY_SIZE(_addr_array), \
582 .mask.addr = { __VA_ARGS__ }, \
583 .test.fn = npf_eth_src_addr_match, \
584 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
585 (.test.name = "eth src mask", \
586 .test.type = NPF_TEST_TYPE_ETH_SRC_ADDR_MASK_MATCH,)) \
587 }
588
599#define NPF_ETH_DST_ADDR_MASK_MATCH(_name, _addr_array, ...) \
600 struct npf_test_eth_addr _name = { \
601 .addresses = (_addr_array), \
602 .nb_addresses = ARRAY_SIZE(_addr_array), \
603 .mask.addr = { __VA_ARGS__ }, \
604 .test.fn = npf_eth_dst_addr_match, \
605 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
606 (.test.name = "eth dst mask", \
607 .test.type = NPF_TEST_TYPE_ETH_DST_ADDR_MASK_MATCH,)) \
608 }
609
611
612struct npf_test_eth_type {
613 struct npf_test test;
614 uint16_t type; /* type in network order */
615};
616
617extern npf_test_fn_t npf_eth_type_match;
618extern npf_test_fn_t npf_eth_type_unmatch;
619extern npf_test_fn_t npf_eth_vlan_type_match;
620extern npf_test_fn_t npf_eth_vlan_type_unmatch;
621
623
630#define NPF_ETH_TYPE_MATCH(_name, _type) \
631 struct npf_test_eth_type _name = { \
632 .type = net_htons(_type), \
633 .test.fn = npf_eth_type_match, \
634 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
635 (.test.name = "eth type", \
636 .test.type = NPF_TEST_TYPE_ETH_TYPE_MATCH,)) \
637 }
638
645#define NPF_ETH_TYPE_UNMATCH(_name, _type) \
646 struct npf_test_eth_type _name = { \
647 .type = net_htons(_type), \
648 .test.fn = npf_eth_type_unmatch, \
649 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
650 (.test.name = "!eth type", \
651 .test.type = NPF_TEST_TYPE_ETH_TYPE_UNMATCH,)) \
652 }
653
661#define NPF_ETH_VLAN_TYPE_MATCH(_name, _type) \
662 struct npf_test_eth_type _name = { \
663 .type = net_htons(_type), \
664 .test.fn = npf_eth_vlan_type_match, \
665 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
666 (.test.name = "eth vlan type", \
667 .test.type = NPF_TEST_TYPE_ETH_VLAN_TYPE_MATCH,)) \
668 }
669
677#define NPF_ETH_VLAN_TYPE_UNMATCH(_name, _type) \
678 struct npf_test_eth_type _name = { \
679 .type = net_htons(_type), \
680 .test.fn = npf_eth_vlan_type_unmatch, \
681 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
682 (.test.name = "!eth vlan type", \
683 .test.type = NPF_TEST_TYPE_ETH_VLAN_TYPE_UNMATCH,)) \
684 }
685
697typedef bool (npf_local_in_fn_t)(struct net_pkt *pkt, void *user_data);
698
700
701extern npf_test_fn_t npf_local_in_match;
702
703struct npf_test_local_in {
704 struct npf_test test;
705 npf_local_in_fn_t *fn; /* local_in hook function */
706 void *user_data; /* optional user data */
707};
708
710
718#define NPF_LOCAL_IN_MATCH(_name, _handler, _user_data) \
719 struct npf_test_local_in _name = { \
720 .test.fn = npf_local_in_match, \
721 .fn = (_handler), \
722 .user_data = (_user_data), \
723 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
724 (.test.name = "local_in", \
725 .test.type = NPF_TEST_TYPE_LOCAL_IN_MATCH,)) \
726 }
727
737
746typedef void (*npf_rule_cb_t)(struct npf_rule *rule,
747 enum npf_rule_type type,
748 void *user_data);
749
757void npf_rules_foreach(npf_rule_cb_t cb, void *user_data);
758
760const char *npf_test_get_str(struct npf_test *test, char *buf,
761 size_t len);
763
765
766#ifdef __cplusplus
767}
768#endif
769
770#endif /* ZEPHYR_INCLUDE_NET_PKT_FILTER_H_ */
Ethernet.
net_priority
Network packet priority settings described in IEEE 802.1Q Annex I.1.
Definition net_ip.h:513
net_verdict
Net Verdict.
Definition net_core.h:109
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.
bool npf_local_in_fn_t(struct net_pkt *pkt, void *user_data)
Function that is called to get the verdict what should happen to the network packet.
Definition net_pkt_filter.h:697
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:746
npf_rule_type
Type of the packet filter rule.
Definition net_pkt_filter.h:729
@ NPF_RULE_TYPE_UNKNOWN
Unknown rule type.
Definition net_pkt_filter.h:730
@ NPF_RULE_TYPE_RECV
Rule for incoming packets.
Definition net_pkt_filter.h:732
@ NPF_RULE_TYPE_LOCAL_IN_RECV
Rule for local incoming packets.
Definition net_pkt_filter.h:733
@ NPF_RULE_TYPE_SEND
Rule for outgoing packets.
Definition net_pkt_filter.h:731
@ NPF_RULE_TYPE_IPV4_RECV
Rule for IPv4 incoming packets.
Definition net_pkt_filter.h:734
@ NPF_RULE_TYPE_IPV6_RECV
Rule for IPv6 incoming packets.
Definition net_pkt_filter.h:735
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 min(a, b)
Return smaller value of two provided expressions.
Definition util.h:457
#define IF_ENABLED(_flag, _code)
Insert code if _flag is defined and equals 1.
Definition util_macro.h:272
#define max(a, b)
Return larger value of two provided expressions.
Definition util.h:426
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:54
Network Interface structure.
Definition net_if.h:726
Network packet.
Definition net_pkt.h:91
rule set for a given test location
Definition net_pkt_filter.h:102
sys_slist_t rule_head
List head.
Definition net_pkt_filter.h:103
struct k_spinlock lock
Lock protecting the list access.
Definition net_pkt_filter.h:104
filter rule structure
Definition net_pkt_filter.h:88
uint32_t nb_tests
number of tests for this rule
Definition net_pkt_filter.h:92
enum net_priority priority
priority in case of NET_CONTINUE
Definition net_pkt_filter.h:91
struct npf_test * tests[]
pointers to npf_test instances
Definition net_pkt_filter.h:93
enum net_verdict result
result if all tests pass
Definition net_pkt_filter.h:90
sys_snode_t node
Slist rule list node.
Definition net_pkt_filter.h:89
common filter test structure to be embedded into larger structures
Definition net_pkt_filter.h:76
npf_test_fn_t * fn
packet condition test function
Definition net_pkt_filter.h:77