[PATCH nf-next] netfilter: nf_meta: support for nexthop and nexthop6

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

 



From: Anders K. Pedersen <akp@xxxxxxxxxxxx>

Add meta support for IPv4 nexthop and IPv6 nexthop6 (i.e. the directly
connected IP address that an outgoing packet is sent to), which can be used
either for matching or accounting, eg.

 # nft add rule filter postrouting \
	ip daddr 192.168.1.0/24 meta nexthop != 192.168.0.1 drop

This will drop any traffic to 192.168.1.0/24 that is not routed via
192.168.0.1.

 # nft add rule filter postrouting \
	flow table acct { meta nexthop timeout 600s counter }
 # nft add rule ip6 filter postrouting \
	flow table acct { meta nexthop6 timeout 600s counter }

These rules count outgoing traffic per nexthop. Note that the timeout
releases an entry if no traffic is seen for this nexthop within 10 minutes.

Signed-off-by: Anders K. Pedersen <akp@xxxxxxxxxxxx>
---
 include/uapi/linux/netfilter/nf_tables.h |  2 ++
 net/netfilter/nft_meta.c                 | 23 +++++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 24161e2..6ef8ac9 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -721,6 +721,8 @@ enum nft_meta_keys {
 	NFT_META_OIFGROUP,
 	NFT_META_CGROUP,
 	NFT_META_PRANDOM,
+	NFT_META_NEXTHOP,
+	NFT_META_NEXTHOP6,
 };
 
 /**
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 2863f34..a283c80 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -20,6 +20,8 @@
 #include <linux/smp.h>
 #include <linux/static_key.h>
 #include <net/dst.h>
+#include <net/ip6_route.h>
+#include <net/route.h>
 #include <net/sock.h>
 #include <net/tcp_states.h> /* for TCP_TIME_WAIT */
 #include <net/netfilter/nf_tables.h>
@@ -188,6 +190,23 @@ void nft_meta_get_eval(const struct nft_expr *expr,
 		*dest = prandom_u32_state(state);
 		break;
 	}
+	case NFT_META_NEXTHOP: {
+		const struct rtable *rt = skb_rtable(skb);
+
+		if (pkt->pf != NFPROTO_IPV4 || !rt)
+			goto err;
+		*dest = rt_nexthop(rt, ip_hdr(skb)->daddr);
+		break;
+	}
+	case NFT_META_NEXTHOP6: {
+		struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
+
+		if (pkt->pf != NFPROTO_IPV6 || !rt)
+			goto err;
+		memcpy(dest, rt6_nexthop(rt, &ipv6_hdr(skb)->daddr),
+		       sizeof(struct in6_addr));
+		break;
+	}
 	default:
 		WARN_ON(1);
 		goto err;
@@ -271,8 +290,12 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
 #ifdef CONFIG_CGROUP_NET_CLASSID
 	case NFT_META_CGROUP:
 #endif
+	case NFT_META_NEXTHOP:
 		len = sizeof(u32);
 		break;
+	case NFT_META_NEXTHOP6:
+		len = sizeof(struct in6_addr);
+		break;
 	case NFT_META_IIFNAME:
 	case NFT_META_OIFNAME:
 		len = IFNAMSIZ;��.n��������+%������w��{.n����z��׫���n�r������&��z�ޗ�zf���h���~����������_��+v���)ߣ�

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux