Skip to content

Commit f8fa9b4

Browse files
dsaherndavem330
authored andcommitted
mlxsw: spectrum_router: Add extack message for RIF and VRF overflow
Add extack argument down to mlxsw_sp_rif_create and mlxsw_sp_vr_create to set an error message on RIF or VR overflow. Now on overflow of either resource the user gets an informative message as opposed to failing with EBUSY. Signed-off-by: David Ahern <dsahern@gmail.com> Reviewed-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 89d5dd2 commit f8fa9b4

File tree

1 file changed

+69
-45
lines changed

1 file changed

+69
-45
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

Lines changed: 69 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -731,14 +731,17 @@ static struct mlxsw_sp_fib *mlxsw_sp_vr_fib(const struct mlxsw_sp_vr *vr,
731731
}
732732

733733
static struct mlxsw_sp_vr *mlxsw_sp_vr_create(struct mlxsw_sp *mlxsw_sp,
734-
u32 tb_id)
734+
u32 tb_id,
735+
struct netlink_ext_ack *extack)
735736
{
736737
struct mlxsw_sp_vr *vr;
737738
int err;
738739

739740
vr = mlxsw_sp_vr_find_unused(mlxsw_sp);
740-
if (!vr)
741+
if (!vr) {
742+
NL_SET_ERR_MSG(extack, "spectrum: Exceeded number of supported virtual routers");
741743
return ERR_PTR(-EBUSY);
744+
}
742745
vr->fib4 = mlxsw_sp_fib_create(vr, MLXSW_SP_L3_PROTO_IPV4);
743746
if (IS_ERR(vr->fib4))
744747
return ERR_CAST(vr->fib4);
@@ -775,14 +778,15 @@ static void mlxsw_sp_vr_destroy(struct mlxsw_sp_vr *vr)
775778
vr->fib4 = NULL;
776779
}
777780

778-
static struct mlxsw_sp_vr *mlxsw_sp_vr_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id)
781+
static struct mlxsw_sp_vr *mlxsw_sp_vr_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id,
782+
struct netlink_ext_ack *extack)
779783
{
780784
struct mlxsw_sp_vr *vr;
781785

782786
tb_id = mlxsw_sp_fix_tb_id(tb_id);
783787
vr = mlxsw_sp_vr_find(mlxsw_sp, tb_id);
784788
if (!vr)
785-
vr = mlxsw_sp_vr_create(mlxsw_sp, tb_id);
789+
vr = mlxsw_sp_vr_create(mlxsw_sp, tb_id, extack);
786790
return vr;
787791
}
788792

@@ -948,7 +952,8 @@ static u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev)
948952

949953
static struct mlxsw_sp_rif *
950954
mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
951-
const struct mlxsw_sp_rif_params *params);
955+
const struct mlxsw_sp_rif_params *params,
956+
struct netlink_ext_ack *extack);
952957

953958
static struct mlxsw_sp_rif_ipip_lb *
954959
mlxsw_sp_ipip_ol_ipip_lb_create(struct mlxsw_sp *mlxsw_sp,
@@ -966,7 +971,7 @@ mlxsw_sp_ipip_ol_ipip_lb_create(struct mlxsw_sp *mlxsw_sp,
966971
.lb_config = ipip_ops->ol_loopback_config(mlxsw_sp, ol_dev),
967972
};
968973

969-
rif = mlxsw_sp_rif_create(mlxsw_sp, &lb_params.common);
974+
rif = mlxsw_sp_rif_create(mlxsw_sp, &lb_params.common, NULL);
970975
if (IS_ERR(rif))
971976
return ERR_CAST(rif);
972977
return container_of(rif, struct mlxsw_sp_rif_ipip_lb, common);
@@ -3836,7 +3841,7 @@ mlxsw_sp_fib_node_get(struct mlxsw_sp *mlxsw_sp, u32 tb_id, const void *addr,
38363841
struct mlxsw_sp_vr *vr;
38373842
int err;
38383843

3839-
vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id);
3844+
vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id, NULL);
38403845
if (IS_ERR(vr))
38413846
return ERR_CAST(vr);
38423847
fib = mlxsw_sp_vr_fib(vr, proto);
@@ -4875,7 +4880,7 @@ static int mlxsw_sp_router_fibmr_add(struct mlxsw_sp *mlxsw_sp,
48754880
if (mlxsw_sp->router->aborted)
48764881
return 0;
48774882

4878-
vr = mlxsw_sp_vr_get(mlxsw_sp, men_info->tb_id);
4883+
vr = mlxsw_sp_vr_get(mlxsw_sp, men_info->tb_id, NULL);
48794884
if (IS_ERR(vr))
48804885
return PTR_ERR(vr);
48814886

@@ -4908,7 +4913,7 @@ mlxsw_sp_router_fibmr_vif_add(struct mlxsw_sp *mlxsw_sp,
49084913
if (mlxsw_sp->router->aborted)
49094914
return 0;
49104915

4911-
vr = mlxsw_sp_vr_get(mlxsw_sp, ven_info->tb_id);
4916+
vr = mlxsw_sp_vr_get(mlxsw_sp, ven_info->tb_id, NULL);
49124917
if (IS_ERR(vr))
49134918
return PTR_ERR(vr);
49144919

@@ -5471,7 +5476,8 @@ const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif)
54715476

54725477
static struct mlxsw_sp_rif *
54735478
mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
5474-
const struct mlxsw_sp_rif_params *params)
5479+
const struct mlxsw_sp_rif_params *params,
5480+
struct netlink_ext_ack *extack)
54755481
{
54765482
u32 tb_id = l3mdev_fib_table(params->dev);
54775483
const struct mlxsw_sp_rif_ops *ops;
@@ -5485,14 +5491,16 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp,
54855491
type = mlxsw_sp_dev_rif_type(mlxsw_sp, params->dev);
54865492
ops = mlxsw_sp->router->rif_ops_arr[type];
54875493

5488-
vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id ? : RT_TABLE_MAIN);
5494+
vr = mlxsw_sp_vr_get(mlxsw_sp, tb_id ? : RT_TABLE_MAIN, extack);
54895495
if (IS_ERR(vr))
54905496
return ERR_CAST(vr);
54915497
vr->rif_count++;
54925498

54935499
err = mlxsw_sp_rif_index_alloc(mlxsw_sp, &rif_index);
5494-
if (err)
5500+
if (err) {
5501+
NL_SET_ERR_MSG(extack, "spectrum: Exceeded number of supported router interfaces");
54955502
goto err_rif_index_alloc;
5503+
}
54965504

54975505
rif = mlxsw_sp_rif_alloc(ops->rif_size, rif_index, vr->id, params->dev);
54985506
if (!rif) {
@@ -5579,7 +5587,8 @@ mlxsw_sp_rif_subport_params_init(struct mlxsw_sp_rif_params *params,
55795587

55805588
static int
55815589
mlxsw_sp_port_vlan_router_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
5582-
struct net_device *l3_dev)
5590+
struct net_device *l3_dev,
5591+
struct netlink_ext_ack *extack)
55835592
{
55845593
struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
55855594
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
@@ -5595,7 +5604,7 @@ mlxsw_sp_port_vlan_router_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
55955604
};
55965605

55975606
mlxsw_sp_rif_subport_params_init(&params, mlxsw_sp_port_vlan);
5598-
rif = mlxsw_sp_rif_create(mlxsw_sp, &params);
5607+
rif = mlxsw_sp_rif_create(mlxsw_sp, &params, extack);
55995608
if (IS_ERR(rif))
56005609
return PTR_ERR(rif);
56015610
}
@@ -5650,7 +5659,8 @@ mlxsw_sp_port_vlan_router_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
56505659

56515660
static int mlxsw_sp_inetaddr_port_vlan_event(struct net_device *l3_dev,
56525661
struct net_device *port_dev,
5653-
unsigned long event, u16 vid)
5662+
unsigned long event, u16 vid,
5663+
struct netlink_ext_ack *extack)
56545664
{
56555665
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(port_dev);
56565666
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
@@ -5662,7 +5672,7 @@ static int mlxsw_sp_inetaddr_port_vlan_event(struct net_device *l3_dev,
56625672
switch (event) {
56635673
case NETDEV_UP:
56645674
return mlxsw_sp_port_vlan_router_join(mlxsw_sp_port_vlan,
5665-
l3_dev);
5675+
l3_dev, extack);
56665676
case NETDEV_DOWN:
56675677
mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port_vlan);
56685678
break;
@@ -5672,19 +5682,22 @@ static int mlxsw_sp_inetaddr_port_vlan_event(struct net_device *l3_dev,
56725682
}
56735683

56745684
static int mlxsw_sp_inetaddr_port_event(struct net_device *port_dev,
5675-
unsigned long event)
5685+
unsigned long event,
5686+
struct netlink_ext_ack *extack)
56765687
{
56775688
if (netif_is_bridge_port(port_dev) ||
56785689
netif_is_lag_port(port_dev) ||
56795690
netif_is_ovs_port(port_dev))
56805691
return 0;
56815692

5682-
return mlxsw_sp_inetaddr_port_vlan_event(port_dev, port_dev, event, 1);
5693+
return mlxsw_sp_inetaddr_port_vlan_event(port_dev, port_dev, event, 1,
5694+
extack);
56835695
}
56845696

56855697
static int __mlxsw_sp_inetaddr_lag_event(struct net_device *l3_dev,
56865698
struct net_device *lag_dev,
5687-
unsigned long event, u16 vid)
5699+
unsigned long event, u16 vid,
5700+
struct netlink_ext_ack *extack)
56885701
{
56895702
struct net_device *port_dev;
56905703
struct list_head *iter;
@@ -5694,7 +5707,8 @@ static int __mlxsw_sp_inetaddr_lag_event(struct net_device *l3_dev,
56945707
if (mlxsw_sp_port_dev_check(port_dev)) {
56955708
err = mlxsw_sp_inetaddr_port_vlan_event(l3_dev,
56965709
port_dev,
5697-
event, vid);
5710+
event, vid,
5711+
extack);
56985712
if (err)
56995713
return err;
57005714
}
@@ -5704,16 +5718,19 @@ static int __mlxsw_sp_inetaddr_lag_event(struct net_device *l3_dev,
57045718
}
57055719

57065720
static int mlxsw_sp_inetaddr_lag_event(struct net_device *lag_dev,
5707-
unsigned long event)
5721+
unsigned long event,
5722+
struct netlink_ext_ack *extack)
57085723
{
57095724
if (netif_is_bridge_port(lag_dev))
57105725
return 0;
57115726

5712-
return __mlxsw_sp_inetaddr_lag_event(lag_dev, lag_dev, event, 1);
5727+
return __mlxsw_sp_inetaddr_lag_event(lag_dev, lag_dev, event, 1,
5728+
extack);
57135729
}
57145730

57155731
static int mlxsw_sp_inetaddr_bridge_event(struct net_device *l3_dev,
5716-
unsigned long event)
5732+
unsigned long event,
5733+
struct netlink_ext_ack *extack)
57175734
{
57185735
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(l3_dev);
57195736
struct mlxsw_sp_rif_params params = {
@@ -5723,7 +5740,7 @@ static int mlxsw_sp_inetaddr_bridge_event(struct net_device *l3_dev,
57235740

57245741
switch (event) {
57255742
case NETDEV_UP:
5726-
rif = mlxsw_sp_rif_create(mlxsw_sp, &params);
5743+
rif = mlxsw_sp_rif_create(mlxsw_sp, &params, extack);
57275744
if (IS_ERR(rif))
57285745
return PTR_ERR(rif);
57295746
break;
@@ -5737,7 +5754,8 @@ static int mlxsw_sp_inetaddr_bridge_event(struct net_device *l3_dev,
57375754
}
57385755

57395756
static int mlxsw_sp_inetaddr_vlan_event(struct net_device *vlan_dev,
5740-
unsigned long event)
5757+
unsigned long event,
5758+
struct netlink_ext_ack *extack)
57415759
{
57425760
struct net_device *real_dev = vlan_dev_real_dev(vlan_dev);
57435761
u16 vid = vlan_dev_vlan_id(vlan_dev);
@@ -5747,27 +5765,28 @@ static int mlxsw_sp_inetaddr_vlan_event(struct net_device *vlan_dev,
57475765

57485766
if (mlxsw_sp_port_dev_check(real_dev))
57495767
return mlxsw_sp_inetaddr_port_vlan_event(vlan_dev, real_dev,
5750-
event, vid);
5768+
event, vid, extack);
57515769
else if (netif_is_lag_master(real_dev))
57525770
return __mlxsw_sp_inetaddr_lag_event(vlan_dev, real_dev, event,
5753-
vid);
5771+
vid, extack);
57545772
else if (netif_is_bridge_master(real_dev) && br_vlan_enabled(real_dev))
5755-
return mlxsw_sp_inetaddr_bridge_event(vlan_dev, event);
5773+
return mlxsw_sp_inetaddr_bridge_event(vlan_dev, event, extack);
57565774

57575775
return 0;
57585776
}
57595777

57605778
static int __mlxsw_sp_inetaddr_event(struct net_device *dev,
5761-
unsigned long event)
5779+
unsigned long event,
5780+
struct netlink_ext_ack *extack)
57625781
{
57635782
if (mlxsw_sp_port_dev_check(dev))
5764-
return mlxsw_sp_inetaddr_port_event(dev, event);
5783+
return mlxsw_sp_inetaddr_port_event(dev, event, extack);
57655784
else if (netif_is_lag_master(dev))
5766-
return mlxsw_sp_inetaddr_lag_event(dev, event);
5785+
return mlxsw_sp_inetaddr_lag_event(dev, event, extack);
57675786
else if (netif_is_bridge_master(dev))
5768-
return mlxsw_sp_inetaddr_bridge_event(dev, event);
5787+
return mlxsw_sp_inetaddr_bridge_event(dev, event, extack);
57695788
else if (is_vlan_dev(dev))
5770-
return mlxsw_sp_inetaddr_vlan_event(dev, event);
5789+
return mlxsw_sp_inetaddr_vlan_event(dev, event, extack);
57715790
else
57725791
return 0;
57735792
}
@@ -5793,7 +5812,7 @@ int mlxsw_sp_inetaddr_event(struct notifier_block *unused,
57935812
if (!mlxsw_sp_rif_should_config(rif, dev, event))
57945813
goto out;
57955814

5796-
err = __mlxsw_sp_inetaddr_event(dev, event);
5815+
err = __mlxsw_sp_inetaddr_event(dev, event, NULL);
57975816
out:
57985817
return notifier_from_errno(err);
57995818
}
@@ -5815,7 +5834,7 @@ int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused,
58155834
if (!mlxsw_sp_rif_should_config(rif, dev, event))
58165835
goto out;
58175836

5818-
err = __mlxsw_sp_inetaddr_event(dev, event);
5837+
err = __mlxsw_sp_inetaddr_event(dev, event, ivi->extack);
58195838
out:
58205839
return notifier_from_errno(err);
58215840
}
@@ -5844,7 +5863,7 @@ static void mlxsw_sp_inet6addr_event_work(struct work_struct *work)
58445863
if (!mlxsw_sp_rif_should_config(rif, dev, event))
58455864
goto out;
58465865

5847-
__mlxsw_sp_inetaddr_event(dev, event);
5866+
__mlxsw_sp_inetaddr_event(dev, event, NULL);
58485867
out:
58495868
rtnl_unlock();
58505869
dev_put(dev);
@@ -5896,7 +5915,7 @@ int mlxsw_sp_inet6addr_valid_event(struct notifier_block *unused,
58965915
if (!mlxsw_sp_rif_should_config(rif, dev, event))
58975916
goto out;
58985917

5899-
err = __mlxsw_sp_inetaddr_event(dev, event);
5918+
err = __mlxsw_sp_inetaddr_event(dev, event, i6vi->extack);
59005919
out:
59015920
return notifier_from_errno(err);
59025921
}
@@ -5973,7 +5992,8 @@ int mlxsw_sp_netdevice_router_port_event(struct net_device *dev)
59735992
}
59745993

59755994
static int mlxsw_sp_port_vrf_join(struct mlxsw_sp *mlxsw_sp,
5976-
struct net_device *l3_dev)
5995+
struct net_device *l3_dev,
5996+
struct netlink_ext_ack *extack)
59775997
{
59785998
struct mlxsw_sp_rif *rif;
59795999

@@ -5982,9 +6002,9 @@ static int mlxsw_sp_port_vrf_join(struct mlxsw_sp *mlxsw_sp,
59826002
*/
59836003
rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev);
59846004
if (rif)
5985-
__mlxsw_sp_inetaddr_event(l3_dev, NETDEV_DOWN);
6005+
__mlxsw_sp_inetaddr_event(l3_dev, NETDEV_DOWN, extack);
59866006

5987-
return __mlxsw_sp_inetaddr_event(l3_dev, NETDEV_UP);
6007+
return __mlxsw_sp_inetaddr_event(l3_dev, NETDEV_UP, extack);
59886008
}
59896009

59906010
static void mlxsw_sp_port_vrf_leave(struct mlxsw_sp *mlxsw_sp,
@@ -5995,7 +6015,7 @@ static void mlxsw_sp_port_vrf_leave(struct mlxsw_sp *mlxsw_sp,
59956015
rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev);
59966016
if (!rif)
59976017
return;
5998-
__mlxsw_sp_inetaddr_event(l3_dev, NETDEV_DOWN);
6018+
__mlxsw_sp_inetaddr_event(l3_dev, NETDEV_DOWN, NULL);
59996019
}
60006020

60016021
int mlxsw_sp_netdevice_vrf_event(struct net_device *l3_dev, unsigned long event,
@@ -6011,10 +6031,14 @@ int mlxsw_sp_netdevice_vrf_event(struct net_device *l3_dev, unsigned long event,
60116031
case NETDEV_PRECHANGEUPPER:
60126032
return 0;
60136033
case NETDEV_CHANGEUPPER:
6014-
if (info->linking)
6015-
err = mlxsw_sp_port_vrf_join(mlxsw_sp, l3_dev);
6016-
else
6034+
if (info->linking) {
6035+
struct netlink_ext_ack *extack;
6036+
6037+
extack = netdev_notifier_info_to_extack(&info->info);
6038+
err = mlxsw_sp_port_vrf_join(mlxsw_sp, l3_dev, extack);
6039+
} else {
60176040
mlxsw_sp_port_vrf_leave(mlxsw_sp, l3_dev);
6041+
}
60186042
break;
60196043
}
60206044

@@ -6321,7 +6345,7 @@ mlxsw_sp_rif_ipip_lb_configure(struct mlxsw_sp_rif *rif)
63216345
struct mlxsw_sp_vr *ul_vr;
63226346
int err;
63236347

6324-
ul_vr = mlxsw_sp_vr_get(mlxsw_sp, ul_tb_id);
6348+
ul_vr = mlxsw_sp_vr_get(mlxsw_sp, ul_tb_id, NULL);
63256349
if (IS_ERR(ul_vr))
63266350
return PTR_ERR(ul_vr);
63276351

0 commit comments

Comments
 (0)