On 2020-05-11 1:17 PM, Pablo Neira Ayuso wrote: > If the flow timer expires, the gc sets on the NF_FLOW_TEARDOWN flag. > Otherwise, the flowtable software path might race to refresh the > timeout, leaving the state machine in inconsistent state. > > Fixes: c29f74e0df7a ("netfilter: nf_flow_table: hardware offload support") > Reported-by: Paul Blakey <paulb@xxxxxxxxxxxx> > Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> > --- > net/netfilter/nf_flow_table_core.c | 8 +++++--- > 1 file changed, 5 insertions(+), 3 deletions(-) > > diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c > index 4344e572b7f9..42da6e337276 100644 > --- a/net/netfilter/nf_flow_table_core.c > +++ b/net/netfilter/nf_flow_table_core.c > @@ -284,7 +284,7 @@ static void flow_offload_del(struct nf_flowtable *flow_table, > > if (nf_flow_has_expired(flow)) > flow_offload_fixup_ct(flow->ct); > - else if (test_bit(NF_FLOW_TEARDOWN, &flow->flags)) > + else > flow_offload_fixup_ct_timeout(flow->ct); > > flow_offload_free(flow); > @@ -361,8 +361,10 @@ static void nf_flow_offload_gc_step(struct flow_offload *flow, void *data) > { > struct nf_flowtable *flow_table = data; > > - if (nf_flow_has_expired(flow) || nf_ct_is_dying(flow->ct) || > - test_bit(NF_FLOW_TEARDOWN, &flow->flags)) { > + if (nf_flow_has_expired(flow) || nf_ct_is_dying(flow->ct)) > + set_bit(NF_FLOW_TEARDOWN, &flow->flags); > + > + if (test_bit(NF_FLOW_TEARDOWN, &flow->flags)) { > if (test_bit(NF_FLOW_HW, &flow->flags)) { > if (!test_bit(NF_FLOW_HW_DYING, &flow->flags)) > nf_flow_offload_del(flow_table, flow); > thanks Reviewed-by: Roi Dayan <roid@xxxxxxxxxxxx>