[][kernel][common][hnat][Add support to identify bond slave device]
[Description]
Add support to identify bond slave device.
Without this patch, the traffic destinate to a bond device can only
forward to GMAC1 or GMAC2 after HNAT offload is enabled, this patch
can identify the slave device and set the correct PPE entry dp.
[Release-log]
N/A
Change-Id: I3f213f1e404000e188b2129c133a244397f1b3ac
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/9527579
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
index c59e97e..50cc41f 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat.h
@@ -1155,15 +1155,19 @@
#define NR_WDMA2_PORT 13
#define NR_GMAC3_PORT 15
#define NR_QDMA_TPORT 1
+#define WAN_DEV_NAME hnat_priv->wan
#define LAN_DEV_NAME hnat_priv->lan
#define LAN2_DEV_NAME hnat_priv->lan2
-#define IS_WAN(dev) \
- (!strncmp((dev)->name, hnat_priv->wan, strlen(hnat_priv->wan)))
+#define IS_WAN(dev) (!strncmp((dev)->name, WAN_DEV_NAME, strlen(WAN_DEV_NAME)))
#define IS_LAN_GRP(dev) (IS_LAN(dev) | IS_LAN2(dev))
-#define IS_LAN(dev) (!strncmp(dev->name, LAN_DEV_NAME, strlen(LAN_DEV_NAME)))
-#define IS_LAN2(dev) (!strncmp(dev->name, LAN2_DEV_NAME, \
- strlen(LAN2_DEV_NAME)))
+#define IS_LAN(dev) \
+ (!strncmp(dev->name, LAN_DEV_NAME, strlen(LAN_DEV_NAME)) || \
+ IS_BOND(dev))
+#define IS_LAN2(dev) \
+ (!strncmp(dev->name, LAN2_DEV_NAME, strlen(LAN2_DEV_NAME)) || \
+ IS_BOND(dev))
#define IS_BR(dev) (!strncmp(dev->name, "br", 2))
+#define IS_BOND(dev) (!strncmp(dev->name, "bond", 4))
#define IS_WHNAT(dev) \
((hnat_priv->data->whnat && \
(get_wifi_hook_if_index_from_dev(dev) != 0)) ? 1 : 0)
@@ -1184,7 +1188,6 @@
(IS_IPV6_3T_ROUTE(x) | IS_IPV6_5T_ROUTE(x) | IS_IPV6_6RD(x) | \
IS_IPV4_DSLITE(x) | IS_IPV4_MAPE(x) | IS_IPV4_MAPT(x) | \
IS_IPV6_HNAPT(x) | IS_IPV6_HNAT(x))
-#define IS_BOND_MODE (!strncmp(LAN_DEV_NAME, "bond", 4))
#define IS_GMAC1_MODE ((hnat_priv->gmac_num == 1) ? 1 : 0)
#define IS_HQOS_MODE (qos_toggle == 1)
#define IS_PPPQ_MODE (qos_toggle == 2) /* Per Port Per Queue */
diff --git a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
index 8b4641f..3abfbf2 100644
--- a/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+++ b/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
@@ -447,7 +447,7 @@
return -1;
}
- if (IS_BOND_MODE &&
+ if (IS_BOND(dev) &&
(((hnat_priv->data->version == MTK_HNAT_V2 ||
hnat_priv->data->version == MTK_HNAT_V3) &&
(skb_hnat_entry(skb) != 0x7fff)) ||
@@ -1246,8 +1246,9 @@
struct flow_offload_hw_path *hw_path)
{
struct net_device *master_dev = (struct net_device *)dev;
+ struct net_device *slave_dev[10];
+ struct list_head *iter;
struct foe_entry entry = { 0 };
- int whnat = IS_WHNAT(dev);
struct mtk_mac *mac;
struct ethhdr *eth;
struct iphdr *iph;
@@ -1256,12 +1257,14 @@
const struct tcpudphdr *pptr;
struct nf_conn *ct;
enum ip_conntrack_info ctinfo;
+ int whnat = IS_WHNAT(dev);
int gmac = NR_DISCARD;
int udp = 0;
int port_id = 0;
u32 qid = 0;
u32 payload_len = 0;
int mape = 0;
+ int i = 0;
if (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPIP)
/* point to ethernet header for DS-Lite and MapE */
@@ -1714,6 +1717,23 @@
entry = ppe_fill_info_blk(eth, entry, hw_path);
if (IS_LAN_GRP(dev) || IS_WAN(dev)) { /* Forward to GMAC Ports */
+ if (IS_BOND(dev)) {
+ /* Retrieve subordinate devices that are connected to the Bond device */
+ netdev_for_each_lower_dev(master_dev, slave_dev[i], iter) {
+ /* Check the link status of the slave device */
+ if (!(slave_dev[i]->flags & IFF_UP) ||
+ !netif_carrier_ok(slave_dev[i]))
+ continue;
+ i++;
+ if (i >= ARRAY_SIZE(slave_dev))
+ break;
+ }
+ if (i > 0) {
+ /* Choose a subordinate device according to the hash index */
+ dev = slave_dev[(skb_hnat_entry(skb) >> 1) % i];
+ master_dev = slave_dev[(skb_hnat_entry(skb) >> 1) % i];
+ }
+ }
port_id = hnat_dsa_get_port(&master_dev);
if (port_id >= 0) {
if (hnat_dsa_fill_stag(dev, &entry, hw_path,
@@ -1724,10 +1744,7 @@
mac = netdev_priv(master_dev);
gmac = HNAT_GMAC_FP(mac->id);
- if (IS_LAN(dev) && IS_BOND_MODE) {
- gmac = ((skb_hnat_entry(skb) >> 1) % hnat_priv->gmac_num) ?
- NR_GMAC2_PORT : NR_GMAC1_PORT;
- } else if (IS_WAN(dev) && mape_toggle && mape == 1) {
+ if (IS_WAN(dev) && mape_toggle && mape == 1) {
gmac = NR_PDMA_PORT;
/* Set act_dp = wan_dev */
entry.ipv4_hnapt.act_dp &= ~UDF_PINGPONG_IFIDX;