forked from luck/tmp_suning_uos_patched
netfilter: conntrack: compute l3proto nla size at compile time
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>
This commit is contained in:
parent
eee6ebbac1
commit
0d03510038
|
@ -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,24 +52,18 @@ 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);
|
||||
int (*nlattr_to_tuple)(struct nlattr *tb[],
|
||||
struct nf_conntrack_tuple *t);
|
||||
const struct nla_policy *nla_policy;
|
||||
#endif
|
||||
|
||||
/* 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;
|
||||
|
||||
size_t nla_size;
|
||||
|
||||
/* Module (if any) which this is connected to. */
|
||||
struct module *me;
|
||||
};
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue
Block a user