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>
This commit is contained in:
		
					parent
					
						
							
								b8dfe49877
							
						
					
				
			
			
				commit
				
					
						d0dba7255b
					
				
			
		
					 3 changed files with 29 additions and 0 deletions
				
			
		|  | @ -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; | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Holger Eitzenberger
				Holger Eitzenberger