--- /dev/null
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -738,6 +738,7 @@ struct sk_buff {
+ #endif
+ __u8 ipvs_property:1;
+ __u8 inner_protocol_type:1;
++ __u8 fast_forwarded:1;
+ __u8 remcsum_offload:1;
+ #ifdef CONFIG_NET_SWITCHDEV
+ __u8 offload_fwd_mark:1;
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2947,8 +2947,14 @@ static int xmit_one(struct sk_buff *skb,
+ unsigned int len;
+ int rc;
+
+- if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all))
+- dev_queue_xmit_nit(skb, dev);
++ /*
++ * If this skb has been fast forwarded then we don't want it to
++ * go to any taps (by definition we're trying to bypass them).
++ */
++ if (!skb->fast_forwarded) {
++ if (!list_empty(&ptype_all))
++ dev_queue_xmit_nit(skb, dev);
++ }
+
+ #ifdef CONFIG_ETHERNET_PACKET_MANGLE
+ if (!dev->eth_mangle_tx ||
+@@ -4137,6 +4143,9 @@ static inline int nf_ingress(struct sk_b
+ return 0;
+ }
+
++int (*fast_nat_recv)(struct sk_buff *skb) __rcu __read_mostly;
++EXPORT_SYMBOL_GPL(fast_nat_recv);
++
+ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
+ {
+ struct packet_type *ptype, *pt_prev;
+@@ -4146,6 +4155,8 @@ static int __netif_receive_skb_core(stru
+ int ret = NET_RX_DROP;
+ __be16 type;
+
++ int (*fast_recv)(struct sk_buff *skb);
++
+ net_timestamp_check(!netdev_tstamp_prequeue, skb);
+
+ trace_netif_receive_skb(skb);
+@@ -4171,6 +4182,12 @@ another_round:
+ goto out;
+ }
+
++ fast_recv = rcu_dereference(fast_nat_recv);
++ if (fast_recv && fast_recv(skb)) {
++ ret = NET_RX_SUCCESS;
++ goto out;
++ }
++
+ #ifdef CONFIG_NET_CLS_ACT
+ if (skb->tc_verd & TC_NCLS) {
+ skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
+--- a/net/netfilter/nf_conntrack_proto_tcp.c
++++ b/net/netfilter/nf_conntrack_proto_tcp.c
+@@ -35,6 +35,7 @@
+
+ /* Do not check the TCP window for incoming packets */
+ static int nf_ct_tcp_no_window_check __read_mostly = 1;
++EXPORT_SYMBOL_GPL(nf_ct_tcp_no_window_check);
+
+ /* "Be conservative in what you do,
+ be liberal in what you accept from others."
+--- a/net/bridge/br_if.c
++++ b/net/bridge/br_if.c
+@@ -655,3 +655,26 @@ void br_port_flags_change(struct net_bri
+ if (mask & BR_AUTO_MASK)
+ nbp_update_port_count(br);
+ }
++/* Update bridge statistics for bridge packets processed by offload engines */
++void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats)
++{
++ struct net_bridge *br;
++ struct pcpu_sw_netstats *stats;
++
++ /*
++ * Is this a bridge?
++ */
++ if (!(dev->priv_flags & IFF_EBRIDGE))
++ return;
++
++ br = netdev_priv(dev);
++ stats = per_cpu_ptr(br->stats, 0);
++
++ u64_stats_update_begin(&stats->syncp);
++ stats->rx_packets += nlstats->rx_packets;
++ stats->rx_bytes += nlstats->rx_bytes;
++ stats->tx_packets += nlstats->tx_packets;
++ stats->tx_bytes += nlstats->tx_bytes;
++ u64_stats_update_end(&stats->syncp);
++}
++EXPORT_SYMBOL_GPL(br_dev_update_stats);