net: pkt_filter: Add enablers for shell support
Add helpers and enablers that allow "net filter" shell command to work. Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
This commit is contained in:
parent
bd3ce84d91
commit
f5bac38865
3 changed files with 362 additions and 86 deletions
|
@ -39,11 +39,46 @@ struct npf_test;
|
|||
|
||||
typedef bool (npf_test_fn_t)(struct npf_test *test, struct net_pkt *pkt);
|
||||
|
||||
enum npf_test_type {
|
||||
NPF_TEST_TYPE_UNKNOWN = 0,
|
||||
NPF_TEST_TYPE_IFACE_MATCH,
|
||||
NPF_TEST_TYPE_IFACE_UNMATCH,
|
||||
NPF_TEST_TYPE_ORIG_IFACE_MATCH,
|
||||
NPF_TEST_TYPE_ORIG_IFACE_UNMATCH,
|
||||
NPF_TEST_TYPE_SIZE_MIN,
|
||||
NPF_TEST_TYPE_SIZE_MAX,
|
||||
NPF_TEST_TYPE_SIZE_BOUNDS,
|
||||
NPF_TEST_TYPE_IP_SRC_ADDR_ALLOWLIST,
|
||||
NPF_TEST_TYPE_IP_SRC_ADDR_BLOCKLIST,
|
||||
NPF_TEST_TYPE_ETH_SRC_ADDR_MATCH,
|
||||
NPF_TEST_TYPE_ETH_SRC_ADDR_UNMATCH,
|
||||
NPF_TEST_TYPE_ETH_DST_ADDR_MATCH,
|
||||
NPF_TEST_TYPE_ETH_DST_ADDR_UNMATCH,
|
||||
NPF_TEST_TYPE_ETH_SRC_ADDR_MASK_MATCH,
|
||||
NPF_TEST_TYPE_ETH_DST_ADDR_MASK_MATCH,
|
||||
NPF_TEST_TYPE_ETH_TYPE_MATCH,
|
||||
NPF_TEST_TYPE_ETH_TYPE_UNMATCH,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_NET_PKT_FILTER_LOG_LEVEL_DBG) || \
|
||||
defined(CONFIG_NET_SHELL_PKT_FILTER_SUPPORTED)
|
||||
#define NPF_TEST_ENABLE_NAME 1
|
||||
#elif defined(NPF_TEST_ENABLE_NAME)
|
||||
#undef NPF_TEST_ENABLE_NAME
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/** @brief common filter test structure to be embedded into larger structures */
|
||||
struct npf_test {
|
||||
npf_test_fn_t *fn; /**< packet condition test function */
|
||||
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME,
|
||||
(const char *name;)) /**< Name of the test */
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME,
|
||||
(enum npf_test_type type;)) /**< Type of the test */
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
/** @brief filter rule structure */
|
||||
|
@ -237,10 +272,13 @@ extern npf_test_fn_t npf_orig_iface_unmatch;
|
|||
* @param _name Name of the condition
|
||||
* @param _iface Interface to match
|
||||
*/
|
||||
#define NPF_IFACE_MATCH(_name, _iface) \
|
||||
struct npf_test_iface _name = { \
|
||||
.iface = (_iface), \
|
||||
.test.fn = npf_iface_match, \
|
||||
#define NPF_IFACE_MATCH(_name, _iface) \
|
||||
struct npf_test_iface _name = { \
|
||||
.iface = (_iface), \
|
||||
.test.fn = npf_iface_match, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "iface", \
|
||||
.test.type = NPF_TEST_TYPE_IFACE_MATCH,)) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -249,10 +287,13 @@ extern npf_test_fn_t npf_orig_iface_unmatch;
|
|||
* @param _name Name of the condition
|
||||
* @param _iface Interface to exclude
|
||||
*/
|
||||
#define NPF_IFACE_UNMATCH(_name, _iface) \
|
||||
struct npf_test_iface _name = { \
|
||||
.iface = (_iface), \
|
||||
.test.fn = npf_iface_unmatch, \
|
||||
#define NPF_IFACE_UNMATCH(_name, _iface) \
|
||||
struct npf_test_iface _name = { \
|
||||
.iface = (_iface), \
|
||||
.test.fn = npf_iface_unmatch, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "!iface", \
|
||||
.test.type = NPF_TEST_TYPE_IFACE_UNMATCH,)) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -261,10 +302,13 @@ extern npf_test_fn_t npf_orig_iface_unmatch;
|
|||
* @param _name Name of the condition
|
||||
* @param _iface Interface to match
|
||||
*/
|
||||
#define NPF_ORIG_IFACE_MATCH(_name, _iface) \
|
||||
struct npf_test_iface _name = { \
|
||||
.iface = (_iface), \
|
||||
.test.fn = npf_orig_iface_match, \
|
||||
#define NPF_ORIG_IFACE_MATCH(_name, _iface) \
|
||||
struct npf_test_iface _name = { \
|
||||
.iface = (_iface), \
|
||||
.test.fn = npf_orig_iface_match, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "orig iface", \
|
||||
.test.type = NPF_TEST_TYPE_ORIG_IFACE_MATCH,)) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -273,10 +317,13 @@ extern npf_test_fn_t npf_orig_iface_unmatch;
|
|||
* @param _name Name of the condition
|
||||
* @param _iface Interface to exclude
|
||||
*/
|
||||
#define NPF_ORIG_IFACE_UNMATCH(_name, _iface) \
|
||||
struct npf_test_iface _name = { \
|
||||
.iface = (_iface), \
|
||||
.test.fn = npf_orig_iface_unmatch, \
|
||||
#define NPF_ORIG_IFACE_UNMATCH(_name, _iface) \
|
||||
struct npf_test_iface _name = { \
|
||||
.iface = (_iface), \
|
||||
.test.fn = npf_orig_iface_unmatch, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "!orig iface", \
|
||||
.test.type = NPF_TEST_TYPE_ORIG_IFACE_UNMATCH,)) \
|
||||
}
|
||||
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
|
@ -297,11 +344,14 @@ extern npf_test_fn_t npf_size_inbounds;
|
|||
* @param _name Name of the condition
|
||||
* @param _size Lower bound of the packet's data size
|
||||
*/
|
||||
#define NPF_SIZE_MIN(_name, _size) \
|
||||
struct npf_test_size_bounds _name = { \
|
||||
.min = (_size), \
|
||||
.max = SIZE_MAX, \
|
||||
.test.fn = npf_size_inbounds, \
|
||||
#define NPF_SIZE_MIN(_name, _size) \
|
||||
struct npf_test_size_bounds _name = { \
|
||||
.min = (_size), \
|
||||
.max = SIZE_MAX, \
|
||||
.test.fn = npf_size_inbounds, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "size min", \
|
||||
.test.type = NPF_TEST_TYPE_SIZE_MIN,)) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -310,11 +360,14 @@ extern npf_test_fn_t npf_size_inbounds;
|
|||
* @param _name Name of the condition
|
||||
* @param _size Higher bound of the packet's data size
|
||||
*/
|
||||
#define NPF_SIZE_MAX(_name, _size) \
|
||||
struct npf_test_size_bounds _name = { \
|
||||
.min = 0, \
|
||||
.max = (_size), \
|
||||
.test.fn = npf_size_inbounds, \
|
||||
#define NPF_SIZE_MAX(_name, _size) \
|
||||
struct npf_test_size_bounds _name = { \
|
||||
.min = 0, \
|
||||
.max = (_size), \
|
||||
.test.fn = npf_size_inbounds, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "size max", \
|
||||
.test.type = NPF_TEST_TYPE_SIZE_MAX,)) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -324,11 +377,14 @@ extern npf_test_fn_t npf_size_inbounds;
|
|||
* @param _min_size Lower bound of the packet's data size
|
||||
* @param _max_size Higher bound of the packet's data size
|
||||
*/
|
||||
#define NPF_SIZE_BOUNDS(_name, _min_size, _max_size) \
|
||||
struct npf_test_size_bounds _name = { \
|
||||
.min = (_min_size), \
|
||||
.max = (_max_size), \
|
||||
.test.fn = npf_size_inbounds, \
|
||||
#define NPF_SIZE_BOUNDS(_name, _min_size, _max_size) \
|
||||
struct npf_test_size_bounds _name = { \
|
||||
.min = (_min_size), \
|
||||
.max = (_max_size), \
|
||||
.test.fn = npf_size_inbounds, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "size bounds", \
|
||||
.test.type = NPF_TEST_TYPE_SIZE_BOUNDS,)) \
|
||||
}
|
||||
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
|
@ -358,11 +414,14 @@ extern npf_test_fn_t npf_ip_src_addr_unmatch;
|
|||
* @param _af Addresses family type (AF_INET / AF_INET6) in the array
|
||||
*/
|
||||
#define NPF_IP_SRC_ADDR_ALLOWLIST(_name, _ip_addr_array, _ip_addr_num, _af) \
|
||||
struct npf_test_ip _name = { \
|
||||
.addr_family = _af, \
|
||||
.ipaddr = (_ip_addr_array), \
|
||||
.ipaddr_num = _ip_addr_num, \
|
||||
.test.fn = npf_ip_src_addr_match, \
|
||||
struct npf_test_ip _name = { \
|
||||
.addr_family = _af, \
|
||||
.ipaddr = (_ip_addr_array), \
|
||||
.ipaddr_num = _ip_addr_num, \
|
||||
.test.fn = npf_ip_src_addr_match, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "ip src allow", \
|
||||
.test.type = NPF_TEST_TYPE_IP_SRC_ADDR_ALLOWLIST,)) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -378,11 +437,14 @@ extern npf_test_fn_t npf_ip_src_addr_unmatch;
|
|||
* @param _af Addresses family type (AF_INET / AF_INET6) in the array
|
||||
*/
|
||||
#define NPF_IP_SRC_ADDR_BLOCKLIST(_name, _ip_addr_array, _ip_addr_num, _af) \
|
||||
struct npf_test_ip _name = { \
|
||||
.addr_family = _af, \
|
||||
.ipaddr = (_ip_addr_array), \
|
||||
.ipaddr_num = _ip_addr_num, \
|
||||
.test.fn = npf_ip_src_addr_unmatch, \
|
||||
struct npf_test_ip _name = { \
|
||||
.addr_family = _af, \
|
||||
.ipaddr = (_ip_addr_array), \
|
||||
.ipaddr_num = _ip_addr_num, \
|
||||
.test.fn = npf_ip_src_addr_unmatch, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "ip src block", \
|
||||
.test.type = NPF_TEST_TYPE_IP_SRC_ADDR_BLOCKLIST,)) \
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -420,12 +482,15 @@ extern npf_test_fn_t npf_eth_dst_addr_unmatch;
|
|||
* @param _name Name of the condition
|
||||
* @param _addr_array Array of <tt>struct net_eth_addr</tt> items to test against
|
||||
*/
|
||||
#define NPF_ETH_SRC_ADDR_MATCH(_name, _addr_array) \
|
||||
struct npf_test_eth_addr _name = { \
|
||||
.addresses = (_addr_array), \
|
||||
.nb_addresses = ARRAY_SIZE(_addr_array), \
|
||||
.test.fn = npf_eth_src_addr_match, \
|
||||
.mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
|
||||
#define NPF_ETH_SRC_ADDR_MATCH(_name, _addr_array) \
|
||||
struct npf_test_eth_addr _name = { \
|
||||
.addresses = (_addr_array), \
|
||||
.nb_addresses = ARRAY_SIZE(_addr_array), \
|
||||
.test.fn = npf_eth_src_addr_match, \
|
||||
.mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "eth src", \
|
||||
.test.type = NPF_TEST_TYPE_ETH_SRC_ADDR_MATCH,)) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -437,12 +502,15 @@ extern npf_test_fn_t npf_eth_dst_addr_unmatch;
|
|||
* @param _name Name of the condition
|
||||
* @param _addr_array Array of <tt>struct net_eth_addr</tt> items to test against
|
||||
*/
|
||||
#define NPF_ETH_SRC_ADDR_UNMATCH(_name, _addr_array) \
|
||||
struct npf_test_eth_addr _name = { \
|
||||
.addresses = (_addr_array), \
|
||||
.nb_addresses = ARRAY_SIZE(_addr_array), \
|
||||
.test.fn = npf_eth_src_addr_unmatch, \
|
||||
.mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
|
||||
#define NPF_ETH_SRC_ADDR_UNMATCH(_name, _addr_array) \
|
||||
struct npf_test_eth_addr _name = { \
|
||||
.addresses = (_addr_array), \
|
||||
.nb_addresses = ARRAY_SIZE(_addr_array), \
|
||||
.test.fn = npf_eth_src_addr_unmatch, \
|
||||
.mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "!eth src", \
|
||||
.test.type = NPF_TEST_TYPE_ETH_SRC_ADDR_UNMATCH,)) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -454,12 +522,15 @@ extern npf_test_fn_t npf_eth_dst_addr_unmatch;
|
|||
* @param _name Name of the condition
|
||||
* @param _addr_array Array of <tt>struct net_eth_addr</tt> items to test against
|
||||
*/
|
||||
#define NPF_ETH_DST_ADDR_MATCH(_name, _addr_array) \
|
||||
struct npf_test_eth_addr _name = { \
|
||||
.addresses = (_addr_array), \
|
||||
.nb_addresses = ARRAY_SIZE(_addr_array), \
|
||||
.test.fn = npf_eth_dst_addr_match, \
|
||||
.mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
|
||||
#define NPF_ETH_DST_ADDR_MATCH(_name, _addr_array) \
|
||||
struct npf_test_eth_addr _name = { \
|
||||
.addresses = (_addr_array), \
|
||||
.nb_addresses = ARRAY_SIZE(_addr_array), \
|
||||
.test.fn = npf_eth_dst_addr_match, \
|
||||
.mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "eth dst", \
|
||||
.test.type = NPF_TEST_TYPE_ETH_DST_ADDR_MATCH,)) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -471,12 +542,15 @@ extern npf_test_fn_t npf_eth_dst_addr_unmatch;
|
|||
* @param _name Name of the condition
|
||||
* @param _addr_array Array of <tt>struct net_eth_addr</tt> items to test against
|
||||
*/
|
||||
#define NPF_ETH_DST_ADDR_UNMATCH(_name, _addr_array) \
|
||||
struct npf_test_eth_addr _name = { \
|
||||
.addresses = (_addr_array), \
|
||||
.nb_addresses = ARRAY_SIZE(_addr_array), \
|
||||
.test.fn = npf_eth_dst_addr_unmatch, \
|
||||
.mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
|
||||
#define NPF_ETH_DST_ADDR_UNMATCH(_name, _addr_array) \
|
||||
struct npf_test_eth_addr _name = { \
|
||||
.addresses = (_addr_array), \
|
||||
.nb_addresses = ARRAY_SIZE(_addr_array), \
|
||||
.test.fn = npf_eth_dst_addr_unmatch, \
|
||||
.mask.addr = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "!eth dst", \
|
||||
.test.type = NPF_TEST_TYPE_ETH_DST_ADDR_UNMATCH,)) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -489,12 +563,15 @@ extern npf_test_fn_t npf_eth_dst_addr_unmatch;
|
|||
* @param _addr_array Array of <tt>struct net_eth_addr</tt> items to test against
|
||||
* @param ... up to 6 mask bytes
|
||||
*/
|
||||
#define NPF_ETH_SRC_ADDR_MASK_MATCH(_name, _addr_array, ...) \
|
||||
struct npf_test_eth_addr _name = { \
|
||||
.addresses = (_addr_array), \
|
||||
.nb_addresses = ARRAY_SIZE(_addr_array), \
|
||||
.mask.addr = { __VA_ARGS__ }, \
|
||||
.test.fn = npf_eth_src_addr_match, \
|
||||
#define NPF_ETH_SRC_ADDR_MASK_MATCH(_name, _addr_array, ...) \
|
||||
struct npf_test_eth_addr _name = { \
|
||||
.addresses = (_addr_array), \
|
||||
.nb_addresses = ARRAY_SIZE(_addr_array), \
|
||||
.mask.addr = { __VA_ARGS__ }, \
|
||||
.test.fn = npf_eth_src_addr_match, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "eth src mask", \
|
||||
.test.type = NPF_TEST_TYPE_ETH_SRC_ADDR_MASK_MATCH,)) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -507,12 +584,15 @@ extern npf_test_fn_t npf_eth_dst_addr_unmatch;
|
|||
* @param _addr_array Array of <tt>struct net_eth_addr</tt> items to test against
|
||||
* @param ... up to 6 mask bytes
|
||||
*/
|
||||
#define NPF_ETH_DST_ADDR_MASK_MATCH(_name, _addr_array, ...) \
|
||||
struct npf_test_eth_addr _name = { \
|
||||
.addresses = (_addr_array), \
|
||||
.nb_addresses = ARRAY_SIZE(_addr_array), \
|
||||
.mask.addr = { __VA_ARGS__ }, \
|
||||
.test.fn = npf_eth_dst_addr_match, \
|
||||
#define NPF_ETH_DST_ADDR_MASK_MATCH(_name, _addr_array, ...) \
|
||||
struct npf_test_eth_addr _name = { \
|
||||
.addresses = (_addr_array), \
|
||||
.nb_addresses = ARRAY_SIZE(_addr_array), \
|
||||
.mask.addr = { __VA_ARGS__ }, \
|
||||
.test.fn = npf_eth_dst_addr_match, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "eth dst mask", \
|
||||
.test.type = NPF_TEST_TYPE_ETH_DST_ADDR_MASK_MATCH,)) \
|
||||
}
|
||||
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
|
@ -533,10 +613,13 @@ extern npf_test_fn_t npf_eth_type_unmatch;
|
|||
* @param _name Name of the condition
|
||||
* @param _type Ethernet type to match
|
||||
*/
|
||||
#define NPF_ETH_TYPE_MATCH(_name, _type) \
|
||||
struct npf_test_eth_type _name = { \
|
||||
.type = htons(_type), \
|
||||
.test.fn = npf_eth_type_match, \
|
||||
#define NPF_ETH_TYPE_MATCH(_name, _type) \
|
||||
struct npf_test_eth_type _name = { \
|
||||
.type = htons(_type), \
|
||||
.test.fn = npf_eth_type_match, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "eth type", \
|
||||
.test.type = NPF_TEST_TYPE_ETH_TYPE_MATCH,)) \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -545,12 +628,51 @@ extern npf_test_fn_t npf_eth_type_unmatch;
|
|||
* @param _name Name of the condition
|
||||
* @param _type Ethernet type to exclude
|
||||
*/
|
||||
#define NPF_ETH_TYPE_UNMATCH(_name, _type) \
|
||||
struct npf_test_eth_type _name = { \
|
||||
.type = htons(_type), \
|
||||
.test.fn = npf_eth_type_unmatch, \
|
||||
#define NPF_ETH_TYPE_UNMATCH(_name, _type) \
|
||||
struct npf_test_eth_type _name = { \
|
||||
.type = htons(_type), \
|
||||
.test.fn = npf_eth_type_unmatch, \
|
||||
IF_ENABLED(NPF_TEST_ENABLE_NAME, \
|
||||
(.test.name = "!eth type", \
|
||||
.test.type = NPF_TEST_TYPE_ETH_TYPE_UNMATCH,)) \
|
||||
}
|
||||
|
||||
/** Type of the packet filter rule. */
|
||||
enum npf_rule_type {
|
||||
NPF_RULE_TYPE_UNKNOWN = 0, /**< Unknown rule type */
|
||||
NPF_RULE_TYPE_SEND, /**< Rule for outgoing packets */
|
||||
NPF_RULE_TYPE_RECV, /**< Rule for incoming packets */
|
||||
NPF_RULE_TYPE_LOCAL_IN_RECV, /**< Rule for local incoming packets */
|
||||
NPF_RULE_TYPE_IPV4_RECV, /**< Rule for IPv4 incoming packets */
|
||||
NPF_RULE_TYPE_IPV6_RECV, /**< Rule for IPv6 incoming packets */
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef npf_rule_cb_t
|
||||
* @brief Callback used while iterating over network packet filter rules.
|
||||
*
|
||||
* @param rule Pointer to current network packet filter rule
|
||||
* @param type Type of the rule (rx, tx, local_in, IPv4 or IPv6)
|
||||
* @param user_data A valid pointer to user data or NULL
|
||||
*/
|
||||
typedef void (*npf_rule_cb_t)(struct npf_rule *rule,
|
||||
enum npf_rule_type type,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Go through all the network packet filter rules and call callback
|
||||
* for each of them.
|
||||
*
|
||||
* @param cb User-supplied callback function to call
|
||||
* @param user_data User specified data
|
||||
*/
|
||||
void npf_rules_foreach(npf_rule_cb_t cb, void *user_data);
|
||||
|
||||
/** @cond INTERNAL_HIDDEN */
|
||||
const char *npf_test_get_str(struct npf_test *test, char *buf,
|
||||
size_t len);
|
||||
/** @endcond */
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -5,5 +5,6 @@ if(CONFIG_NET_PKT_FILTER)
|
|||
zephyr_library()
|
||||
zephyr_library_sources(base.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_NET_L2_ETHERNET ethernet.c)
|
||||
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip)
|
||||
|
||||
endif()
|
||||
|
|
|
@ -87,7 +87,9 @@ static bool apply_tests(struct npf_rule *rule, struct net_pkt *pkt)
|
|||
for (i = 0; i < rule->nb_tests; i++) {
|
||||
test = rule->tests[i];
|
||||
result = test->fn(test, pkt);
|
||||
NET_DBG("test %p result %d", test, result);
|
||||
NET_DBG("test %s (%p) result %d",
|
||||
COND_CODE_1(NPF_TEST_ENABLE_NAME, (test->name), ("")),
|
||||
test, result);
|
||||
if (result == false) {
|
||||
return false;
|
||||
}
|
||||
|
@ -298,3 +300,154 @@ bool npf_ip_src_addr_unmatch(struct npf_test *test, struct net_pkt *pkt)
|
|||
{
|
||||
return !npf_ip_src_addr_match(test, pkt);
|
||||
}
|
||||
|
||||
static void rules_cb(struct npf_rule_list *rules, enum npf_rule_type type,
|
||||
npf_rule_cb_t cb, void *user_data)
|
||||
{
|
||||
struct npf_rule *rule;
|
||||
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&rules->rule_head, rule, node) {
|
||||
cb(rule, type, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
void npf_rules_foreach(npf_rule_cb_t cb, void *user_data)
|
||||
{
|
||||
rules_cb(&npf_send_rules, NPF_RULE_TYPE_SEND, cb, user_data);
|
||||
rules_cb(&npf_recv_rules, NPF_RULE_TYPE_RECV, cb, user_data);
|
||||
|
||||
#ifdef CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK
|
||||
rules_cb(&npf_local_in_recv_rules, NPF_RULE_TYPE_LOCAL_IN_RECV, cb, user_data);
|
||||
#endif /* CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK */
|
||||
|
||||
#ifdef CONFIG_NET_PKT_FILTER_IPV4_HOOK
|
||||
rules_cb(&npf_ipv4_recv_rules, NPF_RULE_TYPE_IPV4_RECV, cb, user_data);
|
||||
#endif /* CONFIG_NET_PKT_FILTER_IPV4_HOOK */
|
||||
|
||||
#ifdef CONFIG_NET_PKT_FILTER_IPV6_HOOK
|
||||
rules_cb(&npf_ipv6_recv_rules, NPF_RULE_TYPE_IPV6_RECV, cb, user_data);
|
||||
#endif /* CONFIG_NET_PKT_FILTER_IPV6_HOOK */
|
||||
}
|
||||
|
||||
#include "net_private.h" /* for net_sprint_addr() */
|
||||
|
||||
const char *npf_test_get_str(struct npf_test *test, char *buf, size_t len)
|
||||
{
|
||||
#if defined(CONFIG_NET_SHELL_PKT_FILTER_SUPPORTED)
|
||||
if (test->type == NPF_TEST_TYPE_IFACE_MATCH ||
|
||||
test->type == NPF_TEST_TYPE_IFACE_UNMATCH ||
|
||||
test->type == NPF_TEST_TYPE_ORIG_IFACE_MATCH ||
|
||||
test->type == NPF_TEST_TYPE_ORIG_IFACE_UNMATCH) {
|
||||
struct npf_test_iface *test_iface =
|
||||
CONTAINER_OF(test, struct npf_test_iface, test);
|
||||
|
||||
snprintk(buf, len, "[%d]", net_if_get_by_iface(test_iface->iface));
|
||||
|
||||
} else if (test->type == NPF_TEST_TYPE_SIZE_BOUNDS ||
|
||||
test->type == NPF_TEST_TYPE_SIZE_MIN ||
|
||||
test->type == NPF_TEST_TYPE_SIZE_MAX) {
|
||||
struct npf_test_size_bounds *bounds =
|
||||
CONTAINER_OF(test, struct npf_test_size_bounds, test);
|
||||
|
||||
if (test->type == NPF_TEST_TYPE_SIZE_MIN ||
|
||||
test->type == NPF_TEST_TYPE_SIZE_MAX) {
|
||||
snprintk(buf, len, "[%zu]",
|
||||
test->type == NPF_TEST_TYPE_SIZE_MIN ?
|
||||
bounds->min : bounds->max);
|
||||
} else {
|
||||
snprintk(buf, len, "[%zu-%zu]", bounds->min, bounds->max);
|
||||
}
|
||||
|
||||
} else if (test->type == NPF_TEST_TYPE_IP_SRC_ADDR_ALLOWLIST ||
|
||||
test->type == NPF_TEST_TYPE_IP_SRC_ADDR_BLOCKLIST) {
|
||||
struct npf_test_ip *test_ip =
|
||||
CONTAINER_OF(test, struct npf_test_ip, test);
|
||||
int pos = 1;
|
||||
|
||||
if (len < 2) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (test_ip->ipaddr_num == 0) {
|
||||
snprintk(buf, len, "[]");
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf[0] = '[';
|
||||
|
||||
for (uint32_t i = 0; i < test_ip->ipaddr_num; i++) {
|
||||
if (IS_ENABLED(CONFIG_NET_IPV4) &&
|
||||
test_ip->addr_family == AF_INET) {
|
||||
struct in_addr *addr =
|
||||
&((struct in_addr *)test_ip->ipaddr)[i];
|
||||
|
||||
pos += snprintk(buf + pos, len - pos,
|
||||
"%s%s", pos > 1 ? "," : "",
|
||||
net_sprint_ipv4_addr(addr));
|
||||
|
||||
} else if (IS_ENABLED(CONFIG_NET_IPV6) &&
|
||||
test_ip->addr_family == AF_INET6) {
|
||||
struct in6_addr *addr =
|
||||
&((struct in6_addr *)test_ip->ipaddr)[i];
|
||||
|
||||
pos += snprintk(buf + pos, len - pos,
|
||||
"%s%s", pos > 1 ? "," : "",
|
||||
net_sprint_ipv6_addr(addr));
|
||||
}
|
||||
}
|
||||
|
||||
if (pos >= len) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf[pos] = ']';
|
||||
|
||||
} else if (test->type == NPF_TEST_TYPE_ETH_SRC_ADDR_MATCH ||
|
||||
test->type == NPF_TEST_TYPE_ETH_SRC_ADDR_UNMATCH ||
|
||||
test->type == NPF_TEST_TYPE_ETH_DST_ADDR_MATCH ||
|
||||
test->type == NPF_TEST_TYPE_ETH_DST_ADDR_UNMATCH ||
|
||||
test->type == NPF_TEST_TYPE_ETH_SRC_ADDR_MASK_MATCH ||
|
||||
test->type == NPF_TEST_TYPE_ETH_DST_ADDR_MASK_MATCH) {
|
||||
struct npf_test_eth_addr *test_eth =
|
||||
CONTAINER_OF(test, struct npf_test_eth_addr, test);
|
||||
int pos = 1;
|
||||
|
||||
if (len < 2) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (test_eth->nb_addresses == 0) {
|
||||
snprintk(buf, len, "[]");
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf[0] = '[';
|
||||
|
||||
for (uint32_t i = 0; i < test_eth->nb_addresses; i++) {
|
||||
pos += snprintk(buf + pos, len - pos,
|
||||
"%s%s", pos > 1 ? "," : "",
|
||||
net_sprint_ll_addr(
|
||||
(const uint8_t *)(&test_eth->addresses[i]),
|
||||
NET_ETH_ADDR_LEN));
|
||||
}
|
||||
|
||||
if (pos >= len) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf[pos] = ']';
|
||||
|
||||
} else if (test->type == NPF_TEST_TYPE_ETH_TYPE_MATCH ||
|
||||
test->type == NPF_TEST_TYPE_ETH_TYPE_UNMATCH) {
|
||||
struct npf_test_eth_type *test_eth =
|
||||
CONTAINER_OF(test, struct npf_test_eth_type, test);
|
||||
|
||||
snprintk(buf, len, "[0x%04x]", ntohs(test_eth->type));
|
||||
}
|
||||
|
||||
out:
|
||||
return test->name;
|
||||
#else
|
||||
return "<UNKNOWN>";
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue