From: wenxu <we...@ucloud.cn>

Currently the nft_offload_reg is only can be used for match condition.
Can not be used for action. Add nft_offload_reg_type to make nft_offload_reg
can be used for action also.

Signed-off-by: wenxu <we...@ucloud.cn>
---
 include/net/netfilter/nf_tables_offload.h | 20 +++++++++++++++++-
 net/netfilter/nft_cmp.c                   | 10 ++++-----
 net/netfilter/nft_meta.c                  |  6 ++++--
 net/netfilter/nft_payload.c               | 34 ++++++++++++++++++++-----------
 4 files changed, 50 insertions(+), 20 deletions(-)

diff --git a/include/net/netfilter/nf_tables_offload.h 
b/include/net/netfilter/nf_tables_offload.h
index 275d014..82e3936 100644
--- a/include/net/netfilter/nf_tables_offload.h
+++ b/include/net/netfilter/nf_tables_offload.h
@@ -4,7 +4,13 @@
 #include <net/flow_offload.h>
 #include <net/netfilter/nf_tables.h>
 
-struct nft_offload_reg {
+enum nft_offload_reg_type {
+       NFT_OFFLOAD_REG_UNSPEC  = 0,
+       NFT_OFFLOAD_REG_MATCH,
+       NFT_OFFLOAD_REG_ACTION,
+};
+
+struct nft_offload_match {
        u32             key;
        u32             len;
        u32             base_offset;
@@ -12,6 +18,18 @@ struct nft_offload_reg {
        struct nft_data mask;
 };
 
+struct nft_offload_action {
+       struct nft_data data;
+};
+
+struct nft_offload_reg {
+       enum nft_offload_reg_type type;
+       union {
+               struct nft_offload_match match;
+               struct nft_offload_action action;
+       };
+};
+
 enum nft_offload_dep_type {
        NFT_OFFLOAD_DEP_UNSPEC  = 0,
        NFT_OFFLOAD_DEP_NETWORK,
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index bd173b1..ee38cba 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -116,14 +116,14 @@ static int __nft_cmp_offload(struct nft_offload_ctx *ctx,
        u8 *mask = (u8 *)&flow->match.mask;
        u8 *key = (u8 *)&flow->match.key;
 
-       if (priv->op != NFT_CMP_EQ)
+       if (priv->op != NFT_CMP_EQ || reg->type != NFT_OFFLOAD_REG_MATCH)
                return -EOPNOTSUPP;
 
-       memcpy(key + reg->offset, &priv->data, priv->len);
-       memcpy(mask + reg->offset, &reg->mask, priv->len);
+       memcpy(key + reg->match.offset, &priv->data, priv->len);
+       memcpy(mask + reg->match.offset, &reg->match.mask, priv->len);
 
-       flow->match.dissector.used_keys |= BIT(reg->key);
-       flow->match.dissector.offset[reg->key] = reg->base_offset;
+       flow->match.dissector.used_keys |= BIT(reg->match.key);
+       flow->match.dissector.offset[reg->match.key] = reg->match.base_offset;
 
        nft_offload_update_dependency(ctx, &priv->data, priv->len);
 
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index f1b1d94..6bb5ba6 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -498,15 +498,17 @@ static int nft_meta_get_offload(struct nft_offload_ctx 
*ctx,
        const struct nft_meta *priv = nft_expr_priv(expr);
        struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+       reg->type = NFT_OFFLOAD_REG_MATCH;
+
        switch (priv->key) {
        case NFT_META_PROTOCOL:
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, n_proto,
-                                 sizeof(__u16), reg);
+                                 sizeof(__u16), &reg->match);
                nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
                break;
        case NFT_META_L4PROTO:
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
-                                 sizeof(__u8), reg);
+                                 sizeof(__u8), &reg->match);
                nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
                break;
        default:
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 22a80eb..36efa1c 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -159,14 +159,16 @@ static int nft_payload_offload_ll(struct nft_offload_ctx 
*ctx,
 {
        struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+       reg->type = NFT_OFFLOAD_REG_MATCH;
+
        switch (priv->offset) {
        case offsetof(struct ethhdr, h_source):
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
-                                 src, ETH_ALEN, reg);
+                                 src, ETH_ALEN, &reg->match);
                break;
        case offsetof(struct ethhdr, h_dest):
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs,
-                                 dst, ETH_ALEN, reg);
+                                 dst, ETH_ALEN, &reg->match);
                break;
        }
 
@@ -179,18 +181,20 @@ static int nft_payload_offload_ip(struct nft_offload_ctx 
*ctx,
 {
        struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+       reg->type = NFT_OFFLOAD_REG_MATCH;
+
        switch (priv->offset) {
        case offsetof(struct iphdr, saddr):
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, src,
-                                 sizeof(struct in_addr), reg);
+                                 sizeof(struct in_addr), &reg->match);
                break;
        case offsetof(struct iphdr, daddr):
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, dst,
-                                 sizeof(struct in_addr), reg);
+                                 sizeof(struct in_addr), &reg->match);
                break;
        case offsetof(struct iphdr, protocol):
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
-                                 sizeof(__u8), reg);
+                                 sizeof(__u8), &reg->match);
                nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
                break;
        default:
@@ -206,18 +210,20 @@ static int nft_payload_offload_ip6(struct nft_offload_ctx 
*ctx,
 {
        struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+       reg->type = NFT_OFFLOAD_REG_MATCH;
+
        switch (priv->offset) {
        case offsetof(struct ipv6hdr, saddr):
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, src,
-                                 sizeof(struct in6_addr), reg);
+                                 sizeof(struct in6_addr), &reg->match);
                break;
        case offsetof(struct ipv6hdr, daddr):
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, dst,
-                                 sizeof(struct in6_addr), reg);
+                                 sizeof(struct in6_addr), &reg->match);
                break;
        case offsetof(struct ipv6hdr, nexthdr):
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
-                                 sizeof(__u8), reg);
+                                 sizeof(__u8), &reg->match);
                nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
                break;
        default:
@@ -253,14 +259,16 @@ static int nft_payload_offload_tcp(struct nft_offload_ctx 
*ctx,
 {
        struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+       reg->type = NFT_OFFLOAD_REG_MATCH;
+
        switch (priv->offset) {
        case offsetof(struct tcphdr, source):
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src,
-                                 sizeof(__be16), reg);
+                                 sizeof(__be16), &reg->match);
                break;
        case offsetof(struct tcphdr, dest):
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst,
-                                 sizeof(__be16), reg);
+                                 sizeof(__be16), &reg->match);
                break;
        default:
                return -EOPNOTSUPP;
@@ -275,14 +283,16 @@ static int nft_payload_offload_udp(struct nft_offload_ctx 
*ctx,
 {
        struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
 
+       reg->type = NFT_OFFLOAD_REG_MATCH;
+
        switch (priv->offset) {
        case offsetof(struct udphdr, source):
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src,
-                                 sizeof(__be16), reg);
+                                 sizeof(__be16), &reg->match);
                break;
        case offsetof(struct udphdr, dest):
                NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst,
-                                 sizeof(__be16), reg);
+                                 sizeof(__be16), &reg->match);
                break;
        default:
                return -EOPNOTSUPP;
-- 
1.8.3.1

Reply via email to