diff mbox

[nft] meta: support for nexthop and nexthop6

Message ID 1473832128.1006.37.camel@cohaesio.com
State Changes Requested
Delegated to: Pablo Neira
Headers show

Commit Message

Anders K. Pedersen | Cohaesio Sept. 14, 2016, 5:48 a.m. UTC
From: Anders K. Pedersen <akp@cohaesio.com>


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@cohaesio.com>

---
 doc/nft.xml                         | 12 ++++++++++++
 include/linux/netfilter/nf_tables.h |  2 ++
 src/meta.c                          |  8 ++++++++
 src/parser_bison.y                  |  4 ++++
 src/scanner.l                       |  2 ++
 5 files changed, 28 insertions(+)
diff mbox

Patch

diff --git a/doc/nft.xml b/doc/nft.xml
index 3b215f8..c391a88 100644
--- a/doc/nft.xml
+++ b/doc/nft.xml
@@ -978,6 +978,8 @@  filter output ip6 daddr ::1
 						<arg>l4proto</arg>
 						<arg>protocol</arg>
 						<arg>priority</arg>
+						<arg>nexthop</arg>
+						<arg>nexthop6</arg>
 					</group>
 				</cmdsynopsis>
 				<cmdsynopsis>
@@ -1134,6 +1136,16 @@  filter output ip6 daddr ::1
 								<entry>pseudo-random number</entry>
 								<entry>integer (32 bits)</entry>
 							</row>
+							<row>
+								<entry>nexthop</entry>
+								<entry>next hop address for the IPv4 packet</entry>
+								<entry>ipv4_addr</entry>
+							</row>
+							<row>
+								<entry>nexthop6</entry>
+								<entry>next hop address for the IPv6 packet</entry>
+								<entry>ipv6_addr</entry>
+							</row>
 						</tbody>
 					</tgroup>
 				</table>
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 8a63f22..da39228 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/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/src/meta.c b/src/meta.c
index 87eafee..31bf0ea 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -432,6 +432,12 @@  static const struct meta_template meta_templates[] = {
 	[NFT_META_PRANDOM]	= META_TEMPLATE("random",    &integer_type,
 						4 * BITS_PER_BYTE,
 						BYTEORDER_BIG_ENDIAN), /* avoid conversion; doesn't have endianess */
+	[NFT_META_NEXTHOP]	= META_TEMPLATE("nexthop",    &ipaddr_type,
+						4 * BITS_PER_BYTE,
+						BYTEORDER_BIG_ENDIAN),
+	[NFT_META_NEXTHOP6]	= META_TEMPLATE("nexthop6",   &ip6addr_type,
+						16 * BITS_PER_BYTE,
+						BYTEORDER_BIG_ENDIAN),
 };
 
 static bool meta_key_is_qualified(enum nft_meta_keys key)
@@ -443,6 +449,8 @@  static bool meta_key_is_qualified(enum nft_meta_keys key)
 	case NFT_META_PROTOCOL:
 	case NFT_META_PRIORITY:
 	case NFT_META_PRANDOM:
+	case NFT_META_NEXTHOP:
+	case NFT_META_NEXTHOP6:
 		return true;
 	default:
 		return false;
diff --git a/src/parser_bison.y b/src/parser_bison.y
index aac10dc..ce84ca2 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -339,6 +339,8 @@  static void location_update(struct location *loc, struct location *rhs, int n)
 %token IIFGROUP			"iifgroup"
 %token OIFGROUP			"oifgroup"
 %token CGROUP			"cgroup"
+%token NEXTHOP			"nexthop"
+%token NEXTHOP6			"nexthop6"
 
 %token CT			"ct"
 %token DIRECTION		"direction"
@@ -2438,6 +2440,8 @@  meta_key_qualified	:	LENGTH		{ $$ = NFT_META_LEN; }
 			|	PROTOCOL	{ $$ = NFT_META_PROTOCOL; }
 			|	PRIORITY	{ $$ = NFT_META_PRIORITY; }
 			|	RANDOM		{ $$ = NFT_META_PRANDOM; }
+			|	NEXTHOP		{ $$ = NFT_META_NEXTHOP; }
+			|	NEXTHOP6	{ $$ = NFT_META_NEXTHOP6; }
 			;
 
 meta_key_unqualified	:	MARK		{ $$ = NFT_META_MARK; }
diff --git a/src/scanner.l b/src/scanner.l
index 8b5a383..cc618dd 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -455,6 +455,8 @@  addrstring	({macaddr}|{ip4addr}|{ip6addr})
 "iifgroup"		{ return IIFGROUP; }
 "oifgroup"		{ return OIFGROUP; }
 "cgroup"		{ return CGROUP; }
+"nexthop"		{ return NEXTHOP; }
+"nexthop6"		{ return NEXTHOP6; }
 
 "ct"			{ return CT; }
 "direction"		{ return DIRECTION; }