nss-packages-qosmio/qca-nss-clients/patches-11.4/0036-vxlanmgr-backport-12.5.patch
Sean Khan 274cc66de7 nss-clients: backport and fixes for ipsecmgr, netlink, vxlanmgr, qdisc
backport 12.5:
* ipsecmgr
* netlink
* vxlanmgr
* qdisc

fixes:
* impsecmgr

Signed-off-by: Sean Khan <datapronix@protonmail.com>
2025-07-10 21:02:00 -04:00

358 lines
11 KiB
Diff

From 580a9ff682ea4e19cb30720662aeecb1ab5df859 Mon Sep 17 00:00:00 2001
From: Apoorv Gupta <apoogupt@codeaurora.org>
Date: Mon, 12 Jul 2021 18:12:43 +0530
Subject: [PATCH] [qca-nss-clients] Options not supported with VxLAN
Flows through VxLAN tunnel should not be accelerated
if the following options are used,
1. RSC(route short-circuit),
2. GPE(Generic Protocol Extension)
Change-Id: I183d24925e1a99ae49a9f1f6011bb7f08eab92f2
Signed-off-by: Apoorv Gupta <apoogupt@codeaurora.org>
---
vxlanmgr/nss_vxlanmgr_tunnel.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
--- a/vxlanmgr/nss_vxlanmgr_tunnel.c
+++ b/vxlanmgr/nss_vxlanmgr_tunnel.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -91,18 +91,23 @@ static uint16_t nss_vxlanmgr_tunnel_flag
uint16_t flags = 0;
uint32_t priv_flags = priv->flags;
+ if (priv_flags & VXLAN_F_RSC)
+ return flags;
if (priv_flags & VXLAN_F_GBP)
flags |= NSS_VXLAN_RULE_FLAG_GBP_ENABLED;
- if (priv_flags & VXLAN_F_IPV6)
+
+ if (priv_flags & VXLAN_F_IPV6) {
flags |= NSS_VXLAN_RULE_FLAG_IPV6;
- else if (!(priv_flags & VXLAN_F_IPV6))
+ if (!(priv_flags & VXLAN_F_UDP_ZERO_CSUM6_TX))
+ flags |= NSS_VXLAN_RULE_FLAG_ENCAP_L4_CSUM_REQUIRED;
+ } else {
flags |= NSS_VXLAN_RULE_FLAG_IPV4;
+ if (priv_flags & VXLAN_F_UDP_CSUM)
+ flags |= NSS_VXLAN_RULE_FLAG_ENCAP_L4_CSUM_REQUIRED;
+ }
+
if (priv->cfg.tos == 1)
flags |= NSS_VXLAN_RULE_FLAG_INHERIT_TOS;
- if (priv_flags & VXLAN_F_UDP_CSUM)
- flags |= NSS_VXLAN_RULE_FLAG_ENCAP_L4_CSUM_REQUIRED;
- else if (!(priv_flags & VXLAN_F_UDP_ZERO_CSUM6_TX))
- flags |= NSS_VXLAN_RULE_FLAG_ENCAP_L4_CSUM_REQUIRED;
return (flags | NSS_VXLAN_RULE_FLAG_UDP);
}
@@ -113,18 +118,25 @@ static uint16_t nss_vxlanmgr_tunnel_flag
struct vxlan_config *cfg = &priv->cfg;
uint32_t priv_flags = cfg->flags;
+ if (priv_flags & VXLAN_F_RSC)
+ return flags;
+ if (priv_flags & VXLAN_F_GPE)
+ return flags;
if (priv_flags & VXLAN_F_GBP)
flags |= NSS_VXLAN_RULE_FLAG_GBP_ENABLED;
- if (priv_flags & VXLAN_F_IPV6)
+
+ if (priv_flags & VXLAN_F_IPV6) {
flags |= NSS_VXLAN_RULE_FLAG_IPV6;
- else if (!(priv_flags & VXLAN_F_IPV6))
+ if (!(priv_flags & VXLAN_F_UDP_ZERO_CSUM6_TX))
+ flags |= NSS_VXLAN_RULE_FLAG_ENCAP_L4_CSUM_REQUIRED;
+ } else {
flags |= NSS_VXLAN_RULE_FLAG_IPV4;
+ if (!(priv_flags & VXLAN_F_UDP_ZERO_CSUM_TX))
+ flags |= NSS_VXLAN_RULE_FLAG_ENCAP_L4_CSUM_REQUIRED;
+ }
+
if (cfg->tos == 1)
flags |= NSS_VXLAN_RULE_FLAG_INHERIT_TOS;
- if (priv_flags & VXLAN_F_UDP_ZERO_CSUM_TX)
- flags |= NSS_VXLAN_RULE_FLAG_ENCAP_L4_CSUM_REQUIRED;
- else if (!(priv_flags & VXLAN_F_UDP_ZERO_CSUM6_TX))
- flags |= NSS_VXLAN_RULE_FLAG_ENCAP_L4_CSUM_REQUIRED;
return (flags | NSS_VXLAN_RULE_FLAG_UDP);
}
@@ -436,7 +448,8 @@ static struct notifier_block nss_vxlanmg
/*
* nss_vxlanmgr_tunnel_inner_stats()
- * Update vxlan netdev stats with inner node stats
+ * Update vxlan netdev stats with inner node stats.
+ * Note: Reference on the netdevice is expected to be held by the caller at the time this function is called.
*/
static void nss_vxlanmgr_tunnel_inner_stats(struct nss_vxlanmgr_tun_ctx *tun_ctx, struct nss_vxlan_msg *nvm)
{
@@ -450,7 +463,6 @@ static void nss_vxlanmgr_tunnel_inner_st
stats = &nvm->msg.stats;
dev = tun_ctx->dev;
- dev_hold(dev);
netdev_stats = (struct net_device_stats *)&dev->stats;
/*
@@ -469,7 +481,6 @@ static void nss_vxlanmgr_tunnel_inner_st
u64_stats_add(&tstats->tx_bytes, stats->node_stats.tx_bytes);
u64_stats_update_end(&tstats->syncp);
netdev_stats->tx_dropped += dropped;
- dev_put(dev);
}
/*
@@ -514,7 +525,7 @@ static void nss_vxlanmgr_tunnel_outer_st
* nss_vxlanmgr_tunnel_fdb_update()
* Update vxlan fdb entries
*/
-static void nss_vxlanmgr_tunnel_fdb_update(struct nss_vxlanmgr_tun_ctx *tun_ctx, struct nss_vxlan_msg *nvm)
+static void nss_vxlanmgr_tunnel_fdb_update(struct net_device *dev, uint32_t vni, struct nss_vxlan_msg *nvm)
{
uint8_t *mac;
uint16_t i, nentries;
@@ -523,13 +534,10 @@ static void nss_vxlanmgr_tunnel_fdb_upda
db_stats = &nvm->msg.db_stats;
nentries = db_stats->cnt;
- priv = netdev_priv(tun_ctx->dev);
-
- dev_hold(tun_ctx->dev);
+ priv = netdev_priv(dev);
if (nentries > NSS_VXLAN_MACDB_ENTRIES_PER_MSG) {
- nss_vxlanmgr_warn("%px: No more than 20 entries allowed per message.\n", tun_ctx->dev);
- dev_put(tun_ctx->dev);
+ nss_vxlanmgr_warn("%px: No more than 20 entries allowed per message.\n", dev);
return;
}
@@ -539,11 +547,10 @@ static void nss_vxlanmgr_tunnel_fdb_upda
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 5, 7))
vxlan_fdb_update_mac(priv, mac);
#else
- vxlan_fdb_update_mac(priv, mac, tun_ctx->vni);
+ vxlan_fdb_update_mac(priv, mac, vni);
#endif
}
}
- dev_put(tun_ctx->dev);
}
/*
@@ -555,20 +562,29 @@ static void nss_vxlanmgr_tunnel_inner_no
struct net_device *dev = (struct net_device *)app_data;
struct nss_vxlanmgr_tun_ctx *tun_ctx;
struct nss_vxlan_msg *nvm;
+ uint32_t vni;
if (!ncm) {
nss_vxlanmgr_info("%px: NULL msg received.\n", dev);
return;
}
+ if (!dev) {
+ nss_vxlanmgr_info("%px: NULL device received.\n", dev);
+ return;
+ }
+
spin_lock_bh(&vxlan_ctx.tun_lock);
+ dev_hold(dev);
tun_ctx = nss_vxlanmgr_tunnel_ctx_dev_get(dev);
if (!tun_ctx) {
spin_unlock_bh(&vxlan_ctx.tun_lock);
nss_vxlanmgr_warn("%px: Invalid tunnel context\n", dev);
+ dev_put(dev);
return;
}
+ vni = tun_ctx->vni;
nvm = (struct nss_vxlan_msg *)ncm;
switch (nvm->cm.type) {
case NSS_VXLAN_MSG_TYPE_STATS_SYNC:
@@ -576,14 +592,24 @@ static void nss_vxlanmgr_tunnel_inner_no
nss_vxlanmgr_tun_stats_sync(tun_ctx, nvm);
break;
case NSS_VXLAN_MSG_TYPE_MACDB_STATS:
- nss_vxlanmgr_tunnel_fdb_update(tun_ctx, nvm);
nss_vxlanmgr_tun_macdb_stats_sync(tun_ctx, nvm);
- break;
- default:
+
+ /*
+ * Release the lock before updating the Linux FDB entry.
+ * This will ensure there is no deadlock when a potential
+ * MAC add event occurs at same time, which needs to hold
+ * the kernel's hash lock followed by the tunnel ctx lock.
+ */
spin_unlock_bh(&vxlan_ctx.tun_lock);
- nss_vxlanmgr_info("%px: Unknown Event from NSS", dev);
+
+ nss_vxlanmgr_tunnel_fdb_update(dev, vni, nvm);
+ dev_put(dev);
return;
+ default:
+ nss_vxlanmgr_info("%px: Unknown Event from NSS", dev);
}
+
+ dev_put(dev);
spin_unlock_bh(&vxlan_ctx.tun_lock);
}
@@ -829,7 +855,7 @@ done:
*/
int nss_vxlanmgr_tunnel_destroy(struct net_device *dev)
{
- uint32_t inner_ifnum, outer_ifnum;
+ uint32_t inner_ifnum, outer_ifnum, tun_count;
struct nss_vxlanmgr_tun_ctx *tun_ctx;
struct nss_vxlan_msg vxlanmsg;
nss_tx_status_t ret;
@@ -866,16 +892,21 @@ int nss_vxlanmgr_tunnel_destroy(struct n
nss_vxlanmgr_tun_stats_deinit(tun_ctx);
nss_vxlanmgr_tun_stats_dentry_remove(tun_ctx);
+ dev_put(tun_ctx->dev);
kfree(tun_ctx);
- if (!vxlan_ctx.tun_count) {
- /*
- * Unregister fdb notifier chain if
- * all vxlan tunnels are destroyed.
- */
+ /*
+ * Unregister fdb notifier chain if
+ * all vxlan tunnels are destroyed.
+ */
+ spin_lock_bh(&vxlan_ctx.tun_lock);
+ tun_count = vxlan_ctx.tun_count;
+ spin_unlock_bh(&vxlan_ctx.tun_lock);
+ if (!tun_count) {
vxlan_fdb_unregister_notify(&nss_vxlanmgr_tunnel_fdb_notifier);
}
- nss_vxlanmgr_info("%px: VxLAN interface count is #%d\n", dev, vxlan_ctx.tun_count);
+
+ nss_vxlanmgr_info("%px: VxLAN interface count is #%d\n", dev, tun_count);
memset(&vxlanmsg, 0, sizeof(struct nss_vxlan_msg));
ret = nss_vxlanmgr_tunnel_tx_msg_sync(vxlan_ctx.nss_ctx,
@@ -929,6 +960,7 @@ int nss_vxlanmgr_tunnel_create(struct ne
struct nss_vxlan_rule_msg *vxlan_cfg;
struct nss_ctx_instance *nss_ctx;
uint32_t inner_ifnum, outer_ifnum;
+ uint16_t parse_flags;
nss_tx_status_t ret;
spin_lock_bh(&vxlan_ctx.tun_lock);
@@ -939,7 +971,20 @@ int nss_vxlanmgr_tunnel_create(struct ne
}
spin_unlock_bh(&vxlan_ctx.tun_lock);
+ /*
+ * The reference to the dev will be released in nss_vxlanmgr_tunnel_destroy()
+ */
dev_hold(dev);
+ priv = netdev_priv(dev);
+ parse_flags = nss_vxlanmgr_tunnel_flags_parse(priv);
+
+ /*
+ * Check if the tunnel is supported.
+ */
+ if (!parse_flags) {
+ nss_vxlanmgr_warn("%px: Tunnel offload not supported\n", dev);
+ goto ctx_alloc_fail;
+ }
tun_ctx = kzalloc(sizeof(struct nss_vxlanmgr_tun_ctx), GFP_ATOMIC);
if (!tun_ctx) {
@@ -988,12 +1033,11 @@ int nss_vxlanmgr_tunnel_create(struct ne
memset(&vxlanmsg, 0, sizeof(struct nss_vxlan_msg));
vxlan_cfg = &vxlanmsg.msg.vxlan_create;
- priv = netdev_priv(dev);
vxlan_cfg->vni = vxlan_get_vni(priv);
- vxlan_cfg->tunnel_flags = nss_vxlanmgr_tunnel_flags_parse(priv);
+ vxlan_cfg->tunnel_flags = parse_flags;
vxlan_cfg->src_port_min = priv->cfg.port_min;
vxlan_cfg->src_port_max = priv->cfg.port_max;
- vxlan_cfg->dest_port = priv->cfg.dst_port;
+ vxlan_cfg->dest_port = ntohs(priv->cfg.dst_port);
vxlan_cfg->tos = priv->cfg.tos;
vxlan_cfg->ttl = (priv->cfg.ttl ? priv->cfg.ttl : IPDEFTTL);
@@ -1059,7 +1103,6 @@ int nss_vxlanmgr_tunnel_create(struct ne
spin_unlock_bh(&vxlan_ctx.tun_lock);
nss_vxlanmgr_info("%px: VxLAN interface count is #%d\n", dev, vxlan_ctx.tun_count);
- dev_put(dev);
return NOTIFY_DONE;
config_fail:
--- a/vxlanmgr/nss_vxlanmgr_tun_stats.c
+++ b/vxlanmgr/nss_vxlanmgr_tun_stats.c
@@ -89,7 +89,7 @@ static int nss_vxlanmgr_tun_stats_show(s
seq_printf(m, "\t\tflow_label = %u\n", tun_ctx->flow_label);
seq_printf(m, "\t\tsrc_port_min = %u\n", tun_ctx->src_port_min);
seq_printf(m, "\t\tsrc_port_max = %u\n", tun_ctx->src_port_max);
- seq_printf(m, "\t\tdest_port = %u\n", ntohs(tun_ctx->dest_port));
+ seq_printf(m, "\t\tdest_port = %u\n", tun_ctx->dest_port);
seq_printf(m, "\t\ttos = %u\n", tun_ctx->tos);
seq_printf(m, "\t\tttl = %u\n", tun_ctx->ttl);
@@ -173,6 +173,7 @@ void nss_vxlanmgr_tun_stats_update(uint6
/*
* nss_vxlanmgr_tun_macdb_stats_sync()
* Sync function for vxlan fdb entries
+ * Note: Reference on the netdevice is expected to be held by the caller at the time this function is called.
*/
void nss_vxlanmgr_tun_macdb_stats_sync(struct nss_vxlanmgr_tun_ctx *tun_ctx, struct nss_vxlan_msg *nvm)
{
@@ -183,11 +184,8 @@ void nss_vxlanmgr_tun_macdb_stats_sync(s
db_stats = &nvm->msg.db_stats;
nentries = db_stats->cnt;
- dev_hold(tun_ctx->dev);
-
if (nentries > NSS_VXLAN_MACDB_ENTRIES_PER_MSG) {
nss_vxlanmgr_warn("%px: No more than 20 entries allowed per message.\n", tun_ctx->dev);
- dev_put(tun_ctx->dev);
return;
}
@@ -203,7 +201,6 @@ void nss_vxlanmgr_tun_macdb_stats_sync(s
}
}
}
- dev_put(tun_ctx->dev);
}
/*
@@ -299,7 +296,7 @@ bool nss_vxlanmgr_tun_stats_dentry_creat
* nss_vxlanmgr_tun_stats_dentry_deinit()
* Cleanup the debugfs tree.
*/
-void nss_vxlanmgr_tun_stats_dentry_deinit()
+void nss_vxlanmgr_tun_stats_dentry_deinit(void)
{
debugfs_remove_recursive(vxlan_ctx.dentry);
}
@@ -308,7 +305,7 @@ void nss_vxlanmgr_tun_stats_dentry_deini
* nss_vxlanmgr_tun_stats_dentry_init()
* Create VxLAN tunnel statistics debugfs entry.
*/
-bool nss_vxlanmgr_tun_stats_dentry_init()
+bool nss_vxlanmgr_tun_stats_dentry_init(void)
{
/*
* initialize debugfs.