LCOV - code coverage report
Current view: top level - zephyr/net - net_pkt_filter.h Coverage Total Hit
Test: new.info Lines: 100.0 % 45 45
Test Date: 2025-09-05 22:20:39

            Line data    Source code
       1            1 : /** @file
       2              :  * @brief Network packet filtering public header file
       3              :  *
       4              :  * The network packet filtering provides a mechanism for deciding the fate
       5              :  * of an incoming or outgoing packet based on a set of basic rules.
       6              :  */
       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
      24              : extern "C" {
      25              : #endif
      26              : 
      27              : /**
      28              :  * @brief Network Packet Filter API
      29              :  * @defgroup net_pkt_filter Network Packet Filter API
      30              :  * @since 3.0
      31              :  * @version 0.8.0
      32              :  * @ingroup networking
      33              :  * @{
      34              :  */
      35              : 
      36              : /** @cond INTERNAL_HIDDEN */
      37              : 
      38              : struct npf_test;
      39              : 
      40              : typedef bool (npf_test_fn_t)(struct npf_test *test, struct net_pkt *pkt);
      41              : 
      42              : enum 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              : 
      72              : /** @endcond */
      73              : 
      74              : /** @brief common filter test structure to be embedded into larger structures */
      75            1 : struct npf_test {
      76            1 :         npf_test_fn_t *fn;      /**< packet condition test function */
      77              : 
      78              : /** @cond INTERNAL_HIDDEN */
      79              :         IF_ENABLED(NPF_TEST_ENABLE_NAME,
      80              :                    (const char *name;))        /**< Name of the test */
      81              :         IF_ENABLED(NPF_TEST_ENABLE_NAME,
      82              :                    (enum npf_test_type type;)) /**< Type of the test */
      83              : /** @endcond */
      84              : };
      85              : 
      86              : /** @brief filter rule structure */
      87            1 : struct npf_rule {
      88            1 :         sys_snode_t node;               /**< Slist rule list node */
      89            1 :         enum net_verdict result;        /**< result if all tests pass */
      90            1 :         uint32_t nb_tests;              /**< number of tests for this rule */
      91            1 :         struct npf_test *tests[];       /**< pointers to @ref npf_test instances */
      92              : };
      93              : 
      94              : /** @brief Default rule list termination for accepting a packet */
      95            1 : extern struct npf_rule npf_default_ok;
      96              : /** @brief Default rule list termination for rejecting a packet */
      97            1 : extern struct npf_rule npf_default_drop;
      98              : 
      99              : /** @brief rule set for a given test location */
     100            1 : struct npf_rule_list {
     101            1 :         sys_slist_t rule_head;   /**< List head */
     102            1 :         struct k_spinlock lock;  /**< Lock protecting the list access */
     103              : };
     104              : 
     105              : /** @brief  rule list applied to outgoing packets */
     106            1 : extern struct npf_rule_list npf_send_rules;
     107              : /** @brief rule list applied to incoming packets */
     108            1 : extern struct npf_rule_list npf_recv_rules;
     109              : /** @brief rule list applied for local incoming packets */
     110            1 : extern struct npf_rule_list npf_local_in_recv_rules;
     111              : /** @brief rule list applied for IPv4 incoming packets */
     112            1 : extern struct npf_rule_list npf_ipv4_recv_rules;
     113              : /** @brief rule list applied for IPv6 incoming packets */
     114            1 : extern struct npf_rule_list npf_ipv6_recv_rules;
     115              : 
     116              : /**
     117              :  * @brief Insert a rule at the front of given rule list
     118              :  *
     119              :  * @param rules the affected rule list
     120              :  * @param rule the rule to be inserted
     121              :  */
     122            1 : void npf_insert_rule(struct npf_rule_list *rules, struct npf_rule *rule);
     123              : 
     124              : /**
     125              :  * @brief Append a rule at the end of given rule list
     126              :  *
     127              :  * @param rules the affected rule list
     128              :  * @param rule the rule to be appended
     129              :  */
     130            1 : void npf_append_rule(struct npf_rule_list *rules, struct npf_rule *rule);
     131              : 
     132              : /**
     133              :  * @brief Remove a rule from the given rule list
     134              :  *
     135              :  * @param rules the affected rule list
     136              :  * @param rule the rule to be removed
     137              :  * @retval true if given rule was found in the rule list and removed
     138              :  */
     139            1 : bool npf_remove_rule(struct npf_rule_list *rules, struct npf_rule *rule);
     140              : 
     141              : /**
     142              :  * @brief Remove all rules from the given rule list
     143              :  *
     144              :  * @param rules the affected rule list
     145              :  * @retval true if at least one rule was removed from the rule list
     146              :  */
     147            1 : bool npf_remove_all_rules(struct npf_rule_list *rules);
     148              : 
     149              : /** @cond INTERNAL_HIDDEN */
     150              : 
     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              : 
     182              : /** @endcond */
     183              : 
     184              : /**
     185              :  * @brief Statically define one packet filter rule
     186              :  *
     187              :  * This creates a rule from a variable amount of filter conditions.
     188              :  * This rule can then be inserted or appended to the rule list for a given
     189              :  * network packet path.
     190              :  *
     191              :  * Example:
     192              :  *
     193              :  * @code{.c}
     194              :  *
     195              :  *     static NPF_SIZE_MAX(maxsize_200, 200);
     196              :  *     static NPF_ETH_TYPE_MATCH(ip_packet, NET_ETH_PTYPE_IP);
     197              :  *
     198              :  *     static NPF_RULE(small_ip_pkt, NET_OK, ip_packet, maxsize_200);
     199              :  *
     200              :  *     void install_my_filter(void)
     201              :  *     {
     202              :  *         npf_insert_recv_rule(&npf_default_drop);
     203              :  *         npf_insert_recv_rule(&small_ip_pkt);
     204              :  *     }
     205              :  *
     206              :  * @endcode
     207              :  *
     208              :  * The above would accept IP packets that are 200 bytes or smaller, and drop
     209              :  * all other packets.
     210              :  *
     211              :  * Another (less efficient) way to create the same result could be:
     212              :  *
     213              :  * @code{.c}
     214              :  *
     215              :  *     static NPF_SIZE_MIN(minsize_201, 201);
     216              :  *     static NPF_ETH_TYPE_UNMATCH(not_ip_packet, NET_ETH_PTYPE_IP);
     217              :  *
     218              :  *     static NPF_RULE(reject_big_pkts, NET_DROP, minsize_201);
     219              :  *     static NPF_RULE(reject_non_ip, NET_DROP, not_ip_packet);
     220              :  *
     221              :  *     void install_my_filter(void) {
     222              :  *         npf_append_recv_rule(&reject_big_pkts);
     223              :  *         npf_append_recv_rule(&reject_non_ip);
     224              :  *         npf_append_recv_rule(&npf_default_ok);
     225              :  *     }
     226              :  *
     227              :  * @endcode
     228              :  *
     229              :  * The first rule in the list for which all conditions are true determines
     230              :  * the fate of the packet. If one condition is false then the next rule in
     231              :  * the list is evaluated.
     232              :  *
     233              :  * @param _name Name for this rule.
     234              :  * @param _result Fate of the packet if all conditions are true, either
     235              :  *                <tt>NET_OK</tt> or <tt>NET_DROP</tt>.
     236              :  * @param ... List of conditions for this rule.
     237              :  */
     238            1 : #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              : 
     247              : /** @} */
     248              : 
     249              : /**
     250              :  * @defgroup npf_basic_cond Basic Filter Conditions
     251              :  * @since 3.0
     252              :  * @version 0.8.0
     253              :  * @ingroup net_pkt_filter
     254              :  * @{
     255              :  */
     256              : 
     257              : /** @cond INTERNAL_HIDDEN */
     258              : 
     259              : struct npf_test_iface {
     260              :         struct npf_test test;
     261              :         struct net_if *iface;
     262              : };
     263              : 
     264              : extern npf_test_fn_t npf_iface_match;
     265              : extern npf_test_fn_t npf_iface_unmatch;
     266              : extern npf_test_fn_t npf_orig_iface_match;
     267              : extern npf_test_fn_t npf_orig_iface_unmatch;
     268              : 
     269              : /** @endcond */
     270              : 
     271              : /**
     272              :  * @brief Statically define an "interface match" packet filter condition
     273              :  *
     274              :  * @param _name Name of the condition
     275              :  * @param _iface Interface to match
     276              :  */
     277            1 : #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              : 
     286              : /**
     287              :  * @brief Statically define an "interface unmatch" packet filter condition
     288              :  *
     289              :  * @param _name Name of the condition
     290              :  * @param _iface Interface to exclude
     291              :  */
     292            1 : #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              : 
     301              : /**
     302              :  * @brief Statically define an "orig interface match" packet filter condition
     303              :  *
     304              :  * @param _name Name of the condition
     305              :  * @param _iface Interface to match
     306              :  */
     307            1 : #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              : 
     316              : /**
     317              :  * @brief Statically define an "orig interface unmatch" packet filter condition
     318              :  *
     319              :  * @param _name Name of the condition
     320              :  * @param _iface Interface to exclude
     321              :  */
     322            1 : #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              : 
     331              : /** @cond INTERNAL_HIDDEN */
     332              : 
     333              : struct npf_test_size_bounds {
     334              :         struct npf_test test;
     335              :         size_t min;
     336              :         size_t max;
     337              : };
     338              : 
     339              : extern npf_test_fn_t npf_size_inbounds;
     340              : 
     341              : /** @endcond */
     342              : 
     343              : /**
     344              :  * @brief Statically define a "data minimum size" packet filter condition
     345              :  *
     346              :  * @param _name Name of the condition
     347              :  * @param _size Lower bound of the packet's data size
     348              :  */
     349            1 : #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              : 
     359              : /**
     360              :  * @brief Statically define a "data maximum size" packet filter condition
     361              :  *
     362              :  * @param _name Name of the condition
     363              :  * @param _size Higher bound of the packet's data size
     364              :  */
     365            1 : #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              : 
     375              : /**
     376              :  * @brief Statically define a "data bounded size" packet filter condition
     377              :  *
     378              :  * @param _name Name of the condition
     379              :  * @param _min_size Lower bound of the packet's data size
     380              :  * @param _max_size Higher bound of the packet's data size
     381              :  */
     382            1 : #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              : 
     392              : /** @cond INTERNAL_HIDDEN */
     393              : 
     394              : struct npf_test_ip {
     395              :         struct npf_test test;
     396              :         uint8_t addr_family;
     397              :         void *ipaddr;
     398              :         uint32_t ipaddr_num;
     399              : };
     400              : 
     401              : extern npf_test_fn_t npf_ip_src_addr_match;
     402              : extern npf_test_fn_t npf_ip_src_addr_unmatch;
     403              : 
     404              : /** @endcond */
     405              : 
     406              : /**
     407              :  * @brief Statically define a "ip address allowlist" packet filter condition
     408              :  *
     409              :  * This tests if the packet source ip address matches any of the ip
     410              :  * addresses contained in the provided set.
     411              :  *
     412              :  * @param _name Name of the condition
     413              :  * @param _ip_addr_array Array of <tt>struct in_addr</tt> or <tt>struct in6_addr</tt> items to test
     414              :  *against
     415              :  * @param _ip_addr_num number of IP addresses in the array
     416              :  * @param _af Addresses family type (AF_INET / AF_INET6) in the array
     417              :  */
     418            1 : #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              : 
     429              : /**
     430              :  * @brief Statically define a "ip address blocklist" packet filter condition
     431              :  *
     432              :  * This tests if the packet source ip address matches any of the ip
     433              :  * addresses contained in the provided set.
     434              :  *
     435              :  * @param _name Name of the condition
     436              :  * @param _ip_addr_array Array of <tt>struct in_addr</tt> or <tt>struct in6_addr</tt> items to test
     437              :  *against
     438              :  * @param _ip_addr_num number of IP addresses in the array
     439              :  * @param _af Addresses family type (AF_INET / AF_INET6) in the array
     440              :  */
     441            1 : #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              : 
     452              : /** @} */
     453              : 
     454              : /**
     455              :  * @defgroup npf_eth_cond Ethernet Filter Conditions
     456              :  * @ingroup net_pkt_filter
     457              :  * @since 3.0
     458              :  * @version 0.8.0
     459              :  * @{
     460              :  */
     461              : 
     462              : /** @cond INTERNAL_HIDDEN */
     463              : 
     464              : struct 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              : 
     471              : extern npf_test_fn_t npf_eth_src_addr_match;
     472              : extern npf_test_fn_t npf_eth_src_addr_unmatch;
     473              : extern npf_test_fn_t npf_eth_dst_addr_match;
     474              : extern npf_test_fn_t npf_eth_dst_addr_unmatch;
     475              : 
     476              : /** @endcond */
     477              : 
     478              : /**
     479              :  * @brief Statically define a "source address match" packet filter condition
     480              :  *
     481              :  * This tests if the packet source address matches any of the Ethernet
     482              :  * addresses contained in the provided set.
     483              :  *
     484              :  * @param _name Name of the condition
     485              :  * @param _addr_array Array of <tt>struct net_eth_addr</tt> items to test against
     486              :  */
     487            1 : #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              : 
     498              : /**
     499              :  * @brief Statically define a "source address unmatch" packet filter condition
     500              :  *
     501              :  * This tests if the packet source address matches none of the Ethernet
     502              :  * addresses contained in the provided set.
     503              :  *
     504              :  * @param _name Name of the condition
     505              :  * @param _addr_array Array of <tt>struct net_eth_addr</tt> items to test against
     506              :  */
     507            1 : #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              : 
     518              : /**
     519              :  * @brief Statically define a "destination address match" packet filter condition
     520              :  *
     521              :  * This tests if the packet destination address matches any of the Ethernet
     522              :  * addresses contained in the provided set.
     523              :  *
     524              :  * @param _name Name of the condition
     525              :  * @param _addr_array Array of <tt>struct net_eth_addr</tt> items to test against
     526              :  */
     527            1 : #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              : 
     538              : /**
     539              :  * @brief Statically define a "destination address unmatch" packet filter condition
     540              :  *
     541              :  * This tests if the packet destination address matches none of the Ethernet
     542              :  * addresses contained in the provided set.
     543              :  *
     544              :  * @param _name Name of the condition
     545              :  * @param _addr_array Array of <tt>struct net_eth_addr</tt> items to test against
     546              :  */
     547            1 : #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              : 
     558              : /**
     559              :  * @brief Statically define a "source address match with mask" packet filter condition
     560              :  *
     561              :  * This tests if the packet source address matches any of the Ethernet
     562              :  * addresses contained in the provided set after applying specified mask.
     563              :  *
     564              :  * @param _name Name of the condition
     565              :  * @param _addr_array Array of <tt>struct net_eth_addr</tt> items to test against
     566              :  * @param ... up to 6 mask bytes
     567              :  */
     568            1 : #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              : 
     579              : /**
     580              :  * @brief Statically define a "destination address match with mask" packet filter condition
     581              :  *
     582              :  * This tests if the packet destination address matches any of the Ethernet
     583              :  * addresses contained in the provided set after applying specified mask.
     584              :  *
     585              :  * @param _name Name of the condition
     586              :  * @param _addr_array Array of <tt>struct net_eth_addr</tt> items to test against
     587              :  * @param ... up to 6 mask bytes
     588              :  */
     589            1 : #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              : 
     600              : /** @cond INTERNAL_HIDDEN */
     601              : 
     602              : struct npf_test_eth_type {
     603              :         struct npf_test test;
     604              :         uint16_t type;                  /* type in network order */
     605              : };
     606              : 
     607              : extern npf_test_fn_t npf_eth_type_match;
     608              : extern npf_test_fn_t npf_eth_type_unmatch;
     609              : extern npf_test_fn_t npf_eth_vlan_type_match;
     610              : extern npf_test_fn_t npf_eth_vlan_type_unmatch;
     611              : 
     612              : /** @endcond */
     613              : 
     614              : /**
     615              :  * @brief Statically define an "Ethernet type match" packet filter condition
     616              :  *
     617              :  * @param _name Name of the condition
     618              :  * @param _type Ethernet type to match
     619              :  */
     620            1 : #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              : 
     629              : /**
     630              :  * @brief Statically define an "Ethernet type unmatch" packet filter condition
     631              :  *
     632              :  * @param _name Name of the condition
     633              :  * @param _type Ethernet type to exclude
     634              :  */
     635            1 : #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              : 
     644              : /**
     645              :  * @brief Statically define an "Ethernet VLAN header type match" packet
     646              :  *        filter condition.
     647              :  *
     648              :  * @param _name Name of the condition
     649              :  * @param _type Ethernet VLAN header type to match
     650              :  */
     651            1 : #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              : 
     660              : /**
     661              :  * @brief Statically define an "Ethernet VLAN header type unmatch" packet
     662              :  *        filter condition.
     663              :  *
     664              :  * @param _name Name of the condition
     665              :  * @param _type Ethernet VLAN header type to exclude
     666              :  */
     667            1 : #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              : 
     676              : /** Type of the packet filter rule. */
     677            1 : enum npf_rule_type {
     678              :         NPF_RULE_TYPE_UNKNOWN = 0,   /**< Unknown rule type */
     679              :         NPF_RULE_TYPE_SEND,          /**< Rule for outgoing packets */
     680              :         NPF_RULE_TYPE_RECV,          /**< Rule for incoming packets */
     681              :         NPF_RULE_TYPE_LOCAL_IN_RECV, /**< Rule for local incoming packets */
     682              :         NPF_RULE_TYPE_IPV4_RECV,     /**< Rule for IPv4 incoming packets */
     683              :         NPF_RULE_TYPE_IPV6_RECV,     /**< Rule for IPv6 incoming packets */
     684              : };
     685              : 
     686              : /**
     687              :  * @typedef npf_rule_cb_t
     688              :  * @brief Callback used while iterating over network packet filter rules.
     689              :  *
     690              :  * @param rule Pointer to current network packet filter rule
     691              :  * @param type Type of the rule (rx, tx, local_in, IPv4 or IPv6)
     692              :  * @param user_data A valid pointer to user data or NULL
     693              :  */
     694            1 : typedef void (*npf_rule_cb_t)(struct npf_rule *rule,
     695              :                               enum npf_rule_type type,
     696              :                               void *user_data);
     697              : 
     698              : /**
     699              :  * @brief Go through all the network packet filter rules and call callback
     700              :  * for each of them.
     701              :  *
     702              :  * @param cb User-supplied callback function to call
     703              :  * @param user_data User specified data
     704              :  */
     705            1 : void npf_rules_foreach(npf_rule_cb_t cb, void *user_data);
     706              : 
     707              : /** @cond INTERNAL_HIDDEN */
     708              : const char *npf_test_get_str(struct npf_test *test, char *buf,
     709              :                              size_t len);
     710              : /** @endcond */
     711              : 
     712              : /** @} */
     713              : 
     714              : #ifdef __cplusplus
     715              : }
     716              : #endif
     717              : 
     718              : #endif /* ZEPHYR_INCLUDE_NET_PKT_FILTER_H_ */
        

Generated by: LCOV version 2.0-1