diff options
Diffstat (limited to 'net/switchdev/switchdev.c')
-rw-r--r-- | net/switchdev/switchdev.c | 85 |
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 | } |
1307 | EXPORT_SYMBOL_GPL(switchdev_port_same_parent_id); | 1307 | EXPORT_SYMBOL_GPL(switchdev_port_same_parent_id); |
1308 | |||
1309 | static 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 | |||
1326 | static 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 | */ | ||
1370 | void 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 | } | ||
1392 | EXPORT_SYMBOL_GPL(switchdev_port_fwd_mark_set); | ||