1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2016 6WIND S.A. 3 * Copyright 2016 Mellanox Technologies, Ltd 4 */ 5 6 #include <stddef.h> 7 #include <stdint.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <inttypes.h> 11 #include <errno.h> 12 #include <ctype.h> 13 #include <string.h> 14 15 #include <rte_string_fns.h> 16 #include <rte_common.h> 17 #include <rte_ethdev.h> 18 #include <rte_byteorder.h> 19 #include <cmdline_parse.h> 20 #include <cmdline_parse_etheraddr.h> 21 #include <cmdline_parse_string.h> 22 #include <cmdline_parse_num.h> 23 #include <rte_flow.h> 24 #include <rte_hexdump.h> 25 #include <rte_vxlan.h> 26 #include <rte_gre.h> 27 #include <rte_mpls.h> 28 #include <rte_gtp.h> 29 #include <rte_geneve.h> 30 31 #include "testpmd.h" 32 33 /** Parser token indices. */ 34 enum index { 35 /* Special tokens. */ 36 ZERO = 0, 37 END, 38 START_SET, 39 END_SET, 40 41 /* Common tokens. */ 42 COMMON_INTEGER, 43 COMMON_UNSIGNED, 44 COMMON_PREFIX, 45 COMMON_BOOLEAN, 46 COMMON_STRING, 47 COMMON_HEX, 48 COMMON_FILE_PATH, 49 COMMON_MAC_ADDR, 50 COMMON_IPV4_ADDR, 51 COMMON_IPV6_ADDR, 52 COMMON_RULE_ID, 53 COMMON_PORT_ID, 54 COMMON_GROUP_ID, 55 COMMON_PRIORITY_LEVEL, 56 COMMON_INDIRECT_ACTION_ID, 57 COMMON_PROFILE_ID, 58 COMMON_POLICY_ID, 59 COMMON_FLEX_HANDLE, 60 COMMON_FLEX_TOKEN, 61 COMMON_PATTERN_TEMPLATE_ID, 62 COMMON_ACTIONS_TEMPLATE_ID, 63 COMMON_TABLE_ID, 64 COMMON_QUEUE_ID, 65 66 /* TOP-level command. */ 67 ADD, 68 69 /* Top-level command. */ 70 SET, 71 /* Sub-leve commands. */ 72 SET_RAW_ENCAP, 73 SET_RAW_DECAP, 74 SET_RAW_INDEX, 75 SET_SAMPLE_ACTIONS, 76 SET_SAMPLE_INDEX, 77 SET_IPV6_EXT_REMOVE, 78 SET_IPV6_EXT_PUSH, 79 SET_IPV6_EXT_INDEX, 80 81 /* Top-level command. */ 82 FLOW, 83 /* Sub-level commands. */ 84 INFO, 85 CONFIGURE, 86 PATTERN_TEMPLATE, 87 ACTIONS_TEMPLATE, 88 TABLE, 89 FLOW_GROUP, 90 INDIRECT_ACTION, 91 VALIDATE, 92 CREATE, 93 DESTROY, 94 UPDATE, 95 FLUSH, 96 DUMP, 97 QUERY, 98 LIST, 99 AGED, 100 ISOLATE, 101 TUNNEL, 102 FLEX, 103 QUEUE, 104 PUSH, 105 PULL, 106 HASH, 107 108 /* Flex arguments */ 109 FLEX_ITEM_CREATE, 110 FLEX_ITEM_DESTROY, 111 112 /* Pattern template arguments. */ 113 PATTERN_TEMPLATE_CREATE, 114 PATTERN_TEMPLATE_DESTROY, 115 PATTERN_TEMPLATE_CREATE_ID, 116 PATTERN_TEMPLATE_DESTROY_ID, 117 PATTERN_TEMPLATE_RELAXED_MATCHING, 118 PATTERN_TEMPLATE_INGRESS, 119 PATTERN_TEMPLATE_EGRESS, 120 PATTERN_TEMPLATE_TRANSFER, 121 PATTERN_TEMPLATE_SPEC, 122 123 /* Actions template arguments. */ 124 ACTIONS_TEMPLATE_CREATE, 125 ACTIONS_TEMPLATE_DESTROY, 126 ACTIONS_TEMPLATE_CREATE_ID, 127 ACTIONS_TEMPLATE_DESTROY_ID, 128 ACTIONS_TEMPLATE_INGRESS, 129 ACTIONS_TEMPLATE_EGRESS, 130 ACTIONS_TEMPLATE_TRANSFER, 131 ACTIONS_TEMPLATE_SPEC, 132 ACTIONS_TEMPLATE_MASK, 133 134 /* Queue arguments. */ 135 QUEUE_CREATE, 136 QUEUE_DESTROY, 137 QUEUE_FLOW_UPDATE_RESIZED, 138 QUEUE_UPDATE, 139 QUEUE_AGED, 140 QUEUE_INDIRECT_ACTION, 141 142 /* Queue create arguments. */ 143 QUEUE_CREATE_POSTPONE, 144 QUEUE_TEMPLATE_TABLE, 145 QUEUE_PATTERN_TEMPLATE, 146 QUEUE_ACTIONS_TEMPLATE, 147 QUEUE_RULE_ID, 148 149 /* Queue destroy arguments. */ 150 QUEUE_DESTROY_ID, 151 QUEUE_DESTROY_POSTPONE, 152 153 /* Queue update arguments. */ 154 QUEUE_UPDATE_ID, 155 156 /* Queue indirect action arguments */ 157 QUEUE_INDIRECT_ACTION_CREATE, 158 QUEUE_INDIRECT_ACTION_LIST_CREATE, 159 QUEUE_INDIRECT_ACTION_UPDATE, 160 QUEUE_INDIRECT_ACTION_DESTROY, 161 QUEUE_INDIRECT_ACTION_QUERY, 162 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 163 164 /* Queue indirect action create arguments */ 165 QUEUE_INDIRECT_ACTION_CREATE_ID, 166 QUEUE_INDIRECT_ACTION_INGRESS, 167 QUEUE_INDIRECT_ACTION_EGRESS, 168 QUEUE_INDIRECT_ACTION_TRANSFER, 169 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 170 QUEUE_INDIRECT_ACTION_SPEC, 171 QUEUE_INDIRECT_ACTION_LIST, 172 173 /* Queue indirect action update arguments */ 174 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 175 176 /* Queue indirect action destroy arguments */ 177 QUEUE_INDIRECT_ACTION_DESTROY_ID, 178 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 179 180 /* Queue indirect action query arguments */ 181 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 182 183 /* Queue indirect action query_update arguments */ 184 QUEUE_INDIRECT_ACTION_QU_MODE, 185 186 /* Push arguments. */ 187 PUSH_QUEUE, 188 189 /* Pull arguments. */ 190 PULL_QUEUE, 191 192 /* Table arguments. */ 193 TABLE_CREATE, 194 TABLE_DESTROY, 195 TABLE_RESIZE, 196 TABLE_RESIZE_COMPLETE, 197 TABLE_CREATE_ID, 198 TABLE_DESTROY_ID, 199 TABLE_RESIZE_ID, 200 TABLE_RESIZE_RULES_NUMBER, 201 TABLE_INSERTION_TYPE, 202 TABLE_INSERTION_TYPE_NAME, 203 TABLE_HASH_FUNC, 204 TABLE_HASH_FUNC_NAME, 205 TABLE_GROUP, 206 TABLE_PRIORITY, 207 TABLE_INGRESS, 208 TABLE_EGRESS, 209 TABLE_TRANSFER, 210 TABLE_TRANSFER_WIRE_ORIG, 211 TABLE_TRANSFER_VPORT_ORIG, 212 TABLE_RESIZABLE, 213 TABLE_RULES_NUMBER, 214 TABLE_PATTERN_TEMPLATE, 215 TABLE_ACTIONS_TEMPLATE, 216 217 /* Group arguments */ 218 GROUP_ID, 219 GROUP_INGRESS, 220 GROUP_EGRESS, 221 GROUP_TRANSFER, 222 GROUP_SET_MISS_ACTIONS, 223 224 /* Hash calculation arguments. */ 225 HASH_CALC_TABLE, 226 HASH_CALC_PATTERN_INDEX, 227 HASH_CALC_PATTERN, 228 HASH_CALC_ENCAP, 229 HASH_CALC_DEST, 230 ENCAP_HASH_FIELD_SRC_PORT, 231 ENCAP_HASH_FIELD_GRE_FLOW_ID, 232 233 /* Tunnel arguments. */ 234 TUNNEL_CREATE, 235 TUNNEL_CREATE_TYPE, 236 TUNNEL_LIST, 237 TUNNEL_DESTROY, 238 TUNNEL_DESTROY_ID, 239 240 /* Destroy arguments. */ 241 DESTROY_RULE, 242 DESTROY_IS_USER_ID, 243 244 /* Query arguments. */ 245 QUERY_ACTION, 246 QUERY_IS_USER_ID, 247 248 /* List arguments. */ 249 LIST_GROUP, 250 251 /* Destroy aged flow arguments. */ 252 AGED_DESTROY, 253 254 /* Validate/create arguments. */ 255 VC_GROUP, 256 VC_PRIORITY, 257 VC_INGRESS, 258 VC_EGRESS, 259 VC_TRANSFER, 260 VC_TUNNEL_SET, 261 VC_TUNNEL_MATCH, 262 VC_USER_ID, 263 VC_IS_USER_ID, 264 265 /* Dump arguments */ 266 DUMP_ALL, 267 DUMP_ONE, 268 DUMP_IS_USER_ID, 269 270 /* Configure arguments */ 271 CONFIG_QUEUES_NUMBER, 272 CONFIG_QUEUES_SIZE, 273 CONFIG_COUNTERS_NUMBER, 274 CONFIG_AGING_OBJECTS_NUMBER, 275 CONFIG_METERS_NUMBER, 276 CONFIG_CONN_TRACK_NUMBER, 277 CONFIG_QUOTAS_NUMBER, 278 CONFIG_FLAGS, 279 CONFIG_HOST_PORT, 280 281 /* Indirect action arguments */ 282 INDIRECT_ACTION_CREATE, 283 INDIRECT_ACTION_LIST_CREATE, 284 INDIRECT_ACTION_FLOW_CONF_CREATE, 285 INDIRECT_ACTION_UPDATE, 286 INDIRECT_ACTION_DESTROY, 287 INDIRECT_ACTION_QUERY, 288 INDIRECT_ACTION_QUERY_UPDATE, 289 290 /* Indirect action create arguments */ 291 INDIRECT_ACTION_CREATE_ID, 292 INDIRECT_ACTION_INGRESS, 293 INDIRECT_ACTION_EGRESS, 294 INDIRECT_ACTION_TRANSFER, 295 INDIRECT_ACTION_SPEC, 296 INDIRECT_ACTION_LIST, 297 INDIRECT_ACTION_FLOW_CONF, 298 299 /* Indirect action destroy arguments */ 300 INDIRECT_ACTION_DESTROY_ID, 301 302 /* Indirect action query-and-update arguments */ 303 INDIRECT_ACTION_QU_MODE, 304 INDIRECT_ACTION_QU_MODE_NAME, 305 306 /* Validate/create pattern. */ 307 ITEM_PATTERN, 308 ITEM_PARAM_IS, 309 ITEM_PARAM_SPEC, 310 ITEM_PARAM_LAST, 311 ITEM_PARAM_MASK, 312 ITEM_PARAM_PREFIX, 313 ITEM_NEXT, 314 ITEM_END, 315 ITEM_VOID, 316 ITEM_INVERT, 317 ITEM_ANY, 318 ITEM_ANY_NUM, 319 ITEM_PORT_ID, 320 ITEM_PORT_ID_ID, 321 ITEM_MARK, 322 ITEM_MARK_ID, 323 ITEM_RAW, 324 ITEM_RAW_RELATIVE, 325 ITEM_RAW_SEARCH, 326 ITEM_RAW_OFFSET, 327 ITEM_RAW_LIMIT, 328 ITEM_RAW_PATTERN, 329 ITEM_RAW_PATTERN_HEX, 330 ITEM_ETH, 331 ITEM_ETH_DST, 332 ITEM_ETH_SRC, 333 ITEM_ETH_TYPE, 334 ITEM_ETH_HAS_VLAN, 335 ITEM_VLAN, 336 ITEM_VLAN_TCI, 337 ITEM_VLAN_PCP, 338 ITEM_VLAN_DEI, 339 ITEM_VLAN_VID, 340 ITEM_VLAN_INNER_TYPE, 341 ITEM_VLAN_HAS_MORE_VLAN, 342 ITEM_IPV4, 343 ITEM_IPV4_VER_IHL, 344 ITEM_IPV4_TOS, 345 ITEM_IPV4_LENGTH, 346 ITEM_IPV4_ID, 347 ITEM_IPV4_FRAGMENT_OFFSET, 348 ITEM_IPV4_TTL, 349 ITEM_IPV4_PROTO, 350 ITEM_IPV4_SRC, 351 ITEM_IPV4_DST, 352 ITEM_IPV6, 353 ITEM_IPV6_TC, 354 ITEM_IPV6_FLOW, 355 ITEM_IPV6_LEN, 356 ITEM_IPV6_PROTO, 357 ITEM_IPV6_HOP, 358 ITEM_IPV6_SRC, 359 ITEM_IPV6_DST, 360 ITEM_IPV6_HAS_FRAG_EXT, 361 ITEM_IPV6_ROUTING_EXT, 362 ITEM_IPV6_ROUTING_EXT_TYPE, 363 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 364 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 365 ITEM_ICMP, 366 ITEM_ICMP_TYPE, 367 ITEM_ICMP_CODE, 368 ITEM_ICMP_IDENT, 369 ITEM_ICMP_SEQ, 370 ITEM_UDP, 371 ITEM_UDP_SRC, 372 ITEM_UDP_DST, 373 ITEM_TCP, 374 ITEM_TCP_SRC, 375 ITEM_TCP_DST, 376 ITEM_TCP_FLAGS, 377 ITEM_SCTP, 378 ITEM_SCTP_SRC, 379 ITEM_SCTP_DST, 380 ITEM_SCTP_TAG, 381 ITEM_SCTP_CKSUM, 382 ITEM_VXLAN, 383 ITEM_VXLAN_VNI, 384 ITEM_VXLAN_FLAG_G, 385 ITEM_VXLAN_FLAG_VER, 386 ITEM_VXLAN_FLAG_I, 387 ITEM_VXLAN_FLAG_P, 388 ITEM_VXLAN_FLAG_B, 389 ITEM_VXLAN_FLAG_O, 390 ITEM_VXLAN_FLAG_D, 391 ITEM_VXLAN_FLAG_A, 392 ITEM_VXLAN_GBP_ID, 393 /* Used for "struct rte_vxlan_hdr", GPE Next protocol */ 394 ITEM_VXLAN_GPE_PROTO, 395 ITEM_VXLAN_FIRST_RSVD, 396 ITEM_VXLAN_SECND_RSVD, 397 ITEM_VXLAN_THIRD_RSVD, 398 ITEM_VXLAN_LAST_RSVD, 399 ITEM_E_TAG, 400 ITEM_E_TAG_GRP_ECID_B, 401 ITEM_NVGRE, 402 ITEM_NVGRE_TNI, 403 ITEM_MPLS, 404 ITEM_MPLS_LABEL, 405 ITEM_MPLS_TC, 406 ITEM_MPLS_S, 407 ITEM_MPLS_TTL, 408 ITEM_GRE, 409 ITEM_GRE_PROTO, 410 ITEM_GRE_C_RSVD0_VER, 411 ITEM_GRE_C_BIT, 412 ITEM_GRE_K_BIT, 413 ITEM_GRE_S_BIT, 414 ITEM_FUZZY, 415 ITEM_FUZZY_THRESH, 416 ITEM_GTP, 417 ITEM_GTP_FLAGS, 418 ITEM_GTP_MSG_TYPE, 419 ITEM_GTP_TEID, 420 ITEM_GTPC, 421 ITEM_GTPU, 422 ITEM_GENEVE, 423 ITEM_GENEVE_VNI, 424 ITEM_GENEVE_PROTO, 425 ITEM_GENEVE_OPTLEN, 426 ITEM_VXLAN_GPE, 427 ITEM_VXLAN_GPE_VNI, 428 /* Used for "struct rte_vxlan_gpe_hdr", deprecated, prefer ITEM_VXLAN_GPE_PROTO */ 429 ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR, 430 ITEM_VXLAN_GPE_FLAGS, 431 ITEM_VXLAN_GPE_RSVD0, 432 ITEM_VXLAN_GPE_RSVD1, 433 ITEM_ARP_ETH_IPV4, 434 ITEM_ARP_ETH_IPV4_SHA, 435 ITEM_ARP_ETH_IPV4_SPA, 436 ITEM_ARP_ETH_IPV4_THA, 437 ITEM_ARP_ETH_IPV4_TPA, 438 ITEM_IPV6_EXT, 439 ITEM_IPV6_EXT_NEXT_HDR, 440 ITEM_IPV6_FRAG_EXT, 441 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 442 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 443 ITEM_IPV6_FRAG_EXT_ID, 444 ITEM_ICMP6, 445 ITEM_ICMP6_TYPE, 446 ITEM_ICMP6_CODE, 447 ITEM_ICMP6_ECHO_REQUEST, 448 ITEM_ICMP6_ECHO_REQUEST_ID, 449 ITEM_ICMP6_ECHO_REQUEST_SEQ, 450 ITEM_ICMP6_ECHO_REPLY, 451 ITEM_ICMP6_ECHO_REPLY_ID, 452 ITEM_ICMP6_ECHO_REPLY_SEQ, 453 ITEM_ICMP6_ND_NS, 454 ITEM_ICMP6_ND_NS_TARGET_ADDR, 455 ITEM_ICMP6_ND_NA, 456 ITEM_ICMP6_ND_NA_TARGET_ADDR, 457 ITEM_ICMP6_ND_OPT, 458 ITEM_ICMP6_ND_OPT_TYPE, 459 ITEM_ICMP6_ND_OPT_SLA_ETH, 460 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 461 ITEM_ICMP6_ND_OPT_TLA_ETH, 462 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 463 ITEM_META, 464 ITEM_META_DATA, 465 ITEM_RANDOM, 466 ITEM_RANDOM_VALUE, 467 ITEM_GRE_KEY, 468 ITEM_GRE_KEY_VALUE, 469 ITEM_GRE_OPTION, 470 ITEM_GRE_OPTION_CHECKSUM, 471 ITEM_GRE_OPTION_KEY, 472 ITEM_GRE_OPTION_SEQUENCE, 473 ITEM_GTP_PSC, 474 ITEM_GTP_PSC_QFI, 475 ITEM_GTP_PSC_PDU_T, 476 ITEM_PPPOES, 477 ITEM_PPPOED, 478 ITEM_PPPOE_SEID, 479 ITEM_PPPOE_PROTO_ID, 480 ITEM_HIGIG2, 481 ITEM_HIGIG2_CLASSIFICATION, 482 ITEM_HIGIG2_VID, 483 ITEM_TAG, 484 ITEM_TAG_DATA, 485 ITEM_TAG_INDEX, 486 ITEM_L2TPV3OIP, 487 ITEM_L2TPV3OIP_SESSION_ID, 488 ITEM_ESP, 489 ITEM_ESP_SPI, 490 ITEM_AH, 491 ITEM_AH_SPI, 492 ITEM_PFCP, 493 ITEM_PFCP_S_FIELD, 494 ITEM_PFCP_SEID, 495 ITEM_ECPRI, 496 ITEM_ECPRI_COMMON, 497 ITEM_ECPRI_COMMON_TYPE, 498 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 499 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 500 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 501 ITEM_ECPRI_MSG_IQ_DATA_PCID, 502 ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 503 ITEM_ECPRI_MSG_DLY_MSR_MSRID, 504 ITEM_GENEVE_OPT, 505 ITEM_GENEVE_OPT_CLASS, 506 ITEM_GENEVE_OPT_TYPE, 507 ITEM_GENEVE_OPT_LENGTH, 508 ITEM_GENEVE_OPT_DATA, 509 ITEM_INTEGRITY, 510 ITEM_INTEGRITY_LEVEL, 511 ITEM_INTEGRITY_VALUE, 512 ITEM_CONNTRACK, 513 ITEM_POL_PORT, 514 ITEM_POL_METER, 515 ITEM_POL_POLICY, 516 ITEM_PORT_REPRESENTOR, 517 ITEM_PORT_REPRESENTOR_PORT_ID, 518 ITEM_REPRESENTED_PORT, 519 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 520 ITEM_FLEX, 521 ITEM_FLEX_ITEM_HANDLE, 522 ITEM_FLEX_PATTERN_HANDLE, 523 ITEM_L2TPV2, 524 ITEM_L2TPV2_TYPE, 525 ITEM_L2TPV2_TYPE_DATA, 526 ITEM_L2TPV2_TYPE_DATA_L, 527 ITEM_L2TPV2_TYPE_DATA_S, 528 ITEM_L2TPV2_TYPE_DATA_O, 529 ITEM_L2TPV2_TYPE_DATA_L_S, 530 ITEM_L2TPV2_TYPE_CTRL, 531 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 532 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 533 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 534 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 535 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 536 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 537 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 538 ITEM_L2TPV2_MSG_DATA_S_NS, 539 ITEM_L2TPV2_MSG_DATA_S_NR, 540 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 541 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 542 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 543 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 544 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 545 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 546 ITEM_L2TPV2_MSG_DATA_L_S_NS, 547 ITEM_L2TPV2_MSG_DATA_L_S_NR, 548 ITEM_L2TPV2_MSG_CTRL_LENGTH, 549 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 550 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 551 ITEM_L2TPV2_MSG_CTRL_NS, 552 ITEM_L2TPV2_MSG_CTRL_NR, 553 ITEM_PPP, 554 ITEM_PPP_ADDR, 555 ITEM_PPP_CTRL, 556 ITEM_PPP_PROTO_ID, 557 ITEM_METER, 558 ITEM_METER_COLOR, 559 ITEM_METER_COLOR_NAME, 560 ITEM_QUOTA, 561 ITEM_QUOTA_STATE, 562 ITEM_QUOTA_STATE_NAME, 563 ITEM_AGGR_AFFINITY, 564 ITEM_AGGR_AFFINITY_VALUE, 565 ITEM_TX_QUEUE, 566 ITEM_TX_QUEUE_VALUE, 567 ITEM_IB_BTH, 568 ITEM_IB_BTH_OPCODE, 569 ITEM_IB_BTH_PKEY, 570 ITEM_IB_BTH_DST_QPN, 571 ITEM_IB_BTH_PSN, 572 ITEM_IPV6_PUSH_REMOVE_EXT, 573 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 574 ITEM_PTYPE, 575 ITEM_PTYPE_VALUE, 576 ITEM_NSH, 577 ITEM_COMPARE, 578 ITEM_COMPARE_OP, 579 ITEM_COMPARE_OP_VALUE, 580 ITEM_COMPARE_FIELD_A_TYPE, 581 ITEM_COMPARE_FIELD_A_TYPE_VALUE, 582 ITEM_COMPARE_FIELD_A_LEVEL, 583 ITEM_COMPARE_FIELD_A_LEVEL_VALUE, 584 ITEM_COMPARE_FIELD_A_TAG_INDEX, 585 ITEM_COMPARE_FIELD_A_TYPE_ID, 586 ITEM_COMPARE_FIELD_A_CLASS_ID, 587 ITEM_COMPARE_FIELD_A_OFFSET, 588 ITEM_COMPARE_FIELD_B_TYPE, 589 ITEM_COMPARE_FIELD_B_TYPE_VALUE, 590 ITEM_COMPARE_FIELD_B_LEVEL, 591 ITEM_COMPARE_FIELD_B_LEVEL_VALUE, 592 ITEM_COMPARE_FIELD_B_TAG_INDEX, 593 ITEM_COMPARE_FIELD_B_TYPE_ID, 594 ITEM_COMPARE_FIELD_B_CLASS_ID, 595 ITEM_COMPARE_FIELD_B_OFFSET, 596 ITEM_COMPARE_FIELD_B_VALUE, 597 ITEM_COMPARE_FIELD_B_POINTER, 598 ITEM_COMPARE_FIELD_WIDTH, 599 600 /* Validate/create actions. */ 601 ACTIONS, 602 ACTION_NEXT, 603 ACTION_END, 604 ACTION_VOID, 605 ACTION_PASSTHRU, 606 ACTION_SKIP_CMAN, 607 ACTION_JUMP, 608 ACTION_JUMP_GROUP, 609 ACTION_MARK, 610 ACTION_MARK_ID, 611 ACTION_FLAG, 612 ACTION_QUEUE, 613 ACTION_QUEUE_INDEX, 614 ACTION_DROP, 615 ACTION_COUNT, 616 ACTION_COUNT_ID, 617 ACTION_RSS, 618 ACTION_RSS_FUNC, 619 ACTION_RSS_LEVEL, 620 ACTION_RSS_FUNC_DEFAULT, 621 ACTION_RSS_FUNC_TOEPLITZ, 622 ACTION_RSS_FUNC_SIMPLE_XOR, 623 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, 624 ACTION_RSS_TYPES, 625 ACTION_RSS_TYPE, 626 ACTION_RSS_KEY, 627 ACTION_RSS_KEY_LEN, 628 ACTION_RSS_QUEUES, 629 ACTION_RSS_QUEUE, 630 ACTION_PF, 631 ACTION_VF, 632 ACTION_VF_ORIGINAL, 633 ACTION_VF_ID, 634 ACTION_PORT_ID, 635 ACTION_PORT_ID_ORIGINAL, 636 ACTION_PORT_ID_ID, 637 ACTION_METER, 638 ACTION_METER_COLOR, 639 ACTION_METER_COLOR_TYPE, 640 ACTION_METER_COLOR_GREEN, 641 ACTION_METER_COLOR_YELLOW, 642 ACTION_METER_COLOR_RED, 643 ACTION_METER_ID, 644 ACTION_METER_MARK, 645 ACTION_METER_PROFILE, 646 ACTION_METER_PROFILE_ID2PTR, 647 ACTION_METER_POLICY, 648 ACTION_METER_POLICY_ID2PTR, 649 ACTION_METER_COLOR_MODE, 650 ACTION_METER_STATE, 651 ACTION_OF_DEC_NW_TTL, 652 ACTION_OF_POP_VLAN, 653 ACTION_OF_PUSH_VLAN, 654 ACTION_OF_PUSH_VLAN_ETHERTYPE, 655 ACTION_OF_SET_VLAN_VID, 656 ACTION_OF_SET_VLAN_VID_VLAN_VID, 657 ACTION_OF_SET_VLAN_PCP, 658 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 659 ACTION_OF_POP_MPLS, 660 ACTION_OF_POP_MPLS_ETHERTYPE, 661 ACTION_OF_PUSH_MPLS, 662 ACTION_OF_PUSH_MPLS_ETHERTYPE, 663 ACTION_VXLAN_ENCAP, 664 ACTION_VXLAN_DECAP, 665 ACTION_NVGRE_ENCAP, 666 ACTION_NVGRE_DECAP, 667 ACTION_L2_ENCAP, 668 ACTION_L2_DECAP, 669 ACTION_MPLSOGRE_ENCAP, 670 ACTION_MPLSOGRE_DECAP, 671 ACTION_MPLSOUDP_ENCAP, 672 ACTION_MPLSOUDP_DECAP, 673 ACTION_SET_IPV4_SRC, 674 ACTION_SET_IPV4_SRC_IPV4_SRC, 675 ACTION_SET_IPV4_DST, 676 ACTION_SET_IPV4_DST_IPV4_DST, 677 ACTION_SET_IPV6_SRC, 678 ACTION_SET_IPV6_SRC_IPV6_SRC, 679 ACTION_SET_IPV6_DST, 680 ACTION_SET_IPV6_DST_IPV6_DST, 681 ACTION_SET_TP_SRC, 682 ACTION_SET_TP_SRC_TP_SRC, 683 ACTION_SET_TP_DST, 684 ACTION_SET_TP_DST_TP_DST, 685 ACTION_MAC_SWAP, 686 ACTION_DEC_TTL, 687 ACTION_SET_TTL, 688 ACTION_SET_TTL_TTL, 689 ACTION_SET_MAC_SRC, 690 ACTION_SET_MAC_SRC_MAC_SRC, 691 ACTION_SET_MAC_DST, 692 ACTION_SET_MAC_DST_MAC_DST, 693 ACTION_INC_TCP_SEQ, 694 ACTION_INC_TCP_SEQ_VALUE, 695 ACTION_DEC_TCP_SEQ, 696 ACTION_DEC_TCP_SEQ_VALUE, 697 ACTION_INC_TCP_ACK, 698 ACTION_INC_TCP_ACK_VALUE, 699 ACTION_DEC_TCP_ACK, 700 ACTION_DEC_TCP_ACK_VALUE, 701 ACTION_RAW_ENCAP, 702 ACTION_RAW_DECAP, 703 ACTION_RAW_ENCAP_SIZE, 704 ACTION_RAW_ENCAP_INDEX, 705 ACTION_RAW_ENCAP_INDEX_VALUE, 706 ACTION_RAW_DECAP_INDEX, 707 ACTION_RAW_DECAP_INDEX_VALUE, 708 ACTION_SET_TAG, 709 ACTION_SET_TAG_DATA, 710 ACTION_SET_TAG_INDEX, 711 ACTION_SET_TAG_MASK, 712 ACTION_SET_META, 713 ACTION_SET_META_DATA, 714 ACTION_SET_META_MASK, 715 ACTION_SET_IPV4_DSCP, 716 ACTION_SET_IPV4_DSCP_VALUE, 717 ACTION_SET_IPV6_DSCP, 718 ACTION_SET_IPV6_DSCP_VALUE, 719 ACTION_AGE, 720 ACTION_AGE_TIMEOUT, 721 ACTION_AGE_UPDATE, 722 ACTION_AGE_UPDATE_TIMEOUT, 723 ACTION_AGE_UPDATE_TOUCH, 724 ACTION_SAMPLE, 725 ACTION_SAMPLE_RATIO, 726 ACTION_SAMPLE_INDEX, 727 ACTION_SAMPLE_INDEX_VALUE, 728 ACTION_INDIRECT, 729 ACTION_INDIRECT_LIST, 730 ACTION_INDIRECT_LIST_HANDLE, 731 ACTION_INDIRECT_LIST_CONF, 732 INDIRECT_LIST_ACTION_ID2PTR_HANDLE, 733 INDIRECT_LIST_ACTION_ID2PTR_CONF, 734 ACTION_SHARED_INDIRECT, 735 INDIRECT_ACTION_PORT, 736 INDIRECT_ACTION_ID2PTR, 737 ACTION_MODIFY_FIELD, 738 ACTION_MODIFY_FIELD_OP, 739 ACTION_MODIFY_FIELD_OP_VALUE, 740 ACTION_MODIFY_FIELD_DST_TYPE, 741 ACTION_MODIFY_FIELD_DST_TYPE_VALUE, 742 ACTION_MODIFY_FIELD_DST_LEVEL, 743 ACTION_MODIFY_FIELD_DST_LEVEL_VALUE, 744 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 745 ACTION_MODIFY_FIELD_DST_TYPE_ID, 746 ACTION_MODIFY_FIELD_DST_CLASS_ID, 747 ACTION_MODIFY_FIELD_DST_OFFSET, 748 ACTION_MODIFY_FIELD_SRC_TYPE, 749 ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, 750 ACTION_MODIFY_FIELD_SRC_LEVEL, 751 ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE, 752 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 753 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 754 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 755 ACTION_MODIFY_FIELD_SRC_OFFSET, 756 ACTION_MODIFY_FIELD_SRC_VALUE, 757 ACTION_MODIFY_FIELD_SRC_POINTER, 758 ACTION_MODIFY_FIELD_WIDTH, 759 ACTION_CONNTRACK, 760 ACTION_CONNTRACK_UPDATE, 761 ACTION_CONNTRACK_UPDATE_DIR, 762 ACTION_CONNTRACK_UPDATE_CTX, 763 ACTION_POL_G, 764 ACTION_POL_Y, 765 ACTION_POL_R, 766 ACTION_PORT_REPRESENTOR, 767 ACTION_PORT_REPRESENTOR_PORT_ID, 768 ACTION_REPRESENTED_PORT, 769 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 770 ACTION_SEND_TO_KERNEL, 771 ACTION_QUOTA_CREATE, 772 ACTION_QUOTA_CREATE_LIMIT, 773 ACTION_QUOTA_CREATE_MODE, 774 ACTION_QUOTA_CREATE_MODE_NAME, 775 ACTION_QUOTA_QU, 776 ACTION_QUOTA_QU_LIMIT, 777 ACTION_QUOTA_QU_UPDATE_OP, 778 ACTION_QUOTA_QU_UPDATE_OP_NAME, 779 ACTION_IPV6_EXT_REMOVE, 780 ACTION_IPV6_EXT_REMOVE_INDEX, 781 ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, 782 ACTION_IPV6_EXT_PUSH, 783 ACTION_IPV6_EXT_PUSH_INDEX, 784 ACTION_IPV6_EXT_PUSH_INDEX_VALUE, 785 ACTION_NAT64, 786 ACTION_NAT64_MODE, 787 ACTION_JUMP_TO_TABLE_INDEX, 788 ACTION_JUMP_TO_TABLE_INDEX_TABLE, 789 ACTION_JUMP_TO_TABLE_INDEX_INDEX, 790 }; 791 792 /** Maximum size for pattern in struct rte_flow_item_raw. */ 793 #define ITEM_RAW_PATTERN_SIZE 512 794 795 /** Maximum size for GENEVE option data pattern in bytes. */ 796 #define ITEM_GENEVE_OPT_DATA_SIZE 124 797 798 /** Storage size for struct rte_flow_item_raw including pattern. */ 799 #define ITEM_RAW_SIZE \ 800 (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) 801 802 static const char *const compare_ops[] = { 803 "eq", "ne", "lt", "le", "gt", "ge", NULL 804 }; 805 806 /** Maximum size for external pattern in struct rte_flow_field_data. */ 807 #define FLOW_FIELD_PATTERN_SIZE 32 808 809 /** Storage size for struct rte_flow_action_modify_field including pattern. */ 810 #define ACTION_MODIFY_SIZE \ 811 (sizeof(struct rte_flow_action_modify_field) + \ 812 FLOW_FIELD_PATTERN_SIZE) 813 814 /** Maximum number of queue indices in struct rte_flow_action_rss. */ 815 #define ACTION_RSS_QUEUE_NUM 128 816 817 /** Storage for struct rte_flow_action_rss including external data. */ 818 struct action_rss_data { 819 struct rte_flow_action_rss conf; 820 uint8_t key[RSS_HASH_KEY_LENGTH]; 821 uint16_t queue[ACTION_RSS_QUEUE_NUM]; 822 }; 823 824 /** Maximum data size in struct rte_flow_action_raw_encap. */ 825 #define ACTION_RAW_ENCAP_MAX_DATA 512 826 #define RAW_ENCAP_CONFS_MAX_NUM 8 827 828 /** Storage for struct rte_flow_action_raw_encap. */ 829 struct raw_encap_conf { 830 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 831 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 832 size_t size; 833 }; 834 835 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 836 837 /** Storage for struct rte_flow_action_raw_encap including external data. */ 838 struct action_raw_encap_data { 839 struct rte_flow_action_raw_encap conf; 840 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 841 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 842 uint16_t idx; 843 }; 844 845 /** Storage for struct rte_flow_action_raw_decap. */ 846 struct raw_decap_conf { 847 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 848 size_t size; 849 }; 850 851 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 852 853 /** Storage for struct rte_flow_action_raw_decap including external data. */ 854 struct action_raw_decap_data { 855 struct rte_flow_action_raw_decap conf; 856 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 857 uint16_t idx; 858 }; 859 860 /** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ 861 #define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 862 #define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 863 864 /** Storage for struct rte_flow_action_ipv6_ext_push. */ 865 struct ipv6_ext_push_conf { 866 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 867 size_t size; 868 uint8_t type; 869 }; 870 871 struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 872 873 /** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ 874 struct action_ipv6_ext_push_data { 875 struct rte_flow_action_ipv6_ext_push conf; 876 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 877 uint8_t type; 878 uint16_t idx; 879 }; 880 881 /** Storage for struct rte_flow_action_ipv6_ext_remove. */ 882 struct ipv6_ext_remove_conf { 883 struct rte_flow_action_ipv6_ext_remove conf; 884 uint8_t type; 885 }; 886 887 struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 888 889 /** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ 890 struct action_ipv6_ext_remove_data { 891 struct rte_flow_action_ipv6_ext_remove conf; 892 uint8_t type; 893 uint16_t idx; 894 }; 895 896 struct vxlan_encap_conf vxlan_encap_conf = { 897 .select_ipv4 = 1, 898 .select_vlan = 0, 899 .select_tos_ttl = 0, 900 .vni = { 0x00, 0x00, 0x00 }, 901 .udp_src = 0, 902 .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), 903 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 904 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 905 .ipv6_src = RTE_IPV6_ADDR_LOOPBACK, 906 .ipv6_dst = RTE_IPV6(0, 0, 0, 0, 0, 0, 0, 0x1111), 907 .vlan_tci = 0, 908 .ip_tos = 0, 909 .ip_ttl = 255, 910 .eth_src = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 911 .eth_dst = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 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 = { 0x00, 0x00, 0x00 }, 935 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 936 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 937 .ipv6_src = RTE_IPV6_ADDR_LOOPBACK, 938 .ipv6_dst = RTE_IPV6(0, 0, 0, 0, 0, 0, 0, 0x1111), 939 .vlan_tci = 0, 940 .eth_src = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 941 .eth_dst = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 942 }; 943 944 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */ 945 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 946 947 /** Storage for struct rte_flow_action_nvgre_encap including external data. */ 948 struct action_nvgre_encap_data { 949 struct rte_flow_action_nvgre_encap conf; 950 struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; 951 struct rte_flow_item_eth item_eth; 952 struct rte_flow_item_vlan item_vlan; 953 union { 954 struct rte_flow_item_ipv4 item_ipv4; 955 struct rte_flow_item_ipv6 item_ipv6; 956 }; 957 struct rte_flow_item_nvgre item_nvgre; 958 }; 959 960 struct l2_encap_conf l2_encap_conf; 961 962 struct l2_decap_conf l2_decap_conf; 963 964 struct mplsogre_encap_conf mplsogre_encap_conf; 965 966 struct mplsogre_decap_conf mplsogre_decap_conf; 967 968 struct mplsoudp_encap_conf mplsoudp_encap_conf; 969 970 struct mplsoudp_decap_conf mplsoudp_decap_conf; 971 972 struct rte_flow_action_conntrack conntrack_context; 973 974 #define ACTION_SAMPLE_ACTIONS_NUM 10 975 #define RAW_SAMPLE_CONFS_MAX_NUM 8 976 /** Storage for struct rte_flow_action_sample including external data. */ 977 struct action_sample_data { 978 struct rte_flow_action_sample conf; 979 uint32_t idx; 980 }; 981 /** Storage for struct rte_flow_action_sample. */ 982 struct raw_sample_conf { 983 struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; 984 }; 985 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; 986 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; 987 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; 988 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; 989 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; 990 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 991 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 992 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 993 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; 994 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; 995 struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; 996 struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; 997 998 static const char *const modify_field_ops[] = { 999 "set", "add", "sub", NULL 1000 }; 1001 1002 static const char *const flow_field_ids[] = { 1003 "start", "mac_dst", "mac_src", 1004 "vlan_type", "vlan_id", "mac_type", 1005 "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", 1006 "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", 1007 "tcp_port_src", "tcp_port_dst", 1008 "tcp_seq_num", "tcp_ack_num", "tcp_flags", 1009 "udp_port_src", "udp_port_dst", 1010 "vxlan_vni", "geneve_vni", "gtp_teid", 1011 "tag", "mark", "meta", "pointer", "value", 1012 "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", 1013 "ipv6_proto", 1014 "flex_item", 1015 "hash_result", 1016 "geneve_opt_type", "geneve_opt_class", "geneve_opt_data", "mpls", 1017 "tcp_data_off", "ipv4_ihl", "ipv4_total_len", "ipv6_payload_len", 1018 "ipv4_proto", 1019 "ipv6_flow_label", "ipv6_traffic_class", 1020 "esp_spi", "esp_seq_num", "esp_proto", 1021 "random", 1022 "vxlan_last_rsvd", 1023 NULL 1024 }; 1025 1026 static const char *const meter_colors[] = { 1027 "green", "yellow", "red", "all", NULL 1028 }; 1029 1030 static const char *const table_insertion_types[] = { 1031 "pattern", "index", "index_with_pattern", NULL 1032 }; 1033 1034 static const char *const table_hash_funcs[] = { 1035 "default", "linear", "crc32", "crc16", NULL 1036 }; 1037 1038 #define RAW_IPSEC_CONFS_MAX_NUM 8 1039 1040 /** Maximum number of subsequent tokens and arguments on the stack. */ 1041 #define CTX_STACK_SIZE 16 1042 1043 /** Parser context. */ 1044 struct context { 1045 /** Stack of subsequent token lists to process. */ 1046 const enum index *next[CTX_STACK_SIZE]; 1047 /** Arguments for stacked tokens. */ 1048 const void *args[CTX_STACK_SIZE]; 1049 enum index curr; /**< Current token index. */ 1050 enum index prev; /**< Index of the last token seen. */ 1051 int next_num; /**< Number of entries in next[]. */ 1052 int args_num; /**< Number of entries in args[]. */ 1053 uint32_t eol:1; /**< EOL has been detected. */ 1054 uint32_t last:1; /**< No more arguments. */ 1055 portid_t port; /**< Current port ID (for completions). */ 1056 uint32_t objdata; /**< Object-specific data. */ 1057 void *object; /**< Address of current object for relative offsets. */ 1058 void *objmask; /**< Object a full mask must be written to. */ 1059 }; 1060 1061 /** Token argument. */ 1062 struct arg { 1063 uint32_t hton:1; /**< Use network byte ordering. */ 1064 uint32_t sign:1; /**< Value is signed. */ 1065 uint32_t bounded:1; /**< Value is bounded. */ 1066 uintmax_t min; /**< Minimum value if bounded. */ 1067 uintmax_t max; /**< Maximum value if bounded. */ 1068 uint32_t offset; /**< Relative offset from ctx->object. */ 1069 uint32_t size; /**< Field size. */ 1070 const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ 1071 }; 1072 1073 /** Parser token definition. */ 1074 struct token { 1075 /** Type displayed during completion (defaults to "TOKEN"). */ 1076 const char *type; 1077 /** Help displayed during completion (defaults to token name). */ 1078 const char *help; 1079 /** Private data used by parser functions. */ 1080 const void *priv; 1081 /** 1082 * Lists of subsequent tokens to push on the stack. Each call to the 1083 * parser consumes the last entry of that stack. 1084 */ 1085 const enum index *const *next; 1086 /** Arguments stack for subsequent tokens that need them. */ 1087 const struct arg *const *args; 1088 /** 1089 * Token-processing callback, returns -1 in case of error, the 1090 * length of the matched string otherwise. If NULL, attempts to 1091 * match the token name. 1092 * 1093 * If buf is not NULL, the result should be stored in it according 1094 * to context. An error is returned if not large enough. 1095 */ 1096 int (*call)(struct context *ctx, const struct token *token, 1097 const char *str, unsigned int len, 1098 void *buf, unsigned int size); 1099 /** 1100 * Callback that provides possible values for this token, used for 1101 * completion. Returns -1 in case of error, the number of possible 1102 * values otherwise. If NULL, the token name is used. 1103 * 1104 * If buf is not NULL, entry index ent is written to buf and the 1105 * full length of the entry is returned (same behavior as 1106 * snprintf()). 1107 */ 1108 int (*comp)(struct context *ctx, const struct token *token, 1109 unsigned int ent, char *buf, unsigned int size); 1110 /** Mandatory token name, no default value. */ 1111 const char *name; 1112 }; 1113 1114 /** Static initializer for the next field. */ 1115 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } 1116 1117 /** Static initializer for a NEXT() entry. */ 1118 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } 1119 1120 /** Static initializer for the args field. */ 1121 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } 1122 1123 /** Static initializer for ARGS() to target a field. */ 1124 #define ARGS_ENTRY(s, f) \ 1125 (&(const struct arg){ \ 1126 .offset = offsetof(s, f), \ 1127 .size = sizeof(((s *)0)->f), \ 1128 }) 1129 1130 /** Static initializer for ARGS() to target a bit-field. */ 1131 #define ARGS_ENTRY_BF(s, f, b) \ 1132 (&(const struct arg){ \ 1133 .size = sizeof(s), \ 1134 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ 1135 }) 1136 1137 /** Static initializer for ARGS() to target a field with limits. */ 1138 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \ 1139 (&(const struct arg){ \ 1140 .bounded = 1, \ 1141 .min = (i), \ 1142 .max = (a), \ 1143 .offset = offsetof(s, f), \ 1144 .size = sizeof(((s *)0)->f), \ 1145 }) 1146 1147 /** Static initializer for ARGS() to target an arbitrary bit-mask. */ 1148 #define ARGS_ENTRY_MASK(s, f, m) \ 1149 (&(const struct arg){ \ 1150 .offset = offsetof(s, f), \ 1151 .size = sizeof(((s *)0)->f), \ 1152 .mask = (const void *)(m), \ 1153 }) 1154 1155 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ 1156 #define ARGS_ENTRY_MASK_HTON(s, f, m) \ 1157 (&(const struct arg){ \ 1158 .hton = 1, \ 1159 .offset = offsetof(s, f), \ 1160 .size = sizeof(((s *)0)->f), \ 1161 .mask = (const void *)(m), \ 1162 }) 1163 1164 /** Static initializer for ARGS() to target a pointer. */ 1165 #define ARGS_ENTRY_PTR(s, f) \ 1166 (&(const struct arg){ \ 1167 .size = sizeof(*((s *)0)->f), \ 1168 }) 1169 1170 /** Static initializer for ARGS() with arbitrary offset and size. */ 1171 #define ARGS_ENTRY_ARB(o, s) \ 1172 (&(const struct arg){ \ 1173 .offset = (o), \ 1174 .size = (s), \ 1175 }) 1176 1177 /** Same as ARGS_ENTRY_ARB() with bounded values. */ 1178 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ 1179 (&(const struct arg){ \ 1180 .bounded = 1, \ 1181 .min = (i), \ 1182 .max = (a), \ 1183 .offset = (o), \ 1184 .size = (s), \ 1185 }) 1186 1187 /** Same as ARGS_ENTRY() using network byte ordering. */ 1188 #define ARGS_ENTRY_HTON(s, f) \ 1189 (&(const struct arg){ \ 1190 .hton = 1, \ 1191 .offset = offsetof(s, f), \ 1192 .size = sizeof(((s *)0)->f), \ 1193 }) 1194 1195 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ 1196 #define ARG_ENTRY_HTON(s) \ 1197 (&(const struct arg){ \ 1198 .hton = 1, \ 1199 .offset = 0, \ 1200 .size = sizeof(s), \ 1201 }) 1202 1203 /** Parser output buffer layout expected by cmd_flow_parsed(). */ 1204 struct buffer { 1205 enum index command; /**< Flow command. */ 1206 portid_t port; /**< Affected port ID. */ 1207 queueid_t queue; /** Async queue ID. */ 1208 bool postpone; /** Postpone async operation */ 1209 union { 1210 struct { 1211 struct rte_flow_port_attr port_attr; 1212 uint32_t nb_queue; 1213 struct rte_flow_queue_attr queue_attr; 1214 } configure; /**< Configuration arguments. */ 1215 struct { 1216 uint32_t *template_id; 1217 uint32_t template_id_n; 1218 } templ_destroy; /**< Template destroy arguments. */ 1219 struct { 1220 uint32_t id; 1221 struct rte_flow_template_table_attr attr; 1222 uint32_t *pat_templ_id; 1223 uint32_t pat_templ_id_n; 1224 uint32_t *act_templ_id; 1225 uint32_t act_templ_id_n; 1226 } table; /**< Table arguments. */ 1227 struct { 1228 uint32_t *table_id; 1229 uint32_t table_id_n; 1230 } table_destroy; /**< Template destroy arguments. */ 1231 struct { 1232 uint32_t *action_id; 1233 uint32_t action_id_n; 1234 } ia_destroy; /**< Indirect action destroy arguments. */ 1235 struct { 1236 uint32_t action_id; 1237 enum rte_flow_query_update_mode qu_mode; 1238 } ia; /* Indirect action query arguments */ 1239 struct { 1240 uint32_t table_id; 1241 uint32_t pat_templ_id; 1242 uint32_t rule_id; 1243 uint32_t act_templ_id; 1244 struct rte_flow_attr attr; 1245 struct tunnel_ops tunnel_ops; 1246 uintptr_t user_id; 1247 struct rte_flow_item *pattern; 1248 struct rte_flow_action *actions; 1249 struct rte_flow_action *masks; 1250 uint32_t pattern_n; 1251 uint32_t actions_n; 1252 uint8_t *data; 1253 enum rte_flow_encap_hash_field field; 1254 uint8_t encap_hash; 1255 } vc; /**< Validate/create arguments. */ 1256 struct { 1257 uint64_t *rule; 1258 uint64_t rule_n; 1259 bool is_user_id; 1260 } destroy; /**< Destroy arguments. */ 1261 struct { 1262 char file[128]; 1263 bool mode; 1264 uint64_t rule; 1265 bool is_user_id; 1266 } dump; /**< Dump arguments. */ 1267 struct { 1268 uint64_t rule; 1269 struct rte_flow_action action; 1270 bool is_user_id; 1271 } query; /**< Query arguments. */ 1272 struct { 1273 uint32_t *group; 1274 uint32_t group_n; 1275 } list; /**< List arguments. */ 1276 struct { 1277 int set; 1278 } isolate; /**< Isolated mode arguments. */ 1279 struct { 1280 int destroy; 1281 } aged; /**< Aged arguments. */ 1282 struct { 1283 uint32_t policy_id; 1284 } policy;/**< Policy arguments. */ 1285 struct { 1286 uint16_t token; 1287 uintptr_t uintptr; 1288 char filename[128]; 1289 } flex; /**< Flex arguments*/ 1290 } args; /**< Command arguments. */ 1291 }; 1292 1293 /** Private data for pattern items. */ 1294 struct parse_item_priv { 1295 enum rte_flow_item_type type; /**< Item type. */ 1296 uint32_t size; /**< Size of item specification structure. */ 1297 }; 1298 1299 #define PRIV_ITEM(t, s) \ 1300 (&(const struct parse_item_priv){ \ 1301 .type = RTE_FLOW_ITEM_TYPE_ ## t, \ 1302 .size = s, \ 1303 }) 1304 1305 /** Private data for actions. */ 1306 struct parse_action_priv { 1307 enum rte_flow_action_type type; /**< Action type. */ 1308 uint32_t size; /**< Size of action configuration structure. */ 1309 }; 1310 1311 #define PRIV_ACTION(t, s) \ 1312 (&(const struct parse_action_priv){ \ 1313 .type = RTE_FLOW_ACTION_TYPE_ ## t, \ 1314 .size = s, \ 1315 }) 1316 1317 static const enum index next_flex_item[] = { 1318 FLEX_ITEM_CREATE, 1319 FLEX_ITEM_DESTROY, 1320 ZERO, 1321 }; 1322 1323 static const enum index next_config_attr[] = { 1324 CONFIG_QUEUES_NUMBER, 1325 CONFIG_QUEUES_SIZE, 1326 CONFIG_COUNTERS_NUMBER, 1327 CONFIG_AGING_OBJECTS_NUMBER, 1328 CONFIG_METERS_NUMBER, 1329 CONFIG_CONN_TRACK_NUMBER, 1330 CONFIG_QUOTAS_NUMBER, 1331 CONFIG_FLAGS, 1332 CONFIG_HOST_PORT, 1333 END, 1334 ZERO, 1335 }; 1336 1337 static const enum index next_pt_subcmd[] = { 1338 PATTERN_TEMPLATE_CREATE, 1339 PATTERN_TEMPLATE_DESTROY, 1340 ZERO, 1341 }; 1342 1343 static const enum index next_pt_attr[] = { 1344 PATTERN_TEMPLATE_CREATE_ID, 1345 PATTERN_TEMPLATE_RELAXED_MATCHING, 1346 PATTERN_TEMPLATE_INGRESS, 1347 PATTERN_TEMPLATE_EGRESS, 1348 PATTERN_TEMPLATE_TRANSFER, 1349 PATTERN_TEMPLATE_SPEC, 1350 ZERO, 1351 }; 1352 1353 static const enum index next_pt_destroy_attr[] = { 1354 PATTERN_TEMPLATE_DESTROY_ID, 1355 END, 1356 ZERO, 1357 }; 1358 1359 static const enum index next_at_subcmd[] = { 1360 ACTIONS_TEMPLATE_CREATE, 1361 ACTIONS_TEMPLATE_DESTROY, 1362 ZERO, 1363 }; 1364 1365 static const enum index next_at_attr[] = { 1366 ACTIONS_TEMPLATE_CREATE_ID, 1367 ACTIONS_TEMPLATE_INGRESS, 1368 ACTIONS_TEMPLATE_EGRESS, 1369 ACTIONS_TEMPLATE_TRANSFER, 1370 ACTIONS_TEMPLATE_SPEC, 1371 ZERO, 1372 }; 1373 1374 static const enum index next_at_destroy_attr[] = { 1375 ACTIONS_TEMPLATE_DESTROY_ID, 1376 END, 1377 ZERO, 1378 }; 1379 1380 static const enum index next_group_attr[] = { 1381 GROUP_INGRESS, 1382 GROUP_EGRESS, 1383 GROUP_TRANSFER, 1384 GROUP_SET_MISS_ACTIONS, 1385 ZERO, 1386 }; 1387 1388 static const enum index next_table_subcmd[] = { 1389 TABLE_CREATE, 1390 TABLE_DESTROY, 1391 TABLE_RESIZE, 1392 TABLE_RESIZE_COMPLETE, 1393 ZERO, 1394 }; 1395 1396 static const enum index next_table_attr[] = { 1397 TABLE_CREATE_ID, 1398 TABLE_GROUP, 1399 TABLE_INSERTION_TYPE, 1400 TABLE_HASH_FUNC, 1401 TABLE_PRIORITY, 1402 TABLE_INGRESS, 1403 TABLE_EGRESS, 1404 TABLE_TRANSFER, 1405 TABLE_TRANSFER_WIRE_ORIG, 1406 TABLE_TRANSFER_VPORT_ORIG, 1407 TABLE_RESIZABLE, 1408 TABLE_RULES_NUMBER, 1409 TABLE_PATTERN_TEMPLATE, 1410 TABLE_ACTIONS_TEMPLATE, 1411 END, 1412 ZERO, 1413 }; 1414 1415 static const enum index next_table_destroy_attr[] = { 1416 TABLE_DESTROY_ID, 1417 END, 1418 ZERO, 1419 }; 1420 1421 static const enum index next_queue_subcmd[] = { 1422 QUEUE_CREATE, 1423 QUEUE_DESTROY, 1424 QUEUE_FLOW_UPDATE_RESIZED, 1425 QUEUE_UPDATE, 1426 QUEUE_AGED, 1427 QUEUE_INDIRECT_ACTION, 1428 ZERO, 1429 }; 1430 1431 static const enum index next_queue_destroy_attr[] = { 1432 QUEUE_DESTROY_ID, 1433 END, 1434 ZERO, 1435 }; 1436 1437 static const enum index next_qia_subcmd[] = { 1438 QUEUE_INDIRECT_ACTION_CREATE, 1439 QUEUE_INDIRECT_ACTION_UPDATE, 1440 QUEUE_INDIRECT_ACTION_DESTROY, 1441 QUEUE_INDIRECT_ACTION_QUERY, 1442 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 1443 ZERO, 1444 }; 1445 1446 static const enum index next_qia_create_attr[] = { 1447 QUEUE_INDIRECT_ACTION_CREATE_ID, 1448 QUEUE_INDIRECT_ACTION_INGRESS, 1449 QUEUE_INDIRECT_ACTION_EGRESS, 1450 QUEUE_INDIRECT_ACTION_TRANSFER, 1451 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 1452 QUEUE_INDIRECT_ACTION_SPEC, 1453 QUEUE_INDIRECT_ACTION_LIST, 1454 ZERO, 1455 }; 1456 1457 static const enum index next_qia_update_attr[] = { 1458 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1459 QUEUE_INDIRECT_ACTION_SPEC, 1460 ZERO, 1461 }; 1462 1463 static const enum index next_qia_destroy_attr[] = { 1464 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 1465 QUEUE_INDIRECT_ACTION_DESTROY_ID, 1466 END, 1467 ZERO, 1468 }; 1469 1470 static const enum index next_qia_query_attr[] = { 1471 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 1472 END, 1473 ZERO, 1474 }; 1475 1476 static const enum index next_ia_create_attr[] = { 1477 INDIRECT_ACTION_CREATE_ID, 1478 INDIRECT_ACTION_INGRESS, 1479 INDIRECT_ACTION_EGRESS, 1480 INDIRECT_ACTION_TRANSFER, 1481 INDIRECT_ACTION_SPEC, 1482 INDIRECT_ACTION_LIST, 1483 INDIRECT_ACTION_FLOW_CONF, 1484 ZERO, 1485 }; 1486 1487 static const enum index next_ia[] = { 1488 INDIRECT_ACTION_ID2PTR, 1489 ACTION_NEXT, 1490 ZERO 1491 }; 1492 1493 static const enum index next_ial[] = { 1494 ACTION_INDIRECT_LIST_HANDLE, 1495 ACTION_INDIRECT_LIST_CONF, 1496 ACTION_NEXT, 1497 ZERO 1498 }; 1499 1500 static const enum index next_qia_qu_attr[] = { 1501 QUEUE_INDIRECT_ACTION_QU_MODE, 1502 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1503 INDIRECT_ACTION_SPEC, 1504 ZERO 1505 }; 1506 1507 static const enum index next_ia_qu_attr[] = { 1508 INDIRECT_ACTION_QU_MODE, 1509 INDIRECT_ACTION_SPEC, 1510 ZERO 1511 }; 1512 1513 static const enum index next_dump_subcmd[] = { 1514 DUMP_ALL, 1515 DUMP_ONE, 1516 DUMP_IS_USER_ID, 1517 ZERO, 1518 }; 1519 1520 static const enum index next_ia_subcmd[] = { 1521 INDIRECT_ACTION_CREATE, 1522 INDIRECT_ACTION_UPDATE, 1523 INDIRECT_ACTION_DESTROY, 1524 INDIRECT_ACTION_QUERY, 1525 INDIRECT_ACTION_QUERY_UPDATE, 1526 ZERO, 1527 }; 1528 1529 static const enum index next_vc_attr[] = { 1530 VC_GROUP, 1531 VC_PRIORITY, 1532 VC_INGRESS, 1533 VC_EGRESS, 1534 VC_TRANSFER, 1535 VC_TUNNEL_SET, 1536 VC_TUNNEL_MATCH, 1537 VC_USER_ID, 1538 ITEM_PATTERN, 1539 ZERO, 1540 }; 1541 1542 static const enum index next_destroy_attr[] = { 1543 DESTROY_RULE, 1544 DESTROY_IS_USER_ID, 1545 END, 1546 ZERO, 1547 }; 1548 1549 static const enum index next_dump_attr[] = { 1550 COMMON_FILE_PATH, 1551 END, 1552 ZERO, 1553 }; 1554 1555 static const enum index next_query_attr[] = { 1556 QUERY_IS_USER_ID, 1557 END, 1558 ZERO, 1559 }; 1560 1561 static const enum index next_list_attr[] = { 1562 LIST_GROUP, 1563 END, 1564 ZERO, 1565 }; 1566 1567 static const enum index next_aged_attr[] = { 1568 AGED_DESTROY, 1569 END, 1570 ZERO, 1571 }; 1572 1573 static const enum index next_ia_destroy_attr[] = { 1574 INDIRECT_ACTION_DESTROY_ID, 1575 END, 1576 ZERO, 1577 }; 1578 1579 static const enum index next_async_insert_subcmd[] = { 1580 QUEUE_PATTERN_TEMPLATE, 1581 QUEUE_RULE_ID, 1582 ZERO, 1583 }; 1584 1585 static const enum index next_async_pattern_subcmd[] = { 1586 QUEUE_PATTERN_TEMPLATE, 1587 QUEUE_ACTIONS_TEMPLATE, 1588 ZERO, 1589 }; 1590 1591 static const enum index item_param[] = { 1592 ITEM_PARAM_IS, 1593 ITEM_PARAM_SPEC, 1594 ITEM_PARAM_LAST, 1595 ITEM_PARAM_MASK, 1596 ITEM_PARAM_PREFIX, 1597 ZERO, 1598 }; 1599 1600 static const enum index next_item[] = { 1601 ITEM_END, 1602 ITEM_VOID, 1603 ITEM_INVERT, 1604 ITEM_ANY, 1605 ITEM_PORT_ID, 1606 ITEM_MARK, 1607 ITEM_RAW, 1608 ITEM_ETH, 1609 ITEM_VLAN, 1610 ITEM_IPV4, 1611 ITEM_IPV6, 1612 ITEM_ICMP, 1613 ITEM_UDP, 1614 ITEM_TCP, 1615 ITEM_SCTP, 1616 ITEM_VXLAN, 1617 ITEM_E_TAG, 1618 ITEM_NVGRE, 1619 ITEM_MPLS, 1620 ITEM_GRE, 1621 ITEM_FUZZY, 1622 ITEM_GTP, 1623 ITEM_GTPC, 1624 ITEM_GTPU, 1625 ITEM_GENEVE, 1626 ITEM_VXLAN_GPE, 1627 ITEM_ARP_ETH_IPV4, 1628 ITEM_IPV6_EXT, 1629 ITEM_IPV6_FRAG_EXT, 1630 ITEM_IPV6_ROUTING_EXT, 1631 ITEM_ICMP6, 1632 ITEM_ICMP6_ECHO_REQUEST, 1633 ITEM_ICMP6_ECHO_REPLY, 1634 ITEM_ICMP6_ND_NS, 1635 ITEM_ICMP6_ND_NA, 1636 ITEM_ICMP6_ND_OPT, 1637 ITEM_ICMP6_ND_OPT_SLA_ETH, 1638 ITEM_ICMP6_ND_OPT_TLA_ETH, 1639 ITEM_META, 1640 ITEM_RANDOM, 1641 ITEM_GRE_KEY, 1642 ITEM_GRE_OPTION, 1643 ITEM_GTP_PSC, 1644 ITEM_PPPOES, 1645 ITEM_PPPOED, 1646 ITEM_PPPOE_PROTO_ID, 1647 ITEM_HIGIG2, 1648 ITEM_TAG, 1649 ITEM_L2TPV3OIP, 1650 ITEM_ESP, 1651 ITEM_AH, 1652 ITEM_PFCP, 1653 ITEM_ECPRI, 1654 ITEM_GENEVE_OPT, 1655 ITEM_INTEGRITY, 1656 ITEM_CONNTRACK, 1657 ITEM_PORT_REPRESENTOR, 1658 ITEM_REPRESENTED_PORT, 1659 ITEM_FLEX, 1660 ITEM_L2TPV2, 1661 ITEM_PPP, 1662 ITEM_METER, 1663 ITEM_QUOTA, 1664 ITEM_AGGR_AFFINITY, 1665 ITEM_TX_QUEUE, 1666 ITEM_IB_BTH, 1667 ITEM_PTYPE, 1668 ITEM_NSH, 1669 ITEM_COMPARE, 1670 END_SET, 1671 ZERO, 1672 }; 1673 1674 static const enum index item_fuzzy[] = { 1675 ITEM_FUZZY_THRESH, 1676 ITEM_NEXT, 1677 ZERO, 1678 }; 1679 1680 static const enum index item_any[] = { 1681 ITEM_ANY_NUM, 1682 ITEM_NEXT, 1683 ZERO, 1684 }; 1685 1686 static const enum index item_port_id[] = { 1687 ITEM_PORT_ID_ID, 1688 ITEM_NEXT, 1689 ZERO, 1690 }; 1691 1692 static const enum index item_mark[] = { 1693 ITEM_MARK_ID, 1694 ITEM_NEXT, 1695 ZERO, 1696 }; 1697 1698 static const enum index item_raw[] = { 1699 ITEM_RAW_RELATIVE, 1700 ITEM_RAW_SEARCH, 1701 ITEM_RAW_OFFSET, 1702 ITEM_RAW_LIMIT, 1703 ITEM_RAW_PATTERN, 1704 ITEM_RAW_PATTERN_HEX, 1705 ITEM_NEXT, 1706 ZERO, 1707 }; 1708 1709 static const enum index item_eth[] = { 1710 ITEM_ETH_DST, 1711 ITEM_ETH_SRC, 1712 ITEM_ETH_TYPE, 1713 ITEM_ETH_HAS_VLAN, 1714 ITEM_NEXT, 1715 ZERO, 1716 }; 1717 1718 static const enum index item_vlan[] = { 1719 ITEM_VLAN_TCI, 1720 ITEM_VLAN_PCP, 1721 ITEM_VLAN_DEI, 1722 ITEM_VLAN_VID, 1723 ITEM_VLAN_INNER_TYPE, 1724 ITEM_VLAN_HAS_MORE_VLAN, 1725 ITEM_NEXT, 1726 ZERO, 1727 }; 1728 1729 static const enum index item_ipv4[] = { 1730 ITEM_IPV4_VER_IHL, 1731 ITEM_IPV4_TOS, 1732 ITEM_IPV4_LENGTH, 1733 ITEM_IPV4_ID, 1734 ITEM_IPV4_FRAGMENT_OFFSET, 1735 ITEM_IPV4_TTL, 1736 ITEM_IPV4_PROTO, 1737 ITEM_IPV4_SRC, 1738 ITEM_IPV4_DST, 1739 ITEM_NEXT, 1740 ZERO, 1741 }; 1742 1743 static const enum index item_ipv6[] = { 1744 ITEM_IPV6_TC, 1745 ITEM_IPV6_FLOW, 1746 ITEM_IPV6_LEN, 1747 ITEM_IPV6_PROTO, 1748 ITEM_IPV6_HOP, 1749 ITEM_IPV6_SRC, 1750 ITEM_IPV6_DST, 1751 ITEM_IPV6_HAS_FRAG_EXT, 1752 ITEM_IPV6_ROUTING_EXT, 1753 ITEM_NEXT, 1754 ZERO, 1755 }; 1756 1757 static const enum index item_ipv6_routing_ext[] = { 1758 ITEM_IPV6_ROUTING_EXT_TYPE, 1759 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 1760 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 1761 ITEM_NEXT, 1762 ZERO, 1763 }; 1764 1765 static const enum index item_icmp[] = { 1766 ITEM_ICMP_TYPE, 1767 ITEM_ICMP_CODE, 1768 ITEM_ICMP_IDENT, 1769 ITEM_ICMP_SEQ, 1770 ITEM_NEXT, 1771 ZERO, 1772 }; 1773 1774 static const enum index item_udp[] = { 1775 ITEM_UDP_SRC, 1776 ITEM_UDP_DST, 1777 ITEM_NEXT, 1778 ZERO, 1779 }; 1780 1781 static const enum index item_tcp[] = { 1782 ITEM_TCP_SRC, 1783 ITEM_TCP_DST, 1784 ITEM_TCP_FLAGS, 1785 ITEM_NEXT, 1786 ZERO, 1787 }; 1788 1789 static const enum index item_sctp[] = { 1790 ITEM_SCTP_SRC, 1791 ITEM_SCTP_DST, 1792 ITEM_SCTP_TAG, 1793 ITEM_SCTP_CKSUM, 1794 ITEM_NEXT, 1795 ZERO, 1796 }; 1797 1798 static const enum index item_vxlan[] = { 1799 ITEM_VXLAN_VNI, 1800 ITEM_VXLAN_FLAG_G, 1801 ITEM_VXLAN_FLAG_VER, 1802 ITEM_VXLAN_FLAG_I, 1803 ITEM_VXLAN_FLAG_P, 1804 ITEM_VXLAN_FLAG_B, 1805 ITEM_VXLAN_FLAG_O, 1806 ITEM_VXLAN_FLAG_D, 1807 ITEM_VXLAN_FLAG_A, 1808 ITEM_VXLAN_GBP_ID, 1809 ITEM_VXLAN_GPE_PROTO, 1810 ITEM_VXLAN_FIRST_RSVD, 1811 ITEM_VXLAN_SECND_RSVD, 1812 ITEM_VXLAN_THIRD_RSVD, 1813 ITEM_VXLAN_LAST_RSVD, 1814 ITEM_NEXT, 1815 ZERO, 1816 }; 1817 1818 static const enum index item_e_tag[] = { 1819 ITEM_E_TAG_GRP_ECID_B, 1820 ITEM_NEXT, 1821 ZERO, 1822 }; 1823 1824 static const enum index item_nvgre[] = { 1825 ITEM_NVGRE_TNI, 1826 ITEM_NEXT, 1827 ZERO, 1828 }; 1829 1830 static const enum index item_mpls[] = { 1831 ITEM_MPLS_LABEL, 1832 ITEM_MPLS_TC, 1833 ITEM_MPLS_S, 1834 ITEM_MPLS_TTL, 1835 ITEM_NEXT, 1836 ZERO, 1837 }; 1838 1839 static const enum index item_gre[] = { 1840 ITEM_GRE_PROTO, 1841 ITEM_GRE_C_RSVD0_VER, 1842 ITEM_GRE_C_BIT, 1843 ITEM_GRE_K_BIT, 1844 ITEM_GRE_S_BIT, 1845 ITEM_NEXT, 1846 ZERO, 1847 }; 1848 1849 static const enum index item_gre_key[] = { 1850 ITEM_GRE_KEY_VALUE, 1851 ITEM_NEXT, 1852 ZERO, 1853 }; 1854 1855 static const enum index item_gre_option[] = { 1856 ITEM_GRE_OPTION_CHECKSUM, 1857 ITEM_GRE_OPTION_KEY, 1858 ITEM_GRE_OPTION_SEQUENCE, 1859 ITEM_NEXT, 1860 ZERO, 1861 }; 1862 1863 static const enum index item_gtp[] = { 1864 ITEM_GTP_FLAGS, 1865 ITEM_GTP_MSG_TYPE, 1866 ITEM_GTP_TEID, 1867 ITEM_NEXT, 1868 ZERO, 1869 }; 1870 1871 static const enum index item_geneve[] = { 1872 ITEM_GENEVE_VNI, 1873 ITEM_GENEVE_PROTO, 1874 ITEM_GENEVE_OPTLEN, 1875 ITEM_NEXT, 1876 ZERO, 1877 }; 1878 1879 static const enum index item_vxlan_gpe[] = { 1880 ITEM_VXLAN_GPE_VNI, 1881 ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR, 1882 ITEM_VXLAN_GPE_FLAGS, 1883 ITEM_VXLAN_GPE_RSVD0, 1884 ITEM_VXLAN_GPE_RSVD1, 1885 ITEM_NEXT, 1886 ZERO, 1887 }; 1888 1889 static const enum index item_arp_eth_ipv4[] = { 1890 ITEM_ARP_ETH_IPV4_SHA, 1891 ITEM_ARP_ETH_IPV4_SPA, 1892 ITEM_ARP_ETH_IPV4_THA, 1893 ITEM_ARP_ETH_IPV4_TPA, 1894 ITEM_NEXT, 1895 ZERO, 1896 }; 1897 1898 static const enum index item_ipv6_ext[] = { 1899 ITEM_IPV6_EXT_NEXT_HDR, 1900 ITEM_NEXT, 1901 ZERO, 1902 }; 1903 1904 static const enum index item_ipv6_frag_ext[] = { 1905 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 1906 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 1907 ITEM_IPV6_FRAG_EXT_ID, 1908 ITEM_NEXT, 1909 ZERO, 1910 }; 1911 1912 static const enum index item_icmp6[] = { 1913 ITEM_ICMP6_TYPE, 1914 ITEM_ICMP6_CODE, 1915 ITEM_NEXT, 1916 ZERO, 1917 }; 1918 1919 static const enum index item_icmp6_echo_request[] = { 1920 ITEM_ICMP6_ECHO_REQUEST_ID, 1921 ITEM_ICMP6_ECHO_REQUEST_SEQ, 1922 ITEM_NEXT, 1923 ZERO, 1924 }; 1925 1926 static const enum index item_icmp6_echo_reply[] = { 1927 ITEM_ICMP6_ECHO_REPLY_ID, 1928 ITEM_ICMP6_ECHO_REPLY_SEQ, 1929 ITEM_NEXT, 1930 ZERO, 1931 }; 1932 1933 static const enum index item_icmp6_nd_ns[] = { 1934 ITEM_ICMP6_ND_NS_TARGET_ADDR, 1935 ITEM_NEXT, 1936 ZERO, 1937 }; 1938 1939 static const enum index item_icmp6_nd_na[] = { 1940 ITEM_ICMP6_ND_NA_TARGET_ADDR, 1941 ITEM_NEXT, 1942 ZERO, 1943 }; 1944 1945 static const enum index item_icmp6_nd_opt[] = { 1946 ITEM_ICMP6_ND_OPT_TYPE, 1947 ITEM_NEXT, 1948 ZERO, 1949 }; 1950 1951 static const enum index item_icmp6_nd_opt_sla_eth[] = { 1952 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 1953 ITEM_NEXT, 1954 ZERO, 1955 }; 1956 1957 static const enum index item_icmp6_nd_opt_tla_eth[] = { 1958 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 1959 ITEM_NEXT, 1960 ZERO, 1961 }; 1962 1963 static const enum index item_meta[] = { 1964 ITEM_META_DATA, 1965 ITEM_NEXT, 1966 ZERO, 1967 }; 1968 1969 static const enum index item_random[] = { 1970 ITEM_RANDOM_VALUE, 1971 ITEM_NEXT, 1972 ZERO, 1973 }; 1974 1975 static const enum index item_gtp_psc[] = { 1976 ITEM_GTP_PSC_QFI, 1977 ITEM_GTP_PSC_PDU_T, 1978 ITEM_NEXT, 1979 ZERO, 1980 }; 1981 1982 static const enum index item_pppoed[] = { 1983 ITEM_PPPOE_SEID, 1984 ITEM_NEXT, 1985 ZERO, 1986 }; 1987 1988 static const enum index item_pppoes[] = { 1989 ITEM_PPPOE_SEID, 1990 ITEM_NEXT, 1991 ZERO, 1992 }; 1993 1994 static const enum index item_pppoe_proto_id[] = { 1995 ITEM_NEXT, 1996 ZERO, 1997 }; 1998 1999 static const enum index item_higig2[] = { 2000 ITEM_HIGIG2_CLASSIFICATION, 2001 ITEM_HIGIG2_VID, 2002 ITEM_NEXT, 2003 ZERO, 2004 }; 2005 2006 static const enum index item_esp[] = { 2007 ITEM_ESP_SPI, 2008 ITEM_NEXT, 2009 ZERO, 2010 }; 2011 2012 static const enum index item_ah[] = { 2013 ITEM_AH_SPI, 2014 ITEM_NEXT, 2015 ZERO, 2016 }; 2017 2018 static const enum index item_pfcp[] = { 2019 ITEM_PFCP_S_FIELD, 2020 ITEM_PFCP_SEID, 2021 ITEM_NEXT, 2022 ZERO, 2023 }; 2024 2025 static const enum index next_set_raw[] = { 2026 SET_RAW_INDEX, 2027 ITEM_ETH, 2028 ZERO, 2029 }; 2030 2031 static const enum index item_tag[] = { 2032 ITEM_TAG_DATA, 2033 ITEM_TAG_INDEX, 2034 ITEM_NEXT, 2035 ZERO, 2036 }; 2037 2038 static const enum index item_l2tpv3oip[] = { 2039 ITEM_L2TPV3OIP_SESSION_ID, 2040 ITEM_NEXT, 2041 ZERO, 2042 }; 2043 2044 static const enum index item_ecpri[] = { 2045 ITEM_ECPRI_COMMON, 2046 ITEM_NEXT, 2047 ZERO, 2048 }; 2049 2050 static const enum index item_ecpri_common[] = { 2051 ITEM_ECPRI_COMMON_TYPE, 2052 ZERO, 2053 }; 2054 2055 static const enum index item_ecpri_common_type[] = { 2056 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 2057 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 2058 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 2059 ZERO, 2060 }; 2061 2062 static const enum index item_geneve_opt[] = { 2063 ITEM_GENEVE_OPT_CLASS, 2064 ITEM_GENEVE_OPT_TYPE, 2065 ITEM_GENEVE_OPT_LENGTH, 2066 ITEM_GENEVE_OPT_DATA, 2067 ITEM_NEXT, 2068 ZERO, 2069 }; 2070 2071 static const enum index item_integrity[] = { 2072 ITEM_INTEGRITY_LEVEL, 2073 ITEM_INTEGRITY_VALUE, 2074 ZERO, 2075 }; 2076 2077 static const enum index item_integrity_lv[] = { 2078 ITEM_INTEGRITY_LEVEL, 2079 ITEM_INTEGRITY_VALUE, 2080 ITEM_NEXT, 2081 ZERO, 2082 }; 2083 2084 static const enum index item_port_representor[] = { 2085 ITEM_PORT_REPRESENTOR_PORT_ID, 2086 ITEM_NEXT, 2087 ZERO, 2088 }; 2089 2090 static const enum index item_represented_port[] = { 2091 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 2092 ITEM_NEXT, 2093 ZERO, 2094 }; 2095 2096 static const enum index item_flex[] = { 2097 ITEM_FLEX_PATTERN_HANDLE, 2098 ITEM_FLEX_ITEM_HANDLE, 2099 ITEM_NEXT, 2100 ZERO, 2101 }; 2102 2103 static const enum index item_l2tpv2[] = { 2104 ITEM_L2TPV2_TYPE, 2105 ITEM_NEXT, 2106 ZERO, 2107 }; 2108 2109 static const enum index item_l2tpv2_type[] = { 2110 ITEM_L2TPV2_TYPE_DATA, 2111 ITEM_L2TPV2_TYPE_DATA_L, 2112 ITEM_L2TPV2_TYPE_DATA_S, 2113 ITEM_L2TPV2_TYPE_DATA_O, 2114 ITEM_L2TPV2_TYPE_DATA_L_S, 2115 ITEM_L2TPV2_TYPE_CTRL, 2116 ZERO, 2117 }; 2118 2119 static const enum index item_l2tpv2_type_data[] = { 2120 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 2121 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 2122 ITEM_NEXT, 2123 ZERO, 2124 }; 2125 2126 static const enum index item_l2tpv2_type_data_l[] = { 2127 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 2128 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 2129 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 2130 ITEM_NEXT, 2131 ZERO, 2132 }; 2133 2134 static const enum index item_l2tpv2_type_data_s[] = { 2135 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 2136 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 2137 ITEM_L2TPV2_MSG_DATA_S_NS, 2138 ITEM_L2TPV2_MSG_DATA_S_NR, 2139 ITEM_NEXT, 2140 ZERO, 2141 }; 2142 2143 static const enum index item_l2tpv2_type_data_o[] = { 2144 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 2145 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 2146 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 2147 ITEM_NEXT, 2148 ZERO, 2149 }; 2150 2151 static const enum index item_l2tpv2_type_data_l_s[] = { 2152 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 2153 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 2154 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 2155 ITEM_L2TPV2_MSG_DATA_L_S_NS, 2156 ITEM_L2TPV2_MSG_DATA_L_S_NR, 2157 ITEM_NEXT, 2158 ZERO, 2159 }; 2160 2161 static const enum index item_l2tpv2_type_ctrl[] = { 2162 ITEM_L2TPV2_MSG_CTRL_LENGTH, 2163 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 2164 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 2165 ITEM_L2TPV2_MSG_CTRL_NS, 2166 ITEM_L2TPV2_MSG_CTRL_NR, 2167 ITEM_NEXT, 2168 ZERO, 2169 }; 2170 2171 static const enum index item_ppp[] = { 2172 ITEM_PPP_ADDR, 2173 ITEM_PPP_CTRL, 2174 ITEM_PPP_PROTO_ID, 2175 ITEM_NEXT, 2176 ZERO, 2177 }; 2178 2179 static const enum index item_meter[] = { 2180 ITEM_METER_COLOR, 2181 ITEM_NEXT, 2182 ZERO, 2183 }; 2184 2185 static const enum index item_quota[] = { 2186 ITEM_QUOTA_STATE, 2187 ITEM_NEXT, 2188 ZERO, 2189 }; 2190 2191 static const enum index item_aggr_affinity[] = { 2192 ITEM_AGGR_AFFINITY_VALUE, 2193 ITEM_NEXT, 2194 ZERO, 2195 }; 2196 2197 static const enum index item_tx_queue[] = { 2198 ITEM_TX_QUEUE_VALUE, 2199 ITEM_NEXT, 2200 ZERO, 2201 }; 2202 2203 static const enum index item_ib_bth[] = { 2204 ITEM_IB_BTH_OPCODE, 2205 ITEM_IB_BTH_PKEY, 2206 ITEM_IB_BTH_DST_QPN, 2207 ITEM_IB_BTH_PSN, 2208 ITEM_NEXT, 2209 ZERO, 2210 }; 2211 2212 static const enum index item_ptype[] = { 2213 ITEM_PTYPE_VALUE, 2214 ITEM_NEXT, 2215 ZERO, 2216 }; 2217 2218 static const enum index item_nsh[] = { 2219 ITEM_NEXT, 2220 ZERO, 2221 }; 2222 2223 static const enum index item_compare_field[] = { 2224 ITEM_COMPARE_OP, 2225 ITEM_COMPARE_FIELD_A_TYPE, 2226 ITEM_COMPARE_FIELD_B_TYPE, 2227 ITEM_NEXT, 2228 ZERO, 2229 }; 2230 2231 static const enum index compare_field_a[] = { 2232 ITEM_COMPARE_FIELD_A_TYPE, 2233 ITEM_COMPARE_FIELD_A_LEVEL, 2234 ITEM_COMPARE_FIELD_A_TAG_INDEX, 2235 ITEM_COMPARE_FIELD_A_TYPE_ID, 2236 ITEM_COMPARE_FIELD_A_CLASS_ID, 2237 ITEM_COMPARE_FIELD_A_OFFSET, 2238 ITEM_COMPARE_FIELD_B_TYPE, 2239 ZERO, 2240 }; 2241 2242 static const enum index compare_field_b[] = { 2243 ITEM_COMPARE_FIELD_B_TYPE, 2244 ITEM_COMPARE_FIELD_B_LEVEL, 2245 ITEM_COMPARE_FIELD_B_TAG_INDEX, 2246 ITEM_COMPARE_FIELD_B_TYPE_ID, 2247 ITEM_COMPARE_FIELD_B_CLASS_ID, 2248 ITEM_COMPARE_FIELD_B_OFFSET, 2249 ITEM_COMPARE_FIELD_B_VALUE, 2250 ITEM_COMPARE_FIELD_B_POINTER, 2251 ITEM_COMPARE_FIELD_WIDTH, 2252 ZERO, 2253 }; 2254 2255 static const enum index next_action[] = { 2256 ACTION_END, 2257 ACTION_VOID, 2258 ACTION_PASSTHRU, 2259 ACTION_SKIP_CMAN, 2260 ACTION_JUMP, 2261 ACTION_MARK, 2262 ACTION_FLAG, 2263 ACTION_QUEUE, 2264 ACTION_DROP, 2265 ACTION_COUNT, 2266 ACTION_RSS, 2267 ACTION_PF, 2268 ACTION_VF, 2269 ACTION_PORT_ID, 2270 ACTION_METER, 2271 ACTION_METER_COLOR, 2272 ACTION_METER_MARK, 2273 ACTION_OF_DEC_NW_TTL, 2274 ACTION_OF_POP_VLAN, 2275 ACTION_OF_PUSH_VLAN, 2276 ACTION_OF_SET_VLAN_VID, 2277 ACTION_OF_SET_VLAN_PCP, 2278 ACTION_OF_POP_MPLS, 2279 ACTION_OF_PUSH_MPLS, 2280 ACTION_VXLAN_ENCAP, 2281 ACTION_VXLAN_DECAP, 2282 ACTION_NVGRE_ENCAP, 2283 ACTION_NVGRE_DECAP, 2284 ACTION_L2_ENCAP, 2285 ACTION_L2_DECAP, 2286 ACTION_MPLSOGRE_ENCAP, 2287 ACTION_MPLSOGRE_DECAP, 2288 ACTION_MPLSOUDP_ENCAP, 2289 ACTION_MPLSOUDP_DECAP, 2290 ACTION_SET_IPV4_SRC, 2291 ACTION_SET_IPV4_DST, 2292 ACTION_SET_IPV6_SRC, 2293 ACTION_SET_IPV6_DST, 2294 ACTION_SET_TP_SRC, 2295 ACTION_SET_TP_DST, 2296 ACTION_MAC_SWAP, 2297 ACTION_DEC_TTL, 2298 ACTION_SET_TTL, 2299 ACTION_SET_MAC_SRC, 2300 ACTION_SET_MAC_DST, 2301 ACTION_INC_TCP_SEQ, 2302 ACTION_DEC_TCP_SEQ, 2303 ACTION_INC_TCP_ACK, 2304 ACTION_DEC_TCP_ACK, 2305 ACTION_RAW_ENCAP, 2306 ACTION_RAW_DECAP, 2307 ACTION_SET_TAG, 2308 ACTION_SET_META, 2309 ACTION_SET_IPV4_DSCP, 2310 ACTION_SET_IPV6_DSCP, 2311 ACTION_AGE, 2312 ACTION_AGE_UPDATE, 2313 ACTION_SAMPLE, 2314 ACTION_INDIRECT, 2315 ACTION_INDIRECT_LIST, 2316 ACTION_SHARED_INDIRECT, 2317 ACTION_MODIFY_FIELD, 2318 ACTION_CONNTRACK, 2319 ACTION_CONNTRACK_UPDATE, 2320 ACTION_PORT_REPRESENTOR, 2321 ACTION_REPRESENTED_PORT, 2322 ACTION_SEND_TO_KERNEL, 2323 ACTION_QUOTA_CREATE, 2324 ACTION_QUOTA_QU, 2325 ACTION_IPV6_EXT_REMOVE, 2326 ACTION_IPV6_EXT_PUSH, 2327 ACTION_NAT64, 2328 ACTION_JUMP_TO_TABLE_INDEX, 2329 ZERO, 2330 }; 2331 2332 static const enum index action_quota_create[] = { 2333 ACTION_QUOTA_CREATE_LIMIT, 2334 ACTION_QUOTA_CREATE_MODE, 2335 ACTION_NEXT, 2336 ZERO 2337 }; 2338 2339 static const enum index action_quota_update[] = { 2340 ACTION_QUOTA_QU_LIMIT, 2341 ACTION_QUOTA_QU_UPDATE_OP, 2342 ACTION_NEXT, 2343 ZERO 2344 }; 2345 2346 static const enum index action_mark[] = { 2347 ACTION_MARK_ID, 2348 ACTION_NEXT, 2349 ZERO, 2350 }; 2351 2352 static const enum index action_queue[] = { 2353 ACTION_QUEUE_INDEX, 2354 ACTION_NEXT, 2355 ZERO, 2356 }; 2357 2358 static const enum index action_count[] = { 2359 ACTION_COUNT_ID, 2360 ACTION_NEXT, 2361 ZERO, 2362 }; 2363 2364 static const enum index action_rss[] = { 2365 ACTION_RSS_FUNC, 2366 ACTION_RSS_LEVEL, 2367 ACTION_RSS_TYPES, 2368 ACTION_RSS_KEY, 2369 ACTION_RSS_KEY_LEN, 2370 ACTION_RSS_QUEUES, 2371 ACTION_NEXT, 2372 ZERO, 2373 }; 2374 2375 static const enum index action_vf[] = { 2376 ACTION_VF_ORIGINAL, 2377 ACTION_VF_ID, 2378 ACTION_NEXT, 2379 ZERO, 2380 }; 2381 2382 static const enum index action_port_id[] = { 2383 ACTION_PORT_ID_ORIGINAL, 2384 ACTION_PORT_ID_ID, 2385 ACTION_NEXT, 2386 ZERO, 2387 }; 2388 2389 static const enum index action_meter[] = { 2390 ACTION_METER_ID, 2391 ACTION_NEXT, 2392 ZERO, 2393 }; 2394 2395 static const enum index action_meter_color[] = { 2396 ACTION_METER_COLOR_TYPE, 2397 ACTION_NEXT, 2398 ZERO, 2399 }; 2400 2401 static const enum index action_meter_mark[] = { 2402 ACTION_METER_PROFILE, 2403 ACTION_METER_POLICY, 2404 ACTION_METER_COLOR_MODE, 2405 ACTION_METER_STATE, 2406 ACTION_NEXT, 2407 ZERO, 2408 }; 2409 2410 static const enum index action_of_push_vlan[] = { 2411 ACTION_OF_PUSH_VLAN_ETHERTYPE, 2412 ACTION_NEXT, 2413 ZERO, 2414 }; 2415 2416 static const enum index action_of_set_vlan_vid[] = { 2417 ACTION_OF_SET_VLAN_VID_VLAN_VID, 2418 ACTION_NEXT, 2419 ZERO, 2420 }; 2421 2422 static const enum index action_of_set_vlan_pcp[] = { 2423 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 2424 ACTION_NEXT, 2425 ZERO, 2426 }; 2427 2428 static const enum index action_of_pop_mpls[] = { 2429 ACTION_OF_POP_MPLS_ETHERTYPE, 2430 ACTION_NEXT, 2431 ZERO, 2432 }; 2433 2434 static const enum index action_of_push_mpls[] = { 2435 ACTION_OF_PUSH_MPLS_ETHERTYPE, 2436 ACTION_NEXT, 2437 ZERO, 2438 }; 2439 2440 static const enum index action_set_ipv4_src[] = { 2441 ACTION_SET_IPV4_SRC_IPV4_SRC, 2442 ACTION_NEXT, 2443 ZERO, 2444 }; 2445 2446 static const enum index action_set_mac_src[] = { 2447 ACTION_SET_MAC_SRC_MAC_SRC, 2448 ACTION_NEXT, 2449 ZERO, 2450 }; 2451 2452 static const enum index action_set_ipv4_dst[] = { 2453 ACTION_SET_IPV4_DST_IPV4_DST, 2454 ACTION_NEXT, 2455 ZERO, 2456 }; 2457 2458 static const enum index action_set_ipv6_src[] = { 2459 ACTION_SET_IPV6_SRC_IPV6_SRC, 2460 ACTION_NEXT, 2461 ZERO, 2462 }; 2463 2464 static const enum index action_set_ipv6_dst[] = { 2465 ACTION_SET_IPV6_DST_IPV6_DST, 2466 ACTION_NEXT, 2467 ZERO, 2468 }; 2469 2470 static const enum index action_set_tp_src[] = { 2471 ACTION_SET_TP_SRC_TP_SRC, 2472 ACTION_NEXT, 2473 ZERO, 2474 }; 2475 2476 static const enum index action_set_tp_dst[] = { 2477 ACTION_SET_TP_DST_TP_DST, 2478 ACTION_NEXT, 2479 ZERO, 2480 }; 2481 2482 static const enum index action_set_ttl[] = { 2483 ACTION_SET_TTL_TTL, 2484 ACTION_NEXT, 2485 ZERO, 2486 }; 2487 2488 static const enum index action_jump[] = { 2489 ACTION_JUMP_GROUP, 2490 ACTION_NEXT, 2491 ZERO, 2492 }; 2493 2494 static const enum index action_set_mac_dst[] = { 2495 ACTION_SET_MAC_DST_MAC_DST, 2496 ACTION_NEXT, 2497 ZERO, 2498 }; 2499 2500 static const enum index action_inc_tcp_seq[] = { 2501 ACTION_INC_TCP_SEQ_VALUE, 2502 ACTION_NEXT, 2503 ZERO, 2504 }; 2505 2506 static const enum index action_dec_tcp_seq[] = { 2507 ACTION_DEC_TCP_SEQ_VALUE, 2508 ACTION_NEXT, 2509 ZERO, 2510 }; 2511 2512 static const enum index action_inc_tcp_ack[] = { 2513 ACTION_INC_TCP_ACK_VALUE, 2514 ACTION_NEXT, 2515 ZERO, 2516 }; 2517 2518 static const enum index action_dec_tcp_ack[] = { 2519 ACTION_DEC_TCP_ACK_VALUE, 2520 ACTION_NEXT, 2521 ZERO, 2522 }; 2523 2524 static const enum index action_raw_encap[] = { 2525 ACTION_RAW_ENCAP_SIZE, 2526 ACTION_RAW_ENCAP_INDEX, 2527 ACTION_NEXT, 2528 ZERO, 2529 }; 2530 2531 static const enum index action_raw_decap[] = { 2532 ACTION_RAW_DECAP_INDEX, 2533 ACTION_NEXT, 2534 ZERO, 2535 }; 2536 2537 static const enum index action_ipv6_ext_remove[] = { 2538 ACTION_IPV6_EXT_REMOVE_INDEX, 2539 ACTION_NEXT, 2540 ZERO, 2541 }; 2542 2543 static const enum index action_ipv6_ext_push[] = { 2544 ACTION_IPV6_EXT_PUSH_INDEX, 2545 ACTION_NEXT, 2546 ZERO, 2547 }; 2548 2549 static const enum index action_set_tag[] = { 2550 ACTION_SET_TAG_DATA, 2551 ACTION_SET_TAG_INDEX, 2552 ACTION_SET_TAG_MASK, 2553 ACTION_NEXT, 2554 ZERO, 2555 }; 2556 2557 static const enum index action_set_meta[] = { 2558 ACTION_SET_META_DATA, 2559 ACTION_SET_META_MASK, 2560 ACTION_NEXT, 2561 ZERO, 2562 }; 2563 2564 static const enum index action_set_ipv4_dscp[] = { 2565 ACTION_SET_IPV4_DSCP_VALUE, 2566 ACTION_NEXT, 2567 ZERO, 2568 }; 2569 2570 static const enum index action_set_ipv6_dscp[] = { 2571 ACTION_SET_IPV6_DSCP_VALUE, 2572 ACTION_NEXT, 2573 ZERO, 2574 }; 2575 2576 static const enum index action_age[] = { 2577 ACTION_AGE, 2578 ACTION_AGE_TIMEOUT, 2579 ACTION_NEXT, 2580 ZERO, 2581 }; 2582 2583 static const enum index action_age_update[] = { 2584 ACTION_AGE_UPDATE, 2585 ACTION_AGE_UPDATE_TIMEOUT, 2586 ACTION_AGE_UPDATE_TOUCH, 2587 ACTION_NEXT, 2588 ZERO, 2589 }; 2590 2591 static const enum index action_sample[] = { 2592 ACTION_SAMPLE, 2593 ACTION_SAMPLE_RATIO, 2594 ACTION_SAMPLE_INDEX, 2595 ACTION_NEXT, 2596 ZERO, 2597 }; 2598 2599 static const enum index next_action_sample[] = { 2600 ACTION_QUEUE, 2601 ACTION_RSS, 2602 ACTION_MARK, 2603 ACTION_COUNT, 2604 ACTION_PORT_ID, 2605 ACTION_RAW_ENCAP, 2606 ACTION_VXLAN_ENCAP, 2607 ACTION_NVGRE_ENCAP, 2608 ACTION_REPRESENTED_PORT, 2609 ACTION_PORT_REPRESENTOR, 2610 ACTION_NEXT, 2611 ZERO, 2612 }; 2613 2614 static const enum index item_ipv6_push_ext[] = { 2615 ITEM_IPV6_PUSH_REMOVE_EXT, 2616 ZERO, 2617 }; 2618 2619 static const enum index item_ipv6_push_ext_type[] = { 2620 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 2621 ZERO, 2622 }; 2623 2624 static const enum index item_ipv6_push_ext_header[] = { 2625 ITEM_IPV6_ROUTING_EXT, 2626 ITEM_NEXT, 2627 ZERO, 2628 }; 2629 2630 static const enum index action_modify_field_dst[] = { 2631 ACTION_MODIFY_FIELD_DST_LEVEL, 2632 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 2633 ACTION_MODIFY_FIELD_DST_TYPE_ID, 2634 ACTION_MODIFY_FIELD_DST_CLASS_ID, 2635 ACTION_MODIFY_FIELD_DST_OFFSET, 2636 ACTION_MODIFY_FIELD_SRC_TYPE, 2637 ZERO, 2638 }; 2639 2640 static const enum index action_modify_field_src[] = { 2641 ACTION_MODIFY_FIELD_SRC_LEVEL, 2642 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 2643 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 2644 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 2645 ACTION_MODIFY_FIELD_SRC_OFFSET, 2646 ACTION_MODIFY_FIELD_SRC_VALUE, 2647 ACTION_MODIFY_FIELD_SRC_POINTER, 2648 ACTION_MODIFY_FIELD_WIDTH, 2649 ZERO, 2650 }; 2651 2652 static const enum index action_update_conntrack[] = { 2653 ACTION_CONNTRACK_UPDATE_DIR, 2654 ACTION_CONNTRACK_UPDATE_CTX, 2655 ACTION_NEXT, 2656 ZERO, 2657 }; 2658 2659 static const enum index action_port_representor[] = { 2660 ACTION_PORT_REPRESENTOR_PORT_ID, 2661 ACTION_NEXT, 2662 ZERO, 2663 }; 2664 2665 static const enum index action_represented_port[] = { 2666 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 2667 ACTION_NEXT, 2668 ZERO, 2669 }; 2670 2671 static const enum index action_nat64[] = { 2672 ACTION_NAT64_MODE, 2673 ACTION_NEXT, 2674 ZERO, 2675 }; 2676 2677 static const enum index next_hash_subcmd[] = { 2678 HASH_CALC_TABLE, 2679 HASH_CALC_ENCAP, 2680 ZERO, 2681 }; 2682 2683 static const enum index next_hash_encap_dest_subcmd[] = { 2684 ENCAP_HASH_FIELD_SRC_PORT, 2685 ENCAP_HASH_FIELD_GRE_FLOW_ID, 2686 ZERO, 2687 }; 2688 2689 static const enum index action_jump_to_table_index[] = { 2690 ACTION_JUMP_TO_TABLE_INDEX_TABLE, 2691 ACTION_JUMP_TO_TABLE_INDEX_INDEX, 2692 ACTION_NEXT, 2693 ZERO, 2694 }; 2695 2696 static int parse_set_raw_encap_decap(struct context *, const struct token *, 2697 const char *, unsigned int, 2698 void *, unsigned int); 2699 static int parse_set_sample_action(struct context *, const struct token *, 2700 const char *, unsigned int, 2701 void *, unsigned int); 2702 static int parse_set_ipv6_ext_action(struct context *, const struct token *, 2703 const char *, unsigned int, 2704 void *, unsigned int); 2705 static int parse_set_init(struct context *, const struct token *, 2706 const char *, unsigned int, 2707 void *, unsigned int); 2708 static int 2709 parse_flex_handle(struct context *, const struct token *, 2710 const char *, unsigned int, void *, unsigned int); 2711 static int parse_init(struct context *, const struct token *, 2712 const char *, unsigned int, 2713 void *, unsigned int); 2714 static int parse_vc(struct context *, const struct token *, 2715 const char *, unsigned int, 2716 void *, unsigned int); 2717 static int parse_vc_spec(struct context *, const struct token *, 2718 const char *, unsigned int, void *, unsigned int); 2719 static int parse_vc_conf(struct context *, const struct token *, 2720 const char *, unsigned int, void *, unsigned int); 2721 static int parse_vc_conf_timeout(struct context *, const struct token *, 2722 const char *, unsigned int, void *, 2723 unsigned int); 2724 static int parse_vc_item_ecpri_type(struct context *, const struct token *, 2725 const char *, unsigned int, 2726 void *, unsigned int); 2727 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, 2728 const char *, unsigned int, 2729 void *, unsigned int); 2730 static int parse_vc_action_meter_color_type(struct context *, 2731 const struct token *, 2732 const char *, unsigned int, void *, 2733 unsigned int); 2734 static int parse_vc_action_rss(struct context *, const struct token *, 2735 const char *, unsigned int, void *, 2736 unsigned int); 2737 static int parse_vc_action_rss_func(struct context *, const struct token *, 2738 const char *, unsigned int, void *, 2739 unsigned int); 2740 static int parse_vc_action_rss_type(struct context *, const struct token *, 2741 const char *, unsigned int, void *, 2742 unsigned int); 2743 static int parse_vc_action_rss_queue(struct context *, const struct token *, 2744 const char *, unsigned int, void *, 2745 unsigned int); 2746 static int parse_vc_action_vxlan_encap(struct context *, const struct token *, 2747 const char *, unsigned int, void *, 2748 unsigned int); 2749 static int parse_vc_action_nvgre_encap(struct context *, const struct token *, 2750 const char *, unsigned int, void *, 2751 unsigned int); 2752 static int parse_vc_action_l2_encap(struct context *, const struct token *, 2753 const char *, unsigned int, void *, 2754 unsigned int); 2755 static int parse_vc_action_l2_decap(struct context *, const struct token *, 2756 const char *, unsigned int, void *, 2757 unsigned int); 2758 static int parse_vc_action_mplsogre_encap(struct context *, 2759 const struct token *, const char *, 2760 unsigned int, void *, unsigned int); 2761 static int parse_vc_action_mplsogre_decap(struct context *, 2762 const struct token *, const char *, 2763 unsigned int, void *, unsigned int); 2764 static int parse_vc_action_mplsoudp_encap(struct context *, 2765 const struct token *, const char *, 2766 unsigned int, void *, unsigned int); 2767 static int parse_vc_action_mplsoudp_decap(struct context *, 2768 const struct token *, const char *, 2769 unsigned int, void *, unsigned int); 2770 static int parse_vc_action_raw_encap(struct context *, 2771 const struct token *, const char *, 2772 unsigned int, void *, unsigned int); 2773 static int parse_vc_action_raw_decap(struct context *, 2774 const struct token *, const char *, 2775 unsigned int, void *, unsigned int); 2776 static int parse_vc_action_raw_encap_index(struct context *, 2777 const struct token *, const char *, 2778 unsigned int, void *, unsigned int); 2779 static int parse_vc_action_raw_decap_index(struct context *, 2780 const struct token *, const char *, 2781 unsigned int, void *, unsigned int); 2782 static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 2783 const char *str, unsigned int len, void *buf, 2784 unsigned int size); 2785 static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, 2786 const struct token *token, 2787 const char *str, unsigned int len, 2788 void *buf, 2789 unsigned int size); 2790 static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 2791 const char *str, unsigned int len, void *buf, 2792 unsigned int size); 2793 static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, 2794 const struct token *token, 2795 const char *str, unsigned int len, 2796 void *buf, 2797 unsigned int size); 2798 static int parse_vc_action_set_meta(struct context *ctx, 2799 const struct token *token, const char *str, 2800 unsigned int len, void *buf, 2801 unsigned int size); 2802 static int parse_vc_action_sample(struct context *ctx, 2803 const struct token *token, const char *str, 2804 unsigned int len, void *buf, 2805 unsigned int size); 2806 static int 2807 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 2808 const char *str, unsigned int len, void *buf, 2809 unsigned int size); 2810 static int 2811 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 2812 const char *str, unsigned int len, void *buf, 2813 unsigned int size); 2814 static int 2815 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 2816 const char *str, unsigned int len, void *buf, 2817 unsigned int size); 2818 static int 2819 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 2820 const char *str, unsigned int len, void *buf, 2821 unsigned int size); 2822 static int 2823 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 2824 const char *str, unsigned int len, void *buf, 2825 unsigned int size); 2826 static int parse_destroy(struct context *, const struct token *, 2827 const char *, unsigned int, 2828 void *, unsigned int); 2829 static int parse_flush(struct context *, const struct token *, 2830 const char *, unsigned int, 2831 void *, unsigned int); 2832 static int parse_dump(struct context *, const struct token *, 2833 const char *, unsigned int, 2834 void *, unsigned int); 2835 static int parse_query(struct context *, const struct token *, 2836 const char *, unsigned int, 2837 void *, unsigned int); 2838 static int parse_action(struct context *, const struct token *, 2839 const char *, unsigned int, 2840 void *, unsigned int); 2841 static int parse_list(struct context *, const struct token *, 2842 const char *, unsigned int, 2843 void *, unsigned int); 2844 static int parse_aged(struct context *, const struct token *, 2845 const char *, unsigned int, 2846 void *, unsigned int); 2847 static int parse_isolate(struct context *, const struct token *, 2848 const char *, unsigned int, 2849 void *, unsigned int); 2850 static int parse_configure(struct context *, const struct token *, 2851 const char *, unsigned int, 2852 void *, unsigned int); 2853 static int parse_template(struct context *, const struct token *, 2854 const char *, unsigned int, 2855 void *, unsigned int); 2856 static int parse_template_destroy(struct context *, const struct token *, 2857 const char *, unsigned int, 2858 void *, unsigned int); 2859 static int parse_table(struct context *, const struct token *, 2860 const char *, unsigned int, void *, unsigned int); 2861 static int parse_table_destroy(struct context *, const struct token *, 2862 const char *, unsigned int, 2863 void *, unsigned int); 2864 static int parse_qo(struct context *, const struct token *, 2865 const char *, unsigned int, 2866 void *, unsigned int); 2867 static int parse_qo_destroy(struct context *, const struct token *, 2868 const char *, unsigned int, 2869 void *, unsigned int); 2870 static int parse_qia(struct context *, const struct token *, 2871 const char *, unsigned int, 2872 void *, unsigned int); 2873 static int parse_qia_destroy(struct context *, const struct token *, 2874 const char *, unsigned int, 2875 void *, unsigned int); 2876 static int parse_push(struct context *, const struct token *, 2877 const char *, unsigned int, 2878 void *, unsigned int); 2879 static int parse_pull(struct context *, const struct token *, 2880 const char *, unsigned int, 2881 void *, unsigned int); 2882 static int parse_group(struct context *, const struct token *, 2883 const char *, unsigned int, 2884 void *, unsigned int); 2885 static int parse_hash(struct context *, const struct token *, 2886 const char *, unsigned int, 2887 void *, unsigned int); 2888 static int parse_tunnel(struct context *, const struct token *, 2889 const char *, unsigned int, 2890 void *, unsigned int); 2891 static int parse_flex(struct context *, const struct token *, 2892 const char *, unsigned int, void *, unsigned int); 2893 static int parse_int(struct context *, const struct token *, 2894 const char *, unsigned int, 2895 void *, unsigned int); 2896 static int parse_prefix(struct context *, const struct token *, 2897 const char *, unsigned int, 2898 void *, unsigned int); 2899 static int parse_boolean(struct context *, const struct token *, 2900 const char *, unsigned int, 2901 void *, unsigned int); 2902 static int parse_string(struct context *, const struct token *, 2903 const char *, unsigned int, 2904 void *, unsigned int); 2905 static int parse_hex(struct context *ctx, const struct token *token, 2906 const char *str, unsigned int len, 2907 void *buf, unsigned int size); 2908 static int parse_string0(struct context *, const struct token *, 2909 const char *, unsigned int, 2910 void *, unsigned int); 2911 static int parse_mac_addr(struct context *, const struct token *, 2912 const char *, unsigned int, 2913 void *, unsigned int); 2914 static int parse_ipv4_addr(struct context *, const struct token *, 2915 const char *, unsigned int, 2916 void *, unsigned int); 2917 static int parse_ipv6_addr(struct context *, const struct token *, 2918 const char *, unsigned int, 2919 void *, unsigned int); 2920 static int parse_port(struct context *, const struct token *, 2921 const char *, unsigned int, 2922 void *, unsigned int); 2923 static int parse_ia(struct context *, const struct token *, 2924 const char *, unsigned int, 2925 void *, unsigned int); 2926 static int parse_ia_destroy(struct context *ctx, const struct token *token, 2927 const char *str, unsigned int len, 2928 void *buf, unsigned int size); 2929 static int parse_ia_id2ptr(struct context *ctx, const struct token *token, 2930 const char *str, unsigned int len, void *buf, 2931 unsigned int size); 2932 2933 static int parse_indlst_id2ptr(struct context *ctx, const struct token *token, 2934 const char *str, unsigned int len, void *buf, 2935 unsigned int size); 2936 static int parse_ia_port(struct context *ctx, const struct token *token, 2937 const char *str, unsigned int len, void *buf, 2938 unsigned int size); 2939 static int parse_mp(struct context *, const struct token *, 2940 const char *, unsigned int, 2941 void *, unsigned int); 2942 static int parse_meter_profile_id2ptr(struct context *ctx, 2943 const struct token *token, 2944 const char *str, unsigned int len, 2945 void *buf, unsigned int size); 2946 static int parse_meter_policy_id2ptr(struct context *ctx, 2947 const struct token *token, 2948 const char *str, unsigned int len, 2949 void *buf, unsigned int size); 2950 static int parse_meter_color(struct context *ctx, const struct token *token, 2951 const char *str, unsigned int len, void *buf, 2952 unsigned int size); 2953 static int parse_insertion_table_type(struct context *ctx, const struct token *token, 2954 const char *str, unsigned int len, void *buf, 2955 unsigned int size); 2956 static int parse_hash_table_type(struct context *ctx, const struct token *token, 2957 const char *str, unsigned int len, void *buf, 2958 unsigned int size); 2959 static int 2960 parse_quota_state_name(struct context *ctx, const struct token *token, 2961 const char *str, unsigned int len, void *buf, 2962 unsigned int size); 2963 static int 2964 parse_quota_mode_name(struct context *ctx, const struct token *token, 2965 const char *str, unsigned int len, void *buf, 2966 unsigned int size); 2967 static int 2968 parse_quota_update_name(struct context *ctx, const struct token *token, 2969 const char *str, unsigned int len, void *buf, 2970 unsigned int size); 2971 static int 2972 parse_qu_mode_name(struct context *ctx, const struct token *token, 2973 const char *str, unsigned int len, void *buf, 2974 unsigned int size); 2975 static int comp_none(struct context *, const struct token *, 2976 unsigned int, char *, unsigned int); 2977 static int comp_boolean(struct context *, const struct token *, 2978 unsigned int, char *, unsigned int); 2979 static int comp_action(struct context *, const struct token *, 2980 unsigned int, char *, unsigned int); 2981 static int comp_port(struct context *, const struct token *, 2982 unsigned int, char *, unsigned int); 2983 static int comp_rule_id(struct context *, const struct token *, 2984 unsigned int, char *, unsigned int); 2985 static int comp_vc_action_rss_type(struct context *, const struct token *, 2986 unsigned int, char *, unsigned int); 2987 static int comp_vc_action_rss_queue(struct context *, const struct token *, 2988 unsigned int, char *, unsigned int); 2989 static int comp_set_raw_index(struct context *, const struct token *, 2990 unsigned int, char *, unsigned int); 2991 static int comp_set_sample_index(struct context *, const struct token *, 2992 unsigned int, char *, unsigned int); 2993 static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 2994 unsigned int ent, char *buf, unsigned int size); 2995 static int comp_set_modify_field_op(struct context *, const struct token *, 2996 unsigned int, char *, unsigned int); 2997 static int comp_set_modify_field_id(struct context *, const struct token *, 2998 unsigned int, char *, unsigned int); 2999 static int comp_pattern_template_id(struct context *, const struct token *, 3000 unsigned int, char *, unsigned int); 3001 static int comp_actions_template_id(struct context *, const struct token *, 3002 unsigned int, char *, unsigned int); 3003 static int comp_table_id(struct context *, const struct token *, 3004 unsigned int, char *, unsigned int); 3005 static int comp_queue_id(struct context *, const struct token *, 3006 unsigned int, char *, unsigned int); 3007 static int comp_meter_color(struct context *, const struct token *, 3008 unsigned int, char *, unsigned int); 3009 static int comp_insertion_table_type(struct context *, const struct token *, 3010 unsigned int, char *, unsigned int); 3011 static int comp_hash_table_type(struct context *, const struct token *, 3012 unsigned int, char *, unsigned int); 3013 static int 3014 comp_quota_state_name(struct context *ctx, const struct token *token, 3015 unsigned int ent, char *buf, unsigned int size); 3016 static int 3017 comp_quota_mode_name(struct context *ctx, const struct token *token, 3018 unsigned int ent, char *buf, unsigned int size); 3019 static int 3020 comp_quota_update_name(struct context *ctx, const struct token *token, 3021 unsigned int ent, char *buf, unsigned int size); 3022 static int 3023 comp_qu_mode_name(struct context *ctx, const struct token *token, 3024 unsigned int ent, char *buf, unsigned int size); 3025 static int 3026 comp_set_compare_field_id(struct context *ctx, const struct token *token, 3027 unsigned int ent, char *buf, unsigned int size); 3028 static int 3029 comp_set_compare_op(struct context *ctx, const struct token *token, 3030 unsigned int ent, char *buf, unsigned int size); 3031 static int 3032 parse_vc_compare_op(struct context *ctx, const struct token *token, 3033 const char *str, unsigned int len, void *buf, 3034 unsigned int size); 3035 static int 3036 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 3037 const char *str, unsigned int len, void *buf, 3038 unsigned int size); 3039 static int 3040 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 3041 const char *str, unsigned int len, void *buf, 3042 unsigned int size); 3043 3044 struct indlst_conf { 3045 uint32_t id; 3046 uint32_t conf_num; 3047 struct rte_flow_action *actions; 3048 const void **conf; 3049 SLIST_ENTRY(indlst_conf) next; 3050 }; 3051 3052 static const struct indlst_conf *indirect_action_list_conf_get(uint32_t conf_id); 3053 3054 /** Token definitions. */ 3055 static const struct token token_list[] = { 3056 /* Special tokens. */ 3057 [ZERO] = { 3058 .name = "ZERO", 3059 .help = "null entry, abused as the entry point", 3060 .next = NEXT(NEXT_ENTRY(FLOW, ADD)), 3061 }, 3062 [END] = { 3063 .name = "", 3064 .type = "RETURN", 3065 .help = "command may end here", 3066 }, 3067 [START_SET] = { 3068 .name = "START_SET", 3069 .help = "null entry, abused as the entry point for set", 3070 .next = NEXT(NEXT_ENTRY(SET)), 3071 }, 3072 [END_SET] = { 3073 .name = "end_set", 3074 .type = "RETURN", 3075 .help = "set command may end here", 3076 }, 3077 /* Common tokens. */ 3078 [COMMON_INTEGER] = { 3079 .name = "{int}", 3080 .type = "INTEGER", 3081 .help = "integer value", 3082 .call = parse_int, 3083 .comp = comp_none, 3084 }, 3085 [COMMON_UNSIGNED] = { 3086 .name = "{unsigned}", 3087 .type = "UNSIGNED", 3088 .help = "unsigned integer value", 3089 .call = parse_int, 3090 .comp = comp_none, 3091 }, 3092 [COMMON_PREFIX] = { 3093 .name = "{prefix}", 3094 .type = "PREFIX", 3095 .help = "prefix length for bit-mask", 3096 .call = parse_prefix, 3097 .comp = comp_none, 3098 }, 3099 [COMMON_BOOLEAN] = { 3100 .name = "{boolean}", 3101 .type = "BOOLEAN", 3102 .help = "any boolean value", 3103 .call = parse_boolean, 3104 .comp = comp_boolean, 3105 }, 3106 [COMMON_STRING] = { 3107 .name = "{string}", 3108 .type = "STRING", 3109 .help = "fixed string", 3110 .call = parse_string, 3111 .comp = comp_none, 3112 }, 3113 [COMMON_HEX] = { 3114 .name = "{hex}", 3115 .type = "HEX", 3116 .help = "fixed string", 3117 .call = parse_hex, 3118 }, 3119 [COMMON_FILE_PATH] = { 3120 .name = "{file path}", 3121 .type = "STRING", 3122 .help = "file path", 3123 .call = parse_string0, 3124 .comp = comp_none, 3125 }, 3126 [COMMON_MAC_ADDR] = { 3127 .name = "{MAC address}", 3128 .type = "MAC-48", 3129 .help = "standard MAC address notation", 3130 .call = parse_mac_addr, 3131 .comp = comp_none, 3132 }, 3133 [COMMON_IPV4_ADDR] = { 3134 .name = "{IPv4 address}", 3135 .type = "IPV4 ADDRESS", 3136 .help = "standard IPv4 address notation", 3137 .call = parse_ipv4_addr, 3138 .comp = comp_none, 3139 }, 3140 [COMMON_IPV6_ADDR] = { 3141 .name = "{IPv6 address}", 3142 .type = "IPV6 ADDRESS", 3143 .help = "standard IPv6 address notation", 3144 .call = parse_ipv6_addr, 3145 .comp = comp_none, 3146 }, 3147 [COMMON_RULE_ID] = { 3148 .name = "{rule id}", 3149 .type = "RULE ID", 3150 .help = "rule identifier", 3151 .call = parse_int, 3152 .comp = comp_rule_id, 3153 }, 3154 [COMMON_PORT_ID] = { 3155 .name = "{port_id}", 3156 .type = "PORT ID", 3157 .help = "port identifier", 3158 .call = parse_port, 3159 .comp = comp_port, 3160 }, 3161 [COMMON_GROUP_ID] = { 3162 .name = "{group_id}", 3163 .type = "GROUP ID", 3164 .help = "group identifier", 3165 .call = parse_int, 3166 .comp = comp_none, 3167 }, 3168 [COMMON_PRIORITY_LEVEL] = { 3169 .name = "{level}", 3170 .type = "PRIORITY", 3171 .help = "priority level", 3172 .call = parse_int, 3173 .comp = comp_none, 3174 }, 3175 [COMMON_INDIRECT_ACTION_ID] = { 3176 .name = "{indirect_action_id}", 3177 .type = "INDIRECT_ACTION_ID", 3178 .help = "indirect action id", 3179 .call = parse_int, 3180 .comp = comp_none, 3181 }, 3182 [COMMON_PROFILE_ID] = { 3183 .name = "{profile_id}", 3184 .type = "PROFILE_ID", 3185 .help = "profile id", 3186 .call = parse_int, 3187 .comp = comp_none, 3188 }, 3189 [COMMON_POLICY_ID] = { 3190 .name = "{policy_id}", 3191 .type = "POLICY_ID", 3192 .help = "policy id", 3193 .call = parse_int, 3194 .comp = comp_none, 3195 }, 3196 [COMMON_FLEX_TOKEN] = { 3197 .name = "{flex token}", 3198 .type = "flex token", 3199 .help = "flex token", 3200 .call = parse_int, 3201 .comp = comp_none, 3202 }, 3203 [COMMON_FLEX_HANDLE] = { 3204 .name = "{flex handle}", 3205 .type = "FLEX HANDLE", 3206 .help = "fill flex item data", 3207 .call = parse_flex_handle, 3208 .comp = comp_none, 3209 }, 3210 [COMMON_PATTERN_TEMPLATE_ID] = { 3211 .name = "{pattern_template_id}", 3212 .type = "PATTERN_TEMPLATE_ID", 3213 .help = "pattern template id", 3214 .call = parse_int, 3215 .comp = comp_pattern_template_id, 3216 }, 3217 [COMMON_ACTIONS_TEMPLATE_ID] = { 3218 .name = "{actions_template_id}", 3219 .type = "ACTIONS_TEMPLATE_ID", 3220 .help = "actions template id", 3221 .call = parse_int, 3222 .comp = comp_actions_template_id, 3223 }, 3224 [COMMON_TABLE_ID] = { 3225 .name = "{table_id}", 3226 .type = "TABLE_ID", 3227 .help = "table id", 3228 .call = parse_int, 3229 .comp = comp_table_id, 3230 }, 3231 [COMMON_QUEUE_ID] = { 3232 .name = "{queue_id}", 3233 .type = "QUEUE_ID", 3234 .help = "queue id", 3235 .call = parse_int, 3236 .comp = comp_queue_id, 3237 }, 3238 /* Top-level command. */ 3239 [FLOW] = { 3240 .name = "flow", 3241 .type = "{command} {port_id} [{arg} [...]]", 3242 .help = "manage ingress/egress flow rules", 3243 .next = NEXT(NEXT_ENTRY 3244 (INFO, 3245 CONFIGURE, 3246 PATTERN_TEMPLATE, 3247 ACTIONS_TEMPLATE, 3248 TABLE, 3249 FLOW_GROUP, 3250 INDIRECT_ACTION, 3251 VALIDATE, 3252 CREATE, 3253 DESTROY, 3254 UPDATE, 3255 FLUSH, 3256 DUMP, 3257 LIST, 3258 AGED, 3259 QUERY, 3260 ISOLATE, 3261 TUNNEL, 3262 FLEX, 3263 QUEUE, 3264 PUSH, 3265 PULL, 3266 HASH)), 3267 .call = parse_init, 3268 }, 3269 /* Top-level command. */ 3270 [INFO] = { 3271 .name = "info", 3272 .help = "get information about flow engine", 3273 .next = NEXT(NEXT_ENTRY(END), 3274 NEXT_ENTRY(COMMON_PORT_ID)), 3275 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3276 .call = parse_configure, 3277 }, 3278 /* Top-level command. */ 3279 [CONFIGURE] = { 3280 .name = "configure", 3281 .help = "configure flow engine", 3282 .next = NEXT(next_config_attr, 3283 NEXT_ENTRY(COMMON_PORT_ID)), 3284 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3285 .call = parse_configure, 3286 }, 3287 /* Configure arguments. */ 3288 [CONFIG_QUEUES_NUMBER] = { 3289 .name = "queues_number", 3290 .help = "number of queues", 3291 .next = NEXT(next_config_attr, 3292 NEXT_ENTRY(COMMON_UNSIGNED)), 3293 .args = ARGS(ARGS_ENTRY(struct buffer, 3294 args.configure.nb_queue)), 3295 }, 3296 [CONFIG_QUEUES_SIZE] = { 3297 .name = "queues_size", 3298 .help = "number of elements in queues", 3299 .next = NEXT(next_config_attr, 3300 NEXT_ENTRY(COMMON_UNSIGNED)), 3301 .args = ARGS(ARGS_ENTRY(struct buffer, 3302 args.configure.queue_attr.size)), 3303 }, 3304 [CONFIG_COUNTERS_NUMBER] = { 3305 .name = "counters_number", 3306 .help = "number of counters", 3307 .next = NEXT(next_config_attr, 3308 NEXT_ENTRY(COMMON_UNSIGNED)), 3309 .args = ARGS(ARGS_ENTRY(struct buffer, 3310 args.configure.port_attr.nb_counters)), 3311 }, 3312 [CONFIG_AGING_OBJECTS_NUMBER] = { 3313 .name = "aging_counters_number", 3314 .help = "number of aging objects", 3315 .next = NEXT(next_config_attr, 3316 NEXT_ENTRY(COMMON_UNSIGNED)), 3317 .args = ARGS(ARGS_ENTRY(struct buffer, 3318 args.configure.port_attr.nb_aging_objects)), 3319 }, 3320 [CONFIG_QUOTAS_NUMBER] = { 3321 .name = "quotas_number", 3322 .help = "number of quotas", 3323 .next = NEXT(next_config_attr, 3324 NEXT_ENTRY(COMMON_UNSIGNED)), 3325 .args = ARGS(ARGS_ENTRY(struct buffer, 3326 args.configure.port_attr.nb_quotas)), 3327 }, 3328 [CONFIG_METERS_NUMBER] = { 3329 .name = "meters_number", 3330 .help = "number of meters", 3331 .next = NEXT(next_config_attr, 3332 NEXT_ENTRY(COMMON_UNSIGNED)), 3333 .args = ARGS(ARGS_ENTRY(struct buffer, 3334 args.configure.port_attr.nb_meters)), 3335 }, 3336 [CONFIG_CONN_TRACK_NUMBER] = { 3337 .name = "conn_tracks_number", 3338 .help = "number of connection trackings", 3339 .next = NEXT(next_config_attr, 3340 NEXT_ENTRY(COMMON_UNSIGNED)), 3341 .args = ARGS(ARGS_ENTRY(struct buffer, 3342 args.configure.port_attr.nb_conn_tracks)), 3343 }, 3344 [CONFIG_FLAGS] = { 3345 .name = "flags", 3346 .help = "configuration flags", 3347 .next = NEXT(next_config_attr, 3348 NEXT_ENTRY(COMMON_UNSIGNED)), 3349 .args = ARGS(ARGS_ENTRY(struct buffer, 3350 args.configure.port_attr.flags)), 3351 }, 3352 [CONFIG_HOST_PORT] = { 3353 .name = "host_port", 3354 .help = "host port for shared objects", 3355 .next = NEXT(next_config_attr, 3356 NEXT_ENTRY(COMMON_UNSIGNED)), 3357 .args = ARGS(ARGS_ENTRY(struct buffer, 3358 args.configure.port_attr.host_port_id)), 3359 }, 3360 /* Top-level command. */ 3361 [PATTERN_TEMPLATE] = { 3362 .name = "pattern_template", 3363 .type = "{command} {port_id} [{arg} [...]]", 3364 .help = "manage pattern templates", 3365 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3366 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3367 .call = parse_template, 3368 }, 3369 /* Sub-level commands. */ 3370 [PATTERN_TEMPLATE_CREATE] = { 3371 .name = "create", 3372 .help = "create pattern template", 3373 .next = NEXT(next_pt_attr), 3374 .call = parse_template, 3375 }, 3376 [PATTERN_TEMPLATE_DESTROY] = { 3377 .name = "destroy", 3378 .help = "destroy pattern template", 3379 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), 3380 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3381 .call = parse_template_destroy, 3382 }, 3383 /* Pattern template arguments. */ 3384 [PATTERN_TEMPLATE_CREATE_ID] = { 3385 .name = "pattern_template_id", 3386 .help = "specify a pattern template id to create", 3387 .next = NEXT(next_pt_attr, 3388 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3389 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), 3390 }, 3391 [PATTERN_TEMPLATE_DESTROY_ID] = { 3392 .name = "pattern_template", 3393 .help = "specify a pattern template id to destroy", 3394 .next = NEXT(next_pt_destroy_attr, 3395 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3396 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3397 args.templ_destroy.template_id)), 3398 .call = parse_template_destroy, 3399 }, 3400 [PATTERN_TEMPLATE_RELAXED_MATCHING] = { 3401 .name = "relaxed", 3402 .help = "is matching relaxed", 3403 .next = NEXT(next_pt_attr, 3404 NEXT_ENTRY(COMMON_BOOLEAN)), 3405 .args = ARGS(ARGS_ENTRY_BF(struct buffer, 3406 args.vc.attr.reserved, 1)), 3407 }, 3408 [PATTERN_TEMPLATE_INGRESS] = { 3409 .name = "ingress", 3410 .help = "attribute pattern to ingress", 3411 .next = NEXT(next_pt_attr), 3412 .call = parse_template, 3413 }, 3414 [PATTERN_TEMPLATE_EGRESS] = { 3415 .name = "egress", 3416 .help = "attribute pattern to egress", 3417 .next = NEXT(next_pt_attr), 3418 .call = parse_template, 3419 }, 3420 [PATTERN_TEMPLATE_TRANSFER] = { 3421 .name = "transfer", 3422 .help = "attribute pattern to transfer", 3423 .next = NEXT(next_pt_attr), 3424 .call = parse_template, 3425 }, 3426 [PATTERN_TEMPLATE_SPEC] = { 3427 .name = "template", 3428 .help = "specify item to create pattern template", 3429 .next = NEXT(next_item), 3430 }, 3431 /* Top-level command. */ 3432 [ACTIONS_TEMPLATE] = { 3433 .name = "actions_template", 3434 .type = "{command} {port_id} [{arg} [...]]", 3435 .help = "manage actions templates", 3436 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3437 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3438 .call = parse_template, 3439 }, 3440 /* Sub-level commands. */ 3441 [ACTIONS_TEMPLATE_CREATE] = { 3442 .name = "create", 3443 .help = "create actions template", 3444 .next = NEXT(next_at_attr), 3445 .call = parse_template, 3446 }, 3447 [ACTIONS_TEMPLATE_DESTROY] = { 3448 .name = "destroy", 3449 .help = "destroy actions template", 3450 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), 3451 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3452 .call = parse_template_destroy, 3453 }, 3454 /* Actions template arguments. */ 3455 [ACTIONS_TEMPLATE_CREATE_ID] = { 3456 .name = "actions_template_id", 3457 .help = "specify an actions template id to create", 3458 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), 3459 NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), 3460 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3461 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), 3462 }, 3463 [ACTIONS_TEMPLATE_DESTROY_ID] = { 3464 .name = "actions_template", 3465 .help = "specify an actions template id to destroy", 3466 .next = NEXT(next_at_destroy_attr, 3467 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3468 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3469 args.templ_destroy.template_id)), 3470 .call = parse_template_destroy, 3471 }, 3472 [ACTIONS_TEMPLATE_INGRESS] = { 3473 .name = "ingress", 3474 .help = "attribute actions to ingress", 3475 .next = NEXT(next_at_attr), 3476 .call = parse_template, 3477 }, 3478 [ACTIONS_TEMPLATE_EGRESS] = { 3479 .name = "egress", 3480 .help = "attribute actions to egress", 3481 .next = NEXT(next_at_attr), 3482 .call = parse_template, 3483 }, 3484 [ACTIONS_TEMPLATE_TRANSFER] = { 3485 .name = "transfer", 3486 .help = "attribute actions to transfer", 3487 .next = NEXT(next_at_attr), 3488 .call = parse_template, 3489 }, 3490 [ACTIONS_TEMPLATE_SPEC] = { 3491 .name = "template", 3492 .help = "specify action to create actions template", 3493 .next = NEXT(next_action), 3494 .call = parse_template, 3495 }, 3496 [ACTIONS_TEMPLATE_MASK] = { 3497 .name = "mask", 3498 .help = "specify action mask to create actions template", 3499 .next = NEXT(next_action), 3500 .call = parse_template, 3501 }, 3502 /* Top-level command. */ 3503 [TABLE] = { 3504 .name = "template_table", 3505 .type = "{command} {port_id} [{arg} [...]]", 3506 .help = "manage template tables", 3507 .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3508 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3509 .call = parse_table, 3510 }, 3511 /* Sub-level commands. */ 3512 [TABLE_CREATE] = { 3513 .name = "create", 3514 .help = "create template table", 3515 .next = NEXT(next_table_attr), 3516 .call = parse_table, 3517 }, 3518 [TABLE_DESTROY] = { 3519 .name = "destroy", 3520 .help = "destroy template table", 3521 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3522 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3523 .call = parse_table_destroy, 3524 }, 3525 [TABLE_RESIZE] = { 3526 .name = "resize", 3527 .help = "resize template table", 3528 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_ID)), 3529 .call = parse_table 3530 }, 3531 [TABLE_RESIZE_COMPLETE] = { 3532 .name = "resize_complete", 3533 .help = "complete table resize", 3534 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3535 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3536 .call = parse_table_destroy, 3537 }, 3538 /* Table arguments. */ 3539 [TABLE_CREATE_ID] = { 3540 .name = "table_id", 3541 .help = "specify table id to create", 3542 .next = NEXT(next_table_attr, 3543 NEXT_ENTRY(COMMON_TABLE_ID)), 3544 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3545 }, 3546 [TABLE_DESTROY_ID] = { 3547 .name = "table", 3548 .help = "table id", 3549 .next = NEXT(next_table_destroy_attr, 3550 NEXT_ENTRY(COMMON_TABLE_ID)), 3551 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3552 args.table_destroy.table_id)), 3553 .call = parse_table_destroy, 3554 }, 3555 [TABLE_RESIZE_ID] = { 3556 .name = "table_resize_id", 3557 .help = "table resize id", 3558 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_RULES_NUMBER), 3559 NEXT_ENTRY(COMMON_TABLE_ID)), 3560 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3561 .call = parse_table 3562 }, 3563 [TABLE_RESIZE_RULES_NUMBER] = { 3564 .name = "table_resize_rules_num", 3565 .help = "table resize rules number", 3566 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_UNSIGNED)), 3567 .args = ARGS(ARGS_ENTRY(struct buffer, 3568 args.table.attr.nb_flows)), 3569 .call = parse_table 3570 }, 3571 [TABLE_INSERTION_TYPE] = { 3572 .name = "insertion_type", 3573 .help = "specify insertion type", 3574 .next = NEXT(next_table_attr, 3575 NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)), 3576 .args = ARGS(ARGS_ENTRY(struct buffer, 3577 args.table.attr.insertion_type)), 3578 }, 3579 [TABLE_INSERTION_TYPE_NAME] = { 3580 .name = "insertion_type_name", 3581 .help = "insertion type name", 3582 .call = parse_insertion_table_type, 3583 .comp = comp_insertion_table_type, 3584 }, 3585 [TABLE_HASH_FUNC] = { 3586 .name = "hash_func", 3587 .help = "specify hash calculation function", 3588 .next = NEXT(next_table_attr, 3589 NEXT_ENTRY(TABLE_HASH_FUNC_NAME)), 3590 .args = ARGS(ARGS_ENTRY(struct buffer, 3591 args.table.attr.hash_func)), 3592 }, 3593 [TABLE_HASH_FUNC_NAME] = { 3594 .name = "hash_func_name", 3595 .help = "hash calculation function name", 3596 .call = parse_hash_table_type, 3597 .comp = comp_hash_table_type, 3598 }, 3599 [TABLE_GROUP] = { 3600 .name = "group", 3601 .help = "specify a group", 3602 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3603 .args = ARGS(ARGS_ENTRY(struct buffer, 3604 args.table.attr.flow_attr.group)), 3605 }, 3606 [TABLE_PRIORITY] = { 3607 .name = "priority", 3608 .help = "specify a priority level", 3609 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 3610 .args = ARGS(ARGS_ENTRY(struct buffer, 3611 args.table.attr.flow_attr.priority)), 3612 }, 3613 [TABLE_EGRESS] = { 3614 .name = "egress", 3615 .help = "affect rule to egress", 3616 .next = NEXT(next_table_attr), 3617 .call = parse_table, 3618 }, 3619 [TABLE_INGRESS] = { 3620 .name = "ingress", 3621 .help = "affect rule to ingress", 3622 .next = NEXT(next_table_attr), 3623 .call = parse_table, 3624 }, 3625 [TABLE_TRANSFER] = { 3626 .name = "transfer", 3627 .help = "affect rule to transfer", 3628 .next = NEXT(next_table_attr), 3629 .call = parse_table, 3630 }, 3631 [TABLE_TRANSFER_WIRE_ORIG] = { 3632 .name = "wire_orig", 3633 .help = "affect rule direction to transfer", 3634 .next = NEXT(next_table_attr), 3635 .call = parse_table, 3636 }, 3637 [TABLE_TRANSFER_VPORT_ORIG] = { 3638 .name = "vport_orig", 3639 .help = "affect rule direction to transfer", 3640 .next = NEXT(next_table_attr), 3641 .call = parse_table, 3642 }, 3643 [TABLE_RESIZABLE] = { 3644 .name = "resizable", 3645 .help = "set resizable attribute", 3646 .next = NEXT(next_table_attr), 3647 .call = parse_table, 3648 }, 3649 [TABLE_RULES_NUMBER] = { 3650 .name = "rules_number", 3651 .help = "number of rules in table", 3652 .next = NEXT(next_table_attr, 3653 NEXT_ENTRY(COMMON_UNSIGNED)), 3654 .args = ARGS(ARGS_ENTRY(struct buffer, 3655 args.table.attr.nb_flows)), 3656 .call = parse_table, 3657 }, 3658 [TABLE_PATTERN_TEMPLATE] = { 3659 .name = "pattern_template", 3660 .help = "specify pattern template id", 3661 .next = NEXT(next_table_attr, 3662 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3663 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3664 args.table.pat_templ_id)), 3665 .call = parse_table, 3666 }, 3667 [TABLE_ACTIONS_TEMPLATE] = { 3668 .name = "actions_template", 3669 .help = "specify actions template id", 3670 .next = NEXT(next_table_attr, 3671 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3672 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3673 args.table.act_templ_id)), 3674 .call = parse_table, 3675 }, 3676 /* Top-level command. */ 3677 [FLOW_GROUP] = { 3678 .name = "group", 3679 .help = "manage flow groups", 3680 .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), 3681 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3682 .call = parse_group, 3683 }, 3684 /* Sub-level commands. */ 3685 [GROUP_SET_MISS_ACTIONS] = { 3686 .name = "set_miss_actions", 3687 .help = "set group miss actions", 3688 .next = NEXT(next_action), 3689 .call = parse_group, 3690 }, 3691 /* Group arguments */ 3692 [GROUP_ID] = { 3693 .name = "group_id", 3694 .help = "group id", 3695 .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3696 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3697 }, 3698 [GROUP_INGRESS] = { 3699 .name = "ingress", 3700 .help = "group ingress attr", 3701 .next = NEXT(next_group_attr), 3702 .call = parse_group, 3703 }, 3704 [GROUP_EGRESS] = { 3705 .name = "egress", 3706 .help = "group egress attr", 3707 .next = NEXT(next_group_attr), 3708 .call = parse_group, 3709 }, 3710 [GROUP_TRANSFER] = { 3711 .name = "transfer", 3712 .help = "group transfer attr", 3713 .next = NEXT(next_group_attr), 3714 .call = parse_group, 3715 }, 3716 /* Top-level command. */ 3717 [QUEUE] = { 3718 .name = "queue", 3719 .help = "queue a flow rule operation", 3720 .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3721 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3722 .call = parse_qo, 3723 }, 3724 /* Sub-level commands. */ 3725 [QUEUE_CREATE] = { 3726 .name = "create", 3727 .help = "create a flow rule", 3728 .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), 3729 NEXT_ENTRY(COMMON_QUEUE_ID)), 3730 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3731 .call = parse_qo, 3732 }, 3733 [QUEUE_DESTROY] = { 3734 .name = "destroy", 3735 .help = "destroy a flow rule", 3736 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_POSTPONE), 3737 NEXT_ENTRY(COMMON_QUEUE_ID)), 3738 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3739 .call = parse_qo_destroy, 3740 }, 3741 [QUEUE_FLOW_UPDATE_RESIZED] = { 3742 .name = "update_resized", 3743 .help = "update a flow after table resize", 3744 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3745 NEXT_ENTRY(COMMON_QUEUE_ID)), 3746 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3747 .call = parse_qo_destroy, 3748 }, 3749 [QUEUE_UPDATE] = { 3750 .name = "update", 3751 .help = "update a flow rule", 3752 .next = NEXT(NEXT_ENTRY(QUEUE_UPDATE_ID), 3753 NEXT_ENTRY(COMMON_QUEUE_ID)), 3754 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3755 .call = parse_qo, 3756 }, 3757 [QUEUE_AGED] = { 3758 .name = "aged", 3759 .help = "list and destroy aged flows", 3760 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), 3761 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3762 .call = parse_aged, 3763 }, 3764 [QUEUE_INDIRECT_ACTION] = { 3765 .name = "indirect_action", 3766 .help = "queue indirect actions", 3767 .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), 3768 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3769 .call = parse_qia, 3770 }, 3771 /* Queue arguments. */ 3772 [QUEUE_TEMPLATE_TABLE] = { 3773 .name = "template_table", 3774 .help = "specify table id", 3775 .next = NEXT(next_async_insert_subcmd, 3776 NEXT_ENTRY(COMMON_TABLE_ID)), 3777 .args = ARGS(ARGS_ENTRY(struct buffer, 3778 args.vc.table_id)), 3779 .call = parse_qo, 3780 }, 3781 [QUEUE_PATTERN_TEMPLATE] = { 3782 .name = "pattern_template", 3783 .help = "specify pattern template index", 3784 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3785 NEXT_ENTRY(COMMON_UNSIGNED)), 3786 .args = ARGS(ARGS_ENTRY(struct buffer, 3787 args.vc.pat_templ_id)), 3788 .call = parse_qo, 3789 }, 3790 [QUEUE_ACTIONS_TEMPLATE] = { 3791 .name = "actions_template", 3792 .help = "specify actions template index", 3793 .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), 3794 NEXT_ENTRY(COMMON_UNSIGNED)), 3795 .args = ARGS(ARGS_ENTRY(struct buffer, 3796 args.vc.act_templ_id)), 3797 .call = parse_qo, 3798 }, 3799 [QUEUE_RULE_ID] = { 3800 .name = "rule_index", 3801 .help = "specify flow rule index", 3802 .next = NEXT(next_async_pattern_subcmd, 3803 NEXT_ENTRY(COMMON_UNSIGNED)), 3804 .args = ARGS(ARGS_ENTRY(struct buffer, 3805 args.vc.rule_id)), 3806 .call = parse_qo, 3807 }, 3808 [QUEUE_CREATE_POSTPONE] = { 3809 .name = "postpone", 3810 .help = "postpone create operation", 3811 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3812 NEXT_ENTRY(COMMON_BOOLEAN)), 3813 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3814 .call = parse_qo, 3815 }, 3816 [QUEUE_DESTROY_POSTPONE] = { 3817 .name = "postpone", 3818 .help = "postpone destroy operation", 3819 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3820 NEXT_ENTRY(COMMON_BOOLEAN)), 3821 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3822 .call = parse_qo_destroy, 3823 }, 3824 [QUEUE_DESTROY_ID] = { 3825 .name = "rule", 3826 .help = "specify rule id to destroy", 3827 .next = NEXT(next_queue_destroy_attr, 3828 NEXT_ENTRY(COMMON_UNSIGNED)), 3829 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3830 args.destroy.rule)), 3831 .call = parse_qo_destroy, 3832 }, 3833 [QUEUE_UPDATE_ID] = { 3834 .name = "rule", 3835 .help = "specify rule id to update", 3836 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3837 NEXT_ENTRY(COMMON_UNSIGNED)), 3838 .args = ARGS(ARGS_ENTRY(struct buffer, 3839 args.vc.rule_id)), 3840 .call = parse_qo, 3841 }, 3842 /* Queue indirect action arguments */ 3843 [QUEUE_INDIRECT_ACTION_CREATE] = { 3844 .name = "create", 3845 .help = "create indirect action", 3846 .next = NEXT(next_qia_create_attr), 3847 .call = parse_qia, 3848 }, 3849 [QUEUE_INDIRECT_ACTION_UPDATE] = { 3850 .name = "update", 3851 .help = "update indirect action", 3852 .next = NEXT(next_qia_update_attr, 3853 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3854 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3855 .call = parse_qia, 3856 }, 3857 [QUEUE_INDIRECT_ACTION_DESTROY] = { 3858 .name = "destroy", 3859 .help = "destroy indirect action", 3860 .next = NEXT(next_qia_destroy_attr), 3861 .call = parse_qia_destroy, 3862 }, 3863 [QUEUE_INDIRECT_ACTION_QUERY] = { 3864 .name = "query", 3865 .help = "query indirect action", 3866 .next = NEXT(next_qia_query_attr, 3867 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3868 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3869 .call = parse_qia, 3870 }, 3871 /* Indirect action destroy arguments. */ 3872 [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { 3873 .name = "postpone", 3874 .help = "postpone destroy operation", 3875 .next = NEXT(next_qia_destroy_attr, 3876 NEXT_ENTRY(COMMON_BOOLEAN)), 3877 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3878 }, 3879 [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { 3880 .name = "action_id", 3881 .help = "specify a indirect action id to destroy", 3882 .next = NEXT(next_qia_destroy_attr, 3883 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3884 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3885 args.ia_destroy.action_id)), 3886 .call = parse_qia_destroy, 3887 }, 3888 [QUEUE_INDIRECT_ACTION_QUERY_UPDATE] = { 3889 .name = "query_update", 3890 .help = "indirect query [and|or] update action", 3891 .next = NEXT(next_qia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3892 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3893 .call = parse_qia 3894 }, 3895 [QUEUE_INDIRECT_ACTION_QU_MODE] = { 3896 .name = "mode", 3897 .help = "indirect query [and|or] update action", 3898 .next = NEXT(next_qia_qu_attr, 3899 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 3900 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 3901 .call = parse_qia 3902 }, 3903 /* Indirect action update arguments. */ 3904 [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { 3905 .name = "postpone", 3906 .help = "postpone update operation", 3907 .next = NEXT(next_qia_update_attr, 3908 NEXT_ENTRY(COMMON_BOOLEAN)), 3909 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3910 }, 3911 /* Indirect action update arguments. */ 3912 [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { 3913 .name = "postpone", 3914 .help = "postpone query operation", 3915 .next = NEXT(next_qia_query_attr, 3916 NEXT_ENTRY(COMMON_BOOLEAN)), 3917 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3918 }, 3919 /* Indirect action create arguments. */ 3920 [QUEUE_INDIRECT_ACTION_CREATE_ID] = { 3921 .name = "action_id", 3922 .help = "specify a indirect action id to create", 3923 .next = NEXT(next_qia_create_attr, 3924 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3925 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3926 }, 3927 [QUEUE_INDIRECT_ACTION_INGRESS] = { 3928 .name = "ingress", 3929 .help = "affect rule to ingress", 3930 .next = NEXT(next_qia_create_attr), 3931 .call = parse_qia, 3932 }, 3933 [QUEUE_INDIRECT_ACTION_EGRESS] = { 3934 .name = "egress", 3935 .help = "affect rule to egress", 3936 .next = NEXT(next_qia_create_attr), 3937 .call = parse_qia, 3938 }, 3939 [QUEUE_INDIRECT_ACTION_TRANSFER] = { 3940 .name = "transfer", 3941 .help = "affect rule to transfer", 3942 .next = NEXT(next_qia_create_attr), 3943 .call = parse_qia, 3944 }, 3945 [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { 3946 .name = "postpone", 3947 .help = "postpone create operation", 3948 .next = NEXT(next_qia_create_attr, 3949 NEXT_ENTRY(COMMON_BOOLEAN)), 3950 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3951 }, 3952 [QUEUE_INDIRECT_ACTION_SPEC] = { 3953 .name = "action", 3954 .help = "specify action to create indirect handle", 3955 .next = NEXT(next_action), 3956 }, 3957 [QUEUE_INDIRECT_ACTION_LIST] = { 3958 .name = "list", 3959 .help = "specify actions for indirect handle list", 3960 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 3961 .call = parse_qia, 3962 }, 3963 /* Top-level command. */ 3964 [PUSH] = { 3965 .name = "push", 3966 .help = "push enqueued operations", 3967 .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3968 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3969 .call = parse_push, 3970 }, 3971 /* Sub-level commands. */ 3972 [PUSH_QUEUE] = { 3973 .name = "queue", 3974 .help = "specify queue id", 3975 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3976 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3977 }, 3978 /* Top-level command. */ 3979 [PULL] = { 3980 .name = "pull", 3981 .help = "pull flow operations results", 3982 .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3983 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3984 .call = parse_pull, 3985 }, 3986 /* Sub-level commands. */ 3987 [PULL_QUEUE] = { 3988 .name = "queue", 3989 .help = "specify queue id", 3990 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3991 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3992 }, 3993 /* Top-level command. */ 3994 [HASH] = { 3995 .name = "hash", 3996 .help = "calculate hash for a given pattern in a given template table", 3997 .next = NEXT(next_hash_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3998 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3999 .call = parse_hash, 4000 }, 4001 /* Sub-level commands. */ 4002 [HASH_CALC_TABLE] = { 4003 .name = "template_table", 4004 .help = "specify table id", 4005 .next = NEXT(NEXT_ENTRY(HASH_CALC_PATTERN_INDEX), 4006 NEXT_ENTRY(COMMON_TABLE_ID)), 4007 .args = ARGS(ARGS_ENTRY(struct buffer, 4008 args.vc.table_id)), 4009 .call = parse_hash, 4010 }, 4011 [HASH_CALC_ENCAP] = { 4012 .name = "encap", 4013 .help = "calculates encap hash", 4014 .next = NEXT(next_hash_encap_dest_subcmd), 4015 .call = parse_hash, 4016 }, 4017 [HASH_CALC_PATTERN_INDEX] = { 4018 .name = "pattern_template", 4019 .help = "specify pattern template id", 4020 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 4021 NEXT_ENTRY(COMMON_UNSIGNED)), 4022 .args = ARGS(ARGS_ENTRY(struct buffer, 4023 args.vc.pat_templ_id)), 4024 .call = parse_hash, 4025 }, 4026 [ENCAP_HASH_FIELD_SRC_PORT] = { 4027 .name = "hash_field_sport", 4028 .help = "the encap hash field is src port", 4029 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 4030 .call = parse_hash, 4031 }, 4032 [ENCAP_HASH_FIELD_GRE_FLOW_ID] = { 4033 .name = "hash_field_flow_id", 4034 .help = "the encap hash field is NVGRE flow id", 4035 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 4036 .call = parse_hash, 4037 }, 4038 /* Top-level command. */ 4039 [INDIRECT_ACTION] = { 4040 .name = "indirect_action", 4041 .type = "{command} {port_id} [{arg} [...]]", 4042 .help = "manage indirect actions", 4043 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4044 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4045 .call = parse_ia, 4046 }, 4047 /* Sub-level commands. */ 4048 [INDIRECT_ACTION_CREATE] = { 4049 .name = "create", 4050 .help = "create indirect action", 4051 .next = NEXT(next_ia_create_attr), 4052 .call = parse_ia, 4053 }, 4054 [INDIRECT_ACTION_UPDATE] = { 4055 .name = "update", 4056 .help = "update indirect action", 4057 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), 4058 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4059 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 4060 .call = parse_ia, 4061 }, 4062 [INDIRECT_ACTION_DESTROY] = { 4063 .name = "destroy", 4064 .help = "destroy indirect action", 4065 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), 4066 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4067 .call = parse_ia_destroy, 4068 }, 4069 [INDIRECT_ACTION_QUERY] = { 4070 .name = "query", 4071 .help = "query indirect action", 4072 .next = NEXT(NEXT_ENTRY(END), 4073 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4074 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4075 .call = parse_ia, 4076 }, 4077 [INDIRECT_ACTION_QUERY_UPDATE] = { 4078 .name = "query_update", 4079 .help = "query [and|or] update", 4080 .next = NEXT(next_ia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4081 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4082 .call = parse_ia 4083 }, 4084 [INDIRECT_ACTION_QU_MODE] = { 4085 .name = "mode", 4086 .help = "query_update mode", 4087 .next = NEXT(next_ia_qu_attr, 4088 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 4089 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 4090 .call = parse_ia, 4091 }, 4092 [INDIRECT_ACTION_QU_MODE_NAME] = { 4093 .name = "mode_name", 4094 .help = "query-update mode name", 4095 .call = parse_qu_mode_name, 4096 .comp = comp_qu_mode_name, 4097 }, 4098 [VALIDATE] = { 4099 .name = "validate", 4100 .help = "check whether a flow rule can be created", 4101 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4102 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4103 .call = parse_vc, 4104 }, 4105 [CREATE] = { 4106 .name = "create", 4107 .help = "create a flow rule", 4108 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4109 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4110 .call = parse_vc, 4111 }, 4112 [DESTROY] = { 4113 .name = "destroy", 4114 .help = "destroy specific flow rules", 4115 .next = NEXT(next_destroy_attr, 4116 NEXT_ENTRY(COMMON_PORT_ID)), 4117 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4118 .call = parse_destroy, 4119 }, 4120 [UPDATE] = { 4121 .name = "update", 4122 .help = "update a flow rule with new actions", 4123 .next = NEXT(NEXT_ENTRY(VC_IS_USER_ID, END), 4124 NEXT_ENTRY(ACTIONS), 4125 NEXT_ENTRY(COMMON_RULE_ID), 4126 NEXT_ENTRY(COMMON_PORT_ID)), 4127 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.rule_id), 4128 ARGS_ENTRY(struct buffer, port)), 4129 .call = parse_vc, 4130 }, 4131 [FLUSH] = { 4132 .name = "flush", 4133 .help = "destroy all flow rules", 4134 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4135 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4136 .call = parse_flush, 4137 }, 4138 [DUMP] = { 4139 .name = "dump", 4140 .help = "dump single/all flow rules to file", 4141 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4142 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4143 .call = parse_dump, 4144 }, 4145 [QUERY] = { 4146 .name = "query", 4147 .help = "query an existing flow rule", 4148 .next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION), 4149 NEXT_ENTRY(COMMON_RULE_ID), 4150 NEXT_ENTRY(COMMON_PORT_ID)), 4151 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), 4152 ARGS_ENTRY(struct buffer, args.query.rule), 4153 ARGS_ENTRY(struct buffer, port)), 4154 .call = parse_query, 4155 }, 4156 [LIST] = { 4157 .name = "list", 4158 .help = "list existing flow rules", 4159 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4160 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4161 .call = parse_list, 4162 }, 4163 [AGED] = { 4164 .name = "aged", 4165 .help = "list and destroy aged flows", 4166 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4167 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4168 .call = parse_aged, 4169 }, 4170 [ISOLATE] = { 4171 .name = "isolate", 4172 .help = "restrict ingress traffic to the defined flow rules", 4173 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), 4174 NEXT_ENTRY(COMMON_PORT_ID)), 4175 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), 4176 ARGS_ENTRY(struct buffer, port)), 4177 .call = parse_isolate, 4178 }, 4179 [FLEX] = { 4180 .name = "flex_item", 4181 .help = "flex item API", 4182 .next = NEXT(next_flex_item), 4183 .call = parse_flex, 4184 }, 4185 [FLEX_ITEM_CREATE] = { 4186 .name = "create", 4187 .help = "flex item create", 4188 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), 4189 ARGS_ENTRY(struct buffer, args.flex.token), 4190 ARGS_ENTRY(struct buffer, port)), 4191 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), 4192 NEXT_ENTRY(COMMON_FLEX_TOKEN), 4193 NEXT_ENTRY(COMMON_PORT_ID)), 4194 .call = parse_flex 4195 }, 4196 [FLEX_ITEM_DESTROY] = { 4197 .name = "destroy", 4198 .help = "flex item destroy", 4199 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4200 ARGS_ENTRY(struct buffer, port)), 4201 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4202 NEXT_ENTRY(COMMON_PORT_ID)), 4203 .call = parse_flex 4204 }, 4205 [TUNNEL] = { 4206 .name = "tunnel", 4207 .help = "new tunnel API", 4208 .next = NEXT(NEXT_ENTRY 4209 (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), 4210 .call = parse_tunnel, 4211 }, 4212 /* Tunnel arguments. */ 4213 [TUNNEL_CREATE] = { 4214 .name = "create", 4215 .help = "create new tunnel object", 4216 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), 4217 NEXT_ENTRY(COMMON_PORT_ID)), 4218 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4219 .call = parse_tunnel, 4220 }, 4221 [TUNNEL_CREATE_TYPE] = { 4222 .name = "type", 4223 .help = "create new tunnel", 4224 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), 4225 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), 4226 .call = parse_tunnel, 4227 }, 4228 [TUNNEL_DESTROY] = { 4229 .name = "destroy", 4230 .help = "destroy tunnel", 4231 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), 4232 NEXT_ENTRY(COMMON_PORT_ID)), 4233 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4234 .call = parse_tunnel, 4235 }, 4236 [TUNNEL_DESTROY_ID] = { 4237 .name = "id", 4238 .help = "tunnel identifier to destroy", 4239 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), 4240 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4241 .call = parse_tunnel, 4242 }, 4243 [TUNNEL_LIST] = { 4244 .name = "list", 4245 .help = "list existing tunnels", 4246 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4247 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4248 .call = parse_tunnel, 4249 }, 4250 /* Destroy arguments. */ 4251 [DESTROY_RULE] = { 4252 .name = "rule", 4253 .help = "specify a rule identifier", 4254 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4255 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), 4256 .call = parse_destroy, 4257 }, 4258 [DESTROY_IS_USER_ID] = { 4259 .name = "user_id", 4260 .help = "rule identifier is user-id", 4261 .next = NEXT(next_destroy_attr), 4262 .call = parse_destroy, 4263 }, 4264 /* Dump arguments. */ 4265 [DUMP_ALL] = { 4266 .name = "all", 4267 .help = "dump all", 4268 .next = NEXT(next_dump_attr), 4269 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), 4270 .call = parse_dump, 4271 }, 4272 [DUMP_ONE] = { 4273 .name = "rule", 4274 .help = "dump one rule", 4275 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4276 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), 4277 ARGS_ENTRY(struct buffer, args.dump.rule)), 4278 .call = parse_dump, 4279 }, 4280 [DUMP_IS_USER_ID] = { 4281 .name = "user_id", 4282 .help = "rule identifier is user-id", 4283 .next = NEXT(next_dump_subcmd), 4284 .call = parse_dump, 4285 }, 4286 /* Query arguments. */ 4287 [QUERY_ACTION] = { 4288 .name = "{action}", 4289 .type = "ACTION", 4290 .help = "action to query, must be part of the rule", 4291 .call = parse_action, 4292 .comp = comp_action, 4293 }, 4294 [QUERY_IS_USER_ID] = { 4295 .name = "user_id", 4296 .help = "rule identifier is user-id", 4297 .next = NEXT(next_query_attr), 4298 .call = parse_query, 4299 }, 4300 /* List arguments. */ 4301 [LIST_GROUP] = { 4302 .name = "group", 4303 .help = "specify a group", 4304 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4305 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), 4306 .call = parse_list, 4307 }, 4308 [AGED_DESTROY] = { 4309 .name = "destroy", 4310 .help = "specify aged flows need be destroyed", 4311 .call = parse_aged, 4312 .comp = comp_none, 4313 }, 4314 /* Validate/create attributes. */ 4315 [VC_GROUP] = { 4316 .name = "group", 4317 .help = "specify a group", 4318 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4319 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), 4320 .call = parse_vc, 4321 }, 4322 [VC_PRIORITY] = { 4323 .name = "priority", 4324 .help = "specify a priority level", 4325 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 4326 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), 4327 .call = parse_vc, 4328 }, 4329 [VC_INGRESS] = { 4330 .name = "ingress", 4331 .help = "affect rule to ingress", 4332 .next = NEXT(next_vc_attr), 4333 .call = parse_vc, 4334 }, 4335 [VC_EGRESS] = { 4336 .name = "egress", 4337 .help = "affect rule to egress", 4338 .next = NEXT(next_vc_attr), 4339 .call = parse_vc, 4340 }, 4341 [VC_TRANSFER] = { 4342 .name = "transfer", 4343 .help = "apply rule directly to endpoints found in pattern", 4344 .next = NEXT(next_vc_attr), 4345 .call = parse_vc, 4346 }, 4347 [VC_TUNNEL_SET] = { 4348 .name = "tunnel_set", 4349 .help = "tunnel steer rule", 4350 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4351 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4352 .call = parse_vc, 4353 }, 4354 [VC_TUNNEL_MATCH] = { 4355 .name = "tunnel_match", 4356 .help = "tunnel match rule", 4357 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4358 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4359 .call = parse_vc, 4360 }, 4361 [VC_USER_ID] = { 4362 .name = "user_id", 4363 .help = "specify a user id to create", 4364 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4365 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)), 4366 .call = parse_vc, 4367 }, 4368 [VC_IS_USER_ID] = { 4369 .name = "user_id", 4370 .help = "rule identifier is user-id", 4371 .call = parse_vc, 4372 }, 4373 /* Validate/create pattern. */ 4374 [ITEM_PATTERN] = { 4375 .name = "pattern", 4376 .help = "submit a list of pattern items", 4377 .next = NEXT(next_item), 4378 .call = parse_vc, 4379 }, 4380 [ITEM_PARAM_IS] = { 4381 .name = "is", 4382 .help = "match value perfectly (with full bit-mask)", 4383 .call = parse_vc_spec, 4384 }, 4385 [ITEM_PARAM_SPEC] = { 4386 .name = "spec", 4387 .help = "match value according to configured bit-mask", 4388 .call = parse_vc_spec, 4389 }, 4390 [ITEM_PARAM_LAST] = { 4391 .name = "last", 4392 .help = "specify upper bound to establish a range", 4393 .call = parse_vc_spec, 4394 }, 4395 [ITEM_PARAM_MASK] = { 4396 .name = "mask", 4397 .help = "specify bit-mask with relevant bits set to one", 4398 .call = parse_vc_spec, 4399 }, 4400 [ITEM_PARAM_PREFIX] = { 4401 .name = "prefix", 4402 .help = "generate bit-mask from a prefix length", 4403 .call = parse_vc_spec, 4404 }, 4405 [ITEM_NEXT] = { 4406 .name = "/", 4407 .help = "specify next pattern item", 4408 .next = NEXT(next_item), 4409 }, 4410 [ITEM_END] = { 4411 .name = "end", 4412 .help = "end list of pattern items", 4413 .priv = PRIV_ITEM(END, 0), 4414 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 4415 .call = parse_vc, 4416 }, 4417 [ITEM_VOID] = { 4418 .name = "void", 4419 .help = "no-op pattern item", 4420 .priv = PRIV_ITEM(VOID, 0), 4421 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4422 .call = parse_vc, 4423 }, 4424 [ITEM_INVERT] = { 4425 .name = "invert", 4426 .help = "perform actions when pattern does not match", 4427 .priv = PRIV_ITEM(INVERT, 0), 4428 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4429 .call = parse_vc, 4430 }, 4431 [ITEM_ANY] = { 4432 .name = "any", 4433 .help = "match any protocol for the current layer", 4434 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), 4435 .next = NEXT(item_any), 4436 .call = parse_vc, 4437 }, 4438 [ITEM_ANY_NUM] = { 4439 .name = "num", 4440 .help = "number of layers covered", 4441 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4442 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), 4443 }, 4444 [ITEM_PORT_ID] = { 4445 .name = "port_id", 4446 .help = "match traffic from/to a given DPDK port ID", 4447 .priv = PRIV_ITEM(PORT_ID, 4448 sizeof(struct rte_flow_item_port_id)), 4449 .next = NEXT(item_port_id), 4450 .call = parse_vc, 4451 }, 4452 [ITEM_PORT_ID_ID] = { 4453 .name = "id", 4454 .help = "DPDK port ID", 4455 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), 4456 item_param), 4457 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), 4458 }, 4459 [ITEM_MARK] = { 4460 .name = "mark", 4461 .help = "match traffic against value set in previously matched rule", 4462 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), 4463 .next = NEXT(item_mark), 4464 .call = parse_vc, 4465 }, 4466 [ITEM_MARK_ID] = { 4467 .name = "id", 4468 .help = "Integer value to match against", 4469 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), 4470 item_param), 4471 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), 4472 }, 4473 [ITEM_RAW] = { 4474 .name = "raw", 4475 .help = "match an arbitrary byte string", 4476 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), 4477 .next = NEXT(item_raw), 4478 .call = parse_vc, 4479 }, 4480 [ITEM_RAW_RELATIVE] = { 4481 .name = "relative", 4482 .help = "look for pattern after the previous item", 4483 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4484 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4485 relative, 1)), 4486 }, 4487 [ITEM_RAW_SEARCH] = { 4488 .name = "search", 4489 .help = "search pattern from offset (see also limit)", 4490 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4491 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4492 search, 1)), 4493 }, 4494 [ITEM_RAW_OFFSET] = { 4495 .name = "offset", 4496 .help = "absolute or relative offset for pattern", 4497 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), 4498 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), 4499 }, 4500 [ITEM_RAW_LIMIT] = { 4501 .name = "limit", 4502 .help = "search area limit for start of pattern", 4503 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4504 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), 4505 }, 4506 [ITEM_RAW_PATTERN] = { 4507 .name = "pattern", 4508 .help = "byte string to look for", 4509 .next = NEXT(item_raw, 4510 NEXT_ENTRY(COMMON_STRING), 4511 NEXT_ENTRY(ITEM_PARAM_IS, 4512 ITEM_PARAM_SPEC, 4513 ITEM_PARAM_MASK)), 4514 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4515 ARGS_ENTRY(struct rte_flow_item_raw, length), 4516 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4517 ITEM_RAW_PATTERN_SIZE)), 4518 }, 4519 [ITEM_RAW_PATTERN_HEX] = { 4520 .name = "pattern_hex", 4521 .help = "hex string to look for", 4522 .next = NEXT(item_raw, 4523 NEXT_ENTRY(COMMON_HEX), 4524 NEXT_ENTRY(ITEM_PARAM_IS, 4525 ITEM_PARAM_SPEC, 4526 ITEM_PARAM_MASK)), 4527 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4528 ARGS_ENTRY(struct rte_flow_item_raw, length), 4529 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4530 ITEM_RAW_PATTERN_SIZE)), 4531 }, 4532 [ITEM_ETH] = { 4533 .name = "eth", 4534 .help = "match Ethernet header", 4535 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), 4536 .next = NEXT(item_eth), 4537 .call = parse_vc, 4538 }, 4539 [ITEM_ETH_DST] = { 4540 .name = "dst", 4541 .help = "destination MAC", 4542 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4543 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), 4544 }, 4545 [ITEM_ETH_SRC] = { 4546 .name = "src", 4547 .help = "source MAC", 4548 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4549 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), 4550 }, 4551 [ITEM_ETH_TYPE] = { 4552 .name = "type", 4553 .help = "EtherType", 4554 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4555 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), 4556 }, 4557 [ITEM_ETH_HAS_VLAN] = { 4558 .name = "has_vlan", 4559 .help = "packet header contains VLAN", 4560 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4561 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, 4562 has_vlan, 1)), 4563 }, 4564 [ITEM_VLAN] = { 4565 .name = "vlan", 4566 .help = "match 802.1Q/ad VLAN tag", 4567 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), 4568 .next = NEXT(item_vlan), 4569 .call = parse_vc, 4570 }, 4571 [ITEM_VLAN_TCI] = { 4572 .name = "tci", 4573 .help = "tag control information", 4574 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4575 item_param), 4576 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, hdr.vlan_tci)), 4577 }, 4578 [ITEM_VLAN_PCP] = { 4579 .name = "pcp", 4580 .help = "priority code point", 4581 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4582 item_param), 4583 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4584 hdr.vlan_tci, "\xe0\x00")), 4585 }, 4586 [ITEM_VLAN_DEI] = { 4587 .name = "dei", 4588 .help = "drop eligible indicator", 4589 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4590 item_param), 4591 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4592 hdr.vlan_tci, "\x10\x00")), 4593 }, 4594 [ITEM_VLAN_VID] = { 4595 .name = "vid", 4596 .help = "VLAN identifier", 4597 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4598 item_param), 4599 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4600 hdr.vlan_tci, "\x0f\xff")), 4601 }, 4602 [ITEM_VLAN_INNER_TYPE] = { 4603 .name = "inner_type", 4604 .help = "inner EtherType", 4605 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4606 item_param), 4607 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, 4608 hdr.eth_proto)), 4609 }, 4610 [ITEM_VLAN_HAS_MORE_VLAN] = { 4611 .name = "has_more_vlan", 4612 .help = "packet header contains another VLAN", 4613 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4614 item_param), 4615 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, 4616 has_more_vlan, 1)), 4617 }, 4618 [ITEM_IPV4] = { 4619 .name = "ipv4", 4620 .help = "match IPv4 header", 4621 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), 4622 .next = NEXT(item_ipv4), 4623 .call = parse_vc, 4624 }, 4625 [ITEM_IPV4_VER_IHL] = { 4626 .name = "version_ihl", 4627 .help = "match header length", 4628 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4629 item_param), 4630 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, 4631 hdr.version_ihl)), 4632 }, 4633 [ITEM_IPV4_TOS] = { 4634 .name = "tos", 4635 .help = "type of service", 4636 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4637 item_param), 4638 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4639 hdr.type_of_service)), 4640 }, 4641 [ITEM_IPV4_LENGTH] = { 4642 .name = "length", 4643 .help = "total length", 4644 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4645 item_param), 4646 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4647 hdr.total_length)), 4648 }, 4649 [ITEM_IPV4_ID] = { 4650 .name = "packet_id", 4651 .help = "fragment packet id", 4652 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4653 item_param), 4654 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4655 hdr.packet_id)), 4656 }, 4657 [ITEM_IPV4_FRAGMENT_OFFSET] = { 4658 .name = "fragment_offset", 4659 .help = "fragmentation flags and fragment offset", 4660 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4661 item_param), 4662 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4663 hdr.fragment_offset)), 4664 }, 4665 [ITEM_IPV4_TTL] = { 4666 .name = "ttl", 4667 .help = "time to live", 4668 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4669 item_param), 4670 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4671 hdr.time_to_live)), 4672 }, 4673 [ITEM_IPV4_PROTO] = { 4674 .name = "proto", 4675 .help = "next protocol ID", 4676 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4677 item_param), 4678 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4679 hdr.next_proto_id)), 4680 }, 4681 [ITEM_IPV4_SRC] = { 4682 .name = "src", 4683 .help = "source address", 4684 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4685 item_param), 4686 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4687 hdr.src_addr)), 4688 }, 4689 [ITEM_IPV4_DST] = { 4690 .name = "dst", 4691 .help = "destination address", 4692 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4693 item_param), 4694 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4695 hdr.dst_addr)), 4696 }, 4697 [ITEM_IPV6] = { 4698 .name = "ipv6", 4699 .help = "match IPv6 header", 4700 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), 4701 .next = NEXT(item_ipv6), 4702 .call = parse_vc, 4703 }, 4704 [ITEM_IPV6_TC] = { 4705 .name = "tc", 4706 .help = "traffic class", 4707 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4708 item_param), 4709 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4710 hdr.vtc_flow, 4711 "\x0f\xf0\x00\x00")), 4712 }, 4713 [ITEM_IPV6_FLOW] = { 4714 .name = "flow", 4715 .help = "flow label", 4716 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4717 item_param), 4718 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4719 hdr.vtc_flow, 4720 "\x00\x0f\xff\xff")), 4721 }, 4722 [ITEM_IPV6_LEN] = { 4723 .name = "length", 4724 .help = "payload length", 4725 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4726 item_param), 4727 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4728 hdr.payload_len)), 4729 }, 4730 [ITEM_IPV6_PROTO] = { 4731 .name = "proto", 4732 .help = "protocol (next header)", 4733 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4734 item_param), 4735 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4736 hdr.proto)), 4737 }, 4738 [ITEM_IPV6_HOP] = { 4739 .name = "hop", 4740 .help = "hop limit", 4741 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4742 item_param), 4743 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4744 hdr.hop_limits)), 4745 }, 4746 [ITEM_IPV6_SRC] = { 4747 .name = "src", 4748 .help = "source address", 4749 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4750 item_param), 4751 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4752 hdr.src_addr)), 4753 }, 4754 [ITEM_IPV6_DST] = { 4755 .name = "dst", 4756 .help = "destination address", 4757 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4758 item_param), 4759 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4760 hdr.dst_addr)), 4761 }, 4762 [ITEM_IPV6_HAS_FRAG_EXT] = { 4763 .name = "has_frag_ext", 4764 .help = "fragment packet attribute", 4765 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4766 item_param), 4767 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, 4768 has_frag_ext, 1)), 4769 }, 4770 [ITEM_IPV6_ROUTING_EXT] = { 4771 .name = "ipv6_routing_ext", 4772 .help = "match IPv6 routing extension header", 4773 .priv = PRIV_ITEM(IPV6_ROUTING_EXT, 4774 sizeof(struct rte_flow_item_ipv6_routing_ext)), 4775 .next = NEXT(item_ipv6_routing_ext), 4776 .call = parse_vc, 4777 }, 4778 [ITEM_IPV6_ROUTING_EXT_TYPE] = { 4779 .name = "ext_type", 4780 .help = "match IPv6 routing extension header type", 4781 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4782 item_param), 4783 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4784 hdr.type)), 4785 }, 4786 [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = { 4787 .name = "ext_next_hdr", 4788 .help = "match IPv6 routing extension header next header type", 4789 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4790 item_param), 4791 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4792 hdr.next_hdr)), 4793 }, 4794 [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = { 4795 .name = "ext_seg_left", 4796 .help = "match IPv6 routing extension header segment left", 4797 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4798 item_param), 4799 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4800 hdr.segments_left)), 4801 }, 4802 [ITEM_ICMP] = { 4803 .name = "icmp", 4804 .help = "match ICMP header", 4805 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), 4806 .next = NEXT(item_icmp), 4807 .call = parse_vc, 4808 }, 4809 [ITEM_ICMP_TYPE] = { 4810 .name = "type", 4811 .help = "ICMP packet type", 4812 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4813 item_param), 4814 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4815 hdr.icmp_type)), 4816 }, 4817 [ITEM_ICMP_CODE] = { 4818 .name = "code", 4819 .help = "ICMP packet code", 4820 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4821 item_param), 4822 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4823 hdr.icmp_code)), 4824 }, 4825 [ITEM_ICMP_IDENT] = { 4826 .name = "ident", 4827 .help = "ICMP packet identifier", 4828 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4829 item_param), 4830 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4831 hdr.icmp_ident)), 4832 }, 4833 [ITEM_ICMP_SEQ] = { 4834 .name = "seq", 4835 .help = "ICMP packet sequence number", 4836 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4837 item_param), 4838 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4839 hdr.icmp_seq_nb)), 4840 }, 4841 [ITEM_UDP] = { 4842 .name = "udp", 4843 .help = "match UDP header", 4844 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), 4845 .next = NEXT(item_udp), 4846 .call = parse_vc, 4847 }, 4848 [ITEM_UDP_SRC] = { 4849 .name = "src", 4850 .help = "UDP source port", 4851 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), 4852 item_param), 4853 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4854 hdr.src_port)), 4855 }, 4856 [ITEM_UDP_DST] = { 4857 .name = "dst", 4858 .help = "UDP destination port", 4859 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4860 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4861 hdr.dst_port)), 4862 }, 4863 [ITEM_TCP] = { 4864 .name = "tcp", 4865 .help = "match TCP header", 4866 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), 4867 .next = NEXT(item_tcp), 4868 .call = parse_vc, 4869 }, 4870 [ITEM_TCP_SRC] = { 4871 .name = "src", 4872 .help = "TCP source port", 4873 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4874 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4875 hdr.src_port)), 4876 }, 4877 [ITEM_TCP_DST] = { 4878 .name = "dst", 4879 .help = "TCP destination port", 4880 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4881 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4882 hdr.dst_port)), 4883 }, 4884 [ITEM_TCP_FLAGS] = { 4885 .name = "flags", 4886 .help = "TCP flags", 4887 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4888 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4889 hdr.tcp_flags)), 4890 }, 4891 [ITEM_SCTP] = { 4892 .name = "sctp", 4893 .help = "match SCTP header", 4894 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), 4895 .next = NEXT(item_sctp), 4896 .call = parse_vc, 4897 }, 4898 [ITEM_SCTP_SRC] = { 4899 .name = "src", 4900 .help = "SCTP source port", 4901 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4902 item_param), 4903 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4904 hdr.src_port)), 4905 }, 4906 [ITEM_SCTP_DST] = { 4907 .name = "dst", 4908 .help = "SCTP destination port", 4909 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4910 item_param), 4911 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4912 hdr.dst_port)), 4913 }, 4914 [ITEM_SCTP_TAG] = { 4915 .name = "tag", 4916 .help = "validation tag", 4917 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4918 item_param), 4919 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4920 hdr.tag)), 4921 }, 4922 [ITEM_SCTP_CKSUM] = { 4923 .name = "cksum", 4924 .help = "checksum", 4925 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4926 item_param), 4927 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4928 hdr.cksum)), 4929 }, 4930 [ITEM_VXLAN] = { 4931 .name = "vxlan", 4932 .help = "match VXLAN header", 4933 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), 4934 .next = NEXT(item_vxlan), 4935 .call = parse_vc, 4936 }, 4937 [ITEM_VXLAN_VNI] = { 4938 .name = "vni", 4939 .help = "VXLAN identifier", 4940 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4941 item_param), 4942 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), 4943 }, 4944 [ITEM_VXLAN_FLAG_G] = { 4945 .name = "flag_g", 4946 .help = "VXLAN GBP bit", 4947 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4948 item_param), 4949 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4950 hdr.flag_g, 1)), 4951 }, 4952 [ITEM_VXLAN_FLAG_VER] = { 4953 .name = "flag_ver", 4954 .help = "VXLAN GPE version", 4955 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4956 item_param), 4957 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4958 hdr.flag_ver, 2)), 4959 }, 4960 [ITEM_VXLAN_FLAG_I] = { 4961 .name = "flag_i", 4962 .help = "VXLAN Instance bit", 4963 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4964 item_param), 4965 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4966 hdr.flag_i, 1)), 4967 }, 4968 [ITEM_VXLAN_FLAG_P] = { 4969 .name = "flag_p", 4970 .help = "VXLAN GPE Next Protocol bit", 4971 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4972 item_param), 4973 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4974 hdr.flag_p, 1)), 4975 }, 4976 [ITEM_VXLAN_FLAG_B] = { 4977 .name = "flag_b", 4978 .help = "VXLAN GPE Ingress-Replicated BUM", 4979 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4980 item_param), 4981 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4982 hdr.flag_b, 1)), 4983 }, 4984 [ITEM_VXLAN_FLAG_O] = { 4985 .name = "flag_o", 4986 .help = "VXLAN GPE OAM Packet bit", 4987 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4988 item_param), 4989 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4990 hdr.flag_o, 1)), 4991 }, 4992 [ITEM_VXLAN_FLAG_D] = { 4993 .name = "flag_d", 4994 .help = "VXLAN GBP Don't Learn bit", 4995 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4996 item_param), 4997 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4998 hdr.flag_d, 1)), 4999 }, 5000 [ITEM_VXLAN_FLAG_A] = { 5001 .name = "flag_a", 5002 .help = "VXLAN GBP Applied bit", 5003 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5004 item_param), 5005 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 5006 hdr.flag_a, 1)), 5007 }, 5008 [ITEM_VXLAN_GBP_ID] = { 5009 .name = "group_policy_id", 5010 .help = "VXLAN GBP ID", 5011 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5012 item_param), 5013 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5014 hdr.policy_id)), 5015 }, 5016 [ITEM_VXLAN_GPE_PROTO] = { 5017 .name = "protocol", 5018 .help = "VXLAN GPE next protocol", 5019 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5020 item_param), 5021 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5022 hdr.proto)), 5023 }, 5024 [ITEM_VXLAN_FIRST_RSVD] = { 5025 .name = "first_rsvd", 5026 .help = "VXLAN rsvd0 first byte", 5027 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5028 item_param), 5029 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5030 hdr.rsvd0[0])), 5031 }, 5032 [ITEM_VXLAN_SECND_RSVD] = { 5033 .name = "second_rsvd", 5034 .help = "VXLAN rsvd0 second byte", 5035 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5036 item_param), 5037 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5038 hdr.rsvd0[1])), 5039 }, 5040 [ITEM_VXLAN_THIRD_RSVD] = { 5041 .name = "third_rsvd", 5042 .help = "VXLAN rsvd0 third byte", 5043 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5044 item_param), 5045 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5046 hdr.rsvd0[2])), 5047 }, 5048 [ITEM_VXLAN_LAST_RSVD] = { 5049 .name = "last_rsvd", 5050 .help = "VXLAN last reserved byte", 5051 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5052 item_param), 5053 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5054 hdr.last_rsvd)), 5055 }, 5056 [ITEM_E_TAG] = { 5057 .name = "e_tag", 5058 .help = "match E-Tag header", 5059 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), 5060 .next = NEXT(item_e_tag), 5061 .call = parse_vc, 5062 }, 5063 [ITEM_E_TAG_GRP_ECID_B] = { 5064 .name = "grp_ecid_b", 5065 .help = "GRP and E-CID base", 5066 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5067 item_param), 5068 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, 5069 rsvd_grp_ecid_b, 5070 "\x3f\xff")), 5071 }, 5072 [ITEM_NVGRE] = { 5073 .name = "nvgre", 5074 .help = "match NVGRE header", 5075 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), 5076 .next = NEXT(item_nvgre), 5077 .call = parse_vc, 5078 }, 5079 [ITEM_NVGRE_TNI] = { 5080 .name = "tni", 5081 .help = "virtual subnet ID", 5082 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), 5083 item_param), 5084 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), 5085 }, 5086 [ITEM_MPLS] = { 5087 .name = "mpls", 5088 .help = "match MPLS header", 5089 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), 5090 .next = NEXT(item_mpls), 5091 .call = parse_vc, 5092 }, 5093 [ITEM_MPLS_LABEL] = { 5094 .name = "label", 5095 .help = "MPLS label", 5096 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5097 item_param), 5098 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5099 label_tc_s, 5100 "\xff\xff\xf0")), 5101 }, 5102 [ITEM_MPLS_TC] = { 5103 .name = "tc", 5104 .help = "MPLS Traffic Class", 5105 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5106 item_param), 5107 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5108 label_tc_s, 5109 "\x00\x00\x0e")), 5110 }, 5111 [ITEM_MPLS_S] = { 5112 .name = "s", 5113 .help = "MPLS Bottom-of-Stack", 5114 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5115 item_param), 5116 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5117 label_tc_s, 5118 "\x00\x00\x01")), 5119 }, 5120 [ITEM_MPLS_TTL] = { 5121 .name = "ttl", 5122 .help = "MPLS Time-to-Live", 5123 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5124 item_param), 5125 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls, ttl)), 5126 }, 5127 [ITEM_GRE] = { 5128 .name = "gre", 5129 .help = "match GRE header", 5130 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), 5131 .next = NEXT(item_gre), 5132 .call = parse_vc, 5133 }, 5134 [ITEM_GRE_PROTO] = { 5135 .name = "protocol", 5136 .help = "GRE protocol type", 5137 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5138 item_param), 5139 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5140 protocol)), 5141 }, 5142 [ITEM_GRE_C_RSVD0_VER] = { 5143 .name = "c_rsvd0_ver", 5144 .help = 5145 "checksum (1b), undefined (1b), key bit (1b)," 5146 " sequence number (1b), reserved 0 (9b)," 5147 " version (3b)", 5148 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5149 item_param), 5150 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5151 c_rsvd0_ver)), 5152 }, 5153 [ITEM_GRE_C_BIT] = { 5154 .name = "c_bit", 5155 .help = "checksum bit (C)", 5156 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), 5157 item_param), 5158 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5159 c_rsvd0_ver, 5160 "\x80\x00\x00\x00")), 5161 }, 5162 [ITEM_GRE_S_BIT] = { 5163 .name = "s_bit", 5164 .help = "sequence number bit (S)", 5165 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5166 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5167 c_rsvd0_ver, 5168 "\x10\x00\x00\x00")), 5169 }, 5170 [ITEM_GRE_K_BIT] = { 5171 .name = "k_bit", 5172 .help = "key bit (K)", 5173 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5174 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5175 c_rsvd0_ver, 5176 "\x20\x00\x00\x00")), 5177 }, 5178 [ITEM_FUZZY] = { 5179 .name = "fuzzy", 5180 .help = "fuzzy pattern match, expect faster than default", 5181 .priv = PRIV_ITEM(FUZZY, 5182 sizeof(struct rte_flow_item_fuzzy)), 5183 .next = NEXT(item_fuzzy), 5184 .call = parse_vc, 5185 }, 5186 [ITEM_FUZZY_THRESH] = { 5187 .name = "thresh", 5188 .help = "match accuracy threshold", 5189 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), 5190 item_param), 5191 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, 5192 thresh)), 5193 }, 5194 [ITEM_GTP] = { 5195 .name = "gtp", 5196 .help = "match GTP header", 5197 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), 5198 .next = NEXT(item_gtp), 5199 .call = parse_vc, 5200 }, 5201 [ITEM_GTP_FLAGS] = { 5202 .name = "v_pt_rsv_flags", 5203 .help = "GTP flags", 5204 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5205 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, 5206 hdr.gtp_hdr_info)), 5207 }, 5208 [ITEM_GTP_MSG_TYPE] = { 5209 .name = "msg_type", 5210 .help = "GTP message type", 5211 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5212 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), 5213 }, 5214 [ITEM_GTP_TEID] = { 5215 .name = "teid", 5216 .help = "tunnel endpoint identifier", 5217 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5218 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), 5219 }, 5220 [ITEM_GTPC] = { 5221 .name = "gtpc", 5222 .help = "match GTP header", 5223 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), 5224 .next = NEXT(item_gtp), 5225 .call = parse_vc, 5226 }, 5227 [ITEM_GTPU] = { 5228 .name = "gtpu", 5229 .help = "match GTP header", 5230 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), 5231 .next = NEXT(item_gtp), 5232 .call = parse_vc, 5233 }, 5234 [ITEM_GENEVE] = { 5235 .name = "geneve", 5236 .help = "match GENEVE header", 5237 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), 5238 .next = NEXT(item_geneve), 5239 .call = parse_vc, 5240 }, 5241 [ITEM_GENEVE_VNI] = { 5242 .name = "vni", 5243 .help = "virtual network identifier", 5244 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5245 item_param), 5246 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), 5247 }, 5248 [ITEM_GENEVE_PROTO] = { 5249 .name = "protocol", 5250 .help = "GENEVE protocol type", 5251 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5252 item_param), 5253 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, 5254 protocol)), 5255 }, 5256 [ITEM_GENEVE_OPTLEN] = { 5257 .name = "optlen", 5258 .help = "GENEVE options length in dwords", 5259 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5260 item_param), 5261 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, 5262 ver_opt_len_o_c_rsvd0, 5263 "\x3f\x00")), 5264 }, 5265 [ITEM_VXLAN_GPE] = { 5266 .name = "vxlan-gpe", 5267 .help = "match VXLAN-GPE header", 5268 .priv = PRIV_ITEM(VXLAN_GPE, 5269 sizeof(struct rte_flow_item_vxlan_gpe)), 5270 .next = NEXT(item_vxlan_gpe), 5271 .call = parse_vc, 5272 }, 5273 [ITEM_VXLAN_GPE_VNI] = { 5274 .name = "vni", 5275 .help = "VXLAN-GPE identifier", 5276 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5277 item_param), 5278 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5279 hdr.vni)), 5280 }, 5281 [ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR] = { 5282 .name = "protocol", 5283 .help = "VXLAN-GPE next protocol", 5284 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5285 item_param), 5286 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5287 protocol)), 5288 }, 5289 [ITEM_VXLAN_GPE_FLAGS] = { 5290 .name = "flags", 5291 .help = "VXLAN-GPE flags", 5292 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5293 item_param), 5294 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5295 flags)), 5296 }, 5297 [ITEM_VXLAN_GPE_RSVD0] = { 5298 .name = "rsvd0", 5299 .help = "VXLAN-GPE rsvd0", 5300 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5301 item_param), 5302 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5303 rsvd0)), 5304 }, 5305 [ITEM_VXLAN_GPE_RSVD1] = { 5306 .name = "rsvd1", 5307 .help = "VXLAN-GPE rsvd1", 5308 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5309 item_param), 5310 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5311 rsvd1)), 5312 }, 5313 [ITEM_ARP_ETH_IPV4] = { 5314 .name = "arp_eth_ipv4", 5315 .help = "match ARP header for Ethernet/IPv4", 5316 .priv = PRIV_ITEM(ARP_ETH_IPV4, 5317 sizeof(struct rte_flow_item_arp_eth_ipv4)), 5318 .next = NEXT(item_arp_eth_ipv4), 5319 .call = parse_vc, 5320 }, 5321 [ITEM_ARP_ETH_IPV4_SHA] = { 5322 .name = "sha", 5323 .help = "sender hardware address", 5324 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5325 item_param), 5326 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5327 hdr.arp_data.arp_sha)), 5328 }, 5329 [ITEM_ARP_ETH_IPV4_SPA] = { 5330 .name = "spa", 5331 .help = "sender IPv4 address", 5332 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5333 item_param), 5334 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5335 hdr.arp_data.arp_sip)), 5336 }, 5337 [ITEM_ARP_ETH_IPV4_THA] = { 5338 .name = "tha", 5339 .help = "target hardware address", 5340 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5341 item_param), 5342 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5343 hdr.arp_data.arp_tha)), 5344 }, 5345 [ITEM_ARP_ETH_IPV4_TPA] = { 5346 .name = "tpa", 5347 .help = "target IPv4 address", 5348 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5349 item_param), 5350 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5351 hdr.arp_data.arp_tip)), 5352 }, 5353 [ITEM_IPV6_EXT] = { 5354 .name = "ipv6_ext", 5355 .help = "match presence of any IPv6 extension header", 5356 .priv = PRIV_ITEM(IPV6_EXT, 5357 sizeof(struct rte_flow_item_ipv6_ext)), 5358 .next = NEXT(item_ipv6_ext), 5359 .call = parse_vc, 5360 }, 5361 [ITEM_IPV6_EXT_NEXT_HDR] = { 5362 .name = "next_hdr", 5363 .help = "next header", 5364 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5365 item_param), 5366 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 5367 next_hdr)), 5368 }, 5369 [ITEM_IPV6_FRAG_EXT] = { 5370 .name = "ipv6_frag_ext", 5371 .help = "match presence of IPv6 fragment extension header", 5372 .priv = PRIV_ITEM(IPV6_FRAG_EXT, 5373 sizeof(struct rte_flow_item_ipv6_frag_ext)), 5374 .next = NEXT(item_ipv6_frag_ext), 5375 .call = parse_vc, 5376 }, 5377 [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { 5378 .name = "next_hdr", 5379 .help = "next header", 5380 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5381 item_param), 5382 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, 5383 hdr.next_header)), 5384 }, 5385 [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { 5386 .name = "frag_data", 5387 .help = "fragment flags and offset", 5388 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5389 item_param), 5390 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5391 hdr.frag_data)), 5392 }, 5393 [ITEM_IPV6_FRAG_EXT_ID] = { 5394 .name = "packet_id", 5395 .help = "fragment packet id", 5396 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5397 item_param), 5398 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5399 hdr.id)), 5400 }, 5401 [ITEM_ICMP6] = { 5402 .name = "icmp6", 5403 .help = "match any ICMPv6 header", 5404 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), 5405 .next = NEXT(item_icmp6), 5406 .call = parse_vc, 5407 }, 5408 [ITEM_ICMP6_TYPE] = { 5409 .name = "type", 5410 .help = "ICMPv6 type", 5411 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5412 item_param), 5413 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5414 type)), 5415 }, 5416 [ITEM_ICMP6_CODE] = { 5417 .name = "code", 5418 .help = "ICMPv6 code", 5419 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5420 item_param), 5421 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5422 code)), 5423 }, 5424 [ITEM_ICMP6_ECHO_REQUEST] = { 5425 .name = "icmp6_echo_request", 5426 .help = "match ICMPv6 echo request", 5427 .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, 5428 sizeof(struct rte_flow_item_icmp6_echo)), 5429 .next = NEXT(item_icmp6_echo_request), 5430 .call = parse_vc, 5431 }, 5432 [ITEM_ICMP6_ECHO_REQUEST_ID] = { 5433 .name = "ident", 5434 .help = "ICMPv6 echo request identifier", 5435 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5436 item_param), 5437 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5438 hdr.identifier)), 5439 }, 5440 [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { 5441 .name = "seq", 5442 .help = "ICMPv6 echo request sequence", 5443 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5444 item_param), 5445 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5446 hdr.sequence)), 5447 }, 5448 [ITEM_ICMP6_ECHO_REPLY] = { 5449 .name = "icmp6_echo_reply", 5450 .help = "match ICMPv6 echo reply", 5451 .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, 5452 sizeof(struct rte_flow_item_icmp6_echo)), 5453 .next = NEXT(item_icmp6_echo_reply), 5454 .call = parse_vc, 5455 }, 5456 [ITEM_ICMP6_ECHO_REPLY_ID] = { 5457 .name = "ident", 5458 .help = "ICMPv6 echo reply identifier", 5459 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5460 item_param), 5461 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5462 hdr.identifier)), 5463 }, 5464 [ITEM_ICMP6_ECHO_REPLY_SEQ] = { 5465 .name = "seq", 5466 .help = "ICMPv6 echo reply sequence", 5467 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5468 item_param), 5469 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5470 hdr.sequence)), 5471 }, 5472 [ITEM_ICMP6_ND_NS] = { 5473 .name = "icmp6_nd_ns", 5474 .help = "match ICMPv6 neighbor discovery solicitation", 5475 .priv = PRIV_ITEM(ICMP6_ND_NS, 5476 sizeof(struct rte_flow_item_icmp6_nd_ns)), 5477 .next = NEXT(item_icmp6_nd_ns), 5478 .call = parse_vc, 5479 }, 5480 [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { 5481 .name = "target_addr", 5482 .help = "target address", 5483 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), 5484 item_param), 5485 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, 5486 target_addr)), 5487 }, 5488 [ITEM_ICMP6_ND_NA] = { 5489 .name = "icmp6_nd_na", 5490 .help = "match ICMPv6 neighbor discovery advertisement", 5491 .priv = PRIV_ITEM(ICMP6_ND_NA, 5492 sizeof(struct rte_flow_item_icmp6_nd_na)), 5493 .next = NEXT(item_icmp6_nd_na), 5494 .call = parse_vc, 5495 }, 5496 [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { 5497 .name = "target_addr", 5498 .help = "target address", 5499 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), 5500 item_param), 5501 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, 5502 target_addr)), 5503 }, 5504 [ITEM_ICMP6_ND_OPT] = { 5505 .name = "icmp6_nd_opt", 5506 .help = "match presence of any ICMPv6 neighbor discovery" 5507 " option", 5508 .priv = PRIV_ITEM(ICMP6_ND_OPT, 5509 sizeof(struct rte_flow_item_icmp6_nd_opt)), 5510 .next = NEXT(item_icmp6_nd_opt), 5511 .call = parse_vc, 5512 }, 5513 [ITEM_ICMP6_ND_OPT_TYPE] = { 5514 .name = "type", 5515 .help = "ND option type", 5516 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5517 item_param), 5518 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, 5519 type)), 5520 }, 5521 [ITEM_ICMP6_ND_OPT_SLA_ETH] = { 5522 .name = "icmp6_nd_opt_sla_eth", 5523 .help = "match ICMPv6 neighbor discovery source Ethernet" 5524 " link-layer address option", 5525 .priv = PRIV_ITEM 5526 (ICMP6_ND_OPT_SLA_ETH, 5527 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), 5528 .next = NEXT(item_icmp6_nd_opt_sla_eth), 5529 .call = parse_vc, 5530 }, 5531 [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { 5532 .name = "sla", 5533 .help = "source Ethernet LLA", 5534 .next = NEXT(item_icmp6_nd_opt_sla_eth, 5535 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5536 .args = ARGS(ARGS_ENTRY_HTON 5537 (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), 5538 }, 5539 [ITEM_ICMP6_ND_OPT_TLA_ETH] = { 5540 .name = "icmp6_nd_opt_tla_eth", 5541 .help = "match ICMPv6 neighbor discovery target Ethernet" 5542 " link-layer address option", 5543 .priv = PRIV_ITEM 5544 (ICMP6_ND_OPT_TLA_ETH, 5545 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), 5546 .next = NEXT(item_icmp6_nd_opt_tla_eth), 5547 .call = parse_vc, 5548 }, 5549 [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { 5550 .name = "tla", 5551 .help = "target Ethernet LLA", 5552 .next = NEXT(item_icmp6_nd_opt_tla_eth, 5553 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5554 .args = ARGS(ARGS_ENTRY_HTON 5555 (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), 5556 }, 5557 [ITEM_META] = { 5558 .name = "meta", 5559 .help = "match metadata header", 5560 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), 5561 .next = NEXT(item_meta), 5562 .call = parse_vc, 5563 }, 5564 [ITEM_META_DATA] = { 5565 .name = "data", 5566 .help = "metadata value", 5567 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), 5568 item_param), 5569 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, 5570 data, "\xff\xff\xff\xff")), 5571 }, 5572 [ITEM_RANDOM] = { 5573 .name = "random", 5574 .help = "match random value", 5575 .priv = PRIV_ITEM(RANDOM, sizeof(struct rte_flow_item_random)), 5576 .next = NEXT(item_random), 5577 .call = parse_vc, 5578 }, 5579 [ITEM_RANDOM_VALUE] = { 5580 .name = "value", 5581 .help = "random value", 5582 .next = NEXT(item_random, NEXT_ENTRY(COMMON_UNSIGNED), 5583 item_param), 5584 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_random, 5585 value, "\xff\xff")), 5586 }, 5587 [ITEM_GRE_KEY] = { 5588 .name = "gre_key", 5589 .help = "match GRE key", 5590 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), 5591 .next = NEXT(item_gre_key), 5592 .call = parse_vc, 5593 }, 5594 [ITEM_GRE_KEY_VALUE] = { 5595 .name = "value", 5596 .help = "key value", 5597 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), 5598 item_param), 5599 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5600 }, 5601 [ITEM_GRE_OPTION] = { 5602 .name = "gre_option", 5603 .help = "match GRE optional fields", 5604 .priv = PRIV_ITEM(GRE_OPTION, 5605 sizeof(struct rte_flow_item_gre_opt)), 5606 .next = NEXT(item_gre_option), 5607 .call = parse_vc, 5608 }, 5609 [ITEM_GRE_OPTION_CHECKSUM] = { 5610 .name = "checksum", 5611 .help = "match GRE checksum", 5612 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5613 item_param), 5614 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5615 checksum_rsvd.checksum)), 5616 }, 5617 [ITEM_GRE_OPTION_KEY] = { 5618 .name = "key", 5619 .help = "match GRE key", 5620 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5621 item_param), 5622 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5623 key.key)), 5624 }, 5625 [ITEM_GRE_OPTION_SEQUENCE] = { 5626 .name = "sequence", 5627 .help = "match GRE sequence", 5628 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5629 item_param), 5630 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5631 sequence.sequence)), 5632 }, 5633 [ITEM_GTP_PSC] = { 5634 .name = "gtp_psc", 5635 .help = "match GTP extension header with type 0x85", 5636 .priv = PRIV_ITEM(GTP_PSC, 5637 sizeof(struct rte_flow_item_gtp_psc)), 5638 .next = NEXT(item_gtp_psc), 5639 .call = parse_vc, 5640 }, 5641 [ITEM_GTP_PSC_QFI] = { 5642 .name = "qfi", 5643 .help = "QoS flow identifier", 5644 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5645 item_param), 5646 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5647 hdr.qfi, 6)), 5648 }, 5649 [ITEM_GTP_PSC_PDU_T] = { 5650 .name = "pdu_t", 5651 .help = "PDU type", 5652 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5653 item_param), 5654 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5655 hdr.type, 4)), 5656 }, 5657 [ITEM_PPPOES] = { 5658 .name = "pppoes", 5659 .help = "match PPPoE session header", 5660 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), 5661 .next = NEXT(item_pppoes), 5662 .call = parse_vc, 5663 }, 5664 [ITEM_PPPOED] = { 5665 .name = "pppoed", 5666 .help = "match PPPoE discovery header", 5667 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), 5668 .next = NEXT(item_pppoed), 5669 .call = parse_vc, 5670 }, 5671 [ITEM_PPPOE_SEID] = { 5672 .name = "seid", 5673 .help = "session identifier", 5674 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), 5675 item_param), 5676 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, 5677 session_id)), 5678 }, 5679 [ITEM_PPPOE_PROTO_ID] = { 5680 .name = "pppoe_proto_id", 5681 .help = "match PPPoE session protocol identifier", 5682 .priv = PRIV_ITEM(PPPOE_PROTO_ID, 5683 sizeof(struct rte_flow_item_pppoe_proto_id)), 5684 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED), 5685 item_param), 5686 .args = ARGS(ARGS_ENTRY_HTON 5687 (struct rte_flow_item_pppoe_proto_id, proto_id)), 5688 .call = parse_vc, 5689 }, 5690 [ITEM_HIGIG2] = { 5691 .name = "higig2", 5692 .help = "matches higig2 header", 5693 .priv = PRIV_ITEM(HIGIG2, 5694 sizeof(struct rte_flow_item_higig2_hdr)), 5695 .next = NEXT(item_higig2), 5696 .call = parse_vc, 5697 }, 5698 [ITEM_HIGIG2_CLASSIFICATION] = { 5699 .name = "classification", 5700 .help = "matches classification of higig2 header", 5701 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5702 item_param), 5703 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5704 hdr.ppt1.classification)), 5705 }, 5706 [ITEM_HIGIG2_VID] = { 5707 .name = "vid", 5708 .help = "matches vid of higig2 header", 5709 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5710 item_param), 5711 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5712 hdr.ppt1.vid)), 5713 }, 5714 [ITEM_TAG] = { 5715 .name = "tag", 5716 .help = "match tag value", 5717 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), 5718 .next = NEXT(item_tag), 5719 .call = parse_vc, 5720 }, 5721 [ITEM_TAG_DATA] = { 5722 .name = "data", 5723 .help = "tag value to match", 5724 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5725 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), 5726 }, 5727 [ITEM_TAG_INDEX] = { 5728 .name = "index", 5729 .help = "index of tag array to match", 5730 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5731 NEXT_ENTRY(ITEM_PARAM_IS)), 5732 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), 5733 }, 5734 [ITEM_L2TPV3OIP] = { 5735 .name = "l2tpv3oip", 5736 .help = "match L2TPv3 over IP header", 5737 .priv = PRIV_ITEM(L2TPV3OIP, 5738 sizeof(struct rte_flow_item_l2tpv3oip)), 5739 .next = NEXT(item_l2tpv3oip), 5740 .call = parse_vc, 5741 }, 5742 [ITEM_L2TPV3OIP_SESSION_ID] = { 5743 .name = "session_id", 5744 .help = "session identifier", 5745 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), 5746 item_param), 5747 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, 5748 session_id)), 5749 }, 5750 [ITEM_ESP] = { 5751 .name = "esp", 5752 .help = "match ESP header", 5753 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), 5754 .next = NEXT(item_esp), 5755 .call = parse_vc, 5756 }, 5757 [ITEM_ESP_SPI] = { 5758 .name = "spi", 5759 .help = "security policy index", 5760 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5761 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, 5762 hdr.spi)), 5763 }, 5764 [ITEM_AH] = { 5765 .name = "ah", 5766 .help = "match AH header", 5767 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), 5768 .next = NEXT(item_ah), 5769 .call = parse_vc, 5770 }, 5771 [ITEM_AH_SPI] = { 5772 .name = "spi", 5773 .help = "security parameters index", 5774 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5775 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), 5776 }, 5777 [ITEM_PFCP] = { 5778 .name = "pfcp", 5779 .help = "match pfcp header", 5780 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), 5781 .next = NEXT(item_pfcp), 5782 .call = parse_vc, 5783 }, 5784 [ITEM_PFCP_S_FIELD] = { 5785 .name = "s_field", 5786 .help = "S field", 5787 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5788 item_param), 5789 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, 5790 s_field)), 5791 }, 5792 [ITEM_PFCP_SEID] = { 5793 .name = "seid", 5794 .help = "session endpoint identifier", 5795 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5796 item_param), 5797 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), 5798 }, 5799 [ITEM_ECPRI] = { 5800 .name = "ecpri", 5801 .help = "match eCPRI header", 5802 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), 5803 .next = NEXT(item_ecpri), 5804 .call = parse_vc, 5805 }, 5806 [ITEM_ECPRI_COMMON] = { 5807 .name = "common", 5808 .help = "eCPRI common header", 5809 .next = NEXT(item_ecpri_common), 5810 }, 5811 [ITEM_ECPRI_COMMON_TYPE] = { 5812 .name = "type", 5813 .help = "type of common header", 5814 .next = NEXT(item_ecpri_common_type), 5815 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), 5816 }, 5817 [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { 5818 .name = "iq_data", 5819 .help = "Type #0: IQ Data", 5820 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5821 ITEM_NEXT)), 5822 .call = parse_vc_item_ecpri_type, 5823 }, 5824 [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { 5825 .name = "pc_id", 5826 .help = "Physical Channel ID", 5827 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5828 ITEM_ECPRI_COMMON, ITEM_NEXT), 5829 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5830 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5831 hdr.type0.pc_id)), 5832 }, 5833 [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { 5834 .name = "rtc_ctrl", 5835 .help = "Type #2: Real-Time Control Data", 5836 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5837 ITEM_NEXT)), 5838 .call = parse_vc_item_ecpri_type, 5839 }, 5840 [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { 5841 .name = "rtc_id", 5842 .help = "Real-Time Control Data ID", 5843 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5844 ITEM_ECPRI_COMMON, ITEM_NEXT), 5845 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5846 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5847 hdr.type2.rtc_id)), 5848 }, 5849 [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { 5850 .name = "delay_measure", 5851 .help = "Type #5: One-Way Delay Measurement", 5852 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5853 ITEM_NEXT)), 5854 .call = parse_vc_item_ecpri_type, 5855 }, 5856 [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { 5857 .name = "msr_id", 5858 .help = "Measurement ID", 5859 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5860 ITEM_ECPRI_COMMON, ITEM_NEXT), 5861 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5862 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5863 hdr.type5.msr_id)), 5864 }, 5865 [ITEM_GENEVE_OPT] = { 5866 .name = "geneve-opt", 5867 .help = "GENEVE header option", 5868 .priv = PRIV_ITEM(GENEVE_OPT, 5869 sizeof(struct rte_flow_item_geneve_opt) + 5870 ITEM_GENEVE_OPT_DATA_SIZE), 5871 .next = NEXT(item_geneve_opt), 5872 .call = parse_vc, 5873 }, 5874 [ITEM_GENEVE_OPT_CLASS] = { 5875 .name = "class", 5876 .help = "GENEVE option class", 5877 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5878 item_param), 5879 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, 5880 option_class)), 5881 }, 5882 [ITEM_GENEVE_OPT_TYPE] = { 5883 .name = "type", 5884 .help = "GENEVE option type", 5885 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5886 item_param), 5887 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, 5888 option_type)), 5889 }, 5890 [ITEM_GENEVE_OPT_LENGTH] = { 5891 .name = "length", 5892 .help = "GENEVE option data length (in 32b words)", 5893 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5894 item_param), 5895 .args = ARGS(ARGS_ENTRY_BOUNDED( 5896 struct rte_flow_item_geneve_opt, option_len, 5897 0, 31)), 5898 }, 5899 [ITEM_GENEVE_OPT_DATA] = { 5900 .name = "data", 5901 .help = "GENEVE option data pattern", 5902 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), 5903 item_param), 5904 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), 5905 ARGS_ENTRY_ARB(0, 0), 5906 ARGS_ENTRY_ARB 5907 (sizeof(struct rte_flow_item_geneve_opt), 5908 ITEM_GENEVE_OPT_DATA_SIZE)), 5909 }, 5910 [ITEM_INTEGRITY] = { 5911 .name = "integrity", 5912 .help = "match packet integrity", 5913 .priv = PRIV_ITEM(INTEGRITY, 5914 sizeof(struct rte_flow_item_integrity)), 5915 .next = NEXT(item_integrity), 5916 .call = parse_vc, 5917 }, 5918 [ITEM_INTEGRITY_LEVEL] = { 5919 .name = "level", 5920 .help = "integrity level", 5921 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5922 item_param), 5923 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), 5924 }, 5925 [ITEM_INTEGRITY_VALUE] = { 5926 .name = "value", 5927 .help = "integrity value", 5928 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5929 item_param), 5930 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), 5931 }, 5932 [ITEM_CONNTRACK] = { 5933 .name = "conntrack", 5934 .help = "conntrack state", 5935 .priv = PRIV_ITEM(CONNTRACK, 5936 sizeof(struct rte_flow_item_conntrack)), 5937 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 5938 item_param), 5939 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 5940 .call = parse_vc, 5941 }, 5942 [ITEM_PORT_REPRESENTOR] = { 5943 .name = "port_representor", 5944 .help = "match traffic entering the embedded switch from the given ethdev", 5945 .priv = PRIV_ITEM(PORT_REPRESENTOR, 5946 sizeof(struct rte_flow_item_ethdev)), 5947 .next = NEXT(item_port_representor), 5948 .call = parse_vc, 5949 }, 5950 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 5951 .name = "port_id", 5952 .help = "ethdev port ID", 5953 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 5954 item_param), 5955 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5956 }, 5957 [ITEM_REPRESENTED_PORT] = { 5958 .name = "represented_port", 5959 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 5960 .priv = PRIV_ITEM(REPRESENTED_PORT, 5961 sizeof(struct rte_flow_item_ethdev)), 5962 .next = NEXT(item_represented_port), 5963 .call = parse_vc, 5964 }, 5965 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 5966 .name = "ethdev_port_id", 5967 .help = "ethdev port ID", 5968 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 5969 item_param), 5970 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5971 }, 5972 [ITEM_FLEX] = { 5973 .name = "flex", 5974 .help = "match flex header", 5975 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 5976 .next = NEXT(item_flex), 5977 .call = parse_vc, 5978 }, 5979 [ITEM_FLEX_ITEM_HANDLE] = { 5980 .name = "item", 5981 .help = "flex item handle", 5982 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5983 NEXT_ENTRY(ITEM_PARAM_IS)), 5984 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 5985 }, 5986 [ITEM_FLEX_PATTERN_HANDLE] = { 5987 .name = "pattern", 5988 .help = "flex pattern handle", 5989 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5990 NEXT_ENTRY(ITEM_PARAM_IS)), 5991 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 5992 }, 5993 [ITEM_L2TPV2] = { 5994 .name = "l2tpv2", 5995 .help = "match L2TPv2 header", 5996 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 5997 .next = NEXT(item_l2tpv2), 5998 .call = parse_vc, 5999 }, 6000 [ITEM_L2TPV2_TYPE] = { 6001 .name = "type", 6002 .help = "type of l2tpv2", 6003 .next = NEXT(item_l2tpv2_type), 6004 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 6005 }, 6006 [ITEM_L2TPV2_TYPE_DATA] = { 6007 .name = "data", 6008 .help = "Type #7: data message without any options", 6009 .next = NEXT(item_l2tpv2_type_data), 6010 .call = parse_vc_item_l2tpv2_type, 6011 }, 6012 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 6013 .name = "tunnel_id", 6014 .help = "tunnel identifier", 6015 .next = NEXT(item_l2tpv2_type_data, 6016 NEXT_ENTRY(COMMON_UNSIGNED), 6017 item_param), 6018 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6019 hdr.type7.tunnel_id)), 6020 }, 6021 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 6022 .name = "session_id", 6023 .help = "session identifier", 6024 .next = NEXT(item_l2tpv2_type_data, 6025 NEXT_ENTRY(COMMON_UNSIGNED), 6026 item_param), 6027 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6028 hdr.type7.session_id)), 6029 }, 6030 [ITEM_L2TPV2_TYPE_DATA_L] = { 6031 .name = "data_l", 6032 .help = "Type #6: data message with length option", 6033 .next = NEXT(item_l2tpv2_type_data_l), 6034 .call = parse_vc_item_l2tpv2_type, 6035 }, 6036 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 6037 .name = "length", 6038 .help = "message length", 6039 .next = NEXT(item_l2tpv2_type_data_l, 6040 NEXT_ENTRY(COMMON_UNSIGNED), 6041 item_param), 6042 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6043 hdr.type6.length)), 6044 }, 6045 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 6046 .name = "tunnel_id", 6047 .help = "tunnel identifier", 6048 .next = NEXT(item_l2tpv2_type_data_l, 6049 NEXT_ENTRY(COMMON_UNSIGNED), 6050 item_param), 6051 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6052 hdr.type6.tunnel_id)), 6053 }, 6054 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 6055 .name = "session_id", 6056 .help = "session identifier", 6057 .next = NEXT(item_l2tpv2_type_data_l, 6058 NEXT_ENTRY(COMMON_UNSIGNED), 6059 item_param), 6060 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6061 hdr.type6.session_id)), 6062 }, 6063 [ITEM_L2TPV2_TYPE_DATA_S] = { 6064 .name = "data_s", 6065 .help = "Type #5: data message with ns, nr option", 6066 .next = NEXT(item_l2tpv2_type_data_s), 6067 .call = parse_vc_item_l2tpv2_type, 6068 }, 6069 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 6070 .name = "tunnel_id", 6071 .help = "tunnel identifier", 6072 .next = NEXT(item_l2tpv2_type_data_s, 6073 NEXT_ENTRY(COMMON_UNSIGNED), 6074 item_param), 6075 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6076 hdr.type5.tunnel_id)), 6077 }, 6078 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 6079 .name = "session_id", 6080 .help = "session identifier", 6081 .next = NEXT(item_l2tpv2_type_data_s, 6082 NEXT_ENTRY(COMMON_UNSIGNED), 6083 item_param), 6084 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6085 hdr.type5.session_id)), 6086 }, 6087 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 6088 .name = "ns", 6089 .help = "sequence number for message", 6090 .next = NEXT(item_l2tpv2_type_data_s, 6091 NEXT_ENTRY(COMMON_UNSIGNED), 6092 item_param), 6093 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6094 hdr.type5.ns)), 6095 }, 6096 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 6097 .name = "nr", 6098 .help = "sequence number for next receive message", 6099 .next = NEXT(item_l2tpv2_type_data_s, 6100 NEXT_ENTRY(COMMON_UNSIGNED), 6101 item_param), 6102 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6103 hdr.type5.nr)), 6104 }, 6105 [ITEM_L2TPV2_TYPE_DATA_O] = { 6106 .name = "data_o", 6107 .help = "Type #4: data message with offset option", 6108 .next = NEXT(item_l2tpv2_type_data_o), 6109 .call = parse_vc_item_l2tpv2_type, 6110 }, 6111 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 6112 .name = "tunnel_id", 6113 .help = "tunnel identifier", 6114 .next = NEXT(item_l2tpv2_type_data_o, 6115 NEXT_ENTRY(COMMON_UNSIGNED), 6116 item_param), 6117 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6118 hdr.type4.tunnel_id)), 6119 }, 6120 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 6121 .name = "session_id", 6122 .help = "session identifier", 6123 .next = NEXT(item_l2tpv2_type_data_o, 6124 NEXT_ENTRY(COMMON_UNSIGNED), 6125 item_param), 6126 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6127 hdr.type5.session_id)), 6128 }, 6129 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 6130 .name = "offset_size", 6131 .help = "the size of offset padding", 6132 .next = NEXT(item_l2tpv2_type_data_o, 6133 NEXT_ENTRY(COMMON_UNSIGNED), 6134 item_param), 6135 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6136 hdr.type4.offset_size)), 6137 }, 6138 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 6139 .name = "data_l_s", 6140 .help = "Type #3: data message contains length, ns, nr " 6141 "options", 6142 .next = NEXT(item_l2tpv2_type_data_l_s), 6143 .call = parse_vc_item_l2tpv2_type, 6144 }, 6145 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 6146 .name = "length", 6147 .help = "message length", 6148 .next = NEXT(item_l2tpv2_type_data_l_s, 6149 NEXT_ENTRY(COMMON_UNSIGNED), 6150 item_param), 6151 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6152 hdr.type3.length)), 6153 }, 6154 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 6155 .name = "tunnel_id", 6156 .help = "tunnel identifier", 6157 .next = NEXT(item_l2tpv2_type_data_l_s, 6158 NEXT_ENTRY(COMMON_UNSIGNED), 6159 item_param), 6160 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6161 hdr.type3.tunnel_id)), 6162 }, 6163 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 6164 .name = "session_id", 6165 .help = "session identifier", 6166 .next = NEXT(item_l2tpv2_type_data_l_s, 6167 NEXT_ENTRY(COMMON_UNSIGNED), 6168 item_param), 6169 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6170 hdr.type3.session_id)), 6171 }, 6172 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 6173 .name = "ns", 6174 .help = "sequence number for message", 6175 .next = NEXT(item_l2tpv2_type_data_l_s, 6176 NEXT_ENTRY(COMMON_UNSIGNED), 6177 item_param), 6178 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6179 hdr.type3.ns)), 6180 }, 6181 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 6182 .name = "nr", 6183 .help = "sequence number for next receive message", 6184 .next = NEXT(item_l2tpv2_type_data_l_s, 6185 NEXT_ENTRY(COMMON_UNSIGNED), 6186 item_param), 6187 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6188 hdr.type3.nr)), 6189 }, 6190 [ITEM_L2TPV2_TYPE_CTRL] = { 6191 .name = "control", 6192 .help = "Type #3: conrtol message contains length, ns, nr " 6193 "options", 6194 .next = NEXT(item_l2tpv2_type_ctrl), 6195 .call = parse_vc_item_l2tpv2_type, 6196 }, 6197 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 6198 .name = "length", 6199 .help = "message length", 6200 .next = NEXT(item_l2tpv2_type_ctrl, 6201 NEXT_ENTRY(COMMON_UNSIGNED), 6202 item_param), 6203 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6204 hdr.type3.length)), 6205 }, 6206 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 6207 .name = "tunnel_id", 6208 .help = "tunnel identifier", 6209 .next = NEXT(item_l2tpv2_type_ctrl, 6210 NEXT_ENTRY(COMMON_UNSIGNED), 6211 item_param), 6212 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6213 hdr.type3.tunnel_id)), 6214 }, 6215 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 6216 .name = "session_id", 6217 .help = "session identifier", 6218 .next = NEXT(item_l2tpv2_type_ctrl, 6219 NEXT_ENTRY(COMMON_UNSIGNED), 6220 item_param), 6221 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6222 hdr.type3.session_id)), 6223 }, 6224 [ITEM_L2TPV2_MSG_CTRL_NS] = { 6225 .name = "ns", 6226 .help = "sequence number for message", 6227 .next = NEXT(item_l2tpv2_type_ctrl, 6228 NEXT_ENTRY(COMMON_UNSIGNED), 6229 item_param), 6230 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6231 hdr.type3.ns)), 6232 }, 6233 [ITEM_L2TPV2_MSG_CTRL_NR] = { 6234 .name = "nr", 6235 .help = "sequence number for next receive message", 6236 .next = NEXT(item_l2tpv2_type_ctrl, 6237 NEXT_ENTRY(COMMON_UNSIGNED), 6238 item_param), 6239 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6240 hdr.type3.nr)), 6241 }, 6242 [ITEM_PPP] = { 6243 .name = "ppp", 6244 .help = "match PPP header", 6245 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 6246 .next = NEXT(item_ppp), 6247 .call = parse_vc, 6248 }, 6249 [ITEM_PPP_ADDR] = { 6250 .name = "addr", 6251 .help = "PPP address", 6252 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6253 item_param), 6254 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 6255 }, 6256 [ITEM_PPP_CTRL] = { 6257 .name = "ctrl", 6258 .help = "PPP control", 6259 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6260 item_param), 6261 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 6262 }, 6263 [ITEM_PPP_PROTO_ID] = { 6264 .name = "proto_id", 6265 .help = "PPP protocol identifier", 6266 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6267 item_param), 6268 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 6269 hdr.proto_id)), 6270 }, 6271 [ITEM_METER] = { 6272 .name = "meter", 6273 .help = "match meter color", 6274 .priv = PRIV_ITEM(METER_COLOR, 6275 sizeof(struct rte_flow_item_meter_color)), 6276 .next = NEXT(item_meter), 6277 .call = parse_vc, 6278 }, 6279 [ITEM_METER_COLOR] = { 6280 .name = "color", 6281 .help = "meter color", 6282 .next = NEXT(item_meter, 6283 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 6284 item_param), 6285 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 6286 color)), 6287 }, 6288 [ITEM_METER_COLOR_NAME] = { 6289 .name = "color_name", 6290 .help = "meter color name", 6291 .call = parse_meter_color, 6292 .comp = comp_meter_color, 6293 }, 6294 [ITEM_QUOTA] = { 6295 .name = "quota", 6296 .help = "match quota", 6297 .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), 6298 .next = NEXT(item_quota), 6299 .call = parse_vc 6300 }, 6301 [ITEM_QUOTA_STATE] = { 6302 .name = "quota_state", 6303 .help = "quota state", 6304 .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), 6305 NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), 6306 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) 6307 }, 6308 [ITEM_QUOTA_STATE_NAME] = { 6309 .name = "state_name", 6310 .help = "quota state name", 6311 .call = parse_quota_state_name, 6312 .comp = comp_quota_state_name 6313 }, 6314 [ITEM_IB_BTH] = { 6315 .name = "ib_bth", 6316 .help = "match ib bth fields", 6317 .priv = PRIV_ITEM(IB_BTH, 6318 sizeof(struct rte_flow_item_ib_bth)), 6319 .next = NEXT(item_ib_bth), 6320 .call = parse_vc, 6321 }, 6322 [ITEM_IB_BTH_OPCODE] = { 6323 .name = "opcode", 6324 .help = "match ib bth opcode", 6325 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6326 item_param), 6327 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6328 hdr.opcode)), 6329 }, 6330 [ITEM_IB_BTH_PKEY] = { 6331 .name = "pkey", 6332 .help = "partition key", 6333 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6334 item_param), 6335 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6336 hdr.pkey)), 6337 }, 6338 [ITEM_IB_BTH_DST_QPN] = { 6339 .name = "dst_qp", 6340 .help = "destination qp", 6341 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6342 item_param), 6343 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6344 hdr.dst_qp)), 6345 }, 6346 [ITEM_IB_BTH_PSN] = { 6347 .name = "psn", 6348 .help = "packet sequence number", 6349 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6350 item_param), 6351 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6352 hdr.psn)), 6353 }, 6354 [ITEM_PTYPE] = { 6355 .name = "ptype", 6356 .help = "match L2/L3/L4 and tunnel information", 6357 .priv = PRIV_ITEM(PTYPE, 6358 sizeof(struct rte_flow_item_ptype)), 6359 .next = NEXT(item_ptype), 6360 .call = parse_vc, 6361 }, 6362 [ITEM_PTYPE_VALUE] = { 6363 .name = "packet_type", 6364 .help = "packet type as defined in rte_mbuf_ptype", 6365 .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), 6366 item_param), 6367 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), 6368 }, 6369 [ITEM_NSH] = { 6370 .name = "nsh", 6371 .help = "match NSH header", 6372 .priv = PRIV_ITEM(NSH, 6373 sizeof(struct rte_flow_item_nsh)), 6374 .next = NEXT(item_nsh), 6375 .call = parse_vc, 6376 }, 6377 [ITEM_COMPARE] = { 6378 .name = "compare", 6379 .help = "match with the comparison result", 6380 .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)), 6381 .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)), 6382 .call = parse_vc, 6383 }, 6384 [ITEM_COMPARE_OP] = { 6385 .name = "op", 6386 .help = "operation type", 6387 .next = NEXT(item_compare_field, 6388 NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param), 6389 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)), 6390 }, 6391 [ITEM_COMPARE_OP_VALUE] = { 6392 .name = "{operation}", 6393 .help = "operation type value", 6394 .call = parse_vc_compare_op, 6395 .comp = comp_set_compare_op, 6396 }, 6397 [ITEM_COMPARE_FIELD_A_TYPE] = { 6398 .name = "a_type", 6399 .help = "compared field type", 6400 .next = NEXT(compare_field_a, 6401 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param), 6402 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)), 6403 }, 6404 [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = { 6405 .name = "{a_type}", 6406 .help = "compared field type value", 6407 .call = parse_vc_compare_field_id, 6408 .comp = comp_set_compare_field_id, 6409 }, 6410 [ITEM_COMPARE_FIELD_A_LEVEL] = { 6411 .name = "a_level", 6412 .help = "compared field level", 6413 .next = NEXT(compare_field_a, 6414 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param), 6415 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)), 6416 }, 6417 [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = { 6418 .name = "{a_level}", 6419 .help = "compared field level value", 6420 .call = parse_vc_compare_field_level, 6421 .comp = comp_none, 6422 }, 6423 [ITEM_COMPARE_FIELD_A_TAG_INDEX] = { 6424 .name = "a_tag_index", 6425 .help = "compared field tag array", 6426 .next = NEXT(compare_field_a, 6427 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6428 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6429 a.tag_index)), 6430 }, 6431 [ITEM_COMPARE_FIELD_A_TYPE_ID] = { 6432 .name = "a_type_id", 6433 .help = "compared field type ID", 6434 .next = NEXT(compare_field_a, 6435 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6436 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6437 a.type)), 6438 }, 6439 [ITEM_COMPARE_FIELD_A_CLASS_ID] = { 6440 .name = "a_class", 6441 .help = "compared field class ID", 6442 .next = NEXT(compare_field_a, 6443 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6444 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6445 a.class_id)), 6446 }, 6447 [ITEM_COMPARE_FIELD_A_OFFSET] = { 6448 .name = "a_offset", 6449 .help = "compared field bit offset", 6450 .next = NEXT(compare_field_a, 6451 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6452 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6453 a.offset)), 6454 }, 6455 [ITEM_COMPARE_FIELD_B_TYPE] = { 6456 .name = "b_type", 6457 .help = "comparator field type", 6458 .next = NEXT(compare_field_b, 6459 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param), 6460 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6461 b.field)), 6462 }, 6463 [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = { 6464 .name = "{b_type}", 6465 .help = "comparator field type value", 6466 .call = parse_vc_compare_field_id, 6467 .comp = comp_set_compare_field_id, 6468 }, 6469 [ITEM_COMPARE_FIELD_B_LEVEL] = { 6470 .name = "b_level", 6471 .help = "comparator field level", 6472 .next = NEXT(compare_field_b, 6473 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param), 6474 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6475 b.level)), 6476 }, 6477 [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = { 6478 .name = "{b_level}", 6479 .help = "comparator field level value", 6480 .call = parse_vc_compare_field_level, 6481 .comp = comp_none, 6482 }, 6483 [ITEM_COMPARE_FIELD_B_TAG_INDEX] = { 6484 .name = "b_tag_index", 6485 .help = "comparator field tag array", 6486 .next = NEXT(compare_field_b, 6487 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6488 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6489 b.tag_index)), 6490 }, 6491 [ITEM_COMPARE_FIELD_B_TYPE_ID] = { 6492 .name = "b_type_id", 6493 .help = "comparator field type ID", 6494 .next = NEXT(compare_field_b, 6495 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6496 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6497 b.type)), 6498 }, 6499 [ITEM_COMPARE_FIELD_B_CLASS_ID] = { 6500 .name = "b_class", 6501 .help = "comparator field class ID", 6502 .next = NEXT(compare_field_b, 6503 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6504 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6505 b.class_id)), 6506 }, 6507 [ITEM_COMPARE_FIELD_B_OFFSET] = { 6508 .name = "b_offset", 6509 .help = "comparator field bit offset", 6510 .next = NEXT(compare_field_b, 6511 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6512 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6513 b.offset)), 6514 }, 6515 [ITEM_COMPARE_FIELD_B_VALUE] = { 6516 .name = "b_value", 6517 .help = "comparator immediate value", 6518 .next = NEXT(compare_field_b, 6519 NEXT_ENTRY(COMMON_HEX), item_param), 6520 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6521 ARGS_ENTRY_ARB(0, 0), 6522 ARGS_ENTRY(struct rte_flow_item_compare, 6523 b.value)), 6524 }, 6525 [ITEM_COMPARE_FIELD_B_POINTER] = { 6526 .name = "b_ptr", 6527 .help = "pointer to comparator immediate value", 6528 .next = NEXT(compare_field_b, 6529 NEXT_ENTRY(COMMON_HEX), item_param), 6530 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6531 b.pvalue), 6532 ARGS_ENTRY_ARB(0, 0), 6533 ARGS_ENTRY_ARB 6534 (sizeof(struct rte_flow_item_compare), 6535 FLOW_FIELD_PATTERN_SIZE)), 6536 }, 6537 [ITEM_COMPARE_FIELD_WIDTH] = { 6538 .name = "width", 6539 .help = "number of bits to compare", 6540 .next = NEXT(item_compare_field, 6541 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6542 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6543 width)), 6544 }, 6545 6546 /* Validate/create actions. */ 6547 [ACTIONS] = { 6548 .name = "actions", 6549 .help = "submit a list of associated actions", 6550 .next = NEXT(next_action), 6551 .call = parse_vc, 6552 }, 6553 [ACTION_NEXT] = { 6554 .name = "/", 6555 .help = "specify next action", 6556 .next = NEXT(next_action), 6557 }, 6558 [ACTION_END] = { 6559 .name = "end", 6560 .help = "end list of actions", 6561 .priv = PRIV_ACTION(END, 0), 6562 .call = parse_vc, 6563 }, 6564 [ACTION_VOID] = { 6565 .name = "void", 6566 .help = "no-op action", 6567 .priv = PRIV_ACTION(VOID, 0), 6568 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6569 .call = parse_vc, 6570 }, 6571 [ACTION_PASSTHRU] = { 6572 .name = "passthru", 6573 .help = "let subsequent rule process matched packets", 6574 .priv = PRIV_ACTION(PASSTHRU, 0), 6575 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6576 .call = parse_vc, 6577 }, 6578 [ACTION_SKIP_CMAN] = { 6579 .name = "skip_cman", 6580 .help = "bypass cman on received packets", 6581 .priv = PRIV_ACTION(SKIP_CMAN, 0), 6582 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6583 .call = parse_vc, 6584 }, 6585 [ACTION_JUMP] = { 6586 .name = "jump", 6587 .help = "redirect traffic to a given group", 6588 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 6589 .next = NEXT(action_jump), 6590 .call = parse_vc, 6591 }, 6592 [ACTION_JUMP_GROUP] = { 6593 .name = "group", 6594 .help = "group to redirect traffic to", 6595 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 6596 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 6597 .call = parse_vc_conf, 6598 }, 6599 [ACTION_MARK] = { 6600 .name = "mark", 6601 .help = "attach 32 bit value to packets", 6602 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 6603 .next = NEXT(action_mark), 6604 .call = parse_vc, 6605 }, 6606 [ACTION_MARK_ID] = { 6607 .name = "id", 6608 .help = "32 bit value to return with packets", 6609 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6610 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 6611 .call = parse_vc_conf, 6612 }, 6613 [ACTION_FLAG] = { 6614 .name = "flag", 6615 .help = "flag packets", 6616 .priv = PRIV_ACTION(FLAG, 0), 6617 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6618 .call = parse_vc, 6619 }, 6620 [ACTION_QUEUE] = { 6621 .name = "queue", 6622 .help = "assign packets to a given queue index", 6623 .priv = PRIV_ACTION(QUEUE, 6624 sizeof(struct rte_flow_action_queue)), 6625 .next = NEXT(action_queue), 6626 .call = parse_vc, 6627 }, 6628 [ACTION_QUEUE_INDEX] = { 6629 .name = "index", 6630 .help = "queue index to use", 6631 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 6632 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 6633 .call = parse_vc_conf, 6634 }, 6635 [ACTION_DROP] = { 6636 .name = "drop", 6637 .help = "drop packets (note: passthru has priority)", 6638 .priv = PRIV_ACTION(DROP, 0), 6639 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6640 .call = parse_vc, 6641 }, 6642 [ACTION_COUNT] = { 6643 .name = "count", 6644 .help = "enable counters for this rule", 6645 .priv = PRIV_ACTION(COUNT, 6646 sizeof(struct rte_flow_action_count)), 6647 .next = NEXT(action_count), 6648 .call = parse_vc, 6649 }, 6650 [ACTION_COUNT_ID] = { 6651 .name = "identifier", 6652 .help = "counter identifier to use", 6653 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 6654 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 6655 .call = parse_vc_conf, 6656 }, 6657 [ACTION_RSS] = { 6658 .name = "rss", 6659 .help = "spread packets among several queues", 6660 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 6661 .next = NEXT(action_rss), 6662 .call = parse_vc_action_rss, 6663 }, 6664 [ACTION_RSS_FUNC] = { 6665 .name = "func", 6666 .help = "RSS hash function to apply", 6667 .next = NEXT(action_rss, 6668 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 6669 ACTION_RSS_FUNC_TOEPLITZ, 6670 ACTION_RSS_FUNC_SIMPLE_XOR, 6671 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 6672 }, 6673 [ACTION_RSS_FUNC_DEFAULT] = { 6674 .name = "default", 6675 .help = "default hash function", 6676 .call = parse_vc_action_rss_func, 6677 }, 6678 [ACTION_RSS_FUNC_TOEPLITZ] = { 6679 .name = "toeplitz", 6680 .help = "Toeplitz hash function", 6681 .call = parse_vc_action_rss_func, 6682 }, 6683 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 6684 .name = "simple_xor", 6685 .help = "simple XOR hash function", 6686 .call = parse_vc_action_rss_func, 6687 }, 6688 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 6689 .name = "symmetric_toeplitz", 6690 .help = "Symmetric Toeplitz hash function", 6691 .call = parse_vc_action_rss_func, 6692 }, 6693 [ACTION_RSS_LEVEL] = { 6694 .name = "level", 6695 .help = "encapsulation level for \"types\"", 6696 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6697 .args = ARGS(ARGS_ENTRY_ARB 6698 (offsetof(struct action_rss_data, conf) + 6699 offsetof(struct rte_flow_action_rss, level), 6700 sizeof(((struct rte_flow_action_rss *)0)-> 6701 level))), 6702 }, 6703 [ACTION_RSS_TYPES] = { 6704 .name = "types", 6705 .help = "specific RSS hash types", 6706 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 6707 }, 6708 [ACTION_RSS_TYPE] = { 6709 .name = "{type}", 6710 .help = "RSS hash type", 6711 .call = parse_vc_action_rss_type, 6712 .comp = comp_vc_action_rss_type, 6713 }, 6714 [ACTION_RSS_KEY] = { 6715 .name = "key", 6716 .help = "RSS hash key", 6717 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 6718 .args = ARGS(ARGS_ENTRY_ARB 6719 (offsetof(struct action_rss_data, conf) + 6720 offsetof(struct rte_flow_action_rss, key), 6721 sizeof(((struct rte_flow_action_rss *)0)->key)), 6722 ARGS_ENTRY_ARB 6723 (offsetof(struct action_rss_data, conf) + 6724 offsetof(struct rte_flow_action_rss, key_len), 6725 sizeof(((struct rte_flow_action_rss *)0)-> 6726 key_len)), 6727 ARGS_ENTRY(struct action_rss_data, key)), 6728 }, 6729 [ACTION_RSS_KEY_LEN] = { 6730 .name = "key_len", 6731 .help = "RSS hash key length in bytes", 6732 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6733 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6734 (offsetof(struct action_rss_data, conf) + 6735 offsetof(struct rte_flow_action_rss, key_len), 6736 sizeof(((struct rte_flow_action_rss *)0)-> 6737 key_len), 6738 0, 6739 RSS_HASH_KEY_LENGTH)), 6740 }, 6741 [ACTION_RSS_QUEUES] = { 6742 .name = "queues", 6743 .help = "queue indices to use", 6744 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 6745 .call = parse_vc_conf, 6746 }, 6747 [ACTION_RSS_QUEUE] = { 6748 .name = "{queue}", 6749 .help = "queue index", 6750 .call = parse_vc_action_rss_queue, 6751 .comp = comp_vc_action_rss_queue, 6752 }, 6753 [ACTION_PF] = { 6754 .name = "pf", 6755 .help = "direct traffic to physical function", 6756 .priv = PRIV_ACTION(PF, 0), 6757 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6758 .call = parse_vc, 6759 }, 6760 [ACTION_VF] = { 6761 .name = "vf", 6762 .help = "direct traffic to a virtual function ID", 6763 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 6764 .next = NEXT(action_vf), 6765 .call = parse_vc, 6766 }, 6767 [ACTION_VF_ORIGINAL] = { 6768 .name = "original", 6769 .help = "use original VF ID if possible", 6770 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 6771 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 6772 original, 1)), 6773 .call = parse_vc_conf, 6774 }, 6775 [ACTION_VF_ID] = { 6776 .name = "id", 6777 .help = "VF ID", 6778 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 6779 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 6780 .call = parse_vc_conf, 6781 }, 6782 [ACTION_PORT_ID] = { 6783 .name = "port_id", 6784 .help = "direct matching traffic to a given DPDK port ID", 6785 .priv = PRIV_ACTION(PORT_ID, 6786 sizeof(struct rte_flow_action_port_id)), 6787 .next = NEXT(action_port_id), 6788 .call = parse_vc, 6789 }, 6790 [ACTION_PORT_ID_ORIGINAL] = { 6791 .name = "original", 6792 .help = "use original DPDK port ID if possible", 6793 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 6794 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 6795 original, 1)), 6796 .call = parse_vc_conf, 6797 }, 6798 [ACTION_PORT_ID_ID] = { 6799 .name = "id", 6800 .help = "DPDK port ID", 6801 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 6802 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 6803 .call = parse_vc_conf, 6804 }, 6805 [ACTION_METER] = { 6806 .name = "meter", 6807 .help = "meter the directed packets at given id", 6808 .priv = PRIV_ACTION(METER, 6809 sizeof(struct rte_flow_action_meter)), 6810 .next = NEXT(action_meter), 6811 .call = parse_vc, 6812 }, 6813 [ACTION_METER_COLOR] = { 6814 .name = "color", 6815 .help = "meter color for the packets", 6816 .priv = PRIV_ACTION(METER_COLOR, 6817 sizeof(struct rte_flow_action_meter_color)), 6818 .next = NEXT(action_meter_color), 6819 .call = parse_vc, 6820 }, 6821 [ACTION_METER_COLOR_TYPE] = { 6822 .name = "type", 6823 .help = "specific meter color", 6824 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6825 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 6826 ACTION_METER_COLOR_YELLOW, 6827 ACTION_METER_COLOR_RED)), 6828 }, 6829 [ACTION_METER_COLOR_GREEN] = { 6830 .name = "green", 6831 .help = "meter color green", 6832 .call = parse_vc_action_meter_color_type, 6833 }, 6834 [ACTION_METER_COLOR_YELLOW] = { 6835 .name = "yellow", 6836 .help = "meter color yellow", 6837 .call = parse_vc_action_meter_color_type, 6838 }, 6839 [ACTION_METER_COLOR_RED] = { 6840 .name = "red", 6841 .help = "meter color red", 6842 .call = parse_vc_action_meter_color_type, 6843 }, 6844 [ACTION_METER_ID] = { 6845 .name = "mtr_id", 6846 .help = "meter id to use", 6847 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 6848 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 6849 .call = parse_vc_conf, 6850 }, 6851 [ACTION_METER_MARK] = { 6852 .name = "meter_mark", 6853 .help = "meter the directed packets using profile and policy", 6854 .priv = PRIV_ACTION(METER_MARK, 6855 sizeof(struct rte_flow_action_meter_mark)), 6856 .next = NEXT(action_meter_mark), 6857 .call = parse_vc, 6858 }, 6859 [ACTION_METER_PROFILE] = { 6860 .name = "mtr_profile", 6861 .help = "meter profile id to use", 6862 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 6863 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6864 }, 6865 [ACTION_METER_PROFILE_ID2PTR] = { 6866 .name = "{mtr_profile_id}", 6867 .type = "PROFILE_ID", 6868 .help = "meter profile id", 6869 .next = NEXT(action_meter_mark), 6870 .call = parse_meter_profile_id2ptr, 6871 .comp = comp_none, 6872 }, 6873 [ACTION_METER_POLICY] = { 6874 .name = "mtr_policy", 6875 .help = "meter policy id to use", 6876 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 6877 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6878 }, 6879 [ACTION_METER_POLICY_ID2PTR] = { 6880 .name = "{mtr_policy_id}", 6881 .type = "POLICY_ID", 6882 .help = "meter policy id", 6883 .next = NEXT(action_meter_mark), 6884 .call = parse_meter_policy_id2ptr, 6885 .comp = comp_none, 6886 }, 6887 [ACTION_METER_COLOR_MODE] = { 6888 .name = "mtr_color_mode", 6889 .help = "meter color awareness mode", 6890 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6891 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 6892 .call = parse_vc_conf, 6893 }, 6894 [ACTION_METER_STATE] = { 6895 .name = "mtr_state", 6896 .help = "meter state", 6897 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6898 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 6899 .call = parse_vc_conf, 6900 }, 6901 [ACTION_OF_DEC_NW_TTL] = { 6902 .name = "of_dec_nw_ttl", 6903 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 6904 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 6905 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6906 .call = parse_vc, 6907 }, 6908 [ACTION_OF_POP_VLAN] = { 6909 .name = "of_pop_vlan", 6910 .help = "OpenFlow's OFPAT_POP_VLAN", 6911 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 6912 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6913 .call = parse_vc, 6914 }, 6915 [ACTION_OF_PUSH_VLAN] = { 6916 .name = "of_push_vlan", 6917 .help = "OpenFlow's OFPAT_PUSH_VLAN", 6918 .priv = PRIV_ACTION 6919 (OF_PUSH_VLAN, 6920 sizeof(struct rte_flow_action_of_push_vlan)), 6921 .next = NEXT(action_of_push_vlan), 6922 .call = parse_vc, 6923 }, 6924 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 6925 .name = "ethertype", 6926 .help = "EtherType", 6927 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 6928 .args = ARGS(ARGS_ENTRY_HTON 6929 (struct rte_flow_action_of_push_vlan, 6930 ethertype)), 6931 .call = parse_vc_conf, 6932 }, 6933 [ACTION_OF_SET_VLAN_VID] = { 6934 .name = "of_set_vlan_vid", 6935 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 6936 .priv = PRIV_ACTION 6937 (OF_SET_VLAN_VID, 6938 sizeof(struct rte_flow_action_of_set_vlan_vid)), 6939 .next = NEXT(action_of_set_vlan_vid), 6940 .call = parse_vc, 6941 }, 6942 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 6943 .name = "vlan_vid", 6944 .help = "VLAN id", 6945 .next = NEXT(action_of_set_vlan_vid, 6946 NEXT_ENTRY(COMMON_UNSIGNED)), 6947 .args = ARGS(ARGS_ENTRY_HTON 6948 (struct rte_flow_action_of_set_vlan_vid, 6949 vlan_vid)), 6950 .call = parse_vc_conf, 6951 }, 6952 [ACTION_OF_SET_VLAN_PCP] = { 6953 .name = "of_set_vlan_pcp", 6954 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 6955 .priv = PRIV_ACTION 6956 (OF_SET_VLAN_PCP, 6957 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 6958 .next = NEXT(action_of_set_vlan_pcp), 6959 .call = parse_vc, 6960 }, 6961 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 6962 .name = "vlan_pcp", 6963 .help = "VLAN priority", 6964 .next = NEXT(action_of_set_vlan_pcp, 6965 NEXT_ENTRY(COMMON_UNSIGNED)), 6966 .args = ARGS(ARGS_ENTRY_HTON 6967 (struct rte_flow_action_of_set_vlan_pcp, 6968 vlan_pcp)), 6969 .call = parse_vc_conf, 6970 }, 6971 [ACTION_OF_POP_MPLS] = { 6972 .name = "of_pop_mpls", 6973 .help = "OpenFlow's OFPAT_POP_MPLS", 6974 .priv = PRIV_ACTION(OF_POP_MPLS, 6975 sizeof(struct rte_flow_action_of_pop_mpls)), 6976 .next = NEXT(action_of_pop_mpls), 6977 .call = parse_vc, 6978 }, 6979 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 6980 .name = "ethertype", 6981 .help = "EtherType", 6982 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6983 .args = ARGS(ARGS_ENTRY_HTON 6984 (struct rte_flow_action_of_pop_mpls, 6985 ethertype)), 6986 .call = parse_vc_conf, 6987 }, 6988 [ACTION_OF_PUSH_MPLS] = { 6989 .name = "of_push_mpls", 6990 .help = "OpenFlow's OFPAT_PUSH_MPLS", 6991 .priv = PRIV_ACTION 6992 (OF_PUSH_MPLS, 6993 sizeof(struct rte_flow_action_of_push_mpls)), 6994 .next = NEXT(action_of_push_mpls), 6995 .call = parse_vc, 6996 }, 6997 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 6998 .name = "ethertype", 6999 .help = "EtherType", 7000 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 7001 .args = ARGS(ARGS_ENTRY_HTON 7002 (struct rte_flow_action_of_push_mpls, 7003 ethertype)), 7004 .call = parse_vc_conf, 7005 }, 7006 [ACTION_VXLAN_ENCAP] = { 7007 .name = "vxlan_encap", 7008 .help = "VXLAN encapsulation, uses configuration set by \"set" 7009 " vxlan\"", 7010 .priv = PRIV_ACTION(VXLAN_ENCAP, 7011 sizeof(struct action_vxlan_encap_data)), 7012 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7013 .call = parse_vc_action_vxlan_encap, 7014 }, 7015 [ACTION_VXLAN_DECAP] = { 7016 .name = "vxlan_decap", 7017 .help = "Performs a decapsulation action by stripping all" 7018 " headers of the VXLAN tunnel network overlay from the" 7019 " matched flow.", 7020 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 7021 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7022 .call = parse_vc, 7023 }, 7024 [ACTION_NVGRE_ENCAP] = { 7025 .name = "nvgre_encap", 7026 .help = "NVGRE encapsulation, uses configuration set by \"set" 7027 " nvgre\"", 7028 .priv = PRIV_ACTION(NVGRE_ENCAP, 7029 sizeof(struct action_nvgre_encap_data)), 7030 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7031 .call = parse_vc_action_nvgre_encap, 7032 }, 7033 [ACTION_NVGRE_DECAP] = { 7034 .name = "nvgre_decap", 7035 .help = "Performs a decapsulation action by stripping all" 7036 " headers of the NVGRE tunnel network overlay from the" 7037 " matched flow.", 7038 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 7039 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7040 .call = parse_vc, 7041 }, 7042 [ACTION_L2_ENCAP] = { 7043 .name = "l2_encap", 7044 .help = "l2 encap, uses configuration set by" 7045 " \"set l2_encap\"", 7046 .priv = PRIV_ACTION(RAW_ENCAP, 7047 sizeof(struct action_raw_encap_data)), 7048 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7049 .call = parse_vc_action_l2_encap, 7050 }, 7051 [ACTION_L2_DECAP] = { 7052 .name = "l2_decap", 7053 .help = "l2 decap, uses configuration set by" 7054 " \"set l2_decap\"", 7055 .priv = PRIV_ACTION(RAW_DECAP, 7056 sizeof(struct action_raw_decap_data)), 7057 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7058 .call = parse_vc_action_l2_decap, 7059 }, 7060 [ACTION_MPLSOGRE_ENCAP] = { 7061 .name = "mplsogre_encap", 7062 .help = "mplsogre encapsulation, uses configuration set by" 7063 " \"set mplsogre_encap\"", 7064 .priv = PRIV_ACTION(RAW_ENCAP, 7065 sizeof(struct action_raw_encap_data)), 7066 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7067 .call = parse_vc_action_mplsogre_encap, 7068 }, 7069 [ACTION_MPLSOGRE_DECAP] = { 7070 .name = "mplsogre_decap", 7071 .help = "mplsogre decapsulation, uses configuration set by" 7072 " \"set mplsogre_decap\"", 7073 .priv = PRIV_ACTION(RAW_DECAP, 7074 sizeof(struct action_raw_decap_data)), 7075 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7076 .call = parse_vc_action_mplsogre_decap, 7077 }, 7078 [ACTION_MPLSOUDP_ENCAP] = { 7079 .name = "mplsoudp_encap", 7080 .help = "mplsoudp encapsulation, uses configuration set by" 7081 " \"set mplsoudp_encap\"", 7082 .priv = PRIV_ACTION(RAW_ENCAP, 7083 sizeof(struct action_raw_encap_data)), 7084 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7085 .call = parse_vc_action_mplsoudp_encap, 7086 }, 7087 [ACTION_MPLSOUDP_DECAP] = { 7088 .name = "mplsoudp_decap", 7089 .help = "mplsoudp decapsulation, uses configuration set by" 7090 " \"set mplsoudp_decap\"", 7091 .priv = PRIV_ACTION(RAW_DECAP, 7092 sizeof(struct action_raw_decap_data)), 7093 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7094 .call = parse_vc_action_mplsoudp_decap, 7095 }, 7096 [ACTION_SET_IPV4_SRC] = { 7097 .name = "set_ipv4_src", 7098 .help = "Set a new IPv4 source address in the outermost" 7099 " IPv4 header", 7100 .priv = PRIV_ACTION(SET_IPV4_SRC, 7101 sizeof(struct rte_flow_action_set_ipv4)), 7102 .next = NEXT(action_set_ipv4_src), 7103 .call = parse_vc, 7104 }, 7105 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 7106 .name = "ipv4_addr", 7107 .help = "new IPv4 source address to set", 7108 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 7109 .args = ARGS(ARGS_ENTRY_HTON 7110 (struct rte_flow_action_set_ipv4, ipv4_addr)), 7111 .call = parse_vc_conf, 7112 }, 7113 [ACTION_SET_IPV4_DST] = { 7114 .name = "set_ipv4_dst", 7115 .help = "Set a new IPv4 destination address in the outermost" 7116 " IPv4 header", 7117 .priv = PRIV_ACTION(SET_IPV4_DST, 7118 sizeof(struct rte_flow_action_set_ipv4)), 7119 .next = NEXT(action_set_ipv4_dst), 7120 .call = parse_vc, 7121 }, 7122 [ACTION_SET_IPV4_DST_IPV4_DST] = { 7123 .name = "ipv4_addr", 7124 .help = "new IPv4 destination address to set", 7125 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 7126 .args = ARGS(ARGS_ENTRY_HTON 7127 (struct rte_flow_action_set_ipv4, ipv4_addr)), 7128 .call = parse_vc_conf, 7129 }, 7130 [ACTION_SET_IPV6_SRC] = { 7131 .name = "set_ipv6_src", 7132 .help = "Set a new IPv6 source address in the outermost" 7133 " IPv6 header", 7134 .priv = PRIV_ACTION(SET_IPV6_SRC, 7135 sizeof(struct rte_flow_action_set_ipv6)), 7136 .next = NEXT(action_set_ipv6_src), 7137 .call = parse_vc, 7138 }, 7139 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 7140 .name = "ipv6_addr", 7141 .help = "new IPv6 source address to set", 7142 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7143 .args = ARGS(ARGS_ENTRY_HTON 7144 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7145 .call = parse_vc_conf, 7146 }, 7147 [ACTION_SET_IPV6_DST] = { 7148 .name = "set_ipv6_dst", 7149 .help = "Set a new IPv6 destination address in the outermost" 7150 " IPv6 header", 7151 .priv = PRIV_ACTION(SET_IPV6_DST, 7152 sizeof(struct rte_flow_action_set_ipv6)), 7153 .next = NEXT(action_set_ipv6_dst), 7154 .call = parse_vc, 7155 }, 7156 [ACTION_SET_IPV6_DST_IPV6_DST] = { 7157 .name = "ipv6_addr", 7158 .help = "new IPv6 destination address to set", 7159 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7160 .args = ARGS(ARGS_ENTRY_HTON 7161 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7162 .call = parse_vc_conf, 7163 }, 7164 [ACTION_SET_TP_SRC] = { 7165 .name = "set_tp_src", 7166 .help = "set a new source port number in the outermost" 7167 " TCP/UDP header", 7168 .priv = PRIV_ACTION(SET_TP_SRC, 7169 sizeof(struct rte_flow_action_set_tp)), 7170 .next = NEXT(action_set_tp_src), 7171 .call = parse_vc, 7172 }, 7173 [ACTION_SET_TP_SRC_TP_SRC] = { 7174 .name = "port", 7175 .help = "new source port number to set", 7176 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 7177 .args = ARGS(ARGS_ENTRY_HTON 7178 (struct rte_flow_action_set_tp, port)), 7179 .call = parse_vc_conf, 7180 }, 7181 [ACTION_SET_TP_DST] = { 7182 .name = "set_tp_dst", 7183 .help = "set a new destination port number in the outermost" 7184 " TCP/UDP header", 7185 .priv = PRIV_ACTION(SET_TP_DST, 7186 sizeof(struct rte_flow_action_set_tp)), 7187 .next = NEXT(action_set_tp_dst), 7188 .call = parse_vc, 7189 }, 7190 [ACTION_SET_TP_DST_TP_DST] = { 7191 .name = "port", 7192 .help = "new destination port number to set", 7193 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 7194 .args = ARGS(ARGS_ENTRY_HTON 7195 (struct rte_flow_action_set_tp, port)), 7196 .call = parse_vc_conf, 7197 }, 7198 [ACTION_MAC_SWAP] = { 7199 .name = "mac_swap", 7200 .help = "Swap the source and destination MAC addresses" 7201 " in the outermost Ethernet header", 7202 .priv = PRIV_ACTION(MAC_SWAP, 0), 7203 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7204 .call = parse_vc, 7205 }, 7206 [ACTION_DEC_TTL] = { 7207 .name = "dec_ttl", 7208 .help = "decrease network TTL if available", 7209 .priv = PRIV_ACTION(DEC_TTL, 0), 7210 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7211 .call = parse_vc, 7212 }, 7213 [ACTION_SET_TTL] = { 7214 .name = "set_ttl", 7215 .help = "set ttl value", 7216 .priv = PRIV_ACTION(SET_TTL, 7217 sizeof(struct rte_flow_action_set_ttl)), 7218 .next = NEXT(action_set_ttl), 7219 .call = parse_vc, 7220 }, 7221 [ACTION_SET_TTL_TTL] = { 7222 .name = "ttl_value", 7223 .help = "new ttl value to set", 7224 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 7225 .args = ARGS(ARGS_ENTRY_HTON 7226 (struct rte_flow_action_set_ttl, ttl_value)), 7227 .call = parse_vc_conf, 7228 }, 7229 [ACTION_SET_MAC_SRC] = { 7230 .name = "set_mac_src", 7231 .help = "set source mac address", 7232 .priv = PRIV_ACTION(SET_MAC_SRC, 7233 sizeof(struct rte_flow_action_set_mac)), 7234 .next = NEXT(action_set_mac_src), 7235 .call = parse_vc, 7236 }, 7237 [ACTION_SET_MAC_SRC_MAC_SRC] = { 7238 .name = "mac_addr", 7239 .help = "new source mac address", 7240 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 7241 .args = ARGS(ARGS_ENTRY_HTON 7242 (struct rte_flow_action_set_mac, mac_addr)), 7243 .call = parse_vc_conf, 7244 }, 7245 [ACTION_SET_MAC_DST] = { 7246 .name = "set_mac_dst", 7247 .help = "set destination mac address", 7248 .priv = PRIV_ACTION(SET_MAC_DST, 7249 sizeof(struct rte_flow_action_set_mac)), 7250 .next = NEXT(action_set_mac_dst), 7251 .call = parse_vc, 7252 }, 7253 [ACTION_SET_MAC_DST_MAC_DST] = { 7254 .name = "mac_addr", 7255 .help = "new destination mac address to set", 7256 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 7257 .args = ARGS(ARGS_ENTRY_HTON 7258 (struct rte_flow_action_set_mac, mac_addr)), 7259 .call = parse_vc_conf, 7260 }, 7261 [ACTION_INC_TCP_SEQ] = { 7262 .name = "inc_tcp_seq", 7263 .help = "increase TCP sequence number", 7264 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 7265 .next = NEXT(action_inc_tcp_seq), 7266 .call = parse_vc, 7267 }, 7268 [ACTION_INC_TCP_SEQ_VALUE] = { 7269 .name = "value", 7270 .help = "the value to increase TCP sequence number by", 7271 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7272 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7273 .call = parse_vc_conf, 7274 }, 7275 [ACTION_DEC_TCP_SEQ] = { 7276 .name = "dec_tcp_seq", 7277 .help = "decrease TCP sequence number", 7278 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 7279 .next = NEXT(action_dec_tcp_seq), 7280 .call = parse_vc, 7281 }, 7282 [ACTION_DEC_TCP_SEQ_VALUE] = { 7283 .name = "value", 7284 .help = "the value to decrease TCP sequence number by", 7285 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7286 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7287 .call = parse_vc_conf, 7288 }, 7289 [ACTION_INC_TCP_ACK] = { 7290 .name = "inc_tcp_ack", 7291 .help = "increase TCP acknowledgment number", 7292 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 7293 .next = NEXT(action_inc_tcp_ack), 7294 .call = parse_vc, 7295 }, 7296 [ACTION_INC_TCP_ACK_VALUE] = { 7297 .name = "value", 7298 .help = "the value to increase TCP acknowledgment number by", 7299 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7300 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7301 .call = parse_vc_conf, 7302 }, 7303 [ACTION_DEC_TCP_ACK] = { 7304 .name = "dec_tcp_ack", 7305 .help = "decrease TCP acknowledgment number", 7306 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 7307 .next = NEXT(action_dec_tcp_ack), 7308 .call = parse_vc, 7309 }, 7310 [ACTION_DEC_TCP_ACK_VALUE] = { 7311 .name = "value", 7312 .help = "the value to decrease TCP acknowledgment number by", 7313 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7314 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7315 .call = parse_vc_conf, 7316 }, 7317 [ACTION_RAW_ENCAP] = { 7318 .name = "raw_encap", 7319 .help = "encapsulation data, defined by set raw_encap", 7320 .priv = PRIV_ACTION(RAW_ENCAP, 7321 sizeof(struct action_raw_encap_data)), 7322 .next = NEXT(action_raw_encap), 7323 .call = parse_vc_action_raw_encap, 7324 }, 7325 [ACTION_RAW_ENCAP_SIZE] = { 7326 .name = "size", 7327 .help = "raw encap size", 7328 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7329 NEXT_ENTRY(COMMON_UNSIGNED)), 7330 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_raw_encap, size)), 7331 .call = parse_vc_conf, 7332 }, 7333 [ACTION_RAW_ENCAP_INDEX] = { 7334 .name = "index", 7335 .help = "the index of raw_encap_confs", 7336 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 7337 }, 7338 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 7339 .name = "{index}", 7340 .type = "UNSIGNED", 7341 .help = "unsigned integer value", 7342 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7343 .call = parse_vc_action_raw_encap_index, 7344 .comp = comp_set_raw_index, 7345 }, 7346 [ACTION_RAW_DECAP] = { 7347 .name = "raw_decap", 7348 .help = "decapsulation data, defined by set raw_encap", 7349 .priv = PRIV_ACTION(RAW_DECAP, 7350 sizeof(struct action_raw_decap_data)), 7351 .next = NEXT(action_raw_decap), 7352 .call = parse_vc_action_raw_decap, 7353 }, 7354 [ACTION_RAW_DECAP_INDEX] = { 7355 .name = "index", 7356 .help = "the index of raw_encap_confs", 7357 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 7358 }, 7359 [ACTION_RAW_DECAP_INDEX_VALUE] = { 7360 .name = "{index}", 7361 .type = "UNSIGNED", 7362 .help = "unsigned integer value", 7363 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7364 .call = parse_vc_action_raw_decap_index, 7365 .comp = comp_set_raw_index, 7366 }, 7367 [ACTION_MODIFY_FIELD] = { 7368 .name = "modify_field", 7369 .help = "modify destination field with data from source field", 7370 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 7371 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 7372 .call = parse_vc, 7373 }, 7374 [ACTION_MODIFY_FIELD_OP] = { 7375 .name = "op", 7376 .help = "operation type", 7377 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 7378 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 7379 .call = parse_vc_conf, 7380 }, 7381 [ACTION_MODIFY_FIELD_OP_VALUE] = { 7382 .name = "{operation}", 7383 .help = "operation type value", 7384 .call = parse_vc_modify_field_op, 7385 .comp = comp_set_modify_field_op, 7386 }, 7387 [ACTION_MODIFY_FIELD_DST_TYPE] = { 7388 .name = "dst_type", 7389 .help = "destination field type", 7390 .next = NEXT(action_modify_field_dst, 7391 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 7392 .call = parse_vc_conf, 7393 }, 7394 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 7395 .name = "{dst_type}", 7396 .help = "destination field type value", 7397 .call = parse_vc_modify_field_id, 7398 .comp = comp_set_modify_field_id, 7399 }, 7400 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 7401 .name = "dst_level", 7402 .help = "destination field level", 7403 .next = NEXT(action_modify_field_dst, 7404 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), 7405 .call = parse_vc_conf, 7406 }, 7407 [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { 7408 .name = "{dst_level}", 7409 .help = "destination field level value", 7410 .call = parse_vc_modify_field_level, 7411 .comp = comp_none, 7412 }, 7413 [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { 7414 .name = "dst_tag_index", 7415 .help = "destination field tag array", 7416 .next = NEXT(action_modify_field_dst, 7417 NEXT_ENTRY(COMMON_UNSIGNED)), 7418 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7419 dst.tag_index)), 7420 .call = parse_vc_conf, 7421 }, 7422 [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { 7423 .name = "dst_type_id", 7424 .help = "destination field type ID", 7425 .next = NEXT(action_modify_field_dst, 7426 NEXT_ENTRY(COMMON_UNSIGNED)), 7427 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7428 dst.type)), 7429 .call = parse_vc_conf, 7430 }, 7431 [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { 7432 .name = "dst_class", 7433 .help = "destination field class ID", 7434 .next = NEXT(action_modify_field_dst, 7435 NEXT_ENTRY(COMMON_UNSIGNED)), 7436 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7437 dst.class_id)), 7438 .call = parse_vc_conf, 7439 }, 7440 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 7441 .name = "dst_offset", 7442 .help = "destination field bit offset", 7443 .next = NEXT(action_modify_field_dst, 7444 NEXT_ENTRY(COMMON_UNSIGNED)), 7445 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7446 dst.offset)), 7447 .call = parse_vc_conf, 7448 }, 7449 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 7450 .name = "src_type", 7451 .help = "source field type", 7452 .next = NEXT(action_modify_field_src, 7453 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 7454 .call = parse_vc_conf, 7455 }, 7456 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 7457 .name = "{src_type}", 7458 .help = "source field type value", 7459 .call = parse_vc_modify_field_id, 7460 .comp = comp_set_modify_field_id, 7461 }, 7462 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 7463 .name = "src_level", 7464 .help = "source field level", 7465 .next = NEXT(action_modify_field_src, 7466 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), 7467 .call = parse_vc_conf, 7468 }, 7469 [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { 7470 .name = "{src_level}", 7471 .help = "source field level value", 7472 .call = parse_vc_modify_field_level, 7473 .comp = comp_none, 7474 }, 7475 [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { 7476 .name = "src_tag_index", 7477 .help = "source field tag array", 7478 .next = NEXT(action_modify_field_src, 7479 NEXT_ENTRY(COMMON_UNSIGNED)), 7480 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7481 src.tag_index)), 7482 .call = parse_vc_conf, 7483 }, 7484 [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { 7485 .name = "src_type_id", 7486 .help = "source field type ID", 7487 .next = NEXT(action_modify_field_src, 7488 NEXT_ENTRY(COMMON_UNSIGNED)), 7489 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7490 src.type)), 7491 .call = parse_vc_conf, 7492 }, 7493 [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { 7494 .name = "src_class", 7495 .help = "source field class ID", 7496 .next = NEXT(action_modify_field_src, 7497 NEXT_ENTRY(COMMON_UNSIGNED)), 7498 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7499 src.class_id)), 7500 .call = parse_vc_conf, 7501 }, 7502 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 7503 .name = "src_offset", 7504 .help = "source field bit offset", 7505 .next = NEXT(action_modify_field_src, 7506 NEXT_ENTRY(COMMON_UNSIGNED)), 7507 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7508 src.offset)), 7509 .call = parse_vc_conf, 7510 }, 7511 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 7512 .name = "src_value", 7513 .help = "source immediate value", 7514 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7515 NEXT_ENTRY(COMMON_HEX)), 7516 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 7517 ARGS_ENTRY_ARB(0, 0), 7518 ARGS_ENTRY(struct rte_flow_action_modify_field, 7519 src.value)), 7520 .call = parse_vc_conf, 7521 }, 7522 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 7523 .name = "src_ptr", 7524 .help = "pointer to source immediate value", 7525 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7526 NEXT_ENTRY(COMMON_HEX)), 7527 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7528 src.pvalue), 7529 ARGS_ENTRY_ARB(0, 0), 7530 ARGS_ENTRY_ARB 7531 (sizeof(struct rte_flow_action_modify_field), 7532 FLOW_FIELD_PATTERN_SIZE)), 7533 .call = parse_vc_conf, 7534 }, 7535 [ACTION_MODIFY_FIELD_WIDTH] = { 7536 .name = "width", 7537 .help = "number of bits to copy", 7538 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7539 NEXT_ENTRY(COMMON_UNSIGNED)), 7540 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7541 width)), 7542 .call = parse_vc_conf, 7543 }, 7544 [ACTION_SEND_TO_KERNEL] = { 7545 .name = "send_to_kernel", 7546 .help = "send packets to kernel", 7547 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 7548 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7549 .call = parse_vc, 7550 }, 7551 [ACTION_IPV6_EXT_REMOVE] = { 7552 .name = "ipv6_ext_remove", 7553 .help = "IPv6 extension type, defined by set ipv6_ext_remove", 7554 .priv = PRIV_ACTION(IPV6_EXT_REMOVE, 7555 sizeof(struct action_ipv6_ext_remove_data)), 7556 .next = NEXT(action_ipv6_ext_remove), 7557 .call = parse_vc_action_ipv6_ext_remove, 7558 }, 7559 [ACTION_IPV6_EXT_REMOVE_INDEX] = { 7560 .name = "index", 7561 .help = "the index of ipv6_ext_remove", 7562 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), 7563 }, 7564 [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { 7565 .name = "{index}", 7566 .type = "UNSIGNED", 7567 .help = "unsigned integer value", 7568 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7569 .call = parse_vc_action_ipv6_ext_remove_index, 7570 .comp = comp_set_ipv6_ext_index, 7571 }, 7572 [ACTION_IPV6_EXT_PUSH] = { 7573 .name = "ipv6_ext_push", 7574 .help = "IPv6 extension data, defined by set ipv6_ext_push", 7575 .priv = PRIV_ACTION(IPV6_EXT_PUSH, 7576 sizeof(struct action_ipv6_ext_push_data)), 7577 .next = NEXT(action_ipv6_ext_push), 7578 .call = parse_vc_action_ipv6_ext_push, 7579 }, 7580 [ACTION_IPV6_EXT_PUSH_INDEX] = { 7581 .name = "index", 7582 .help = "the index of ipv6_ext_push", 7583 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), 7584 }, 7585 [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { 7586 .name = "{index}", 7587 .type = "UNSIGNED", 7588 .help = "unsigned integer value", 7589 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7590 .call = parse_vc_action_ipv6_ext_push_index, 7591 .comp = comp_set_ipv6_ext_index, 7592 }, 7593 [ACTION_NAT64] = { 7594 .name = "nat64", 7595 .help = "NAT64 IP headers translation", 7596 .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), 7597 .next = NEXT(action_nat64), 7598 .call = parse_vc, 7599 }, 7600 [ACTION_NAT64_MODE] = { 7601 .name = "type", 7602 .help = "NAT64 translation type", 7603 .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), 7604 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), 7605 .call = parse_vc_conf, 7606 }, 7607 [ACTION_JUMP_TO_TABLE_INDEX] = { 7608 .name = "jump_to_table_index", 7609 .help = "Jump to table index", 7610 .priv = PRIV_ACTION(JUMP_TO_TABLE_INDEX, 7611 sizeof(struct rte_flow_action_jump_to_table_index)), 7612 .next = NEXT(action_jump_to_table_index), 7613 .call = parse_vc, 7614 }, 7615 [ACTION_JUMP_TO_TABLE_INDEX_TABLE] = { 7616 .name = "table", 7617 .help = "table to redirect traffic to", 7618 .next = NEXT(action_jump_to_table_index, NEXT_ENTRY(COMMON_UNSIGNED)), 7619 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump_to_table_index, table)), 7620 .call = parse_vc_conf, 7621 }, 7622 [ACTION_JUMP_TO_TABLE_INDEX_INDEX] = { 7623 .name = "index", 7624 .help = "rule index to redirect traffic to", 7625 .next = NEXT(action_jump_to_table_index, NEXT_ENTRY(COMMON_UNSIGNED)), 7626 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump_to_table_index, index)), 7627 .call = parse_vc_conf, 7628 }, 7629 7630 /* Top level command. */ 7631 [SET] = { 7632 .name = "set", 7633 .help = "set raw encap/decap/sample data", 7634 .type = "set raw_encap|raw_decap <index> <pattern>" 7635 " or set sample_actions <index> <action>", 7636 .next = NEXT(NEXT_ENTRY 7637 (SET_RAW_ENCAP, 7638 SET_RAW_DECAP, 7639 SET_SAMPLE_ACTIONS, 7640 SET_IPV6_EXT_REMOVE, 7641 SET_IPV6_EXT_PUSH)), 7642 .call = parse_set_init, 7643 }, 7644 /* Sub-level commands. */ 7645 [SET_RAW_ENCAP] = { 7646 .name = "raw_encap", 7647 .help = "set raw encap data", 7648 .next = NEXT(next_set_raw), 7649 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7650 (offsetof(struct buffer, port), 7651 sizeof(((struct buffer *)0)->port), 7652 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7653 .call = parse_set_raw_encap_decap, 7654 }, 7655 [SET_RAW_DECAP] = { 7656 .name = "raw_decap", 7657 .help = "set raw decap data", 7658 .next = NEXT(next_set_raw), 7659 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7660 (offsetof(struct buffer, port), 7661 sizeof(((struct buffer *)0)->port), 7662 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7663 .call = parse_set_raw_encap_decap, 7664 }, 7665 [SET_RAW_INDEX] = { 7666 .name = "{index}", 7667 .type = "COMMON_UNSIGNED", 7668 .help = "index of raw_encap/raw_decap data", 7669 .next = NEXT(next_item), 7670 .call = parse_port, 7671 }, 7672 [SET_SAMPLE_INDEX] = { 7673 .name = "{index}", 7674 .type = "UNSIGNED", 7675 .help = "index of sample actions", 7676 .next = NEXT(next_action_sample), 7677 .call = parse_port, 7678 }, 7679 [SET_SAMPLE_ACTIONS] = { 7680 .name = "sample_actions", 7681 .help = "set sample actions list", 7682 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 7683 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7684 (offsetof(struct buffer, port), 7685 sizeof(((struct buffer *)0)->port), 7686 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 7687 .call = parse_set_sample_action, 7688 }, 7689 [SET_IPV6_EXT_PUSH] = { 7690 .name = "ipv6_ext_push", 7691 .help = "set IPv6 extension header", 7692 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7693 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7694 (offsetof(struct buffer, port), 7695 sizeof(((struct buffer *)0)->port), 7696 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7697 .call = parse_set_ipv6_ext_action, 7698 }, 7699 [SET_IPV6_EXT_REMOVE] = { 7700 .name = "ipv6_ext_remove", 7701 .help = "set IPv6 extension header", 7702 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7703 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7704 (offsetof(struct buffer, port), 7705 sizeof(((struct buffer *)0)->port), 7706 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7707 .call = parse_set_ipv6_ext_action, 7708 }, 7709 [SET_IPV6_EXT_INDEX] = { 7710 .name = "{index}", 7711 .type = "UNSIGNED", 7712 .help = "index of ipv6 extension push/remove actions", 7713 .next = NEXT(item_ipv6_push_ext), 7714 .call = parse_port, 7715 }, 7716 [ITEM_IPV6_PUSH_REMOVE_EXT] = { 7717 .name = "ipv6_ext", 7718 .help = "set IPv6 extension header", 7719 .priv = PRIV_ITEM(IPV6_EXT, 7720 sizeof(struct rte_flow_item_ipv6_ext)), 7721 .next = NEXT(item_ipv6_push_ext_type), 7722 .call = parse_vc, 7723 }, 7724 [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { 7725 .name = "type", 7726 .help = "set IPv6 extension type", 7727 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 7728 next_hdr)), 7729 .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), 7730 item_param), 7731 }, 7732 [ACTION_SET_TAG] = { 7733 .name = "set_tag", 7734 .help = "set tag", 7735 .priv = PRIV_ACTION(SET_TAG, 7736 sizeof(struct rte_flow_action_set_tag)), 7737 .next = NEXT(action_set_tag), 7738 .call = parse_vc, 7739 }, 7740 [ACTION_SET_TAG_INDEX] = { 7741 .name = "index", 7742 .help = "index of tag array", 7743 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7744 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 7745 .call = parse_vc_conf, 7746 }, 7747 [ACTION_SET_TAG_DATA] = { 7748 .name = "data", 7749 .help = "tag value", 7750 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7751 .args = ARGS(ARGS_ENTRY 7752 (struct rte_flow_action_set_tag, data)), 7753 .call = parse_vc_conf, 7754 }, 7755 [ACTION_SET_TAG_MASK] = { 7756 .name = "mask", 7757 .help = "mask for tag value", 7758 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7759 .args = ARGS(ARGS_ENTRY 7760 (struct rte_flow_action_set_tag, mask)), 7761 .call = parse_vc_conf, 7762 }, 7763 [ACTION_SET_META] = { 7764 .name = "set_meta", 7765 .help = "set metadata", 7766 .priv = PRIV_ACTION(SET_META, 7767 sizeof(struct rte_flow_action_set_meta)), 7768 .next = NEXT(action_set_meta), 7769 .call = parse_vc_action_set_meta, 7770 }, 7771 [ACTION_SET_META_DATA] = { 7772 .name = "data", 7773 .help = "metadata value", 7774 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7775 .args = ARGS(ARGS_ENTRY 7776 (struct rte_flow_action_set_meta, data)), 7777 .call = parse_vc_conf, 7778 }, 7779 [ACTION_SET_META_MASK] = { 7780 .name = "mask", 7781 .help = "mask for metadata value", 7782 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7783 .args = ARGS(ARGS_ENTRY 7784 (struct rte_flow_action_set_meta, mask)), 7785 .call = parse_vc_conf, 7786 }, 7787 [ACTION_SET_IPV4_DSCP] = { 7788 .name = "set_ipv4_dscp", 7789 .help = "set DSCP value", 7790 .priv = PRIV_ACTION(SET_IPV4_DSCP, 7791 sizeof(struct rte_flow_action_set_dscp)), 7792 .next = NEXT(action_set_ipv4_dscp), 7793 .call = parse_vc, 7794 }, 7795 [ACTION_SET_IPV4_DSCP_VALUE] = { 7796 .name = "dscp_value", 7797 .help = "new IPv4 DSCP value to set", 7798 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7799 .args = ARGS(ARGS_ENTRY 7800 (struct rte_flow_action_set_dscp, dscp)), 7801 .call = parse_vc_conf, 7802 }, 7803 [ACTION_SET_IPV6_DSCP] = { 7804 .name = "set_ipv6_dscp", 7805 .help = "set DSCP value", 7806 .priv = PRIV_ACTION(SET_IPV6_DSCP, 7807 sizeof(struct rte_flow_action_set_dscp)), 7808 .next = NEXT(action_set_ipv6_dscp), 7809 .call = parse_vc, 7810 }, 7811 [ACTION_SET_IPV6_DSCP_VALUE] = { 7812 .name = "dscp_value", 7813 .help = "new IPv6 DSCP value to set", 7814 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7815 .args = ARGS(ARGS_ENTRY 7816 (struct rte_flow_action_set_dscp, dscp)), 7817 .call = parse_vc_conf, 7818 }, 7819 [ACTION_AGE] = { 7820 .name = "age", 7821 .help = "set a specific metadata header", 7822 .next = NEXT(action_age), 7823 .priv = PRIV_ACTION(AGE, 7824 sizeof(struct rte_flow_action_age)), 7825 .call = parse_vc, 7826 }, 7827 [ACTION_AGE_TIMEOUT] = { 7828 .name = "timeout", 7829 .help = "flow age timeout value", 7830 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 7831 timeout, 24)), 7832 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 7833 .call = parse_vc_conf, 7834 }, 7835 [ACTION_AGE_UPDATE] = { 7836 .name = "age_update", 7837 .help = "update aging parameter", 7838 .next = NEXT(action_age_update), 7839 .priv = PRIV_ACTION(AGE, 7840 sizeof(struct rte_flow_update_age)), 7841 .call = parse_vc, 7842 }, 7843 [ACTION_AGE_UPDATE_TIMEOUT] = { 7844 .name = "timeout", 7845 .help = "age timeout update value", 7846 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7847 timeout, 24)), 7848 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7849 .call = parse_vc_conf_timeout, 7850 }, 7851 [ACTION_AGE_UPDATE_TOUCH] = { 7852 .name = "touch", 7853 .help = "this flow is touched", 7854 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), 7855 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7856 touch, 1)), 7857 .call = parse_vc_conf, 7858 }, 7859 [ACTION_SAMPLE] = { 7860 .name = "sample", 7861 .help = "set a sample action", 7862 .next = NEXT(action_sample), 7863 .priv = PRIV_ACTION(SAMPLE, 7864 sizeof(struct action_sample_data)), 7865 .call = parse_vc_action_sample, 7866 }, 7867 [ACTION_SAMPLE_RATIO] = { 7868 .name = "ratio", 7869 .help = "flow sample ratio value", 7870 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 7871 .args = ARGS(ARGS_ENTRY_ARB 7872 (offsetof(struct action_sample_data, conf) + 7873 offsetof(struct rte_flow_action_sample, ratio), 7874 sizeof(((struct rte_flow_action_sample *)0)-> 7875 ratio))), 7876 }, 7877 [ACTION_SAMPLE_INDEX] = { 7878 .name = "index", 7879 .help = "the index of sample actions list", 7880 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 7881 }, 7882 [ACTION_SAMPLE_INDEX_VALUE] = { 7883 .name = "{index}", 7884 .type = "COMMON_UNSIGNED", 7885 .help = "unsigned integer value", 7886 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7887 .call = parse_vc_action_sample_index, 7888 .comp = comp_set_sample_index, 7889 }, 7890 [ACTION_CONNTRACK] = { 7891 .name = "conntrack", 7892 .help = "create a conntrack object", 7893 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7894 .priv = PRIV_ACTION(CONNTRACK, 7895 sizeof(struct rte_flow_action_conntrack)), 7896 .call = parse_vc, 7897 }, 7898 [ACTION_CONNTRACK_UPDATE] = { 7899 .name = "conntrack_update", 7900 .help = "update a conntrack object", 7901 .next = NEXT(action_update_conntrack), 7902 .priv = PRIV_ACTION(CONNTRACK, 7903 sizeof(struct rte_flow_modify_conntrack)), 7904 .call = parse_vc, 7905 }, 7906 [ACTION_CONNTRACK_UPDATE_DIR] = { 7907 .name = "dir", 7908 .help = "update a conntrack object direction", 7909 .next = NEXT(action_update_conntrack), 7910 .call = parse_vc_action_conntrack_update, 7911 }, 7912 [ACTION_CONNTRACK_UPDATE_CTX] = { 7913 .name = "ctx", 7914 .help = "update a conntrack object context", 7915 .next = NEXT(action_update_conntrack), 7916 .call = parse_vc_action_conntrack_update, 7917 }, 7918 [ACTION_PORT_REPRESENTOR] = { 7919 .name = "port_representor", 7920 .help = "at embedded switch level, send matching traffic to the given ethdev", 7921 .priv = PRIV_ACTION(PORT_REPRESENTOR, 7922 sizeof(struct rte_flow_action_ethdev)), 7923 .next = NEXT(action_port_representor), 7924 .call = parse_vc, 7925 }, 7926 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 7927 .name = "port_id", 7928 .help = "ethdev port ID", 7929 .next = NEXT(action_port_representor, 7930 NEXT_ENTRY(COMMON_UNSIGNED)), 7931 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7932 port_id)), 7933 .call = parse_vc_conf, 7934 }, 7935 [ACTION_REPRESENTED_PORT] = { 7936 .name = "represented_port", 7937 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 7938 .priv = PRIV_ACTION(REPRESENTED_PORT, 7939 sizeof(struct rte_flow_action_ethdev)), 7940 .next = NEXT(action_represented_port), 7941 .call = parse_vc, 7942 }, 7943 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 7944 .name = "ethdev_port_id", 7945 .help = "ethdev port ID", 7946 .next = NEXT(action_represented_port, 7947 NEXT_ENTRY(COMMON_UNSIGNED)), 7948 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7949 port_id)), 7950 .call = parse_vc_conf, 7951 }, 7952 /* Indirect action destroy arguments. */ 7953 [INDIRECT_ACTION_DESTROY_ID] = { 7954 .name = "action_id", 7955 .help = "specify a indirect action id to destroy", 7956 .next = NEXT(next_ia_destroy_attr, 7957 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7958 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 7959 args.ia_destroy.action_id)), 7960 .call = parse_ia_destroy, 7961 }, 7962 /* Indirect action create arguments. */ 7963 [INDIRECT_ACTION_CREATE_ID] = { 7964 .name = "action_id", 7965 .help = "specify a indirect action id to create", 7966 .next = NEXT(next_ia_create_attr, 7967 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7968 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 7969 }, 7970 [ACTION_INDIRECT] = { 7971 .name = "indirect", 7972 .help = "apply indirect action by id", 7973 .priv = PRIV_ACTION(INDIRECT, 0), 7974 .next = NEXT(next_ia), 7975 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7976 .call = parse_vc, 7977 }, 7978 [ACTION_INDIRECT_LIST] = { 7979 .name = "indirect_list", 7980 .help = "apply indirect list action by id", 7981 .priv = PRIV_ACTION(INDIRECT_LIST, 7982 sizeof(struct 7983 rte_flow_action_indirect_list)), 7984 .next = NEXT(next_ial), 7985 .call = parse_vc, 7986 }, 7987 [ACTION_INDIRECT_LIST_HANDLE] = { 7988 .name = "handle", 7989 .help = "indirect list handle", 7990 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), 7991 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7992 }, 7993 [ACTION_INDIRECT_LIST_CONF] = { 7994 .name = "conf", 7995 .help = "indirect list configuration", 7996 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), 7997 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7998 }, 7999 [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { 8000 .type = "UNSIGNED", 8001 .help = "unsigned integer value", 8002 .call = parse_indlst_id2ptr, 8003 .comp = comp_none, 8004 }, 8005 [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { 8006 .type = "UNSIGNED", 8007 .help = "unsigned integer value", 8008 .call = parse_indlst_id2ptr, 8009 .comp = comp_none, 8010 }, 8011 [ACTION_SHARED_INDIRECT] = { 8012 .name = "shared_indirect", 8013 .help = "apply indirect action by id and port", 8014 .priv = PRIV_ACTION(INDIRECT, 0), 8015 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), 8016 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), 8017 ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 8018 .call = parse_vc, 8019 }, 8020 [INDIRECT_ACTION_PORT] = { 8021 .name = "{indirect_action_port}", 8022 .type = "INDIRECT_ACTION_PORT", 8023 .help = "indirect action port", 8024 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 8025 .call = parse_ia_port, 8026 .comp = comp_none, 8027 }, 8028 [INDIRECT_ACTION_ID2PTR] = { 8029 .name = "{action_id}", 8030 .type = "INDIRECT_ACTION_ID", 8031 .help = "indirect action id", 8032 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 8033 .call = parse_ia_id2ptr, 8034 .comp = comp_none, 8035 }, 8036 [INDIRECT_ACTION_INGRESS] = { 8037 .name = "ingress", 8038 .help = "affect rule to ingress", 8039 .next = NEXT(next_ia_create_attr), 8040 .call = parse_ia, 8041 }, 8042 [INDIRECT_ACTION_EGRESS] = { 8043 .name = "egress", 8044 .help = "affect rule to egress", 8045 .next = NEXT(next_ia_create_attr), 8046 .call = parse_ia, 8047 }, 8048 [INDIRECT_ACTION_TRANSFER] = { 8049 .name = "transfer", 8050 .help = "affect rule to transfer", 8051 .next = NEXT(next_ia_create_attr), 8052 .call = parse_ia, 8053 }, 8054 [INDIRECT_ACTION_SPEC] = { 8055 .name = "action", 8056 .help = "specify action to create indirect handle", 8057 .next = NEXT(next_action), 8058 }, 8059 [INDIRECT_ACTION_LIST] = { 8060 .name = "list", 8061 .help = "specify actions for indirect handle list", 8062 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 8063 .call = parse_ia, 8064 }, 8065 [INDIRECT_ACTION_FLOW_CONF] = { 8066 .name = "flow_conf", 8067 .help = "specify actions configuration for indirect handle list", 8068 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 8069 .call = parse_ia, 8070 }, 8071 [ACTION_POL_G] = { 8072 .name = "g_actions", 8073 .help = "submit a list of associated actions for green", 8074 .next = NEXT(next_action), 8075 .call = parse_mp, 8076 }, 8077 [ACTION_POL_Y] = { 8078 .name = "y_actions", 8079 .help = "submit a list of associated actions for yellow", 8080 .next = NEXT(next_action), 8081 }, 8082 [ACTION_POL_R] = { 8083 .name = "r_actions", 8084 .help = "submit a list of associated actions for red", 8085 .next = NEXT(next_action), 8086 }, 8087 [ACTION_QUOTA_CREATE] = { 8088 .name = "quota_create", 8089 .help = "create quota action", 8090 .priv = PRIV_ACTION(QUOTA, 8091 sizeof(struct rte_flow_action_quota)), 8092 .next = NEXT(action_quota_create), 8093 .call = parse_vc 8094 }, 8095 [ACTION_QUOTA_CREATE_LIMIT] = { 8096 .name = "limit", 8097 .help = "quota limit", 8098 .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), 8099 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), 8100 .call = parse_vc_conf 8101 }, 8102 [ACTION_QUOTA_CREATE_MODE] = { 8103 .name = "mode", 8104 .help = "quota mode", 8105 .next = NEXT(action_quota_create, 8106 NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), 8107 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), 8108 .call = parse_vc_conf 8109 }, 8110 [ACTION_QUOTA_CREATE_MODE_NAME] = { 8111 .name = "mode_name", 8112 .help = "quota mode name", 8113 .call = parse_quota_mode_name, 8114 .comp = comp_quota_mode_name 8115 }, 8116 [ACTION_QUOTA_QU] = { 8117 .name = "quota_update", 8118 .help = "update quota action", 8119 .priv = PRIV_ACTION(QUOTA, 8120 sizeof(struct rte_flow_update_quota)), 8121 .next = NEXT(action_quota_update), 8122 .call = parse_vc 8123 }, 8124 [ACTION_QUOTA_QU_LIMIT] = { 8125 .name = "limit", 8126 .help = "quota limit", 8127 .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), 8128 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), 8129 .call = parse_vc_conf 8130 }, 8131 [ACTION_QUOTA_QU_UPDATE_OP] = { 8132 .name = "update_op", 8133 .help = "query update op SET|ADD", 8134 .next = NEXT(action_quota_update, 8135 NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), 8136 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), 8137 .call = parse_vc_conf 8138 }, 8139 [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { 8140 .name = "update_op_name", 8141 .help = "quota update op name", 8142 .call = parse_quota_update_name, 8143 .comp = comp_quota_update_name 8144 }, 8145 8146 /* Top-level command. */ 8147 [ADD] = { 8148 .name = "add", 8149 .type = "port meter policy {port_id} {arg}", 8150 .help = "add port meter policy", 8151 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 8152 .call = parse_init, 8153 }, 8154 /* Sub-level commands. */ 8155 [ITEM_POL_PORT] = { 8156 .name = "port", 8157 .help = "add port meter policy", 8158 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 8159 }, 8160 [ITEM_POL_METER] = { 8161 .name = "meter", 8162 .help = "add port meter policy", 8163 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 8164 }, 8165 [ITEM_POL_POLICY] = { 8166 .name = "policy", 8167 .help = "add port meter policy", 8168 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 8169 NEXT_ENTRY(ACTION_POL_Y), 8170 NEXT_ENTRY(ACTION_POL_G), 8171 NEXT_ENTRY(COMMON_POLICY_ID), 8172 NEXT_ENTRY(COMMON_PORT_ID)), 8173 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 8174 ARGS_ENTRY(struct buffer, port)), 8175 .call = parse_mp, 8176 }, 8177 [ITEM_AGGR_AFFINITY] = { 8178 .name = "aggr_affinity", 8179 .help = "match on the aggregated port receiving the packets", 8180 .priv = PRIV_ITEM(AGGR_AFFINITY, 8181 sizeof(struct rte_flow_item_aggr_affinity)), 8182 .next = NEXT(item_aggr_affinity), 8183 .call = parse_vc, 8184 }, 8185 [ITEM_AGGR_AFFINITY_VALUE] = { 8186 .name = "affinity", 8187 .help = "aggregated affinity value", 8188 .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), 8189 item_param), 8190 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, 8191 affinity)), 8192 }, 8193 [ITEM_TX_QUEUE] = { 8194 .name = "tx_queue", 8195 .help = "match on the tx queue of send packet", 8196 .priv = PRIV_ITEM(TX_QUEUE, 8197 sizeof(struct rte_flow_item_tx_queue)), 8198 .next = NEXT(item_tx_queue), 8199 .call = parse_vc, 8200 }, 8201 [ITEM_TX_QUEUE_VALUE] = { 8202 .name = "tx_queue_value", 8203 .help = "tx queue value", 8204 .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), 8205 item_param), 8206 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, 8207 tx_queue)), 8208 }, 8209 }; 8210 8211 /** Remove and return last entry from argument stack. */ 8212 static const struct arg * 8213 pop_args(struct context *ctx) 8214 { 8215 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 8216 } 8217 8218 /** Add entry on top of the argument stack. */ 8219 static int 8220 push_args(struct context *ctx, const struct arg *arg) 8221 { 8222 if (ctx->args_num == CTX_STACK_SIZE) 8223 return -1; 8224 ctx->args[ctx->args_num++] = arg; 8225 return 0; 8226 } 8227 8228 /** Spread value into buffer according to bit-mask. */ 8229 static size_t 8230 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 8231 { 8232 uint32_t i = arg->size; 8233 uint32_t end = 0; 8234 int sub = 1; 8235 int add = 0; 8236 size_t len = 0; 8237 8238 if (!arg->mask) 8239 return 0; 8240 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8241 if (!arg->hton) { 8242 i = 0; 8243 end = arg->size; 8244 sub = 0; 8245 add = 1; 8246 } 8247 #endif 8248 while (i != end) { 8249 unsigned int shift = 0; 8250 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 8251 8252 for (shift = 0; arg->mask[i] >> shift; ++shift) { 8253 if (!(arg->mask[i] & (1 << shift))) 8254 continue; 8255 ++len; 8256 if (!dst) 8257 continue; 8258 *buf &= ~(1 << shift); 8259 *buf |= (val & 1) << shift; 8260 val >>= 1; 8261 } 8262 i += add; 8263 } 8264 return len; 8265 } 8266 8267 /** Compare a string with a partial one of a given length. */ 8268 static int 8269 strcmp_partial(const char *full, const char *partial, size_t partial_len) 8270 { 8271 int r = strncmp(full, partial, partial_len); 8272 8273 if (r) 8274 return r; 8275 if (strlen(full) <= partial_len) 8276 return 0; 8277 return full[partial_len]; 8278 } 8279 8280 /** 8281 * Parse a prefix length and generate a bit-mask. 8282 * 8283 * Last argument (ctx->args) is retrieved to determine mask size, storage 8284 * location and whether the result must use network byte ordering. 8285 */ 8286 static int 8287 parse_prefix(struct context *ctx, const struct token *token, 8288 const char *str, unsigned int len, 8289 void *buf, unsigned int size) 8290 { 8291 const struct arg *arg = pop_args(ctx); 8292 static const uint8_t conv[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 8293 0xf8, 0xfc, 0xfe, 0xff }; 8294 char *end; 8295 uintmax_t u; 8296 unsigned int bytes; 8297 unsigned int extra; 8298 8299 (void)token; 8300 /* Argument is expected. */ 8301 if (!arg) 8302 return -1; 8303 errno = 0; 8304 u = strtoumax(str, &end, 0); 8305 if (errno || (size_t)(end - str) != len) 8306 goto error; 8307 if (arg->mask) { 8308 uintmax_t v = 0; 8309 8310 extra = arg_entry_bf_fill(NULL, 0, arg); 8311 if (u > extra) 8312 goto error; 8313 if (!ctx->object) 8314 return len; 8315 extra -= u; 8316 while (u--) 8317 (v <<= 1, v |= 1); 8318 v <<= extra; 8319 if (!arg_entry_bf_fill(ctx->object, v, arg) || 8320 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 8321 goto error; 8322 return len; 8323 } 8324 bytes = u / 8; 8325 extra = u % 8; 8326 size = arg->size; 8327 if (bytes > size || bytes + !!extra > size) 8328 goto error; 8329 if (!ctx->object) 8330 return len; 8331 buf = (uint8_t *)ctx->object + arg->offset; 8332 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8333 if (!arg->hton) { 8334 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 8335 memset(buf, 0x00, size - bytes); 8336 if (extra) 8337 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 8338 } else 8339 #endif 8340 { 8341 memset(buf, 0xff, bytes); 8342 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 8343 if (extra) 8344 ((uint8_t *)buf)[bytes] = conv[extra]; 8345 } 8346 if (ctx->objmask) 8347 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 8348 return len; 8349 error: 8350 push_args(ctx, arg); 8351 return -1; 8352 } 8353 8354 /** Default parsing function for token name matching. */ 8355 static int 8356 parse_default(struct context *ctx, const struct token *token, 8357 const char *str, unsigned int len, 8358 void *buf, unsigned int size) 8359 { 8360 (void)ctx; 8361 (void)buf; 8362 (void)size; 8363 if (strcmp_partial(token->name, str, len)) 8364 return -1; 8365 return len; 8366 } 8367 8368 /** Parse flow command, initialize output buffer for subsequent tokens. */ 8369 static int 8370 parse_init(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 /* Make sure buffer is large enough. */ 8383 if (size < sizeof(*out)) 8384 return -1; 8385 /* Initialize buffer. */ 8386 memset(out, 0x00, sizeof(*out)); 8387 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 8388 ctx->objdata = 0; 8389 ctx->object = out; 8390 ctx->objmask = NULL; 8391 return len; 8392 } 8393 8394 /** Parse tokens for indirect action commands. */ 8395 static int 8396 parse_ia(struct context *ctx, const struct token *token, 8397 const char *str, unsigned int len, 8398 void *buf, unsigned int size) 8399 { 8400 struct buffer *out = buf; 8401 8402 /* Token name must match. */ 8403 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8404 return -1; 8405 /* Nothing else to do if there is no buffer. */ 8406 if (!out) 8407 return len; 8408 if (!out->command) { 8409 if (ctx->curr != INDIRECT_ACTION) 8410 return -1; 8411 if (sizeof(*out) > size) 8412 return -1; 8413 out->command = ctx->curr; 8414 ctx->objdata = 0; 8415 ctx->object = out; 8416 ctx->objmask = NULL; 8417 out->args.vc.data = (uint8_t *)out + size; 8418 return len; 8419 } 8420 switch (ctx->curr) { 8421 case INDIRECT_ACTION_CREATE: 8422 case INDIRECT_ACTION_UPDATE: 8423 case INDIRECT_ACTION_QUERY_UPDATE: 8424 out->args.vc.actions = 8425 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8426 sizeof(double)); 8427 out->args.vc.attr.group = UINT32_MAX; 8428 /* fallthrough */ 8429 case INDIRECT_ACTION_QUERY: 8430 out->command = ctx->curr; 8431 ctx->objdata = 0; 8432 ctx->object = out; 8433 ctx->objmask = NULL; 8434 return len; 8435 case INDIRECT_ACTION_EGRESS: 8436 out->args.vc.attr.egress = 1; 8437 return len; 8438 case INDIRECT_ACTION_INGRESS: 8439 out->args.vc.attr.ingress = 1; 8440 return len; 8441 case INDIRECT_ACTION_TRANSFER: 8442 out->args.vc.attr.transfer = 1; 8443 return len; 8444 case INDIRECT_ACTION_QU_MODE: 8445 return len; 8446 case INDIRECT_ACTION_LIST: 8447 out->command = INDIRECT_ACTION_LIST_CREATE; 8448 return len; 8449 case INDIRECT_ACTION_FLOW_CONF: 8450 out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; 8451 return len; 8452 default: 8453 return -1; 8454 } 8455 } 8456 8457 8458 /** Parse tokens for indirect action destroy command. */ 8459 static int 8460 parse_ia_destroy(struct context *ctx, const struct token *token, 8461 const char *str, unsigned int len, 8462 void *buf, unsigned int size) 8463 { 8464 struct buffer *out = buf; 8465 uint32_t *action_id; 8466 8467 /* Token name must match. */ 8468 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8469 return -1; 8470 /* Nothing else to do if there is no buffer. */ 8471 if (!out) 8472 return len; 8473 if (!out->command || out->command == INDIRECT_ACTION) { 8474 if (ctx->curr != INDIRECT_ACTION_DESTROY) 8475 return -1; 8476 if (sizeof(*out) > size) 8477 return -1; 8478 out->command = ctx->curr; 8479 ctx->objdata = 0; 8480 ctx->object = out; 8481 ctx->objmask = NULL; 8482 out->args.ia_destroy.action_id = 8483 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8484 sizeof(double)); 8485 return len; 8486 } 8487 action_id = out->args.ia_destroy.action_id 8488 + out->args.ia_destroy.action_id_n++; 8489 if ((uint8_t *)action_id > (uint8_t *)out + size) 8490 return -1; 8491 ctx->objdata = 0; 8492 ctx->object = action_id; 8493 ctx->objmask = NULL; 8494 return len; 8495 } 8496 8497 /** Parse tokens for indirect action commands. */ 8498 static int 8499 parse_qia(struct context *ctx, const struct token *token, 8500 const char *str, unsigned int len, 8501 void *buf, unsigned int size) 8502 { 8503 struct buffer *out = buf; 8504 8505 /* Token name must match. */ 8506 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8507 return -1; 8508 /* Nothing else to do if there is no buffer. */ 8509 if (!out) 8510 return len; 8511 if (!out->command) { 8512 if (ctx->curr != QUEUE) 8513 return -1; 8514 if (sizeof(*out) > size) 8515 return -1; 8516 out->args.vc.data = (uint8_t *)out + size; 8517 return len; 8518 } 8519 switch (ctx->curr) { 8520 case QUEUE_INDIRECT_ACTION: 8521 return len; 8522 case QUEUE_INDIRECT_ACTION_CREATE: 8523 case QUEUE_INDIRECT_ACTION_UPDATE: 8524 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 8525 out->args.vc.actions = 8526 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8527 sizeof(double)); 8528 out->args.vc.attr.group = UINT32_MAX; 8529 /* fallthrough */ 8530 case QUEUE_INDIRECT_ACTION_QUERY: 8531 out->command = ctx->curr; 8532 ctx->objdata = 0; 8533 ctx->object = out; 8534 ctx->objmask = NULL; 8535 return len; 8536 case QUEUE_INDIRECT_ACTION_EGRESS: 8537 out->args.vc.attr.egress = 1; 8538 return len; 8539 case QUEUE_INDIRECT_ACTION_INGRESS: 8540 out->args.vc.attr.ingress = 1; 8541 return len; 8542 case QUEUE_INDIRECT_ACTION_TRANSFER: 8543 out->args.vc.attr.transfer = 1; 8544 return len; 8545 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 8546 return len; 8547 case QUEUE_INDIRECT_ACTION_QU_MODE: 8548 return len; 8549 case QUEUE_INDIRECT_ACTION_LIST: 8550 out->command = QUEUE_INDIRECT_ACTION_LIST_CREATE; 8551 return len; 8552 default: 8553 return -1; 8554 } 8555 } 8556 8557 /** Parse tokens for indirect action destroy command. */ 8558 static int 8559 parse_qia_destroy(struct context *ctx, const struct token *token, 8560 const char *str, unsigned int len, 8561 void *buf, unsigned int size) 8562 { 8563 struct buffer *out = buf; 8564 uint32_t *action_id; 8565 8566 /* Token name must match. */ 8567 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8568 return -1; 8569 /* Nothing else to do if there is no buffer. */ 8570 if (!out) 8571 return len; 8572 if (!out->command || out->command == QUEUE) { 8573 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 8574 return -1; 8575 if (sizeof(*out) > size) 8576 return -1; 8577 out->command = ctx->curr; 8578 ctx->objdata = 0; 8579 ctx->object = out; 8580 ctx->objmask = NULL; 8581 out->args.ia_destroy.action_id = 8582 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8583 sizeof(double)); 8584 return len; 8585 } 8586 switch (ctx->curr) { 8587 case QUEUE_INDIRECT_ACTION: 8588 out->command = ctx->curr; 8589 ctx->objdata = 0; 8590 ctx->object = out; 8591 ctx->objmask = NULL; 8592 return len; 8593 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 8594 action_id = out->args.ia_destroy.action_id 8595 + out->args.ia_destroy.action_id_n++; 8596 if ((uint8_t *)action_id > (uint8_t *)out + size) 8597 return -1; 8598 ctx->objdata = 0; 8599 ctx->object = action_id; 8600 ctx->objmask = NULL; 8601 return len; 8602 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 8603 return len; 8604 default: 8605 return -1; 8606 } 8607 } 8608 8609 /** Parse tokens for meter policy action commands. */ 8610 static int 8611 parse_mp(struct context *ctx, const struct token *token, 8612 const char *str, unsigned int len, 8613 void *buf, unsigned int size) 8614 { 8615 struct buffer *out = buf; 8616 8617 /* Token name must match. */ 8618 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8619 return -1; 8620 /* Nothing else to do if there is no buffer. */ 8621 if (!out) 8622 return len; 8623 if (!out->command) { 8624 if (ctx->curr != ITEM_POL_POLICY) 8625 return -1; 8626 if (sizeof(*out) > size) 8627 return -1; 8628 out->command = ctx->curr; 8629 ctx->objdata = 0; 8630 ctx->object = out; 8631 ctx->objmask = NULL; 8632 out->args.vc.data = (uint8_t *)out + size; 8633 return len; 8634 } 8635 switch (ctx->curr) { 8636 case ACTION_POL_G: 8637 out->args.vc.actions = 8638 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8639 sizeof(double)); 8640 out->command = ctx->curr; 8641 ctx->objdata = 0; 8642 ctx->object = out; 8643 ctx->objmask = NULL; 8644 return len; 8645 default: 8646 return -1; 8647 } 8648 } 8649 8650 /** Parse tokens for validate/create commands. */ 8651 static int 8652 parse_vc(struct context *ctx, const struct token *token, 8653 const char *str, unsigned int len, 8654 void *buf, unsigned int size) 8655 { 8656 struct buffer *out = buf; 8657 uint8_t *data; 8658 uint32_t data_size; 8659 8660 /* Token name must match. */ 8661 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8662 return -1; 8663 /* Nothing else to do if there is no buffer. */ 8664 if (!out) 8665 return len; 8666 if (!out->command) { 8667 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 8668 ctx->curr != PATTERN_TEMPLATE_CREATE && 8669 ctx->curr != ACTIONS_TEMPLATE_CREATE && 8670 ctx->curr != UPDATE) 8671 return -1; 8672 if (ctx->curr == UPDATE) 8673 out->args.vc.pattern = 8674 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8675 sizeof(double)); 8676 if (sizeof(*out) > size) 8677 return -1; 8678 out->command = ctx->curr; 8679 ctx->objdata = 0; 8680 ctx->object = out; 8681 ctx->objmask = NULL; 8682 out->args.vc.data = (uint8_t *)out + size; 8683 return len; 8684 } 8685 ctx->objdata = 0; 8686 switch (ctx->curr) { 8687 default: 8688 ctx->object = &out->args.vc.attr; 8689 break; 8690 case VC_TUNNEL_SET: 8691 case VC_TUNNEL_MATCH: 8692 ctx->object = &out->args.vc.tunnel_ops; 8693 break; 8694 case VC_USER_ID: 8695 ctx->object = out; 8696 break; 8697 } 8698 ctx->objmask = NULL; 8699 switch (ctx->curr) { 8700 case VC_GROUP: 8701 case VC_PRIORITY: 8702 case VC_USER_ID: 8703 return len; 8704 case VC_TUNNEL_SET: 8705 out->args.vc.tunnel_ops.enabled = 1; 8706 out->args.vc.tunnel_ops.actions = 1; 8707 return len; 8708 case VC_TUNNEL_MATCH: 8709 out->args.vc.tunnel_ops.enabled = 1; 8710 out->args.vc.tunnel_ops.items = 1; 8711 return len; 8712 case VC_INGRESS: 8713 out->args.vc.attr.ingress = 1; 8714 return len; 8715 case VC_EGRESS: 8716 out->args.vc.attr.egress = 1; 8717 return len; 8718 case VC_TRANSFER: 8719 out->args.vc.attr.transfer = 1; 8720 return len; 8721 case ITEM_PATTERN: 8722 out->args.vc.pattern = 8723 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8724 sizeof(double)); 8725 ctx->object = out->args.vc.pattern; 8726 ctx->objmask = NULL; 8727 return len; 8728 case ITEM_END: 8729 if ((out->command == VALIDATE || out->command == CREATE) && 8730 ctx->last) 8731 return -1; 8732 if (out->command == PATTERN_TEMPLATE_CREATE && 8733 !ctx->last) 8734 return -1; 8735 break; 8736 case ACTIONS: 8737 out->args.vc.actions = out->args.vc.pattern ? 8738 (void *)RTE_ALIGN_CEIL((uintptr_t) 8739 (out->args.vc.pattern + 8740 out->args.vc.pattern_n), 8741 sizeof(double)) : 8742 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8743 sizeof(double)); 8744 ctx->object = out->args.vc.actions; 8745 ctx->objmask = NULL; 8746 return len; 8747 case VC_IS_USER_ID: 8748 out->args.vc.user_id = true; 8749 return len; 8750 default: 8751 if (!token->priv) 8752 return -1; 8753 break; 8754 } 8755 if (!out->args.vc.actions) { 8756 const struct parse_item_priv *priv = token->priv; 8757 struct rte_flow_item *item = 8758 out->args.vc.pattern + out->args.vc.pattern_n; 8759 8760 data_size = priv->size * 3; /* spec, last, mask */ 8761 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8762 (out->args.vc.data - data_size), 8763 sizeof(double)); 8764 if ((uint8_t *)item + sizeof(*item) > data) 8765 return -1; 8766 *item = (struct rte_flow_item){ 8767 .type = priv->type, 8768 }; 8769 ++out->args.vc.pattern_n; 8770 ctx->object = item; 8771 ctx->objmask = NULL; 8772 } else { 8773 const struct parse_action_priv *priv = token->priv; 8774 struct rte_flow_action *action = 8775 out->args.vc.actions + out->args.vc.actions_n; 8776 8777 data_size = priv->size; /* configuration */ 8778 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8779 (out->args.vc.data - data_size), 8780 sizeof(double)); 8781 if ((uint8_t *)action + sizeof(*action) > data) 8782 return -1; 8783 *action = (struct rte_flow_action){ 8784 .type = priv->type, 8785 .conf = data_size ? data : NULL, 8786 }; 8787 ++out->args.vc.actions_n; 8788 ctx->object = action; 8789 ctx->objmask = NULL; 8790 } 8791 memset(data, 0, data_size); 8792 out->args.vc.data = data; 8793 ctx->objdata = data_size; 8794 return len; 8795 } 8796 8797 /** Parse pattern item parameter type. */ 8798 static int 8799 parse_vc_spec(struct context *ctx, const struct token *token, 8800 const char *str, unsigned int len, 8801 void *buf, unsigned int size) 8802 { 8803 struct buffer *out = buf; 8804 struct rte_flow_item *item; 8805 uint32_t data_size; 8806 int index; 8807 int objmask = 0; 8808 8809 (void)size; 8810 /* Token name must match. */ 8811 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8812 return -1; 8813 /* Parse parameter types. */ 8814 switch (ctx->curr) { 8815 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 8816 8817 case ITEM_PARAM_IS: 8818 index = 0; 8819 objmask = 1; 8820 break; 8821 case ITEM_PARAM_SPEC: 8822 index = 0; 8823 break; 8824 case ITEM_PARAM_LAST: 8825 index = 1; 8826 break; 8827 case ITEM_PARAM_PREFIX: 8828 /* Modify next token to expect a prefix. */ 8829 if (ctx->next_num < 2) 8830 return -1; 8831 ctx->next[ctx->next_num - 2] = prefix; 8832 /* Fall through. */ 8833 case ITEM_PARAM_MASK: 8834 index = 2; 8835 break; 8836 default: 8837 return -1; 8838 } 8839 /* Nothing else to do if there is no buffer. */ 8840 if (!out) 8841 return len; 8842 if (!out->args.vc.pattern_n) 8843 return -1; 8844 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8845 data_size = ctx->objdata / 3; /* spec, last, mask */ 8846 /* Point to selected object. */ 8847 ctx->object = out->args.vc.data + (data_size * index); 8848 if (objmask) { 8849 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 8850 item->mask = ctx->objmask; 8851 } else 8852 ctx->objmask = NULL; 8853 /* Update relevant item pointer. */ 8854 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 8855 ctx->object; 8856 return len; 8857 } 8858 8859 /** Parse action configuration field. */ 8860 static int 8861 parse_vc_conf(struct context *ctx, const struct token *token, 8862 const char *str, unsigned int len, 8863 void *buf, unsigned int size) 8864 { 8865 struct buffer *out = buf; 8866 8867 (void)size; 8868 /* Token name must match. */ 8869 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8870 return -1; 8871 /* Nothing else to do if there is no buffer. */ 8872 if (!out) 8873 return len; 8874 /* Point to selected object. */ 8875 ctx->object = out->args.vc.data; 8876 ctx->objmask = NULL; 8877 return len; 8878 } 8879 8880 /** Parse action configuration field. */ 8881 static int 8882 parse_vc_conf_timeout(struct context *ctx, const struct token *token, 8883 const char *str, unsigned int len, 8884 void *buf, unsigned int size) 8885 { 8886 struct buffer *out = buf; 8887 struct rte_flow_update_age *update; 8888 8889 (void)size; 8890 if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) 8891 return -1; 8892 /* Token name must match. */ 8893 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8894 return -1; 8895 /* Nothing else to do if there is no buffer. */ 8896 if (!out) 8897 return len; 8898 /* Point to selected object. */ 8899 ctx->object = out->args.vc.data; 8900 ctx->objmask = NULL; 8901 /* Update the timeout is valid. */ 8902 update = (struct rte_flow_update_age *)out->args.vc.data; 8903 update->timeout_valid = 1; 8904 return len; 8905 } 8906 8907 /** Parse eCPRI common header type field. */ 8908 static int 8909 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 8910 const char *str, unsigned int len, 8911 void *buf, unsigned int size) 8912 { 8913 struct rte_flow_item_ecpri *ecpri; 8914 struct rte_flow_item_ecpri *ecpri_mask; 8915 struct rte_flow_item *item; 8916 uint32_t data_size; 8917 uint8_t msg_type; 8918 struct buffer *out = buf; 8919 const struct arg *arg; 8920 8921 (void)size; 8922 /* Token name must match. */ 8923 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8924 return -1; 8925 switch (ctx->curr) { 8926 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 8927 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 8928 break; 8929 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 8930 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 8931 break; 8932 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 8933 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 8934 break; 8935 default: 8936 return -1; 8937 } 8938 if (!ctx->object) 8939 return len; 8940 arg = pop_args(ctx); 8941 if (!arg) 8942 return -1; 8943 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 8944 ecpri->hdr.common.type = msg_type; 8945 data_size = ctx->objdata / 3; /* spec, last, mask */ 8946 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 8947 (data_size * 2)); 8948 ecpri_mask->hdr.common.type = 0xFF; 8949 if (arg->hton) { 8950 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 8951 ecpri_mask->hdr.common.u32 = 8952 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 8953 } 8954 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8955 item->spec = ecpri; 8956 item->mask = ecpri_mask; 8957 return len; 8958 } 8959 8960 /** Parse L2TPv2 common header type field. */ 8961 static int 8962 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, 8963 const char *str, unsigned int len, 8964 void *buf, unsigned int size) 8965 { 8966 struct rte_flow_item_l2tpv2 *l2tpv2; 8967 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 8968 struct rte_flow_item *item; 8969 uint32_t data_size; 8970 uint16_t msg_type = 0; 8971 struct buffer *out = buf; 8972 const struct arg *arg; 8973 8974 (void)size; 8975 /* Token name must match. */ 8976 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8977 return -1; 8978 switch (ctx->curr) { 8979 case ITEM_L2TPV2_TYPE_DATA: 8980 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 8981 break; 8982 case ITEM_L2TPV2_TYPE_DATA_L: 8983 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 8984 break; 8985 case ITEM_L2TPV2_TYPE_DATA_S: 8986 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 8987 break; 8988 case ITEM_L2TPV2_TYPE_DATA_O: 8989 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 8990 break; 8991 case ITEM_L2TPV2_TYPE_DATA_L_S: 8992 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 8993 break; 8994 case ITEM_L2TPV2_TYPE_CTRL: 8995 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 8996 break; 8997 default: 8998 return -1; 8999 } 9000 if (!ctx->object) 9001 return len; 9002 arg = pop_args(ctx); 9003 if (!arg) 9004 return -1; 9005 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 9006 l2tpv2->hdr.common.flags_version |= msg_type; 9007 data_size = ctx->objdata / 3; /* spec, last, mask */ 9008 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 9009 (data_size * 2)); 9010 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 9011 if (arg->hton) { 9012 l2tpv2->hdr.common.flags_version = 9013 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 9014 l2tpv2_mask->hdr.common.flags_version = 9015 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 9016 } 9017 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 9018 item->spec = l2tpv2; 9019 item->mask = l2tpv2_mask; 9020 return len; 9021 } 9022 9023 /** Parse operation for compare match item. */ 9024 static int 9025 parse_vc_compare_op(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_OP_VALUE) 9036 return -1; 9037 for (i = 0; compare_ops[i]; ++i) 9038 if (!strcmp_partial(compare_ops[i], str, len)) 9039 break; 9040 if (!compare_ops[i]) 9041 return -1; 9042 if (!ctx->object) 9043 return len; 9044 compare_item = ctx->object; 9045 compare_item->operation = (enum rte_flow_item_compare_op)i; 9046 return len; 9047 } 9048 9049 /** Parse id for compare match item. */ 9050 static int 9051 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 9052 const char *str, unsigned int len, void *buf, 9053 unsigned int size) 9054 { 9055 struct rte_flow_item_compare *compare_item; 9056 unsigned int i; 9057 9058 (void)token; 9059 (void)buf; 9060 (void)size; 9061 if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE && 9062 ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE) 9063 return -1; 9064 for (i = 0; flow_field_ids[i]; ++i) 9065 if (!strcmp_partial(flow_field_ids[i], str, len)) 9066 break; 9067 if (!flow_field_ids[i]) 9068 return -1; 9069 if (!ctx->object) 9070 return len; 9071 compare_item = ctx->object; 9072 if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE) 9073 compare_item->a.field = (enum rte_flow_field_id)i; 9074 else 9075 compare_item->b.field = (enum rte_flow_field_id)i; 9076 return len; 9077 } 9078 9079 /** Parse level for compare match item. */ 9080 static int 9081 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 9082 const char *str, unsigned int len, void *buf, 9083 unsigned int size) 9084 { 9085 struct rte_flow_item_compare *compare_item; 9086 struct flex_item *fp = NULL; 9087 uint32_t val; 9088 struct buffer *out = buf; 9089 char *end; 9090 9091 (void)token; 9092 (void)size; 9093 if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 9094 ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE) 9095 return -1; 9096 if (!ctx->object) 9097 return len; 9098 compare_item = ctx->object; 9099 errno = 0; 9100 val = strtoumax(str, &end, 0); 9101 if (errno || (size_t)(end - str) != len) 9102 return -1; 9103 /* No need to validate action template mask value */ 9104 if (out->args.vc.masks) { 9105 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) 9106 compare_item->a.level = val; 9107 else 9108 compare_item->b.level = val; 9109 return len; 9110 } 9111 if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 9112 compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) || 9113 (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE && 9114 compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 9115 if (val >= FLEX_MAX_PARSERS_NUM) { 9116 printf("Bad flex item handle\n"); 9117 return -1; 9118 } 9119 fp = flex_items[ctx->port][val]; 9120 if (!fp) { 9121 printf("Bad flex item handle\n"); 9122 return -1; 9123 } 9124 } 9125 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) { 9126 if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM) 9127 compare_item->a.level = val; 9128 else 9129 compare_item->a.flex_handle = fp->flex_handle; 9130 } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) { 9131 if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM) 9132 compare_item->b.level = val; 9133 else 9134 compare_item->b.flex_handle = fp->flex_handle; 9135 } 9136 return len; 9137 } 9138 9139 /** Parse meter color action type. */ 9140 static int 9141 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 9142 const char *str, unsigned int len, 9143 void *buf, unsigned int size) 9144 { 9145 struct rte_flow_action *action_data; 9146 struct rte_flow_action_meter_color *conf; 9147 enum rte_color color; 9148 9149 (void)buf; 9150 (void)size; 9151 /* Token name must match. */ 9152 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9153 return -1; 9154 switch (ctx->curr) { 9155 case ACTION_METER_COLOR_GREEN: 9156 color = RTE_COLOR_GREEN; 9157 break; 9158 case ACTION_METER_COLOR_YELLOW: 9159 color = RTE_COLOR_YELLOW; 9160 break; 9161 case ACTION_METER_COLOR_RED: 9162 color = RTE_COLOR_RED; 9163 break; 9164 default: 9165 return -1; 9166 } 9167 9168 if (!ctx->object) 9169 return len; 9170 action_data = ctx->object; 9171 conf = (struct rte_flow_action_meter_color *) 9172 (uintptr_t)(action_data->conf); 9173 conf->color = color; 9174 return len; 9175 } 9176 9177 /** Parse RSS action. */ 9178 static int 9179 parse_vc_action_rss(struct context *ctx, const struct token *token, 9180 const char *str, unsigned int len, 9181 void *buf, unsigned int size) 9182 { 9183 struct buffer *out = buf; 9184 struct rte_flow_action *action; 9185 struct action_rss_data *action_rss_data; 9186 unsigned int i; 9187 int ret; 9188 9189 ret = parse_vc(ctx, token, str, len, buf, size); 9190 if (ret < 0) 9191 return ret; 9192 /* Nothing else to do if there is no buffer. */ 9193 if (!out) 9194 return ret; 9195 if (!out->args.vc.actions_n) 9196 return -1; 9197 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9198 /* Point to selected object. */ 9199 ctx->object = out->args.vc.data; 9200 ctx->objmask = NULL; 9201 /* Set up default configuration. */ 9202 action_rss_data = ctx->object; 9203 *action_rss_data = (struct action_rss_data){ 9204 .conf = (struct rte_flow_action_rss){ 9205 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 9206 .level = 0, 9207 .types = rss_hf, 9208 .key_len = 0, 9209 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 9210 .key = NULL, 9211 .queue = action_rss_data->queue, 9212 }, 9213 .queue = { 0 }, 9214 }; 9215 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 9216 action_rss_data->queue[i] = i; 9217 action->conf = &action_rss_data->conf; 9218 return ret; 9219 } 9220 9221 /** 9222 * Parse func field for RSS action. 9223 * 9224 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 9225 * ACTION_RSS_FUNC_* index that called this function. 9226 */ 9227 static int 9228 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 9229 const char *str, unsigned int len, 9230 void *buf, unsigned int size) 9231 { 9232 struct action_rss_data *action_rss_data; 9233 enum rte_eth_hash_function func; 9234 9235 (void)buf; 9236 (void)size; 9237 /* Token name must match. */ 9238 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9239 return -1; 9240 switch (ctx->curr) { 9241 case ACTION_RSS_FUNC_DEFAULT: 9242 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 9243 break; 9244 case ACTION_RSS_FUNC_TOEPLITZ: 9245 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 9246 break; 9247 case ACTION_RSS_FUNC_SIMPLE_XOR: 9248 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 9249 break; 9250 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 9251 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 9252 break; 9253 default: 9254 return -1; 9255 } 9256 if (!ctx->object) 9257 return len; 9258 action_rss_data = ctx->object; 9259 action_rss_data->conf.func = func; 9260 return len; 9261 } 9262 9263 /** 9264 * Parse type field for RSS action. 9265 * 9266 * Valid tokens are type field names and the "end" token. 9267 */ 9268 static int 9269 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 9270 const char *str, unsigned int len, 9271 void *buf, unsigned int size) 9272 { 9273 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 9274 struct action_rss_data *action_rss_data; 9275 unsigned int i; 9276 9277 (void)token; 9278 (void)buf; 9279 (void)size; 9280 if (ctx->curr != ACTION_RSS_TYPE) 9281 return -1; 9282 if (!(ctx->objdata >> 16) && ctx->object) { 9283 action_rss_data = ctx->object; 9284 action_rss_data->conf.types = 0; 9285 } 9286 if (!strcmp_partial("end", str, len)) { 9287 ctx->objdata &= 0xffff; 9288 return len; 9289 } 9290 for (i = 0; rss_type_table[i].str; ++i) 9291 if (!strcmp_partial(rss_type_table[i].str, str, len)) 9292 break; 9293 if (!rss_type_table[i].str) 9294 return -1; 9295 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 9296 /* Repeat token. */ 9297 if (ctx->next_num == RTE_DIM(ctx->next)) 9298 return -1; 9299 ctx->next[ctx->next_num++] = next; 9300 if (!ctx->object) 9301 return len; 9302 action_rss_data = ctx->object; 9303 action_rss_data->conf.types |= rss_type_table[i].rss_type; 9304 return len; 9305 } 9306 9307 /** 9308 * Parse queue field for RSS action. 9309 * 9310 * Valid tokens are queue indices and the "end" token. 9311 */ 9312 static int 9313 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 9314 const char *str, unsigned int len, 9315 void *buf, unsigned int size) 9316 { 9317 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 9318 struct action_rss_data *action_rss_data; 9319 const struct arg *arg; 9320 int ret; 9321 int i; 9322 9323 (void)token; 9324 (void)buf; 9325 (void)size; 9326 if (ctx->curr != ACTION_RSS_QUEUE) 9327 return -1; 9328 i = ctx->objdata >> 16; 9329 if (!strcmp_partial("end", str, len)) { 9330 ctx->objdata &= 0xffff; 9331 goto end; 9332 } 9333 if (i >= ACTION_RSS_QUEUE_NUM) 9334 return -1; 9335 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 9336 i * sizeof(action_rss_data->queue[i]), 9337 sizeof(action_rss_data->queue[i])); 9338 if (push_args(ctx, arg)) 9339 return -1; 9340 ret = parse_int(ctx, token, str, len, NULL, 0); 9341 if (ret < 0) { 9342 pop_args(ctx); 9343 return -1; 9344 } 9345 ++i; 9346 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 9347 /* Repeat token. */ 9348 if (ctx->next_num == RTE_DIM(ctx->next)) 9349 return -1; 9350 ctx->next[ctx->next_num++] = next; 9351 end: 9352 if (!ctx->object) 9353 return len; 9354 action_rss_data = ctx->object; 9355 action_rss_data->conf.queue_num = i; 9356 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 9357 return len; 9358 } 9359 9360 /** Setup VXLAN encap configuration. */ 9361 static int 9362 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 9363 { 9364 /* Set up default configuration. */ 9365 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 9366 .conf = (struct rte_flow_action_vxlan_encap){ 9367 .definition = action_vxlan_encap_data->items, 9368 }, 9369 .items = { 9370 { 9371 .type = RTE_FLOW_ITEM_TYPE_ETH, 9372 .spec = &action_vxlan_encap_data->item_eth, 9373 .mask = &rte_flow_item_eth_mask, 9374 }, 9375 { 9376 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9377 .spec = &action_vxlan_encap_data->item_vlan, 9378 .mask = &rte_flow_item_vlan_mask, 9379 }, 9380 { 9381 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9382 .spec = &action_vxlan_encap_data->item_ipv4, 9383 .mask = &rte_flow_item_ipv4_mask, 9384 }, 9385 { 9386 .type = RTE_FLOW_ITEM_TYPE_UDP, 9387 .spec = &action_vxlan_encap_data->item_udp, 9388 .mask = &rte_flow_item_udp_mask, 9389 }, 9390 { 9391 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 9392 .spec = &action_vxlan_encap_data->item_vxlan, 9393 .mask = &rte_flow_item_vxlan_mask, 9394 }, 9395 { 9396 .type = RTE_FLOW_ITEM_TYPE_END, 9397 }, 9398 }, 9399 .item_eth.hdr.ether_type = 0, 9400 .item_vlan = { 9401 .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, 9402 .hdr.eth_proto = 0, 9403 }, 9404 .item_ipv4.hdr = { 9405 .src_addr = vxlan_encap_conf.ipv4_src, 9406 .dst_addr = vxlan_encap_conf.ipv4_dst, 9407 }, 9408 .item_udp.hdr = { 9409 .src_port = vxlan_encap_conf.udp_src, 9410 .dst_port = vxlan_encap_conf.udp_dst, 9411 }, 9412 .item_vxlan.hdr.flags = 0, 9413 }; 9414 memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9415 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9416 memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, 9417 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9418 if (!vxlan_encap_conf.select_ipv4) { 9419 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 9420 &vxlan_encap_conf.ipv6_src, 9421 sizeof(vxlan_encap_conf.ipv6_src)); 9422 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 9423 &vxlan_encap_conf.ipv6_dst, 9424 sizeof(vxlan_encap_conf.ipv6_dst)); 9425 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 9426 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9427 .spec = &action_vxlan_encap_data->item_ipv6, 9428 .mask = &rte_flow_item_ipv6_mask, 9429 }; 9430 } 9431 if (!vxlan_encap_conf.select_vlan) 9432 action_vxlan_encap_data->items[1].type = 9433 RTE_FLOW_ITEM_TYPE_VOID; 9434 if (vxlan_encap_conf.select_tos_ttl) { 9435 if (vxlan_encap_conf.select_ipv4) { 9436 static struct rte_flow_item_ipv4 ipv4_mask_tos; 9437 9438 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 9439 sizeof(ipv4_mask_tos)); 9440 ipv4_mask_tos.hdr.type_of_service = 0xff; 9441 ipv4_mask_tos.hdr.time_to_live = 0xff; 9442 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 9443 vxlan_encap_conf.ip_tos; 9444 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 9445 vxlan_encap_conf.ip_ttl; 9446 action_vxlan_encap_data->items[2].mask = 9447 &ipv4_mask_tos; 9448 } else { 9449 static struct rte_flow_item_ipv6 ipv6_mask_tos; 9450 9451 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 9452 sizeof(ipv6_mask_tos)); 9453 ipv6_mask_tos.hdr.vtc_flow |= 9454 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 9455 ipv6_mask_tos.hdr.hop_limits = 0xff; 9456 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 9457 rte_cpu_to_be_32 9458 ((uint32_t)vxlan_encap_conf.ip_tos << 9459 RTE_IPV6_HDR_TC_SHIFT); 9460 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 9461 vxlan_encap_conf.ip_ttl; 9462 action_vxlan_encap_data->items[2].mask = 9463 &ipv6_mask_tos; 9464 } 9465 } 9466 memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, 9467 RTE_DIM(vxlan_encap_conf.vni)); 9468 return 0; 9469 } 9470 9471 /** Parse VXLAN encap action. */ 9472 static int 9473 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 9474 const char *str, unsigned int len, 9475 void *buf, unsigned int size) 9476 { 9477 struct buffer *out = buf; 9478 struct rte_flow_action *action; 9479 struct action_vxlan_encap_data *action_vxlan_encap_data; 9480 int ret; 9481 9482 ret = parse_vc(ctx, token, str, len, buf, size); 9483 if (ret < 0) 9484 return ret; 9485 /* Nothing else to do if there is no buffer. */ 9486 if (!out) 9487 return ret; 9488 if (!out->args.vc.actions_n) 9489 return -1; 9490 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9491 /* Point to selected object. */ 9492 ctx->object = out->args.vc.data; 9493 ctx->objmask = NULL; 9494 action_vxlan_encap_data = ctx->object; 9495 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 9496 action->conf = &action_vxlan_encap_data->conf; 9497 return ret; 9498 } 9499 9500 /** Setup NVGRE encap configuration. */ 9501 static int 9502 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 9503 { 9504 /* Set up default configuration. */ 9505 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 9506 .conf = (struct rte_flow_action_nvgre_encap){ 9507 .definition = action_nvgre_encap_data->items, 9508 }, 9509 .items = { 9510 { 9511 .type = RTE_FLOW_ITEM_TYPE_ETH, 9512 .spec = &action_nvgre_encap_data->item_eth, 9513 .mask = &rte_flow_item_eth_mask, 9514 }, 9515 { 9516 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9517 .spec = &action_nvgre_encap_data->item_vlan, 9518 .mask = &rte_flow_item_vlan_mask, 9519 }, 9520 { 9521 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9522 .spec = &action_nvgre_encap_data->item_ipv4, 9523 .mask = &rte_flow_item_ipv4_mask, 9524 }, 9525 { 9526 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 9527 .spec = &action_nvgre_encap_data->item_nvgre, 9528 .mask = &rte_flow_item_nvgre_mask, 9529 }, 9530 { 9531 .type = RTE_FLOW_ITEM_TYPE_END, 9532 }, 9533 }, 9534 .item_eth.hdr.ether_type = 0, 9535 .item_vlan = { 9536 .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, 9537 .hdr.eth_proto = 0, 9538 }, 9539 .item_ipv4.hdr = { 9540 .src_addr = nvgre_encap_conf.ipv4_src, 9541 .dst_addr = nvgre_encap_conf.ipv4_dst, 9542 }, 9543 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 9544 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 9545 .item_nvgre.flow_id = 0, 9546 }; 9547 memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9548 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9549 memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, 9550 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9551 if (!nvgre_encap_conf.select_ipv4) { 9552 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 9553 &nvgre_encap_conf.ipv6_src, 9554 sizeof(nvgre_encap_conf.ipv6_src)); 9555 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 9556 &nvgre_encap_conf.ipv6_dst, 9557 sizeof(nvgre_encap_conf.ipv6_dst)); 9558 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 9559 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9560 .spec = &action_nvgre_encap_data->item_ipv6, 9561 .mask = &rte_flow_item_ipv6_mask, 9562 }; 9563 } 9564 if (!nvgre_encap_conf.select_vlan) 9565 action_nvgre_encap_data->items[1].type = 9566 RTE_FLOW_ITEM_TYPE_VOID; 9567 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 9568 RTE_DIM(nvgre_encap_conf.tni)); 9569 return 0; 9570 } 9571 9572 /** Parse NVGRE encap action. */ 9573 static int 9574 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 9575 const char *str, unsigned int len, 9576 void *buf, unsigned int size) 9577 { 9578 struct buffer *out = buf; 9579 struct rte_flow_action *action; 9580 struct action_nvgre_encap_data *action_nvgre_encap_data; 9581 int ret; 9582 9583 ret = parse_vc(ctx, token, str, len, buf, size); 9584 if (ret < 0) 9585 return ret; 9586 /* Nothing else to do if there is no buffer. */ 9587 if (!out) 9588 return ret; 9589 if (!out->args.vc.actions_n) 9590 return -1; 9591 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9592 /* Point to selected object. */ 9593 ctx->object = out->args.vc.data; 9594 ctx->objmask = NULL; 9595 action_nvgre_encap_data = ctx->object; 9596 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 9597 action->conf = &action_nvgre_encap_data->conf; 9598 return ret; 9599 } 9600 9601 /** Parse l2 encap action. */ 9602 static int 9603 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 9604 const char *str, unsigned int len, 9605 void *buf, unsigned int size) 9606 { 9607 struct buffer *out = buf; 9608 struct rte_flow_action *action; 9609 struct action_raw_encap_data *action_encap_data; 9610 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9611 struct rte_flow_item_vlan vlan = { 9612 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9613 .hdr.eth_proto = 0, 9614 }; 9615 uint8_t *header; 9616 int ret; 9617 9618 ret = parse_vc(ctx, token, str, len, buf, size); 9619 if (ret < 0) 9620 return ret; 9621 /* Nothing else to do if there is no buffer. */ 9622 if (!out) 9623 return ret; 9624 if (!out->args.vc.actions_n) 9625 return -1; 9626 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9627 /* Point to selected object. */ 9628 ctx->object = out->args.vc.data; 9629 ctx->objmask = NULL; 9630 /* Copy the headers to the buffer. */ 9631 action_encap_data = ctx->object; 9632 *action_encap_data = (struct action_raw_encap_data) { 9633 .conf = (struct rte_flow_action_raw_encap){ 9634 .data = action_encap_data->data, 9635 }, 9636 .data = {}, 9637 }; 9638 header = action_encap_data->data; 9639 if (l2_encap_conf.select_vlan) 9640 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9641 else if (l2_encap_conf.select_ipv4) 9642 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9643 else 9644 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9645 memcpy(eth.hdr.dst_addr.addr_bytes, 9646 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9647 memcpy(eth.hdr.src_addr.addr_bytes, 9648 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9649 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9650 header += sizeof(struct rte_ether_hdr); 9651 if (l2_encap_conf.select_vlan) { 9652 if (l2_encap_conf.select_ipv4) 9653 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9654 else 9655 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9656 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9657 header += sizeof(struct rte_vlan_hdr); 9658 } 9659 action_encap_data->conf.size = header - 9660 action_encap_data->data; 9661 action->conf = &action_encap_data->conf; 9662 return ret; 9663 } 9664 9665 /** Parse l2 decap action. */ 9666 static int 9667 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 9668 const char *str, unsigned int len, 9669 void *buf, unsigned int size) 9670 { 9671 struct buffer *out = buf; 9672 struct rte_flow_action *action; 9673 struct action_raw_decap_data *action_decap_data; 9674 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9675 struct rte_flow_item_vlan vlan = { 9676 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9677 .hdr.eth_proto = 0, 9678 }; 9679 uint8_t *header; 9680 int ret; 9681 9682 ret = parse_vc(ctx, token, str, len, buf, size); 9683 if (ret < 0) 9684 return ret; 9685 /* Nothing else to do if there is no buffer. */ 9686 if (!out) 9687 return ret; 9688 if (!out->args.vc.actions_n) 9689 return -1; 9690 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9691 /* Point to selected object. */ 9692 ctx->object = out->args.vc.data; 9693 ctx->objmask = NULL; 9694 /* Copy the headers to the buffer. */ 9695 action_decap_data = ctx->object; 9696 *action_decap_data = (struct action_raw_decap_data) { 9697 .conf = (struct rte_flow_action_raw_decap){ 9698 .data = action_decap_data->data, 9699 }, 9700 .data = {}, 9701 }; 9702 header = action_decap_data->data; 9703 if (l2_decap_conf.select_vlan) 9704 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9705 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9706 header += sizeof(struct rte_ether_hdr); 9707 if (l2_decap_conf.select_vlan) { 9708 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9709 header += sizeof(struct rte_vlan_hdr); 9710 } 9711 action_decap_data->conf.size = header - 9712 action_decap_data->data; 9713 action->conf = &action_decap_data->conf; 9714 return ret; 9715 } 9716 9717 #define ETHER_TYPE_MPLS_UNICAST 0x8847 9718 9719 /** Parse MPLSOGRE encap action. */ 9720 static int 9721 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 9722 const char *str, unsigned int len, 9723 void *buf, unsigned int size) 9724 { 9725 struct buffer *out = buf; 9726 struct rte_flow_action *action; 9727 struct action_raw_encap_data *action_encap_data; 9728 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9729 struct rte_flow_item_vlan vlan = { 9730 .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, 9731 .hdr.eth_proto = 0, 9732 }; 9733 struct rte_flow_item_ipv4 ipv4 = { 9734 .hdr = { 9735 .src_addr = mplsogre_encap_conf.ipv4_src, 9736 .dst_addr = mplsogre_encap_conf.ipv4_dst, 9737 .next_proto_id = IPPROTO_GRE, 9738 .version_ihl = RTE_IPV4_VHL_DEF, 9739 .time_to_live = IPDEFTTL, 9740 }, 9741 }; 9742 struct rte_flow_item_ipv6 ipv6 = { 9743 .hdr = { 9744 .proto = IPPROTO_GRE, 9745 .hop_limits = IPDEFTTL, 9746 }, 9747 }; 9748 struct rte_flow_item_gre gre = { 9749 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9750 }; 9751 struct rte_flow_item_mpls mpls = { 9752 .ttl = 0, 9753 }; 9754 uint8_t *header; 9755 int ret; 9756 9757 ret = parse_vc(ctx, token, str, len, buf, size); 9758 if (ret < 0) 9759 return ret; 9760 /* Nothing else to do if there is no buffer. */ 9761 if (!out) 9762 return ret; 9763 if (!out->args.vc.actions_n) 9764 return -1; 9765 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9766 /* Point to selected object. */ 9767 ctx->object = out->args.vc.data; 9768 ctx->objmask = NULL; 9769 /* Copy the headers to the buffer. */ 9770 action_encap_data = ctx->object; 9771 *action_encap_data = (struct action_raw_encap_data) { 9772 .conf = (struct rte_flow_action_raw_encap){ 9773 .data = action_encap_data->data, 9774 }, 9775 .data = {}, 9776 .preserve = {}, 9777 }; 9778 header = action_encap_data->data; 9779 if (mplsogre_encap_conf.select_vlan) 9780 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9781 else if (mplsogre_encap_conf.select_ipv4) 9782 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9783 else 9784 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9785 memcpy(eth.hdr.dst_addr.addr_bytes, 9786 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9787 memcpy(eth.hdr.src_addr.addr_bytes, 9788 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9789 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9790 header += sizeof(struct rte_ether_hdr); 9791 if (mplsogre_encap_conf.select_vlan) { 9792 if (mplsogre_encap_conf.select_ipv4) 9793 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9794 else 9795 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9796 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9797 header += sizeof(struct rte_vlan_hdr); 9798 } 9799 if (mplsogre_encap_conf.select_ipv4) { 9800 memcpy(header, &ipv4, sizeof(ipv4)); 9801 header += sizeof(ipv4); 9802 } else { 9803 memcpy(&ipv6.hdr.src_addr, 9804 &mplsogre_encap_conf.ipv6_src, 9805 sizeof(mplsogre_encap_conf.ipv6_src)); 9806 memcpy(&ipv6.hdr.dst_addr, 9807 &mplsogre_encap_conf.ipv6_dst, 9808 sizeof(mplsogre_encap_conf.ipv6_dst)); 9809 memcpy(header, &ipv6, sizeof(ipv6)); 9810 header += sizeof(ipv6); 9811 } 9812 memcpy(header, &gre, sizeof(gre)); 9813 header += sizeof(gre); 9814 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 9815 RTE_DIM(mplsogre_encap_conf.label)); 9816 mpls.label_tc_s[2] |= 0x1; 9817 memcpy(header, &mpls, sizeof(mpls)); 9818 header += sizeof(mpls); 9819 action_encap_data->conf.size = header - 9820 action_encap_data->data; 9821 action->conf = &action_encap_data->conf; 9822 return ret; 9823 } 9824 9825 /** Parse MPLSOGRE decap action. */ 9826 static int 9827 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 9828 const char *str, unsigned int len, 9829 void *buf, unsigned int size) 9830 { 9831 struct buffer *out = buf; 9832 struct rte_flow_action *action; 9833 struct action_raw_decap_data *action_decap_data; 9834 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9835 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9836 struct rte_flow_item_ipv4 ipv4 = { 9837 .hdr = { 9838 .next_proto_id = IPPROTO_GRE, 9839 }, 9840 }; 9841 struct rte_flow_item_ipv6 ipv6 = { 9842 .hdr = { 9843 .proto = IPPROTO_GRE, 9844 }, 9845 }; 9846 struct rte_flow_item_gre gre = { 9847 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9848 }; 9849 struct rte_flow_item_mpls mpls; 9850 uint8_t *header; 9851 int ret; 9852 9853 ret = parse_vc(ctx, token, str, len, buf, size); 9854 if (ret < 0) 9855 return ret; 9856 /* Nothing else to do if there is no buffer. */ 9857 if (!out) 9858 return ret; 9859 if (!out->args.vc.actions_n) 9860 return -1; 9861 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9862 /* Point to selected object. */ 9863 ctx->object = out->args.vc.data; 9864 ctx->objmask = NULL; 9865 /* Copy the headers to the buffer. */ 9866 action_decap_data = ctx->object; 9867 *action_decap_data = (struct action_raw_decap_data) { 9868 .conf = (struct rte_flow_action_raw_decap){ 9869 .data = action_decap_data->data, 9870 }, 9871 .data = {}, 9872 }; 9873 header = action_decap_data->data; 9874 if (mplsogre_decap_conf.select_vlan) 9875 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9876 else if (mplsogre_encap_conf.select_ipv4) 9877 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9878 else 9879 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9880 memcpy(eth.hdr.dst_addr.addr_bytes, 9881 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9882 memcpy(eth.hdr.src_addr.addr_bytes, 9883 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9884 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9885 header += sizeof(struct rte_ether_hdr); 9886 if (mplsogre_encap_conf.select_vlan) { 9887 if (mplsogre_encap_conf.select_ipv4) 9888 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9889 else 9890 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9891 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9892 header += sizeof(struct rte_vlan_hdr); 9893 } 9894 if (mplsogre_encap_conf.select_ipv4) { 9895 memcpy(header, &ipv4, sizeof(ipv4)); 9896 header += sizeof(ipv4); 9897 } else { 9898 memcpy(header, &ipv6, sizeof(ipv6)); 9899 header += sizeof(ipv6); 9900 } 9901 memcpy(header, &gre, sizeof(gre)); 9902 header += sizeof(gre); 9903 memset(&mpls, 0, sizeof(mpls)); 9904 memcpy(header, &mpls, sizeof(mpls)); 9905 header += sizeof(mpls); 9906 action_decap_data->conf.size = header - 9907 action_decap_data->data; 9908 action->conf = &action_decap_data->conf; 9909 return ret; 9910 } 9911 9912 /** Parse MPLSOUDP encap action. */ 9913 static int 9914 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 9915 const char *str, unsigned int len, 9916 void *buf, unsigned int size) 9917 { 9918 struct buffer *out = buf; 9919 struct rte_flow_action *action; 9920 struct action_raw_encap_data *action_encap_data; 9921 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9922 struct rte_flow_item_vlan vlan = { 9923 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9924 .hdr.eth_proto = 0, 9925 }; 9926 struct rte_flow_item_ipv4 ipv4 = { 9927 .hdr = { 9928 .src_addr = mplsoudp_encap_conf.ipv4_src, 9929 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 9930 .next_proto_id = IPPROTO_UDP, 9931 .version_ihl = RTE_IPV4_VHL_DEF, 9932 .time_to_live = IPDEFTTL, 9933 }, 9934 }; 9935 struct rte_flow_item_ipv6 ipv6 = { 9936 .hdr = { 9937 .proto = IPPROTO_UDP, 9938 .hop_limits = IPDEFTTL, 9939 }, 9940 }; 9941 struct rte_flow_item_udp udp = { 9942 .hdr = { 9943 .src_port = mplsoudp_encap_conf.udp_src, 9944 .dst_port = mplsoudp_encap_conf.udp_dst, 9945 }, 9946 }; 9947 struct rte_flow_item_mpls mpls; 9948 uint8_t *header; 9949 int ret; 9950 9951 ret = parse_vc(ctx, token, str, len, buf, size); 9952 if (ret < 0) 9953 return ret; 9954 /* Nothing else to do if there is no buffer. */ 9955 if (!out) 9956 return ret; 9957 if (!out->args.vc.actions_n) 9958 return -1; 9959 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9960 /* Point to selected object. */ 9961 ctx->object = out->args.vc.data; 9962 ctx->objmask = NULL; 9963 /* Copy the headers to the buffer. */ 9964 action_encap_data = ctx->object; 9965 *action_encap_data = (struct action_raw_encap_data) { 9966 .conf = (struct rte_flow_action_raw_encap){ 9967 .data = action_encap_data->data, 9968 }, 9969 .data = {}, 9970 .preserve = {}, 9971 }; 9972 header = action_encap_data->data; 9973 if (mplsoudp_encap_conf.select_vlan) 9974 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9975 else if (mplsoudp_encap_conf.select_ipv4) 9976 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9977 else 9978 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9979 memcpy(eth.hdr.dst_addr.addr_bytes, 9980 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9981 memcpy(eth.hdr.src_addr.addr_bytes, 9982 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9983 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9984 header += sizeof(struct rte_ether_hdr); 9985 if (mplsoudp_encap_conf.select_vlan) { 9986 if (mplsoudp_encap_conf.select_ipv4) 9987 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9988 else 9989 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9990 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9991 header += sizeof(struct rte_vlan_hdr); 9992 } 9993 if (mplsoudp_encap_conf.select_ipv4) { 9994 memcpy(header, &ipv4, sizeof(ipv4)); 9995 header += sizeof(ipv4); 9996 } else { 9997 memcpy(&ipv6.hdr.src_addr, 9998 &mplsoudp_encap_conf.ipv6_src, 9999 sizeof(mplsoudp_encap_conf.ipv6_src)); 10000 memcpy(&ipv6.hdr.dst_addr, 10001 &mplsoudp_encap_conf.ipv6_dst, 10002 sizeof(mplsoudp_encap_conf.ipv6_dst)); 10003 memcpy(header, &ipv6, sizeof(ipv6)); 10004 header += sizeof(ipv6); 10005 } 10006 memcpy(header, &udp, sizeof(udp)); 10007 header += sizeof(udp); 10008 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 10009 RTE_DIM(mplsoudp_encap_conf.label)); 10010 mpls.label_tc_s[2] |= 0x1; 10011 memcpy(header, &mpls, sizeof(mpls)); 10012 header += sizeof(mpls); 10013 action_encap_data->conf.size = header - 10014 action_encap_data->data; 10015 action->conf = &action_encap_data->conf; 10016 return ret; 10017 } 10018 10019 /** Parse MPLSOUDP decap action. */ 10020 static int 10021 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 10022 const char *str, unsigned int len, 10023 void *buf, unsigned int size) 10024 { 10025 struct buffer *out = buf; 10026 struct rte_flow_action *action; 10027 struct action_raw_decap_data *action_decap_data; 10028 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 10029 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 10030 struct rte_flow_item_ipv4 ipv4 = { 10031 .hdr = { 10032 .next_proto_id = IPPROTO_UDP, 10033 }, 10034 }; 10035 struct rte_flow_item_ipv6 ipv6 = { 10036 .hdr = { 10037 .proto = IPPROTO_UDP, 10038 }, 10039 }; 10040 struct rte_flow_item_udp udp = { 10041 .hdr = { 10042 .dst_port = rte_cpu_to_be_16(6635), 10043 }, 10044 }; 10045 struct rte_flow_item_mpls mpls; 10046 uint8_t *header; 10047 int ret; 10048 10049 ret = parse_vc(ctx, token, str, len, buf, size); 10050 if (ret < 0) 10051 return ret; 10052 /* Nothing else to do if there is no buffer. */ 10053 if (!out) 10054 return ret; 10055 if (!out->args.vc.actions_n) 10056 return -1; 10057 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10058 /* Point to selected object. */ 10059 ctx->object = out->args.vc.data; 10060 ctx->objmask = NULL; 10061 /* Copy the headers to the buffer. */ 10062 action_decap_data = ctx->object; 10063 *action_decap_data = (struct action_raw_decap_data) { 10064 .conf = (struct rte_flow_action_raw_decap){ 10065 .data = action_decap_data->data, 10066 }, 10067 .data = {}, 10068 }; 10069 header = action_decap_data->data; 10070 if (mplsoudp_decap_conf.select_vlan) 10071 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 10072 else if (mplsoudp_encap_conf.select_ipv4) 10073 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 10074 else 10075 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 10076 memcpy(eth.hdr.dst_addr.addr_bytes, 10077 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 10078 memcpy(eth.hdr.src_addr.addr_bytes, 10079 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 10080 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 10081 header += sizeof(struct rte_ether_hdr); 10082 if (mplsoudp_encap_conf.select_vlan) { 10083 if (mplsoudp_encap_conf.select_ipv4) 10084 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 10085 else 10086 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 10087 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 10088 header += sizeof(struct rte_vlan_hdr); 10089 } 10090 if (mplsoudp_encap_conf.select_ipv4) { 10091 memcpy(header, &ipv4, sizeof(ipv4)); 10092 header += sizeof(ipv4); 10093 } else { 10094 memcpy(header, &ipv6, sizeof(ipv6)); 10095 header += sizeof(ipv6); 10096 } 10097 memcpy(header, &udp, sizeof(udp)); 10098 header += sizeof(udp); 10099 memset(&mpls, 0, sizeof(mpls)); 10100 memcpy(header, &mpls, sizeof(mpls)); 10101 header += sizeof(mpls); 10102 action_decap_data->conf.size = header - 10103 action_decap_data->data; 10104 action->conf = &action_decap_data->conf; 10105 return ret; 10106 } 10107 10108 static int 10109 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 10110 const char *str, unsigned int len, void *buf, 10111 unsigned int size) 10112 { 10113 struct action_raw_decap_data *action_raw_decap_data; 10114 struct rte_flow_action *action; 10115 const struct arg *arg; 10116 struct buffer *out = buf; 10117 int ret; 10118 uint16_t idx; 10119 10120 RTE_SET_USED(token); 10121 RTE_SET_USED(buf); 10122 RTE_SET_USED(size); 10123 arg = ARGS_ENTRY_ARB_BOUNDED 10124 (offsetof(struct action_raw_decap_data, idx), 10125 sizeof(((struct action_raw_decap_data *)0)->idx), 10126 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10127 if (push_args(ctx, arg)) 10128 return -1; 10129 ret = parse_int(ctx, token, str, len, NULL, 0); 10130 if (ret < 0) { 10131 pop_args(ctx); 10132 return -1; 10133 } 10134 if (!ctx->object) 10135 return len; 10136 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10137 action_raw_decap_data = ctx->object; 10138 idx = action_raw_decap_data->idx; 10139 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 10140 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 10141 action->conf = &action_raw_decap_data->conf; 10142 return len; 10143 } 10144 10145 10146 static int 10147 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 10148 const char *str, unsigned int len, void *buf, 10149 unsigned int size) 10150 { 10151 struct action_raw_encap_data *action_raw_encap_data; 10152 struct rte_flow_action *action; 10153 const struct arg *arg; 10154 struct buffer *out = buf; 10155 int ret; 10156 uint16_t idx; 10157 10158 RTE_SET_USED(token); 10159 RTE_SET_USED(buf); 10160 RTE_SET_USED(size); 10161 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 10162 return -1; 10163 arg = ARGS_ENTRY_ARB_BOUNDED 10164 (offsetof(struct action_raw_encap_data, idx), 10165 sizeof(((struct action_raw_encap_data *)0)->idx), 10166 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10167 if (push_args(ctx, arg)) 10168 return -1; 10169 ret = parse_int(ctx, token, str, len, NULL, 0); 10170 if (ret < 0) { 10171 pop_args(ctx); 10172 return -1; 10173 } 10174 if (!ctx->object) 10175 return len; 10176 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10177 action_raw_encap_data = ctx->object; 10178 idx = action_raw_encap_data->idx; 10179 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 10180 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 10181 action_raw_encap_data->conf.preserve = NULL; 10182 action->conf = &action_raw_encap_data->conf; 10183 return len; 10184 } 10185 10186 static int 10187 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 10188 const char *str, unsigned int len, void *buf, 10189 unsigned int size) 10190 { 10191 struct buffer *out = buf; 10192 int ret; 10193 10194 ret = parse_vc(ctx, token, str, len, buf, size); 10195 if (ret < 0) 10196 return ret; 10197 /* Nothing else to do if there is no buffer. */ 10198 if (!out) 10199 return ret; 10200 if (!out->args.vc.actions_n) 10201 return -1; 10202 /* Point to selected object. */ 10203 ctx->object = out->args.vc.data; 10204 ctx->objmask = NULL; 10205 return ret; 10206 } 10207 10208 static int 10209 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 10210 const char *str, unsigned int len, void *buf, 10211 unsigned int size) 10212 { 10213 struct buffer *out = buf; 10214 struct rte_flow_action *action; 10215 struct action_raw_decap_data *action_raw_decap_data = NULL; 10216 int ret; 10217 10218 ret = parse_vc(ctx, token, str, len, buf, size); 10219 if (ret < 0) 10220 return ret; 10221 /* Nothing else to do if there is no buffer. */ 10222 if (!out) 10223 return ret; 10224 if (!out->args.vc.actions_n) 10225 return -1; 10226 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10227 /* Point to selected object. */ 10228 ctx->object = out->args.vc.data; 10229 ctx->objmask = NULL; 10230 /* Copy the headers to the buffer. */ 10231 action_raw_decap_data = ctx->object; 10232 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 10233 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 10234 action->conf = &action_raw_decap_data->conf; 10235 return ret; 10236 } 10237 10238 static int 10239 parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 10240 const char *str, unsigned int len, void *buf, 10241 unsigned int size) 10242 { 10243 struct buffer *out = buf; 10244 struct rte_flow_action *action; 10245 struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; 10246 int ret; 10247 10248 ret = parse_vc(ctx, token, str, len, buf, size); 10249 if (ret < 0) 10250 return ret; 10251 /* Nothing else to do if there is no buffer. */ 10252 if (!out) 10253 return ret; 10254 if (!out->args.vc.actions_n) 10255 return -1; 10256 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10257 /* Point to selected object. */ 10258 ctx->object = out->args.vc.data; 10259 ctx->objmask = NULL; 10260 /* Copy the headers to the buffer. */ 10261 ipv6_ext_remove_data = ctx->object; 10262 ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; 10263 action->conf = &ipv6_ext_remove_data->conf; 10264 return ret; 10265 } 10266 10267 static int 10268 parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, 10269 const char *str, unsigned int len, void *buf, 10270 unsigned int size) 10271 { 10272 struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; 10273 struct rte_flow_action *action; 10274 const struct arg *arg; 10275 struct buffer *out = buf; 10276 int ret; 10277 uint16_t idx; 10278 10279 RTE_SET_USED(token); 10280 RTE_SET_USED(buf); 10281 RTE_SET_USED(size); 10282 arg = ARGS_ENTRY_ARB_BOUNDED 10283 (offsetof(struct action_ipv6_ext_remove_data, idx), 10284 sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), 10285 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10286 if (push_args(ctx, arg)) 10287 return -1; 10288 ret = parse_int(ctx, token, str, len, NULL, 0); 10289 if (ret < 0) { 10290 pop_args(ctx); 10291 return -1; 10292 } 10293 if (!ctx->object) 10294 return len; 10295 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10296 action_ipv6_ext_remove_data = ctx->object; 10297 idx = action_ipv6_ext_remove_data->idx; 10298 action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; 10299 action->conf = &action_ipv6_ext_remove_data->conf; 10300 return len; 10301 } 10302 10303 static int 10304 parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 10305 const char *str, unsigned int len, void *buf, 10306 unsigned int size) 10307 { 10308 struct buffer *out = buf; 10309 struct rte_flow_action *action; 10310 struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; 10311 int ret; 10312 10313 ret = parse_vc(ctx, token, str, len, buf, size); 10314 if (ret < 0) 10315 return ret; 10316 /* Nothing else to do if there is no buffer. */ 10317 if (!out) 10318 return ret; 10319 if (!out->args.vc.actions_n) 10320 return -1; 10321 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10322 /* Point to selected object. */ 10323 ctx->object = out->args.vc.data; 10324 ctx->objmask = NULL; 10325 /* Copy the headers to the buffer. */ 10326 ipv6_ext_push_data = ctx->object; 10327 ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; 10328 ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; 10329 ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; 10330 action->conf = &ipv6_ext_push_data->conf; 10331 return ret; 10332 } 10333 10334 static int 10335 parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, 10336 const char *str, unsigned int len, void *buf, 10337 unsigned int size) 10338 { 10339 struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; 10340 struct rte_flow_action *action; 10341 const struct arg *arg; 10342 struct buffer *out = buf; 10343 int ret; 10344 uint16_t idx; 10345 10346 RTE_SET_USED(token); 10347 RTE_SET_USED(buf); 10348 RTE_SET_USED(size); 10349 arg = ARGS_ENTRY_ARB_BOUNDED 10350 (offsetof(struct action_ipv6_ext_push_data, idx), 10351 sizeof(((struct action_ipv6_ext_push_data *)0)->idx), 10352 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10353 if (push_args(ctx, arg)) 10354 return -1; 10355 ret = parse_int(ctx, token, str, len, NULL, 0); 10356 if (ret < 0) { 10357 pop_args(ctx); 10358 return -1; 10359 } 10360 if (!ctx->object) 10361 return len; 10362 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10363 action_ipv6_ext_push_data = ctx->object; 10364 idx = action_ipv6_ext_push_data->idx; 10365 action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; 10366 action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; 10367 action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; 10368 action->conf = &action_ipv6_ext_push_data->conf; 10369 return len; 10370 } 10371 10372 static int 10373 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 10374 const char *str, unsigned int len, void *buf, 10375 unsigned int size) 10376 { 10377 int ret; 10378 10379 ret = parse_vc(ctx, token, str, len, buf, size); 10380 if (ret < 0) 10381 return ret; 10382 ret = rte_flow_dynf_metadata_register(); 10383 if (ret < 0) 10384 return -1; 10385 return len; 10386 } 10387 10388 static int 10389 parse_vc_action_sample(struct context *ctx, const struct token *token, 10390 const char *str, unsigned int len, void *buf, 10391 unsigned int size) 10392 { 10393 struct buffer *out = buf; 10394 struct rte_flow_action *action; 10395 struct action_sample_data *action_sample_data = NULL; 10396 static struct rte_flow_action end_action = { 10397 RTE_FLOW_ACTION_TYPE_END, 0 10398 }; 10399 int ret; 10400 10401 ret = parse_vc(ctx, token, str, len, buf, size); 10402 if (ret < 0) 10403 return ret; 10404 /* Nothing else to do if there is no buffer. */ 10405 if (!out) 10406 return ret; 10407 if (!out->args.vc.actions_n) 10408 return -1; 10409 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10410 /* Point to selected object. */ 10411 ctx->object = out->args.vc.data; 10412 ctx->objmask = NULL; 10413 /* Copy the headers to the buffer. */ 10414 action_sample_data = ctx->object; 10415 action_sample_data->conf.actions = &end_action; 10416 action->conf = &action_sample_data->conf; 10417 return ret; 10418 } 10419 10420 static int 10421 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 10422 const char *str, unsigned int len, void *buf, 10423 unsigned int size) 10424 { 10425 struct action_sample_data *action_sample_data; 10426 struct rte_flow_action *action; 10427 const struct arg *arg; 10428 struct buffer *out = buf; 10429 int ret; 10430 uint16_t idx; 10431 10432 RTE_SET_USED(token); 10433 RTE_SET_USED(buf); 10434 RTE_SET_USED(size); 10435 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 10436 return -1; 10437 arg = ARGS_ENTRY_ARB_BOUNDED 10438 (offsetof(struct action_sample_data, idx), 10439 sizeof(((struct action_sample_data *)0)->idx), 10440 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 10441 if (push_args(ctx, arg)) 10442 return -1; 10443 ret = parse_int(ctx, token, str, len, NULL, 0); 10444 if (ret < 0) { 10445 pop_args(ctx); 10446 return -1; 10447 } 10448 if (!ctx->object) 10449 return len; 10450 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10451 action_sample_data = ctx->object; 10452 idx = action_sample_data->idx; 10453 action_sample_data->conf.actions = raw_sample_confs[idx].data; 10454 action->conf = &action_sample_data->conf; 10455 return len; 10456 } 10457 10458 /** Parse operation for modify_field command. */ 10459 static int 10460 parse_vc_modify_field_op(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_OP_VALUE) 10471 return -1; 10472 for (i = 0; modify_field_ops[i]; ++i) 10473 if (!strcmp_partial(modify_field_ops[i], str, len)) 10474 break; 10475 if (!modify_field_ops[i]) 10476 return -1; 10477 if (!ctx->object) 10478 return len; 10479 action_modify_field = ctx->object; 10480 action_modify_field->operation = (enum rte_flow_modify_op)i; 10481 return len; 10482 } 10483 10484 /** Parse id for modify_field command. */ 10485 static int 10486 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 10487 const char *str, unsigned int len, void *buf, 10488 unsigned int size) 10489 { 10490 struct rte_flow_action_modify_field *action_modify_field; 10491 unsigned int i; 10492 10493 (void)token; 10494 (void)buf; 10495 (void)size; 10496 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 10497 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 10498 return -1; 10499 for (i = 0; flow_field_ids[i]; ++i) 10500 if (!strcmp_partial(flow_field_ids[i], str, len)) 10501 break; 10502 if (!flow_field_ids[i]) 10503 return -1; 10504 if (!ctx->object) 10505 return len; 10506 action_modify_field = ctx->object; 10507 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 10508 action_modify_field->dst.field = (enum rte_flow_field_id)i; 10509 else 10510 action_modify_field->src.field = (enum rte_flow_field_id)i; 10511 return len; 10512 } 10513 10514 /** Parse level for modify_field command. */ 10515 static int 10516 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 10517 const char *str, unsigned int len, void *buf, 10518 unsigned int size) 10519 { 10520 struct rte_flow_action_modify_field *action; 10521 struct flex_item *fp = NULL; 10522 uint32_t val; 10523 struct buffer *out = buf; 10524 char *end; 10525 10526 (void)token; 10527 (void)size; 10528 if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10529 ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) 10530 return -1; 10531 if (!ctx->object) 10532 return len; 10533 action = ctx->object; 10534 errno = 0; 10535 val = strtoumax(str, &end, 0); 10536 if (errno || (size_t)(end - str) != len) 10537 return -1; 10538 /* No need to validate action template mask value */ 10539 if (out->args.vc.masks) { 10540 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) 10541 action->dst.level = val; 10542 else 10543 action->src.level = val; 10544 return len; 10545 } 10546 if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10547 action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || 10548 (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && 10549 action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 10550 if (val >= FLEX_MAX_PARSERS_NUM) { 10551 printf("Bad flex item handle\n"); 10552 return -1; 10553 } 10554 fp = flex_items[ctx->port][val]; 10555 if (!fp) { 10556 printf("Bad flex item handle\n"); 10557 return -1; 10558 } 10559 } 10560 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { 10561 if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) 10562 action->dst.level = val; 10563 else 10564 action->dst.flex_handle = fp->flex_handle; 10565 } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { 10566 if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) 10567 action->src.level = val; 10568 else 10569 action->src.flex_handle = fp->flex_handle; 10570 } 10571 return len; 10572 } 10573 10574 /** Parse the conntrack update, not a rte_flow_action. */ 10575 static int 10576 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 10577 const char *str, unsigned int len, void *buf, 10578 unsigned int size) 10579 { 10580 struct buffer *out = buf; 10581 struct rte_flow_modify_conntrack *ct_modify = NULL; 10582 10583 (void)size; 10584 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 10585 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 10586 return -1; 10587 /* Token name must match. */ 10588 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10589 return -1; 10590 /* Nothing else to do if there is no buffer. */ 10591 if (!out) 10592 return len; 10593 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 10594 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 10595 ct_modify->new_ct.is_original_dir = 10596 conntrack_context.is_original_dir; 10597 ct_modify->direction = 1; 10598 } else { 10599 uint32_t old_dir; 10600 10601 old_dir = ct_modify->new_ct.is_original_dir; 10602 memcpy(&ct_modify->new_ct, &conntrack_context, 10603 sizeof(conntrack_context)); 10604 ct_modify->new_ct.is_original_dir = old_dir; 10605 ct_modify->state = 1; 10606 } 10607 return len; 10608 } 10609 10610 /** Parse tokens for destroy command. */ 10611 static int 10612 parse_destroy(struct context *ctx, const struct token *token, 10613 const char *str, unsigned int len, 10614 void *buf, unsigned int size) 10615 { 10616 struct buffer *out = buf; 10617 10618 /* Token name must match. */ 10619 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10620 return -1; 10621 /* Nothing else to do if there is no buffer. */ 10622 if (!out) 10623 return len; 10624 if (!out->command) { 10625 if (ctx->curr != DESTROY) 10626 return -1; 10627 if (sizeof(*out) > size) 10628 return -1; 10629 out->command = ctx->curr; 10630 ctx->objdata = 0; 10631 ctx->object = out; 10632 ctx->objmask = NULL; 10633 out->args.destroy.rule = 10634 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10635 sizeof(double)); 10636 return len; 10637 } 10638 if (ctx->curr == DESTROY_IS_USER_ID) { 10639 out->args.destroy.is_user_id = true; 10640 return len; 10641 } 10642 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 10643 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 10644 return -1; 10645 ctx->objdata = 0; 10646 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 10647 ctx->objmask = NULL; 10648 return len; 10649 } 10650 10651 /** Parse tokens for flush command. */ 10652 static int 10653 parse_flush(struct context *ctx, const struct token *token, 10654 const char *str, unsigned int len, 10655 void *buf, unsigned int size) 10656 { 10657 struct buffer *out = buf; 10658 10659 /* Token name must match. */ 10660 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10661 return -1; 10662 /* Nothing else to do if there is no buffer. */ 10663 if (!out) 10664 return len; 10665 if (!out->command) { 10666 if (ctx->curr != FLUSH) 10667 return -1; 10668 if (sizeof(*out) > size) 10669 return -1; 10670 out->command = ctx->curr; 10671 ctx->objdata = 0; 10672 ctx->object = out; 10673 ctx->objmask = NULL; 10674 } 10675 return len; 10676 } 10677 10678 /** Parse tokens for dump command. */ 10679 static int 10680 parse_dump(struct context *ctx, const struct token *token, 10681 const char *str, unsigned int len, 10682 void *buf, unsigned int size) 10683 { 10684 struct buffer *out = buf; 10685 10686 /* Token name must match. */ 10687 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10688 return -1; 10689 /* Nothing else to do if there is no buffer. */ 10690 if (!out) 10691 return len; 10692 if (!out->command) { 10693 if (ctx->curr != DUMP) 10694 return -1; 10695 if (sizeof(*out) > size) 10696 return -1; 10697 out->command = ctx->curr; 10698 ctx->objdata = 0; 10699 ctx->object = out; 10700 ctx->objmask = NULL; 10701 return len; 10702 } 10703 switch (ctx->curr) { 10704 case DUMP_ALL: 10705 case DUMP_ONE: 10706 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 10707 out->command = ctx->curr; 10708 ctx->objdata = 0; 10709 ctx->object = out; 10710 ctx->objmask = NULL; 10711 return len; 10712 case DUMP_IS_USER_ID: 10713 out->args.dump.is_user_id = true; 10714 return len; 10715 default: 10716 return -1; 10717 } 10718 } 10719 10720 /** Parse tokens for query command. */ 10721 static int 10722 parse_query(struct context *ctx, const struct token *token, 10723 const char *str, unsigned int len, 10724 void *buf, unsigned int size) 10725 { 10726 struct buffer *out = buf; 10727 10728 /* Token name must match. */ 10729 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10730 return -1; 10731 /* Nothing else to do if there is no buffer. */ 10732 if (!out) 10733 return len; 10734 if (!out->command) { 10735 if (ctx->curr != QUERY) 10736 return -1; 10737 if (sizeof(*out) > size) 10738 return -1; 10739 out->command = ctx->curr; 10740 ctx->objdata = 0; 10741 ctx->object = out; 10742 ctx->objmask = NULL; 10743 } 10744 if (ctx->curr == QUERY_IS_USER_ID) { 10745 out->args.query.is_user_id = true; 10746 return len; 10747 } 10748 return len; 10749 } 10750 10751 /** Parse action names. */ 10752 static int 10753 parse_action(struct context *ctx, const struct token *token, 10754 const char *str, unsigned int len, 10755 void *buf, unsigned int size) 10756 { 10757 struct buffer *out = buf; 10758 const struct arg *arg = pop_args(ctx); 10759 unsigned int i; 10760 10761 (void)size; 10762 /* Argument is expected. */ 10763 if (!arg) 10764 return -1; 10765 /* Parse action name. */ 10766 for (i = 0; next_action[i]; ++i) { 10767 const struct parse_action_priv *priv; 10768 10769 token = &token_list[next_action[i]]; 10770 if (strcmp_partial(token->name, str, len)) 10771 continue; 10772 priv = token->priv; 10773 if (!priv) 10774 goto error; 10775 if (out) 10776 memcpy((uint8_t *)ctx->object + arg->offset, 10777 &priv->type, 10778 arg->size); 10779 return len; 10780 } 10781 error: 10782 push_args(ctx, arg); 10783 return -1; 10784 } 10785 10786 /** Parse tokens for list command. */ 10787 static int 10788 parse_list(struct context *ctx, const struct token *token, 10789 const char *str, unsigned int len, 10790 void *buf, unsigned int size) 10791 { 10792 struct buffer *out = buf; 10793 10794 /* Token name must match. */ 10795 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10796 return -1; 10797 /* Nothing else to do if there is no buffer. */ 10798 if (!out) 10799 return len; 10800 if (!out->command) { 10801 if (ctx->curr != LIST) 10802 return -1; 10803 if (sizeof(*out) > size) 10804 return -1; 10805 out->command = ctx->curr; 10806 ctx->objdata = 0; 10807 ctx->object = out; 10808 ctx->objmask = NULL; 10809 out->args.list.group = 10810 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10811 sizeof(double)); 10812 return len; 10813 } 10814 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 10815 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 10816 return -1; 10817 ctx->objdata = 0; 10818 ctx->object = out->args.list.group + out->args.list.group_n++; 10819 ctx->objmask = NULL; 10820 return len; 10821 } 10822 10823 /** Parse tokens for list all aged flows command. */ 10824 static int 10825 parse_aged(struct context *ctx, const struct token *token, 10826 const char *str, unsigned int len, 10827 void *buf, unsigned int size) 10828 { 10829 struct buffer *out = buf; 10830 10831 /* Token name must match. */ 10832 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10833 return -1; 10834 /* Nothing else to do if there is no buffer. */ 10835 if (!out) 10836 return len; 10837 if (!out->command || out->command == QUEUE) { 10838 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 10839 return -1; 10840 if (sizeof(*out) > size) 10841 return -1; 10842 out->command = ctx->curr; 10843 ctx->objdata = 0; 10844 ctx->object = out; 10845 ctx->objmask = NULL; 10846 } 10847 if (ctx->curr == AGED_DESTROY) 10848 out->args.aged.destroy = 1; 10849 return len; 10850 } 10851 10852 /** Parse tokens for isolate command. */ 10853 static int 10854 parse_isolate(struct context *ctx, const struct token *token, 10855 const char *str, unsigned int len, 10856 void *buf, unsigned int size) 10857 { 10858 struct buffer *out = buf; 10859 10860 /* Token name must match. */ 10861 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10862 return -1; 10863 /* Nothing else to do if there is no buffer. */ 10864 if (!out) 10865 return len; 10866 if (!out->command) { 10867 if (ctx->curr != ISOLATE) 10868 return -1; 10869 if (sizeof(*out) > size) 10870 return -1; 10871 out->command = ctx->curr; 10872 ctx->objdata = 0; 10873 ctx->object = out; 10874 ctx->objmask = NULL; 10875 } 10876 return len; 10877 } 10878 10879 /** Parse tokens for info/configure command. */ 10880 static int 10881 parse_configure(struct context *ctx, const struct token *token, 10882 const char *str, unsigned int len, 10883 void *buf, unsigned int size) 10884 { 10885 struct buffer *out = buf; 10886 10887 /* Token name must match. */ 10888 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10889 return -1; 10890 /* Nothing else to do if there is no buffer. */ 10891 if (!out) 10892 return len; 10893 if (!out->command) { 10894 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 10895 return -1; 10896 if (sizeof(*out) > size) 10897 return -1; 10898 out->command = ctx->curr; 10899 ctx->objdata = 0; 10900 ctx->object = out; 10901 ctx->objmask = NULL; 10902 } 10903 return len; 10904 } 10905 10906 /** Parse tokens for template create command. */ 10907 static int 10908 parse_template(struct context *ctx, const struct token *token, 10909 const char *str, unsigned int len, 10910 void *buf, unsigned int size) 10911 { 10912 struct buffer *out = buf; 10913 10914 /* Token name must match. */ 10915 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10916 return -1; 10917 /* Nothing else to do if there is no buffer. */ 10918 if (!out) 10919 return len; 10920 if (!out->command) { 10921 if (ctx->curr != PATTERN_TEMPLATE && 10922 ctx->curr != ACTIONS_TEMPLATE) 10923 return -1; 10924 if (sizeof(*out) > size) 10925 return -1; 10926 out->command = ctx->curr; 10927 ctx->objdata = 0; 10928 ctx->object = out; 10929 ctx->objmask = NULL; 10930 out->args.vc.data = (uint8_t *)out + size; 10931 return len; 10932 } 10933 switch (ctx->curr) { 10934 case PATTERN_TEMPLATE_CREATE: 10935 out->args.vc.pattern = 10936 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10937 sizeof(double)); 10938 out->args.vc.pat_templ_id = UINT32_MAX; 10939 out->command = ctx->curr; 10940 ctx->objdata = 0; 10941 ctx->object = out; 10942 ctx->objmask = NULL; 10943 return len; 10944 case PATTERN_TEMPLATE_EGRESS: 10945 out->args.vc.attr.egress = 1; 10946 return len; 10947 case PATTERN_TEMPLATE_INGRESS: 10948 out->args.vc.attr.ingress = 1; 10949 return len; 10950 case PATTERN_TEMPLATE_TRANSFER: 10951 out->args.vc.attr.transfer = 1; 10952 return len; 10953 case ACTIONS_TEMPLATE_CREATE: 10954 out->args.vc.act_templ_id = UINT32_MAX; 10955 out->command = ctx->curr; 10956 ctx->objdata = 0; 10957 ctx->object = out; 10958 ctx->objmask = NULL; 10959 return len; 10960 case ACTIONS_TEMPLATE_SPEC: 10961 out->args.vc.actions = 10962 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10963 sizeof(double)); 10964 ctx->object = out->args.vc.actions; 10965 ctx->objmask = NULL; 10966 return len; 10967 case ACTIONS_TEMPLATE_MASK: 10968 out->args.vc.masks = 10969 (void *)RTE_ALIGN_CEIL((uintptr_t) 10970 (out->args.vc.actions + 10971 out->args.vc.actions_n), 10972 sizeof(double)); 10973 ctx->object = out->args.vc.masks; 10974 ctx->objmask = NULL; 10975 return len; 10976 case ACTIONS_TEMPLATE_EGRESS: 10977 out->args.vc.attr.egress = 1; 10978 return len; 10979 case ACTIONS_TEMPLATE_INGRESS: 10980 out->args.vc.attr.ingress = 1; 10981 return len; 10982 case ACTIONS_TEMPLATE_TRANSFER: 10983 out->args.vc.attr.transfer = 1; 10984 return len; 10985 default: 10986 return -1; 10987 } 10988 } 10989 10990 /** Parse tokens for template destroy command. */ 10991 static int 10992 parse_template_destroy(struct context *ctx, const struct token *token, 10993 const char *str, unsigned int len, 10994 void *buf, unsigned int size) 10995 { 10996 struct buffer *out = buf; 10997 uint32_t *template_id; 10998 10999 /* Token name must match. */ 11000 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11001 return -1; 11002 /* Nothing else to do if there is no buffer. */ 11003 if (!out) 11004 return len; 11005 if (!out->command || 11006 out->command == PATTERN_TEMPLATE || 11007 out->command == ACTIONS_TEMPLATE) { 11008 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 11009 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 11010 return -1; 11011 if (sizeof(*out) > size) 11012 return -1; 11013 out->command = ctx->curr; 11014 ctx->objdata = 0; 11015 ctx->object = out; 11016 ctx->objmask = NULL; 11017 out->args.templ_destroy.template_id = 11018 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11019 sizeof(double)); 11020 return len; 11021 } 11022 template_id = out->args.templ_destroy.template_id 11023 + out->args.templ_destroy.template_id_n++; 11024 if ((uint8_t *)template_id > (uint8_t *)out + size) 11025 return -1; 11026 ctx->objdata = 0; 11027 ctx->object = template_id; 11028 ctx->objmask = NULL; 11029 return len; 11030 } 11031 11032 /** Parse tokens for table create command. */ 11033 static int 11034 parse_table(struct context *ctx, const struct token *token, 11035 const char *str, unsigned int len, 11036 void *buf, unsigned int size) 11037 { 11038 struct buffer *out = buf; 11039 uint32_t *template_id; 11040 11041 /* Token name must match. */ 11042 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11043 return -1; 11044 /* Nothing else to do if there is no buffer. */ 11045 if (!out) 11046 return len; 11047 if (!out->command) { 11048 if (ctx->curr != TABLE) 11049 return -1; 11050 if (sizeof(*out) > size) 11051 return -1; 11052 out->command = ctx->curr; 11053 ctx->objdata = 0; 11054 ctx->object = out; 11055 ctx->objmask = NULL; 11056 return len; 11057 } 11058 switch (ctx->curr) { 11059 case TABLE_CREATE: 11060 case TABLE_RESIZE: 11061 out->command = ctx->curr; 11062 ctx->objdata = 0; 11063 ctx->object = out; 11064 ctx->objmask = NULL; 11065 out->args.table.id = UINT32_MAX; 11066 return len; 11067 case TABLE_PATTERN_TEMPLATE: 11068 out->args.table.pat_templ_id = 11069 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11070 sizeof(double)); 11071 template_id = out->args.table.pat_templ_id 11072 + out->args.table.pat_templ_id_n++; 11073 if ((uint8_t *)template_id > (uint8_t *)out + size) 11074 return -1; 11075 ctx->objdata = 0; 11076 ctx->object = template_id; 11077 ctx->objmask = NULL; 11078 return len; 11079 case TABLE_ACTIONS_TEMPLATE: 11080 out->args.table.act_templ_id = 11081 (void *)RTE_ALIGN_CEIL((uintptr_t) 11082 (out->args.table.pat_templ_id + 11083 out->args.table.pat_templ_id_n), 11084 sizeof(double)); 11085 template_id = out->args.table.act_templ_id 11086 + out->args.table.act_templ_id_n++; 11087 if ((uint8_t *)template_id > (uint8_t *)out + size) 11088 return -1; 11089 ctx->objdata = 0; 11090 ctx->object = template_id; 11091 ctx->objmask = NULL; 11092 return len; 11093 case TABLE_INGRESS: 11094 out->args.table.attr.flow_attr.ingress = 1; 11095 return len; 11096 case TABLE_EGRESS: 11097 out->args.table.attr.flow_attr.egress = 1; 11098 return len; 11099 case TABLE_TRANSFER: 11100 out->args.table.attr.flow_attr.transfer = 1; 11101 return len; 11102 case TABLE_TRANSFER_WIRE_ORIG: 11103 if (!out->args.table.attr.flow_attr.transfer) 11104 return -1; 11105 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; 11106 return len; 11107 case TABLE_TRANSFER_VPORT_ORIG: 11108 if (!out->args.table.attr.flow_attr.transfer) 11109 return -1; 11110 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; 11111 return len; 11112 case TABLE_RESIZABLE: 11113 out->args.table.attr.specialize |= 11114 RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE; 11115 return len; 11116 case TABLE_RULES_NUMBER: 11117 ctx->objdata = 0; 11118 ctx->object = out; 11119 ctx->objmask = NULL; 11120 return len; 11121 case TABLE_RESIZE_ID: 11122 case TABLE_RESIZE_RULES_NUMBER: 11123 return len; 11124 default: 11125 return -1; 11126 } 11127 } 11128 11129 /** Parse tokens for table destroy command. */ 11130 static int 11131 parse_table_destroy(struct context *ctx, const struct token *token, 11132 const char *str, unsigned int len, 11133 void *buf, unsigned int size) 11134 { 11135 struct buffer *out = buf; 11136 uint32_t *table_id; 11137 11138 /* Token name must match. */ 11139 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11140 return -1; 11141 /* Nothing else to do if there is no buffer. */ 11142 if (!out) 11143 return len; 11144 if (!out->command || out->command == TABLE) { 11145 if (ctx->curr != TABLE_DESTROY && 11146 ctx->curr != TABLE_RESIZE_COMPLETE) 11147 return -1; 11148 if (sizeof(*out) > size) 11149 return -1; 11150 out->command = ctx->curr; 11151 ctx->objdata = 0; 11152 ctx->object = out; 11153 ctx->objmask = NULL; 11154 out->args.table_destroy.table_id = 11155 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11156 sizeof(double)); 11157 return len; 11158 } 11159 table_id = out->args.table_destroy.table_id 11160 + out->args.table_destroy.table_id_n++; 11161 if ((uint8_t *)table_id > (uint8_t *)out + size) 11162 return -1; 11163 ctx->objdata = 0; 11164 ctx->object = table_id; 11165 ctx->objmask = NULL; 11166 return len; 11167 } 11168 11169 /** Parse tokens for queue create commands. */ 11170 static int 11171 parse_qo(struct context *ctx, const struct token *token, 11172 const char *str, unsigned int len, 11173 void *buf, unsigned int size) 11174 { 11175 struct buffer *out = buf; 11176 11177 /* Token name must match. */ 11178 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11179 return -1; 11180 /* Nothing else to do if there is no buffer. */ 11181 if (!out) 11182 return len; 11183 if (!out->command) { 11184 if (ctx->curr != QUEUE) 11185 return -1; 11186 if (sizeof(*out) > size) 11187 return -1; 11188 out->command = ctx->curr; 11189 ctx->objdata = 0; 11190 ctx->object = out; 11191 ctx->objmask = NULL; 11192 out->args.vc.data = (uint8_t *)out + size; 11193 return len; 11194 } 11195 switch (ctx->curr) { 11196 case QUEUE_CREATE: 11197 case QUEUE_UPDATE: 11198 out->command = ctx->curr; 11199 ctx->objdata = 0; 11200 ctx->object = out; 11201 ctx->objmask = NULL; 11202 out->args.vc.rule_id = UINT32_MAX; 11203 return len; 11204 case QUEUE_TEMPLATE_TABLE: 11205 case QUEUE_PATTERN_TEMPLATE: 11206 case QUEUE_ACTIONS_TEMPLATE: 11207 case QUEUE_CREATE_POSTPONE: 11208 case QUEUE_RULE_ID: 11209 case QUEUE_UPDATE_ID: 11210 return len; 11211 case ITEM_PATTERN: 11212 out->args.vc.pattern = 11213 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11214 sizeof(double)); 11215 ctx->object = out->args.vc.pattern; 11216 ctx->objmask = NULL; 11217 return len; 11218 case ACTIONS: 11219 out->args.vc.actions = 11220 (void *)RTE_ALIGN_CEIL((uintptr_t) 11221 (out->args.vc.pattern + 11222 out->args.vc.pattern_n), 11223 sizeof(double)); 11224 ctx->object = out->args.vc.actions; 11225 ctx->objmask = NULL; 11226 return len; 11227 default: 11228 return -1; 11229 } 11230 } 11231 11232 /** Parse tokens for queue destroy command. */ 11233 static int 11234 parse_qo_destroy(struct context *ctx, const struct token *token, 11235 const char *str, unsigned int len, 11236 void *buf, unsigned int size) 11237 { 11238 struct buffer *out = buf; 11239 uint64_t *flow_id; 11240 11241 /* Token name must match. */ 11242 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11243 return -1; 11244 /* Nothing else to do if there is no buffer. */ 11245 if (!out) 11246 return len; 11247 if (!out->command || out->command == QUEUE) { 11248 if (ctx->curr != QUEUE_DESTROY && 11249 ctx->curr != QUEUE_FLOW_UPDATE_RESIZED) 11250 return -1; 11251 if (sizeof(*out) > size) 11252 return -1; 11253 out->command = ctx->curr; 11254 ctx->objdata = 0; 11255 ctx->object = out; 11256 ctx->objmask = NULL; 11257 out->args.destroy.rule = 11258 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11259 sizeof(double)); 11260 return len; 11261 } 11262 switch (ctx->curr) { 11263 case QUEUE_DESTROY_ID: 11264 flow_id = out->args.destroy.rule 11265 + out->args.destroy.rule_n++; 11266 if ((uint8_t *)flow_id > (uint8_t *)out + size) 11267 return -1; 11268 ctx->objdata = 0; 11269 ctx->object = flow_id; 11270 ctx->objmask = NULL; 11271 return len; 11272 case QUEUE_DESTROY_POSTPONE: 11273 return len; 11274 default: 11275 return -1; 11276 } 11277 } 11278 11279 /** Parse tokens for push queue command. */ 11280 static int 11281 parse_push(struct context *ctx, const struct token *token, 11282 const char *str, unsigned int len, 11283 void *buf, unsigned int size) 11284 { 11285 struct buffer *out = buf; 11286 11287 /* Token name must match. */ 11288 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11289 return -1; 11290 /* Nothing else to do if there is no buffer. */ 11291 if (!out) 11292 return len; 11293 if (!out->command) { 11294 if (ctx->curr != PUSH) 11295 return -1; 11296 if (sizeof(*out) > size) 11297 return -1; 11298 out->command = ctx->curr; 11299 ctx->objdata = 0; 11300 ctx->object = out; 11301 ctx->objmask = NULL; 11302 out->args.vc.data = (uint8_t *)out + size; 11303 } 11304 return len; 11305 } 11306 11307 /** Parse tokens for pull command. */ 11308 static int 11309 parse_pull(struct context *ctx, const struct token *token, 11310 const char *str, unsigned int len, 11311 void *buf, unsigned int size) 11312 { 11313 struct buffer *out = buf; 11314 11315 /* Token name must match. */ 11316 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11317 return -1; 11318 /* Nothing else to do if there is no buffer. */ 11319 if (!out) 11320 return len; 11321 if (!out->command) { 11322 if (ctx->curr != PULL) 11323 return -1; 11324 if (sizeof(*out) > size) 11325 return -1; 11326 out->command = ctx->curr; 11327 ctx->objdata = 0; 11328 ctx->object = out; 11329 ctx->objmask = NULL; 11330 out->args.vc.data = (uint8_t *)out + size; 11331 } 11332 return len; 11333 } 11334 11335 /** Parse tokens for hash calculation commands. */ 11336 static int 11337 parse_hash(struct context *ctx, const struct token *token, 11338 const char *str, unsigned int len, 11339 void *buf, unsigned int size) 11340 { 11341 struct buffer *out = buf; 11342 11343 /* Token name must match. */ 11344 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11345 return -1; 11346 /* Nothing else to do if there is no buffer. */ 11347 if (!out) 11348 return len; 11349 if (!out->command) { 11350 if (ctx->curr != HASH) 11351 return -1; 11352 if (sizeof(*out) > size) 11353 return -1; 11354 out->command = ctx->curr; 11355 ctx->objdata = 0; 11356 ctx->object = out; 11357 ctx->objmask = NULL; 11358 out->args.vc.data = (uint8_t *)out + size; 11359 return len; 11360 } 11361 switch (ctx->curr) { 11362 case HASH_CALC_TABLE: 11363 case HASH_CALC_PATTERN_INDEX: 11364 return len; 11365 case ITEM_PATTERN: 11366 out->args.vc.pattern = 11367 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11368 sizeof(double)); 11369 ctx->object = out->args.vc.pattern; 11370 ctx->objmask = NULL; 11371 return len; 11372 case HASH_CALC_ENCAP: 11373 out->args.vc.encap_hash = 1; 11374 return len; 11375 case ENCAP_HASH_FIELD_SRC_PORT: 11376 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT; 11377 return len; 11378 case ENCAP_HASH_FIELD_GRE_FLOW_ID: 11379 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID; 11380 return len; 11381 default: 11382 return -1; 11383 } 11384 } 11385 11386 static int 11387 parse_group(struct context *ctx, const struct token *token, 11388 const char *str, unsigned int len, 11389 void *buf, unsigned int size) 11390 { 11391 struct buffer *out = buf; 11392 11393 /* Token name must match. */ 11394 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11395 return -1; 11396 /* Nothing else to do if there is no buffer. */ 11397 if (!out) 11398 return len; 11399 if (!out->command) { 11400 if (ctx->curr != FLOW_GROUP) 11401 return -1; 11402 if (sizeof(*out) > size) 11403 return -1; 11404 out->command = ctx->curr; 11405 ctx->objdata = 0; 11406 ctx->object = out; 11407 ctx->objmask = NULL; 11408 out->args.vc.data = (uint8_t *)out + size; 11409 return len; 11410 } 11411 switch (ctx->curr) { 11412 case GROUP_INGRESS: 11413 out->args.vc.attr.ingress = 1; 11414 return len; 11415 case GROUP_EGRESS: 11416 out->args.vc.attr.egress = 1; 11417 return len; 11418 case GROUP_TRANSFER: 11419 out->args.vc.attr.transfer = 1; 11420 return len; 11421 case GROUP_SET_MISS_ACTIONS: 11422 out->command = ctx->curr; 11423 ctx->objdata = 0; 11424 ctx->object = out; 11425 ctx->objmask = NULL; 11426 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11427 sizeof(double)); 11428 return len; 11429 default: 11430 return -1; 11431 } 11432 } 11433 11434 static int 11435 parse_flex(struct context *ctx, const struct token *token, 11436 const char *str, unsigned int len, 11437 void *buf, unsigned int size) 11438 { 11439 struct buffer *out = buf; 11440 11441 /* Token name must match. */ 11442 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11443 return -1; 11444 /* Nothing else to do if there is no buffer. */ 11445 if (!out) 11446 return len; 11447 if (out->command == ZERO) { 11448 if (ctx->curr != FLEX) 11449 return -1; 11450 if (sizeof(*out) > size) 11451 return -1; 11452 out->command = ctx->curr; 11453 ctx->objdata = 0; 11454 ctx->object = out; 11455 ctx->objmask = NULL; 11456 } else { 11457 switch (ctx->curr) { 11458 default: 11459 break; 11460 case FLEX_ITEM_CREATE: 11461 case FLEX_ITEM_DESTROY: 11462 out->command = ctx->curr; 11463 break; 11464 } 11465 } 11466 11467 return len; 11468 } 11469 11470 static int 11471 parse_tunnel(struct context *ctx, const struct token *token, 11472 const char *str, unsigned int len, 11473 void *buf, unsigned int size) 11474 { 11475 struct buffer *out = buf; 11476 11477 /* Token name must match. */ 11478 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11479 return -1; 11480 /* Nothing else to do if there is no buffer. */ 11481 if (!out) 11482 return len; 11483 if (!out->command) { 11484 if (ctx->curr != TUNNEL) 11485 return -1; 11486 if (sizeof(*out) > size) 11487 return -1; 11488 out->command = ctx->curr; 11489 ctx->objdata = 0; 11490 ctx->object = out; 11491 ctx->objmask = NULL; 11492 } else { 11493 switch (ctx->curr) { 11494 default: 11495 break; 11496 case TUNNEL_CREATE: 11497 case TUNNEL_DESTROY: 11498 case TUNNEL_LIST: 11499 out->command = ctx->curr; 11500 break; 11501 case TUNNEL_CREATE_TYPE: 11502 case TUNNEL_DESTROY_ID: 11503 ctx->object = &out->args.vc.tunnel_ops; 11504 break; 11505 } 11506 } 11507 11508 return len; 11509 } 11510 11511 /** 11512 * Parse signed/unsigned integers 8 to 64-bit long. 11513 * 11514 * Last argument (ctx->args) is retrieved to determine integer type and 11515 * storage location. 11516 */ 11517 static int 11518 parse_int(struct context *ctx, const struct token *token, 11519 const char *str, unsigned int len, 11520 void *buf, unsigned int size) 11521 { 11522 const struct arg *arg = pop_args(ctx); 11523 uintmax_t u; 11524 char *end; 11525 11526 (void)token; 11527 /* Argument is expected. */ 11528 if (!arg) 11529 return -1; 11530 errno = 0; 11531 u = arg->sign ? 11532 (uintmax_t)strtoimax(str, &end, 0) : 11533 strtoumax(str, &end, 0); 11534 if (errno || (size_t)(end - str) != len) 11535 goto error; 11536 if (arg->bounded && 11537 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 11538 (intmax_t)u > (intmax_t)arg->max)) || 11539 (!arg->sign && (u < arg->min || u > arg->max)))) 11540 goto error; 11541 if (!ctx->object) 11542 return len; 11543 if (arg->mask) { 11544 if (!arg_entry_bf_fill(ctx->object, u, arg) || 11545 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 11546 goto error; 11547 return len; 11548 } 11549 buf = (uint8_t *)ctx->object + arg->offset; 11550 size = arg->size; 11551 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 11552 return -1; 11553 objmask: 11554 switch (size) { 11555 case sizeof(uint8_t): 11556 *(uint8_t *)buf = u; 11557 break; 11558 case sizeof(uint16_t): 11559 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 11560 break; 11561 case sizeof(uint8_t [3]): 11562 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 11563 if (!arg->hton) { 11564 ((uint8_t *)buf)[0] = u; 11565 ((uint8_t *)buf)[1] = u >> 8; 11566 ((uint8_t *)buf)[2] = u >> 16; 11567 break; 11568 } 11569 #endif 11570 ((uint8_t *)buf)[0] = u >> 16; 11571 ((uint8_t *)buf)[1] = u >> 8; 11572 ((uint8_t *)buf)[2] = u; 11573 break; 11574 case sizeof(uint32_t): 11575 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 11576 break; 11577 case sizeof(uint64_t): 11578 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 11579 break; 11580 default: 11581 goto error; 11582 } 11583 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 11584 u = -1; 11585 buf = (uint8_t *)ctx->objmask + arg->offset; 11586 goto objmask; 11587 } 11588 return len; 11589 error: 11590 push_args(ctx, arg); 11591 return -1; 11592 } 11593 11594 /** 11595 * Parse a string. 11596 * 11597 * Three arguments (ctx->args) are retrieved from the stack to store data, 11598 * its actual length and address (in that order). 11599 */ 11600 static int 11601 parse_string(struct context *ctx, const struct token *token, 11602 const char *str, unsigned int len, 11603 void *buf, unsigned int size) 11604 { 11605 const struct arg *arg_data = pop_args(ctx); 11606 const struct arg *arg_len = pop_args(ctx); 11607 const struct arg *arg_addr = pop_args(ctx); 11608 char tmp[16]; /* Ought to be enough. */ 11609 int ret; 11610 11611 /* Arguments are expected. */ 11612 if (!arg_data) 11613 return -1; 11614 if (!arg_len) { 11615 push_args(ctx, arg_data); 11616 return -1; 11617 } 11618 if (!arg_addr) { 11619 push_args(ctx, arg_len); 11620 push_args(ctx, arg_data); 11621 return -1; 11622 } 11623 size = arg_data->size; 11624 /* Bit-mask fill is not supported. */ 11625 if (arg_data->mask || size < len) 11626 goto error; 11627 if (!ctx->object) 11628 return len; 11629 /* Let parse_int() fill length information first. */ 11630 ret = snprintf(tmp, sizeof(tmp), "%u", len); 11631 if (ret < 0) 11632 goto error; 11633 push_args(ctx, arg_len); 11634 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11635 if (ret < 0) { 11636 pop_args(ctx); 11637 goto error; 11638 } 11639 buf = (uint8_t *)ctx->object + arg_data->offset; 11640 /* Output buffer is not necessarily NUL-terminated. */ 11641 memcpy(buf, str, len); 11642 memset((uint8_t *)buf + len, 0x00, size - len); 11643 if (ctx->objmask) 11644 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11645 /* Save address if requested. */ 11646 if (arg_addr->size) { 11647 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11648 (void *[]){ 11649 (uint8_t *)ctx->object + arg_data->offset 11650 }, 11651 arg_addr->size); 11652 if (ctx->objmask) 11653 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11654 (void *[]){ 11655 (uint8_t *)ctx->objmask + arg_data->offset 11656 }, 11657 arg_addr->size); 11658 } 11659 return len; 11660 error: 11661 push_args(ctx, arg_addr); 11662 push_args(ctx, arg_len); 11663 push_args(ctx, arg_data); 11664 return -1; 11665 } 11666 11667 static int 11668 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 11669 { 11670 const uint8_t *head = dst; 11671 uint32_t left; 11672 11673 if (*size == 0) 11674 return -1; 11675 11676 left = *size; 11677 11678 /* Convert chars to bytes */ 11679 while (left) { 11680 char tmp[3], *end = tmp; 11681 uint32_t read_lim = left & 1 ? 1 : 2; 11682 11683 snprintf(tmp, read_lim + 1, "%s", src); 11684 *dst = strtoul(tmp, &end, 16); 11685 if (*end) { 11686 *dst = 0; 11687 *size = (uint32_t)(dst - head); 11688 return -1; 11689 } 11690 left -= read_lim; 11691 src += read_lim; 11692 dst++; 11693 } 11694 *dst = 0; 11695 *size = (uint32_t)(dst - head); 11696 return 0; 11697 } 11698 11699 static int 11700 parse_hex(struct context *ctx, const struct token *token, 11701 const char *str, unsigned int len, 11702 void *buf, unsigned int size) 11703 { 11704 const struct arg *arg_data = pop_args(ctx); 11705 const struct arg *arg_len = pop_args(ctx); 11706 const struct arg *arg_addr = pop_args(ctx); 11707 char tmp[16]; /* Ought to be enough. */ 11708 int ret; 11709 unsigned int hexlen = len; 11710 unsigned int length = 256; 11711 uint8_t hex_tmp[length]; 11712 11713 /* Arguments are expected. */ 11714 if (!arg_data) 11715 return -1; 11716 if (!arg_len) { 11717 push_args(ctx, arg_data); 11718 return -1; 11719 } 11720 if (!arg_addr) { 11721 push_args(ctx, arg_len); 11722 push_args(ctx, arg_data); 11723 return -1; 11724 } 11725 size = arg_data->size; 11726 /* Bit-mask fill is not supported. */ 11727 if (arg_data->mask) 11728 goto error; 11729 if (!ctx->object) 11730 return len; 11731 11732 /* translate bytes string to array. */ 11733 if (str[0] == '0' && ((str[1] == 'x') || 11734 (str[1] == 'X'))) { 11735 str += 2; 11736 hexlen -= 2; 11737 } 11738 if (hexlen > length) 11739 goto error; 11740 ret = parse_hex_string(str, hex_tmp, &hexlen); 11741 if (ret < 0) 11742 goto error; 11743 /* Check the converted binary fits into data buffer. */ 11744 if (hexlen > size) 11745 goto error; 11746 /* Let parse_int() fill length information first. */ 11747 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 11748 if (ret < 0) 11749 goto error; 11750 /* Save length if requested. */ 11751 if (arg_len->size) { 11752 push_args(ctx, arg_len); 11753 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11754 if (ret < 0) { 11755 pop_args(ctx); 11756 goto error; 11757 } 11758 } 11759 buf = (uint8_t *)ctx->object + arg_data->offset; 11760 /* Output buffer is not necessarily NUL-terminated. */ 11761 memcpy(buf, hex_tmp, hexlen); 11762 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 11763 if (ctx->objmask) 11764 memset((uint8_t *)ctx->objmask + arg_data->offset, 11765 0xff, hexlen); 11766 /* Save address if requested. */ 11767 if (arg_addr->size) { 11768 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11769 (void *[]){ 11770 (uint8_t *)ctx->object + arg_data->offset 11771 }, 11772 arg_addr->size); 11773 if (ctx->objmask) 11774 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11775 (void *[]){ 11776 (uint8_t *)ctx->objmask + arg_data->offset 11777 }, 11778 arg_addr->size); 11779 } 11780 return len; 11781 error: 11782 push_args(ctx, arg_addr); 11783 push_args(ctx, arg_len); 11784 push_args(ctx, arg_data); 11785 return -1; 11786 11787 } 11788 11789 /** 11790 * Parse a zero-ended string. 11791 */ 11792 static int 11793 parse_string0(struct context *ctx, const struct token *token __rte_unused, 11794 const char *str, unsigned int len, 11795 void *buf, unsigned int size) 11796 { 11797 const struct arg *arg_data = pop_args(ctx); 11798 11799 /* Arguments are expected. */ 11800 if (!arg_data) 11801 return -1; 11802 size = arg_data->size; 11803 /* Bit-mask fill is not supported. */ 11804 if (arg_data->mask || size < len + 1) 11805 goto error; 11806 if (!ctx->object) 11807 return len; 11808 buf = (uint8_t *)ctx->object + arg_data->offset; 11809 strncpy(buf, str, len); 11810 if (ctx->objmask) 11811 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11812 return len; 11813 error: 11814 push_args(ctx, arg_data); 11815 return -1; 11816 } 11817 11818 /** 11819 * Parse a MAC address. 11820 * 11821 * Last argument (ctx->args) is retrieved to determine storage size and 11822 * location. 11823 */ 11824 static int 11825 parse_mac_addr(struct context *ctx, const struct token *token, 11826 const char *str, unsigned int len, 11827 void *buf, unsigned int size) 11828 { 11829 const struct arg *arg = pop_args(ctx); 11830 struct rte_ether_addr tmp; 11831 int ret; 11832 11833 (void)token; 11834 /* Argument is expected. */ 11835 if (!arg) 11836 return -1; 11837 size = arg->size; 11838 /* Bit-mask fill is not supported. */ 11839 if (arg->mask || size != sizeof(tmp)) 11840 goto error; 11841 /* Only network endian is supported. */ 11842 if (!arg->hton) 11843 goto error; 11844 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 11845 if (ret < 0 || (unsigned int)ret != len) 11846 goto error; 11847 if (!ctx->object) 11848 return len; 11849 buf = (uint8_t *)ctx->object + arg->offset; 11850 memcpy(buf, &tmp, size); 11851 if (ctx->objmask) 11852 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11853 return len; 11854 error: 11855 push_args(ctx, arg); 11856 return -1; 11857 } 11858 11859 /** 11860 * Parse an IPv4 address. 11861 * 11862 * Last argument (ctx->args) is retrieved to determine storage size and 11863 * location. 11864 */ 11865 static int 11866 parse_ipv4_addr(struct context *ctx, const struct token *token, 11867 const char *str, unsigned int len, 11868 void *buf, unsigned int size) 11869 { 11870 const struct arg *arg = pop_args(ctx); 11871 char str2[len + 1]; 11872 struct in_addr tmp; 11873 int ret; 11874 11875 /* Argument is expected. */ 11876 if (!arg) 11877 return -1; 11878 size = arg->size; 11879 /* Bit-mask fill is not supported. */ 11880 if (arg->mask || size != sizeof(tmp)) 11881 goto error; 11882 /* Only network endian is supported. */ 11883 if (!arg->hton) 11884 goto error; 11885 memcpy(str2, str, len); 11886 str2[len] = '\0'; 11887 ret = inet_pton(AF_INET, str2, &tmp); 11888 if (ret != 1) { 11889 /* Attempt integer parsing. */ 11890 push_args(ctx, arg); 11891 return parse_int(ctx, token, str, len, buf, size); 11892 } 11893 if (!ctx->object) 11894 return len; 11895 buf = (uint8_t *)ctx->object + arg->offset; 11896 memcpy(buf, &tmp, size); 11897 if (ctx->objmask) 11898 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11899 return len; 11900 error: 11901 push_args(ctx, arg); 11902 return -1; 11903 } 11904 11905 /** 11906 * Parse an IPv6 address. 11907 * 11908 * Last argument (ctx->args) is retrieved to determine storage size and 11909 * location. 11910 */ 11911 static int 11912 parse_ipv6_addr(struct context *ctx, const struct token *token, 11913 const char *str, unsigned int len, 11914 void *buf, unsigned int size) 11915 { 11916 const struct arg *arg = pop_args(ctx); 11917 char str2[len + 1]; 11918 struct rte_ipv6_addr tmp; 11919 int ret; 11920 11921 (void)token; 11922 /* Argument is expected. */ 11923 if (!arg) 11924 return -1; 11925 size = arg->size; 11926 /* Bit-mask fill is not supported. */ 11927 if (arg->mask || size != sizeof(tmp)) 11928 goto error; 11929 /* Only network endian is supported. */ 11930 if (!arg->hton) 11931 goto error; 11932 memcpy(str2, str, len); 11933 str2[len] = '\0'; 11934 ret = inet_pton(AF_INET6, str2, &tmp); 11935 if (ret != 1) 11936 goto error; 11937 if (!ctx->object) 11938 return len; 11939 buf = (uint8_t *)ctx->object + arg->offset; 11940 memcpy(buf, &tmp, size); 11941 if (ctx->objmask) 11942 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11943 return len; 11944 error: 11945 push_args(ctx, arg); 11946 return -1; 11947 } 11948 11949 /** Boolean values (even indices stand for false). */ 11950 static const char *const boolean_name[] = { 11951 "0", "1", 11952 "false", "true", 11953 "no", "yes", 11954 "N", "Y", 11955 "off", "on", 11956 NULL, 11957 }; 11958 11959 /** 11960 * Parse a boolean value. 11961 * 11962 * Last argument (ctx->args) is retrieved to determine storage size and 11963 * location. 11964 */ 11965 static int 11966 parse_boolean(struct context *ctx, const struct token *token, 11967 const char *str, unsigned int len, 11968 void *buf, unsigned int size) 11969 { 11970 const struct arg *arg = pop_args(ctx); 11971 unsigned int i; 11972 int ret; 11973 11974 /* Argument is expected. */ 11975 if (!arg) 11976 return -1; 11977 for (i = 0; boolean_name[i]; ++i) 11978 if (!strcmp_partial(boolean_name[i], str, len)) 11979 break; 11980 /* Process token as integer. */ 11981 if (boolean_name[i]) 11982 str = i & 1 ? "1" : "0"; 11983 push_args(ctx, arg); 11984 ret = parse_int(ctx, token, str, strlen(str), buf, size); 11985 return ret > 0 ? (int)len : ret; 11986 } 11987 11988 /** Parse port and update context. */ 11989 static int 11990 parse_port(struct context *ctx, const struct token *token, 11991 const char *str, unsigned int len, 11992 void *buf, unsigned int size) 11993 { 11994 struct buffer *out = &(struct buffer){ .port = 0 }; 11995 int ret; 11996 11997 if (buf) 11998 out = buf; 11999 else { 12000 ctx->objdata = 0; 12001 ctx->object = out; 12002 ctx->objmask = NULL; 12003 size = sizeof(*out); 12004 } 12005 ret = parse_int(ctx, token, str, len, out, size); 12006 if (ret >= 0) 12007 ctx->port = out->port; 12008 if (!buf) 12009 ctx->object = NULL; 12010 return ret; 12011 } 12012 12013 /** Parse tokens for shared indirect actions. */ 12014 static int 12015 parse_ia_port(struct context *ctx, const struct token *token, 12016 const char *str, unsigned int len, 12017 void *buf, unsigned int size) 12018 { 12019 struct rte_flow_action *action = ctx->object; 12020 uint32_t id; 12021 int ret; 12022 12023 (void)buf; 12024 (void)size; 12025 ctx->objdata = 0; 12026 ctx->object = &id; 12027 ctx->objmask = NULL; 12028 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12029 ctx->object = action; 12030 if (ret != (int)len) 12031 return ret; 12032 /* set indirect action */ 12033 if (action) 12034 action->conf = (void *)(uintptr_t)id; 12035 return ret; 12036 } 12037 12038 static int 12039 parse_ia_id2ptr(struct context *ctx, const struct token *token, 12040 const char *str, unsigned int len, 12041 void *buf, unsigned int size) 12042 { 12043 struct rte_flow_action *action = ctx->object; 12044 uint32_t id; 12045 int ret; 12046 12047 (void)buf; 12048 (void)size; 12049 ctx->objdata = 0; 12050 ctx->object = &id; 12051 ctx->objmask = NULL; 12052 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12053 ctx->object = action; 12054 if (ret != (int)len) 12055 return ret; 12056 /* set indirect action */ 12057 if (action) { 12058 portid_t port_id = ctx->port; 12059 if (ctx->prev == INDIRECT_ACTION_PORT) 12060 port_id = (portid_t)(uintptr_t)action->conf; 12061 action->conf = port_action_handle_get_by_id(port_id, id); 12062 ret = (action->conf) ? ret : -1; 12063 } 12064 return ret; 12065 } 12066 12067 static int 12068 parse_indlst_id2ptr(struct context *ctx, const struct token *token, 12069 const char *str, unsigned int len, 12070 __rte_unused void *buf, __rte_unused unsigned int size) 12071 { 12072 struct rte_flow_action *action = ctx->object; 12073 struct rte_flow_action_indirect_list *action_conf; 12074 const struct indlst_conf *indlst_conf; 12075 uint32_t id; 12076 int ret; 12077 12078 ctx->objdata = 0; 12079 ctx->object = &id; 12080 ctx->objmask = NULL; 12081 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12082 ctx->object = action; 12083 if (ret != (int)len) 12084 return ret; 12085 12086 /* set handle and conf */ 12087 if (action) { 12088 action_conf = (void *)(uintptr_t)action->conf; 12089 action_conf->conf = NULL; 12090 switch (ctx->curr) { 12091 case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: 12092 action_conf->handle = (typeof(action_conf->handle)) 12093 port_action_handle_get_by_id(ctx->port, id); 12094 if (!action_conf->handle) { 12095 printf("no indirect list handle for id %u\n", id); 12096 return -1; 12097 } 12098 break; 12099 case INDIRECT_LIST_ACTION_ID2PTR_CONF: 12100 indlst_conf = indirect_action_list_conf_get(id); 12101 if (!indlst_conf) 12102 return -1; 12103 action_conf->conf = (const void **)indlst_conf->conf; 12104 break; 12105 default: 12106 break; 12107 } 12108 } 12109 return ret; 12110 } 12111 12112 static int 12113 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 12114 const char *str, unsigned int len, 12115 void *buf, unsigned int size) 12116 { 12117 struct rte_flow_action *action = ctx->object; 12118 struct rte_flow_action_meter_mark *meter; 12119 struct rte_flow_meter_profile *profile = NULL; 12120 uint32_t id = 0; 12121 int ret; 12122 12123 (void)buf; 12124 (void)size; 12125 ctx->objdata = 0; 12126 ctx->object = &id; 12127 ctx->objmask = NULL; 12128 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12129 ctx->object = action; 12130 if (ret != (int)len) 12131 return ret; 12132 /* set meter profile */ 12133 if (action) { 12134 meter = (struct rte_flow_action_meter_mark *) 12135 (uintptr_t)(action->conf); 12136 profile = port_meter_profile_get_by_id(ctx->port, id); 12137 meter->profile = profile; 12138 ret = (profile) ? ret : -1; 12139 } 12140 return ret; 12141 } 12142 12143 static int 12144 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 12145 const char *str, unsigned int len, 12146 void *buf, unsigned int size) 12147 { 12148 struct rte_flow_action *action = ctx->object; 12149 struct rte_flow_action_meter_mark *meter; 12150 struct rte_flow_meter_policy *policy = NULL; 12151 uint32_t id = 0; 12152 int ret; 12153 12154 (void)buf; 12155 (void)size; 12156 ctx->objdata = 0; 12157 ctx->object = &id; 12158 ctx->objmask = NULL; 12159 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12160 ctx->object = action; 12161 if (ret != (int)len) 12162 return ret; 12163 /* set meter policy */ 12164 if (action) { 12165 meter = (struct rte_flow_action_meter_mark *) 12166 (uintptr_t)(action->conf); 12167 policy = port_meter_policy_get_by_id(ctx->port, id); 12168 meter->policy = policy; 12169 ret = (policy) ? ret : -1; 12170 } 12171 return ret; 12172 } 12173 12174 /** Parse set command, initialize output buffer for subsequent tokens. */ 12175 static int 12176 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 12177 const char *str, unsigned int len, 12178 void *buf, unsigned int size) 12179 { 12180 struct buffer *out = buf; 12181 12182 /* Token name must match. */ 12183 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12184 return -1; 12185 /* Nothing else to do if there is no buffer. */ 12186 if (!out) 12187 return len; 12188 /* Make sure buffer is large enough. */ 12189 if (size < sizeof(*out)) 12190 return -1; 12191 ctx->objdata = 0; 12192 ctx->objmask = NULL; 12193 ctx->object = out; 12194 if (!out->command) 12195 return -1; 12196 out->command = ctx->curr; 12197 /* For encap/decap we need is pattern */ 12198 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12199 sizeof(double)); 12200 return len; 12201 } 12202 12203 /** Parse set command, initialize output buffer for subsequent tokens. */ 12204 static int 12205 parse_set_sample_action(struct context *ctx, const struct token *token, 12206 const char *str, unsigned int len, 12207 void *buf, unsigned int size) 12208 { 12209 struct buffer *out = buf; 12210 12211 /* Token name must match. */ 12212 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12213 return -1; 12214 /* Nothing else to do if there is no buffer. */ 12215 if (!out) 12216 return len; 12217 /* Make sure buffer is large enough. */ 12218 if (size < sizeof(*out)) 12219 return -1; 12220 ctx->objdata = 0; 12221 ctx->objmask = NULL; 12222 ctx->object = out; 12223 if (!out->command) 12224 return -1; 12225 out->command = ctx->curr; 12226 /* For sampler we need is actions */ 12227 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12228 sizeof(double)); 12229 return len; 12230 } 12231 12232 /** Parse set command, initialize output buffer for subsequent tokens. */ 12233 static int 12234 parse_set_ipv6_ext_action(struct context *ctx, const struct token *token, 12235 const char *str, unsigned int len, 12236 void *buf, unsigned int size) 12237 { 12238 struct buffer *out = buf; 12239 12240 /* Token name must match. */ 12241 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12242 return -1; 12243 /* Nothing else to do if there is no buffer. */ 12244 if (!out) 12245 return len; 12246 /* Make sure buffer is large enough. */ 12247 if (size < sizeof(*out)) 12248 return -1; 12249 ctx->objdata = 0; 12250 ctx->objmask = NULL; 12251 ctx->object = out; 12252 if (!out->command) 12253 return -1; 12254 out->command = ctx->curr; 12255 /* For ipv6_ext_push/remove we need is pattern */ 12256 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12257 sizeof(double)); 12258 return len; 12259 } 12260 12261 /** 12262 * Parse set raw_encap/raw_decap command, 12263 * initialize output buffer for subsequent tokens. 12264 */ 12265 static int 12266 parse_set_init(struct context *ctx, const struct token *token, 12267 const char *str, unsigned int len, 12268 void *buf, unsigned int size) 12269 { 12270 struct buffer *out = buf; 12271 12272 /* Token name must match. */ 12273 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12274 return -1; 12275 /* Nothing else to do if there is no buffer. */ 12276 if (!out) 12277 return len; 12278 /* Make sure buffer is large enough. */ 12279 if (size < sizeof(*out)) 12280 return -1; 12281 /* Initialize buffer. */ 12282 memset(out, 0x00, sizeof(*out)); 12283 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 12284 ctx->objdata = 0; 12285 ctx->object = out; 12286 ctx->objmask = NULL; 12287 if (!out->command) { 12288 if (ctx->curr != SET) 12289 return -1; 12290 if (sizeof(*out) > size) 12291 return -1; 12292 out->command = ctx->curr; 12293 out->args.vc.data = (uint8_t *)out + size; 12294 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12295 sizeof(double)); 12296 } 12297 return len; 12298 } 12299 12300 /* 12301 * Replace testpmd handles in a flex flow item with real values. 12302 */ 12303 static int 12304 parse_flex_handle(struct context *ctx, const struct token *token, 12305 const char *str, unsigned int len, 12306 void *buf, unsigned int size) 12307 { 12308 struct rte_flow_item_flex *spec, *mask; 12309 const struct rte_flow_item_flex *src_spec, *src_mask; 12310 const struct arg *arg = pop_args(ctx); 12311 uint32_t offset; 12312 uint16_t handle; 12313 int ret; 12314 12315 if (!arg) { 12316 printf("Bad environment\n"); 12317 return -1; 12318 } 12319 offset = arg->offset; 12320 push_args(ctx, arg); 12321 ret = parse_int(ctx, token, str, len, buf, size); 12322 if (ret <= 0 || !ctx->object) 12323 return ret; 12324 if (ctx->port >= RTE_MAX_ETHPORTS) { 12325 printf("Bad port\n"); 12326 return -1; 12327 } 12328 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 12329 const struct flex_item *fp; 12330 spec = ctx->object; 12331 handle = (uint16_t)(uintptr_t)spec->handle; 12332 if (handle >= FLEX_MAX_PARSERS_NUM) { 12333 printf("Bad flex item handle\n"); 12334 return -1; 12335 } 12336 fp = flex_items[ctx->port][handle]; 12337 if (!fp) { 12338 printf("Bad flex item handle\n"); 12339 return -1; 12340 } 12341 spec->handle = fp->flex_handle; 12342 mask = spec + 2; /* spec, last, mask */ 12343 mask->handle = fp->flex_handle; 12344 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 12345 handle = (uint16_t)(uintptr_t) 12346 ((struct rte_flow_item_flex *)ctx->object)->pattern; 12347 if (handle >= FLEX_MAX_PATTERNS_NUM) { 12348 printf("Bad pattern handle\n"); 12349 return -1; 12350 } 12351 src_spec = &flex_patterns[handle].spec; 12352 src_mask = &flex_patterns[handle].mask; 12353 spec = ctx->object; 12354 mask = spec + 2; /* spec, last, mask */ 12355 /* fill flow rule spec and mask parameters */ 12356 spec->length = src_spec->length; 12357 spec->pattern = src_spec->pattern; 12358 mask->length = src_mask->length; 12359 mask->pattern = src_mask->pattern; 12360 } else { 12361 printf("Bad arguments - unknown flex item offset\n"); 12362 return -1; 12363 } 12364 return ret; 12365 } 12366 12367 /** Parse Meter color name */ 12368 static int 12369 parse_meter_color(struct context *ctx, const struct token *token, 12370 const char *str, unsigned int len, void *buf, 12371 unsigned int size) 12372 { 12373 struct rte_flow_item_meter_color *meter_color; 12374 unsigned int i; 12375 12376 (void)token; 12377 (void)buf; 12378 (void)size; 12379 for (i = 0; meter_colors[i]; ++i) 12380 if (!strcmp_partial(meter_colors[i], str, len)) 12381 break; 12382 if (!meter_colors[i]) 12383 return -1; 12384 if (!ctx->object) 12385 return len; 12386 meter_color = ctx->object; 12387 meter_color->color = (enum rte_color)i; 12388 return len; 12389 } 12390 12391 /** Parse Insertion Table Type name */ 12392 static int 12393 parse_insertion_table_type(struct context *ctx, const struct token *token, 12394 const char *str, unsigned int len, void *buf, 12395 unsigned int size) 12396 { 12397 const struct arg *arg = pop_args(ctx); 12398 unsigned int i; 12399 char tmp[2]; 12400 int ret; 12401 12402 (void)size; 12403 /* Argument is expected. */ 12404 if (!arg) 12405 return -1; 12406 for (i = 0; table_insertion_types[i]; ++i) 12407 if (!strcmp_partial(table_insertion_types[i], str, len)) 12408 break; 12409 if (!table_insertion_types[i]) 12410 return -1; 12411 push_args(ctx, arg); 12412 snprintf(tmp, sizeof(tmp), "%u", i); 12413 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12414 return ret > 0 ? (int)len : ret; 12415 } 12416 12417 /** Parse Hash Calculation Table Type name */ 12418 static int 12419 parse_hash_table_type(struct context *ctx, const struct token *token, 12420 const char *str, unsigned int len, void *buf, 12421 unsigned int size) 12422 { 12423 const struct arg *arg = pop_args(ctx); 12424 unsigned int i; 12425 char tmp[2]; 12426 int ret; 12427 12428 (void)size; 12429 /* Argument is expected. */ 12430 if (!arg) 12431 return -1; 12432 for (i = 0; table_hash_funcs[i]; ++i) 12433 if (!strcmp_partial(table_hash_funcs[i], str, len)) 12434 break; 12435 if (!table_hash_funcs[i]) 12436 return -1; 12437 push_args(ctx, arg); 12438 snprintf(tmp, sizeof(tmp), "%u", i); 12439 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12440 return ret > 0 ? (int)len : ret; 12441 } 12442 12443 static int 12444 parse_name_to_index(struct context *ctx, const struct token *token, 12445 const char *str, unsigned int len, void *buf, 12446 unsigned int size, 12447 const char *const names[], size_t names_size, uint32_t *dst) 12448 { 12449 int ret; 12450 uint32_t i; 12451 12452 RTE_SET_USED(token); 12453 RTE_SET_USED(buf); 12454 RTE_SET_USED(size); 12455 if (!ctx->object) 12456 return len; 12457 for (i = 0; i < names_size; i++) { 12458 if (!names[i]) 12459 continue; 12460 ret = strcmp_partial(names[i], str, 12461 RTE_MIN(len, strlen(names[i]))); 12462 if (!ret) { 12463 *dst = i; 12464 return len; 12465 } 12466 } 12467 return -1; 12468 } 12469 12470 static const char *const quota_mode_names[] = { 12471 NULL, 12472 [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", 12473 [RTE_FLOW_QUOTA_MODE_L2] = "l2", 12474 [RTE_FLOW_QUOTA_MODE_L3] = "l3" 12475 }; 12476 12477 static const char *const quota_state_names[] = { 12478 [RTE_FLOW_QUOTA_STATE_PASS] = "pass", 12479 [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" 12480 }; 12481 12482 static const char *const quota_update_names[] = { 12483 [RTE_FLOW_UPDATE_QUOTA_SET] = "set", 12484 [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" 12485 }; 12486 12487 static const char *const query_update_mode_names[] = { 12488 [RTE_FLOW_QU_QUERY_FIRST] = "query_first", 12489 [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" 12490 }; 12491 12492 static int 12493 parse_quota_state_name(struct context *ctx, const struct token *token, 12494 const char *str, unsigned int len, void *buf, 12495 unsigned int size) 12496 { 12497 struct rte_flow_item_quota *quota = ctx->object; 12498 12499 return parse_name_to_index(ctx, token, str, len, buf, size, 12500 quota_state_names, 12501 RTE_DIM(quota_state_names), 12502 (uint32_t *)"a->state); 12503 } 12504 12505 static int 12506 parse_quota_mode_name(struct context *ctx, const struct token *token, 12507 const char *str, unsigned int len, void *buf, 12508 unsigned int size) 12509 { 12510 struct rte_flow_action_quota *quota = ctx->object; 12511 12512 return parse_name_to_index(ctx, token, str, len, buf, size, 12513 quota_mode_names, 12514 RTE_DIM(quota_mode_names), 12515 (uint32_t *)"a->mode); 12516 } 12517 12518 static int 12519 parse_quota_update_name(struct context *ctx, const struct token *token, 12520 const char *str, unsigned int len, void *buf, 12521 unsigned int size) 12522 { 12523 struct rte_flow_update_quota *update = ctx->object; 12524 12525 return parse_name_to_index(ctx, token, str, len, buf, size, 12526 quota_update_names, 12527 RTE_DIM(quota_update_names), 12528 (uint32_t *)&update->op); 12529 } 12530 12531 static int 12532 parse_qu_mode_name(struct context *ctx, const struct token *token, 12533 const char *str, unsigned int len, void *buf, 12534 unsigned int size) 12535 { 12536 struct buffer *out = ctx->object; 12537 12538 return parse_name_to_index(ctx, token, str, len, buf, size, 12539 query_update_mode_names, 12540 RTE_DIM(query_update_mode_names), 12541 (uint32_t *)&out->args.ia.qu_mode); 12542 } 12543 12544 /** No completion. */ 12545 static int 12546 comp_none(struct context *ctx, const struct token *token, 12547 unsigned int ent, char *buf, unsigned int size) 12548 { 12549 (void)ctx; 12550 (void)token; 12551 (void)ent; 12552 (void)buf; 12553 (void)size; 12554 return 0; 12555 } 12556 12557 /** Complete boolean values. */ 12558 static int 12559 comp_boolean(struct context *ctx, const struct token *token, 12560 unsigned int ent, char *buf, unsigned int size) 12561 { 12562 unsigned int i; 12563 12564 (void)ctx; 12565 (void)token; 12566 for (i = 0; boolean_name[i]; ++i) 12567 if (buf && i == ent) 12568 return strlcpy(buf, boolean_name[i], size); 12569 if (buf) 12570 return -1; 12571 return i; 12572 } 12573 12574 /** Complete action names. */ 12575 static int 12576 comp_action(struct context *ctx, const struct token *token, 12577 unsigned int ent, char *buf, unsigned int size) 12578 { 12579 unsigned int i; 12580 12581 (void)ctx; 12582 (void)token; 12583 for (i = 0; next_action[i]; ++i) 12584 if (buf && i == ent) 12585 return strlcpy(buf, token_list[next_action[i]].name, 12586 size); 12587 if (buf) 12588 return -1; 12589 return i; 12590 } 12591 12592 /** Complete available ports. */ 12593 static int 12594 comp_port(struct context *ctx, const struct token *token, 12595 unsigned int ent, char *buf, unsigned int size) 12596 { 12597 unsigned int i = 0; 12598 portid_t p; 12599 12600 (void)ctx; 12601 (void)token; 12602 RTE_ETH_FOREACH_DEV(p) { 12603 if (buf && i == ent) 12604 return snprintf(buf, size, "%u", p); 12605 ++i; 12606 } 12607 if (buf) 12608 return -1; 12609 return i; 12610 } 12611 12612 /** Complete available rule IDs. */ 12613 static int 12614 comp_rule_id(struct context *ctx, const struct token *token, 12615 unsigned int ent, char *buf, unsigned int size) 12616 { 12617 unsigned int i = 0; 12618 struct rte_port *port; 12619 struct port_flow *pf; 12620 12621 (void)token; 12622 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12623 ctx->port == (portid_t)RTE_PORT_ALL) 12624 return -1; 12625 port = &ports[ctx->port]; 12626 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 12627 if (buf && i == ent) 12628 return snprintf(buf, size, "%"PRIu64, pf->id); 12629 ++i; 12630 } 12631 if (buf) 12632 return -1; 12633 return i; 12634 } 12635 12636 /** Complete operation for compare match item. */ 12637 static int 12638 comp_set_compare_op(struct context *ctx, const struct token *token, 12639 unsigned int ent, char *buf, unsigned int size) 12640 { 12641 RTE_SET_USED(ctx); 12642 RTE_SET_USED(token); 12643 if (!buf) 12644 return RTE_DIM(compare_ops); 12645 if (ent < RTE_DIM(compare_ops) - 1) 12646 return strlcpy(buf, compare_ops[ent], size); 12647 return -1; 12648 } 12649 12650 /** Complete field id for compare match item. */ 12651 static int 12652 comp_set_compare_field_id(struct context *ctx, const struct token *token, 12653 unsigned int ent, char *buf, unsigned int size) 12654 { 12655 const char *name; 12656 12657 RTE_SET_USED(token); 12658 if (!buf) 12659 return RTE_DIM(flow_field_ids); 12660 if (ent >= RTE_DIM(flow_field_ids) - 1) 12661 return -1; 12662 name = flow_field_ids[ent]; 12663 if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE || 12664 (strcmp(name, "pointer") && strcmp(name, "value"))) 12665 return strlcpy(buf, name, size); 12666 return -1; 12667 } 12668 12669 /** Complete type field for RSS action. */ 12670 static int 12671 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 12672 unsigned int ent, char *buf, unsigned int size) 12673 { 12674 unsigned int i; 12675 12676 (void)ctx; 12677 (void)token; 12678 for (i = 0; rss_type_table[i].str; ++i) 12679 ; 12680 if (!buf) 12681 return i + 1; 12682 if (ent < i) 12683 return strlcpy(buf, rss_type_table[ent].str, size); 12684 if (ent == i) 12685 return snprintf(buf, size, "end"); 12686 return -1; 12687 } 12688 12689 /** Complete queue field for RSS action. */ 12690 static int 12691 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 12692 unsigned int ent, char *buf, unsigned int size) 12693 { 12694 (void)ctx; 12695 (void)token; 12696 if (!buf) 12697 return nb_rxq + 1; 12698 if (ent < nb_rxq) 12699 return snprintf(buf, size, "%u", ent); 12700 if (ent == nb_rxq) 12701 return snprintf(buf, size, "end"); 12702 return -1; 12703 } 12704 12705 /** Complete index number for set raw_encap/raw_decap commands. */ 12706 static int 12707 comp_set_raw_index(struct context *ctx, const struct token *token, 12708 unsigned int ent, char *buf, unsigned int size) 12709 { 12710 uint16_t idx = 0; 12711 uint16_t nb = 0; 12712 12713 RTE_SET_USED(ctx); 12714 RTE_SET_USED(token); 12715 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 12716 if (buf && idx == ent) 12717 return snprintf(buf, size, "%u", idx); 12718 ++nb; 12719 } 12720 return nb; 12721 } 12722 12723 /** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ 12724 static int 12725 comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 12726 unsigned int ent, char *buf, unsigned int size) 12727 { 12728 uint16_t idx = 0; 12729 uint16_t nb = 0; 12730 12731 RTE_SET_USED(ctx); 12732 RTE_SET_USED(token); 12733 for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { 12734 if (buf && idx == ent) 12735 return snprintf(buf, size, "%u", idx); 12736 ++nb; 12737 } 12738 return nb; 12739 } 12740 12741 /** Complete index number for set raw_encap/raw_decap commands. */ 12742 static int 12743 comp_set_sample_index(struct context *ctx, const struct token *token, 12744 unsigned int ent, char *buf, unsigned int size) 12745 { 12746 uint16_t idx = 0; 12747 uint16_t nb = 0; 12748 12749 RTE_SET_USED(ctx); 12750 RTE_SET_USED(token); 12751 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 12752 if (buf && idx == ent) 12753 return snprintf(buf, size, "%u", idx); 12754 ++nb; 12755 } 12756 return nb; 12757 } 12758 12759 /** Complete operation for modify_field command. */ 12760 static int 12761 comp_set_modify_field_op(struct context *ctx, const struct token *token, 12762 unsigned int ent, char *buf, unsigned int size) 12763 { 12764 RTE_SET_USED(ctx); 12765 RTE_SET_USED(token); 12766 if (!buf) 12767 return RTE_DIM(modify_field_ops); 12768 if (ent < RTE_DIM(modify_field_ops) - 1) 12769 return strlcpy(buf, modify_field_ops[ent], size); 12770 return -1; 12771 } 12772 12773 /** Complete field id for modify_field command. */ 12774 static int 12775 comp_set_modify_field_id(struct context *ctx, const struct token *token, 12776 unsigned int ent, char *buf, unsigned int size) 12777 { 12778 const char *name; 12779 12780 RTE_SET_USED(token); 12781 if (!buf) 12782 return RTE_DIM(flow_field_ids); 12783 if (ent >= RTE_DIM(flow_field_ids) - 1) 12784 return -1; 12785 name = flow_field_ids[ent]; 12786 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 12787 (strcmp(name, "pointer") && strcmp(name, "value"))) 12788 return strlcpy(buf, name, size); 12789 return -1; 12790 } 12791 12792 /** Complete available pattern template IDs. */ 12793 static int 12794 comp_pattern_template_id(struct context *ctx, const struct token *token, 12795 unsigned int ent, char *buf, unsigned int size) 12796 { 12797 unsigned int i = 0; 12798 struct rte_port *port; 12799 struct port_template *pt; 12800 12801 (void)token; 12802 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12803 ctx->port == (portid_t)RTE_PORT_ALL) 12804 return -1; 12805 port = &ports[ctx->port]; 12806 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 12807 if (buf && i == ent) 12808 return snprintf(buf, size, "%u", pt->id); 12809 ++i; 12810 } 12811 if (buf) 12812 return -1; 12813 return i; 12814 } 12815 12816 /** Complete available actions template IDs. */ 12817 static int 12818 comp_actions_template_id(struct context *ctx, const struct token *token, 12819 unsigned int ent, char *buf, unsigned int size) 12820 { 12821 unsigned int i = 0; 12822 struct rte_port *port; 12823 struct port_template *pt; 12824 12825 (void)token; 12826 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12827 ctx->port == (portid_t)RTE_PORT_ALL) 12828 return -1; 12829 port = &ports[ctx->port]; 12830 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 12831 if (buf && i == ent) 12832 return snprintf(buf, size, "%u", pt->id); 12833 ++i; 12834 } 12835 if (buf) 12836 return -1; 12837 return i; 12838 } 12839 12840 /** Complete available table IDs. */ 12841 static int 12842 comp_table_id(struct context *ctx, const struct token *token, 12843 unsigned int ent, char *buf, unsigned int size) 12844 { 12845 unsigned int i = 0; 12846 struct rte_port *port; 12847 struct port_table *pt; 12848 12849 (void)token; 12850 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12851 ctx->port == (portid_t)RTE_PORT_ALL) 12852 return -1; 12853 port = &ports[ctx->port]; 12854 for (pt = port->table_list; pt != NULL; pt = pt->next) { 12855 if (buf && i == ent) 12856 return snprintf(buf, size, "%u", pt->id); 12857 ++i; 12858 } 12859 if (buf) 12860 return -1; 12861 return i; 12862 } 12863 12864 /** Complete available queue IDs. */ 12865 static int 12866 comp_queue_id(struct context *ctx, const struct token *token, 12867 unsigned int ent, char *buf, unsigned int size) 12868 { 12869 unsigned int i = 0; 12870 struct rte_port *port; 12871 12872 (void)token; 12873 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12874 ctx->port == (portid_t)RTE_PORT_ALL) 12875 return -1; 12876 port = &ports[ctx->port]; 12877 for (i = 0; i < port->queue_nb; i++) { 12878 if (buf && i == ent) 12879 return snprintf(buf, size, "%u", i); 12880 } 12881 if (buf) 12882 return -1; 12883 return i; 12884 } 12885 12886 static int 12887 comp_names_to_index(struct context *ctx, const struct token *token, 12888 unsigned int ent, char *buf, unsigned int size, 12889 const char *const names[], size_t names_size) 12890 { 12891 RTE_SET_USED(ctx); 12892 RTE_SET_USED(token); 12893 if (!buf) 12894 return names_size; 12895 if (ent < names_size && names[ent] != NULL) 12896 return rte_strscpy(buf, names[ent], size); 12897 return -1; 12898 12899 } 12900 12901 /** Complete available Meter colors. */ 12902 static int 12903 comp_meter_color(struct context *ctx, const struct token *token, 12904 unsigned int ent, char *buf, unsigned int size) 12905 { 12906 RTE_SET_USED(ctx); 12907 RTE_SET_USED(token); 12908 if (!buf) 12909 return RTE_DIM(meter_colors); 12910 if (ent < RTE_DIM(meter_colors) - 1) 12911 return strlcpy(buf, meter_colors[ent], size); 12912 return -1; 12913 } 12914 12915 /** Complete available Insertion Table types. */ 12916 static int 12917 comp_insertion_table_type(struct context *ctx, const struct token *token, 12918 unsigned int ent, char *buf, unsigned int size) 12919 { 12920 RTE_SET_USED(ctx); 12921 RTE_SET_USED(token); 12922 if (!buf) 12923 return RTE_DIM(table_insertion_types); 12924 if (ent < RTE_DIM(table_insertion_types) - 1) 12925 return rte_strscpy(buf, table_insertion_types[ent], size); 12926 return -1; 12927 } 12928 12929 /** Complete available Hash Calculation Table types. */ 12930 static int 12931 comp_hash_table_type(struct context *ctx, const struct token *token, 12932 unsigned int ent, char *buf, unsigned int size) 12933 { 12934 RTE_SET_USED(ctx); 12935 RTE_SET_USED(token); 12936 if (!buf) 12937 return RTE_DIM(table_hash_funcs); 12938 if (ent < RTE_DIM(table_hash_funcs) - 1) 12939 return rte_strscpy(buf, table_hash_funcs[ent], size); 12940 return -1; 12941 } 12942 12943 static int 12944 comp_quota_state_name(struct context *ctx, const struct token *token, 12945 unsigned int ent, char *buf, unsigned int size) 12946 { 12947 return comp_names_to_index(ctx, token, ent, buf, size, 12948 quota_state_names, 12949 RTE_DIM(quota_state_names)); 12950 } 12951 12952 static int 12953 comp_quota_mode_name(struct context *ctx, const struct token *token, 12954 unsigned int ent, char *buf, unsigned int size) 12955 { 12956 return comp_names_to_index(ctx, token, ent, buf, size, 12957 quota_mode_names, 12958 RTE_DIM(quota_mode_names)); 12959 } 12960 12961 static int 12962 comp_quota_update_name(struct context *ctx, const struct token *token, 12963 unsigned int ent, char *buf, unsigned int size) 12964 { 12965 return comp_names_to_index(ctx, token, ent, buf, size, 12966 quota_update_names, 12967 RTE_DIM(quota_update_names)); 12968 } 12969 12970 static int 12971 comp_qu_mode_name(struct context *ctx, const struct token *token, 12972 unsigned int ent, char *buf, unsigned int size) 12973 { 12974 return comp_names_to_index(ctx, token, ent, buf, size, 12975 query_update_mode_names, 12976 RTE_DIM(query_update_mode_names)); 12977 } 12978 12979 /** Internal context. */ 12980 static struct context cmd_flow_context; 12981 12982 /** Global parser instance (cmdline API). */ 12983 cmdline_parse_inst_t cmd_flow; 12984 cmdline_parse_inst_t cmd_set_raw; 12985 12986 /** Initialize context. */ 12987 static void 12988 cmd_flow_context_init(struct context *ctx) 12989 { 12990 /* A full memset() is not necessary. */ 12991 ctx->curr = ZERO; 12992 ctx->prev = ZERO; 12993 ctx->next_num = 0; 12994 ctx->args_num = 0; 12995 ctx->eol = 0; 12996 ctx->last = 0; 12997 ctx->port = 0; 12998 ctx->objdata = 0; 12999 ctx->object = NULL; 13000 ctx->objmask = NULL; 13001 } 13002 13003 /** Parse a token (cmdline API). */ 13004 static int 13005 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 13006 unsigned int size) 13007 { 13008 struct context *ctx = &cmd_flow_context; 13009 const struct token *token; 13010 const enum index *list; 13011 int len; 13012 int i; 13013 13014 (void)hdr; 13015 token = &token_list[ctx->curr]; 13016 /* Check argument length. */ 13017 ctx->eol = 0; 13018 ctx->last = 1; 13019 for (len = 0; src[len]; ++len) 13020 if (src[len] == '#' || isspace(src[len])) 13021 break; 13022 if (!len) 13023 return -1; 13024 /* Last argument and EOL detection. */ 13025 for (i = len; src[i]; ++i) 13026 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 13027 break; 13028 else if (!isspace(src[i])) { 13029 ctx->last = 0; 13030 break; 13031 } 13032 for (; src[i]; ++i) 13033 if (src[i] == '\r' || src[i] == '\n') { 13034 ctx->eol = 1; 13035 break; 13036 } 13037 /* Initialize context if necessary. */ 13038 if (!ctx->next_num) { 13039 if (!token->next) 13040 return 0; 13041 ctx->next[ctx->next_num++] = token->next[0]; 13042 } 13043 /* Process argument through candidates. */ 13044 ctx->prev = ctx->curr; 13045 list = ctx->next[ctx->next_num - 1]; 13046 for (i = 0; list[i]; ++i) { 13047 const struct token *next = &token_list[list[i]]; 13048 int tmp; 13049 13050 ctx->curr = list[i]; 13051 if (next->call) 13052 tmp = next->call(ctx, next, src, len, result, size); 13053 else 13054 tmp = parse_default(ctx, next, src, len, result, size); 13055 if (tmp == -1 || tmp != len) 13056 continue; 13057 token = next; 13058 break; 13059 } 13060 if (!list[i]) 13061 return -1; 13062 --ctx->next_num; 13063 /* Push subsequent tokens if any. */ 13064 if (token->next) 13065 for (i = 0; token->next[i]; ++i) { 13066 if (ctx->next_num == RTE_DIM(ctx->next)) 13067 return -1; 13068 ctx->next[ctx->next_num++] = token->next[i]; 13069 } 13070 /* Push arguments if any. */ 13071 if (token->args) 13072 for (i = 0; token->args[i]; ++i) { 13073 if (ctx->args_num == RTE_DIM(ctx->args)) 13074 return -1; 13075 ctx->args[ctx->args_num++] = token->args[i]; 13076 } 13077 return len; 13078 } 13079 13080 int 13081 flow_parse(const char *src, void *result, unsigned int size, 13082 struct rte_flow_attr **attr, 13083 struct rte_flow_item **pattern, struct rte_flow_action **actions) 13084 { 13085 int ret; 13086 struct context saved_flow_ctx = cmd_flow_context; 13087 13088 cmd_flow_context_init(&cmd_flow_context); 13089 do { 13090 ret = cmd_flow_parse(NULL, src, result, size); 13091 if (ret > 0) { 13092 src += ret; 13093 while (isspace(*src)) 13094 src++; 13095 } 13096 } while (ret > 0 && strlen(src)); 13097 cmd_flow_context = saved_flow_ctx; 13098 *attr = &((struct buffer *)result)->args.vc.attr; 13099 *pattern = ((struct buffer *)result)->args.vc.pattern; 13100 *actions = ((struct buffer *)result)->args.vc.actions; 13101 return (ret >= 0 && !strlen(src)) ? 0 : -1; 13102 } 13103 13104 /** Return number of completion entries (cmdline API). */ 13105 static int 13106 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 13107 { 13108 struct context *ctx = &cmd_flow_context; 13109 const struct token *token = &token_list[ctx->curr]; 13110 const enum index *list; 13111 int i; 13112 13113 (void)hdr; 13114 /* Count number of tokens in current list. */ 13115 if (ctx->next_num) 13116 list = ctx->next[ctx->next_num - 1]; 13117 else 13118 list = token->next[0]; 13119 for (i = 0; list[i]; ++i) 13120 ; 13121 if (!i) 13122 return 0; 13123 /* 13124 * If there is a single token, use its completion callback, otherwise 13125 * return the number of entries. 13126 */ 13127 token = &token_list[list[0]]; 13128 if (i == 1 && token->comp) { 13129 /* Save index for cmd_flow_get_help(). */ 13130 ctx->prev = list[0]; 13131 return token->comp(ctx, token, 0, NULL, 0); 13132 } 13133 return i; 13134 } 13135 13136 /** Return a completion entry (cmdline API). */ 13137 static int 13138 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 13139 char *dst, unsigned int size) 13140 { 13141 struct context *ctx = &cmd_flow_context; 13142 const struct token *token = &token_list[ctx->curr]; 13143 const enum index *list; 13144 int i; 13145 13146 (void)hdr; 13147 /* Count number of tokens in current list. */ 13148 if (ctx->next_num) 13149 list = ctx->next[ctx->next_num - 1]; 13150 else 13151 list = token->next[0]; 13152 for (i = 0; list[i]; ++i) 13153 ; 13154 if (!i) 13155 return -1; 13156 /* If there is a single token, use its completion callback. */ 13157 token = &token_list[list[0]]; 13158 if (i == 1 && token->comp) { 13159 /* Save index for cmd_flow_get_help(). */ 13160 ctx->prev = list[0]; 13161 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 13162 } 13163 /* Otherwise make sure the index is valid and use defaults. */ 13164 if (index >= i) 13165 return -1; 13166 token = &token_list[list[index]]; 13167 strlcpy(dst, token->name, size); 13168 /* Save index for cmd_flow_get_help(). */ 13169 ctx->prev = list[index]; 13170 return 0; 13171 } 13172 13173 /** Populate help strings for current token (cmdline API). */ 13174 static int 13175 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 13176 { 13177 struct context *ctx = &cmd_flow_context; 13178 const struct token *token = &token_list[ctx->prev]; 13179 13180 (void)hdr; 13181 if (!size) 13182 return -1; 13183 /* Set token type and update global help with details. */ 13184 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 13185 if (token->help) 13186 cmd_flow.help_str = token->help; 13187 else 13188 cmd_flow.help_str = token->name; 13189 return 0; 13190 } 13191 13192 /** Token definition template (cmdline API). */ 13193 static struct cmdline_token_hdr cmd_flow_token_hdr = { 13194 .ops = &(struct cmdline_token_ops){ 13195 .parse = cmd_flow_parse, 13196 .complete_get_nb = cmd_flow_complete_get_nb, 13197 .complete_get_elt = cmd_flow_complete_get_elt, 13198 .get_help = cmd_flow_get_help, 13199 }, 13200 .offset = 0, 13201 }; 13202 13203 /** Populate the next dynamic token. */ 13204 static void 13205 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 13206 cmdline_parse_token_hdr_t **hdr_inst) 13207 { 13208 struct context *ctx = &cmd_flow_context; 13209 13210 /* Always reinitialize context before requesting the first token. */ 13211 if (!(hdr_inst - cmd_flow.tokens)) 13212 cmd_flow_context_init(ctx); 13213 /* Return NULL when no more tokens are expected. */ 13214 if (!ctx->next_num && ctx->curr) { 13215 *hdr = NULL; 13216 return; 13217 } 13218 /* Determine if command should end here. */ 13219 if (ctx->eol && ctx->last && ctx->next_num) { 13220 const enum index *list = ctx->next[ctx->next_num - 1]; 13221 int i; 13222 13223 for (i = 0; list[i]; ++i) { 13224 if (list[i] != END) 13225 continue; 13226 *hdr = NULL; 13227 return; 13228 } 13229 } 13230 *hdr = &cmd_flow_token_hdr; 13231 } 13232 13233 static SLIST_HEAD(, indlst_conf) indlst_conf_head = 13234 SLIST_HEAD_INITIALIZER(); 13235 13236 static void 13237 indirect_action_flow_conf_create(const struct buffer *in) 13238 { 13239 int len, ret; 13240 uint32_t i; 13241 struct indlst_conf *indlst_conf = NULL; 13242 size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); 13243 struct rte_flow_action *src = in->args.vc.actions; 13244 13245 if (!in->args.vc.actions_n) 13246 goto end; 13247 len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); 13248 if (len <= 0) 13249 goto end; 13250 len = RTE_ALIGN(len, 16); 13251 13252 indlst_conf = calloc(1, base + len + 13253 in->args.vc.actions_n * sizeof(uintptr_t)); 13254 if (!indlst_conf) 13255 goto end; 13256 indlst_conf->id = in->args.vc.attr.group; 13257 indlst_conf->conf_num = in->args.vc.actions_n - 1; 13258 indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); 13259 ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, 13260 len, src, NULL); 13261 if (ret <= 0) { 13262 free(indlst_conf); 13263 indlst_conf = NULL; 13264 goto end; 13265 } 13266 indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); 13267 for (i = 0; i < indlst_conf->conf_num; i++) 13268 indlst_conf->conf[i] = indlst_conf->actions[i].conf; 13269 SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); 13270 end: 13271 if (indlst_conf) 13272 printf("created indirect action list configuration %u\n", 13273 in->args.vc.attr.group); 13274 else 13275 printf("cannot create indirect action list configuration %u\n", 13276 in->args.vc.attr.group); 13277 } 13278 13279 static const struct indlst_conf * 13280 indirect_action_list_conf_get(uint32_t conf_id) 13281 { 13282 const struct indlst_conf *conf; 13283 13284 SLIST_FOREACH(conf, &indlst_conf_head, next) { 13285 if (conf->id == conf_id) 13286 return conf; 13287 } 13288 return NULL; 13289 } 13290 13291 /** Dispatch parsed buffer to function calls. */ 13292 static void 13293 cmd_flow_parsed(const struct buffer *in) 13294 { 13295 switch (in->command) { 13296 case INFO: 13297 port_flow_get_info(in->port); 13298 break; 13299 case CONFIGURE: 13300 port_flow_configure(in->port, 13301 &in->args.configure.port_attr, 13302 in->args.configure.nb_queue, 13303 &in->args.configure.queue_attr); 13304 break; 13305 case PATTERN_TEMPLATE_CREATE: 13306 port_flow_pattern_template_create(in->port, 13307 in->args.vc.pat_templ_id, 13308 &((const struct rte_flow_pattern_template_attr) { 13309 .relaxed_matching = in->args.vc.attr.reserved, 13310 .ingress = in->args.vc.attr.ingress, 13311 .egress = in->args.vc.attr.egress, 13312 .transfer = in->args.vc.attr.transfer, 13313 }), 13314 in->args.vc.pattern); 13315 break; 13316 case PATTERN_TEMPLATE_DESTROY: 13317 port_flow_pattern_template_destroy(in->port, 13318 in->args.templ_destroy.template_id_n, 13319 in->args.templ_destroy.template_id); 13320 break; 13321 case ACTIONS_TEMPLATE_CREATE: 13322 port_flow_actions_template_create(in->port, 13323 in->args.vc.act_templ_id, 13324 &((const struct rte_flow_actions_template_attr) { 13325 .ingress = in->args.vc.attr.ingress, 13326 .egress = in->args.vc.attr.egress, 13327 .transfer = in->args.vc.attr.transfer, 13328 }), 13329 in->args.vc.actions, 13330 in->args.vc.masks); 13331 break; 13332 case ACTIONS_TEMPLATE_DESTROY: 13333 port_flow_actions_template_destroy(in->port, 13334 in->args.templ_destroy.template_id_n, 13335 in->args.templ_destroy.template_id); 13336 break; 13337 case TABLE_CREATE: 13338 port_flow_template_table_create(in->port, in->args.table.id, 13339 &in->args.table.attr, in->args.table.pat_templ_id_n, 13340 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 13341 in->args.table.act_templ_id); 13342 break; 13343 case TABLE_DESTROY: 13344 port_flow_template_table_destroy(in->port, 13345 in->args.table_destroy.table_id_n, 13346 in->args.table_destroy.table_id); 13347 break; 13348 case TABLE_RESIZE_COMPLETE: 13349 port_flow_template_table_resize_complete 13350 (in->port, in->args.table_destroy.table_id[0]); 13351 break; 13352 case GROUP_SET_MISS_ACTIONS: 13353 port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, 13354 in->args.vc.actions); 13355 break; 13356 case TABLE_RESIZE: 13357 port_flow_template_table_resize(in->port, in->args.table.id, 13358 in->args.table.attr.nb_flows); 13359 break; 13360 case QUEUE_CREATE: 13361 port_queue_flow_create(in->port, in->queue, in->postpone, 13362 in->args.vc.table_id, in->args.vc.rule_id, 13363 in->args.vc.pat_templ_id, in->args.vc.act_templ_id, 13364 in->args.vc.pattern, in->args.vc.actions); 13365 break; 13366 case QUEUE_DESTROY: 13367 port_queue_flow_destroy(in->port, in->queue, in->postpone, 13368 in->args.destroy.rule_n, 13369 in->args.destroy.rule); 13370 break; 13371 case QUEUE_FLOW_UPDATE_RESIZED: 13372 port_queue_flow_update_resized(in->port, in->queue, 13373 in->postpone, 13374 in->args.destroy.rule[0]); 13375 break; 13376 case QUEUE_UPDATE: 13377 port_queue_flow_update(in->port, in->queue, in->postpone, 13378 in->args.vc.rule_id, in->args.vc.act_templ_id, 13379 in->args.vc.actions); 13380 break; 13381 case PUSH: 13382 port_queue_flow_push(in->port, in->queue); 13383 break; 13384 case PULL: 13385 port_queue_flow_pull(in->port, in->queue); 13386 break; 13387 case HASH: 13388 if (!in->args.vc.encap_hash) 13389 port_flow_hash_calc(in->port, in->args.vc.table_id, 13390 in->args.vc.pat_templ_id, 13391 in->args.vc.pattern); 13392 else 13393 port_flow_hash_calc_encap(in->port, in->args.vc.field, 13394 in->args.vc.pattern); 13395 break; 13396 case QUEUE_AGED: 13397 port_queue_flow_aged(in->port, in->queue, 13398 in->args.aged.destroy); 13399 break; 13400 case QUEUE_INDIRECT_ACTION_CREATE: 13401 case QUEUE_INDIRECT_ACTION_LIST_CREATE: 13402 port_queue_action_handle_create( 13403 in->port, in->queue, in->postpone, 13404 in->args.vc.attr.group, 13405 in->command == QUEUE_INDIRECT_ACTION_LIST_CREATE, 13406 &((const struct rte_flow_indir_action_conf) { 13407 .ingress = in->args.vc.attr.ingress, 13408 .egress = in->args.vc.attr.egress, 13409 .transfer = in->args.vc.attr.transfer, 13410 }), 13411 in->args.vc.actions); 13412 break; 13413 case QUEUE_INDIRECT_ACTION_DESTROY: 13414 port_queue_action_handle_destroy(in->port, 13415 in->queue, in->postpone, 13416 in->args.ia_destroy.action_id_n, 13417 in->args.ia_destroy.action_id); 13418 break; 13419 case QUEUE_INDIRECT_ACTION_UPDATE: 13420 port_queue_action_handle_update(in->port, 13421 in->queue, in->postpone, 13422 in->args.vc.attr.group, 13423 in->args.vc.actions); 13424 break; 13425 case QUEUE_INDIRECT_ACTION_QUERY: 13426 port_queue_action_handle_query(in->port, 13427 in->queue, in->postpone, 13428 in->args.ia.action_id); 13429 break; 13430 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 13431 port_queue_action_handle_query_update(in->port, in->queue, 13432 in->postpone, 13433 in->args.ia.action_id, 13434 in->args.ia.qu_mode, 13435 in->args.vc.actions); 13436 break; 13437 case INDIRECT_ACTION_CREATE: 13438 case INDIRECT_ACTION_LIST_CREATE: 13439 port_action_handle_create( 13440 in->port, in->args.vc.attr.group, 13441 in->command == INDIRECT_ACTION_LIST_CREATE, 13442 &((const struct rte_flow_indir_action_conf) { 13443 .ingress = in->args.vc.attr.ingress, 13444 .egress = in->args.vc.attr.egress, 13445 .transfer = in->args.vc.attr.transfer, 13446 }), 13447 in->args.vc.actions); 13448 break; 13449 case INDIRECT_ACTION_FLOW_CONF_CREATE: 13450 indirect_action_flow_conf_create(in); 13451 break; 13452 case INDIRECT_ACTION_DESTROY: 13453 port_action_handle_destroy(in->port, 13454 in->args.ia_destroy.action_id_n, 13455 in->args.ia_destroy.action_id); 13456 break; 13457 case INDIRECT_ACTION_UPDATE: 13458 port_action_handle_update(in->port, in->args.vc.attr.group, 13459 in->args.vc.actions); 13460 break; 13461 case INDIRECT_ACTION_QUERY: 13462 port_action_handle_query(in->port, in->args.ia.action_id); 13463 break; 13464 case INDIRECT_ACTION_QUERY_UPDATE: 13465 port_action_handle_query_update(in->port, 13466 in->args.ia.action_id, 13467 in->args.ia.qu_mode, 13468 in->args.vc.actions); 13469 break; 13470 case VALIDATE: 13471 port_flow_validate(in->port, &in->args.vc.attr, 13472 in->args.vc.pattern, in->args.vc.actions, 13473 &in->args.vc.tunnel_ops); 13474 break; 13475 case CREATE: 13476 port_flow_create(in->port, &in->args.vc.attr, 13477 in->args.vc.pattern, in->args.vc.actions, 13478 &in->args.vc.tunnel_ops, in->args.vc.user_id); 13479 break; 13480 case DESTROY: 13481 port_flow_destroy(in->port, in->args.destroy.rule_n, 13482 in->args.destroy.rule, 13483 in->args.destroy.is_user_id); 13484 break; 13485 case UPDATE: 13486 port_flow_update(in->port, in->args.vc.rule_id, 13487 in->args.vc.actions, in->args.vc.user_id); 13488 break; 13489 case FLUSH: 13490 port_flow_flush(in->port); 13491 break; 13492 case DUMP_ONE: 13493 case DUMP_ALL: 13494 port_flow_dump(in->port, in->args.dump.mode, 13495 in->args.dump.rule, in->args.dump.file, 13496 in->args.dump.is_user_id); 13497 break; 13498 case QUERY: 13499 port_flow_query(in->port, in->args.query.rule, 13500 &in->args.query.action, 13501 in->args.query.is_user_id); 13502 break; 13503 case LIST: 13504 port_flow_list(in->port, in->args.list.group_n, 13505 in->args.list.group); 13506 break; 13507 case ISOLATE: 13508 port_flow_isolate(in->port, in->args.isolate.set); 13509 break; 13510 case AGED: 13511 port_flow_aged(in->port, in->args.aged.destroy); 13512 break; 13513 case TUNNEL_CREATE: 13514 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 13515 break; 13516 case TUNNEL_DESTROY: 13517 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 13518 break; 13519 case TUNNEL_LIST: 13520 port_flow_tunnel_list(in->port); 13521 break; 13522 case ACTION_POL_G: 13523 port_meter_policy_add(in->port, in->args.policy.policy_id, 13524 in->args.vc.actions); 13525 break; 13526 case FLEX_ITEM_CREATE: 13527 flex_item_create(in->port, in->args.flex.token, 13528 in->args.flex.filename); 13529 break; 13530 case FLEX_ITEM_DESTROY: 13531 flex_item_destroy(in->port, in->args.flex.token); 13532 break; 13533 default: 13534 break; 13535 } 13536 fflush(stdout); 13537 } 13538 13539 /** Token generator and output processing callback (cmdline API). */ 13540 static void 13541 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 13542 { 13543 if (cl == NULL) 13544 cmd_flow_tok(arg0, arg2); 13545 else 13546 cmd_flow_parsed(arg0); 13547 } 13548 13549 /** Global parser instance (cmdline API). */ 13550 cmdline_parse_inst_t cmd_flow = { 13551 .f = cmd_flow_cb, 13552 .data = NULL, /**< Unused. */ 13553 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 13554 .tokens = { 13555 NULL, 13556 }, /**< Tokens are returned by cmd_flow_tok(). */ 13557 }; 13558 13559 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 13560 13561 static void 13562 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 13563 { 13564 struct rte_ipv4_hdr *ipv4; 13565 struct rte_ether_hdr *eth; 13566 struct rte_ipv6_hdr *ipv6; 13567 struct rte_vxlan_hdr *vxlan; 13568 struct rte_vxlan_gpe_hdr *gpe; 13569 struct rte_flow_item_nvgre *nvgre; 13570 uint32_t ipv6_vtc_flow; 13571 13572 switch (item->type) { 13573 case RTE_FLOW_ITEM_TYPE_ETH: 13574 eth = (struct rte_ether_hdr *)buf; 13575 if (next_proto) 13576 eth->ether_type = rte_cpu_to_be_16(next_proto); 13577 break; 13578 case RTE_FLOW_ITEM_TYPE_IPV4: 13579 ipv4 = (struct rte_ipv4_hdr *)buf; 13580 if (!ipv4->version_ihl) 13581 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 13582 if (next_proto && ipv4->next_proto_id == 0) 13583 ipv4->next_proto_id = (uint8_t)next_proto; 13584 break; 13585 case RTE_FLOW_ITEM_TYPE_IPV6: 13586 ipv6 = (struct rte_ipv6_hdr *)buf; 13587 if (next_proto && ipv6->proto == 0) 13588 ipv6->proto = (uint8_t)next_proto; 13589 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 13590 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 13591 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 13592 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 13593 break; 13594 case RTE_FLOW_ITEM_TYPE_VXLAN: 13595 vxlan = (struct rte_vxlan_hdr *)buf; 13596 vxlan->vx_flags = 0x08; 13597 break; 13598 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13599 gpe = (struct rte_vxlan_gpe_hdr *)buf; 13600 gpe->vx_flags = 0x0C; 13601 break; 13602 case RTE_FLOW_ITEM_TYPE_NVGRE: 13603 nvgre = (struct rte_flow_item_nvgre *)buf; 13604 nvgre->protocol = rte_cpu_to_be_16(0x6558); 13605 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 13606 break; 13607 default: 13608 break; 13609 } 13610 } 13611 13612 /** Helper of get item's default mask. */ 13613 static const void * 13614 flow_item_default_mask(const struct rte_flow_item *item) 13615 { 13616 const void *mask = NULL; 13617 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 13618 static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { 13619 .hdr = { 13620 .next_hdr = 0xff, 13621 .type = 0xff, 13622 .segments_left = 0xff, 13623 }, 13624 }; 13625 13626 switch (item->type) { 13627 case RTE_FLOW_ITEM_TYPE_ANY: 13628 mask = &rte_flow_item_any_mask; 13629 break; 13630 case RTE_FLOW_ITEM_TYPE_PORT_ID: 13631 mask = &rte_flow_item_port_id_mask; 13632 break; 13633 case RTE_FLOW_ITEM_TYPE_RAW: 13634 mask = &rte_flow_item_raw_mask; 13635 break; 13636 case RTE_FLOW_ITEM_TYPE_ETH: 13637 mask = &rte_flow_item_eth_mask; 13638 break; 13639 case RTE_FLOW_ITEM_TYPE_VLAN: 13640 mask = &rte_flow_item_vlan_mask; 13641 break; 13642 case RTE_FLOW_ITEM_TYPE_IPV4: 13643 mask = &rte_flow_item_ipv4_mask; 13644 break; 13645 case RTE_FLOW_ITEM_TYPE_IPV6: 13646 mask = &rte_flow_item_ipv6_mask; 13647 break; 13648 case RTE_FLOW_ITEM_TYPE_ICMP: 13649 mask = &rte_flow_item_icmp_mask; 13650 break; 13651 case RTE_FLOW_ITEM_TYPE_UDP: 13652 mask = &rte_flow_item_udp_mask; 13653 break; 13654 case RTE_FLOW_ITEM_TYPE_TCP: 13655 mask = &rte_flow_item_tcp_mask; 13656 break; 13657 case RTE_FLOW_ITEM_TYPE_SCTP: 13658 mask = &rte_flow_item_sctp_mask; 13659 break; 13660 case RTE_FLOW_ITEM_TYPE_VXLAN: 13661 mask = &rte_flow_item_vxlan_mask; 13662 break; 13663 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13664 mask = &rte_flow_item_vxlan_gpe_mask; 13665 break; 13666 case RTE_FLOW_ITEM_TYPE_E_TAG: 13667 mask = &rte_flow_item_e_tag_mask; 13668 break; 13669 case RTE_FLOW_ITEM_TYPE_NVGRE: 13670 mask = &rte_flow_item_nvgre_mask; 13671 break; 13672 case RTE_FLOW_ITEM_TYPE_MPLS: 13673 mask = &rte_flow_item_mpls_mask; 13674 break; 13675 case RTE_FLOW_ITEM_TYPE_GRE: 13676 mask = &rte_flow_item_gre_mask; 13677 break; 13678 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13679 mask = &gre_key_default_mask; 13680 break; 13681 case RTE_FLOW_ITEM_TYPE_META: 13682 mask = &rte_flow_item_meta_mask; 13683 break; 13684 case RTE_FLOW_ITEM_TYPE_RANDOM: 13685 mask = &rte_flow_item_random_mask; 13686 break; 13687 case RTE_FLOW_ITEM_TYPE_FUZZY: 13688 mask = &rte_flow_item_fuzzy_mask; 13689 break; 13690 case RTE_FLOW_ITEM_TYPE_GTP: 13691 mask = &rte_flow_item_gtp_mask; 13692 break; 13693 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13694 mask = &rte_flow_item_gtp_psc_mask; 13695 break; 13696 case RTE_FLOW_ITEM_TYPE_GENEVE: 13697 mask = &rte_flow_item_geneve_mask; 13698 break; 13699 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13700 mask = &rte_flow_item_geneve_opt_mask; 13701 break; 13702 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 13703 mask = &rte_flow_item_pppoe_proto_id_mask; 13704 break; 13705 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13706 mask = &rte_flow_item_l2tpv3oip_mask; 13707 break; 13708 case RTE_FLOW_ITEM_TYPE_ESP: 13709 mask = &rte_flow_item_esp_mask; 13710 break; 13711 case RTE_FLOW_ITEM_TYPE_AH: 13712 mask = &rte_flow_item_ah_mask; 13713 break; 13714 case RTE_FLOW_ITEM_TYPE_PFCP: 13715 mask = &rte_flow_item_pfcp_mask; 13716 break; 13717 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 13718 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 13719 mask = &rte_flow_item_ethdev_mask; 13720 break; 13721 case RTE_FLOW_ITEM_TYPE_L2TPV2: 13722 mask = &rte_flow_item_l2tpv2_mask; 13723 break; 13724 case RTE_FLOW_ITEM_TYPE_PPP: 13725 mask = &rte_flow_item_ppp_mask; 13726 break; 13727 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 13728 mask = &rte_flow_item_meter_color_mask; 13729 break; 13730 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13731 mask = &ipv6_routing_ext_default_mask; 13732 break; 13733 case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: 13734 mask = &rte_flow_item_aggr_affinity_mask; 13735 break; 13736 case RTE_FLOW_ITEM_TYPE_TX_QUEUE: 13737 mask = &rte_flow_item_tx_queue_mask; 13738 break; 13739 case RTE_FLOW_ITEM_TYPE_IB_BTH: 13740 mask = &rte_flow_item_ib_bth_mask; 13741 break; 13742 case RTE_FLOW_ITEM_TYPE_PTYPE: 13743 mask = &rte_flow_item_ptype_mask; 13744 break; 13745 default: 13746 break; 13747 } 13748 return mask; 13749 } 13750 13751 /** Dispatch parsed buffer to function calls. */ 13752 static void 13753 cmd_set_ipv6_ext_parsed(const struct buffer *in) 13754 { 13755 uint32_t n = in->args.vc.pattern_n; 13756 int i = 0; 13757 struct rte_flow_item *item = NULL; 13758 size_t size = 0; 13759 uint8_t *data = NULL; 13760 uint8_t *type = NULL; 13761 size_t *total_size = NULL; 13762 uint16_t idx = in->port; /* We borrow port field as index */ 13763 struct rte_flow_item_ipv6_routing_ext *ext; 13764 const struct rte_flow_item_ipv6_ext *ipv6_ext; 13765 13766 RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || 13767 in->command == SET_IPV6_EXT_REMOVE); 13768 13769 if (in->command == SET_IPV6_EXT_REMOVE) { 13770 if (n != 1 || in->args.vc.pattern->type != 13771 RTE_FLOW_ITEM_TYPE_IPV6_EXT) { 13772 fprintf(stderr, "Error - Not supported item\n"); 13773 return; 13774 } 13775 type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; 13776 item = in->args.vc.pattern; 13777 ipv6_ext = item->spec; 13778 *type = ipv6_ext->next_hdr; 13779 return; 13780 } 13781 13782 total_size = &ipv6_ext_push_confs[idx].size; 13783 data = (uint8_t *)&ipv6_ext_push_confs[idx].data; 13784 type = (uint8_t *)&ipv6_ext_push_confs[idx].type; 13785 13786 *total_size = 0; 13787 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13788 for (i = n - 1 ; i >= 0; --i) { 13789 item = in->args.vc.pattern + i; 13790 switch (item->type) { 13791 case RTE_FLOW_ITEM_TYPE_IPV6_EXT: 13792 ipv6_ext = item->spec; 13793 *type = ipv6_ext->next_hdr; 13794 break; 13795 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13796 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13797 if (!ext->hdr.hdr_len) { 13798 size = sizeof(struct rte_ipv6_routing_ext) + 13799 (ext->hdr.segments_left << 4); 13800 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13801 /* Indicate no TLV once SRH. */ 13802 if (ext->hdr.type == 4) 13803 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13804 } else { 13805 size = sizeof(struct rte_ipv6_routing_ext) + 13806 (ext->hdr.hdr_len << 3); 13807 } 13808 *total_size += size; 13809 memcpy(data, ext, size); 13810 break; 13811 default: 13812 fprintf(stderr, "Error - Not supported item\n"); 13813 goto error; 13814 } 13815 } 13816 RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); 13817 return; 13818 error: 13819 *total_size = 0; 13820 memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); 13821 } 13822 13823 /** Dispatch parsed buffer to function calls. */ 13824 static void 13825 cmd_set_raw_parsed_sample(const struct buffer *in) 13826 { 13827 uint32_t n = in->args.vc.actions_n; 13828 uint32_t i = 0; 13829 struct rte_flow_action *action = NULL; 13830 struct rte_flow_action *data = NULL; 13831 const struct rte_flow_action_rss *rss = NULL; 13832 size_t size = 0; 13833 uint16_t idx = in->port; /* We borrow port field as index */ 13834 uint32_t max_size = sizeof(struct rte_flow_action) * 13835 ACTION_SAMPLE_ACTIONS_NUM; 13836 13837 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 13838 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 13839 memset(data, 0x00, max_size); 13840 for (; i <= n - 1; i++) { 13841 action = in->args.vc.actions + i; 13842 if (action->type == RTE_FLOW_ACTION_TYPE_END) 13843 break; 13844 switch (action->type) { 13845 case RTE_FLOW_ACTION_TYPE_MARK: 13846 size = sizeof(struct rte_flow_action_mark); 13847 rte_memcpy(&sample_mark[idx], 13848 (const void *)action->conf, size); 13849 action->conf = &sample_mark[idx]; 13850 break; 13851 case RTE_FLOW_ACTION_TYPE_COUNT: 13852 size = sizeof(struct rte_flow_action_count); 13853 rte_memcpy(&sample_count[idx], 13854 (const void *)action->conf, size); 13855 action->conf = &sample_count[idx]; 13856 break; 13857 case RTE_FLOW_ACTION_TYPE_QUEUE: 13858 size = sizeof(struct rte_flow_action_queue); 13859 rte_memcpy(&sample_queue[idx], 13860 (const void *)action->conf, size); 13861 action->conf = &sample_queue[idx]; 13862 break; 13863 case RTE_FLOW_ACTION_TYPE_RSS: 13864 size = sizeof(struct rte_flow_action_rss); 13865 rss = action->conf; 13866 rte_memcpy(&sample_rss_data[idx].conf, 13867 (const void *)rss, size); 13868 if (rss->key_len && rss->key) { 13869 sample_rss_data[idx].conf.key = 13870 sample_rss_data[idx].key; 13871 rte_memcpy((void *)((uintptr_t) 13872 sample_rss_data[idx].conf.key), 13873 (const void *)rss->key, 13874 sizeof(uint8_t) * rss->key_len); 13875 } 13876 if (rss->queue_num && rss->queue) { 13877 sample_rss_data[idx].conf.queue = 13878 sample_rss_data[idx].queue; 13879 rte_memcpy((void *)((uintptr_t) 13880 sample_rss_data[idx].conf.queue), 13881 (const void *)rss->queue, 13882 sizeof(uint16_t) * rss->queue_num); 13883 } 13884 action->conf = &sample_rss_data[idx].conf; 13885 break; 13886 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 13887 size = sizeof(struct rte_flow_action_raw_encap); 13888 rte_memcpy(&sample_encap[idx], 13889 (const void *)action->conf, size); 13890 action->conf = &sample_encap[idx]; 13891 break; 13892 case RTE_FLOW_ACTION_TYPE_PORT_ID: 13893 size = sizeof(struct rte_flow_action_port_id); 13894 rte_memcpy(&sample_port_id[idx], 13895 (const void *)action->conf, size); 13896 action->conf = &sample_port_id[idx]; 13897 break; 13898 case RTE_FLOW_ACTION_TYPE_PF: 13899 break; 13900 case RTE_FLOW_ACTION_TYPE_VF: 13901 size = sizeof(struct rte_flow_action_vf); 13902 rte_memcpy(&sample_vf[idx], 13903 (const void *)action->conf, size); 13904 action->conf = &sample_vf[idx]; 13905 break; 13906 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 13907 size = sizeof(struct rte_flow_action_vxlan_encap); 13908 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 13909 action->conf = &sample_vxlan_encap[idx].conf; 13910 break; 13911 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 13912 size = sizeof(struct rte_flow_action_nvgre_encap); 13913 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 13914 action->conf = &sample_nvgre_encap[idx]; 13915 break; 13916 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 13917 size = sizeof(struct rte_flow_action_ethdev); 13918 rte_memcpy(&sample_port_representor[idx], 13919 (const void *)action->conf, size); 13920 action->conf = &sample_port_representor[idx]; 13921 break; 13922 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 13923 size = sizeof(struct rte_flow_action_ethdev); 13924 rte_memcpy(&sample_represented_port[idx], 13925 (const void *)action->conf, size); 13926 action->conf = &sample_represented_port[idx]; 13927 break; 13928 default: 13929 fprintf(stderr, "Error - Not supported action\n"); 13930 return; 13931 } 13932 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 13933 data++; 13934 } 13935 } 13936 13937 /** Dispatch parsed buffer to function calls. */ 13938 static void 13939 cmd_set_raw_parsed(const struct buffer *in) 13940 { 13941 uint32_t n = in->args.vc.pattern_n; 13942 int i = 0; 13943 struct rte_flow_item *item = NULL; 13944 size_t size = 0; 13945 uint8_t *data = NULL; 13946 uint8_t *data_tail = NULL; 13947 size_t *total_size = NULL; 13948 uint16_t upper_layer = 0; 13949 uint16_t proto = 0; 13950 uint16_t idx = in->port; /* We borrow port field as index */ 13951 int gtp_psc = -1; /* GTP PSC option index. */ 13952 const void *src_spec; 13953 13954 if (in->command == SET_SAMPLE_ACTIONS) 13955 return cmd_set_raw_parsed_sample(in); 13956 else if (in->command == SET_IPV6_EXT_PUSH || 13957 in->command == SET_IPV6_EXT_REMOVE) 13958 return cmd_set_ipv6_ext_parsed(in); 13959 RTE_ASSERT(in->command == SET_RAW_ENCAP || 13960 in->command == SET_RAW_DECAP); 13961 if (in->command == SET_RAW_ENCAP) { 13962 total_size = &raw_encap_confs[idx].size; 13963 data = (uint8_t *)&raw_encap_confs[idx].data; 13964 } else { 13965 total_size = &raw_decap_confs[idx].size; 13966 data = (uint8_t *)&raw_decap_confs[idx].data; 13967 } 13968 *total_size = 0; 13969 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13970 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 13971 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 13972 for (i = n - 1 ; i >= 0; --i) { 13973 const struct rte_flow_item_gtp *gtp; 13974 const struct rte_flow_item_geneve_opt *opt; 13975 struct rte_flow_item_ipv6_routing_ext *ext; 13976 13977 item = in->args.vc.pattern + i; 13978 if (item->spec == NULL) 13979 item->spec = flow_item_default_mask(item); 13980 src_spec = item->spec; 13981 switch (item->type) { 13982 case RTE_FLOW_ITEM_TYPE_ETH: 13983 size = sizeof(struct rte_ether_hdr); 13984 break; 13985 case RTE_FLOW_ITEM_TYPE_VLAN: 13986 size = sizeof(struct rte_vlan_hdr); 13987 proto = RTE_ETHER_TYPE_VLAN; 13988 break; 13989 case RTE_FLOW_ITEM_TYPE_IPV4: 13990 size = sizeof(struct rte_ipv4_hdr); 13991 proto = RTE_ETHER_TYPE_IPV4; 13992 break; 13993 case RTE_FLOW_ITEM_TYPE_IPV6: 13994 size = sizeof(struct rte_ipv6_hdr); 13995 proto = RTE_ETHER_TYPE_IPV6; 13996 break; 13997 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13998 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13999 if (!ext->hdr.hdr_len) { 14000 size = sizeof(struct rte_ipv6_routing_ext) + 14001 (ext->hdr.segments_left << 4); 14002 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 14003 /* SRv6 without TLV. */ 14004 if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) 14005 ext->hdr.last_entry = ext->hdr.segments_left - 1; 14006 } else { 14007 size = sizeof(struct rte_ipv6_routing_ext) + 14008 (ext->hdr.hdr_len << 3); 14009 } 14010 proto = IPPROTO_ROUTING; 14011 break; 14012 case RTE_FLOW_ITEM_TYPE_UDP: 14013 size = sizeof(struct rte_udp_hdr); 14014 proto = 0x11; 14015 break; 14016 case RTE_FLOW_ITEM_TYPE_TCP: 14017 size = sizeof(struct rte_tcp_hdr); 14018 proto = 0x06; 14019 break; 14020 case RTE_FLOW_ITEM_TYPE_VXLAN: 14021 size = sizeof(struct rte_vxlan_hdr); 14022 break; 14023 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 14024 size = sizeof(struct rte_vxlan_gpe_hdr); 14025 break; 14026 case RTE_FLOW_ITEM_TYPE_GRE: 14027 size = sizeof(struct rte_gre_hdr); 14028 proto = 0x2F; 14029 break; 14030 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 14031 size = sizeof(rte_be32_t); 14032 proto = 0x0; 14033 break; 14034 case RTE_FLOW_ITEM_TYPE_MPLS: 14035 size = sizeof(struct rte_mpls_hdr); 14036 proto = 0x0; 14037 break; 14038 case RTE_FLOW_ITEM_TYPE_NVGRE: 14039 size = sizeof(struct rte_flow_item_nvgre); 14040 proto = 0x2F; 14041 break; 14042 case RTE_FLOW_ITEM_TYPE_GENEVE: 14043 size = sizeof(struct rte_geneve_hdr); 14044 break; 14045 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 14046 opt = (const struct rte_flow_item_geneve_opt *) 14047 item->spec; 14048 size = offsetof(struct rte_flow_item_geneve_opt, 14049 option_len) + sizeof(uint8_t); 14050 if (opt->option_len && opt->data) { 14051 *total_size += opt->option_len * 14052 sizeof(uint32_t); 14053 rte_memcpy(data_tail - (*total_size), 14054 opt->data, 14055 opt->option_len * sizeof(uint32_t)); 14056 } 14057 break; 14058 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 14059 size = sizeof(rte_be32_t); 14060 proto = 0x73; 14061 break; 14062 case RTE_FLOW_ITEM_TYPE_ESP: 14063 size = sizeof(struct rte_esp_hdr); 14064 proto = 0x32; 14065 break; 14066 case RTE_FLOW_ITEM_TYPE_AH: 14067 size = sizeof(struct rte_flow_item_ah); 14068 proto = 0x33; 14069 break; 14070 case RTE_FLOW_ITEM_TYPE_GTP: 14071 if (gtp_psc < 0) { 14072 size = sizeof(struct rte_gtp_hdr); 14073 break; 14074 } 14075 if (gtp_psc != i + 1) { 14076 fprintf(stderr, 14077 "Error - GTP PSC does not follow GTP\n"); 14078 goto error; 14079 } 14080 gtp = item->spec; 14081 if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { 14082 /* Only E flag should be set. */ 14083 fprintf(stderr, 14084 "Error - GTP unsupported flags\n"); 14085 goto error; 14086 } else { 14087 struct rte_gtp_hdr_ext_word ext_word = { 14088 .next_ext = 0x85 14089 }; 14090 14091 /* We have to add GTP header extra word. */ 14092 *total_size += sizeof(ext_word); 14093 rte_memcpy(data_tail - (*total_size), 14094 &ext_word, sizeof(ext_word)); 14095 } 14096 size = sizeof(struct rte_gtp_hdr); 14097 break; 14098 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 14099 if (gtp_psc >= 0) { 14100 fprintf(stderr, 14101 "Error - Multiple GTP PSC items\n"); 14102 goto error; 14103 } else { 14104 const struct rte_flow_item_gtp_psc 14105 *opt = item->spec; 14106 struct rte_gtp_psc_generic_hdr *hdr; 14107 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 14108 sizeof(int32_t)); 14109 14110 *total_size += hdr_size; 14111 hdr = (typeof(hdr))(data_tail - (*total_size)); 14112 memset(hdr, 0, hdr_size); 14113 *hdr = opt->hdr; 14114 hdr->ext_hdr_len = 1; 14115 gtp_psc = i; 14116 size = 0; 14117 } 14118 break; 14119 case RTE_FLOW_ITEM_TYPE_PFCP: 14120 size = sizeof(struct rte_flow_item_pfcp); 14121 break; 14122 case RTE_FLOW_ITEM_TYPE_FLEX: 14123 if (item->spec != NULL) { 14124 size = ((const struct rte_flow_item_flex *)item->spec)->length; 14125 src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; 14126 } else { 14127 size = 0; 14128 src_spec = NULL; 14129 } 14130 break; 14131 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 14132 size = 0; 14133 if (item->spec) { 14134 const struct rte_flow_item_gre_opt 14135 *opt = item->spec; 14136 if (opt->checksum_rsvd.checksum) { 14137 *total_size += 14138 sizeof(opt->checksum_rsvd); 14139 rte_memcpy(data_tail - (*total_size), 14140 &opt->checksum_rsvd, 14141 sizeof(opt->checksum_rsvd)); 14142 } 14143 if (opt->key.key) { 14144 *total_size += sizeof(opt->key.key); 14145 rte_memcpy(data_tail - (*total_size), 14146 &opt->key.key, 14147 sizeof(opt->key.key)); 14148 } 14149 if (opt->sequence.sequence) { 14150 *total_size += sizeof(opt->sequence.sequence); 14151 rte_memcpy(data_tail - (*total_size), 14152 &opt->sequence.sequence, 14153 sizeof(opt->sequence.sequence)); 14154 } 14155 } 14156 proto = 0x2F; 14157 break; 14158 default: 14159 fprintf(stderr, "Error - Not supported item\n"); 14160 goto error; 14161 } 14162 if (size) { 14163 *total_size += size; 14164 rte_memcpy(data_tail - (*total_size), src_spec, size); 14165 /* update some fields which cannot be set by cmdline */ 14166 update_fields((data_tail - (*total_size)), item, 14167 upper_layer); 14168 upper_layer = proto; 14169 } 14170 } 14171 if (verbose_level & 0x1) 14172 printf("total data size is %zu\n", (*total_size)); 14173 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 14174 memmove(data, (data_tail - (*total_size)), *total_size); 14175 return; 14176 14177 error: 14178 *total_size = 0; 14179 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 14180 } 14181 14182 /** Populate help strings for current token (cmdline API). */ 14183 static int 14184 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 14185 unsigned int size) 14186 { 14187 struct context *ctx = &cmd_flow_context; 14188 const struct token *token = &token_list[ctx->prev]; 14189 14190 (void)hdr; 14191 if (!size) 14192 return -1; 14193 /* Set token type and update global help with details. */ 14194 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 14195 if (token->help) 14196 cmd_set_raw.help_str = token->help; 14197 else 14198 cmd_set_raw.help_str = token->name; 14199 return 0; 14200 } 14201 14202 /** Token definition template (cmdline API). */ 14203 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 14204 .ops = &(struct cmdline_token_ops){ 14205 .parse = cmd_flow_parse, 14206 .complete_get_nb = cmd_flow_complete_get_nb, 14207 .complete_get_elt = cmd_flow_complete_get_elt, 14208 .get_help = cmd_set_raw_get_help, 14209 }, 14210 .offset = 0, 14211 }; 14212 14213 /** Populate the next dynamic token. */ 14214 static void 14215 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 14216 cmdline_parse_token_hdr_t **hdr_inst) 14217 { 14218 struct context *ctx = &cmd_flow_context; 14219 14220 /* Always reinitialize context before requesting the first token. */ 14221 if (!(hdr_inst - cmd_set_raw.tokens)) { 14222 cmd_flow_context_init(ctx); 14223 ctx->curr = START_SET; 14224 } 14225 /* Return NULL when no more tokens are expected. */ 14226 if (!ctx->next_num && (ctx->curr != START_SET)) { 14227 *hdr = NULL; 14228 return; 14229 } 14230 /* Determine if command should end here. */ 14231 if (ctx->eol && ctx->last && ctx->next_num) { 14232 const enum index *list = ctx->next[ctx->next_num - 1]; 14233 int i; 14234 14235 for (i = 0; list[i]; ++i) { 14236 if (list[i] != END) 14237 continue; 14238 *hdr = NULL; 14239 return; 14240 } 14241 } 14242 *hdr = &cmd_set_raw_token_hdr; 14243 } 14244 14245 /** Token generator and output processing callback (cmdline API). */ 14246 static void 14247 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 14248 { 14249 if (cl == NULL) 14250 cmd_set_raw_tok(arg0, arg2); 14251 else 14252 cmd_set_raw_parsed(arg0); 14253 } 14254 14255 /** Global parser instance (cmdline API). */ 14256 cmdline_parse_inst_t cmd_set_raw = { 14257 .f = cmd_set_raw_cb, 14258 .data = NULL, /**< Unused. */ 14259 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 14260 .tokens = { 14261 NULL, 14262 }, /**< Tokens are returned by cmd_flow_tok(). */ 14263 }; 14264 14265 /* *** display raw_encap/raw_decap buf */ 14266 struct cmd_show_set_raw_result { 14267 cmdline_fixed_string_t cmd_show; 14268 cmdline_fixed_string_t cmd_what; 14269 cmdline_fixed_string_t cmd_all; 14270 uint16_t cmd_index; 14271 }; 14272 14273 static void 14274 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 14275 { 14276 struct cmd_show_set_raw_result *res = parsed_result; 14277 uint16_t index = res->cmd_index; 14278 uint8_t all = 0; 14279 uint8_t *raw_data = NULL; 14280 size_t raw_size = 0; 14281 char title[16] = {0}; 14282 14283 RTE_SET_USED(cl); 14284 RTE_SET_USED(data); 14285 if (!strcmp(res->cmd_all, "all")) { 14286 all = 1; 14287 index = 0; 14288 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 14289 fprintf(stderr, "index should be 0-%u\n", 14290 RAW_ENCAP_CONFS_MAX_NUM - 1); 14291 return; 14292 } 14293 do { 14294 if (!strcmp(res->cmd_what, "raw_encap")) { 14295 raw_data = (uint8_t *)&raw_encap_confs[index].data; 14296 raw_size = raw_encap_confs[index].size; 14297 snprintf(title, 16, "\nindex: %u", index); 14298 rte_hexdump(stdout, title, raw_data, raw_size); 14299 } else { 14300 raw_data = (uint8_t *)&raw_decap_confs[index].data; 14301 raw_size = raw_decap_confs[index].size; 14302 snprintf(title, 16, "\nindex: %u", index); 14303 rte_hexdump(stdout, title, raw_data, raw_size); 14304 } 14305 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 14306 } 14307 14308 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 14309 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14310 cmd_show, "show"); 14311 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 14312 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14313 cmd_what, "raw_encap#raw_decap"); 14314 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 14315 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 14316 cmd_index, RTE_UINT16); 14317 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 14318 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14319 cmd_all, "all"); 14320 cmdline_parse_inst_t cmd_show_set_raw = { 14321 .f = cmd_show_set_raw_parsed, 14322 .data = NULL, 14323 .help_str = "show <raw_encap|raw_decap> <index>", 14324 .tokens = { 14325 (void *)&cmd_show_set_raw_cmd_show, 14326 (void *)&cmd_show_set_raw_cmd_what, 14327 (void *)&cmd_show_set_raw_cmd_index, 14328 NULL, 14329 }, 14330 }; 14331 cmdline_parse_inst_t cmd_show_set_raw_all = { 14332 .f = cmd_show_set_raw_parsed, 14333 .data = NULL, 14334 .help_str = "show <raw_encap|raw_decap> all", 14335 .tokens = { 14336 (void *)&cmd_show_set_raw_cmd_show, 14337 (void *)&cmd_show_set_raw_cmd_what, 14338 (void *)&cmd_show_set_raw_cmd_all, 14339 NULL, 14340 }, 14341 }; 14342