mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	net/sched: act_ct: Offload established connections to flow table
Add a ft entry when connections enter an established state and delete the connections when they leave the established state. The flow table assumes ownership of the connection. In the following patch act_ct will lookup the ct state from the FT. In future patches, drivers will register for callbacks for ft add/del events and will be able to use the information to offload the connections. Note that connection aging is managed by the FT. Signed-off-by: Paul Blakey <paulb@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									c34b961a24
								
							
						
					
					
						commit
						64ff70b80f
					
				
					 1 changed files with 63 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -125,6 +125,67 @@ static void tcf_ct_flow_table_put(struct tcf_ct_params *params)
 | 
			
		|||
	spin_unlock_bh(&zones_lock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft,
 | 
			
		||||
				  struct nf_conn *ct,
 | 
			
		||||
				  bool tcp)
 | 
			
		||||
{
 | 
			
		||||
	struct flow_offload *entry;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	entry = flow_offload_alloc(ct);
 | 
			
		||||
	if (!entry) {
 | 
			
		||||
		WARN_ON_ONCE(1);
 | 
			
		||||
		goto err_alloc;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (tcp) {
 | 
			
		||||
		ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
 | 
			
		||||
		ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = flow_offload_add(&ct_ft->nf_ft, entry);
 | 
			
		||||
	if (err)
 | 
			
		||||
		goto err_add;
 | 
			
		||||
 | 
			
		||||
	return;
 | 
			
		||||
 | 
			
		||||
err_add:
 | 
			
		||||
	flow_offload_free(entry);
 | 
			
		||||
err_alloc:
 | 
			
		||||
	clear_bit(IPS_OFFLOAD_BIT, &ct->status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void tcf_ct_flow_table_process_conn(struct tcf_ct_flow_table *ct_ft,
 | 
			
		||||
					   struct nf_conn *ct,
 | 
			
		||||
					   enum ip_conntrack_info ctinfo)
 | 
			
		||||
{
 | 
			
		||||
	bool tcp = false;
 | 
			
		||||
 | 
			
		||||
	if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	switch (nf_ct_protonum(ct)) {
 | 
			
		||||
	case IPPROTO_TCP:
 | 
			
		||||
		tcp = true;
 | 
			
		||||
		if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED)
 | 
			
		||||
			return;
 | 
			
		||||
		break;
 | 
			
		||||
	case IPPROTO_UDP:
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) ||
 | 
			
		||||
	    ct->status & IPS_SEQ_ADJUST)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	tcf_ct_flow_table_add(ct_ft, ct, tcp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int tcf_ct_flow_tables_init(void)
 | 
			
		||||
{
 | 
			
		||||
	return rhashtable_init(&zones_ht, &zones_params);
 | 
			
		||||
| 
						 | 
				
			
			@ -578,6 +639,8 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
 | 
			
		|||
		nf_conntrack_confirm(skb);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tcf_ct_flow_table_process_conn(p->ct_ft, ct, ctinfo);
 | 
			
		||||
 | 
			
		||||
out_push:
 | 
			
		||||
	skb_push_rcsum(skb, nh_ofs);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue