openwrt_deco_e4r/target/linux/generic/patches-3.3/998-Add-support-to-refresh-bridge-FDB-entries-for-NSS-ac.patch

102 lines
3.3 KiB
Diff

From 2f562a5434d7e34b2392b2e620bacafb653998b6 Mon Sep 17 00:00:00 2001
From: "Kiran Kumar C.S.K" <kkumarcs@codeaurora.org>
Date: Mon, 25 Nov 2013 17:32:43 +0530
Subject: [PATCH] Add support to refresh bridge FDB entries for NSS accelerated
flows
CRs Fixed: 582515
Summary: This commit adds two APIs for the following, to be used by NSS connection managers
1.) To update bridge statistics at host for bridge packets bring forwarded by NSS fast path
2.) To refresh MAC entries in bridge table for bridge packets bring forwarded by NSS fast path
Change-Id: I8d5a6a31ee70d88499206f6e3b1afd610adec70a
Signed-off-by: Kiran Kumar C.S.K <kkumarcs@codeaurora.org>
---
include/linux/if_bridge.h | 2 ++
net/bridge/br_fdb.c | 20 ++++++++++++++++++++
net/bridge/br_if.c | 25 +++++++++++++++++++++++++
3 files changed, 47 insertions(+)
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index b35d660..0d8ba92 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -103,6 +103,8 @@ struct __fdb_entry {
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
extern struct net_device *br_port_dev_get(struct net_device *dev, unsigned char *addr);
+extern void br_refresh_fdb_entry(struct net_device *dev, const char *addr);
+extern void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats);
typedef int br_should_route_hook_t(struct sk_buff *skb);
extern br_should_route_hook_t __rcu *br_should_route_hook;
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index a7aa832..561ecf8 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -454,6 +454,26 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
}
}
+/* Refresh FDB entries for bridge packets being forwarded by offload engines */
+void br_refresh_fdb_entry(struct net_device *dev, const char *addr)
+{
+ struct net_bridge_port *p = br_port_get_rcu(dev);
+
+ if (!p || p->state == BR_STATE_DISABLED)
+ return;
+
+ if (!is_valid_ether_addr(addr)) {
+ pr_info("bridge: Attempt to refresh with invalid ether address\n");
+ return;
+ }
+
+ rcu_read_lock();
+ br_fdb_update(p->br, p, addr);
+ rcu_read_unlock();
+}
+
+EXPORT_SYMBOL_GPL(br_refresh_fdb_entry);
+
static int fdb_to_nud(const struct net_bridge_fdb_entry *fdb)
{
if (fdb->is_local)
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 33d8fe5..509e89e 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -496,3 +496,28 @@ struct net_device *br_port_dev_get(struct net_device *dev, unsigned char *addr)
return pdev;
}
EXPORT_SYMBOL_GPL(br_port_dev_get);
+
+/* Update bridge statistics for bridge packets processed by offload engines */
+void br_dev_update_stats(struct net_device *dev, struct rtnl_link_stats64 *nlstats)
+{
+ struct net_bridge *br;
+ struct br_cpu_netstats *stats;
+
+ /*
+ * Is this a bridge?
+ */
+ if (!(dev->priv_flags & IFF_EBRIDGE)) {
+ return;
+ }
+
+ br = netdev_priv(dev);
+ stats = per_cpu_ptr(br->stats, 0);
+
+ u64_stats_update_begin(&stats->syncp);
+ stats->rx_packets += nlstats->rx_packets;
+ stats->rx_bytes += nlstats->rx_bytes;
+ stats->tx_packets += nlstats->tx_packets;
+ stats->tx_bytes += nlstats->tx_bytes;
+ u64_stats_update_end(&stats->syncp);
+}
+EXPORT_SYMBOL_GPL(br_dev_update_stats);
--
1.8.4.2