Skip to content

Commit 64ff70b

Browse files
Paul Blakeydavem330
authored andcommitted
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 <[email protected]> Acked-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c34b961 commit 64ff70b

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

net/sched/act_ct.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,67 @@ static void tcf_ct_flow_table_put(struct tcf_ct_params *params)
125125
spin_unlock_bh(&zones_lock);
126126
}
127127

128+
static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft,
129+
struct nf_conn *ct,
130+
bool tcp)
131+
{
132+
struct flow_offload *entry;
133+
int err;
134+
135+
if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status))
136+
return;
137+
138+
entry = flow_offload_alloc(ct);
139+
if (!entry) {
140+
WARN_ON_ONCE(1);
141+
goto err_alloc;
142+
}
143+
144+
if (tcp) {
145+
ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
146+
ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
147+
}
148+
149+
err = flow_offload_add(&ct_ft->nf_ft, entry);
150+
if (err)
151+
goto err_add;
152+
153+
return;
154+
155+
err_add:
156+
flow_offload_free(entry);
157+
err_alloc:
158+
clear_bit(IPS_OFFLOAD_BIT, &ct->status);
159+
}
160+
161+
static void tcf_ct_flow_table_process_conn(struct tcf_ct_flow_table *ct_ft,
162+
struct nf_conn *ct,
163+
enum ip_conntrack_info ctinfo)
164+
{
165+
bool tcp = false;
166+
167+
if (ctinfo != IP_CT_ESTABLISHED && ctinfo != IP_CT_ESTABLISHED_REPLY)
168+
return;
169+
170+
switch (nf_ct_protonum(ct)) {
171+
case IPPROTO_TCP:
172+
tcp = true;
173+
if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED)
174+
return;
175+
break;
176+
case IPPROTO_UDP:
177+
break;
178+
default:
179+
return;
180+
}
181+
182+
if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) ||
183+
ct->status & IPS_SEQ_ADJUST)
184+
return;
185+
186+
tcf_ct_flow_table_add(ct_ft, ct, tcp);
187+
}
188+
128189
static int tcf_ct_flow_tables_init(void)
129190
{
130191
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,
578639
nf_conntrack_confirm(skb);
579640
}
580641

642+
tcf_ct_flow_table_process_conn(p->ct_ft, ct, ctinfo);
643+
581644
out_push:
582645
skb_push_rcsum(skb, nh_ofs);
583646

0 commit comments

Comments
 (0)