1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2016 6WIND S.A. 3 * Copyright 2016 Mellanox Technologies, Ltd 4 */ 5 6 #include <stddef.h> 7 #include <stdint.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <inttypes.h> 11 #include <errno.h> 12 #include <ctype.h> 13 #include <string.h> 14 15 #include <rte_string_fns.h> 16 #include <rte_common.h> 17 #include <rte_ethdev.h> 18 #include <rte_byteorder.h> 19 #include <cmdline_parse.h> 20 #include <cmdline_parse_etheraddr.h> 21 #include <cmdline_parse_string.h> 22 #include <cmdline_parse_num.h> 23 #include <rte_flow.h> 24 #include <rte_hexdump.h> 25 #include <rte_vxlan.h> 26 #include <rte_gre.h> 27 #include <rte_mpls.h> 28 #include <rte_gtp.h> 29 #include <rte_geneve.h> 30 31 #include "testpmd.h" 32 33 /** Parser token indices. */ 34 enum index { 35 /* Special tokens. */ 36 ZERO = 0, 37 END, 38 START_SET, 39 END_SET, 40 41 /* Common tokens. */ 42 COMMON_INTEGER, 43 COMMON_UNSIGNED, 44 COMMON_PREFIX, 45 COMMON_BOOLEAN, 46 COMMON_STRING, 47 COMMON_HEX, 48 COMMON_FILE_PATH, 49 COMMON_MAC_ADDR, 50 COMMON_IPV4_ADDR, 51 COMMON_IPV6_ADDR, 52 COMMON_RULE_ID, 53 COMMON_PORT_ID, 54 COMMON_GROUP_ID, 55 COMMON_PRIORITY_LEVEL, 56 COMMON_INDIRECT_ACTION_ID, 57 COMMON_PROFILE_ID, 58 COMMON_POLICY_ID, 59 COMMON_FLEX_HANDLE, 60 COMMON_FLEX_TOKEN, 61 COMMON_PATTERN_TEMPLATE_ID, 62 COMMON_ACTIONS_TEMPLATE_ID, 63 COMMON_TABLE_ID, 64 COMMON_QUEUE_ID, 65 66 /* TOP-level command. */ 67 ADD, 68 69 /* Top-level command. */ 70 SET, 71 /* Sub-leve commands. */ 72 SET_RAW_ENCAP, 73 SET_RAW_DECAP, 74 SET_RAW_INDEX, 75 SET_SAMPLE_ACTIONS, 76 SET_SAMPLE_INDEX, 77 SET_IPV6_EXT_REMOVE, 78 SET_IPV6_EXT_PUSH, 79 SET_IPV6_EXT_INDEX, 80 81 /* Top-level command. */ 82 FLOW, 83 /* Sub-level commands. */ 84 INFO, 85 CONFIGURE, 86 PATTERN_TEMPLATE, 87 ACTIONS_TEMPLATE, 88 TABLE, 89 FLOW_GROUP, 90 INDIRECT_ACTION, 91 VALIDATE, 92 CREATE, 93 DESTROY, 94 UPDATE, 95 FLUSH, 96 DUMP, 97 QUERY, 98 LIST, 99 AGED, 100 ISOLATE, 101 TUNNEL, 102 FLEX, 103 QUEUE, 104 PUSH, 105 PULL, 106 HASH, 107 108 /* Flex arguments */ 109 FLEX_ITEM_CREATE, 110 FLEX_ITEM_DESTROY, 111 112 /* Pattern template arguments. */ 113 PATTERN_TEMPLATE_CREATE, 114 PATTERN_TEMPLATE_DESTROY, 115 PATTERN_TEMPLATE_CREATE_ID, 116 PATTERN_TEMPLATE_DESTROY_ID, 117 PATTERN_TEMPLATE_RELAXED_MATCHING, 118 PATTERN_TEMPLATE_INGRESS, 119 PATTERN_TEMPLATE_EGRESS, 120 PATTERN_TEMPLATE_TRANSFER, 121 PATTERN_TEMPLATE_SPEC, 122 123 /* Actions template arguments. */ 124 ACTIONS_TEMPLATE_CREATE, 125 ACTIONS_TEMPLATE_DESTROY, 126 ACTIONS_TEMPLATE_CREATE_ID, 127 ACTIONS_TEMPLATE_DESTROY_ID, 128 ACTIONS_TEMPLATE_INGRESS, 129 ACTIONS_TEMPLATE_EGRESS, 130 ACTIONS_TEMPLATE_TRANSFER, 131 ACTIONS_TEMPLATE_SPEC, 132 ACTIONS_TEMPLATE_MASK, 133 134 /* Queue arguments. */ 135 QUEUE_CREATE, 136 QUEUE_DESTROY, 137 QUEUE_FLOW_UPDATE_RESIZED, 138 QUEUE_UPDATE, 139 QUEUE_AGED, 140 QUEUE_INDIRECT_ACTION, 141 142 /* Queue create arguments. */ 143 QUEUE_CREATE_POSTPONE, 144 QUEUE_TEMPLATE_TABLE, 145 QUEUE_PATTERN_TEMPLATE, 146 QUEUE_ACTIONS_TEMPLATE, 147 QUEUE_RULE_ID, 148 149 /* Queue destroy arguments. */ 150 QUEUE_DESTROY_ID, 151 QUEUE_DESTROY_POSTPONE, 152 153 /* Queue update arguments. */ 154 QUEUE_UPDATE_ID, 155 156 /* Queue indirect action arguments */ 157 QUEUE_INDIRECT_ACTION_CREATE, 158 QUEUE_INDIRECT_ACTION_LIST_CREATE, 159 QUEUE_INDIRECT_ACTION_UPDATE, 160 QUEUE_INDIRECT_ACTION_DESTROY, 161 QUEUE_INDIRECT_ACTION_QUERY, 162 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 163 164 /* Queue indirect action create arguments */ 165 QUEUE_INDIRECT_ACTION_CREATE_ID, 166 QUEUE_INDIRECT_ACTION_INGRESS, 167 QUEUE_INDIRECT_ACTION_EGRESS, 168 QUEUE_INDIRECT_ACTION_TRANSFER, 169 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 170 QUEUE_INDIRECT_ACTION_SPEC, 171 QUEUE_INDIRECT_ACTION_LIST, 172 173 /* Queue indirect action update arguments */ 174 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 175 176 /* Queue indirect action destroy arguments */ 177 QUEUE_INDIRECT_ACTION_DESTROY_ID, 178 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 179 180 /* Queue indirect action query arguments */ 181 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 182 183 /* Queue indirect action query_update arguments */ 184 QUEUE_INDIRECT_ACTION_QU_MODE, 185 186 /* Push arguments. */ 187 PUSH_QUEUE, 188 189 /* Pull arguments. */ 190 PULL_QUEUE, 191 192 /* Table arguments. */ 193 TABLE_CREATE, 194 TABLE_DESTROY, 195 TABLE_RESIZE, 196 TABLE_RESIZE_COMPLETE, 197 TABLE_CREATE_ID, 198 TABLE_DESTROY_ID, 199 TABLE_RESIZE_ID, 200 TABLE_RESIZE_RULES_NUMBER, 201 TABLE_INSERTION_TYPE, 202 TABLE_INSERTION_TYPE_NAME, 203 TABLE_HASH_FUNC, 204 TABLE_HASH_FUNC_NAME, 205 TABLE_GROUP, 206 TABLE_PRIORITY, 207 TABLE_INGRESS, 208 TABLE_EGRESS, 209 TABLE_TRANSFER, 210 TABLE_TRANSFER_WIRE_ORIG, 211 TABLE_TRANSFER_VPORT_ORIG, 212 TABLE_RESIZABLE, 213 TABLE_RULES_NUMBER, 214 TABLE_PATTERN_TEMPLATE, 215 TABLE_ACTIONS_TEMPLATE, 216 217 /* Group arguments */ 218 GROUP_ID, 219 GROUP_INGRESS, 220 GROUP_EGRESS, 221 GROUP_TRANSFER, 222 GROUP_SET_MISS_ACTIONS, 223 224 /* Hash calculation arguments. */ 225 HASH_CALC_TABLE, 226 HASH_CALC_PATTERN_INDEX, 227 HASH_CALC_PATTERN, 228 HASH_CALC_ENCAP, 229 HASH_CALC_DEST, 230 ENCAP_HASH_FIELD_SRC_PORT, 231 ENCAP_HASH_FIELD_GRE_FLOW_ID, 232 233 /* Tunnel arguments. */ 234 TUNNEL_CREATE, 235 TUNNEL_CREATE_TYPE, 236 TUNNEL_LIST, 237 TUNNEL_DESTROY, 238 TUNNEL_DESTROY_ID, 239 240 /* Destroy arguments. */ 241 DESTROY_RULE, 242 DESTROY_IS_USER_ID, 243 244 /* Query arguments. */ 245 QUERY_ACTION, 246 QUERY_IS_USER_ID, 247 248 /* List arguments. */ 249 LIST_GROUP, 250 251 /* Destroy aged flow arguments. */ 252 AGED_DESTROY, 253 254 /* Validate/create arguments. */ 255 VC_GROUP, 256 VC_PRIORITY, 257 VC_INGRESS, 258 VC_EGRESS, 259 VC_TRANSFER, 260 VC_TUNNEL_SET, 261 VC_TUNNEL_MATCH, 262 VC_USER_ID, 263 VC_IS_USER_ID, 264 265 /* Dump arguments */ 266 DUMP_ALL, 267 DUMP_ONE, 268 DUMP_IS_USER_ID, 269 270 /* Configure arguments */ 271 CONFIG_QUEUES_NUMBER, 272 CONFIG_QUEUES_SIZE, 273 CONFIG_COUNTERS_NUMBER, 274 CONFIG_AGING_OBJECTS_NUMBER, 275 CONFIG_METERS_NUMBER, 276 CONFIG_CONN_TRACK_NUMBER, 277 CONFIG_QUOTAS_NUMBER, 278 CONFIG_FLAGS, 279 CONFIG_HOST_PORT, 280 281 /* Indirect action arguments */ 282 INDIRECT_ACTION_CREATE, 283 INDIRECT_ACTION_LIST_CREATE, 284 INDIRECT_ACTION_FLOW_CONF_CREATE, 285 INDIRECT_ACTION_UPDATE, 286 INDIRECT_ACTION_DESTROY, 287 INDIRECT_ACTION_QUERY, 288 INDIRECT_ACTION_QUERY_UPDATE, 289 290 /* Indirect action create arguments */ 291 INDIRECT_ACTION_CREATE_ID, 292 INDIRECT_ACTION_INGRESS, 293 INDIRECT_ACTION_EGRESS, 294 INDIRECT_ACTION_TRANSFER, 295 INDIRECT_ACTION_SPEC, 296 INDIRECT_ACTION_LIST, 297 INDIRECT_ACTION_FLOW_CONF, 298 299 /* Indirect action destroy arguments */ 300 INDIRECT_ACTION_DESTROY_ID, 301 302 /* Indirect action query-and-update arguments */ 303 INDIRECT_ACTION_QU_MODE, 304 INDIRECT_ACTION_QU_MODE_NAME, 305 306 /* Validate/create pattern. */ 307 ITEM_PATTERN, 308 ITEM_PARAM_IS, 309 ITEM_PARAM_SPEC, 310 ITEM_PARAM_LAST, 311 ITEM_PARAM_MASK, 312 ITEM_PARAM_PREFIX, 313 ITEM_NEXT, 314 ITEM_END, 315 ITEM_VOID, 316 ITEM_INVERT, 317 ITEM_ANY, 318 ITEM_ANY_NUM, 319 ITEM_PORT_ID, 320 ITEM_PORT_ID_ID, 321 ITEM_MARK, 322 ITEM_MARK_ID, 323 ITEM_RAW, 324 ITEM_RAW_RELATIVE, 325 ITEM_RAW_SEARCH, 326 ITEM_RAW_OFFSET, 327 ITEM_RAW_LIMIT, 328 ITEM_RAW_PATTERN, 329 ITEM_RAW_PATTERN_HEX, 330 ITEM_ETH, 331 ITEM_ETH_DST, 332 ITEM_ETH_SRC, 333 ITEM_ETH_TYPE, 334 ITEM_ETH_HAS_VLAN, 335 ITEM_VLAN, 336 ITEM_VLAN_TCI, 337 ITEM_VLAN_PCP, 338 ITEM_VLAN_DEI, 339 ITEM_VLAN_VID, 340 ITEM_VLAN_INNER_TYPE, 341 ITEM_VLAN_HAS_MORE_VLAN, 342 ITEM_IPV4, 343 ITEM_IPV4_VER_IHL, 344 ITEM_IPV4_TOS, 345 ITEM_IPV4_LENGTH, 346 ITEM_IPV4_ID, 347 ITEM_IPV4_FRAGMENT_OFFSET, 348 ITEM_IPV4_TTL, 349 ITEM_IPV4_PROTO, 350 ITEM_IPV4_SRC, 351 ITEM_IPV4_DST, 352 ITEM_IPV6, 353 ITEM_IPV6_TC, 354 ITEM_IPV6_FLOW, 355 ITEM_IPV6_LEN, 356 ITEM_IPV6_PROTO, 357 ITEM_IPV6_HOP, 358 ITEM_IPV6_SRC, 359 ITEM_IPV6_DST, 360 ITEM_IPV6_HAS_FRAG_EXT, 361 ITEM_IPV6_ROUTING_EXT, 362 ITEM_IPV6_ROUTING_EXT_TYPE, 363 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 364 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 365 ITEM_ICMP, 366 ITEM_ICMP_TYPE, 367 ITEM_ICMP_CODE, 368 ITEM_ICMP_IDENT, 369 ITEM_ICMP_SEQ, 370 ITEM_UDP, 371 ITEM_UDP_SRC, 372 ITEM_UDP_DST, 373 ITEM_TCP, 374 ITEM_TCP_SRC, 375 ITEM_TCP_DST, 376 ITEM_TCP_FLAGS, 377 ITEM_SCTP, 378 ITEM_SCTP_SRC, 379 ITEM_SCTP_DST, 380 ITEM_SCTP_TAG, 381 ITEM_SCTP_CKSUM, 382 ITEM_VXLAN, 383 ITEM_VXLAN_VNI, 384 ITEM_VXLAN_FLAG_G, 385 ITEM_VXLAN_FLAG_VER, 386 ITEM_VXLAN_FLAG_I, 387 ITEM_VXLAN_FLAG_P, 388 ITEM_VXLAN_FLAG_B, 389 ITEM_VXLAN_FLAG_O, 390 ITEM_VXLAN_FLAG_D, 391 ITEM_VXLAN_FLAG_A, 392 ITEM_VXLAN_GBP_ID, 393 /* Used for "struct rte_vxlan_hdr", GPE Next protocol */ 394 ITEM_VXLAN_GPE_PROTO, 395 ITEM_VXLAN_FIRST_RSVD, 396 ITEM_VXLAN_SECND_RSVD, 397 ITEM_VXLAN_THIRD_RSVD, 398 ITEM_VXLAN_LAST_RSVD, 399 ITEM_E_TAG, 400 ITEM_E_TAG_GRP_ECID_B, 401 ITEM_NVGRE, 402 ITEM_NVGRE_TNI, 403 ITEM_MPLS, 404 ITEM_MPLS_LABEL, 405 ITEM_MPLS_TC, 406 ITEM_MPLS_S, 407 ITEM_MPLS_TTL, 408 ITEM_GRE, 409 ITEM_GRE_PROTO, 410 ITEM_GRE_C_RSVD0_VER, 411 ITEM_GRE_C_BIT, 412 ITEM_GRE_K_BIT, 413 ITEM_GRE_S_BIT, 414 ITEM_FUZZY, 415 ITEM_FUZZY_THRESH, 416 ITEM_GTP, 417 ITEM_GTP_FLAGS, 418 ITEM_GTP_MSG_TYPE, 419 ITEM_GTP_TEID, 420 ITEM_GTPC, 421 ITEM_GTPU, 422 ITEM_GENEVE, 423 ITEM_GENEVE_VNI, 424 ITEM_GENEVE_PROTO, 425 ITEM_GENEVE_OPTLEN, 426 ITEM_VXLAN_GPE, 427 ITEM_VXLAN_GPE_VNI, 428 /* Used for "struct rte_vxlan_gpe_hdr", deprecated, prefer ITEM_VXLAN_GPE_PROTO */ 429 ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR, 430 ITEM_VXLAN_GPE_FLAGS, 431 ITEM_VXLAN_GPE_RSVD0, 432 ITEM_VXLAN_GPE_RSVD1, 433 ITEM_ARP_ETH_IPV4, 434 ITEM_ARP_ETH_IPV4_SHA, 435 ITEM_ARP_ETH_IPV4_SPA, 436 ITEM_ARP_ETH_IPV4_THA, 437 ITEM_ARP_ETH_IPV4_TPA, 438 ITEM_IPV6_EXT, 439 ITEM_IPV6_EXT_NEXT_HDR, 440 ITEM_IPV6_FRAG_EXT, 441 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 442 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 443 ITEM_IPV6_FRAG_EXT_ID, 444 ITEM_ICMP6, 445 ITEM_ICMP6_TYPE, 446 ITEM_ICMP6_CODE, 447 ITEM_ICMP6_ECHO_REQUEST, 448 ITEM_ICMP6_ECHO_REQUEST_ID, 449 ITEM_ICMP6_ECHO_REQUEST_SEQ, 450 ITEM_ICMP6_ECHO_REPLY, 451 ITEM_ICMP6_ECHO_REPLY_ID, 452 ITEM_ICMP6_ECHO_REPLY_SEQ, 453 ITEM_ICMP6_ND_NS, 454 ITEM_ICMP6_ND_NS_TARGET_ADDR, 455 ITEM_ICMP6_ND_NA, 456 ITEM_ICMP6_ND_NA_TARGET_ADDR, 457 ITEM_ICMP6_ND_OPT, 458 ITEM_ICMP6_ND_OPT_TYPE, 459 ITEM_ICMP6_ND_OPT_SLA_ETH, 460 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 461 ITEM_ICMP6_ND_OPT_TLA_ETH, 462 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 463 ITEM_META, 464 ITEM_META_DATA, 465 ITEM_RANDOM, 466 ITEM_RANDOM_VALUE, 467 ITEM_GRE_KEY, 468 ITEM_GRE_KEY_VALUE, 469 ITEM_GRE_OPTION, 470 ITEM_GRE_OPTION_CHECKSUM, 471 ITEM_GRE_OPTION_KEY, 472 ITEM_GRE_OPTION_SEQUENCE, 473 ITEM_GTP_PSC, 474 ITEM_GTP_PSC_QFI, 475 ITEM_GTP_PSC_PDU_T, 476 ITEM_PPPOES, 477 ITEM_PPPOED, 478 ITEM_PPPOE_SEID, 479 ITEM_PPPOE_PROTO_ID, 480 ITEM_HIGIG2, 481 ITEM_HIGIG2_CLASSIFICATION, 482 ITEM_HIGIG2_VID, 483 ITEM_TAG, 484 ITEM_TAG_DATA, 485 ITEM_TAG_INDEX, 486 ITEM_L2TPV3OIP, 487 ITEM_L2TPV3OIP_SESSION_ID, 488 ITEM_ESP, 489 ITEM_ESP_SPI, 490 ITEM_AH, 491 ITEM_AH_SPI, 492 ITEM_PFCP, 493 ITEM_PFCP_S_FIELD, 494 ITEM_PFCP_SEID, 495 ITEM_ECPRI, 496 ITEM_ECPRI_COMMON, 497 ITEM_ECPRI_COMMON_TYPE, 498 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 499 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 500 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 501 ITEM_ECPRI_MSG_IQ_DATA_PCID, 502 ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 503 ITEM_ECPRI_MSG_DLY_MSR_MSRID, 504 ITEM_GENEVE_OPT, 505 ITEM_GENEVE_OPT_CLASS, 506 ITEM_GENEVE_OPT_TYPE, 507 ITEM_GENEVE_OPT_LENGTH, 508 ITEM_GENEVE_OPT_DATA, 509 ITEM_INTEGRITY, 510 ITEM_INTEGRITY_LEVEL, 511 ITEM_INTEGRITY_VALUE, 512 ITEM_CONNTRACK, 513 ITEM_POL_PORT, 514 ITEM_POL_METER, 515 ITEM_POL_POLICY, 516 ITEM_PORT_REPRESENTOR, 517 ITEM_PORT_REPRESENTOR_PORT_ID, 518 ITEM_REPRESENTED_PORT, 519 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 520 ITEM_FLEX, 521 ITEM_FLEX_ITEM_HANDLE, 522 ITEM_FLEX_PATTERN_HANDLE, 523 ITEM_L2TPV2, 524 ITEM_L2TPV2_TYPE, 525 ITEM_L2TPV2_TYPE_DATA, 526 ITEM_L2TPV2_TYPE_DATA_L, 527 ITEM_L2TPV2_TYPE_DATA_S, 528 ITEM_L2TPV2_TYPE_DATA_O, 529 ITEM_L2TPV2_TYPE_DATA_L_S, 530 ITEM_L2TPV2_TYPE_CTRL, 531 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 532 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 533 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 534 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 535 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 536 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 537 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 538 ITEM_L2TPV2_MSG_DATA_S_NS, 539 ITEM_L2TPV2_MSG_DATA_S_NR, 540 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 541 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 542 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 543 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 544 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 545 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 546 ITEM_L2TPV2_MSG_DATA_L_S_NS, 547 ITEM_L2TPV2_MSG_DATA_L_S_NR, 548 ITEM_L2TPV2_MSG_CTRL_LENGTH, 549 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 550 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 551 ITEM_L2TPV2_MSG_CTRL_NS, 552 ITEM_L2TPV2_MSG_CTRL_NR, 553 ITEM_PPP, 554 ITEM_PPP_ADDR, 555 ITEM_PPP_CTRL, 556 ITEM_PPP_PROTO_ID, 557 ITEM_METER, 558 ITEM_METER_COLOR, 559 ITEM_METER_COLOR_NAME, 560 ITEM_QUOTA, 561 ITEM_QUOTA_STATE, 562 ITEM_QUOTA_STATE_NAME, 563 ITEM_AGGR_AFFINITY, 564 ITEM_AGGR_AFFINITY_VALUE, 565 ITEM_TX_QUEUE, 566 ITEM_TX_QUEUE_VALUE, 567 ITEM_IB_BTH, 568 ITEM_IB_BTH_OPCODE, 569 ITEM_IB_BTH_PKEY, 570 ITEM_IB_BTH_DST_QPN, 571 ITEM_IB_BTH_PSN, 572 ITEM_IPV6_PUSH_REMOVE_EXT, 573 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 574 ITEM_PTYPE, 575 ITEM_PTYPE_VALUE, 576 ITEM_NSH, 577 ITEM_COMPARE, 578 ITEM_COMPARE_OP, 579 ITEM_COMPARE_OP_VALUE, 580 ITEM_COMPARE_FIELD_A_TYPE, 581 ITEM_COMPARE_FIELD_A_TYPE_VALUE, 582 ITEM_COMPARE_FIELD_A_LEVEL, 583 ITEM_COMPARE_FIELD_A_LEVEL_VALUE, 584 ITEM_COMPARE_FIELD_A_TAG_INDEX, 585 ITEM_COMPARE_FIELD_A_TYPE_ID, 586 ITEM_COMPARE_FIELD_A_CLASS_ID, 587 ITEM_COMPARE_FIELD_A_OFFSET, 588 ITEM_COMPARE_FIELD_B_TYPE, 589 ITEM_COMPARE_FIELD_B_TYPE_VALUE, 590 ITEM_COMPARE_FIELD_B_LEVEL, 591 ITEM_COMPARE_FIELD_B_LEVEL_VALUE, 592 ITEM_COMPARE_FIELD_B_TAG_INDEX, 593 ITEM_COMPARE_FIELD_B_TYPE_ID, 594 ITEM_COMPARE_FIELD_B_CLASS_ID, 595 ITEM_COMPARE_FIELD_B_OFFSET, 596 ITEM_COMPARE_FIELD_B_VALUE, 597 ITEM_COMPARE_FIELD_B_POINTER, 598 ITEM_COMPARE_FIELD_WIDTH, 599 600 /* Validate/create actions. */ 601 ACTIONS, 602 ACTION_NEXT, 603 ACTION_END, 604 ACTION_VOID, 605 ACTION_PASSTHRU, 606 ACTION_SKIP_CMAN, 607 ACTION_JUMP, 608 ACTION_JUMP_GROUP, 609 ACTION_MARK, 610 ACTION_MARK_ID, 611 ACTION_FLAG, 612 ACTION_QUEUE, 613 ACTION_QUEUE_INDEX, 614 ACTION_DROP, 615 ACTION_COUNT, 616 ACTION_COUNT_ID, 617 ACTION_RSS, 618 ACTION_RSS_FUNC, 619 ACTION_RSS_LEVEL, 620 ACTION_RSS_FUNC_DEFAULT, 621 ACTION_RSS_FUNC_TOEPLITZ, 622 ACTION_RSS_FUNC_SIMPLE_XOR, 623 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, 624 ACTION_RSS_TYPES, 625 ACTION_RSS_TYPE, 626 ACTION_RSS_KEY, 627 ACTION_RSS_KEY_LEN, 628 ACTION_RSS_QUEUES, 629 ACTION_RSS_QUEUE, 630 ACTION_PF, 631 ACTION_VF, 632 ACTION_VF_ORIGINAL, 633 ACTION_VF_ID, 634 ACTION_PORT_ID, 635 ACTION_PORT_ID_ORIGINAL, 636 ACTION_PORT_ID_ID, 637 ACTION_METER, 638 ACTION_METER_COLOR, 639 ACTION_METER_COLOR_TYPE, 640 ACTION_METER_COLOR_GREEN, 641 ACTION_METER_COLOR_YELLOW, 642 ACTION_METER_COLOR_RED, 643 ACTION_METER_ID, 644 ACTION_METER_MARK, 645 ACTION_METER_PROFILE, 646 ACTION_METER_PROFILE_ID2PTR, 647 ACTION_METER_POLICY, 648 ACTION_METER_POLICY_ID2PTR, 649 ACTION_METER_COLOR_MODE, 650 ACTION_METER_STATE, 651 ACTION_OF_DEC_NW_TTL, 652 ACTION_OF_POP_VLAN, 653 ACTION_OF_PUSH_VLAN, 654 ACTION_OF_PUSH_VLAN_ETHERTYPE, 655 ACTION_OF_SET_VLAN_VID, 656 ACTION_OF_SET_VLAN_VID_VLAN_VID, 657 ACTION_OF_SET_VLAN_PCP, 658 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 659 ACTION_OF_POP_MPLS, 660 ACTION_OF_POP_MPLS_ETHERTYPE, 661 ACTION_OF_PUSH_MPLS, 662 ACTION_OF_PUSH_MPLS_ETHERTYPE, 663 ACTION_VXLAN_ENCAP, 664 ACTION_VXLAN_DECAP, 665 ACTION_NVGRE_ENCAP, 666 ACTION_NVGRE_DECAP, 667 ACTION_L2_ENCAP, 668 ACTION_L2_DECAP, 669 ACTION_MPLSOGRE_ENCAP, 670 ACTION_MPLSOGRE_DECAP, 671 ACTION_MPLSOUDP_ENCAP, 672 ACTION_MPLSOUDP_DECAP, 673 ACTION_SET_IPV4_SRC, 674 ACTION_SET_IPV4_SRC_IPV4_SRC, 675 ACTION_SET_IPV4_DST, 676 ACTION_SET_IPV4_DST_IPV4_DST, 677 ACTION_SET_IPV6_SRC, 678 ACTION_SET_IPV6_SRC_IPV6_SRC, 679 ACTION_SET_IPV6_DST, 680 ACTION_SET_IPV6_DST_IPV6_DST, 681 ACTION_SET_TP_SRC, 682 ACTION_SET_TP_SRC_TP_SRC, 683 ACTION_SET_TP_DST, 684 ACTION_SET_TP_DST_TP_DST, 685 ACTION_MAC_SWAP, 686 ACTION_DEC_TTL, 687 ACTION_SET_TTL, 688 ACTION_SET_TTL_TTL, 689 ACTION_SET_MAC_SRC, 690 ACTION_SET_MAC_SRC_MAC_SRC, 691 ACTION_SET_MAC_DST, 692 ACTION_SET_MAC_DST_MAC_DST, 693 ACTION_INC_TCP_SEQ, 694 ACTION_INC_TCP_SEQ_VALUE, 695 ACTION_DEC_TCP_SEQ, 696 ACTION_DEC_TCP_SEQ_VALUE, 697 ACTION_INC_TCP_ACK, 698 ACTION_INC_TCP_ACK_VALUE, 699 ACTION_DEC_TCP_ACK, 700 ACTION_DEC_TCP_ACK_VALUE, 701 ACTION_RAW_ENCAP, 702 ACTION_RAW_DECAP, 703 ACTION_RAW_ENCAP_SIZE, 704 ACTION_RAW_ENCAP_INDEX, 705 ACTION_RAW_ENCAP_INDEX_VALUE, 706 ACTION_RAW_DECAP_INDEX, 707 ACTION_RAW_DECAP_INDEX_VALUE, 708 ACTION_SET_TAG, 709 ACTION_SET_TAG_DATA, 710 ACTION_SET_TAG_INDEX, 711 ACTION_SET_TAG_MASK, 712 ACTION_SET_META, 713 ACTION_SET_META_DATA, 714 ACTION_SET_META_MASK, 715 ACTION_SET_IPV4_DSCP, 716 ACTION_SET_IPV4_DSCP_VALUE, 717 ACTION_SET_IPV6_DSCP, 718 ACTION_SET_IPV6_DSCP_VALUE, 719 ACTION_AGE, 720 ACTION_AGE_TIMEOUT, 721 ACTION_AGE_UPDATE, 722 ACTION_AGE_UPDATE_TIMEOUT, 723 ACTION_AGE_UPDATE_TOUCH, 724 ACTION_SAMPLE, 725 ACTION_SAMPLE_RATIO, 726 ACTION_SAMPLE_INDEX, 727 ACTION_SAMPLE_INDEX_VALUE, 728 ACTION_INDIRECT, 729 ACTION_INDIRECT_LIST, 730 ACTION_INDIRECT_LIST_HANDLE, 731 ACTION_INDIRECT_LIST_CONF, 732 INDIRECT_LIST_ACTION_ID2PTR_HANDLE, 733 INDIRECT_LIST_ACTION_ID2PTR_CONF, 734 ACTION_SHARED_INDIRECT, 735 INDIRECT_ACTION_PORT, 736 INDIRECT_ACTION_ID2PTR, 737 ACTION_MODIFY_FIELD, 738 ACTION_MODIFY_FIELD_OP, 739 ACTION_MODIFY_FIELD_OP_VALUE, 740 ACTION_MODIFY_FIELD_DST_TYPE, 741 ACTION_MODIFY_FIELD_DST_TYPE_VALUE, 742 ACTION_MODIFY_FIELD_DST_LEVEL, 743 ACTION_MODIFY_FIELD_DST_LEVEL_VALUE, 744 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 745 ACTION_MODIFY_FIELD_DST_TYPE_ID, 746 ACTION_MODIFY_FIELD_DST_CLASS_ID, 747 ACTION_MODIFY_FIELD_DST_OFFSET, 748 ACTION_MODIFY_FIELD_SRC_TYPE, 749 ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, 750 ACTION_MODIFY_FIELD_SRC_LEVEL, 751 ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE, 752 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 753 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 754 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 755 ACTION_MODIFY_FIELD_SRC_OFFSET, 756 ACTION_MODIFY_FIELD_SRC_VALUE, 757 ACTION_MODIFY_FIELD_SRC_POINTER, 758 ACTION_MODIFY_FIELD_WIDTH, 759 ACTION_CONNTRACK, 760 ACTION_CONNTRACK_UPDATE, 761 ACTION_CONNTRACK_UPDATE_DIR, 762 ACTION_CONNTRACK_UPDATE_CTX, 763 ACTION_POL_G, 764 ACTION_POL_Y, 765 ACTION_POL_R, 766 ACTION_PORT_REPRESENTOR, 767 ACTION_PORT_REPRESENTOR_PORT_ID, 768 ACTION_REPRESENTED_PORT, 769 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 770 ACTION_SEND_TO_KERNEL, 771 ACTION_QUOTA_CREATE, 772 ACTION_QUOTA_CREATE_LIMIT, 773 ACTION_QUOTA_CREATE_MODE, 774 ACTION_QUOTA_CREATE_MODE_NAME, 775 ACTION_QUOTA_QU, 776 ACTION_QUOTA_QU_LIMIT, 777 ACTION_QUOTA_QU_UPDATE_OP, 778 ACTION_QUOTA_QU_UPDATE_OP_NAME, 779 ACTION_IPV6_EXT_REMOVE, 780 ACTION_IPV6_EXT_REMOVE_INDEX, 781 ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, 782 ACTION_IPV6_EXT_PUSH, 783 ACTION_IPV6_EXT_PUSH_INDEX, 784 ACTION_IPV6_EXT_PUSH_INDEX_VALUE, 785 ACTION_NAT64, 786 ACTION_NAT64_MODE, 787 ACTION_JUMP_TO_TABLE_INDEX, 788 ACTION_JUMP_TO_TABLE_INDEX_TABLE, 789 ACTION_JUMP_TO_TABLE_INDEX_INDEX, 790 }; 791 792 /** Maximum size for pattern in struct rte_flow_item_raw. */ 793 #define ITEM_RAW_PATTERN_SIZE 512 794 795 /** Maximum size for GENEVE option data pattern in bytes. */ 796 #define ITEM_GENEVE_OPT_DATA_SIZE 124 797 798 /** Storage size for struct rte_flow_item_raw including pattern. */ 799 #define ITEM_RAW_SIZE \ 800 (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) 801 802 static const char *const compare_ops[] = { 803 "eq", "ne", "lt", "le", "gt", "ge", NULL 804 }; 805 806 /** Maximum size for external pattern in struct rte_flow_field_data. */ 807 #define FLOW_FIELD_PATTERN_SIZE 32 808 809 /** Storage size for struct rte_flow_action_modify_field including pattern. */ 810 #define ACTION_MODIFY_SIZE \ 811 (sizeof(struct rte_flow_action_modify_field) + \ 812 FLOW_FIELD_PATTERN_SIZE) 813 814 /** Maximum number of queue indices in struct rte_flow_action_rss. */ 815 #define ACTION_RSS_QUEUE_NUM 128 816 817 /** Storage for struct rte_flow_action_rss including external data. */ 818 struct action_rss_data { 819 struct rte_flow_action_rss conf; 820 uint8_t key[RSS_HASH_KEY_LENGTH]; 821 uint16_t queue[ACTION_RSS_QUEUE_NUM]; 822 }; 823 824 /** Maximum data size in struct rte_flow_action_raw_encap. */ 825 #define ACTION_RAW_ENCAP_MAX_DATA 512 826 #define RAW_ENCAP_CONFS_MAX_NUM 8 827 828 /** Storage for struct rte_flow_action_raw_encap. */ 829 struct raw_encap_conf { 830 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 831 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 832 size_t size; 833 }; 834 835 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 836 837 /** Storage for struct rte_flow_action_raw_encap including external data. */ 838 struct action_raw_encap_data { 839 struct rte_flow_action_raw_encap conf; 840 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 841 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 842 uint16_t idx; 843 }; 844 845 /** Storage for struct rte_flow_action_raw_decap. */ 846 struct raw_decap_conf { 847 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 848 size_t size; 849 }; 850 851 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 852 853 /** Storage for struct rte_flow_action_raw_decap including external data. */ 854 struct action_raw_decap_data { 855 struct rte_flow_action_raw_decap conf; 856 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 857 uint16_t idx; 858 }; 859 860 /** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ 861 #define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 862 #define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 863 864 /** Storage for struct rte_flow_action_ipv6_ext_push. */ 865 struct ipv6_ext_push_conf { 866 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 867 size_t size; 868 uint8_t type; 869 }; 870 871 struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 872 873 /** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ 874 struct action_ipv6_ext_push_data { 875 struct rte_flow_action_ipv6_ext_push conf; 876 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 877 uint8_t type; 878 uint16_t idx; 879 }; 880 881 /** Storage for struct rte_flow_action_ipv6_ext_remove. */ 882 struct ipv6_ext_remove_conf { 883 struct rte_flow_action_ipv6_ext_remove conf; 884 uint8_t type; 885 }; 886 887 struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 888 889 /** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ 890 struct action_ipv6_ext_remove_data { 891 struct rte_flow_action_ipv6_ext_remove conf; 892 uint8_t type; 893 uint16_t idx; 894 }; 895 896 struct vxlan_encap_conf vxlan_encap_conf = { 897 .select_ipv4 = 1, 898 .select_vlan = 0, 899 .select_tos_ttl = 0, 900 .vni = { 0x00, 0x00, 0x00 }, 901 .udp_src = 0, 902 .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), 903 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 904 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 905 .ipv6_src = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 906 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, 907 .ipv6_dst = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 908 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11 }, 909 .vlan_tci = 0, 910 .ip_tos = 0, 911 .ip_ttl = 255, 912 .eth_src = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 913 .eth_dst = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 914 }; 915 916 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */ 917 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6 918 919 /** Storage for struct rte_flow_action_vxlan_encap including external data. */ 920 struct action_vxlan_encap_data { 921 struct rte_flow_action_vxlan_encap conf; 922 struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; 923 struct rte_flow_item_eth item_eth; 924 struct rte_flow_item_vlan item_vlan; 925 union { 926 struct rte_flow_item_ipv4 item_ipv4; 927 struct rte_flow_item_ipv6 item_ipv6; 928 }; 929 struct rte_flow_item_udp item_udp; 930 struct rte_flow_item_vxlan item_vxlan; 931 }; 932 933 struct nvgre_encap_conf nvgre_encap_conf = { 934 .select_ipv4 = 1, 935 .select_vlan = 0, 936 .tni = { 0x00, 0x00, 0x00 }, 937 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 938 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 939 .ipv6_src = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 940 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, 941 .ipv6_dst = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 942 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11 }, 943 .vlan_tci = 0, 944 .eth_src = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 945 .eth_dst = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 946 }; 947 948 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */ 949 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 950 951 /** Storage for struct rte_flow_action_nvgre_encap including external data. */ 952 struct action_nvgre_encap_data { 953 struct rte_flow_action_nvgre_encap conf; 954 struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; 955 struct rte_flow_item_eth item_eth; 956 struct rte_flow_item_vlan item_vlan; 957 union { 958 struct rte_flow_item_ipv4 item_ipv4; 959 struct rte_flow_item_ipv6 item_ipv6; 960 }; 961 struct rte_flow_item_nvgre item_nvgre; 962 }; 963 964 struct l2_encap_conf l2_encap_conf; 965 966 struct l2_decap_conf l2_decap_conf; 967 968 struct mplsogre_encap_conf mplsogre_encap_conf; 969 970 struct mplsogre_decap_conf mplsogre_decap_conf; 971 972 struct mplsoudp_encap_conf mplsoudp_encap_conf; 973 974 struct mplsoudp_decap_conf mplsoudp_decap_conf; 975 976 struct rte_flow_action_conntrack conntrack_context; 977 978 #define ACTION_SAMPLE_ACTIONS_NUM 10 979 #define RAW_SAMPLE_CONFS_MAX_NUM 8 980 /** Storage for struct rte_flow_action_sample including external data. */ 981 struct action_sample_data { 982 struct rte_flow_action_sample conf; 983 uint32_t idx; 984 }; 985 /** Storage for struct rte_flow_action_sample. */ 986 struct raw_sample_conf { 987 struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; 988 }; 989 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; 990 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; 991 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; 992 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; 993 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; 994 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 995 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 996 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 997 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; 998 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; 999 struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; 1000 struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; 1001 1002 static const char *const modify_field_ops[] = { 1003 "set", "add", "sub", NULL 1004 }; 1005 1006 static const char *const flow_field_ids[] = { 1007 "start", "mac_dst", "mac_src", 1008 "vlan_type", "vlan_id", "mac_type", 1009 "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", 1010 "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", 1011 "tcp_port_src", "tcp_port_dst", 1012 "tcp_seq_num", "tcp_ack_num", "tcp_flags", 1013 "udp_port_src", "udp_port_dst", 1014 "vxlan_vni", "geneve_vni", "gtp_teid", 1015 "tag", "mark", "meta", "pointer", "value", 1016 "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", 1017 "ipv6_proto", 1018 "flex_item", 1019 "hash_result", 1020 "geneve_opt_type", "geneve_opt_class", "geneve_opt_data", "mpls", 1021 "tcp_data_off", "ipv4_ihl", "ipv4_total_len", "ipv6_payload_len", 1022 "ipv4_proto", 1023 "ipv6_flow_label", "ipv6_traffic_class", 1024 "esp_spi", "esp_seq_num", "esp_proto", 1025 "random", 1026 "vxlan_last_rsvd", 1027 NULL 1028 }; 1029 1030 static const char *const meter_colors[] = { 1031 "green", "yellow", "red", "all", NULL 1032 }; 1033 1034 static const char *const table_insertion_types[] = { 1035 "pattern", "index", "index_with_pattern", NULL 1036 }; 1037 1038 static const char *const table_hash_funcs[] = { 1039 "default", "linear", "crc32", "crc16", NULL 1040 }; 1041 1042 #define RAW_IPSEC_CONFS_MAX_NUM 8 1043 1044 /** Maximum number of subsequent tokens and arguments on the stack. */ 1045 #define CTX_STACK_SIZE 16 1046 1047 /** Parser context. */ 1048 struct context { 1049 /** Stack of subsequent token lists to process. */ 1050 const enum index *next[CTX_STACK_SIZE]; 1051 /** Arguments for stacked tokens. */ 1052 const void *args[CTX_STACK_SIZE]; 1053 enum index curr; /**< Current token index. */ 1054 enum index prev; /**< Index of the last token seen. */ 1055 int next_num; /**< Number of entries in next[]. */ 1056 int args_num; /**< Number of entries in args[]. */ 1057 uint32_t eol:1; /**< EOL has been detected. */ 1058 uint32_t last:1; /**< No more arguments. */ 1059 portid_t port; /**< Current port ID (for completions). */ 1060 uint32_t objdata; /**< Object-specific data. */ 1061 void *object; /**< Address of current object for relative offsets. */ 1062 void *objmask; /**< Object a full mask must be written to. */ 1063 }; 1064 1065 /** Token argument. */ 1066 struct arg { 1067 uint32_t hton:1; /**< Use network byte ordering. */ 1068 uint32_t sign:1; /**< Value is signed. */ 1069 uint32_t bounded:1; /**< Value is bounded. */ 1070 uintmax_t min; /**< Minimum value if bounded. */ 1071 uintmax_t max; /**< Maximum value if bounded. */ 1072 uint32_t offset; /**< Relative offset from ctx->object. */ 1073 uint32_t size; /**< Field size. */ 1074 const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ 1075 }; 1076 1077 /** Parser token definition. */ 1078 struct token { 1079 /** Type displayed during completion (defaults to "TOKEN"). */ 1080 const char *type; 1081 /** Help displayed during completion (defaults to token name). */ 1082 const char *help; 1083 /** Private data used by parser functions. */ 1084 const void *priv; 1085 /** 1086 * Lists of subsequent tokens to push on the stack. Each call to the 1087 * parser consumes the last entry of that stack. 1088 */ 1089 const enum index *const *next; 1090 /** Arguments stack for subsequent tokens that need them. */ 1091 const struct arg *const *args; 1092 /** 1093 * Token-processing callback, returns -1 in case of error, the 1094 * length of the matched string otherwise. If NULL, attempts to 1095 * match the token name. 1096 * 1097 * If buf is not NULL, the result should be stored in it according 1098 * to context. An error is returned if not large enough. 1099 */ 1100 int (*call)(struct context *ctx, const struct token *token, 1101 const char *str, unsigned int len, 1102 void *buf, unsigned int size); 1103 /** 1104 * Callback that provides possible values for this token, used for 1105 * completion. Returns -1 in case of error, the number of possible 1106 * values otherwise. If NULL, the token name is used. 1107 * 1108 * If buf is not NULL, entry index ent is written to buf and the 1109 * full length of the entry is returned (same behavior as 1110 * snprintf()). 1111 */ 1112 int (*comp)(struct context *ctx, const struct token *token, 1113 unsigned int ent, char *buf, unsigned int size); 1114 /** Mandatory token name, no default value. */ 1115 const char *name; 1116 }; 1117 1118 /** Static initializer for the next field. */ 1119 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } 1120 1121 /** Static initializer for a NEXT() entry. */ 1122 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } 1123 1124 /** Static initializer for the args field. */ 1125 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } 1126 1127 /** Static initializer for ARGS() to target a field. */ 1128 #define ARGS_ENTRY(s, f) \ 1129 (&(const struct arg){ \ 1130 .offset = offsetof(s, f), \ 1131 .size = sizeof(((s *)0)->f), \ 1132 }) 1133 1134 /** Static initializer for ARGS() to target a bit-field. */ 1135 #define ARGS_ENTRY_BF(s, f, b) \ 1136 (&(const struct arg){ \ 1137 .size = sizeof(s), \ 1138 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ 1139 }) 1140 1141 /** Static initializer for ARGS() to target a field with limits. */ 1142 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \ 1143 (&(const struct arg){ \ 1144 .bounded = 1, \ 1145 .min = (i), \ 1146 .max = (a), \ 1147 .offset = offsetof(s, f), \ 1148 .size = sizeof(((s *)0)->f), \ 1149 }) 1150 1151 /** Static initializer for ARGS() to target an arbitrary bit-mask. */ 1152 #define ARGS_ENTRY_MASK(s, f, m) \ 1153 (&(const struct arg){ \ 1154 .offset = offsetof(s, f), \ 1155 .size = sizeof(((s *)0)->f), \ 1156 .mask = (const void *)(m), \ 1157 }) 1158 1159 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ 1160 #define ARGS_ENTRY_MASK_HTON(s, f, m) \ 1161 (&(const struct arg){ \ 1162 .hton = 1, \ 1163 .offset = offsetof(s, f), \ 1164 .size = sizeof(((s *)0)->f), \ 1165 .mask = (const void *)(m), \ 1166 }) 1167 1168 /** Static initializer for ARGS() to target a pointer. */ 1169 #define ARGS_ENTRY_PTR(s, f) \ 1170 (&(const struct arg){ \ 1171 .size = sizeof(*((s *)0)->f), \ 1172 }) 1173 1174 /** Static initializer for ARGS() with arbitrary offset and size. */ 1175 #define ARGS_ENTRY_ARB(o, s) \ 1176 (&(const struct arg){ \ 1177 .offset = (o), \ 1178 .size = (s), \ 1179 }) 1180 1181 /** Same as ARGS_ENTRY_ARB() with bounded values. */ 1182 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ 1183 (&(const struct arg){ \ 1184 .bounded = 1, \ 1185 .min = (i), \ 1186 .max = (a), \ 1187 .offset = (o), \ 1188 .size = (s), \ 1189 }) 1190 1191 /** Same as ARGS_ENTRY() using network byte ordering. */ 1192 #define ARGS_ENTRY_HTON(s, f) \ 1193 (&(const struct arg){ \ 1194 .hton = 1, \ 1195 .offset = offsetof(s, f), \ 1196 .size = sizeof(((s *)0)->f), \ 1197 }) 1198 1199 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ 1200 #define ARG_ENTRY_HTON(s) \ 1201 (&(const struct arg){ \ 1202 .hton = 1, \ 1203 .offset = 0, \ 1204 .size = sizeof(s), \ 1205 }) 1206 1207 /** Parser output buffer layout expected by cmd_flow_parsed(). */ 1208 struct buffer { 1209 enum index command; /**< Flow command. */ 1210 portid_t port; /**< Affected port ID. */ 1211 queueid_t queue; /** Async queue ID. */ 1212 bool postpone; /** Postpone async operation */ 1213 union { 1214 struct { 1215 struct rte_flow_port_attr port_attr; 1216 uint32_t nb_queue; 1217 struct rte_flow_queue_attr queue_attr; 1218 } configure; /**< Configuration arguments. */ 1219 struct { 1220 uint32_t *template_id; 1221 uint32_t template_id_n; 1222 } templ_destroy; /**< Template destroy arguments. */ 1223 struct { 1224 uint32_t id; 1225 struct rte_flow_template_table_attr attr; 1226 uint32_t *pat_templ_id; 1227 uint32_t pat_templ_id_n; 1228 uint32_t *act_templ_id; 1229 uint32_t act_templ_id_n; 1230 } table; /**< Table arguments. */ 1231 struct { 1232 uint32_t *table_id; 1233 uint32_t table_id_n; 1234 } table_destroy; /**< Template destroy arguments. */ 1235 struct { 1236 uint32_t *action_id; 1237 uint32_t action_id_n; 1238 } ia_destroy; /**< Indirect action destroy arguments. */ 1239 struct { 1240 uint32_t action_id; 1241 enum rte_flow_query_update_mode qu_mode; 1242 } ia; /* Indirect action query arguments */ 1243 struct { 1244 uint32_t table_id; 1245 uint32_t pat_templ_id; 1246 uint32_t rule_id; 1247 uint32_t act_templ_id; 1248 struct rte_flow_attr attr; 1249 struct tunnel_ops tunnel_ops; 1250 uintptr_t user_id; 1251 struct rte_flow_item *pattern; 1252 struct rte_flow_action *actions; 1253 struct rte_flow_action *masks; 1254 uint32_t pattern_n; 1255 uint32_t actions_n; 1256 uint8_t *data; 1257 enum rte_flow_encap_hash_field field; 1258 uint8_t encap_hash; 1259 } vc; /**< Validate/create arguments. */ 1260 struct { 1261 uint64_t *rule; 1262 uint64_t rule_n; 1263 bool is_user_id; 1264 } destroy; /**< Destroy arguments. */ 1265 struct { 1266 char file[128]; 1267 bool mode; 1268 uint64_t rule; 1269 bool is_user_id; 1270 } dump; /**< Dump arguments. */ 1271 struct { 1272 uint64_t rule; 1273 struct rte_flow_action action; 1274 bool is_user_id; 1275 } query; /**< Query arguments. */ 1276 struct { 1277 uint32_t *group; 1278 uint32_t group_n; 1279 } list; /**< List arguments. */ 1280 struct { 1281 int set; 1282 } isolate; /**< Isolated mode arguments. */ 1283 struct { 1284 int destroy; 1285 } aged; /**< Aged arguments. */ 1286 struct { 1287 uint32_t policy_id; 1288 } policy;/**< Policy arguments. */ 1289 struct { 1290 uint16_t token; 1291 uintptr_t uintptr; 1292 char filename[128]; 1293 } flex; /**< Flex arguments*/ 1294 } args; /**< Command arguments. */ 1295 }; 1296 1297 /** Private data for pattern items. */ 1298 struct parse_item_priv { 1299 enum rte_flow_item_type type; /**< Item type. */ 1300 uint32_t size; /**< Size of item specification structure. */ 1301 }; 1302 1303 #define PRIV_ITEM(t, s) \ 1304 (&(const struct parse_item_priv){ \ 1305 .type = RTE_FLOW_ITEM_TYPE_ ## t, \ 1306 .size = s, \ 1307 }) 1308 1309 /** Private data for actions. */ 1310 struct parse_action_priv { 1311 enum rte_flow_action_type type; /**< Action type. */ 1312 uint32_t size; /**< Size of action configuration structure. */ 1313 }; 1314 1315 #define PRIV_ACTION(t, s) \ 1316 (&(const struct parse_action_priv){ \ 1317 .type = RTE_FLOW_ACTION_TYPE_ ## t, \ 1318 .size = s, \ 1319 }) 1320 1321 static const enum index next_flex_item[] = { 1322 FLEX_ITEM_CREATE, 1323 FLEX_ITEM_DESTROY, 1324 ZERO, 1325 }; 1326 1327 static const enum index next_config_attr[] = { 1328 CONFIG_QUEUES_NUMBER, 1329 CONFIG_QUEUES_SIZE, 1330 CONFIG_COUNTERS_NUMBER, 1331 CONFIG_AGING_OBJECTS_NUMBER, 1332 CONFIG_METERS_NUMBER, 1333 CONFIG_CONN_TRACK_NUMBER, 1334 CONFIG_QUOTAS_NUMBER, 1335 CONFIG_FLAGS, 1336 CONFIG_HOST_PORT, 1337 END, 1338 ZERO, 1339 }; 1340 1341 static const enum index next_pt_subcmd[] = { 1342 PATTERN_TEMPLATE_CREATE, 1343 PATTERN_TEMPLATE_DESTROY, 1344 ZERO, 1345 }; 1346 1347 static const enum index next_pt_attr[] = { 1348 PATTERN_TEMPLATE_CREATE_ID, 1349 PATTERN_TEMPLATE_RELAXED_MATCHING, 1350 PATTERN_TEMPLATE_INGRESS, 1351 PATTERN_TEMPLATE_EGRESS, 1352 PATTERN_TEMPLATE_TRANSFER, 1353 PATTERN_TEMPLATE_SPEC, 1354 ZERO, 1355 }; 1356 1357 static const enum index next_pt_destroy_attr[] = { 1358 PATTERN_TEMPLATE_DESTROY_ID, 1359 END, 1360 ZERO, 1361 }; 1362 1363 static const enum index next_at_subcmd[] = { 1364 ACTIONS_TEMPLATE_CREATE, 1365 ACTIONS_TEMPLATE_DESTROY, 1366 ZERO, 1367 }; 1368 1369 static const enum index next_at_attr[] = { 1370 ACTIONS_TEMPLATE_CREATE_ID, 1371 ACTIONS_TEMPLATE_INGRESS, 1372 ACTIONS_TEMPLATE_EGRESS, 1373 ACTIONS_TEMPLATE_TRANSFER, 1374 ACTIONS_TEMPLATE_SPEC, 1375 ZERO, 1376 }; 1377 1378 static const enum index next_at_destroy_attr[] = { 1379 ACTIONS_TEMPLATE_DESTROY_ID, 1380 END, 1381 ZERO, 1382 }; 1383 1384 static const enum index next_group_attr[] = { 1385 GROUP_INGRESS, 1386 GROUP_EGRESS, 1387 GROUP_TRANSFER, 1388 GROUP_SET_MISS_ACTIONS, 1389 ZERO, 1390 }; 1391 1392 static const enum index next_table_subcmd[] = { 1393 TABLE_CREATE, 1394 TABLE_DESTROY, 1395 TABLE_RESIZE, 1396 TABLE_RESIZE_COMPLETE, 1397 ZERO, 1398 }; 1399 1400 static const enum index next_table_attr[] = { 1401 TABLE_CREATE_ID, 1402 TABLE_GROUP, 1403 TABLE_INSERTION_TYPE, 1404 TABLE_HASH_FUNC, 1405 TABLE_PRIORITY, 1406 TABLE_INGRESS, 1407 TABLE_EGRESS, 1408 TABLE_TRANSFER, 1409 TABLE_TRANSFER_WIRE_ORIG, 1410 TABLE_TRANSFER_VPORT_ORIG, 1411 TABLE_RESIZABLE, 1412 TABLE_RULES_NUMBER, 1413 TABLE_PATTERN_TEMPLATE, 1414 TABLE_ACTIONS_TEMPLATE, 1415 END, 1416 ZERO, 1417 }; 1418 1419 static const enum index next_table_destroy_attr[] = { 1420 TABLE_DESTROY_ID, 1421 END, 1422 ZERO, 1423 }; 1424 1425 static const enum index next_queue_subcmd[] = { 1426 QUEUE_CREATE, 1427 QUEUE_DESTROY, 1428 QUEUE_FLOW_UPDATE_RESIZED, 1429 QUEUE_UPDATE, 1430 QUEUE_AGED, 1431 QUEUE_INDIRECT_ACTION, 1432 ZERO, 1433 }; 1434 1435 static const enum index next_queue_destroy_attr[] = { 1436 QUEUE_DESTROY_ID, 1437 END, 1438 ZERO, 1439 }; 1440 1441 static const enum index next_qia_subcmd[] = { 1442 QUEUE_INDIRECT_ACTION_CREATE, 1443 QUEUE_INDIRECT_ACTION_UPDATE, 1444 QUEUE_INDIRECT_ACTION_DESTROY, 1445 QUEUE_INDIRECT_ACTION_QUERY, 1446 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 1447 ZERO, 1448 }; 1449 1450 static const enum index next_qia_create_attr[] = { 1451 QUEUE_INDIRECT_ACTION_CREATE_ID, 1452 QUEUE_INDIRECT_ACTION_INGRESS, 1453 QUEUE_INDIRECT_ACTION_EGRESS, 1454 QUEUE_INDIRECT_ACTION_TRANSFER, 1455 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 1456 QUEUE_INDIRECT_ACTION_SPEC, 1457 QUEUE_INDIRECT_ACTION_LIST, 1458 ZERO, 1459 }; 1460 1461 static const enum index next_qia_update_attr[] = { 1462 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1463 QUEUE_INDIRECT_ACTION_SPEC, 1464 ZERO, 1465 }; 1466 1467 static const enum index next_qia_destroy_attr[] = { 1468 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 1469 QUEUE_INDIRECT_ACTION_DESTROY_ID, 1470 END, 1471 ZERO, 1472 }; 1473 1474 static const enum index next_qia_query_attr[] = { 1475 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 1476 END, 1477 ZERO, 1478 }; 1479 1480 static const enum index next_ia_create_attr[] = { 1481 INDIRECT_ACTION_CREATE_ID, 1482 INDIRECT_ACTION_INGRESS, 1483 INDIRECT_ACTION_EGRESS, 1484 INDIRECT_ACTION_TRANSFER, 1485 INDIRECT_ACTION_SPEC, 1486 INDIRECT_ACTION_LIST, 1487 INDIRECT_ACTION_FLOW_CONF, 1488 ZERO, 1489 }; 1490 1491 static const enum index next_ia[] = { 1492 INDIRECT_ACTION_ID2PTR, 1493 ACTION_NEXT, 1494 ZERO 1495 }; 1496 1497 static const enum index next_ial[] = { 1498 ACTION_INDIRECT_LIST_HANDLE, 1499 ACTION_INDIRECT_LIST_CONF, 1500 ACTION_NEXT, 1501 ZERO 1502 }; 1503 1504 static const enum index next_qia_qu_attr[] = { 1505 QUEUE_INDIRECT_ACTION_QU_MODE, 1506 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1507 INDIRECT_ACTION_SPEC, 1508 ZERO 1509 }; 1510 1511 static const enum index next_ia_qu_attr[] = { 1512 INDIRECT_ACTION_QU_MODE, 1513 INDIRECT_ACTION_SPEC, 1514 ZERO 1515 }; 1516 1517 static const enum index next_dump_subcmd[] = { 1518 DUMP_ALL, 1519 DUMP_ONE, 1520 DUMP_IS_USER_ID, 1521 ZERO, 1522 }; 1523 1524 static const enum index next_ia_subcmd[] = { 1525 INDIRECT_ACTION_CREATE, 1526 INDIRECT_ACTION_UPDATE, 1527 INDIRECT_ACTION_DESTROY, 1528 INDIRECT_ACTION_QUERY, 1529 INDIRECT_ACTION_QUERY_UPDATE, 1530 ZERO, 1531 }; 1532 1533 static const enum index next_vc_attr[] = { 1534 VC_GROUP, 1535 VC_PRIORITY, 1536 VC_INGRESS, 1537 VC_EGRESS, 1538 VC_TRANSFER, 1539 VC_TUNNEL_SET, 1540 VC_TUNNEL_MATCH, 1541 VC_USER_ID, 1542 ITEM_PATTERN, 1543 ZERO, 1544 }; 1545 1546 static const enum index next_destroy_attr[] = { 1547 DESTROY_RULE, 1548 DESTROY_IS_USER_ID, 1549 END, 1550 ZERO, 1551 }; 1552 1553 static const enum index next_dump_attr[] = { 1554 COMMON_FILE_PATH, 1555 END, 1556 ZERO, 1557 }; 1558 1559 static const enum index next_query_attr[] = { 1560 QUERY_IS_USER_ID, 1561 END, 1562 ZERO, 1563 }; 1564 1565 static const enum index next_list_attr[] = { 1566 LIST_GROUP, 1567 END, 1568 ZERO, 1569 }; 1570 1571 static const enum index next_aged_attr[] = { 1572 AGED_DESTROY, 1573 END, 1574 ZERO, 1575 }; 1576 1577 static const enum index next_ia_destroy_attr[] = { 1578 INDIRECT_ACTION_DESTROY_ID, 1579 END, 1580 ZERO, 1581 }; 1582 1583 static const enum index next_async_insert_subcmd[] = { 1584 QUEUE_PATTERN_TEMPLATE, 1585 QUEUE_RULE_ID, 1586 ZERO, 1587 }; 1588 1589 static const enum index next_async_pattern_subcmd[] = { 1590 QUEUE_PATTERN_TEMPLATE, 1591 QUEUE_ACTIONS_TEMPLATE, 1592 ZERO, 1593 }; 1594 1595 static const enum index item_param[] = { 1596 ITEM_PARAM_IS, 1597 ITEM_PARAM_SPEC, 1598 ITEM_PARAM_LAST, 1599 ITEM_PARAM_MASK, 1600 ITEM_PARAM_PREFIX, 1601 ZERO, 1602 }; 1603 1604 static const enum index next_item[] = { 1605 ITEM_END, 1606 ITEM_VOID, 1607 ITEM_INVERT, 1608 ITEM_ANY, 1609 ITEM_PORT_ID, 1610 ITEM_MARK, 1611 ITEM_RAW, 1612 ITEM_ETH, 1613 ITEM_VLAN, 1614 ITEM_IPV4, 1615 ITEM_IPV6, 1616 ITEM_ICMP, 1617 ITEM_UDP, 1618 ITEM_TCP, 1619 ITEM_SCTP, 1620 ITEM_VXLAN, 1621 ITEM_E_TAG, 1622 ITEM_NVGRE, 1623 ITEM_MPLS, 1624 ITEM_GRE, 1625 ITEM_FUZZY, 1626 ITEM_GTP, 1627 ITEM_GTPC, 1628 ITEM_GTPU, 1629 ITEM_GENEVE, 1630 ITEM_VXLAN_GPE, 1631 ITEM_ARP_ETH_IPV4, 1632 ITEM_IPV6_EXT, 1633 ITEM_IPV6_FRAG_EXT, 1634 ITEM_IPV6_ROUTING_EXT, 1635 ITEM_ICMP6, 1636 ITEM_ICMP6_ECHO_REQUEST, 1637 ITEM_ICMP6_ECHO_REPLY, 1638 ITEM_ICMP6_ND_NS, 1639 ITEM_ICMP6_ND_NA, 1640 ITEM_ICMP6_ND_OPT, 1641 ITEM_ICMP6_ND_OPT_SLA_ETH, 1642 ITEM_ICMP6_ND_OPT_TLA_ETH, 1643 ITEM_META, 1644 ITEM_RANDOM, 1645 ITEM_GRE_KEY, 1646 ITEM_GRE_OPTION, 1647 ITEM_GTP_PSC, 1648 ITEM_PPPOES, 1649 ITEM_PPPOED, 1650 ITEM_PPPOE_PROTO_ID, 1651 ITEM_HIGIG2, 1652 ITEM_TAG, 1653 ITEM_L2TPV3OIP, 1654 ITEM_ESP, 1655 ITEM_AH, 1656 ITEM_PFCP, 1657 ITEM_ECPRI, 1658 ITEM_GENEVE_OPT, 1659 ITEM_INTEGRITY, 1660 ITEM_CONNTRACK, 1661 ITEM_PORT_REPRESENTOR, 1662 ITEM_REPRESENTED_PORT, 1663 ITEM_FLEX, 1664 ITEM_L2TPV2, 1665 ITEM_PPP, 1666 ITEM_METER, 1667 ITEM_QUOTA, 1668 ITEM_AGGR_AFFINITY, 1669 ITEM_TX_QUEUE, 1670 ITEM_IB_BTH, 1671 ITEM_PTYPE, 1672 ITEM_NSH, 1673 ITEM_COMPARE, 1674 END_SET, 1675 ZERO, 1676 }; 1677 1678 static const enum index item_fuzzy[] = { 1679 ITEM_FUZZY_THRESH, 1680 ITEM_NEXT, 1681 ZERO, 1682 }; 1683 1684 static const enum index item_any[] = { 1685 ITEM_ANY_NUM, 1686 ITEM_NEXT, 1687 ZERO, 1688 }; 1689 1690 static const enum index item_port_id[] = { 1691 ITEM_PORT_ID_ID, 1692 ITEM_NEXT, 1693 ZERO, 1694 }; 1695 1696 static const enum index item_mark[] = { 1697 ITEM_MARK_ID, 1698 ITEM_NEXT, 1699 ZERO, 1700 }; 1701 1702 static const enum index item_raw[] = { 1703 ITEM_RAW_RELATIVE, 1704 ITEM_RAW_SEARCH, 1705 ITEM_RAW_OFFSET, 1706 ITEM_RAW_LIMIT, 1707 ITEM_RAW_PATTERN, 1708 ITEM_RAW_PATTERN_HEX, 1709 ITEM_NEXT, 1710 ZERO, 1711 }; 1712 1713 static const enum index item_eth[] = { 1714 ITEM_ETH_DST, 1715 ITEM_ETH_SRC, 1716 ITEM_ETH_TYPE, 1717 ITEM_ETH_HAS_VLAN, 1718 ITEM_NEXT, 1719 ZERO, 1720 }; 1721 1722 static const enum index item_vlan[] = { 1723 ITEM_VLAN_TCI, 1724 ITEM_VLAN_PCP, 1725 ITEM_VLAN_DEI, 1726 ITEM_VLAN_VID, 1727 ITEM_VLAN_INNER_TYPE, 1728 ITEM_VLAN_HAS_MORE_VLAN, 1729 ITEM_NEXT, 1730 ZERO, 1731 }; 1732 1733 static const enum index item_ipv4[] = { 1734 ITEM_IPV4_VER_IHL, 1735 ITEM_IPV4_TOS, 1736 ITEM_IPV4_LENGTH, 1737 ITEM_IPV4_ID, 1738 ITEM_IPV4_FRAGMENT_OFFSET, 1739 ITEM_IPV4_TTL, 1740 ITEM_IPV4_PROTO, 1741 ITEM_IPV4_SRC, 1742 ITEM_IPV4_DST, 1743 ITEM_NEXT, 1744 ZERO, 1745 }; 1746 1747 static const enum index item_ipv6[] = { 1748 ITEM_IPV6_TC, 1749 ITEM_IPV6_FLOW, 1750 ITEM_IPV6_LEN, 1751 ITEM_IPV6_PROTO, 1752 ITEM_IPV6_HOP, 1753 ITEM_IPV6_SRC, 1754 ITEM_IPV6_DST, 1755 ITEM_IPV6_HAS_FRAG_EXT, 1756 ITEM_IPV6_ROUTING_EXT, 1757 ITEM_NEXT, 1758 ZERO, 1759 }; 1760 1761 static const enum index item_ipv6_routing_ext[] = { 1762 ITEM_IPV6_ROUTING_EXT_TYPE, 1763 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 1764 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 1765 ITEM_NEXT, 1766 ZERO, 1767 }; 1768 1769 static const enum index item_icmp[] = { 1770 ITEM_ICMP_TYPE, 1771 ITEM_ICMP_CODE, 1772 ITEM_ICMP_IDENT, 1773 ITEM_ICMP_SEQ, 1774 ITEM_NEXT, 1775 ZERO, 1776 }; 1777 1778 static const enum index item_udp[] = { 1779 ITEM_UDP_SRC, 1780 ITEM_UDP_DST, 1781 ITEM_NEXT, 1782 ZERO, 1783 }; 1784 1785 static const enum index item_tcp[] = { 1786 ITEM_TCP_SRC, 1787 ITEM_TCP_DST, 1788 ITEM_TCP_FLAGS, 1789 ITEM_NEXT, 1790 ZERO, 1791 }; 1792 1793 static const enum index item_sctp[] = { 1794 ITEM_SCTP_SRC, 1795 ITEM_SCTP_DST, 1796 ITEM_SCTP_TAG, 1797 ITEM_SCTP_CKSUM, 1798 ITEM_NEXT, 1799 ZERO, 1800 }; 1801 1802 static const enum index item_vxlan[] = { 1803 ITEM_VXLAN_VNI, 1804 ITEM_VXLAN_FLAG_G, 1805 ITEM_VXLAN_FLAG_VER, 1806 ITEM_VXLAN_FLAG_I, 1807 ITEM_VXLAN_FLAG_P, 1808 ITEM_VXLAN_FLAG_B, 1809 ITEM_VXLAN_FLAG_O, 1810 ITEM_VXLAN_FLAG_D, 1811 ITEM_VXLAN_FLAG_A, 1812 ITEM_VXLAN_GBP_ID, 1813 ITEM_VXLAN_GPE_PROTO, 1814 ITEM_VXLAN_FIRST_RSVD, 1815 ITEM_VXLAN_SECND_RSVD, 1816 ITEM_VXLAN_THIRD_RSVD, 1817 ITEM_VXLAN_LAST_RSVD, 1818 ITEM_NEXT, 1819 ZERO, 1820 }; 1821 1822 static const enum index item_e_tag[] = { 1823 ITEM_E_TAG_GRP_ECID_B, 1824 ITEM_NEXT, 1825 ZERO, 1826 }; 1827 1828 static const enum index item_nvgre[] = { 1829 ITEM_NVGRE_TNI, 1830 ITEM_NEXT, 1831 ZERO, 1832 }; 1833 1834 static const enum index item_mpls[] = { 1835 ITEM_MPLS_LABEL, 1836 ITEM_MPLS_TC, 1837 ITEM_MPLS_S, 1838 ITEM_MPLS_TTL, 1839 ITEM_NEXT, 1840 ZERO, 1841 }; 1842 1843 static const enum index item_gre[] = { 1844 ITEM_GRE_PROTO, 1845 ITEM_GRE_C_RSVD0_VER, 1846 ITEM_GRE_C_BIT, 1847 ITEM_GRE_K_BIT, 1848 ITEM_GRE_S_BIT, 1849 ITEM_NEXT, 1850 ZERO, 1851 }; 1852 1853 static const enum index item_gre_key[] = { 1854 ITEM_GRE_KEY_VALUE, 1855 ITEM_NEXT, 1856 ZERO, 1857 }; 1858 1859 static const enum index item_gre_option[] = { 1860 ITEM_GRE_OPTION_CHECKSUM, 1861 ITEM_GRE_OPTION_KEY, 1862 ITEM_GRE_OPTION_SEQUENCE, 1863 ITEM_NEXT, 1864 ZERO, 1865 }; 1866 1867 static const enum index item_gtp[] = { 1868 ITEM_GTP_FLAGS, 1869 ITEM_GTP_MSG_TYPE, 1870 ITEM_GTP_TEID, 1871 ITEM_NEXT, 1872 ZERO, 1873 }; 1874 1875 static const enum index item_geneve[] = { 1876 ITEM_GENEVE_VNI, 1877 ITEM_GENEVE_PROTO, 1878 ITEM_GENEVE_OPTLEN, 1879 ITEM_NEXT, 1880 ZERO, 1881 }; 1882 1883 static const enum index item_vxlan_gpe[] = { 1884 ITEM_VXLAN_GPE_VNI, 1885 ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR, 1886 ITEM_VXLAN_GPE_FLAGS, 1887 ITEM_VXLAN_GPE_RSVD0, 1888 ITEM_VXLAN_GPE_RSVD1, 1889 ITEM_NEXT, 1890 ZERO, 1891 }; 1892 1893 static const enum index item_arp_eth_ipv4[] = { 1894 ITEM_ARP_ETH_IPV4_SHA, 1895 ITEM_ARP_ETH_IPV4_SPA, 1896 ITEM_ARP_ETH_IPV4_THA, 1897 ITEM_ARP_ETH_IPV4_TPA, 1898 ITEM_NEXT, 1899 ZERO, 1900 }; 1901 1902 static const enum index item_ipv6_ext[] = { 1903 ITEM_IPV6_EXT_NEXT_HDR, 1904 ITEM_NEXT, 1905 ZERO, 1906 }; 1907 1908 static const enum index item_ipv6_frag_ext[] = { 1909 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 1910 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 1911 ITEM_IPV6_FRAG_EXT_ID, 1912 ITEM_NEXT, 1913 ZERO, 1914 }; 1915 1916 static const enum index item_icmp6[] = { 1917 ITEM_ICMP6_TYPE, 1918 ITEM_ICMP6_CODE, 1919 ITEM_NEXT, 1920 ZERO, 1921 }; 1922 1923 static const enum index item_icmp6_echo_request[] = { 1924 ITEM_ICMP6_ECHO_REQUEST_ID, 1925 ITEM_ICMP6_ECHO_REQUEST_SEQ, 1926 ITEM_NEXT, 1927 ZERO, 1928 }; 1929 1930 static const enum index item_icmp6_echo_reply[] = { 1931 ITEM_ICMP6_ECHO_REPLY_ID, 1932 ITEM_ICMP6_ECHO_REPLY_SEQ, 1933 ITEM_NEXT, 1934 ZERO, 1935 }; 1936 1937 static const enum index item_icmp6_nd_ns[] = { 1938 ITEM_ICMP6_ND_NS_TARGET_ADDR, 1939 ITEM_NEXT, 1940 ZERO, 1941 }; 1942 1943 static const enum index item_icmp6_nd_na[] = { 1944 ITEM_ICMP6_ND_NA_TARGET_ADDR, 1945 ITEM_NEXT, 1946 ZERO, 1947 }; 1948 1949 static const enum index item_icmp6_nd_opt[] = { 1950 ITEM_ICMP6_ND_OPT_TYPE, 1951 ITEM_NEXT, 1952 ZERO, 1953 }; 1954 1955 static const enum index item_icmp6_nd_opt_sla_eth[] = { 1956 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 1957 ITEM_NEXT, 1958 ZERO, 1959 }; 1960 1961 static const enum index item_icmp6_nd_opt_tla_eth[] = { 1962 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 1963 ITEM_NEXT, 1964 ZERO, 1965 }; 1966 1967 static const enum index item_meta[] = { 1968 ITEM_META_DATA, 1969 ITEM_NEXT, 1970 ZERO, 1971 }; 1972 1973 static const enum index item_random[] = { 1974 ITEM_RANDOM_VALUE, 1975 ITEM_NEXT, 1976 ZERO, 1977 }; 1978 1979 static const enum index item_gtp_psc[] = { 1980 ITEM_GTP_PSC_QFI, 1981 ITEM_GTP_PSC_PDU_T, 1982 ITEM_NEXT, 1983 ZERO, 1984 }; 1985 1986 static const enum index item_pppoed[] = { 1987 ITEM_PPPOE_SEID, 1988 ITEM_NEXT, 1989 ZERO, 1990 }; 1991 1992 static const enum index item_pppoes[] = { 1993 ITEM_PPPOE_SEID, 1994 ITEM_NEXT, 1995 ZERO, 1996 }; 1997 1998 static const enum index item_pppoe_proto_id[] = { 1999 ITEM_NEXT, 2000 ZERO, 2001 }; 2002 2003 static const enum index item_higig2[] = { 2004 ITEM_HIGIG2_CLASSIFICATION, 2005 ITEM_HIGIG2_VID, 2006 ITEM_NEXT, 2007 ZERO, 2008 }; 2009 2010 static const enum index item_esp[] = { 2011 ITEM_ESP_SPI, 2012 ITEM_NEXT, 2013 ZERO, 2014 }; 2015 2016 static const enum index item_ah[] = { 2017 ITEM_AH_SPI, 2018 ITEM_NEXT, 2019 ZERO, 2020 }; 2021 2022 static const enum index item_pfcp[] = { 2023 ITEM_PFCP_S_FIELD, 2024 ITEM_PFCP_SEID, 2025 ITEM_NEXT, 2026 ZERO, 2027 }; 2028 2029 static const enum index next_set_raw[] = { 2030 SET_RAW_INDEX, 2031 ITEM_ETH, 2032 ZERO, 2033 }; 2034 2035 static const enum index item_tag[] = { 2036 ITEM_TAG_DATA, 2037 ITEM_TAG_INDEX, 2038 ITEM_NEXT, 2039 ZERO, 2040 }; 2041 2042 static const enum index item_l2tpv3oip[] = { 2043 ITEM_L2TPV3OIP_SESSION_ID, 2044 ITEM_NEXT, 2045 ZERO, 2046 }; 2047 2048 static const enum index item_ecpri[] = { 2049 ITEM_ECPRI_COMMON, 2050 ITEM_NEXT, 2051 ZERO, 2052 }; 2053 2054 static const enum index item_ecpri_common[] = { 2055 ITEM_ECPRI_COMMON_TYPE, 2056 ZERO, 2057 }; 2058 2059 static const enum index item_ecpri_common_type[] = { 2060 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 2061 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 2062 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 2063 ZERO, 2064 }; 2065 2066 static const enum index item_geneve_opt[] = { 2067 ITEM_GENEVE_OPT_CLASS, 2068 ITEM_GENEVE_OPT_TYPE, 2069 ITEM_GENEVE_OPT_LENGTH, 2070 ITEM_GENEVE_OPT_DATA, 2071 ITEM_NEXT, 2072 ZERO, 2073 }; 2074 2075 static const enum index item_integrity[] = { 2076 ITEM_INTEGRITY_LEVEL, 2077 ITEM_INTEGRITY_VALUE, 2078 ZERO, 2079 }; 2080 2081 static const enum index item_integrity_lv[] = { 2082 ITEM_INTEGRITY_LEVEL, 2083 ITEM_INTEGRITY_VALUE, 2084 ITEM_NEXT, 2085 ZERO, 2086 }; 2087 2088 static const enum index item_port_representor[] = { 2089 ITEM_PORT_REPRESENTOR_PORT_ID, 2090 ITEM_NEXT, 2091 ZERO, 2092 }; 2093 2094 static const enum index item_represented_port[] = { 2095 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 2096 ITEM_NEXT, 2097 ZERO, 2098 }; 2099 2100 static const enum index item_flex[] = { 2101 ITEM_FLEX_PATTERN_HANDLE, 2102 ITEM_FLEX_ITEM_HANDLE, 2103 ITEM_NEXT, 2104 ZERO, 2105 }; 2106 2107 static const enum index item_l2tpv2[] = { 2108 ITEM_L2TPV2_TYPE, 2109 ITEM_NEXT, 2110 ZERO, 2111 }; 2112 2113 static const enum index item_l2tpv2_type[] = { 2114 ITEM_L2TPV2_TYPE_DATA, 2115 ITEM_L2TPV2_TYPE_DATA_L, 2116 ITEM_L2TPV2_TYPE_DATA_S, 2117 ITEM_L2TPV2_TYPE_DATA_O, 2118 ITEM_L2TPV2_TYPE_DATA_L_S, 2119 ITEM_L2TPV2_TYPE_CTRL, 2120 ZERO, 2121 }; 2122 2123 static const enum index item_l2tpv2_type_data[] = { 2124 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 2125 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 2126 ITEM_NEXT, 2127 ZERO, 2128 }; 2129 2130 static const enum index item_l2tpv2_type_data_l[] = { 2131 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 2132 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 2133 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 2134 ITEM_NEXT, 2135 ZERO, 2136 }; 2137 2138 static const enum index item_l2tpv2_type_data_s[] = { 2139 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 2140 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 2141 ITEM_L2TPV2_MSG_DATA_S_NS, 2142 ITEM_L2TPV2_MSG_DATA_S_NR, 2143 ITEM_NEXT, 2144 ZERO, 2145 }; 2146 2147 static const enum index item_l2tpv2_type_data_o[] = { 2148 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 2149 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 2150 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 2151 ITEM_NEXT, 2152 ZERO, 2153 }; 2154 2155 static const enum index item_l2tpv2_type_data_l_s[] = { 2156 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 2157 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 2158 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 2159 ITEM_L2TPV2_MSG_DATA_L_S_NS, 2160 ITEM_L2TPV2_MSG_DATA_L_S_NR, 2161 ITEM_NEXT, 2162 ZERO, 2163 }; 2164 2165 static const enum index item_l2tpv2_type_ctrl[] = { 2166 ITEM_L2TPV2_MSG_CTRL_LENGTH, 2167 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 2168 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 2169 ITEM_L2TPV2_MSG_CTRL_NS, 2170 ITEM_L2TPV2_MSG_CTRL_NR, 2171 ITEM_NEXT, 2172 ZERO, 2173 }; 2174 2175 static const enum index item_ppp[] = { 2176 ITEM_PPP_ADDR, 2177 ITEM_PPP_CTRL, 2178 ITEM_PPP_PROTO_ID, 2179 ITEM_NEXT, 2180 ZERO, 2181 }; 2182 2183 static const enum index item_meter[] = { 2184 ITEM_METER_COLOR, 2185 ITEM_NEXT, 2186 ZERO, 2187 }; 2188 2189 static const enum index item_quota[] = { 2190 ITEM_QUOTA_STATE, 2191 ITEM_NEXT, 2192 ZERO, 2193 }; 2194 2195 static const enum index item_aggr_affinity[] = { 2196 ITEM_AGGR_AFFINITY_VALUE, 2197 ITEM_NEXT, 2198 ZERO, 2199 }; 2200 2201 static const enum index item_tx_queue[] = { 2202 ITEM_TX_QUEUE_VALUE, 2203 ITEM_NEXT, 2204 ZERO, 2205 }; 2206 2207 static const enum index item_ib_bth[] = { 2208 ITEM_IB_BTH_OPCODE, 2209 ITEM_IB_BTH_PKEY, 2210 ITEM_IB_BTH_DST_QPN, 2211 ITEM_IB_BTH_PSN, 2212 ITEM_NEXT, 2213 ZERO, 2214 }; 2215 2216 static const enum index item_ptype[] = { 2217 ITEM_PTYPE_VALUE, 2218 ITEM_NEXT, 2219 ZERO, 2220 }; 2221 2222 static const enum index item_nsh[] = { 2223 ITEM_NEXT, 2224 ZERO, 2225 }; 2226 2227 static const enum index item_compare_field[] = { 2228 ITEM_COMPARE_OP, 2229 ITEM_COMPARE_FIELD_A_TYPE, 2230 ITEM_COMPARE_FIELD_B_TYPE, 2231 ITEM_NEXT, 2232 ZERO, 2233 }; 2234 2235 static const enum index compare_field_a[] = { 2236 ITEM_COMPARE_FIELD_A_TYPE, 2237 ITEM_COMPARE_FIELD_A_LEVEL, 2238 ITEM_COMPARE_FIELD_A_TAG_INDEX, 2239 ITEM_COMPARE_FIELD_A_TYPE_ID, 2240 ITEM_COMPARE_FIELD_A_CLASS_ID, 2241 ITEM_COMPARE_FIELD_A_OFFSET, 2242 ITEM_COMPARE_FIELD_B_TYPE, 2243 ZERO, 2244 }; 2245 2246 static const enum index compare_field_b[] = { 2247 ITEM_COMPARE_FIELD_B_TYPE, 2248 ITEM_COMPARE_FIELD_B_LEVEL, 2249 ITEM_COMPARE_FIELD_B_TAG_INDEX, 2250 ITEM_COMPARE_FIELD_B_TYPE_ID, 2251 ITEM_COMPARE_FIELD_B_CLASS_ID, 2252 ITEM_COMPARE_FIELD_B_OFFSET, 2253 ITEM_COMPARE_FIELD_B_VALUE, 2254 ITEM_COMPARE_FIELD_B_POINTER, 2255 ITEM_COMPARE_FIELD_WIDTH, 2256 ZERO, 2257 }; 2258 2259 static const enum index next_action[] = { 2260 ACTION_END, 2261 ACTION_VOID, 2262 ACTION_PASSTHRU, 2263 ACTION_SKIP_CMAN, 2264 ACTION_JUMP, 2265 ACTION_MARK, 2266 ACTION_FLAG, 2267 ACTION_QUEUE, 2268 ACTION_DROP, 2269 ACTION_COUNT, 2270 ACTION_RSS, 2271 ACTION_PF, 2272 ACTION_VF, 2273 ACTION_PORT_ID, 2274 ACTION_METER, 2275 ACTION_METER_COLOR, 2276 ACTION_METER_MARK, 2277 ACTION_OF_DEC_NW_TTL, 2278 ACTION_OF_POP_VLAN, 2279 ACTION_OF_PUSH_VLAN, 2280 ACTION_OF_SET_VLAN_VID, 2281 ACTION_OF_SET_VLAN_PCP, 2282 ACTION_OF_POP_MPLS, 2283 ACTION_OF_PUSH_MPLS, 2284 ACTION_VXLAN_ENCAP, 2285 ACTION_VXLAN_DECAP, 2286 ACTION_NVGRE_ENCAP, 2287 ACTION_NVGRE_DECAP, 2288 ACTION_L2_ENCAP, 2289 ACTION_L2_DECAP, 2290 ACTION_MPLSOGRE_ENCAP, 2291 ACTION_MPLSOGRE_DECAP, 2292 ACTION_MPLSOUDP_ENCAP, 2293 ACTION_MPLSOUDP_DECAP, 2294 ACTION_SET_IPV4_SRC, 2295 ACTION_SET_IPV4_DST, 2296 ACTION_SET_IPV6_SRC, 2297 ACTION_SET_IPV6_DST, 2298 ACTION_SET_TP_SRC, 2299 ACTION_SET_TP_DST, 2300 ACTION_MAC_SWAP, 2301 ACTION_DEC_TTL, 2302 ACTION_SET_TTL, 2303 ACTION_SET_MAC_SRC, 2304 ACTION_SET_MAC_DST, 2305 ACTION_INC_TCP_SEQ, 2306 ACTION_DEC_TCP_SEQ, 2307 ACTION_INC_TCP_ACK, 2308 ACTION_DEC_TCP_ACK, 2309 ACTION_RAW_ENCAP, 2310 ACTION_RAW_DECAP, 2311 ACTION_SET_TAG, 2312 ACTION_SET_META, 2313 ACTION_SET_IPV4_DSCP, 2314 ACTION_SET_IPV6_DSCP, 2315 ACTION_AGE, 2316 ACTION_AGE_UPDATE, 2317 ACTION_SAMPLE, 2318 ACTION_INDIRECT, 2319 ACTION_INDIRECT_LIST, 2320 ACTION_SHARED_INDIRECT, 2321 ACTION_MODIFY_FIELD, 2322 ACTION_CONNTRACK, 2323 ACTION_CONNTRACK_UPDATE, 2324 ACTION_PORT_REPRESENTOR, 2325 ACTION_REPRESENTED_PORT, 2326 ACTION_SEND_TO_KERNEL, 2327 ACTION_QUOTA_CREATE, 2328 ACTION_QUOTA_QU, 2329 ACTION_IPV6_EXT_REMOVE, 2330 ACTION_IPV6_EXT_PUSH, 2331 ACTION_NAT64, 2332 ACTION_JUMP_TO_TABLE_INDEX, 2333 ZERO, 2334 }; 2335 2336 static const enum index action_quota_create[] = { 2337 ACTION_QUOTA_CREATE_LIMIT, 2338 ACTION_QUOTA_CREATE_MODE, 2339 ACTION_NEXT, 2340 ZERO 2341 }; 2342 2343 static const enum index action_quota_update[] = { 2344 ACTION_QUOTA_QU_LIMIT, 2345 ACTION_QUOTA_QU_UPDATE_OP, 2346 ACTION_NEXT, 2347 ZERO 2348 }; 2349 2350 static const enum index action_mark[] = { 2351 ACTION_MARK_ID, 2352 ACTION_NEXT, 2353 ZERO, 2354 }; 2355 2356 static const enum index action_queue[] = { 2357 ACTION_QUEUE_INDEX, 2358 ACTION_NEXT, 2359 ZERO, 2360 }; 2361 2362 static const enum index action_count[] = { 2363 ACTION_COUNT_ID, 2364 ACTION_NEXT, 2365 ZERO, 2366 }; 2367 2368 static const enum index action_rss[] = { 2369 ACTION_RSS_FUNC, 2370 ACTION_RSS_LEVEL, 2371 ACTION_RSS_TYPES, 2372 ACTION_RSS_KEY, 2373 ACTION_RSS_KEY_LEN, 2374 ACTION_RSS_QUEUES, 2375 ACTION_NEXT, 2376 ZERO, 2377 }; 2378 2379 static const enum index action_vf[] = { 2380 ACTION_VF_ORIGINAL, 2381 ACTION_VF_ID, 2382 ACTION_NEXT, 2383 ZERO, 2384 }; 2385 2386 static const enum index action_port_id[] = { 2387 ACTION_PORT_ID_ORIGINAL, 2388 ACTION_PORT_ID_ID, 2389 ACTION_NEXT, 2390 ZERO, 2391 }; 2392 2393 static const enum index action_meter[] = { 2394 ACTION_METER_ID, 2395 ACTION_NEXT, 2396 ZERO, 2397 }; 2398 2399 static const enum index action_meter_color[] = { 2400 ACTION_METER_COLOR_TYPE, 2401 ACTION_NEXT, 2402 ZERO, 2403 }; 2404 2405 static const enum index action_meter_mark[] = { 2406 ACTION_METER_PROFILE, 2407 ACTION_METER_POLICY, 2408 ACTION_METER_COLOR_MODE, 2409 ACTION_METER_STATE, 2410 ACTION_NEXT, 2411 ZERO, 2412 }; 2413 2414 static const enum index action_of_push_vlan[] = { 2415 ACTION_OF_PUSH_VLAN_ETHERTYPE, 2416 ACTION_NEXT, 2417 ZERO, 2418 }; 2419 2420 static const enum index action_of_set_vlan_vid[] = { 2421 ACTION_OF_SET_VLAN_VID_VLAN_VID, 2422 ACTION_NEXT, 2423 ZERO, 2424 }; 2425 2426 static const enum index action_of_set_vlan_pcp[] = { 2427 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 2428 ACTION_NEXT, 2429 ZERO, 2430 }; 2431 2432 static const enum index action_of_pop_mpls[] = { 2433 ACTION_OF_POP_MPLS_ETHERTYPE, 2434 ACTION_NEXT, 2435 ZERO, 2436 }; 2437 2438 static const enum index action_of_push_mpls[] = { 2439 ACTION_OF_PUSH_MPLS_ETHERTYPE, 2440 ACTION_NEXT, 2441 ZERO, 2442 }; 2443 2444 static const enum index action_set_ipv4_src[] = { 2445 ACTION_SET_IPV4_SRC_IPV4_SRC, 2446 ACTION_NEXT, 2447 ZERO, 2448 }; 2449 2450 static const enum index action_set_mac_src[] = { 2451 ACTION_SET_MAC_SRC_MAC_SRC, 2452 ACTION_NEXT, 2453 ZERO, 2454 }; 2455 2456 static const enum index action_set_ipv4_dst[] = { 2457 ACTION_SET_IPV4_DST_IPV4_DST, 2458 ACTION_NEXT, 2459 ZERO, 2460 }; 2461 2462 static const enum index action_set_ipv6_src[] = { 2463 ACTION_SET_IPV6_SRC_IPV6_SRC, 2464 ACTION_NEXT, 2465 ZERO, 2466 }; 2467 2468 static const enum index action_set_ipv6_dst[] = { 2469 ACTION_SET_IPV6_DST_IPV6_DST, 2470 ACTION_NEXT, 2471 ZERO, 2472 }; 2473 2474 static const enum index action_set_tp_src[] = { 2475 ACTION_SET_TP_SRC_TP_SRC, 2476 ACTION_NEXT, 2477 ZERO, 2478 }; 2479 2480 static const enum index action_set_tp_dst[] = { 2481 ACTION_SET_TP_DST_TP_DST, 2482 ACTION_NEXT, 2483 ZERO, 2484 }; 2485 2486 static const enum index action_set_ttl[] = { 2487 ACTION_SET_TTL_TTL, 2488 ACTION_NEXT, 2489 ZERO, 2490 }; 2491 2492 static const enum index action_jump[] = { 2493 ACTION_JUMP_GROUP, 2494 ACTION_NEXT, 2495 ZERO, 2496 }; 2497 2498 static const enum index action_set_mac_dst[] = { 2499 ACTION_SET_MAC_DST_MAC_DST, 2500 ACTION_NEXT, 2501 ZERO, 2502 }; 2503 2504 static const enum index action_inc_tcp_seq[] = { 2505 ACTION_INC_TCP_SEQ_VALUE, 2506 ACTION_NEXT, 2507 ZERO, 2508 }; 2509 2510 static const enum index action_dec_tcp_seq[] = { 2511 ACTION_DEC_TCP_SEQ_VALUE, 2512 ACTION_NEXT, 2513 ZERO, 2514 }; 2515 2516 static const enum index action_inc_tcp_ack[] = { 2517 ACTION_INC_TCP_ACK_VALUE, 2518 ACTION_NEXT, 2519 ZERO, 2520 }; 2521 2522 static const enum index action_dec_tcp_ack[] = { 2523 ACTION_DEC_TCP_ACK_VALUE, 2524 ACTION_NEXT, 2525 ZERO, 2526 }; 2527 2528 static const enum index action_raw_encap[] = { 2529 ACTION_RAW_ENCAP_SIZE, 2530 ACTION_RAW_ENCAP_INDEX, 2531 ACTION_NEXT, 2532 ZERO, 2533 }; 2534 2535 static const enum index action_raw_decap[] = { 2536 ACTION_RAW_DECAP_INDEX, 2537 ACTION_NEXT, 2538 ZERO, 2539 }; 2540 2541 static const enum index action_ipv6_ext_remove[] = { 2542 ACTION_IPV6_EXT_REMOVE_INDEX, 2543 ACTION_NEXT, 2544 ZERO, 2545 }; 2546 2547 static const enum index action_ipv6_ext_push[] = { 2548 ACTION_IPV6_EXT_PUSH_INDEX, 2549 ACTION_NEXT, 2550 ZERO, 2551 }; 2552 2553 static const enum index action_set_tag[] = { 2554 ACTION_SET_TAG_DATA, 2555 ACTION_SET_TAG_INDEX, 2556 ACTION_SET_TAG_MASK, 2557 ACTION_NEXT, 2558 ZERO, 2559 }; 2560 2561 static const enum index action_set_meta[] = { 2562 ACTION_SET_META_DATA, 2563 ACTION_SET_META_MASK, 2564 ACTION_NEXT, 2565 ZERO, 2566 }; 2567 2568 static const enum index action_set_ipv4_dscp[] = { 2569 ACTION_SET_IPV4_DSCP_VALUE, 2570 ACTION_NEXT, 2571 ZERO, 2572 }; 2573 2574 static const enum index action_set_ipv6_dscp[] = { 2575 ACTION_SET_IPV6_DSCP_VALUE, 2576 ACTION_NEXT, 2577 ZERO, 2578 }; 2579 2580 static const enum index action_age[] = { 2581 ACTION_AGE, 2582 ACTION_AGE_TIMEOUT, 2583 ACTION_NEXT, 2584 ZERO, 2585 }; 2586 2587 static const enum index action_age_update[] = { 2588 ACTION_AGE_UPDATE, 2589 ACTION_AGE_UPDATE_TIMEOUT, 2590 ACTION_AGE_UPDATE_TOUCH, 2591 ACTION_NEXT, 2592 ZERO, 2593 }; 2594 2595 static const enum index action_sample[] = { 2596 ACTION_SAMPLE, 2597 ACTION_SAMPLE_RATIO, 2598 ACTION_SAMPLE_INDEX, 2599 ACTION_NEXT, 2600 ZERO, 2601 }; 2602 2603 static const enum index next_action_sample[] = { 2604 ACTION_QUEUE, 2605 ACTION_RSS, 2606 ACTION_MARK, 2607 ACTION_COUNT, 2608 ACTION_PORT_ID, 2609 ACTION_RAW_ENCAP, 2610 ACTION_VXLAN_ENCAP, 2611 ACTION_NVGRE_ENCAP, 2612 ACTION_REPRESENTED_PORT, 2613 ACTION_PORT_REPRESENTOR, 2614 ACTION_NEXT, 2615 ZERO, 2616 }; 2617 2618 static const enum index item_ipv6_push_ext[] = { 2619 ITEM_IPV6_PUSH_REMOVE_EXT, 2620 ZERO, 2621 }; 2622 2623 static const enum index item_ipv6_push_ext_type[] = { 2624 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 2625 ZERO, 2626 }; 2627 2628 static const enum index item_ipv6_push_ext_header[] = { 2629 ITEM_IPV6_ROUTING_EXT, 2630 ITEM_NEXT, 2631 ZERO, 2632 }; 2633 2634 static const enum index action_modify_field_dst[] = { 2635 ACTION_MODIFY_FIELD_DST_LEVEL, 2636 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 2637 ACTION_MODIFY_FIELD_DST_TYPE_ID, 2638 ACTION_MODIFY_FIELD_DST_CLASS_ID, 2639 ACTION_MODIFY_FIELD_DST_OFFSET, 2640 ACTION_MODIFY_FIELD_SRC_TYPE, 2641 ZERO, 2642 }; 2643 2644 static const enum index action_modify_field_src[] = { 2645 ACTION_MODIFY_FIELD_SRC_LEVEL, 2646 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 2647 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 2648 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 2649 ACTION_MODIFY_FIELD_SRC_OFFSET, 2650 ACTION_MODIFY_FIELD_SRC_VALUE, 2651 ACTION_MODIFY_FIELD_SRC_POINTER, 2652 ACTION_MODIFY_FIELD_WIDTH, 2653 ZERO, 2654 }; 2655 2656 static const enum index action_update_conntrack[] = { 2657 ACTION_CONNTRACK_UPDATE_DIR, 2658 ACTION_CONNTRACK_UPDATE_CTX, 2659 ACTION_NEXT, 2660 ZERO, 2661 }; 2662 2663 static const enum index action_port_representor[] = { 2664 ACTION_PORT_REPRESENTOR_PORT_ID, 2665 ACTION_NEXT, 2666 ZERO, 2667 }; 2668 2669 static const enum index action_represented_port[] = { 2670 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 2671 ACTION_NEXT, 2672 ZERO, 2673 }; 2674 2675 static const enum index action_nat64[] = { 2676 ACTION_NAT64_MODE, 2677 ACTION_NEXT, 2678 ZERO, 2679 }; 2680 2681 static const enum index next_hash_subcmd[] = { 2682 HASH_CALC_TABLE, 2683 HASH_CALC_ENCAP, 2684 ZERO, 2685 }; 2686 2687 static const enum index next_hash_encap_dest_subcmd[] = { 2688 ENCAP_HASH_FIELD_SRC_PORT, 2689 ENCAP_HASH_FIELD_GRE_FLOW_ID, 2690 ZERO, 2691 }; 2692 2693 static const enum index action_jump_to_table_index[] = { 2694 ACTION_JUMP_TO_TABLE_INDEX_TABLE, 2695 ACTION_JUMP_TO_TABLE_INDEX_INDEX, 2696 ACTION_NEXT, 2697 ZERO, 2698 }; 2699 2700 static int parse_set_raw_encap_decap(struct context *, const struct token *, 2701 const char *, unsigned int, 2702 void *, unsigned int); 2703 static int parse_set_sample_action(struct context *, const struct token *, 2704 const char *, unsigned int, 2705 void *, unsigned int); 2706 static int parse_set_ipv6_ext_action(struct context *, const struct token *, 2707 const char *, unsigned int, 2708 void *, unsigned int); 2709 static int parse_set_init(struct context *, const struct token *, 2710 const char *, unsigned int, 2711 void *, unsigned int); 2712 static int 2713 parse_flex_handle(struct context *, const struct token *, 2714 const char *, unsigned int, void *, unsigned int); 2715 static int parse_init(struct context *, const struct token *, 2716 const char *, unsigned int, 2717 void *, unsigned int); 2718 static int parse_vc(struct context *, const struct token *, 2719 const char *, unsigned int, 2720 void *, unsigned int); 2721 static int parse_vc_spec(struct context *, const struct token *, 2722 const char *, unsigned int, void *, unsigned int); 2723 static int parse_vc_conf(struct context *, const struct token *, 2724 const char *, unsigned int, void *, unsigned int); 2725 static int parse_vc_conf_timeout(struct context *, const struct token *, 2726 const char *, unsigned int, void *, 2727 unsigned int); 2728 static int parse_vc_item_ecpri_type(struct context *, const struct token *, 2729 const char *, unsigned int, 2730 void *, unsigned int); 2731 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, 2732 const char *, unsigned int, 2733 void *, unsigned int); 2734 static int parse_vc_action_meter_color_type(struct context *, 2735 const struct token *, 2736 const char *, unsigned int, void *, 2737 unsigned int); 2738 static int parse_vc_action_rss(struct context *, const struct token *, 2739 const char *, unsigned int, void *, 2740 unsigned int); 2741 static int parse_vc_action_rss_func(struct context *, const struct token *, 2742 const char *, unsigned int, void *, 2743 unsigned int); 2744 static int parse_vc_action_rss_type(struct context *, const struct token *, 2745 const char *, unsigned int, void *, 2746 unsigned int); 2747 static int parse_vc_action_rss_queue(struct context *, const struct token *, 2748 const char *, unsigned int, void *, 2749 unsigned int); 2750 static int parse_vc_action_vxlan_encap(struct context *, const struct token *, 2751 const char *, unsigned int, void *, 2752 unsigned int); 2753 static int parse_vc_action_nvgre_encap(struct context *, const struct token *, 2754 const char *, unsigned int, void *, 2755 unsigned int); 2756 static int parse_vc_action_l2_encap(struct context *, const struct token *, 2757 const char *, unsigned int, void *, 2758 unsigned int); 2759 static int parse_vc_action_l2_decap(struct context *, const struct token *, 2760 const char *, unsigned int, void *, 2761 unsigned int); 2762 static int parse_vc_action_mplsogre_encap(struct context *, 2763 const struct token *, const char *, 2764 unsigned int, void *, unsigned int); 2765 static int parse_vc_action_mplsogre_decap(struct context *, 2766 const struct token *, const char *, 2767 unsigned int, void *, unsigned int); 2768 static int parse_vc_action_mplsoudp_encap(struct context *, 2769 const struct token *, const char *, 2770 unsigned int, void *, unsigned int); 2771 static int parse_vc_action_mplsoudp_decap(struct context *, 2772 const struct token *, const char *, 2773 unsigned int, void *, unsigned int); 2774 static int parse_vc_action_raw_encap(struct context *, 2775 const struct token *, const char *, 2776 unsigned int, void *, unsigned int); 2777 static int parse_vc_action_raw_decap(struct context *, 2778 const struct token *, const char *, 2779 unsigned int, void *, unsigned int); 2780 static int parse_vc_action_raw_encap_index(struct context *, 2781 const struct token *, const char *, 2782 unsigned int, void *, unsigned int); 2783 static int parse_vc_action_raw_decap_index(struct context *, 2784 const struct token *, const char *, 2785 unsigned int, void *, unsigned int); 2786 static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 2787 const char *str, unsigned int len, void *buf, 2788 unsigned int size); 2789 static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, 2790 const struct token *token, 2791 const char *str, unsigned int len, 2792 void *buf, 2793 unsigned int size); 2794 static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 2795 const char *str, unsigned int len, void *buf, 2796 unsigned int size); 2797 static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, 2798 const struct token *token, 2799 const char *str, unsigned int len, 2800 void *buf, 2801 unsigned int size); 2802 static int parse_vc_action_set_meta(struct context *ctx, 2803 const struct token *token, const char *str, 2804 unsigned int len, void *buf, 2805 unsigned int size); 2806 static int parse_vc_action_sample(struct context *ctx, 2807 const struct token *token, const char *str, 2808 unsigned int len, void *buf, 2809 unsigned int size); 2810 static int 2811 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 2812 const char *str, unsigned int len, void *buf, 2813 unsigned int size); 2814 static int 2815 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 2816 const char *str, unsigned int len, void *buf, 2817 unsigned int size); 2818 static int 2819 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 2820 const char *str, unsigned int len, void *buf, 2821 unsigned int size); 2822 static int 2823 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 2824 const char *str, unsigned int len, void *buf, 2825 unsigned int size); 2826 static int 2827 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 2828 const char *str, unsigned int len, void *buf, 2829 unsigned int size); 2830 static int parse_destroy(struct context *, const struct token *, 2831 const char *, unsigned int, 2832 void *, unsigned int); 2833 static int parse_flush(struct context *, const struct token *, 2834 const char *, unsigned int, 2835 void *, unsigned int); 2836 static int parse_dump(struct context *, const struct token *, 2837 const char *, unsigned int, 2838 void *, unsigned int); 2839 static int parse_query(struct context *, const struct token *, 2840 const char *, unsigned int, 2841 void *, unsigned int); 2842 static int parse_action(struct context *, const struct token *, 2843 const char *, unsigned int, 2844 void *, unsigned int); 2845 static int parse_list(struct context *, const struct token *, 2846 const char *, unsigned int, 2847 void *, unsigned int); 2848 static int parse_aged(struct context *, const struct token *, 2849 const char *, unsigned int, 2850 void *, unsigned int); 2851 static int parse_isolate(struct context *, const struct token *, 2852 const char *, unsigned int, 2853 void *, unsigned int); 2854 static int parse_configure(struct context *, const struct token *, 2855 const char *, unsigned int, 2856 void *, unsigned int); 2857 static int parse_template(struct context *, const struct token *, 2858 const char *, unsigned int, 2859 void *, unsigned int); 2860 static int parse_template_destroy(struct context *, const struct token *, 2861 const char *, unsigned int, 2862 void *, unsigned int); 2863 static int parse_table(struct context *, const struct token *, 2864 const char *, unsigned int, void *, unsigned int); 2865 static int parse_table_destroy(struct context *, const struct token *, 2866 const char *, unsigned int, 2867 void *, unsigned int); 2868 static int parse_qo(struct context *, const struct token *, 2869 const char *, unsigned int, 2870 void *, unsigned int); 2871 static int parse_qo_destroy(struct context *, const struct token *, 2872 const char *, unsigned int, 2873 void *, unsigned int); 2874 static int parse_qia(struct context *, const struct token *, 2875 const char *, unsigned int, 2876 void *, unsigned int); 2877 static int parse_qia_destroy(struct context *, const struct token *, 2878 const char *, unsigned int, 2879 void *, unsigned int); 2880 static int parse_push(struct context *, const struct token *, 2881 const char *, unsigned int, 2882 void *, unsigned int); 2883 static int parse_pull(struct context *, const struct token *, 2884 const char *, unsigned int, 2885 void *, unsigned int); 2886 static int parse_group(struct context *, const struct token *, 2887 const char *, unsigned int, 2888 void *, unsigned int); 2889 static int parse_hash(struct context *, const struct token *, 2890 const char *, unsigned int, 2891 void *, unsigned int); 2892 static int parse_tunnel(struct context *, const struct token *, 2893 const char *, unsigned int, 2894 void *, unsigned int); 2895 static int parse_flex(struct context *, const struct token *, 2896 const char *, unsigned int, void *, unsigned int); 2897 static int parse_int(struct context *, const struct token *, 2898 const char *, unsigned int, 2899 void *, unsigned int); 2900 static int parse_prefix(struct context *, const struct token *, 2901 const char *, unsigned int, 2902 void *, unsigned int); 2903 static int parse_boolean(struct context *, const struct token *, 2904 const char *, unsigned int, 2905 void *, unsigned int); 2906 static int parse_string(struct context *, const struct token *, 2907 const char *, unsigned int, 2908 void *, unsigned int); 2909 static int parse_hex(struct context *ctx, const struct token *token, 2910 const char *str, unsigned int len, 2911 void *buf, unsigned int size); 2912 static int parse_string0(struct context *, const struct token *, 2913 const char *, unsigned int, 2914 void *, unsigned int); 2915 static int parse_mac_addr(struct context *, const struct token *, 2916 const char *, unsigned int, 2917 void *, unsigned int); 2918 static int parse_ipv4_addr(struct context *, const struct token *, 2919 const char *, unsigned int, 2920 void *, unsigned int); 2921 static int parse_ipv6_addr(struct context *, const struct token *, 2922 const char *, unsigned int, 2923 void *, unsigned int); 2924 static int parse_port(struct context *, const struct token *, 2925 const char *, unsigned int, 2926 void *, unsigned int); 2927 static int parse_ia(struct context *, const struct token *, 2928 const char *, unsigned int, 2929 void *, unsigned int); 2930 static int parse_ia_destroy(struct context *ctx, const struct token *token, 2931 const char *str, unsigned int len, 2932 void *buf, unsigned int size); 2933 static int parse_ia_id2ptr(struct context *ctx, const struct token *token, 2934 const char *str, unsigned int len, void *buf, 2935 unsigned int size); 2936 2937 static int parse_indlst_id2ptr(struct context *ctx, const struct token *token, 2938 const char *str, unsigned int len, void *buf, 2939 unsigned int size); 2940 static int parse_ia_port(struct context *ctx, const struct token *token, 2941 const char *str, unsigned int len, void *buf, 2942 unsigned int size); 2943 static int parse_mp(struct context *, const struct token *, 2944 const char *, unsigned int, 2945 void *, unsigned int); 2946 static int parse_meter_profile_id2ptr(struct context *ctx, 2947 const struct token *token, 2948 const char *str, unsigned int len, 2949 void *buf, unsigned int size); 2950 static int parse_meter_policy_id2ptr(struct context *ctx, 2951 const struct token *token, 2952 const char *str, unsigned int len, 2953 void *buf, unsigned int size); 2954 static int parse_meter_color(struct context *ctx, const struct token *token, 2955 const char *str, unsigned int len, void *buf, 2956 unsigned int size); 2957 static int parse_insertion_table_type(struct context *ctx, const struct token *token, 2958 const char *str, unsigned int len, void *buf, 2959 unsigned int size); 2960 static int parse_hash_table_type(struct context *ctx, const struct token *token, 2961 const char *str, unsigned int len, void *buf, 2962 unsigned int size); 2963 static int 2964 parse_quota_state_name(struct context *ctx, const struct token *token, 2965 const char *str, unsigned int len, void *buf, 2966 unsigned int size); 2967 static int 2968 parse_quota_mode_name(struct context *ctx, const struct token *token, 2969 const char *str, unsigned int len, void *buf, 2970 unsigned int size); 2971 static int 2972 parse_quota_update_name(struct context *ctx, const struct token *token, 2973 const char *str, unsigned int len, void *buf, 2974 unsigned int size); 2975 static int 2976 parse_qu_mode_name(struct context *ctx, const struct token *token, 2977 const char *str, unsigned int len, void *buf, 2978 unsigned int size); 2979 static int comp_none(struct context *, const struct token *, 2980 unsigned int, char *, unsigned int); 2981 static int comp_boolean(struct context *, const struct token *, 2982 unsigned int, char *, unsigned int); 2983 static int comp_action(struct context *, const struct token *, 2984 unsigned int, char *, unsigned int); 2985 static int comp_port(struct context *, const struct token *, 2986 unsigned int, char *, unsigned int); 2987 static int comp_rule_id(struct context *, const struct token *, 2988 unsigned int, char *, unsigned int); 2989 static int comp_vc_action_rss_type(struct context *, const struct token *, 2990 unsigned int, char *, unsigned int); 2991 static int comp_vc_action_rss_queue(struct context *, const struct token *, 2992 unsigned int, char *, unsigned int); 2993 static int comp_set_raw_index(struct context *, const struct token *, 2994 unsigned int, char *, unsigned int); 2995 static int comp_set_sample_index(struct context *, const struct token *, 2996 unsigned int, char *, unsigned int); 2997 static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 2998 unsigned int ent, char *buf, unsigned int size); 2999 static int comp_set_modify_field_op(struct context *, const struct token *, 3000 unsigned int, char *, unsigned int); 3001 static int comp_set_modify_field_id(struct context *, const struct token *, 3002 unsigned int, char *, unsigned int); 3003 static int comp_pattern_template_id(struct context *, const struct token *, 3004 unsigned int, char *, unsigned int); 3005 static int comp_actions_template_id(struct context *, const struct token *, 3006 unsigned int, char *, unsigned int); 3007 static int comp_table_id(struct context *, const struct token *, 3008 unsigned int, char *, unsigned int); 3009 static int comp_queue_id(struct context *, const struct token *, 3010 unsigned int, char *, unsigned int); 3011 static int comp_meter_color(struct context *, const struct token *, 3012 unsigned int, char *, unsigned int); 3013 static int comp_insertion_table_type(struct context *, const struct token *, 3014 unsigned int, char *, unsigned int); 3015 static int comp_hash_table_type(struct context *, const struct token *, 3016 unsigned int, char *, unsigned int); 3017 static int 3018 comp_quota_state_name(struct context *ctx, const struct token *token, 3019 unsigned int ent, char *buf, unsigned int size); 3020 static int 3021 comp_quota_mode_name(struct context *ctx, const struct token *token, 3022 unsigned int ent, char *buf, unsigned int size); 3023 static int 3024 comp_quota_update_name(struct context *ctx, const struct token *token, 3025 unsigned int ent, char *buf, unsigned int size); 3026 static int 3027 comp_qu_mode_name(struct context *ctx, const struct token *token, 3028 unsigned int ent, char *buf, unsigned int size); 3029 static int 3030 comp_set_compare_field_id(struct context *ctx, const struct token *token, 3031 unsigned int ent, char *buf, unsigned int size); 3032 static int 3033 comp_set_compare_op(struct context *ctx, const struct token *token, 3034 unsigned int ent, char *buf, unsigned int size); 3035 static int 3036 parse_vc_compare_op(struct context *ctx, const struct token *token, 3037 const char *str, unsigned int len, void *buf, 3038 unsigned int size); 3039 static int 3040 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 3041 const char *str, unsigned int len, void *buf, 3042 unsigned int size); 3043 static int 3044 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 3045 const char *str, unsigned int len, void *buf, 3046 unsigned int size); 3047 3048 struct indlst_conf { 3049 uint32_t id; 3050 uint32_t conf_num; 3051 struct rte_flow_action *actions; 3052 const void **conf; 3053 SLIST_ENTRY(indlst_conf) next; 3054 }; 3055 3056 static const struct indlst_conf *indirect_action_list_conf_get(uint32_t conf_id); 3057 3058 /** Token definitions. */ 3059 static const struct token token_list[] = { 3060 /* Special tokens. */ 3061 [ZERO] = { 3062 .name = "ZERO", 3063 .help = "null entry, abused as the entry point", 3064 .next = NEXT(NEXT_ENTRY(FLOW, ADD)), 3065 }, 3066 [END] = { 3067 .name = "", 3068 .type = "RETURN", 3069 .help = "command may end here", 3070 }, 3071 [START_SET] = { 3072 .name = "START_SET", 3073 .help = "null entry, abused as the entry point for set", 3074 .next = NEXT(NEXT_ENTRY(SET)), 3075 }, 3076 [END_SET] = { 3077 .name = "end_set", 3078 .type = "RETURN", 3079 .help = "set command may end here", 3080 }, 3081 /* Common tokens. */ 3082 [COMMON_INTEGER] = { 3083 .name = "{int}", 3084 .type = "INTEGER", 3085 .help = "integer value", 3086 .call = parse_int, 3087 .comp = comp_none, 3088 }, 3089 [COMMON_UNSIGNED] = { 3090 .name = "{unsigned}", 3091 .type = "UNSIGNED", 3092 .help = "unsigned integer value", 3093 .call = parse_int, 3094 .comp = comp_none, 3095 }, 3096 [COMMON_PREFIX] = { 3097 .name = "{prefix}", 3098 .type = "PREFIX", 3099 .help = "prefix length for bit-mask", 3100 .call = parse_prefix, 3101 .comp = comp_none, 3102 }, 3103 [COMMON_BOOLEAN] = { 3104 .name = "{boolean}", 3105 .type = "BOOLEAN", 3106 .help = "any boolean value", 3107 .call = parse_boolean, 3108 .comp = comp_boolean, 3109 }, 3110 [COMMON_STRING] = { 3111 .name = "{string}", 3112 .type = "STRING", 3113 .help = "fixed string", 3114 .call = parse_string, 3115 .comp = comp_none, 3116 }, 3117 [COMMON_HEX] = { 3118 .name = "{hex}", 3119 .type = "HEX", 3120 .help = "fixed string", 3121 .call = parse_hex, 3122 }, 3123 [COMMON_FILE_PATH] = { 3124 .name = "{file path}", 3125 .type = "STRING", 3126 .help = "file path", 3127 .call = parse_string0, 3128 .comp = comp_none, 3129 }, 3130 [COMMON_MAC_ADDR] = { 3131 .name = "{MAC address}", 3132 .type = "MAC-48", 3133 .help = "standard MAC address notation", 3134 .call = parse_mac_addr, 3135 .comp = comp_none, 3136 }, 3137 [COMMON_IPV4_ADDR] = { 3138 .name = "{IPv4 address}", 3139 .type = "IPV4 ADDRESS", 3140 .help = "standard IPv4 address notation", 3141 .call = parse_ipv4_addr, 3142 .comp = comp_none, 3143 }, 3144 [COMMON_IPV6_ADDR] = { 3145 .name = "{IPv6 address}", 3146 .type = "IPV6 ADDRESS", 3147 .help = "standard IPv6 address notation", 3148 .call = parse_ipv6_addr, 3149 .comp = comp_none, 3150 }, 3151 [COMMON_RULE_ID] = { 3152 .name = "{rule id}", 3153 .type = "RULE ID", 3154 .help = "rule identifier", 3155 .call = parse_int, 3156 .comp = comp_rule_id, 3157 }, 3158 [COMMON_PORT_ID] = { 3159 .name = "{port_id}", 3160 .type = "PORT ID", 3161 .help = "port identifier", 3162 .call = parse_port, 3163 .comp = comp_port, 3164 }, 3165 [COMMON_GROUP_ID] = { 3166 .name = "{group_id}", 3167 .type = "GROUP ID", 3168 .help = "group identifier", 3169 .call = parse_int, 3170 .comp = comp_none, 3171 }, 3172 [COMMON_PRIORITY_LEVEL] = { 3173 .name = "{level}", 3174 .type = "PRIORITY", 3175 .help = "priority level", 3176 .call = parse_int, 3177 .comp = comp_none, 3178 }, 3179 [COMMON_INDIRECT_ACTION_ID] = { 3180 .name = "{indirect_action_id}", 3181 .type = "INDIRECT_ACTION_ID", 3182 .help = "indirect action id", 3183 .call = parse_int, 3184 .comp = comp_none, 3185 }, 3186 [COMMON_PROFILE_ID] = { 3187 .name = "{profile_id}", 3188 .type = "PROFILE_ID", 3189 .help = "profile id", 3190 .call = parse_int, 3191 .comp = comp_none, 3192 }, 3193 [COMMON_POLICY_ID] = { 3194 .name = "{policy_id}", 3195 .type = "POLICY_ID", 3196 .help = "policy id", 3197 .call = parse_int, 3198 .comp = comp_none, 3199 }, 3200 [COMMON_FLEX_TOKEN] = { 3201 .name = "{flex token}", 3202 .type = "flex token", 3203 .help = "flex token", 3204 .call = parse_int, 3205 .comp = comp_none, 3206 }, 3207 [COMMON_FLEX_HANDLE] = { 3208 .name = "{flex handle}", 3209 .type = "FLEX HANDLE", 3210 .help = "fill flex item data", 3211 .call = parse_flex_handle, 3212 .comp = comp_none, 3213 }, 3214 [COMMON_PATTERN_TEMPLATE_ID] = { 3215 .name = "{pattern_template_id}", 3216 .type = "PATTERN_TEMPLATE_ID", 3217 .help = "pattern template id", 3218 .call = parse_int, 3219 .comp = comp_pattern_template_id, 3220 }, 3221 [COMMON_ACTIONS_TEMPLATE_ID] = { 3222 .name = "{actions_template_id}", 3223 .type = "ACTIONS_TEMPLATE_ID", 3224 .help = "actions template id", 3225 .call = parse_int, 3226 .comp = comp_actions_template_id, 3227 }, 3228 [COMMON_TABLE_ID] = { 3229 .name = "{table_id}", 3230 .type = "TABLE_ID", 3231 .help = "table id", 3232 .call = parse_int, 3233 .comp = comp_table_id, 3234 }, 3235 [COMMON_QUEUE_ID] = { 3236 .name = "{queue_id}", 3237 .type = "QUEUE_ID", 3238 .help = "queue id", 3239 .call = parse_int, 3240 .comp = comp_queue_id, 3241 }, 3242 /* Top-level command. */ 3243 [FLOW] = { 3244 .name = "flow", 3245 .type = "{command} {port_id} [{arg} [...]]", 3246 .help = "manage ingress/egress flow rules", 3247 .next = NEXT(NEXT_ENTRY 3248 (INFO, 3249 CONFIGURE, 3250 PATTERN_TEMPLATE, 3251 ACTIONS_TEMPLATE, 3252 TABLE, 3253 FLOW_GROUP, 3254 INDIRECT_ACTION, 3255 VALIDATE, 3256 CREATE, 3257 DESTROY, 3258 UPDATE, 3259 FLUSH, 3260 DUMP, 3261 LIST, 3262 AGED, 3263 QUERY, 3264 ISOLATE, 3265 TUNNEL, 3266 FLEX, 3267 QUEUE, 3268 PUSH, 3269 PULL, 3270 HASH)), 3271 .call = parse_init, 3272 }, 3273 /* Top-level command. */ 3274 [INFO] = { 3275 .name = "info", 3276 .help = "get information about flow engine", 3277 .next = NEXT(NEXT_ENTRY(END), 3278 NEXT_ENTRY(COMMON_PORT_ID)), 3279 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3280 .call = parse_configure, 3281 }, 3282 /* Top-level command. */ 3283 [CONFIGURE] = { 3284 .name = "configure", 3285 .help = "configure flow engine", 3286 .next = NEXT(next_config_attr, 3287 NEXT_ENTRY(COMMON_PORT_ID)), 3288 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3289 .call = parse_configure, 3290 }, 3291 /* Configure arguments. */ 3292 [CONFIG_QUEUES_NUMBER] = { 3293 .name = "queues_number", 3294 .help = "number of queues", 3295 .next = NEXT(next_config_attr, 3296 NEXT_ENTRY(COMMON_UNSIGNED)), 3297 .args = ARGS(ARGS_ENTRY(struct buffer, 3298 args.configure.nb_queue)), 3299 }, 3300 [CONFIG_QUEUES_SIZE] = { 3301 .name = "queues_size", 3302 .help = "number of elements in queues", 3303 .next = NEXT(next_config_attr, 3304 NEXT_ENTRY(COMMON_UNSIGNED)), 3305 .args = ARGS(ARGS_ENTRY(struct buffer, 3306 args.configure.queue_attr.size)), 3307 }, 3308 [CONFIG_COUNTERS_NUMBER] = { 3309 .name = "counters_number", 3310 .help = "number of counters", 3311 .next = NEXT(next_config_attr, 3312 NEXT_ENTRY(COMMON_UNSIGNED)), 3313 .args = ARGS(ARGS_ENTRY(struct buffer, 3314 args.configure.port_attr.nb_counters)), 3315 }, 3316 [CONFIG_AGING_OBJECTS_NUMBER] = { 3317 .name = "aging_counters_number", 3318 .help = "number of aging objects", 3319 .next = NEXT(next_config_attr, 3320 NEXT_ENTRY(COMMON_UNSIGNED)), 3321 .args = ARGS(ARGS_ENTRY(struct buffer, 3322 args.configure.port_attr.nb_aging_objects)), 3323 }, 3324 [CONFIG_QUOTAS_NUMBER] = { 3325 .name = "quotas_number", 3326 .help = "number of quotas", 3327 .next = NEXT(next_config_attr, 3328 NEXT_ENTRY(COMMON_UNSIGNED)), 3329 .args = ARGS(ARGS_ENTRY(struct buffer, 3330 args.configure.port_attr.nb_quotas)), 3331 }, 3332 [CONFIG_METERS_NUMBER] = { 3333 .name = "meters_number", 3334 .help = "number of meters", 3335 .next = NEXT(next_config_attr, 3336 NEXT_ENTRY(COMMON_UNSIGNED)), 3337 .args = ARGS(ARGS_ENTRY(struct buffer, 3338 args.configure.port_attr.nb_meters)), 3339 }, 3340 [CONFIG_CONN_TRACK_NUMBER] = { 3341 .name = "conn_tracks_number", 3342 .help = "number of connection trackings", 3343 .next = NEXT(next_config_attr, 3344 NEXT_ENTRY(COMMON_UNSIGNED)), 3345 .args = ARGS(ARGS_ENTRY(struct buffer, 3346 args.configure.port_attr.nb_conn_tracks)), 3347 }, 3348 [CONFIG_FLAGS] = { 3349 .name = "flags", 3350 .help = "configuration flags", 3351 .next = NEXT(next_config_attr, 3352 NEXT_ENTRY(COMMON_UNSIGNED)), 3353 .args = ARGS(ARGS_ENTRY(struct buffer, 3354 args.configure.port_attr.flags)), 3355 }, 3356 [CONFIG_HOST_PORT] = { 3357 .name = "host_port", 3358 .help = "host port for shared objects", 3359 .next = NEXT(next_config_attr, 3360 NEXT_ENTRY(COMMON_UNSIGNED)), 3361 .args = ARGS(ARGS_ENTRY(struct buffer, 3362 args.configure.port_attr.host_port_id)), 3363 }, 3364 /* Top-level command. */ 3365 [PATTERN_TEMPLATE] = { 3366 .name = "pattern_template", 3367 .type = "{command} {port_id} [{arg} [...]]", 3368 .help = "manage pattern templates", 3369 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3370 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3371 .call = parse_template, 3372 }, 3373 /* Sub-level commands. */ 3374 [PATTERN_TEMPLATE_CREATE] = { 3375 .name = "create", 3376 .help = "create pattern template", 3377 .next = NEXT(next_pt_attr), 3378 .call = parse_template, 3379 }, 3380 [PATTERN_TEMPLATE_DESTROY] = { 3381 .name = "destroy", 3382 .help = "destroy pattern template", 3383 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), 3384 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3385 .call = parse_template_destroy, 3386 }, 3387 /* Pattern template arguments. */ 3388 [PATTERN_TEMPLATE_CREATE_ID] = { 3389 .name = "pattern_template_id", 3390 .help = "specify a pattern template id to create", 3391 .next = NEXT(next_pt_attr, 3392 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3393 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), 3394 }, 3395 [PATTERN_TEMPLATE_DESTROY_ID] = { 3396 .name = "pattern_template", 3397 .help = "specify a pattern template id to destroy", 3398 .next = NEXT(next_pt_destroy_attr, 3399 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3400 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3401 args.templ_destroy.template_id)), 3402 .call = parse_template_destroy, 3403 }, 3404 [PATTERN_TEMPLATE_RELAXED_MATCHING] = { 3405 .name = "relaxed", 3406 .help = "is matching relaxed", 3407 .next = NEXT(next_pt_attr, 3408 NEXT_ENTRY(COMMON_BOOLEAN)), 3409 .args = ARGS(ARGS_ENTRY_BF(struct buffer, 3410 args.vc.attr.reserved, 1)), 3411 }, 3412 [PATTERN_TEMPLATE_INGRESS] = { 3413 .name = "ingress", 3414 .help = "attribute pattern to ingress", 3415 .next = NEXT(next_pt_attr), 3416 .call = parse_template, 3417 }, 3418 [PATTERN_TEMPLATE_EGRESS] = { 3419 .name = "egress", 3420 .help = "attribute pattern to egress", 3421 .next = NEXT(next_pt_attr), 3422 .call = parse_template, 3423 }, 3424 [PATTERN_TEMPLATE_TRANSFER] = { 3425 .name = "transfer", 3426 .help = "attribute pattern to transfer", 3427 .next = NEXT(next_pt_attr), 3428 .call = parse_template, 3429 }, 3430 [PATTERN_TEMPLATE_SPEC] = { 3431 .name = "template", 3432 .help = "specify item to create pattern template", 3433 .next = NEXT(next_item), 3434 }, 3435 /* Top-level command. */ 3436 [ACTIONS_TEMPLATE] = { 3437 .name = "actions_template", 3438 .type = "{command} {port_id} [{arg} [...]]", 3439 .help = "manage actions templates", 3440 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3441 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3442 .call = parse_template, 3443 }, 3444 /* Sub-level commands. */ 3445 [ACTIONS_TEMPLATE_CREATE] = { 3446 .name = "create", 3447 .help = "create actions template", 3448 .next = NEXT(next_at_attr), 3449 .call = parse_template, 3450 }, 3451 [ACTIONS_TEMPLATE_DESTROY] = { 3452 .name = "destroy", 3453 .help = "destroy actions template", 3454 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), 3455 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3456 .call = parse_template_destroy, 3457 }, 3458 /* Actions template arguments. */ 3459 [ACTIONS_TEMPLATE_CREATE_ID] = { 3460 .name = "actions_template_id", 3461 .help = "specify an actions template id to create", 3462 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), 3463 NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), 3464 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3465 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), 3466 }, 3467 [ACTIONS_TEMPLATE_DESTROY_ID] = { 3468 .name = "actions_template", 3469 .help = "specify an actions template id to destroy", 3470 .next = NEXT(next_at_destroy_attr, 3471 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3472 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3473 args.templ_destroy.template_id)), 3474 .call = parse_template_destroy, 3475 }, 3476 [ACTIONS_TEMPLATE_INGRESS] = { 3477 .name = "ingress", 3478 .help = "attribute actions to ingress", 3479 .next = NEXT(next_at_attr), 3480 .call = parse_template, 3481 }, 3482 [ACTIONS_TEMPLATE_EGRESS] = { 3483 .name = "egress", 3484 .help = "attribute actions to egress", 3485 .next = NEXT(next_at_attr), 3486 .call = parse_template, 3487 }, 3488 [ACTIONS_TEMPLATE_TRANSFER] = { 3489 .name = "transfer", 3490 .help = "attribute actions to transfer", 3491 .next = NEXT(next_at_attr), 3492 .call = parse_template, 3493 }, 3494 [ACTIONS_TEMPLATE_SPEC] = { 3495 .name = "template", 3496 .help = "specify action to create actions template", 3497 .next = NEXT(next_action), 3498 .call = parse_template, 3499 }, 3500 [ACTIONS_TEMPLATE_MASK] = { 3501 .name = "mask", 3502 .help = "specify action mask to create actions template", 3503 .next = NEXT(next_action), 3504 .call = parse_template, 3505 }, 3506 /* Top-level command. */ 3507 [TABLE] = { 3508 .name = "template_table", 3509 .type = "{command} {port_id} [{arg} [...]]", 3510 .help = "manage template tables", 3511 .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3512 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3513 .call = parse_table, 3514 }, 3515 /* Sub-level commands. */ 3516 [TABLE_CREATE] = { 3517 .name = "create", 3518 .help = "create template table", 3519 .next = NEXT(next_table_attr), 3520 .call = parse_table, 3521 }, 3522 [TABLE_DESTROY] = { 3523 .name = "destroy", 3524 .help = "destroy template table", 3525 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3526 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3527 .call = parse_table_destroy, 3528 }, 3529 [TABLE_RESIZE] = { 3530 .name = "resize", 3531 .help = "resize template table", 3532 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_ID)), 3533 .call = parse_table 3534 }, 3535 [TABLE_RESIZE_COMPLETE] = { 3536 .name = "resize_complete", 3537 .help = "complete table resize", 3538 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3539 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3540 .call = parse_table_destroy, 3541 }, 3542 /* Table arguments. */ 3543 [TABLE_CREATE_ID] = { 3544 .name = "table_id", 3545 .help = "specify table id to create", 3546 .next = NEXT(next_table_attr, 3547 NEXT_ENTRY(COMMON_TABLE_ID)), 3548 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3549 }, 3550 [TABLE_DESTROY_ID] = { 3551 .name = "table", 3552 .help = "table id", 3553 .next = NEXT(next_table_destroy_attr, 3554 NEXT_ENTRY(COMMON_TABLE_ID)), 3555 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3556 args.table_destroy.table_id)), 3557 .call = parse_table_destroy, 3558 }, 3559 [TABLE_RESIZE_ID] = { 3560 .name = "table_resize_id", 3561 .help = "table resize id", 3562 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_RULES_NUMBER), 3563 NEXT_ENTRY(COMMON_TABLE_ID)), 3564 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3565 .call = parse_table 3566 }, 3567 [TABLE_RESIZE_RULES_NUMBER] = { 3568 .name = "table_resize_rules_num", 3569 .help = "table resize rules number", 3570 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_UNSIGNED)), 3571 .args = ARGS(ARGS_ENTRY(struct buffer, 3572 args.table.attr.nb_flows)), 3573 .call = parse_table 3574 }, 3575 [TABLE_INSERTION_TYPE] = { 3576 .name = "insertion_type", 3577 .help = "specify insertion type", 3578 .next = NEXT(next_table_attr, 3579 NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)), 3580 .args = ARGS(ARGS_ENTRY(struct buffer, 3581 args.table.attr.insertion_type)), 3582 }, 3583 [TABLE_INSERTION_TYPE_NAME] = { 3584 .name = "insertion_type_name", 3585 .help = "insertion type name", 3586 .call = parse_insertion_table_type, 3587 .comp = comp_insertion_table_type, 3588 }, 3589 [TABLE_HASH_FUNC] = { 3590 .name = "hash_func", 3591 .help = "specify hash calculation function", 3592 .next = NEXT(next_table_attr, 3593 NEXT_ENTRY(TABLE_HASH_FUNC_NAME)), 3594 .args = ARGS(ARGS_ENTRY(struct buffer, 3595 args.table.attr.hash_func)), 3596 }, 3597 [TABLE_HASH_FUNC_NAME] = { 3598 .name = "hash_func_name", 3599 .help = "hash calculation function name", 3600 .call = parse_hash_table_type, 3601 .comp = comp_hash_table_type, 3602 }, 3603 [TABLE_GROUP] = { 3604 .name = "group", 3605 .help = "specify a group", 3606 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3607 .args = ARGS(ARGS_ENTRY(struct buffer, 3608 args.table.attr.flow_attr.group)), 3609 }, 3610 [TABLE_PRIORITY] = { 3611 .name = "priority", 3612 .help = "specify a priority level", 3613 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 3614 .args = ARGS(ARGS_ENTRY(struct buffer, 3615 args.table.attr.flow_attr.priority)), 3616 }, 3617 [TABLE_EGRESS] = { 3618 .name = "egress", 3619 .help = "affect rule to egress", 3620 .next = NEXT(next_table_attr), 3621 .call = parse_table, 3622 }, 3623 [TABLE_INGRESS] = { 3624 .name = "ingress", 3625 .help = "affect rule to ingress", 3626 .next = NEXT(next_table_attr), 3627 .call = parse_table, 3628 }, 3629 [TABLE_TRANSFER] = { 3630 .name = "transfer", 3631 .help = "affect rule to transfer", 3632 .next = NEXT(next_table_attr), 3633 .call = parse_table, 3634 }, 3635 [TABLE_TRANSFER_WIRE_ORIG] = { 3636 .name = "wire_orig", 3637 .help = "affect rule direction to transfer", 3638 .next = NEXT(next_table_attr), 3639 .call = parse_table, 3640 }, 3641 [TABLE_TRANSFER_VPORT_ORIG] = { 3642 .name = "vport_orig", 3643 .help = "affect rule direction to transfer", 3644 .next = NEXT(next_table_attr), 3645 .call = parse_table, 3646 }, 3647 [TABLE_RESIZABLE] = { 3648 .name = "resizable", 3649 .help = "set resizable attribute", 3650 .next = NEXT(next_table_attr), 3651 .call = parse_table, 3652 }, 3653 [TABLE_RULES_NUMBER] = { 3654 .name = "rules_number", 3655 .help = "number of rules in table", 3656 .next = NEXT(next_table_attr, 3657 NEXT_ENTRY(COMMON_UNSIGNED)), 3658 .args = ARGS(ARGS_ENTRY(struct buffer, 3659 args.table.attr.nb_flows)), 3660 .call = parse_table, 3661 }, 3662 [TABLE_PATTERN_TEMPLATE] = { 3663 .name = "pattern_template", 3664 .help = "specify pattern template id", 3665 .next = NEXT(next_table_attr, 3666 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3667 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3668 args.table.pat_templ_id)), 3669 .call = parse_table, 3670 }, 3671 [TABLE_ACTIONS_TEMPLATE] = { 3672 .name = "actions_template", 3673 .help = "specify actions template id", 3674 .next = NEXT(next_table_attr, 3675 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3676 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3677 args.table.act_templ_id)), 3678 .call = parse_table, 3679 }, 3680 /* Top-level command. */ 3681 [FLOW_GROUP] = { 3682 .name = "group", 3683 .help = "manage flow groups", 3684 .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), 3685 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3686 .call = parse_group, 3687 }, 3688 /* Sub-level commands. */ 3689 [GROUP_SET_MISS_ACTIONS] = { 3690 .name = "set_miss_actions", 3691 .help = "set group miss actions", 3692 .next = NEXT(next_action), 3693 .call = parse_group, 3694 }, 3695 /* Group arguments */ 3696 [GROUP_ID] = { 3697 .name = "group_id", 3698 .help = "group id", 3699 .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3700 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3701 }, 3702 [GROUP_INGRESS] = { 3703 .name = "ingress", 3704 .help = "group ingress attr", 3705 .next = NEXT(next_group_attr), 3706 .call = parse_group, 3707 }, 3708 [GROUP_EGRESS] = { 3709 .name = "egress", 3710 .help = "group egress attr", 3711 .next = NEXT(next_group_attr), 3712 .call = parse_group, 3713 }, 3714 [GROUP_TRANSFER] = { 3715 .name = "transfer", 3716 .help = "group transfer attr", 3717 .next = NEXT(next_group_attr), 3718 .call = parse_group, 3719 }, 3720 /* Top-level command. */ 3721 [QUEUE] = { 3722 .name = "queue", 3723 .help = "queue a flow rule operation", 3724 .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3725 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3726 .call = parse_qo, 3727 }, 3728 /* Sub-level commands. */ 3729 [QUEUE_CREATE] = { 3730 .name = "create", 3731 .help = "create a flow rule", 3732 .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), 3733 NEXT_ENTRY(COMMON_QUEUE_ID)), 3734 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3735 .call = parse_qo, 3736 }, 3737 [QUEUE_DESTROY] = { 3738 .name = "destroy", 3739 .help = "destroy a flow rule", 3740 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_POSTPONE), 3741 NEXT_ENTRY(COMMON_QUEUE_ID)), 3742 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3743 .call = parse_qo_destroy, 3744 }, 3745 [QUEUE_FLOW_UPDATE_RESIZED] = { 3746 .name = "update_resized", 3747 .help = "update a flow after table resize", 3748 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3749 NEXT_ENTRY(COMMON_QUEUE_ID)), 3750 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3751 .call = parse_qo_destroy, 3752 }, 3753 [QUEUE_UPDATE] = { 3754 .name = "update", 3755 .help = "update a flow rule", 3756 .next = NEXT(NEXT_ENTRY(QUEUE_UPDATE_ID), 3757 NEXT_ENTRY(COMMON_QUEUE_ID)), 3758 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3759 .call = parse_qo, 3760 }, 3761 [QUEUE_AGED] = { 3762 .name = "aged", 3763 .help = "list and destroy aged flows", 3764 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), 3765 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3766 .call = parse_aged, 3767 }, 3768 [QUEUE_INDIRECT_ACTION] = { 3769 .name = "indirect_action", 3770 .help = "queue indirect actions", 3771 .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), 3772 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3773 .call = parse_qia, 3774 }, 3775 /* Queue arguments. */ 3776 [QUEUE_TEMPLATE_TABLE] = { 3777 .name = "template_table", 3778 .help = "specify table id", 3779 .next = NEXT(next_async_insert_subcmd, 3780 NEXT_ENTRY(COMMON_TABLE_ID)), 3781 .args = ARGS(ARGS_ENTRY(struct buffer, 3782 args.vc.table_id)), 3783 .call = parse_qo, 3784 }, 3785 [QUEUE_PATTERN_TEMPLATE] = { 3786 .name = "pattern_template", 3787 .help = "specify pattern template index", 3788 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3789 NEXT_ENTRY(COMMON_UNSIGNED)), 3790 .args = ARGS(ARGS_ENTRY(struct buffer, 3791 args.vc.pat_templ_id)), 3792 .call = parse_qo, 3793 }, 3794 [QUEUE_ACTIONS_TEMPLATE] = { 3795 .name = "actions_template", 3796 .help = "specify actions template index", 3797 .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), 3798 NEXT_ENTRY(COMMON_UNSIGNED)), 3799 .args = ARGS(ARGS_ENTRY(struct buffer, 3800 args.vc.act_templ_id)), 3801 .call = parse_qo, 3802 }, 3803 [QUEUE_RULE_ID] = { 3804 .name = "rule_index", 3805 .help = "specify flow rule index", 3806 .next = NEXT(next_async_pattern_subcmd, 3807 NEXT_ENTRY(COMMON_UNSIGNED)), 3808 .args = ARGS(ARGS_ENTRY(struct buffer, 3809 args.vc.rule_id)), 3810 .call = parse_qo, 3811 }, 3812 [QUEUE_CREATE_POSTPONE] = { 3813 .name = "postpone", 3814 .help = "postpone create operation", 3815 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3816 NEXT_ENTRY(COMMON_BOOLEAN)), 3817 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3818 .call = parse_qo, 3819 }, 3820 [QUEUE_DESTROY_POSTPONE] = { 3821 .name = "postpone", 3822 .help = "postpone destroy operation", 3823 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3824 NEXT_ENTRY(COMMON_BOOLEAN)), 3825 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3826 .call = parse_qo_destroy, 3827 }, 3828 [QUEUE_DESTROY_ID] = { 3829 .name = "rule", 3830 .help = "specify rule id to destroy", 3831 .next = NEXT(next_queue_destroy_attr, 3832 NEXT_ENTRY(COMMON_UNSIGNED)), 3833 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3834 args.destroy.rule)), 3835 .call = parse_qo_destroy, 3836 }, 3837 [QUEUE_UPDATE_ID] = { 3838 .name = "rule", 3839 .help = "specify rule id to update", 3840 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3841 NEXT_ENTRY(COMMON_UNSIGNED)), 3842 .args = ARGS(ARGS_ENTRY(struct buffer, 3843 args.vc.rule_id)), 3844 .call = parse_qo, 3845 }, 3846 /* Queue indirect action arguments */ 3847 [QUEUE_INDIRECT_ACTION_CREATE] = { 3848 .name = "create", 3849 .help = "create indirect action", 3850 .next = NEXT(next_qia_create_attr), 3851 .call = parse_qia, 3852 }, 3853 [QUEUE_INDIRECT_ACTION_UPDATE] = { 3854 .name = "update", 3855 .help = "update indirect action", 3856 .next = NEXT(next_qia_update_attr, 3857 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3858 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3859 .call = parse_qia, 3860 }, 3861 [QUEUE_INDIRECT_ACTION_DESTROY] = { 3862 .name = "destroy", 3863 .help = "destroy indirect action", 3864 .next = NEXT(next_qia_destroy_attr), 3865 .call = parse_qia_destroy, 3866 }, 3867 [QUEUE_INDIRECT_ACTION_QUERY] = { 3868 .name = "query", 3869 .help = "query indirect action", 3870 .next = NEXT(next_qia_query_attr, 3871 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3872 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3873 .call = parse_qia, 3874 }, 3875 /* Indirect action destroy arguments. */ 3876 [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { 3877 .name = "postpone", 3878 .help = "postpone destroy operation", 3879 .next = NEXT(next_qia_destroy_attr, 3880 NEXT_ENTRY(COMMON_BOOLEAN)), 3881 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3882 }, 3883 [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { 3884 .name = "action_id", 3885 .help = "specify a indirect action id to destroy", 3886 .next = NEXT(next_qia_destroy_attr, 3887 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3888 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3889 args.ia_destroy.action_id)), 3890 .call = parse_qia_destroy, 3891 }, 3892 [QUEUE_INDIRECT_ACTION_QUERY_UPDATE] = { 3893 .name = "query_update", 3894 .help = "indirect query [and|or] update action", 3895 .next = NEXT(next_qia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3896 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3897 .call = parse_qia 3898 }, 3899 [QUEUE_INDIRECT_ACTION_QU_MODE] = { 3900 .name = "mode", 3901 .help = "indirect query [and|or] update action", 3902 .next = NEXT(next_qia_qu_attr, 3903 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 3904 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 3905 .call = parse_qia 3906 }, 3907 /* Indirect action update arguments. */ 3908 [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { 3909 .name = "postpone", 3910 .help = "postpone update operation", 3911 .next = NEXT(next_qia_update_attr, 3912 NEXT_ENTRY(COMMON_BOOLEAN)), 3913 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3914 }, 3915 /* Indirect action update arguments. */ 3916 [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { 3917 .name = "postpone", 3918 .help = "postpone query operation", 3919 .next = NEXT(next_qia_query_attr, 3920 NEXT_ENTRY(COMMON_BOOLEAN)), 3921 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3922 }, 3923 /* Indirect action create arguments. */ 3924 [QUEUE_INDIRECT_ACTION_CREATE_ID] = { 3925 .name = "action_id", 3926 .help = "specify a indirect action id to create", 3927 .next = NEXT(next_qia_create_attr, 3928 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3929 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3930 }, 3931 [QUEUE_INDIRECT_ACTION_INGRESS] = { 3932 .name = "ingress", 3933 .help = "affect rule to ingress", 3934 .next = NEXT(next_qia_create_attr), 3935 .call = parse_qia, 3936 }, 3937 [QUEUE_INDIRECT_ACTION_EGRESS] = { 3938 .name = "egress", 3939 .help = "affect rule to egress", 3940 .next = NEXT(next_qia_create_attr), 3941 .call = parse_qia, 3942 }, 3943 [QUEUE_INDIRECT_ACTION_TRANSFER] = { 3944 .name = "transfer", 3945 .help = "affect rule to transfer", 3946 .next = NEXT(next_qia_create_attr), 3947 .call = parse_qia, 3948 }, 3949 [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { 3950 .name = "postpone", 3951 .help = "postpone create operation", 3952 .next = NEXT(next_qia_create_attr, 3953 NEXT_ENTRY(COMMON_BOOLEAN)), 3954 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3955 }, 3956 [QUEUE_INDIRECT_ACTION_SPEC] = { 3957 .name = "action", 3958 .help = "specify action to create indirect handle", 3959 .next = NEXT(next_action), 3960 }, 3961 [QUEUE_INDIRECT_ACTION_LIST] = { 3962 .name = "list", 3963 .help = "specify actions for indirect handle list", 3964 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 3965 .call = parse_qia, 3966 }, 3967 /* Top-level command. */ 3968 [PUSH] = { 3969 .name = "push", 3970 .help = "push enqueued operations", 3971 .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3972 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3973 .call = parse_push, 3974 }, 3975 /* Sub-level commands. */ 3976 [PUSH_QUEUE] = { 3977 .name = "queue", 3978 .help = "specify queue id", 3979 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3980 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3981 }, 3982 /* Top-level command. */ 3983 [PULL] = { 3984 .name = "pull", 3985 .help = "pull flow operations results", 3986 .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3987 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3988 .call = parse_pull, 3989 }, 3990 /* Sub-level commands. */ 3991 [PULL_QUEUE] = { 3992 .name = "queue", 3993 .help = "specify queue id", 3994 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3995 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3996 }, 3997 /* Top-level command. */ 3998 [HASH] = { 3999 .name = "hash", 4000 .help = "calculate hash for a given pattern in a given template table", 4001 .next = NEXT(next_hash_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4002 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4003 .call = parse_hash, 4004 }, 4005 /* Sub-level commands. */ 4006 [HASH_CALC_TABLE] = { 4007 .name = "template_table", 4008 .help = "specify table id", 4009 .next = NEXT(NEXT_ENTRY(HASH_CALC_PATTERN_INDEX), 4010 NEXT_ENTRY(COMMON_TABLE_ID)), 4011 .args = ARGS(ARGS_ENTRY(struct buffer, 4012 args.vc.table_id)), 4013 .call = parse_hash, 4014 }, 4015 [HASH_CALC_ENCAP] = { 4016 .name = "encap", 4017 .help = "calculates encap hash", 4018 .next = NEXT(next_hash_encap_dest_subcmd), 4019 .call = parse_hash, 4020 }, 4021 [HASH_CALC_PATTERN_INDEX] = { 4022 .name = "pattern_template", 4023 .help = "specify pattern template id", 4024 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 4025 NEXT_ENTRY(COMMON_UNSIGNED)), 4026 .args = ARGS(ARGS_ENTRY(struct buffer, 4027 args.vc.pat_templ_id)), 4028 .call = parse_hash, 4029 }, 4030 [ENCAP_HASH_FIELD_SRC_PORT] = { 4031 .name = "hash_field_sport", 4032 .help = "the encap hash field is src port", 4033 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 4034 .call = parse_hash, 4035 }, 4036 [ENCAP_HASH_FIELD_GRE_FLOW_ID] = { 4037 .name = "hash_field_flow_id", 4038 .help = "the encap hash field is NVGRE flow id", 4039 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 4040 .call = parse_hash, 4041 }, 4042 /* Top-level command. */ 4043 [INDIRECT_ACTION] = { 4044 .name = "indirect_action", 4045 .type = "{command} {port_id} [{arg} [...]]", 4046 .help = "manage indirect actions", 4047 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4048 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4049 .call = parse_ia, 4050 }, 4051 /* Sub-level commands. */ 4052 [INDIRECT_ACTION_CREATE] = { 4053 .name = "create", 4054 .help = "create indirect action", 4055 .next = NEXT(next_ia_create_attr), 4056 .call = parse_ia, 4057 }, 4058 [INDIRECT_ACTION_UPDATE] = { 4059 .name = "update", 4060 .help = "update indirect action", 4061 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), 4062 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4063 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 4064 .call = parse_ia, 4065 }, 4066 [INDIRECT_ACTION_DESTROY] = { 4067 .name = "destroy", 4068 .help = "destroy indirect action", 4069 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), 4070 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4071 .call = parse_ia_destroy, 4072 }, 4073 [INDIRECT_ACTION_QUERY] = { 4074 .name = "query", 4075 .help = "query indirect action", 4076 .next = NEXT(NEXT_ENTRY(END), 4077 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4078 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4079 .call = parse_ia, 4080 }, 4081 [INDIRECT_ACTION_QUERY_UPDATE] = { 4082 .name = "query_update", 4083 .help = "query [and|or] update", 4084 .next = NEXT(next_ia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4085 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4086 .call = parse_ia 4087 }, 4088 [INDIRECT_ACTION_QU_MODE] = { 4089 .name = "mode", 4090 .help = "query_update mode", 4091 .next = NEXT(next_ia_qu_attr, 4092 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 4093 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 4094 .call = parse_ia, 4095 }, 4096 [INDIRECT_ACTION_QU_MODE_NAME] = { 4097 .name = "mode_name", 4098 .help = "query-update mode name", 4099 .call = parse_qu_mode_name, 4100 .comp = comp_qu_mode_name, 4101 }, 4102 [VALIDATE] = { 4103 .name = "validate", 4104 .help = "check whether a flow rule can be created", 4105 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4106 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4107 .call = parse_vc, 4108 }, 4109 [CREATE] = { 4110 .name = "create", 4111 .help = "create a flow rule", 4112 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4113 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4114 .call = parse_vc, 4115 }, 4116 [DESTROY] = { 4117 .name = "destroy", 4118 .help = "destroy specific flow rules", 4119 .next = NEXT(next_destroy_attr, 4120 NEXT_ENTRY(COMMON_PORT_ID)), 4121 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4122 .call = parse_destroy, 4123 }, 4124 [UPDATE] = { 4125 .name = "update", 4126 .help = "update a flow rule with new actions", 4127 .next = NEXT(NEXT_ENTRY(VC_IS_USER_ID, END), 4128 NEXT_ENTRY(ACTIONS), 4129 NEXT_ENTRY(COMMON_RULE_ID), 4130 NEXT_ENTRY(COMMON_PORT_ID)), 4131 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.rule_id), 4132 ARGS_ENTRY(struct buffer, port)), 4133 .call = parse_vc, 4134 }, 4135 [FLUSH] = { 4136 .name = "flush", 4137 .help = "destroy all flow rules", 4138 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4139 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4140 .call = parse_flush, 4141 }, 4142 [DUMP] = { 4143 .name = "dump", 4144 .help = "dump single/all flow rules to file", 4145 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4146 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4147 .call = parse_dump, 4148 }, 4149 [QUERY] = { 4150 .name = "query", 4151 .help = "query an existing flow rule", 4152 .next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION), 4153 NEXT_ENTRY(COMMON_RULE_ID), 4154 NEXT_ENTRY(COMMON_PORT_ID)), 4155 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), 4156 ARGS_ENTRY(struct buffer, args.query.rule), 4157 ARGS_ENTRY(struct buffer, port)), 4158 .call = parse_query, 4159 }, 4160 [LIST] = { 4161 .name = "list", 4162 .help = "list existing flow rules", 4163 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4164 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4165 .call = parse_list, 4166 }, 4167 [AGED] = { 4168 .name = "aged", 4169 .help = "list and destroy aged flows", 4170 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4171 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4172 .call = parse_aged, 4173 }, 4174 [ISOLATE] = { 4175 .name = "isolate", 4176 .help = "restrict ingress traffic to the defined flow rules", 4177 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), 4178 NEXT_ENTRY(COMMON_PORT_ID)), 4179 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), 4180 ARGS_ENTRY(struct buffer, port)), 4181 .call = parse_isolate, 4182 }, 4183 [FLEX] = { 4184 .name = "flex_item", 4185 .help = "flex item API", 4186 .next = NEXT(next_flex_item), 4187 .call = parse_flex, 4188 }, 4189 [FLEX_ITEM_CREATE] = { 4190 .name = "create", 4191 .help = "flex item create", 4192 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), 4193 ARGS_ENTRY(struct buffer, args.flex.token), 4194 ARGS_ENTRY(struct buffer, port)), 4195 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), 4196 NEXT_ENTRY(COMMON_FLEX_TOKEN), 4197 NEXT_ENTRY(COMMON_PORT_ID)), 4198 .call = parse_flex 4199 }, 4200 [FLEX_ITEM_DESTROY] = { 4201 .name = "destroy", 4202 .help = "flex item destroy", 4203 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4204 ARGS_ENTRY(struct buffer, port)), 4205 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4206 NEXT_ENTRY(COMMON_PORT_ID)), 4207 .call = parse_flex 4208 }, 4209 [TUNNEL] = { 4210 .name = "tunnel", 4211 .help = "new tunnel API", 4212 .next = NEXT(NEXT_ENTRY 4213 (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), 4214 .call = parse_tunnel, 4215 }, 4216 /* Tunnel arguments. */ 4217 [TUNNEL_CREATE] = { 4218 .name = "create", 4219 .help = "create new tunnel object", 4220 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), 4221 NEXT_ENTRY(COMMON_PORT_ID)), 4222 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4223 .call = parse_tunnel, 4224 }, 4225 [TUNNEL_CREATE_TYPE] = { 4226 .name = "type", 4227 .help = "create new tunnel", 4228 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), 4229 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), 4230 .call = parse_tunnel, 4231 }, 4232 [TUNNEL_DESTROY] = { 4233 .name = "destroy", 4234 .help = "destroy tunnel", 4235 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), 4236 NEXT_ENTRY(COMMON_PORT_ID)), 4237 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4238 .call = parse_tunnel, 4239 }, 4240 [TUNNEL_DESTROY_ID] = { 4241 .name = "id", 4242 .help = "tunnel identifier to destroy", 4243 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), 4244 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4245 .call = parse_tunnel, 4246 }, 4247 [TUNNEL_LIST] = { 4248 .name = "list", 4249 .help = "list existing tunnels", 4250 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4251 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4252 .call = parse_tunnel, 4253 }, 4254 /* Destroy arguments. */ 4255 [DESTROY_RULE] = { 4256 .name = "rule", 4257 .help = "specify a rule identifier", 4258 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4259 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), 4260 .call = parse_destroy, 4261 }, 4262 [DESTROY_IS_USER_ID] = { 4263 .name = "user_id", 4264 .help = "rule identifier is user-id", 4265 .next = NEXT(next_destroy_attr), 4266 .call = parse_destroy, 4267 }, 4268 /* Dump arguments. */ 4269 [DUMP_ALL] = { 4270 .name = "all", 4271 .help = "dump all", 4272 .next = NEXT(next_dump_attr), 4273 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), 4274 .call = parse_dump, 4275 }, 4276 [DUMP_ONE] = { 4277 .name = "rule", 4278 .help = "dump one rule", 4279 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4280 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), 4281 ARGS_ENTRY(struct buffer, args.dump.rule)), 4282 .call = parse_dump, 4283 }, 4284 [DUMP_IS_USER_ID] = { 4285 .name = "user_id", 4286 .help = "rule identifier is user-id", 4287 .next = NEXT(next_dump_subcmd), 4288 .call = parse_dump, 4289 }, 4290 /* Query arguments. */ 4291 [QUERY_ACTION] = { 4292 .name = "{action}", 4293 .type = "ACTION", 4294 .help = "action to query, must be part of the rule", 4295 .call = parse_action, 4296 .comp = comp_action, 4297 }, 4298 [QUERY_IS_USER_ID] = { 4299 .name = "user_id", 4300 .help = "rule identifier is user-id", 4301 .next = NEXT(next_query_attr), 4302 .call = parse_query, 4303 }, 4304 /* List arguments. */ 4305 [LIST_GROUP] = { 4306 .name = "group", 4307 .help = "specify a group", 4308 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4309 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), 4310 .call = parse_list, 4311 }, 4312 [AGED_DESTROY] = { 4313 .name = "destroy", 4314 .help = "specify aged flows need be destroyed", 4315 .call = parse_aged, 4316 .comp = comp_none, 4317 }, 4318 /* Validate/create attributes. */ 4319 [VC_GROUP] = { 4320 .name = "group", 4321 .help = "specify a group", 4322 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4323 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), 4324 .call = parse_vc, 4325 }, 4326 [VC_PRIORITY] = { 4327 .name = "priority", 4328 .help = "specify a priority level", 4329 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 4330 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), 4331 .call = parse_vc, 4332 }, 4333 [VC_INGRESS] = { 4334 .name = "ingress", 4335 .help = "affect rule to ingress", 4336 .next = NEXT(next_vc_attr), 4337 .call = parse_vc, 4338 }, 4339 [VC_EGRESS] = { 4340 .name = "egress", 4341 .help = "affect rule to egress", 4342 .next = NEXT(next_vc_attr), 4343 .call = parse_vc, 4344 }, 4345 [VC_TRANSFER] = { 4346 .name = "transfer", 4347 .help = "apply rule directly to endpoints found in pattern", 4348 .next = NEXT(next_vc_attr), 4349 .call = parse_vc, 4350 }, 4351 [VC_TUNNEL_SET] = { 4352 .name = "tunnel_set", 4353 .help = "tunnel steer rule", 4354 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4355 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4356 .call = parse_vc, 4357 }, 4358 [VC_TUNNEL_MATCH] = { 4359 .name = "tunnel_match", 4360 .help = "tunnel match rule", 4361 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4362 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4363 .call = parse_vc, 4364 }, 4365 [VC_USER_ID] = { 4366 .name = "user_id", 4367 .help = "specify a user id to create", 4368 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4369 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)), 4370 .call = parse_vc, 4371 }, 4372 [VC_IS_USER_ID] = { 4373 .name = "user_id", 4374 .help = "rule identifier is user-id", 4375 .call = parse_vc, 4376 }, 4377 /* Validate/create pattern. */ 4378 [ITEM_PATTERN] = { 4379 .name = "pattern", 4380 .help = "submit a list of pattern items", 4381 .next = NEXT(next_item), 4382 .call = parse_vc, 4383 }, 4384 [ITEM_PARAM_IS] = { 4385 .name = "is", 4386 .help = "match value perfectly (with full bit-mask)", 4387 .call = parse_vc_spec, 4388 }, 4389 [ITEM_PARAM_SPEC] = { 4390 .name = "spec", 4391 .help = "match value according to configured bit-mask", 4392 .call = parse_vc_spec, 4393 }, 4394 [ITEM_PARAM_LAST] = { 4395 .name = "last", 4396 .help = "specify upper bound to establish a range", 4397 .call = parse_vc_spec, 4398 }, 4399 [ITEM_PARAM_MASK] = { 4400 .name = "mask", 4401 .help = "specify bit-mask with relevant bits set to one", 4402 .call = parse_vc_spec, 4403 }, 4404 [ITEM_PARAM_PREFIX] = { 4405 .name = "prefix", 4406 .help = "generate bit-mask from a prefix length", 4407 .call = parse_vc_spec, 4408 }, 4409 [ITEM_NEXT] = { 4410 .name = "/", 4411 .help = "specify next pattern item", 4412 .next = NEXT(next_item), 4413 }, 4414 [ITEM_END] = { 4415 .name = "end", 4416 .help = "end list of pattern items", 4417 .priv = PRIV_ITEM(END, 0), 4418 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 4419 .call = parse_vc, 4420 }, 4421 [ITEM_VOID] = { 4422 .name = "void", 4423 .help = "no-op pattern item", 4424 .priv = PRIV_ITEM(VOID, 0), 4425 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4426 .call = parse_vc, 4427 }, 4428 [ITEM_INVERT] = { 4429 .name = "invert", 4430 .help = "perform actions when pattern does not match", 4431 .priv = PRIV_ITEM(INVERT, 0), 4432 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4433 .call = parse_vc, 4434 }, 4435 [ITEM_ANY] = { 4436 .name = "any", 4437 .help = "match any protocol for the current layer", 4438 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), 4439 .next = NEXT(item_any), 4440 .call = parse_vc, 4441 }, 4442 [ITEM_ANY_NUM] = { 4443 .name = "num", 4444 .help = "number of layers covered", 4445 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4446 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), 4447 }, 4448 [ITEM_PORT_ID] = { 4449 .name = "port_id", 4450 .help = "match traffic from/to a given DPDK port ID", 4451 .priv = PRIV_ITEM(PORT_ID, 4452 sizeof(struct rte_flow_item_port_id)), 4453 .next = NEXT(item_port_id), 4454 .call = parse_vc, 4455 }, 4456 [ITEM_PORT_ID_ID] = { 4457 .name = "id", 4458 .help = "DPDK port ID", 4459 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), 4460 item_param), 4461 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), 4462 }, 4463 [ITEM_MARK] = { 4464 .name = "mark", 4465 .help = "match traffic against value set in previously matched rule", 4466 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), 4467 .next = NEXT(item_mark), 4468 .call = parse_vc, 4469 }, 4470 [ITEM_MARK_ID] = { 4471 .name = "id", 4472 .help = "Integer value to match against", 4473 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), 4474 item_param), 4475 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), 4476 }, 4477 [ITEM_RAW] = { 4478 .name = "raw", 4479 .help = "match an arbitrary byte string", 4480 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), 4481 .next = NEXT(item_raw), 4482 .call = parse_vc, 4483 }, 4484 [ITEM_RAW_RELATIVE] = { 4485 .name = "relative", 4486 .help = "look for pattern after the previous item", 4487 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4488 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4489 relative, 1)), 4490 }, 4491 [ITEM_RAW_SEARCH] = { 4492 .name = "search", 4493 .help = "search pattern from offset (see also limit)", 4494 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4495 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4496 search, 1)), 4497 }, 4498 [ITEM_RAW_OFFSET] = { 4499 .name = "offset", 4500 .help = "absolute or relative offset for pattern", 4501 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), 4502 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), 4503 }, 4504 [ITEM_RAW_LIMIT] = { 4505 .name = "limit", 4506 .help = "search area limit for start of pattern", 4507 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4508 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), 4509 }, 4510 [ITEM_RAW_PATTERN] = { 4511 .name = "pattern", 4512 .help = "byte string to look for", 4513 .next = NEXT(item_raw, 4514 NEXT_ENTRY(COMMON_STRING), 4515 NEXT_ENTRY(ITEM_PARAM_IS, 4516 ITEM_PARAM_SPEC, 4517 ITEM_PARAM_MASK)), 4518 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4519 ARGS_ENTRY(struct rte_flow_item_raw, length), 4520 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4521 ITEM_RAW_PATTERN_SIZE)), 4522 }, 4523 [ITEM_RAW_PATTERN_HEX] = { 4524 .name = "pattern_hex", 4525 .help = "hex string to look for", 4526 .next = NEXT(item_raw, 4527 NEXT_ENTRY(COMMON_HEX), 4528 NEXT_ENTRY(ITEM_PARAM_IS, 4529 ITEM_PARAM_SPEC, 4530 ITEM_PARAM_MASK)), 4531 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4532 ARGS_ENTRY(struct rte_flow_item_raw, length), 4533 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4534 ITEM_RAW_PATTERN_SIZE)), 4535 }, 4536 [ITEM_ETH] = { 4537 .name = "eth", 4538 .help = "match Ethernet header", 4539 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), 4540 .next = NEXT(item_eth), 4541 .call = parse_vc, 4542 }, 4543 [ITEM_ETH_DST] = { 4544 .name = "dst", 4545 .help = "destination MAC", 4546 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4547 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), 4548 }, 4549 [ITEM_ETH_SRC] = { 4550 .name = "src", 4551 .help = "source MAC", 4552 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4553 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), 4554 }, 4555 [ITEM_ETH_TYPE] = { 4556 .name = "type", 4557 .help = "EtherType", 4558 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4559 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), 4560 }, 4561 [ITEM_ETH_HAS_VLAN] = { 4562 .name = "has_vlan", 4563 .help = "packet header contains VLAN", 4564 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4565 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, 4566 has_vlan, 1)), 4567 }, 4568 [ITEM_VLAN] = { 4569 .name = "vlan", 4570 .help = "match 802.1Q/ad VLAN tag", 4571 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), 4572 .next = NEXT(item_vlan), 4573 .call = parse_vc, 4574 }, 4575 [ITEM_VLAN_TCI] = { 4576 .name = "tci", 4577 .help = "tag control information", 4578 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4579 item_param), 4580 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, hdr.vlan_tci)), 4581 }, 4582 [ITEM_VLAN_PCP] = { 4583 .name = "pcp", 4584 .help = "priority code point", 4585 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4586 item_param), 4587 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4588 hdr.vlan_tci, "\xe0\x00")), 4589 }, 4590 [ITEM_VLAN_DEI] = { 4591 .name = "dei", 4592 .help = "drop eligible indicator", 4593 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4594 item_param), 4595 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4596 hdr.vlan_tci, "\x10\x00")), 4597 }, 4598 [ITEM_VLAN_VID] = { 4599 .name = "vid", 4600 .help = "VLAN identifier", 4601 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4602 item_param), 4603 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4604 hdr.vlan_tci, "\x0f\xff")), 4605 }, 4606 [ITEM_VLAN_INNER_TYPE] = { 4607 .name = "inner_type", 4608 .help = "inner EtherType", 4609 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4610 item_param), 4611 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, 4612 hdr.eth_proto)), 4613 }, 4614 [ITEM_VLAN_HAS_MORE_VLAN] = { 4615 .name = "has_more_vlan", 4616 .help = "packet header contains another VLAN", 4617 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4618 item_param), 4619 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, 4620 has_more_vlan, 1)), 4621 }, 4622 [ITEM_IPV4] = { 4623 .name = "ipv4", 4624 .help = "match IPv4 header", 4625 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), 4626 .next = NEXT(item_ipv4), 4627 .call = parse_vc, 4628 }, 4629 [ITEM_IPV4_VER_IHL] = { 4630 .name = "version_ihl", 4631 .help = "match header length", 4632 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4633 item_param), 4634 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, 4635 hdr.version_ihl)), 4636 }, 4637 [ITEM_IPV4_TOS] = { 4638 .name = "tos", 4639 .help = "type of service", 4640 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4641 item_param), 4642 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4643 hdr.type_of_service)), 4644 }, 4645 [ITEM_IPV4_LENGTH] = { 4646 .name = "length", 4647 .help = "total length", 4648 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4649 item_param), 4650 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4651 hdr.total_length)), 4652 }, 4653 [ITEM_IPV4_ID] = { 4654 .name = "packet_id", 4655 .help = "fragment packet id", 4656 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4657 item_param), 4658 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4659 hdr.packet_id)), 4660 }, 4661 [ITEM_IPV4_FRAGMENT_OFFSET] = { 4662 .name = "fragment_offset", 4663 .help = "fragmentation flags and fragment offset", 4664 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4665 item_param), 4666 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4667 hdr.fragment_offset)), 4668 }, 4669 [ITEM_IPV4_TTL] = { 4670 .name = "ttl", 4671 .help = "time to live", 4672 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4673 item_param), 4674 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4675 hdr.time_to_live)), 4676 }, 4677 [ITEM_IPV4_PROTO] = { 4678 .name = "proto", 4679 .help = "next protocol ID", 4680 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4681 item_param), 4682 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4683 hdr.next_proto_id)), 4684 }, 4685 [ITEM_IPV4_SRC] = { 4686 .name = "src", 4687 .help = "source address", 4688 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4689 item_param), 4690 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4691 hdr.src_addr)), 4692 }, 4693 [ITEM_IPV4_DST] = { 4694 .name = "dst", 4695 .help = "destination address", 4696 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4697 item_param), 4698 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4699 hdr.dst_addr)), 4700 }, 4701 [ITEM_IPV6] = { 4702 .name = "ipv6", 4703 .help = "match IPv6 header", 4704 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), 4705 .next = NEXT(item_ipv6), 4706 .call = parse_vc, 4707 }, 4708 [ITEM_IPV6_TC] = { 4709 .name = "tc", 4710 .help = "traffic class", 4711 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4712 item_param), 4713 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4714 hdr.vtc_flow, 4715 "\x0f\xf0\x00\x00")), 4716 }, 4717 [ITEM_IPV6_FLOW] = { 4718 .name = "flow", 4719 .help = "flow label", 4720 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4721 item_param), 4722 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4723 hdr.vtc_flow, 4724 "\x00\x0f\xff\xff")), 4725 }, 4726 [ITEM_IPV6_LEN] = { 4727 .name = "length", 4728 .help = "payload length", 4729 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4730 item_param), 4731 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4732 hdr.payload_len)), 4733 }, 4734 [ITEM_IPV6_PROTO] = { 4735 .name = "proto", 4736 .help = "protocol (next header)", 4737 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4738 item_param), 4739 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4740 hdr.proto)), 4741 }, 4742 [ITEM_IPV6_HOP] = { 4743 .name = "hop", 4744 .help = "hop limit", 4745 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4746 item_param), 4747 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4748 hdr.hop_limits)), 4749 }, 4750 [ITEM_IPV6_SRC] = { 4751 .name = "src", 4752 .help = "source address", 4753 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4754 item_param), 4755 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4756 hdr.src_addr)), 4757 }, 4758 [ITEM_IPV6_DST] = { 4759 .name = "dst", 4760 .help = "destination address", 4761 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4762 item_param), 4763 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4764 hdr.dst_addr)), 4765 }, 4766 [ITEM_IPV6_HAS_FRAG_EXT] = { 4767 .name = "has_frag_ext", 4768 .help = "fragment packet attribute", 4769 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4770 item_param), 4771 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, 4772 has_frag_ext, 1)), 4773 }, 4774 [ITEM_IPV6_ROUTING_EXT] = { 4775 .name = "ipv6_routing_ext", 4776 .help = "match IPv6 routing extension header", 4777 .priv = PRIV_ITEM(IPV6_ROUTING_EXT, 4778 sizeof(struct rte_flow_item_ipv6_routing_ext)), 4779 .next = NEXT(item_ipv6_routing_ext), 4780 .call = parse_vc, 4781 }, 4782 [ITEM_IPV6_ROUTING_EXT_TYPE] = { 4783 .name = "ext_type", 4784 .help = "match IPv6 routing extension header type", 4785 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4786 item_param), 4787 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4788 hdr.type)), 4789 }, 4790 [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = { 4791 .name = "ext_next_hdr", 4792 .help = "match IPv6 routing extension header next header type", 4793 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4794 item_param), 4795 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4796 hdr.next_hdr)), 4797 }, 4798 [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = { 4799 .name = "ext_seg_left", 4800 .help = "match IPv6 routing extension header segment left", 4801 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4802 item_param), 4803 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4804 hdr.segments_left)), 4805 }, 4806 [ITEM_ICMP] = { 4807 .name = "icmp", 4808 .help = "match ICMP header", 4809 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), 4810 .next = NEXT(item_icmp), 4811 .call = parse_vc, 4812 }, 4813 [ITEM_ICMP_TYPE] = { 4814 .name = "type", 4815 .help = "ICMP packet type", 4816 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4817 item_param), 4818 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4819 hdr.icmp_type)), 4820 }, 4821 [ITEM_ICMP_CODE] = { 4822 .name = "code", 4823 .help = "ICMP packet code", 4824 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4825 item_param), 4826 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4827 hdr.icmp_code)), 4828 }, 4829 [ITEM_ICMP_IDENT] = { 4830 .name = "ident", 4831 .help = "ICMP packet identifier", 4832 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4833 item_param), 4834 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4835 hdr.icmp_ident)), 4836 }, 4837 [ITEM_ICMP_SEQ] = { 4838 .name = "seq", 4839 .help = "ICMP packet sequence number", 4840 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4841 item_param), 4842 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4843 hdr.icmp_seq_nb)), 4844 }, 4845 [ITEM_UDP] = { 4846 .name = "udp", 4847 .help = "match UDP header", 4848 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), 4849 .next = NEXT(item_udp), 4850 .call = parse_vc, 4851 }, 4852 [ITEM_UDP_SRC] = { 4853 .name = "src", 4854 .help = "UDP source port", 4855 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), 4856 item_param), 4857 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4858 hdr.src_port)), 4859 }, 4860 [ITEM_UDP_DST] = { 4861 .name = "dst", 4862 .help = "UDP destination port", 4863 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4864 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4865 hdr.dst_port)), 4866 }, 4867 [ITEM_TCP] = { 4868 .name = "tcp", 4869 .help = "match TCP header", 4870 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), 4871 .next = NEXT(item_tcp), 4872 .call = parse_vc, 4873 }, 4874 [ITEM_TCP_SRC] = { 4875 .name = "src", 4876 .help = "TCP source port", 4877 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4878 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4879 hdr.src_port)), 4880 }, 4881 [ITEM_TCP_DST] = { 4882 .name = "dst", 4883 .help = "TCP destination port", 4884 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4885 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4886 hdr.dst_port)), 4887 }, 4888 [ITEM_TCP_FLAGS] = { 4889 .name = "flags", 4890 .help = "TCP flags", 4891 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4892 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4893 hdr.tcp_flags)), 4894 }, 4895 [ITEM_SCTP] = { 4896 .name = "sctp", 4897 .help = "match SCTP header", 4898 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), 4899 .next = NEXT(item_sctp), 4900 .call = parse_vc, 4901 }, 4902 [ITEM_SCTP_SRC] = { 4903 .name = "src", 4904 .help = "SCTP source port", 4905 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4906 item_param), 4907 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4908 hdr.src_port)), 4909 }, 4910 [ITEM_SCTP_DST] = { 4911 .name = "dst", 4912 .help = "SCTP destination port", 4913 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4914 item_param), 4915 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4916 hdr.dst_port)), 4917 }, 4918 [ITEM_SCTP_TAG] = { 4919 .name = "tag", 4920 .help = "validation tag", 4921 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4922 item_param), 4923 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4924 hdr.tag)), 4925 }, 4926 [ITEM_SCTP_CKSUM] = { 4927 .name = "cksum", 4928 .help = "checksum", 4929 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4930 item_param), 4931 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4932 hdr.cksum)), 4933 }, 4934 [ITEM_VXLAN] = { 4935 .name = "vxlan", 4936 .help = "match VXLAN header", 4937 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), 4938 .next = NEXT(item_vxlan), 4939 .call = parse_vc, 4940 }, 4941 [ITEM_VXLAN_VNI] = { 4942 .name = "vni", 4943 .help = "VXLAN identifier", 4944 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4945 item_param), 4946 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), 4947 }, 4948 [ITEM_VXLAN_FLAG_G] = { 4949 .name = "flag_g", 4950 .help = "VXLAN GBP bit", 4951 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4952 item_param), 4953 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4954 hdr.flag_g, 1)), 4955 }, 4956 [ITEM_VXLAN_FLAG_VER] = { 4957 .name = "flag_ver", 4958 .help = "VXLAN GPE version", 4959 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4960 item_param), 4961 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4962 hdr.flag_ver, 2)), 4963 }, 4964 [ITEM_VXLAN_FLAG_I] = { 4965 .name = "flag_i", 4966 .help = "VXLAN Instance bit", 4967 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4968 item_param), 4969 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4970 hdr.flag_i, 1)), 4971 }, 4972 [ITEM_VXLAN_FLAG_P] = { 4973 .name = "flag_p", 4974 .help = "VXLAN GPE Next Protocol bit", 4975 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4976 item_param), 4977 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4978 hdr.flag_p, 1)), 4979 }, 4980 [ITEM_VXLAN_FLAG_B] = { 4981 .name = "flag_b", 4982 .help = "VXLAN GPE Ingress-Replicated BUM", 4983 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4984 item_param), 4985 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4986 hdr.flag_b, 1)), 4987 }, 4988 [ITEM_VXLAN_FLAG_O] = { 4989 .name = "flag_o", 4990 .help = "VXLAN GPE OAM Packet bit", 4991 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4992 item_param), 4993 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4994 hdr.flag_o, 1)), 4995 }, 4996 [ITEM_VXLAN_FLAG_D] = { 4997 .name = "flag_d", 4998 .help = "VXLAN GBP Don't Learn bit", 4999 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5000 item_param), 5001 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 5002 hdr.flag_d, 1)), 5003 }, 5004 [ITEM_VXLAN_FLAG_A] = { 5005 .name = "flag_a", 5006 .help = "VXLAN GBP Applied bit", 5007 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5008 item_param), 5009 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 5010 hdr.flag_a, 1)), 5011 }, 5012 [ITEM_VXLAN_GBP_ID] = { 5013 .name = "group_policy_id", 5014 .help = "VXLAN GBP ID", 5015 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5016 item_param), 5017 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5018 hdr.policy_id)), 5019 }, 5020 [ITEM_VXLAN_GPE_PROTO] = { 5021 .name = "protocol", 5022 .help = "VXLAN GPE next protocol", 5023 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5024 item_param), 5025 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5026 hdr.proto)), 5027 }, 5028 [ITEM_VXLAN_FIRST_RSVD] = { 5029 .name = "first_rsvd", 5030 .help = "VXLAN rsvd0 first byte", 5031 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5032 item_param), 5033 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5034 hdr.rsvd0[0])), 5035 }, 5036 [ITEM_VXLAN_SECND_RSVD] = { 5037 .name = "second_rsvd", 5038 .help = "VXLAN rsvd0 second byte", 5039 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5040 item_param), 5041 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5042 hdr.rsvd0[1])), 5043 }, 5044 [ITEM_VXLAN_THIRD_RSVD] = { 5045 .name = "third_rsvd", 5046 .help = "VXLAN rsvd0 third byte", 5047 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5048 item_param), 5049 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5050 hdr.rsvd0[2])), 5051 }, 5052 [ITEM_VXLAN_LAST_RSVD] = { 5053 .name = "last_rsvd", 5054 .help = "VXLAN last reserved byte", 5055 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5056 item_param), 5057 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5058 hdr.last_rsvd)), 5059 }, 5060 [ITEM_E_TAG] = { 5061 .name = "e_tag", 5062 .help = "match E-Tag header", 5063 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), 5064 .next = NEXT(item_e_tag), 5065 .call = parse_vc, 5066 }, 5067 [ITEM_E_TAG_GRP_ECID_B] = { 5068 .name = "grp_ecid_b", 5069 .help = "GRP and E-CID base", 5070 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5071 item_param), 5072 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, 5073 rsvd_grp_ecid_b, 5074 "\x3f\xff")), 5075 }, 5076 [ITEM_NVGRE] = { 5077 .name = "nvgre", 5078 .help = "match NVGRE header", 5079 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), 5080 .next = NEXT(item_nvgre), 5081 .call = parse_vc, 5082 }, 5083 [ITEM_NVGRE_TNI] = { 5084 .name = "tni", 5085 .help = "virtual subnet ID", 5086 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), 5087 item_param), 5088 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), 5089 }, 5090 [ITEM_MPLS] = { 5091 .name = "mpls", 5092 .help = "match MPLS header", 5093 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), 5094 .next = NEXT(item_mpls), 5095 .call = parse_vc, 5096 }, 5097 [ITEM_MPLS_LABEL] = { 5098 .name = "label", 5099 .help = "MPLS label", 5100 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5101 item_param), 5102 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5103 label_tc_s, 5104 "\xff\xff\xf0")), 5105 }, 5106 [ITEM_MPLS_TC] = { 5107 .name = "tc", 5108 .help = "MPLS Traffic Class", 5109 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5110 item_param), 5111 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5112 label_tc_s, 5113 "\x00\x00\x0e")), 5114 }, 5115 [ITEM_MPLS_S] = { 5116 .name = "s", 5117 .help = "MPLS Bottom-of-Stack", 5118 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5119 item_param), 5120 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5121 label_tc_s, 5122 "\x00\x00\x01")), 5123 }, 5124 [ITEM_MPLS_TTL] = { 5125 .name = "ttl", 5126 .help = "MPLS Time-to-Live", 5127 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5128 item_param), 5129 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls, ttl)), 5130 }, 5131 [ITEM_GRE] = { 5132 .name = "gre", 5133 .help = "match GRE header", 5134 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), 5135 .next = NEXT(item_gre), 5136 .call = parse_vc, 5137 }, 5138 [ITEM_GRE_PROTO] = { 5139 .name = "protocol", 5140 .help = "GRE protocol type", 5141 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5142 item_param), 5143 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5144 protocol)), 5145 }, 5146 [ITEM_GRE_C_RSVD0_VER] = { 5147 .name = "c_rsvd0_ver", 5148 .help = 5149 "checksum (1b), undefined (1b), key bit (1b)," 5150 " sequence number (1b), reserved 0 (9b)," 5151 " version (3b)", 5152 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5153 item_param), 5154 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5155 c_rsvd0_ver)), 5156 }, 5157 [ITEM_GRE_C_BIT] = { 5158 .name = "c_bit", 5159 .help = "checksum bit (C)", 5160 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), 5161 item_param), 5162 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5163 c_rsvd0_ver, 5164 "\x80\x00\x00\x00")), 5165 }, 5166 [ITEM_GRE_S_BIT] = { 5167 .name = "s_bit", 5168 .help = "sequence number bit (S)", 5169 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5170 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5171 c_rsvd0_ver, 5172 "\x10\x00\x00\x00")), 5173 }, 5174 [ITEM_GRE_K_BIT] = { 5175 .name = "k_bit", 5176 .help = "key bit (K)", 5177 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5178 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5179 c_rsvd0_ver, 5180 "\x20\x00\x00\x00")), 5181 }, 5182 [ITEM_FUZZY] = { 5183 .name = "fuzzy", 5184 .help = "fuzzy pattern match, expect faster than default", 5185 .priv = PRIV_ITEM(FUZZY, 5186 sizeof(struct rte_flow_item_fuzzy)), 5187 .next = NEXT(item_fuzzy), 5188 .call = parse_vc, 5189 }, 5190 [ITEM_FUZZY_THRESH] = { 5191 .name = "thresh", 5192 .help = "match accuracy threshold", 5193 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), 5194 item_param), 5195 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, 5196 thresh)), 5197 }, 5198 [ITEM_GTP] = { 5199 .name = "gtp", 5200 .help = "match GTP header", 5201 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), 5202 .next = NEXT(item_gtp), 5203 .call = parse_vc, 5204 }, 5205 [ITEM_GTP_FLAGS] = { 5206 .name = "v_pt_rsv_flags", 5207 .help = "GTP flags", 5208 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5209 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, 5210 hdr.gtp_hdr_info)), 5211 }, 5212 [ITEM_GTP_MSG_TYPE] = { 5213 .name = "msg_type", 5214 .help = "GTP message type", 5215 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5216 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), 5217 }, 5218 [ITEM_GTP_TEID] = { 5219 .name = "teid", 5220 .help = "tunnel endpoint identifier", 5221 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5222 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), 5223 }, 5224 [ITEM_GTPC] = { 5225 .name = "gtpc", 5226 .help = "match GTP header", 5227 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), 5228 .next = NEXT(item_gtp), 5229 .call = parse_vc, 5230 }, 5231 [ITEM_GTPU] = { 5232 .name = "gtpu", 5233 .help = "match GTP header", 5234 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), 5235 .next = NEXT(item_gtp), 5236 .call = parse_vc, 5237 }, 5238 [ITEM_GENEVE] = { 5239 .name = "geneve", 5240 .help = "match GENEVE header", 5241 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), 5242 .next = NEXT(item_geneve), 5243 .call = parse_vc, 5244 }, 5245 [ITEM_GENEVE_VNI] = { 5246 .name = "vni", 5247 .help = "virtual network identifier", 5248 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5249 item_param), 5250 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), 5251 }, 5252 [ITEM_GENEVE_PROTO] = { 5253 .name = "protocol", 5254 .help = "GENEVE protocol type", 5255 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5256 item_param), 5257 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, 5258 protocol)), 5259 }, 5260 [ITEM_GENEVE_OPTLEN] = { 5261 .name = "optlen", 5262 .help = "GENEVE options length in dwords", 5263 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5264 item_param), 5265 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, 5266 ver_opt_len_o_c_rsvd0, 5267 "\x3f\x00")), 5268 }, 5269 [ITEM_VXLAN_GPE] = { 5270 .name = "vxlan-gpe", 5271 .help = "match VXLAN-GPE header", 5272 .priv = PRIV_ITEM(VXLAN_GPE, 5273 sizeof(struct rte_flow_item_vxlan_gpe)), 5274 .next = NEXT(item_vxlan_gpe), 5275 .call = parse_vc, 5276 }, 5277 [ITEM_VXLAN_GPE_VNI] = { 5278 .name = "vni", 5279 .help = "VXLAN-GPE identifier", 5280 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5281 item_param), 5282 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5283 hdr.vni)), 5284 }, 5285 [ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR] = { 5286 .name = "protocol", 5287 .help = "VXLAN-GPE next protocol", 5288 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5289 item_param), 5290 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5291 protocol)), 5292 }, 5293 [ITEM_VXLAN_GPE_FLAGS] = { 5294 .name = "flags", 5295 .help = "VXLAN-GPE flags", 5296 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5297 item_param), 5298 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5299 flags)), 5300 }, 5301 [ITEM_VXLAN_GPE_RSVD0] = { 5302 .name = "rsvd0", 5303 .help = "VXLAN-GPE rsvd0", 5304 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5305 item_param), 5306 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5307 rsvd0)), 5308 }, 5309 [ITEM_VXLAN_GPE_RSVD1] = { 5310 .name = "rsvd1", 5311 .help = "VXLAN-GPE rsvd1", 5312 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5313 item_param), 5314 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5315 rsvd1)), 5316 }, 5317 [ITEM_ARP_ETH_IPV4] = { 5318 .name = "arp_eth_ipv4", 5319 .help = "match ARP header for Ethernet/IPv4", 5320 .priv = PRIV_ITEM(ARP_ETH_IPV4, 5321 sizeof(struct rte_flow_item_arp_eth_ipv4)), 5322 .next = NEXT(item_arp_eth_ipv4), 5323 .call = parse_vc, 5324 }, 5325 [ITEM_ARP_ETH_IPV4_SHA] = { 5326 .name = "sha", 5327 .help = "sender hardware address", 5328 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5329 item_param), 5330 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5331 hdr.arp_data.arp_sha)), 5332 }, 5333 [ITEM_ARP_ETH_IPV4_SPA] = { 5334 .name = "spa", 5335 .help = "sender IPv4 address", 5336 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5337 item_param), 5338 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5339 hdr.arp_data.arp_sip)), 5340 }, 5341 [ITEM_ARP_ETH_IPV4_THA] = { 5342 .name = "tha", 5343 .help = "target hardware address", 5344 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5345 item_param), 5346 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5347 hdr.arp_data.arp_tha)), 5348 }, 5349 [ITEM_ARP_ETH_IPV4_TPA] = { 5350 .name = "tpa", 5351 .help = "target IPv4 address", 5352 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5353 item_param), 5354 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5355 hdr.arp_data.arp_tip)), 5356 }, 5357 [ITEM_IPV6_EXT] = { 5358 .name = "ipv6_ext", 5359 .help = "match presence of any IPv6 extension header", 5360 .priv = PRIV_ITEM(IPV6_EXT, 5361 sizeof(struct rte_flow_item_ipv6_ext)), 5362 .next = NEXT(item_ipv6_ext), 5363 .call = parse_vc, 5364 }, 5365 [ITEM_IPV6_EXT_NEXT_HDR] = { 5366 .name = "next_hdr", 5367 .help = "next header", 5368 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5369 item_param), 5370 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 5371 next_hdr)), 5372 }, 5373 [ITEM_IPV6_FRAG_EXT] = { 5374 .name = "ipv6_frag_ext", 5375 .help = "match presence of IPv6 fragment extension header", 5376 .priv = PRIV_ITEM(IPV6_FRAG_EXT, 5377 sizeof(struct rte_flow_item_ipv6_frag_ext)), 5378 .next = NEXT(item_ipv6_frag_ext), 5379 .call = parse_vc, 5380 }, 5381 [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { 5382 .name = "next_hdr", 5383 .help = "next header", 5384 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5385 item_param), 5386 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, 5387 hdr.next_header)), 5388 }, 5389 [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { 5390 .name = "frag_data", 5391 .help = "fragment flags and offset", 5392 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5393 item_param), 5394 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5395 hdr.frag_data)), 5396 }, 5397 [ITEM_IPV6_FRAG_EXT_ID] = { 5398 .name = "packet_id", 5399 .help = "fragment packet id", 5400 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5401 item_param), 5402 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5403 hdr.id)), 5404 }, 5405 [ITEM_ICMP6] = { 5406 .name = "icmp6", 5407 .help = "match any ICMPv6 header", 5408 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), 5409 .next = NEXT(item_icmp6), 5410 .call = parse_vc, 5411 }, 5412 [ITEM_ICMP6_TYPE] = { 5413 .name = "type", 5414 .help = "ICMPv6 type", 5415 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5416 item_param), 5417 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5418 type)), 5419 }, 5420 [ITEM_ICMP6_CODE] = { 5421 .name = "code", 5422 .help = "ICMPv6 code", 5423 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5424 item_param), 5425 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5426 code)), 5427 }, 5428 [ITEM_ICMP6_ECHO_REQUEST] = { 5429 .name = "icmp6_echo_request", 5430 .help = "match ICMPv6 echo request", 5431 .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, 5432 sizeof(struct rte_flow_item_icmp6_echo)), 5433 .next = NEXT(item_icmp6_echo_request), 5434 .call = parse_vc, 5435 }, 5436 [ITEM_ICMP6_ECHO_REQUEST_ID] = { 5437 .name = "ident", 5438 .help = "ICMPv6 echo request identifier", 5439 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5440 item_param), 5441 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5442 hdr.identifier)), 5443 }, 5444 [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { 5445 .name = "seq", 5446 .help = "ICMPv6 echo request sequence", 5447 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5448 item_param), 5449 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5450 hdr.sequence)), 5451 }, 5452 [ITEM_ICMP6_ECHO_REPLY] = { 5453 .name = "icmp6_echo_reply", 5454 .help = "match ICMPv6 echo reply", 5455 .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, 5456 sizeof(struct rte_flow_item_icmp6_echo)), 5457 .next = NEXT(item_icmp6_echo_reply), 5458 .call = parse_vc, 5459 }, 5460 [ITEM_ICMP6_ECHO_REPLY_ID] = { 5461 .name = "ident", 5462 .help = "ICMPv6 echo reply identifier", 5463 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5464 item_param), 5465 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5466 hdr.identifier)), 5467 }, 5468 [ITEM_ICMP6_ECHO_REPLY_SEQ] = { 5469 .name = "seq", 5470 .help = "ICMPv6 echo reply sequence", 5471 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5472 item_param), 5473 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5474 hdr.sequence)), 5475 }, 5476 [ITEM_ICMP6_ND_NS] = { 5477 .name = "icmp6_nd_ns", 5478 .help = "match ICMPv6 neighbor discovery solicitation", 5479 .priv = PRIV_ITEM(ICMP6_ND_NS, 5480 sizeof(struct rte_flow_item_icmp6_nd_ns)), 5481 .next = NEXT(item_icmp6_nd_ns), 5482 .call = parse_vc, 5483 }, 5484 [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { 5485 .name = "target_addr", 5486 .help = "target address", 5487 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), 5488 item_param), 5489 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, 5490 target_addr)), 5491 }, 5492 [ITEM_ICMP6_ND_NA] = { 5493 .name = "icmp6_nd_na", 5494 .help = "match ICMPv6 neighbor discovery advertisement", 5495 .priv = PRIV_ITEM(ICMP6_ND_NA, 5496 sizeof(struct rte_flow_item_icmp6_nd_na)), 5497 .next = NEXT(item_icmp6_nd_na), 5498 .call = parse_vc, 5499 }, 5500 [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { 5501 .name = "target_addr", 5502 .help = "target address", 5503 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), 5504 item_param), 5505 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, 5506 target_addr)), 5507 }, 5508 [ITEM_ICMP6_ND_OPT] = { 5509 .name = "icmp6_nd_opt", 5510 .help = "match presence of any ICMPv6 neighbor discovery" 5511 " option", 5512 .priv = PRIV_ITEM(ICMP6_ND_OPT, 5513 sizeof(struct rte_flow_item_icmp6_nd_opt)), 5514 .next = NEXT(item_icmp6_nd_opt), 5515 .call = parse_vc, 5516 }, 5517 [ITEM_ICMP6_ND_OPT_TYPE] = { 5518 .name = "type", 5519 .help = "ND option type", 5520 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5521 item_param), 5522 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, 5523 type)), 5524 }, 5525 [ITEM_ICMP6_ND_OPT_SLA_ETH] = { 5526 .name = "icmp6_nd_opt_sla_eth", 5527 .help = "match ICMPv6 neighbor discovery source Ethernet" 5528 " link-layer address option", 5529 .priv = PRIV_ITEM 5530 (ICMP6_ND_OPT_SLA_ETH, 5531 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), 5532 .next = NEXT(item_icmp6_nd_opt_sla_eth), 5533 .call = parse_vc, 5534 }, 5535 [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { 5536 .name = "sla", 5537 .help = "source Ethernet LLA", 5538 .next = NEXT(item_icmp6_nd_opt_sla_eth, 5539 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5540 .args = ARGS(ARGS_ENTRY_HTON 5541 (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), 5542 }, 5543 [ITEM_ICMP6_ND_OPT_TLA_ETH] = { 5544 .name = "icmp6_nd_opt_tla_eth", 5545 .help = "match ICMPv6 neighbor discovery target Ethernet" 5546 " link-layer address option", 5547 .priv = PRIV_ITEM 5548 (ICMP6_ND_OPT_TLA_ETH, 5549 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), 5550 .next = NEXT(item_icmp6_nd_opt_tla_eth), 5551 .call = parse_vc, 5552 }, 5553 [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { 5554 .name = "tla", 5555 .help = "target Ethernet LLA", 5556 .next = NEXT(item_icmp6_nd_opt_tla_eth, 5557 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5558 .args = ARGS(ARGS_ENTRY_HTON 5559 (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), 5560 }, 5561 [ITEM_META] = { 5562 .name = "meta", 5563 .help = "match metadata header", 5564 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), 5565 .next = NEXT(item_meta), 5566 .call = parse_vc, 5567 }, 5568 [ITEM_META_DATA] = { 5569 .name = "data", 5570 .help = "metadata value", 5571 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), 5572 item_param), 5573 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, 5574 data, "\xff\xff\xff\xff")), 5575 }, 5576 [ITEM_RANDOM] = { 5577 .name = "random", 5578 .help = "match random value", 5579 .priv = PRIV_ITEM(RANDOM, sizeof(struct rte_flow_item_random)), 5580 .next = NEXT(item_random), 5581 .call = parse_vc, 5582 }, 5583 [ITEM_RANDOM_VALUE] = { 5584 .name = "value", 5585 .help = "random value", 5586 .next = NEXT(item_random, NEXT_ENTRY(COMMON_UNSIGNED), 5587 item_param), 5588 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_random, 5589 value, "\xff\xff")), 5590 }, 5591 [ITEM_GRE_KEY] = { 5592 .name = "gre_key", 5593 .help = "match GRE key", 5594 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), 5595 .next = NEXT(item_gre_key), 5596 .call = parse_vc, 5597 }, 5598 [ITEM_GRE_KEY_VALUE] = { 5599 .name = "value", 5600 .help = "key value", 5601 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), 5602 item_param), 5603 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5604 }, 5605 [ITEM_GRE_OPTION] = { 5606 .name = "gre_option", 5607 .help = "match GRE optional fields", 5608 .priv = PRIV_ITEM(GRE_OPTION, 5609 sizeof(struct rte_flow_item_gre_opt)), 5610 .next = NEXT(item_gre_option), 5611 .call = parse_vc, 5612 }, 5613 [ITEM_GRE_OPTION_CHECKSUM] = { 5614 .name = "checksum", 5615 .help = "match GRE checksum", 5616 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5617 item_param), 5618 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5619 checksum_rsvd.checksum)), 5620 }, 5621 [ITEM_GRE_OPTION_KEY] = { 5622 .name = "key", 5623 .help = "match GRE key", 5624 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5625 item_param), 5626 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5627 key.key)), 5628 }, 5629 [ITEM_GRE_OPTION_SEQUENCE] = { 5630 .name = "sequence", 5631 .help = "match GRE sequence", 5632 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5633 item_param), 5634 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5635 sequence.sequence)), 5636 }, 5637 [ITEM_GTP_PSC] = { 5638 .name = "gtp_psc", 5639 .help = "match GTP extension header with type 0x85", 5640 .priv = PRIV_ITEM(GTP_PSC, 5641 sizeof(struct rte_flow_item_gtp_psc)), 5642 .next = NEXT(item_gtp_psc), 5643 .call = parse_vc, 5644 }, 5645 [ITEM_GTP_PSC_QFI] = { 5646 .name = "qfi", 5647 .help = "QoS flow identifier", 5648 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5649 item_param), 5650 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5651 hdr.qfi, 6)), 5652 }, 5653 [ITEM_GTP_PSC_PDU_T] = { 5654 .name = "pdu_t", 5655 .help = "PDU type", 5656 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5657 item_param), 5658 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5659 hdr.type, 4)), 5660 }, 5661 [ITEM_PPPOES] = { 5662 .name = "pppoes", 5663 .help = "match PPPoE session header", 5664 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), 5665 .next = NEXT(item_pppoes), 5666 .call = parse_vc, 5667 }, 5668 [ITEM_PPPOED] = { 5669 .name = "pppoed", 5670 .help = "match PPPoE discovery header", 5671 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), 5672 .next = NEXT(item_pppoed), 5673 .call = parse_vc, 5674 }, 5675 [ITEM_PPPOE_SEID] = { 5676 .name = "seid", 5677 .help = "session identifier", 5678 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), 5679 item_param), 5680 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, 5681 session_id)), 5682 }, 5683 [ITEM_PPPOE_PROTO_ID] = { 5684 .name = "pppoe_proto_id", 5685 .help = "match PPPoE session protocol identifier", 5686 .priv = PRIV_ITEM(PPPOE_PROTO_ID, 5687 sizeof(struct rte_flow_item_pppoe_proto_id)), 5688 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED), 5689 item_param), 5690 .args = ARGS(ARGS_ENTRY_HTON 5691 (struct rte_flow_item_pppoe_proto_id, proto_id)), 5692 .call = parse_vc, 5693 }, 5694 [ITEM_HIGIG2] = { 5695 .name = "higig2", 5696 .help = "matches higig2 header", 5697 .priv = PRIV_ITEM(HIGIG2, 5698 sizeof(struct rte_flow_item_higig2_hdr)), 5699 .next = NEXT(item_higig2), 5700 .call = parse_vc, 5701 }, 5702 [ITEM_HIGIG2_CLASSIFICATION] = { 5703 .name = "classification", 5704 .help = "matches classification of higig2 header", 5705 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5706 item_param), 5707 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5708 hdr.ppt1.classification)), 5709 }, 5710 [ITEM_HIGIG2_VID] = { 5711 .name = "vid", 5712 .help = "matches vid of higig2 header", 5713 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5714 item_param), 5715 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5716 hdr.ppt1.vid)), 5717 }, 5718 [ITEM_TAG] = { 5719 .name = "tag", 5720 .help = "match tag value", 5721 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), 5722 .next = NEXT(item_tag), 5723 .call = parse_vc, 5724 }, 5725 [ITEM_TAG_DATA] = { 5726 .name = "data", 5727 .help = "tag value to match", 5728 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5729 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), 5730 }, 5731 [ITEM_TAG_INDEX] = { 5732 .name = "index", 5733 .help = "index of tag array to match", 5734 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5735 NEXT_ENTRY(ITEM_PARAM_IS)), 5736 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), 5737 }, 5738 [ITEM_L2TPV3OIP] = { 5739 .name = "l2tpv3oip", 5740 .help = "match L2TPv3 over IP header", 5741 .priv = PRIV_ITEM(L2TPV3OIP, 5742 sizeof(struct rte_flow_item_l2tpv3oip)), 5743 .next = NEXT(item_l2tpv3oip), 5744 .call = parse_vc, 5745 }, 5746 [ITEM_L2TPV3OIP_SESSION_ID] = { 5747 .name = "session_id", 5748 .help = "session identifier", 5749 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), 5750 item_param), 5751 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, 5752 session_id)), 5753 }, 5754 [ITEM_ESP] = { 5755 .name = "esp", 5756 .help = "match ESP header", 5757 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), 5758 .next = NEXT(item_esp), 5759 .call = parse_vc, 5760 }, 5761 [ITEM_ESP_SPI] = { 5762 .name = "spi", 5763 .help = "security policy index", 5764 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5765 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, 5766 hdr.spi)), 5767 }, 5768 [ITEM_AH] = { 5769 .name = "ah", 5770 .help = "match AH header", 5771 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), 5772 .next = NEXT(item_ah), 5773 .call = parse_vc, 5774 }, 5775 [ITEM_AH_SPI] = { 5776 .name = "spi", 5777 .help = "security parameters index", 5778 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5779 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), 5780 }, 5781 [ITEM_PFCP] = { 5782 .name = "pfcp", 5783 .help = "match pfcp header", 5784 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), 5785 .next = NEXT(item_pfcp), 5786 .call = parse_vc, 5787 }, 5788 [ITEM_PFCP_S_FIELD] = { 5789 .name = "s_field", 5790 .help = "S field", 5791 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5792 item_param), 5793 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, 5794 s_field)), 5795 }, 5796 [ITEM_PFCP_SEID] = { 5797 .name = "seid", 5798 .help = "session endpoint identifier", 5799 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5800 item_param), 5801 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), 5802 }, 5803 [ITEM_ECPRI] = { 5804 .name = "ecpri", 5805 .help = "match eCPRI header", 5806 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), 5807 .next = NEXT(item_ecpri), 5808 .call = parse_vc, 5809 }, 5810 [ITEM_ECPRI_COMMON] = { 5811 .name = "common", 5812 .help = "eCPRI common header", 5813 .next = NEXT(item_ecpri_common), 5814 }, 5815 [ITEM_ECPRI_COMMON_TYPE] = { 5816 .name = "type", 5817 .help = "type of common header", 5818 .next = NEXT(item_ecpri_common_type), 5819 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), 5820 }, 5821 [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { 5822 .name = "iq_data", 5823 .help = "Type #0: IQ Data", 5824 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5825 ITEM_NEXT)), 5826 .call = parse_vc_item_ecpri_type, 5827 }, 5828 [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { 5829 .name = "pc_id", 5830 .help = "Physical Channel ID", 5831 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5832 ITEM_ECPRI_COMMON, ITEM_NEXT), 5833 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5834 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5835 hdr.type0.pc_id)), 5836 }, 5837 [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { 5838 .name = "rtc_ctrl", 5839 .help = "Type #2: Real-Time Control Data", 5840 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5841 ITEM_NEXT)), 5842 .call = parse_vc_item_ecpri_type, 5843 }, 5844 [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { 5845 .name = "rtc_id", 5846 .help = "Real-Time Control Data ID", 5847 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5848 ITEM_ECPRI_COMMON, ITEM_NEXT), 5849 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5850 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5851 hdr.type2.rtc_id)), 5852 }, 5853 [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { 5854 .name = "delay_measure", 5855 .help = "Type #5: One-Way Delay Measurement", 5856 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5857 ITEM_NEXT)), 5858 .call = parse_vc_item_ecpri_type, 5859 }, 5860 [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { 5861 .name = "msr_id", 5862 .help = "Measurement ID", 5863 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5864 ITEM_ECPRI_COMMON, ITEM_NEXT), 5865 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5866 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5867 hdr.type5.msr_id)), 5868 }, 5869 [ITEM_GENEVE_OPT] = { 5870 .name = "geneve-opt", 5871 .help = "GENEVE header option", 5872 .priv = PRIV_ITEM(GENEVE_OPT, 5873 sizeof(struct rte_flow_item_geneve_opt) + 5874 ITEM_GENEVE_OPT_DATA_SIZE), 5875 .next = NEXT(item_geneve_opt), 5876 .call = parse_vc, 5877 }, 5878 [ITEM_GENEVE_OPT_CLASS] = { 5879 .name = "class", 5880 .help = "GENEVE option class", 5881 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5882 item_param), 5883 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, 5884 option_class)), 5885 }, 5886 [ITEM_GENEVE_OPT_TYPE] = { 5887 .name = "type", 5888 .help = "GENEVE option type", 5889 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5890 item_param), 5891 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, 5892 option_type)), 5893 }, 5894 [ITEM_GENEVE_OPT_LENGTH] = { 5895 .name = "length", 5896 .help = "GENEVE option data length (in 32b words)", 5897 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5898 item_param), 5899 .args = ARGS(ARGS_ENTRY_BOUNDED( 5900 struct rte_flow_item_geneve_opt, option_len, 5901 0, 31)), 5902 }, 5903 [ITEM_GENEVE_OPT_DATA] = { 5904 .name = "data", 5905 .help = "GENEVE option data pattern", 5906 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), 5907 item_param), 5908 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), 5909 ARGS_ENTRY_ARB(0, 0), 5910 ARGS_ENTRY_ARB 5911 (sizeof(struct rte_flow_item_geneve_opt), 5912 ITEM_GENEVE_OPT_DATA_SIZE)), 5913 }, 5914 [ITEM_INTEGRITY] = { 5915 .name = "integrity", 5916 .help = "match packet integrity", 5917 .priv = PRIV_ITEM(INTEGRITY, 5918 sizeof(struct rte_flow_item_integrity)), 5919 .next = NEXT(item_integrity), 5920 .call = parse_vc, 5921 }, 5922 [ITEM_INTEGRITY_LEVEL] = { 5923 .name = "level", 5924 .help = "integrity level", 5925 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5926 item_param), 5927 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), 5928 }, 5929 [ITEM_INTEGRITY_VALUE] = { 5930 .name = "value", 5931 .help = "integrity value", 5932 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5933 item_param), 5934 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), 5935 }, 5936 [ITEM_CONNTRACK] = { 5937 .name = "conntrack", 5938 .help = "conntrack state", 5939 .priv = PRIV_ITEM(CONNTRACK, 5940 sizeof(struct rte_flow_item_conntrack)), 5941 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 5942 item_param), 5943 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 5944 .call = parse_vc, 5945 }, 5946 [ITEM_PORT_REPRESENTOR] = { 5947 .name = "port_representor", 5948 .help = "match traffic entering the embedded switch from the given ethdev", 5949 .priv = PRIV_ITEM(PORT_REPRESENTOR, 5950 sizeof(struct rte_flow_item_ethdev)), 5951 .next = NEXT(item_port_representor), 5952 .call = parse_vc, 5953 }, 5954 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 5955 .name = "port_id", 5956 .help = "ethdev port ID", 5957 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 5958 item_param), 5959 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5960 }, 5961 [ITEM_REPRESENTED_PORT] = { 5962 .name = "represented_port", 5963 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 5964 .priv = PRIV_ITEM(REPRESENTED_PORT, 5965 sizeof(struct rte_flow_item_ethdev)), 5966 .next = NEXT(item_represented_port), 5967 .call = parse_vc, 5968 }, 5969 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 5970 .name = "ethdev_port_id", 5971 .help = "ethdev port ID", 5972 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 5973 item_param), 5974 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5975 }, 5976 [ITEM_FLEX] = { 5977 .name = "flex", 5978 .help = "match flex header", 5979 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 5980 .next = NEXT(item_flex), 5981 .call = parse_vc, 5982 }, 5983 [ITEM_FLEX_ITEM_HANDLE] = { 5984 .name = "item", 5985 .help = "flex item handle", 5986 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5987 NEXT_ENTRY(ITEM_PARAM_IS)), 5988 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 5989 }, 5990 [ITEM_FLEX_PATTERN_HANDLE] = { 5991 .name = "pattern", 5992 .help = "flex pattern handle", 5993 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5994 NEXT_ENTRY(ITEM_PARAM_IS)), 5995 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 5996 }, 5997 [ITEM_L2TPV2] = { 5998 .name = "l2tpv2", 5999 .help = "match L2TPv2 header", 6000 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 6001 .next = NEXT(item_l2tpv2), 6002 .call = parse_vc, 6003 }, 6004 [ITEM_L2TPV2_TYPE] = { 6005 .name = "type", 6006 .help = "type of l2tpv2", 6007 .next = NEXT(item_l2tpv2_type), 6008 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 6009 }, 6010 [ITEM_L2TPV2_TYPE_DATA] = { 6011 .name = "data", 6012 .help = "Type #7: data message without any options", 6013 .next = NEXT(item_l2tpv2_type_data), 6014 .call = parse_vc_item_l2tpv2_type, 6015 }, 6016 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 6017 .name = "tunnel_id", 6018 .help = "tunnel identifier", 6019 .next = NEXT(item_l2tpv2_type_data, 6020 NEXT_ENTRY(COMMON_UNSIGNED), 6021 item_param), 6022 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6023 hdr.type7.tunnel_id)), 6024 }, 6025 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 6026 .name = "session_id", 6027 .help = "session identifier", 6028 .next = NEXT(item_l2tpv2_type_data, 6029 NEXT_ENTRY(COMMON_UNSIGNED), 6030 item_param), 6031 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6032 hdr.type7.session_id)), 6033 }, 6034 [ITEM_L2TPV2_TYPE_DATA_L] = { 6035 .name = "data_l", 6036 .help = "Type #6: data message with length option", 6037 .next = NEXT(item_l2tpv2_type_data_l), 6038 .call = parse_vc_item_l2tpv2_type, 6039 }, 6040 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 6041 .name = "length", 6042 .help = "message length", 6043 .next = NEXT(item_l2tpv2_type_data_l, 6044 NEXT_ENTRY(COMMON_UNSIGNED), 6045 item_param), 6046 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6047 hdr.type6.length)), 6048 }, 6049 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 6050 .name = "tunnel_id", 6051 .help = "tunnel identifier", 6052 .next = NEXT(item_l2tpv2_type_data_l, 6053 NEXT_ENTRY(COMMON_UNSIGNED), 6054 item_param), 6055 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6056 hdr.type6.tunnel_id)), 6057 }, 6058 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 6059 .name = "session_id", 6060 .help = "session identifier", 6061 .next = NEXT(item_l2tpv2_type_data_l, 6062 NEXT_ENTRY(COMMON_UNSIGNED), 6063 item_param), 6064 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6065 hdr.type6.session_id)), 6066 }, 6067 [ITEM_L2TPV2_TYPE_DATA_S] = { 6068 .name = "data_s", 6069 .help = "Type #5: data message with ns, nr option", 6070 .next = NEXT(item_l2tpv2_type_data_s), 6071 .call = parse_vc_item_l2tpv2_type, 6072 }, 6073 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 6074 .name = "tunnel_id", 6075 .help = "tunnel identifier", 6076 .next = NEXT(item_l2tpv2_type_data_s, 6077 NEXT_ENTRY(COMMON_UNSIGNED), 6078 item_param), 6079 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6080 hdr.type5.tunnel_id)), 6081 }, 6082 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 6083 .name = "session_id", 6084 .help = "session identifier", 6085 .next = NEXT(item_l2tpv2_type_data_s, 6086 NEXT_ENTRY(COMMON_UNSIGNED), 6087 item_param), 6088 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6089 hdr.type5.session_id)), 6090 }, 6091 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 6092 .name = "ns", 6093 .help = "sequence number for message", 6094 .next = NEXT(item_l2tpv2_type_data_s, 6095 NEXT_ENTRY(COMMON_UNSIGNED), 6096 item_param), 6097 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6098 hdr.type5.ns)), 6099 }, 6100 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 6101 .name = "nr", 6102 .help = "sequence number for next receive message", 6103 .next = NEXT(item_l2tpv2_type_data_s, 6104 NEXT_ENTRY(COMMON_UNSIGNED), 6105 item_param), 6106 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6107 hdr.type5.nr)), 6108 }, 6109 [ITEM_L2TPV2_TYPE_DATA_O] = { 6110 .name = "data_o", 6111 .help = "Type #4: data message with offset option", 6112 .next = NEXT(item_l2tpv2_type_data_o), 6113 .call = parse_vc_item_l2tpv2_type, 6114 }, 6115 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 6116 .name = "tunnel_id", 6117 .help = "tunnel identifier", 6118 .next = NEXT(item_l2tpv2_type_data_o, 6119 NEXT_ENTRY(COMMON_UNSIGNED), 6120 item_param), 6121 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6122 hdr.type4.tunnel_id)), 6123 }, 6124 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 6125 .name = "session_id", 6126 .help = "session identifier", 6127 .next = NEXT(item_l2tpv2_type_data_o, 6128 NEXT_ENTRY(COMMON_UNSIGNED), 6129 item_param), 6130 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6131 hdr.type5.session_id)), 6132 }, 6133 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 6134 .name = "offset_size", 6135 .help = "the size of offset padding", 6136 .next = NEXT(item_l2tpv2_type_data_o, 6137 NEXT_ENTRY(COMMON_UNSIGNED), 6138 item_param), 6139 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6140 hdr.type4.offset_size)), 6141 }, 6142 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 6143 .name = "data_l_s", 6144 .help = "Type #3: data message contains length, ns, nr " 6145 "options", 6146 .next = NEXT(item_l2tpv2_type_data_l_s), 6147 .call = parse_vc_item_l2tpv2_type, 6148 }, 6149 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 6150 .name = "length", 6151 .help = "message length", 6152 .next = NEXT(item_l2tpv2_type_data_l_s, 6153 NEXT_ENTRY(COMMON_UNSIGNED), 6154 item_param), 6155 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6156 hdr.type3.length)), 6157 }, 6158 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 6159 .name = "tunnel_id", 6160 .help = "tunnel identifier", 6161 .next = NEXT(item_l2tpv2_type_data_l_s, 6162 NEXT_ENTRY(COMMON_UNSIGNED), 6163 item_param), 6164 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6165 hdr.type3.tunnel_id)), 6166 }, 6167 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 6168 .name = "session_id", 6169 .help = "session identifier", 6170 .next = NEXT(item_l2tpv2_type_data_l_s, 6171 NEXT_ENTRY(COMMON_UNSIGNED), 6172 item_param), 6173 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6174 hdr.type3.session_id)), 6175 }, 6176 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 6177 .name = "ns", 6178 .help = "sequence number for message", 6179 .next = NEXT(item_l2tpv2_type_data_l_s, 6180 NEXT_ENTRY(COMMON_UNSIGNED), 6181 item_param), 6182 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6183 hdr.type3.ns)), 6184 }, 6185 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 6186 .name = "nr", 6187 .help = "sequence number for next receive message", 6188 .next = NEXT(item_l2tpv2_type_data_l_s, 6189 NEXT_ENTRY(COMMON_UNSIGNED), 6190 item_param), 6191 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6192 hdr.type3.nr)), 6193 }, 6194 [ITEM_L2TPV2_TYPE_CTRL] = { 6195 .name = "control", 6196 .help = "Type #3: conrtol message contains length, ns, nr " 6197 "options", 6198 .next = NEXT(item_l2tpv2_type_ctrl), 6199 .call = parse_vc_item_l2tpv2_type, 6200 }, 6201 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 6202 .name = "length", 6203 .help = "message length", 6204 .next = NEXT(item_l2tpv2_type_ctrl, 6205 NEXT_ENTRY(COMMON_UNSIGNED), 6206 item_param), 6207 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6208 hdr.type3.length)), 6209 }, 6210 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 6211 .name = "tunnel_id", 6212 .help = "tunnel identifier", 6213 .next = NEXT(item_l2tpv2_type_ctrl, 6214 NEXT_ENTRY(COMMON_UNSIGNED), 6215 item_param), 6216 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6217 hdr.type3.tunnel_id)), 6218 }, 6219 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 6220 .name = "session_id", 6221 .help = "session identifier", 6222 .next = NEXT(item_l2tpv2_type_ctrl, 6223 NEXT_ENTRY(COMMON_UNSIGNED), 6224 item_param), 6225 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6226 hdr.type3.session_id)), 6227 }, 6228 [ITEM_L2TPV2_MSG_CTRL_NS] = { 6229 .name = "ns", 6230 .help = "sequence number for message", 6231 .next = NEXT(item_l2tpv2_type_ctrl, 6232 NEXT_ENTRY(COMMON_UNSIGNED), 6233 item_param), 6234 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6235 hdr.type3.ns)), 6236 }, 6237 [ITEM_L2TPV2_MSG_CTRL_NR] = { 6238 .name = "nr", 6239 .help = "sequence number for next receive message", 6240 .next = NEXT(item_l2tpv2_type_ctrl, 6241 NEXT_ENTRY(COMMON_UNSIGNED), 6242 item_param), 6243 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6244 hdr.type3.nr)), 6245 }, 6246 [ITEM_PPP] = { 6247 .name = "ppp", 6248 .help = "match PPP header", 6249 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 6250 .next = NEXT(item_ppp), 6251 .call = parse_vc, 6252 }, 6253 [ITEM_PPP_ADDR] = { 6254 .name = "addr", 6255 .help = "PPP address", 6256 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6257 item_param), 6258 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 6259 }, 6260 [ITEM_PPP_CTRL] = { 6261 .name = "ctrl", 6262 .help = "PPP control", 6263 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6264 item_param), 6265 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 6266 }, 6267 [ITEM_PPP_PROTO_ID] = { 6268 .name = "proto_id", 6269 .help = "PPP protocol identifier", 6270 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6271 item_param), 6272 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 6273 hdr.proto_id)), 6274 }, 6275 [ITEM_METER] = { 6276 .name = "meter", 6277 .help = "match meter color", 6278 .priv = PRIV_ITEM(METER_COLOR, 6279 sizeof(struct rte_flow_item_meter_color)), 6280 .next = NEXT(item_meter), 6281 .call = parse_vc, 6282 }, 6283 [ITEM_METER_COLOR] = { 6284 .name = "color", 6285 .help = "meter color", 6286 .next = NEXT(item_meter, 6287 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 6288 item_param), 6289 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 6290 color)), 6291 }, 6292 [ITEM_METER_COLOR_NAME] = { 6293 .name = "color_name", 6294 .help = "meter color name", 6295 .call = parse_meter_color, 6296 .comp = comp_meter_color, 6297 }, 6298 [ITEM_QUOTA] = { 6299 .name = "quota", 6300 .help = "match quota", 6301 .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), 6302 .next = NEXT(item_quota), 6303 .call = parse_vc 6304 }, 6305 [ITEM_QUOTA_STATE] = { 6306 .name = "quota_state", 6307 .help = "quota state", 6308 .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), 6309 NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), 6310 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) 6311 }, 6312 [ITEM_QUOTA_STATE_NAME] = { 6313 .name = "state_name", 6314 .help = "quota state name", 6315 .call = parse_quota_state_name, 6316 .comp = comp_quota_state_name 6317 }, 6318 [ITEM_IB_BTH] = { 6319 .name = "ib_bth", 6320 .help = "match ib bth fields", 6321 .priv = PRIV_ITEM(IB_BTH, 6322 sizeof(struct rte_flow_item_ib_bth)), 6323 .next = NEXT(item_ib_bth), 6324 .call = parse_vc, 6325 }, 6326 [ITEM_IB_BTH_OPCODE] = { 6327 .name = "opcode", 6328 .help = "match ib bth opcode", 6329 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6330 item_param), 6331 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6332 hdr.opcode)), 6333 }, 6334 [ITEM_IB_BTH_PKEY] = { 6335 .name = "pkey", 6336 .help = "partition key", 6337 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6338 item_param), 6339 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6340 hdr.pkey)), 6341 }, 6342 [ITEM_IB_BTH_DST_QPN] = { 6343 .name = "dst_qp", 6344 .help = "destination qp", 6345 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6346 item_param), 6347 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6348 hdr.dst_qp)), 6349 }, 6350 [ITEM_IB_BTH_PSN] = { 6351 .name = "psn", 6352 .help = "packet sequence number", 6353 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6354 item_param), 6355 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6356 hdr.psn)), 6357 }, 6358 [ITEM_PTYPE] = { 6359 .name = "ptype", 6360 .help = "match L2/L3/L4 and tunnel information", 6361 .priv = PRIV_ITEM(PTYPE, 6362 sizeof(struct rte_flow_item_ptype)), 6363 .next = NEXT(item_ptype), 6364 .call = parse_vc, 6365 }, 6366 [ITEM_PTYPE_VALUE] = { 6367 .name = "packet_type", 6368 .help = "packet type as defined in rte_mbuf_ptype", 6369 .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), 6370 item_param), 6371 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), 6372 }, 6373 [ITEM_NSH] = { 6374 .name = "nsh", 6375 .help = "match NSH header", 6376 .priv = PRIV_ITEM(NSH, 6377 sizeof(struct rte_flow_item_nsh)), 6378 .next = NEXT(item_nsh), 6379 .call = parse_vc, 6380 }, 6381 [ITEM_COMPARE] = { 6382 .name = "compare", 6383 .help = "match with the comparison result", 6384 .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)), 6385 .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)), 6386 .call = parse_vc, 6387 }, 6388 [ITEM_COMPARE_OP] = { 6389 .name = "op", 6390 .help = "operation type", 6391 .next = NEXT(item_compare_field, 6392 NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param), 6393 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)), 6394 }, 6395 [ITEM_COMPARE_OP_VALUE] = { 6396 .name = "{operation}", 6397 .help = "operation type value", 6398 .call = parse_vc_compare_op, 6399 .comp = comp_set_compare_op, 6400 }, 6401 [ITEM_COMPARE_FIELD_A_TYPE] = { 6402 .name = "a_type", 6403 .help = "compared field type", 6404 .next = NEXT(compare_field_a, 6405 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param), 6406 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)), 6407 }, 6408 [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = { 6409 .name = "{a_type}", 6410 .help = "compared field type value", 6411 .call = parse_vc_compare_field_id, 6412 .comp = comp_set_compare_field_id, 6413 }, 6414 [ITEM_COMPARE_FIELD_A_LEVEL] = { 6415 .name = "a_level", 6416 .help = "compared field level", 6417 .next = NEXT(compare_field_a, 6418 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param), 6419 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)), 6420 }, 6421 [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = { 6422 .name = "{a_level}", 6423 .help = "compared field level value", 6424 .call = parse_vc_compare_field_level, 6425 .comp = comp_none, 6426 }, 6427 [ITEM_COMPARE_FIELD_A_TAG_INDEX] = { 6428 .name = "a_tag_index", 6429 .help = "compared field tag array", 6430 .next = NEXT(compare_field_a, 6431 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6432 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6433 a.tag_index)), 6434 }, 6435 [ITEM_COMPARE_FIELD_A_TYPE_ID] = { 6436 .name = "a_type_id", 6437 .help = "compared field type ID", 6438 .next = NEXT(compare_field_a, 6439 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6440 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6441 a.type)), 6442 }, 6443 [ITEM_COMPARE_FIELD_A_CLASS_ID] = { 6444 .name = "a_class", 6445 .help = "compared field class ID", 6446 .next = NEXT(compare_field_a, 6447 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6448 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6449 a.class_id)), 6450 }, 6451 [ITEM_COMPARE_FIELD_A_OFFSET] = { 6452 .name = "a_offset", 6453 .help = "compared field bit offset", 6454 .next = NEXT(compare_field_a, 6455 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6456 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6457 a.offset)), 6458 }, 6459 [ITEM_COMPARE_FIELD_B_TYPE] = { 6460 .name = "b_type", 6461 .help = "comparator field type", 6462 .next = NEXT(compare_field_b, 6463 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param), 6464 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6465 b.field)), 6466 }, 6467 [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = { 6468 .name = "{b_type}", 6469 .help = "comparator field type value", 6470 .call = parse_vc_compare_field_id, 6471 .comp = comp_set_compare_field_id, 6472 }, 6473 [ITEM_COMPARE_FIELD_B_LEVEL] = { 6474 .name = "b_level", 6475 .help = "comparator field level", 6476 .next = NEXT(compare_field_b, 6477 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param), 6478 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6479 b.level)), 6480 }, 6481 [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = { 6482 .name = "{b_level}", 6483 .help = "comparator field level value", 6484 .call = parse_vc_compare_field_level, 6485 .comp = comp_none, 6486 }, 6487 [ITEM_COMPARE_FIELD_B_TAG_INDEX] = { 6488 .name = "b_tag_index", 6489 .help = "comparator field tag array", 6490 .next = NEXT(compare_field_b, 6491 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6492 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6493 b.tag_index)), 6494 }, 6495 [ITEM_COMPARE_FIELD_B_TYPE_ID] = { 6496 .name = "b_type_id", 6497 .help = "comparator field type ID", 6498 .next = NEXT(compare_field_b, 6499 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6500 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6501 b.type)), 6502 }, 6503 [ITEM_COMPARE_FIELD_B_CLASS_ID] = { 6504 .name = "b_class", 6505 .help = "comparator field class ID", 6506 .next = NEXT(compare_field_b, 6507 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6508 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6509 b.class_id)), 6510 }, 6511 [ITEM_COMPARE_FIELD_B_OFFSET] = { 6512 .name = "b_offset", 6513 .help = "comparator field bit offset", 6514 .next = NEXT(compare_field_b, 6515 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6516 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6517 b.offset)), 6518 }, 6519 [ITEM_COMPARE_FIELD_B_VALUE] = { 6520 .name = "b_value", 6521 .help = "comparator immediate value", 6522 .next = NEXT(compare_field_b, 6523 NEXT_ENTRY(COMMON_HEX), item_param), 6524 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6525 ARGS_ENTRY_ARB(0, 0), 6526 ARGS_ENTRY(struct rte_flow_item_compare, 6527 b.value)), 6528 }, 6529 [ITEM_COMPARE_FIELD_B_POINTER] = { 6530 .name = "b_ptr", 6531 .help = "pointer to comparator immediate value", 6532 .next = NEXT(compare_field_b, 6533 NEXT_ENTRY(COMMON_HEX), item_param), 6534 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6535 b.pvalue), 6536 ARGS_ENTRY_ARB(0, 0), 6537 ARGS_ENTRY_ARB 6538 (sizeof(struct rte_flow_item_compare), 6539 FLOW_FIELD_PATTERN_SIZE)), 6540 }, 6541 [ITEM_COMPARE_FIELD_WIDTH] = { 6542 .name = "width", 6543 .help = "number of bits to compare", 6544 .next = NEXT(item_compare_field, 6545 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6546 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6547 width)), 6548 }, 6549 6550 /* Validate/create actions. */ 6551 [ACTIONS] = { 6552 .name = "actions", 6553 .help = "submit a list of associated actions", 6554 .next = NEXT(next_action), 6555 .call = parse_vc, 6556 }, 6557 [ACTION_NEXT] = { 6558 .name = "/", 6559 .help = "specify next action", 6560 .next = NEXT(next_action), 6561 }, 6562 [ACTION_END] = { 6563 .name = "end", 6564 .help = "end list of actions", 6565 .priv = PRIV_ACTION(END, 0), 6566 .call = parse_vc, 6567 }, 6568 [ACTION_VOID] = { 6569 .name = "void", 6570 .help = "no-op action", 6571 .priv = PRIV_ACTION(VOID, 0), 6572 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6573 .call = parse_vc, 6574 }, 6575 [ACTION_PASSTHRU] = { 6576 .name = "passthru", 6577 .help = "let subsequent rule process matched packets", 6578 .priv = PRIV_ACTION(PASSTHRU, 0), 6579 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6580 .call = parse_vc, 6581 }, 6582 [ACTION_SKIP_CMAN] = { 6583 .name = "skip_cman", 6584 .help = "bypass cman on received packets", 6585 .priv = PRIV_ACTION(SKIP_CMAN, 0), 6586 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6587 .call = parse_vc, 6588 }, 6589 [ACTION_JUMP] = { 6590 .name = "jump", 6591 .help = "redirect traffic to a given group", 6592 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 6593 .next = NEXT(action_jump), 6594 .call = parse_vc, 6595 }, 6596 [ACTION_JUMP_GROUP] = { 6597 .name = "group", 6598 .help = "group to redirect traffic to", 6599 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 6600 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 6601 .call = parse_vc_conf, 6602 }, 6603 [ACTION_MARK] = { 6604 .name = "mark", 6605 .help = "attach 32 bit value to packets", 6606 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 6607 .next = NEXT(action_mark), 6608 .call = parse_vc, 6609 }, 6610 [ACTION_MARK_ID] = { 6611 .name = "id", 6612 .help = "32 bit value to return with packets", 6613 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6614 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 6615 .call = parse_vc_conf, 6616 }, 6617 [ACTION_FLAG] = { 6618 .name = "flag", 6619 .help = "flag packets", 6620 .priv = PRIV_ACTION(FLAG, 0), 6621 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6622 .call = parse_vc, 6623 }, 6624 [ACTION_QUEUE] = { 6625 .name = "queue", 6626 .help = "assign packets to a given queue index", 6627 .priv = PRIV_ACTION(QUEUE, 6628 sizeof(struct rte_flow_action_queue)), 6629 .next = NEXT(action_queue), 6630 .call = parse_vc, 6631 }, 6632 [ACTION_QUEUE_INDEX] = { 6633 .name = "index", 6634 .help = "queue index to use", 6635 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 6636 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 6637 .call = parse_vc_conf, 6638 }, 6639 [ACTION_DROP] = { 6640 .name = "drop", 6641 .help = "drop packets (note: passthru has priority)", 6642 .priv = PRIV_ACTION(DROP, 0), 6643 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6644 .call = parse_vc, 6645 }, 6646 [ACTION_COUNT] = { 6647 .name = "count", 6648 .help = "enable counters for this rule", 6649 .priv = PRIV_ACTION(COUNT, 6650 sizeof(struct rte_flow_action_count)), 6651 .next = NEXT(action_count), 6652 .call = parse_vc, 6653 }, 6654 [ACTION_COUNT_ID] = { 6655 .name = "identifier", 6656 .help = "counter identifier to use", 6657 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 6658 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 6659 .call = parse_vc_conf, 6660 }, 6661 [ACTION_RSS] = { 6662 .name = "rss", 6663 .help = "spread packets among several queues", 6664 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 6665 .next = NEXT(action_rss), 6666 .call = parse_vc_action_rss, 6667 }, 6668 [ACTION_RSS_FUNC] = { 6669 .name = "func", 6670 .help = "RSS hash function to apply", 6671 .next = NEXT(action_rss, 6672 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 6673 ACTION_RSS_FUNC_TOEPLITZ, 6674 ACTION_RSS_FUNC_SIMPLE_XOR, 6675 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 6676 }, 6677 [ACTION_RSS_FUNC_DEFAULT] = { 6678 .name = "default", 6679 .help = "default hash function", 6680 .call = parse_vc_action_rss_func, 6681 }, 6682 [ACTION_RSS_FUNC_TOEPLITZ] = { 6683 .name = "toeplitz", 6684 .help = "Toeplitz hash function", 6685 .call = parse_vc_action_rss_func, 6686 }, 6687 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 6688 .name = "simple_xor", 6689 .help = "simple XOR hash function", 6690 .call = parse_vc_action_rss_func, 6691 }, 6692 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 6693 .name = "symmetric_toeplitz", 6694 .help = "Symmetric Toeplitz hash function", 6695 .call = parse_vc_action_rss_func, 6696 }, 6697 [ACTION_RSS_LEVEL] = { 6698 .name = "level", 6699 .help = "encapsulation level for \"types\"", 6700 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6701 .args = ARGS(ARGS_ENTRY_ARB 6702 (offsetof(struct action_rss_data, conf) + 6703 offsetof(struct rte_flow_action_rss, level), 6704 sizeof(((struct rte_flow_action_rss *)0)-> 6705 level))), 6706 }, 6707 [ACTION_RSS_TYPES] = { 6708 .name = "types", 6709 .help = "specific RSS hash types", 6710 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 6711 }, 6712 [ACTION_RSS_TYPE] = { 6713 .name = "{type}", 6714 .help = "RSS hash type", 6715 .call = parse_vc_action_rss_type, 6716 .comp = comp_vc_action_rss_type, 6717 }, 6718 [ACTION_RSS_KEY] = { 6719 .name = "key", 6720 .help = "RSS hash key", 6721 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 6722 .args = ARGS(ARGS_ENTRY_ARB 6723 (offsetof(struct action_rss_data, conf) + 6724 offsetof(struct rte_flow_action_rss, key), 6725 sizeof(((struct rte_flow_action_rss *)0)->key)), 6726 ARGS_ENTRY_ARB 6727 (offsetof(struct action_rss_data, conf) + 6728 offsetof(struct rte_flow_action_rss, key_len), 6729 sizeof(((struct rte_flow_action_rss *)0)-> 6730 key_len)), 6731 ARGS_ENTRY(struct action_rss_data, key)), 6732 }, 6733 [ACTION_RSS_KEY_LEN] = { 6734 .name = "key_len", 6735 .help = "RSS hash key length in bytes", 6736 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6737 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6738 (offsetof(struct action_rss_data, conf) + 6739 offsetof(struct rte_flow_action_rss, key_len), 6740 sizeof(((struct rte_flow_action_rss *)0)-> 6741 key_len), 6742 0, 6743 RSS_HASH_KEY_LENGTH)), 6744 }, 6745 [ACTION_RSS_QUEUES] = { 6746 .name = "queues", 6747 .help = "queue indices to use", 6748 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 6749 .call = parse_vc_conf, 6750 }, 6751 [ACTION_RSS_QUEUE] = { 6752 .name = "{queue}", 6753 .help = "queue index", 6754 .call = parse_vc_action_rss_queue, 6755 .comp = comp_vc_action_rss_queue, 6756 }, 6757 [ACTION_PF] = { 6758 .name = "pf", 6759 .help = "direct traffic to physical function", 6760 .priv = PRIV_ACTION(PF, 0), 6761 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6762 .call = parse_vc, 6763 }, 6764 [ACTION_VF] = { 6765 .name = "vf", 6766 .help = "direct traffic to a virtual function ID", 6767 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 6768 .next = NEXT(action_vf), 6769 .call = parse_vc, 6770 }, 6771 [ACTION_VF_ORIGINAL] = { 6772 .name = "original", 6773 .help = "use original VF ID if possible", 6774 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 6775 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 6776 original, 1)), 6777 .call = parse_vc_conf, 6778 }, 6779 [ACTION_VF_ID] = { 6780 .name = "id", 6781 .help = "VF ID", 6782 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 6783 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 6784 .call = parse_vc_conf, 6785 }, 6786 [ACTION_PORT_ID] = { 6787 .name = "port_id", 6788 .help = "direct matching traffic to a given DPDK port ID", 6789 .priv = PRIV_ACTION(PORT_ID, 6790 sizeof(struct rte_flow_action_port_id)), 6791 .next = NEXT(action_port_id), 6792 .call = parse_vc, 6793 }, 6794 [ACTION_PORT_ID_ORIGINAL] = { 6795 .name = "original", 6796 .help = "use original DPDK port ID if possible", 6797 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 6798 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 6799 original, 1)), 6800 .call = parse_vc_conf, 6801 }, 6802 [ACTION_PORT_ID_ID] = { 6803 .name = "id", 6804 .help = "DPDK port ID", 6805 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 6806 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 6807 .call = parse_vc_conf, 6808 }, 6809 [ACTION_METER] = { 6810 .name = "meter", 6811 .help = "meter the directed packets at given id", 6812 .priv = PRIV_ACTION(METER, 6813 sizeof(struct rte_flow_action_meter)), 6814 .next = NEXT(action_meter), 6815 .call = parse_vc, 6816 }, 6817 [ACTION_METER_COLOR] = { 6818 .name = "color", 6819 .help = "meter color for the packets", 6820 .priv = PRIV_ACTION(METER_COLOR, 6821 sizeof(struct rte_flow_action_meter_color)), 6822 .next = NEXT(action_meter_color), 6823 .call = parse_vc, 6824 }, 6825 [ACTION_METER_COLOR_TYPE] = { 6826 .name = "type", 6827 .help = "specific meter color", 6828 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6829 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 6830 ACTION_METER_COLOR_YELLOW, 6831 ACTION_METER_COLOR_RED)), 6832 }, 6833 [ACTION_METER_COLOR_GREEN] = { 6834 .name = "green", 6835 .help = "meter color green", 6836 .call = parse_vc_action_meter_color_type, 6837 }, 6838 [ACTION_METER_COLOR_YELLOW] = { 6839 .name = "yellow", 6840 .help = "meter color yellow", 6841 .call = parse_vc_action_meter_color_type, 6842 }, 6843 [ACTION_METER_COLOR_RED] = { 6844 .name = "red", 6845 .help = "meter color red", 6846 .call = parse_vc_action_meter_color_type, 6847 }, 6848 [ACTION_METER_ID] = { 6849 .name = "mtr_id", 6850 .help = "meter id to use", 6851 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 6852 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 6853 .call = parse_vc_conf, 6854 }, 6855 [ACTION_METER_MARK] = { 6856 .name = "meter_mark", 6857 .help = "meter the directed packets using profile and policy", 6858 .priv = PRIV_ACTION(METER_MARK, 6859 sizeof(struct rte_flow_action_meter_mark)), 6860 .next = NEXT(action_meter_mark), 6861 .call = parse_vc, 6862 }, 6863 [ACTION_METER_PROFILE] = { 6864 .name = "mtr_profile", 6865 .help = "meter profile id to use", 6866 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 6867 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6868 }, 6869 [ACTION_METER_PROFILE_ID2PTR] = { 6870 .name = "{mtr_profile_id}", 6871 .type = "PROFILE_ID", 6872 .help = "meter profile id", 6873 .next = NEXT(action_meter_mark), 6874 .call = parse_meter_profile_id2ptr, 6875 .comp = comp_none, 6876 }, 6877 [ACTION_METER_POLICY] = { 6878 .name = "mtr_policy", 6879 .help = "meter policy id to use", 6880 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 6881 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6882 }, 6883 [ACTION_METER_POLICY_ID2PTR] = { 6884 .name = "{mtr_policy_id}", 6885 .type = "POLICY_ID", 6886 .help = "meter policy id", 6887 .next = NEXT(action_meter_mark), 6888 .call = parse_meter_policy_id2ptr, 6889 .comp = comp_none, 6890 }, 6891 [ACTION_METER_COLOR_MODE] = { 6892 .name = "mtr_color_mode", 6893 .help = "meter color awareness mode", 6894 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6895 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 6896 .call = parse_vc_conf, 6897 }, 6898 [ACTION_METER_STATE] = { 6899 .name = "mtr_state", 6900 .help = "meter state", 6901 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6902 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 6903 .call = parse_vc_conf, 6904 }, 6905 [ACTION_OF_DEC_NW_TTL] = { 6906 .name = "of_dec_nw_ttl", 6907 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 6908 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 6909 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6910 .call = parse_vc, 6911 }, 6912 [ACTION_OF_POP_VLAN] = { 6913 .name = "of_pop_vlan", 6914 .help = "OpenFlow's OFPAT_POP_VLAN", 6915 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 6916 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6917 .call = parse_vc, 6918 }, 6919 [ACTION_OF_PUSH_VLAN] = { 6920 .name = "of_push_vlan", 6921 .help = "OpenFlow's OFPAT_PUSH_VLAN", 6922 .priv = PRIV_ACTION 6923 (OF_PUSH_VLAN, 6924 sizeof(struct rte_flow_action_of_push_vlan)), 6925 .next = NEXT(action_of_push_vlan), 6926 .call = parse_vc, 6927 }, 6928 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 6929 .name = "ethertype", 6930 .help = "EtherType", 6931 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 6932 .args = ARGS(ARGS_ENTRY_HTON 6933 (struct rte_flow_action_of_push_vlan, 6934 ethertype)), 6935 .call = parse_vc_conf, 6936 }, 6937 [ACTION_OF_SET_VLAN_VID] = { 6938 .name = "of_set_vlan_vid", 6939 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 6940 .priv = PRIV_ACTION 6941 (OF_SET_VLAN_VID, 6942 sizeof(struct rte_flow_action_of_set_vlan_vid)), 6943 .next = NEXT(action_of_set_vlan_vid), 6944 .call = parse_vc, 6945 }, 6946 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 6947 .name = "vlan_vid", 6948 .help = "VLAN id", 6949 .next = NEXT(action_of_set_vlan_vid, 6950 NEXT_ENTRY(COMMON_UNSIGNED)), 6951 .args = ARGS(ARGS_ENTRY_HTON 6952 (struct rte_flow_action_of_set_vlan_vid, 6953 vlan_vid)), 6954 .call = parse_vc_conf, 6955 }, 6956 [ACTION_OF_SET_VLAN_PCP] = { 6957 .name = "of_set_vlan_pcp", 6958 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 6959 .priv = PRIV_ACTION 6960 (OF_SET_VLAN_PCP, 6961 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 6962 .next = NEXT(action_of_set_vlan_pcp), 6963 .call = parse_vc, 6964 }, 6965 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 6966 .name = "vlan_pcp", 6967 .help = "VLAN priority", 6968 .next = NEXT(action_of_set_vlan_pcp, 6969 NEXT_ENTRY(COMMON_UNSIGNED)), 6970 .args = ARGS(ARGS_ENTRY_HTON 6971 (struct rte_flow_action_of_set_vlan_pcp, 6972 vlan_pcp)), 6973 .call = parse_vc_conf, 6974 }, 6975 [ACTION_OF_POP_MPLS] = { 6976 .name = "of_pop_mpls", 6977 .help = "OpenFlow's OFPAT_POP_MPLS", 6978 .priv = PRIV_ACTION(OF_POP_MPLS, 6979 sizeof(struct rte_flow_action_of_pop_mpls)), 6980 .next = NEXT(action_of_pop_mpls), 6981 .call = parse_vc, 6982 }, 6983 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 6984 .name = "ethertype", 6985 .help = "EtherType", 6986 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6987 .args = ARGS(ARGS_ENTRY_HTON 6988 (struct rte_flow_action_of_pop_mpls, 6989 ethertype)), 6990 .call = parse_vc_conf, 6991 }, 6992 [ACTION_OF_PUSH_MPLS] = { 6993 .name = "of_push_mpls", 6994 .help = "OpenFlow's OFPAT_PUSH_MPLS", 6995 .priv = PRIV_ACTION 6996 (OF_PUSH_MPLS, 6997 sizeof(struct rte_flow_action_of_push_mpls)), 6998 .next = NEXT(action_of_push_mpls), 6999 .call = parse_vc, 7000 }, 7001 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 7002 .name = "ethertype", 7003 .help = "EtherType", 7004 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 7005 .args = ARGS(ARGS_ENTRY_HTON 7006 (struct rte_flow_action_of_push_mpls, 7007 ethertype)), 7008 .call = parse_vc_conf, 7009 }, 7010 [ACTION_VXLAN_ENCAP] = { 7011 .name = "vxlan_encap", 7012 .help = "VXLAN encapsulation, uses configuration set by \"set" 7013 " vxlan\"", 7014 .priv = PRIV_ACTION(VXLAN_ENCAP, 7015 sizeof(struct action_vxlan_encap_data)), 7016 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7017 .call = parse_vc_action_vxlan_encap, 7018 }, 7019 [ACTION_VXLAN_DECAP] = { 7020 .name = "vxlan_decap", 7021 .help = "Performs a decapsulation action by stripping all" 7022 " headers of the VXLAN tunnel network overlay from the" 7023 " matched flow.", 7024 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 7025 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7026 .call = parse_vc, 7027 }, 7028 [ACTION_NVGRE_ENCAP] = { 7029 .name = "nvgre_encap", 7030 .help = "NVGRE encapsulation, uses configuration set by \"set" 7031 " nvgre\"", 7032 .priv = PRIV_ACTION(NVGRE_ENCAP, 7033 sizeof(struct action_nvgre_encap_data)), 7034 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7035 .call = parse_vc_action_nvgre_encap, 7036 }, 7037 [ACTION_NVGRE_DECAP] = { 7038 .name = "nvgre_decap", 7039 .help = "Performs a decapsulation action by stripping all" 7040 " headers of the NVGRE tunnel network overlay from the" 7041 " matched flow.", 7042 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 7043 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7044 .call = parse_vc, 7045 }, 7046 [ACTION_L2_ENCAP] = { 7047 .name = "l2_encap", 7048 .help = "l2 encap, uses configuration set by" 7049 " \"set l2_encap\"", 7050 .priv = PRIV_ACTION(RAW_ENCAP, 7051 sizeof(struct action_raw_encap_data)), 7052 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7053 .call = parse_vc_action_l2_encap, 7054 }, 7055 [ACTION_L2_DECAP] = { 7056 .name = "l2_decap", 7057 .help = "l2 decap, uses configuration set by" 7058 " \"set l2_decap\"", 7059 .priv = PRIV_ACTION(RAW_DECAP, 7060 sizeof(struct action_raw_decap_data)), 7061 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7062 .call = parse_vc_action_l2_decap, 7063 }, 7064 [ACTION_MPLSOGRE_ENCAP] = { 7065 .name = "mplsogre_encap", 7066 .help = "mplsogre encapsulation, uses configuration set by" 7067 " \"set mplsogre_encap\"", 7068 .priv = PRIV_ACTION(RAW_ENCAP, 7069 sizeof(struct action_raw_encap_data)), 7070 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7071 .call = parse_vc_action_mplsogre_encap, 7072 }, 7073 [ACTION_MPLSOGRE_DECAP] = { 7074 .name = "mplsogre_decap", 7075 .help = "mplsogre decapsulation, uses configuration set by" 7076 " \"set mplsogre_decap\"", 7077 .priv = PRIV_ACTION(RAW_DECAP, 7078 sizeof(struct action_raw_decap_data)), 7079 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7080 .call = parse_vc_action_mplsogre_decap, 7081 }, 7082 [ACTION_MPLSOUDP_ENCAP] = { 7083 .name = "mplsoudp_encap", 7084 .help = "mplsoudp encapsulation, uses configuration set by" 7085 " \"set mplsoudp_encap\"", 7086 .priv = PRIV_ACTION(RAW_ENCAP, 7087 sizeof(struct action_raw_encap_data)), 7088 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7089 .call = parse_vc_action_mplsoudp_encap, 7090 }, 7091 [ACTION_MPLSOUDP_DECAP] = { 7092 .name = "mplsoudp_decap", 7093 .help = "mplsoudp decapsulation, uses configuration set by" 7094 " \"set mplsoudp_decap\"", 7095 .priv = PRIV_ACTION(RAW_DECAP, 7096 sizeof(struct action_raw_decap_data)), 7097 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7098 .call = parse_vc_action_mplsoudp_decap, 7099 }, 7100 [ACTION_SET_IPV4_SRC] = { 7101 .name = "set_ipv4_src", 7102 .help = "Set a new IPv4 source address in the outermost" 7103 " IPv4 header", 7104 .priv = PRIV_ACTION(SET_IPV4_SRC, 7105 sizeof(struct rte_flow_action_set_ipv4)), 7106 .next = NEXT(action_set_ipv4_src), 7107 .call = parse_vc, 7108 }, 7109 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 7110 .name = "ipv4_addr", 7111 .help = "new IPv4 source address to set", 7112 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 7113 .args = ARGS(ARGS_ENTRY_HTON 7114 (struct rte_flow_action_set_ipv4, ipv4_addr)), 7115 .call = parse_vc_conf, 7116 }, 7117 [ACTION_SET_IPV4_DST] = { 7118 .name = "set_ipv4_dst", 7119 .help = "Set a new IPv4 destination address in the outermost" 7120 " IPv4 header", 7121 .priv = PRIV_ACTION(SET_IPV4_DST, 7122 sizeof(struct rte_flow_action_set_ipv4)), 7123 .next = NEXT(action_set_ipv4_dst), 7124 .call = parse_vc, 7125 }, 7126 [ACTION_SET_IPV4_DST_IPV4_DST] = { 7127 .name = "ipv4_addr", 7128 .help = "new IPv4 destination address to set", 7129 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 7130 .args = ARGS(ARGS_ENTRY_HTON 7131 (struct rte_flow_action_set_ipv4, ipv4_addr)), 7132 .call = parse_vc_conf, 7133 }, 7134 [ACTION_SET_IPV6_SRC] = { 7135 .name = "set_ipv6_src", 7136 .help = "Set a new IPv6 source address in the outermost" 7137 " IPv6 header", 7138 .priv = PRIV_ACTION(SET_IPV6_SRC, 7139 sizeof(struct rte_flow_action_set_ipv6)), 7140 .next = NEXT(action_set_ipv6_src), 7141 .call = parse_vc, 7142 }, 7143 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 7144 .name = "ipv6_addr", 7145 .help = "new IPv6 source address to set", 7146 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7147 .args = ARGS(ARGS_ENTRY_HTON 7148 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7149 .call = parse_vc_conf, 7150 }, 7151 [ACTION_SET_IPV6_DST] = { 7152 .name = "set_ipv6_dst", 7153 .help = "Set a new IPv6 destination address in the outermost" 7154 " IPv6 header", 7155 .priv = PRIV_ACTION(SET_IPV6_DST, 7156 sizeof(struct rte_flow_action_set_ipv6)), 7157 .next = NEXT(action_set_ipv6_dst), 7158 .call = parse_vc, 7159 }, 7160 [ACTION_SET_IPV6_DST_IPV6_DST] = { 7161 .name = "ipv6_addr", 7162 .help = "new IPv6 destination address to set", 7163 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7164 .args = ARGS(ARGS_ENTRY_HTON 7165 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7166 .call = parse_vc_conf, 7167 }, 7168 [ACTION_SET_TP_SRC] = { 7169 .name = "set_tp_src", 7170 .help = "set a new source port number in the outermost" 7171 " TCP/UDP header", 7172 .priv = PRIV_ACTION(SET_TP_SRC, 7173 sizeof(struct rte_flow_action_set_tp)), 7174 .next = NEXT(action_set_tp_src), 7175 .call = parse_vc, 7176 }, 7177 [ACTION_SET_TP_SRC_TP_SRC] = { 7178 .name = "port", 7179 .help = "new source port number to set", 7180 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 7181 .args = ARGS(ARGS_ENTRY_HTON 7182 (struct rte_flow_action_set_tp, port)), 7183 .call = parse_vc_conf, 7184 }, 7185 [ACTION_SET_TP_DST] = { 7186 .name = "set_tp_dst", 7187 .help = "set a new destination port number in the outermost" 7188 " TCP/UDP header", 7189 .priv = PRIV_ACTION(SET_TP_DST, 7190 sizeof(struct rte_flow_action_set_tp)), 7191 .next = NEXT(action_set_tp_dst), 7192 .call = parse_vc, 7193 }, 7194 [ACTION_SET_TP_DST_TP_DST] = { 7195 .name = "port", 7196 .help = "new destination port number to set", 7197 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 7198 .args = ARGS(ARGS_ENTRY_HTON 7199 (struct rte_flow_action_set_tp, port)), 7200 .call = parse_vc_conf, 7201 }, 7202 [ACTION_MAC_SWAP] = { 7203 .name = "mac_swap", 7204 .help = "Swap the source and destination MAC addresses" 7205 " in the outermost Ethernet header", 7206 .priv = PRIV_ACTION(MAC_SWAP, 0), 7207 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7208 .call = parse_vc, 7209 }, 7210 [ACTION_DEC_TTL] = { 7211 .name = "dec_ttl", 7212 .help = "decrease network TTL if available", 7213 .priv = PRIV_ACTION(DEC_TTL, 0), 7214 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7215 .call = parse_vc, 7216 }, 7217 [ACTION_SET_TTL] = { 7218 .name = "set_ttl", 7219 .help = "set ttl value", 7220 .priv = PRIV_ACTION(SET_TTL, 7221 sizeof(struct rte_flow_action_set_ttl)), 7222 .next = NEXT(action_set_ttl), 7223 .call = parse_vc, 7224 }, 7225 [ACTION_SET_TTL_TTL] = { 7226 .name = "ttl_value", 7227 .help = "new ttl value to set", 7228 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 7229 .args = ARGS(ARGS_ENTRY_HTON 7230 (struct rte_flow_action_set_ttl, ttl_value)), 7231 .call = parse_vc_conf, 7232 }, 7233 [ACTION_SET_MAC_SRC] = { 7234 .name = "set_mac_src", 7235 .help = "set source mac address", 7236 .priv = PRIV_ACTION(SET_MAC_SRC, 7237 sizeof(struct rte_flow_action_set_mac)), 7238 .next = NEXT(action_set_mac_src), 7239 .call = parse_vc, 7240 }, 7241 [ACTION_SET_MAC_SRC_MAC_SRC] = { 7242 .name = "mac_addr", 7243 .help = "new source mac address", 7244 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 7245 .args = ARGS(ARGS_ENTRY_HTON 7246 (struct rte_flow_action_set_mac, mac_addr)), 7247 .call = parse_vc_conf, 7248 }, 7249 [ACTION_SET_MAC_DST] = { 7250 .name = "set_mac_dst", 7251 .help = "set destination mac address", 7252 .priv = PRIV_ACTION(SET_MAC_DST, 7253 sizeof(struct rte_flow_action_set_mac)), 7254 .next = NEXT(action_set_mac_dst), 7255 .call = parse_vc, 7256 }, 7257 [ACTION_SET_MAC_DST_MAC_DST] = { 7258 .name = "mac_addr", 7259 .help = "new destination mac address to set", 7260 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 7261 .args = ARGS(ARGS_ENTRY_HTON 7262 (struct rte_flow_action_set_mac, mac_addr)), 7263 .call = parse_vc_conf, 7264 }, 7265 [ACTION_INC_TCP_SEQ] = { 7266 .name = "inc_tcp_seq", 7267 .help = "increase TCP sequence number", 7268 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 7269 .next = NEXT(action_inc_tcp_seq), 7270 .call = parse_vc, 7271 }, 7272 [ACTION_INC_TCP_SEQ_VALUE] = { 7273 .name = "value", 7274 .help = "the value to increase TCP sequence number by", 7275 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7276 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7277 .call = parse_vc_conf, 7278 }, 7279 [ACTION_DEC_TCP_SEQ] = { 7280 .name = "dec_tcp_seq", 7281 .help = "decrease TCP sequence number", 7282 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 7283 .next = NEXT(action_dec_tcp_seq), 7284 .call = parse_vc, 7285 }, 7286 [ACTION_DEC_TCP_SEQ_VALUE] = { 7287 .name = "value", 7288 .help = "the value to decrease TCP sequence number by", 7289 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7290 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7291 .call = parse_vc_conf, 7292 }, 7293 [ACTION_INC_TCP_ACK] = { 7294 .name = "inc_tcp_ack", 7295 .help = "increase TCP acknowledgment number", 7296 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 7297 .next = NEXT(action_inc_tcp_ack), 7298 .call = parse_vc, 7299 }, 7300 [ACTION_INC_TCP_ACK_VALUE] = { 7301 .name = "value", 7302 .help = "the value to increase TCP acknowledgment number by", 7303 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7304 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7305 .call = parse_vc_conf, 7306 }, 7307 [ACTION_DEC_TCP_ACK] = { 7308 .name = "dec_tcp_ack", 7309 .help = "decrease TCP acknowledgment number", 7310 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 7311 .next = NEXT(action_dec_tcp_ack), 7312 .call = parse_vc, 7313 }, 7314 [ACTION_DEC_TCP_ACK_VALUE] = { 7315 .name = "value", 7316 .help = "the value to decrease TCP acknowledgment number by", 7317 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7318 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7319 .call = parse_vc_conf, 7320 }, 7321 [ACTION_RAW_ENCAP] = { 7322 .name = "raw_encap", 7323 .help = "encapsulation data, defined by set raw_encap", 7324 .priv = PRIV_ACTION(RAW_ENCAP, 7325 sizeof(struct action_raw_encap_data)), 7326 .next = NEXT(action_raw_encap), 7327 .call = parse_vc_action_raw_encap, 7328 }, 7329 [ACTION_RAW_ENCAP_SIZE] = { 7330 .name = "size", 7331 .help = "raw encap size", 7332 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7333 NEXT_ENTRY(COMMON_UNSIGNED)), 7334 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_raw_encap, size)), 7335 .call = parse_vc_conf, 7336 }, 7337 [ACTION_RAW_ENCAP_INDEX] = { 7338 .name = "index", 7339 .help = "the index of raw_encap_confs", 7340 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 7341 }, 7342 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 7343 .name = "{index}", 7344 .type = "UNSIGNED", 7345 .help = "unsigned integer value", 7346 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7347 .call = parse_vc_action_raw_encap_index, 7348 .comp = comp_set_raw_index, 7349 }, 7350 [ACTION_RAW_DECAP] = { 7351 .name = "raw_decap", 7352 .help = "decapsulation data, defined by set raw_encap", 7353 .priv = PRIV_ACTION(RAW_DECAP, 7354 sizeof(struct action_raw_decap_data)), 7355 .next = NEXT(action_raw_decap), 7356 .call = parse_vc_action_raw_decap, 7357 }, 7358 [ACTION_RAW_DECAP_INDEX] = { 7359 .name = "index", 7360 .help = "the index of raw_encap_confs", 7361 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 7362 }, 7363 [ACTION_RAW_DECAP_INDEX_VALUE] = { 7364 .name = "{index}", 7365 .type = "UNSIGNED", 7366 .help = "unsigned integer value", 7367 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7368 .call = parse_vc_action_raw_decap_index, 7369 .comp = comp_set_raw_index, 7370 }, 7371 [ACTION_MODIFY_FIELD] = { 7372 .name = "modify_field", 7373 .help = "modify destination field with data from source field", 7374 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 7375 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 7376 .call = parse_vc, 7377 }, 7378 [ACTION_MODIFY_FIELD_OP] = { 7379 .name = "op", 7380 .help = "operation type", 7381 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 7382 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 7383 .call = parse_vc_conf, 7384 }, 7385 [ACTION_MODIFY_FIELD_OP_VALUE] = { 7386 .name = "{operation}", 7387 .help = "operation type value", 7388 .call = parse_vc_modify_field_op, 7389 .comp = comp_set_modify_field_op, 7390 }, 7391 [ACTION_MODIFY_FIELD_DST_TYPE] = { 7392 .name = "dst_type", 7393 .help = "destination field type", 7394 .next = NEXT(action_modify_field_dst, 7395 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 7396 .call = parse_vc_conf, 7397 }, 7398 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 7399 .name = "{dst_type}", 7400 .help = "destination field type value", 7401 .call = parse_vc_modify_field_id, 7402 .comp = comp_set_modify_field_id, 7403 }, 7404 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 7405 .name = "dst_level", 7406 .help = "destination field level", 7407 .next = NEXT(action_modify_field_dst, 7408 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), 7409 .call = parse_vc_conf, 7410 }, 7411 [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { 7412 .name = "{dst_level}", 7413 .help = "destination field level value", 7414 .call = parse_vc_modify_field_level, 7415 .comp = comp_none, 7416 }, 7417 [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { 7418 .name = "dst_tag_index", 7419 .help = "destination field tag array", 7420 .next = NEXT(action_modify_field_dst, 7421 NEXT_ENTRY(COMMON_UNSIGNED)), 7422 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7423 dst.tag_index)), 7424 .call = parse_vc_conf, 7425 }, 7426 [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { 7427 .name = "dst_type_id", 7428 .help = "destination field type ID", 7429 .next = NEXT(action_modify_field_dst, 7430 NEXT_ENTRY(COMMON_UNSIGNED)), 7431 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7432 dst.type)), 7433 .call = parse_vc_conf, 7434 }, 7435 [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { 7436 .name = "dst_class", 7437 .help = "destination field class ID", 7438 .next = NEXT(action_modify_field_dst, 7439 NEXT_ENTRY(COMMON_UNSIGNED)), 7440 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7441 dst.class_id)), 7442 .call = parse_vc_conf, 7443 }, 7444 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 7445 .name = "dst_offset", 7446 .help = "destination field bit offset", 7447 .next = NEXT(action_modify_field_dst, 7448 NEXT_ENTRY(COMMON_UNSIGNED)), 7449 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7450 dst.offset)), 7451 .call = parse_vc_conf, 7452 }, 7453 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 7454 .name = "src_type", 7455 .help = "source field type", 7456 .next = NEXT(action_modify_field_src, 7457 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 7458 .call = parse_vc_conf, 7459 }, 7460 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 7461 .name = "{src_type}", 7462 .help = "source field type value", 7463 .call = parse_vc_modify_field_id, 7464 .comp = comp_set_modify_field_id, 7465 }, 7466 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 7467 .name = "src_level", 7468 .help = "source field level", 7469 .next = NEXT(action_modify_field_src, 7470 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), 7471 .call = parse_vc_conf, 7472 }, 7473 [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { 7474 .name = "{src_level}", 7475 .help = "source field level value", 7476 .call = parse_vc_modify_field_level, 7477 .comp = comp_none, 7478 }, 7479 [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { 7480 .name = "src_tag_index", 7481 .help = "source field tag array", 7482 .next = NEXT(action_modify_field_src, 7483 NEXT_ENTRY(COMMON_UNSIGNED)), 7484 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7485 src.tag_index)), 7486 .call = parse_vc_conf, 7487 }, 7488 [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { 7489 .name = "src_type_id", 7490 .help = "source field type ID", 7491 .next = NEXT(action_modify_field_src, 7492 NEXT_ENTRY(COMMON_UNSIGNED)), 7493 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7494 src.type)), 7495 .call = parse_vc_conf, 7496 }, 7497 [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { 7498 .name = "src_class", 7499 .help = "source field class ID", 7500 .next = NEXT(action_modify_field_src, 7501 NEXT_ENTRY(COMMON_UNSIGNED)), 7502 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7503 src.class_id)), 7504 .call = parse_vc_conf, 7505 }, 7506 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 7507 .name = "src_offset", 7508 .help = "source field bit offset", 7509 .next = NEXT(action_modify_field_src, 7510 NEXT_ENTRY(COMMON_UNSIGNED)), 7511 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7512 src.offset)), 7513 .call = parse_vc_conf, 7514 }, 7515 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 7516 .name = "src_value", 7517 .help = "source immediate value", 7518 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7519 NEXT_ENTRY(COMMON_HEX)), 7520 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 7521 ARGS_ENTRY_ARB(0, 0), 7522 ARGS_ENTRY(struct rte_flow_action_modify_field, 7523 src.value)), 7524 .call = parse_vc_conf, 7525 }, 7526 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 7527 .name = "src_ptr", 7528 .help = "pointer to source immediate value", 7529 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7530 NEXT_ENTRY(COMMON_HEX)), 7531 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7532 src.pvalue), 7533 ARGS_ENTRY_ARB(0, 0), 7534 ARGS_ENTRY_ARB 7535 (sizeof(struct rte_flow_action_modify_field), 7536 FLOW_FIELD_PATTERN_SIZE)), 7537 .call = parse_vc_conf, 7538 }, 7539 [ACTION_MODIFY_FIELD_WIDTH] = { 7540 .name = "width", 7541 .help = "number of bits to copy", 7542 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7543 NEXT_ENTRY(COMMON_UNSIGNED)), 7544 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7545 width)), 7546 .call = parse_vc_conf, 7547 }, 7548 [ACTION_SEND_TO_KERNEL] = { 7549 .name = "send_to_kernel", 7550 .help = "send packets to kernel", 7551 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 7552 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7553 .call = parse_vc, 7554 }, 7555 [ACTION_IPV6_EXT_REMOVE] = { 7556 .name = "ipv6_ext_remove", 7557 .help = "IPv6 extension type, defined by set ipv6_ext_remove", 7558 .priv = PRIV_ACTION(IPV6_EXT_REMOVE, 7559 sizeof(struct action_ipv6_ext_remove_data)), 7560 .next = NEXT(action_ipv6_ext_remove), 7561 .call = parse_vc_action_ipv6_ext_remove, 7562 }, 7563 [ACTION_IPV6_EXT_REMOVE_INDEX] = { 7564 .name = "index", 7565 .help = "the index of ipv6_ext_remove", 7566 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), 7567 }, 7568 [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { 7569 .name = "{index}", 7570 .type = "UNSIGNED", 7571 .help = "unsigned integer value", 7572 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7573 .call = parse_vc_action_ipv6_ext_remove_index, 7574 .comp = comp_set_ipv6_ext_index, 7575 }, 7576 [ACTION_IPV6_EXT_PUSH] = { 7577 .name = "ipv6_ext_push", 7578 .help = "IPv6 extension data, defined by set ipv6_ext_push", 7579 .priv = PRIV_ACTION(IPV6_EXT_PUSH, 7580 sizeof(struct action_ipv6_ext_push_data)), 7581 .next = NEXT(action_ipv6_ext_push), 7582 .call = parse_vc_action_ipv6_ext_push, 7583 }, 7584 [ACTION_IPV6_EXT_PUSH_INDEX] = { 7585 .name = "index", 7586 .help = "the index of ipv6_ext_push", 7587 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), 7588 }, 7589 [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { 7590 .name = "{index}", 7591 .type = "UNSIGNED", 7592 .help = "unsigned integer value", 7593 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7594 .call = parse_vc_action_ipv6_ext_push_index, 7595 .comp = comp_set_ipv6_ext_index, 7596 }, 7597 [ACTION_NAT64] = { 7598 .name = "nat64", 7599 .help = "NAT64 IP headers translation", 7600 .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), 7601 .next = NEXT(action_nat64), 7602 .call = parse_vc, 7603 }, 7604 [ACTION_NAT64_MODE] = { 7605 .name = "type", 7606 .help = "NAT64 translation type", 7607 .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), 7608 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), 7609 .call = parse_vc_conf, 7610 }, 7611 [ACTION_JUMP_TO_TABLE_INDEX] = { 7612 .name = "jump_to_table_index", 7613 .help = "Jump to table index", 7614 .priv = PRIV_ACTION(JUMP_TO_TABLE_INDEX, 7615 sizeof(struct rte_flow_action_jump_to_table_index)), 7616 .next = NEXT(action_jump_to_table_index), 7617 .call = parse_vc, 7618 }, 7619 [ACTION_JUMP_TO_TABLE_INDEX_TABLE] = { 7620 .name = "table", 7621 .help = "table to redirect traffic to", 7622 .next = NEXT(action_jump_to_table_index, NEXT_ENTRY(COMMON_UNSIGNED)), 7623 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump_to_table_index, table)), 7624 .call = parse_vc_conf, 7625 }, 7626 [ACTION_JUMP_TO_TABLE_INDEX_INDEX] = { 7627 .name = "index", 7628 .help = "rule index to redirect traffic to", 7629 .next = NEXT(action_jump_to_table_index, NEXT_ENTRY(COMMON_UNSIGNED)), 7630 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump_to_table_index, index)), 7631 .call = parse_vc_conf, 7632 }, 7633 7634 /* Top level command. */ 7635 [SET] = { 7636 .name = "set", 7637 .help = "set raw encap/decap/sample data", 7638 .type = "set raw_encap|raw_decap <index> <pattern>" 7639 " or set sample_actions <index> <action>", 7640 .next = NEXT(NEXT_ENTRY 7641 (SET_RAW_ENCAP, 7642 SET_RAW_DECAP, 7643 SET_SAMPLE_ACTIONS, 7644 SET_IPV6_EXT_REMOVE, 7645 SET_IPV6_EXT_PUSH)), 7646 .call = parse_set_init, 7647 }, 7648 /* Sub-level commands. */ 7649 [SET_RAW_ENCAP] = { 7650 .name = "raw_encap", 7651 .help = "set raw encap data", 7652 .next = NEXT(next_set_raw), 7653 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7654 (offsetof(struct buffer, port), 7655 sizeof(((struct buffer *)0)->port), 7656 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7657 .call = parse_set_raw_encap_decap, 7658 }, 7659 [SET_RAW_DECAP] = { 7660 .name = "raw_decap", 7661 .help = "set raw decap data", 7662 .next = NEXT(next_set_raw), 7663 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7664 (offsetof(struct buffer, port), 7665 sizeof(((struct buffer *)0)->port), 7666 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7667 .call = parse_set_raw_encap_decap, 7668 }, 7669 [SET_RAW_INDEX] = { 7670 .name = "{index}", 7671 .type = "COMMON_UNSIGNED", 7672 .help = "index of raw_encap/raw_decap data", 7673 .next = NEXT(next_item), 7674 .call = parse_port, 7675 }, 7676 [SET_SAMPLE_INDEX] = { 7677 .name = "{index}", 7678 .type = "UNSIGNED", 7679 .help = "index of sample actions", 7680 .next = NEXT(next_action_sample), 7681 .call = parse_port, 7682 }, 7683 [SET_SAMPLE_ACTIONS] = { 7684 .name = "sample_actions", 7685 .help = "set sample actions list", 7686 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 7687 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7688 (offsetof(struct buffer, port), 7689 sizeof(((struct buffer *)0)->port), 7690 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 7691 .call = parse_set_sample_action, 7692 }, 7693 [SET_IPV6_EXT_PUSH] = { 7694 .name = "ipv6_ext_push", 7695 .help = "set IPv6 extension header", 7696 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7697 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7698 (offsetof(struct buffer, port), 7699 sizeof(((struct buffer *)0)->port), 7700 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7701 .call = parse_set_ipv6_ext_action, 7702 }, 7703 [SET_IPV6_EXT_REMOVE] = { 7704 .name = "ipv6_ext_remove", 7705 .help = "set IPv6 extension header", 7706 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7707 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7708 (offsetof(struct buffer, port), 7709 sizeof(((struct buffer *)0)->port), 7710 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7711 .call = parse_set_ipv6_ext_action, 7712 }, 7713 [SET_IPV6_EXT_INDEX] = { 7714 .name = "{index}", 7715 .type = "UNSIGNED", 7716 .help = "index of ipv6 extension push/remove actions", 7717 .next = NEXT(item_ipv6_push_ext), 7718 .call = parse_port, 7719 }, 7720 [ITEM_IPV6_PUSH_REMOVE_EXT] = { 7721 .name = "ipv6_ext", 7722 .help = "set IPv6 extension header", 7723 .priv = PRIV_ITEM(IPV6_EXT, 7724 sizeof(struct rte_flow_item_ipv6_ext)), 7725 .next = NEXT(item_ipv6_push_ext_type), 7726 .call = parse_vc, 7727 }, 7728 [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { 7729 .name = "type", 7730 .help = "set IPv6 extension type", 7731 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 7732 next_hdr)), 7733 .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), 7734 item_param), 7735 }, 7736 [ACTION_SET_TAG] = { 7737 .name = "set_tag", 7738 .help = "set tag", 7739 .priv = PRIV_ACTION(SET_TAG, 7740 sizeof(struct rte_flow_action_set_tag)), 7741 .next = NEXT(action_set_tag), 7742 .call = parse_vc, 7743 }, 7744 [ACTION_SET_TAG_INDEX] = { 7745 .name = "index", 7746 .help = "index of tag array", 7747 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7748 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 7749 .call = parse_vc_conf, 7750 }, 7751 [ACTION_SET_TAG_DATA] = { 7752 .name = "data", 7753 .help = "tag value", 7754 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7755 .args = ARGS(ARGS_ENTRY 7756 (struct rte_flow_action_set_tag, data)), 7757 .call = parse_vc_conf, 7758 }, 7759 [ACTION_SET_TAG_MASK] = { 7760 .name = "mask", 7761 .help = "mask for tag value", 7762 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7763 .args = ARGS(ARGS_ENTRY 7764 (struct rte_flow_action_set_tag, mask)), 7765 .call = parse_vc_conf, 7766 }, 7767 [ACTION_SET_META] = { 7768 .name = "set_meta", 7769 .help = "set metadata", 7770 .priv = PRIV_ACTION(SET_META, 7771 sizeof(struct rte_flow_action_set_meta)), 7772 .next = NEXT(action_set_meta), 7773 .call = parse_vc_action_set_meta, 7774 }, 7775 [ACTION_SET_META_DATA] = { 7776 .name = "data", 7777 .help = "metadata value", 7778 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7779 .args = ARGS(ARGS_ENTRY 7780 (struct rte_flow_action_set_meta, data)), 7781 .call = parse_vc_conf, 7782 }, 7783 [ACTION_SET_META_MASK] = { 7784 .name = "mask", 7785 .help = "mask for metadata value", 7786 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7787 .args = ARGS(ARGS_ENTRY 7788 (struct rte_flow_action_set_meta, mask)), 7789 .call = parse_vc_conf, 7790 }, 7791 [ACTION_SET_IPV4_DSCP] = { 7792 .name = "set_ipv4_dscp", 7793 .help = "set DSCP value", 7794 .priv = PRIV_ACTION(SET_IPV4_DSCP, 7795 sizeof(struct rte_flow_action_set_dscp)), 7796 .next = NEXT(action_set_ipv4_dscp), 7797 .call = parse_vc, 7798 }, 7799 [ACTION_SET_IPV4_DSCP_VALUE] = { 7800 .name = "dscp_value", 7801 .help = "new IPv4 DSCP value to set", 7802 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7803 .args = ARGS(ARGS_ENTRY 7804 (struct rte_flow_action_set_dscp, dscp)), 7805 .call = parse_vc_conf, 7806 }, 7807 [ACTION_SET_IPV6_DSCP] = { 7808 .name = "set_ipv6_dscp", 7809 .help = "set DSCP value", 7810 .priv = PRIV_ACTION(SET_IPV6_DSCP, 7811 sizeof(struct rte_flow_action_set_dscp)), 7812 .next = NEXT(action_set_ipv6_dscp), 7813 .call = parse_vc, 7814 }, 7815 [ACTION_SET_IPV6_DSCP_VALUE] = { 7816 .name = "dscp_value", 7817 .help = "new IPv6 DSCP value to set", 7818 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7819 .args = ARGS(ARGS_ENTRY 7820 (struct rte_flow_action_set_dscp, dscp)), 7821 .call = parse_vc_conf, 7822 }, 7823 [ACTION_AGE] = { 7824 .name = "age", 7825 .help = "set a specific metadata header", 7826 .next = NEXT(action_age), 7827 .priv = PRIV_ACTION(AGE, 7828 sizeof(struct rte_flow_action_age)), 7829 .call = parse_vc, 7830 }, 7831 [ACTION_AGE_TIMEOUT] = { 7832 .name = "timeout", 7833 .help = "flow age timeout value", 7834 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 7835 timeout, 24)), 7836 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 7837 .call = parse_vc_conf, 7838 }, 7839 [ACTION_AGE_UPDATE] = { 7840 .name = "age_update", 7841 .help = "update aging parameter", 7842 .next = NEXT(action_age_update), 7843 .priv = PRIV_ACTION(AGE, 7844 sizeof(struct rte_flow_update_age)), 7845 .call = parse_vc, 7846 }, 7847 [ACTION_AGE_UPDATE_TIMEOUT] = { 7848 .name = "timeout", 7849 .help = "age timeout update value", 7850 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7851 timeout, 24)), 7852 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7853 .call = parse_vc_conf_timeout, 7854 }, 7855 [ACTION_AGE_UPDATE_TOUCH] = { 7856 .name = "touch", 7857 .help = "this flow is touched", 7858 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), 7859 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7860 touch, 1)), 7861 .call = parse_vc_conf, 7862 }, 7863 [ACTION_SAMPLE] = { 7864 .name = "sample", 7865 .help = "set a sample action", 7866 .next = NEXT(action_sample), 7867 .priv = PRIV_ACTION(SAMPLE, 7868 sizeof(struct action_sample_data)), 7869 .call = parse_vc_action_sample, 7870 }, 7871 [ACTION_SAMPLE_RATIO] = { 7872 .name = "ratio", 7873 .help = "flow sample ratio value", 7874 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 7875 .args = ARGS(ARGS_ENTRY_ARB 7876 (offsetof(struct action_sample_data, conf) + 7877 offsetof(struct rte_flow_action_sample, ratio), 7878 sizeof(((struct rte_flow_action_sample *)0)-> 7879 ratio))), 7880 }, 7881 [ACTION_SAMPLE_INDEX] = { 7882 .name = "index", 7883 .help = "the index of sample actions list", 7884 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 7885 }, 7886 [ACTION_SAMPLE_INDEX_VALUE] = { 7887 .name = "{index}", 7888 .type = "COMMON_UNSIGNED", 7889 .help = "unsigned integer value", 7890 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7891 .call = parse_vc_action_sample_index, 7892 .comp = comp_set_sample_index, 7893 }, 7894 [ACTION_CONNTRACK] = { 7895 .name = "conntrack", 7896 .help = "create a conntrack object", 7897 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7898 .priv = PRIV_ACTION(CONNTRACK, 7899 sizeof(struct rte_flow_action_conntrack)), 7900 .call = parse_vc, 7901 }, 7902 [ACTION_CONNTRACK_UPDATE] = { 7903 .name = "conntrack_update", 7904 .help = "update a conntrack object", 7905 .next = NEXT(action_update_conntrack), 7906 .priv = PRIV_ACTION(CONNTRACK, 7907 sizeof(struct rte_flow_modify_conntrack)), 7908 .call = parse_vc, 7909 }, 7910 [ACTION_CONNTRACK_UPDATE_DIR] = { 7911 .name = "dir", 7912 .help = "update a conntrack object direction", 7913 .next = NEXT(action_update_conntrack), 7914 .call = parse_vc_action_conntrack_update, 7915 }, 7916 [ACTION_CONNTRACK_UPDATE_CTX] = { 7917 .name = "ctx", 7918 .help = "update a conntrack object context", 7919 .next = NEXT(action_update_conntrack), 7920 .call = parse_vc_action_conntrack_update, 7921 }, 7922 [ACTION_PORT_REPRESENTOR] = { 7923 .name = "port_representor", 7924 .help = "at embedded switch level, send matching traffic to the given ethdev", 7925 .priv = PRIV_ACTION(PORT_REPRESENTOR, 7926 sizeof(struct rte_flow_action_ethdev)), 7927 .next = NEXT(action_port_representor), 7928 .call = parse_vc, 7929 }, 7930 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 7931 .name = "port_id", 7932 .help = "ethdev port ID", 7933 .next = NEXT(action_port_representor, 7934 NEXT_ENTRY(COMMON_UNSIGNED)), 7935 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7936 port_id)), 7937 .call = parse_vc_conf, 7938 }, 7939 [ACTION_REPRESENTED_PORT] = { 7940 .name = "represented_port", 7941 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 7942 .priv = PRIV_ACTION(REPRESENTED_PORT, 7943 sizeof(struct rte_flow_action_ethdev)), 7944 .next = NEXT(action_represented_port), 7945 .call = parse_vc, 7946 }, 7947 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 7948 .name = "ethdev_port_id", 7949 .help = "ethdev port ID", 7950 .next = NEXT(action_represented_port, 7951 NEXT_ENTRY(COMMON_UNSIGNED)), 7952 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7953 port_id)), 7954 .call = parse_vc_conf, 7955 }, 7956 /* Indirect action destroy arguments. */ 7957 [INDIRECT_ACTION_DESTROY_ID] = { 7958 .name = "action_id", 7959 .help = "specify a indirect action id to destroy", 7960 .next = NEXT(next_ia_destroy_attr, 7961 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7962 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 7963 args.ia_destroy.action_id)), 7964 .call = parse_ia_destroy, 7965 }, 7966 /* Indirect action create arguments. */ 7967 [INDIRECT_ACTION_CREATE_ID] = { 7968 .name = "action_id", 7969 .help = "specify a indirect action id to create", 7970 .next = NEXT(next_ia_create_attr, 7971 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7972 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 7973 }, 7974 [ACTION_INDIRECT] = { 7975 .name = "indirect", 7976 .help = "apply indirect action by id", 7977 .priv = PRIV_ACTION(INDIRECT, 0), 7978 .next = NEXT(next_ia), 7979 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7980 .call = parse_vc, 7981 }, 7982 [ACTION_INDIRECT_LIST] = { 7983 .name = "indirect_list", 7984 .help = "apply indirect list action by id", 7985 .priv = PRIV_ACTION(INDIRECT_LIST, 7986 sizeof(struct 7987 rte_flow_action_indirect_list)), 7988 .next = NEXT(next_ial), 7989 .call = parse_vc, 7990 }, 7991 [ACTION_INDIRECT_LIST_HANDLE] = { 7992 .name = "handle", 7993 .help = "indirect list handle", 7994 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), 7995 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7996 }, 7997 [ACTION_INDIRECT_LIST_CONF] = { 7998 .name = "conf", 7999 .help = "indirect list configuration", 8000 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), 8001 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 8002 }, 8003 [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { 8004 .type = "UNSIGNED", 8005 .help = "unsigned integer value", 8006 .call = parse_indlst_id2ptr, 8007 .comp = comp_none, 8008 }, 8009 [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { 8010 .type = "UNSIGNED", 8011 .help = "unsigned integer value", 8012 .call = parse_indlst_id2ptr, 8013 .comp = comp_none, 8014 }, 8015 [ACTION_SHARED_INDIRECT] = { 8016 .name = "shared_indirect", 8017 .help = "apply indirect action by id and port", 8018 .priv = PRIV_ACTION(INDIRECT, 0), 8019 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), 8020 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), 8021 ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 8022 .call = parse_vc, 8023 }, 8024 [INDIRECT_ACTION_PORT] = { 8025 .name = "{indirect_action_port}", 8026 .type = "INDIRECT_ACTION_PORT", 8027 .help = "indirect action port", 8028 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 8029 .call = parse_ia_port, 8030 .comp = comp_none, 8031 }, 8032 [INDIRECT_ACTION_ID2PTR] = { 8033 .name = "{action_id}", 8034 .type = "INDIRECT_ACTION_ID", 8035 .help = "indirect action id", 8036 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 8037 .call = parse_ia_id2ptr, 8038 .comp = comp_none, 8039 }, 8040 [INDIRECT_ACTION_INGRESS] = { 8041 .name = "ingress", 8042 .help = "affect rule to ingress", 8043 .next = NEXT(next_ia_create_attr), 8044 .call = parse_ia, 8045 }, 8046 [INDIRECT_ACTION_EGRESS] = { 8047 .name = "egress", 8048 .help = "affect rule to egress", 8049 .next = NEXT(next_ia_create_attr), 8050 .call = parse_ia, 8051 }, 8052 [INDIRECT_ACTION_TRANSFER] = { 8053 .name = "transfer", 8054 .help = "affect rule to transfer", 8055 .next = NEXT(next_ia_create_attr), 8056 .call = parse_ia, 8057 }, 8058 [INDIRECT_ACTION_SPEC] = { 8059 .name = "action", 8060 .help = "specify action to create indirect handle", 8061 .next = NEXT(next_action), 8062 }, 8063 [INDIRECT_ACTION_LIST] = { 8064 .name = "list", 8065 .help = "specify actions for indirect handle list", 8066 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 8067 .call = parse_ia, 8068 }, 8069 [INDIRECT_ACTION_FLOW_CONF] = { 8070 .name = "flow_conf", 8071 .help = "specify actions configuration for indirect handle list", 8072 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 8073 .call = parse_ia, 8074 }, 8075 [ACTION_POL_G] = { 8076 .name = "g_actions", 8077 .help = "submit a list of associated actions for green", 8078 .next = NEXT(next_action), 8079 .call = parse_mp, 8080 }, 8081 [ACTION_POL_Y] = { 8082 .name = "y_actions", 8083 .help = "submit a list of associated actions for yellow", 8084 .next = NEXT(next_action), 8085 }, 8086 [ACTION_POL_R] = { 8087 .name = "r_actions", 8088 .help = "submit a list of associated actions for red", 8089 .next = NEXT(next_action), 8090 }, 8091 [ACTION_QUOTA_CREATE] = { 8092 .name = "quota_create", 8093 .help = "create quota action", 8094 .priv = PRIV_ACTION(QUOTA, 8095 sizeof(struct rte_flow_action_quota)), 8096 .next = NEXT(action_quota_create), 8097 .call = parse_vc 8098 }, 8099 [ACTION_QUOTA_CREATE_LIMIT] = { 8100 .name = "limit", 8101 .help = "quota limit", 8102 .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), 8103 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), 8104 .call = parse_vc_conf 8105 }, 8106 [ACTION_QUOTA_CREATE_MODE] = { 8107 .name = "mode", 8108 .help = "quota mode", 8109 .next = NEXT(action_quota_create, 8110 NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), 8111 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), 8112 .call = parse_vc_conf 8113 }, 8114 [ACTION_QUOTA_CREATE_MODE_NAME] = { 8115 .name = "mode_name", 8116 .help = "quota mode name", 8117 .call = parse_quota_mode_name, 8118 .comp = comp_quota_mode_name 8119 }, 8120 [ACTION_QUOTA_QU] = { 8121 .name = "quota_update", 8122 .help = "update quota action", 8123 .priv = PRIV_ACTION(QUOTA, 8124 sizeof(struct rte_flow_update_quota)), 8125 .next = NEXT(action_quota_update), 8126 .call = parse_vc 8127 }, 8128 [ACTION_QUOTA_QU_LIMIT] = { 8129 .name = "limit", 8130 .help = "quota limit", 8131 .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), 8132 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), 8133 .call = parse_vc_conf 8134 }, 8135 [ACTION_QUOTA_QU_UPDATE_OP] = { 8136 .name = "update_op", 8137 .help = "query update op SET|ADD", 8138 .next = NEXT(action_quota_update, 8139 NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), 8140 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), 8141 .call = parse_vc_conf 8142 }, 8143 [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { 8144 .name = "update_op_name", 8145 .help = "quota update op name", 8146 .call = parse_quota_update_name, 8147 .comp = comp_quota_update_name 8148 }, 8149 8150 /* Top-level command. */ 8151 [ADD] = { 8152 .name = "add", 8153 .type = "port meter policy {port_id} {arg}", 8154 .help = "add port meter policy", 8155 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 8156 .call = parse_init, 8157 }, 8158 /* Sub-level commands. */ 8159 [ITEM_POL_PORT] = { 8160 .name = "port", 8161 .help = "add port meter policy", 8162 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 8163 }, 8164 [ITEM_POL_METER] = { 8165 .name = "meter", 8166 .help = "add port meter policy", 8167 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 8168 }, 8169 [ITEM_POL_POLICY] = { 8170 .name = "policy", 8171 .help = "add port meter policy", 8172 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 8173 NEXT_ENTRY(ACTION_POL_Y), 8174 NEXT_ENTRY(ACTION_POL_G), 8175 NEXT_ENTRY(COMMON_POLICY_ID), 8176 NEXT_ENTRY(COMMON_PORT_ID)), 8177 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 8178 ARGS_ENTRY(struct buffer, port)), 8179 .call = parse_mp, 8180 }, 8181 [ITEM_AGGR_AFFINITY] = { 8182 .name = "aggr_affinity", 8183 .help = "match on the aggregated port receiving the packets", 8184 .priv = PRIV_ITEM(AGGR_AFFINITY, 8185 sizeof(struct rte_flow_item_aggr_affinity)), 8186 .next = NEXT(item_aggr_affinity), 8187 .call = parse_vc, 8188 }, 8189 [ITEM_AGGR_AFFINITY_VALUE] = { 8190 .name = "affinity", 8191 .help = "aggregated affinity value", 8192 .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), 8193 item_param), 8194 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, 8195 affinity)), 8196 }, 8197 [ITEM_TX_QUEUE] = { 8198 .name = "tx_queue", 8199 .help = "match on the tx queue of send packet", 8200 .priv = PRIV_ITEM(TX_QUEUE, 8201 sizeof(struct rte_flow_item_tx_queue)), 8202 .next = NEXT(item_tx_queue), 8203 .call = parse_vc, 8204 }, 8205 [ITEM_TX_QUEUE_VALUE] = { 8206 .name = "tx_queue_value", 8207 .help = "tx queue value", 8208 .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), 8209 item_param), 8210 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, 8211 tx_queue)), 8212 }, 8213 }; 8214 8215 /** Remove and return last entry from argument stack. */ 8216 static const struct arg * 8217 pop_args(struct context *ctx) 8218 { 8219 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 8220 } 8221 8222 /** Add entry on top of the argument stack. */ 8223 static int 8224 push_args(struct context *ctx, const struct arg *arg) 8225 { 8226 if (ctx->args_num == CTX_STACK_SIZE) 8227 return -1; 8228 ctx->args[ctx->args_num++] = arg; 8229 return 0; 8230 } 8231 8232 /** Spread value into buffer according to bit-mask. */ 8233 static size_t 8234 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 8235 { 8236 uint32_t i = arg->size; 8237 uint32_t end = 0; 8238 int sub = 1; 8239 int add = 0; 8240 size_t len = 0; 8241 8242 if (!arg->mask) 8243 return 0; 8244 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8245 if (!arg->hton) { 8246 i = 0; 8247 end = arg->size; 8248 sub = 0; 8249 add = 1; 8250 } 8251 #endif 8252 while (i != end) { 8253 unsigned int shift = 0; 8254 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 8255 8256 for (shift = 0; arg->mask[i] >> shift; ++shift) { 8257 if (!(arg->mask[i] & (1 << shift))) 8258 continue; 8259 ++len; 8260 if (!dst) 8261 continue; 8262 *buf &= ~(1 << shift); 8263 *buf |= (val & 1) << shift; 8264 val >>= 1; 8265 } 8266 i += add; 8267 } 8268 return len; 8269 } 8270 8271 /** Compare a string with a partial one of a given length. */ 8272 static int 8273 strcmp_partial(const char *full, const char *partial, size_t partial_len) 8274 { 8275 int r = strncmp(full, partial, partial_len); 8276 8277 if (r) 8278 return r; 8279 if (strlen(full) <= partial_len) 8280 return 0; 8281 return full[partial_len]; 8282 } 8283 8284 /** 8285 * Parse a prefix length and generate a bit-mask. 8286 * 8287 * Last argument (ctx->args) is retrieved to determine mask size, storage 8288 * location and whether the result must use network byte ordering. 8289 */ 8290 static int 8291 parse_prefix(struct context *ctx, const struct token *token, 8292 const char *str, unsigned int len, 8293 void *buf, unsigned int size) 8294 { 8295 const struct arg *arg = pop_args(ctx); 8296 static const uint8_t conv[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 8297 0xf8, 0xfc, 0xfe, 0xff }; 8298 char *end; 8299 uintmax_t u; 8300 unsigned int bytes; 8301 unsigned int extra; 8302 8303 (void)token; 8304 /* Argument is expected. */ 8305 if (!arg) 8306 return -1; 8307 errno = 0; 8308 u = strtoumax(str, &end, 0); 8309 if (errno || (size_t)(end - str) != len) 8310 goto error; 8311 if (arg->mask) { 8312 uintmax_t v = 0; 8313 8314 extra = arg_entry_bf_fill(NULL, 0, arg); 8315 if (u > extra) 8316 goto error; 8317 if (!ctx->object) 8318 return len; 8319 extra -= u; 8320 while (u--) 8321 (v <<= 1, v |= 1); 8322 v <<= extra; 8323 if (!arg_entry_bf_fill(ctx->object, v, arg) || 8324 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 8325 goto error; 8326 return len; 8327 } 8328 bytes = u / 8; 8329 extra = u % 8; 8330 size = arg->size; 8331 if (bytes > size || bytes + !!extra > size) 8332 goto error; 8333 if (!ctx->object) 8334 return len; 8335 buf = (uint8_t *)ctx->object + arg->offset; 8336 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8337 if (!arg->hton) { 8338 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 8339 memset(buf, 0x00, size - bytes); 8340 if (extra) 8341 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 8342 } else 8343 #endif 8344 { 8345 memset(buf, 0xff, bytes); 8346 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 8347 if (extra) 8348 ((uint8_t *)buf)[bytes] = conv[extra]; 8349 } 8350 if (ctx->objmask) 8351 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 8352 return len; 8353 error: 8354 push_args(ctx, arg); 8355 return -1; 8356 } 8357 8358 /** Default parsing function for token name matching. */ 8359 static int 8360 parse_default(struct context *ctx, const struct token *token, 8361 const char *str, unsigned int len, 8362 void *buf, unsigned int size) 8363 { 8364 (void)ctx; 8365 (void)buf; 8366 (void)size; 8367 if (strcmp_partial(token->name, str, len)) 8368 return -1; 8369 return len; 8370 } 8371 8372 /** Parse flow command, initialize output buffer for subsequent tokens. */ 8373 static int 8374 parse_init(struct context *ctx, const struct token *token, 8375 const char *str, unsigned int len, 8376 void *buf, unsigned int size) 8377 { 8378 struct buffer *out = buf; 8379 8380 /* Token name must match. */ 8381 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8382 return -1; 8383 /* Nothing else to do if there is no buffer. */ 8384 if (!out) 8385 return len; 8386 /* Make sure buffer is large enough. */ 8387 if (size < sizeof(*out)) 8388 return -1; 8389 /* Initialize buffer. */ 8390 memset(out, 0x00, sizeof(*out)); 8391 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 8392 ctx->objdata = 0; 8393 ctx->object = out; 8394 ctx->objmask = NULL; 8395 return len; 8396 } 8397 8398 /** Parse tokens for indirect action commands. */ 8399 static int 8400 parse_ia(struct context *ctx, const struct token *token, 8401 const char *str, unsigned int len, 8402 void *buf, unsigned int size) 8403 { 8404 struct buffer *out = buf; 8405 8406 /* Token name must match. */ 8407 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8408 return -1; 8409 /* Nothing else to do if there is no buffer. */ 8410 if (!out) 8411 return len; 8412 if (!out->command) { 8413 if (ctx->curr != INDIRECT_ACTION) 8414 return -1; 8415 if (sizeof(*out) > size) 8416 return -1; 8417 out->command = ctx->curr; 8418 ctx->objdata = 0; 8419 ctx->object = out; 8420 ctx->objmask = NULL; 8421 out->args.vc.data = (uint8_t *)out + size; 8422 return len; 8423 } 8424 switch (ctx->curr) { 8425 case INDIRECT_ACTION_CREATE: 8426 case INDIRECT_ACTION_UPDATE: 8427 case INDIRECT_ACTION_QUERY_UPDATE: 8428 out->args.vc.actions = 8429 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8430 sizeof(double)); 8431 out->args.vc.attr.group = UINT32_MAX; 8432 /* fallthrough */ 8433 case INDIRECT_ACTION_QUERY: 8434 out->command = ctx->curr; 8435 ctx->objdata = 0; 8436 ctx->object = out; 8437 ctx->objmask = NULL; 8438 return len; 8439 case INDIRECT_ACTION_EGRESS: 8440 out->args.vc.attr.egress = 1; 8441 return len; 8442 case INDIRECT_ACTION_INGRESS: 8443 out->args.vc.attr.ingress = 1; 8444 return len; 8445 case INDIRECT_ACTION_TRANSFER: 8446 out->args.vc.attr.transfer = 1; 8447 return len; 8448 case INDIRECT_ACTION_QU_MODE: 8449 return len; 8450 case INDIRECT_ACTION_LIST: 8451 out->command = INDIRECT_ACTION_LIST_CREATE; 8452 return len; 8453 case INDIRECT_ACTION_FLOW_CONF: 8454 out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; 8455 return len; 8456 default: 8457 return -1; 8458 } 8459 } 8460 8461 8462 /** Parse tokens for indirect action destroy command. */ 8463 static int 8464 parse_ia_destroy(struct context *ctx, const struct token *token, 8465 const char *str, unsigned int len, 8466 void *buf, unsigned int size) 8467 { 8468 struct buffer *out = buf; 8469 uint32_t *action_id; 8470 8471 /* Token name must match. */ 8472 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8473 return -1; 8474 /* Nothing else to do if there is no buffer. */ 8475 if (!out) 8476 return len; 8477 if (!out->command || out->command == INDIRECT_ACTION) { 8478 if (ctx->curr != INDIRECT_ACTION_DESTROY) 8479 return -1; 8480 if (sizeof(*out) > size) 8481 return -1; 8482 out->command = ctx->curr; 8483 ctx->objdata = 0; 8484 ctx->object = out; 8485 ctx->objmask = NULL; 8486 out->args.ia_destroy.action_id = 8487 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8488 sizeof(double)); 8489 return len; 8490 } 8491 action_id = out->args.ia_destroy.action_id 8492 + out->args.ia_destroy.action_id_n++; 8493 if ((uint8_t *)action_id > (uint8_t *)out + size) 8494 return -1; 8495 ctx->objdata = 0; 8496 ctx->object = action_id; 8497 ctx->objmask = NULL; 8498 return len; 8499 } 8500 8501 /** Parse tokens for indirect action commands. */ 8502 static int 8503 parse_qia(struct context *ctx, const struct token *token, 8504 const char *str, unsigned int len, 8505 void *buf, unsigned int size) 8506 { 8507 struct buffer *out = buf; 8508 8509 /* Token name must match. */ 8510 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8511 return -1; 8512 /* Nothing else to do if there is no buffer. */ 8513 if (!out) 8514 return len; 8515 if (!out->command) { 8516 if (ctx->curr != QUEUE) 8517 return -1; 8518 if (sizeof(*out) > size) 8519 return -1; 8520 out->args.vc.data = (uint8_t *)out + size; 8521 return len; 8522 } 8523 switch (ctx->curr) { 8524 case QUEUE_INDIRECT_ACTION: 8525 return len; 8526 case QUEUE_INDIRECT_ACTION_CREATE: 8527 case QUEUE_INDIRECT_ACTION_UPDATE: 8528 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 8529 out->args.vc.actions = 8530 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8531 sizeof(double)); 8532 out->args.vc.attr.group = UINT32_MAX; 8533 /* fallthrough */ 8534 case QUEUE_INDIRECT_ACTION_QUERY: 8535 out->command = ctx->curr; 8536 ctx->objdata = 0; 8537 ctx->object = out; 8538 ctx->objmask = NULL; 8539 return len; 8540 case QUEUE_INDIRECT_ACTION_EGRESS: 8541 out->args.vc.attr.egress = 1; 8542 return len; 8543 case QUEUE_INDIRECT_ACTION_INGRESS: 8544 out->args.vc.attr.ingress = 1; 8545 return len; 8546 case QUEUE_INDIRECT_ACTION_TRANSFER: 8547 out->args.vc.attr.transfer = 1; 8548 return len; 8549 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 8550 return len; 8551 case QUEUE_INDIRECT_ACTION_QU_MODE: 8552 return len; 8553 case QUEUE_INDIRECT_ACTION_LIST: 8554 out->command = QUEUE_INDIRECT_ACTION_LIST_CREATE; 8555 return len; 8556 default: 8557 return -1; 8558 } 8559 } 8560 8561 /** Parse tokens for indirect action destroy command. */ 8562 static int 8563 parse_qia_destroy(struct context *ctx, const struct token *token, 8564 const char *str, unsigned int len, 8565 void *buf, unsigned int size) 8566 { 8567 struct buffer *out = buf; 8568 uint32_t *action_id; 8569 8570 /* Token name must match. */ 8571 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8572 return -1; 8573 /* Nothing else to do if there is no buffer. */ 8574 if (!out) 8575 return len; 8576 if (!out->command || out->command == QUEUE) { 8577 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 8578 return -1; 8579 if (sizeof(*out) > size) 8580 return -1; 8581 out->command = ctx->curr; 8582 ctx->objdata = 0; 8583 ctx->object = out; 8584 ctx->objmask = NULL; 8585 out->args.ia_destroy.action_id = 8586 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8587 sizeof(double)); 8588 return len; 8589 } 8590 switch (ctx->curr) { 8591 case QUEUE_INDIRECT_ACTION: 8592 out->command = ctx->curr; 8593 ctx->objdata = 0; 8594 ctx->object = out; 8595 ctx->objmask = NULL; 8596 return len; 8597 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 8598 action_id = out->args.ia_destroy.action_id 8599 + out->args.ia_destroy.action_id_n++; 8600 if ((uint8_t *)action_id > (uint8_t *)out + size) 8601 return -1; 8602 ctx->objdata = 0; 8603 ctx->object = action_id; 8604 ctx->objmask = NULL; 8605 return len; 8606 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 8607 return len; 8608 default: 8609 return -1; 8610 } 8611 } 8612 8613 /** Parse tokens for meter policy action commands. */ 8614 static int 8615 parse_mp(struct context *ctx, const struct token *token, 8616 const char *str, unsigned int len, 8617 void *buf, unsigned int size) 8618 { 8619 struct buffer *out = buf; 8620 8621 /* Token name must match. */ 8622 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8623 return -1; 8624 /* Nothing else to do if there is no buffer. */ 8625 if (!out) 8626 return len; 8627 if (!out->command) { 8628 if (ctx->curr != ITEM_POL_POLICY) 8629 return -1; 8630 if (sizeof(*out) > size) 8631 return -1; 8632 out->command = ctx->curr; 8633 ctx->objdata = 0; 8634 ctx->object = out; 8635 ctx->objmask = NULL; 8636 out->args.vc.data = (uint8_t *)out + size; 8637 return len; 8638 } 8639 switch (ctx->curr) { 8640 case ACTION_POL_G: 8641 out->args.vc.actions = 8642 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8643 sizeof(double)); 8644 out->command = ctx->curr; 8645 ctx->objdata = 0; 8646 ctx->object = out; 8647 ctx->objmask = NULL; 8648 return len; 8649 default: 8650 return -1; 8651 } 8652 } 8653 8654 /** Parse tokens for validate/create commands. */ 8655 static int 8656 parse_vc(struct context *ctx, const struct token *token, 8657 const char *str, unsigned int len, 8658 void *buf, unsigned int size) 8659 { 8660 struct buffer *out = buf; 8661 uint8_t *data; 8662 uint32_t data_size; 8663 8664 /* Token name must match. */ 8665 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8666 return -1; 8667 /* Nothing else to do if there is no buffer. */ 8668 if (!out) 8669 return len; 8670 if (!out->command) { 8671 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 8672 ctx->curr != PATTERN_TEMPLATE_CREATE && 8673 ctx->curr != ACTIONS_TEMPLATE_CREATE && 8674 ctx->curr != UPDATE) 8675 return -1; 8676 if (ctx->curr == UPDATE) 8677 out->args.vc.pattern = 8678 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8679 sizeof(double)); 8680 if (sizeof(*out) > size) 8681 return -1; 8682 out->command = ctx->curr; 8683 ctx->objdata = 0; 8684 ctx->object = out; 8685 ctx->objmask = NULL; 8686 out->args.vc.data = (uint8_t *)out + size; 8687 return len; 8688 } 8689 ctx->objdata = 0; 8690 switch (ctx->curr) { 8691 default: 8692 ctx->object = &out->args.vc.attr; 8693 break; 8694 case VC_TUNNEL_SET: 8695 case VC_TUNNEL_MATCH: 8696 ctx->object = &out->args.vc.tunnel_ops; 8697 break; 8698 case VC_USER_ID: 8699 ctx->object = out; 8700 break; 8701 } 8702 ctx->objmask = NULL; 8703 switch (ctx->curr) { 8704 case VC_GROUP: 8705 case VC_PRIORITY: 8706 case VC_USER_ID: 8707 return len; 8708 case VC_TUNNEL_SET: 8709 out->args.vc.tunnel_ops.enabled = 1; 8710 out->args.vc.tunnel_ops.actions = 1; 8711 return len; 8712 case VC_TUNNEL_MATCH: 8713 out->args.vc.tunnel_ops.enabled = 1; 8714 out->args.vc.tunnel_ops.items = 1; 8715 return len; 8716 case VC_INGRESS: 8717 out->args.vc.attr.ingress = 1; 8718 return len; 8719 case VC_EGRESS: 8720 out->args.vc.attr.egress = 1; 8721 return len; 8722 case VC_TRANSFER: 8723 out->args.vc.attr.transfer = 1; 8724 return len; 8725 case ITEM_PATTERN: 8726 out->args.vc.pattern = 8727 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8728 sizeof(double)); 8729 ctx->object = out->args.vc.pattern; 8730 ctx->objmask = NULL; 8731 return len; 8732 case ITEM_END: 8733 if ((out->command == VALIDATE || out->command == CREATE) && 8734 ctx->last) 8735 return -1; 8736 if (out->command == PATTERN_TEMPLATE_CREATE && 8737 !ctx->last) 8738 return -1; 8739 break; 8740 case ACTIONS: 8741 out->args.vc.actions = out->args.vc.pattern ? 8742 (void *)RTE_ALIGN_CEIL((uintptr_t) 8743 (out->args.vc.pattern + 8744 out->args.vc.pattern_n), 8745 sizeof(double)) : 8746 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8747 sizeof(double)); 8748 ctx->object = out->args.vc.actions; 8749 ctx->objmask = NULL; 8750 return len; 8751 case VC_IS_USER_ID: 8752 out->args.vc.user_id = true; 8753 return len; 8754 default: 8755 if (!token->priv) 8756 return -1; 8757 break; 8758 } 8759 if (!out->args.vc.actions) { 8760 const struct parse_item_priv *priv = token->priv; 8761 struct rte_flow_item *item = 8762 out->args.vc.pattern + out->args.vc.pattern_n; 8763 8764 data_size = priv->size * 3; /* spec, last, mask */ 8765 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8766 (out->args.vc.data - data_size), 8767 sizeof(double)); 8768 if ((uint8_t *)item + sizeof(*item) > data) 8769 return -1; 8770 *item = (struct rte_flow_item){ 8771 .type = priv->type, 8772 }; 8773 ++out->args.vc.pattern_n; 8774 ctx->object = item; 8775 ctx->objmask = NULL; 8776 } else { 8777 const struct parse_action_priv *priv = token->priv; 8778 struct rte_flow_action *action = 8779 out->args.vc.actions + out->args.vc.actions_n; 8780 8781 data_size = priv->size; /* configuration */ 8782 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8783 (out->args.vc.data - data_size), 8784 sizeof(double)); 8785 if ((uint8_t *)action + sizeof(*action) > data) 8786 return -1; 8787 *action = (struct rte_flow_action){ 8788 .type = priv->type, 8789 .conf = data_size ? data : NULL, 8790 }; 8791 ++out->args.vc.actions_n; 8792 ctx->object = action; 8793 ctx->objmask = NULL; 8794 } 8795 memset(data, 0, data_size); 8796 out->args.vc.data = data; 8797 ctx->objdata = data_size; 8798 return len; 8799 } 8800 8801 /** Parse pattern item parameter type. */ 8802 static int 8803 parse_vc_spec(struct context *ctx, const struct token *token, 8804 const char *str, unsigned int len, 8805 void *buf, unsigned int size) 8806 { 8807 struct buffer *out = buf; 8808 struct rte_flow_item *item; 8809 uint32_t data_size; 8810 int index; 8811 int objmask = 0; 8812 8813 (void)size; 8814 /* Token name must match. */ 8815 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8816 return -1; 8817 /* Parse parameter types. */ 8818 switch (ctx->curr) { 8819 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 8820 8821 case ITEM_PARAM_IS: 8822 index = 0; 8823 objmask = 1; 8824 break; 8825 case ITEM_PARAM_SPEC: 8826 index = 0; 8827 break; 8828 case ITEM_PARAM_LAST: 8829 index = 1; 8830 break; 8831 case ITEM_PARAM_PREFIX: 8832 /* Modify next token to expect a prefix. */ 8833 if (ctx->next_num < 2) 8834 return -1; 8835 ctx->next[ctx->next_num - 2] = prefix; 8836 /* Fall through. */ 8837 case ITEM_PARAM_MASK: 8838 index = 2; 8839 break; 8840 default: 8841 return -1; 8842 } 8843 /* Nothing else to do if there is no buffer. */ 8844 if (!out) 8845 return len; 8846 if (!out->args.vc.pattern_n) 8847 return -1; 8848 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8849 data_size = ctx->objdata / 3; /* spec, last, mask */ 8850 /* Point to selected object. */ 8851 ctx->object = out->args.vc.data + (data_size * index); 8852 if (objmask) { 8853 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 8854 item->mask = ctx->objmask; 8855 } else 8856 ctx->objmask = NULL; 8857 /* Update relevant item pointer. */ 8858 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 8859 ctx->object; 8860 return len; 8861 } 8862 8863 /** Parse action configuration field. */ 8864 static int 8865 parse_vc_conf(struct context *ctx, const struct token *token, 8866 const char *str, unsigned int len, 8867 void *buf, unsigned int size) 8868 { 8869 struct buffer *out = buf; 8870 8871 (void)size; 8872 /* Token name must match. */ 8873 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8874 return -1; 8875 /* Nothing else to do if there is no buffer. */ 8876 if (!out) 8877 return len; 8878 /* Point to selected object. */ 8879 ctx->object = out->args.vc.data; 8880 ctx->objmask = NULL; 8881 return len; 8882 } 8883 8884 /** Parse action configuration field. */ 8885 static int 8886 parse_vc_conf_timeout(struct context *ctx, const struct token *token, 8887 const char *str, unsigned int len, 8888 void *buf, unsigned int size) 8889 { 8890 struct buffer *out = buf; 8891 struct rte_flow_update_age *update; 8892 8893 (void)size; 8894 if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) 8895 return -1; 8896 /* Token name must match. */ 8897 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8898 return -1; 8899 /* Nothing else to do if there is no buffer. */ 8900 if (!out) 8901 return len; 8902 /* Point to selected object. */ 8903 ctx->object = out->args.vc.data; 8904 ctx->objmask = NULL; 8905 /* Update the timeout is valid. */ 8906 update = (struct rte_flow_update_age *)out->args.vc.data; 8907 update->timeout_valid = 1; 8908 return len; 8909 } 8910 8911 /** Parse eCPRI common header type field. */ 8912 static int 8913 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 8914 const char *str, unsigned int len, 8915 void *buf, unsigned int size) 8916 { 8917 struct rte_flow_item_ecpri *ecpri; 8918 struct rte_flow_item_ecpri *ecpri_mask; 8919 struct rte_flow_item *item; 8920 uint32_t data_size; 8921 uint8_t msg_type; 8922 struct buffer *out = buf; 8923 const struct arg *arg; 8924 8925 (void)size; 8926 /* Token name must match. */ 8927 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8928 return -1; 8929 switch (ctx->curr) { 8930 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 8931 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 8932 break; 8933 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 8934 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 8935 break; 8936 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 8937 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 8938 break; 8939 default: 8940 return -1; 8941 } 8942 if (!ctx->object) 8943 return len; 8944 arg = pop_args(ctx); 8945 if (!arg) 8946 return -1; 8947 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 8948 ecpri->hdr.common.type = msg_type; 8949 data_size = ctx->objdata / 3; /* spec, last, mask */ 8950 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 8951 (data_size * 2)); 8952 ecpri_mask->hdr.common.type = 0xFF; 8953 if (arg->hton) { 8954 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 8955 ecpri_mask->hdr.common.u32 = 8956 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 8957 } 8958 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8959 item->spec = ecpri; 8960 item->mask = ecpri_mask; 8961 return len; 8962 } 8963 8964 /** Parse L2TPv2 common header type field. */ 8965 static int 8966 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, 8967 const char *str, unsigned int len, 8968 void *buf, unsigned int size) 8969 { 8970 struct rte_flow_item_l2tpv2 *l2tpv2; 8971 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 8972 struct rte_flow_item *item; 8973 uint32_t data_size; 8974 uint16_t msg_type = 0; 8975 struct buffer *out = buf; 8976 const struct arg *arg; 8977 8978 (void)size; 8979 /* Token name must match. */ 8980 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8981 return -1; 8982 switch (ctx->curr) { 8983 case ITEM_L2TPV2_TYPE_DATA: 8984 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 8985 break; 8986 case ITEM_L2TPV2_TYPE_DATA_L: 8987 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 8988 break; 8989 case ITEM_L2TPV2_TYPE_DATA_S: 8990 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 8991 break; 8992 case ITEM_L2TPV2_TYPE_DATA_O: 8993 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 8994 break; 8995 case ITEM_L2TPV2_TYPE_DATA_L_S: 8996 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 8997 break; 8998 case ITEM_L2TPV2_TYPE_CTRL: 8999 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 9000 break; 9001 default: 9002 return -1; 9003 } 9004 if (!ctx->object) 9005 return len; 9006 arg = pop_args(ctx); 9007 if (!arg) 9008 return -1; 9009 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 9010 l2tpv2->hdr.common.flags_version |= msg_type; 9011 data_size = ctx->objdata / 3; /* spec, last, mask */ 9012 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 9013 (data_size * 2)); 9014 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 9015 if (arg->hton) { 9016 l2tpv2->hdr.common.flags_version = 9017 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 9018 l2tpv2_mask->hdr.common.flags_version = 9019 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 9020 } 9021 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 9022 item->spec = l2tpv2; 9023 item->mask = l2tpv2_mask; 9024 return len; 9025 } 9026 9027 /** Parse operation for compare match item. */ 9028 static int 9029 parse_vc_compare_op(struct context *ctx, const struct token *token, 9030 const char *str, unsigned int len, void *buf, 9031 unsigned int size) 9032 { 9033 struct rte_flow_item_compare *compare_item; 9034 unsigned int i; 9035 9036 (void)token; 9037 (void)buf; 9038 (void)size; 9039 if (ctx->curr != ITEM_COMPARE_OP_VALUE) 9040 return -1; 9041 for (i = 0; compare_ops[i]; ++i) 9042 if (!strcmp_partial(compare_ops[i], str, len)) 9043 break; 9044 if (!compare_ops[i]) 9045 return -1; 9046 if (!ctx->object) 9047 return len; 9048 compare_item = ctx->object; 9049 compare_item->operation = (enum rte_flow_item_compare_op)i; 9050 return len; 9051 } 9052 9053 /** Parse id for compare match item. */ 9054 static int 9055 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 9056 const char *str, unsigned int len, void *buf, 9057 unsigned int size) 9058 { 9059 struct rte_flow_item_compare *compare_item; 9060 unsigned int i; 9061 9062 (void)token; 9063 (void)buf; 9064 (void)size; 9065 if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE && 9066 ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE) 9067 return -1; 9068 for (i = 0; flow_field_ids[i]; ++i) 9069 if (!strcmp_partial(flow_field_ids[i], str, len)) 9070 break; 9071 if (!flow_field_ids[i]) 9072 return -1; 9073 if (!ctx->object) 9074 return len; 9075 compare_item = ctx->object; 9076 if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE) 9077 compare_item->a.field = (enum rte_flow_field_id)i; 9078 else 9079 compare_item->b.field = (enum rte_flow_field_id)i; 9080 return len; 9081 } 9082 9083 /** Parse level for compare match item. */ 9084 static int 9085 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 9086 const char *str, unsigned int len, void *buf, 9087 unsigned int size) 9088 { 9089 struct rte_flow_item_compare *compare_item; 9090 struct flex_item *fp = NULL; 9091 uint32_t val; 9092 struct buffer *out = buf; 9093 char *end; 9094 9095 (void)token; 9096 (void)size; 9097 if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 9098 ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE) 9099 return -1; 9100 if (!ctx->object) 9101 return len; 9102 compare_item = ctx->object; 9103 errno = 0; 9104 val = strtoumax(str, &end, 0); 9105 if (errno || (size_t)(end - str) != len) 9106 return -1; 9107 /* No need to validate action template mask value */ 9108 if (out->args.vc.masks) { 9109 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) 9110 compare_item->a.level = val; 9111 else 9112 compare_item->b.level = val; 9113 return len; 9114 } 9115 if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 9116 compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) || 9117 (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE && 9118 compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 9119 if (val >= FLEX_MAX_PARSERS_NUM) { 9120 printf("Bad flex item handle\n"); 9121 return -1; 9122 } 9123 fp = flex_items[ctx->port][val]; 9124 if (!fp) { 9125 printf("Bad flex item handle\n"); 9126 return -1; 9127 } 9128 } 9129 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) { 9130 if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM) 9131 compare_item->a.level = val; 9132 else 9133 compare_item->a.flex_handle = fp->flex_handle; 9134 } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) { 9135 if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM) 9136 compare_item->b.level = val; 9137 else 9138 compare_item->b.flex_handle = fp->flex_handle; 9139 } 9140 return len; 9141 } 9142 9143 /** Parse meter color action type. */ 9144 static int 9145 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 9146 const char *str, unsigned int len, 9147 void *buf, unsigned int size) 9148 { 9149 struct rte_flow_action *action_data; 9150 struct rte_flow_action_meter_color *conf; 9151 enum rte_color color; 9152 9153 (void)buf; 9154 (void)size; 9155 /* Token name must match. */ 9156 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9157 return -1; 9158 switch (ctx->curr) { 9159 case ACTION_METER_COLOR_GREEN: 9160 color = RTE_COLOR_GREEN; 9161 break; 9162 case ACTION_METER_COLOR_YELLOW: 9163 color = RTE_COLOR_YELLOW; 9164 break; 9165 case ACTION_METER_COLOR_RED: 9166 color = RTE_COLOR_RED; 9167 break; 9168 default: 9169 return -1; 9170 } 9171 9172 if (!ctx->object) 9173 return len; 9174 action_data = ctx->object; 9175 conf = (struct rte_flow_action_meter_color *) 9176 (uintptr_t)(action_data->conf); 9177 conf->color = color; 9178 return len; 9179 } 9180 9181 /** Parse RSS action. */ 9182 static int 9183 parse_vc_action_rss(struct context *ctx, const struct token *token, 9184 const char *str, unsigned int len, 9185 void *buf, unsigned int size) 9186 { 9187 struct buffer *out = buf; 9188 struct rte_flow_action *action; 9189 struct action_rss_data *action_rss_data; 9190 unsigned int i; 9191 int ret; 9192 9193 ret = parse_vc(ctx, token, str, len, buf, size); 9194 if (ret < 0) 9195 return ret; 9196 /* Nothing else to do if there is no buffer. */ 9197 if (!out) 9198 return ret; 9199 if (!out->args.vc.actions_n) 9200 return -1; 9201 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9202 /* Point to selected object. */ 9203 ctx->object = out->args.vc.data; 9204 ctx->objmask = NULL; 9205 /* Set up default configuration. */ 9206 action_rss_data = ctx->object; 9207 *action_rss_data = (struct action_rss_data){ 9208 .conf = (struct rte_flow_action_rss){ 9209 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 9210 .level = 0, 9211 .types = rss_hf, 9212 .key_len = 0, 9213 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 9214 .key = NULL, 9215 .queue = action_rss_data->queue, 9216 }, 9217 .queue = { 0 }, 9218 }; 9219 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 9220 action_rss_data->queue[i] = i; 9221 action->conf = &action_rss_data->conf; 9222 return ret; 9223 } 9224 9225 /** 9226 * Parse func field for RSS action. 9227 * 9228 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 9229 * ACTION_RSS_FUNC_* index that called this function. 9230 */ 9231 static int 9232 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 9233 const char *str, unsigned int len, 9234 void *buf, unsigned int size) 9235 { 9236 struct action_rss_data *action_rss_data; 9237 enum rte_eth_hash_function func; 9238 9239 (void)buf; 9240 (void)size; 9241 /* Token name must match. */ 9242 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9243 return -1; 9244 switch (ctx->curr) { 9245 case ACTION_RSS_FUNC_DEFAULT: 9246 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 9247 break; 9248 case ACTION_RSS_FUNC_TOEPLITZ: 9249 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 9250 break; 9251 case ACTION_RSS_FUNC_SIMPLE_XOR: 9252 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 9253 break; 9254 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 9255 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 9256 break; 9257 default: 9258 return -1; 9259 } 9260 if (!ctx->object) 9261 return len; 9262 action_rss_data = ctx->object; 9263 action_rss_data->conf.func = func; 9264 return len; 9265 } 9266 9267 /** 9268 * Parse type field for RSS action. 9269 * 9270 * Valid tokens are type field names and the "end" token. 9271 */ 9272 static int 9273 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 9274 const char *str, unsigned int len, 9275 void *buf, unsigned int size) 9276 { 9277 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 9278 struct action_rss_data *action_rss_data; 9279 unsigned int i; 9280 9281 (void)token; 9282 (void)buf; 9283 (void)size; 9284 if (ctx->curr != ACTION_RSS_TYPE) 9285 return -1; 9286 if (!(ctx->objdata >> 16) && ctx->object) { 9287 action_rss_data = ctx->object; 9288 action_rss_data->conf.types = 0; 9289 } 9290 if (!strcmp_partial("end", str, len)) { 9291 ctx->objdata &= 0xffff; 9292 return len; 9293 } 9294 for (i = 0; rss_type_table[i].str; ++i) 9295 if (!strcmp_partial(rss_type_table[i].str, str, len)) 9296 break; 9297 if (!rss_type_table[i].str) 9298 return -1; 9299 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 9300 /* Repeat token. */ 9301 if (ctx->next_num == RTE_DIM(ctx->next)) 9302 return -1; 9303 ctx->next[ctx->next_num++] = next; 9304 if (!ctx->object) 9305 return len; 9306 action_rss_data = ctx->object; 9307 action_rss_data->conf.types |= rss_type_table[i].rss_type; 9308 return len; 9309 } 9310 9311 /** 9312 * Parse queue field for RSS action. 9313 * 9314 * Valid tokens are queue indices and the "end" token. 9315 */ 9316 static int 9317 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 9318 const char *str, unsigned int len, 9319 void *buf, unsigned int size) 9320 { 9321 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 9322 struct action_rss_data *action_rss_data; 9323 const struct arg *arg; 9324 int ret; 9325 int i; 9326 9327 (void)token; 9328 (void)buf; 9329 (void)size; 9330 if (ctx->curr != ACTION_RSS_QUEUE) 9331 return -1; 9332 i = ctx->objdata >> 16; 9333 if (!strcmp_partial("end", str, len)) { 9334 ctx->objdata &= 0xffff; 9335 goto end; 9336 } 9337 if (i >= ACTION_RSS_QUEUE_NUM) 9338 return -1; 9339 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 9340 i * sizeof(action_rss_data->queue[i]), 9341 sizeof(action_rss_data->queue[i])); 9342 if (push_args(ctx, arg)) 9343 return -1; 9344 ret = parse_int(ctx, token, str, len, NULL, 0); 9345 if (ret < 0) { 9346 pop_args(ctx); 9347 return -1; 9348 } 9349 ++i; 9350 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 9351 /* Repeat token. */ 9352 if (ctx->next_num == RTE_DIM(ctx->next)) 9353 return -1; 9354 ctx->next[ctx->next_num++] = next; 9355 end: 9356 if (!ctx->object) 9357 return len; 9358 action_rss_data = ctx->object; 9359 action_rss_data->conf.queue_num = i; 9360 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 9361 return len; 9362 } 9363 9364 /** Setup VXLAN encap configuration. */ 9365 static int 9366 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 9367 { 9368 /* Set up default configuration. */ 9369 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 9370 .conf = (struct rte_flow_action_vxlan_encap){ 9371 .definition = action_vxlan_encap_data->items, 9372 }, 9373 .items = { 9374 { 9375 .type = RTE_FLOW_ITEM_TYPE_ETH, 9376 .spec = &action_vxlan_encap_data->item_eth, 9377 .mask = &rte_flow_item_eth_mask, 9378 }, 9379 { 9380 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9381 .spec = &action_vxlan_encap_data->item_vlan, 9382 .mask = &rte_flow_item_vlan_mask, 9383 }, 9384 { 9385 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9386 .spec = &action_vxlan_encap_data->item_ipv4, 9387 .mask = &rte_flow_item_ipv4_mask, 9388 }, 9389 { 9390 .type = RTE_FLOW_ITEM_TYPE_UDP, 9391 .spec = &action_vxlan_encap_data->item_udp, 9392 .mask = &rte_flow_item_udp_mask, 9393 }, 9394 { 9395 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 9396 .spec = &action_vxlan_encap_data->item_vxlan, 9397 .mask = &rte_flow_item_vxlan_mask, 9398 }, 9399 { 9400 .type = RTE_FLOW_ITEM_TYPE_END, 9401 }, 9402 }, 9403 .item_eth.hdr.ether_type = 0, 9404 .item_vlan = { 9405 .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, 9406 .hdr.eth_proto = 0, 9407 }, 9408 .item_ipv4.hdr = { 9409 .src_addr = vxlan_encap_conf.ipv4_src, 9410 .dst_addr = vxlan_encap_conf.ipv4_dst, 9411 }, 9412 .item_udp.hdr = { 9413 .src_port = vxlan_encap_conf.udp_src, 9414 .dst_port = vxlan_encap_conf.udp_dst, 9415 }, 9416 .item_vxlan.hdr.flags = 0, 9417 }; 9418 memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9419 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9420 memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, 9421 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9422 if (!vxlan_encap_conf.select_ipv4) { 9423 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 9424 &vxlan_encap_conf.ipv6_src, 9425 sizeof(vxlan_encap_conf.ipv6_src)); 9426 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 9427 &vxlan_encap_conf.ipv6_dst, 9428 sizeof(vxlan_encap_conf.ipv6_dst)); 9429 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 9430 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9431 .spec = &action_vxlan_encap_data->item_ipv6, 9432 .mask = &rte_flow_item_ipv6_mask, 9433 }; 9434 } 9435 if (!vxlan_encap_conf.select_vlan) 9436 action_vxlan_encap_data->items[1].type = 9437 RTE_FLOW_ITEM_TYPE_VOID; 9438 if (vxlan_encap_conf.select_tos_ttl) { 9439 if (vxlan_encap_conf.select_ipv4) { 9440 static struct rte_flow_item_ipv4 ipv4_mask_tos; 9441 9442 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 9443 sizeof(ipv4_mask_tos)); 9444 ipv4_mask_tos.hdr.type_of_service = 0xff; 9445 ipv4_mask_tos.hdr.time_to_live = 0xff; 9446 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 9447 vxlan_encap_conf.ip_tos; 9448 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 9449 vxlan_encap_conf.ip_ttl; 9450 action_vxlan_encap_data->items[2].mask = 9451 &ipv4_mask_tos; 9452 } else { 9453 static struct rte_flow_item_ipv6 ipv6_mask_tos; 9454 9455 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 9456 sizeof(ipv6_mask_tos)); 9457 ipv6_mask_tos.hdr.vtc_flow |= 9458 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 9459 ipv6_mask_tos.hdr.hop_limits = 0xff; 9460 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 9461 rte_cpu_to_be_32 9462 ((uint32_t)vxlan_encap_conf.ip_tos << 9463 RTE_IPV6_HDR_TC_SHIFT); 9464 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 9465 vxlan_encap_conf.ip_ttl; 9466 action_vxlan_encap_data->items[2].mask = 9467 &ipv6_mask_tos; 9468 } 9469 } 9470 memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, 9471 RTE_DIM(vxlan_encap_conf.vni)); 9472 return 0; 9473 } 9474 9475 /** Parse VXLAN encap action. */ 9476 static int 9477 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 9478 const char *str, unsigned int len, 9479 void *buf, unsigned int size) 9480 { 9481 struct buffer *out = buf; 9482 struct rte_flow_action *action; 9483 struct action_vxlan_encap_data *action_vxlan_encap_data; 9484 int ret; 9485 9486 ret = parse_vc(ctx, token, str, len, buf, size); 9487 if (ret < 0) 9488 return ret; 9489 /* Nothing else to do if there is no buffer. */ 9490 if (!out) 9491 return ret; 9492 if (!out->args.vc.actions_n) 9493 return -1; 9494 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9495 /* Point to selected object. */ 9496 ctx->object = out->args.vc.data; 9497 ctx->objmask = NULL; 9498 action_vxlan_encap_data = ctx->object; 9499 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 9500 action->conf = &action_vxlan_encap_data->conf; 9501 return ret; 9502 } 9503 9504 /** Setup NVGRE encap configuration. */ 9505 static int 9506 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 9507 { 9508 /* Set up default configuration. */ 9509 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 9510 .conf = (struct rte_flow_action_nvgre_encap){ 9511 .definition = action_nvgre_encap_data->items, 9512 }, 9513 .items = { 9514 { 9515 .type = RTE_FLOW_ITEM_TYPE_ETH, 9516 .spec = &action_nvgre_encap_data->item_eth, 9517 .mask = &rte_flow_item_eth_mask, 9518 }, 9519 { 9520 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9521 .spec = &action_nvgre_encap_data->item_vlan, 9522 .mask = &rte_flow_item_vlan_mask, 9523 }, 9524 { 9525 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9526 .spec = &action_nvgre_encap_data->item_ipv4, 9527 .mask = &rte_flow_item_ipv4_mask, 9528 }, 9529 { 9530 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 9531 .spec = &action_nvgre_encap_data->item_nvgre, 9532 .mask = &rte_flow_item_nvgre_mask, 9533 }, 9534 { 9535 .type = RTE_FLOW_ITEM_TYPE_END, 9536 }, 9537 }, 9538 .item_eth.hdr.ether_type = 0, 9539 .item_vlan = { 9540 .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, 9541 .hdr.eth_proto = 0, 9542 }, 9543 .item_ipv4.hdr = { 9544 .src_addr = nvgre_encap_conf.ipv4_src, 9545 .dst_addr = nvgre_encap_conf.ipv4_dst, 9546 }, 9547 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 9548 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 9549 .item_nvgre.flow_id = 0, 9550 }; 9551 memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9552 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9553 memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, 9554 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9555 if (!nvgre_encap_conf.select_ipv4) { 9556 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 9557 &nvgre_encap_conf.ipv6_src, 9558 sizeof(nvgre_encap_conf.ipv6_src)); 9559 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 9560 &nvgre_encap_conf.ipv6_dst, 9561 sizeof(nvgre_encap_conf.ipv6_dst)); 9562 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 9563 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9564 .spec = &action_nvgre_encap_data->item_ipv6, 9565 .mask = &rte_flow_item_ipv6_mask, 9566 }; 9567 } 9568 if (!nvgre_encap_conf.select_vlan) 9569 action_nvgre_encap_data->items[1].type = 9570 RTE_FLOW_ITEM_TYPE_VOID; 9571 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 9572 RTE_DIM(nvgre_encap_conf.tni)); 9573 return 0; 9574 } 9575 9576 /** Parse NVGRE encap action. */ 9577 static int 9578 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 9579 const char *str, unsigned int len, 9580 void *buf, unsigned int size) 9581 { 9582 struct buffer *out = buf; 9583 struct rte_flow_action *action; 9584 struct action_nvgre_encap_data *action_nvgre_encap_data; 9585 int ret; 9586 9587 ret = parse_vc(ctx, token, str, len, buf, size); 9588 if (ret < 0) 9589 return ret; 9590 /* Nothing else to do if there is no buffer. */ 9591 if (!out) 9592 return ret; 9593 if (!out->args.vc.actions_n) 9594 return -1; 9595 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9596 /* Point to selected object. */ 9597 ctx->object = out->args.vc.data; 9598 ctx->objmask = NULL; 9599 action_nvgre_encap_data = ctx->object; 9600 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 9601 action->conf = &action_nvgre_encap_data->conf; 9602 return ret; 9603 } 9604 9605 /** Parse l2 encap action. */ 9606 static int 9607 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 9608 const char *str, unsigned int len, 9609 void *buf, unsigned int size) 9610 { 9611 struct buffer *out = buf; 9612 struct rte_flow_action *action; 9613 struct action_raw_encap_data *action_encap_data; 9614 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9615 struct rte_flow_item_vlan vlan = { 9616 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9617 .hdr.eth_proto = 0, 9618 }; 9619 uint8_t *header; 9620 int ret; 9621 9622 ret = parse_vc(ctx, token, str, len, buf, size); 9623 if (ret < 0) 9624 return ret; 9625 /* Nothing else to do if there is no buffer. */ 9626 if (!out) 9627 return ret; 9628 if (!out->args.vc.actions_n) 9629 return -1; 9630 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9631 /* Point to selected object. */ 9632 ctx->object = out->args.vc.data; 9633 ctx->objmask = NULL; 9634 /* Copy the headers to the buffer. */ 9635 action_encap_data = ctx->object; 9636 *action_encap_data = (struct action_raw_encap_data) { 9637 .conf = (struct rte_flow_action_raw_encap){ 9638 .data = action_encap_data->data, 9639 }, 9640 .data = {}, 9641 }; 9642 header = action_encap_data->data; 9643 if (l2_encap_conf.select_vlan) 9644 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9645 else if (l2_encap_conf.select_ipv4) 9646 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9647 else 9648 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9649 memcpy(eth.hdr.dst_addr.addr_bytes, 9650 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9651 memcpy(eth.hdr.src_addr.addr_bytes, 9652 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9653 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9654 header += sizeof(struct rte_ether_hdr); 9655 if (l2_encap_conf.select_vlan) { 9656 if (l2_encap_conf.select_ipv4) 9657 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9658 else 9659 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9660 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9661 header += sizeof(struct rte_vlan_hdr); 9662 } 9663 action_encap_data->conf.size = header - 9664 action_encap_data->data; 9665 action->conf = &action_encap_data->conf; 9666 return ret; 9667 } 9668 9669 /** Parse l2 decap action. */ 9670 static int 9671 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 9672 const char *str, unsigned int len, 9673 void *buf, unsigned int size) 9674 { 9675 struct buffer *out = buf; 9676 struct rte_flow_action *action; 9677 struct action_raw_decap_data *action_decap_data; 9678 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9679 struct rte_flow_item_vlan vlan = { 9680 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9681 .hdr.eth_proto = 0, 9682 }; 9683 uint8_t *header; 9684 int ret; 9685 9686 ret = parse_vc(ctx, token, str, len, buf, size); 9687 if (ret < 0) 9688 return ret; 9689 /* Nothing else to do if there is no buffer. */ 9690 if (!out) 9691 return ret; 9692 if (!out->args.vc.actions_n) 9693 return -1; 9694 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9695 /* Point to selected object. */ 9696 ctx->object = out->args.vc.data; 9697 ctx->objmask = NULL; 9698 /* Copy the headers to the buffer. */ 9699 action_decap_data = ctx->object; 9700 *action_decap_data = (struct action_raw_decap_data) { 9701 .conf = (struct rte_flow_action_raw_decap){ 9702 .data = action_decap_data->data, 9703 }, 9704 .data = {}, 9705 }; 9706 header = action_decap_data->data; 9707 if (l2_decap_conf.select_vlan) 9708 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9709 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9710 header += sizeof(struct rte_ether_hdr); 9711 if (l2_decap_conf.select_vlan) { 9712 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9713 header += sizeof(struct rte_vlan_hdr); 9714 } 9715 action_decap_data->conf.size = header - 9716 action_decap_data->data; 9717 action->conf = &action_decap_data->conf; 9718 return ret; 9719 } 9720 9721 #define ETHER_TYPE_MPLS_UNICAST 0x8847 9722 9723 /** Parse MPLSOGRE encap action. */ 9724 static int 9725 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 9726 const char *str, unsigned int len, 9727 void *buf, unsigned int size) 9728 { 9729 struct buffer *out = buf; 9730 struct rte_flow_action *action; 9731 struct action_raw_encap_data *action_encap_data; 9732 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9733 struct rte_flow_item_vlan vlan = { 9734 .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, 9735 .hdr.eth_proto = 0, 9736 }; 9737 struct rte_flow_item_ipv4 ipv4 = { 9738 .hdr = { 9739 .src_addr = mplsogre_encap_conf.ipv4_src, 9740 .dst_addr = mplsogre_encap_conf.ipv4_dst, 9741 .next_proto_id = IPPROTO_GRE, 9742 .version_ihl = RTE_IPV4_VHL_DEF, 9743 .time_to_live = IPDEFTTL, 9744 }, 9745 }; 9746 struct rte_flow_item_ipv6 ipv6 = { 9747 .hdr = { 9748 .proto = IPPROTO_GRE, 9749 .hop_limits = IPDEFTTL, 9750 }, 9751 }; 9752 struct rte_flow_item_gre gre = { 9753 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9754 }; 9755 struct rte_flow_item_mpls mpls = { 9756 .ttl = 0, 9757 }; 9758 uint8_t *header; 9759 int ret; 9760 9761 ret = parse_vc(ctx, token, str, len, buf, size); 9762 if (ret < 0) 9763 return ret; 9764 /* Nothing else to do if there is no buffer. */ 9765 if (!out) 9766 return ret; 9767 if (!out->args.vc.actions_n) 9768 return -1; 9769 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9770 /* Point to selected object. */ 9771 ctx->object = out->args.vc.data; 9772 ctx->objmask = NULL; 9773 /* Copy the headers to the buffer. */ 9774 action_encap_data = ctx->object; 9775 *action_encap_data = (struct action_raw_encap_data) { 9776 .conf = (struct rte_flow_action_raw_encap){ 9777 .data = action_encap_data->data, 9778 }, 9779 .data = {}, 9780 .preserve = {}, 9781 }; 9782 header = action_encap_data->data; 9783 if (mplsogre_encap_conf.select_vlan) 9784 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9785 else if (mplsogre_encap_conf.select_ipv4) 9786 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9787 else 9788 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9789 memcpy(eth.hdr.dst_addr.addr_bytes, 9790 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9791 memcpy(eth.hdr.src_addr.addr_bytes, 9792 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9793 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9794 header += sizeof(struct rte_ether_hdr); 9795 if (mplsogre_encap_conf.select_vlan) { 9796 if (mplsogre_encap_conf.select_ipv4) 9797 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9798 else 9799 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9800 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9801 header += sizeof(struct rte_vlan_hdr); 9802 } 9803 if (mplsogre_encap_conf.select_ipv4) { 9804 memcpy(header, &ipv4, sizeof(ipv4)); 9805 header += sizeof(ipv4); 9806 } else { 9807 memcpy(&ipv6.hdr.src_addr, 9808 &mplsogre_encap_conf.ipv6_src, 9809 sizeof(mplsogre_encap_conf.ipv6_src)); 9810 memcpy(&ipv6.hdr.dst_addr, 9811 &mplsogre_encap_conf.ipv6_dst, 9812 sizeof(mplsogre_encap_conf.ipv6_dst)); 9813 memcpy(header, &ipv6, sizeof(ipv6)); 9814 header += sizeof(ipv6); 9815 } 9816 memcpy(header, &gre, sizeof(gre)); 9817 header += sizeof(gre); 9818 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 9819 RTE_DIM(mplsogre_encap_conf.label)); 9820 mpls.label_tc_s[2] |= 0x1; 9821 memcpy(header, &mpls, sizeof(mpls)); 9822 header += sizeof(mpls); 9823 action_encap_data->conf.size = header - 9824 action_encap_data->data; 9825 action->conf = &action_encap_data->conf; 9826 return ret; 9827 } 9828 9829 /** Parse MPLSOGRE decap action. */ 9830 static int 9831 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 9832 const char *str, unsigned int len, 9833 void *buf, unsigned int size) 9834 { 9835 struct buffer *out = buf; 9836 struct rte_flow_action *action; 9837 struct action_raw_decap_data *action_decap_data; 9838 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9839 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9840 struct rte_flow_item_ipv4 ipv4 = { 9841 .hdr = { 9842 .next_proto_id = IPPROTO_GRE, 9843 }, 9844 }; 9845 struct rte_flow_item_ipv6 ipv6 = { 9846 .hdr = { 9847 .proto = IPPROTO_GRE, 9848 }, 9849 }; 9850 struct rte_flow_item_gre gre = { 9851 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9852 }; 9853 struct rte_flow_item_mpls mpls; 9854 uint8_t *header; 9855 int ret; 9856 9857 ret = parse_vc(ctx, token, str, len, buf, size); 9858 if (ret < 0) 9859 return ret; 9860 /* Nothing else to do if there is no buffer. */ 9861 if (!out) 9862 return ret; 9863 if (!out->args.vc.actions_n) 9864 return -1; 9865 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9866 /* Point to selected object. */ 9867 ctx->object = out->args.vc.data; 9868 ctx->objmask = NULL; 9869 /* Copy the headers to the buffer. */ 9870 action_decap_data = ctx->object; 9871 *action_decap_data = (struct action_raw_decap_data) { 9872 .conf = (struct rte_flow_action_raw_decap){ 9873 .data = action_decap_data->data, 9874 }, 9875 .data = {}, 9876 }; 9877 header = action_decap_data->data; 9878 if (mplsogre_decap_conf.select_vlan) 9879 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9880 else if (mplsogre_encap_conf.select_ipv4) 9881 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9882 else 9883 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9884 memcpy(eth.hdr.dst_addr.addr_bytes, 9885 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9886 memcpy(eth.hdr.src_addr.addr_bytes, 9887 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9888 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9889 header += sizeof(struct rte_ether_hdr); 9890 if (mplsogre_encap_conf.select_vlan) { 9891 if (mplsogre_encap_conf.select_ipv4) 9892 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9893 else 9894 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9895 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9896 header += sizeof(struct rte_vlan_hdr); 9897 } 9898 if (mplsogre_encap_conf.select_ipv4) { 9899 memcpy(header, &ipv4, sizeof(ipv4)); 9900 header += sizeof(ipv4); 9901 } else { 9902 memcpy(header, &ipv6, sizeof(ipv6)); 9903 header += sizeof(ipv6); 9904 } 9905 memcpy(header, &gre, sizeof(gre)); 9906 header += sizeof(gre); 9907 memset(&mpls, 0, sizeof(mpls)); 9908 memcpy(header, &mpls, sizeof(mpls)); 9909 header += sizeof(mpls); 9910 action_decap_data->conf.size = header - 9911 action_decap_data->data; 9912 action->conf = &action_decap_data->conf; 9913 return ret; 9914 } 9915 9916 /** Parse MPLSOUDP encap action. */ 9917 static int 9918 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 9919 const char *str, unsigned int len, 9920 void *buf, unsigned int size) 9921 { 9922 struct buffer *out = buf; 9923 struct rte_flow_action *action; 9924 struct action_raw_encap_data *action_encap_data; 9925 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9926 struct rte_flow_item_vlan vlan = { 9927 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9928 .hdr.eth_proto = 0, 9929 }; 9930 struct rte_flow_item_ipv4 ipv4 = { 9931 .hdr = { 9932 .src_addr = mplsoudp_encap_conf.ipv4_src, 9933 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 9934 .next_proto_id = IPPROTO_UDP, 9935 .version_ihl = RTE_IPV4_VHL_DEF, 9936 .time_to_live = IPDEFTTL, 9937 }, 9938 }; 9939 struct rte_flow_item_ipv6 ipv6 = { 9940 .hdr = { 9941 .proto = IPPROTO_UDP, 9942 .hop_limits = IPDEFTTL, 9943 }, 9944 }; 9945 struct rte_flow_item_udp udp = { 9946 .hdr = { 9947 .src_port = mplsoudp_encap_conf.udp_src, 9948 .dst_port = mplsoudp_encap_conf.udp_dst, 9949 }, 9950 }; 9951 struct rte_flow_item_mpls mpls; 9952 uint8_t *header; 9953 int ret; 9954 9955 ret = parse_vc(ctx, token, str, len, buf, size); 9956 if (ret < 0) 9957 return ret; 9958 /* Nothing else to do if there is no buffer. */ 9959 if (!out) 9960 return ret; 9961 if (!out->args.vc.actions_n) 9962 return -1; 9963 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9964 /* Point to selected object. */ 9965 ctx->object = out->args.vc.data; 9966 ctx->objmask = NULL; 9967 /* Copy the headers to the buffer. */ 9968 action_encap_data = ctx->object; 9969 *action_encap_data = (struct action_raw_encap_data) { 9970 .conf = (struct rte_flow_action_raw_encap){ 9971 .data = action_encap_data->data, 9972 }, 9973 .data = {}, 9974 .preserve = {}, 9975 }; 9976 header = action_encap_data->data; 9977 if (mplsoudp_encap_conf.select_vlan) 9978 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9979 else if (mplsoudp_encap_conf.select_ipv4) 9980 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9981 else 9982 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9983 memcpy(eth.hdr.dst_addr.addr_bytes, 9984 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9985 memcpy(eth.hdr.src_addr.addr_bytes, 9986 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9987 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9988 header += sizeof(struct rte_ether_hdr); 9989 if (mplsoudp_encap_conf.select_vlan) { 9990 if (mplsoudp_encap_conf.select_ipv4) 9991 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9992 else 9993 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9994 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9995 header += sizeof(struct rte_vlan_hdr); 9996 } 9997 if (mplsoudp_encap_conf.select_ipv4) { 9998 memcpy(header, &ipv4, sizeof(ipv4)); 9999 header += sizeof(ipv4); 10000 } else { 10001 memcpy(&ipv6.hdr.src_addr, 10002 &mplsoudp_encap_conf.ipv6_src, 10003 sizeof(mplsoudp_encap_conf.ipv6_src)); 10004 memcpy(&ipv6.hdr.dst_addr, 10005 &mplsoudp_encap_conf.ipv6_dst, 10006 sizeof(mplsoudp_encap_conf.ipv6_dst)); 10007 memcpy(header, &ipv6, sizeof(ipv6)); 10008 header += sizeof(ipv6); 10009 } 10010 memcpy(header, &udp, sizeof(udp)); 10011 header += sizeof(udp); 10012 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 10013 RTE_DIM(mplsoudp_encap_conf.label)); 10014 mpls.label_tc_s[2] |= 0x1; 10015 memcpy(header, &mpls, sizeof(mpls)); 10016 header += sizeof(mpls); 10017 action_encap_data->conf.size = header - 10018 action_encap_data->data; 10019 action->conf = &action_encap_data->conf; 10020 return ret; 10021 } 10022 10023 /** Parse MPLSOUDP decap action. */ 10024 static int 10025 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 10026 const char *str, unsigned int len, 10027 void *buf, unsigned int size) 10028 { 10029 struct buffer *out = buf; 10030 struct rte_flow_action *action; 10031 struct action_raw_decap_data *action_decap_data; 10032 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 10033 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 10034 struct rte_flow_item_ipv4 ipv4 = { 10035 .hdr = { 10036 .next_proto_id = IPPROTO_UDP, 10037 }, 10038 }; 10039 struct rte_flow_item_ipv6 ipv6 = { 10040 .hdr = { 10041 .proto = IPPROTO_UDP, 10042 }, 10043 }; 10044 struct rte_flow_item_udp udp = { 10045 .hdr = { 10046 .dst_port = rte_cpu_to_be_16(6635), 10047 }, 10048 }; 10049 struct rte_flow_item_mpls mpls; 10050 uint8_t *header; 10051 int ret; 10052 10053 ret = parse_vc(ctx, token, str, len, buf, size); 10054 if (ret < 0) 10055 return ret; 10056 /* Nothing else to do if there is no buffer. */ 10057 if (!out) 10058 return ret; 10059 if (!out->args.vc.actions_n) 10060 return -1; 10061 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10062 /* Point to selected object. */ 10063 ctx->object = out->args.vc.data; 10064 ctx->objmask = NULL; 10065 /* Copy the headers to the buffer. */ 10066 action_decap_data = ctx->object; 10067 *action_decap_data = (struct action_raw_decap_data) { 10068 .conf = (struct rte_flow_action_raw_decap){ 10069 .data = action_decap_data->data, 10070 }, 10071 .data = {}, 10072 }; 10073 header = action_decap_data->data; 10074 if (mplsoudp_decap_conf.select_vlan) 10075 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 10076 else if (mplsoudp_encap_conf.select_ipv4) 10077 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 10078 else 10079 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 10080 memcpy(eth.hdr.dst_addr.addr_bytes, 10081 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 10082 memcpy(eth.hdr.src_addr.addr_bytes, 10083 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 10084 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 10085 header += sizeof(struct rte_ether_hdr); 10086 if (mplsoudp_encap_conf.select_vlan) { 10087 if (mplsoudp_encap_conf.select_ipv4) 10088 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 10089 else 10090 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 10091 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 10092 header += sizeof(struct rte_vlan_hdr); 10093 } 10094 if (mplsoudp_encap_conf.select_ipv4) { 10095 memcpy(header, &ipv4, sizeof(ipv4)); 10096 header += sizeof(ipv4); 10097 } else { 10098 memcpy(header, &ipv6, sizeof(ipv6)); 10099 header += sizeof(ipv6); 10100 } 10101 memcpy(header, &udp, sizeof(udp)); 10102 header += sizeof(udp); 10103 memset(&mpls, 0, sizeof(mpls)); 10104 memcpy(header, &mpls, sizeof(mpls)); 10105 header += sizeof(mpls); 10106 action_decap_data->conf.size = header - 10107 action_decap_data->data; 10108 action->conf = &action_decap_data->conf; 10109 return ret; 10110 } 10111 10112 static int 10113 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 10114 const char *str, unsigned int len, void *buf, 10115 unsigned int size) 10116 { 10117 struct action_raw_decap_data *action_raw_decap_data; 10118 struct rte_flow_action *action; 10119 const struct arg *arg; 10120 struct buffer *out = buf; 10121 int ret; 10122 uint16_t idx; 10123 10124 RTE_SET_USED(token); 10125 RTE_SET_USED(buf); 10126 RTE_SET_USED(size); 10127 arg = ARGS_ENTRY_ARB_BOUNDED 10128 (offsetof(struct action_raw_decap_data, idx), 10129 sizeof(((struct action_raw_decap_data *)0)->idx), 10130 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10131 if (push_args(ctx, arg)) 10132 return -1; 10133 ret = parse_int(ctx, token, str, len, NULL, 0); 10134 if (ret < 0) { 10135 pop_args(ctx); 10136 return -1; 10137 } 10138 if (!ctx->object) 10139 return len; 10140 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10141 action_raw_decap_data = ctx->object; 10142 idx = action_raw_decap_data->idx; 10143 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 10144 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 10145 action->conf = &action_raw_decap_data->conf; 10146 return len; 10147 } 10148 10149 10150 static int 10151 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 10152 const char *str, unsigned int len, void *buf, 10153 unsigned int size) 10154 { 10155 struct action_raw_encap_data *action_raw_encap_data; 10156 struct rte_flow_action *action; 10157 const struct arg *arg; 10158 struct buffer *out = buf; 10159 int ret; 10160 uint16_t idx; 10161 10162 RTE_SET_USED(token); 10163 RTE_SET_USED(buf); 10164 RTE_SET_USED(size); 10165 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 10166 return -1; 10167 arg = ARGS_ENTRY_ARB_BOUNDED 10168 (offsetof(struct action_raw_encap_data, idx), 10169 sizeof(((struct action_raw_encap_data *)0)->idx), 10170 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10171 if (push_args(ctx, arg)) 10172 return -1; 10173 ret = parse_int(ctx, token, str, len, NULL, 0); 10174 if (ret < 0) { 10175 pop_args(ctx); 10176 return -1; 10177 } 10178 if (!ctx->object) 10179 return len; 10180 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10181 action_raw_encap_data = ctx->object; 10182 idx = action_raw_encap_data->idx; 10183 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 10184 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 10185 action_raw_encap_data->conf.preserve = NULL; 10186 action->conf = &action_raw_encap_data->conf; 10187 return len; 10188 } 10189 10190 static int 10191 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 10192 const char *str, unsigned int len, void *buf, 10193 unsigned int size) 10194 { 10195 struct buffer *out = buf; 10196 int ret; 10197 10198 ret = parse_vc(ctx, token, str, len, buf, size); 10199 if (ret < 0) 10200 return ret; 10201 /* Nothing else to do if there is no buffer. */ 10202 if (!out) 10203 return ret; 10204 if (!out->args.vc.actions_n) 10205 return -1; 10206 /* Point to selected object. */ 10207 ctx->object = out->args.vc.data; 10208 ctx->objmask = NULL; 10209 return ret; 10210 } 10211 10212 static int 10213 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 10214 const char *str, unsigned int len, void *buf, 10215 unsigned int size) 10216 { 10217 struct buffer *out = buf; 10218 struct rte_flow_action *action; 10219 struct action_raw_decap_data *action_raw_decap_data = NULL; 10220 int ret; 10221 10222 ret = parse_vc(ctx, token, str, len, buf, size); 10223 if (ret < 0) 10224 return ret; 10225 /* Nothing else to do if there is no buffer. */ 10226 if (!out) 10227 return ret; 10228 if (!out->args.vc.actions_n) 10229 return -1; 10230 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10231 /* Point to selected object. */ 10232 ctx->object = out->args.vc.data; 10233 ctx->objmask = NULL; 10234 /* Copy the headers to the buffer. */ 10235 action_raw_decap_data = ctx->object; 10236 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 10237 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 10238 action->conf = &action_raw_decap_data->conf; 10239 return ret; 10240 } 10241 10242 static int 10243 parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 10244 const char *str, unsigned int len, void *buf, 10245 unsigned int size) 10246 { 10247 struct buffer *out = buf; 10248 struct rte_flow_action *action; 10249 struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; 10250 int ret; 10251 10252 ret = parse_vc(ctx, token, str, len, buf, size); 10253 if (ret < 0) 10254 return ret; 10255 /* Nothing else to do if there is no buffer. */ 10256 if (!out) 10257 return ret; 10258 if (!out->args.vc.actions_n) 10259 return -1; 10260 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10261 /* Point to selected object. */ 10262 ctx->object = out->args.vc.data; 10263 ctx->objmask = NULL; 10264 /* Copy the headers to the buffer. */ 10265 ipv6_ext_remove_data = ctx->object; 10266 ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; 10267 action->conf = &ipv6_ext_remove_data->conf; 10268 return ret; 10269 } 10270 10271 static int 10272 parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, 10273 const char *str, unsigned int len, void *buf, 10274 unsigned int size) 10275 { 10276 struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; 10277 struct rte_flow_action *action; 10278 const struct arg *arg; 10279 struct buffer *out = buf; 10280 int ret; 10281 uint16_t idx; 10282 10283 RTE_SET_USED(token); 10284 RTE_SET_USED(buf); 10285 RTE_SET_USED(size); 10286 arg = ARGS_ENTRY_ARB_BOUNDED 10287 (offsetof(struct action_ipv6_ext_remove_data, idx), 10288 sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), 10289 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10290 if (push_args(ctx, arg)) 10291 return -1; 10292 ret = parse_int(ctx, token, str, len, NULL, 0); 10293 if (ret < 0) { 10294 pop_args(ctx); 10295 return -1; 10296 } 10297 if (!ctx->object) 10298 return len; 10299 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10300 action_ipv6_ext_remove_data = ctx->object; 10301 idx = action_ipv6_ext_remove_data->idx; 10302 action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; 10303 action->conf = &action_ipv6_ext_remove_data->conf; 10304 return len; 10305 } 10306 10307 static int 10308 parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 10309 const char *str, unsigned int len, void *buf, 10310 unsigned int size) 10311 { 10312 struct buffer *out = buf; 10313 struct rte_flow_action *action; 10314 struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; 10315 int ret; 10316 10317 ret = parse_vc(ctx, token, str, len, buf, size); 10318 if (ret < 0) 10319 return ret; 10320 /* Nothing else to do if there is no buffer. */ 10321 if (!out) 10322 return ret; 10323 if (!out->args.vc.actions_n) 10324 return -1; 10325 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10326 /* Point to selected object. */ 10327 ctx->object = out->args.vc.data; 10328 ctx->objmask = NULL; 10329 /* Copy the headers to the buffer. */ 10330 ipv6_ext_push_data = ctx->object; 10331 ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; 10332 ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; 10333 ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; 10334 action->conf = &ipv6_ext_push_data->conf; 10335 return ret; 10336 } 10337 10338 static int 10339 parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, 10340 const char *str, unsigned int len, void *buf, 10341 unsigned int size) 10342 { 10343 struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; 10344 struct rte_flow_action *action; 10345 const struct arg *arg; 10346 struct buffer *out = buf; 10347 int ret; 10348 uint16_t idx; 10349 10350 RTE_SET_USED(token); 10351 RTE_SET_USED(buf); 10352 RTE_SET_USED(size); 10353 arg = ARGS_ENTRY_ARB_BOUNDED 10354 (offsetof(struct action_ipv6_ext_push_data, idx), 10355 sizeof(((struct action_ipv6_ext_push_data *)0)->idx), 10356 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10357 if (push_args(ctx, arg)) 10358 return -1; 10359 ret = parse_int(ctx, token, str, len, NULL, 0); 10360 if (ret < 0) { 10361 pop_args(ctx); 10362 return -1; 10363 } 10364 if (!ctx->object) 10365 return len; 10366 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10367 action_ipv6_ext_push_data = ctx->object; 10368 idx = action_ipv6_ext_push_data->idx; 10369 action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; 10370 action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; 10371 action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; 10372 action->conf = &action_ipv6_ext_push_data->conf; 10373 return len; 10374 } 10375 10376 static int 10377 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 10378 const char *str, unsigned int len, void *buf, 10379 unsigned int size) 10380 { 10381 int ret; 10382 10383 ret = parse_vc(ctx, token, str, len, buf, size); 10384 if (ret < 0) 10385 return ret; 10386 ret = rte_flow_dynf_metadata_register(); 10387 if (ret < 0) 10388 return -1; 10389 return len; 10390 } 10391 10392 static int 10393 parse_vc_action_sample(struct context *ctx, const struct token *token, 10394 const char *str, unsigned int len, void *buf, 10395 unsigned int size) 10396 { 10397 struct buffer *out = buf; 10398 struct rte_flow_action *action; 10399 struct action_sample_data *action_sample_data = NULL; 10400 static struct rte_flow_action end_action = { 10401 RTE_FLOW_ACTION_TYPE_END, 0 10402 }; 10403 int ret; 10404 10405 ret = parse_vc(ctx, token, str, len, buf, size); 10406 if (ret < 0) 10407 return ret; 10408 /* Nothing else to do if there is no buffer. */ 10409 if (!out) 10410 return ret; 10411 if (!out->args.vc.actions_n) 10412 return -1; 10413 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10414 /* Point to selected object. */ 10415 ctx->object = out->args.vc.data; 10416 ctx->objmask = NULL; 10417 /* Copy the headers to the buffer. */ 10418 action_sample_data = ctx->object; 10419 action_sample_data->conf.actions = &end_action; 10420 action->conf = &action_sample_data->conf; 10421 return ret; 10422 } 10423 10424 static int 10425 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 10426 const char *str, unsigned int len, void *buf, 10427 unsigned int size) 10428 { 10429 struct action_sample_data *action_sample_data; 10430 struct rte_flow_action *action; 10431 const struct arg *arg; 10432 struct buffer *out = buf; 10433 int ret; 10434 uint16_t idx; 10435 10436 RTE_SET_USED(token); 10437 RTE_SET_USED(buf); 10438 RTE_SET_USED(size); 10439 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 10440 return -1; 10441 arg = ARGS_ENTRY_ARB_BOUNDED 10442 (offsetof(struct action_sample_data, idx), 10443 sizeof(((struct action_sample_data *)0)->idx), 10444 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 10445 if (push_args(ctx, arg)) 10446 return -1; 10447 ret = parse_int(ctx, token, str, len, NULL, 0); 10448 if (ret < 0) { 10449 pop_args(ctx); 10450 return -1; 10451 } 10452 if (!ctx->object) 10453 return len; 10454 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10455 action_sample_data = ctx->object; 10456 idx = action_sample_data->idx; 10457 action_sample_data->conf.actions = raw_sample_confs[idx].data; 10458 action->conf = &action_sample_data->conf; 10459 return len; 10460 } 10461 10462 /** Parse operation for modify_field command. */ 10463 static int 10464 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 10465 const char *str, unsigned int len, void *buf, 10466 unsigned int size) 10467 { 10468 struct rte_flow_action_modify_field *action_modify_field; 10469 unsigned int i; 10470 10471 (void)token; 10472 (void)buf; 10473 (void)size; 10474 if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) 10475 return -1; 10476 for (i = 0; modify_field_ops[i]; ++i) 10477 if (!strcmp_partial(modify_field_ops[i], str, len)) 10478 break; 10479 if (!modify_field_ops[i]) 10480 return -1; 10481 if (!ctx->object) 10482 return len; 10483 action_modify_field = ctx->object; 10484 action_modify_field->operation = (enum rte_flow_modify_op)i; 10485 return len; 10486 } 10487 10488 /** Parse id for modify_field command. */ 10489 static int 10490 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 10491 const char *str, unsigned int len, void *buf, 10492 unsigned int size) 10493 { 10494 struct rte_flow_action_modify_field *action_modify_field; 10495 unsigned int i; 10496 10497 (void)token; 10498 (void)buf; 10499 (void)size; 10500 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 10501 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 10502 return -1; 10503 for (i = 0; flow_field_ids[i]; ++i) 10504 if (!strcmp_partial(flow_field_ids[i], str, len)) 10505 break; 10506 if (!flow_field_ids[i]) 10507 return -1; 10508 if (!ctx->object) 10509 return len; 10510 action_modify_field = ctx->object; 10511 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 10512 action_modify_field->dst.field = (enum rte_flow_field_id)i; 10513 else 10514 action_modify_field->src.field = (enum rte_flow_field_id)i; 10515 return len; 10516 } 10517 10518 /** Parse level for modify_field command. */ 10519 static int 10520 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 10521 const char *str, unsigned int len, void *buf, 10522 unsigned int size) 10523 { 10524 struct rte_flow_action_modify_field *action; 10525 struct flex_item *fp = NULL; 10526 uint32_t val; 10527 struct buffer *out = buf; 10528 char *end; 10529 10530 (void)token; 10531 (void)size; 10532 if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10533 ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) 10534 return -1; 10535 if (!ctx->object) 10536 return len; 10537 action = ctx->object; 10538 errno = 0; 10539 val = strtoumax(str, &end, 0); 10540 if (errno || (size_t)(end - str) != len) 10541 return -1; 10542 /* No need to validate action template mask value */ 10543 if (out->args.vc.masks) { 10544 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) 10545 action->dst.level = val; 10546 else 10547 action->src.level = val; 10548 return len; 10549 } 10550 if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10551 action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || 10552 (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && 10553 action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 10554 if (val >= FLEX_MAX_PARSERS_NUM) { 10555 printf("Bad flex item handle\n"); 10556 return -1; 10557 } 10558 fp = flex_items[ctx->port][val]; 10559 if (!fp) { 10560 printf("Bad flex item handle\n"); 10561 return -1; 10562 } 10563 } 10564 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { 10565 if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) 10566 action->dst.level = val; 10567 else 10568 action->dst.flex_handle = fp->flex_handle; 10569 } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { 10570 if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) 10571 action->src.level = val; 10572 else 10573 action->src.flex_handle = fp->flex_handle; 10574 } 10575 return len; 10576 } 10577 10578 /** Parse the conntrack update, not a rte_flow_action. */ 10579 static int 10580 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 10581 const char *str, unsigned int len, void *buf, 10582 unsigned int size) 10583 { 10584 struct buffer *out = buf; 10585 struct rte_flow_modify_conntrack *ct_modify = NULL; 10586 10587 (void)size; 10588 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 10589 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 10590 return -1; 10591 /* Token name must match. */ 10592 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10593 return -1; 10594 /* Nothing else to do if there is no buffer. */ 10595 if (!out) 10596 return len; 10597 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 10598 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 10599 ct_modify->new_ct.is_original_dir = 10600 conntrack_context.is_original_dir; 10601 ct_modify->direction = 1; 10602 } else { 10603 uint32_t old_dir; 10604 10605 old_dir = ct_modify->new_ct.is_original_dir; 10606 memcpy(&ct_modify->new_ct, &conntrack_context, 10607 sizeof(conntrack_context)); 10608 ct_modify->new_ct.is_original_dir = old_dir; 10609 ct_modify->state = 1; 10610 } 10611 return len; 10612 } 10613 10614 /** Parse tokens for destroy command. */ 10615 static int 10616 parse_destroy(struct context *ctx, const struct token *token, 10617 const char *str, unsigned int len, 10618 void *buf, unsigned int size) 10619 { 10620 struct buffer *out = buf; 10621 10622 /* Token name must match. */ 10623 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10624 return -1; 10625 /* Nothing else to do if there is no buffer. */ 10626 if (!out) 10627 return len; 10628 if (!out->command) { 10629 if (ctx->curr != DESTROY) 10630 return -1; 10631 if (sizeof(*out) > size) 10632 return -1; 10633 out->command = ctx->curr; 10634 ctx->objdata = 0; 10635 ctx->object = out; 10636 ctx->objmask = NULL; 10637 out->args.destroy.rule = 10638 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10639 sizeof(double)); 10640 return len; 10641 } 10642 if (ctx->curr == DESTROY_IS_USER_ID) { 10643 out->args.destroy.is_user_id = true; 10644 return len; 10645 } 10646 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 10647 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 10648 return -1; 10649 ctx->objdata = 0; 10650 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 10651 ctx->objmask = NULL; 10652 return len; 10653 } 10654 10655 /** Parse tokens for flush command. */ 10656 static int 10657 parse_flush(struct context *ctx, const struct token *token, 10658 const char *str, unsigned int len, 10659 void *buf, unsigned int size) 10660 { 10661 struct buffer *out = buf; 10662 10663 /* Token name must match. */ 10664 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10665 return -1; 10666 /* Nothing else to do if there is no buffer. */ 10667 if (!out) 10668 return len; 10669 if (!out->command) { 10670 if (ctx->curr != FLUSH) 10671 return -1; 10672 if (sizeof(*out) > size) 10673 return -1; 10674 out->command = ctx->curr; 10675 ctx->objdata = 0; 10676 ctx->object = out; 10677 ctx->objmask = NULL; 10678 } 10679 return len; 10680 } 10681 10682 /** Parse tokens for dump command. */ 10683 static int 10684 parse_dump(struct context *ctx, const struct token *token, 10685 const char *str, unsigned int len, 10686 void *buf, unsigned int size) 10687 { 10688 struct buffer *out = buf; 10689 10690 /* Token name must match. */ 10691 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10692 return -1; 10693 /* Nothing else to do if there is no buffer. */ 10694 if (!out) 10695 return len; 10696 if (!out->command) { 10697 if (ctx->curr != DUMP) 10698 return -1; 10699 if (sizeof(*out) > size) 10700 return -1; 10701 out->command = ctx->curr; 10702 ctx->objdata = 0; 10703 ctx->object = out; 10704 ctx->objmask = NULL; 10705 return len; 10706 } 10707 switch (ctx->curr) { 10708 case DUMP_ALL: 10709 case DUMP_ONE: 10710 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 10711 out->command = ctx->curr; 10712 ctx->objdata = 0; 10713 ctx->object = out; 10714 ctx->objmask = NULL; 10715 return len; 10716 case DUMP_IS_USER_ID: 10717 out->args.dump.is_user_id = true; 10718 return len; 10719 default: 10720 return -1; 10721 } 10722 } 10723 10724 /** Parse tokens for query command. */ 10725 static int 10726 parse_query(struct context *ctx, const struct token *token, 10727 const char *str, unsigned int len, 10728 void *buf, unsigned int size) 10729 { 10730 struct buffer *out = buf; 10731 10732 /* Token name must match. */ 10733 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10734 return -1; 10735 /* Nothing else to do if there is no buffer. */ 10736 if (!out) 10737 return len; 10738 if (!out->command) { 10739 if (ctx->curr != QUERY) 10740 return -1; 10741 if (sizeof(*out) > size) 10742 return -1; 10743 out->command = ctx->curr; 10744 ctx->objdata = 0; 10745 ctx->object = out; 10746 ctx->objmask = NULL; 10747 } 10748 if (ctx->curr == QUERY_IS_USER_ID) { 10749 out->args.query.is_user_id = true; 10750 return len; 10751 } 10752 return len; 10753 } 10754 10755 /** Parse action names. */ 10756 static int 10757 parse_action(struct context *ctx, const struct token *token, 10758 const char *str, unsigned int len, 10759 void *buf, unsigned int size) 10760 { 10761 struct buffer *out = buf; 10762 const struct arg *arg = pop_args(ctx); 10763 unsigned int i; 10764 10765 (void)size; 10766 /* Argument is expected. */ 10767 if (!arg) 10768 return -1; 10769 /* Parse action name. */ 10770 for (i = 0; next_action[i]; ++i) { 10771 const struct parse_action_priv *priv; 10772 10773 token = &token_list[next_action[i]]; 10774 if (strcmp_partial(token->name, str, len)) 10775 continue; 10776 priv = token->priv; 10777 if (!priv) 10778 goto error; 10779 if (out) 10780 memcpy((uint8_t *)ctx->object + arg->offset, 10781 &priv->type, 10782 arg->size); 10783 return len; 10784 } 10785 error: 10786 push_args(ctx, arg); 10787 return -1; 10788 } 10789 10790 /** Parse tokens for list command. */ 10791 static int 10792 parse_list(struct context *ctx, const struct token *token, 10793 const char *str, unsigned int len, 10794 void *buf, unsigned int size) 10795 { 10796 struct buffer *out = buf; 10797 10798 /* Token name must match. */ 10799 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10800 return -1; 10801 /* Nothing else to do if there is no buffer. */ 10802 if (!out) 10803 return len; 10804 if (!out->command) { 10805 if (ctx->curr != LIST) 10806 return -1; 10807 if (sizeof(*out) > size) 10808 return -1; 10809 out->command = ctx->curr; 10810 ctx->objdata = 0; 10811 ctx->object = out; 10812 ctx->objmask = NULL; 10813 out->args.list.group = 10814 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10815 sizeof(double)); 10816 return len; 10817 } 10818 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 10819 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 10820 return -1; 10821 ctx->objdata = 0; 10822 ctx->object = out->args.list.group + out->args.list.group_n++; 10823 ctx->objmask = NULL; 10824 return len; 10825 } 10826 10827 /** Parse tokens for list all aged flows command. */ 10828 static int 10829 parse_aged(struct context *ctx, const struct token *token, 10830 const char *str, unsigned int len, 10831 void *buf, unsigned int size) 10832 { 10833 struct buffer *out = buf; 10834 10835 /* Token name must match. */ 10836 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10837 return -1; 10838 /* Nothing else to do if there is no buffer. */ 10839 if (!out) 10840 return len; 10841 if (!out->command || out->command == QUEUE) { 10842 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 10843 return -1; 10844 if (sizeof(*out) > size) 10845 return -1; 10846 out->command = ctx->curr; 10847 ctx->objdata = 0; 10848 ctx->object = out; 10849 ctx->objmask = NULL; 10850 } 10851 if (ctx->curr == AGED_DESTROY) 10852 out->args.aged.destroy = 1; 10853 return len; 10854 } 10855 10856 /** Parse tokens for isolate command. */ 10857 static int 10858 parse_isolate(struct context *ctx, const struct token *token, 10859 const char *str, unsigned int len, 10860 void *buf, unsigned int size) 10861 { 10862 struct buffer *out = buf; 10863 10864 /* Token name must match. */ 10865 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10866 return -1; 10867 /* Nothing else to do if there is no buffer. */ 10868 if (!out) 10869 return len; 10870 if (!out->command) { 10871 if (ctx->curr != ISOLATE) 10872 return -1; 10873 if (sizeof(*out) > size) 10874 return -1; 10875 out->command = ctx->curr; 10876 ctx->objdata = 0; 10877 ctx->object = out; 10878 ctx->objmask = NULL; 10879 } 10880 return len; 10881 } 10882 10883 /** Parse tokens for info/configure command. */ 10884 static int 10885 parse_configure(struct context *ctx, const struct token *token, 10886 const char *str, unsigned int len, 10887 void *buf, unsigned int size) 10888 { 10889 struct buffer *out = buf; 10890 10891 /* Token name must match. */ 10892 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10893 return -1; 10894 /* Nothing else to do if there is no buffer. */ 10895 if (!out) 10896 return len; 10897 if (!out->command) { 10898 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 10899 return -1; 10900 if (sizeof(*out) > size) 10901 return -1; 10902 out->command = ctx->curr; 10903 ctx->objdata = 0; 10904 ctx->object = out; 10905 ctx->objmask = NULL; 10906 } 10907 return len; 10908 } 10909 10910 /** Parse tokens for template create command. */ 10911 static int 10912 parse_template(struct context *ctx, const struct token *token, 10913 const char *str, unsigned int len, 10914 void *buf, unsigned int size) 10915 { 10916 struct buffer *out = buf; 10917 10918 /* Token name must match. */ 10919 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10920 return -1; 10921 /* Nothing else to do if there is no buffer. */ 10922 if (!out) 10923 return len; 10924 if (!out->command) { 10925 if (ctx->curr != PATTERN_TEMPLATE && 10926 ctx->curr != ACTIONS_TEMPLATE) 10927 return -1; 10928 if (sizeof(*out) > size) 10929 return -1; 10930 out->command = ctx->curr; 10931 ctx->objdata = 0; 10932 ctx->object = out; 10933 ctx->objmask = NULL; 10934 out->args.vc.data = (uint8_t *)out + size; 10935 return len; 10936 } 10937 switch (ctx->curr) { 10938 case PATTERN_TEMPLATE_CREATE: 10939 out->args.vc.pattern = 10940 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10941 sizeof(double)); 10942 out->args.vc.pat_templ_id = UINT32_MAX; 10943 out->command = ctx->curr; 10944 ctx->objdata = 0; 10945 ctx->object = out; 10946 ctx->objmask = NULL; 10947 return len; 10948 case PATTERN_TEMPLATE_EGRESS: 10949 out->args.vc.attr.egress = 1; 10950 return len; 10951 case PATTERN_TEMPLATE_INGRESS: 10952 out->args.vc.attr.ingress = 1; 10953 return len; 10954 case PATTERN_TEMPLATE_TRANSFER: 10955 out->args.vc.attr.transfer = 1; 10956 return len; 10957 case ACTIONS_TEMPLATE_CREATE: 10958 out->args.vc.act_templ_id = UINT32_MAX; 10959 out->command = ctx->curr; 10960 ctx->objdata = 0; 10961 ctx->object = out; 10962 ctx->objmask = NULL; 10963 return len; 10964 case ACTIONS_TEMPLATE_SPEC: 10965 out->args.vc.actions = 10966 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10967 sizeof(double)); 10968 ctx->object = out->args.vc.actions; 10969 ctx->objmask = NULL; 10970 return len; 10971 case ACTIONS_TEMPLATE_MASK: 10972 out->args.vc.masks = 10973 (void *)RTE_ALIGN_CEIL((uintptr_t) 10974 (out->args.vc.actions + 10975 out->args.vc.actions_n), 10976 sizeof(double)); 10977 ctx->object = out->args.vc.masks; 10978 ctx->objmask = NULL; 10979 return len; 10980 case ACTIONS_TEMPLATE_EGRESS: 10981 out->args.vc.attr.egress = 1; 10982 return len; 10983 case ACTIONS_TEMPLATE_INGRESS: 10984 out->args.vc.attr.ingress = 1; 10985 return len; 10986 case ACTIONS_TEMPLATE_TRANSFER: 10987 out->args.vc.attr.transfer = 1; 10988 return len; 10989 default: 10990 return -1; 10991 } 10992 } 10993 10994 /** Parse tokens for template destroy command. */ 10995 static int 10996 parse_template_destroy(struct context *ctx, const struct token *token, 10997 const char *str, unsigned int len, 10998 void *buf, unsigned int size) 10999 { 11000 struct buffer *out = buf; 11001 uint32_t *template_id; 11002 11003 /* Token name must match. */ 11004 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11005 return -1; 11006 /* Nothing else to do if there is no buffer. */ 11007 if (!out) 11008 return len; 11009 if (!out->command || 11010 out->command == PATTERN_TEMPLATE || 11011 out->command == ACTIONS_TEMPLATE) { 11012 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 11013 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 11014 return -1; 11015 if (sizeof(*out) > size) 11016 return -1; 11017 out->command = ctx->curr; 11018 ctx->objdata = 0; 11019 ctx->object = out; 11020 ctx->objmask = NULL; 11021 out->args.templ_destroy.template_id = 11022 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11023 sizeof(double)); 11024 return len; 11025 } 11026 template_id = out->args.templ_destroy.template_id 11027 + out->args.templ_destroy.template_id_n++; 11028 if ((uint8_t *)template_id > (uint8_t *)out + size) 11029 return -1; 11030 ctx->objdata = 0; 11031 ctx->object = template_id; 11032 ctx->objmask = NULL; 11033 return len; 11034 } 11035 11036 /** Parse tokens for table create command. */ 11037 static int 11038 parse_table(struct context *ctx, const struct token *token, 11039 const char *str, unsigned int len, 11040 void *buf, unsigned int size) 11041 { 11042 struct buffer *out = buf; 11043 uint32_t *template_id; 11044 11045 /* Token name must match. */ 11046 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11047 return -1; 11048 /* Nothing else to do if there is no buffer. */ 11049 if (!out) 11050 return len; 11051 if (!out->command) { 11052 if (ctx->curr != TABLE) 11053 return -1; 11054 if (sizeof(*out) > size) 11055 return -1; 11056 out->command = ctx->curr; 11057 ctx->objdata = 0; 11058 ctx->object = out; 11059 ctx->objmask = NULL; 11060 return len; 11061 } 11062 switch (ctx->curr) { 11063 case TABLE_CREATE: 11064 case TABLE_RESIZE: 11065 out->command = ctx->curr; 11066 ctx->objdata = 0; 11067 ctx->object = out; 11068 ctx->objmask = NULL; 11069 out->args.table.id = UINT32_MAX; 11070 return len; 11071 case TABLE_PATTERN_TEMPLATE: 11072 out->args.table.pat_templ_id = 11073 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11074 sizeof(double)); 11075 template_id = out->args.table.pat_templ_id 11076 + out->args.table.pat_templ_id_n++; 11077 if ((uint8_t *)template_id > (uint8_t *)out + size) 11078 return -1; 11079 ctx->objdata = 0; 11080 ctx->object = template_id; 11081 ctx->objmask = NULL; 11082 return len; 11083 case TABLE_ACTIONS_TEMPLATE: 11084 out->args.table.act_templ_id = 11085 (void *)RTE_ALIGN_CEIL((uintptr_t) 11086 (out->args.table.pat_templ_id + 11087 out->args.table.pat_templ_id_n), 11088 sizeof(double)); 11089 template_id = out->args.table.act_templ_id 11090 + out->args.table.act_templ_id_n++; 11091 if ((uint8_t *)template_id > (uint8_t *)out + size) 11092 return -1; 11093 ctx->objdata = 0; 11094 ctx->object = template_id; 11095 ctx->objmask = NULL; 11096 return len; 11097 case TABLE_INGRESS: 11098 out->args.table.attr.flow_attr.ingress = 1; 11099 return len; 11100 case TABLE_EGRESS: 11101 out->args.table.attr.flow_attr.egress = 1; 11102 return len; 11103 case TABLE_TRANSFER: 11104 out->args.table.attr.flow_attr.transfer = 1; 11105 return len; 11106 case TABLE_TRANSFER_WIRE_ORIG: 11107 if (!out->args.table.attr.flow_attr.transfer) 11108 return -1; 11109 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; 11110 return len; 11111 case TABLE_TRANSFER_VPORT_ORIG: 11112 if (!out->args.table.attr.flow_attr.transfer) 11113 return -1; 11114 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; 11115 return len; 11116 case TABLE_RESIZABLE: 11117 out->args.table.attr.specialize |= 11118 RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE; 11119 return len; 11120 case TABLE_RULES_NUMBER: 11121 ctx->objdata = 0; 11122 ctx->object = out; 11123 ctx->objmask = NULL; 11124 return len; 11125 case TABLE_RESIZE_ID: 11126 case TABLE_RESIZE_RULES_NUMBER: 11127 return len; 11128 default: 11129 return -1; 11130 } 11131 } 11132 11133 /** Parse tokens for table destroy command. */ 11134 static int 11135 parse_table_destroy(struct context *ctx, const struct token *token, 11136 const char *str, unsigned int len, 11137 void *buf, unsigned int size) 11138 { 11139 struct buffer *out = buf; 11140 uint32_t *table_id; 11141 11142 /* Token name must match. */ 11143 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11144 return -1; 11145 /* Nothing else to do if there is no buffer. */ 11146 if (!out) 11147 return len; 11148 if (!out->command || out->command == TABLE) { 11149 if (ctx->curr != TABLE_DESTROY && 11150 ctx->curr != TABLE_RESIZE_COMPLETE) 11151 return -1; 11152 if (sizeof(*out) > size) 11153 return -1; 11154 out->command = ctx->curr; 11155 ctx->objdata = 0; 11156 ctx->object = out; 11157 ctx->objmask = NULL; 11158 out->args.table_destroy.table_id = 11159 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11160 sizeof(double)); 11161 return len; 11162 } 11163 table_id = out->args.table_destroy.table_id 11164 + out->args.table_destroy.table_id_n++; 11165 if ((uint8_t *)table_id > (uint8_t *)out + size) 11166 return -1; 11167 ctx->objdata = 0; 11168 ctx->object = table_id; 11169 ctx->objmask = NULL; 11170 return len; 11171 } 11172 11173 /** Parse tokens for queue create commands. */ 11174 static int 11175 parse_qo(struct context *ctx, const struct token *token, 11176 const char *str, unsigned int len, 11177 void *buf, unsigned int size) 11178 { 11179 struct buffer *out = buf; 11180 11181 /* Token name must match. */ 11182 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11183 return -1; 11184 /* Nothing else to do if there is no buffer. */ 11185 if (!out) 11186 return len; 11187 if (!out->command) { 11188 if (ctx->curr != QUEUE) 11189 return -1; 11190 if (sizeof(*out) > size) 11191 return -1; 11192 out->command = ctx->curr; 11193 ctx->objdata = 0; 11194 ctx->object = out; 11195 ctx->objmask = NULL; 11196 out->args.vc.data = (uint8_t *)out + size; 11197 return len; 11198 } 11199 switch (ctx->curr) { 11200 case QUEUE_CREATE: 11201 case QUEUE_UPDATE: 11202 out->command = ctx->curr; 11203 ctx->objdata = 0; 11204 ctx->object = out; 11205 ctx->objmask = NULL; 11206 out->args.vc.rule_id = UINT32_MAX; 11207 return len; 11208 case QUEUE_TEMPLATE_TABLE: 11209 case QUEUE_PATTERN_TEMPLATE: 11210 case QUEUE_ACTIONS_TEMPLATE: 11211 case QUEUE_CREATE_POSTPONE: 11212 case QUEUE_RULE_ID: 11213 case QUEUE_UPDATE_ID: 11214 return len; 11215 case ITEM_PATTERN: 11216 out->args.vc.pattern = 11217 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11218 sizeof(double)); 11219 ctx->object = out->args.vc.pattern; 11220 ctx->objmask = NULL; 11221 return len; 11222 case ACTIONS: 11223 out->args.vc.actions = 11224 (void *)RTE_ALIGN_CEIL((uintptr_t) 11225 (out->args.vc.pattern + 11226 out->args.vc.pattern_n), 11227 sizeof(double)); 11228 ctx->object = out->args.vc.actions; 11229 ctx->objmask = NULL; 11230 return len; 11231 default: 11232 return -1; 11233 } 11234 } 11235 11236 /** Parse tokens for queue destroy command. */ 11237 static int 11238 parse_qo_destroy(struct context *ctx, const struct token *token, 11239 const char *str, unsigned int len, 11240 void *buf, unsigned int size) 11241 { 11242 struct buffer *out = buf; 11243 uint64_t *flow_id; 11244 11245 /* Token name must match. */ 11246 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11247 return -1; 11248 /* Nothing else to do if there is no buffer. */ 11249 if (!out) 11250 return len; 11251 if (!out->command || out->command == QUEUE) { 11252 if (ctx->curr != QUEUE_DESTROY && 11253 ctx->curr != QUEUE_FLOW_UPDATE_RESIZED) 11254 return -1; 11255 if (sizeof(*out) > size) 11256 return -1; 11257 out->command = ctx->curr; 11258 ctx->objdata = 0; 11259 ctx->object = out; 11260 ctx->objmask = NULL; 11261 out->args.destroy.rule = 11262 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11263 sizeof(double)); 11264 return len; 11265 } 11266 switch (ctx->curr) { 11267 case QUEUE_DESTROY_ID: 11268 flow_id = out->args.destroy.rule 11269 + out->args.destroy.rule_n++; 11270 if ((uint8_t *)flow_id > (uint8_t *)out + size) 11271 return -1; 11272 ctx->objdata = 0; 11273 ctx->object = flow_id; 11274 ctx->objmask = NULL; 11275 return len; 11276 case QUEUE_DESTROY_POSTPONE: 11277 return len; 11278 default: 11279 return -1; 11280 } 11281 } 11282 11283 /** Parse tokens for push queue command. */ 11284 static int 11285 parse_push(struct context *ctx, const struct token *token, 11286 const char *str, unsigned int len, 11287 void *buf, unsigned int size) 11288 { 11289 struct buffer *out = buf; 11290 11291 /* Token name must match. */ 11292 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11293 return -1; 11294 /* Nothing else to do if there is no buffer. */ 11295 if (!out) 11296 return len; 11297 if (!out->command) { 11298 if (ctx->curr != PUSH) 11299 return -1; 11300 if (sizeof(*out) > size) 11301 return -1; 11302 out->command = ctx->curr; 11303 ctx->objdata = 0; 11304 ctx->object = out; 11305 ctx->objmask = NULL; 11306 out->args.vc.data = (uint8_t *)out + size; 11307 } 11308 return len; 11309 } 11310 11311 /** Parse tokens for pull command. */ 11312 static int 11313 parse_pull(struct context *ctx, const struct token *token, 11314 const char *str, unsigned int len, 11315 void *buf, unsigned int size) 11316 { 11317 struct buffer *out = buf; 11318 11319 /* Token name must match. */ 11320 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11321 return -1; 11322 /* Nothing else to do if there is no buffer. */ 11323 if (!out) 11324 return len; 11325 if (!out->command) { 11326 if (ctx->curr != PULL) 11327 return -1; 11328 if (sizeof(*out) > size) 11329 return -1; 11330 out->command = ctx->curr; 11331 ctx->objdata = 0; 11332 ctx->object = out; 11333 ctx->objmask = NULL; 11334 out->args.vc.data = (uint8_t *)out + size; 11335 } 11336 return len; 11337 } 11338 11339 /** Parse tokens for hash calculation commands. */ 11340 static int 11341 parse_hash(struct context *ctx, const struct token *token, 11342 const char *str, unsigned int len, 11343 void *buf, unsigned int size) 11344 { 11345 struct buffer *out = buf; 11346 11347 /* Token name must match. */ 11348 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11349 return -1; 11350 /* Nothing else to do if there is no buffer. */ 11351 if (!out) 11352 return len; 11353 if (!out->command) { 11354 if (ctx->curr != HASH) 11355 return -1; 11356 if (sizeof(*out) > size) 11357 return -1; 11358 out->command = ctx->curr; 11359 ctx->objdata = 0; 11360 ctx->object = out; 11361 ctx->objmask = NULL; 11362 out->args.vc.data = (uint8_t *)out + size; 11363 return len; 11364 } 11365 switch (ctx->curr) { 11366 case HASH_CALC_TABLE: 11367 case HASH_CALC_PATTERN_INDEX: 11368 return len; 11369 case ITEM_PATTERN: 11370 out->args.vc.pattern = 11371 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11372 sizeof(double)); 11373 ctx->object = out->args.vc.pattern; 11374 ctx->objmask = NULL; 11375 return len; 11376 case HASH_CALC_ENCAP: 11377 out->args.vc.encap_hash = 1; 11378 return len; 11379 case ENCAP_HASH_FIELD_SRC_PORT: 11380 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT; 11381 return len; 11382 case ENCAP_HASH_FIELD_GRE_FLOW_ID: 11383 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID; 11384 return len; 11385 default: 11386 return -1; 11387 } 11388 } 11389 11390 static int 11391 parse_group(struct context *ctx, const struct token *token, 11392 const char *str, unsigned int len, 11393 void *buf, unsigned int size) 11394 { 11395 struct buffer *out = buf; 11396 11397 /* Token name must match. */ 11398 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11399 return -1; 11400 /* Nothing else to do if there is no buffer. */ 11401 if (!out) 11402 return len; 11403 if (!out->command) { 11404 if (ctx->curr != FLOW_GROUP) 11405 return -1; 11406 if (sizeof(*out) > size) 11407 return -1; 11408 out->command = ctx->curr; 11409 ctx->objdata = 0; 11410 ctx->object = out; 11411 ctx->objmask = NULL; 11412 out->args.vc.data = (uint8_t *)out + size; 11413 return len; 11414 } 11415 switch (ctx->curr) { 11416 case GROUP_INGRESS: 11417 out->args.vc.attr.ingress = 1; 11418 return len; 11419 case GROUP_EGRESS: 11420 out->args.vc.attr.egress = 1; 11421 return len; 11422 case GROUP_TRANSFER: 11423 out->args.vc.attr.transfer = 1; 11424 return len; 11425 case GROUP_SET_MISS_ACTIONS: 11426 out->command = ctx->curr; 11427 ctx->objdata = 0; 11428 ctx->object = out; 11429 ctx->objmask = NULL; 11430 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11431 sizeof(double)); 11432 return len; 11433 default: 11434 return -1; 11435 } 11436 } 11437 11438 static int 11439 parse_flex(struct context *ctx, const struct token *token, 11440 const char *str, unsigned int len, 11441 void *buf, unsigned int size) 11442 { 11443 struct buffer *out = buf; 11444 11445 /* Token name must match. */ 11446 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11447 return -1; 11448 /* Nothing else to do if there is no buffer. */ 11449 if (!out) 11450 return len; 11451 if (out->command == ZERO) { 11452 if (ctx->curr != FLEX) 11453 return -1; 11454 if (sizeof(*out) > size) 11455 return -1; 11456 out->command = ctx->curr; 11457 ctx->objdata = 0; 11458 ctx->object = out; 11459 ctx->objmask = NULL; 11460 } else { 11461 switch (ctx->curr) { 11462 default: 11463 break; 11464 case FLEX_ITEM_CREATE: 11465 case FLEX_ITEM_DESTROY: 11466 out->command = ctx->curr; 11467 break; 11468 } 11469 } 11470 11471 return len; 11472 } 11473 11474 static int 11475 parse_tunnel(struct context *ctx, const struct token *token, 11476 const char *str, unsigned int len, 11477 void *buf, unsigned int size) 11478 { 11479 struct buffer *out = buf; 11480 11481 /* Token name must match. */ 11482 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11483 return -1; 11484 /* Nothing else to do if there is no buffer. */ 11485 if (!out) 11486 return len; 11487 if (!out->command) { 11488 if (ctx->curr != TUNNEL) 11489 return -1; 11490 if (sizeof(*out) > size) 11491 return -1; 11492 out->command = ctx->curr; 11493 ctx->objdata = 0; 11494 ctx->object = out; 11495 ctx->objmask = NULL; 11496 } else { 11497 switch (ctx->curr) { 11498 default: 11499 break; 11500 case TUNNEL_CREATE: 11501 case TUNNEL_DESTROY: 11502 case TUNNEL_LIST: 11503 out->command = ctx->curr; 11504 break; 11505 case TUNNEL_CREATE_TYPE: 11506 case TUNNEL_DESTROY_ID: 11507 ctx->object = &out->args.vc.tunnel_ops; 11508 break; 11509 } 11510 } 11511 11512 return len; 11513 } 11514 11515 /** 11516 * Parse signed/unsigned integers 8 to 64-bit long. 11517 * 11518 * Last argument (ctx->args) is retrieved to determine integer type and 11519 * storage location. 11520 */ 11521 static int 11522 parse_int(struct context *ctx, const struct token *token, 11523 const char *str, unsigned int len, 11524 void *buf, unsigned int size) 11525 { 11526 const struct arg *arg = pop_args(ctx); 11527 uintmax_t u; 11528 char *end; 11529 11530 (void)token; 11531 /* Argument is expected. */ 11532 if (!arg) 11533 return -1; 11534 errno = 0; 11535 u = arg->sign ? 11536 (uintmax_t)strtoimax(str, &end, 0) : 11537 strtoumax(str, &end, 0); 11538 if (errno || (size_t)(end - str) != len) 11539 goto error; 11540 if (arg->bounded && 11541 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 11542 (intmax_t)u > (intmax_t)arg->max)) || 11543 (!arg->sign && (u < arg->min || u > arg->max)))) 11544 goto error; 11545 if (!ctx->object) 11546 return len; 11547 if (arg->mask) { 11548 if (!arg_entry_bf_fill(ctx->object, u, arg) || 11549 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 11550 goto error; 11551 return len; 11552 } 11553 buf = (uint8_t *)ctx->object + arg->offset; 11554 size = arg->size; 11555 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 11556 return -1; 11557 objmask: 11558 switch (size) { 11559 case sizeof(uint8_t): 11560 *(uint8_t *)buf = u; 11561 break; 11562 case sizeof(uint16_t): 11563 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 11564 break; 11565 case sizeof(uint8_t [3]): 11566 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 11567 if (!arg->hton) { 11568 ((uint8_t *)buf)[0] = u; 11569 ((uint8_t *)buf)[1] = u >> 8; 11570 ((uint8_t *)buf)[2] = u >> 16; 11571 break; 11572 } 11573 #endif 11574 ((uint8_t *)buf)[0] = u >> 16; 11575 ((uint8_t *)buf)[1] = u >> 8; 11576 ((uint8_t *)buf)[2] = u; 11577 break; 11578 case sizeof(uint32_t): 11579 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 11580 break; 11581 case sizeof(uint64_t): 11582 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 11583 break; 11584 default: 11585 goto error; 11586 } 11587 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 11588 u = -1; 11589 buf = (uint8_t *)ctx->objmask + arg->offset; 11590 goto objmask; 11591 } 11592 return len; 11593 error: 11594 push_args(ctx, arg); 11595 return -1; 11596 } 11597 11598 /** 11599 * Parse a string. 11600 * 11601 * Three arguments (ctx->args) are retrieved from the stack to store data, 11602 * its actual length and address (in that order). 11603 */ 11604 static int 11605 parse_string(struct context *ctx, const struct token *token, 11606 const char *str, unsigned int len, 11607 void *buf, unsigned int size) 11608 { 11609 const struct arg *arg_data = pop_args(ctx); 11610 const struct arg *arg_len = pop_args(ctx); 11611 const struct arg *arg_addr = pop_args(ctx); 11612 char tmp[16]; /* Ought to be enough. */ 11613 int ret; 11614 11615 /* Arguments are expected. */ 11616 if (!arg_data) 11617 return -1; 11618 if (!arg_len) { 11619 push_args(ctx, arg_data); 11620 return -1; 11621 } 11622 if (!arg_addr) { 11623 push_args(ctx, arg_len); 11624 push_args(ctx, arg_data); 11625 return -1; 11626 } 11627 size = arg_data->size; 11628 /* Bit-mask fill is not supported. */ 11629 if (arg_data->mask || size < len) 11630 goto error; 11631 if (!ctx->object) 11632 return len; 11633 /* Let parse_int() fill length information first. */ 11634 ret = snprintf(tmp, sizeof(tmp), "%u", len); 11635 if (ret < 0) 11636 goto error; 11637 push_args(ctx, arg_len); 11638 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11639 if (ret < 0) { 11640 pop_args(ctx); 11641 goto error; 11642 } 11643 buf = (uint8_t *)ctx->object + arg_data->offset; 11644 /* Output buffer is not necessarily NUL-terminated. */ 11645 memcpy(buf, str, len); 11646 memset((uint8_t *)buf + len, 0x00, size - len); 11647 if (ctx->objmask) 11648 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11649 /* Save address if requested. */ 11650 if (arg_addr->size) { 11651 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11652 (void *[]){ 11653 (uint8_t *)ctx->object + arg_data->offset 11654 }, 11655 arg_addr->size); 11656 if (ctx->objmask) 11657 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11658 (void *[]){ 11659 (uint8_t *)ctx->objmask + arg_data->offset 11660 }, 11661 arg_addr->size); 11662 } 11663 return len; 11664 error: 11665 push_args(ctx, arg_addr); 11666 push_args(ctx, arg_len); 11667 push_args(ctx, arg_data); 11668 return -1; 11669 } 11670 11671 static int 11672 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 11673 { 11674 const uint8_t *head = dst; 11675 uint32_t left; 11676 11677 if (*size == 0) 11678 return -1; 11679 11680 left = *size; 11681 11682 /* Convert chars to bytes */ 11683 while (left) { 11684 char tmp[3], *end = tmp; 11685 uint32_t read_lim = left & 1 ? 1 : 2; 11686 11687 snprintf(tmp, read_lim + 1, "%s", src); 11688 *dst = strtoul(tmp, &end, 16); 11689 if (*end) { 11690 *dst = 0; 11691 *size = (uint32_t)(dst - head); 11692 return -1; 11693 } 11694 left -= read_lim; 11695 src += read_lim; 11696 dst++; 11697 } 11698 *dst = 0; 11699 *size = (uint32_t)(dst - head); 11700 return 0; 11701 } 11702 11703 static int 11704 parse_hex(struct context *ctx, const struct token *token, 11705 const char *str, unsigned int len, 11706 void *buf, unsigned int size) 11707 { 11708 const struct arg *arg_data = pop_args(ctx); 11709 const struct arg *arg_len = pop_args(ctx); 11710 const struct arg *arg_addr = pop_args(ctx); 11711 char tmp[16]; /* Ought to be enough. */ 11712 int ret; 11713 unsigned int hexlen = len; 11714 unsigned int length = 256; 11715 uint8_t hex_tmp[length]; 11716 11717 /* Arguments are expected. */ 11718 if (!arg_data) 11719 return -1; 11720 if (!arg_len) { 11721 push_args(ctx, arg_data); 11722 return -1; 11723 } 11724 if (!arg_addr) { 11725 push_args(ctx, arg_len); 11726 push_args(ctx, arg_data); 11727 return -1; 11728 } 11729 size = arg_data->size; 11730 /* Bit-mask fill is not supported. */ 11731 if (arg_data->mask) 11732 goto error; 11733 if (!ctx->object) 11734 return len; 11735 11736 /* translate bytes string to array. */ 11737 if (str[0] == '0' && ((str[1] == 'x') || 11738 (str[1] == 'X'))) { 11739 str += 2; 11740 hexlen -= 2; 11741 } 11742 if (hexlen > length) 11743 goto error; 11744 ret = parse_hex_string(str, hex_tmp, &hexlen); 11745 if (ret < 0) 11746 goto error; 11747 /* Check the converted binary fits into data buffer. */ 11748 if (hexlen > size) 11749 goto error; 11750 /* Let parse_int() fill length information first. */ 11751 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 11752 if (ret < 0) 11753 goto error; 11754 /* Save length if requested. */ 11755 if (arg_len->size) { 11756 push_args(ctx, arg_len); 11757 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11758 if (ret < 0) { 11759 pop_args(ctx); 11760 goto error; 11761 } 11762 } 11763 buf = (uint8_t *)ctx->object + arg_data->offset; 11764 /* Output buffer is not necessarily NUL-terminated. */ 11765 memcpy(buf, hex_tmp, hexlen); 11766 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 11767 if (ctx->objmask) 11768 memset((uint8_t *)ctx->objmask + arg_data->offset, 11769 0xff, hexlen); 11770 /* Save address if requested. */ 11771 if (arg_addr->size) { 11772 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11773 (void *[]){ 11774 (uint8_t *)ctx->object + arg_data->offset 11775 }, 11776 arg_addr->size); 11777 if (ctx->objmask) 11778 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11779 (void *[]){ 11780 (uint8_t *)ctx->objmask + arg_data->offset 11781 }, 11782 arg_addr->size); 11783 } 11784 return len; 11785 error: 11786 push_args(ctx, arg_addr); 11787 push_args(ctx, arg_len); 11788 push_args(ctx, arg_data); 11789 return -1; 11790 11791 } 11792 11793 /** 11794 * Parse a zero-ended string. 11795 */ 11796 static int 11797 parse_string0(struct context *ctx, const struct token *token __rte_unused, 11798 const char *str, unsigned int len, 11799 void *buf, unsigned int size) 11800 { 11801 const struct arg *arg_data = pop_args(ctx); 11802 11803 /* Arguments are expected. */ 11804 if (!arg_data) 11805 return -1; 11806 size = arg_data->size; 11807 /* Bit-mask fill is not supported. */ 11808 if (arg_data->mask || size < len + 1) 11809 goto error; 11810 if (!ctx->object) 11811 return len; 11812 buf = (uint8_t *)ctx->object + arg_data->offset; 11813 strncpy(buf, str, len); 11814 if (ctx->objmask) 11815 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11816 return len; 11817 error: 11818 push_args(ctx, arg_data); 11819 return -1; 11820 } 11821 11822 /** 11823 * Parse a MAC address. 11824 * 11825 * Last argument (ctx->args) is retrieved to determine storage size and 11826 * location. 11827 */ 11828 static int 11829 parse_mac_addr(struct context *ctx, const struct token *token, 11830 const char *str, unsigned int len, 11831 void *buf, unsigned int size) 11832 { 11833 const struct arg *arg = pop_args(ctx); 11834 struct rte_ether_addr tmp; 11835 int ret; 11836 11837 (void)token; 11838 /* Argument is expected. */ 11839 if (!arg) 11840 return -1; 11841 size = arg->size; 11842 /* Bit-mask fill is not supported. */ 11843 if (arg->mask || size != sizeof(tmp)) 11844 goto error; 11845 /* Only network endian is supported. */ 11846 if (!arg->hton) 11847 goto error; 11848 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 11849 if (ret < 0 || (unsigned int)ret != len) 11850 goto error; 11851 if (!ctx->object) 11852 return len; 11853 buf = (uint8_t *)ctx->object + arg->offset; 11854 memcpy(buf, &tmp, size); 11855 if (ctx->objmask) 11856 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11857 return len; 11858 error: 11859 push_args(ctx, arg); 11860 return -1; 11861 } 11862 11863 /** 11864 * Parse an IPv4 address. 11865 * 11866 * Last argument (ctx->args) is retrieved to determine storage size and 11867 * location. 11868 */ 11869 static int 11870 parse_ipv4_addr(struct context *ctx, const struct token *token, 11871 const char *str, unsigned int len, 11872 void *buf, unsigned int size) 11873 { 11874 const struct arg *arg = pop_args(ctx); 11875 char str2[len + 1]; 11876 struct in_addr tmp; 11877 int ret; 11878 11879 /* Argument is expected. */ 11880 if (!arg) 11881 return -1; 11882 size = arg->size; 11883 /* Bit-mask fill is not supported. */ 11884 if (arg->mask || size != sizeof(tmp)) 11885 goto error; 11886 /* Only network endian is supported. */ 11887 if (!arg->hton) 11888 goto error; 11889 memcpy(str2, str, len); 11890 str2[len] = '\0'; 11891 ret = inet_pton(AF_INET, str2, &tmp); 11892 if (ret != 1) { 11893 /* Attempt integer parsing. */ 11894 push_args(ctx, arg); 11895 return parse_int(ctx, token, str, len, buf, size); 11896 } 11897 if (!ctx->object) 11898 return len; 11899 buf = (uint8_t *)ctx->object + arg->offset; 11900 memcpy(buf, &tmp, size); 11901 if (ctx->objmask) 11902 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11903 return len; 11904 error: 11905 push_args(ctx, arg); 11906 return -1; 11907 } 11908 11909 /** 11910 * Parse an IPv6 address. 11911 * 11912 * Last argument (ctx->args) is retrieved to determine storage size and 11913 * location. 11914 */ 11915 static int 11916 parse_ipv6_addr(struct context *ctx, const struct token *token, 11917 const char *str, unsigned int len, 11918 void *buf, unsigned int size) 11919 { 11920 const struct arg *arg = pop_args(ctx); 11921 char str2[len + 1]; 11922 struct in6_addr tmp; 11923 int ret; 11924 11925 (void)token; 11926 /* Argument is expected. */ 11927 if (!arg) 11928 return -1; 11929 size = arg->size; 11930 /* Bit-mask fill is not supported. */ 11931 if (arg->mask || size != sizeof(tmp)) 11932 goto error; 11933 /* Only network endian is supported. */ 11934 if (!arg->hton) 11935 goto error; 11936 memcpy(str2, str, len); 11937 str2[len] = '\0'; 11938 ret = inet_pton(AF_INET6, str2, &tmp); 11939 if (ret != 1) 11940 goto error; 11941 if (!ctx->object) 11942 return len; 11943 buf = (uint8_t *)ctx->object + arg->offset; 11944 memcpy(buf, &tmp, size); 11945 if (ctx->objmask) 11946 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11947 return len; 11948 error: 11949 push_args(ctx, arg); 11950 return -1; 11951 } 11952 11953 /** Boolean values (even indices stand for false). */ 11954 static const char *const boolean_name[] = { 11955 "0", "1", 11956 "false", "true", 11957 "no", "yes", 11958 "N", "Y", 11959 "off", "on", 11960 NULL, 11961 }; 11962 11963 /** 11964 * Parse a boolean value. 11965 * 11966 * Last argument (ctx->args) is retrieved to determine storage size and 11967 * location. 11968 */ 11969 static int 11970 parse_boolean(struct context *ctx, const struct token *token, 11971 const char *str, unsigned int len, 11972 void *buf, unsigned int size) 11973 { 11974 const struct arg *arg = pop_args(ctx); 11975 unsigned int i; 11976 int ret; 11977 11978 /* Argument is expected. */ 11979 if (!arg) 11980 return -1; 11981 for (i = 0; boolean_name[i]; ++i) 11982 if (!strcmp_partial(boolean_name[i], str, len)) 11983 break; 11984 /* Process token as integer. */ 11985 if (boolean_name[i]) 11986 str = i & 1 ? "1" : "0"; 11987 push_args(ctx, arg); 11988 ret = parse_int(ctx, token, str, strlen(str), buf, size); 11989 return ret > 0 ? (int)len : ret; 11990 } 11991 11992 /** Parse port and update context. */ 11993 static int 11994 parse_port(struct context *ctx, const struct token *token, 11995 const char *str, unsigned int len, 11996 void *buf, unsigned int size) 11997 { 11998 struct buffer *out = &(struct buffer){ .port = 0 }; 11999 int ret; 12000 12001 if (buf) 12002 out = buf; 12003 else { 12004 ctx->objdata = 0; 12005 ctx->object = out; 12006 ctx->objmask = NULL; 12007 size = sizeof(*out); 12008 } 12009 ret = parse_int(ctx, token, str, len, out, size); 12010 if (ret >= 0) 12011 ctx->port = out->port; 12012 if (!buf) 12013 ctx->object = NULL; 12014 return ret; 12015 } 12016 12017 /** Parse tokens for shared indirect actions. */ 12018 static int 12019 parse_ia_port(struct context *ctx, const struct token *token, 12020 const char *str, unsigned int len, 12021 void *buf, unsigned int size) 12022 { 12023 struct rte_flow_action *action = ctx->object; 12024 uint32_t id; 12025 int ret; 12026 12027 (void)buf; 12028 (void)size; 12029 ctx->objdata = 0; 12030 ctx->object = &id; 12031 ctx->objmask = NULL; 12032 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12033 ctx->object = action; 12034 if (ret != (int)len) 12035 return ret; 12036 /* set indirect action */ 12037 if (action) 12038 action->conf = (void *)(uintptr_t)id; 12039 return ret; 12040 } 12041 12042 static int 12043 parse_ia_id2ptr(struct context *ctx, const struct token *token, 12044 const char *str, unsigned int len, 12045 void *buf, unsigned int size) 12046 { 12047 struct rte_flow_action *action = ctx->object; 12048 uint32_t id; 12049 int ret; 12050 12051 (void)buf; 12052 (void)size; 12053 ctx->objdata = 0; 12054 ctx->object = &id; 12055 ctx->objmask = NULL; 12056 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12057 ctx->object = action; 12058 if (ret != (int)len) 12059 return ret; 12060 /* set indirect action */ 12061 if (action) { 12062 portid_t port_id = ctx->port; 12063 if (ctx->prev == INDIRECT_ACTION_PORT) 12064 port_id = (portid_t)(uintptr_t)action->conf; 12065 action->conf = port_action_handle_get_by_id(port_id, id); 12066 ret = (action->conf) ? ret : -1; 12067 } 12068 return ret; 12069 } 12070 12071 static int 12072 parse_indlst_id2ptr(struct context *ctx, const struct token *token, 12073 const char *str, unsigned int len, 12074 __rte_unused void *buf, __rte_unused unsigned int size) 12075 { 12076 struct rte_flow_action *action = ctx->object; 12077 struct rte_flow_action_indirect_list *action_conf; 12078 const struct indlst_conf *indlst_conf; 12079 uint32_t id; 12080 int ret; 12081 12082 ctx->objdata = 0; 12083 ctx->object = &id; 12084 ctx->objmask = NULL; 12085 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12086 ctx->object = action; 12087 if (ret != (int)len) 12088 return ret; 12089 12090 /* set handle and conf */ 12091 if (action) { 12092 action_conf = (void *)(uintptr_t)action->conf; 12093 action_conf->conf = NULL; 12094 switch (ctx->curr) { 12095 case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: 12096 action_conf->handle = (typeof(action_conf->handle)) 12097 port_action_handle_get_by_id(ctx->port, id); 12098 if (!action_conf->handle) { 12099 printf("no indirect list handle for id %u\n", id); 12100 return -1; 12101 } 12102 break; 12103 case INDIRECT_LIST_ACTION_ID2PTR_CONF: 12104 indlst_conf = indirect_action_list_conf_get(id); 12105 if (!indlst_conf) 12106 return -1; 12107 action_conf->conf = (const void **)indlst_conf->conf; 12108 break; 12109 default: 12110 break; 12111 } 12112 } 12113 return ret; 12114 } 12115 12116 static int 12117 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 12118 const char *str, unsigned int len, 12119 void *buf, unsigned int size) 12120 { 12121 struct rte_flow_action *action = ctx->object; 12122 struct rte_flow_action_meter_mark *meter; 12123 struct rte_flow_meter_profile *profile = NULL; 12124 uint32_t id = 0; 12125 int ret; 12126 12127 (void)buf; 12128 (void)size; 12129 ctx->objdata = 0; 12130 ctx->object = &id; 12131 ctx->objmask = NULL; 12132 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12133 ctx->object = action; 12134 if (ret != (int)len) 12135 return ret; 12136 /* set meter profile */ 12137 if (action) { 12138 meter = (struct rte_flow_action_meter_mark *) 12139 (uintptr_t)(action->conf); 12140 profile = port_meter_profile_get_by_id(ctx->port, id); 12141 meter->profile = profile; 12142 ret = (profile) ? ret : -1; 12143 } 12144 return ret; 12145 } 12146 12147 static int 12148 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 12149 const char *str, unsigned int len, 12150 void *buf, unsigned int size) 12151 { 12152 struct rte_flow_action *action = ctx->object; 12153 struct rte_flow_action_meter_mark *meter; 12154 struct rte_flow_meter_policy *policy = NULL; 12155 uint32_t id = 0; 12156 int ret; 12157 12158 (void)buf; 12159 (void)size; 12160 ctx->objdata = 0; 12161 ctx->object = &id; 12162 ctx->objmask = NULL; 12163 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12164 ctx->object = action; 12165 if (ret != (int)len) 12166 return ret; 12167 /* set meter policy */ 12168 if (action) { 12169 meter = (struct rte_flow_action_meter_mark *) 12170 (uintptr_t)(action->conf); 12171 policy = port_meter_policy_get_by_id(ctx->port, id); 12172 meter->policy = policy; 12173 ret = (policy) ? ret : -1; 12174 } 12175 return ret; 12176 } 12177 12178 /** Parse set command, initialize output buffer for subsequent tokens. */ 12179 static int 12180 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 12181 const char *str, unsigned int len, 12182 void *buf, unsigned int size) 12183 { 12184 struct buffer *out = buf; 12185 12186 /* Token name must match. */ 12187 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12188 return -1; 12189 /* Nothing else to do if there is no buffer. */ 12190 if (!out) 12191 return len; 12192 /* Make sure buffer is large enough. */ 12193 if (size < sizeof(*out)) 12194 return -1; 12195 ctx->objdata = 0; 12196 ctx->objmask = NULL; 12197 ctx->object = out; 12198 if (!out->command) 12199 return -1; 12200 out->command = ctx->curr; 12201 /* For encap/decap we need is pattern */ 12202 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12203 sizeof(double)); 12204 return len; 12205 } 12206 12207 /** Parse set command, initialize output buffer for subsequent tokens. */ 12208 static int 12209 parse_set_sample_action(struct context *ctx, const struct token *token, 12210 const char *str, unsigned int len, 12211 void *buf, unsigned int size) 12212 { 12213 struct buffer *out = buf; 12214 12215 /* Token name must match. */ 12216 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12217 return -1; 12218 /* Nothing else to do if there is no buffer. */ 12219 if (!out) 12220 return len; 12221 /* Make sure buffer is large enough. */ 12222 if (size < sizeof(*out)) 12223 return -1; 12224 ctx->objdata = 0; 12225 ctx->objmask = NULL; 12226 ctx->object = out; 12227 if (!out->command) 12228 return -1; 12229 out->command = ctx->curr; 12230 /* For sampler we need is actions */ 12231 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12232 sizeof(double)); 12233 return len; 12234 } 12235 12236 /** Parse set command, initialize output buffer for subsequent tokens. */ 12237 static int 12238 parse_set_ipv6_ext_action(struct context *ctx, const struct token *token, 12239 const char *str, unsigned int len, 12240 void *buf, unsigned int size) 12241 { 12242 struct buffer *out = buf; 12243 12244 /* Token name must match. */ 12245 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12246 return -1; 12247 /* Nothing else to do if there is no buffer. */ 12248 if (!out) 12249 return len; 12250 /* Make sure buffer is large enough. */ 12251 if (size < sizeof(*out)) 12252 return -1; 12253 ctx->objdata = 0; 12254 ctx->objmask = NULL; 12255 ctx->object = out; 12256 if (!out->command) 12257 return -1; 12258 out->command = ctx->curr; 12259 /* For ipv6_ext_push/remove we need is pattern */ 12260 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12261 sizeof(double)); 12262 return len; 12263 } 12264 12265 /** 12266 * Parse set raw_encap/raw_decap command, 12267 * initialize output buffer for subsequent tokens. 12268 */ 12269 static int 12270 parse_set_init(struct context *ctx, const struct token *token, 12271 const char *str, unsigned int len, 12272 void *buf, unsigned int size) 12273 { 12274 struct buffer *out = buf; 12275 12276 /* Token name must match. */ 12277 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12278 return -1; 12279 /* Nothing else to do if there is no buffer. */ 12280 if (!out) 12281 return len; 12282 /* Make sure buffer is large enough. */ 12283 if (size < sizeof(*out)) 12284 return -1; 12285 /* Initialize buffer. */ 12286 memset(out, 0x00, sizeof(*out)); 12287 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 12288 ctx->objdata = 0; 12289 ctx->object = out; 12290 ctx->objmask = NULL; 12291 if (!out->command) { 12292 if (ctx->curr != SET) 12293 return -1; 12294 if (sizeof(*out) > size) 12295 return -1; 12296 out->command = ctx->curr; 12297 out->args.vc.data = (uint8_t *)out + size; 12298 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12299 sizeof(double)); 12300 } 12301 return len; 12302 } 12303 12304 /* 12305 * Replace testpmd handles in a flex flow item with real values. 12306 */ 12307 static int 12308 parse_flex_handle(struct context *ctx, const struct token *token, 12309 const char *str, unsigned int len, 12310 void *buf, unsigned int size) 12311 { 12312 struct rte_flow_item_flex *spec, *mask; 12313 const struct rte_flow_item_flex *src_spec, *src_mask; 12314 const struct arg *arg = pop_args(ctx); 12315 uint32_t offset; 12316 uint16_t handle; 12317 int ret; 12318 12319 if (!arg) { 12320 printf("Bad environment\n"); 12321 return -1; 12322 } 12323 offset = arg->offset; 12324 push_args(ctx, arg); 12325 ret = parse_int(ctx, token, str, len, buf, size); 12326 if (ret <= 0 || !ctx->object) 12327 return ret; 12328 if (ctx->port >= RTE_MAX_ETHPORTS) { 12329 printf("Bad port\n"); 12330 return -1; 12331 } 12332 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 12333 const struct flex_item *fp; 12334 spec = ctx->object; 12335 handle = (uint16_t)(uintptr_t)spec->handle; 12336 if (handle >= FLEX_MAX_PARSERS_NUM) { 12337 printf("Bad flex item handle\n"); 12338 return -1; 12339 } 12340 fp = flex_items[ctx->port][handle]; 12341 if (!fp) { 12342 printf("Bad flex item handle\n"); 12343 return -1; 12344 } 12345 spec->handle = fp->flex_handle; 12346 mask = spec + 2; /* spec, last, mask */ 12347 mask->handle = fp->flex_handle; 12348 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 12349 handle = (uint16_t)(uintptr_t) 12350 ((struct rte_flow_item_flex *)ctx->object)->pattern; 12351 if (handle >= FLEX_MAX_PATTERNS_NUM) { 12352 printf("Bad pattern handle\n"); 12353 return -1; 12354 } 12355 src_spec = &flex_patterns[handle].spec; 12356 src_mask = &flex_patterns[handle].mask; 12357 spec = ctx->object; 12358 mask = spec + 2; /* spec, last, mask */ 12359 /* fill flow rule spec and mask parameters */ 12360 spec->length = src_spec->length; 12361 spec->pattern = src_spec->pattern; 12362 mask->length = src_mask->length; 12363 mask->pattern = src_mask->pattern; 12364 } else { 12365 printf("Bad arguments - unknown flex item offset\n"); 12366 return -1; 12367 } 12368 return ret; 12369 } 12370 12371 /** Parse Meter color name */ 12372 static int 12373 parse_meter_color(struct context *ctx, const struct token *token, 12374 const char *str, unsigned int len, void *buf, 12375 unsigned int size) 12376 { 12377 struct rte_flow_item_meter_color *meter_color; 12378 unsigned int i; 12379 12380 (void)token; 12381 (void)buf; 12382 (void)size; 12383 for (i = 0; meter_colors[i]; ++i) 12384 if (!strcmp_partial(meter_colors[i], str, len)) 12385 break; 12386 if (!meter_colors[i]) 12387 return -1; 12388 if (!ctx->object) 12389 return len; 12390 meter_color = ctx->object; 12391 meter_color->color = (enum rte_color)i; 12392 return len; 12393 } 12394 12395 /** Parse Insertion Table Type name */ 12396 static int 12397 parse_insertion_table_type(struct context *ctx, const struct token *token, 12398 const char *str, unsigned int len, void *buf, 12399 unsigned int size) 12400 { 12401 const struct arg *arg = pop_args(ctx); 12402 unsigned int i; 12403 char tmp[2]; 12404 int ret; 12405 12406 (void)size; 12407 /* Argument is expected. */ 12408 if (!arg) 12409 return -1; 12410 for (i = 0; table_insertion_types[i]; ++i) 12411 if (!strcmp_partial(table_insertion_types[i], str, len)) 12412 break; 12413 if (!table_insertion_types[i]) 12414 return -1; 12415 push_args(ctx, arg); 12416 snprintf(tmp, sizeof(tmp), "%u", i); 12417 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12418 return ret > 0 ? (int)len : ret; 12419 } 12420 12421 /** Parse Hash Calculation Table Type name */ 12422 static int 12423 parse_hash_table_type(struct context *ctx, const struct token *token, 12424 const char *str, unsigned int len, void *buf, 12425 unsigned int size) 12426 { 12427 const struct arg *arg = pop_args(ctx); 12428 unsigned int i; 12429 char tmp[2]; 12430 int ret; 12431 12432 (void)size; 12433 /* Argument is expected. */ 12434 if (!arg) 12435 return -1; 12436 for (i = 0; table_hash_funcs[i]; ++i) 12437 if (!strcmp_partial(table_hash_funcs[i], str, len)) 12438 break; 12439 if (!table_hash_funcs[i]) 12440 return -1; 12441 push_args(ctx, arg); 12442 snprintf(tmp, sizeof(tmp), "%u", i); 12443 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12444 return ret > 0 ? (int)len : ret; 12445 } 12446 12447 static int 12448 parse_name_to_index(struct context *ctx, const struct token *token, 12449 const char *str, unsigned int len, void *buf, 12450 unsigned int size, 12451 const char *const names[], size_t names_size, uint32_t *dst) 12452 { 12453 int ret; 12454 uint32_t i; 12455 12456 RTE_SET_USED(token); 12457 RTE_SET_USED(buf); 12458 RTE_SET_USED(size); 12459 if (!ctx->object) 12460 return len; 12461 for (i = 0; i < names_size; i++) { 12462 if (!names[i]) 12463 continue; 12464 ret = strcmp_partial(names[i], str, 12465 RTE_MIN(len, strlen(names[i]))); 12466 if (!ret) { 12467 *dst = i; 12468 return len; 12469 } 12470 } 12471 return -1; 12472 } 12473 12474 static const char *const quota_mode_names[] = { 12475 NULL, 12476 [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", 12477 [RTE_FLOW_QUOTA_MODE_L2] = "l2", 12478 [RTE_FLOW_QUOTA_MODE_L3] = "l3" 12479 }; 12480 12481 static const char *const quota_state_names[] = { 12482 [RTE_FLOW_QUOTA_STATE_PASS] = "pass", 12483 [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" 12484 }; 12485 12486 static const char *const quota_update_names[] = { 12487 [RTE_FLOW_UPDATE_QUOTA_SET] = "set", 12488 [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" 12489 }; 12490 12491 static const char *const query_update_mode_names[] = { 12492 [RTE_FLOW_QU_QUERY_FIRST] = "query_first", 12493 [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" 12494 }; 12495 12496 static int 12497 parse_quota_state_name(struct context *ctx, const struct token *token, 12498 const char *str, unsigned int len, void *buf, 12499 unsigned int size) 12500 { 12501 struct rte_flow_item_quota *quota = ctx->object; 12502 12503 return parse_name_to_index(ctx, token, str, len, buf, size, 12504 quota_state_names, 12505 RTE_DIM(quota_state_names), 12506 (uint32_t *)"a->state); 12507 } 12508 12509 static int 12510 parse_quota_mode_name(struct context *ctx, const struct token *token, 12511 const char *str, unsigned int len, void *buf, 12512 unsigned int size) 12513 { 12514 struct rte_flow_action_quota *quota = ctx->object; 12515 12516 return parse_name_to_index(ctx, token, str, len, buf, size, 12517 quota_mode_names, 12518 RTE_DIM(quota_mode_names), 12519 (uint32_t *)"a->mode); 12520 } 12521 12522 static int 12523 parse_quota_update_name(struct context *ctx, const struct token *token, 12524 const char *str, unsigned int len, void *buf, 12525 unsigned int size) 12526 { 12527 struct rte_flow_update_quota *update = ctx->object; 12528 12529 return parse_name_to_index(ctx, token, str, len, buf, size, 12530 quota_update_names, 12531 RTE_DIM(quota_update_names), 12532 (uint32_t *)&update->op); 12533 } 12534 12535 static int 12536 parse_qu_mode_name(struct context *ctx, const struct token *token, 12537 const char *str, unsigned int len, void *buf, 12538 unsigned int size) 12539 { 12540 struct buffer *out = ctx->object; 12541 12542 return parse_name_to_index(ctx, token, str, len, buf, size, 12543 query_update_mode_names, 12544 RTE_DIM(query_update_mode_names), 12545 (uint32_t *)&out->args.ia.qu_mode); 12546 } 12547 12548 /** No completion. */ 12549 static int 12550 comp_none(struct context *ctx, const struct token *token, 12551 unsigned int ent, char *buf, unsigned int size) 12552 { 12553 (void)ctx; 12554 (void)token; 12555 (void)ent; 12556 (void)buf; 12557 (void)size; 12558 return 0; 12559 } 12560 12561 /** Complete boolean values. */ 12562 static int 12563 comp_boolean(struct context *ctx, const struct token *token, 12564 unsigned int ent, char *buf, unsigned int size) 12565 { 12566 unsigned int i; 12567 12568 (void)ctx; 12569 (void)token; 12570 for (i = 0; boolean_name[i]; ++i) 12571 if (buf && i == ent) 12572 return strlcpy(buf, boolean_name[i], size); 12573 if (buf) 12574 return -1; 12575 return i; 12576 } 12577 12578 /** Complete action names. */ 12579 static int 12580 comp_action(struct context *ctx, const struct token *token, 12581 unsigned int ent, char *buf, unsigned int size) 12582 { 12583 unsigned int i; 12584 12585 (void)ctx; 12586 (void)token; 12587 for (i = 0; next_action[i]; ++i) 12588 if (buf && i == ent) 12589 return strlcpy(buf, token_list[next_action[i]].name, 12590 size); 12591 if (buf) 12592 return -1; 12593 return i; 12594 } 12595 12596 /** Complete available ports. */ 12597 static int 12598 comp_port(struct context *ctx, const struct token *token, 12599 unsigned int ent, char *buf, unsigned int size) 12600 { 12601 unsigned int i = 0; 12602 portid_t p; 12603 12604 (void)ctx; 12605 (void)token; 12606 RTE_ETH_FOREACH_DEV(p) { 12607 if (buf && i == ent) 12608 return snprintf(buf, size, "%u", p); 12609 ++i; 12610 } 12611 if (buf) 12612 return -1; 12613 return i; 12614 } 12615 12616 /** Complete available rule IDs. */ 12617 static int 12618 comp_rule_id(struct context *ctx, const struct token *token, 12619 unsigned int ent, char *buf, unsigned int size) 12620 { 12621 unsigned int i = 0; 12622 struct rte_port *port; 12623 struct port_flow *pf; 12624 12625 (void)token; 12626 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12627 ctx->port == (portid_t)RTE_PORT_ALL) 12628 return -1; 12629 port = &ports[ctx->port]; 12630 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 12631 if (buf && i == ent) 12632 return snprintf(buf, size, "%"PRIu64, pf->id); 12633 ++i; 12634 } 12635 if (buf) 12636 return -1; 12637 return i; 12638 } 12639 12640 /** Complete operation for compare match item. */ 12641 static int 12642 comp_set_compare_op(struct context *ctx, const struct token *token, 12643 unsigned int ent, char *buf, unsigned int size) 12644 { 12645 RTE_SET_USED(ctx); 12646 RTE_SET_USED(token); 12647 if (!buf) 12648 return RTE_DIM(compare_ops); 12649 if (ent < RTE_DIM(compare_ops) - 1) 12650 return strlcpy(buf, compare_ops[ent], size); 12651 return -1; 12652 } 12653 12654 /** Complete field id for compare match item. */ 12655 static int 12656 comp_set_compare_field_id(struct context *ctx, const struct token *token, 12657 unsigned int ent, char *buf, unsigned int size) 12658 { 12659 const char *name; 12660 12661 RTE_SET_USED(token); 12662 if (!buf) 12663 return RTE_DIM(flow_field_ids); 12664 if (ent >= RTE_DIM(flow_field_ids) - 1) 12665 return -1; 12666 name = flow_field_ids[ent]; 12667 if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE || 12668 (strcmp(name, "pointer") && strcmp(name, "value"))) 12669 return strlcpy(buf, name, size); 12670 return -1; 12671 } 12672 12673 /** Complete type field for RSS action. */ 12674 static int 12675 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 12676 unsigned int ent, char *buf, unsigned int size) 12677 { 12678 unsigned int i; 12679 12680 (void)ctx; 12681 (void)token; 12682 for (i = 0; rss_type_table[i].str; ++i) 12683 ; 12684 if (!buf) 12685 return i + 1; 12686 if (ent < i) 12687 return strlcpy(buf, rss_type_table[ent].str, size); 12688 if (ent == i) 12689 return snprintf(buf, size, "end"); 12690 return -1; 12691 } 12692 12693 /** Complete queue field for RSS action. */ 12694 static int 12695 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 12696 unsigned int ent, char *buf, unsigned int size) 12697 { 12698 (void)ctx; 12699 (void)token; 12700 if (!buf) 12701 return nb_rxq + 1; 12702 if (ent < nb_rxq) 12703 return snprintf(buf, size, "%u", ent); 12704 if (ent == nb_rxq) 12705 return snprintf(buf, size, "end"); 12706 return -1; 12707 } 12708 12709 /** Complete index number for set raw_encap/raw_decap commands. */ 12710 static int 12711 comp_set_raw_index(struct context *ctx, const struct token *token, 12712 unsigned int ent, char *buf, unsigned int size) 12713 { 12714 uint16_t idx = 0; 12715 uint16_t nb = 0; 12716 12717 RTE_SET_USED(ctx); 12718 RTE_SET_USED(token); 12719 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 12720 if (buf && idx == ent) 12721 return snprintf(buf, size, "%u", idx); 12722 ++nb; 12723 } 12724 return nb; 12725 } 12726 12727 /** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ 12728 static int 12729 comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 12730 unsigned int ent, char *buf, unsigned int size) 12731 { 12732 uint16_t idx = 0; 12733 uint16_t nb = 0; 12734 12735 RTE_SET_USED(ctx); 12736 RTE_SET_USED(token); 12737 for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { 12738 if (buf && idx == ent) 12739 return snprintf(buf, size, "%u", idx); 12740 ++nb; 12741 } 12742 return nb; 12743 } 12744 12745 /** Complete index number for set raw_encap/raw_decap commands. */ 12746 static int 12747 comp_set_sample_index(struct context *ctx, const struct token *token, 12748 unsigned int ent, char *buf, unsigned int size) 12749 { 12750 uint16_t idx = 0; 12751 uint16_t nb = 0; 12752 12753 RTE_SET_USED(ctx); 12754 RTE_SET_USED(token); 12755 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 12756 if (buf && idx == ent) 12757 return snprintf(buf, size, "%u", idx); 12758 ++nb; 12759 } 12760 return nb; 12761 } 12762 12763 /** Complete operation for modify_field command. */ 12764 static int 12765 comp_set_modify_field_op(struct context *ctx, const struct token *token, 12766 unsigned int ent, char *buf, unsigned int size) 12767 { 12768 RTE_SET_USED(ctx); 12769 RTE_SET_USED(token); 12770 if (!buf) 12771 return RTE_DIM(modify_field_ops); 12772 if (ent < RTE_DIM(modify_field_ops) - 1) 12773 return strlcpy(buf, modify_field_ops[ent], size); 12774 return -1; 12775 } 12776 12777 /** Complete field id for modify_field command. */ 12778 static int 12779 comp_set_modify_field_id(struct context *ctx, const struct token *token, 12780 unsigned int ent, char *buf, unsigned int size) 12781 { 12782 const char *name; 12783 12784 RTE_SET_USED(token); 12785 if (!buf) 12786 return RTE_DIM(flow_field_ids); 12787 if (ent >= RTE_DIM(flow_field_ids) - 1) 12788 return -1; 12789 name = flow_field_ids[ent]; 12790 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 12791 (strcmp(name, "pointer") && strcmp(name, "value"))) 12792 return strlcpy(buf, name, size); 12793 return -1; 12794 } 12795 12796 /** Complete available pattern template IDs. */ 12797 static int 12798 comp_pattern_template_id(struct context *ctx, const struct token *token, 12799 unsigned int ent, char *buf, unsigned int size) 12800 { 12801 unsigned int i = 0; 12802 struct rte_port *port; 12803 struct port_template *pt; 12804 12805 (void)token; 12806 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12807 ctx->port == (portid_t)RTE_PORT_ALL) 12808 return -1; 12809 port = &ports[ctx->port]; 12810 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 12811 if (buf && i == ent) 12812 return snprintf(buf, size, "%u", pt->id); 12813 ++i; 12814 } 12815 if (buf) 12816 return -1; 12817 return i; 12818 } 12819 12820 /** Complete available actions template IDs. */ 12821 static int 12822 comp_actions_template_id(struct context *ctx, const struct token *token, 12823 unsigned int ent, char *buf, unsigned int size) 12824 { 12825 unsigned int i = 0; 12826 struct rte_port *port; 12827 struct port_template *pt; 12828 12829 (void)token; 12830 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12831 ctx->port == (portid_t)RTE_PORT_ALL) 12832 return -1; 12833 port = &ports[ctx->port]; 12834 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 12835 if (buf && i == ent) 12836 return snprintf(buf, size, "%u", pt->id); 12837 ++i; 12838 } 12839 if (buf) 12840 return -1; 12841 return i; 12842 } 12843 12844 /** Complete available table IDs. */ 12845 static int 12846 comp_table_id(struct context *ctx, const struct token *token, 12847 unsigned int ent, char *buf, unsigned int size) 12848 { 12849 unsigned int i = 0; 12850 struct rte_port *port; 12851 struct port_table *pt; 12852 12853 (void)token; 12854 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12855 ctx->port == (portid_t)RTE_PORT_ALL) 12856 return -1; 12857 port = &ports[ctx->port]; 12858 for (pt = port->table_list; pt != NULL; pt = pt->next) { 12859 if (buf && i == ent) 12860 return snprintf(buf, size, "%u", pt->id); 12861 ++i; 12862 } 12863 if (buf) 12864 return -1; 12865 return i; 12866 } 12867 12868 /** Complete available queue IDs. */ 12869 static int 12870 comp_queue_id(struct context *ctx, const struct token *token, 12871 unsigned int ent, char *buf, unsigned int size) 12872 { 12873 unsigned int i = 0; 12874 struct rte_port *port; 12875 12876 (void)token; 12877 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12878 ctx->port == (portid_t)RTE_PORT_ALL) 12879 return -1; 12880 port = &ports[ctx->port]; 12881 for (i = 0; i < port->queue_nb; i++) { 12882 if (buf && i == ent) 12883 return snprintf(buf, size, "%u", i); 12884 } 12885 if (buf) 12886 return -1; 12887 return i; 12888 } 12889 12890 static int 12891 comp_names_to_index(struct context *ctx, const struct token *token, 12892 unsigned int ent, char *buf, unsigned int size, 12893 const char *const names[], size_t names_size) 12894 { 12895 RTE_SET_USED(ctx); 12896 RTE_SET_USED(token); 12897 if (!buf) 12898 return names_size; 12899 if (names[ent] && ent < names_size) 12900 return rte_strscpy(buf, names[ent], size); 12901 return -1; 12902 12903 } 12904 12905 /** Complete available Meter colors. */ 12906 static int 12907 comp_meter_color(struct context *ctx, const struct token *token, 12908 unsigned int ent, char *buf, unsigned int size) 12909 { 12910 RTE_SET_USED(ctx); 12911 RTE_SET_USED(token); 12912 if (!buf) 12913 return RTE_DIM(meter_colors); 12914 if (ent < RTE_DIM(meter_colors) - 1) 12915 return strlcpy(buf, meter_colors[ent], size); 12916 return -1; 12917 } 12918 12919 /** Complete available Insertion Table types. */ 12920 static int 12921 comp_insertion_table_type(struct context *ctx, const struct token *token, 12922 unsigned int ent, char *buf, unsigned int size) 12923 { 12924 RTE_SET_USED(ctx); 12925 RTE_SET_USED(token); 12926 if (!buf) 12927 return RTE_DIM(table_insertion_types); 12928 if (ent < RTE_DIM(table_insertion_types) - 1) 12929 return rte_strscpy(buf, table_insertion_types[ent], size); 12930 return -1; 12931 } 12932 12933 /** Complete available Hash Calculation Table types. */ 12934 static int 12935 comp_hash_table_type(struct context *ctx, const struct token *token, 12936 unsigned int ent, char *buf, unsigned int size) 12937 { 12938 RTE_SET_USED(ctx); 12939 RTE_SET_USED(token); 12940 if (!buf) 12941 return RTE_DIM(table_hash_funcs); 12942 if (ent < RTE_DIM(table_hash_funcs) - 1) 12943 return rte_strscpy(buf, table_hash_funcs[ent], size); 12944 return -1; 12945 } 12946 12947 static int 12948 comp_quota_state_name(struct context *ctx, const struct token *token, 12949 unsigned int ent, char *buf, unsigned int size) 12950 { 12951 return comp_names_to_index(ctx, token, ent, buf, size, 12952 quota_state_names, 12953 RTE_DIM(quota_state_names)); 12954 } 12955 12956 static int 12957 comp_quota_mode_name(struct context *ctx, const struct token *token, 12958 unsigned int ent, char *buf, unsigned int size) 12959 { 12960 return comp_names_to_index(ctx, token, ent, buf, size, 12961 quota_mode_names, 12962 RTE_DIM(quota_mode_names)); 12963 } 12964 12965 static int 12966 comp_quota_update_name(struct context *ctx, const struct token *token, 12967 unsigned int ent, char *buf, unsigned int size) 12968 { 12969 return comp_names_to_index(ctx, token, ent, buf, size, 12970 quota_update_names, 12971 RTE_DIM(quota_update_names)); 12972 } 12973 12974 static int 12975 comp_qu_mode_name(struct context *ctx, const struct token *token, 12976 unsigned int ent, char *buf, unsigned int size) 12977 { 12978 return comp_names_to_index(ctx, token, ent, buf, size, 12979 query_update_mode_names, 12980 RTE_DIM(query_update_mode_names)); 12981 } 12982 12983 /** Internal context. */ 12984 static struct context cmd_flow_context; 12985 12986 /** Global parser instance (cmdline API). */ 12987 cmdline_parse_inst_t cmd_flow; 12988 cmdline_parse_inst_t cmd_set_raw; 12989 12990 /** Initialize context. */ 12991 static void 12992 cmd_flow_context_init(struct context *ctx) 12993 { 12994 /* A full memset() is not necessary. */ 12995 ctx->curr = ZERO; 12996 ctx->prev = ZERO; 12997 ctx->next_num = 0; 12998 ctx->args_num = 0; 12999 ctx->eol = 0; 13000 ctx->last = 0; 13001 ctx->port = 0; 13002 ctx->objdata = 0; 13003 ctx->object = NULL; 13004 ctx->objmask = NULL; 13005 } 13006 13007 /** Parse a token (cmdline API). */ 13008 static int 13009 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 13010 unsigned int size) 13011 { 13012 struct context *ctx = &cmd_flow_context; 13013 const struct token *token; 13014 const enum index *list; 13015 int len; 13016 int i; 13017 13018 (void)hdr; 13019 token = &token_list[ctx->curr]; 13020 /* Check argument length. */ 13021 ctx->eol = 0; 13022 ctx->last = 1; 13023 for (len = 0; src[len]; ++len) 13024 if (src[len] == '#' || isspace(src[len])) 13025 break; 13026 if (!len) 13027 return -1; 13028 /* Last argument and EOL detection. */ 13029 for (i = len; src[i]; ++i) 13030 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 13031 break; 13032 else if (!isspace(src[i])) { 13033 ctx->last = 0; 13034 break; 13035 } 13036 for (; src[i]; ++i) 13037 if (src[i] == '\r' || src[i] == '\n') { 13038 ctx->eol = 1; 13039 break; 13040 } 13041 /* Initialize context if necessary. */ 13042 if (!ctx->next_num) { 13043 if (!token->next) 13044 return 0; 13045 ctx->next[ctx->next_num++] = token->next[0]; 13046 } 13047 /* Process argument through candidates. */ 13048 ctx->prev = ctx->curr; 13049 list = ctx->next[ctx->next_num - 1]; 13050 for (i = 0; list[i]; ++i) { 13051 const struct token *next = &token_list[list[i]]; 13052 int tmp; 13053 13054 ctx->curr = list[i]; 13055 if (next->call) 13056 tmp = next->call(ctx, next, src, len, result, size); 13057 else 13058 tmp = parse_default(ctx, next, src, len, result, size); 13059 if (tmp == -1 || tmp != len) 13060 continue; 13061 token = next; 13062 break; 13063 } 13064 if (!list[i]) 13065 return -1; 13066 --ctx->next_num; 13067 /* Push subsequent tokens if any. */ 13068 if (token->next) 13069 for (i = 0; token->next[i]; ++i) { 13070 if (ctx->next_num == RTE_DIM(ctx->next)) 13071 return -1; 13072 ctx->next[ctx->next_num++] = token->next[i]; 13073 } 13074 /* Push arguments if any. */ 13075 if (token->args) 13076 for (i = 0; token->args[i]; ++i) { 13077 if (ctx->args_num == RTE_DIM(ctx->args)) 13078 return -1; 13079 ctx->args[ctx->args_num++] = token->args[i]; 13080 } 13081 return len; 13082 } 13083 13084 int 13085 flow_parse(const char *src, void *result, unsigned int size, 13086 struct rte_flow_attr **attr, 13087 struct rte_flow_item **pattern, struct rte_flow_action **actions) 13088 { 13089 int ret; 13090 struct context saved_flow_ctx = cmd_flow_context; 13091 13092 cmd_flow_context_init(&cmd_flow_context); 13093 do { 13094 ret = cmd_flow_parse(NULL, src, result, size); 13095 if (ret > 0) { 13096 src += ret; 13097 while (isspace(*src)) 13098 src++; 13099 } 13100 } while (ret > 0 && strlen(src)); 13101 cmd_flow_context = saved_flow_ctx; 13102 *attr = &((struct buffer *)result)->args.vc.attr; 13103 *pattern = ((struct buffer *)result)->args.vc.pattern; 13104 *actions = ((struct buffer *)result)->args.vc.actions; 13105 return (ret >= 0 && !strlen(src)) ? 0 : -1; 13106 } 13107 13108 /** Return number of completion entries (cmdline API). */ 13109 static int 13110 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 13111 { 13112 struct context *ctx = &cmd_flow_context; 13113 const struct token *token = &token_list[ctx->curr]; 13114 const enum index *list; 13115 int i; 13116 13117 (void)hdr; 13118 /* Count number of tokens in current list. */ 13119 if (ctx->next_num) 13120 list = ctx->next[ctx->next_num - 1]; 13121 else 13122 list = token->next[0]; 13123 for (i = 0; list[i]; ++i) 13124 ; 13125 if (!i) 13126 return 0; 13127 /* 13128 * If there is a single token, use its completion callback, otherwise 13129 * return the number of entries. 13130 */ 13131 token = &token_list[list[0]]; 13132 if (i == 1 && token->comp) { 13133 /* Save index for cmd_flow_get_help(). */ 13134 ctx->prev = list[0]; 13135 return token->comp(ctx, token, 0, NULL, 0); 13136 } 13137 return i; 13138 } 13139 13140 /** Return a completion entry (cmdline API). */ 13141 static int 13142 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 13143 char *dst, unsigned int size) 13144 { 13145 struct context *ctx = &cmd_flow_context; 13146 const struct token *token = &token_list[ctx->curr]; 13147 const enum index *list; 13148 int i; 13149 13150 (void)hdr; 13151 /* Count number of tokens in current list. */ 13152 if (ctx->next_num) 13153 list = ctx->next[ctx->next_num - 1]; 13154 else 13155 list = token->next[0]; 13156 for (i = 0; list[i]; ++i) 13157 ; 13158 if (!i) 13159 return -1; 13160 /* If there is a single token, use its completion callback. */ 13161 token = &token_list[list[0]]; 13162 if (i == 1 && token->comp) { 13163 /* Save index for cmd_flow_get_help(). */ 13164 ctx->prev = list[0]; 13165 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 13166 } 13167 /* Otherwise make sure the index is valid and use defaults. */ 13168 if (index >= i) 13169 return -1; 13170 token = &token_list[list[index]]; 13171 strlcpy(dst, token->name, size); 13172 /* Save index for cmd_flow_get_help(). */ 13173 ctx->prev = list[index]; 13174 return 0; 13175 } 13176 13177 /** Populate help strings for current token (cmdline API). */ 13178 static int 13179 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 13180 { 13181 struct context *ctx = &cmd_flow_context; 13182 const struct token *token = &token_list[ctx->prev]; 13183 13184 (void)hdr; 13185 if (!size) 13186 return -1; 13187 /* Set token type and update global help with details. */ 13188 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 13189 if (token->help) 13190 cmd_flow.help_str = token->help; 13191 else 13192 cmd_flow.help_str = token->name; 13193 return 0; 13194 } 13195 13196 /** Token definition template (cmdline API). */ 13197 static struct cmdline_token_hdr cmd_flow_token_hdr = { 13198 .ops = &(struct cmdline_token_ops){ 13199 .parse = cmd_flow_parse, 13200 .complete_get_nb = cmd_flow_complete_get_nb, 13201 .complete_get_elt = cmd_flow_complete_get_elt, 13202 .get_help = cmd_flow_get_help, 13203 }, 13204 .offset = 0, 13205 }; 13206 13207 /** Populate the next dynamic token. */ 13208 static void 13209 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 13210 cmdline_parse_token_hdr_t **hdr_inst) 13211 { 13212 struct context *ctx = &cmd_flow_context; 13213 13214 /* Always reinitialize context before requesting the first token. */ 13215 if (!(hdr_inst - cmd_flow.tokens)) 13216 cmd_flow_context_init(ctx); 13217 /* Return NULL when no more tokens are expected. */ 13218 if (!ctx->next_num && ctx->curr) { 13219 *hdr = NULL; 13220 return; 13221 } 13222 /* Determine if command should end here. */ 13223 if (ctx->eol && ctx->last && ctx->next_num) { 13224 const enum index *list = ctx->next[ctx->next_num - 1]; 13225 int i; 13226 13227 for (i = 0; list[i]; ++i) { 13228 if (list[i] != END) 13229 continue; 13230 *hdr = NULL; 13231 return; 13232 } 13233 } 13234 *hdr = &cmd_flow_token_hdr; 13235 } 13236 13237 static SLIST_HEAD(, indlst_conf) indlst_conf_head = 13238 SLIST_HEAD_INITIALIZER(); 13239 13240 static void 13241 indirect_action_flow_conf_create(const struct buffer *in) 13242 { 13243 int len, ret; 13244 uint32_t i; 13245 struct indlst_conf *indlst_conf = NULL; 13246 size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); 13247 struct rte_flow_action *src = in->args.vc.actions; 13248 13249 if (!in->args.vc.actions_n) 13250 goto end; 13251 len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); 13252 if (len <= 0) 13253 goto end; 13254 len = RTE_ALIGN(len, 16); 13255 13256 indlst_conf = calloc(1, base + len + 13257 in->args.vc.actions_n * sizeof(uintptr_t)); 13258 if (!indlst_conf) 13259 goto end; 13260 indlst_conf->id = in->args.vc.attr.group; 13261 indlst_conf->conf_num = in->args.vc.actions_n - 1; 13262 indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); 13263 ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, 13264 len, src, NULL); 13265 if (ret <= 0) { 13266 free(indlst_conf); 13267 indlst_conf = NULL; 13268 goto end; 13269 } 13270 indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); 13271 for (i = 0; i < indlst_conf->conf_num; i++) 13272 indlst_conf->conf[i] = indlst_conf->actions[i].conf; 13273 SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); 13274 end: 13275 if (indlst_conf) 13276 printf("created indirect action list configuration %u\n", 13277 in->args.vc.attr.group); 13278 else 13279 printf("cannot create indirect action list configuration %u\n", 13280 in->args.vc.attr.group); 13281 } 13282 13283 static const struct indlst_conf * 13284 indirect_action_list_conf_get(uint32_t conf_id) 13285 { 13286 const struct indlst_conf *conf; 13287 13288 SLIST_FOREACH(conf, &indlst_conf_head, next) { 13289 if (conf->id == conf_id) 13290 return conf; 13291 } 13292 return NULL; 13293 } 13294 13295 /** Dispatch parsed buffer to function calls. */ 13296 static void 13297 cmd_flow_parsed(const struct buffer *in) 13298 { 13299 switch (in->command) { 13300 case INFO: 13301 port_flow_get_info(in->port); 13302 break; 13303 case CONFIGURE: 13304 port_flow_configure(in->port, 13305 &in->args.configure.port_attr, 13306 in->args.configure.nb_queue, 13307 &in->args.configure.queue_attr); 13308 break; 13309 case PATTERN_TEMPLATE_CREATE: 13310 port_flow_pattern_template_create(in->port, 13311 in->args.vc.pat_templ_id, 13312 &((const struct rte_flow_pattern_template_attr) { 13313 .relaxed_matching = in->args.vc.attr.reserved, 13314 .ingress = in->args.vc.attr.ingress, 13315 .egress = in->args.vc.attr.egress, 13316 .transfer = in->args.vc.attr.transfer, 13317 }), 13318 in->args.vc.pattern); 13319 break; 13320 case PATTERN_TEMPLATE_DESTROY: 13321 port_flow_pattern_template_destroy(in->port, 13322 in->args.templ_destroy.template_id_n, 13323 in->args.templ_destroy.template_id); 13324 break; 13325 case ACTIONS_TEMPLATE_CREATE: 13326 port_flow_actions_template_create(in->port, 13327 in->args.vc.act_templ_id, 13328 &((const struct rte_flow_actions_template_attr) { 13329 .ingress = in->args.vc.attr.ingress, 13330 .egress = in->args.vc.attr.egress, 13331 .transfer = in->args.vc.attr.transfer, 13332 }), 13333 in->args.vc.actions, 13334 in->args.vc.masks); 13335 break; 13336 case ACTIONS_TEMPLATE_DESTROY: 13337 port_flow_actions_template_destroy(in->port, 13338 in->args.templ_destroy.template_id_n, 13339 in->args.templ_destroy.template_id); 13340 break; 13341 case TABLE_CREATE: 13342 port_flow_template_table_create(in->port, in->args.table.id, 13343 &in->args.table.attr, in->args.table.pat_templ_id_n, 13344 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 13345 in->args.table.act_templ_id); 13346 break; 13347 case TABLE_DESTROY: 13348 port_flow_template_table_destroy(in->port, 13349 in->args.table_destroy.table_id_n, 13350 in->args.table_destroy.table_id); 13351 break; 13352 case TABLE_RESIZE_COMPLETE: 13353 port_flow_template_table_resize_complete 13354 (in->port, in->args.table_destroy.table_id[0]); 13355 break; 13356 case GROUP_SET_MISS_ACTIONS: 13357 port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, 13358 in->args.vc.actions); 13359 break; 13360 case TABLE_RESIZE: 13361 port_flow_template_table_resize(in->port, in->args.table.id, 13362 in->args.table.attr.nb_flows); 13363 break; 13364 case QUEUE_CREATE: 13365 port_queue_flow_create(in->port, in->queue, in->postpone, 13366 in->args.vc.table_id, in->args.vc.rule_id, 13367 in->args.vc.pat_templ_id, in->args.vc.act_templ_id, 13368 in->args.vc.pattern, in->args.vc.actions); 13369 break; 13370 case QUEUE_DESTROY: 13371 port_queue_flow_destroy(in->port, in->queue, in->postpone, 13372 in->args.destroy.rule_n, 13373 in->args.destroy.rule); 13374 break; 13375 case QUEUE_FLOW_UPDATE_RESIZED: 13376 port_queue_flow_update_resized(in->port, in->queue, 13377 in->postpone, 13378 in->args.destroy.rule[0]); 13379 break; 13380 case QUEUE_UPDATE: 13381 port_queue_flow_update(in->port, in->queue, in->postpone, 13382 in->args.vc.rule_id, in->args.vc.act_templ_id, 13383 in->args.vc.actions); 13384 break; 13385 case PUSH: 13386 port_queue_flow_push(in->port, in->queue); 13387 break; 13388 case PULL: 13389 port_queue_flow_pull(in->port, in->queue); 13390 break; 13391 case HASH: 13392 if (!in->args.vc.encap_hash) 13393 port_flow_hash_calc(in->port, in->args.vc.table_id, 13394 in->args.vc.pat_templ_id, 13395 in->args.vc.pattern); 13396 else 13397 port_flow_hash_calc_encap(in->port, in->args.vc.field, 13398 in->args.vc.pattern); 13399 break; 13400 case QUEUE_AGED: 13401 port_queue_flow_aged(in->port, in->queue, 13402 in->args.aged.destroy); 13403 break; 13404 case QUEUE_INDIRECT_ACTION_CREATE: 13405 case QUEUE_INDIRECT_ACTION_LIST_CREATE: 13406 port_queue_action_handle_create( 13407 in->port, in->queue, in->postpone, 13408 in->args.vc.attr.group, 13409 in->command == QUEUE_INDIRECT_ACTION_LIST_CREATE, 13410 &((const struct rte_flow_indir_action_conf) { 13411 .ingress = in->args.vc.attr.ingress, 13412 .egress = in->args.vc.attr.egress, 13413 .transfer = in->args.vc.attr.transfer, 13414 }), 13415 in->args.vc.actions); 13416 break; 13417 case QUEUE_INDIRECT_ACTION_DESTROY: 13418 port_queue_action_handle_destroy(in->port, 13419 in->queue, in->postpone, 13420 in->args.ia_destroy.action_id_n, 13421 in->args.ia_destroy.action_id); 13422 break; 13423 case QUEUE_INDIRECT_ACTION_UPDATE: 13424 port_queue_action_handle_update(in->port, 13425 in->queue, in->postpone, 13426 in->args.vc.attr.group, 13427 in->args.vc.actions); 13428 break; 13429 case QUEUE_INDIRECT_ACTION_QUERY: 13430 port_queue_action_handle_query(in->port, 13431 in->queue, in->postpone, 13432 in->args.ia.action_id); 13433 break; 13434 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 13435 port_queue_action_handle_query_update(in->port, in->queue, 13436 in->postpone, 13437 in->args.ia.action_id, 13438 in->args.ia.qu_mode, 13439 in->args.vc.actions); 13440 break; 13441 case INDIRECT_ACTION_CREATE: 13442 case INDIRECT_ACTION_LIST_CREATE: 13443 port_action_handle_create( 13444 in->port, in->args.vc.attr.group, 13445 in->command == INDIRECT_ACTION_LIST_CREATE, 13446 &((const struct rte_flow_indir_action_conf) { 13447 .ingress = in->args.vc.attr.ingress, 13448 .egress = in->args.vc.attr.egress, 13449 .transfer = in->args.vc.attr.transfer, 13450 }), 13451 in->args.vc.actions); 13452 break; 13453 case INDIRECT_ACTION_FLOW_CONF_CREATE: 13454 indirect_action_flow_conf_create(in); 13455 break; 13456 case INDIRECT_ACTION_DESTROY: 13457 port_action_handle_destroy(in->port, 13458 in->args.ia_destroy.action_id_n, 13459 in->args.ia_destroy.action_id); 13460 break; 13461 case INDIRECT_ACTION_UPDATE: 13462 port_action_handle_update(in->port, in->args.vc.attr.group, 13463 in->args.vc.actions); 13464 break; 13465 case INDIRECT_ACTION_QUERY: 13466 port_action_handle_query(in->port, in->args.ia.action_id); 13467 break; 13468 case INDIRECT_ACTION_QUERY_UPDATE: 13469 port_action_handle_query_update(in->port, 13470 in->args.ia.action_id, 13471 in->args.ia.qu_mode, 13472 in->args.vc.actions); 13473 break; 13474 case VALIDATE: 13475 port_flow_validate(in->port, &in->args.vc.attr, 13476 in->args.vc.pattern, in->args.vc.actions, 13477 &in->args.vc.tunnel_ops); 13478 break; 13479 case CREATE: 13480 port_flow_create(in->port, &in->args.vc.attr, 13481 in->args.vc.pattern, in->args.vc.actions, 13482 &in->args.vc.tunnel_ops, in->args.vc.user_id); 13483 break; 13484 case DESTROY: 13485 port_flow_destroy(in->port, in->args.destroy.rule_n, 13486 in->args.destroy.rule, 13487 in->args.destroy.is_user_id); 13488 break; 13489 case UPDATE: 13490 port_flow_update(in->port, in->args.vc.rule_id, 13491 in->args.vc.actions, in->args.vc.user_id); 13492 break; 13493 case FLUSH: 13494 port_flow_flush(in->port); 13495 break; 13496 case DUMP_ONE: 13497 case DUMP_ALL: 13498 port_flow_dump(in->port, in->args.dump.mode, 13499 in->args.dump.rule, in->args.dump.file, 13500 in->args.dump.is_user_id); 13501 break; 13502 case QUERY: 13503 port_flow_query(in->port, in->args.query.rule, 13504 &in->args.query.action, 13505 in->args.query.is_user_id); 13506 break; 13507 case LIST: 13508 port_flow_list(in->port, in->args.list.group_n, 13509 in->args.list.group); 13510 break; 13511 case ISOLATE: 13512 port_flow_isolate(in->port, in->args.isolate.set); 13513 break; 13514 case AGED: 13515 port_flow_aged(in->port, in->args.aged.destroy); 13516 break; 13517 case TUNNEL_CREATE: 13518 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 13519 break; 13520 case TUNNEL_DESTROY: 13521 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 13522 break; 13523 case TUNNEL_LIST: 13524 port_flow_tunnel_list(in->port); 13525 break; 13526 case ACTION_POL_G: 13527 port_meter_policy_add(in->port, in->args.policy.policy_id, 13528 in->args.vc.actions); 13529 break; 13530 case FLEX_ITEM_CREATE: 13531 flex_item_create(in->port, in->args.flex.token, 13532 in->args.flex.filename); 13533 break; 13534 case FLEX_ITEM_DESTROY: 13535 flex_item_destroy(in->port, in->args.flex.token); 13536 break; 13537 default: 13538 break; 13539 } 13540 fflush(stdout); 13541 } 13542 13543 /** Token generator and output processing callback (cmdline API). */ 13544 static void 13545 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 13546 { 13547 if (cl == NULL) 13548 cmd_flow_tok(arg0, arg2); 13549 else 13550 cmd_flow_parsed(arg0); 13551 } 13552 13553 /** Global parser instance (cmdline API). */ 13554 cmdline_parse_inst_t cmd_flow = { 13555 .f = cmd_flow_cb, 13556 .data = NULL, /**< Unused. */ 13557 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 13558 .tokens = { 13559 NULL, 13560 }, /**< Tokens are returned by cmd_flow_tok(). */ 13561 }; 13562 13563 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 13564 13565 static void 13566 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 13567 { 13568 struct rte_ipv4_hdr *ipv4; 13569 struct rte_ether_hdr *eth; 13570 struct rte_ipv6_hdr *ipv6; 13571 struct rte_vxlan_hdr *vxlan; 13572 struct rte_vxlan_gpe_hdr *gpe; 13573 struct rte_flow_item_nvgre *nvgre; 13574 uint32_t ipv6_vtc_flow; 13575 13576 switch (item->type) { 13577 case RTE_FLOW_ITEM_TYPE_ETH: 13578 eth = (struct rte_ether_hdr *)buf; 13579 if (next_proto) 13580 eth->ether_type = rte_cpu_to_be_16(next_proto); 13581 break; 13582 case RTE_FLOW_ITEM_TYPE_IPV4: 13583 ipv4 = (struct rte_ipv4_hdr *)buf; 13584 if (!ipv4->version_ihl) 13585 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 13586 if (next_proto && ipv4->next_proto_id == 0) 13587 ipv4->next_proto_id = (uint8_t)next_proto; 13588 break; 13589 case RTE_FLOW_ITEM_TYPE_IPV6: 13590 ipv6 = (struct rte_ipv6_hdr *)buf; 13591 if (next_proto && ipv6->proto == 0) 13592 ipv6->proto = (uint8_t)next_proto; 13593 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 13594 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 13595 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 13596 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 13597 break; 13598 case RTE_FLOW_ITEM_TYPE_VXLAN: 13599 vxlan = (struct rte_vxlan_hdr *)buf; 13600 vxlan->vx_flags = 0x08; 13601 break; 13602 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13603 gpe = (struct rte_vxlan_gpe_hdr *)buf; 13604 gpe->vx_flags = 0x0C; 13605 break; 13606 case RTE_FLOW_ITEM_TYPE_NVGRE: 13607 nvgre = (struct rte_flow_item_nvgre *)buf; 13608 nvgre->protocol = rte_cpu_to_be_16(0x6558); 13609 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 13610 break; 13611 default: 13612 break; 13613 } 13614 } 13615 13616 /** Helper of get item's default mask. */ 13617 static const void * 13618 flow_item_default_mask(const struct rte_flow_item *item) 13619 { 13620 const void *mask = NULL; 13621 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 13622 static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { 13623 .hdr = { 13624 .next_hdr = 0xff, 13625 .type = 0xff, 13626 .segments_left = 0xff, 13627 }, 13628 }; 13629 13630 switch (item->type) { 13631 case RTE_FLOW_ITEM_TYPE_ANY: 13632 mask = &rte_flow_item_any_mask; 13633 break; 13634 case RTE_FLOW_ITEM_TYPE_PORT_ID: 13635 mask = &rte_flow_item_port_id_mask; 13636 break; 13637 case RTE_FLOW_ITEM_TYPE_RAW: 13638 mask = &rte_flow_item_raw_mask; 13639 break; 13640 case RTE_FLOW_ITEM_TYPE_ETH: 13641 mask = &rte_flow_item_eth_mask; 13642 break; 13643 case RTE_FLOW_ITEM_TYPE_VLAN: 13644 mask = &rte_flow_item_vlan_mask; 13645 break; 13646 case RTE_FLOW_ITEM_TYPE_IPV4: 13647 mask = &rte_flow_item_ipv4_mask; 13648 break; 13649 case RTE_FLOW_ITEM_TYPE_IPV6: 13650 mask = &rte_flow_item_ipv6_mask; 13651 break; 13652 case RTE_FLOW_ITEM_TYPE_ICMP: 13653 mask = &rte_flow_item_icmp_mask; 13654 break; 13655 case RTE_FLOW_ITEM_TYPE_UDP: 13656 mask = &rte_flow_item_udp_mask; 13657 break; 13658 case RTE_FLOW_ITEM_TYPE_TCP: 13659 mask = &rte_flow_item_tcp_mask; 13660 break; 13661 case RTE_FLOW_ITEM_TYPE_SCTP: 13662 mask = &rte_flow_item_sctp_mask; 13663 break; 13664 case RTE_FLOW_ITEM_TYPE_VXLAN: 13665 mask = &rte_flow_item_vxlan_mask; 13666 break; 13667 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13668 mask = &rte_flow_item_vxlan_gpe_mask; 13669 break; 13670 case RTE_FLOW_ITEM_TYPE_E_TAG: 13671 mask = &rte_flow_item_e_tag_mask; 13672 break; 13673 case RTE_FLOW_ITEM_TYPE_NVGRE: 13674 mask = &rte_flow_item_nvgre_mask; 13675 break; 13676 case RTE_FLOW_ITEM_TYPE_MPLS: 13677 mask = &rte_flow_item_mpls_mask; 13678 break; 13679 case RTE_FLOW_ITEM_TYPE_GRE: 13680 mask = &rte_flow_item_gre_mask; 13681 break; 13682 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13683 mask = &gre_key_default_mask; 13684 break; 13685 case RTE_FLOW_ITEM_TYPE_META: 13686 mask = &rte_flow_item_meta_mask; 13687 break; 13688 case RTE_FLOW_ITEM_TYPE_RANDOM: 13689 mask = &rte_flow_item_random_mask; 13690 break; 13691 case RTE_FLOW_ITEM_TYPE_FUZZY: 13692 mask = &rte_flow_item_fuzzy_mask; 13693 break; 13694 case RTE_FLOW_ITEM_TYPE_GTP: 13695 mask = &rte_flow_item_gtp_mask; 13696 break; 13697 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13698 mask = &rte_flow_item_gtp_psc_mask; 13699 break; 13700 case RTE_FLOW_ITEM_TYPE_GENEVE: 13701 mask = &rte_flow_item_geneve_mask; 13702 break; 13703 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13704 mask = &rte_flow_item_geneve_opt_mask; 13705 break; 13706 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 13707 mask = &rte_flow_item_pppoe_proto_id_mask; 13708 break; 13709 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13710 mask = &rte_flow_item_l2tpv3oip_mask; 13711 break; 13712 case RTE_FLOW_ITEM_TYPE_ESP: 13713 mask = &rte_flow_item_esp_mask; 13714 break; 13715 case RTE_FLOW_ITEM_TYPE_AH: 13716 mask = &rte_flow_item_ah_mask; 13717 break; 13718 case RTE_FLOW_ITEM_TYPE_PFCP: 13719 mask = &rte_flow_item_pfcp_mask; 13720 break; 13721 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 13722 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 13723 mask = &rte_flow_item_ethdev_mask; 13724 break; 13725 case RTE_FLOW_ITEM_TYPE_L2TPV2: 13726 mask = &rte_flow_item_l2tpv2_mask; 13727 break; 13728 case RTE_FLOW_ITEM_TYPE_PPP: 13729 mask = &rte_flow_item_ppp_mask; 13730 break; 13731 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 13732 mask = &rte_flow_item_meter_color_mask; 13733 break; 13734 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13735 mask = &ipv6_routing_ext_default_mask; 13736 break; 13737 case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: 13738 mask = &rte_flow_item_aggr_affinity_mask; 13739 break; 13740 case RTE_FLOW_ITEM_TYPE_TX_QUEUE: 13741 mask = &rte_flow_item_tx_queue_mask; 13742 break; 13743 case RTE_FLOW_ITEM_TYPE_IB_BTH: 13744 mask = &rte_flow_item_ib_bth_mask; 13745 break; 13746 case RTE_FLOW_ITEM_TYPE_PTYPE: 13747 mask = &rte_flow_item_ptype_mask; 13748 break; 13749 default: 13750 break; 13751 } 13752 return mask; 13753 } 13754 13755 /** Dispatch parsed buffer to function calls. */ 13756 static void 13757 cmd_set_ipv6_ext_parsed(const struct buffer *in) 13758 { 13759 uint32_t n = in->args.vc.pattern_n; 13760 int i = 0; 13761 struct rte_flow_item *item = NULL; 13762 size_t size = 0; 13763 uint8_t *data = NULL; 13764 uint8_t *type = NULL; 13765 size_t *total_size = NULL; 13766 uint16_t idx = in->port; /* We borrow port field as index */ 13767 struct rte_flow_item_ipv6_routing_ext *ext; 13768 const struct rte_flow_item_ipv6_ext *ipv6_ext; 13769 13770 RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || 13771 in->command == SET_IPV6_EXT_REMOVE); 13772 13773 if (in->command == SET_IPV6_EXT_REMOVE) { 13774 if (n != 1 || in->args.vc.pattern->type != 13775 RTE_FLOW_ITEM_TYPE_IPV6_EXT) { 13776 fprintf(stderr, "Error - Not supported item\n"); 13777 return; 13778 } 13779 type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; 13780 item = in->args.vc.pattern; 13781 ipv6_ext = item->spec; 13782 *type = ipv6_ext->next_hdr; 13783 return; 13784 } 13785 13786 total_size = &ipv6_ext_push_confs[idx].size; 13787 data = (uint8_t *)&ipv6_ext_push_confs[idx].data; 13788 type = (uint8_t *)&ipv6_ext_push_confs[idx].type; 13789 13790 *total_size = 0; 13791 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13792 for (i = n - 1 ; i >= 0; --i) { 13793 item = in->args.vc.pattern + i; 13794 switch (item->type) { 13795 case RTE_FLOW_ITEM_TYPE_IPV6_EXT: 13796 ipv6_ext = item->spec; 13797 *type = ipv6_ext->next_hdr; 13798 break; 13799 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13800 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13801 if (!ext->hdr.hdr_len) { 13802 size = sizeof(struct rte_ipv6_routing_ext) + 13803 (ext->hdr.segments_left << 4); 13804 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13805 /* Indicate no TLV once SRH. */ 13806 if (ext->hdr.type == 4) 13807 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13808 } else { 13809 size = sizeof(struct rte_ipv6_routing_ext) + 13810 (ext->hdr.hdr_len << 3); 13811 } 13812 *total_size += size; 13813 memcpy(data, ext, size); 13814 break; 13815 default: 13816 fprintf(stderr, "Error - Not supported item\n"); 13817 goto error; 13818 } 13819 } 13820 RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); 13821 return; 13822 error: 13823 *total_size = 0; 13824 memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); 13825 } 13826 13827 /** Dispatch parsed buffer to function calls. */ 13828 static void 13829 cmd_set_raw_parsed_sample(const struct buffer *in) 13830 { 13831 uint32_t n = in->args.vc.actions_n; 13832 uint32_t i = 0; 13833 struct rte_flow_action *action = NULL; 13834 struct rte_flow_action *data = NULL; 13835 const struct rte_flow_action_rss *rss = NULL; 13836 size_t size = 0; 13837 uint16_t idx = in->port; /* We borrow port field as index */ 13838 uint32_t max_size = sizeof(struct rte_flow_action) * 13839 ACTION_SAMPLE_ACTIONS_NUM; 13840 13841 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 13842 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 13843 memset(data, 0x00, max_size); 13844 for (; i <= n - 1; i++) { 13845 action = in->args.vc.actions + i; 13846 if (action->type == RTE_FLOW_ACTION_TYPE_END) 13847 break; 13848 switch (action->type) { 13849 case RTE_FLOW_ACTION_TYPE_MARK: 13850 size = sizeof(struct rte_flow_action_mark); 13851 rte_memcpy(&sample_mark[idx], 13852 (const void *)action->conf, size); 13853 action->conf = &sample_mark[idx]; 13854 break; 13855 case RTE_FLOW_ACTION_TYPE_COUNT: 13856 size = sizeof(struct rte_flow_action_count); 13857 rte_memcpy(&sample_count[idx], 13858 (const void *)action->conf, size); 13859 action->conf = &sample_count[idx]; 13860 break; 13861 case RTE_FLOW_ACTION_TYPE_QUEUE: 13862 size = sizeof(struct rte_flow_action_queue); 13863 rte_memcpy(&sample_queue[idx], 13864 (const void *)action->conf, size); 13865 action->conf = &sample_queue[idx]; 13866 break; 13867 case RTE_FLOW_ACTION_TYPE_RSS: 13868 size = sizeof(struct rte_flow_action_rss); 13869 rss = action->conf; 13870 rte_memcpy(&sample_rss_data[idx].conf, 13871 (const void *)rss, size); 13872 if (rss->key_len && rss->key) { 13873 sample_rss_data[idx].conf.key = 13874 sample_rss_data[idx].key; 13875 rte_memcpy((void *)((uintptr_t) 13876 sample_rss_data[idx].conf.key), 13877 (const void *)rss->key, 13878 sizeof(uint8_t) * rss->key_len); 13879 } 13880 if (rss->queue_num && rss->queue) { 13881 sample_rss_data[idx].conf.queue = 13882 sample_rss_data[idx].queue; 13883 rte_memcpy((void *)((uintptr_t) 13884 sample_rss_data[idx].conf.queue), 13885 (const void *)rss->queue, 13886 sizeof(uint16_t) * rss->queue_num); 13887 } 13888 action->conf = &sample_rss_data[idx].conf; 13889 break; 13890 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 13891 size = sizeof(struct rte_flow_action_raw_encap); 13892 rte_memcpy(&sample_encap[idx], 13893 (const void *)action->conf, size); 13894 action->conf = &sample_encap[idx]; 13895 break; 13896 case RTE_FLOW_ACTION_TYPE_PORT_ID: 13897 size = sizeof(struct rte_flow_action_port_id); 13898 rte_memcpy(&sample_port_id[idx], 13899 (const void *)action->conf, size); 13900 action->conf = &sample_port_id[idx]; 13901 break; 13902 case RTE_FLOW_ACTION_TYPE_PF: 13903 break; 13904 case RTE_FLOW_ACTION_TYPE_VF: 13905 size = sizeof(struct rte_flow_action_vf); 13906 rte_memcpy(&sample_vf[idx], 13907 (const void *)action->conf, size); 13908 action->conf = &sample_vf[idx]; 13909 break; 13910 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 13911 size = sizeof(struct rte_flow_action_vxlan_encap); 13912 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 13913 action->conf = &sample_vxlan_encap[idx].conf; 13914 break; 13915 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 13916 size = sizeof(struct rte_flow_action_nvgre_encap); 13917 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 13918 action->conf = &sample_nvgre_encap[idx]; 13919 break; 13920 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 13921 size = sizeof(struct rte_flow_action_ethdev); 13922 rte_memcpy(&sample_port_representor[idx], 13923 (const void *)action->conf, size); 13924 action->conf = &sample_port_representor[idx]; 13925 break; 13926 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 13927 size = sizeof(struct rte_flow_action_ethdev); 13928 rte_memcpy(&sample_represented_port[idx], 13929 (const void *)action->conf, size); 13930 action->conf = &sample_represented_port[idx]; 13931 break; 13932 default: 13933 fprintf(stderr, "Error - Not supported action\n"); 13934 return; 13935 } 13936 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 13937 data++; 13938 } 13939 } 13940 13941 /** Dispatch parsed buffer to function calls. */ 13942 static void 13943 cmd_set_raw_parsed(const struct buffer *in) 13944 { 13945 uint32_t n = in->args.vc.pattern_n; 13946 int i = 0; 13947 struct rte_flow_item *item = NULL; 13948 size_t size = 0; 13949 uint8_t *data = NULL; 13950 uint8_t *data_tail = NULL; 13951 size_t *total_size = NULL; 13952 uint16_t upper_layer = 0; 13953 uint16_t proto = 0; 13954 uint16_t idx = in->port; /* We borrow port field as index */ 13955 int gtp_psc = -1; /* GTP PSC option index. */ 13956 const void *src_spec; 13957 13958 if (in->command == SET_SAMPLE_ACTIONS) 13959 return cmd_set_raw_parsed_sample(in); 13960 else if (in->command == SET_IPV6_EXT_PUSH || 13961 in->command == SET_IPV6_EXT_REMOVE) 13962 return cmd_set_ipv6_ext_parsed(in); 13963 RTE_ASSERT(in->command == SET_RAW_ENCAP || 13964 in->command == SET_RAW_DECAP); 13965 if (in->command == SET_RAW_ENCAP) { 13966 total_size = &raw_encap_confs[idx].size; 13967 data = (uint8_t *)&raw_encap_confs[idx].data; 13968 } else { 13969 total_size = &raw_decap_confs[idx].size; 13970 data = (uint8_t *)&raw_decap_confs[idx].data; 13971 } 13972 *total_size = 0; 13973 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13974 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 13975 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 13976 for (i = n - 1 ; i >= 0; --i) { 13977 const struct rte_flow_item_gtp *gtp; 13978 const struct rte_flow_item_geneve_opt *opt; 13979 struct rte_flow_item_ipv6_routing_ext *ext; 13980 13981 item = in->args.vc.pattern + i; 13982 if (item->spec == NULL) 13983 item->spec = flow_item_default_mask(item); 13984 src_spec = item->spec; 13985 switch (item->type) { 13986 case RTE_FLOW_ITEM_TYPE_ETH: 13987 size = sizeof(struct rte_ether_hdr); 13988 break; 13989 case RTE_FLOW_ITEM_TYPE_VLAN: 13990 size = sizeof(struct rte_vlan_hdr); 13991 proto = RTE_ETHER_TYPE_VLAN; 13992 break; 13993 case RTE_FLOW_ITEM_TYPE_IPV4: 13994 size = sizeof(struct rte_ipv4_hdr); 13995 proto = RTE_ETHER_TYPE_IPV4; 13996 break; 13997 case RTE_FLOW_ITEM_TYPE_IPV6: 13998 size = sizeof(struct rte_ipv6_hdr); 13999 proto = RTE_ETHER_TYPE_IPV6; 14000 break; 14001 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 14002 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 14003 if (!ext->hdr.hdr_len) { 14004 size = sizeof(struct rte_ipv6_routing_ext) + 14005 (ext->hdr.segments_left << 4); 14006 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 14007 /* SRv6 without TLV. */ 14008 if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) 14009 ext->hdr.last_entry = ext->hdr.segments_left - 1; 14010 } else { 14011 size = sizeof(struct rte_ipv6_routing_ext) + 14012 (ext->hdr.hdr_len << 3); 14013 } 14014 proto = IPPROTO_ROUTING; 14015 break; 14016 case RTE_FLOW_ITEM_TYPE_UDP: 14017 size = sizeof(struct rte_udp_hdr); 14018 proto = 0x11; 14019 break; 14020 case RTE_FLOW_ITEM_TYPE_TCP: 14021 size = sizeof(struct rte_tcp_hdr); 14022 proto = 0x06; 14023 break; 14024 case RTE_FLOW_ITEM_TYPE_VXLAN: 14025 size = sizeof(struct rte_vxlan_hdr); 14026 break; 14027 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 14028 size = sizeof(struct rte_vxlan_gpe_hdr); 14029 break; 14030 case RTE_FLOW_ITEM_TYPE_GRE: 14031 size = sizeof(struct rte_gre_hdr); 14032 proto = 0x2F; 14033 break; 14034 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 14035 size = sizeof(rte_be32_t); 14036 proto = 0x0; 14037 break; 14038 case RTE_FLOW_ITEM_TYPE_MPLS: 14039 size = sizeof(struct rte_mpls_hdr); 14040 proto = 0x0; 14041 break; 14042 case RTE_FLOW_ITEM_TYPE_NVGRE: 14043 size = sizeof(struct rte_flow_item_nvgre); 14044 proto = 0x2F; 14045 break; 14046 case RTE_FLOW_ITEM_TYPE_GENEVE: 14047 size = sizeof(struct rte_geneve_hdr); 14048 break; 14049 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 14050 opt = (const struct rte_flow_item_geneve_opt *) 14051 item->spec; 14052 size = offsetof(struct rte_flow_item_geneve_opt, 14053 option_len) + sizeof(uint8_t); 14054 if (opt->option_len && opt->data) { 14055 *total_size += opt->option_len * 14056 sizeof(uint32_t); 14057 rte_memcpy(data_tail - (*total_size), 14058 opt->data, 14059 opt->option_len * sizeof(uint32_t)); 14060 } 14061 break; 14062 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 14063 size = sizeof(rte_be32_t); 14064 proto = 0x73; 14065 break; 14066 case RTE_FLOW_ITEM_TYPE_ESP: 14067 size = sizeof(struct rte_esp_hdr); 14068 proto = 0x32; 14069 break; 14070 case RTE_FLOW_ITEM_TYPE_AH: 14071 size = sizeof(struct rte_flow_item_ah); 14072 proto = 0x33; 14073 break; 14074 case RTE_FLOW_ITEM_TYPE_GTP: 14075 if (gtp_psc < 0) { 14076 size = sizeof(struct rte_gtp_hdr); 14077 break; 14078 } 14079 if (gtp_psc != i + 1) { 14080 fprintf(stderr, 14081 "Error - GTP PSC does not follow GTP\n"); 14082 goto error; 14083 } 14084 gtp = item->spec; 14085 if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { 14086 /* Only E flag should be set. */ 14087 fprintf(stderr, 14088 "Error - GTP unsupported flags\n"); 14089 goto error; 14090 } else { 14091 struct rte_gtp_hdr_ext_word ext_word = { 14092 .next_ext = 0x85 14093 }; 14094 14095 /* We have to add GTP header extra word. */ 14096 *total_size += sizeof(ext_word); 14097 rte_memcpy(data_tail - (*total_size), 14098 &ext_word, sizeof(ext_word)); 14099 } 14100 size = sizeof(struct rte_gtp_hdr); 14101 break; 14102 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 14103 if (gtp_psc >= 0) { 14104 fprintf(stderr, 14105 "Error - Multiple GTP PSC items\n"); 14106 goto error; 14107 } else { 14108 const struct rte_flow_item_gtp_psc 14109 *opt = item->spec; 14110 struct rte_gtp_psc_generic_hdr *hdr; 14111 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 14112 sizeof(int32_t)); 14113 14114 *total_size += hdr_size; 14115 hdr = (typeof(hdr))(data_tail - (*total_size)); 14116 memset(hdr, 0, hdr_size); 14117 *hdr = opt->hdr; 14118 hdr->ext_hdr_len = 1; 14119 gtp_psc = i; 14120 size = 0; 14121 } 14122 break; 14123 case RTE_FLOW_ITEM_TYPE_PFCP: 14124 size = sizeof(struct rte_flow_item_pfcp); 14125 break; 14126 case RTE_FLOW_ITEM_TYPE_FLEX: 14127 if (item->spec != NULL) { 14128 size = ((const struct rte_flow_item_flex *)item->spec)->length; 14129 src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; 14130 } else { 14131 size = 0; 14132 src_spec = NULL; 14133 } 14134 break; 14135 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 14136 size = 0; 14137 if (item->spec) { 14138 const struct rte_flow_item_gre_opt 14139 *opt = item->spec; 14140 if (opt->checksum_rsvd.checksum) { 14141 *total_size += 14142 sizeof(opt->checksum_rsvd); 14143 rte_memcpy(data_tail - (*total_size), 14144 &opt->checksum_rsvd, 14145 sizeof(opt->checksum_rsvd)); 14146 } 14147 if (opt->key.key) { 14148 *total_size += sizeof(opt->key.key); 14149 rte_memcpy(data_tail - (*total_size), 14150 &opt->key.key, 14151 sizeof(opt->key.key)); 14152 } 14153 if (opt->sequence.sequence) { 14154 *total_size += sizeof(opt->sequence.sequence); 14155 rte_memcpy(data_tail - (*total_size), 14156 &opt->sequence.sequence, 14157 sizeof(opt->sequence.sequence)); 14158 } 14159 } 14160 proto = 0x2F; 14161 break; 14162 default: 14163 fprintf(stderr, "Error - Not supported item\n"); 14164 goto error; 14165 } 14166 if (size) { 14167 *total_size += size; 14168 rte_memcpy(data_tail - (*total_size), src_spec, size); 14169 /* update some fields which cannot be set by cmdline */ 14170 update_fields((data_tail - (*total_size)), item, 14171 upper_layer); 14172 upper_layer = proto; 14173 } 14174 } 14175 if (verbose_level & 0x1) 14176 printf("total data size is %zu\n", (*total_size)); 14177 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 14178 memmove(data, (data_tail - (*total_size)), *total_size); 14179 return; 14180 14181 error: 14182 *total_size = 0; 14183 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 14184 } 14185 14186 /** Populate help strings for current token (cmdline API). */ 14187 static int 14188 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 14189 unsigned int size) 14190 { 14191 struct context *ctx = &cmd_flow_context; 14192 const struct token *token = &token_list[ctx->prev]; 14193 14194 (void)hdr; 14195 if (!size) 14196 return -1; 14197 /* Set token type and update global help with details. */ 14198 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 14199 if (token->help) 14200 cmd_set_raw.help_str = token->help; 14201 else 14202 cmd_set_raw.help_str = token->name; 14203 return 0; 14204 } 14205 14206 /** Token definition template (cmdline API). */ 14207 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 14208 .ops = &(struct cmdline_token_ops){ 14209 .parse = cmd_flow_parse, 14210 .complete_get_nb = cmd_flow_complete_get_nb, 14211 .complete_get_elt = cmd_flow_complete_get_elt, 14212 .get_help = cmd_set_raw_get_help, 14213 }, 14214 .offset = 0, 14215 }; 14216 14217 /** Populate the next dynamic token. */ 14218 static void 14219 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 14220 cmdline_parse_token_hdr_t **hdr_inst) 14221 { 14222 struct context *ctx = &cmd_flow_context; 14223 14224 /* Always reinitialize context before requesting the first token. */ 14225 if (!(hdr_inst - cmd_set_raw.tokens)) { 14226 cmd_flow_context_init(ctx); 14227 ctx->curr = START_SET; 14228 } 14229 /* Return NULL when no more tokens are expected. */ 14230 if (!ctx->next_num && (ctx->curr != START_SET)) { 14231 *hdr = NULL; 14232 return; 14233 } 14234 /* Determine if command should end here. */ 14235 if (ctx->eol && ctx->last && ctx->next_num) { 14236 const enum index *list = ctx->next[ctx->next_num - 1]; 14237 int i; 14238 14239 for (i = 0; list[i]; ++i) { 14240 if (list[i] != END) 14241 continue; 14242 *hdr = NULL; 14243 return; 14244 } 14245 } 14246 *hdr = &cmd_set_raw_token_hdr; 14247 } 14248 14249 /** Token generator and output processing callback (cmdline API). */ 14250 static void 14251 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 14252 { 14253 if (cl == NULL) 14254 cmd_set_raw_tok(arg0, arg2); 14255 else 14256 cmd_set_raw_parsed(arg0); 14257 } 14258 14259 /** Global parser instance (cmdline API). */ 14260 cmdline_parse_inst_t cmd_set_raw = { 14261 .f = cmd_set_raw_cb, 14262 .data = NULL, /**< Unused. */ 14263 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 14264 .tokens = { 14265 NULL, 14266 }, /**< Tokens are returned by cmd_flow_tok(). */ 14267 }; 14268 14269 /* *** display raw_encap/raw_decap buf */ 14270 struct cmd_show_set_raw_result { 14271 cmdline_fixed_string_t cmd_show; 14272 cmdline_fixed_string_t cmd_what; 14273 cmdline_fixed_string_t cmd_all; 14274 uint16_t cmd_index; 14275 }; 14276 14277 static void 14278 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 14279 { 14280 struct cmd_show_set_raw_result *res = parsed_result; 14281 uint16_t index = res->cmd_index; 14282 uint8_t all = 0; 14283 uint8_t *raw_data = NULL; 14284 size_t raw_size = 0; 14285 char title[16] = {0}; 14286 14287 RTE_SET_USED(cl); 14288 RTE_SET_USED(data); 14289 if (!strcmp(res->cmd_all, "all")) { 14290 all = 1; 14291 index = 0; 14292 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 14293 fprintf(stderr, "index should be 0-%u\n", 14294 RAW_ENCAP_CONFS_MAX_NUM - 1); 14295 return; 14296 } 14297 do { 14298 if (!strcmp(res->cmd_what, "raw_encap")) { 14299 raw_data = (uint8_t *)&raw_encap_confs[index].data; 14300 raw_size = raw_encap_confs[index].size; 14301 snprintf(title, 16, "\nindex: %u", index); 14302 rte_hexdump(stdout, title, raw_data, raw_size); 14303 } else { 14304 raw_data = (uint8_t *)&raw_decap_confs[index].data; 14305 raw_size = raw_decap_confs[index].size; 14306 snprintf(title, 16, "\nindex: %u", index); 14307 rte_hexdump(stdout, title, raw_data, raw_size); 14308 } 14309 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 14310 } 14311 14312 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 14313 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14314 cmd_show, "show"); 14315 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 14316 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14317 cmd_what, "raw_encap#raw_decap"); 14318 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 14319 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 14320 cmd_index, RTE_UINT16); 14321 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 14322 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14323 cmd_all, "all"); 14324 cmdline_parse_inst_t cmd_show_set_raw = { 14325 .f = cmd_show_set_raw_parsed, 14326 .data = NULL, 14327 .help_str = "show <raw_encap|raw_decap> <index>", 14328 .tokens = { 14329 (void *)&cmd_show_set_raw_cmd_show, 14330 (void *)&cmd_show_set_raw_cmd_what, 14331 (void *)&cmd_show_set_raw_cmd_index, 14332 NULL, 14333 }, 14334 }; 14335 cmdline_parse_inst_t cmd_show_set_raw_all = { 14336 .f = cmd_show_set_raw_parsed, 14337 .data = NULL, 14338 .help_str = "show <raw_encap|raw_decap> all", 14339 .tokens = { 14340 (void *)&cmd_show_set_raw_cmd_show, 14341 (void *)&cmd_show_set_raw_cmd_what, 14342 (void *)&cmd_show_set_raw_cmd_all, 14343 NULL, 14344 }, 14345 }; 14346