Commit 64ff70b8 authored by Paul Blakey's avatar Paul Blakey Committed by David S. Miller

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: default avatarPaul Blakey <paulb@mellanox.com>
Acked-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c34b961a
...@@ -125,6 +125,67 @@ static void tcf_ct_flow_table_put(struct tcf_ct_params *params) ...@@ -125,6 +125,67 @@ static void tcf_ct_flow_table_put(struct tcf_ct_params *params)
spin_unlock_bh(&zones_lock); 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) static int tcf_ct_flow_tables_init(void)
{ {
return rhashtable_init(&zones_ht, &zones_params); 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, ...@@ -578,6 +639,8 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
nf_conntrack_confirm(skb); nf_conntrack_confirm(skb);
} }
tcf_ct_flow_table_process_conn(p->ct_ft, ct, ctinfo);
out_push: out_push:
skb_push_rcsum(skb, nh_ofs); skb_push_rcsum(skb, nh_ofs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment