OSDN Git Service
(root)
/
uclinux-h8
/
linux.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
net: dsa: request drivers to perform FDB isolation
[uclinux-h8/linux.git]
/
net
/
dsa
/
switch.c
diff --git
a/net/dsa/switch.c
b/net/dsa/switch.c
index
eb38beb
..
1d3c161
100644
(file)
--- a/
net/dsa/switch.c
+++ b/
net/dsa/switch.c
@@
-210,21
+210,41
@@
static bool dsa_port_host_address_match(struct dsa_port *dp,
return false;
}
return false;
}
+static bool dsa_db_equal(const struct dsa_db *a, const struct dsa_db *b)
+{
+ if (a->type != b->type)
+ return false;
+
+ switch (a->type) {
+ case DSA_DB_PORT:
+ return a->dp == b->dp;
+ case DSA_DB_LAG:
+ return a->lag.dev == b->lag.dev;
+ case DSA_DB_BRIDGE:
+ return a->bridge.num == b->bridge.num;
+ default:
+ WARN_ON(1);
+ return false;
+ }
+}
+
static struct dsa_mac_addr *dsa_mac_addr_find(struct list_head *addr_list,
static struct dsa_mac_addr *dsa_mac_addr_find(struct list_head *addr_list,
- const unsigned char *addr,
-
u16 vid
)
+ const unsigned char *addr,
u16 vid,
+
struct dsa_db db
)
{
struct dsa_mac_addr *a;
list_for_each_entry(a, addr_list, list)
{
struct dsa_mac_addr *a;
list_for_each_entry(a, addr_list, list)
- if (ether_addr_equal(a->addr, addr) && a->vid == vid)
+ if (ether_addr_equal(a->addr, addr) && a->vid == vid &&
+ dsa_db_equal(&a->db, &db))
return a;
return NULL;
}
static int dsa_port_do_mdb_add(struct dsa_port *dp,
return a;
return NULL;
}
static int dsa_port_do_mdb_add(struct dsa_port *dp,
- const struct switchdev_obj_port_mdb *mdb)
+ const struct switchdev_obj_port_mdb *mdb,
+ struct dsa_db db)
{
struct dsa_switch *ds = dp->ds;
struct dsa_mac_addr *a;
{
struct dsa_switch *ds = dp->ds;
struct dsa_mac_addr *a;
@@
-233,11
+253,11
@@
static int dsa_port_do_mdb_add(struct dsa_port *dp,
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
- return ds->ops->port_mdb_add(ds, port, mdb);
+ return ds->ops->port_mdb_add(ds, port, mdb
, db
);
mutex_lock(&dp->addr_lists_lock);
mutex_lock(&dp->addr_lists_lock);
- a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid);
+ a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid
, db
);
if (a) {
refcount_inc(&a->refcount);
goto out;
if (a) {
refcount_inc(&a->refcount);
goto out;
@@
-249,7
+269,7
@@
static int dsa_port_do_mdb_add(struct dsa_port *dp,
goto out;
}
goto out;
}
- err = ds->ops->port_mdb_add(ds, port, mdb);
+ err = ds->ops->port_mdb_add(ds, port, mdb
, db
);
if (err) {
kfree(a);
goto out;
if (err) {
kfree(a);
goto out;
@@
-257,6
+277,7
@@
static int dsa_port_do_mdb_add(struct dsa_port *dp,
ether_addr_copy(a->addr, mdb->addr);
a->vid = mdb->vid;
ether_addr_copy(a->addr, mdb->addr);
a->vid = mdb->vid;
+ a->db = db;
refcount_set(&a->refcount, 1);
list_add_tail(&a->list, &dp->mdbs);
refcount_set(&a->refcount, 1);
list_add_tail(&a->list, &dp->mdbs);
@@
-267,7
+288,8
@@
out:
}
static int dsa_port_do_mdb_del(struct dsa_port *dp,
}
static int dsa_port_do_mdb_del(struct dsa_port *dp,
- const struct switchdev_obj_port_mdb *mdb)
+ const struct switchdev_obj_port_mdb *mdb,
+ struct dsa_db db)
{
struct dsa_switch *ds = dp->ds;
struct dsa_mac_addr *a;
{
struct dsa_switch *ds = dp->ds;
struct dsa_mac_addr *a;
@@
-276,11
+298,11
@@
static int dsa_port_do_mdb_del(struct dsa_port *dp,
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
- return ds->ops->port_mdb_del(ds, port, mdb);
+ return ds->ops->port_mdb_del(ds, port, mdb
, db
);
mutex_lock(&dp->addr_lists_lock);
mutex_lock(&dp->addr_lists_lock);
- a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid);
+ a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid
, db
);
if (!a) {
err = -ENOENT;
goto out;
if (!a) {
err = -ENOENT;
goto out;
@@
-289,7
+311,7
@@
static int dsa_port_do_mdb_del(struct dsa_port *dp,
if (!refcount_dec_and_test(&a->refcount))
goto out;
if (!refcount_dec_and_test(&a->refcount))
goto out;
- err = ds->ops->port_mdb_del(ds, port, mdb);
+ err = ds->ops->port_mdb_del(ds, port, mdb
, db
);
if (err) {
refcount_set(&a->refcount, 1);
goto out;
if (err) {
refcount_set(&a->refcount, 1);
goto out;
@@
-305,7
+327,7
@@
out:
}
static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
}
static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
- u16 vid)
+ u16 vid
, struct dsa_db db
)
{
struct dsa_switch *ds = dp->ds;
struct dsa_mac_addr *a;
{
struct dsa_switch *ds = dp->ds;
struct dsa_mac_addr *a;
@@
-314,11
+336,11
@@
static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
- return ds->ops->port_fdb_add(ds, port, addr, vid);
+ return ds->ops->port_fdb_add(ds, port, addr, vid
, db
);
mutex_lock(&dp->addr_lists_lock);
mutex_lock(&dp->addr_lists_lock);
- a = dsa_mac_addr_find(&dp->fdbs, addr, vid);
+ a = dsa_mac_addr_find(&dp->fdbs, addr, vid
, db
);
if (a) {
refcount_inc(&a->refcount);
goto out;
if (a) {
refcount_inc(&a->refcount);
goto out;
@@
-330,7
+352,7
@@
static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
goto out;
}
goto out;
}
- err = ds->ops->port_fdb_add(ds, port, addr, vid);
+ err = ds->ops->port_fdb_add(ds, port, addr, vid
, db
);
if (err) {
kfree(a);
goto out;
if (err) {
kfree(a);
goto out;
@@
-338,6
+360,7
@@
static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
ether_addr_copy(a->addr, addr);
a->vid = vid;
ether_addr_copy(a->addr, addr);
a->vid = vid;
+ a->db = db;
refcount_set(&a->refcount, 1);
list_add_tail(&a->list, &dp->fdbs);
refcount_set(&a->refcount, 1);
list_add_tail(&a->list, &dp->fdbs);
@@
-348,7
+371,7
@@
out:
}
static int dsa_port_do_fdb_del(struct dsa_port *dp, const unsigned char *addr,
}
static int dsa_port_do_fdb_del(struct dsa_port *dp, const unsigned char *addr,
- u16 vid)
+ u16 vid
, struct dsa_db db
)
{
struct dsa_switch *ds = dp->ds;
struct dsa_mac_addr *a;
{
struct dsa_switch *ds = dp->ds;
struct dsa_mac_addr *a;
@@
-357,11
+380,11
@@
static int dsa_port_do_fdb_del(struct dsa_port *dp, const unsigned char *addr,
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
/* No need to bother with refcounting for user ports */
if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
- return ds->ops->port_fdb_del(ds, port, addr, vid);
+ return ds->ops->port_fdb_del(ds, port, addr, vid
, db
);
mutex_lock(&dp->addr_lists_lock);
mutex_lock(&dp->addr_lists_lock);
- a = dsa_mac_addr_find(&dp->fdbs, addr, vid);
+ a = dsa_mac_addr_find(&dp->fdbs, addr, vid
, db
);
if (!a) {
err = -ENOENT;
goto out;
if (!a) {
err = -ENOENT;
goto out;
@@
-370,7
+393,7
@@
static int dsa_port_do_fdb_del(struct dsa_port *dp, const unsigned char *addr,
if (!refcount_dec_and_test(&a->refcount))
goto out;
if (!refcount_dec_and_test(&a->refcount))
goto out;
- err = ds->ops->port_fdb_del(ds, port, addr, vid);
+ err = ds->ops->port_fdb_del(ds, port, addr, vid
, db
);
if (err) {
refcount_set(&a->refcount, 1);
goto out;
if (err) {
refcount_set(&a->refcount, 1);
goto out;
@@
-386,14
+409,15
@@
out:
}
static int dsa_switch_do_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag *lag,
}
static int dsa_switch_do_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag *lag,
- const unsigned char *addr, u16 vid)
+ const unsigned char *addr, u16 vid,
+ struct dsa_db db)
{
struct dsa_mac_addr *a;
int err = 0;
mutex_lock(&lag->fdb_lock);
{
struct dsa_mac_addr *a;
int err = 0;
mutex_lock(&lag->fdb_lock);
- a = dsa_mac_addr_find(&lag->fdbs, addr, vid);
+ a = dsa_mac_addr_find(&lag->fdbs, addr, vid
, db
);
if (a) {
refcount_inc(&a->refcount);
goto out;
if (a) {
refcount_inc(&a->refcount);
goto out;
@@
-405,7
+429,7
@@
static int dsa_switch_do_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag *lag,
goto out;
}
goto out;
}
- err = ds->ops->lag_fdb_add(ds, *lag, addr, vid);
+ err = ds->ops->lag_fdb_add(ds, *lag, addr, vid
, db
);
if (err) {
kfree(a);
goto out;
if (err) {
kfree(a);
goto out;
@@
-423,14
+447,15
@@
out:
}
static int dsa_switch_do_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag *lag,
}
static int dsa_switch_do_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag *lag,
- const unsigned char *addr, u16 vid)
+ const unsigned char *addr, u16 vid,
+ struct dsa_db db)
{
struct dsa_mac_addr *a;
int err = 0;
mutex_lock(&lag->fdb_lock);
{
struct dsa_mac_addr *a;
int err = 0;
mutex_lock(&lag->fdb_lock);
- a = dsa_mac_addr_find(&lag->fdbs, addr, vid);
+ a = dsa_mac_addr_find(&lag->fdbs, addr, vid
, db
);
if (!a) {
err = -ENOENT;
goto out;
if (!a) {
err = -ENOENT;
goto out;
@@
-439,7
+464,7
@@
static int dsa_switch_do_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag *lag,
if (!refcount_dec_and_test(&a->refcount))
goto out;
if (!refcount_dec_and_test(&a->refcount))
goto out;
- err = ds->ops->lag_fdb_del(ds, *lag, addr, vid);
+ err = ds->ops->lag_fdb_del(ds, *lag, addr, vid
, db
);
if (err) {
refcount_set(&a->refcount, 1);
goto out;
if (err) {
refcount_set(&a->refcount, 1);
goto out;
@@
-466,7
+491,8
@@
static int dsa_switch_host_fdb_add(struct dsa_switch *ds,
dsa_switch_for_each_port(dp, ds) {
if (dsa_port_host_address_match(dp, info->sw_index,
info->port)) {
dsa_switch_for_each_port(dp, ds) {
if (dsa_port_host_address_match(dp, info->sw_index,
info->port)) {
- err = dsa_port_do_fdb_add(dp, info->addr, info->vid);
+ err = dsa_port_do_fdb_add(dp, info->addr, info->vid,
+ info->db);
if (err)
break;
}
if (err)
break;
}
@@
-487,7
+513,8
@@
static int dsa_switch_host_fdb_del(struct dsa_switch *ds,
dsa_switch_for_each_port(dp, ds) {
if (dsa_port_host_address_match(dp, info->sw_index,
info->port)) {
dsa_switch_for_each_port(dp, ds) {
if (dsa_port_host_address_match(dp, info->sw_index,
info->port)) {
- err = dsa_port_do_fdb_del(dp, info->addr, info->vid);
+ err = dsa_port_do_fdb_del(dp, info->addr, info->vid,
+ info->db);
if (err)
break;
}
if (err)
break;
}
@@
-505,7
+532,7
@@
static int dsa_switch_fdb_add(struct dsa_switch *ds,
if (!ds->ops->port_fdb_add)
return -EOPNOTSUPP;
if (!ds->ops->port_fdb_add)
return -EOPNOTSUPP;
- return dsa_port_do_fdb_add(dp, info->addr, info->vid);
+ return dsa_port_do_fdb_add(dp, info->addr, info->vid
, info->db
);
}
static int dsa_switch_fdb_del(struct dsa_switch *ds,
}
static int dsa_switch_fdb_del(struct dsa_switch *ds,
@@
-517,7
+544,7
@@
static int dsa_switch_fdb_del(struct dsa_switch *ds,
if (!ds->ops->port_fdb_del)
return -EOPNOTSUPP;
if (!ds->ops->port_fdb_del)
return -EOPNOTSUPP;
- return dsa_port_do_fdb_del(dp, info->addr, info->vid);
+ return dsa_port_do_fdb_del(dp, info->addr, info->vid
, info->db
);
}
static int dsa_switch_lag_fdb_add(struct dsa_switch *ds,
}
static int dsa_switch_lag_fdb_add(struct dsa_switch *ds,
@@
-532,7
+559,8
@@
static int dsa_switch_lag_fdb_add(struct dsa_switch *ds,
dsa_switch_for_each_port(dp, ds)
if (dsa_port_offloads_lag(dp, info->lag))
return dsa_switch_do_lag_fdb_add(ds, info->lag,
dsa_switch_for_each_port(dp, ds)
if (dsa_port_offloads_lag(dp, info->lag))
return dsa_switch_do_lag_fdb_add(ds, info->lag,
- info->addr, info->vid);
+ info->addr, info->vid,
+ info->db);
return 0;
}
return 0;
}
@@
-549,7
+577,8
@@
static int dsa_switch_lag_fdb_del(struct dsa_switch *ds,
dsa_switch_for_each_port(dp, ds)
if (dsa_port_offloads_lag(dp, info->lag))
return dsa_switch_do_lag_fdb_del(ds, info->lag,
dsa_switch_for_each_port(dp, ds)
if (dsa_port_offloads_lag(dp, info->lag))
return dsa_switch_do_lag_fdb_del(ds, info->lag,
- info->addr, info->vid);
+ info->addr, info->vid,
+ info->db);
return 0;
}
return 0;
}
@@
-604,7
+633,7
@@
static int dsa_switch_mdb_add(struct dsa_switch *ds,
if (!ds->ops->port_mdb_add)
return -EOPNOTSUPP;
if (!ds->ops->port_mdb_add)
return -EOPNOTSUPP;
- return dsa_port_do_mdb_add(dp, info->mdb);
+ return dsa_port_do_mdb_add(dp, info->mdb
, info->db
);
}
static int dsa_switch_mdb_del(struct dsa_switch *ds,
}
static int dsa_switch_mdb_del(struct dsa_switch *ds,
@@
-616,7
+645,7
@@
static int dsa_switch_mdb_del(struct dsa_switch *ds,
if (!ds->ops->port_mdb_del)
return -EOPNOTSUPP;
if (!ds->ops->port_mdb_del)
return -EOPNOTSUPP;
- return dsa_port_do_mdb_del(dp, info->mdb);
+ return dsa_port_do_mdb_del(dp, info->mdb
, info->db
);
}
static int dsa_switch_host_mdb_add(struct dsa_switch *ds,
}
static int dsa_switch_host_mdb_add(struct dsa_switch *ds,
@@
-631,7
+660,7
@@
static int dsa_switch_host_mdb_add(struct dsa_switch *ds,
dsa_switch_for_each_port(dp, ds) {
if (dsa_port_host_address_match(dp, info->sw_index,
info->port)) {
dsa_switch_for_each_port(dp, ds) {
if (dsa_port_host_address_match(dp, info->sw_index,
info->port)) {
- err = dsa_port_do_mdb_add(dp, info->mdb);
+ err = dsa_port_do_mdb_add(dp, info->mdb
, info->db
);
if (err)
break;
}
if (err)
break;
}
@@
-652,7
+681,7
@@
static int dsa_switch_host_mdb_del(struct dsa_switch *ds,
dsa_switch_for_each_port(dp, ds) {
if (dsa_port_host_address_match(dp, info->sw_index,
info->port)) {
dsa_switch_for_each_port(dp, ds) {
if (dsa_port_host_address_match(dp, info->sw_index,
info->port)) {
- err = dsa_port_do_mdb_del(dp, info->mdb);
+ err = dsa_port_do_mdb_del(dp, info->mdb
, info->db
);
if (err)
break;
}
if (err)
break;
}