1 /* 2 * Copyright (c) 2016, Mellanox Technologies. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32 33 #include <net/flow_dissector.h> 34 #include <net/flow_offload.h> 35 #include <net/sch_generic.h> 36 #include <net/pkt_cls.h> 37 #include <linux/mlx5/fs.h> 38 #include <linux/mlx5/lag.h> 39 #include <linux/mlx5/device.h> 40 #include <linux/rhashtable.h> 41 #include <linux/refcount.h> 42 #include <linux/completion.h> 43 #include <net/arp.h> 44 #include <net/bareudp.h> 45 #include <net/bonding.h> 46 #include <net/dst_metadata.h> 47 #include "devlink.h" 48 #include "en.h" 49 #include "en/tc/post_act.h" 50 #include "en/tc/act_stats.h" 51 #include "en_rep.h" 52 #include "en/rep/tc.h" 53 #include "en/rep/neigh.h" 54 #include "en_tc.h" 55 #include "eswitch.h" 56 #include "fs_core.h" 57 #include "en/port.h" 58 #include "en/tc_tun.h" 59 #include "en/mapping.h" 60 #include "en/tc_ct.h" 61 #include "en/mod_hdr.h" 62 #include "en/tc_tun_encap.h" 63 #include "en/tc/sample.h" 64 #include "en/tc/act/act.h" 65 #include "en/tc/post_meter.h" 66 #include "lib/devcom.h" 67 #include "lib/geneve.h" 68 #include "lib/fs_chains.h" 69 #include "lib/mlx5.h" 70 #include "diag/en_tc_tracepoint.h" 71 #include <asm/div64.h> 72 #include "lag/lag.h" 73 #include "lag/mp.h" 74 #include "lib/sd.h" 75 76 #define MLX5E_TC_TABLE_NUM_GROUPS 4 77 #define MLX5E_TC_TABLE_MAX_GROUP_SIZE BIT(18) 78 79 struct mlx5e_tc_table { 80 /* Protects the dynamic assignment of the t parameter 81 * which is the nic tc root table. 82 */ 83 struct mutex t_lock; 84 struct mlx5e_priv *priv; 85 struct mlx5_flow_table *t; 86 struct mlx5_flow_table *miss_t; 87 struct mlx5_fs_chains *chains; 88 struct mlx5e_post_act *post_act; 89 90 struct rhashtable ht; 91 92 struct mod_hdr_tbl mod_hdr; 93 struct mutex hairpin_tbl_lock; /* protects hairpin_tbl */ 94 DECLARE_HASHTABLE(hairpin_tbl, 8); 95 96 struct notifier_block netdevice_nb; 97 struct netdev_net_notifier netdevice_nn; 98 99 struct mlx5_tc_ct_priv *ct; 100 struct mapping_ctx *mapping; 101 struct dentry *dfs_root; 102 103 /* tc action stats */ 104 struct mlx5e_tc_act_stats_handle *action_stats_handle; 105 }; 106 107 struct mlx5e_tc_attr_to_reg_mapping mlx5e_tc_attr_to_reg_mappings[] = { 108 [MAPPED_OBJ_TO_REG] = { 109 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_0, 110 .moffset = 0, 111 .mlen = 16, 112 }, 113 [VPORT_TO_REG] = { 114 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_0, 115 .moffset = 16, 116 .mlen = 16, 117 }, 118 [TUNNEL_TO_REG] = { 119 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_1, 120 .moffset = 8, 121 .mlen = ESW_TUN_OPTS_BITS + ESW_TUN_ID_BITS, 122 .soffset = MLX5_BYTE_OFF(fte_match_param, 123 misc_parameters_2.metadata_reg_c_1), 124 }, 125 [ZONE_TO_REG] = zone_to_reg_ct, 126 [ZONE_RESTORE_TO_REG] = zone_restore_to_reg_ct, 127 [CTSTATE_TO_REG] = ctstate_to_reg_ct, 128 [MARK_TO_REG] = mark_to_reg_ct, 129 [LABELS_TO_REG] = labels_to_reg_ct, 130 [FTEID_TO_REG] = fteid_to_reg_ct, 131 /* For NIC rules we store the restore metadata directly 132 * into reg_b that is passed to SW since we don't 133 * jump between steering domains. 134 */ 135 [NIC_MAPPED_OBJ_TO_REG] = { 136 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_B, 137 .moffset = 0, 138 .mlen = 16, 139 }, 140 [NIC_ZONE_RESTORE_TO_REG] = nic_zone_restore_to_reg_ct, 141 [PACKET_COLOR_TO_REG] = packet_color_to_reg, 142 }; 143 144 struct mlx5e_tc_jump_state { 145 u32 jump_count; 146 bool jump_target; 147 struct mlx5_flow_attr *jumping_attr; 148 149 enum flow_action_id last_id; 150 u32 last_index; 151 }; 152 153 struct mlx5e_tc_table *mlx5e_tc_table_alloc(void) 154 { 155 struct mlx5e_tc_table *tc; 156 157 tc = kvzalloc_obj(*tc); 158 return tc ? tc : ERR_PTR(-ENOMEM); 159 } 160 161 void mlx5e_tc_table_free(struct mlx5e_tc_table *tc) 162 { 163 kvfree(tc); 164 } 165 166 struct mlx5_fs_chains *mlx5e_nic_chains(struct mlx5e_tc_table *tc) 167 { 168 return tc->chains; 169 } 170 171 /* To avoid false lock dependency warning set the tc_ht lock 172 * class different than the lock class of the ht being used when deleting 173 * last flow from a group and then deleting a group, we get into del_sw_flow_group() 174 * which call rhashtable_destroy on fg->ftes_hash which will take ht->mutex but 175 * it's different than the ht->mutex here. 176 */ 177 static struct lock_class_key tc_ht_lock_key; 178 static struct lock_class_key tc_ht_wq_key; 179 180 static void mlx5e_put_flow_tunnel_id(struct mlx5e_tc_flow *flow); 181 static void free_flow_post_acts(struct mlx5e_tc_flow *flow); 182 static void mlx5_free_flow_attr_actions(struct mlx5e_tc_flow *flow, 183 struct mlx5_flow_attr *attr); 184 185 void 186 mlx5e_tc_match_to_reg_match(struct mlx5_flow_spec *spec, 187 enum mlx5e_tc_attr_to_reg type, 188 u32 val, 189 u32 mask) 190 { 191 void *headers_c = spec->match_criteria, *headers_v = spec->match_value, *fmask, *fval; 192 int soffset = mlx5e_tc_attr_to_reg_mappings[type].soffset; 193 int moffset = mlx5e_tc_attr_to_reg_mappings[type].moffset; 194 int match_len = mlx5e_tc_attr_to_reg_mappings[type].mlen; 195 u32 max_mask = GENMASK(match_len - 1, 0); 196 __be32 curr_mask_be, curr_val_be; 197 u32 curr_mask, curr_val; 198 199 fmask = headers_c + soffset; 200 fval = headers_v + soffset; 201 202 memcpy(&curr_mask_be, fmask, 4); 203 memcpy(&curr_val_be, fval, 4); 204 205 curr_mask = be32_to_cpu(curr_mask_be); 206 curr_val = be32_to_cpu(curr_val_be); 207 208 //move to correct offset 209 WARN_ON(mask > max_mask); 210 mask <<= moffset; 211 val <<= moffset; 212 max_mask <<= moffset; 213 214 //zero val and mask 215 curr_mask &= ~max_mask; 216 curr_val &= ~max_mask; 217 218 //add current to mask 219 curr_mask |= mask; 220 curr_val |= val; 221 222 //back to be32 and write 223 curr_mask_be = cpu_to_be32(curr_mask); 224 curr_val_be = cpu_to_be32(curr_val); 225 226 memcpy(fmask, &curr_mask_be, 4); 227 memcpy(fval, &curr_val_be, 4); 228 229 spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_2; 230 } 231 232 void 233 mlx5e_tc_match_to_reg_get_match(struct mlx5_flow_spec *spec, 234 enum mlx5e_tc_attr_to_reg type, 235 u32 *val, 236 u32 *mask) 237 { 238 void *headers_c = spec->match_criteria, *headers_v = spec->match_value, *fmask, *fval; 239 int soffset = mlx5e_tc_attr_to_reg_mappings[type].soffset; 240 int moffset = mlx5e_tc_attr_to_reg_mappings[type].moffset; 241 int match_len = mlx5e_tc_attr_to_reg_mappings[type].mlen; 242 u32 max_mask = GENMASK(match_len - 1, 0); 243 __be32 curr_mask_be, curr_val_be; 244 u32 curr_mask, curr_val; 245 246 fmask = headers_c + soffset; 247 fval = headers_v + soffset; 248 249 memcpy(&curr_mask_be, fmask, 4); 250 memcpy(&curr_val_be, fval, 4); 251 252 curr_mask = be32_to_cpu(curr_mask_be); 253 curr_val = be32_to_cpu(curr_val_be); 254 255 *mask = (curr_mask >> moffset) & max_mask; 256 *val = (curr_val >> moffset) & max_mask; 257 } 258 259 int 260 mlx5e_tc_match_to_reg_set_and_get_id(struct mlx5_core_dev *mdev, 261 struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts, 262 enum mlx5_flow_namespace_type ns, 263 enum mlx5e_tc_attr_to_reg type, 264 u32 data) 265 { 266 int moffset = mlx5e_tc_attr_to_reg_mappings[type].moffset; 267 int mfield = mlx5e_tc_attr_to_reg_mappings[type].mfield; 268 int mlen = mlx5e_tc_attr_to_reg_mappings[type].mlen; 269 char *modact; 270 int err; 271 272 modact = mlx5e_mod_hdr_alloc(mdev, ns, mod_hdr_acts); 273 if (IS_ERR(modact)) 274 return PTR_ERR(modact); 275 276 /* Firmware has 5bit length field and 0 means 32bits */ 277 if (mlen == 32) 278 mlen = 0; 279 280 MLX5_SET(set_action_in, modact, action_type, MLX5_ACTION_TYPE_SET); 281 MLX5_SET(set_action_in, modact, field, mfield); 282 MLX5_SET(set_action_in, modact, offset, moffset); 283 MLX5_SET(set_action_in, modact, length, mlen); 284 MLX5_SET(set_action_in, modact, data, data); 285 err = mod_hdr_acts->num_actions; 286 mod_hdr_acts->num_actions++; 287 288 return err; 289 } 290 291 static struct mlx5e_tc_act_stats_handle * 292 get_act_stats_handle(struct mlx5e_priv *priv) 293 { 294 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 295 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 296 struct mlx5_rep_uplink_priv *uplink_priv; 297 struct mlx5e_rep_priv *uplink_rpriv; 298 299 if (is_mdev_switchdev_mode(priv->mdev)) { 300 uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); 301 uplink_priv = &uplink_rpriv->uplink_priv; 302 303 return uplink_priv->action_stats_handle; 304 } 305 306 return tc->action_stats_handle; 307 } 308 309 struct mlx5e_tc_int_port_priv * 310 mlx5e_get_int_port_priv(struct mlx5e_priv *priv) 311 { 312 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 313 struct mlx5_rep_uplink_priv *uplink_priv; 314 struct mlx5e_rep_priv *uplink_rpriv; 315 316 if (is_mdev_switchdev_mode(priv->mdev)) { 317 uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); 318 uplink_priv = &uplink_rpriv->uplink_priv; 319 320 return uplink_priv->int_port_priv; 321 } 322 323 return NULL; 324 } 325 326 struct mlx5e_flow_meters * 327 mlx5e_get_flow_meters(struct mlx5_core_dev *dev) 328 { 329 struct mlx5_eswitch *esw = dev->priv.eswitch; 330 struct mlx5_rep_uplink_priv *uplink_priv; 331 struct mlx5e_rep_priv *uplink_rpriv; 332 struct mlx5e_priv *priv; 333 334 if (is_mdev_switchdev_mode(dev)) { 335 uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); 336 uplink_priv = &uplink_rpriv->uplink_priv; 337 priv = netdev_priv(uplink_rpriv->netdev); 338 if (!uplink_priv->flow_meters) 339 uplink_priv->flow_meters = 340 mlx5e_flow_meters_init(priv, 341 MLX5_FLOW_NAMESPACE_FDB, 342 uplink_priv->post_act); 343 if (!IS_ERR(uplink_priv->flow_meters)) 344 return uplink_priv->flow_meters; 345 } 346 347 return NULL; 348 } 349 350 static struct mlx5_tc_ct_priv * 351 get_ct_priv(struct mlx5e_priv *priv) 352 { 353 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 354 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 355 struct mlx5_rep_uplink_priv *uplink_priv; 356 struct mlx5e_rep_priv *uplink_rpriv; 357 358 if (is_mdev_switchdev_mode(priv->mdev)) { 359 uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); 360 uplink_priv = &uplink_rpriv->uplink_priv; 361 362 return uplink_priv->ct_priv; 363 } 364 365 return tc->ct; 366 } 367 368 static struct mlx5e_tc_psample * 369 get_sample_priv(struct mlx5e_priv *priv) 370 { 371 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 372 struct mlx5_rep_uplink_priv *uplink_priv; 373 struct mlx5e_rep_priv *uplink_rpriv; 374 375 if (is_mdev_switchdev_mode(priv->mdev)) { 376 uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); 377 uplink_priv = &uplink_rpriv->uplink_priv; 378 379 return uplink_priv->tc_psample; 380 } 381 382 return NULL; 383 } 384 385 static struct mlx5e_post_act * 386 get_post_action(struct mlx5e_priv *priv) 387 { 388 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 389 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 390 struct mlx5_rep_uplink_priv *uplink_priv; 391 struct mlx5e_rep_priv *uplink_rpriv; 392 393 if (is_mdev_switchdev_mode(priv->mdev)) { 394 uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); 395 uplink_priv = &uplink_rpriv->uplink_priv; 396 397 return uplink_priv->post_act; 398 } 399 400 return tc->post_act; 401 } 402 403 struct mlx5_flow_handle * 404 mlx5_tc_rule_insert(struct mlx5e_priv *priv, 405 struct mlx5_flow_spec *spec, 406 struct mlx5_flow_attr *attr) 407 { 408 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 409 410 if (is_mdev_switchdev_mode(priv->mdev)) 411 return mlx5_eswitch_add_offloaded_rule(esw, spec, attr); 412 413 return mlx5e_add_offloaded_nic_rule(priv, spec, attr); 414 } 415 416 void 417 mlx5_tc_rule_delete(struct mlx5e_priv *priv, 418 struct mlx5_flow_handle *rule, 419 struct mlx5_flow_attr *attr) 420 { 421 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 422 423 if (is_mdev_switchdev_mode(priv->mdev)) { 424 mlx5_eswitch_del_offloaded_rule(esw, rule, attr); 425 return; 426 } 427 428 mlx5e_del_offloaded_nic_rule(priv, rule, attr); 429 } 430 431 static bool 432 is_flow_meter_action(struct mlx5_flow_attr *attr) 433 { 434 return (((attr->action & MLX5_FLOW_CONTEXT_ACTION_EXECUTE_ASO) && 435 (attr->exe_aso_type == MLX5_EXE_ASO_FLOW_METER)) || 436 attr->flags & MLX5_ATTR_FLAG_MTU); 437 } 438 439 static int 440 mlx5e_tc_add_flow_meter(struct mlx5e_priv *priv, 441 struct mlx5_flow_attr *attr) 442 { 443 struct mlx5e_post_act *post_act = get_post_action(priv); 444 struct mlx5e_post_meter_priv *post_meter; 445 enum mlx5_flow_namespace_type ns_type; 446 struct mlx5e_flow_meter_handle *meter; 447 enum mlx5e_post_meter_type type; 448 449 if (IS_ERR(post_act)) 450 return PTR_ERR(post_act); 451 452 meter = mlx5e_tc_meter_replace(priv->mdev, &attr->meter_attr.params); 453 if (IS_ERR(meter)) { 454 mlx5_core_err(priv->mdev, "Failed to get flow meter\n"); 455 return PTR_ERR(meter); 456 } 457 458 ns_type = mlx5e_tc_meter_get_namespace(meter->flow_meters); 459 type = meter->params.mtu ? MLX5E_POST_METER_MTU : MLX5E_POST_METER_RATE; 460 post_meter = mlx5e_post_meter_init(priv, ns_type, post_act, 461 type, 462 meter->act_counter, meter->drop_counter, 463 attr->branch_true, attr->branch_false); 464 if (IS_ERR(post_meter)) { 465 mlx5_core_err(priv->mdev, "Failed to init post meter\n"); 466 goto err_meter_init; 467 } 468 469 attr->meter_attr.meter = meter; 470 attr->meter_attr.post_meter = post_meter; 471 attr->dest_ft = mlx5e_post_meter_get_ft(post_meter); 472 attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 473 474 return 0; 475 476 err_meter_init: 477 mlx5e_tc_meter_put(meter); 478 return PTR_ERR(post_meter); 479 } 480 481 static void 482 mlx5e_tc_del_flow_meter(struct mlx5_eswitch *esw, struct mlx5_flow_attr *attr) 483 { 484 mlx5e_post_meter_cleanup(esw, attr->meter_attr.post_meter); 485 mlx5e_tc_meter_put(attr->meter_attr.meter); 486 } 487 488 struct mlx5_flow_handle * 489 mlx5e_tc_rule_offload(struct mlx5e_priv *priv, 490 struct mlx5_flow_spec *spec, 491 struct mlx5_flow_attr *attr) 492 { 493 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 494 int err; 495 496 if (!is_mdev_switchdev_mode(priv->mdev)) 497 return mlx5e_add_offloaded_nic_rule(priv, spec, attr); 498 499 if (attr->flags & MLX5_ATTR_FLAG_SAMPLE) 500 return mlx5e_tc_sample_offload(get_sample_priv(priv), spec, attr); 501 502 if (is_flow_meter_action(attr)) { 503 err = mlx5e_tc_add_flow_meter(priv, attr); 504 if (err) 505 return ERR_PTR(err); 506 } 507 508 return mlx5_eswitch_add_offloaded_rule(esw, spec, attr); 509 } 510 511 void 512 mlx5e_tc_rule_unoffload(struct mlx5e_priv *priv, 513 struct mlx5_flow_handle *rule, 514 struct mlx5_flow_attr *attr) 515 { 516 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 517 518 if (!is_mdev_switchdev_mode(priv->mdev)) { 519 mlx5e_del_offloaded_nic_rule(priv, rule, attr); 520 return; 521 } 522 523 if (attr->flags & MLX5_ATTR_FLAG_SAMPLE) { 524 mlx5e_tc_sample_unoffload(get_sample_priv(priv), rule, attr); 525 return; 526 } 527 528 mlx5_eswitch_del_offloaded_rule(esw, rule, attr); 529 530 if (attr->meter_attr.meter) 531 mlx5e_tc_del_flow_meter(esw, attr); 532 } 533 534 int 535 mlx5e_tc_match_to_reg_set(struct mlx5_core_dev *mdev, 536 struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts, 537 enum mlx5_flow_namespace_type ns, 538 enum mlx5e_tc_attr_to_reg type, 539 u32 data) 540 { 541 int ret = mlx5e_tc_match_to_reg_set_and_get_id(mdev, mod_hdr_acts, ns, type, data); 542 543 return ret < 0 ? ret : 0; 544 } 545 546 void mlx5e_tc_match_to_reg_mod_hdr_change(struct mlx5_core_dev *mdev, 547 struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts, 548 enum mlx5e_tc_attr_to_reg type, 549 int act_id, u32 data) 550 { 551 int moffset = mlx5e_tc_attr_to_reg_mappings[type].moffset; 552 int mfield = mlx5e_tc_attr_to_reg_mappings[type].mfield; 553 int mlen = mlx5e_tc_attr_to_reg_mappings[type].mlen; 554 char *modact; 555 556 modact = mlx5e_mod_hdr_get_item(mod_hdr_acts, act_id); 557 558 /* Firmware has 5bit length field and 0 means 32bits */ 559 if (mlen == 32) 560 mlen = 0; 561 562 MLX5_SET(set_action_in, modact, action_type, MLX5_ACTION_TYPE_SET); 563 MLX5_SET(set_action_in, modact, field, mfield); 564 MLX5_SET(set_action_in, modact, offset, moffset); 565 MLX5_SET(set_action_in, modact, length, mlen); 566 MLX5_SET(set_action_in, modact, data, data); 567 } 568 569 struct mlx5e_hairpin { 570 struct mlx5_hairpin *pair; 571 572 struct mlx5_core_dev *func_mdev; 573 struct mlx5e_priv *func_priv; 574 u32 tdn; 575 struct mlx5e_tir direct_tir; 576 577 int num_channels; 578 u8 log_num_packets; 579 struct mlx5e_rqt indir_rqt; 580 struct mlx5e_tir indir_tir[MLX5E_NUM_INDIR_TIRS]; 581 struct mlx5_ttc_table *ttc; 582 }; 583 584 struct mlx5e_hairpin_entry { 585 /* a node of a hash table which keeps all the hairpin entries */ 586 struct hlist_node hairpin_hlist; 587 588 /* protects flows list */ 589 spinlock_t flows_lock; 590 /* flows sharing the same hairpin */ 591 struct list_head flows; 592 /* hpe's that were not fully initialized when dead peer update event 593 * function traversed them. 594 */ 595 struct list_head dead_peer_wait_list; 596 597 u16 peer_vhca_id; 598 u8 prio; 599 struct mlx5e_hairpin *hp; 600 refcount_t refcnt; 601 struct completion res_ready; 602 }; 603 604 static void mlx5e_tc_del_flow(struct mlx5e_priv *priv, 605 struct mlx5e_tc_flow *flow); 606 607 struct mlx5e_tc_flow *mlx5e_flow_get(struct mlx5e_tc_flow *flow) 608 { 609 if (!flow || !refcount_inc_not_zero(&flow->refcnt)) 610 return ERR_PTR(-EINVAL); 611 return flow; 612 } 613 614 void mlx5e_flow_put(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow) 615 { 616 if (refcount_dec_and_test(&flow->refcnt)) { 617 mlx5e_tc_del_flow(priv, flow); 618 kfree_rcu(flow, rcu_head); 619 } 620 } 621 622 bool mlx5e_is_eswitch_flow(struct mlx5e_tc_flow *flow) 623 { 624 return flow_flag_test(flow, ESWITCH); 625 } 626 627 bool mlx5e_is_ft_flow(struct mlx5e_tc_flow *flow) 628 { 629 return flow_flag_test(flow, FT); 630 } 631 632 bool mlx5e_is_offloaded_flow(struct mlx5e_tc_flow *flow) 633 { 634 return flow_flag_test(flow, OFFLOADED); 635 } 636 637 int mlx5e_get_flow_namespace(struct mlx5e_tc_flow *flow) 638 { 639 return mlx5e_is_eswitch_flow(flow) ? 640 MLX5_FLOW_NAMESPACE_FDB : MLX5_FLOW_NAMESPACE_KERNEL; 641 } 642 643 static struct mlx5_core_dev * 644 get_flow_counter_dev(struct mlx5e_tc_flow *flow) 645 { 646 return mlx5e_is_eswitch_flow(flow) ? flow->attr->esw_attr->counter_dev : flow->priv->mdev; 647 } 648 649 static struct mod_hdr_tbl * 650 get_mod_hdr_table(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow) 651 { 652 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 653 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 654 655 return mlx5e_get_flow_namespace(flow) == MLX5_FLOW_NAMESPACE_FDB ? 656 &esw->offloads.mod_hdr : 657 &tc->mod_hdr; 658 } 659 660 int mlx5e_tc_attach_mod_hdr(struct mlx5e_priv *priv, 661 struct mlx5e_tc_flow *flow, 662 struct mlx5_flow_attr *attr) 663 { 664 struct mlx5e_mod_hdr_handle *mh; 665 666 mh = mlx5e_mod_hdr_attach(priv->mdev, get_mod_hdr_table(priv, flow), 667 mlx5e_get_flow_namespace(flow), 668 &attr->parse_attr->mod_hdr_acts); 669 if (IS_ERR(mh)) 670 return PTR_ERR(mh); 671 672 WARN_ON(attr->modify_hdr); 673 attr->modify_hdr = mlx5e_mod_hdr_get(mh); 674 attr->mh = mh; 675 676 return 0; 677 } 678 679 void mlx5e_tc_detach_mod_hdr(struct mlx5e_priv *priv, 680 struct mlx5e_tc_flow *flow, 681 struct mlx5_flow_attr *attr) 682 { 683 /* flow wasn't fully initialized */ 684 if (!attr->mh) 685 return; 686 687 mlx5e_mod_hdr_detach(priv->mdev, get_mod_hdr_table(priv, flow), 688 attr->mh); 689 attr->mh = NULL; 690 } 691 692 static 693 struct mlx5_core_dev *mlx5e_hairpin_get_mdev(struct net *net, int ifindex) 694 { 695 struct mlx5_core_dev *mdev; 696 struct net_device *netdev; 697 struct mlx5e_priv *priv; 698 699 netdev = dev_get_by_index(net, ifindex); 700 if (!netdev) 701 return ERR_PTR(-ENODEV); 702 703 priv = netdev_priv(netdev); 704 mdev = priv->mdev; 705 dev_put(netdev); 706 707 /* Mirred tc action holds a refcount on the ifindex net_device (see 708 * net/sched/act_mirred.c:tcf_mirred_get_dev). So, it's okay to continue using mdev 709 * after dev_put(netdev), while we're in the context of adding a tc flow. 710 * 711 * The mdev pointer corresponds to the peer/out net_device of a hairpin. It is then 712 * stored in a hairpin object, which exists until all flows, that refer to it, get 713 * removed. 714 * 715 * On the other hand, after a hairpin object has been created, the peer net_device may 716 * be removed/unbound while there are still some hairpin flows that are using it. This 717 * case is handled by mlx5e_tc_hairpin_update_dead_peer, which is hooked to 718 * NETDEV_UNREGISTER event of the peer net_device. 719 */ 720 return mdev; 721 } 722 723 static int mlx5e_hairpin_create_transport(struct mlx5e_hairpin *hp) 724 { 725 struct mlx5e_tir_builder *builder; 726 int err; 727 728 builder = mlx5e_tir_builder_alloc(false); 729 if (!builder) 730 return -ENOMEM; 731 732 err = mlx5_core_alloc_transport_domain(hp->func_mdev, &hp->tdn); 733 if (err) 734 goto out; 735 736 mlx5e_tir_builder_build_inline(builder, hp->tdn, hp->pair->rqn[0]); 737 err = mlx5e_tir_init(&hp->direct_tir, builder, hp->func_mdev, false); 738 if (err) 739 goto create_tir_err; 740 741 out: 742 mlx5e_tir_builder_free(builder); 743 return err; 744 745 create_tir_err: 746 mlx5_core_dealloc_transport_domain(hp->func_mdev, hp->tdn); 747 748 goto out; 749 } 750 751 static void mlx5e_hairpin_destroy_transport(struct mlx5e_hairpin *hp) 752 { 753 mlx5e_tir_destroy(&hp->direct_tir); 754 mlx5_core_dealloc_transport_domain(hp->func_mdev, hp->tdn); 755 } 756 757 static int mlx5e_hairpin_create_indirect_rqt(struct mlx5e_hairpin *hp) 758 { 759 struct mlx5e_priv *priv = hp->func_priv; 760 struct mlx5_core_dev *mdev = priv->mdev; 761 struct mlx5e_rss_params_indir indir; 762 u32 rqt_size; 763 int err; 764 765 rqt_size = mlx5e_rqt_size(mdev, hp->num_channels); 766 err = mlx5e_rss_params_indir_init(&indir, rqt_size, rqt_size); 767 if (err) 768 return err; 769 770 mlx5e_rss_params_indir_init_uniform(&indir, hp->num_channels); 771 err = mlx5e_rqt_init_indir(&hp->indir_rqt, mdev, hp->pair->rqn, NULL, hp->num_channels, 772 mlx5e_rx_res_get_current_hash(priv->rx_res).hfunc, 773 &indir); 774 775 mlx5e_rss_params_indir_cleanup(&indir); 776 return err; 777 } 778 779 static int mlx5e_hairpin_create_indirect_tirs(struct mlx5e_hairpin *hp) 780 { 781 struct mlx5e_priv *priv = hp->func_priv; 782 struct mlx5e_rss_params_hash rss_hash; 783 enum mlx5_traffic_types tt, max_tt; 784 struct mlx5e_tir_builder *builder; 785 int err = 0; 786 787 builder = mlx5e_tir_builder_alloc(false); 788 if (!builder) 789 return -ENOMEM; 790 791 rss_hash = mlx5e_rx_res_get_current_hash(priv->rx_res); 792 793 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) { 794 struct mlx5e_rss_params_traffic_type rss_tt; 795 796 rss_tt = mlx5e_rss_get_default_tt_config(tt); 797 798 mlx5e_tir_builder_build_rqt(builder, hp->tdn, 799 mlx5e_rqt_get_rqtn(&hp->indir_rqt), 800 false); 801 mlx5e_tir_builder_build_rss(builder, &rss_hash, &rss_tt, false); 802 803 err = mlx5e_tir_init(&hp->indir_tir[tt], builder, hp->func_mdev, false); 804 if (err) { 805 mlx5_core_warn(hp->func_mdev, "create indirect tirs failed, %d\n", err); 806 goto err_destroy_tirs; 807 } 808 809 mlx5e_tir_builder_clear(builder); 810 } 811 812 out: 813 mlx5e_tir_builder_free(builder); 814 return err; 815 816 err_destroy_tirs: 817 max_tt = tt; 818 for (tt = 0; tt < max_tt; tt++) 819 mlx5e_tir_destroy(&hp->indir_tir[tt]); 820 821 goto out; 822 } 823 824 static void mlx5e_hairpin_destroy_indirect_tirs(struct mlx5e_hairpin *hp) 825 { 826 int tt; 827 828 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) 829 mlx5e_tir_destroy(&hp->indir_tir[tt]); 830 } 831 832 static void mlx5e_hairpin_set_ttc_params(struct mlx5e_hairpin *hp, 833 struct ttc_params *ttc_params) 834 { 835 struct mlx5_flow_table_attr *ft_attr = &ttc_params->ft_attr; 836 int tt; 837 838 memset(ttc_params, 0, sizeof(*ttc_params)); 839 840 ttc_params->ns_type = MLX5_FLOW_NAMESPACE_KERNEL; 841 for (tt = 0; tt < MLX5_NUM_TT; tt++) { 842 if (mlx5_ttc_is_decrypted_esp_tt(tt)) 843 continue; 844 845 ttc_params->dests[tt].type = MLX5_FLOW_DESTINATION_TYPE_TIR; 846 ttc_params->dests[tt].tir_num = 847 tt == MLX5_TT_ANY ? 848 mlx5e_tir_get_tirn(&hp->direct_tir) : 849 mlx5e_tir_get_tirn(&hp->indir_tir[tt]); 850 } 851 852 ft_attr->level = MLX5E_TC_TTC_FT_LEVEL; 853 ft_attr->prio = MLX5E_TC_PRIO; 854 } 855 856 static int mlx5e_hairpin_rss_init(struct mlx5e_hairpin *hp) 857 { 858 struct mlx5e_priv *priv = hp->func_priv; 859 struct ttc_params ttc_params; 860 struct mlx5_ttc_table *ttc; 861 int err; 862 863 err = mlx5e_hairpin_create_indirect_rqt(hp); 864 if (err) 865 return err; 866 867 err = mlx5e_hairpin_create_indirect_tirs(hp); 868 if (err) 869 goto err_create_indirect_tirs; 870 871 mlx5e_hairpin_set_ttc_params(hp, &ttc_params); 872 hp->ttc = mlx5_create_ttc_table(priv->mdev, &ttc_params); 873 if (IS_ERR(hp->ttc)) { 874 err = PTR_ERR(hp->ttc); 875 goto err_create_ttc_table; 876 } 877 878 ttc = mlx5e_fs_get_ttc(priv->fs, false); 879 netdev_dbg(priv->netdev, "add hairpin: using %d channels rss ttc table id %x\n", 880 hp->num_channels, 881 mlx5_get_ttc_flow_table(ttc)->id); 882 883 return 0; 884 885 err_create_ttc_table: 886 mlx5e_hairpin_destroy_indirect_tirs(hp); 887 err_create_indirect_tirs: 888 mlx5e_rqt_destroy(&hp->indir_rqt); 889 890 return err; 891 } 892 893 static void mlx5e_hairpin_rss_cleanup(struct mlx5e_hairpin *hp) 894 { 895 mlx5_destroy_ttc_table(hp->ttc); 896 mlx5e_hairpin_destroy_indirect_tirs(hp); 897 mlx5e_rqt_destroy(&hp->indir_rqt); 898 } 899 900 static struct mlx5e_hairpin * 901 mlx5e_hairpin_create(struct mlx5e_priv *priv, struct mlx5_hairpin_params *params, 902 int peer_ifindex) 903 { 904 struct mlx5_core_dev *func_mdev, *peer_mdev; 905 struct mlx5e_hairpin *hp; 906 struct mlx5_hairpin *pair; 907 int err; 908 909 hp = kzalloc_obj(*hp); 910 if (!hp) 911 return ERR_PTR(-ENOMEM); 912 913 func_mdev = priv->mdev; 914 peer_mdev = mlx5e_hairpin_get_mdev(dev_net(priv->netdev), peer_ifindex); 915 if (IS_ERR(peer_mdev)) { 916 err = PTR_ERR(peer_mdev); 917 goto create_pair_err; 918 } 919 920 pair = mlx5_core_hairpin_create(func_mdev, peer_mdev, params); 921 if (IS_ERR(pair)) { 922 err = PTR_ERR(pair); 923 goto create_pair_err; 924 } 925 hp->pair = pair; 926 hp->func_mdev = func_mdev; 927 hp->func_priv = priv; 928 hp->num_channels = params->num_channels; 929 hp->log_num_packets = params->log_num_packets; 930 931 err = mlx5e_hairpin_create_transport(hp); 932 if (err) 933 goto create_transport_err; 934 935 if (hp->num_channels > 1) { 936 err = mlx5e_hairpin_rss_init(hp); 937 if (err) 938 goto rss_init_err; 939 } 940 941 return hp; 942 943 rss_init_err: 944 mlx5e_hairpin_destroy_transport(hp); 945 create_transport_err: 946 mlx5_core_hairpin_destroy(hp->pair); 947 create_pair_err: 948 kfree(hp); 949 return ERR_PTR(err); 950 } 951 952 static void mlx5e_hairpin_destroy(struct mlx5e_hairpin *hp) 953 { 954 if (hp->num_channels > 1) 955 mlx5e_hairpin_rss_cleanup(hp); 956 mlx5e_hairpin_destroy_transport(hp); 957 mlx5_core_hairpin_destroy(hp->pair); 958 kvfree(hp); 959 } 960 961 static inline u32 hash_hairpin_info(u16 peer_vhca_id, u8 prio) 962 { 963 return (peer_vhca_id << 16 | prio); 964 } 965 966 static struct mlx5e_hairpin_entry *mlx5e_hairpin_get(struct mlx5e_priv *priv, 967 u16 peer_vhca_id, u8 prio) 968 { 969 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 970 struct mlx5e_hairpin_entry *hpe; 971 u32 hash_key = hash_hairpin_info(peer_vhca_id, prio); 972 973 hash_for_each_possible(tc->hairpin_tbl, hpe, 974 hairpin_hlist, hash_key) { 975 if (hpe->peer_vhca_id == peer_vhca_id && hpe->prio == prio) { 976 refcount_inc(&hpe->refcnt); 977 return hpe; 978 } 979 } 980 981 return NULL; 982 } 983 984 static void mlx5e_hairpin_put(struct mlx5e_priv *priv, 985 struct mlx5e_hairpin_entry *hpe) 986 { 987 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 988 /* no more hairpin flows for us, release the hairpin pair */ 989 if (!refcount_dec_and_mutex_lock(&hpe->refcnt, &tc->hairpin_tbl_lock)) 990 return; 991 hash_del(&hpe->hairpin_hlist); 992 mutex_unlock(&tc->hairpin_tbl_lock); 993 994 if (!IS_ERR_OR_NULL(hpe->hp)) { 995 netdev_dbg(priv->netdev, "del hairpin: peer %s\n", 996 dev_name(hpe->hp->pair->peer_mdev->device)); 997 998 mlx5e_hairpin_destroy(hpe->hp); 999 } 1000 1001 WARN_ON(!list_empty(&hpe->flows)); 1002 kfree(hpe); 1003 } 1004 1005 #define UNKNOWN_MATCH_PRIO 8 1006 1007 static int mlx5e_hairpin_get_prio(struct mlx5e_priv *priv, 1008 struct mlx5_flow_spec *spec, u8 *match_prio, 1009 struct netlink_ext_ack *extack) 1010 { 1011 void *headers_c, *headers_v; 1012 u8 prio_val, prio_mask = 0; 1013 bool vlan_present; 1014 1015 #ifdef CONFIG_MLX5_CORE_EN_DCB 1016 if (priv->dcbx_dp.trust_state != MLX5_QPTS_TRUST_PCP) { 1017 NL_SET_ERR_MSG_MOD(extack, 1018 "only PCP trust state supported for hairpin"); 1019 return -EOPNOTSUPP; 1020 } 1021 #endif 1022 headers_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, outer_headers); 1023 headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, outer_headers); 1024 1025 vlan_present = MLX5_GET(fte_match_set_lyr_2_4, headers_v, cvlan_tag); 1026 if (vlan_present) { 1027 prio_mask = MLX5_GET(fte_match_set_lyr_2_4, headers_c, first_prio); 1028 prio_val = MLX5_GET(fte_match_set_lyr_2_4, headers_v, first_prio); 1029 } 1030 1031 if (!vlan_present || !prio_mask) { 1032 prio_val = UNKNOWN_MATCH_PRIO; 1033 } else if (prio_mask != 0x7) { 1034 NL_SET_ERR_MSG_MOD(extack, 1035 "masked priority match not supported for hairpin"); 1036 return -EOPNOTSUPP; 1037 } 1038 1039 *match_prio = prio_val; 1040 return 0; 1041 } 1042 1043 static int debugfs_hairpin_num_active_get(void *data, u64 *val) 1044 { 1045 struct mlx5e_tc_table *tc = data; 1046 struct mlx5e_hairpin_entry *hpe; 1047 u32 cnt = 0; 1048 u32 bkt; 1049 1050 mutex_lock(&tc->hairpin_tbl_lock); 1051 hash_for_each(tc->hairpin_tbl, bkt, hpe, hairpin_hlist) 1052 cnt++; 1053 mutex_unlock(&tc->hairpin_tbl_lock); 1054 1055 *val = cnt; 1056 1057 return 0; 1058 } 1059 DEFINE_DEBUGFS_ATTRIBUTE(fops_hairpin_num_active, 1060 debugfs_hairpin_num_active_get, NULL, "%llu\n"); 1061 1062 static int debugfs_hairpin_table_dump_show(struct seq_file *file, void *priv) 1063 1064 { 1065 struct mlx5e_tc_table *tc = file->private; 1066 struct mlx5e_hairpin_entry *hpe; 1067 u32 bkt; 1068 1069 mutex_lock(&tc->hairpin_tbl_lock); 1070 hash_for_each(tc->hairpin_tbl, bkt, hpe, hairpin_hlist) 1071 seq_printf(file, 1072 "Hairpin peer_vhca_id %u prio %u refcnt %u num_channels %u num_packets %lu\n", 1073 hpe->peer_vhca_id, hpe->prio, 1074 refcount_read(&hpe->refcnt), hpe->hp->num_channels, 1075 BIT(hpe->hp->log_num_packets)); 1076 mutex_unlock(&tc->hairpin_tbl_lock); 1077 1078 return 0; 1079 } 1080 DEFINE_SHOW_ATTRIBUTE(debugfs_hairpin_table_dump); 1081 1082 static void mlx5e_tc_debugfs_init(struct mlx5e_tc_table *tc, 1083 struct dentry *dfs_root) 1084 { 1085 if (IS_ERR_OR_NULL(dfs_root)) 1086 return; 1087 1088 tc->dfs_root = debugfs_create_dir("tc", dfs_root); 1089 1090 debugfs_create_file("hairpin_num_active", 0444, tc->dfs_root, tc, 1091 &fops_hairpin_num_active); 1092 debugfs_create_file("hairpin_table_dump", 0444, tc->dfs_root, tc, 1093 &debugfs_hairpin_table_dump_fops); 1094 } 1095 1096 static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv, 1097 struct mlx5e_tc_flow *flow, 1098 struct mlx5e_tc_flow_parse_attr *parse_attr, 1099 struct netlink_ext_ack *extack) 1100 { 1101 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 1102 struct devlink *devlink = priv_to_devlink(priv->mdev); 1103 int peer_ifindex = parse_attr->mirred_ifindex[0]; 1104 union devlink_param_value val = {}; 1105 struct mlx5_hairpin_params params; 1106 struct mlx5_core_dev *peer_mdev; 1107 struct mlx5e_hairpin_entry *hpe; 1108 struct mlx5e_hairpin *hp; 1109 u8 match_prio; 1110 u16 peer_id; 1111 int err; 1112 1113 peer_mdev = mlx5e_hairpin_get_mdev(dev_net(priv->netdev), peer_ifindex); 1114 if (IS_ERR(peer_mdev)) { 1115 NL_SET_ERR_MSG_MOD(extack, "invalid ifindex of mirred device"); 1116 return PTR_ERR(peer_mdev); 1117 } 1118 1119 if (!MLX5_CAP_GEN(priv->mdev, hairpin) || !MLX5_CAP_GEN(peer_mdev, hairpin)) { 1120 NL_SET_ERR_MSG_MOD(extack, "hairpin is not supported"); 1121 return -EOPNOTSUPP; 1122 } 1123 1124 peer_id = MLX5_CAP_GEN(peer_mdev, vhca_id); 1125 err = mlx5e_hairpin_get_prio(priv, &parse_attr->spec, &match_prio, 1126 extack); 1127 if (err) 1128 return err; 1129 1130 mutex_lock(&tc->hairpin_tbl_lock); 1131 hpe = mlx5e_hairpin_get(priv, peer_id, match_prio); 1132 if (hpe) { 1133 mutex_unlock(&tc->hairpin_tbl_lock); 1134 wait_for_completion(&hpe->res_ready); 1135 1136 if (IS_ERR(hpe->hp)) { 1137 err = -EREMOTEIO; 1138 goto out_err; 1139 } 1140 goto attach_flow; 1141 } 1142 1143 hpe = kzalloc_obj(*hpe); 1144 if (!hpe) { 1145 mutex_unlock(&tc->hairpin_tbl_lock); 1146 return -ENOMEM; 1147 } 1148 1149 spin_lock_init(&hpe->flows_lock); 1150 INIT_LIST_HEAD(&hpe->flows); 1151 INIT_LIST_HEAD(&hpe->dead_peer_wait_list); 1152 hpe->peer_vhca_id = peer_id; 1153 hpe->prio = match_prio; 1154 refcount_set(&hpe->refcnt, 1); 1155 init_completion(&hpe->res_ready); 1156 1157 hash_add(tc->hairpin_tbl, &hpe->hairpin_hlist, 1158 hash_hairpin_info(peer_id, match_prio)); 1159 mutex_unlock(&tc->hairpin_tbl_lock); 1160 1161 err = devl_param_driverinit_value_get( 1162 devlink, MLX5_DEVLINK_PARAM_ID_HAIRPIN_QUEUE_SIZE, &val); 1163 if (err) { 1164 err = -ENOMEM; 1165 goto out_err; 1166 } 1167 1168 params.log_num_packets = ilog2(val.vu32); 1169 params.log_data_size = 1170 clamp_t(u32, 1171 params.log_num_packets + 1172 MLX5_MPWRQ_MIN_LOG_STRIDE_SZ(priv->mdev), 1173 MLX5_CAP_GEN(priv->mdev, log_min_hairpin_wq_data_sz), 1174 MLX5_CAP_GEN(priv->mdev, log_max_hairpin_wq_data_sz)); 1175 1176 params.q_counter = priv->q_counter[0]; 1177 err = devl_param_driverinit_value_get( 1178 devlink, MLX5_DEVLINK_PARAM_ID_HAIRPIN_NUM_QUEUES, &val); 1179 if (err) { 1180 err = -ENOMEM; 1181 goto out_err; 1182 } 1183 1184 params.num_channels = val.vu32; 1185 1186 hp = mlx5e_hairpin_create(priv, ¶ms, peer_ifindex); 1187 hpe->hp = hp; 1188 complete_all(&hpe->res_ready); 1189 if (IS_ERR(hp)) { 1190 err = PTR_ERR(hp); 1191 goto out_err; 1192 } 1193 1194 netdev_dbg(priv->netdev, "add hairpin: tirn %x rqn %x peer %s sqn %x prio %d (log) data %d packets %d\n", 1195 mlx5e_tir_get_tirn(&hp->direct_tir), hp->pair->rqn[0], 1196 dev_name(hp->pair->peer_mdev->device), 1197 hp->pair->sqn[0], match_prio, params.log_data_size, params.log_num_packets); 1198 1199 attach_flow: 1200 if (hpe->hp->num_channels > 1) { 1201 flow_flag_set(flow, HAIRPIN_RSS); 1202 flow->attr->nic_attr->hairpin_ft = 1203 mlx5_get_ttc_flow_table(hpe->hp->ttc); 1204 } else { 1205 flow->attr->nic_attr->hairpin_tirn = mlx5e_tir_get_tirn(&hpe->hp->direct_tir); 1206 } 1207 1208 flow->hpe = hpe; 1209 spin_lock(&hpe->flows_lock); 1210 list_add(&flow->hairpin, &hpe->flows); 1211 spin_unlock(&hpe->flows_lock); 1212 1213 return 0; 1214 1215 out_err: 1216 mlx5e_hairpin_put(priv, hpe); 1217 return err; 1218 } 1219 1220 static void mlx5e_hairpin_flow_del(struct mlx5e_priv *priv, 1221 struct mlx5e_tc_flow *flow) 1222 { 1223 /* flow wasn't fully initialized */ 1224 if (!flow->hpe) 1225 return; 1226 1227 spin_lock(&flow->hpe->flows_lock); 1228 list_del(&flow->hairpin); 1229 spin_unlock(&flow->hpe->flows_lock); 1230 1231 mlx5e_hairpin_put(priv, flow->hpe); 1232 flow->hpe = NULL; 1233 } 1234 1235 struct mlx5_flow_handle * 1236 mlx5e_add_offloaded_nic_rule(struct mlx5e_priv *priv, 1237 struct mlx5_flow_spec *spec, 1238 struct mlx5_flow_attr *attr) 1239 { 1240 struct mlx5_flow_context *flow_context = &spec->flow_context; 1241 struct mlx5e_vlan_table *vlan = mlx5e_fs_get_vlan(priv->fs); 1242 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 1243 struct mlx5_nic_flow_attr *nic_attr = attr->nic_attr; 1244 struct mlx5_flow_destination dest[2] = {}; 1245 struct mlx5_fs_chains *nic_chains; 1246 struct mlx5_flow_act flow_act = { 1247 .action = attr->action, 1248 .flags = FLOW_ACT_NO_APPEND, 1249 }; 1250 struct mlx5_flow_handle *rule; 1251 struct mlx5_flow_table *ft; 1252 int dest_ix = 0; 1253 1254 nic_chains = mlx5e_nic_chains(tc); 1255 flow_context->flags |= FLOW_CONTEXT_HAS_TAG; 1256 flow_context->flow_tag = nic_attr->flow_tag; 1257 1258 if (attr->dest_ft) { 1259 dest[dest_ix].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 1260 dest[dest_ix].ft = attr->dest_ft; 1261 dest_ix++; 1262 } else if (nic_attr->hairpin_ft) { 1263 dest[dest_ix].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 1264 dest[dest_ix].ft = nic_attr->hairpin_ft; 1265 dest_ix++; 1266 } else if (nic_attr->hairpin_tirn) { 1267 dest[dest_ix].type = MLX5_FLOW_DESTINATION_TYPE_TIR; 1268 dest[dest_ix].tir_num = nic_attr->hairpin_tirn; 1269 dest_ix++; 1270 } else if (attr->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { 1271 dest[dest_ix].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 1272 if (attr->dest_chain) { 1273 dest[dest_ix].ft = mlx5_chains_get_table(nic_chains, 1274 attr->dest_chain, 1, 1275 MLX5E_TC_FT_LEVEL); 1276 if (IS_ERR(dest[dest_ix].ft)) 1277 return ERR_CAST(dest[dest_ix].ft); 1278 } else { 1279 dest[dest_ix].ft = mlx5e_vlan_get_flowtable(vlan); 1280 } 1281 dest_ix++; 1282 } 1283 1284 if (dest[0].type == MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE && 1285 MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ignore_flow_level)) 1286 flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL; 1287 1288 if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) { 1289 dest[dest_ix].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER; 1290 dest[dest_ix].counter = attr->counter; 1291 dest_ix++; 1292 } 1293 1294 if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) 1295 flow_act.modify_hdr = attr->modify_hdr; 1296 1297 mutex_lock(&tc->t_lock); 1298 if (IS_ERR_OR_NULL(tc->t)) { 1299 /* Create the root table here if doesn't exist yet */ 1300 tc->t = 1301 mlx5_chains_get_table(nic_chains, 0, 1, MLX5E_TC_FT_LEVEL); 1302 1303 if (IS_ERR(tc->t)) { 1304 mutex_unlock(&tc->t_lock); 1305 netdev_err(priv->netdev, 1306 "Failed to create tc offload table\n"); 1307 rule = ERR_CAST(tc->t); 1308 goto err_ft_get; 1309 } 1310 } 1311 mutex_unlock(&tc->t_lock); 1312 1313 if (attr->chain || attr->prio) 1314 ft = mlx5_chains_get_table(nic_chains, 1315 attr->chain, attr->prio, 1316 MLX5E_TC_FT_LEVEL); 1317 else 1318 ft = attr->ft; 1319 1320 if (IS_ERR(ft)) { 1321 rule = ERR_CAST(ft); 1322 goto err_ft_get; 1323 } 1324 1325 if (attr->outer_match_level != MLX5_MATCH_NONE) 1326 spec->match_criteria_enable |= MLX5_MATCH_OUTER_HEADERS; 1327 1328 rule = mlx5_add_flow_rules(ft, spec, 1329 &flow_act, dest, dest_ix); 1330 if (IS_ERR(rule)) 1331 goto err_rule; 1332 1333 return rule; 1334 1335 err_rule: 1336 if (attr->chain || attr->prio) 1337 mlx5_chains_put_table(nic_chains, 1338 attr->chain, attr->prio, 1339 MLX5E_TC_FT_LEVEL); 1340 err_ft_get: 1341 if (attr->dest_chain) 1342 mlx5_chains_put_table(nic_chains, 1343 attr->dest_chain, 1, 1344 MLX5E_TC_FT_LEVEL); 1345 1346 return ERR_CAST(rule); 1347 } 1348 1349 static int 1350 alloc_flow_attr_counter(struct mlx5_core_dev *counter_dev, 1351 struct mlx5_flow_attr *attr) 1352 1353 { 1354 struct mlx5_fc *counter; 1355 1356 counter = mlx5_fc_create(counter_dev, true); 1357 if (IS_ERR(counter)) 1358 return PTR_ERR(counter); 1359 1360 attr->counter = counter; 1361 return 0; 1362 } 1363 1364 static int 1365 mlx5e_tc_add_nic_flow(struct mlx5e_priv *priv, 1366 struct mlx5e_tc_flow *flow, 1367 struct netlink_ext_ack *extack) 1368 { 1369 struct mlx5e_tc_flow_parse_attr *parse_attr; 1370 struct mlx5_flow_attr *attr = flow->attr; 1371 struct mlx5_core_dev *dev = priv->mdev; 1372 int err; 1373 1374 parse_attr = attr->parse_attr; 1375 1376 if (flow_flag_test(flow, HAIRPIN)) { 1377 err = mlx5e_hairpin_flow_add(priv, flow, parse_attr, extack); 1378 if (err) 1379 return err; 1380 } 1381 1382 if (attr->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) { 1383 err = alloc_flow_attr_counter(dev, attr); 1384 if (err) 1385 return err; 1386 } 1387 1388 if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) { 1389 err = mlx5e_tc_attach_mod_hdr(priv, flow, attr); 1390 if (err) 1391 return err; 1392 } 1393 1394 flow->rule[0] = mlx5e_add_offloaded_nic_rule(priv, &parse_attr->spec, attr); 1395 return PTR_ERR_OR_ZERO(flow->rule[0]); 1396 } 1397 1398 void mlx5e_del_offloaded_nic_rule(struct mlx5e_priv *priv, 1399 struct mlx5_flow_handle *rule, 1400 struct mlx5_flow_attr *attr) 1401 { 1402 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 1403 struct mlx5_fs_chains *nic_chains; 1404 1405 nic_chains = mlx5e_nic_chains(tc); 1406 mlx5_del_flow_rules(rule); 1407 1408 if (attr->chain || attr->prio) 1409 mlx5_chains_put_table(nic_chains, attr->chain, attr->prio, 1410 MLX5E_TC_FT_LEVEL); 1411 1412 if (attr->dest_chain) 1413 mlx5_chains_put_table(nic_chains, attr->dest_chain, 1, 1414 MLX5E_TC_FT_LEVEL); 1415 } 1416 1417 static void mlx5e_tc_free_parse_attr(struct mlx5_flow_attr *attr) 1418 { 1419 if (!attr->parse_attr) 1420 return; 1421 1422 mlx5e_mod_hdr_dealloc(&attr->parse_attr->mod_hdr_acts); 1423 kvfree(attr->parse_attr); 1424 attr->parse_attr = NULL; 1425 } 1426 1427 static void mlx5e_tc_del_nic_flow(struct mlx5e_priv *priv, 1428 struct mlx5e_tc_flow *flow) 1429 { 1430 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 1431 struct mlx5_flow_attr *attr = flow->attr; 1432 1433 flow_flag_clear(flow, OFFLOADED); 1434 1435 if (!IS_ERR_OR_NULL(flow->rule[0])) 1436 mlx5e_del_offloaded_nic_rule(priv, flow->rule[0], attr); 1437 1438 /* Remove root table if no rules are left to avoid 1439 * extra steering hops. 1440 */ 1441 mutex_lock(&tc->t_lock); 1442 if (!mlx5e_tc_num_filters(priv, MLX5_TC_FLAG(NIC_OFFLOAD)) && 1443 !IS_ERR_OR_NULL(tc->t)) { 1444 mlx5_chains_put_table(mlx5e_nic_chains(tc), 0, 1, MLX5E_TC_FT_LEVEL); 1445 tc->t = NULL; 1446 } 1447 mutex_unlock(&tc->t_lock); 1448 1449 if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) 1450 mlx5e_tc_detach_mod_hdr(priv, flow, attr); 1451 1452 if (attr->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) 1453 mlx5_fc_destroy(priv->mdev, attr->counter); 1454 1455 if (flow_flag_test(flow, HAIRPIN)) 1456 mlx5e_hairpin_flow_del(priv, flow); 1457 1458 free_flow_post_acts(flow); 1459 mlx5_tc_ct_delete_flow(get_ct_priv(flow->priv), attr); 1460 1461 mlx5e_tc_free_parse_attr(attr); 1462 kfree(flow->attr); 1463 } 1464 1465 struct mlx5_flow_handle * 1466 mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw, 1467 struct mlx5e_tc_flow *flow, 1468 struct mlx5_flow_spec *spec, 1469 struct mlx5_flow_attr *attr) 1470 { 1471 struct mlx5_flow_handle *rule; 1472 1473 if (attr->flags & MLX5_ATTR_FLAG_SLOW_PATH) 1474 return mlx5_eswitch_add_offloaded_rule(esw, spec, attr); 1475 1476 rule = mlx5e_tc_rule_offload(flow->priv, spec, attr); 1477 1478 if (IS_ERR(rule)) 1479 return rule; 1480 1481 if (attr->esw_attr->split_count) { 1482 flow->rule[1] = mlx5_eswitch_add_fwd_rule(esw, spec, attr); 1483 if (IS_ERR(flow->rule[1])) 1484 goto err_rule1; 1485 } 1486 1487 return rule; 1488 1489 err_rule1: 1490 mlx5e_tc_rule_unoffload(flow->priv, rule, attr); 1491 return flow->rule[1]; 1492 } 1493 1494 void mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw, 1495 struct mlx5e_tc_flow *flow, 1496 struct mlx5_flow_attr *attr) 1497 { 1498 flow_flag_clear(flow, OFFLOADED); 1499 1500 if (attr->flags & MLX5_ATTR_FLAG_SLOW_PATH) 1501 return mlx5_eswitch_del_offloaded_rule(esw, flow->rule[0], attr); 1502 1503 if (attr->esw_attr->split_count) 1504 mlx5_eswitch_del_fwd_rule(esw, flow->rule[1], attr); 1505 1506 mlx5e_tc_rule_unoffload(flow->priv, flow->rule[0], attr); 1507 } 1508 1509 struct mlx5_flow_handle * 1510 mlx5e_tc_offload_to_slow_path(struct mlx5_eswitch *esw, 1511 struct mlx5e_tc_flow *flow, 1512 struct mlx5_flow_spec *spec) 1513 { 1514 struct mlx5e_tc_mod_hdr_acts mod_acts = {}; 1515 struct mlx5e_mod_hdr_handle *mh = NULL; 1516 struct mlx5_flow_attr *slow_attr; 1517 struct mlx5_flow_handle *rule; 1518 bool fwd_and_modify_cap; 1519 u32 chain_mapping = 0; 1520 int err; 1521 1522 slow_attr = mlx5_alloc_flow_attr(MLX5_FLOW_NAMESPACE_FDB); 1523 if (!slow_attr) 1524 return ERR_PTR(-ENOMEM); 1525 1526 memcpy(slow_attr, flow->attr, ESW_FLOW_ATTR_SZ); 1527 slow_attr->action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 1528 slow_attr->esw_attr->split_count = 0; 1529 slow_attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH; 1530 1531 fwd_and_modify_cap = MLX5_CAP_ESW_FLOWTABLE((esw)->dev, fdb_modify_header_fwd_to_table); 1532 if (!fwd_and_modify_cap) 1533 goto skip_restore; 1534 1535 err = mlx5_chains_get_chain_mapping(esw_chains(esw), flow->attr->chain, &chain_mapping); 1536 if (err) 1537 goto err_get_chain; 1538 1539 err = mlx5e_tc_match_to_reg_set(esw->dev, &mod_acts, MLX5_FLOW_NAMESPACE_FDB, 1540 MAPPED_OBJ_TO_REG, chain_mapping); 1541 if (err) 1542 goto err_reg_set; 1543 1544 mh = mlx5e_mod_hdr_attach(esw->dev, get_mod_hdr_table(flow->priv, flow), 1545 MLX5_FLOW_NAMESPACE_FDB, &mod_acts); 1546 if (IS_ERR(mh)) { 1547 err = PTR_ERR(mh); 1548 goto err_attach; 1549 } 1550 1551 slow_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; 1552 slow_attr->modify_hdr = mlx5e_mod_hdr_get(mh); 1553 1554 skip_restore: 1555 rule = mlx5e_tc_offload_fdb_rules(esw, flow, spec, slow_attr); 1556 if (IS_ERR(rule)) { 1557 err = PTR_ERR(rule); 1558 goto err_offload; 1559 } 1560 1561 flow->attr->slow_mh = mh; 1562 flow->chain_mapping = chain_mapping; 1563 flow_flag_set(flow, SLOW); 1564 1565 mlx5e_mod_hdr_dealloc(&mod_acts); 1566 kfree(slow_attr); 1567 1568 return rule; 1569 1570 err_offload: 1571 if (fwd_and_modify_cap) 1572 mlx5e_mod_hdr_detach(esw->dev, get_mod_hdr_table(flow->priv, flow), mh); 1573 err_attach: 1574 err_reg_set: 1575 if (fwd_and_modify_cap) 1576 mlx5_chains_put_chain_mapping(esw_chains(esw), chain_mapping); 1577 err_get_chain: 1578 mlx5e_mod_hdr_dealloc(&mod_acts); 1579 kfree(slow_attr); 1580 return ERR_PTR(err); 1581 } 1582 1583 void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw, 1584 struct mlx5e_tc_flow *flow) 1585 { 1586 struct mlx5e_mod_hdr_handle *slow_mh = flow->attr->slow_mh; 1587 struct mlx5_flow_attr *slow_attr; 1588 1589 slow_attr = mlx5_alloc_flow_attr(MLX5_FLOW_NAMESPACE_FDB); 1590 if (!slow_attr) { 1591 mlx5_core_warn(flow->priv->mdev, "Unable to alloc attr to unoffload slow path rule\n"); 1592 return; 1593 } 1594 1595 memcpy(slow_attr, flow->attr, ESW_FLOW_ATTR_SZ); 1596 slow_attr->action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 1597 slow_attr->esw_attr->split_count = 0; 1598 slow_attr->flags |= MLX5_ATTR_FLAG_SLOW_PATH; 1599 if (slow_mh) { 1600 slow_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; 1601 slow_attr->modify_hdr = mlx5e_mod_hdr_get(slow_mh); 1602 } 1603 mlx5e_tc_unoffload_fdb_rules(esw, flow, slow_attr); 1604 if (slow_mh) { 1605 mlx5e_mod_hdr_detach(esw->dev, get_mod_hdr_table(flow->priv, flow), slow_mh); 1606 mlx5_chains_put_chain_mapping(esw_chains(esw), flow->chain_mapping); 1607 flow->chain_mapping = 0; 1608 flow->attr->slow_mh = NULL; 1609 } 1610 flow_flag_clear(flow, SLOW); 1611 kfree(slow_attr); 1612 } 1613 1614 /* Caller must obtain uplink_priv->unready_flows_lock mutex before calling this 1615 * function. 1616 */ 1617 static void unready_flow_add(struct mlx5e_tc_flow *flow, 1618 struct list_head *unready_flows) 1619 { 1620 flow_flag_set(flow, NOT_READY); 1621 list_add_tail(&flow->unready, unready_flows); 1622 } 1623 1624 /* Caller must obtain uplink_priv->unready_flows_lock mutex before calling this 1625 * function. 1626 */ 1627 static void unready_flow_del(struct mlx5e_tc_flow *flow) 1628 { 1629 list_del(&flow->unready); 1630 flow_flag_clear(flow, NOT_READY); 1631 } 1632 1633 static void add_unready_flow(struct mlx5e_tc_flow *flow) 1634 { 1635 struct mlx5_rep_uplink_priv *uplink_priv; 1636 struct mlx5e_rep_priv *rpriv; 1637 struct mlx5_eswitch *esw; 1638 1639 esw = flow->priv->mdev->priv.eswitch; 1640 rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); 1641 uplink_priv = &rpriv->uplink_priv; 1642 1643 mutex_lock(&uplink_priv->unready_flows_lock); 1644 unready_flow_add(flow, &uplink_priv->unready_flows); 1645 mutex_unlock(&uplink_priv->unready_flows_lock); 1646 } 1647 1648 static void remove_unready_flow(struct mlx5e_tc_flow *flow) 1649 { 1650 struct mlx5_rep_uplink_priv *uplink_priv; 1651 struct mlx5e_rep_priv *rpriv; 1652 struct mlx5_eswitch *esw; 1653 1654 esw = flow->priv->mdev->priv.eswitch; 1655 rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); 1656 uplink_priv = &rpriv->uplink_priv; 1657 1658 mutex_lock(&uplink_priv->unready_flows_lock); 1659 if (flow_flag_test(flow, NOT_READY)) 1660 unready_flow_del(flow); 1661 mutex_unlock(&uplink_priv->unready_flows_lock); 1662 } 1663 1664 bool mlx5e_tc_is_vf_tunnel(struct net_device *out_dev, struct net_device *route_dev) 1665 { 1666 struct mlx5_core_dev *out_mdev, *route_mdev; 1667 struct mlx5e_priv *out_priv, *route_priv; 1668 1669 out_priv = netdev_priv(out_dev); 1670 out_mdev = out_priv->mdev; 1671 route_priv = netdev_priv(route_dev); 1672 route_mdev = route_priv->mdev; 1673 1674 if (out_mdev->coredev_type != MLX5_COREDEV_PF) 1675 return false; 1676 1677 if (route_mdev->coredev_type != MLX5_COREDEV_VF && 1678 route_mdev->coredev_type != MLX5_COREDEV_SF) 1679 return false; 1680 1681 return mlx5e_same_hw_devs(out_priv, route_priv); 1682 } 1683 1684 int mlx5e_tc_query_route_vport(struct net_device *out_dev, struct net_device *route_dev, u16 *vport) 1685 { 1686 struct mlx5e_priv *out_priv, *route_priv; 1687 struct mlx5_core_dev *route_mdev; 1688 struct mlx5_devcom_comp_dev *pos; 1689 struct mlx5_eswitch *esw; 1690 u16 vhca_id; 1691 int err; 1692 1693 out_priv = netdev_priv(out_dev); 1694 esw = out_priv->mdev->priv.eswitch; 1695 route_priv = netdev_priv(route_dev); 1696 route_mdev = route_priv->mdev; 1697 1698 vhca_id = MLX5_CAP_GEN(route_mdev, vhca_id); 1699 err = mlx5_eswitch_vhca_id_to_vport(esw, vhca_id, vport); 1700 if (!err) 1701 return err; 1702 1703 if (!mlx5_lag_is_active(out_priv->mdev)) 1704 return err; 1705 1706 rcu_read_lock(); 1707 err = -ENODEV; 1708 mlx5_devcom_for_each_peer_entry_rcu(esw->devcom, esw, pos) { 1709 err = mlx5_eswitch_vhca_id_to_vport(esw, vhca_id, vport); 1710 if (!err) 1711 break; 1712 } 1713 rcu_read_unlock(); 1714 1715 return err; 1716 } 1717 1718 static int 1719 verify_attr_actions(u32 actions, struct netlink_ext_ack *extack) 1720 { 1721 if (!(actions & 1722 (MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_DROP))) { 1723 NL_SET_ERR_MSG_MOD(extack, "Rule must have at least one forward/drop action"); 1724 return -EOPNOTSUPP; 1725 } 1726 1727 if (!(~actions & 1728 (MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_DROP))) { 1729 NL_SET_ERR_MSG_MOD(extack, "Rule cannot support forward+drop action"); 1730 return -EOPNOTSUPP; 1731 } 1732 1733 if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR && 1734 actions & MLX5_FLOW_CONTEXT_ACTION_DROP) { 1735 NL_SET_ERR_MSG_MOD(extack, "Drop with modify header action is not supported"); 1736 return -EOPNOTSUPP; 1737 } 1738 1739 return 0; 1740 } 1741 1742 static bool 1743 has_encap_dests(struct mlx5_flow_attr *attr) 1744 { 1745 struct mlx5_esw_flow_attr *esw_attr = attr->esw_attr; 1746 int out_index; 1747 1748 for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) 1749 if (esw_attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP) 1750 return true; 1751 1752 return false; 1753 } 1754 1755 static int 1756 extra_split_attr_dests_needed(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr *attr) 1757 { 1758 bool int_dest = false, ext_dest = false; 1759 struct mlx5_esw_flow_attr *esw_attr; 1760 int i; 1761 1762 if (flow->attr != attr || 1763 !list_is_first(&attr->list, &flow->attrs)) 1764 return 0; 1765 1766 esw_attr = attr->esw_attr; 1767 if (!esw_attr->split_count || 1768 esw_attr->split_count == esw_attr->out_count - 1) 1769 return 0; 1770 1771 if (esw_attr->dest_int_port && 1772 (esw_attr->dests[esw_attr->split_count].flags & 1773 MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE)) 1774 return esw_attr->split_count + 1; 1775 1776 for (i = esw_attr->split_count; i < esw_attr->out_count; i++) { 1777 /* external dest with encap is considered as internal by firmware */ 1778 if (esw_attr->dests[i].vport == MLX5_VPORT_UPLINK && 1779 !(esw_attr->dests[i].flags & MLX5_ESW_DEST_ENCAP)) 1780 ext_dest = true; 1781 else 1782 int_dest = true; 1783 1784 if (ext_dest && int_dest) 1785 return esw_attr->split_count; 1786 } 1787 1788 return 0; 1789 } 1790 1791 static int 1792 extra_split_attr_dests(struct mlx5e_tc_flow *flow, 1793 struct mlx5_flow_attr *attr, int split_count) 1794 { 1795 struct mlx5e_post_act *post_act = get_post_action(flow->priv); 1796 struct mlx5e_tc_flow_parse_attr *parse_attr, *parse_attr2; 1797 struct mlx5_esw_flow_attr *esw_attr, *esw_attr2; 1798 struct mlx5e_post_act_handle *handle; 1799 struct mlx5_flow_attr *attr2; 1800 int i, j, err; 1801 1802 if (IS_ERR(post_act)) 1803 return PTR_ERR(post_act); 1804 1805 attr2 = mlx5_alloc_flow_attr(mlx5e_get_flow_namespace(flow)); 1806 parse_attr2 = kvzalloc_obj(*parse_attr); 1807 if (!attr2 || !parse_attr2) { 1808 err = -ENOMEM; 1809 goto err_free; 1810 } 1811 attr2->parse_attr = parse_attr2; 1812 1813 handle = mlx5e_tc_post_act_add(post_act, attr2); 1814 if (IS_ERR(handle)) { 1815 err = PTR_ERR(handle); 1816 goto err_free; 1817 } 1818 1819 esw_attr = attr->esw_attr; 1820 esw_attr2 = attr2->esw_attr; 1821 esw_attr2->in_rep = esw_attr->in_rep; 1822 1823 parse_attr = attr->parse_attr; 1824 parse_attr2->filter_dev = parse_attr->filter_dev; 1825 1826 for (i = split_count, j = 0; i < esw_attr->out_count; i++, j++) 1827 esw_attr2->dests[j] = esw_attr->dests[i]; 1828 1829 esw_attr2->out_count = j; 1830 attr2->action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 1831 1832 err = mlx5e_tc_post_act_offload(post_act, handle); 1833 if (err) 1834 goto err_post_act_offload; 1835 1836 err = mlx5e_tc_post_act_set_handle(flow->priv->mdev, handle, 1837 &parse_attr->mod_hdr_acts); 1838 if (err) 1839 goto err_post_act_set_handle; 1840 1841 esw_attr->out_count = split_count; 1842 attr->extra_split_ft = mlx5e_tc_post_act_get_ft(post_act); 1843 flow->extra_split_attr = attr2; 1844 1845 attr2->post_act_handle = handle; 1846 1847 return 0; 1848 1849 err_post_act_set_handle: 1850 mlx5e_tc_post_act_unoffload(post_act, handle); 1851 err_post_act_offload: 1852 mlx5e_tc_post_act_del(post_act, handle); 1853 err_free: 1854 kvfree(parse_attr2); 1855 kfree(attr2); 1856 return err; 1857 } 1858 1859 static int 1860 post_process_attr(struct mlx5e_tc_flow *flow, 1861 struct mlx5_flow_attr *attr, 1862 struct netlink_ext_ack *extack) 1863 { 1864 int extra_split; 1865 bool vf_tun; 1866 int err = 0; 1867 1868 err = verify_attr_actions(attr->action, extack); 1869 if (err) 1870 goto err_out; 1871 1872 if (mlx5e_is_eswitch_flow(flow) && has_encap_dests(attr)) { 1873 err = mlx5e_tc_tun_encap_dests_set(flow->priv, flow, attr, extack, &vf_tun); 1874 if (err) 1875 goto err_out; 1876 } 1877 1878 extra_split = extra_split_attr_dests_needed(flow, attr); 1879 if (extra_split > 0) { 1880 err = extra_split_attr_dests(flow, attr, extra_split); 1881 if (err) 1882 goto err_out; 1883 } 1884 1885 if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) { 1886 err = mlx5e_tc_attach_mod_hdr(flow->priv, flow, attr); 1887 if (err) 1888 goto err_out; 1889 } 1890 1891 if (attr->branch_true && 1892 attr->branch_true->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) { 1893 err = mlx5e_tc_attach_mod_hdr(flow->priv, flow, attr->branch_true); 1894 if (err) 1895 goto err_out; 1896 } 1897 1898 if (attr->branch_false && 1899 attr->branch_false->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) { 1900 err = mlx5e_tc_attach_mod_hdr(flow->priv, flow, attr->branch_false); 1901 if (err) 1902 goto err_out; 1903 } 1904 1905 if (attr->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) { 1906 err = alloc_flow_attr_counter(get_flow_counter_dev(flow), attr); 1907 if (err) 1908 goto err_out; 1909 } 1910 1911 err_out: 1912 return err; 1913 } 1914 1915 static int 1916 mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv, 1917 struct mlx5e_tc_flow *flow, 1918 struct netlink_ext_ack *extack) 1919 { 1920 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 1921 struct mlx5e_tc_flow_parse_attr *parse_attr; 1922 struct mlx5_flow_attr *attr = flow->attr; 1923 struct mlx5_esw_flow_attr *esw_attr; 1924 u32 max_prio, max_chain; 1925 int err = 0; 1926 1927 parse_attr = attr->parse_attr; 1928 esw_attr = attr->esw_attr; 1929 1930 /* We check chain range only for tc flows. 1931 * For ft flows, we checked attr->chain was originally 0 and set it to 1932 * FDB_FT_CHAIN which is outside tc range. 1933 * See mlx5e_rep_setup_ft_cb(). 1934 */ 1935 max_chain = mlx5_chains_get_chain_range(esw_chains(esw)); 1936 if (!mlx5e_is_ft_flow(flow) && attr->chain > max_chain) { 1937 NL_SET_ERR_MSG_MOD(extack, 1938 "Requested chain is out of supported range"); 1939 err = -EOPNOTSUPP; 1940 goto err_out; 1941 } 1942 1943 max_prio = mlx5_chains_get_prio_range(esw_chains(esw)); 1944 if (attr->prio > max_prio) { 1945 NL_SET_ERR_MSG_MOD(extack, 1946 "Requested priority is out of supported range"); 1947 err = -EOPNOTSUPP; 1948 goto err_out; 1949 } 1950 1951 if (flow_flag_test(flow, TUN_RX)) { 1952 err = mlx5e_attach_decap_route(priv, flow); 1953 if (err) 1954 goto err_out; 1955 1956 if (!attr->chain && esw_attr->int_port && 1957 attr->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { 1958 /* If decap route device is internal port, change the 1959 * source vport value in reg_c0 back to uplink just in 1960 * case the rule performs goto chain > 0. If we have a miss 1961 * on chain > 0 we want the metadata regs to hold the 1962 * chain id so SW will resume handling of this packet 1963 * from the proper chain. 1964 */ 1965 u32 metadata = mlx5_eswitch_get_vport_metadata_for_set(esw, 1966 esw_attr->in_rep->vport); 1967 1968 err = mlx5e_tc_match_to_reg_set(priv->mdev, &parse_attr->mod_hdr_acts, 1969 MLX5_FLOW_NAMESPACE_FDB, VPORT_TO_REG, 1970 metadata); 1971 if (err) 1972 goto err_out; 1973 1974 attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; 1975 } 1976 } 1977 1978 if (flow_flag_test(flow, L3_TO_L2_DECAP)) { 1979 err = mlx5e_attach_decap(priv, flow, extack); 1980 if (err) 1981 goto err_out; 1982 } 1983 1984 if (netif_is_ovs_master(parse_attr->filter_dev)) { 1985 struct mlx5e_tc_int_port *int_port; 1986 1987 if (attr->chain) { 1988 NL_SET_ERR_MSG_MOD(extack, 1989 "Internal port rule is only supported on chain 0"); 1990 err = -EOPNOTSUPP; 1991 goto err_out; 1992 } 1993 1994 if (attr->dest_chain) { 1995 NL_SET_ERR_MSG_MOD(extack, 1996 "Internal port rule offload doesn't support goto action"); 1997 err = -EOPNOTSUPP; 1998 goto err_out; 1999 } 2000 2001 int_port = mlx5e_tc_int_port_get(mlx5e_get_int_port_priv(priv), 2002 parse_attr->filter_dev->ifindex, 2003 flow_flag_test(flow, EGRESS) ? 2004 MLX5E_TC_INT_PORT_EGRESS : 2005 MLX5E_TC_INT_PORT_INGRESS); 2006 if (IS_ERR(int_port)) { 2007 err = PTR_ERR(int_port); 2008 goto err_out; 2009 } 2010 2011 esw_attr->int_port = int_port; 2012 } 2013 2014 err = post_process_attr(flow, attr, extack); 2015 if (err) 2016 goto err_out; 2017 2018 err = mlx5e_tc_act_stats_add_flow(get_act_stats_handle(priv), flow); 2019 if (err) 2020 goto err_out; 2021 2022 /* we get here if one of the following takes place: 2023 * (1) there's no error 2024 * (2) there's an encap action and we don't have valid neigh 2025 */ 2026 if (flow_flag_test(flow, SLOW)) 2027 flow->rule[0] = mlx5e_tc_offload_to_slow_path(esw, flow, &parse_attr->spec); 2028 else 2029 flow->rule[0] = mlx5e_tc_offload_fdb_rules(esw, flow, &parse_attr->spec, attr); 2030 2031 if (IS_ERR(flow->rule[0])) { 2032 err = PTR_ERR(flow->rule[0]); 2033 goto err_out; 2034 } 2035 flow_flag_set(flow, OFFLOADED); 2036 2037 return 0; 2038 2039 err_out: 2040 flow_flag_set(flow, FAILED); 2041 return err; 2042 } 2043 2044 static bool mlx5_flow_has_geneve_opt(struct mlx5_flow_spec *spec) 2045 { 2046 void *headers_v = MLX5_ADDR_OF(fte_match_param, 2047 spec->match_value, 2048 misc_parameters_3); 2049 u32 geneve_tlv_opt_0_data = MLX5_GET(fte_match_set_misc3, 2050 headers_v, 2051 geneve_tlv_option_0_data); 2052 2053 return !!geneve_tlv_opt_0_data; 2054 } 2055 2056 static void free_branch_attr(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr *attr) 2057 { 2058 if (!attr) 2059 return; 2060 2061 mlx5_free_flow_attr_actions(flow, attr); 2062 kvfree(attr->parse_attr); 2063 kfree(attr); 2064 } 2065 2066 static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, 2067 struct mlx5e_tc_flow *flow) 2068 { 2069 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 2070 struct mlx5_flow_attr *attr = flow->attr; 2071 2072 mlx5e_put_flow_tunnel_id(flow); 2073 2074 remove_unready_flow(flow); 2075 2076 if (mlx5e_is_offloaded_flow(flow)) { 2077 if (flow_flag_test(flow, SLOW)) 2078 mlx5e_tc_unoffload_from_slow_path(esw, flow); 2079 else 2080 mlx5e_tc_unoffload_fdb_rules(esw, flow, attr); 2081 } 2082 complete_all(&flow->del_hw_done); 2083 2084 if (mlx5_flow_has_geneve_opt(&attr->parse_attr->spec)) 2085 mlx5_geneve_tlv_option_del(priv->mdev->geneve); 2086 2087 if (flow->decap_route) 2088 mlx5e_detach_decap_route(priv, flow); 2089 2090 mlx5_tc_ct_match_del(get_ct_priv(priv), &flow->attr->ct_attr); 2091 2092 if (flow_flag_test(flow, L3_TO_L2_DECAP)) 2093 mlx5e_detach_decap(priv, flow); 2094 2095 mlx5e_tc_act_stats_del_flow(get_act_stats_handle(priv), flow); 2096 2097 free_flow_post_acts(flow); 2098 if (flow->extra_split_attr) { 2099 mlx5_free_flow_attr_actions(flow, flow->extra_split_attr); 2100 kvfree(flow->extra_split_attr->parse_attr); 2101 kfree(flow->extra_split_attr); 2102 } 2103 mlx5_free_flow_attr_actions(flow, attr); 2104 2105 kvfree(attr->esw_attr->rx_tun_attr); 2106 kvfree(attr->parse_attr); 2107 kfree(flow->attr); 2108 } 2109 2110 struct mlx5_fc *mlx5e_tc_get_counter(struct mlx5e_tc_flow *flow) 2111 { 2112 struct mlx5_flow_attr *attr; 2113 2114 attr = list_first_entry(&flow->attrs, struct mlx5_flow_attr, list); 2115 return attr->counter; 2116 } 2117 2118 /* Iterate over tmp_list of flows attached to flow_list head. */ 2119 void mlx5e_put_flow_list(struct mlx5e_priv *priv, struct list_head *flow_list) 2120 { 2121 struct mlx5e_tc_flow *flow, *tmp; 2122 2123 list_for_each_entry_safe(flow, tmp, flow_list, tmp_list) 2124 mlx5e_flow_put(priv, flow); 2125 } 2126 2127 static void mlx5e_tc_del_fdb_peer_flow(struct mlx5e_tc_flow *peer_flow) 2128 { 2129 struct mlx5e_tc_flow *flow = peer_flow->peer_orig; 2130 struct mlx5_eswitch *esw; 2131 2132 esw = flow->priv->mdev->priv.eswitch; 2133 mutex_lock(&esw->offloads.peer_mutex); 2134 list_del(&peer_flow->peer); 2135 mutex_unlock(&esw->offloads.peer_mutex); 2136 2137 list_del(&peer_flow->peer_flows); 2138 if (list_empty(&flow->peer_flows)) 2139 flow_flag_clear(flow, DUP); 2140 2141 if (refcount_dec_and_test(&peer_flow->refcnt)) { 2142 mlx5e_tc_del_fdb_flow(peer_flow->priv, peer_flow); 2143 kfree(peer_flow); 2144 } 2145 } 2146 2147 static void mlx5e_tc_del_fdb_peers_flow(struct mlx5e_tc_flow *flow) 2148 { 2149 struct mlx5e_tc_flow *peer_flow, *tmp; 2150 2151 if (!flow_flag_test(flow, ESWITCH) || !flow_flag_test(flow, DUP)) 2152 return; 2153 2154 list_for_each_entry_safe(peer_flow, tmp, &flow->peer_flows, peer_flows) 2155 mlx5e_tc_del_fdb_peer_flow(peer_flow); 2156 } 2157 2158 static void mlx5e_tc_del_flow(struct mlx5e_priv *priv, 2159 struct mlx5e_tc_flow *flow) 2160 { 2161 if (mlx5e_is_eswitch_flow(flow)) { 2162 struct mlx5_devcom_comp_dev *devcom = flow->priv->mdev->priv.eswitch->devcom; 2163 2164 if (flow_flag_test(flow, PEER) || 2165 !mlx5_devcom_for_each_peer_begin(devcom)) { 2166 mlx5e_tc_del_fdb_flow(priv, flow); 2167 return; 2168 } 2169 2170 mlx5e_tc_del_fdb_peers_flow(flow); 2171 mlx5_devcom_for_each_peer_end(devcom); 2172 mlx5e_tc_del_fdb_flow(priv, flow); 2173 } else { 2174 mlx5e_tc_del_nic_flow(priv, flow); 2175 } 2176 } 2177 2178 static bool flow_requires_tunnel_mapping(u32 chain, struct flow_cls_offload *f) 2179 { 2180 struct flow_rule *rule = flow_cls_offload_flow_rule(f); 2181 struct flow_action *flow_action = &rule->action; 2182 const struct flow_action_entry *act; 2183 int i; 2184 2185 if (chain) 2186 return false; 2187 2188 flow_action_for_each(i, act, flow_action) { 2189 switch (act->id) { 2190 case FLOW_ACTION_GOTO: 2191 return true; 2192 case FLOW_ACTION_SAMPLE: 2193 return true; 2194 default: 2195 continue; 2196 } 2197 } 2198 2199 return false; 2200 } 2201 2202 static int 2203 enc_opts_is_dont_care_or_full_match(struct mlx5e_priv *priv, 2204 struct flow_dissector_key_enc_opts *opts, 2205 struct netlink_ext_ack *extack, 2206 bool *dont_care) 2207 { 2208 struct geneve_opt *opt; 2209 int off = 0; 2210 2211 *dont_care = true; 2212 2213 while (opts->len > off) { 2214 opt = (struct geneve_opt *)&opts->data[off]; 2215 2216 if (!(*dont_care) || opt->opt_class || opt->type || 2217 memchr_inv(opt->opt_data, 0, opt->length * 4)) { 2218 *dont_care = false; 2219 2220 if (opt->opt_class != htons(U16_MAX) || 2221 opt->type != U8_MAX) { 2222 NL_SET_ERR_MSG_MOD(extack, 2223 "Partial match of tunnel options in chain > 0 isn't supported"); 2224 netdev_warn(priv->netdev, 2225 "Partial match of tunnel options in chain > 0 isn't supported"); 2226 return -EOPNOTSUPP; 2227 } 2228 } 2229 2230 off += sizeof(struct geneve_opt) + opt->length * 4; 2231 } 2232 2233 return 0; 2234 } 2235 2236 #define COPY_DISSECTOR(rule, diss_key, dst)\ 2237 ({ \ 2238 struct flow_rule *__rule = (rule);\ 2239 typeof(dst) __dst = dst;\ 2240 \ 2241 memcpy(__dst,\ 2242 skb_flow_dissector_target(__rule->match.dissector,\ 2243 diss_key,\ 2244 __rule->match.key),\ 2245 sizeof(*__dst));\ 2246 }) 2247 2248 static int mlx5e_get_flow_tunnel_id(struct mlx5e_priv *priv, 2249 struct mlx5e_tc_flow *flow, 2250 struct flow_cls_offload *f, 2251 struct net_device *filter_dev) 2252 { 2253 struct flow_rule *rule = flow_cls_offload_flow_rule(f); 2254 struct netlink_ext_ack *extack = f->common.extack; 2255 struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts; 2256 struct flow_match_enc_opts enc_opts_match; 2257 struct tunnel_match_enc_opts tun_enc_opts; 2258 struct mlx5_rep_uplink_priv *uplink_priv; 2259 struct mlx5_flow_attr *attr = flow->attr; 2260 struct mlx5e_rep_priv *uplink_rpriv; 2261 struct tunnel_match_key tunnel_key; 2262 bool enc_opts_is_dont_care = true; 2263 u32 tun_id, enc_opts_id = 0; 2264 struct mlx5_eswitch *esw; 2265 u32 value, mask; 2266 int err; 2267 2268 esw = priv->mdev->priv.eswitch; 2269 uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); 2270 uplink_priv = &uplink_rpriv->uplink_priv; 2271 2272 memset(&tunnel_key, 0, sizeof(tunnel_key)); 2273 COPY_DISSECTOR(rule, FLOW_DISSECTOR_KEY_ENC_CONTROL, 2274 &tunnel_key.enc_control); 2275 if (tunnel_key.enc_control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) 2276 COPY_DISSECTOR(rule, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, 2277 &tunnel_key.enc_ipv4); 2278 else 2279 COPY_DISSECTOR(rule, FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, 2280 &tunnel_key.enc_ipv6); 2281 COPY_DISSECTOR(rule, FLOW_DISSECTOR_KEY_ENC_IP, &tunnel_key.enc_ip); 2282 COPY_DISSECTOR(rule, FLOW_DISSECTOR_KEY_ENC_PORTS, 2283 &tunnel_key.enc_tp); 2284 COPY_DISSECTOR(rule, FLOW_DISSECTOR_KEY_ENC_KEYID, 2285 &tunnel_key.enc_key_id); 2286 tunnel_key.filter_ifindex = filter_dev->ifindex; 2287 2288 err = mapping_add(uplink_priv->tunnel_mapping, &tunnel_key, &tun_id); 2289 if (err) 2290 return err; 2291 2292 flow_rule_match_enc_opts(rule, &enc_opts_match); 2293 err = enc_opts_is_dont_care_or_full_match(priv, 2294 enc_opts_match.mask, 2295 extack, 2296 &enc_opts_is_dont_care); 2297 if (err) 2298 goto err_enc_opts; 2299 2300 if (!enc_opts_is_dont_care) { 2301 memset(&tun_enc_opts, 0, sizeof(tun_enc_opts)); 2302 memcpy(&tun_enc_opts.key, enc_opts_match.key, 2303 sizeof(*enc_opts_match.key)); 2304 memcpy(&tun_enc_opts.mask, enc_opts_match.mask, 2305 sizeof(*enc_opts_match.mask)); 2306 2307 err = mapping_add(uplink_priv->tunnel_enc_opts_mapping, 2308 &tun_enc_opts, &enc_opts_id); 2309 if (err) 2310 goto err_enc_opts; 2311 } 2312 2313 value = tun_id << ENC_OPTS_BITS | enc_opts_id; 2314 mask = enc_opts_id ? TUNNEL_ID_MASK : 2315 (TUNNEL_ID_MASK & ~ENC_OPTS_BITS_MASK); 2316 2317 if (attr->chain) { 2318 mlx5e_tc_match_to_reg_match(&attr->parse_attr->spec, 2319 TUNNEL_TO_REG, value, mask); 2320 } else { 2321 mod_hdr_acts = &attr->parse_attr->mod_hdr_acts; 2322 err = mlx5e_tc_match_to_reg_set(priv->mdev, 2323 mod_hdr_acts, MLX5_FLOW_NAMESPACE_FDB, 2324 TUNNEL_TO_REG, value); 2325 if (err) 2326 goto err_set; 2327 2328 attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; 2329 } 2330 2331 flow->attr->tunnel_id = value; 2332 return 0; 2333 2334 err_set: 2335 if (enc_opts_id) 2336 mapping_remove(uplink_priv->tunnel_enc_opts_mapping, 2337 enc_opts_id); 2338 err_enc_opts: 2339 mapping_remove(uplink_priv->tunnel_mapping, tun_id); 2340 return err; 2341 } 2342 2343 static void mlx5e_put_flow_tunnel_id(struct mlx5e_tc_flow *flow) 2344 { 2345 u32 enc_opts_id = flow->attr->tunnel_id & ENC_OPTS_BITS_MASK; 2346 u32 tun_id = flow->attr->tunnel_id >> ENC_OPTS_BITS; 2347 struct mlx5_rep_uplink_priv *uplink_priv; 2348 struct mlx5e_rep_priv *uplink_rpriv; 2349 struct mlx5_eswitch *esw; 2350 2351 esw = flow->priv->mdev->priv.eswitch; 2352 uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); 2353 uplink_priv = &uplink_rpriv->uplink_priv; 2354 2355 if (tun_id) 2356 mapping_remove(uplink_priv->tunnel_mapping, tun_id); 2357 if (enc_opts_id) 2358 mapping_remove(uplink_priv->tunnel_enc_opts_mapping, 2359 enc_opts_id); 2360 } 2361 2362 void mlx5e_tc_set_ethertype(struct mlx5_core_dev *mdev, 2363 struct flow_match_basic *match, bool outer, 2364 void *headers_c, void *headers_v) 2365 { 2366 bool ip_version_cap; 2367 2368 ip_version_cap = outer ? 2369 MLX5_CAP_FLOWTABLE_NIC_RX(mdev, 2370 ft_field_support.outer_ip_version) : 2371 MLX5_CAP_FLOWTABLE_NIC_RX(mdev, 2372 ft_field_support.inner_ip_version); 2373 2374 if (ip_version_cap && match->mask->n_proto == htons(0xFFFF) && 2375 (match->key->n_proto == htons(ETH_P_IP) || 2376 match->key->n_proto == htons(ETH_P_IPV6))) { 2377 MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, headers_c, ip_version); 2378 MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_version, 2379 match->key->n_proto == htons(ETH_P_IP) ? 4 : 6); 2380 } else { 2381 MLX5_SET(fte_match_set_lyr_2_4, headers_c, ethertype, 2382 ntohs(match->mask->n_proto)); 2383 MLX5_SET(fte_match_set_lyr_2_4, headers_v, ethertype, 2384 ntohs(match->key->n_proto)); 2385 } 2386 } 2387 2388 u8 mlx5e_tc_get_ip_version(struct mlx5_flow_spec *spec, bool outer) 2389 { 2390 void *headers_v; 2391 u16 ethertype; 2392 u8 ip_version; 2393 2394 if (outer) 2395 headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, outer_headers); 2396 else 2397 headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, inner_headers); 2398 2399 ip_version = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_version); 2400 /* Return ip_version converted from ethertype anyway */ 2401 if (!ip_version) { 2402 ethertype = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ethertype); 2403 if (ethertype == ETH_P_IP || ethertype == ETH_P_ARP) 2404 ip_version = 4; 2405 else if (ethertype == ETH_P_IPV6) 2406 ip_version = 6; 2407 } 2408 return ip_version; 2409 } 2410 2411 /* Tunnel device follows RFC 6040, see include/net/inet_ecn.h. 2412 * And changes inner ip_ecn depending on inner and outer ip_ecn as follows: 2413 * +---------+----------------------------------------+ 2414 * |Arriving | Arriving Outer Header | 2415 * | Inner +---------+---------+---------+----------+ 2416 * | Header | Not-ECT | ECT(0) | ECT(1) | CE | 2417 * +---------+---------+---------+---------+----------+ 2418 * | Not-ECT | Not-ECT | Not-ECT | Not-ECT | <drop> | 2419 * | ECT(0) | ECT(0) | ECT(0) | ECT(1) | CE* | 2420 * | ECT(1) | ECT(1) | ECT(1) | ECT(1)* | CE* | 2421 * | CE | CE | CE | CE | CE | 2422 * +---------+---------+---------+---------+----------+ 2423 * 2424 * Tc matches on inner after decapsulation on tunnel device, but hw offload matches 2425 * the inner ip_ecn value before hardware decap action. 2426 * 2427 * Cells marked are changed from original inner packet ip_ecn value during decap, and 2428 * so matching those values on inner ip_ecn before decap will fail. 2429 * 2430 * The following helper allows offload when inner ip_ecn won't be changed by outer ip_ecn, 2431 * except for the outer ip_ecn = CE, where in all cases inner ip_ecn will be changed to CE, 2432 * and such we can drop the inner ip_ecn=CE match. 2433 */ 2434 2435 static int mlx5e_tc_verify_tunnel_ecn(struct mlx5e_priv *priv, 2436 struct flow_cls_offload *f, 2437 bool *match_inner_ecn) 2438 { 2439 u8 outer_ecn_mask = 0, outer_ecn_key = 0, inner_ecn_mask = 0, inner_ecn_key = 0; 2440 struct flow_rule *rule = flow_cls_offload_flow_rule(f); 2441 struct netlink_ext_ack *extack = f->common.extack; 2442 struct flow_match_ip match; 2443 2444 *match_inner_ecn = true; 2445 2446 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IP)) { 2447 flow_rule_match_enc_ip(rule, &match); 2448 outer_ecn_key = match.key->tos & INET_ECN_MASK; 2449 outer_ecn_mask = match.mask->tos & INET_ECN_MASK; 2450 } 2451 2452 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) { 2453 flow_rule_match_ip(rule, &match); 2454 inner_ecn_key = match.key->tos & INET_ECN_MASK; 2455 inner_ecn_mask = match.mask->tos & INET_ECN_MASK; 2456 } 2457 2458 if (outer_ecn_mask != 0 && outer_ecn_mask != INET_ECN_MASK) { 2459 NL_SET_ERR_MSG_MOD(extack, "Partial match on enc_tos ecn bits isn't supported"); 2460 netdev_warn(priv->netdev, "Partial match on enc_tos ecn bits isn't supported"); 2461 return -EOPNOTSUPP; 2462 } 2463 2464 if (!outer_ecn_mask) { 2465 if (!inner_ecn_mask) 2466 return 0; 2467 2468 NL_SET_ERR_MSG_MOD(extack, 2469 "Matching on tos ecn bits without also matching enc_tos ecn bits isn't supported"); 2470 netdev_warn(priv->netdev, 2471 "Matching on tos ecn bits without also matching enc_tos ecn bits isn't supported"); 2472 return -EOPNOTSUPP; 2473 } 2474 2475 if (inner_ecn_mask && inner_ecn_mask != INET_ECN_MASK) { 2476 NL_SET_ERR_MSG_MOD(extack, 2477 "Partial match on tos ecn bits with match on enc_tos ecn bits isn't supported"); 2478 netdev_warn(priv->netdev, 2479 "Partial match on tos ecn bits with match on enc_tos ecn bits isn't supported"); 2480 return -EOPNOTSUPP; 2481 } 2482 2483 if (!inner_ecn_mask) 2484 return 0; 2485 2486 /* Both inner and outer have full mask on ecn */ 2487 2488 if (outer_ecn_key == INET_ECN_ECT_1) { 2489 /* inner ecn might change by DECAP action */ 2490 2491 NL_SET_ERR_MSG_MOD(extack, "Match on enc_tos ecn = ECT(1) isn't supported"); 2492 netdev_warn(priv->netdev, "Match on enc_tos ecn = ECT(1) isn't supported"); 2493 return -EOPNOTSUPP; 2494 } 2495 2496 if (outer_ecn_key != INET_ECN_CE) 2497 return 0; 2498 2499 if (inner_ecn_key != INET_ECN_CE) { 2500 /* Can't happen in software, as packet ecn will be changed to CE after decap */ 2501 NL_SET_ERR_MSG_MOD(extack, 2502 "Match on tos enc_tos ecn = CE while match on tos ecn != CE isn't supported"); 2503 netdev_warn(priv->netdev, 2504 "Match on tos enc_tos ecn = CE while match on tos ecn != CE isn't supported"); 2505 return -EOPNOTSUPP; 2506 } 2507 2508 /* outer ecn = CE, inner ecn = CE, as decap will change inner ecn to CE in anycase, 2509 * drop match on inner ecn 2510 */ 2511 *match_inner_ecn = false; 2512 2513 return 0; 2514 } 2515 2516 static int parse_tunnel_attr(struct mlx5e_priv *priv, 2517 struct mlx5e_tc_flow *flow, 2518 struct mlx5_flow_spec *spec, 2519 struct flow_cls_offload *f, 2520 struct net_device *filter_dev, 2521 u8 *match_level, 2522 bool *match_inner) 2523 { 2524 struct mlx5e_tc_tunnel *tunnel = mlx5e_get_tc_tun(filter_dev); 2525 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 2526 struct netlink_ext_ack *extack = f->common.extack; 2527 bool needs_mapping, sets_mapping; 2528 int err; 2529 2530 if (!mlx5e_is_eswitch_flow(flow)) { 2531 NL_SET_ERR_MSG_MOD(extack, "Match on tunnel is not supported"); 2532 return -EOPNOTSUPP; 2533 } 2534 2535 needs_mapping = !!flow->attr->chain; 2536 sets_mapping = flow_requires_tunnel_mapping(flow->attr->chain, f); 2537 *match_inner = !needs_mapping; 2538 2539 if ((needs_mapping || sets_mapping) && 2540 !mlx5_eswitch_reg_c1_loopback_enabled(esw)) { 2541 NL_SET_ERR_MSG_MOD(extack, 2542 "Chains on tunnel devices isn't supported without register loopback support"); 2543 netdev_warn(priv->netdev, 2544 "Chains on tunnel devices isn't supported without register loopback support"); 2545 return -EOPNOTSUPP; 2546 } 2547 2548 if (!flow->attr->chain) { 2549 err = mlx5e_tc_tun_parse(filter_dev, priv, spec, f, 2550 match_level); 2551 if (err) { 2552 NL_SET_ERR_MSG_MOD(extack, 2553 "Failed to parse tunnel attributes"); 2554 netdev_warn(priv->netdev, 2555 "Failed to parse tunnel attributes"); 2556 return err; 2557 } 2558 2559 /* With mpls over udp we decapsulate using packet reformat 2560 * object 2561 */ 2562 if (!netif_is_bareudp(filter_dev)) 2563 flow->attr->action |= MLX5_FLOW_CONTEXT_ACTION_DECAP; 2564 err = mlx5e_tc_set_attr_rx_tun(flow, spec); 2565 if (err) 2566 return err; 2567 } else if (tunnel) { 2568 struct mlx5_flow_spec *tmp_spec; 2569 2570 tmp_spec = kvzalloc_obj(*tmp_spec); 2571 if (!tmp_spec) { 2572 NL_SET_ERR_MSG_MOD(extack, "Failed to allocate memory for tunnel tmp spec"); 2573 netdev_warn(priv->netdev, "Failed to allocate memory for tunnel tmp spec"); 2574 return -ENOMEM; 2575 } 2576 memcpy(tmp_spec, spec, sizeof(*tmp_spec)); 2577 2578 err = mlx5e_tc_tun_parse(filter_dev, priv, tmp_spec, f, match_level); 2579 if (err) { 2580 NL_SET_ERR_MSG_MOD(extack, "Failed to parse tunnel attributes"); 2581 netdev_warn(priv->netdev, "Failed to parse tunnel attributes"); 2582 } else { 2583 err = mlx5e_tc_set_attr_rx_tun(flow, tmp_spec); 2584 } 2585 if (mlx5_flow_has_geneve_opt(tmp_spec)) 2586 mlx5_geneve_tlv_option_del(priv->mdev->geneve); 2587 kvfree(tmp_spec); 2588 if (err) 2589 return err; 2590 } 2591 2592 if (!needs_mapping && !sets_mapping) 2593 return 0; 2594 2595 return mlx5e_get_flow_tunnel_id(priv, flow, f, filter_dev); 2596 } 2597 2598 static void *get_match_inner_headers_criteria(struct mlx5_flow_spec *spec) 2599 { 2600 return MLX5_ADDR_OF(fte_match_param, spec->match_criteria, 2601 inner_headers); 2602 } 2603 2604 static void *get_match_inner_headers_value(struct mlx5_flow_spec *spec) 2605 { 2606 return MLX5_ADDR_OF(fte_match_param, spec->match_value, 2607 inner_headers); 2608 } 2609 2610 static void *get_match_outer_headers_criteria(struct mlx5_flow_spec *spec) 2611 { 2612 return MLX5_ADDR_OF(fte_match_param, spec->match_criteria, 2613 outer_headers); 2614 } 2615 2616 static void *get_match_outer_headers_value(struct mlx5_flow_spec *spec) 2617 { 2618 return MLX5_ADDR_OF(fte_match_param, spec->match_value, 2619 outer_headers); 2620 } 2621 2622 void *mlx5e_get_match_headers_value(u32 flags, struct mlx5_flow_spec *spec) 2623 { 2624 return (flags & MLX5_FLOW_CONTEXT_ACTION_DECAP) ? 2625 get_match_inner_headers_value(spec) : 2626 get_match_outer_headers_value(spec); 2627 } 2628 2629 void *mlx5e_get_match_headers_criteria(u32 flags, struct mlx5_flow_spec *spec) 2630 { 2631 return (flags & MLX5_FLOW_CONTEXT_ACTION_DECAP) ? 2632 get_match_inner_headers_criteria(spec) : 2633 get_match_outer_headers_criteria(spec); 2634 } 2635 2636 static int mlx5e_flower_parse_meta(struct net_device *filter_dev, 2637 struct flow_cls_offload *f) 2638 { 2639 struct flow_rule *rule = flow_cls_offload_flow_rule(f); 2640 struct netlink_ext_ack *extack = f->common.extack; 2641 struct net_device *ingress_dev; 2642 struct flow_match_meta match; 2643 2644 if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META)) 2645 return 0; 2646 2647 flow_rule_match_meta(rule, &match); 2648 2649 if (match.mask->l2_miss) { 2650 NL_SET_ERR_MSG_MOD(f->common.extack, "Can't match on \"l2_miss\""); 2651 return -EOPNOTSUPP; 2652 } 2653 2654 if (!match.mask->ingress_ifindex) 2655 return 0; 2656 2657 if (match.mask->ingress_ifindex != 0xFFFFFFFF) { 2658 NL_SET_ERR_MSG_MOD(extack, "Unsupported ingress ifindex mask"); 2659 return -EOPNOTSUPP; 2660 } 2661 2662 ingress_dev = __dev_get_by_index(dev_net(filter_dev), 2663 match.key->ingress_ifindex); 2664 if (!ingress_dev) { 2665 NL_SET_ERR_MSG_MOD(extack, 2666 "Can't find the ingress port to match on"); 2667 return -ENOENT; 2668 } 2669 2670 if (ingress_dev != filter_dev) { 2671 NL_SET_ERR_MSG_MOD(extack, 2672 "Can't match on the ingress filter port"); 2673 return -EOPNOTSUPP; 2674 } 2675 2676 return 0; 2677 } 2678 2679 static bool skip_key_basic(struct net_device *filter_dev, 2680 struct flow_cls_offload *f) 2681 { 2682 /* When doing mpls over udp decap, the user needs to provide 2683 * MPLS_UC as the protocol in order to be able to match on mpls 2684 * label fields. However, the actual ethertype is IP so we want to 2685 * avoid matching on this, otherwise we'll fail the match. 2686 */ 2687 if (netif_is_bareudp(filter_dev) && f->common.chain_index == 0) 2688 return true; 2689 2690 return false; 2691 } 2692 2693 static int __parse_cls_flower(struct mlx5e_priv *priv, 2694 struct mlx5e_tc_flow *flow, 2695 struct mlx5_flow_spec *spec, 2696 struct flow_cls_offload *f, 2697 struct net_device *filter_dev, 2698 u8 *inner_match_level, u8 *outer_match_level) 2699 { 2700 struct netlink_ext_ack *extack = f->common.extack; 2701 void *headers_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, 2702 outer_headers); 2703 void *headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, 2704 outer_headers); 2705 void *misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, 2706 misc_parameters); 2707 void *misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, 2708 misc_parameters); 2709 void *misc_c_3 = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, 2710 misc_parameters_3); 2711 void *misc_v_3 = MLX5_ADDR_OF(fte_match_param, spec->match_value, 2712 misc_parameters_3); 2713 struct flow_rule *rule = flow_cls_offload_flow_rule(f); 2714 struct flow_dissector *dissector = rule->match.dissector; 2715 enum fs_flow_table_type fs_type; 2716 bool match_inner_ecn = true; 2717 u16 addr_type = 0; 2718 u8 ip_proto = 0; 2719 u8 *match_level; 2720 int err; 2721 2722 fs_type = mlx5e_is_eswitch_flow(flow) ? FS_FT_FDB : FS_FT_NIC_RX; 2723 match_level = outer_match_level; 2724 2725 if (dissector->used_keys & 2726 ~(BIT_ULL(FLOW_DISSECTOR_KEY_META) | 2727 BIT_ULL(FLOW_DISSECTOR_KEY_CONTROL) | 2728 BIT_ULL(FLOW_DISSECTOR_KEY_BASIC) | 2729 BIT_ULL(FLOW_DISSECTOR_KEY_ETH_ADDRS) | 2730 BIT_ULL(FLOW_DISSECTOR_KEY_VLAN) | 2731 BIT_ULL(FLOW_DISSECTOR_KEY_CVLAN) | 2732 BIT_ULL(FLOW_DISSECTOR_KEY_IPV4_ADDRS) | 2733 BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | 2734 BIT_ULL(FLOW_DISSECTOR_KEY_PORTS) | 2735 BIT_ULL(FLOW_DISSECTOR_KEY_ENC_KEYID) | 2736 BIT_ULL(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) | 2737 BIT_ULL(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) | 2738 BIT_ULL(FLOW_DISSECTOR_KEY_ENC_PORTS) | 2739 BIT_ULL(FLOW_DISSECTOR_KEY_ENC_CONTROL) | 2740 BIT_ULL(FLOW_DISSECTOR_KEY_TCP) | 2741 BIT_ULL(FLOW_DISSECTOR_KEY_IP) | 2742 BIT_ULL(FLOW_DISSECTOR_KEY_CT) | 2743 BIT_ULL(FLOW_DISSECTOR_KEY_ENC_IP) | 2744 BIT_ULL(FLOW_DISSECTOR_KEY_ENC_OPTS) | 2745 BIT_ULL(FLOW_DISSECTOR_KEY_ICMP) | 2746 BIT_ULL(FLOW_DISSECTOR_KEY_MPLS))) { 2747 NL_SET_ERR_MSG_MOD(extack, "Unsupported key"); 2748 netdev_dbg(priv->netdev, "Unsupported key used: 0x%llx\n", 2749 dissector->used_keys); 2750 return -EOPNOTSUPP; 2751 } 2752 2753 if (mlx5e_get_tc_tun(filter_dev)) { 2754 bool match_inner = false; 2755 2756 err = parse_tunnel_attr(priv, flow, spec, f, filter_dev, 2757 outer_match_level, &match_inner); 2758 if (err) 2759 return err; 2760 2761 if (match_inner) { 2762 /* header pointers should point to the inner headers 2763 * if the packet was decapsulated already. 2764 * outer headers are set by parse_tunnel_attr. 2765 */ 2766 match_level = inner_match_level; 2767 headers_c = get_match_inner_headers_criteria(spec); 2768 headers_v = get_match_inner_headers_value(spec); 2769 } 2770 2771 err = mlx5e_tc_verify_tunnel_ecn(priv, f, &match_inner_ecn); 2772 if (err) 2773 return err; 2774 } 2775 2776 err = mlx5e_flower_parse_meta(filter_dev, f); 2777 if (err) 2778 return err; 2779 2780 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC) && 2781 !skip_key_basic(filter_dev, f)) { 2782 struct flow_match_basic match; 2783 2784 flow_rule_match_basic(rule, &match); 2785 mlx5e_tc_set_ethertype(priv->mdev, &match, 2786 match_level == outer_match_level, 2787 headers_c, headers_v); 2788 2789 if (match.mask->n_proto) 2790 *match_level = MLX5_MATCH_L2; 2791 } 2792 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN) || 2793 is_vlan_dev(filter_dev)) { 2794 struct flow_dissector_key_vlan filter_dev_mask; 2795 struct flow_dissector_key_vlan filter_dev_key; 2796 struct flow_match_vlan match; 2797 2798 if (is_vlan_dev(filter_dev)) { 2799 match.key = &filter_dev_key; 2800 match.key->vlan_id = vlan_dev_vlan_id(filter_dev); 2801 match.key->vlan_tpid = vlan_dev_vlan_proto(filter_dev); 2802 match.key->vlan_priority = 0; 2803 match.mask = &filter_dev_mask; 2804 memset(match.mask, 0xff, sizeof(*match.mask)); 2805 match.mask->vlan_priority = 0; 2806 } else { 2807 flow_rule_match_vlan(rule, &match); 2808 } 2809 if (match.mask->vlan_id || 2810 match.mask->vlan_priority || 2811 match.mask->vlan_tpid) { 2812 if (match.key->vlan_tpid == htons(ETH_P_8021AD)) { 2813 MLX5_SET(fte_match_set_lyr_2_4, headers_c, 2814 svlan_tag, 1); 2815 MLX5_SET(fte_match_set_lyr_2_4, headers_v, 2816 svlan_tag, 1); 2817 } else { 2818 MLX5_SET(fte_match_set_lyr_2_4, headers_c, 2819 cvlan_tag, 1); 2820 MLX5_SET(fte_match_set_lyr_2_4, headers_v, 2821 cvlan_tag, 1); 2822 } 2823 2824 MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_vid, 2825 match.mask->vlan_id); 2826 MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_vid, 2827 match.key->vlan_id); 2828 2829 MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_prio, 2830 match.mask->vlan_priority); 2831 MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_prio, 2832 match.key->vlan_priority); 2833 2834 *match_level = MLX5_MATCH_L2; 2835 2836 if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CVLAN) && 2837 match.mask->vlan_eth_type && 2838 MLX5_CAP_FLOWTABLE_TYPE(priv->mdev, 2839 ft_field_support.outer_second_vid, 2840 fs_type)) { 2841 MLX5_SET(fte_match_set_misc, misc_c, 2842 outer_second_cvlan_tag, 1); 2843 spec->match_criteria_enable |= 2844 MLX5_MATCH_MISC_PARAMETERS; 2845 } 2846 } 2847 } else if (*match_level != MLX5_MATCH_NONE) { 2848 /* cvlan_tag enabled in match criteria and 2849 * disabled in match value means both S & C tags 2850 * don't exist (untagged of both) 2851 */ 2852 MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1); 2853 *match_level = MLX5_MATCH_L2; 2854 } 2855 2856 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CVLAN)) { 2857 struct flow_match_vlan match; 2858 2859 flow_rule_match_cvlan(rule, &match); 2860 if (match.mask->vlan_id || 2861 match.mask->vlan_priority || 2862 match.mask->vlan_tpid) { 2863 if (!MLX5_CAP_FLOWTABLE_TYPE(priv->mdev, ft_field_support.outer_second_vid, 2864 fs_type)) { 2865 NL_SET_ERR_MSG_MOD(extack, 2866 "Matching on CVLAN is not supported"); 2867 return -EOPNOTSUPP; 2868 } 2869 2870 if (match.key->vlan_tpid == htons(ETH_P_8021AD)) { 2871 MLX5_SET(fte_match_set_misc, misc_c, 2872 outer_second_svlan_tag, 1); 2873 MLX5_SET(fte_match_set_misc, misc_v, 2874 outer_second_svlan_tag, 1); 2875 } else { 2876 MLX5_SET(fte_match_set_misc, misc_c, 2877 outer_second_cvlan_tag, 1); 2878 MLX5_SET(fte_match_set_misc, misc_v, 2879 outer_second_cvlan_tag, 1); 2880 } 2881 2882 MLX5_SET(fte_match_set_misc, misc_c, outer_second_vid, 2883 match.mask->vlan_id); 2884 MLX5_SET(fte_match_set_misc, misc_v, outer_second_vid, 2885 match.key->vlan_id); 2886 MLX5_SET(fte_match_set_misc, misc_c, outer_second_prio, 2887 match.mask->vlan_priority); 2888 MLX5_SET(fte_match_set_misc, misc_v, outer_second_prio, 2889 match.key->vlan_priority); 2890 2891 *match_level = MLX5_MATCH_L2; 2892 spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS; 2893 } 2894 } 2895 2896 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { 2897 struct flow_match_eth_addrs match; 2898 2899 flow_rule_match_eth_addrs(rule, &match); 2900 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, 2901 dmac_47_16), 2902 match.mask->dst); 2903 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, 2904 dmac_47_16), 2905 match.key->dst); 2906 2907 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, 2908 smac_47_16), 2909 match.mask->src); 2910 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, 2911 smac_47_16), 2912 match.key->src); 2913 2914 if (!is_zero_ether_addr(match.mask->src) || 2915 !is_zero_ether_addr(match.mask->dst)) 2916 *match_level = MLX5_MATCH_L2; 2917 } 2918 2919 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) { 2920 struct flow_match_control match; 2921 2922 flow_rule_match_control(rule, &match); 2923 addr_type = match.key->addr_type; 2924 2925 if (match.mask->flags & FLOW_DIS_IS_FRAGMENT) { 2926 MLX5_SET(fte_match_set_lyr_2_4, headers_c, frag, 1); 2927 MLX5_SET(fte_match_set_lyr_2_4, headers_v, frag, 2928 match.key->flags & FLOW_DIS_IS_FRAGMENT); 2929 2930 /* the HW doesn't need L3 inline to match on frag=no */ 2931 if (!(match.key->flags & FLOW_DIS_IS_FRAGMENT)) 2932 *match_level = MLX5_MATCH_L2; 2933 /* *** L2 attributes parsing up to here *** */ 2934 else 2935 *match_level = MLX5_MATCH_L3; 2936 } 2937 2938 if (!flow_rule_is_supp_control_flags(FLOW_DIS_IS_FRAGMENT, 2939 match.mask->flags, extack)) 2940 return -EOPNOTSUPP; 2941 } 2942 2943 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) { 2944 struct flow_match_basic match; 2945 2946 flow_rule_match_basic(rule, &match); 2947 ip_proto = match.key->ip_proto; 2948 2949 MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol, 2950 match.mask->ip_proto); 2951 MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol, 2952 match.key->ip_proto); 2953 2954 if (match.mask->ip_proto) 2955 *match_level = MLX5_MATCH_L3; 2956 } 2957 2958 if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { 2959 struct flow_match_ipv4_addrs match; 2960 2961 flow_rule_match_ipv4_addrs(rule, &match); 2962 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, 2963 src_ipv4_src_ipv6.ipv4_layout.ipv4), 2964 &match.mask->src, sizeof(match.mask->src)); 2965 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, 2966 src_ipv4_src_ipv6.ipv4_layout.ipv4), 2967 &match.key->src, sizeof(match.key->src)); 2968 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, 2969 dst_ipv4_dst_ipv6.ipv4_layout.ipv4), 2970 &match.mask->dst, sizeof(match.mask->dst)); 2971 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, 2972 dst_ipv4_dst_ipv6.ipv4_layout.ipv4), 2973 &match.key->dst, sizeof(match.key->dst)); 2974 2975 if (match.mask->src || match.mask->dst) 2976 *match_level = MLX5_MATCH_L3; 2977 } 2978 2979 if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { 2980 struct flow_match_ipv6_addrs match; 2981 2982 flow_rule_match_ipv6_addrs(rule, &match); 2983 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, 2984 src_ipv4_src_ipv6.ipv6_layout.ipv6), 2985 &match.mask->src, sizeof(match.mask->src)); 2986 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, 2987 src_ipv4_src_ipv6.ipv6_layout.ipv6), 2988 &match.key->src, sizeof(match.key->src)); 2989 2990 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c, 2991 dst_ipv4_dst_ipv6.ipv6_layout.ipv6), 2992 &match.mask->dst, sizeof(match.mask->dst)); 2993 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v, 2994 dst_ipv4_dst_ipv6.ipv6_layout.ipv6), 2995 &match.key->dst, sizeof(match.key->dst)); 2996 2997 if (ipv6_addr_type(&match.mask->src) != IPV6_ADDR_ANY || 2998 ipv6_addr_type(&match.mask->dst) != IPV6_ADDR_ANY) 2999 *match_level = MLX5_MATCH_L3; 3000 } 3001 3002 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) { 3003 struct flow_match_ip match; 3004 3005 flow_rule_match_ip(rule, &match); 3006 if (match_inner_ecn) { 3007 MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_ecn, 3008 match.mask->tos & 0x3); 3009 MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_ecn, 3010 match.key->tos & 0x3); 3011 } 3012 3013 MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_dscp, 3014 match.mask->tos >> 2); 3015 MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_dscp, 3016 match.key->tos >> 2); 3017 3018 MLX5_SET(fte_match_set_lyr_2_4, headers_c, ttl_hoplimit, 3019 match.mask->ttl); 3020 MLX5_SET(fte_match_set_lyr_2_4, headers_v, ttl_hoplimit, 3021 match.key->ttl); 3022 3023 if (match.mask->ttl && 3024 !MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev, 3025 ft_field_support.outer_ipv4_ttl)) { 3026 NL_SET_ERR_MSG_MOD(extack, 3027 "Matching on TTL is not supported"); 3028 return -EOPNOTSUPP; 3029 } 3030 3031 if (match.mask->tos || match.mask->ttl) 3032 *match_level = MLX5_MATCH_L3; 3033 } 3034 3035 /* *** L3 attributes parsing up to here *** */ 3036 3037 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) { 3038 struct flow_match_ports match; 3039 3040 flow_rule_match_ports(rule, &match); 3041 switch (ip_proto) { 3042 case IPPROTO_TCP: 3043 MLX5_SET(fte_match_set_lyr_2_4, headers_c, 3044 tcp_sport, ntohs(match.mask->src)); 3045 MLX5_SET(fte_match_set_lyr_2_4, headers_v, 3046 tcp_sport, ntohs(match.key->src)); 3047 3048 MLX5_SET(fte_match_set_lyr_2_4, headers_c, 3049 tcp_dport, ntohs(match.mask->dst)); 3050 MLX5_SET(fte_match_set_lyr_2_4, headers_v, 3051 tcp_dport, ntohs(match.key->dst)); 3052 break; 3053 3054 case IPPROTO_UDP: 3055 MLX5_SET(fte_match_set_lyr_2_4, headers_c, 3056 udp_sport, ntohs(match.mask->src)); 3057 MLX5_SET(fte_match_set_lyr_2_4, headers_v, 3058 udp_sport, ntohs(match.key->src)); 3059 3060 MLX5_SET(fte_match_set_lyr_2_4, headers_c, 3061 udp_dport, ntohs(match.mask->dst)); 3062 MLX5_SET(fte_match_set_lyr_2_4, headers_v, 3063 udp_dport, ntohs(match.key->dst)); 3064 break; 3065 default: 3066 NL_SET_ERR_MSG_MOD(extack, 3067 "Only UDP and TCP transports are supported for L4 matching"); 3068 netdev_err(priv->netdev, 3069 "Only UDP and TCP transport are supported\n"); 3070 return -EINVAL; 3071 } 3072 3073 if (match.mask->src || match.mask->dst) 3074 *match_level = MLX5_MATCH_L4; 3075 } 3076 3077 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_TCP)) { 3078 struct flow_match_tcp match; 3079 3080 flow_rule_match_tcp(rule, &match); 3081 MLX5_SET(fte_match_set_lyr_2_4, headers_c, tcp_flags, 3082 ntohs(match.mask->flags)); 3083 MLX5_SET(fte_match_set_lyr_2_4, headers_v, tcp_flags, 3084 ntohs(match.key->flags)); 3085 3086 if (match.mask->flags) 3087 *match_level = MLX5_MATCH_L4; 3088 } 3089 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ICMP)) { 3090 struct flow_match_icmp match; 3091 3092 flow_rule_match_icmp(rule, &match); 3093 switch (ip_proto) { 3094 case IPPROTO_ICMP: 3095 if (!(MLX5_CAP_GEN(priv->mdev, flex_parser_protocols) & 3096 MLX5_FLEX_PROTO_ICMP)) { 3097 NL_SET_ERR_MSG_MOD(extack, 3098 "Match on Flex protocols for ICMP is not supported"); 3099 return -EOPNOTSUPP; 3100 } 3101 MLX5_SET(fte_match_set_misc3, misc_c_3, icmp_type, 3102 match.mask->type); 3103 MLX5_SET(fte_match_set_misc3, misc_v_3, icmp_type, 3104 match.key->type); 3105 MLX5_SET(fte_match_set_misc3, misc_c_3, icmp_code, 3106 match.mask->code); 3107 MLX5_SET(fte_match_set_misc3, misc_v_3, icmp_code, 3108 match.key->code); 3109 break; 3110 case IPPROTO_ICMPV6: 3111 if (!(MLX5_CAP_GEN(priv->mdev, flex_parser_protocols) & 3112 MLX5_FLEX_PROTO_ICMPV6)) { 3113 NL_SET_ERR_MSG_MOD(extack, 3114 "Match on Flex protocols for ICMPV6 is not supported"); 3115 return -EOPNOTSUPP; 3116 } 3117 MLX5_SET(fte_match_set_misc3, misc_c_3, icmpv6_type, 3118 match.mask->type); 3119 MLX5_SET(fte_match_set_misc3, misc_v_3, icmpv6_type, 3120 match.key->type); 3121 MLX5_SET(fte_match_set_misc3, misc_c_3, icmpv6_code, 3122 match.mask->code); 3123 MLX5_SET(fte_match_set_misc3, misc_v_3, icmpv6_code, 3124 match.key->code); 3125 break; 3126 default: 3127 NL_SET_ERR_MSG_MOD(extack, 3128 "Code and type matching only with ICMP and ICMPv6"); 3129 netdev_err(priv->netdev, 3130 "Code and type matching only with ICMP and ICMPv6\n"); 3131 return -EINVAL; 3132 } 3133 if (match.mask->code || match.mask->type) { 3134 *match_level = MLX5_MATCH_L4; 3135 spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_3; 3136 } 3137 } 3138 /* Currently supported only for MPLS over UDP */ 3139 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS) && 3140 !netif_is_bareudp(filter_dev)) { 3141 NL_SET_ERR_MSG_MOD(extack, 3142 "Matching on MPLS is supported only for MPLS over UDP"); 3143 netdev_err(priv->netdev, 3144 "Matching on MPLS is supported only for MPLS over UDP\n"); 3145 return -EOPNOTSUPP; 3146 } 3147 3148 return 0; 3149 } 3150 3151 static int parse_cls_flower(struct mlx5e_priv *priv, 3152 struct mlx5e_tc_flow *flow, 3153 struct mlx5_flow_spec *spec, 3154 struct flow_cls_offload *f, 3155 struct net_device *filter_dev) 3156 { 3157 u8 inner_match_level, outer_match_level, non_tunnel_match_level; 3158 struct netlink_ext_ack *extack = f->common.extack; 3159 struct mlx5_core_dev *dev = priv->mdev; 3160 struct mlx5_eswitch *esw = dev->priv.eswitch; 3161 struct mlx5e_rep_priv *rpriv = priv->ppriv; 3162 struct mlx5_eswitch_rep *rep; 3163 bool is_eswitch_flow; 3164 int err; 3165 3166 inner_match_level = MLX5_MATCH_NONE; 3167 outer_match_level = MLX5_MATCH_NONE; 3168 3169 err = __parse_cls_flower(priv, flow, spec, f, filter_dev, 3170 &inner_match_level, &outer_match_level); 3171 non_tunnel_match_level = (inner_match_level == MLX5_MATCH_NONE) ? 3172 outer_match_level : inner_match_level; 3173 3174 is_eswitch_flow = mlx5e_is_eswitch_flow(flow); 3175 if (!err && is_eswitch_flow) { 3176 rep = rpriv->rep; 3177 if (rep->vport != MLX5_VPORT_UPLINK && 3178 (esw->offloads.inline_mode != MLX5_INLINE_MODE_NONE && 3179 esw->offloads.inline_mode < non_tunnel_match_level)) { 3180 NL_SET_ERR_MSG_MOD(extack, 3181 "Flow is not offloaded due to min inline setting"); 3182 netdev_warn(priv->netdev, 3183 "Flow is not offloaded due to min inline setting, required %d actual %d\n", 3184 non_tunnel_match_level, esw->offloads.inline_mode); 3185 return -EOPNOTSUPP; 3186 } 3187 } 3188 3189 flow->attr->inner_match_level = inner_match_level; 3190 flow->attr->outer_match_level = outer_match_level; 3191 3192 3193 return err; 3194 } 3195 3196 struct mlx5_fields { 3197 u8 field; 3198 u8 field_bsize; 3199 u32 field_mask; 3200 u32 offset; 3201 u32 match_offset; 3202 }; 3203 3204 #define OFFLOAD(fw_field, field_bsize, field_mask, field, off, match_field) \ 3205 {MLX5_ACTION_IN_FIELD_OUT_ ## fw_field, field_bsize, field_mask, \ 3206 offsetof(struct pedit_headers, field) + (off), \ 3207 MLX5_BYTE_OFF(fte_match_set_lyr_2_4, match_field)} 3208 3209 /* masked values are the same and there are no rewrites that do not have a 3210 * match. 3211 */ 3212 #define SAME_VAL_MASK(type, valp, maskp, matchvalp, matchmaskp) ({ \ 3213 type matchmaskx = *(type *)(matchmaskp); \ 3214 type matchvalx = *(type *)(matchvalp); \ 3215 type maskx = *(type *)(maskp); \ 3216 type valx = *(type *)(valp); \ 3217 \ 3218 (valx & maskx) == (matchvalx & matchmaskx) && !(maskx & (maskx ^ \ 3219 matchmaskx)); \ 3220 }) 3221 3222 static bool cmp_val_mask(void *valp, void *maskp, void *matchvalp, 3223 void *matchmaskp, u8 bsize) 3224 { 3225 bool same = false; 3226 3227 switch (bsize) { 3228 case 8: 3229 same = SAME_VAL_MASK(u8, valp, maskp, matchvalp, matchmaskp); 3230 break; 3231 case 16: 3232 same = SAME_VAL_MASK(u16, valp, maskp, matchvalp, matchmaskp); 3233 break; 3234 case 32: 3235 same = SAME_VAL_MASK(u32, valp, maskp, matchvalp, matchmaskp); 3236 break; 3237 } 3238 3239 return same; 3240 } 3241 3242 static struct mlx5_fields fields[] = { 3243 OFFLOAD(DMAC_47_16, 32, U32_MAX, eth.h_dest[0], 0, dmac_47_16), 3244 OFFLOAD(DMAC_15_0, 16, U16_MAX, eth.h_dest[4], 0, dmac_15_0), 3245 OFFLOAD(SMAC_47_16, 32, U32_MAX, eth.h_source[0], 0, smac_47_16), 3246 OFFLOAD(SMAC_15_0, 16, U16_MAX, eth.h_source[4], 0, smac_15_0), 3247 OFFLOAD(ETHERTYPE, 16, U16_MAX, eth.h_proto, 0, ethertype), 3248 OFFLOAD(FIRST_VID, 16, U16_MAX, vlan.h_vlan_TCI, 0, first_vid), 3249 3250 OFFLOAD(IP_DSCP, 8, 0xfc, ip4.tos, 0, ip_dscp), 3251 OFFLOAD(IP_TTL, 8, U8_MAX, ip4.ttl, 0, ttl_hoplimit), 3252 OFFLOAD(SIPV4, 32, U32_MAX, ip4.saddr, 0, src_ipv4_src_ipv6.ipv4_layout.ipv4), 3253 OFFLOAD(DIPV4, 32, U32_MAX, ip4.daddr, 0, dst_ipv4_dst_ipv6.ipv4_layout.ipv4), 3254 3255 OFFLOAD(SIPV6_127_96, 32, U32_MAX, ip6.saddr.s6_addr32[0], 0, 3256 src_ipv4_src_ipv6.ipv6_layout.ipv6[0]), 3257 OFFLOAD(SIPV6_95_64, 32, U32_MAX, ip6.saddr.s6_addr32[1], 0, 3258 src_ipv4_src_ipv6.ipv6_layout.ipv6[4]), 3259 OFFLOAD(SIPV6_63_32, 32, U32_MAX, ip6.saddr.s6_addr32[2], 0, 3260 src_ipv4_src_ipv6.ipv6_layout.ipv6[8]), 3261 OFFLOAD(SIPV6_31_0, 32, U32_MAX, ip6.saddr.s6_addr32[3], 0, 3262 src_ipv4_src_ipv6.ipv6_layout.ipv6[12]), 3263 OFFLOAD(DIPV6_127_96, 32, U32_MAX, ip6.daddr.s6_addr32[0], 0, 3264 dst_ipv4_dst_ipv6.ipv6_layout.ipv6[0]), 3265 OFFLOAD(DIPV6_95_64, 32, U32_MAX, ip6.daddr.s6_addr32[1], 0, 3266 dst_ipv4_dst_ipv6.ipv6_layout.ipv6[4]), 3267 OFFLOAD(DIPV6_63_32, 32, U32_MAX, ip6.daddr.s6_addr32[2], 0, 3268 dst_ipv4_dst_ipv6.ipv6_layout.ipv6[8]), 3269 OFFLOAD(DIPV6_31_0, 32, U32_MAX, ip6.daddr.s6_addr32[3], 0, 3270 dst_ipv4_dst_ipv6.ipv6_layout.ipv6[12]), 3271 OFFLOAD(IPV6_HOPLIMIT, 8, U8_MAX, ip6.hop_limit, 0, ttl_hoplimit), 3272 OFFLOAD(IP_DSCP, 16, 0x0fc0, ip6, 0, ip_dscp), 3273 3274 OFFLOAD(TCP_SPORT, 16, U16_MAX, tcp.source, 0, tcp_sport), 3275 OFFLOAD(TCP_DPORT, 16, U16_MAX, tcp.dest, 0, tcp_dport), 3276 /* in linux iphdr tcp_flags is 8 bits long */ 3277 OFFLOAD(TCP_FLAGS, 8, U8_MAX, tcp.ack_seq, 5, tcp_flags), 3278 3279 OFFLOAD(UDP_SPORT, 16, U16_MAX, udp.source, 0, udp_sport), 3280 OFFLOAD(UDP_DPORT, 16, U16_MAX, udp.dest, 0, udp_dport), 3281 }; 3282 3283 static u32 mask_field_get(void *mask, struct mlx5_fields *f) 3284 { 3285 switch (f->field_bsize) { 3286 case 32: 3287 return be32_to_cpu(*(__be32 *)mask) & f->field_mask; 3288 case 16: 3289 return be16_to_cpu(*(__be16 *)mask) & (u16)f->field_mask; 3290 default: 3291 return *(u8 *)mask & (u8)f->field_mask; 3292 } 3293 } 3294 3295 static void mask_field_clear(void *mask, struct mlx5_fields *f) 3296 { 3297 switch (f->field_bsize) { 3298 case 32: 3299 *(__be32 *)mask &= ~cpu_to_be32(f->field_mask); 3300 break; 3301 case 16: 3302 *(__be16 *)mask &= ~cpu_to_be16((u16)f->field_mask); 3303 break; 3304 default: 3305 *(u8 *)mask &= ~(u8)f->field_mask; 3306 break; 3307 } 3308 } 3309 3310 static int offload_pedit_fields(struct mlx5e_priv *priv, 3311 int namespace, 3312 struct mlx5e_tc_flow_parse_attr *parse_attr, 3313 u32 *action_flags, 3314 struct netlink_ext_ack *extack) 3315 { 3316 struct pedit_headers *set_masks, *add_masks, *set_vals, *add_vals; 3317 struct pedit_headers_action *hdrs = parse_attr->hdrs; 3318 void *headers_c, *headers_v, *action, *vals_p; 3319 struct mlx5e_tc_mod_hdr_acts *mod_acts; 3320 void *s_masks_p, *a_masks_p; 3321 int i, first, last, next_z; 3322 struct mlx5_fields *f; 3323 unsigned long mask; 3324 u32 s_mask, a_mask; 3325 u8 cmd; 3326 3327 mod_acts = &parse_attr->mod_hdr_acts; 3328 headers_c = mlx5e_get_match_headers_criteria(*action_flags, &parse_attr->spec); 3329 headers_v = mlx5e_get_match_headers_value(*action_flags, &parse_attr->spec); 3330 3331 set_masks = &hdrs[TCA_PEDIT_KEY_EX_CMD_SET].masks; 3332 add_masks = &hdrs[TCA_PEDIT_KEY_EX_CMD_ADD].masks; 3333 set_vals = &hdrs[TCA_PEDIT_KEY_EX_CMD_SET].vals; 3334 add_vals = &hdrs[TCA_PEDIT_KEY_EX_CMD_ADD].vals; 3335 3336 for (i = 0; i < ARRAY_SIZE(fields); i++) { 3337 bool skip; 3338 3339 f = &fields[i]; 3340 s_masks_p = (void *)set_masks + f->offset; 3341 a_masks_p = (void *)add_masks + f->offset; 3342 3343 s_mask = mask_field_get(s_masks_p, f); 3344 a_mask = mask_field_get(a_masks_p, f); 3345 3346 if (!s_mask && !a_mask) /* nothing to offload here */ 3347 continue; 3348 3349 if (s_mask && a_mask) { 3350 NL_SET_ERR_MSG_MOD(extack, 3351 "can't set and add to the same HW field"); 3352 netdev_warn(priv->netdev, 3353 "mlx5: can't set and add to the same HW field (%x)\n", 3354 f->field); 3355 return -EOPNOTSUPP; 3356 } 3357 3358 skip = false; 3359 if (s_mask) { 3360 void *match_mask = headers_c + f->match_offset; 3361 void *match_val = headers_v + f->match_offset; 3362 3363 cmd = MLX5_ACTION_TYPE_SET; 3364 mask = s_mask; 3365 vals_p = (void *)set_vals + f->offset; 3366 /* don't rewrite if we have a match on the same value */ 3367 if (cmp_val_mask(vals_p, s_masks_p, match_val, 3368 match_mask, f->field_bsize)) 3369 skip = true; 3370 /* clear to denote we consumed this field */ 3371 mask_field_clear(s_masks_p, f); 3372 } else { 3373 cmd = MLX5_ACTION_TYPE_ADD; 3374 mask = a_mask; 3375 vals_p = (void *)add_vals + f->offset; 3376 /* add 0 is no change */ 3377 if (!mask_field_get(vals_p, f)) 3378 skip = true; 3379 /* clear to denote we consumed this field */ 3380 mask_field_clear(a_masks_p, f); 3381 } 3382 if (skip) 3383 continue; 3384 3385 first = find_first_bit(&mask, f->field_bsize); 3386 next_z = find_next_zero_bit(&mask, f->field_bsize, first); 3387 last = find_last_bit(&mask, f->field_bsize); 3388 if (first < next_z && next_z < last) { 3389 NL_SET_ERR_MSG_MOD(extack, 3390 "rewrite of few sub-fields isn't supported"); 3391 netdev_warn(priv->netdev, 3392 "mlx5: rewrite of few sub-fields (mask %lx) isn't offloaded\n", 3393 mask); 3394 return -EOPNOTSUPP; 3395 } 3396 3397 action = mlx5e_mod_hdr_alloc(priv->mdev, namespace, mod_acts); 3398 if (IS_ERR(action)) { 3399 NL_SET_ERR_MSG_MOD(extack, 3400 "too many pedit actions, can't offload"); 3401 mlx5_core_warn(priv->mdev, 3402 "mlx5: parsed %d pedit actions, can't do more\n", 3403 mod_acts->num_actions); 3404 return PTR_ERR(action); 3405 } 3406 3407 MLX5_SET(set_action_in, action, action_type, cmd); 3408 MLX5_SET(set_action_in, action, field, f->field); 3409 3410 if (cmd == MLX5_ACTION_TYPE_SET) { 3411 unsigned long field_mask = f->field_mask; 3412 int start; 3413 3414 /* if field is bit sized it can start not from first bit */ 3415 start = find_first_bit(&field_mask, f->field_bsize); 3416 3417 MLX5_SET(set_action_in, action, offset, first - start); 3418 /* length is num of bits to be written, zero means length of 32 */ 3419 MLX5_SET(set_action_in, action, length, (last - first + 1)); 3420 } 3421 3422 if (f->field_bsize == 32) 3423 MLX5_SET(set_action_in, action, data, ntohl(*(__be32 *)vals_p) >> first); 3424 else if (f->field_bsize == 16) 3425 MLX5_SET(set_action_in, action, data, ntohs(*(__be16 *)vals_p) >> first); 3426 else if (f->field_bsize == 8) 3427 MLX5_SET(set_action_in, action, data, *(u8 *)vals_p >> first); 3428 3429 ++mod_acts->num_actions; 3430 } 3431 3432 return 0; 3433 } 3434 3435 static const struct pedit_headers zero_masks = {}; 3436 3437 static int verify_offload_pedit_fields(struct mlx5e_priv *priv, 3438 struct mlx5e_tc_flow_parse_attr *parse_attr, 3439 struct netlink_ext_ack *extack) 3440 { 3441 struct pedit_headers *cmd_masks; 3442 u8 cmd; 3443 3444 for (cmd = 0; cmd < __PEDIT_CMD_MAX; cmd++) { 3445 cmd_masks = &parse_attr->hdrs[cmd].masks; 3446 if (memcmp(cmd_masks, &zero_masks, sizeof(zero_masks))) { 3447 NL_SET_ERR_MSG_MOD(extack, "attempt to offload an unsupported field"); 3448 netdev_warn(priv->netdev, "attempt to offload an unsupported field (cmd %d)\n", cmd); 3449 print_hex_dump(KERN_WARNING, "mask: ", DUMP_PREFIX_ADDRESS, 3450 16, 1, cmd_masks, sizeof(zero_masks), true); 3451 return -EOPNOTSUPP; 3452 } 3453 } 3454 3455 return 0; 3456 } 3457 3458 static int alloc_tc_pedit_action(struct mlx5e_priv *priv, int namespace, 3459 struct mlx5e_tc_flow_parse_attr *parse_attr, 3460 u32 *action_flags, 3461 struct netlink_ext_ack *extack) 3462 { 3463 int err; 3464 3465 err = offload_pedit_fields(priv, namespace, parse_attr, action_flags, extack); 3466 if (err) 3467 goto out_dealloc_parsed_actions; 3468 3469 err = verify_offload_pedit_fields(priv, parse_attr, extack); 3470 if (err) 3471 goto out_dealloc_parsed_actions; 3472 3473 return 0; 3474 3475 out_dealloc_parsed_actions: 3476 mlx5e_mod_hdr_dealloc(&parse_attr->mod_hdr_acts); 3477 return err; 3478 } 3479 3480 struct ip_ttl_word { 3481 __u8 ttl; 3482 __u8 protocol; 3483 __sum16 check; 3484 }; 3485 3486 struct ipv6_hoplimit_word { 3487 __be16 payload_len; 3488 __u8 nexthdr; 3489 __u8 hop_limit; 3490 }; 3491 3492 static bool 3493 is_flow_action_modify_ip_header(struct flow_action *flow_action) 3494 { 3495 const struct flow_action_entry *act; 3496 u32 mask, offset; 3497 u8 htype; 3498 int i; 3499 3500 /* For IPv4 & IPv6 header check 4 byte word, 3501 * to determine that modified fields 3502 * are NOT ttl & hop_limit only. 3503 */ 3504 flow_action_for_each(i, act, flow_action) { 3505 if (act->id != FLOW_ACTION_MANGLE && 3506 act->id != FLOW_ACTION_ADD) 3507 continue; 3508 3509 htype = act->mangle.htype; 3510 offset = act->mangle.offset; 3511 mask = ~act->mangle.mask; 3512 3513 if (htype == FLOW_ACT_MANGLE_HDR_TYPE_IP4) { 3514 struct ip_ttl_word *ttl_word = 3515 (struct ip_ttl_word *)&mask; 3516 3517 if (offset != offsetof(struct iphdr, ttl) || 3518 ttl_word->protocol || 3519 ttl_word->check) 3520 return true; 3521 } else if (htype == FLOW_ACT_MANGLE_HDR_TYPE_IP6) { 3522 struct ipv6_hoplimit_word *hoplimit_word = 3523 (struct ipv6_hoplimit_word *)&mask; 3524 3525 if (offset != offsetof(struct ipv6hdr, payload_len) || 3526 hoplimit_word->payload_len || 3527 hoplimit_word->nexthdr) 3528 return true; 3529 } 3530 } 3531 3532 return false; 3533 } 3534 3535 static bool modify_header_match_supported(struct mlx5e_priv *priv, 3536 struct mlx5_flow_spec *spec, 3537 struct flow_action *flow_action, 3538 u32 actions, 3539 struct netlink_ext_ack *extack) 3540 { 3541 bool modify_ip_header; 3542 void *headers_c; 3543 void *headers_v; 3544 u16 ethertype; 3545 u8 ip_proto; 3546 3547 headers_c = mlx5e_get_match_headers_criteria(actions, spec); 3548 headers_v = mlx5e_get_match_headers_value(actions, spec); 3549 ethertype = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ethertype); 3550 3551 /* for non-IP we only re-write MACs, so we're okay */ 3552 if (MLX5_GET(fte_match_set_lyr_2_4, headers_c, ip_version) == 0 && 3553 ethertype != ETH_P_IP && ethertype != ETH_P_IPV6) 3554 goto out_ok; 3555 3556 modify_ip_header = is_flow_action_modify_ip_header(flow_action); 3557 ip_proto = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol); 3558 if (modify_ip_header && ip_proto != IPPROTO_TCP && 3559 ip_proto != IPPROTO_UDP && ip_proto != IPPROTO_ICMP) { 3560 NL_SET_ERR_MSG_MOD(extack, 3561 "can't offload re-write of non TCP/UDP"); 3562 netdev_info(priv->netdev, "can't offload re-write of ip proto %d\n", 3563 ip_proto); 3564 return false; 3565 } 3566 3567 out_ok: 3568 return true; 3569 } 3570 3571 static bool 3572 actions_match_supported_fdb(struct mlx5e_priv *priv, 3573 struct mlx5e_tc_flow *flow, 3574 struct netlink_ext_ack *extack) 3575 { 3576 struct mlx5_esw_flow_attr *esw_attr = flow->attr->esw_attr; 3577 3578 if (esw_attr->split_count > 0 && !mlx5_esw_has_fwd_fdb(priv->mdev)) { 3579 NL_SET_ERR_MSG_MOD(extack, 3580 "current firmware doesn't support split rule for port mirroring"); 3581 netdev_warn_once(priv->netdev, 3582 "current firmware doesn't support split rule for port mirroring\n"); 3583 return false; 3584 } 3585 3586 return true; 3587 } 3588 3589 static bool 3590 actions_match_supported(struct mlx5e_priv *priv, 3591 struct flow_action *flow_action, 3592 u32 actions, 3593 struct mlx5e_tc_flow_parse_attr *parse_attr, 3594 struct mlx5e_tc_flow *flow, 3595 struct netlink_ext_ack *extack) 3596 { 3597 if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR && 3598 !modify_header_match_supported(priv, &parse_attr->spec, flow_action, actions, 3599 extack)) 3600 return false; 3601 3602 if (mlx5e_is_eswitch_flow(flow) && 3603 !actions_match_supported_fdb(priv, flow, extack)) 3604 return false; 3605 3606 return true; 3607 } 3608 3609 static bool same_port_devs(struct mlx5e_priv *priv, struct mlx5e_priv *peer_priv) 3610 { 3611 return priv->mdev == peer_priv->mdev; 3612 } 3613 3614 bool mlx5e_same_hw_devs(struct mlx5e_priv *priv, struct mlx5e_priv *peer_priv) 3615 { 3616 struct mlx5_core_dev *fmdev, *pmdev; 3617 3618 fmdev = priv->mdev; 3619 pmdev = peer_priv->mdev; 3620 3621 return mlx5_same_hw_devs(fmdev, pmdev); 3622 } 3623 3624 static int 3625 actions_prepare_mod_hdr_actions(struct mlx5e_priv *priv, 3626 struct mlx5e_tc_flow *flow, 3627 struct mlx5_flow_attr *attr, 3628 struct netlink_ext_ack *extack) 3629 { 3630 struct mlx5e_tc_flow_parse_attr *parse_attr = attr->parse_attr; 3631 struct pedit_headers_action *hdrs = parse_attr->hdrs; 3632 enum mlx5_flow_namespace_type ns_type; 3633 int err; 3634 3635 if (!hdrs[TCA_PEDIT_KEY_EX_CMD_SET].pedits && 3636 !hdrs[TCA_PEDIT_KEY_EX_CMD_ADD].pedits) 3637 return 0; 3638 3639 ns_type = mlx5e_get_flow_namespace(flow); 3640 3641 err = alloc_tc_pedit_action(priv, ns_type, parse_attr, &attr->action, extack); 3642 if (err) 3643 return err; 3644 3645 if (parse_attr->mod_hdr_acts.num_actions > 0) 3646 return 0; 3647 3648 /* In case all pedit actions are skipped, remove the MOD_HDR flag. */ 3649 attr->action &= ~MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; 3650 mlx5e_mod_hdr_dealloc(&parse_attr->mod_hdr_acts); 3651 3652 if (ns_type != MLX5_FLOW_NAMESPACE_FDB) 3653 return 0; 3654 3655 if (!((attr->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_POP) || 3656 (attr->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH))) 3657 attr->esw_attr->split_count = 0; 3658 3659 return 0; 3660 } 3661 3662 static struct mlx5_flow_attr* 3663 mlx5e_clone_flow_attr_for_post_act(struct mlx5_flow_attr *attr, 3664 enum mlx5_flow_namespace_type ns_type) 3665 { 3666 struct mlx5e_tc_flow_parse_attr *parse_attr; 3667 u32 attr_sz = ns_to_attr_sz(ns_type); 3668 struct mlx5_flow_attr *attr2; 3669 3670 attr2 = mlx5_alloc_flow_attr(ns_type); 3671 parse_attr = kvzalloc_obj(*parse_attr); 3672 if (!attr2 || !parse_attr) { 3673 kvfree(parse_attr); 3674 kfree(attr2); 3675 return NULL; 3676 } 3677 3678 memcpy(attr2, attr, attr_sz); 3679 INIT_LIST_HEAD(&attr2->list); 3680 parse_attr->filter_dev = attr->parse_attr->filter_dev; 3681 attr2->action = 0; 3682 attr2->counter = NULL; 3683 attr2->tc_act_cookies_count = 0; 3684 attr2->flags = 0; 3685 attr2->parse_attr = parse_attr; 3686 attr2->dest_chain = 0; 3687 attr2->dest_ft = NULL; 3688 attr2->act_id_restore_rule = NULL; 3689 memset(&attr2->ct_attr, 0, sizeof(attr2->ct_attr)); 3690 3691 if (ns_type == MLX5_FLOW_NAMESPACE_FDB) { 3692 attr2->esw_attr->out_count = 0; 3693 attr2->esw_attr->split_count = 0; 3694 } 3695 3696 attr2->branch_true = NULL; 3697 attr2->branch_false = NULL; 3698 attr2->jumping_attr = NULL; 3699 return attr2; 3700 } 3701 3702 struct mlx5_flow_attr * 3703 mlx5e_tc_get_encap_attr(struct mlx5e_tc_flow *flow) 3704 { 3705 struct mlx5_esw_flow_attr *esw_attr; 3706 struct mlx5_flow_attr *attr; 3707 int i; 3708 3709 list_for_each_entry(attr, &flow->attrs, list) { 3710 esw_attr = attr->esw_attr; 3711 for (i = 0; i < MLX5_MAX_FLOW_FWD_VPORTS; i++) { 3712 if (esw_attr->dests[i].flags & MLX5_ESW_DEST_ENCAP) 3713 return attr; 3714 } 3715 } 3716 3717 return NULL; 3718 } 3719 3720 void 3721 mlx5e_tc_unoffload_flow_post_acts(struct mlx5e_tc_flow *flow) 3722 { 3723 struct mlx5e_post_act *post_act = get_post_action(flow->priv); 3724 struct mlx5_flow_attr *attr; 3725 3726 list_for_each_entry(attr, &flow->attrs, list) { 3727 if (list_is_last(&attr->list, &flow->attrs)) 3728 break; 3729 3730 mlx5e_tc_post_act_unoffload(post_act, attr->post_act_handle); 3731 } 3732 } 3733 3734 static void 3735 free_flow_post_acts(struct mlx5e_tc_flow *flow) 3736 { 3737 struct mlx5_flow_attr *attr, *tmp; 3738 3739 list_for_each_entry_safe(attr, tmp, &flow->attrs, list) { 3740 if (list_is_last(&attr->list, &flow->attrs)) 3741 break; 3742 3743 mlx5_free_flow_attr_actions(flow, attr); 3744 3745 list_del(&attr->list); 3746 kvfree(attr->parse_attr); 3747 kfree(attr); 3748 } 3749 } 3750 3751 int 3752 mlx5e_tc_offload_flow_post_acts(struct mlx5e_tc_flow *flow) 3753 { 3754 struct mlx5e_post_act *post_act = get_post_action(flow->priv); 3755 struct mlx5_flow_attr *attr; 3756 int err = 0; 3757 3758 list_for_each_entry(attr, &flow->attrs, list) { 3759 if (list_is_last(&attr->list, &flow->attrs)) 3760 break; 3761 3762 err = mlx5e_tc_post_act_offload(post_act, attr->post_act_handle); 3763 if (err) 3764 break; 3765 } 3766 3767 return err; 3768 } 3769 3770 /* TC filter rule HW translation: 3771 * 3772 * +---------------------+ 3773 * + ft prio (tc chain) + 3774 * + original match + 3775 * +---------------------+ 3776 * | 3777 * | if multi table action 3778 * | 3779 * v 3780 * +---------------------+ 3781 * + post act ft |<----. 3782 * + match fte id | | split on multi table action 3783 * + do actions |-----' 3784 * +---------------------+ 3785 * | 3786 * | 3787 * v 3788 * Do rest of the actions after last multi table action. 3789 */ 3790 static int 3791 alloc_flow_post_acts(struct mlx5e_tc_flow *flow, struct netlink_ext_ack *extack) 3792 { 3793 struct mlx5e_post_act *post_act = get_post_action(flow->priv); 3794 struct mlx5_flow_attr *attr, *next_attr = NULL; 3795 struct mlx5e_post_act_handle *handle; 3796 int err; 3797 3798 /* This is going in reverse order as needed. 3799 * The first entry is the last attribute. 3800 */ 3801 list_for_each_entry(attr, &flow->attrs, list) { 3802 if (!next_attr) { 3803 /* Set counter action on last post act rule. */ 3804 attr->action |= MLX5_FLOW_CONTEXT_ACTION_COUNT; 3805 } 3806 3807 if (next_attr && !(attr->flags & MLX5_ATTR_FLAG_TERMINATING)) { 3808 err = mlx5e_tc_act_set_next_post_act(flow, attr, next_attr); 3809 if (err) 3810 goto out_free; 3811 } 3812 3813 /* Don't add post_act rule for first attr (last in the list). 3814 * It's being handled by the caller. 3815 */ 3816 if (list_is_last(&attr->list, &flow->attrs)) 3817 break; 3818 3819 err = actions_prepare_mod_hdr_actions(flow->priv, flow, attr, extack); 3820 if (err) 3821 goto out_free; 3822 3823 err = post_process_attr(flow, attr, extack); 3824 if (err) 3825 goto out_free; 3826 3827 handle = mlx5e_tc_post_act_add(post_act, attr); 3828 if (IS_ERR(handle)) { 3829 err = PTR_ERR(handle); 3830 goto out_free; 3831 } 3832 3833 attr->post_act_handle = handle; 3834 3835 if (attr->jumping_attr) { 3836 err = mlx5e_tc_act_set_next_post_act(flow, attr->jumping_attr, attr); 3837 if (err) 3838 goto out_free; 3839 } 3840 3841 next_attr = attr; 3842 } 3843 3844 if (flow_flag_test(flow, SLOW)) 3845 goto out; 3846 3847 err = mlx5e_tc_offload_flow_post_acts(flow); 3848 if (err) 3849 goto out_free; 3850 3851 out: 3852 return 0; 3853 3854 out_free: 3855 free_flow_post_acts(flow); 3856 return err; 3857 } 3858 3859 static int 3860 set_branch_dest_ft(struct mlx5e_priv *priv, struct mlx5_flow_attr *attr) 3861 { 3862 struct mlx5e_post_act *post_act = get_post_action(priv); 3863 3864 if (IS_ERR(post_act)) 3865 return PTR_ERR(post_act); 3866 3867 attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 3868 attr->dest_ft = mlx5e_tc_post_act_get_ft(post_act); 3869 3870 return 0; 3871 } 3872 3873 static int 3874 alloc_branch_attr(struct mlx5e_tc_flow *flow, 3875 struct mlx5e_tc_act_branch_ctrl *cond, 3876 struct mlx5_flow_attr **cond_attr, 3877 u32 *jump_count, 3878 struct netlink_ext_ack *extack) 3879 { 3880 struct mlx5_flow_attr *attr; 3881 int err = 0; 3882 3883 *cond_attr = mlx5e_clone_flow_attr_for_post_act(flow->attr, 3884 mlx5e_get_flow_namespace(flow)); 3885 if (!(*cond_attr)) 3886 return -ENOMEM; 3887 3888 attr = *cond_attr; 3889 3890 switch (cond->act_id) { 3891 case FLOW_ACTION_DROP: 3892 attr->action |= MLX5_FLOW_CONTEXT_ACTION_DROP; 3893 break; 3894 case FLOW_ACTION_ACCEPT: 3895 case FLOW_ACTION_PIPE: 3896 err = set_branch_dest_ft(flow->priv, attr); 3897 if (err) 3898 goto out_err; 3899 break; 3900 case FLOW_ACTION_JUMP: 3901 if (*jump_count) { 3902 NL_SET_ERR_MSG_MOD(extack, "Cannot offload flows with nested jumps"); 3903 err = -EOPNOTSUPP; 3904 goto out_err; 3905 } 3906 *jump_count = cond->extval; 3907 err = set_branch_dest_ft(flow->priv, attr); 3908 if (err) 3909 goto out_err; 3910 break; 3911 default: 3912 err = -EOPNOTSUPP; 3913 goto out_err; 3914 } 3915 3916 return err; 3917 out_err: 3918 kfree(*cond_attr); 3919 *cond_attr = NULL; 3920 return err; 3921 } 3922 3923 static void 3924 dec_jump_count(struct flow_action_entry *act, struct mlx5e_tc_act *tc_act, 3925 struct mlx5_flow_attr *attr, struct mlx5e_priv *priv, 3926 struct mlx5e_tc_jump_state *jump_state) 3927 { 3928 if (!jump_state->jump_count) 3929 return; 3930 3931 /* Single tc action can instantiate multiple offload actions (e.g. pedit) 3932 * Jump only over a tc action 3933 */ 3934 if (act->id == jump_state->last_id && act->hw_index == jump_state->last_index) 3935 return; 3936 3937 jump_state->last_id = act->id; 3938 jump_state->last_index = act->hw_index; 3939 3940 /* nothing to do for intermediate actions */ 3941 if (--jump_state->jump_count > 1) 3942 return; 3943 3944 if (jump_state->jump_count == 1) { /* last action in the jump action list */ 3945 3946 /* create a new attribute after this action */ 3947 jump_state->jump_target = true; 3948 3949 if (tc_act->is_terminating_action) { /* the branch ends here */ 3950 attr->flags |= MLX5_ATTR_FLAG_TERMINATING; 3951 attr->action |= MLX5_FLOW_CONTEXT_ACTION_COUNT; 3952 } else { /* the branch continues executing the rest of the actions */ 3953 struct mlx5e_post_act *post_act; 3954 3955 attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 3956 post_act = get_post_action(priv); 3957 attr->dest_ft = mlx5e_tc_post_act_get_ft(post_act); 3958 } 3959 } else if (jump_state->jump_count == 0) { /* first attr after the jump action list */ 3960 /* This is the post action for the jumping attribute (either red or green) 3961 * Use the stored jumping_attr to set the post act id on the jumping attribute 3962 */ 3963 attr->jumping_attr = jump_state->jumping_attr; 3964 } 3965 } 3966 3967 static int 3968 parse_branch_ctrl(struct flow_action_entry *act, struct mlx5e_tc_act *tc_act, 3969 struct mlx5e_tc_flow *flow, struct mlx5_flow_attr *attr, 3970 struct mlx5e_tc_jump_state *jump_state, 3971 struct netlink_ext_ack *extack) 3972 { 3973 struct mlx5e_tc_act_branch_ctrl cond_true, cond_false; 3974 u32 jump_count = jump_state->jump_count; 3975 int err; 3976 3977 if (!tc_act->get_branch_ctrl) 3978 return 0; 3979 3980 tc_act->get_branch_ctrl(act, &cond_true, &cond_false); 3981 3982 err = alloc_branch_attr(flow, &cond_true, 3983 &attr->branch_true, &jump_count, extack); 3984 if (err) 3985 goto out_err; 3986 3987 if (jump_count) 3988 jump_state->jumping_attr = attr->branch_true; 3989 3990 err = alloc_branch_attr(flow, &cond_false, 3991 &attr->branch_false, &jump_count, extack); 3992 if (err) 3993 goto err_branch_false; 3994 3995 if (jump_count && !jump_state->jumping_attr) 3996 jump_state->jumping_attr = attr->branch_false; 3997 3998 jump_state->jump_count = jump_count; 3999 4000 /* branching action requires its own counter */ 4001 attr->action |= MLX5_FLOW_CONTEXT_ACTION_COUNT; 4002 flow_flag_set(flow, USE_ACT_STATS); 4003 4004 return 0; 4005 4006 err_branch_false: 4007 free_branch_attr(flow, attr->branch_true); 4008 out_err: 4009 return err; 4010 } 4011 4012 static int 4013 parse_tc_actions(struct mlx5e_tc_act_parse_state *parse_state, 4014 struct flow_action *flow_action) 4015 { 4016 struct netlink_ext_ack *extack = parse_state->extack; 4017 struct mlx5e_tc_flow *flow = parse_state->flow; 4018 struct mlx5e_tc_jump_state jump_state = {}; 4019 struct mlx5_flow_attr *attr = flow->attr; 4020 enum mlx5_flow_namespace_type ns_type; 4021 struct mlx5e_priv *priv = flow->priv; 4022 struct mlx5_flow_attr *prev_attr; 4023 struct flow_action_entry *act; 4024 struct mlx5e_tc_act *tc_act; 4025 int err, i, i_split = 0; 4026 bool is_missable; 4027 4028 ns_type = mlx5e_get_flow_namespace(flow); 4029 list_add(&attr->list, &flow->attrs); 4030 4031 flow_action_for_each(i, act, flow_action) { 4032 jump_state.jump_target = false; 4033 is_missable = false; 4034 prev_attr = attr; 4035 4036 tc_act = mlx5e_tc_act_get(act->id, ns_type); 4037 if (!tc_act) { 4038 NL_SET_ERR_MSG_MOD(extack, "Not implemented offload action"); 4039 err = -EOPNOTSUPP; 4040 goto out_free_post_acts; 4041 } 4042 4043 if (tc_act->can_offload && !tc_act->can_offload(parse_state, act, i, attr)) { 4044 err = -EOPNOTSUPP; 4045 goto out_free_post_acts; 4046 } 4047 4048 err = tc_act->parse_action(parse_state, act, priv, attr); 4049 if (err) 4050 goto out_free_post_acts; 4051 4052 dec_jump_count(act, tc_act, attr, priv, &jump_state); 4053 4054 err = parse_branch_ctrl(act, tc_act, flow, attr, &jump_state, extack); 4055 if (err) 4056 goto out_free_post_acts; 4057 4058 parse_state->actions |= attr->action; 4059 4060 /* Split attr for multi table act if not the last act. */ 4061 if (jump_state.jump_target || 4062 (tc_act->is_multi_table_act && 4063 tc_act->is_multi_table_act(priv, act, attr) && 4064 i < flow_action->num_entries - 1)) { 4065 is_missable = tc_act->is_missable ? tc_act->is_missable(act) : false; 4066 4067 err = mlx5e_tc_act_post_parse(parse_state, flow_action, i_split, i, attr, 4068 ns_type); 4069 if (err) 4070 goto out_free_post_acts; 4071 4072 attr = mlx5e_clone_flow_attr_for_post_act(flow->attr, ns_type); 4073 if (!attr) { 4074 err = -ENOMEM; 4075 goto out_free_post_acts; 4076 } 4077 4078 i_split = i + 1; 4079 parse_state->if_count = 0; 4080 list_add(&attr->list, &flow->attrs); 4081 } 4082 4083 if (is_missable) { 4084 /* Add counter to prev, and assign act to new (next) attr */ 4085 prev_attr->action |= MLX5_FLOW_CONTEXT_ACTION_COUNT; 4086 flow_flag_set(flow, USE_ACT_STATS); 4087 4088 attr->tc_act_cookies[attr->tc_act_cookies_count++] = act->cookie; 4089 } else if (!tc_act->stats_action) { 4090 prev_attr->tc_act_cookies[prev_attr->tc_act_cookies_count++] = act->cookie; 4091 } 4092 } 4093 4094 err = mlx5e_tc_act_post_parse(parse_state, flow_action, i_split, i, attr, ns_type); 4095 if (err) 4096 goto out_free_post_acts; 4097 4098 err = alloc_flow_post_acts(flow, extack); 4099 if (err) 4100 goto out_free_post_acts; 4101 4102 return 0; 4103 4104 out_free_post_acts: 4105 free_flow_post_acts(flow); 4106 4107 return err; 4108 } 4109 4110 static int 4111 flow_action_supported(struct flow_action *flow_action, 4112 struct netlink_ext_ack *extack) 4113 { 4114 if (!flow_action_has_entries(flow_action)) { 4115 NL_SET_ERR_MSG_MOD(extack, "Flow action doesn't have any entries"); 4116 return -EINVAL; 4117 } 4118 4119 if (!flow_action_hw_stats_check(flow_action, extack, 4120 FLOW_ACTION_HW_STATS_DELAYED_BIT)) { 4121 NL_SET_ERR_MSG_MOD(extack, "Flow action HW stats type is not supported"); 4122 return -EOPNOTSUPP; 4123 } 4124 4125 return 0; 4126 } 4127 4128 static int 4129 parse_tc_nic_actions(struct mlx5e_priv *priv, 4130 struct flow_action *flow_action, 4131 struct mlx5e_tc_flow *flow, 4132 struct netlink_ext_ack *extack) 4133 { 4134 struct mlx5e_tc_act_parse_state *parse_state; 4135 struct mlx5e_tc_flow_parse_attr *parse_attr; 4136 struct mlx5_flow_attr *attr = flow->attr; 4137 int err; 4138 4139 err = flow_action_supported(flow_action, extack); 4140 if (err) 4141 return err; 4142 4143 attr->nic_attr->flow_tag = MLX5_FS_DEFAULT_FLOW_TAG; 4144 parse_attr = attr->parse_attr; 4145 parse_state = &parse_attr->parse_state; 4146 mlx5e_tc_act_init_parse_state(parse_state, flow, flow_action, extack); 4147 parse_state->ct_priv = get_ct_priv(priv); 4148 4149 err = parse_tc_actions(parse_state, flow_action); 4150 if (err) 4151 return err; 4152 4153 err = actions_prepare_mod_hdr_actions(priv, flow, attr, extack); 4154 if (err) 4155 return err; 4156 4157 err = verify_attr_actions(attr->action, extack); 4158 if (err) 4159 return err; 4160 4161 if (!actions_match_supported(priv, flow_action, parse_state->actions, 4162 parse_attr, flow, extack)) 4163 return -EOPNOTSUPP; 4164 4165 return 0; 4166 } 4167 4168 static bool is_merged_eswitch_vfs(struct mlx5e_priv *priv, 4169 struct net_device *peer_netdev) 4170 { 4171 struct mlx5e_priv *peer_priv; 4172 4173 peer_priv = netdev_priv(peer_netdev); 4174 4175 return (MLX5_CAP_ESW(priv->mdev, merged_eswitch) && 4176 mlx5e_eswitch_vf_rep(priv->netdev) && 4177 mlx5e_eswitch_vf_rep(peer_netdev) && 4178 mlx5e_same_hw_devs(priv, peer_priv)); 4179 } 4180 4181 static bool same_hw_reps(struct mlx5e_priv *priv, 4182 struct net_device *peer_netdev) 4183 { 4184 struct mlx5e_priv *peer_priv; 4185 4186 peer_priv = netdev_priv(peer_netdev); 4187 4188 return mlx5e_eswitch_rep(priv->netdev) && 4189 mlx5e_eswitch_rep(peer_netdev) && 4190 mlx5e_same_hw_devs(priv, peer_priv); 4191 } 4192 4193 static bool is_lag_dev(struct mlx5e_priv *priv, 4194 struct net_device *peer_netdev) 4195 { 4196 return ((mlx5_lag_is_sriov(priv->mdev) || 4197 mlx5_lag_is_multipath(priv->mdev)) && 4198 same_hw_reps(priv, peer_netdev)); 4199 } 4200 4201 static bool is_sd_eligible(struct mlx5e_priv *priv, 4202 struct net_device *peer_netdev) 4203 { 4204 struct mlx5e_priv *peer_priv; 4205 4206 peer_priv = netdev_priv(peer_netdev); 4207 return same_hw_reps(priv, peer_netdev) && 4208 mlx5_lag_is_sd(priv->mdev) && 4209 (mlx5_sd_get_primary(priv->mdev) == 4210 mlx5_sd_get_primary(peer_priv->mdev)); 4211 } 4212 4213 static bool is_multiport_eligible(struct mlx5e_priv *priv, struct net_device *out_dev) 4214 { 4215 struct mlx5_core_dev *primary = mlx5_sd_get_primary(priv->mdev); 4216 4217 if (!primary) 4218 return false; 4219 4220 return same_hw_reps(priv, out_dev) && mlx5_lag_is_mpesw(primary); 4221 } 4222 4223 bool mlx5e_is_valid_eswitch_fwd_dev(struct mlx5e_priv *priv, 4224 struct net_device *out_dev) 4225 { 4226 if (is_merged_eswitch_vfs(priv, out_dev)) 4227 return true; 4228 4229 if (is_sd_eligible(priv, out_dev)) 4230 return true; 4231 4232 if (is_multiport_eligible(priv, out_dev)) 4233 return true; 4234 4235 if (is_lag_dev(priv, out_dev)) 4236 return true; 4237 4238 return mlx5e_eswitch_rep(out_dev) && 4239 same_port_devs(priv, netdev_priv(out_dev)); 4240 } 4241 4242 int mlx5e_set_fwd_to_int_port_actions(struct mlx5e_priv *priv, 4243 struct mlx5_flow_attr *attr, 4244 int ifindex, 4245 enum mlx5e_tc_int_port_type type, 4246 u32 *action, 4247 int out_index) 4248 { 4249 struct mlx5_esw_flow_attr *esw_attr = attr->esw_attr; 4250 struct mlx5e_tc_int_port_priv *int_port_priv; 4251 struct mlx5e_tc_flow_parse_attr *parse_attr; 4252 struct mlx5e_tc_int_port *dest_int_port; 4253 int err; 4254 4255 parse_attr = attr->parse_attr; 4256 int_port_priv = mlx5e_get_int_port_priv(priv); 4257 4258 dest_int_port = mlx5e_tc_int_port_get(int_port_priv, ifindex, type); 4259 if (IS_ERR(dest_int_port)) 4260 return PTR_ERR(dest_int_port); 4261 4262 err = mlx5e_tc_match_to_reg_set(priv->mdev, &parse_attr->mod_hdr_acts, 4263 MLX5_FLOW_NAMESPACE_FDB, VPORT_TO_REG, 4264 mlx5e_tc_int_port_get_metadata(dest_int_port)); 4265 if (err) { 4266 mlx5e_tc_int_port_put(int_port_priv, dest_int_port); 4267 return err; 4268 } 4269 4270 *action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; 4271 4272 esw_attr->dest_int_port = dest_int_port; 4273 esw_attr->dests[out_index].flags |= MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE; 4274 esw_attr->split_count = out_index; 4275 4276 /* Forward to root fdb for matching against the new source vport */ 4277 attr->dest_chain = 0; 4278 4279 return 0; 4280 } 4281 4282 static int 4283 parse_tc_fdb_actions(struct mlx5e_priv *priv, 4284 struct flow_action *flow_action, 4285 struct mlx5e_tc_flow *flow, 4286 struct netlink_ext_ack *extack) 4287 { 4288 struct mlx5e_tc_act_parse_state *parse_state; 4289 struct mlx5e_tc_flow_parse_attr *parse_attr; 4290 struct mlx5_flow_attr *attr = flow->attr; 4291 struct mlx5_esw_flow_attr *esw_attr; 4292 struct net_device *filter_dev; 4293 int err; 4294 4295 err = flow_action_supported(flow_action, extack); 4296 if (err) 4297 return err; 4298 4299 esw_attr = attr->esw_attr; 4300 parse_attr = attr->parse_attr; 4301 filter_dev = parse_attr->filter_dev; 4302 parse_state = &parse_attr->parse_state; 4303 mlx5e_tc_act_init_parse_state(parse_state, flow, flow_action, extack); 4304 parse_state->ct_priv = get_ct_priv(priv); 4305 4306 err = parse_tc_actions(parse_state, flow_action); 4307 if (err) 4308 return err; 4309 4310 /* Forward to/from internal port can only have 1 dest */ 4311 if ((netif_is_ovs_master(filter_dev) || esw_attr->dest_int_port) && 4312 esw_attr->out_count > 1) { 4313 NL_SET_ERR_MSG_MOD(extack, 4314 "Rules with internal port can have only one destination"); 4315 return -EOPNOTSUPP; 4316 } 4317 4318 /* Forward from tunnel/internal port to internal port is not supported */ 4319 if ((mlx5e_get_tc_tun(filter_dev) || netif_is_ovs_master(filter_dev)) && 4320 esw_attr->dest_int_port) { 4321 NL_SET_ERR_MSG_MOD(extack, 4322 "Forwarding from tunnel/internal port to internal port is not supported"); 4323 return -EOPNOTSUPP; 4324 } 4325 4326 err = actions_prepare_mod_hdr_actions(priv, flow, attr, extack); 4327 if (err) 4328 return err; 4329 4330 if (!actions_match_supported(priv, flow_action, parse_state->actions, 4331 parse_attr, flow, extack)) 4332 return -EOPNOTSUPP; 4333 4334 return 0; 4335 } 4336 4337 static void get_flags(int flags, unsigned long *flow_flags) 4338 { 4339 unsigned long __flow_flags = 0; 4340 4341 if (flags & MLX5_TC_FLAG(INGRESS)) 4342 __flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_INGRESS); 4343 if (flags & MLX5_TC_FLAG(EGRESS)) 4344 __flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_EGRESS); 4345 4346 if (flags & MLX5_TC_FLAG(ESW_OFFLOAD)) 4347 __flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_ESWITCH); 4348 if (flags & MLX5_TC_FLAG(NIC_OFFLOAD)) 4349 __flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_NIC); 4350 if (flags & MLX5_TC_FLAG(FT_OFFLOAD)) 4351 __flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_FT); 4352 4353 *flow_flags = __flow_flags; 4354 } 4355 4356 static const struct rhashtable_params tc_ht_params = { 4357 .head_offset = offsetof(struct mlx5e_tc_flow, node), 4358 .key_offset = offsetof(struct mlx5e_tc_flow, cookie), 4359 .key_len = sizeof(((struct mlx5e_tc_flow *)0)->cookie), 4360 .automatic_shrinking = true, 4361 }; 4362 4363 static struct rhashtable *get_tc_ht(struct mlx5e_priv *priv, 4364 unsigned long flags) 4365 { 4366 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 4367 struct mlx5e_rep_priv *rpriv; 4368 4369 if (flags & MLX5_TC_FLAG(ESW_OFFLOAD)) { 4370 rpriv = priv->ppriv; 4371 return &rpriv->tc_ht; 4372 } else /* NIC offload */ 4373 return &tc->ht; 4374 } 4375 4376 static bool is_peer_flow_needed(struct mlx5e_tc_flow *flow, bool *is_sd) 4377 { 4378 struct mlx5_esw_flow_attr *esw_attr = flow->attr->esw_attr; 4379 struct mlx5_flow_attr *attr = flow->attr; 4380 bool is_rep_ingress = esw_attr->in_rep->vport != MLX5_VPORT_UPLINK && 4381 flow_flag_test(flow, INGRESS); 4382 bool act_is_encap = !!(attr->action & 4383 MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT); 4384 bool esw_paired = mlx5_devcom_comp_is_ready(esw_attr->in_mdev->priv.eswitch->devcom); 4385 4386 if (!esw_paired) 4387 return false; 4388 4389 if ((mlx5_lag_is_sriov(esw_attr->in_mdev) || 4390 mlx5_lag_is_multipath(esw_attr->in_mdev)) && 4391 (is_rep_ingress || act_is_encap)) 4392 return true; 4393 4394 if (mlx5_lag_is_mpesw(esw_attr->in_mdev)) 4395 return true; 4396 4397 if (mlx5_lag_is_sd(esw_attr->in_mdev) && 4398 !mlx5_sd_is_primary(esw_attr->in_mdev)) { 4399 if (!mlx5_lag_is_mpesw(mlx5_sd_get_primary(esw_attr->in_mdev))) 4400 *is_sd = true; 4401 return true; 4402 } 4403 4404 return false; 4405 } 4406 4407 struct mlx5_flow_attr * 4408 mlx5_alloc_flow_attr(enum mlx5_flow_namespace_type type) 4409 { 4410 u32 ex_attr_size = (type == MLX5_FLOW_NAMESPACE_FDB) ? 4411 sizeof(struct mlx5_esw_flow_attr) : 4412 sizeof(struct mlx5_nic_flow_attr); 4413 struct mlx5_flow_attr *attr; 4414 4415 attr = kzalloc(sizeof(*attr) + ex_attr_size, GFP_KERNEL); 4416 if (!attr) 4417 return attr; 4418 4419 INIT_LIST_HEAD(&attr->list); 4420 return attr; 4421 } 4422 4423 static void 4424 mlx5_free_flow_attr_actions(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr *attr) 4425 { 4426 struct mlx5_core_dev *counter_dev = get_flow_counter_dev(flow); 4427 struct mlx5_esw_flow_attr *esw_attr; 4428 4429 if (!attr) 4430 return; 4431 4432 if (attr->post_act_handle) 4433 mlx5e_tc_post_act_del(get_post_action(flow->priv), attr->post_act_handle); 4434 4435 mlx5e_tc_tun_encap_dests_unset(flow->priv, flow, attr); 4436 4437 if (attr->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) 4438 mlx5_fc_destroy(counter_dev, attr->counter); 4439 4440 if (attr->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR) { 4441 mlx5e_mod_hdr_dealloc(&attr->parse_attr->mod_hdr_acts); 4442 mlx5e_tc_detach_mod_hdr(flow->priv, flow, attr); 4443 } 4444 4445 if (mlx5e_is_eswitch_flow(flow)) { 4446 esw_attr = attr->esw_attr; 4447 4448 if (esw_attr->int_port) 4449 mlx5e_tc_int_port_put(mlx5e_get_int_port_priv(flow->priv), 4450 esw_attr->int_port); 4451 4452 if (esw_attr->dest_int_port) 4453 mlx5e_tc_int_port_put(mlx5e_get_int_port_priv(flow->priv), 4454 esw_attr->dest_int_port); 4455 } 4456 4457 mlx5_tc_ct_delete_flow(get_ct_priv(flow->priv), attr); 4458 4459 free_branch_attr(flow, attr->branch_true); 4460 free_branch_attr(flow, attr->branch_false); 4461 } 4462 4463 static int 4464 mlx5e_alloc_flow(struct mlx5e_priv *priv, int attr_size, 4465 struct flow_cls_offload *f, unsigned long flow_flags, 4466 struct mlx5e_tc_flow_parse_attr **__parse_attr, 4467 struct mlx5e_tc_flow **__flow) 4468 { 4469 struct mlx5e_tc_flow_parse_attr *parse_attr; 4470 struct mlx5_flow_attr *attr; 4471 struct mlx5e_tc_flow *flow; 4472 int err = -ENOMEM; 4473 int out_index; 4474 4475 flow = kzalloc_obj(*flow); 4476 parse_attr = kvzalloc_obj(*parse_attr); 4477 if (!parse_attr || !flow) 4478 goto err_free; 4479 4480 flow->flags = flow_flags; 4481 flow->cookie = f->cookie; 4482 flow->priv = priv; 4483 4484 attr = mlx5_alloc_flow_attr(mlx5e_get_flow_namespace(flow)); 4485 if (!attr) 4486 goto err_free; 4487 4488 flow->attr = attr; 4489 4490 for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) 4491 INIT_LIST_HEAD(&flow->encaps[out_index].list); 4492 INIT_LIST_HEAD(&flow->hairpin); 4493 INIT_LIST_HEAD(&flow->l3_to_l2_reformat); 4494 INIT_LIST_HEAD(&flow->attrs); 4495 INIT_LIST_HEAD(&flow->peer_flows); 4496 refcount_set(&flow->refcnt, 1); 4497 init_completion(&flow->init_done); 4498 init_completion(&flow->del_hw_done); 4499 4500 *__flow = flow; 4501 *__parse_attr = parse_attr; 4502 4503 return 0; 4504 4505 err_free: 4506 kfree(flow); 4507 kvfree(parse_attr); 4508 return err; 4509 } 4510 4511 static void 4512 mlx5e_flow_attr_init(struct mlx5_flow_attr *attr, 4513 struct mlx5e_tc_flow_parse_attr *parse_attr, 4514 struct flow_cls_offload *f) 4515 { 4516 attr->parse_attr = parse_attr; 4517 attr->chain = f->common.chain_index; 4518 attr->prio = f->common.prio; 4519 } 4520 4521 static void 4522 mlx5e_flow_esw_attr_init(struct mlx5_flow_attr *attr, 4523 struct mlx5e_priv *priv, 4524 struct mlx5e_tc_flow_parse_attr *parse_attr, 4525 struct flow_cls_offload *f, 4526 struct mlx5_eswitch_rep *in_rep, 4527 struct mlx5_core_dev *in_mdev) 4528 { 4529 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 4530 struct mlx5_esw_flow_attr *esw_attr = attr->esw_attr; 4531 4532 mlx5e_flow_attr_init(attr, parse_attr, f); 4533 4534 esw_attr->in_rep = in_rep; 4535 esw_attr->in_mdev = in_mdev; 4536 4537 if (MLX5_CAP_ESW(esw->dev, counter_eswitch_affinity) == 4538 MLX5_COUNTER_SOURCE_ESWITCH) 4539 esw_attr->counter_dev = in_mdev; 4540 else 4541 esw_attr->counter_dev = priv->mdev; 4542 } 4543 4544 static struct mlx5e_tc_flow * 4545 __mlx5e_add_fdb_flow(struct mlx5e_priv *priv, 4546 struct flow_cls_offload *f, 4547 unsigned long flow_flags, 4548 struct net_device *filter_dev, 4549 struct mlx5_eswitch_rep *in_rep, 4550 struct mlx5_core_dev *in_mdev) 4551 { 4552 struct flow_rule *rule = flow_cls_offload_flow_rule(f); 4553 struct netlink_ext_ack *extack = f->common.extack; 4554 struct mlx5e_tc_flow_parse_attr *parse_attr; 4555 struct mlx5e_tc_flow *flow; 4556 int attr_size, err; 4557 4558 flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_ESWITCH); 4559 attr_size = sizeof(struct mlx5_esw_flow_attr); 4560 err = mlx5e_alloc_flow(priv, attr_size, f, flow_flags, 4561 &parse_attr, &flow); 4562 if (err) 4563 goto out; 4564 4565 parse_attr->filter_dev = filter_dev; 4566 mlx5e_flow_esw_attr_init(flow->attr, 4567 priv, parse_attr, 4568 f, in_rep, in_mdev); 4569 4570 err = parse_cls_flower(flow->priv, flow, &parse_attr->spec, 4571 f, filter_dev); 4572 if (err) 4573 goto err_free; 4574 4575 /* actions validation depends on parsing the ct matches first */ 4576 err = mlx5_tc_ct_match_add(get_ct_priv(priv), &parse_attr->spec, f, 4577 &flow->attr->ct_attr, extack); 4578 if (err) 4579 goto err_free; 4580 4581 err = parse_tc_fdb_actions(priv, &rule->action, flow, extack); 4582 if (err) 4583 goto err_free; 4584 4585 err = mlx5e_tc_add_fdb_flow(priv, flow, extack); 4586 complete_all(&flow->init_done); 4587 if (err) { 4588 if (!(err == -ENETUNREACH && mlx5_lag_is_multipath(in_mdev))) 4589 goto err_free; 4590 4591 add_unready_flow(flow); 4592 } 4593 4594 return flow; 4595 4596 err_free: 4597 mlx5e_flow_put(priv, flow); 4598 out: 4599 return ERR_PTR(err); 4600 } 4601 4602 static int mlx5e_tc_add_fdb_peer_flow(struct flow_cls_offload *f, 4603 struct mlx5e_tc_flow *flow, 4604 unsigned long flow_flags, 4605 struct mlx5_eswitch *peer_esw) 4606 { 4607 u16 peer_vhca_id = MLX5_CAP_GEN(peer_esw->dev, vhca_id); 4608 struct mlx5e_priv *priv = flow->priv, *peer_priv; 4609 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 4610 struct mlx5_esw_flow_attr *attr = flow->attr->esw_attr; 4611 struct mlx5e_tc_flow_parse_attr *parse_attr; 4612 struct mlx5e_rep_priv *peer_urpriv; 4613 struct list_head *dup_peer_flows; 4614 struct mlx5e_tc_flow *peer_flow; 4615 struct mlx5_core_dev *in_mdev; 4616 int err = 0; 4617 4618 peer_urpriv = mlx5_eswitch_get_uplink_priv(peer_esw, REP_ETH); 4619 peer_priv = netdev_priv(peer_urpriv->netdev); 4620 4621 /* in_mdev is assigned of which the packet originated from. 4622 * So packets redirected to uplink use the same mdev of the 4623 * original flow and packets redirected from uplink use the 4624 * peer mdev. 4625 * In multiport eswitch it's a special case that we need to 4626 * keep the original mdev. 4627 */ 4628 if (attr->in_rep->vport == MLX5_VPORT_UPLINK && !mlx5_lag_is_mpesw(priv->mdev)) 4629 in_mdev = peer_priv->mdev; 4630 else 4631 in_mdev = priv->mdev; 4632 4633 flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_PEER); 4634 parse_attr = flow->attr->parse_attr; 4635 peer_flow = __mlx5e_add_fdb_flow(peer_priv, f, flow_flags, 4636 parse_attr->filter_dev, 4637 attr->in_rep, in_mdev); 4638 if (IS_ERR(peer_flow)) { 4639 err = PTR_ERR(peer_flow); 4640 goto out; 4641 } 4642 4643 peer_flow->peer_orig = flow; 4644 list_add_tail(&peer_flow->peer_flows, &flow->peer_flows); 4645 flow_flag_set(flow, DUP); 4646 dup_peer_flows = xa_load(&esw->offloads.peer_flows, peer_vhca_id); 4647 if (!dup_peer_flows) 4648 return -ENODEV; 4649 mutex_lock(&esw->offloads.peer_mutex); 4650 list_add_tail(&peer_flow->peer, dup_peer_flows); 4651 mutex_unlock(&esw->offloads.peer_mutex); 4652 4653 out: 4654 return err; 4655 } 4656 4657 static int 4658 mlx5e_add_fdb_flow(struct mlx5e_priv *priv, 4659 struct flow_cls_offload *f, 4660 unsigned long flow_flags, 4661 struct net_device *filter_dev, 4662 struct mlx5e_tc_flow **__flow) 4663 { 4664 struct mlx5_devcom_comp_dev *devcom = priv->mdev->priv.eswitch->devcom, *pos; 4665 struct netlink_ext_ack *extack = f->common.extack; 4666 struct mlx5e_rep_priv *rpriv = priv->ppriv; 4667 struct mlx5_eswitch_rep *in_rep = rpriv->rep; 4668 struct mlx5_core_dev *in_mdev = priv->mdev; 4669 struct mlx5_eswitch *peer_esw; 4670 struct mlx5e_tc_flow *flow; 4671 bool is_sd = false; 4672 int err; 4673 4674 if (mlx5_lag_is_sd(in_mdev) && !mlx5_lag_is_active(in_mdev)) { 4675 NL_SET_ERR_MSG_MOD(extack, "SD shared FDB not yet active"); 4676 return -EOPNOTSUPP; 4677 } 4678 4679 flow = __mlx5e_add_fdb_flow(priv, f, flow_flags, filter_dev, in_rep, 4680 in_mdev); 4681 if (IS_ERR(flow)) 4682 return PTR_ERR(flow); 4683 4684 if (!is_peer_flow_needed(flow, &is_sd)) { 4685 *__flow = flow; 4686 return 0; 4687 } 4688 4689 if (!mlx5_devcom_for_each_peer_begin(devcom)) { 4690 err = -ENODEV; 4691 goto clean_flow; 4692 } 4693 4694 mlx5_devcom_for_each_peer_entry(devcom, peer_esw, pos) { 4695 if (is_sd) { 4696 /* SD shared FDB: only the matching SD primary. */ 4697 if (mlx5_sd_get_primary(in_mdev) != 4698 mlx5_sd_get_primary(peer_esw->dev)) 4699 continue; 4700 } else { 4701 if (!mlx5_sd_is_primary(peer_esw->dev)) 4702 continue; 4703 } 4704 err = mlx5e_tc_add_fdb_peer_flow(f, flow, flow_flags, peer_esw); 4705 if (err) 4706 goto peer_clean; 4707 } 4708 4709 mlx5_devcom_for_each_peer_end(devcom); 4710 4711 *__flow = flow; 4712 return 0; 4713 4714 peer_clean: 4715 mlx5e_tc_del_fdb_peers_flow(flow); 4716 mlx5_devcom_for_each_peer_end(devcom); 4717 clean_flow: 4718 mlx5e_tc_del_fdb_flow(priv, flow); 4719 return err; 4720 } 4721 4722 static int 4723 mlx5e_add_nic_flow(struct mlx5e_priv *priv, 4724 struct flow_cls_offload *f, 4725 unsigned long flow_flags, 4726 struct net_device *filter_dev, 4727 struct mlx5e_tc_flow **__flow) 4728 { 4729 struct flow_rule *rule = flow_cls_offload_flow_rule(f); 4730 struct netlink_ext_ack *extack = f->common.extack; 4731 struct mlx5e_tc_flow_parse_attr *parse_attr; 4732 struct mlx5e_tc_flow *flow; 4733 int attr_size, err; 4734 4735 if (!MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ignore_flow_level)) { 4736 if (!tc_cls_can_offload_and_chain0(priv->netdev, &f->common)) 4737 return -EOPNOTSUPP; 4738 } else if (!tc_can_offload_extack(priv->netdev, f->common.extack)) { 4739 return -EOPNOTSUPP; 4740 } 4741 4742 flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_NIC); 4743 attr_size = sizeof(struct mlx5_nic_flow_attr); 4744 err = mlx5e_alloc_flow(priv, attr_size, f, flow_flags, 4745 &parse_attr, &flow); 4746 if (err) 4747 goto out; 4748 4749 parse_attr->filter_dev = filter_dev; 4750 mlx5e_flow_attr_init(flow->attr, parse_attr, f); 4751 4752 err = parse_cls_flower(flow->priv, flow, &parse_attr->spec, 4753 f, filter_dev); 4754 if (err) 4755 goto err_free; 4756 4757 err = mlx5_tc_ct_match_add(get_ct_priv(priv), &parse_attr->spec, f, 4758 &flow->attr->ct_attr, extack); 4759 if (err) 4760 goto err_free; 4761 4762 err = parse_tc_nic_actions(priv, &rule->action, flow, extack); 4763 if (err) 4764 goto err_free; 4765 4766 err = mlx5e_tc_add_nic_flow(priv, flow, extack); 4767 if (err) 4768 goto err_free; 4769 4770 mlx5e_tc_free_parse_attr(flow->attr); 4771 flow_flag_set(flow, OFFLOADED); 4772 *__flow = flow; 4773 4774 return 0; 4775 4776 err_free: 4777 flow_flag_set(flow, FAILED); 4778 mlx5e_flow_put(priv, flow); 4779 out: 4780 return err; 4781 } 4782 4783 static int 4784 mlx5e_tc_add_flow(struct mlx5e_priv *priv, 4785 struct flow_cls_offload *f, 4786 unsigned long flags, 4787 struct net_device *filter_dev, 4788 struct mlx5e_tc_flow **flow) 4789 { 4790 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 4791 unsigned long flow_flags; 4792 int err; 4793 4794 get_flags(flags, &flow_flags); 4795 4796 if (!tc_can_offload_extack(priv->netdev, f->common.extack)) 4797 return -EOPNOTSUPP; 4798 4799 if (esw && esw->mode == MLX5_ESWITCH_OFFLOADS) 4800 err = mlx5e_add_fdb_flow(priv, f, flow_flags, 4801 filter_dev, flow); 4802 else 4803 err = mlx5e_add_nic_flow(priv, f, flow_flags, 4804 filter_dev, flow); 4805 4806 return err; 4807 } 4808 4809 static bool is_flow_rule_duplicate_allowed(struct net_device *dev, 4810 struct mlx5e_rep_priv *rpriv) 4811 { 4812 /* Offloaded flow rule is allowed to duplicate on non-uplink representor 4813 * sharing tc block with other slaves of a lag device. Rpriv can be NULL if this 4814 * function is called from NIC mode. 4815 */ 4816 return netif_is_lag_port(dev) && rpriv && rpriv->rep->vport != MLX5_VPORT_UPLINK; 4817 } 4818 4819 /* As IPsec and TC order is not aligned between software and hardware-offload, 4820 * either IPsec offload or TC offload, not both, is allowed for a specific interface. 4821 */ 4822 static bool is_tc_ipsec_order_check_needed(struct net_device *filter, struct mlx5e_priv *priv) 4823 { 4824 if (!IS_ENABLED(CONFIG_MLX5_EN_IPSEC)) 4825 return false; 4826 4827 if (filter != priv->netdev) 4828 return false; 4829 4830 if (mlx5e_eswitch_vf_rep(priv->netdev)) 4831 return false; 4832 4833 return true; 4834 } 4835 4836 static int mlx5e_tc_block_ipsec_offload(struct net_device *filter, struct mlx5e_priv *priv) 4837 { 4838 struct mlx5_core_dev *mdev = priv->mdev; 4839 4840 if (!is_tc_ipsec_order_check_needed(filter, priv)) 4841 return 0; 4842 4843 if (mdev->num_block_tc) 4844 return -EBUSY; 4845 4846 mdev->num_block_ipsec++; 4847 4848 return 0; 4849 } 4850 4851 static void mlx5e_tc_unblock_ipsec_offload(struct net_device *filter, struct mlx5e_priv *priv) 4852 { 4853 if (!is_tc_ipsec_order_check_needed(filter, priv)) 4854 return; 4855 4856 priv->mdev->num_block_ipsec--; 4857 } 4858 4859 int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv, 4860 struct flow_cls_offload *f, unsigned long flags) 4861 { 4862 struct netlink_ext_ack *extack = f->common.extack; 4863 struct rhashtable *tc_ht = get_tc_ht(priv, flags); 4864 struct mlx5e_rep_priv *rpriv = priv->ppriv; 4865 struct mlx5e_tc_flow *flow; 4866 int err = 0; 4867 4868 if (!mlx5_esw_hold(priv->mdev)) 4869 return -EBUSY; 4870 4871 err = mlx5e_tc_block_ipsec_offload(dev, priv); 4872 if (err) 4873 goto esw_release; 4874 4875 mlx5_esw_get(priv->mdev); 4876 4877 rcu_read_lock(); 4878 flow = rhashtable_lookup(tc_ht, &f->cookie, tc_ht_params); 4879 if (flow) { 4880 /* Same flow rule offloaded to non-uplink representor sharing tc block, 4881 * just return 0. 4882 */ 4883 if (is_flow_rule_duplicate_allowed(dev, rpriv) && flow->orig_dev != dev) 4884 goto rcu_unlock; 4885 4886 NL_SET_ERR_MSG_MOD(extack, 4887 "flow cookie already exists, ignoring"); 4888 netdev_warn_once(priv->netdev, 4889 "flow cookie %lx already exists, ignoring\n", 4890 f->cookie); 4891 err = -EEXIST; 4892 goto rcu_unlock; 4893 } 4894 rcu_unlock: 4895 rcu_read_unlock(); 4896 if (flow) 4897 goto out; 4898 4899 trace_mlx5e_configure_flower(f); 4900 err = mlx5e_tc_add_flow(priv, f, flags, dev, &flow); 4901 if (err) 4902 goto out; 4903 4904 /* Flow rule offloaded to non-uplink representor sharing tc block, 4905 * set the flow's owner dev. 4906 */ 4907 if (is_flow_rule_duplicate_allowed(dev, rpriv)) 4908 flow->orig_dev = dev; 4909 4910 err = rhashtable_lookup_insert_fast(tc_ht, &flow->node, tc_ht_params); 4911 if (err) 4912 goto err_free; 4913 4914 mlx5_esw_release(priv->mdev); 4915 return 0; 4916 4917 err_free: 4918 mlx5e_flow_put(priv, flow); 4919 out: 4920 mlx5e_tc_unblock_ipsec_offload(dev, priv); 4921 mlx5_esw_put(priv->mdev); 4922 esw_release: 4923 mlx5_esw_release(priv->mdev); 4924 return err; 4925 } 4926 4927 static bool same_flow_direction(struct mlx5e_tc_flow *flow, int flags) 4928 { 4929 bool dir_ingress = !!(flags & MLX5_TC_FLAG(INGRESS)); 4930 bool dir_egress = !!(flags & MLX5_TC_FLAG(EGRESS)); 4931 4932 return flow_flag_test(flow, INGRESS) == dir_ingress && 4933 flow_flag_test(flow, EGRESS) == dir_egress; 4934 } 4935 4936 int mlx5e_delete_flower(struct net_device *dev, struct mlx5e_priv *priv, 4937 struct flow_cls_offload *f, unsigned long flags) 4938 { 4939 struct rhashtable *tc_ht = get_tc_ht(priv, flags); 4940 struct mlx5e_tc_flow *flow; 4941 int err; 4942 4943 rcu_read_lock(); 4944 flow = rhashtable_lookup(tc_ht, &f->cookie, tc_ht_params); 4945 if (!flow || !same_flow_direction(flow, flags)) { 4946 err = -EINVAL; 4947 goto errout; 4948 } 4949 4950 /* Only delete the flow if it doesn't have MLX5E_TC_FLOW_DELETED flag 4951 * set. 4952 */ 4953 if (flow_flag_test_and_set(flow, DELETED)) { 4954 err = -EINVAL; 4955 goto errout; 4956 } 4957 rhashtable_remove_fast(tc_ht, &flow->node, tc_ht_params); 4958 rcu_read_unlock(); 4959 4960 trace_mlx5e_delete_flower(f); 4961 mlx5e_flow_put(priv, flow); 4962 4963 mlx5e_tc_unblock_ipsec_offload(dev, priv); 4964 mlx5_esw_put(priv->mdev); 4965 return 0; 4966 4967 errout: 4968 rcu_read_unlock(); 4969 return err; 4970 } 4971 4972 int mlx5e_tc_fill_action_stats(struct mlx5e_priv *priv, 4973 struct flow_offload_action *fl_act) 4974 { 4975 return mlx5e_tc_act_stats_fill_stats(get_act_stats_handle(priv), fl_act); 4976 } 4977 4978 int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv, 4979 struct flow_cls_offload *f, unsigned long flags) 4980 { 4981 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 4982 struct rhashtable *tc_ht = get_tc_ht(priv, flags); 4983 struct mlx5e_tc_flow *flow; 4984 struct mlx5_fc *counter; 4985 u64 lastuse = 0; 4986 u64 packets = 0; 4987 u64 bytes = 0; 4988 int err = 0; 4989 4990 rcu_read_lock(); 4991 flow = mlx5e_flow_get(rhashtable_lookup(tc_ht, &f->cookie, 4992 tc_ht_params)); 4993 rcu_read_unlock(); 4994 if (IS_ERR(flow)) 4995 return PTR_ERR(flow); 4996 4997 if (!same_flow_direction(flow, flags)) { 4998 err = -EINVAL; 4999 goto errout; 5000 } 5001 5002 if (mlx5e_is_offloaded_flow(flow)) { 5003 if (flow_flag_test(flow, USE_ACT_STATS)) { 5004 f->use_act_stats = true; 5005 } else { 5006 counter = mlx5e_tc_get_counter(flow); 5007 if (!counter) 5008 goto errout; 5009 5010 mlx5_fc_query_cached(counter, &bytes, &packets, &lastuse); 5011 } 5012 } 5013 5014 /* Under multipath it's possible for one rule to be currently 5015 * un-offloaded while the other rule is offloaded. 5016 */ 5017 if (esw && !mlx5_devcom_for_each_peer_begin(esw->devcom)) 5018 goto out; 5019 5020 if (flow_flag_test(flow, DUP)) { 5021 struct mlx5e_tc_flow *peer_flow; 5022 5023 list_for_each_entry(peer_flow, &flow->peer_flows, peer_flows) { 5024 u64 packets2; 5025 u64 lastuse2; 5026 u64 bytes2; 5027 5028 if (!flow_flag_test(peer_flow, OFFLOADED)) 5029 continue; 5030 if (flow_flag_test(flow, USE_ACT_STATS)) { 5031 f->use_act_stats = true; 5032 break; 5033 } 5034 5035 counter = mlx5e_tc_get_counter(peer_flow); 5036 if (!counter) 5037 goto no_peer_counter; 5038 mlx5_fc_query_cached(counter, &bytes2, &packets2, 5039 &lastuse2); 5040 5041 bytes += bytes2; 5042 packets += packets2; 5043 lastuse = max_t(u64, lastuse, lastuse2); 5044 } 5045 } 5046 5047 no_peer_counter: 5048 if (esw) 5049 mlx5_devcom_for_each_peer_end(esw->devcom); 5050 out: 5051 flow_stats_update(&f->stats, bytes, packets, 0, lastuse, 5052 FLOW_ACTION_HW_STATS_DELAYED); 5053 trace_mlx5e_stats_flower(f); 5054 errout: 5055 mlx5e_flow_put(priv, flow); 5056 return err; 5057 } 5058 5059 static int apply_police_params(struct mlx5e_priv *priv, u64 rate, 5060 struct netlink_ext_ack *extack) 5061 { 5062 struct mlx5e_rep_priv *rpriv = priv->ppriv; 5063 struct mlx5_eswitch *esw; 5064 u32 rate_mbps = 0; 5065 u16 vport_num; 5066 int err; 5067 5068 vport_num = rpriv->rep->vport; 5069 if (vport_num >= MLX5_VPORT_ECPF) { 5070 NL_SET_ERR_MSG_MOD(extack, 5071 "Ingress rate limit is supported only for Eswitch ports connected to VFs"); 5072 return -EOPNOTSUPP; 5073 } 5074 5075 esw = priv->mdev->priv.eswitch; 5076 /* rate is given in bytes/sec. 5077 * First convert to bits/sec and then round to the nearest mbit/secs. 5078 * mbit means million bits. 5079 * Moreover, if rate is non zero we choose to configure to a minimum of 5080 * 1 mbit/sec. 5081 */ 5082 if (rate) { 5083 rate = (rate * BITS_PER_BYTE) + 500000; 5084 do_div(rate, 1000000); 5085 rate_mbps = max_t(u32, rate, 1); 5086 } 5087 5088 err = mlx5_esw_qos_modify_vport_rate(esw, vport_num, rate_mbps); 5089 if (err) 5090 NL_SET_ERR_MSG_MOD(extack, "failed applying action to hardware"); 5091 5092 return err; 5093 } 5094 5095 static int 5096 tc_matchall_police_validate(const struct flow_action *action, 5097 const struct flow_action_entry *act, 5098 struct netlink_ext_ack *extack) 5099 { 5100 if (act->police.notexceed.act_id != FLOW_ACTION_CONTINUE) { 5101 NL_SET_ERR_MSG_MOD(extack, 5102 "Offload not supported when conform action is not continue"); 5103 return -EOPNOTSUPP; 5104 } 5105 5106 if (act->police.exceed.act_id != FLOW_ACTION_DROP) { 5107 NL_SET_ERR_MSG_MOD(extack, 5108 "Offload not supported when exceed action is not drop"); 5109 return -EOPNOTSUPP; 5110 } 5111 5112 if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT && 5113 !flow_action_is_last_entry(action, act)) { 5114 NL_SET_ERR_MSG_MOD(extack, 5115 "Offload not supported when conform action is ok, but action is not last"); 5116 return -EOPNOTSUPP; 5117 } 5118 5119 if (act->police.peakrate_bytes_ps || 5120 act->police.avrate || act->police.overhead) { 5121 NL_SET_ERR_MSG_MOD(extack, 5122 "Offload not supported when peakrate/avrate/overhead is configured"); 5123 return -EOPNOTSUPP; 5124 } 5125 5126 return 0; 5127 } 5128 5129 static int scan_tc_matchall_fdb_actions(struct mlx5e_priv *priv, 5130 struct flow_action *flow_action, 5131 struct netlink_ext_ack *extack) 5132 { 5133 struct mlx5e_rep_priv *rpriv = priv->ppriv; 5134 const struct flow_action_entry *act; 5135 int err; 5136 int i; 5137 5138 if (!flow_action_has_entries(flow_action)) { 5139 NL_SET_ERR_MSG_MOD(extack, "matchall called with no action"); 5140 return -EINVAL; 5141 } 5142 5143 if (!flow_offload_has_one_action(flow_action)) { 5144 NL_SET_ERR_MSG_MOD(extack, "matchall policing support only a single action"); 5145 return -EOPNOTSUPP; 5146 } 5147 5148 if (!flow_action_basic_hw_stats_check(flow_action, extack)) { 5149 NL_SET_ERR_MSG_MOD(extack, "Flow action HW stats type is not supported"); 5150 return -EOPNOTSUPP; 5151 } 5152 5153 flow_action_for_each(i, act, flow_action) { 5154 switch (act->id) { 5155 case FLOW_ACTION_POLICE: 5156 err = tc_matchall_police_validate(flow_action, act, extack); 5157 if (err) 5158 return err; 5159 5160 err = apply_police_params(priv, act->police.rate_bytes_ps, extack); 5161 if (err) 5162 return err; 5163 5164 mlx5e_stats_copy_rep_stats(&rpriv->prev_vf_vport_stats, 5165 &priv->stats.rep_stats); 5166 break; 5167 default: 5168 NL_SET_ERR_MSG_MOD(extack, "mlx5 supports only police action for matchall"); 5169 return -EOPNOTSUPP; 5170 } 5171 } 5172 5173 return 0; 5174 } 5175 5176 int mlx5e_tc_configure_matchall(struct mlx5e_priv *priv, 5177 struct tc_cls_matchall_offload *ma) 5178 { 5179 struct netlink_ext_ack *extack = ma->common.extack; 5180 5181 if (ma->common.prio != 1) { 5182 NL_SET_ERR_MSG_MOD(extack, "only priority 1 is supported"); 5183 return -EINVAL; 5184 } 5185 5186 return scan_tc_matchall_fdb_actions(priv, &ma->rule->action, extack); 5187 } 5188 5189 int mlx5e_tc_delete_matchall(struct mlx5e_priv *priv, 5190 struct tc_cls_matchall_offload *ma) 5191 { 5192 struct netlink_ext_ack *extack = ma->common.extack; 5193 5194 return apply_police_params(priv, 0, extack); 5195 } 5196 5197 static void mlx5e_tc_hairpin_update_dead_peer(struct mlx5e_priv *priv, 5198 struct mlx5e_priv *peer_priv) 5199 { 5200 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 5201 struct mlx5_core_dev *peer_mdev = peer_priv->mdev; 5202 struct mlx5e_hairpin_entry *hpe, *tmp; 5203 LIST_HEAD(init_wait_list); 5204 u16 peer_vhca_id; 5205 int bkt; 5206 5207 if (!mlx5e_same_hw_devs(priv, peer_priv)) 5208 return; 5209 5210 peer_vhca_id = MLX5_CAP_GEN(peer_mdev, vhca_id); 5211 5212 mutex_lock(&tc->hairpin_tbl_lock); 5213 hash_for_each(tc->hairpin_tbl, bkt, hpe, hairpin_hlist) 5214 if (refcount_inc_not_zero(&hpe->refcnt)) 5215 list_add(&hpe->dead_peer_wait_list, &init_wait_list); 5216 mutex_unlock(&tc->hairpin_tbl_lock); 5217 5218 list_for_each_entry_safe(hpe, tmp, &init_wait_list, dead_peer_wait_list) { 5219 wait_for_completion(&hpe->res_ready); 5220 if (!IS_ERR_OR_NULL(hpe->hp) && hpe->peer_vhca_id == peer_vhca_id) 5221 mlx5_core_hairpin_clear_dead_peer(hpe->hp->pair); 5222 5223 mlx5e_hairpin_put(priv, hpe); 5224 } 5225 } 5226 5227 static int mlx5e_tc_netdev_event(struct notifier_block *this, 5228 unsigned long event, void *ptr) 5229 { 5230 struct net_device *ndev = netdev_notifier_info_to_dev(ptr); 5231 struct mlx5e_priv *peer_priv; 5232 struct mlx5e_tc_table *tc; 5233 struct mlx5e_priv *priv; 5234 5235 if (ndev->netdev_ops != &mlx5e_netdev_ops || 5236 event != NETDEV_UNREGISTER || 5237 ndev->reg_state == NETREG_REGISTERED) 5238 return NOTIFY_DONE; 5239 5240 tc = container_of(this, struct mlx5e_tc_table, netdevice_nb); 5241 priv = tc->priv; 5242 peer_priv = netdev_priv(ndev); 5243 if (priv == peer_priv || 5244 !(priv->netdev->features & NETIF_F_HW_TC)) 5245 return NOTIFY_DONE; 5246 5247 mlx5e_tc_hairpin_update_dead_peer(priv, peer_priv); 5248 5249 return NOTIFY_DONE; 5250 } 5251 5252 static int mlx5e_tc_nic_create_miss_table(struct mlx5e_priv *priv) 5253 { 5254 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 5255 struct mlx5_flow_table **ft = &tc->miss_t; 5256 struct mlx5_flow_table_attr ft_attr = {}; 5257 struct mlx5_flow_namespace *ns; 5258 int err = 0; 5259 5260 ft_attr.max_fte = 1; 5261 ft_attr.autogroup.max_num_groups = 1; 5262 ft_attr.level = MLX5E_TC_MISS_LEVEL; 5263 ft_attr.prio = 0; 5264 ns = mlx5_get_flow_namespace(priv->mdev, MLX5_FLOW_NAMESPACE_KERNEL); 5265 5266 *ft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr); 5267 if (IS_ERR(*ft)) { 5268 err = PTR_ERR(*ft); 5269 netdev_err(priv->netdev, "failed to create tc nic miss table err=%d\n", err); 5270 } 5271 5272 return err; 5273 } 5274 5275 static void mlx5e_tc_nic_destroy_miss_table(struct mlx5e_priv *priv) 5276 { 5277 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 5278 5279 mlx5_destroy_flow_table(tc->miss_t); 5280 } 5281 5282 int mlx5e_tc_nic_init(struct mlx5e_priv *priv) 5283 { 5284 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 5285 u8 mapping_id[MLX5_SW_IMAGE_GUID_MAX_BYTES]; 5286 struct mlx5_core_dev *dev = priv->mdev; 5287 struct mapping_ctx *chains_mapping; 5288 struct mlx5_chains_attr attr = {}; 5289 u8 id_len; 5290 int err; 5291 5292 mlx5e_mod_hdr_tbl_init(&tc->mod_hdr); 5293 mutex_init(&tc->t_lock); 5294 mutex_init(&tc->hairpin_tbl_lock); 5295 hash_init(tc->hairpin_tbl); 5296 tc->priv = priv; 5297 5298 err = rhashtable_init(&tc->ht, &tc_ht_params); 5299 if (err) 5300 return err; 5301 5302 lockdep_set_class(&tc->ht.mutex, &tc_ht_lock_key); 5303 lockdep_init_map(&tc->ht.run_work.lockdep_map, "tc_ht_wq_key", &tc_ht_wq_key, 0); 5304 5305 mlx5_query_nic_sw_system_image_guid(dev, mapping_id, &id_len); 5306 5307 chains_mapping = mapping_create_for_id(mapping_id, id_len, 5308 MAPPING_TYPE_CHAIN, 5309 sizeof(struct mlx5_mapped_obj), 5310 MLX5E_TC_TABLE_CHAIN_TAG_MASK, 5311 true); 5312 5313 if (IS_ERR(chains_mapping)) { 5314 err = PTR_ERR(chains_mapping); 5315 goto err_mapping; 5316 } 5317 tc->mapping = chains_mapping; 5318 5319 err = mlx5e_tc_nic_create_miss_table(priv); 5320 if (err) 5321 goto err_chains; 5322 5323 if (MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ignore_flow_level)) 5324 attr.flags = MLX5_CHAINS_AND_PRIOS_SUPPORTED | 5325 MLX5_CHAINS_IGNORE_FLOW_LEVEL_SUPPORTED; 5326 attr.ns = MLX5_FLOW_NAMESPACE_KERNEL; 5327 attr.max_grp_num = MLX5E_TC_TABLE_NUM_GROUPS; 5328 attr.default_ft = tc->miss_t; 5329 attr.mapping = chains_mapping; 5330 attr.fs_base_prio = MLX5E_TC_PRIO; 5331 5332 tc->chains = mlx5_chains_create(dev, &attr); 5333 if (IS_ERR(tc->chains)) { 5334 err = PTR_ERR(tc->chains); 5335 goto err_miss; 5336 } 5337 5338 mlx5_chains_print_info(tc->chains); 5339 5340 tc->post_act = mlx5e_tc_post_act_init(priv, tc->chains, MLX5_FLOW_NAMESPACE_KERNEL); 5341 tc->ct = mlx5_tc_ct_init(priv, tc->chains, &tc->mod_hdr, 5342 MLX5_FLOW_NAMESPACE_KERNEL, tc->post_act); 5343 5344 tc->netdevice_nb.notifier_call = mlx5e_tc_netdev_event; 5345 err = register_netdevice_notifier_dev_net(priv->netdev, 5346 &tc->netdevice_nb, 5347 &tc->netdevice_nn); 5348 if (err) { 5349 tc->netdevice_nb.notifier_call = NULL; 5350 mlx5_core_warn(priv->mdev, "Failed to register netdev notifier\n"); 5351 goto err_reg; 5352 } 5353 5354 mlx5e_tc_debugfs_init(tc, mlx5e_fs_get_debugfs_root(priv->fs)); 5355 5356 tc->action_stats_handle = mlx5e_tc_act_stats_create(); 5357 if (IS_ERR(tc->action_stats_handle)) { 5358 err = PTR_ERR(tc->action_stats_handle); 5359 goto err_act_stats; 5360 } 5361 5362 return 0; 5363 5364 err_act_stats: 5365 unregister_netdevice_notifier_dev_net(priv->netdev, 5366 &tc->netdevice_nb, 5367 &tc->netdevice_nn); 5368 err_reg: 5369 mlx5_tc_ct_clean(tc->ct); 5370 mlx5e_tc_post_act_destroy(tc->post_act); 5371 mlx5_chains_destroy(tc->chains); 5372 err_miss: 5373 mlx5e_tc_nic_destroy_miss_table(priv); 5374 err_chains: 5375 mapping_destroy(chains_mapping); 5376 err_mapping: 5377 rhashtable_destroy(&tc->ht); 5378 return err; 5379 } 5380 5381 static void _mlx5e_tc_del_flow(void *ptr, void *arg) 5382 { 5383 struct mlx5e_tc_flow *flow = ptr; 5384 struct mlx5e_priv *priv = flow->priv; 5385 5386 mlx5e_tc_del_flow(priv, flow); 5387 kfree(flow); 5388 } 5389 5390 void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv) 5391 { 5392 struct mlx5e_tc_table *tc = mlx5e_fs_get_tc(priv->fs); 5393 5394 debugfs_remove_recursive(tc->dfs_root); 5395 5396 if (tc->netdevice_nb.notifier_call) 5397 unregister_netdevice_notifier_dev_net(priv->netdev, 5398 &tc->netdevice_nb, 5399 &tc->netdevice_nn); 5400 5401 mlx5e_mod_hdr_tbl_destroy(&tc->mod_hdr); 5402 mutex_destroy(&tc->hairpin_tbl_lock); 5403 5404 rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, NULL); 5405 5406 if (!IS_ERR_OR_NULL(tc->t)) { 5407 mlx5_chains_put_table(tc->chains, 0, 1, MLX5E_TC_FT_LEVEL); 5408 tc->t = NULL; 5409 } 5410 mutex_destroy(&tc->t_lock); 5411 5412 mlx5_tc_ct_clean(tc->ct); 5413 mlx5e_tc_post_act_destroy(tc->post_act); 5414 mapping_destroy(tc->mapping); 5415 mlx5_chains_destroy(tc->chains); 5416 mlx5e_tc_nic_destroy_miss_table(priv); 5417 mlx5e_tc_act_stats_free(tc->action_stats_handle); 5418 } 5419 5420 int mlx5e_tc_ht_init(struct rhashtable *tc_ht) 5421 { 5422 int err; 5423 5424 err = rhashtable_init(tc_ht, &tc_ht_params); 5425 if (err) 5426 return err; 5427 5428 lockdep_set_class(&tc_ht->mutex, &tc_ht_lock_key); 5429 lockdep_init_map(&tc_ht->run_work.lockdep_map, "tc_ht_wq_key", &tc_ht_wq_key, 0); 5430 5431 return 0; 5432 } 5433 5434 void mlx5e_tc_ht_cleanup(struct rhashtable *tc_ht) 5435 { 5436 rhashtable_free_and_destroy(tc_ht, _mlx5e_tc_del_flow, NULL); 5437 } 5438 5439 int mlx5e_tc_esw_init(struct mlx5_rep_uplink_priv *uplink_priv) 5440 { 5441 const size_t sz_enc_opts = sizeof(struct tunnel_match_enc_opts); 5442 u8 mapping_id[MLX5_SW_IMAGE_GUID_MAX_BYTES]; 5443 struct mlx5e_rep_priv *rpriv; 5444 struct mapping_ctx *mapping; 5445 struct mlx5_eswitch *esw; 5446 struct mlx5e_priv *priv; 5447 int err = 0; 5448 u8 id_len; 5449 5450 rpriv = container_of(uplink_priv, struct mlx5e_rep_priv, uplink_priv); 5451 priv = netdev_priv(rpriv->netdev); 5452 esw = priv->mdev->priv.eswitch; 5453 5454 uplink_priv->post_act = mlx5e_tc_post_act_init(priv, esw_chains(esw), 5455 MLX5_FLOW_NAMESPACE_FDB); 5456 uplink_priv->ct_priv = mlx5_tc_ct_init(netdev_priv(priv->netdev), 5457 esw_chains(esw), 5458 &esw->offloads.mod_hdr, 5459 MLX5_FLOW_NAMESPACE_FDB, 5460 uplink_priv->post_act); 5461 5462 uplink_priv->int_port_priv = mlx5e_tc_int_port_init(netdev_priv(priv->netdev)); 5463 5464 uplink_priv->tc_psample = mlx5e_tc_sample_init(esw, uplink_priv->post_act); 5465 5466 mlx5_query_nic_sw_system_image_guid(esw->dev, mapping_id, &id_len); 5467 5468 mapping = mapping_create_for_id(mapping_id, id_len, MAPPING_TYPE_TUNNEL, 5469 sizeof(struct tunnel_match_key), 5470 TUNNEL_INFO_BITS_MASK, true); 5471 5472 if (IS_ERR(mapping)) { 5473 err = PTR_ERR(mapping); 5474 goto err_tun_mapping; 5475 } 5476 uplink_priv->tunnel_mapping = mapping; 5477 5478 /* Two last values are reserved for stack devices slow path table mark 5479 * and bridge ingress push mark. 5480 */ 5481 mapping = mapping_create_for_id(mapping_id, id_len, 5482 MAPPING_TYPE_TUNNEL_ENC_OPTS, 5483 sz_enc_opts, ENC_OPTS_BITS_MASK - 2, 5484 true); 5485 if (IS_ERR(mapping)) { 5486 err = PTR_ERR(mapping); 5487 goto err_enc_opts_mapping; 5488 } 5489 uplink_priv->tunnel_enc_opts_mapping = mapping; 5490 5491 uplink_priv->encap = mlx5e_tc_tun_init(priv); 5492 if (IS_ERR(uplink_priv->encap)) { 5493 err = PTR_ERR(uplink_priv->encap); 5494 goto err_register_fib_notifier; 5495 } 5496 5497 uplink_priv->action_stats_handle = mlx5e_tc_act_stats_create(); 5498 if (IS_ERR(uplink_priv->action_stats_handle)) { 5499 err = PTR_ERR(uplink_priv->action_stats_handle); 5500 goto err_action_counter; 5501 } 5502 5503 return 0; 5504 5505 err_action_counter: 5506 mlx5e_tc_tun_cleanup(uplink_priv->encap); 5507 err_register_fib_notifier: 5508 mapping_destroy(uplink_priv->tunnel_enc_opts_mapping); 5509 err_enc_opts_mapping: 5510 mapping_destroy(uplink_priv->tunnel_mapping); 5511 err_tun_mapping: 5512 mlx5e_tc_sample_cleanup(uplink_priv->tc_psample); 5513 mlx5e_tc_int_port_cleanup(uplink_priv->int_port_priv); 5514 mlx5_tc_ct_clean(uplink_priv->ct_priv); 5515 netdev_warn(priv->netdev, 5516 "Failed to initialize tc (eswitch), err: %d", err); 5517 mlx5e_tc_post_act_destroy(uplink_priv->post_act); 5518 return err; 5519 } 5520 5521 void mlx5e_tc_esw_cleanup(struct mlx5_rep_uplink_priv *uplink_priv) 5522 { 5523 mlx5e_tc_tun_cleanup(uplink_priv->encap); 5524 5525 mapping_destroy(uplink_priv->tunnel_enc_opts_mapping); 5526 mapping_destroy(uplink_priv->tunnel_mapping); 5527 5528 mlx5e_tc_sample_cleanup(uplink_priv->tc_psample); 5529 mlx5e_tc_int_port_cleanup(uplink_priv->int_port_priv); 5530 mlx5_tc_ct_clean(uplink_priv->ct_priv); 5531 mlx5e_flow_meters_cleanup(uplink_priv->flow_meters); 5532 mlx5e_tc_post_act_destroy(uplink_priv->post_act); 5533 mlx5e_tc_act_stats_free(uplink_priv->action_stats_handle); 5534 } 5535 5536 int mlx5e_tc_num_filters(struct mlx5e_priv *priv, unsigned long flags) 5537 { 5538 struct rhashtable *tc_ht = get_tc_ht(priv, flags); 5539 5540 return atomic_read(&tc_ht->nelems); 5541 } 5542 5543 void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw) 5544 { 5545 struct mlx5e_tc_flow *peer_flow, *tmp_peer_flow; 5546 struct list_head *dup_peer_flows; 5547 unsigned long index; 5548 5549 xa_for_each(&esw->offloads.peer_flows, index, dup_peer_flows) 5550 list_for_each_entry_safe(peer_flow, tmp_peer_flow, 5551 dup_peer_flows, peer) 5552 mlx5e_tc_del_fdb_peer_flow(peer_flow); 5553 } 5554 5555 void mlx5e_tc_reoffload_flows_work(struct work_struct *work) 5556 { 5557 struct mlx5_rep_uplink_priv *rpriv = 5558 container_of(work, struct mlx5_rep_uplink_priv, 5559 reoffload_flows_work); 5560 struct mlx5e_tc_flow *flow, *tmp; 5561 5562 mutex_lock(&rpriv->unready_flows_lock); 5563 list_for_each_entry_safe(flow, tmp, &rpriv->unready_flows, unready) { 5564 if (!mlx5e_tc_add_fdb_flow(flow->priv, flow, NULL)) 5565 unready_flow_del(flow); 5566 } 5567 mutex_unlock(&rpriv->unready_flows_lock); 5568 } 5569 5570 static int mlx5e_setup_tc_cls_flower(struct mlx5e_priv *priv, 5571 struct flow_cls_offload *cls_flower, 5572 unsigned long flags) 5573 { 5574 switch (cls_flower->command) { 5575 case FLOW_CLS_REPLACE: 5576 return mlx5e_configure_flower(priv->netdev, priv, cls_flower, 5577 flags); 5578 case FLOW_CLS_DESTROY: 5579 return mlx5e_delete_flower(priv->netdev, priv, cls_flower, 5580 flags); 5581 case FLOW_CLS_STATS: 5582 return mlx5e_stats_flower(priv->netdev, priv, cls_flower, 5583 flags); 5584 default: 5585 return -EOPNOTSUPP; 5586 } 5587 } 5588 5589 int mlx5e_setup_tc_block_cb(enum tc_setup_type type, void *type_data, 5590 void *cb_priv) 5591 { 5592 unsigned long flags = MLX5_TC_FLAG(INGRESS); 5593 struct mlx5e_priv *priv = cb_priv; 5594 5595 if (!priv->netdev || !netif_device_present(priv->netdev)) 5596 return -EOPNOTSUPP; 5597 5598 if (mlx5e_is_uplink_rep(priv)) 5599 flags |= MLX5_TC_FLAG(ESW_OFFLOAD); 5600 else 5601 flags |= MLX5_TC_FLAG(NIC_OFFLOAD); 5602 5603 switch (type) { 5604 case TC_SETUP_CLSFLOWER: 5605 return mlx5e_setup_tc_cls_flower(priv, type_data, flags); 5606 default: 5607 return -EOPNOTSUPP; 5608 } 5609 } 5610 5611 static bool mlx5e_tc_restore_tunnel(struct mlx5e_priv *priv, struct sk_buff *skb, 5612 struct mlx5e_tc_update_priv *tc_priv, 5613 u32 tunnel_id) 5614 { 5615 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 5616 struct tunnel_match_enc_opts enc_opts = {}; 5617 struct mlx5_rep_uplink_priv *uplink_priv; 5618 IP_TUNNEL_DECLARE_FLAGS(flags) = { }; 5619 struct mlx5e_rep_priv *uplink_rpriv; 5620 struct metadata_dst *tun_dst; 5621 struct tunnel_match_key key; 5622 u32 tun_id, enc_opts_id; 5623 struct net_device *dev; 5624 int err; 5625 5626 __set_bit(IP_TUNNEL_KEY_BIT, flags); 5627 5628 enc_opts_id = tunnel_id & ENC_OPTS_BITS_MASK; 5629 tun_id = tunnel_id >> ENC_OPTS_BITS; 5630 5631 if (!tun_id) 5632 return true; 5633 5634 uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); 5635 uplink_priv = &uplink_rpriv->uplink_priv; 5636 5637 err = mapping_find(uplink_priv->tunnel_mapping, tun_id, &key); 5638 if (err) { 5639 netdev_dbg(priv->netdev, 5640 "Couldn't find tunnel for tun_id: %d, err: %d\n", 5641 tun_id, err); 5642 return false; 5643 } 5644 5645 if (enc_opts_id) { 5646 err = mapping_find(uplink_priv->tunnel_enc_opts_mapping, 5647 enc_opts_id, &enc_opts); 5648 if (err) { 5649 netdev_dbg(priv->netdev, 5650 "Couldn't find tunnel (opts) for tun_id: %d, err: %d\n", 5651 enc_opts_id, err); 5652 return false; 5653 } 5654 } 5655 5656 switch (key.enc_control.addr_type) { 5657 case FLOW_DISSECTOR_KEY_IPV4_ADDRS: 5658 tun_dst = __ip_tun_set_dst(key.enc_ipv4.src, key.enc_ipv4.dst, 5659 key.enc_ip.tos, key.enc_ip.ttl, 5660 key.enc_tp.dst, flags, 5661 key32_to_tunnel_id(key.enc_key_id.keyid), 5662 enc_opts.key.len); 5663 break; 5664 case FLOW_DISSECTOR_KEY_IPV6_ADDRS: 5665 tun_dst = __ipv6_tun_set_dst(&key.enc_ipv6.src, &key.enc_ipv6.dst, 5666 key.enc_ip.tos, key.enc_ip.ttl, 5667 key.enc_tp.dst, 0, flags, 5668 key32_to_tunnel_id(key.enc_key_id.keyid), 5669 enc_opts.key.len); 5670 break; 5671 default: 5672 netdev_dbg(priv->netdev, 5673 "Couldn't restore tunnel, unsupported addr_type: %d\n", 5674 key.enc_control.addr_type); 5675 return false; 5676 } 5677 5678 if (!tun_dst) { 5679 netdev_dbg(priv->netdev, "Couldn't restore tunnel, no tun_dst\n"); 5680 return false; 5681 } 5682 5683 tun_dst->u.tun_info.key.tp_src = key.enc_tp.src; 5684 5685 if (enc_opts.key.len) { 5686 ip_tunnel_flags_zero(flags); 5687 if (enc_opts.key.dst_opt_type) 5688 __set_bit(enc_opts.key.dst_opt_type, flags); 5689 5690 ip_tunnel_info_opts_set(&tun_dst->u.tun_info, 5691 enc_opts.key.data, 5692 enc_opts.key.len, 5693 flags); 5694 } 5695 5696 skb_dst_set(skb, (struct dst_entry *)tun_dst); 5697 dev = dev_get_by_index(&init_net, key.filter_ifindex); 5698 if (!dev) { 5699 netdev_dbg(priv->netdev, 5700 "Couldn't find tunnel device with ifindex: %d\n", 5701 key.filter_ifindex); 5702 return false; 5703 } 5704 5705 /* Set fwd_dev so we do dev_put() after datapath */ 5706 tc_priv->fwd_dev = dev; 5707 5708 skb->dev = dev; 5709 5710 return true; 5711 } 5712 5713 static bool mlx5e_tc_restore_skb_tc_meta(struct sk_buff *skb, struct mlx5_tc_ct_priv *ct_priv, 5714 struct mlx5_mapped_obj *mapped_obj, u32 zone_restore_id, 5715 u32 tunnel_id, struct mlx5e_tc_update_priv *tc_priv) 5716 { 5717 struct mlx5e_priv *priv = netdev_priv(skb->dev); 5718 struct tc_skb_ext *tc_skb_ext; 5719 u64 act_miss_cookie; 5720 u32 chain; 5721 5722 chain = mapped_obj->type == MLX5_MAPPED_OBJ_CHAIN ? mapped_obj->chain : 0; 5723 act_miss_cookie = mapped_obj->type == MLX5_MAPPED_OBJ_ACT_MISS ? 5724 mapped_obj->act_miss_cookie : 0; 5725 if (chain || act_miss_cookie) { 5726 if (!mlx5e_tc_ct_restore_flow(ct_priv, skb, zone_restore_id)) 5727 return false; 5728 5729 tc_skb_ext = tc_skb_ext_alloc(skb); 5730 if (!tc_skb_ext) { 5731 WARN_ON(1); 5732 return false; 5733 } 5734 5735 if (act_miss_cookie) { 5736 tc_skb_ext->act_miss_cookie = act_miss_cookie; 5737 tc_skb_ext->act_miss = 1; 5738 } else { 5739 tc_skb_ext->chain = chain; 5740 } 5741 } 5742 5743 if (tc_priv) 5744 return mlx5e_tc_restore_tunnel(priv, skb, tc_priv, tunnel_id); 5745 5746 return true; 5747 } 5748 5749 static void mlx5e_tc_restore_skb_sample(struct mlx5e_priv *priv, struct sk_buff *skb, 5750 struct mlx5_mapped_obj *mapped_obj, 5751 struct mlx5e_tc_update_priv *tc_priv) 5752 { 5753 if (!mlx5e_tc_restore_tunnel(priv, skb, tc_priv, mapped_obj->sample.tunnel_id)) { 5754 netdev_dbg(priv->netdev, 5755 "Failed to restore tunnel info for sampled packet\n"); 5756 return; 5757 } 5758 mlx5e_tc_sample_skb(skb, mapped_obj); 5759 } 5760 5761 static bool mlx5e_tc_restore_skb_int_port(struct mlx5e_priv *priv, struct sk_buff *skb, 5762 struct mlx5_mapped_obj *mapped_obj, 5763 struct mlx5e_tc_update_priv *tc_priv, 5764 u32 tunnel_id) 5765 { 5766 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; 5767 struct mlx5_rep_uplink_priv *uplink_priv; 5768 struct mlx5e_rep_priv *uplink_rpriv; 5769 bool forward_tx = false; 5770 5771 /* Tunnel restore takes precedence over int port restore */ 5772 if (tunnel_id) 5773 return mlx5e_tc_restore_tunnel(priv, skb, tc_priv, tunnel_id); 5774 5775 uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); 5776 uplink_priv = &uplink_rpriv->uplink_priv; 5777 5778 if (mlx5e_tc_int_port_dev_fwd(uplink_priv->int_port_priv, skb, 5779 mapped_obj->int_port_metadata, &forward_tx)) { 5780 /* Set fwd_dev for future dev_put */ 5781 tc_priv->fwd_dev = skb->dev; 5782 tc_priv->forward_tx = forward_tx; 5783 5784 return true; 5785 } 5786 5787 return false; 5788 } 5789 5790 bool mlx5e_tc_update_skb(struct mlx5_cqe64 *cqe, struct sk_buff *skb, 5791 struct mapping_ctx *mapping_ctx, u32 mapped_obj_id, 5792 struct mlx5_tc_ct_priv *ct_priv, 5793 u32 zone_restore_id, u32 tunnel_id, 5794 struct mlx5e_tc_update_priv *tc_priv) 5795 { 5796 struct mlx5e_priv *priv = netdev_priv(skb->dev); 5797 struct mlx5_mapped_obj mapped_obj; 5798 int err; 5799 5800 err = mapping_find(mapping_ctx, mapped_obj_id, &mapped_obj); 5801 if (err) { 5802 netdev_dbg(skb->dev, 5803 "Couldn't find mapped object for mapped_obj_id: %d, err: %d\n", 5804 mapped_obj_id, err); 5805 return false; 5806 } 5807 5808 switch (mapped_obj.type) { 5809 case MLX5_MAPPED_OBJ_CHAIN: 5810 case MLX5_MAPPED_OBJ_ACT_MISS: 5811 return mlx5e_tc_restore_skb_tc_meta(skb, ct_priv, &mapped_obj, zone_restore_id, 5812 tunnel_id, tc_priv); 5813 case MLX5_MAPPED_OBJ_SAMPLE: 5814 mlx5e_tc_restore_skb_sample(priv, skb, &mapped_obj, tc_priv); 5815 tc_priv->skb_done = true; 5816 return true; 5817 case MLX5_MAPPED_OBJ_INT_PORT_METADATA: 5818 return mlx5e_tc_restore_skb_int_port(priv, skb, &mapped_obj, tc_priv, tunnel_id); 5819 default: 5820 netdev_dbg(priv->netdev, "Invalid mapped object type: %d\n", mapped_obj.type); 5821 return false; 5822 } 5823 5824 return false; 5825 } 5826 5827 bool mlx5e_tc_update_skb_nic(struct mlx5_cqe64 *cqe, struct sk_buff *skb) 5828 { 5829 struct mlx5e_priv *priv = netdev_priv(skb->dev); 5830 u32 mapped_obj_id, reg_b, zone_restore_id; 5831 struct mlx5_tc_ct_priv *ct_priv; 5832 struct mapping_ctx *mapping_ctx; 5833 struct mlx5e_tc_table *tc; 5834 5835 reg_b = be32_to_cpu(cqe->ft_metadata); 5836 tc = mlx5e_fs_get_tc(priv->fs); 5837 mapped_obj_id = reg_b & MLX5E_TC_TABLE_CHAIN_TAG_MASK; 5838 zone_restore_id = (reg_b >> MLX5_REG_MAPPING_MOFFSET(NIC_ZONE_RESTORE_TO_REG)) & 5839 ESW_ZONE_ID_MASK; 5840 ct_priv = tc->ct; 5841 mapping_ctx = tc->mapping; 5842 5843 return mlx5e_tc_update_skb(cqe, skb, mapping_ctx, mapped_obj_id, ct_priv, zone_restore_id, 5844 0, NULL); 5845 } 5846 5847 static struct mapping_ctx * 5848 mlx5e_get_priv_obj_mapping(struct mlx5e_priv *priv) 5849 { 5850 struct mlx5e_tc_table *tc; 5851 struct mlx5_eswitch *esw; 5852 struct mapping_ctx *ctx; 5853 5854 if (is_mdev_switchdev_mode(priv->mdev)) { 5855 esw = priv->mdev->priv.eswitch; 5856 ctx = esw->offloads.reg_c0_obj_pool; 5857 } else { 5858 tc = mlx5e_fs_get_tc(priv->fs); 5859 ctx = tc->mapping; 5860 } 5861 5862 return ctx; 5863 } 5864 5865 int mlx5e_tc_action_miss_mapping_get(struct mlx5e_priv *priv, struct mlx5_flow_attr *attr, 5866 u64 act_miss_cookie, u32 *act_miss_mapping) 5867 { 5868 struct mlx5_mapped_obj mapped_obj = {}; 5869 struct mlx5_eswitch *esw; 5870 struct mapping_ctx *ctx; 5871 int err; 5872 5873 ctx = mlx5e_get_priv_obj_mapping(priv); 5874 mapped_obj.type = MLX5_MAPPED_OBJ_ACT_MISS; 5875 mapped_obj.act_miss_cookie = act_miss_cookie; 5876 err = mapping_add(ctx, &mapped_obj, act_miss_mapping); 5877 if (err) 5878 return err; 5879 5880 if (!is_mdev_switchdev_mode(priv->mdev)) 5881 return 0; 5882 5883 esw = priv->mdev->priv.eswitch; 5884 attr->act_id_restore_rule = esw_add_restore_rule(esw, *act_miss_mapping); 5885 if (IS_ERR(attr->act_id_restore_rule)) { 5886 err = PTR_ERR(attr->act_id_restore_rule); 5887 goto err_rule; 5888 } 5889 5890 return 0; 5891 5892 err_rule: 5893 mapping_remove(ctx, *act_miss_mapping); 5894 return err; 5895 } 5896 5897 void mlx5e_tc_action_miss_mapping_put(struct mlx5e_priv *priv, struct mlx5_flow_attr *attr, 5898 u32 act_miss_mapping) 5899 { 5900 struct mapping_ctx *ctx = mlx5e_get_priv_obj_mapping(priv); 5901 5902 if (is_mdev_switchdev_mode(priv->mdev)) 5903 mlx5_del_flow_rules(attr->act_id_restore_rule); 5904 mapping_remove(ctx, act_miss_mapping); 5905 } 5906