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_INIT, 110 FLEX_ITEM_CREATE, 111 FLEX_ITEM_DESTROY, 112 113 /* Pattern template arguments. */ 114 PATTERN_TEMPLATE_CREATE, 115 PATTERN_TEMPLATE_DESTROY, 116 PATTERN_TEMPLATE_CREATE_ID, 117 PATTERN_TEMPLATE_DESTROY_ID, 118 PATTERN_TEMPLATE_RELAXED_MATCHING, 119 PATTERN_TEMPLATE_INGRESS, 120 PATTERN_TEMPLATE_EGRESS, 121 PATTERN_TEMPLATE_TRANSFER, 122 PATTERN_TEMPLATE_SPEC, 123 124 /* Actions template arguments. */ 125 ACTIONS_TEMPLATE_CREATE, 126 ACTIONS_TEMPLATE_DESTROY, 127 ACTIONS_TEMPLATE_CREATE_ID, 128 ACTIONS_TEMPLATE_DESTROY_ID, 129 ACTIONS_TEMPLATE_INGRESS, 130 ACTIONS_TEMPLATE_EGRESS, 131 ACTIONS_TEMPLATE_TRANSFER, 132 ACTIONS_TEMPLATE_SPEC, 133 ACTIONS_TEMPLATE_MASK, 134 135 /* Queue arguments. */ 136 QUEUE_CREATE, 137 QUEUE_DESTROY, 138 QUEUE_FLOW_UPDATE_RESIZED, 139 QUEUE_UPDATE, 140 QUEUE_AGED, 141 QUEUE_INDIRECT_ACTION, 142 143 /* Queue create arguments. */ 144 QUEUE_CREATE_POSTPONE, 145 QUEUE_TEMPLATE_TABLE, 146 QUEUE_PATTERN_TEMPLATE, 147 QUEUE_ACTIONS_TEMPLATE, 148 QUEUE_RULE_ID, 149 150 /* Queue destroy arguments. */ 151 QUEUE_DESTROY_ID, 152 QUEUE_DESTROY_POSTPONE, 153 154 /* Queue update arguments. */ 155 QUEUE_UPDATE_ID, 156 157 /* Queue indirect action arguments */ 158 QUEUE_INDIRECT_ACTION_CREATE, 159 QUEUE_INDIRECT_ACTION_LIST_CREATE, 160 QUEUE_INDIRECT_ACTION_UPDATE, 161 QUEUE_INDIRECT_ACTION_DESTROY, 162 QUEUE_INDIRECT_ACTION_QUERY, 163 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 164 165 /* Queue indirect action create arguments */ 166 QUEUE_INDIRECT_ACTION_CREATE_ID, 167 QUEUE_INDIRECT_ACTION_INGRESS, 168 QUEUE_INDIRECT_ACTION_EGRESS, 169 QUEUE_INDIRECT_ACTION_TRANSFER, 170 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 171 QUEUE_INDIRECT_ACTION_SPEC, 172 QUEUE_INDIRECT_ACTION_LIST, 173 174 /* Queue indirect action update arguments */ 175 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 176 177 /* Queue indirect action destroy arguments */ 178 QUEUE_INDIRECT_ACTION_DESTROY_ID, 179 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 180 181 /* Queue indirect action query arguments */ 182 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 183 184 /* Queue indirect action query_update arguments */ 185 QUEUE_INDIRECT_ACTION_QU_MODE, 186 187 /* Push arguments. */ 188 PUSH_QUEUE, 189 190 /* Pull arguments. */ 191 PULL_QUEUE, 192 193 /* Table arguments. */ 194 TABLE_CREATE, 195 TABLE_DESTROY, 196 TABLE_RESIZE, 197 TABLE_RESIZE_COMPLETE, 198 TABLE_CREATE_ID, 199 TABLE_DESTROY_ID, 200 TABLE_RESIZE_ID, 201 TABLE_RESIZE_RULES_NUMBER, 202 TABLE_INSERTION_TYPE, 203 TABLE_INSERTION_TYPE_NAME, 204 TABLE_HASH_FUNC, 205 TABLE_HASH_FUNC_NAME, 206 TABLE_GROUP, 207 TABLE_PRIORITY, 208 TABLE_INGRESS, 209 TABLE_EGRESS, 210 TABLE_TRANSFER, 211 TABLE_TRANSFER_WIRE_ORIG, 212 TABLE_TRANSFER_VPORT_ORIG, 213 TABLE_RESIZABLE, 214 TABLE_RULES_NUMBER, 215 TABLE_PATTERN_TEMPLATE, 216 TABLE_ACTIONS_TEMPLATE, 217 218 /* Group arguments */ 219 GROUP_ID, 220 GROUP_INGRESS, 221 GROUP_EGRESS, 222 GROUP_TRANSFER, 223 GROUP_SET_MISS_ACTIONS, 224 225 /* Hash calculation arguments. */ 226 HASH_CALC_TABLE, 227 HASH_CALC_PATTERN_INDEX, 228 HASH_CALC_PATTERN, 229 HASH_CALC_ENCAP, 230 HASH_CALC_DEST, 231 ENCAP_HASH_FIELD_SRC_PORT, 232 ENCAP_HASH_FIELD_GRE_FLOW_ID, 233 234 /* Tunnel arguments. */ 235 TUNNEL_CREATE, 236 TUNNEL_CREATE_TYPE, 237 TUNNEL_LIST, 238 TUNNEL_DESTROY, 239 TUNNEL_DESTROY_ID, 240 241 /* Destroy arguments. */ 242 DESTROY_RULE, 243 DESTROY_IS_USER_ID, 244 245 /* Query arguments. */ 246 QUERY_ACTION, 247 QUERY_IS_USER_ID, 248 249 /* List arguments. */ 250 LIST_GROUP, 251 252 /* Destroy aged flow arguments. */ 253 AGED_DESTROY, 254 255 /* Validate/create arguments. */ 256 VC_GROUP, 257 VC_PRIORITY, 258 VC_INGRESS, 259 VC_EGRESS, 260 VC_TRANSFER, 261 VC_TUNNEL_SET, 262 VC_TUNNEL_MATCH, 263 VC_USER_ID, 264 VC_IS_USER_ID, 265 266 /* Dump arguments */ 267 DUMP_ALL, 268 DUMP_ONE, 269 DUMP_IS_USER_ID, 270 271 /* Configure arguments */ 272 CONFIG_QUEUES_NUMBER, 273 CONFIG_QUEUES_SIZE, 274 CONFIG_COUNTERS_NUMBER, 275 CONFIG_AGING_OBJECTS_NUMBER, 276 CONFIG_METERS_NUMBER, 277 CONFIG_CONN_TRACK_NUMBER, 278 CONFIG_QUOTAS_NUMBER, 279 CONFIG_FLAGS, 280 CONFIG_HOST_PORT, 281 282 /* Indirect action arguments */ 283 INDIRECT_ACTION_CREATE, 284 INDIRECT_ACTION_LIST_CREATE, 285 INDIRECT_ACTION_FLOW_CONF_CREATE, 286 INDIRECT_ACTION_UPDATE, 287 INDIRECT_ACTION_DESTROY, 288 INDIRECT_ACTION_QUERY, 289 INDIRECT_ACTION_QUERY_UPDATE, 290 291 /* Indirect action create arguments */ 292 INDIRECT_ACTION_CREATE_ID, 293 INDIRECT_ACTION_INGRESS, 294 INDIRECT_ACTION_EGRESS, 295 INDIRECT_ACTION_TRANSFER, 296 INDIRECT_ACTION_SPEC, 297 INDIRECT_ACTION_LIST, 298 INDIRECT_ACTION_FLOW_CONF, 299 300 /* Indirect action destroy arguments */ 301 INDIRECT_ACTION_DESTROY_ID, 302 303 /* Indirect action query-and-update arguments */ 304 INDIRECT_ACTION_QU_MODE, 305 INDIRECT_ACTION_QU_MODE_NAME, 306 307 /* Validate/create pattern. */ 308 ITEM_PATTERN, 309 ITEM_PARAM_IS, 310 ITEM_PARAM_SPEC, 311 ITEM_PARAM_LAST, 312 ITEM_PARAM_MASK, 313 ITEM_PARAM_PREFIX, 314 ITEM_NEXT, 315 ITEM_END, 316 ITEM_VOID, 317 ITEM_INVERT, 318 ITEM_ANY, 319 ITEM_ANY_NUM, 320 ITEM_PORT_ID, 321 ITEM_PORT_ID_ID, 322 ITEM_MARK, 323 ITEM_MARK_ID, 324 ITEM_RAW, 325 ITEM_RAW_RELATIVE, 326 ITEM_RAW_SEARCH, 327 ITEM_RAW_OFFSET, 328 ITEM_RAW_LIMIT, 329 ITEM_RAW_PATTERN, 330 ITEM_RAW_PATTERN_HEX, 331 ITEM_ETH, 332 ITEM_ETH_DST, 333 ITEM_ETH_SRC, 334 ITEM_ETH_TYPE, 335 ITEM_ETH_HAS_VLAN, 336 ITEM_VLAN, 337 ITEM_VLAN_TCI, 338 ITEM_VLAN_PCP, 339 ITEM_VLAN_DEI, 340 ITEM_VLAN_VID, 341 ITEM_VLAN_INNER_TYPE, 342 ITEM_VLAN_HAS_MORE_VLAN, 343 ITEM_IPV4, 344 ITEM_IPV4_VER_IHL, 345 ITEM_IPV4_TOS, 346 ITEM_IPV4_LENGTH, 347 ITEM_IPV4_ID, 348 ITEM_IPV4_FRAGMENT_OFFSET, 349 ITEM_IPV4_TTL, 350 ITEM_IPV4_PROTO, 351 ITEM_IPV4_SRC, 352 ITEM_IPV4_DST, 353 ITEM_IPV6, 354 ITEM_IPV6_TC, 355 ITEM_IPV6_FLOW, 356 ITEM_IPV6_LEN, 357 ITEM_IPV6_PROTO, 358 ITEM_IPV6_HOP, 359 ITEM_IPV6_SRC, 360 ITEM_IPV6_DST, 361 ITEM_IPV6_HAS_FRAG_EXT, 362 ITEM_IPV6_ROUTING_EXT, 363 ITEM_IPV6_ROUTING_EXT_TYPE, 364 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 365 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 366 ITEM_ICMP, 367 ITEM_ICMP_TYPE, 368 ITEM_ICMP_CODE, 369 ITEM_ICMP_IDENT, 370 ITEM_ICMP_SEQ, 371 ITEM_UDP, 372 ITEM_UDP_SRC, 373 ITEM_UDP_DST, 374 ITEM_TCP, 375 ITEM_TCP_SRC, 376 ITEM_TCP_DST, 377 ITEM_TCP_FLAGS, 378 ITEM_SCTP, 379 ITEM_SCTP_SRC, 380 ITEM_SCTP_DST, 381 ITEM_SCTP_TAG, 382 ITEM_SCTP_CKSUM, 383 ITEM_VXLAN, 384 ITEM_VXLAN_VNI, 385 ITEM_VXLAN_FLAG_G, 386 ITEM_VXLAN_FLAG_VER, 387 ITEM_VXLAN_FLAG_I, 388 ITEM_VXLAN_FLAG_P, 389 ITEM_VXLAN_FLAG_B, 390 ITEM_VXLAN_FLAG_O, 391 ITEM_VXLAN_FLAG_D, 392 ITEM_VXLAN_FLAG_A, 393 ITEM_VXLAN_GBP_ID, 394 /* Used for "struct rte_vxlan_hdr", GPE Next protocol */ 395 ITEM_VXLAN_GPE_PROTO, 396 ITEM_VXLAN_FIRST_RSVD, 397 ITEM_VXLAN_SECND_RSVD, 398 ITEM_VXLAN_THIRD_RSVD, 399 ITEM_VXLAN_LAST_RSVD, 400 ITEM_E_TAG, 401 ITEM_E_TAG_GRP_ECID_B, 402 ITEM_NVGRE, 403 ITEM_NVGRE_TNI, 404 ITEM_MPLS, 405 ITEM_MPLS_LABEL, 406 ITEM_MPLS_TC, 407 ITEM_MPLS_S, 408 ITEM_MPLS_TTL, 409 ITEM_GRE, 410 ITEM_GRE_PROTO, 411 ITEM_GRE_C_RSVD0_VER, 412 ITEM_GRE_C_BIT, 413 ITEM_GRE_K_BIT, 414 ITEM_GRE_S_BIT, 415 ITEM_FUZZY, 416 ITEM_FUZZY_THRESH, 417 ITEM_GTP, 418 ITEM_GTP_FLAGS, 419 ITEM_GTP_MSG_TYPE, 420 ITEM_GTP_TEID, 421 ITEM_GTPC, 422 ITEM_GTPU, 423 ITEM_GENEVE, 424 ITEM_GENEVE_VNI, 425 ITEM_GENEVE_PROTO, 426 ITEM_GENEVE_OPTLEN, 427 ITEM_VXLAN_GPE, 428 ITEM_VXLAN_GPE_VNI, 429 /* Used for "struct rte_vxlan_gpe_hdr", deprecated, prefer ITEM_VXLAN_GPE_PROTO */ 430 ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR, 431 ITEM_VXLAN_GPE_FLAGS, 432 ITEM_VXLAN_GPE_RSVD0, 433 ITEM_VXLAN_GPE_RSVD1, 434 ITEM_ARP_ETH_IPV4, 435 ITEM_ARP_ETH_IPV4_SHA, 436 ITEM_ARP_ETH_IPV4_SPA, 437 ITEM_ARP_ETH_IPV4_THA, 438 ITEM_ARP_ETH_IPV4_TPA, 439 ITEM_IPV6_EXT, 440 ITEM_IPV6_EXT_NEXT_HDR, 441 ITEM_IPV6_FRAG_EXT, 442 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 443 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 444 ITEM_IPV6_FRAG_EXT_ID, 445 ITEM_ICMP6, 446 ITEM_ICMP6_TYPE, 447 ITEM_ICMP6_CODE, 448 ITEM_ICMP6_ECHO_REQUEST, 449 ITEM_ICMP6_ECHO_REQUEST_ID, 450 ITEM_ICMP6_ECHO_REQUEST_SEQ, 451 ITEM_ICMP6_ECHO_REPLY, 452 ITEM_ICMP6_ECHO_REPLY_ID, 453 ITEM_ICMP6_ECHO_REPLY_SEQ, 454 ITEM_ICMP6_ND_NS, 455 ITEM_ICMP6_ND_NS_TARGET_ADDR, 456 ITEM_ICMP6_ND_NA, 457 ITEM_ICMP6_ND_NA_TARGET_ADDR, 458 ITEM_ICMP6_ND_OPT, 459 ITEM_ICMP6_ND_OPT_TYPE, 460 ITEM_ICMP6_ND_OPT_SLA_ETH, 461 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 462 ITEM_ICMP6_ND_OPT_TLA_ETH, 463 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 464 ITEM_META, 465 ITEM_META_DATA, 466 ITEM_RANDOM, 467 ITEM_RANDOM_VALUE, 468 ITEM_GRE_KEY, 469 ITEM_GRE_KEY_VALUE, 470 ITEM_GRE_OPTION, 471 ITEM_GRE_OPTION_CHECKSUM, 472 ITEM_GRE_OPTION_KEY, 473 ITEM_GRE_OPTION_SEQUENCE, 474 ITEM_GTP_PSC, 475 ITEM_GTP_PSC_QFI, 476 ITEM_GTP_PSC_PDU_T, 477 ITEM_PPPOES, 478 ITEM_PPPOED, 479 ITEM_PPPOE_SEID, 480 ITEM_PPPOE_PROTO_ID, 481 ITEM_HIGIG2, 482 ITEM_HIGIG2_CLASSIFICATION, 483 ITEM_HIGIG2_VID, 484 ITEM_TAG, 485 ITEM_TAG_DATA, 486 ITEM_TAG_INDEX, 487 ITEM_L2TPV3OIP, 488 ITEM_L2TPV3OIP_SESSION_ID, 489 ITEM_ESP, 490 ITEM_ESP_SPI, 491 ITEM_AH, 492 ITEM_AH_SPI, 493 ITEM_PFCP, 494 ITEM_PFCP_S_FIELD, 495 ITEM_PFCP_SEID, 496 ITEM_ECPRI, 497 ITEM_ECPRI_COMMON, 498 ITEM_ECPRI_COMMON_TYPE, 499 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 500 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 501 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 502 ITEM_ECPRI_MSG_IQ_DATA_PCID, 503 ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 504 ITEM_ECPRI_MSG_DLY_MSR_MSRID, 505 ITEM_GENEVE_OPT, 506 ITEM_GENEVE_OPT_CLASS, 507 ITEM_GENEVE_OPT_TYPE, 508 ITEM_GENEVE_OPT_LENGTH, 509 ITEM_GENEVE_OPT_DATA, 510 ITEM_INTEGRITY, 511 ITEM_INTEGRITY_LEVEL, 512 ITEM_INTEGRITY_VALUE, 513 ITEM_CONNTRACK, 514 ITEM_POL_PORT, 515 ITEM_POL_METER, 516 ITEM_POL_POLICY, 517 ITEM_PORT_REPRESENTOR, 518 ITEM_PORT_REPRESENTOR_PORT_ID, 519 ITEM_REPRESENTED_PORT, 520 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 521 ITEM_FLEX, 522 ITEM_FLEX_ITEM_HANDLE, 523 ITEM_FLEX_PATTERN_HANDLE, 524 ITEM_L2TPV2, 525 ITEM_L2TPV2_TYPE, 526 ITEM_L2TPV2_TYPE_DATA, 527 ITEM_L2TPV2_TYPE_DATA_L, 528 ITEM_L2TPV2_TYPE_DATA_S, 529 ITEM_L2TPV2_TYPE_DATA_O, 530 ITEM_L2TPV2_TYPE_DATA_L_S, 531 ITEM_L2TPV2_TYPE_CTRL, 532 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 533 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 534 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 535 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 536 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 537 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 538 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 539 ITEM_L2TPV2_MSG_DATA_S_NS, 540 ITEM_L2TPV2_MSG_DATA_S_NR, 541 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 542 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 543 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 544 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 545 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 546 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 547 ITEM_L2TPV2_MSG_DATA_L_S_NS, 548 ITEM_L2TPV2_MSG_DATA_L_S_NR, 549 ITEM_L2TPV2_MSG_CTRL_LENGTH, 550 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 551 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 552 ITEM_L2TPV2_MSG_CTRL_NS, 553 ITEM_L2TPV2_MSG_CTRL_NR, 554 ITEM_PPP, 555 ITEM_PPP_ADDR, 556 ITEM_PPP_CTRL, 557 ITEM_PPP_PROTO_ID, 558 ITEM_METER, 559 ITEM_METER_COLOR, 560 ITEM_METER_COLOR_NAME, 561 ITEM_QUOTA, 562 ITEM_QUOTA_STATE, 563 ITEM_QUOTA_STATE_NAME, 564 ITEM_AGGR_AFFINITY, 565 ITEM_AGGR_AFFINITY_VALUE, 566 ITEM_TX_QUEUE, 567 ITEM_TX_QUEUE_VALUE, 568 ITEM_IB_BTH, 569 ITEM_IB_BTH_OPCODE, 570 ITEM_IB_BTH_PKEY, 571 ITEM_IB_BTH_DST_QPN, 572 ITEM_IB_BTH_PSN, 573 ITEM_IPV6_PUSH_REMOVE_EXT, 574 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 575 ITEM_PTYPE, 576 ITEM_PTYPE_VALUE, 577 ITEM_NSH, 578 ITEM_COMPARE, 579 ITEM_COMPARE_OP, 580 ITEM_COMPARE_OP_VALUE, 581 ITEM_COMPARE_FIELD_A_TYPE, 582 ITEM_COMPARE_FIELD_A_TYPE_VALUE, 583 ITEM_COMPARE_FIELD_A_LEVEL, 584 ITEM_COMPARE_FIELD_A_LEVEL_VALUE, 585 ITEM_COMPARE_FIELD_A_TAG_INDEX, 586 ITEM_COMPARE_FIELD_A_TYPE_ID, 587 ITEM_COMPARE_FIELD_A_CLASS_ID, 588 ITEM_COMPARE_FIELD_A_OFFSET, 589 ITEM_COMPARE_FIELD_B_TYPE, 590 ITEM_COMPARE_FIELD_B_TYPE_VALUE, 591 ITEM_COMPARE_FIELD_B_LEVEL, 592 ITEM_COMPARE_FIELD_B_LEVEL_VALUE, 593 ITEM_COMPARE_FIELD_B_TAG_INDEX, 594 ITEM_COMPARE_FIELD_B_TYPE_ID, 595 ITEM_COMPARE_FIELD_B_CLASS_ID, 596 ITEM_COMPARE_FIELD_B_OFFSET, 597 ITEM_COMPARE_FIELD_B_VALUE, 598 ITEM_COMPARE_FIELD_B_POINTER, 599 ITEM_COMPARE_FIELD_WIDTH, 600 601 /* Validate/create actions. */ 602 ACTIONS, 603 ACTION_NEXT, 604 ACTION_END, 605 ACTION_VOID, 606 ACTION_PASSTHRU, 607 ACTION_SKIP_CMAN, 608 ACTION_JUMP, 609 ACTION_JUMP_GROUP, 610 ACTION_MARK, 611 ACTION_MARK_ID, 612 ACTION_FLAG, 613 ACTION_QUEUE, 614 ACTION_QUEUE_INDEX, 615 ACTION_DROP, 616 ACTION_COUNT, 617 ACTION_COUNT_ID, 618 ACTION_RSS, 619 ACTION_RSS_FUNC, 620 ACTION_RSS_LEVEL, 621 ACTION_RSS_FUNC_DEFAULT, 622 ACTION_RSS_FUNC_TOEPLITZ, 623 ACTION_RSS_FUNC_SIMPLE_XOR, 624 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, 625 ACTION_RSS_TYPES, 626 ACTION_RSS_TYPE, 627 ACTION_RSS_KEY, 628 ACTION_RSS_KEY_LEN, 629 ACTION_RSS_QUEUES, 630 ACTION_RSS_QUEUE, 631 ACTION_PF, 632 ACTION_VF, 633 ACTION_VF_ORIGINAL, 634 ACTION_VF_ID, 635 ACTION_PORT_ID, 636 ACTION_PORT_ID_ORIGINAL, 637 ACTION_PORT_ID_ID, 638 ACTION_METER, 639 ACTION_METER_COLOR, 640 ACTION_METER_COLOR_TYPE, 641 ACTION_METER_COLOR_GREEN, 642 ACTION_METER_COLOR_YELLOW, 643 ACTION_METER_COLOR_RED, 644 ACTION_METER_ID, 645 ACTION_METER_MARK, 646 ACTION_METER_PROFILE, 647 ACTION_METER_PROFILE_ID2PTR, 648 ACTION_METER_POLICY, 649 ACTION_METER_POLICY_ID2PTR, 650 ACTION_METER_COLOR_MODE, 651 ACTION_METER_STATE, 652 ACTION_OF_DEC_NW_TTL, 653 ACTION_OF_POP_VLAN, 654 ACTION_OF_PUSH_VLAN, 655 ACTION_OF_PUSH_VLAN_ETHERTYPE, 656 ACTION_OF_SET_VLAN_VID, 657 ACTION_OF_SET_VLAN_VID_VLAN_VID, 658 ACTION_OF_SET_VLAN_PCP, 659 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 660 ACTION_OF_POP_MPLS, 661 ACTION_OF_POP_MPLS_ETHERTYPE, 662 ACTION_OF_PUSH_MPLS, 663 ACTION_OF_PUSH_MPLS_ETHERTYPE, 664 ACTION_VXLAN_ENCAP, 665 ACTION_VXLAN_DECAP, 666 ACTION_NVGRE_ENCAP, 667 ACTION_NVGRE_DECAP, 668 ACTION_L2_ENCAP, 669 ACTION_L2_DECAP, 670 ACTION_MPLSOGRE_ENCAP, 671 ACTION_MPLSOGRE_DECAP, 672 ACTION_MPLSOUDP_ENCAP, 673 ACTION_MPLSOUDP_DECAP, 674 ACTION_SET_IPV4_SRC, 675 ACTION_SET_IPV4_SRC_IPV4_SRC, 676 ACTION_SET_IPV4_DST, 677 ACTION_SET_IPV4_DST_IPV4_DST, 678 ACTION_SET_IPV6_SRC, 679 ACTION_SET_IPV6_SRC_IPV6_SRC, 680 ACTION_SET_IPV6_DST, 681 ACTION_SET_IPV6_DST_IPV6_DST, 682 ACTION_SET_TP_SRC, 683 ACTION_SET_TP_SRC_TP_SRC, 684 ACTION_SET_TP_DST, 685 ACTION_SET_TP_DST_TP_DST, 686 ACTION_MAC_SWAP, 687 ACTION_DEC_TTL, 688 ACTION_SET_TTL, 689 ACTION_SET_TTL_TTL, 690 ACTION_SET_MAC_SRC, 691 ACTION_SET_MAC_SRC_MAC_SRC, 692 ACTION_SET_MAC_DST, 693 ACTION_SET_MAC_DST_MAC_DST, 694 ACTION_INC_TCP_SEQ, 695 ACTION_INC_TCP_SEQ_VALUE, 696 ACTION_DEC_TCP_SEQ, 697 ACTION_DEC_TCP_SEQ_VALUE, 698 ACTION_INC_TCP_ACK, 699 ACTION_INC_TCP_ACK_VALUE, 700 ACTION_DEC_TCP_ACK, 701 ACTION_DEC_TCP_ACK_VALUE, 702 ACTION_RAW_ENCAP, 703 ACTION_RAW_DECAP, 704 ACTION_RAW_ENCAP_SIZE, 705 ACTION_RAW_ENCAP_INDEX, 706 ACTION_RAW_ENCAP_INDEX_VALUE, 707 ACTION_RAW_DECAP_INDEX, 708 ACTION_RAW_DECAP_INDEX_VALUE, 709 ACTION_SET_TAG, 710 ACTION_SET_TAG_DATA, 711 ACTION_SET_TAG_INDEX, 712 ACTION_SET_TAG_MASK, 713 ACTION_SET_META, 714 ACTION_SET_META_DATA, 715 ACTION_SET_META_MASK, 716 ACTION_SET_IPV4_DSCP, 717 ACTION_SET_IPV4_DSCP_VALUE, 718 ACTION_SET_IPV6_DSCP, 719 ACTION_SET_IPV6_DSCP_VALUE, 720 ACTION_AGE, 721 ACTION_AGE_TIMEOUT, 722 ACTION_AGE_UPDATE, 723 ACTION_AGE_UPDATE_TIMEOUT, 724 ACTION_AGE_UPDATE_TOUCH, 725 ACTION_SAMPLE, 726 ACTION_SAMPLE_RATIO, 727 ACTION_SAMPLE_INDEX, 728 ACTION_SAMPLE_INDEX_VALUE, 729 ACTION_INDIRECT, 730 ACTION_INDIRECT_LIST, 731 ACTION_INDIRECT_LIST_HANDLE, 732 ACTION_INDIRECT_LIST_CONF, 733 INDIRECT_LIST_ACTION_ID2PTR_HANDLE, 734 INDIRECT_LIST_ACTION_ID2PTR_CONF, 735 ACTION_SHARED_INDIRECT, 736 INDIRECT_ACTION_PORT, 737 INDIRECT_ACTION_ID2PTR, 738 ACTION_MODIFY_FIELD, 739 ACTION_MODIFY_FIELD_OP, 740 ACTION_MODIFY_FIELD_OP_VALUE, 741 ACTION_MODIFY_FIELD_DST_TYPE, 742 ACTION_MODIFY_FIELD_DST_TYPE_VALUE, 743 ACTION_MODIFY_FIELD_DST_LEVEL, 744 ACTION_MODIFY_FIELD_DST_LEVEL_VALUE, 745 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 746 ACTION_MODIFY_FIELD_DST_TYPE_ID, 747 ACTION_MODIFY_FIELD_DST_CLASS_ID, 748 ACTION_MODIFY_FIELD_DST_OFFSET, 749 ACTION_MODIFY_FIELD_SRC_TYPE, 750 ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, 751 ACTION_MODIFY_FIELD_SRC_LEVEL, 752 ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE, 753 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 754 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 755 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 756 ACTION_MODIFY_FIELD_SRC_OFFSET, 757 ACTION_MODIFY_FIELD_SRC_VALUE, 758 ACTION_MODIFY_FIELD_SRC_POINTER, 759 ACTION_MODIFY_FIELD_WIDTH, 760 ACTION_CONNTRACK, 761 ACTION_CONNTRACK_UPDATE, 762 ACTION_CONNTRACK_UPDATE_DIR, 763 ACTION_CONNTRACK_UPDATE_CTX, 764 ACTION_POL_G, 765 ACTION_POL_Y, 766 ACTION_POL_R, 767 ACTION_PORT_REPRESENTOR, 768 ACTION_PORT_REPRESENTOR_PORT_ID, 769 ACTION_REPRESENTED_PORT, 770 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 771 ACTION_SEND_TO_KERNEL, 772 ACTION_QUOTA_CREATE, 773 ACTION_QUOTA_CREATE_LIMIT, 774 ACTION_QUOTA_CREATE_MODE, 775 ACTION_QUOTA_CREATE_MODE_NAME, 776 ACTION_QUOTA_QU, 777 ACTION_QUOTA_QU_LIMIT, 778 ACTION_QUOTA_QU_UPDATE_OP, 779 ACTION_QUOTA_QU_UPDATE_OP_NAME, 780 ACTION_IPV6_EXT_REMOVE, 781 ACTION_IPV6_EXT_REMOVE_INDEX, 782 ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, 783 ACTION_IPV6_EXT_PUSH, 784 ACTION_IPV6_EXT_PUSH_INDEX, 785 ACTION_IPV6_EXT_PUSH_INDEX_VALUE, 786 ACTION_NAT64, 787 ACTION_NAT64_MODE, 788 }; 789 790 /** Maximum size for pattern in struct rte_flow_item_raw. */ 791 #define ITEM_RAW_PATTERN_SIZE 512 792 793 /** Maximum size for GENEVE option data pattern in bytes. */ 794 #define ITEM_GENEVE_OPT_DATA_SIZE 124 795 796 /** Storage size for struct rte_flow_item_raw including pattern. */ 797 #define ITEM_RAW_SIZE \ 798 (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) 799 800 static const char *const compare_ops[] = { 801 "eq", "ne", "lt", "le", "gt", "ge", NULL 802 }; 803 804 /** Maximum size for external pattern in struct rte_flow_field_data. */ 805 #define FLOW_FIELD_PATTERN_SIZE 32 806 807 /** Storage size for struct rte_flow_action_modify_field including pattern. */ 808 #define ACTION_MODIFY_SIZE \ 809 (sizeof(struct rte_flow_action_modify_field) + \ 810 FLOW_FIELD_PATTERN_SIZE) 811 812 /** Maximum number of queue indices in struct rte_flow_action_rss. */ 813 #define ACTION_RSS_QUEUE_NUM 128 814 815 /** Storage for struct rte_flow_action_rss including external data. */ 816 struct action_rss_data { 817 struct rte_flow_action_rss conf; 818 uint8_t key[RSS_HASH_KEY_LENGTH]; 819 uint16_t queue[ACTION_RSS_QUEUE_NUM]; 820 }; 821 822 /** Maximum data size in struct rte_flow_action_raw_encap. */ 823 #define ACTION_RAW_ENCAP_MAX_DATA 512 824 #define RAW_ENCAP_CONFS_MAX_NUM 8 825 826 /** Storage for struct rte_flow_action_raw_encap. */ 827 struct raw_encap_conf { 828 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 829 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 830 size_t size; 831 }; 832 833 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 834 835 /** Storage for struct rte_flow_action_raw_encap including external data. */ 836 struct action_raw_encap_data { 837 struct rte_flow_action_raw_encap conf; 838 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 839 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 840 uint16_t idx; 841 }; 842 843 /** Storage for struct rte_flow_action_raw_decap. */ 844 struct raw_decap_conf { 845 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 846 size_t size; 847 }; 848 849 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 850 851 /** Storage for struct rte_flow_action_raw_decap including external data. */ 852 struct action_raw_decap_data { 853 struct rte_flow_action_raw_decap conf; 854 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 855 uint16_t idx; 856 }; 857 858 /** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ 859 #define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 860 #define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 861 862 /** Storage for struct rte_flow_action_ipv6_ext_push. */ 863 struct ipv6_ext_push_conf { 864 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 865 size_t size; 866 uint8_t type; 867 }; 868 869 struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 870 871 /** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ 872 struct action_ipv6_ext_push_data { 873 struct rte_flow_action_ipv6_ext_push conf; 874 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 875 uint8_t type; 876 uint16_t idx; 877 }; 878 879 /** Storage for struct rte_flow_action_ipv6_ext_remove. */ 880 struct ipv6_ext_remove_conf { 881 struct rte_flow_action_ipv6_ext_remove conf; 882 uint8_t type; 883 }; 884 885 struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 886 887 /** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ 888 struct action_ipv6_ext_remove_data { 889 struct rte_flow_action_ipv6_ext_remove conf; 890 uint8_t type; 891 uint16_t idx; 892 }; 893 894 struct vxlan_encap_conf vxlan_encap_conf = { 895 .select_ipv4 = 1, 896 .select_vlan = 0, 897 .select_tos_ttl = 0, 898 .vni = "\x00\x00\x00", 899 .udp_src = 0, 900 .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), 901 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 902 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 903 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 904 "\x00\x00\x00\x00\x00\x00\x00\x01", 905 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 906 "\x00\x00\x00\x00\x00\x00\x11\x11", 907 .vlan_tci = 0, 908 .ip_tos = 0, 909 .ip_ttl = 255, 910 .eth_src = "\x00\x00\x00\x00\x00\x00", 911 .eth_dst = "\xff\xff\xff\xff\xff\xff", 912 }; 913 914 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */ 915 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6 916 917 /** Storage for struct rte_flow_action_vxlan_encap including external data. */ 918 struct action_vxlan_encap_data { 919 struct rte_flow_action_vxlan_encap conf; 920 struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; 921 struct rte_flow_item_eth item_eth; 922 struct rte_flow_item_vlan item_vlan; 923 union { 924 struct rte_flow_item_ipv4 item_ipv4; 925 struct rte_flow_item_ipv6 item_ipv6; 926 }; 927 struct rte_flow_item_udp item_udp; 928 struct rte_flow_item_vxlan item_vxlan; 929 }; 930 931 struct nvgre_encap_conf nvgre_encap_conf = { 932 .select_ipv4 = 1, 933 .select_vlan = 0, 934 .tni = "\x00\x00\x00", 935 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 936 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 937 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 938 "\x00\x00\x00\x00\x00\x00\x00\x01", 939 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 940 "\x00\x00\x00\x00\x00\x00\x11\x11", 941 .vlan_tci = 0, 942 .eth_src = "\x00\x00\x00\x00\x00\x00", 943 .eth_dst = "\xff\xff\xff\xff\xff\xff", 944 }; 945 946 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */ 947 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 948 949 /** Storage for struct rte_flow_action_nvgre_encap including external data. */ 950 struct action_nvgre_encap_data { 951 struct rte_flow_action_nvgre_encap conf; 952 struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; 953 struct rte_flow_item_eth item_eth; 954 struct rte_flow_item_vlan item_vlan; 955 union { 956 struct rte_flow_item_ipv4 item_ipv4; 957 struct rte_flow_item_ipv6 item_ipv6; 958 }; 959 struct rte_flow_item_nvgre item_nvgre; 960 }; 961 962 struct l2_encap_conf l2_encap_conf; 963 964 struct l2_decap_conf l2_decap_conf; 965 966 struct mplsogre_encap_conf mplsogre_encap_conf; 967 968 struct mplsogre_decap_conf mplsogre_decap_conf; 969 970 struct mplsoudp_encap_conf mplsoudp_encap_conf; 971 972 struct mplsoudp_decap_conf mplsoudp_decap_conf; 973 974 struct rte_flow_action_conntrack conntrack_context; 975 976 #define ACTION_SAMPLE_ACTIONS_NUM 10 977 #define RAW_SAMPLE_CONFS_MAX_NUM 8 978 /** Storage for struct rte_flow_action_sample including external data. */ 979 struct action_sample_data { 980 struct rte_flow_action_sample conf; 981 uint32_t idx; 982 }; 983 /** Storage for struct rte_flow_action_sample. */ 984 struct raw_sample_conf { 985 struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; 986 }; 987 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; 988 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; 989 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; 990 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; 991 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; 992 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 993 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 994 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 995 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; 996 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; 997 struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; 998 struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; 999 1000 static const char *const modify_field_ops[] = { 1001 "set", "add", "sub", NULL 1002 }; 1003 1004 static const char *const flow_field_ids[] = { 1005 "start", "mac_dst", "mac_src", 1006 "vlan_type", "vlan_id", "mac_type", 1007 "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", 1008 "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", 1009 "tcp_port_src", "tcp_port_dst", 1010 "tcp_seq_num", "tcp_ack_num", "tcp_flags", 1011 "udp_port_src", "udp_port_dst", 1012 "vxlan_vni", "geneve_vni", "gtp_teid", 1013 "tag", "mark", "meta", "pointer", "value", 1014 "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", 1015 "ipv6_proto", 1016 "flex_item", 1017 "hash_result", 1018 "geneve_opt_type", "geneve_opt_class", "geneve_opt_data", "mpls", 1019 "tcp_data_off", "ipv4_ihl", "ipv4_total_len", "ipv6_payload_len", 1020 "ipv4_proto", 1021 "ipv6_flow_label", "ipv6_traffic_class", 1022 "esp_spi", "esp_seq_num", "esp_proto", 1023 "random", 1024 "vxlan_last_rsvd", 1025 NULL 1026 }; 1027 1028 static const char *const meter_colors[] = { 1029 "green", "yellow", "red", "all", NULL 1030 }; 1031 1032 static const char *const table_insertion_types[] = { 1033 "pattern", "index", NULL 1034 }; 1035 1036 static const char *const table_hash_funcs[] = { 1037 "default", "linear", "crc32", "crc16", NULL 1038 }; 1039 1040 #define RAW_IPSEC_CONFS_MAX_NUM 8 1041 1042 /** Maximum number of subsequent tokens and arguments on the stack. */ 1043 #define CTX_STACK_SIZE 16 1044 1045 /** Parser context. */ 1046 struct context { 1047 /** Stack of subsequent token lists to process. */ 1048 const enum index *next[CTX_STACK_SIZE]; 1049 /** Arguments for stacked tokens. */ 1050 const void *args[CTX_STACK_SIZE]; 1051 enum index curr; /**< Current token index. */ 1052 enum index prev; /**< Index of the last token seen. */ 1053 int next_num; /**< Number of entries in next[]. */ 1054 int args_num; /**< Number of entries in args[]. */ 1055 uint32_t eol:1; /**< EOL has been detected. */ 1056 uint32_t last:1; /**< No more arguments. */ 1057 portid_t port; /**< Current port ID (for completions). */ 1058 uint32_t objdata; /**< Object-specific data. */ 1059 void *object; /**< Address of current object for relative offsets. */ 1060 void *objmask; /**< Object a full mask must be written to. */ 1061 }; 1062 1063 /** Token argument. */ 1064 struct arg { 1065 uint32_t hton:1; /**< Use network byte ordering. */ 1066 uint32_t sign:1; /**< Value is signed. */ 1067 uint32_t bounded:1; /**< Value is bounded. */ 1068 uintmax_t min; /**< Minimum value if bounded. */ 1069 uintmax_t max; /**< Maximum value if bounded. */ 1070 uint32_t offset; /**< Relative offset from ctx->object. */ 1071 uint32_t size; /**< Field size. */ 1072 const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ 1073 }; 1074 1075 /** Parser token definition. */ 1076 struct token { 1077 /** Type displayed during completion (defaults to "TOKEN"). */ 1078 const char *type; 1079 /** Help displayed during completion (defaults to token name). */ 1080 const char *help; 1081 /** Private data used by parser functions. */ 1082 const void *priv; 1083 /** 1084 * Lists of subsequent tokens to push on the stack. Each call to the 1085 * parser consumes the last entry of that stack. 1086 */ 1087 const enum index *const *next; 1088 /** Arguments stack for subsequent tokens that need them. */ 1089 const struct arg *const *args; 1090 /** 1091 * Token-processing callback, returns -1 in case of error, the 1092 * length of the matched string otherwise. If NULL, attempts to 1093 * match the token name. 1094 * 1095 * If buf is not NULL, the result should be stored in it according 1096 * to context. An error is returned if not large enough. 1097 */ 1098 int (*call)(struct context *ctx, const struct token *token, 1099 const char *str, unsigned int len, 1100 void *buf, unsigned int size); 1101 /** 1102 * Callback that provides possible values for this token, used for 1103 * completion. Returns -1 in case of error, the number of possible 1104 * values otherwise. If NULL, the token name is used. 1105 * 1106 * If buf is not NULL, entry index ent is written to buf and the 1107 * full length of the entry is returned (same behavior as 1108 * snprintf()). 1109 */ 1110 int (*comp)(struct context *ctx, const struct token *token, 1111 unsigned int ent, char *buf, unsigned int size); 1112 /** Mandatory token name, no default value. */ 1113 const char *name; 1114 }; 1115 1116 /** Static initializer for the next field. */ 1117 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } 1118 1119 /** Static initializer for a NEXT() entry. */ 1120 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } 1121 1122 /** Static initializer for the args field. */ 1123 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } 1124 1125 /** Static initializer for ARGS() to target a field. */ 1126 #define ARGS_ENTRY(s, f) \ 1127 (&(const struct arg){ \ 1128 .offset = offsetof(s, f), \ 1129 .size = sizeof(((s *)0)->f), \ 1130 }) 1131 1132 /** Static initializer for ARGS() to target a bit-field. */ 1133 #define ARGS_ENTRY_BF(s, f, b) \ 1134 (&(const struct arg){ \ 1135 .size = sizeof(s), \ 1136 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ 1137 }) 1138 1139 /** Static initializer for ARGS() to target a field with limits. */ 1140 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \ 1141 (&(const struct arg){ \ 1142 .bounded = 1, \ 1143 .min = (i), \ 1144 .max = (a), \ 1145 .offset = offsetof(s, f), \ 1146 .size = sizeof(((s *)0)->f), \ 1147 }) 1148 1149 /** Static initializer for ARGS() to target an arbitrary bit-mask. */ 1150 #define ARGS_ENTRY_MASK(s, f, m) \ 1151 (&(const struct arg){ \ 1152 .offset = offsetof(s, f), \ 1153 .size = sizeof(((s *)0)->f), \ 1154 .mask = (const void *)(m), \ 1155 }) 1156 1157 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ 1158 #define ARGS_ENTRY_MASK_HTON(s, f, m) \ 1159 (&(const struct arg){ \ 1160 .hton = 1, \ 1161 .offset = offsetof(s, f), \ 1162 .size = sizeof(((s *)0)->f), \ 1163 .mask = (const void *)(m), \ 1164 }) 1165 1166 /** Static initializer for ARGS() to target a pointer. */ 1167 #define ARGS_ENTRY_PTR(s, f) \ 1168 (&(const struct arg){ \ 1169 .size = sizeof(*((s *)0)->f), \ 1170 }) 1171 1172 /** Static initializer for ARGS() with arbitrary offset and size. */ 1173 #define ARGS_ENTRY_ARB(o, s) \ 1174 (&(const struct arg){ \ 1175 .offset = (o), \ 1176 .size = (s), \ 1177 }) 1178 1179 /** Same as ARGS_ENTRY_ARB() with bounded values. */ 1180 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ 1181 (&(const struct arg){ \ 1182 .bounded = 1, \ 1183 .min = (i), \ 1184 .max = (a), \ 1185 .offset = (o), \ 1186 .size = (s), \ 1187 }) 1188 1189 /** Same as ARGS_ENTRY() using network byte ordering. */ 1190 #define ARGS_ENTRY_HTON(s, f) \ 1191 (&(const struct arg){ \ 1192 .hton = 1, \ 1193 .offset = offsetof(s, f), \ 1194 .size = sizeof(((s *)0)->f), \ 1195 }) 1196 1197 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ 1198 #define ARG_ENTRY_HTON(s) \ 1199 (&(const struct arg){ \ 1200 .hton = 1, \ 1201 .offset = 0, \ 1202 .size = sizeof(s), \ 1203 }) 1204 1205 /** Parser output buffer layout expected by cmd_flow_parsed(). */ 1206 struct buffer { 1207 enum index command; /**< Flow command. */ 1208 portid_t port; /**< Affected port ID. */ 1209 queueid_t queue; /** Async queue ID. */ 1210 bool postpone; /** Postpone async operation */ 1211 union { 1212 struct { 1213 struct rte_flow_port_attr port_attr; 1214 uint32_t nb_queue; 1215 struct rte_flow_queue_attr queue_attr; 1216 } configure; /**< Configuration arguments. */ 1217 struct { 1218 uint32_t *template_id; 1219 uint32_t template_id_n; 1220 } templ_destroy; /**< Template destroy arguments. */ 1221 struct { 1222 uint32_t id; 1223 struct rte_flow_template_table_attr attr; 1224 uint32_t *pat_templ_id; 1225 uint32_t pat_templ_id_n; 1226 uint32_t *act_templ_id; 1227 uint32_t act_templ_id_n; 1228 } table; /**< Table arguments. */ 1229 struct { 1230 uint32_t *table_id; 1231 uint32_t table_id_n; 1232 } table_destroy; /**< Template destroy arguments. */ 1233 struct { 1234 uint32_t *action_id; 1235 uint32_t action_id_n; 1236 } ia_destroy; /**< Indirect action destroy arguments. */ 1237 struct { 1238 uint32_t action_id; 1239 enum rte_flow_query_update_mode qu_mode; 1240 } ia; /* Indirect action query arguments */ 1241 struct { 1242 uint32_t table_id; 1243 uint32_t pat_templ_id; 1244 uint32_t rule_id; 1245 uint32_t act_templ_id; 1246 struct rte_flow_attr attr; 1247 struct tunnel_ops tunnel_ops; 1248 uintptr_t user_id; 1249 struct rte_flow_item *pattern; 1250 struct rte_flow_action *actions; 1251 struct rte_flow_action *masks; 1252 uint32_t pattern_n; 1253 uint32_t actions_n; 1254 uint8_t *data; 1255 enum rte_flow_encap_hash_field field; 1256 uint8_t encap_hash; 1257 } vc; /**< Validate/create arguments. */ 1258 struct { 1259 uint64_t *rule; 1260 uint64_t rule_n; 1261 bool is_user_id; 1262 } destroy; /**< Destroy arguments. */ 1263 struct { 1264 char file[128]; 1265 bool mode; 1266 uint64_t rule; 1267 bool is_user_id; 1268 } dump; /**< Dump arguments. */ 1269 struct { 1270 uint64_t rule; 1271 struct rte_flow_action action; 1272 bool is_user_id; 1273 } query; /**< Query arguments. */ 1274 struct { 1275 uint32_t *group; 1276 uint32_t group_n; 1277 } list; /**< List arguments. */ 1278 struct { 1279 int set; 1280 } isolate; /**< Isolated mode arguments. */ 1281 struct { 1282 int destroy; 1283 } aged; /**< Aged arguments. */ 1284 struct { 1285 uint32_t policy_id; 1286 } policy;/**< Policy arguments. */ 1287 struct { 1288 uint16_t token; 1289 uintptr_t uintptr; 1290 char filename[128]; 1291 } flex; /**< Flex arguments*/ 1292 } args; /**< Command arguments. */ 1293 }; 1294 1295 /** Private data for pattern items. */ 1296 struct parse_item_priv { 1297 enum rte_flow_item_type type; /**< Item type. */ 1298 uint32_t size; /**< Size of item specification structure. */ 1299 }; 1300 1301 #define PRIV_ITEM(t, s) \ 1302 (&(const struct parse_item_priv){ \ 1303 .type = RTE_FLOW_ITEM_TYPE_ ## t, \ 1304 .size = s, \ 1305 }) 1306 1307 /** Private data for actions. */ 1308 struct parse_action_priv { 1309 enum rte_flow_action_type type; /**< Action type. */ 1310 uint32_t size; /**< Size of action configuration structure. */ 1311 }; 1312 1313 #define PRIV_ACTION(t, s) \ 1314 (&(const struct parse_action_priv){ \ 1315 .type = RTE_FLOW_ACTION_TYPE_ ## t, \ 1316 .size = s, \ 1317 }) 1318 1319 static const enum index next_flex_item[] = { 1320 FLEX_ITEM_INIT, 1321 FLEX_ITEM_CREATE, 1322 FLEX_ITEM_DESTROY, 1323 ZERO, 1324 }; 1325 1326 static const enum index next_config_attr[] = { 1327 CONFIG_QUEUES_NUMBER, 1328 CONFIG_QUEUES_SIZE, 1329 CONFIG_COUNTERS_NUMBER, 1330 CONFIG_AGING_OBJECTS_NUMBER, 1331 CONFIG_METERS_NUMBER, 1332 CONFIG_CONN_TRACK_NUMBER, 1333 CONFIG_QUOTAS_NUMBER, 1334 CONFIG_FLAGS, 1335 CONFIG_HOST_PORT, 1336 END, 1337 ZERO, 1338 }; 1339 1340 static const enum index next_pt_subcmd[] = { 1341 PATTERN_TEMPLATE_CREATE, 1342 PATTERN_TEMPLATE_DESTROY, 1343 ZERO, 1344 }; 1345 1346 static const enum index next_pt_attr[] = { 1347 PATTERN_TEMPLATE_CREATE_ID, 1348 PATTERN_TEMPLATE_RELAXED_MATCHING, 1349 PATTERN_TEMPLATE_INGRESS, 1350 PATTERN_TEMPLATE_EGRESS, 1351 PATTERN_TEMPLATE_TRANSFER, 1352 PATTERN_TEMPLATE_SPEC, 1353 ZERO, 1354 }; 1355 1356 static const enum index next_pt_destroy_attr[] = { 1357 PATTERN_TEMPLATE_DESTROY_ID, 1358 END, 1359 ZERO, 1360 }; 1361 1362 static const enum index next_at_subcmd[] = { 1363 ACTIONS_TEMPLATE_CREATE, 1364 ACTIONS_TEMPLATE_DESTROY, 1365 ZERO, 1366 }; 1367 1368 static const enum index next_at_attr[] = { 1369 ACTIONS_TEMPLATE_CREATE_ID, 1370 ACTIONS_TEMPLATE_INGRESS, 1371 ACTIONS_TEMPLATE_EGRESS, 1372 ACTIONS_TEMPLATE_TRANSFER, 1373 ACTIONS_TEMPLATE_SPEC, 1374 ZERO, 1375 }; 1376 1377 static const enum index next_at_destroy_attr[] = { 1378 ACTIONS_TEMPLATE_DESTROY_ID, 1379 END, 1380 ZERO, 1381 }; 1382 1383 static const enum index next_group_attr[] = { 1384 GROUP_INGRESS, 1385 GROUP_EGRESS, 1386 GROUP_TRANSFER, 1387 GROUP_SET_MISS_ACTIONS, 1388 ZERO, 1389 }; 1390 1391 static const enum index next_table_subcmd[] = { 1392 TABLE_CREATE, 1393 TABLE_DESTROY, 1394 TABLE_RESIZE, 1395 TABLE_RESIZE_COMPLETE, 1396 ZERO, 1397 }; 1398 1399 static const enum index next_table_attr[] = { 1400 TABLE_CREATE_ID, 1401 TABLE_GROUP, 1402 TABLE_INSERTION_TYPE, 1403 TABLE_HASH_FUNC, 1404 TABLE_PRIORITY, 1405 TABLE_INGRESS, 1406 TABLE_EGRESS, 1407 TABLE_TRANSFER, 1408 TABLE_TRANSFER_WIRE_ORIG, 1409 TABLE_TRANSFER_VPORT_ORIG, 1410 TABLE_RESIZABLE, 1411 TABLE_RULES_NUMBER, 1412 TABLE_PATTERN_TEMPLATE, 1413 TABLE_ACTIONS_TEMPLATE, 1414 END, 1415 ZERO, 1416 }; 1417 1418 static const enum index next_table_destroy_attr[] = { 1419 TABLE_DESTROY_ID, 1420 END, 1421 ZERO, 1422 }; 1423 1424 static const enum index next_queue_subcmd[] = { 1425 QUEUE_CREATE, 1426 QUEUE_DESTROY, 1427 QUEUE_FLOW_UPDATE_RESIZED, 1428 QUEUE_UPDATE, 1429 QUEUE_AGED, 1430 QUEUE_INDIRECT_ACTION, 1431 ZERO, 1432 }; 1433 1434 static const enum index next_queue_destroy_attr[] = { 1435 QUEUE_DESTROY_ID, 1436 END, 1437 ZERO, 1438 }; 1439 1440 static const enum index next_qia_subcmd[] = { 1441 QUEUE_INDIRECT_ACTION_CREATE, 1442 QUEUE_INDIRECT_ACTION_UPDATE, 1443 QUEUE_INDIRECT_ACTION_DESTROY, 1444 QUEUE_INDIRECT_ACTION_QUERY, 1445 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 1446 ZERO, 1447 }; 1448 1449 static const enum index next_qia_create_attr[] = { 1450 QUEUE_INDIRECT_ACTION_CREATE_ID, 1451 QUEUE_INDIRECT_ACTION_INGRESS, 1452 QUEUE_INDIRECT_ACTION_EGRESS, 1453 QUEUE_INDIRECT_ACTION_TRANSFER, 1454 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 1455 QUEUE_INDIRECT_ACTION_SPEC, 1456 QUEUE_INDIRECT_ACTION_LIST, 1457 ZERO, 1458 }; 1459 1460 static const enum index next_qia_update_attr[] = { 1461 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1462 QUEUE_INDIRECT_ACTION_SPEC, 1463 ZERO, 1464 }; 1465 1466 static const enum index next_qia_destroy_attr[] = { 1467 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 1468 QUEUE_INDIRECT_ACTION_DESTROY_ID, 1469 END, 1470 ZERO, 1471 }; 1472 1473 static const enum index next_qia_query_attr[] = { 1474 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 1475 END, 1476 ZERO, 1477 }; 1478 1479 static const enum index next_ia_create_attr[] = { 1480 INDIRECT_ACTION_CREATE_ID, 1481 INDIRECT_ACTION_INGRESS, 1482 INDIRECT_ACTION_EGRESS, 1483 INDIRECT_ACTION_TRANSFER, 1484 INDIRECT_ACTION_SPEC, 1485 INDIRECT_ACTION_LIST, 1486 INDIRECT_ACTION_FLOW_CONF, 1487 ZERO, 1488 }; 1489 1490 static const enum index next_ia[] = { 1491 INDIRECT_ACTION_ID2PTR, 1492 ACTION_NEXT, 1493 ZERO 1494 }; 1495 1496 static const enum index next_ial[] = { 1497 ACTION_INDIRECT_LIST_HANDLE, 1498 ACTION_INDIRECT_LIST_CONF, 1499 ACTION_NEXT, 1500 ZERO 1501 }; 1502 1503 static const enum index next_qia_qu_attr[] = { 1504 QUEUE_INDIRECT_ACTION_QU_MODE, 1505 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1506 INDIRECT_ACTION_SPEC, 1507 ZERO 1508 }; 1509 1510 static const enum index next_ia_qu_attr[] = { 1511 INDIRECT_ACTION_QU_MODE, 1512 INDIRECT_ACTION_SPEC, 1513 ZERO 1514 }; 1515 1516 static const enum index next_dump_subcmd[] = { 1517 DUMP_ALL, 1518 DUMP_ONE, 1519 DUMP_IS_USER_ID, 1520 ZERO, 1521 }; 1522 1523 static const enum index next_ia_subcmd[] = { 1524 INDIRECT_ACTION_CREATE, 1525 INDIRECT_ACTION_UPDATE, 1526 INDIRECT_ACTION_DESTROY, 1527 INDIRECT_ACTION_QUERY, 1528 INDIRECT_ACTION_QUERY_UPDATE, 1529 ZERO, 1530 }; 1531 1532 static const enum index next_vc_attr[] = { 1533 VC_GROUP, 1534 VC_PRIORITY, 1535 VC_INGRESS, 1536 VC_EGRESS, 1537 VC_TRANSFER, 1538 VC_TUNNEL_SET, 1539 VC_TUNNEL_MATCH, 1540 VC_USER_ID, 1541 ITEM_PATTERN, 1542 ZERO, 1543 }; 1544 1545 static const enum index next_destroy_attr[] = { 1546 DESTROY_RULE, 1547 DESTROY_IS_USER_ID, 1548 END, 1549 ZERO, 1550 }; 1551 1552 static const enum index next_dump_attr[] = { 1553 COMMON_FILE_PATH, 1554 END, 1555 ZERO, 1556 }; 1557 1558 static const enum index next_query_attr[] = { 1559 QUERY_IS_USER_ID, 1560 END, 1561 ZERO, 1562 }; 1563 1564 static const enum index next_list_attr[] = { 1565 LIST_GROUP, 1566 END, 1567 ZERO, 1568 }; 1569 1570 static const enum index next_aged_attr[] = { 1571 AGED_DESTROY, 1572 END, 1573 ZERO, 1574 }; 1575 1576 static const enum index next_ia_destroy_attr[] = { 1577 INDIRECT_ACTION_DESTROY_ID, 1578 END, 1579 ZERO, 1580 }; 1581 1582 static const enum index next_async_insert_subcmd[] = { 1583 QUEUE_PATTERN_TEMPLATE, 1584 QUEUE_RULE_ID, 1585 ZERO, 1586 }; 1587 1588 static const enum index item_param[] = { 1589 ITEM_PARAM_IS, 1590 ITEM_PARAM_SPEC, 1591 ITEM_PARAM_LAST, 1592 ITEM_PARAM_MASK, 1593 ITEM_PARAM_PREFIX, 1594 ZERO, 1595 }; 1596 1597 static const enum index next_item[] = { 1598 ITEM_END, 1599 ITEM_VOID, 1600 ITEM_INVERT, 1601 ITEM_ANY, 1602 ITEM_PORT_ID, 1603 ITEM_MARK, 1604 ITEM_RAW, 1605 ITEM_ETH, 1606 ITEM_VLAN, 1607 ITEM_IPV4, 1608 ITEM_IPV6, 1609 ITEM_ICMP, 1610 ITEM_UDP, 1611 ITEM_TCP, 1612 ITEM_SCTP, 1613 ITEM_VXLAN, 1614 ITEM_E_TAG, 1615 ITEM_NVGRE, 1616 ITEM_MPLS, 1617 ITEM_GRE, 1618 ITEM_FUZZY, 1619 ITEM_GTP, 1620 ITEM_GTPC, 1621 ITEM_GTPU, 1622 ITEM_GENEVE, 1623 ITEM_VXLAN_GPE, 1624 ITEM_ARP_ETH_IPV4, 1625 ITEM_IPV6_EXT, 1626 ITEM_IPV6_FRAG_EXT, 1627 ITEM_IPV6_ROUTING_EXT, 1628 ITEM_ICMP6, 1629 ITEM_ICMP6_ECHO_REQUEST, 1630 ITEM_ICMP6_ECHO_REPLY, 1631 ITEM_ICMP6_ND_NS, 1632 ITEM_ICMP6_ND_NA, 1633 ITEM_ICMP6_ND_OPT, 1634 ITEM_ICMP6_ND_OPT_SLA_ETH, 1635 ITEM_ICMP6_ND_OPT_TLA_ETH, 1636 ITEM_META, 1637 ITEM_RANDOM, 1638 ITEM_GRE_KEY, 1639 ITEM_GRE_OPTION, 1640 ITEM_GTP_PSC, 1641 ITEM_PPPOES, 1642 ITEM_PPPOED, 1643 ITEM_PPPOE_PROTO_ID, 1644 ITEM_HIGIG2, 1645 ITEM_TAG, 1646 ITEM_L2TPV3OIP, 1647 ITEM_ESP, 1648 ITEM_AH, 1649 ITEM_PFCP, 1650 ITEM_ECPRI, 1651 ITEM_GENEVE_OPT, 1652 ITEM_INTEGRITY, 1653 ITEM_CONNTRACK, 1654 ITEM_PORT_REPRESENTOR, 1655 ITEM_REPRESENTED_PORT, 1656 ITEM_FLEX, 1657 ITEM_L2TPV2, 1658 ITEM_PPP, 1659 ITEM_METER, 1660 ITEM_QUOTA, 1661 ITEM_AGGR_AFFINITY, 1662 ITEM_TX_QUEUE, 1663 ITEM_IB_BTH, 1664 ITEM_PTYPE, 1665 ITEM_NSH, 1666 ITEM_COMPARE, 1667 END_SET, 1668 ZERO, 1669 }; 1670 1671 static const enum index item_fuzzy[] = { 1672 ITEM_FUZZY_THRESH, 1673 ITEM_NEXT, 1674 ZERO, 1675 }; 1676 1677 static const enum index item_any[] = { 1678 ITEM_ANY_NUM, 1679 ITEM_NEXT, 1680 ZERO, 1681 }; 1682 1683 static const enum index item_port_id[] = { 1684 ITEM_PORT_ID_ID, 1685 ITEM_NEXT, 1686 ZERO, 1687 }; 1688 1689 static const enum index item_mark[] = { 1690 ITEM_MARK_ID, 1691 ITEM_NEXT, 1692 ZERO, 1693 }; 1694 1695 static const enum index item_raw[] = { 1696 ITEM_RAW_RELATIVE, 1697 ITEM_RAW_SEARCH, 1698 ITEM_RAW_OFFSET, 1699 ITEM_RAW_LIMIT, 1700 ITEM_RAW_PATTERN, 1701 ITEM_RAW_PATTERN_HEX, 1702 ITEM_NEXT, 1703 ZERO, 1704 }; 1705 1706 static const enum index item_eth[] = { 1707 ITEM_ETH_DST, 1708 ITEM_ETH_SRC, 1709 ITEM_ETH_TYPE, 1710 ITEM_ETH_HAS_VLAN, 1711 ITEM_NEXT, 1712 ZERO, 1713 }; 1714 1715 static const enum index item_vlan[] = { 1716 ITEM_VLAN_TCI, 1717 ITEM_VLAN_PCP, 1718 ITEM_VLAN_DEI, 1719 ITEM_VLAN_VID, 1720 ITEM_VLAN_INNER_TYPE, 1721 ITEM_VLAN_HAS_MORE_VLAN, 1722 ITEM_NEXT, 1723 ZERO, 1724 }; 1725 1726 static const enum index item_ipv4[] = { 1727 ITEM_IPV4_VER_IHL, 1728 ITEM_IPV4_TOS, 1729 ITEM_IPV4_LENGTH, 1730 ITEM_IPV4_ID, 1731 ITEM_IPV4_FRAGMENT_OFFSET, 1732 ITEM_IPV4_TTL, 1733 ITEM_IPV4_PROTO, 1734 ITEM_IPV4_SRC, 1735 ITEM_IPV4_DST, 1736 ITEM_NEXT, 1737 ZERO, 1738 }; 1739 1740 static const enum index item_ipv6[] = { 1741 ITEM_IPV6_TC, 1742 ITEM_IPV6_FLOW, 1743 ITEM_IPV6_LEN, 1744 ITEM_IPV6_PROTO, 1745 ITEM_IPV6_HOP, 1746 ITEM_IPV6_SRC, 1747 ITEM_IPV6_DST, 1748 ITEM_IPV6_HAS_FRAG_EXT, 1749 ITEM_IPV6_ROUTING_EXT, 1750 ITEM_NEXT, 1751 ZERO, 1752 }; 1753 1754 static const enum index item_ipv6_routing_ext[] = { 1755 ITEM_IPV6_ROUTING_EXT_TYPE, 1756 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 1757 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 1758 ITEM_NEXT, 1759 ZERO, 1760 }; 1761 1762 static const enum index item_icmp[] = { 1763 ITEM_ICMP_TYPE, 1764 ITEM_ICMP_CODE, 1765 ITEM_ICMP_IDENT, 1766 ITEM_ICMP_SEQ, 1767 ITEM_NEXT, 1768 ZERO, 1769 }; 1770 1771 static const enum index item_udp[] = { 1772 ITEM_UDP_SRC, 1773 ITEM_UDP_DST, 1774 ITEM_NEXT, 1775 ZERO, 1776 }; 1777 1778 static const enum index item_tcp[] = { 1779 ITEM_TCP_SRC, 1780 ITEM_TCP_DST, 1781 ITEM_TCP_FLAGS, 1782 ITEM_NEXT, 1783 ZERO, 1784 }; 1785 1786 static const enum index item_sctp[] = { 1787 ITEM_SCTP_SRC, 1788 ITEM_SCTP_DST, 1789 ITEM_SCTP_TAG, 1790 ITEM_SCTP_CKSUM, 1791 ITEM_NEXT, 1792 ZERO, 1793 }; 1794 1795 static const enum index item_vxlan[] = { 1796 ITEM_VXLAN_VNI, 1797 ITEM_VXLAN_FLAG_G, 1798 ITEM_VXLAN_FLAG_VER, 1799 ITEM_VXLAN_FLAG_I, 1800 ITEM_VXLAN_FLAG_P, 1801 ITEM_VXLAN_FLAG_B, 1802 ITEM_VXLAN_FLAG_O, 1803 ITEM_VXLAN_FLAG_D, 1804 ITEM_VXLAN_FLAG_A, 1805 ITEM_VXLAN_GBP_ID, 1806 ITEM_VXLAN_GPE_PROTO, 1807 ITEM_VXLAN_FIRST_RSVD, 1808 ITEM_VXLAN_SECND_RSVD, 1809 ITEM_VXLAN_THIRD_RSVD, 1810 ITEM_VXLAN_LAST_RSVD, 1811 ITEM_NEXT, 1812 ZERO, 1813 }; 1814 1815 static const enum index item_e_tag[] = { 1816 ITEM_E_TAG_GRP_ECID_B, 1817 ITEM_NEXT, 1818 ZERO, 1819 }; 1820 1821 static const enum index item_nvgre[] = { 1822 ITEM_NVGRE_TNI, 1823 ITEM_NEXT, 1824 ZERO, 1825 }; 1826 1827 static const enum index item_mpls[] = { 1828 ITEM_MPLS_LABEL, 1829 ITEM_MPLS_TC, 1830 ITEM_MPLS_S, 1831 ITEM_MPLS_TTL, 1832 ITEM_NEXT, 1833 ZERO, 1834 }; 1835 1836 static const enum index item_gre[] = { 1837 ITEM_GRE_PROTO, 1838 ITEM_GRE_C_RSVD0_VER, 1839 ITEM_GRE_C_BIT, 1840 ITEM_GRE_K_BIT, 1841 ITEM_GRE_S_BIT, 1842 ITEM_NEXT, 1843 ZERO, 1844 }; 1845 1846 static const enum index item_gre_key[] = { 1847 ITEM_GRE_KEY_VALUE, 1848 ITEM_NEXT, 1849 ZERO, 1850 }; 1851 1852 static const enum index item_gre_option[] = { 1853 ITEM_GRE_OPTION_CHECKSUM, 1854 ITEM_GRE_OPTION_KEY, 1855 ITEM_GRE_OPTION_SEQUENCE, 1856 ITEM_NEXT, 1857 ZERO, 1858 }; 1859 1860 static const enum index item_gtp[] = { 1861 ITEM_GTP_FLAGS, 1862 ITEM_GTP_MSG_TYPE, 1863 ITEM_GTP_TEID, 1864 ITEM_NEXT, 1865 ZERO, 1866 }; 1867 1868 static const enum index item_geneve[] = { 1869 ITEM_GENEVE_VNI, 1870 ITEM_GENEVE_PROTO, 1871 ITEM_GENEVE_OPTLEN, 1872 ITEM_NEXT, 1873 ZERO, 1874 }; 1875 1876 static const enum index item_vxlan_gpe[] = { 1877 ITEM_VXLAN_GPE_VNI, 1878 ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR, 1879 ITEM_VXLAN_GPE_FLAGS, 1880 ITEM_VXLAN_GPE_RSVD0, 1881 ITEM_VXLAN_GPE_RSVD1, 1882 ITEM_NEXT, 1883 ZERO, 1884 }; 1885 1886 static const enum index item_arp_eth_ipv4[] = { 1887 ITEM_ARP_ETH_IPV4_SHA, 1888 ITEM_ARP_ETH_IPV4_SPA, 1889 ITEM_ARP_ETH_IPV4_THA, 1890 ITEM_ARP_ETH_IPV4_TPA, 1891 ITEM_NEXT, 1892 ZERO, 1893 }; 1894 1895 static const enum index item_ipv6_ext[] = { 1896 ITEM_IPV6_EXT_NEXT_HDR, 1897 ITEM_NEXT, 1898 ZERO, 1899 }; 1900 1901 static const enum index item_ipv6_frag_ext[] = { 1902 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 1903 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 1904 ITEM_IPV6_FRAG_EXT_ID, 1905 ITEM_NEXT, 1906 ZERO, 1907 }; 1908 1909 static const enum index item_icmp6[] = { 1910 ITEM_ICMP6_TYPE, 1911 ITEM_ICMP6_CODE, 1912 ITEM_NEXT, 1913 ZERO, 1914 }; 1915 1916 static const enum index item_icmp6_echo_request[] = { 1917 ITEM_ICMP6_ECHO_REQUEST_ID, 1918 ITEM_ICMP6_ECHO_REQUEST_SEQ, 1919 ITEM_NEXT, 1920 ZERO, 1921 }; 1922 1923 static const enum index item_icmp6_echo_reply[] = { 1924 ITEM_ICMP6_ECHO_REPLY_ID, 1925 ITEM_ICMP6_ECHO_REPLY_SEQ, 1926 ITEM_NEXT, 1927 ZERO, 1928 }; 1929 1930 static const enum index item_icmp6_nd_ns[] = { 1931 ITEM_ICMP6_ND_NS_TARGET_ADDR, 1932 ITEM_NEXT, 1933 ZERO, 1934 }; 1935 1936 static const enum index item_icmp6_nd_na[] = { 1937 ITEM_ICMP6_ND_NA_TARGET_ADDR, 1938 ITEM_NEXT, 1939 ZERO, 1940 }; 1941 1942 static const enum index item_icmp6_nd_opt[] = { 1943 ITEM_ICMP6_ND_OPT_TYPE, 1944 ITEM_NEXT, 1945 ZERO, 1946 }; 1947 1948 static const enum index item_icmp6_nd_opt_sla_eth[] = { 1949 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 1950 ITEM_NEXT, 1951 ZERO, 1952 }; 1953 1954 static const enum index item_icmp6_nd_opt_tla_eth[] = { 1955 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 1956 ITEM_NEXT, 1957 ZERO, 1958 }; 1959 1960 static const enum index item_meta[] = { 1961 ITEM_META_DATA, 1962 ITEM_NEXT, 1963 ZERO, 1964 }; 1965 1966 static const enum index item_random[] = { 1967 ITEM_RANDOM_VALUE, 1968 ITEM_NEXT, 1969 ZERO, 1970 }; 1971 1972 static const enum index item_gtp_psc[] = { 1973 ITEM_GTP_PSC_QFI, 1974 ITEM_GTP_PSC_PDU_T, 1975 ITEM_NEXT, 1976 ZERO, 1977 }; 1978 1979 static const enum index item_pppoed[] = { 1980 ITEM_PPPOE_SEID, 1981 ITEM_NEXT, 1982 ZERO, 1983 }; 1984 1985 static const enum index item_pppoes[] = { 1986 ITEM_PPPOE_SEID, 1987 ITEM_NEXT, 1988 ZERO, 1989 }; 1990 1991 static const enum index item_pppoe_proto_id[] = { 1992 ITEM_NEXT, 1993 ZERO, 1994 }; 1995 1996 static const enum index item_higig2[] = { 1997 ITEM_HIGIG2_CLASSIFICATION, 1998 ITEM_HIGIG2_VID, 1999 ITEM_NEXT, 2000 ZERO, 2001 }; 2002 2003 static const enum index item_esp[] = { 2004 ITEM_ESP_SPI, 2005 ITEM_NEXT, 2006 ZERO, 2007 }; 2008 2009 static const enum index item_ah[] = { 2010 ITEM_AH_SPI, 2011 ITEM_NEXT, 2012 ZERO, 2013 }; 2014 2015 static const enum index item_pfcp[] = { 2016 ITEM_PFCP_S_FIELD, 2017 ITEM_PFCP_SEID, 2018 ITEM_NEXT, 2019 ZERO, 2020 }; 2021 2022 static const enum index next_set_raw[] = { 2023 SET_RAW_INDEX, 2024 ITEM_ETH, 2025 ZERO, 2026 }; 2027 2028 static const enum index item_tag[] = { 2029 ITEM_TAG_DATA, 2030 ITEM_TAG_INDEX, 2031 ITEM_NEXT, 2032 ZERO, 2033 }; 2034 2035 static const enum index item_l2tpv3oip[] = { 2036 ITEM_L2TPV3OIP_SESSION_ID, 2037 ITEM_NEXT, 2038 ZERO, 2039 }; 2040 2041 static const enum index item_ecpri[] = { 2042 ITEM_ECPRI_COMMON, 2043 ITEM_NEXT, 2044 ZERO, 2045 }; 2046 2047 static const enum index item_ecpri_common[] = { 2048 ITEM_ECPRI_COMMON_TYPE, 2049 ZERO, 2050 }; 2051 2052 static const enum index item_ecpri_common_type[] = { 2053 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 2054 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 2055 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 2056 ZERO, 2057 }; 2058 2059 static const enum index item_geneve_opt[] = { 2060 ITEM_GENEVE_OPT_CLASS, 2061 ITEM_GENEVE_OPT_TYPE, 2062 ITEM_GENEVE_OPT_LENGTH, 2063 ITEM_GENEVE_OPT_DATA, 2064 ITEM_NEXT, 2065 ZERO, 2066 }; 2067 2068 static const enum index item_integrity[] = { 2069 ITEM_INTEGRITY_LEVEL, 2070 ITEM_INTEGRITY_VALUE, 2071 ZERO, 2072 }; 2073 2074 static const enum index item_integrity_lv[] = { 2075 ITEM_INTEGRITY_LEVEL, 2076 ITEM_INTEGRITY_VALUE, 2077 ITEM_NEXT, 2078 ZERO, 2079 }; 2080 2081 static const enum index item_port_representor[] = { 2082 ITEM_PORT_REPRESENTOR_PORT_ID, 2083 ITEM_NEXT, 2084 ZERO, 2085 }; 2086 2087 static const enum index item_represented_port[] = { 2088 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 2089 ITEM_NEXT, 2090 ZERO, 2091 }; 2092 2093 static const enum index item_flex[] = { 2094 ITEM_FLEX_PATTERN_HANDLE, 2095 ITEM_FLEX_ITEM_HANDLE, 2096 ITEM_NEXT, 2097 ZERO, 2098 }; 2099 2100 static const enum index item_l2tpv2[] = { 2101 ITEM_L2TPV2_TYPE, 2102 ITEM_NEXT, 2103 ZERO, 2104 }; 2105 2106 static const enum index item_l2tpv2_type[] = { 2107 ITEM_L2TPV2_TYPE_DATA, 2108 ITEM_L2TPV2_TYPE_DATA_L, 2109 ITEM_L2TPV2_TYPE_DATA_S, 2110 ITEM_L2TPV2_TYPE_DATA_O, 2111 ITEM_L2TPV2_TYPE_DATA_L_S, 2112 ITEM_L2TPV2_TYPE_CTRL, 2113 ZERO, 2114 }; 2115 2116 static const enum index item_l2tpv2_type_data[] = { 2117 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 2118 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 2119 ITEM_NEXT, 2120 ZERO, 2121 }; 2122 2123 static const enum index item_l2tpv2_type_data_l[] = { 2124 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 2125 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 2126 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 2127 ITEM_NEXT, 2128 ZERO, 2129 }; 2130 2131 static const enum index item_l2tpv2_type_data_s[] = { 2132 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 2133 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 2134 ITEM_L2TPV2_MSG_DATA_S_NS, 2135 ITEM_L2TPV2_MSG_DATA_S_NR, 2136 ITEM_NEXT, 2137 ZERO, 2138 }; 2139 2140 static const enum index item_l2tpv2_type_data_o[] = { 2141 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 2142 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 2143 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 2144 ITEM_NEXT, 2145 ZERO, 2146 }; 2147 2148 static const enum index item_l2tpv2_type_data_l_s[] = { 2149 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 2150 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 2151 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 2152 ITEM_L2TPV2_MSG_DATA_L_S_NS, 2153 ITEM_L2TPV2_MSG_DATA_L_S_NR, 2154 ITEM_NEXT, 2155 ZERO, 2156 }; 2157 2158 static const enum index item_l2tpv2_type_ctrl[] = { 2159 ITEM_L2TPV2_MSG_CTRL_LENGTH, 2160 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 2161 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 2162 ITEM_L2TPV2_MSG_CTRL_NS, 2163 ITEM_L2TPV2_MSG_CTRL_NR, 2164 ITEM_NEXT, 2165 ZERO, 2166 }; 2167 2168 static const enum index item_ppp[] = { 2169 ITEM_PPP_ADDR, 2170 ITEM_PPP_CTRL, 2171 ITEM_PPP_PROTO_ID, 2172 ITEM_NEXT, 2173 ZERO, 2174 }; 2175 2176 static const enum index item_meter[] = { 2177 ITEM_METER_COLOR, 2178 ITEM_NEXT, 2179 ZERO, 2180 }; 2181 2182 static const enum index item_quota[] = { 2183 ITEM_QUOTA_STATE, 2184 ITEM_NEXT, 2185 ZERO, 2186 }; 2187 2188 static const enum index item_aggr_affinity[] = { 2189 ITEM_AGGR_AFFINITY_VALUE, 2190 ITEM_NEXT, 2191 ZERO, 2192 }; 2193 2194 static const enum index item_tx_queue[] = { 2195 ITEM_TX_QUEUE_VALUE, 2196 ITEM_NEXT, 2197 ZERO, 2198 }; 2199 2200 static const enum index item_ib_bth[] = { 2201 ITEM_IB_BTH_OPCODE, 2202 ITEM_IB_BTH_PKEY, 2203 ITEM_IB_BTH_DST_QPN, 2204 ITEM_IB_BTH_PSN, 2205 ITEM_NEXT, 2206 ZERO, 2207 }; 2208 2209 static const enum index item_ptype[] = { 2210 ITEM_PTYPE_VALUE, 2211 ITEM_NEXT, 2212 ZERO, 2213 }; 2214 2215 static const enum index item_nsh[] = { 2216 ITEM_NEXT, 2217 ZERO, 2218 }; 2219 2220 static const enum index item_compare_field[] = { 2221 ITEM_COMPARE_OP, 2222 ITEM_COMPARE_FIELD_A_TYPE, 2223 ITEM_COMPARE_FIELD_B_TYPE, 2224 ITEM_NEXT, 2225 ZERO, 2226 }; 2227 2228 static const enum index compare_field_a[] = { 2229 ITEM_COMPARE_FIELD_A_TYPE, 2230 ITEM_COMPARE_FIELD_A_LEVEL, 2231 ITEM_COMPARE_FIELD_A_TAG_INDEX, 2232 ITEM_COMPARE_FIELD_A_TYPE_ID, 2233 ITEM_COMPARE_FIELD_A_CLASS_ID, 2234 ITEM_COMPARE_FIELD_A_OFFSET, 2235 ITEM_COMPARE_FIELD_B_TYPE, 2236 ZERO, 2237 }; 2238 2239 static const enum index compare_field_b[] = { 2240 ITEM_COMPARE_FIELD_B_TYPE, 2241 ITEM_COMPARE_FIELD_B_LEVEL, 2242 ITEM_COMPARE_FIELD_B_TAG_INDEX, 2243 ITEM_COMPARE_FIELD_B_TYPE_ID, 2244 ITEM_COMPARE_FIELD_B_CLASS_ID, 2245 ITEM_COMPARE_FIELD_B_OFFSET, 2246 ITEM_COMPARE_FIELD_B_VALUE, 2247 ITEM_COMPARE_FIELD_B_POINTER, 2248 ITEM_COMPARE_FIELD_WIDTH, 2249 ZERO, 2250 }; 2251 2252 static const enum index next_action[] = { 2253 ACTION_END, 2254 ACTION_VOID, 2255 ACTION_PASSTHRU, 2256 ACTION_SKIP_CMAN, 2257 ACTION_JUMP, 2258 ACTION_MARK, 2259 ACTION_FLAG, 2260 ACTION_QUEUE, 2261 ACTION_DROP, 2262 ACTION_COUNT, 2263 ACTION_RSS, 2264 ACTION_PF, 2265 ACTION_VF, 2266 ACTION_PORT_ID, 2267 ACTION_METER, 2268 ACTION_METER_COLOR, 2269 ACTION_METER_MARK, 2270 ACTION_OF_DEC_NW_TTL, 2271 ACTION_OF_POP_VLAN, 2272 ACTION_OF_PUSH_VLAN, 2273 ACTION_OF_SET_VLAN_VID, 2274 ACTION_OF_SET_VLAN_PCP, 2275 ACTION_OF_POP_MPLS, 2276 ACTION_OF_PUSH_MPLS, 2277 ACTION_VXLAN_ENCAP, 2278 ACTION_VXLAN_DECAP, 2279 ACTION_NVGRE_ENCAP, 2280 ACTION_NVGRE_DECAP, 2281 ACTION_L2_ENCAP, 2282 ACTION_L2_DECAP, 2283 ACTION_MPLSOGRE_ENCAP, 2284 ACTION_MPLSOGRE_DECAP, 2285 ACTION_MPLSOUDP_ENCAP, 2286 ACTION_MPLSOUDP_DECAP, 2287 ACTION_SET_IPV4_SRC, 2288 ACTION_SET_IPV4_DST, 2289 ACTION_SET_IPV6_SRC, 2290 ACTION_SET_IPV6_DST, 2291 ACTION_SET_TP_SRC, 2292 ACTION_SET_TP_DST, 2293 ACTION_MAC_SWAP, 2294 ACTION_DEC_TTL, 2295 ACTION_SET_TTL, 2296 ACTION_SET_MAC_SRC, 2297 ACTION_SET_MAC_DST, 2298 ACTION_INC_TCP_SEQ, 2299 ACTION_DEC_TCP_SEQ, 2300 ACTION_INC_TCP_ACK, 2301 ACTION_DEC_TCP_ACK, 2302 ACTION_RAW_ENCAP, 2303 ACTION_RAW_DECAP, 2304 ACTION_SET_TAG, 2305 ACTION_SET_META, 2306 ACTION_SET_IPV4_DSCP, 2307 ACTION_SET_IPV6_DSCP, 2308 ACTION_AGE, 2309 ACTION_AGE_UPDATE, 2310 ACTION_SAMPLE, 2311 ACTION_INDIRECT, 2312 ACTION_INDIRECT_LIST, 2313 ACTION_SHARED_INDIRECT, 2314 ACTION_MODIFY_FIELD, 2315 ACTION_CONNTRACK, 2316 ACTION_CONNTRACK_UPDATE, 2317 ACTION_PORT_REPRESENTOR, 2318 ACTION_REPRESENTED_PORT, 2319 ACTION_SEND_TO_KERNEL, 2320 ACTION_QUOTA_CREATE, 2321 ACTION_QUOTA_QU, 2322 ACTION_IPV6_EXT_REMOVE, 2323 ACTION_IPV6_EXT_PUSH, 2324 ACTION_NAT64, 2325 ZERO, 2326 }; 2327 2328 static const enum index action_quota_create[] = { 2329 ACTION_QUOTA_CREATE_LIMIT, 2330 ACTION_QUOTA_CREATE_MODE, 2331 ACTION_NEXT, 2332 ZERO 2333 }; 2334 2335 static const enum index action_quota_update[] = { 2336 ACTION_QUOTA_QU_LIMIT, 2337 ACTION_QUOTA_QU_UPDATE_OP, 2338 ACTION_NEXT, 2339 ZERO 2340 }; 2341 2342 static const enum index action_mark[] = { 2343 ACTION_MARK_ID, 2344 ACTION_NEXT, 2345 ZERO, 2346 }; 2347 2348 static const enum index action_queue[] = { 2349 ACTION_QUEUE_INDEX, 2350 ACTION_NEXT, 2351 ZERO, 2352 }; 2353 2354 static const enum index action_count[] = { 2355 ACTION_COUNT_ID, 2356 ACTION_NEXT, 2357 ZERO, 2358 }; 2359 2360 static const enum index action_rss[] = { 2361 ACTION_RSS_FUNC, 2362 ACTION_RSS_LEVEL, 2363 ACTION_RSS_TYPES, 2364 ACTION_RSS_KEY, 2365 ACTION_RSS_KEY_LEN, 2366 ACTION_RSS_QUEUES, 2367 ACTION_NEXT, 2368 ZERO, 2369 }; 2370 2371 static const enum index action_vf[] = { 2372 ACTION_VF_ORIGINAL, 2373 ACTION_VF_ID, 2374 ACTION_NEXT, 2375 ZERO, 2376 }; 2377 2378 static const enum index action_port_id[] = { 2379 ACTION_PORT_ID_ORIGINAL, 2380 ACTION_PORT_ID_ID, 2381 ACTION_NEXT, 2382 ZERO, 2383 }; 2384 2385 static const enum index action_meter[] = { 2386 ACTION_METER_ID, 2387 ACTION_NEXT, 2388 ZERO, 2389 }; 2390 2391 static const enum index action_meter_color[] = { 2392 ACTION_METER_COLOR_TYPE, 2393 ACTION_NEXT, 2394 ZERO, 2395 }; 2396 2397 static const enum index action_meter_mark[] = { 2398 ACTION_METER_PROFILE, 2399 ACTION_METER_POLICY, 2400 ACTION_METER_COLOR_MODE, 2401 ACTION_METER_STATE, 2402 ACTION_NEXT, 2403 ZERO, 2404 }; 2405 2406 static const enum index action_of_push_vlan[] = { 2407 ACTION_OF_PUSH_VLAN_ETHERTYPE, 2408 ACTION_NEXT, 2409 ZERO, 2410 }; 2411 2412 static const enum index action_of_set_vlan_vid[] = { 2413 ACTION_OF_SET_VLAN_VID_VLAN_VID, 2414 ACTION_NEXT, 2415 ZERO, 2416 }; 2417 2418 static const enum index action_of_set_vlan_pcp[] = { 2419 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 2420 ACTION_NEXT, 2421 ZERO, 2422 }; 2423 2424 static const enum index action_of_pop_mpls[] = { 2425 ACTION_OF_POP_MPLS_ETHERTYPE, 2426 ACTION_NEXT, 2427 ZERO, 2428 }; 2429 2430 static const enum index action_of_push_mpls[] = { 2431 ACTION_OF_PUSH_MPLS_ETHERTYPE, 2432 ACTION_NEXT, 2433 ZERO, 2434 }; 2435 2436 static const enum index action_set_ipv4_src[] = { 2437 ACTION_SET_IPV4_SRC_IPV4_SRC, 2438 ACTION_NEXT, 2439 ZERO, 2440 }; 2441 2442 static const enum index action_set_mac_src[] = { 2443 ACTION_SET_MAC_SRC_MAC_SRC, 2444 ACTION_NEXT, 2445 ZERO, 2446 }; 2447 2448 static const enum index action_set_ipv4_dst[] = { 2449 ACTION_SET_IPV4_DST_IPV4_DST, 2450 ACTION_NEXT, 2451 ZERO, 2452 }; 2453 2454 static const enum index action_set_ipv6_src[] = { 2455 ACTION_SET_IPV6_SRC_IPV6_SRC, 2456 ACTION_NEXT, 2457 ZERO, 2458 }; 2459 2460 static const enum index action_set_ipv6_dst[] = { 2461 ACTION_SET_IPV6_DST_IPV6_DST, 2462 ACTION_NEXT, 2463 ZERO, 2464 }; 2465 2466 static const enum index action_set_tp_src[] = { 2467 ACTION_SET_TP_SRC_TP_SRC, 2468 ACTION_NEXT, 2469 ZERO, 2470 }; 2471 2472 static const enum index action_set_tp_dst[] = { 2473 ACTION_SET_TP_DST_TP_DST, 2474 ACTION_NEXT, 2475 ZERO, 2476 }; 2477 2478 static const enum index action_set_ttl[] = { 2479 ACTION_SET_TTL_TTL, 2480 ACTION_NEXT, 2481 ZERO, 2482 }; 2483 2484 static const enum index action_jump[] = { 2485 ACTION_JUMP_GROUP, 2486 ACTION_NEXT, 2487 ZERO, 2488 }; 2489 2490 static const enum index action_set_mac_dst[] = { 2491 ACTION_SET_MAC_DST_MAC_DST, 2492 ACTION_NEXT, 2493 ZERO, 2494 }; 2495 2496 static const enum index action_inc_tcp_seq[] = { 2497 ACTION_INC_TCP_SEQ_VALUE, 2498 ACTION_NEXT, 2499 ZERO, 2500 }; 2501 2502 static const enum index action_dec_tcp_seq[] = { 2503 ACTION_DEC_TCP_SEQ_VALUE, 2504 ACTION_NEXT, 2505 ZERO, 2506 }; 2507 2508 static const enum index action_inc_tcp_ack[] = { 2509 ACTION_INC_TCP_ACK_VALUE, 2510 ACTION_NEXT, 2511 ZERO, 2512 }; 2513 2514 static const enum index action_dec_tcp_ack[] = { 2515 ACTION_DEC_TCP_ACK_VALUE, 2516 ACTION_NEXT, 2517 ZERO, 2518 }; 2519 2520 static const enum index action_raw_encap[] = { 2521 ACTION_RAW_ENCAP_SIZE, 2522 ACTION_RAW_ENCAP_INDEX, 2523 ACTION_NEXT, 2524 ZERO, 2525 }; 2526 2527 static const enum index action_raw_decap[] = { 2528 ACTION_RAW_DECAP_INDEX, 2529 ACTION_NEXT, 2530 ZERO, 2531 }; 2532 2533 static const enum index action_ipv6_ext_remove[] = { 2534 ACTION_IPV6_EXT_REMOVE_INDEX, 2535 ACTION_NEXT, 2536 ZERO, 2537 }; 2538 2539 static const enum index action_ipv6_ext_push[] = { 2540 ACTION_IPV6_EXT_PUSH_INDEX, 2541 ACTION_NEXT, 2542 ZERO, 2543 }; 2544 2545 static const enum index action_set_tag[] = { 2546 ACTION_SET_TAG_DATA, 2547 ACTION_SET_TAG_INDEX, 2548 ACTION_SET_TAG_MASK, 2549 ACTION_NEXT, 2550 ZERO, 2551 }; 2552 2553 static const enum index action_set_meta[] = { 2554 ACTION_SET_META_DATA, 2555 ACTION_SET_META_MASK, 2556 ACTION_NEXT, 2557 ZERO, 2558 }; 2559 2560 static const enum index action_set_ipv4_dscp[] = { 2561 ACTION_SET_IPV4_DSCP_VALUE, 2562 ACTION_NEXT, 2563 ZERO, 2564 }; 2565 2566 static const enum index action_set_ipv6_dscp[] = { 2567 ACTION_SET_IPV6_DSCP_VALUE, 2568 ACTION_NEXT, 2569 ZERO, 2570 }; 2571 2572 static const enum index action_age[] = { 2573 ACTION_AGE, 2574 ACTION_AGE_TIMEOUT, 2575 ACTION_NEXT, 2576 ZERO, 2577 }; 2578 2579 static const enum index action_age_update[] = { 2580 ACTION_AGE_UPDATE, 2581 ACTION_AGE_UPDATE_TIMEOUT, 2582 ACTION_AGE_UPDATE_TOUCH, 2583 ACTION_NEXT, 2584 ZERO, 2585 }; 2586 2587 static const enum index action_sample[] = { 2588 ACTION_SAMPLE, 2589 ACTION_SAMPLE_RATIO, 2590 ACTION_SAMPLE_INDEX, 2591 ACTION_NEXT, 2592 ZERO, 2593 }; 2594 2595 static const enum index next_action_sample[] = { 2596 ACTION_QUEUE, 2597 ACTION_RSS, 2598 ACTION_MARK, 2599 ACTION_COUNT, 2600 ACTION_PORT_ID, 2601 ACTION_RAW_ENCAP, 2602 ACTION_VXLAN_ENCAP, 2603 ACTION_NVGRE_ENCAP, 2604 ACTION_REPRESENTED_PORT, 2605 ACTION_PORT_REPRESENTOR, 2606 ACTION_NEXT, 2607 ZERO, 2608 }; 2609 2610 static const enum index item_ipv6_push_ext[] = { 2611 ITEM_IPV6_PUSH_REMOVE_EXT, 2612 ZERO, 2613 }; 2614 2615 static const enum index item_ipv6_push_ext_type[] = { 2616 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 2617 ZERO, 2618 }; 2619 2620 static const enum index item_ipv6_push_ext_header[] = { 2621 ITEM_IPV6_ROUTING_EXT, 2622 ITEM_NEXT, 2623 ZERO, 2624 }; 2625 2626 static const enum index action_modify_field_dst[] = { 2627 ACTION_MODIFY_FIELD_DST_LEVEL, 2628 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 2629 ACTION_MODIFY_FIELD_DST_TYPE_ID, 2630 ACTION_MODIFY_FIELD_DST_CLASS_ID, 2631 ACTION_MODIFY_FIELD_DST_OFFSET, 2632 ACTION_MODIFY_FIELD_SRC_TYPE, 2633 ZERO, 2634 }; 2635 2636 static const enum index action_modify_field_src[] = { 2637 ACTION_MODIFY_FIELD_SRC_LEVEL, 2638 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 2639 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 2640 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 2641 ACTION_MODIFY_FIELD_SRC_OFFSET, 2642 ACTION_MODIFY_FIELD_SRC_VALUE, 2643 ACTION_MODIFY_FIELD_SRC_POINTER, 2644 ACTION_MODIFY_FIELD_WIDTH, 2645 ZERO, 2646 }; 2647 2648 static const enum index action_update_conntrack[] = { 2649 ACTION_CONNTRACK_UPDATE_DIR, 2650 ACTION_CONNTRACK_UPDATE_CTX, 2651 ACTION_NEXT, 2652 ZERO, 2653 }; 2654 2655 static const enum index action_port_representor[] = { 2656 ACTION_PORT_REPRESENTOR_PORT_ID, 2657 ACTION_NEXT, 2658 ZERO, 2659 }; 2660 2661 static const enum index action_represented_port[] = { 2662 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 2663 ACTION_NEXT, 2664 ZERO, 2665 }; 2666 2667 static const enum index action_nat64[] = { 2668 ACTION_NAT64_MODE, 2669 ACTION_NEXT, 2670 ZERO, 2671 }; 2672 2673 static const enum index next_hash_subcmd[] = { 2674 HASH_CALC_TABLE, 2675 HASH_CALC_ENCAP, 2676 ZERO, 2677 }; 2678 2679 static const enum index next_hash_encap_dest_subcmd[] = { 2680 ENCAP_HASH_FIELD_SRC_PORT, 2681 ENCAP_HASH_FIELD_GRE_FLOW_ID, 2682 ZERO, 2683 }; 2684 2685 static int parse_set_raw_encap_decap(struct context *, const struct token *, 2686 const char *, unsigned int, 2687 void *, unsigned int); 2688 static int parse_set_sample_action(struct context *, const struct token *, 2689 const char *, unsigned int, 2690 void *, unsigned int); 2691 static int parse_set_ipv6_ext_action(struct context *, const struct token *, 2692 const char *, unsigned int, 2693 void *, unsigned int); 2694 static int parse_set_init(struct context *, const struct token *, 2695 const char *, unsigned int, 2696 void *, unsigned int); 2697 static int 2698 parse_flex_handle(struct context *, const struct token *, 2699 const char *, unsigned int, void *, unsigned int); 2700 static int parse_init(struct context *, const struct token *, 2701 const char *, unsigned int, 2702 void *, unsigned int); 2703 static int parse_vc(struct context *, const struct token *, 2704 const char *, unsigned int, 2705 void *, unsigned int); 2706 static int parse_vc_spec(struct context *, const struct token *, 2707 const char *, unsigned int, void *, unsigned int); 2708 static int parse_vc_conf(struct context *, const struct token *, 2709 const char *, unsigned int, void *, unsigned int); 2710 static int parse_vc_conf_timeout(struct context *, const struct token *, 2711 const char *, unsigned int, void *, 2712 unsigned int); 2713 static int parse_vc_item_ecpri_type(struct context *, const struct token *, 2714 const char *, unsigned int, 2715 void *, unsigned int); 2716 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, 2717 const char *, unsigned int, 2718 void *, unsigned int); 2719 static int parse_vc_action_meter_color_type(struct context *, 2720 const struct token *, 2721 const char *, unsigned int, void *, 2722 unsigned int); 2723 static int parse_vc_action_rss(struct context *, const struct token *, 2724 const char *, unsigned int, void *, 2725 unsigned int); 2726 static int parse_vc_action_rss_func(struct context *, const struct token *, 2727 const char *, unsigned int, void *, 2728 unsigned int); 2729 static int parse_vc_action_rss_type(struct context *, const struct token *, 2730 const char *, unsigned int, void *, 2731 unsigned int); 2732 static int parse_vc_action_rss_queue(struct context *, const struct token *, 2733 const char *, unsigned int, void *, 2734 unsigned int); 2735 static int parse_vc_action_vxlan_encap(struct context *, const struct token *, 2736 const char *, unsigned int, void *, 2737 unsigned int); 2738 static int parse_vc_action_nvgre_encap(struct context *, const struct token *, 2739 const char *, unsigned int, void *, 2740 unsigned int); 2741 static int parse_vc_action_l2_encap(struct context *, const struct token *, 2742 const char *, unsigned int, void *, 2743 unsigned int); 2744 static int parse_vc_action_l2_decap(struct context *, const struct token *, 2745 const char *, unsigned int, void *, 2746 unsigned int); 2747 static int parse_vc_action_mplsogre_encap(struct context *, 2748 const struct token *, const char *, 2749 unsigned int, void *, unsigned int); 2750 static int parse_vc_action_mplsogre_decap(struct context *, 2751 const struct token *, const char *, 2752 unsigned int, void *, unsigned int); 2753 static int parse_vc_action_mplsoudp_encap(struct context *, 2754 const struct token *, const char *, 2755 unsigned int, void *, unsigned int); 2756 static int parse_vc_action_mplsoudp_decap(struct context *, 2757 const struct token *, const char *, 2758 unsigned int, void *, unsigned int); 2759 static int parse_vc_action_raw_encap(struct context *, 2760 const struct token *, const char *, 2761 unsigned int, void *, unsigned int); 2762 static int parse_vc_action_raw_decap(struct context *, 2763 const struct token *, const char *, 2764 unsigned int, void *, unsigned int); 2765 static int parse_vc_action_raw_encap_index(struct context *, 2766 const struct token *, const char *, 2767 unsigned int, void *, unsigned int); 2768 static int parse_vc_action_raw_decap_index(struct context *, 2769 const struct token *, const char *, 2770 unsigned int, void *, unsigned int); 2771 static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 2772 const char *str, unsigned int len, void *buf, 2773 unsigned int size); 2774 static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, 2775 const struct token *token, 2776 const char *str, unsigned int len, 2777 void *buf, 2778 unsigned int size); 2779 static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 2780 const char *str, unsigned int len, void *buf, 2781 unsigned int size); 2782 static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, 2783 const struct token *token, 2784 const char *str, unsigned int len, 2785 void *buf, 2786 unsigned int size); 2787 static int parse_vc_action_set_meta(struct context *ctx, 2788 const struct token *token, const char *str, 2789 unsigned int len, void *buf, 2790 unsigned int size); 2791 static int parse_vc_action_sample(struct context *ctx, 2792 const struct token *token, const char *str, 2793 unsigned int len, void *buf, 2794 unsigned int size); 2795 static int 2796 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 2797 const char *str, unsigned int len, void *buf, 2798 unsigned int size); 2799 static int 2800 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 2801 const char *str, unsigned int len, void *buf, 2802 unsigned int size); 2803 static int 2804 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 2805 const char *str, unsigned int len, void *buf, 2806 unsigned int size); 2807 static int 2808 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 2809 const char *str, unsigned int len, void *buf, 2810 unsigned int size); 2811 static int 2812 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 2813 const char *str, unsigned int len, void *buf, 2814 unsigned int size); 2815 static int parse_destroy(struct context *, const struct token *, 2816 const char *, unsigned int, 2817 void *, unsigned int); 2818 static int parse_flush(struct context *, const struct token *, 2819 const char *, unsigned int, 2820 void *, unsigned int); 2821 static int parse_dump(struct context *, const struct token *, 2822 const char *, unsigned int, 2823 void *, unsigned int); 2824 static int parse_query(struct context *, const struct token *, 2825 const char *, unsigned int, 2826 void *, unsigned int); 2827 static int parse_action(struct context *, const struct token *, 2828 const char *, unsigned int, 2829 void *, unsigned int); 2830 static int parse_list(struct context *, const struct token *, 2831 const char *, unsigned int, 2832 void *, unsigned int); 2833 static int parse_aged(struct context *, const struct token *, 2834 const char *, unsigned int, 2835 void *, unsigned int); 2836 static int parse_isolate(struct context *, const struct token *, 2837 const char *, unsigned int, 2838 void *, unsigned int); 2839 static int parse_configure(struct context *, const struct token *, 2840 const char *, unsigned int, 2841 void *, unsigned int); 2842 static int parse_template(struct context *, const struct token *, 2843 const char *, unsigned int, 2844 void *, unsigned int); 2845 static int parse_template_destroy(struct context *, const struct token *, 2846 const char *, unsigned int, 2847 void *, unsigned int); 2848 static int parse_table(struct context *, const struct token *, 2849 const char *, unsigned int, void *, unsigned int); 2850 static int parse_table_destroy(struct context *, const struct token *, 2851 const char *, unsigned int, 2852 void *, unsigned int); 2853 static int parse_qo(struct context *, const struct token *, 2854 const char *, unsigned int, 2855 void *, unsigned int); 2856 static int parse_qo_destroy(struct context *, const struct token *, 2857 const char *, unsigned int, 2858 void *, unsigned int); 2859 static int parse_qia(struct context *, const struct token *, 2860 const char *, unsigned int, 2861 void *, unsigned int); 2862 static int parse_qia_destroy(struct context *, const struct token *, 2863 const char *, unsigned int, 2864 void *, unsigned int); 2865 static int parse_push(struct context *, const struct token *, 2866 const char *, unsigned int, 2867 void *, unsigned int); 2868 static int parse_pull(struct context *, const struct token *, 2869 const char *, unsigned int, 2870 void *, unsigned int); 2871 static int parse_group(struct context *, const struct token *, 2872 const char *, unsigned int, 2873 void *, unsigned int); 2874 static int parse_hash(struct context *, const struct token *, 2875 const char *, unsigned int, 2876 void *, unsigned int); 2877 static int parse_tunnel(struct context *, const struct token *, 2878 const char *, unsigned int, 2879 void *, unsigned int); 2880 static int parse_flex(struct context *, const struct token *, 2881 const char *, unsigned int, void *, unsigned int); 2882 static int parse_int(struct context *, const struct token *, 2883 const char *, unsigned int, 2884 void *, unsigned int); 2885 static int parse_prefix(struct context *, const struct token *, 2886 const char *, unsigned int, 2887 void *, unsigned int); 2888 static int parse_boolean(struct context *, const struct token *, 2889 const char *, unsigned int, 2890 void *, unsigned int); 2891 static int parse_string(struct context *, const struct token *, 2892 const char *, unsigned int, 2893 void *, unsigned int); 2894 static int parse_hex(struct context *ctx, const struct token *token, 2895 const char *str, unsigned int len, 2896 void *buf, unsigned int size); 2897 static int parse_string0(struct context *, const struct token *, 2898 const char *, unsigned int, 2899 void *, unsigned int); 2900 static int parse_mac_addr(struct context *, const struct token *, 2901 const char *, unsigned int, 2902 void *, unsigned int); 2903 static int parse_ipv4_addr(struct context *, const struct token *, 2904 const char *, unsigned int, 2905 void *, unsigned int); 2906 static int parse_ipv6_addr(struct context *, const struct token *, 2907 const char *, unsigned int, 2908 void *, unsigned int); 2909 static int parse_port(struct context *, const struct token *, 2910 const char *, unsigned int, 2911 void *, unsigned int); 2912 static int parse_ia(struct context *, const struct token *, 2913 const char *, unsigned int, 2914 void *, unsigned int); 2915 static int parse_ia_destroy(struct context *ctx, const struct token *token, 2916 const char *str, unsigned int len, 2917 void *buf, unsigned int size); 2918 static int parse_ia_id2ptr(struct context *ctx, const struct token *token, 2919 const char *str, unsigned int len, void *buf, 2920 unsigned int size); 2921 2922 static int parse_indlst_id2ptr(struct context *ctx, const struct token *token, 2923 const char *str, unsigned int len, void *buf, 2924 unsigned int size); 2925 static int parse_ia_port(struct context *ctx, const struct token *token, 2926 const char *str, unsigned int len, void *buf, 2927 unsigned int size); 2928 static int parse_mp(struct context *, const struct token *, 2929 const char *, unsigned int, 2930 void *, unsigned int); 2931 static int parse_meter_profile_id2ptr(struct context *ctx, 2932 const struct token *token, 2933 const char *str, unsigned int len, 2934 void *buf, unsigned int size); 2935 static int parse_meter_policy_id2ptr(struct context *ctx, 2936 const struct token *token, 2937 const char *str, unsigned int len, 2938 void *buf, unsigned int size); 2939 static int parse_meter_color(struct context *ctx, const struct token *token, 2940 const char *str, unsigned int len, void *buf, 2941 unsigned int size); 2942 static int parse_insertion_table_type(struct context *ctx, const struct token *token, 2943 const char *str, unsigned int len, void *buf, 2944 unsigned int size); 2945 static int parse_hash_table_type(struct context *ctx, const struct token *token, 2946 const char *str, unsigned int len, void *buf, 2947 unsigned int size); 2948 static int 2949 parse_quota_state_name(struct context *ctx, const struct token *token, 2950 const char *str, unsigned int len, void *buf, 2951 unsigned int size); 2952 static int 2953 parse_quota_mode_name(struct context *ctx, const struct token *token, 2954 const char *str, unsigned int len, void *buf, 2955 unsigned int size); 2956 static int 2957 parse_quota_update_name(struct context *ctx, const struct token *token, 2958 const char *str, unsigned int len, void *buf, 2959 unsigned int size); 2960 static int 2961 parse_qu_mode_name(struct context *ctx, const struct token *token, 2962 const char *str, unsigned int len, void *buf, 2963 unsigned int size); 2964 static int comp_none(struct context *, const struct token *, 2965 unsigned int, char *, unsigned int); 2966 static int comp_boolean(struct context *, const struct token *, 2967 unsigned int, char *, unsigned int); 2968 static int comp_action(struct context *, const struct token *, 2969 unsigned int, char *, unsigned int); 2970 static int comp_port(struct context *, const struct token *, 2971 unsigned int, char *, unsigned int); 2972 static int comp_rule_id(struct context *, const struct token *, 2973 unsigned int, char *, unsigned int); 2974 static int comp_vc_action_rss_type(struct context *, const struct token *, 2975 unsigned int, char *, unsigned int); 2976 static int comp_vc_action_rss_queue(struct context *, const struct token *, 2977 unsigned int, char *, unsigned int); 2978 static int comp_set_raw_index(struct context *, const struct token *, 2979 unsigned int, char *, unsigned int); 2980 static int comp_set_sample_index(struct context *, const struct token *, 2981 unsigned int, char *, unsigned int); 2982 static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 2983 unsigned int ent, char *buf, unsigned int size); 2984 static int comp_set_modify_field_op(struct context *, const struct token *, 2985 unsigned int, char *, unsigned int); 2986 static int comp_set_modify_field_id(struct context *, const struct token *, 2987 unsigned int, char *, unsigned int); 2988 static int comp_pattern_template_id(struct context *, const struct token *, 2989 unsigned int, char *, unsigned int); 2990 static int comp_actions_template_id(struct context *, const struct token *, 2991 unsigned int, char *, unsigned int); 2992 static int comp_table_id(struct context *, const struct token *, 2993 unsigned int, char *, unsigned int); 2994 static int comp_queue_id(struct context *, const struct token *, 2995 unsigned int, char *, unsigned int); 2996 static int comp_meter_color(struct context *, const struct token *, 2997 unsigned int, char *, unsigned int); 2998 static int comp_insertion_table_type(struct context *, const struct token *, 2999 unsigned int, char *, unsigned int); 3000 static int comp_hash_table_type(struct context *, const struct token *, 3001 unsigned int, char *, unsigned int); 3002 static int 3003 comp_quota_state_name(struct context *ctx, const struct token *token, 3004 unsigned int ent, char *buf, unsigned int size); 3005 static int 3006 comp_quota_mode_name(struct context *ctx, const struct token *token, 3007 unsigned int ent, char *buf, unsigned int size); 3008 static int 3009 comp_quota_update_name(struct context *ctx, const struct token *token, 3010 unsigned int ent, char *buf, unsigned int size); 3011 static int 3012 comp_qu_mode_name(struct context *ctx, const struct token *token, 3013 unsigned int ent, char *buf, unsigned int size); 3014 static int 3015 comp_set_compare_field_id(struct context *ctx, const struct token *token, 3016 unsigned int ent, char *buf, unsigned int size); 3017 static int 3018 comp_set_compare_op(struct context *ctx, const struct token *token, 3019 unsigned int ent, char *buf, unsigned int size); 3020 static int 3021 parse_vc_compare_op(struct context *ctx, const struct token *token, 3022 const char *str, unsigned int len, void *buf, 3023 unsigned int size); 3024 static int 3025 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 3026 const char *str, unsigned int len, void *buf, 3027 unsigned int size); 3028 static int 3029 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 3030 const char *str, unsigned int len, void *buf, 3031 unsigned int size); 3032 3033 struct indlst_conf { 3034 uint32_t id; 3035 uint32_t conf_num; 3036 struct rte_flow_action *actions; 3037 const void **conf; 3038 SLIST_ENTRY(indlst_conf) next; 3039 }; 3040 3041 static const struct indlst_conf *indirect_action_list_conf_get(uint32_t conf_id); 3042 3043 /** Token definitions. */ 3044 static const struct token token_list[] = { 3045 /* Special tokens. */ 3046 [ZERO] = { 3047 .name = "ZERO", 3048 .help = "null entry, abused as the entry point", 3049 .next = NEXT(NEXT_ENTRY(FLOW, ADD)), 3050 }, 3051 [END] = { 3052 .name = "", 3053 .type = "RETURN", 3054 .help = "command may end here", 3055 }, 3056 [START_SET] = { 3057 .name = "START_SET", 3058 .help = "null entry, abused as the entry point for set", 3059 .next = NEXT(NEXT_ENTRY(SET)), 3060 }, 3061 [END_SET] = { 3062 .name = "end_set", 3063 .type = "RETURN", 3064 .help = "set command may end here", 3065 }, 3066 /* Common tokens. */ 3067 [COMMON_INTEGER] = { 3068 .name = "{int}", 3069 .type = "INTEGER", 3070 .help = "integer value", 3071 .call = parse_int, 3072 .comp = comp_none, 3073 }, 3074 [COMMON_UNSIGNED] = { 3075 .name = "{unsigned}", 3076 .type = "UNSIGNED", 3077 .help = "unsigned integer value", 3078 .call = parse_int, 3079 .comp = comp_none, 3080 }, 3081 [COMMON_PREFIX] = { 3082 .name = "{prefix}", 3083 .type = "PREFIX", 3084 .help = "prefix length for bit-mask", 3085 .call = parse_prefix, 3086 .comp = comp_none, 3087 }, 3088 [COMMON_BOOLEAN] = { 3089 .name = "{boolean}", 3090 .type = "BOOLEAN", 3091 .help = "any boolean value", 3092 .call = parse_boolean, 3093 .comp = comp_boolean, 3094 }, 3095 [COMMON_STRING] = { 3096 .name = "{string}", 3097 .type = "STRING", 3098 .help = "fixed string", 3099 .call = parse_string, 3100 .comp = comp_none, 3101 }, 3102 [COMMON_HEX] = { 3103 .name = "{hex}", 3104 .type = "HEX", 3105 .help = "fixed string", 3106 .call = parse_hex, 3107 }, 3108 [COMMON_FILE_PATH] = { 3109 .name = "{file path}", 3110 .type = "STRING", 3111 .help = "file path", 3112 .call = parse_string0, 3113 .comp = comp_none, 3114 }, 3115 [COMMON_MAC_ADDR] = { 3116 .name = "{MAC address}", 3117 .type = "MAC-48", 3118 .help = "standard MAC address notation", 3119 .call = parse_mac_addr, 3120 .comp = comp_none, 3121 }, 3122 [COMMON_IPV4_ADDR] = { 3123 .name = "{IPv4 address}", 3124 .type = "IPV4 ADDRESS", 3125 .help = "standard IPv4 address notation", 3126 .call = parse_ipv4_addr, 3127 .comp = comp_none, 3128 }, 3129 [COMMON_IPV6_ADDR] = { 3130 .name = "{IPv6 address}", 3131 .type = "IPV6 ADDRESS", 3132 .help = "standard IPv6 address notation", 3133 .call = parse_ipv6_addr, 3134 .comp = comp_none, 3135 }, 3136 [COMMON_RULE_ID] = { 3137 .name = "{rule id}", 3138 .type = "RULE ID", 3139 .help = "rule identifier", 3140 .call = parse_int, 3141 .comp = comp_rule_id, 3142 }, 3143 [COMMON_PORT_ID] = { 3144 .name = "{port_id}", 3145 .type = "PORT ID", 3146 .help = "port identifier", 3147 .call = parse_port, 3148 .comp = comp_port, 3149 }, 3150 [COMMON_GROUP_ID] = { 3151 .name = "{group_id}", 3152 .type = "GROUP ID", 3153 .help = "group identifier", 3154 .call = parse_int, 3155 .comp = comp_none, 3156 }, 3157 [COMMON_PRIORITY_LEVEL] = { 3158 .name = "{level}", 3159 .type = "PRIORITY", 3160 .help = "priority level", 3161 .call = parse_int, 3162 .comp = comp_none, 3163 }, 3164 [COMMON_INDIRECT_ACTION_ID] = { 3165 .name = "{indirect_action_id}", 3166 .type = "INDIRECT_ACTION_ID", 3167 .help = "indirect action id", 3168 .call = parse_int, 3169 .comp = comp_none, 3170 }, 3171 [COMMON_PROFILE_ID] = { 3172 .name = "{profile_id}", 3173 .type = "PROFILE_ID", 3174 .help = "profile id", 3175 .call = parse_int, 3176 .comp = comp_none, 3177 }, 3178 [COMMON_POLICY_ID] = { 3179 .name = "{policy_id}", 3180 .type = "POLICY_ID", 3181 .help = "policy id", 3182 .call = parse_int, 3183 .comp = comp_none, 3184 }, 3185 [COMMON_FLEX_TOKEN] = { 3186 .name = "{flex token}", 3187 .type = "flex token", 3188 .help = "flex token", 3189 .call = parse_int, 3190 .comp = comp_none, 3191 }, 3192 [COMMON_FLEX_HANDLE] = { 3193 .name = "{flex handle}", 3194 .type = "FLEX HANDLE", 3195 .help = "fill flex item data", 3196 .call = parse_flex_handle, 3197 .comp = comp_none, 3198 }, 3199 [COMMON_PATTERN_TEMPLATE_ID] = { 3200 .name = "{pattern_template_id}", 3201 .type = "PATTERN_TEMPLATE_ID", 3202 .help = "pattern template id", 3203 .call = parse_int, 3204 .comp = comp_pattern_template_id, 3205 }, 3206 [COMMON_ACTIONS_TEMPLATE_ID] = { 3207 .name = "{actions_template_id}", 3208 .type = "ACTIONS_TEMPLATE_ID", 3209 .help = "actions template id", 3210 .call = parse_int, 3211 .comp = comp_actions_template_id, 3212 }, 3213 [COMMON_TABLE_ID] = { 3214 .name = "{table_id}", 3215 .type = "TABLE_ID", 3216 .help = "table id", 3217 .call = parse_int, 3218 .comp = comp_table_id, 3219 }, 3220 [COMMON_QUEUE_ID] = { 3221 .name = "{queue_id}", 3222 .type = "QUEUE_ID", 3223 .help = "queue id", 3224 .call = parse_int, 3225 .comp = comp_queue_id, 3226 }, 3227 /* Top-level command. */ 3228 [FLOW] = { 3229 .name = "flow", 3230 .type = "{command} {port_id} [{arg} [...]]", 3231 .help = "manage ingress/egress flow rules", 3232 .next = NEXT(NEXT_ENTRY 3233 (INFO, 3234 CONFIGURE, 3235 PATTERN_TEMPLATE, 3236 ACTIONS_TEMPLATE, 3237 TABLE, 3238 FLOW_GROUP, 3239 INDIRECT_ACTION, 3240 VALIDATE, 3241 CREATE, 3242 DESTROY, 3243 UPDATE, 3244 FLUSH, 3245 DUMP, 3246 LIST, 3247 AGED, 3248 QUERY, 3249 ISOLATE, 3250 TUNNEL, 3251 FLEX, 3252 QUEUE, 3253 PUSH, 3254 PULL, 3255 HASH)), 3256 .call = parse_init, 3257 }, 3258 /* Top-level command. */ 3259 [INFO] = { 3260 .name = "info", 3261 .help = "get information about flow engine", 3262 .next = NEXT(NEXT_ENTRY(END), 3263 NEXT_ENTRY(COMMON_PORT_ID)), 3264 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3265 .call = parse_configure, 3266 }, 3267 /* Top-level command. */ 3268 [CONFIGURE] = { 3269 .name = "configure", 3270 .help = "configure flow engine", 3271 .next = NEXT(next_config_attr, 3272 NEXT_ENTRY(COMMON_PORT_ID)), 3273 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3274 .call = parse_configure, 3275 }, 3276 /* Configure arguments. */ 3277 [CONFIG_QUEUES_NUMBER] = { 3278 .name = "queues_number", 3279 .help = "number of queues", 3280 .next = NEXT(next_config_attr, 3281 NEXT_ENTRY(COMMON_UNSIGNED)), 3282 .args = ARGS(ARGS_ENTRY(struct buffer, 3283 args.configure.nb_queue)), 3284 }, 3285 [CONFIG_QUEUES_SIZE] = { 3286 .name = "queues_size", 3287 .help = "number of elements in queues", 3288 .next = NEXT(next_config_attr, 3289 NEXT_ENTRY(COMMON_UNSIGNED)), 3290 .args = ARGS(ARGS_ENTRY(struct buffer, 3291 args.configure.queue_attr.size)), 3292 }, 3293 [CONFIG_COUNTERS_NUMBER] = { 3294 .name = "counters_number", 3295 .help = "number of counters", 3296 .next = NEXT(next_config_attr, 3297 NEXT_ENTRY(COMMON_UNSIGNED)), 3298 .args = ARGS(ARGS_ENTRY(struct buffer, 3299 args.configure.port_attr.nb_counters)), 3300 }, 3301 [CONFIG_AGING_OBJECTS_NUMBER] = { 3302 .name = "aging_counters_number", 3303 .help = "number of aging objects", 3304 .next = NEXT(next_config_attr, 3305 NEXT_ENTRY(COMMON_UNSIGNED)), 3306 .args = ARGS(ARGS_ENTRY(struct buffer, 3307 args.configure.port_attr.nb_aging_objects)), 3308 }, 3309 [CONFIG_QUOTAS_NUMBER] = { 3310 .name = "quotas_number", 3311 .help = "number of quotas", 3312 .next = NEXT(next_config_attr, 3313 NEXT_ENTRY(COMMON_UNSIGNED)), 3314 .args = ARGS(ARGS_ENTRY(struct buffer, 3315 args.configure.port_attr.nb_quotas)), 3316 }, 3317 [CONFIG_METERS_NUMBER] = { 3318 .name = "meters_number", 3319 .help = "number of meters", 3320 .next = NEXT(next_config_attr, 3321 NEXT_ENTRY(COMMON_UNSIGNED)), 3322 .args = ARGS(ARGS_ENTRY(struct buffer, 3323 args.configure.port_attr.nb_meters)), 3324 }, 3325 [CONFIG_CONN_TRACK_NUMBER] = { 3326 .name = "conn_tracks_number", 3327 .help = "number of connection trackings", 3328 .next = NEXT(next_config_attr, 3329 NEXT_ENTRY(COMMON_UNSIGNED)), 3330 .args = ARGS(ARGS_ENTRY(struct buffer, 3331 args.configure.port_attr.nb_conn_tracks)), 3332 }, 3333 [CONFIG_FLAGS] = { 3334 .name = "flags", 3335 .help = "configuration flags", 3336 .next = NEXT(next_config_attr, 3337 NEXT_ENTRY(COMMON_UNSIGNED)), 3338 .args = ARGS(ARGS_ENTRY(struct buffer, 3339 args.configure.port_attr.flags)), 3340 }, 3341 [CONFIG_HOST_PORT] = { 3342 .name = "host_port", 3343 .help = "host port for shared objects", 3344 .next = NEXT(next_config_attr, 3345 NEXT_ENTRY(COMMON_UNSIGNED)), 3346 .args = ARGS(ARGS_ENTRY(struct buffer, 3347 args.configure.port_attr.host_port_id)), 3348 }, 3349 /* Top-level command. */ 3350 [PATTERN_TEMPLATE] = { 3351 .name = "pattern_template", 3352 .type = "{command} {port_id} [{arg} [...]]", 3353 .help = "manage pattern templates", 3354 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3355 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3356 .call = parse_template, 3357 }, 3358 /* Sub-level commands. */ 3359 [PATTERN_TEMPLATE_CREATE] = { 3360 .name = "create", 3361 .help = "create pattern template", 3362 .next = NEXT(next_pt_attr), 3363 .call = parse_template, 3364 }, 3365 [PATTERN_TEMPLATE_DESTROY] = { 3366 .name = "destroy", 3367 .help = "destroy pattern template", 3368 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), 3369 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3370 .call = parse_template_destroy, 3371 }, 3372 /* Pattern template arguments. */ 3373 [PATTERN_TEMPLATE_CREATE_ID] = { 3374 .name = "pattern_template_id", 3375 .help = "specify a pattern template id to create", 3376 .next = NEXT(next_pt_attr, 3377 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3378 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), 3379 }, 3380 [PATTERN_TEMPLATE_DESTROY_ID] = { 3381 .name = "pattern_template", 3382 .help = "specify a pattern template id to destroy", 3383 .next = NEXT(next_pt_destroy_attr, 3384 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3385 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3386 args.templ_destroy.template_id)), 3387 .call = parse_template_destroy, 3388 }, 3389 [PATTERN_TEMPLATE_RELAXED_MATCHING] = { 3390 .name = "relaxed", 3391 .help = "is matching relaxed", 3392 .next = NEXT(next_pt_attr, 3393 NEXT_ENTRY(COMMON_BOOLEAN)), 3394 .args = ARGS(ARGS_ENTRY_BF(struct buffer, 3395 args.vc.attr.reserved, 1)), 3396 }, 3397 [PATTERN_TEMPLATE_INGRESS] = { 3398 .name = "ingress", 3399 .help = "attribute pattern to ingress", 3400 .next = NEXT(next_pt_attr), 3401 .call = parse_template, 3402 }, 3403 [PATTERN_TEMPLATE_EGRESS] = { 3404 .name = "egress", 3405 .help = "attribute pattern to egress", 3406 .next = NEXT(next_pt_attr), 3407 .call = parse_template, 3408 }, 3409 [PATTERN_TEMPLATE_TRANSFER] = { 3410 .name = "transfer", 3411 .help = "attribute pattern to transfer", 3412 .next = NEXT(next_pt_attr), 3413 .call = parse_template, 3414 }, 3415 [PATTERN_TEMPLATE_SPEC] = { 3416 .name = "template", 3417 .help = "specify item to create pattern template", 3418 .next = NEXT(next_item), 3419 }, 3420 /* Top-level command. */ 3421 [ACTIONS_TEMPLATE] = { 3422 .name = "actions_template", 3423 .type = "{command} {port_id} [{arg} [...]]", 3424 .help = "manage actions templates", 3425 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3426 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3427 .call = parse_template, 3428 }, 3429 /* Sub-level commands. */ 3430 [ACTIONS_TEMPLATE_CREATE] = { 3431 .name = "create", 3432 .help = "create actions template", 3433 .next = NEXT(next_at_attr), 3434 .call = parse_template, 3435 }, 3436 [ACTIONS_TEMPLATE_DESTROY] = { 3437 .name = "destroy", 3438 .help = "destroy actions template", 3439 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), 3440 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3441 .call = parse_template_destroy, 3442 }, 3443 /* Actions template arguments. */ 3444 [ACTIONS_TEMPLATE_CREATE_ID] = { 3445 .name = "actions_template_id", 3446 .help = "specify an actions template id to create", 3447 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), 3448 NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), 3449 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3450 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), 3451 }, 3452 [ACTIONS_TEMPLATE_DESTROY_ID] = { 3453 .name = "actions_template", 3454 .help = "specify an actions template id to destroy", 3455 .next = NEXT(next_at_destroy_attr, 3456 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3457 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3458 args.templ_destroy.template_id)), 3459 .call = parse_template_destroy, 3460 }, 3461 [ACTIONS_TEMPLATE_INGRESS] = { 3462 .name = "ingress", 3463 .help = "attribute actions to ingress", 3464 .next = NEXT(next_at_attr), 3465 .call = parse_template, 3466 }, 3467 [ACTIONS_TEMPLATE_EGRESS] = { 3468 .name = "egress", 3469 .help = "attribute actions to egress", 3470 .next = NEXT(next_at_attr), 3471 .call = parse_template, 3472 }, 3473 [ACTIONS_TEMPLATE_TRANSFER] = { 3474 .name = "transfer", 3475 .help = "attribute actions to transfer", 3476 .next = NEXT(next_at_attr), 3477 .call = parse_template, 3478 }, 3479 [ACTIONS_TEMPLATE_SPEC] = { 3480 .name = "template", 3481 .help = "specify action to create actions template", 3482 .next = NEXT(next_action), 3483 .call = parse_template, 3484 }, 3485 [ACTIONS_TEMPLATE_MASK] = { 3486 .name = "mask", 3487 .help = "specify action mask to create actions template", 3488 .next = NEXT(next_action), 3489 .call = parse_template, 3490 }, 3491 /* Top-level command. */ 3492 [TABLE] = { 3493 .name = "template_table", 3494 .type = "{command} {port_id} [{arg} [...]]", 3495 .help = "manage template tables", 3496 .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3497 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3498 .call = parse_table, 3499 }, 3500 /* Sub-level commands. */ 3501 [TABLE_CREATE] = { 3502 .name = "create", 3503 .help = "create template table", 3504 .next = NEXT(next_table_attr), 3505 .call = parse_table, 3506 }, 3507 [TABLE_DESTROY] = { 3508 .name = "destroy", 3509 .help = "destroy template table", 3510 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3511 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3512 .call = parse_table_destroy, 3513 }, 3514 [TABLE_RESIZE] = { 3515 .name = "resize", 3516 .help = "resize template table", 3517 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_ID)), 3518 .call = parse_table 3519 }, 3520 [TABLE_RESIZE_COMPLETE] = { 3521 .name = "resize_complete", 3522 .help = "complete table resize", 3523 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3524 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3525 .call = parse_table_destroy, 3526 }, 3527 /* Table arguments. */ 3528 [TABLE_CREATE_ID] = { 3529 .name = "table_id", 3530 .help = "specify table id to create", 3531 .next = NEXT(next_table_attr, 3532 NEXT_ENTRY(COMMON_TABLE_ID)), 3533 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3534 }, 3535 [TABLE_DESTROY_ID] = { 3536 .name = "table", 3537 .help = "table id", 3538 .next = NEXT(next_table_destroy_attr, 3539 NEXT_ENTRY(COMMON_TABLE_ID)), 3540 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3541 args.table_destroy.table_id)), 3542 .call = parse_table_destroy, 3543 }, 3544 [TABLE_RESIZE_ID] = { 3545 .name = "table_resize_id", 3546 .help = "table resize id", 3547 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_RULES_NUMBER), 3548 NEXT_ENTRY(COMMON_TABLE_ID)), 3549 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3550 .call = parse_table 3551 }, 3552 [TABLE_RESIZE_RULES_NUMBER] = { 3553 .name = "table_resize_rules_num", 3554 .help = "table resize rules number", 3555 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_UNSIGNED)), 3556 .args = ARGS(ARGS_ENTRY(struct buffer, 3557 args.table.attr.nb_flows)), 3558 .call = parse_table 3559 }, 3560 [TABLE_INSERTION_TYPE] = { 3561 .name = "insertion_type", 3562 .help = "specify insertion type", 3563 .next = NEXT(next_table_attr, 3564 NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)), 3565 .args = ARGS(ARGS_ENTRY(struct buffer, 3566 args.table.attr.insertion_type)), 3567 }, 3568 [TABLE_INSERTION_TYPE_NAME] = { 3569 .name = "insertion_type_name", 3570 .help = "insertion type name", 3571 .call = parse_insertion_table_type, 3572 .comp = comp_insertion_table_type, 3573 }, 3574 [TABLE_HASH_FUNC] = { 3575 .name = "hash_func", 3576 .help = "specify hash calculation function", 3577 .next = NEXT(next_table_attr, 3578 NEXT_ENTRY(TABLE_HASH_FUNC_NAME)), 3579 .args = ARGS(ARGS_ENTRY(struct buffer, 3580 args.table.attr.hash_func)), 3581 }, 3582 [TABLE_HASH_FUNC_NAME] = { 3583 .name = "hash_func_name", 3584 .help = "hash calculation function name", 3585 .call = parse_hash_table_type, 3586 .comp = comp_hash_table_type, 3587 }, 3588 [TABLE_GROUP] = { 3589 .name = "group", 3590 .help = "specify a group", 3591 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3592 .args = ARGS(ARGS_ENTRY(struct buffer, 3593 args.table.attr.flow_attr.group)), 3594 }, 3595 [TABLE_PRIORITY] = { 3596 .name = "priority", 3597 .help = "specify a priority level", 3598 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 3599 .args = ARGS(ARGS_ENTRY(struct buffer, 3600 args.table.attr.flow_attr.priority)), 3601 }, 3602 [TABLE_EGRESS] = { 3603 .name = "egress", 3604 .help = "affect rule to egress", 3605 .next = NEXT(next_table_attr), 3606 .call = parse_table, 3607 }, 3608 [TABLE_INGRESS] = { 3609 .name = "ingress", 3610 .help = "affect rule to ingress", 3611 .next = NEXT(next_table_attr), 3612 .call = parse_table, 3613 }, 3614 [TABLE_TRANSFER] = { 3615 .name = "transfer", 3616 .help = "affect rule to transfer", 3617 .next = NEXT(next_table_attr), 3618 .call = parse_table, 3619 }, 3620 [TABLE_TRANSFER_WIRE_ORIG] = { 3621 .name = "wire_orig", 3622 .help = "affect rule direction to transfer", 3623 .next = NEXT(next_table_attr), 3624 .call = parse_table, 3625 }, 3626 [TABLE_TRANSFER_VPORT_ORIG] = { 3627 .name = "vport_orig", 3628 .help = "affect rule direction to transfer", 3629 .next = NEXT(next_table_attr), 3630 .call = parse_table, 3631 }, 3632 [TABLE_RESIZABLE] = { 3633 .name = "resizable", 3634 .help = "set resizable attribute", 3635 .next = NEXT(next_table_attr), 3636 .call = parse_table, 3637 }, 3638 [TABLE_RULES_NUMBER] = { 3639 .name = "rules_number", 3640 .help = "number of rules in table", 3641 .next = NEXT(next_table_attr, 3642 NEXT_ENTRY(COMMON_UNSIGNED)), 3643 .args = ARGS(ARGS_ENTRY(struct buffer, 3644 args.table.attr.nb_flows)), 3645 .call = parse_table, 3646 }, 3647 [TABLE_PATTERN_TEMPLATE] = { 3648 .name = "pattern_template", 3649 .help = "specify pattern template id", 3650 .next = NEXT(next_table_attr, 3651 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3652 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3653 args.table.pat_templ_id)), 3654 .call = parse_table, 3655 }, 3656 [TABLE_ACTIONS_TEMPLATE] = { 3657 .name = "actions_template", 3658 .help = "specify actions template id", 3659 .next = NEXT(next_table_attr, 3660 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3661 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3662 args.table.act_templ_id)), 3663 .call = parse_table, 3664 }, 3665 /* Top-level command. */ 3666 [FLOW_GROUP] = { 3667 .name = "group", 3668 .help = "manage flow groups", 3669 .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), 3670 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3671 .call = parse_group, 3672 }, 3673 /* Sub-level commands. */ 3674 [GROUP_SET_MISS_ACTIONS] = { 3675 .name = "set_miss_actions", 3676 .help = "set group miss actions", 3677 .next = NEXT(next_action), 3678 .call = parse_group, 3679 }, 3680 /* Group arguments */ 3681 [GROUP_ID] = { 3682 .name = "group_id", 3683 .help = "group id", 3684 .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3685 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3686 }, 3687 [GROUP_INGRESS] = { 3688 .name = "ingress", 3689 .help = "group ingress attr", 3690 .next = NEXT(next_group_attr), 3691 .call = parse_group, 3692 }, 3693 [GROUP_EGRESS] = { 3694 .name = "egress", 3695 .help = "group egress attr", 3696 .next = NEXT(next_group_attr), 3697 .call = parse_group, 3698 }, 3699 [GROUP_TRANSFER] = { 3700 .name = "transfer", 3701 .help = "group transfer attr", 3702 .next = NEXT(next_group_attr), 3703 .call = parse_group, 3704 }, 3705 /* Top-level command. */ 3706 [QUEUE] = { 3707 .name = "queue", 3708 .help = "queue a flow rule operation", 3709 .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3710 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3711 .call = parse_qo, 3712 }, 3713 /* Sub-level commands. */ 3714 [QUEUE_CREATE] = { 3715 .name = "create", 3716 .help = "create a flow rule", 3717 .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), 3718 NEXT_ENTRY(COMMON_QUEUE_ID)), 3719 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3720 .call = parse_qo, 3721 }, 3722 [QUEUE_DESTROY] = { 3723 .name = "destroy", 3724 .help = "destroy a flow rule", 3725 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_POSTPONE), 3726 NEXT_ENTRY(COMMON_QUEUE_ID)), 3727 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3728 .call = parse_qo_destroy, 3729 }, 3730 [QUEUE_FLOW_UPDATE_RESIZED] = { 3731 .name = "update_resized", 3732 .help = "update a flow after table resize", 3733 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3734 NEXT_ENTRY(COMMON_QUEUE_ID)), 3735 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3736 .call = parse_qo_destroy, 3737 }, 3738 [QUEUE_UPDATE] = { 3739 .name = "update", 3740 .help = "update a flow rule", 3741 .next = NEXT(NEXT_ENTRY(QUEUE_UPDATE_ID), 3742 NEXT_ENTRY(COMMON_QUEUE_ID)), 3743 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3744 .call = parse_qo, 3745 }, 3746 [QUEUE_AGED] = { 3747 .name = "aged", 3748 .help = "list and destroy aged flows", 3749 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), 3750 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3751 .call = parse_aged, 3752 }, 3753 [QUEUE_INDIRECT_ACTION] = { 3754 .name = "indirect_action", 3755 .help = "queue indirect actions", 3756 .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), 3757 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3758 .call = parse_qia, 3759 }, 3760 /* Queue arguments. */ 3761 [QUEUE_TEMPLATE_TABLE] = { 3762 .name = "template_table", 3763 .help = "specify table id", 3764 .next = NEXT(next_async_insert_subcmd, 3765 NEXT_ENTRY(COMMON_TABLE_ID)), 3766 .args = ARGS(ARGS_ENTRY(struct buffer, 3767 args.vc.table_id)), 3768 .call = parse_qo, 3769 }, 3770 [QUEUE_PATTERN_TEMPLATE] = { 3771 .name = "pattern_template", 3772 .help = "specify pattern template index", 3773 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3774 NEXT_ENTRY(COMMON_UNSIGNED)), 3775 .args = ARGS(ARGS_ENTRY(struct buffer, 3776 args.vc.pat_templ_id)), 3777 .call = parse_qo, 3778 }, 3779 [QUEUE_ACTIONS_TEMPLATE] = { 3780 .name = "actions_template", 3781 .help = "specify actions template index", 3782 .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), 3783 NEXT_ENTRY(COMMON_UNSIGNED)), 3784 .args = ARGS(ARGS_ENTRY(struct buffer, 3785 args.vc.act_templ_id)), 3786 .call = parse_qo, 3787 }, 3788 [QUEUE_RULE_ID] = { 3789 .name = "rule_index", 3790 .help = "specify flow rule index", 3791 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3792 NEXT_ENTRY(COMMON_UNSIGNED)), 3793 .args = ARGS(ARGS_ENTRY(struct buffer, 3794 args.vc.rule_id)), 3795 .call = parse_qo, 3796 }, 3797 [QUEUE_CREATE_POSTPONE] = { 3798 .name = "postpone", 3799 .help = "postpone create operation", 3800 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3801 NEXT_ENTRY(COMMON_BOOLEAN)), 3802 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3803 .call = parse_qo, 3804 }, 3805 [QUEUE_DESTROY_POSTPONE] = { 3806 .name = "postpone", 3807 .help = "postpone destroy operation", 3808 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3809 NEXT_ENTRY(COMMON_BOOLEAN)), 3810 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3811 .call = parse_qo_destroy, 3812 }, 3813 [QUEUE_DESTROY_ID] = { 3814 .name = "rule", 3815 .help = "specify rule id to destroy", 3816 .next = NEXT(next_queue_destroy_attr, 3817 NEXT_ENTRY(COMMON_UNSIGNED)), 3818 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3819 args.destroy.rule)), 3820 .call = parse_qo_destroy, 3821 }, 3822 [QUEUE_UPDATE_ID] = { 3823 .name = "rule", 3824 .help = "specify rule id to update", 3825 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3826 NEXT_ENTRY(COMMON_UNSIGNED)), 3827 .args = ARGS(ARGS_ENTRY(struct buffer, 3828 args.vc.rule_id)), 3829 .call = parse_qo, 3830 }, 3831 /* Queue indirect action arguments */ 3832 [QUEUE_INDIRECT_ACTION_CREATE] = { 3833 .name = "create", 3834 .help = "create indirect action", 3835 .next = NEXT(next_qia_create_attr), 3836 .call = parse_qia, 3837 }, 3838 [QUEUE_INDIRECT_ACTION_UPDATE] = { 3839 .name = "update", 3840 .help = "update indirect action", 3841 .next = NEXT(next_qia_update_attr, 3842 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3843 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3844 .call = parse_qia, 3845 }, 3846 [QUEUE_INDIRECT_ACTION_DESTROY] = { 3847 .name = "destroy", 3848 .help = "destroy indirect action", 3849 .next = NEXT(next_qia_destroy_attr), 3850 .call = parse_qia_destroy, 3851 }, 3852 [QUEUE_INDIRECT_ACTION_QUERY] = { 3853 .name = "query", 3854 .help = "query indirect action", 3855 .next = NEXT(next_qia_query_attr, 3856 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3857 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3858 .call = parse_qia, 3859 }, 3860 /* Indirect action destroy arguments. */ 3861 [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { 3862 .name = "postpone", 3863 .help = "postpone destroy operation", 3864 .next = NEXT(next_qia_destroy_attr, 3865 NEXT_ENTRY(COMMON_BOOLEAN)), 3866 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3867 }, 3868 [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { 3869 .name = "action_id", 3870 .help = "specify a indirect action id to destroy", 3871 .next = NEXT(next_qia_destroy_attr, 3872 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3873 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3874 args.ia_destroy.action_id)), 3875 .call = parse_qia_destroy, 3876 }, 3877 [QUEUE_INDIRECT_ACTION_QUERY_UPDATE] = { 3878 .name = "query_update", 3879 .help = "indirect query [and|or] update action", 3880 .next = NEXT(next_qia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3881 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3882 .call = parse_qia 3883 }, 3884 [QUEUE_INDIRECT_ACTION_QU_MODE] = { 3885 .name = "mode", 3886 .help = "indirect query [and|or] update action", 3887 .next = NEXT(next_qia_qu_attr, 3888 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 3889 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 3890 .call = parse_qia 3891 }, 3892 /* Indirect action update arguments. */ 3893 [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { 3894 .name = "postpone", 3895 .help = "postpone update operation", 3896 .next = NEXT(next_qia_update_attr, 3897 NEXT_ENTRY(COMMON_BOOLEAN)), 3898 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3899 }, 3900 /* Indirect action update arguments. */ 3901 [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { 3902 .name = "postpone", 3903 .help = "postpone query operation", 3904 .next = NEXT(next_qia_query_attr, 3905 NEXT_ENTRY(COMMON_BOOLEAN)), 3906 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3907 }, 3908 /* Indirect action create arguments. */ 3909 [QUEUE_INDIRECT_ACTION_CREATE_ID] = { 3910 .name = "action_id", 3911 .help = "specify a indirect action id to create", 3912 .next = NEXT(next_qia_create_attr, 3913 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3914 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3915 }, 3916 [QUEUE_INDIRECT_ACTION_INGRESS] = { 3917 .name = "ingress", 3918 .help = "affect rule to ingress", 3919 .next = NEXT(next_qia_create_attr), 3920 .call = parse_qia, 3921 }, 3922 [QUEUE_INDIRECT_ACTION_EGRESS] = { 3923 .name = "egress", 3924 .help = "affect rule to egress", 3925 .next = NEXT(next_qia_create_attr), 3926 .call = parse_qia, 3927 }, 3928 [QUEUE_INDIRECT_ACTION_TRANSFER] = { 3929 .name = "transfer", 3930 .help = "affect rule to transfer", 3931 .next = NEXT(next_qia_create_attr), 3932 .call = parse_qia, 3933 }, 3934 [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { 3935 .name = "postpone", 3936 .help = "postpone create operation", 3937 .next = NEXT(next_qia_create_attr, 3938 NEXT_ENTRY(COMMON_BOOLEAN)), 3939 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3940 }, 3941 [QUEUE_INDIRECT_ACTION_SPEC] = { 3942 .name = "action", 3943 .help = "specify action to create indirect handle", 3944 .next = NEXT(next_action), 3945 }, 3946 [QUEUE_INDIRECT_ACTION_LIST] = { 3947 .name = "list", 3948 .help = "specify actions for indirect handle list", 3949 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 3950 .call = parse_qia, 3951 }, 3952 /* Top-level command. */ 3953 [PUSH] = { 3954 .name = "push", 3955 .help = "push enqueued operations", 3956 .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3957 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3958 .call = parse_push, 3959 }, 3960 /* Sub-level commands. */ 3961 [PUSH_QUEUE] = { 3962 .name = "queue", 3963 .help = "specify queue id", 3964 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3965 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3966 }, 3967 /* Top-level command. */ 3968 [PULL] = { 3969 .name = "pull", 3970 .help = "pull flow operations results", 3971 .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3972 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3973 .call = parse_pull, 3974 }, 3975 /* Sub-level commands. */ 3976 [PULL_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 [HASH] = { 3984 .name = "hash", 3985 .help = "calculate hash for a given pattern in a given template table", 3986 .next = NEXT(next_hash_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3987 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3988 .call = parse_hash, 3989 }, 3990 /* Sub-level commands. */ 3991 [HASH_CALC_TABLE] = { 3992 .name = "template_table", 3993 .help = "specify table id", 3994 .next = NEXT(NEXT_ENTRY(HASH_CALC_PATTERN_INDEX), 3995 NEXT_ENTRY(COMMON_TABLE_ID)), 3996 .args = ARGS(ARGS_ENTRY(struct buffer, 3997 args.vc.table_id)), 3998 .call = parse_hash, 3999 }, 4000 [HASH_CALC_ENCAP] = { 4001 .name = "encap", 4002 .help = "calculates encap hash", 4003 .next = NEXT(next_hash_encap_dest_subcmd), 4004 .call = parse_hash, 4005 }, 4006 [HASH_CALC_PATTERN_INDEX] = { 4007 .name = "pattern_template", 4008 .help = "specify pattern template id", 4009 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 4010 NEXT_ENTRY(COMMON_UNSIGNED)), 4011 .args = ARGS(ARGS_ENTRY(struct buffer, 4012 args.vc.pat_templ_id)), 4013 .call = parse_hash, 4014 }, 4015 [ENCAP_HASH_FIELD_SRC_PORT] = { 4016 .name = "hash_field_sport", 4017 .help = "the encap hash field is src port", 4018 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 4019 .call = parse_hash, 4020 }, 4021 [ENCAP_HASH_FIELD_GRE_FLOW_ID] = { 4022 .name = "hash_field_flow_id", 4023 .help = "the encap hash field is NVGRE flow id", 4024 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 4025 .call = parse_hash, 4026 }, 4027 /* Top-level command. */ 4028 [INDIRECT_ACTION] = { 4029 .name = "indirect_action", 4030 .type = "{command} {port_id} [{arg} [...]]", 4031 .help = "manage indirect actions", 4032 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4033 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4034 .call = parse_ia, 4035 }, 4036 /* Sub-level commands. */ 4037 [INDIRECT_ACTION_CREATE] = { 4038 .name = "create", 4039 .help = "create indirect action", 4040 .next = NEXT(next_ia_create_attr), 4041 .call = parse_ia, 4042 }, 4043 [INDIRECT_ACTION_UPDATE] = { 4044 .name = "update", 4045 .help = "update indirect action", 4046 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), 4047 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4048 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 4049 .call = parse_ia, 4050 }, 4051 [INDIRECT_ACTION_DESTROY] = { 4052 .name = "destroy", 4053 .help = "destroy indirect action", 4054 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), 4055 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4056 .call = parse_ia_destroy, 4057 }, 4058 [INDIRECT_ACTION_QUERY] = { 4059 .name = "query", 4060 .help = "query indirect action", 4061 .next = NEXT(NEXT_ENTRY(END), 4062 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4063 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4064 .call = parse_ia, 4065 }, 4066 [INDIRECT_ACTION_QUERY_UPDATE] = { 4067 .name = "query_update", 4068 .help = "query [and|or] update", 4069 .next = NEXT(next_ia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4070 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4071 .call = parse_ia 4072 }, 4073 [INDIRECT_ACTION_QU_MODE] = { 4074 .name = "mode", 4075 .help = "query_update mode", 4076 .next = NEXT(next_ia_qu_attr, 4077 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 4078 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 4079 .call = parse_ia, 4080 }, 4081 [INDIRECT_ACTION_QU_MODE_NAME] = { 4082 .name = "mode_name", 4083 .help = "query-update mode name", 4084 .call = parse_qu_mode_name, 4085 .comp = comp_qu_mode_name, 4086 }, 4087 [VALIDATE] = { 4088 .name = "validate", 4089 .help = "check whether a flow rule can be created", 4090 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4091 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4092 .call = parse_vc, 4093 }, 4094 [CREATE] = { 4095 .name = "create", 4096 .help = "create a flow rule", 4097 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4098 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4099 .call = parse_vc, 4100 }, 4101 [DESTROY] = { 4102 .name = "destroy", 4103 .help = "destroy specific flow rules", 4104 .next = NEXT(next_destroy_attr, 4105 NEXT_ENTRY(COMMON_PORT_ID)), 4106 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4107 .call = parse_destroy, 4108 }, 4109 [UPDATE] = { 4110 .name = "update", 4111 .help = "update a flow rule with new actions", 4112 .next = NEXT(NEXT_ENTRY(VC_IS_USER_ID, END), 4113 NEXT_ENTRY(ACTIONS), 4114 NEXT_ENTRY(COMMON_RULE_ID), 4115 NEXT_ENTRY(COMMON_PORT_ID)), 4116 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.rule_id), 4117 ARGS_ENTRY(struct buffer, port)), 4118 .call = parse_vc, 4119 }, 4120 [FLUSH] = { 4121 .name = "flush", 4122 .help = "destroy all flow rules", 4123 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4124 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4125 .call = parse_flush, 4126 }, 4127 [DUMP] = { 4128 .name = "dump", 4129 .help = "dump single/all flow rules to file", 4130 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4131 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4132 .call = parse_dump, 4133 }, 4134 [QUERY] = { 4135 .name = "query", 4136 .help = "query an existing flow rule", 4137 .next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION), 4138 NEXT_ENTRY(COMMON_RULE_ID), 4139 NEXT_ENTRY(COMMON_PORT_ID)), 4140 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), 4141 ARGS_ENTRY(struct buffer, args.query.rule), 4142 ARGS_ENTRY(struct buffer, port)), 4143 .call = parse_query, 4144 }, 4145 [LIST] = { 4146 .name = "list", 4147 .help = "list existing flow rules", 4148 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4149 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4150 .call = parse_list, 4151 }, 4152 [AGED] = { 4153 .name = "aged", 4154 .help = "list and destroy aged flows", 4155 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4156 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4157 .call = parse_aged, 4158 }, 4159 [ISOLATE] = { 4160 .name = "isolate", 4161 .help = "restrict ingress traffic to the defined flow rules", 4162 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), 4163 NEXT_ENTRY(COMMON_PORT_ID)), 4164 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), 4165 ARGS_ENTRY(struct buffer, port)), 4166 .call = parse_isolate, 4167 }, 4168 [FLEX] = { 4169 .name = "flex_item", 4170 .help = "flex item API", 4171 .next = NEXT(next_flex_item), 4172 .call = parse_flex, 4173 }, 4174 [FLEX_ITEM_INIT] = { 4175 .name = "init", 4176 .help = "flex item init", 4177 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4178 ARGS_ENTRY(struct buffer, port)), 4179 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4180 NEXT_ENTRY(COMMON_PORT_ID)), 4181 .call = parse_flex 4182 }, 4183 [FLEX_ITEM_CREATE] = { 4184 .name = "create", 4185 .help = "flex item create", 4186 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), 4187 ARGS_ENTRY(struct buffer, args.flex.token), 4188 ARGS_ENTRY(struct buffer, port)), 4189 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), 4190 NEXT_ENTRY(COMMON_FLEX_TOKEN), 4191 NEXT_ENTRY(COMMON_PORT_ID)), 4192 .call = parse_flex 4193 }, 4194 [FLEX_ITEM_DESTROY] = { 4195 .name = "destroy", 4196 .help = "flex item destroy", 4197 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4198 ARGS_ENTRY(struct buffer, port)), 4199 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4200 NEXT_ENTRY(COMMON_PORT_ID)), 4201 .call = parse_flex 4202 }, 4203 [TUNNEL] = { 4204 .name = "tunnel", 4205 .help = "new tunnel API", 4206 .next = NEXT(NEXT_ENTRY 4207 (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), 4208 .call = parse_tunnel, 4209 }, 4210 /* Tunnel arguments. */ 4211 [TUNNEL_CREATE] = { 4212 .name = "create", 4213 .help = "create new tunnel object", 4214 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), 4215 NEXT_ENTRY(COMMON_PORT_ID)), 4216 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4217 .call = parse_tunnel, 4218 }, 4219 [TUNNEL_CREATE_TYPE] = { 4220 .name = "type", 4221 .help = "create new tunnel", 4222 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), 4223 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), 4224 .call = parse_tunnel, 4225 }, 4226 [TUNNEL_DESTROY] = { 4227 .name = "destroy", 4228 .help = "destroy tunnel", 4229 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), 4230 NEXT_ENTRY(COMMON_PORT_ID)), 4231 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4232 .call = parse_tunnel, 4233 }, 4234 [TUNNEL_DESTROY_ID] = { 4235 .name = "id", 4236 .help = "tunnel identifier to destroy", 4237 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), 4238 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4239 .call = parse_tunnel, 4240 }, 4241 [TUNNEL_LIST] = { 4242 .name = "list", 4243 .help = "list existing tunnels", 4244 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4245 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4246 .call = parse_tunnel, 4247 }, 4248 /* Destroy arguments. */ 4249 [DESTROY_RULE] = { 4250 .name = "rule", 4251 .help = "specify a rule identifier", 4252 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4253 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), 4254 .call = parse_destroy, 4255 }, 4256 [DESTROY_IS_USER_ID] = { 4257 .name = "user_id", 4258 .help = "rule identifier is user-id", 4259 .next = NEXT(next_destroy_attr), 4260 .call = parse_destroy, 4261 }, 4262 /* Dump arguments. */ 4263 [DUMP_ALL] = { 4264 .name = "all", 4265 .help = "dump all", 4266 .next = NEXT(next_dump_attr), 4267 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), 4268 .call = parse_dump, 4269 }, 4270 [DUMP_ONE] = { 4271 .name = "rule", 4272 .help = "dump one rule", 4273 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4274 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), 4275 ARGS_ENTRY(struct buffer, args.dump.rule)), 4276 .call = parse_dump, 4277 }, 4278 [DUMP_IS_USER_ID] = { 4279 .name = "user_id", 4280 .help = "rule identifier is user-id", 4281 .next = NEXT(next_dump_subcmd), 4282 .call = parse_dump, 4283 }, 4284 /* Query arguments. */ 4285 [QUERY_ACTION] = { 4286 .name = "{action}", 4287 .type = "ACTION", 4288 .help = "action to query, must be part of the rule", 4289 .call = parse_action, 4290 .comp = comp_action, 4291 }, 4292 [QUERY_IS_USER_ID] = { 4293 .name = "user_id", 4294 .help = "rule identifier is user-id", 4295 .next = NEXT(next_query_attr), 4296 .call = parse_query, 4297 }, 4298 /* List arguments. */ 4299 [LIST_GROUP] = { 4300 .name = "group", 4301 .help = "specify a group", 4302 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4303 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), 4304 .call = parse_list, 4305 }, 4306 [AGED_DESTROY] = { 4307 .name = "destroy", 4308 .help = "specify aged flows need be destroyed", 4309 .call = parse_aged, 4310 .comp = comp_none, 4311 }, 4312 /* Validate/create attributes. */ 4313 [VC_GROUP] = { 4314 .name = "group", 4315 .help = "specify a group", 4316 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4317 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), 4318 .call = parse_vc, 4319 }, 4320 [VC_PRIORITY] = { 4321 .name = "priority", 4322 .help = "specify a priority level", 4323 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 4324 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), 4325 .call = parse_vc, 4326 }, 4327 [VC_INGRESS] = { 4328 .name = "ingress", 4329 .help = "affect rule to ingress", 4330 .next = NEXT(next_vc_attr), 4331 .call = parse_vc, 4332 }, 4333 [VC_EGRESS] = { 4334 .name = "egress", 4335 .help = "affect rule to egress", 4336 .next = NEXT(next_vc_attr), 4337 .call = parse_vc, 4338 }, 4339 [VC_TRANSFER] = { 4340 .name = "transfer", 4341 .help = "apply rule directly to endpoints found in pattern", 4342 .next = NEXT(next_vc_attr), 4343 .call = parse_vc, 4344 }, 4345 [VC_TUNNEL_SET] = { 4346 .name = "tunnel_set", 4347 .help = "tunnel steer rule", 4348 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4349 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4350 .call = parse_vc, 4351 }, 4352 [VC_TUNNEL_MATCH] = { 4353 .name = "tunnel_match", 4354 .help = "tunnel match rule", 4355 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4356 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4357 .call = parse_vc, 4358 }, 4359 [VC_USER_ID] = { 4360 .name = "user_id", 4361 .help = "specify a user id to create", 4362 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4363 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)), 4364 .call = parse_vc, 4365 }, 4366 [VC_IS_USER_ID] = { 4367 .name = "user_id", 4368 .help = "rule identifier is user-id", 4369 .call = parse_vc, 4370 }, 4371 /* Validate/create pattern. */ 4372 [ITEM_PATTERN] = { 4373 .name = "pattern", 4374 .help = "submit a list of pattern items", 4375 .next = NEXT(next_item), 4376 .call = parse_vc, 4377 }, 4378 [ITEM_PARAM_IS] = { 4379 .name = "is", 4380 .help = "match value perfectly (with full bit-mask)", 4381 .call = parse_vc_spec, 4382 }, 4383 [ITEM_PARAM_SPEC] = { 4384 .name = "spec", 4385 .help = "match value according to configured bit-mask", 4386 .call = parse_vc_spec, 4387 }, 4388 [ITEM_PARAM_LAST] = { 4389 .name = "last", 4390 .help = "specify upper bound to establish a range", 4391 .call = parse_vc_spec, 4392 }, 4393 [ITEM_PARAM_MASK] = { 4394 .name = "mask", 4395 .help = "specify bit-mask with relevant bits set to one", 4396 .call = parse_vc_spec, 4397 }, 4398 [ITEM_PARAM_PREFIX] = { 4399 .name = "prefix", 4400 .help = "generate bit-mask from a prefix length", 4401 .call = parse_vc_spec, 4402 }, 4403 [ITEM_NEXT] = { 4404 .name = "/", 4405 .help = "specify next pattern item", 4406 .next = NEXT(next_item), 4407 }, 4408 [ITEM_END] = { 4409 .name = "end", 4410 .help = "end list of pattern items", 4411 .priv = PRIV_ITEM(END, 0), 4412 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 4413 .call = parse_vc, 4414 }, 4415 [ITEM_VOID] = { 4416 .name = "void", 4417 .help = "no-op pattern item", 4418 .priv = PRIV_ITEM(VOID, 0), 4419 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4420 .call = parse_vc, 4421 }, 4422 [ITEM_INVERT] = { 4423 .name = "invert", 4424 .help = "perform actions when pattern does not match", 4425 .priv = PRIV_ITEM(INVERT, 0), 4426 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4427 .call = parse_vc, 4428 }, 4429 [ITEM_ANY] = { 4430 .name = "any", 4431 .help = "match any protocol for the current layer", 4432 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), 4433 .next = NEXT(item_any), 4434 .call = parse_vc, 4435 }, 4436 [ITEM_ANY_NUM] = { 4437 .name = "num", 4438 .help = "number of layers covered", 4439 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4440 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), 4441 }, 4442 [ITEM_PORT_ID] = { 4443 .name = "port_id", 4444 .help = "match traffic from/to a given DPDK port ID", 4445 .priv = PRIV_ITEM(PORT_ID, 4446 sizeof(struct rte_flow_item_port_id)), 4447 .next = NEXT(item_port_id), 4448 .call = parse_vc, 4449 }, 4450 [ITEM_PORT_ID_ID] = { 4451 .name = "id", 4452 .help = "DPDK port ID", 4453 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), 4454 item_param), 4455 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), 4456 }, 4457 [ITEM_MARK] = { 4458 .name = "mark", 4459 .help = "match traffic against value set in previously matched rule", 4460 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), 4461 .next = NEXT(item_mark), 4462 .call = parse_vc, 4463 }, 4464 [ITEM_MARK_ID] = { 4465 .name = "id", 4466 .help = "Integer value to match against", 4467 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), 4468 item_param), 4469 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), 4470 }, 4471 [ITEM_RAW] = { 4472 .name = "raw", 4473 .help = "match an arbitrary byte string", 4474 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), 4475 .next = NEXT(item_raw), 4476 .call = parse_vc, 4477 }, 4478 [ITEM_RAW_RELATIVE] = { 4479 .name = "relative", 4480 .help = "look for pattern after the previous item", 4481 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4482 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4483 relative, 1)), 4484 }, 4485 [ITEM_RAW_SEARCH] = { 4486 .name = "search", 4487 .help = "search pattern from offset (see also limit)", 4488 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4489 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4490 search, 1)), 4491 }, 4492 [ITEM_RAW_OFFSET] = { 4493 .name = "offset", 4494 .help = "absolute or relative offset for pattern", 4495 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), 4496 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), 4497 }, 4498 [ITEM_RAW_LIMIT] = { 4499 .name = "limit", 4500 .help = "search area limit for start of pattern", 4501 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4502 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), 4503 }, 4504 [ITEM_RAW_PATTERN] = { 4505 .name = "pattern", 4506 .help = "byte string to look for", 4507 .next = NEXT(item_raw, 4508 NEXT_ENTRY(COMMON_STRING), 4509 NEXT_ENTRY(ITEM_PARAM_IS, 4510 ITEM_PARAM_SPEC, 4511 ITEM_PARAM_MASK)), 4512 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4513 ARGS_ENTRY(struct rte_flow_item_raw, length), 4514 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4515 ITEM_RAW_PATTERN_SIZE)), 4516 }, 4517 [ITEM_RAW_PATTERN_HEX] = { 4518 .name = "pattern_hex", 4519 .help = "hex string to look for", 4520 .next = NEXT(item_raw, 4521 NEXT_ENTRY(COMMON_HEX), 4522 NEXT_ENTRY(ITEM_PARAM_IS, 4523 ITEM_PARAM_SPEC, 4524 ITEM_PARAM_MASK)), 4525 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4526 ARGS_ENTRY(struct rte_flow_item_raw, length), 4527 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4528 ITEM_RAW_PATTERN_SIZE)), 4529 }, 4530 [ITEM_ETH] = { 4531 .name = "eth", 4532 .help = "match Ethernet header", 4533 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), 4534 .next = NEXT(item_eth), 4535 .call = parse_vc, 4536 }, 4537 [ITEM_ETH_DST] = { 4538 .name = "dst", 4539 .help = "destination MAC", 4540 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4541 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), 4542 }, 4543 [ITEM_ETH_SRC] = { 4544 .name = "src", 4545 .help = "source 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.src_addr)), 4548 }, 4549 [ITEM_ETH_TYPE] = { 4550 .name = "type", 4551 .help = "EtherType", 4552 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4553 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), 4554 }, 4555 [ITEM_ETH_HAS_VLAN] = { 4556 .name = "has_vlan", 4557 .help = "packet header contains VLAN", 4558 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4559 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, 4560 has_vlan, 1)), 4561 }, 4562 [ITEM_VLAN] = { 4563 .name = "vlan", 4564 .help = "match 802.1Q/ad VLAN tag", 4565 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), 4566 .next = NEXT(item_vlan), 4567 .call = parse_vc, 4568 }, 4569 [ITEM_VLAN_TCI] = { 4570 .name = "tci", 4571 .help = "tag control information", 4572 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4573 item_param), 4574 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, hdr.vlan_tci)), 4575 }, 4576 [ITEM_VLAN_PCP] = { 4577 .name = "pcp", 4578 .help = "priority code point", 4579 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4580 item_param), 4581 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4582 hdr.vlan_tci, "\xe0\x00")), 4583 }, 4584 [ITEM_VLAN_DEI] = { 4585 .name = "dei", 4586 .help = "drop eligible indicator", 4587 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4588 item_param), 4589 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4590 hdr.vlan_tci, "\x10\x00")), 4591 }, 4592 [ITEM_VLAN_VID] = { 4593 .name = "vid", 4594 .help = "VLAN identifier", 4595 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4596 item_param), 4597 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4598 hdr.vlan_tci, "\x0f\xff")), 4599 }, 4600 [ITEM_VLAN_INNER_TYPE] = { 4601 .name = "inner_type", 4602 .help = "inner EtherType", 4603 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4604 item_param), 4605 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, 4606 hdr.eth_proto)), 4607 }, 4608 [ITEM_VLAN_HAS_MORE_VLAN] = { 4609 .name = "has_more_vlan", 4610 .help = "packet header contains another VLAN", 4611 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4612 item_param), 4613 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, 4614 has_more_vlan, 1)), 4615 }, 4616 [ITEM_IPV4] = { 4617 .name = "ipv4", 4618 .help = "match IPv4 header", 4619 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), 4620 .next = NEXT(item_ipv4), 4621 .call = parse_vc, 4622 }, 4623 [ITEM_IPV4_VER_IHL] = { 4624 .name = "version_ihl", 4625 .help = "match header length", 4626 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4627 item_param), 4628 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, 4629 hdr.version_ihl)), 4630 }, 4631 [ITEM_IPV4_TOS] = { 4632 .name = "tos", 4633 .help = "type of service", 4634 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4635 item_param), 4636 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4637 hdr.type_of_service)), 4638 }, 4639 [ITEM_IPV4_LENGTH] = { 4640 .name = "length", 4641 .help = "total length", 4642 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4643 item_param), 4644 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4645 hdr.total_length)), 4646 }, 4647 [ITEM_IPV4_ID] = { 4648 .name = "packet_id", 4649 .help = "fragment packet id", 4650 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4651 item_param), 4652 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4653 hdr.packet_id)), 4654 }, 4655 [ITEM_IPV4_FRAGMENT_OFFSET] = { 4656 .name = "fragment_offset", 4657 .help = "fragmentation flags and fragment offset", 4658 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4659 item_param), 4660 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4661 hdr.fragment_offset)), 4662 }, 4663 [ITEM_IPV4_TTL] = { 4664 .name = "ttl", 4665 .help = "time to live", 4666 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4667 item_param), 4668 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4669 hdr.time_to_live)), 4670 }, 4671 [ITEM_IPV4_PROTO] = { 4672 .name = "proto", 4673 .help = "next protocol ID", 4674 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4675 item_param), 4676 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4677 hdr.next_proto_id)), 4678 }, 4679 [ITEM_IPV4_SRC] = { 4680 .name = "src", 4681 .help = "source address", 4682 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4683 item_param), 4684 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4685 hdr.src_addr)), 4686 }, 4687 [ITEM_IPV4_DST] = { 4688 .name = "dst", 4689 .help = "destination address", 4690 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4691 item_param), 4692 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4693 hdr.dst_addr)), 4694 }, 4695 [ITEM_IPV6] = { 4696 .name = "ipv6", 4697 .help = "match IPv6 header", 4698 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), 4699 .next = NEXT(item_ipv6), 4700 .call = parse_vc, 4701 }, 4702 [ITEM_IPV6_TC] = { 4703 .name = "tc", 4704 .help = "traffic class", 4705 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4706 item_param), 4707 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4708 hdr.vtc_flow, 4709 "\x0f\xf0\x00\x00")), 4710 }, 4711 [ITEM_IPV6_FLOW] = { 4712 .name = "flow", 4713 .help = "flow label", 4714 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4715 item_param), 4716 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4717 hdr.vtc_flow, 4718 "\x00\x0f\xff\xff")), 4719 }, 4720 [ITEM_IPV6_LEN] = { 4721 .name = "length", 4722 .help = "payload length", 4723 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4724 item_param), 4725 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4726 hdr.payload_len)), 4727 }, 4728 [ITEM_IPV6_PROTO] = { 4729 .name = "proto", 4730 .help = "protocol (next header)", 4731 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4732 item_param), 4733 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4734 hdr.proto)), 4735 }, 4736 [ITEM_IPV6_HOP] = { 4737 .name = "hop", 4738 .help = "hop limit", 4739 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4740 item_param), 4741 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4742 hdr.hop_limits)), 4743 }, 4744 [ITEM_IPV6_SRC] = { 4745 .name = "src", 4746 .help = "source address", 4747 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4748 item_param), 4749 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4750 hdr.src_addr)), 4751 }, 4752 [ITEM_IPV6_DST] = { 4753 .name = "dst", 4754 .help = "destination address", 4755 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4756 item_param), 4757 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4758 hdr.dst_addr)), 4759 }, 4760 [ITEM_IPV6_HAS_FRAG_EXT] = { 4761 .name = "has_frag_ext", 4762 .help = "fragment packet attribute", 4763 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4764 item_param), 4765 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, 4766 has_frag_ext, 1)), 4767 }, 4768 [ITEM_IPV6_ROUTING_EXT] = { 4769 .name = "ipv6_routing_ext", 4770 .help = "match IPv6 routing extension header", 4771 .priv = PRIV_ITEM(IPV6_ROUTING_EXT, 4772 sizeof(struct rte_flow_item_ipv6_routing_ext)), 4773 .next = NEXT(item_ipv6_routing_ext), 4774 .call = parse_vc, 4775 }, 4776 [ITEM_IPV6_ROUTING_EXT_TYPE] = { 4777 .name = "ext_type", 4778 .help = "match IPv6 routing extension header type", 4779 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4780 item_param), 4781 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4782 hdr.type)), 4783 }, 4784 [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = { 4785 .name = "ext_next_hdr", 4786 .help = "match IPv6 routing extension header next header type", 4787 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4788 item_param), 4789 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4790 hdr.next_hdr)), 4791 }, 4792 [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = { 4793 .name = "ext_seg_left", 4794 .help = "match IPv6 routing extension header segment left", 4795 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4796 item_param), 4797 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4798 hdr.segments_left)), 4799 }, 4800 [ITEM_ICMP] = { 4801 .name = "icmp", 4802 .help = "match ICMP header", 4803 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), 4804 .next = NEXT(item_icmp), 4805 .call = parse_vc, 4806 }, 4807 [ITEM_ICMP_TYPE] = { 4808 .name = "type", 4809 .help = "ICMP packet type", 4810 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4811 item_param), 4812 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4813 hdr.icmp_type)), 4814 }, 4815 [ITEM_ICMP_CODE] = { 4816 .name = "code", 4817 .help = "ICMP packet code", 4818 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4819 item_param), 4820 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4821 hdr.icmp_code)), 4822 }, 4823 [ITEM_ICMP_IDENT] = { 4824 .name = "ident", 4825 .help = "ICMP packet identifier", 4826 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4827 item_param), 4828 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4829 hdr.icmp_ident)), 4830 }, 4831 [ITEM_ICMP_SEQ] = { 4832 .name = "seq", 4833 .help = "ICMP packet sequence number", 4834 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4835 item_param), 4836 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4837 hdr.icmp_seq_nb)), 4838 }, 4839 [ITEM_UDP] = { 4840 .name = "udp", 4841 .help = "match UDP header", 4842 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), 4843 .next = NEXT(item_udp), 4844 .call = parse_vc, 4845 }, 4846 [ITEM_UDP_SRC] = { 4847 .name = "src", 4848 .help = "UDP source port", 4849 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), 4850 item_param), 4851 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4852 hdr.src_port)), 4853 }, 4854 [ITEM_UDP_DST] = { 4855 .name = "dst", 4856 .help = "UDP destination port", 4857 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4858 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4859 hdr.dst_port)), 4860 }, 4861 [ITEM_TCP] = { 4862 .name = "tcp", 4863 .help = "match TCP header", 4864 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), 4865 .next = NEXT(item_tcp), 4866 .call = parse_vc, 4867 }, 4868 [ITEM_TCP_SRC] = { 4869 .name = "src", 4870 .help = "TCP source port", 4871 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4872 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4873 hdr.src_port)), 4874 }, 4875 [ITEM_TCP_DST] = { 4876 .name = "dst", 4877 .help = "TCP destination port", 4878 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4879 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4880 hdr.dst_port)), 4881 }, 4882 [ITEM_TCP_FLAGS] = { 4883 .name = "flags", 4884 .help = "TCP flags", 4885 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4886 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4887 hdr.tcp_flags)), 4888 }, 4889 [ITEM_SCTP] = { 4890 .name = "sctp", 4891 .help = "match SCTP header", 4892 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), 4893 .next = NEXT(item_sctp), 4894 .call = parse_vc, 4895 }, 4896 [ITEM_SCTP_SRC] = { 4897 .name = "src", 4898 .help = "SCTP source port", 4899 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4900 item_param), 4901 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4902 hdr.src_port)), 4903 }, 4904 [ITEM_SCTP_DST] = { 4905 .name = "dst", 4906 .help = "SCTP destination port", 4907 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4908 item_param), 4909 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4910 hdr.dst_port)), 4911 }, 4912 [ITEM_SCTP_TAG] = { 4913 .name = "tag", 4914 .help = "validation tag", 4915 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4916 item_param), 4917 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4918 hdr.tag)), 4919 }, 4920 [ITEM_SCTP_CKSUM] = { 4921 .name = "cksum", 4922 .help = "checksum", 4923 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4924 item_param), 4925 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4926 hdr.cksum)), 4927 }, 4928 [ITEM_VXLAN] = { 4929 .name = "vxlan", 4930 .help = "match VXLAN header", 4931 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), 4932 .next = NEXT(item_vxlan), 4933 .call = parse_vc, 4934 }, 4935 [ITEM_VXLAN_VNI] = { 4936 .name = "vni", 4937 .help = "VXLAN identifier", 4938 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4939 item_param), 4940 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), 4941 }, 4942 [ITEM_VXLAN_FLAG_G] = { 4943 .name = "flag_g", 4944 .help = "VXLAN GBP bit", 4945 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4946 item_param), 4947 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4948 hdr.flag_g, 1)), 4949 }, 4950 [ITEM_VXLAN_FLAG_VER] = { 4951 .name = "flag_ver", 4952 .help = "VXLAN GPE version", 4953 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4954 item_param), 4955 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4956 hdr.flag_ver, 2)), 4957 }, 4958 [ITEM_VXLAN_FLAG_I] = { 4959 .name = "flag_i", 4960 .help = "VXLAN Instance bit", 4961 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4962 item_param), 4963 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4964 hdr.flag_i, 1)), 4965 }, 4966 [ITEM_VXLAN_FLAG_P] = { 4967 .name = "flag_p", 4968 .help = "VXLAN GPE Next Protocol bit", 4969 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4970 item_param), 4971 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4972 hdr.flag_p, 1)), 4973 }, 4974 [ITEM_VXLAN_FLAG_B] = { 4975 .name = "flag_b", 4976 .help = "VXLAN GPE Ingress-Replicated BUM", 4977 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4978 item_param), 4979 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4980 hdr.flag_b, 1)), 4981 }, 4982 [ITEM_VXLAN_FLAG_O] = { 4983 .name = "flag_o", 4984 .help = "VXLAN GPE OAM Packet bit", 4985 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4986 item_param), 4987 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4988 hdr.flag_o, 1)), 4989 }, 4990 [ITEM_VXLAN_FLAG_D] = { 4991 .name = "flag_d", 4992 .help = "VXLAN GBP Don't Learn bit", 4993 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4994 item_param), 4995 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4996 hdr.flag_d, 1)), 4997 }, 4998 [ITEM_VXLAN_FLAG_A] = { 4999 .name = "flag_a", 5000 .help = "VXLAN GBP Applied bit", 5001 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5002 item_param), 5003 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 5004 hdr.flag_a, 1)), 5005 }, 5006 [ITEM_VXLAN_GBP_ID] = { 5007 .name = "group_policy_id", 5008 .help = "VXLAN GBP ID", 5009 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5010 item_param), 5011 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5012 hdr.policy_id)), 5013 }, 5014 [ITEM_VXLAN_GPE_PROTO] = { 5015 .name = "protocol", 5016 .help = "VXLAN GPE next protocol", 5017 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5018 item_param), 5019 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5020 hdr.proto)), 5021 }, 5022 [ITEM_VXLAN_FIRST_RSVD] = { 5023 .name = "first_rsvd", 5024 .help = "VXLAN rsvd0 first byte", 5025 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5026 item_param), 5027 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5028 hdr.rsvd0[0])), 5029 }, 5030 [ITEM_VXLAN_SECND_RSVD] = { 5031 .name = "second_rsvd", 5032 .help = "VXLAN rsvd0 second byte", 5033 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5034 item_param), 5035 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5036 hdr.rsvd0[1])), 5037 }, 5038 [ITEM_VXLAN_THIRD_RSVD] = { 5039 .name = "third_rsvd", 5040 .help = "VXLAN rsvd0 third byte", 5041 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5042 item_param), 5043 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5044 hdr.rsvd0[2])), 5045 }, 5046 [ITEM_VXLAN_LAST_RSVD] = { 5047 .name = "last_rsvd", 5048 .help = "VXLAN last reserved byte", 5049 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5050 item_param), 5051 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5052 hdr.last_rsvd)), 5053 }, 5054 [ITEM_E_TAG] = { 5055 .name = "e_tag", 5056 .help = "match E-Tag header", 5057 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), 5058 .next = NEXT(item_e_tag), 5059 .call = parse_vc, 5060 }, 5061 [ITEM_E_TAG_GRP_ECID_B] = { 5062 .name = "grp_ecid_b", 5063 .help = "GRP and E-CID base", 5064 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5065 item_param), 5066 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, 5067 rsvd_grp_ecid_b, 5068 "\x3f\xff")), 5069 }, 5070 [ITEM_NVGRE] = { 5071 .name = "nvgre", 5072 .help = "match NVGRE header", 5073 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), 5074 .next = NEXT(item_nvgre), 5075 .call = parse_vc, 5076 }, 5077 [ITEM_NVGRE_TNI] = { 5078 .name = "tni", 5079 .help = "virtual subnet ID", 5080 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), 5081 item_param), 5082 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), 5083 }, 5084 [ITEM_MPLS] = { 5085 .name = "mpls", 5086 .help = "match MPLS header", 5087 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), 5088 .next = NEXT(item_mpls), 5089 .call = parse_vc, 5090 }, 5091 [ITEM_MPLS_LABEL] = { 5092 .name = "label", 5093 .help = "MPLS label", 5094 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5095 item_param), 5096 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5097 label_tc_s, 5098 "\xff\xff\xf0")), 5099 }, 5100 [ITEM_MPLS_TC] = { 5101 .name = "tc", 5102 .help = "MPLS Traffic Class", 5103 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5104 item_param), 5105 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5106 label_tc_s, 5107 "\x00\x00\x0e")), 5108 }, 5109 [ITEM_MPLS_S] = { 5110 .name = "s", 5111 .help = "MPLS Bottom-of-Stack", 5112 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5113 item_param), 5114 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5115 label_tc_s, 5116 "\x00\x00\x01")), 5117 }, 5118 [ITEM_MPLS_TTL] = { 5119 .name = "ttl", 5120 .help = "MPLS Time-to-Live", 5121 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5122 item_param), 5123 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls, ttl)), 5124 }, 5125 [ITEM_GRE] = { 5126 .name = "gre", 5127 .help = "match GRE header", 5128 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), 5129 .next = NEXT(item_gre), 5130 .call = parse_vc, 5131 }, 5132 [ITEM_GRE_PROTO] = { 5133 .name = "protocol", 5134 .help = "GRE protocol type", 5135 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5136 item_param), 5137 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5138 protocol)), 5139 }, 5140 [ITEM_GRE_C_RSVD0_VER] = { 5141 .name = "c_rsvd0_ver", 5142 .help = 5143 "checksum (1b), undefined (1b), key bit (1b)," 5144 " sequence number (1b), reserved 0 (9b)," 5145 " version (3b)", 5146 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5147 item_param), 5148 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5149 c_rsvd0_ver)), 5150 }, 5151 [ITEM_GRE_C_BIT] = { 5152 .name = "c_bit", 5153 .help = "checksum bit (C)", 5154 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), 5155 item_param), 5156 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5157 c_rsvd0_ver, 5158 "\x80\x00\x00\x00")), 5159 }, 5160 [ITEM_GRE_S_BIT] = { 5161 .name = "s_bit", 5162 .help = "sequence number bit (S)", 5163 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5164 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5165 c_rsvd0_ver, 5166 "\x10\x00\x00\x00")), 5167 }, 5168 [ITEM_GRE_K_BIT] = { 5169 .name = "k_bit", 5170 .help = "key bit (K)", 5171 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5172 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5173 c_rsvd0_ver, 5174 "\x20\x00\x00\x00")), 5175 }, 5176 [ITEM_FUZZY] = { 5177 .name = "fuzzy", 5178 .help = "fuzzy pattern match, expect faster than default", 5179 .priv = PRIV_ITEM(FUZZY, 5180 sizeof(struct rte_flow_item_fuzzy)), 5181 .next = NEXT(item_fuzzy), 5182 .call = parse_vc, 5183 }, 5184 [ITEM_FUZZY_THRESH] = { 5185 .name = "thresh", 5186 .help = "match accuracy threshold", 5187 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), 5188 item_param), 5189 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, 5190 thresh)), 5191 }, 5192 [ITEM_GTP] = { 5193 .name = "gtp", 5194 .help = "match GTP header", 5195 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), 5196 .next = NEXT(item_gtp), 5197 .call = parse_vc, 5198 }, 5199 [ITEM_GTP_FLAGS] = { 5200 .name = "v_pt_rsv_flags", 5201 .help = "GTP flags", 5202 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5203 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, 5204 hdr.gtp_hdr_info)), 5205 }, 5206 [ITEM_GTP_MSG_TYPE] = { 5207 .name = "msg_type", 5208 .help = "GTP message type", 5209 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5210 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), 5211 }, 5212 [ITEM_GTP_TEID] = { 5213 .name = "teid", 5214 .help = "tunnel endpoint identifier", 5215 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5216 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), 5217 }, 5218 [ITEM_GTPC] = { 5219 .name = "gtpc", 5220 .help = "match GTP header", 5221 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), 5222 .next = NEXT(item_gtp), 5223 .call = parse_vc, 5224 }, 5225 [ITEM_GTPU] = { 5226 .name = "gtpu", 5227 .help = "match GTP header", 5228 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), 5229 .next = NEXT(item_gtp), 5230 .call = parse_vc, 5231 }, 5232 [ITEM_GENEVE] = { 5233 .name = "geneve", 5234 .help = "match GENEVE header", 5235 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), 5236 .next = NEXT(item_geneve), 5237 .call = parse_vc, 5238 }, 5239 [ITEM_GENEVE_VNI] = { 5240 .name = "vni", 5241 .help = "virtual network identifier", 5242 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5243 item_param), 5244 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), 5245 }, 5246 [ITEM_GENEVE_PROTO] = { 5247 .name = "protocol", 5248 .help = "GENEVE protocol type", 5249 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5250 item_param), 5251 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, 5252 protocol)), 5253 }, 5254 [ITEM_GENEVE_OPTLEN] = { 5255 .name = "optlen", 5256 .help = "GENEVE options length in dwords", 5257 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5258 item_param), 5259 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, 5260 ver_opt_len_o_c_rsvd0, 5261 "\x3f\x00")), 5262 }, 5263 [ITEM_VXLAN_GPE] = { 5264 .name = "vxlan-gpe", 5265 .help = "match VXLAN-GPE header", 5266 .priv = PRIV_ITEM(VXLAN_GPE, 5267 sizeof(struct rte_flow_item_vxlan_gpe)), 5268 .next = NEXT(item_vxlan_gpe), 5269 .call = parse_vc, 5270 }, 5271 [ITEM_VXLAN_GPE_VNI] = { 5272 .name = "vni", 5273 .help = "VXLAN-GPE identifier", 5274 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5275 item_param), 5276 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5277 hdr.vni)), 5278 }, 5279 [ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR] = { 5280 .name = "protocol", 5281 .help = "VXLAN-GPE next protocol", 5282 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5283 item_param), 5284 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5285 protocol)), 5286 }, 5287 [ITEM_VXLAN_GPE_FLAGS] = { 5288 .name = "flags", 5289 .help = "VXLAN-GPE flags", 5290 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5291 item_param), 5292 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5293 flags)), 5294 }, 5295 [ITEM_VXLAN_GPE_RSVD0] = { 5296 .name = "rsvd0", 5297 .help = "VXLAN-GPE rsvd0", 5298 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5299 item_param), 5300 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5301 rsvd0)), 5302 }, 5303 [ITEM_VXLAN_GPE_RSVD1] = { 5304 .name = "rsvd1", 5305 .help = "VXLAN-GPE rsvd1", 5306 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5307 item_param), 5308 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5309 rsvd1)), 5310 }, 5311 [ITEM_ARP_ETH_IPV4] = { 5312 .name = "arp_eth_ipv4", 5313 .help = "match ARP header for Ethernet/IPv4", 5314 .priv = PRIV_ITEM(ARP_ETH_IPV4, 5315 sizeof(struct rte_flow_item_arp_eth_ipv4)), 5316 .next = NEXT(item_arp_eth_ipv4), 5317 .call = parse_vc, 5318 }, 5319 [ITEM_ARP_ETH_IPV4_SHA] = { 5320 .name = "sha", 5321 .help = "sender hardware address", 5322 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5323 item_param), 5324 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5325 hdr.arp_data.arp_sha)), 5326 }, 5327 [ITEM_ARP_ETH_IPV4_SPA] = { 5328 .name = "spa", 5329 .help = "sender IPv4 address", 5330 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5331 item_param), 5332 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5333 hdr.arp_data.arp_sip)), 5334 }, 5335 [ITEM_ARP_ETH_IPV4_THA] = { 5336 .name = "tha", 5337 .help = "target hardware address", 5338 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5339 item_param), 5340 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5341 hdr.arp_data.arp_tha)), 5342 }, 5343 [ITEM_ARP_ETH_IPV4_TPA] = { 5344 .name = "tpa", 5345 .help = "target IPv4 address", 5346 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5347 item_param), 5348 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5349 hdr.arp_data.arp_tip)), 5350 }, 5351 [ITEM_IPV6_EXT] = { 5352 .name = "ipv6_ext", 5353 .help = "match presence of any IPv6 extension header", 5354 .priv = PRIV_ITEM(IPV6_EXT, 5355 sizeof(struct rte_flow_item_ipv6_ext)), 5356 .next = NEXT(item_ipv6_ext), 5357 .call = parse_vc, 5358 }, 5359 [ITEM_IPV6_EXT_NEXT_HDR] = { 5360 .name = "next_hdr", 5361 .help = "next header", 5362 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5363 item_param), 5364 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 5365 next_hdr)), 5366 }, 5367 [ITEM_IPV6_FRAG_EXT] = { 5368 .name = "ipv6_frag_ext", 5369 .help = "match presence of IPv6 fragment extension header", 5370 .priv = PRIV_ITEM(IPV6_FRAG_EXT, 5371 sizeof(struct rte_flow_item_ipv6_frag_ext)), 5372 .next = NEXT(item_ipv6_frag_ext), 5373 .call = parse_vc, 5374 }, 5375 [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { 5376 .name = "next_hdr", 5377 .help = "next header", 5378 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5379 item_param), 5380 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, 5381 hdr.next_header)), 5382 }, 5383 [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { 5384 .name = "frag_data", 5385 .help = "fragment flags and offset", 5386 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5387 item_param), 5388 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5389 hdr.frag_data)), 5390 }, 5391 [ITEM_IPV6_FRAG_EXT_ID] = { 5392 .name = "packet_id", 5393 .help = "fragment packet id", 5394 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5395 item_param), 5396 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5397 hdr.id)), 5398 }, 5399 [ITEM_ICMP6] = { 5400 .name = "icmp6", 5401 .help = "match any ICMPv6 header", 5402 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), 5403 .next = NEXT(item_icmp6), 5404 .call = parse_vc, 5405 }, 5406 [ITEM_ICMP6_TYPE] = { 5407 .name = "type", 5408 .help = "ICMPv6 type", 5409 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5410 item_param), 5411 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5412 type)), 5413 }, 5414 [ITEM_ICMP6_CODE] = { 5415 .name = "code", 5416 .help = "ICMPv6 code", 5417 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5418 item_param), 5419 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5420 code)), 5421 }, 5422 [ITEM_ICMP6_ECHO_REQUEST] = { 5423 .name = "icmp6_echo_request", 5424 .help = "match ICMPv6 echo request", 5425 .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, 5426 sizeof(struct rte_flow_item_icmp6_echo)), 5427 .next = NEXT(item_icmp6_echo_request), 5428 .call = parse_vc, 5429 }, 5430 [ITEM_ICMP6_ECHO_REQUEST_ID] = { 5431 .name = "ident", 5432 .help = "ICMPv6 echo request identifier", 5433 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5434 item_param), 5435 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5436 hdr.identifier)), 5437 }, 5438 [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { 5439 .name = "seq", 5440 .help = "ICMPv6 echo request sequence", 5441 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5442 item_param), 5443 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5444 hdr.sequence)), 5445 }, 5446 [ITEM_ICMP6_ECHO_REPLY] = { 5447 .name = "icmp6_echo_reply", 5448 .help = "match ICMPv6 echo reply", 5449 .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, 5450 sizeof(struct rte_flow_item_icmp6_echo)), 5451 .next = NEXT(item_icmp6_echo_reply), 5452 .call = parse_vc, 5453 }, 5454 [ITEM_ICMP6_ECHO_REPLY_ID] = { 5455 .name = "ident", 5456 .help = "ICMPv6 echo reply identifier", 5457 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5458 item_param), 5459 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5460 hdr.identifier)), 5461 }, 5462 [ITEM_ICMP6_ECHO_REPLY_SEQ] = { 5463 .name = "seq", 5464 .help = "ICMPv6 echo reply sequence", 5465 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5466 item_param), 5467 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5468 hdr.sequence)), 5469 }, 5470 [ITEM_ICMP6_ND_NS] = { 5471 .name = "icmp6_nd_ns", 5472 .help = "match ICMPv6 neighbor discovery solicitation", 5473 .priv = PRIV_ITEM(ICMP6_ND_NS, 5474 sizeof(struct rte_flow_item_icmp6_nd_ns)), 5475 .next = NEXT(item_icmp6_nd_ns), 5476 .call = parse_vc, 5477 }, 5478 [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { 5479 .name = "target_addr", 5480 .help = "target address", 5481 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), 5482 item_param), 5483 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, 5484 target_addr)), 5485 }, 5486 [ITEM_ICMP6_ND_NA] = { 5487 .name = "icmp6_nd_na", 5488 .help = "match ICMPv6 neighbor discovery advertisement", 5489 .priv = PRIV_ITEM(ICMP6_ND_NA, 5490 sizeof(struct rte_flow_item_icmp6_nd_na)), 5491 .next = NEXT(item_icmp6_nd_na), 5492 .call = parse_vc, 5493 }, 5494 [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { 5495 .name = "target_addr", 5496 .help = "target address", 5497 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), 5498 item_param), 5499 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, 5500 target_addr)), 5501 }, 5502 [ITEM_ICMP6_ND_OPT] = { 5503 .name = "icmp6_nd_opt", 5504 .help = "match presence of any ICMPv6 neighbor discovery" 5505 " option", 5506 .priv = PRIV_ITEM(ICMP6_ND_OPT, 5507 sizeof(struct rte_flow_item_icmp6_nd_opt)), 5508 .next = NEXT(item_icmp6_nd_opt), 5509 .call = parse_vc, 5510 }, 5511 [ITEM_ICMP6_ND_OPT_TYPE] = { 5512 .name = "type", 5513 .help = "ND option type", 5514 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5515 item_param), 5516 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, 5517 type)), 5518 }, 5519 [ITEM_ICMP6_ND_OPT_SLA_ETH] = { 5520 .name = "icmp6_nd_opt_sla_eth", 5521 .help = "match ICMPv6 neighbor discovery source Ethernet" 5522 " link-layer address option", 5523 .priv = PRIV_ITEM 5524 (ICMP6_ND_OPT_SLA_ETH, 5525 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), 5526 .next = NEXT(item_icmp6_nd_opt_sla_eth), 5527 .call = parse_vc, 5528 }, 5529 [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { 5530 .name = "sla", 5531 .help = "source Ethernet LLA", 5532 .next = NEXT(item_icmp6_nd_opt_sla_eth, 5533 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5534 .args = ARGS(ARGS_ENTRY_HTON 5535 (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), 5536 }, 5537 [ITEM_ICMP6_ND_OPT_TLA_ETH] = { 5538 .name = "icmp6_nd_opt_tla_eth", 5539 .help = "match ICMPv6 neighbor discovery target Ethernet" 5540 " link-layer address option", 5541 .priv = PRIV_ITEM 5542 (ICMP6_ND_OPT_TLA_ETH, 5543 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), 5544 .next = NEXT(item_icmp6_nd_opt_tla_eth), 5545 .call = parse_vc, 5546 }, 5547 [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { 5548 .name = "tla", 5549 .help = "target Ethernet LLA", 5550 .next = NEXT(item_icmp6_nd_opt_tla_eth, 5551 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5552 .args = ARGS(ARGS_ENTRY_HTON 5553 (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), 5554 }, 5555 [ITEM_META] = { 5556 .name = "meta", 5557 .help = "match metadata header", 5558 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), 5559 .next = NEXT(item_meta), 5560 .call = parse_vc, 5561 }, 5562 [ITEM_META_DATA] = { 5563 .name = "data", 5564 .help = "metadata value", 5565 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), 5566 item_param), 5567 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, 5568 data, "\xff\xff\xff\xff")), 5569 }, 5570 [ITEM_RANDOM] = { 5571 .name = "random", 5572 .help = "match random value", 5573 .priv = PRIV_ITEM(RANDOM, sizeof(struct rte_flow_item_random)), 5574 .next = NEXT(item_random), 5575 .call = parse_vc, 5576 }, 5577 [ITEM_RANDOM_VALUE] = { 5578 .name = "value", 5579 .help = "random value", 5580 .next = NEXT(item_random, NEXT_ENTRY(COMMON_UNSIGNED), 5581 item_param), 5582 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_random, 5583 value, "\xff\xff")), 5584 }, 5585 [ITEM_GRE_KEY] = { 5586 .name = "gre_key", 5587 .help = "match GRE key", 5588 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), 5589 .next = NEXT(item_gre_key), 5590 .call = parse_vc, 5591 }, 5592 [ITEM_GRE_KEY_VALUE] = { 5593 .name = "value", 5594 .help = "key value", 5595 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), 5596 item_param), 5597 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5598 }, 5599 [ITEM_GRE_OPTION] = { 5600 .name = "gre_option", 5601 .help = "match GRE optional fields", 5602 .priv = PRIV_ITEM(GRE_OPTION, 5603 sizeof(struct rte_flow_item_gre_opt)), 5604 .next = NEXT(item_gre_option), 5605 .call = parse_vc, 5606 }, 5607 [ITEM_GRE_OPTION_CHECKSUM] = { 5608 .name = "checksum", 5609 .help = "match GRE checksum", 5610 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5611 item_param), 5612 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5613 checksum_rsvd.checksum)), 5614 }, 5615 [ITEM_GRE_OPTION_KEY] = { 5616 .name = "key", 5617 .help = "match GRE key", 5618 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5619 item_param), 5620 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5621 key.key)), 5622 }, 5623 [ITEM_GRE_OPTION_SEQUENCE] = { 5624 .name = "sequence", 5625 .help = "match GRE sequence", 5626 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5627 item_param), 5628 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5629 sequence.sequence)), 5630 }, 5631 [ITEM_GTP_PSC] = { 5632 .name = "gtp_psc", 5633 .help = "match GTP extension header with type 0x85", 5634 .priv = PRIV_ITEM(GTP_PSC, 5635 sizeof(struct rte_flow_item_gtp_psc)), 5636 .next = NEXT(item_gtp_psc), 5637 .call = parse_vc, 5638 }, 5639 [ITEM_GTP_PSC_QFI] = { 5640 .name = "qfi", 5641 .help = "QoS flow identifier", 5642 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5643 item_param), 5644 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5645 hdr.qfi, 6)), 5646 }, 5647 [ITEM_GTP_PSC_PDU_T] = { 5648 .name = "pdu_t", 5649 .help = "PDU type", 5650 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5651 item_param), 5652 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5653 hdr.type, 4)), 5654 }, 5655 [ITEM_PPPOES] = { 5656 .name = "pppoes", 5657 .help = "match PPPoE session header", 5658 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), 5659 .next = NEXT(item_pppoes), 5660 .call = parse_vc, 5661 }, 5662 [ITEM_PPPOED] = { 5663 .name = "pppoed", 5664 .help = "match PPPoE discovery header", 5665 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), 5666 .next = NEXT(item_pppoed), 5667 .call = parse_vc, 5668 }, 5669 [ITEM_PPPOE_SEID] = { 5670 .name = "seid", 5671 .help = "session identifier", 5672 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), 5673 item_param), 5674 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, 5675 session_id)), 5676 }, 5677 [ITEM_PPPOE_PROTO_ID] = { 5678 .name = "pppoe_proto_id", 5679 .help = "match PPPoE session protocol identifier", 5680 .priv = PRIV_ITEM(PPPOE_PROTO_ID, 5681 sizeof(struct rte_flow_item_pppoe_proto_id)), 5682 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED), 5683 item_param), 5684 .args = ARGS(ARGS_ENTRY_HTON 5685 (struct rte_flow_item_pppoe_proto_id, proto_id)), 5686 .call = parse_vc, 5687 }, 5688 [ITEM_HIGIG2] = { 5689 .name = "higig2", 5690 .help = "matches higig2 header", 5691 .priv = PRIV_ITEM(HIGIG2, 5692 sizeof(struct rte_flow_item_higig2_hdr)), 5693 .next = NEXT(item_higig2), 5694 .call = parse_vc, 5695 }, 5696 [ITEM_HIGIG2_CLASSIFICATION] = { 5697 .name = "classification", 5698 .help = "matches classification of higig2 header", 5699 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5700 item_param), 5701 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5702 hdr.ppt1.classification)), 5703 }, 5704 [ITEM_HIGIG2_VID] = { 5705 .name = "vid", 5706 .help = "matches vid of higig2 header", 5707 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5708 item_param), 5709 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5710 hdr.ppt1.vid)), 5711 }, 5712 [ITEM_TAG] = { 5713 .name = "tag", 5714 .help = "match tag value", 5715 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), 5716 .next = NEXT(item_tag), 5717 .call = parse_vc, 5718 }, 5719 [ITEM_TAG_DATA] = { 5720 .name = "data", 5721 .help = "tag value to match", 5722 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5723 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), 5724 }, 5725 [ITEM_TAG_INDEX] = { 5726 .name = "index", 5727 .help = "index of tag array to match", 5728 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5729 NEXT_ENTRY(ITEM_PARAM_IS)), 5730 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), 5731 }, 5732 [ITEM_L2TPV3OIP] = { 5733 .name = "l2tpv3oip", 5734 .help = "match L2TPv3 over IP header", 5735 .priv = PRIV_ITEM(L2TPV3OIP, 5736 sizeof(struct rte_flow_item_l2tpv3oip)), 5737 .next = NEXT(item_l2tpv3oip), 5738 .call = parse_vc, 5739 }, 5740 [ITEM_L2TPV3OIP_SESSION_ID] = { 5741 .name = "session_id", 5742 .help = "session identifier", 5743 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), 5744 item_param), 5745 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, 5746 session_id)), 5747 }, 5748 [ITEM_ESP] = { 5749 .name = "esp", 5750 .help = "match ESP header", 5751 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), 5752 .next = NEXT(item_esp), 5753 .call = parse_vc, 5754 }, 5755 [ITEM_ESP_SPI] = { 5756 .name = "spi", 5757 .help = "security policy index", 5758 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5759 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, 5760 hdr.spi)), 5761 }, 5762 [ITEM_AH] = { 5763 .name = "ah", 5764 .help = "match AH header", 5765 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), 5766 .next = NEXT(item_ah), 5767 .call = parse_vc, 5768 }, 5769 [ITEM_AH_SPI] = { 5770 .name = "spi", 5771 .help = "security parameters index", 5772 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5773 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), 5774 }, 5775 [ITEM_PFCP] = { 5776 .name = "pfcp", 5777 .help = "match pfcp header", 5778 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), 5779 .next = NEXT(item_pfcp), 5780 .call = parse_vc, 5781 }, 5782 [ITEM_PFCP_S_FIELD] = { 5783 .name = "s_field", 5784 .help = "S field", 5785 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5786 item_param), 5787 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, 5788 s_field)), 5789 }, 5790 [ITEM_PFCP_SEID] = { 5791 .name = "seid", 5792 .help = "session endpoint identifier", 5793 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5794 item_param), 5795 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), 5796 }, 5797 [ITEM_ECPRI] = { 5798 .name = "ecpri", 5799 .help = "match eCPRI header", 5800 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), 5801 .next = NEXT(item_ecpri), 5802 .call = parse_vc, 5803 }, 5804 [ITEM_ECPRI_COMMON] = { 5805 .name = "common", 5806 .help = "eCPRI common header", 5807 .next = NEXT(item_ecpri_common), 5808 }, 5809 [ITEM_ECPRI_COMMON_TYPE] = { 5810 .name = "type", 5811 .help = "type of common header", 5812 .next = NEXT(item_ecpri_common_type), 5813 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), 5814 }, 5815 [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { 5816 .name = "iq_data", 5817 .help = "Type #0: IQ Data", 5818 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5819 ITEM_NEXT)), 5820 .call = parse_vc_item_ecpri_type, 5821 }, 5822 [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { 5823 .name = "pc_id", 5824 .help = "Physical Channel ID", 5825 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5826 ITEM_ECPRI_COMMON, ITEM_NEXT), 5827 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5828 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5829 hdr.type0.pc_id)), 5830 }, 5831 [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { 5832 .name = "rtc_ctrl", 5833 .help = "Type #2: Real-Time Control Data", 5834 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5835 ITEM_NEXT)), 5836 .call = parse_vc_item_ecpri_type, 5837 }, 5838 [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { 5839 .name = "rtc_id", 5840 .help = "Real-Time Control Data ID", 5841 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5842 ITEM_ECPRI_COMMON, ITEM_NEXT), 5843 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5844 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5845 hdr.type2.rtc_id)), 5846 }, 5847 [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { 5848 .name = "delay_measure", 5849 .help = "Type #5: One-Way Delay Measurement", 5850 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5851 ITEM_NEXT)), 5852 .call = parse_vc_item_ecpri_type, 5853 }, 5854 [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { 5855 .name = "msr_id", 5856 .help = "Measurement ID", 5857 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5858 ITEM_ECPRI_COMMON, ITEM_NEXT), 5859 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5860 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5861 hdr.type5.msr_id)), 5862 }, 5863 [ITEM_GENEVE_OPT] = { 5864 .name = "geneve-opt", 5865 .help = "GENEVE header option", 5866 .priv = PRIV_ITEM(GENEVE_OPT, 5867 sizeof(struct rte_flow_item_geneve_opt) + 5868 ITEM_GENEVE_OPT_DATA_SIZE), 5869 .next = NEXT(item_geneve_opt), 5870 .call = parse_vc, 5871 }, 5872 [ITEM_GENEVE_OPT_CLASS] = { 5873 .name = "class", 5874 .help = "GENEVE option class", 5875 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5876 item_param), 5877 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, 5878 option_class)), 5879 }, 5880 [ITEM_GENEVE_OPT_TYPE] = { 5881 .name = "type", 5882 .help = "GENEVE option type", 5883 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5884 item_param), 5885 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, 5886 option_type)), 5887 }, 5888 [ITEM_GENEVE_OPT_LENGTH] = { 5889 .name = "length", 5890 .help = "GENEVE option data length (in 32b words)", 5891 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5892 item_param), 5893 .args = ARGS(ARGS_ENTRY_BOUNDED( 5894 struct rte_flow_item_geneve_opt, option_len, 5895 0, 31)), 5896 }, 5897 [ITEM_GENEVE_OPT_DATA] = { 5898 .name = "data", 5899 .help = "GENEVE option data pattern", 5900 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), 5901 item_param), 5902 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), 5903 ARGS_ENTRY_ARB(0, 0), 5904 ARGS_ENTRY_ARB 5905 (sizeof(struct rte_flow_item_geneve_opt), 5906 ITEM_GENEVE_OPT_DATA_SIZE)), 5907 }, 5908 [ITEM_INTEGRITY] = { 5909 .name = "integrity", 5910 .help = "match packet integrity", 5911 .priv = PRIV_ITEM(INTEGRITY, 5912 sizeof(struct rte_flow_item_integrity)), 5913 .next = NEXT(item_integrity), 5914 .call = parse_vc, 5915 }, 5916 [ITEM_INTEGRITY_LEVEL] = { 5917 .name = "level", 5918 .help = "integrity level", 5919 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5920 item_param), 5921 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), 5922 }, 5923 [ITEM_INTEGRITY_VALUE] = { 5924 .name = "value", 5925 .help = "integrity value", 5926 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5927 item_param), 5928 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), 5929 }, 5930 [ITEM_CONNTRACK] = { 5931 .name = "conntrack", 5932 .help = "conntrack state", 5933 .priv = PRIV_ITEM(CONNTRACK, 5934 sizeof(struct rte_flow_item_conntrack)), 5935 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 5936 item_param), 5937 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 5938 .call = parse_vc, 5939 }, 5940 [ITEM_PORT_REPRESENTOR] = { 5941 .name = "port_representor", 5942 .help = "match traffic entering the embedded switch from the given ethdev", 5943 .priv = PRIV_ITEM(PORT_REPRESENTOR, 5944 sizeof(struct rte_flow_item_ethdev)), 5945 .next = NEXT(item_port_representor), 5946 .call = parse_vc, 5947 }, 5948 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 5949 .name = "port_id", 5950 .help = "ethdev port ID", 5951 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 5952 item_param), 5953 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5954 }, 5955 [ITEM_REPRESENTED_PORT] = { 5956 .name = "represented_port", 5957 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 5958 .priv = PRIV_ITEM(REPRESENTED_PORT, 5959 sizeof(struct rte_flow_item_ethdev)), 5960 .next = NEXT(item_represented_port), 5961 .call = parse_vc, 5962 }, 5963 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 5964 .name = "ethdev_port_id", 5965 .help = "ethdev port ID", 5966 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 5967 item_param), 5968 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5969 }, 5970 [ITEM_FLEX] = { 5971 .name = "flex", 5972 .help = "match flex header", 5973 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 5974 .next = NEXT(item_flex), 5975 .call = parse_vc, 5976 }, 5977 [ITEM_FLEX_ITEM_HANDLE] = { 5978 .name = "item", 5979 .help = "flex item handle", 5980 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5981 NEXT_ENTRY(ITEM_PARAM_IS)), 5982 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 5983 }, 5984 [ITEM_FLEX_PATTERN_HANDLE] = { 5985 .name = "pattern", 5986 .help = "flex pattern handle", 5987 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5988 NEXT_ENTRY(ITEM_PARAM_IS)), 5989 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 5990 }, 5991 [ITEM_L2TPV2] = { 5992 .name = "l2tpv2", 5993 .help = "match L2TPv2 header", 5994 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 5995 .next = NEXT(item_l2tpv2), 5996 .call = parse_vc, 5997 }, 5998 [ITEM_L2TPV2_TYPE] = { 5999 .name = "type", 6000 .help = "type of l2tpv2", 6001 .next = NEXT(item_l2tpv2_type), 6002 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 6003 }, 6004 [ITEM_L2TPV2_TYPE_DATA] = { 6005 .name = "data", 6006 .help = "Type #7: data message without any options", 6007 .next = NEXT(item_l2tpv2_type_data), 6008 .call = parse_vc_item_l2tpv2_type, 6009 }, 6010 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 6011 .name = "tunnel_id", 6012 .help = "tunnel identifier", 6013 .next = NEXT(item_l2tpv2_type_data, 6014 NEXT_ENTRY(COMMON_UNSIGNED), 6015 item_param), 6016 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6017 hdr.type7.tunnel_id)), 6018 }, 6019 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 6020 .name = "session_id", 6021 .help = "session identifier", 6022 .next = NEXT(item_l2tpv2_type_data, 6023 NEXT_ENTRY(COMMON_UNSIGNED), 6024 item_param), 6025 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6026 hdr.type7.session_id)), 6027 }, 6028 [ITEM_L2TPV2_TYPE_DATA_L] = { 6029 .name = "data_l", 6030 .help = "Type #6: data message with length option", 6031 .next = NEXT(item_l2tpv2_type_data_l), 6032 .call = parse_vc_item_l2tpv2_type, 6033 }, 6034 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 6035 .name = "length", 6036 .help = "message length", 6037 .next = NEXT(item_l2tpv2_type_data_l, 6038 NEXT_ENTRY(COMMON_UNSIGNED), 6039 item_param), 6040 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6041 hdr.type6.length)), 6042 }, 6043 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 6044 .name = "tunnel_id", 6045 .help = "tunnel identifier", 6046 .next = NEXT(item_l2tpv2_type_data_l, 6047 NEXT_ENTRY(COMMON_UNSIGNED), 6048 item_param), 6049 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6050 hdr.type6.tunnel_id)), 6051 }, 6052 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 6053 .name = "session_id", 6054 .help = "session identifier", 6055 .next = NEXT(item_l2tpv2_type_data_l, 6056 NEXT_ENTRY(COMMON_UNSIGNED), 6057 item_param), 6058 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6059 hdr.type6.session_id)), 6060 }, 6061 [ITEM_L2TPV2_TYPE_DATA_S] = { 6062 .name = "data_s", 6063 .help = "Type #5: data message with ns, nr option", 6064 .next = NEXT(item_l2tpv2_type_data_s), 6065 .call = parse_vc_item_l2tpv2_type, 6066 }, 6067 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 6068 .name = "tunnel_id", 6069 .help = "tunnel identifier", 6070 .next = NEXT(item_l2tpv2_type_data_s, 6071 NEXT_ENTRY(COMMON_UNSIGNED), 6072 item_param), 6073 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6074 hdr.type5.tunnel_id)), 6075 }, 6076 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 6077 .name = "session_id", 6078 .help = "session identifier", 6079 .next = NEXT(item_l2tpv2_type_data_s, 6080 NEXT_ENTRY(COMMON_UNSIGNED), 6081 item_param), 6082 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6083 hdr.type5.session_id)), 6084 }, 6085 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 6086 .name = "ns", 6087 .help = "sequence number for message", 6088 .next = NEXT(item_l2tpv2_type_data_s, 6089 NEXT_ENTRY(COMMON_UNSIGNED), 6090 item_param), 6091 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6092 hdr.type5.ns)), 6093 }, 6094 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 6095 .name = "nr", 6096 .help = "sequence number for next receive message", 6097 .next = NEXT(item_l2tpv2_type_data_s, 6098 NEXT_ENTRY(COMMON_UNSIGNED), 6099 item_param), 6100 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6101 hdr.type5.nr)), 6102 }, 6103 [ITEM_L2TPV2_TYPE_DATA_O] = { 6104 .name = "data_o", 6105 .help = "Type #4: data message with offset option", 6106 .next = NEXT(item_l2tpv2_type_data_o), 6107 .call = parse_vc_item_l2tpv2_type, 6108 }, 6109 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 6110 .name = "tunnel_id", 6111 .help = "tunnel identifier", 6112 .next = NEXT(item_l2tpv2_type_data_o, 6113 NEXT_ENTRY(COMMON_UNSIGNED), 6114 item_param), 6115 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6116 hdr.type4.tunnel_id)), 6117 }, 6118 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 6119 .name = "session_id", 6120 .help = "session identifier", 6121 .next = NEXT(item_l2tpv2_type_data_o, 6122 NEXT_ENTRY(COMMON_UNSIGNED), 6123 item_param), 6124 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6125 hdr.type5.session_id)), 6126 }, 6127 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 6128 .name = "offset_size", 6129 .help = "the size of offset padding", 6130 .next = NEXT(item_l2tpv2_type_data_o, 6131 NEXT_ENTRY(COMMON_UNSIGNED), 6132 item_param), 6133 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6134 hdr.type4.offset_size)), 6135 }, 6136 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 6137 .name = "data_l_s", 6138 .help = "Type #3: data message contains length, ns, nr " 6139 "options", 6140 .next = NEXT(item_l2tpv2_type_data_l_s), 6141 .call = parse_vc_item_l2tpv2_type, 6142 }, 6143 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 6144 .name = "length", 6145 .help = "message length", 6146 .next = NEXT(item_l2tpv2_type_data_l_s, 6147 NEXT_ENTRY(COMMON_UNSIGNED), 6148 item_param), 6149 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6150 hdr.type3.length)), 6151 }, 6152 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 6153 .name = "tunnel_id", 6154 .help = "tunnel identifier", 6155 .next = NEXT(item_l2tpv2_type_data_l_s, 6156 NEXT_ENTRY(COMMON_UNSIGNED), 6157 item_param), 6158 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6159 hdr.type3.tunnel_id)), 6160 }, 6161 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 6162 .name = "session_id", 6163 .help = "session identifier", 6164 .next = NEXT(item_l2tpv2_type_data_l_s, 6165 NEXT_ENTRY(COMMON_UNSIGNED), 6166 item_param), 6167 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6168 hdr.type3.session_id)), 6169 }, 6170 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 6171 .name = "ns", 6172 .help = "sequence number for message", 6173 .next = NEXT(item_l2tpv2_type_data_l_s, 6174 NEXT_ENTRY(COMMON_UNSIGNED), 6175 item_param), 6176 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6177 hdr.type3.ns)), 6178 }, 6179 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 6180 .name = "nr", 6181 .help = "sequence number for next receive message", 6182 .next = NEXT(item_l2tpv2_type_data_l_s, 6183 NEXT_ENTRY(COMMON_UNSIGNED), 6184 item_param), 6185 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6186 hdr.type3.nr)), 6187 }, 6188 [ITEM_L2TPV2_TYPE_CTRL] = { 6189 .name = "control", 6190 .help = "Type #3: conrtol message contains length, ns, nr " 6191 "options", 6192 .next = NEXT(item_l2tpv2_type_ctrl), 6193 .call = parse_vc_item_l2tpv2_type, 6194 }, 6195 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 6196 .name = "length", 6197 .help = "message length", 6198 .next = NEXT(item_l2tpv2_type_ctrl, 6199 NEXT_ENTRY(COMMON_UNSIGNED), 6200 item_param), 6201 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6202 hdr.type3.length)), 6203 }, 6204 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 6205 .name = "tunnel_id", 6206 .help = "tunnel identifier", 6207 .next = NEXT(item_l2tpv2_type_ctrl, 6208 NEXT_ENTRY(COMMON_UNSIGNED), 6209 item_param), 6210 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6211 hdr.type3.tunnel_id)), 6212 }, 6213 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 6214 .name = "session_id", 6215 .help = "session identifier", 6216 .next = NEXT(item_l2tpv2_type_ctrl, 6217 NEXT_ENTRY(COMMON_UNSIGNED), 6218 item_param), 6219 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6220 hdr.type3.session_id)), 6221 }, 6222 [ITEM_L2TPV2_MSG_CTRL_NS] = { 6223 .name = "ns", 6224 .help = "sequence number for message", 6225 .next = NEXT(item_l2tpv2_type_ctrl, 6226 NEXT_ENTRY(COMMON_UNSIGNED), 6227 item_param), 6228 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6229 hdr.type3.ns)), 6230 }, 6231 [ITEM_L2TPV2_MSG_CTRL_NR] = { 6232 .name = "nr", 6233 .help = "sequence number for next receive message", 6234 .next = NEXT(item_l2tpv2_type_ctrl, 6235 NEXT_ENTRY(COMMON_UNSIGNED), 6236 item_param), 6237 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6238 hdr.type3.nr)), 6239 }, 6240 [ITEM_PPP] = { 6241 .name = "ppp", 6242 .help = "match PPP header", 6243 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 6244 .next = NEXT(item_ppp), 6245 .call = parse_vc, 6246 }, 6247 [ITEM_PPP_ADDR] = { 6248 .name = "addr", 6249 .help = "PPP address", 6250 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6251 item_param), 6252 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 6253 }, 6254 [ITEM_PPP_CTRL] = { 6255 .name = "ctrl", 6256 .help = "PPP control", 6257 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6258 item_param), 6259 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 6260 }, 6261 [ITEM_PPP_PROTO_ID] = { 6262 .name = "proto_id", 6263 .help = "PPP protocol identifier", 6264 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6265 item_param), 6266 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 6267 hdr.proto_id)), 6268 }, 6269 [ITEM_METER] = { 6270 .name = "meter", 6271 .help = "match meter color", 6272 .priv = PRIV_ITEM(METER_COLOR, 6273 sizeof(struct rte_flow_item_meter_color)), 6274 .next = NEXT(item_meter), 6275 .call = parse_vc, 6276 }, 6277 [ITEM_METER_COLOR] = { 6278 .name = "color", 6279 .help = "meter color", 6280 .next = NEXT(item_meter, 6281 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 6282 item_param), 6283 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 6284 color)), 6285 }, 6286 [ITEM_METER_COLOR_NAME] = { 6287 .name = "color_name", 6288 .help = "meter color name", 6289 .call = parse_meter_color, 6290 .comp = comp_meter_color, 6291 }, 6292 [ITEM_QUOTA] = { 6293 .name = "quota", 6294 .help = "match quota", 6295 .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), 6296 .next = NEXT(item_quota), 6297 .call = parse_vc 6298 }, 6299 [ITEM_QUOTA_STATE] = { 6300 .name = "quota_state", 6301 .help = "quota state", 6302 .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), 6303 NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), 6304 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) 6305 }, 6306 [ITEM_QUOTA_STATE_NAME] = { 6307 .name = "state_name", 6308 .help = "quota state name", 6309 .call = parse_quota_state_name, 6310 .comp = comp_quota_state_name 6311 }, 6312 [ITEM_IB_BTH] = { 6313 .name = "ib_bth", 6314 .help = "match ib bth fields", 6315 .priv = PRIV_ITEM(IB_BTH, 6316 sizeof(struct rte_flow_item_ib_bth)), 6317 .next = NEXT(item_ib_bth), 6318 .call = parse_vc, 6319 }, 6320 [ITEM_IB_BTH_OPCODE] = { 6321 .name = "opcode", 6322 .help = "match ib bth opcode", 6323 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6324 item_param), 6325 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6326 hdr.opcode)), 6327 }, 6328 [ITEM_IB_BTH_PKEY] = { 6329 .name = "pkey", 6330 .help = "partition key", 6331 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6332 item_param), 6333 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6334 hdr.pkey)), 6335 }, 6336 [ITEM_IB_BTH_DST_QPN] = { 6337 .name = "dst_qp", 6338 .help = "destination qp", 6339 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6340 item_param), 6341 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6342 hdr.dst_qp)), 6343 }, 6344 [ITEM_IB_BTH_PSN] = { 6345 .name = "psn", 6346 .help = "packet sequence number", 6347 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6348 item_param), 6349 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6350 hdr.psn)), 6351 }, 6352 [ITEM_PTYPE] = { 6353 .name = "ptype", 6354 .help = "match L2/L3/L4 and tunnel information", 6355 .priv = PRIV_ITEM(PTYPE, 6356 sizeof(struct rte_flow_item_ptype)), 6357 .next = NEXT(item_ptype), 6358 .call = parse_vc, 6359 }, 6360 [ITEM_PTYPE_VALUE] = { 6361 .name = "packet_type", 6362 .help = "packet type as defined in rte_mbuf_ptype", 6363 .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), 6364 item_param), 6365 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), 6366 }, 6367 [ITEM_NSH] = { 6368 .name = "nsh", 6369 .help = "match NSH header", 6370 .priv = PRIV_ITEM(NSH, 6371 sizeof(struct rte_flow_item_nsh)), 6372 .next = NEXT(item_nsh), 6373 .call = parse_vc, 6374 }, 6375 [ITEM_COMPARE] = { 6376 .name = "compare", 6377 .help = "match with the comparison result", 6378 .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)), 6379 .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)), 6380 .call = parse_vc, 6381 }, 6382 [ITEM_COMPARE_OP] = { 6383 .name = "op", 6384 .help = "operation type", 6385 .next = NEXT(item_compare_field, 6386 NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param), 6387 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)), 6388 }, 6389 [ITEM_COMPARE_OP_VALUE] = { 6390 .name = "{operation}", 6391 .help = "operation type value", 6392 .call = parse_vc_compare_op, 6393 .comp = comp_set_compare_op, 6394 }, 6395 [ITEM_COMPARE_FIELD_A_TYPE] = { 6396 .name = "a_type", 6397 .help = "compared field type", 6398 .next = NEXT(compare_field_a, 6399 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param), 6400 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)), 6401 }, 6402 [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = { 6403 .name = "{a_type}", 6404 .help = "compared field type value", 6405 .call = parse_vc_compare_field_id, 6406 .comp = comp_set_compare_field_id, 6407 }, 6408 [ITEM_COMPARE_FIELD_A_LEVEL] = { 6409 .name = "a_level", 6410 .help = "compared field level", 6411 .next = NEXT(compare_field_a, 6412 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param), 6413 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)), 6414 }, 6415 [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = { 6416 .name = "{a_level}", 6417 .help = "compared field level value", 6418 .call = parse_vc_compare_field_level, 6419 .comp = comp_none, 6420 }, 6421 [ITEM_COMPARE_FIELD_A_TAG_INDEX] = { 6422 .name = "a_tag_index", 6423 .help = "compared field tag array", 6424 .next = NEXT(compare_field_a, 6425 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6426 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6427 a.tag_index)), 6428 }, 6429 [ITEM_COMPARE_FIELD_A_TYPE_ID] = { 6430 .name = "a_type_id", 6431 .help = "compared field type ID", 6432 .next = NEXT(compare_field_a, 6433 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6434 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6435 a.type)), 6436 }, 6437 [ITEM_COMPARE_FIELD_A_CLASS_ID] = { 6438 .name = "a_class", 6439 .help = "compared field class ID", 6440 .next = NEXT(compare_field_a, 6441 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6442 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6443 a.class_id)), 6444 }, 6445 [ITEM_COMPARE_FIELD_A_OFFSET] = { 6446 .name = "a_offset", 6447 .help = "compared field bit offset", 6448 .next = NEXT(compare_field_a, 6449 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6450 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6451 a.offset)), 6452 }, 6453 [ITEM_COMPARE_FIELD_B_TYPE] = { 6454 .name = "b_type", 6455 .help = "comparator field type", 6456 .next = NEXT(compare_field_b, 6457 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param), 6458 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6459 b.field)), 6460 }, 6461 [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = { 6462 .name = "{b_type}", 6463 .help = "comparator field type value", 6464 .call = parse_vc_compare_field_id, 6465 .comp = comp_set_compare_field_id, 6466 }, 6467 [ITEM_COMPARE_FIELD_B_LEVEL] = { 6468 .name = "b_level", 6469 .help = "comparator field level", 6470 .next = NEXT(compare_field_b, 6471 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param), 6472 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6473 b.level)), 6474 }, 6475 [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = { 6476 .name = "{b_level}", 6477 .help = "comparator field level value", 6478 .call = parse_vc_compare_field_level, 6479 .comp = comp_none, 6480 }, 6481 [ITEM_COMPARE_FIELD_B_TAG_INDEX] = { 6482 .name = "b_tag_index", 6483 .help = "comparator field tag array", 6484 .next = NEXT(compare_field_b, 6485 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6486 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6487 b.tag_index)), 6488 }, 6489 [ITEM_COMPARE_FIELD_B_TYPE_ID] = { 6490 .name = "b_type_id", 6491 .help = "comparator field type ID", 6492 .next = NEXT(compare_field_b, 6493 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6494 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6495 b.type)), 6496 }, 6497 [ITEM_COMPARE_FIELD_B_CLASS_ID] = { 6498 .name = "b_class", 6499 .help = "comparator field class ID", 6500 .next = NEXT(compare_field_b, 6501 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6502 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6503 b.class_id)), 6504 }, 6505 [ITEM_COMPARE_FIELD_B_OFFSET] = { 6506 .name = "b_offset", 6507 .help = "comparator field bit offset", 6508 .next = NEXT(compare_field_b, 6509 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6510 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6511 b.offset)), 6512 }, 6513 [ITEM_COMPARE_FIELD_B_VALUE] = { 6514 .name = "b_value", 6515 .help = "comparator immediate value", 6516 .next = NEXT(compare_field_b, 6517 NEXT_ENTRY(COMMON_HEX), item_param), 6518 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6519 ARGS_ENTRY_ARB(0, 0), 6520 ARGS_ENTRY(struct rte_flow_item_compare, 6521 b.value)), 6522 }, 6523 [ITEM_COMPARE_FIELD_B_POINTER] = { 6524 .name = "b_ptr", 6525 .help = "pointer to comparator immediate value", 6526 .next = NEXT(compare_field_b, 6527 NEXT_ENTRY(COMMON_HEX), item_param), 6528 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6529 b.pvalue), 6530 ARGS_ENTRY_ARB(0, 0), 6531 ARGS_ENTRY_ARB 6532 (sizeof(struct rte_flow_item_compare), 6533 FLOW_FIELD_PATTERN_SIZE)), 6534 }, 6535 [ITEM_COMPARE_FIELD_WIDTH] = { 6536 .name = "width", 6537 .help = "number of bits to compare", 6538 .next = NEXT(item_compare_field, 6539 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6540 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6541 width)), 6542 }, 6543 6544 /* Validate/create actions. */ 6545 [ACTIONS] = { 6546 .name = "actions", 6547 .help = "submit a list of associated actions", 6548 .next = NEXT(next_action), 6549 .call = parse_vc, 6550 }, 6551 [ACTION_NEXT] = { 6552 .name = "/", 6553 .help = "specify next action", 6554 .next = NEXT(next_action), 6555 }, 6556 [ACTION_END] = { 6557 .name = "end", 6558 .help = "end list of actions", 6559 .priv = PRIV_ACTION(END, 0), 6560 .call = parse_vc, 6561 }, 6562 [ACTION_VOID] = { 6563 .name = "void", 6564 .help = "no-op action", 6565 .priv = PRIV_ACTION(VOID, 0), 6566 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6567 .call = parse_vc, 6568 }, 6569 [ACTION_PASSTHRU] = { 6570 .name = "passthru", 6571 .help = "let subsequent rule process matched packets", 6572 .priv = PRIV_ACTION(PASSTHRU, 0), 6573 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6574 .call = parse_vc, 6575 }, 6576 [ACTION_SKIP_CMAN] = { 6577 .name = "skip_cman", 6578 .help = "bypass cman on received packets", 6579 .priv = PRIV_ACTION(SKIP_CMAN, 0), 6580 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6581 .call = parse_vc, 6582 }, 6583 [ACTION_JUMP] = { 6584 .name = "jump", 6585 .help = "redirect traffic to a given group", 6586 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 6587 .next = NEXT(action_jump), 6588 .call = parse_vc, 6589 }, 6590 [ACTION_JUMP_GROUP] = { 6591 .name = "group", 6592 .help = "group to redirect traffic to", 6593 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 6594 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 6595 .call = parse_vc_conf, 6596 }, 6597 [ACTION_MARK] = { 6598 .name = "mark", 6599 .help = "attach 32 bit value to packets", 6600 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 6601 .next = NEXT(action_mark), 6602 .call = parse_vc, 6603 }, 6604 [ACTION_MARK_ID] = { 6605 .name = "id", 6606 .help = "32 bit value to return with packets", 6607 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6608 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 6609 .call = parse_vc_conf, 6610 }, 6611 [ACTION_FLAG] = { 6612 .name = "flag", 6613 .help = "flag packets", 6614 .priv = PRIV_ACTION(FLAG, 0), 6615 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6616 .call = parse_vc, 6617 }, 6618 [ACTION_QUEUE] = { 6619 .name = "queue", 6620 .help = "assign packets to a given queue index", 6621 .priv = PRIV_ACTION(QUEUE, 6622 sizeof(struct rte_flow_action_queue)), 6623 .next = NEXT(action_queue), 6624 .call = parse_vc, 6625 }, 6626 [ACTION_QUEUE_INDEX] = { 6627 .name = "index", 6628 .help = "queue index to use", 6629 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 6630 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 6631 .call = parse_vc_conf, 6632 }, 6633 [ACTION_DROP] = { 6634 .name = "drop", 6635 .help = "drop packets (note: passthru has priority)", 6636 .priv = PRIV_ACTION(DROP, 0), 6637 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6638 .call = parse_vc, 6639 }, 6640 [ACTION_COUNT] = { 6641 .name = "count", 6642 .help = "enable counters for this rule", 6643 .priv = PRIV_ACTION(COUNT, 6644 sizeof(struct rte_flow_action_count)), 6645 .next = NEXT(action_count), 6646 .call = parse_vc, 6647 }, 6648 [ACTION_COUNT_ID] = { 6649 .name = "identifier", 6650 .help = "counter identifier to use", 6651 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 6652 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 6653 .call = parse_vc_conf, 6654 }, 6655 [ACTION_RSS] = { 6656 .name = "rss", 6657 .help = "spread packets among several queues", 6658 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 6659 .next = NEXT(action_rss), 6660 .call = parse_vc_action_rss, 6661 }, 6662 [ACTION_RSS_FUNC] = { 6663 .name = "func", 6664 .help = "RSS hash function to apply", 6665 .next = NEXT(action_rss, 6666 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 6667 ACTION_RSS_FUNC_TOEPLITZ, 6668 ACTION_RSS_FUNC_SIMPLE_XOR, 6669 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 6670 }, 6671 [ACTION_RSS_FUNC_DEFAULT] = { 6672 .name = "default", 6673 .help = "default hash function", 6674 .call = parse_vc_action_rss_func, 6675 }, 6676 [ACTION_RSS_FUNC_TOEPLITZ] = { 6677 .name = "toeplitz", 6678 .help = "Toeplitz hash function", 6679 .call = parse_vc_action_rss_func, 6680 }, 6681 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 6682 .name = "simple_xor", 6683 .help = "simple XOR hash function", 6684 .call = parse_vc_action_rss_func, 6685 }, 6686 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 6687 .name = "symmetric_toeplitz", 6688 .help = "Symmetric Toeplitz hash function", 6689 .call = parse_vc_action_rss_func, 6690 }, 6691 [ACTION_RSS_LEVEL] = { 6692 .name = "level", 6693 .help = "encapsulation level for \"types\"", 6694 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6695 .args = ARGS(ARGS_ENTRY_ARB 6696 (offsetof(struct action_rss_data, conf) + 6697 offsetof(struct rte_flow_action_rss, level), 6698 sizeof(((struct rte_flow_action_rss *)0)-> 6699 level))), 6700 }, 6701 [ACTION_RSS_TYPES] = { 6702 .name = "types", 6703 .help = "specific RSS hash types", 6704 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 6705 }, 6706 [ACTION_RSS_TYPE] = { 6707 .name = "{type}", 6708 .help = "RSS hash type", 6709 .call = parse_vc_action_rss_type, 6710 .comp = comp_vc_action_rss_type, 6711 }, 6712 [ACTION_RSS_KEY] = { 6713 .name = "key", 6714 .help = "RSS hash key", 6715 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 6716 .args = ARGS(ARGS_ENTRY_ARB 6717 (offsetof(struct action_rss_data, conf) + 6718 offsetof(struct rte_flow_action_rss, key), 6719 sizeof(((struct rte_flow_action_rss *)0)->key)), 6720 ARGS_ENTRY_ARB 6721 (offsetof(struct action_rss_data, conf) + 6722 offsetof(struct rte_flow_action_rss, key_len), 6723 sizeof(((struct rte_flow_action_rss *)0)-> 6724 key_len)), 6725 ARGS_ENTRY(struct action_rss_data, key)), 6726 }, 6727 [ACTION_RSS_KEY_LEN] = { 6728 .name = "key_len", 6729 .help = "RSS hash key length in bytes", 6730 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6731 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6732 (offsetof(struct action_rss_data, conf) + 6733 offsetof(struct rte_flow_action_rss, key_len), 6734 sizeof(((struct rte_flow_action_rss *)0)-> 6735 key_len), 6736 0, 6737 RSS_HASH_KEY_LENGTH)), 6738 }, 6739 [ACTION_RSS_QUEUES] = { 6740 .name = "queues", 6741 .help = "queue indices to use", 6742 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 6743 .call = parse_vc_conf, 6744 }, 6745 [ACTION_RSS_QUEUE] = { 6746 .name = "{queue}", 6747 .help = "queue index", 6748 .call = parse_vc_action_rss_queue, 6749 .comp = comp_vc_action_rss_queue, 6750 }, 6751 [ACTION_PF] = { 6752 .name = "pf", 6753 .help = "direct traffic to physical function", 6754 .priv = PRIV_ACTION(PF, 0), 6755 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6756 .call = parse_vc, 6757 }, 6758 [ACTION_VF] = { 6759 .name = "vf", 6760 .help = "direct traffic to a virtual function ID", 6761 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 6762 .next = NEXT(action_vf), 6763 .call = parse_vc, 6764 }, 6765 [ACTION_VF_ORIGINAL] = { 6766 .name = "original", 6767 .help = "use original VF ID if possible", 6768 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 6769 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 6770 original, 1)), 6771 .call = parse_vc_conf, 6772 }, 6773 [ACTION_VF_ID] = { 6774 .name = "id", 6775 .help = "VF ID", 6776 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 6777 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 6778 .call = parse_vc_conf, 6779 }, 6780 [ACTION_PORT_ID] = { 6781 .name = "port_id", 6782 .help = "direct matching traffic to a given DPDK port ID", 6783 .priv = PRIV_ACTION(PORT_ID, 6784 sizeof(struct rte_flow_action_port_id)), 6785 .next = NEXT(action_port_id), 6786 .call = parse_vc, 6787 }, 6788 [ACTION_PORT_ID_ORIGINAL] = { 6789 .name = "original", 6790 .help = "use original DPDK port ID if possible", 6791 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 6792 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 6793 original, 1)), 6794 .call = parse_vc_conf, 6795 }, 6796 [ACTION_PORT_ID_ID] = { 6797 .name = "id", 6798 .help = "DPDK port ID", 6799 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 6800 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 6801 .call = parse_vc_conf, 6802 }, 6803 [ACTION_METER] = { 6804 .name = "meter", 6805 .help = "meter the directed packets at given id", 6806 .priv = PRIV_ACTION(METER, 6807 sizeof(struct rte_flow_action_meter)), 6808 .next = NEXT(action_meter), 6809 .call = parse_vc, 6810 }, 6811 [ACTION_METER_COLOR] = { 6812 .name = "color", 6813 .help = "meter color for the packets", 6814 .priv = PRIV_ACTION(METER_COLOR, 6815 sizeof(struct rte_flow_action_meter_color)), 6816 .next = NEXT(action_meter_color), 6817 .call = parse_vc, 6818 }, 6819 [ACTION_METER_COLOR_TYPE] = { 6820 .name = "type", 6821 .help = "specific meter color", 6822 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6823 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 6824 ACTION_METER_COLOR_YELLOW, 6825 ACTION_METER_COLOR_RED)), 6826 }, 6827 [ACTION_METER_COLOR_GREEN] = { 6828 .name = "green", 6829 .help = "meter color green", 6830 .call = parse_vc_action_meter_color_type, 6831 }, 6832 [ACTION_METER_COLOR_YELLOW] = { 6833 .name = "yellow", 6834 .help = "meter color yellow", 6835 .call = parse_vc_action_meter_color_type, 6836 }, 6837 [ACTION_METER_COLOR_RED] = { 6838 .name = "red", 6839 .help = "meter color red", 6840 .call = parse_vc_action_meter_color_type, 6841 }, 6842 [ACTION_METER_ID] = { 6843 .name = "mtr_id", 6844 .help = "meter id to use", 6845 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 6846 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 6847 .call = parse_vc_conf, 6848 }, 6849 [ACTION_METER_MARK] = { 6850 .name = "meter_mark", 6851 .help = "meter the directed packets using profile and policy", 6852 .priv = PRIV_ACTION(METER_MARK, 6853 sizeof(struct rte_flow_action_meter_mark)), 6854 .next = NEXT(action_meter_mark), 6855 .call = parse_vc, 6856 }, 6857 [ACTION_METER_PROFILE] = { 6858 .name = "mtr_profile", 6859 .help = "meter profile id to use", 6860 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 6861 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6862 }, 6863 [ACTION_METER_PROFILE_ID2PTR] = { 6864 .name = "{mtr_profile_id}", 6865 .type = "PROFILE_ID", 6866 .help = "meter profile id", 6867 .next = NEXT(action_meter_mark), 6868 .call = parse_meter_profile_id2ptr, 6869 .comp = comp_none, 6870 }, 6871 [ACTION_METER_POLICY] = { 6872 .name = "mtr_policy", 6873 .help = "meter policy id to use", 6874 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 6875 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6876 }, 6877 [ACTION_METER_POLICY_ID2PTR] = { 6878 .name = "{mtr_policy_id}", 6879 .type = "POLICY_ID", 6880 .help = "meter policy id", 6881 .next = NEXT(action_meter_mark), 6882 .call = parse_meter_policy_id2ptr, 6883 .comp = comp_none, 6884 }, 6885 [ACTION_METER_COLOR_MODE] = { 6886 .name = "mtr_color_mode", 6887 .help = "meter color awareness mode", 6888 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6889 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 6890 .call = parse_vc_conf, 6891 }, 6892 [ACTION_METER_STATE] = { 6893 .name = "mtr_state", 6894 .help = "meter state", 6895 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6896 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 6897 .call = parse_vc_conf, 6898 }, 6899 [ACTION_OF_DEC_NW_TTL] = { 6900 .name = "of_dec_nw_ttl", 6901 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 6902 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 6903 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6904 .call = parse_vc, 6905 }, 6906 [ACTION_OF_POP_VLAN] = { 6907 .name = "of_pop_vlan", 6908 .help = "OpenFlow's OFPAT_POP_VLAN", 6909 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 6910 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6911 .call = parse_vc, 6912 }, 6913 [ACTION_OF_PUSH_VLAN] = { 6914 .name = "of_push_vlan", 6915 .help = "OpenFlow's OFPAT_PUSH_VLAN", 6916 .priv = PRIV_ACTION 6917 (OF_PUSH_VLAN, 6918 sizeof(struct rte_flow_action_of_push_vlan)), 6919 .next = NEXT(action_of_push_vlan), 6920 .call = parse_vc, 6921 }, 6922 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 6923 .name = "ethertype", 6924 .help = "EtherType", 6925 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 6926 .args = ARGS(ARGS_ENTRY_HTON 6927 (struct rte_flow_action_of_push_vlan, 6928 ethertype)), 6929 .call = parse_vc_conf, 6930 }, 6931 [ACTION_OF_SET_VLAN_VID] = { 6932 .name = "of_set_vlan_vid", 6933 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 6934 .priv = PRIV_ACTION 6935 (OF_SET_VLAN_VID, 6936 sizeof(struct rte_flow_action_of_set_vlan_vid)), 6937 .next = NEXT(action_of_set_vlan_vid), 6938 .call = parse_vc, 6939 }, 6940 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 6941 .name = "vlan_vid", 6942 .help = "VLAN id", 6943 .next = NEXT(action_of_set_vlan_vid, 6944 NEXT_ENTRY(COMMON_UNSIGNED)), 6945 .args = ARGS(ARGS_ENTRY_HTON 6946 (struct rte_flow_action_of_set_vlan_vid, 6947 vlan_vid)), 6948 .call = parse_vc_conf, 6949 }, 6950 [ACTION_OF_SET_VLAN_PCP] = { 6951 .name = "of_set_vlan_pcp", 6952 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 6953 .priv = PRIV_ACTION 6954 (OF_SET_VLAN_PCP, 6955 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 6956 .next = NEXT(action_of_set_vlan_pcp), 6957 .call = parse_vc, 6958 }, 6959 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 6960 .name = "vlan_pcp", 6961 .help = "VLAN priority", 6962 .next = NEXT(action_of_set_vlan_pcp, 6963 NEXT_ENTRY(COMMON_UNSIGNED)), 6964 .args = ARGS(ARGS_ENTRY_HTON 6965 (struct rte_flow_action_of_set_vlan_pcp, 6966 vlan_pcp)), 6967 .call = parse_vc_conf, 6968 }, 6969 [ACTION_OF_POP_MPLS] = { 6970 .name = "of_pop_mpls", 6971 .help = "OpenFlow's OFPAT_POP_MPLS", 6972 .priv = PRIV_ACTION(OF_POP_MPLS, 6973 sizeof(struct rte_flow_action_of_pop_mpls)), 6974 .next = NEXT(action_of_pop_mpls), 6975 .call = parse_vc, 6976 }, 6977 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 6978 .name = "ethertype", 6979 .help = "EtherType", 6980 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6981 .args = ARGS(ARGS_ENTRY_HTON 6982 (struct rte_flow_action_of_pop_mpls, 6983 ethertype)), 6984 .call = parse_vc_conf, 6985 }, 6986 [ACTION_OF_PUSH_MPLS] = { 6987 .name = "of_push_mpls", 6988 .help = "OpenFlow's OFPAT_PUSH_MPLS", 6989 .priv = PRIV_ACTION 6990 (OF_PUSH_MPLS, 6991 sizeof(struct rte_flow_action_of_push_mpls)), 6992 .next = NEXT(action_of_push_mpls), 6993 .call = parse_vc, 6994 }, 6995 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 6996 .name = "ethertype", 6997 .help = "EtherType", 6998 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6999 .args = ARGS(ARGS_ENTRY_HTON 7000 (struct rte_flow_action_of_push_mpls, 7001 ethertype)), 7002 .call = parse_vc_conf, 7003 }, 7004 [ACTION_VXLAN_ENCAP] = { 7005 .name = "vxlan_encap", 7006 .help = "VXLAN encapsulation, uses configuration set by \"set" 7007 " vxlan\"", 7008 .priv = PRIV_ACTION(VXLAN_ENCAP, 7009 sizeof(struct action_vxlan_encap_data)), 7010 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7011 .call = parse_vc_action_vxlan_encap, 7012 }, 7013 [ACTION_VXLAN_DECAP] = { 7014 .name = "vxlan_decap", 7015 .help = "Performs a decapsulation action by stripping all" 7016 " headers of the VXLAN tunnel network overlay from the" 7017 " matched flow.", 7018 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 7019 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7020 .call = parse_vc, 7021 }, 7022 [ACTION_NVGRE_ENCAP] = { 7023 .name = "nvgre_encap", 7024 .help = "NVGRE encapsulation, uses configuration set by \"set" 7025 " nvgre\"", 7026 .priv = PRIV_ACTION(NVGRE_ENCAP, 7027 sizeof(struct action_nvgre_encap_data)), 7028 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7029 .call = parse_vc_action_nvgre_encap, 7030 }, 7031 [ACTION_NVGRE_DECAP] = { 7032 .name = "nvgre_decap", 7033 .help = "Performs a decapsulation action by stripping all" 7034 " headers of the NVGRE tunnel network overlay from the" 7035 " matched flow.", 7036 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 7037 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7038 .call = parse_vc, 7039 }, 7040 [ACTION_L2_ENCAP] = { 7041 .name = "l2_encap", 7042 .help = "l2 encap, uses configuration set by" 7043 " \"set l2_encap\"", 7044 .priv = PRIV_ACTION(RAW_ENCAP, 7045 sizeof(struct action_raw_encap_data)), 7046 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7047 .call = parse_vc_action_l2_encap, 7048 }, 7049 [ACTION_L2_DECAP] = { 7050 .name = "l2_decap", 7051 .help = "l2 decap, uses configuration set by" 7052 " \"set l2_decap\"", 7053 .priv = PRIV_ACTION(RAW_DECAP, 7054 sizeof(struct action_raw_decap_data)), 7055 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7056 .call = parse_vc_action_l2_decap, 7057 }, 7058 [ACTION_MPLSOGRE_ENCAP] = { 7059 .name = "mplsogre_encap", 7060 .help = "mplsogre encapsulation, uses configuration set by" 7061 " \"set mplsogre_encap\"", 7062 .priv = PRIV_ACTION(RAW_ENCAP, 7063 sizeof(struct action_raw_encap_data)), 7064 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7065 .call = parse_vc_action_mplsogre_encap, 7066 }, 7067 [ACTION_MPLSOGRE_DECAP] = { 7068 .name = "mplsogre_decap", 7069 .help = "mplsogre decapsulation, uses configuration set by" 7070 " \"set mplsogre_decap\"", 7071 .priv = PRIV_ACTION(RAW_DECAP, 7072 sizeof(struct action_raw_decap_data)), 7073 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7074 .call = parse_vc_action_mplsogre_decap, 7075 }, 7076 [ACTION_MPLSOUDP_ENCAP] = { 7077 .name = "mplsoudp_encap", 7078 .help = "mplsoudp encapsulation, uses configuration set by" 7079 " \"set mplsoudp_encap\"", 7080 .priv = PRIV_ACTION(RAW_ENCAP, 7081 sizeof(struct action_raw_encap_data)), 7082 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7083 .call = parse_vc_action_mplsoudp_encap, 7084 }, 7085 [ACTION_MPLSOUDP_DECAP] = { 7086 .name = "mplsoudp_decap", 7087 .help = "mplsoudp decapsulation, uses configuration set by" 7088 " \"set mplsoudp_decap\"", 7089 .priv = PRIV_ACTION(RAW_DECAP, 7090 sizeof(struct action_raw_decap_data)), 7091 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7092 .call = parse_vc_action_mplsoudp_decap, 7093 }, 7094 [ACTION_SET_IPV4_SRC] = { 7095 .name = "set_ipv4_src", 7096 .help = "Set a new IPv4 source address in the outermost" 7097 " IPv4 header", 7098 .priv = PRIV_ACTION(SET_IPV4_SRC, 7099 sizeof(struct rte_flow_action_set_ipv4)), 7100 .next = NEXT(action_set_ipv4_src), 7101 .call = parse_vc, 7102 }, 7103 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 7104 .name = "ipv4_addr", 7105 .help = "new IPv4 source address to set", 7106 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 7107 .args = ARGS(ARGS_ENTRY_HTON 7108 (struct rte_flow_action_set_ipv4, ipv4_addr)), 7109 .call = parse_vc_conf, 7110 }, 7111 [ACTION_SET_IPV4_DST] = { 7112 .name = "set_ipv4_dst", 7113 .help = "Set a new IPv4 destination address in the outermost" 7114 " IPv4 header", 7115 .priv = PRIV_ACTION(SET_IPV4_DST, 7116 sizeof(struct rte_flow_action_set_ipv4)), 7117 .next = NEXT(action_set_ipv4_dst), 7118 .call = parse_vc, 7119 }, 7120 [ACTION_SET_IPV4_DST_IPV4_DST] = { 7121 .name = "ipv4_addr", 7122 .help = "new IPv4 destination address to set", 7123 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 7124 .args = ARGS(ARGS_ENTRY_HTON 7125 (struct rte_flow_action_set_ipv4, ipv4_addr)), 7126 .call = parse_vc_conf, 7127 }, 7128 [ACTION_SET_IPV6_SRC] = { 7129 .name = "set_ipv6_src", 7130 .help = "Set a new IPv6 source address in the outermost" 7131 " IPv6 header", 7132 .priv = PRIV_ACTION(SET_IPV6_SRC, 7133 sizeof(struct rte_flow_action_set_ipv6)), 7134 .next = NEXT(action_set_ipv6_src), 7135 .call = parse_vc, 7136 }, 7137 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 7138 .name = "ipv6_addr", 7139 .help = "new IPv6 source address to set", 7140 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7141 .args = ARGS(ARGS_ENTRY_HTON 7142 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7143 .call = parse_vc_conf, 7144 }, 7145 [ACTION_SET_IPV6_DST] = { 7146 .name = "set_ipv6_dst", 7147 .help = "Set a new IPv6 destination address in the outermost" 7148 " IPv6 header", 7149 .priv = PRIV_ACTION(SET_IPV6_DST, 7150 sizeof(struct rte_flow_action_set_ipv6)), 7151 .next = NEXT(action_set_ipv6_dst), 7152 .call = parse_vc, 7153 }, 7154 [ACTION_SET_IPV6_DST_IPV6_DST] = { 7155 .name = "ipv6_addr", 7156 .help = "new IPv6 destination address to set", 7157 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7158 .args = ARGS(ARGS_ENTRY_HTON 7159 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7160 .call = parse_vc_conf, 7161 }, 7162 [ACTION_SET_TP_SRC] = { 7163 .name = "set_tp_src", 7164 .help = "set a new source port number in the outermost" 7165 " TCP/UDP header", 7166 .priv = PRIV_ACTION(SET_TP_SRC, 7167 sizeof(struct rte_flow_action_set_tp)), 7168 .next = NEXT(action_set_tp_src), 7169 .call = parse_vc, 7170 }, 7171 [ACTION_SET_TP_SRC_TP_SRC] = { 7172 .name = "port", 7173 .help = "new source port number to set", 7174 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 7175 .args = ARGS(ARGS_ENTRY_HTON 7176 (struct rte_flow_action_set_tp, port)), 7177 .call = parse_vc_conf, 7178 }, 7179 [ACTION_SET_TP_DST] = { 7180 .name = "set_tp_dst", 7181 .help = "set a new destination port number in the outermost" 7182 " TCP/UDP header", 7183 .priv = PRIV_ACTION(SET_TP_DST, 7184 sizeof(struct rte_flow_action_set_tp)), 7185 .next = NEXT(action_set_tp_dst), 7186 .call = parse_vc, 7187 }, 7188 [ACTION_SET_TP_DST_TP_DST] = { 7189 .name = "port", 7190 .help = "new destination port number to set", 7191 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 7192 .args = ARGS(ARGS_ENTRY_HTON 7193 (struct rte_flow_action_set_tp, port)), 7194 .call = parse_vc_conf, 7195 }, 7196 [ACTION_MAC_SWAP] = { 7197 .name = "mac_swap", 7198 .help = "Swap the source and destination MAC addresses" 7199 " in the outermost Ethernet header", 7200 .priv = PRIV_ACTION(MAC_SWAP, 0), 7201 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7202 .call = parse_vc, 7203 }, 7204 [ACTION_DEC_TTL] = { 7205 .name = "dec_ttl", 7206 .help = "decrease network TTL if available", 7207 .priv = PRIV_ACTION(DEC_TTL, 0), 7208 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7209 .call = parse_vc, 7210 }, 7211 [ACTION_SET_TTL] = { 7212 .name = "set_ttl", 7213 .help = "set ttl value", 7214 .priv = PRIV_ACTION(SET_TTL, 7215 sizeof(struct rte_flow_action_set_ttl)), 7216 .next = NEXT(action_set_ttl), 7217 .call = parse_vc, 7218 }, 7219 [ACTION_SET_TTL_TTL] = { 7220 .name = "ttl_value", 7221 .help = "new ttl value to set", 7222 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 7223 .args = ARGS(ARGS_ENTRY_HTON 7224 (struct rte_flow_action_set_ttl, ttl_value)), 7225 .call = parse_vc_conf, 7226 }, 7227 [ACTION_SET_MAC_SRC] = { 7228 .name = "set_mac_src", 7229 .help = "set source mac address", 7230 .priv = PRIV_ACTION(SET_MAC_SRC, 7231 sizeof(struct rte_flow_action_set_mac)), 7232 .next = NEXT(action_set_mac_src), 7233 .call = parse_vc, 7234 }, 7235 [ACTION_SET_MAC_SRC_MAC_SRC] = { 7236 .name = "mac_addr", 7237 .help = "new source mac address", 7238 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 7239 .args = ARGS(ARGS_ENTRY_HTON 7240 (struct rte_flow_action_set_mac, mac_addr)), 7241 .call = parse_vc_conf, 7242 }, 7243 [ACTION_SET_MAC_DST] = { 7244 .name = "set_mac_dst", 7245 .help = "set destination mac address", 7246 .priv = PRIV_ACTION(SET_MAC_DST, 7247 sizeof(struct rte_flow_action_set_mac)), 7248 .next = NEXT(action_set_mac_dst), 7249 .call = parse_vc, 7250 }, 7251 [ACTION_SET_MAC_DST_MAC_DST] = { 7252 .name = "mac_addr", 7253 .help = "new destination mac address to set", 7254 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 7255 .args = ARGS(ARGS_ENTRY_HTON 7256 (struct rte_flow_action_set_mac, mac_addr)), 7257 .call = parse_vc_conf, 7258 }, 7259 [ACTION_INC_TCP_SEQ] = { 7260 .name = "inc_tcp_seq", 7261 .help = "increase TCP sequence number", 7262 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 7263 .next = NEXT(action_inc_tcp_seq), 7264 .call = parse_vc, 7265 }, 7266 [ACTION_INC_TCP_SEQ_VALUE] = { 7267 .name = "value", 7268 .help = "the value to increase TCP sequence number by", 7269 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7270 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7271 .call = parse_vc_conf, 7272 }, 7273 [ACTION_DEC_TCP_SEQ] = { 7274 .name = "dec_tcp_seq", 7275 .help = "decrease TCP sequence number", 7276 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 7277 .next = NEXT(action_dec_tcp_seq), 7278 .call = parse_vc, 7279 }, 7280 [ACTION_DEC_TCP_SEQ_VALUE] = { 7281 .name = "value", 7282 .help = "the value to decrease TCP sequence number by", 7283 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7284 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7285 .call = parse_vc_conf, 7286 }, 7287 [ACTION_INC_TCP_ACK] = { 7288 .name = "inc_tcp_ack", 7289 .help = "increase TCP acknowledgment number", 7290 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 7291 .next = NEXT(action_inc_tcp_ack), 7292 .call = parse_vc, 7293 }, 7294 [ACTION_INC_TCP_ACK_VALUE] = { 7295 .name = "value", 7296 .help = "the value to increase TCP acknowledgment number by", 7297 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7298 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7299 .call = parse_vc_conf, 7300 }, 7301 [ACTION_DEC_TCP_ACK] = { 7302 .name = "dec_tcp_ack", 7303 .help = "decrease TCP acknowledgment number", 7304 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 7305 .next = NEXT(action_dec_tcp_ack), 7306 .call = parse_vc, 7307 }, 7308 [ACTION_DEC_TCP_ACK_VALUE] = { 7309 .name = "value", 7310 .help = "the value to decrease TCP acknowledgment number by", 7311 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7312 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7313 .call = parse_vc_conf, 7314 }, 7315 [ACTION_RAW_ENCAP] = { 7316 .name = "raw_encap", 7317 .help = "encapsulation data, defined by set raw_encap", 7318 .priv = PRIV_ACTION(RAW_ENCAP, 7319 sizeof(struct action_raw_encap_data)), 7320 .next = NEXT(action_raw_encap), 7321 .call = parse_vc_action_raw_encap, 7322 }, 7323 [ACTION_RAW_ENCAP_SIZE] = { 7324 .name = "size", 7325 .help = "raw encap size", 7326 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7327 NEXT_ENTRY(COMMON_UNSIGNED)), 7328 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_raw_encap, size)), 7329 .call = parse_vc_conf, 7330 }, 7331 [ACTION_RAW_ENCAP_INDEX] = { 7332 .name = "index", 7333 .help = "the index of raw_encap_confs", 7334 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 7335 }, 7336 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 7337 .name = "{index}", 7338 .type = "UNSIGNED", 7339 .help = "unsigned integer value", 7340 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7341 .call = parse_vc_action_raw_encap_index, 7342 .comp = comp_set_raw_index, 7343 }, 7344 [ACTION_RAW_DECAP] = { 7345 .name = "raw_decap", 7346 .help = "decapsulation data, defined by set raw_encap", 7347 .priv = PRIV_ACTION(RAW_DECAP, 7348 sizeof(struct action_raw_decap_data)), 7349 .next = NEXT(action_raw_decap), 7350 .call = parse_vc_action_raw_decap, 7351 }, 7352 [ACTION_RAW_DECAP_INDEX] = { 7353 .name = "index", 7354 .help = "the index of raw_encap_confs", 7355 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 7356 }, 7357 [ACTION_RAW_DECAP_INDEX_VALUE] = { 7358 .name = "{index}", 7359 .type = "UNSIGNED", 7360 .help = "unsigned integer value", 7361 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7362 .call = parse_vc_action_raw_decap_index, 7363 .comp = comp_set_raw_index, 7364 }, 7365 [ACTION_MODIFY_FIELD] = { 7366 .name = "modify_field", 7367 .help = "modify destination field with data from source field", 7368 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 7369 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 7370 .call = parse_vc, 7371 }, 7372 [ACTION_MODIFY_FIELD_OP] = { 7373 .name = "op", 7374 .help = "operation type", 7375 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 7376 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 7377 .call = parse_vc_conf, 7378 }, 7379 [ACTION_MODIFY_FIELD_OP_VALUE] = { 7380 .name = "{operation}", 7381 .help = "operation type value", 7382 .call = parse_vc_modify_field_op, 7383 .comp = comp_set_modify_field_op, 7384 }, 7385 [ACTION_MODIFY_FIELD_DST_TYPE] = { 7386 .name = "dst_type", 7387 .help = "destination field type", 7388 .next = NEXT(action_modify_field_dst, 7389 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 7390 .call = parse_vc_conf, 7391 }, 7392 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 7393 .name = "{dst_type}", 7394 .help = "destination field type value", 7395 .call = parse_vc_modify_field_id, 7396 .comp = comp_set_modify_field_id, 7397 }, 7398 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 7399 .name = "dst_level", 7400 .help = "destination field level", 7401 .next = NEXT(action_modify_field_dst, 7402 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), 7403 .call = parse_vc_conf, 7404 }, 7405 [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { 7406 .name = "{dst_level}", 7407 .help = "destination field level value", 7408 .call = parse_vc_modify_field_level, 7409 .comp = comp_none, 7410 }, 7411 [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { 7412 .name = "dst_tag_index", 7413 .help = "destination field tag array", 7414 .next = NEXT(action_modify_field_dst, 7415 NEXT_ENTRY(COMMON_UNSIGNED)), 7416 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7417 dst.tag_index)), 7418 .call = parse_vc_conf, 7419 }, 7420 [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { 7421 .name = "dst_type_id", 7422 .help = "destination field type ID", 7423 .next = NEXT(action_modify_field_dst, 7424 NEXT_ENTRY(COMMON_UNSIGNED)), 7425 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7426 dst.type)), 7427 .call = parse_vc_conf, 7428 }, 7429 [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { 7430 .name = "dst_class", 7431 .help = "destination field class ID", 7432 .next = NEXT(action_modify_field_dst, 7433 NEXT_ENTRY(COMMON_UNSIGNED)), 7434 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7435 dst.class_id)), 7436 .call = parse_vc_conf, 7437 }, 7438 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 7439 .name = "dst_offset", 7440 .help = "destination field bit offset", 7441 .next = NEXT(action_modify_field_dst, 7442 NEXT_ENTRY(COMMON_UNSIGNED)), 7443 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7444 dst.offset)), 7445 .call = parse_vc_conf, 7446 }, 7447 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 7448 .name = "src_type", 7449 .help = "source field type", 7450 .next = NEXT(action_modify_field_src, 7451 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 7452 .call = parse_vc_conf, 7453 }, 7454 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 7455 .name = "{src_type}", 7456 .help = "source field type value", 7457 .call = parse_vc_modify_field_id, 7458 .comp = comp_set_modify_field_id, 7459 }, 7460 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 7461 .name = "src_level", 7462 .help = "source field level", 7463 .next = NEXT(action_modify_field_src, 7464 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), 7465 .call = parse_vc_conf, 7466 }, 7467 [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { 7468 .name = "{src_level}", 7469 .help = "source field level value", 7470 .call = parse_vc_modify_field_level, 7471 .comp = comp_none, 7472 }, 7473 [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { 7474 .name = "src_tag_index", 7475 .help = "source field tag array", 7476 .next = NEXT(action_modify_field_src, 7477 NEXT_ENTRY(COMMON_UNSIGNED)), 7478 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7479 src.tag_index)), 7480 .call = parse_vc_conf, 7481 }, 7482 [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { 7483 .name = "src_type_id", 7484 .help = "source field type ID", 7485 .next = NEXT(action_modify_field_src, 7486 NEXT_ENTRY(COMMON_UNSIGNED)), 7487 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7488 src.type)), 7489 .call = parse_vc_conf, 7490 }, 7491 [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { 7492 .name = "src_class", 7493 .help = "source field class ID", 7494 .next = NEXT(action_modify_field_src, 7495 NEXT_ENTRY(COMMON_UNSIGNED)), 7496 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7497 src.class_id)), 7498 .call = parse_vc_conf, 7499 }, 7500 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 7501 .name = "src_offset", 7502 .help = "source field bit offset", 7503 .next = NEXT(action_modify_field_src, 7504 NEXT_ENTRY(COMMON_UNSIGNED)), 7505 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7506 src.offset)), 7507 .call = parse_vc_conf, 7508 }, 7509 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 7510 .name = "src_value", 7511 .help = "source immediate value", 7512 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7513 NEXT_ENTRY(COMMON_HEX)), 7514 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 7515 ARGS_ENTRY_ARB(0, 0), 7516 ARGS_ENTRY(struct rte_flow_action_modify_field, 7517 src.value)), 7518 .call = parse_vc_conf, 7519 }, 7520 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 7521 .name = "src_ptr", 7522 .help = "pointer to source immediate value", 7523 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7524 NEXT_ENTRY(COMMON_HEX)), 7525 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7526 src.pvalue), 7527 ARGS_ENTRY_ARB(0, 0), 7528 ARGS_ENTRY_ARB 7529 (sizeof(struct rte_flow_action_modify_field), 7530 FLOW_FIELD_PATTERN_SIZE)), 7531 .call = parse_vc_conf, 7532 }, 7533 [ACTION_MODIFY_FIELD_WIDTH] = { 7534 .name = "width", 7535 .help = "number of bits to copy", 7536 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7537 NEXT_ENTRY(COMMON_UNSIGNED)), 7538 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7539 width)), 7540 .call = parse_vc_conf, 7541 }, 7542 [ACTION_SEND_TO_KERNEL] = { 7543 .name = "send_to_kernel", 7544 .help = "send packets to kernel", 7545 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 7546 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7547 .call = parse_vc, 7548 }, 7549 [ACTION_IPV6_EXT_REMOVE] = { 7550 .name = "ipv6_ext_remove", 7551 .help = "IPv6 extension type, defined by set ipv6_ext_remove", 7552 .priv = PRIV_ACTION(IPV6_EXT_REMOVE, 7553 sizeof(struct action_ipv6_ext_remove_data)), 7554 .next = NEXT(action_ipv6_ext_remove), 7555 .call = parse_vc_action_ipv6_ext_remove, 7556 }, 7557 [ACTION_IPV6_EXT_REMOVE_INDEX] = { 7558 .name = "index", 7559 .help = "the index of ipv6_ext_remove", 7560 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), 7561 }, 7562 [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { 7563 .name = "{index}", 7564 .type = "UNSIGNED", 7565 .help = "unsigned integer value", 7566 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7567 .call = parse_vc_action_ipv6_ext_remove_index, 7568 .comp = comp_set_ipv6_ext_index, 7569 }, 7570 [ACTION_IPV6_EXT_PUSH] = { 7571 .name = "ipv6_ext_push", 7572 .help = "IPv6 extension data, defined by set ipv6_ext_push", 7573 .priv = PRIV_ACTION(IPV6_EXT_PUSH, 7574 sizeof(struct action_ipv6_ext_push_data)), 7575 .next = NEXT(action_ipv6_ext_push), 7576 .call = parse_vc_action_ipv6_ext_push, 7577 }, 7578 [ACTION_IPV6_EXT_PUSH_INDEX] = { 7579 .name = "index", 7580 .help = "the index of ipv6_ext_push", 7581 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), 7582 }, 7583 [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { 7584 .name = "{index}", 7585 .type = "UNSIGNED", 7586 .help = "unsigned integer value", 7587 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7588 .call = parse_vc_action_ipv6_ext_push_index, 7589 .comp = comp_set_ipv6_ext_index, 7590 }, 7591 [ACTION_NAT64] = { 7592 .name = "nat64", 7593 .help = "NAT64 IP headers translation", 7594 .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), 7595 .next = NEXT(action_nat64), 7596 .call = parse_vc, 7597 }, 7598 [ACTION_NAT64_MODE] = { 7599 .name = "type", 7600 .help = "NAT64 translation type", 7601 .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), 7602 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), 7603 .call = parse_vc_conf, 7604 }, 7605 /* Top level command. */ 7606 [SET] = { 7607 .name = "set", 7608 .help = "set raw encap/decap/sample data", 7609 .type = "set raw_encap|raw_decap <index> <pattern>" 7610 " or set sample_actions <index> <action>", 7611 .next = NEXT(NEXT_ENTRY 7612 (SET_RAW_ENCAP, 7613 SET_RAW_DECAP, 7614 SET_SAMPLE_ACTIONS, 7615 SET_IPV6_EXT_REMOVE, 7616 SET_IPV6_EXT_PUSH)), 7617 .call = parse_set_init, 7618 }, 7619 /* Sub-level commands. */ 7620 [SET_RAW_ENCAP] = { 7621 .name = "raw_encap", 7622 .help = "set raw encap data", 7623 .next = NEXT(next_set_raw), 7624 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7625 (offsetof(struct buffer, port), 7626 sizeof(((struct buffer *)0)->port), 7627 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7628 .call = parse_set_raw_encap_decap, 7629 }, 7630 [SET_RAW_DECAP] = { 7631 .name = "raw_decap", 7632 .help = "set raw decap data", 7633 .next = NEXT(next_set_raw), 7634 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7635 (offsetof(struct buffer, port), 7636 sizeof(((struct buffer *)0)->port), 7637 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7638 .call = parse_set_raw_encap_decap, 7639 }, 7640 [SET_RAW_INDEX] = { 7641 .name = "{index}", 7642 .type = "COMMON_UNSIGNED", 7643 .help = "index of raw_encap/raw_decap data", 7644 .next = NEXT(next_item), 7645 .call = parse_port, 7646 }, 7647 [SET_SAMPLE_INDEX] = { 7648 .name = "{index}", 7649 .type = "UNSIGNED", 7650 .help = "index of sample actions", 7651 .next = NEXT(next_action_sample), 7652 .call = parse_port, 7653 }, 7654 [SET_SAMPLE_ACTIONS] = { 7655 .name = "sample_actions", 7656 .help = "set sample actions list", 7657 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 7658 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7659 (offsetof(struct buffer, port), 7660 sizeof(((struct buffer *)0)->port), 7661 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 7662 .call = parse_set_sample_action, 7663 }, 7664 [SET_IPV6_EXT_PUSH] = { 7665 .name = "ipv6_ext_push", 7666 .help = "set IPv6 extension header", 7667 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7668 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7669 (offsetof(struct buffer, port), 7670 sizeof(((struct buffer *)0)->port), 7671 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7672 .call = parse_set_ipv6_ext_action, 7673 }, 7674 [SET_IPV6_EXT_REMOVE] = { 7675 .name = "ipv6_ext_remove", 7676 .help = "set IPv6 extension header", 7677 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7678 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7679 (offsetof(struct buffer, port), 7680 sizeof(((struct buffer *)0)->port), 7681 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7682 .call = parse_set_ipv6_ext_action, 7683 }, 7684 [SET_IPV6_EXT_INDEX] = { 7685 .name = "{index}", 7686 .type = "UNSIGNED", 7687 .help = "index of ipv6 extension push/remove actions", 7688 .next = NEXT(item_ipv6_push_ext), 7689 .call = parse_port, 7690 }, 7691 [ITEM_IPV6_PUSH_REMOVE_EXT] = { 7692 .name = "ipv6_ext", 7693 .help = "set IPv6 extension header", 7694 .priv = PRIV_ITEM(IPV6_EXT, 7695 sizeof(struct rte_flow_item_ipv6_ext)), 7696 .next = NEXT(item_ipv6_push_ext_type), 7697 .call = parse_vc, 7698 }, 7699 [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { 7700 .name = "type", 7701 .help = "set IPv6 extension type", 7702 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 7703 next_hdr)), 7704 .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), 7705 item_param), 7706 }, 7707 [ACTION_SET_TAG] = { 7708 .name = "set_tag", 7709 .help = "set tag", 7710 .priv = PRIV_ACTION(SET_TAG, 7711 sizeof(struct rte_flow_action_set_tag)), 7712 .next = NEXT(action_set_tag), 7713 .call = parse_vc, 7714 }, 7715 [ACTION_SET_TAG_INDEX] = { 7716 .name = "index", 7717 .help = "index of tag array", 7718 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7719 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 7720 .call = parse_vc_conf, 7721 }, 7722 [ACTION_SET_TAG_DATA] = { 7723 .name = "data", 7724 .help = "tag value", 7725 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7726 .args = ARGS(ARGS_ENTRY 7727 (struct rte_flow_action_set_tag, data)), 7728 .call = parse_vc_conf, 7729 }, 7730 [ACTION_SET_TAG_MASK] = { 7731 .name = "mask", 7732 .help = "mask for tag value", 7733 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7734 .args = ARGS(ARGS_ENTRY 7735 (struct rte_flow_action_set_tag, mask)), 7736 .call = parse_vc_conf, 7737 }, 7738 [ACTION_SET_META] = { 7739 .name = "set_meta", 7740 .help = "set metadata", 7741 .priv = PRIV_ACTION(SET_META, 7742 sizeof(struct rte_flow_action_set_meta)), 7743 .next = NEXT(action_set_meta), 7744 .call = parse_vc_action_set_meta, 7745 }, 7746 [ACTION_SET_META_DATA] = { 7747 .name = "data", 7748 .help = "metadata value", 7749 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7750 .args = ARGS(ARGS_ENTRY 7751 (struct rte_flow_action_set_meta, data)), 7752 .call = parse_vc_conf, 7753 }, 7754 [ACTION_SET_META_MASK] = { 7755 .name = "mask", 7756 .help = "mask for metadata value", 7757 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7758 .args = ARGS(ARGS_ENTRY 7759 (struct rte_flow_action_set_meta, mask)), 7760 .call = parse_vc_conf, 7761 }, 7762 [ACTION_SET_IPV4_DSCP] = { 7763 .name = "set_ipv4_dscp", 7764 .help = "set DSCP value", 7765 .priv = PRIV_ACTION(SET_IPV4_DSCP, 7766 sizeof(struct rte_flow_action_set_dscp)), 7767 .next = NEXT(action_set_ipv4_dscp), 7768 .call = parse_vc, 7769 }, 7770 [ACTION_SET_IPV4_DSCP_VALUE] = { 7771 .name = "dscp_value", 7772 .help = "new IPv4 DSCP value to set", 7773 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7774 .args = ARGS(ARGS_ENTRY 7775 (struct rte_flow_action_set_dscp, dscp)), 7776 .call = parse_vc_conf, 7777 }, 7778 [ACTION_SET_IPV6_DSCP] = { 7779 .name = "set_ipv6_dscp", 7780 .help = "set DSCP value", 7781 .priv = PRIV_ACTION(SET_IPV6_DSCP, 7782 sizeof(struct rte_flow_action_set_dscp)), 7783 .next = NEXT(action_set_ipv6_dscp), 7784 .call = parse_vc, 7785 }, 7786 [ACTION_SET_IPV6_DSCP_VALUE] = { 7787 .name = "dscp_value", 7788 .help = "new IPv6 DSCP value to set", 7789 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7790 .args = ARGS(ARGS_ENTRY 7791 (struct rte_flow_action_set_dscp, dscp)), 7792 .call = parse_vc_conf, 7793 }, 7794 [ACTION_AGE] = { 7795 .name = "age", 7796 .help = "set a specific metadata header", 7797 .next = NEXT(action_age), 7798 .priv = PRIV_ACTION(AGE, 7799 sizeof(struct rte_flow_action_age)), 7800 .call = parse_vc, 7801 }, 7802 [ACTION_AGE_TIMEOUT] = { 7803 .name = "timeout", 7804 .help = "flow age timeout value", 7805 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 7806 timeout, 24)), 7807 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 7808 .call = parse_vc_conf, 7809 }, 7810 [ACTION_AGE_UPDATE] = { 7811 .name = "age_update", 7812 .help = "update aging parameter", 7813 .next = NEXT(action_age_update), 7814 .priv = PRIV_ACTION(AGE, 7815 sizeof(struct rte_flow_update_age)), 7816 .call = parse_vc, 7817 }, 7818 [ACTION_AGE_UPDATE_TIMEOUT] = { 7819 .name = "timeout", 7820 .help = "age timeout update value", 7821 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7822 timeout, 24)), 7823 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7824 .call = parse_vc_conf_timeout, 7825 }, 7826 [ACTION_AGE_UPDATE_TOUCH] = { 7827 .name = "touch", 7828 .help = "this flow is touched", 7829 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), 7830 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7831 touch, 1)), 7832 .call = parse_vc_conf, 7833 }, 7834 [ACTION_SAMPLE] = { 7835 .name = "sample", 7836 .help = "set a sample action", 7837 .next = NEXT(action_sample), 7838 .priv = PRIV_ACTION(SAMPLE, 7839 sizeof(struct action_sample_data)), 7840 .call = parse_vc_action_sample, 7841 }, 7842 [ACTION_SAMPLE_RATIO] = { 7843 .name = "ratio", 7844 .help = "flow sample ratio value", 7845 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 7846 .args = ARGS(ARGS_ENTRY_ARB 7847 (offsetof(struct action_sample_data, conf) + 7848 offsetof(struct rte_flow_action_sample, ratio), 7849 sizeof(((struct rte_flow_action_sample *)0)-> 7850 ratio))), 7851 }, 7852 [ACTION_SAMPLE_INDEX] = { 7853 .name = "index", 7854 .help = "the index of sample actions list", 7855 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 7856 }, 7857 [ACTION_SAMPLE_INDEX_VALUE] = { 7858 .name = "{index}", 7859 .type = "COMMON_UNSIGNED", 7860 .help = "unsigned integer value", 7861 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7862 .call = parse_vc_action_sample_index, 7863 .comp = comp_set_sample_index, 7864 }, 7865 [ACTION_CONNTRACK] = { 7866 .name = "conntrack", 7867 .help = "create a conntrack object", 7868 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7869 .priv = PRIV_ACTION(CONNTRACK, 7870 sizeof(struct rte_flow_action_conntrack)), 7871 .call = parse_vc, 7872 }, 7873 [ACTION_CONNTRACK_UPDATE] = { 7874 .name = "conntrack_update", 7875 .help = "update a conntrack object", 7876 .next = NEXT(action_update_conntrack), 7877 .priv = PRIV_ACTION(CONNTRACK, 7878 sizeof(struct rte_flow_modify_conntrack)), 7879 .call = parse_vc, 7880 }, 7881 [ACTION_CONNTRACK_UPDATE_DIR] = { 7882 .name = "dir", 7883 .help = "update a conntrack object direction", 7884 .next = NEXT(action_update_conntrack), 7885 .call = parse_vc_action_conntrack_update, 7886 }, 7887 [ACTION_CONNTRACK_UPDATE_CTX] = { 7888 .name = "ctx", 7889 .help = "update a conntrack object context", 7890 .next = NEXT(action_update_conntrack), 7891 .call = parse_vc_action_conntrack_update, 7892 }, 7893 [ACTION_PORT_REPRESENTOR] = { 7894 .name = "port_representor", 7895 .help = "at embedded switch level, send matching traffic to the given ethdev", 7896 .priv = PRIV_ACTION(PORT_REPRESENTOR, 7897 sizeof(struct rte_flow_action_ethdev)), 7898 .next = NEXT(action_port_representor), 7899 .call = parse_vc, 7900 }, 7901 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 7902 .name = "port_id", 7903 .help = "ethdev port ID", 7904 .next = NEXT(action_port_representor, 7905 NEXT_ENTRY(COMMON_UNSIGNED)), 7906 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7907 port_id)), 7908 .call = parse_vc_conf, 7909 }, 7910 [ACTION_REPRESENTED_PORT] = { 7911 .name = "represented_port", 7912 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 7913 .priv = PRIV_ACTION(REPRESENTED_PORT, 7914 sizeof(struct rte_flow_action_ethdev)), 7915 .next = NEXT(action_represented_port), 7916 .call = parse_vc, 7917 }, 7918 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 7919 .name = "ethdev_port_id", 7920 .help = "ethdev port ID", 7921 .next = NEXT(action_represented_port, 7922 NEXT_ENTRY(COMMON_UNSIGNED)), 7923 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7924 port_id)), 7925 .call = parse_vc_conf, 7926 }, 7927 /* Indirect action destroy arguments. */ 7928 [INDIRECT_ACTION_DESTROY_ID] = { 7929 .name = "action_id", 7930 .help = "specify a indirect action id to destroy", 7931 .next = NEXT(next_ia_destroy_attr, 7932 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7933 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 7934 args.ia_destroy.action_id)), 7935 .call = parse_ia_destroy, 7936 }, 7937 /* Indirect action create arguments. */ 7938 [INDIRECT_ACTION_CREATE_ID] = { 7939 .name = "action_id", 7940 .help = "specify a indirect action id to create", 7941 .next = NEXT(next_ia_create_attr, 7942 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7943 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 7944 }, 7945 [ACTION_INDIRECT] = { 7946 .name = "indirect", 7947 .help = "apply indirect action by id", 7948 .priv = PRIV_ACTION(INDIRECT, 0), 7949 .next = NEXT(next_ia), 7950 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7951 .call = parse_vc, 7952 }, 7953 [ACTION_INDIRECT_LIST] = { 7954 .name = "indirect_list", 7955 .help = "apply indirect list action by id", 7956 .priv = PRIV_ACTION(INDIRECT_LIST, 7957 sizeof(struct 7958 rte_flow_action_indirect_list)), 7959 .next = NEXT(next_ial), 7960 .call = parse_vc, 7961 }, 7962 [ACTION_INDIRECT_LIST_HANDLE] = { 7963 .name = "handle", 7964 .help = "indirect list handle", 7965 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), 7966 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7967 }, 7968 [ACTION_INDIRECT_LIST_CONF] = { 7969 .name = "conf", 7970 .help = "indirect list configuration", 7971 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), 7972 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7973 }, 7974 [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { 7975 .type = "UNSIGNED", 7976 .help = "unsigned integer value", 7977 .call = parse_indlst_id2ptr, 7978 .comp = comp_none, 7979 }, 7980 [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { 7981 .type = "UNSIGNED", 7982 .help = "unsigned integer value", 7983 .call = parse_indlst_id2ptr, 7984 .comp = comp_none, 7985 }, 7986 [ACTION_SHARED_INDIRECT] = { 7987 .name = "shared_indirect", 7988 .help = "apply indirect action by id and port", 7989 .priv = PRIV_ACTION(INDIRECT, 0), 7990 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), 7991 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), 7992 ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7993 .call = parse_vc, 7994 }, 7995 [INDIRECT_ACTION_PORT] = { 7996 .name = "{indirect_action_port}", 7997 .type = "INDIRECT_ACTION_PORT", 7998 .help = "indirect action port", 7999 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 8000 .call = parse_ia_port, 8001 .comp = comp_none, 8002 }, 8003 [INDIRECT_ACTION_ID2PTR] = { 8004 .name = "{action_id}", 8005 .type = "INDIRECT_ACTION_ID", 8006 .help = "indirect action id", 8007 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 8008 .call = parse_ia_id2ptr, 8009 .comp = comp_none, 8010 }, 8011 [INDIRECT_ACTION_INGRESS] = { 8012 .name = "ingress", 8013 .help = "affect rule to ingress", 8014 .next = NEXT(next_ia_create_attr), 8015 .call = parse_ia, 8016 }, 8017 [INDIRECT_ACTION_EGRESS] = { 8018 .name = "egress", 8019 .help = "affect rule to egress", 8020 .next = NEXT(next_ia_create_attr), 8021 .call = parse_ia, 8022 }, 8023 [INDIRECT_ACTION_TRANSFER] = { 8024 .name = "transfer", 8025 .help = "affect rule to transfer", 8026 .next = NEXT(next_ia_create_attr), 8027 .call = parse_ia, 8028 }, 8029 [INDIRECT_ACTION_SPEC] = { 8030 .name = "action", 8031 .help = "specify action to create indirect handle", 8032 .next = NEXT(next_action), 8033 }, 8034 [INDIRECT_ACTION_LIST] = { 8035 .name = "list", 8036 .help = "specify actions for indirect handle list", 8037 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 8038 .call = parse_ia, 8039 }, 8040 [INDIRECT_ACTION_FLOW_CONF] = { 8041 .name = "flow_conf", 8042 .help = "specify actions configuration for indirect handle list", 8043 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 8044 .call = parse_ia, 8045 }, 8046 [ACTION_POL_G] = { 8047 .name = "g_actions", 8048 .help = "submit a list of associated actions for green", 8049 .next = NEXT(next_action), 8050 .call = parse_mp, 8051 }, 8052 [ACTION_POL_Y] = { 8053 .name = "y_actions", 8054 .help = "submit a list of associated actions for yellow", 8055 .next = NEXT(next_action), 8056 }, 8057 [ACTION_POL_R] = { 8058 .name = "r_actions", 8059 .help = "submit a list of associated actions for red", 8060 .next = NEXT(next_action), 8061 }, 8062 [ACTION_QUOTA_CREATE] = { 8063 .name = "quota_create", 8064 .help = "create quota action", 8065 .priv = PRIV_ACTION(QUOTA, 8066 sizeof(struct rte_flow_action_quota)), 8067 .next = NEXT(action_quota_create), 8068 .call = parse_vc 8069 }, 8070 [ACTION_QUOTA_CREATE_LIMIT] = { 8071 .name = "limit", 8072 .help = "quota limit", 8073 .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), 8074 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), 8075 .call = parse_vc_conf 8076 }, 8077 [ACTION_QUOTA_CREATE_MODE] = { 8078 .name = "mode", 8079 .help = "quota mode", 8080 .next = NEXT(action_quota_create, 8081 NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), 8082 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), 8083 .call = parse_vc_conf 8084 }, 8085 [ACTION_QUOTA_CREATE_MODE_NAME] = { 8086 .name = "mode_name", 8087 .help = "quota mode name", 8088 .call = parse_quota_mode_name, 8089 .comp = comp_quota_mode_name 8090 }, 8091 [ACTION_QUOTA_QU] = { 8092 .name = "quota_update", 8093 .help = "update quota action", 8094 .priv = PRIV_ACTION(QUOTA, 8095 sizeof(struct rte_flow_update_quota)), 8096 .next = NEXT(action_quota_update), 8097 .call = parse_vc 8098 }, 8099 [ACTION_QUOTA_QU_LIMIT] = { 8100 .name = "limit", 8101 .help = "quota limit", 8102 .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), 8103 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), 8104 .call = parse_vc_conf 8105 }, 8106 [ACTION_QUOTA_QU_UPDATE_OP] = { 8107 .name = "update_op", 8108 .help = "query update op SET|ADD", 8109 .next = NEXT(action_quota_update, 8110 NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), 8111 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), 8112 .call = parse_vc_conf 8113 }, 8114 [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { 8115 .name = "update_op_name", 8116 .help = "quota update op name", 8117 .call = parse_quota_update_name, 8118 .comp = comp_quota_update_name 8119 }, 8120 8121 /* Top-level command. */ 8122 [ADD] = { 8123 .name = "add", 8124 .type = "port meter policy {port_id} {arg}", 8125 .help = "add port meter policy", 8126 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 8127 .call = parse_init, 8128 }, 8129 /* Sub-level commands. */ 8130 [ITEM_POL_PORT] = { 8131 .name = "port", 8132 .help = "add port meter policy", 8133 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 8134 }, 8135 [ITEM_POL_METER] = { 8136 .name = "meter", 8137 .help = "add port meter policy", 8138 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 8139 }, 8140 [ITEM_POL_POLICY] = { 8141 .name = "policy", 8142 .help = "add port meter policy", 8143 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 8144 NEXT_ENTRY(ACTION_POL_Y), 8145 NEXT_ENTRY(ACTION_POL_G), 8146 NEXT_ENTRY(COMMON_POLICY_ID), 8147 NEXT_ENTRY(COMMON_PORT_ID)), 8148 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 8149 ARGS_ENTRY(struct buffer, port)), 8150 .call = parse_mp, 8151 }, 8152 [ITEM_AGGR_AFFINITY] = { 8153 .name = "aggr_affinity", 8154 .help = "match on the aggregated port receiving the packets", 8155 .priv = PRIV_ITEM(AGGR_AFFINITY, 8156 sizeof(struct rte_flow_item_aggr_affinity)), 8157 .next = NEXT(item_aggr_affinity), 8158 .call = parse_vc, 8159 }, 8160 [ITEM_AGGR_AFFINITY_VALUE] = { 8161 .name = "affinity", 8162 .help = "aggregated affinity value", 8163 .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), 8164 item_param), 8165 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, 8166 affinity)), 8167 }, 8168 [ITEM_TX_QUEUE] = { 8169 .name = "tx_queue", 8170 .help = "match on the tx queue of send packet", 8171 .priv = PRIV_ITEM(TX_QUEUE, 8172 sizeof(struct rte_flow_item_tx_queue)), 8173 .next = NEXT(item_tx_queue), 8174 .call = parse_vc, 8175 }, 8176 [ITEM_TX_QUEUE_VALUE] = { 8177 .name = "tx_queue_value", 8178 .help = "tx queue value", 8179 .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), 8180 item_param), 8181 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, 8182 tx_queue)), 8183 }, 8184 }; 8185 8186 /** Remove and return last entry from argument stack. */ 8187 static const struct arg * 8188 pop_args(struct context *ctx) 8189 { 8190 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 8191 } 8192 8193 /** Add entry on top of the argument stack. */ 8194 static int 8195 push_args(struct context *ctx, const struct arg *arg) 8196 { 8197 if (ctx->args_num == CTX_STACK_SIZE) 8198 return -1; 8199 ctx->args[ctx->args_num++] = arg; 8200 return 0; 8201 } 8202 8203 /** Spread value into buffer according to bit-mask. */ 8204 static size_t 8205 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 8206 { 8207 uint32_t i = arg->size; 8208 uint32_t end = 0; 8209 int sub = 1; 8210 int add = 0; 8211 size_t len = 0; 8212 8213 if (!arg->mask) 8214 return 0; 8215 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8216 if (!arg->hton) { 8217 i = 0; 8218 end = arg->size; 8219 sub = 0; 8220 add = 1; 8221 } 8222 #endif 8223 while (i != end) { 8224 unsigned int shift = 0; 8225 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 8226 8227 for (shift = 0; arg->mask[i] >> shift; ++shift) { 8228 if (!(arg->mask[i] & (1 << shift))) 8229 continue; 8230 ++len; 8231 if (!dst) 8232 continue; 8233 *buf &= ~(1 << shift); 8234 *buf |= (val & 1) << shift; 8235 val >>= 1; 8236 } 8237 i += add; 8238 } 8239 return len; 8240 } 8241 8242 /** Compare a string with a partial one of a given length. */ 8243 static int 8244 strcmp_partial(const char *full, const char *partial, size_t partial_len) 8245 { 8246 int r = strncmp(full, partial, partial_len); 8247 8248 if (r) 8249 return r; 8250 if (strlen(full) <= partial_len) 8251 return 0; 8252 return full[partial_len]; 8253 } 8254 8255 /** 8256 * Parse a prefix length and generate a bit-mask. 8257 * 8258 * Last argument (ctx->args) is retrieved to determine mask size, storage 8259 * location and whether the result must use network byte ordering. 8260 */ 8261 static int 8262 parse_prefix(struct context *ctx, const struct token *token, 8263 const char *str, unsigned int len, 8264 void *buf, unsigned int size) 8265 { 8266 const struct arg *arg = pop_args(ctx); 8267 static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff"; 8268 char *end; 8269 uintmax_t u; 8270 unsigned int bytes; 8271 unsigned int extra; 8272 8273 (void)token; 8274 /* Argument is expected. */ 8275 if (!arg) 8276 return -1; 8277 errno = 0; 8278 u = strtoumax(str, &end, 0); 8279 if (errno || (size_t)(end - str) != len) 8280 goto error; 8281 if (arg->mask) { 8282 uintmax_t v = 0; 8283 8284 extra = arg_entry_bf_fill(NULL, 0, arg); 8285 if (u > extra) 8286 goto error; 8287 if (!ctx->object) 8288 return len; 8289 extra -= u; 8290 while (u--) 8291 (v <<= 1, v |= 1); 8292 v <<= extra; 8293 if (!arg_entry_bf_fill(ctx->object, v, arg) || 8294 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 8295 goto error; 8296 return len; 8297 } 8298 bytes = u / 8; 8299 extra = u % 8; 8300 size = arg->size; 8301 if (bytes > size || bytes + !!extra > size) 8302 goto error; 8303 if (!ctx->object) 8304 return len; 8305 buf = (uint8_t *)ctx->object + arg->offset; 8306 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8307 if (!arg->hton) { 8308 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 8309 memset(buf, 0x00, size - bytes); 8310 if (extra) 8311 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 8312 } else 8313 #endif 8314 { 8315 memset(buf, 0xff, bytes); 8316 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 8317 if (extra) 8318 ((uint8_t *)buf)[bytes] = conv[extra]; 8319 } 8320 if (ctx->objmask) 8321 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 8322 return len; 8323 error: 8324 push_args(ctx, arg); 8325 return -1; 8326 } 8327 8328 /** Default parsing function for token name matching. */ 8329 static int 8330 parse_default(struct context *ctx, const struct token *token, 8331 const char *str, unsigned int len, 8332 void *buf, unsigned int size) 8333 { 8334 (void)ctx; 8335 (void)buf; 8336 (void)size; 8337 if (strcmp_partial(token->name, str, len)) 8338 return -1; 8339 return len; 8340 } 8341 8342 /** Parse flow command, initialize output buffer for subsequent tokens. */ 8343 static int 8344 parse_init(struct context *ctx, const struct token *token, 8345 const char *str, unsigned int len, 8346 void *buf, unsigned int size) 8347 { 8348 struct buffer *out = buf; 8349 8350 /* Token name must match. */ 8351 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8352 return -1; 8353 /* Nothing else to do if there is no buffer. */ 8354 if (!out) 8355 return len; 8356 /* Make sure buffer is large enough. */ 8357 if (size < sizeof(*out)) 8358 return -1; 8359 /* Initialize buffer. */ 8360 memset(out, 0x00, sizeof(*out)); 8361 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 8362 ctx->objdata = 0; 8363 ctx->object = out; 8364 ctx->objmask = NULL; 8365 return len; 8366 } 8367 8368 /** Parse tokens for indirect action commands. */ 8369 static int 8370 parse_ia(struct context *ctx, const struct token *token, 8371 const char *str, unsigned int len, 8372 void *buf, unsigned int size) 8373 { 8374 struct buffer *out = buf; 8375 8376 /* Token name must match. */ 8377 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8378 return -1; 8379 /* Nothing else to do if there is no buffer. */ 8380 if (!out) 8381 return len; 8382 if (!out->command) { 8383 if (ctx->curr != INDIRECT_ACTION) 8384 return -1; 8385 if (sizeof(*out) > size) 8386 return -1; 8387 out->command = ctx->curr; 8388 ctx->objdata = 0; 8389 ctx->object = out; 8390 ctx->objmask = NULL; 8391 out->args.vc.data = (uint8_t *)out + size; 8392 return len; 8393 } 8394 switch (ctx->curr) { 8395 case INDIRECT_ACTION_CREATE: 8396 case INDIRECT_ACTION_UPDATE: 8397 case INDIRECT_ACTION_QUERY_UPDATE: 8398 out->args.vc.actions = 8399 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8400 sizeof(double)); 8401 out->args.vc.attr.group = UINT32_MAX; 8402 /* fallthrough */ 8403 case INDIRECT_ACTION_QUERY: 8404 out->command = ctx->curr; 8405 ctx->objdata = 0; 8406 ctx->object = out; 8407 ctx->objmask = NULL; 8408 return len; 8409 case INDIRECT_ACTION_EGRESS: 8410 out->args.vc.attr.egress = 1; 8411 return len; 8412 case INDIRECT_ACTION_INGRESS: 8413 out->args.vc.attr.ingress = 1; 8414 return len; 8415 case INDIRECT_ACTION_TRANSFER: 8416 out->args.vc.attr.transfer = 1; 8417 return len; 8418 case INDIRECT_ACTION_QU_MODE: 8419 return len; 8420 case INDIRECT_ACTION_LIST: 8421 out->command = INDIRECT_ACTION_LIST_CREATE; 8422 return len; 8423 case INDIRECT_ACTION_FLOW_CONF: 8424 out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; 8425 return len; 8426 default: 8427 return -1; 8428 } 8429 } 8430 8431 8432 /** Parse tokens for indirect action destroy command. */ 8433 static int 8434 parse_ia_destroy(struct context *ctx, const struct token *token, 8435 const char *str, unsigned int len, 8436 void *buf, unsigned int size) 8437 { 8438 struct buffer *out = buf; 8439 uint32_t *action_id; 8440 8441 /* Token name must match. */ 8442 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8443 return -1; 8444 /* Nothing else to do if there is no buffer. */ 8445 if (!out) 8446 return len; 8447 if (!out->command || out->command == INDIRECT_ACTION) { 8448 if (ctx->curr != INDIRECT_ACTION_DESTROY) 8449 return -1; 8450 if (sizeof(*out) > size) 8451 return -1; 8452 out->command = ctx->curr; 8453 ctx->objdata = 0; 8454 ctx->object = out; 8455 ctx->objmask = NULL; 8456 out->args.ia_destroy.action_id = 8457 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8458 sizeof(double)); 8459 return len; 8460 } 8461 action_id = out->args.ia_destroy.action_id 8462 + out->args.ia_destroy.action_id_n++; 8463 if ((uint8_t *)action_id > (uint8_t *)out + size) 8464 return -1; 8465 ctx->objdata = 0; 8466 ctx->object = action_id; 8467 ctx->objmask = NULL; 8468 return len; 8469 } 8470 8471 /** Parse tokens for indirect action commands. */ 8472 static int 8473 parse_qia(struct context *ctx, const struct token *token, 8474 const char *str, unsigned int len, 8475 void *buf, unsigned int size) 8476 { 8477 struct buffer *out = buf; 8478 8479 /* Token name must match. */ 8480 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8481 return -1; 8482 /* Nothing else to do if there is no buffer. */ 8483 if (!out) 8484 return len; 8485 if (!out->command) { 8486 if (ctx->curr != QUEUE) 8487 return -1; 8488 if (sizeof(*out) > size) 8489 return -1; 8490 out->args.vc.data = (uint8_t *)out + size; 8491 return len; 8492 } 8493 switch (ctx->curr) { 8494 case QUEUE_INDIRECT_ACTION: 8495 return len; 8496 case QUEUE_INDIRECT_ACTION_CREATE: 8497 case QUEUE_INDIRECT_ACTION_UPDATE: 8498 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 8499 out->args.vc.actions = 8500 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8501 sizeof(double)); 8502 out->args.vc.attr.group = UINT32_MAX; 8503 /* fallthrough */ 8504 case QUEUE_INDIRECT_ACTION_QUERY: 8505 out->command = ctx->curr; 8506 ctx->objdata = 0; 8507 ctx->object = out; 8508 ctx->objmask = NULL; 8509 return len; 8510 case QUEUE_INDIRECT_ACTION_EGRESS: 8511 out->args.vc.attr.egress = 1; 8512 return len; 8513 case QUEUE_INDIRECT_ACTION_INGRESS: 8514 out->args.vc.attr.ingress = 1; 8515 return len; 8516 case QUEUE_INDIRECT_ACTION_TRANSFER: 8517 out->args.vc.attr.transfer = 1; 8518 return len; 8519 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 8520 return len; 8521 case QUEUE_INDIRECT_ACTION_QU_MODE: 8522 return len; 8523 case QUEUE_INDIRECT_ACTION_LIST: 8524 out->command = QUEUE_INDIRECT_ACTION_LIST_CREATE; 8525 return len; 8526 default: 8527 return -1; 8528 } 8529 } 8530 8531 /** Parse tokens for indirect action destroy command. */ 8532 static int 8533 parse_qia_destroy(struct context *ctx, const struct token *token, 8534 const char *str, unsigned int len, 8535 void *buf, unsigned int size) 8536 { 8537 struct buffer *out = buf; 8538 uint32_t *action_id; 8539 8540 /* Token name must match. */ 8541 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8542 return -1; 8543 /* Nothing else to do if there is no buffer. */ 8544 if (!out) 8545 return len; 8546 if (!out->command || out->command == QUEUE) { 8547 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 8548 return -1; 8549 if (sizeof(*out) > size) 8550 return -1; 8551 out->command = ctx->curr; 8552 ctx->objdata = 0; 8553 ctx->object = out; 8554 ctx->objmask = NULL; 8555 out->args.ia_destroy.action_id = 8556 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8557 sizeof(double)); 8558 return len; 8559 } 8560 switch (ctx->curr) { 8561 case QUEUE_INDIRECT_ACTION: 8562 out->command = ctx->curr; 8563 ctx->objdata = 0; 8564 ctx->object = out; 8565 ctx->objmask = NULL; 8566 return len; 8567 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 8568 action_id = out->args.ia_destroy.action_id 8569 + out->args.ia_destroy.action_id_n++; 8570 if ((uint8_t *)action_id > (uint8_t *)out + size) 8571 return -1; 8572 ctx->objdata = 0; 8573 ctx->object = action_id; 8574 ctx->objmask = NULL; 8575 return len; 8576 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 8577 return len; 8578 default: 8579 return -1; 8580 } 8581 } 8582 8583 /** Parse tokens for meter policy action commands. */ 8584 static int 8585 parse_mp(struct context *ctx, const struct token *token, 8586 const char *str, unsigned int len, 8587 void *buf, unsigned int size) 8588 { 8589 struct buffer *out = buf; 8590 8591 /* Token name must match. */ 8592 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8593 return -1; 8594 /* Nothing else to do if there is no buffer. */ 8595 if (!out) 8596 return len; 8597 if (!out->command) { 8598 if (ctx->curr != ITEM_POL_POLICY) 8599 return -1; 8600 if (sizeof(*out) > size) 8601 return -1; 8602 out->command = ctx->curr; 8603 ctx->objdata = 0; 8604 ctx->object = out; 8605 ctx->objmask = NULL; 8606 out->args.vc.data = (uint8_t *)out + size; 8607 return len; 8608 } 8609 switch (ctx->curr) { 8610 case ACTION_POL_G: 8611 out->args.vc.actions = 8612 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8613 sizeof(double)); 8614 out->command = ctx->curr; 8615 ctx->objdata = 0; 8616 ctx->object = out; 8617 ctx->objmask = NULL; 8618 return len; 8619 default: 8620 return -1; 8621 } 8622 } 8623 8624 /** Parse tokens for validate/create commands. */ 8625 static int 8626 parse_vc(struct context *ctx, const struct token *token, 8627 const char *str, unsigned int len, 8628 void *buf, unsigned int size) 8629 { 8630 struct buffer *out = buf; 8631 uint8_t *data; 8632 uint32_t data_size; 8633 8634 /* Token name must match. */ 8635 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8636 return -1; 8637 /* Nothing else to do if there is no buffer. */ 8638 if (!out) 8639 return len; 8640 if (!out->command) { 8641 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 8642 ctx->curr != PATTERN_TEMPLATE_CREATE && 8643 ctx->curr != ACTIONS_TEMPLATE_CREATE && 8644 ctx->curr != UPDATE) 8645 return -1; 8646 if (ctx->curr == UPDATE) 8647 out->args.vc.pattern = 8648 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8649 sizeof(double)); 8650 if (sizeof(*out) > size) 8651 return -1; 8652 out->command = ctx->curr; 8653 ctx->objdata = 0; 8654 ctx->object = out; 8655 ctx->objmask = NULL; 8656 out->args.vc.data = (uint8_t *)out + size; 8657 return len; 8658 } 8659 ctx->objdata = 0; 8660 switch (ctx->curr) { 8661 default: 8662 ctx->object = &out->args.vc.attr; 8663 break; 8664 case VC_TUNNEL_SET: 8665 case VC_TUNNEL_MATCH: 8666 ctx->object = &out->args.vc.tunnel_ops; 8667 break; 8668 case VC_USER_ID: 8669 ctx->object = out; 8670 break; 8671 } 8672 ctx->objmask = NULL; 8673 switch (ctx->curr) { 8674 case VC_GROUP: 8675 case VC_PRIORITY: 8676 case VC_USER_ID: 8677 return len; 8678 case VC_TUNNEL_SET: 8679 out->args.vc.tunnel_ops.enabled = 1; 8680 out->args.vc.tunnel_ops.actions = 1; 8681 return len; 8682 case VC_TUNNEL_MATCH: 8683 out->args.vc.tunnel_ops.enabled = 1; 8684 out->args.vc.tunnel_ops.items = 1; 8685 return len; 8686 case VC_INGRESS: 8687 out->args.vc.attr.ingress = 1; 8688 return len; 8689 case VC_EGRESS: 8690 out->args.vc.attr.egress = 1; 8691 return len; 8692 case VC_TRANSFER: 8693 out->args.vc.attr.transfer = 1; 8694 return len; 8695 case ITEM_PATTERN: 8696 out->args.vc.pattern = 8697 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8698 sizeof(double)); 8699 ctx->object = out->args.vc.pattern; 8700 ctx->objmask = NULL; 8701 return len; 8702 case ITEM_END: 8703 if ((out->command == VALIDATE || out->command == CREATE) && 8704 ctx->last) 8705 return -1; 8706 if (out->command == PATTERN_TEMPLATE_CREATE && 8707 !ctx->last) 8708 return -1; 8709 break; 8710 case ACTIONS: 8711 out->args.vc.actions = out->args.vc.pattern ? 8712 (void *)RTE_ALIGN_CEIL((uintptr_t) 8713 (out->args.vc.pattern + 8714 out->args.vc.pattern_n), 8715 sizeof(double)) : 8716 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8717 sizeof(double)); 8718 ctx->object = out->args.vc.actions; 8719 ctx->objmask = NULL; 8720 return len; 8721 case VC_IS_USER_ID: 8722 out->args.vc.user_id = true; 8723 return len; 8724 default: 8725 if (!token->priv) 8726 return -1; 8727 break; 8728 } 8729 if (!out->args.vc.actions) { 8730 const struct parse_item_priv *priv = token->priv; 8731 struct rte_flow_item *item = 8732 out->args.vc.pattern + out->args.vc.pattern_n; 8733 8734 data_size = priv->size * 3; /* spec, last, mask */ 8735 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8736 (out->args.vc.data - data_size), 8737 sizeof(double)); 8738 if ((uint8_t *)item + sizeof(*item) > data) 8739 return -1; 8740 *item = (struct rte_flow_item){ 8741 .type = priv->type, 8742 }; 8743 ++out->args.vc.pattern_n; 8744 ctx->object = item; 8745 ctx->objmask = NULL; 8746 } else { 8747 const struct parse_action_priv *priv = token->priv; 8748 struct rte_flow_action *action = 8749 out->args.vc.actions + out->args.vc.actions_n; 8750 8751 data_size = priv->size; /* configuration */ 8752 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8753 (out->args.vc.data - data_size), 8754 sizeof(double)); 8755 if ((uint8_t *)action + sizeof(*action) > data) 8756 return -1; 8757 *action = (struct rte_flow_action){ 8758 .type = priv->type, 8759 .conf = data_size ? data : NULL, 8760 }; 8761 ++out->args.vc.actions_n; 8762 ctx->object = action; 8763 ctx->objmask = NULL; 8764 } 8765 memset(data, 0, data_size); 8766 out->args.vc.data = data; 8767 ctx->objdata = data_size; 8768 return len; 8769 } 8770 8771 /** Parse pattern item parameter type. */ 8772 static int 8773 parse_vc_spec(struct context *ctx, const struct token *token, 8774 const char *str, unsigned int len, 8775 void *buf, unsigned int size) 8776 { 8777 struct buffer *out = buf; 8778 struct rte_flow_item *item; 8779 uint32_t data_size; 8780 int index; 8781 int objmask = 0; 8782 8783 (void)size; 8784 /* Token name must match. */ 8785 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8786 return -1; 8787 /* Parse parameter types. */ 8788 switch (ctx->curr) { 8789 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 8790 8791 case ITEM_PARAM_IS: 8792 index = 0; 8793 objmask = 1; 8794 break; 8795 case ITEM_PARAM_SPEC: 8796 index = 0; 8797 break; 8798 case ITEM_PARAM_LAST: 8799 index = 1; 8800 break; 8801 case ITEM_PARAM_PREFIX: 8802 /* Modify next token to expect a prefix. */ 8803 if (ctx->next_num < 2) 8804 return -1; 8805 ctx->next[ctx->next_num - 2] = prefix; 8806 /* Fall through. */ 8807 case ITEM_PARAM_MASK: 8808 index = 2; 8809 break; 8810 default: 8811 return -1; 8812 } 8813 /* Nothing else to do if there is no buffer. */ 8814 if (!out) 8815 return len; 8816 if (!out->args.vc.pattern_n) 8817 return -1; 8818 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8819 data_size = ctx->objdata / 3; /* spec, last, mask */ 8820 /* Point to selected object. */ 8821 ctx->object = out->args.vc.data + (data_size * index); 8822 if (objmask) { 8823 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 8824 item->mask = ctx->objmask; 8825 } else 8826 ctx->objmask = NULL; 8827 /* Update relevant item pointer. */ 8828 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 8829 ctx->object; 8830 return len; 8831 } 8832 8833 /** Parse action configuration field. */ 8834 static int 8835 parse_vc_conf(struct context *ctx, const struct token *token, 8836 const char *str, unsigned int len, 8837 void *buf, unsigned int size) 8838 { 8839 struct buffer *out = buf; 8840 8841 (void)size; 8842 /* Token name must match. */ 8843 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8844 return -1; 8845 /* Nothing else to do if there is no buffer. */ 8846 if (!out) 8847 return len; 8848 /* Point to selected object. */ 8849 ctx->object = out->args.vc.data; 8850 ctx->objmask = NULL; 8851 return len; 8852 } 8853 8854 /** Parse action configuration field. */ 8855 static int 8856 parse_vc_conf_timeout(struct context *ctx, const struct token *token, 8857 const char *str, unsigned int len, 8858 void *buf, unsigned int size) 8859 { 8860 struct buffer *out = buf; 8861 struct rte_flow_update_age *update; 8862 8863 (void)size; 8864 if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) 8865 return -1; 8866 /* Token name must match. */ 8867 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8868 return -1; 8869 /* Nothing else to do if there is no buffer. */ 8870 if (!out) 8871 return len; 8872 /* Point to selected object. */ 8873 ctx->object = out->args.vc.data; 8874 ctx->objmask = NULL; 8875 /* Update the timeout is valid. */ 8876 update = (struct rte_flow_update_age *)out->args.vc.data; 8877 update->timeout_valid = 1; 8878 return len; 8879 } 8880 8881 /** Parse eCPRI common header type field. */ 8882 static int 8883 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 8884 const char *str, unsigned int len, 8885 void *buf, unsigned int size) 8886 { 8887 struct rte_flow_item_ecpri *ecpri; 8888 struct rte_flow_item_ecpri *ecpri_mask; 8889 struct rte_flow_item *item; 8890 uint32_t data_size; 8891 uint8_t msg_type; 8892 struct buffer *out = buf; 8893 const struct arg *arg; 8894 8895 (void)size; 8896 /* Token name must match. */ 8897 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8898 return -1; 8899 switch (ctx->curr) { 8900 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 8901 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 8902 break; 8903 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 8904 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 8905 break; 8906 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 8907 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 8908 break; 8909 default: 8910 return -1; 8911 } 8912 if (!ctx->object) 8913 return len; 8914 arg = pop_args(ctx); 8915 if (!arg) 8916 return -1; 8917 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 8918 ecpri->hdr.common.type = msg_type; 8919 data_size = ctx->objdata / 3; /* spec, last, mask */ 8920 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 8921 (data_size * 2)); 8922 ecpri_mask->hdr.common.type = 0xFF; 8923 if (arg->hton) { 8924 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 8925 ecpri_mask->hdr.common.u32 = 8926 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 8927 } 8928 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8929 item->spec = ecpri; 8930 item->mask = ecpri_mask; 8931 return len; 8932 } 8933 8934 /** Parse L2TPv2 common header type field. */ 8935 static int 8936 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, 8937 const char *str, unsigned int len, 8938 void *buf, unsigned int size) 8939 { 8940 struct rte_flow_item_l2tpv2 *l2tpv2; 8941 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 8942 struct rte_flow_item *item; 8943 uint32_t data_size; 8944 uint16_t msg_type = 0; 8945 struct buffer *out = buf; 8946 const struct arg *arg; 8947 8948 (void)size; 8949 /* Token name must match. */ 8950 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8951 return -1; 8952 switch (ctx->curr) { 8953 case ITEM_L2TPV2_TYPE_DATA: 8954 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 8955 break; 8956 case ITEM_L2TPV2_TYPE_DATA_L: 8957 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 8958 break; 8959 case ITEM_L2TPV2_TYPE_DATA_S: 8960 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 8961 break; 8962 case ITEM_L2TPV2_TYPE_DATA_O: 8963 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 8964 break; 8965 case ITEM_L2TPV2_TYPE_DATA_L_S: 8966 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 8967 break; 8968 case ITEM_L2TPV2_TYPE_CTRL: 8969 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 8970 break; 8971 default: 8972 return -1; 8973 } 8974 if (!ctx->object) 8975 return len; 8976 arg = pop_args(ctx); 8977 if (!arg) 8978 return -1; 8979 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 8980 l2tpv2->hdr.common.flags_version |= msg_type; 8981 data_size = ctx->objdata / 3; /* spec, last, mask */ 8982 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 8983 (data_size * 2)); 8984 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 8985 if (arg->hton) { 8986 l2tpv2->hdr.common.flags_version = 8987 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 8988 l2tpv2_mask->hdr.common.flags_version = 8989 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 8990 } 8991 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8992 item->spec = l2tpv2; 8993 item->mask = l2tpv2_mask; 8994 return len; 8995 } 8996 8997 /** Parse operation for compare match item. */ 8998 static int 8999 parse_vc_compare_op(struct context *ctx, const struct token *token, 9000 const char *str, unsigned int len, void *buf, 9001 unsigned int size) 9002 { 9003 struct rte_flow_item_compare *compare_item; 9004 unsigned int i; 9005 9006 (void)token; 9007 (void)buf; 9008 (void)size; 9009 if (ctx->curr != ITEM_COMPARE_OP_VALUE) 9010 return -1; 9011 for (i = 0; compare_ops[i]; ++i) 9012 if (!strcmp_partial(compare_ops[i], str, len)) 9013 break; 9014 if (!compare_ops[i]) 9015 return -1; 9016 if (!ctx->object) 9017 return len; 9018 compare_item = ctx->object; 9019 compare_item->operation = (enum rte_flow_item_compare_op)i; 9020 return len; 9021 } 9022 9023 /** Parse id for compare match item. */ 9024 static int 9025 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 9026 const char *str, unsigned int len, void *buf, 9027 unsigned int size) 9028 { 9029 struct rte_flow_item_compare *compare_item; 9030 unsigned int i; 9031 9032 (void)token; 9033 (void)buf; 9034 (void)size; 9035 if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE && 9036 ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE) 9037 return -1; 9038 for (i = 0; flow_field_ids[i]; ++i) 9039 if (!strcmp_partial(flow_field_ids[i], str, len)) 9040 break; 9041 if (!flow_field_ids[i]) 9042 return -1; 9043 if (!ctx->object) 9044 return len; 9045 compare_item = ctx->object; 9046 if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE) 9047 compare_item->a.field = (enum rte_flow_field_id)i; 9048 else 9049 compare_item->b.field = (enum rte_flow_field_id)i; 9050 return len; 9051 } 9052 9053 /** Parse level for compare match item. */ 9054 static int 9055 parse_vc_compare_field_level(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 struct flex_item *fp = NULL; 9061 uint32_t val; 9062 struct buffer *out = buf; 9063 char *end; 9064 9065 (void)token; 9066 (void)size; 9067 if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 9068 ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE) 9069 return -1; 9070 if (!ctx->object) 9071 return len; 9072 compare_item = ctx->object; 9073 errno = 0; 9074 val = strtoumax(str, &end, 0); 9075 if (errno || (size_t)(end - str) != len) 9076 return -1; 9077 /* No need to validate action template mask value */ 9078 if (out->args.vc.masks) { 9079 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) 9080 compare_item->a.level = val; 9081 else 9082 compare_item->b.level = val; 9083 return len; 9084 } 9085 if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 9086 compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) || 9087 (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE && 9088 compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 9089 if (val >= FLEX_MAX_PARSERS_NUM) { 9090 printf("Bad flex item handle\n"); 9091 return -1; 9092 } 9093 fp = flex_items[ctx->port][val]; 9094 if (!fp) { 9095 printf("Bad flex item handle\n"); 9096 return -1; 9097 } 9098 } 9099 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) { 9100 if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM) 9101 compare_item->a.level = val; 9102 else 9103 compare_item->a.flex_handle = fp->flex_handle; 9104 } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) { 9105 if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM) 9106 compare_item->b.level = val; 9107 else 9108 compare_item->b.flex_handle = fp->flex_handle; 9109 } 9110 return len; 9111 } 9112 9113 /** Parse meter color action type. */ 9114 static int 9115 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 9116 const char *str, unsigned int len, 9117 void *buf, unsigned int size) 9118 { 9119 struct rte_flow_action *action_data; 9120 struct rte_flow_action_meter_color *conf; 9121 enum rte_color color; 9122 9123 (void)buf; 9124 (void)size; 9125 /* Token name must match. */ 9126 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9127 return -1; 9128 switch (ctx->curr) { 9129 case ACTION_METER_COLOR_GREEN: 9130 color = RTE_COLOR_GREEN; 9131 break; 9132 case ACTION_METER_COLOR_YELLOW: 9133 color = RTE_COLOR_YELLOW; 9134 break; 9135 case ACTION_METER_COLOR_RED: 9136 color = RTE_COLOR_RED; 9137 break; 9138 default: 9139 return -1; 9140 } 9141 9142 if (!ctx->object) 9143 return len; 9144 action_data = ctx->object; 9145 conf = (struct rte_flow_action_meter_color *) 9146 (uintptr_t)(action_data->conf); 9147 conf->color = color; 9148 return len; 9149 } 9150 9151 /** Parse RSS action. */ 9152 static int 9153 parse_vc_action_rss(struct context *ctx, const struct token *token, 9154 const char *str, unsigned int len, 9155 void *buf, unsigned int size) 9156 { 9157 struct buffer *out = buf; 9158 struct rte_flow_action *action; 9159 struct action_rss_data *action_rss_data; 9160 unsigned int i; 9161 int ret; 9162 9163 ret = parse_vc(ctx, token, str, len, buf, size); 9164 if (ret < 0) 9165 return ret; 9166 /* Nothing else to do if there is no buffer. */ 9167 if (!out) 9168 return ret; 9169 if (!out->args.vc.actions_n) 9170 return -1; 9171 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9172 /* Point to selected object. */ 9173 ctx->object = out->args.vc.data; 9174 ctx->objmask = NULL; 9175 /* Set up default configuration. */ 9176 action_rss_data = ctx->object; 9177 *action_rss_data = (struct action_rss_data){ 9178 .conf = (struct rte_flow_action_rss){ 9179 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 9180 .level = 0, 9181 .types = rss_hf, 9182 .key_len = 0, 9183 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 9184 .key = NULL, 9185 .queue = action_rss_data->queue, 9186 }, 9187 .queue = { 0 }, 9188 }; 9189 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 9190 action_rss_data->queue[i] = i; 9191 action->conf = &action_rss_data->conf; 9192 return ret; 9193 } 9194 9195 /** 9196 * Parse func field for RSS action. 9197 * 9198 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 9199 * ACTION_RSS_FUNC_* index that called this function. 9200 */ 9201 static int 9202 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 9203 const char *str, unsigned int len, 9204 void *buf, unsigned int size) 9205 { 9206 struct action_rss_data *action_rss_data; 9207 enum rte_eth_hash_function func; 9208 9209 (void)buf; 9210 (void)size; 9211 /* Token name must match. */ 9212 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9213 return -1; 9214 switch (ctx->curr) { 9215 case ACTION_RSS_FUNC_DEFAULT: 9216 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 9217 break; 9218 case ACTION_RSS_FUNC_TOEPLITZ: 9219 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 9220 break; 9221 case ACTION_RSS_FUNC_SIMPLE_XOR: 9222 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 9223 break; 9224 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 9225 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 9226 break; 9227 default: 9228 return -1; 9229 } 9230 if (!ctx->object) 9231 return len; 9232 action_rss_data = ctx->object; 9233 action_rss_data->conf.func = func; 9234 return len; 9235 } 9236 9237 /** 9238 * Parse type field for RSS action. 9239 * 9240 * Valid tokens are type field names and the "end" token. 9241 */ 9242 static int 9243 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 9244 const char *str, unsigned int len, 9245 void *buf, unsigned int size) 9246 { 9247 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 9248 struct action_rss_data *action_rss_data; 9249 unsigned int i; 9250 9251 (void)token; 9252 (void)buf; 9253 (void)size; 9254 if (ctx->curr != ACTION_RSS_TYPE) 9255 return -1; 9256 if (!(ctx->objdata >> 16) && ctx->object) { 9257 action_rss_data = ctx->object; 9258 action_rss_data->conf.types = 0; 9259 } 9260 if (!strcmp_partial("end", str, len)) { 9261 ctx->objdata &= 0xffff; 9262 return len; 9263 } 9264 for (i = 0; rss_type_table[i].str; ++i) 9265 if (!strcmp_partial(rss_type_table[i].str, str, len)) 9266 break; 9267 if (!rss_type_table[i].str) 9268 return -1; 9269 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 9270 /* Repeat token. */ 9271 if (ctx->next_num == RTE_DIM(ctx->next)) 9272 return -1; 9273 ctx->next[ctx->next_num++] = next; 9274 if (!ctx->object) 9275 return len; 9276 action_rss_data = ctx->object; 9277 action_rss_data->conf.types |= rss_type_table[i].rss_type; 9278 return len; 9279 } 9280 9281 /** 9282 * Parse queue field for RSS action. 9283 * 9284 * Valid tokens are queue indices and the "end" token. 9285 */ 9286 static int 9287 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 9288 const char *str, unsigned int len, 9289 void *buf, unsigned int size) 9290 { 9291 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 9292 struct action_rss_data *action_rss_data; 9293 const struct arg *arg; 9294 int ret; 9295 int i; 9296 9297 (void)token; 9298 (void)buf; 9299 (void)size; 9300 if (ctx->curr != ACTION_RSS_QUEUE) 9301 return -1; 9302 i = ctx->objdata >> 16; 9303 if (!strcmp_partial("end", str, len)) { 9304 ctx->objdata &= 0xffff; 9305 goto end; 9306 } 9307 if (i >= ACTION_RSS_QUEUE_NUM) 9308 return -1; 9309 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 9310 i * sizeof(action_rss_data->queue[i]), 9311 sizeof(action_rss_data->queue[i])); 9312 if (push_args(ctx, arg)) 9313 return -1; 9314 ret = parse_int(ctx, token, str, len, NULL, 0); 9315 if (ret < 0) { 9316 pop_args(ctx); 9317 return -1; 9318 } 9319 ++i; 9320 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 9321 /* Repeat token. */ 9322 if (ctx->next_num == RTE_DIM(ctx->next)) 9323 return -1; 9324 ctx->next[ctx->next_num++] = next; 9325 end: 9326 if (!ctx->object) 9327 return len; 9328 action_rss_data = ctx->object; 9329 action_rss_data->conf.queue_num = i; 9330 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 9331 return len; 9332 } 9333 9334 /** Setup VXLAN encap configuration. */ 9335 static int 9336 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 9337 { 9338 /* Set up default configuration. */ 9339 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 9340 .conf = (struct rte_flow_action_vxlan_encap){ 9341 .definition = action_vxlan_encap_data->items, 9342 }, 9343 .items = { 9344 { 9345 .type = RTE_FLOW_ITEM_TYPE_ETH, 9346 .spec = &action_vxlan_encap_data->item_eth, 9347 .mask = &rte_flow_item_eth_mask, 9348 }, 9349 { 9350 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9351 .spec = &action_vxlan_encap_data->item_vlan, 9352 .mask = &rte_flow_item_vlan_mask, 9353 }, 9354 { 9355 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9356 .spec = &action_vxlan_encap_data->item_ipv4, 9357 .mask = &rte_flow_item_ipv4_mask, 9358 }, 9359 { 9360 .type = RTE_FLOW_ITEM_TYPE_UDP, 9361 .spec = &action_vxlan_encap_data->item_udp, 9362 .mask = &rte_flow_item_udp_mask, 9363 }, 9364 { 9365 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 9366 .spec = &action_vxlan_encap_data->item_vxlan, 9367 .mask = &rte_flow_item_vxlan_mask, 9368 }, 9369 { 9370 .type = RTE_FLOW_ITEM_TYPE_END, 9371 }, 9372 }, 9373 .item_eth.hdr.ether_type = 0, 9374 .item_vlan = { 9375 .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, 9376 .hdr.eth_proto = 0, 9377 }, 9378 .item_ipv4.hdr = { 9379 .src_addr = vxlan_encap_conf.ipv4_src, 9380 .dst_addr = vxlan_encap_conf.ipv4_dst, 9381 }, 9382 .item_udp.hdr = { 9383 .src_port = vxlan_encap_conf.udp_src, 9384 .dst_port = vxlan_encap_conf.udp_dst, 9385 }, 9386 .item_vxlan.hdr.flags = 0, 9387 }; 9388 memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9389 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9390 memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, 9391 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9392 if (!vxlan_encap_conf.select_ipv4) { 9393 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 9394 &vxlan_encap_conf.ipv6_src, 9395 sizeof(vxlan_encap_conf.ipv6_src)); 9396 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 9397 &vxlan_encap_conf.ipv6_dst, 9398 sizeof(vxlan_encap_conf.ipv6_dst)); 9399 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 9400 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9401 .spec = &action_vxlan_encap_data->item_ipv6, 9402 .mask = &rte_flow_item_ipv6_mask, 9403 }; 9404 } 9405 if (!vxlan_encap_conf.select_vlan) 9406 action_vxlan_encap_data->items[1].type = 9407 RTE_FLOW_ITEM_TYPE_VOID; 9408 if (vxlan_encap_conf.select_tos_ttl) { 9409 if (vxlan_encap_conf.select_ipv4) { 9410 static struct rte_flow_item_ipv4 ipv4_mask_tos; 9411 9412 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 9413 sizeof(ipv4_mask_tos)); 9414 ipv4_mask_tos.hdr.type_of_service = 0xff; 9415 ipv4_mask_tos.hdr.time_to_live = 0xff; 9416 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 9417 vxlan_encap_conf.ip_tos; 9418 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 9419 vxlan_encap_conf.ip_ttl; 9420 action_vxlan_encap_data->items[2].mask = 9421 &ipv4_mask_tos; 9422 } else { 9423 static struct rte_flow_item_ipv6 ipv6_mask_tos; 9424 9425 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 9426 sizeof(ipv6_mask_tos)); 9427 ipv6_mask_tos.hdr.vtc_flow |= 9428 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 9429 ipv6_mask_tos.hdr.hop_limits = 0xff; 9430 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 9431 rte_cpu_to_be_32 9432 ((uint32_t)vxlan_encap_conf.ip_tos << 9433 RTE_IPV6_HDR_TC_SHIFT); 9434 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 9435 vxlan_encap_conf.ip_ttl; 9436 action_vxlan_encap_data->items[2].mask = 9437 &ipv6_mask_tos; 9438 } 9439 } 9440 memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, 9441 RTE_DIM(vxlan_encap_conf.vni)); 9442 return 0; 9443 } 9444 9445 /** Parse VXLAN encap action. */ 9446 static int 9447 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 9448 const char *str, unsigned int len, 9449 void *buf, unsigned int size) 9450 { 9451 struct buffer *out = buf; 9452 struct rte_flow_action *action; 9453 struct action_vxlan_encap_data *action_vxlan_encap_data; 9454 int ret; 9455 9456 ret = parse_vc(ctx, token, str, len, buf, size); 9457 if (ret < 0) 9458 return ret; 9459 /* Nothing else to do if there is no buffer. */ 9460 if (!out) 9461 return ret; 9462 if (!out->args.vc.actions_n) 9463 return -1; 9464 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9465 /* Point to selected object. */ 9466 ctx->object = out->args.vc.data; 9467 ctx->objmask = NULL; 9468 action_vxlan_encap_data = ctx->object; 9469 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 9470 action->conf = &action_vxlan_encap_data->conf; 9471 return ret; 9472 } 9473 9474 /** Setup NVGRE encap configuration. */ 9475 static int 9476 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 9477 { 9478 /* Set up default configuration. */ 9479 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 9480 .conf = (struct rte_flow_action_nvgre_encap){ 9481 .definition = action_nvgre_encap_data->items, 9482 }, 9483 .items = { 9484 { 9485 .type = RTE_FLOW_ITEM_TYPE_ETH, 9486 .spec = &action_nvgre_encap_data->item_eth, 9487 .mask = &rte_flow_item_eth_mask, 9488 }, 9489 { 9490 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9491 .spec = &action_nvgre_encap_data->item_vlan, 9492 .mask = &rte_flow_item_vlan_mask, 9493 }, 9494 { 9495 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9496 .spec = &action_nvgre_encap_data->item_ipv4, 9497 .mask = &rte_flow_item_ipv4_mask, 9498 }, 9499 { 9500 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 9501 .spec = &action_nvgre_encap_data->item_nvgre, 9502 .mask = &rte_flow_item_nvgre_mask, 9503 }, 9504 { 9505 .type = RTE_FLOW_ITEM_TYPE_END, 9506 }, 9507 }, 9508 .item_eth.hdr.ether_type = 0, 9509 .item_vlan = { 9510 .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, 9511 .hdr.eth_proto = 0, 9512 }, 9513 .item_ipv4.hdr = { 9514 .src_addr = nvgre_encap_conf.ipv4_src, 9515 .dst_addr = nvgre_encap_conf.ipv4_dst, 9516 }, 9517 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 9518 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 9519 .item_nvgre.flow_id = 0, 9520 }; 9521 memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9522 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9523 memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, 9524 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9525 if (!nvgre_encap_conf.select_ipv4) { 9526 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 9527 &nvgre_encap_conf.ipv6_src, 9528 sizeof(nvgre_encap_conf.ipv6_src)); 9529 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 9530 &nvgre_encap_conf.ipv6_dst, 9531 sizeof(nvgre_encap_conf.ipv6_dst)); 9532 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 9533 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9534 .spec = &action_nvgre_encap_data->item_ipv6, 9535 .mask = &rte_flow_item_ipv6_mask, 9536 }; 9537 } 9538 if (!nvgre_encap_conf.select_vlan) 9539 action_nvgre_encap_data->items[1].type = 9540 RTE_FLOW_ITEM_TYPE_VOID; 9541 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 9542 RTE_DIM(nvgre_encap_conf.tni)); 9543 return 0; 9544 } 9545 9546 /** Parse NVGRE encap action. */ 9547 static int 9548 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 9549 const char *str, unsigned int len, 9550 void *buf, unsigned int size) 9551 { 9552 struct buffer *out = buf; 9553 struct rte_flow_action *action; 9554 struct action_nvgre_encap_data *action_nvgre_encap_data; 9555 int ret; 9556 9557 ret = parse_vc(ctx, token, str, len, buf, size); 9558 if (ret < 0) 9559 return ret; 9560 /* Nothing else to do if there is no buffer. */ 9561 if (!out) 9562 return ret; 9563 if (!out->args.vc.actions_n) 9564 return -1; 9565 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9566 /* Point to selected object. */ 9567 ctx->object = out->args.vc.data; 9568 ctx->objmask = NULL; 9569 action_nvgre_encap_data = ctx->object; 9570 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 9571 action->conf = &action_nvgre_encap_data->conf; 9572 return ret; 9573 } 9574 9575 /** Parse l2 encap action. */ 9576 static int 9577 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 9578 const char *str, unsigned int len, 9579 void *buf, unsigned int size) 9580 { 9581 struct buffer *out = buf; 9582 struct rte_flow_action *action; 9583 struct action_raw_encap_data *action_encap_data; 9584 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9585 struct rte_flow_item_vlan vlan = { 9586 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9587 .hdr.eth_proto = 0, 9588 }; 9589 uint8_t *header; 9590 int ret; 9591 9592 ret = parse_vc(ctx, token, str, len, buf, size); 9593 if (ret < 0) 9594 return ret; 9595 /* Nothing else to do if there is no buffer. */ 9596 if (!out) 9597 return ret; 9598 if (!out->args.vc.actions_n) 9599 return -1; 9600 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9601 /* Point to selected object. */ 9602 ctx->object = out->args.vc.data; 9603 ctx->objmask = NULL; 9604 /* Copy the headers to the buffer. */ 9605 action_encap_data = ctx->object; 9606 *action_encap_data = (struct action_raw_encap_data) { 9607 .conf = (struct rte_flow_action_raw_encap){ 9608 .data = action_encap_data->data, 9609 }, 9610 .data = {}, 9611 }; 9612 header = action_encap_data->data; 9613 if (l2_encap_conf.select_vlan) 9614 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9615 else if (l2_encap_conf.select_ipv4) 9616 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9617 else 9618 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9619 memcpy(eth.hdr.dst_addr.addr_bytes, 9620 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9621 memcpy(eth.hdr.src_addr.addr_bytes, 9622 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9623 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9624 header += sizeof(struct rte_ether_hdr); 9625 if (l2_encap_conf.select_vlan) { 9626 if (l2_encap_conf.select_ipv4) 9627 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9628 else 9629 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9630 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9631 header += sizeof(struct rte_vlan_hdr); 9632 } 9633 action_encap_data->conf.size = header - 9634 action_encap_data->data; 9635 action->conf = &action_encap_data->conf; 9636 return ret; 9637 } 9638 9639 /** Parse l2 decap action. */ 9640 static int 9641 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 9642 const char *str, unsigned int len, 9643 void *buf, unsigned int size) 9644 { 9645 struct buffer *out = buf; 9646 struct rte_flow_action *action; 9647 struct action_raw_decap_data *action_decap_data; 9648 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9649 struct rte_flow_item_vlan vlan = { 9650 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9651 .hdr.eth_proto = 0, 9652 }; 9653 uint8_t *header; 9654 int ret; 9655 9656 ret = parse_vc(ctx, token, str, len, buf, size); 9657 if (ret < 0) 9658 return ret; 9659 /* Nothing else to do if there is no buffer. */ 9660 if (!out) 9661 return ret; 9662 if (!out->args.vc.actions_n) 9663 return -1; 9664 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9665 /* Point to selected object. */ 9666 ctx->object = out->args.vc.data; 9667 ctx->objmask = NULL; 9668 /* Copy the headers to the buffer. */ 9669 action_decap_data = ctx->object; 9670 *action_decap_data = (struct action_raw_decap_data) { 9671 .conf = (struct rte_flow_action_raw_decap){ 9672 .data = action_decap_data->data, 9673 }, 9674 .data = {}, 9675 }; 9676 header = action_decap_data->data; 9677 if (l2_decap_conf.select_vlan) 9678 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9679 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9680 header += sizeof(struct rte_ether_hdr); 9681 if (l2_decap_conf.select_vlan) { 9682 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9683 header += sizeof(struct rte_vlan_hdr); 9684 } 9685 action_decap_data->conf.size = header - 9686 action_decap_data->data; 9687 action->conf = &action_decap_data->conf; 9688 return ret; 9689 } 9690 9691 #define ETHER_TYPE_MPLS_UNICAST 0x8847 9692 9693 /** Parse MPLSOGRE encap action. */ 9694 static int 9695 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 9696 const char *str, unsigned int len, 9697 void *buf, unsigned int size) 9698 { 9699 struct buffer *out = buf; 9700 struct rte_flow_action *action; 9701 struct action_raw_encap_data *action_encap_data; 9702 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9703 struct rte_flow_item_vlan vlan = { 9704 .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, 9705 .hdr.eth_proto = 0, 9706 }; 9707 struct rte_flow_item_ipv4 ipv4 = { 9708 .hdr = { 9709 .src_addr = mplsogre_encap_conf.ipv4_src, 9710 .dst_addr = mplsogre_encap_conf.ipv4_dst, 9711 .next_proto_id = IPPROTO_GRE, 9712 .version_ihl = RTE_IPV4_VHL_DEF, 9713 .time_to_live = IPDEFTTL, 9714 }, 9715 }; 9716 struct rte_flow_item_ipv6 ipv6 = { 9717 .hdr = { 9718 .proto = IPPROTO_GRE, 9719 .hop_limits = IPDEFTTL, 9720 }, 9721 }; 9722 struct rte_flow_item_gre gre = { 9723 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9724 }; 9725 struct rte_flow_item_mpls mpls = { 9726 .ttl = 0, 9727 }; 9728 uint8_t *header; 9729 int ret; 9730 9731 ret = parse_vc(ctx, token, str, len, buf, size); 9732 if (ret < 0) 9733 return ret; 9734 /* Nothing else to do if there is no buffer. */ 9735 if (!out) 9736 return ret; 9737 if (!out->args.vc.actions_n) 9738 return -1; 9739 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9740 /* Point to selected object. */ 9741 ctx->object = out->args.vc.data; 9742 ctx->objmask = NULL; 9743 /* Copy the headers to the buffer. */ 9744 action_encap_data = ctx->object; 9745 *action_encap_data = (struct action_raw_encap_data) { 9746 .conf = (struct rte_flow_action_raw_encap){ 9747 .data = action_encap_data->data, 9748 }, 9749 .data = {}, 9750 .preserve = {}, 9751 }; 9752 header = action_encap_data->data; 9753 if (mplsogre_encap_conf.select_vlan) 9754 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9755 else if (mplsogre_encap_conf.select_ipv4) 9756 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9757 else 9758 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9759 memcpy(eth.hdr.dst_addr.addr_bytes, 9760 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9761 memcpy(eth.hdr.src_addr.addr_bytes, 9762 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9763 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9764 header += sizeof(struct rte_ether_hdr); 9765 if (mplsogre_encap_conf.select_vlan) { 9766 if (mplsogre_encap_conf.select_ipv4) 9767 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9768 else 9769 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9770 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9771 header += sizeof(struct rte_vlan_hdr); 9772 } 9773 if (mplsogre_encap_conf.select_ipv4) { 9774 memcpy(header, &ipv4, sizeof(ipv4)); 9775 header += sizeof(ipv4); 9776 } else { 9777 memcpy(&ipv6.hdr.src_addr, 9778 &mplsogre_encap_conf.ipv6_src, 9779 sizeof(mplsogre_encap_conf.ipv6_src)); 9780 memcpy(&ipv6.hdr.dst_addr, 9781 &mplsogre_encap_conf.ipv6_dst, 9782 sizeof(mplsogre_encap_conf.ipv6_dst)); 9783 memcpy(header, &ipv6, sizeof(ipv6)); 9784 header += sizeof(ipv6); 9785 } 9786 memcpy(header, &gre, sizeof(gre)); 9787 header += sizeof(gre); 9788 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 9789 RTE_DIM(mplsogre_encap_conf.label)); 9790 mpls.label_tc_s[2] |= 0x1; 9791 memcpy(header, &mpls, sizeof(mpls)); 9792 header += sizeof(mpls); 9793 action_encap_data->conf.size = header - 9794 action_encap_data->data; 9795 action->conf = &action_encap_data->conf; 9796 return ret; 9797 } 9798 9799 /** Parse MPLSOGRE decap action. */ 9800 static int 9801 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 9802 const char *str, unsigned int len, 9803 void *buf, unsigned int size) 9804 { 9805 struct buffer *out = buf; 9806 struct rte_flow_action *action; 9807 struct action_raw_decap_data *action_decap_data; 9808 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9809 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9810 struct rte_flow_item_ipv4 ipv4 = { 9811 .hdr = { 9812 .next_proto_id = IPPROTO_GRE, 9813 }, 9814 }; 9815 struct rte_flow_item_ipv6 ipv6 = { 9816 .hdr = { 9817 .proto = IPPROTO_GRE, 9818 }, 9819 }; 9820 struct rte_flow_item_gre gre = { 9821 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9822 }; 9823 struct rte_flow_item_mpls mpls; 9824 uint8_t *header; 9825 int ret; 9826 9827 ret = parse_vc(ctx, token, str, len, buf, size); 9828 if (ret < 0) 9829 return ret; 9830 /* Nothing else to do if there is no buffer. */ 9831 if (!out) 9832 return ret; 9833 if (!out->args.vc.actions_n) 9834 return -1; 9835 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9836 /* Point to selected object. */ 9837 ctx->object = out->args.vc.data; 9838 ctx->objmask = NULL; 9839 /* Copy the headers to the buffer. */ 9840 action_decap_data = ctx->object; 9841 *action_decap_data = (struct action_raw_decap_data) { 9842 .conf = (struct rte_flow_action_raw_decap){ 9843 .data = action_decap_data->data, 9844 }, 9845 .data = {}, 9846 }; 9847 header = action_decap_data->data; 9848 if (mplsogre_decap_conf.select_vlan) 9849 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9850 else if (mplsogre_encap_conf.select_ipv4) 9851 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9852 else 9853 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9854 memcpy(eth.hdr.dst_addr.addr_bytes, 9855 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9856 memcpy(eth.hdr.src_addr.addr_bytes, 9857 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9858 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9859 header += sizeof(struct rte_ether_hdr); 9860 if (mplsogre_encap_conf.select_vlan) { 9861 if (mplsogre_encap_conf.select_ipv4) 9862 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9863 else 9864 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9865 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9866 header += sizeof(struct rte_vlan_hdr); 9867 } 9868 if (mplsogre_encap_conf.select_ipv4) { 9869 memcpy(header, &ipv4, sizeof(ipv4)); 9870 header += sizeof(ipv4); 9871 } else { 9872 memcpy(header, &ipv6, sizeof(ipv6)); 9873 header += sizeof(ipv6); 9874 } 9875 memcpy(header, &gre, sizeof(gre)); 9876 header += sizeof(gre); 9877 memset(&mpls, 0, sizeof(mpls)); 9878 memcpy(header, &mpls, sizeof(mpls)); 9879 header += sizeof(mpls); 9880 action_decap_data->conf.size = header - 9881 action_decap_data->data; 9882 action->conf = &action_decap_data->conf; 9883 return ret; 9884 } 9885 9886 /** Parse MPLSOUDP encap action. */ 9887 static int 9888 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 9889 const char *str, unsigned int len, 9890 void *buf, unsigned int size) 9891 { 9892 struct buffer *out = buf; 9893 struct rte_flow_action *action; 9894 struct action_raw_encap_data *action_encap_data; 9895 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9896 struct rte_flow_item_vlan vlan = { 9897 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9898 .hdr.eth_proto = 0, 9899 }; 9900 struct rte_flow_item_ipv4 ipv4 = { 9901 .hdr = { 9902 .src_addr = mplsoudp_encap_conf.ipv4_src, 9903 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 9904 .next_proto_id = IPPROTO_UDP, 9905 .version_ihl = RTE_IPV4_VHL_DEF, 9906 .time_to_live = IPDEFTTL, 9907 }, 9908 }; 9909 struct rte_flow_item_ipv6 ipv6 = { 9910 .hdr = { 9911 .proto = IPPROTO_UDP, 9912 .hop_limits = IPDEFTTL, 9913 }, 9914 }; 9915 struct rte_flow_item_udp udp = { 9916 .hdr = { 9917 .src_port = mplsoudp_encap_conf.udp_src, 9918 .dst_port = mplsoudp_encap_conf.udp_dst, 9919 }, 9920 }; 9921 struct rte_flow_item_mpls mpls; 9922 uint8_t *header; 9923 int ret; 9924 9925 ret = parse_vc(ctx, token, str, len, buf, size); 9926 if (ret < 0) 9927 return ret; 9928 /* Nothing else to do if there is no buffer. */ 9929 if (!out) 9930 return ret; 9931 if (!out->args.vc.actions_n) 9932 return -1; 9933 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9934 /* Point to selected object. */ 9935 ctx->object = out->args.vc.data; 9936 ctx->objmask = NULL; 9937 /* Copy the headers to the buffer. */ 9938 action_encap_data = ctx->object; 9939 *action_encap_data = (struct action_raw_encap_data) { 9940 .conf = (struct rte_flow_action_raw_encap){ 9941 .data = action_encap_data->data, 9942 }, 9943 .data = {}, 9944 .preserve = {}, 9945 }; 9946 header = action_encap_data->data; 9947 if (mplsoudp_encap_conf.select_vlan) 9948 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9949 else if (mplsoudp_encap_conf.select_ipv4) 9950 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9951 else 9952 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9953 memcpy(eth.hdr.dst_addr.addr_bytes, 9954 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9955 memcpy(eth.hdr.src_addr.addr_bytes, 9956 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9957 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9958 header += sizeof(struct rte_ether_hdr); 9959 if (mplsoudp_encap_conf.select_vlan) { 9960 if (mplsoudp_encap_conf.select_ipv4) 9961 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9962 else 9963 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9964 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9965 header += sizeof(struct rte_vlan_hdr); 9966 } 9967 if (mplsoudp_encap_conf.select_ipv4) { 9968 memcpy(header, &ipv4, sizeof(ipv4)); 9969 header += sizeof(ipv4); 9970 } else { 9971 memcpy(&ipv6.hdr.src_addr, 9972 &mplsoudp_encap_conf.ipv6_src, 9973 sizeof(mplsoudp_encap_conf.ipv6_src)); 9974 memcpy(&ipv6.hdr.dst_addr, 9975 &mplsoudp_encap_conf.ipv6_dst, 9976 sizeof(mplsoudp_encap_conf.ipv6_dst)); 9977 memcpy(header, &ipv6, sizeof(ipv6)); 9978 header += sizeof(ipv6); 9979 } 9980 memcpy(header, &udp, sizeof(udp)); 9981 header += sizeof(udp); 9982 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 9983 RTE_DIM(mplsoudp_encap_conf.label)); 9984 mpls.label_tc_s[2] |= 0x1; 9985 memcpy(header, &mpls, sizeof(mpls)); 9986 header += sizeof(mpls); 9987 action_encap_data->conf.size = header - 9988 action_encap_data->data; 9989 action->conf = &action_encap_data->conf; 9990 return ret; 9991 } 9992 9993 /** Parse MPLSOUDP decap action. */ 9994 static int 9995 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 9996 const char *str, unsigned int len, 9997 void *buf, unsigned int size) 9998 { 9999 struct buffer *out = buf; 10000 struct rte_flow_action *action; 10001 struct action_raw_decap_data *action_decap_data; 10002 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 10003 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 10004 struct rte_flow_item_ipv4 ipv4 = { 10005 .hdr = { 10006 .next_proto_id = IPPROTO_UDP, 10007 }, 10008 }; 10009 struct rte_flow_item_ipv6 ipv6 = { 10010 .hdr = { 10011 .proto = IPPROTO_UDP, 10012 }, 10013 }; 10014 struct rte_flow_item_udp udp = { 10015 .hdr = { 10016 .dst_port = rte_cpu_to_be_16(6635), 10017 }, 10018 }; 10019 struct rte_flow_item_mpls mpls; 10020 uint8_t *header; 10021 int ret; 10022 10023 ret = parse_vc(ctx, token, str, len, buf, size); 10024 if (ret < 0) 10025 return ret; 10026 /* Nothing else to do if there is no buffer. */ 10027 if (!out) 10028 return ret; 10029 if (!out->args.vc.actions_n) 10030 return -1; 10031 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10032 /* Point to selected object. */ 10033 ctx->object = out->args.vc.data; 10034 ctx->objmask = NULL; 10035 /* Copy the headers to the buffer. */ 10036 action_decap_data = ctx->object; 10037 *action_decap_data = (struct action_raw_decap_data) { 10038 .conf = (struct rte_flow_action_raw_decap){ 10039 .data = action_decap_data->data, 10040 }, 10041 .data = {}, 10042 }; 10043 header = action_decap_data->data; 10044 if (mplsoudp_decap_conf.select_vlan) 10045 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 10046 else if (mplsoudp_encap_conf.select_ipv4) 10047 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 10048 else 10049 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 10050 memcpy(eth.hdr.dst_addr.addr_bytes, 10051 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 10052 memcpy(eth.hdr.src_addr.addr_bytes, 10053 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 10054 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 10055 header += sizeof(struct rte_ether_hdr); 10056 if (mplsoudp_encap_conf.select_vlan) { 10057 if (mplsoudp_encap_conf.select_ipv4) 10058 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 10059 else 10060 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 10061 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 10062 header += sizeof(struct rte_vlan_hdr); 10063 } 10064 if (mplsoudp_encap_conf.select_ipv4) { 10065 memcpy(header, &ipv4, sizeof(ipv4)); 10066 header += sizeof(ipv4); 10067 } else { 10068 memcpy(header, &ipv6, sizeof(ipv6)); 10069 header += sizeof(ipv6); 10070 } 10071 memcpy(header, &udp, sizeof(udp)); 10072 header += sizeof(udp); 10073 memset(&mpls, 0, sizeof(mpls)); 10074 memcpy(header, &mpls, sizeof(mpls)); 10075 header += sizeof(mpls); 10076 action_decap_data->conf.size = header - 10077 action_decap_data->data; 10078 action->conf = &action_decap_data->conf; 10079 return ret; 10080 } 10081 10082 static int 10083 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 10084 const char *str, unsigned int len, void *buf, 10085 unsigned int size) 10086 { 10087 struct action_raw_decap_data *action_raw_decap_data; 10088 struct rte_flow_action *action; 10089 const struct arg *arg; 10090 struct buffer *out = buf; 10091 int ret; 10092 uint16_t idx; 10093 10094 RTE_SET_USED(token); 10095 RTE_SET_USED(buf); 10096 RTE_SET_USED(size); 10097 arg = ARGS_ENTRY_ARB_BOUNDED 10098 (offsetof(struct action_raw_decap_data, idx), 10099 sizeof(((struct action_raw_decap_data *)0)->idx), 10100 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10101 if (push_args(ctx, arg)) 10102 return -1; 10103 ret = parse_int(ctx, token, str, len, NULL, 0); 10104 if (ret < 0) { 10105 pop_args(ctx); 10106 return -1; 10107 } 10108 if (!ctx->object) 10109 return len; 10110 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10111 action_raw_decap_data = ctx->object; 10112 idx = action_raw_decap_data->idx; 10113 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 10114 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 10115 action->conf = &action_raw_decap_data->conf; 10116 return len; 10117 } 10118 10119 10120 static int 10121 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 10122 const char *str, unsigned int len, void *buf, 10123 unsigned int size) 10124 { 10125 struct action_raw_encap_data *action_raw_encap_data; 10126 struct rte_flow_action *action; 10127 const struct arg *arg; 10128 struct buffer *out = buf; 10129 int ret; 10130 uint16_t idx; 10131 10132 RTE_SET_USED(token); 10133 RTE_SET_USED(buf); 10134 RTE_SET_USED(size); 10135 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 10136 return -1; 10137 arg = ARGS_ENTRY_ARB_BOUNDED 10138 (offsetof(struct action_raw_encap_data, idx), 10139 sizeof(((struct action_raw_encap_data *)0)->idx), 10140 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10141 if (push_args(ctx, arg)) 10142 return -1; 10143 ret = parse_int(ctx, token, str, len, NULL, 0); 10144 if (ret < 0) { 10145 pop_args(ctx); 10146 return -1; 10147 } 10148 if (!ctx->object) 10149 return len; 10150 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10151 action_raw_encap_data = ctx->object; 10152 idx = action_raw_encap_data->idx; 10153 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 10154 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 10155 action_raw_encap_data->conf.preserve = NULL; 10156 action->conf = &action_raw_encap_data->conf; 10157 return len; 10158 } 10159 10160 static int 10161 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 10162 const char *str, unsigned int len, void *buf, 10163 unsigned int size) 10164 { 10165 struct buffer *out = buf; 10166 int ret; 10167 10168 ret = parse_vc(ctx, token, str, len, buf, size); 10169 if (ret < 0) 10170 return ret; 10171 /* Nothing else to do if there is no buffer. */ 10172 if (!out) 10173 return ret; 10174 if (!out->args.vc.actions_n) 10175 return -1; 10176 /* Point to selected object. */ 10177 ctx->object = out->args.vc.data; 10178 ctx->objmask = NULL; 10179 return ret; 10180 } 10181 10182 static int 10183 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 10184 const char *str, unsigned int len, void *buf, 10185 unsigned int size) 10186 { 10187 struct buffer *out = buf; 10188 struct rte_flow_action *action; 10189 struct action_raw_decap_data *action_raw_decap_data = NULL; 10190 int ret; 10191 10192 ret = parse_vc(ctx, token, str, len, buf, size); 10193 if (ret < 0) 10194 return ret; 10195 /* Nothing else to do if there is no buffer. */ 10196 if (!out) 10197 return ret; 10198 if (!out->args.vc.actions_n) 10199 return -1; 10200 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10201 /* Point to selected object. */ 10202 ctx->object = out->args.vc.data; 10203 ctx->objmask = NULL; 10204 /* Copy the headers to the buffer. */ 10205 action_raw_decap_data = ctx->object; 10206 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 10207 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 10208 action->conf = &action_raw_decap_data->conf; 10209 return ret; 10210 } 10211 10212 static int 10213 parse_vc_action_ipv6_ext_remove(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_ipv6_ext_remove_data *ipv6_ext_remove_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 ipv6_ext_remove_data = ctx->object; 10236 ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; 10237 action->conf = &ipv6_ext_remove_data->conf; 10238 return ret; 10239 } 10240 10241 static int 10242 parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, 10243 const char *str, unsigned int len, void *buf, 10244 unsigned int size) 10245 { 10246 struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; 10247 struct rte_flow_action *action; 10248 const struct arg *arg; 10249 struct buffer *out = buf; 10250 int ret; 10251 uint16_t idx; 10252 10253 RTE_SET_USED(token); 10254 RTE_SET_USED(buf); 10255 RTE_SET_USED(size); 10256 arg = ARGS_ENTRY_ARB_BOUNDED 10257 (offsetof(struct action_ipv6_ext_remove_data, idx), 10258 sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), 10259 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10260 if (push_args(ctx, arg)) 10261 return -1; 10262 ret = parse_int(ctx, token, str, len, NULL, 0); 10263 if (ret < 0) { 10264 pop_args(ctx); 10265 return -1; 10266 } 10267 if (!ctx->object) 10268 return len; 10269 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10270 action_ipv6_ext_remove_data = ctx->object; 10271 idx = action_ipv6_ext_remove_data->idx; 10272 action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; 10273 action->conf = &action_ipv6_ext_remove_data->conf; 10274 return len; 10275 } 10276 10277 static int 10278 parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 10279 const char *str, unsigned int len, void *buf, 10280 unsigned int size) 10281 { 10282 struct buffer *out = buf; 10283 struct rte_flow_action *action; 10284 struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; 10285 int ret; 10286 10287 ret = parse_vc(ctx, token, str, len, buf, size); 10288 if (ret < 0) 10289 return ret; 10290 /* Nothing else to do if there is no buffer. */ 10291 if (!out) 10292 return ret; 10293 if (!out->args.vc.actions_n) 10294 return -1; 10295 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10296 /* Point to selected object. */ 10297 ctx->object = out->args.vc.data; 10298 ctx->objmask = NULL; 10299 /* Copy the headers to the buffer. */ 10300 ipv6_ext_push_data = ctx->object; 10301 ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; 10302 ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; 10303 ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; 10304 action->conf = &ipv6_ext_push_data->conf; 10305 return ret; 10306 } 10307 10308 static int 10309 parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, 10310 const char *str, unsigned int len, void *buf, 10311 unsigned int size) 10312 { 10313 struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; 10314 struct rte_flow_action *action; 10315 const struct arg *arg; 10316 struct buffer *out = buf; 10317 int ret; 10318 uint16_t idx; 10319 10320 RTE_SET_USED(token); 10321 RTE_SET_USED(buf); 10322 RTE_SET_USED(size); 10323 arg = ARGS_ENTRY_ARB_BOUNDED 10324 (offsetof(struct action_ipv6_ext_push_data, idx), 10325 sizeof(((struct action_ipv6_ext_push_data *)0)->idx), 10326 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10327 if (push_args(ctx, arg)) 10328 return -1; 10329 ret = parse_int(ctx, token, str, len, NULL, 0); 10330 if (ret < 0) { 10331 pop_args(ctx); 10332 return -1; 10333 } 10334 if (!ctx->object) 10335 return len; 10336 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10337 action_ipv6_ext_push_data = ctx->object; 10338 idx = action_ipv6_ext_push_data->idx; 10339 action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; 10340 action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; 10341 action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; 10342 action->conf = &action_ipv6_ext_push_data->conf; 10343 return len; 10344 } 10345 10346 static int 10347 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 10348 const char *str, unsigned int len, void *buf, 10349 unsigned int size) 10350 { 10351 int ret; 10352 10353 ret = parse_vc(ctx, token, str, len, buf, size); 10354 if (ret < 0) 10355 return ret; 10356 ret = rte_flow_dynf_metadata_register(); 10357 if (ret < 0) 10358 return -1; 10359 return len; 10360 } 10361 10362 static int 10363 parse_vc_action_sample(struct context *ctx, const struct token *token, 10364 const char *str, unsigned int len, void *buf, 10365 unsigned int size) 10366 { 10367 struct buffer *out = buf; 10368 struct rte_flow_action *action; 10369 struct action_sample_data *action_sample_data = NULL; 10370 static struct rte_flow_action end_action = { 10371 RTE_FLOW_ACTION_TYPE_END, 0 10372 }; 10373 int ret; 10374 10375 ret = parse_vc(ctx, token, str, len, buf, size); 10376 if (ret < 0) 10377 return ret; 10378 /* Nothing else to do if there is no buffer. */ 10379 if (!out) 10380 return ret; 10381 if (!out->args.vc.actions_n) 10382 return -1; 10383 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10384 /* Point to selected object. */ 10385 ctx->object = out->args.vc.data; 10386 ctx->objmask = NULL; 10387 /* Copy the headers to the buffer. */ 10388 action_sample_data = ctx->object; 10389 action_sample_data->conf.actions = &end_action; 10390 action->conf = &action_sample_data->conf; 10391 return ret; 10392 } 10393 10394 static int 10395 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 10396 const char *str, unsigned int len, void *buf, 10397 unsigned int size) 10398 { 10399 struct action_sample_data *action_sample_data; 10400 struct rte_flow_action *action; 10401 const struct arg *arg; 10402 struct buffer *out = buf; 10403 int ret; 10404 uint16_t idx; 10405 10406 RTE_SET_USED(token); 10407 RTE_SET_USED(buf); 10408 RTE_SET_USED(size); 10409 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 10410 return -1; 10411 arg = ARGS_ENTRY_ARB_BOUNDED 10412 (offsetof(struct action_sample_data, idx), 10413 sizeof(((struct action_sample_data *)0)->idx), 10414 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 10415 if (push_args(ctx, arg)) 10416 return -1; 10417 ret = parse_int(ctx, token, str, len, NULL, 0); 10418 if (ret < 0) { 10419 pop_args(ctx); 10420 return -1; 10421 } 10422 if (!ctx->object) 10423 return len; 10424 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10425 action_sample_data = ctx->object; 10426 idx = action_sample_data->idx; 10427 action_sample_data->conf.actions = raw_sample_confs[idx].data; 10428 action->conf = &action_sample_data->conf; 10429 return len; 10430 } 10431 10432 /** Parse operation for modify_field command. */ 10433 static int 10434 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 10435 const char *str, unsigned int len, void *buf, 10436 unsigned int size) 10437 { 10438 struct rte_flow_action_modify_field *action_modify_field; 10439 unsigned int i; 10440 10441 (void)token; 10442 (void)buf; 10443 (void)size; 10444 if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) 10445 return -1; 10446 for (i = 0; modify_field_ops[i]; ++i) 10447 if (!strcmp_partial(modify_field_ops[i], str, len)) 10448 break; 10449 if (!modify_field_ops[i]) 10450 return -1; 10451 if (!ctx->object) 10452 return len; 10453 action_modify_field = ctx->object; 10454 action_modify_field->operation = (enum rte_flow_modify_op)i; 10455 return len; 10456 } 10457 10458 /** Parse id for modify_field command. */ 10459 static int 10460 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 10461 const char *str, unsigned int len, void *buf, 10462 unsigned int size) 10463 { 10464 struct rte_flow_action_modify_field *action_modify_field; 10465 unsigned int i; 10466 10467 (void)token; 10468 (void)buf; 10469 (void)size; 10470 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 10471 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 10472 return -1; 10473 for (i = 0; flow_field_ids[i]; ++i) 10474 if (!strcmp_partial(flow_field_ids[i], str, len)) 10475 break; 10476 if (!flow_field_ids[i]) 10477 return -1; 10478 if (!ctx->object) 10479 return len; 10480 action_modify_field = ctx->object; 10481 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 10482 action_modify_field->dst.field = (enum rte_flow_field_id)i; 10483 else 10484 action_modify_field->src.field = (enum rte_flow_field_id)i; 10485 return len; 10486 } 10487 10488 /** Parse level for modify_field command. */ 10489 static int 10490 parse_vc_modify_field_level(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; 10495 struct flex_item *fp = NULL; 10496 uint32_t val; 10497 struct buffer *out = buf; 10498 char *end; 10499 10500 (void)token; 10501 (void)size; 10502 if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10503 ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) 10504 return -1; 10505 if (!ctx->object) 10506 return len; 10507 action = ctx->object; 10508 errno = 0; 10509 val = strtoumax(str, &end, 0); 10510 if (errno || (size_t)(end - str) != len) 10511 return -1; 10512 /* No need to validate action template mask value */ 10513 if (out->args.vc.masks) { 10514 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) 10515 action->dst.level = val; 10516 else 10517 action->src.level = val; 10518 return len; 10519 } 10520 if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10521 action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || 10522 (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && 10523 action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 10524 if (val >= FLEX_MAX_PARSERS_NUM) { 10525 printf("Bad flex item handle\n"); 10526 return -1; 10527 } 10528 fp = flex_items[ctx->port][val]; 10529 if (!fp) { 10530 printf("Bad flex item handle\n"); 10531 return -1; 10532 } 10533 } 10534 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { 10535 if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) 10536 action->dst.level = val; 10537 else 10538 action->dst.flex_handle = fp->flex_handle; 10539 } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { 10540 if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) 10541 action->src.level = val; 10542 else 10543 action->src.flex_handle = fp->flex_handle; 10544 } 10545 return len; 10546 } 10547 10548 /** Parse the conntrack update, not a rte_flow_action. */ 10549 static int 10550 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 10551 const char *str, unsigned int len, void *buf, 10552 unsigned int size) 10553 { 10554 struct buffer *out = buf; 10555 struct rte_flow_modify_conntrack *ct_modify = NULL; 10556 10557 (void)size; 10558 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 10559 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 10560 return -1; 10561 /* Token name must match. */ 10562 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10563 return -1; 10564 /* Nothing else to do if there is no buffer. */ 10565 if (!out) 10566 return len; 10567 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 10568 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 10569 ct_modify->new_ct.is_original_dir = 10570 conntrack_context.is_original_dir; 10571 ct_modify->direction = 1; 10572 } else { 10573 uint32_t old_dir; 10574 10575 old_dir = ct_modify->new_ct.is_original_dir; 10576 memcpy(&ct_modify->new_ct, &conntrack_context, 10577 sizeof(conntrack_context)); 10578 ct_modify->new_ct.is_original_dir = old_dir; 10579 ct_modify->state = 1; 10580 } 10581 return len; 10582 } 10583 10584 /** Parse tokens for destroy command. */ 10585 static int 10586 parse_destroy(struct context *ctx, const struct token *token, 10587 const char *str, unsigned int len, 10588 void *buf, unsigned int size) 10589 { 10590 struct buffer *out = buf; 10591 10592 /* Token name must match. */ 10593 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10594 return -1; 10595 /* Nothing else to do if there is no buffer. */ 10596 if (!out) 10597 return len; 10598 if (!out->command) { 10599 if (ctx->curr != DESTROY) 10600 return -1; 10601 if (sizeof(*out) > size) 10602 return -1; 10603 out->command = ctx->curr; 10604 ctx->objdata = 0; 10605 ctx->object = out; 10606 ctx->objmask = NULL; 10607 out->args.destroy.rule = 10608 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10609 sizeof(double)); 10610 return len; 10611 } 10612 if (ctx->curr == DESTROY_IS_USER_ID) { 10613 out->args.destroy.is_user_id = true; 10614 return len; 10615 } 10616 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 10617 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 10618 return -1; 10619 ctx->objdata = 0; 10620 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 10621 ctx->objmask = NULL; 10622 return len; 10623 } 10624 10625 /** Parse tokens for flush command. */ 10626 static int 10627 parse_flush(struct context *ctx, const struct token *token, 10628 const char *str, unsigned int len, 10629 void *buf, unsigned int size) 10630 { 10631 struct buffer *out = buf; 10632 10633 /* Token name must match. */ 10634 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10635 return -1; 10636 /* Nothing else to do if there is no buffer. */ 10637 if (!out) 10638 return len; 10639 if (!out->command) { 10640 if (ctx->curr != FLUSH) 10641 return -1; 10642 if (sizeof(*out) > size) 10643 return -1; 10644 out->command = ctx->curr; 10645 ctx->objdata = 0; 10646 ctx->object = out; 10647 ctx->objmask = NULL; 10648 } 10649 return len; 10650 } 10651 10652 /** Parse tokens for dump command. */ 10653 static int 10654 parse_dump(struct context *ctx, const struct token *token, 10655 const char *str, unsigned int len, 10656 void *buf, unsigned int size) 10657 { 10658 struct buffer *out = buf; 10659 10660 /* Token name must match. */ 10661 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10662 return -1; 10663 /* Nothing else to do if there is no buffer. */ 10664 if (!out) 10665 return len; 10666 if (!out->command) { 10667 if (ctx->curr != DUMP) 10668 return -1; 10669 if (sizeof(*out) > size) 10670 return -1; 10671 out->command = ctx->curr; 10672 ctx->objdata = 0; 10673 ctx->object = out; 10674 ctx->objmask = NULL; 10675 return len; 10676 } 10677 switch (ctx->curr) { 10678 case DUMP_ALL: 10679 case DUMP_ONE: 10680 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 10681 out->command = ctx->curr; 10682 ctx->objdata = 0; 10683 ctx->object = out; 10684 ctx->objmask = NULL; 10685 return len; 10686 case DUMP_IS_USER_ID: 10687 out->args.dump.is_user_id = true; 10688 return len; 10689 default: 10690 return -1; 10691 } 10692 } 10693 10694 /** Parse tokens for query command. */ 10695 static int 10696 parse_query(struct context *ctx, const struct token *token, 10697 const char *str, unsigned int len, 10698 void *buf, unsigned int size) 10699 { 10700 struct buffer *out = buf; 10701 10702 /* Token name must match. */ 10703 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10704 return -1; 10705 /* Nothing else to do if there is no buffer. */ 10706 if (!out) 10707 return len; 10708 if (!out->command) { 10709 if (ctx->curr != QUERY) 10710 return -1; 10711 if (sizeof(*out) > size) 10712 return -1; 10713 out->command = ctx->curr; 10714 ctx->objdata = 0; 10715 ctx->object = out; 10716 ctx->objmask = NULL; 10717 } 10718 if (ctx->curr == QUERY_IS_USER_ID) { 10719 out->args.query.is_user_id = true; 10720 return len; 10721 } 10722 return len; 10723 } 10724 10725 /** Parse action names. */ 10726 static int 10727 parse_action(struct context *ctx, const struct token *token, 10728 const char *str, unsigned int len, 10729 void *buf, unsigned int size) 10730 { 10731 struct buffer *out = buf; 10732 const struct arg *arg = pop_args(ctx); 10733 unsigned int i; 10734 10735 (void)size; 10736 /* Argument is expected. */ 10737 if (!arg) 10738 return -1; 10739 /* Parse action name. */ 10740 for (i = 0; next_action[i]; ++i) { 10741 const struct parse_action_priv *priv; 10742 10743 token = &token_list[next_action[i]]; 10744 if (strcmp_partial(token->name, str, len)) 10745 continue; 10746 priv = token->priv; 10747 if (!priv) 10748 goto error; 10749 if (out) 10750 memcpy((uint8_t *)ctx->object + arg->offset, 10751 &priv->type, 10752 arg->size); 10753 return len; 10754 } 10755 error: 10756 push_args(ctx, arg); 10757 return -1; 10758 } 10759 10760 /** Parse tokens for list command. */ 10761 static int 10762 parse_list(struct context *ctx, const struct token *token, 10763 const char *str, unsigned int len, 10764 void *buf, unsigned int size) 10765 { 10766 struct buffer *out = buf; 10767 10768 /* Token name must match. */ 10769 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10770 return -1; 10771 /* Nothing else to do if there is no buffer. */ 10772 if (!out) 10773 return len; 10774 if (!out->command) { 10775 if (ctx->curr != LIST) 10776 return -1; 10777 if (sizeof(*out) > size) 10778 return -1; 10779 out->command = ctx->curr; 10780 ctx->objdata = 0; 10781 ctx->object = out; 10782 ctx->objmask = NULL; 10783 out->args.list.group = 10784 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10785 sizeof(double)); 10786 return len; 10787 } 10788 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 10789 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 10790 return -1; 10791 ctx->objdata = 0; 10792 ctx->object = out->args.list.group + out->args.list.group_n++; 10793 ctx->objmask = NULL; 10794 return len; 10795 } 10796 10797 /** Parse tokens for list all aged flows command. */ 10798 static int 10799 parse_aged(struct context *ctx, const struct token *token, 10800 const char *str, unsigned int len, 10801 void *buf, unsigned int size) 10802 { 10803 struct buffer *out = buf; 10804 10805 /* Token name must match. */ 10806 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10807 return -1; 10808 /* Nothing else to do if there is no buffer. */ 10809 if (!out) 10810 return len; 10811 if (!out->command || out->command == QUEUE) { 10812 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 10813 return -1; 10814 if (sizeof(*out) > size) 10815 return -1; 10816 out->command = ctx->curr; 10817 ctx->objdata = 0; 10818 ctx->object = out; 10819 ctx->objmask = NULL; 10820 } 10821 if (ctx->curr == AGED_DESTROY) 10822 out->args.aged.destroy = 1; 10823 return len; 10824 } 10825 10826 /** Parse tokens for isolate command. */ 10827 static int 10828 parse_isolate(struct context *ctx, const struct token *token, 10829 const char *str, unsigned int len, 10830 void *buf, unsigned int size) 10831 { 10832 struct buffer *out = buf; 10833 10834 /* Token name must match. */ 10835 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10836 return -1; 10837 /* Nothing else to do if there is no buffer. */ 10838 if (!out) 10839 return len; 10840 if (!out->command) { 10841 if (ctx->curr != ISOLATE) 10842 return -1; 10843 if (sizeof(*out) > size) 10844 return -1; 10845 out->command = ctx->curr; 10846 ctx->objdata = 0; 10847 ctx->object = out; 10848 ctx->objmask = NULL; 10849 } 10850 return len; 10851 } 10852 10853 /** Parse tokens for info/configure command. */ 10854 static int 10855 parse_configure(struct context *ctx, const struct token *token, 10856 const char *str, unsigned int len, 10857 void *buf, unsigned int size) 10858 { 10859 struct buffer *out = buf; 10860 10861 /* Token name must match. */ 10862 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10863 return -1; 10864 /* Nothing else to do if there is no buffer. */ 10865 if (!out) 10866 return len; 10867 if (!out->command) { 10868 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 10869 return -1; 10870 if (sizeof(*out) > size) 10871 return -1; 10872 out->command = ctx->curr; 10873 ctx->objdata = 0; 10874 ctx->object = out; 10875 ctx->objmask = NULL; 10876 } 10877 return len; 10878 } 10879 10880 /** Parse tokens for template create command. */ 10881 static int 10882 parse_template(struct context *ctx, const struct token *token, 10883 const char *str, unsigned int len, 10884 void *buf, unsigned int size) 10885 { 10886 struct buffer *out = buf; 10887 10888 /* Token name must match. */ 10889 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10890 return -1; 10891 /* Nothing else to do if there is no buffer. */ 10892 if (!out) 10893 return len; 10894 if (!out->command) { 10895 if (ctx->curr != PATTERN_TEMPLATE && 10896 ctx->curr != ACTIONS_TEMPLATE) 10897 return -1; 10898 if (sizeof(*out) > size) 10899 return -1; 10900 out->command = ctx->curr; 10901 ctx->objdata = 0; 10902 ctx->object = out; 10903 ctx->objmask = NULL; 10904 out->args.vc.data = (uint8_t *)out + size; 10905 return len; 10906 } 10907 switch (ctx->curr) { 10908 case PATTERN_TEMPLATE_CREATE: 10909 out->args.vc.pattern = 10910 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10911 sizeof(double)); 10912 out->args.vc.pat_templ_id = UINT32_MAX; 10913 out->command = ctx->curr; 10914 ctx->objdata = 0; 10915 ctx->object = out; 10916 ctx->objmask = NULL; 10917 return len; 10918 case PATTERN_TEMPLATE_EGRESS: 10919 out->args.vc.attr.egress = 1; 10920 return len; 10921 case PATTERN_TEMPLATE_INGRESS: 10922 out->args.vc.attr.ingress = 1; 10923 return len; 10924 case PATTERN_TEMPLATE_TRANSFER: 10925 out->args.vc.attr.transfer = 1; 10926 return len; 10927 case ACTIONS_TEMPLATE_CREATE: 10928 out->args.vc.act_templ_id = UINT32_MAX; 10929 out->command = ctx->curr; 10930 ctx->objdata = 0; 10931 ctx->object = out; 10932 ctx->objmask = NULL; 10933 return len; 10934 case ACTIONS_TEMPLATE_SPEC: 10935 out->args.vc.actions = 10936 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10937 sizeof(double)); 10938 ctx->object = out->args.vc.actions; 10939 ctx->objmask = NULL; 10940 return len; 10941 case ACTIONS_TEMPLATE_MASK: 10942 out->args.vc.masks = 10943 (void *)RTE_ALIGN_CEIL((uintptr_t) 10944 (out->args.vc.actions + 10945 out->args.vc.actions_n), 10946 sizeof(double)); 10947 ctx->object = out->args.vc.masks; 10948 ctx->objmask = NULL; 10949 return len; 10950 case ACTIONS_TEMPLATE_EGRESS: 10951 out->args.vc.attr.egress = 1; 10952 return len; 10953 case ACTIONS_TEMPLATE_INGRESS: 10954 out->args.vc.attr.ingress = 1; 10955 return len; 10956 case ACTIONS_TEMPLATE_TRANSFER: 10957 out->args.vc.attr.transfer = 1; 10958 return len; 10959 default: 10960 return -1; 10961 } 10962 } 10963 10964 /** Parse tokens for template destroy command. */ 10965 static int 10966 parse_template_destroy(struct context *ctx, const struct token *token, 10967 const char *str, unsigned int len, 10968 void *buf, unsigned int size) 10969 { 10970 struct buffer *out = buf; 10971 uint32_t *template_id; 10972 10973 /* Token name must match. */ 10974 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10975 return -1; 10976 /* Nothing else to do if there is no buffer. */ 10977 if (!out) 10978 return len; 10979 if (!out->command || 10980 out->command == PATTERN_TEMPLATE || 10981 out->command == ACTIONS_TEMPLATE) { 10982 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 10983 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 10984 return -1; 10985 if (sizeof(*out) > size) 10986 return -1; 10987 out->command = ctx->curr; 10988 ctx->objdata = 0; 10989 ctx->object = out; 10990 ctx->objmask = NULL; 10991 out->args.templ_destroy.template_id = 10992 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10993 sizeof(double)); 10994 return len; 10995 } 10996 template_id = out->args.templ_destroy.template_id 10997 + out->args.templ_destroy.template_id_n++; 10998 if ((uint8_t *)template_id > (uint8_t *)out + size) 10999 return -1; 11000 ctx->objdata = 0; 11001 ctx->object = template_id; 11002 ctx->objmask = NULL; 11003 return len; 11004 } 11005 11006 /** Parse tokens for table create command. */ 11007 static int 11008 parse_table(struct context *ctx, const struct token *token, 11009 const char *str, unsigned int len, 11010 void *buf, unsigned int size) 11011 { 11012 struct buffer *out = buf; 11013 uint32_t *template_id; 11014 11015 /* Token name must match. */ 11016 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11017 return -1; 11018 /* Nothing else to do if there is no buffer. */ 11019 if (!out) 11020 return len; 11021 if (!out->command) { 11022 if (ctx->curr != TABLE) 11023 return -1; 11024 if (sizeof(*out) > size) 11025 return -1; 11026 out->command = ctx->curr; 11027 ctx->objdata = 0; 11028 ctx->object = out; 11029 ctx->objmask = NULL; 11030 return len; 11031 } 11032 switch (ctx->curr) { 11033 case TABLE_CREATE: 11034 case TABLE_RESIZE: 11035 out->command = ctx->curr; 11036 ctx->objdata = 0; 11037 ctx->object = out; 11038 ctx->objmask = NULL; 11039 out->args.table.id = UINT32_MAX; 11040 return len; 11041 case TABLE_PATTERN_TEMPLATE: 11042 out->args.table.pat_templ_id = 11043 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11044 sizeof(double)); 11045 template_id = out->args.table.pat_templ_id 11046 + out->args.table.pat_templ_id_n++; 11047 if ((uint8_t *)template_id > (uint8_t *)out + size) 11048 return -1; 11049 ctx->objdata = 0; 11050 ctx->object = template_id; 11051 ctx->objmask = NULL; 11052 return len; 11053 case TABLE_ACTIONS_TEMPLATE: 11054 out->args.table.act_templ_id = 11055 (void *)RTE_ALIGN_CEIL((uintptr_t) 11056 (out->args.table.pat_templ_id + 11057 out->args.table.pat_templ_id_n), 11058 sizeof(double)); 11059 template_id = out->args.table.act_templ_id 11060 + out->args.table.act_templ_id_n++; 11061 if ((uint8_t *)template_id > (uint8_t *)out + size) 11062 return -1; 11063 ctx->objdata = 0; 11064 ctx->object = template_id; 11065 ctx->objmask = NULL; 11066 return len; 11067 case TABLE_INGRESS: 11068 out->args.table.attr.flow_attr.ingress = 1; 11069 return len; 11070 case TABLE_EGRESS: 11071 out->args.table.attr.flow_attr.egress = 1; 11072 return len; 11073 case TABLE_TRANSFER: 11074 out->args.table.attr.flow_attr.transfer = 1; 11075 return len; 11076 case TABLE_TRANSFER_WIRE_ORIG: 11077 if (!out->args.table.attr.flow_attr.transfer) 11078 return -1; 11079 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; 11080 return len; 11081 case TABLE_TRANSFER_VPORT_ORIG: 11082 if (!out->args.table.attr.flow_attr.transfer) 11083 return -1; 11084 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; 11085 return len; 11086 case TABLE_RESIZABLE: 11087 out->args.table.attr.specialize |= 11088 RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE; 11089 return len; 11090 case TABLE_RULES_NUMBER: 11091 ctx->objdata = 0; 11092 ctx->object = out; 11093 ctx->objmask = NULL; 11094 return len; 11095 case TABLE_RESIZE_ID: 11096 case TABLE_RESIZE_RULES_NUMBER: 11097 return len; 11098 default: 11099 return -1; 11100 } 11101 } 11102 11103 /** Parse tokens for table destroy command. */ 11104 static int 11105 parse_table_destroy(struct context *ctx, const struct token *token, 11106 const char *str, unsigned int len, 11107 void *buf, unsigned int size) 11108 { 11109 struct buffer *out = buf; 11110 uint32_t *table_id; 11111 11112 /* Token name must match. */ 11113 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11114 return -1; 11115 /* Nothing else to do if there is no buffer. */ 11116 if (!out) 11117 return len; 11118 if (!out->command || out->command == TABLE) { 11119 if (ctx->curr != TABLE_DESTROY && 11120 ctx->curr != TABLE_RESIZE_COMPLETE) 11121 return -1; 11122 if (sizeof(*out) > size) 11123 return -1; 11124 out->command = ctx->curr; 11125 ctx->objdata = 0; 11126 ctx->object = out; 11127 ctx->objmask = NULL; 11128 out->args.table_destroy.table_id = 11129 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11130 sizeof(double)); 11131 return len; 11132 } 11133 table_id = out->args.table_destroy.table_id 11134 + out->args.table_destroy.table_id_n++; 11135 if ((uint8_t *)table_id > (uint8_t *)out + size) 11136 return -1; 11137 ctx->objdata = 0; 11138 ctx->object = table_id; 11139 ctx->objmask = NULL; 11140 return len; 11141 } 11142 11143 /** Parse tokens for queue create commands. */ 11144 static int 11145 parse_qo(struct context *ctx, const struct token *token, 11146 const char *str, unsigned int len, 11147 void *buf, unsigned int size) 11148 { 11149 struct buffer *out = buf; 11150 11151 /* Token name must match. */ 11152 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11153 return -1; 11154 /* Nothing else to do if there is no buffer. */ 11155 if (!out) 11156 return len; 11157 if (!out->command) { 11158 if (ctx->curr != QUEUE) 11159 return -1; 11160 if (sizeof(*out) > size) 11161 return -1; 11162 out->command = ctx->curr; 11163 ctx->objdata = 0; 11164 ctx->object = out; 11165 ctx->objmask = NULL; 11166 out->args.vc.data = (uint8_t *)out + size; 11167 return len; 11168 } 11169 switch (ctx->curr) { 11170 case QUEUE_CREATE: 11171 case QUEUE_UPDATE: 11172 out->command = ctx->curr; 11173 ctx->objdata = 0; 11174 ctx->object = out; 11175 ctx->objmask = NULL; 11176 out->args.vc.rule_id = UINT32_MAX; 11177 return len; 11178 case QUEUE_TEMPLATE_TABLE: 11179 case QUEUE_PATTERN_TEMPLATE: 11180 case QUEUE_ACTIONS_TEMPLATE: 11181 case QUEUE_CREATE_POSTPONE: 11182 case QUEUE_RULE_ID: 11183 case QUEUE_UPDATE_ID: 11184 return len; 11185 case ITEM_PATTERN: 11186 out->args.vc.pattern = 11187 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11188 sizeof(double)); 11189 ctx->object = out->args.vc.pattern; 11190 ctx->objmask = NULL; 11191 return len; 11192 case ACTIONS: 11193 out->args.vc.actions = 11194 (void *)RTE_ALIGN_CEIL((uintptr_t) 11195 (out->args.vc.pattern + 11196 out->args.vc.pattern_n), 11197 sizeof(double)); 11198 ctx->object = out->args.vc.actions; 11199 ctx->objmask = NULL; 11200 return len; 11201 default: 11202 return -1; 11203 } 11204 } 11205 11206 /** Parse tokens for queue destroy command. */ 11207 static int 11208 parse_qo_destroy(struct context *ctx, const struct token *token, 11209 const char *str, unsigned int len, 11210 void *buf, unsigned int size) 11211 { 11212 struct buffer *out = buf; 11213 uint64_t *flow_id; 11214 11215 /* Token name must match. */ 11216 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11217 return -1; 11218 /* Nothing else to do if there is no buffer. */ 11219 if (!out) 11220 return len; 11221 if (!out->command || out->command == QUEUE) { 11222 if (ctx->curr != QUEUE_DESTROY && 11223 ctx->curr != QUEUE_FLOW_UPDATE_RESIZED) 11224 return -1; 11225 if (sizeof(*out) > size) 11226 return -1; 11227 out->command = ctx->curr; 11228 ctx->objdata = 0; 11229 ctx->object = out; 11230 ctx->objmask = NULL; 11231 out->args.destroy.rule = 11232 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11233 sizeof(double)); 11234 return len; 11235 } 11236 switch (ctx->curr) { 11237 case QUEUE_DESTROY_ID: 11238 flow_id = out->args.destroy.rule 11239 + out->args.destroy.rule_n++; 11240 if ((uint8_t *)flow_id > (uint8_t *)out + size) 11241 return -1; 11242 ctx->objdata = 0; 11243 ctx->object = flow_id; 11244 ctx->objmask = NULL; 11245 return len; 11246 case QUEUE_DESTROY_POSTPONE: 11247 return len; 11248 default: 11249 return -1; 11250 } 11251 } 11252 11253 /** Parse tokens for push queue command. */ 11254 static int 11255 parse_push(struct context *ctx, const struct token *token, 11256 const char *str, unsigned int len, 11257 void *buf, unsigned int size) 11258 { 11259 struct buffer *out = buf; 11260 11261 /* Token name must match. */ 11262 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11263 return -1; 11264 /* Nothing else to do if there is no buffer. */ 11265 if (!out) 11266 return len; 11267 if (!out->command) { 11268 if (ctx->curr != PUSH) 11269 return -1; 11270 if (sizeof(*out) > size) 11271 return -1; 11272 out->command = ctx->curr; 11273 ctx->objdata = 0; 11274 ctx->object = out; 11275 ctx->objmask = NULL; 11276 out->args.vc.data = (uint8_t *)out + size; 11277 } 11278 return len; 11279 } 11280 11281 /** Parse tokens for pull command. */ 11282 static int 11283 parse_pull(struct context *ctx, const struct token *token, 11284 const char *str, unsigned int len, 11285 void *buf, unsigned int size) 11286 { 11287 struct buffer *out = buf; 11288 11289 /* Token name must match. */ 11290 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11291 return -1; 11292 /* Nothing else to do if there is no buffer. */ 11293 if (!out) 11294 return len; 11295 if (!out->command) { 11296 if (ctx->curr != PULL) 11297 return -1; 11298 if (sizeof(*out) > size) 11299 return -1; 11300 out->command = ctx->curr; 11301 ctx->objdata = 0; 11302 ctx->object = out; 11303 ctx->objmask = NULL; 11304 out->args.vc.data = (uint8_t *)out + size; 11305 } 11306 return len; 11307 } 11308 11309 /** Parse tokens for hash calculation commands. */ 11310 static int 11311 parse_hash(struct context *ctx, const struct token *token, 11312 const char *str, unsigned int len, 11313 void *buf, unsigned int size) 11314 { 11315 struct buffer *out = buf; 11316 11317 /* Token name must match. */ 11318 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11319 return -1; 11320 /* Nothing else to do if there is no buffer. */ 11321 if (!out) 11322 return len; 11323 if (!out->command) { 11324 if (ctx->curr != HASH) 11325 return -1; 11326 if (sizeof(*out) > size) 11327 return -1; 11328 out->command = ctx->curr; 11329 ctx->objdata = 0; 11330 ctx->object = out; 11331 ctx->objmask = NULL; 11332 out->args.vc.data = (uint8_t *)out + size; 11333 return len; 11334 } 11335 switch (ctx->curr) { 11336 case HASH_CALC_TABLE: 11337 case HASH_CALC_PATTERN_INDEX: 11338 return len; 11339 case ITEM_PATTERN: 11340 out->args.vc.pattern = 11341 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11342 sizeof(double)); 11343 ctx->object = out->args.vc.pattern; 11344 ctx->objmask = NULL; 11345 return len; 11346 case HASH_CALC_ENCAP: 11347 out->args.vc.encap_hash = 1; 11348 return len; 11349 case ENCAP_HASH_FIELD_SRC_PORT: 11350 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT; 11351 return len; 11352 case ENCAP_HASH_FIELD_GRE_FLOW_ID: 11353 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID; 11354 return len; 11355 default: 11356 return -1; 11357 } 11358 } 11359 11360 static int 11361 parse_group(struct context *ctx, const struct token *token, 11362 const char *str, unsigned int len, 11363 void *buf, unsigned int size) 11364 { 11365 struct buffer *out = buf; 11366 11367 /* Token name must match. */ 11368 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11369 return -1; 11370 /* Nothing else to do if there is no buffer. */ 11371 if (!out) 11372 return len; 11373 if (!out->command) { 11374 if (ctx->curr != FLOW_GROUP) 11375 return -1; 11376 if (sizeof(*out) > size) 11377 return -1; 11378 out->command = ctx->curr; 11379 ctx->objdata = 0; 11380 ctx->object = out; 11381 ctx->objmask = NULL; 11382 out->args.vc.data = (uint8_t *)out + size; 11383 return len; 11384 } 11385 switch (ctx->curr) { 11386 case GROUP_INGRESS: 11387 out->args.vc.attr.ingress = 1; 11388 return len; 11389 case GROUP_EGRESS: 11390 out->args.vc.attr.egress = 1; 11391 return len; 11392 case GROUP_TRANSFER: 11393 out->args.vc.attr.transfer = 1; 11394 return len; 11395 case GROUP_SET_MISS_ACTIONS: 11396 out->command = ctx->curr; 11397 ctx->objdata = 0; 11398 ctx->object = out; 11399 ctx->objmask = NULL; 11400 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11401 sizeof(double)); 11402 return len; 11403 default: 11404 return -1; 11405 } 11406 } 11407 11408 static int 11409 parse_flex(struct context *ctx, const struct token *token, 11410 const char *str, unsigned int len, 11411 void *buf, unsigned int size) 11412 { 11413 struct buffer *out = buf; 11414 11415 /* Token name must match. */ 11416 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11417 return -1; 11418 /* Nothing else to do if there is no buffer. */ 11419 if (!out) 11420 return len; 11421 if (out->command == ZERO) { 11422 if (ctx->curr != FLEX) 11423 return -1; 11424 if (sizeof(*out) > size) 11425 return -1; 11426 out->command = ctx->curr; 11427 ctx->objdata = 0; 11428 ctx->object = out; 11429 ctx->objmask = NULL; 11430 } else { 11431 switch (ctx->curr) { 11432 default: 11433 break; 11434 case FLEX_ITEM_INIT: 11435 case FLEX_ITEM_CREATE: 11436 case FLEX_ITEM_DESTROY: 11437 out->command = ctx->curr; 11438 break; 11439 } 11440 } 11441 11442 return len; 11443 } 11444 11445 static int 11446 parse_tunnel(struct context *ctx, const struct token *token, 11447 const char *str, unsigned int len, 11448 void *buf, unsigned int size) 11449 { 11450 struct buffer *out = buf; 11451 11452 /* Token name must match. */ 11453 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11454 return -1; 11455 /* Nothing else to do if there is no buffer. */ 11456 if (!out) 11457 return len; 11458 if (!out->command) { 11459 if (ctx->curr != TUNNEL) 11460 return -1; 11461 if (sizeof(*out) > size) 11462 return -1; 11463 out->command = ctx->curr; 11464 ctx->objdata = 0; 11465 ctx->object = out; 11466 ctx->objmask = NULL; 11467 } else { 11468 switch (ctx->curr) { 11469 default: 11470 break; 11471 case TUNNEL_CREATE: 11472 case TUNNEL_DESTROY: 11473 case TUNNEL_LIST: 11474 out->command = ctx->curr; 11475 break; 11476 case TUNNEL_CREATE_TYPE: 11477 case TUNNEL_DESTROY_ID: 11478 ctx->object = &out->args.vc.tunnel_ops; 11479 break; 11480 } 11481 } 11482 11483 return len; 11484 } 11485 11486 /** 11487 * Parse signed/unsigned integers 8 to 64-bit long. 11488 * 11489 * Last argument (ctx->args) is retrieved to determine integer type and 11490 * storage location. 11491 */ 11492 static int 11493 parse_int(struct context *ctx, const struct token *token, 11494 const char *str, unsigned int len, 11495 void *buf, unsigned int size) 11496 { 11497 const struct arg *arg = pop_args(ctx); 11498 uintmax_t u; 11499 char *end; 11500 11501 (void)token; 11502 /* Argument is expected. */ 11503 if (!arg) 11504 return -1; 11505 errno = 0; 11506 u = arg->sign ? 11507 (uintmax_t)strtoimax(str, &end, 0) : 11508 strtoumax(str, &end, 0); 11509 if (errno || (size_t)(end - str) != len) 11510 goto error; 11511 if (arg->bounded && 11512 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 11513 (intmax_t)u > (intmax_t)arg->max)) || 11514 (!arg->sign && (u < arg->min || u > arg->max)))) 11515 goto error; 11516 if (!ctx->object) 11517 return len; 11518 if (arg->mask) { 11519 if (!arg_entry_bf_fill(ctx->object, u, arg) || 11520 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 11521 goto error; 11522 return len; 11523 } 11524 buf = (uint8_t *)ctx->object + arg->offset; 11525 size = arg->size; 11526 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 11527 return -1; 11528 objmask: 11529 switch (size) { 11530 case sizeof(uint8_t): 11531 *(uint8_t *)buf = u; 11532 break; 11533 case sizeof(uint16_t): 11534 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 11535 break; 11536 case sizeof(uint8_t [3]): 11537 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 11538 if (!arg->hton) { 11539 ((uint8_t *)buf)[0] = u; 11540 ((uint8_t *)buf)[1] = u >> 8; 11541 ((uint8_t *)buf)[2] = u >> 16; 11542 break; 11543 } 11544 #endif 11545 ((uint8_t *)buf)[0] = u >> 16; 11546 ((uint8_t *)buf)[1] = u >> 8; 11547 ((uint8_t *)buf)[2] = u; 11548 break; 11549 case sizeof(uint32_t): 11550 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 11551 break; 11552 case sizeof(uint64_t): 11553 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 11554 break; 11555 default: 11556 goto error; 11557 } 11558 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 11559 u = -1; 11560 buf = (uint8_t *)ctx->objmask + arg->offset; 11561 goto objmask; 11562 } 11563 return len; 11564 error: 11565 push_args(ctx, arg); 11566 return -1; 11567 } 11568 11569 /** 11570 * Parse a string. 11571 * 11572 * Three arguments (ctx->args) are retrieved from the stack to store data, 11573 * its actual length and address (in that order). 11574 */ 11575 static int 11576 parse_string(struct context *ctx, const struct token *token, 11577 const char *str, unsigned int len, 11578 void *buf, unsigned int size) 11579 { 11580 const struct arg *arg_data = pop_args(ctx); 11581 const struct arg *arg_len = pop_args(ctx); 11582 const struct arg *arg_addr = pop_args(ctx); 11583 char tmp[16]; /* Ought to be enough. */ 11584 int ret; 11585 11586 /* Arguments are expected. */ 11587 if (!arg_data) 11588 return -1; 11589 if (!arg_len) { 11590 push_args(ctx, arg_data); 11591 return -1; 11592 } 11593 if (!arg_addr) { 11594 push_args(ctx, arg_len); 11595 push_args(ctx, arg_data); 11596 return -1; 11597 } 11598 size = arg_data->size; 11599 /* Bit-mask fill is not supported. */ 11600 if (arg_data->mask || size < len) 11601 goto error; 11602 if (!ctx->object) 11603 return len; 11604 /* Let parse_int() fill length information first. */ 11605 ret = snprintf(tmp, sizeof(tmp), "%u", len); 11606 if (ret < 0) 11607 goto error; 11608 push_args(ctx, arg_len); 11609 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11610 if (ret < 0) { 11611 pop_args(ctx); 11612 goto error; 11613 } 11614 buf = (uint8_t *)ctx->object + arg_data->offset; 11615 /* Output buffer is not necessarily NUL-terminated. */ 11616 memcpy(buf, str, len); 11617 memset((uint8_t *)buf + len, 0x00, size - len); 11618 if (ctx->objmask) 11619 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11620 /* Save address if requested. */ 11621 if (arg_addr->size) { 11622 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11623 (void *[]){ 11624 (uint8_t *)ctx->object + arg_data->offset 11625 }, 11626 arg_addr->size); 11627 if (ctx->objmask) 11628 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11629 (void *[]){ 11630 (uint8_t *)ctx->objmask + arg_data->offset 11631 }, 11632 arg_addr->size); 11633 } 11634 return len; 11635 error: 11636 push_args(ctx, arg_addr); 11637 push_args(ctx, arg_len); 11638 push_args(ctx, arg_data); 11639 return -1; 11640 } 11641 11642 static int 11643 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 11644 { 11645 const uint8_t *head = dst; 11646 uint32_t left; 11647 11648 if (*size == 0) 11649 return -1; 11650 11651 left = *size; 11652 11653 /* Convert chars to bytes */ 11654 while (left) { 11655 char tmp[3], *end = tmp; 11656 uint32_t read_lim = left & 1 ? 1 : 2; 11657 11658 snprintf(tmp, read_lim + 1, "%s", src); 11659 *dst = strtoul(tmp, &end, 16); 11660 if (*end) { 11661 *dst = 0; 11662 *size = (uint32_t)(dst - head); 11663 return -1; 11664 } 11665 left -= read_lim; 11666 src += read_lim; 11667 dst++; 11668 } 11669 *dst = 0; 11670 *size = (uint32_t)(dst - head); 11671 return 0; 11672 } 11673 11674 static int 11675 parse_hex(struct context *ctx, const struct token *token, 11676 const char *str, unsigned int len, 11677 void *buf, unsigned int size) 11678 { 11679 const struct arg *arg_data = pop_args(ctx); 11680 const struct arg *arg_len = pop_args(ctx); 11681 const struct arg *arg_addr = pop_args(ctx); 11682 char tmp[16]; /* Ought to be enough. */ 11683 int ret; 11684 unsigned int hexlen = len; 11685 unsigned int length = 256; 11686 uint8_t hex_tmp[length]; 11687 11688 /* Arguments are expected. */ 11689 if (!arg_data) 11690 return -1; 11691 if (!arg_len) { 11692 push_args(ctx, arg_data); 11693 return -1; 11694 } 11695 if (!arg_addr) { 11696 push_args(ctx, arg_len); 11697 push_args(ctx, arg_data); 11698 return -1; 11699 } 11700 size = arg_data->size; 11701 /* Bit-mask fill is not supported. */ 11702 if (arg_data->mask) 11703 goto error; 11704 if (!ctx->object) 11705 return len; 11706 11707 /* translate bytes string to array. */ 11708 if (str[0] == '0' && ((str[1] == 'x') || 11709 (str[1] == 'X'))) { 11710 str += 2; 11711 hexlen -= 2; 11712 } 11713 if (hexlen > length) 11714 goto error; 11715 ret = parse_hex_string(str, hex_tmp, &hexlen); 11716 if (ret < 0) 11717 goto error; 11718 /* Check the converted binary fits into data buffer. */ 11719 if (hexlen > size) 11720 goto error; 11721 /* Let parse_int() fill length information first. */ 11722 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 11723 if (ret < 0) 11724 goto error; 11725 /* Save length if requested. */ 11726 if (arg_len->size) { 11727 push_args(ctx, arg_len); 11728 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11729 if (ret < 0) { 11730 pop_args(ctx); 11731 goto error; 11732 } 11733 } 11734 buf = (uint8_t *)ctx->object + arg_data->offset; 11735 /* Output buffer is not necessarily NUL-terminated. */ 11736 memcpy(buf, hex_tmp, hexlen); 11737 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 11738 if (ctx->objmask) 11739 memset((uint8_t *)ctx->objmask + arg_data->offset, 11740 0xff, hexlen); 11741 /* Save address if requested. */ 11742 if (arg_addr->size) { 11743 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11744 (void *[]){ 11745 (uint8_t *)ctx->object + arg_data->offset 11746 }, 11747 arg_addr->size); 11748 if (ctx->objmask) 11749 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11750 (void *[]){ 11751 (uint8_t *)ctx->objmask + arg_data->offset 11752 }, 11753 arg_addr->size); 11754 } 11755 return len; 11756 error: 11757 push_args(ctx, arg_addr); 11758 push_args(ctx, arg_len); 11759 push_args(ctx, arg_data); 11760 return -1; 11761 11762 } 11763 11764 /** 11765 * Parse a zero-ended string. 11766 */ 11767 static int 11768 parse_string0(struct context *ctx, const struct token *token __rte_unused, 11769 const char *str, unsigned int len, 11770 void *buf, unsigned int size) 11771 { 11772 const struct arg *arg_data = pop_args(ctx); 11773 11774 /* Arguments are expected. */ 11775 if (!arg_data) 11776 return -1; 11777 size = arg_data->size; 11778 /* Bit-mask fill is not supported. */ 11779 if (arg_data->mask || size < len + 1) 11780 goto error; 11781 if (!ctx->object) 11782 return len; 11783 buf = (uint8_t *)ctx->object + arg_data->offset; 11784 strncpy(buf, str, len); 11785 if (ctx->objmask) 11786 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11787 return len; 11788 error: 11789 push_args(ctx, arg_data); 11790 return -1; 11791 } 11792 11793 /** 11794 * Parse a MAC address. 11795 * 11796 * Last argument (ctx->args) is retrieved to determine storage size and 11797 * location. 11798 */ 11799 static int 11800 parse_mac_addr(struct context *ctx, const struct token *token, 11801 const char *str, unsigned int len, 11802 void *buf, unsigned int size) 11803 { 11804 const struct arg *arg = pop_args(ctx); 11805 struct rte_ether_addr tmp; 11806 int ret; 11807 11808 (void)token; 11809 /* Argument is expected. */ 11810 if (!arg) 11811 return -1; 11812 size = arg->size; 11813 /* Bit-mask fill is not supported. */ 11814 if (arg->mask || size != sizeof(tmp)) 11815 goto error; 11816 /* Only network endian is supported. */ 11817 if (!arg->hton) 11818 goto error; 11819 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 11820 if (ret < 0 || (unsigned int)ret != len) 11821 goto error; 11822 if (!ctx->object) 11823 return len; 11824 buf = (uint8_t *)ctx->object + arg->offset; 11825 memcpy(buf, &tmp, size); 11826 if (ctx->objmask) 11827 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11828 return len; 11829 error: 11830 push_args(ctx, arg); 11831 return -1; 11832 } 11833 11834 /** 11835 * Parse an IPv4 address. 11836 * 11837 * Last argument (ctx->args) is retrieved to determine storage size and 11838 * location. 11839 */ 11840 static int 11841 parse_ipv4_addr(struct context *ctx, const struct token *token, 11842 const char *str, unsigned int len, 11843 void *buf, unsigned int size) 11844 { 11845 const struct arg *arg = pop_args(ctx); 11846 char str2[len + 1]; 11847 struct in_addr tmp; 11848 int ret; 11849 11850 /* Argument is expected. */ 11851 if (!arg) 11852 return -1; 11853 size = arg->size; 11854 /* Bit-mask fill is not supported. */ 11855 if (arg->mask || size != sizeof(tmp)) 11856 goto error; 11857 /* Only network endian is supported. */ 11858 if (!arg->hton) 11859 goto error; 11860 memcpy(str2, str, len); 11861 str2[len] = '\0'; 11862 ret = inet_pton(AF_INET, str2, &tmp); 11863 if (ret != 1) { 11864 /* Attempt integer parsing. */ 11865 push_args(ctx, arg); 11866 return parse_int(ctx, token, str, len, buf, size); 11867 } 11868 if (!ctx->object) 11869 return len; 11870 buf = (uint8_t *)ctx->object + arg->offset; 11871 memcpy(buf, &tmp, size); 11872 if (ctx->objmask) 11873 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11874 return len; 11875 error: 11876 push_args(ctx, arg); 11877 return -1; 11878 } 11879 11880 /** 11881 * Parse an IPv6 address. 11882 * 11883 * Last argument (ctx->args) is retrieved to determine storage size and 11884 * location. 11885 */ 11886 static int 11887 parse_ipv6_addr(struct context *ctx, const struct token *token, 11888 const char *str, unsigned int len, 11889 void *buf, unsigned int size) 11890 { 11891 const struct arg *arg = pop_args(ctx); 11892 char str2[len + 1]; 11893 struct in6_addr tmp; 11894 int ret; 11895 11896 (void)token; 11897 /* Argument is expected. */ 11898 if (!arg) 11899 return -1; 11900 size = arg->size; 11901 /* Bit-mask fill is not supported. */ 11902 if (arg->mask || size != sizeof(tmp)) 11903 goto error; 11904 /* Only network endian is supported. */ 11905 if (!arg->hton) 11906 goto error; 11907 memcpy(str2, str, len); 11908 str2[len] = '\0'; 11909 ret = inet_pton(AF_INET6, str2, &tmp); 11910 if (ret != 1) 11911 goto error; 11912 if (!ctx->object) 11913 return len; 11914 buf = (uint8_t *)ctx->object + arg->offset; 11915 memcpy(buf, &tmp, size); 11916 if (ctx->objmask) 11917 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11918 return len; 11919 error: 11920 push_args(ctx, arg); 11921 return -1; 11922 } 11923 11924 /** Boolean values (even indices stand for false). */ 11925 static const char *const boolean_name[] = { 11926 "0", "1", 11927 "false", "true", 11928 "no", "yes", 11929 "N", "Y", 11930 "off", "on", 11931 NULL, 11932 }; 11933 11934 /** 11935 * Parse a boolean value. 11936 * 11937 * Last argument (ctx->args) is retrieved to determine storage size and 11938 * location. 11939 */ 11940 static int 11941 parse_boolean(struct context *ctx, const struct token *token, 11942 const char *str, unsigned int len, 11943 void *buf, unsigned int size) 11944 { 11945 const struct arg *arg = pop_args(ctx); 11946 unsigned int i; 11947 int ret; 11948 11949 /* Argument is expected. */ 11950 if (!arg) 11951 return -1; 11952 for (i = 0; boolean_name[i]; ++i) 11953 if (!strcmp_partial(boolean_name[i], str, len)) 11954 break; 11955 /* Process token as integer. */ 11956 if (boolean_name[i]) 11957 str = i & 1 ? "1" : "0"; 11958 push_args(ctx, arg); 11959 ret = parse_int(ctx, token, str, strlen(str), buf, size); 11960 return ret > 0 ? (int)len : ret; 11961 } 11962 11963 /** Parse port and update context. */ 11964 static int 11965 parse_port(struct context *ctx, const struct token *token, 11966 const char *str, unsigned int len, 11967 void *buf, unsigned int size) 11968 { 11969 struct buffer *out = &(struct buffer){ .port = 0 }; 11970 int ret; 11971 11972 if (buf) 11973 out = buf; 11974 else { 11975 ctx->objdata = 0; 11976 ctx->object = out; 11977 ctx->objmask = NULL; 11978 size = sizeof(*out); 11979 } 11980 ret = parse_int(ctx, token, str, len, out, size); 11981 if (ret >= 0) 11982 ctx->port = out->port; 11983 if (!buf) 11984 ctx->object = NULL; 11985 return ret; 11986 } 11987 11988 /** Parse tokens for shared indirect actions. */ 11989 static int 11990 parse_ia_port(struct context *ctx, const struct token *token, 11991 const char *str, unsigned int len, 11992 void *buf, unsigned int size) 11993 { 11994 struct rte_flow_action *action = ctx->object; 11995 uint32_t id; 11996 int ret; 11997 11998 (void)buf; 11999 (void)size; 12000 ctx->objdata = 0; 12001 ctx->object = &id; 12002 ctx->objmask = NULL; 12003 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12004 ctx->object = action; 12005 if (ret != (int)len) 12006 return ret; 12007 /* set indirect action */ 12008 if (action) 12009 action->conf = (void *)(uintptr_t)id; 12010 return ret; 12011 } 12012 12013 static int 12014 parse_ia_id2ptr(struct context *ctx, const struct token *token, 12015 const char *str, unsigned int len, 12016 void *buf, unsigned int size) 12017 { 12018 struct rte_flow_action *action = ctx->object; 12019 uint32_t id; 12020 int ret; 12021 12022 (void)buf; 12023 (void)size; 12024 ctx->objdata = 0; 12025 ctx->object = &id; 12026 ctx->objmask = NULL; 12027 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12028 ctx->object = action; 12029 if (ret != (int)len) 12030 return ret; 12031 /* set indirect action */ 12032 if (action) { 12033 portid_t port_id = ctx->port; 12034 if (ctx->prev == INDIRECT_ACTION_PORT) 12035 port_id = (portid_t)(uintptr_t)action->conf; 12036 action->conf = port_action_handle_get_by_id(port_id, id); 12037 ret = (action->conf) ? ret : -1; 12038 } 12039 return ret; 12040 } 12041 12042 static int 12043 parse_indlst_id2ptr(struct context *ctx, const struct token *token, 12044 const char *str, unsigned int len, 12045 __rte_unused void *buf, __rte_unused unsigned int size) 12046 { 12047 struct rte_flow_action *action = ctx->object; 12048 struct rte_flow_action_indirect_list *action_conf; 12049 const struct indlst_conf *indlst_conf; 12050 uint32_t id; 12051 int ret; 12052 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 12061 /* set handle and conf */ 12062 if (action) { 12063 action_conf = (void *)(uintptr_t)action->conf; 12064 action_conf->conf = NULL; 12065 switch (ctx->curr) { 12066 case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: 12067 action_conf->handle = (typeof(action_conf->handle)) 12068 port_action_handle_get_by_id(ctx->port, id); 12069 if (!action_conf->handle) { 12070 printf("no indirect list handle for id %u\n", id); 12071 return -1; 12072 } 12073 break; 12074 case INDIRECT_LIST_ACTION_ID2PTR_CONF: 12075 indlst_conf = indirect_action_list_conf_get(id); 12076 if (!indlst_conf) 12077 return -1; 12078 action_conf->conf = (const void **)indlst_conf->conf; 12079 break; 12080 default: 12081 break; 12082 } 12083 } 12084 return ret; 12085 } 12086 12087 static int 12088 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 12089 const char *str, unsigned int len, 12090 void *buf, unsigned int size) 12091 { 12092 struct rte_flow_action *action = ctx->object; 12093 struct rte_flow_action_meter_mark *meter; 12094 struct rte_flow_meter_profile *profile = NULL; 12095 uint32_t id = 0; 12096 int ret; 12097 12098 (void)buf; 12099 (void)size; 12100 ctx->objdata = 0; 12101 ctx->object = &id; 12102 ctx->objmask = NULL; 12103 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12104 ctx->object = action; 12105 if (ret != (int)len) 12106 return ret; 12107 /* set meter profile */ 12108 if (action) { 12109 meter = (struct rte_flow_action_meter_mark *) 12110 (uintptr_t)(action->conf); 12111 profile = port_meter_profile_get_by_id(ctx->port, id); 12112 meter->profile = profile; 12113 ret = (profile) ? ret : -1; 12114 } 12115 return ret; 12116 } 12117 12118 static int 12119 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 12120 const char *str, unsigned int len, 12121 void *buf, unsigned int size) 12122 { 12123 struct rte_flow_action *action = ctx->object; 12124 struct rte_flow_action_meter_mark *meter; 12125 struct rte_flow_meter_policy *policy = NULL; 12126 uint32_t id = 0; 12127 int ret; 12128 12129 (void)buf; 12130 (void)size; 12131 ctx->objdata = 0; 12132 ctx->object = &id; 12133 ctx->objmask = NULL; 12134 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12135 ctx->object = action; 12136 if (ret != (int)len) 12137 return ret; 12138 /* set meter policy */ 12139 if (action) { 12140 meter = (struct rte_flow_action_meter_mark *) 12141 (uintptr_t)(action->conf); 12142 policy = port_meter_policy_get_by_id(ctx->port, id); 12143 meter->policy = policy; 12144 ret = (policy) ? ret : -1; 12145 } 12146 return ret; 12147 } 12148 12149 /** Parse set command, initialize output buffer for subsequent tokens. */ 12150 static int 12151 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 12152 const char *str, unsigned int len, 12153 void *buf, unsigned int size) 12154 { 12155 struct buffer *out = buf; 12156 12157 /* Token name must match. */ 12158 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12159 return -1; 12160 /* Nothing else to do if there is no buffer. */ 12161 if (!out) 12162 return len; 12163 /* Make sure buffer is large enough. */ 12164 if (size < sizeof(*out)) 12165 return -1; 12166 ctx->objdata = 0; 12167 ctx->objmask = NULL; 12168 ctx->object = out; 12169 if (!out->command) 12170 return -1; 12171 out->command = ctx->curr; 12172 /* For encap/decap we need is pattern */ 12173 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12174 sizeof(double)); 12175 return len; 12176 } 12177 12178 /** Parse set command, initialize output buffer for subsequent tokens. */ 12179 static int 12180 parse_set_sample_action(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 sampler we need is actions */ 12202 out->args.vc.actions = (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_ipv6_ext_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 ipv6_ext_push/remove we need is pattern */ 12231 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12232 sizeof(double)); 12233 return len; 12234 } 12235 12236 /** 12237 * Parse set raw_encap/raw_decap command, 12238 * initialize output buffer for subsequent tokens. 12239 */ 12240 static int 12241 parse_set_init(struct context *ctx, const struct token *token, 12242 const char *str, unsigned int len, 12243 void *buf, unsigned int size) 12244 { 12245 struct buffer *out = buf; 12246 12247 /* Token name must match. */ 12248 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12249 return -1; 12250 /* Nothing else to do if there is no buffer. */ 12251 if (!out) 12252 return len; 12253 /* Make sure buffer is large enough. */ 12254 if (size < sizeof(*out)) 12255 return -1; 12256 /* Initialize buffer. */ 12257 memset(out, 0x00, sizeof(*out)); 12258 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 12259 ctx->objdata = 0; 12260 ctx->object = out; 12261 ctx->objmask = NULL; 12262 if (!out->command) { 12263 if (ctx->curr != SET) 12264 return -1; 12265 if (sizeof(*out) > size) 12266 return -1; 12267 out->command = ctx->curr; 12268 out->args.vc.data = (uint8_t *)out + size; 12269 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12270 sizeof(double)); 12271 } 12272 return len; 12273 } 12274 12275 /* 12276 * Replace testpmd handles in a flex flow item with real values. 12277 */ 12278 static int 12279 parse_flex_handle(struct context *ctx, const struct token *token, 12280 const char *str, unsigned int len, 12281 void *buf, unsigned int size) 12282 { 12283 struct rte_flow_item_flex *spec, *mask; 12284 const struct rte_flow_item_flex *src_spec, *src_mask; 12285 const struct arg *arg = pop_args(ctx); 12286 uint32_t offset; 12287 uint16_t handle; 12288 int ret; 12289 12290 if (!arg) { 12291 printf("Bad environment\n"); 12292 return -1; 12293 } 12294 offset = arg->offset; 12295 push_args(ctx, arg); 12296 ret = parse_int(ctx, token, str, len, buf, size); 12297 if (ret <= 0 || !ctx->object) 12298 return ret; 12299 if (ctx->port >= RTE_MAX_ETHPORTS) { 12300 printf("Bad port\n"); 12301 return -1; 12302 } 12303 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 12304 const struct flex_item *fp; 12305 spec = ctx->object; 12306 handle = (uint16_t)(uintptr_t)spec->handle; 12307 if (handle >= FLEX_MAX_PARSERS_NUM) { 12308 printf("Bad flex item handle\n"); 12309 return -1; 12310 } 12311 fp = flex_items[ctx->port][handle]; 12312 if (!fp) { 12313 printf("Bad flex item handle\n"); 12314 return -1; 12315 } 12316 spec->handle = fp->flex_handle; 12317 mask = spec + 2; /* spec, last, mask */ 12318 mask->handle = fp->flex_handle; 12319 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 12320 handle = (uint16_t)(uintptr_t) 12321 ((struct rte_flow_item_flex *)ctx->object)->pattern; 12322 if (handle >= FLEX_MAX_PATTERNS_NUM) { 12323 printf("Bad pattern handle\n"); 12324 return -1; 12325 } 12326 src_spec = &flex_patterns[handle].spec; 12327 src_mask = &flex_patterns[handle].mask; 12328 spec = ctx->object; 12329 mask = spec + 2; /* spec, last, mask */ 12330 /* fill flow rule spec and mask parameters */ 12331 spec->length = src_spec->length; 12332 spec->pattern = src_spec->pattern; 12333 mask->length = src_mask->length; 12334 mask->pattern = src_mask->pattern; 12335 } else { 12336 printf("Bad arguments - unknown flex item offset\n"); 12337 return -1; 12338 } 12339 return ret; 12340 } 12341 12342 /** Parse Meter color name */ 12343 static int 12344 parse_meter_color(struct context *ctx, const struct token *token, 12345 const char *str, unsigned int len, void *buf, 12346 unsigned int size) 12347 { 12348 struct rte_flow_item_meter_color *meter_color; 12349 unsigned int i; 12350 12351 (void)token; 12352 (void)buf; 12353 (void)size; 12354 for (i = 0; meter_colors[i]; ++i) 12355 if (!strcmp_partial(meter_colors[i], str, len)) 12356 break; 12357 if (!meter_colors[i]) 12358 return -1; 12359 if (!ctx->object) 12360 return len; 12361 meter_color = ctx->object; 12362 meter_color->color = (enum rte_color)i; 12363 return len; 12364 } 12365 12366 /** Parse Insertion Table Type name */ 12367 static int 12368 parse_insertion_table_type(struct context *ctx, const struct token *token, 12369 const char *str, unsigned int len, void *buf, 12370 unsigned int size) 12371 { 12372 const struct arg *arg = pop_args(ctx); 12373 unsigned int i; 12374 char tmp[2]; 12375 int ret; 12376 12377 (void)size; 12378 /* Argument is expected. */ 12379 if (!arg) 12380 return -1; 12381 for (i = 0; table_insertion_types[i]; ++i) 12382 if (!strcmp_partial(table_insertion_types[i], str, len)) 12383 break; 12384 if (!table_insertion_types[i]) 12385 return -1; 12386 push_args(ctx, arg); 12387 snprintf(tmp, sizeof(tmp), "%u", i); 12388 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12389 return ret > 0 ? (int)len : ret; 12390 } 12391 12392 /** Parse Hash Calculation Table Type name */ 12393 static int 12394 parse_hash_table_type(struct context *ctx, const struct token *token, 12395 const char *str, unsigned int len, void *buf, 12396 unsigned int size) 12397 { 12398 const struct arg *arg = pop_args(ctx); 12399 unsigned int i; 12400 char tmp[2]; 12401 int ret; 12402 12403 (void)size; 12404 /* Argument is expected. */ 12405 if (!arg) 12406 return -1; 12407 for (i = 0; table_hash_funcs[i]; ++i) 12408 if (!strcmp_partial(table_hash_funcs[i], str, len)) 12409 break; 12410 if (!table_hash_funcs[i]) 12411 return -1; 12412 push_args(ctx, arg); 12413 snprintf(tmp, sizeof(tmp), "%u", i); 12414 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12415 return ret > 0 ? (int)len : ret; 12416 } 12417 12418 static int 12419 parse_name_to_index(struct context *ctx, const struct token *token, 12420 const char *str, unsigned int len, void *buf, 12421 unsigned int size, 12422 const char *const names[], size_t names_size, uint32_t *dst) 12423 { 12424 int ret; 12425 uint32_t i; 12426 12427 RTE_SET_USED(token); 12428 RTE_SET_USED(buf); 12429 RTE_SET_USED(size); 12430 if (!ctx->object) 12431 return len; 12432 for (i = 0; i < names_size; i++) { 12433 if (!names[i]) 12434 continue; 12435 ret = strcmp_partial(names[i], str, 12436 RTE_MIN(len, strlen(names[i]))); 12437 if (!ret) { 12438 *dst = i; 12439 return len; 12440 } 12441 } 12442 return -1; 12443 } 12444 12445 static const char *const quota_mode_names[] = { 12446 NULL, 12447 [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", 12448 [RTE_FLOW_QUOTA_MODE_L2] = "l2", 12449 [RTE_FLOW_QUOTA_MODE_L3] = "l3" 12450 }; 12451 12452 static const char *const quota_state_names[] = { 12453 [RTE_FLOW_QUOTA_STATE_PASS] = "pass", 12454 [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" 12455 }; 12456 12457 static const char *const quota_update_names[] = { 12458 [RTE_FLOW_UPDATE_QUOTA_SET] = "set", 12459 [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" 12460 }; 12461 12462 static const char *const query_update_mode_names[] = { 12463 [RTE_FLOW_QU_QUERY_FIRST] = "query_first", 12464 [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" 12465 }; 12466 12467 static int 12468 parse_quota_state_name(struct context *ctx, const struct token *token, 12469 const char *str, unsigned int len, void *buf, 12470 unsigned int size) 12471 { 12472 struct rte_flow_item_quota *quota = ctx->object; 12473 12474 return parse_name_to_index(ctx, token, str, len, buf, size, 12475 quota_state_names, 12476 RTE_DIM(quota_state_names), 12477 (uint32_t *)"a->state); 12478 } 12479 12480 static int 12481 parse_quota_mode_name(struct context *ctx, const struct token *token, 12482 const char *str, unsigned int len, void *buf, 12483 unsigned int size) 12484 { 12485 struct rte_flow_action_quota *quota = ctx->object; 12486 12487 return parse_name_to_index(ctx, token, str, len, buf, size, 12488 quota_mode_names, 12489 RTE_DIM(quota_mode_names), 12490 (uint32_t *)"a->mode); 12491 } 12492 12493 static int 12494 parse_quota_update_name(struct context *ctx, const struct token *token, 12495 const char *str, unsigned int len, void *buf, 12496 unsigned int size) 12497 { 12498 struct rte_flow_update_quota *update = ctx->object; 12499 12500 return parse_name_to_index(ctx, token, str, len, buf, size, 12501 quota_update_names, 12502 RTE_DIM(quota_update_names), 12503 (uint32_t *)&update->op); 12504 } 12505 12506 static int 12507 parse_qu_mode_name(struct context *ctx, const struct token *token, 12508 const char *str, unsigned int len, void *buf, 12509 unsigned int size) 12510 { 12511 struct buffer *out = ctx->object; 12512 12513 return parse_name_to_index(ctx, token, str, len, buf, size, 12514 query_update_mode_names, 12515 RTE_DIM(query_update_mode_names), 12516 (uint32_t *)&out->args.ia.qu_mode); 12517 } 12518 12519 /** No completion. */ 12520 static int 12521 comp_none(struct context *ctx, const struct token *token, 12522 unsigned int ent, char *buf, unsigned int size) 12523 { 12524 (void)ctx; 12525 (void)token; 12526 (void)ent; 12527 (void)buf; 12528 (void)size; 12529 return 0; 12530 } 12531 12532 /** Complete boolean values. */ 12533 static int 12534 comp_boolean(struct context *ctx, const struct token *token, 12535 unsigned int ent, char *buf, unsigned int size) 12536 { 12537 unsigned int i; 12538 12539 (void)ctx; 12540 (void)token; 12541 for (i = 0; boolean_name[i]; ++i) 12542 if (buf && i == ent) 12543 return strlcpy(buf, boolean_name[i], size); 12544 if (buf) 12545 return -1; 12546 return i; 12547 } 12548 12549 /** Complete action names. */ 12550 static int 12551 comp_action(struct context *ctx, const struct token *token, 12552 unsigned int ent, char *buf, unsigned int size) 12553 { 12554 unsigned int i; 12555 12556 (void)ctx; 12557 (void)token; 12558 for (i = 0; next_action[i]; ++i) 12559 if (buf && i == ent) 12560 return strlcpy(buf, token_list[next_action[i]].name, 12561 size); 12562 if (buf) 12563 return -1; 12564 return i; 12565 } 12566 12567 /** Complete available ports. */ 12568 static int 12569 comp_port(struct context *ctx, const struct token *token, 12570 unsigned int ent, char *buf, unsigned int size) 12571 { 12572 unsigned int i = 0; 12573 portid_t p; 12574 12575 (void)ctx; 12576 (void)token; 12577 RTE_ETH_FOREACH_DEV(p) { 12578 if (buf && i == ent) 12579 return snprintf(buf, size, "%u", p); 12580 ++i; 12581 } 12582 if (buf) 12583 return -1; 12584 return i; 12585 } 12586 12587 /** Complete available rule IDs. */ 12588 static int 12589 comp_rule_id(struct context *ctx, const struct token *token, 12590 unsigned int ent, char *buf, unsigned int size) 12591 { 12592 unsigned int i = 0; 12593 struct rte_port *port; 12594 struct port_flow *pf; 12595 12596 (void)token; 12597 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12598 ctx->port == (portid_t)RTE_PORT_ALL) 12599 return -1; 12600 port = &ports[ctx->port]; 12601 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 12602 if (buf && i == ent) 12603 return snprintf(buf, size, "%"PRIu64, pf->id); 12604 ++i; 12605 } 12606 if (buf) 12607 return -1; 12608 return i; 12609 } 12610 12611 /** Complete operation for compare match item. */ 12612 static int 12613 comp_set_compare_op(struct context *ctx, const struct token *token, 12614 unsigned int ent, char *buf, unsigned int size) 12615 { 12616 RTE_SET_USED(ctx); 12617 RTE_SET_USED(token); 12618 if (!buf) 12619 return RTE_DIM(compare_ops); 12620 if (ent < RTE_DIM(compare_ops) - 1) 12621 return strlcpy(buf, compare_ops[ent], size); 12622 return -1; 12623 } 12624 12625 /** Complete field id for compare match item. */ 12626 static int 12627 comp_set_compare_field_id(struct context *ctx, const struct token *token, 12628 unsigned int ent, char *buf, unsigned int size) 12629 { 12630 const char *name; 12631 12632 RTE_SET_USED(token); 12633 if (!buf) 12634 return RTE_DIM(flow_field_ids); 12635 if (ent >= RTE_DIM(flow_field_ids) - 1) 12636 return -1; 12637 name = flow_field_ids[ent]; 12638 if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE || 12639 (strcmp(name, "pointer") && strcmp(name, "value"))) 12640 return strlcpy(buf, name, size); 12641 return -1; 12642 } 12643 12644 /** Complete type field for RSS action. */ 12645 static int 12646 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 12647 unsigned int ent, char *buf, unsigned int size) 12648 { 12649 unsigned int i; 12650 12651 (void)ctx; 12652 (void)token; 12653 for (i = 0; rss_type_table[i].str; ++i) 12654 ; 12655 if (!buf) 12656 return i + 1; 12657 if (ent < i) 12658 return strlcpy(buf, rss_type_table[ent].str, size); 12659 if (ent == i) 12660 return snprintf(buf, size, "end"); 12661 return -1; 12662 } 12663 12664 /** Complete queue field for RSS action. */ 12665 static int 12666 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 12667 unsigned int ent, char *buf, unsigned int size) 12668 { 12669 (void)ctx; 12670 (void)token; 12671 if (!buf) 12672 return nb_rxq + 1; 12673 if (ent < nb_rxq) 12674 return snprintf(buf, size, "%u", ent); 12675 if (ent == nb_rxq) 12676 return snprintf(buf, size, "end"); 12677 return -1; 12678 } 12679 12680 /** Complete index number for set raw_encap/raw_decap commands. */ 12681 static int 12682 comp_set_raw_index(struct context *ctx, const struct token *token, 12683 unsigned int ent, char *buf, unsigned int size) 12684 { 12685 uint16_t idx = 0; 12686 uint16_t nb = 0; 12687 12688 RTE_SET_USED(ctx); 12689 RTE_SET_USED(token); 12690 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 12691 if (buf && idx == ent) 12692 return snprintf(buf, size, "%u", idx); 12693 ++nb; 12694 } 12695 return nb; 12696 } 12697 12698 /** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ 12699 static int 12700 comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 12701 unsigned int ent, char *buf, unsigned int size) 12702 { 12703 uint16_t idx = 0; 12704 uint16_t nb = 0; 12705 12706 RTE_SET_USED(ctx); 12707 RTE_SET_USED(token); 12708 for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { 12709 if (buf && idx == ent) 12710 return snprintf(buf, size, "%u", idx); 12711 ++nb; 12712 } 12713 return nb; 12714 } 12715 12716 /** Complete index number for set raw_encap/raw_decap commands. */ 12717 static int 12718 comp_set_sample_index(struct context *ctx, const struct token *token, 12719 unsigned int ent, char *buf, unsigned int size) 12720 { 12721 uint16_t idx = 0; 12722 uint16_t nb = 0; 12723 12724 RTE_SET_USED(ctx); 12725 RTE_SET_USED(token); 12726 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 12727 if (buf && idx == ent) 12728 return snprintf(buf, size, "%u", idx); 12729 ++nb; 12730 } 12731 return nb; 12732 } 12733 12734 /** Complete operation for modify_field command. */ 12735 static int 12736 comp_set_modify_field_op(struct context *ctx, const struct token *token, 12737 unsigned int ent, char *buf, unsigned int size) 12738 { 12739 RTE_SET_USED(ctx); 12740 RTE_SET_USED(token); 12741 if (!buf) 12742 return RTE_DIM(modify_field_ops); 12743 if (ent < RTE_DIM(modify_field_ops) - 1) 12744 return strlcpy(buf, modify_field_ops[ent], size); 12745 return -1; 12746 } 12747 12748 /** Complete field id for modify_field command. */ 12749 static int 12750 comp_set_modify_field_id(struct context *ctx, const struct token *token, 12751 unsigned int ent, char *buf, unsigned int size) 12752 { 12753 const char *name; 12754 12755 RTE_SET_USED(token); 12756 if (!buf) 12757 return RTE_DIM(flow_field_ids); 12758 if (ent >= RTE_DIM(flow_field_ids) - 1) 12759 return -1; 12760 name = flow_field_ids[ent]; 12761 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 12762 (strcmp(name, "pointer") && strcmp(name, "value"))) 12763 return strlcpy(buf, name, size); 12764 return -1; 12765 } 12766 12767 /** Complete available pattern template IDs. */ 12768 static int 12769 comp_pattern_template_id(struct context *ctx, const struct token *token, 12770 unsigned int ent, char *buf, unsigned int size) 12771 { 12772 unsigned int i = 0; 12773 struct rte_port *port; 12774 struct port_template *pt; 12775 12776 (void)token; 12777 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12778 ctx->port == (portid_t)RTE_PORT_ALL) 12779 return -1; 12780 port = &ports[ctx->port]; 12781 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 12782 if (buf && i == ent) 12783 return snprintf(buf, size, "%u", pt->id); 12784 ++i; 12785 } 12786 if (buf) 12787 return -1; 12788 return i; 12789 } 12790 12791 /** Complete available actions template IDs. */ 12792 static int 12793 comp_actions_template_id(struct context *ctx, const struct token *token, 12794 unsigned int ent, char *buf, unsigned int size) 12795 { 12796 unsigned int i = 0; 12797 struct rte_port *port; 12798 struct port_template *pt; 12799 12800 (void)token; 12801 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12802 ctx->port == (portid_t)RTE_PORT_ALL) 12803 return -1; 12804 port = &ports[ctx->port]; 12805 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 12806 if (buf && i == ent) 12807 return snprintf(buf, size, "%u", pt->id); 12808 ++i; 12809 } 12810 if (buf) 12811 return -1; 12812 return i; 12813 } 12814 12815 /** Complete available table IDs. */ 12816 static int 12817 comp_table_id(struct context *ctx, const struct token *token, 12818 unsigned int ent, char *buf, unsigned int size) 12819 { 12820 unsigned int i = 0; 12821 struct rte_port *port; 12822 struct port_table *pt; 12823 12824 (void)token; 12825 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12826 ctx->port == (portid_t)RTE_PORT_ALL) 12827 return -1; 12828 port = &ports[ctx->port]; 12829 for (pt = port->table_list; pt != NULL; pt = pt->next) { 12830 if (buf && i == ent) 12831 return snprintf(buf, size, "%u", pt->id); 12832 ++i; 12833 } 12834 if (buf) 12835 return -1; 12836 return i; 12837 } 12838 12839 /** Complete available queue IDs. */ 12840 static int 12841 comp_queue_id(struct context *ctx, const struct token *token, 12842 unsigned int ent, char *buf, unsigned int size) 12843 { 12844 unsigned int i = 0; 12845 struct rte_port *port; 12846 12847 (void)token; 12848 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12849 ctx->port == (portid_t)RTE_PORT_ALL) 12850 return -1; 12851 port = &ports[ctx->port]; 12852 for (i = 0; i < port->queue_nb; i++) { 12853 if (buf && i == ent) 12854 return snprintf(buf, size, "%u", i); 12855 } 12856 if (buf) 12857 return -1; 12858 return i; 12859 } 12860 12861 static int 12862 comp_names_to_index(struct context *ctx, const struct token *token, 12863 unsigned int ent, char *buf, unsigned int size, 12864 const char *const names[], size_t names_size) 12865 { 12866 RTE_SET_USED(ctx); 12867 RTE_SET_USED(token); 12868 if (!buf) 12869 return names_size; 12870 if (names[ent] && ent < names_size) 12871 return rte_strscpy(buf, names[ent], size); 12872 return -1; 12873 12874 } 12875 12876 /** Complete available Meter colors. */ 12877 static int 12878 comp_meter_color(struct context *ctx, const struct token *token, 12879 unsigned int ent, char *buf, unsigned int size) 12880 { 12881 RTE_SET_USED(ctx); 12882 RTE_SET_USED(token); 12883 if (!buf) 12884 return RTE_DIM(meter_colors); 12885 if (ent < RTE_DIM(meter_colors) - 1) 12886 return strlcpy(buf, meter_colors[ent], size); 12887 return -1; 12888 } 12889 12890 /** Complete available Insertion Table types. */ 12891 static int 12892 comp_insertion_table_type(struct context *ctx, const struct token *token, 12893 unsigned int ent, char *buf, unsigned int size) 12894 { 12895 RTE_SET_USED(ctx); 12896 RTE_SET_USED(token); 12897 if (!buf) 12898 return RTE_DIM(table_insertion_types); 12899 if (ent < RTE_DIM(table_insertion_types) - 1) 12900 return rte_strscpy(buf, table_insertion_types[ent], size); 12901 return -1; 12902 } 12903 12904 /** Complete available Hash Calculation Table types. */ 12905 static int 12906 comp_hash_table_type(struct context *ctx, const struct token *token, 12907 unsigned int ent, char *buf, unsigned int size) 12908 { 12909 RTE_SET_USED(ctx); 12910 RTE_SET_USED(token); 12911 if (!buf) 12912 return RTE_DIM(table_hash_funcs); 12913 if (ent < RTE_DIM(table_hash_funcs) - 1) 12914 return rte_strscpy(buf, table_hash_funcs[ent], size); 12915 return -1; 12916 } 12917 12918 static int 12919 comp_quota_state_name(struct context *ctx, const struct token *token, 12920 unsigned int ent, char *buf, unsigned int size) 12921 { 12922 return comp_names_to_index(ctx, token, ent, buf, size, 12923 quota_state_names, 12924 RTE_DIM(quota_state_names)); 12925 } 12926 12927 static int 12928 comp_quota_mode_name(struct context *ctx, const struct token *token, 12929 unsigned int ent, char *buf, unsigned int size) 12930 { 12931 return comp_names_to_index(ctx, token, ent, buf, size, 12932 quota_mode_names, 12933 RTE_DIM(quota_mode_names)); 12934 } 12935 12936 static int 12937 comp_quota_update_name(struct context *ctx, const struct token *token, 12938 unsigned int ent, char *buf, unsigned int size) 12939 { 12940 return comp_names_to_index(ctx, token, ent, buf, size, 12941 quota_update_names, 12942 RTE_DIM(quota_update_names)); 12943 } 12944 12945 static int 12946 comp_qu_mode_name(struct context *ctx, const struct token *token, 12947 unsigned int ent, char *buf, unsigned int size) 12948 { 12949 return comp_names_to_index(ctx, token, ent, buf, size, 12950 query_update_mode_names, 12951 RTE_DIM(query_update_mode_names)); 12952 } 12953 12954 /** Internal context. */ 12955 static struct context cmd_flow_context; 12956 12957 /** Global parser instance (cmdline API). */ 12958 cmdline_parse_inst_t cmd_flow; 12959 cmdline_parse_inst_t cmd_set_raw; 12960 12961 /** Initialize context. */ 12962 static void 12963 cmd_flow_context_init(struct context *ctx) 12964 { 12965 /* A full memset() is not necessary. */ 12966 ctx->curr = ZERO; 12967 ctx->prev = ZERO; 12968 ctx->next_num = 0; 12969 ctx->args_num = 0; 12970 ctx->eol = 0; 12971 ctx->last = 0; 12972 ctx->port = 0; 12973 ctx->objdata = 0; 12974 ctx->object = NULL; 12975 ctx->objmask = NULL; 12976 } 12977 12978 /** Parse a token (cmdline API). */ 12979 static int 12980 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 12981 unsigned int size) 12982 { 12983 struct context *ctx = &cmd_flow_context; 12984 const struct token *token; 12985 const enum index *list; 12986 int len; 12987 int i; 12988 12989 (void)hdr; 12990 token = &token_list[ctx->curr]; 12991 /* Check argument length. */ 12992 ctx->eol = 0; 12993 ctx->last = 1; 12994 for (len = 0; src[len]; ++len) 12995 if (src[len] == '#' || isspace(src[len])) 12996 break; 12997 if (!len) 12998 return -1; 12999 /* Last argument and EOL detection. */ 13000 for (i = len; src[i]; ++i) 13001 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 13002 break; 13003 else if (!isspace(src[i])) { 13004 ctx->last = 0; 13005 break; 13006 } 13007 for (; src[i]; ++i) 13008 if (src[i] == '\r' || src[i] == '\n') { 13009 ctx->eol = 1; 13010 break; 13011 } 13012 /* Initialize context if necessary. */ 13013 if (!ctx->next_num) { 13014 if (!token->next) 13015 return 0; 13016 ctx->next[ctx->next_num++] = token->next[0]; 13017 } 13018 /* Process argument through candidates. */ 13019 ctx->prev = ctx->curr; 13020 list = ctx->next[ctx->next_num - 1]; 13021 for (i = 0; list[i]; ++i) { 13022 const struct token *next = &token_list[list[i]]; 13023 int tmp; 13024 13025 ctx->curr = list[i]; 13026 if (next->call) 13027 tmp = next->call(ctx, next, src, len, result, size); 13028 else 13029 tmp = parse_default(ctx, next, src, len, result, size); 13030 if (tmp == -1 || tmp != len) 13031 continue; 13032 token = next; 13033 break; 13034 } 13035 if (!list[i]) 13036 return -1; 13037 --ctx->next_num; 13038 /* Push subsequent tokens if any. */ 13039 if (token->next) 13040 for (i = 0; token->next[i]; ++i) { 13041 if (ctx->next_num == RTE_DIM(ctx->next)) 13042 return -1; 13043 ctx->next[ctx->next_num++] = token->next[i]; 13044 } 13045 /* Push arguments if any. */ 13046 if (token->args) 13047 for (i = 0; token->args[i]; ++i) { 13048 if (ctx->args_num == RTE_DIM(ctx->args)) 13049 return -1; 13050 ctx->args[ctx->args_num++] = token->args[i]; 13051 } 13052 return len; 13053 } 13054 13055 int 13056 flow_parse(const char *src, void *result, unsigned int size, 13057 struct rte_flow_attr **attr, 13058 struct rte_flow_item **pattern, struct rte_flow_action **actions) 13059 { 13060 int ret; 13061 struct context saved_flow_ctx = cmd_flow_context; 13062 13063 cmd_flow_context_init(&cmd_flow_context); 13064 do { 13065 ret = cmd_flow_parse(NULL, src, result, size); 13066 if (ret > 0) { 13067 src += ret; 13068 while (isspace(*src)) 13069 src++; 13070 } 13071 } while (ret > 0 && strlen(src)); 13072 cmd_flow_context = saved_flow_ctx; 13073 *attr = &((struct buffer *)result)->args.vc.attr; 13074 *pattern = ((struct buffer *)result)->args.vc.pattern; 13075 *actions = ((struct buffer *)result)->args.vc.actions; 13076 return (ret >= 0 && !strlen(src)) ? 0 : -1; 13077 } 13078 13079 /** Return number of completion entries (cmdline API). */ 13080 static int 13081 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 13082 { 13083 struct context *ctx = &cmd_flow_context; 13084 const struct token *token = &token_list[ctx->curr]; 13085 const enum index *list; 13086 int i; 13087 13088 (void)hdr; 13089 /* Count number of tokens in current list. */ 13090 if (ctx->next_num) 13091 list = ctx->next[ctx->next_num - 1]; 13092 else 13093 list = token->next[0]; 13094 for (i = 0; list[i]; ++i) 13095 ; 13096 if (!i) 13097 return 0; 13098 /* 13099 * If there is a single token, use its completion callback, otherwise 13100 * return the number of entries. 13101 */ 13102 token = &token_list[list[0]]; 13103 if (i == 1 && token->comp) { 13104 /* Save index for cmd_flow_get_help(). */ 13105 ctx->prev = list[0]; 13106 return token->comp(ctx, token, 0, NULL, 0); 13107 } 13108 return i; 13109 } 13110 13111 /** Return a completion entry (cmdline API). */ 13112 static int 13113 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 13114 char *dst, unsigned int size) 13115 { 13116 struct context *ctx = &cmd_flow_context; 13117 const struct token *token = &token_list[ctx->curr]; 13118 const enum index *list; 13119 int i; 13120 13121 (void)hdr; 13122 /* Count number of tokens in current list. */ 13123 if (ctx->next_num) 13124 list = ctx->next[ctx->next_num - 1]; 13125 else 13126 list = token->next[0]; 13127 for (i = 0; list[i]; ++i) 13128 ; 13129 if (!i) 13130 return -1; 13131 /* If there is a single token, use its completion callback. */ 13132 token = &token_list[list[0]]; 13133 if (i == 1 && token->comp) { 13134 /* Save index for cmd_flow_get_help(). */ 13135 ctx->prev = list[0]; 13136 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 13137 } 13138 /* Otherwise make sure the index is valid and use defaults. */ 13139 if (index >= i) 13140 return -1; 13141 token = &token_list[list[index]]; 13142 strlcpy(dst, token->name, size); 13143 /* Save index for cmd_flow_get_help(). */ 13144 ctx->prev = list[index]; 13145 return 0; 13146 } 13147 13148 /** Populate help strings for current token (cmdline API). */ 13149 static int 13150 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 13151 { 13152 struct context *ctx = &cmd_flow_context; 13153 const struct token *token = &token_list[ctx->prev]; 13154 13155 (void)hdr; 13156 if (!size) 13157 return -1; 13158 /* Set token type and update global help with details. */ 13159 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 13160 if (token->help) 13161 cmd_flow.help_str = token->help; 13162 else 13163 cmd_flow.help_str = token->name; 13164 return 0; 13165 } 13166 13167 /** Token definition template (cmdline API). */ 13168 static struct cmdline_token_hdr cmd_flow_token_hdr = { 13169 .ops = &(struct cmdline_token_ops){ 13170 .parse = cmd_flow_parse, 13171 .complete_get_nb = cmd_flow_complete_get_nb, 13172 .complete_get_elt = cmd_flow_complete_get_elt, 13173 .get_help = cmd_flow_get_help, 13174 }, 13175 .offset = 0, 13176 }; 13177 13178 /** Populate the next dynamic token. */ 13179 static void 13180 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 13181 cmdline_parse_token_hdr_t **hdr_inst) 13182 { 13183 struct context *ctx = &cmd_flow_context; 13184 13185 /* Always reinitialize context before requesting the first token. */ 13186 if (!(hdr_inst - cmd_flow.tokens)) 13187 cmd_flow_context_init(ctx); 13188 /* Return NULL when no more tokens are expected. */ 13189 if (!ctx->next_num && ctx->curr) { 13190 *hdr = NULL; 13191 return; 13192 } 13193 /* Determine if command should end here. */ 13194 if (ctx->eol && ctx->last && ctx->next_num) { 13195 const enum index *list = ctx->next[ctx->next_num - 1]; 13196 int i; 13197 13198 for (i = 0; list[i]; ++i) { 13199 if (list[i] != END) 13200 continue; 13201 *hdr = NULL; 13202 return; 13203 } 13204 } 13205 *hdr = &cmd_flow_token_hdr; 13206 } 13207 13208 static SLIST_HEAD(, indlst_conf) indlst_conf_head = 13209 SLIST_HEAD_INITIALIZER(); 13210 13211 static void 13212 indirect_action_flow_conf_create(const struct buffer *in) 13213 { 13214 int len, ret; 13215 uint32_t i; 13216 struct indlst_conf *indlst_conf = NULL; 13217 size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); 13218 struct rte_flow_action *src = in->args.vc.actions; 13219 13220 if (!in->args.vc.actions_n) 13221 goto end; 13222 len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); 13223 if (len <= 0) 13224 goto end; 13225 len = RTE_ALIGN(len, 16); 13226 13227 indlst_conf = calloc(1, base + len + 13228 in->args.vc.actions_n * sizeof(uintptr_t)); 13229 if (!indlst_conf) 13230 goto end; 13231 indlst_conf->id = in->args.vc.attr.group; 13232 indlst_conf->conf_num = in->args.vc.actions_n - 1; 13233 indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); 13234 ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, 13235 len, src, NULL); 13236 if (ret <= 0) { 13237 free(indlst_conf); 13238 indlst_conf = NULL; 13239 goto end; 13240 } 13241 indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); 13242 for (i = 0; i < indlst_conf->conf_num; i++) 13243 indlst_conf->conf[i] = indlst_conf->actions[i].conf; 13244 SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); 13245 end: 13246 if (indlst_conf) 13247 printf("created indirect action list configuration %u\n", 13248 in->args.vc.attr.group); 13249 else 13250 printf("cannot create indirect action list configuration %u\n", 13251 in->args.vc.attr.group); 13252 } 13253 13254 static const struct indlst_conf * 13255 indirect_action_list_conf_get(uint32_t conf_id) 13256 { 13257 const struct indlst_conf *conf; 13258 13259 SLIST_FOREACH(conf, &indlst_conf_head, next) { 13260 if (conf->id == conf_id) 13261 return conf; 13262 } 13263 return NULL; 13264 } 13265 13266 /** Dispatch parsed buffer to function calls. */ 13267 static void 13268 cmd_flow_parsed(const struct buffer *in) 13269 { 13270 switch (in->command) { 13271 case INFO: 13272 port_flow_get_info(in->port); 13273 break; 13274 case CONFIGURE: 13275 port_flow_configure(in->port, 13276 &in->args.configure.port_attr, 13277 in->args.configure.nb_queue, 13278 &in->args.configure.queue_attr); 13279 break; 13280 case PATTERN_TEMPLATE_CREATE: 13281 port_flow_pattern_template_create(in->port, 13282 in->args.vc.pat_templ_id, 13283 &((const struct rte_flow_pattern_template_attr) { 13284 .relaxed_matching = in->args.vc.attr.reserved, 13285 .ingress = in->args.vc.attr.ingress, 13286 .egress = in->args.vc.attr.egress, 13287 .transfer = in->args.vc.attr.transfer, 13288 }), 13289 in->args.vc.pattern); 13290 break; 13291 case PATTERN_TEMPLATE_DESTROY: 13292 port_flow_pattern_template_destroy(in->port, 13293 in->args.templ_destroy.template_id_n, 13294 in->args.templ_destroy.template_id); 13295 break; 13296 case ACTIONS_TEMPLATE_CREATE: 13297 port_flow_actions_template_create(in->port, 13298 in->args.vc.act_templ_id, 13299 &((const struct rte_flow_actions_template_attr) { 13300 .ingress = in->args.vc.attr.ingress, 13301 .egress = in->args.vc.attr.egress, 13302 .transfer = in->args.vc.attr.transfer, 13303 }), 13304 in->args.vc.actions, 13305 in->args.vc.masks); 13306 break; 13307 case ACTIONS_TEMPLATE_DESTROY: 13308 port_flow_actions_template_destroy(in->port, 13309 in->args.templ_destroy.template_id_n, 13310 in->args.templ_destroy.template_id); 13311 break; 13312 case TABLE_CREATE: 13313 port_flow_template_table_create(in->port, in->args.table.id, 13314 &in->args.table.attr, in->args.table.pat_templ_id_n, 13315 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 13316 in->args.table.act_templ_id); 13317 break; 13318 case TABLE_DESTROY: 13319 port_flow_template_table_destroy(in->port, 13320 in->args.table_destroy.table_id_n, 13321 in->args.table_destroy.table_id); 13322 break; 13323 case TABLE_RESIZE_COMPLETE: 13324 port_flow_template_table_resize_complete 13325 (in->port, in->args.table_destroy.table_id[0]); 13326 break; 13327 case GROUP_SET_MISS_ACTIONS: 13328 port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, 13329 in->args.vc.actions); 13330 break; 13331 case TABLE_RESIZE: 13332 port_flow_template_table_resize(in->port, in->args.table.id, 13333 in->args.table.attr.nb_flows); 13334 break; 13335 case QUEUE_CREATE: 13336 port_queue_flow_create(in->port, in->queue, in->postpone, 13337 in->args.vc.table_id, in->args.vc.rule_id, 13338 in->args.vc.pat_templ_id, in->args.vc.act_templ_id, 13339 in->args.vc.pattern, in->args.vc.actions); 13340 break; 13341 case QUEUE_DESTROY: 13342 port_queue_flow_destroy(in->port, in->queue, in->postpone, 13343 in->args.destroy.rule_n, 13344 in->args.destroy.rule); 13345 break; 13346 case QUEUE_FLOW_UPDATE_RESIZED: 13347 port_queue_flow_update_resized(in->port, in->queue, 13348 in->postpone, 13349 in->args.destroy.rule[0]); 13350 break; 13351 case QUEUE_UPDATE: 13352 port_queue_flow_update(in->port, in->queue, in->postpone, 13353 in->args.vc.rule_id, in->args.vc.act_templ_id, 13354 in->args.vc.actions); 13355 break; 13356 case PUSH: 13357 port_queue_flow_push(in->port, in->queue); 13358 break; 13359 case PULL: 13360 port_queue_flow_pull(in->port, in->queue); 13361 break; 13362 case HASH: 13363 if (!in->args.vc.encap_hash) 13364 port_flow_hash_calc(in->port, in->args.vc.table_id, 13365 in->args.vc.pat_templ_id, 13366 in->args.vc.pattern); 13367 else 13368 port_flow_hash_calc_encap(in->port, in->args.vc.field, 13369 in->args.vc.pattern); 13370 break; 13371 case QUEUE_AGED: 13372 port_queue_flow_aged(in->port, in->queue, 13373 in->args.aged.destroy); 13374 break; 13375 case QUEUE_INDIRECT_ACTION_CREATE: 13376 case QUEUE_INDIRECT_ACTION_LIST_CREATE: 13377 port_queue_action_handle_create( 13378 in->port, in->queue, in->postpone, 13379 in->args.vc.attr.group, 13380 in->command == QUEUE_INDIRECT_ACTION_LIST_CREATE, 13381 &((const struct rte_flow_indir_action_conf) { 13382 .ingress = in->args.vc.attr.ingress, 13383 .egress = in->args.vc.attr.egress, 13384 .transfer = in->args.vc.attr.transfer, 13385 }), 13386 in->args.vc.actions); 13387 break; 13388 case QUEUE_INDIRECT_ACTION_DESTROY: 13389 port_queue_action_handle_destroy(in->port, 13390 in->queue, in->postpone, 13391 in->args.ia_destroy.action_id_n, 13392 in->args.ia_destroy.action_id); 13393 break; 13394 case QUEUE_INDIRECT_ACTION_UPDATE: 13395 port_queue_action_handle_update(in->port, 13396 in->queue, in->postpone, 13397 in->args.vc.attr.group, 13398 in->args.vc.actions); 13399 break; 13400 case QUEUE_INDIRECT_ACTION_QUERY: 13401 port_queue_action_handle_query(in->port, 13402 in->queue, in->postpone, 13403 in->args.ia.action_id); 13404 break; 13405 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 13406 port_queue_action_handle_query_update(in->port, in->queue, 13407 in->postpone, 13408 in->args.ia.action_id, 13409 in->args.ia.qu_mode, 13410 in->args.vc.actions); 13411 break; 13412 case INDIRECT_ACTION_CREATE: 13413 case INDIRECT_ACTION_LIST_CREATE: 13414 port_action_handle_create( 13415 in->port, in->args.vc.attr.group, 13416 in->command == INDIRECT_ACTION_LIST_CREATE, 13417 &((const struct rte_flow_indir_action_conf) { 13418 .ingress = in->args.vc.attr.ingress, 13419 .egress = in->args.vc.attr.egress, 13420 .transfer = in->args.vc.attr.transfer, 13421 }), 13422 in->args.vc.actions); 13423 break; 13424 case INDIRECT_ACTION_FLOW_CONF_CREATE: 13425 indirect_action_flow_conf_create(in); 13426 break; 13427 case INDIRECT_ACTION_DESTROY: 13428 port_action_handle_destroy(in->port, 13429 in->args.ia_destroy.action_id_n, 13430 in->args.ia_destroy.action_id); 13431 break; 13432 case INDIRECT_ACTION_UPDATE: 13433 port_action_handle_update(in->port, in->args.vc.attr.group, 13434 in->args.vc.actions); 13435 break; 13436 case INDIRECT_ACTION_QUERY: 13437 port_action_handle_query(in->port, in->args.ia.action_id); 13438 break; 13439 case INDIRECT_ACTION_QUERY_UPDATE: 13440 port_action_handle_query_update(in->port, 13441 in->args.ia.action_id, 13442 in->args.ia.qu_mode, 13443 in->args.vc.actions); 13444 break; 13445 case VALIDATE: 13446 port_flow_validate(in->port, &in->args.vc.attr, 13447 in->args.vc.pattern, in->args.vc.actions, 13448 &in->args.vc.tunnel_ops); 13449 break; 13450 case CREATE: 13451 port_flow_create(in->port, &in->args.vc.attr, 13452 in->args.vc.pattern, in->args.vc.actions, 13453 &in->args.vc.tunnel_ops, in->args.vc.user_id); 13454 break; 13455 case DESTROY: 13456 port_flow_destroy(in->port, in->args.destroy.rule_n, 13457 in->args.destroy.rule, 13458 in->args.destroy.is_user_id); 13459 break; 13460 case UPDATE: 13461 port_flow_update(in->port, in->args.vc.rule_id, 13462 in->args.vc.actions, in->args.vc.user_id); 13463 break; 13464 case FLUSH: 13465 port_flow_flush(in->port); 13466 break; 13467 case DUMP_ONE: 13468 case DUMP_ALL: 13469 port_flow_dump(in->port, in->args.dump.mode, 13470 in->args.dump.rule, in->args.dump.file, 13471 in->args.dump.is_user_id); 13472 break; 13473 case QUERY: 13474 port_flow_query(in->port, in->args.query.rule, 13475 &in->args.query.action, 13476 in->args.query.is_user_id); 13477 break; 13478 case LIST: 13479 port_flow_list(in->port, in->args.list.group_n, 13480 in->args.list.group); 13481 break; 13482 case ISOLATE: 13483 port_flow_isolate(in->port, in->args.isolate.set); 13484 break; 13485 case AGED: 13486 port_flow_aged(in->port, in->args.aged.destroy); 13487 break; 13488 case TUNNEL_CREATE: 13489 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 13490 break; 13491 case TUNNEL_DESTROY: 13492 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 13493 break; 13494 case TUNNEL_LIST: 13495 port_flow_tunnel_list(in->port); 13496 break; 13497 case ACTION_POL_G: 13498 port_meter_policy_add(in->port, in->args.policy.policy_id, 13499 in->args.vc.actions); 13500 break; 13501 case FLEX_ITEM_CREATE: 13502 flex_item_create(in->port, in->args.flex.token, 13503 in->args.flex.filename); 13504 break; 13505 case FLEX_ITEM_DESTROY: 13506 flex_item_destroy(in->port, in->args.flex.token); 13507 break; 13508 default: 13509 break; 13510 } 13511 fflush(stdout); 13512 } 13513 13514 /** Token generator and output processing callback (cmdline API). */ 13515 static void 13516 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 13517 { 13518 if (cl == NULL) 13519 cmd_flow_tok(arg0, arg2); 13520 else 13521 cmd_flow_parsed(arg0); 13522 } 13523 13524 /** Global parser instance (cmdline API). */ 13525 cmdline_parse_inst_t cmd_flow = { 13526 .f = cmd_flow_cb, 13527 .data = NULL, /**< Unused. */ 13528 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 13529 .tokens = { 13530 NULL, 13531 }, /**< Tokens are returned by cmd_flow_tok(). */ 13532 }; 13533 13534 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 13535 13536 static void 13537 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 13538 { 13539 struct rte_ipv4_hdr *ipv4; 13540 struct rte_ether_hdr *eth; 13541 struct rte_ipv6_hdr *ipv6; 13542 struct rte_vxlan_hdr *vxlan; 13543 struct rte_vxlan_gpe_hdr *gpe; 13544 struct rte_flow_item_nvgre *nvgre; 13545 uint32_t ipv6_vtc_flow; 13546 13547 switch (item->type) { 13548 case RTE_FLOW_ITEM_TYPE_ETH: 13549 eth = (struct rte_ether_hdr *)buf; 13550 if (next_proto) 13551 eth->ether_type = rte_cpu_to_be_16(next_proto); 13552 break; 13553 case RTE_FLOW_ITEM_TYPE_IPV4: 13554 ipv4 = (struct rte_ipv4_hdr *)buf; 13555 if (!ipv4->version_ihl) 13556 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 13557 if (next_proto && ipv4->next_proto_id == 0) 13558 ipv4->next_proto_id = (uint8_t)next_proto; 13559 break; 13560 case RTE_FLOW_ITEM_TYPE_IPV6: 13561 ipv6 = (struct rte_ipv6_hdr *)buf; 13562 if (next_proto && ipv6->proto == 0) 13563 ipv6->proto = (uint8_t)next_proto; 13564 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 13565 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 13566 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 13567 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 13568 break; 13569 case RTE_FLOW_ITEM_TYPE_VXLAN: 13570 vxlan = (struct rte_vxlan_hdr *)buf; 13571 vxlan->vx_flags = 0x08; 13572 break; 13573 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13574 gpe = (struct rte_vxlan_gpe_hdr *)buf; 13575 gpe->vx_flags = 0x0C; 13576 break; 13577 case RTE_FLOW_ITEM_TYPE_NVGRE: 13578 nvgre = (struct rte_flow_item_nvgre *)buf; 13579 nvgre->protocol = rte_cpu_to_be_16(0x6558); 13580 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 13581 break; 13582 default: 13583 break; 13584 } 13585 } 13586 13587 /** Helper of get item's default mask. */ 13588 static const void * 13589 flow_item_default_mask(const struct rte_flow_item *item) 13590 { 13591 const void *mask = NULL; 13592 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 13593 static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { 13594 .hdr = { 13595 .next_hdr = 0xff, 13596 .type = 0xff, 13597 .segments_left = 0xff, 13598 }, 13599 }; 13600 13601 switch (item->type) { 13602 case RTE_FLOW_ITEM_TYPE_ANY: 13603 mask = &rte_flow_item_any_mask; 13604 break; 13605 case RTE_FLOW_ITEM_TYPE_PORT_ID: 13606 mask = &rte_flow_item_port_id_mask; 13607 break; 13608 case RTE_FLOW_ITEM_TYPE_RAW: 13609 mask = &rte_flow_item_raw_mask; 13610 break; 13611 case RTE_FLOW_ITEM_TYPE_ETH: 13612 mask = &rte_flow_item_eth_mask; 13613 break; 13614 case RTE_FLOW_ITEM_TYPE_VLAN: 13615 mask = &rte_flow_item_vlan_mask; 13616 break; 13617 case RTE_FLOW_ITEM_TYPE_IPV4: 13618 mask = &rte_flow_item_ipv4_mask; 13619 break; 13620 case RTE_FLOW_ITEM_TYPE_IPV6: 13621 mask = &rte_flow_item_ipv6_mask; 13622 break; 13623 case RTE_FLOW_ITEM_TYPE_ICMP: 13624 mask = &rte_flow_item_icmp_mask; 13625 break; 13626 case RTE_FLOW_ITEM_TYPE_UDP: 13627 mask = &rte_flow_item_udp_mask; 13628 break; 13629 case RTE_FLOW_ITEM_TYPE_TCP: 13630 mask = &rte_flow_item_tcp_mask; 13631 break; 13632 case RTE_FLOW_ITEM_TYPE_SCTP: 13633 mask = &rte_flow_item_sctp_mask; 13634 break; 13635 case RTE_FLOW_ITEM_TYPE_VXLAN: 13636 mask = &rte_flow_item_vxlan_mask; 13637 break; 13638 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13639 mask = &rte_flow_item_vxlan_gpe_mask; 13640 break; 13641 case RTE_FLOW_ITEM_TYPE_E_TAG: 13642 mask = &rte_flow_item_e_tag_mask; 13643 break; 13644 case RTE_FLOW_ITEM_TYPE_NVGRE: 13645 mask = &rte_flow_item_nvgre_mask; 13646 break; 13647 case RTE_FLOW_ITEM_TYPE_MPLS: 13648 mask = &rte_flow_item_mpls_mask; 13649 break; 13650 case RTE_FLOW_ITEM_TYPE_GRE: 13651 mask = &rte_flow_item_gre_mask; 13652 break; 13653 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13654 mask = &gre_key_default_mask; 13655 break; 13656 case RTE_FLOW_ITEM_TYPE_META: 13657 mask = &rte_flow_item_meta_mask; 13658 break; 13659 case RTE_FLOW_ITEM_TYPE_RANDOM: 13660 mask = &rte_flow_item_random_mask; 13661 break; 13662 case RTE_FLOW_ITEM_TYPE_FUZZY: 13663 mask = &rte_flow_item_fuzzy_mask; 13664 break; 13665 case RTE_FLOW_ITEM_TYPE_GTP: 13666 mask = &rte_flow_item_gtp_mask; 13667 break; 13668 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13669 mask = &rte_flow_item_gtp_psc_mask; 13670 break; 13671 case RTE_FLOW_ITEM_TYPE_GENEVE: 13672 mask = &rte_flow_item_geneve_mask; 13673 break; 13674 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13675 mask = &rte_flow_item_geneve_opt_mask; 13676 break; 13677 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 13678 mask = &rte_flow_item_pppoe_proto_id_mask; 13679 break; 13680 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13681 mask = &rte_flow_item_l2tpv3oip_mask; 13682 break; 13683 case RTE_FLOW_ITEM_TYPE_ESP: 13684 mask = &rte_flow_item_esp_mask; 13685 break; 13686 case RTE_FLOW_ITEM_TYPE_AH: 13687 mask = &rte_flow_item_ah_mask; 13688 break; 13689 case RTE_FLOW_ITEM_TYPE_PFCP: 13690 mask = &rte_flow_item_pfcp_mask; 13691 break; 13692 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 13693 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 13694 mask = &rte_flow_item_ethdev_mask; 13695 break; 13696 case RTE_FLOW_ITEM_TYPE_L2TPV2: 13697 mask = &rte_flow_item_l2tpv2_mask; 13698 break; 13699 case RTE_FLOW_ITEM_TYPE_PPP: 13700 mask = &rte_flow_item_ppp_mask; 13701 break; 13702 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 13703 mask = &rte_flow_item_meter_color_mask; 13704 break; 13705 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13706 mask = &ipv6_routing_ext_default_mask; 13707 break; 13708 case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: 13709 mask = &rte_flow_item_aggr_affinity_mask; 13710 break; 13711 case RTE_FLOW_ITEM_TYPE_TX_QUEUE: 13712 mask = &rte_flow_item_tx_queue_mask; 13713 break; 13714 case RTE_FLOW_ITEM_TYPE_IB_BTH: 13715 mask = &rte_flow_item_ib_bth_mask; 13716 break; 13717 case RTE_FLOW_ITEM_TYPE_PTYPE: 13718 mask = &rte_flow_item_ptype_mask; 13719 break; 13720 default: 13721 break; 13722 } 13723 return mask; 13724 } 13725 13726 /** Dispatch parsed buffer to function calls. */ 13727 static void 13728 cmd_set_ipv6_ext_parsed(const struct buffer *in) 13729 { 13730 uint32_t n = in->args.vc.pattern_n; 13731 int i = 0; 13732 struct rte_flow_item *item = NULL; 13733 size_t size = 0; 13734 uint8_t *data = NULL; 13735 uint8_t *type = NULL; 13736 size_t *total_size = NULL; 13737 uint16_t idx = in->port; /* We borrow port field as index */ 13738 struct rte_flow_item_ipv6_routing_ext *ext; 13739 const struct rte_flow_item_ipv6_ext *ipv6_ext; 13740 13741 RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || 13742 in->command == SET_IPV6_EXT_REMOVE); 13743 13744 if (in->command == SET_IPV6_EXT_REMOVE) { 13745 if (n != 1 || in->args.vc.pattern->type != 13746 RTE_FLOW_ITEM_TYPE_IPV6_EXT) { 13747 fprintf(stderr, "Error - Not supported item\n"); 13748 return; 13749 } 13750 type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; 13751 item = in->args.vc.pattern; 13752 ipv6_ext = item->spec; 13753 *type = ipv6_ext->next_hdr; 13754 return; 13755 } 13756 13757 total_size = &ipv6_ext_push_confs[idx].size; 13758 data = (uint8_t *)&ipv6_ext_push_confs[idx].data; 13759 type = (uint8_t *)&ipv6_ext_push_confs[idx].type; 13760 13761 *total_size = 0; 13762 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13763 for (i = n - 1 ; i >= 0; --i) { 13764 item = in->args.vc.pattern + i; 13765 switch (item->type) { 13766 case RTE_FLOW_ITEM_TYPE_IPV6_EXT: 13767 ipv6_ext = item->spec; 13768 *type = ipv6_ext->next_hdr; 13769 break; 13770 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13771 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13772 if (!ext->hdr.hdr_len) { 13773 size = sizeof(struct rte_ipv6_routing_ext) + 13774 (ext->hdr.segments_left << 4); 13775 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13776 /* Indicate no TLV once SRH. */ 13777 if (ext->hdr.type == 4) 13778 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13779 } else { 13780 size = sizeof(struct rte_ipv6_routing_ext) + 13781 (ext->hdr.hdr_len << 3); 13782 } 13783 *total_size += size; 13784 memcpy(data, ext, size); 13785 break; 13786 default: 13787 fprintf(stderr, "Error - Not supported item\n"); 13788 goto error; 13789 } 13790 } 13791 RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); 13792 return; 13793 error: 13794 *total_size = 0; 13795 memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); 13796 } 13797 13798 /** Dispatch parsed buffer to function calls. */ 13799 static void 13800 cmd_set_raw_parsed_sample(const struct buffer *in) 13801 { 13802 uint32_t n = in->args.vc.actions_n; 13803 uint32_t i = 0; 13804 struct rte_flow_action *action = NULL; 13805 struct rte_flow_action *data = NULL; 13806 const struct rte_flow_action_rss *rss = NULL; 13807 size_t size = 0; 13808 uint16_t idx = in->port; /* We borrow port field as index */ 13809 uint32_t max_size = sizeof(struct rte_flow_action) * 13810 ACTION_SAMPLE_ACTIONS_NUM; 13811 13812 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 13813 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 13814 memset(data, 0x00, max_size); 13815 for (; i <= n - 1; i++) { 13816 action = in->args.vc.actions + i; 13817 if (action->type == RTE_FLOW_ACTION_TYPE_END) 13818 break; 13819 switch (action->type) { 13820 case RTE_FLOW_ACTION_TYPE_MARK: 13821 size = sizeof(struct rte_flow_action_mark); 13822 rte_memcpy(&sample_mark[idx], 13823 (const void *)action->conf, size); 13824 action->conf = &sample_mark[idx]; 13825 break; 13826 case RTE_FLOW_ACTION_TYPE_COUNT: 13827 size = sizeof(struct rte_flow_action_count); 13828 rte_memcpy(&sample_count[idx], 13829 (const void *)action->conf, size); 13830 action->conf = &sample_count[idx]; 13831 break; 13832 case RTE_FLOW_ACTION_TYPE_QUEUE: 13833 size = sizeof(struct rte_flow_action_queue); 13834 rte_memcpy(&sample_queue[idx], 13835 (const void *)action->conf, size); 13836 action->conf = &sample_queue[idx]; 13837 break; 13838 case RTE_FLOW_ACTION_TYPE_RSS: 13839 size = sizeof(struct rte_flow_action_rss); 13840 rss = action->conf; 13841 rte_memcpy(&sample_rss_data[idx].conf, 13842 (const void *)rss, size); 13843 if (rss->key_len && rss->key) { 13844 sample_rss_data[idx].conf.key = 13845 sample_rss_data[idx].key; 13846 rte_memcpy((void *)((uintptr_t) 13847 sample_rss_data[idx].conf.key), 13848 (const void *)rss->key, 13849 sizeof(uint8_t) * rss->key_len); 13850 } 13851 if (rss->queue_num && rss->queue) { 13852 sample_rss_data[idx].conf.queue = 13853 sample_rss_data[idx].queue; 13854 rte_memcpy((void *)((uintptr_t) 13855 sample_rss_data[idx].conf.queue), 13856 (const void *)rss->queue, 13857 sizeof(uint16_t) * rss->queue_num); 13858 } 13859 action->conf = &sample_rss_data[idx].conf; 13860 break; 13861 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 13862 size = sizeof(struct rte_flow_action_raw_encap); 13863 rte_memcpy(&sample_encap[idx], 13864 (const void *)action->conf, size); 13865 action->conf = &sample_encap[idx]; 13866 break; 13867 case RTE_FLOW_ACTION_TYPE_PORT_ID: 13868 size = sizeof(struct rte_flow_action_port_id); 13869 rte_memcpy(&sample_port_id[idx], 13870 (const void *)action->conf, size); 13871 action->conf = &sample_port_id[idx]; 13872 break; 13873 case RTE_FLOW_ACTION_TYPE_PF: 13874 break; 13875 case RTE_FLOW_ACTION_TYPE_VF: 13876 size = sizeof(struct rte_flow_action_vf); 13877 rte_memcpy(&sample_vf[idx], 13878 (const void *)action->conf, size); 13879 action->conf = &sample_vf[idx]; 13880 break; 13881 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 13882 size = sizeof(struct rte_flow_action_vxlan_encap); 13883 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 13884 action->conf = &sample_vxlan_encap[idx].conf; 13885 break; 13886 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 13887 size = sizeof(struct rte_flow_action_nvgre_encap); 13888 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 13889 action->conf = &sample_nvgre_encap[idx]; 13890 break; 13891 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 13892 size = sizeof(struct rte_flow_action_ethdev); 13893 rte_memcpy(&sample_port_representor[idx], 13894 (const void *)action->conf, size); 13895 action->conf = &sample_port_representor[idx]; 13896 break; 13897 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 13898 size = sizeof(struct rte_flow_action_ethdev); 13899 rte_memcpy(&sample_represented_port[idx], 13900 (const void *)action->conf, size); 13901 action->conf = &sample_represented_port[idx]; 13902 break; 13903 default: 13904 fprintf(stderr, "Error - Not supported action\n"); 13905 return; 13906 } 13907 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 13908 data++; 13909 } 13910 } 13911 13912 /** Dispatch parsed buffer to function calls. */ 13913 static void 13914 cmd_set_raw_parsed(const struct buffer *in) 13915 { 13916 uint32_t n = in->args.vc.pattern_n; 13917 int i = 0; 13918 struct rte_flow_item *item = NULL; 13919 size_t size = 0; 13920 uint8_t *data = NULL; 13921 uint8_t *data_tail = NULL; 13922 size_t *total_size = NULL; 13923 uint16_t upper_layer = 0; 13924 uint16_t proto = 0; 13925 uint16_t idx = in->port; /* We borrow port field as index */ 13926 int gtp_psc = -1; /* GTP PSC option index. */ 13927 const void *src_spec; 13928 13929 if (in->command == SET_SAMPLE_ACTIONS) 13930 return cmd_set_raw_parsed_sample(in); 13931 else if (in->command == SET_IPV6_EXT_PUSH || 13932 in->command == SET_IPV6_EXT_REMOVE) 13933 return cmd_set_ipv6_ext_parsed(in); 13934 RTE_ASSERT(in->command == SET_RAW_ENCAP || 13935 in->command == SET_RAW_DECAP); 13936 if (in->command == SET_RAW_ENCAP) { 13937 total_size = &raw_encap_confs[idx].size; 13938 data = (uint8_t *)&raw_encap_confs[idx].data; 13939 } else { 13940 total_size = &raw_decap_confs[idx].size; 13941 data = (uint8_t *)&raw_decap_confs[idx].data; 13942 } 13943 *total_size = 0; 13944 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13945 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 13946 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 13947 for (i = n - 1 ; i >= 0; --i) { 13948 const struct rte_flow_item_gtp *gtp; 13949 const struct rte_flow_item_geneve_opt *opt; 13950 struct rte_flow_item_ipv6_routing_ext *ext; 13951 13952 item = in->args.vc.pattern + i; 13953 if (item->spec == NULL) 13954 item->spec = flow_item_default_mask(item); 13955 src_spec = item->spec; 13956 switch (item->type) { 13957 case RTE_FLOW_ITEM_TYPE_ETH: 13958 size = sizeof(struct rte_ether_hdr); 13959 break; 13960 case RTE_FLOW_ITEM_TYPE_VLAN: 13961 size = sizeof(struct rte_vlan_hdr); 13962 proto = RTE_ETHER_TYPE_VLAN; 13963 break; 13964 case RTE_FLOW_ITEM_TYPE_IPV4: 13965 size = sizeof(struct rte_ipv4_hdr); 13966 proto = RTE_ETHER_TYPE_IPV4; 13967 break; 13968 case RTE_FLOW_ITEM_TYPE_IPV6: 13969 size = sizeof(struct rte_ipv6_hdr); 13970 proto = RTE_ETHER_TYPE_IPV6; 13971 break; 13972 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13973 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13974 if (!ext->hdr.hdr_len) { 13975 size = sizeof(struct rte_ipv6_routing_ext) + 13976 (ext->hdr.segments_left << 4); 13977 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13978 /* SRv6 without TLV. */ 13979 if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) 13980 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13981 } else { 13982 size = sizeof(struct rte_ipv6_routing_ext) + 13983 (ext->hdr.hdr_len << 3); 13984 } 13985 proto = IPPROTO_ROUTING; 13986 break; 13987 case RTE_FLOW_ITEM_TYPE_UDP: 13988 size = sizeof(struct rte_udp_hdr); 13989 proto = 0x11; 13990 break; 13991 case RTE_FLOW_ITEM_TYPE_TCP: 13992 size = sizeof(struct rte_tcp_hdr); 13993 proto = 0x06; 13994 break; 13995 case RTE_FLOW_ITEM_TYPE_VXLAN: 13996 size = sizeof(struct rte_vxlan_hdr); 13997 break; 13998 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13999 size = sizeof(struct rte_vxlan_gpe_hdr); 14000 break; 14001 case RTE_FLOW_ITEM_TYPE_GRE: 14002 size = sizeof(struct rte_gre_hdr); 14003 proto = 0x2F; 14004 break; 14005 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 14006 size = sizeof(rte_be32_t); 14007 proto = 0x0; 14008 break; 14009 case RTE_FLOW_ITEM_TYPE_MPLS: 14010 size = sizeof(struct rte_mpls_hdr); 14011 proto = 0x0; 14012 break; 14013 case RTE_FLOW_ITEM_TYPE_NVGRE: 14014 size = sizeof(struct rte_flow_item_nvgre); 14015 proto = 0x2F; 14016 break; 14017 case RTE_FLOW_ITEM_TYPE_GENEVE: 14018 size = sizeof(struct rte_geneve_hdr); 14019 break; 14020 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 14021 opt = (const struct rte_flow_item_geneve_opt *) 14022 item->spec; 14023 size = offsetof(struct rte_flow_item_geneve_opt, 14024 option_len) + sizeof(uint8_t); 14025 if (opt->option_len && opt->data) { 14026 *total_size += opt->option_len * 14027 sizeof(uint32_t); 14028 rte_memcpy(data_tail - (*total_size), 14029 opt->data, 14030 opt->option_len * sizeof(uint32_t)); 14031 } 14032 break; 14033 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 14034 size = sizeof(rte_be32_t); 14035 proto = 0x73; 14036 break; 14037 case RTE_FLOW_ITEM_TYPE_ESP: 14038 size = sizeof(struct rte_esp_hdr); 14039 proto = 0x32; 14040 break; 14041 case RTE_FLOW_ITEM_TYPE_AH: 14042 size = sizeof(struct rte_flow_item_ah); 14043 proto = 0x33; 14044 break; 14045 case RTE_FLOW_ITEM_TYPE_GTP: 14046 if (gtp_psc < 0) { 14047 size = sizeof(struct rte_gtp_hdr); 14048 break; 14049 } 14050 if (gtp_psc != i + 1) { 14051 fprintf(stderr, 14052 "Error - GTP PSC does not follow GTP\n"); 14053 goto error; 14054 } 14055 gtp = item->spec; 14056 if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { 14057 /* Only E flag should be set. */ 14058 fprintf(stderr, 14059 "Error - GTP unsupported flags\n"); 14060 goto error; 14061 } else { 14062 struct rte_gtp_hdr_ext_word ext_word = { 14063 .next_ext = 0x85 14064 }; 14065 14066 /* We have to add GTP header extra word. */ 14067 *total_size += sizeof(ext_word); 14068 rte_memcpy(data_tail - (*total_size), 14069 &ext_word, sizeof(ext_word)); 14070 } 14071 size = sizeof(struct rte_gtp_hdr); 14072 break; 14073 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 14074 if (gtp_psc >= 0) { 14075 fprintf(stderr, 14076 "Error - Multiple GTP PSC items\n"); 14077 goto error; 14078 } else { 14079 const struct rte_flow_item_gtp_psc 14080 *opt = item->spec; 14081 struct rte_gtp_psc_generic_hdr *hdr; 14082 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 14083 sizeof(int32_t)); 14084 14085 *total_size += hdr_size; 14086 hdr = (typeof(hdr))(data_tail - (*total_size)); 14087 memset(hdr, 0, hdr_size); 14088 *hdr = opt->hdr; 14089 hdr->ext_hdr_len = 1; 14090 gtp_psc = i; 14091 size = 0; 14092 } 14093 break; 14094 case RTE_FLOW_ITEM_TYPE_PFCP: 14095 size = sizeof(struct rte_flow_item_pfcp); 14096 break; 14097 case RTE_FLOW_ITEM_TYPE_FLEX: 14098 if (item->spec != NULL) { 14099 size = ((const struct rte_flow_item_flex *)item->spec)->length; 14100 src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; 14101 } else { 14102 size = 0; 14103 src_spec = NULL; 14104 } 14105 break; 14106 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 14107 size = 0; 14108 if (item->spec) { 14109 const struct rte_flow_item_gre_opt 14110 *opt = item->spec; 14111 if (opt->checksum_rsvd.checksum) { 14112 *total_size += 14113 sizeof(opt->checksum_rsvd); 14114 rte_memcpy(data_tail - (*total_size), 14115 &opt->checksum_rsvd, 14116 sizeof(opt->checksum_rsvd)); 14117 } 14118 if (opt->key.key) { 14119 *total_size += sizeof(opt->key.key); 14120 rte_memcpy(data_tail - (*total_size), 14121 &opt->key.key, 14122 sizeof(opt->key.key)); 14123 } 14124 if (opt->sequence.sequence) { 14125 *total_size += sizeof(opt->sequence.sequence); 14126 rte_memcpy(data_tail - (*total_size), 14127 &opt->sequence.sequence, 14128 sizeof(opt->sequence.sequence)); 14129 } 14130 } 14131 proto = 0x2F; 14132 break; 14133 default: 14134 fprintf(stderr, "Error - Not supported item\n"); 14135 goto error; 14136 } 14137 if (size) { 14138 *total_size += size; 14139 rte_memcpy(data_tail - (*total_size), src_spec, size); 14140 /* update some fields which cannot be set by cmdline */ 14141 update_fields((data_tail - (*total_size)), item, 14142 upper_layer); 14143 upper_layer = proto; 14144 } 14145 } 14146 if (verbose_level & 0x1) 14147 printf("total data size is %zu\n", (*total_size)); 14148 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 14149 memmove(data, (data_tail - (*total_size)), *total_size); 14150 return; 14151 14152 error: 14153 *total_size = 0; 14154 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 14155 } 14156 14157 /** Populate help strings for current token (cmdline API). */ 14158 static int 14159 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 14160 unsigned int size) 14161 { 14162 struct context *ctx = &cmd_flow_context; 14163 const struct token *token = &token_list[ctx->prev]; 14164 14165 (void)hdr; 14166 if (!size) 14167 return -1; 14168 /* Set token type and update global help with details. */ 14169 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 14170 if (token->help) 14171 cmd_set_raw.help_str = token->help; 14172 else 14173 cmd_set_raw.help_str = token->name; 14174 return 0; 14175 } 14176 14177 /** Token definition template (cmdline API). */ 14178 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 14179 .ops = &(struct cmdline_token_ops){ 14180 .parse = cmd_flow_parse, 14181 .complete_get_nb = cmd_flow_complete_get_nb, 14182 .complete_get_elt = cmd_flow_complete_get_elt, 14183 .get_help = cmd_set_raw_get_help, 14184 }, 14185 .offset = 0, 14186 }; 14187 14188 /** Populate the next dynamic token. */ 14189 static void 14190 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 14191 cmdline_parse_token_hdr_t **hdr_inst) 14192 { 14193 struct context *ctx = &cmd_flow_context; 14194 14195 /* Always reinitialize context before requesting the first token. */ 14196 if (!(hdr_inst - cmd_set_raw.tokens)) { 14197 cmd_flow_context_init(ctx); 14198 ctx->curr = START_SET; 14199 } 14200 /* Return NULL when no more tokens are expected. */ 14201 if (!ctx->next_num && (ctx->curr != START_SET)) { 14202 *hdr = NULL; 14203 return; 14204 } 14205 /* Determine if command should end here. */ 14206 if (ctx->eol && ctx->last && ctx->next_num) { 14207 const enum index *list = ctx->next[ctx->next_num - 1]; 14208 int i; 14209 14210 for (i = 0; list[i]; ++i) { 14211 if (list[i] != END) 14212 continue; 14213 *hdr = NULL; 14214 return; 14215 } 14216 } 14217 *hdr = &cmd_set_raw_token_hdr; 14218 } 14219 14220 /** Token generator and output processing callback (cmdline API). */ 14221 static void 14222 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 14223 { 14224 if (cl == NULL) 14225 cmd_set_raw_tok(arg0, arg2); 14226 else 14227 cmd_set_raw_parsed(arg0); 14228 } 14229 14230 /** Global parser instance (cmdline API). */ 14231 cmdline_parse_inst_t cmd_set_raw = { 14232 .f = cmd_set_raw_cb, 14233 .data = NULL, /**< Unused. */ 14234 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 14235 .tokens = { 14236 NULL, 14237 }, /**< Tokens are returned by cmd_flow_tok(). */ 14238 }; 14239 14240 /* *** display raw_encap/raw_decap buf */ 14241 struct cmd_show_set_raw_result { 14242 cmdline_fixed_string_t cmd_show; 14243 cmdline_fixed_string_t cmd_what; 14244 cmdline_fixed_string_t cmd_all; 14245 uint16_t cmd_index; 14246 }; 14247 14248 static void 14249 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 14250 { 14251 struct cmd_show_set_raw_result *res = parsed_result; 14252 uint16_t index = res->cmd_index; 14253 uint8_t all = 0; 14254 uint8_t *raw_data = NULL; 14255 size_t raw_size = 0; 14256 char title[16] = {0}; 14257 14258 RTE_SET_USED(cl); 14259 RTE_SET_USED(data); 14260 if (!strcmp(res->cmd_all, "all")) { 14261 all = 1; 14262 index = 0; 14263 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 14264 fprintf(stderr, "index should be 0-%u\n", 14265 RAW_ENCAP_CONFS_MAX_NUM - 1); 14266 return; 14267 } 14268 do { 14269 if (!strcmp(res->cmd_what, "raw_encap")) { 14270 raw_data = (uint8_t *)&raw_encap_confs[index].data; 14271 raw_size = raw_encap_confs[index].size; 14272 snprintf(title, 16, "\nindex: %u", index); 14273 rte_hexdump(stdout, title, raw_data, raw_size); 14274 } else { 14275 raw_data = (uint8_t *)&raw_decap_confs[index].data; 14276 raw_size = raw_decap_confs[index].size; 14277 snprintf(title, 16, "\nindex: %u", index); 14278 rte_hexdump(stdout, title, raw_data, raw_size); 14279 } 14280 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 14281 } 14282 14283 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 14284 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14285 cmd_show, "show"); 14286 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 14287 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14288 cmd_what, "raw_encap#raw_decap"); 14289 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 14290 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 14291 cmd_index, RTE_UINT16); 14292 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 14293 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14294 cmd_all, "all"); 14295 cmdline_parse_inst_t cmd_show_set_raw = { 14296 .f = cmd_show_set_raw_parsed, 14297 .data = NULL, 14298 .help_str = "show <raw_encap|raw_decap> <index>", 14299 .tokens = { 14300 (void *)&cmd_show_set_raw_cmd_show, 14301 (void *)&cmd_show_set_raw_cmd_what, 14302 (void *)&cmd_show_set_raw_cmd_index, 14303 NULL, 14304 }, 14305 }; 14306 cmdline_parse_inst_t cmd_show_set_raw_all = { 14307 .f = cmd_show_set_raw_parsed, 14308 .data = NULL, 14309 .help_str = "show <raw_encap|raw_decap> all", 14310 .tokens = { 14311 (void *)&cmd_show_set_raw_cmd_show, 14312 (void *)&cmd_show_set_raw_cmd_what, 14313 (void *)&cmd_show_set_raw_cmd_all, 14314 NULL, 14315 }, 14316 }; 14317