@@ -79,7 +79,7 @@ mlx5_esw_bridge_fdb_offload_notify(struct net_device *dev, const unsigned char *
7979static void
8080mlx5_esw_bridge_fdb_del_notify (struct mlx5_esw_bridge_fdb_entry * entry )
8181{
82- if (!(entry -> flags & MLX5_ESW_BRIDGE_FLAG_ADDED_BY_USER ))
82+ if (!(entry -> flags & ( MLX5_ESW_BRIDGE_FLAG_ADDED_BY_USER | MLX5_ESW_BRIDGE_FLAG_PEER ) ))
8383 mlx5_esw_bridge_fdb_offload_notify (entry -> dev , entry -> key .addr ,
8484 entry -> key .vid ,
8585 SWITCHDEV_FDB_DEL_TO_BRIDGE );
@@ -513,7 +513,7 @@ mlx5_esw_bridge_ingress_filter_flow_create(u16 vport_num, const unsigned char *a
513513}
514514
515515static struct mlx5_flow_handle *
516- mlx5_esw_bridge_egress_flow_create (u16 vport_num , const unsigned char * addr ,
516+ mlx5_esw_bridge_egress_flow_create (u16 vport_num , u16 esw_owner_vhca_id , const unsigned char * addr ,
517517 struct mlx5_esw_bridge_vlan * vlan ,
518518 struct mlx5_esw_bridge * bridge )
519519{
@@ -558,6 +558,10 @@ mlx5_esw_bridge_egress_flow_create(u16 vport_num, const unsigned char *addr,
558558 vlan -> vid );
559559 }
560560
561+ if (MLX5_CAP_ESW (bridge -> br_offloads -> esw -> dev , merged_eswitch )) {
562+ dest .vport .flags = MLX5_FLOW_DEST_VPORT_VHCA_ID ;
563+ dest .vport .vhca_id = esw_owner_vhca_id ;
564+ }
561565 handle = mlx5_add_flow_rules (bridge -> egress_ft , rule_spec , & flow_act , & dest , 1 );
562566
563567 kvfree (rule_spec );
@@ -917,7 +921,7 @@ mlx5_esw_bridge_port_vlan_lookup(u16 vid, u16 vport_num, u16 esw_owner_vhca_id,
917921
918922static struct mlx5_esw_bridge_fdb_entry *
919923mlx5_esw_bridge_fdb_entry_init (struct net_device * dev , u16 vport_num , u16 esw_owner_vhca_id ,
920- const unsigned char * addr , u16 vid , bool added_by_user ,
924+ const unsigned char * addr , u16 vid , bool added_by_user , bool peer ,
921925 struct mlx5_eswitch * esw , struct mlx5_esw_bridge * bridge )
922926{
923927 struct mlx5_esw_bridge_vlan * vlan = NULL ;
@@ -945,6 +949,8 @@ mlx5_esw_bridge_fdb_entry_init(struct net_device *dev, u16 vport_num, u16 esw_ow
945949 entry -> lastuse = jiffies ;
946950 if (added_by_user )
947951 entry -> flags |= MLX5_ESW_BRIDGE_FLAG_ADDED_BY_USER ;
952+ if (peer )
953+ entry -> flags |= MLX5_ESW_BRIDGE_FLAG_PEER ;
948954
949955 counter = mlx5_fc_create (esw -> dev , true);
950956 if (IS_ERR (counter )) {
@@ -974,7 +980,8 @@ mlx5_esw_bridge_fdb_entry_init(struct net_device *dev, u16 vport_num, u16 esw_ow
974980 entry -> filter_handle = handle ;
975981 }
976982
977- handle = mlx5_esw_bridge_egress_flow_create (vport_num , addr , vlan , bridge );
983+ handle = mlx5_esw_bridge_egress_flow_create (vport_num , esw_owner_vhca_id , addr , vlan ,
984+ bridge );
978985 if (IS_ERR (handle )) {
979986 err = PTR_ERR (handle );
980987 esw_warn (esw -> dev , "Failed to create egress flow(vport=%u,err=%d)\n" ,
@@ -1050,7 +1057,7 @@ int mlx5_esw_bridge_vlan_filtering_set(u16 vport_num, u16 esw_owner_vhca_id, boo
10501057 return 0 ;
10511058}
10521059
1053- static int mlx5_esw_bridge_vport_init (u16 vport_num , u16 esw_owner_vhca_id ,
1060+ static int mlx5_esw_bridge_vport_init (u16 vport_num , u16 esw_owner_vhca_id , u16 flags ,
10541061 struct mlx5_esw_bridge_offloads * br_offloads ,
10551062 struct mlx5_esw_bridge * bridge )
10561063{
@@ -1065,6 +1072,7 @@ static int mlx5_esw_bridge_vport_init(u16 vport_num, u16 esw_owner_vhca_id,
10651072 port -> vport_num = vport_num ;
10661073 port -> esw_owner_vhca_id = esw_owner_vhca_id ;
10671074 port -> bridge = bridge ;
1075+ port -> flags |= flags ;
10681076 xa_init (& port -> vlans );
10691077 err = mlx5_esw_bridge_port_insert (port , br_offloads );
10701078 if (err ) {
@@ -1101,9 +1109,10 @@ static int mlx5_esw_bridge_vport_cleanup(struct mlx5_esw_bridge_offloads *br_off
11011109 return 0 ;
11021110}
11031111
1104- int mlx5_esw_bridge_vport_link (int ifindex , u16 vport_num , u16 esw_owner_vhca_id ,
1105- struct mlx5_esw_bridge_offloads * br_offloads ,
1106- struct netlink_ext_ack * extack )
1112+ static int mlx5_esw_bridge_vport_link_with_flags (int ifindex , u16 vport_num , u16 esw_owner_vhca_id ,
1113+ u16 flags ,
1114+ struct mlx5_esw_bridge_offloads * br_offloads ,
1115+ struct netlink_ext_ack * extack )
11071116{
11081117 struct mlx5_esw_bridge * bridge ;
11091118 int err ;
@@ -1114,7 +1123,7 @@ int mlx5_esw_bridge_vport_link(int ifindex, u16 vport_num, u16 esw_owner_vhca_id
11141123 return PTR_ERR (bridge );
11151124 }
11161125
1117- err = mlx5_esw_bridge_vport_init (vport_num , esw_owner_vhca_id , br_offloads , bridge );
1126+ err = mlx5_esw_bridge_vport_init (vport_num , esw_owner_vhca_id , flags , br_offloads , bridge );
11181127 if (err ) {
11191128 NL_SET_ERR_MSG_MOD (extack , "Error initializing port" );
11201129 goto err_vport ;
@@ -1126,6 +1135,14 @@ int mlx5_esw_bridge_vport_link(int ifindex, u16 vport_num, u16 esw_owner_vhca_id
11261135 return err ;
11271136}
11281137
1138+ int mlx5_esw_bridge_vport_link (int ifindex , u16 vport_num , u16 esw_owner_vhca_id ,
1139+ struct mlx5_esw_bridge_offloads * br_offloads ,
1140+ struct netlink_ext_ack * extack )
1141+ {
1142+ return mlx5_esw_bridge_vport_link_with_flags (ifindex , vport_num , esw_owner_vhca_id , 0 ,
1143+ br_offloads , extack );
1144+ }
1145+
11291146int mlx5_esw_bridge_vport_unlink (int ifindex , u16 vport_num , u16 esw_owner_vhca_id ,
11301147 struct mlx5_esw_bridge_offloads * br_offloads ,
11311148 struct netlink_ext_ack * extack )
@@ -1149,6 +1166,26 @@ int mlx5_esw_bridge_vport_unlink(int ifindex, u16 vport_num, u16 esw_owner_vhca_
11491166 return err ;
11501167}
11511168
1169+ int mlx5_esw_bridge_vport_peer_link (int ifindex , u16 vport_num , u16 esw_owner_vhca_id ,
1170+ struct mlx5_esw_bridge_offloads * br_offloads ,
1171+ struct netlink_ext_ack * extack )
1172+ {
1173+ if (!MLX5_CAP_ESW (br_offloads -> esw -> dev , merged_eswitch ))
1174+ return 0 ;
1175+
1176+ return mlx5_esw_bridge_vport_link_with_flags (ifindex , vport_num , esw_owner_vhca_id ,
1177+ MLX5_ESW_BRIDGE_PORT_FLAG_PEER ,
1178+ br_offloads , extack );
1179+ }
1180+
1181+ int mlx5_esw_bridge_vport_peer_unlink (int ifindex , u16 vport_num , u16 esw_owner_vhca_id ,
1182+ struct mlx5_esw_bridge_offloads * br_offloads ,
1183+ struct netlink_ext_ack * extack )
1184+ {
1185+ return mlx5_esw_bridge_vport_unlink (ifindex , vport_num , esw_owner_vhca_id , br_offloads ,
1186+ extack );
1187+ }
1188+
11521189int mlx5_esw_bridge_port_vlan_add (u16 vport_num , u16 esw_owner_vhca_id , u16 vid , u16 flags ,
11531190 struct mlx5_esw_bridge_offloads * br_offloads ,
11541191 struct netlink_ext_ack * extack )
@@ -1206,14 +1243,15 @@ void mlx5_esw_bridge_fdb_create(struct net_device *dev, u16 vport_num, u16 esw_o
12061243 bridge = port -> bridge ;
12071244 entry = mlx5_esw_bridge_fdb_entry_init (dev , vport_num , esw_owner_vhca_id , fdb_info -> addr ,
12081245 fdb_info -> vid , fdb_info -> added_by_user ,
1246+ port -> flags & MLX5_ESW_BRIDGE_PORT_FLAG_PEER ,
12091247 br_offloads -> esw , bridge );
12101248 if (IS_ERR (entry ))
12111249 return ;
12121250
12131251 if (entry -> flags & MLX5_ESW_BRIDGE_FLAG_ADDED_BY_USER )
12141252 mlx5_esw_bridge_fdb_offload_notify (dev , entry -> key .addr , entry -> key .vid ,
12151253 SWITCHDEV_FDB_OFFLOADED );
1216- else
1254+ else if (!( entry -> flags & MLX5_ESW_BRIDGE_FLAG_PEER ))
12171255 /* Take over dynamic entries to prevent kernel bridge from aging them out. */
12181256 mlx5_esw_bridge_fdb_offload_notify (dev , entry -> key .addr , entry -> key .vid ,
12191257 SWITCHDEV_FDB_ADD_TO_BRIDGE );
@@ -1263,7 +1301,8 @@ void mlx5_esw_bridge_update(struct mlx5_esw_bridge_offloads *br_offloads)
12631301
12641302 if (time_after (lastuse , entry -> lastuse )) {
12651303 mlx5_esw_bridge_fdb_entry_refresh (lastuse , entry );
1266- } else if (time_is_before_jiffies (entry -> lastuse + bridge -> ageing_time )) {
1304+ } else if (!(entry -> flags & MLX5_ESW_BRIDGE_FLAG_PEER ) &&
1305+ time_is_before_jiffies (entry -> lastuse + bridge -> ageing_time )) {
12671306 mlx5_esw_bridge_fdb_del_notify (entry );
12681307 mlx5_esw_bridge_fdb_entry_cleanup (entry , bridge );
12691308 }
0 commit comments