forked from mirrors/linux
		
	act_ct: prepare for stolen verdict coming from conntrack and nat engine
At this time, conntrack either returns NF_ACCEPT or NF_DROP. To improve debuging it would be nice to be able to replace NF_DROP verdict with NF_DROP_REASON() helper, This helper releases the skb instantly (so drop_monitor can pinpoint exact location) and returns NF_STOLEN. Prepare call sites to deal with this before introducing such changes in conntrack and nat core. Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									2f5e639571
								
							
						
					
					
						commit
						3abbd7ed8b
					
				
					 1 changed files with 25 additions and 6 deletions
				
			
		|  | @ -944,6 +944,8 @@ static int tcf_ct_act_nat(struct sk_buff *skb, | ||||||
| 		action |= BIT(NF_NAT_MANIP_DST); | 		action |= BIT(NF_NAT_MANIP_DST); | ||||||
| 
 | 
 | ||||||
| 	err = nf_ct_nat(skb, ct, ctinfo, &action, range, commit); | 	err = nf_ct_nat(skb, ct, ctinfo, &action, range, commit); | ||||||
|  | 	if (err != NF_ACCEPT) | ||||||
|  | 		return err & NF_VERDICT_MASK; | ||||||
| 
 | 
 | ||||||
| 	if (action & BIT(NF_NAT_MANIP_SRC)) | 	if (action & BIT(NF_NAT_MANIP_SRC)) | ||||||
| 		tc_skb_cb(skb)->post_ct_snat = 1; | 		tc_skb_cb(skb)->post_ct_snat = 1; | ||||||
|  | @ -1035,7 +1037,7 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, | ||||||
| 		state.pf = family; | 		state.pf = family; | ||||||
| 		err = nf_conntrack_in(skb, &state); | 		err = nf_conntrack_in(skb, &state); | ||||||
| 		if (err != NF_ACCEPT) | 		if (err != NF_ACCEPT) | ||||||
| 			goto out_push; | 			goto nf_error; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| do_nat: | do_nat: | ||||||
|  | @ -1047,7 +1049,7 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, | ||||||
| 
 | 
 | ||||||
| 	err = tcf_ct_act_nat(skb, ct, ctinfo, p->ct_action, &p->range, commit); | 	err = tcf_ct_act_nat(skb, ct, ctinfo, p->ct_action, &p->range, commit); | ||||||
| 	if (err != NF_ACCEPT) | 	if (err != NF_ACCEPT) | ||||||
| 		goto drop; | 		goto nf_error; | ||||||
| 
 | 
 | ||||||
| 	if (!nf_ct_is_confirmed(ct) && commit && p->helper && !nfct_help(ct)) { | 	if (!nf_ct_is_confirmed(ct) && commit && p->helper && !nfct_help(ct)) { | ||||||
| 		err = __nf_ct_try_assign_helper(ct, p->tmpl, GFP_ATOMIC); | 		err = __nf_ct_try_assign_helper(ct, p->tmpl, GFP_ATOMIC); | ||||||
|  | @ -1061,8 +1063,9 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (nf_ct_is_confirmed(ct) ? ((!cached && !skip_add) || add_helper) : commit) { | 	if (nf_ct_is_confirmed(ct) ? ((!cached && !skip_add) || add_helper) : commit) { | ||||||
| 		if (nf_ct_helper(skb, ct, ctinfo, family) != NF_ACCEPT) | 		err = nf_ct_helper(skb, ct, ctinfo, family); | ||||||
| 			goto drop; | 		if (err != NF_ACCEPT) | ||||||
|  | 			goto nf_error; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (commit) { | 	if (commit) { | ||||||
|  | @ -1075,8 +1078,9 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, | ||||||
| 		/* This will take care of sending queued events
 | 		/* This will take care of sending queued events
 | ||||||
| 		 * even if the connection is already confirmed. | 		 * even if the connection is already confirmed. | ||||||
| 		 */ | 		 */ | ||||||
| 		if (nf_conntrack_confirm(skb) != NF_ACCEPT) | 		err = nf_conntrack_confirm(skb); | ||||||
| 			goto drop; | 		if (err != NF_ACCEPT) | ||||||
|  | 			goto nf_error; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!skip_add) | 	if (!skip_add) | ||||||
|  | @ -1100,6 +1104,21 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, | ||||||
| drop: | drop: | ||||||
| 	tcf_action_inc_drop_qstats(&c->common); | 	tcf_action_inc_drop_qstats(&c->common); | ||||||
| 	return TC_ACT_SHOT; | 	return TC_ACT_SHOT; | ||||||
|  | 
 | ||||||
|  | nf_error: | ||||||
|  | 	/* some verdicts store extra data in upper bits, such
 | ||||||
|  | 	 * as errno or queue number. | ||||||
|  | 	 */ | ||||||
|  | 	switch (err & NF_VERDICT_MASK) { | ||||||
|  | 	case NF_DROP: | ||||||
|  | 		goto drop; | ||||||
|  | 	case NF_STOLEN: | ||||||
|  | 		tcf_action_inc_drop_qstats(&c->common); | ||||||
|  | 		return TC_ACT_CONSUMED; | ||||||
|  | 	default: | ||||||
|  | 		DEBUG_NET_WARN_ON_ONCE(1); | ||||||
|  | 		goto drop; | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct nla_policy ct_policy[TCA_CT_MAX + 1] = { | static const struct nla_policy ct_policy[TCA_CT_MAX + 1] = { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Florian Westphal
						Florian Westphal