---
create mode 100644 net/netfilter/xt_OFFLOAD.c
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -56,8 +56,6 @@ config NF_TABLES_ARP
- help
- This option enables the ARP support for nf_tables.
-
--endif # NF_TABLES
--
- config NF_FLOW_TABLE_IPV4
- tristate "Netfilter flow table IPv4 module"
- depends on NF_FLOW_TABLE
-@@ -66,6 +64,8 @@ config NF_FLOW_TABLE_IPV4
-
- To compile it as a module, choose M here.
-
-+endif # NF_TABLES
-+
- config NF_DUP_IPV4
- tristate "Netfilter IPv4 packet duplication to alternate destination"
- depends on !NF_CONNTRACK || NF_CONNTRACK
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -45,7 +45,6 @@ config NFT_FIB_IPV6
- multicast or blackhole.
-
- endif # NF_TABLES_IPV6
--endif # NF_TABLES
-
- config NF_FLOW_TABLE_IPV6
- tristate "Netfilter flow table IPv6 module"
-@@ -55,6 +54,8 @@ config NF_FLOW_TABLE_IPV6
-
- To compile it as a module, choose M here.
-
-+endif # NF_TABLES
-+
- config NF_DUP_IPV6
- tristate "Netfilter IPv6 packet duplication to alternate destination"
- depends on !NF_CONNTRACK || NF_CONNTRACK
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
-@@ -707,8 +707,6 @@ config NFT_REJECT_NETDEV
-
- endif # NF_TABLES_NETDEV
-
--endif # NF_TABLES
--
- config NF_FLOW_TABLE_INET
- tristate "Netfilter flow table mixed IPv4/IPv6 module"
- depends on NF_FLOW_TABLE
-@@ -717,11 +715,12 @@ config NF_FLOW_TABLE_INET
-
- To compile it as a module, choose M here.
-
-+endif # NF_TABLES
-+
- config NF_FLOW_TABLE
+@@ -726,7 +726,6 @@ config NF_FLOW_TABLE
tristate "Netfilter flow table module"
depends on NETFILTER_INGRESS
depends on NF_CONNTRACK
help
This option adds the flow table core infrastructure.
-@@ -1010,6 +1009,15 @@ config NETFILTER_XT_TARGET_NOTRACK
+@@ -1023,6 +1022,15 @@ config NETFILTER_XT_TARGET_NOTRACK
depends on NETFILTER_ADVANCED
select NETFILTER_XT_TARGET_CT
depends on NETFILTER_ADVANCED
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
-@@ -143,6 +143,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF
+@@ -154,6 +154,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
--- /dev/null
+++ b/net/netfilter/xt_FLOWOFFLOAD.c
-@@ -0,0 +1,698 @@
+@@ -0,0 +1,703 @@
+/*
+ * Copyright (C) 2018-2021 Felix Fietkau <nbd@nbd.name>
+ *
+ proto = veth->h_vlan_encapsulated_proto;
+ break;
+ case htons(ETH_P_PPP_SES):
-+ proto = nf_flow_pppoe_proto(skb);
++ if (!nf_flow_pppoe_proto(skb, &proto))
++ return NF_ACCEPT;
+ break;
+ default:
+ proto = skb->protocol;
+ break;
+ }
+
++ if (!dst_hold_safe(this_dst))
++ return -ENOENT;
++
+ nf_route(xt_net(par), &other_dst, &fl, false, xt_family(par));
-+ if (!other_dst)
++ if (!other_dst) {
++ dst_release(this_dst);
+ return -ENOENT;
++ }
+
+ nf_default_forward_path(route, this_dst, dir, devs);
+ nf_default_forward_path(route, other_dst, !dir, devs);
+ if (!nf_ct_is_confirmed(ct))
+ return XT_CONTINUE;
+
++ dir = CTINFO2DIR(ctinfo);
++
+ devs[dir] = xt_out(par);
+ devs[!dir] = xt_in(par);
+
+ if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status))
+ return XT_CONTINUE;
+
-+ dir = CTINFO2DIR(ctinfo);
-+
+ if (xt_flowoffload_route(skb, ct, par, &route, dir, devs) < 0)
+ goto err_flow_route;
+
+ if (!flow)
+ goto err_flow_alloc;
+
-+ if (flow_offload_route_init(flow, &route) < 0)
-+ goto err_flow_add;
++ flow_offload_route_init(flow, &route);
+
+ if (tcph) {
+ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
+ if (!net)
+ write_pnet(&table->ft.net, xt_net(par));
+
++ __set_bit(NF_FLOW_HW_BIDIRECTIONAL, &flow->flags);
+ if (flow_offload_add(&table->ft, flow) < 0)
+ goto err_flow_add;
+
+ xt_flowoffload_check_device(table, devs[0]);
+ xt_flowoffload_check_device(table, devs[1]);
+
-+ dst_release(route.tuple[!dir].dst);
-+
+ return XT_CONTINUE;
+
+err_flow_add:
+ flow_offload_free(flow);
+err_flow_alloc:
++ dst_release(route.tuple[dir].dst);
+ dst_release(route.tuple[!dir].dst);
+err_flow_route:
+ clear_bit(IPS_OFFLOAD_BIT, &ct->status);
+};
+
+static int nf_flow_rule_route_inet(struct net *net,
-+ const struct flow_offload *flow,
++ struct flow_offload *flow,
+ enum flow_offload_tuple_dir dir,
+ struct nf_flow_rule *flow_rule)
+{
#include <net/netfilter/nf_flow_table.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
-@@ -380,8 +379,7 @@ flow_offload_lookup(struct nf_flowtable
+@@ -374,8 +373,7 @@ flow_offload_lookup(struct nf_flowtable
}
EXPORT_SYMBOL_GPL(flow_offload_lookup);
void (*iter)(struct nf_flowtable *flowtable,
struct flow_offload *flow, void *data),
void *data)
-@@ -435,6 +433,7 @@ static void nf_flow_offload_gc_step(stru
+@@ -436,6 +434,7 @@ static void nf_flow_offload_gc_step(stru
nf_flow_offload_stats(flow_table, flow);
}
}
+#endif /* _XT_FLOWOFFLOAD_H */
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
-@@ -276,6 +276,11 @@ void nf_flow_table_free(struct nf_flowta
+@@ -293,6 +293,11 @@ void nf_flow_table_free(struct nf_flowta
void flow_offload_teardown(struct flow_offload *flow);