|
@@ -71,11 +71,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;
|
|
|
|
|
|
|
@@ -88,7 +88,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,
|
|
|
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;
|
|
|
}
|
|
}
|