Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b26b51b authored by Arkadi Sharshevsky's avatar Arkadi Sharshevsky Committed by David S. Miller
Browse files

net: bridge: Add support for notifying devices about FDB add/del



Currently the bridge doesn't notify the underlying devices about new
FDBs learned. The FDB sync is placed on the switchdev notifier chain
because devices may potentially learn FDB that are not directly related
to their ports, for example:

1. Mixed SW/HW bridge - FDBs that point to the ASICs external devices
                        should be offloaded as CPU traps in order to
			perform forwarding in slow path.
2. EVPN - Externally learned FDBs for the vtep device.

Notification is sent only about static FDB add/del. This is done due
to fact that currently this is the only scenario supported by switch
drivers.

Signed-off-by: default avatarArkadi Sharshevsky <arkadis@mellanox.com>
Reviewed-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Reviewed-by: default avatarNikolay Aleksandrov <nikolay@cumulusnetworks.com>
Reviewed-by: default avatarIvan Vecera <ivecera@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ff5cf100
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1867,7 +1867,7 @@ static void mlxsw_sp_fdb_call_notifiers(bool learning_sync, bool adding,
	if (learning_sync) {
		info.addr = mac;
		info.vid = vid;
		notifier_type = adding ? SWITCHDEV_FDB_ADD : SWITCHDEV_FDB_DEL;
		notifier_type = adding ? SWITCHDEV_FDB_ADD_TO_BRIDGE : SWITCHDEV_FDB_DEL_TO_BRIDGE;
		call_switchdev_notifiers(notifier_type, dev, &info.info);
	}
}
+2 −2
Original line number Diff line number Diff line
@@ -1939,10 +1939,10 @@ static void ofdpa_port_fdb_learn_work(struct work_struct *work)

	rtnl_lock();
	if (learned && removing)
		call_switchdev_notifiers(SWITCHDEV_FDB_DEL,
		call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE,
					 lw->ofdpa_port->dev, &info.info);
	else if (learned && !removing)
		call_switchdev_notifiers(SWITCHDEV_FDB_ADD,
		call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE,
					 lw->ofdpa_port->dev, &info.info);
	rtnl_unlock();

+4 −2
Original line number Diff line number Diff line
@@ -155,8 +155,10 @@ struct switchdev_ops {
};

enum switchdev_notifier_type {
	SWITCHDEV_FDB_ADD = 1,
	SWITCHDEV_FDB_DEL,
	SWITCHDEV_FDB_ADD_TO_BRIDGE = 1,
	SWITCHDEV_FDB_DEL_TO_BRIDGE,
	SWITCHDEV_FDB_ADD_TO_DEVICE,
	SWITCHDEV_FDB_DEL_TO_DEVICE,
};

struct switchdev_notifier_info {
+2 −2
Original line number Diff line number Diff line
@@ -138,14 +138,14 @@ static int br_switchdev_event(struct notifier_block *unused,
	br = p->br;

	switch (event) {
	case SWITCHDEV_FDB_ADD:
	case SWITCHDEV_FDB_ADD_TO_BRIDGE:
		fdb_info = ptr;
		err = br_fdb_external_learn_add(br, p, fdb_info->addr,
						fdb_info->vid);
		if (err)
			err = notifier_from_errno(err);
		break;
	case SWITCHDEV_FDB_DEL:
	case SWITCHDEV_FDB_DEL_TO_BRIDGE:
		fdb_info = ptr;
		err = br_fdb_external_learn_del(br, p, fdb_info->addr,
						fdb_info->vid);
+2 −0
Original line number Diff line number Diff line
@@ -690,6 +690,8 @@ static void fdb_notify(struct net_bridge *br,
	struct sk_buff *skb;
	int err = -ENOBUFS;

	br_switchdev_fdb_notify(fdb, type);

	skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC);
	if (skb == NULL)
		goto errout;
Loading