@@ -782,10 +782,25 @@ mlxsw_sp_bridge_port_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
782782
783783static int
784784mlxsw_sp_port_attr_br_pre_flags_set (struct mlxsw_sp_port * mlxsw_sp_port ,
785- struct switchdev_brport_flags flags )
785+ const struct net_device * orig_dev ,
786+ struct switchdev_brport_flags flags ,
787+ struct netlink_ext_ack * extack )
786788{
787- if (flags .mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD ))
789+ if (flags .mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
790+ BR_PORT_LOCKED | BR_PORT_MAB )) {
791+ NL_SET_ERR_MSG_MOD (extack , "Unsupported bridge port flag" );
788792 return - EINVAL ;
793+ }
794+
795+ if ((flags .mask & BR_PORT_LOCKED ) && is_vlan_dev (orig_dev )) {
796+ NL_SET_ERR_MSG_MOD (extack , "Locked flag cannot be set on a VLAN upper" );
797+ return - EINVAL ;
798+ }
799+
800+ if ((flags .mask & BR_PORT_LOCKED ) && vlan_uses_dev (orig_dev )) {
801+ NL_SET_ERR_MSG_MOD (extack , "Locked flag cannot be set on a bridge port that has VLAN uppers" );
802+ return - EINVAL ;
803+ }
789804
790805 return 0 ;
791806}
@@ -819,6 +834,13 @@ static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
819834 return err ;
820835 }
821836
837+ if (flags .mask & BR_PORT_LOCKED ) {
838+ err = mlxsw_sp_port_security_set (mlxsw_sp_port ,
839+ flags .val & BR_PORT_LOCKED );
840+ if (err )
841+ return err ;
842+ }
843+
822844 if (bridge_port -> bridge_device -> multicast_enabled )
823845 goto out ;
824846
@@ -1186,7 +1208,9 @@ static int mlxsw_sp_port_attr_set(struct net_device *dev, const void *ctx,
11861208 break ;
11871209 case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS :
11881210 err = mlxsw_sp_port_attr_br_pre_flags_set (mlxsw_sp_port ,
1189- attr -> u .brport_flags );
1211+ attr -> orig_dev ,
1212+ attr -> u .brport_flags ,
1213+ extack );
11901214 break ;
11911215 case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS :
11921216 err = mlxsw_sp_port_attr_br_flags_set (mlxsw_sp_port ,
@@ -2783,6 +2807,7 @@ void mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port,
27832807
27842808 bridge_device -> ops -> port_leave (bridge_device , bridge_port ,
27852809 mlxsw_sp_port );
2810+ mlxsw_sp_port_security_set (mlxsw_sp_port , false);
27862811 mlxsw_sp_bridge_port_put (mlxsw_sp -> bridge , bridge_port );
27872812}
27882813
@@ -2888,13 +2913,14 @@ static void mlxsw_sp_fdb_nve_call_notifiers(struct net_device *dev,
28882913static void
28892914mlxsw_sp_fdb_call_notifiers (enum switchdev_notifier_type type ,
28902915 const char * mac , u16 vid ,
2891- struct net_device * dev , bool offloaded )
2916+ struct net_device * dev , bool offloaded , bool locked )
28922917{
28932918 struct switchdev_notifier_fdb_info info = {};
28942919
28952920 info .addr = mac ;
28962921 info .vid = vid ;
28972922 info .offloaded = offloaded ;
2923+ info .locked = locked ;
28982924 call_switchdev_notifiers (type , dev , & info .info , NULL );
28992925}
29002926
@@ -2941,6 +2967,12 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
29412967 vid = bridge_device -> vlan_enabled ? mlxsw_sp_port_vlan -> vid : 0 ;
29422968 evid = mlxsw_sp_port_vlan -> vid ;
29432969
2970+ if (adding && mlxsw_sp_port -> security ) {
2971+ mlxsw_sp_fdb_call_notifiers (SWITCHDEV_FDB_ADD_TO_BRIDGE , mac ,
2972+ vid , bridge_port -> dev , false, true);
2973+ return ;
2974+ }
2975+
29442976do_fdb_op :
29452977 err = mlxsw_sp_port_fdb_uc_op (mlxsw_sp , local_port , mac , fid , evid ,
29462978 adding , true);
@@ -2952,7 +2984,8 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
29522984 if (!do_notification )
29532985 return ;
29542986 type = adding ? SWITCHDEV_FDB_ADD_TO_BRIDGE : SWITCHDEV_FDB_DEL_TO_BRIDGE ;
2955- mlxsw_sp_fdb_call_notifiers (type , mac , vid , bridge_port -> dev , adding );
2987+ mlxsw_sp_fdb_call_notifiers (type , mac , vid , bridge_port -> dev , adding ,
2988+ false);
29562989
29572990 return ;
29582991
@@ -3004,6 +3037,12 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
30043037 vid = bridge_device -> vlan_enabled ? mlxsw_sp_port_vlan -> vid : 0 ;
30053038 lag_vid = mlxsw_sp_port_vlan -> vid ;
30063039
3040+ if (adding && mlxsw_sp_port -> security ) {
3041+ mlxsw_sp_fdb_call_notifiers (SWITCHDEV_FDB_ADD_TO_BRIDGE , mac ,
3042+ vid , bridge_port -> dev , false, true);
3043+ return ;
3044+ }
3045+
30073046do_fdb_op :
30083047 err = mlxsw_sp_port_fdb_uc_lag_op (mlxsw_sp , lag_id , mac , fid , lag_vid ,
30093048 adding , true);
@@ -3015,7 +3054,8 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
30153054 if (!do_notification )
30163055 return ;
30173056 type = adding ? SWITCHDEV_FDB_ADD_TO_BRIDGE : SWITCHDEV_FDB_DEL_TO_BRIDGE ;
3018- mlxsw_sp_fdb_call_notifiers (type , mac , vid , bridge_port -> dev , adding );
3057+ mlxsw_sp_fdb_call_notifiers (type , mac , vid , bridge_port -> dev , adding ,
3058+ false);
30193059
30203060 return ;
30213061
@@ -3122,7 +3162,7 @@ static void mlxsw_sp_fdb_notify_mac_uc_tunnel_process(struct mlxsw_sp *mlxsw_sp,
31223162
31233163 type = adding ? SWITCHDEV_FDB_ADD_TO_BRIDGE :
31243164 SWITCHDEV_FDB_DEL_TO_BRIDGE ;
3125- mlxsw_sp_fdb_call_notifiers (type , mac , vid , nve_dev , adding );
3165+ mlxsw_sp_fdb_call_notifiers (type , mac , vid , nve_dev , adding , false );
31263166
31273167 mlxsw_sp_fid_put (fid );
31283168
@@ -3264,7 +3304,7 @@ mlxsw_sp_switchdev_bridge_vxlan_fdb_event(struct mlxsw_sp *mlxsw_sp,
32643304 & vxlan_fdb_info .info , NULL );
32653305 mlxsw_sp_fdb_call_notifiers (SWITCHDEV_FDB_OFFLOADED ,
32663306 vxlan_fdb_info .eth_addr ,
3267- fdb_info -> vid , dev , true);
3307+ fdb_info -> vid , dev , true, false );
32683308 break ;
32693309 case SWITCHDEV_FDB_DEL_TO_DEVICE :
32703310 err = mlxsw_sp_port_fdb_tunnel_uc_op (mlxsw_sp ,
@@ -3359,7 +3399,7 @@ static void mlxsw_sp_switchdev_bridge_fdb_event_work(struct work_struct *work)
33593399 break ;
33603400 mlxsw_sp_fdb_call_notifiers (SWITCHDEV_FDB_OFFLOADED ,
33613401 fdb_info -> addr ,
3362- fdb_info -> vid , dev , true);
3402+ fdb_info -> vid , dev , true, false );
33633403 break ;
33643404 case SWITCHDEV_FDB_DEL_TO_DEVICE :
33653405 fdb_info = & switchdev_work -> fdb_info ;
@@ -3443,7 +3483,8 @@ mlxsw_sp_switchdev_vxlan_fdb_add(struct mlxsw_sp *mlxsw_sp,
34433483 call_switchdev_notifiers (SWITCHDEV_VXLAN_FDB_OFFLOADED , dev ,
34443484 & vxlan_fdb_info -> info , NULL );
34453485 mlxsw_sp_fdb_call_notifiers (SWITCHDEV_FDB_OFFLOADED ,
3446- vxlan_fdb_info -> eth_addr , vid , dev , true);
3486+ vxlan_fdb_info -> eth_addr , vid , dev , true,
3487+ false);
34473488
34483489 mlxsw_sp_fid_put (fid );
34493490
@@ -3493,7 +3534,8 @@ mlxsw_sp_switchdev_vxlan_fdb_del(struct mlxsw_sp *mlxsw_sp,
34933534 false, false);
34943535 vid = bridge_device -> ops -> fid_vid (bridge_device , fid );
34953536 mlxsw_sp_fdb_call_notifiers (SWITCHDEV_FDB_OFFLOADED ,
3496- vxlan_fdb_info -> eth_addr , vid , dev , false);
3537+ vxlan_fdb_info -> eth_addr , vid , dev , false,
3538+ false);
34973539
34983540 mlxsw_sp_fid_put (fid );
34993541}
0 commit comments