netfilter: ctnetlink: refactor ctnetlink_create_expect
This patch refactors ctnetlink_create_expect by spliting it in two chunks. As a result, we have a new function ctnetlink_alloc_expect to allocate and to setup the expectation from ctnetlink. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
		
					parent
					
						
							
								c655bc6896
							
						
					
				
			
			
				commit
				
					
						0ef71ee1a5
					
				
			
		
					 1 changed files with 88 additions and 70 deletions
				
			
		|  | @ -2735,76 +2735,26 @@ ctnetlink_parse_expect_nat(const struct nlattr *attr, | |||
| #endif | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| ctnetlink_create_expect(struct net *net, u16 zone, | ||||
| 			const struct nlattr * const cda[], | ||||
| 			u_int8_t u3, | ||||
| 			u32 portid, int report) | ||||
| static struct nf_conntrack_expect * | ||||
| ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct, | ||||
| 		       struct nf_conntrack_helper *helper, | ||||
| 		       struct nf_conntrack_tuple *tuple, | ||||
| 		       struct nf_conntrack_tuple *mask) | ||||
| { | ||||
| 	struct nf_conntrack_tuple tuple, mask, master_tuple; | ||||
| 	struct nf_conntrack_tuple_hash *h = NULL; | ||||
| 	struct nf_conntrack_expect *exp; | ||||
| 	struct nf_conn *ct; | ||||
| 	struct nf_conn_help *help; | ||||
| 	struct nf_conntrack_helper *helper = NULL; | ||||
| 	u_int32_t class = 0; | ||||
| 	int err = 0; | ||||
| 
 | ||||
| 	/* caller guarantees that those three CTA_EXPECT_* exist */ | ||||
| 	err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); | ||||
| 	if (err < 0) | ||||
| 		return err; | ||||
| 	err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK, u3); | ||||
| 	if (err < 0) | ||||
| 		return err; | ||||
| 	err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER, u3); | ||||
| 	if (err < 0) | ||||
| 		return err; | ||||
| 
 | ||||
| 	/* Look for master conntrack of this expectation */ | ||||
| 	h = nf_conntrack_find_get(net, zone, &master_tuple); | ||||
| 	if (!h) | ||||
| 		return -ENOENT; | ||||
| 	ct = nf_ct_tuplehash_to_ctrack(h); | ||||
| 
 | ||||
| 	/* Look for helper of this expectation */ | ||||
| 	if (cda[CTA_EXPECT_HELP_NAME]) { | ||||
| 		const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]); | ||||
| 
 | ||||
| 		helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct), | ||||
| 						    nf_ct_protonum(ct)); | ||||
| 		if (helper == NULL) { | ||||
| #ifdef CONFIG_MODULES | ||||
| 			if (request_module("nfct-helper-%s", helpname) < 0) { | ||||
| 				err = -EOPNOTSUPP; | ||||
| 				goto out; | ||||
| 			} | ||||
| 
 | ||||
| 			helper = __nf_conntrack_helper_find(helpname, | ||||
| 							    nf_ct_l3num(ct), | ||||
| 							    nf_ct_protonum(ct)); | ||||
| 			if (helper) { | ||||
| 				err = -EAGAIN; | ||||
| 				goto out; | ||||
| 			} | ||||
| #endif | ||||
| 			err = -EOPNOTSUPP; | ||||
| 			goto out; | ||||
| 		} | ||||
| 	} | ||||
| 	struct nf_conntrack_expect *exp; | ||||
| 	struct nf_conn_help *help; | ||||
| 	int err; | ||||
| 
 | ||||
| 	if (cda[CTA_EXPECT_CLASS] && helper) { | ||||
| 		class = ntohl(nla_get_be32(cda[CTA_EXPECT_CLASS])); | ||||
| 		if (class > helper->expect_class_max) { | ||||
| 			err = -EINVAL; | ||||
| 			goto out; | ||||
| 		} | ||||
| 		if (class > helper->expect_class_max) | ||||
| 			return ERR_PTR(-EINVAL); | ||||
| 	} | ||||
| 	exp = nf_ct_expect_alloc(ct); | ||||
| 	if (!exp) { | ||||
| 		err = -ENOMEM; | ||||
| 		goto out; | ||||
| 	} | ||||
| 	if (!exp) | ||||
| 		return ERR_PTR(-ENOMEM); | ||||
| 
 | ||||
| 	help = nfct_help(ct); | ||||
| 	if (!help) { | ||||
| 		if (!cda[CTA_EXPECT_TIMEOUT]) { | ||||
|  | @ -2842,21 +2792,89 @@ ctnetlink_create_expect(struct net *net, u16 zone, | |||
| 	exp->class = class; | ||||
| 	exp->master = ct; | ||||
| 	exp->helper = helper; | ||||
| 	memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple)); | ||||
| 	memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3)); | ||||
| 	exp->mask.src.u.all = mask.src.u.all; | ||||
| 	exp->tuple = *tuple; | ||||
| 	exp->mask.src.u3 = mask->src.u3; | ||||
| 	exp->mask.src.u.all = mask->src.u.all; | ||||
| 
 | ||||
| 	if (cda[CTA_EXPECT_NAT]) { | ||||
| 		err = ctnetlink_parse_expect_nat(cda[CTA_EXPECT_NAT], | ||||
| 						 exp, u3); | ||||
| 						 exp, nf_ct_l3num(ct)); | ||||
| 		if (err < 0) | ||||
| 			goto err_out; | ||||
| 	} | ||||
| 	err = nf_ct_expect_related_report(exp, portid, report); | ||||
| 	return exp; | ||||
| err_out: | ||||
| 	nf_ct_expect_put(exp); | ||||
| out: | ||||
| 	nf_ct_put(nf_ct_tuplehash_to_ctrack(h)); | ||||
| 	return ERR_PTR(err); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| ctnetlink_create_expect(struct net *net, u16 zone, | ||||
| 			const struct nlattr * const cda[], | ||||
| 			u_int8_t u3, u32 portid, int report) | ||||
| { | ||||
| 	struct nf_conntrack_tuple tuple, mask, master_tuple; | ||||
| 	struct nf_conntrack_tuple_hash *h = NULL; | ||||
| 	struct nf_conntrack_helper *helper = NULL; | ||||
| 	struct nf_conntrack_expect *exp; | ||||
| 	struct nf_conn *ct; | ||||
| 	int err; | ||||
| 
 | ||||
| 	/* caller guarantees that those three CTA_EXPECT_* exist */ | ||||
| 	err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3); | ||||
| 	if (err < 0) | ||||
| 		return err; | ||||
| 	err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK, u3); | ||||
| 	if (err < 0) | ||||
| 		return err; | ||||
| 	err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER, u3); | ||||
| 	if (err < 0) | ||||
| 		return err; | ||||
| 
 | ||||
| 	/* Look for master conntrack of this expectation */ | ||||
| 	h = nf_conntrack_find_get(net, zone, &master_tuple); | ||||
| 	if (!h) | ||||
| 		return -ENOENT; | ||||
| 	ct = nf_ct_tuplehash_to_ctrack(h); | ||||
| 
 | ||||
| 	if (cda[CTA_EXPECT_HELP_NAME]) { | ||||
| 		const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]); | ||||
| 
 | ||||
| 		helper = __nf_conntrack_helper_find(helpname, u3, | ||||
| 						    nf_ct_protonum(ct)); | ||||
| 		if (helper == NULL) { | ||||
| #ifdef CONFIG_MODULES | ||||
| 			if (request_module("nfct-helper-%s", helpname) < 0) { | ||||
| 				err = -EOPNOTSUPP; | ||||
| 				goto err_ct; | ||||
| 			} | ||||
| 			helper = __nf_conntrack_helper_find(helpname, u3, | ||||
| 							    nf_ct_protonum(ct)); | ||||
| 			if (helper) { | ||||
| 				err = -EAGAIN; | ||||
| 				goto err_ct; | ||||
| 			} | ||||
| #endif | ||||
| 			err = -EOPNOTSUPP; | ||||
| 			goto err_ct; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	exp = ctnetlink_alloc_expect(cda, ct, helper, &tuple, &mask); | ||||
| 	if (IS_ERR(exp)) { | ||||
| 		err = PTR_ERR(exp); | ||||
| 		goto err_ct; | ||||
| 	} | ||||
| 
 | ||||
| 	err = nf_ct_expect_related_report(exp, portid, report); | ||||
| 	if (err < 0) | ||||
| 		goto err_exp; | ||||
| 
 | ||||
| 	return 0; | ||||
| err_exp: | ||||
| 	nf_ct_expect_put(exp); | ||||
| err_ct: | ||||
| 	nf_ct_put(ct); | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Pablo Neira Ayuso
				Pablo Neira Ayuso