Before I can get to work a feed repository that work i have included qca-nss source needed on this commit Source author: SqTER-PL <r.napierala@asta-net.pl>
11299 lines
366 KiB
Diff
11299 lines
366 KiB
Diff
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -5,27 +5,25 @@ ccflags-y := -I$(obj) -I$(obj)/..
|
|
export BUILD_ID = \"Build Id: $(shell date +'%m/%d/%y, %H:%M:%S')\"
|
|
ccflags-y += -DNSS_CLIENT_BUILD_ID="$(BUILD_ID)"
|
|
|
|
+qca-nss-tunipip6-objs := nss_connmgr_tunipip6.o
|
|
qca-nss-tun6rd-objs := nss_connmgr_tun6rd.o
|
|
|
|
+ccflags-y += -DNSS_TUNIPIP6_DEBUG_LEVEL=0
|
|
ccflags-y += -DNSS_TUN6RD_DEBUG_LEVEL=0
|
|
-ccflags-y += -Wall -Werror
|
|
-
|
|
-KERNELVERSION := $(word 1, $(subst ., ,$(KERNELVERSION))).$(word 2, $(subst ., ,$(KERNELVERSION)))
|
|
+ccflags-y += -Werror
|
|
|
|
obj-$(bridge-mgr)+= bridge/
|
|
obj-$(capwapmgr)+= capwapmgr/
|
|
obj-$(dtlsmgr)+= dtls/$(DTLSMGR_DIR)/
|
|
obj-$(gre)+= gre/
|
|
obj-$(ipsecmgr)+= ipsecmgr/$(IPSECMGR_DIR)/
|
|
-obj-$(ipsecmgr-klips)+= ipsecmgr/$(IPSECMGR_DIR)/plugins/klips/
|
|
-obj-$(ipsecmgr-xfrm)+= ipsecmgr/$(IPSECMGR_DIR)/plugins/xfrm/
|
|
obj-$(l2tpv2)+= l2tp/l2tpv2/
|
|
obj-$(lag-mgr)+= lag/
|
|
obj-$(map-t)+= map/map-t/
|
|
obj-$(portifmgr)+= portifmgr/
|
|
obj-$(pptp)+= pptp/
|
|
obj-$(profile)+= profiler/
|
|
-obj-$(tunipip6)+= tunipip6/
|
|
+obj-$(tunipip6)+= qca-nss-tunipip6.o
|
|
obj-$(tun6rd)+= qca-nss-tun6rd.o
|
|
obj-$(qdisc)+= nss_qdisc/
|
|
obj-$(vlan-mgr)+= vlan/
|
|
@@ -38,8 +36,6 @@ obj-$(clmapmgr)+= clmapmgr/
|
|
obj-$(match)+= match/
|
|
obj-$(tlsmgr)+= tls/
|
|
obj-$(mirror)+= mirror/
|
|
-obj-$(mscs)+= mscs/
|
|
-obj-$(wifi-meshmgr)+= wifi_meshmgr/
|
|
|
|
#NSS NETLINK
|
|
obj-$(netlink)+= netlink/
|
|
--- a/bridge/Makefile
|
|
+++ b/bridge/Makefile
|
|
@@ -9,7 +9,7 @@ qca-nss-bridge-mgr-objs += nss_bridge_mg
|
|
endif
|
|
|
|
ccflags-y += -DNSS_BRIDGE_MGR_DEBUG_LEVEL=0
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
|
|
ifeq ($(SoC),$(filter $(SoC),ipq807x ipq807x_64 ipq60xx ipq60xx_64))
|
|
ccflags-y += -DNSS_BRIDGE_MGR_PPE_SUPPORT
|
|
--- a/bridge/nss_bridge_mgr.c
|
|
+++ b/bridge/nss_bridge_mgr.c
|
|
@@ -1,12 +1,9 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
|
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
- *
|
|
+ * Copyright (c) 2016-2020, 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.
|
|
- *
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
@@ -418,37 +415,6 @@ static int nss_bridge_mgr_del_bond_slave
|
|
}
|
|
|
|
/*
|
|
- * nss_bridge_mgr_bond_fdb_join()
|
|
- * Update FDB state when a bond interface joining bridge.
|
|
- */
|
|
-static int nss_bridge_mgr_bond_fdb_join(struct nss_bridge_pvt *b_pvt)
|
|
-{
|
|
- /*
|
|
- * If already other bond devices are attached to bridge,
|
|
- * only increment bond_slave_num,
|
|
- */
|
|
- spin_lock(&br_mgr_ctx.lock);
|
|
- if (b_pvt->bond_slave_num) {
|
|
- b_pvt->bond_slave_num++;
|
|
- spin_unlock(&br_mgr_ctx.lock);
|
|
- return NOTIFY_DONE;
|
|
- }
|
|
- b_pvt->bond_slave_num = 1;
|
|
- spin_unlock(&br_mgr_ctx.lock);
|
|
-
|
|
- /*
|
|
- * This is the first bond device being attached to bridge. In order to enforce Linux
|
|
- * bond slave selection in bridge flows involving bond interfaces, we need to disable
|
|
- * fdb learning on this bridge master to allow flow based bridging.
|
|
- */
|
|
- if (nss_bridge_mgr_disable_fdb_learning(b_pvt) < 0) {
|
|
- return NOTIFY_BAD;
|
|
- }
|
|
-
|
|
- return NOTIFY_DONE;
|
|
-}
|
|
-
|
|
-/*
|
|
* nss_bridge_mgr_bond_master_join()
|
|
* Add a bond interface to bridge
|
|
*/
|
|
@@ -481,7 +447,28 @@ static int nss_bridge_mgr_bond_master_jo
|
|
}
|
|
}
|
|
|
|
- if (nss_bridge_mgr_bond_fdb_join(b_pvt) == NOTIFY_DONE) {
|
|
+ /*
|
|
+ * If already other bond devices are attached to bridge,
|
|
+ * only increment bond_slave_num,
|
|
+ */
|
|
+ spin_lock(&br_mgr_ctx.lock);
|
|
+ if (b_pvt->bond_slave_num) {
|
|
+ b_pvt->bond_slave_num++;
|
|
+ spin_unlock(&br_mgr_ctx.lock);
|
|
+ return NOTIFY_DONE;
|
|
+ }
|
|
+ spin_unlock(&br_mgr_ctx.lock);
|
|
+
|
|
+ /*
|
|
+ * This is the first bond device being attached to bridge. In order to enforce Linux
|
|
+ * bond slave selection in bridge flows involving bond interfaces, we need to disable
|
|
+ * fdb learning on this bridge master to allow flow based bridging.
|
|
+ */
|
|
+ if (!nss_bridge_mgr_disable_fdb_learning(b_pvt)) {
|
|
+ spin_lock(&br_mgr_ctx.lock);
|
|
+ b_pvt->bond_slave_num = 1;
|
|
+ spin_unlock(&br_mgr_ctx.lock);
|
|
+
|
|
return NOTIFY_DONE;
|
|
}
|
|
|
|
@@ -501,40 +488,6 @@ cleanup:
|
|
}
|
|
|
|
/*
|
|
- * nss_bridge_mgr_bond_fdb_leave()
|
|
- * Update FDB state when a bond interface leaving bridge.
|
|
- */
|
|
-static int nss_bridge_mgr_bond_fdb_leave(struct nss_bridge_pvt *b_pvt)
|
|
-{
|
|
-
|
|
- nss_bridge_mgr_assert(b_pvt->bond_slave_num == 0);
|
|
-
|
|
- /*
|
|
- * If more than one bond devices are attached to bridge,
|
|
- * only decrement the bond_slave_num
|
|
- */
|
|
- spin_lock(&br_mgr_ctx.lock);
|
|
- if (b_pvt->bond_slave_num > 1) {
|
|
- b_pvt->bond_slave_num--;
|
|
- spin_unlock(&br_mgr_ctx.lock);
|
|
- return NOTIFY_DONE;
|
|
- }
|
|
- b_pvt->bond_slave_num = 0;
|
|
- spin_unlock(&br_mgr_ctx.lock);
|
|
-
|
|
- /*
|
|
- * The last bond interface is removed from bridge, we can switch back to FDB
|
|
- * learning mode.
|
|
- */
|
|
- if (nss_bridge_mgr_enable_fdb_learning(b_pvt) < 0) {
|
|
- return NOTIFY_BAD;
|
|
- }
|
|
-
|
|
- return NOTIFY_DONE;
|
|
-}
|
|
-
|
|
-
|
|
-/*
|
|
* nss_bridge_mgr_bond_master_leave()
|
|
* Remove a bond interface from bridge
|
|
*/
|
|
@@ -563,7 +516,27 @@ static int nss_bridge_mgr_bond_master_le
|
|
}
|
|
}
|
|
|
|
- if (nss_bridge_mgr_bond_fdb_leave(b_pvt) == NOTIFY_DONE) {
|
|
+ /*
|
|
+ * If more than one bond devices are attached to bridge,
|
|
+ * only decrement the bond_slave_num
|
|
+ */
|
|
+ spin_lock(&br_mgr_ctx.lock);
|
|
+ if (b_pvt->bond_slave_num > 1) {
|
|
+ b_pvt->bond_slave_num--;
|
|
+ spin_unlock(&br_mgr_ctx.lock);
|
|
+ return NOTIFY_DONE;
|
|
+ }
|
|
+ spin_unlock(&br_mgr_ctx.lock);
|
|
+
|
|
+ /*
|
|
+ * The last bond interface is removed from bridge, we can switch back to FDB
|
|
+ * learning mode.
|
|
+ */
|
|
+ if (!nss_bridge_mgr_enable_fdb_learning(b_pvt)) {
|
|
+ spin_lock(&br_mgr_ctx.lock);
|
|
+ b_pvt->bond_slave_num = 0;
|
|
+ spin_unlock(&br_mgr_ctx.lock);
|
|
+
|
|
return NOTIFY_DONE;
|
|
}
|
|
|
|
@@ -782,6 +755,10 @@ int nss_bridge_mgr_join_bridge(struct ne
|
|
* This is done by not sending join message to the bridge in NSS.
|
|
*/
|
|
if (br_mgr_ctx.wan_if_num == ifnum) {
|
|
+ if (!nss_bridge_mgr_l2_exception_acl_enable()) {
|
|
+ nss_bridge_mgr_warn("%px: failed to enable ACL\n", br);
|
|
+ return -EIO;
|
|
+ }
|
|
br->wan_if_enabled = true;
|
|
br->wan_if_num = ifnum;
|
|
nss_bridge_mgr_info("if_num %d is added as WAN interface \n", ifnum);
|
|
@@ -830,10 +807,9 @@ int nss_bridge_mgr_join_bridge(struct ne
|
|
}
|
|
|
|
/*
|
|
- * Update FDB state of the bridge. No need to add individual interfaces of bond to the bridge.
|
|
- * VLAN interface verifies that all interfaces are physical so, no need to verify again.
|
|
+ * Add the bond_master to bridge.
|
|
*/
|
|
- if (nss_bridge_mgr_bond_fdb_join(br) != NOTIFY_DONE) {
|
|
+ if (nss_bridge_mgr_bond_master_join(real_dev, br) != NOTIFY_DONE) {
|
|
nss_bridge_mgr_warn("%px: Slaves of bond interface %s join bridge failed\n", br, real_dev->name);
|
|
nss_bridge_tx_leave_msg(br->ifnum, dev);
|
|
nss_vlan_mgr_leave_bridge(dev, br->vsi);
|
|
@@ -888,6 +864,7 @@ int nss_bridge_mgr_leave_bridge(struct n
|
|
* Hence a leave message should also be avaoided.
|
|
*/
|
|
if ((br->wan_if_enabled) && (br->wan_if_num == ifnum)) {
|
|
+ nss_bridge_mgr_l2_exception_acl_disable();
|
|
br->wan_if_enabled = false;
|
|
br->wan_if_num = -1;
|
|
nss_bridge_mgr_info("if_num %d is added as WAN interface\n", ifnum);
|
|
@@ -933,10 +910,9 @@ int nss_bridge_mgr_leave_bridge(struct n
|
|
}
|
|
|
|
/*
|
|
- * Update FDB state of the bridge. No need to add individual interfaces of bond to the bridge.
|
|
- * VLAN interface verifies that all interfaces are physical so, no need to verify again.
|
|
+ * Remove the bond_master from bridge.
|
|
*/
|
|
- if (nss_bridge_mgr_bond_fdb_leave(br) != NOTIFY_DONE) {
|
|
+ if (nss_bridge_mgr_bond_master_leave(real_dev, br) != NOTIFY_DONE) {
|
|
nss_bridge_mgr_warn("%px: Slaves of bond interface %s leave bridge failed\n", br, real_dev->name);
|
|
nss_vlan_mgr_join_bridge(dev, br->vsi);
|
|
nss_bridge_tx_join_msg(br->ifnum, dev);
|
|
@@ -1046,45 +1022,44 @@ int nss_bridge_mgr_register_br(struct ne
|
|
|
|
b_pvt->dev = dev;
|
|
|
|
-#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
|
|
- err = ppe_vsi_alloc(NSS_BRIDGE_MGR_SWITCH_ID, &vsi_id);
|
|
- if (err) {
|
|
- nss_bridge_mgr_warn("%px: failed to alloc bridge vsi, error = %d\n", b_pvt, err);
|
|
- goto fail;
|
|
- }
|
|
-
|
|
- b_pvt->vsi = vsi_id;
|
|
-#endif
|
|
-
|
|
ifnum = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE);
|
|
if (ifnum < 0) {
|
|
nss_bridge_mgr_warn("%px: failed to alloc bridge di\n", b_pvt);
|
|
- goto fail_1;
|
|
+ nss_bridge_mgr_delete_instance(b_pvt);
|
|
+ return -EFAULT;
|
|
}
|
|
|
|
if (!nss_bridge_register(ifnum, dev, NULL, NULL, 0, b_pvt)) {
|
|
nss_bridge_mgr_warn("%px: failed to register bridge di to NSS\n", b_pvt);
|
|
- goto fail_2;
|
|
+ goto fail;
|
|
}
|
|
|
|
#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
|
|
+ err = ppe_vsi_alloc(NSS_BRIDGE_MGR_SWITCH_ID, &vsi_id);
|
|
+ if (err) {
|
|
+ nss_bridge_mgr_warn("%px: failed to alloc bridge vsi, error = %d\n", b_pvt, err);
|
|
+ goto fail_1;
|
|
+ }
|
|
+
|
|
+ b_pvt->vsi = vsi_id;
|
|
+
|
|
err = nss_bridge_tx_vsi_assign_msg(ifnum, vsi_id);
|
|
if (err != NSS_TX_SUCCESS) {
|
|
nss_bridge_mgr_warn("%px: failed to assign vsi msg, error = %d\n", b_pvt, err);
|
|
- goto fail_3;
|
|
+ goto fail_2;
|
|
}
|
|
#endif
|
|
|
|
err = nss_bridge_tx_set_mac_addr_msg(ifnum, dev->dev_addr);
|
|
if (err != NSS_TX_SUCCESS) {
|
|
nss_bridge_mgr_warn("%px: failed to set mac_addr msg, error = %d\n", b_pvt, err);
|
|
- goto fail_4;
|
|
+ goto fail_3;
|
|
}
|
|
|
|
err = nss_bridge_tx_set_mtu_msg(ifnum, dev->mtu);
|
|
if (err != NSS_TX_SUCCESS) {
|
|
nss_bridge_mgr_warn("%px: failed to set mtu msg, error = %d\n", b_pvt, err);
|
|
- goto fail_4;
|
|
+ goto fail_3;
|
|
}
|
|
|
|
/*
|
|
@@ -1092,8 +1067,10 @@ int nss_bridge_mgr_register_br(struct ne
|
|
*/
|
|
b_pvt->ifnum = ifnum;
|
|
b_pvt->mtu = dev->mtu;
|
|
+#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
|
|
b_pvt->wan_if_num = -1;
|
|
b_pvt->wan_if_enabled = false;
|
|
+#endif
|
|
ether_addr_copy(b_pvt->dev_addr, dev->dev_addr);
|
|
spin_lock(&br_mgr_ctx.lock);
|
|
list_add(&b_pvt->list, &br_mgr_ctx.list);
|
|
@@ -1110,29 +1087,25 @@ int nss_bridge_mgr_register_br(struct ne
|
|
#endif
|
|
return 0;
|
|
|
|
-fail_4:
|
|
+fail_3:
|
|
#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
|
|
if (nss_bridge_tx_vsi_unassign_msg(ifnum, vsi_id) != NSS_TX_SUCCESS) {
|
|
nss_bridge_mgr_warn("%px: failed to unassign vsi\n", b_pvt);
|
|
}
|
|
-fail_3:
|
|
-#endif
|
|
|
|
+fail_2:
|
|
+ ppe_vsi_free(NSS_BRIDGE_MGR_SWITCH_ID, vsi_id);
|
|
+
|
|
+fail_1:
|
|
+#endif
|
|
nss_bridge_unregister(ifnum);
|
|
|
|
-fail_2:
|
|
+fail:
|
|
if (nss_dynamic_interface_dealloc_node(ifnum, NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE) != NSS_TX_SUCCESS) {
|
|
nss_bridge_mgr_warn("%px: failed to dealloc bridge di\n", b_pvt);
|
|
}
|
|
|
|
-fail_1:
|
|
-#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
|
|
- ppe_vsi_free(NSS_BRIDGE_MGR_SWITCH_ID, vsi_id);
|
|
-fail:
|
|
-#endif
|
|
-
|
|
nss_bridge_mgr_delete_instance(b_pvt);
|
|
-
|
|
return -EFAULT;
|
|
}
|
|
|
|
@@ -1159,6 +1132,7 @@ static int nss_bridge_mgr_bond_slave_cha
|
|
return NOTIFY_DONE;
|
|
}
|
|
|
|
+#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
|
|
/*
|
|
* Add or remove the slave based based on linking event
|
|
*/
|
|
@@ -1173,6 +1147,7 @@ static int nss_bridge_mgr_bond_slave_cha
|
|
cu_info->upper_dev->name, master->name);
|
|
}
|
|
}
|
|
+#endif
|
|
|
|
return NOTIFY_DONE;
|
|
}
|
|
@@ -1200,7 +1175,7 @@ static int nss_bridge_mgr_changemtu_even
|
|
|
|
if (nss_bridge_tx_set_mtu_msg(b_pvt->ifnum, dev->mtu) != NSS_TX_SUCCESS) {
|
|
nss_bridge_mgr_warn("%px: Failed to send change MTU message to NSS\n", b_pvt);
|
|
- return NOTIFY_DONE;
|
|
+ return NOTIFY_BAD;
|
|
}
|
|
|
|
spin_lock(&br_mgr_ctx.lock);
|
|
@@ -1234,7 +1209,7 @@ static int nss_bridge_mgr_changeaddr_eve
|
|
|
|
if (nss_bridge_tx_set_mac_addr_msg(b_pvt->ifnum, dev->dev_addr) != NSS_TX_SUCCESS) {
|
|
nss_bridge_mgr_warn("%px: Failed to send change MAC address message to NSS\n", b_pvt);
|
|
- return NOTIFY_DONE;
|
|
+ return NOTIFY_BAD;
|
|
}
|
|
|
|
spin_lock(&br_mgr_ctx.lock);
|
|
@@ -1294,6 +1269,7 @@ static int nss_bridge_mgr_changeupper_ev
|
|
nss_bridge_mgr_trace("%px: Interface %s joining bridge %s\n", b_pvt, dev->name, master_dev->name);
|
|
if (nss_bridge_mgr_join_bridge(dev, b_pvt)) {
|
|
nss_bridge_mgr_warn("%px: Interface %s failed to join bridge %s\n", b_pvt, dev->name, master_dev->name);
|
|
+ return NOTIFY_BAD;
|
|
}
|
|
|
|
return NOTIFY_DONE;
|
|
@@ -1302,6 +1278,7 @@ static int nss_bridge_mgr_changeupper_ev
|
|
nss_bridge_mgr_trace("%px: Interface %s leaving bridge %s\n", b_pvt, dev->name, master_dev->name);
|
|
if (nss_bridge_mgr_leave_bridge(dev, b_pvt)) {
|
|
nss_bridge_mgr_warn("%px: Interface %s failed to leave bridge %s\n", b_pvt, dev->name, master_dev->name);
|
|
+ return NOTIFY_BAD;
|
|
}
|
|
|
|
return NOTIFY_DONE;
|
|
@@ -1627,14 +1604,6 @@ int __init nss_bridge_mgr_init_module(vo
|
|
br_mgr_ctx.wan_if_num = -1;
|
|
br_fdb_update_register_notify(&nss_bridge_mgr_fdb_update_notifier);
|
|
br_mgr_ctx.nss_bridge_mgr_header = register_sysctl_table(nss_bridge_mgr_root_dir);
|
|
-
|
|
- /*
|
|
- * Enable ACL rule to enable L2 exception. This is needed if PPE Virtual ports is added to bridge.
|
|
- * It is assumed that VP is using flow based bridging, hence L2 exceptions will need to be enabled on PPE bridge.
|
|
- */
|
|
- if (!nss_bridge_mgr_l2_exception_acl_enable()) {
|
|
- nss_bridge_mgr_warn("Failed to enable ACL\n");
|
|
- }
|
|
#endif
|
|
#if defined (NSS_BRIDGE_MGR_OVS_ENABLE)
|
|
nss_bridge_mgr_ovs_init();
|
|
@@ -1656,12 +1625,6 @@ void __exit nss_bridge_mgr_exit_module(v
|
|
if (br_mgr_ctx.nss_bridge_mgr_header) {
|
|
unregister_sysctl_table(br_mgr_ctx.nss_bridge_mgr_header);
|
|
}
|
|
-
|
|
- /*
|
|
- * Disable the PPE L2 exceptions which were enabled during module init for PPE virtual ports.
|
|
- */
|
|
- nss_bridge_mgr_l2_exception_acl_disable();
|
|
-
|
|
#endif
|
|
#if defined (NSS_BRIDGE_MGR_OVS_ENABLE)
|
|
nss_bridge_mgr_ovs_exit();
|
|
--- a/capwapmgr/Makefile
|
|
+++ b/capwapmgr/Makefile
|
|
@@ -14,4 +14,4 @@ qca-nss-capwapmgr-objs := nss_capwapmgr.
|
|
ccflags-y += -DNSS_CAPWAPMGR_DEBUG_LEVEL=6
|
|
|
|
ccflags-y += $(NSS_CCFLAGS) -DNSS_DEBUG_LEVEL=0 -DNSS_PKT_STATS_ENABLED=0
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
--- a/capwapmgr/nss_capwapmgr.c
|
|
+++ b/capwapmgr/nss_capwapmgr.c
|
|
@@ -1,12 +1,9 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
|
|
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
|
- *
|
|
+ * Copyright (c) 2014-2020, 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.
|
|
- *
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
@@ -95,16 +92,17 @@
|
|
#define NSS_CAPWAPMGR_BIND_BITMAP 0x7E
|
|
|
|
/*
|
|
- * We need 4 ACL rules - 2 rules for each v4 and v6 classification.
|
|
+ * The number of rules supported by a list is 4. Since we need 2 rules for every
|
|
+ * dscp classification (v4 and v6). We set this value to 2.
|
|
*/
|
|
-#define NSS_CAPWAPMGR_ACL_RULES_PER_LIST 4
|
|
+#define NSS_CAPWAPMGR_ACL_RULES_PER_LIST 2
|
|
|
|
/*
|
|
- * We currently have list-id 60 reserved for this purpose.
|
|
+ * We currently have list-id 60 and 61 reserved for this purpose.
|
|
* TODO: Find a better approach to reserve list-id.
|
|
*/
|
|
#define NSS_CAPWAPMGR_ACL_LIST_START 60
|
|
-#define NSS_CAPWAPMGR_ACL_LIST_CNT 1
|
|
+#define NSS_CAPWAPMGR_ACL_LIST_CNT 2
|
|
|
|
#define NSS_CAPWAPMGR_NORMAL_FRAME_MTU 1500
|
|
|
|
@@ -234,7 +232,7 @@ static void nss_capwapmgr_decongestion_c
|
|
|
|
/*
|
|
* nss_capwapmgr_start_xmit()
|
|
- * Transmit's skb to NSS FW over CAPWAP if_num_inner.
|
|
+ * Transmit's skb to NSS FW over CAPWAP if_num.
|
|
*
|
|
* Please make sure to leave headroom of NSS_CAPWAP_HEADROOM with every
|
|
* packet so that NSS can encap eth,vlan,ip,udp,capwap headers.
|
|
@@ -246,7 +244,7 @@ static netdev_tx_t nss_capwapmgr_start_x
|
|
struct net_device_stats *stats = &dev->stats;
|
|
struct nss_capwapmgr_priv *priv;
|
|
struct nss_capwap_metaheader *pre;
|
|
- uint32_t if_num_inner;
|
|
+ uint32_t if_num;
|
|
nss_tx_status_t status;
|
|
|
|
priv = netdev_priv(dev);
|
|
@@ -259,9 +257,9 @@ static netdev_tx_t nss_capwapmgr_start_x
|
|
return NETDEV_TX_OK;
|
|
}
|
|
|
|
- if_num_inner = priv->tunnel[pre->tunnel_id].if_num_inner;
|
|
- if (unlikely(if_num_inner == -1)) {
|
|
- nss_capwapmgr_warn("%px: (CAPWAP packet) if_num_inner in the tunnel not set pre->tunnel_id %d\n", dev,
|
|
+ if_num = priv->tunnel[pre->tunnel_id].if_num;
|
|
+ if (unlikely(if_num == 0)) {
|
|
+ nss_capwapmgr_warn("%px: (CAPWAP packet) if_num in the tunnel not set pre->tunnel_id %d\n", dev,
|
|
pre->tunnel_id);
|
|
kfree_skb(skb);
|
|
stats->tx_dropped++;
|
|
@@ -277,7 +275,7 @@ static netdev_tx_t nss_capwapmgr_start_x
|
|
*/
|
|
skb_set_queue_mapping(skb, pre->flow_id & 0x1);
|
|
|
|
- status = nss_capwap_tx_buf(priv->nss_ctx, skb, if_num_inner);
|
|
+ status = nss_capwap_tx_buf(priv->nss_ctx, skb, if_num);
|
|
if (unlikely(status != NSS_TX_SUCCESS)) {
|
|
if (status == NSS_TX_FAILURE_QUEUE) {
|
|
nss_capwapmgr_warn("%px: netdev :%px queue is full", dev, dev);
|
|
@@ -302,7 +300,7 @@ static void nss_capwapmgr_fill_up_stats(
|
|
stats->rx_dropped += tstats->pnode_stats.rx_dropped;
|
|
|
|
/* rx_fifo_errors will appear as rx overruns in ifconfig */
|
|
- stats->rx_fifo_errors += (tstats->rx_n2h_drops + tstats->rx_n2h_queue_full_drops);
|
|
+ stats->rx_fifo_errors += (tstats->rx_queue_full_drops + tstats->rx_n2h_queue_full_drops);
|
|
stats->rx_errors += (tstats->rx_mem_failure_drops + tstats->rx_oversize_drops + tstats->rx_frag_timeout_drops);
|
|
stats->rx_bytes += tstats->pnode_stats.rx_bytes;
|
|
|
|
@@ -370,6 +368,20 @@ static void nss_capwapmgr_dev_tunnel_sta
|
|
}
|
|
#endif
|
|
|
|
+/**
|
|
+ * nss_capwapmgr_change_mtu - set new MTU size
|
|
+ * @dev: network device
|
|
+ * @new_mtu: new Maximum Transfer Unit
|
|
+ *
|
|
+ * Allow changing MTU size. Needs to be overridden for devices
|
|
+ * supporting jumbo frames.
|
|
+ */
|
|
+int nss_capwapmgr_change_mtu(struct net_device *dev, int new_mtu)
|
|
+{
|
|
+ dev->mtu = new_mtu;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/*
|
|
* nss_capwapmgr_netdev_ops
|
|
* Netdev operations.
|
|
@@ -379,7 +391,7 @@ static const struct net_device_ops nss_c
|
|
.ndo_stop = nss_capwapmgr_close,
|
|
.ndo_start_xmit = nss_capwapmgr_start_xmit,
|
|
.ndo_set_mac_address = eth_mac_addr,
|
|
- .ndo_change_mtu = eth_change_mtu,
|
|
+ .ndo_change_mtu = nss_capwapmgr_change_mtu,
|
|
.ndo_get_stats64 = nss_capwapmgr_dev_tunnel_stats,
|
|
};
|
|
|
|
@@ -559,12 +571,15 @@ static struct nss_capwapmgr_tunnel *nss_
|
|
return NULL;
|
|
}
|
|
|
|
+ dev_hold(dev);
|
|
priv = netdev_priv(dev);
|
|
t = &priv->tunnel[tunnel_id];
|
|
- if ( (t->if_num_inner == -1) || (t->if_num_outer == -1) ) {
|
|
+ if (t->if_num == 0) {
|
|
+ dev_put(dev);
|
|
return NULL;
|
|
}
|
|
|
|
+ dev_put(dev);
|
|
return t;
|
|
}
|
|
|
|
@@ -607,10 +622,6 @@ struct net_device *nss_capwapmgr_netdev_
|
|
goto fail1;
|
|
}
|
|
memset(priv->tunnel, 0, sizeof(struct nss_capwapmgr_tunnel) * NSS_CAPWAPMGR_MAX_TUNNELS);
|
|
- for (i = 0; i < NSS_CAPWAPMGR_MAX_TUNNELS; i++) {
|
|
- priv->tunnel[i].if_num_inner = -1;
|
|
- priv->tunnel[i].if_num_outer = -1;
|
|
- }
|
|
|
|
priv->resp = kmalloc(sizeof(struct nss_capwapmgr_response) * NSS_MAX_DYNAMIC_INTERFACES, GFP_ATOMIC);
|
|
if (!priv->resp) {
|
|
@@ -870,10 +881,6 @@ static nss_tx_status_t nss_capwapmgr_cre
|
|
memcpy(nircm->conn_rule.return_mac, unic->dest_mac, 6);
|
|
}
|
|
|
|
- nircm->valid_flags |= NSS_IPV4_RULE_CREATE_SRC_MAC_VALID;
|
|
- nircm->src_mac_rule.mac_valid_flags |=NSS_IPV4_SRC_MAC_FLOW_VALID;
|
|
- memcpy(nircm->src_mac_rule.flow_src_mac, nircm->conn_rule.return_mac, 6);
|
|
-
|
|
/*
|
|
* Copy over the DSCP rule parameters
|
|
*/
|
|
@@ -1009,10 +1016,6 @@ static nss_tx_status_t nss_capwapmgr_cre
|
|
memcpy(nircm->conn_rule.return_mac, unic->dest_mac, 6);
|
|
nircm->valid_flags |= NSS_IPV6_RULE_CREATE_CONN_VALID;
|
|
|
|
- nircm->valid_flags |= NSS_IPV6_RULE_CREATE_SRC_MAC_VALID;
|
|
- nircm->src_mac_rule.mac_valid_flags |=NSS_IPV6_SRC_MAC_FLOW_VALID;
|
|
- memcpy(nircm->src_mac_rule.flow_src_mac, nircm->conn_rule.return_mac, 6);
|
|
-
|
|
/*
|
|
* Copy over the DSCP rule parameters
|
|
*/
|
|
@@ -1294,85 +1297,23 @@ static nss_capwapmgr_status_t nss_capwap
|
|
}
|
|
|
|
/*
|
|
- * nss_capwapmgr_tx_msg_enable_tunnel()
|
|
- * Common function to send CAPWAP tunnel enable msg
|
|
- */
|
|
-static nss_tx_status_t nss_capwapmgr_tx_msg_enable_tunnel(struct nss_ctx_instance *ctx, struct net_device *dev, uint32_t if_num, uint32_t sibling_if_num)
|
|
-{
|
|
- struct nss_capwap_msg capwapmsg;
|
|
- nss_tx_status_t status;
|
|
-
|
|
- /*
|
|
- * Prepare the tunnel configuration parameter to send to NSS FW
|
|
- */
|
|
- memset(&capwapmsg, 0, sizeof(struct nss_capwap_msg));
|
|
- capwapmsg.msg.enable_tunnel.sibling_if_num = sibling_if_num;
|
|
-
|
|
- /*
|
|
- * Send CAPWAP data tunnel command to NSS
|
|
- */
|
|
- nss_capwap_msg_init(&capwapmsg, if_num, NSS_CAPWAP_MSG_TYPE_ENABLE_TUNNEL, sizeof(struct nss_capwap_enable_tunnel_msg), nss_capwapmgr_msg_event_receive, dev);
|
|
-
|
|
- status = nss_capwapmgr_tx_msg_sync(ctx, dev, &capwapmsg);
|
|
- if (status != NSS_TX_SUCCESS) {
|
|
- nss_capwapmgr_warn("%px: ctx: CMD: %d Tunnel error : %d \n", ctx, NSS_CAPWAP_MSG_TYPE_ENABLE_TUNNEL, status);
|
|
- }
|
|
-
|
|
- return status;
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_capwapmgr_tunnel_action()
|
|
- * Common function for CAPWAP tunnel operation messages without
|
|
- * any message data structures.
|
|
- */
|
|
-static nss_tx_status_t nss_capwapmgr_tunnel_action(struct nss_ctx_instance *ctx, struct net_device *dev, uint32_t if_num, nss_capwap_msg_type_t cmd)
|
|
-{
|
|
- struct nss_capwap_msg capwapmsg;
|
|
- nss_tx_status_t status;
|
|
-
|
|
- /*
|
|
- * Prepare the tunnel configuration parameter to send to NSS FW
|
|
- */
|
|
- memset(&capwapmsg, 0, sizeof(struct nss_capwap_msg));
|
|
-
|
|
- /*
|
|
- * Send CAPWAP data tunnel command to NSS
|
|
- */
|
|
- nss_capwap_msg_init(&capwapmsg, if_num, cmd, 0, nss_capwapmgr_msg_event_receive, dev);
|
|
-
|
|
- status = nss_capwapmgr_tx_msg_sync(ctx, dev, &capwapmsg);
|
|
- if (status != NSS_TX_SUCCESS) {
|
|
- nss_capwapmgr_warn("%px: ctx: CMD: %d Tunnel error : %d \n", ctx, cmd, status);
|
|
- }
|
|
-
|
|
- return status;
|
|
-}
|
|
-
|
|
-/*
|
|
* nss_capwapmgr_get_dtls_netdev()
|
|
* API for getting the dtls netdev associated to the capwap tunnel
|
|
- *
|
|
- * The caller is expected to do a dev_put() to release the reference.
|
|
*/
|
|
struct net_device *nss_capwapmgr_get_dtls_netdev(struct net_device *capwap_dev, uint8_t tunnel_id)
|
|
{
|
|
struct nss_capwapmgr_tunnel *t;
|
|
struct net_device *dtls_dev;
|
|
|
|
- dev_hold(capwap_dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(capwap_dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_warn("%px: can't find tunnel: %d\n", capwap_dev, tunnel_id);
|
|
- dev_put(capwap_dev);
|
|
return NULL;
|
|
}
|
|
|
|
dtls_dev = t->dtls_dev;
|
|
- dev_hold(dtls_dev);
|
|
-
|
|
- dev_put(capwap_dev);
|
|
|
|
+ dev_hold(dtls_dev);
|
|
return dtls_dev;
|
|
}
|
|
EXPORT_SYMBOL(nss_capwapmgr_get_dtls_netdev);
|
|
@@ -1394,16 +1335,15 @@ nss_capwapmgr_status_t nss_capwapmgr_upd
|
|
return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_warn("%px: can't find tunnel: %d\n", dev, tunnel_id);
|
|
- dev_put(dev);
|
|
return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
+ dev_hold(dev);
|
|
priv = netdev_priv(dev);
|
|
- nss_capwapmgr_info("%px: %d: tunnel update MTU is being called\n", dev, t->if_num_inner);
|
|
+ nss_capwapmgr_info("%px: %d: tunnel update MTU is being called\n", dev, t->if_num);
|
|
|
|
/*
|
|
* Prepare the tunnel configuration parameter to send to NSS FW
|
|
@@ -1413,7 +1353,7 @@ nss_capwapmgr_status_t nss_capwapmgr_upd
|
|
/*
|
|
* Send CAPWAP data tunnel command to NSS
|
|
*/
|
|
- nss_capwap_msg_init(&capwapmsg, t->if_num_inner, NSS_CAPWAP_MSG_TYPE_UPDATE_PATH_MTU,
|
|
+ nss_capwap_msg_init(&capwapmsg, t->if_num, NSS_CAPWAP_MSG_TYPE_UPDATE_PATH_MTU,
|
|
sizeof(struct nss_capwap_path_mtu_msg), nss_capwapmgr_msg_event_receive, dev);
|
|
capwapmsg.msg.mtu.path_mtu = htonl(mtu);
|
|
status = nss_capwapmgr_tx_msg_sync(priv->nss_ctx, dev, &capwapmsg);
|
|
@@ -1473,22 +1413,20 @@ nss_capwapmgr_status_t nss_capwapmgr_upd
|
|
{
|
|
struct nss_capwapmgr_priv *priv;
|
|
struct nss_capwapmgr_tunnel *t;
|
|
+ nss_capwapmgr_status_t status;
|
|
nss_tx_status_t nss_status;
|
|
- nss_capwapmgr_status_t status = NSS_CAPWAPMGR_SUCCESS;
|
|
struct nss_ipv6_create *v6;
|
|
uint8_t mac_addr_old[ETH_ALEN];
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_warn("%px: can't find tunnel: %d\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
-
|
|
+ dev_hold(dev);
|
|
priv = netdev_priv(dev);
|
|
- nss_capwapmgr_info("%px: %d: tunnel update mac Addr is being called\n", dev, tunnel_id);
|
|
+ nss_capwapmgr_info("%px: %d: tunnel update mac Addr is being called\n", dev, t->if_num);
|
|
|
|
/*
|
|
* Update the IPv4/IPv6 rule with the new destination mac address for flow and return.
|
|
@@ -1505,10 +1443,11 @@ nss_capwapmgr_status_t nss_capwapmgr_upd
|
|
if (nss_status != NSS_TX_SUCCESS) {
|
|
nss_capwapmgr_warn("%px: Update Destination Mac for tunnel error : %d \n", dev, nss_status);
|
|
memcpy(t->ip_rule.v4.src_mac, mac_addr_old, ETH_ALEN);
|
|
- status = NSS_CAPWAPMGR_FAILURE_IP_RULE;
|
|
}
|
|
|
|
- goto done;
|
|
+ dev_put(dev);
|
|
+ return status;
|
|
+
|
|
}
|
|
|
|
v6 = &t->ip_rule.v6;
|
|
@@ -1519,10 +1458,10 @@ nss_capwapmgr_status_t nss_capwapmgr_upd
|
|
if (nss_status != NSS_TX_SUCCESS) {
|
|
nss_capwapmgr_warn("%px: Update Destination Mac for tunnel error : %d \n", dev, nss_status);
|
|
memcpy(t->ip_rule.v6.src_mac, mac_addr_old, ETH_ALEN);
|
|
- status = NSS_CAPWAPMGR_FAILURE_IP_RULE;
|
|
+ dev_put(dev);
|
|
+ return NSS_CAPWAPMGR_FAILURE_IP_RULE;
|
|
}
|
|
|
|
-done:
|
|
dev_put(dev);
|
|
return status;
|
|
}
|
|
@@ -1532,24 +1471,23 @@ EXPORT_SYMBOL(nss_capwapmgr_update_dest_
|
|
* nss_capwapmgr_update_src_interface()
|
|
* API for updating Source Interface
|
|
*/
|
|
-nss_capwapmgr_status_t nss_capwapmgr_update_src_interface(struct net_device *dev, uint8_t tunnel_id, uint32_t src_interface_num)
|
|
+nss_capwapmgr_status_t nss_capwapmgr_update_src_interface(struct net_device *dev, uint8_t tunnel_id, int32_t src_interface_num)
|
|
{
|
|
struct nss_capwapmgr_priv *priv;
|
|
struct nss_capwapmgr_tunnel *t;
|
|
+ nss_capwapmgr_status_t status;
|
|
nss_tx_status_t nss_status;
|
|
uint32_t outer_trustsec_enabled, dtls_enabled, forward_if_num, src_interface_num_temp;
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_warn("%px: can't find tunnel: %d\n", dev, tunnel_id);
|
|
- dev_put(dev);
|
|
return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
-
|
|
+ dev_hold(dev);
|
|
priv = netdev_priv(dev);
|
|
- nss_capwapmgr_info("%px: %d: tunnel update source interface is being called\n", dev, tunnel_id);
|
|
+ nss_capwapmgr_info("%px: %d: tunnel update source interface is being called\n", dev, t->if_num);
|
|
outer_trustsec_enabled = t->capwap_rule.enabled_features & NSS_CAPWAPMGR_FEATURE_OUTER_TRUSTSEC_ENABLED;
|
|
dtls_enabled = t->capwap_rule.enabled_features & NSS_CAPWAPMGR_FEATURE_DTLS_ENABLED;
|
|
|
|
@@ -1558,7 +1496,7 @@ nss_capwapmgr_status_t nss_capwapmgr_upd
|
|
*/
|
|
if (outer_trustsec_enabled) {
|
|
if (!dtls_enabled) {
|
|
- forward_if_num = nss_capwap_ifnum_with_core_id(t->if_num_outer);
|
|
+ forward_if_num = nss_capwap_ifnum_with_core_id(t->if_num);
|
|
} else {
|
|
forward_if_num = nss_dtlsmgr_get_interface(t->dtls_dev, NSS_DTLSMGR_INTERFACE_TYPE_OUTER);
|
|
}
|
|
@@ -1566,7 +1504,6 @@ nss_capwapmgr_status_t nss_capwapmgr_upd
|
|
nss_status = nss_trustsec_tx_update_nexthop(forward_if_num, src_interface_num, t->capwap_rule.outer_sgt_value);
|
|
if (nss_status != NSS_TX_SUCCESS) {
|
|
nss_capwapmgr_warn("%px: unconfigure trustsec_tx failed\n", dev);
|
|
- dev_put(dev);
|
|
return NSS_CAPWAPMGR_FAILURE_UNCONFIGURE_TRUSTSEC_TX;
|
|
}
|
|
|
|
@@ -1575,7 +1512,6 @@ nss_capwapmgr_status_t nss_capwapmgr_upd
|
|
} else {
|
|
t->ip_rule.v6.src_interface_num = src_interface_num;
|
|
}
|
|
- dev_put(dev);
|
|
return NSS_CAPWAPMGR_SUCCESS;
|
|
}
|
|
|
|
@@ -1659,8 +1595,7 @@ nss_capwapmgr_status_t nss_capwapmgr_upd
|
|
}
|
|
}
|
|
t->tunnel_state |= NSS_CAPWAPMGR_TUNNEL_STATE_IPRULE_CONFIGURED;
|
|
- dev_put(dev);
|
|
- return NSS_CAPWAPMGR_SUCCESS;
|
|
+ return status;
|
|
}
|
|
EXPORT_SYMBOL(nss_capwapmgr_update_src_interface);
|
|
|
|
@@ -1997,7 +1932,7 @@ EXPORT_SYMBOL(nss_capwapmgr_dscp_rule_cr
|
|
nss_capwapmgr_status_t nss_capwapmgr_configure_dtls(struct net_device *dev, uint8_t tunnel_id, uint8_t enable_dtls, struct nss_dtlsmgr_config *in_data)
|
|
{
|
|
struct nss_capwapmgr_priv *priv;
|
|
- struct nss_capwap_msg capwapmsg_inner, capwapmsg_outer;
|
|
+ struct nss_capwap_msg capwapmsg;
|
|
struct nss_capwapmgr_tunnel *t;
|
|
struct nss_ipv4_destroy v4;
|
|
struct nss_ipv6_destroy v6;
|
|
@@ -2005,11 +1940,9 @@ nss_capwapmgr_status_t nss_capwapmgr_con
|
|
nss_capwapmgr_status_t status;
|
|
uint32_t ip_if_num, dtls_enabled, outer_trustsec_enabled;
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_warn("%px: can't find tunnel: %d\n", dev, tunnel_id);
|
|
- dev_put(dev);
|
|
return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
@@ -2017,7 +1950,6 @@ nss_capwapmgr_status_t nss_capwapmgr_con
|
|
dtls_enabled = t->capwap_rule.enabled_features & NSS_CAPWAPMGR_FEATURE_DTLS_ENABLED;
|
|
if ((enable_dtls && dtls_enabled) || (!enable_dtls && !dtls_enabled)) {
|
|
nss_capwapmgr_warn("%px: nothing changed for tunnel: %d\n", dev, tunnel_id);
|
|
- dev_put(dev);
|
|
return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
@@ -2027,31 +1959,23 @@ nss_capwapmgr_status_t nss_capwapmgr_con
|
|
*/
|
|
if (t->tunnel_state & NSS_CAPWAPMGR_TUNNEL_STATE_ENABLED) {
|
|
nss_capwapmgr_warn("%px: tunnel %d is already enabled\n", dev, tunnel_id);
|
|
- dev_put(dev);
|
|
return NSS_CAPWAPMGR_FAILURE_TUNNEL_ENABLED;
|
|
}
|
|
|
|
/*
|
|
* Prepare DTLS configure message
|
|
*/
|
|
- memset(&capwapmsg_inner, 0, sizeof(struct nss_capwap_msg));
|
|
- nss_capwap_msg_init(&capwapmsg_inner, t->if_num_inner, NSS_CAPWAP_MSG_TYPE_DTLS,
|
|
- sizeof(struct nss_capwap_dtls_msg), nss_capwapmgr_msg_event_receive, dev);
|
|
-
|
|
- memset(&capwapmsg_outer, 0, sizeof(struct nss_capwap_msg));
|
|
- nss_capwap_msg_init(&capwapmsg_outer, t->if_num_outer, NSS_CAPWAP_MSG_TYPE_DTLS,
|
|
+ memset(&capwapmsg, 0, sizeof(struct nss_capwap_msg));
|
|
+ nss_capwap_msg_init(&capwapmsg, t->if_num, NSS_CAPWAP_MSG_TYPE_DTLS,
|
|
sizeof(struct nss_capwap_dtls_msg), nss_capwapmgr_msg_event_receive, dev);
|
|
|
|
-
|
|
if (!enable_dtls) {
|
|
nss_capwapmgr_info("%px disabling DTLS for tunnel: %d\n", dev, tunnel_id);
|
|
|
|
- ip_if_num = nss_capwap_ifnum_with_core_id(t->if_num_outer);
|
|
- capwapmsg_inner.msg.dtls.enable = 0;
|
|
- capwapmsg_inner.msg.dtls.dtls_inner_if_num = t->capwap_rule.dtls_inner_if_num;
|
|
- capwapmsg_inner.msg.dtls.mtu_adjust = 0;
|
|
-
|
|
- capwapmsg_outer.msg.dtls.enable = 0;
|
|
+ ip_if_num = nss_capwap_ifnum_with_core_id(t->if_num);
|
|
+ capwapmsg.msg.dtls.enable = 0;
|
|
+ capwapmsg.msg.dtls.dtls_inner_if_num = t->capwap_rule.dtls_inner_if_num;
|
|
+ capwapmsg.msg.dtls.mtu_adjust = 0;
|
|
|
|
/*
|
|
* Unconfigure trustsec tx first
|
|
@@ -2060,7 +1984,6 @@ nss_capwapmgr_status_t nss_capwapmgr_con
|
|
nss_status = nss_trustsec_tx_unconfigure_sgt(t->capwap_rule.dtls_inner_if_num, t->capwap_rule.outer_sgt_value);
|
|
if (nss_status != NSS_TX_SUCCESS) {
|
|
nss_capwapmgr_warn("%px: unconfigure trustsec_tx failed\n", dev);
|
|
- dev_put(dev);
|
|
return NSS_CAPWAPMGR_FAILURE_UNCONFIGURE_TRUSTSEC_TX;
|
|
}
|
|
}
|
|
@@ -2075,7 +1998,6 @@ nss_capwapmgr_status_t nss_capwapmgr_con
|
|
*/
|
|
if (!in_data) {
|
|
nss_capwapmgr_info("%px: dtls in_data required to create dtls tunnel\n", dev);
|
|
- dev_put(dev);
|
|
return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
@@ -2085,12 +2007,11 @@ nss_capwapmgr_status_t nss_capwapmgr_con
|
|
* ensure that the user does not configure this mode accidentally.
|
|
*/
|
|
in_data->flags &= ~NSS_DTLSMGR_ENCAP_METADATA;
|
|
- in_data->decap.nexthop_ifnum = nss_capwap_ifnum_with_core_id(t->if_num_outer);
|
|
+ in_data->decap.nexthop_ifnum = nss_capwap_ifnum_with_core_id(t->if_num);
|
|
|
|
t->dtls_dev = nss_dtlsmgr_session_create(in_data);
|
|
if (!t->dtls_dev) {
|
|
nss_capwapmgr_warn("%px: cannot create DTLS session\n", dev);
|
|
- dev_put(dev);
|
|
return NSS_CAPWAPMGR_FAILURE_DI_ALLOC_FAILED;
|
|
}
|
|
|
|
@@ -2104,20 +2025,17 @@ nss_capwapmgr_status_t nss_capwapmgr_con
|
|
|
|
ip_if_num = nss_dtlsmgr_get_interface(t->dtls_dev, NSS_DTLSMGR_INTERFACE_TYPE_OUTER);
|
|
|
|
- capwapmsg_inner.msg.dtls.enable = 1;
|
|
- capwapmsg_inner.msg.dtls.dtls_inner_if_num = t->capwap_rule.dtls_inner_if_num;
|
|
- capwapmsg_inner.msg.dtls.mtu_adjust = t->capwap_rule.mtu_adjust;
|
|
-
|
|
- capwapmsg_outer.msg.dtls.enable = 1;
|
|
+ capwapmsg.msg.dtls.enable = 1;
|
|
+ capwapmsg.msg.dtls.dtls_inner_if_num = t->capwap_rule.dtls_inner_if_num;
|
|
+ capwapmsg.msg.dtls.mtu_adjust = t->capwap_rule.mtu_adjust;
|
|
|
|
/*
|
|
* Unconfigure trustsec tx first
|
|
*/
|
|
if (outer_trustsec_enabled) {
|
|
- nss_status = nss_trustsec_tx_unconfigure_sgt(t->if_num_outer, t->capwap_rule.outer_sgt_value);
|
|
+ nss_status = nss_trustsec_tx_unconfigure_sgt(t->if_num, t->capwap_rule.outer_sgt_value);
|
|
if (nss_status != NSS_TX_SUCCESS) {
|
|
nss_capwapmgr_warn("%px: unconfigure trustsec_tx failed\n", dev);
|
|
- dev_put(dev);
|
|
return NSS_CAPWAPMGR_FAILURE_UNCONFIGURE_TRUSTSEC_TX;
|
|
}
|
|
}
|
|
@@ -2130,11 +2048,11 @@ nss_capwapmgr_status_t nss_capwapmgr_con
|
|
nss_status = nss_trustsec_tx_configure_sgt(ip_if_num, t->capwap_rule.gmac_ifnum, t->capwap_rule.outer_sgt_value);
|
|
if (nss_status != NSS_TX_SUCCESS) {
|
|
nss_capwapmgr_warn("%px: configure trustsec_tx failed\n", dev);
|
|
- dev_put(dev);
|
|
return NSS_CAPWAPMGR_FAILURE_CONFIGURE_TRUSTSEC_TX;
|
|
}
|
|
}
|
|
|
|
+ dev_hold(dev);
|
|
priv = netdev_priv(dev);
|
|
|
|
/*
|
|
@@ -2200,18 +2118,11 @@ nss_capwapmgr_status_t nss_capwapmgr_con
|
|
* Now configure capwap dtls
|
|
*/
|
|
t->tunnel_state |= NSS_CAPWAPMGR_TUNNEL_STATE_IPRULE_CONFIGURED;
|
|
- status = nss_capwapmgr_tx_msg_sync(priv->nss_ctx, dev, &capwapmsg_inner);
|
|
- if (status != NSS_CAPWAPMGR_SUCCESS) {
|
|
- nss_capwapmgr_warn("%px: configure DTLS failed for inner node: %d\n", dev, status);
|
|
- dev_put(dev);
|
|
- return status;
|
|
- }
|
|
-
|
|
- status = nss_capwapmgr_tx_msg_sync(priv->nss_ctx, dev, &capwapmsg_outer);
|
|
+ status = nss_capwapmgr_tx_msg_sync(priv->nss_ctx, dev, &capwapmsg);
|
|
if (status != NSS_CAPWAPMGR_SUCCESS) {
|
|
- nss_capwapmgr_warn("%px: configure DTLS failed for outer node: %d\n", dev, status);
|
|
+ nss_capwapmgr_warn("%px: configure DTLS failed : %d\n", dev, status);
|
|
dev_put(dev);
|
|
- return status;
|
|
+ return nss_status;
|
|
}
|
|
|
|
if (enable_dtls) {
|
|
@@ -2227,8 +2138,6 @@ EXPORT_SYMBOL(nss_capwapmgr_configure_dt
|
|
/*
|
|
* nss_capwapmgr_verify_dtls_rekey_param()
|
|
* Validate the rekey param for a DTLS tunnel and return the DTLS netdevice
|
|
- *
|
|
- * The caller should hold the reference on the net device before calling.
|
|
*/
|
|
static inline struct net_device *nss_capwapmgr_verify_dtls_rekey_param(struct net_device *dev, uint8_t tunnel_id,
|
|
struct nss_dtlsmgr_config_update *udata)
|
|
@@ -2261,27 +2170,16 @@ static inline struct net_device *nss_cap
|
|
nss_capwapmgr_status_t nss_capwapmgr_dtls_rekey_rx_cipher_update(struct net_device *dev, uint8_t tunnel_id,
|
|
struct nss_dtlsmgr_config_update *udata)
|
|
{
|
|
- struct net_device *dtls_ndev;
|
|
-
|
|
- dev_hold(dev);
|
|
- dtls_ndev = nss_capwapmgr_verify_dtls_rekey_param(dev, tunnel_id, udata);
|
|
- dev_put(dev);
|
|
-
|
|
- if (!dtls_ndev) {
|
|
- goto fail;
|
|
- }
|
|
+ struct net_device *dtls_ndev = nss_capwapmgr_verify_dtls_rekey_param(dev, tunnel_id, udata);
|
|
|
|
/*
|
|
* Calling dtlsmgr for rekey
|
|
*/
|
|
if (nss_dtlsmgr_session_update_decap(dtls_ndev, udata) != NSS_DTLSMGR_OK) {
|
|
- goto fail;
|
|
+ nss_capwapmgr_warn("%px: tunnel: %d rekey rx cipher update failed\n", dtls_ndev, tunnel_id);
|
|
+ return NSS_CAPWAPMGR_FAILURE_INVALID_DTLS_CFG;
|
|
}
|
|
return NSS_CAPWAPMGR_SUCCESS;
|
|
-
|
|
-fail:
|
|
- nss_capwapmgr_warn("%px: tunnel: %d rekey rx cipher update failed\n", dtls_ndev, tunnel_id);
|
|
- return NSS_CAPWAPMGR_FAILURE_INVALID_DTLS_CFG;
|
|
}
|
|
EXPORT_SYMBOL(nss_capwapmgr_dtls_rekey_rx_cipher_update);
|
|
|
|
@@ -2292,27 +2190,16 @@ EXPORT_SYMBOL(nss_capwapmgr_dtls_rekey_r
|
|
nss_capwapmgr_status_t nss_capwapmgr_dtls_rekey_tx_cipher_update(struct net_device *dev, uint8_t tunnel_id,
|
|
struct nss_dtlsmgr_config_update *udata)
|
|
{
|
|
- struct net_device *dtls_ndev;
|
|
-
|
|
- dev_hold(dev);
|
|
- dtls_ndev = nss_capwapmgr_verify_dtls_rekey_param(dev, tunnel_id, udata);
|
|
- dev_put(dev);
|
|
-
|
|
- if (!dtls_ndev) {
|
|
- goto fail;
|
|
- }
|
|
+ struct net_device *dtls_ndev = nss_capwapmgr_verify_dtls_rekey_param(dev, tunnel_id, udata);
|
|
|
|
/*
|
|
* Calling dtlsmgr for rekey
|
|
*/
|
|
if (nss_dtlsmgr_session_update_encap(dtls_ndev, udata) != NSS_DTLSMGR_OK) {
|
|
- goto fail;
|
|
+ nss_capwapmgr_warn("%px: tunnel: %d rekey tx cipher update failed\n", dtls_ndev, tunnel_id);
|
|
+ return NSS_CAPWAPMGR_FAILURE_INVALID_DTLS_CFG;
|
|
}
|
|
return NSS_CAPWAPMGR_SUCCESS;
|
|
-
|
|
-fail:
|
|
- nss_capwapmgr_warn("%px: tunnel: %d rekey rx cipher update failed\n", dtls_ndev, tunnel_id);
|
|
- return NSS_CAPWAPMGR_FAILURE_INVALID_DTLS_CFG;
|
|
}
|
|
EXPORT_SYMBOL(nss_capwapmgr_dtls_rekey_tx_cipher_update);
|
|
|
|
@@ -2323,20 +2210,16 @@ EXPORT_SYMBOL(nss_capwapmgr_dtls_rekey_t
|
|
nss_capwapmgr_status_t nss_capwapmgr_dtls_rekey_rx_cipher_switch(struct net_device *dev, uint8_t tunnel_id)
|
|
{
|
|
struct nss_capwapmgr_tunnel *t;
|
|
- nss_capwapmgr_status_t status = NSS_CAPWAPMGR_SUCCESS;
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_warn("%px: can't find tunnel: %d\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
if (!(t->capwap_rule.enabled_features & NSS_CAPWAPMGR_FEATURE_DTLS_ENABLED)) {
|
|
nss_capwapmgr_warn("%px: tunnel does not enable DTLS: %d\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
/*
|
|
@@ -2344,12 +2227,10 @@ nss_capwapmgr_status_t nss_capwapmgr_dtl
|
|
*/
|
|
if (!nss_dtlsmgr_session_switch_decap(t->dtls_dev)) {
|
|
nss_capwapmgr_warn("%px: tunnel: %d rekey rx cipher switch failed\n", t->dtls_dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_INVALID_DTLS_CFG;
|
|
+ return NSS_CAPWAPMGR_FAILURE_INVALID_DTLS_CFG;
|
|
}
|
|
|
|
-done:
|
|
- dev_put(dev);
|
|
- return status;
|
|
+ return NSS_CAPWAPMGR_SUCCESS;
|
|
}
|
|
EXPORT_SYMBOL(nss_capwapmgr_dtls_rekey_rx_cipher_switch);
|
|
|
|
@@ -2360,20 +2241,16 @@ EXPORT_SYMBOL(nss_capwapmgr_dtls_rekey_r
|
|
nss_capwapmgr_status_t nss_capwapmgr_dtls_rekey_tx_cipher_switch(struct net_device *dev, uint8_t tunnel_id)
|
|
{
|
|
struct nss_capwapmgr_tunnel *t;
|
|
- nss_capwapmgr_status_t status = NSS_CAPWAPMGR_SUCCESS;
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_warn("%px: can't find tunnel: %d\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
if (!(t->capwap_rule.enabled_features & NSS_CAPWAPMGR_FEATURE_DTLS_ENABLED)) {
|
|
nss_capwapmgr_warn("%px: tunnel does not enable DTLS: %d\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
/*
|
|
@@ -2381,12 +2258,10 @@ nss_capwapmgr_status_t nss_capwapmgr_dtl
|
|
*/
|
|
if (!nss_dtlsmgr_session_switch_encap(t->dtls_dev)) {
|
|
nss_capwapmgr_warn("%px: tunnel: %d rekey tx cipher switch failed\n", t->dtls_dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_INVALID_DTLS_CFG;
|
|
+ return NSS_CAPWAPMGR_FAILURE_INVALID_DTLS_CFG;
|
|
}
|
|
|
|
-done:
|
|
- dev_put(dev);
|
|
- return status;
|
|
+ return NSS_CAPWAPMGR_SUCCESS;
|
|
}
|
|
EXPORT_SYMBOL(nss_capwapmgr_dtls_rekey_tx_cipher_switch);
|
|
|
|
@@ -2400,22 +2275,20 @@ nss_capwapmgr_status_t nss_capwapmgr_cha
|
|
struct nss_capwapmgr_priv *priv;
|
|
struct nss_capwap_msg capwapmsg;
|
|
struct nss_capwapmgr_tunnel *t;
|
|
- nss_capwapmgr_status_t status = NSS_CAPWAPMGR_SUCCESS;
|
|
+ nss_capwapmgr_status_t status;
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_warn("%px: can't find tunnel: %d\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
if (ver > NSS_CAPWAP_VERSION_V2) {
|
|
nss_capwapmgr_warn("%px: un-supported Version: %d\n", dev, ver);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
+ dev_hold(dev);
|
|
priv = netdev_priv(dev);
|
|
|
|
/*
|
|
@@ -2426,21 +2299,50 @@ nss_capwapmgr_status_t nss_capwapmgr_cha
|
|
/*
|
|
* Send CAPWAP data tunnel command to NSS
|
|
*/
|
|
- nss_capwap_msg_init(&capwapmsg, t->if_num_inner, NSS_CAPWAP_MSG_TYPE_VERSION,
|
|
+ nss_capwap_msg_init(&capwapmsg, t->if_num, NSS_CAPWAP_MSG_TYPE_VERSION,
|
|
sizeof(struct nss_capwap_version_msg), nss_capwapmgr_msg_event_receive, dev);
|
|
capwapmsg.msg.version.version = ver;
|
|
status = nss_capwapmgr_tx_msg_sync(priv->nss_ctx, dev, &capwapmsg);
|
|
if (status != NSS_CAPWAPMGR_SUCCESS) {
|
|
nss_capwapmgr_warn("%px: Update Path MTU Tunnel error : %d \n", dev, status);
|
|
+ dev_put(dev);
|
|
+ return status;
|
|
}
|
|
|
|
-done:
|
|
dev_put(dev);
|
|
return status;
|
|
}
|
|
EXPORT_SYMBOL(nss_capwapmgr_change_version);
|
|
|
|
/*
|
|
+ * nss_capwapmgr_tunnel_action()
|
|
+ * Common function for CAPWAP tunnel operation messages without
|
|
+ * any message data structures.
|
|
+ */
|
|
+static nss_tx_status_t nss_capwapmgr_tunnel_action(struct nss_ctx_instance *ctx, struct net_device *dev, uint32_t if_num, nss_capwap_msg_type_t cmd)
|
|
+{
|
|
+ struct nss_capwap_msg capwapmsg;
|
|
+ nss_tx_status_t status;
|
|
+
|
|
+ /*
|
|
+ * Prepare the tunnel configuration parameter to send to NSS FW
|
|
+ */
|
|
+ memset(&capwapmsg, 0, sizeof(struct nss_capwap_msg));
|
|
+
|
|
+ /*
|
|
+ * Send CAPWAP data tunnel command to NSS
|
|
+ */
|
|
+ nss_capwap_msg_init(&capwapmsg, if_num, cmd, 0, nss_capwapmgr_msg_event_receive, dev);
|
|
+ status = nss_capwapmgr_tx_msg_sync(ctx, dev, &capwapmsg);
|
|
+ if (status != NSS_TX_SUCCESS) {
|
|
+ nss_capwapmgr_warn("%px: ctx: CMD: %d Tunnel error : %d \n", ctx, cmd, status);
|
|
+ return status;
|
|
+ }
|
|
+
|
|
+ return status;
|
|
+}
|
|
+
|
|
+/*
|
|
* nss_capwapmgr_enable_tunnel()
|
|
* API for enabling a data tunnel
|
|
*/
|
|
@@ -2448,41 +2350,28 @@ nss_capwapmgr_status_t nss_capwapmgr_ena
|
|
{
|
|
struct nss_capwapmgr_priv *priv;
|
|
struct nss_capwapmgr_tunnel *t;
|
|
- nss_capwapmgr_status_t status = NSS_CAPWAPMGR_SUCCESS;
|
|
+ nss_tx_status_t ret;
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_warn("%px: can't find tunnel: %d\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
if (t->tunnel_state & NSS_CAPWAPMGR_TUNNEL_STATE_ENABLED) {
|
|
nss_capwapmgr_warn("%px: tunnel %d is already enabled\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_TUNNEL_ENABLED;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_TUNNEL_ENABLED;
|
|
}
|
|
|
|
+ dev_hold(dev);
|
|
priv = netdev_priv(dev);
|
|
- nss_capwapmgr_info("%px: Inner:%d Outer:%d. Tunnel enable is being called\n", dev, t->if_num_inner, t->if_num_outer);
|
|
-
|
|
- status = nss_capwapmgr_tx_msg_enable_tunnel(priv->nss_ctx, dev, t->if_num_inner,t->if_num_outer);
|
|
- if (status != NSS_CAPWAPMGR_SUCCESS) {
|
|
- goto done;
|
|
+ nss_capwapmgr_info("%px: %d: tunnel enable is being called\n", dev, t->if_num);
|
|
+ ret = nss_capwapmgr_tunnel_action(priv->nss_ctx, dev, t->if_num, NSS_CAPWAP_MSG_TYPE_ENABLE_TUNNEL);
|
|
+ if (ret == NSS_TX_SUCCESS) {
|
|
+ t->tunnel_state |= NSS_CAPWAPMGR_TUNNEL_STATE_ENABLED;
|
|
}
|
|
-
|
|
- status = nss_capwapmgr_tx_msg_enable_tunnel(priv->nss_ctx, dev, t->if_num_outer,t->if_num_inner);
|
|
- if(status != NSS_CAPWAPMGR_SUCCESS) {
|
|
- nss_capwapmgr_tunnel_action(priv->nss_ctx, dev, t->if_num_inner,NSS_CAPWAP_MSG_TYPE_DISABLE_TUNNEL);
|
|
- goto done;
|
|
- }
|
|
-
|
|
- t->tunnel_state |= NSS_CAPWAPMGR_TUNNEL_STATE_ENABLED;
|
|
-
|
|
-done:
|
|
dev_put(dev);
|
|
- return status;
|
|
+ return ret;
|
|
}
|
|
EXPORT_SYMBOL(nss_capwapmgr_enable_tunnel);
|
|
|
|
@@ -2494,44 +2383,28 @@ nss_capwapmgr_status_t nss_capwapmgr_dis
|
|
{
|
|
struct nss_capwapmgr_priv *priv;
|
|
struct nss_capwapmgr_tunnel *t;
|
|
- nss_capwapmgr_status_t status = NSS_CAPWAPMGR_SUCCESS;
|
|
+ nss_tx_status_t ret;
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_warn("%px: can't find tunnel: %d\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
if (!(t->tunnel_state & NSS_CAPWAPMGR_TUNNEL_STATE_ENABLED)) {
|
|
- nss_capwapmgr_warn("%px: tunnel %d is already disabled\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_TUNNEL_DISABLED;
|
|
- goto done;
|
|
+ nss_capwapmgr_warn("%px: tunnel %d is already enabled\n", dev, tunnel_id);
|
|
+ return NSS_CAPWAPMGR_FAILURE_TUNNEL_DISABLED;
|
|
}
|
|
|
|
+ dev_hold(dev);
|
|
priv = netdev_priv(dev);
|
|
- nss_capwapmgr_info("%px: Inner:%d Outer:%d. Tunnel disable is being called\n", dev, t->if_num_inner, t->if_num_outer);
|
|
-
|
|
- status = nss_capwapmgr_tunnel_action(priv->nss_ctx, dev, t->if_num_inner,NSS_CAPWAP_MSG_TYPE_DISABLE_TUNNEL);
|
|
- if (status != NSS_CAPWAPMGR_SUCCESS) {
|
|
- status = NSS_CAPWAPMGR_FAILURE_TUNNEL_DISABLED;
|
|
- nss_capwapmgr_warn("%px: tunnel %d disable failed\n", dev, tunnel_id);
|
|
- goto done;
|
|
- }
|
|
-
|
|
- status = nss_capwapmgr_tunnel_action(priv->nss_ctx, dev, t->if_num_outer,NSS_CAPWAP_MSG_TYPE_DISABLE_TUNNEL);
|
|
- if (status != NSS_CAPWAPMGR_SUCCESS) {
|
|
- nss_capwapmgr_warn("%px: tunnel %d disable failed\n", dev, tunnel_id);
|
|
- nss_capwapmgr_tx_msg_enable_tunnel(priv->nss_ctx, dev, t->if_num_inner, t->if_num_outer);
|
|
- goto done;
|
|
+ nss_capwapmgr_info("%px: %d: tunnel disable is being called\n", dev, t->if_num);
|
|
+ ret = nss_capwapmgr_tunnel_action(priv->nss_ctx, dev, t->if_num, NSS_CAPWAP_MSG_TYPE_DISABLE_TUNNEL);
|
|
+ if (ret == NSS_TX_SUCCESS) {
|
|
+ t->tunnel_state &= ~NSS_CAPWAPMGR_TUNNEL_STATE_ENABLED;
|
|
}
|
|
-
|
|
- t->tunnel_state &= ~NSS_CAPWAPMGR_TUNNEL_STATE_ENABLED;
|
|
-
|
|
-done:
|
|
dev_put(dev);
|
|
- return status;
|
|
+ return ret;
|
|
}
|
|
EXPORT_SYMBOL(nss_capwapmgr_disable_tunnel);
|
|
|
|
@@ -2545,7 +2418,7 @@ static nss_capwapmgr_status_t nss_capwap
|
|
struct nss_capwapmgr_priv *priv;
|
|
struct nss_capwapmgr_tunnel *t;
|
|
nss_capwapmgr_status_t status = NSS_CAPWAPMGR_SUCCESS;
|
|
- int32_t capwap_if_num_inner, capwap_if_num_outer, forward_if_num;
|
|
+ int32_t capwap_if_num, forward_if_num;
|
|
uint16_t type_flags = 0;
|
|
nss_tx_status_t nss_status = NSS_TX_SUCCESS;
|
|
uint32_t dtls_enabled = capwap_rule->enabled_features & NSS_CAPWAPMGR_FEATURE_DTLS_ENABLED;
|
|
@@ -2578,44 +2451,28 @@ static nss_capwapmgr_status_t nss_capwap
|
|
return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (t) {
|
|
nss_capwapmgr_warn("%px: tunnel: %d already created\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_TUNNEL_EXISTS;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_TUNNEL_EXISTS;
|
|
}
|
|
|
|
- capwap_if_num_inner = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP_HOST_INNER);
|
|
- if (capwap_if_num_inner < 0) {
|
|
- nss_capwapmgr_warn("%px: di returned error : %d\n", dev, capwap_if_num_inner);
|
|
- status = NSS_CAPWAPMGR_FAILURE_DI_ALLOC_FAILED;
|
|
- goto done;
|
|
+ capwap_if_num = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP);
|
|
+ if (capwap_if_num < 0) {
|
|
+ nss_capwapmgr_warn("%px: di returned error : %d\n", dev, capwap_if_num);
|
|
+ return NSS_CAPWAPMGR_FAILURE_DI_ALLOC_FAILED;
|
|
}
|
|
|
|
- if (nss_capwapmgr_register_with_nss(capwap_if_num_inner, dev) != NSS_CAPWAPMGR_SUCCESS) {
|
|
- nss_capwapmgr_warn("%d: NSS CAPWAP register with NSS failed", capwap_if_num_inner);
|
|
- status = NSS_CAPWAPMGR_FAILURE_REGISTER_NSS;
|
|
- goto fail1;
|
|
- }
|
|
-
|
|
- capwap_if_num_outer = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP_OUTER);
|
|
- if (capwap_if_num_outer < 0) {
|
|
- nss_capwapmgr_warn("%px: di returned error : %d\n", dev, capwap_if_num_outer);
|
|
- status = NSS_CAPWAPMGR_FAILURE_DI_ALLOC_FAILED;
|
|
- goto fail2;
|
|
- }
|
|
-
|
|
- if (nss_capwapmgr_register_with_nss(capwap_if_num_outer, dev) != NSS_CAPWAPMGR_SUCCESS) {
|
|
- nss_capwapmgr_warn("%d: NSS CAPWAP register with NSS failed", capwap_if_num_outer);
|
|
- status = NSS_CAPWAPMGR_FAILURE_REGISTER_NSS;
|
|
- goto fail3;
|
|
+ if (nss_capwapmgr_register_with_nss(capwap_if_num, dev) != NSS_CAPWAPMGR_SUCCESS) {
|
|
+ nss_capwapmgr_warn("%d: NSS CAPWAP register with NSS failed", capwap_if_num);
|
|
+ (void)nss_dynamic_interface_dealloc_node(capwap_if_num, NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP);
|
|
+ return NSS_CAPWAPMGR_FAILURE_REGISTER_NSS;
|
|
}
|
|
|
|
if (!dtls_enabled) {
|
|
capwap_rule->mtu_adjust = 0;
|
|
capwap_rule->dtls_inner_if_num = 0;
|
|
- forward_if_num = nss_capwap_ifnum_with_core_id(capwap_if_num_outer);
|
|
+ forward_if_num = nss_capwap_ifnum_with_core_id(capwap_if_num);
|
|
} else {
|
|
/*
|
|
* We only support the METADATA mode for pure DTLS tunnels; in CAPWAP-DTLS
|
|
@@ -2623,13 +2480,14 @@ static nss_capwapmgr_status_t nss_capwap
|
|
* ensure that the user does not configure this mode accidentally.
|
|
*/
|
|
in_data->flags &= ~NSS_DTLSMGR_ENCAP_METADATA;
|
|
- in_data->decap.nexthop_ifnum = nss_capwap_ifnum_with_core_id(capwap_if_num_outer);
|
|
+ in_data->decap.nexthop_ifnum = nss_capwap_ifnum_with_core_id(capwap_if_num);
|
|
|
|
t->dtls_dev = nss_dtlsmgr_session_create(in_data);
|
|
if (!t->dtls_dev) {
|
|
nss_capwapmgr_warn("%px: NSS DTLS node alloc failed\n", dev);
|
|
- status = NSS_CAPWAPMGR_FAILURE_DI_ALLOC_FAILED;
|
|
- goto fail4;
|
|
+ nss_capwapmgr_unregister_with_nss(capwap_if_num);
|
|
+ (void)nss_dynamic_interface_dealloc_node(capwap_if_num, NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP);
|
|
+ return NSS_CAPWAPMGR_FAILURE_DI_ALLOC_FAILED;
|
|
}
|
|
capwap_rule->dtls_inner_if_num = nss_dtlsmgr_get_interface(t->dtls_dev, NSS_DTLSMGR_INTERFACE_TYPE_INNER);
|
|
forward_if_num = nss_dtlsmgr_get_interface(t->dtls_dev, NSS_DTLSMGR_INTERFACE_TYPE_OUTER);
|
|
@@ -2650,7 +2508,7 @@ static nss_capwapmgr_status_t nss_capwap
|
|
if (nss_status != NSS_TX_SUCCESS) {
|
|
nss_capwapmgr_warn("%px: configure trustsectx node failed\n", dev);
|
|
status = NSS_CAPWAPMGR_FAILURE_CONFIGURE_TRUSTSEC_TX;
|
|
- goto fail5;
|
|
+ goto fail;
|
|
}
|
|
}
|
|
|
|
@@ -2706,20 +2564,12 @@ static nss_capwapmgr_status_t nss_capwap
|
|
capwap_rule->encap.dest_ip.ip.ipv6[3] = htonl(v6->src_ip[3]);
|
|
}
|
|
|
|
- status = nss_capwapmgr_create_capwap_rule(dev, capwap_if_num_inner, capwap_rule, type_flags);
|
|
- nss_capwapmgr_info("%px: dynamic interface if_num is :%d and capwap tunnel status:%d\n", dev, capwap_if_num_inner, status);
|
|
+ status = nss_capwapmgr_create_capwap_rule(dev, capwap_if_num, capwap_rule, type_flags);
|
|
+ nss_capwapmgr_info("%px: dynamic interface if_num is :%d and capwap tunnel status:%d\n", dev, capwap_if_num, status);
|
|
if (status != NSS_CAPWAPMGR_SUCCESS) {
|
|
- nss_capwapmgr_warn("%px: %d: CAPWAP rule create failed with status: %d", dev, capwap_if_num_inner, status);
|
|
+ nss_capwapmgr_warn("%px: %d: CAPWAP rule create failed with status: %d", dev, capwap_if_num, status);
|
|
status = NSS_CAPWAPMGR_FAILURE_CAPWAP_RULE;
|
|
- goto fail5;
|
|
- }
|
|
-
|
|
- status = nss_capwapmgr_create_capwap_rule(dev, capwap_if_num_outer, capwap_rule, type_flags);
|
|
- nss_capwapmgr_info("%px: dynamic interface if_num is :%d and capwap tunnel status:%d\n", dev, capwap_if_num_outer, status);
|
|
- if (status != NSS_CAPWAPMGR_SUCCESS) {
|
|
- nss_capwapmgr_warn("%px: %d: CAPWAP rule create failed with status: %d", dev, capwap_if_num_outer, status);
|
|
- status = NSS_CAPWAPMGR_FAILURE_CAPWAP_RULE;
|
|
- goto fail5;
|
|
+ goto fail;
|
|
}
|
|
|
|
if (v4) {
|
|
@@ -2733,12 +2583,13 @@ static nss_capwapmgr_status_t nss_capwap
|
|
if (nss_status != NSS_TX_SUCCESS) {
|
|
nss_capwapmgr_warn("%px: %d: IPv4/IPv6 rule create failed with status: %d", dev, forward_if_num, nss_status);
|
|
status = NSS_CAPWAPMGR_FAILURE_IP_RULE;
|
|
- goto fail5;
|
|
+ goto fail;
|
|
}
|
|
|
|
+ dev_hold(dev);
|
|
priv = netdev_priv(dev);
|
|
t = &priv->tunnel[tunnel_id];
|
|
- nss_capwapmgr_info("%px: %d: %d: CAPWAP TUNNEL CREATE DONE tunnel_id:%d (%px)\n", dev, capwap_if_num_inner, capwap_if_num_outer, tunnel_id, t);
|
|
+ nss_capwapmgr_info("%px: %d: CAPWAP TUNNEL CREATE DONE tunnel_id:%d (%px)\n", dev, capwap_if_num, tunnel_id, t);
|
|
|
|
/*
|
|
* Keep a copy of rule information.
|
|
@@ -2754,33 +2605,22 @@ static nss_capwapmgr_status_t nss_capwap
|
|
/*
|
|
* Make it globally visible inside the netdev.
|
|
*/
|
|
- t->if_num_inner = capwap_if_num_inner;
|
|
- t->if_num_outer = capwap_if_num_outer;
|
|
- priv->if_num_to_tunnel_id[capwap_if_num_inner] = tunnel_id;
|
|
- priv->if_num_to_tunnel_id[capwap_if_num_outer] = tunnel_id;
|
|
+ t->if_num = capwap_if_num;
|
|
+ priv->if_num_to_tunnel_id[capwap_if_num] = tunnel_id;
|
|
t->tunnel_state |= NSS_CAPWAPMGR_TUNNEL_STATE_CONFIGURED;
|
|
t->tunnel_state |= NSS_CAPWAPMGR_TUNNEL_STATE_IPRULE_CONFIGURED;
|
|
- t->type_flags = type_flags;
|
|
|
|
- goto done;
|
|
+ dev_put(dev);
|
|
+ return status;
|
|
|
|
-fail5:
|
|
+fail:
|
|
+ nss_capwapmgr_unregister_with_nss(capwap_if_num);
|
|
+ (void)nss_dynamic_interface_dealloc_node(capwap_if_num, NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP);
|
|
if (dtls_enabled) {
|
|
if (nss_dtlsmgr_session_destroy(t->dtls_dev) != NSS_DTLSMGR_OK) {
|
|
nss_capwapmgr_warn("%px: failed to destroy DTLS session", t->dtls_dev);
|
|
}
|
|
}
|
|
-fail4:
|
|
- nss_capwapmgr_unregister_with_nss(capwap_if_num_outer);
|
|
-fail3:
|
|
- (void)nss_dynamic_interface_dealloc_node(capwap_if_num_outer, NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP_OUTER);
|
|
-fail2:
|
|
- nss_capwapmgr_unregister_with_nss(capwap_if_num_inner);
|
|
-fail1:
|
|
- (void)nss_dynamic_interface_dealloc_node(capwap_if_num_inner, NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP_HOST_INNER);
|
|
-
|
|
-done:
|
|
- dev_put(dev);
|
|
return status;
|
|
}
|
|
|
|
@@ -2819,7 +2659,7 @@ static void nss_capwapmgr_tunnel_save_st
|
|
save->rx_dup_frag += fstats->rx_dup_frag;
|
|
save->rx_oversize_drops += fstats->rx_oversize_drops;
|
|
save->rx_frag_timeout_drops += fstats->rx_frag_timeout_drops;
|
|
- save->rx_n2h_drops += fstats->rx_n2h_drops;
|
|
+ save->rx_queue_full_drops += fstats->rx_queue_full_drops;
|
|
save->rx_n2h_queue_full_drops += fstats->rx_n2h_queue_full_drops;
|
|
save->rx_mem_failure_drops += fstats->rx_mem_failure_drops;
|
|
save->rx_csum_drops += fstats->rx_csum_drops;
|
|
@@ -2857,21 +2697,18 @@ nss_capwapmgr_status_t nss_capwapmgr_tun
|
|
struct nss_capwapmgr_priv *priv;
|
|
struct nss_capwapmgr_tunnel *t;
|
|
nss_tx_status_t nss_status = NSS_TX_SUCCESS;
|
|
- uint32_t if_num_inner, if_num_outer;
|
|
+ uint32_t if_num;
|
|
nss_capwapmgr_status_t status = NSS_CAPWAPMGR_SUCCESS;
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_warn("%px: tunnel %d: wrong argument for tunnel destroy\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
if (!(t->tunnel_state & NSS_CAPWAPMGR_TUNNEL_STATE_CONFIGURED)) {
|
|
nss_capwapmgr_warn("%px: tunnel %d is not configured yet\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_TUNNEL_NOT_CFG;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_TUNNEL_NOT_CFG;
|
|
}
|
|
|
|
/*
|
|
@@ -2879,49 +2716,34 @@ nss_capwapmgr_status_t nss_capwapmgr_tun
|
|
*/
|
|
if (t->tunnel_state & NSS_CAPWAPMGR_TUNNEL_STATE_ENABLED) {
|
|
nss_capwapmgr_warn("%px: no destroy alloed for an eanbled tunnel: %d\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_TUNNEL_ENABLED;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_TUNNEL_ENABLED;
|
|
}
|
|
|
|
if (!(t->capwap_rule.l3_proto == NSS_CAPWAP_TUNNEL_IPV4 ||
|
|
t->capwap_rule.l3_proto == NSS_CAPWAP_TUNNEL_IPV6)) {
|
|
nss_capwapmgr_warn("%px: tunnel %d: wrong argument for l3_proto\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
if (!(t->capwap_rule.which_udp == NSS_CAPWAP_TUNNEL_UDP ||
|
|
t->capwap_rule.which_udp == NSS_CAPWAP_TUNNEL_UDPLite)) {
|
|
nss_capwapmgr_warn("%px: tunnel %d: wrong argument for which_udp(%d)\n", dev, tunnel_id, t->capwap_rule.which_udp);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
+ dev_hold(dev);
|
|
priv = netdev_priv(dev);
|
|
- nss_capwapmgr_info("%px: %d: tunnel destroy is being called\n", dev, tunnel_id);
|
|
-
|
|
- if_num_inner = t->if_num_inner;
|
|
- if_num_outer = t->if_num_outer;
|
|
+ nss_capwapmgr_info("%px: %d: tunnel destroy is being called\n", dev, t->if_num);
|
|
+ if_num = t->if_num;
|
|
|
|
- if (priv->if_num_to_tunnel_id[if_num_inner] != tunnel_id) {
|
|
+ if (priv->if_num_to_tunnel_id[if_num] != tunnel_id) {
|
|
nss_capwapmgr_warn("%px: %d: tunnel_id %d didn't match with tunnel_id :%d\n",
|
|
- dev, if_num_inner, tunnel_id, priv->if_num_to_tunnel_id[if_num_inner]);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- if (priv->if_num_to_tunnel_id[if_num_outer] != tunnel_id) {
|
|
- nss_capwapmgr_warn("%px: %d: tunnel_id %d didn't match with tunnel_id :%d\n",
|
|
- dev, if_num_outer, tunnel_id, priv->if_num_to_tunnel_id[if_num_outer]);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- if (nss_capwap_get_stats(if_num_inner, &stats) == true) {
|
|
- nss_capwapmgr_tunnel_save_stats(&global.tunneld, &stats);
|
|
+ dev, if_num, tunnel_id, priv->if_num_to_tunnel_id[if_num]);
|
|
+ dev_put(dev);
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
- if (nss_capwap_get_stats(if_num_outer, &stats) == true) {
|
|
+ if (nss_capwap_get_stats(if_num, &stats) == true) {
|
|
nss_capwapmgr_tunnel_save_stats(&global.tunneld, &stats);
|
|
}
|
|
|
|
@@ -2961,10 +2783,9 @@ nss_capwapmgr_status_t nss_capwapmgr_tun
|
|
}
|
|
|
|
if (nss_status != NSS_TX_SUCCESS) {
|
|
- nss_capwapmgr_warn("%px: Unconfigure IP rule failed for tunnel : %d\n",
|
|
- dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_IP_DESTROY_RULE;
|
|
- goto done;
|
|
+ nss_capwapmgr_warn("%px: %d: Unconfigure IP rule failed for tunnel : %d\n",
|
|
+ dev, if_num, tunnel_id);
|
|
+ return NSS_CAPWAPMGR_FAILURE_IP_DESTROY_RULE;
|
|
}
|
|
t->tunnel_state &= ~NSS_CAPWAPMGR_TUNNEL_STATE_IPRULE_CONFIGURED;
|
|
}
|
|
@@ -2972,45 +2793,36 @@ nss_capwapmgr_status_t nss_capwapmgr_tun
|
|
/*
|
|
* Destroy CAPWAP rule now.
|
|
*/
|
|
- status = nss_capwapmgr_tunnel_action(priv->nss_ctx, dev, if_num_outer, NSS_CAPWAP_MSG_TYPE_UNCFG_RULE);
|
|
+ status = nss_capwapmgr_tunnel_action(priv->nss_ctx, dev, if_num, NSS_CAPWAP_MSG_TYPE_UNCFG_RULE);
|
|
if (status != NSS_CAPWAPMGR_SUCCESS) {
|
|
nss_capwapmgr_warn("%px: %d: Unconfigure CAPWAP rule failed for tunnel : %d\n",
|
|
- dev, if_num_outer, tunnel_id);
|
|
- goto fail;
|
|
-
|
|
- }
|
|
+ dev, if_num, tunnel_id);
|
|
|
|
- status = nss_capwapmgr_tunnel_action(priv->nss_ctx, dev, if_num_inner, NSS_CAPWAP_MSG_TYPE_UNCFG_RULE);
|
|
- if (status != NSS_CAPWAPMGR_SUCCESS) {
|
|
- nss_capwapmgr_warn("%px: %d: Unconfigure CAPWAP rule failed for tunnel : %d\n",
|
|
- dev, if_num_inner, tunnel_id);
|
|
- status = nss_capwapmgr_create_capwap_rule(dev, if_num_outer, &(t->capwap_rule), t->type_flags);
|
|
- if (status != NSS_CAPWAPMGR_SUCCESS) {
|
|
- nss_capwapmgr_warn("%px: %d: re creating the CAPWAP rule failed for tunnel : %d\n",
|
|
- dev, if_num_inner, tunnel_id);
|
|
- goto done;
|
|
+ if (t->capwap_rule.l3_proto == NSS_CAPWAP_TUNNEL_IPV4) {
|
|
+ nss_status = nss_capwapmgr_configure_ipv4(&t->ip_rule.v4, 0, 0);
|
|
+ if (nss_status == NSS_TX_SUCCESS) {
|
|
+ t->tunnel_state |= NSS_CAPWAPMGR_TUNNEL_STATE_IPRULE_CONFIGURED;
|
|
}
|
|
|
|
- goto fail;
|
|
+ } else {
|
|
+ nss_status = nss_capwapmgr_configure_ipv6(&t->ip_rule.v6, 0, 0);
|
|
+ if (nss_status == NSS_TX_SUCCESS) {
|
|
+ t->tunnel_state |= NSS_CAPWAPMGR_TUNNEL_STATE_IPRULE_CONFIGURED;
|
|
+ }
|
|
+ }
|
|
|
|
+ return NSS_CAPWAPMGR_FAILURE_CAPWAP_DESTROY_RULE;
|
|
}
|
|
|
|
- nss_capwapmgr_unregister_with_nss(if_num_outer);
|
|
- nss_capwapmgr_unregister_with_nss(if_num_inner);
|
|
+ nss_capwapmgr_unregister_with_nss(if_num);
|
|
|
|
/*
|
|
* Deallocate dynamic interface
|
|
*/
|
|
- nss_status = nss_dynamic_interface_dealloc_node(if_num_outer, NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP_OUTER);
|
|
- if (nss_status != NSS_TX_SUCCESS) {
|
|
- nss_capwapmgr_warn("%px: %d: Dealloc of dynamic interface failed for tunnel : %d\n",
|
|
- dev, if_num_outer, tunnel_id);
|
|
- }
|
|
-
|
|
- nss_status = nss_dynamic_interface_dealloc_node(if_num_inner, NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP_HOST_INNER);
|
|
+ nss_status = nss_dynamic_interface_dealloc_node(if_num, NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP);
|
|
if (nss_status != NSS_TX_SUCCESS) {
|
|
nss_capwapmgr_warn("%px: %d: Dealloc of dynamic interface failed for tunnel : %d\n",
|
|
- dev, if_num_inner, tunnel_id);
|
|
+ dev, if_num, tunnel_id);
|
|
}
|
|
|
|
/*
|
|
@@ -3020,9 +2832,8 @@ nss_capwapmgr_status_t nss_capwapmgr_tun
|
|
if (t->capwap_rule.enabled_features & NSS_CAPWAPMGR_FEATURE_DTLS_ENABLED) {
|
|
nss_status = nss_trustsec_tx_unconfigure_sgt(t->capwap_rule.dtls_inner_if_num, t->capwap_rule.outer_sgt_value);
|
|
} else {
|
|
- nss_status = nss_trustsec_tx_unconfigure_sgt(t->if_num_outer, t->capwap_rule.outer_sgt_value);
|
|
+ nss_status = nss_trustsec_tx_unconfigure_sgt(t->if_num, t->capwap_rule.outer_sgt_value);
|
|
}
|
|
-
|
|
if (nss_status != NSS_TX_SUCCESS) {
|
|
nss_capwapmgr_warn("%px: unconfigure trustsec_tx failed\n", dev);
|
|
}
|
|
@@ -3037,35 +2848,14 @@ nss_capwapmgr_status_t nss_capwapmgr_tun
|
|
}
|
|
}
|
|
|
|
+ t->if_num = 0;
|
|
t->tunnel_state &= ~NSS_CAPWAPMGR_TUNNEL_STATE_CONFIGURED;
|
|
- priv->if_num_to_tunnel_id[if_num_inner] = -1;
|
|
- priv->if_num_to_tunnel_id[if_num_outer] = -1;
|
|
-
|
|
+ priv->if_num_to_tunnel_id[if_num] = 0;
|
|
memset(t, 0, sizeof(struct nss_capwapmgr_tunnel));
|
|
|
|
- t->if_num_inner = -1;
|
|
- t->if_num_outer = -1;
|
|
-
|
|
- nss_capwapmgr_info("%px: Tunnel %d is completely destroyed\n", dev , tunnel_id);
|
|
- status = NSS_CAPWAPMGR_SUCCESS;
|
|
- goto done;
|
|
-
|
|
-fail:
|
|
- if (t->capwap_rule.l3_proto == NSS_CAPWAP_TUNNEL_IPV4) {
|
|
- nss_status = nss_capwapmgr_configure_ipv4(&t->ip_rule.v4, 0, 0);
|
|
- } else {
|
|
- nss_status = nss_capwapmgr_configure_ipv6(&t->ip_rule.v6, 0, 0);
|
|
- }
|
|
-
|
|
- if (nss_status == NSS_TX_SUCCESS) {
|
|
- t->tunnel_state |= NSS_CAPWAPMGR_TUNNEL_STATE_IPRULE_CONFIGURED;
|
|
- }
|
|
-
|
|
- status = NSS_CAPWAPMGR_FAILURE_CAPWAP_DESTROY_RULE;
|
|
-
|
|
-done:
|
|
+ nss_capwapmgr_info("%px: %d: Tunnel %d is completely destroyed\n", dev, if_num, tunnel_id);
|
|
dev_put(dev);
|
|
- return status;
|
|
+ return NSS_CAPWAPMGR_SUCCESS;
|
|
}
|
|
EXPORT_SYMBOL(nss_capwapmgr_tunnel_destroy);
|
|
|
|
@@ -3083,18 +2873,17 @@ static inline nss_capwapmgr_status_t nss
|
|
struct nss_capwapmgr_tunnel *t;
|
|
nss_capwapmgr_status_t status;
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_warn("%px: can't find tunnel: %d\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
+ dev_hold(dev);
|
|
priv = netdev_priv(dev);
|
|
|
|
memset(&capwapmsg, 0, sizeof(struct nss_capwap_msg));
|
|
- nss_capwap_msg_init(&capwapmsg, t->if_num_outer, cmd,
|
|
+ nss_capwap_msg_init(&capwapmsg, t->if_num, cmd,
|
|
sizeof(struct nss_capwap_flow_rule_msg), nss_capwapmgr_msg_event_receive, dev);
|
|
|
|
/*
|
|
@@ -3121,7 +2910,6 @@ static inline nss_capwapmgr_status_t nss
|
|
nss_capwapmgr_warn("%px: send flow rule message failed with error: %d\n", dev, status);
|
|
}
|
|
|
|
-done:
|
|
dev_put(dev);
|
|
return status;
|
|
}
|
|
@@ -3160,85 +2948,29 @@ nss_capwapmgr_status_t nss_capwapmgr_tun
|
|
uint8_t tunnel_id, struct nss_capwap_tunnel_stats *stats)
|
|
{
|
|
struct nss_capwapmgr_tunnel *t;
|
|
- struct nss_capwap_tunnel_stats stats_temp;
|
|
- nss_capwapmgr_status_t status = NSS_CAPWAPMGR_SUCCESS;
|
|
|
|
if (!stats) {
|
|
nss_capwapmgr_warn("%px: invalid rtnl structure\n", dev);
|
|
return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
- dev_hold(dev);
|
|
t = nss_capwapmgr_verify_tunnel_param(dev, tunnel_id);
|
|
if (!t) {
|
|
nss_capwapmgr_trace("%px: can't find tunnel: %d\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_BAD_PARAM;
|
|
}
|
|
|
|
if (!(t->tunnel_state & NSS_CAPWAPMGR_TUNNEL_STATE_CONFIGURED)) {
|
|
nss_capwapmgr_trace("%px: tunnel: %d not configured yet\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_TUNNEL_NOT_CFG;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_TUNNEL_NOT_CFG;
|
|
}
|
|
|
|
- /*
|
|
- * Copy the inner interface stats.
|
|
- */
|
|
- if (nss_capwap_get_stats(t->if_num_inner, &stats_temp) == false) {
|
|
+ if (nss_capwap_get_stats(t->if_num, stats) == false) {
|
|
nss_capwapmgr_warn("%px: tunnel %d not ready yet\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_NOT_READY;
|
|
- goto done;
|
|
+ return NSS_CAPWAPMGR_FAILURE_NOT_READY;
|
|
}
|
|
|
|
- stats->dtls_pkts += stats_temp.dtls_pkts;
|
|
- stats->tx_segments += stats_temp.tx_segments;
|
|
- stats->tx_queue_full_drops += stats_temp.tx_queue_full_drops;
|
|
- stats->tx_mem_failure_drops += stats_temp.tx_mem_failure_drops;
|
|
- stats->tx_dropped_sg_ref += stats_temp.tx_dropped_sg_ref;
|
|
- stats->tx_dropped_ver_mis += stats_temp.tx_dropped_ver_mis;
|
|
- stats->tx_dropped_hroom += stats_temp.tx_dropped_hroom;
|
|
- stats->tx_dropped_dtls += stats_temp.tx_dropped_dtls;
|
|
- stats->tx_dropped_nwireless += stats_temp.tx_dropped_nwireless;
|
|
-
|
|
- /*
|
|
- * Pnode tx stats for Inner node.
|
|
- */
|
|
- stats->pnode_stats.tx_packets += stats_temp.pnode_stats.tx_packets;
|
|
- stats->pnode_stats.tx_bytes += stats_temp.pnode_stats.tx_bytes;
|
|
- stats->tx_dropped_inner += stats_temp.tx_dropped_inner;
|
|
-
|
|
- /*
|
|
- * Copy the outer interface stats.
|
|
- */
|
|
- if (nss_capwap_get_stats(t->if_num_outer, &stats_temp) == false) {
|
|
- nss_capwapmgr_warn("%px: tunnel %d not ready yet\n", dev, tunnel_id);
|
|
- status = NSS_CAPWAPMGR_FAILURE_NOT_READY;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- stats->rx_segments += stats_temp.rx_segments;
|
|
- stats->dtls_pkts += stats_temp.dtls_pkts;
|
|
- stats->rx_dup_frag += stats_temp.rx_dup_frag;
|
|
- stats->rx_oversize_drops += stats_temp.rx_oversize_drops;
|
|
- stats->rx_frag_timeout_drops += stats_temp.rx_frag_timeout_drops;
|
|
- stats->rx_n2h_drops += stats_temp.rx_n2h_drops;
|
|
- stats->rx_n2h_queue_full_drops += stats_temp.rx_n2h_queue_full_drops;
|
|
- stats->rx_mem_failure_drops += stats_temp.rx_mem_failure_drops;
|
|
- stats->rx_csum_drops += stats_temp.rx_csum_drops;
|
|
- stats->rx_malformed += stats_temp.rx_malformed;
|
|
- stats->rx_frag_gap_drops += stats_temp.rx_frag_gap_drops;
|
|
-
|
|
- /*
|
|
- * Pnode rx stats for outer node.
|
|
- */
|
|
- stats->pnode_stats.rx_packets += stats_temp.pnode_stats.rx_packets;
|
|
- stats->pnode_stats.rx_bytes += stats_temp.pnode_stats.rx_bytes;
|
|
- stats->pnode_stats.rx_dropped += stats_temp.pnode_stats.rx_dropped;
|
|
-
|
|
-done:
|
|
- dev_put(dev);
|
|
- return status;
|
|
+ return NSS_CAPWAPMGR_SUCCESS;
|
|
}
|
|
EXPORT_SYMBOL(nss_capwapmgr_tunnel_stats);
|
|
|
|
@@ -3341,7 +3073,10 @@ EXPORT_SYMBOL(nss_capwapmgr_get_netdev);
|
|
*/
|
|
static int nss_capwapmgr_netdev_up(struct net_device *netdev)
|
|
{
|
|
+ struct nss_capwapmgr_priv *priv;
|
|
uint8_t i;
|
|
+
|
|
+ priv = netdev_priv(netdev);
|
|
for (i = 0; i < NSS_CAPWAPMGR_MAX_TUNNELS; i++) {
|
|
(void)nss_capwapmgr_enable_tunnel(nss_capwapmgr_ndev, i);
|
|
}
|
|
@@ -3355,7 +3090,10 @@ static int nss_capwapmgr_netdev_up(struc
|
|
*/
|
|
static int nss_capwapmgr_netdev_down(struct net_device *netdev)
|
|
{
|
|
+ struct nss_capwapmgr_priv *priv;
|
|
uint8_t i;
|
|
+
|
|
+ priv = netdev_priv(netdev);
|
|
for (i = 0; i < NSS_CAPWAPMGR_MAX_TUNNELS; i++) {
|
|
(void)nss_capwapmgr_disable_tunnel(nss_capwapmgr_ndev, i);
|
|
}
|
|
@@ -3367,7 +3105,7 @@ static int nss_capwapmgr_netdev_down(str
|
|
* nss_capwapmgr_netdev_event()
|
|
* Net device notifier for NSS CAPWAP manager module
|
|
*/
|
|
-static int nss_capwapmgr_netdev_event(struct notifier_block *nb, unsigned long event, void *dev)
|
|
+static int nss_capwapmgr_netdev_event(struct notifier_block *nb, unsigned long event, void *dev)
|
|
{
|
|
struct net_device *netdev = (struct net_device *)dev;
|
|
|
|
--- a/clmapmgr/nss_clmapmgr.c
|
|
+++ b/clmapmgr/nss_clmapmgr.c
|
|
@@ -84,17 +84,16 @@ fail:
|
|
}
|
|
|
|
/*
|
|
- * nss_clmapmgr_get_dev_stats64()
|
|
+ * nss_clmapmgr_dev_stats64()
|
|
* Netdev ops function to retrieve stats.
|
|
*/
|
|
-static struct rtnl_link_stats64 *nss_clmapmgr_get_dev_stats64(struct net_device *dev,
|
|
+void nss_clmapmgr_dev_stats64(struct net_device *dev,
|
|
struct rtnl_link_stats64 *stats)
|
|
{
|
|
struct nss_clmapmgr_priv_t *priv;
|
|
|
|
if (!stats) {
|
|
nss_clmapmgr_warning("%px: invalid rtnl structure\n", dev);
|
|
- return stats;
|
|
}
|
|
|
|
dev_hold(dev);
|
|
@@ -109,30 +108,7 @@ static struct rtnl_link_stats64 *nss_clm
|
|
memcpy(stats, &priv->stats, sizeof(struct rtnl_link_stats64));
|
|
dev_put(dev);
|
|
|
|
- return stats;
|
|
-}
|
|
-
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
|
|
-/*
|
|
- * nss_clmapmgr_dev_stats64()
|
|
- * Netdev ops function to retrieve stats for kernel version < 4.6
|
|
- */
|
|
-static struct rtnl_link_stats64 *nss_clmapmgr_dev_stats64(struct net_device *dev,
|
|
- struct rtnl_link_stats64 *tot)
|
|
-{
|
|
- return nss_clmapmgr_get_dev_stats64(dev, tot);
|
|
-}
|
|
-#else
|
|
-/*
|
|
- * nss_clmapmgr_dev_stats64()
|
|
- * Netdev ops function to retrieve stats for kernel version >= 4.6
|
|
- */
|
|
-static void nss_clmapmgr_dev_stats64(struct net_device *dev,
|
|
- struct rtnl_link_stats64 *tot)
|
|
-{
|
|
- nss_clmapmgr_get_dev_stats64(dev, tot);
|
|
}
|
|
-#endif
|
|
|
|
/*
|
|
* nss_clmapmgr_dev_init()
|
|
--- a/dtls/v1.0/nss_connmgr_dtls_netdev.c
|
|
+++ b/dtls/v1.0/nss_connmgr_dtls_netdev.c
|
|
@@ -160,7 +160,7 @@ static void nss_dtlsmgr_dev_setup(struct
|
|
dev->ethtool_ops = NULL;
|
|
dev->header_ops = NULL;
|
|
dev->netdev_ops = &nss_dtlsmgr_session_ops;
|
|
- dev->destructor = NULL;
|
|
+ dev->priv_destructor = NULL;
|
|
|
|
memcpy(dev->dev_addr, "\xaa\xbb\xcc\xdd\xee\xff", dev->addr_len);
|
|
memset(dev->broadcast, 0xff, dev->addr_len);
|
|
--- a/dtls/v2.0/Makefile
|
|
+++ b/dtls/v2.0/Makefile
|
|
@@ -3,7 +3,7 @@
|
|
ccflags-y += $(NSS_CCFLAGS) -I$(obj)/../../exports
|
|
ccflags-y += -DNSS_DTLSMGR_DEBUG_LEVEL=0
|
|
ccflags-y += -DNSS_DTLSMGR_BUILD_ID=\"'Build_ID - $(shell date +'%m/%d/%y, %H:%M:%S') SoC=$(SoC)'\"
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
|
|
obj-m += qca-nss-dtlsmgr.o
|
|
qca-nss-dtlsmgr-objs += nss_dtlsmgr.o
|
|
--- a/dtls/v2.0/nss_dtlsmgr_ctx.c
|
|
+++ b/dtls/v2.0/nss_dtlsmgr_ctx.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2017-2020, 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.
|
|
@@ -627,7 +627,7 @@ struct net_device *nss_dtlsmgr_session_c
|
|
* so that the skb data pointer remains 4 byte aligned when the
|
|
* headroom/tailroom is adjusted.
|
|
*/
|
|
- dev->needed_headroom = ALIGN(ctx->encap.headroom, 4);
|
|
+ dev->needed_headroom = ALIGN(ctx->encap.headroom + NSS_DTLSMGR_EDMA_PRE_HDR_SZ, 4);
|
|
dev->needed_tailroom = ALIGN(ctx->encap.tailroom, 4);
|
|
|
|
ctx->app_data = cfg->app_data;
|
|
@@ -643,7 +643,7 @@ struct net_device *nss_dtlsmgr_session_c
|
|
ctx->app_data = ctx;
|
|
}
|
|
|
|
- error = register_netdev(dev);
|
|
+ error = rtnl_is_locked() ? register_netdevice(dev) : register_netdev(dev);
|
|
if (error < 0) {
|
|
nss_dtlsmgr_warn("%px: unable register net_device(%s)", ctx, dev->name);
|
|
goto destroy_decap;
|
|
@@ -708,7 +708,7 @@ nss_dtlsmgr_status_t nss_dtlsmgr_session
|
|
|
|
NSS_DTLSMGR_SET_MAGIC(ctx, 0);
|
|
|
|
- unregister_netdev(dev);
|
|
+ rtnl_is_locked() ? unregister_netdevice(dev) : unregister_netdev(dev);
|
|
|
|
return NSS_DTLSMGR_OK;
|
|
}
|
|
--- a/dtls/v2.0/nss_dtlsmgr_ctx_dev.c
|
|
+++ b/dtls/v2.0/nss_dtlsmgr_ctx_dev.c
|
|
@@ -349,7 +349,7 @@ static netdev_tx_t nss_dtlsmgr_ctx_dev_t
|
|
stats = &encap->stats;
|
|
|
|
nhead = dev->needed_headroom;
|
|
- ntail = dev->needed_tailroom + nhead; /* Firmware uses tailroom for header add */
|
|
+ ntail = dev->needed_tailroom;
|
|
|
|
/*
|
|
* Check if skb is shared; unshare in case it is shared
|
|
--- a/eogremgr/nss_eogremgr.c
|
|
+++ b/eogremgr/nss_eogremgr.c
|
|
@@ -19,10 +19,10 @@
|
|
* NSS EOGRE manager
|
|
*/
|
|
|
|
+#include <linux/of.h>
|
|
#include <nss_api_if.h>
|
|
#include <nss_cmn.h>
|
|
#include "nss_connmgr_gre_public.h"
|
|
-#include <linux/of.h>
|
|
#include "nss_eogremgr.h"
|
|
#include "nss_eogremgr_priv.h"
|
|
|
|
@@ -565,15 +565,12 @@ static void __exit nss_eogremgr_exit_mod
|
|
*/
|
|
static int __init nss_eogremgr_init_module(void)
|
|
{
|
|
-
|
|
-#ifdef CONFIG_OF
|
|
/*
|
|
* If the node is not compatible, don't do anything.
|
|
*/
|
|
if (!of_find_node_by_name(NULL, "nss-common")) {
|
|
return 0;
|
|
}
|
|
-#endif
|
|
|
|
nss_eogremgr_info("module %s loaded\n", NSS_CLIENT_BUILD_ID);
|
|
|
|
--- a/exports/nss_capwapmgr.h
|
|
+++ b/exports/nss_capwapmgr.h
|
|
@@ -61,10 +61,8 @@ struct nss_capwapmgr_response {
|
|
*/
|
|
struct nss_capwapmgr_tunnel {
|
|
struct net_device *dtls_dev; /**< DTLS netdevice */
|
|
- uint32_t if_num_inner; /**< Interface number of the INNER CAPWAP node */
|
|
- uint32_t if_num_outer; /**< Interface number of the OUTER CAPWAP node */
|
|
+ uint32_t if_num; /**< Interface number of NSS */
|
|
uint32_t tunnel_state; /**< Tunnel state */
|
|
- uint16_t type_flags; /**< Tunnel Type to determine header size */
|
|
union {
|
|
struct nss_ipv4_create v4; /**< IPv4 rule structure */
|
|
struct nss_ipv6_create v6; /**< IPv6 rule struture */
|
|
@@ -224,7 +222,7 @@ nss_capwapmgr_status_t nss_capwapmgr_upd
|
|
*
|
|
* @return nss_capwapmgr_status_t
|
|
*/
|
|
-extern nss_capwapmgr_status_t nss_capwapmgr_update_src_interface(struct net_device *dev, uint8_t tunnel_id, uint32_t src_interface_num);
|
|
+extern nss_capwapmgr_status_t nss_capwapmgr_update_src_interface(struct net_device *dev, uint8_t tunnel_id, int32_t src_interface_num);
|
|
|
|
/**
|
|
* @brief Delete a DSCP prioritization rule that was created.
|
|
--- a/exports/nss_dtlsmgr.h
|
|
+++ b/exports/nss_dtlsmgr.h
|
|
@@ -60,12 +60,6 @@
|
|
#define NSS_DTLSMGR_METADATA_FLAG_SEQ 0x0002 /**< Metadata has a valid sequence no. */
|
|
#define NSS_DTLSMGR_METADATA_FLAG_CTYPE 0x0004 /**< Metadata has a valid DTLS content type */
|
|
|
|
-/*
|
|
- * NSS DTLS manager reserved size of header
|
|
- */
|
|
-#define NSS_DTLSMGR_NEEDED_HEADROOM_SZ 128
|
|
-#define NSS_DTLSMGR_NEEDED_TAILROOM_SZ 128
|
|
-
|
|
/**
|
|
* NSS DTLS manager status
|
|
*/
|
|
@@ -134,7 +128,7 @@ enum nss_dtlsmgr_metadata_result {
|
|
* NSS DTLS manager cryptographic structure to represent key and its length.
|
|
*/
|
|
struct nss_dtlsmgr_crypto_data {
|
|
- const uint8_t *data; /**< Pointer to key or nonce. */
|
|
+ uint8_t *data; /**< Pointer to key or nonce. */
|
|
uint16_t len; /**< Length of the key. */
|
|
};
|
|
|
|
--- a/exports/nss_ipsecmgr.h
|
|
+++ b/exports/nss_ipsecmgr.h
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2014-2019, 2021 The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2014-2019, 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.
|
|
@@ -252,10 +252,7 @@ struct nss_ipsecmgr_sa_stats {
|
|
uint32_t pkt_count; /**< Number of packets processed. */
|
|
uint32_t pkt_failed; /**< Number of packets failed in processing. */
|
|
uint16_t window_size; /**< Current size of the window. */
|
|
- uint16_t replay_fail_alarm; /**< Alarm for consecutive hash fail. */
|
|
- uint32_t fail_replay_win; /**< Failure in anti-replay; packet outside the window */
|
|
- uint32_t fail_replay_dup; /**< Failure in anti-replay; duplicate records */
|
|
- uint32_t fail_auth; /**< Failure in authenticating the data */
|
|
+ bool replay_fail_alarm; /**< Alarm for consecutive hash fail. */
|
|
};
|
|
|
|
/**
|
|
@@ -270,20 +267,6 @@ struct nss_ipsecmgr_event {
|
|
};
|
|
|
|
/**
|
|
- * nss_ipsecmgr_sa_info
|
|
- * Crypto information for an already created SA.
|
|
- */
|
|
-struct nss_ipsecmgr_sa_info {
|
|
- uint16_t session_idx; /**< Crypto Session index */
|
|
- uint16_t hdr_len; /**< Encap header length */
|
|
- uint16_t trailer_len; /**< Encap Trailer length */
|
|
- uint8_t blk_len; /**< Cipher Block length */
|
|
- uint8_t iv_len; /**< Cipher IV lengh */
|
|
- uint8_t hash_len; /**< Hash lengh */
|
|
- uint8_t res[3]; /**< Reserved */
|
|
-};
|
|
-
|
|
-/**
|
|
* nss_ipsecmgr_sa_cmn_init_keys
|
|
* Fill and initialize common information for SA creation with crypto keys.
|
|
*
|
|
@@ -392,20 +375,6 @@ static inline bool nss_ipsecmgr_sa_cmn_i
|
|
return true;
|
|
}
|
|
|
|
-/**
|
|
- * nss_ipsecmgr_sa_set_transport
|
|
- * Enable transport mode for an SA thats is getting initialized.
|
|
- *
|
|
- * @datatypes
|
|
- * nss_ipsecmgr_sa_cmn \n
|
|
- *
|
|
- * @param[in/out] cmn Pointer to the common IPsec manager SA configuration information.
|
|
- */
|
|
-static inline void nss_ipsecmgr_sa_set_transport(struct nss_ipsecmgr_sa_cmn *cmn)
|
|
-{
|
|
- cmn->transport_mode = true;
|
|
-}
|
|
-
|
|
#ifdef __KERNEL__ /* only kernel will use. */
|
|
|
|
/**
|
|
@@ -439,7 +408,6 @@ struct nss_ipsecmgr_callback {
|
|
struct net_device *skb_dev; /**< Net device to use for Socket Buffer. */
|
|
nss_ipsecmgr_data_callback_t data_cb; /**< Data callback function. */
|
|
nss_ipsecmgr_event_callback_t event_cb; /**< Event callback function. */
|
|
- nss_ipsecmgr_data_callback_t except_cb; /**< Outer exception callback function. */
|
|
};
|
|
|
|
/**
|
|
@@ -654,35 +622,5 @@ nss_ipsecmgr_status_t nss_ipsecmgr_sa_tx
|
|
nss_ipsecmgr_status_t nss_ipsecmgr_sa_tx_outer(struct net_device *tun, struct nss_ipsecmgr_sa_tuple *sa,
|
|
struct sk_buff *skb);
|
|
|
|
-/*
|
|
- * nss_ipsecmgr_cra_name2algo()
|
|
- * Get ipsecmgr algo from cra name.
|
|
- *
|
|
- * @param[in] cra_name Name of the crypto algo.
|
|
- *
|
|
- * @return
|
|
- * nss_ipsecmgr_algo
|
|
- */
|
|
-enum nss_ipsecmgr_algo nss_ipsecmgr_cra_name2algo(const char *cra_name);
|
|
-
|
|
-/*
|
|
- * nss_ipsecmgr_sa_get_info()
|
|
- * Get Crypto information for an already created SA.
|
|
- *
|
|
- * @datatypes
|
|
- * net_device \n
|
|
- * nss_ipsecmgr_sa_tuple \n
|
|
- * nss_ipsecmgr_sa_info
|
|
- *
|
|
- * @param[in] tun Pointer to the network device associated with the tunnel.
|
|
- * @param[in] sa Pointer to the SA tuple for which info is to be retrieved.
|
|
- * @param[out] info Pointer to the SA info to fill.
|
|
- *
|
|
- * @return
|
|
- * Success or failure.
|
|
- */
|
|
-bool nss_ipsecmgr_sa_get_info(struct net_device *tun, struct nss_ipsecmgr_sa_tuple *sa,
|
|
- struct nss_ipsecmgr_sa_info *info);
|
|
-
|
|
#endif /* __KERNEL__ */
|
|
#endif /* __NSS_IPSECMGR_H */
|
|
--- a/exports/nss_l2tpmgr.h
|
|
+++ b/exports/nss_l2tpmgr.h
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2019, 2021 The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2019 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.
|
|
@@ -16,25 +16,22 @@
|
|
#ifndef __NSS_L2TPMGR_H__
|
|
#define __NSS_L2TPMGR_H__
|
|
|
|
-typedef int32_t (*get_ipsec_ifnum_by_dev_callback_t)(struct net_device *);
|
|
-typedef int32_t (*get_ipsec_ifnum_by_ip_addr_callback_t)(uint8_t ipversion, uint32_t *src_ip, uint32_t *dest_ip);
|
|
+typedef struct net_device *(*get_ipsec_tundev_callback_t)(struct net_device *dev);
|
|
|
|
/**
|
|
* l2tpmgr_ipsecmgr_cb
|
|
- * Callback to get the dummy IPSec interface number that was used to register with NSS
|
|
- * by the IPSec manager when given the IPSec Linux dev.
|
|
- * get_ifnum_by_dev: passes net_device ptr to get associated IPsec if_num in KLIPS
|
|
- * get_ifnum_by_ip_addr: passes IPv4 src & dest addr in Big-endian form to get IPsec if_num in XFRM
|
|
+ * Callback to get the dummy IPSec netdev that was
|
|
+ * used to register with NSS by the IPSec manager
|
|
+ * when given the IPSec Linux dev.
|
|
*/
|
|
struct l2tpmgr_ipsecmgr_cb {
|
|
- get_ipsec_ifnum_by_dev_callback_t get_ifnum_by_dev;
|
|
- get_ipsec_ifnum_by_ip_addr_callback_t get_ifnum_by_ip_addr;
|
|
+ get_ipsec_tundev_callback_t cb;
|
|
+ /**< IPSec mgr Callback> */
|
|
};
|
|
|
|
-#if defined(NSS_L2TP_IPSEC_BIND_BY_NETDEV)
|
|
/**
|
|
- * l2tpmgr_register_ipsecmgr_callback_by_netdev
|
|
- * Register IPSecmgr callback function with l2tpmgr by netdev for KLIPS.
|
|
+ * l2tpmgr_register_ipsecmgr_callback
|
|
+ * Register IPSecmgr callback function with l2tpmgr.
|
|
*
|
|
* @datatypes
|
|
* l2tpmgr_ipsecmgr_cb \n
|
|
@@ -44,38 +41,15 @@ struct l2tpmgr_ipsecmgr_cb {
|
|
* @return
|
|
* none
|
|
*/
|
|
-void l2tpmgr_register_ipsecmgr_callback_by_netdev(struct l2tpmgr_ipsecmgr_cb *cb);
|
|
+void l2tpmgr_register_ipsecmgr_callback(struct l2tpmgr_ipsecmgr_cb *cb);
|
|
|
|
/**
|
|
* l2tpmgr_unregister_ipsecmgr_callback
|
|
- * Unregister IPSecmgr callback function with l2tpmgr by netdev for KLIPS.
|
|
+ * Unregister IPSecmgr callback function with l2tpmgr.
|
|
*
|
|
* @return
|
|
* none
|
|
*/
|
|
-void l2tpmgr_unregister_ipsecmgr_callback_by_netdev(void);
|
|
-#endif
|
|
+void l2tpmgr_unregister_ipsecmgr_callback(void);
|
|
|
|
-/**
|
|
- * l2tpmgr_register_ipsecmgr_callback_by_ipaddr
|
|
- * Register IPSecmgr callback function with l2tpmgr by IP address for XFRM.
|
|
- *
|
|
- * @datatypes
|
|
- * l2tpmgr_ipsecmgr_cb \n
|
|
- *
|
|
- * @param[in] cb IPSecmgr callback function to be registered with l2tpmgr.
|
|
- *
|
|
- * @return
|
|
- * none
|
|
- */
|
|
-void l2tpmgr_register_ipsecmgr_callback_by_ipaddr(struct l2tpmgr_ipsecmgr_cb *cb);
|
|
-
|
|
-/**
|
|
- * l2tpmgr_unregister_ipsecmgr_callback_by_ipaddr
|
|
- * Unregister IPSecmgr callback function with l2tpmgr by IP address for XFRM.
|
|
- *
|
|
- * @return
|
|
- * none
|
|
- */
|
|
-void l2tpmgr_unregister_ipsecmgr_callback_by_ipaddr(void);
|
|
#endif
|
|
--- a/gre/Makefile
|
|
+++ b/gre/Makefile
|
|
@@ -1,7 +1,7 @@
|
|
# Makefile for gre client
|
|
ccflags-y += -I$(obj)/../../exports -I$(obj)/../..
|
|
ccflags-y += -DNSS_GRE_DEBUG_LEVEL=0
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
obj-m += qca-nss-gre.o
|
|
qca-nss-gre-objs := nss_connmgr_gre.o nss_connmgr_gre_v4.o nss_connmgr_gre_v6.o
|
|
|
|
--- a/gre/nss_connmgr_gre_v4.c
|
|
+++ b/gre/nss_connmgr_gre_v4.c
|
|
@@ -98,12 +98,9 @@ static int nss_connmgr_gre_v4_get_mac_ad
|
|
neigh = neigh_lookup(&arp_tbl, (const void *)&raddr, rt->dst.dev);
|
|
}
|
|
|
|
- if (neigh) {
|
|
- if (!(neigh->nud_state & NUD_VALID) || !is_valid_ether_addr(neigh->ha)) {
|
|
- nss_connmgr_gre_info("neigh lookup failed for %pI4, state=%x, neigh->ha=%pM\n", &raddr, neigh->nud_state, neigh->ha);
|
|
- neigh_release(neigh);
|
|
- neigh = NULL;
|
|
- }
|
|
+ if (neigh && !is_valid_ether_addr(neigh->ha)) {
|
|
+ neigh_release(neigh);
|
|
+ neigh = NULL;
|
|
}
|
|
|
|
/*
|
|
@@ -122,13 +119,6 @@ static int nss_connmgr_gre_v4_get_mac_ad
|
|
msleep(2000);
|
|
}
|
|
|
|
- if (!(neigh->nud_state & NUD_VALID) || !is_valid_ether_addr(neigh->ha)) {
|
|
- ip_rt_put(rt);
|
|
- nss_connmgr_gre_warning("invalid neigh state (%x) or invalid MAC(%pM) for %pI4\n", neigh->nud_state, neigh->ha, &raddr);
|
|
- neigh_release(neigh);
|
|
- return GRE_ERR_NEIGH_CREATE;
|
|
- }
|
|
-
|
|
if (neigh->dev->type == ARPHRD_LOOPBACK) {
|
|
ip_rt_put(rt);
|
|
neigh_release(neigh);
|
|
@@ -172,14 +162,6 @@ int nss_connmgr_gre_v4_set_config(struct
|
|
}
|
|
}
|
|
|
|
- /*
|
|
- * IP address validate
|
|
- */
|
|
- if ((cfg->src_ip == 0) || (cfg->dest_ip == 0)) {
|
|
- nss_connmgr_gre_warning("Source ip/Destination IP is invalid");
|
|
- return GRE_ERR_INVALID_IP;
|
|
- }
|
|
-
|
|
memset(t, 0, sizeof(struct ip_tunnel));
|
|
|
|
priv->pad_len = (cfg->add_padding) ? GRE_HDR_PAD_LEN : 0;
|
|
--- a/gre/nss_connmgr_gre_v6.c
|
|
+++ b/gre/nss_connmgr_gre_v6.c
|
|
@@ -95,7 +95,8 @@ static int nss_connmgr_gre_v6_get_mac_ad
|
|
/*
|
|
* Find src MAC address
|
|
*/
|
|
- local_dev = (struct net_device *)ipv6_dev_find(&init_net, &src_addr, 1);
|
|
+ local_dev = NULL;
|
|
+ local_dev = (struct net_device *)ipv6_dev_find(&init_net, &src_addr, local_dev);
|
|
if (!local_dev) {
|
|
nss_connmgr_gre_warning("Unable to find local dev for %pI6", src_ip);
|
|
return GRE_ERR_NO_LOCAL_NETDEV;
|
|
@@ -106,7 +107,6 @@ static int nss_connmgr_gre_v6_get_mac_ad
|
|
/*
|
|
* Find dest MAC address
|
|
*/
|
|
-
|
|
rt = nss_connmgr_gre_v6_route_lookup(&init_net, &dst_addr);
|
|
if (!rt) {
|
|
nss_connmgr_gre_warning("Unable to find route lookup for %pI6", dest_ip);
|
|
@@ -118,12 +118,9 @@ static int nss_connmgr_gre_v6_get_mac_ad
|
|
#else
|
|
neigh = rt->dst.ops->neigh_lookup(&rt->dst, NULL, &dst_addr);
|
|
#endif
|
|
- if (neigh) {
|
|
- if (!(neigh->nud_state & NUD_VALID) || !is_valid_ether_addr(neigh->ha)) {
|
|
- nss_connmgr_gre_warning("neigh state is either invalid (%x) or mac address is null (%pM) for %pI6", neigh->nud_state, neigh->ha, dest_ip);
|
|
- neigh_release(neigh);
|
|
- neigh = NULL;
|
|
- }
|
|
+ if (neigh && !is_valid_ether_addr(neigh->ha)) {
|
|
+ neigh_release(neigh);
|
|
+ neigh = NULL;
|
|
}
|
|
|
|
if (!neigh) {
|
|
@@ -143,8 +140,7 @@ static int nss_connmgr_gre_v6_get_mac_ad
|
|
* Release hold on existing route entry, and find the route entry again
|
|
*/
|
|
ip6_rt_put(rt);
|
|
-
|
|
- rt = nss_connmgr_gre_v6_route_lookup(&init_net, &dst_addr);
|
|
+ rt = rt6_lookup(&init_net, &dst_addr, NULL, 0, NULL, 0);
|
|
if (!rt) {
|
|
nss_connmgr_gre_warning("Unable to find route lookup for %pI6\n", dest_ip);
|
|
return GRE_ERR_NEIGH_LOOKUP;
|
|
@@ -155,19 +151,11 @@ static int nss_connmgr_gre_v6_get_mac_ad
|
|
#else
|
|
neigh = rt->dst.ops->neigh_lookup(&rt->dst, NULL, &dst_addr);
|
|
#endif
|
|
-
|
|
- if (!neigh) {
|
|
+ if (!neigh || !is_valid_ether_addr(neigh->ha)) {
|
|
ip6_rt_put(rt);
|
|
nss_connmgr_gre_warning("Err in MAC address, neighbour look up failed\n");
|
|
return GRE_ERR_NEIGH_LOOKUP;
|
|
}
|
|
-
|
|
- if (!(neigh->nud_state & NUD_VALID) || !is_valid_ether_addr(neigh->ha)) {
|
|
- ip6_rt_put(rt);
|
|
- nss_connmgr_gre_warning("Err in MAC address, invalid neigh state (%x) or invalid mac(%pM)\n", neigh->nud_state, neigh->ha);
|
|
- neigh_release(neigh);
|
|
- return GRE_ERR_NEIGH_LOOKUP;
|
|
- }
|
|
}
|
|
|
|
ether_addr_copy(dest_mac, neigh->ha);
|
|
--- a/gre/test/Makefile
|
|
+++ b/gre/test/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
# Makefile for custom gre test module
|
|
ccflags-y += -I$(obj)/../../../exports -I$(obj)/../../.. -I$(obj)/../
|
|
ccflags-y += -DNSS_GRE_DEBUG_LEVEL=0
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
obj-m += qca-nss-gre-test.o
|
|
qca-nss-gre-test-objs := nss_connmgr_gre_test.o
|
|
--- a/gre/test/nss_connmgr_gre_test.c
|
|
+++ b/gre/test/nss_connmgr_gre_test.c
|
|
@@ -229,10 +229,12 @@ static int nss_connmgr_gre_test_open_pro
|
|
/*
|
|
* Proc ops
|
|
*/
|
|
-static const struct file_operations nss_connmgr_gre_test_proc_ops = {
|
|
- .open = nss_connmgr_gre_test_open_proc,
|
|
- .write = nss_connmgr_gre_test_write_proc,
|
|
- .read = seq_read,
|
|
+static const struct proc_ops nss_connmgr_gre_test_proc_ops = {
|
|
+ .proc_open = nss_connmgr_gre_test_open_proc,
|
|
+ .proc_read = seq_read,
|
|
+ .proc_lseek = seq_lseek,
|
|
+ .proc_release = single_release,
|
|
+ .proc_write = nss_connmgr_gre_test_write_proc,
|
|
};
|
|
|
|
/*
|
|
--- a/ipsecmgr/v1.0/Makefile
|
|
+++ b/ipsecmgr/v1.0/Makefile
|
|
@@ -2,7 +2,7 @@
|
|
|
|
ccflags-y := -I$(obj) -I$(obj)/../..
|
|
ccflags-y += -DNSS_CLIENT_BUILD_ID="$(BUILD_ID)"
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
ifeq ($(SoC), fsm9010)
|
|
ccflags-y += -DNSS_IPSECMGR_PMTU_SUPPORT
|
|
endif
|
|
--- a/ipsecmgr/v1.0/nss_ipsecmgr.c
|
|
+++ b/ipsecmgr/v1.0/nss_ipsecmgr.c
|
|
@@ -377,7 +377,7 @@ free:
|
|
* nss_ipsecmgr_tunnel_stats()
|
|
* get tunnel statistics
|
|
*/
|
|
-static struct rtnl_link_stats64 *nss_ipsecmgr_tunnel_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
|
+void nss_ipsecmgr_tunnel_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
|
{
|
|
struct nss_ipsecmgr_priv *priv = netdev_priv(dev);
|
|
|
|
@@ -389,8 +389,6 @@ static struct rtnl_link_stats64 *nss_ips
|
|
read_lock_bh(&ipsecmgr_ctx->lock);
|
|
memcpy(stats, &priv->stats, sizeof(struct rtnl_link_stats64));
|
|
read_unlock_bh(&ipsecmgr_ctx->lock);
|
|
-
|
|
- return stats;
|
|
}
|
|
|
|
/*
|
|
@@ -442,7 +440,7 @@ static void nss_ipsecmgr_tunnel_setup(st
|
|
dev->header_ops = NULL;
|
|
dev->netdev_ops = &nss_ipsecmgr_tunnel_ops;
|
|
|
|
- dev->destructor = nss_ipsecmgr_tunnel_free;
|
|
+ dev->priv_destructor = nss_ipsecmgr_tunnel_free;
|
|
|
|
/*
|
|
* get the MAC address from the ethernet device
|
|
--- a/ipsecmgr/v2.0/Makefile
|
|
+++ b/ipsecmgr/v2.0/Makefile
|
|
@@ -2,7 +2,7 @@
|
|
|
|
ccflags-y += $(NSS_CCFLAGS) -I$(obj)/../../exports
|
|
ccflags-y += -DNSS_CLIENT_BUILD_ID="$(BUILD_ID)"
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
|
|
obj-m += qca-nss-ipsecmgr.o
|
|
qca-nss-ipsecmgr-objs := nss_ipsecmgr.o
|
|
--- a/ipsecmgr/v2.0/nss_ipsecmgr.c
|
|
+++ b/ipsecmgr/v2.0/nss_ipsecmgr.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2017-2020, 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.
|
|
@@ -67,15 +67,6 @@ struct nss_ipsecmgr_drv *ipsecmgr_drv;
|
|
static const struct net_device_ops nss_ipsecmgr_dummy_ndev_ops;
|
|
|
|
/*
|
|
- * nss_ipsecmgr_dummy_free()
|
|
- * Setup function for dummy netdevice.
|
|
- */
|
|
-static void nss_ipsecmgr_dummy_free(struct net_device *dev)
|
|
-{
|
|
- free_netdev(dev);
|
|
-}
|
|
-
|
|
-/*
|
|
* nss_ipsecmgr_dummy_setup()
|
|
* Setup function for dummy netdevice.
|
|
*/
|
|
@@ -86,11 +77,6 @@ static void nss_ipsecmgr_dummy_setup(str
|
|
* transform.
|
|
*/
|
|
dev->mtu = ETH_DATA_LEN;
|
|
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 8))
|
|
- dev->destructor = nss_ipsecmgr_dummy_free;
|
|
-#else
|
|
- dev->priv_destructor = nss_ipsecmgr_dummy_free;
|
|
-#endif
|
|
}
|
|
|
|
/*
|
|
@@ -110,9 +96,12 @@ static void nss_ipsecmgr_rx_notify(void
|
|
static void nss_ipsecmgr_configure(struct work_struct *work)
|
|
{
|
|
enum nss_ipsec_cmn_msg_type type = NSS_IPSEC_CMN_MSG_TYPE_NODE_CONFIG;
|
|
+ struct nss_ipsecmgr_tunnel *tun = netdev_priv(ipsecmgr_drv->dev);
|
|
uint32_t ifnum = ipsecmgr_drv->ifnum;
|
|
struct nss_ipsec_cmn_msg nicm = {0};
|
|
+ struct nss_ipsecmgr_ctx *redir;
|
|
nss_tx_status_t status;
|
|
+ uint32_t vsi_num = 0;
|
|
|
|
/*
|
|
* By making sure that cryptoapi is registered,
|
|
@@ -150,10 +139,6 @@ static void nss_ipsecmgr_configure(struc
|
|
if (ipsecmgr_drv->ipsec_inline) {
|
|
|
|
#ifdef NSS_IPSECMGR_PPE_SUPPORT
|
|
- struct nss_ipsecmgr_tunnel *tun = netdev_priv(ipsecmgr_drv->dev);
|
|
- struct nss_ipsecmgr_ctx *redir;
|
|
- uint32_t vsi_num = 0;
|
|
-
|
|
redir = nss_ipsecmgr_ctx_alloc(tun,
|
|
NSS_IPSEC_CMN_CTX_TYPE_REDIR,
|
|
NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_REDIRECT,
|
|
@@ -213,7 +198,7 @@ static void nss_ipsecmgr_configure(struc
|
|
static int __init nss_ipsecmgr_init(void)
|
|
{
|
|
struct nss_ipsecmgr_tunnel *tun;
|
|
- struct net_device *dev = NULL;
|
|
+ struct net_device *dev;
|
|
int status;
|
|
|
|
ipsecmgr_drv = vzalloc(sizeof(*ipsecmgr_drv));
|
|
@@ -251,7 +236,7 @@ static int __init nss_ipsecmgr_init(void
|
|
status = register_netdev(dev);
|
|
if (status) {
|
|
nss_ipsecmgr_info("%px: Failed to register dummy netdevice(%px)", ipsecmgr_drv, dev);
|
|
- goto free;
|
|
+ goto netdev_free;
|
|
}
|
|
|
|
ipsecmgr_drv->dev = dev;
|
|
@@ -269,31 +254,41 @@ static int __init nss_ipsecmgr_init(void
|
|
* Initialize debugfs.
|
|
*/
|
|
ipsecmgr_drv->dentry = debugfs_create_dir("qca-nss-ipsecmgr", NULL);
|
|
- if (ipsecmgr_drv->dentry) {
|
|
- tun->dentry = debugfs_create_dir(dev->name, ipsecmgr_drv->dentry);
|
|
+ if (!ipsecmgr_drv->dentry) {
|
|
+ nss_ipsecmgr_warn("%px: Failed to create root debugfs entry", ipsecmgr_drv);
|
|
+ nss_ipsec_cmn_notify_unregister(ipsecmgr_drv->nss_ctx, ipsecmgr_drv->ifnum);
|
|
+ goto unregister_dev;
|
|
}
|
|
|
|
/*
|
|
+ * Create debugfs entry for tunnel
|
|
+ */
|
|
+ tun->dentry = debugfs_create_dir(dev->name, ipsecmgr_drv->dentry);
|
|
+
|
|
+ /*
|
|
* Configure inline mode and the DMA rings.
|
|
*/
|
|
nss_ipsecmgr_configure(&ipsecmgr_drv->cfg_work.work);
|
|
|
|
- write_lock_bh(&ipsecmgr_drv->lock);
|
|
+ write_lock(&ipsecmgr_drv->lock);
|
|
list_add(&tun->list, &ipsecmgr_drv->tun_db);
|
|
|
|
ipsecmgr_drv->max_mtu = dev->mtu;
|
|
- write_unlock_bh(&ipsecmgr_drv->lock);
|
|
+ write_unlock(&ipsecmgr_drv->lock);
|
|
|
|
nss_ipsecmgr_info("NSS IPsec manager loaded: %s\n", NSS_CLIENT_BUILD_ID);
|
|
return 0;
|
|
|
|
+unregister_dev:
|
|
+ unregister_netdev(ipsecmgr_drv->dev);
|
|
+
|
|
+netdev_free:
|
|
+ free_netdev(ipsecmgr_drv->dev);
|
|
+
|
|
free:
|
|
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 8))
|
|
- if (dev)
|
|
- dev->destructor(dev);
|
|
-#endif
|
|
vfree(ipsecmgr_drv);
|
|
ipsecmgr_drv = NULL;
|
|
+
|
|
return -1;
|
|
}
|
|
|
|
--- a/ipsecmgr/v2.0/nss_ipsecmgr_ctx.c
|
|
+++ b/ipsecmgr/v2.0/nss_ipsecmgr_ctx.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
* ********************************************************************************
|
|
- * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2018-2020, 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.
|
|
@@ -92,7 +92,6 @@ static const struct nss_ipsecmgr_print i
|
|
{"\texceptioned", NSS_IPSECMGR_PRINT_DWORD},
|
|
{"\tlinearized", NSS_IPSECMGR_PRINT_DWORD},
|
|
{"\tredirected", NSS_IPSECMGR_PRINT_DWORD},
|
|
- {"\tdropped", NSS_IPSECMGR_PRINT_DWORD},
|
|
{"\tfail_sa", NSS_IPSECMGR_PRINT_DWORD},
|
|
{"\tfail_flow", NSS_IPSECMGR_PRINT_DWORD},
|
|
{"\tfail_stats", NSS_IPSECMGR_PRINT_DWORD},
|
|
@@ -100,9 +99,6 @@ static const struct nss_ipsecmgr_print i
|
|
{"\tfail_transform", NSS_IPSECMGR_PRINT_DWORD},
|
|
{"\tfail_linearized", NSS_IPSECMGR_PRINT_DWORD},
|
|
{"\tfail_mdata_ver", NSS_IPSECMGR_PRINT_DWORD},
|
|
- {"\tfail_ctx_active", NSS_IPSECMGR_PRINT_DWORD},
|
|
- {"\tfail_pbuf_crypto", NSS_IPSECMGR_PRINT_DWORD},
|
|
- {"\tfail_queue_crypto", NSS_IPSECMGR_PRINT_DWORD},
|
|
};
|
|
|
|
/*
|
|
@@ -552,8 +548,8 @@ void nss_ipsecmgr_ctx_rx_redir(struct ne
|
|
* If, data callback is available then send the packet to the
|
|
* callback function
|
|
*/
|
|
- if (tun->cb.except_cb) {
|
|
- tun->cb.except_cb(tun->cb.app_data, skb);
|
|
+ if (tun->cb.data_cb) {
|
|
+ tun->cb.data_cb(tun->cb.app_data, skb);
|
|
ctx->hstats.redir_cb++;
|
|
return;
|
|
}
|
|
@@ -609,11 +605,6 @@ void nss_ipsecmgr_ctx_rx_outer(struct ne
|
|
}
|
|
|
|
skb_set_transport_header(skb, sizeof(*iph));
|
|
- if (tun->cb.except_cb) {
|
|
- tun->cb.except_cb(tun->cb.app_data, skb);
|
|
- ctx->hstats.outer_cb++;
|
|
- return;
|
|
- }
|
|
nss_ipsecmgr_ctx_route_ipv4(skb, ctx);
|
|
return;
|
|
}
|
|
@@ -631,11 +622,6 @@ void nss_ipsecmgr_ctx_rx_outer(struct ne
|
|
}
|
|
|
|
skb_set_transport_header(skb, sizeof(*ip6h));
|
|
- if (tun->cb.except_cb) {
|
|
- tun->cb.except_cb(tun->cb.app_data, skb);
|
|
- ctx->hstats.outer_cb++;
|
|
- return;
|
|
- }
|
|
nss_ipsecmgr_ctx_route_ipv6(skb, ctx);
|
|
return;
|
|
}
|
|
@@ -731,7 +717,6 @@ void nss_ipsecmgr_ctx_rx_stats(void *app
|
|
struct nss_ipsecmgr_sa *sa;
|
|
void *app_data;
|
|
|
|
- event.type = NSS_IPSECMGR_EVENT_SA_STATS;
|
|
write_lock(&ipsecmgr_drv->lock);
|
|
|
|
sa = nss_ipsecmgr_sa_find(sa_db, &sync->sa_tuple);
|
|
@@ -874,30 +859,13 @@ struct nss_ipsecmgr_ctx *nss_ipsecmgr_ct
|
|
}
|
|
|
|
/*
|
|
- * nss_ipsecmgr_ctx_attach()
|
|
- * Attach context to the database
|
|
- */
|
|
-void nss_ipsecmgr_ctx_attach(struct list_head *db, struct nss_ipsecmgr_ctx *ctx)
|
|
-{
|
|
- struct nss_ipsecmgr_tunnel *tun = ctx->tun;
|
|
-
|
|
- list_add(&ctx->list, db);
|
|
-
|
|
- /*
|
|
- * Add ctx->ref to tun->ref
|
|
- */
|
|
- write_lock_bh(&ipsecmgr_drv->lock);
|
|
- nss_ipsecmgr_ref_add(&ctx->ref, &tun->ref);
|
|
- write_unlock_bh(&ipsecmgr_drv->lock);
|
|
-}
|
|
-
|
|
-/*
|
|
* nss_ipsecmgr_ctx_config()
|
|
* Configure context
|
|
*/
|
|
bool nss_ipsecmgr_ctx_config(struct nss_ipsecmgr_ctx *ctx)
|
|
{
|
|
enum nss_ipsec_cmn_msg_type msg_type = NSS_IPSEC_CMN_MSG_TYPE_CTX_CONFIG;
|
|
+ struct nss_ipsecmgr_tunnel *tun = ctx->tun;
|
|
struct nss_ipsec_cmn_ctx *ctx_msg;
|
|
struct nss_ipsec_cmn_msg nicm;
|
|
nss_tx_status_t status;
|
|
@@ -907,7 +875,6 @@ bool nss_ipsecmgr_ctx_config(struct nss_
|
|
ctx_msg = &nicm.msg.ctx;
|
|
ctx_msg->type = ctx->state.type;
|
|
ctx_msg->except_ifnum = ctx->state.except_ifnum;
|
|
- ctx_msg->sibling_ifnum = ctx->state.sibling_ifnum;
|
|
|
|
status = nss_ipsec_cmn_tx_msg_sync(ctx->nss_ctx, ctx->ifnum, msg_type, sizeof(*ctx_msg), &nicm);
|
|
if (status != NSS_TX_SUCCESS) {
|
|
@@ -916,6 +883,10 @@ bool nss_ipsecmgr_ctx_config(struct nss_
|
|
return false;
|
|
}
|
|
|
|
+ write_lock_bh(&ipsecmgr_drv->lock);
|
|
+ nss_ipsecmgr_ref_add(&ctx->ref, &tun->ref);
|
|
+ write_unlock_bh(&ipsecmgr_drv->lock);
|
|
+
|
|
return true;
|
|
}
|
|
|
|
@@ -941,7 +912,6 @@ struct nss_ipsecmgr_ctx *nss_ipsecmgr_ct
|
|
uint32_t features)
|
|
{
|
|
struct nss_ipsecmgr_ctx *ctx;
|
|
- int32_t ifnum;
|
|
|
|
ctx = kzalloc(sizeof(*ctx), in_atomic() ? GFP_ATOMIC : GFP_KERNEL);
|
|
if (!ctx) {
|
|
@@ -955,14 +925,13 @@ struct nss_ipsecmgr_ctx *nss_ipsecmgr_ct
|
|
ctx->state.type = ctx_type;
|
|
ctx->state.di_type = di_type;
|
|
|
|
- ifnum = nss_dynamic_interface_alloc_node(di_type);
|
|
- if (ifnum < 0) {
|
|
+ ctx->ifnum = nss_dynamic_interface_alloc_node(di_type);
|
|
+ if (ctx->ifnum < 0) {
|
|
nss_ipsecmgr_warn("%px: failed to allocate dynamic interface(%d)", tun, di_type);
|
|
kfree(ctx);
|
|
return NULL;
|
|
}
|
|
|
|
- ctx->ifnum = ifnum;
|
|
ctx->state.stats_len = ctx->state.print_len = nss_ipsecmgr_ctx_stats_size();
|
|
nss_ipsecmgr_ref_init(&ctx->ref, nss_ipsecmgr_ctx_del_ref, nss_ipsecmgr_ctx_free_ref);
|
|
nss_ipsecmgr_ref_init_print(&ctx->ref, nss_ipsecmgr_ctx_print_len, nss_ipsecmgr_ctx_print);
|
|
--- a/ipsecmgr/v2.0/nss_ipsecmgr_ctx.h
|
|
+++ b/ipsecmgr/v2.0/nss_ipsecmgr_ctx.h
|
|
@@ -43,7 +43,7 @@ struct nss_ipsecmgr_ctx_host_stats {
|
|
uint64_t inner_fail_flow; /* Failed to find flow for inner packet */
|
|
uint64_t outer_exp; /* Host processed inner IPv6 exceptioned packet */
|
|
uint64_t outer_exp_drop; /* Host processed and dropped inner IPv6 exceptioned packet */
|
|
- uint64_t outer_cb; /* Number of times exception call back called for outer packet */
|
|
+ uint64_t outer_cb; /* Number of times data call back called for inner packet */
|
|
uint64_t outer_fail_dev; /* Failed to find netdevice for inner packet */
|
|
uint64_t outer_fail_sa; /* Failed to find SA for outer packet */
|
|
uint64_t outer_fail_flow; /* Failed to find flow for outer packet */
|
|
@@ -70,7 +70,6 @@ struct nss_ipsecmgr_ctx_stats_priv {
|
|
uint64_t exceptioned; /* Exceptioned to host */
|
|
uint64_t linearized; /* Linearized packets */
|
|
uint64_t redirected; /* Redirected from inline */
|
|
- uint64_t dropped; /* Total dropped packets */
|
|
uint64_t fail_sa; /* Failed to find SA */
|
|
uint64_t fail_flow; /* Failed to find flow */
|
|
uint64_t fail_stats; /* Failed to send statistics */
|
|
@@ -78,9 +77,6 @@ struct nss_ipsecmgr_ctx_stats_priv {
|
|
uint64_t fail_transform; /* Failed to transform */
|
|
uint64_t fail_linearized; /* Failed to linearized */
|
|
uint64_t fail_mdata_ver; /* Invalid meta data version */
|
|
- uint64_t fail_ctx_active; /* Failed to queue as ctx is not active. */
|
|
- uint64_t fail_pbuf_crypto; /* Failed to allocate pbuf for crypto operation */
|
|
- uint64_t fail_queue_crypto; /* Failed to queue pbuf to crypto pnode */
|
|
};
|
|
|
|
/*
|
|
@@ -90,7 +86,6 @@ struct nss_ipsecmgr_ctx_state {
|
|
ssize_t print_len; /* Print buffer length */
|
|
ssize_t stats_len; /* Total stats length */
|
|
uint32_t except_ifnum; /* Exception interface number */
|
|
- uint32_t sibling_ifnum; /* Sibling interface number */
|
|
enum nss_ipsec_cmn_ctx_type type; /* Type */
|
|
enum nss_dynamic_interface_type di_type; /* Dynamic interface type */
|
|
};
|
|
@@ -112,19 +107,20 @@ struct nss_ipsecmgr_ctx {
|
|
};
|
|
|
|
/*
|
|
- * Set the exception interface number for context
|
|
+ * nss_ipsecmgr_ctx_attach()
|
|
+ * Attach context to the database
|
|
*/
|
|
-static inline void nss_ipsecmgr_ctx_set_except(struct nss_ipsecmgr_ctx *ctx, uint32_t except_ifnum)
|
|
+static inline void nss_ipsecmgr_ctx_attach(struct list_head *db, struct nss_ipsecmgr_ctx *ctx)
|
|
{
|
|
- ctx->state.except_ifnum = except_ifnum;
|
|
+ list_add(&ctx->list, db);
|
|
}
|
|
|
|
/*
|
|
- * Set the sibling interface number for context
|
|
+ * Set the exception interface number for context
|
|
*/
|
|
-static inline void nss_ipsecmgr_ctx_set_sibling(struct nss_ipsecmgr_ctx *ctx, uint32_t sibling_ifnum)
|
|
+static inline void nss_ipsecmgr_ctx_set_except(struct nss_ipsecmgr_ctx *ctx, uint32_t except_ifnum)
|
|
{
|
|
- ctx->state.sibling_ifnum = sibling_ifnum;
|
|
+ ctx->state.except_ifnum = except_ifnum;
|
|
}
|
|
|
|
extern const struct file_operations ipsecmgr_ctx_file_ops;
|
|
@@ -135,7 +131,6 @@ extern void nss_ipsecmgr_ctx_rx_redir(st
|
|
extern void nss_ipsecmgr_ctx_rx_outer(struct net_device *dev, struct sk_buff *skb, struct napi_struct *napi);
|
|
extern void nss_ipsecmgr_ctx_rx_inner(struct net_device *dev, struct sk_buff *skb, struct napi_struct *napi);
|
|
|
|
-extern void nss_ipsecmgr_ctx_attach(struct list_head *db, struct nss_ipsecmgr_ctx *ctx);
|
|
extern bool nss_ipsecmgr_ctx_config(struct nss_ipsecmgr_ctx *ctx);
|
|
extern void nss_ipsecmgr_ctx_free(struct nss_ipsecmgr_ctx *ctx);
|
|
extern struct nss_ipsecmgr_ctx *nss_ipsecmgr_ctx_alloc(struct nss_ipsecmgr_tunnel *tun,
|
|
--- a/ipsecmgr/v2.0/nss_ipsecmgr_flow.c
|
|
+++ b/ipsecmgr/v2.0/nss_ipsecmgr_flow.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2017-2020, 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.
|
|
@@ -149,10 +149,10 @@ static bool nss_ipsecmgr_flow_update_db(
|
|
|
|
hash_idx = nss_ipsecmgr_flow_tuple2hash(&flow->state.tuple, NSS_IPSECMGR_FLOW_MAX);
|
|
|
|
- write_lock_bh(&ipsecmgr_drv->lock);
|
|
+ write_lock(&ipsecmgr_drv->lock);
|
|
sa = nss_ipsecmgr_sa_find(ipsecmgr_drv->sa_db, sa_tuple);
|
|
if (!sa) {
|
|
- write_unlock_bh(&ipsecmgr_drv->lock);
|
|
+ write_unlock(&ipsecmgr_drv->lock);
|
|
nss_ipsecmgr_trace("%px: failed to find SA during flow update", flow);
|
|
return false;
|
|
}
|
|
@@ -163,7 +163,7 @@ static bool nss_ipsecmgr_flow_update_db(
|
|
*/
|
|
nss_ipsecmgr_ref_add(&flow->ref, &sa->ref);
|
|
list_add(&flow->list, &ipsecmgr_drv->flow_db[hash_idx]);
|
|
- write_unlock_bh(&ipsecmgr_drv->lock);
|
|
+ write_unlock(&ipsecmgr_drv->lock);
|
|
return true;
|
|
}
|
|
|
|
@@ -215,7 +215,7 @@ static void nss_ipsecmgr_flow_del_ref(st
|
|
* Write lock needs to be held by the caller since flow db is
|
|
* getting modified.
|
|
*/
|
|
- nss_ipsecmgr_write_lock_is_held(&ipsecmgr_drv->lock);
|
|
+ BUG_ON(write_can_lock(&ipsecmgr_drv->lock));
|
|
list_del_init(&flow->list);
|
|
}
|
|
|
|
--- a/ipsecmgr/v2.0/nss_ipsecmgr_priv.h
|
|
+++ b/ipsecmgr/v2.0/nss_ipsecmgr_priv.h
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
* ********************************************************************************
|
|
- * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2016-2019, 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.
|
|
@@ -20,8 +20,6 @@
|
|
#define __NSS_IPSECMGR_PRIV_H
|
|
|
|
#include <net/ipv6.h>
|
|
-#include <linux/lockdep.h>
|
|
-#include <linux/version.h>
|
|
|
|
#define NSS_IPSECMGR_DEBUG_LVL_ERROR 1 /**< Turn on debug for an error. */
|
|
#define NSS_IPSECMGR_DEBUG_LVL_WARN 2 /**< Turn on debug for a warning. */
|
|
@@ -78,16 +76,6 @@
|
|
#define NSS_IPSECMGR_PRINT_SHORT NSS_IPSECMGR_PRINT_BYTES(2)
|
|
#define NSS_IPSECMGR_PRINT_BYTE NSS_IPSECMGR_PRINT_BYTES(1)
|
|
#define NSS_IPSECMGR_PRINT_IPADDR (NSS_IPSECMGR_PRINT_WORD * 4)
|
|
-/*
|
|
- * Check if lock is held
|
|
- */
|
|
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 14, 196))
|
|
-#define nss_ipsecmgr_write_lock_is_held(x) BUG_ON(write_can_lock(x))
|
|
-#define nss_ipsecmgr_lock_is_held(x) BUG_ON(read_can_lock(x))
|
|
-#else
|
|
-#define nss_ipsecmgr_lock_is_held(x) lockdep_assert_held(x)
|
|
-#define nss_ipsecmgr_write_lock_is_held(x) lockdep_assert_held_write(x)
|
|
-#endif
|
|
|
|
/*
|
|
* Statistics dump information
|
|
--- a/ipsecmgr/v2.0/nss_ipsecmgr_ref.c
|
|
+++ b/ipsecmgr/v2.0/nss_ipsecmgr_ref.c
|
|
@@ -140,7 +140,7 @@ ssize_t nss_ipsecmgr_ref_print(struct ns
|
|
/*
|
|
* DEBUG check to see if the lock is taken before touching the list
|
|
*/
|
|
- nss_ipsecmgr_write_lock_is_held(&ipsecmgr_drv->lock);
|
|
+ BUG_ON(write_can_lock(&ipsecmgr_drv->lock));
|
|
|
|
len += ref->print(ref, buf);
|
|
|
|
@@ -163,7 +163,7 @@ ssize_t nss_ipsecmgr_ref_print_len(struc
|
|
/*
|
|
* DEBUG check to see if the lock is taken before touching the list
|
|
*/
|
|
- nss_ipsecmgr_write_lock_is_held(&ipsecmgr_drv->lock);
|
|
+ BUG_ON(write_can_lock(&ipsecmgr_drv->lock));
|
|
|
|
list_for_each_entry(entry, &ref->head, node) {
|
|
total_len += nss_ipsecmgr_ref_print_len(entry);
|
|
@@ -203,7 +203,7 @@ void nss_ipsecmgr_ref_del(struct nss_ips
|
|
/*
|
|
* DEBUG check to see if the lock is taken before touching the list
|
|
*/
|
|
- nss_ipsecmgr_write_lock_is_held(&ipsecmgr_drv->lock);
|
|
+ BUG_ON(write_can_lock(&ipsecmgr_drv->lock));
|
|
|
|
while (!list_empty(&ref->head)) {
|
|
entry = list_first_entry(&ref->head, struct nss_ipsecmgr_ref, node);
|
|
@@ -231,7 +231,7 @@ void nss_ipsecmgr_ref_add(struct nss_ips
|
|
/*
|
|
* DEBUG check to see if the lock is taken before touching the list
|
|
*/
|
|
- nss_ipsecmgr_write_lock_is_held(&ipsecmgr_drv->lock);
|
|
+ BUG_ON(write_can_lock(&ipsecmgr_drv->lock));
|
|
|
|
/*
|
|
* if child is already part of an existing chain then remove it before
|
|
--- a/ipsecmgr/v2.0/nss_ipsecmgr_ref.h
|
|
+++ b/ipsecmgr/v2.0/nss_ipsecmgr_ref.h
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
* ********************************************************************************
|
|
- * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2016-2019, 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.
|
|
@@ -42,12 +42,6 @@ struct nss_ipsecmgr_ref {
|
|
nss_ipsecmgr_ref_method_t del; /* unlink function */
|
|
};
|
|
|
|
-/* Check if the reference tree is empty */
|
|
-static inline bool nss_ipsecmgr_ref_is_empty(struct nss_ipsecmgr_ref *ref)
|
|
-{
|
|
- return list_empty(&ref->head);
|
|
-}
|
|
-
|
|
/* functions to operate on reference object */
|
|
extern ssize_t nss_ipsecmgr_ref_print_len(struct nss_ipsecmgr_ref *ref);
|
|
extern ssize_t nss_ipsecmgr_ref_print(struct nss_ipsecmgr_ref *ref, char *buf);
|
|
--- a/ipsecmgr/v2.0/nss_ipsecmgr_sa.c
|
|
+++ b/ipsecmgr/v2.0/nss_ipsecmgr_sa.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2016-2020, 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.
|
|
@@ -130,7 +130,6 @@ static const struct nss_ipsecmgr_print i
|
|
{"\tfail_transform", NSS_IPSECMGR_PRINT_DWORD},
|
|
{"\tfail_crypto", NSS_IPSECMGR_PRINT_DWORD},
|
|
{"\tfail_classification", NSS_IPSECMGR_PRINT_DWORD},
|
|
- {"\tis_stopped", NSS_IPSECMGR_PRINT_DWORD},
|
|
};
|
|
|
|
/*
|
|
@@ -364,7 +363,6 @@ static nss_ipsecmgr_status_t nss_ipsecmg
|
|
if (!rt_keys) {
|
|
nss_ipsecmgr_warn("%px: failed to allocate key memory\n", sa);
|
|
crypto_free_aead(sa->aead);
|
|
- sa->aead = NULL;
|
|
return NSS_IPSECMGR_FAIL_NOMEM;
|
|
}
|
|
|
|
@@ -390,7 +388,6 @@ static nss_ipsecmgr_status_t nss_ipsecmg
|
|
if (crypto_aead_setkey(sa->aead, rt_keys, keylen)) {
|
|
nss_ipsecmgr_warn("%px: failed to configure keys\n", sa);
|
|
crypto_free_aead(sa->aead);
|
|
- sa->aead = NULL;
|
|
vfree(rt_keys);
|
|
return NSS_IPSECMGR_INVALID_KEYLEN;
|
|
}
|
|
@@ -417,7 +414,6 @@ static nss_ipsecmgr_status_t nss_ipsecmg
|
|
if (crypto_ahash_setkey(sa->ahash, keys->auth_key, keys->auth_keylen)) {
|
|
nss_ipsecmgr_warn("%px: failed to configure keys\n", sa);
|
|
crypto_free_ahash(sa->ahash);
|
|
- sa->ahash = NULL;
|
|
return NSS_IPSECMGR_INVALID_KEYLEN;
|
|
}
|
|
|
|
@@ -448,7 +444,6 @@ static nss_ipsecmgr_status_t nss_ipsecmg
|
|
if (!rt_keys) {
|
|
nss_ipsecmgr_warn("%px: failed to allocate key memory\n", sa);
|
|
crypto_free_aead(sa->aead);
|
|
- sa->aead = NULL;
|
|
return NSS_IPSECMGR_FAIL_NOMEM;
|
|
}
|
|
|
|
@@ -458,7 +453,6 @@ static nss_ipsecmgr_status_t nss_ipsecmg
|
|
if (crypto_aead_setkey(sa->aead, rt_keys, keylen)) {
|
|
nss_ipsecmgr_warn("%px: failed to configure keys\n", sa);
|
|
crypto_free_aead(sa->aead);
|
|
- sa->aead = NULL;
|
|
vfree(rt_keys);
|
|
return NSS_IPSECMGR_INVALID_KEYLEN;
|
|
}
|
|
@@ -486,15 +480,11 @@ static nss_ipsecmgr_status_t nss_ipsecmg
|
|
*/
|
|
static void nss_ipsecmgr_sa_free(struct nss_ipsecmgr_sa *sa)
|
|
{
|
|
- if (sa->aead) {
|
|
+ if (sa->aead)
|
|
crypto_free_aead(sa->aead);
|
|
- sa->aead = NULL;
|
|
- }
|
|
|
|
- if (sa->ahash) {
|
|
+ if (sa->ahash)
|
|
crypto_free_ahash(sa->ahash);
|
|
- sa->ahash = NULL;
|
|
- }
|
|
|
|
kfree(sa);
|
|
}
|
|
@@ -513,7 +503,7 @@ static void nss_ipsecmgr_sa_del_ref(stru
|
|
* Linux does not provide any specific API(s) to test for RW locks. The caller
|
|
* being internal is assumed to hold write lock before initiating this.
|
|
*/
|
|
- nss_ipsecmgr_write_lock_is_held(&ipsecmgr_drv->lock);
|
|
+ BUG_ON(write_can_lock(&ipsecmgr_drv->lock));
|
|
|
|
list_del_init(&sa->list);
|
|
|
|
@@ -789,10 +779,6 @@ void nss_ipsecmgr_sa_sync2stats(struct n
|
|
stats->seq_start = sync->replay.seq_start;
|
|
stats->seq_cur = sync->replay.seq_cur;
|
|
}
|
|
-
|
|
- stats->fail_replay_win = sa_stats->fail_replay_win;
|
|
- stats->fail_replay_dup = sa_stats->fail_replay_dup;
|
|
- stats->fail_auth = sa_stats->fail_auth;
|
|
}
|
|
|
|
/*
|
|
@@ -809,7 +795,7 @@ void nss_ipsecmgr_sa_sync_state(struct n
|
|
* DEBUG check to see if the lock is taken before accessing
|
|
* SA entry in the database
|
|
*/
|
|
- nss_ipsecmgr_write_lock_is_held(&ipsecmgr_drv->lock);
|
|
+ BUG_ON(write_can_lock(&ipsecmgr_drv->lock));
|
|
|
|
for (num = 0; num < sizeof(sa->stats)/sizeof(*sa_stats); num++) {
|
|
sa_stats[num] += msg_stats[num];
|
|
@@ -1082,85 +1068,6 @@ bool nss_ipsecmgr_sa_verify(struct net_d
|
|
EXPORT_SYMBOL(nss_ipsecmgr_sa_verify);
|
|
|
|
/*
|
|
- * nss_ipsecmgr_cra_name2algo()
|
|
- * Returns nss_ipsecmgr_algo
|
|
- */
|
|
-enum nss_ipsecmgr_algo nss_ipsecmgr_cra_name2algo(const char *cra_name)
|
|
-{
|
|
- enum nss_ipsecmgr_algo algo = NSS_IPSECMGR_ALGO_AES_CBC_SHA1_HMAC;
|
|
- const char **algo_name = ipsecmgr_algo_name;
|
|
-
|
|
- for (; algo < NSS_IPSECMGR_ALGO_MAX; algo++, algo_name++) {
|
|
- if (!strncmp(cra_name, *algo_name, strlen(*algo_name))) {
|
|
- return algo;
|
|
- }
|
|
- }
|
|
-
|
|
- return NSS_IPSECMGR_ALGO_MAX;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_ipsecmgr_cra_name2algo);
|
|
-
|
|
-/*
|
|
- * nss_ipsecmgr_sa_get_info()
|
|
- * Get Crypto information for an already created SA.
|
|
- */
|
|
-bool nss_ipsecmgr_sa_get_info(struct net_device *dev, struct nss_ipsecmgr_sa_tuple *tuple,
|
|
- struct nss_ipsecmgr_sa_info *sa_info)
|
|
-{
|
|
- struct nss_ipsec_cmn_sa_tuple sa_tuple = {0};
|
|
- struct nss_ipsecmgr_sa *sa;
|
|
- uint32_t mask;
|
|
-
|
|
- /*
|
|
- * Look for an existing SA.
|
|
- */
|
|
- nss_ipsecmgr_sa2tuple(tuple, &sa_tuple);
|
|
-
|
|
- read_lock_bh(&ipsecmgr_drv->lock);
|
|
- sa = nss_ipsecmgr_sa_find(ipsecmgr_drv->sa_db, &sa_tuple);
|
|
- if (!sa) {
|
|
- read_unlock_bh(&ipsecmgr_drv->lock);
|
|
- return false;
|
|
- }
|
|
-
|
|
- sa_info->blk_len = sa->state.data.blk_len;
|
|
- sa_info->iv_len = sa->state.data.iv_len;
|
|
- sa_info->hash_len = sa->state.data.icv_len;
|
|
- sa_info->session_idx = sa->state.tuple.crypto_index;
|
|
-
|
|
- sa_info->hdr_len = sizeof(struct ip_esp_hdr) + sa_info->iv_len;
|
|
- mask = NSS_IPSEC_CMN_FLAG_HDR_MASK | NSS_IPSEC_CMN_FLAG_MODE_TRANS;
|
|
-
|
|
- switch (sa->state.data.flags & mask) {
|
|
- case NSS_IPSEC_CMN_FLAG_IPV4_NATT | NSS_IPSEC_CMN_FLAG_MODE_TRANS:
|
|
- sa_info->hdr_len += sizeof(struct udphdr);
|
|
- break;
|
|
- case NSS_IPSEC_CMN_FLAG_IPV6 | NSS_IPSEC_CMN_FLAG_MODE_TRANS:
|
|
- case NSS_IPSEC_CMN_FLAG_MODE_TRANS:
|
|
- break;
|
|
- case NSS_IPSEC_CMN_FLAG_IPV4_NATT:
|
|
- sa_info->hdr_len += sizeof(struct iphdr) + sizeof(struct udphdr);
|
|
- break;
|
|
- case NSS_IPSEC_CMN_FLAG_IPV6:
|
|
- sa_info->hdr_len += sizeof(struct ipv6hdr);
|
|
- break;
|
|
- default:
|
|
- sa_info->hdr_len += sizeof(struct iphdr);
|
|
- break;
|
|
- }
|
|
-
|
|
- read_unlock_bh(&ipsecmgr_drv->lock);
|
|
-
|
|
- /*
|
|
- * The user of trailer_len should take care of the odd length.
|
|
- */
|
|
- sa_info->trailer_len = sa_info->blk_len + 1 + sa_info->hash_len;
|
|
-
|
|
- return true;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_ipsecmgr_sa_get_info);
|
|
-
|
|
-/*
|
|
* nss_ipsecmgr_sa_tx_inner()
|
|
* Offload given SKB to NSS for inner processing.
|
|
*/
|
|
--- a/ipsecmgr/v2.0/nss_ipsecmgr_sa.h
|
|
+++ b/ipsecmgr/v2.0/nss_ipsecmgr_sa.h
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
* ********************************************************************************
|
|
- * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2016-2019, 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.
|
|
@@ -62,8 +62,7 @@ struct nss_ipsecmgr_sa_stats_priv {
|
|
uint64_t fail_hash_len; /**< Failure in decap due to bad hash block len. */
|
|
uint64_t fail_transform; /**< Failure in transformation; general error. */
|
|
uint64_t fail_crypto; /**< Failure in crypto transformation. */
|
|
- uint64_t fail_cle; /**< Failure in classification; general failure */
|
|
- uint64_t is_stopped; /**< Indicates if SA is stopped; eg: seq overflow */
|
|
+ uint64_t fail_cle; /* Failure in classification; general failure */
|
|
};
|
|
|
|
/*
|
|
--- a/ipsecmgr/v2.0/nss_ipsecmgr_tunnel.c
|
|
+++ b/ipsecmgr/v2.0/nss_ipsecmgr_tunnel.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2017-2020, 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.
|
|
@@ -128,14 +128,6 @@ static netdev_tx_t nss_ipsecmgr_tunnel_t
|
|
}
|
|
|
|
/*
|
|
- * Linearize the nonlinear SKB.
|
|
- */
|
|
- if (skb_linearize(skb)) {
|
|
- nss_ipsecmgr_trace("%s: unable to Linearize SKB\n", dev->name);
|
|
- goto free;
|
|
- }
|
|
-
|
|
- /*
|
|
* For all these cases
|
|
* - create a writable copy of buffer
|
|
* - increase the head room
|
|
@@ -227,10 +219,10 @@ free:
|
|
}
|
|
|
|
/*
|
|
- * nss_ipsecmgr_tunnel_get_stats64()
|
|
+ * nss_ipsecmgr_tunnel_stats64()
|
|
* Get device statistics
|
|
*/
|
|
-static struct rtnl_link_stats64 *nss_ipsecmgr_tunnel_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
|
+static struct rtnl_link_stats64 *nss_ipsecmgr_tunnel_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
|
{
|
|
struct nss_ipsecmgr_tunnel *tun = netdev_priv(dev);
|
|
struct list_head *head = &tun->ctx_db;
|
|
@@ -248,22 +240,6 @@ static struct rtnl_link_stats64 *nss_ips
|
|
}
|
|
|
|
/*
|
|
- * nss_ipsecmgr_tunnel_stats64()
|
|
- * Sync statistics to linux
|
|
- */
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0))
|
|
-static struct rtnl_link_stats64 *nss_ipsecmgr_tunnel_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
|
-{
|
|
- return nss_ipsecmgr_tunnel_get_stats64(dev, stats);
|
|
-}
|
|
-#else
|
|
-static void nss_ipsecmgr_tunnel_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
|
-{
|
|
- nss_ipsecmgr_tunnel_get_stats64(dev, stats);
|
|
-}
|
|
-#endif
|
|
-
|
|
-/*
|
|
* nss_ipsecmgr_tunnel_mtu_update()
|
|
* Update tunnel max MTU
|
|
*/
|
|
@@ -273,7 +249,7 @@ static void nss_ipsecmgr_tunnel_mtu_upda
|
|
uint16_t max_mtu = 0;
|
|
bool update_mtu = false;
|
|
|
|
- write_lock_bh(&ipsecmgr_drv->lock);
|
|
+ write_lock(&ipsecmgr_drv->lock);
|
|
list_for_each_entry(tun, head, list) {
|
|
if (tun->dev->mtu > max_mtu)
|
|
max_mtu = tun->dev->mtu;
|
|
@@ -284,7 +260,7 @@ static void nss_ipsecmgr_tunnel_mtu_upda
|
|
update_mtu = true;
|
|
}
|
|
|
|
- write_unlock_bh(&ipsecmgr_drv->lock);
|
|
+ write_unlock(&ipsecmgr_drv->lock);
|
|
|
|
#ifdef NSS_IPSECMGR_PPE_SUPPORT
|
|
/*
|
|
@@ -337,29 +313,7 @@ static const struct net_device_ops ipsec
|
|
*/
|
|
static void nss_ipsecmgr_tunnel_free(struct net_device *dev)
|
|
{
|
|
- struct nss_ipsecmgr_tunnel *tun = netdev_priv(dev);
|
|
- struct nss_ipsecmgr_ref *ref, *tmp;
|
|
- struct list_head free_refs;
|
|
-
|
|
nss_ipsecmgr_info("IPsec tunnel device(%s) freed\n", dev->name);
|
|
-
|
|
- INIT_LIST_HEAD(&free_refs);
|
|
-
|
|
- /*
|
|
- * Remove context(s) from the tunnel reference tree if it has been
|
|
- * added
|
|
- */
|
|
- write_lock_bh(&ipsecmgr_drv->lock);
|
|
- if (!nss_ipsecmgr_ref_is_empty(&tun->ref)) {
|
|
- nss_ipsecmgr_ref_del(&tun->ref, &free_refs);
|
|
- }
|
|
-
|
|
- write_unlock_bh(&ipsecmgr_drv->lock);
|
|
-
|
|
- list_for_each_entry_safe(ref, tmp, &free_refs, node) {
|
|
- ref->free(ref);
|
|
- }
|
|
-
|
|
free_netdev(dev);
|
|
}
|
|
|
|
@@ -397,14 +351,13 @@ static void nss_ipsecmgr_tunnel_free_ref
|
|
{
|
|
struct nss_ipsecmgr_tunnel *tun = container_of(ref, struct nss_ipsecmgr_tunnel, ref);
|
|
|
|
+ nss_ipsecmgr_tunnel_mtu_update(&ipsecmgr_drv->tun_db);
|
|
+
|
|
/*
|
|
* The unregister should start here but the expectation is that the free would
|
|
* happen when the reference count goes down to '0'
|
|
*/
|
|
- if (tun->dev->reg_state == NETREG_REGISTERED) {
|
|
- nss_ipsecmgr_tunnel_mtu_update(&ipsecmgr_drv->tun_db);
|
|
- rtnl_is_locked() ? unregister_netdevice(tun->dev) : unregister_netdev(tun->dev);
|
|
- }
|
|
+ rtnl_is_locked() ? unregister_netdevice(tun->dev) : unregister_netdev(tun->dev);
|
|
}
|
|
|
|
/*
|
|
@@ -436,11 +389,7 @@ static void nss_ipsecmgr_tunnel_setup(st
|
|
dev->header_ops = NULL;
|
|
dev->netdev_ops = &ipsecmgr_dev_ops;
|
|
|
|
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 8))
|
|
dev->destructor = nss_ipsecmgr_tunnel_free;
|
|
-#else
|
|
- dev->priv_destructor = nss_ipsecmgr_tunnel_free;
|
|
-#endif
|
|
|
|
/*
|
|
* Get the MAC address from the ethernet device
|
|
@@ -524,11 +473,9 @@ struct net_device *nss_ipsecmgr_tunnel_a
|
|
NSS_IPSEC_CMN_FEATURE_INLINE_ACCEL);
|
|
if (!inner) {
|
|
nss_ipsecmgr_warn("%px: failed to allocate context inner\n", tun);
|
|
- goto free;
|
|
+ goto free_dev;
|
|
}
|
|
|
|
- nss_ipsecmgr_ctx_attach(&tun->ctx_db, inner);
|
|
-
|
|
/*
|
|
* Inner Metadata context allocation
|
|
*/
|
|
@@ -540,10 +487,9 @@ struct net_device *nss_ipsecmgr_tunnel_a
|
|
0);
|
|
if (!mdata_inner) {
|
|
nss_ipsecmgr_warn("%px: failed to allocate context metadata inner\n", tun);
|
|
- goto free;
|
|
+ goto free_inner;
|
|
}
|
|
|
|
- nss_ipsecmgr_ctx_attach(&tun->ctx_db, mdata_inner);
|
|
/*
|
|
* Outer context allocation
|
|
*/
|
|
@@ -555,10 +501,9 @@ struct net_device *nss_ipsecmgr_tunnel_a
|
|
NSS_IPSEC_CMN_FEATURE_INLINE_ACCEL);
|
|
if (!outer) {
|
|
nss_ipsecmgr_warn("%px: failed to allocate context outer\n", tun);
|
|
- goto free;
|
|
+ goto free_mdata_inner;
|
|
}
|
|
|
|
- nss_ipsecmgr_ctx_attach(&tun->ctx_db, outer);
|
|
/*
|
|
* Outer metadata context allocation
|
|
*/
|
|
@@ -570,9 +515,13 @@ struct net_device *nss_ipsecmgr_tunnel_a
|
|
0);
|
|
if (!mdata_outer) {
|
|
nss_ipsecmgr_warn("%px: failed to allocate context metadata outer\n", tun);
|
|
- goto free;
|
|
+ goto free_outer;
|
|
}
|
|
|
|
+ nss_ipsecmgr_ctx_attach(&tun->ctx_db, inner);
|
|
+ nss_ipsecmgr_ctx_attach(&tun->ctx_db, mdata_inner);
|
|
+
|
|
+ nss_ipsecmgr_ctx_attach(&tun->ctx_db, outer);
|
|
nss_ipsecmgr_ctx_attach(&tun->ctx_db, mdata_outer);
|
|
|
|
/*
|
|
@@ -587,49 +536,35 @@ struct net_device *nss_ipsecmgr_tunnel_a
|
|
nss_ipsecmgr_ctx_set_except(outer, inner->ifnum);
|
|
nss_ipsecmgr_ctx_set_except(mdata_outer, inner->ifnum);
|
|
|
|
- /*
|
|
- * We need to setup the sibling interface number for inner & outer;
|
|
- * The sibling interface is used by the NSS to configure SA on sibling.
|
|
- */
|
|
- nss_ipsecmgr_ctx_set_sibling(inner, mdata_inner->ifnum);
|
|
- nss_ipsecmgr_ctx_set_sibling(outer, mdata_outer->ifnum);
|
|
-
|
|
if (!nss_ipsecmgr_ctx_config(inner)) {
|
|
nss_ipsecmgr_warn("%px: failed to configure inner context\n", tun);
|
|
- goto free;
|
|
+ goto free_mdata_outer;
|
|
}
|
|
|
|
if (!nss_ipsecmgr_ctx_config(mdata_inner)) {
|
|
nss_ipsecmgr_warn("%px: failed to configure metadata inner context\n", tun);
|
|
- goto free;
|
|
+ goto free_mdata_outer;
|
|
}
|
|
|
|
if (!nss_ipsecmgr_ctx_config(outer)) {
|
|
nss_ipsecmgr_warn("%px: failed to configure outer context\n", tun);
|
|
- goto free;
|
|
+ goto free_mdata_outer;
|
|
}
|
|
|
|
if (!nss_ipsecmgr_ctx_config(mdata_outer)) {
|
|
nss_ipsecmgr_warn("%px: failed to configure metadata outer context\n", tun);
|
|
- goto free;
|
|
+ goto free_mdata_outer;
|
|
}
|
|
|
|
status = rtnl_is_locked() ? register_netdevice(dev) : register_netdev(dev);
|
|
if (status < 0) {
|
|
nss_ipsecmgr_warn("%px: register net dev failed :%s\n", tun, dev->name);
|
|
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 8))
|
|
- goto free;
|
|
-#else
|
|
- /*
|
|
- * Later kernels invoke the destructor upon failure
|
|
- */
|
|
- return NULL;
|
|
-#endif
|
|
+ goto free_mdata_outer;
|
|
}
|
|
|
|
- write_lock_bh(&ipsecmgr_drv->lock);
|
|
+ write_lock(&ipsecmgr_drv->lock);
|
|
list_add(&tun->list, &ipsecmgr_drv->tun_db);
|
|
- write_unlock_bh(&ipsecmgr_drv->lock);
|
|
+ write_unlock(&ipsecmgr_drv->lock);
|
|
|
|
nss_ipsecmgr_tunnel_mtu(dev, skb_dev ? skb_dev->mtu : dev->mtu);
|
|
|
|
@@ -645,12 +580,16 @@ struct net_device *nss_ipsecmgr_tunnel_a
|
|
}
|
|
|
|
return dev;
|
|
-free:
|
|
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 8))
|
|
- dev->destructor(dev);
|
|
-#else
|
|
- dev->priv_destructor(dev);
|
|
-#endif
|
|
+free_mdata_outer:
|
|
+ nss_ipsecmgr_ctx_free(mdata_outer);
|
|
+free_outer:
|
|
+ nss_ipsecmgr_ctx_free(outer);
|
|
+free_mdata_inner:
|
|
+ nss_ipsecmgr_ctx_free(mdata_inner);
|
|
+free_inner:
|
|
+ nss_ipsecmgr_ctx_free(inner);
|
|
+free_dev:
|
|
+ free_netdev(dev);
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL(nss_ipsecmgr_tunnel_add);
|
|
--- a/ipsecmgr/v2.0/plugins/klips/Makefile
|
|
+++ b/ipsecmgr/v2.0/plugins/klips/Makefile
|
|
@@ -10,7 +10,7 @@ ccflags-y += -I$(obj)/../../include
|
|
ccflags-y += -I$(obj)/
|
|
ccflags-y += -DNSS_IPSEC_KLIPS_DEBUG_LEVEL=3
|
|
ccflags-y += -DNSS_IPSEC_KLIPS_BUILD_ID="$(BUILD_ID)"
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
ifeq ($(SoC),$(filter $(SoC),ipq807x ipq807x_64))
|
|
ccflags-y += -DNSS_CFI_IPQ807X_SUPPORT
|
|
endif
|
|
@@ -18,7 +18,3 @@ endif
|
|
ifeq ($(SoC),$(filter $(SoC),ipq60xx ipq60xx_64))
|
|
ccflags-y += -DNSS_CFI_IPQ60XX_SUPPORT
|
|
endif
|
|
-
|
|
-ifeq ($(SoC),$(filter $(SoC),ipq50xx ipq50xx_64))
|
|
-ccflags-y += -DNSS_CFI_IPQ50XX_SUPPORT
|
|
-endif
|
|
--- a/ipsecmgr/v2.0/plugins/klips/nss_ipsec_klips.c
|
|
+++ b/ipsecmgr/v2.0/plugins/klips/nss_ipsec_klips.c
|
|
@@ -1,5 +1,4 @@
|
|
-/*
|
|
- * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
|
+/* Copyright (c) 2018-2020, 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
|
|
@@ -13,10 +12,11 @@
|
|
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
+ *
|
|
+ *
|
|
*/
|
|
|
|
-/*
|
|
- * nss_ipsec_klips.c
|
|
+/* nss_ipsec_klips.c
|
|
* NSS IPsec offload glue for Openswan/KLIPS
|
|
*/
|
|
#include <linux/version.h>
|
|
@@ -51,9 +51,6 @@
|
|
#if defined(NSS_L2TPV2_ENABLED)
|
|
#include <nss_l2tpmgr.h>
|
|
#endif
|
|
-#if defined(NSS_VXLAN_ENABLED)
|
|
-#include <nss_vxlanmgr.h>
|
|
-#endif
|
|
#include "nss_ipsec_klips.h"
|
|
|
|
#define NSS_IPSEC_KLIPS_BASE_NAME "ipsec"
|
|
@@ -62,7 +59,6 @@
|
|
#define NSS_IPSEC_KLIPS_FLAG_NATT 0x00000001
|
|
#define NSS_IPSEC_KLIPS_FLAG_TRANSPORT_MODE 0x00000002
|
|
#define NSS_IPSEC_KLIPS_SKB_CB_MAGIC 0xAAAB
|
|
-#define NSS_IPSEC_KLIPS_IP6_ADDR_LEN 4
|
|
|
|
/*
|
|
* This is used by KLIPS for communicate the device along with the
|
|
@@ -348,32 +344,6 @@ static struct net_device *nss_ipsec_klip
|
|
return tun_dev;
|
|
}
|
|
|
|
-#if defined(NSS_L2TPV2_ENABLED)
|
|
-/*
|
|
- * nss_ipsec_klips_get_inner_ifnum()
|
|
- * Get ipsecmgr interface number for klips netdevice
|
|
- *
|
|
- * Calls nss_ipsec_klips_get_tun_dev(), which holds reference for tunnel,
|
|
- * which gets released at the end of this function.
|
|
- */
|
|
-static int nss_ipsec_klips_get_inner_ifnum(struct net_device *klips_dev)
|
|
-{
|
|
- struct net_device *tun_dev;
|
|
- int32_t ipsec_ifnum;
|
|
-
|
|
- tun_dev = nss_ipsec_klips_get_tun_dev(klips_dev);
|
|
- if (!tun_dev) {
|
|
- nss_ipsec_klips_warn("%px: Tunnel device not found for klips dev", klips_dev);
|
|
- return -1;
|
|
- }
|
|
-
|
|
- ipsec_ifnum = nss_cmn_get_interface_number_by_dev_and_type(tun_dev, NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER);
|
|
- dev_put(tun_dev);
|
|
-
|
|
- return ipsec_ifnum;
|
|
-}
|
|
-#endif
|
|
-
|
|
/*
|
|
* nss_ipsec_klips_get_tun_by_addr()
|
|
* Get the tunnel entry for given ip header from tunnel map table.
|
|
@@ -402,75 +372,6 @@ static struct nss_ipsec_klips_tun *nss_i
|
|
return NULL;
|
|
}
|
|
|
|
-#if defined(NSS_VXLAN_ENABLED)
|
|
-/*
|
|
- * nss_ipsec_klips_tun_match_ip_addr()
|
|
- * Compare tunnel address with source & destination ip addresses.
|
|
- */
|
|
-static bool nss_ipsec_klips_tun_match_ip_addr(struct nss_ipsec_klips_tun *tun, uint8_t ip_ver, uint32_t *local_ip, uint32_t *remote_ip)
|
|
-{
|
|
- struct nss_ipsec_klips_tun_addr *addr = &tun->addr;
|
|
- uint32_t status = 0;
|
|
- uint8_t i;
|
|
-
|
|
- switch (ip_ver) {
|
|
- case IPVERSION:
|
|
- status += local_ip[0] ^ addr->dest[0];
|
|
- status += remote_ip[0] ^ addr->src[0];
|
|
- status += addr->ver ^ ip_ver;
|
|
- nss_ipsec_klips_trace("%px: tun dev comparing with IPV4 tunnel local_ip: %x & remote_ip: %x IP pair.\n", tun, addr->dest[0], addr->src[0]);
|
|
- return !status;
|
|
-
|
|
- case 6:
|
|
- status += addr->ver ^ ip_ver;
|
|
- for (i = 0; i < NSS_IPSEC_KLIPS_IP6_ADDR_LEN; i++) {
|
|
- status += local_ip[i] ^ addr->dest[i];
|
|
- status += remote_ip[i] ^ addr->src[i];
|
|
- nss_ipsec_klips_trace("%px: tun dev comparing with IPV6 tunnel local_ip[%u]: %x & remote_ip[%u]: %x IP pair.\n", tun, i, addr->dest[i], i, addr->src[i]);
|
|
- }
|
|
- return !status;
|
|
-
|
|
- default:
|
|
- nss_ipsec_klips_warn("%px: non ip version:%u received", tun, ip_ver);
|
|
- return false;
|
|
- }
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_ipsec_klips_get_ipsec_ifnum()
|
|
- * Get ipsecmgr tunnel interface num for klips netdevice
|
|
- */
|
|
-static int32_t __maybe_unused nss_ipsec_klips_get_ipsec_ifnum(uint8_t ip_ver, uint32_t *local_ip, uint32_t *remote_ip)
|
|
-{
|
|
- struct nss_ipsec_klips_tun *tun;
|
|
- struct net_device *tun_dev;
|
|
- uint32_t if_num = -1;
|
|
- uint32_t i;
|
|
-
|
|
- read_lock(&tunnel_map.lock);
|
|
-
|
|
- for (i = 0, tun = tunnel_map.tbl; i < tunnel_map.max; i++, tun++) {
|
|
- if (!tun->klips_dev) {
|
|
- nss_ipsec_klips_warn("%px: klips dev is NULL.\n", tun);
|
|
- continue;
|
|
- }
|
|
-
|
|
- if (nss_ipsec_klips_tun_match_ip_addr(tun, ip_ver, local_ip, remote_ip)) {
|
|
- tun_dev = tun->nss_dev;
|
|
- if_num = nss_cmn_get_interface_number_by_dev_and_type(tun_dev, NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER);
|
|
- nss_ipsec_klips_warn("%px: tun dev(with ifnum:%d) is mapped with local & remote IP pair.\n", tun, if_num);
|
|
- read_unlock(&tunnel_map.lock);
|
|
- return if_num;
|
|
- }
|
|
- }
|
|
-
|
|
- read_unlock(&tunnel_map.lock);
|
|
-
|
|
- nss_ipsec_klips_warn("%px: tun dev not found with the local(%pI4) & remote(%pI4) IP pair.\n", tun, local_ip, remote_ip);
|
|
- return -1;
|
|
-}
|
|
-#endif
|
|
-
|
|
/*
|
|
* nss_ipsec_klips_get_index()
|
|
* given an interface name retrived the numeric suffix
|
|
@@ -2070,14 +1971,7 @@ static struct notifier_block nss_ipsec_k
|
|
|
|
#if defined(NSS_L2TPV2_ENABLED)
|
|
static struct l2tpmgr_ipsecmgr_cb nss_ipsec_klips_l2tp = {
|
|
- .get_ifnum_by_dev = nss_ipsec_klips_get_inner_ifnum,
|
|
- .get_ifnum_by_ip_addr = NULL
|
|
-};
|
|
-#endif
|
|
-
|
|
-#if defined(NSS_VXLAN_ENABLED)
|
|
-static struct nss_vxlanmgr_get_ipsec_if_num nss_ipsec_klips_vxlan_cb = {
|
|
- .get_ifnum_by_ip = nss_ipsec_klips_get_ipsec_ifnum
|
|
+ .cb = nss_ipsec_klips_get_tun_dev
|
|
};
|
|
#endif
|
|
|
|
@@ -2116,11 +2010,7 @@ int __init nss_ipsec_klips_init_module(v
|
|
ecm_interface_ipsec_register_callbacks(&nss_ipsec_klips_ecm);
|
|
ecm_notifier_register_connection_notify(&nss_ipsec_klips_ecm_conn_notifier);
|
|
#if defined(NSS_L2TPV2_ENABLED)
|
|
- l2tpmgr_register_ipsecmgr_callback_by_netdev(&nss_ipsec_klips_l2tp);
|
|
-#endif
|
|
-
|
|
-#if defined(NSS_VXLAN_ENABLED)
|
|
- nss_vxlanmgr_register_ipsecmgr_callback_by_ip(&nss_ipsec_klips_vxlan_cb);
|
|
+ l2tpmgr_register_ipsecmgr_callback(&nss_ipsec_klips_l2tp);
|
|
#endif
|
|
return 0;
|
|
}
|
|
@@ -2142,11 +2032,7 @@ void __exit nss_ipsec_klips_exit_module(
|
|
ecm_notifier_unregister_connection_notify(&nss_ipsec_klips_ecm_conn_notifier);
|
|
ecm_interface_ipsec_unregister_callbacks();
|
|
#if defined(NSS_L2TPV2_ENABLED)
|
|
- l2tpmgr_unregister_ipsecmgr_callback_by_netdev();
|
|
-#endif
|
|
-
|
|
-#if defined(NSS_VXLAN_ENABLED)
|
|
- nss_vxlanmgr_unregister_ipsecmgr_callback_by_ip();
|
|
+ l2tpmgr_unregister_ipsecmgr_callback();
|
|
#endif
|
|
|
|
nss_cfi_ocf_unregister_ipsec();
|
|
--- a/l2tp/l2tpv2/Makefile
|
|
+++ b/l2tp/l2tpv2/Makefile
|
|
@@ -1,7 +1,7 @@
|
|
# Makefile for l2tp client
|
|
ccflags-y += -I$(obj)/../../exports -I$(obj)/../.. -I$(obj)/nss_hal/include
|
|
ccflags-y += -DNSS_L2TP_DEBUG_LEVEL=0
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
ifneq (,$(filter $(CONFIG_L2TP),m y))
|
|
obj-m += qca-nss-l2tpv2.o
|
|
qca-nss-l2tpv2-objs := nss_connmgr_l2tpv2.o nss_l2tpv2_stats.o
|
|
--- a/l2tp/l2tpv2/nss_connmgr_l2tpv2.c
|
|
+++ b/l2tp/l2tpv2/nss_connmgr_l2tpv2.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2015-2017, 2019-2021 The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2015-2017, 2019-2020 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.
|
|
@@ -35,7 +35,6 @@
|
|
#include <linux/version.h>
|
|
#include <linux/sysctl.h>
|
|
#include <net/route.h>
|
|
-#include <linux/refcount.h>
|
|
#include <linux/../../net/l2tp/l2tp_core.h>
|
|
|
|
#include <nss_api_if.h>
|
|
@@ -100,11 +99,8 @@
|
|
|
|
static DEFINE_HASHTABLE(l2tpv2_session_data_hash_table, HASH_BUCKET_SIZE);
|
|
static int ip_ttl_max = 255;
|
|
-
|
|
-#if defined(NSS_L2TP_IPSEC_BIND_BY_NETDEV)
|
|
static char l2tpoipsec_config[L2TP_SYSCTL_STR_LEN_MAX];
|
|
static struct ctl_table_header *ctl_tbl_hdr; /* l2tpv2 sysctl */
|
|
-#endif
|
|
static struct l2tpmgr_ipsecmgr_cb __rcu ipsecmgr_cb;
|
|
|
|
/*
|
|
@@ -248,23 +244,24 @@ static struct nss_connmgr_l2tpv2_session
|
|
*/
|
|
data->l2tpv2.session.session_id = session->session_id;
|
|
data->l2tpv2.session.peer_session_id = session->peer_session_id;
|
|
+ data->l2tpv2.session.offset = 0;
|
|
data->l2tpv2.session.hdr_len = session->hdr_len;
|
|
data->l2tpv2.session.reorder_timeout = session->reorder_timeout;
|
|
data->l2tpv2.session.recv_seq = session->recv_seq;
|
|
data->l2tpv2.session.send_seq = session->send_seq;
|
|
|
|
- nss_connmgr_l2tpv2_info("sess %u, peer=%u nr=%u ns=%u hdr_len=%u timeout=%x"
|
|
+ nss_connmgr_l2tpv2_info("sess %u, peer=%u nr=%u ns=%u off=%u hdr_len=%u timeout=%x"
|
|
" recv_seq=%x send_seq=%x\n",
|
|
session->session_id, session->peer_session_id, session->nr,
|
|
- session->ns, session->hdr_len,
|
|
+ session->ns, 0, session->hdr_len,
|
|
session->reorder_timeout, session->recv_seq,
|
|
session->send_seq);
|
|
|
|
- /*
|
|
- * tunnel->sock->sk_no_check/sk_no_check_tx is set to true
|
|
- * if UDP checksum is not needed for the L2TP socket.
|
|
- */
|
|
- data->l2tpv2.tunnel.udp_csum = !tunnel->sock->sk_no_check_tx;
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 16, 0))
|
|
+ data->l2tpv2.tunnel.udp_csum = tunnel->sock->sk_no_check;
|
|
+#else
|
|
+ data->l2tpv2.tunnel.udp_csum = tunnel->sock->sk_no_check_tx;
|
|
+#endif
|
|
|
|
inet = inet_sk(tunnel->sock);
|
|
|
|
@@ -359,6 +356,9 @@ static void nss_connmgr_l2tpv2_exception
|
|
{
|
|
const struct iphdr *iph_outer, *iph_inner;
|
|
struct nss_connmgr_l2tpv2_session_data *ptr;
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 8, 0))
|
|
+ struct hlist_node *node;
|
|
+#endif
|
|
uint16_t *l2tp_hdr;
|
|
uint16_t l2tp_flags;
|
|
int l2tp_hdr_len = L2TP_HDR_MIN_LEN;
|
|
@@ -374,6 +374,9 @@ static void nss_connmgr_l2tpv2_exception
|
|
|
|
rcu_read_lock();
|
|
hash_for_each_possible_rcu(l2tpv2_session_data_hash_table, ptr,
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 8, 0))
|
|
+ node,
|
|
+#endif
|
|
hash_list, dev->ifindex) {
|
|
if (ptr->dev == dev) {
|
|
tunnel_local_ip = ptr->data.ip.v4.saddr.s_addr;
|
|
@@ -477,56 +480,6 @@ static void nss_connmgr_l2tpv2_event_rec
|
|
}
|
|
|
|
/*
|
|
- * nss_connmgr_l2tpv2_bind_ipsec_by_ipaddr()
|
|
- * Bind L2TP tunnel with IPsec(xfrm) based on IP Address
|
|
- */
|
|
-static void nss_connmgr_l2tpv2_bind_ipsec_by_ipaddr(struct nss_ctx_instance *nss_ctx, struct nss_connmgr_l2tpv2_data *l2tpv2_data, uint32_t l2tp_ifnum)
|
|
-{
|
|
- struct nss_l2tpv2_msg l2tpv2msg;
|
|
- nss_tx_status_t status;
|
|
- struct nss_l2tpv2_bind_ipsec_if_msg *l2tpv2_bind_ipsec_msg;
|
|
- int32_t ipsec_ifnum = -1;
|
|
- get_ipsec_ifnum_by_ip_addr_callback_t ipsec_cb;
|
|
-
|
|
- /*
|
|
- * Check if the L2TP interface is applied over an IPsec (XFRM) interface by querying the IPsec
|
|
- * client by using the L2TP tunnel IPv4 source/destination addresses.
|
|
- */
|
|
- rcu_read_lock();
|
|
- ipsec_cb = rcu_dereference(ipsecmgr_cb.get_ifnum_by_ip_addr);
|
|
- ipsec_ifnum = ipsec_cb ? ipsec_cb(IPVERSION, &l2tpv2_data->ip.v4.saddr.s_addr, &l2tpv2_data->ip.v4.daddr.s_addr) : -1;
|
|
- rcu_read_unlock();
|
|
-
|
|
- if (ipsec_ifnum < 0) {
|
|
- nss_connmgr_l2tpv2_info("%px: Invalid IPsec interface no.(0x%x) based on local & remote IP-address\n", nss_ctx, ipsec_ifnum);
|
|
- return;
|
|
- }
|
|
-
|
|
- /*
|
|
- * For, l2tpoipsec, send the command to bind the l2tp session with the IPsec interface.
|
|
- */
|
|
- memset(&l2tpv2msg, 0, sizeof(struct nss_l2tpv2_msg));
|
|
- nss_l2tpv2_msg_init(&l2tpv2msg, l2tp_ifnum, NSS_L2TPV2_MSG_BIND_IPSEC_IF,
|
|
- sizeof(struct nss_l2tpv2_bind_ipsec_if_msg), (void *)nss_connmgr_l2tpv2_msg_cb, NULL);
|
|
- l2tpv2_bind_ipsec_msg = &l2tpv2msg.msg.bind_ipsec_if_msg;
|
|
- l2tpv2_bind_ipsec_msg->ipsec_ifnum = ipsec_ifnum;
|
|
-
|
|
- status = nss_l2tpv2_tx(nss_ctx, &l2tpv2msg);
|
|
- if (status != NSS_TX_SUCCESS) {
|
|
- /*
|
|
- * TODO: Add retry logic. Currently it sends a warning message to user.
|
|
- * In case of bind fails, then we don't bring down L2TP tunnel, instead we give a warning log
|
|
- * to user, as this introduces a potential risk of not having a per packet check for source
|
|
- * interface number in firmware.
|
|
- */
|
|
- nss_connmgr_l2tpv2_warning("%px: L2TPv2 interface binding with IPSec interface(0x%x) failed.\n", nss_ctx, ipsec_ifnum);
|
|
- return;
|
|
- }
|
|
-
|
|
- nss_connmgr_l2tpv2_info("%px: L2TPv2 interface is bound to IPsec interface with if_num(0x%x)\n", nss_ctx, ipsec_ifnum);
|
|
-}
|
|
-
|
|
-/*
|
|
* nss_connmgr_l2tpv2_dev_up()
|
|
* pppol2tpv2 interface's up event handler
|
|
*/
|
|
@@ -630,12 +583,7 @@ static int nss_connmgr_l2tpv2_dev_up(str
|
|
return NOTIFY_BAD;
|
|
}
|
|
|
|
- nss_connmgr_l2tpv2_info("%px: nss_l2tpv2_tx() CREATE successful\n", nss_ctx);
|
|
-
|
|
- /*
|
|
- * Check if we need to bind the L2TP to an IPsec interface. This is required as per RFC3193
|
|
- */
|
|
- nss_connmgr_l2tpv2_bind_ipsec_by_ipaddr(nss_ctx, data, if_number);
|
|
+ nss_connmgr_l2tpv2_info("%px: nss_l2tpv2_tx() successful\n", nss_ctx);
|
|
|
|
return NOTIFY_DONE;
|
|
}
|
|
@@ -648,6 +596,9 @@ static int nss_connmgr_l2tpv2_dev_down(s
|
|
{
|
|
struct nss_connmgr_l2tpv2_session_data *ptr;
|
|
struct hlist_node *tmp;
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 8, 0))
|
|
+ struct hlist_node *node;
|
|
+#endif
|
|
struct nss_l2tpv2_msg l2tpv2msg;
|
|
struct nss_l2tpv2_session_destroy_msg *l2tpv2cfg;
|
|
int if_number;
|
|
@@ -671,6 +622,9 @@ static int nss_connmgr_l2tpv2_dev_down(s
|
|
}
|
|
|
|
hash_for_each_possible_safe(l2tpv2_session_data_hash_table, ptr,
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 8, 0))
|
|
+ node,
|
|
+#endif
|
|
tmp, hash_list, dev->ifindex) {
|
|
if (ptr->dev == dev) {
|
|
dev_put(dev);
|
|
@@ -713,7 +667,11 @@ static int nss_connmgr_l2tpv2_dev_event(
|
|
unsigned long event, void *dev)
|
|
{
|
|
struct net_device *netdev;
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 10, 0))
|
|
+ netdev = (struct net_device *)dev;
|
|
+#else
|
|
netdev = netdev_notifier_info_to_dev(dev);
|
|
+#endif
|
|
|
|
switch (event) {
|
|
case NETDEV_UP:
|
|
@@ -736,6 +694,9 @@ static int nss_connmgr_l2tpv2_dev_event(
|
|
int nss_connmgr_l2tpv2_get_data(struct net_device *dev, struct nss_connmgr_l2tpv2_data *data)
|
|
{
|
|
struct nss_connmgr_l2tpv2_session_data *ptr;
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 8, 0))
|
|
+ struct hlist_node *node;
|
|
+#endif
|
|
if (!data) {
|
|
nss_connmgr_l2tpv2_info("nss_connmgr_l2tpv2_data ptr is null\n");
|
|
return -EINVAL;
|
|
@@ -743,6 +704,9 @@ int nss_connmgr_l2tpv2_get_data(struct n
|
|
|
|
rcu_read_lock();
|
|
hash_for_each_possible_rcu(l2tpv2_session_data_hash_table, ptr,
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 8, 0))
|
|
+ node,
|
|
+#endif
|
|
hash_list, dev->ifindex) {
|
|
if (ptr->dev == dev) {
|
|
memcpy(data, &ptr->data, sizeof(struct nss_connmgr_l2tpv2_data));
|
|
@@ -763,9 +727,15 @@ EXPORT_SYMBOL(nss_connmgr_l2tpv2_get_dat
|
|
int nss_connmgr_l2tpv2_does_connmgr_track(const struct net_device *dev)
|
|
{
|
|
struct nss_connmgr_l2tpv2_session_data *ptr;
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 8, 0))
|
|
+ struct hlist_node *node;
|
|
+#endif
|
|
|
|
rcu_read_lock();
|
|
hash_for_each_possible_rcu(l2tpv2_session_data_hash_table, ptr,
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 8, 0))
|
|
+ node,
|
|
+#endif
|
|
hash_list, dev->ifindex) {
|
|
if (ptr->dev == dev) {
|
|
rcu_read_unlock();
|
|
@@ -779,83 +749,6 @@ int nss_connmgr_l2tpv2_does_connmgr_trac
|
|
EXPORT_SYMBOL(nss_connmgr_l2tpv2_does_connmgr_track);
|
|
|
|
/*
|
|
- * l2tpmgr_register_ipsecmgr_callback_by_ipaddr()
|
|
- * Register IPSecmgr callback.
|
|
- */
|
|
-void l2tpmgr_register_ipsecmgr_callback_by_ipaddr(struct l2tpmgr_ipsecmgr_cb *cb)
|
|
-{
|
|
- get_ipsec_ifnum_by_ip_addr_callback_t ipsec_get_ifnum_by_ip_addr;
|
|
-
|
|
- rcu_read_lock();
|
|
- ipsec_get_ifnum_by_ip_addr = rcu_dereference(ipsecmgr_cb.get_ifnum_by_ip_addr);
|
|
- if (ipsec_get_ifnum_by_ip_addr) {
|
|
- rcu_read_unlock();
|
|
- nss_connmgr_l2tpv2_info("%px: IPSecmgr Callback get_ifnum_by_ip_addr is already registered\n", cb);
|
|
- return;
|
|
- }
|
|
- rcu_read_unlock();
|
|
-
|
|
- if (cb->get_ifnum_by_ip_addr == NULL) {
|
|
- nss_connmgr_l2tpv2_warning("%px: IPSecmgr Callback get_ifnum_by_ip_addr is NULL\n", cb);
|
|
- return;
|
|
- }
|
|
-
|
|
- rcu_assign_pointer(ipsecmgr_cb.get_ifnum_by_ip_addr, cb->get_ifnum_by_ip_addr);
|
|
- synchronize_rcu();
|
|
-}
|
|
-EXPORT_SYMBOL(l2tpmgr_register_ipsecmgr_callback_by_ipaddr);
|
|
-
|
|
-/*
|
|
- * l2tpmgr_unregister_ipsecmgr_callback_by_ipaddr
|
|
- * Unregister callback.
|
|
- */
|
|
-void l2tpmgr_unregister_ipsecmgr_callback_by_ipaddr(void)
|
|
-{
|
|
- rcu_assign_pointer(ipsecmgr_cb.get_ifnum_by_ip_addr, NULL);
|
|
- synchronize_rcu();
|
|
-}
|
|
-EXPORT_SYMBOL(l2tpmgr_unregister_ipsecmgr_callback_by_ipaddr);
|
|
-
|
|
-#if defined(NSS_L2TP_IPSEC_BIND_BY_NETDEV)
|
|
-/*
|
|
- * l2tpmgr_register_ipsecmgr_callback_by_netdev()
|
|
- * Register IPSecmgr callback.
|
|
- */
|
|
-void l2tpmgr_register_ipsecmgr_callback_by_netdev(struct l2tpmgr_ipsecmgr_cb *cb)
|
|
-{
|
|
- get_ipsec_ifnum_by_dev_callback_t ipsec_get_ifnum_by_dev;
|
|
-
|
|
- rcu_read_lock();
|
|
- ipsec_get_ifnum_by_dev = rcu_dereference(ipsecmgr_cb.get_ifnum_by_dev);
|
|
- if (ipsec_get_ifnum_by_dev) {
|
|
- rcu_read_unlock();
|
|
- nss_connmgr_l2tpv2_info("%px: IPSecmgr Callback get_ifnum_by_dev is already registered\n", cb);
|
|
- return;
|
|
- }
|
|
- rcu_read_unlock();
|
|
-
|
|
- if (cb->get_ifnum_by_dev == NULL) {
|
|
- nss_connmgr_l2tpv2_warning("%px: IPSecmgr Callback get_ifnum_by_dev is NULL\n", cb);
|
|
- return;
|
|
- }
|
|
-
|
|
- rcu_assign_pointer(ipsecmgr_cb.get_ifnum_by_dev, cb->get_ifnum_by_dev);
|
|
- synchronize_rcu();
|
|
-}
|
|
-EXPORT_SYMBOL(l2tpmgr_register_ipsecmgr_callback_by_netdev);
|
|
-
|
|
-/*
|
|
- * l2tpmgr_unregister_ipsecmgr_callback_by_netdev
|
|
- * Unregister callback.
|
|
- */
|
|
-void l2tpmgr_unregister_ipsecmgr_callback_by_netdev(void)
|
|
-{
|
|
- rcu_assign_pointer(ipsecmgr_cb.get_ifnum_by_dev, NULL);
|
|
- synchronize_rcu();
|
|
-}
|
|
-EXPORT_SYMBOL(l2tpmgr_unregister_ipsecmgr_callback_by_netdev);
|
|
-
|
|
-/*
|
|
* nss_connmgr_l2tpv2_proc_handler()
|
|
* Read and write handler for sysctl.
|
|
*/
|
|
@@ -866,14 +759,13 @@ static int nss_connmgr_l2tpv2_proc_handl
|
|
char *l2tp_device_name, *ipsec_device_name;
|
|
char *input_str = l2tpoipsec_config;
|
|
int32_t l2tp_ifnum, ipsec_ifnum;
|
|
- struct net_device *l2tpdev, *ipsecdev;
|
|
+ struct net_device *l2tpdev, *ipsecdev, *ipsectundev;
|
|
nss_tx_status_t status;
|
|
struct nss_l2tpv2_msg l2tpv2msg;
|
|
- get_ipsec_ifnum_by_dev_callback_t ipsec_cb;
|
|
- struct nss_l2tpv2_bind_ipsec_if_msg *l2tpv2_bind_ipsec_msg;
|
|
+ get_ipsec_tundev_callback_t ipsec_cb;
|
|
+ struct nss_l2tpv2_bind_ipsec_if_msg *l2tpv2_bind_ipsec_if;
|
|
struct nss_ctx_instance *nss_ctx = nss_l2tpv2_get_context();
|
|
int ret = proc_dostring(ctl, write, buffer, lenp, ppos);
|
|
- struct nss_connmgr_l2tpv2_session_data *ptr;
|
|
|
|
if (!write) {
|
|
nss_connmgr_l2tpv2_info("command to write is echo <l2tp-device-name> <ipsec-device-name> > <filename>\n");
|
|
@@ -900,19 +792,6 @@ static int nss_connmgr_l2tpv2_proc_handl
|
|
return -EINVAL;
|
|
}
|
|
|
|
- rcu_read_lock();
|
|
- hash_for_each_possible_rcu(l2tpv2_session_data_hash_table, ptr,
|
|
- hash_list, l2tpdev->ifindex) {
|
|
- if (ptr->dev != l2tpdev) {
|
|
- continue;
|
|
- }
|
|
-
|
|
- if (ptr->data.l2tpv2.tunnel.udp_csum) {
|
|
- nss_connmgr_l2tpv2_info("Enabling UDP checksum in L2TP packet is not supported for l2tpoipsec flow\n");
|
|
- }
|
|
- }
|
|
- rcu_read_unlock();
|
|
-
|
|
ipsecdev = dev_get_by_name(&init_net, ipsec_device_name);
|
|
if (!ipsecdev) {
|
|
nss_connmgr_l2tpv2_info("Cannot find the netdevice associated with %s\n", ipsec_device_name);
|
|
@@ -931,7 +810,7 @@ static int nss_connmgr_l2tpv2_proc_handl
|
|
}
|
|
|
|
rcu_read_lock();
|
|
- ipsec_cb = rcu_dereference(ipsecmgr_cb.get_ifnum_by_dev);
|
|
+ ipsec_cb = rcu_dereference(ipsecmgr_cb.cb);
|
|
if (!ipsec_cb) {
|
|
rcu_read_unlock();
|
|
nss_connmgr_l2tpv2_info("Callback to get IPsec tun device not registered");
|
|
@@ -940,13 +819,27 @@ static int nss_connmgr_l2tpv2_proc_handl
|
|
}
|
|
|
|
/*
|
|
- * Get NSS ifnum for IPsec interface.
|
|
+ * Get the dummy netdevice used to register this IPSec
|
|
+ * device with NSS from the ipsecmgr module. This is
|
|
+ * needed for looking up the NSS ifnum for the IPSec
|
|
+ * netdevice.
|
|
*/
|
|
- ipsec_ifnum = ipsec_cb(ipsecdev);
|
|
+ ipsectundev = ipsec_cb(ipsecdev);
|
|
rcu_read_unlock();
|
|
+ if (!ipsectundev) {
|
|
+ nss_connmgr_l2tpv2_info("Cannot get the device from IPSecmgr for %s\n", ipsec_device_name);
|
|
+ ret = -ENODEV;
|
|
+ goto exit;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Get NSS ifnum for IPsec interface.
|
|
+ */
|
|
+ ipsec_ifnum = nss_cmn_get_interface_number_by_dev_and_type(ipsectundev, NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER);
|
|
if (ipsec_ifnum == -1) {
|
|
nss_connmgr_l2tpv2_info("Cannot find the NSS interface associated with %s\n", ipsec_device_name);
|
|
ret = -ENODEV;
|
|
+ dev_put(ipsectundev);
|
|
goto exit;
|
|
}
|
|
|
|
@@ -955,14 +848,15 @@ static int nss_connmgr_l2tpv2_proc_handl
|
|
*/
|
|
memset(&l2tpv2msg, 0, sizeof(struct nss_l2tpv2_msg));
|
|
nss_l2tpv2_msg_init(&l2tpv2msg, l2tp_ifnum, NSS_L2TPV2_MSG_BIND_IPSEC_IF, sizeof(struct nss_l2tpv2_bind_ipsec_if_msg), (void *)nss_connmgr_l2tpv2_msg_cb, NULL);
|
|
- l2tpv2_bind_ipsec_msg = &l2tpv2msg.msg.bind_ipsec_if_msg;
|
|
- l2tpv2_bind_ipsec_msg->ipsec_ifnum = ipsec_ifnum;
|
|
+ l2tpv2_bind_ipsec_if = &l2tpv2msg.msg.bind_ipsec_if_msg;
|
|
+ l2tpv2_bind_ipsec_if->ipsec_ifnum = ipsec_ifnum;
|
|
status = nss_l2tpv2_tx(nss_ctx, &l2tpv2msg);
|
|
if (status != NSS_TX_SUCCESS) {
|
|
nss_connmgr_l2tpv2_info("%px IPSec interface bind failed\n", nss_ctx);
|
|
ret = -EAGAIN;
|
|
}
|
|
|
|
+ dev_put(ipsectundev);
|
|
exit:
|
|
dev_put(l2tpdev);
|
|
dev_put(ipsecdev);
|
|
@@ -970,6 +864,38 @@ exit:
|
|
}
|
|
|
|
/*
|
|
+ * l2tpmgr_register_ipsecmgr_callback()
|
|
+ * Register IPSecmgr callback.
|
|
+ */
|
|
+void l2tpmgr_register_ipsecmgr_callback(struct l2tpmgr_ipsecmgr_cb *cb)
|
|
+{
|
|
+ get_ipsec_tundev_callback_t ipsec_cb;
|
|
+ rcu_read_lock();
|
|
+ ipsec_cb = rcu_dereference(ipsecmgr_cb.cb);
|
|
+ if (ipsec_cb) {
|
|
+ rcu_read_unlock();
|
|
+ nss_connmgr_l2tpv2_info("IPSecmgr Callback is already registered\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ rcu_assign_pointer(ipsecmgr_cb.cb, cb->cb);
|
|
+ rcu_read_unlock();
|
|
+}
|
|
+EXPORT_SYMBOL(l2tpmgr_register_ipsecmgr_callback);
|
|
+
|
|
+/*
|
|
+ * l2tpmgr_unregister_ipsecmgr_callback
|
|
+ * Unregister callback.
|
|
+ */
|
|
+void l2tpmgr_unregister_ipsecmgr_callback(void)
|
|
+{
|
|
+ rcu_read_lock();
|
|
+ rcu_assign_pointer(ipsecmgr_cb.cb, NULL);
|
|
+ rcu_read_unlock();
|
|
+}
|
|
+EXPORT_SYMBOL(l2tpmgr_unregister_ipsecmgr_callback);
|
|
+
|
|
+/*
|
|
* nss_connmgr_l2tpv2_table
|
|
*/
|
|
static struct ctl_table nss_connmgr_l2tpv2_table[] = {
|
|
@@ -1006,7 +932,6 @@ static struct ctl_table nss_connmgr_l2tp
|
|
},
|
|
{ }
|
|
};
|
|
-#endif
|
|
|
|
/*
|
|
* Linux Net device Notifier
|
|
@@ -1029,20 +954,18 @@ int __init nss_connmgr_l2tpv2_init_modul
|
|
return 0;
|
|
}
|
|
#endif
|
|
-#if defined(NSS_L2TP_IPSEC_BIND_BY_NETDEV)
|
|
ctl_tbl_hdr = register_sysctl_table(nss_connmgr_l2tpv2_sysroot);
|
|
if (!ctl_tbl_hdr) {
|
|
nss_connmgr_l2tpv2_info("Unable to register sysctl table for L2TP conn mgr\n");
|
|
return -EFAULT;
|
|
}
|
|
|
|
-#endif
|
|
/*
|
|
* Initialize ipsecmgr callback.
|
|
*/
|
|
- rcu_assign_pointer(ipsecmgr_cb.get_ifnum_by_dev, NULL);
|
|
- rcu_assign_pointer(ipsecmgr_cb.get_ifnum_by_ip_addr, NULL);
|
|
- synchronize_rcu();
|
|
+ rcu_read_lock();
|
|
+ rcu_assign_pointer(ipsecmgr_cb.cb, NULL);
|
|
+ rcu_read_unlock();
|
|
register_netdevice_notifier(&nss_connmgr_l2tpv2_notifier);
|
|
return 0;
|
|
}
|
|
--- a/l2tp/l2tpv2/nss_connmgr_l2tpv2.h
|
|
+++ b/l2tp/l2tpv2/nss_connmgr_l2tpv2.h
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2015, 2020, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2015, 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.
|
|
@@ -27,21 +27,13 @@
|
|
#include <linux/in.h>
|
|
#include <linux/socket.h>
|
|
#include <linux/types.h>
|
|
-#include <linux/version.h>
|
|
|
|
#define L2TP_V_2 2
|
|
|
|
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 12, 0))
|
|
-#define tunnel_hold(tunnel) atomic_inc(&tunnel->ref_count)
|
|
-#define tunnel_put(tunnel) atomic_dec(&tunnel->ref_count)
|
|
-#define session_hold(session) atomic_inc(&session->ref_count)
|
|
-#define session_put(session) atomic_dec(&session->ref_count)
|
|
-#else
|
|
#define tunnel_hold(tunnel) refcount_inc(&tunnel->ref_count)
|
|
#define tunnel_put(tunnel) refcount_dec(&tunnel->ref_count)
|
|
#define session_hold(session) refcount_inc(&session->ref_count)
|
|
#define session_put(session) refcount_dec(&session->ref_count)
|
|
-#endif
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------------
|
|
@@ -54,6 +46,7 @@
|
|
*/
|
|
struct session_info {
|
|
u32 session_id, peer_session_id; /* local & remote session id */
|
|
+ u16 offset; /* offset to data */
|
|
u16 hdr_len; /* header length */
|
|
int reorder_timeout; /* reorder timeout */
|
|
unsigned send_seq:1; /* enable tx sequence number ? */
|
|
--- a/l2tp/l2tpv2/nss_l2tpv2_stats.c
|
|
+++ b/l2tp/l2tpv2/nss_l2tpv2_stats.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2015, 2020, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2015, 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.
|
|
@@ -21,9 +21,7 @@
|
|
*/
|
|
|
|
#include <linux/types.h>
|
|
-#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
|
|
-#include <net/netfilter/nf_flow_table.h>
|
|
-#endif
|
|
+#include <linux/netdevice.h>
|
|
#include <linux/ppp_channel.h>
|
|
#include <nss_api_if.h>
|
|
#include <nss_dynamic_interface.h>
|
|
@@ -94,8 +92,6 @@ void nss_l2tpv2_update_dev_stats(struct
|
|
|
|
dev_hold(dev);
|
|
|
|
- memset(&l2tp_stats, 0, sizeof(struct l2tp_stats));
|
|
-
|
|
/*
|
|
* Get tunnel id
|
|
*/
|
|
@@ -108,35 +104,37 @@ void nss_l2tpv2_update_dev_stats(struct
|
|
/*
|
|
* Update tunnel & session stats
|
|
*/
|
|
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 12, 0))
|
|
- tunnel = l2tp_tunnel_find(dev_net(dev), data.l2tpv2.tunnel.tunnel_id);
|
|
+ tunnel = l2tp_tunnel_get(dev_net(dev), data.l2tpv2.tunnel.tunnel_id);
|
|
if (!tunnel) {
|
|
dev_put(dev);
|
|
return;
|
|
}
|
|
tunnel_hold(tunnel);
|
|
|
|
- session = l2tp_session_find(dev_net(dev), tunnel, data.l2tpv2.session.session_id);
|
|
+ session = l2tp_session_get(dev_net(dev), data.l2tpv2.session.session_id);
|
|
if (!session) {
|
|
tunnel_put(tunnel);
|
|
dev_put(dev);
|
|
return;
|
|
}
|
|
+
|
|
+ memset(&l2tp_stats, 0, sizeof(struct l2tp_stats));
|
|
+
|
|
session_hold(session);
|
|
-#else
|
|
- tunnel = l2tp_tunnel_get(dev_net(dev), data.l2tpv2.tunnel.tunnel_id);
|
|
- if (!tunnel) {
|
|
- dev_put(dev);
|
|
- return;
|
|
- }
|
|
- session = l2tp_tunnel_get_session(tunnel, data.l2tpv2.session.session_id);
|
|
- if (!session) {
|
|
- tunnel_put(tunnel);
|
|
- dev_put(dev);
|
|
- return;
|
|
- }
|
|
-#endif
|
|
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 8, 0))
|
|
+ /* valid session found. Update stats */
|
|
+ l2tp_stats.tx_packets = (u64)sync_stats->node_stats.tx_packets;
|
|
+ l2tp_stats.tx_bytes = (u64)sync_stats->node_stats.tx_bytes;
|
|
+ l2tp_stats.tx_errors = (u64)sync_stats->tx_errors;
|
|
+
|
|
+ l2tp_stats.rx_packets = (u64)sync_stats->node_stats.rx_packets;
|
|
+ l2tp_stats.rx_bytes = (u64)sync_stats->node_stats.rx_bytes;
|
|
+ l2tp_stats.rx_errors = (u64)sync_stats->rx_errors;
|
|
+
|
|
+ l2tp_stats.rx_seq_discards = (u64)sync_stats->rx_seq_discards;
|
|
+ l2tp_stats.rx_oos_packets = (u64)sync_stats->rx_oos_packets;
|
|
+#else
|
|
atomic_long_set(&l2tp_stats.tx_packets, (long)sync_stats->node_stats.tx_packets);
|
|
atomic_long_set(&l2tp_stats.tx_bytes, (long)sync_stats->node_stats.tx_bytes);
|
|
atomic_long_set(&l2tp_stats.tx_errors, (long)sync_stats->tx_errors);
|
|
@@ -148,6 +146,7 @@ void nss_l2tpv2_update_dev_stats(struct
|
|
atomic_long_set(&l2tp_stats.rx_seq_discards, (long)sync_stats->rx_seq_discards);
|
|
atomic_long_set(&l2tp_stats.rx_oos_packets, (long)(sync_stats->rx_oos_packets));
|
|
|
|
+#endif
|
|
l2tp_stats_update(tunnel, session, &l2tp_stats);
|
|
|
|
session_put(session);
|
|
--- a/lag/Makefile
|
|
+++ b/lag/Makefile
|
|
@@ -7,7 +7,7 @@ endif
|
|
ccflags-y := -I$(obj) -I$(obj)/..
|
|
ccflags-y += -DNSS_CLIENT_BUILD_ID="$(BUILD_ID)"
|
|
ccflags-y += -DNSS_LAG_MGR_DEBUG_LEVEL=0
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
|
|
obj-m += qca-nss-lag-mgr.o
|
|
qca-nss-lag-mgr-objs := nss_lag.o
|
|
--- a/map/map-t/Makefile
|
|
+++ b/map/map-t/Makefile
|
|
@@ -1,7 +1,7 @@
|
|
# Makefile for map-t client
|
|
ccflags-y += -I$(obj)/../../exports -I$(obj)/../.. -I$(obj)/nss_hal/include
|
|
ccflags-y += -DNSS_MAP_T_DEBUG_LEVEL=0
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
obj-m += qca-nss-map-t.o
|
|
qca-nss-map-t-objs := nss_connmgr_map_t.o
|
|
|
|
--- a/map/map-t/nss_connmgr_map_t.c
|
|
+++ b/map/map-t/nss_connmgr_map_t.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2016-2020, 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.
|
|
@@ -424,15 +424,12 @@ static void nss_connmgr_map_t_decap_exce
|
|
struct ipv6hdr ip6_hdr_r;
|
|
uint8_t next_hdr, hop_limit, tclass, l4_proto;
|
|
int total_len;
|
|
- uint32_t identifier = 0;
|
|
+ uint32_t identifier;
|
|
bool df_bit = false;
|
|
uint16_t skip_sz = 0;
|
|
- struct nss_map_t_mdata *mdata;
|
|
|
|
- mdata = (struct nss_map_t_mdata *)skb->data;
|
|
-
|
|
- /* discard meta data header */
|
|
- skb_pull(skb, sizeof(struct nss_map_t_mdata));
|
|
+ /* discard L2 header */
|
|
+ skb_pull(skb, sizeof(struct ethhdr));
|
|
skb_reset_mac_header(skb);
|
|
|
|
skb_reset_network_header(skb);
|
|
@@ -462,12 +459,7 @@ static void nss_connmgr_map_t_decap_exce
|
|
tclass = nss_connmgr_map_t_ipv6_get_tclass(ip6_hdr);
|
|
|
|
if (likely(next_hdr != NEXTHDR_FRAGMENT)) {
|
|
-
|
|
- /*
|
|
- * Set DF bit
|
|
- */
|
|
- df_bit = !!(mdata->flags & NSS_MAPT_MDATA_FLAG_DF_BIT);
|
|
-
|
|
+ df_bit = true;
|
|
l4_proto = next_hdr;
|
|
} else {
|
|
struct frag_hdr tmp_fh, *fh;
|
|
@@ -504,16 +496,8 @@ static void nss_connmgr_map_t_decap_exce
|
|
ip4_hdr->tos = tclass;
|
|
if (unlikely(df_bit)) {
|
|
ip4_hdr->frag_off = htons(IP_DF);
|
|
- }
|
|
-
|
|
- if (unlikely(identifier)) {
|
|
- ip4_hdr->id = htons(identifier & 0xffff);
|
|
} else {
|
|
- /*
|
|
- * Generate the new identifier value and set it
|
|
- * in the IPv4 Identification field.
|
|
- */
|
|
- __ip_select_ident(dev_net(dev), ip4_hdr, 1);
|
|
+ ip4_hdr->id = htons(identifier & 0xffff);
|
|
}
|
|
|
|
skb->pkt_type = PACKET_HOST;
|
|
@@ -531,7 +515,7 @@ static void nss_connmgr_map_t_decap_exce
|
|
/*
|
|
* nss_connmgr_map_t_encap_exception()
|
|
* Exception handler registered to NSS for handling map_t ipv4 pkts
|
|
- * Send the translated ipv4 packets to the stack directly.
|
|
+ * Translates ipv4 packet back to ipv6 and send to nat46 device directly.
|
|
*/
|
|
static void nss_connmgr_map_t_encap_exception(struct net_device *dev,
|
|
struct sk_buff *skb,
|
|
@@ -539,32 +523,147 @@ static void nss_connmgr_map_t_encap_exce
|
|
|
|
{
|
|
struct iphdr *ip4_hdr;
|
|
+ struct ipv6hdr *ip6_hdr;
|
|
+ uint8_t v6saddr[16], v6daddr[16];
|
|
+ struct tcphdr *tcph = NULL;
|
|
+ struct udphdr *udph = NULL;
|
|
+ struct iphdr ip4_hdr_r;
|
|
+ __be16 sport, dport;
|
|
+ uint8_t nexthdr, hop_limit, tos;
|
|
+ int payload_len;
|
|
+ bool df_bit = false;
|
|
+ uint16_t append_hdr_sz = 0;
|
|
+ uint16_t identifier;
|
|
+ uint32_t l4_csum;
|
|
+ uint16_t csum;
|
|
|
|
+ /* discard L2 header */
|
|
skb_pull(skb, sizeof(struct ethhdr));
|
|
skb_reset_mac_header(skb);
|
|
+
|
|
skb_reset_network_header(skb);
|
|
|
|
ip4_hdr = ip_hdr(skb);
|
|
- skb_set_transport_header(skb, ip4_hdr->ihl * 4);
|
|
+ skb_set_transport_header(skb, ip4_hdr->ihl*4);
|
|
+
|
|
+ if (ip4_hdr->protocol == IPPROTO_TCP) {
|
|
+ tcph = tcp_hdr(skb);
|
|
+ l4_csum = tcph->check;
|
|
+ sport = tcph->source;
|
|
+ dport = tcph->dest;
|
|
+ } else if (ip4_hdr->protocol == IPPROTO_UDP) {
|
|
+ udph = udp_hdr(skb);
|
|
+ l4_csum = udph->check;
|
|
+ sport = udph->source;
|
|
+ dport = udph->dest;
|
|
+ } else {
|
|
+ nss_connmgr_map_t_warning("%px: Unsupported protocol, free it up\n", dev);
|
|
+ dev_kfree_skb_any(skb);
|
|
+ return;
|
|
+ }
|
|
|
|
/*
|
|
- * IP Header checksum is not generated yet, calculate it now.
|
|
+ * Undo the checksum of the IPv4 source and destinationIPv4 address.
|
|
*/
|
|
- ip4_hdr->check = 0;
|
|
- ip4_hdr->check = ip_fast_csum((unsigned char *)ip4_hdr, ip4_hdr->ihl);
|
|
+ csum = ip_compute_csum(&ip4_hdr->saddr, 2 * sizeof(ip4_hdr->saddr));
|
|
+ l4_csum += ((~csum) & 0xFFFF);
|
|
+
|
|
+ /*
|
|
+ * IPv6 packet is xlated to ipv4 packet by acceleration engine. But there is no ipv4 rule.
|
|
+ * Call xlate_4_to_6() [ which is exported by nat46.ko ] to find original ipv6 src and ipv6 dest address.
|
|
+ * These functions is designed for packets from lan to wan. Since this packet is from wan, need to call
|
|
+ * this function with parameters reversed. ipv4_hdr_r is used for reversing ip addresses.
|
|
+ */
|
|
+ ip4_hdr_r.daddr = ip4_hdr->saddr;
|
|
+ ip4_hdr_r.saddr = ip4_hdr->daddr;
|
|
+
|
|
+ if (unlikely(!xlate_4_to_6(dev, &ip4_hdr_r, dport, sport, v6saddr, v6daddr))) { /* exception happened after packet got xlated */
|
|
+ nss_connmgr_map_t_warning("%px: Martian ipv4 packet !!..free it. (saddr = 0x%x daddr = 0x%x sport = %d dport = %d)\n", dev,\
|
|
+ ip4_hdr->saddr, ip4_hdr->daddr, sport, dport);
|
|
+ dev_kfree_skb_any(skb);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ nexthdr = ip4_hdr->protocol;
|
|
+ payload_len = ntohs(ip4_hdr->tot_len) - sizeof(struct iphdr);
|
|
+ hop_limit = ip4_hdr->ttl;
|
|
+ tos = ip4_hdr->tos;
|
|
+ identifier = ntohs(ip4_hdr->id);
|
|
+
|
|
+ if (ip4_hdr->frag_off & htons(IP_DF)) {
|
|
+ df_bit = true;
|
|
+ } else if (map_t_flags & MAPT_FLAG_ADD_DUMMY_HDR) {
|
|
+ append_hdr_sz = sizeof(struct frag_hdr);
|
|
+ }
|
|
+
|
|
+ if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + append_hdr_sz - sizeof(struct iphdr))) {
|
|
+ nss_connmgr_map_t_warning("%px: Not enough headroom for ipv6 packet...Freeing the packet\n", dev);
|
|
+ dev_kfree_skb_any(skb);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ skb_push(skb, sizeof(struct ipv6hdr) + append_hdr_sz - sizeof(struct iphdr));
|
|
+ skb_reset_network_header(skb);
|
|
+ skb_reset_mac_header(skb);
|
|
+
|
|
+ skb->protocol = htons(ETH_P_IPV6);
|
|
+
|
|
+ ip6_hdr = ipv6_hdr(skb);
|
|
+ memset(ip6_hdr, 0, sizeof(struct ipv6hdr));
|
|
+
|
|
+ ip6_hdr->version = 6;
|
|
+ ip6_hdr->payload_len = htons(payload_len + append_hdr_sz);
|
|
+ ip6_hdr->hop_limit = hop_limit;
|
|
+
|
|
+ nss_connmgr_map_t_ipv6_set_tclass(ip6_hdr, tos);
|
|
+ memcpy(&ip6_hdr->daddr, v6saddr, sizeof(struct in6_addr));
|
|
+ memcpy(&ip6_hdr->saddr, v6daddr, sizeof(struct in6_addr));
|
|
+
|
|
+ if (unlikely(df_bit) || !(map_t_flags & MAPT_FLAG_ADD_DUMMY_HDR)) {
|
|
+ ip6_hdr->nexthdr = nexthdr;
|
|
+ } else {
|
|
+ struct frag_hdr tmp_fh, *fh;
|
|
+ const __be32 *fh_addr = skb_header_pointer(skb, sizeof(struct ipv6hdr), sizeof(struct frag_hdr), &tmp_fh);
|
|
+ if (!fh_addr) {
|
|
+ nss_connmgr_map_t_warning("%px: Not able to offset to frag header\n", dev);
|
|
+ dev_kfree_skb_any(skb);
|
|
+ return;
|
|
+ }
|
|
+ fh = (struct frag_hdr *)fh_addr;
|
|
+ memset(fh, 0, sizeof(struct frag_hdr));
|
|
+ fh->identification = htonl(identifier);
|
|
+ fh->nexthdr = nexthdr;
|
|
+ ip6_hdr->nexthdr = NEXTHDR_FRAGMENT;
|
|
+ }
|
|
+
|
|
+ skb_set_transport_header(skb, sizeof(struct ipv6hdr) + append_hdr_sz);
|
|
+
|
|
+ /*
|
|
+ * Add the checksum of the IPv6 source and destination address.
|
|
+ */
|
|
+ l4_csum += ip_compute_csum(ip6_hdr->saddr.s6_addr16, 2 * sizeof(ip6_hdr->saddr));
|
|
+
|
|
+ /*
|
|
+ * Fold the 32 bits checksum to 16 bits
|
|
+ */
|
|
+ l4_csum = (l4_csum & 0x0000FFFF) + (l4_csum >> 16);
|
|
+ l4_csum = (l4_csum & 0x0000FFFF) + (l4_csum >> 16);
|
|
+
|
|
+ if (nexthdr == IPPROTO_TCP) {
|
|
+ tcph->check = (uint16_t)l4_csum;
|
|
+ } else {
|
|
+ udph->check = (uint16_t)l4_csum;
|
|
+ }
|
|
|
|
- skb->protocol = htons(ETH_P_IP);
|
|
skb->pkt_type = PACKET_HOST;
|
|
skb->skb_iif = dev->ifindex;
|
|
skb->ip_summed = CHECKSUM_NONE;
|
|
skb->dev = dev;
|
|
|
|
- nss_connmgr_map_t_trace("%px: ipv4 packet exceptioned after v6/v4xlat src=%pI4 dest=%pI4 proto=%d\n",
|
|
- dev, &ip4_hdr->saddr, &ip4_hdr->daddr, ip4_hdr->protocol);
|
|
- /*
|
|
- * Go through Linux network stack.
|
|
- */
|
|
- netif_receive_skb(skb);
|
|
+ nss_connmgr_map_t_trace("%px: ipv4 packet exceptioned after v6 ---> v4 xlate, created original ipv6 packet\n", dev);
|
|
+ nss_connmgr_map_t_trace("%p: Calculted ipv6 params: src_addr=%pI6, dest_addr=%pI6, payload_len=%d, checksum=%x\n", dev, v6saddr, v6daddr, payload_len, l4_csum);
|
|
+
|
|
+ dev_queue_xmit(skb);
|
|
return;
|
|
}
|
|
|
|
--- a/match/nss_match_priv.h
|
|
+++ b/match/nss_match_priv.h
|
|
@@ -29,19 +29,19 @@
|
|
/*
|
|
* Statically compile messages at different levels
|
|
*/
|
|
-#if (NSS_match_DEBUG_LEVEL < 2)
|
|
+#if (NSS_MATCH_DEBUG_LEVEL < 2)
|
|
#define nss_match_warn(s, ...)
|
|
#else
|
|
#define nss_match_warn(s, ...) pr_warn("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
#endif
|
|
|
|
-#if (NSS_match_DEBUG_LEVEL < 3)
|
|
+#if (NSS_MATCH_DEBUG_LEVEL < 3)
|
|
#define nss_match_info(s, ...)
|
|
#else
|
|
#define nss_match_info(s, ...) pr_notice("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
#endif
|
|
|
|
-#if (NSS_match_DEBUG_LEVEL < 4)
|
|
+#if (NSS_MATCH_DEBUG_LEVEL < 4)
|
|
#define nss_match_trace(s, ...)
|
|
#else
|
|
#define nss_match_trace(s, ...) pr_info("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
--- a/mirror/Makefile
|
|
+++ b/mirror/Makefile
|
|
@@ -2,7 +2,7 @@
|
|
|
|
ccflags-y += $(NSS_CCFLAGS) -I$(obj)/../../exports
|
|
ccflags-y += -DNSS_MIRROR_DEBUG_LEVEL=2
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
|
|
obj-m += qca-nss-mirror.o
|
|
qca-nss-mirror-objs := \
|
|
--- a/mirror/nss_mirror.c
|
|
+++ b/mirror/nss_mirror.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
***************************************************************************
|
|
- * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2020, 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
|
|
@@ -180,28 +180,6 @@ static struct rtnl_link_stats64 *nss_mir
|
|
return stats;
|
|
}
|
|
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
|
|
-/*
|
|
- * nss_mirror_netdev_stats64()
|
|
- * Netdev ops function to retrieve stats for kernel version < 4.6
|
|
- */
|
|
-static struct rtnl_link_stats64 *nss_mirror_netdev_stats64(struct net_device *dev,
|
|
- struct rtnl_link_stats64 *tot)
|
|
-{
|
|
- return nss_mirror_get_stats(dev, tot);
|
|
-}
|
|
-#else
|
|
-/*
|
|
- * nss_mirror_netdev_stats64()
|
|
- * Netdev ops function to retrieve stats
|
|
- */
|
|
-static void nss_mirror_netdev_stats64(struct net_device *dev,
|
|
- struct rtnl_link_stats64 *tot)
|
|
-{
|
|
- nss_mirror_get_stats(dev, tot);
|
|
-}
|
|
-#endif
|
|
-
|
|
/*
|
|
* nss_mirror_netdev_ops
|
|
* Mirror net device operations.
|
|
@@ -209,7 +187,7 @@ static void nss_mirror_netdev_stats64(st
|
|
static const struct net_device_ops nss_mirror_netdev_ops = {
|
|
.ndo_open = nss_mirror_netdev_up,
|
|
.ndo_stop = nss_mirror_netdev_down,
|
|
- .ndo_get_stats64 = nss_mirror_netdev_stats64,
|
|
+ .ndo_get_stats64 = nss_mirror_get_stats,
|
|
};
|
|
|
|
/*
|
|
@@ -300,6 +278,10 @@ static void nss_mirror_data_cb(struct ne
|
|
return;
|
|
}
|
|
|
|
+ nss_mirror_info("Printing 64 bytes of data\n");
|
|
+ print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1,
|
|
+ skb->data, 64, 0);
|
|
+
|
|
dev_hold(netdev);
|
|
|
|
/*
|
|
--- a/mscs/Makefile
|
|
+++ /dev/null
|
|
@@ -1,7 +0,0 @@
|
|
-# Makefile for mscs client
|
|
-ccflags-y += -I$(obj)/../exports -I$(obj)/..
|
|
-ccflags-y += -DNSS_CLIENT_BUILD_ID="$(BUILD_ID)"
|
|
-ccflags-y += -DNSS_MSCS_DEBUG_LEVEL=2
|
|
-ccflags-y += -Wall -Werror
|
|
-obj-m += qca-nss-mscs.o
|
|
-qca-nss-mscs-objs := nss_mscs.o
|
|
--- a/mscs/nss_mscs.c
|
|
+++ /dev/null
|
|
@@ -1,144 +0,0 @@
|
|
-/*
|
|
- **************************************************************************
|
|
- * Copyright (c) 2020-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.
|
|
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
|
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
- **************************************************************************
|
|
- */
|
|
-
|
|
-#include <linux/version.h>
|
|
-#include <linux/types.h>
|
|
-#include <linux/of.h>
|
|
-#include <linux/module.h>
|
|
-#include <linux/skbuff.h>
|
|
-
|
|
-#include <qca_mscs_if.h>
|
|
-#include <qca_mesh_latency_if.h>
|
|
-#include <nss_api_if.h>
|
|
-#include <ecm_classifier_mscs_public.h>
|
|
-#include <ecm_classifier_emesh_public.h>
|
|
-#include <qca_scs_if.h>
|
|
-
|
|
-#if defined(CONFIG_DYNAMIC_DEBUG)
|
|
-
|
|
-/*
|
|
- * Compile messakes for dynamic enable/disable
|
|
- */
|
|
-#define nss_mscs_warning(s, ...) pr_debug("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
|
|
-#define nss_mscs_info(s, ...) pr_debug("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
|
|
-#define nss_mscs_trace(s, ...) pr_debug("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
|
|
-#else
|
|
-
|
|
-/*
|
|
- * Statically compile messages at different levels
|
|
- */
|
|
-#if (NSS_MSCS_DEBUG_LEVEL < 2)
|
|
-#define nss_mscs_warning(s, ...)
|
|
-#else
|
|
-#define nss_mscs_warning(s, ...) pr_warn("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
|
|
-#endif
|
|
-
|
|
-#if (NSS_MSCS_DEBUG_LEVEL < 3)
|
|
-#define nss_mscs_info(s, ...)
|
|
-#else
|
|
-#define nss_mscs_info(s, ...) pr_notice("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
|
|
-#endif
|
|
-
|
|
-#if (NSS_MSCS_DEBUG_LEVEL < 4)
|
|
-#define nss_mscs_trace(s, ...)
|
|
-#else
|
|
-#define nss_mscs_trace(s, ...) pr_info("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
|
|
-#endif
|
|
-#endif
|
|
-
|
|
-/*
|
|
- * nss_mscs_ecm
|
|
- * Register MSCS client callback with ECM MSCS classifier to support MSCS wifi peer lookup.
|
|
- */
|
|
-static struct ecm_classifier_mscs_callbacks nss_mscs_ecm = {
|
|
- .get_peer_priority = qca_mscs_peer_lookup_n_get_priority,
|
|
- .update_skb_priority = qca_scs_peer_lookup_n_rule_match,
|
|
-};
|
|
-
|
|
-/*
|
|
- * nss_emesh_ecm
|
|
- * Register EMESH client callback with ECM EMSH-SAWF classifier to update peer mesh latency parameters.
|
|
- */
|
|
-static struct ecm_classifier_emesh_sawf_callbacks nss_emesh_ecm = {
|
|
- .update_peer_mesh_latency_params = qca_mesh_latency_update_peer_parameter,
|
|
-};
|
|
-
|
|
-/*
|
|
- * nss_mscs_init_module()
|
|
- * MSCS clinet module init function
|
|
- */
|
|
-int __init nss_mscs_init_module(void)
|
|
-{
|
|
-#ifdef CONFIG_OF
|
|
- /*
|
|
- * If the node is not compatible, don't do anything.
|
|
- */
|
|
- if (!of_find_node_by_name(NULL, "nss-common")) {
|
|
- return 0;
|
|
- }
|
|
-#endif
|
|
-
|
|
- /*
|
|
- * MSCS is enabled only on supported platform
|
|
- */
|
|
- if (!nss_cmn_get_nss_enabled()) {
|
|
- nss_mscs_warning("MSCS client is not compatible with this Platform\n");
|
|
- return -1;
|
|
- }
|
|
-
|
|
- if (ecm_classifier_mscs_callback_register(&nss_mscs_ecm)) {
|
|
- nss_mscs_warning("ecm mscs classifier callback registration failed.\n");
|
|
- return -1;
|
|
- }
|
|
-
|
|
- if (ecm_classifier_emesh_latency_config_callback_register(&nss_emesh_ecm)) {
|
|
- ecm_classifier_mscs_callback_unregister();
|
|
- nss_mscs_warning("ecm mesh classifier callback registration failed.\n");
|
|
- return -1;
|
|
- }
|
|
-
|
|
- nss_mscs_info("NSS MSCS Client loaded: %s\n", NSS_CLIENT_BUILD_ID);
|
|
- return 0;
|
|
-
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_mscs_exit_module()
|
|
- * MSCS module exit function
|
|
- */
|
|
-void __exit nss_mscs_exit_module(void)
|
|
-{
|
|
-#ifdef CONFIG_OF
|
|
-
|
|
- /*
|
|
- * If the node is not compatible, don't do anything.
|
|
- */
|
|
- if (!of_find_node_by_name(NULL, "nss-common")) {
|
|
- return;
|
|
- }
|
|
-#endif
|
|
-
|
|
- ecm_classifier_mscs_callback_unregister();
|
|
- ecm_classifier_emesh_latency_config_callback_unregister();
|
|
- nss_mscs_info("MSCS Client unloaded\n");
|
|
-
|
|
-}
|
|
-
|
|
-module_init(nss_mscs_init_module);
|
|
-module_exit(nss_mscs_exit_module);
|
|
-
|
|
-MODULE_LICENSE("Dual BSD/GPL");
|
|
-MODULE_DESCRIPTION("NSS MSCS client module");
|
|
--- a/netlink/Makefile
|
|
+++ b/netlink/Makefile
|
|
@@ -1,8 +1,9 @@
|
|
+GRE_ENABLED := $(strip $(if $(filter $(gre), y), 1 , 0))
|
|
CAPWAP_ENABLED := $(strip $(if $(filter $(capwapmgr), y), 1 , 0))
|
|
-IPSEC_ENABLED := $(strip $(if $(filter $(ipsecmgr), y), 1 , 0))
|
|
+IPSEC_ENABLED := 0
|
|
DTLS_ENABLED := $(strip $(if $(filter $(dtlsmgr), y), 1 , 0))
|
|
|
|
-ccflags-y := -Wall -Werror
|
|
+ccflags-y := -Werror
|
|
ccflags-y += -I$(obj)/include
|
|
ccflags-y += -I$(obj)/../exports
|
|
ccflags-y += -DNSS_NL_DEBUG_LEVEL=4
|
|
@@ -10,48 +11,39 @@ ccflags-y += -DNSS_CLIENT_BUILD_ID="$(BU
|
|
|
|
ccflags-y += -DCONFIG_NSS_NLIPV4=1
|
|
ccflags-y += -DCONFIG_NSS_NLIPV6=1
|
|
-ccflags-y += -DCONFIG_NSS_NLOAM=1
|
|
-ccflags-y += -DCONFIG_NSS_NLGRE_REDIR_FAMILY=1
|
|
+ccflags-y += -DCONFIG_NSS_NLOAM=0
|
|
+ccflags-y += -DCONFIG_NSS_NLGRE_REDIR_FAMILY=${GRE_ENABLED}
|
|
ccflags-y += -DCONFIG_NSS_NLETHRX=1
|
|
ccflags-y += -DCONFIG_NSS_NLDYNAMIC_INTERFACE=1
|
|
ccflags-y += -DCONFIG_NSS_NLN2H=1
|
|
-ccflags-y += -DCONFIG_NSS_NLIPV4_REASM=1
|
|
-ccflags-y += -DCONFIG_NSS_NLIPV6_REASM=1
|
|
+ccflags-y += -DCONFIG_NSS_NLIPV4_REASM=0
|
|
+ccflags-y += -DCONFIG_NSS_NLIPV6_REASM=0
|
|
ccflags-y += -DCONFIG_NSS_NLWIFILI=1
|
|
ccflags-y += -DCONFIG_NSS_NLLSO_RX=1
|
|
-ccflags-y += -DCONFIG_NSS_NLMAP_T=1
|
|
-ccflags-y += -DCONFIG_NSS_NLPPPOE=1
|
|
-ccflags-y += -DCONFIG_NSS_NLL2TPV2=1
|
|
-ccflags-y += -DCONFIG_NSS_NLQRFS=1
|
|
-ccflags-y += -DCONFIG_NSS_NLPPTP=1
|
|
+ccflags-y += -DCONFIG_NSS_NLMAP_T=0
|
|
+ccflags-y += -DCONFIG_NSS_NLPPPOE=0
|
|
+ccflags-y += -DCONFIG_NSS_NLL2TPV2=0
|
|
+ccflags-y += -DCONFIG_NSS_NLPPTP=0
|
|
ccflags-y += -DCONFIG_NSS_NLCAPWAP=${CAPWAP_ENABLED}
|
|
ccflags-y += -DCONFIG_NSS_NLIPSEC=${IPSEC_ENABLED}
|
|
ccflags-y += -DCONFIG_NSS_NLDTLS=${DTLS_ENABLED}
|
|
-ccflags-y += -DCONFIG_NSS_NLUDP_ST=1
|
|
|
|
qca-nss-netlink-objs := nss_nl.o
|
|
-qca-nss-netlink-objs += nss_nlgre_redir_family.o
|
|
-qca-nss-netlink-objs += nss_nlgre_redir_cmd.o
|
|
-qca-nss-netlink-objs += nss_nlgre_redir_cmn.o
|
|
-qca-nss-netlink-objs += nss_nlgre_redir.o
|
|
-qca-nss-netlink-objs += nss_nlgre_redir_lag.o
|
|
qca-nss-netlink-objs += nss_nlipv4.o
|
|
qca-nss-netlink-objs += nss_nlipv6.o
|
|
-qca-nss-netlink-objs += nss_nloam.o
|
|
+# qca-nss-netlink-objs += nss_nloam.o
|
|
qca-nss-netlink-objs += nss_nlethrx.o
|
|
qca-nss-netlink-objs += nss_nldynamic_interface.o
|
|
qca-nss-netlink-objs += nss_nln2h.o
|
|
-qca-nss-netlink-objs += nss_nlipv4_reasm.o
|
|
-qca-nss-netlink-objs += nss_nlipv6_reasm.o
|
|
+# qca-nss-netlink-objs += nss_nlipv4_reasm.o
|
|
+# qca-nss-netlink-objs += nss_nlipv6_reasm.o
|
|
qca-nss-netlink-objs += nss_nlwifili.o
|
|
qca-nss-netlink-objs += nss_nllso_rx.o
|
|
-qca-nss-netlink-objs += nss_nlmap_t.o
|
|
-qca-nss-netlink-objs += nss_nlpppoe.o
|
|
-qca-nss-netlink-objs += nss_nll2tpv2.o
|
|
-qca-nss-netlink-objs += nss_nlpptp.o
|
|
-qca-nss-netlink-objs += nss_nludp_st.o
|
|
-qca-nss-netlink-objs += nss_nlqrfs.o
|
|
-
|
|
+# qca-nss-netlink-objs += nss_nlmap_t.o
|
|
+# qca-nss-netlink-objs += nss_nlpppoe.o
|
|
+# qca-nss-netlink-objs += nss_nll2tpv2.o
|
|
+# qca-nss-netlink-objs += nss_nlpptp.o
|
|
+#
|
|
ifneq (,$(filter $(capwapmgr), y))
|
|
qca-nss-netlink-objs += nss_nlcapwap.o
|
|
endif
|
|
@@ -60,8 +52,12 @@ ifneq (,$(filter $(dtlsmgr), y))
|
|
qca-nss-netlink-objs += nss_nldtls.o
|
|
endif
|
|
|
|
-ifneq (,$(filter $(ipsecmgr), y))
|
|
-qca-nss-netlink-objs += nss_nlipsec.o
|
|
+ifneq (,$(filter $(gre), y))
|
|
+qca-nss-netlink-objs += nss_nlgre_redir_family.o
|
|
+qca-nss-netlink-objs += nss_nlgre_redir_cmd.o
|
|
+qca-nss-netlink-objs += nss_nlgre_redir_cmn.o
|
|
+qca-nss-netlink-objs += nss_nlgre_redir.o
|
|
+qca-nss-netlink-objs += nss_nlgre_redir_lag.o
|
|
endif
|
|
|
|
ifeq ($(SoC),$(filter $(SoC),ipq807x ipq807x_64))
|
|
--- a/netlink/nss_nl.c
|
|
+++ b/netlink/nss_nl.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2015-2016,2018-2021 The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2015-2016,2018-2020 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.
|
|
@@ -35,8 +35,6 @@
|
|
#include "nss_nlcmn_if.h"
|
|
#include "nss_nldtls.h"
|
|
#include "nss_nldtls_if.h"
|
|
-#include "nss_nlgre_redir_if.h"
|
|
-#include "nss_nlgre_redir_family.h"
|
|
#include "nss_nlipsec.h"
|
|
#include "nss_nlipsec_if.h"
|
|
#include "nss_nlipv4.h"
|
|
@@ -59,10 +57,6 @@
|
|
#include "nss_nlc2c_tx_if.h"
|
|
#include "nss_nlc2c_rx.h"
|
|
#include "nss_nlc2c_rx_if.h"
|
|
-#include "nss_nlipv4_reasm.h"
|
|
-#include "nss_nlipv4_reasm_if.h"
|
|
-#include "nss_nlipv6_reasm.h"
|
|
-#include "nss_nlipv6_reasm_if.h"
|
|
#include "nss_nlwifili.h"
|
|
#include "nss_nlwifili_if.h"
|
|
#include "nss_nllso_rx.h"
|
|
@@ -75,10 +69,6 @@
|
|
#include "nss_nll2tpv2_if.h"
|
|
#include "nss_nlpptp.h"
|
|
#include "nss_nlpptp_if.h"
|
|
-#include "nss_nludp_st.h"
|
|
-#include "nss_nludp_st_if.h"
|
|
-#include "nss_nlqrfs.h"
|
|
-#include "nss_nlqrfs_if.h"
|
|
|
|
/*
|
|
* nss_nl.c
|
|
@@ -110,24 +100,6 @@ static struct nss_nl_family family_handl
|
|
},
|
|
{
|
|
/*
|
|
- * NSS_NLIPSEC
|
|
- */
|
|
- .name = NSS_NLIPSEC_FAMILY, /* ipsec */
|
|
- .entry = NSS_NLIPSEC_INIT, /* init */
|
|
- .exit = NSS_NLIPSEC_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLIPSEC /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
- * NSS_NLOAM
|
|
- */
|
|
- .name = NSS_NLOAM_FAMILY, /* oam */
|
|
- .entry = NSS_NLOAM_INIT, /* init */
|
|
- .exit = NSS_NLOAM_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLOAM /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
* NSS_NLIPV6
|
|
*/
|
|
.name = NSS_NLIPV6_FAMILY, /* ipv6 */
|
|
@@ -137,24 +109,6 @@ static struct nss_nl_family family_handl
|
|
},
|
|
{
|
|
/*
|
|
- * NSS_NLGRE_REDIR
|
|
- */
|
|
- .name = NSS_NLGRE_REDIR_FAMILY, /* gre_redir */
|
|
- .entry = NSS_NLGRE_REDIR_FAMILY_INIT, /* init */
|
|
- .exit = NSS_NLGRE_REDIR_FAMILY_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLGRE_REDIR_FAMILY /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
- * NSS_NLCAPWAP
|
|
- */
|
|
- .name = NSS_NLCAPWAP_FAMILY, /* capwap */
|
|
- .entry = NSS_NLCAPWAP_INIT, /* init */
|
|
- .exit = NSS_NLCAPWAP_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLCAPWAP /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
* NSS_NLDTLS
|
|
*/
|
|
.name = NSS_NLDTLS_FAMILY, /* dtls */
|
|
@@ -173,15 +127,6 @@ static struct nss_nl_family family_handl
|
|
},
|
|
{
|
|
/*
|
|
- * NSS_NLEDMA
|
|
- */
|
|
- .name = NSS_NLEDMA_FAMILY, /* edma */
|
|
- .entry = NSS_NLEDMA_INIT, /* init */
|
|
- .exit = NSS_NLEDMA_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLEDMA /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
* NSS_NLDYNAMIC_INTERFACE
|
|
*/
|
|
.name = NSS_NLDYNAMIC_INTERFACE_FAMILY, /* dynamic interface */
|
|
@@ -200,42 +145,6 @@ static struct nss_nl_family family_handl
|
|
},
|
|
{
|
|
/*
|
|
- * NSS_NLC2C_TX
|
|
- */
|
|
- .name = NSS_NLC2C_TX_FAMILY, /* c2c_tx */
|
|
- .entry = NSS_NLC2C_TX_INIT, /* init */
|
|
- .exit = NSS_NLC2C_TX_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLC2C_TX /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
- * NSS_NLC2C_RX
|
|
- */
|
|
- .name = NSS_NLC2C_RX_FAMILY, /* c2c_rx */
|
|
- .entry = NSS_NLC2C_RX_INIT, /* init */
|
|
- .exit = NSS_NLC2C_RX_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLC2C_RX /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
- * NSS_NLIPV4_REASM
|
|
- */
|
|
- .name = NSS_NLIPV4_REASM_FAMILY, /* ipv4_reasm */
|
|
- .entry = NSS_NLIPV4_REASM_INIT, /* init */
|
|
- .exit = NSS_NLIPV4_REASM_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLIPV4_REASM /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
- * NSS_NLIPV6_REASM
|
|
- */
|
|
- .name = NSS_NLIPV6_REASM_FAMILY, /* ipv6_reasm */
|
|
- .entry = NSS_NLIPV6_REASM_INIT, /* init */
|
|
- .exit = NSS_NLIPV6_REASM_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLIPV6_REASM /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
* NSS_NLWIFILI
|
|
*/
|
|
.name = NSS_NLWIFILI_FAMILY, /* wifili */
|
|
@@ -252,62 +161,6 @@ static struct nss_nl_family family_handl
|
|
.exit = NSS_NLLSO_RX_EXIT, /* exit */
|
|
.valid = CONFIG_NSS_NLLSO_RX /* 1 or 0 */
|
|
},
|
|
- {
|
|
- /*
|
|
- * NSS_NLMAP_T
|
|
- */
|
|
- .name = NSS_NLMAP_T_FAMILY, /* map_t */
|
|
- .entry = NSS_NLMAP_T_INIT, /* init */
|
|
- .exit = NSS_NLMAP_T_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLMAP_T /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
- * NSS_NLPPPOE
|
|
- */
|
|
- .name = NSS_NLPPPOE_FAMILY, /* pppoe */
|
|
- .entry = NSS_NLPPPOE_INIT, /* init */
|
|
- .exit = NSS_NLPPPOE_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLPPPOE /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
- * NSS_NLL2TPV2
|
|
- */
|
|
- .name = NSS_NLL2TPV2_FAMILY, /* l2tpv2 */
|
|
- .entry = NSS_NLL2TPV2_INIT, /* init */
|
|
- .exit = NSS_NLL2TPV2_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLL2TPV2 /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
- * NSS_NLPPTP
|
|
- */
|
|
- .name = NSS_NLPPTP_FAMILY, /* pptp */
|
|
- .entry = NSS_NLPPTP_INIT, /* init */
|
|
- .exit = NSS_NLPPTP_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLPPTP /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
- * NSS_NLUDP_ST
|
|
- */
|
|
- .name = NSS_NLUDP_ST_FAMILY, /* udp_st */
|
|
- .entry = NSS_NLUDP_ST_INIT, /* init */
|
|
- .exit = NSS_NLUDP_ST_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLUDP_ST /* 1 or 0 */
|
|
- },
|
|
- {
|
|
- /*
|
|
- * NSS_NLQRFS
|
|
- */
|
|
- .name = NSS_NLQRFS_FAMILY, /* qrfs */
|
|
- .entry = NSS_NLQRFS_INIT, /* init */
|
|
- .exit = NSS_NLQRFS_EXIT, /* exit */
|
|
- .valid = CONFIG_NSS_NLQRFS /* 1 or 0 */
|
|
- },
|
|
-
|
|
-
|
|
};
|
|
|
|
#define NSS_NL_FAMILY_HANDLER_SZ ARRAY_SIZE(family_handlers)
|
|
--- a/netlink/nss_nl.h
|
|
+++ b/netlink/nss_nl.h
|
|
@@ -25,6 +25,7 @@
|
|
#define NSS_NL_DEBUG_LVL_WARN 2
|
|
#define NSS_NL_DEBUG_LVL_INFO 3
|
|
#define NSS_NL_DEBUG_LVL_TRACE 4
|
|
+#define GENL_ID_GENERATE 0
|
|
|
|
|
|
#if defined(CONFIG_DYNAMIC_DEBUG)
|
|
--- a/netlink/nss_nlcapwap.c
|
|
+++ b/netlink/nss_nlcapwap.c
|
|
@@ -1,12 +1,9 @@
|
|
/*
|
|
**************************************************************************
|
|
* Copyright (c) 2015-2016,2018-2020 The Linux Foundation. All rights reserved.
|
|
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. 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.
|
|
- *
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
@@ -39,7 +36,6 @@
|
|
#include <nss_dtls_cmn.h>
|
|
#include <nss_nlcmn_if.h>
|
|
#include <nss_nl_if.h>
|
|
-#include "nss_crypto_defines.h"
|
|
#include "nss_nl.h"
|
|
#include "nss_nlcapwap_if.h"
|
|
#include "nss_nlcapwap.h"
|
|
@@ -162,17 +158,6 @@ struct nss_nlcapwap_hdr {
|
|
*/
|
|
static struct nss_nlcapwap_global_ctx global_ctx;
|
|
|
|
-static int nss_nlcapwap_ops_create_tun(struct sk_buff *skb, struct genl_info *info);
|
|
-static int nss_nlcapwap_ops_destroy_tun(struct sk_buff *skb, struct genl_info *info);
|
|
-static int nss_nlcapwap_ops_update_mtu(struct sk_buff *skb, struct genl_info *info);
|
|
-static int nss_nlcapwap_ops_dtls(struct sk_buff *skb, struct genl_info *info);
|
|
-static int nss_nlcapwap_ops_perf(struct sk_buff *skb, struct genl_info *info);
|
|
-static int nss_nlcapwap_ops_tx_packets(struct sk_buff *skb, struct genl_info *info);
|
|
-static int nss_nlcapwap_ops_meta_header(struct sk_buff *skb, struct genl_info *info);
|
|
-static int nss_nlcapwap_ops_ip_flow(struct sk_buff *skb, struct genl_info *info);
|
|
-static int nss_nlcapwap_ops_keepalive(struct sk_buff *skb, struct genl_info *info);
|
|
-static int nss_nlcapwap_ops_get_stats(struct sk_buff *skb, struct genl_info *info);
|
|
-
|
|
/*
|
|
* nss_nlcapwap_family_mcgrp
|
|
* Multicast group for sending message status & events
|
|
@@ -182,30 +167,11 @@ static const struct genl_multicast_group
|
|
};
|
|
|
|
/*
|
|
- * nss_nlcapwap_cmd_ops
|
|
- * Operation table called by the generic netlink layer based on the command
|
|
- */
|
|
-struct genl_ops nss_nlcapwap_cmd_ops[] = {
|
|
- {.cmd = NSS_NLCAPWAP_CMD_TYPE_CREATE_TUN, .doit = nss_nlcapwap_ops_create_tun,},
|
|
- {.cmd = NSS_NLCAPWAP_CMD_TYPE_DESTROY_TUN, .doit = nss_nlcapwap_ops_destroy_tun,},
|
|
- {.cmd = NSS_NLCAPWAP_CMD_TYPE_UPDATE_MTU, .doit = nss_nlcapwap_ops_update_mtu,},
|
|
- {.cmd = NSS_NLCAPWAP_CMD_TYPE_DTLS, .doit = nss_nlcapwap_ops_dtls,},
|
|
- {.cmd = NSS_NLCAPWAP_CMD_TYPE_PERF, .doit = nss_nlcapwap_ops_perf,},
|
|
- {.cmd = NSS_NLCAPWAP_CMD_TYPE_TX_PACKETS, .doit = nss_nlcapwap_ops_tx_packets,},
|
|
- {.cmd = NSS_NLCAPWAP_CMD_TYPE_META_HEADER, .doit = nss_nlcapwap_ops_meta_header,},
|
|
- {.cmd = NSS_NLCAPWAP_CMD_TYPE_IP_FLOW, .doit = nss_nlcapwap_ops_ip_flow,},
|
|
- {.cmd = NSS_NLCAPWAP_CMD_TYPE_KEEPALIVE, .doit = nss_nlcapwap_ops_keepalive,},
|
|
- {.cmd = NSS_STATS_EVENT_NOTIFY, .doit = nss_nlcapwap_ops_get_stats,},
|
|
-};
|
|
-
|
|
-/*
|
|
* nss_nlcapwap_family
|
|
* Capwap family definition
|
|
*/
|
|
struct genl_family nss_nlcapwap_family = {
|
|
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0))
|
|
.id = GENL_ID_GENERATE, /* Auto generate ID */
|
|
-#endif
|
|
.name = NSS_NLCAPWAP_FAMILY, /* family name string */
|
|
.hdrsize = sizeof(struct nss_nlcapwap_rule), /* NSS NETLINK capwap rule */
|
|
.version = NSS_NL_VER, /* Set it to NSS_NL_VER version */
|
|
@@ -213,10 +179,6 @@ struct genl_family nss_nlcapwap_family =
|
|
.netnsok = true,
|
|
.pre_doit = NULL,
|
|
.post_doit = NULL,
|
|
- .ops = nss_nlcapwap_cmd_ops,
|
|
- .n_ops = ARRAY_SIZE(nss_nlcapwap_cmd_ops),
|
|
- .mcgrps = nss_nlcapwap_family_mcgrp,
|
|
- .n_mcgrps = ARRAY_SIZE(nss_nlcapwap_family_mcgrp)
|
|
};
|
|
|
|
/*
|
|
@@ -601,7 +563,6 @@ static void nss_nlcapwap_create_tun_ipv4
|
|
}
|
|
|
|
capwap_rule->enabled_features = features;
|
|
- capwap_rule->outer_sgt_value = nl_rule->msg.create.rule.outer_sgt_value;
|
|
|
|
/*
|
|
* Configure IPv4 rule
|
|
@@ -1471,6 +1432,23 @@ static const struct file_operations nss_
|
|
};
|
|
|
|
/*
|
|
+ * nss_nlcapwap_cmd_ops
|
|
+ * Operation table called by the generic netlink layer based on the command
|
|
+ */
|
|
+struct genl_ops nss_nlcapwap_cmd_ops[] = {
|
|
+ {.cmd = NSS_NLCAPWAP_CMD_TYPE_CREATE_TUN, .doit = nss_nlcapwap_ops_create_tun,},
|
|
+ {.cmd = NSS_NLCAPWAP_CMD_TYPE_DESTROY_TUN, .doit = nss_nlcapwap_ops_destroy_tun,},
|
|
+ {.cmd = NSS_NLCAPWAP_CMD_TYPE_UPDATE_MTU, .doit = nss_nlcapwap_ops_update_mtu,},
|
|
+ {.cmd = NSS_NLCAPWAP_CMD_TYPE_DTLS, .doit = nss_nlcapwap_ops_dtls,},
|
|
+ {.cmd = NSS_NLCAPWAP_CMD_TYPE_PERF, .doit = nss_nlcapwap_ops_perf,},
|
|
+ {.cmd = NSS_NLCAPWAP_CMD_TYPE_TX_PACKETS, .doit = nss_nlcapwap_ops_tx_packets,},
|
|
+ {.cmd = NSS_NLCAPWAP_CMD_TYPE_META_HEADER, .doit = nss_nlcapwap_ops_meta_header,},
|
|
+ {.cmd = NSS_NLCAPWAP_CMD_TYPE_IP_FLOW, .doit = nss_nlcapwap_ops_ip_flow,},
|
|
+ {.cmd = NSS_NLCAPWAP_CMD_TYPE_KEEPALIVE, .doit = nss_nlcapwap_ops_keepalive,},
|
|
+ {.cmd = NSS_STATS_EVENT_NOTIFY, .doit = nss_nlcapwap_ops_get_stats,},
|
|
+};
|
|
+
|
|
+/*
|
|
* nss_nlcapwap_get_ifnum()
|
|
* Get the interface number corresponding to netdev
|
|
*/
|
|
--- a/netlink/nss_nldtls.c
|
|
+++ b/netlink/nss_nldtls.c
|
|
@@ -1,12 +1,9 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2015-2016,2018-2021 The Linux Foundation. All rights reserved.
|
|
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
- *
|
|
+ * Copyright (c) 2015-2016,2018-2020 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.
|
|
- *
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
@@ -449,7 +446,7 @@ static void nss_nldtls_data_callback(voi
|
|
* nss_nldtls_create_session()
|
|
* Create a DTLS session through dtlsmgr driver API.
|
|
*/
|
|
-static struct net_device *nss_nldtls_create_session(struct nss_nldtls_rule *nl_rule)
|
|
+static struct net_device *nss_nldtls_create_session(struct nss_nldtls_rule *nl_rule, uint32_t flags)
|
|
{
|
|
struct nss_nldtls_tun_ctx *dtls_tun_data;
|
|
struct nss_dtlsmgr_config dcfg;
|
|
@@ -466,7 +463,7 @@ static struct net_device *nss_nldtls_cre
|
|
|
|
memset(&dcfg, 0, sizeof(struct nss_dtlsmgr_config));
|
|
algo = nl_rule->msg.create.encap.cfg.crypto.algo;
|
|
- dcfg.flags = nl_rule->msg.create.flags | NSS_DTLSMGR_ENCAP_METADATA;
|
|
+ dcfg.flags = flags | (NSS_DTLSMGR_ENCAP_METADATA | NSS_DTLSMGR_HDR_CAPWAP);
|
|
if (algo == NSS_DTLSMGR_ALGO_AES_GCM)
|
|
dcfg.flags |= NSS_DTLSMGR_CIPHER_MODE_GCM;
|
|
|
|
@@ -608,11 +605,7 @@ static int nss_nldtls_create_ipv4_rule_e
|
|
ipv4.dest_port = nl_rule->msg.create.encap.cfg.sport;
|
|
ipv4.dest_port_xlate = nl_rule->msg.create.encap.cfg.sport;
|
|
|
|
- if (nl_rule->msg.create.flags & NSS_DTLSMGR_HDR_UDPLITE)
|
|
- ipv4.protocol = IPPROTO_UDPLITE;
|
|
- else
|
|
- ipv4.protocol = IPPROTO_UDP;
|
|
-
|
|
+ ipv4.protocol = IPPROTO_UDP;
|
|
ipv4.in_vlan_tag[0] = NSS_NLDTLS_VLAN_INVALID;
|
|
ipv4.out_vlan_tag[0] = NSS_NLDTLS_VLAN_INVALID;
|
|
ipv4.in_vlan_tag[1] = NSS_NLDTLS_VLAN_INVALID;
|
|
@@ -620,8 +613,6 @@ static int nss_nldtls_create_ipv4_rule_e
|
|
|
|
memcpy(&ipv4.src_mac[0], &nl_rule->msg.create.gmac_ifmac[0], sizeof(ipv4.src_mac));
|
|
|
|
- dev_put(ndev);
|
|
-
|
|
/*
|
|
* Create an ipv4 rule entry
|
|
*/
|
|
@@ -663,11 +654,7 @@ static int nss_nldtls_create_ipv6_rule_e
|
|
*/
|
|
memcpy(ipv6.src_ip, nl_rule->msg.create.encap.cfg.dip, sizeof(ipv6.src_ip));
|
|
memcpy(ipv6.dest_ip, nl_rule->msg.create.encap.cfg.sip, sizeof(ipv6.dest_ip));
|
|
-
|
|
- if (nl_rule->msg.create.flags & NSS_DTLSMGR_HDR_UDPLITE)
|
|
- ipv6.protocol = IPPROTO_UDPLITE;
|
|
- else
|
|
- ipv6.protocol = IPPROTO_UDP;
|
|
+ ipv6.protocol = IPPROTO_UDP;
|
|
|
|
ipv6.in_vlan_tag[0] = NSS_NLDTLS_VLAN_INVALID;
|
|
ipv6.in_vlan_tag[1] = NSS_NLDTLS_VLAN_INVALID;
|
|
@@ -676,8 +663,6 @@ static int nss_nldtls_create_ipv6_rule_e
|
|
|
|
memcpy(&ipv6.src_mac[0], &nl_rule->msg.create.gmac_ifmac[0], sizeof(ipv6.src_mac));
|
|
|
|
- dev_put(ndev);
|
|
-
|
|
/*
|
|
* Create an ipv6 rule entry
|
|
*/
|
|
@@ -744,7 +729,7 @@ static int nss_nldtls_ops_create_tun(str
|
|
* Create tunnel based on ip version
|
|
*/
|
|
if (nl_rule->msg.create.ip_version == NSS_NLDTLS_IP_VERS_4) {
|
|
- dtls_dev = nss_nldtls_create_session(nl_rule);
|
|
+ dtls_dev = nss_nldtls_create_session(nl_rule, NSS_NLDTLS_IPV4_SESSION);
|
|
if (!dtls_dev) {
|
|
nss_nl_error("%px: Unable to create dtls session for v4\n", skb);
|
|
return -EINVAL;
|
|
@@ -763,7 +748,7 @@ static int nss_nldtls_ops_create_tun(str
|
|
atomic_inc(&gbl_ctx.num_tun);
|
|
nss_nl_info("%px: Successfully created ipv4 dtls tunnel\n", skb);
|
|
} else {
|
|
- dtls_dev = nss_nldtls_create_session(nl_rule);
|
|
+ dtls_dev = nss_nldtls_create_session(nl_rule, NSS_DTLSMGR_HDR_IPV6);
|
|
if (!dtls_dev) {
|
|
nss_nl_error("%px: Unable to create dtls session for v6\n", skb);
|
|
return -EINVAL;
|
|
@@ -886,7 +871,6 @@ static int nss_nldtls_ops_update_config(
|
|
key_len = nl_rule->msg.update_config.config_update.crypto.cipher_key.len;
|
|
if (key_len > NSS_NLDTLS_CIPHER_KEY_MAX) {
|
|
nss_nl_error("Invalid cipher length: %u\n", key_len);
|
|
- dev_put(dev);
|
|
return -EINVAL;
|
|
}
|
|
|
|
@@ -894,7 +878,6 @@ static int nss_nldtls_ops_update_config(
|
|
key_len = nl_rule->msg.update_config.config_update.crypto.auth_key.len;
|
|
if (key_len > NSS_NLDTLS_AUTH_KEY_MAX) {
|
|
nss_nl_error("Invalid authentication length: %u\n", key_len);
|
|
- dev_put(dev);
|
|
return -EINVAL;
|
|
}
|
|
|
|
@@ -902,7 +885,6 @@ static int nss_nldtls_ops_update_config(
|
|
key_len = nl_rule->msg.update_config.config_update.crypto.nonce.len;
|
|
if (key_len > NSS_NLDTLS_NONCE_SIZE_MAX) {
|
|
nss_nl_error("Invalid nonce length: %u\n", key_len);
|
|
- dev_put(dev);
|
|
return -EINVAL;
|
|
}
|
|
|
|
--- a/netlink/nss_nlgre_redir_cmn.c
|
|
+++ b/netlink/nss_nlgre_redir_cmn.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
***************************************************************************
|
|
- * Copyright (c) 2015-2016, 2018-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2015-2016,2018-2020, 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.
|
|
@@ -325,7 +325,7 @@ static struct rtnl_link_stats64 *nss_nlg
|
|
int i;
|
|
|
|
for (i = 0; i < NSS_GRE_REDIR_MAX_INTERFACES; i++) {
|
|
- if (!nss_gre_redir_stats_get(i, &get_stats)) {
|
|
+ if (!nss_gre_redir_get_stats(i, &get_stats)) {
|
|
continue;
|
|
}
|
|
|
|
@@ -340,15 +340,15 @@ static struct rtnl_link_stats64 *nss_nlg
|
|
if (found == false)
|
|
return NULL;
|
|
|
|
- stats->tx_bytes = get_stats.tstats.tx_bytes;
|
|
- stats->tx_packets = get_stats.tstats.tx_packets;
|
|
- stats->rx_bytes = get_stats.tstats.rx_bytes;
|
|
- stats->rx_packets = get_stats.tstats.rx_packets;
|
|
- for (i = 0;i < ARRAY_SIZE(get_stats.tstats.rx_dropped); i++) {
|
|
- stats->rx_dropped += get_stats.tstats.rx_dropped[i];
|
|
+ stats->tx_bytes = get_stats.node_stats.tx_bytes;
|
|
+ stats->tx_packets = get_stats.node_stats.tx_packets;
|
|
+ stats->rx_bytes = get_stats.node_stats.rx_bytes;
|
|
+ stats->rx_packets = get_stats.node_stats.rx_packets;
|
|
+ for (i = 0;i < ARRAY_SIZE(get_stats.node_stats.rx_dropped); i++) {
|
|
+ stats->rx_dropped += get_stats.node_stats.rx_dropped[i];
|
|
}
|
|
|
|
- stats->tx_dropped = get_stats.tstats.tx_dropped;
|
|
+ stats->tx_dropped = get_stats.tx_dropped;
|
|
|
|
return stats;
|
|
}
|
|
--- a/netlink/nss_nlipsec.c
|
|
+++ b/netlink/nss_nlipsec.c
|
|
@@ -1,12 +1,9 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2015-2016,2018-2021 The Linux Foundation. All rights reserved.
|
|
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
- *
|
|
+ * Copyright (c) 2015-2016,2018-2020 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.
|
|
- *
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
@@ -52,8 +49,8 @@ static int nss_nlipsec_op_create_tunnel(
|
|
static int nss_nlipsec_op_destroy_tunnel(struct sk_buff *skb, struct genl_info *info);
|
|
static int nss_nlipsec_op_add_sa(struct sk_buff *skb, struct genl_info *info);
|
|
static int nss_nlipsec_op_delete_sa(struct sk_buff *skb, struct genl_info *info);
|
|
-static int nss_nlipsec_op_add_flow(struct sk_buff *skb, struct genl_info *info);
|
|
-static int nss_nlipsec_op_delete_flow(struct sk_buff *skb, struct genl_info *info);
|
|
+// static int nss_nlipsec_op_add_flow(struct sk_buff *skb, struct genl_info *info);
|
|
+// static int nss_nlipsec_op_delete_flow(struct sk_buff *skb, struct genl_info *info);
|
|
|
|
/*
|
|
* Hold netdevice references
|
|
@@ -111,14 +108,14 @@ static struct genl_ops nss_nlipsec_ops[]
|
|
.cmd = NSS_NLIPSEC_CMD_DEL_SA,
|
|
.doit = nss_nlipsec_op_delete_sa,
|
|
},
|
|
- { /* Add flow */
|
|
- .cmd = NSS_NLIPSEC_CMD_ADD_FLOW,
|
|
- .doit = nss_nlipsec_op_add_flow,
|
|
- },
|
|
- { /* Delete flow */
|
|
- .cmd = NSS_NLIPSEC_CMD_DEL_FLOW,
|
|
- .doit = nss_nlipsec_op_delete_flow,
|
|
- },
|
|
+ // { /* Add flow */
|
|
+ // .cmd = NSS_NLIPSEC_CMD_ADD_FLOW,
|
|
+ // .doit = nss_nlipsec_op_add_flow,
|
|
+ // },
|
|
+ // { /* Delete flow */
|
|
+ // .cmd = NSS_NLIPSEC_CMD_DEL_FLOW,
|
|
+ // .doit = nss_nlipsec_op_delete_flow,
|
|
+ // },
|
|
};
|
|
|
|
/*
|
|
@@ -329,7 +326,7 @@ int nss_nlipsec_get_mtu(struct net_devic
|
|
static int nss_nlipsec_op_create_tunnel(struct sk_buff *skb, struct genl_info *info)
|
|
{
|
|
struct nss_nlipsec_rule *nl_rule;
|
|
- struct nss_ipsecmgr_callback cb = {0};
|
|
+ struct nss_ipsecmgr_callback cb;
|
|
struct nss_nlcmn *nl_cm;
|
|
struct net_device *dev;
|
|
struct sk_buff *resp;
|
|
@@ -511,8 +508,6 @@ static struct nss_nlipsec_rule *nss_nlip
|
|
dev_put(*dev);
|
|
return NULL;
|
|
}
|
|
-
|
|
- dev_put(*dev);
|
|
return nl_rule;
|
|
}
|
|
|
|
@@ -552,7 +547,7 @@ static int nss_nlipsec_op_add_sa(struct
|
|
sa_data->cmn.keys.auth_key = sa_rule->auth_key;
|
|
sa_data->cmn.keys.nonce = sa_rule->nonce;
|
|
|
|
- error = nss_ipsecmgr_sa_add_sync(dev, &sa_rule->tuple, sa_data, &if_num);
|
|
+ error = nss_ipsecmgr_sa_add(dev, &sa_rule->tuple, sa_data, &if_num);
|
|
if (error) {
|
|
nss_nl_error("%d: Failed to add SA for net device(%s), error:%d\n", pid, nl_rule->ifname, error);
|
|
goto free_dev;
|
|
@@ -630,72 +625,73 @@ static int nss_nlipsec_op_delete_sa(stru
|
|
* nss_nlipsec_op_add_flow()
|
|
* Add a flow
|
|
*/
|
|
-static int nss_nlipsec_op_add_flow(struct sk_buff *skb, struct genl_info *info)
|
|
-{
|
|
- struct nss_ipsecmgr_flow_tuple *flow_tuple;
|
|
- struct nss_ipsecmgr_sa_tuple *sa_tuple;
|
|
- struct nss_nlipsec_rule *nl_rule;
|
|
- struct net_device *dev;
|
|
- uint32_t pid;
|
|
- int error = 0;
|
|
-
|
|
- nl_rule = nss_nlipsec_get_rule(info, NSS_NLIPSEC_CMD_ADD_FLOW, &dev);
|
|
- if (!nl_rule) {
|
|
- nss_nl_error("Failed to extract SA data\n");
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- pid = nl_rule->cm.pid;
|
|
- nss_nl_error("%d: device(%s)", pid, dev->name);
|
|
-
|
|
- flow_tuple = &nl_rule->rule.flow.tuple;
|
|
- sa_tuple = &nl_rule->rule.flow.sa;
|
|
-
|
|
- error = nss_ipsecmgr_flow_add_sync(dev, flow_tuple, sa_tuple);
|
|
- if (error) {
|
|
- nss_nl_error("%d: Failed to add subnet for net_device(%s)", pid, nl_rule->ifname);
|
|
- }
|
|
-
|
|
- /*
|
|
- * dev_put for dev_get done on nss_nlipsec_get_rule
|
|
- */
|
|
- dev_put(dev);
|
|
- return error;
|
|
-}
|
|
+// static int nss_nlipsec_op_add_flow(struct sk_buff *skb, struct genl_info *info)
|
|
+// {
|
|
+// struct nss_ipsecmgr_flow_tuple *flow_tuple;
|
|
+// struct nss_ipsecmgr_sa_tuple *sa_tuple;
|
|
+// struct nss_nlipsec_rule *nl_rule;
|
|
+// struct net_device *dev;
|
|
+// uint32_t pid;
|
|
+// int error = 0;
|
|
+//
|
|
+// nl_rule = nss_nlipsec_get_rule(info, NSS_NLIPSEC_CMD_ADD_FLOW, &dev);
|
|
+// if (!nl_rule) {
|
|
+// nss_nl_error("Failed to extract SA data\n");
|
|
+// return -EINVAL;
|
|
+// }
|
|
+//
|
|
+// pid = nl_rule->cm.pid;
|
|
+// nss_nl_error("%d: device(%s)", pid, dev->name);
|
|
+//
|
|
+// flow_tuple = &nl_rule->rule.flow.tuple;
|
|
+// sa_tuple = &nl_rule->rule.flow.sa;
|
|
+//
|
|
+// //struct nss_ipsecmgr_ref *nss_ipsecmgr_flow_alloc(struct nss_ipsecmgr_priv *priv, struct nss_ipsecmgr_key *key)
|
|
+// error = nss_ipsecmgr_flow_add_sync(dev, flow_tuple, sa_tuple);
|
|
+// if (error) {
|
|
+// nss_nl_error("%d: Failed to add subnet for net_device(%s)", pid, nl_rule->ifname);
|
|
+// }
|
|
+//
|
|
+// /*
|
|
+// * dev_put for dev_get done on nss_nlipsec_get_rule
|
|
+// */
|
|
+// dev_put(dev);
|
|
+// return error;
|
|
+// }
|
|
|
|
/*
|
|
* nss_nlipsec_op_delete_flow()
|
|
* Delete a flow
|
|
*/
|
|
-static int nss_nlipsec_op_delete_flow(struct sk_buff *skb, struct genl_info *info)
|
|
-{
|
|
- struct nss_ipsecmgr_flow_tuple *flow_tuple;
|
|
- struct nss_ipsecmgr_sa_tuple *sa_tuple;
|
|
- struct nss_nlipsec_rule *nl_rule;
|
|
- struct net_device *dev;
|
|
- uint32_t pid;
|
|
- int error = 0;
|
|
-
|
|
- nl_rule = nss_nlipsec_get_rule(info, NSS_NLIPSEC_CMD_DEL_FLOW, &dev);
|
|
- if (!nl_rule) {
|
|
- nss_nl_error("Failed to extract SA data\n");
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- pid = nl_rule->cm.pid;
|
|
- nss_nl_error("%d: device(%s)", pid, dev->name);
|
|
-
|
|
- flow_tuple = &nl_rule->rule.flow.tuple;
|
|
- sa_tuple = &nl_rule->rule.flow.sa;
|
|
-
|
|
- nss_ipsecmgr_flow_del(dev, flow_tuple, sa_tuple);
|
|
-
|
|
- /*
|
|
- * dev_put for dev_get done on nss_nlipsec_get_rule
|
|
- */
|
|
- dev_put(dev);
|
|
- return error;
|
|
-}
|
|
+// static int nss_nlipsec_op_delete_flow(struct sk_buff *skb, struct genl_info *info)
|
|
+// {
|
|
+// struct nss_ipsecmgr_flow_tuple *flow_tuple;
|
|
+// struct nss_ipsecmgr_sa_tuple *sa_tuple;
|
|
+// struct nss_nlipsec_rule *nl_rule;
|
|
+// struct net_device *dev;
|
|
+// uint32_t pid;
|
|
+// int error = 0;
|
|
+//
|
|
+// nl_rule = nss_nlipsec_get_rule(info, NSS_NLIPSEC_CMD_DEL_FLOW, &dev);
|
|
+// if (!nl_rule) {
|
|
+// nss_nl_error("Failed to extract SA data\n");
|
|
+// return -EINVAL;
|
|
+// }
|
|
+//
|
|
+// pid = nl_rule->cm.pid;
|
|
+// nss_nl_error("%d: device(%s)", pid, dev->name);
|
|
+//
|
|
+// flow_tuple = &nl_rule->rule.flow.tuple;
|
|
+// sa_tuple = &nl_rule->rule.flow.sa;
|
|
+//
|
|
+// nss_ipsecmgr_flow_del(dev, flow_tuple, sa_tuple);
|
|
+//
|
|
+// /*
|
|
+// * dev_put for dev_get done on nss_nlipsec_get_rule
|
|
+// */
|
|
+// dev_put(dev);
|
|
+// return error;
|
|
+// }
|
|
|
|
/*
|
|
* nss_nlipsec_init()
|
|
--- a/netlink/nss_nlipv4.c
|
|
+++ b/netlink/nss_nlipv4.c
|
|
@@ -336,20 +336,6 @@ static int nss_nlipv4_verify_conn_rule(s
|
|
tuple->return_ident, tuple->flow_ident);
|
|
break;
|
|
|
|
- case NSS_NL_IFTYPE_TUNNEL_GRE:
|
|
- /*
|
|
- * Currently this implementation is only for gre_redir
|
|
- */
|
|
- conn->flow_interface_num = nss_nlgre_redir_cmd_get_ifnum(flow_dev, tuple->protocol);
|
|
- if (conn->flow_interface_num < 0 ) {
|
|
- nss_nl_error("%px: Failed to get flow interface number (dev:%s, type:%d)\n",
|
|
- flow_dev, flow_dev->name, flow_iftype);
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- conn->flow_mtu = nss_nlgre_redir_cmd_get_mtu(flow_dev, NSS_GRE_REDIR_IP_HDR_TYPE_IPV4, conn->flow_interface_num);
|
|
- break;
|
|
-
|
|
case NSS_NL_IFTYPE_VLAN:
|
|
conn->flow_interface_num = nss_cmn_get_interface_number_by_dev(vlan_dev_real_dev(flow_dev));
|
|
if (conn->flow_interface_num < 0 ) {
|
|
@@ -396,17 +382,6 @@ static int nss_nlipv4_verify_conn_rule(s
|
|
tuple->return_ident, tuple->flow_ident);
|
|
break;
|
|
|
|
- case NSS_NL_IFTYPE_TUNNEL_GRE:
|
|
- conn->return_interface_num = nss_nlgre_redir_cmd_get_ifnum(return_dev, tuple->protocol);
|
|
- if (conn->return_interface_num < 0 ) {
|
|
- nss_nl_error("%px: Failed to get return interface number (dev:%s, type:%d)\n",
|
|
- return_dev, return_dev->name, return_iftype);
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- conn->return_mtu = nss_nlgre_redir_cmd_get_mtu(return_dev, NSS_GRE_REDIR_IP_HDR_TYPE_IPV4, conn->return_interface_num);
|
|
- break;
|
|
-
|
|
case NSS_NL_IFTYPE_VLAN:
|
|
conn->return_interface_num = nss_cmn_get_interface_number_by_dev(vlan_dev_real_dev(return_dev));
|
|
if (conn->return_interface_num < 0 ) {
|
|
@@ -623,27 +598,6 @@ static int nss_nlipv4_verify_vlan_rule(s
|
|
}
|
|
|
|
/*
|
|
- * nss_nlipv4_verify_identifier()
|
|
- * verify and override identifier rule entries
|
|
- */
|
|
-static int nss_nlipv4_verify_identifier(struct nss_ipv4_rule_create_msg *msg)
|
|
-{
|
|
- struct nss_ipv4_identifier_rule *identifier = &msg->identifier;
|
|
- const size_t rule_sz = sizeof(struct nss_ipv4_identifier_rule);
|
|
- uint16_t valid;
|
|
-
|
|
- /*
|
|
- * if identifier is not valid, set identifier rule to 0
|
|
- */
|
|
- valid = msg->valid_flags & NSS_IPV4_RULE_CREATE_IDENTIFIER_VALID;
|
|
- if (!valid) {
|
|
- memset(identifier, 0, rule_sz);
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/*
|
|
* nss_nlipv4_process_notify()
|
|
* process notification messages from NSS
|
|
*/
|
|
@@ -823,15 +777,6 @@ static int nss_nlipv4_ops_create_rule(st
|
|
}
|
|
|
|
/*
|
|
- * check identifier
|
|
- */
|
|
- error = nss_nlipv4_verify_identifier(&nim->msg.rule_create);
|
|
- if (error < 0) {
|
|
- nss_nl_error("%d:invalid identifier rule information passed\n", pid);
|
|
- goto done;
|
|
- }
|
|
-
|
|
- /*
|
|
* copy the NL message for response
|
|
*/
|
|
resp = nss_nl_copy_msg(skb);
|
|
@@ -855,10 +800,6 @@ static int nss_nlipv4_ops_create_rule(st
|
|
* Push Rule to NSS
|
|
*/
|
|
tx_status = nss_ipv4_tx_sync(gbl_ctx.nss, nim);
|
|
-
|
|
- /* TODO: Handle the case where firmware has received the response
|
|
- * and there is a failure in firmware.
|
|
- */
|
|
if (tx_status != NSS_TX_SUCCESS) {
|
|
nss_nl_error("%d:unable to send IPv4 rule create, status(%d)\n", pid, tx_status);
|
|
error = -EBUSY;
|
|
@@ -933,10 +874,6 @@ static int nss_nlipv4_ops_destroy_rule(s
|
|
* Push rule to NSS
|
|
*/
|
|
tx_status = nss_ipv4_tx_sync(gbl_ctx.nss, nim);
|
|
-
|
|
- /* TODO: Handle the case where firmware has received the response
|
|
- * and there is a failure in firmware.
|
|
- */
|
|
if (tx_status != NSS_TX_SUCCESS) {
|
|
nss_nl_error("%d:unable to send IPv4 rule delete, status(%d)\n", pid, tx_status);
|
|
return -EBUSY;
|
|
--- a/netlink/nss_nlipv6.c
|
|
+++ b/netlink/nss_nlipv6.c
|
|
@@ -353,17 +353,6 @@ static int nss_nlipv6_verify_conn_rule(s
|
|
tuple->return_ident, tuple->flow_ident);
|
|
break;
|
|
|
|
- case NSS_NL_IFTYPE_TUNNEL_GRE:
|
|
- conn->flow_interface_num = nss_nlgre_redir_cmd_get_ifnum(flow_dev, tuple->protocol);
|
|
- if (conn->flow_interface_num < 0 ) {
|
|
- nss_nl_error("%px: Failed to get flow interface number (dev:%s, type:%d)\n",
|
|
- flow_dev, flow_dev->name, flow_iftype);
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- conn->flow_mtu = nss_nlgre_redir_cmd_get_mtu(flow_dev, NSS_GRE_REDIR_IP_HDR_TYPE_IPV6, conn->flow_interface_num);
|
|
- break;
|
|
-
|
|
case NSS_NL_IFTYPE_VLAN:
|
|
conn->flow_interface_num = nss_cmn_get_interface_number_by_dev(vlan_dev_real_dev(flow_dev));
|
|
if (conn->flow_interface_num < 0 ) {
|
|
@@ -411,17 +400,6 @@ static int nss_nlipv6_verify_conn_rule(s
|
|
tuple->return_ident, tuple->flow_ident);
|
|
break;
|
|
|
|
- case NSS_NL_IFTYPE_TUNNEL_GRE:
|
|
- conn->return_interface_num = nss_nlgre_redir_cmd_get_ifnum(return_dev, tuple->protocol);
|
|
- if (conn->return_interface_num < 0 ) {
|
|
- nss_nl_error("%px: Failed to get return interface number (dev:%s, type:%d)\n",
|
|
- return_dev, return_dev->name, return_iftype);
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- conn->return_mtu = nss_nlgre_redir_cmd_get_mtu(return_dev, NSS_GRE_REDIR_IP_HDR_TYPE_IPV6, conn->return_interface_num);
|
|
- break;
|
|
-
|
|
case NSS_NL_IFTYPE_VLAN:
|
|
conn->return_interface_num = nss_cmn_get_interface_number_by_dev(vlan_dev_real_dev(return_dev));
|
|
if (conn->return_interface_num < 0 ) {
|
|
@@ -624,27 +602,6 @@ static int nss_nlipv6_verify_vlan_rule(s
|
|
}
|
|
|
|
/*
|
|
- * nss_nlipv6_verify_identifier()
|
|
- * verify and override identifier rule entries
|
|
- */
|
|
-static int nss_nlipv6_verify_identifier(struct nss_ipv6_rule_create_msg *msg)
|
|
-{
|
|
- struct nss_ipv6_identifier_rule *identifier = &msg->identifier;
|
|
- const size_t rule_sz = sizeof(struct nss_ipv6_identifier_rule);
|
|
- uint16_t valid;
|
|
-
|
|
- /*
|
|
- * if identifier is not valid, set identifier rule to 0
|
|
- */
|
|
- valid = msg->valid_flags & NSS_IPV6_RULE_CREATE_IDENTIFIER_VALID;
|
|
- if (!valid) {
|
|
- memset(identifier, 0, rule_sz);
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/*
|
|
* nss_nlipv6_process_notify()
|
|
* process notification messages from NSS
|
|
*/
|
|
@@ -817,15 +774,6 @@ static int nss_nlipv6_ops_create_rule(st
|
|
}
|
|
|
|
/*
|
|
- * check identifier
|
|
- */
|
|
- error = nss_nlipv6_verify_identifier(&nim->msg.rule_create);
|
|
- if (error < 0) {
|
|
- nss_nl_error("%d:invalid identifier rule information passed\n", pid);
|
|
- goto done;
|
|
- }
|
|
-
|
|
- /*
|
|
* copy the NL message for response
|
|
*/
|
|
resp = nss_nl_copy_msg(skb);
|
|
@@ -855,10 +803,6 @@ static int nss_nlipv6_ops_create_rule(st
|
|
* Push Rule to NSS
|
|
*/
|
|
tx_status = nss_ipv6_tx_sync(gbl_ctx.nss, nim);
|
|
-
|
|
- /* TODO: Handle the case where firmware has received the response
|
|
- * and there is a failure in firmware.
|
|
- */
|
|
if (tx_status != NSS_TX_SUCCESS) {
|
|
nss_nl_error("%d:unable to send IPV6 rule create, status(%d)\n", pid, tx_status);
|
|
error = -EBUSY;
|
|
@@ -938,10 +882,6 @@ static int nss_nlipv6_ops_destroy_rule(s
|
|
* Push rule to NSS
|
|
*/
|
|
tx_status = nss_ipv6_tx_sync(gbl_ctx.nss, nim);
|
|
-
|
|
- /* TODO: Handle the case where firmware has received the response
|
|
- * and there is a failure in firmware.
|
|
- */
|
|
if (tx_status != NSS_TX_SUCCESS) {
|
|
nss_nl_error("%d:unable to send IPV6 rule delete, status(%d)\n", pid, tx_status);
|
|
return -EBUSY;
|
|
--- /dev/null
|
|
+++ b/nss_connmgr_tunipip6.c
|
|
@@ -0,0 +1,503 @@
|
|
+/*
|
|
+ **************************************************************************
|
|
+ * Copyright (c) 2014, 2017-2018, 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.
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
|
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
+ **************************************************************************
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * nss_tunipip6.c
|
|
+ *
|
|
+ * This file is the NSS DS-lit and IPP6 tunnel module
|
|
+ * ------------------------REVISION HISTORY-----------------------------
|
|
+ * Qualcomm Atheros 15/sep/2013 Created
|
|
+ */
|
|
+
|
|
+#include <linux/version.h>
|
|
+#include <linux/types.h>
|
|
+#include <linux/ip.h>
|
|
+#include <linux/of.h>
|
|
+#include <linux/tcp.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/skbuff.h>
|
|
+#include <net/ipv6.h>
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3,9,0))
|
|
+#include <net/ipip.h>
|
|
+#else
|
|
+#include <net/ip_tunnels.h>
|
|
+#endif
|
|
+#include <net/ip6_tunnel.h>
|
|
+#include <linux/if_arp.h>
|
|
+#include <nss_api_if.h>
|
|
+
|
|
+/*
|
|
+ * NSS tunipip6 debug macros
|
|
+ */
|
|
+#if (NSS_TUNIPIP6_DEBUG_LEVEL < 1)
|
|
+#define nss_tunipip6_assert(fmt, args...)
|
|
+#else
|
|
+#define nss_tunipip6_assert(c) if (!(c)) { BUG_ON(!(c)); }
|
|
+#endif
|
|
+
|
|
+#if defined(CONFIG_DYNAMIC_DEBUG)
|
|
+
|
|
+/*
|
|
+ * Compile messages for dynamic enable/disable
|
|
+ */
|
|
+#define nss_tunipip6_warning(s, ...) pr_debug("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
|
|
+#define nss_tunipip6_info(s, ...) pr_debug("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
|
|
+#define nss_tunipip6_trace(s, ...) pr_debug("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
|
|
+#else
|
|
+
|
|
+/*
|
|
+ * Statically compile messages at different levels
|
|
+ */
|
|
+#if (NSS_TUNIPIP6_DEBUG_LEVEL < 2)
|
|
+#define nss_tunipip6_warning(s, ...)
|
|
+#else
|
|
+#define nss_tunipip6_warning(s, ...) pr_warn("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
|
|
+#endif
|
|
+
|
|
+#if (NSS_TUNIPIP6_DEBUG_LEVEL < 3)
|
|
+#define nss_tunipip6_info(s, ...)
|
|
+#else
|
|
+#define nss_tunipip6_info(s, ...) pr_notice("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
|
|
+#endif
|
|
+
|
|
+#if (NSS_TUNIPIP6_DEBUG_LEVEL < 4)
|
|
+#define nss_tunipip6_trace(s, ...)
|
|
+#else
|
|
+#define nss_tunipip6_trace(s, ...) pr_info("%s[%d]:" s, __func__, __LINE__, ##__VA_ARGS__)
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * tunipip6 stats structure
|
|
+ */
|
|
+struct nss_tunipip6_stats {
|
|
+ uint32_t rx_packets; /* Number of received packets */
|
|
+ uint32_t rx_bytes; /* Number of received bytes */
|
|
+ uint32_t tx_packets; /* Number of transmitted packets */
|
|
+ uint32_t tx_bytes; /* Number of transmitted bytes */
|
|
+};
|
|
+
|
|
+/*
|
|
+ * nss_tunipip6_encap_exception()
|
|
+ * Exception handler registered to NSS driver.
|
|
+ *
|
|
+ * This function is called when no rule is found for successful encapsulation.
|
|
+ */
|
|
+static void nss_tunipip6_encap_exception(struct net_device *dev, struct sk_buff *skb, __attribute__((unused)) struct napi_struct *napi)
|
|
+{
|
|
+ skb->dev = dev;
|
|
+ nss_tunipip6_info("received - %d bytes name %s ver %x\n",
|
|
+ skb->len, dev->name, (skb->data[0] >> 4));
|
|
+
|
|
+ skb->protocol = htons(ETH_P_IP);
|
|
+ skb_reset_network_header(skb);
|
|
+ skb->pkt_type = PACKET_HOST;
|
|
+ skb->skb_iif = dev->ifindex;
|
|
+ skb->ip_summed = CHECKSUM_NONE;
|
|
+ netif_receive_skb(skb);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * nss_tunipip6_decap_exception()
|
|
+ * Exception handler registered to NSS driver.
|
|
+ *
|
|
+ * This function is called when no rule is found for successful decapsulation.
|
|
+ */
|
|
+static void nss_tunipip6_decap_exception(struct net_device *dev, struct sk_buff *skb, __attribute__((unused)) struct napi_struct *napi)
|
|
+{
|
|
+ skb->dev = dev;
|
|
+ nss_tunipip6_info("received - %d bytes name %s ver %x\n",
|
|
+ skb->len, dev->name, (skb->data[0] >> 4));
|
|
+
|
|
+ skb->protocol = htons(ETH_P_IPV6);
|
|
+ skb_reset_network_header(skb);
|
|
+ skb->pkt_type = PACKET_HOST;
|
|
+ skb->skb_iif = dev->ifindex;
|
|
+ skb->ip_summed = CHECKSUM_NONE;
|
|
+ netif_receive_skb(skb);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * nss_tunipip6_update_dev_stats
|
|
+ * Update the Dev stats received from NetAp
|
|
+ */
|
|
+static void nss_tunipip6_update_dev_stats(struct net_device *dev,
|
|
+ struct nss_tunipip6_stats_sync_msg *sync_stats)
|
|
+{
|
|
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
|
|
+ struct pcpu_sw_netstats stats;
|
|
+
|
|
+ u64_stats_init(&stats.syncp);
|
|
+ u64_stats_update_begin(&stats.syncp);
|
|
+ stats.rx_packets = sync_stats->node_stats.rx_packets;
|
|
+ stats.rx_bytes = sync_stats->node_stats.rx_bytes;
|
|
+ stats.tx_packets = sync_stats->node_stats.tx_packets;
|
|
+ stats.tx_bytes = sync_stats->node_stats.tx_bytes;
|
|
+ u64_stats_update_end(&stats.syncp);
|
|
+#else
|
|
+ struct nss_tunipip6_stats stats;
|
|
+
|
|
+ stats.rx_packets = sync_stats->node_stats.rx_packets;
|
|
+ stats.rx_bytes = sync_stats->node_stats.rx_bytes;
|
|
+ stats.tx_packets = sync_stats->node_stats.tx_packets;
|
|
+ stats.tx_bytes = sync_stats->node_stats.tx_bytes;
|
|
+#endif
|
|
+
|
|
+ dev->stats.rx_dropped += nss_cmn_rx_dropped_sum(&sync_stats->node_stats);
|
|
+ ip6_update_offload_stats(dev, (void *)&stats);
|
|
+
|
|
+}
|
|
+
|
|
+/*
|
|
+ * nss_tunipip6_event_receive()
|
|
+ * Event Callback to receive events from NSS.
|
|
+ */
|
|
+void nss_tunipip6_event_receive(void *if_ctx, struct nss_tunipip6_msg *tnlmsg)
|
|
+{
|
|
+ struct net_device *netdev = NULL;
|
|
+ netdev = (struct net_device *)if_ctx;
|
|
+
|
|
+ switch (tnlmsg->cm.type) {
|
|
+ case NSS_TUNIPIP6_RX_STATS_SYNC:
|
|
+ nss_tunipip6_update_dev_stats(netdev, (struct nss_tunipip6_stats_sync_msg *)&tnlmsg->msg.stats_sync);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ nss_tunipip6_info("%s: Unknown Event from NSS", __func__);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ * nss_tunipip6_dev_up()
|
|
+ * IPIP6 Tunnel device i/f up handler
|
|
+ */
|
|
+int nss_tunipip6_dev_up(struct net_device *netdev)
|
|
+{
|
|
+ struct ip6_tnl *tunnel;
|
|
+ struct nss_tunipip6_msg tnlmsg;
|
|
+ struct nss_tunipip6_create_msg *tnlcfg;
|
|
+ struct flowi6 *fl6;
|
|
+ uint32_t fmr_number = 0;
|
|
+ int inner_ifnum, outer_ifnum;
|
|
+ uint32_t features = 0;
|
|
+ nss_tx_status_t status;
|
|
+ struct nss_ctx_instance *nss_ctx;
|
|
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
|
+ struct __ip6_tnl_fmr *fmr;
|
|
+#endif
|
|
+
|
|
+ /*
|
|
+ * Validate netdev for ipv6-in-ipv4 Tunnel
|
|
+ */
|
|
+ if (netdev->type != ARPHRD_TUNNEL6 ) {
|
|
+ return NOTIFY_DONE;
|
|
+ }
|
|
+
|
|
+ tunnel = (struct ip6_tnl *)netdev_priv(netdev);
|
|
+
|
|
+ /*
|
|
+ * Find the Tunnel device flow information
|
|
+ */
|
|
+ fl6 = &tunnel->fl.u.ip6;
|
|
+
|
|
+ nss_tunipip6_trace("%p: Tunnel Param srcaddr %x:%x:%x:%x daddr %x:%x:%x:%x\n", netdev,
|
|
+ fl6->saddr.s6_addr32[0], fl6->saddr.s6_addr32[1],
|
|
+ fl6->saddr.s6_addr32[2], fl6->saddr.s6_addr32[3],
|
|
+ fl6->daddr.s6_addr32[0], fl6->daddr.s6_addr32[1],
|
|
+ fl6->daddr.s6_addr32[2], fl6->daddr.s6_addr32[3] );
|
|
+ nss_tunipip6_trace("%p: Hop limit %d\n", netdev, tunnel->parms.hop_limit);
|
|
+ nss_tunipip6_trace("%p: Tunnel param flag %x fl6.flowlabel %x\n", netdev, tunnel->parms.flags, fl6->flowlabel);
|
|
+
|
|
+ inner_ifnum = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_INNER);
|
|
+ if (inner_ifnum < 0) {
|
|
+ nss_tunipip6_warning("%p: Request interface number failed\n", netdev);
|
|
+ goto inner_alloc_fail;
|
|
+ }
|
|
+
|
|
+ outer_ifnum = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_OUTER);
|
|
+ if (outer_ifnum < 0) {
|
|
+ nss_tunipip6_warning("%p: Request interface number failed\n", netdev);
|
|
+ goto outer_alloc_fail;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Register ipip6 tunnel with NSS
|
|
+ */
|
|
+ nss_ctx = nss_register_tunipip6_if(inner_ifnum,
|
|
+ NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_INNER,
|
|
+ nss_tunipip6_encap_exception,
|
|
+ nss_tunipip6_event_receive,
|
|
+ netdev,
|
|
+ features);
|
|
+ if (!nss_ctx) {
|
|
+ nss_tunipip6_warning("%p: nss_register_tunipip6_if Failed\n", netdev);
|
|
+ goto inner_reg_fail;
|
|
+ }
|
|
+
|
|
+ nss_ctx = nss_register_tunipip6_if(outer_ifnum,
|
|
+ NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_OUTER,
|
|
+ nss_tunipip6_decap_exception,
|
|
+ nss_tunipip6_event_receive,
|
|
+ netdev,
|
|
+ features);
|
|
+ if (!nss_ctx) {
|
|
+ nss_tunipip6_warning("%p: nss_register_tunipip6_if Failed\n", netdev);
|
|
+ goto outer_reg_fail;
|
|
+ }
|
|
+
|
|
+ nss_tunipip6_trace("%p: nss_register_tunipip6_if Success\n", netdev);
|
|
+
|
|
+ /*
|
|
+ * Prepare The Tunnel configuration parameter to send to nss
|
|
+ */
|
|
+ memset(&tnlmsg, 0, sizeof(struct nss_tunipip6_msg));
|
|
+ tnlcfg = &tnlmsg.msg.tunipip6_create;
|
|
+
|
|
+ tnlcfg->saddr[0] = ntohl(fl6->saddr.s6_addr32[0]);
|
|
+ tnlcfg->saddr[1] = ntohl(fl6->saddr.s6_addr32[1]);
|
|
+ tnlcfg->saddr[2] = ntohl(fl6->saddr.s6_addr32[2]);
|
|
+ tnlcfg->saddr[3] = ntohl(fl6->saddr.s6_addr32[3]);
|
|
+ tnlcfg->daddr[0] = ntohl(fl6->daddr.s6_addr32[0]);
|
|
+ tnlcfg->daddr[1] = ntohl(fl6->daddr.s6_addr32[1]);
|
|
+ tnlcfg->daddr[2] = ntohl(fl6->daddr.s6_addr32[2]);
|
|
+ tnlcfg->daddr[3] = ntohl(fl6->daddr.s6_addr32[3]);
|
|
+ tnlcfg->hop_limit = tunnel->parms.hop_limit;
|
|
+ tnlcfg->flags = ntohl(tunnel->parms.flags);
|
|
+
|
|
+ /*
|
|
+ * Flow Label In kernel is stored in big endian format.
|
|
+ */
|
|
+ tnlcfg->flowlabel = fl6->flowlabel;
|
|
+ tnlcfg->draft03 = tunnel->parms.draft03;
|
|
+
|
|
+ /*
|
|
+ * Configure FMR table up to MAX_FMR_NUMBER, the rest will be forwarded to BR
|
|
+ */
|
|
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
|
|
+ for (fmr = tunnel->parms.fmrs; fmr && fmr_number < NSS_TUNIPIP6_MAX_FMR_NUMBER; fmr = fmr->next, fmr_number++) {
|
|
+ tnlcfg->fmr[fmr_number].ip6_prefix[0] = ntohl(fmr->ip6_prefix.s6_addr32[0]);
|
|
+ tnlcfg->fmr[fmr_number].ip6_prefix[1] = ntohl(fmr->ip6_prefix.s6_addr32[1]);
|
|
+ tnlcfg->fmr[fmr_number].ip6_prefix[2] = ntohl(fmr->ip6_prefix.s6_addr32[2]);
|
|
+ tnlcfg->fmr[fmr_number].ip6_prefix[3] = ntohl(fmr->ip6_prefix.s6_addr32[3]);
|
|
+ tnlcfg->fmr[fmr_number].ip4_prefix = ntohl(fmr->ip4_prefix.s_addr);
|
|
+ tnlcfg->fmr[fmr_number].ip6_prefix_len = fmr->ip6_prefix_len;
|
|
+ tnlcfg->fmr[fmr_number].ip4_prefix_len = fmr->ip4_prefix_len;
|
|
+ tnlcfg->fmr[fmr_number].ea_len = fmr->ea_len;
|
|
+ tnlcfg->fmr[fmr_number].offset = fmr->offset;
|
|
+ }
|
|
+#endif
|
|
+ tnlcfg->fmr_number = fmr_number;
|
|
+
|
|
+ /*
|
|
+ * Updating sibling_if_num for encap interface.
|
|
+ */
|
|
+ tnlcfg->sibling_if_num = outer_ifnum;
|
|
+
|
|
+ nss_tunipip6_trace("%p: Tunnel Param srcaddr %x:%x:%x:%x daddr %x:%x:%x:%x\n", netdev,
|
|
+ tnlcfg->saddr[0], tnlcfg->saddr[1],
|
|
+ tnlcfg->saddr[2], tnlcfg->saddr[3],
|
|
+ tnlcfg->daddr[0], tnlcfg->daddr[1],
|
|
+ tnlcfg->daddr[2], tnlcfg->daddr[3] );
|
|
+
|
|
+ /*
|
|
+ * Send configure message to encap interface.
|
|
+ */
|
|
+ nss_tunipip6_msg_init(&tnlmsg, inner_ifnum, NSS_TUNIPIP6_TX_ENCAP_IF_CREATE,
|
|
+ sizeof(struct nss_tunipip6_create_msg), NULL, NULL);
|
|
+
|
|
+ nss_tunipip6_trace("%p: Sending IPIP6 tunnel i/f up command to NSS %p\n", netdev, nss_ctx);
|
|
+ status = nss_tunipip6_tx(nss_ctx, &tnlmsg);
|
|
+ if (status != NSS_TX_SUCCESS) {
|
|
+ nss_tunipip6_warning("%p: Tunnel up command error %d\n", netdev, status);
|
|
+ goto config_fail;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Updating sibling_if_num for decap interface.
|
|
+ */
|
|
+ tnlcfg->sibling_if_num = inner_ifnum;
|
|
+
|
|
+ /*
|
|
+ * Send configure message to decap interface.
|
|
+ */
|
|
+ nss_tunipip6_msg_init(&tnlmsg, outer_ifnum, NSS_TUNIPIP6_TX_DECAP_IF_CREATE,
|
|
+ sizeof(struct nss_tunipip6_create_msg), NULL, NULL);
|
|
+
|
|
+ nss_tunipip6_trace("%p: Sending IPIP6 tunnel i/f up command to NSS %p\n", netdev, nss_ctx);
|
|
+ status = nss_tunipip6_tx(nss_ctx, &tnlmsg);
|
|
+ if (status != NSS_TX_SUCCESS) {
|
|
+ nss_tunipip6_warning("%p: Tunnel up command error %d\n", netdev, status);
|
|
+ goto config_fail;
|
|
+ }
|
|
+ return NOTIFY_DONE;
|
|
+
|
|
+config_fail:
|
|
+ nss_unregister_tunipip6_if(outer_ifnum);
|
|
+outer_reg_fail:
|
|
+ nss_unregister_tunipip6_if(inner_ifnum);
|
|
+inner_reg_fail:
|
|
+ status = nss_dynamic_interface_dealloc_node(outer_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_OUTER);
|
|
+ if (status != NSS_TX_SUCCESS) {
|
|
+ nss_tunipip6_warning("%p: Unable to dealloc the node[%d] in the NSS fw!\n", netdev, outer_ifnum);
|
|
+ }
|
|
+outer_alloc_fail:
|
|
+ status = nss_dynamic_interface_dealloc_node(inner_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_INNER);
|
|
+ if (status != NSS_TX_SUCCESS) {
|
|
+ nss_tunipip6_warning("%p: Unable to dealloc the node[%d] in the NSS fw!\n", netdev, inner_ifnum);
|
|
+ }
|
|
+inner_alloc_fail:
|
|
+ return NOTIFY_DONE;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * nss_tunipip6_dev_down()
|
|
+ * IPP6 Tunnel device i/f down handler
|
|
+ */
|
|
+int nss_tunipip6_dev_down(struct net_device *netdev)
|
|
+{
|
|
+ int inner_ifnum, outer_ifnum;
|
|
+ nss_tx_status_t status;
|
|
+
|
|
+ /*
|
|
+ * Validate netdev for ipv6-in-ipv4 Tunnel
|
|
+ */
|
|
+ if (netdev->type != ARPHRD_TUNNEL6) {
|
|
+ return NOTIFY_DONE;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Check if tunnel ipip6 is registered ?
|
|
+ */
|
|
+ inner_ifnum = nss_cmn_get_interface_number_by_dev_and_type(netdev, NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_INNER);
|
|
+ if (inner_ifnum < 0) {
|
|
+ nss_tunipip6_warning("%p: Net device is not registered with nss\n", netdev);
|
|
+ return NOTIFY_DONE;
|
|
+ }
|
|
+
|
|
+ outer_ifnum = nss_cmn_get_interface_number_by_dev_and_type(netdev, NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_OUTER);
|
|
+ if (outer_ifnum < 0) {
|
|
+ nss_tunipip6_warning("%p: Net device is not registered with nss\n", netdev);
|
|
+ return NOTIFY_DONE;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Un-Register IPIP6 tunnel with NSS
|
|
+ */
|
|
+ nss_unregister_tunipip6_if(inner_ifnum);
|
|
+ nss_unregister_tunipip6_if(outer_ifnum);
|
|
+
|
|
+ status = nss_dynamic_interface_dealloc_node(inner_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_INNER);
|
|
+ if (status != NSS_TX_SUCCESS) {
|
|
+ nss_tunipip6_warning("%p: Dealloc node failure\n", netdev);
|
|
+ return NOTIFY_DONE;
|
|
+ }
|
|
+
|
|
+ status = nss_dynamic_interface_dealloc_node(outer_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_OUTER);
|
|
+ if (status != NSS_TX_SUCCESS) {
|
|
+ nss_tunipip6_warning("%p: Dealloc node failure\n", netdev);
|
|
+ return NOTIFY_DONE;
|
|
+ }
|
|
+
|
|
+ return NOTIFY_DONE;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * nss_tunipip6_dev_event()
|
|
+ * Net device notifier for ipip6 module
|
|
+ */
|
|
+static int nss_tunipip6_dev_event(struct notifier_block *nb,
|
|
+ unsigned long event, void *dev)
|
|
+{
|
|
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 10, 0))
|
|
+ struct net_device *netdev = (struct net_device *)dev;
|
|
+#else
|
|
+ struct net_device *netdev = netdev_notifier_info_to_dev(dev);
|
|
+#endif
|
|
+
|
|
+ switch (event) {
|
|
+ case NETDEV_UP:
|
|
+ nss_tunipip6_trace("%p: NETDEV_UP :event %lu name %s\n", netdev, event, netdev->name);
|
|
+ return nss_tunipip6_dev_up(netdev);
|
|
+
|
|
+ case NETDEV_DOWN:
|
|
+ nss_tunipip6_trace("%p: NETDEV_DOWN :event %lu name %s\n", netdev, event, netdev->name);
|
|
+ return nss_tunipip6_dev_down(netdev);
|
|
+
|
|
+ default:
|
|
+ nss_tunipip6_trace("%p: Unhandled notifier dev %s event %x\n", netdev, netdev->name, (int)event);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return NOTIFY_DONE;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Linux Net device Notifier
|
|
+ */
|
|
+struct notifier_block nss_tunipip6_notifier = {
|
|
+ .notifier_call = nss_tunipip6_dev_event,
|
|
+};
|
|
+
|
|
+/*
|
|
+ * nss_tunipip6_init_module()
|
|
+ * Tunnel ipip6 module init function
|
|
+ */
|
|
+int __init nss_tunipip6_init_module(void)
|
|
+{
|
|
+#ifdef CONFIG_OF
|
|
+ /*
|
|
+ * If the node is not compatible, don't do anything.
|
|
+ */
|
|
+ if (!of_find_node_by_name(NULL, "nss-common")) {
|
|
+ return 0;
|
|
+ }
|
|
+#endif
|
|
+ nss_tunipip6_info("module (platform - IPQ806x , %s) loaded\n",
|
|
+ NSS_CLIENT_BUILD_ID);
|
|
+
|
|
+ register_netdevice_notifier(&nss_tunipip6_notifier);
|
|
+ nss_tunipip6_trace("Netdev Notifier registerd\n");
|
|
+
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * nss_tunipip6_exit_module()
|
|
+ * Tunnel ipip6 module exit function
|
|
+ */
|
|
+void __exit nss_tunipip6_exit_module(void)
|
|
+{
|
|
+#ifdef CONFIG_OF
|
|
+
|
|
+ /*
|
|
+ * If the node is not compatible, don't do anything.
|
|
+ */
|
|
+ if (!of_find_node_by_name(NULL, "nss-common")) {
|
|
+ return;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ unregister_netdevice_notifier(&nss_tunipip6_notifier);
|
|
+ nss_tunipip6_info("module unloaded\n");
|
|
+}
|
|
+
|
|
+module_init(nss_tunipip6_init_module);
|
|
+module_exit(nss_tunipip6_exit_module);
|
|
+
|
|
+MODULE_LICENSE("Dual BSD/GPL");
|
|
+MODULE_DESCRIPTION("NSS tunipip6 offload manager");
|
|
--- a/nss_qdisc/Makefile
|
|
+++ b/nss_qdisc/Makefile
|
|
@@ -9,18 +9,16 @@ endif
|
|
ccflags-y += -Wall -Werror
|
|
|
|
obj-m += qca-nss-qdisc.o
|
|
-qca-nss-qdisc-objs := nss_bf.o \
|
|
- nss_blackhole.o \
|
|
- nss_codel.o \
|
|
+qca-nss-qdisc-objs := nss_qdisc.o \
|
|
nss_fifo.o \
|
|
- nss_htb.o \
|
|
- nss_prio.o \
|
|
- nss_qdisc.o \
|
|
- nss_qdisc_htable.o \
|
|
- nss_qdisc_stats.o \
|
|
+ nss_codel.o \
|
|
nss_tbl.o \
|
|
- nss_wred.o \
|
|
- nss_wrr.o
|
|
+ nss_prio.o \
|
|
+ nss_bf.o \
|
|
+ nss_wrr.o \
|
|
+ nss_htb.o \
|
|
+ nss_blackhole.o \
|
|
+ nss_wred.o
|
|
|
|
ifeq ($(SoC),$(filter $(SoC),ipq807x ipq807x_64 ipq60xx ipq60xx_64))
|
|
qca-nss-qdisc-objs += nss_ppe.o \
|
|
--- a/nss_qdisc/igs/Makefile
|
|
+++ b/nss_qdisc/igs/Makefile
|
|
@@ -1,7 +1,6 @@
|
|
# Makefile for IGS (Ingress Shaping)
|
|
|
|
ccflags-y += $(NSS_CCFLAGS) -I$(obj)/../../exports
|
|
-ccflags-y += -DNSS_IGS_DEBUG_LEVEL=2
|
|
ccflags-y += -Wall -Werror
|
|
|
|
obj-m += act_nssmirred.o
|
|
--- a/nss_qdisc/igs/nss_mirred.c
|
|
+++ b/nss_qdisc/igs/nss_mirred.c
|
|
@@ -82,20 +82,24 @@ static const struct nla_policy nss_mirre
|
|
* nss_mirred_init()
|
|
* Initialize the nss mirred action.
|
|
*/
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
|
|
static int nss_mirred_init(struct net *net, struct nlattr *nla,
|
|
- struct nlattr *est, struct tc_action *tc_act, int ovr,
|
|
- int bind)
|
|
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
|
|
+ struct nlattr *est, struct tc_action *tc_act, int ovr,
|
|
+ int bind)
|
|
+{
|
|
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
|
|
+ struct nlattr *est, struct tc_action **tc_act, int ovr,
|
|
+ int bind, bool rtnl_held, struct tcf_proto *tp,
|
|
+ u32 flags, struct netlink_ext_ack *extack)
|
|
{
|
|
#else
|
|
-static int nss_mirred_init(struct net *net, struct nlattr *nla,
|
|
- struct nlattr *est, struct tc_action **tc_act, int ovr,
|
|
- int bind, bool rtnl_held, struct tcf_proto *tp,
|
|
- struct netlink_ext_ack *extack)
|
|
+ struct nlattr *est, struct tc_action **tc_act,
|
|
+ struct tcf_proto *tp, u32 flags, struct netlink_ext_ack *extack)
|
|
{
|
|
+ bool bind = flags & TCA_ACT_FLAGS_BIND;
|
|
+#endif
|
|
struct tc_action_net *tn = net_generic(net, nss_mirred_net_id);
|
|
u32 index;
|
|
-#endif
|
|
struct nlattr *arr[TC_NSS_MIRRED_MAX + 1];
|
|
struct tc_nss_mirred *parm;
|
|
struct nss_mirred_tcf *act;
|
|
@@ -239,8 +243,13 @@ static int nss_mirred_init(struct net *n
|
|
}
|
|
|
|
if (!ret) {
|
|
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0))
|
|
ret = tcf_idr_create(tn, index, est, tc_act, &nss_mirred_act_ops,
|
|
bind, true);
|
|
+#else
|
|
+ ret = tcf_idr_create(tn, index, est, tc_act, &nss_mirred_act_ops,
|
|
+ bind, true, 0);
|
|
+#endif
|
|
if (ret) {
|
|
tcf_idr_cleanup(tn, index);
|
|
return ret;
|
|
--- a/nss_qdisc/nss_bf.c
|
|
+++ b/nss_qdisc/nss_bf.c
|
|
@@ -1,13 +1,9 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2014-2017, 2019-2021, The Linux Foundation. All rights reserved.
|
|
- *
|
|
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
|
- *
|
|
+ * Copyright (c) 2014-2017, 2019-2020, 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.
|
|
- *
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
@@ -178,6 +174,11 @@ static int nss_bf_change_class(struct Qd
|
|
*/
|
|
qdisc_class_hash_grow(sch, &q->clhash);
|
|
|
|
+ /*
|
|
+ * Start the stats polling timer
|
|
+ */
|
|
+ nss_qdisc_start_basic_stats_polling(&cl->nq);
|
|
+
|
|
nss_qdisc_info("Class %u successfully allocated\n", classid);
|
|
}
|
|
|
|
@@ -276,6 +277,11 @@ static void nss_bf_destroy_class(struct
|
|
nss_qdisc_put(cl->qdisc);
|
|
|
|
/*
|
|
+ * Stop the stats polling timer and free class
|
|
+ */
|
|
+ nss_qdisc_stop_basic_stats_polling(&cl->nq);
|
|
+
|
|
+ /*
|
|
* Destroy the shaper in NSS
|
|
*/
|
|
nss_qdisc_destroy(&cl->nq);
|
|
@@ -290,7 +296,11 @@ static void nss_bf_destroy_class(struct
|
|
* nss_bf_delete_class()
|
|
* Detaches a class from operation, but does not destroy it.
|
|
*/
|
|
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0))
|
|
+static int nss_bf_delete_class(struct Qdisc *sch, unsigned long arg, struct netlink_ext_ack *extack)
|
|
+#else
|
|
static int nss_bf_delete_class(struct Qdisc *sch, unsigned long arg)
|
|
+#endif
|
|
{
|
|
struct nss_bf_sched_data *q = qdisc_priv(sch);
|
|
struct nss_bf_class_data *cl = (struct nss_bf_class_data *)arg;
|
|
@@ -299,14 +309,11 @@ static int nss_bf_delete_class(struct Qd
|
|
struct nss_qdisc *nq_child = (struct nss_qdisc *)qdisc_priv(cl->qdisc);
|
|
|
|
/*
|
|
- * If the class is the root class or has qdiscs attached, we do not
|
|
- * support deleting it.
|
|
+ * Since all classes are leaf nodes in our case, we dont have to make
|
|
+ * that check.
|
|
*/
|
|
- if ((cl == &q->root) || (cl->qdisc != &noop_qdisc)) {
|
|
- nss_qdisc_warning("Cannot delete bf class %x as it is the root "
|
|
- "class or has child qdisc attached\n", cl->nq.qos_tag);
|
|
+ if (cl == &q->root)
|
|
return -EBUSY;
|
|
- }
|
|
|
|
/*
|
|
* The message to NSS should be sent to the parent of this class
|
|
@@ -320,22 +327,14 @@ static int nss_bf_delete_class(struct Qd
|
|
}
|
|
|
|
sch_tree_lock(sch);
|
|
+ qdisc_reset(cl->qdisc);
|
|
qdisc_class_hash_remove(&q->clhash, &cl->cl_common);
|
|
refcnt = nss_qdisc_atomic_sub_return(&cl->nq);
|
|
sch_tree_unlock(sch);
|
|
-
|
|
- /*
|
|
- * For 5.4 and above kernels, calling nss_htb_destroy_class
|
|
- * explicitly as there is no put_class which would have called
|
|
- * nss_bf_destroy_class when refcnt becomes zero.
|
|
- */
|
|
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
|
|
- nss_bf_destroy_class(sch, cl);
|
|
-#else
|
|
if (!refcnt) {
|
|
nss_qdisc_error("Reference count should not be zero for class %px\n", cl);
|
|
}
|
|
-#endif
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -635,11 +634,6 @@ static int nss_bf_change_qdisc(struct Qd
|
|
*/
|
|
static void nss_bf_reset_class(struct nss_bf_class_data *cl)
|
|
{
|
|
- if (cl->qdisc == &noop_qdisc) {
|
|
- nss_qdisc_trace("Class %x has no child qdisc to reset\n", cl->nq.qos_tag);
|
|
- return;
|
|
- }
|
|
-
|
|
nss_qdisc_reset(cl->qdisc);
|
|
nss_qdisc_info("Nssbf class resetted %px\n", cl->qdisc);
|
|
}
|
|
@@ -721,6 +715,11 @@ static void nss_bf_destroy_qdisc(struct
|
|
qdisc_class_hash_destroy(&q->clhash);
|
|
|
|
/*
|
|
+ * Stop the polling of basic stats
|
|
+ */
|
|
+ nss_qdisc_stop_basic_stats_polling(&q->nq);
|
|
+
|
|
+ /*
|
|
* Now we can go ahead and destroy the qdisc.
|
|
* Note: We dont have to detach ourself from our parent because this
|
|
* will be taken care of by the graft call.
|
|
@@ -799,6 +798,11 @@ static int nss_bf_init_qdisc(struct Qdis
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ /*
|
|
+ * Start the stats polling timer
|
|
+ */
|
|
+ nss_qdisc_start_basic_stats_polling(&q->nq);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
--- a/nss_qdisc/nss_blackhole.c
|
|
+++ b/nss_qdisc/nss_blackhole.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2014, 2016-2017, 2020-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2014, 2016-2017, 2020, 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.
|
|
@@ -90,6 +90,11 @@ static void nss_blackhole_destroy(struct
|
|
{
|
|
struct nss_qdisc *nq = (struct nss_qdisc *)qdisc_priv(sch);
|
|
|
|
+ /*
|
|
+ * Stop the polling of basic stats
|
|
+ */
|
|
+ nss_qdisc_stop_basic_stats_polling(nq);
|
|
+
|
|
nss_qdisc_info("destroying qdisc %x\n", sch->handle);
|
|
nss_qdisc_destroy(nq);
|
|
}
|
|
@@ -219,6 +224,11 @@ static int nss_blackhole_init(struct Qdi
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ /*
|
|
+ * Start the stats polling timer
|
|
+ */
|
|
+ nss_qdisc_start_basic_stats_polling(nq);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
--- a/nss_qdisc/nss_codel.c
|
|
+++ b/nss_qdisc/nss_codel.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2014, 2016-2018, 2020-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2014, 2016-2018, 2020, 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.
|
|
@@ -155,6 +155,10 @@ static void nss_codel_destroy(struct Qdi
|
|
{
|
|
struct nss_codel_sched_data *q = qdisc_priv(sch);
|
|
|
|
+ /*
|
|
+ * Stop the polling of basic stats
|
|
+ */
|
|
+ nss_qdisc_stop_basic_stats_polling(&q->nq);
|
|
nss_qdisc_destroy(&q->nq);
|
|
nss_codel_flow_queues_free(q);
|
|
nss_qdisc_info("nss_codel destroyed");
|
|
@@ -451,6 +455,11 @@ static int nss_codel_init(struct Qdisc *
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ /*
|
|
+ * Start the stats polling timer
|
|
+ */
|
|
+ nss_qdisc_start_basic_stats_polling(nq);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
--- a/nss_qdisc/nss_fifo.c
|
|
+++ b/nss_qdisc/nss_fifo.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2014, 2016-2017, 2020-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2014, 2016-2017, 2020, 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.
|
|
@@ -66,6 +66,11 @@ static void nss_fifo_destroy(struct Qdis
|
|
{
|
|
struct nss_qdisc *nq = (struct nss_qdisc *)qdisc_priv(sch);
|
|
|
|
+ /*
|
|
+ * Stop the polling of basic stats
|
|
+ */
|
|
+ nss_qdisc_stop_basic_stats_polling(nq);
|
|
+
|
|
nss_qdisc_destroy(nq);
|
|
nss_qdisc_info("nss_fifo destroyed");
|
|
}
|
|
@@ -291,6 +296,11 @@ static int nss_fifo_init(struct Qdisc *s
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ /*
|
|
+ * Start the stats polling timer
|
|
+ */
|
|
+ nss_qdisc_start_basic_stats_polling(nq);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
--- a/nss_qdisc/nss_htb.c
|
|
+++ b/nss_qdisc/nss_htb.c
|
|
@@ -1,13 +1,9 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2014-2017, 2019-2021, The Linux Foundation. All rights reserved.
|
|
- *
|
|
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
|
- *
|
|
+ * Copyright (c) 2014-2017, 2019-2020, 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.
|
|
- *
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
@@ -413,6 +409,11 @@ static int nss_htb_change_class(struct Q
|
|
*/
|
|
qdisc_class_hash_grow(sch, &q->clhash);
|
|
|
|
+ /*
|
|
+ * Start the stats polling timer
|
|
+ */
|
|
+ nss_qdisc_start_basic_stats_polling(&cl->nq);
|
|
+
|
|
nss_qdisc_trace("class %x successfully allocated and initialized\n", classid);
|
|
}
|
|
|
|
@@ -502,6 +503,11 @@ static void nss_htb_destroy_class(struct
|
|
nss_qdisc_put(cl->qdisc);
|
|
|
|
/*
|
|
+ * Stop the stats polling timer and free class
|
|
+ */
|
|
+ nss_qdisc_stop_basic_stats_polling(&cl->nq);
|
|
+
|
|
+ /*
|
|
* Destroy the shaper in NSS
|
|
*/
|
|
nss_qdisc_destroy(&cl->nq);
|
|
@@ -516,7 +522,11 @@ static void nss_htb_destroy_class(struct
|
|
* nss_htb_delete_class()
|
|
* Detaches a class from operation, but does not destroy it.
|
|
*/
|
|
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0))
|
|
+static int nss_htb_delete_class(struct Qdisc *sch, unsigned long arg, struct netlink_ext_ack *extack)
|
|
+#else
|
|
static int nss_htb_delete_class(struct Qdisc *sch, unsigned long arg)
|
|
+#endif
|
|
{
|
|
struct nss_htb_sched_data *q = qdisc_priv(sch);
|
|
struct nss_htb_class_data *cl = (struct nss_htb_class_data *)arg;
|
|
@@ -524,12 +534,10 @@ static int nss_htb_delete_class(struct Q
|
|
int refcnt;
|
|
|
|
/*
|
|
- * If the class still has child nodes or qdiscs, then we do not
|
|
+ * If the class still has child nodes, then we do not
|
|
* support deleting it.
|
|
*/
|
|
- if ((cl->children) || (cl->qdisc != &noop_qdisc)) {
|
|
- nss_qdisc_warning("Cannot delete htb class %x with child nodes "
|
|
- "or qdisc attached\n", cl->nq.qos_tag);
|
|
+ if (cl->children) {
|
|
return -EBUSY;
|
|
}
|
|
|
|
@@ -560,21 +568,16 @@ static int nss_htb_delete_class(struct Q
|
|
}
|
|
|
|
sch_tree_lock(sch);
|
|
+ qdisc_reset(cl->qdisc);
|
|
qdisc_class_hash_remove(&q->clhash, &cl->sch_common);
|
|
|
|
/*
|
|
* If we are root class, we dont have to update our parent.
|
|
* We simply deduct refcnt and return.
|
|
- * For 5.4 and above kernels, calling nss_htb_destroy_class
|
|
- * explicitly as there is no put_class which would have called
|
|
- * nss_htb_destroy_class when refcnt becomes zero.
|
|
*/
|
|
if (!cl->parent) {
|
|
refcnt = nss_qdisc_atomic_sub_return(&cl->nq);
|
|
sch_tree_unlock(sch);
|
|
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
|
|
- nss_htb_destroy_class(sch, cl);
|
|
-#endif
|
|
return 0;
|
|
}
|
|
|
|
@@ -593,14 +596,6 @@ static int nss_htb_delete_class(struct Q
|
|
refcnt = nss_qdisc_atomic_sub_return(&cl->nq);
|
|
sch_tree_unlock(sch);
|
|
|
|
- /*
|
|
- * For 5.4 and above kernels, calling nss_htb_destroy_class
|
|
- * explicitly as there is no put_class which would have called
|
|
- * nss_htb_destroy_class when refcnt becomes zero.
|
|
- */
|
|
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
|
|
- nss_htb_destroy_class(sch, cl);
|
|
-#endif
|
|
return 0;
|
|
}
|
|
|
|
@@ -903,11 +898,6 @@ static int nss_htb_change_qdisc(struct Q
|
|
*/
|
|
static void nss_htb_reset_class(struct nss_htb_class_data *cl)
|
|
{
|
|
- if (cl->qdisc == &noop_qdisc) {
|
|
- nss_qdisc_trace("Class %x has no child qdisc to reset\n", cl->nq.qos_tag);
|
|
- return;
|
|
- }
|
|
-
|
|
nss_qdisc_reset(cl->qdisc);
|
|
nss_qdisc_trace("htb class %x reset\n", cl->nq.qos_tag);
|
|
}
|
|
@@ -991,6 +981,11 @@ static void nss_htb_destroy_qdisc(struct
|
|
qdisc_class_hash_destroy(&q->clhash);
|
|
|
|
/*
|
|
+ * Stop the polling of basic stats
|
|
+ */
|
|
+ nss_qdisc_stop_basic_stats_polling(&q->nq);
|
|
+
|
|
+ /*
|
|
* Now we can go ahead and destroy the qdisc.
|
|
* Note: We dont have to detach ourself from our parent because this
|
|
* will be taken care of by the graft call.
|
|
@@ -1066,6 +1061,11 @@ static int nss_htb_init_qdisc(struct Qdi
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ /*
|
|
+ * Start the stats polling timer
|
|
+ */
|
|
+ nss_qdisc_start_basic_stats_polling(&q->nq);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
--- a/nss_qdisc/nss_ppe.c
|
|
+++ b/nss_qdisc/nss_ppe.c
|
|
@@ -1,8 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
|
- *
|
|
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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.
|
|
@@ -128,7 +126,7 @@ static struct nss_ppe_res *nss_ppe_res_e
|
|
|
|
spin_lock_bh(&ppe_port->lock);
|
|
for (i = max; i > 0; i--) {
|
|
- res = kzalloc(sizeof(struct nss_ppe_res), GFP_ATOMIC);
|
|
+ res = kzalloc(sizeof(struct nss_ppe_res), GFP_KERNEL);
|
|
if (!res) {
|
|
nss_qdisc_error("Free queue list allocation failed for port %u\n", port);
|
|
goto fail;
|
|
--- a/nss_qdisc/nss_prio.c
|
|
+++ b/nss_qdisc/nss_prio.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2014-2017, 2019-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2014-2017, 2019-2020, 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.
|
|
@@ -136,6 +136,11 @@ static void nss_prio_destroy(struct Qdis
|
|
}
|
|
|
|
/*
|
|
+ * Stop the polling of basic stats
|
|
+ */
|
|
+ nss_qdisc_stop_basic_stats_polling(&q->nq);
|
|
+
|
|
+ /*
|
|
* Destroy the qdisc in NSS
|
|
*/
|
|
nss_qdisc_destroy(&q->nq);
|
|
@@ -279,6 +284,10 @@ static int nss_prio_init(struct Qdisc *s
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ /*
|
|
+ * Start the stats polling timer
|
|
+ */
|
|
+ nss_qdisc_start_basic_stats_polling(&q->nq);
|
|
return 0;
|
|
}
|
|
|
|
--- a/nss_qdisc/nss_qdisc.c
|
|
+++ b/nss_qdisc/nss_qdisc.c
|
|
@@ -29,6 +29,9 @@
|
|
|
|
void *nss_qdisc_ctx; /* Shaping context for nss_qdisc */
|
|
|
|
+#define NSS_QDISC_COMMAND_TIMEOUT (10*HZ) /* We set 10sec to be the command */
|
|
+ /* timeout value for messages */
|
|
+
|
|
/*
|
|
* Defines related to root hash maintenance
|
|
*/
|
|
@@ -36,53 +39,6 @@ void *nss_qdisc_ctx; /* Shaping contex
|
|
#define NSS_QDISC_ROOT_HASH_MASK (NSS_QDISC_ROOT_HASH_SIZE - 1)
|
|
|
|
/*
|
|
- * nss_qdisc_get_interface_msg()
|
|
- * Returns the correct message that needs to be sent down to the NSS interface.
|
|
- */
|
|
-int nss_qdisc_get_interface_msg(bool is_bridge, uint32_t msg_type)
|
|
-{
|
|
- /*
|
|
- * We re-assign the message based on whether this is for the I shaper
|
|
- * or the B shaper. The is_bridge flag tells if we are on a bridge interface.
|
|
- */
|
|
- if (is_bridge) {
|
|
- switch (msg_type) {
|
|
- case NSS_QDISC_IF_SHAPER_ASSIGN:
|
|
- return NSS_IF_BSHAPER_ASSIGN;
|
|
- case NSS_QDISC_IF_SHAPER_UNASSIGN:
|
|
- return NSS_IF_BSHAPER_UNASSIGN;
|
|
- case NSS_QDISC_IF_SHAPER_CONFIG:
|
|
- return NSS_IF_BSHAPER_CONFIG;
|
|
- default:
|
|
- nss_qdisc_info("Unknown message type for a bridge - type %d", msg_type);
|
|
- return -1;
|
|
- }
|
|
- } else {
|
|
- switch (msg_type) {
|
|
- case NSS_QDISC_IF_SHAPER_ASSIGN:
|
|
- return NSS_IF_ISHAPER_ASSIGN;
|
|
- case NSS_QDISC_IF_SHAPER_UNASSIGN:
|
|
- return NSS_IF_ISHAPER_UNASSIGN;
|
|
- case NSS_QDISC_IF_SHAPER_CONFIG:
|
|
- return NSS_IF_ISHAPER_CONFIG;
|
|
- default:
|
|
- nss_qdisc_info("Unknown message type for an interface - type %d", msg_type);
|
|
- return -1;
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_qdisc_msg_init()
|
|
- * Initialize the qdisc specific message
|
|
- */
|
|
-void nss_qdisc_msg_init(struct nss_if_msg *nim, uint16_t if_num, uint32_t msg_type, uint32_t len,
|
|
- nss_if_msg_callback_t cb, void *app_data)
|
|
-{
|
|
- nss_cmn_msg_init(&nim->cm, if_num, msg_type, len, (void *)cb, app_data);
|
|
-}
|
|
-
|
|
-/*
|
|
* nss_qdisc_interface_is_virtual()
|
|
* Return true if it is redirect or bridge interface.
|
|
*/
|
|
@@ -165,6 +121,53 @@ static int nss_qdisc_ppe_init(struct Qdi
|
|
#endif
|
|
|
|
/*
|
|
+ * nss_qdisc_msg_init()
|
|
+ * Initialize the qdisc specific message
|
|
+ */
|
|
+static void nss_qdisc_msg_init(struct nss_if_msg *nim, uint16_t if_num, uint32_t msg_type, uint32_t len,
|
|
+ nss_if_msg_callback_t cb, void *app_data)
|
|
+{
|
|
+ nss_cmn_msg_init(&nim->cm, if_num, msg_type, len, (void*)cb, app_data);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * nss_qdisc_get_interface_msg()
|
|
+ * Returns the correct message that needs to be sent down to the NSS interface.
|
|
+ */
|
|
+static inline int nss_qdisc_get_interface_msg(bool is_bridge, uint32_t msg_type)
|
|
+{
|
|
+ /*
|
|
+ * We re-assign the message based on whether this is for the I shaper
|
|
+ * or the B shaper. The is_bridge flag tells if we are on a bridge interface.
|
|
+ */
|
|
+ if (is_bridge) {
|
|
+ switch(msg_type) {
|
|
+ case NSS_QDISC_IF_SHAPER_ASSIGN:
|
|
+ return NSS_IF_BSHAPER_ASSIGN;
|
|
+ case NSS_QDISC_IF_SHAPER_UNASSIGN:
|
|
+ return NSS_IF_BSHAPER_UNASSIGN;
|
|
+ case NSS_QDISC_IF_SHAPER_CONFIG:
|
|
+ return NSS_IF_BSHAPER_CONFIG;
|
|
+ default:
|
|
+ nss_qdisc_info("Unknown message type for a bridge - type %d", msg_type);
|
|
+ return -1;
|
|
+ }
|
|
+ } else {
|
|
+ switch(msg_type) {
|
|
+ case NSS_QDISC_IF_SHAPER_ASSIGN:
|
|
+ return NSS_IF_ISHAPER_ASSIGN;
|
|
+ case NSS_QDISC_IF_SHAPER_UNASSIGN:
|
|
+ return NSS_IF_ISHAPER_UNASSIGN;
|
|
+ case NSS_QDISC_IF_SHAPER_CONFIG:
|
|
+ return NSS_IF_ISHAPER_CONFIG;
|
|
+ default:
|
|
+ nss_qdisc_info("Unknown message type for an interface - type %d", msg_type);
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
* nss_qdisc_attach_bshaper_callback()
|
|
* Call back funtion for bridge shaper attach to an interface.
|
|
*/
|
|
@@ -609,6 +612,7 @@ static void nss_qdisc_root_cleanup_free_
|
|
nss_qdisc_info("Root qdisc %px (type %d) free SUCCESS - response "
|
|
"type: %d\n", nq->qdisc, nq->type,
|
|
nim->msg.shaper_configure.config.response_type);
|
|
+
|
|
nss_qdisc_root_cleanup_shaper_unassign(nq);
|
|
}
|
|
|
|
@@ -1162,15 +1166,8 @@ unsigned int nss_qdisc_drop(struct Qdisc
|
|
*/
|
|
void nss_qdisc_reset(struct Qdisc *sch)
|
|
{
|
|
- struct nss_qdisc *nq;
|
|
-
|
|
- if(!(sch->flags & TCQ_F_NSS)) {
|
|
- qdisc_reset_queue(sch);
|
|
- nss_qdisc_info("Qdisc %px resetting non NSS qdisc\n", sch);
|
|
- return;
|
|
- }
|
|
+ struct nss_qdisc *nq = qdisc_priv(sch);
|
|
|
|
- nq = qdisc_priv(sch);
|
|
nss_qdisc_info("Qdisc %px (type %d) resetting\n",
|
|
sch, nq->type);
|
|
|
|
@@ -1209,10 +1206,10 @@ static bool nss_qdisc_iterate_fl(struct
|
|
return 0;
|
|
}
|
|
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
|
|
- status = tc_classify(skb, tcf, &res, false);
|
|
-#else
|
|
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
|
|
status = tcf_classify(skb, tcf, &res, false);
|
|
+#else
|
|
+ status = tcf_classify(skb, NULL, tcf, &res, false);
|
|
#endif
|
|
if ((status == TC_ACT_STOLEN) || (status == TC_ACT_QUEUED)) {
|
|
return 1;
|
|
@@ -1892,7 +1889,6 @@ int nss_qdisc_configure(struct nss_qdisc
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
/*
|
|
* nss_qdisc_register_configure_callback()
|
|
* Register shaper configure callback, which gets invoked on receiving a response.
|
|
@@ -1949,11 +1945,6 @@ void nss_qdisc_destroy(struct nss_qdisc
|
|
}
|
|
|
|
/*
|
|
- * Delete node from stats list
|
|
- */
|
|
- nss_qdisc_stats_qdisc_detach(nq);
|
|
-
|
|
- /*
|
|
* How we begin to tidy up depends on whether we are root or child
|
|
*/
|
|
nq->pending_final_state = NSS_QDISC_STATE_IDLE;
|
|
@@ -1972,11 +1963,6 @@ void nss_qdisc_destroy(struct nss_qdisc
|
|
}
|
|
|
|
/*
|
|
- * Stop stats polling
|
|
- */
|
|
- nss_qdisc_stats_stop_polling(nq);
|
|
-
|
|
- /*
|
|
* Begin by freeing the root shaper node
|
|
*/
|
|
nss_qdisc_root_cleanup_free_node(nq);
|
|
@@ -2129,8 +2115,6 @@ int __nss_qdisc_init(struct Qdisc *sch,
|
|
*/
|
|
if ((sch->parent == TC_H_ROOT) && (!nq->is_class)) {
|
|
nss_qdisc_info("Qdisc %px (type %d) is root\n", nq->qdisc, nq->type);
|
|
- nss_qdisc_info("Qdisc %px dev-name %s qdisc_dev(sch)->qdisc %px, qdisc_dev(sch)->qdisc->handle %x\n", qdisc_dev(sch), qdisc_dev(sch)->name, qdisc_dev(sch)->qdisc, qdisc_dev(sch)->qdisc->handle);
|
|
- nss_qdisc_info("Qdisc %px (sch %px) is root, sch->handle %x\n", nq->qdisc, sch, sch->handle);
|
|
nq->is_root = true;
|
|
root = sch;
|
|
} else {
|
|
@@ -2188,6 +2172,8 @@ int __nss_qdisc_init(struct Qdisc *sch,
|
|
* This is to prevent mixing NSS and PPE qdisc with linux qdisc.
|
|
*/
|
|
if ((parent != TC_H_ROOT) && (root->ops->owner != THIS_MODULE)) {
|
|
+ nss_qdisc_warning("parent (%d) and TC_H_ROOT (%d))", parent, TC_H_ROOT);
|
|
+ nss_qdisc_warning("root->ops->owner (%px) and THIS_MODULE (%px))", root->ops->owner , THIS_MODULE);
|
|
nss_qdisc_warning("NSS qdisc %px (type %d) used along with non-nss qdiscs,"
|
|
" or the interface is currently down", nq->qdisc, nq->type);
|
|
}
|
|
@@ -2288,11 +2274,6 @@ int __nss_qdisc_init(struct Qdisc *sch,
|
|
* If state is positive, return success
|
|
*/
|
|
if (state > 0) {
|
|
-
|
|
- /*
|
|
- * Qdisc successfully initialized, add it to stats list if its not a class
|
|
- */
|
|
- nss_qdisc_stats_qdisc_attach(nq);
|
|
return 0;
|
|
}
|
|
|
|
@@ -2460,15 +2441,6 @@ int __nss_qdisc_init(struct Qdisc *sch,
|
|
goto init_fail;
|
|
}
|
|
#endif
|
|
- /*
|
|
- * Initialize the stats management only for root node
|
|
- */
|
|
- if (!nss_qdisc_stats_sync_many_init(nq)) {
|
|
- nss_qdisc_error("Qdisc %px (type %d) stats sync init failed", nq->qdisc, nq->type);
|
|
- nss_shaper_unregister_shaping(nq->nss_shaping_ctx);
|
|
- atomic_set(&nq->state, NSS_QDISC_STATE_INIT_FAILED);
|
|
- goto init_fail;
|
|
- }
|
|
|
|
/*
|
|
* Create and send the shaper assign message to the NSS interface
|
|
@@ -2498,7 +2470,7 @@ int __nss_qdisc_init(struct Qdisc *sch,
|
|
if (igs_put) {
|
|
nss_igs_module_put();
|
|
}
|
|
- nss_qdisc_error("init for qdisc %x timedout!\n", nq->qos_tag);
|
|
+ nss_qdisc_error("init for qdisc %x timedout!\n", nq->qos_tag);
|
|
return -1;
|
|
}
|
|
|
|
@@ -2509,16 +2481,6 @@ int __nss_qdisc_init(struct Qdisc *sch,
|
|
if (state > 0) {
|
|
|
|
/*
|
|
- * Qdisc successfully initialized add it to stats list if its not a class
|
|
- */
|
|
- nss_qdisc_stats_qdisc_attach(nq);
|
|
-
|
|
- /*
|
|
- * Root node is successfully configured, start stats polling
|
|
- */
|
|
- nss_qdisc_stats_start_polling(nq);
|
|
-
|
|
- /*
|
|
* Return if this is not a root qdisc on a bridge interface.
|
|
*/
|
|
if (!nq->is_root || !nq->is_bridge) {
|
|
@@ -2559,14 +2521,6 @@ init_fail:
|
|
}
|
|
#endif
|
|
|
|
-
|
|
- /*
|
|
- * Clean up stats sync objects if initialized.
|
|
- */
|
|
- if (nq->stats_wq) {
|
|
- nss_qdisc_stats_sync_many_exit(nq);
|
|
- }
|
|
-
|
|
/*
|
|
* Destroy any virtual interfaces created by us before returning a failure.
|
|
*/
|
|
@@ -2601,6 +2555,210 @@ int nss_qdisc_init(struct Qdisc *sch, st
|
|
}
|
|
|
|
/*
|
|
+ * nss_qdisc_basic_stats_callback()
|
|
+ * Invoked after getting basic stats
|
|
+ */
|
|
+static void nss_qdisc_basic_stats_callback(void *app_data,
|
|
+ struct nss_if_msg *nim)
|
|
+{
|
|
+ struct nss_qdisc *nq = (struct nss_qdisc *)app_data;
|
|
+ struct Qdisc *qdisc = nq->qdisc;
|
|
+ struct gnet_stats_basic_packed *bstats;
|
|
+ struct gnet_stats_queue *qstats;
|
|
+ struct nss_shaper_node_stats_response *response;
|
|
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0))
|
|
+ atomic_t *refcnt;
|
|
+#else
|
|
+ refcount_t *refcnt;
|
|
+#endif
|
|
+
|
|
+ if (nim->cm.response != NSS_CMN_RESPONSE_ACK) {
|
|
+ nss_qdisc_warning("Qdisc %px (type %d): Receive stats FAILED - "
|
|
+ "response: type: %d\n", qdisc, nq->type,
|
|
+ nim->msg.shaper_configure.config.response_type);
|
|
+ atomic_sub(1, &nq->pending_stat_requests);
|
|
+ wake_up(&nq->wait_queue);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ response = &nim->msg.shaper_configure.config.msg.shaper_node_stats_get.response;
|
|
+
|
|
+ /*
|
|
+ * Get the right stats pointers based on whether it is a class
|
|
+ * or a qdisc.
|
|
+ */
|
|
+ if (nq->is_class) {
|
|
+ bstats = &nq->bstats;
|
|
+ qstats = &nq->qstats;
|
|
+ refcnt = &nq->refcnt;
|
|
+ } else {
|
|
+ bstats = &qdisc->bstats;
|
|
+ qstats = &qdisc->qstats;
|
|
+ refcnt = &qdisc->refcnt;
|
|
+ qdisc->q.qlen = response->sn_stats.qlen_packets;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Update qdisc->bstats
|
|
+ */
|
|
+ spin_lock_bh(&nq->lock);
|
|
+ bstats->bytes += (__u64)response->sn_stats.delta.dequeued_bytes;
|
|
+ bstats->packets += response->sn_stats.delta.dequeued_packets;
|
|
+
|
|
+ /*
|
|
+ * Update qdisc->qstats
|
|
+ */
|
|
+ qstats->backlog = response->sn_stats.qlen_bytes;
|
|
+
|
|
+ qstats->drops += (response->sn_stats.delta.enqueued_packets_dropped +
|
|
+ response->sn_stats.delta.dequeued_packets_dropped);
|
|
+
|
|
+ /*
|
|
+ * Update qdisc->qstats
|
|
+ */
|
|
+ qstats->qlen = response->sn_stats.qlen_packets;
|
|
+ qstats->requeues = 0;
|
|
+ qstats->overlimits += response->sn_stats.delta.queue_overrun;
|
|
+ spin_unlock_bh(&nq->lock);
|
|
+
|
|
+ /*
|
|
+ * Shapers that maintain additional unique statistics will process them
|
|
+ * via a registered callback. So invoke if its been registered.
|
|
+ */
|
|
+ if (nq->stats_cb) {
|
|
+ nq->stats_cb(nq, response);
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * All access to nq fields below do not need lock protection. They
|
|
+ * do not get manipulated on different thread contexts.
|
|
+ */
|
|
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0))
|
|
+ if (atomic_read(refcnt) == 0) {
|
|
+#else
|
|
+ if (refcount_read(refcnt) == 0) {
|
|
+#endif
|
|
+ atomic_sub(1, &nq->pending_stat_requests);
|
|
+ wake_up(&nq->wait_queue);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Requests for stats again, after 1 sec.
|
|
+ */
|
|
+ nq->stats_get_timer.expires += HZ;
|
|
+ if (nq->stats_get_timer.expires <= jiffies) {
|
|
+ nss_qdisc_info("losing time %lu, jiffies = %lu\n",
|
|
+ nq->stats_get_timer.expires, jiffies);
|
|
+ nq->stats_get_timer.expires = jiffies + HZ;
|
|
+ }
|
|
+ add_timer(&nq->stats_get_timer);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * nss_qdisc_get_stats_timer_callback()
|
|
+ * Invoked periodically to get updated stats
|
|
+ */
|
|
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
|
|
+static void nss_qdisc_get_stats_timer_callback(unsigned long int data)
|
|
+#else
|
|
+static void nss_qdisc_get_stats_timer_callback(struct timer_list *tm)
|
|
+#endif
|
|
+{
|
|
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
|
|
+ struct nss_qdisc *nq = (struct nss_qdisc *)data;
|
|
+#else
|
|
+ struct nss_qdisc *nq = from_timer(nq, tm, stats_get_timer);
|
|
+#endif
|
|
+
|
|
+ nss_tx_status_t rc;
|
|
+ struct nss_if_msg nim;
|
|
+ int msg_type;
|
|
+
|
|
+ /*
|
|
+ * Create and send the shaper configure message to the NSS interface
|
|
+ */
|
|
+ msg_type = nss_qdisc_get_interface_msg(nq->is_bridge, NSS_QDISC_IF_SHAPER_CONFIG);
|
|
+ nss_qdisc_msg_init(&nim, nq->nss_interface_number, msg_type, sizeof(struct nss_if_shaper_configure),
|
|
+ nss_qdisc_basic_stats_callback,
|
|
+ nq);
|
|
+ nim.msg.shaper_configure.config.request_type = NSS_SHAPER_CONFIG_TYPE_SHAPER_NODE_BASIC_STATS_GET;
|
|
+ nim.msg.shaper_configure.config.msg.shaper_node_stats_get.qos_tag = nq->qos_tag;
|
|
+ rc = nss_if_tx_msg(nq->nss_shaping_ctx, &nim);
|
|
+
|
|
+ /*
|
|
+ * Check if we failed to send the stats request to NSS.
|
|
+ */
|
|
+ if (rc != NSS_TX_SUCCESS) {
|
|
+ nss_qdisc_info("%px: stats fetch request dropped, causing "
|
|
+ "delay in stats fetch\n", nq->qdisc);
|
|
+
|
|
+ /*
|
|
+ * Schedule the timer once again for re-trying. Since this is a
|
|
+ * re-try we schedule it 100ms from now, instead of a whole second.
|
|
+ */
|
|
+ nq->stats_get_timer.expires = jiffies + HZ/10;
|
|
+ add_timer(&nq->stats_get_timer);
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ * nss_qdisc_start_basic_stats_polling()
|
|
+ * Call to initiate the stats polling timer
|
|
+ */
|
|
+void nss_qdisc_start_basic_stats_polling(struct nss_qdisc *nq)
|
|
+{
|
|
+ /*
|
|
+ * In case the stats polling timer is already
|
|
+ * initiated, return. This can happen only when
|
|
+ * there is a fallback from PPE to NSS qdisc.
|
|
+ */
|
|
+ if (atomic_read(&nq->pending_stat_requests)) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
|
|
+ init_timer(&nq->stats_get_timer);
|
|
+ nq->stats_get_timer.function = nss_qdisc_get_stats_timer_callback;
|
|
+ nq->stats_get_timer.data = (unsigned long)nq;
|
|
+#else
|
|
+ timer_setup(&nq->stats_get_timer, nss_qdisc_get_stats_timer_callback, 0);
|
|
+#endif
|
|
+
|
|
+ nq->stats_get_timer.expires = jiffies + HZ;
|
|
+ atomic_set(&nq->pending_stat_requests, 1);
|
|
+ add_timer(&nq->stats_get_timer);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * nss_qdisc_stop_basic_stats_polling()
|
|
+ * Call to stop polling of basic stats
|
|
+ */
|
|
+void nss_qdisc_stop_basic_stats_polling(struct nss_qdisc *nq)
|
|
+{
|
|
+ /*
|
|
+ * If the timer was active, then delete timer and return.
|
|
+ */
|
|
+ if (del_timer(&nq->stats_get_timer) > 0) {
|
|
+ /*
|
|
+ * The timer was still active (counting down) when it was deleted.
|
|
+ * Therefore we are sure that there are no pending stats request
|
|
+ * for which we need to wait for. We can therefore return.
|
|
+ */
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * The timer has already fired, which means we have a pending stat response.
|
|
+ * We will have to wait until we have received the pending response.
|
|
+ */
|
|
+ if (!wait_event_timeout(nq->wait_queue, atomic_read(&nq->pending_stat_requests) == 0,
|
|
+ NSS_QDISC_COMMAND_TIMEOUT)) {
|
|
+ nss_qdisc_error("Stats request command for %x timedout!\n", nq->qos_tag);
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
* nss_qdisc_gnet_stats_copy_basic()
|
|
* Wrapper around gnet_stats_copy_basic()
|
|
*/
|
|
@@ -2876,10 +3034,6 @@ static int __init nss_qdisc_module_init(
|
|
return ret;
|
|
nss_qdisc_info("nss qdisc device notifiers registered\n");
|
|
|
|
- if (!nss_qdisc_stats_work_queue_init()) {
|
|
- nss_qdisc_error("Failed to initialized stats workqueue thread\n");
|
|
- }
|
|
-
|
|
#if defined(NSS_QDISC_PPE_SUPPORT)
|
|
nss_ppe_port_res_alloc();
|
|
nss_qdisc_info("nss ppe qdsic configured");
|
|
@@ -2899,8 +3053,6 @@ static void __exit nss_qdisc_module_exit
|
|
}
|
|
#endif
|
|
|
|
- nss_qdisc_stats_work_queue_exit();
|
|
-
|
|
unregister_qdisc(&nss_pfifo_qdisc_ops);
|
|
nss_qdisc_info("nsspfifo unregistered\n");
|
|
|
|
--- a/nss_qdisc/nss_qdisc.h
|
|
+++ b/nss_qdisc/nss_qdisc.h
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2014-2018, 2020 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.
|
|
@@ -35,17 +35,12 @@
|
|
#if defined(NSS_QDISC_PPE_SUPPORT)
|
|
#include "nss_ppe.h"
|
|
#endif
|
|
-#include "nss_qdisc_stats.h"
|
|
-#include "nss_qdisc_htable.h"
|
|
|
|
#define NSS_QDISC_DEBUG_LEVEL_ERROR 1
|
|
#define NSS_QDISC_DEBUG_LEVEL_WARN 2
|
|
#define NSS_QDISC_DEBUG_LEVEL_INFO 3
|
|
#define NSS_QDISC_DEBUG_LEVEL_TRACE 4
|
|
|
|
-#define NSS_QDISC_COMMAND_TIMEOUT (10*HZ) /* We set 10sec to be the command */
|
|
- /* timeout value for messages */
|
|
-
|
|
/*
|
|
* Debug message for module init and exit
|
|
*/
|
|
@@ -92,9 +87,6 @@
|
|
#endif
|
|
#endif
|
|
|
|
-#define NSS_QDISC_STATS_SYNC_MANY_PERIOD msecs_to_jiffies(1000)
|
|
-#define NSS_QDISC_STATS_SYNC_MANY_UDELAY 5000 /* Delay for 5 ms */
|
|
-
|
|
/*
|
|
* State values
|
|
*/
|
|
@@ -144,27 +136,6 @@ struct nss_qdisc;
|
|
typedef void (*nss_qdisc_stats_callback_t)(struct nss_qdisc *nq, struct nss_shaper_node_stats_response *response);
|
|
typedef void (*nss_qdisc_configure_callback_t)(struct nss_qdisc *nq, struct nss_shaper_configure *response);
|
|
|
|
-
|
|
-/*
|
|
- * Qdisc stats sync info object
|
|
- */
|
|
-struct nss_qdisc_stats_wq {
|
|
- struct nss_qdisc *nq; /* Pointer to root nss_qdisc */
|
|
- struct list_head stats_list; /* List head stats sync management work */
|
|
- struct nss_if_msg stats_sync_req_msg; /* FW sync message */
|
|
- struct timer_list stats_get_timer; /* Timer used to start fresh iter */
|
|
- unsigned long int next_req_time; /* Time at which next sync iteration starts */
|
|
- unsigned long int stats_request_success; /* Number of success stats request */
|
|
- unsigned long int stats_request_fail; /* Number of failed stats request */
|
|
- unsigned long int stats_request_nack; /* Number of NACK'd stats request */
|
|
- atomic_t pending_stat_work; /* Pending work queue status */
|
|
- atomic_t pending_stat_resp; /* Pending statistics response from FW */
|
|
- bool stats_polling_stopped; /* True when polling is stopped due to qdisc delete */
|
|
- wait_queue_head_t stats_work_waitqueue; /* Wait queue to wait on work queue processing */
|
|
- wait_queue_head_t stats_resp_waitqueue; /* Wait queue used to wait on response from the NSS */
|
|
- struct nss_qdisc_htable nqt; /* Struct to manage hash table of Qdiscs for stats */
|
|
-};
|
|
-
|
|
struct nss_qdisc {
|
|
struct Qdisc *qdisc; /* Handy pointer back to containing qdisc */
|
|
struct nss_qdisc *parent; /* Pointer to parent nss qdisc */
|
|
@@ -226,8 +197,6 @@ struct nss_qdisc {
|
|
#endif
|
|
struct timer_list stats_get_timer; /* Timer used to poll for stats */
|
|
atomic_t pending_stat_requests; /* Number of pending stats responses */
|
|
- struct nss_qdisc_stats_wq *stats_wq; /* Stats info and state work object */
|
|
- struct hlist_node hlist; /* Hlist node for managing stats hash list */
|
|
wait_queue_head_t wait_queue; /* Wait queue used to wait on responses from the NSS */
|
|
spinlock_t lock; /* Lock to protect the nss qdisc structure */
|
|
uint16_t mode; /* Mode of Qdisc/class */
|
|
@@ -460,6 +429,18 @@ extern int nss_qdisc_init(struct Qdisc *
|
|
void *extack);
|
|
|
|
/*
|
|
+ * nss_qdisc_start_basic_stats_polling()
|
|
+ * Call to initiate the stats polling timer
|
|
+ */
|
|
+extern void nss_qdisc_start_basic_stats_polling(struct nss_qdisc *nq);
|
|
+
|
|
+/*
|
|
+ * nss_qdisc_stop_basic_stats_polling()
|
|
+ * Call to stop polling of basic stats
|
|
+ */
|
|
+extern void nss_qdisc_stop_basic_stats_polling(struct nss_qdisc *nq);
|
|
+
|
|
+/*
|
|
* nss_qdisc_gnet_stats_copy_basic()
|
|
* Wrapper around gnet_stats_copy_basic()
|
|
*/
|
|
@@ -505,15 +486,3 @@ extern unsigned long nss_qdisc_tcf_bind(
|
|
* Unbind the filter from the qdisc.
|
|
*/
|
|
extern void nss_qdisc_tcf_unbind(struct Qdisc *sch, unsigned long arg);
|
|
-
|
|
-/*
|
|
- * nss_qdisc_get_interface_msg()
|
|
- * Returns the correct message that needs to be sent down to the NSS interface.
|
|
- */
|
|
-extern int nss_qdisc_get_interface_msg(bool is_bridge, uint32_t msg_type);
|
|
-
|
|
-/*
|
|
- * nss_qdisc_msg_init()
|
|
- * Initialize the qdisc specific message
|
|
- */
|
|
-extern void nss_qdisc_msg_init(struct nss_if_msg *nim, uint16_t if_num, uint32_t msg_type, uint32_t len, nss_if_msg_callback_t cb, void *app_data);
|
|
--- a/nss_qdisc/nss_tbl.c
|
|
+++ b/nss_qdisc/nss_tbl.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2014-2017, 2019-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2014-2017, 2019-2020, 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.
|
|
@@ -88,7 +88,12 @@ static void nss_tbl_destroy(struct Qdisc
|
|
/*
|
|
* Now we can destroy our child qdisc
|
|
*/
|
|
- nss_qdisc_put(q->qdisc);
|
|
+ nss_qdisc_put(q->qdisc);
|
|
+
|
|
+ /*
|
|
+ * Stop the polling of basic stats and destroy qdisc.
|
|
+ */
|
|
+ nss_qdisc_stop_basic_stats_polling(&q->nq);
|
|
nss_qdisc_destroy(&q->nq);
|
|
}
|
|
|
|
@@ -287,6 +292,11 @@ static int nss_tbl_init(struct Qdisc *sc
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ /*
|
|
+ * Start the stats polling timer
|
|
+ */
|
|
+ nss_qdisc_start_basic_stats_polling(&q->nq);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
--- a/nss_qdisc/nss_wred.c
|
|
+++ b/nss_qdisc/nss_wred.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2014-2017, 2020-2021 The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2014-2017, 2020 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.
|
|
@@ -108,6 +108,11 @@ static void nss_wred_destroy(struct Qdis
|
|
{
|
|
struct nss_qdisc *nq = (struct nss_qdisc *)qdisc_priv(sch);
|
|
|
|
+ /*
|
|
+ * Stop the polling of basic stats
|
|
+ */
|
|
+ nss_qdisc_stop_basic_stats_polling(nq);
|
|
+
|
|
nss_qdisc_destroy(nq);
|
|
nss_qdisc_info("nsswred destroyed");
|
|
}
|
|
@@ -370,6 +375,11 @@ static int nss_wred_init(struct Qdisc *s
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ /*
|
|
+ * Start the stats polling timer
|
|
+ */
|
|
+ nss_qdisc_start_basic_stats_polling(nq);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
--- a/nss_qdisc/nss_wrr.c
|
|
+++ b/nss_qdisc/nss_wrr.c
|
|
@@ -1,13 +1,9 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2014-2017, 2019-2021, The Linux Foundation. All rights reserved.
|
|
- *
|
|
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
|
- *
|
|
+ * Copyright (c) 2014-2017, 2019-2020, 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.
|
|
- *
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
@@ -91,6 +87,11 @@ static void nss_wrr_destroy_class(struct
|
|
nss_qdisc_put(cl->qdisc);
|
|
|
|
/*
|
|
+ * Stop the stats polling timer and free class
|
|
+ */
|
|
+ nss_qdisc_stop_basic_stats_polling(&cl->nq);
|
|
+
|
|
+ /*
|
|
* Destroy the shaper in NSS
|
|
*/
|
|
nss_qdisc_destroy(&cl->nq);
|
|
@@ -351,6 +352,11 @@ static int nss_wrr_change_class(struct Q
|
|
*/
|
|
qdisc_class_hash_grow(sch, &q->clhash);
|
|
|
|
+ /*
|
|
+ * Start the stats polling timer
|
|
+ */
|
|
+ nss_qdisc_start_basic_stats_polling(&cl->nq);
|
|
+
|
|
nss_qdisc_info("Class %u successfully allocated\n", classid);
|
|
}
|
|
|
|
@@ -400,7 +406,11 @@ failure:
|
|
return -EINVAL;
|
|
}
|
|
|
|
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0))
|
|
+static int nss_wrr_delete_class(struct Qdisc *sch, unsigned long arg, struct netlink_ext_ack *extack)
|
|
+#else
|
|
static int nss_wrr_delete_class(struct Qdisc *sch, unsigned long arg)
|
|
+#endif
|
|
{
|
|
struct nss_wrr_sched_data *q = qdisc_priv(sch);
|
|
struct nss_wrr_class_data *cl = (struct nss_wrr_class_data *)arg;
|
|
@@ -408,14 +418,11 @@ static int nss_wrr_delete_class(struct Q
|
|
int refcnt;
|
|
|
|
/*
|
|
- * If the class is a root class or has a child qdisc attached
|
|
- * we do not support deleting it.
|
|
+ * Since all classes are leaf nodes in our case, we dont have to make
|
|
+ * that check.
|
|
*/
|
|
- if ((cl == &q->root) || (cl->qdisc != &noop_qdisc)) {
|
|
- nss_qdisc_warning("Cannot delete wrr class %x as it is the "
|
|
- "root class or has a child qdisc attached\n", cl->nq.qos_tag);
|
|
+ if (cl == &q->root)
|
|
return -EBUSY;
|
|
- }
|
|
|
|
/*
|
|
* The message to NSS should be sent to the parent of this class
|
|
@@ -429,24 +436,16 @@ static int nss_wrr_delete_class(struct Q
|
|
}
|
|
|
|
sch_tree_lock(sch);
|
|
+ qdisc_reset(cl->qdisc);
|
|
qdisc_class_hash_remove(&q->clhash, &cl->cl_common);
|
|
|
|
refcnt = nss_qdisc_atomic_sub_return(&cl->nq);
|
|
|
|
sch_tree_unlock(sch);
|
|
-
|
|
- /*
|
|
- * For 5.4 and above kernels, calling nss_htb_destroy_class
|
|
- * explicitly as there is no put_class which would have called
|
|
- * nss_wrr_destroy_class when refcnt becomes zero.
|
|
- */
|
|
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
|
|
- nss_wrr_destroy_class(sch, cl);
|
|
-#else
|
|
if (!refcnt) {
|
|
nss_qdisc_error("Reference count should not be zero for class %px\n", cl);
|
|
}
|
|
-#endif
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -722,6 +721,11 @@ static int nss_wrr_init_qdisc(struct Qdi
|
|
|
|
nss_qdisc_info("Nsswrr initialized - handle %x parent %x\n", sch->handle, sch->parent);
|
|
|
|
+ /*
|
|
+ * Start the stats polling timer
|
|
+ */
|
|
+ nss_qdisc_start_basic_stats_polling(&q->nq);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -760,11 +764,6 @@ static int nss_wrr_change_qdisc(struct Q
|
|
|
|
static void nss_wrr_reset_class(struct nss_wrr_class_data *cl)
|
|
{
|
|
- if (cl->qdisc == &noop_qdisc) {
|
|
- nss_qdisc_trace("Class %x has no child qdisc to reset\n", cl->nq.qos_tag);
|
|
- return;
|
|
- }
|
|
-
|
|
nss_qdisc_reset(cl->qdisc);
|
|
nss_qdisc_info("Nsswrr class resetted %px\n", cl->qdisc);
|
|
}
|
|
@@ -837,6 +836,11 @@ static void nss_wrr_destroy_qdisc(struct
|
|
qdisc_class_hash_destroy(&q->clhash);
|
|
|
|
/*
|
|
+ * Stop the polling of basic stats
|
|
+ */
|
|
+ nss_qdisc_stop_basic_stats_polling(&q->nq);
|
|
+
|
|
+ /*
|
|
* Now we can go ahead and destroy the qdisc.
|
|
* Note: We dont have to detach ourself from our parent because this
|
|
* will be taken care of by the graft call.
|
|
--- a/openvpn/plugins/Makefile
|
|
+++ b/openvpn/plugins/Makefile
|
|
@@ -1,12 +1,11 @@
|
|
|
|
# Makefile for the ovpn plugins
|
|
|
|
-ccflags-y := $(NSS_CCFLAGS) -I$(obj) -I$(obj)/../../exports -I$(obj)/include -I$(obj)/../src -I$(STAGING_DIR)/usr/include/qca-nss-ecm
|
|
-
|
|
+ccflags-y := $(NSS_CCFLAGS) -I$(obj) -I$(obj)/../../exports -I$(obj)/include -I$(obj)/../src
|
|
ccflags-y += -DNSS_CLIENT_BUILD_ID="$(BUILD_ID)"
|
|
ccflags-y += -DNSS_OVPNMGR_DEBUG_LEVEL=0
|
|
ccflags-y += -DNSS_OVPN_LINK_DEBUG_LEVEL=0
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
|
|
obj-m += qca-nss-ovpn-link.o
|
|
qca-nss-ovpn-link-objs := nss_ovpn_link.o
|
|
--- a/openvpn/plugins/nss_ovpn_sk.c
|
|
+++ b/openvpn/plugins/nss_ovpn_sk.c
|
|
@@ -19,7 +19,6 @@
|
|
* Socket implementation for OVPN.
|
|
*/
|
|
|
|
-#include <linux/version.h>
|
|
#include <linux/net.h>
|
|
#include <linux/socket.h>
|
|
#include <net/sock.h>
|
|
@@ -264,12 +263,7 @@ static int nss_ovpn_sk_update_ipv6_tuple
|
|
struct rt6_info *rt6;
|
|
int addr_type;
|
|
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
|
|
rt6 = rt6_lookup(dev_net(pinfo->dev), (struct in6_addr *)tun_data->tun_hdr.dst_ip, NULL, 0, 0);
|
|
-#else
|
|
- rt6 = rt6_lookup(dev_net(pinfo->dev), (struct in6_addr *)tun_data->tun_hdr.dst_ip, NULL, 0, 0, 0);
|
|
-#endif
|
|
-
|
|
if (!rt6) {
|
|
nss_ovpn_sk_warn("%px: Failed to find IPv6 route.\n", pinfo);
|
|
return -EINVAL;
|
|
@@ -411,11 +405,7 @@ static int nss_ovpn_sk_tun_add(struct so
|
|
* Bring up tunnel device.
|
|
*/
|
|
rtnl_lock();
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0))
|
|
err = dev_open(tun_dev);
|
|
-#else
|
|
- err = dev_open(tun_dev, NULL);
|
|
-#endif
|
|
rtnl_unlock();
|
|
|
|
if (err) {
|
|
@@ -642,11 +632,11 @@ static int nss_ovpn_sk_sendmsg(struct so
|
|
*/
|
|
static int nss_ovpn_sk_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, int flags)
|
|
{
|
|
- struct nss_ovpn_sk_pkt_info *pkt_info_data, pkt_data;
|
|
+ struct nss_ovpn_sk_pkt_info *pkt_info_data;
|
|
struct nss_ovpnmgr_metadata pkt_info;
|
|
int copied, ret;
|
|
struct sk_buff *skb;
|
|
- struct cmsghdr *cmsg, k_cmsg;
|
|
+ struct cmsghdr *cmsg;
|
|
struct sock *sk = sock->sk;
|
|
|
|
if (flags & ~(MSG_PEEK | MSG_DONTWAIT | MSG_TRUNC | MSG_CMSG_COMPAT)) {
|
|
@@ -666,13 +656,6 @@ static int nss_ovpn_sk_recvmsg(struct so
|
|
return -EINVAL;
|
|
}
|
|
|
|
- if (copy_from_user(&k_cmsg, cmsg, sizeof(struct cmsghdr))) {
|
|
- nss_ovpn_sk_warn("Copy from user failed\n");
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
- cmsg = &k_cmsg;
|
|
-
|
|
if (!CMSG_OK(msg, cmsg)) {
|
|
nss_ovpn_sk_warn("%px: Incorrect message format\n", sock);
|
|
return -EINVAL;
|
|
@@ -700,15 +683,8 @@ static int nss_ovpn_sk_recvmsg(struct so
|
|
* Send control information to application.
|
|
*/
|
|
memcpy(&pkt_info, skb->cb, sizeof(pkt_info));
|
|
-
|
|
- pkt_data.tunnel_id = pkt_info.tunnel_id;
|
|
- pkt_data.flags = pkt_info.flags;
|
|
-
|
|
- if (copy_to_user(pkt_info_data, &pkt_data, sizeof(pkt_data))) {
|
|
- nss_ovpn_sk_warn("Copy from user failed\n");
|
|
- return -EINVAL;
|
|
- }
|
|
-
|
|
+ pkt_info_data->tunnel_id = pkt_info.tunnel_id;
|
|
+ pkt_info_data->flags = pkt_info.flags;
|
|
put_cmsg(msg, SOL_IP, IP_PKTINFO, sizeof(*pkt_info_data), pkt_info_data);
|
|
|
|
copied = skb->len;
|
|
@@ -864,12 +840,7 @@ int nss_ovpn_sk_send(struct sk_buff *skb
|
|
* for indefinite time.
|
|
*/
|
|
skb_orphan(skb);
|
|
-
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
|
|
nf_reset(skb);
|
|
-#else
|
|
- nf_reset_ct(skb);
|
|
-#endif
|
|
|
|
/* Enqueue packet */
|
|
if (sock_queue_rcv_skb(sk, skb) < 0) {
|
|
--- a/openvpn/src/Makefile
|
|
+++ b/openvpn/src/Makefile
|
|
@@ -3,7 +3,7 @@
|
|
ccflags-y := $(NSS_CCFLAGS) -I$(obj) -I$(obj)/../../exports -I$(obj)/include -I$(obj)/../plugins
|
|
ccflags-y += -DNSS_CLIENT_BUILD_ID="$(BUILD_ID)"
|
|
ccflags-y += -DNSS_OVPNMGR_DEBUG_LEVEL=0 -DNSS_OVPNMGR_DEBUG_ENABLE_PKT_DUMP=0
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
|
|
obj-m += qca-nss-ovpn-mgr.o
|
|
qca-nss-ovpn-mgr-objs := nss_ovpnmgr.o nss_ovpnmgr_app.o nss_ovpnmgr_tun.o nss_ovpnmgr_crypto.o \
|
|
--- a/openvpn/src/nss_ovpnmgr.c
|
|
+++ b/openvpn/src/nss_ovpnmgr.c
|
|
@@ -99,12 +99,7 @@ static int nss_ovpnmgr_netdevice_event(s
|
|
*/
|
|
read_unlock_bh(&ovpnmgr_ctx.lock);
|
|
if (event == NETDEV_UP) {
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 0, 0))
|
|
dev_open(nss_dev);
|
|
-#else
|
|
- dev_open(nss_dev, NULL);
|
|
-#endif
|
|
-
|
|
} else {
|
|
dev_close(nss_dev);
|
|
}
|
|
--- a/openvpn/src/nss_ovpnmgr_app.c
|
|
+++ b/openvpn/src/nss_ovpnmgr_app.c
|
|
@@ -62,12 +62,7 @@ static struct net_device *nss_ovpnmgr_ap
|
|
return dev;
|
|
}
|
|
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
|
|
rt6 = rt6_lookup(&init_net, (const struct in6_addr *)rt->ip_addr, NULL, 0, 0);
|
|
-#else
|
|
- rt6 = rt6_lookup(&init_net, (const struct in6_addr *)rt->ip_addr, NULL, 0, 0, 0);
|
|
-#endif
|
|
-
|
|
if (!rt6) {
|
|
return NULL;
|
|
}
|
|
--- a/openvpn/src/nss_ovpnmgr_route.c
|
|
+++ b/openvpn/src/nss_ovpnmgr_route.c
|
|
@@ -80,7 +80,7 @@ int nss_ovpnmgr_route_set_active(struct
|
|
/*
|
|
* This API should be called under lock.
|
|
*/
|
|
- lockdep_assert_held(&ovpnmgr_ctx.lock);
|
|
+ BUG_ON(write_can_lock(&ovpnmgr_ctx.lock));
|
|
|
|
/*
|
|
* Search for route entry with from_addr.
|
|
--- a/openvpn/src/nss_ovpnmgr_tun.c
|
|
+++ b/openvpn/src/nss_ovpnmgr_tun.c
|
|
@@ -130,11 +130,7 @@ static void nss_ovpnmgr_tun_ipv6_forward
|
|
skb->protocol = htons(ETH_P_IPV6);
|
|
ip6h = ipv6_hdr(skb);
|
|
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
|
|
rt6 = rt6_lookup(dev_net(app->dev), &ip6h->daddr, &ip6h->saddr, 0, 0);
|
|
-#else
|
|
- rt6 = rt6_lookup(dev_net(app->dev), &ip6h->daddr, &ip6h->saddr, 0, 0, 0);
|
|
-#endif
|
|
if (!rt6) {
|
|
nss_ovpnmgr_warn("%px: Failed to find IPv6 route.\n", skb);
|
|
tun->outer.stats.host_pkt_drop++;
|
|
@@ -488,11 +484,7 @@ static void nss_ovpnmgr_tun_dev_setup(st
|
|
dev->header_ops = NULL;
|
|
dev->netdev_ops = &ovpnmgr_dev_ops;
|
|
dev->ethtool_ops = NULL;
|
|
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 8))
|
|
dev->destructor = nss_ovpnmgr_tun_free;
|
|
-#else
|
|
- dev->priv_destructor = nss_ovpnmgr_tun_free;
|
|
-#endif
|
|
}
|
|
|
|
/*
|
|
--- a/portifmgr/Makefile
|
|
+++ b/portifmgr/Makefile
|
|
@@ -11,4 +11,4 @@ obj-m += qca-nss-portifmgr.o
|
|
qca-nss-portifmgr-objs := nss_portifmgr.o
|
|
|
|
ccflags-y += -DNSS_PORTIFMGR_DEBUG_LEVEL=2 #-DNSS_PORTIFMGR_REF_AP148
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
\ No newline at end of file
|
|
--- a/portifmgr/nss_portifmgr.c
|
|
+++ b/portifmgr/nss_portifmgr.c
|
|
@@ -187,16 +187,20 @@ drop:
|
|
}
|
|
|
|
/*
|
|
- * nss_portifmgr_get_stats()
|
|
+ * nss_portifmgr_get_stats64()
|
|
* Netdev get stats function to get port stats
|
|
*/
|
|
-static struct rtnl_link_stats64 *nss_portifmgr_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
|
+/*
|
|
+ * nss_nlgre_redir_cmn_dev_stats64
|
|
+ * Report packet statistics to linux
|
|
+ */
|
|
+static void nss_portifmgr_get_stats64(struct net_device *dev,
|
|
+ struct rtnl_link_stats64 *stats)
|
|
{
|
|
struct nss_portifmgr_priv *priv = (struct nss_portifmgr_priv *)netdev_priv(dev);
|
|
BUG_ON(priv == NULL);
|
|
|
|
nss_portid_get_stats(priv->if_num, stats);
|
|
- return stats;
|
|
}
|
|
|
|
/*
|
|
@@ -225,7 +229,7 @@ static const struct net_device_ops nss_p
|
|
.ndo_start_xmit = nss_portifmgr_start_xmit,
|
|
.ndo_set_mac_address = eth_mac_addr,
|
|
.ndo_change_mtu = nss_portifmgr_change_mtu,
|
|
- .ndo_get_stats64 = nss_portifmgr_get_stats,
|
|
+ .ndo_get_stats64 = nss_portifmgr_get_stats64,
|
|
};
|
|
|
|
/*
|
|
--- a/pppoe/Makefile
|
|
+++ b/pppoe/Makefile
|
|
@@ -1,10 +1,12 @@
|
|
# Makefile for pppoe client
|
|
ccflags-y += -I$(obj)/../exports -I$(obj)/.. -I$(obj)/nss_hal/include
|
|
ccflags-y += -DNSS_PPPOE_DEBUG_LEVEL=0
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
obj-m += qca-nss-pppoe.o
|
|
qca-nss-pppoe-objs := nss_connmgr_pppoe.o
|
|
|
|
ifneq (,$(filter $(CONFIG_BONDING),y m))
|
|
+ifneq ($(findstring 4.4, $(KERNELVERSION)),)
|
|
ccflags-y += -DBONDING_SUPPORT
|
|
endif
|
|
+endif
|
|
--- a/pppoe/nss_connmgr_pppoe.c
|
|
+++ b/pppoe/nss_connmgr_pppoe.c
|
|
@@ -69,11 +69,7 @@ static int nss_connmgr_pppoe_get_session
|
|
return -1;
|
|
}
|
|
|
|
- if (pppoe_channel_addressing_get(channel[0], addressing)) {
|
|
- nss_connmgr_pppoe_warn("%px: failed to get addressing information\n", dev);
|
|
- ppp_release_channels(channel, 1);
|
|
- return -1;
|
|
- }
|
|
+ pppoe_channel_addressing_get(channel[0], addressing);
|
|
|
|
dev_put(addressing->dev);
|
|
ppp_release_channels(channel, 1);
|
|
--- a/pptp/Makefile
|
|
+++ b/pptp/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
# Makefile for pptp client
|
|
ccflags-y += -I$(obj)/../exports -I$(obj)/.. -I$(obj)/nss_hal/include
|
|
ccflags-y += -DNSS_PPTP_DEBUG_LEVEL=0
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
obj-m += qca-nss-pptp.o
|
|
qca-nss-pptp-objs := nss_connmgr_pptp.o
|
|
--- a/pptp/nss_connmgr_pptp.c
|
|
+++ b/pptp/nss_connmgr_pptp.c
|
|
@@ -156,11 +156,6 @@ static int nss_connmgr_pptp_get_session(
|
|
return -1;
|
|
}
|
|
|
|
- if (ppp_is_cp_enabled(dev)) {
|
|
- nss_connmgr_pptp_warning("%px: rx or tx compression is enabled for PPP\n", dev);
|
|
- return -1;
|
|
- }
|
|
-
|
|
ppp_ch_count = ppp_hold_channels(dev, channel, 1);
|
|
nss_connmgr_pptp_info("%px: PPP hold channel ret %d\n", dev, ppp_ch_count);
|
|
if (ppp_ch_count != 1) {
|
|
--- a/profiler/Makefile
|
|
+++ b/profiler/Makefile
|
|
@@ -1,5 +1,5 @@
|
|
ccflags-y := -I$(obj) -I$(obj)/.. -I$(obj)/../exports -DNSS_DEBUG_LEVEL=0 #-DPROFILE_DEBUG
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
|
|
obj-m += qca-nss-profile-drv.o
|
|
qca-nss-profile-drv-objs := profile.o
|
|
--- a/profiler/profile.c
|
|
+++ b/profiler/profile.c
|
|
@@ -31,6 +31,7 @@
|
|
#include <linux/fs.h>
|
|
#include <linux/page-flags.h>
|
|
#include <linux/sched.h>
|
|
+#include <linux/version.h>
|
|
#include <asm/uaccess.h>
|
|
#include <asm/page.h>
|
|
#include <asm/thread_info.h>
|
|
@@ -937,12 +938,26 @@ static ssize_t debug_if(struct file *fil
|
|
return count;
|
|
}
|
|
|
|
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
|
|
+#define HAVE_PROC_OPS
|
|
+#endif
|
|
+
|
|
+#ifdef HAVE_PROC_OPS
|
|
+static const struct proc_ops profile_fops = {
|
|
+ .proc_open = profile_open,
|
|
+ .proc_read = profile_read,
|
|
+ .proc_lseek = seq_lseek,
|
|
+ .proc_release = profile_release,
|
|
+ .proc_write = debug_if,
|
|
+};
|
|
+#else
|
|
static const struct file_operations profile_fops = {
|
|
.open = profile_open,
|
|
.read = profile_read,
|
|
.release = profile_release,
|
|
.write = debug_if,
|
|
};
|
|
+#endif
|
|
|
|
/*
|
|
* showing sample status on Linux console
|
|
@@ -971,6 +986,15 @@ static ssize_t profile_rate_write(struct
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef HAVE_PROC_OPS
|
|
+static const struct proc_ops profile_rate_fops = {
|
|
+ .proc_open = profile_rate_open,
|
|
+ .proc_read = seq_read,
|
|
+ .proc_lseek = seq_lseek,
|
|
+ .proc_release = single_release,
|
|
+ .proc_write = profile_rate_write,
|
|
+};
|
|
+#else
|
|
static const struct file_operations profile_rate_fops = {
|
|
.open = profile_rate_open,
|
|
.read = seq_read,
|
|
@@ -978,6 +1002,7 @@ static const struct file_operations prof
|
|
.release = single_release,
|
|
.write = profile_rate_write,
|
|
};
|
|
+#endif
|
|
|
|
/*
|
|
* hexdump
|
|
@@ -1269,25 +1294,15 @@ void netap_profile_release_resource(void
|
|
remove_proc_entry("rate", pdir);
|
|
remove_proc_entry("data", pdir);
|
|
remove_proc_entry("data1", pdir);
|
|
- proc_remove(pdir);
|
|
- pdir = NULL;
|
|
- }
|
|
-
|
|
- if (node[0]->ctx) {
|
|
- nss_profile_dma_deregister_cb(node[0]->ctx, 0);
|
|
- if (node[1] && node[1]->ctx) {
|
|
- nss_profile_dma_deregister_cb(node[1]->ctx, 0);
|
|
- nss_profiler_release_dma(node[1]->ctx);
|
|
- /*
|
|
- * node[1] memory is part of node[0] allocation; same as the ccl.
|
|
- */
|
|
- node[1] = NULL;
|
|
- }
|
|
- nss_profiler_release_dma(node[0]->ctx);
|
|
}
|
|
+ nss_profile_dma_deregister_cb(node[0]->ctx, 0);
|
|
+ nss_profile_dma_deregister_cb(node[1]->ctx, 0);
|
|
+ nss_profiler_release_dma(node[1]->ctx);
|
|
+ nss_profiler_release_dma(node[0]->ctx);
|
|
kfree(node[0]->ccl);
|
|
kfree(node[0]);
|
|
node[0] = NULL;
|
|
+
|
|
}
|
|
|
|
/*
|
|
--- a/tls/Makefile
|
|
+++ b/tls/Makefile
|
|
@@ -4,7 +4,7 @@ ccflags-y += $(NSS_CCFLAGS) -I$(obj)/../
|
|
#ccflags-y += -DNSS_TLSMGR_DEBUG_DUMP
|
|
ccflags-y += -DNSS_TLSMGR_DEBUG_LEVEL=3
|
|
ccflags-y += -DNSS_TLSMGR_BUILD_ID=\"'Build_ID - $(shell date +'%m/%d/%y, %H:%M:%S') SoC=$(SoC)'\"
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -Werror
|
|
|
|
obj-m += qca-nss-tlsmgr.o
|
|
qca-nss-tlsmgr-objs += nss_tlsmgr.o
|
|
--- a/tls/nss_tlsmgr_buf.c
|
|
+++ b/tls/nss_tlsmgr_buf.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2020, 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
|
|
@@ -52,15 +52,6 @@
|
|
#define NSS_TLSMGR_REC_MAX_SIZE (sizeof(struct nss_tlsmgr_rec) * NSS_TLSMGR_MDATA_REC_MAX)
|
|
|
|
/*
|
|
- * nss_tlsmgr_buf_get_rec_start()
|
|
- * Get record start
|
|
- */
|
|
-struct nss_tlsmgr_rec *nss_tlsmgr_buf_get_rec_start(struct nss_tlsmgr_buf *buf)
|
|
-{
|
|
- return (struct nss_tlsmgr_rec *)((uint8_t *)buf + sizeof(*buf));
|
|
-}
|
|
-
|
|
-/*
|
|
* nss_tlsmgr_buf_set_rec()
|
|
* Reserve space for a record in a buffer.
|
|
*/
|
|
@@ -181,7 +172,7 @@ EXPORT_SYMBOL(nss_tlsmgr_buf_encap);
|
|
*/
|
|
nss_tlsmgr_status_t nss_tlsmgr_buf_decap(struct nss_tlsmgr_buf *buf, nss_tlsmgr_data_callback_t cb, void *app_data)
|
|
{
|
|
- struct nss_tlsmgr_tun *tun = buf->tun;
|
|
+ struct nss_tlsmgr_tun *tun;
|
|
struct nss_tlsmgr_ctx *ctx;
|
|
struct sk_buff *skb;
|
|
struct nss_tlsmgr_rec *rec;
|
|
@@ -216,6 +207,7 @@ nss_tlsmgr_status_t nss_tlsmgr_buf_decap
|
|
skb = buf->skb;
|
|
skb_pull(skb, mdata_start - skb->data);
|
|
|
|
+ tun = buf->tun;
|
|
ctx = &tun->ctx_dec;
|
|
|
|
return nss_tlsmgr_ctx_tx(ctx, skb, rec);
|
|
--- a/tls/nss_tlsmgr_buf.h
|
|
+++ b/tls/nss_tlsmgr_buf.h
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2020, 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
|
|
@@ -41,6 +41,13 @@ struct nss_tlsmgr_buf {
|
|
|
|
void nss_tlsmgr_buf_rx(struct nss_tlsmgr_buf *buf, nss_tlsmgr_status_t status);
|
|
|
|
-struct nss_tlsmgr_rec *nss_tlsmgr_buf_get_rec_start(struct nss_tlsmgr_buf *buf);
|
|
+/*
|
|
+ * nss_tlsmgr_buf_get_rec_start()
|
|
+ * Get record start
|
|
+ */
|
|
+static struct nss_tlsmgr_rec *nss_tlsmgr_buf_get_rec_start(struct nss_tlsmgr_buf *buf)
|
|
+{
|
|
+ return (struct nss_tlsmgr_rec *)((uint8_t *)buf + sizeof(*buf));
|
|
+}
|
|
|
|
#endif /* !__NSS_TLSMGR_BUF_H_ */
|
|
--- a/tls/nss_tlsmgr_tun.c
|
|
+++ b/tls/nss_tlsmgr_tun.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2020, 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
|
|
@@ -102,7 +102,7 @@ static int nss_tlsmgr_tun_open(struct ne
|
|
* nss_tlsmgr_tun_stats64()
|
|
* TLS manager tunnel device
|
|
*/
|
|
-static struct rtnl_link_stats64 *nss_tlsmgr_get_tun_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
|
+void nss_tlsmgr_tun_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
|
{
|
|
struct nss_tlsmgr_tun *tun = netdev_priv(dev);
|
|
|
|
@@ -113,29 +113,8 @@ static struct rtnl_link_stats64 *nss_tls
|
|
nss_tlsmgr_ctx_stats_copy(&tun->ctx_dec, stats);
|
|
read_unlock_bh(&tun->lock);
|
|
|
|
- return stats;
|
|
}
|
|
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
|
|
-/*
|
|
- * nss_tlsmgr_tun_stats64()
|
|
- * Netdev ops function to retrieve stats for kernel version < 4.6
|
|
- */
|
|
-static struct rtnl_link_stats64 *nss_tlsmgr_tun_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
|
-{
|
|
- return nss_tlsmgr_get_tun_stats64(dev, stats);
|
|
-}
|
|
-#else
|
|
-/*
|
|
- * nss_tlsmgr_tun_stats64()
|
|
- * Netdev ops function to retrieve stats for kernel version >= 4.6
|
|
- */
|
|
-static void nss_tlsmgr_tun_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
|
-{
|
|
- nss_tlsmgr_get_tun_stats64(dev, stats);
|
|
-}
|
|
-#endif
|
|
-
|
|
/*
|
|
* nss_tlsmgr_tun_change_mtu()
|
|
* Change MTU size of TLS context device.
|
|
@@ -211,22 +190,13 @@ static void nss_tlsmgr_tun_free_work(str
|
|
read_unlock_bh(&tun->lock);
|
|
}
|
|
|
|
-
|
|
/*
|
|
* nss_tlsmgr_notify_event()
|
|
* TLS manager notification timer handler
|
|
*/
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
|
|
static void nss_tlsmgr_notify_event(unsigned long data)
|
|
-#else
|
|
-static void nss_tlsmgr_notify_event(struct timer_list *tm)
|
|
-#endif
|
|
{
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
|
|
struct nss_tlsmgr_tun *tun = (struct nss_tlsmgr_tun *)data;
|
|
-#else
|
|
- struct nss_tlsmgr_tun *tun = from_timer(tun, tm, notify.timer);
|
|
-#endif
|
|
nss_tlsmgr_notify_callback_t cb;
|
|
struct nss_tlsmgr_stats stats;
|
|
void *app_data;
|
|
@@ -248,17 +218,9 @@ static void nss_tlsmgr_notify_event(stru
|
|
* nss_tlsmgr_notify_decongestion()
|
|
* TLS manager decongestion notification
|
|
*/
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
|
|
static void nss_tlsmgr_notify_decongestion(unsigned long data)
|
|
-#else
|
|
-static void nss_tlsmgr_notify_decongestion(struct timer_list *tm)
|
|
-#endif
|
|
{
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
|
|
struct nss_tlsmgr_tun *tun = (struct nss_tlsmgr_tun *)data;
|
|
-#else
|
|
- struct nss_tlsmgr_tun *tun = from_timer(tun, tm, notify.timer);
|
|
-#endif
|
|
nss_tlsmgr_decongest_callback_t cb;
|
|
void *app_data;
|
|
|
|
@@ -393,7 +355,6 @@ struct net_device *nss_tlsmgr_tun_add(ns
|
|
/*
|
|
* Initialize Event notification and Decongestion timer
|
|
*/
|
|
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0))
|
|
init_timer(&tun->notify.timer);
|
|
tun->notify.timer.function = nss_tlsmgr_notify_event;
|
|
tun->notify.timer.data = (unsigned long)tun;
|
|
@@ -401,10 +362,6 @@ struct net_device *nss_tlsmgr_tun_add(ns
|
|
init_timer(&tun->decongest.timer);
|
|
tun->decongest.timer.function = nss_tlsmgr_notify_decongestion;
|
|
tun->decongest.timer.data = (unsigned long)tun;
|
|
-#else
|
|
- timer_setup(&tun->notify.timer, nss_tlsmgr_notify_event, 0);
|
|
- timer_setup(&tun->decongest.timer, nss_tlsmgr_notify_decongestion, 0);
|
|
-#endif
|
|
|
|
INIT_LIST_HEAD(&tun->free_list);
|
|
INIT_WORK(&tun->free_work, nss_tlsmgr_tun_free_work);
|
|
--- a/tunipip6/Makefile
|
|
+++ b/tunipip6/Makefile
|
|
@@ -2,7 +2,6 @@
|
|
ccflags-y += -I$(obj)/../exports -I$(obj)/..
|
|
ccflags-y += -DNSS_CLIENT_BUILD_ID="$(BUILD_ID)"
|
|
ccflags-y += -DNSS_TUNIPIP6_DEBUG_LEVEL=0
|
|
-ccflags-y += -Wall -Werror
|
|
obj-m += qca-nss-tunipip6.o
|
|
qca-nss-tunipip6-objs := nss_connmgr_tunipip6.o nss_connmgr_tunipip6_sysctl.o nss_connmgr_tunipip6_stats.o
|
|
ifneq ($(findstring 4.4, $(KERNELVERSION)),)
|
|
--- a/tunipip6/nss_connmgr_tunipip6.c
|
|
+++ b/tunipip6/nss_connmgr_tunipip6.c
|
|
@@ -194,7 +194,6 @@ static void nss_tunipip6_encap_exception
|
|
skb->pkt_type = PACKET_HOST;
|
|
skb->skb_iif = dev->ifindex;
|
|
skb->ip_summed = CHECKSUM_NONE;
|
|
- ip_rt_put(rt);
|
|
netif_receive_skb(skb);
|
|
return;
|
|
}
|
|
@@ -348,7 +347,7 @@ static void nss_tunipip6_update_dev_stat
|
|
{
|
|
struct pcpu_sw_netstats stats;
|
|
enum nss_dynamic_interface_type interface_type;
|
|
- struct nss_tunipip6_stats_sync_msg *sync_stats = (struct nss_tunipip6_stats_sync_msg *)&tnlmsg->msg.stats;
|
|
+ struct nss_tunipip6_stats_sync_msg *sync_stats = (struct nss_tunipip6_stats_sync_msg *)&tnlmsg->msg.stats_sync;
|
|
|
|
interface_type = nss_dynamic_interface_get_type(nss_tunipip6_get_context(), tnlmsg->cm.interface);
|
|
|
|
@@ -381,7 +380,7 @@ void nss_tunipip6_event_receive(void *if
|
|
netdev = (struct net_device *)if_ctx;
|
|
|
|
switch (tnlmsg->cm.type) {
|
|
- case NSS_TUNIPIP6_STATS_SYNC:
|
|
+ case NSS_TUNIPIP6_RX_STATS_SYNC:
|
|
/*
|
|
* Update netdevice statistics.
|
|
*/
|
|
@@ -627,7 +626,6 @@ configure_tunnel:
|
|
tnlcreate->ttl_inherit = tnlcfg->ttl_inherit;
|
|
tnlcreate->tos_inherit = tnlcfg->tos_inherit;
|
|
tnlcreate->frag_id_update = tnlcfg->frag_id_update;
|
|
- tnlcreate->fmr_max = tnlcfg->fmr_max;
|
|
|
|
/*
|
|
* Set "draft03" based on "tunnel_type". draft03 should be
|
|
--- a/tunipip6/nss_connmgr_tunipip6_stats.c
|
|
+++ b/tunipip6/nss_connmgr_tunipip6_stats.c
|
|
@@ -132,7 +132,7 @@ static void nss_tunipip6_stats_update(ui
|
|
void nss_tunipip6_stats_sync(struct net_device *dev, struct nss_tunipip6_msg *ntm)
|
|
{
|
|
uint32_t ifnum = ntm->cm.interface;
|
|
- struct nss_tunipip6_stats_sync_msg *stats = &ntm->msg.stats;
|
|
+ struct nss_tunipip6_stats_sync_msg *stats = &ntm->msg.stats_sync;
|
|
struct nss_tunipip6_instance *ntii;
|
|
struct nss_tunipip6_stats *s;
|
|
|
|
@@ -147,7 +147,6 @@ void nss_tunipip6_stats_sync(struct net_
|
|
s = &ntii->stats;
|
|
if (ntii->inner_ifnum == ifnum) {
|
|
nss_tunipip6_stats_update(s->inner_stats, stats);
|
|
- s->inner_stats[NSS_TUNIPIP6_STATS_CONFIG_ENCAP_TOTAL_FMR] = stats->tun_stats.encap.cfg.total_fmr;
|
|
} else if (ntii->outer_ifnum == ifnum) {
|
|
nss_tunipip6_stats_update(s->outer_stats, stats);
|
|
} else {
|
|
--- a/vlan/Makefile
|
|
+++ b/vlan/Makefile
|
|
@@ -8,8 +8,8 @@ ifeq ($(SoC),$(filter $(SoC),ipq807x ipq
|
|
ccflags-y += -DNSS_VLAN_MGR_PPE_SUPPORT
|
|
endif
|
|
|
|
-ccflags-y += -DNSS_VLAN_MGR_DEBUG_LEVEL=0
|
|
-ccflags-y += -Wall -Werror
|
|
+ccflags-y += -DNSS_VLAN_MGR_DEBUG_LEVEL=4
|
|
+ccflags-y += -Werror
|
|
|
|
ifneq (,$(filter $(CONFIG_BONDING),y m))
|
|
ccflags-y += -DBONDING_SUPPORT
|
|
--- a/vlan/nss_vlan_mgr.c
|
|
+++ b/vlan/nss_vlan_mgr.c
|
|
@@ -1,12 +1,9 @@
|
|
/*
|
|
**************************************************************************
|
|
* Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved.
|
|
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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.
|
|
- *
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
@@ -368,16 +365,22 @@ static void nss_vlan_mgr_port_role_event
|
|
* nss_vlan_mgr_bond_configure_ppe()
|
|
* Configure PPE for bond device
|
|
*/
|
|
-static int nss_vlan_mgr_bond_configure_ppe(struct nss_vlan_pvt *v, struct net_device *bond_dev, uint32_t vsi)
|
|
+static int nss_vlan_mgr_bond_configure_ppe(struct nss_vlan_pvt *v, struct net_device *bond_dev)
|
|
{
|
|
+ uint32_t vsi;
|
|
int ret = 0;
|
|
struct net_device *slave;
|
|
int32_t port;
|
|
int vlan_mgr_bond_port_role = -1;
|
|
|
|
+ if (ppe_vsi_alloc(NSS_VLAN_MGR_SWITCH_ID, &vsi)) {
|
|
+ nss_vlan_mgr_warn("%s: failed to allocate VSI for bond vlan device", bond_dev->name);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
if (nss_vlan_tx_vsi_attach_msg(v->nss_if, vsi) != NSS_TX_SUCCESS) {
|
|
nss_vlan_mgr_warn("%s: failed to attach VSI to bond vlan interface\n", bond_dev->name);
|
|
- return -1;
|
|
+ goto free_vsi;
|
|
}
|
|
|
|
/*
|
|
@@ -390,7 +393,7 @@ static int nss_vlan_mgr_bond_configure_p
|
|
if (!NSS_VLAN_PHY_PORT_CHK(port)) {
|
|
rcu_read_unlock();
|
|
nss_vlan_mgr_warn("%s: %d is not valid physical port\n", slave->name, port);
|
|
- return -1;
|
|
+ goto free_vsi;
|
|
}
|
|
|
|
/*
|
|
@@ -406,7 +409,7 @@ static int nss_vlan_mgr_bond_configure_p
|
|
* In case the bond interface has no slaves, we do not want to proceed further
|
|
*/
|
|
if (vlan_mgr_bond_port_role == -1) {
|
|
- return -1;
|
|
+ goto free_vsi;
|
|
}
|
|
|
|
/*
|
|
@@ -510,6 +513,7 @@ static int nss_vlan_mgr_bond_configure_p
|
|
ret = NSS_VLAN_PORT_ROLE_CHANGED;
|
|
}
|
|
|
|
+ v->ppe_vsi = vsi;
|
|
return ret;
|
|
|
|
delete_egress_rule:
|
|
@@ -541,19 +545,30 @@ detach_vsi:
|
|
nss_vlan_mgr_warn("%px: Failed to detach vsi %d\n", v, vsi);
|
|
}
|
|
|
|
+free_vsi:
|
|
+ if (ppe_vsi_free(NSS_VLAN_MGR_SWITCH_ID, vsi)) {
|
|
+ nss_vlan_mgr_warn("%px: Failed to free VLAN VSI\n", v);
|
|
+ }
|
|
+
|
|
return -1;
|
|
}
|
|
/*
|
|
* nss_vlan_mgr_configure_ppe()
|
|
* Configure PPE for physical devices
|
|
*/
|
|
-static int nss_vlan_mgr_configure_ppe(struct nss_vlan_pvt *v, struct net_device *dev, uint32_t vsi)
|
|
+static int nss_vlan_mgr_configure_ppe(struct nss_vlan_pvt *v, struct net_device *dev)
|
|
{
|
|
+ uint32_t vsi;
|
|
int ret = 0;
|
|
|
|
+ if (ppe_vsi_alloc(NSS_VLAN_MGR_SWITCH_ID, &vsi)) {
|
|
+ nss_vlan_mgr_warn("%s: failed to allocate VSI for vlan device", dev->name);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
if (nss_vlan_tx_vsi_attach_msg(v->nss_if, vsi) != NSS_TX_SUCCESS) {
|
|
nss_vlan_mgr_warn("%s: failed to attach VSI to vlan interface\n", dev->name);
|
|
- return -1;
|
|
+ goto free_vsi;
|
|
}
|
|
|
|
/*
|
|
@@ -637,6 +652,7 @@ static int nss_vlan_mgr_configure_ppe(st
|
|
ret = NSS_VLAN_PORT_ROLE_CHANGED;
|
|
}
|
|
|
|
+ v->ppe_vsi = vsi;
|
|
return ret;
|
|
|
|
delete_egress_rule:
|
|
@@ -658,6 +674,11 @@ detach_vsi:
|
|
nss_vlan_mgr_warn("%px: Failed to detach vsi %d\n", v, vsi);
|
|
}
|
|
|
|
+free_vsi:
|
|
+ if (ppe_vsi_free(NSS_VLAN_MGR_SWITCH_ID, vsi)) {
|
|
+ nss_vlan_mgr_warn("%px: Failed to free VLAN VSI\n", v);
|
|
+ }
|
|
+
|
|
return -1;
|
|
}
|
|
#endif
|
|
@@ -800,8 +821,10 @@ static struct nss_vlan_pvt *nss_vlan_mgr
|
|
*/
|
|
static void nss_vlan_mgr_instance_free(struct nss_vlan_pvt *v)
|
|
{
|
|
+#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
int32_t i;
|
|
int ret = 0;
|
|
+#endif
|
|
|
|
spin_lock(&vlan_mgr_ctx.lock);
|
|
BUG_ON(--v->refs);
|
|
@@ -847,8 +870,7 @@ static void nss_vlan_mgr_instance_free(s
|
|
}
|
|
|
|
/*
|
|
- * We will always have a VSI since this is allocated in beginning
|
|
- * of the code.
|
|
+ * Free PPE VSI
|
|
*/
|
|
if (ppe_vsi_free(NSS_VLAN_MGR_SWITCH_ID, v->ppe_vsi)) {
|
|
nss_vlan_mgr_warn("%px: Failed to free VLAN VSI\n", v);
|
|
@@ -957,12 +979,14 @@ static int nss_vlan_mgr_register_event(s
|
|
struct nss_vlan_pvt *v;
|
|
int if_num;
|
|
#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
- uint32_t vsi;
|
|
int ret;
|
|
#endif
|
|
uint32_t vlan_tag;
|
|
+#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
struct net_device *slave;
|
|
- int32_t port, port_if;
|
|
+ int32_t port;
|
|
+#endif
|
|
+ int32_t port_if;
|
|
struct vlan_dev_priv *vlan;
|
|
struct net_device *real_dev;
|
|
bool is_bond_master = false;
|
|
@@ -971,25 +995,19 @@ static int nss_vlan_mgr_register_event(s
|
|
if (!v)
|
|
return NOTIFY_DONE;
|
|
|
|
- /*
|
|
- * Allocate the VSI here.
|
|
- */
|
|
-#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
- if (ppe_vsi_alloc(NSS_VLAN_MGR_SWITCH_ID, &vsi)) {
|
|
- nss_vlan_mgr_warn("%s: failed to allocate VSI for vlan device", dev->name);
|
|
- return NOTIFY_DONE;
|
|
- }
|
|
-#endif
|
|
-
|
|
if_num = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_VLAN);
|
|
if (if_num < 0) {
|
|
nss_vlan_mgr_warn("%s: failed to alloc NSS dynamic interface\n", dev->name);
|
|
- goto vsi_alloc_free;
|
|
+ nss_vlan_mgr_instance_free(v);
|
|
+ return NOTIFY_DONE;
|
|
}
|
|
|
|
if (!nss_register_vlan_if(if_num, NULL, dev, 0, v)) {
|
|
nss_vlan_mgr_warn("%s: failed to register NSS dynamic interface", dev->name);
|
|
- goto free_dynamic_interface;
|
|
+ if (nss_dynamic_interface_dealloc_node(if_num, NSS_DYNAMIC_INTERFACE_TYPE_VLAN) != NSS_TX_SUCCESS)
|
|
+ nss_vlan_mgr_warn("%px: Failed to dealloc vlan dynamic interface\n", v);
|
|
+ nss_vlan_mgr_instance_free(v);
|
|
+ return NOTIFY_DONE;
|
|
}
|
|
v->nss_if = if_num;
|
|
|
|
@@ -1003,25 +1021,26 @@ static int nss_vlan_mgr_register_event(s
|
|
|
|
#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
if (!is_bond_master)
|
|
- ret = nss_vlan_mgr_configure_ppe(v, dev, vsi);
|
|
+ ret = nss_vlan_mgr_configure_ppe(v, dev);
|
|
else
|
|
- ret = nss_vlan_mgr_bond_configure_ppe(v, real_dev, vsi);
|
|
+ ret = nss_vlan_mgr_bond_configure_ppe(v, real_dev);
|
|
|
|
if (ret < 0) {
|
|
- goto vlan_instance_free;
|
|
+ nss_vlan_mgr_instance_free(v);
|
|
+ return NOTIFY_DONE;
|
|
}
|
|
-
|
|
- v->ppe_vsi = vsi;
|
|
#endif
|
|
|
|
if (nss_vlan_tx_set_mac_addr_msg(v->nss_if, v->dev_addr) != NSS_TX_SUCCESS) {
|
|
nss_vlan_mgr_warn("%s: failed to set mac_addr msg\n", dev->name);
|
|
- goto vlan_instance_free;
|
|
+ nss_vlan_mgr_instance_free(v);
|
|
+ return NOTIFY_DONE;
|
|
}
|
|
|
|
if (nss_vlan_tx_set_mtu_msg(v->nss_if, v->mtu) != NSS_TX_SUCCESS) {
|
|
nss_vlan_mgr_warn("%s: failed to set mtu msg\n", dev->name);
|
|
- goto vlan_instance_free;
|
|
+ nss_vlan_mgr_instance_free(v);
|
|
+ return NOTIFY_DONE;
|
|
}
|
|
|
|
vlan_tag = (v->tpid << NSS_VLAN_TPID_SHIFT | v->vid);
|
|
@@ -1030,7 +1049,8 @@ static int nss_vlan_mgr_register_event(s
|
|
(v->parent ? v->parent->nss_if : port_if),
|
|
port_if) != NSS_TX_SUCCESS) {
|
|
nss_vlan_mgr_warn("%s: failed to add vlan in nss\n", dev->name);
|
|
- goto vlan_instance_free;
|
|
+ nss_vlan_mgr_instance_free(v);
|
|
+ return NOTIFY_DONE;
|
|
}
|
|
|
|
spin_lock(&vlan_mgr_ctx.lock);
|
|
@@ -1058,21 +1078,6 @@ static int nss_vlan_mgr_register_event(s
|
|
}
|
|
#endif
|
|
return NOTIFY_DONE;
|
|
-
|
|
-free_dynamic_interface:
|
|
- if (nss_dynamic_interface_dealloc_node(if_num, NSS_DYNAMIC_INTERFACE_TYPE_VLAN) != NSS_TX_SUCCESS)
|
|
- nss_vlan_mgr_warn("%px: Failed to dealloc vlan dynamic interface\n", v);
|
|
-
|
|
-vsi_alloc_free:
|
|
-#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
- if (ppe_vsi_free(NSS_VLAN_MGR_SWITCH_ID, v->ppe_vsi)) {
|
|
- nss_vlan_mgr_warn("%px: Failed to free VLAN VSI\n", v);
|
|
- }
|
|
-#endif
|
|
-
|
|
-vlan_instance_free:
|
|
- nss_vlan_mgr_instance_free(v);
|
|
- return NOTIFY_DONE;
|
|
}
|
|
|
|
/*
|
|
@@ -1355,8 +1360,10 @@ return_with_error:
|
|
int nss_vlan_mgr_join_bridge(struct net_device *dev, uint32_t bridge_vsi)
|
|
{
|
|
struct nss_vlan_pvt *v = nss_vlan_mgr_instance_find_and_ref(dev);
|
|
+#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
struct net_device *real_dev;
|
|
int ret;
|
|
+#endif
|
|
|
|
if (!v)
|
|
return 0;
|
|
@@ -1416,8 +1423,10 @@ EXPORT_SYMBOL(nss_vlan_mgr_join_bridge);
|
|
int nss_vlan_mgr_leave_bridge(struct net_device *dev, uint32_t bridge_vsi)
|
|
{
|
|
struct nss_vlan_pvt *v = nss_vlan_mgr_instance_find_and_ref(dev);
|
|
+#ifdef NSS_VLAN_MGR_PPE_SUPPORT
|
|
struct net_device *real_dev;
|
|
int ret;
|
|
+#endif
|
|
|
|
if (!v)
|
|
return 0;
|
|
--- a/vxlanmgr/nss_vxlanmgr.c
|
|
+++ b/vxlanmgr/nss_vxlanmgr.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2019-2020, 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.
|
|
@@ -22,18 +22,15 @@
|
|
#include <linux/module.h>
|
|
#include <linux/netdevice.h>
|
|
#include <linux/of.h>
|
|
-#include <linux/rcupdate.h>
|
|
#include <net/vxlan.h>
|
|
#include <nss_api_if.h>
|
|
#include "nss_vxlanmgr.h"
|
|
-#include "nss_vxlanmgr_priv.h"
|
|
#include "nss_vxlanmgr_tun_stats.h"
|
|
|
|
/*
|
|
* VxLAN context
|
|
*/
|
|
struct nss_vxlanmgr_ctx vxlan_ctx;
|
|
-static struct nss_vxlanmgr_get_ipsec_if_num __rcu ipsecmgr_cb;
|
|
|
|
/*
|
|
* nss_vxlanmgr_netdev_event()
|
|
@@ -77,77 +74,6 @@ static struct notifier_block nss_vxlanmg
|
|
};
|
|
|
|
/*
|
|
- * nss_vxlanmgr_bind_ipsec_by_ip()
|
|
- * Bind VxLAN tunnel with IPsec based on IP Address
|
|
- */
|
|
-int32_t nss_vxlanmgr_bind_ipsec_by_ip(union vxlan_addr *src_ip, union vxlan_addr *dest_ip)
|
|
-{
|
|
- int32_t ipsec_if_num;
|
|
- nss_vxlanmgr_get_ipsec_if_num_by_ip_callback_t ipsec_cb;
|
|
- struct nss_ctx_instance *nss_ctx = nss_vxlan_get_ctx();
|
|
-
|
|
- /*
|
|
- * Check if the VxLAN interface is applied over an IPsec interface by querying the IPsec.
|
|
- */
|
|
- rcu_read_lock();
|
|
- ipsec_cb = rcu_dereference(ipsecmgr_cb.get_ifnum_by_ip);
|
|
- if (!ipsec_cb) {
|
|
- rcu_read_unlock();
|
|
- nss_vxlanmgr_info("%px: IPsec get_ifnum_by_ip callback is not registered\n", nss_ctx);
|
|
- return -1;
|
|
- }
|
|
-
|
|
- if (dest_ip->sa.sa_family == AF_INET) {
|
|
- ipsec_if_num = ipsec_cb(IPVERSION, &src_ip->sin.sin_addr.s_addr, &dest_ip->sin.sin_addr.s_addr);
|
|
- } else {
|
|
- ipsec_if_num = ipsec_cb(6, src_ip->sin6.sin6_addr.in6_u.u6_addr32, dest_ip->sin6.sin6_addr.in6_u.u6_addr32);
|
|
- }
|
|
-
|
|
- rcu_read_unlock();
|
|
- nss_vxlanmgr_info("%px: VxLAN interface is bound to IPsec interface with if_num(0x%x)\n", nss_ctx, ipsec_if_num);
|
|
-
|
|
- return ipsec_if_num;
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_vxlanmgr_unregister_ipsecmgr_callback_by_ip
|
|
- * Unregister callback.
|
|
- */
|
|
-void nss_vxlanmgr_unregister_ipsecmgr_callback_by_ip(void)
|
|
-{
|
|
- rcu_assign_pointer(ipsecmgr_cb.get_ifnum_by_ip, NULL);
|
|
- synchronize_rcu();
|
|
-}
|
|
-EXPORT_SYMBOL(nss_vxlanmgr_unregister_ipsecmgr_callback_by_ip);
|
|
-
|
|
-/*
|
|
- * nss_vxlanmgr_register_ipsecmgr_callback_by_ip()
|
|
- * Register IPSecmgr callback.
|
|
- */
|
|
-void nss_vxlanmgr_register_ipsecmgr_callback_by_ip(struct nss_vxlanmgr_get_ipsec_if_num *cb)
|
|
-{
|
|
- nss_vxlanmgr_get_ipsec_if_num_by_ip_callback_t ipsec_get_ifnum_by_ip;
|
|
-
|
|
- rcu_read_lock();
|
|
- ipsec_get_ifnum_by_ip = rcu_dereference(ipsecmgr_cb.get_ifnum_by_ip);
|
|
- if (ipsec_get_ifnum_by_ip) {
|
|
- rcu_read_unlock();
|
|
- nss_vxlanmgr_info("%px: IPSecmgr Callback get_ifnum_by_ip is already registered\n", cb);
|
|
- return;
|
|
- }
|
|
- rcu_read_unlock();
|
|
-
|
|
- if (cb->get_ifnum_by_ip == NULL) {
|
|
- nss_vxlanmgr_warn("%px: IPSecmgr Callback get_ifnum_by_ip is NULL\n", cb);
|
|
- return;
|
|
- }
|
|
-
|
|
- rcu_assign_pointer(ipsecmgr_cb.get_ifnum_by_ip, cb->get_ifnum_by_ip);
|
|
- synchronize_rcu();
|
|
-}
|
|
-EXPORT_SYMBOL(nss_vxlanmgr_register_ipsecmgr_callback_by_ip);
|
|
-
|
|
-/*
|
|
* nss_vxlanmgr_exit_module()
|
|
* Tunnel vxlan module exit function
|
|
*/
|
|
@@ -194,12 +120,6 @@ int __init nss_vxlanmgr_init_module(void
|
|
return -1;
|
|
}
|
|
|
|
- /*
|
|
- * Initialize ipsecmgr callback.
|
|
- */
|
|
- rcu_assign_pointer(ipsecmgr_cb.get_ifnum_by_ip, NULL);
|
|
- synchronize_rcu();
|
|
-
|
|
INIT_LIST_HEAD(&vxlan_ctx.list);
|
|
vxlan_ctx.nss_ctx = nss_vxlan_get_ctx();
|
|
spin_lock_init(&vxlan_ctx.tun_lock);
|
|
--- /dev/null
|
|
+++ b/vxlanmgr/nss_vxlanmgr.h
|
|
@@ -0,0 +1,85 @@
|
|
+/*
|
|
+ **************************************************************************
|
|
+ * Copyright (c) 2019, 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.
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
|
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
+ **************************************************************************
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * nss_vxlanmgr.h
|
|
+ * VxLAN manager header
|
|
+ */
|
|
+#ifndef __NSS_VXLANMGR_H
|
|
+#define __NSS_VXLANMGR_H
|
|
+
|
|
+/*
|
|
+ * Compile messages for dynamic enable/disable
|
|
+ */
|
|
+#if defined(CONFIG_DYNAMIC_DEBUG)
|
|
+#define nss_vxlanmgr_warn(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
+#define nss_vxlanmgr_info(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
+#define nss_vxlanmgr_trace(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
+#else /* CONFIG_DYNAMIC_DEBUG */
|
|
+/*
|
|
+ * Statically compile messages at different levels
|
|
+ */
|
|
+#if (NSS_VXLANMGR_DEBUG_LEVEL < 2)
|
|
+#define nss_vxlanmgr_warn(s, ...)
|
|
+#else
|
|
+#define nss_vxlanmgr_warn(s, ...) pr_warn("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
+#endif
|
|
+
|
|
+#if (NSS_VXLANMGR_DEBUG_LEVEL < 3)
|
|
+#define nss_vxlanmgr_info(s, ...)
|
|
+#else
|
|
+#define nss_vxlanmgr_info(s, ...) pr_notice("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
+#endif
|
|
+
|
|
+#if (NSS_VXLANMGR_DEBUG_LEVEL < 4)
|
|
+#define nss_vxlanmgr_trace(s, ...)
|
|
+#else
|
|
+#define nss_vxlanmgr_trace(s, ...) pr_info("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
+#endif
|
|
+#endif /* CONFIG_DYNAMIC_DEBUG */
|
|
+
|
|
+struct nss_vxlanmgr_ctx {
|
|
+ struct list_head list; /* vxlanmgr context list head */
|
|
+ struct dentry *dentry; /* debugfs entry for qca-nss-vxlanmgr */
|
|
+ struct nss_ctx_instance *nss_ctx; /* nss context for vxlan tunnel */
|
|
+ uint32_t tun_count; /* active vxlan tunnel count */
|
|
+ spinlock_t tun_lock; /* spinlock */
|
|
+};
|
|
+
|
|
+struct nss_vxlanmgr_tun_ctx {
|
|
+ struct list_head head; /* tunnel context list entry */
|
|
+ struct net_device *dev; /* tunnel netdevice pointer */
|
|
+ struct dentry *dentry; /* per tunnel debugfs entry */
|
|
+ struct nss_vxlanmgr_ctx *vxlan_ctx; /* pointer to vxlanmgr context */
|
|
+ struct nss_vxlanmgr_tun_stats *stats; /* tunnel statistics structure */
|
|
+ uint32_t inner_ifnum; /* inner node interface number */
|
|
+ uint32_t outer_ifnum; /* outer node interface number */
|
|
+ uint32_t vni; /* vnet identifier */
|
|
+ uint16_t tunnel_flags; /* vxlan tunnel flags */
|
|
+ uint16_t flow_label; /* flowlabel */
|
|
+ uint16_t src_port_min; /* minimum source port */
|
|
+ uint16_t src_port_max; /* maximum source port*/
|
|
+ uint16_t dest_port; /* destination port */
|
|
+ uint8_t tos; /* tos value */
|
|
+ uint8_t ttl; /* time to live */
|
|
+};
|
|
+
|
|
+extern int nss_vxlanmgr_tunnel_create(struct net_device *dev);
|
|
+extern int nss_vxlanmgr_tunnel_destroy(struct net_device *dev);
|
|
+extern int nss_vxlanmgr_tunnel_config(struct net_device *dev);
|
|
+extern int nss_vxlanmgr_tunnel_deconfig(struct net_device *dev);
|
|
+
|
|
+#endif /* __NSS_VXLANMGR_H */
|
|
--- a/vxlanmgr/nss_vxlanmgr_tun_stats.c
|
|
+++ b/vxlanmgr/nss_vxlanmgr_tun_stats.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2019-2020, 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.
|
|
@@ -18,7 +18,7 @@
|
|
#include <linux/etherdevice.h>
|
|
#include <linux/netdevice.h>
|
|
#include <nss_api_if.h>
|
|
-#include "nss_vxlanmgr_priv.h"
|
|
+#include "nss_vxlanmgr.h"
|
|
#include "nss_vxlanmgr_tun_stats.h"
|
|
|
|
/*
|
|
@@ -47,8 +47,6 @@ static int8_t *nss_vxlanmgr_tun_stats_st
|
|
"Except VNI Look-up failed",
|
|
"Dropped packet malformed",
|
|
"Dropped next node queue is full",
|
|
- "Except Inner hash calculation failed",
|
|
- "Decap IPSec source interface invalid"
|
|
};
|
|
|
|
/*
|
|
@@ -90,7 +88,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", tun_ctx->dest_port);
|
|
+ seq_printf(m, "\t\tdest_port = %u\n", ntohs(tun_ctx->dest_port));
|
|
seq_printf(m, "\t\ttos = %u\n", tun_ctx->tos);
|
|
seq_printf(m, "\t\tttl = %u\n", tun_ctx->ttl);
|
|
|
|
@@ -167,16 +165,11 @@ void nss_vxlanmgr_tun_stats_update(uint6
|
|
stats_msg->dropped_malformed;
|
|
stats[NSS_VXLANMGR_TUN_STATS_TYPE_DROP_NEXT_NODE_QUEUE_FULL] +=
|
|
stats_msg->dropped_next_node_queue_full;
|
|
- stats[NSS_VXLANMGR_TUN_STATS_TYPE_EXCEPT_INNER_HASH] +=
|
|
- stats_msg->except_inner_hash;
|
|
- stats[NSS_VXLANMGR_TUN_STATS_TYPE_DECAP_IPSEC_SRC_INVALID] +=
|
|
- stats_msg->decap_ipsec_src_err;
|
|
}
|
|
|
|
/*
|
|
* 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)
|
|
{
|
|
@@ -187,8 +180,11 @@ 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;
|
|
}
|
|
|
|
@@ -204,6 +200,7 @@ void nss_vxlanmgr_tun_macdb_stats_sync(s
|
|
}
|
|
}
|
|
}
|
|
+ dev_put(tun_ctx->dev);
|
|
}
|
|
|
|
/*
|
|
--- a/vxlanmgr/nss_vxlanmgr_tun_stats.h
|
|
+++ b/vxlanmgr/nss_vxlanmgr_tun_stats.h
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
******************************************************************************
|
|
- * Copyright (c) 2019, 2021 The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2019, 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.
|
|
@@ -37,8 +37,6 @@ enum nss_vxlanmgr_tun_stats_type {
|
|
NSS_VXLANMGR_TUN_STATS_TYPE_EXCEPT_VNI_LOOKUP_FAILED,
|
|
NSS_VXLANMGR_TUN_STATS_TYPE_DROP_MALFORMED,
|
|
NSS_VXLANMGR_TUN_STATS_TYPE_DROP_NEXT_NODE_QUEUE_FULL,
|
|
- NSS_VXLANMGR_TUN_STATS_TYPE_EXCEPT_INNER_HASH,
|
|
- NSS_VXLANMGR_TUN_STATS_TYPE_DECAP_IPSEC_SRC_INVALID,
|
|
NSS_VXLANMGR_TUN_STATS_TYPE_MAX,
|
|
};
|
|
|
|
--- a/vxlanmgr/nss_vxlanmgr_tunnel.c
|
|
+++ b/vxlanmgr/nss_vxlanmgr_tunnel.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
**************************************************************************
|
|
- * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
|
+ * Copyright (c) 2019-2020, 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.
|
|
@@ -27,7 +27,7 @@
|
|
#include <net/route.h>
|
|
#include <net/vxlan.h>
|
|
#include <nss_api_if.h>
|
|
-#include "nss_vxlanmgr_priv.h"
|
|
+#include "nss_vxlanmgr.h"
|
|
#include "nss_vxlanmgr_tun_stats.h"
|
|
|
|
/*
|
|
@@ -91,23 +91,18 @@ 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;
|
|
- if (!(priv_flags & VXLAN_F_UDP_ZERO_CSUM6_TX))
|
|
- flags |= NSS_VXLAN_RULE_FLAG_ENCAP_L4_CSUM_REQUIRED;
|
|
- } else {
|
|
+ else if (!(priv_flags & VXLAN_F_IPV6))
|
|
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);
|
|
}
|
|
@@ -118,25 +113,18 @@ 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;
|
|
- if (!(priv_flags & VXLAN_F_UDP_ZERO_CSUM6_TX))
|
|
- flags |= NSS_VXLAN_RULE_FLAG_ENCAP_L4_CSUM_REQUIRED;
|
|
- } else {
|
|
+ else if (!(priv_flags & VXLAN_F_IPV6))
|
|
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);
|
|
}
|
|
@@ -323,7 +311,6 @@ static nss_tx_status_t nss_vxlanmgr_tunn
|
|
union vxlan_addr *remote_ip, *src_ip;
|
|
uint32_t i, inner_ifnum;
|
|
uint32_t new_src_ip[4] = {0};
|
|
- int32_t ipsec_if_num;
|
|
nss_tx_status_t status = NSS_TX_FAILURE;
|
|
|
|
dev = vfe->dev;
|
|
@@ -380,17 +367,6 @@ static nss_tx_status_t nss_vxlanmgr_tunn
|
|
}
|
|
|
|
/*
|
|
- * Check if this is a VxLAN over IPsec use case. If so, we need to bind the IPsec interface to the VxLAN.
|
|
- * When the IPsec interface is deleted in NSS, user is expected to bring the vxlan interface down as well, thereby flushing the MAC entries in NSS.
|
|
- */
|
|
- ipsec_if_num = nss_vxlanmgr_bind_ipsec_by_ip(src_ip, remote_ip);
|
|
- if (ipsec_if_num > 0) {
|
|
- mac_add_msg->ipsec_if_num = (uint32_t)ipsec_if_num;
|
|
- mac_add_msg->flags = mac_add_msg->flags | NSS_VXLAN_MAC_ENABLE_IPSEC_BIND;
|
|
- nss_vxlanmgr_trace("%px: VxLAN interface is bound to IPsec interface with if_num(0x%x)\n", dev, ipsec_if_num);
|
|
- }
|
|
-
|
|
- /*
|
|
* Send MAC add message asynchronously as it is called by chain
|
|
* notifier in atomic context from the vxlan driver.
|
|
*/
|
|
@@ -460,8 +436,7 @@ static struct notifier_block nss_vxlanmg
|
|
|
|
/*
|
|
* nss_vxlanmgr_tunnel_inner_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.
|
|
+ * Update vxlan netdev stats with inner node stats
|
|
*/
|
|
static void nss_vxlanmgr_tunnel_inner_stats(struct nss_vxlanmgr_tun_ctx *tun_ctx, struct nss_vxlan_msg *nvm)
|
|
{
|
|
@@ -475,6 +450,7 @@ 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;
|
|
|
|
/*
|
|
@@ -493,6 +469,7 @@ static void nss_vxlanmgr_tunnel_inner_st
|
|
tstats->tx_bytes += stats->node_stats.tx_bytes;
|
|
u64_stats_update_end(&tstats->syncp);
|
|
netdev_stats->tx_dropped += dropped;
|
|
+ dev_put(dev);
|
|
}
|
|
|
|
/*
|
|
@@ -537,7 +514,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 net_device *dev, uint32_t vni, struct nss_vxlan_msg *nvm)
|
|
+static void nss_vxlanmgr_tunnel_fdb_update(struct nss_vxlanmgr_tun_ctx *tun_ctx, struct nss_vxlan_msg *nvm)
|
|
{
|
|
uint8_t *mac;
|
|
uint16_t i, nentries;
|
|
@@ -546,10 +523,13 @@ static void nss_vxlanmgr_tunnel_fdb_upda
|
|
|
|
db_stats = &nvm->msg.db_stats;
|
|
nentries = db_stats->cnt;
|
|
- priv = netdev_priv(dev);
|
|
+ priv = netdev_priv(tun_ctx->dev);
|
|
+
|
|
+ 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", dev);
|
|
+ nss_vxlanmgr_warn("%px: No more than 20 entries allowed per message.\n", tun_ctx->dev);
|
|
+ dev_put(tun_ctx->dev);
|
|
return;
|
|
}
|
|
|
|
@@ -559,10 +539,11 @@ 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, vni);
|
|
+ vxlan_fdb_update_mac(priv, mac, tun_ctx->vni);
|
|
#endif
|
|
}
|
|
}
|
|
+ dev_put(tun_ctx->dev);
|
|
}
|
|
|
|
/*
|
|
@@ -574,29 +555,20 @@ 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:
|
|
@@ -604,24 +576,14 @@ 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);
|
|
-
|
|
- /*
|
|
- * 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_tunnel_fdb_update(dev, vni, nvm);
|
|
- dev_put(dev);
|
|
- return;
|
|
+ break;
|
|
default:
|
|
+ spin_unlock_bh(&vxlan_ctx.tun_lock);
|
|
nss_vxlanmgr_info("%px: Unknown Event from NSS", dev);
|
|
+ return;
|
|
}
|
|
-
|
|
- dev_put(dev);
|
|
spin_unlock_bh(&vxlan_ctx.tun_lock);
|
|
}
|
|
|
|
@@ -867,7 +829,7 @@ done:
|
|
*/
|
|
int nss_vxlanmgr_tunnel_destroy(struct net_device *dev)
|
|
{
|
|
- uint32_t inner_ifnum, outer_ifnum, tun_count;
|
|
+ uint32_t inner_ifnum, outer_ifnum;
|
|
struct nss_vxlanmgr_tun_ctx *tun_ctx;
|
|
struct nss_vxlan_msg vxlanmsg;
|
|
nss_tx_status_t ret;
|
|
@@ -904,21 +866,16 @@ 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);
|
|
|
|
- /*
|
|
- * 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) {
|
|
+ if (!vxlan_ctx.tun_count) {
|
|
+ /*
|
|
+ * Unregister fdb notifier chain if
|
|
+ * all vxlan tunnels are destroyed.
|
|
+ */
|
|
vxlan_fdb_unregister_notify(&nss_vxlanmgr_tunnel_fdb_notifier);
|
|
}
|
|
-
|
|
- nss_vxlanmgr_info("%px: VxLAN interface count is #%d\n", dev, tun_count);
|
|
+ nss_vxlanmgr_info("%px: VxLAN interface count is #%d\n", dev, vxlan_ctx.tun_count);
|
|
|
|
memset(&vxlanmsg, 0, sizeof(struct nss_vxlan_msg));
|
|
ret = nss_vxlanmgr_tunnel_tx_msg_sync(vxlan_ctx.nss_ctx,
|
|
@@ -972,7 +929,6 @@ 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);
|
|
@@ -983,20 +939,7 @@ 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) {
|
|
@@ -1045,11 +988,12 @@ 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 = parse_flags;
|
|
+ vxlan_cfg->tunnel_flags = nss_vxlanmgr_tunnel_flags_parse(priv);
|
|
vxlan_cfg->src_port_min = priv->cfg.port_min;
|
|
vxlan_cfg->src_port_max = priv->cfg.port_max;
|
|
- vxlan_cfg->dest_port = ntohs(priv->cfg.dst_port);
|
|
+ vxlan_cfg->dest_port = priv->cfg.dst_port;
|
|
vxlan_cfg->tos = priv->cfg.tos;
|
|
vxlan_cfg->ttl = (priv->cfg.ttl ? priv->cfg.ttl : IPDEFTTL);
|
|
|
|
@@ -1115,6 +1059,7 @@ 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/wifi_meshmgr/Makefile
|
|
+++ /dev/null
|
|
@@ -1,7 +0,0 @@
|
|
-ccflags-y += -I$(obj)/../exports -I$(obj)/.. -I$(obj)/nss_hal/include
|
|
-ccflags-y += -DNSS_CLIENT_BUILD_ID="$(BUILD_ID)"
|
|
-ccflags-y += -DNSS_WIFI_MESHMGR_DEBUG_LEVEL=4
|
|
-ccflags-y += -Wall -Werror
|
|
-
|
|
-obj-m += qca-nss-wifi-meshmgr.o
|
|
-qca-nss-wifi-meshmgr-objs := nss_wifi_meshmgr.o
|
|
--- a/wifi_meshmgr/nss_wifi_mesh_priv.h
|
|
+++ /dev/null
|
|
@@ -1,83 +0,0 @@
|
|
-/*
|
|
- **************************************************************************
|
|
- * Copyright (c) 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.
|
|
- *
|
|
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
- **************************************************************************
|
|
- */
|
|
-
|
|
-/*
|
|
- * nss_wifi_mesh_priv.h
|
|
- * Mesh manager header
|
|
- */
|
|
-#ifndef __NSS_WIFI_MESH_PRIV_H_
|
|
-#define __NSS_WIFI_MESH_PRIV_H_
|
|
-
|
|
-#define NSS_WIFI_MESH_MAX 16
|
|
-
|
|
-/*
|
|
- * Compile messages for dynamic enable/disable
|
|
- */
|
|
-#if defined(CONFIG_DYNAMIC_DEBUG)
|
|
-#define nss_wifi_meshmgr_warn(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
-#define nss_wifi_meshmgr_info(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
-#define nss_wifi_meshmgr_trace(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
-#else /* CONFIG_DYNAMIC_DEBUG */
|
|
-/*
|
|
- * Statically compile messages at different levels
|
|
- */
|
|
-#if (NSS_WIFI_MESHMGR_DEBUG_LEVEL < 2)
|
|
-#define nss_wifi_meshmgr_warn(s, ...)
|
|
-#else
|
|
-#define nss_wifi_meshmgr_warn(s, ...) pr_warn("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
-#endif
|
|
-
|
|
-#if (NSS_WIFI_MESHMGR_DEBUG_LEVEL < 3)
|
|
-#define nss_wifi_meshmgr_info(s, ...)
|
|
-#else
|
|
-#define nss_wifi_meshmgr_info(s, ...) pr_notice("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
-#endif
|
|
-
|
|
-#if (NSS_WIFI_MESHMGR_DEBUG_LEVEL < 4)
|
|
-#define nss_wifi_meshmgr_trace(s, ...)
|
|
-#else
|
|
-#define nss_wifi_meshmgr_trace(s, ...) pr_info("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
|
-#endif
|
|
-#endif /* CONFIG_DYNAMIC_DEBUG */
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_ctx
|
|
- * Mesh context per interface.
|
|
- */
|
|
-struct nss_wifi_meshmgr_mesh_ctx {
|
|
- struct net_device *dev; /* Netdevice pointer */
|
|
- atomic_t ref; /* Atomic reference count */
|
|
- int32_t encap_ifnum; /* Encap interface number */
|
|
- int32_t decap_ifnum; /* Decap interface number */
|
|
- struct semaphore sem; /* Semaphore for message synchronization */
|
|
- struct completion complete; /* Per context complete */
|
|
- nss_tx_status_t response; /* Response type */
|
|
-};
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_ctx
|
|
- * Global mesh context.
|
|
- */
|
|
-struct nss_wifi_meshmgr_ctx {
|
|
- struct nss_ctx_instance *nss_ctx; /* Nss context for mesh */
|
|
- uint32_t mesh_count; /* Active mesh count */
|
|
- spinlock_t ref_lock; /* Spinlock */
|
|
- struct nss_wifi_meshmgr_mesh_ctx *mesh_ctx[NSS_WIFI_MESH_MAX];
|
|
- /* Mesh handle table */
|
|
-};
|
|
-#endif /* __NSS_WIFI_MESH_PRIV_H_ */
|
|
--- a/wifi_meshmgr/nss_wifi_meshmgr.c
|
|
+++ /dev/null
|
|
@@ -1,2005 +0,0 @@
|
|
-/*
|
|
- **************************************************************************
|
|
- * Copyright (c) 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.
|
|
- *
|
|
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
- **************************************************************************
|
|
- */
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr.c
|
|
- * NSS to HLOS WiFi-Mesh manager
|
|
- */
|
|
-
|
|
-#include <linux/module.h>
|
|
-#include <linux/netdevice.h>
|
|
-#include <linux/of.h>
|
|
-#include <nss_api_if.h>
|
|
-#include <nss_wifi_meshmgr.h>
|
|
-#include "nss_wifi_mesh_priv.h"
|
|
-
|
|
-/*
|
|
- * WiFi-Mesh context
|
|
- */
|
|
-static struct nss_wifi_meshmgr_ctx wmgr_ctx;
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_verify_if_num()
|
|
- * Verify interface number.
|
|
- */
|
|
-static bool nss_wifi_meshmgr_verify_if_num(int32_t if_num, enum nss_dynamic_interface_type di_type)
|
|
-{
|
|
- return (nss_is_dynamic_interface(if_num) &&
|
|
- (nss_dynamic_interface_get_type(wmgr_ctx.nss_ctx, if_num) == di_type));
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_tx_msg()
|
|
- * WiFi-Mesh message send API
|
|
- */
|
|
-static nss_wifi_meshmgr_status_t nss_wifi_meshmgr_tx_msg(struct nss_wifi_mesh_msg *msg)
|
|
-{
|
|
- return nss_wifi_mesh_tx_msg(wmgr_ctx.nss_ctx, msg);
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_ctx_insert()
|
|
- * Insert the mesh context into global table
|
|
- */
|
|
-static int32_t nss_wifi_meshmgr_ctx_insert(struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx)
|
|
-{
|
|
- int32_t i, idx = -1;
|
|
- struct net_device *dev;
|
|
-
|
|
- assert_spin_locked(&wmgr_ctx.ref_lock);
|
|
-
|
|
- /*
|
|
- * Check if the context already exist for the same netdev.
|
|
- */
|
|
- for (i = 0; i < NSS_WIFI_MESH_MAX; i++) {
|
|
- if (!wmgr_ctx.mesh_ctx[i]) {
|
|
- idx = i;
|
|
- continue;
|
|
- }
|
|
-
|
|
- dev = (wmgr_ctx.mesh_ctx[i])->dev;
|
|
- if (dev == wmesh_ctx->dev) {
|
|
- nss_wifi_meshmgr_warn("%px: The mesh context already exist for dev:%s",
|
|
- &wmgr_ctx, wmesh_ctx->dev->name);
|
|
- return -1;
|
|
- }
|
|
- }
|
|
-
|
|
- if (idx == -1) {
|
|
- return idx;
|
|
- }
|
|
-
|
|
- wmgr_ctx.mesh_ctx[idx] = wmesh_ctx;
|
|
- return idx;
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_ctx_remove()
|
|
- * Remove the mesh context from global table
|
|
- */
|
|
-static void nss_wifi_meshmgr_ctx_remove(struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx)
|
|
-{
|
|
- int32_t i;
|
|
-
|
|
- assert_spin_locked(&wmgr_ctx.ref_lock);
|
|
-
|
|
- for (i = 0; i < NSS_WIFI_MESH_MAX; i++) {
|
|
- if (wmgr_ctx.mesh_ctx[i] != wmesh_ctx) {
|
|
- continue;
|
|
- }
|
|
-
|
|
- wmgr_ctx.mesh_ctx[i] = NULL;
|
|
- return;
|
|
- }
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_cleanup()
|
|
- * Clean up the mesh context.
|
|
- */
|
|
-static void nss_wifi_meshmgr_cleanup(struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx)
|
|
-{
|
|
- int32_t encap_ifnum, decap_ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- nss_wifi_meshmgr_trace("%px: Mesh handle cleanup called for: %s\n", &wmgr_ctx, wmesh_ctx->dev->name);
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
- decap_ifnum = wmesh_ctx->decap_ifnum;
|
|
-
|
|
- /*
|
|
- * Unregister and dealloc decap DI.
|
|
- */
|
|
- nss_unregister_wifi_mesh_if(decap_ifnum);
|
|
- nss_status = nss_dynamic_interface_dealloc_node(decap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_OUTER);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Failed to dealloc decap: %d\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- /*
|
|
- * Unregister and dealloc encap DI.
|
|
- */
|
|
- nss_unregister_wifi_mesh_if(encap_ifnum);
|
|
- nss_status = nss_dynamic_interface_dealloc_node(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Failed to dealloc encap: %d\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- dev_put(wmesh_ctx->dev);
|
|
- kfree(wmesh_ctx);
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_ref_dec()
|
|
- * Find and decrement the reference counter.
|
|
- */
|
|
-static void nss_wifi_meshmgr_ref_dec(struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx)
|
|
-{
|
|
- if (atomic_dec_and_test(&wmesh_ctx->ref)) {
|
|
- nss_wifi_meshmgr_cleanup(wmesh_ctx);
|
|
- }
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_find_and_ref_inc()
|
|
- * Find and inreae the reference counter.
|
|
- */
|
|
-static struct nss_wifi_meshmgr_mesh_ctx *nss_wifi_meshmgr_find_and_ref_inc(nss_wifi_mesh_handle_t mesh_handle)
|
|
-{
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
-
|
|
- if ((mesh_handle < 0) || (mesh_handle >= NSS_WIFI_MESH_MAX)) {
|
|
- nss_wifi_meshmgr_warn("%px: Invalid mesh handle: %d\n", &wmgr_ctx, mesh_handle);
|
|
- return NULL;
|
|
- }
|
|
-
|
|
- spin_lock_bh(&wmgr_ctx.ref_lock);
|
|
- wmesh_ctx = wmgr_ctx.mesh_ctx[mesh_handle];
|
|
- if (wmesh_ctx && atomic_inc_and_test(&wmesh_ctx->ref)) {
|
|
- BUG_ON(1);
|
|
- }
|
|
- spin_unlock_bh(&wmgr_ctx.ref_lock);
|
|
- return wmesh_ctx;
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_remap_error()
|
|
- * Remap the error code.
|
|
- */
|
|
-static nss_wifi_meshmgr_status_t nss_wifi_meshmgr_remap_error(enum nss_wifi_mesh_error_types error)
|
|
-{
|
|
- switch (error) {
|
|
- case NSS_WIFI_MESH_ERROR_UNKNOWN_MSG:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_UNKNOWN_MSG;
|
|
- case NSS_WIFI_MESH_ERROR_TTL_CONFIG:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_TTL_CONFIG;
|
|
- case NSS_WIFI_MESH_ERROR_REFRESH_TIME_CONFIG:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_REFRESH_TIME_CONFIG;
|
|
- case NSS_WIFI_MESH_ERROR_MPP_LEARNING_MODE_CONFIG:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_MPP_LEARNING_MODE_CONFIG;
|
|
- case NSS_WIFI_MESH_ERROR_PATH_ADD_MAX_RADIO_CNT:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PATH_ADD_MAX_RADIO_CNT;
|
|
- case NSS_WIFI_MESH_ERROR_PATH_ADD_INVALID_INTERFACE_NUM:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PATH_ADD_INVALID_INTERFACE_NUM;
|
|
- case NSS_WIFI_MESH_ERROR_PATH_ADD_INTERFACE_NUM_NOT_FOUND:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PATH_ADD_INTERFACE_NUM_NOT_FOUND;
|
|
- case NSS_WIFI_MESH_ERROR_PATH_TABLE_FULL:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PATH_TABLE_FULL;
|
|
- case NSS_WIFI_MESH_ERROR_PATH_ALLOC_FAIL:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PATH_ALLOC_FAIL;
|
|
- case NSS_WIFI_MESH_ERROR_PATH_INSERT_FAIL:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PATH_INSERT_FAIL;
|
|
- case NSS_WIFI_MESH_ERROR_PATH_NOT_FOUND:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PATH_NOT_FOUND;
|
|
- case NSS_WIFI_MESH_ERROR_PATH_UNHASHED:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PATH_UNHASHED;
|
|
- case NSS_WIFI_MESH_ERROR_PATH_DELETE_FAIL:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PATH_DELETE_FAIL;
|
|
- case NSS_WIFI_MESH_ERROR_PROXY_PATH_NOT_FOUND:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PROXY_PATH_NOT_FOUND;
|
|
- case NSS_WIFI_MESH_ERROR_PROXY_PATH_UNHASHED:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PROXY_PATH_UNHASHED;
|
|
- case NSS_WIFI_MESH_ERROR_PROXY_PATH_DELETE_FAIL:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PROXY_PATH_DELETE_FAIL;
|
|
- case NSS_WIFI_MESH_ERROR_PROXY_PATH_EXISTS:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PROXY_PATH_EXISTS;
|
|
- case NSS_WIFI_MESH_ERROR_PROXY_PATH_ALLOC_FAIL:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PROXY_PATH_ALLOC_FAIL;
|
|
- case NSS_WIFI_MESH_ERROR_PROXY_PATH_INSERT_FAIL:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PROXY_PATH_INSERT_FAIL;
|
|
- case NSS_WIFI_MESH_ERROR_PROXY_PATH_TABLE_FULL:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PROXY_PATH_TABLE_FULL;
|
|
- case NSS_WIFI_MESH_ERROR_PB_ALLOC_FAIL:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_PB_ALLOC_FAIL;
|
|
- case NSS_WIFI_MESH_ERROR_ENQUEUE_TO_HOST_FAIL:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_ENQUEUE_TO_HOST_FAIL;
|
|
- case NSS_WIFI_MESH_ERROR_ENABLE_INTERFACE_FAIL:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_ENABLE_INTERFACE_FAIL;
|
|
- case NSS_WIFI_MESH_ERROR_DISABLE_INTERFACE_FAIL:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_DISABLE_INTERFACE_FAIL;
|
|
- case NSS_WIFI_MESH_ERROR_INVALID_EXCEPTION_NUM:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_INVALID_EXCEPTION_NUM;
|
|
- case NSS_WIFI_MESH_ERROR_ONESHOT_ALREADY_ATTACHED:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_ONESHOT_ALREADY_ATTACHED;
|
|
- case NSS_WIFI_MESH_ERROR_DUMMY_PATH_ADD_FAILED:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_DUMMY_PATH_ADD;
|
|
- case NSS_WIFI_MESH_ERROR_DUMMY_PROXY_PATH_ADD_FAILED:
|
|
- return NSS_WIFI_MESHMGR_FAILURE_DUMMY_PROXY_PATH_ADD;
|
|
- default:
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- };
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_tx_msg_cb()
|
|
- * Callback to handle the completion of NSS->HLOS messages.
|
|
- */
|
|
-static void nss_wifi_meshmgr_tx_msg_cb(void *app_data, struct nss_cmn_msg *ncm)
|
|
-{
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx = (struct nss_wifi_meshmgr_mesh_ctx *)app_data;
|
|
- uint32_t error_code = ncm->error;
|
|
-
|
|
- /*
|
|
- * FIXME: The wmesh_ctx can be invalid if the memory goes away with the caller being timedout.
|
|
- */
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_SUCCESS;
|
|
- if (ncm->response != NSS_CMN_RESPONSE_ACK) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi-Mesh error response %d error_code: %u\n", &wmgr_ctx, ncm->response, error_code);
|
|
- wmesh_ctx->response = nss_wifi_meshmgr_remap_error(error_code);
|
|
- }
|
|
-
|
|
- complete(&wmesh_ctx->complete);
|
|
-}
|
|
-
|
|
- /*
|
|
- * nss_wifi_meshmgr_tx_msg_sync()
|
|
- * Transmit a WiFi mesh message to NSS firmware synchronously.
|
|
- */
|
|
-static nss_wifi_meshmgr_status_t nss_wifi_meshmgr_tx_msg_sync(struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx, struct nss_wifi_mesh_msg *wmesh_msg)
|
|
-{
|
|
- nss_wifi_meshmgr_status_t status;
|
|
- int ret;
|
|
-
|
|
- down(&wmesh_ctx->sem);
|
|
- status = nss_wifi_meshmgr_tx_msg(wmesh_msg);
|
|
- if (status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh tx sync msg failed: %d\n", &wmgr_ctx, status);
|
|
- up(&wmesh_ctx->sem);
|
|
- return status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement.
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
- return status;
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_tx_buf()
|
|
- * Send packets to mesh I/F
|
|
- */
|
|
-nss_wifi_meshmgr_status_t nss_wifi_meshmgr_tx_buf(nss_wifi_mesh_handle_t mesh_handle, struct sk_buff *os_buf)
|
|
-{
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- int32_t encap_ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- nss_status = nss_wifi_mesh_tx_buf(wmgr_ctx.nss_ctx, os_buf, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_tx_buf);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_if_down()
|
|
- * Make the NSS interface down synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t nss_wifi_meshmgr_if_down(nss_wifi_mesh_handle_t mesh_handle)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t encap_ifnum, decap_ifnum;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
- decap_ifnum = wmesh_ctx->decap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the I/F encap and decap number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER) ||
|
|
- nss_wifi_meshmgr_verify_if_num(decap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_OUTER))) {
|
|
- nss_wifi_meshmgr_warn("%px: Interface verification failed\n", &wmgr_ctx);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the encap I/F down message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_IF_CLOSE,
|
|
- sizeof(struct nss_if_close), nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
-
|
|
- /*
|
|
- * Send the I/F down message to the encap I/F.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg_sync(wmesh_ctx, &wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh link encap I/F down failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the decap I/F down message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, decap_ifnum, NSS_IF_CLOSE,
|
|
- sizeof(struct nss_if_close), nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
-
|
|
- /*
|
|
- * Send the I/F down message to the decap I/F.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg_sync(wmesh_ctx, &wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh link decap I/F down failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_if_down);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_if_up()
|
|
- * Make the NSS interface up synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t nss_wifi_meshmgr_if_up(nss_wifi_mesh_handle_t mesh_handle)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t encap_ifnum, decap_ifnum;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
- decap_ifnum = wmesh_ctx->decap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the I/F encap and decap number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER) ||
|
|
- nss_wifi_meshmgr_verify_if_num(decap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_OUTER))) {
|
|
- nss_wifi_meshmgr_warn("%px: Interface verification failed\n", &wmgr_ctx);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the encap I/F up message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_IF_OPEN,
|
|
- sizeof(struct nss_if_open), nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
-
|
|
- /*
|
|
- * Send the I/F up message to the encap I/F.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg_sync(wmesh_ctx, &wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh link encap I/F up failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the I/F decap up message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, decap_ifnum, NSS_IF_OPEN,
|
|
- sizeof(struct nss_if_open), nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
-
|
|
- /*
|
|
- * Send the I/F up message to the decap interface.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg_sync(wmesh_ctx, &wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh link decap I/F up failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_if_up);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_dump_mesh_path()
|
|
- * Dump mesh path table request asynchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_dump_mesh_path(nss_wifi_mesh_handle_t mesh_handle, nss_wifi_mesh_msg_callback_t msg_cb, void *app_data)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t encap_ifnum;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the path dump request message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_WIFI_MESH_MSG_PATH_TABLE_DUMP,
|
|
- sizeof(struct nss_wifi_mesh_path_table_dump), msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the path dump request mesage to the NSS asynchronously.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg(&wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh dump mesh path failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_dump_mesh_path);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_dump_mesh_path_sync()
|
|
- * Dump mesh path table request synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_dump_mesh_path_sync(nss_wifi_mesh_handle_t mesh_handle)
|
|
-{
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t ret;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the path dump request mesage to the NSS synchronously.
|
|
- */
|
|
- down(&wmesh_ctx->sem);
|
|
- nss_status = nss_wifi_meshmgr_dump_mesh_path(mesh_handle, nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh path dump msg failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- nss_status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_dump_mesh_path_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_dump_mesh_proxy_path()
|
|
- * Dump mesh proxy path table request asynchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_dump_mesh_proxy_path(nss_wifi_mesh_handle_t mesh_handle, nss_wifi_mesh_msg_callback_t msg_cb, void *app_data)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t encap_ifnum;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the proxy path table message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_WIFI_MESH_MSG_PROXY_PATH_TABLE_DUMP,
|
|
- sizeof(struct nss_wifi_mesh_proxy_path_table_dump), msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the proxy path dump message to NSS asynchronously.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg(&wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh link vap proxy path dump failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_dump_mesh_proxy_path);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_dump_mesh_path_sync()
|
|
- * Dump mesh proxy path table request synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_dump_mesh_proxy_path_sync(nss_wifi_mesh_handle_t mesh_handle)
|
|
-{
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t ret;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the path dump request to the NSS synchronously.
|
|
- */
|
|
- down(&wmesh_ctx->sem);
|
|
- nss_status = nss_wifi_meshmgr_dump_mesh_proxy_path(mesh_handle, nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh proxy path dump msg failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- nss_status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_dump_mesh_proxy_path_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_assoc_link_vap()
|
|
- * Associate the link interface to the mesh I/F asynchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_assoc_link_vap(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_assoc_link_vap *wmalv,
|
|
- nss_wifi_mesh_msg_callback_t msg_cb, void *app_data)
|
|
-{
|
|
- struct nss_wifi_vdev_msg *wifivdevmsg;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- struct nss_wifi_vdev_set_next_hop_msg *next_hop_msg = NULL;
|
|
- int32_t decap_ifnum, link_ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- wifivdevmsg = kzalloc(sizeof(*wifivdevmsg), GFP_ATOMIC);
|
|
- if (!wifivdevmsg) {
|
|
- nss_wifi_meshmgr_warn("%px: Failed to allocate message memmory", &wmgr_ctx);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- decap_ifnum = wmesh_ctx->decap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the decap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(decap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_OUTER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, decap_ifnum);
|
|
- kfree(wifivdevmsg);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
-
|
|
- link_ifnum = wmalv->link_vap_id;
|
|
-
|
|
- /*
|
|
- * Verify the link VAP I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(link_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_VAP))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, link_ifnum);
|
|
- kfree(wifivdevmsg);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
-
|
|
- next_hop_msg = &wifivdevmsg->msg.next_hop;
|
|
- next_hop_msg->ifnumber = decap_ifnum;
|
|
- nss_cmn_msg_init(&wifivdevmsg->cm, link_ifnum, NSS_WIFI_VDEV_SET_NEXT_HOP, sizeof(*next_hop_msg),
|
|
- msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the link vap mesage to the NSS synchronously.
|
|
- */
|
|
- nss_status = nss_wifi_vdev_tx_msg(wmgr_ctx.nss_ctx, wifivdevmsg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh link vap association failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- kfree(wifivdevmsg);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_assoc_link_vap);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_assoc_link_vap_sync()
|
|
- * Associate the link VAP to the mesh I/F synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_assoc_link_vap_sync(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_assoc_link_vap *wmalv)
|
|
-{
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t ret;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the link vap mesage to the NSS synchronously.
|
|
- */
|
|
- down(&wmesh_ctx->sem);
|
|
- nss_status = nss_wifi_meshmgr_assoc_link_vap(mesh_handle, wmalv, nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh link vap association failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- nss_status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_assoc_link_vap_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_config_update()
|
|
- * Update mesh configuration message asynchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_config_update(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_config_msg *wmcum,
|
|
- nss_wifi_mesh_msg_callback_t msg_cb, void *app_data)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- struct nss_wifi_mesh_config_msg *nwmcum;
|
|
- int32_t encap_ifnum, decap_ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
- decap_ifnum = wmesh_ctx->decap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Verify the decap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(decap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_OUTER))) {
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, decap_ifnum);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the mesh configuration messsage.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nwmcum = &wmesh_msg.msg.mesh_config;
|
|
- memcpy(nwmcum, wmcum, sizeof(*nwmcum));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_WIFI_MESH_MSG_INTERFACE_CONFIGURE,
|
|
- sizeof(*nwmcum), msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the configuration message to encap I/F.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg(&wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh configuration message failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the mesh configuration messsage.
|
|
- */
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, decap_ifnum, NSS_WIFI_MESH_MSG_INTERFACE_CONFIGURE,
|
|
- sizeof(*nwmcum), msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the configuration message decap I/F.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg(&wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh configuration message failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_config_update);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_config_update_sync()
|
|
- * Update mesh configuration message synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_config_update_sync(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_config_msg *wmcum)
|
|
-{
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t ret;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the message to NSS synchronously.
|
|
- */
|
|
- down(&wmesh_ctx->sem);
|
|
- nss_status = nss_wifi_meshmgr_mesh_config_update(mesh_handle, wmcum, nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh proxy path update failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- nss_status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_config_update_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_proxy_path_delete()
|
|
- * Delete the mesh proxy path asynchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_proxy_path_delete(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_proxy_path_del_msg *wmppdm,
|
|
- nss_wifi_mesh_msg_callback_t msg_cb, void *app_data)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- struct nss_wifi_mesh_proxy_path_del_msg *nwmppdm;
|
|
- int32_t encap_ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nwmppdm = &wmesh_msg.msg.proxy_del_msg;
|
|
- memcpy(nwmppdm, wmppdm, sizeof(*nwmppdm));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_WIFI_MESH_MSG_PROXY_PATH_DELETE,
|
|
- sizeof(*nwmppdm), msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the message to NSS asynchronously.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg(&wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh proxy path delete failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_proxy_path_delete);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_proxy_path_delete_sync()
|
|
- * Delete the mesh proxy path synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_proxy_path_delete_sync(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_proxy_path_del_msg *wmppdm)
|
|
-{
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t ret;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the message to NSS synchronously.
|
|
- */
|
|
- down(&wmesh_ctx->sem);
|
|
- nss_status = nss_wifi_meshmgr_mesh_proxy_path_delete(mesh_handle, wmppdm, nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh proxy path delete failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- nss_status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_proxy_path_delete_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_proxy_path_update()
|
|
- * Mesh prpxy path update message asynchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_proxy_path_update(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_proxy_path_update_msg *wmppum,
|
|
- nss_wifi_mesh_msg_callback_t msg_cb, void *app_data)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- struct nss_wifi_mesh_proxy_path_update_msg *nwmppum;
|
|
- int32_t encap_ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nwmppum = &wmesh_msg.msg.proxy_update_msg;
|
|
- memcpy(nwmppum, wmppum, sizeof(*nwmppum));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_WIFI_MESH_MSG_PROXY_PATH_UPDATE,
|
|
- sizeof(*nwmppum), msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the message to NSS asynchronously
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg(&wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh proxy path update failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_proxy_path_update);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_proxy_path_update_sync()
|
|
- * Send proxy update message synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_proxy_path_update_sync(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_proxy_path_update_msg *wmppum)
|
|
-{
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t ret;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the message to NSS synchronously.
|
|
- */
|
|
- down(&wmesh_ctx->sem);
|
|
- nss_status = nss_wifi_meshmgr_mesh_proxy_path_update(mesh_handle, wmppum, nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh proxy path update failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- nss_status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_proxy_path_update_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_proxy_path_add()
|
|
- * Send mesh proxy add message asynchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_proxy_path_add(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_proxy_path_add_msg *wmppam,
|
|
- nss_wifi_mesh_msg_callback_t msg_cb, void *app_data)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- struct nss_wifi_mesh_proxy_path_add_msg *nwmppam;
|
|
- int32_t encap_ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the message
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nwmppam = &wmesh_msg.msg.proxy_add_msg;
|
|
- memcpy(nwmppam, wmppam, sizeof(*nwmppam));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_WIFI_MESH_MSG_PROXY_PATH_ADD,
|
|
- sizeof(*nwmppam), msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the message to NSS asynchronously.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg(&wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh proxy path add failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_proxy_path_add);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_proxy_path_add_sync()
|
|
- * Send mesh proxy add message synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_proxy_path_add_sync(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_proxy_path_add_msg *wmppam)
|
|
-{
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- int32_t ret;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the message to NSS synchronously.
|
|
- */
|
|
- down(&wmesh_ctx->sem);
|
|
- nss_status = nss_wifi_meshmgr_mesh_proxy_path_add(mesh_handle, wmppam, nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh proxy path add failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- nss_status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_proxy_path_add_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_path_delete()
|
|
- * Send the mesh path delete message asynchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_path_delete(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_mpath_del_msg *wmpdm,
|
|
- nss_wifi_mesh_msg_callback_t msg_cb, void *app_data)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- struct nss_wifi_mesh_mpath_del_msg *nwmpdm;
|
|
- int32_t encap_ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nwmpdm = &wmesh_msg.msg.mpath_del;
|
|
- memcpy(nwmpdm, wmpdm, sizeof(*nwmpdm));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_WIFI_MESH_MSG_MPATH_DELETE,
|
|
- sizeof(*nwmpdm), msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the message to NSS asynchronously.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg(&wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh path delete failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_path_delete);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_path_delete_sync()
|
|
- * Send the mesh path delete message synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_path_delete_sync(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_mpath_del_msg *wmpdm)
|
|
-{
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- int32_t ret;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the message to NSS synchronously.
|
|
- */
|
|
- down(&wmesh_ctx->sem);
|
|
- nss_status = nss_wifi_meshmgr_mesh_path_delete(mesh_handle, wmpdm, nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh path delete failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- nss_status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_path_delete_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_path_add()
|
|
- * Mesh path add message asynchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_path_add(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_mpath_add_msg *wmpam,
|
|
- nss_wifi_mesh_msg_callback_t msg_cb, void *app_data)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_mesh_mpath_add_msg *nwmpam;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- int32_t encap_ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nwmpam = &wmesh_msg.msg.mpath_add;
|
|
- memcpy(nwmpam, wmpam, sizeof(*nwmpam));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_WIFI_MESH_MSG_MPATH_ADD,
|
|
- sizeof(*nwmpam), msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the message to NSS asynchronously.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg(&wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh path addition failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_path_add);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_path_add_sync()
|
|
- * Mesh path add message synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_path_add_sync(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_mpath_add_msg *wmpam)
|
|
-{
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- int32_t ret;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the message to NSS synchronously.
|
|
- */
|
|
- down(&wmesh_ctx->sem);
|
|
- nss_status = nss_wifi_meshmgr_mesh_path_add(mesh_handle, wmpam, nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh path addition failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- nss_status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_path_add_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mpath_update()
|
|
- * Send mesh path update message asynchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_path_update(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_mpath_update_msg *wmpum,
|
|
- nss_wifi_mesh_msg_callback_t msg_cb, void *app_data)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_mesh_mpath_update_msg *nwmpum;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- int32_t encap_ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the mesh path update message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nwmpum = &wmesh_msg.msg.mpath_update;
|
|
- memcpy(nwmpum, wmpum, sizeof(*nwmpum));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_WIFI_MESH_MSG_MPATH_UPDATE,
|
|
- sizeof(*nwmpum), msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the message to NSS asynchronously.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg(&wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh MPath update failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_path_update);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mpath_update_sync()
|
|
- * Send mesh path update message sychronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_path_update_sync(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_mpath_update_msg *wmpum)
|
|
-{
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t ret;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the message to NSS synchronously.
|
|
- */
|
|
- down(&wmesh_ctx->sem);
|
|
- nss_status = nss_wifi_meshmgr_mesh_path_update(mesh_handle, wmpum, nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh MPath update failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- nss_status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_path_update_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_path_exception()
|
|
- * Mesh path exception msg asynchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_path_exception(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_exception_flag_msg *wmefm,
|
|
- nss_wifi_mesh_msg_callback_t msg_cb, void *app_data)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_mesh_exception_flag_msg *nwmefm;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- int32_t encap_ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nwmefm = &wmesh_msg.msg.exception_msg;
|
|
- memcpy(nwmefm, wmefm, sizeof(*nwmefm));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_WIFI_MESH_MSG_EXCEPTION_FLAG,
|
|
- sizeof(*nwmefm), msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the message to NSS asynchronously.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg(&wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh path exception message failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_path_exception);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_mesh_path_exception_sync()
|
|
- * Send mesh path exception message sychronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_mesh_path_exception_sync(nss_wifi_mesh_handle_t mesh_handle,struct nss_wifi_mesh_exception_flag_msg *wmefm)
|
|
-{
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t ret;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the message to NSS synchronously.
|
|
- */
|
|
- down(&wmesh_ctx->sem);
|
|
- nss_status = nss_wifi_meshmgr_mesh_path_exception(mesh_handle, wmefm, nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh path exception message failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- nss_status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_mesh_path_exception_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_config_mesh_exception()
|
|
- * Configure mesh exception asynchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_config_mesh_exception(nss_wifi_mesh_handle_t mesh_handle, struct nss_wifi_mesh_rate_limit_config *wmrlc,
|
|
- nss_wifi_mesh_msg_callback_t msg_cb, void *app_data)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_mesh_rate_limit_config *nwmrlc;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
- int32_t encap_ifnum, decap_ifnum, ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- decap_ifnum = wmesh_ctx->decap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the decap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(decap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_OUTER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, decap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- switch(wmrlc->exception_num) {
|
|
- case NSS_WIFI_MESH_DS_MESH_PATH_NOT_FOUND:
|
|
- ifnum = encap_ifnum;
|
|
- break;
|
|
-
|
|
- case NSS_WIFI_MESH_US_MESH_PROXY_NOT_FOUND:
|
|
- ifnum = decap_ifnum;
|
|
- break;
|
|
-
|
|
- case NSS_WIFI_MESH_US_MESH_PATH_NOT_FOUND:
|
|
- ifnum = decap_ifnum;
|
|
- break;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nwmrlc = &wmesh_msg.msg.exc_cfg;
|
|
- memcpy(nwmrlc, wmrlc, sizeof(*nwmrlc));
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, ifnum, NSS_WIFI_MESH_CONFIG_EXCEPTION,
|
|
- sizeof(*nwmrlc), msg_cb, app_data);
|
|
-
|
|
- /*
|
|
- * Send the message to NSS asynchronously.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg(&wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh config exception message failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_config_mesh_exception);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_config_mesh_exception_sync()
|
|
- * Configure mesh exception synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t
|
|
-nss_wifi_meshmgr_config_mesh_exception_sync(nss_wifi_mesh_handle_t mesh_handle,struct nss_wifi_mesh_rate_limit_config *wmrlc)
|
|
-{
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- int32_t ret;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_NULL_MESH_CTX;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the message to NSS synchronously.
|
|
- */
|
|
- down(&wmesh_ctx->sem);
|
|
- nss_status = nss_wifi_meshmgr_config_mesh_exception(mesh_handle, wmrlc, nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh config exception message failed: %d.\n", &wmgr_ctx, nss_status);
|
|
- up(&wmesh_ctx->sem);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Wait for the acknowledgement
|
|
- */
|
|
- ret = wait_for_completion_timeout(&wmesh_ctx->complete, msecs_to_jiffies(NSS_WIFI_MESH_TX_TIMEOUT));
|
|
- if (!ret) {
|
|
- nss_wifi_meshmgr_warn("%px: WiFi mesh msg tx failed due to timeout\n", &wmgr_ctx);
|
|
- wmesh_ctx->response = NSS_WIFI_MESHMGR_FAILURE_SYNC_TIMEOUT;
|
|
- }
|
|
-
|
|
- nss_status = wmesh_ctx->response;
|
|
- up(&wmesh_ctx->sem);
|
|
-
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_config_mesh_exception_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_if_destroy_sync()
|
|
- * Function to unregister and destroy dynamic interfaces synchronously.
|
|
- */
|
|
-nss_wifi_meshmgr_status_t nss_wifi_meshmgr_if_destroy_sync(nss_wifi_mesh_handle_t mesh_handle)
|
|
-{
|
|
- int32_t encap_ifnum, decap_ifnum;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
-
|
|
- wmesh_ctx = nss_wifi_meshmgr_find_and_ref_inc(mesh_handle);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Mesh context is null\n", &wmgr_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE_BAD_PARAM;
|
|
- }
|
|
-
|
|
- encap_ifnum = wmesh_ctx->encap_ifnum;
|
|
- decap_ifnum = wmesh_ctx->decap_ifnum;
|
|
-
|
|
- /*
|
|
- * Verify the encap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, encap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Verify the decap I/F number against it types.
|
|
- */
|
|
- if (!(nss_wifi_meshmgr_verify_if_num(decap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_OUTER))) {
|
|
- nss_wifi_meshmgr_warn("%px: I/F num: 0x%x verification failed\n", &wmgr_ctx, decap_ifnum);
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return NSS_WIFI_MESHMGR_FAILURE;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Send the I/F down message to NSS.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_if_down(mesh_handle);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Sending mesh I/F down to NSS failed: %d\n", &wmgr_ctx, nss_status);
|
|
- }
|
|
-
|
|
- /*
|
|
- * Remove mesh context from the table.
|
|
- */
|
|
- spin_lock_bh(&wmgr_ctx.ref_lock);
|
|
- nss_wifi_meshmgr_ctx_remove(wmesh_ctx);
|
|
- wmgr_ctx.mesh_count--;
|
|
- spin_unlock_bh(&wmgr_ctx.ref_lock);
|
|
-
|
|
- /*
|
|
- * Release the reference taken during alloc.
|
|
- */
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
-
|
|
- /*
|
|
- * Release the reference for the find taken at the beginning of the function.
|
|
- */
|
|
- nss_wifi_meshmgr_ref_dec(wmesh_ctx);
|
|
- return nss_status;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_if_destroy_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_if_create_sync()
|
|
- * Create and register dynamic interface synchronously.
|
|
- *
|
|
- * Note: Synchronous create message, callbacks are used for driver registration not message handling.
|
|
- */
|
|
-nss_wifi_mesh_handle_t nss_wifi_meshmgr_if_create_sync(struct net_device *dev, struct nss_wifi_mesh_config_msg *wmcm,
|
|
- nss_wifi_mesh_data_callback_t data_cb,
|
|
- nss_wifi_mesh_ext_data_callback_t ext_data_cb,
|
|
- nss_wifi_mesh_msg_callback_t event_cb)
|
|
-{
|
|
- struct nss_wifi_mesh_msg wmesh_msg;
|
|
- struct nss_wifi_mesh_config_msg *nwmcm;
|
|
- int32_t encap_ifnum, decap_ifnum;
|
|
- uint32_t features = 0;
|
|
- nss_wifi_mesh_handle_t mesh_handle;
|
|
- nss_wifi_meshmgr_status_t nss_status;
|
|
- struct nss_wifi_meshmgr_mesh_ctx *wmesh_ctx;
|
|
-
|
|
- spin_lock_bh(&wmgr_ctx.ref_lock);
|
|
- if (wmgr_ctx.mesh_count == NSS_WIFI_MESH_MAX) {
|
|
- nss_wifi_meshmgr_warn("%px: Reached maxed number of mesh interface\n", dev);
|
|
- spin_unlock_bh(&wmgr_ctx.ref_lock);
|
|
- return -1;
|
|
- }
|
|
-
|
|
- wmgr_ctx.mesh_count++;
|
|
- spin_unlock_bh(&wmgr_ctx.ref_lock);
|
|
-
|
|
- dev_hold(dev);
|
|
- wmesh_ctx = kzalloc(sizeof(*wmesh_ctx), GFP_ATOMIC);
|
|
- if (!wmesh_ctx) {
|
|
- nss_wifi_meshmgr_warn("%px: Failed to allocate memory for mesh context\n", dev);
|
|
- goto ctx_alloc_fail;
|
|
- }
|
|
-
|
|
- wmesh_ctx->dev = dev;
|
|
- sema_init(&wmesh_ctx->sem, 1);
|
|
- init_completion(&wmesh_ctx->complete);
|
|
-
|
|
- /*
|
|
- * Alloc the encap dynamic interface node.
|
|
- */
|
|
- encap_ifnum = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER);
|
|
- if (encap_ifnum < 0) {
|
|
- nss_wifi_meshmgr_warn("%px: Encap allocation failed.\n", dev);
|
|
- goto encap_alloc_fail;
|
|
- }
|
|
-
|
|
- if (nss_register_wifi_mesh_if(encap_ifnum, data_cb, ext_data_cb, event_cb,
|
|
- NSS_WIFI_MESH_DP_INNER, dev, features) != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Encap registration failed.\n", dev);
|
|
- goto encap_reg_fail;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Allocate and register decap interface.
|
|
- */
|
|
- decap_ifnum = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_OUTER);
|
|
- if (decap_ifnum < 0) {
|
|
- nss_wifi_meshmgr_warn("%px: Decap allocation failed.\n", dev);
|
|
- goto decap_alloc_fail;
|
|
- }
|
|
-
|
|
-
|
|
- if (nss_register_wifi_mesh_if(decap_ifnum, data_cb, ext_data_cb, event_cb,
|
|
- NSS_WIFI_MESH_DP_OUTER, dev, features) != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Decap registration failed.\n", dev);
|
|
- goto decap_reg_fail;
|
|
- }
|
|
-
|
|
- wmesh_ctx->encap_ifnum = encap_ifnum;
|
|
- wmesh_ctx->decap_ifnum = decap_ifnum;
|
|
-
|
|
- nss_wifi_meshmgr_trace("%px: Successfully registered encap and decap iface for Mesh\n", dev);
|
|
-
|
|
- /*
|
|
- * Initialize the encap configuration message.
|
|
- */
|
|
- memset(&wmesh_msg, 0, sizeof(struct nss_wifi_mesh_msg));
|
|
- nwmcm = &wmesh_msg.msg.mesh_config;
|
|
- nwmcm->ttl = wmcm->ttl;
|
|
- nwmcm->mesh_path_refresh_time = wmcm->mesh_path_refresh_time;
|
|
- nwmcm->mpp_learning_mode = wmcm->mpp_learning_mode;
|
|
- nwmcm->config_flags = wmcm->config_flags | NSS_WIFI_MESH_CONFIG_FLAG_SIBLING_IF_NUM_VALID;
|
|
- nwmcm->sibling_ifnum = decap_ifnum;
|
|
-
|
|
- ether_addr_copy(nwmcm->local_mac_addr, wmcm->local_mac_addr);
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, encap_ifnum, NSS_WIFI_MESH_MSG_INTERFACE_CONFIGURE,
|
|
- sizeof(*nwmcm), nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
-
|
|
- /*
|
|
- * Send the encap configuration message.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg_sync(wmesh_ctx, &wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Encap configuration message failed: %d.\n", dev, nss_status);
|
|
- goto config_failed;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Initialize the decap configuration message.
|
|
- */
|
|
- nwmcm->sibling_ifnum = encap_ifnum;
|
|
- nwmcm->block_mesh_forwarding = wmcm->block_mesh_forwarding;
|
|
- nss_wifi_mesh_msg_init(&wmesh_msg, decap_ifnum, NSS_WIFI_MESH_MSG_INTERFACE_CONFIGURE,
|
|
- sizeof(*nwmcm), nss_wifi_meshmgr_tx_msg_cb, wmesh_ctx);
|
|
-
|
|
- /*
|
|
- * Send the decap configuration message.
|
|
- */
|
|
- nss_status = nss_wifi_meshmgr_tx_msg_sync(wmesh_ctx, &wmesh_msg);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Decap configuration message failed: %d.\n", dev, nss_status);
|
|
- goto config_failed;
|
|
- }
|
|
-
|
|
- /*
|
|
- * Take the self reference on the mesh context.
|
|
- */
|
|
- atomic_set(&wmesh_ctx->ref, 1);
|
|
-
|
|
- /*
|
|
- * Add the Mesh context to the mesh manager's list.
|
|
- */
|
|
- spin_lock_bh(&wmgr_ctx.ref_lock);
|
|
- mesh_handle = nss_wifi_meshmgr_ctx_insert(wmesh_ctx);
|
|
- if (mesh_handle < 0) {
|
|
- spin_unlock_bh(&wmgr_ctx.ref_lock);
|
|
- nss_wifi_meshmgr_warn("%px: Insertion for mesh context failed", &wmgr_ctx);
|
|
- goto config_failed;
|
|
- }
|
|
-
|
|
- spin_unlock_bh(&wmgr_ctx.ref_lock);
|
|
-
|
|
- nss_wifi_meshmgr_trace("%px: WiFi Mesh interface count:%d.\n", dev, wmgr_ctx.mesh_count);
|
|
- return mesh_handle;
|
|
-
|
|
-config_failed:
|
|
- nss_unregister_wifi_mesh_if(decap_ifnum);
|
|
-decap_reg_fail:
|
|
- nss_dynamic_interface_dealloc_node(decap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_OUTER);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Decap interface dealloc failed: %d\n", dev, nss_status);
|
|
- }
|
|
-decap_alloc_fail:
|
|
- nss_unregister_wifi_mesh_if(encap_ifnum);
|
|
-encap_reg_fail:
|
|
- nss_dynamic_interface_dealloc_node(encap_ifnum, NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER);
|
|
- if (nss_status != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px: Encap interface dealloc failed: %d\n", dev, nss_status);
|
|
- }
|
|
-encap_alloc_fail:
|
|
- kfree(wmesh_ctx);
|
|
-ctx_alloc_fail:
|
|
- spin_lock_bh(&wmgr_ctx.ref_lock);
|
|
- wmgr_ctx.mesh_count--;
|
|
- spin_unlock_bh(&wmgr_ctx.ref_lock);
|
|
- dev_put(dev);
|
|
- return -1;
|
|
-}
|
|
-EXPORT_SYMBOL(nss_wifi_meshmgr_if_create_sync);
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_exit_module()
|
|
- * WiFi-Mesh module exit function
|
|
- */
|
|
-static void __exit nss_wifi_meshmgr_exit_module(void)
|
|
-{
|
|
- int32_t i;
|
|
-
|
|
- /*
|
|
- * Check if there are any mesh I/F. Delete all the mesh I/F from NSS FW and free.
|
|
- */
|
|
- for (i = 0; i < NSS_WIFI_MESH_MAX; i++) {
|
|
- if (nss_wifi_meshmgr_if_destroy_sync(i) != NSS_WIFI_MESHMGR_SUCCESS) {
|
|
- nss_wifi_meshmgr_warn("%px Destroy failed or context does not exist", &wmgr_ctx);
|
|
- }
|
|
- }
|
|
- nss_wifi_meshmgr_info("Module %s unloaded\n", NSS_CLIENT_BUILD_ID);
|
|
-}
|
|
-
|
|
-/*
|
|
- * nss_wifi_meshmgr_init_module()
|
|
- * Wi-Fi mesh manager module init function
|
|
- */
|
|
-static int __init nss_wifi_meshmgr_init_module(void)
|
|
-{
|
|
- struct nss_ctx_instance *nss_ctx;
|
|
- int32_t idx;
|
|
-
|
|
-#ifdef CONFIG_OF
|
|
- /*
|
|
- * If the node is not compatible, don't do anything.
|
|
- */
|
|
- if (!of_find_node_by_name(NULL, "nss-common")) {
|
|
- nss_wifi_meshmgr_warn("NSS common not found.\n");
|
|
- return -1;
|
|
- }
|
|
-#endif
|
|
-
|
|
- nss_ctx = nss_wifi_mesh_get_context();
|
|
- if (!nss_ctx) {
|
|
- nss_wifi_meshmgr_warn("NSS SoC context is NULL.\n");
|
|
- return -1;
|
|
- }
|
|
-
|
|
- wmgr_ctx.nss_ctx = nss_ctx;
|
|
- for (idx = 0; idx < NSS_WIFI_MESH_MAX; idx++) {
|
|
- wmgr_ctx.mesh_ctx[idx] = NULL;
|
|
- }
|
|
-
|
|
- wmgr_ctx.mesh_count = 0;
|
|
- spin_lock_init(&wmgr_ctx.ref_lock);
|
|
-
|
|
- nss_wifi_meshmgr_info("Module %s loaded\n", NSS_CLIENT_BUILD_ID);
|
|
- return 0;
|
|
-}
|
|
-
|
|
-module_init(nss_wifi_meshmgr_init_module);
|
|
-module_exit(nss_wifi_meshmgr_exit_module);
|
|
-
|
|
-MODULE_LICENSE("Dual BSD/GPL");
|
|
-MODULE_DESCRIPTION("NSS WiFi-Mesh manager");
|