netfilter: flowtable: GC pushes back packets to classic path
[ Upstream commit 735795f68b37e9bb49f642407a0d49b1631ea1c7 ] Since 41f2c7c342d3 ("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: 41f2c7c342d3 ("net/sched: act_ct: Fix promotion of offloaded unreplied tuple") Reported-by: Vladimir Smelhaus <vl.sm@email.cz> Reviewed-by: Paul Blakey <paulb@nvidia.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Stable-dep-of: 125f1c7f26ff ("net/sched: act_ct: Take per-cb reference to tcf_ct_flow_table") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
df01de08b4
commit
2bb4ecb334
@ -53,6 +53,7 @@ struct nf_flowtable_type {
|
|||||||
struct list_head list;
|
struct list_head list;
|
||||||
int family;
|
int family;
|
||||||
int (*init)(struct nf_flowtable *ft);
|
int (*init)(struct nf_flowtable *ft);
|
||||||
|
bool (*gc)(const struct flow_offload *flow);
|
||||||
int (*setup)(struct nf_flowtable *ft,
|
int (*setup)(struct nf_flowtable *ft,
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
enum flow_block_command cmd);
|
enum flow_block_command cmd);
|
||||||
|
@ -331,12 +331,6 @@ void flow_offload_refresh(struct nf_flowtable *flow_table,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(flow_offload_refresh);
|
EXPORT_SYMBOL_GPL(flow_offload_refresh);
|
||||||
|
|
||||||
static bool nf_flow_is_outdated(const struct flow_offload *flow)
|
|
||||||
{
|
|
||||||
return test_bit(IPS_SEEN_REPLY_BIT, &flow->ct->status) &&
|
|
||||||
!test_bit(NF_FLOW_HW_ESTABLISHED, &flow->flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool nf_flow_has_expired(const struct flow_offload *flow)
|
static inline bool nf_flow_has_expired(const struct flow_offload *flow)
|
||||||
{
|
{
|
||||||
return nf_flow_timeout_delta(flow->timeout) <= 0;
|
return nf_flow_timeout_delta(flow->timeout) <= 0;
|
||||||
@ -422,12 +416,18 @@ nf_flow_table_iterate(struct nf_flowtable *flow_table,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool nf_flow_custom_gc(struct nf_flowtable *flow_table,
|
||||||
|
const struct flow_offload *flow)
|
||||||
|
{
|
||||||
|
return flow_table->type->gc && flow_table->type->gc(flow);
|
||||||
|
}
|
||||||
|
|
||||||
static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table,
|
static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table,
|
||||||
struct flow_offload *flow, void *data)
|
struct flow_offload *flow, void *data)
|
||||||
{
|
{
|
||||||
if (nf_flow_has_expired(flow) ||
|
if (nf_flow_has_expired(flow) ||
|
||||||
nf_ct_is_dying(flow->ct) ||
|
nf_ct_is_dying(flow->ct) ||
|
||||||
nf_flow_is_outdated(flow))
|
nf_flow_custom_gc(flow_table, flow))
|
||||||
flow_offload_teardown(flow);
|
flow_offload_teardown(flow);
|
||||||
|
|
||||||
if (test_bit(NF_FLOW_TEARDOWN, &flow->flags)) {
|
if (test_bit(NF_FLOW_TEARDOWN, &flow->flags)) {
|
||||||
|
@ -274,7 +274,14 @@ static int tcf_ct_flow_table_fill_actions(struct net *net,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool tcf_ct_flow_is_outdated(const struct flow_offload *flow)
|
||||||
|
{
|
||||||
|
return test_bit(IPS_SEEN_REPLY_BIT, &flow->ct->status) &&
|
||||||
|
!test_bit(NF_FLOW_HW_ESTABLISHED, &flow->flags);
|
||||||
|
}
|
||||||
|
|
||||||
static struct nf_flowtable_type flowtable_ct = {
|
static struct nf_flowtable_type flowtable_ct = {
|
||||||
|
.gc = tcf_ct_flow_is_outdated,
|
||||||
.action = tcf_ct_flow_table_fill_actions,
|
.action = tcf_ct_flow_table_fill_actions,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user