@@ -79,7 +79,7 @@ mlx5_esw_bridge_fdb_offload_notify(struct net_device *dev, const unsigned char *
79
79
static void
80
80
mlx5_esw_bridge_fdb_del_notify (struct mlx5_esw_bridge_fdb_entry * entry )
81
81
{
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 ) ))
83
83
mlx5_esw_bridge_fdb_offload_notify (entry -> dev , entry -> key .addr ,
84
84
entry -> key .vid ,
85
85
SWITCHDEV_FDB_DEL_TO_BRIDGE );
@@ -513,7 +513,7 @@ mlx5_esw_bridge_ingress_filter_flow_create(u16 vport_num, const unsigned char *a
513
513
}
514
514
515
515
static 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 ,
517
517
struct mlx5_esw_bridge_vlan * vlan ,
518
518
struct mlx5_esw_bridge * bridge )
519
519
{
@@ -558,6 +558,10 @@ mlx5_esw_bridge_egress_flow_create(u16 vport_num, const unsigned char *addr,
558
558
vlan -> vid );
559
559
}
560
560
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
+ }
561
565
handle = mlx5_add_flow_rules (bridge -> egress_ft , rule_spec , & flow_act , & dest , 1 );
562
566
563
567
kvfree (rule_spec );
@@ -917,7 +921,7 @@ mlx5_esw_bridge_port_vlan_lookup(u16 vid, u16 vport_num, u16 esw_owner_vhca_id,
917
921
918
922
static struct mlx5_esw_bridge_fdb_entry *
919
923
mlx5_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 ,
921
925
struct mlx5_eswitch * esw , struct mlx5_esw_bridge * bridge )
922
926
{
923
927
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
945
949
entry -> lastuse = jiffies ;
946
950
if (added_by_user )
947
951
entry -> flags |= MLX5_ESW_BRIDGE_FLAG_ADDED_BY_USER ;
952
+ if (peer )
953
+ entry -> flags |= MLX5_ESW_BRIDGE_FLAG_PEER ;
948
954
949
955
counter = mlx5_fc_create (esw -> dev , true);
950
956
if (IS_ERR (counter )) {
@@ -974,7 +980,8 @@ mlx5_esw_bridge_fdb_entry_init(struct net_device *dev, u16 vport_num, u16 esw_ow
974
980
entry -> filter_handle = handle ;
975
981
}
976
982
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 );
978
985
if (IS_ERR (handle )) {
979
986
err = PTR_ERR (handle );
980
987
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
1050
1057
return 0 ;
1051
1058
}
1052
1059
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 ,
1054
1061
struct mlx5_esw_bridge_offloads * br_offloads ,
1055
1062
struct mlx5_esw_bridge * bridge )
1056
1063
{
@@ -1065,6 +1072,7 @@ static int mlx5_esw_bridge_vport_init(u16 vport_num, u16 esw_owner_vhca_id,
1065
1072
port -> vport_num = vport_num ;
1066
1073
port -> esw_owner_vhca_id = esw_owner_vhca_id ;
1067
1074
port -> bridge = bridge ;
1075
+ port -> flags |= flags ;
1068
1076
xa_init (& port -> vlans );
1069
1077
err = mlx5_esw_bridge_port_insert (port , br_offloads );
1070
1078
if (err ) {
@@ -1101,9 +1109,10 @@ static int mlx5_esw_bridge_vport_cleanup(struct mlx5_esw_bridge_offloads *br_off
1101
1109
return 0 ;
1102
1110
}
1103
1111
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 )
1107
1116
{
1108
1117
struct mlx5_esw_bridge * bridge ;
1109
1118
int err ;
@@ -1114,7 +1123,7 @@ int mlx5_esw_bridge_vport_link(int ifindex, u16 vport_num, u16 esw_owner_vhca_id
1114
1123
return PTR_ERR (bridge );
1115
1124
}
1116
1125
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 );
1118
1127
if (err ) {
1119
1128
NL_SET_ERR_MSG_MOD (extack , "Error initializing port" );
1120
1129
goto err_vport ;
@@ -1126,6 +1135,14 @@ int mlx5_esw_bridge_vport_link(int ifindex, u16 vport_num, u16 esw_owner_vhca_id
1126
1135
return err ;
1127
1136
}
1128
1137
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
+
1129
1146
int mlx5_esw_bridge_vport_unlink (int ifindex , u16 vport_num , u16 esw_owner_vhca_id ,
1130
1147
struct mlx5_esw_bridge_offloads * br_offloads ,
1131
1148
struct netlink_ext_ack * extack )
@@ -1149,6 +1166,26 @@ int mlx5_esw_bridge_vport_unlink(int ifindex, u16 vport_num, u16 esw_owner_vhca_
1149
1166
return err ;
1150
1167
}
1151
1168
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
+
1152
1189
int mlx5_esw_bridge_port_vlan_add (u16 vport_num , u16 esw_owner_vhca_id , u16 vid , u16 flags ,
1153
1190
struct mlx5_esw_bridge_offloads * br_offloads ,
1154
1191
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
1206
1243
bridge = port -> bridge ;
1207
1244
entry = mlx5_esw_bridge_fdb_entry_init (dev , vport_num , esw_owner_vhca_id , fdb_info -> addr ,
1208
1245
fdb_info -> vid , fdb_info -> added_by_user ,
1246
+ port -> flags & MLX5_ESW_BRIDGE_PORT_FLAG_PEER ,
1209
1247
br_offloads -> esw , bridge );
1210
1248
if (IS_ERR (entry ))
1211
1249
return ;
1212
1250
1213
1251
if (entry -> flags & MLX5_ESW_BRIDGE_FLAG_ADDED_BY_USER )
1214
1252
mlx5_esw_bridge_fdb_offload_notify (dev , entry -> key .addr , entry -> key .vid ,
1215
1253
SWITCHDEV_FDB_OFFLOADED );
1216
- else
1254
+ else if (!( entry -> flags & MLX5_ESW_BRIDGE_FLAG_PEER ))
1217
1255
/* Take over dynamic entries to prevent kernel bridge from aging them out. */
1218
1256
mlx5_esw_bridge_fdb_offload_notify (dev , entry -> key .addr , entry -> key .vid ,
1219
1257
SWITCHDEV_FDB_ADD_TO_BRIDGE );
@@ -1263,7 +1301,8 @@ void mlx5_esw_bridge_update(struct mlx5_esw_bridge_offloads *br_offloads)
1263
1301
1264
1302
if (time_after (lastuse , entry -> lastuse )) {
1265
1303
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 )) {
1267
1306
mlx5_esw_bridge_fdb_del_notify (entry );
1268
1307
mlx5_esw_bridge_fdb_entry_cleanup (entry , bridge );
1269
1308
}
0 commit comments