| From 535fd215b53c4e880184f85b3eb6355885fd4eda Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 11 May 2020 11:54:31 +0200 |
| Subject: netfilter: flowtable: set NF_FLOW_TEARDOWN flag on entry expiration |
| |
| From: Pablo Neira Ayuso <pablo@netfilter.org> |
| |
| [ Upstream commit 9ed81c8e0deb7bd2aa0d69371e4a0f9a7b31205d ] |
| |
| 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@mellanox.com> |
| Reviewed-by: Roi Dayan <roid@mellanox.com> |
| Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| 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 70ebebaf5bc12..0ee78a1663786 100644 |
| --- a/net/netfilter/nf_flow_table_core.c |
| +++ b/net/netfilter/nf_flow_table_core.c |
| @@ -271,7 +271,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); |
| @@ -348,8 +348,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); |
| -- |
| 2.20.1 |
| |