netfilter: nf_tables: get rid of NFT_REG_VERDICT usage
[deliverable/linux.git] / net / netfilter / nft_ct.c
index cc5603016242ea8e1f5cdce1d633e3a2687276ae..077e06b5308e4080dfccb2d3c81057fb1e083d93 100644 (file)
@@ -31,11 +31,11 @@ struct nft_ct {
 };
 
 static void nft_ct_get_eval(const struct nft_expr *expr,
-                           struct nft_data data[NFT_REG_MAX + 1],
+                           struct nft_regs *regs,
                            const struct nft_pktinfo *pkt)
 {
        const struct nft_ct *priv = nft_expr_priv(expr);
-       struct nft_data *dest = &data[priv->dreg];
+       struct nft_data *dest = &regs->data[priv->dreg];
        enum ip_conntrack_info ctinfo;
        const struct nf_conn *ct;
        const struct nf_conn_help *help;
@@ -56,6 +56,8 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
                        state = NF_CT_STATE_BIT(ctinfo);
                dest->data[0] = state;
                return;
+       default:
+               break;
        }
 
        if (ct == NULL)
@@ -93,8 +95,6 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
                helper = rcu_dereference(help->helper);
                if (helper == NULL)
                        goto err;
-               if (strlen(helper->name) >= sizeof(dest->data))
-                       goto err;
                strncpy((char *)dest->data, helper->name, sizeof(dest->data));
                return;
 #ifdef CONFIG_NF_CONNTRACK_LABELS
@@ -107,9 +107,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
                        return;
                }
 
-               BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > sizeof(dest->data));
                size = labels->words * sizeof(long);
-
                memcpy(dest->data, labels->bits, size);
                if (size < sizeof(dest->data))
                        memset(((char *) dest->data) + size, 0,
@@ -117,6 +115,8 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
                return;
        }
 #endif
+       default:
+               break;
        }
 
        tuple = &ct->tuplehash[priv->dir].tuple;
@@ -141,20 +141,22 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
        case NFT_CT_PROTO_DST:
                dest->data[0] = (__force __u16)tuple->dst.u.all;
                return;
+       default:
+               break;
        }
        return;
 err:
-       data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+       regs->verdict.code = NFT_BREAK;
 }
 
 static void nft_ct_set_eval(const struct nft_expr *expr,
-                           struct nft_data data[NFT_REG_MAX + 1],
+                           struct nft_regs *regs,
                            const struct nft_pktinfo *pkt)
 {
        const struct nft_ct *priv = nft_expr_priv(expr);
        struct sk_buff *skb = pkt->skb;
 #ifdef CONFIG_NF_CONNTRACK_MARK
-       u32 value = data[priv->sreg].data[0];
+       u32 value = regs->data[priv->sreg].data[0];
 #endif
        enum ip_conntrack_info ctinfo;
        struct nf_conn *ct;
@@ -172,6 +174,8 @@ static void nft_ct_set_eval(const struct nft_expr *expr,
                }
                break;
 #endif
+       default:
+               break;
        }
 }
 
@@ -220,12 +224,17 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
                           const struct nlattr * const tb[])
 {
        struct nft_ct *priv = nft_expr_priv(expr);
+       unsigned int len;
        int err;
 
        priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
        switch (priv->key) {
-       case NFT_CT_STATE:
        case NFT_CT_DIRECTION:
+               if (tb[NFTA_CT_DIRECTION] != NULL)
+                       return -EINVAL;
+               len = sizeof(u8);
+               break;
+       case NFT_CT_STATE:
        case NFT_CT_STATUS:
 #ifdef CONFIG_NF_CONNTRACK_MARK
        case NFT_CT_MARK:
@@ -233,22 +242,54 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
 #ifdef CONFIG_NF_CONNTRACK_SECMARK
        case NFT_CT_SECMARK:
 #endif
+       case NFT_CT_EXPIRATION:
+               if (tb[NFTA_CT_DIRECTION] != NULL)
+                       return -EINVAL;
+               len = sizeof(u32);
+               break;
 #ifdef CONFIG_NF_CONNTRACK_LABELS
        case NFT_CT_LABELS:
+               if (tb[NFTA_CT_DIRECTION] != NULL)
+                       return -EINVAL;
+               len = NF_CT_LABELS_MAX_SIZE;
+               break;
 #endif
-       case NFT_CT_EXPIRATION:
        case NFT_CT_HELPER:
                if (tb[NFTA_CT_DIRECTION] != NULL)
                        return -EINVAL;
+               len = NF_CT_HELPER_NAME_LEN;
                break;
+
        case NFT_CT_L3PROTOCOL:
        case NFT_CT_PROTOCOL:
+               if (tb[NFTA_CT_DIRECTION] == NULL)
+                       return -EINVAL;
+               len = sizeof(u8);
+               break;
        case NFT_CT_SRC:
        case NFT_CT_DST:
+               if (tb[NFTA_CT_DIRECTION] == NULL)
+                       return -EINVAL;
+
+               switch (ctx->afi->family) {
+               case NFPROTO_IPV4:
+                       len = FIELD_SIZEOF(struct nf_conntrack_tuple,
+                                          src.u3.ip);
+                       break;
+               case NFPROTO_IPV6:
+               case NFPROTO_INET:
+                       len = FIELD_SIZEOF(struct nf_conntrack_tuple,
+                                          src.u3.ip6);
+                       break;
+               default:
+                       return -EAFNOSUPPORT;
+               }
+               break;
        case NFT_CT_PROTO_SRC:
        case NFT_CT_PROTO_DST:
                if (tb[NFTA_CT_DIRECTION] == NULL)
                        return -EINVAL;
+               len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
                break;
        default:
                return -EOPNOTSUPP;
@@ -266,11 +307,8 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
        }
 
        priv->dreg = ntohl(nla_get_be32(tb[NFTA_CT_DREG]));
-       err = nft_validate_output_register(priv->dreg);
-       if (err < 0)
-               return err;
-
-       err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
+       err = nft_validate_register_store(ctx, priv->dreg, NULL,
+                                         NFT_DATA_VALUE, len);
        if (err < 0)
                return err;
 
@@ -286,12 +324,14 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
                           const struct nlattr * const tb[])
 {
        struct nft_ct *priv = nft_expr_priv(expr);
+       unsigned int len;
        int err;
 
        priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
        switch (priv->key) {
 #ifdef CONFIG_NF_CONNTRACK_MARK
        case NFT_CT_MARK:
+               len = FIELD_SIZEOF(struct nf_conn, mark);
                break;
 #endif
        default:
@@ -299,7 +339,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
        }
 
        priv->sreg = ntohl(nla_get_be32(tb[NFTA_CT_SREG]));
-       err = nft_validate_input_register(priv->sreg);
+       err = nft_validate_register_load(priv->sreg, len);
        if (err < 0)
                return err;
 
This page took 0.029676 seconds and 5 git commands to generate.