Zephyr API Documentation 4.3.0-rc2
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};
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
73
75struct npf_test {
76 npf_test_fn_t *fn;
77
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
94
96extern struct npf_rule npf_default_ok;
98extern struct npf_rule npf_default_drop;
99
105
107extern struct npf_rule_list npf_send_rules;
109extern struct npf_rule_list npf_recv_rules;
116
123void npf_insert_rule(struct npf_rule_list *rules, struct npf_rule *rule);
124
131void npf_append_rule(struct npf_rule_list *rules, struct npf_rule *rule);
132
140bool npf_remove_rule(struct npf_rule_list *rules, struct npf_rule *rule);
141
149
151
152/* convenience shortcuts */
153#define npf_insert_send_rule(rule) npf_insert_rule(&npf_send_rules, rule)
154#define npf_insert_recv_rule(rule) npf_insert_rule(&npf_recv_rules, rule)
155#define npf_append_send_rule(rule) npf_append_rule(&npf_send_rules, rule)
156#define npf_append_recv_rule(rule) npf_append_rule(&npf_recv_rules, rule)
157#define npf_remove_send_rule(rule) npf_remove_rule(&npf_send_rules, rule)
158#define npf_remove_recv_rule(rule) npf_remove_rule(&npf_recv_rules, rule)
159#define npf_remove_all_send_rules() npf_remove_all_rules(&npf_send_rules)
160#define npf_remove_all_recv_rules() npf_remove_all_rules(&npf_recv_rules)
161
162#ifdef CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK
163#define npf_insert_local_in_recv_rule(rule) npf_insert_rule(&npf_local_in_recv_rules, rule)
164#define npf_append_local_in_recv_rule(rule) npf_append_rule(&npf_local_in_recv_rules, rule)
165#define npf_remove_local_in_recv_rule(rule) npf_remove_rule(&npf_local_in_recv_rules, rule)
166#define npf_remove_all_local_in_recv_rules() npf_remove_all_rules(&npf_local_in_recv_rules)
167#endif /* CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK */
168
169#ifdef CONFIG_NET_PKT_FILTER_IPV4_HOOK
170#define npf_insert_ipv4_recv_rule(rule) npf_insert_rule(&npf_ipv4_recv_rules, rule)
171#define npf_append_ipv4_recv_rule(rule) npf_append_rule(&npf_ipv4_recv_rules, rule)
172#define npf_remove_ipv4_recv_rule(rule) npf_remove_rule(&npf_ipv4_recv_rules, rule)
173#define npf_remove_all_ipv4_recv_rules() npf_remove_all_rules(&npf_ipv4_recv_rules)
174#endif /* CONFIG_NET_PKT_FILTER_IPV4_HOOK */
175
176#ifdef CONFIG_NET_PKT_FILTER_IPV6_HOOK
177#define npf_insert_ipv6_recv_rule(rule) npf_insert_rule(&npf_ipv6_recv_rules, rule)
178#define npf_append_ipv6_recv_rule(rule) npf_append_rule(&npf_ipv6_recv_rules, rule)
179#define npf_remove_ipv6_recv_rule(rule) npf_remove_rule(&npf_ipv6_recv_rules, rule)
180#define npf_remove_all_ipv6_recv_rules() npf_remove_all_rules(&npf_ipv6_recv_rules)
181#endif /* CONFIG_NET_PKT_FILTER_IPV6_HOOK */
182
184
239#define NPF_RULE(_name, _result, ...) \
240 struct npf_rule _name = { \
241 .result = (_result), \
242 .nb_tests = NUM_VA_ARGS_LESS_1(__VA_ARGS__) + 1, \
243 .tests = { FOR_EACH(Z_NPF_TEST_ADDR, (,), __VA_ARGS__) }, \
244 }
245
246#define NPF_PRIORITY(_name, _priority, ...) \
247 struct npf_rule _name = { \
248 .result = NET_CONTINUE, \
249 .priority = (_priority), \
250 .nb_tests = NUM_VA_ARGS_LESS_1(__VA_ARGS__) + 1, \
251 .tests = {FOR_EACH(Z_NPF_TEST_ADDR, (,), __VA_ARGS__)}, \
252 }
253
254#define Z_NPF_TEST_ADDR(arg) &arg.test
255
257
265
267
268struct npf_test_iface {
269 struct npf_test test;
270 struct net_if *iface;
271};
272
273extern npf_test_fn_t npf_iface_match;
274extern npf_test_fn_t npf_iface_unmatch;
275extern npf_test_fn_t npf_orig_iface_match;
276extern npf_test_fn_t npf_orig_iface_unmatch;
277
279
286#define NPF_IFACE_MATCH(_name, _iface) \
287 struct npf_test_iface _name = { \
288 .iface = (_iface), \
289 .test.fn = npf_iface_match, \
290 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
291 (.test.name = "iface", \
292 .test.type = NPF_TEST_TYPE_IFACE_MATCH,)) \
293 }
294
301#define NPF_IFACE_UNMATCH(_name, _iface) \
302 struct npf_test_iface _name = { \
303 .iface = (_iface), \
304 .test.fn = npf_iface_unmatch, \
305 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
306 (.test.name = "!iface", \
307 .test.type = NPF_TEST_TYPE_IFACE_UNMATCH,)) \
308 }
309
316#define NPF_ORIG_IFACE_MATCH(_name, _iface) \
317 struct npf_test_iface _name = { \
318 .iface = (_iface), \
319 .test.fn = npf_orig_iface_match, \
320 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
321 (.test.name = "orig iface", \
322 .test.type = NPF_TEST_TYPE_ORIG_IFACE_MATCH,)) \
323 }
324
331#define NPF_ORIG_IFACE_UNMATCH(_name, _iface) \
332 struct npf_test_iface _name = { \
333 .iface = (_iface), \
334 .test.fn = npf_orig_iface_unmatch, \
335 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
336 (.test.name = "!orig iface", \
337 .test.type = NPF_TEST_TYPE_ORIG_IFACE_UNMATCH,)) \
338 }
339
341
342struct npf_test_size_bounds {
343 struct npf_test test;
344 size_t min;
345 size_t max;
346};
347
348extern npf_test_fn_t npf_size_inbounds;
349
351
358#define NPF_SIZE_MIN(_name, _size) \
359 struct npf_test_size_bounds _name = { \
360 .min = (_size), \
361 .max = SIZE_MAX, \
362 .test.fn = npf_size_inbounds, \
363 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
364 (.test.name = "size min", \
365 .test.type = NPF_TEST_TYPE_SIZE_MIN,)) \
366 }
367
374#define NPF_SIZE_MAX(_name, _size) \
375 struct npf_test_size_bounds _name = { \
376 .min = 0, \
377 .max = (_size), \
378 .test.fn = npf_size_inbounds, \
379 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
380 (.test.name = "size max", \
381 .test.type = NPF_TEST_TYPE_SIZE_MAX,)) \
382 }
383
391#define NPF_SIZE_BOUNDS(_name, _min_size, _max_size) \
392 struct npf_test_size_bounds _name = { \
393 .min = (_min_size), \
394 .max = (_max_size), \
395 .test.fn = npf_size_inbounds, \
396 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
397 (.test.name = "size bounds", \
398 .test.type = NPF_TEST_TYPE_SIZE_BOUNDS,)) \
399 }
400
402
403struct npf_test_ip {
404 struct npf_test test;
405 uint8_t addr_family;
406 void *ipaddr;
407 uint32_t ipaddr_num;
408};
409
410extern npf_test_fn_t npf_ip_src_addr_match;
411extern npf_test_fn_t npf_ip_src_addr_unmatch;
412
414
427#define NPF_IP_SRC_ADDR_ALLOWLIST(_name, _ip_addr_array, _ip_addr_num, _af) \
428 struct npf_test_ip _name = { \
429 .addr_family = _af, \
430 .ipaddr = (_ip_addr_array), \
431 .ipaddr_num = _ip_addr_num, \
432 .test.fn = npf_ip_src_addr_match, \
433 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
434 (.test.name = "ip src allow", \
435 .test.type = NPF_TEST_TYPE_IP_SRC_ADDR_ALLOWLIST,)) \
436 }
437
450#define NPF_IP_SRC_ADDR_BLOCKLIST(_name, _ip_addr_array, _ip_addr_num, _af) \
451 struct npf_test_ip _name = { \
452 .addr_family = _af, \
453 .ipaddr = (_ip_addr_array), \
454 .ipaddr_num = _ip_addr_num, \
455 .test.fn = npf_ip_src_addr_unmatch, \
456 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
457 (.test.name = "ip src block", \
458 .test.type = NPF_TEST_TYPE_IP_SRC_ADDR_BLOCKLIST,)) \
459 }
460
462
470
472
473struct npf_test_eth_addr {
474 struct npf_test test;
475 unsigned int nb_addresses;
476 struct net_eth_addr *addresses;
477 struct net_eth_addr mask;
478};
479
480extern npf_test_fn_t npf_eth_src_addr_match;
481extern npf_test_fn_t npf_eth_src_addr_unmatch;
482extern npf_test_fn_t npf_eth_dst_addr_match;
483extern npf_test_fn_t npf_eth_dst_addr_unmatch;
484
486
496#define NPF_ETH_SRC_ADDR_MATCH(_name, _addr_array) \
497 struct npf_test_eth_addr _name = { \
498 .addresses = (_addr_array), \
499 .nb_addresses = ARRAY_SIZE(_addr_array), \
500 .test.fn = npf_eth_src_addr_match, \
501 .mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
502 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
503 (.test.name = "eth src", \
504 .test.type = NPF_TEST_TYPE_ETH_SRC_ADDR_MATCH,)) \
505 }
506
516#define NPF_ETH_SRC_ADDR_UNMATCH(_name, _addr_array) \
517 struct npf_test_eth_addr _name = { \
518 .addresses = (_addr_array), \
519 .nb_addresses = ARRAY_SIZE(_addr_array), \
520 .test.fn = npf_eth_src_addr_unmatch, \
521 .mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
522 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
523 (.test.name = "!eth src", \
524 .test.type = NPF_TEST_TYPE_ETH_SRC_ADDR_UNMATCH,)) \
525 }
526
536#define NPF_ETH_DST_ADDR_MATCH(_name, _addr_array) \
537 struct npf_test_eth_addr _name = { \
538 .addresses = (_addr_array), \
539 .nb_addresses = ARRAY_SIZE(_addr_array), \
540 .test.fn = npf_eth_dst_addr_match, \
541 .mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
542 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
543 (.test.name = "eth dst", \
544 .test.type = NPF_TEST_TYPE_ETH_DST_ADDR_MATCH,)) \
545 }
546
556#define NPF_ETH_DST_ADDR_UNMATCH(_name, _addr_array) \
557 struct npf_test_eth_addr _name = { \
558 .addresses = (_addr_array), \
559 .nb_addresses = ARRAY_SIZE(_addr_array), \
560 .test.fn = npf_eth_dst_addr_unmatch, \
561 .mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
562 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
563 (.test.name = "!eth dst", \
564 .test.type = NPF_TEST_TYPE_ETH_DST_ADDR_UNMATCH,)) \
565 }
566
577#define NPF_ETH_SRC_ADDR_MASK_MATCH(_name, _addr_array, ...) \
578 struct npf_test_eth_addr _name = { \
579 .addresses = (_addr_array), \
580 .nb_addresses = ARRAY_SIZE(_addr_array), \
581 .mask.addr = { __VA_ARGS__ }, \
582 .test.fn = npf_eth_src_addr_match, \
583 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
584 (.test.name = "eth src mask", \
585 .test.type = NPF_TEST_TYPE_ETH_SRC_ADDR_MASK_MATCH,)) \
586 }
587
598#define NPF_ETH_DST_ADDR_MASK_MATCH(_name, _addr_array, ...) \
599 struct npf_test_eth_addr _name = { \
600 .addresses = (_addr_array), \
601 .nb_addresses = ARRAY_SIZE(_addr_array), \
602 .mask.addr = { __VA_ARGS__ }, \
603 .test.fn = npf_eth_dst_addr_match, \
604 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
605 (.test.name = "eth dst mask", \
606 .test.type = NPF_TEST_TYPE_ETH_DST_ADDR_MASK_MATCH,)) \
607 }
608
610
611struct npf_test_eth_type {
612 struct npf_test test;
613 uint16_t type; /* type in network order */
614};
615
616extern npf_test_fn_t npf_eth_type_match;
617extern npf_test_fn_t npf_eth_type_unmatch;
618extern npf_test_fn_t npf_eth_vlan_type_match;
619extern npf_test_fn_t npf_eth_vlan_type_unmatch;
620
622
629#define NPF_ETH_TYPE_MATCH(_name, _type) \
630 struct npf_test_eth_type _name = { \
631 .type = htons(_type), \
632 .test.fn = npf_eth_type_match, \
633 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
634 (.test.name = "eth type", \
635 .test.type = NPF_TEST_TYPE_ETH_TYPE_MATCH,)) \
636 }
637
644#define NPF_ETH_TYPE_UNMATCH(_name, _type) \
645 struct npf_test_eth_type _name = { \
646 .type = htons(_type), \
647 .test.fn = npf_eth_type_unmatch, \
648 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
649 (.test.name = "!eth type", \
650 .test.type = NPF_TEST_TYPE_ETH_TYPE_UNMATCH,)) \
651 }
652
660#define NPF_ETH_VLAN_TYPE_MATCH(_name, _type) \
661 struct npf_test_eth_type _name = { \
662 .type = htons(_type), \
663 .test.fn = npf_eth_vlan_type_match, \
664 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
665 (.test.name = "eth vlan type", \
666 .test.type = NPF_TEST_TYPE_ETH_VLAN_TYPE_MATCH,)) \
667 }
668
676#define NPF_ETH_VLAN_TYPE_UNMATCH(_name, _type) \
677 struct npf_test_eth_type _name = { \
678 .type = htons(_type), \
679 .test.fn = npf_eth_vlan_type_unmatch, \
680 IF_ENABLED(NPF_TEST_ENABLE_NAME, \
681 (.test.name = "!eth vlan type", \
682 .test.type = NPF_TEST_TYPE_ETH_VLAN_TYPE_UNMATCH,)) \
683 }
684
694
703typedef void (*npf_rule_cb_t)(struct npf_rule *rule,
704 enum npf_rule_type type,
705 void *user_data);
706
714void npf_rules_foreach(npf_rule_cb_t cb, void *user_data);
715
717const char *npf_test_get_str(struct npf_test *test, char *buf,
718 size_t len);
720
722
723#ifdef __cplusplus
724}
725#endif
726
727#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:509
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.
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:703
npf_rule_type
Type of the packet filter rule.
Definition net_pkt_filter.h:686
@ NPF_RULE_TYPE_UNKNOWN
Unknown rule type.
Definition net_pkt_filter.h:687
@ NPF_RULE_TYPE_RECV
Rule for incoming packets.
Definition net_pkt_filter.h:689
@ NPF_RULE_TYPE_LOCAL_IN_RECV
Rule for local incoming packets.
Definition net_pkt_filter.h:690
@ NPF_RULE_TYPE_SEND
Rule for outgoing packets.
Definition net_pkt_filter.h:688
@ NPF_RULE_TYPE_IPV4_RECV
Rule for IPv4 incoming packets.
Definition net_pkt_filter.h:691
@ NPF_RULE_TYPE_IPV6_RECV
Rule for IPv6 incoming packets.
Definition net_pkt_filter.h:692
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:247
#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:53
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:101
sys_slist_t rule_head
List head.
Definition net_pkt_filter.h:102
struct k_spinlock lock
Lock protecting the list access.
Definition net_pkt_filter.h:103
filter rule structure
Definition net_pkt_filter.h:87
uint32_t nb_tests
number of tests for this rule
Definition net_pkt_filter.h:91
enum net_priority priority
priority in case of NET_CONTINUE
Definition net_pkt_filter.h:90
struct npf_test * tests[]
pointers to npf_test instances
Definition net_pkt_filter.h:92
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