History

net: dsa: Move FDB dump implementation inside DSA

>From all switchdev devices only DSA requires special FDB dump. This is due to lack of ability for syncing the hardware learned FDBs with the bridge. Due to this it is removed from switchdev and moved inside DSA.

Arkadi Sharshevsky committed 9 years ago

Commit 2bedde11 parent dc0cbff12 files · +112 −204Browse files

Unified · Split

12 files
  1. drivers/net/dsa/b53/b53_common.c +5 −11
  2. drivers/net/dsa/b53/b53_priv.h +1 −2
  3. drivers/net/dsa/microchip/ksz_common.c +6 −14
  4. drivers/net/dsa/mt7530.c +3 −7
  5. drivers/net/dsa/mv88e6xxx/chip.c +12 −26
  6. drivers/net/dsa/qca8k.c +4 −11
  7. include/net/dsa.h +3 −2
  8. include/net/switchdev.h +0 −12
  9. net/dsa/dsa_priv.h +0 −2
  10. net/dsa/port.c +0 −11
  11. net/dsa/slave.c +78 −22
  12. net/switchdev/switchdev.c +0 −84
drivers/net/dsa/b53/b53_common.c+5−11
@@ -1227,8 +1227,7 @@ static void b53_arl_search_rd(struct b53_device *dev, u8 idx, · 1226 unmodified lines
1227}1227}
1228 1228
1229static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,1229static int b53_fdb_copy(int port, const struct b53_arl_entry *ent,
1230 struct switchdev_obj_port_fdb *fdb,1230 dsa_fdb_dump_cb_t *cb, void *data)
1231 switchdev_obj_dump_cb_t *cb)
1232{1231{
1233 if (!ent->is_valid)1232 if (!ent->is_valid)
1234 return 0;1233 return 0;
@@ -1236,16 +1235,11 @@ static int b53_fdb_copy(int port, const struct b53_arl_entry *ent, · 1 unmodified line
1236 if (port != ent->port)1235 if (port != ent->port)
1237 return 0;1236 return 0;
1238 1237
1239 ether_addr_copy(fdb->addr, ent->mac);1238 return cb(ent->mac, ent->vid, ent->is_static, data);
1240 fdb->vid = ent->vid;
1241 fdb->ndm_state = ent->is_static ? NUD_NOARP : NUD_REACHABLE;
1242
1243 return cb(&fdb->obj);
1244}1239}
1245 1240
1246int b53_fdb_dump(struct dsa_switch *ds, int port,1241int b53_fdb_dump(struct dsa_switch *ds, int port,
1247 struct switchdev_obj_port_fdb *fdb,1242 dsa_fdb_dump_cb_t *cb, void *data)
1248 switchdev_obj_dump_cb_t *cb)
1249{1243{
1250 struct b53_device *priv = ds->priv;1244 struct b53_device *priv = ds->priv;
1251 struct b53_arl_entry results[2];1245 struct b53_arl_entry results[2];
@@ -1263,13 +1257,13 @@ int b53_fdb_dump(struct dsa_switch *ds, int port, · 11 unmodified lines
1263 return ret;1257 return ret;
1264 1258
1265 b53_arl_search_rd(priv, 0, &results[0]);1259 b53_arl_search_rd(priv, 0, &results[0]);
1266 ret = b53_fdb_copy(port, &results[0], fdb, cb);1260 ret = b53_fdb_copy(port, &results[0], cb, data);
1267 if (ret)1261 if (ret)
1268 return ret;1262 return ret;
1269 1263
1270 if (priv->num_arl_entries > 2) {1264 if (priv->num_arl_entries > 2) {
1271 b53_arl_search_rd(priv, 1, &results[1]);1265 b53_arl_search_rd(priv, 1, &results[1]);
1272 ret = b53_fdb_copy(port, &results[1], fdb, cb);1266 ret = b53_fdb_copy(port, &results[1], cb, data);
1273 if (ret)1267 if (ret)
1274 return ret;1268 return ret;
1275 1269
drivers/net/dsa/b53/b53_priv.h+1−2
@@ -398,8 +398,7 @@ int b53_fdb_add(struct dsa_switch *ds, int port, · 397 unmodified lines
398int b53_fdb_del(struct dsa_switch *ds, int port,398int b53_fdb_del(struct dsa_switch *ds, int port,
399 const unsigned char *addr, u16 vid);399 const unsigned char *addr, u16 vid);
400int b53_fdb_dump(struct dsa_switch *ds, int port,400int b53_fdb_dump(struct dsa_switch *ds, int port,
401 struct switchdev_obj_port_fdb *fdb,401 dsa_fdb_dump_cb_t *cb, void *data);
402 switchdev_obj_dump_cb_t *cb);
403int b53_mirror_add(struct dsa_switch *ds, int port,402int b53_mirror_add(struct dsa_switch *ds, int port,
404 struct dsa_mall_mirror_tc_entry *mirror, bool ingress);403 struct dsa_mall_mirror_tc_entry *mirror, bool ingress);
405void b53_mirror_del(struct dsa_switch *ds, int port,404void b53_mirror_del(struct dsa_switch *ds, int port,
drivers/net/dsa/microchip/ksz_common.c+6−14
@@ -805,12 +805,11 @@ static void convert_alu(struct alu_struct *alu, u32 *alu_table) · 804 unmodified lines
805}805}
806 806
807static int ksz_port_fdb_dump(struct dsa_switch *ds, int port,807static int ksz_port_fdb_dump(struct dsa_switch *ds, int port,
808 struct switchdev_obj_port_fdb *fdb,808 dsa_fdb_dump_cb_t *cb, void *data)
809 switchdev_obj_dump_cb_t *cb)
810{809{
811 struct ksz_device *dev = ds->priv;810 struct ksz_device *dev = ds->priv;
812 int ret = 0;811 int ret = 0;
813 u32 data;812 u32 ksz_data;
814 u32 alu_table[4];813 u32 alu_table[4];
815 struct alu_struct alu;814 struct alu_struct alu;
816 int timeout;815 int timeout;
@@ -823,8 +822,8 @@ static int ksz_port_fdb_dump(struct dsa_switch *ds, int port, · 6 unmodified lines
823 do {822 do {
824 timeout = 1000;823 timeout = 1000;
825 do {824 do {
826 ksz_read32(dev, REG_SW_ALU_CTRL__4, &data);825 ksz_read32(dev, REG_SW_ALU_CTRL__4, &ksz_data);
827 if ((data & ALU_VALID) || !(data & ALU_START))826 if ((ksz_data & ALU_VALID) || !(ksz_data & ALU_START))
828 break;827 break;
829 usleep_range(1, 10);828 usleep_range(1, 10);
830 } while (timeout-- > 0);829 } while (timeout-- > 0);
@@ -841,18 +840,11 @@ static int ksz_port_fdb_dump(struct dsa_switch *ds, int port, · 10 unmodified lines
841 convert_alu(&alu, alu_table);840 convert_alu(&alu, alu_table);
842 841
843 if (alu.port_forward & BIT(port)) {842 if (alu.port_forward & BIT(port)) {
844 fdb->vid = alu.fid;843 ret = cb(alu.mac, alu.fid, alu.is_static, data);
845 if (alu.is_static)
846 fdb->ndm_state = NUD_NOARP;
847 else
848 fdb->ndm_state = NUD_REACHABLE;
849 ether_addr_copy(fdb->addr, alu.mac);
850
851 ret = cb(&fdb->obj);
852 if (ret)844 if (ret)
853 goto exit;845 goto exit;
854 }846 }
855 } while (data & ALU_START);847 } while (ksz_data & ALU_START);
856 848
857exit:849exit:
858 850
drivers/net/dsa/mt7530.c+3−7
@@ -834,8 +834,7 @@ mt7530_port_fdb_del(struct dsa_switch *ds, int port, · 833 unmodified lines
834 834
835static int835static int
836mt7530_port_fdb_dump(struct dsa_switch *ds, int port,836mt7530_port_fdb_dump(struct dsa_switch *ds, int port,
837 struct switchdev_obj_port_fdb *fdb,837 dsa_fdb_dump_cb_t *cb, void *data)
838 switchdev_obj_dump_cb_t *cb)
839{838{
840 struct mt7530_priv *priv = ds->priv;839 struct mt7530_priv *priv = ds->priv;
841 struct mt7530_fdb _fdb = { 0 };840 struct mt7530_fdb _fdb = { 0 };
@@ -853,11 +852,8 @@ mt7530_port_fdb_dump(struct dsa_switch *ds, int port, · 11 unmodified lines
853 if (rsp & ATC_SRCH_HIT) {852 if (rsp & ATC_SRCH_HIT) {
854 mt7530_fdb_read(priv, &_fdb);853 mt7530_fdb_read(priv, &_fdb);
855 if (_fdb.port_mask & BIT(port)) {854 if (_fdb.port_mask & BIT(port)) {
856 ether_addr_copy(fdb->addr, _fdb.mac);855 ret = cb(_fdb.mac, _fdb.vid, _fdb.noarp,
857 fdb->vid = _fdb.vid;856 data);
858 fdb->ndm_state = _fdb.noarp ?
859 NUD_NOARP : NUD_REACHABLE;
860 ret = cb(&fdb->obj);
861 if (ret < 0)857 if (ret < 0)
862 break;858 break;
863 }859 }
drivers/net/dsa/mv88e6xxx/chip.c+12−26
@@ -1381,10 +1381,10 @@ static int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, · 1380 unmodified lines
1381 1381
1382static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,1382static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
1383 u16 fid, u16 vid, int port,1383 u16 fid, u16 vid, int port,
1384 struct switchdev_obj *obj,1384 dsa_fdb_dump_cb_t *cb, void *data)
1385 switchdev_obj_dump_cb_t *cb)
1386{1385{
1387 struct mv88e6xxx_atu_entry addr;1386 struct mv88e6xxx_atu_entry addr;
1387 bool is_static;
1388 int err;1388 int err;
1389 1389
1390 addr.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;1390 addr.state = MV88E6XXX_G1_ATU_DATA_STATE_UNUSED;
@@ -1401,24 +1401,12 @@ static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip, · 10 unmodified lines
1401 if (addr.trunk || (addr.portvec & BIT(port)) == 0)1401 if (addr.trunk || (addr.portvec & BIT(port)) == 0)
1402 continue;1402 continue;
1403 1403
1404 if (obj->id == SWITCHDEV_OBJ_ID_PORT_FDB) {1404 if (!is_unicast_ether_addr(addr.mac))
1405 struct switchdev_obj_port_fdb *fdb;1405 continue;
1406
1407 if (!is_unicast_ether_addr(addr.mac))
1408 continue;
1409
1410 fdb = SWITCHDEV_OBJ_PORT_FDB(obj);
1411 fdb->vid = vid;
1412 ether_addr_copy(fdb->addr, addr.mac);
1413 if (addr.state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC)
1414 fdb->ndm_state = NUD_NOARP;
1415 else
1416 fdb->ndm_state = NUD_REACHABLE;
1417 } else {
1418 return -EOPNOTSUPP;
1419 }
1420 1406
1421 err = cb(obj);1407 is_static = (addr.state ==
1408 MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
1409 err = cb(addr.mac, vid, is_static, data);
1422 if (err)1410 if (err)
1423 return err;1411 return err;
1424 } while (!is_broadcast_ether_addr(addr.mac));1412 } while (!is_broadcast_ether_addr(addr.mac));
@@ -1427,8 +1415,7 @@ static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip, · 2 unmodified lines
1427}1415}
1428 1416
1429static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,1417static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
1430 struct switchdev_obj *obj,1418 dsa_fdb_dump_cb_t *cb, void *data)
1431 switchdev_obj_dump_cb_t *cb)
1432{1419{
1433 struct mv88e6xxx_vtu_entry vlan = {1420 struct mv88e6xxx_vtu_entry vlan = {
1434 .vid = chip->info->max_vid,1421 .vid = chip->info->max_vid,
@@ -1441,7 +1428,7 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port, · 6 unmodified lines
1441 if (err)1428 if (err)
1442 return err;1429 return err;
1443 1430
1444 err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, obj, cb);1431 err = mv88e6xxx_port_db_dump_fid(chip, fid, 0, port, cb, data);
1445 if (err)1432 if (err)
1446 return err;1433 return err;
1447 1434
@@ -1455,7 +1442,7 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port, · 7 unmodified lines
1455 break;1442 break;
1456 1443
1457 err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,1444 err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
1458 obj, cb);1445 cb, data);
1459 if (err)1446 if (err)
1460 return err;1447 return err;
1461 } while (vlan.vid < chip->info->max_vid);1448 } while (vlan.vid < chip->info->max_vid);
@@ -1464,14 +1451,13 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port, · 2 unmodified lines
1464}1451}
1465 1452
1466static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,1453static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
1467 struct switchdev_obj_port_fdb *fdb,1454 dsa_fdb_dump_cb_t *cb, void *data)
1468 switchdev_obj_dump_cb_t *cb)
1469{1455{
1470 struct mv88e6xxx_chip *chip = ds->priv;1456 struct mv88e6xxx_chip *chip = ds->priv;
1471 int err;1457 int err;
1472 1458
1473 mutex_lock(&chip->reg_lock);1459 mutex_lock(&chip->reg_lock);
1474 err = mv88e6xxx_port_db_dump(chip, port, &fdb->obj, cb);1460 err = mv88e6xxx_port_db_dump(chip, port, cb, data);
1475 mutex_unlock(&chip->reg_lock);1461 mutex_unlock(&chip->reg_lock);
1476 1462
1477 return err;1463 return err;
drivers/net/dsa/qca8k.c+4−11
@@ -801,27 +801,20 @@ qca8k_port_fdb_del(struct dsa_switch *ds, int port, · 800 unmodified lines
801 801
802static int802static int
803qca8k_port_fdb_dump(struct dsa_switch *ds, int port,803qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
804 struct switchdev_obj_port_fdb *fdb,804 dsa_fdb_dump_cb_t *cb, void *data)
805 switchdev_obj_dump_cb_t *cb)
806{805{
807 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;806 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
808 struct qca8k_fdb _fdb = { 0 };807 struct qca8k_fdb _fdb = { 0 };
809 int cnt = QCA8K_NUM_FDB_RECORDS;808 int cnt = QCA8K_NUM_FDB_RECORDS;
809 bool is_static;
810 int ret = 0;810 int ret = 0;
811 811
812 mutex_lock(&priv->reg_mutex);812 mutex_lock(&priv->reg_mutex);
813 while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {813 while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
814 if (!_fdb.aging)814 if (!_fdb.aging)
815 break;815 break;
816 816 is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
817 ether_addr_copy(fdb->addr, _fdb.mac);817 ret = cb(_fdb.mac, _fdb.vid, is_static, data);
818 fdb->vid = _fdb.vid;
819 if (_fdb.aging == QCA8K_ATU_STATUS_STATIC)
820 fdb->ndm_state = NUD_NOARP;
821 else
822 fdb->ndm_state = NUD_REACHABLE;
823
824 ret = cb(&fdb->obj);
825 if (ret)818 if (ret)
826 break;819 break;
827 }820 }
include/net/dsa.h+3−2
@@ -272,6 +272,8 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds) · 271 unmodified lines
272 return ds->rtable[dst->cpu_dp->ds->index];272 return ds->rtable[dst->cpu_dp->ds->index];
273}273}
274 274
275typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid,
276 bool is_static, void *data);
275struct dsa_switch_ops {277struct dsa_switch_ops {
276 /*278 /*
277 * Legacy probing.279 * Legacy probing.
@@ -386,8 +388,7 @@ struct dsa_switch_ops { · 108 unmodified lines
386 int (*port_fdb_del)(struct dsa_switch *ds, int port,388 int (*port_fdb_del)(struct dsa_switch *ds, int port,
387 const unsigned char *addr, u16 vid);389 const unsigned char *addr, u16 vid);
388 int (*port_fdb_dump)(struct dsa_switch *ds, int port,390 int (*port_fdb_dump)(struct dsa_switch *ds, int port,
389 struct switchdev_obj_port_fdb *fdb,391 dsa_fdb_dump_cb_t *cb, void *data);
390 switchdev_obj_dump_cb_t *cb);
391 392
392 /*393 /*
393 * Multicast database394 * Multicast database
include/net/switchdev.h+0−12
@@ -208,9 +208,6 @@ int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], · 207 unmodified lines
208int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],208int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
209 struct net_device *dev, const unsigned char *addr,209 struct net_device *dev, const unsigned char *addr,
210 u16 vid);210 u16 vid);
211int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
212 struct net_device *dev,
213 struct net_device *filter_dev, int *idx);
214void switchdev_port_fwd_mark_set(struct net_device *dev,211void switchdev_port_fwd_mark_set(struct net_device *dev,
215 struct net_device *group_dev,212 struct net_device *group_dev,
216 bool joining);213 bool joining);
@@ -309,15 +306,6 @@ static inline int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], · 92 unmodified lines
309 return -EOPNOTSUPP;306 return -EOPNOTSUPP;
310}307}
311 308
312static inline int switchdev_port_fdb_dump(struct sk_buff *skb,
313 struct netlink_callback *cb,
314 struct net_device *dev,
315 struct net_device *filter_dev,
316 int *idx)
317{
318 return *idx;
319}
320
321static inline bool switchdev_port_same_parent_id(struct net_device *a,309static inline bool switchdev_port_same_parent_id(struct net_device *a,
322 struct net_device *b)310 struct net_device *b)
323{311{
net/dsa/dsa_priv.h+0−2
@@ -133,8 +133,6 @@ int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr, · 132 unmodified lines
133 u16 vid);133 u16 vid);
134int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,134int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
135 u16 vid);135 u16 vid);
136int dsa_port_fdb_dump(struct dsa_port *dp, struct switchdev_obj_port_fdb *fdb,
137 switchdev_obj_dump_cb_t *cb);
138int dsa_port_mdb_add(struct dsa_port *dp,136int dsa_port_mdb_add(struct dsa_port *dp,
139 const struct switchdev_obj_port_mdb *mdb,137 const struct switchdev_obj_port_mdb *mdb,
140 struct switchdev_trans *trans);138 struct switchdev_trans *trans);
net/dsa/port.c+0−11
@@ -173,17 +173,6 @@ int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr, · 172 unmodified lines
173 return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info);173 return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info);
174}174}
175 175
176int dsa_port_fdb_dump(struct dsa_port *dp, struct switchdev_obj_port_fdb *fdb,
177 switchdev_obj_dump_cb_t *cb)
178{
179 struct dsa_switch *ds = dp->ds;
180
181 if (ds->ops->port_fdb_dump)
182 return ds->ops->port_fdb_dump(ds, dp->index, fdb, cb);
183
184 return -EOPNOTSUPP;
185}
186
187int dsa_port_mdb_add(struct dsa_port *dp,176int dsa_port_mdb_add(struct dsa_port *dp,
188 const struct switchdev_obj_port_mdb *mdb,177 const struct switchdev_obj_port_mdb *mdb,
189 struct switchdev_trans *trans)178 struct switchdev_trans *trans)
net/dsa/slave.c+78−22
@@ -199,6 +199,83 @@ out: · 198 unmodified lines
199 return 0;199 return 0;
200}200}
201 201
202struct dsa_slave_dump_ctx {
203 struct net_device *dev;
204 struct sk_buff *skb;
205 struct netlink_callback *cb;
206 int idx;
207};
208
209static int
210dsa_slave_port_fdb_do_dump(const unsigned char *addr, u16 vid,
211 bool is_static, void *data)
212{
213 struct dsa_slave_dump_ctx *dump = data;
214 u32 portid = NETLINK_CB(dump->cb->skb).portid;
215 u32 seq = dump->cb->nlh->nlmsg_seq;
216 struct nlmsghdr *nlh;
217 struct ndmsg *ndm;
218
219 if (dump->idx < dump->cb->args[2])
220 goto skip;
221
222 nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
223 sizeof(*ndm), NLM_F_MULTI);
224 if (!nlh)
225 return -EMSGSIZE;
226
227 ndm = nlmsg_data(nlh);
228 ndm->ndm_family = AF_BRIDGE;
229 ndm->ndm_pad1 = 0;
230 ndm->ndm_pad2 = 0;
231 ndm->ndm_flags = NTF_SELF;
232 ndm->ndm_type = 0;
233 ndm->ndm_ifindex = dump->dev->ifindex;
234 ndm->ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE;
235
236 if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, addr))
237 goto nla_put_failure;
238
239 if (vid && nla_put_u16(dump->skb, NDA_VLAN, vid))
240 goto nla_put_failure;
241
242 nlmsg_end(dump->skb, nlh);
243
244skip:
245 dump->idx++;
246 return 0;
247
248nla_put_failure:
249 nlmsg_cancel(dump->skb, nlh);
250 return -EMSGSIZE;
251}
252
253static int
254dsa_slave_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
255 struct net_device *dev, struct net_device *filter_dev,
256 int *idx)
257{
258 struct dsa_slave_dump_ctx dump = {
259 .dev = dev,
260 .skb = skb,
261 .cb = cb,
262 .idx = *idx,
263 };
264 struct dsa_slave_priv *p = netdev_priv(dev);
265 struct dsa_port *dp = p->dp;
266 struct dsa_switch *ds = dp->ds;
267 int err;
268
269 if (!ds->ops->port_fdb_dump)
270 return -EOPNOTSUPP;
271
272 err = ds->ops->port_fdb_dump(ds, dp->index,
273 dsa_slave_port_fdb_do_dump,
274 &dump);
275 *idx = dump.idx;
276 return err;
277}
278
202static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)279static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
203{280{
204 struct dsa_slave_priv *p = netdev_priv(dev);281 struct dsa_slave_priv *p = netdev_priv(dev);
@@ -287,26 +364,6 @@ static int dsa_slave_port_obj_del(struct net_device *dev, · 82 unmodified lines
287 return err;364 return err;
288}365}
289 366
290static int dsa_slave_port_obj_dump(struct net_device *dev,
291 struct switchdev_obj *obj,
292 switchdev_obj_dump_cb_t *cb)
293{
294 struct dsa_slave_priv *p = netdev_priv(dev);
295 struct dsa_port *dp = p->dp;
296 int err;
297
298 switch (obj->id) {
299 case SWITCHDEV_OBJ_ID_PORT_FDB:
300 err = dsa_port_fdb_dump(dp, SWITCHDEV_OBJ_PORT_FDB(obj), cb);
301 break;
302 default:
303 err = -EOPNOTSUPP;
304 break;
305 }
306
307 return err;
308}
309
310static int dsa_slave_port_attr_get(struct net_device *dev,367static int dsa_slave_port_attr_get(struct net_device *dev,
311 struct switchdev_attr *attr)368 struct switchdev_attr *attr)
312{369{
@@ -974,7 +1031,7 @@ static const struct net_device_ops dsa_slave_netdev_ops = { · 661 unmodified lines
974 .ndo_set_mac_address = dsa_slave_set_mac_address,1031 .ndo_set_mac_address = dsa_slave_set_mac_address,
975 .ndo_fdb_add = dsa_legacy_fdb_add,1032 .ndo_fdb_add = dsa_legacy_fdb_add,
976 .ndo_fdb_del = dsa_legacy_fdb_del,1033 .ndo_fdb_del = dsa_legacy_fdb_del,
977 .ndo_fdb_dump = switchdev_port_fdb_dump,1034 .ndo_fdb_dump = dsa_slave_fdb_dump,
978 .ndo_do_ioctl = dsa_slave_ioctl,1035 .ndo_do_ioctl = dsa_slave_ioctl,
979 .ndo_get_iflink = dsa_slave_get_iflink,1036 .ndo_get_iflink = dsa_slave_get_iflink,
980#ifdef CONFIG_NET_POLL_CONTROLLER1037#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -992,7 +1049,6 @@ static const struct switchdev_ops dsa_slave_switchdev_ops = { · 11 unmodified lines
992 .switchdev_port_attr_set = dsa_slave_port_attr_set,1049 .switchdev_port_attr_set = dsa_slave_port_attr_set,
993 .switchdev_port_obj_add = dsa_slave_port_obj_add,1050 .switchdev_port_obj_add = dsa_slave_port_obj_add,
994 .switchdev_port_obj_del = dsa_slave_port_obj_del,1051 .switchdev_port_obj_del = dsa_slave_port_obj_del,
995 .switchdev_port_obj_dump = dsa_slave_port_obj_dump,
996};1052};
997 1053
998static struct device_type dsa_type = {1054static struct device_type dsa_type = {
net/switchdev/switchdev.c+0−84
@@ -1009,90 +1009,6 @@ int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], · 1008 unmodified lines
1009}1009}
1010EXPORT_SYMBOL_GPL(switchdev_port_fdb_del);1010EXPORT_SYMBOL_GPL(switchdev_port_fdb_del);
1011 1011
1012struct switchdev_fdb_dump {
1013 struct switchdev_obj_port_fdb fdb;
1014 struct net_device *dev;
1015 struct sk_buff *skb;
1016 struct netlink_callback *cb;
1017 int idx;
1018};
1019
1020static int switchdev_port_fdb_dump_cb(struct switchdev_obj *obj)
1021{
1022 struct switchdev_obj_port_fdb *fdb = SWITCHDEV_OBJ_PORT_FDB(obj);
1023 struct switchdev_fdb_dump *dump =
1024 container_of(fdb, struct switchdev_fdb_dump, fdb);
1025 u32 portid = NETLINK_CB(dump->cb->skb).portid;
1026 u32 seq = dump->cb->nlh->nlmsg_seq;
1027 struct nlmsghdr *nlh;
1028 struct ndmsg *ndm;
1029
1030 if (dump->idx < dump->cb->args[2])
1031 goto skip;
1032
1033 nlh = nlmsg_put(dump->skb, portid, seq, RTM_NEWNEIGH,
1034 sizeof(*ndm), NLM_F_MULTI);
1035 if (!nlh)
1036 return -EMSGSIZE;
1037
1038 ndm = nlmsg_data(nlh);
1039 ndm->ndm_family = AF_BRIDGE;
1040 ndm->ndm_pad1 = 0;
1041 ndm->ndm_pad2 = 0;
1042 ndm->ndm_flags = NTF_SELF;
1043 ndm->ndm_type = 0;
1044 ndm->ndm_ifindex = dump->dev->ifindex;
1045 ndm->ndm_state = fdb->ndm_state;
1046
1047 if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, fdb->addr))
1048 goto nla_put_failure;
1049
1050 if (fdb->vid && nla_put_u16(dump->skb, NDA_VLAN, fdb->vid))
1051 goto nla_put_failure;
1052
1053 nlmsg_end(dump->skb, nlh);
1054
1055skip:
1056 dump->idx++;
1057 return 0;
1058
1059nla_put_failure:
1060 nlmsg_cancel(dump->skb, nlh);
1061 return -EMSGSIZE;
1062}
1063
1064/**
1065 * switchdev_port_fdb_dump - Dump port FDB (MAC/VLAN) entries
1066 *
1067 * @skb: netlink skb
1068 * @cb: netlink callback
1069 * @dev: port device
1070 * @filter_dev: filter device
1071 * @idx:
1072 *
1073 * Dump FDB entries from switch device.
1074 */
1075int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
1076 struct net_device *dev,
1077 struct net_device *filter_dev, int *idx)
1078{
1079 struct switchdev_fdb_dump dump = {
1080 .fdb.obj.orig_dev = dev,
1081 .fdb.obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
1082 .dev = dev,
1083 .skb = skb,
1084 .cb = cb,
1085 .idx = *idx,
1086 };
1087 int err;
1088
1089 err = switchdev_port_obj_dump(dev, &dump.fdb.obj,
1090 switchdev_port_fdb_dump_cb);
1091 *idx = dump.idx;
1092 return err;
1093}
1094EXPORT_SYMBOL_GPL(switchdev_port_fdb_dump);
1095
1096bool switchdev_port_same_parent_id(struct net_device *a,1012bool switchdev_port_same_parent_id(struct net_device *a,
1097 struct net_device *b)1013 struct net_device *b)
1098{1014{