@@ -1141,16 +1141,20 @@ static void mlxsw_sp_port_vlan_flush(struct mlxsw_sp_port *mlxsw_sp_port)
1141
1141
1142
1142
list_for_each_entry_safe (mlxsw_sp_port_vlan , tmp ,
1143
1143
& mlxsw_sp_port -> vlans_list , list )
1144
- mlxsw_sp_port_vlan_put (mlxsw_sp_port_vlan );
1144
+ mlxsw_sp_port_vlan_destroy (mlxsw_sp_port_vlan );
1145
1145
}
1146
1146
1147
- static struct mlxsw_sp_port_vlan *
1147
+ struct mlxsw_sp_port_vlan *
1148
1148
mlxsw_sp_port_vlan_create (struct mlxsw_sp_port * mlxsw_sp_port , u16 vid )
1149
1149
{
1150
1150
struct mlxsw_sp_port_vlan * mlxsw_sp_port_vlan ;
1151
1151
bool untagged = vid == 1 ;
1152
1152
int err ;
1153
1153
1154
+ mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid (mlxsw_sp_port , vid );
1155
+ if (mlxsw_sp_port_vlan )
1156
+ return ERR_PTR (- EEXIST );
1157
+
1154
1158
err = mlxsw_sp_port_vlan_set (mlxsw_sp_port , vid , vid , true, untagged );
1155
1159
if (err )
1156
1160
return ERR_PTR (err );
@@ -1162,7 +1166,6 @@ mlxsw_sp_port_vlan_create(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
1162
1166
}
1163
1167
1164
1168
mlxsw_sp_port_vlan -> mlxsw_sp_port = mlxsw_sp_port ;
1165
- mlxsw_sp_port_vlan -> ref_count = 1 ;
1166
1169
mlxsw_sp_port_vlan -> vid = vid ;
1167
1170
list_add (& mlxsw_sp_port_vlan -> list , & mlxsw_sp_port -> vlans_list );
1168
1171
@@ -1173,44 +1176,19 @@ mlxsw_sp_port_vlan_create(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
1173
1176
return ERR_PTR (err );
1174
1177
}
1175
1178
1176
- static void
1177
- mlxsw_sp_port_vlan_destroy (struct mlxsw_sp_port_vlan * mlxsw_sp_port_vlan )
1179
+ void mlxsw_sp_port_vlan_destroy (struct mlxsw_sp_port_vlan * mlxsw_sp_port_vlan )
1178
1180
{
1179
1181
struct mlxsw_sp_port * mlxsw_sp_port = mlxsw_sp_port_vlan -> mlxsw_sp_port ;
1180
1182
u16 vid = mlxsw_sp_port_vlan -> vid ;
1181
1183
1182
- list_del (& mlxsw_sp_port_vlan -> list );
1183
- kfree (mlxsw_sp_port_vlan );
1184
- mlxsw_sp_port_vlan_set (mlxsw_sp_port , vid , vid , false, false);
1185
- }
1186
-
1187
- struct mlxsw_sp_port_vlan *
1188
- mlxsw_sp_port_vlan_get (struct mlxsw_sp_port * mlxsw_sp_port , u16 vid )
1189
- {
1190
- struct mlxsw_sp_port_vlan * mlxsw_sp_port_vlan ;
1191
-
1192
- mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid (mlxsw_sp_port , vid );
1193
- if (mlxsw_sp_port_vlan ) {
1194
- mlxsw_sp_port_vlan -> ref_count ++ ;
1195
- return mlxsw_sp_port_vlan ;
1196
- }
1197
-
1198
- return mlxsw_sp_port_vlan_create (mlxsw_sp_port , vid );
1199
- }
1200
-
1201
- void mlxsw_sp_port_vlan_put (struct mlxsw_sp_port_vlan * mlxsw_sp_port_vlan )
1202
- {
1203
- struct mlxsw_sp_fid * fid = mlxsw_sp_port_vlan -> fid ;
1204
-
1205
- if (-- mlxsw_sp_port_vlan -> ref_count != 0 )
1206
- return ;
1207
-
1208
1184
if (mlxsw_sp_port_vlan -> bridge_port )
1209
1185
mlxsw_sp_port_vlan_bridge_leave (mlxsw_sp_port_vlan );
1210
- else if (fid )
1186
+ else if (mlxsw_sp_port_vlan -> fid )
1211
1187
mlxsw_sp_port_vlan_router_leave (mlxsw_sp_port_vlan );
1212
1188
1213
- mlxsw_sp_port_vlan_destroy (mlxsw_sp_port_vlan );
1189
+ list_del (& mlxsw_sp_port_vlan -> list );
1190
+ kfree (mlxsw_sp_port_vlan );
1191
+ mlxsw_sp_port_vlan_set (mlxsw_sp_port , vid , vid , false, false);
1214
1192
}
1215
1193
1216
1194
static int mlxsw_sp_port_add_vid (struct net_device * dev ,
@@ -1224,7 +1202,7 @@ static int mlxsw_sp_port_add_vid(struct net_device *dev,
1224
1202
if (!vid )
1225
1203
return 0 ;
1226
1204
1227
- return PTR_ERR_OR_ZERO (mlxsw_sp_port_vlan_get (mlxsw_sp_port , vid ));
1205
+ return PTR_ERR_OR_ZERO (mlxsw_sp_port_vlan_create (mlxsw_sp_port , vid ));
1228
1206
}
1229
1207
1230
1208
static int mlxsw_sp_port_kill_vid (struct net_device * dev ,
@@ -1242,7 +1220,7 @@ static int mlxsw_sp_port_kill_vid(struct net_device *dev,
1242
1220
mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid (mlxsw_sp_port , vid );
1243
1221
if (!mlxsw_sp_port_vlan )
1244
1222
return 0 ;
1245
- mlxsw_sp_port_vlan_put (mlxsw_sp_port_vlan );
1223
+ mlxsw_sp_port_vlan_destroy (mlxsw_sp_port_vlan );
1246
1224
1247
1225
return 0 ;
1248
1226
}
@@ -3198,12 +3176,12 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
3198
3176
goto err_port_nve_init ;
3199
3177
}
3200
3178
3201
- mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_get (mlxsw_sp_port , 1 );
3179
+ mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_create (mlxsw_sp_port , 1 );
3202
3180
if (IS_ERR (mlxsw_sp_port_vlan )) {
3203
3181
dev_err (mlxsw_sp -> bus_info -> dev , "Port %d: Failed to create VID 1\n" ,
3204
3182
mlxsw_sp_port -> local_port );
3205
3183
err = PTR_ERR (mlxsw_sp_port_vlan );
3206
- goto err_port_vlan_get ;
3184
+ goto err_port_vlan_create ;
3207
3185
}
3208
3186
3209
3187
mlxsw_sp_port_switchdev_init (mlxsw_sp_port );
@@ -3224,8 +3202,8 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
3224
3202
err_register_netdev :
3225
3203
mlxsw_sp -> ports [local_port ] = NULL ;
3226
3204
mlxsw_sp_port_switchdev_fini (mlxsw_sp_port );
3227
- mlxsw_sp_port_vlan_put (mlxsw_sp_port_vlan );
3228
- err_port_vlan_get :
3205
+ mlxsw_sp_port_vlan_destroy (mlxsw_sp_port_vlan );
3206
+ err_port_vlan_create :
3229
3207
mlxsw_sp_port_nve_fini (mlxsw_sp_port );
3230
3208
err_port_nve_init :
3231
3209
mlxsw_sp_tc_qdisc_fini (mlxsw_sp_port );
@@ -4520,6 +4498,25 @@ void mlxsw_sp_port_dev_put(struct mlxsw_sp_port *mlxsw_sp_port)
4520
4498
dev_put (mlxsw_sp_port -> dev );
4521
4499
}
4522
4500
4501
+ static void
4502
+ mlxsw_sp_port_lag_uppers_cleanup (struct mlxsw_sp_port * mlxsw_sp_port ,
4503
+ struct net_device * lag_dev )
4504
+ {
4505
+ struct net_device * br_dev = netdev_master_upper_dev_get (lag_dev );
4506
+ struct net_device * upper_dev ;
4507
+ struct list_head * iter ;
4508
+
4509
+ if (netif_is_bridge_port (lag_dev ))
4510
+ mlxsw_sp_port_bridge_leave (mlxsw_sp_port , lag_dev , br_dev );
4511
+
4512
+ netdev_for_each_upper_dev_rcu (lag_dev , upper_dev , iter ) {
4513
+ if (!netif_is_bridge_port (upper_dev ))
4514
+ continue ;
4515
+ br_dev = netdev_master_upper_dev_get (upper_dev );
4516
+ mlxsw_sp_port_bridge_leave (mlxsw_sp_port , upper_dev , br_dev );
4517
+ }
4518
+ }
4519
+
4523
4520
static int mlxsw_sp_lag_create (struct mlxsw_sp * mlxsw_sp , u16 lag_id )
4524
4521
{
4525
4522
char sldr_pl [MLXSW_REG_SLDR_LEN ];
@@ -4712,6 +4709,10 @@ static void mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
4712
4709
4713
4710
/* Any VLANs configured on the port are no longer valid */
4714
4711
mlxsw_sp_port_vlan_flush (mlxsw_sp_port );
4712
+ /* Make the LAG and its directly linked uppers leave bridges they
4713
+ * are memeber in
4714
+ */
4715
+ mlxsw_sp_port_lag_uppers_cleanup (mlxsw_sp_port , lag_dev );
4715
4716
4716
4717
if (lag -> ref_count == 1 )
4717
4718
mlxsw_sp_lag_destroy (mlxsw_sp , lag_id );
@@ -4721,7 +4722,7 @@ static void mlxsw_sp_port_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port,
4721
4722
mlxsw_sp_port -> lagged = 0 ;
4722
4723
lag -> ref_count -- ;
4723
4724
4724
- mlxsw_sp_port_vlan_get (mlxsw_sp_port , 1 );
4725
+ mlxsw_sp_port_vlan_create (mlxsw_sp_port , 1 );
4725
4726
/* Make sure untagged frames are allowed to ingress */
4726
4727
mlxsw_sp_port_pvid_set (mlxsw_sp_port , 1 );
4727
4728
}
@@ -5000,6 +5001,16 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
5000
5001
} else if (netif_is_macvlan (upper_dev )) {
5001
5002
if (!info -> linking )
5002
5003
mlxsw_sp_rif_macvlan_del (mlxsw_sp , upper_dev );
5004
+ } else if (is_vlan_dev (upper_dev )) {
5005
+ struct net_device * br_dev ;
5006
+
5007
+ if (!netif_is_bridge_port (upper_dev ))
5008
+ break ;
5009
+ if (info -> linking )
5010
+ break ;
5011
+ br_dev = netdev_master_upper_dev_get (upper_dev );
5012
+ mlxsw_sp_port_bridge_leave (mlxsw_sp_port , upper_dev ,
5013
+ br_dev );
5003
5014
}
5004
5015
break ;
5005
5016
}
@@ -5156,6 +5167,48 @@ static int mlxsw_sp_netdevice_lag_port_vlan_event(struct net_device *vlan_dev,
5156
5167
return 0 ;
5157
5168
}
5158
5169
5170
+ static int mlxsw_sp_netdevice_bridge_vlan_event (struct net_device * vlan_dev ,
5171
+ struct net_device * br_dev ,
5172
+ unsigned long event , void * ptr ,
5173
+ u16 vid )
5174
+ {
5175
+ struct mlxsw_sp * mlxsw_sp = mlxsw_sp_lower_get (vlan_dev );
5176
+ struct netdev_notifier_changeupper_info * info = ptr ;
5177
+ struct netlink_ext_ack * extack ;
5178
+ struct net_device * upper_dev ;
5179
+
5180
+ if (!mlxsw_sp )
5181
+ return 0 ;
5182
+
5183
+ extack = netdev_notifier_info_to_extack (& info -> info );
5184
+
5185
+ switch (event ) {
5186
+ case NETDEV_PRECHANGEUPPER :
5187
+ upper_dev = info -> upper_dev ;
5188
+ if (!netif_is_macvlan (upper_dev )) {
5189
+ NL_SET_ERR_MSG_MOD (extack , "Unknown upper device type" );
5190
+ return - EOPNOTSUPP ;
5191
+ }
5192
+ if (!info -> linking )
5193
+ break ;
5194
+ if (netif_is_macvlan (upper_dev ) &&
5195
+ !mlxsw_sp_rif_find_by_dev (mlxsw_sp , vlan_dev )) {
5196
+ NL_SET_ERR_MSG_MOD (extack , "macvlan is only supported on top of router interfaces" );
5197
+ return - EOPNOTSUPP ;
5198
+ }
5199
+ break ;
5200
+ case NETDEV_CHANGEUPPER :
5201
+ upper_dev = info -> upper_dev ;
5202
+ if (info -> linking )
5203
+ break ;
5204
+ if (netif_is_macvlan (upper_dev ))
5205
+ mlxsw_sp_rif_macvlan_del (mlxsw_sp , upper_dev );
5206
+ break ;
5207
+ }
5208
+
5209
+ return 0 ;
5210
+ }
5211
+
5159
5212
static int mlxsw_sp_netdevice_vlan_event (struct net_device * vlan_dev ,
5160
5213
unsigned long event , void * ptr )
5161
5214
{
@@ -5169,6 +5222,9 @@ static int mlxsw_sp_netdevice_vlan_event(struct net_device *vlan_dev,
5169
5222
return mlxsw_sp_netdevice_lag_port_vlan_event (vlan_dev ,
5170
5223
real_dev , event ,
5171
5224
ptr , vid );
5225
+ else if (netif_is_bridge_master (real_dev ))
5226
+ return mlxsw_sp_netdevice_bridge_vlan_event (vlan_dev , real_dev ,
5227
+ event , ptr , vid );
5172
5228
5173
5229
return 0 ;
5174
5230
}
@@ -5358,18 +5414,10 @@ static struct notifier_block mlxsw_sp_inetaddr_valid_nb __read_mostly = {
5358
5414
.notifier_call = mlxsw_sp_inetaddr_valid_event ,
5359
5415
};
5360
5416
5361
- static struct notifier_block mlxsw_sp_inetaddr_nb __read_mostly = {
5362
- .notifier_call = mlxsw_sp_inetaddr_event ,
5363
- };
5364
-
5365
5417
static struct notifier_block mlxsw_sp_inet6addr_valid_nb __read_mostly = {
5366
5418
.notifier_call = mlxsw_sp_inet6addr_valid_event ,
5367
5419
};
5368
5420
5369
- static struct notifier_block mlxsw_sp_inet6addr_nb __read_mostly = {
5370
- .notifier_call = mlxsw_sp_inet6addr_event ,
5371
- };
5372
-
5373
5421
static const struct pci_device_id mlxsw_sp1_pci_id_table [] = {
5374
5422
{PCI_VDEVICE (MELLANOX , PCI_DEVICE_ID_MELLANOX_SPECTRUM ), 0 },
5375
5423
{0 , },
@@ -5395,9 +5443,7 @@ static int __init mlxsw_sp_module_init(void)
5395
5443
int err ;
5396
5444
5397
5445
register_inetaddr_validator_notifier (& mlxsw_sp_inetaddr_valid_nb );
5398
- register_inetaddr_notifier (& mlxsw_sp_inetaddr_nb );
5399
5446
register_inet6addr_validator_notifier (& mlxsw_sp_inet6addr_valid_nb );
5400
- register_inet6addr_notifier (& mlxsw_sp_inet6addr_nb );
5401
5447
5402
5448
err = mlxsw_core_driver_register (& mlxsw_sp1_driver );
5403
5449
if (err )
@@ -5424,9 +5470,7 @@ static int __init mlxsw_sp_module_init(void)
5424
5470
err_sp2_core_driver_register :
5425
5471
mlxsw_core_driver_unregister (& mlxsw_sp1_driver );
5426
5472
err_sp1_core_driver_register :
5427
- unregister_inet6addr_notifier (& mlxsw_sp_inet6addr_nb );
5428
5473
unregister_inet6addr_validator_notifier (& mlxsw_sp_inet6addr_valid_nb );
5429
- unregister_inetaddr_notifier (& mlxsw_sp_inetaddr_nb );
5430
5474
unregister_inetaddr_validator_notifier (& mlxsw_sp_inetaddr_valid_nb );
5431
5475
return err ;
5432
5476
}
@@ -5437,9 +5481,7 @@ static void __exit mlxsw_sp_module_exit(void)
5437
5481
mlxsw_pci_driver_unregister (& mlxsw_sp1_pci_driver );
5438
5482
mlxsw_core_driver_unregister (& mlxsw_sp2_driver );
5439
5483
mlxsw_core_driver_unregister (& mlxsw_sp1_driver );
5440
- unregister_inet6addr_notifier (& mlxsw_sp_inet6addr_nb );
5441
5484
unregister_inet6addr_validator_notifier (& mlxsw_sp_inet6addr_valid_nb );
5442
- unregister_inetaddr_notifier (& mlxsw_sp_inetaddr_nb );
5443
5485
unregister_inetaddr_validator_notifier (& mlxsw_sp_inetaddr_valid_nb );
5444
5486
}
5445
5487
0 commit comments