net: shell: Add packet filter support

Add a "net filter" command that will allow user to see the
current network packet filter configuration.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
This commit is contained in:
Jukka Rissanen 2025-04-11 14:52:52 +03:00 committed by Benjamin Cabé
commit 28dca17436
4 changed files with 122 additions and 0 deletions

View file

@ -26,6 +26,8 @@ The following net-shell commands are implemented:
resolve a DNS name. Only available if :kconfig:option:`CONFIG_DNS_RESOLVER` is set." resolve a DNS name. Only available if :kconfig:option:`CONFIG_DNS_RESOLVER` is set."
"net events", "Enable network event monitoring. Only available if "net events", "Enable network event monitoring. Only available if
:kconfig:option:`CONFIG_NET_MGMT_EVENT_MONITOR` is set." :kconfig:option:`CONFIG_NET_MGMT_EVENT_MONITOR` is set."
"net filter", "View network packet filter rules. Only available if
:kconfig:option:`CONFIG_NET_PKT_FILTER` is set."
"net gptp", "Print information about gPTP support. Only available if "net gptp", "Print information about gPTP support. Only available if
:kconfig:option:`CONFIG_NET_GPTP` is set." :kconfig:option:`CONFIG_NET_GPTP` is set."
"net iface", "Print information about network interfaces." "net iface", "Print information about network interfaces."

View file

@ -268,6 +268,11 @@ config NET_SHELL_PKT_ALLOC_SUPPORTED
default y default y
depends on NET_SHELL_SHOW_DISABLED_COMMANDS || NET_DEBUG_NET_PKT_ALLOC depends on NET_SHELL_SHOW_DISABLED_COMMANDS || NET_DEBUG_NET_PKT_ALLOC
config NET_SHELL_PKT_FILTER_SUPPORTED
bool "Network packet filter related configuration"
default y
depends on NET_SHELL_SHOW_DISABLED_COMMANDS || NET_PKT_FILTER
config NET_SHELL_PMTU_SUPPORTED config NET_SHELL_PMTU_SUPPORTED
bool "PMTU config" bool "PMTU config"
default y default y

View file

@ -24,6 +24,7 @@ zephyr_library_sources(mem.c)
zephyr_library_sources_ifdef(CONFIG_NET_SHELL_IPV6_SUPPORTED nbr.c) zephyr_library_sources_ifdef(CONFIG_NET_SHELL_IPV6_SUPPORTED nbr.c)
zephyr_library_sources_ifdef(CONFIG_NET_SHELL_IP_SUPPORTED ping.c) zephyr_library_sources_ifdef(CONFIG_NET_SHELL_IP_SUPPORTED ping.c)
zephyr_library_sources(pkt.c) zephyr_library_sources(pkt.c)
zephyr_library_sources_ifdef(CONFIG_NET_SHELL_PKT_FILTER_SUPPORTED filter.c)
zephyr_library_sources_ifdef(CONFIG_NET_SHELL_PMTU_SUPPORTED pmtu.c) zephyr_library_sources_ifdef(CONFIG_NET_SHELL_PMTU_SUPPORTED pmtu.c)
zephyr_library_sources_ifdef(CONFIG_NET_SHELL_PPP_SUPPORTED ppp.c) zephyr_library_sources_ifdef(CONFIG_NET_SHELL_PPP_SUPPORTED ppp.c)
zephyr_library_sources_ifdef(CONFIG_NET_SHELL_POWER_MANAGEMENT_SUPPORTED resume.c) zephyr_library_sources_ifdef(CONFIG_NET_SHELL_POWER_MANAGEMENT_SUPPORTED resume.c)

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(net_shell);
#include <zephyr/net/net_pkt_filter.h>
#include "net_shell_private.h"
#if defined(CONFIG_NET_PKT_FILTER)
static const char *rule_type2str(enum npf_rule_type type)
{
switch (type) {
case NPF_RULE_TYPE_SEND:
return "send";
case NPF_RULE_TYPE_RECV:
return "recv";
case NPF_RULE_TYPE_LOCAL_IN_RECV:
return "local recv";
case NPF_RULE_TYPE_IPV4_RECV:
return "IPv4 recv";
case NPF_RULE_TYPE_IPV6_RECV:
return "IPv6 recv";
case NPF_RULE_TYPE_UNKNOWN:
__fallthrough;
default:
break;
}
return "<UNKNOWN>";
}
static const char *verdict2str(enum net_verdict verdict)
{
switch (verdict) {
case NET_OK:
return "OK";
case NET_DROP:
return "DROP";
case NET_CONTINUE:
return "CONTINUE";
default:
break;
}
return "<UNK>";
}
static void rule_cb(struct npf_rule *rule, enum npf_rule_type type, void *user_data)
{
struct net_shell_user_data *data = user_data;
const struct shell *sh = data->sh;
int *count = data->user_data;
PR("[%2d] %-10s %-7s %-5d",
(*count) + 1, rule_type2str(type), verdict2str(rule->result), rule->nb_tests);
for (int i = 0; i < rule->nb_tests; i++) {
/* Allocate room for storing two full IPv4/6 addresses */
#define MAX_BUF_LEN ((IS_ENABLED(CONFIG_NET_IPV6) ? \
INET6_ADDRSTRLEN : INET_ADDRSTRLEN) * 2)
char buf[MAX_BUF_LEN] = { 0 };
struct npf_test *test;
const char *str;
test = rule->tests[i];
str = npf_test_get_str(test, buf, sizeof(buf) - 1);
PR("%s%s%s", str, buf[0] != '\0' ? buf : "",
i == rule->nb_tests - 1 ? "" : ",");
}
PR("\n");
(*count)++;
}
#endif /* CONFIG_NET_PKT_FILTER */
static int cmd_net_filter(const struct shell *sh, size_t argc, char *argv[])
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
#if defined(CONFIG_NET_PKT_FILTER)
struct net_shell_user_data user_data;
int count = 0;
PR("Rule %-10s Verdict Tests \n", "Type");
user_data.sh = sh;
user_data.user_data = &count;
npf_rules_foreach(rule_cb, &user_data);
if (count == 0) {
PR("No network packet filter rules\n");
}
#else
PR_INFO("Set %s to enable %s support.\n",
"CONFIG_NET_PKT_FILTER",
"packet filter information");
#endif /* CONFIG_NET_PKT_FILTER */
return 0;
}
SHELL_SUBCMD_ADD((net), filter, NULL, "Print information about network packet filters.",
cmd_net_filter, 1, 0);