netfilter: conntrack: compute l3proto nla size at compile time
authorFlorian Westphal <fw@strlen.de>
Fri, 11 Aug 2017 22:57:02 +0000 (00:57 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 24 Aug 2017 16:52:32 +0000 (18:52 +0200)
avoids a pointer and allows struct to be const later on.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/nf_conntrack_l3proto.h
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_proto.c

index 1b8de164d7446108d0a1748a074629cbc40549cc..6a27ffea7480be4c39f7357e414bec2fc34077a3 100644 (file)
@@ -20,6 +20,9 @@ struct nf_conntrack_l3proto {
        /* L3 Protocol Family number. ex) PF_INET */
        u_int16_t l3proto;
 
+       /* size of tuple nlattr, fills a hole */
+       u16 nla_size;
+
        /* Protocol name */
        const char *name;
 
@@ -49,23 +52,17 @@ struct nf_conntrack_l3proto {
        int (*get_l4proto)(const struct sk_buff *skb, unsigned int nhoff,
                           unsigned int *dataoff, u_int8_t *protonum);
 
+#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
        int (*tuple_to_nlattr)(struct sk_buff *skb,
                               const struct nf_conntrack_tuple *t);
-
-       /* Called when netns wants to use connection tracking */
-       int (*net_ns_get)(struct net *);
-       void (*net_ns_put)(struct net *);
-
-       /*
-        * Calculate size of tuple nlattr
-        */
-       int (*nlattr_tuple_size)(void);
-
        int (*nlattr_to_tuple)(struct nlattr *tb[],
                               struct nf_conntrack_tuple *t);
        const struct nla_policy *nla_policy;
+#endif
 
-       size_t nla_size;
+       /* Called when netns wants to use connection tracking */
+       int (*net_ns_get)(struct net *);
+       void (*net_ns_put)(struct net *);
 
        /* Module (if any) which this is connected to. */
        struct module *me;
index de5f0e6ddd1b1a95b68a302e18640a32e26c2a30..9fb8cb033d80434cdb6c64c65ee0b7e597616890 100644 (file)
@@ -303,11 +303,6 @@ static int ipv4_nlattr_to_tuple(struct nlattr *tb[],
 
        return 0;
 }
-
-static int ipv4_nlattr_tuple_size(void)
-{
-       return nla_policy_len(ipv4_nla_policy, CTA_IP_MAX + 1);
-}
 #endif
 
 static struct nf_sockopt_ops so_getorigdst = {
@@ -365,9 +360,10 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
        .get_l4proto     = ipv4_get_l4proto,
 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
        .tuple_to_nlattr = ipv4_tuple_to_nlattr,
-       .nlattr_tuple_size = ipv4_nlattr_tuple_size,
        .nlattr_to_tuple = ipv4_nlattr_to_tuple,
        .nla_policy      = ipv4_nla_policy,
+       .nla_size        = NLA_ALIGN(NLA_HDRLEN + sizeof(u32)) + /* CTA_IP_V4_SRC */
+                          NLA_ALIGN(NLA_HDRLEN + sizeof(u32)),  /* CTA_IP_V4_DST */
 #endif
        .net_ns_get      = ipv4_hooks_register,
        .net_ns_put      = ipv4_hooks_unregister,
@@ -421,6 +417,11 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
 
        need_conntrack();
 
+#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
+       if (WARN_ON(nla_policy_len(ipv4_nla_policy, CTA_IP_MAX + 1) !=
+           nf_conntrack_l3proto_ipv4.nla_size))
+               return -EINVAL;
+#endif
        ret = nf_register_sockopt(&so_getorigdst);
        if (ret < 0) {
                pr_err("Unable to register netfilter socket option\n");
index ddef5ee9e0a863f407410645020d7a0655175d7c..6b4d59fd021474c0332ec7164a76583b7078beab 100644 (file)
@@ -308,11 +308,6 @@ static int ipv6_nlattr_to_tuple(struct nlattr *tb[],
 
        return 0;
 }
-
-static int ipv6_nlattr_tuple_size(void)
-{
-       return nla_policy_len(ipv6_nla_policy, CTA_IP_MAX + 1);
-}
 #endif
 
 static int ipv6_hooks_register(struct net *net)
@@ -360,9 +355,10 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
        .get_l4proto            = ipv6_get_l4proto,
 #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
        .tuple_to_nlattr        = ipv6_tuple_to_nlattr,
-       .nlattr_tuple_size      = ipv6_nlattr_tuple_size,
        .nlattr_to_tuple        = ipv6_nlattr_to_tuple,
        .nla_policy             = ipv6_nla_policy,
+       .nla_size               = NLA_ALIGN(NLA_HDRLEN + sizeof(u32[4])) +
+                                 NLA_ALIGN(NLA_HDRLEN + sizeof(u32[4])),
 #endif
        .net_ns_get             = ipv6_hooks_register,
        .net_ns_put             = ipv6_hooks_unregister,
@@ -421,6 +417,12 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
 
        need_conntrack();
 
+#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
+       if (WARN_ON(nla_policy_len(ipv6_nla_policy, CTA_IP_MAX + 1) !=
+           nf_conntrack_l3proto_ipv6.nla_size))
+               return -EINVAL;
+#endif
+
        ret = nf_register_sockopt(&so_getorigdst6);
        if (ret < 0) {
                pr_err("Unable to register netfilter socket option\n");
index f4ca48817f66922916930687472d4329941ff412..b59a453a0fd829d6be085923afdd7dc2ee1e509a 100644 (file)
@@ -540,7 +540,8 @@ static inline size_t ctnetlink_proto_size(const struct nf_conn *ct)
        size_t len = 0;
 
        l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
-       len += l3proto->nla_size;
+       len = l3proto->nla_size;
+       len *= 3u; /* ORIG, REPLY, MASTER */
 
        l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
        len += l4proto->nla_size;
index 27810cf816a6b943b4bd6acd30bea099a164580c..85104a27cc8987cc952e8880952a53e8a9d0008f 100644 (file)
@@ -214,10 +214,10 @@ int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto)
 
        if (proto->l3proto >= NFPROTO_NUMPROTO)
                return -EBUSY;
-
-       if (proto->tuple_to_nlattr && !proto->nlattr_tuple_size)
+#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
+       if (proto->tuple_to_nlattr && proto->nla_size == 0)
                return -EINVAL;
-
+#endif
        mutex_lock(&nf_ct_proto_mutex);
        old = rcu_dereference_protected(nf_ct_l3protos[proto->l3proto],
                                        lockdep_is_held(&nf_ct_proto_mutex));
@@ -226,9 +226,6 @@ int nf_ct_l3proto_register(struct nf_conntrack_l3proto *proto)
                goto out_unlock;
        }
 
-       if (proto->nlattr_tuple_size)
-               proto->nla_size = 3 * proto->nlattr_tuple_size();
-
        rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto);
 
 out_unlock: