summaryrefslogtreecommitdiffstats
path: root/net/switchdev/switchdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/switchdev/switchdev.c')
-rw-r--r--net/switchdev/switchdev.c85
1 files changed, 0 insertions, 85 deletions
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 2c683f24d557..1031a0327fff 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -1305,88 +1305,3 @@ bool switchdev_port_same_parent_id(struct net_device *a,
1305 return netdev_phys_item_id_same(&a_attr.u.ppid, &b_attr.u.ppid); 1305 return netdev_phys_item_id_same(&a_attr.u.ppid, &b_attr.u.ppid);
1306} 1306}
1307EXPORT_SYMBOL_GPL(switchdev_port_same_parent_id); 1307EXPORT_SYMBOL_GPL(switchdev_port_same_parent_id);
1308
1309static u32 switchdev_port_fwd_mark_get(struct net_device *dev,
1310 struct net_device *group_dev)
1311{
1312 struct net_device *lower_dev;
1313 struct list_head *iter;
1314
1315 netdev_for_each_lower_dev(group_dev, lower_dev, iter) {
1316 if (lower_dev == dev)
1317 continue;
1318 if (switchdev_port_same_parent_id(dev, lower_dev))
1319 return lower_dev->offload_fwd_mark;
1320 return switchdev_port_fwd_mark_get(dev, lower_dev);
1321 }
1322
1323 return dev->ifindex;
1324}
1325
1326static void switchdev_port_fwd_mark_reset(struct net_device *group_dev,
1327 u32 old_mark, u32 *reset_mark)
1328{
1329 struct net_device *lower_dev;
1330 struct list_head *iter;
1331
1332 netdev_for_each_lower_dev(group_dev, lower_dev, iter) {
1333 if (lower_dev->offload_fwd_mark == old_mark) {
1334 if (!*reset_mark)
1335 *reset_mark = lower_dev->ifindex;
1336 lower_dev->offload_fwd_mark = *reset_mark;
1337 }
1338 switchdev_port_fwd_mark_reset(lower_dev, old_mark, reset_mark);
1339 }
1340}
1341
1342/**
1343 * switchdev_port_fwd_mark_set - Set port offload forwarding mark
1344 *
1345 * @dev: port device
1346 * @group_dev: containing device
1347 * @joining: true if dev is joining group; false if leaving group
1348 *
1349 * An ungrouped port's offload mark is just its ifindex. A grouped
1350 * port's (member of a bridge, for example) offload mark is the ifindex
1351 * of one of the ports in the group with the same parent (switch) ID.
1352 * Ports on the same device in the same group will have the same mark.
1353 *
1354 * Example:
1355 *
1356 * br0 ifindex=9
1357 * sw1p1 ifindex=2 mark=2
1358 * sw1p2 ifindex=3 mark=2
1359 * sw2p1 ifindex=4 mark=5
1360 * sw2p2 ifindex=5 mark=5
1361 *
1362 * If sw2p2 leaves the bridge, we'll have:
1363 *
1364 * br0 ifindex=9
1365 * sw1p1 ifindex=2 mark=2
1366 * sw1p2 ifindex=3 mark=2
1367 * sw2p1 ifindex=4 mark=4
1368 * sw2p2 ifindex=5 mark=5
1369 */
1370void switchdev_port_fwd_mark_set(struct net_device *dev,
1371 struct net_device *group_dev,
1372 bool joining)
1373{
1374 u32 mark = dev->ifindex;
1375 u32 reset_mark = 0;
1376
1377 if (group_dev) {
1378 ASSERT_RTNL();
1379 if (joining)
1380 mark = switchdev_port_fwd_mark_get(dev, group_dev);
1381 else if (dev->offload_fwd_mark == mark)
1382 /* Ohoh, this port was the mark reference port,
1383 * but it's leaving the group, so reset the
1384 * mark for the remaining ports in the group.
1385 */
1386 switchdev_port_fwd_mark_reset(group_dev, mark,
1387 &reset_mark);
1388 }
1389
1390 dev->offload_fwd_mark = mark;
1391}
1392EXPORT_SYMBOL_GPL(switchdev_port_fwd_mark_set);