[PATCH nft v2 2/5] src: mnl: make family specification more strict when listing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



make "nft list hooks <family>" more strict.

nft list hooks: query/list all NFPROTO_XXX values, i.e.
arp, bridge, ipv4, ipv6.

If a device is also given, then do include the netdev family for
the given device as well.

"nft list hooks arp" will only dump the hooks registered
for NFPROTO_ARP (or nothing at all if none are active).

"bridge", "ip", "ip6" will list the pre/in/forward/output/postrouting
hooks for these families, if any.

"inet" serves as an alias for "ip" and "ip6".

Link: https://lore.kernel.org/netfilter-devel/20240729153211.GA26048@xxxxxxxxxxxxx/
Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
---
 src/mnl.c | 53 ++++++++++++++++++++++++-----------------------------
 1 file changed, 24 insertions(+), 29 deletions(-)

diff --git a/src/mnl.c b/src/mnl.c
index e4bbbcf6d536..88475ef4c25e 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -2391,25 +2391,6 @@ static int dump_nf_hooks(const struct nlmsghdr *nlh, void *_data)
 
 	hook->family = nfg->nfgen_family;
 
-	/* Netdev hooks potentially interfer with this family datapath. */
-	if (hook->family == NFPROTO_NETDEV) {
-		switch (data->family) {
-		case NFPROTO_IPV4:
-		case NFPROTO_IPV6:
-		case NFPROTO_INET:
-		case NFPROTO_BRIDGE:
-			hook->family = data->family;
-			hook->num = NF_INET_INGRESS;
-			break;
-		case NFPROTO_ARP:
-			if (hook->chain_family == NFPROTO_NETDEV) {
-				hook->family = data->family;
-				hook->num = __NF_ARP_INGRESS;
-			}
-			break;
-		}
-	}
-
 	basehook_list_add_tail(hook, data->hook_list);
 
 	return MNL_CB_OK;
@@ -2523,9 +2504,6 @@ static int mnl_nft_dump_nf(struct netlink_ctx *ctx, int family, int hook,
 {
 	int i, err;
 
-	/* show ingress in first place in hook listing. */
-	err = __mnl_nft_dump_nf_hooks(ctx, family, NFPROTO_NETDEV, NF_NETDEV_INGRESS, devname, hook_list);
-
 	for (i = 0; i <= NF_INET_POST_ROUTING; i++) {
 		int tmp;
 
@@ -2566,6 +2544,12 @@ static void release_hook_list(struct list_head *hook_list)
 		basehook_free(hook);
 }
 
+static void warn_if_device(struct nft_ctx *nft, const char *devname)
+{
+	if (devname)
+		nft_print(&nft->output, "# device keyword (%s) unexpected for this family\n", devname);
+}
+
 int mnl_nft_dump_nf_hooks(struct netlink_ctx *ctx, int family, int hook, const char *devname)
 {
 	LIST_HEAD(hook_list);
@@ -2576,30 +2560,41 @@ int mnl_nft_dump_nf_hooks(struct netlink_ctx *ctx, int family, int hook, const c
 	switch (family) {
 	case NFPROTO_UNSPEC:
 		ret = mnl_nft_dump_nf_hooks(ctx, NFPROTO_ARP, hook, NULL);
-		tmp = mnl_nft_dump_nf_hooks(ctx, NFPROTO_INET, hook, devname);
+		tmp = mnl_nft_dump_nf_hooks(ctx, NFPROTO_INET, hook, NULL);
 		if (tmp == 0)
 			ret = 0;
 		tmp = mnl_nft_dump_nf_hooks(ctx, NFPROTO_BRIDGE, hook, NULL);
 		if (tmp == 0)
 			ret = 0;
-		tmp = mnl_nft_dump_nf_hooks(ctx, NFPROTO_NETDEV, hook, devname);
-		if (tmp == 0)
-			ret = 0;
+
+		if (devname) {
+			tmp = mnl_nft_dump_nf_hooks(ctx, NFPROTO_NETDEV, hook, devname);
+			if (tmp == 0)
+				ret = 0;
+		}
 
 		return ret;
 	case NFPROTO_INET:
-		ret = mnl_nft_dump_nf_hooks(ctx, NFPROTO_IPV4, hook, devname);
-		tmp = mnl_nft_dump_nf_hooks(ctx, NFPROTO_IPV6, hook, devname);
+		ret = 0;
+		if (devname)
+			ret = __mnl_nft_dump_nf_hooks(ctx, family, NFPROTO_NETDEV,
+						      NF_NETDEV_INGRESS, devname, &hook_list);
+		tmp = mnl_nft_dump_nf_hooks(ctx, NFPROTO_IPV4, hook, NULL);
+		if (tmp == 0)
+			ret = 0;
+		tmp = mnl_nft_dump_nf_hooks(ctx, NFPROTO_IPV6, hook, NULL);
 		if (tmp == 0)
 			ret = 0;
 
-		return ret;
+		break;
 	case NFPROTO_IPV4:
 	case NFPROTO_IPV6:
 	case NFPROTO_BRIDGE:
+		warn_if_device(ctx->nft, devname);
 		ret = mnl_nft_dump_nf(ctx, family, hook, devname, &hook_list);
 		break;
 	case NFPROTO_ARP:
+		warn_if_device(ctx->nft, devname);
 		ret = mnl_nft_dump_nf_arp(ctx, family, hook, devname, &hook_list);
 		break;
 	case NFPROTO_NETDEV:
-- 
2.44.2





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux