From: Florian Westphal Date: Tue, 20 Aug 2024 22:12:27 +0000 (+0200) Subject: src: mnl: always dump all netdev hooks if no interface name was given X-Git-Tag: v1.1.1~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=db70959a5ccf2952b218f51c3d529e186a5a43bb;p=thirdparty%2Fnftables.git src: mnl: always dump all netdev hooks if no interface name was given Instead of not returning any results for nft list hooks netdev Iterate all interfaces and then query all of them. Signed-off-by: Florian Westphal --- diff --git a/doc/additional-commands.txt b/doc/additional-commands.txt index 9ad338f8..2ebc2993 100644 --- a/doc/additional-commands.txt +++ b/doc/additional-commands.txt @@ -8,13 +8,13 @@ registered implicitly by kernel modules such as nf_conntrack. + [verse] ____ *list hooks* ['family'] -*list hooks netdev device* 'DEVICE_NAME' +*list hooks netdev* [ *device* 'DEVICE_NAME' ] ____ *list hooks* is enough to display everything that is active -on the system, however, it does currently omit hooks that are -tied to a specific network device (netdev family). To obtain -those, the network device needs to be queried by name. +on the system. Hooks in the netdev family are tied to a network +device. If no device name is given, nft will query all network +devices in the current network namespace. Example Usage: .List all active netfilter hooks in either the ip or ip6 stack diff --git a/include/iface.h b/include/iface.h index f41ee8be..786b1dfc 100644 --- a/include/iface.h +++ b/include/iface.h @@ -2,6 +2,7 @@ #define _NFTABLES_IFACE_H_ #include +#include struct iface { struct list_head list; @@ -15,4 +16,5 @@ char *nft_if_indextoname(unsigned int ifindex, char *name); void iface_cache_update(void); void iface_cache_release(void); +const struct iface *iface_cache_get_next_entry(const struct iface *prev); #endif diff --git a/src/iface.c b/src/iface.c index 428acaae..a85341a1 100644 --- a/src/iface.c +++ b/src/iface.c @@ -171,3 +171,20 @@ char *nft_if_indextoname(unsigned int ifindex, char *name) } return NULL; } + +const struct iface *iface_cache_get_next_entry(const struct iface *prev) +{ + if (!iface_cache_init) + iface_cache_update(); + + if (list_empty(&iface_list)) + return NULL; + + if (!prev) + return list_first_entry(&iface_list, struct iface, list); + + if (list_is_last(&prev->list, &iface_list)) + return NULL; + + return list_next_entry(prev, list); +} diff --git a/src/mnl.c b/src/mnl.c index e585241d..12e14520 100644 --- a/src/mnl.c +++ b/src/mnl.c @@ -9,6 +9,7 @@ */ #include +#include #include #include @@ -2205,7 +2206,7 @@ static void basehook_list_add_tail(struct basehook *b, struct list_head *head) list_for_each_entry(hook, head, list) { if (hook->family != b->family) continue; - if (hook->num != b->num) + if (!basehook_eq(hook, b)) continue; if (hook->prio < b->prio) continue; @@ -2591,11 +2592,9 @@ int mnl_nft_dump_nf_hooks(struct netlink_ctx *ctx, int family, const char *devna if (tmp == 0) ret = 0; - if (devname) { - tmp = mnl_nft_dump_nf_hooks(ctx, NFPROTO_NETDEV, devname); - if (tmp == 0) - ret = 0; - } + tmp = mnl_nft_dump_nf_hooks(ctx, NFPROTO_NETDEV, devname); + if (tmp == 0) + ret = 0; return ret; case NFPROTO_INET: @@ -2622,7 +2621,23 @@ int mnl_nft_dump_nf_hooks(struct netlink_ctx *ctx, int family, const char *devna ret = mnl_nft_dump_nf_arp(ctx, family, devname, &hook_list); break; case NFPROTO_NETDEV: - ret = mnl_nft_dump_nf_netdev(ctx, family, devname, &hook_list); + if (devname) { + ret = mnl_nft_dump_nf_netdev(ctx, family, devname, &hook_list); + } else { + const struct iface *iface; + + iface = iface_cache_get_next_entry(NULL); + ret = 0; + + while (iface) { + tmp = mnl_nft_dump_nf_netdev(ctx, family, iface->name, &hook_list); + if (tmp == 0) + ret = 0; + + iface = iface_cache_get_next_entry(iface); + } + } + break; }