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 <fw@xxxxxxxxx> --- doc/additional-commands.txt | 8 ++++---- include/iface.h | 2 ++ src/iface.c | 17 +++++++++++++++++ src/mnl.c | 29 ++++++++++++++++++++++------- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/doc/additional-commands.txt b/doc/additional-commands.txt index 9ad338f8c7d1..0f96fc354007 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 f41ee8be6c89..786b1dfc8f8f 100644 --- a/include/iface.h +++ b/include/iface.h @@ -2,6 +2,7 @@ #define _NFTABLES_IFACE_H_ #include <net/if.h> +#include <list.h> 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 428acaae2eac..a85341a1703a 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 e585241d9395..12e145204ef5 100644 --- a/src/mnl.c +++ b/src/mnl.c @@ -9,6 +9,7 @@ */ #include <nft.h> +#include <iface.h> #include <libmnl/libmnl.h> #include <libnftnl/common.h> @@ -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; } -- 2.44.2