Skip to content

Commit 735795f

Browse files
committed
netfilter: flowtable: GC pushes back packets to classic path
Since 41f2c7c ("net/sched: act_ct: Fix promotion of offloaded unreplied tuple"), flowtable GC pushes back flows with IPS_SEEN_REPLY back to classic path in every run, ie. every second. This is because of a new check for NF_FLOW_HW_ESTABLISHED which is specific of sched/act_ct. In Netfilter's flowtable case, NF_FLOW_HW_ESTABLISHED never gets set on and IPS_SEEN_REPLY is unreliable since users decide when to offload the flow before, such bit might be set on at a later stage. Fix it by adding a custom .gc handler that sched/act_ct can use to deal with its NF_FLOW_HW_ESTABLISHED bit. Fixes: 41f2c7c ("net/sched: act_ct: Fix promotion of offloaded unreplied tuple") Reported-by: Vladimir Smelhaus <[email protected]> Reviewed-by: Paul Blakey <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent d2a0fc3 commit 735795f

File tree

3 files changed

+15
-7
lines changed

3 files changed

+15
-7
lines changed

include/net/netfilter/nf_flow_table.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ struct nf_flowtable_type {
5353
struct list_head list;
5454
int family;
5555
int (*init)(struct nf_flowtable *ft);
56+
bool (*gc)(const struct flow_offload *flow);
5657
int (*setup)(struct nf_flowtable *ft,
5758
struct net_device *dev,
5859
enum flow_block_command cmd);

net/netfilter/nf_flow_table_core.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -316,12 +316,6 @@ void flow_offload_refresh(struct nf_flowtable *flow_table,
316316
}
317317
EXPORT_SYMBOL_GPL(flow_offload_refresh);
318318

319-
static bool nf_flow_is_outdated(const struct flow_offload *flow)
320-
{
321-
return test_bit(IPS_SEEN_REPLY_BIT, &flow->ct->status) &&
322-
!test_bit(NF_FLOW_HW_ESTABLISHED, &flow->flags);
323-
}
324-
325319
static inline bool nf_flow_has_expired(const struct flow_offload *flow)
326320
{
327321
return nf_flow_timeout_delta(flow->timeout) <= 0;
@@ -407,12 +401,18 @@ nf_flow_table_iterate(struct nf_flowtable *flow_table,
407401
return err;
408402
}
409403

404+
static bool nf_flow_custom_gc(struct nf_flowtable *flow_table,
405+
const struct flow_offload *flow)
406+
{
407+
return flow_table->type->gc && flow_table->type->gc(flow);
408+
}
409+
410410
static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table,
411411
struct flow_offload *flow, void *data)
412412
{
413413
if (nf_flow_has_expired(flow) ||
414414
nf_ct_is_dying(flow->ct) ||
415-
nf_flow_is_outdated(flow))
415+
nf_flow_custom_gc(flow_table, flow))
416416
flow_offload_teardown(flow);
417417

418418
if (test_bit(NF_FLOW_TEARDOWN, &flow->flags)) {

net/sched/act_ct.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,14 @@ static int tcf_ct_flow_table_fill_actions(struct net *net,
278278
return err;
279279
}
280280

281+
static bool tcf_ct_flow_is_outdated(const struct flow_offload *flow)
282+
{
283+
return test_bit(IPS_SEEN_REPLY_BIT, &flow->ct->status) &&
284+
!test_bit(NF_FLOW_HW_ESTABLISHED, &flow->flags);
285+
}
286+
281287
static struct nf_flowtable_type flowtable_ct = {
288+
.gc = tcf_ct_flow_is_outdated,
282289
.action = tcf_ct_flow_table_fill_actions,
283290
.owner = THIS_MODULE,
284291
};

0 commit comments

Comments
 (0)