The 'id' key allows for matching on the id of the conntrack entry.

This is most useful as a key for maps

nft add map nat conntoip { type ct_id: ipv4_addr \; }
nft add rule ip nat postrouting snat ct id map @conntoip

Signed-off-by: Brett Mastbergen <[email protected]>
---
 doc/payload-expression.txt          |  5 ++++-
 include/ct.h                        |  1 +
 include/datatype.h                  |  1 +
 include/linux/netfilter/nf_tables.h |  2 ++
 src/ct.c                            | 11 +++++++++++
 src/datatype.c                      |  1 +
 src/parser_bison.y                  |  1 +
 7 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/doc/payload-expression.txt b/doc/payload-expression.txt
index 28061f3..e93022b 100644
--- a/doc/payload-expression.txt
+++ b/doc/payload-expression.txt
@@ -588,7 +588,7 @@ is true for the *zone*, if a direction is given, the zone 
is only matched if the
 zone id is tied to the given direction. +
 
 [verse]
-*ct* {state | direction | status | mark | expiration | helper | label | 
l3proto | protocol | bytes | packets | avgpkt | zone}
+*ct* {state | direction | status | mark | expiration | helper | label | 
l3proto | protocol | bytes | packets | avgpkt | zone | id}
 *ct* {original | reply} {l3proto | protocol | proto-src | proto-dst | bytes | 
packets | avgpkt | zone}
 *ct* {original | reply} {ip | ip6} {saddr | daddr}
 
@@ -650,6 +650,9 @@ integer (16 bit)
 |count|
 count number of connections
 integer (32 bit)
+|id|
+Connection id
+ct_id
 |==========================================
 A description of conntrack-specific types listed above can be found 
sub-section CONNTRACK TYPES above.
 
diff --git a/include/ct.h b/include/ct.h
index 4c5bd80..1e707e7 100644
--- a/include/ct.h
+++ b/include/ct.h
@@ -39,5 +39,6 @@ extern const char *ct_label2str(unsigned long value);
 extern const struct datatype ct_dir_type;
 extern const struct datatype ct_state_type;
 extern const struct datatype ct_status_type;
+extern const struct datatype ct_id_type;
 
 #endif /* NFTABLES_CT_H */
diff --git a/include/datatype.h b/include/datatype.h
index 14ece28..73a9cf2 100644
--- a/include/datatype.h
+++ b/include/datatype.h
@@ -90,6 +90,7 @@ enum datatypes {
        TYPE_CT_EVENTBIT,
        TYPE_IFNAME,
        TYPE_IGMP_TYPE,
+       TYPE_CT_ID,
        __TYPE_MAX
 };
 #define TYPE_MAX               (__TYPE_MAX - 1)
diff --git a/include/linux/netfilter/nf_tables.h 
b/include/linux/netfilter/nf_tables.h
index 09a7b9e..150f32a 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -986,6 +986,7 @@ enum nft_osf_flags {
  * @NFT_CT_SRC_IP6: conntrack layer 3 protocol source (IPv6 address)
  * @NFT_CT_DST_IP6: conntrack layer 3 protocol destination (IPv6 address)
  * @NFT_CT_TIMEOUT: connection tracking timeout policy assigned to conntrack
+ * @NFT_CT_ID: conntrack id
  */
 enum nft_ct_keys {
        NFT_CT_STATE,
@@ -1012,6 +1013,7 @@ enum nft_ct_keys {
        NFT_CT_SRC_IP6,
        NFT_CT_DST_IP6,
        NFT_CT_TIMEOUT,
+       NFT_CT_ID,
        __NFT_CT_MAX
 };
 #define NFT_CT_MAX             (__NFT_CT_MAX - 1)
diff --git a/src/ct.c b/src/ct.c
index 2256ce3..21bc182 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -239,6 +239,15 @@ void ct_label_table_exit(void)
        rt_symbol_table_free(ct_label_tbl);
 }
 
+const struct datatype ct_id_type = {
+       .type           = TYPE_CT_ID,
+       .name           = "ct_id",
+       .desc           = "conntrack id",
+       .byteorder      = BYTEORDER_BIG_ENDIAN,
+       .size           = 4 * BITS_PER_BYTE,
+       .basetype       = &integer_type,
+};
+
 #ifndef NF_CT_HELPER_NAME_LEN
 #define NF_CT_HELPER_NAME_LEN  16
 #endif
@@ -291,6 +300,8 @@ const struct ct_template ct_templates[__NFT_CT_MAX] = {
                                              BYTEORDER_HOST_ENDIAN, 16),
        [NFT_CT_EVENTMASK]      = CT_TEMPLATE("event", &ct_event_type,
                                              BYTEORDER_HOST_ENDIAN, 32),
+       [NFT_CT_ID]             = CT_TEMPLATE("id", &ct_id_type,
+                                             BYTEORDER_BIG_ENDIAN, 32),
 };
 
 static void ct_print(enum nft_ct_keys key, int8_t dir, uint8_t nfproto,
diff --git a/src/datatype.c b/src/datatype.c
index ac9f2af..6b76fc9 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -71,6 +71,7 @@ static const struct datatype *datatypes[TYPE_MAX + 1] = {
        [TYPE_BOOLEAN]          = &boolean_type,
        [TYPE_IFNAME]           = &ifname_type,
        [TYPE_IGMP_TYPE]        = &igmp_type_type,
+       [TYPE_CT_ID]            = &ct_id_type,
 };
 
 const struct datatype *datatype_lookup(enum datatypes type)
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 4a2a81c..92660ce 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -4100,6 +4100,7 @@ ct_key                    :       L3PROTOCOL      { $$ = 
NFT_CT_L3PROTOCOL; }
                        |       LABEL           { $$ = NFT_CT_LABELS; }
                        |       EVENT           { $$ = NFT_CT_EVENTMASK; }
                        |       TIMEOUT         { $$ = NFT_CT_TIMEOUT; }
+                       |       ID              { $$ = NFT_CT_ID; }
                        |       ct_key_dir_optional
                        ;
 
-- 
2.11.0

Reply via email to