mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 23:12:32 +00:00
111 lines
3.2 KiB
Diff
111 lines
3.2 KiB
Diff
|
From d16102cad769f430144ca8094d928762b445e9b0 Mon Sep 17 00:00:00 2001
|
||
|
From: Robert Marko <robimarko@gmail.com>
|
||
|
Date: Fri, 18 Mar 2022 22:02:01 +0100
|
||
|
Subject: [PATCH] switchdev: fix FDB roaming
|
||
|
|
||
|
Try and solve the roaming issue by trying to replicate what NSS bridge
|
||
|
module is doing, but by utilizing switchdev FDB notifiers instead of
|
||
|
adding new notifiers to the bridge code.
|
||
|
|
||
|
We register a new non-blocking switchdev notifier and simply wait for
|
||
|
notification, and then process the SWITCHDEV_FDB_DEL_TO_DEVICE
|
||
|
notifications.
|
||
|
|
||
|
Those tell us that a certain FDB entry should be removed, then a VSI ID
|
||
|
is fetched for the physical PPE port and using that VSI ID and the
|
||
|
notification provided MAC adress existing FDB entry gets removed.
|
||
|
|
||
|
Signed-off-by: Robert Marko <robimarko@gmail.com>
|
||
|
---
|
||
|
nss_dp_switchdev.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
1 file changed, 61 insertions(+)
|
||
|
|
||
|
--- a/nss_dp_switchdev.c
|
||
|
+++ b/nss_dp_switchdev.c
|
||
|
@@ -24,6 +24,8 @@
|
||
|
#include "nss_dp_dev.h"
|
||
|
#include "fal/fal_stp.h"
|
||
|
#include "fal/fal_ctrlpkt.h"
|
||
|
+#include "fal/fal_fdb.h"
|
||
|
+#include "ref/ref_vsi.h"
|
||
|
|
||
|
#define NSS_DP_SWITCH_ID 0
|
||
|
#define NSS_DP_SW_ETHTYPE_PID 0 /* PPE ethtype profile ID for slow protocols */
|
||
|
@@ -348,10 +350,64 @@ static int nss_dp_switchdev_event(struct
|
||
|
return NOTIFY_DONE;
|
||
|
}
|
||
|
|
||
|
+static int nss_dp_switchdev_fdb_del_event(struct net_device *netdev,
|
||
|
+ struct switchdev_notifier_fdb_info *fdb_info)
|
||
|
+{
|
||
|
+ struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev);
|
||
|
+ fal_fdb_entry_t entry;
|
||
|
+ a_uint32_t vsi_id;
|
||
|
+ sw_error_t rv;
|
||
|
+
|
||
|
+ netdev_dbg(netdev, "FDB DEL %pM port %d\n", fdb_info->addr, dp_priv->macid);
|
||
|
+
|
||
|
+ rv = ppe_port_vsi_get(NSS_DP_SWITCH_ID, dp_priv->macid, &vsi_id);
|
||
|
+ if (rv) {
|
||
|
+ netdev_err(netdev, "cannot get VSI ID for port %d\n", dp_priv->macid);
|
||
|
+ return notifier_from_errno(rv);
|
||
|
+ }
|
||
|
+
|
||
|
+ memset(&entry, 0, sizeof(entry));
|
||
|
+ memcpy(&entry.addr, fdb_info->addr, ETH_ALEN);
|
||
|
+ entry.fid = vsi_id;
|
||
|
+
|
||
|
+ rv = fal_fdb_entry_del_bymac(NSS_DP_SWITCH_ID, &entry);
|
||
|
+ if (rv) {
|
||
|
+ netdev_err(netdev, "FDB entry delete failed with MAC %pM and fid %d\n",
|
||
|
+ &entry.addr, entry.fid);
|
||
|
+ return notifier_from_errno(rv);
|
||
|
+ }
|
||
|
+
|
||
|
+ return notifier_from_errno(rv);
|
||
|
+}
|
||
|
+
|
||
|
+static int nss_dp_fdb_switchdev_event(struct notifier_block *nb,
|
||
|
+ unsigned long event, void *ptr)
|
||
|
+{
|
||
|
+ struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
|
||
|
+
|
||
|
+ /*
|
||
|
+ * Handle switchdev event only for physical devices
|
||
|
+ */
|
||
|
+ if (!nss_dp_is_phy_dev(dev)) {
|
||
|
+ return NOTIFY_DONE;
|
||
|
+ }
|
||
|
+
|
||
|
+ switch (event) {
|
||
|
+ case SWITCHDEV_FDB_DEL_TO_DEVICE:
|
||
|
+ return nss_dp_switchdev_fdb_del_event(dev, ptr);
|
||
|
+ }
|
||
|
+
|
||
|
+ return NOTIFY_DONE;
|
||
|
+}
|
||
|
+
|
||
|
static struct notifier_block nss_dp_switchdev_notifier = {
|
||
|
.notifier_call = nss_dp_switchdev_event,
|
||
|
};
|
||
|
|
||
|
+static struct notifier_block nss_dp_switchdev_fdb_notifier = {
|
||
|
+ .notifier_call = nss_dp_fdb_switchdev_event,
|
||
|
+};
|
||
|
+
|
||
|
static bool switch_init_done;
|
||
|
|
||
|
/*
|
||
|
@@ -366,6 +422,11 @@ void nss_dp_switchdev_setup(struct net_d
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
+ err = register_switchdev_notifier(&nss_dp_switchdev_fdb_notifier);
|
||
|
+ if (err) {
|
||
|
+ netdev_dbg(dev, "%px:Failed to register switchdev FDB notifier\n", dev);
|
||
|
+ }
|
||
|
+
|
||
|
err = register_switchdev_blocking_notifier(&nss_dp_switchdev_notifier);
|
||
|
if (err) {
|
||
|
netdev_dbg(dev, "%px:Failed to register switchdev notifier\n", dev);
|