Commit dfe42be1 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nft_flow_offload: skip tcp rst and fin packets

TCP rst and fin packets do not qualify to place a flow into the
flowtable. Most likely there will be no more packets after connection
closure. Without this patch, this flow entry expires and connection
tracking picks up the entry in ESTABLISHED state using the fixup
timeout, which makes this look inconsistent to the user for a connection
that is actually already closed.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 656c8e9c
...@@ -72,11 +72,11 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, ...@@ -72,11 +72,11 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
{ {
struct nft_flow_offload *priv = nft_expr_priv(expr); struct nft_flow_offload *priv = nft_expr_priv(expr);
struct nf_flowtable *flowtable = &priv->flowtable->data; struct nf_flowtable *flowtable = &priv->flowtable->data;
struct tcphdr _tcph, *tcph = NULL;
enum ip_conntrack_info ctinfo; enum ip_conntrack_info ctinfo;
struct nf_flow_route route; struct nf_flow_route route;
struct flow_offload *flow; struct flow_offload *flow;
enum ip_conntrack_dir dir; enum ip_conntrack_dir dir;
bool is_tcp = false;
struct nf_conn *ct; struct nf_conn *ct;
int ret; int ret;
...@@ -89,7 +89,10 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, ...@@ -89,7 +89,10 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) { switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) {
case IPPROTO_TCP: case IPPROTO_TCP:
is_tcp = true; tcph = skb_header_pointer(pkt->skb, pkt->xt.thoff,
sizeof(_tcph), &_tcph);
if (unlikely(!tcph || tcph->fin || tcph->rst))
goto out;
break; break;
case IPPROTO_UDP: case IPPROTO_UDP:
break; break;
...@@ -115,7 +118,7 @@ static void nft_flow_offload_eval(const struct nft_expr *expr, ...@@ -115,7 +118,7 @@ static void nft_flow_offload_eval(const struct nft_expr *expr,
if (!flow) if (!flow)
goto err_flow_alloc; goto err_flow_alloc;
if (is_tcp) { if (tcph) {
ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment