Skip to content

Commit

Permalink
netfilter: ctnetlink: add callbacks to the per-proto nlattrs
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Patrick McHardy <[email protected]>
  • Loading branch information
vaesoo authored and kaber committed Mar 25, 2009
1 parent b8dfe49 commit d0dba72
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 0 deletions.
7 changes: 7 additions & 0 deletions include/net/netfilter/nf_conntrack_l3proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,17 @@ struct nf_conntrack_l3proto
int (*tuple_to_nlattr)(struct sk_buff *skb,
const struct nf_conntrack_tuple *t);

/*
* 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;

#ifdef CONFIG_SYSCTL
struct ctl_table_header *ctl_table_header;
struct ctl_path *ctl_table_path;
Expand Down
6 changes: 6 additions & 0 deletions include/net/netfilter/nf_conntrack_l4proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,22 @@ struct nf_conntrack_l4proto
/* convert protoinfo to nfnetink attributes */
int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla,
const struct nf_conn *ct);
/* Calculate protoinfo nlattr size */
int (*nlattr_size)(void);

/* convert nfnetlink attributes to protoinfo */
int (*from_nlattr)(struct nlattr *tb[], struct nf_conn *ct);

int (*tuple_to_nlattr)(struct sk_buff *skb,
const struct nf_conntrack_tuple *t);
/* Calculate tuple nlattr size */
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;

#ifdef CONFIG_SYSCTL
struct ctl_table_header **ctl_table_header;
struct ctl_table *ctl_table;
Expand Down
16 changes: 16 additions & 0 deletions net/netfilter/nf_conntrack_proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
if (proto->l3proto >= AF_MAX)
return -EBUSY;

if (proto->tuple_to_nlattr && !proto->nlattr_tuple_size)
return -EINVAL;

mutex_lock(&nf_ct_proto_mutex);
if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) {
ret = -EBUSY;
Expand All @@ -177,6 +180,9 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
if (ret < 0)
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:
Expand Down Expand Up @@ -263,6 +269,10 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
if (l4proto->l3proto >= PF_MAX)
return -EBUSY;

if ((l4proto->to_nlattr && !l4proto->nlattr_size)
|| (l4proto->tuple_to_nlattr && !l4proto->nlattr_tuple_size))
return -EINVAL;

mutex_lock(&nf_ct_proto_mutex);
if (!nf_ct_protos[l4proto->l3proto]) {
/* l3proto may be loaded latter. */
Expand Down Expand Up @@ -290,6 +300,12 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
if (ret < 0)
goto out_unlock;

l4proto->nla_size = 0;
if (l4proto->nlattr_size)
l4proto->nla_size += l4proto->nlattr_size();
if (l4proto->nlattr_tuple_size)
l4proto->nla_size += 3 * l4proto->nlattr_tuple_size();

rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
l4proto);

Expand Down

0 comments on commit d0dba72

Please sign in to comment.