Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: conntrack: don't cache nlattr_tuple_size result in nla_size

We currently call ->nlattr_tuple_size() once at register time and
cache result in l4proto->nla_size.

nla_size is the only member that is written to, avoiding this would
allow to make l4proto trackers const.

We can use ->nlattr_tuple_size() at run time, and cache result in
the individual trackers instead.

This is an intermediate step, next patch removes nlattr_size()
callback and computes size at compile time, then removes nla_size.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
5caaed15 7f4dae2d

+37 -15
+2 -2
include/net/netfilter/nf_conntrack_l4proto.h
··· 74 74 int (*tuple_to_nlattr)(struct sk_buff *skb, 75 75 const struct nf_conntrack_tuple *t); 76 76 /* Calculate tuple nlattr size */ 77 - int (*nlattr_tuple_size)(void); 77 + unsigned int (*nlattr_tuple_size)(void); 78 78 int (*nlattr_to_tuple)(struct nlattr *tb[], 79 79 struct nf_conntrack_tuple *t); 80 80 const struct nla_policy *nla_policy; ··· 144 144 const struct nf_conntrack_tuple *tuple); 145 145 int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[], 146 146 struct nf_conntrack_tuple *t); 147 - int nf_ct_port_nlattr_tuple_size(void); 147 + unsigned int nf_ct_port_nlattr_tuple_size(void); 148 148 extern const struct nla_policy nf_ct_port_nla_policy[]; 149 149 150 150 #ifdef CONFIG_SYSCTL
+7 -2
net/ipv4/netfilter/nf_conntrack_proto_icmp.c
··· 258 258 return 0; 259 259 } 260 260 261 - static int icmp_nlattr_tuple_size(void) 261 + static unsigned int icmp_nlattr_tuple_size(void) 262 262 { 263 - return nla_policy_len(icmp_nla_policy, CTA_PROTO_MAX + 1); 263 + static unsigned int size __read_mostly; 264 + 265 + if (!size) 266 + size = nla_policy_len(icmp_nla_policy, CTA_PROTO_MAX + 1); 267 + 268 + return size; 264 269 } 265 270 #endif 266 271
+7 -2
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
··· 259 259 return 0; 260 260 } 261 261 262 - static int icmpv6_nlattr_tuple_size(void) 262 + static unsigned int icmpv6_nlattr_tuple_size(void) 263 263 { 264 - return nla_policy_len(icmpv6_nla_policy, CTA_PROTO_MAX + 1); 264 + static unsigned int size __read_mostly; 265 + 266 + if (!size) 267 + size = nla_policy_len(icmpv6_nla_policy, CTA_PROTO_MAX + 1); 268 + 269 + return size; 265 270 } 266 271 #endif 267 272
+7 -2
net/netfilter/nf_conntrack_core.c
··· 1563 1563 } 1564 1564 EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_to_tuple); 1565 1565 1566 - int nf_ct_port_nlattr_tuple_size(void) 1566 + unsigned int nf_ct_port_nlattr_tuple_size(void) 1567 1567 { 1568 - return nla_policy_len(nf_ct_port_nla_policy, CTA_PROTO_MAX + 1); 1568 + static unsigned int size __read_mostly; 1569 + 1570 + if (!size) 1571 + size = nla_policy_len(nf_ct_port_nla_policy, CTA_PROTO_MAX + 1); 1572 + 1573 + return size; 1569 1574 } 1570 1575 EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_tuple_size); 1571 1576 #endif
+7 -3
net/netfilter/nf_conntrack_netlink.c
··· 533 533 return -1; 534 534 } 535 535 536 - static inline size_t ctnetlink_proto_size(const struct nf_conn *ct) 536 + static size_t ctnetlink_proto_size(const struct nf_conn *ct) 537 537 { 538 538 const struct nf_conntrack_l3proto *l3proto; 539 539 const struct nf_conntrack_l4proto *l4proto; 540 - size_t len; 540 + size_t len, len4 = 0; 541 541 542 542 l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct)); 543 543 len = l3proto->nla_size; ··· 545 545 546 546 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); 547 547 len += l4proto->nla_size; 548 + if (l4proto->nlattr_tuple_size) { 549 + len4 = l4proto->nlattr_tuple_size(); 550 + len4 *= 3u; /* ORIG, REPLY, MASTER */ 551 + } 548 552 549 - return len; 553 + return len + len4; 550 554 } 551 555 552 556 static inline size_t ctnetlink_acct_size(const struct nf_conn *ct)
-2
net/netfilter/nf_conntrack_proto.c
··· 398 398 l4proto->nla_size = 0; 399 399 if (l4proto->nlattr_size) 400 400 l4proto->nla_size += l4proto->nlattr_size(); 401 - if (l4proto->nlattr_tuple_size) 402 - l4proto->nla_size += 3 * l4proto->nlattr_tuple_size(); 403 401 404 402 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], 405 403 l4proto);
+7 -2
net/netfilter/nf_conntrack_proto_tcp.c
··· 1277 1277 + nla_policy_len(tcp_nla_policy, CTA_PROTOINFO_TCP_MAX + 1); 1278 1278 } 1279 1279 1280 - static int tcp_nlattr_tuple_size(void) 1280 + static unsigned int tcp_nlattr_tuple_size(void) 1281 1281 { 1282 - return nla_policy_len(nf_ct_port_nla_policy, CTA_PROTO_MAX + 1); 1282 + static unsigned int size __read_mostly; 1283 + 1284 + if (!size) 1285 + size = nla_policy_len(nf_ct_port_nla_policy, CTA_PROTO_MAX + 1); 1286 + 1287 + return size; 1283 1288 } 1284 1289 #endif 1285 1290