From: Jiri Pirko <jiri@resnulli.us>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, nhorman@tuxdriver.com, andy@greyhouse.net,
tgraf@suug.ch, dborkman@redhat.com, ogerlitz@mellanox.com,
jesse@nicira.com, pshelar@nicira.com, azhou@nicira.com,
ben@decadent.org.uk, stephen@networkplumber.org,
jeffrey.t.kirsher@intel.com, vyasevic@redhat.com,
xiyou.wangcong@gmail.com, john.r.fastabend@intel.com,
edumazet@google.com, jhs@mojatatu.com, sfeldma@gmail.com,
f.fainelli@gmail.com, roopa@cumulusnetworks.com,
linville@tuxdriver.com, jasowang@redhat.com,
ebiederm@xmission.com, nicolas.dichtel@6wind.com,
ryazanov.s.a@gmail.com, buytenh@wantstofly.org,
aviadr@mellanox.com, nbd@openwrt.org,
alexei.starovoitov@gmail.com, Neil.Jerram@metaswitch.com,
ronye@mellanox.com, simon.horman@netronome.com,
alexander.h.duyck@redhat.com, john.ronciak@intel.com,
mleitner@redhat.com, shrijeet@gmail.com,
gospo@cumulusnetworks.com, bcrl@kvack.org, hemal@broadcom.co
Subject: [patch net-next v5 10/21] bridge: add API to notify bridge driver of learned FBD on offloaded device
Date: Fri, 28 Nov 2014 14:34:21 +0100 [thread overview]
Message-ID: <1417181672-11531-11-git-send-email-jiri@resnulli.us> (raw)
In-Reply-To: <1417181672-11531-1-git-send-email-jiri@resnulli.us>
From: Scott Feldman <sfeldma@gmail.com>
When the swdev device learns a new mac/vlan on a port, it sends some async
notification to the driver and the driver installs an FDB in the device.
To give a holistic system view, the learned mac/vlan should be reflected
in the bridge's FBD table, so the user, using normal iproute2 cmds, can view
what is currently learned by the device. This API on the bridge driver gives
a way for the swdev driver to install an FBD entry in the bridge FBD table.
(And remove one).
This is equivalent to the device running these cmds:
bridge fdb [add|del] <mac> dev <dev> vid <vlan id> master
This patch needs some extra eyeballs for review, in paricular around the
locking and contexts.
Signed-off-by: Scott Feldman <sfeldma@gmail.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
v4->v5:
-no change
v3->v4:
-cosmetic changes to resolve conflicts
-call bh version of spinlock for hash_lock to avoid deadlock
v2->v3:
-added "external" word into function names to emphasize fdbs are learned
externally
-added "added_by_external_learn" to fbd entry struct indicate the entry
was learned externaly and build some logic around that
-expose the fact that fdb entry was learned externally to userspace
v1->v2:
-no change
---
include/linux/if_bridge.h | 18 +++++++++
include/uapi/linux/neighbour.h | 1 +
net/bridge/br_fdb.c | 91 +++++++++++++++++++++++++++++++++++++++++-
net/bridge/br_private.h | 3 +-
4 files changed, 111 insertions(+), 2 deletions(-)
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index 808dcb8..fa2eca6 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -37,6 +37,24 @@ extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __use
typedef int br_should_route_hook_t(struct sk_buff *skb);
extern br_should_route_hook_t __rcu *br_should_route_hook;
+#if IS_ENABLED(CONFIG_BRIDGE)
+int br_fdb_external_learn_add(struct net_device *dev,
+ const unsigned char *addr, u16 vid);
+int br_fdb_external_learn_del(struct net_device *dev,
+ const unsigned char *addr, u16 vid);
+#else
+static inline int br_fdb_external_learn_add(struct net_device *dev,
+ const unsigned char *addr, u16 vid)
+{
+ return 0;
+}
+static inline int br_fdb_external_learn_del(struct net_device *dev,
+ const unsigned char *addr, u16 vid)
+{
+ return 0;
+}
+#endif
+
#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
int br_multicast_list_adjacent(struct net_device *dev,
struct list_head *br_ip_list);
diff --git a/include/uapi/linux/neighbour.h b/include/uapi/linux/neighbour.h
index 2f043af..f3d77f9 100644
--- a/include/uapi/linux/neighbour.h
+++ b/include/uapi/linux/neighbour.h
@@ -38,6 +38,7 @@ enum {
#define NTF_SELF 0x02
#define NTF_MASTER 0x04
#define NTF_PROXY 0x08 /* == ATF_PUBL */
+#define NTF_EXT_LEARNED 0x10
#define NTF_ROUTER 0x80
/*
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index b1be971..cc36e59 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -481,6 +481,7 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head,
fdb->is_local = 0;
fdb->is_static = 0;
fdb->added_by_user = 0;
+ fdb->added_by_external_learn = 0;
fdb->updated = fdb->used = jiffies;
hlist_add_head_rcu(&fdb->hlist, head);
}
@@ -613,7 +614,7 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
ndm->ndm_family = AF_BRIDGE;
ndm->ndm_pad1 = 0;
ndm->ndm_pad2 = 0;
- ndm->ndm_flags = 0;
+ ndm->ndm_flags = fdb->added_by_external_learn ? NTF_EXT_LEARNED : 0;
ndm->ndm_type = 0;
ndm->ndm_ifindex = fdb->dst ? fdb->dst->dev->ifindex : br->dev->ifindex;
ndm->ndm_state = fdb_to_nud(fdb);
@@ -983,3 +984,91 @@ void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p)
}
}
}
+
+int br_fdb_external_learn_add(struct net_device *dev,
+ const unsigned char *addr, u16 vid)
+{
+ struct net_bridge_port *p;
+ struct net_bridge *br;
+ struct hlist_head *head;
+ struct net_bridge_fdb_entry *fdb;
+ int err = 0;
+
+ rtnl_lock();
+
+ p = br_port_get_rtnl(dev);
+ if (!p) {
+ pr_info("bridge: %s not a bridge port\n", dev->name);
+ err = -EINVAL;
+ goto err_rtnl_unlock;
+ }
+
+ br = p->br;
+
+ spin_lock_bh(&br->hash_lock);
+
+ head = &br->hash[br_mac_hash(addr, vid)];
+ fdb = fdb_find(head, addr, vid);
+ if (!fdb) {
+ fdb = fdb_create(head, p, addr, vid);
+ if (!fdb) {
+ err = -ENOMEM;
+ goto err_unlock;
+ }
+ fdb->added_by_external_learn = 1;
+ fdb_notify(br, fdb, RTM_NEWNEIGH);
+ } else if (fdb->added_by_external_learn) {
+ /* Refresh entry */
+ fdb->updated = fdb->used = jiffies;
+ } else if (!fdb->added_by_user) {
+ /* Take over SW learned entry */
+ fdb->added_by_external_learn = 1;
+ fdb->updated = jiffies;
+ fdb_notify(br, fdb, RTM_NEWNEIGH);
+ }
+
+err_unlock:
+ spin_unlock_bh(&br->hash_lock);
+err_rtnl_unlock:
+ rtnl_unlock();
+
+ return err;
+}
+EXPORT_SYMBOL(br_fdb_external_learn_add);
+
+int br_fdb_external_learn_del(struct net_device *dev,
+ const unsigned char *addr, u16 vid)
+{
+ struct net_bridge_port *p;
+ struct net_bridge *br;
+ struct hlist_head *head;
+ struct net_bridge_fdb_entry *fdb;
+ int err = 0;
+
+ rtnl_lock();
+
+ p = br_port_get_rtnl(dev);
+ if (!p) {
+ pr_info("bridge: %s not a bridge port\n", dev->name);
+ err = -EINVAL;
+ goto err_rtnl_unlock;
+ }
+
+ br = p->br;
+
+ spin_lock_bh(&br->hash_lock);
+
+ head = &br->hash[br_mac_hash(addr, vid)];
+ fdb = fdb_find(head, addr, vid);
+ if (fdb && fdb->added_by_external_learn)
+ fdb_delete(br, fdb);
+ else
+ err = -ENOENT;
+
+ spin_unlock_bh(&br->hash_lock);
+err_rtnl_unlock:
+ rtnl_unlock();
+
+ return err;
+}
+EXPORT_SYMBOL(br_fdb_external_learn_del);
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 1b529da..cc36fb3 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -100,7 +100,8 @@ struct net_bridge_fdb_entry
mac_addr addr;
unsigned char is_local:1,
is_static:1,
- added_by_user:1;
+ added_by_user:1,
+ added_by_external_learn:1;
__u16 vlan_id;
};
--
1.9.3
next prev parent reply other threads:[~2014-11-28 13:34 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-28 13:34 [patch net-next v5 00/21] introduce rocker switch driver with hardware accelerated datapath api - phase 1: bridge fdb offload Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 01/21] bridge: rename fdb_*_hw to fdb_*_hw_addr to avoid confusion Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 02/21] neigh: sort Neighbor Cache Entry Flags Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 03/21] bridge: convert flags in fbd entry into bitfields Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 04/21] net: make vid as a parameter for ndo_fdb_add/ndo_fdb_del Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 05/21] net: rename netdev_phys_port_id to more generic name Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 06/21] net: introduce generic switch devices support Jiri Pirko
2014-11-29 9:31 ` Lino Sanfilippo
2014-11-29 9:59 ` Jiri Pirko
2014-11-29 10:44 ` Lino Sanfilippo
2014-11-28 13:34 ` [patch net-next v5 07/21] rtnl: expose physical switch id for particular device Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 08/21] net-sysfs: " Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 09/21] bridge: call netdev_sw_port_stp_update when bridge port STP status changes Jiri Pirko
2014-11-28 13:34 ` Jiri Pirko [this message]
2014-11-28 13:34 ` [patch net-next v5 11/21] bridge: move private brport flags to if_bridge.h so port drivers can use flags Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 12/21] bridge: add new brport flag LEARNING_SYNC Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 13/21] bridge: add new hwmode swdev Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 14/21] bridge: add brport flags to dflt bridge_getlink Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 15/21] rocker: introduce rocker switch driver Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 16/21] rocker: implement rocker ofdpa flow table manipulation Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 17/21] rocker: implement L2 bridge offloading Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 18/21] rocker: implement ndo_fdb_dump Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 19/21] rocker: add ndo_bridge_setlink/getlink support for learning policy Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 20/21] rocker: Add proper validation of Netlink attributes Jiri Pirko
2014-11-28 13:34 ` [patch net-next v5 21/21] rocker: Use logical operators on booleans Jiri Pirko
2014-12-03 4:02 ` [patch net-next v5 00/21] introduce rocker switch driver with hardware accelerated datapath api - phase 1: bridge fdb offload David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1417181672-11531-11-git-send-email-jiri@resnulli.us \
--to=jiri@resnulli.us \
--cc=Neil.Jerram@metaswitch.com \
--cc=alexander.h.duyck@redhat.com \
--cc=alexei.starovoitov@gmail.com \
--cc=andy@greyhouse.net \
--cc=aviadr@mellanox.com \
--cc=azhou@nicira.com \
--cc=bcrl@kvack.org \
--cc=ben@decadent.org.uk \
--cc=buytenh@wantstofly.org \
--cc=davem@davemloft.net \
--cc=dborkman@redhat.com \
--cc=ebiederm@xmission.com \
--cc=edumazet@google.com \
--cc=f.fainelli@gmail.com \
--cc=gospo@cumulusnetworks.com \
--cc=hemal@broadcom.co \
--cc=jasowang@redhat.com \
--cc=jeffrey.t.kirsher@intel.com \
--cc=jesse@nicira.com \
--cc=jhs@mojatatu.com \
--cc=john.r.fastabend@intel.com \
--cc=john.ronciak@intel.com \
--cc=linville@tuxdriver.com \
--cc=mleitner@redhat.com \
--cc=nbd@openwrt.org \
--cc=netdev@vger.kernel.org \
--cc=nhorman@tuxdriver.com \
--cc=nicolas.dichtel@6wind.com \
--cc=ogerlitz@mellanox.com \
--cc=pshelar@nicira.com \
--cc=ronye@mellanox.com \
--cc=roopa@cumulusnetworks.com \
--cc=ryazanov.s.a@gmail.com \
--cc=sfeldma@gmail.com \
--cc=shrijeet@gmail.com \
--cc=simon.horman@netronome.com \
--cc=stephen@networkplumber.org \
--cc=tgraf@suug.ch \
--cc=vyasevic@redhat.com \
--cc=xiyou.wangcong@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).