bridge: Add bridge API to access the bridge slave port

This API is needed by the NSS connection manager modules
to enable NSS fast path for bridge flows. The connection
manager needs to inspect the netdevice of the bridge slave
port that has learned a given MAC address.
Currently no such API exists that is exported out of the
kernel network stack for this purpose.

Change-Id: I3f8848739d820346135b09b93f760122874468fd
Signed-off-by: Ravinder konka <rkonka@codeaurora.org>
Signed-off-by: Mohammed Javid <mjavid@codeaurora.org>
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index ed0dd33..9218931 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -655,3 +655,34 @@
 	if (mask & BR_AUTO_MASK)
 		nbp_update_port_count(br);
 }
+
+/* br_port_dev_get()
+ * Using the given addr, identify the port to which it is reachable,
+ * returing a reference to the net device associated with that port.
+ *
+ * NOTE: Return NULL if given dev is not a bridge or
+ *       the mac has no associated port
+ */
+struct net_device *br_port_dev_get(struct net_device *dev, unsigned char *addr)
+{
+	struct net_bridge_fdb_entry *fdbe;
+	struct net_bridge *br;
+	struct net_device *netdev = NULL;
+
+	/* Is this a bridge? */
+	if (!(dev->priv_flags & IFF_EBRIDGE))
+		return NULL;
+
+	br = netdev_priv(dev);
+
+	/* Lookup the fdb entry and get reference to the port dev */
+	rcu_read_lock();
+	fdbe = __br_fdb_get(br, addr, 0);
+	if (fdbe && fdbe->dst) {
+		netdev = fdbe->dst->dev; /* port device */
+		dev_hold(netdev);
+	}
+	rcu_read_unlock();
+	return netdev;
+}
+EXPORT_SYMBOL(br_port_dev_get);