Merge tag 'nfc-next-4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo...
[deliverable/linux.git] / net / netfilter / nft_compat.c
index 1279cd85663e67594ac7e3a6be052577cc47284e..0d137c1ac889ea2cd8f74aaf71238773855198c0 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
@@ -123,7 +125,7 @@ static void
 nft_target_set_tgchk_param(struct xt_tgchk_param *par,
                           const struct nft_ctx *ctx,
                           struct xt_target *target, void *info,
-                          union nft_entry *entry, u8 proto, bool inv)
+                          union nft_entry *entry, u16 proto, bool inv)
 {
        par->net        = ctx->net;
        par->table      = ctx->table->name;
@@ -133,13 +135,18 @@ 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;
        case NFPROTO_BRIDGE:
-               entry->ebt.ethproto = proto;
+               entry->ebt.ethproto = (__force __be16)proto;
                entry->ebt.invflags = inv ? EBT_IPROTO : 0;
                break;
+       case NFPROTO_ARP:
+               break;
        }
        par->entryinfo  = entry;
        par->target     = target;
@@ -171,7 +178,7 @@ static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1]
        [NFTA_RULE_COMPAT_FLAGS]        = { .type = NLA_U32 },
 };
 
-static int nft_parse_compat(const struct nlattr *attr, u8 *proto, bool *inv)
+static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv)
 {
        struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1];
        u32 flags;
@@ -203,7 +210,7 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
        struct xt_target *target = expr->ops->data;
        struct xt_tgchk_param par;
        size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO]));
-       u8 proto = 0;
+       u16 proto = 0;
        bool inv = false;
        union nft_entry e = {};
        int ret;
@@ -314,11 +321,11 @@ static void nft_match_eval(const struct nft_expr *expr,
                return;
        }
 
-       switch(ret) {
-       case true:
+       switch (ret ? 1 : 0) {
+       case 1:
                data[NFT_REG_VERDICT].verdict = NFT_CONTINUE;
                break;
-       case false:
+       case 0:
                data[NFT_REG_VERDICT].verdict = NFT_BREAK;
                break;
        }
@@ -334,7 +341,7 @@ static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = {
 static void
 nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
                          struct xt_match *match, void *info,
-                         union nft_entry *entry, u8 proto, bool inv)
+                         union nft_entry *entry, u16 proto, bool inv)
 {
        par->net        = ctx->net;
        par->table      = ctx->table->name;
@@ -344,13 +351,18 @@ 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;
        case NFPROTO_BRIDGE:
-               entry->ebt.ethproto = proto;
+               entry->ebt.ethproto = (__force __be16)proto;
                entry->ebt.invflags = inv ? EBT_IPROTO : 0;
                break;
+       case NFPROTO_ARP:
+               break;
        }
        par->entryinfo  = entry;
        par->match      = match;
@@ -385,7 +397,7 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
        struct xt_match *match = expr->ops->data;
        struct xt_mtchk_param par;
        size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO]));
-       u8 proto = 0;
+       u16 proto = 0;
        bool inv = false;
        union nft_entry e = {};
        int ret;
@@ -537,6 +549,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.027742 seconds and 5 git commands to generate.