Skip to content

Commit 2e359b0

Browse files
vladimirolteanPaolo Abeni
authored andcommitted
net: dsa: propagate extack to port_lag_join
Drivers could refuse to offload a LAG configuration for a variety of reasons, mainly having to do with its TX type. Additionally, since DSA masters may now also be LAG interfaces, and this will translate into a call to port_lag_join on the CPU ports, there may be extra restrictions there. Propagate the netlink extack to this DSA method in order for drivers to give a meaningful error message back to the user. Signed-off-by: Vladimir Oltean <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 13eccc1 commit 2e359b0

File tree

11 files changed

+60
-28
lines changed

11 files changed

+60
-28
lines changed

drivers/net/dsa/mv88e6xxx/chip.c

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6593,14 +6593,17 @@ static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port,
65936593

65946594
static bool mv88e6xxx_lag_can_offload(struct dsa_switch *ds,
65956595
struct dsa_lag lag,
6596-
struct netdev_lag_upper_info *info)
6596+
struct netdev_lag_upper_info *info,
6597+
struct netlink_ext_ack *extack)
65976598
{
65986599
struct mv88e6xxx_chip *chip = ds->priv;
65996600
struct dsa_port *dp;
66006601
int members = 0;
66016602

6602-
if (!mv88e6xxx_has_lag(chip))
6603+
if (!mv88e6xxx_has_lag(chip)) {
6604+
NL_SET_ERR_MSG_MOD(extack, "Chip does not support LAG offload");
66036605
return false;
6606+
}
66046607

66056608
if (!lag.id)
66066609
return false;
@@ -6609,14 +6612,20 @@ static bool mv88e6xxx_lag_can_offload(struct dsa_switch *ds,
66096612
/* Includes the port joining the LAG */
66106613
members++;
66116614

6612-
if (members > 8)
6615+
if (members > 8) {
6616+
NL_SET_ERR_MSG_MOD(extack,
6617+
"Cannot offload more than 8 LAG ports");
66136618
return false;
6619+
}
66146620

66156621
/* We could potentially relax this to include active
66166622
* backup in the future.
66176623
*/
6618-
if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
6624+
if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
6625+
NL_SET_ERR_MSG_MOD(extack,
6626+
"Can only offload LAG using hash TX type");
66196627
return false;
6628+
}
66206629

66216630
/* Ideally we would also validate that the hash type matches
66226631
* the hardware. Alas, this is always set to unknown on team
@@ -6769,12 +6778,13 @@ static int mv88e6xxx_port_lag_change(struct dsa_switch *ds, int port)
67696778

67706779
static int mv88e6xxx_port_lag_join(struct dsa_switch *ds, int port,
67716780
struct dsa_lag lag,
6772-
struct netdev_lag_upper_info *info)
6781+
struct netdev_lag_upper_info *info,
6782+
struct netlink_ext_ack *extack)
67736783
{
67746784
struct mv88e6xxx_chip *chip = ds->priv;
67756785
int err, id;
67766786

6777-
if (!mv88e6xxx_lag_can_offload(ds, lag, info))
6787+
if (!mv88e6xxx_lag_can_offload(ds, lag, info, extack))
67786788
return -EOPNOTSUPP;
67796789

67806790
/* DSA LAG IDs are one-based */
@@ -6827,12 +6837,13 @@ static int mv88e6xxx_crosschip_lag_change(struct dsa_switch *ds, int sw_index,
68276837

68286838
static int mv88e6xxx_crosschip_lag_join(struct dsa_switch *ds, int sw_index,
68296839
int port, struct dsa_lag lag,
6830-
struct netdev_lag_upper_info *info)
6840+
struct netdev_lag_upper_info *info,
6841+
struct netlink_ext_ack *extack)
68316842
{
68326843
struct mv88e6xxx_chip *chip = ds->priv;
68336844
int err;
68346845

6835-
if (!mv88e6xxx_lag_can_offload(ds, lag, info))
6846+
if (!mv88e6xxx_lag_can_offload(ds, lag, info, extack))
68366847
return -EOPNOTSUPP;
68376848

68386849
mv88e6xxx_reg_lock(chip);

drivers/net/dsa/ocelot/felix.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -861,11 +861,12 @@ static void felix_bridge_leave(struct dsa_switch *ds, int port,
861861

862862
static int felix_lag_join(struct dsa_switch *ds, int port,
863863
struct dsa_lag lag,
864-
struct netdev_lag_upper_info *info)
864+
struct netdev_lag_upper_info *info,
865+
struct netlink_ext_ack *extack)
865866
{
866867
struct ocelot *ocelot = ds->priv;
867868

868-
return ocelot_port_lag_join(ocelot, port, lag.dev, info);
869+
return ocelot_port_lag_join(ocelot, port, lag.dev, info, extack);
869870
}
870871

871872
static int felix_lag_leave(struct dsa_switch *ds, int port,

drivers/net/dsa/qca/qca8k-common.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,8 @@ int qca8k_port_vlan_del(struct dsa_switch *ds, int port,
10171017

10181018
static bool qca8k_lag_can_offload(struct dsa_switch *ds,
10191019
struct dsa_lag lag,
1020-
struct netdev_lag_upper_info *info)
1020+
struct netdev_lag_upper_info *info,
1021+
struct netlink_ext_ack *extack)
10211022
{
10221023
struct dsa_port *dp;
10231024
int members = 0;
@@ -1029,15 +1030,24 @@ static bool qca8k_lag_can_offload(struct dsa_switch *ds,
10291030
/* Includes the port joining the LAG */
10301031
members++;
10311032

1032-
if (members > QCA8K_NUM_PORTS_FOR_LAG)
1033+
if (members > QCA8K_NUM_PORTS_FOR_LAG) {
1034+
NL_SET_ERR_MSG_MOD(extack,
1035+
"Cannot offload more than 4 LAG ports");
10331036
return false;
1037+
}
10341038

1035-
if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
1039+
if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
1040+
NL_SET_ERR_MSG_MOD(extack,
1041+
"Can only offload LAG using hash TX type");
10361042
return false;
1043+
}
10371044

10381045
if (info->hash_type != NETDEV_LAG_HASH_L2 &&
1039-
info->hash_type != NETDEV_LAG_HASH_L23)
1046+
info->hash_type != NETDEV_LAG_HASH_L23) {
1047+
NL_SET_ERR_MSG_MOD(extack,
1048+
"Can only offload L2 or L2+L3 TX hash");
10401049
return false;
1050+
}
10411051

10421052
return true;
10431053
}
@@ -1160,11 +1170,12 @@ static int qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port,
11601170
}
11611171

11621172
int qca8k_port_lag_join(struct dsa_switch *ds, int port, struct dsa_lag lag,
1163-
struct netdev_lag_upper_info *info)
1173+
struct netdev_lag_upper_info *info,
1174+
struct netlink_ext_ack *extack)
11641175
{
11651176
int ret;
11661177

1167-
if (!qca8k_lag_can_offload(ds, lag, info))
1178+
if (!qca8k_lag_can_offload(ds, lag, info, extack))
11681179
return -EOPNOTSUPP;
11691180

11701181
ret = qca8k_lag_setup_hash(ds, lag, info);

drivers/net/dsa/qca/qca8k.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,8 @@ int qca8k_port_vlan_del(struct dsa_switch *ds, int port,
512512

513513
/* Common port LAG function */
514514
int qca8k_port_lag_join(struct dsa_switch *ds, int port, struct dsa_lag lag,
515-
struct netdev_lag_upper_info *info);
515+
struct netdev_lag_upper_info *info,
516+
struct netlink_ext_ack *extack);
516517
int qca8k_port_lag_leave(struct dsa_switch *ds, int port,
517518
struct dsa_lag lag);
518519

drivers/net/ethernet/mscc/ocelot.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,10 +2132,14 @@ static void ocelot_migrate_lag_fdbs(struct ocelot *ocelot,
21322132

21332133
int ocelot_port_lag_join(struct ocelot *ocelot, int port,
21342134
struct net_device *bond,
2135-
struct netdev_lag_upper_info *info)
2135+
struct netdev_lag_upper_info *info,
2136+
struct netlink_ext_ack *extack)
21362137
{
2137-
if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
2138+
if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
2139+
NL_SET_ERR_MSG_MOD(extack,
2140+
"Can only offload LAG using hash TX type");
21382141
return -EOPNOTSUPP;
2142+
}
21392143

21402144
mutex_lock(&ocelot->fwd_domain_lock);
21412145

drivers/net/ethernet/mscc/ocelot_net.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,11 +1412,10 @@ static int ocelot_netdevice_lag_join(struct net_device *dev,
14121412
int port = priv->port.index;
14131413
int err;
14141414

1415-
err = ocelot_port_lag_join(ocelot, port, bond, info);
1416-
if (err == -EOPNOTSUPP) {
1417-
NL_SET_ERR_MSG_MOD(extack, "Offloading not supported");
1415+
err = ocelot_port_lag_join(ocelot, port, bond, info, extack);
1416+
if (err == -EOPNOTSUPP)
1417+
/* Offloading not supported, fall back to software LAG */
14181418
return 0;
1419-
}
14201419

14211420
bridge_dev = netdev_master_upper_dev_get(bond);
14221421
if (!bridge_dev || !netif_is_bridge_master(bridge_dev))

include/net/dsa.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,8 @@ struct dsa_switch_ops {
10941094
int port);
10951095
int (*crosschip_lag_join)(struct dsa_switch *ds, int sw_index,
10961096
int port, struct dsa_lag lag,
1097-
struct netdev_lag_upper_info *info);
1097+
struct netdev_lag_upper_info *info,
1098+
struct netlink_ext_ack *extack);
10981099
int (*crosschip_lag_leave)(struct dsa_switch *ds, int sw_index,
10991100
int port, struct dsa_lag lag);
11001101

@@ -1169,7 +1170,8 @@ struct dsa_switch_ops {
11691170
int (*port_lag_change)(struct dsa_switch *ds, int port);
11701171
int (*port_lag_join)(struct dsa_switch *ds, int port,
11711172
struct dsa_lag lag,
1172-
struct netdev_lag_upper_info *info);
1173+
struct netdev_lag_upper_info *info,
1174+
struct netlink_ext_ack *extack);
11731175
int (*port_lag_leave)(struct dsa_switch *ds, int port,
11741176
struct dsa_lag lag);
11751177

include/soc/mscc/ocelot.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,8 @@ int ocelot_port_mdb_del(struct ocelot *ocelot, int port,
12291229
const struct net_device *bridge);
12301230
int ocelot_port_lag_join(struct ocelot *ocelot, int port,
12311231
struct net_device *bond,
1232-
struct netdev_lag_upper_info *info);
1232+
struct netdev_lag_upper_info *info,
1233+
struct netlink_ext_ack *extack);
12331234
void ocelot_port_lag_leave(struct ocelot *ocelot, int port,
12341235
struct net_device *bond);
12351236
void ocelot_port_lag_change(struct ocelot *ocelot, int port, bool lag_tx_active);

net/dsa/dsa_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ struct dsa_notifier_lag_info {
8888
const struct dsa_port *dp;
8989
struct dsa_lag lag;
9090
struct netdev_lag_upper_info *info;
91+
struct netlink_ext_ack *extack;
9192
};
9293

9394
/* DSA_NOTIFIER_VLAN_* */

net/dsa/port.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,7 @@ int dsa_port_lag_join(struct dsa_port *dp, struct net_device *lag_dev,
635635
struct dsa_notifier_lag_info info = {
636636
.dp = dp,
637637
.info = uinfo,
638+
.extack = extack,
638639
};
639640
struct net_device *bridge_dev;
640641
int err;

net/dsa/switch.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,12 +507,12 @@ static int dsa_switch_lag_join(struct dsa_switch *ds,
507507
{
508508
if (info->dp->ds == ds && ds->ops->port_lag_join)
509509
return ds->ops->port_lag_join(ds, info->dp->index, info->lag,
510-
info->info);
510+
info->info, info->extack);
511511

512512
if (info->dp->ds != ds && ds->ops->crosschip_lag_join)
513513
return ds->ops->crosschip_lag_join(ds, info->dp->ds->index,
514514
info->dp->index, info->lag,
515-
info->info);
515+
info->info, info->extack);
516516

517517
return -EOPNOTSUPP;
518518
}

0 commit comments

Comments
 (0)