Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d0dba725 authored by Holger Eitzenberger's avatar Holger Eitzenberger Committed by Patrick McHardy
Browse files

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: default avatarHolger Eitzenberger <holger@eitzenberger.org>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent b8dfe498
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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;
+6 −0
Original line number Diff line number Diff line
@@ -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;
+16 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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:
@@ -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. */
@@ -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);