[][MAC80211][hnat][Flow offload cannot bind]

[Description]
Fix flow offload cannot bind entry without arp in bridge mode.
We need get mac info from eth header

If we don't apply this patch,
HW path cannot work correctly in bridge mode without neighbor learned.

[Release-log]
N/A


Change-Id: Id2c03a0fc73f024b98fb1fa7cec39d55c4a783a1
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7483290
diff --git a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch
index 7d4c5d6..17f2cb1 100755
--- a/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch
+++ b/autobuild_mac80211_release/target/linux/mediatek/patches-5.4/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch
@@ -6122,10 +6122,10 @@
 +}
 diff --git a/net/netfilter/xt_FLOWOFFLOAD.c b/net/netfilter/xt_FLOWOFFLOAD.c
 new file mode 100644
-index 000000000..ae1eb2656
+index 0000000..12f067c
 --- /dev/null
 +++ b/net/netfilter/xt_FLOWOFFLOAD.c
-@@ -0,0 +1,776 @@
+@@ -0,0 +1,794 @@
 +/*
 + * Copyright (C) 2018-2021 Felix Fietkau <nbd@nbd.name>
 + *
@@ -6493,34 +6493,52 @@
 +	if (!nf_is_valid_ether_device(dev))
 +		goto out;
 +
-+	n = dst_neigh_lookup(dst_cache, daddr);
-+	if (!n)
-+		return -1;
++	if (ct->status & IPS_NAT_MASK) {
++		n = dst_neigh_lookup(dst_cache, daddr);
++		if (!n)
++			return -1;
 +
-+	read_lock_bh(&n->lock);
-+	nud_state = n->nud_state;
-+	ether_addr_copy(ha, n->ha);
-+	read_unlock_bh(&n->lock);
-+	neigh_release(n);
++		read_lock_bh(&n->lock);
++		nud_state = n->nud_state;
++		ether_addr_copy(ha, n->ha);
++		read_unlock_bh(&n->lock);
++		neigh_release(n);
 +
-+	if (!(nud_state & NUD_VALID))
-+		return -1;
++		if (!(nud_state & NUD_VALID))
++			return -1;
++	}
 +
 +out:
 +	return dev_fill_forward_path(dev, ha, stack);
 +}
 +
-+static int nf_dev_forward_path(struct nf_flow_route *route,
++static int nf_dev_forward_path(struct sk_buff *skb,
++				struct nf_flow_route *route,
 +				const struct nf_conn *ct,
 +				enum ip_conntrack_dir dir,
 +				struct net_device **devs)
 +{
 +	const struct dst_entry *dst = route->tuple[dir].dst;
++	struct ethhdr *eth;
++	enum ip_conntrack_dir skb_dir;
 +	struct net_device_path_stack stack;
 +	struct nf_forward_info info = {};
 +	unsigned char ha[ETH_ALEN];
 +	int i;
 +
++	if (!(ct->status & IPS_NAT_MASK) && skb_mac_header_was_set(skb)) {
++		eth = eth_hdr(skb);
++		skb_dir = CTINFO2DIR(skb_get_nfct(skb) & NFCT_INFOMASK);
++
++		if (skb_dir != dir) {
++			memcpy(ha, eth->h_source, ETH_ALEN);
++			memcpy(info.h_source, eth->h_dest, ETH_ALEN);
++		} else {
++			memcpy(ha, eth->h_dest, ETH_ALEN);
++			memcpy(info.h_source, eth->h_source, ETH_ALEN);
++		}
++	}
++
 +	if (nf_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
 +		nf_dev_path_info(&stack, &info, ha);
 +
@@ -6610,9 +6628,9 @@
 +
 +	if (route->tuple[dir].xmit_type	== FLOW_OFFLOAD_XMIT_NEIGH &&
 +	    route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) {
-+		if (nf_dev_forward_path(route, ct, dir, devs))
++		if (nf_dev_forward_path(skb, route, ct, dir, devs))
 +			return -1;
-+		if (nf_dev_forward_path(route, ct, !dir, devs))
++		if (nf_dev_forward_path(skb, route, ct, !dir, devs))
 +			return -1;
 +	}
 +
@@ -6641,8 +6659,8 @@
 +
 +	if (route->tuple[dir].xmit_type	== FLOW_OFFLOAD_XMIT_NEIGH &&
 +	    route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) {
-+		if (nf_dev_forward_path(route, ct, dir, devs) ||
-+		    nf_dev_forward_path(route, ct, !dir, devs)) {
++		if (nf_dev_forward_path(skb, route, ct, dir, devs) ||
++		    nf_dev_forward_path(skb, route, ct, !dir, devs)) {
 +			ret = -1;
 +			goto err_route_dir2;
 +		}