Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[deliverable/linux.git] / net / netfilter / nft_compat.c
index 213584cf04b34858164a07f99f1fc0b623c1ab44..66def315eb5619a26b64da8a1a5525af7d4a5e3f 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv6/ip6_tables.h>
 #include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_arp/arp_tables.h>
 #include <net/netfilter/nf_tables.h>
 
 static int nft_compat_chain_validate_dependency(const char *tablename,
@@ -42,6 +43,7 @@ union nft_entry {
        struct ipt_entry e4;
        struct ip6t_entry e6;
        struct ebt_entry ebt;
+       struct arpt_entry arp;
 };
 
 static inline void
@@ -53,7 +55,7 @@ nft_compat_set_par(struct xt_action_param *par, void *xt, const void *xt_info)
 }
 
 static void nft_target_eval_xt(const struct nft_expr *expr,
-                              struct nft_data data[NFT_REG_MAX + 1],
+                              struct nft_regs *regs,
                               const struct nft_pktinfo *pkt)
 {
        void *info = nft_expr_priv(expr);
@@ -70,16 +72,16 @@ static void nft_target_eval_xt(const struct nft_expr *expr,
 
        switch (ret) {
        case XT_CONTINUE:
-               data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
+               regs->verdict.code = NFT_CONTINUE;
                break;
        default:
-               data[NFT_REG_VERDICT].verdict = ret;
+               regs->verdict.code = ret;
                break;
        }
 }
 
 static void nft_target_eval_bridge(const struct nft_expr *expr,
-                                  struct nft_data data[NFT_REG_MAX + 1],
+                                  struct nft_regs *regs,
                                   const struct nft_pktinfo *pkt)
 {
        void *info = nft_expr_priv(expr);
@@ -96,19 +98,19 @@ static void nft_target_eval_bridge(const struct nft_expr *expr,
 
        switch (ret) {
        case EBT_ACCEPT:
-               data[NFT_REG_VERDICT].verdict = NF_ACCEPT;
+               regs->verdict.code = NF_ACCEPT;
                break;
        case EBT_DROP:
-               data[NFT_REG_VERDICT].verdict = NF_DROP;
+               regs->verdict.code = NF_DROP;
                break;
        case EBT_CONTINUE:
-               data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
+               regs->verdict.code = NFT_CONTINUE;
                break;
        case EBT_RETURN:
-               data[NFT_REG_VERDICT].verdict = NFT_RETURN;
+               regs->verdict.code = NFT_RETURN;
                break;
        default:
-               data[NFT_REG_VERDICT].verdict = ret;
+               regs->verdict.code = ret;
                break;
        }
 }
@@ -133,6 +135,9 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par,
                entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0;
                break;
        case AF_INET6:
+               if (proto)
+                       entry->e6.ipv6.flags |= IP6T_F_PROTO;
+
                entry->e6.ipv6.proto = proto;
                entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
                break;
@@ -140,6 +145,8 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par,
                entry->ebt.ethproto = (__force __be16)proto;
                entry->ebt.invflags = inv ? EBT_IPROTO : 0;
                break;
+       case NFPROTO_ARP:
+               break;
        }
        par->entryinfo  = entry;
        par->target     = target;
@@ -154,6 +161,7 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par,
                par->hook_mask = 0;
        }
        par->family     = ctx->afi->family;
+       par->nft_compat = true;
 }
 
 static void target_compat_from_user(struct xt_target *t, void *in, void *out)
@@ -297,7 +305,7 @@ static int nft_target_validate(const struct nft_ctx *ctx,
 }
 
 static void nft_match_eval(const struct nft_expr *expr,
-                          struct nft_data data[NFT_REG_MAX + 1],
+                          struct nft_regs *regs,
                           const struct nft_pktinfo *pkt)
 {
        void *info = nft_expr_priv(expr);
@@ -310,16 +318,16 @@ static void nft_match_eval(const struct nft_expr *expr,
        ret = match->match(skb, (struct xt_action_param *)&pkt->xt);
 
        if (pkt->xt.hotdrop) {
-               data[NFT_REG_VERDICT].verdict = NF_DROP;
+               regs->verdict.code = NF_DROP;
                return;
        }
 
-       switch(ret) {
-       case true:
-               data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
+       switch (ret ? 1 : 0) {
+       case 1:
+               regs->verdict.code = NFT_CONTINUE;
                break;
-       case false:
-               data[NFT_REG_VERDICT].verdict = NFT_BREAK;
+       case 0:
+               regs->verdict.code = NFT_BREAK;
                break;
        }
 }
@@ -344,6 +352,9 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
                entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0;
                break;
        case AF_INET6:
+               if (proto)
+                       entry->e6.ipv6.flags |= IP6T_F_PROTO;
+
                entry->e6.ipv6.proto = proto;
                entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
                break;
@@ -351,6 +362,8 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
                entry->ebt.ethproto = (__force __be16)proto;
                entry->ebt.invflags = inv ? EBT_IPROTO : 0;
                break;
+       case NFPROTO_ARP:
+               break;
        }
        par->entryinfo  = entry;
        par->match      = match;
@@ -365,6 +378,7 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
                par->hook_mask = 0;
        }
        par->family     = ctx->afi->family;
+       par->nft_compat = true;
 }
 
 static void match_compat_from_user(struct xt_match *m, void *in, void *out)
@@ -537,6 +551,9 @@ nfnl_compat_get(struct sock *nfnl, struct sk_buff *skb,
        case NFPROTO_BRIDGE:
                fmt = "ebt_%s";
                break;
+       case NFPROTO_ARP:
+               fmt = "arpt_%s";
+               break;
        default:
                pr_err("nft_compat: unsupported protocol %d\n",
                        nfmsg->nfgen_family);
This page took 0.030371 seconds and 5 git commands to generate.