Skip to content

Commit 8df3025

Browse files
viviendavem330
authored andcommitted
net: dsa: add MDB support
Add SWITCHDEV_OBJ_ID_PORT_MDB support to the DSA layer. Signed-off-by: Vivien Didelot <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent dbeb714 commit 8df3025

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

Documentation/networking/dsa/dsa.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,29 @@ of DSA, would be the its port-based VLAN, used by the associated bridge device.
584584
function that the driver has to call for each MAC address known to be behind
585585
the given port. A switchdev object is used to carry the VID and FDB info.
586586

587+
- port_mdb_prepare: bridge layer function invoked when the bridge prepares the
588+
installation of a multicast database entry. If the operation is not supported,
589+
this function should return -EOPNOTSUPP to inform the bridge code to fallback
590+
to a software implementation. No hardware setup must be done in this function.
591+
See port_fdb_add for this and details.
592+
593+
- port_mdb_add: bridge layer function invoked when the bridge wants to install
594+
a multicast database entry, the switch hardware should be programmed with the
595+
specified address in the specified VLAN ID in the forwarding database
596+
associated with this VLAN ID.
597+
598+
Note: VLAN ID 0 corresponds to the port private database, which, in the context
599+
of DSA, would be the its port-based VLAN, used by the associated bridge device.
600+
601+
- port_mdb_del: bridge layer function invoked when the bridge wants to remove a
602+
multicast database entry, the switch hardware should be programmed to delete
603+
the specified MAC address from the specified VLAN ID if it was mapped into
604+
this port forwarding database.
605+
606+
- port_mdb_dump: bridge layer function invoked with a switchdev callback
607+
function that the driver has to call for each MAC address known to be behind
608+
the given port. A switchdev object is used to carry the VID and MDB info.
609+
587610
TODO
588611
====
589612

include/net/dsa.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
234234
struct switchdev_trans;
235235
struct switchdev_obj;
236236
struct switchdev_obj_port_fdb;
237+
struct switchdev_obj_port_mdb;
237238
struct switchdev_obj_port_vlan;
238239

239240
struct dsa_switch_ops {
@@ -369,6 +370,21 @@ struct dsa_switch_ops {
369370
int (*port_fdb_dump)(struct dsa_switch *ds, int port,
370371
struct switchdev_obj_port_fdb *fdb,
371372
int (*cb)(struct switchdev_obj *obj));
373+
374+
/*
375+
* Multicast database
376+
*/
377+
int (*port_mdb_prepare)(struct dsa_switch *ds, int port,
378+
const struct switchdev_obj_port_mdb *mdb,
379+
struct switchdev_trans *trans);
380+
void (*port_mdb_add)(struct dsa_switch *ds, int port,
381+
const struct switchdev_obj_port_mdb *mdb,
382+
struct switchdev_trans *trans);
383+
int (*port_mdb_del)(struct dsa_switch *ds, int port,
384+
const struct switchdev_obj_port_mdb *mdb);
385+
int (*port_mdb_dump)(struct dsa_switch *ds, int port,
386+
struct switchdev_obj_port_mdb *mdb,
387+
int (*cb)(struct switchdev_obj *obj));
372388
};
373389

374390
void register_switch_driver(struct dsa_switch_ops *type);

net/dsa/slave.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,50 @@ static int dsa_slave_port_fdb_dump(struct net_device *dev,
290290
return -EOPNOTSUPP;
291291
}
292292

293+
static int dsa_slave_port_mdb_add(struct net_device *dev,
294+
const struct switchdev_obj_port_mdb *mdb,
295+
struct switchdev_trans *trans)
296+
{
297+
struct dsa_slave_priv *p = netdev_priv(dev);
298+
struct dsa_switch *ds = p->parent;
299+
300+
if (switchdev_trans_ph_prepare(trans)) {
301+
if (!ds->ops->port_mdb_prepare || !ds->ops->port_mdb_add)
302+
return -EOPNOTSUPP;
303+
304+
return ds->ops->port_mdb_prepare(ds, p->port, mdb, trans);
305+
}
306+
307+
ds->ops->port_mdb_add(ds, p->port, mdb, trans);
308+
309+
return 0;
310+
}
311+
312+
static int dsa_slave_port_mdb_del(struct net_device *dev,
313+
const struct switchdev_obj_port_mdb *mdb)
314+
{
315+
struct dsa_slave_priv *p = netdev_priv(dev);
316+
struct dsa_switch *ds = p->parent;
317+
318+
if (ds->ops->port_mdb_del)
319+
return ds->ops->port_mdb_del(ds, p->port, mdb);
320+
321+
return -EOPNOTSUPP;
322+
}
323+
324+
static int dsa_slave_port_mdb_dump(struct net_device *dev,
325+
struct switchdev_obj_port_mdb *mdb,
326+
switchdev_obj_dump_cb_t *cb)
327+
{
328+
struct dsa_slave_priv *p = netdev_priv(dev);
329+
struct dsa_switch *ds = p->parent;
330+
331+
if (ds->ops->port_mdb_dump)
332+
return ds->ops->port_mdb_dump(ds, p->port, mdb, cb);
333+
334+
return -EOPNOTSUPP;
335+
}
336+
293337
static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
294338
{
295339
struct dsa_slave_priv *p = netdev_priv(dev);
@@ -412,6 +456,10 @@ static int dsa_slave_port_obj_add(struct net_device *dev,
412456
SWITCHDEV_OBJ_PORT_FDB(obj),
413457
trans);
414458
break;
459+
case SWITCHDEV_OBJ_ID_PORT_MDB:
460+
err = dsa_slave_port_mdb_add(dev, SWITCHDEV_OBJ_PORT_MDB(obj),
461+
trans);
462+
break;
415463
case SWITCHDEV_OBJ_ID_PORT_VLAN:
416464
err = dsa_slave_port_vlan_add(dev,
417465
SWITCHDEV_OBJ_PORT_VLAN(obj),
@@ -435,6 +483,9 @@ static int dsa_slave_port_obj_del(struct net_device *dev,
435483
err = dsa_slave_port_fdb_del(dev,
436484
SWITCHDEV_OBJ_PORT_FDB(obj));
437485
break;
486+
case SWITCHDEV_OBJ_ID_PORT_MDB:
487+
err = dsa_slave_port_mdb_del(dev, SWITCHDEV_OBJ_PORT_MDB(obj));
488+
break;
438489
case SWITCHDEV_OBJ_ID_PORT_VLAN:
439490
err = dsa_slave_port_vlan_del(dev,
440491
SWITCHDEV_OBJ_PORT_VLAN(obj));
@@ -459,6 +510,10 @@ static int dsa_slave_port_obj_dump(struct net_device *dev,
459510
SWITCHDEV_OBJ_PORT_FDB(obj),
460511
cb);
461512
break;
513+
case SWITCHDEV_OBJ_ID_PORT_MDB:
514+
err = dsa_slave_port_mdb_dump(dev, SWITCHDEV_OBJ_PORT_MDB(obj),
515+
cb);
516+
break;
462517
case SWITCHDEV_OBJ_ID_PORT_VLAN:
463518
err = dsa_slave_port_vlan_dump(dev,
464519
SWITCHDEV_OBJ_PORT_VLAN(obj),

0 commit comments

Comments
 (0)