aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Eitzenberger <holger@eitzenberger.org>2009-03-25 13:24:48 -0400
committerPatrick McHardy <kaber@trash.net>2009-03-25 13:24:48 -0400
commitd0dba7255b541f1651a88e75ebdb20dd45509c2f (patch)
treedb731388062d6b81e73bc9328fdd29e6eb81c509
parentb8dfe498775de912116f275680ddb57c8799d9ef (diff)
netfilter: ctnetlink: add callbacks to the per-proto nlattrs
There is added a single callback for the l3 proto helper. The two callbacks for the l4 protos are necessary because of the general structure of a ctnetlink event, which is in short: CTA_TUPLE_ORIG <l3/l4-proto-attributes> CTA_TUPLE_REPLY <l3/l4-proto-attributes> CTA_ID ... CTA_PROTOINFO <l4-proto-attributes> CTA_TUPLE_MASTER <l3/l4-proto-attributes> Therefore the formular is size := sizeof(generic-nlas) + 3 * sizeof(tuple_nlas) + sizeof(protoinfo_nlas) Some of the NLAs are optional, e. g. CTA_TUPLE_MASTER, which is only set if it's an expected connection. But the number of optional NLAs is small enough to prevent netlink_trim() from reallocating if calculated properly. Signed-off-by: Holger Eitzenberger <holger@eitzenberger.org> Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h7
-rw-r--r--include/net/netfilter/nf_conntrack_l4proto.h6
-rw-r--r--net/netfilter/nf_conntrack_proto.c16
3 files changed, 29 insertions, 0 deletions
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 0378676c3dd8..9f99d36d5de9 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -53,10 +53,17 @@ struct nf_conntrack_l3proto
53 int (*tuple_to_nlattr)(struct sk_buff *skb, 53 int (*tuple_to_nlattr)(struct sk_buff *skb,
54 const struct nf_conntrack_tuple *t); 54 const struct nf_conntrack_tuple *t);
55 55
56 /*
57 * Calculate size of tuple nlattr
58 */
59 int (*nlattr_tuple_size)(void);
60
56 int (*nlattr_to_tuple)(struct nlattr *tb[], 61 int (*nlattr_to_tuple)(struct nlattr *tb[],
57 struct nf_conntrack_tuple *t); 62 struct nf_conntrack_tuple *t);
58 const struct nla_policy *nla_policy; 63 const struct nla_policy *nla_policy;
59 64
65 size_t nla_size;
66
60#ifdef CONFIG_SYSCTL 67#ifdef CONFIG_SYSCTL
61 struct ctl_table_header *ctl_table_header; 68 struct ctl_table_header *ctl_table_header;
62 struct ctl_path *ctl_table_path; 69 struct ctl_path *ctl_table_path;
diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index b01070bf2f84..a120990b3b2b 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -64,16 +64,22 @@ struct nf_conntrack_l4proto
64 /* convert protoinfo to nfnetink attributes */ 64 /* convert protoinfo to nfnetink attributes */
65 int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla, 65 int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla,
66 const struct nf_conn *ct); 66 const struct nf_conn *ct);
67 /* Calculate protoinfo nlattr size */
68 int (*nlattr_size)(void);
67 69
68 /* convert nfnetlink attributes to protoinfo */ 70 /* convert nfnetlink attributes to protoinfo */
69 int (*from_nlattr)(struct nlattr *tb[], struct nf_conn *ct); 71 int (*from_nlattr)(struct nlattr *tb[], struct nf_conn *ct);
70 72
71 int (*tuple_to_nlattr)(struct sk_buff *skb, 73 int (*tuple_to_nlattr)(struct sk_buff *skb,
72 const struct nf_conntrack_tuple *t); 74 const struct nf_conntrack_tuple *t);
75 /* Calculate tuple nlattr size */
76 int (*nlattr_tuple_size)(void);
73 int (*nlattr_to_tuple)(struct nlattr *tb[], 77 int (*nlattr_to_tuple)(struct nlattr *tb[],
74 struct nf_conntrack_tuple *t); 78 struct nf_conntrack_tuple *t);
75 const struct nla_policy *nla_policy; 79 const struct nla_policy *nla_policy;
76 80
81 size_t nla_size;
82
77#ifdef CONFIG_SYSCTL 83#ifdef CONFIG_SYSCTL
78 struct ctl_table_header **ctl_table_header; 84 struct ctl_table_header **ctl_table_header;
79 struct ctl_table *ctl_table; 85 struct ctl_table *ctl_table;
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 9a62b4efa0e1..1a4568bf7ea5 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -167,6 +167,9 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
167 if (proto->l3proto >= AF_MAX) 167 if (proto->l3proto >= AF_MAX)
168 return -EBUSY; 168 return -EBUSY;
169 169
170 if (proto->tuple_to_nlattr && !proto->nlattr_tuple_size)
171 return -EINVAL;
172
170 mutex_lock(&nf_ct_proto_mutex); 173 mutex_lock(&nf_ct_proto_mutex);
171 if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) { 174 if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) {
172 ret = -EBUSY; 175 ret = -EBUSY;
@@ -177,6 +180,9 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
177 if (ret < 0) 180 if (ret < 0)
178 goto out_unlock; 181 goto out_unlock;
179 182
183 if (proto->nlattr_tuple_size)
184 proto->nla_size = 3 * proto->nlattr_tuple_size();
185
180 rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto); 186 rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto);
181 187
182out_unlock: 188out_unlock:
@@ -263,6 +269,10 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
263 if (l4proto->l3proto >= PF_MAX) 269 if (l4proto->l3proto >= PF_MAX)
264 return -EBUSY; 270 return -EBUSY;
265 271
272 if ((l4proto->to_nlattr && !l4proto->nlattr_size)
273 || (l4proto->tuple_to_nlattr && !l4proto->nlattr_tuple_size))
274 return -EINVAL;
275
266 mutex_lock(&nf_ct_proto_mutex); 276 mutex_lock(&nf_ct_proto_mutex);
267 if (!nf_ct_protos[l4proto->l3proto]) { 277 if (!nf_ct_protos[l4proto->l3proto]) {
268 /* l3proto may be loaded latter. */ 278 /* l3proto may be loaded latter. */
@@ -290,6 +300,12 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
290 if (ret < 0) 300 if (ret < 0)
291 goto out_unlock; 301 goto out_unlock;
292 302
303 l4proto->nla_size = 0;
304 if (l4proto->nlattr_size)
305 l4proto->nla_size += l4proto->nlattr_size();
306 if (l4proto->nlattr_tuple_size)
307 l4proto->nla_size += 3 * l4proto->nlattr_tuple_size();
308
293 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], 309 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
294 l4proto); 310 l4proto);
295 311