Skip to content

Commit 3535d70

Browse files
vladimirolteankuba-moo
authored andcommitted
net: dsa: allow matchall mirroring rules towards the CPU
If the CPU bandwidth capacity permits, it may be useful to mirror the entire ingress of a user port to software. This is in fact possible to express even if there is no net_device representation for the CPU port. In fact, that approach was already exhausted and that representation wouldn't have even helped [1]. The idea behind implementing this is that currently, we refuse to offload any mirroring towards a non-DSA target net_device. But if we acknowledge the fact that to reach any foreign net_device, the switch must send the packet to the CPU anyway, then we can simply offload just that part, and let the software do the rest. There is only one condition we need to uphold: the filter needs to be present in the software data path as well (no skip_sw). There are 2 actions to consider: FLOW_ACTION_MIRRED (redirect to egress of target interface) and FLOW_ACTION_MIRRED_INGRESS (redirect to ingress of target interface). We don't have the ability/API to offload FLOW_ACTION_MIRRED_INGRESS when the target port is also a DSA user port, but we could also permit that through mirred to the CPU + software. Example: $ ip link add dummy0 type dummy; ip link set dummy0 up $ tc qdisc add dev swp0 clsact $ tc filter add dev swp0 ingress matchall action mirred ingress mirror dev dummy0 Any DSA driver with a ds->ops->port_mirror_add() implementation can now make use of this with no additional change. [1] https://lore.kernel.org/netdev/[email protected]/ Signed-off-by: Vladimir Oltean <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 4cc4394 commit 3535d70

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

net/dsa/user.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,7 @@ dsa_user_mall_tc_entry_find(struct net_device *dev, unsigned long cookie)
13641364
static int
13651365
dsa_user_add_cls_matchall_mirred(struct net_device *dev,
13661366
struct tc_cls_matchall_offload *cls,
1367-
bool ingress)
1367+
bool ingress, bool ingress_target)
13681368
{
13691369
struct netlink_ext_ack *extack = cls->common.extack;
13701370
struct dsa_port *dp = dsa_user_to_port(dev);
@@ -1396,10 +1396,30 @@ dsa_user_add_cls_matchall_mirred(struct net_device *dev,
13961396
if (!act->dev)
13971397
return -EINVAL;
13981398

1399-
if (!dsa_user_dev_check(act->dev))
1400-
return -EOPNOTSUPP;
1401-
1402-
to_dp = dsa_user_to_port(act->dev);
1399+
if (dsa_user_dev_check(act->dev)) {
1400+
if (ingress_target) {
1401+
/* We can only fulfill this using software assist */
1402+
if (cls->common.skip_sw) {
1403+
NL_SET_ERR_MSG_MOD(extack,
1404+
"Can only mirred to ingress of DSA user port if filter also runs in software");
1405+
return -EOPNOTSUPP;
1406+
}
1407+
to_dp = dp->cpu_dp;
1408+
} else {
1409+
to_dp = dsa_user_to_port(act->dev);
1410+
}
1411+
} else {
1412+
/* Handle mirroring to foreign target ports as a mirror towards
1413+
* the CPU. The software tc rule will take the packets from
1414+
* there.
1415+
*/
1416+
if (cls->common.skip_sw) {
1417+
NL_SET_ERR_MSG_MOD(extack,
1418+
"Can only mirred to CPU if filter also runs in software");
1419+
return -EOPNOTSUPP;
1420+
}
1421+
to_dp = dp->cpu_dp;
1422+
}
14031423

14041424
if (dp->ds != to_dp->ds) {
14051425
NL_SET_ERR_MSG_MOD(extack,
@@ -1503,7 +1523,11 @@ static int dsa_user_add_cls_matchall(struct net_device *dev,
15031523

15041524
switch (action->entries[0].id) {
15051525
case FLOW_ACTION_MIRRED:
1506-
return dsa_user_add_cls_matchall_mirred(dev, cls, ingress);
1526+
return dsa_user_add_cls_matchall_mirred(dev, cls, ingress,
1527+
false);
1528+
case FLOW_ACTION_MIRRED_INGRESS:
1529+
return dsa_user_add_cls_matchall_mirred(dev, cls, ingress,
1530+
true);
15071531
case FLOW_ACTION_POLICE:
15081532
return dsa_user_add_cls_matchall_police(dev, cls, ingress);
15091533
default:

0 commit comments

Comments
 (0)