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 FLUSH, 95 DUMP, 96 QUERY, 97 LIST, 98 AGED, 99 ISOLATE, 100 TUNNEL, 101 FLEX, 102 QUEUE, 103 PUSH, 104 PULL, 105 HASH, 106 107 /* Flex arguments */ 108 FLEX_ITEM_INIT, 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 264 /* Dump arguments */ 265 DUMP_ALL, 266 DUMP_ONE, 267 DUMP_IS_USER_ID, 268 269 /* Configure arguments */ 270 CONFIG_QUEUES_NUMBER, 271 CONFIG_QUEUES_SIZE, 272 CONFIG_COUNTERS_NUMBER, 273 CONFIG_AGING_OBJECTS_NUMBER, 274 CONFIG_METERS_NUMBER, 275 CONFIG_CONN_TRACK_NUMBER, 276 CONFIG_QUOTAS_NUMBER, 277 CONFIG_FLAGS, 278 CONFIG_HOST_PORT, 279 280 /* Indirect action arguments */ 281 INDIRECT_ACTION_CREATE, 282 INDIRECT_ACTION_LIST_CREATE, 283 INDIRECT_ACTION_FLOW_CONF_CREATE, 284 INDIRECT_ACTION_UPDATE, 285 INDIRECT_ACTION_DESTROY, 286 INDIRECT_ACTION_QUERY, 287 INDIRECT_ACTION_QUERY_UPDATE, 288 289 /* Indirect action create arguments */ 290 INDIRECT_ACTION_CREATE_ID, 291 INDIRECT_ACTION_INGRESS, 292 INDIRECT_ACTION_EGRESS, 293 INDIRECT_ACTION_TRANSFER, 294 INDIRECT_ACTION_SPEC, 295 INDIRECT_ACTION_LIST, 296 INDIRECT_ACTION_FLOW_CONF, 297 298 /* Indirect action destroy arguments */ 299 INDIRECT_ACTION_DESTROY_ID, 300 301 /* Indirect action query-and-update arguments */ 302 INDIRECT_ACTION_QU_MODE, 303 INDIRECT_ACTION_QU_MODE_NAME, 304 305 /* Validate/create pattern. */ 306 ITEM_PATTERN, 307 ITEM_PARAM_IS, 308 ITEM_PARAM_SPEC, 309 ITEM_PARAM_LAST, 310 ITEM_PARAM_MASK, 311 ITEM_PARAM_PREFIX, 312 ITEM_NEXT, 313 ITEM_END, 314 ITEM_VOID, 315 ITEM_INVERT, 316 ITEM_ANY, 317 ITEM_ANY_NUM, 318 ITEM_PORT_ID, 319 ITEM_PORT_ID_ID, 320 ITEM_MARK, 321 ITEM_MARK_ID, 322 ITEM_RAW, 323 ITEM_RAW_RELATIVE, 324 ITEM_RAW_SEARCH, 325 ITEM_RAW_OFFSET, 326 ITEM_RAW_LIMIT, 327 ITEM_RAW_PATTERN, 328 ITEM_RAW_PATTERN_HEX, 329 ITEM_ETH, 330 ITEM_ETH_DST, 331 ITEM_ETH_SRC, 332 ITEM_ETH_TYPE, 333 ITEM_ETH_HAS_VLAN, 334 ITEM_VLAN, 335 ITEM_VLAN_TCI, 336 ITEM_VLAN_PCP, 337 ITEM_VLAN_DEI, 338 ITEM_VLAN_VID, 339 ITEM_VLAN_INNER_TYPE, 340 ITEM_VLAN_HAS_MORE_VLAN, 341 ITEM_IPV4, 342 ITEM_IPV4_VER_IHL, 343 ITEM_IPV4_TOS, 344 ITEM_IPV4_LENGTH, 345 ITEM_IPV4_ID, 346 ITEM_IPV4_FRAGMENT_OFFSET, 347 ITEM_IPV4_TTL, 348 ITEM_IPV4_PROTO, 349 ITEM_IPV4_SRC, 350 ITEM_IPV4_DST, 351 ITEM_IPV6, 352 ITEM_IPV6_TC, 353 ITEM_IPV6_FLOW, 354 ITEM_IPV6_LEN, 355 ITEM_IPV6_PROTO, 356 ITEM_IPV6_HOP, 357 ITEM_IPV6_SRC, 358 ITEM_IPV6_DST, 359 ITEM_IPV6_HAS_FRAG_EXT, 360 ITEM_IPV6_ROUTING_EXT, 361 ITEM_IPV6_ROUTING_EXT_TYPE, 362 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 363 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 364 ITEM_ICMP, 365 ITEM_ICMP_TYPE, 366 ITEM_ICMP_CODE, 367 ITEM_ICMP_IDENT, 368 ITEM_ICMP_SEQ, 369 ITEM_UDP, 370 ITEM_UDP_SRC, 371 ITEM_UDP_DST, 372 ITEM_TCP, 373 ITEM_TCP_SRC, 374 ITEM_TCP_DST, 375 ITEM_TCP_FLAGS, 376 ITEM_SCTP, 377 ITEM_SCTP_SRC, 378 ITEM_SCTP_DST, 379 ITEM_SCTP_TAG, 380 ITEM_SCTP_CKSUM, 381 ITEM_VXLAN, 382 ITEM_VXLAN_VNI, 383 ITEM_VXLAN_LAST_RSVD, 384 ITEM_E_TAG, 385 ITEM_E_TAG_GRP_ECID_B, 386 ITEM_NVGRE, 387 ITEM_NVGRE_TNI, 388 ITEM_MPLS, 389 ITEM_MPLS_LABEL, 390 ITEM_MPLS_TC, 391 ITEM_MPLS_S, 392 ITEM_MPLS_TTL, 393 ITEM_GRE, 394 ITEM_GRE_PROTO, 395 ITEM_GRE_C_RSVD0_VER, 396 ITEM_GRE_C_BIT, 397 ITEM_GRE_K_BIT, 398 ITEM_GRE_S_BIT, 399 ITEM_FUZZY, 400 ITEM_FUZZY_THRESH, 401 ITEM_GTP, 402 ITEM_GTP_FLAGS, 403 ITEM_GTP_MSG_TYPE, 404 ITEM_GTP_TEID, 405 ITEM_GTPC, 406 ITEM_GTPU, 407 ITEM_GENEVE, 408 ITEM_GENEVE_VNI, 409 ITEM_GENEVE_PROTO, 410 ITEM_GENEVE_OPTLEN, 411 ITEM_VXLAN_GPE, 412 ITEM_VXLAN_GPE_VNI, 413 ITEM_VXLAN_GPE_PROTO, 414 ITEM_VXLAN_GPE_FLAGS, 415 ITEM_VXLAN_GPE_RSVD0, 416 ITEM_VXLAN_GPE_RSVD1, 417 ITEM_ARP_ETH_IPV4, 418 ITEM_ARP_ETH_IPV4_SHA, 419 ITEM_ARP_ETH_IPV4_SPA, 420 ITEM_ARP_ETH_IPV4_THA, 421 ITEM_ARP_ETH_IPV4_TPA, 422 ITEM_IPV6_EXT, 423 ITEM_IPV6_EXT_NEXT_HDR, 424 ITEM_IPV6_FRAG_EXT, 425 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 426 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 427 ITEM_IPV6_FRAG_EXT_ID, 428 ITEM_ICMP6, 429 ITEM_ICMP6_TYPE, 430 ITEM_ICMP6_CODE, 431 ITEM_ICMP6_ECHO_REQUEST, 432 ITEM_ICMP6_ECHO_REQUEST_ID, 433 ITEM_ICMP6_ECHO_REQUEST_SEQ, 434 ITEM_ICMP6_ECHO_REPLY, 435 ITEM_ICMP6_ECHO_REPLY_ID, 436 ITEM_ICMP6_ECHO_REPLY_SEQ, 437 ITEM_ICMP6_ND_NS, 438 ITEM_ICMP6_ND_NS_TARGET_ADDR, 439 ITEM_ICMP6_ND_NA, 440 ITEM_ICMP6_ND_NA_TARGET_ADDR, 441 ITEM_ICMP6_ND_OPT, 442 ITEM_ICMP6_ND_OPT_TYPE, 443 ITEM_ICMP6_ND_OPT_SLA_ETH, 444 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 445 ITEM_ICMP6_ND_OPT_TLA_ETH, 446 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 447 ITEM_META, 448 ITEM_META_DATA, 449 ITEM_RANDOM, 450 ITEM_RANDOM_VALUE, 451 ITEM_GRE_KEY, 452 ITEM_GRE_KEY_VALUE, 453 ITEM_GRE_OPTION, 454 ITEM_GRE_OPTION_CHECKSUM, 455 ITEM_GRE_OPTION_KEY, 456 ITEM_GRE_OPTION_SEQUENCE, 457 ITEM_GTP_PSC, 458 ITEM_GTP_PSC_QFI, 459 ITEM_GTP_PSC_PDU_T, 460 ITEM_PPPOES, 461 ITEM_PPPOED, 462 ITEM_PPPOE_SEID, 463 ITEM_PPPOE_PROTO_ID, 464 ITEM_HIGIG2, 465 ITEM_HIGIG2_CLASSIFICATION, 466 ITEM_HIGIG2_VID, 467 ITEM_TAG, 468 ITEM_TAG_DATA, 469 ITEM_TAG_INDEX, 470 ITEM_L2TPV3OIP, 471 ITEM_L2TPV3OIP_SESSION_ID, 472 ITEM_ESP, 473 ITEM_ESP_SPI, 474 ITEM_AH, 475 ITEM_AH_SPI, 476 ITEM_PFCP, 477 ITEM_PFCP_S_FIELD, 478 ITEM_PFCP_SEID, 479 ITEM_ECPRI, 480 ITEM_ECPRI_COMMON, 481 ITEM_ECPRI_COMMON_TYPE, 482 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 483 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 484 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 485 ITEM_ECPRI_MSG_IQ_DATA_PCID, 486 ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 487 ITEM_ECPRI_MSG_DLY_MSR_MSRID, 488 ITEM_GENEVE_OPT, 489 ITEM_GENEVE_OPT_CLASS, 490 ITEM_GENEVE_OPT_TYPE, 491 ITEM_GENEVE_OPT_LENGTH, 492 ITEM_GENEVE_OPT_DATA, 493 ITEM_INTEGRITY, 494 ITEM_INTEGRITY_LEVEL, 495 ITEM_INTEGRITY_VALUE, 496 ITEM_CONNTRACK, 497 ITEM_POL_PORT, 498 ITEM_POL_METER, 499 ITEM_POL_POLICY, 500 ITEM_PORT_REPRESENTOR, 501 ITEM_PORT_REPRESENTOR_PORT_ID, 502 ITEM_REPRESENTED_PORT, 503 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 504 ITEM_FLEX, 505 ITEM_FLEX_ITEM_HANDLE, 506 ITEM_FLEX_PATTERN_HANDLE, 507 ITEM_L2TPV2, 508 ITEM_L2TPV2_TYPE, 509 ITEM_L2TPV2_TYPE_DATA, 510 ITEM_L2TPV2_TYPE_DATA_L, 511 ITEM_L2TPV2_TYPE_DATA_S, 512 ITEM_L2TPV2_TYPE_DATA_O, 513 ITEM_L2TPV2_TYPE_DATA_L_S, 514 ITEM_L2TPV2_TYPE_CTRL, 515 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 516 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 517 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 518 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 519 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 520 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 521 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 522 ITEM_L2TPV2_MSG_DATA_S_NS, 523 ITEM_L2TPV2_MSG_DATA_S_NR, 524 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 525 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 526 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 527 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 528 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 529 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 530 ITEM_L2TPV2_MSG_DATA_L_S_NS, 531 ITEM_L2TPV2_MSG_DATA_L_S_NR, 532 ITEM_L2TPV2_MSG_CTRL_LENGTH, 533 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 534 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 535 ITEM_L2TPV2_MSG_CTRL_NS, 536 ITEM_L2TPV2_MSG_CTRL_NR, 537 ITEM_PPP, 538 ITEM_PPP_ADDR, 539 ITEM_PPP_CTRL, 540 ITEM_PPP_PROTO_ID, 541 ITEM_METER, 542 ITEM_METER_COLOR, 543 ITEM_METER_COLOR_NAME, 544 ITEM_QUOTA, 545 ITEM_QUOTA_STATE, 546 ITEM_QUOTA_STATE_NAME, 547 ITEM_AGGR_AFFINITY, 548 ITEM_AGGR_AFFINITY_VALUE, 549 ITEM_TX_QUEUE, 550 ITEM_TX_QUEUE_VALUE, 551 ITEM_IB_BTH, 552 ITEM_IB_BTH_OPCODE, 553 ITEM_IB_BTH_PKEY, 554 ITEM_IB_BTH_DST_QPN, 555 ITEM_IB_BTH_PSN, 556 ITEM_IPV6_PUSH_REMOVE_EXT, 557 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 558 ITEM_PTYPE, 559 ITEM_PTYPE_VALUE, 560 ITEM_NSH, 561 ITEM_COMPARE, 562 ITEM_COMPARE_OP, 563 ITEM_COMPARE_OP_VALUE, 564 ITEM_COMPARE_FIELD_A_TYPE, 565 ITEM_COMPARE_FIELD_A_TYPE_VALUE, 566 ITEM_COMPARE_FIELD_A_LEVEL, 567 ITEM_COMPARE_FIELD_A_LEVEL_VALUE, 568 ITEM_COMPARE_FIELD_A_TAG_INDEX, 569 ITEM_COMPARE_FIELD_A_TYPE_ID, 570 ITEM_COMPARE_FIELD_A_CLASS_ID, 571 ITEM_COMPARE_FIELD_A_OFFSET, 572 ITEM_COMPARE_FIELD_B_TYPE, 573 ITEM_COMPARE_FIELD_B_TYPE_VALUE, 574 ITEM_COMPARE_FIELD_B_LEVEL, 575 ITEM_COMPARE_FIELD_B_LEVEL_VALUE, 576 ITEM_COMPARE_FIELD_B_TAG_INDEX, 577 ITEM_COMPARE_FIELD_B_TYPE_ID, 578 ITEM_COMPARE_FIELD_B_CLASS_ID, 579 ITEM_COMPARE_FIELD_B_OFFSET, 580 ITEM_COMPARE_FIELD_B_VALUE, 581 ITEM_COMPARE_FIELD_B_POINTER, 582 ITEM_COMPARE_FIELD_WIDTH, 583 584 /* Validate/create actions. */ 585 ACTIONS, 586 ACTION_NEXT, 587 ACTION_END, 588 ACTION_VOID, 589 ACTION_PASSTHRU, 590 ACTION_SKIP_CMAN, 591 ACTION_JUMP, 592 ACTION_JUMP_GROUP, 593 ACTION_MARK, 594 ACTION_MARK_ID, 595 ACTION_FLAG, 596 ACTION_QUEUE, 597 ACTION_QUEUE_INDEX, 598 ACTION_DROP, 599 ACTION_COUNT, 600 ACTION_COUNT_ID, 601 ACTION_RSS, 602 ACTION_RSS_FUNC, 603 ACTION_RSS_LEVEL, 604 ACTION_RSS_FUNC_DEFAULT, 605 ACTION_RSS_FUNC_TOEPLITZ, 606 ACTION_RSS_FUNC_SIMPLE_XOR, 607 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, 608 ACTION_RSS_TYPES, 609 ACTION_RSS_TYPE, 610 ACTION_RSS_KEY, 611 ACTION_RSS_KEY_LEN, 612 ACTION_RSS_QUEUES, 613 ACTION_RSS_QUEUE, 614 ACTION_PF, 615 ACTION_VF, 616 ACTION_VF_ORIGINAL, 617 ACTION_VF_ID, 618 ACTION_PORT_ID, 619 ACTION_PORT_ID_ORIGINAL, 620 ACTION_PORT_ID_ID, 621 ACTION_METER, 622 ACTION_METER_COLOR, 623 ACTION_METER_COLOR_TYPE, 624 ACTION_METER_COLOR_GREEN, 625 ACTION_METER_COLOR_YELLOW, 626 ACTION_METER_COLOR_RED, 627 ACTION_METER_ID, 628 ACTION_METER_MARK, 629 ACTION_METER_PROFILE, 630 ACTION_METER_PROFILE_ID2PTR, 631 ACTION_METER_POLICY, 632 ACTION_METER_POLICY_ID2PTR, 633 ACTION_METER_COLOR_MODE, 634 ACTION_METER_STATE, 635 ACTION_OF_DEC_NW_TTL, 636 ACTION_OF_POP_VLAN, 637 ACTION_OF_PUSH_VLAN, 638 ACTION_OF_PUSH_VLAN_ETHERTYPE, 639 ACTION_OF_SET_VLAN_VID, 640 ACTION_OF_SET_VLAN_VID_VLAN_VID, 641 ACTION_OF_SET_VLAN_PCP, 642 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 643 ACTION_OF_POP_MPLS, 644 ACTION_OF_POP_MPLS_ETHERTYPE, 645 ACTION_OF_PUSH_MPLS, 646 ACTION_OF_PUSH_MPLS_ETHERTYPE, 647 ACTION_VXLAN_ENCAP, 648 ACTION_VXLAN_DECAP, 649 ACTION_NVGRE_ENCAP, 650 ACTION_NVGRE_DECAP, 651 ACTION_L2_ENCAP, 652 ACTION_L2_DECAP, 653 ACTION_MPLSOGRE_ENCAP, 654 ACTION_MPLSOGRE_DECAP, 655 ACTION_MPLSOUDP_ENCAP, 656 ACTION_MPLSOUDP_DECAP, 657 ACTION_SET_IPV4_SRC, 658 ACTION_SET_IPV4_SRC_IPV4_SRC, 659 ACTION_SET_IPV4_DST, 660 ACTION_SET_IPV4_DST_IPV4_DST, 661 ACTION_SET_IPV6_SRC, 662 ACTION_SET_IPV6_SRC_IPV6_SRC, 663 ACTION_SET_IPV6_DST, 664 ACTION_SET_IPV6_DST_IPV6_DST, 665 ACTION_SET_TP_SRC, 666 ACTION_SET_TP_SRC_TP_SRC, 667 ACTION_SET_TP_DST, 668 ACTION_SET_TP_DST_TP_DST, 669 ACTION_MAC_SWAP, 670 ACTION_DEC_TTL, 671 ACTION_SET_TTL, 672 ACTION_SET_TTL_TTL, 673 ACTION_SET_MAC_SRC, 674 ACTION_SET_MAC_SRC_MAC_SRC, 675 ACTION_SET_MAC_DST, 676 ACTION_SET_MAC_DST_MAC_DST, 677 ACTION_INC_TCP_SEQ, 678 ACTION_INC_TCP_SEQ_VALUE, 679 ACTION_DEC_TCP_SEQ, 680 ACTION_DEC_TCP_SEQ_VALUE, 681 ACTION_INC_TCP_ACK, 682 ACTION_INC_TCP_ACK_VALUE, 683 ACTION_DEC_TCP_ACK, 684 ACTION_DEC_TCP_ACK_VALUE, 685 ACTION_RAW_ENCAP, 686 ACTION_RAW_DECAP, 687 ACTION_RAW_ENCAP_SIZE, 688 ACTION_RAW_ENCAP_INDEX, 689 ACTION_RAW_ENCAP_INDEX_VALUE, 690 ACTION_RAW_DECAP_INDEX, 691 ACTION_RAW_DECAP_INDEX_VALUE, 692 ACTION_SET_TAG, 693 ACTION_SET_TAG_DATA, 694 ACTION_SET_TAG_INDEX, 695 ACTION_SET_TAG_MASK, 696 ACTION_SET_META, 697 ACTION_SET_META_DATA, 698 ACTION_SET_META_MASK, 699 ACTION_SET_IPV4_DSCP, 700 ACTION_SET_IPV4_DSCP_VALUE, 701 ACTION_SET_IPV6_DSCP, 702 ACTION_SET_IPV6_DSCP_VALUE, 703 ACTION_AGE, 704 ACTION_AGE_TIMEOUT, 705 ACTION_AGE_UPDATE, 706 ACTION_AGE_UPDATE_TIMEOUT, 707 ACTION_AGE_UPDATE_TOUCH, 708 ACTION_SAMPLE, 709 ACTION_SAMPLE_RATIO, 710 ACTION_SAMPLE_INDEX, 711 ACTION_SAMPLE_INDEX_VALUE, 712 ACTION_INDIRECT, 713 ACTION_INDIRECT_LIST, 714 ACTION_INDIRECT_LIST_HANDLE, 715 ACTION_INDIRECT_LIST_CONF, 716 INDIRECT_LIST_ACTION_ID2PTR_HANDLE, 717 INDIRECT_LIST_ACTION_ID2PTR_CONF, 718 ACTION_SHARED_INDIRECT, 719 INDIRECT_ACTION_PORT, 720 INDIRECT_ACTION_ID2PTR, 721 ACTION_MODIFY_FIELD, 722 ACTION_MODIFY_FIELD_OP, 723 ACTION_MODIFY_FIELD_OP_VALUE, 724 ACTION_MODIFY_FIELD_DST_TYPE, 725 ACTION_MODIFY_FIELD_DST_TYPE_VALUE, 726 ACTION_MODIFY_FIELD_DST_LEVEL, 727 ACTION_MODIFY_FIELD_DST_LEVEL_VALUE, 728 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 729 ACTION_MODIFY_FIELD_DST_TYPE_ID, 730 ACTION_MODIFY_FIELD_DST_CLASS_ID, 731 ACTION_MODIFY_FIELD_DST_OFFSET, 732 ACTION_MODIFY_FIELD_SRC_TYPE, 733 ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, 734 ACTION_MODIFY_FIELD_SRC_LEVEL, 735 ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE, 736 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 737 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 738 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 739 ACTION_MODIFY_FIELD_SRC_OFFSET, 740 ACTION_MODIFY_FIELD_SRC_VALUE, 741 ACTION_MODIFY_FIELD_SRC_POINTER, 742 ACTION_MODIFY_FIELD_WIDTH, 743 ACTION_CONNTRACK, 744 ACTION_CONNTRACK_UPDATE, 745 ACTION_CONNTRACK_UPDATE_DIR, 746 ACTION_CONNTRACK_UPDATE_CTX, 747 ACTION_POL_G, 748 ACTION_POL_Y, 749 ACTION_POL_R, 750 ACTION_PORT_REPRESENTOR, 751 ACTION_PORT_REPRESENTOR_PORT_ID, 752 ACTION_REPRESENTED_PORT, 753 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 754 ACTION_SEND_TO_KERNEL, 755 ACTION_QUOTA_CREATE, 756 ACTION_QUOTA_CREATE_LIMIT, 757 ACTION_QUOTA_CREATE_MODE, 758 ACTION_QUOTA_CREATE_MODE_NAME, 759 ACTION_QUOTA_QU, 760 ACTION_QUOTA_QU_LIMIT, 761 ACTION_QUOTA_QU_UPDATE_OP, 762 ACTION_QUOTA_QU_UPDATE_OP_NAME, 763 ACTION_IPV6_EXT_REMOVE, 764 ACTION_IPV6_EXT_REMOVE_INDEX, 765 ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, 766 ACTION_IPV6_EXT_PUSH, 767 ACTION_IPV6_EXT_PUSH_INDEX, 768 ACTION_IPV6_EXT_PUSH_INDEX_VALUE, 769 ACTION_NAT64, 770 ACTION_NAT64_MODE, 771 }; 772 773 /** Maximum size for pattern in struct rte_flow_item_raw. */ 774 #define ITEM_RAW_PATTERN_SIZE 512 775 776 /** Maximum size for GENEVE option data pattern in bytes. */ 777 #define ITEM_GENEVE_OPT_DATA_SIZE 124 778 779 /** Storage size for struct rte_flow_item_raw including pattern. */ 780 #define ITEM_RAW_SIZE \ 781 (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) 782 783 static const char *const compare_ops[] = { 784 "eq", "ne", "lt", "le", "gt", "ge", NULL 785 }; 786 787 /** Maximum size for external pattern in struct rte_flow_field_data. */ 788 #define FLOW_FIELD_PATTERN_SIZE 32 789 790 /** Storage size for struct rte_flow_action_modify_field including pattern. */ 791 #define ACTION_MODIFY_SIZE \ 792 (sizeof(struct rte_flow_action_modify_field) + \ 793 FLOW_FIELD_PATTERN_SIZE) 794 795 /** Maximum number of queue indices in struct rte_flow_action_rss. */ 796 #define ACTION_RSS_QUEUE_NUM 128 797 798 /** Storage for struct rte_flow_action_rss including external data. */ 799 struct action_rss_data { 800 struct rte_flow_action_rss conf; 801 uint8_t key[RSS_HASH_KEY_LENGTH]; 802 uint16_t queue[ACTION_RSS_QUEUE_NUM]; 803 }; 804 805 /** Maximum data size in struct rte_flow_action_raw_encap. */ 806 #define ACTION_RAW_ENCAP_MAX_DATA 512 807 #define RAW_ENCAP_CONFS_MAX_NUM 8 808 809 /** Storage for struct rte_flow_action_raw_encap. */ 810 struct raw_encap_conf { 811 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 812 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 813 size_t size; 814 }; 815 816 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 817 818 /** Storage for struct rte_flow_action_raw_encap including external data. */ 819 struct action_raw_encap_data { 820 struct rte_flow_action_raw_encap conf; 821 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 822 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 823 uint16_t idx; 824 }; 825 826 /** Storage for struct rte_flow_action_raw_decap. */ 827 struct raw_decap_conf { 828 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 829 size_t size; 830 }; 831 832 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 833 834 /** Storage for struct rte_flow_action_raw_decap including external data. */ 835 struct action_raw_decap_data { 836 struct rte_flow_action_raw_decap conf; 837 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 838 uint16_t idx; 839 }; 840 841 /** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ 842 #define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 843 #define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 844 845 /** Storage for struct rte_flow_action_ipv6_ext_push. */ 846 struct ipv6_ext_push_conf { 847 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 848 size_t size; 849 uint8_t type; 850 }; 851 852 struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 853 854 /** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ 855 struct action_ipv6_ext_push_data { 856 struct rte_flow_action_ipv6_ext_push conf; 857 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 858 uint8_t type; 859 uint16_t idx; 860 }; 861 862 /** Storage for struct rte_flow_action_ipv6_ext_remove. */ 863 struct ipv6_ext_remove_conf { 864 struct rte_flow_action_ipv6_ext_remove conf; 865 uint8_t type; 866 }; 867 868 struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 869 870 /** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ 871 struct action_ipv6_ext_remove_data { 872 struct rte_flow_action_ipv6_ext_remove conf; 873 uint8_t type; 874 uint16_t idx; 875 }; 876 877 struct vxlan_encap_conf vxlan_encap_conf = { 878 .select_ipv4 = 1, 879 .select_vlan = 0, 880 .select_tos_ttl = 0, 881 .vni = "\x00\x00\x00", 882 .udp_src = 0, 883 .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), 884 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 885 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 886 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 887 "\x00\x00\x00\x00\x00\x00\x00\x01", 888 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 889 "\x00\x00\x00\x00\x00\x00\x11\x11", 890 .vlan_tci = 0, 891 .ip_tos = 0, 892 .ip_ttl = 255, 893 .eth_src = "\x00\x00\x00\x00\x00\x00", 894 .eth_dst = "\xff\xff\xff\xff\xff\xff", 895 }; 896 897 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */ 898 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6 899 900 /** Storage for struct rte_flow_action_vxlan_encap including external data. */ 901 struct action_vxlan_encap_data { 902 struct rte_flow_action_vxlan_encap conf; 903 struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; 904 struct rte_flow_item_eth item_eth; 905 struct rte_flow_item_vlan item_vlan; 906 union { 907 struct rte_flow_item_ipv4 item_ipv4; 908 struct rte_flow_item_ipv6 item_ipv6; 909 }; 910 struct rte_flow_item_udp item_udp; 911 struct rte_flow_item_vxlan item_vxlan; 912 }; 913 914 struct nvgre_encap_conf nvgre_encap_conf = { 915 .select_ipv4 = 1, 916 .select_vlan = 0, 917 .tni = "\x00\x00\x00", 918 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 919 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 920 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 921 "\x00\x00\x00\x00\x00\x00\x00\x01", 922 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 923 "\x00\x00\x00\x00\x00\x00\x11\x11", 924 .vlan_tci = 0, 925 .eth_src = "\x00\x00\x00\x00\x00\x00", 926 .eth_dst = "\xff\xff\xff\xff\xff\xff", 927 }; 928 929 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */ 930 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 931 932 /** Storage for struct rte_flow_action_nvgre_encap including external data. */ 933 struct action_nvgre_encap_data { 934 struct rte_flow_action_nvgre_encap conf; 935 struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; 936 struct rte_flow_item_eth item_eth; 937 struct rte_flow_item_vlan item_vlan; 938 union { 939 struct rte_flow_item_ipv4 item_ipv4; 940 struct rte_flow_item_ipv6 item_ipv6; 941 }; 942 struct rte_flow_item_nvgre item_nvgre; 943 }; 944 945 struct l2_encap_conf l2_encap_conf; 946 947 struct l2_decap_conf l2_decap_conf; 948 949 struct mplsogre_encap_conf mplsogre_encap_conf; 950 951 struct mplsogre_decap_conf mplsogre_decap_conf; 952 953 struct mplsoudp_encap_conf mplsoudp_encap_conf; 954 955 struct mplsoudp_decap_conf mplsoudp_decap_conf; 956 957 struct rte_flow_action_conntrack conntrack_context; 958 959 #define ACTION_SAMPLE_ACTIONS_NUM 10 960 #define RAW_SAMPLE_CONFS_MAX_NUM 8 961 /** Storage for struct rte_flow_action_sample including external data. */ 962 struct action_sample_data { 963 struct rte_flow_action_sample conf; 964 uint32_t idx; 965 }; 966 /** Storage for struct rte_flow_action_sample. */ 967 struct raw_sample_conf { 968 struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; 969 }; 970 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; 971 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; 972 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; 973 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; 974 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; 975 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 976 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 977 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 978 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; 979 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; 980 struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; 981 struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; 982 983 static const char *const modify_field_ops[] = { 984 "set", "add", "sub", NULL 985 }; 986 987 static const char *const flow_field_ids[] = { 988 "start", "mac_dst", "mac_src", 989 "vlan_type", "vlan_id", "mac_type", 990 "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", 991 "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", 992 "tcp_port_src", "tcp_port_dst", 993 "tcp_seq_num", "tcp_ack_num", "tcp_flags", 994 "udp_port_src", "udp_port_dst", 995 "vxlan_vni", "geneve_vni", "gtp_teid", 996 "tag", "mark", "meta", "pointer", "value", 997 "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", 998 "ipv6_proto", 999 "flex_item", 1000 "hash_result", 1001 "geneve_opt_type", "geneve_opt_class", "geneve_opt_data", "mpls", 1002 "tcp_data_off", "ipv4_ihl", "ipv4_total_len", "ipv6_payload_len", 1003 "random", 1004 "ipv4_proto", 1005 "esp_spi", "esp_seq_num", "esp_proto", 1006 "ipv6_flow_label", "ipv6_traffic_class", 1007 NULL 1008 }; 1009 1010 static const char *const meter_colors[] = { 1011 "green", "yellow", "red", "all", NULL 1012 }; 1013 1014 static const char *const table_insertion_types[] = { 1015 "pattern", "index", NULL 1016 }; 1017 1018 static const char *const table_hash_funcs[] = { 1019 "default", "linear", "crc32", "crc16", NULL 1020 }; 1021 1022 #define RAW_IPSEC_CONFS_MAX_NUM 8 1023 1024 /** Maximum number of subsequent tokens and arguments on the stack. */ 1025 #define CTX_STACK_SIZE 16 1026 1027 /** Parser context. */ 1028 struct context { 1029 /** Stack of subsequent token lists to process. */ 1030 const enum index *next[CTX_STACK_SIZE]; 1031 /** Arguments for stacked tokens. */ 1032 const void *args[CTX_STACK_SIZE]; 1033 enum index curr; /**< Current token index. */ 1034 enum index prev; /**< Index of the last token seen. */ 1035 int next_num; /**< Number of entries in next[]. */ 1036 int args_num; /**< Number of entries in args[]. */ 1037 uint32_t eol:1; /**< EOL has been detected. */ 1038 uint32_t last:1; /**< No more arguments. */ 1039 portid_t port; /**< Current port ID (for completions). */ 1040 uint32_t objdata; /**< Object-specific data. */ 1041 void *object; /**< Address of current object for relative offsets. */ 1042 void *objmask; /**< Object a full mask must be written to. */ 1043 }; 1044 1045 /** Token argument. */ 1046 struct arg { 1047 uint32_t hton:1; /**< Use network byte ordering. */ 1048 uint32_t sign:1; /**< Value is signed. */ 1049 uint32_t bounded:1; /**< Value is bounded. */ 1050 uintmax_t min; /**< Minimum value if bounded. */ 1051 uintmax_t max; /**< Maximum value if bounded. */ 1052 uint32_t offset; /**< Relative offset from ctx->object. */ 1053 uint32_t size; /**< Field size. */ 1054 const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ 1055 }; 1056 1057 /** Parser token definition. */ 1058 struct token { 1059 /** Type displayed during completion (defaults to "TOKEN"). */ 1060 const char *type; 1061 /** Help displayed during completion (defaults to token name). */ 1062 const char *help; 1063 /** Private data used by parser functions. */ 1064 const void *priv; 1065 /** 1066 * Lists of subsequent tokens to push on the stack. Each call to the 1067 * parser consumes the last entry of that stack. 1068 */ 1069 const enum index *const *next; 1070 /** Arguments stack for subsequent tokens that need them. */ 1071 const struct arg *const *args; 1072 /** 1073 * Token-processing callback, returns -1 in case of error, the 1074 * length of the matched string otherwise. If NULL, attempts to 1075 * match the token name. 1076 * 1077 * If buf is not NULL, the result should be stored in it according 1078 * to context. An error is returned if not large enough. 1079 */ 1080 int (*call)(struct context *ctx, const struct token *token, 1081 const char *str, unsigned int len, 1082 void *buf, unsigned int size); 1083 /** 1084 * Callback that provides possible values for this token, used for 1085 * completion. Returns -1 in case of error, the number of possible 1086 * values otherwise. If NULL, the token name is used. 1087 * 1088 * If buf is not NULL, entry index ent is written to buf and the 1089 * full length of the entry is returned (same behavior as 1090 * snprintf()). 1091 */ 1092 int (*comp)(struct context *ctx, const struct token *token, 1093 unsigned int ent, char *buf, unsigned int size); 1094 /** Mandatory token name, no default value. */ 1095 const char *name; 1096 }; 1097 1098 /** Static initializer for the next field. */ 1099 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } 1100 1101 /** Static initializer for a NEXT() entry. */ 1102 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } 1103 1104 /** Static initializer for the args field. */ 1105 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } 1106 1107 /** Static initializer for ARGS() to target a field. */ 1108 #define ARGS_ENTRY(s, f) \ 1109 (&(const struct arg){ \ 1110 .offset = offsetof(s, f), \ 1111 .size = sizeof(((s *)0)->f), \ 1112 }) 1113 1114 /** Static initializer for ARGS() to target a bit-field. */ 1115 #define ARGS_ENTRY_BF(s, f, b) \ 1116 (&(const struct arg){ \ 1117 .size = sizeof(s), \ 1118 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ 1119 }) 1120 1121 /** Static initializer for ARGS() to target a field with limits. */ 1122 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \ 1123 (&(const struct arg){ \ 1124 .bounded = 1, \ 1125 .min = (i), \ 1126 .max = (a), \ 1127 .offset = offsetof(s, f), \ 1128 .size = sizeof(((s *)0)->f), \ 1129 }) 1130 1131 /** Static initializer for ARGS() to target an arbitrary bit-mask. */ 1132 #define ARGS_ENTRY_MASK(s, f, m) \ 1133 (&(const struct arg){ \ 1134 .offset = offsetof(s, f), \ 1135 .size = sizeof(((s *)0)->f), \ 1136 .mask = (const void *)(m), \ 1137 }) 1138 1139 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ 1140 #define ARGS_ENTRY_MASK_HTON(s, f, m) \ 1141 (&(const struct arg){ \ 1142 .hton = 1, \ 1143 .offset = offsetof(s, f), \ 1144 .size = sizeof(((s *)0)->f), \ 1145 .mask = (const void *)(m), \ 1146 }) 1147 1148 /** Static initializer for ARGS() to target a pointer. */ 1149 #define ARGS_ENTRY_PTR(s, f) \ 1150 (&(const struct arg){ \ 1151 .size = sizeof(*((s *)0)->f), \ 1152 }) 1153 1154 /** Static initializer for ARGS() with arbitrary offset and size. */ 1155 #define ARGS_ENTRY_ARB(o, s) \ 1156 (&(const struct arg){ \ 1157 .offset = (o), \ 1158 .size = (s), \ 1159 }) 1160 1161 /** Same as ARGS_ENTRY_ARB() with bounded values. */ 1162 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ 1163 (&(const struct arg){ \ 1164 .bounded = 1, \ 1165 .min = (i), \ 1166 .max = (a), \ 1167 .offset = (o), \ 1168 .size = (s), \ 1169 }) 1170 1171 /** Same as ARGS_ENTRY() using network byte ordering. */ 1172 #define ARGS_ENTRY_HTON(s, f) \ 1173 (&(const struct arg){ \ 1174 .hton = 1, \ 1175 .offset = offsetof(s, f), \ 1176 .size = sizeof(((s *)0)->f), \ 1177 }) 1178 1179 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ 1180 #define ARG_ENTRY_HTON(s) \ 1181 (&(const struct arg){ \ 1182 .hton = 1, \ 1183 .offset = 0, \ 1184 .size = sizeof(s), \ 1185 }) 1186 1187 /** Parser output buffer layout expected by cmd_flow_parsed(). */ 1188 struct buffer { 1189 enum index command; /**< Flow command. */ 1190 portid_t port; /**< Affected port ID. */ 1191 queueid_t queue; /** Async queue ID. */ 1192 bool postpone; /** Postpone async operation */ 1193 union { 1194 struct { 1195 struct rte_flow_port_attr port_attr; 1196 uint32_t nb_queue; 1197 struct rte_flow_queue_attr queue_attr; 1198 } configure; /**< Configuration arguments. */ 1199 struct { 1200 uint32_t *template_id; 1201 uint32_t template_id_n; 1202 } templ_destroy; /**< Template destroy arguments. */ 1203 struct { 1204 uint32_t id; 1205 struct rte_flow_template_table_attr attr; 1206 uint32_t *pat_templ_id; 1207 uint32_t pat_templ_id_n; 1208 uint32_t *act_templ_id; 1209 uint32_t act_templ_id_n; 1210 } table; /**< Table arguments. */ 1211 struct { 1212 uint32_t *table_id; 1213 uint32_t table_id_n; 1214 } table_destroy; /**< Template destroy arguments. */ 1215 struct { 1216 uint32_t *action_id; 1217 uint32_t action_id_n; 1218 } ia_destroy; /**< Indirect action destroy arguments. */ 1219 struct { 1220 uint32_t action_id; 1221 enum rte_flow_query_update_mode qu_mode; 1222 } ia; /* Indirect action query arguments */ 1223 struct { 1224 uint32_t table_id; 1225 uint32_t pat_templ_id; 1226 uint32_t rule_id; 1227 uint32_t act_templ_id; 1228 struct rte_flow_attr attr; 1229 struct tunnel_ops tunnel_ops; 1230 uintptr_t user_id; 1231 struct rte_flow_item *pattern; 1232 struct rte_flow_action *actions; 1233 struct rte_flow_action *masks; 1234 uint32_t pattern_n; 1235 uint32_t actions_n; 1236 uint8_t *data; 1237 enum rte_flow_encap_hash_field field; 1238 uint8_t encap_hash; 1239 } vc; /**< Validate/create arguments. */ 1240 struct { 1241 uint64_t *rule; 1242 uint64_t rule_n; 1243 bool is_user_id; 1244 } destroy; /**< Destroy arguments. */ 1245 struct { 1246 char file[128]; 1247 bool mode; 1248 uint64_t rule; 1249 bool is_user_id; 1250 } dump; /**< Dump arguments. */ 1251 struct { 1252 uint64_t rule; 1253 struct rte_flow_action action; 1254 bool is_user_id; 1255 } query; /**< Query arguments. */ 1256 struct { 1257 uint32_t *group; 1258 uint32_t group_n; 1259 } list; /**< List arguments. */ 1260 struct { 1261 int set; 1262 } isolate; /**< Isolated mode arguments. */ 1263 struct { 1264 int destroy; 1265 } aged; /**< Aged arguments. */ 1266 struct { 1267 uint32_t policy_id; 1268 } policy;/**< Policy arguments. */ 1269 struct { 1270 uint16_t token; 1271 uintptr_t uintptr; 1272 char filename[128]; 1273 } flex; /**< Flex arguments*/ 1274 } args; /**< Command arguments. */ 1275 }; 1276 1277 /** Private data for pattern items. */ 1278 struct parse_item_priv { 1279 enum rte_flow_item_type type; /**< Item type. */ 1280 uint32_t size; /**< Size of item specification structure. */ 1281 }; 1282 1283 #define PRIV_ITEM(t, s) \ 1284 (&(const struct parse_item_priv){ \ 1285 .type = RTE_FLOW_ITEM_TYPE_ ## t, \ 1286 .size = s, \ 1287 }) 1288 1289 /** Private data for actions. */ 1290 struct parse_action_priv { 1291 enum rte_flow_action_type type; /**< Action type. */ 1292 uint32_t size; /**< Size of action configuration structure. */ 1293 }; 1294 1295 #define PRIV_ACTION(t, s) \ 1296 (&(const struct parse_action_priv){ \ 1297 .type = RTE_FLOW_ACTION_TYPE_ ## t, \ 1298 .size = s, \ 1299 }) 1300 1301 static const enum index next_flex_item[] = { 1302 FLEX_ITEM_INIT, 1303 FLEX_ITEM_CREATE, 1304 FLEX_ITEM_DESTROY, 1305 ZERO, 1306 }; 1307 1308 static const enum index next_config_attr[] = { 1309 CONFIG_QUEUES_NUMBER, 1310 CONFIG_QUEUES_SIZE, 1311 CONFIG_COUNTERS_NUMBER, 1312 CONFIG_AGING_OBJECTS_NUMBER, 1313 CONFIG_METERS_NUMBER, 1314 CONFIG_CONN_TRACK_NUMBER, 1315 CONFIG_QUOTAS_NUMBER, 1316 CONFIG_FLAGS, 1317 CONFIG_HOST_PORT, 1318 END, 1319 ZERO, 1320 }; 1321 1322 static const enum index next_pt_subcmd[] = { 1323 PATTERN_TEMPLATE_CREATE, 1324 PATTERN_TEMPLATE_DESTROY, 1325 ZERO, 1326 }; 1327 1328 static const enum index next_pt_attr[] = { 1329 PATTERN_TEMPLATE_CREATE_ID, 1330 PATTERN_TEMPLATE_RELAXED_MATCHING, 1331 PATTERN_TEMPLATE_INGRESS, 1332 PATTERN_TEMPLATE_EGRESS, 1333 PATTERN_TEMPLATE_TRANSFER, 1334 PATTERN_TEMPLATE_SPEC, 1335 ZERO, 1336 }; 1337 1338 static const enum index next_pt_destroy_attr[] = { 1339 PATTERN_TEMPLATE_DESTROY_ID, 1340 END, 1341 ZERO, 1342 }; 1343 1344 static const enum index next_at_subcmd[] = { 1345 ACTIONS_TEMPLATE_CREATE, 1346 ACTIONS_TEMPLATE_DESTROY, 1347 ZERO, 1348 }; 1349 1350 static const enum index next_at_attr[] = { 1351 ACTIONS_TEMPLATE_CREATE_ID, 1352 ACTIONS_TEMPLATE_INGRESS, 1353 ACTIONS_TEMPLATE_EGRESS, 1354 ACTIONS_TEMPLATE_TRANSFER, 1355 ACTIONS_TEMPLATE_SPEC, 1356 ZERO, 1357 }; 1358 1359 static const enum index next_at_destroy_attr[] = { 1360 ACTIONS_TEMPLATE_DESTROY_ID, 1361 END, 1362 ZERO, 1363 }; 1364 1365 static const enum index next_group_attr[] = { 1366 GROUP_INGRESS, 1367 GROUP_EGRESS, 1368 GROUP_TRANSFER, 1369 GROUP_SET_MISS_ACTIONS, 1370 ZERO, 1371 }; 1372 1373 static const enum index next_table_subcmd[] = { 1374 TABLE_CREATE, 1375 TABLE_DESTROY, 1376 TABLE_RESIZE, 1377 TABLE_RESIZE_COMPLETE, 1378 ZERO, 1379 }; 1380 1381 static const enum index next_table_attr[] = { 1382 TABLE_CREATE_ID, 1383 TABLE_GROUP, 1384 TABLE_INSERTION_TYPE, 1385 TABLE_HASH_FUNC, 1386 TABLE_PRIORITY, 1387 TABLE_INGRESS, 1388 TABLE_EGRESS, 1389 TABLE_TRANSFER, 1390 TABLE_TRANSFER_WIRE_ORIG, 1391 TABLE_TRANSFER_VPORT_ORIG, 1392 TABLE_RESIZABLE, 1393 TABLE_RULES_NUMBER, 1394 TABLE_PATTERN_TEMPLATE, 1395 TABLE_ACTIONS_TEMPLATE, 1396 END, 1397 ZERO, 1398 }; 1399 1400 static const enum index next_table_destroy_attr[] = { 1401 TABLE_DESTROY_ID, 1402 END, 1403 ZERO, 1404 }; 1405 1406 static const enum index next_queue_subcmd[] = { 1407 QUEUE_CREATE, 1408 QUEUE_DESTROY, 1409 QUEUE_FLOW_UPDATE_RESIZED, 1410 QUEUE_UPDATE, 1411 QUEUE_AGED, 1412 QUEUE_INDIRECT_ACTION, 1413 ZERO, 1414 }; 1415 1416 static const enum index next_queue_destroy_attr[] = { 1417 QUEUE_DESTROY_ID, 1418 END, 1419 ZERO, 1420 }; 1421 1422 static const enum index next_qia_subcmd[] = { 1423 QUEUE_INDIRECT_ACTION_CREATE, 1424 QUEUE_INDIRECT_ACTION_UPDATE, 1425 QUEUE_INDIRECT_ACTION_DESTROY, 1426 QUEUE_INDIRECT_ACTION_QUERY, 1427 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 1428 ZERO, 1429 }; 1430 1431 static const enum index next_qia_create_attr[] = { 1432 QUEUE_INDIRECT_ACTION_CREATE_ID, 1433 QUEUE_INDIRECT_ACTION_INGRESS, 1434 QUEUE_INDIRECT_ACTION_EGRESS, 1435 QUEUE_INDIRECT_ACTION_TRANSFER, 1436 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 1437 QUEUE_INDIRECT_ACTION_SPEC, 1438 QUEUE_INDIRECT_ACTION_LIST, 1439 ZERO, 1440 }; 1441 1442 static const enum index next_qia_update_attr[] = { 1443 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1444 QUEUE_INDIRECT_ACTION_SPEC, 1445 ZERO, 1446 }; 1447 1448 static const enum index next_qia_destroy_attr[] = { 1449 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 1450 QUEUE_INDIRECT_ACTION_DESTROY_ID, 1451 END, 1452 ZERO, 1453 }; 1454 1455 static const enum index next_qia_query_attr[] = { 1456 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 1457 END, 1458 ZERO, 1459 }; 1460 1461 static const enum index next_ia_create_attr[] = { 1462 INDIRECT_ACTION_CREATE_ID, 1463 INDIRECT_ACTION_INGRESS, 1464 INDIRECT_ACTION_EGRESS, 1465 INDIRECT_ACTION_TRANSFER, 1466 INDIRECT_ACTION_SPEC, 1467 INDIRECT_ACTION_LIST, 1468 INDIRECT_ACTION_FLOW_CONF, 1469 ZERO, 1470 }; 1471 1472 static const enum index next_ia[] = { 1473 INDIRECT_ACTION_ID2PTR, 1474 ACTION_NEXT, 1475 ZERO 1476 }; 1477 1478 static const enum index next_ial[] = { 1479 ACTION_INDIRECT_LIST_HANDLE, 1480 ACTION_INDIRECT_LIST_CONF, 1481 ACTION_NEXT, 1482 ZERO 1483 }; 1484 1485 static const enum index next_qia_qu_attr[] = { 1486 QUEUE_INDIRECT_ACTION_QU_MODE, 1487 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1488 INDIRECT_ACTION_SPEC, 1489 ZERO 1490 }; 1491 1492 static const enum index next_ia_qu_attr[] = { 1493 INDIRECT_ACTION_QU_MODE, 1494 INDIRECT_ACTION_SPEC, 1495 ZERO 1496 }; 1497 1498 static const enum index next_dump_subcmd[] = { 1499 DUMP_ALL, 1500 DUMP_ONE, 1501 DUMP_IS_USER_ID, 1502 ZERO, 1503 }; 1504 1505 static const enum index next_ia_subcmd[] = { 1506 INDIRECT_ACTION_CREATE, 1507 INDIRECT_ACTION_UPDATE, 1508 INDIRECT_ACTION_DESTROY, 1509 INDIRECT_ACTION_QUERY, 1510 INDIRECT_ACTION_QUERY_UPDATE, 1511 ZERO, 1512 }; 1513 1514 static const enum index next_vc_attr[] = { 1515 VC_GROUP, 1516 VC_PRIORITY, 1517 VC_INGRESS, 1518 VC_EGRESS, 1519 VC_TRANSFER, 1520 VC_TUNNEL_SET, 1521 VC_TUNNEL_MATCH, 1522 VC_USER_ID, 1523 ITEM_PATTERN, 1524 ZERO, 1525 }; 1526 1527 static const enum index next_destroy_attr[] = { 1528 DESTROY_RULE, 1529 DESTROY_IS_USER_ID, 1530 END, 1531 ZERO, 1532 }; 1533 1534 static const enum index next_dump_attr[] = { 1535 COMMON_FILE_PATH, 1536 END, 1537 ZERO, 1538 }; 1539 1540 static const enum index next_query_attr[] = { 1541 QUERY_IS_USER_ID, 1542 END, 1543 ZERO, 1544 }; 1545 1546 static const enum index next_list_attr[] = { 1547 LIST_GROUP, 1548 END, 1549 ZERO, 1550 }; 1551 1552 static const enum index next_aged_attr[] = { 1553 AGED_DESTROY, 1554 END, 1555 ZERO, 1556 }; 1557 1558 static const enum index next_ia_destroy_attr[] = { 1559 INDIRECT_ACTION_DESTROY_ID, 1560 END, 1561 ZERO, 1562 }; 1563 1564 static const enum index next_async_insert_subcmd[] = { 1565 QUEUE_PATTERN_TEMPLATE, 1566 QUEUE_RULE_ID, 1567 ZERO, 1568 }; 1569 1570 static const enum index item_param[] = { 1571 ITEM_PARAM_IS, 1572 ITEM_PARAM_SPEC, 1573 ITEM_PARAM_LAST, 1574 ITEM_PARAM_MASK, 1575 ITEM_PARAM_PREFIX, 1576 ZERO, 1577 }; 1578 1579 static const enum index next_item[] = { 1580 ITEM_END, 1581 ITEM_VOID, 1582 ITEM_INVERT, 1583 ITEM_ANY, 1584 ITEM_PORT_ID, 1585 ITEM_MARK, 1586 ITEM_RAW, 1587 ITEM_ETH, 1588 ITEM_VLAN, 1589 ITEM_IPV4, 1590 ITEM_IPV6, 1591 ITEM_ICMP, 1592 ITEM_UDP, 1593 ITEM_TCP, 1594 ITEM_SCTP, 1595 ITEM_VXLAN, 1596 ITEM_E_TAG, 1597 ITEM_NVGRE, 1598 ITEM_MPLS, 1599 ITEM_GRE, 1600 ITEM_FUZZY, 1601 ITEM_GTP, 1602 ITEM_GTPC, 1603 ITEM_GTPU, 1604 ITEM_GENEVE, 1605 ITEM_VXLAN_GPE, 1606 ITEM_ARP_ETH_IPV4, 1607 ITEM_IPV6_EXT, 1608 ITEM_IPV6_FRAG_EXT, 1609 ITEM_IPV6_ROUTING_EXT, 1610 ITEM_ICMP6, 1611 ITEM_ICMP6_ECHO_REQUEST, 1612 ITEM_ICMP6_ECHO_REPLY, 1613 ITEM_ICMP6_ND_NS, 1614 ITEM_ICMP6_ND_NA, 1615 ITEM_ICMP6_ND_OPT, 1616 ITEM_ICMP6_ND_OPT_SLA_ETH, 1617 ITEM_ICMP6_ND_OPT_TLA_ETH, 1618 ITEM_META, 1619 ITEM_RANDOM, 1620 ITEM_GRE_KEY, 1621 ITEM_GRE_OPTION, 1622 ITEM_GTP_PSC, 1623 ITEM_PPPOES, 1624 ITEM_PPPOED, 1625 ITEM_PPPOE_PROTO_ID, 1626 ITEM_HIGIG2, 1627 ITEM_TAG, 1628 ITEM_L2TPV3OIP, 1629 ITEM_ESP, 1630 ITEM_AH, 1631 ITEM_PFCP, 1632 ITEM_ECPRI, 1633 ITEM_GENEVE_OPT, 1634 ITEM_INTEGRITY, 1635 ITEM_CONNTRACK, 1636 ITEM_PORT_REPRESENTOR, 1637 ITEM_REPRESENTED_PORT, 1638 ITEM_FLEX, 1639 ITEM_L2TPV2, 1640 ITEM_PPP, 1641 ITEM_METER, 1642 ITEM_QUOTA, 1643 ITEM_AGGR_AFFINITY, 1644 ITEM_TX_QUEUE, 1645 ITEM_IB_BTH, 1646 ITEM_PTYPE, 1647 ITEM_NSH, 1648 ITEM_COMPARE, 1649 END_SET, 1650 ZERO, 1651 }; 1652 1653 static const enum index item_fuzzy[] = { 1654 ITEM_FUZZY_THRESH, 1655 ITEM_NEXT, 1656 ZERO, 1657 }; 1658 1659 static const enum index item_any[] = { 1660 ITEM_ANY_NUM, 1661 ITEM_NEXT, 1662 ZERO, 1663 }; 1664 1665 static const enum index item_port_id[] = { 1666 ITEM_PORT_ID_ID, 1667 ITEM_NEXT, 1668 ZERO, 1669 }; 1670 1671 static const enum index item_mark[] = { 1672 ITEM_MARK_ID, 1673 ITEM_NEXT, 1674 ZERO, 1675 }; 1676 1677 static const enum index item_raw[] = { 1678 ITEM_RAW_RELATIVE, 1679 ITEM_RAW_SEARCH, 1680 ITEM_RAW_OFFSET, 1681 ITEM_RAW_LIMIT, 1682 ITEM_RAW_PATTERN, 1683 ITEM_RAW_PATTERN_HEX, 1684 ITEM_NEXT, 1685 ZERO, 1686 }; 1687 1688 static const enum index item_eth[] = { 1689 ITEM_ETH_DST, 1690 ITEM_ETH_SRC, 1691 ITEM_ETH_TYPE, 1692 ITEM_ETH_HAS_VLAN, 1693 ITEM_NEXT, 1694 ZERO, 1695 }; 1696 1697 static const enum index item_vlan[] = { 1698 ITEM_VLAN_TCI, 1699 ITEM_VLAN_PCP, 1700 ITEM_VLAN_DEI, 1701 ITEM_VLAN_VID, 1702 ITEM_VLAN_INNER_TYPE, 1703 ITEM_VLAN_HAS_MORE_VLAN, 1704 ITEM_NEXT, 1705 ZERO, 1706 }; 1707 1708 static const enum index item_ipv4[] = { 1709 ITEM_IPV4_VER_IHL, 1710 ITEM_IPV4_TOS, 1711 ITEM_IPV4_LENGTH, 1712 ITEM_IPV4_ID, 1713 ITEM_IPV4_FRAGMENT_OFFSET, 1714 ITEM_IPV4_TTL, 1715 ITEM_IPV4_PROTO, 1716 ITEM_IPV4_SRC, 1717 ITEM_IPV4_DST, 1718 ITEM_NEXT, 1719 ZERO, 1720 }; 1721 1722 static const enum index item_ipv6[] = { 1723 ITEM_IPV6_TC, 1724 ITEM_IPV6_FLOW, 1725 ITEM_IPV6_LEN, 1726 ITEM_IPV6_PROTO, 1727 ITEM_IPV6_HOP, 1728 ITEM_IPV6_SRC, 1729 ITEM_IPV6_DST, 1730 ITEM_IPV6_HAS_FRAG_EXT, 1731 ITEM_IPV6_ROUTING_EXT, 1732 ITEM_NEXT, 1733 ZERO, 1734 }; 1735 1736 static const enum index item_ipv6_routing_ext[] = { 1737 ITEM_IPV6_ROUTING_EXT_TYPE, 1738 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 1739 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 1740 ITEM_NEXT, 1741 ZERO, 1742 }; 1743 1744 static const enum index item_icmp[] = { 1745 ITEM_ICMP_TYPE, 1746 ITEM_ICMP_CODE, 1747 ITEM_ICMP_IDENT, 1748 ITEM_ICMP_SEQ, 1749 ITEM_NEXT, 1750 ZERO, 1751 }; 1752 1753 static const enum index item_udp[] = { 1754 ITEM_UDP_SRC, 1755 ITEM_UDP_DST, 1756 ITEM_NEXT, 1757 ZERO, 1758 }; 1759 1760 static const enum index item_tcp[] = { 1761 ITEM_TCP_SRC, 1762 ITEM_TCP_DST, 1763 ITEM_TCP_FLAGS, 1764 ITEM_NEXT, 1765 ZERO, 1766 }; 1767 1768 static const enum index item_sctp[] = { 1769 ITEM_SCTP_SRC, 1770 ITEM_SCTP_DST, 1771 ITEM_SCTP_TAG, 1772 ITEM_SCTP_CKSUM, 1773 ITEM_NEXT, 1774 ZERO, 1775 }; 1776 1777 static const enum index item_vxlan[] = { 1778 ITEM_VXLAN_VNI, 1779 ITEM_VXLAN_LAST_RSVD, 1780 ITEM_NEXT, 1781 ZERO, 1782 }; 1783 1784 static const enum index item_e_tag[] = { 1785 ITEM_E_TAG_GRP_ECID_B, 1786 ITEM_NEXT, 1787 ZERO, 1788 }; 1789 1790 static const enum index item_nvgre[] = { 1791 ITEM_NVGRE_TNI, 1792 ITEM_NEXT, 1793 ZERO, 1794 }; 1795 1796 static const enum index item_mpls[] = { 1797 ITEM_MPLS_LABEL, 1798 ITEM_MPLS_TC, 1799 ITEM_MPLS_S, 1800 ITEM_MPLS_TTL, 1801 ITEM_NEXT, 1802 ZERO, 1803 }; 1804 1805 static const enum index item_gre[] = { 1806 ITEM_GRE_PROTO, 1807 ITEM_GRE_C_RSVD0_VER, 1808 ITEM_GRE_C_BIT, 1809 ITEM_GRE_K_BIT, 1810 ITEM_GRE_S_BIT, 1811 ITEM_NEXT, 1812 ZERO, 1813 }; 1814 1815 static const enum index item_gre_key[] = { 1816 ITEM_GRE_KEY_VALUE, 1817 ITEM_NEXT, 1818 ZERO, 1819 }; 1820 1821 static const enum index item_gre_option[] = { 1822 ITEM_GRE_OPTION_CHECKSUM, 1823 ITEM_GRE_OPTION_KEY, 1824 ITEM_GRE_OPTION_SEQUENCE, 1825 ITEM_NEXT, 1826 ZERO, 1827 }; 1828 1829 static const enum index item_gtp[] = { 1830 ITEM_GTP_FLAGS, 1831 ITEM_GTP_MSG_TYPE, 1832 ITEM_GTP_TEID, 1833 ITEM_NEXT, 1834 ZERO, 1835 }; 1836 1837 static const enum index item_geneve[] = { 1838 ITEM_GENEVE_VNI, 1839 ITEM_GENEVE_PROTO, 1840 ITEM_GENEVE_OPTLEN, 1841 ITEM_NEXT, 1842 ZERO, 1843 }; 1844 1845 static const enum index item_vxlan_gpe[] = { 1846 ITEM_VXLAN_GPE_VNI, 1847 ITEM_VXLAN_GPE_PROTO, 1848 ITEM_VXLAN_GPE_FLAGS, 1849 ITEM_VXLAN_GPE_RSVD0, 1850 ITEM_VXLAN_GPE_RSVD1, 1851 ITEM_NEXT, 1852 ZERO, 1853 }; 1854 1855 static const enum index item_arp_eth_ipv4[] = { 1856 ITEM_ARP_ETH_IPV4_SHA, 1857 ITEM_ARP_ETH_IPV4_SPA, 1858 ITEM_ARP_ETH_IPV4_THA, 1859 ITEM_ARP_ETH_IPV4_TPA, 1860 ITEM_NEXT, 1861 ZERO, 1862 }; 1863 1864 static const enum index item_ipv6_ext[] = { 1865 ITEM_IPV6_EXT_NEXT_HDR, 1866 ITEM_NEXT, 1867 ZERO, 1868 }; 1869 1870 static const enum index item_ipv6_frag_ext[] = { 1871 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 1872 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 1873 ITEM_IPV6_FRAG_EXT_ID, 1874 ITEM_NEXT, 1875 ZERO, 1876 }; 1877 1878 static const enum index item_icmp6[] = { 1879 ITEM_ICMP6_TYPE, 1880 ITEM_ICMP6_CODE, 1881 ITEM_NEXT, 1882 ZERO, 1883 }; 1884 1885 static const enum index item_icmp6_echo_request[] = { 1886 ITEM_ICMP6_ECHO_REQUEST_ID, 1887 ITEM_ICMP6_ECHO_REQUEST_SEQ, 1888 ITEM_NEXT, 1889 ZERO, 1890 }; 1891 1892 static const enum index item_icmp6_echo_reply[] = { 1893 ITEM_ICMP6_ECHO_REPLY_ID, 1894 ITEM_ICMP6_ECHO_REPLY_SEQ, 1895 ITEM_NEXT, 1896 ZERO, 1897 }; 1898 1899 static const enum index item_icmp6_nd_ns[] = { 1900 ITEM_ICMP6_ND_NS_TARGET_ADDR, 1901 ITEM_NEXT, 1902 ZERO, 1903 }; 1904 1905 static const enum index item_icmp6_nd_na[] = { 1906 ITEM_ICMP6_ND_NA_TARGET_ADDR, 1907 ITEM_NEXT, 1908 ZERO, 1909 }; 1910 1911 static const enum index item_icmp6_nd_opt[] = { 1912 ITEM_ICMP6_ND_OPT_TYPE, 1913 ITEM_NEXT, 1914 ZERO, 1915 }; 1916 1917 static const enum index item_icmp6_nd_opt_sla_eth[] = { 1918 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 1919 ITEM_NEXT, 1920 ZERO, 1921 }; 1922 1923 static const enum index item_icmp6_nd_opt_tla_eth[] = { 1924 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 1925 ITEM_NEXT, 1926 ZERO, 1927 }; 1928 1929 static const enum index item_meta[] = { 1930 ITEM_META_DATA, 1931 ITEM_NEXT, 1932 ZERO, 1933 }; 1934 1935 static const enum index item_random[] = { 1936 ITEM_RANDOM_VALUE, 1937 ITEM_NEXT, 1938 ZERO, 1939 }; 1940 1941 static const enum index item_gtp_psc[] = { 1942 ITEM_GTP_PSC_QFI, 1943 ITEM_GTP_PSC_PDU_T, 1944 ITEM_NEXT, 1945 ZERO, 1946 }; 1947 1948 static const enum index item_pppoed[] = { 1949 ITEM_PPPOE_SEID, 1950 ITEM_NEXT, 1951 ZERO, 1952 }; 1953 1954 static const enum index item_pppoes[] = { 1955 ITEM_PPPOE_SEID, 1956 ITEM_NEXT, 1957 ZERO, 1958 }; 1959 1960 static const enum index item_pppoe_proto_id[] = { 1961 ITEM_NEXT, 1962 ZERO, 1963 }; 1964 1965 static const enum index item_higig2[] = { 1966 ITEM_HIGIG2_CLASSIFICATION, 1967 ITEM_HIGIG2_VID, 1968 ITEM_NEXT, 1969 ZERO, 1970 }; 1971 1972 static const enum index item_esp[] = { 1973 ITEM_ESP_SPI, 1974 ITEM_NEXT, 1975 ZERO, 1976 }; 1977 1978 static const enum index item_ah[] = { 1979 ITEM_AH_SPI, 1980 ITEM_NEXT, 1981 ZERO, 1982 }; 1983 1984 static const enum index item_pfcp[] = { 1985 ITEM_PFCP_S_FIELD, 1986 ITEM_PFCP_SEID, 1987 ITEM_NEXT, 1988 ZERO, 1989 }; 1990 1991 static const enum index next_set_raw[] = { 1992 SET_RAW_INDEX, 1993 ITEM_ETH, 1994 ZERO, 1995 }; 1996 1997 static const enum index item_tag[] = { 1998 ITEM_TAG_DATA, 1999 ITEM_TAG_INDEX, 2000 ITEM_NEXT, 2001 ZERO, 2002 }; 2003 2004 static const enum index item_l2tpv3oip[] = { 2005 ITEM_L2TPV3OIP_SESSION_ID, 2006 ITEM_NEXT, 2007 ZERO, 2008 }; 2009 2010 static const enum index item_ecpri[] = { 2011 ITEM_ECPRI_COMMON, 2012 ITEM_NEXT, 2013 ZERO, 2014 }; 2015 2016 static const enum index item_ecpri_common[] = { 2017 ITEM_ECPRI_COMMON_TYPE, 2018 ZERO, 2019 }; 2020 2021 static const enum index item_ecpri_common_type[] = { 2022 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 2023 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 2024 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 2025 ZERO, 2026 }; 2027 2028 static const enum index item_geneve_opt[] = { 2029 ITEM_GENEVE_OPT_CLASS, 2030 ITEM_GENEVE_OPT_TYPE, 2031 ITEM_GENEVE_OPT_LENGTH, 2032 ITEM_GENEVE_OPT_DATA, 2033 ITEM_NEXT, 2034 ZERO, 2035 }; 2036 2037 static const enum index item_integrity[] = { 2038 ITEM_INTEGRITY_LEVEL, 2039 ITEM_INTEGRITY_VALUE, 2040 ZERO, 2041 }; 2042 2043 static const enum index item_integrity_lv[] = { 2044 ITEM_INTEGRITY_LEVEL, 2045 ITEM_INTEGRITY_VALUE, 2046 ITEM_NEXT, 2047 ZERO, 2048 }; 2049 2050 static const enum index item_port_representor[] = { 2051 ITEM_PORT_REPRESENTOR_PORT_ID, 2052 ITEM_NEXT, 2053 ZERO, 2054 }; 2055 2056 static const enum index item_represented_port[] = { 2057 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 2058 ITEM_NEXT, 2059 ZERO, 2060 }; 2061 2062 static const enum index item_flex[] = { 2063 ITEM_FLEX_PATTERN_HANDLE, 2064 ITEM_FLEX_ITEM_HANDLE, 2065 ITEM_NEXT, 2066 ZERO, 2067 }; 2068 2069 static const enum index item_l2tpv2[] = { 2070 ITEM_L2TPV2_TYPE, 2071 ITEM_NEXT, 2072 ZERO, 2073 }; 2074 2075 static const enum index item_l2tpv2_type[] = { 2076 ITEM_L2TPV2_TYPE_DATA, 2077 ITEM_L2TPV2_TYPE_DATA_L, 2078 ITEM_L2TPV2_TYPE_DATA_S, 2079 ITEM_L2TPV2_TYPE_DATA_O, 2080 ITEM_L2TPV2_TYPE_DATA_L_S, 2081 ITEM_L2TPV2_TYPE_CTRL, 2082 ZERO, 2083 }; 2084 2085 static const enum index item_l2tpv2_type_data[] = { 2086 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 2087 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 2088 ITEM_NEXT, 2089 ZERO, 2090 }; 2091 2092 static const enum index item_l2tpv2_type_data_l[] = { 2093 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 2094 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 2095 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 2096 ITEM_NEXT, 2097 ZERO, 2098 }; 2099 2100 static const enum index item_l2tpv2_type_data_s[] = { 2101 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 2102 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 2103 ITEM_L2TPV2_MSG_DATA_S_NS, 2104 ITEM_L2TPV2_MSG_DATA_S_NR, 2105 ITEM_NEXT, 2106 ZERO, 2107 }; 2108 2109 static const enum index item_l2tpv2_type_data_o[] = { 2110 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 2111 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 2112 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 2113 ITEM_NEXT, 2114 ZERO, 2115 }; 2116 2117 static const enum index item_l2tpv2_type_data_l_s[] = { 2118 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 2119 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 2120 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 2121 ITEM_L2TPV2_MSG_DATA_L_S_NS, 2122 ITEM_L2TPV2_MSG_DATA_L_S_NR, 2123 ITEM_NEXT, 2124 ZERO, 2125 }; 2126 2127 static const enum index item_l2tpv2_type_ctrl[] = { 2128 ITEM_L2TPV2_MSG_CTRL_LENGTH, 2129 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 2130 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 2131 ITEM_L2TPV2_MSG_CTRL_NS, 2132 ITEM_L2TPV2_MSG_CTRL_NR, 2133 ITEM_NEXT, 2134 ZERO, 2135 }; 2136 2137 static const enum index item_ppp[] = { 2138 ITEM_PPP_ADDR, 2139 ITEM_PPP_CTRL, 2140 ITEM_PPP_PROTO_ID, 2141 ITEM_NEXT, 2142 ZERO, 2143 }; 2144 2145 static const enum index item_meter[] = { 2146 ITEM_METER_COLOR, 2147 ITEM_NEXT, 2148 ZERO, 2149 }; 2150 2151 static const enum index item_quota[] = { 2152 ITEM_QUOTA_STATE, 2153 ITEM_NEXT, 2154 ZERO, 2155 }; 2156 2157 static const enum index item_aggr_affinity[] = { 2158 ITEM_AGGR_AFFINITY_VALUE, 2159 ITEM_NEXT, 2160 ZERO, 2161 }; 2162 2163 static const enum index item_tx_queue[] = { 2164 ITEM_TX_QUEUE_VALUE, 2165 ITEM_NEXT, 2166 ZERO, 2167 }; 2168 2169 static const enum index item_ib_bth[] = { 2170 ITEM_IB_BTH_OPCODE, 2171 ITEM_IB_BTH_PKEY, 2172 ITEM_IB_BTH_DST_QPN, 2173 ITEM_IB_BTH_PSN, 2174 ITEM_NEXT, 2175 ZERO, 2176 }; 2177 2178 static const enum index item_ptype[] = { 2179 ITEM_PTYPE_VALUE, 2180 ITEM_NEXT, 2181 ZERO, 2182 }; 2183 2184 static const enum index item_nsh[] = { 2185 ITEM_NEXT, 2186 ZERO, 2187 }; 2188 2189 static const enum index item_compare_field[] = { 2190 ITEM_COMPARE_OP, 2191 ITEM_COMPARE_FIELD_A_TYPE, 2192 ITEM_COMPARE_FIELD_B_TYPE, 2193 ITEM_NEXT, 2194 ZERO, 2195 }; 2196 2197 static const enum index compare_field_a[] = { 2198 ITEM_COMPARE_FIELD_A_TYPE, 2199 ITEM_COMPARE_FIELD_A_LEVEL, 2200 ITEM_COMPARE_FIELD_A_TAG_INDEX, 2201 ITEM_COMPARE_FIELD_A_TYPE_ID, 2202 ITEM_COMPARE_FIELD_A_CLASS_ID, 2203 ITEM_COMPARE_FIELD_A_OFFSET, 2204 ITEM_COMPARE_FIELD_B_TYPE, 2205 ZERO, 2206 }; 2207 2208 static const enum index compare_field_b[] = { 2209 ITEM_COMPARE_FIELD_B_TYPE, 2210 ITEM_COMPARE_FIELD_B_LEVEL, 2211 ITEM_COMPARE_FIELD_B_TAG_INDEX, 2212 ITEM_COMPARE_FIELD_B_TYPE_ID, 2213 ITEM_COMPARE_FIELD_B_CLASS_ID, 2214 ITEM_COMPARE_FIELD_B_OFFSET, 2215 ITEM_COMPARE_FIELD_B_VALUE, 2216 ITEM_COMPARE_FIELD_B_POINTER, 2217 ITEM_COMPARE_FIELD_WIDTH, 2218 ZERO, 2219 }; 2220 2221 static const enum index next_action[] = { 2222 ACTION_END, 2223 ACTION_VOID, 2224 ACTION_PASSTHRU, 2225 ACTION_SKIP_CMAN, 2226 ACTION_JUMP, 2227 ACTION_MARK, 2228 ACTION_FLAG, 2229 ACTION_QUEUE, 2230 ACTION_DROP, 2231 ACTION_COUNT, 2232 ACTION_RSS, 2233 ACTION_PF, 2234 ACTION_VF, 2235 ACTION_PORT_ID, 2236 ACTION_METER, 2237 ACTION_METER_COLOR, 2238 ACTION_METER_MARK, 2239 ACTION_OF_DEC_NW_TTL, 2240 ACTION_OF_POP_VLAN, 2241 ACTION_OF_PUSH_VLAN, 2242 ACTION_OF_SET_VLAN_VID, 2243 ACTION_OF_SET_VLAN_PCP, 2244 ACTION_OF_POP_MPLS, 2245 ACTION_OF_PUSH_MPLS, 2246 ACTION_VXLAN_ENCAP, 2247 ACTION_VXLAN_DECAP, 2248 ACTION_NVGRE_ENCAP, 2249 ACTION_NVGRE_DECAP, 2250 ACTION_L2_ENCAP, 2251 ACTION_L2_DECAP, 2252 ACTION_MPLSOGRE_ENCAP, 2253 ACTION_MPLSOGRE_DECAP, 2254 ACTION_MPLSOUDP_ENCAP, 2255 ACTION_MPLSOUDP_DECAP, 2256 ACTION_SET_IPV4_SRC, 2257 ACTION_SET_IPV4_DST, 2258 ACTION_SET_IPV6_SRC, 2259 ACTION_SET_IPV6_DST, 2260 ACTION_SET_TP_SRC, 2261 ACTION_SET_TP_DST, 2262 ACTION_MAC_SWAP, 2263 ACTION_DEC_TTL, 2264 ACTION_SET_TTL, 2265 ACTION_SET_MAC_SRC, 2266 ACTION_SET_MAC_DST, 2267 ACTION_INC_TCP_SEQ, 2268 ACTION_DEC_TCP_SEQ, 2269 ACTION_INC_TCP_ACK, 2270 ACTION_DEC_TCP_ACK, 2271 ACTION_RAW_ENCAP, 2272 ACTION_RAW_DECAP, 2273 ACTION_SET_TAG, 2274 ACTION_SET_META, 2275 ACTION_SET_IPV4_DSCP, 2276 ACTION_SET_IPV6_DSCP, 2277 ACTION_AGE, 2278 ACTION_AGE_UPDATE, 2279 ACTION_SAMPLE, 2280 ACTION_INDIRECT, 2281 ACTION_INDIRECT_LIST, 2282 ACTION_SHARED_INDIRECT, 2283 ACTION_MODIFY_FIELD, 2284 ACTION_CONNTRACK, 2285 ACTION_CONNTRACK_UPDATE, 2286 ACTION_PORT_REPRESENTOR, 2287 ACTION_REPRESENTED_PORT, 2288 ACTION_SEND_TO_KERNEL, 2289 ACTION_QUOTA_CREATE, 2290 ACTION_QUOTA_QU, 2291 ACTION_IPV6_EXT_REMOVE, 2292 ACTION_IPV6_EXT_PUSH, 2293 ACTION_NAT64, 2294 ZERO, 2295 }; 2296 2297 static const enum index action_quota_create[] = { 2298 ACTION_QUOTA_CREATE_LIMIT, 2299 ACTION_QUOTA_CREATE_MODE, 2300 ACTION_NEXT, 2301 ZERO 2302 }; 2303 2304 static const enum index action_quota_update[] = { 2305 ACTION_QUOTA_QU_LIMIT, 2306 ACTION_QUOTA_QU_UPDATE_OP, 2307 ACTION_NEXT, 2308 ZERO 2309 }; 2310 2311 static const enum index action_mark[] = { 2312 ACTION_MARK_ID, 2313 ACTION_NEXT, 2314 ZERO, 2315 }; 2316 2317 static const enum index action_queue[] = { 2318 ACTION_QUEUE_INDEX, 2319 ACTION_NEXT, 2320 ZERO, 2321 }; 2322 2323 static const enum index action_count[] = { 2324 ACTION_COUNT_ID, 2325 ACTION_NEXT, 2326 ZERO, 2327 }; 2328 2329 static const enum index action_rss[] = { 2330 ACTION_RSS_FUNC, 2331 ACTION_RSS_LEVEL, 2332 ACTION_RSS_TYPES, 2333 ACTION_RSS_KEY, 2334 ACTION_RSS_KEY_LEN, 2335 ACTION_RSS_QUEUES, 2336 ACTION_NEXT, 2337 ZERO, 2338 }; 2339 2340 static const enum index action_vf[] = { 2341 ACTION_VF_ORIGINAL, 2342 ACTION_VF_ID, 2343 ACTION_NEXT, 2344 ZERO, 2345 }; 2346 2347 static const enum index action_port_id[] = { 2348 ACTION_PORT_ID_ORIGINAL, 2349 ACTION_PORT_ID_ID, 2350 ACTION_NEXT, 2351 ZERO, 2352 }; 2353 2354 static const enum index action_meter[] = { 2355 ACTION_METER_ID, 2356 ACTION_NEXT, 2357 ZERO, 2358 }; 2359 2360 static const enum index action_meter_color[] = { 2361 ACTION_METER_COLOR_TYPE, 2362 ACTION_NEXT, 2363 ZERO, 2364 }; 2365 2366 static const enum index action_meter_mark[] = { 2367 ACTION_METER_PROFILE, 2368 ACTION_METER_POLICY, 2369 ACTION_METER_COLOR_MODE, 2370 ACTION_METER_STATE, 2371 ACTION_NEXT, 2372 ZERO, 2373 }; 2374 2375 static const enum index action_of_push_vlan[] = { 2376 ACTION_OF_PUSH_VLAN_ETHERTYPE, 2377 ACTION_NEXT, 2378 ZERO, 2379 }; 2380 2381 static const enum index action_of_set_vlan_vid[] = { 2382 ACTION_OF_SET_VLAN_VID_VLAN_VID, 2383 ACTION_NEXT, 2384 ZERO, 2385 }; 2386 2387 static const enum index action_of_set_vlan_pcp[] = { 2388 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 2389 ACTION_NEXT, 2390 ZERO, 2391 }; 2392 2393 static const enum index action_of_pop_mpls[] = { 2394 ACTION_OF_POP_MPLS_ETHERTYPE, 2395 ACTION_NEXT, 2396 ZERO, 2397 }; 2398 2399 static const enum index action_of_push_mpls[] = { 2400 ACTION_OF_PUSH_MPLS_ETHERTYPE, 2401 ACTION_NEXT, 2402 ZERO, 2403 }; 2404 2405 static const enum index action_set_ipv4_src[] = { 2406 ACTION_SET_IPV4_SRC_IPV4_SRC, 2407 ACTION_NEXT, 2408 ZERO, 2409 }; 2410 2411 static const enum index action_set_mac_src[] = { 2412 ACTION_SET_MAC_SRC_MAC_SRC, 2413 ACTION_NEXT, 2414 ZERO, 2415 }; 2416 2417 static const enum index action_set_ipv4_dst[] = { 2418 ACTION_SET_IPV4_DST_IPV4_DST, 2419 ACTION_NEXT, 2420 ZERO, 2421 }; 2422 2423 static const enum index action_set_ipv6_src[] = { 2424 ACTION_SET_IPV6_SRC_IPV6_SRC, 2425 ACTION_NEXT, 2426 ZERO, 2427 }; 2428 2429 static const enum index action_set_ipv6_dst[] = { 2430 ACTION_SET_IPV6_DST_IPV6_DST, 2431 ACTION_NEXT, 2432 ZERO, 2433 }; 2434 2435 static const enum index action_set_tp_src[] = { 2436 ACTION_SET_TP_SRC_TP_SRC, 2437 ACTION_NEXT, 2438 ZERO, 2439 }; 2440 2441 static const enum index action_set_tp_dst[] = { 2442 ACTION_SET_TP_DST_TP_DST, 2443 ACTION_NEXT, 2444 ZERO, 2445 }; 2446 2447 static const enum index action_set_ttl[] = { 2448 ACTION_SET_TTL_TTL, 2449 ACTION_NEXT, 2450 ZERO, 2451 }; 2452 2453 static const enum index action_jump[] = { 2454 ACTION_JUMP_GROUP, 2455 ACTION_NEXT, 2456 ZERO, 2457 }; 2458 2459 static const enum index action_set_mac_dst[] = { 2460 ACTION_SET_MAC_DST_MAC_DST, 2461 ACTION_NEXT, 2462 ZERO, 2463 }; 2464 2465 static const enum index action_inc_tcp_seq[] = { 2466 ACTION_INC_TCP_SEQ_VALUE, 2467 ACTION_NEXT, 2468 ZERO, 2469 }; 2470 2471 static const enum index action_dec_tcp_seq[] = { 2472 ACTION_DEC_TCP_SEQ_VALUE, 2473 ACTION_NEXT, 2474 ZERO, 2475 }; 2476 2477 static const enum index action_inc_tcp_ack[] = { 2478 ACTION_INC_TCP_ACK_VALUE, 2479 ACTION_NEXT, 2480 ZERO, 2481 }; 2482 2483 static const enum index action_dec_tcp_ack[] = { 2484 ACTION_DEC_TCP_ACK_VALUE, 2485 ACTION_NEXT, 2486 ZERO, 2487 }; 2488 2489 static const enum index action_raw_encap[] = { 2490 ACTION_RAW_ENCAP_SIZE, 2491 ACTION_RAW_ENCAP_INDEX, 2492 ACTION_NEXT, 2493 ZERO, 2494 }; 2495 2496 static const enum index action_raw_decap[] = { 2497 ACTION_RAW_DECAP_INDEX, 2498 ACTION_NEXT, 2499 ZERO, 2500 }; 2501 2502 static const enum index action_ipv6_ext_remove[] = { 2503 ACTION_IPV6_EXT_REMOVE_INDEX, 2504 ACTION_NEXT, 2505 ZERO, 2506 }; 2507 2508 static const enum index action_ipv6_ext_push[] = { 2509 ACTION_IPV6_EXT_PUSH_INDEX, 2510 ACTION_NEXT, 2511 ZERO, 2512 }; 2513 2514 static const enum index action_set_tag[] = { 2515 ACTION_SET_TAG_DATA, 2516 ACTION_SET_TAG_INDEX, 2517 ACTION_SET_TAG_MASK, 2518 ACTION_NEXT, 2519 ZERO, 2520 }; 2521 2522 static const enum index action_set_meta[] = { 2523 ACTION_SET_META_DATA, 2524 ACTION_SET_META_MASK, 2525 ACTION_NEXT, 2526 ZERO, 2527 }; 2528 2529 static const enum index action_set_ipv4_dscp[] = { 2530 ACTION_SET_IPV4_DSCP_VALUE, 2531 ACTION_NEXT, 2532 ZERO, 2533 }; 2534 2535 static const enum index action_set_ipv6_dscp[] = { 2536 ACTION_SET_IPV6_DSCP_VALUE, 2537 ACTION_NEXT, 2538 ZERO, 2539 }; 2540 2541 static const enum index action_age[] = { 2542 ACTION_AGE, 2543 ACTION_AGE_TIMEOUT, 2544 ACTION_NEXT, 2545 ZERO, 2546 }; 2547 2548 static const enum index action_age_update[] = { 2549 ACTION_AGE_UPDATE, 2550 ACTION_AGE_UPDATE_TIMEOUT, 2551 ACTION_AGE_UPDATE_TOUCH, 2552 ACTION_NEXT, 2553 ZERO, 2554 }; 2555 2556 static const enum index action_sample[] = { 2557 ACTION_SAMPLE, 2558 ACTION_SAMPLE_RATIO, 2559 ACTION_SAMPLE_INDEX, 2560 ACTION_NEXT, 2561 ZERO, 2562 }; 2563 2564 static const enum index next_action_sample[] = { 2565 ACTION_QUEUE, 2566 ACTION_RSS, 2567 ACTION_MARK, 2568 ACTION_COUNT, 2569 ACTION_PORT_ID, 2570 ACTION_RAW_ENCAP, 2571 ACTION_VXLAN_ENCAP, 2572 ACTION_NVGRE_ENCAP, 2573 ACTION_REPRESENTED_PORT, 2574 ACTION_PORT_REPRESENTOR, 2575 ACTION_NEXT, 2576 ZERO, 2577 }; 2578 2579 static const enum index item_ipv6_push_ext[] = { 2580 ITEM_IPV6_PUSH_REMOVE_EXT, 2581 ZERO, 2582 }; 2583 2584 static const enum index item_ipv6_push_ext_type[] = { 2585 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 2586 ZERO, 2587 }; 2588 2589 static const enum index item_ipv6_push_ext_header[] = { 2590 ITEM_IPV6_ROUTING_EXT, 2591 ITEM_NEXT, 2592 ZERO, 2593 }; 2594 2595 static const enum index action_modify_field_dst[] = { 2596 ACTION_MODIFY_FIELD_DST_LEVEL, 2597 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 2598 ACTION_MODIFY_FIELD_DST_TYPE_ID, 2599 ACTION_MODIFY_FIELD_DST_CLASS_ID, 2600 ACTION_MODIFY_FIELD_DST_OFFSET, 2601 ACTION_MODIFY_FIELD_SRC_TYPE, 2602 ZERO, 2603 }; 2604 2605 static const enum index action_modify_field_src[] = { 2606 ACTION_MODIFY_FIELD_SRC_LEVEL, 2607 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 2608 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 2609 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 2610 ACTION_MODIFY_FIELD_SRC_OFFSET, 2611 ACTION_MODIFY_FIELD_SRC_VALUE, 2612 ACTION_MODIFY_FIELD_SRC_POINTER, 2613 ACTION_MODIFY_FIELD_WIDTH, 2614 ZERO, 2615 }; 2616 2617 static const enum index action_update_conntrack[] = { 2618 ACTION_CONNTRACK_UPDATE_DIR, 2619 ACTION_CONNTRACK_UPDATE_CTX, 2620 ACTION_NEXT, 2621 ZERO, 2622 }; 2623 2624 static const enum index action_port_representor[] = { 2625 ACTION_PORT_REPRESENTOR_PORT_ID, 2626 ACTION_NEXT, 2627 ZERO, 2628 }; 2629 2630 static const enum index action_represented_port[] = { 2631 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 2632 ACTION_NEXT, 2633 ZERO, 2634 }; 2635 2636 static const enum index action_nat64[] = { 2637 ACTION_NAT64_MODE, 2638 ACTION_NEXT, 2639 ZERO, 2640 }; 2641 2642 static const enum index next_hash_subcmd[] = { 2643 HASH_CALC_TABLE, 2644 HASH_CALC_ENCAP, 2645 ZERO, 2646 }; 2647 2648 static const enum index next_hash_encap_dest_subcmd[] = { 2649 ENCAP_HASH_FIELD_SRC_PORT, 2650 ENCAP_HASH_FIELD_GRE_FLOW_ID, 2651 ZERO, 2652 }; 2653 2654 static int parse_set_raw_encap_decap(struct context *, const struct token *, 2655 const char *, unsigned int, 2656 void *, unsigned int); 2657 static int parse_set_sample_action(struct context *, const struct token *, 2658 const char *, unsigned int, 2659 void *, unsigned int); 2660 static int parse_set_ipv6_ext_action(struct context *, const struct token *, 2661 const char *, unsigned int, 2662 void *, unsigned int); 2663 static int parse_set_init(struct context *, const struct token *, 2664 const char *, unsigned int, 2665 void *, unsigned int); 2666 static int 2667 parse_flex_handle(struct context *, const struct token *, 2668 const char *, unsigned int, void *, unsigned int); 2669 static int parse_init(struct context *, const struct token *, 2670 const char *, unsigned int, 2671 void *, unsigned int); 2672 static int parse_vc(struct context *, const struct token *, 2673 const char *, unsigned int, 2674 void *, unsigned int); 2675 static int parse_vc_spec(struct context *, const struct token *, 2676 const char *, unsigned int, void *, unsigned int); 2677 static int parse_vc_conf(struct context *, const struct token *, 2678 const char *, unsigned int, void *, unsigned int); 2679 static int parse_vc_conf_timeout(struct context *, const struct token *, 2680 const char *, unsigned int, void *, 2681 unsigned int); 2682 static int parse_vc_item_ecpri_type(struct context *, const struct token *, 2683 const char *, unsigned int, 2684 void *, unsigned int); 2685 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, 2686 const char *, unsigned int, 2687 void *, unsigned int); 2688 static int parse_vc_action_meter_color_type(struct context *, 2689 const struct token *, 2690 const char *, unsigned int, void *, 2691 unsigned int); 2692 static int parse_vc_action_rss(struct context *, const struct token *, 2693 const char *, unsigned int, void *, 2694 unsigned int); 2695 static int parse_vc_action_rss_func(struct context *, const struct token *, 2696 const char *, unsigned int, void *, 2697 unsigned int); 2698 static int parse_vc_action_rss_type(struct context *, const struct token *, 2699 const char *, unsigned int, void *, 2700 unsigned int); 2701 static int parse_vc_action_rss_queue(struct context *, const struct token *, 2702 const char *, unsigned int, void *, 2703 unsigned int); 2704 static int parse_vc_action_vxlan_encap(struct context *, const struct token *, 2705 const char *, unsigned int, void *, 2706 unsigned int); 2707 static int parse_vc_action_nvgre_encap(struct context *, const struct token *, 2708 const char *, unsigned int, void *, 2709 unsigned int); 2710 static int parse_vc_action_l2_encap(struct context *, const struct token *, 2711 const char *, unsigned int, void *, 2712 unsigned int); 2713 static int parse_vc_action_l2_decap(struct context *, const struct token *, 2714 const char *, unsigned int, void *, 2715 unsigned int); 2716 static int parse_vc_action_mplsogre_encap(struct context *, 2717 const struct token *, const char *, 2718 unsigned int, void *, unsigned int); 2719 static int parse_vc_action_mplsogre_decap(struct context *, 2720 const struct token *, const char *, 2721 unsigned int, void *, unsigned int); 2722 static int parse_vc_action_mplsoudp_encap(struct context *, 2723 const struct token *, const char *, 2724 unsigned int, void *, unsigned int); 2725 static int parse_vc_action_mplsoudp_decap(struct context *, 2726 const struct token *, const char *, 2727 unsigned int, void *, unsigned int); 2728 static int parse_vc_action_raw_encap(struct context *, 2729 const struct token *, const char *, 2730 unsigned int, void *, unsigned int); 2731 static int parse_vc_action_raw_decap(struct context *, 2732 const struct token *, const char *, 2733 unsigned int, void *, unsigned int); 2734 static int parse_vc_action_raw_encap_index(struct context *, 2735 const struct token *, const char *, 2736 unsigned int, void *, unsigned int); 2737 static int parse_vc_action_raw_decap_index(struct context *, 2738 const struct token *, const char *, 2739 unsigned int, void *, unsigned int); 2740 static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 2741 const char *str, unsigned int len, void *buf, 2742 unsigned int size); 2743 static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, 2744 const struct token *token, 2745 const char *str, unsigned int len, 2746 void *buf, 2747 unsigned int size); 2748 static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 2749 const char *str, unsigned int len, void *buf, 2750 unsigned int size); 2751 static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, 2752 const struct token *token, 2753 const char *str, unsigned int len, 2754 void *buf, 2755 unsigned int size); 2756 static int parse_vc_action_set_meta(struct context *ctx, 2757 const struct token *token, const char *str, 2758 unsigned int len, void *buf, 2759 unsigned int size); 2760 static int parse_vc_action_sample(struct context *ctx, 2761 const struct token *token, const char *str, 2762 unsigned int len, void *buf, 2763 unsigned int size); 2764 static int 2765 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 2766 const char *str, unsigned int len, void *buf, 2767 unsigned int size); 2768 static int 2769 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 2770 const char *str, unsigned int len, void *buf, 2771 unsigned int size); 2772 static int 2773 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 2774 const char *str, unsigned int len, void *buf, 2775 unsigned int size); 2776 static int 2777 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 2778 const char *str, unsigned int len, void *buf, 2779 unsigned int size); 2780 static int 2781 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 2782 const char *str, unsigned int len, void *buf, 2783 unsigned int size); 2784 static int parse_destroy(struct context *, const struct token *, 2785 const char *, unsigned int, 2786 void *, unsigned int); 2787 static int parse_flush(struct context *, const struct token *, 2788 const char *, unsigned int, 2789 void *, unsigned int); 2790 static int parse_dump(struct context *, const struct token *, 2791 const char *, unsigned int, 2792 void *, unsigned int); 2793 static int parse_query(struct context *, const struct token *, 2794 const char *, unsigned int, 2795 void *, unsigned int); 2796 static int parse_action(struct context *, const struct token *, 2797 const char *, unsigned int, 2798 void *, unsigned int); 2799 static int parse_list(struct context *, const struct token *, 2800 const char *, unsigned int, 2801 void *, unsigned int); 2802 static int parse_aged(struct context *, const struct token *, 2803 const char *, unsigned int, 2804 void *, unsigned int); 2805 static int parse_isolate(struct context *, const struct token *, 2806 const char *, unsigned int, 2807 void *, unsigned int); 2808 static int parse_configure(struct context *, const struct token *, 2809 const char *, unsigned int, 2810 void *, unsigned int); 2811 static int parse_template(struct context *, const struct token *, 2812 const char *, unsigned int, 2813 void *, unsigned int); 2814 static int parse_template_destroy(struct context *, const struct token *, 2815 const char *, unsigned int, 2816 void *, unsigned int); 2817 static int parse_table(struct context *, const struct token *, 2818 const char *, unsigned int, void *, unsigned int); 2819 static int parse_table_destroy(struct context *, const struct token *, 2820 const char *, unsigned int, 2821 void *, unsigned int); 2822 static int parse_qo(struct context *, const struct token *, 2823 const char *, unsigned int, 2824 void *, unsigned int); 2825 static int parse_qo_destroy(struct context *, const struct token *, 2826 const char *, unsigned int, 2827 void *, unsigned int); 2828 static int parse_qia(struct context *, const struct token *, 2829 const char *, unsigned int, 2830 void *, unsigned int); 2831 static int parse_qia_destroy(struct context *, const struct token *, 2832 const char *, unsigned int, 2833 void *, unsigned int); 2834 static int parse_push(struct context *, const struct token *, 2835 const char *, unsigned int, 2836 void *, unsigned int); 2837 static int parse_pull(struct context *, const struct token *, 2838 const char *, unsigned int, 2839 void *, unsigned int); 2840 static int parse_group(struct context *, const struct token *, 2841 const char *, unsigned int, 2842 void *, unsigned int); 2843 static int parse_hash(struct context *, const struct token *, 2844 const char *, unsigned int, 2845 void *, unsigned int); 2846 static int parse_tunnel(struct context *, const struct token *, 2847 const char *, unsigned int, 2848 void *, unsigned int); 2849 static int parse_flex(struct context *, const struct token *, 2850 const char *, unsigned int, void *, unsigned int); 2851 static int parse_int(struct context *, const struct token *, 2852 const char *, unsigned int, 2853 void *, unsigned int); 2854 static int parse_prefix(struct context *, const struct token *, 2855 const char *, unsigned int, 2856 void *, unsigned int); 2857 static int parse_boolean(struct context *, const struct token *, 2858 const char *, unsigned int, 2859 void *, unsigned int); 2860 static int parse_string(struct context *, const struct token *, 2861 const char *, unsigned int, 2862 void *, unsigned int); 2863 static int parse_hex(struct context *ctx, const struct token *token, 2864 const char *str, unsigned int len, 2865 void *buf, unsigned int size); 2866 static int parse_string0(struct context *, const struct token *, 2867 const char *, unsigned int, 2868 void *, unsigned int); 2869 static int parse_mac_addr(struct context *, const struct token *, 2870 const char *, unsigned int, 2871 void *, unsigned int); 2872 static int parse_ipv4_addr(struct context *, const struct token *, 2873 const char *, unsigned int, 2874 void *, unsigned int); 2875 static int parse_ipv6_addr(struct context *, const struct token *, 2876 const char *, unsigned int, 2877 void *, unsigned int); 2878 static int parse_port(struct context *, const struct token *, 2879 const char *, unsigned int, 2880 void *, unsigned int); 2881 static int parse_ia(struct context *, const struct token *, 2882 const char *, unsigned int, 2883 void *, unsigned int); 2884 static int parse_ia_destroy(struct context *ctx, const struct token *token, 2885 const char *str, unsigned int len, 2886 void *buf, unsigned int size); 2887 static int parse_ia_id2ptr(struct context *ctx, const struct token *token, 2888 const char *str, unsigned int len, void *buf, 2889 unsigned int size); 2890 2891 static int parse_indlst_id2ptr(struct context *ctx, const struct token *token, 2892 const char *str, unsigned int len, void *buf, 2893 unsigned int size); 2894 static int parse_ia_port(struct context *ctx, const struct token *token, 2895 const char *str, unsigned int len, void *buf, 2896 unsigned int size); 2897 static int parse_mp(struct context *, const struct token *, 2898 const char *, unsigned int, 2899 void *, unsigned int); 2900 static int parse_meter_profile_id2ptr(struct context *ctx, 2901 const struct token *token, 2902 const char *str, unsigned int len, 2903 void *buf, unsigned int size); 2904 static int parse_meter_policy_id2ptr(struct context *ctx, 2905 const struct token *token, 2906 const char *str, unsigned int len, 2907 void *buf, unsigned int size); 2908 static int parse_meter_color(struct context *ctx, const struct token *token, 2909 const char *str, unsigned int len, void *buf, 2910 unsigned int size); 2911 static int parse_insertion_table_type(struct context *ctx, const struct token *token, 2912 const char *str, unsigned int len, void *buf, 2913 unsigned int size); 2914 static int parse_hash_table_type(struct context *ctx, const struct token *token, 2915 const char *str, unsigned int len, void *buf, 2916 unsigned int size); 2917 static int 2918 parse_quota_state_name(struct context *ctx, const struct token *token, 2919 const char *str, unsigned int len, void *buf, 2920 unsigned int size); 2921 static int 2922 parse_quota_mode_name(struct context *ctx, const struct token *token, 2923 const char *str, unsigned int len, void *buf, 2924 unsigned int size); 2925 static int 2926 parse_quota_update_name(struct context *ctx, const struct token *token, 2927 const char *str, unsigned int len, void *buf, 2928 unsigned int size); 2929 static int 2930 parse_qu_mode_name(struct context *ctx, const struct token *token, 2931 const char *str, unsigned int len, void *buf, 2932 unsigned int size); 2933 static int comp_none(struct context *, const struct token *, 2934 unsigned int, char *, unsigned int); 2935 static int comp_boolean(struct context *, const struct token *, 2936 unsigned int, char *, unsigned int); 2937 static int comp_action(struct context *, const struct token *, 2938 unsigned int, char *, unsigned int); 2939 static int comp_port(struct context *, const struct token *, 2940 unsigned int, char *, unsigned int); 2941 static int comp_rule_id(struct context *, const struct token *, 2942 unsigned int, char *, unsigned int); 2943 static int comp_vc_action_rss_type(struct context *, const struct token *, 2944 unsigned int, char *, unsigned int); 2945 static int comp_vc_action_rss_queue(struct context *, const struct token *, 2946 unsigned int, char *, unsigned int); 2947 static int comp_set_raw_index(struct context *, const struct token *, 2948 unsigned int, char *, unsigned int); 2949 static int comp_set_sample_index(struct context *, const struct token *, 2950 unsigned int, char *, unsigned int); 2951 static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 2952 unsigned int ent, char *buf, unsigned int size); 2953 static int comp_set_modify_field_op(struct context *, const struct token *, 2954 unsigned int, char *, unsigned int); 2955 static int comp_set_modify_field_id(struct context *, const struct token *, 2956 unsigned int, char *, unsigned int); 2957 static int comp_pattern_template_id(struct context *, const struct token *, 2958 unsigned int, char *, unsigned int); 2959 static int comp_actions_template_id(struct context *, const struct token *, 2960 unsigned int, char *, unsigned int); 2961 static int comp_table_id(struct context *, const struct token *, 2962 unsigned int, char *, unsigned int); 2963 static int comp_queue_id(struct context *, const struct token *, 2964 unsigned int, char *, unsigned int); 2965 static int comp_meter_color(struct context *, const struct token *, 2966 unsigned int, char *, unsigned int); 2967 static int comp_insertion_table_type(struct context *, const struct token *, 2968 unsigned int, char *, unsigned int); 2969 static int comp_hash_table_type(struct context *, const struct token *, 2970 unsigned int, char *, unsigned int); 2971 static int 2972 comp_quota_state_name(struct context *ctx, const struct token *token, 2973 unsigned int ent, char *buf, unsigned int size); 2974 static int 2975 comp_quota_mode_name(struct context *ctx, const struct token *token, 2976 unsigned int ent, char *buf, unsigned int size); 2977 static int 2978 comp_quota_update_name(struct context *ctx, const struct token *token, 2979 unsigned int ent, char *buf, unsigned int size); 2980 static int 2981 comp_qu_mode_name(struct context *ctx, const struct token *token, 2982 unsigned int ent, char *buf, unsigned int size); 2983 static int 2984 comp_set_compare_field_id(struct context *ctx, const struct token *token, 2985 unsigned int ent, char *buf, unsigned int size); 2986 static int 2987 comp_set_compare_op(struct context *ctx, const struct token *token, 2988 unsigned int ent, char *buf, unsigned int size); 2989 static int 2990 parse_vc_compare_op(struct context *ctx, const struct token *token, 2991 const char *str, unsigned int len, void *buf, 2992 unsigned int size); 2993 static int 2994 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 2995 const char *str, unsigned int len, void *buf, 2996 unsigned int size); 2997 static int 2998 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 2999 const char *str, unsigned int len, void *buf, 3000 unsigned int size); 3001 3002 struct indlst_conf { 3003 uint32_t id; 3004 uint32_t conf_num; 3005 struct rte_flow_action *actions; 3006 const void **conf; 3007 SLIST_ENTRY(indlst_conf) next; 3008 }; 3009 3010 static const struct indlst_conf *indirect_action_list_conf_get(uint32_t conf_id); 3011 3012 /** Token definitions. */ 3013 static const struct token token_list[] = { 3014 /* Special tokens. */ 3015 [ZERO] = { 3016 .name = "ZERO", 3017 .help = "null entry, abused as the entry point", 3018 .next = NEXT(NEXT_ENTRY(FLOW, ADD)), 3019 }, 3020 [END] = { 3021 .name = "", 3022 .type = "RETURN", 3023 .help = "command may end here", 3024 }, 3025 [START_SET] = { 3026 .name = "START_SET", 3027 .help = "null entry, abused as the entry point for set", 3028 .next = NEXT(NEXT_ENTRY(SET)), 3029 }, 3030 [END_SET] = { 3031 .name = "end_set", 3032 .type = "RETURN", 3033 .help = "set command may end here", 3034 }, 3035 /* Common tokens. */ 3036 [COMMON_INTEGER] = { 3037 .name = "{int}", 3038 .type = "INTEGER", 3039 .help = "integer value", 3040 .call = parse_int, 3041 .comp = comp_none, 3042 }, 3043 [COMMON_UNSIGNED] = { 3044 .name = "{unsigned}", 3045 .type = "UNSIGNED", 3046 .help = "unsigned integer value", 3047 .call = parse_int, 3048 .comp = comp_none, 3049 }, 3050 [COMMON_PREFIX] = { 3051 .name = "{prefix}", 3052 .type = "PREFIX", 3053 .help = "prefix length for bit-mask", 3054 .call = parse_prefix, 3055 .comp = comp_none, 3056 }, 3057 [COMMON_BOOLEAN] = { 3058 .name = "{boolean}", 3059 .type = "BOOLEAN", 3060 .help = "any boolean value", 3061 .call = parse_boolean, 3062 .comp = comp_boolean, 3063 }, 3064 [COMMON_STRING] = { 3065 .name = "{string}", 3066 .type = "STRING", 3067 .help = "fixed string", 3068 .call = parse_string, 3069 .comp = comp_none, 3070 }, 3071 [COMMON_HEX] = { 3072 .name = "{hex}", 3073 .type = "HEX", 3074 .help = "fixed string", 3075 .call = parse_hex, 3076 }, 3077 [COMMON_FILE_PATH] = { 3078 .name = "{file path}", 3079 .type = "STRING", 3080 .help = "file path", 3081 .call = parse_string0, 3082 .comp = comp_none, 3083 }, 3084 [COMMON_MAC_ADDR] = { 3085 .name = "{MAC address}", 3086 .type = "MAC-48", 3087 .help = "standard MAC address notation", 3088 .call = parse_mac_addr, 3089 .comp = comp_none, 3090 }, 3091 [COMMON_IPV4_ADDR] = { 3092 .name = "{IPv4 address}", 3093 .type = "IPV4 ADDRESS", 3094 .help = "standard IPv4 address notation", 3095 .call = parse_ipv4_addr, 3096 .comp = comp_none, 3097 }, 3098 [COMMON_IPV6_ADDR] = { 3099 .name = "{IPv6 address}", 3100 .type = "IPV6 ADDRESS", 3101 .help = "standard IPv6 address notation", 3102 .call = parse_ipv6_addr, 3103 .comp = comp_none, 3104 }, 3105 [COMMON_RULE_ID] = { 3106 .name = "{rule id}", 3107 .type = "RULE ID", 3108 .help = "rule identifier", 3109 .call = parse_int, 3110 .comp = comp_rule_id, 3111 }, 3112 [COMMON_PORT_ID] = { 3113 .name = "{port_id}", 3114 .type = "PORT ID", 3115 .help = "port identifier", 3116 .call = parse_port, 3117 .comp = comp_port, 3118 }, 3119 [COMMON_GROUP_ID] = { 3120 .name = "{group_id}", 3121 .type = "GROUP ID", 3122 .help = "group identifier", 3123 .call = parse_int, 3124 .comp = comp_none, 3125 }, 3126 [COMMON_PRIORITY_LEVEL] = { 3127 .name = "{level}", 3128 .type = "PRIORITY", 3129 .help = "priority level", 3130 .call = parse_int, 3131 .comp = comp_none, 3132 }, 3133 [COMMON_INDIRECT_ACTION_ID] = { 3134 .name = "{indirect_action_id}", 3135 .type = "INDIRECT_ACTION_ID", 3136 .help = "indirect action id", 3137 .call = parse_int, 3138 .comp = comp_none, 3139 }, 3140 [COMMON_PROFILE_ID] = { 3141 .name = "{profile_id}", 3142 .type = "PROFILE_ID", 3143 .help = "profile id", 3144 .call = parse_int, 3145 .comp = comp_none, 3146 }, 3147 [COMMON_POLICY_ID] = { 3148 .name = "{policy_id}", 3149 .type = "POLICY_ID", 3150 .help = "policy id", 3151 .call = parse_int, 3152 .comp = comp_none, 3153 }, 3154 [COMMON_FLEX_TOKEN] = { 3155 .name = "{flex token}", 3156 .type = "flex token", 3157 .help = "flex token", 3158 .call = parse_int, 3159 .comp = comp_none, 3160 }, 3161 [COMMON_FLEX_HANDLE] = { 3162 .name = "{flex handle}", 3163 .type = "FLEX HANDLE", 3164 .help = "fill flex item data", 3165 .call = parse_flex_handle, 3166 .comp = comp_none, 3167 }, 3168 [COMMON_PATTERN_TEMPLATE_ID] = { 3169 .name = "{pattern_template_id}", 3170 .type = "PATTERN_TEMPLATE_ID", 3171 .help = "pattern template id", 3172 .call = parse_int, 3173 .comp = comp_pattern_template_id, 3174 }, 3175 [COMMON_ACTIONS_TEMPLATE_ID] = { 3176 .name = "{actions_template_id}", 3177 .type = "ACTIONS_TEMPLATE_ID", 3178 .help = "actions template id", 3179 .call = parse_int, 3180 .comp = comp_actions_template_id, 3181 }, 3182 [COMMON_TABLE_ID] = { 3183 .name = "{table_id}", 3184 .type = "TABLE_ID", 3185 .help = "table id", 3186 .call = parse_int, 3187 .comp = comp_table_id, 3188 }, 3189 [COMMON_QUEUE_ID] = { 3190 .name = "{queue_id}", 3191 .type = "QUEUE_ID", 3192 .help = "queue id", 3193 .call = parse_int, 3194 .comp = comp_queue_id, 3195 }, 3196 /* Top-level command. */ 3197 [FLOW] = { 3198 .name = "flow", 3199 .type = "{command} {port_id} [{arg} [...]]", 3200 .help = "manage ingress/egress flow rules", 3201 .next = NEXT(NEXT_ENTRY 3202 (INFO, 3203 CONFIGURE, 3204 PATTERN_TEMPLATE, 3205 ACTIONS_TEMPLATE, 3206 TABLE, 3207 FLOW_GROUP, 3208 INDIRECT_ACTION, 3209 VALIDATE, 3210 CREATE, 3211 DESTROY, 3212 FLUSH, 3213 DUMP, 3214 LIST, 3215 AGED, 3216 QUERY, 3217 ISOLATE, 3218 TUNNEL, 3219 FLEX, 3220 QUEUE, 3221 PUSH, 3222 PULL, 3223 HASH)), 3224 .call = parse_init, 3225 }, 3226 /* Top-level command. */ 3227 [INFO] = { 3228 .name = "info", 3229 .help = "get information about flow engine", 3230 .next = NEXT(NEXT_ENTRY(END), 3231 NEXT_ENTRY(COMMON_PORT_ID)), 3232 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3233 .call = parse_configure, 3234 }, 3235 /* Top-level command. */ 3236 [CONFIGURE] = { 3237 .name = "configure", 3238 .help = "configure flow engine", 3239 .next = NEXT(next_config_attr, 3240 NEXT_ENTRY(COMMON_PORT_ID)), 3241 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3242 .call = parse_configure, 3243 }, 3244 /* Configure arguments. */ 3245 [CONFIG_QUEUES_NUMBER] = { 3246 .name = "queues_number", 3247 .help = "number of queues", 3248 .next = NEXT(next_config_attr, 3249 NEXT_ENTRY(COMMON_UNSIGNED)), 3250 .args = ARGS(ARGS_ENTRY(struct buffer, 3251 args.configure.nb_queue)), 3252 }, 3253 [CONFIG_QUEUES_SIZE] = { 3254 .name = "queues_size", 3255 .help = "number of elements in queues", 3256 .next = NEXT(next_config_attr, 3257 NEXT_ENTRY(COMMON_UNSIGNED)), 3258 .args = ARGS(ARGS_ENTRY(struct buffer, 3259 args.configure.queue_attr.size)), 3260 }, 3261 [CONFIG_COUNTERS_NUMBER] = { 3262 .name = "counters_number", 3263 .help = "number of counters", 3264 .next = NEXT(next_config_attr, 3265 NEXT_ENTRY(COMMON_UNSIGNED)), 3266 .args = ARGS(ARGS_ENTRY(struct buffer, 3267 args.configure.port_attr.nb_counters)), 3268 }, 3269 [CONFIG_AGING_OBJECTS_NUMBER] = { 3270 .name = "aging_counters_number", 3271 .help = "number of aging objects", 3272 .next = NEXT(next_config_attr, 3273 NEXT_ENTRY(COMMON_UNSIGNED)), 3274 .args = ARGS(ARGS_ENTRY(struct buffer, 3275 args.configure.port_attr.nb_aging_objects)), 3276 }, 3277 [CONFIG_QUOTAS_NUMBER] = { 3278 .name = "quotas_number", 3279 .help = "number of quotas", 3280 .next = NEXT(next_config_attr, 3281 NEXT_ENTRY(COMMON_UNSIGNED)), 3282 .args = ARGS(ARGS_ENTRY(struct buffer, 3283 args.configure.port_attr.nb_quotas)), 3284 }, 3285 [CONFIG_METERS_NUMBER] = { 3286 .name = "meters_number", 3287 .help = "number of meters", 3288 .next = NEXT(next_config_attr, 3289 NEXT_ENTRY(COMMON_UNSIGNED)), 3290 .args = ARGS(ARGS_ENTRY(struct buffer, 3291 args.configure.port_attr.nb_meters)), 3292 }, 3293 [CONFIG_CONN_TRACK_NUMBER] = { 3294 .name = "conn_tracks_number", 3295 .help = "number of connection trackings", 3296 .next = NEXT(next_config_attr, 3297 NEXT_ENTRY(COMMON_UNSIGNED)), 3298 .args = ARGS(ARGS_ENTRY(struct buffer, 3299 args.configure.port_attr.nb_conn_tracks)), 3300 }, 3301 [CONFIG_FLAGS] = { 3302 .name = "flags", 3303 .help = "configuration flags", 3304 .next = NEXT(next_config_attr, 3305 NEXT_ENTRY(COMMON_UNSIGNED)), 3306 .args = ARGS(ARGS_ENTRY(struct buffer, 3307 args.configure.port_attr.flags)), 3308 }, 3309 [CONFIG_HOST_PORT] = { 3310 .name = "host_port", 3311 .help = "host port for shared objects", 3312 .next = NEXT(next_config_attr, 3313 NEXT_ENTRY(COMMON_UNSIGNED)), 3314 .args = ARGS(ARGS_ENTRY(struct buffer, 3315 args.configure.port_attr.host_port_id)), 3316 }, 3317 /* Top-level command. */ 3318 [PATTERN_TEMPLATE] = { 3319 .name = "pattern_template", 3320 .type = "{command} {port_id} [{arg} [...]]", 3321 .help = "manage pattern templates", 3322 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3323 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3324 .call = parse_template, 3325 }, 3326 /* Sub-level commands. */ 3327 [PATTERN_TEMPLATE_CREATE] = { 3328 .name = "create", 3329 .help = "create pattern template", 3330 .next = NEXT(next_pt_attr), 3331 .call = parse_template, 3332 }, 3333 [PATTERN_TEMPLATE_DESTROY] = { 3334 .name = "destroy", 3335 .help = "destroy pattern template", 3336 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), 3337 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3338 .call = parse_template_destroy, 3339 }, 3340 /* Pattern template arguments. */ 3341 [PATTERN_TEMPLATE_CREATE_ID] = { 3342 .name = "pattern_template_id", 3343 .help = "specify a pattern template id to create", 3344 .next = NEXT(next_pt_attr, 3345 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3346 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), 3347 }, 3348 [PATTERN_TEMPLATE_DESTROY_ID] = { 3349 .name = "pattern_template", 3350 .help = "specify a pattern template id to destroy", 3351 .next = NEXT(next_pt_destroy_attr, 3352 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3353 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3354 args.templ_destroy.template_id)), 3355 .call = parse_template_destroy, 3356 }, 3357 [PATTERN_TEMPLATE_RELAXED_MATCHING] = { 3358 .name = "relaxed", 3359 .help = "is matching relaxed", 3360 .next = NEXT(next_pt_attr, 3361 NEXT_ENTRY(COMMON_BOOLEAN)), 3362 .args = ARGS(ARGS_ENTRY_BF(struct buffer, 3363 args.vc.attr.reserved, 1)), 3364 }, 3365 [PATTERN_TEMPLATE_INGRESS] = { 3366 .name = "ingress", 3367 .help = "attribute pattern to ingress", 3368 .next = NEXT(next_pt_attr), 3369 .call = parse_template, 3370 }, 3371 [PATTERN_TEMPLATE_EGRESS] = { 3372 .name = "egress", 3373 .help = "attribute pattern to egress", 3374 .next = NEXT(next_pt_attr), 3375 .call = parse_template, 3376 }, 3377 [PATTERN_TEMPLATE_TRANSFER] = { 3378 .name = "transfer", 3379 .help = "attribute pattern to transfer", 3380 .next = NEXT(next_pt_attr), 3381 .call = parse_template, 3382 }, 3383 [PATTERN_TEMPLATE_SPEC] = { 3384 .name = "template", 3385 .help = "specify item to create pattern template", 3386 .next = NEXT(next_item), 3387 }, 3388 /* Top-level command. */ 3389 [ACTIONS_TEMPLATE] = { 3390 .name = "actions_template", 3391 .type = "{command} {port_id} [{arg} [...]]", 3392 .help = "manage actions templates", 3393 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3394 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3395 .call = parse_template, 3396 }, 3397 /* Sub-level commands. */ 3398 [ACTIONS_TEMPLATE_CREATE] = { 3399 .name = "create", 3400 .help = "create actions template", 3401 .next = NEXT(next_at_attr), 3402 .call = parse_template, 3403 }, 3404 [ACTIONS_TEMPLATE_DESTROY] = { 3405 .name = "destroy", 3406 .help = "destroy actions template", 3407 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), 3408 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3409 .call = parse_template_destroy, 3410 }, 3411 /* Actions template arguments. */ 3412 [ACTIONS_TEMPLATE_CREATE_ID] = { 3413 .name = "actions_template_id", 3414 .help = "specify an actions template id to create", 3415 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), 3416 NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), 3417 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3418 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), 3419 }, 3420 [ACTIONS_TEMPLATE_DESTROY_ID] = { 3421 .name = "actions_template", 3422 .help = "specify an actions template id to destroy", 3423 .next = NEXT(next_at_destroy_attr, 3424 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3425 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3426 args.templ_destroy.template_id)), 3427 .call = parse_template_destroy, 3428 }, 3429 [ACTIONS_TEMPLATE_INGRESS] = { 3430 .name = "ingress", 3431 .help = "attribute actions to ingress", 3432 .next = NEXT(next_at_attr), 3433 .call = parse_template, 3434 }, 3435 [ACTIONS_TEMPLATE_EGRESS] = { 3436 .name = "egress", 3437 .help = "attribute actions to egress", 3438 .next = NEXT(next_at_attr), 3439 .call = parse_template, 3440 }, 3441 [ACTIONS_TEMPLATE_TRANSFER] = { 3442 .name = "transfer", 3443 .help = "attribute actions to transfer", 3444 .next = NEXT(next_at_attr), 3445 .call = parse_template, 3446 }, 3447 [ACTIONS_TEMPLATE_SPEC] = { 3448 .name = "template", 3449 .help = "specify action to create actions template", 3450 .next = NEXT(next_action), 3451 .call = parse_template, 3452 }, 3453 [ACTIONS_TEMPLATE_MASK] = { 3454 .name = "mask", 3455 .help = "specify action mask to create actions template", 3456 .next = NEXT(next_action), 3457 .call = parse_template, 3458 }, 3459 /* Top-level command. */ 3460 [TABLE] = { 3461 .name = "template_table", 3462 .type = "{command} {port_id} [{arg} [...]]", 3463 .help = "manage template tables", 3464 .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3465 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3466 .call = parse_table, 3467 }, 3468 /* Sub-level commands. */ 3469 [TABLE_CREATE] = { 3470 .name = "create", 3471 .help = "create template table", 3472 .next = NEXT(next_table_attr), 3473 .call = parse_table, 3474 }, 3475 [TABLE_DESTROY] = { 3476 .name = "destroy", 3477 .help = "destroy template table", 3478 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3479 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3480 .call = parse_table_destroy, 3481 }, 3482 [TABLE_RESIZE] = { 3483 .name = "resize", 3484 .help = "resize template table", 3485 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_ID)), 3486 .call = parse_table 3487 }, 3488 [TABLE_RESIZE_COMPLETE] = { 3489 .name = "resize_complete", 3490 .help = "complete table resize", 3491 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3492 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3493 .call = parse_table_destroy, 3494 }, 3495 /* Table arguments. */ 3496 [TABLE_CREATE_ID] = { 3497 .name = "table_id", 3498 .help = "specify table id to create", 3499 .next = NEXT(next_table_attr, 3500 NEXT_ENTRY(COMMON_TABLE_ID)), 3501 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3502 }, 3503 [TABLE_DESTROY_ID] = { 3504 .name = "table", 3505 .help = "table id", 3506 .next = NEXT(next_table_destroy_attr, 3507 NEXT_ENTRY(COMMON_TABLE_ID)), 3508 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3509 args.table_destroy.table_id)), 3510 .call = parse_table_destroy, 3511 }, 3512 [TABLE_RESIZE_ID] = { 3513 .name = "table_resize_id", 3514 .help = "table resize id", 3515 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_RULES_NUMBER), 3516 NEXT_ENTRY(COMMON_TABLE_ID)), 3517 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3518 .call = parse_table 3519 }, 3520 [TABLE_RESIZE_RULES_NUMBER] = { 3521 .name = "table_resize_rules_num", 3522 .help = "table resize rules number", 3523 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_UNSIGNED)), 3524 .args = ARGS(ARGS_ENTRY(struct buffer, 3525 args.table.attr.nb_flows)), 3526 .call = parse_table 3527 }, 3528 [TABLE_INSERTION_TYPE] = { 3529 .name = "insertion_type", 3530 .help = "specify insertion type", 3531 .next = NEXT(next_table_attr, 3532 NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)), 3533 .args = ARGS(ARGS_ENTRY(struct buffer, 3534 args.table.attr.insertion_type)), 3535 }, 3536 [TABLE_INSERTION_TYPE_NAME] = { 3537 .name = "insertion_type_name", 3538 .help = "insertion type name", 3539 .call = parse_insertion_table_type, 3540 .comp = comp_insertion_table_type, 3541 }, 3542 [TABLE_HASH_FUNC] = { 3543 .name = "hash_func", 3544 .help = "specify hash calculation function", 3545 .next = NEXT(next_table_attr, 3546 NEXT_ENTRY(TABLE_HASH_FUNC_NAME)), 3547 .args = ARGS(ARGS_ENTRY(struct buffer, 3548 args.table.attr.hash_func)), 3549 }, 3550 [TABLE_HASH_FUNC_NAME] = { 3551 .name = "hash_func_name", 3552 .help = "hash calculation function name", 3553 .call = parse_hash_table_type, 3554 .comp = comp_hash_table_type, 3555 }, 3556 [TABLE_GROUP] = { 3557 .name = "group", 3558 .help = "specify a group", 3559 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3560 .args = ARGS(ARGS_ENTRY(struct buffer, 3561 args.table.attr.flow_attr.group)), 3562 }, 3563 [TABLE_PRIORITY] = { 3564 .name = "priority", 3565 .help = "specify a priority level", 3566 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 3567 .args = ARGS(ARGS_ENTRY(struct buffer, 3568 args.table.attr.flow_attr.priority)), 3569 }, 3570 [TABLE_EGRESS] = { 3571 .name = "egress", 3572 .help = "affect rule to egress", 3573 .next = NEXT(next_table_attr), 3574 .call = parse_table, 3575 }, 3576 [TABLE_INGRESS] = { 3577 .name = "ingress", 3578 .help = "affect rule to ingress", 3579 .next = NEXT(next_table_attr), 3580 .call = parse_table, 3581 }, 3582 [TABLE_TRANSFER] = { 3583 .name = "transfer", 3584 .help = "affect rule to transfer", 3585 .next = NEXT(next_table_attr), 3586 .call = parse_table, 3587 }, 3588 [TABLE_TRANSFER_WIRE_ORIG] = { 3589 .name = "wire_orig", 3590 .help = "affect rule direction to transfer", 3591 .next = NEXT(next_table_attr), 3592 .call = parse_table, 3593 }, 3594 [TABLE_TRANSFER_VPORT_ORIG] = { 3595 .name = "vport_orig", 3596 .help = "affect rule direction to transfer", 3597 .next = NEXT(next_table_attr), 3598 .call = parse_table, 3599 }, 3600 [TABLE_RESIZABLE] = { 3601 .name = "resizable", 3602 .help = "set resizable attribute", 3603 .next = NEXT(next_table_attr), 3604 .call = parse_table, 3605 }, 3606 [TABLE_RULES_NUMBER] = { 3607 .name = "rules_number", 3608 .help = "number of rules in table", 3609 .next = NEXT(next_table_attr, 3610 NEXT_ENTRY(COMMON_UNSIGNED)), 3611 .args = ARGS(ARGS_ENTRY(struct buffer, 3612 args.table.attr.nb_flows)), 3613 .call = parse_table, 3614 }, 3615 [TABLE_PATTERN_TEMPLATE] = { 3616 .name = "pattern_template", 3617 .help = "specify pattern template id", 3618 .next = NEXT(next_table_attr, 3619 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3620 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3621 args.table.pat_templ_id)), 3622 .call = parse_table, 3623 }, 3624 [TABLE_ACTIONS_TEMPLATE] = { 3625 .name = "actions_template", 3626 .help = "specify actions template id", 3627 .next = NEXT(next_table_attr, 3628 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3629 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3630 args.table.act_templ_id)), 3631 .call = parse_table, 3632 }, 3633 /* Top-level command. */ 3634 [FLOW_GROUP] = { 3635 .name = "group", 3636 .help = "manage flow groups", 3637 .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), 3638 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3639 .call = parse_group, 3640 }, 3641 /* Sub-level commands. */ 3642 [GROUP_SET_MISS_ACTIONS] = { 3643 .name = "set_miss_actions", 3644 .help = "set group miss actions", 3645 .next = NEXT(next_action), 3646 .call = parse_group, 3647 }, 3648 /* Group arguments */ 3649 [GROUP_ID] = { 3650 .name = "group_id", 3651 .help = "group id", 3652 .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3653 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3654 }, 3655 [GROUP_INGRESS] = { 3656 .name = "ingress", 3657 .help = "group ingress attr", 3658 .next = NEXT(next_group_attr), 3659 .call = parse_group, 3660 }, 3661 [GROUP_EGRESS] = { 3662 .name = "egress", 3663 .help = "group egress attr", 3664 .next = NEXT(next_group_attr), 3665 .call = parse_group, 3666 }, 3667 [GROUP_TRANSFER] = { 3668 .name = "transfer", 3669 .help = "group transfer attr", 3670 .next = NEXT(next_group_attr), 3671 .call = parse_group, 3672 }, 3673 /* Top-level command. */ 3674 [QUEUE] = { 3675 .name = "queue", 3676 .help = "queue a flow rule operation", 3677 .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3678 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3679 .call = parse_qo, 3680 }, 3681 /* Sub-level commands. */ 3682 [QUEUE_CREATE] = { 3683 .name = "create", 3684 .help = "create a flow rule", 3685 .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), 3686 NEXT_ENTRY(COMMON_QUEUE_ID)), 3687 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3688 .call = parse_qo, 3689 }, 3690 [QUEUE_DESTROY] = { 3691 .name = "destroy", 3692 .help = "destroy a flow rule", 3693 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3694 NEXT_ENTRY(COMMON_QUEUE_ID)), 3695 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3696 .call = parse_qo_destroy, 3697 }, 3698 [QUEUE_FLOW_UPDATE_RESIZED] = { 3699 .name = "update_resized", 3700 .help = "update a flow after table resize", 3701 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3702 NEXT_ENTRY(COMMON_QUEUE_ID)), 3703 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3704 .call = parse_qo_destroy, 3705 }, 3706 [QUEUE_UPDATE] = { 3707 .name = "update", 3708 .help = "update a flow rule", 3709 .next = NEXT(NEXT_ENTRY(QUEUE_UPDATE_ID), 3710 NEXT_ENTRY(COMMON_QUEUE_ID)), 3711 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3712 .call = parse_qo, 3713 }, 3714 [QUEUE_AGED] = { 3715 .name = "aged", 3716 .help = "list and destroy aged flows", 3717 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), 3718 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3719 .call = parse_aged, 3720 }, 3721 [QUEUE_INDIRECT_ACTION] = { 3722 .name = "indirect_action", 3723 .help = "queue indirect actions", 3724 .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), 3725 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3726 .call = parse_qia, 3727 }, 3728 /* Queue arguments. */ 3729 [QUEUE_TEMPLATE_TABLE] = { 3730 .name = "template_table", 3731 .help = "specify table id", 3732 .next = NEXT(next_async_insert_subcmd, 3733 NEXT_ENTRY(COMMON_TABLE_ID)), 3734 .args = ARGS(ARGS_ENTRY(struct buffer, 3735 args.vc.table_id)), 3736 .call = parse_qo, 3737 }, 3738 [QUEUE_PATTERN_TEMPLATE] = { 3739 .name = "pattern_template", 3740 .help = "specify pattern template index", 3741 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3742 NEXT_ENTRY(COMMON_UNSIGNED)), 3743 .args = ARGS(ARGS_ENTRY(struct buffer, 3744 args.vc.pat_templ_id)), 3745 .call = parse_qo, 3746 }, 3747 [QUEUE_ACTIONS_TEMPLATE] = { 3748 .name = "actions_template", 3749 .help = "specify actions template index", 3750 .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), 3751 NEXT_ENTRY(COMMON_UNSIGNED)), 3752 .args = ARGS(ARGS_ENTRY(struct buffer, 3753 args.vc.act_templ_id)), 3754 .call = parse_qo, 3755 }, 3756 [QUEUE_RULE_ID] = { 3757 .name = "rule_index", 3758 .help = "specify flow rule index", 3759 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3760 NEXT_ENTRY(COMMON_UNSIGNED)), 3761 .args = ARGS(ARGS_ENTRY(struct buffer, 3762 args.vc.rule_id)), 3763 .call = parse_qo, 3764 }, 3765 [QUEUE_CREATE_POSTPONE] = { 3766 .name = "postpone", 3767 .help = "postpone create operation", 3768 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3769 NEXT_ENTRY(COMMON_BOOLEAN)), 3770 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3771 .call = parse_qo, 3772 }, 3773 [QUEUE_DESTROY_POSTPONE] = { 3774 .name = "postpone", 3775 .help = "postpone destroy operation", 3776 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3777 NEXT_ENTRY(COMMON_BOOLEAN)), 3778 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3779 .call = parse_qo_destroy, 3780 }, 3781 [QUEUE_DESTROY_ID] = { 3782 .name = "rule", 3783 .help = "specify rule id to destroy", 3784 .next = NEXT(next_queue_destroy_attr, 3785 NEXT_ENTRY(COMMON_UNSIGNED)), 3786 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3787 args.destroy.rule)), 3788 .call = parse_qo_destroy, 3789 }, 3790 [QUEUE_UPDATE_ID] = { 3791 .name = "rule", 3792 .help = "specify rule id to update", 3793 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3794 NEXT_ENTRY(COMMON_UNSIGNED)), 3795 .args = ARGS(ARGS_ENTRY(struct buffer, 3796 args.vc.rule_id)), 3797 .call = parse_qo, 3798 }, 3799 /* Queue indirect action arguments */ 3800 [QUEUE_INDIRECT_ACTION_CREATE] = { 3801 .name = "create", 3802 .help = "create indirect action", 3803 .next = NEXT(next_qia_create_attr), 3804 .call = parse_qia, 3805 }, 3806 [QUEUE_INDIRECT_ACTION_UPDATE] = { 3807 .name = "update", 3808 .help = "update indirect action", 3809 .next = NEXT(next_qia_update_attr, 3810 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3811 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3812 .call = parse_qia, 3813 }, 3814 [QUEUE_INDIRECT_ACTION_DESTROY] = { 3815 .name = "destroy", 3816 .help = "destroy indirect action", 3817 .next = NEXT(next_qia_destroy_attr), 3818 .call = parse_qia_destroy, 3819 }, 3820 [QUEUE_INDIRECT_ACTION_QUERY] = { 3821 .name = "query", 3822 .help = "query indirect action", 3823 .next = NEXT(next_qia_query_attr, 3824 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3825 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3826 .call = parse_qia, 3827 }, 3828 /* Indirect action destroy arguments. */ 3829 [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { 3830 .name = "postpone", 3831 .help = "postpone destroy operation", 3832 .next = NEXT(next_qia_destroy_attr, 3833 NEXT_ENTRY(COMMON_BOOLEAN)), 3834 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3835 }, 3836 [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { 3837 .name = "action_id", 3838 .help = "specify a indirect action id to destroy", 3839 .next = NEXT(next_qia_destroy_attr, 3840 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3841 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3842 args.ia_destroy.action_id)), 3843 .call = parse_qia_destroy, 3844 }, 3845 [QUEUE_INDIRECT_ACTION_QUERY_UPDATE] = { 3846 .name = "query_update", 3847 .help = "indirect query [and|or] update action", 3848 .next = NEXT(next_qia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3849 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3850 .call = parse_qia 3851 }, 3852 [QUEUE_INDIRECT_ACTION_QU_MODE] = { 3853 .name = "mode", 3854 .help = "indirect query [and|or] update action", 3855 .next = NEXT(next_qia_qu_attr, 3856 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 3857 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 3858 .call = parse_qia 3859 }, 3860 /* Indirect action update arguments. */ 3861 [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { 3862 .name = "postpone", 3863 .help = "postpone update operation", 3864 .next = NEXT(next_qia_update_attr, 3865 NEXT_ENTRY(COMMON_BOOLEAN)), 3866 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3867 }, 3868 /* Indirect action update arguments. */ 3869 [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { 3870 .name = "postpone", 3871 .help = "postpone query operation", 3872 .next = NEXT(next_qia_query_attr, 3873 NEXT_ENTRY(COMMON_BOOLEAN)), 3874 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3875 }, 3876 /* Indirect action create arguments. */ 3877 [QUEUE_INDIRECT_ACTION_CREATE_ID] = { 3878 .name = "action_id", 3879 .help = "specify a indirect action id to create", 3880 .next = NEXT(next_qia_create_attr, 3881 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3882 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3883 }, 3884 [QUEUE_INDIRECT_ACTION_INGRESS] = { 3885 .name = "ingress", 3886 .help = "affect rule to ingress", 3887 .next = NEXT(next_qia_create_attr), 3888 .call = parse_qia, 3889 }, 3890 [QUEUE_INDIRECT_ACTION_EGRESS] = { 3891 .name = "egress", 3892 .help = "affect rule to egress", 3893 .next = NEXT(next_qia_create_attr), 3894 .call = parse_qia, 3895 }, 3896 [QUEUE_INDIRECT_ACTION_TRANSFER] = { 3897 .name = "transfer", 3898 .help = "affect rule to transfer", 3899 .next = NEXT(next_qia_create_attr), 3900 .call = parse_qia, 3901 }, 3902 [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { 3903 .name = "postpone", 3904 .help = "postpone create operation", 3905 .next = NEXT(next_qia_create_attr, 3906 NEXT_ENTRY(COMMON_BOOLEAN)), 3907 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3908 }, 3909 [QUEUE_INDIRECT_ACTION_SPEC] = { 3910 .name = "action", 3911 .help = "specify action to create indirect handle", 3912 .next = NEXT(next_action), 3913 }, 3914 [QUEUE_INDIRECT_ACTION_LIST] = { 3915 .name = "list", 3916 .help = "specify actions for indirect handle list", 3917 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 3918 .call = parse_qia, 3919 }, 3920 /* Top-level command. */ 3921 [PUSH] = { 3922 .name = "push", 3923 .help = "push enqueued operations", 3924 .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3925 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3926 .call = parse_push, 3927 }, 3928 /* Sub-level commands. */ 3929 [PUSH_QUEUE] = { 3930 .name = "queue", 3931 .help = "specify queue id", 3932 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3933 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3934 }, 3935 /* Top-level command. */ 3936 [PULL] = { 3937 .name = "pull", 3938 .help = "pull flow operations results", 3939 .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3940 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3941 .call = parse_pull, 3942 }, 3943 /* Sub-level commands. */ 3944 [PULL_QUEUE] = { 3945 .name = "queue", 3946 .help = "specify queue id", 3947 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3948 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3949 }, 3950 /* Top-level command. */ 3951 [HASH] = { 3952 .name = "hash", 3953 .help = "calculate hash for a given pattern in a given template table", 3954 .next = NEXT(next_hash_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3955 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3956 .call = parse_hash, 3957 }, 3958 /* Sub-level commands. */ 3959 [HASH_CALC_TABLE] = { 3960 .name = "template_table", 3961 .help = "specify table id", 3962 .next = NEXT(NEXT_ENTRY(HASH_CALC_PATTERN_INDEX), 3963 NEXT_ENTRY(COMMON_TABLE_ID)), 3964 .args = ARGS(ARGS_ENTRY(struct buffer, 3965 args.vc.table_id)), 3966 .call = parse_hash, 3967 }, 3968 [HASH_CALC_ENCAP] = { 3969 .name = "encap", 3970 .help = "calculates encap hash", 3971 .next = NEXT(next_hash_encap_dest_subcmd), 3972 .call = parse_hash, 3973 }, 3974 [HASH_CALC_PATTERN_INDEX] = { 3975 .name = "pattern_template", 3976 .help = "specify pattern template id", 3977 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3978 NEXT_ENTRY(COMMON_UNSIGNED)), 3979 .args = ARGS(ARGS_ENTRY(struct buffer, 3980 args.vc.pat_templ_id)), 3981 .call = parse_hash, 3982 }, 3983 [ENCAP_HASH_FIELD_SRC_PORT] = { 3984 .name = "hash_field_sport", 3985 .help = "the encap hash field is src port", 3986 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 3987 .call = parse_hash, 3988 }, 3989 [ENCAP_HASH_FIELD_GRE_FLOW_ID] = { 3990 .name = "hash_field_flow_id", 3991 .help = "the encap hash field is NVGRE flow id", 3992 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 3993 .call = parse_hash, 3994 }, 3995 /* Top-level command. */ 3996 [INDIRECT_ACTION] = { 3997 .name = "indirect_action", 3998 .type = "{command} {port_id} [{arg} [...]]", 3999 .help = "manage indirect actions", 4000 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4001 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4002 .call = parse_ia, 4003 }, 4004 /* Sub-level commands. */ 4005 [INDIRECT_ACTION_CREATE] = { 4006 .name = "create", 4007 .help = "create indirect action", 4008 .next = NEXT(next_ia_create_attr), 4009 .call = parse_ia, 4010 }, 4011 [INDIRECT_ACTION_UPDATE] = { 4012 .name = "update", 4013 .help = "update indirect action", 4014 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), 4015 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4016 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 4017 .call = parse_ia, 4018 }, 4019 [INDIRECT_ACTION_DESTROY] = { 4020 .name = "destroy", 4021 .help = "destroy indirect action", 4022 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), 4023 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4024 .call = parse_ia_destroy, 4025 }, 4026 [INDIRECT_ACTION_QUERY] = { 4027 .name = "query", 4028 .help = "query indirect action", 4029 .next = NEXT(NEXT_ENTRY(END), 4030 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4031 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4032 .call = parse_ia, 4033 }, 4034 [INDIRECT_ACTION_QUERY_UPDATE] = { 4035 .name = "query_update", 4036 .help = "query [and|or] update", 4037 .next = NEXT(next_ia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4038 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4039 .call = parse_ia 4040 }, 4041 [INDIRECT_ACTION_QU_MODE] = { 4042 .name = "mode", 4043 .help = "query_update mode", 4044 .next = NEXT(next_ia_qu_attr, 4045 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 4046 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 4047 .call = parse_ia, 4048 }, 4049 [INDIRECT_ACTION_QU_MODE_NAME] = { 4050 .name = "mode_name", 4051 .help = "query-update mode name", 4052 .call = parse_qu_mode_name, 4053 .comp = comp_qu_mode_name, 4054 }, 4055 [VALIDATE] = { 4056 .name = "validate", 4057 .help = "check whether a flow rule can be created", 4058 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4059 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4060 .call = parse_vc, 4061 }, 4062 [CREATE] = { 4063 .name = "create", 4064 .help = "create a flow rule", 4065 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4066 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4067 .call = parse_vc, 4068 }, 4069 [DESTROY] = { 4070 .name = "destroy", 4071 .help = "destroy specific flow rules", 4072 .next = NEXT(next_destroy_attr, 4073 NEXT_ENTRY(COMMON_PORT_ID)), 4074 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4075 .call = parse_destroy, 4076 }, 4077 [FLUSH] = { 4078 .name = "flush", 4079 .help = "destroy all flow rules", 4080 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4081 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4082 .call = parse_flush, 4083 }, 4084 [DUMP] = { 4085 .name = "dump", 4086 .help = "dump single/all flow rules to file", 4087 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4088 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4089 .call = parse_dump, 4090 }, 4091 [QUERY] = { 4092 .name = "query", 4093 .help = "query an existing flow rule", 4094 .next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION), 4095 NEXT_ENTRY(COMMON_RULE_ID), 4096 NEXT_ENTRY(COMMON_PORT_ID)), 4097 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), 4098 ARGS_ENTRY(struct buffer, args.query.rule), 4099 ARGS_ENTRY(struct buffer, port)), 4100 .call = parse_query, 4101 }, 4102 [LIST] = { 4103 .name = "list", 4104 .help = "list existing flow rules", 4105 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4106 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4107 .call = parse_list, 4108 }, 4109 [AGED] = { 4110 .name = "aged", 4111 .help = "list and destroy aged flows", 4112 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4113 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4114 .call = parse_aged, 4115 }, 4116 [ISOLATE] = { 4117 .name = "isolate", 4118 .help = "restrict ingress traffic to the defined flow rules", 4119 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), 4120 NEXT_ENTRY(COMMON_PORT_ID)), 4121 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), 4122 ARGS_ENTRY(struct buffer, port)), 4123 .call = parse_isolate, 4124 }, 4125 [FLEX] = { 4126 .name = "flex_item", 4127 .help = "flex item API", 4128 .next = NEXT(next_flex_item), 4129 .call = parse_flex, 4130 }, 4131 [FLEX_ITEM_INIT] = { 4132 .name = "init", 4133 .help = "flex item init", 4134 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4135 ARGS_ENTRY(struct buffer, port)), 4136 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4137 NEXT_ENTRY(COMMON_PORT_ID)), 4138 .call = parse_flex 4139 }, 4140 [FLEX_ITEM_CREATE] = { 4141 .name = "create", 4142 .help = "flex item create", 4143 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), 4144 ARGS_ENTRY(struct buffer, args.flex.token), 4145 ARGS_ENTRY(struct buffer, port)), 4146 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), 4147 NEXT_ENTRY(COMMON_FLEX_TOKEN), 4148 NEXT_ENTRY(COMMON_PORT_ID)), 4149 .call = parse_flex 4150 }, 4151 [FLEX_ITEM_DESTROY] = { 4152 .name = "destroy", 4153 .help = "flex item destroy", 4154 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4155 ARGS_ENTRY(struct buffer, port)), 4156 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4157 NEXT_ENTRY(COMMON_PORT_ID)), 4158 .call = parse_flex 4159 }, 4160 [TUNNEL] = { 4161 .name = "tunnel", 4162 .help = "new tunnel API", 4163 .next = NEXT(NEXT_ENTRY 4164 (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), 4165 .call = parse_tunnel, 4166 }, 4167 /* Tunnel arguments. */ 4168 [TUNNEL_CREATE] = { 4169 .name = "create", 4170 .help = "create new tunnel object", 4171 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), 4172 NEXT_ENTRY(COMMON_PORT_ID)), 4173 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4174 .call = parse_tunnel, 4175 }, 4176 [TUNNEL_CREATE_TYPE] = { 4177 .name = "type", 4178 .help = "create new tunnel", 4179 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), 4180 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), 4181 .call = parse_tunnel, 4182 }, 4183 [TUNNEL_DESTROY] = { 4184 .name = "destroy", 4185 .help = "destroy tunnel", 4186 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), 4187 NEXT_ENTRY(COMMON_PORT_ID)), 4188 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4189 .call = parse_tunnel, 4190 }, 4191 [TUNNEL_DESTROY_ID] = { 4192 .name = "id", 4193 .help = "tunnel identifier to destroy", 4194 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), 4195 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4196 .call = parse_tunnel, 4197 }, 4198 [TUNNEL_LIST] = { 4199 .name = "list", 4200 .help = "list existing tunnels", 4201 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4202 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4203 .call = parse_tunnel, 4204 }, 4205 /* Destroy arguments. */ 4206 [DESTROY_RULE] = { 4207 .name = "rule", 4208 .help = "specify a rule identifier", 4209 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4210 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), 4211 .call = parse_destroy, 4212 }, 4213 [DESTROY_IS_USER_ID] = { 4214 .name = "user_id", 4215 .help = "rule identifier is user-id", 4216 .next = NEXT(next_destroy_attr), 4217 .call = parse_destroy, 4218 }, 4219 /* Dump arguments. */ 4220 [DUMP_ALL] = { 4221 .name = "all", 4222 .help = "dump all", 4223 .next = NEXT(next_dump_attr), 4224 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), 4225 .call = parse_dump, 4226 }, 4227 [DUMP_ONE] = { 4228 .name = "rule", 4229 .help = "dump one rule", 4230 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4231 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), 4232 ARGS_ENTRY(struct buffer, args.dump.rule)), 4233 .call = parse_dump, 4234 }, 4235 [DUMP_IS_USER_ID] = { 4236 .name = "user_id", 4237 .help = "rule identifier is user-id", 4238 .next = NEXT(next_dump_subcmd), 4239 .call = parse_dump, 4240 }, 4241 /* Query arguments. */ 4242 [QUERY_ACTION] = { 4243 .name = "{action}", 4244 .type = "ACTION", 4245 .help = "action to query, must be part of the rule", 4246 .call = parse_action, 4247 .comp = comp_action, 4248 }, 4249 [QUERY_IS_USER_ID] = { 4250 .name = "user_id", 4251 .help = "rule identifier is user-id", 4252 .next = NEXT(next_query_attr), 4253 .call = parse_query, 4254 }, 4255 /* List arguments. */ 4256 [LIST_GROUP] = { 4257 .name = "group", 4258 .help = "specify a group", 4259 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4260 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), 4261 .call = parse_list, 4262 }, 4263 [AGED_DESTROY] = { 4264 .name = "destroy", 4265 .help = "specify aged flows need be destroyed", 4266 .call = parse_aged, 4267 .comp = comp_none, 4268 }, 4269 /* Validate/create attributes. */ 4270 [VC_GROUP] = { 4271 .name = "group", 4272 .help = "specify a group", 4273 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4274 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), 4275 .call = parse_vc, 4276 }, 4277 [VC_PRIORITY] = { 4278 .name = "priority", 4279 .help = "specify a priority level", 4280 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 4281 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), 4282 .call = parse_vc, 4283 }, 4284 [VC_INGRESS] = { 4285 .name = "ingress", 4286 .help = "affect rule to ingress", 4287 .next = NEXT(next_vc_attr), 4288 .call = parse_vc, 4289 }, 4290 [VC_EGRESS] = { 4291 .name = "egress", 4292 .help = "affect rule to egress", 4293 .next = NEXT(next_vc_attr), 4294 .call = parse_vc, 4295 }, 4296 [VC_TRANSFER] = { 4297 .name = "transfer", 4298 .help = "apply rule directly to endpoints found in pattern", 4299 .next = NEXT(next_vc_attr), 4300 .call = parse_vc, 4301 }, 4302 [VC_TUNNEL_SET] = { 4303 .name = "tunnel_set", 4304 .help = "tunnel steer rule", 4305 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4306 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4307 .call = parse_vc, 4308 }, 4309 [VC_TUNNEL_MATCH] = { 4310 .name = "tunnel_match", 4311 .help = "tunnel match rule", 4312 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4313 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4314 .call = parse_vc, 4315 }, 4316 [VC_USER_ID] = { 4317 .name = "user_id", 4318 .help = "specify a user id to create", 4319 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4320 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)), 4321 .call = parse_vc, 4322 }, 4323 /* Validate/create pattern. */ 4324 [ITEM_PATTERN] = { 4325 .name = "pattern", 4326 .help = "submit a list of pattern items", 4327 .next = NEXT(next_item), 4328 .call = parse_vc, 4329 }, 4330 [ITEM_PARAM_IS] = { 4331 .name = "is", 4332 .help = "match value perfectly (with full bit-mask)", 4333 .call = parse_vc_spec, 4334 }, 4335 [ITEM_PARAM_SPEC] = { 4336 .name = "spec", 4337 .help = "match value according to configured bit-mask", 4338 .call = parse_vc_spec, 4339 }, 4340 [ITEM_PARAM_LAST] = { 4341 .name = "last", 4342 .help = "specify upper bound to establish a range", 4343 .call = parse_vc_spec, 4344 }, 4345 [ITEM_PARAM_MASK] = { 4346 .name = "mask", 4347 .help = "specify bit-mask with relevant bits set to one", 4348 .call = parse_vc_spec, 4349 }, 4350 [ITEM_PARAM_PREFIX] = { 4351 .name = "prefix", 4352 .help = "generate bit-mask from a prefix length", 4353 .call = parse_vc_spec, 4354 }, 4355 [ITEM_NEXT] = { 4356 .name = "/", 4357 .help = "specify next pattern item", 4358 .next = NEXT(next_item), 4359 }, 4360 [ITEM_END] = { 4361 .name = "end", 4362 .help = "end list of pattern items", 4363 .priv = PRIV_ITEM(END, 0), 4364 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 4365 .call = parse_vc, 4366 }, 4367 [ITEM_VOID] = { 4368 .name = "void", 4369 .help = "no-op pattern item", 4370 .priv = PRIV_ITEM(VOID, 0), 4371 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4372 .call = parse_vc, 4373 }, 4374 [ITEM_INVERT] = { 4375 .name = "invert", 4376 .help = "perform actions when pattern does not match", 4377 .priv = PRIV_ITEM(INVERT, 0), 4378 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4379 .call = parse_vc, 4380 }, 4381 [ITEM_ANY] = { 4382 .name = "any", 4383 .help = "match any protocol for the current layer", 4384 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), 4385 .next = NEXT(item_any), 4386 .call = parse_vc, 4387 }, 4388 [ITEM_ANY_NUM] = { 4389 .name = "num", 4390 .help = "number of layers covered", 4391 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4392 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), 4393 }, 4394 [ITEM_PORT_ID] = { 4395 .name = "port_id", 4396 .help = "match traffic from/to a given DPDK port ID", 4397 .priv = PRIV_ITEM(PORT_ID, 4398 sizeof(struct rte_flow_item_port_id)), 4399 .next = NEXT(item_port_id), 4400 .call = parse_vc, 4401 }, 4402 [ITEM_PORT_ID_ID] = { 4403 .name = "id", 4404 .help = "DPDK port ID", 4405 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), 4406 item_param), 4407 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), 4408 }, 4409 [ITEM_MARK] = { 4410 .name = "mark", 4411 .help = "match traffic against value set in previously matched rule", 4412 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), 4413 .next = NEXT(item_mark), 4414 .call = parse_vc, 4415 }, 4416 [ITEM_MARK_ID] = { 4417 .name = "id", 4418 .help = "Integer value to match against", 4419 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), 4420 item_param), 4421 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), 4422 }, 4423 [ITEM_RAW] = { 4424 .name = "raw", 4425 .help = "match an arbitrary byte string", 4426 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), 4427 .next = NEXT(item_raw), 4428 .call = parse_vc, 4429 }, 4430 [ITEM_RAW_RELATIVE] = { 4431 .name = "relative", 4432 .help = "look for pattern after the previous item", 4433 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4434 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4435 relative, 1)), 4436 }, 4437 [ITEM_RAW_SEARCH] = { 4438 .name = "search", 4439 .help = "search pattern from offset (see also limit)", 4440 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4441 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4442 search, 1)), 4443 }, 4444 [ITEM_RAW_OFFSET] = { 4445 .name = "offset", 4446 .help = "absolute or relative offset for pattern", 4447 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), 4448 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), 4449 }, 4450 [ITEM_RAW_LIMIT] = { 4451 .name = "limit", 4452 .help = "search area limit for start of pattern", 4453 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4454 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), 4455 }, 4456 [ITEM_RAW_PATTERN] = { 4457 .name = "pattern", 4458 .help = "byte string to look for", 4459 .next = NEXT(item_raw, 4460 NEXT_ENTRY(COMMON_STRING), 4461 NEXT_ENTRY(ITEM_PARAM_IS, 4462 ITEM_PARAM_SPEC, 4463 ITEM_PARAM_MASK)), 4464 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4465 ARGS_ENTRY(struct rte_flow_item_raw, length), 4466 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4467 ITEM_RAW_PATTERN_SIZE)), 4468 }, 4469 [ITEM_RAW_PATTERN_HEX] = { 4470 .name = "pattern_hex", 4471 .help = "hex string to look for", 4472 .next = NEXT(item_raw, 4473 NEXT_ENTRY(COMMON_HEX), 4474 NEXT_ENTRY(ITEM_PARAM_IS, 4475 ITEM_PARAM_SPEC, 4476 ITEM_PARAM_MASK)), 4477 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4478 ARGS_ENTRY(struct rte_flow_item_raw, length), 4479 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4480 ITEM_RAW_PATTERN_SIZE)), 4481 }, 4482 [ITEM_ETH] = { 4483 .name = "eth", 4484 .help = "match Ethernet header", 4485 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), 4486 .next = NEXT(item_eth), 4487 .call = parse_vc, 4488 }, 4489 [ITEM_ETH_DST] = { 4490 .name = "dst", 4491 .help = "destination MAC", 4492 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4493 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), 4494 }, 4495 [ITEM_ETH_SRC] = { 4496 .name = "src", 4497 .help = "source MAC", 4498 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4499 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), 4500 }, 4501 [ITEM_ETH_TYPE] = { 4502 .name = "type", 4503 .help = "EtherType", 4504 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4505 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), 4506 }, 4507 [ITEM_ETH_HAS_VLAN] = { 4508 .name = "has_vlan", 4509 .help = "packet header contains VLAN", 4510 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4511 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, 4512 has_vlan, 1)), 4513 }, 4514 [ITEM_VLAN] = { 4515 .name = "vlan", 4516 .help = "match 802.1Q/ad VLAN tag", 4517 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), 4518 .next = NEXT(item_vlan), 4519 .call = parse_vc, 4520 }, 4521 [ITEM_VLAN_TCI] = { 4522 .name = "tci", 4523 .help = "tag control information", 4524 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4525 item_param), 4526 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, hdr.vlan_tci)), 4527 }, 4528 [ITEM_VLAN_PCP] = { 4529 .name = "pcp", 4530 .help = "priority code point", 4531 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4532 item_param), 4533 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4534 hdr.vlan_tci, "\xe0\x00")), 4535 }, 4536 [ITEM_VLAN_DEI] = { 4537 .name = "dei", 4538 .help = "drop eligible indicator", 4539 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4540 item_param), 4541 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4542 hdr.vlan_tci, "\x10\x00")), 4543 }, 4544 [ITEM_VLAN_VID] = { 4545 .name = "vid", 4546 .help = "VLAN identifier", 4547 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4548 item_param), 4549 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4550 hdr.vlan_tci, "\x0f\xff")), 4551 }, 4552 [ITEM_VLAN_INNER_TYPE] = { 4553 .name = "inner_type", 4554 .help = "inner EtherType", 4555 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4556 item_param), 4557 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, 4558 hdr.eth_proto)), 4559 }, 4560 [ITEM_VLAN_HAS_MORE_VLAN] = { 4561 .name = "has_more_vlan", 4562 .help = "packet header contains another VLAN", 4563 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4564 item_param), 4565 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, 4566 has_more_vlan, 1)), 4567 }, 4568 [ITEM_IPV4] = { 4569 .name = "ipv4", 4570 .help = "match IPv4 header", 4571 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), 4572 .next = NEXT(item_ipv4), 4573 .call = parse_vc, 4574 }, 4575 [ITEM_IPV4_VER_IHL] = { 4576 .name = "version_ihl", 4577 .help = "match header length", 4578 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4579 item_param), 4580 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, 4581 hdr.version_ihl)), 4582 }, 4583 [ITEM_IPV4_TOS] = { 4584 .name = "tos", 4585 .help = "type of service", 4586 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4587 item_param), 4588 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4589 hdr.type_of_service)), 4590 }, 4591 [ITEM_IPV4_LENGTH] = { 4592 .name = "length", 4593 .help = "total length", 4594 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4595 item_param), 4596 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4597 hdr.total_length)), 4598 }, 4599 [ITEM_IPV4_ID] = { 4600 .name = "packet_id", 4601 .help = "fragment packet id", 4602 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4603 item_param), 4604 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4605 hdr.packet_id)), 4606 }, 4607 [ITEM_IPV4_FRAGMENT_OFFSET] = { 4608 .name = "fragment_offset", 4609 .help = "fragmentation flags and fragment offset", 4610 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4611 item_param), 4612 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4613 hdr.fragment_offset)), 4614 }, 4615 [ITEM_IPV4_TTL] = { 4616 .name = "ttl", 4617 .help = "time to live", 4618 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4619 item_param), 4620 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4621 hdr.time_to_live)), 4622 }, 4623 [ITEM_IPV4_PROTO] = { 4624 .name = "proto", 4625 .help = "next protocol ID", 4626 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4627 item_param), 4628 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4629 hdr.next_proto_id)), 4630 }, 4631 [ITEM_IPV4_SRC] = { 4632 .name = "src", 4633 .help = "source address", 4634 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4635 item_param), 4636 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4637 hdr.src_addr)), 4638 }, 4639 [ITEM_IPV4_DST] = { 4640 .name = "dst", 4641 .help = "destination address", 4642 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4643 item_param), 4644 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4645 hdr.dst_addr)), 4646 }, 4647 [ITEM_IPV6] = { 4648 .name = "ipv6", 4649 .help = "match IPv6 header", 4650 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), 4651 .next = NEXT(item_ipv6), 4652 .call = parse_vc, 4653 }, 4654 [ITEM_IPV6_TC] = { 4655 .name = "tc", 4656 .help = "traffic class", 4657 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4658 item_param), 4659 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4660 hdr.vtc_flow, 4661 "\x0f\xf0\x00\x00")), 4662 }, 4663 [ITEM_IPV6_FLOW] = { 4664 .name = "flow", 4665 .help = "flow label", 4666 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4667 item_param), 4668 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4669 hdr.vtc_flow, 4670 "\x00\x0f\xff\xff")), 4671 }, 4672 [ITEM_IPV6_LEN] = { 4673 .name = "length", 4674 .help = "payload length", 4675 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4676 item_param), 4677 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4678 hdr.payload_len)), 4679 }, 4680 [ITEM_IPV6_PROTO] = { 4681 .name = "proto", 4682 .help = "protocol (next header)", 4683 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4684 item_param), 4685 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4686 hdr.proto)), 4687 }, 4688 [ITEM_IPV6_HOP] = { 4689 .name = "hop", 4690 .help = "hop limit", 4691 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4692 item_param), 4693 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4694 hdr.hop_limits)), 4695 }, 4696 [ITEM_IPV6_SRC] = { 4697 .name = "src", 4698 .help = "source address", 4699 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4700 item_param), 4701 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4702 hdr.src_addr)), 4703 }, 4704 [ITEM_IPV6_DST] = { 4705 .name = "dst", 4706 .help = "destination address", 4707 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4708 item_param), 4709 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4710 hdr.dst_addr)), 4711 }, 4712 [ITEM_IPV6_HAS_FRAG_EXT] = { 4713 .name = "has_frag_ext", 4714 .help = "fragment packet attribute", 4715 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4716 item_param), 4717 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, 4718 has_frag_ext, 1)), 4719 }, 4720 [ITEM_IPV6_ROUTING_EXT] = { 4721 .name = "ipv6_routing_ext", 4722 .help = "match IPv6 routing extension header", 4723 .priv = PRIV_ITEM(IPV6_ROUTING_EXT, 4724 sizeof(struct rte_flow_item_ipv6_routing_ext)), 4725 .next = NEXT(item_ipv6_routing_ext), 4726 .call = parse_vc, 4727 }, 4728 [ITEM_IPV6_ROUTING_EXT_TYPE] = { 4729 .name = "ext_type", 4730 .help = "match IPv6 routing extension header type", 4731 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4732 item_param), 4733 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4734 hdr.type)), 4735 }, 4736 [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = { 4737 .name = "ext_next_hdr", 4738 .help = "match IPv6 routing extension header next header type", 4739 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4740 item_param), 4741 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4742 hdr.next_hdr)), 4743 }, 4744 [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = { 4745 .name = "ext_seg_left", 4746 .help = "match IPv6 routing extension header segment left", 4747 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4748 item_param), 4749 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4750 hdr.segments_left)), 4751 }, 4752 [ITEM_ICMP] = { 4753 .name = "icmp", 4754 .help = "match ICMP header", 4755 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), 4756 .next = NEXT(item_icmp), 4757 .call = parse_vc, 4758 }, 4759 [ITEM_ICMP_TYPE] = { 4760 .name = "type", 4761 .help = "ICMP packet type", 4762 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4763 item_param), 4764 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4765 hdr.icmp_type)), 4766 }, 4767 [ITEM_ICMP_CODE] = { 4768 .name = "code", 4769 .help = "ICMP packet code", 4770 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4771 item_param), 4772 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4773 hdr.icmp_code)), 4774 }, 4775 [ITEM_ICMP_IDENT] = { 4776 .name = "ident", 4777 .help = "ICMP packet identifier", 4778 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4779 item_param), 4780 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4781 hdr.icmp_ident)), 4782 }, 4783 [ITEM_ICMP_SEQ] = { 4784 .name = "seq", 4785 .help = "ICMP packet sequence number", 4786 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4787 item_param), 4788 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4789 hdr.icmp_seq_nb)), 4790 }, 4791 [ITEM_UDP] = { 4792 .name = "udp", 4793 .help = "match UDP header", 4794 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), 4795 .next = NEXT(item_udp), 4796 .call = parse_vc, 4797 }, 4798 [ITEM_UDP_SRC] = { 4799 .name = "src", 4800 .help = "UDP source port", 4801 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), 4802 item_param), 4803 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4804 hdr.src_port)), 4805 }, 4806 [ITEM_UDP_DST] = { 4807 .name = "dst", 4808 .help = "UDP destination port", 4809 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4810 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4811 hdr.dst_port)), 4812 }, 4813 [ITEM_TCP] = { 4814 .name = "tcp", 4815 .help = "match TCP header", 4816 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), 4817 .next = NEXT(item_tcp), 4818 .call = parse_vc, 4819 }, 4820 [ITEM_TCP_SRC] = { 4821 .name = "src", 4822 .help = "TCP source port", 4823 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4824 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4825 hdr.src_port)), 4826 }, 4827 [ITEM_TCP_DST] = { 4828 .name = "dst", 4829 .help = "TCP destination port", 4830 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4831 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4832 hdr.dst_port)), 4833 }, 4834 [ITEM_TCP_FLAGS] = { 4835 .name = "flags", 4836 .help = "TCP flags", 4837 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4838 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4839 hdr.tcp_flags)), 4840 }, 4841 [ITEM_SCTP] = { 4842 .name = "sctp", 4843 .help = "match SCTP header", 4844 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), 4845 .next = NEXT(item_sctp), 4846 .call = parse_vc, 4847 }, 4848 [ITEM_SCTP_SRC] = { 4849 .name = "src", 4850 .help = "SCTP source port", 4851 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4852 item_param), 4853 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4854 hdr.src_port)), 4855 }, 4856 [ITEM_SCTP_DST] = { 4857 .name = "dst", 4858 .help = "SCTP destination port", 4859 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4860 item_param), 4861 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4862 hdr.dst_port)), 4863 }, 4864 [ITEM_SCTP_TAG] = { 4865 .name = "tag", 4866 .help = "validation tag", 4867 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4868 item_param), 4869 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4870 hdr.tag)), 4871 }, 4872 [ITEM_SCTP_CKSUM] = { 4873 .name = "cksum", 4874 .help = "checksum", 4875 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4876 item_param), 4877 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4878 hdr.cksum)), 4879 }, 4880 [ITEM_VXLAN] = { 4881 .name = "vxlan", 4882 .help = "match VXLAN header", 4883 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), 4884 .next = NEXT(item_vxlan), 4885 .call = parse_vc, 4886 }, 4887 [ITEM_VXLAN_VNI] = { 4888 .name = "vni", 4889 .help = "VXLAN identifier", 4890 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4891 item_param), 4892 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), 4893 }, 4894 [ITEM_VXLAN_LAST_RSVD] = { 4895 .name = "last_rsvd", 4896 .help = "VXLAN last reserved bits", 4897 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4898 item_param), 4899 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 4900 hdr.rsvd1)), 4901 }, 4902 [ITEM_E_TAG] = { 4903 .name = "e_tag", 4904 .help = "match E-Tag header", 4905 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), 4906 .next = NEXT(item_e_tag), 4907 .call = parse_vc, 4908 }, 4909 [ITEM_E_TAG_GRP_ECID_B] = { 4910 .name = "grp_ecid_b", 4911 .help = "GRP and E-CID base", 4912 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), 4913 item_param), 4914 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, 4915 rsvd_grp_ecid_b, 4916 "\x3f\xff")), 4917 }, 4918 [ITEM_NVGRE] = { 4919 .name = "nvgre", 4920 .help = "match NVGRE header", 4921 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), 4922 .next = NEXT(item_nvgre), 4923 .call = parse_vc, 4924 }, 4925 [ITEM_NVGRE_TNI] = { 4926 .name = "tni", 4927 .help = "virtual subnet ID", 4928 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), 4929 item_param), 4930 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), 4931 }, 4932 [ITEM_MPLS] = { 4933 .name = "mpls", 4934 .help = "match MPLS header", 4935 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), 4936 .next = NEXT(item_mpls), 4937 .call = parse_vc, 4938 }, 4939 [ITEM_MPLS_LABEL] = { 4940 .name = "label", 4941 .help = "MPLS label", 4942 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4943 item_param), 4944 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4945 label_tc_s, 4946 "\xff\xff\xf0")), 4947 }, 4948 [ITEM_MPLS_TC] = { 4949 .name = "tc", 4950 .help = "MPLS Traffic Class", 4951 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4952 item_param), 4953 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4954 label_tc_s, 4955 "\x00\x00\x0e")), 4956 }, 4957 [ITEM_MPLS_S] = { 4958 .name = "s", 4959 .help = "MPLS Bottom-of-Stack", 4960 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4961 item_param), 4962 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4963 label_tc_s, 4964 "\x00\x00\x01")), 4965 }, 4966 [ITEM_MPLS_TTL] = { 4967 .name = "ttl", 4968 .help = "MPLS Time-to-Live", 4969 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4970 item_param), 4971 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls, ttl)), 4972 }, 4973 [ITEM_GRE] = { 4974 .name = "gre", 4975 .help = "match GRE header", 4976 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), 4977 .next = NEXT(item_gre), 4978 .call = parse_vc, 4979 }, 4980 [ITEM_GRE_PROTO] = { 4981 .name = "protocol", 4982 .help = "GRE protocol type", 4983 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 4984 item_param), 4985 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 4986 protocol)), 4987 }, 4988 [ITEM_GRE_C_RSVD0_VER] = { 4989 .name = "c_rsvd0_ver", 4990 .help = 4991 "checksum (1b), undefined (1b), key bit (1b)," 4992 " sequence number (1b), reserved 0 (9b)," 4993 " version (3b)", 4994 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 4995 item_param), 4996 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 4997 c_rsvd0_ver)), 4998 }, 4999 [ITEM_GRE_C_BIT] = { 5000 .name = "c_bit", 5001 .help = "checksum bit (C)", 5002 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), 5003 item_param), 5004 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5005 c_rsvd0_ver, 5006 "\x80\x00\x00\x00")), 5007 }, 5008 [ITEM_GRE_S_BIT] = { 5009 .name = "s_bit", 5010 .help = "sequence number bit (S)", 5011 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5012 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5013 c_rsvd0_ver, 5014 "\x10\x00\x00\x00")), 5015 }, 5016 [ITEM_GRE_K_BIT] = { 5017 .name = "k_bit", 5018 .help = "key bit (K)", 5019 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5020 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5021 c_rsvd0_ver, 5022 "\x20\x00\x00\x00")), 5023 }, 5024 [ITEM_FUZZY] = { 5025 .name = "fuzzy", 5026 .help = "fuzzy pattern match, expect faster than default", 5027 .priv = PRIV_ITEM(FUZZY, 5028 sizeof(struct rte_flow_item_fuzzy)), 5029 .next = NEXT(item_fuzzy), 5030 .call = parse_vc, 5031 }, 5032 [ITEM_FUZZY_THRESH] = { 5033 .name = "thresh", 5034 .help = "match accuracy threshold", 5035 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), 5036 item_param), 5037 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, 5038 thresh)), 5039 }, 5040 [ITEM_GTP] = { 5041 .name = "gtp", 5042 .help = "match GTP header", 5043 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), 5044 .next = NEXT(item_gtp), 5045 .call = parse_vc, 5046 }, 5047 [ITEM_GTP_FLAGS] = { 5048 .name = "v_pt_rsv_flags", 5049 .help = "GTP flags", 5050 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5051 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, 5052 hdr.gtp_hdr_info)), 5053 }, 5054 [ITEM_GTP_MSG_TYPE] = { 5055 .name = "msg_type", 5056 .help = "GTP message type", 5057 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5058 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), 5059 }, 5060 [ITEM_GTP_TEID] = { 5061 .name = "teid", 5062 .help = "tunnel endpoint identifier", 5063 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5064 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), 5065 }, 5066 [ITEM_GTPC] = { 5067 .name = "gtpc", 5068 .help = "match GTP header", 5069 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), 5070 .next = NEXT(item_gtp), 5071 .call = parse_vc, 5072 }, 5073 [ITEM_GTPU] = { 5074 .name = "gtpu", 5075 .help = "match GTP header", 5076 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), 5077 .next = NEXT(item_gtp), 5078 .call = parse_vc, 5079 }, 5080 [ITEM_GENEVE] = { 5081 .name = "geneve", 5082 .help = "match GENEVE header", 5083 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), 5084 .next = NEXT(item_geneve), 5085 .call = parse_vc, 5086 }, 5087 [ITEM_GENEVE_VNI] = { 5088 .name = "vni", 5089 .help = "virtual network identifier", 5090 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5091 item_param), 5092 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), 5093 }, 5094 [ITEM_GENEVE_PROTO] = { 5095 .name = "protocol", 5096 .help = "GENEVE protocol type", 5097 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5098 item_param), 5099 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, 5100 protocol)), 5101 }, 5102 [ITEM_GENEVE_OPTLEN] = { 5103 .name = "optlen", 5104 .help = "GENEVE options length in dwords", 5105 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5106 item_param), 5107 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, 5108 ver_opt_len_o_c_rsvd0, 5109 "\x3f\x00")), 5110 }, 5111 [ITEM_VXLAN_GPE] = { 5112 .name = "vxlan-gpe", 5113 .help = "match VXLAN-GPE header", 5114 .priv = PRIV_ITEM(VXLAN_GPE, 5115 sizeof(struct rte_flow_item_vxlan_gpe)), 5116 .next = NEXT(item_vxlan_gpe), 5117 .call = parse_vc, 5118 }, 5119 [ITEM_VXLAN_GPE_VNI] = { 5120 .name = "vni", 5121 .help = "VXLAN-GPE identifier", 5122 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5123 item_param), 5124 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5125 hdr.vni)), 5126 }, 5127 [ITEM_VXLAN_GPE_PROTO] = { 5128 .name = "protocol", 5129 .help = "VXLAN-GPE next protocol", 5130 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5131 item_param), 5132 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5133 protocol)), 5134 }, 5135 [ITEM_VXLAN_GPE_FLAGS] = { 5136 .name = "flags", 5137 .help = "VXLAN-GPE flags", 5138 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5139 item_param), 5140 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5141 flags)), 5142 }, 5143 [ITEM_VXLAN_GPE_RSVD0] = { 5144 .name = "rsvd0", 5145 .help = "VXLAN-GPE rsvd0", 5146 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5147 item_param), 5148 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5149 rsvd0)), 5150 }, 5151 [ITEM_VXLAN_GPE_RSVD1] = { 5152 .name = "rsvd1", 5153 .help = "VXLAN-GPE rsvd1", 5154 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5155 item_param), 5156 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5157 rsvd1)), 5158 }, 5159 [ITEM_ARP_ETH_IPV4] = { 5160 .name = "arp_eth_ipv4", 5161 .help = "match ARP header for Ethernet/IPv4", 5162 .priv = PRIV_ITEM(ARP_ETH_IPV4, 5163 sizeof(struct rte_flow_item_arp_eth_ipv4)), 5164 .next = NEXT(item_arp_eth_ipv4), 5165 .call = parse_vc, 5166 }, 5167 [ITEM_ARP_ETH_IPV4_SHA] = { 5168 .name = "sha", 5169 .help = "sender hardware address", 5170 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5171 item_param), 5172 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5173 hdr.arp_data.arp_sha)), 5174 }, 5175 [ITEM_ARP_ETH_IPV4_SPA] = { 5176 .name = "spa", 5177 .help = "sender IPv4 address", 5178 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5179 item_param), 5180 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5181 hdr.arp_data.arp_sip)), 5182 }, 5183 [ITEM_ARP_ETH_IPV4_THA] = { 5184 .name = "tha", 5185 .help = "target hardware address", 5186 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5187 item_param), 5188 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5189 hdr.arp_data.arp_tha)), 5190 }, 5191 [ITEM_ARP_ETH_IPV4_TPA] = { 5192 .name = "tpa", 5193 .help = "target IPv4 address", 5194 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5195 item_param), 5196 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5197 hdr.arp_data.arp_tip)), 5198 }, 5199 [ITEM_IPV6_EXT] = { 5200 .name = "ipv6_ext", 5201 .help = "match presence of any IPv6 extension header", 5202 .priv = PRIV_ITEM(IPV6_EXT, 5203 sizeof(struct rte_flow_item_ipv6_ext)), 5204 .next = NEXT(item_ipv6_ext), 5205 .call = parse_vc, 5206 }, 5207 [ITEM_IPV6_EXT_NEXT_HDR] = { 5208 .name = "next_hdr", 5209 .help = "next header", 5210 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5211 item_param), 5212 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 5213 next_hdr)), 5214 }, 5215 [ITEM_IPV6_FRAG_EXT] = { 5216 .name = "ipv6_frag_ext", 5217 .help = "match presence of IPv6 fragment extension header", 5218 .priv = PRIV_ITEM(IPV6_FRAG_EXT, 5219 sizeof(struct rte_flow_item_ipv6_frag_ext)), 5220 .next = NEXT(item_ipv6_frag_ext), 5221 .call = parse_vc, 5222 }, 5223 [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { 5224 .name = "next_hdr", 5225 .help = "next header", 5226 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5227 item_param), 5228 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, 5229 hdr.next_header)), 5230 }, 5231 [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { 5232 .name = "frag_data", 5233 .help = "fragment flags and offset", 5234 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5235 item_param), 5236 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5237 hdr.frag_data)), 5238 }, 5239 [ITEM_IPV6_FRAG_EXT_ID] = { 5240 .name = "packet_id", 5241 .help = "fragment packet id", 5242 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5243 item_param), 5244 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5245 hdr.id)), 5246 }, 5247 [ITEM_ICMP6] = { 5248 .name = "icmp6", 5249 .help = "match any ICMPv6 header", 5250 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), 5251 .next = NEXT(item_icmp6), 5252 .call = parse_vc, 5253 }, 5254 [ITEM_ICMP6_TYPE] = { 5255 .name = "type", 5256 .help = "ICMPv6 type", 5257 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5258 item_param), 5259 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5260 type)), 5261 }, 5262 [ITEM_ICMP6_CODE] = { 5263 .name = "code", 5264 .help = "ICMPv6 code", 5265 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5266 item_param), 5267 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5268 code)), 5269 }, 5270 [ITEM_ICMP6_ECHO_REQUEST] = { 5271 .name = "icmp6_echo_request", 5272 .help = "match ICMPv6 echo request", 5273 .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, 5274 sizeof(struct rte_flow_item_icmp6_echo)), 5275 .next = NEXT(item_icmp6_echo_request), 5276 .call = parse_vc, 5277 }, 5278 [ITEM_ICMP6_ECHO_REQUEST_ID] = { 5279 .name = "ident", 5280 .help = "ICMPv6 echo request identifier", 5281 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5282 item_param), 5283 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5284 hdr.identifier)), 5285 }, 5286 [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { 5287 .name = "seq", 5288 .help = "ICMPv6 echo request sequence", 5289 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5290 item_param), 5291 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5292 hdr.sequence)), 5293 }, 5294 [ITEM_ICMP6_ECHO_REPLY] = { 5295 .name = "icmp6_echo_reply", 5296 .help = "match ICMPv6 echo reply", 5297 .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, 5298 sizeof(struct rte_flow_item_icmp6_echo)), 5299 .next = NEXT(item_icmp6_echo_reply), 5300 .call = parse_vc, 5301 }, 5302 [ITEM_ICMP6_ECHO_REPLY_ID] = { 5303 .name = "ident", 5304 .help = "ICMPv6 echo reply identifier", 5305 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5306 item_param), 5307 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5308 hdr.identifier)), 5309 }, 5310 [ITEM_ICMP6_ECHO_REPLY_SEQ] = { 5311 .name = "seq", 5312 .help = "ICMPv6 echo reply sequence", 5313 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5314 item_param), 5315 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5316 hdr.sequence)), 5317 }, 5318 [ITEM_ICMP6_ND_NS] = { 5319 .name = "icmp6_nd_ns", 5320 .help = "match ICMPv6 neighbor discovery solicitation", 5321 .priv = PRIV_ITEM(ICMP6_ND_NS, 5322 sizeof(struct rte_flow_item_icmp6_nd_ns)), 5323 .next = NEXT(item_icmp6_nd_ns), 5324 .call = parse_vc, 5325 }, 5326 [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { 5327 .name = "target_addr", 5328 .help = "target address", 5329 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), 5330 item_param), 5331 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, 5332 target_addr)), 5333 }, 5334 [ITEM_ICMP6_ND_NA] = { 5335 .name = "icmp6_nd_na", 5336 .help = "match ICMPv6 neighbor discovery advertisement", 5337 .priv = PRIV_ITEM(ICMP6_ND_NA, 5338 sizeof(struct rte_flow_item_icmp6_nd_na)), 5339 .next = NEXT(item_icmp6_nd_na), 5340 .call = parse_vc, 5341 }, 5342 [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { 5343 .name = "target_addr", 5344 .help = "target address", 5345 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), 5346 item_param), 5347 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, 5348 target_addr)), 5349 }, 5350 [ITEM_ICMP6_ND_OPT] = { 5351 .name = "icmp6_nd_opt", 5352 .help = "match presence of any ICMPv6 neighbor discovery" 5353 " option", 5354 .priv = PRIV_ITEM(ICMP6_ND_OPT, 5355 sizeof(struct rte_flow_item_icmp6_nd_opt)), 5356 .next = NEXT(item_icmp6_nd_opt), 5357 .call = parse_vc, 5358 }, 5359 [ITEM_ICMP6_ND_OPT_TYPE] = { 5360 .name = "type", 5361 .help = "ND option type", 5362 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5363 item_param), 5364 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, 5365 type)), 5366 }, 5367 [ITEM_ICMP6_ND_OPT_SLA_ETH] = { 5368 .name = "icmp6_nd_opt_sla_eth", 5369 .help = "match ICMPv6 neighbor discovery source Ethernet" 5370 " link-layer address option", 5371 .priv = PRIV_ITEM 5372 (ICMP6_ND_OPT_SLA_ETH, 5373 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), 5374 .next = NEXT(item_icmp6_nd_opt_sla_eth), 5375 .call = parse_vc, 5376 }, 5377 [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { 5378 .name = "sla", 5379 .help = "source Ethernet LLA", 5380 .next = NEXT(item_icmp6_nd_opt_sla_eth, 5381 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5382 .args = ARGS(ARGS_ENTRY_HTON 5383 (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), 5384 }, 5385 [ITEM_ICMP6_ND_OPT_TLA_ETH] = { 5386 .name = "icmp6_nd_opt_tla_eth", 5387 .help = "match ICMPv6 neighbor discovery target Ethernet" 5388 " link-layer address option", 5389 .priv = PRIV_ITEM 5390 (ICMP6_ND_OPT_TLA_ETH, 5391 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), 5392 .next = NEXT(item_icmp6_nd_opt_tla_eth), 5393 .call = parse_vc, 5394 }, 5395 [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { 5396 .name = "tla", 5397 .help = "target Ethernet LLA", 5398 .next = NEXT(item_icmp6_nd_opt_tla_eth, 5399 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5400 .args = ARGS(ARGS_ENTRY_HTON 5401 (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), 5402 }, 5403 [ITEM_META] = { 5404 .name = "meta", 5405 .help = "match metadata header", 5406 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), 5407 .next = NEXT(item_meta), 5408 .call = parse_vc, 5409 }, 5410 [ITEM_META_DATA] = { 5411 .name = "data", 5412 .help = "metadata value", 5413 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), 5414 item_param), 5415 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, 5416 data, "\xff\xff\xff\xff")), 5417 }, 5418 [ITEM_RANDOM] = { 5419 .name = "random", 5420 .help = "match random value", 5421 .priv = PRIV_ITEM(RANDOM, sizeof(struct rte_flow_item_random)), 5422 .next = NEXT(item_random), 5423 .call = parse_vc, 5424 }, 5425 [ITEM_RANDOM_VALUE] = { 5426 .name = "value", 5427 .help = "random value", 5428 .next = NEXT(item_random, NEXT_ENTRY(COMMON_UNSIGNED), 5429 item_param), 5430 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_random, 5431 value, "\xff\xff")), 5432 }, 5433 [ITEM_GRE_KEY] = { 5434 .name = "gre_key", 5435 .help = "match GRE key", 5436 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), 5437 .next = NEXT(item_gre_key), 5438 .call = parse_vc, 5439 }, 5440 [ITEM_GRE_KEY_VALUE] = { 5441 .name = "value", 5442 .help = "key value", 5443 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), 5444 item_param), 5445 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5446 }, 5447 [ITEM_GRE_OPTION] = { 5448 .name = "gre_option", 5449 .help = "match GRE optional fields", 5450 .priv = PRIV_ITEM(GRE_OPTION, 5451 sizeof(struct rte_flow_item_gre_opt)), 5452 .next = NEXT(item_gre_option), 5453 .call = parse_vc, 5454 }, 5455 [ITEM_GRE_OPTION_CHECKSUM] = { 5456 .name = "checksum", 5457 .help = "match GRE checksum", 5458 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5459 item_param), 5460 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5461 checksum_rsvd.checksum)), 5462 }, 5463 [ITEM_GRE_OPTION_KEY] = { 5464 .name = "key", 5465 .help = "match GRE key", 5466 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5467 item_param), 5468 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5469 key.key)), 5470 }, 5471 [ITEM_GRE_OPTION_SEQUENCE] = { 5472 .name = "sequence", 5473 .help = "match GRE sequence", 5474 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5475 item_param), 5476 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5477 sequence.sequence)), 5478 }, 5479 [ITEM_GTP_PSC] = { 5480 .name = "gtp_psc", 5481 .help = "match GTP extension header with type 0x85", 5482 .priv = PRIV_ITEM(GTP_PSC, 5483 sizeof(struct rte_flow_item_gtp_psc)), 5484 .next = NEXT(item_gtp_psc), 5485 .call = parse_vc, 5486 }, 5487 [ITEM_GTP_PSC_QFI] = { 5488 .name = "qfi", 5489 .help = "QoS flow identifier", 5490 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5491 item_param), 5492 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5493 hdr.qfi, 6)), 5494 }, 5495 [ITEM_GTP_PSC_PDU_T] = { 5496 .name = "pdu_t", 5497 .help = "PDU type", 5498 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5499 item_param), 5500 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5501 hdr.type, 4)), 5502 }, 5503 [ITEM_PPPOES] = { 5504 .name = "pppoes", 5505 .help = "match PPPoE session header", 5506 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), 5507 .next = NEXT(item_pppoes), 5508 .call = parse_vc, 5509 }, 5510 [ITEM_PPPOED] = { 5511 .name = "pppoed", 5512 .help = "match PPPoE discovery header", 5513 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), 5514 .next = NEXT(item_pppoed), 5515 .call = parse_vc, 5516 }, 5517 [ITEM_PPPOE_SEID] = { 5518 .name = "seid", 5519 .help = "session identifier", 5520 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), 5521 item_param), 5522 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, 5523 session_id)), 5524 }, 5525 [ITEM_PPPOE_PROTO_ID] = { 5526 .name = "pppoe_proto_id", 5527 .help = "match PPPoE session protocol identifier", 5528 .priv = PRIV_ITEM(PPPOE_PROTO_ID, 5529 sizeof(struct rte_flow_item_pppoe_proto_id)), 5530 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED), 5531 item_param), 5532 .args = ARGS(ARGS_ENTRY_HTON 5533 (struct rte_flow_item_pppoe_proto_id, proto_id)), 5534 .call = parse_vc, 5535 }, 5536 [ITEM_HIGIG2] = { 5537 .name = "higig2", 5538 .help = "matches higig2 header", 5539 .priv = PRIV_ITEM(HIGIG2, 5540 sizeof(struct rte_flow_item_higig2_hdr)), 5541 .next = NEXT(item_higig2), 5542 .call = parse_vc, 5543 }, 5544 [ITEM_HIGIG2_CLASSIFICATION] = { 5545 .name = "classification", 5546 .help = "matches classification of higig2 header", 5547 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5548 item_param), 5549 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5550 hdr.ppt1.classification)), 5551 }, 5552 [ITEM_HIGIG2_VID] = { 5553 .name = "vid", 5554 .help = "matches vid of higig2 header", 5555 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5556 item_param), 5557 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5558 hdr.ppt1.vid)), 5559 }, 5560 [ITEM_TAG] = { 5561 .name = "tag", 5562 .help = "match tag value", 5563 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), 5564 .next = NEXT(item_tag), 5565 .call = parse_vc, 5566 }, 5567 [ITEM_TAG_DATA] = { 5568 .name = "data", 5569 .help = "tag value to match", 5570 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5571 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), 5572 }, 5573 [ITEM_TAG_INDEX] = { 5574 .name = "index", 5575 .help = "index of tag array to match", 5576 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5577 NEXT_ENTRY(ITEM_PARAM_IS)), 5578 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), 5579 }, 5580 [ITEM_L2TPV3OIP] = { 5581 .name = "l2tpv3oip", 5582 .help = "match L2TPv3 over IP header", 5583 .priv = PRIV_ITEM(L2TPV3OIP, 5584 sizeof(struct rte_flow_item_l2tpv3oip)), 5585 .next = NEXT(item_l2tpv3oip), 5586 .call = parse_vc, 5587 }, 5588 [ITEM_L2TPV3OIP_SESSION_ID] = { 5589 .name = "session_id", 5590 .help = "session identifier", 5591 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), 5592 item_param), 5593 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, 5594 session_id)), 5595 }, 5596 [ITEM_ESP] = { 5597 .name = "esp", 5598 .help = "match ESP header", 5599 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), 5600 .next = NEXT(item_esp), 5601 .call = parse_vc, 5602 }, 5603 [ITEM_ESP_SPI] = { 5604 .name = "spi", 5605 .help = "security policy index", 5606 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5607 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, 5608 hdr.spi)), 5609 }, 5610 [ITEM_AH] = { 5611 .name = "ah", 5612 .help = "match AH header", 5613 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), 5614 .next = NEXT(item_ah), 5615 .call = parse_vc, 5616 }, 5617 [ITEM_AH_SPI] = { 5618 .name = "spi", 5619 .help = "security parameters index", 5620 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5621 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), 5622 }, 5623 [ITEM_PFCP] = { 5624 .name = "pfcp", 5625 .help = "match pfcp header", 5626 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), 5627 .next = NEXT(item_pfcp), 5628 .call = parse_vc, 5629 }, 5630 [ITEM_PFCP_S_FIELD] = { 5631 .name = "s_field", 5632 .help = "S field", 5633 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5634 item_param), 5635 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, 5636 s_field)), 5637 }, 5638 [ITEM_PFCP_SEID] = { 5639 .name = "seid", 5640 .help = "session endpoint identifier", 5641 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5642 item_param), 5643 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), 5644 }, 5645 [ITEM_ECPRI] = { 5646 .name = "ecpri", 5647 .help = "match eCPRI header", 5648 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), 5649 .next = NEXT(item_ecpri), 5650 .call = parse_vc, 5651 }, 5652 [ITEM_ECPRI_COMMON] = { 5653 .name = "common", 5654 .help = "eCPRI common header", 5655 .next = NEXT(item_ecpri_common), 5656 }, 5657 [ITEM_ECPRI_COMMON_TYPE] = { 5658 .name = "type", 5659 .help = "type of common header", 5660 .next = NEXT(item_ecpri_common_type), 5661 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), 5662 }, 5663 [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { 5664 .name = "iq_data", 5665 .help = "Type #0: IQ Data", 5666 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5667 ITEM_NEXT)), 5668 .call = parse_vc_item_ecpri_type, 5669 }, 5670 [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { 5671 .name = "pc_id", 5672 .help = "Physical Channel ID", 5673 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5674 ITEM_ECPRI_COMMON, ITEM_NEXT), 5675 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5676 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5677 hdr.type0.pc_id)), 5678 }, 5679 [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { 5680 .name = "rtc_ctrl", 5681 .help = "Type #2: Real-Time Control Data", 5682 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5683 ITEM_NEXT)), 5684 .call = parse_vc_item_ecpri_type, 5685 }, 5686 [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { 5687 .name = "rtc_id", 5688 .help = "Real-Time Control Data ID", 5689 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5690 ITEM_ECPRI_COMMON, ITEM_NEXT), 5691 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5692 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5693 hdr.type2.rtc_id)), 5694 }, 5695 [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { 5696 .name = "delay_measure", 5697 .help = "Type #5: One-Way Delay Measurement", 5698 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5699 ITEM_NEXT)), 5700 .call = parse_vc_item_ecpri_type, 5701 }, 5702 [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { 5703 .name = "msr_id", 5704 .help = "Measurement ID", 5705 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5706 ITEM_ECPRI_COMMON, ITEM_NEXT), 5707 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5708 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5709 hdr.type5.msr_id)), 5710 }, 5711 [ITEM_GENEVE_OPT] = { 5712 .name = "geneve-opt", 5713 .help = "GENEVE header option", 5714 .priv = PRIV_ITEM(GENEVE_OPT, 5715 sizeof(struct rte_flow_item_geneve_opt) + 5716 ITEM_GENEVE_OPT_DATA_SIZE), 5717 .next = NEXT(item_geneve_opt), 5718 .call = parse_vc, 5719 }, 5720 [ITEM_GENEVE_OPT_CLASS] = { 5721 .name = "class", 5722 .help = "GENEVE option class", 5723 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5724 item_param), 5725 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, 5726 option_class)), 5727 }, 5728 [ITEM_GENEVE_OPT_TYPE] = { 5729 .name = "type", 5730 .help = "GENEVE option type", 5731 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5732 item_param), 5733 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, 5734 option_type)), 5735 }, 5736 [ITEM_GENEVE_OPT_LENGTH] = { 5737 .name = "length", 5738 .help = "GENEVE option data length (in 32b words)", 5739 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5740 item_param), 5741 .args = ARGS(ARGS_ENTRY_BOUNDED( 5742 struct rte_flow_item_geneve_opt, option_len, 5743 0, 31)), 5744 }, 5745 [ITEM_GENEVE_OPT_DATA] = { 5746 .name = "data", 5747 .help = "GENEVE option data pattern", 5748 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), 5749 item_param), 5750 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), 5751 ARGS_ENTRY_ARB(0, 0), 5752 ARGS_ENTRY_ARB 5753 (sizeof(struct rte_flow_item_geneve_opt), 5754 ITEM_GENEVE_OPT_DATA_SIZE)), 5755 }, 5756 [ITEM_INTEGRITY] = { 5757 .name = "integrity", 5758 .help = "match packet integrity", 5759 .priv = PRIV_ITEM(INTEGRITY, 5760 sizeof(struct rte_flow_item_integrity)), 5761 .next = NEXT(item_integrity), 5762 .call = parse_vc, 5763 }, 5764 [ITEM_INTEGRITY_LEVEL] = { 5765 .name = "level", 5766 .help = "integrity level", 5767 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5768 item_param), 5769 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), 5770 }, 5771 [ITEM_INTEGRITY_VALUE] = { 5772 .name = "value", 5773 .help = "integrity value", 5774 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5775 item_param), 5776 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), 5777 }, 5778 [ITEM_CONNTRACK] = { 5779 .name = "conntrack", 5780 .help = "conntrack state", 5781 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 5782 item_param), 5783 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 5784 }, 5785 [ITEM_PORT_REPRESENTOR] = { 5786 .name = "port_representor", 5787 .help = "match traffic entering the embedded switch from the given ethdev", 5788 .priv = PRIV_ITEM(PORT_REPRESENTOR, 5789 sizeof(struct rte_flow_item_ethdev)), 5790 .next = NEXT(item_port_representor), 5791 .call = parse_vc, 5792 }, 5793 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 5794 .name = "port_id", 5795 .help = "ethdev port ID", 5796 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 5797 item_param), 5798 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5799 }, 5800 [ITEM_REPRESENTED_PORT] = { 5801 .name = "represented_port", 5802 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 5803 .priv = PRIV_ITEM(REPRESENTED_PORT, 5804 sizeof(struct rte_flow_item_ethdev)), 5805 .next = NEXT(item_represented_port), 5806 .call = parse_vc, 5807 }, 5808 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 5809 .name = "ethdev_port_id", 5810 .help = "ethdev port ID", 5811 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 5812 item_param), 5813 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5814 }, 5815 [ITEM_FLEX] = { 5816 .name = "flex", 5817 .help = "match flex header", 5818 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 5819 .next = NEXT(item_flex), 5820 .call = parse_vc, 5821 }, 5822 [ITEM_FLEX_ITEM_HANDLE] = { 5823 .name = "item", 5824 .help = "flex item handle", 5825 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5826 NEXT_ENTRY(ITEM_PARAM_IS)), 5827 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 5828 }, 5829 [ITEM_FLEX_PATTERN_HANDLE] = { 5830 .name = "pattern", 5831 .help = "flex pattern handle", 5832 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5833 NEXT_ENTRY(ITEM_PARAM_IS)), 5834 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 5835 }, 5836 [ITEM_L2TPV2] = { 5837 .name = "l2tpv2", 5838 .help = "match L2TPv2 header", 5839 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 5840 .next = NEXT(item_l2tpv2), 5841 .call = parse_vc, 5842 }, 5843 [ITEM_L2TPV2_TYPE] = { 5844 .name = "type", 5845 .help = "type of l2tpv2", 5846 .next = NEXT(item_l2tpv2_type), 5847 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 5848 }, 5849 [ITEM_L2TPV2_TYPE_DATA] = { 5850 .name = "data", 5851 .help = "Type #7: data message without any options", 5852 .next = NEXT(item_l2tpv2_type_data), 5853 .call = parse_vc_item_l2tpv2_type, 5854 }, 5855 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 5856 .name = "tunnel_id", 5857 .help = "tunnel identifier", 5858 .next = NEXT(item_l2tpv2_type_data, 5859 NEXT_ENTRY(COMMON_UNSIGNED), 5860 item_param), 5861 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5862 hdr.type7.tunnel_id)), 5863 }, 5864 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 5865 .name = "session_id", 5866 .help = "session identifier", 5867 .next = NEXT(item_l2tpv2_type_data, 5868 NEXT_ENTRY(COMMON_UNSIGNED), 5869 item_param), 5870 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5871 hdr.type7.session_id)), 5872 }, 5873 [ITEM_L2TPV2_TYPE_DATA_L] = { 5874 .name = "data_l", 5875 .help = "Type #6: data message with length option", 5876 .next = NEXT(item_l2tpv2_type_data_l), 5877 .call = parse_vc_item_l2tpv2_type, 5878 }, 5879 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 5880 .name = "length", 5881 .help = "message length", 5882 .next = NEXT(item_l2tpv2_type_data_l, 5883 NEXT_ENTRY(COMMON_UNSIGNED), 5884 item_param), 5885 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5886 hdr.type6.length)), 5887 }, 5888 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 5889 .name = "tunnel_id", 5890 .help = "tunnel identifier", 5891 .next = NEXT(item_l2tpv2_type_data_l, 5892 NEXT_ENTRY(COMMON_UNSIGNED), 5893 item_param), 5894 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5895 hdr.type6.tunnel_id)), 5896 }, 5897 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 5898 .name = "session_id", 5899 .help = "session identifier", 5900 .next = NEXT(item_l2tpv2_type_data_l, 5901 NEXT_ENTRY(COMMON_UNSIGNED), 5902 item_param), 5903 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5904 hdr.type6.session_id)), 5905 }, 5906 [ITEM_L2TPV2_TYPE_DATA_S] = { 5907 .name = "data_s", 5908 .help = "Type #5: data message with ns, nr option", 5909 .next = NEXT(item_l2tpv2_type_data_s), 5910 .call = parse_vc_item_l2tpv2_type, 5911 }, 5912 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 5913 .name = "tunnel_id", 5914 .help = "tunnel identifier", 5915 .next = NEXT(item_l2tpv2_type_data_s, 5916 NEXT_ENTRY(COMMON_UNSIGNED), 5917 item_param), 5918 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5919 hdr.type5.tunnel_id)), 5920 }, 5921 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 5922 .name = "session_id", 5923 .help = "session identifier", 5924 .next = NEXT(item_l2tpv2_type_data_s, 5925 NEXT_ENTRY(COMMON_UNSIGNED), 5926 item_param), 5927 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5928 hdr.type5.session_id)), 5929 }, 5930 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 5931 .name = "ns", 5932 .help = "sequence number for message", 5933 .next = NEXT(item_l2tpv2_type_data_s, 5934 NEXT_ENTRY(COMMON_UNSIGNED), 5935 item_param), 5936 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5937 hdr.type5.ns)), 5938 }, 5939 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 5940 .name = "nr", 5941 .help = "sequence number for next receive message", 5942 .next = NEXT(item_l2tpv2_type_data_s, 5943 NEXT_ENTRY(COMMON_UNSIGNED), 5944 item_param), 5945 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5946 hdr.type5.nr)), 5947 }, 5948 [ITEM_L2TPV2_TYPE_DATA_O] = { 5949 .name = "data_o", 5950 .help = "Type #4: data message with offset option", 5951 .next = NEXT(item_l2tpv2_type_data_o), 5952 .call = parse_vc_item_l2tpv2_type, 5953 }, 5954 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 5955 .name = "tunnel_id", 5956 .help = "tunnel identifier", 5957 .next = NEXT(item_l2tpv2_type_data_o, 5958 NEXT_ENTRY(COMMON_UNSIGNED), 5959 item_param), 5960 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5961 hdr.type4.tunnel_id)), 5962 }, 5963 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 5964 .name = "session_id", 5965 .help = "session identifier", 5966 .next = NEXT(item_l2tpv2_type_data_o, 5967 NEXT_ENTRY(COMMON_UNSIGNED), 5968 item_param), 5969 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5970 hdr.type5.session_id)), 5971 }, 5972 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 5973 .name = "offset_size", 5974 .help = "the size of offset padding", 5975 .next = NEXT(item_l2tpv2_type_data_o, 5976 NEXT_ENTRY(COMMON_UNSIGNED), 5977 item_param), 5978 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5979 hdr.type4.offset_size)), 5980 }, 5981 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 5982 .name = "data_l_s", 5983 .help = "Type #3: data message contains length, ns, nr " 5984 "options", 5985 .next = NEXT(item_l2tpv2_type_data_l_s), 5986 .call = parse_vc_item_l2tpv2_type, 5987 }, 5988 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 5989 .name = "length", 5990 .help = "message length", 5991 .next = NEXT(item_l2tpv2_type_data_l_s, 5992 NEXT_ENTRY(COMMON_UNSIGNED), 5993 item_param), 5994 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5995 hdr.type3.length)), 5996 }, 5997 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 5998 .name = "tunnel_id", 5999 .help = "tunnel identifier", 6000 .next = NEXT(item_l2tpv2_type_data_l_s, 6001 NEXT_ENTRY(COMMON_UNSIGNED), 6002 item_param), 6003 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6004 hdr.type3.tunnel_id)), 6005 }, 6006 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 6007 .name = "session_id", 6008 .help = "session identifier", 6009 .next = NEXT(item_l2tpv2_type_data_l_s, 6010 NEXT_ENTRY(COMMON_UNSIGNED), 6011 item_param), 6012 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6013 hdr.type3.session_id)), 6014 }, 6015 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 6016 .name = "ns", 6017 .help = "sequence number for message", 6018 .next = NEXT(item_l2tpv2_type_data_l_s, 6019 NEXT_ENTRY(COMMON_UNSIGNED), 6020 item_param), 6021 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6022 hdr.type3.ns)), 6023 }, 6024 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 6025 .name = "nr", 6026 .help = "sequence number for next receive message", 6027 .next = NEXT(item_l2tpv2_type_data_l_s, 6028 NEXT_ENTRY(COMMON_UNSIGNED), 6029 item_param), 6030 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6031 hdr.type3.nr)), 6032 }, 6033 [ITEM_L2TPV2_TYPE_CTRL] = { 6034 .name = "control", 6035 .help = "Type #3: conrtol message contains length, ns, nr " 6036 "options", 6037 .next = NEXT(item_l2tpv2_type_ctrl), 6038 .call = parse_vc_item_l2tpv2_type, 6039 }, 6040 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 6041 .name = "length", 6042 .help = "message length", 6043 .next = NEXT(item_l2tpv2_type_ctrl, 6044 NEXT_ENTRY(COMMON_UNSIGNED), 6045 item_param), 6046 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6047 hdr.type3.length)), 6048 }, 6049 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 6050 .name = "tunnel_id", 6051 .help = "tunnel identifier", 6052 .next = NEXT(item_l2tpv2_type_ctrl, 6053 NEXT_ENTRY(COMMON_UNSIGNED), 6054 item_param), 6055 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6056 hdr.type3.tunnel_id)), 6057 }, 6058 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 6059 .name = "session_id", 6060 .help = "session identifier", 6061 .next = NEXT(item_l2tpv2_type_ctrl, 6062 NEXT_ENTRY(COMMON_UNSIGNED), 6063 item_param), 6064 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6065 hdr.type3.session_id)), 6066 }, 6067 [ITEM_L2TPV2_MSG_CTRL_NS] = { 6068 .name = "ns", 6069 .help = "sequence number for message", 6070 .next = NEXT(item_l2tpv2_type_ctrl, 6071 NEXT_ENTRY(COMMON_UNSIGNED), 6072 item_param), 6073 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6074 hdr.type3.ns)), 6075 }, 6076 [ITEM_L2TPV2_MSG_CTRL_NR] = { 6077 .name = "nr", 6078 .help = "sequence number for next receive message", 6079 .next = NEXT(item_l2tpv2_type_ctrl, 6080 NEXT_ENTRY(COMMON_UNSIGNED), 6081 item_param), 6082 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6083 hdr.type3.nr)), 6084 }, 6085 [ITEM_PPP] = { 6086 .name = "ppp", 6087 .help = "match PPP header", 6088 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 6089 .next = NEXT(item_ppp), 6090 .call = parse_vc, 6091 }, 6092 [ITEM_PPP_ADDR] = { 6093 .name = "addr", 6094 .help = "PPP address", 6095 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6096 item_param), 6097 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 6098 }, 6099 [ITEM_PPP_CTRL] = { 6100 .name = "ctrl", 6101 .help = "PPP control", 6102 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6103 item_param), 6104 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 6105 }, 6106 [ITEM_PPP_PROTO_ID] = { 6107 .name = "proto_id", 6108 .help = "PPP protocol identifier", 6109 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6110 item_param), 6111 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 6112 hdr.proto_id)), 6113 }, 6114 [ITEM_METER] = { 6115 .name = "meter", 6116 .help = "match meter color", 6117 .priv = PRIV_ITEM(METER_COLOR, 6118 sizeof(struct rte_flow_item_meter_color)), 6119 .next = NEXT(item_meter), 6120 .call = parse_vc, 6121 }, 6122 [ITEM_METER_COLOR] = { 6123 .name = "color", 6124 .help = "meter color", 6125 .next = NEXT(item_meter, 6126 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 6127 item_param), 6128 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 6129 color)), 6130 }, 6131 [ITEM_METER_COLOR_NAME] = { 6132 .name = "color_name", 6133 .help = "meter color name", 6134 .call = parse_meter_color, 6135 .comp = comp_meter_color, 6136 }, 6137 [ITEM_QUOTA] = { 6138 .name = "quota", 6139 .help = "match quota", 6140 .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), 6141 .next = NEXT(item_quota), 6142 .call = parse_vc 6143 }, 6144 [ITEM_QUOTA_STATE] = { 6145 .name = "quota_state", 6146 .help = "quota state", 6147 .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), 6148 NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), 6149 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) 6150 }, 6151 [ITEM_QUOTA_STATE_NAME] = { 6152 .name = "state_name", 6153 .help = "quota state name", 6154 .call = parse_quota_state_name, 6155 .comp = comp_quota_state_name 6156 }, 6157 [ITEM_IB_BTH] = { 6158 .name = "ib_bth", 6159 .help = "match ib bth fields", 6160 .priv = PRIV_ITEM(IB_BTH, 6161 sizeof(struct rte_flow_item_ib_bth)), 6162 .next = NEXT(item_ib_bth), 6163 .call = parse_vc, 6164 }, 6165 [ITEM_IB_BTH_OPCODE] = { 6166 .name = "opcode", 6167 .help = "match ib bth opcode", 6168 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6169 item_param), 6170 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6171 hdr.opcode)), 6172 }, 6173 [ITEM_IB_BTH_PKEY] = { 6174 .name = "pkey", 6175 .help = "partition key", 6176 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6177 item_param), 6178 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6179 hdr.pkey)), 6180 }, 6181 [ITEM_IB_BTH_DST_QPN] = { 6182 .name = "dst_qp", 6183 .help = "destination qp", 6184 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6185 item_param), 6186 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6187 hdr.dst_qp)), 6188 }, 6189 [ITEM_IB_BTH_PSN] = { 6190 .name = "psn", 6191 .help = "packet sequence number", 6192 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6193 item_param), 6194 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6195 hdr.psn)), 6196 }, 6197 [ITEM_PTYPE] = { 6198 .name = "ptype", 6199 .help = "match L2/L3/L4 and tunnel information", 6200 .priv = PRIV_ITEM(PTYPE, 6201 sizeof(struct rte_flow_item_ptype)), 6202 .next = NEXT(item_ptype), 6203 .call = parse_vc, 6204 }, 6205 [ITEM_PTYPE_VALUE] = { 6206 .name = "packet_type", 6207 .help = "packet type as defined in rte_mbuf_ptype", 6208 .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), 6209 item_param), 6210 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), 6211 }, 6212 [ITEM_NSH] = { 6213 .name = "nsh", 6214 .help = "match NSH header", 6215 .priv = PRIV_ITEM(NSH, 6216 sizeof(struct rte_flow_item_nsh)), 6217 .next = NEXT(item_nsh), 6218 .call = parse_vc, 6219 }, 6220 [ITEM_COMPARE] = { 6221 .name = "compare", 6222 .help = "match with the comparison result", 6223 .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)), 6224 .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)), 6225 .call = parse_vc, 6226 }, 6227 [ITEM_COMPARE_OP] = { 6228 .name = "op", 6229 .help = "operation type", 6230 .next = NEXT(item_compare_field, 6231 NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param), 6232 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)), 6233 }, 6234 [ITEM_COMPARE_OP_VALUE] = { 6235 .name = "{operation}", 6236 .help = "operation type value", 6237 .call = parse_vc_compare_op, 6238 .comp = comp_set_compare_op, 6239 }, 6240 [ITEM_COMPARE_FIELD_A_TYPE] = { 6241 .name = "a_type", 6242 .help = "compared field type", 6243 .next = NEXT(compare_field_a, 6244 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param), 6245 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)), 6246 }, 6247 [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = { 6248 .name = "{a_type}", 6249 .help = "compared field type value", 6250 .call = parse_vc_compare_field_id, 6251 .comp = comp_set_compare_field_id, 6252 }, 6253 [ITEM_COMPARE_FIELD_A_LEVEL] = { 6254 .name = "a_level", 6255 .help = "compared field level", 6256 .next = NEXT(compare_field_a, 6257 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param), 6258 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)), 6259 }, 6260 [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = { 6261 .name = "{a_level}", 6262 .help = "compared field level value", 6263 .call = parse_vc_compare_field_level, 6264 .comp = comp_none, 6265 }, 6266 [ITEM_COMPARE_FIELD_A_TAG_INDEX] = { 6267 .name = "a_tag_index", 6268 .help = "compared field tag array", 6269 .next = NEXT(compare_field_a, 6270 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6271 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6272 a.tag_index)), 6273 }, 6274 [ITEM_COMPARE_FIELD_A_TYPE_ID] = { 6275 .name = "a_type_id", 6276 .help = "compared field type ID", 6277 .next = NEXT(compare_field_a, 6278 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6279 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6280 a.type)), 6281 }, 6282 [ITEM_COMPARE_FIELD_A_CLASS_ID] = { 6283 .name = "a_class", 6284 .help = "compared field class ID", 6285 .next = NEXT(compare_field_a, 6286 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6287 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6288 a.class_id)), 6289 }, 6290 [ITEM_COMPARE_FIELD_A_OFFSET] = { 6291 .name = "a_offset", 6292 .help = "compared field bit offset", 6293 .next = NEXT(compare_field_a, 6294 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6295 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6296 a.offset)), 6297 }, 6298 [ITEM_COMPARE_FIELD_B_TYPE] = { 6299 .name = "b_type", 6300 .help = "comparator field type", 6301 .next = NEXT(compare_field_b, 6302 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param), 6303 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6304 b.field)), 6305 }, 6306 [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = { 6307 .name = "{b_type}", 6308 .help = "comparator field type value", 6309 .call = parse_vc_compare_field_id, 6310 .comp = comp_set_compare_field_id, 6311 }, 6312 [ITEM_COMPARE_FIELD_B_LEVEL] = { 6313 .name = "b_level", 6314 .help = "comparator field level", 6315 .next = NEXT(compare_field_b, 6316 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param), 6317 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6318 b.level)), 6319 }, 6320 [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = { 6321 .name = "{b_level}", 6322 .help = "comparator field level value", 6323 .call = parse_vc_compare_field_level, 6324 .comp = comp_none, 6325 }, 6326 [ITEM_COMPARE_FIELD_B_TAG_INDEX] = { 6327 .name = "b_tag_index", 6328 .help = "comparator field tag array", 6329 .next = NEXT(compare_field_b, 6330 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6331 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6332 b.tag_index)), 6333 }, 6334 [ITEM_COMPARE_FIELD_B_TYPE_ID] = { 6335 .name = "b_type_id", 6336 .help = "comparator field type ID", 6337 .next = NEXT(compare_field_b, 6338 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6339 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6340 b.type)), 6341 }, 6342 [ITEM_COMPARE_FIELD_B_CLASS_ID] = { 6343 .name = "b_class", 6344 .help = "comparator field class ID", 6345 .next = NEXT(compare_field_b, 6346 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6347 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6348 b.class_id)), 6349 }, 6350 [ITEM_COMPARE_FIELD_B_OFFSET] = { 6351 .name = "b_offset", 6352 .help = "comparator field bit offset", 6353 .next = NEXT(compare_field_b, 6354 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6355 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6356 b.offset)), 6357 }, 6358 [ITEM_COMPARE_FIELD_B_VALUE] = { 6359 .name = "b_value", 6360 .help = "comparator immediate value", 6361 .next = NEXT(compare_field_b, 6362 NEXT_ENTRY(COMMON_HEX), item_param), 6363 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6364 ARGS_ENTRY_ARB(0, 0), 6365 ARGS_ENTRY(struct rte_flow_item_compare, 6366 b.value)), 6367 }, 6368 [ITEM_COMPARE_FIELD_B_POINTER] = { 6369 .name = "b_ptr", 6370 .help = "pointer to comparator immediate value", 6371 .next = NEXT(compare_field_b, 6372 NEXT_ENTRY(COMMON_HEX), item_param), 6373 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6374 b.pvalue), 6375 ARGS_ENTRY_ARB(0, 0), 6376 ARGS_ENTRY_ARB 6377 (sizeof(struct rte_flow_item_compare), 6378 FLOW_FIELD_PATTERN_SIZE)), 6379 }, 6380 [ITEM_COMPARE_FIELD_WIDTH] = { 6381 .name = "width", 6382 .help = "number of bits to compare", 6383 .next = NEXT(item_compare_field, 6384 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6385 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6386 width)), 6387 }, 6388 6389 /* Validate/create actions. */ 6390 [ACTIONS] = { 6391 .name = "actions", 6392 .help = "submit a list of associated actions", 6393 .next = NEXT(next_action), 6394 .call = parse_vc, 6395 }, 6396 [ACTION_NEXT] = { 6397 .name = "/", 6398 .help = "specify next action", 6399 .next = NEXT(next_action), 6400 }, 6401 [ACTION_END] = { 6402 .name = "end", 6403 .help = "end list of actions", 6404 .priv = PRIV_ACTION(END, 0), 6405 .call = parse_vc, 6406 }, 6407 [ACTION_VOID] = { 6408 .name = "void", 6409 .help = "no-op action", 6410 .priv = PRIV_ACTION(VOID, 0), 6411 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6412 .call = parse_vc, 6413 }, 6414 [ACTION_PASSTHRU] = { 6415 .name = "passthru", 6416 .help = "let subsequent rule process matched packets", 6417 .priv = PRIV_ACTION(PASSTHRU, 0), 6418 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6419 .call = parse_vc, 6420 }, 6421 [ACTION_SKIP_CMAN] = { 6422 .name = "skip_cman", 6423 .help = "bypass cman on received packets", 6424 .priv = PRIV_ACTION(SKIP_CMAN, 0), 6425 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6426 .call = parse_vc, 6427 }, 6428 [ACTION_JUMP] = { 6429 .name = "jump", 6430 .help = "redirect traffic to a given group", 6431 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 6432 .next = NEXT(action_jump), 6433 .call = parse_vc, 6434 }, 6435 [ACTION_JUMP_GROUP] = { 6436 .name = "group", 6437 .help = "group to redirect traffic to", 6438 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 6439 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 6440 .call = parse_vc_conf, 6441 }, 6442 [ACTION_MARK] = { 6443 .name = "mark", 6444 .help = "attach 32 bit value to packets", 6445 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 6446 .next = NEXT(action_mark), 6447 .call = parse_vc, 6448 }, 6449 [ACTION_MARK_ID] = { 6450 .name = "id", 6451 .help = "32 bit value to return with packets", 6452 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6453 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 6454 .call = parse_vc_conf, 6455 }, 6456 [ACTION_FLAG] = { 6457 .name = "flag", 6458 .help = "flag packets", 6459 .priv = PRIV_ACTION(FLAG, 0), 6460 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6461 .call = parse_vc, 6462 }, 6463 [ACTION_QUEUE] = { 6464 .name = "queue", 6465 .help = "assign packets to a given queue index", 6466 .priv = PRIV_ACTION(QUEUE, 6467 sizeof(struct rte_flow_action_queue)), 6468 .next = NEXT(action_queue), 6469 .call = parse_vc, 6470 }, 6471 [ACTION_QUEUE_INDEX] = { 6472 .name = "index", 6473 .help = "queue index to use", 6474 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 6475 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 6476 .call = parse_vc_conf, 6477 }, 6478 [ACTION_DROP] = { 6479 .name = "drop", 6480 .help = "drop packets (note: passthru has priority)", 6481 .priv = PRIV_ACTION(DROP, 0), 6482 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6483 .call = parse_vc, 6484 }, 6485 [ACTION_COUNT] = { 6486 .name = "count", 6487 .help = "enable counters for this rule", 6488 .priv = PRIV_ACTION(COUNT, 6489 sizeof(struct rte_flow_action_count)), 6490 .next = NEXT(action_count), 6491 .call = parse_vc, 6492 }, 6493 [ACTION_COUNT_ID] = { 6494 .name = "identifier", 6495 .help = "counter identifier to use", 6496 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 6497 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 6498 .call = parse_vc_conf, 6499 }, 6500 [ACTION_RSS] = { 6501 .name = "rss", 6502 .help = "spread packets among several queues", 6503 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 6504 .next = NEXT(action_rss), 6505 .call = parse_vc_action_rss, 6506 }, 6507 [ACTION_RSS_FUNC] = { 6508 .name = "func", 6509 .help = "RSS hash function to apply", 6510 .next = NEXT(action_rss, 6511 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 6512 ACTION_RSS_FUNC_TOEPLITZ, 6513 ACTION_RSS_FUNC_SIMPLE_XOR, 6514 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 6515 }, 6516 [ACTION_RSS_FUNC_DEFAULT] = { 6517 .name = "default", 6518 .help = "default hash function", 6519 .call = parse_vc_action_rss_func, 6520 }, 6521 [ACTION_RSS_FUNC_TOEPLITZ] = { 6522 .name = "toeplitz", 6523 .help = "Toeplitz hash function", 6524 .call = parse_vc_action_rss_func, 6525 }, 6526 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 6527 .name = "simple_xor", 6528 .help = "simple XOR hash function", 6529 .call = parse_vc_action_rss_func, 6530 }, 6531 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 6532 .name = "symmetric_toeplitz", 6533 .help = "Symmetric Toeplitz hash function", 6534 .call = parse_vc_action_rss_func, 6535 }, 6536 [ACTION_RSS_LEVEL] = { 6537 .name = "level", 6538 .help = "encapsulation level for \"types\"", 6539 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6540 .args = ARGS(ARGS_ENTRY_ARB 6541 (offsetof(struct action_rss_data, conf) + 6542 offsetof(struct rte_flow_action_rss, level), 6543 sizeof(((struct rte_flow_action_rss *)0)-> 6544 level))), 6545 }, 6546 [ACTION_RSS_TYPES] = { 6547 .name = "types", 6548 .help = "specific RSS hash types", 6549 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 6550 }, 6551 [ACTION_RSS_TYPE] = { 6552 .name = "{type}", 6553 .help = "RSS hash type", 6554 .call = parse_vc_action_rss_type, 6555 .comp = comp_vc_action_rss_type, 6556 }, 6557 [ACTION_RSS_KEY] = { 6558 .name = "key", 6559 .help = "RSS hash key", 6560 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 6561 .args = ARGS(ARGS_ENTRY_ARB 6562 (offsetof(struct action_rss_data, conf) + 6563 offsetof(struct rte_flow_action_rss, key), 6564 sizeof(((struct rte_flow_action_rss *)0)->key)), 6565 ARGS_ENTRY_ARB 6566 (offsetof(struct action_rss_data, conf) + 6567 offsetof(struct rte_flow_action_rss, key_len), 6568 sizeof(((struct rte_flow_action_rss *)0)-> 6569 key_len)), 6570 ARGS_ENTRY(struct action_rss_data, key)), 6571 }, 6572 [ACTION_RSS_KEY_LEN] = { 6573 .name = "key_len", 6574 .help = "RSS hash key length in bytes", 6575 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6576 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6577 (offsetof(struct action_rss_data, conf) + 6578 offsetof(struct rte_flow_action_rss, key_len), 6579 sizeof(((struct rte_flow_action_rss *)0)-> 6580 key_len), 6581 0, 6582 RSS_HASH_KEY_LENGTH)), 6583 }, 6584 [ACTION_RSS_QUEUES] = { 6585 .name = "queues", 6586 .help = "queue indices to use", 6587 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 6588 .call = parse_vc_conf, 6589 }, 6590 [ACTION_RSS_QUEUE] = { 6591 .name = "{queue}", 6592 .help = "queue index", 6593 .call = parse_vc_action_rss_queue, 6594 .comp = comp_vc_action_rss_queue, 6595 }, 6596 [ACTION_PF] = { 6597 .name = "pf", 6598 .help = "direct traffic to physical function", 6599 .priv = PRIV_ACTION(PF, 0), 6600 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6601 .call = parse_vc, 6602 }, 6603 [ACTION_VF] = { 6604 .name = "vf", 6605 .help = "direct traffic to a virtual function ID", 6606 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 6607 .next = NEXT(action_vf), 6608 .call = parse_vc, 6609 }, 6610 [ACTION_VF_ORIGINAL] = { 6611 .name = "original", 6612 .help = "use original VF ID if possible", 6613 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 6614 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 6615 original, 1)), 6616 .call = parse_vc_conf, 6617 }, 6618 [ACTION_VF_ID] = { 6619 .name = "id", 6620 .help = "VF ID", 6621 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 6622 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 6623 .call = parse_vc_conf, 6624 }, 6625 [ACTION_PORT_ID] = { 6626 .name = "port_id", 6627 .help = "direct matching traffic to a given DPDK port ID", 6628 .priv = PRIV_ACTION(PORT_ID, 6629 sizeof(struct rte_flow_action_port_id)), 6630 .next = NEXT(action_port_id), 6631 .call = parse_vc, 6632 }, 6633 [ACTION_PORT_ID_ORIGINAL] = { 6634 .name = "original", 6635 .help = "use original DPDK port ID if possible", 6636 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 6637 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 6638 original, 1)), 6639 .call = parse_vc_conf, 6640 }, 6641 [ACTION_PORT_ID_ID] = { 6642 .name = "id", 6643 .help = "DPDK port ID", 6644 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 6645 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 6646 .call = parse_vc_conf, 6647 }, 6648 [ACTION_METER] = { 6649 .name = "meter", 6650 .help = "meter the directed packets at given id", 6651 .priv = PRIV_ACTION(METER, 6652 sizeof(struct rte_flow_action_meter)), 6653 .next = NEXT(action_meter), 6654 .call = parse_vc, 6655 }, 6656 [ACTION_METER_COLOR] = { 6657 .name = "color", 6658 .help = "meter color for the packets", 6659 .priv = PRIV_ACTION(METER_COLOR, 6660 sizeof(struct rte_flow_action_meter_color)), 6661 .next = NEXT(action_meter_color), 6662 .call = parse_vc, 6663 }, 6664 [ACTION_METER_COLOR_TYPE] = { 6665 .name = "type", 6666 .help = "specific meter color", 6667 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6668 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 6669 ACTION_METER_COLOR_YELLOW, 6670 ACTION_METER_COLOR_RED)), 6671 }, 6672 [ACTION_METER_COLOR_GREEN] = { 6673 .name = "green", 6674 .help = "meter color green", 6675 .call = parse_vc_action_meter_color_type, 6676 }, 6677 [ACTION_METER_COLOR_YELLOW] = { 6678 .name = "yellow", 6679 .help = "meter color yellow", 6680 .call = parse_vc_action_meter_color_type, 6681 }, 6682 [ACTION_METER_COLOR_RED] = { 6683 .name = "red", 6684 .help = "meter color red", 6685 .call = parse_vc_action_meter_color_type, 6686 }, 6687 [ACTION_METER_ID] = { 6688 .name = "mtr_id", 6689 .help = "meter id to use", 6690 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 6691 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 6692 .call = parse_vc_conf, 6693 }, 6694 [ACTION_METER_MARK] = { 6695 .name = "meter_mark", 6696 .help = "meter the directed packets using profile and policy", 6697 .priv = PRIV_ACTION(METER_MARK, 6698 sizeof(struct rte_flow_action_meter_mark)), 6699 .next = NEXT(action_meter_mark), 6700 .call = parse_vc, 6701 }, 6702 [ACTION_METER_PROFILE] = { 6703 .name = "mtr_profile", 6704 .help = "meter profile id to use", 6705 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 6706 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6707 }, 6708 [ACTION_METER_PROFILE_ID2PTR] = { 6709 .name = "{mtr_profile_id}", 6710 .type = "PROFILE_ID", 6711 .help = "meter profile id", 6712 .next = NEXT(action_meter_mark), 6713 .call = parse_meter_profile_id2ptr, 6714 .comp = comp_none, 6715 }, 6716 [ACTION_METER_POLICY] = { 6717 .name = "mtr_policy", 6718 .help = "meter policy id to use", 6719 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 6720 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6721 }, 6722 [ACTION_METER_POLICY_ID2PTR] = { 6723 .name = "{mtr_policy_id}", 6724 .type = "POLICY_ID", 6725 .help = "meter policy id", 6726 .next = NEXT(action_meter_mark), 6727 .call = parse_meter_policy_id2ptr, 6728 .comp = comp_none, 6729 }, 6730 [ACTION_METER_COLOR_MODE] = { 6731 .name = "mtr_color_mode", 6732 .help = "meter color awareness mode", 6733 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6734 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 6735 .call = parse_vc_conf, 6736 }, 6737 [ACTION_METER_STATE] = { 6738 .name = "mtr_state", 6739 .help = "meter state", 6740 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6741 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 6742 .call = parse_vc_conf, 6743 }, 6744 [ACTION_OF_DEC_NW_TTL] = { 6745 .name = "of_dec_nw_ttl", 6746 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 6747 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 6748 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6749 .call = parse_vc, 6750 }, 6751 [ACTION_OF_POP_VLAN] = { 6752 .name = "of_pop_vlan", 6753 .help = "OpenFlow's OFPAT_POP_VLAN", 6754 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 6755 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6756 .call = parse_vc, 6757 }, 6758 [ACTION_OF_PUSH_VLAN] = { 6759 .name = "of_push_vlan", 6760 .help = "OpenFlow's OFPAT_PUSH_VLAN", 6761 .priv = PRIV_ACTION 6762 (OF_PUSH_VLAN, 6763 sizeof(struct rte_flow_action_of_push_vlan)), 6764 .next = NEXT(action_of_push_vlan), 6765 .call = parse_vc, 6766 }, 6767 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 6768 .name = "ethertype", 6769 .help = "EtherType", 6770 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 6771 .args = ARGS(ARGS_ENTRY_HTON 6772 (struct rte_flow_action_of_push_vlan, 6773 ethertype)), 6774 .call = parse_vc_conf, 6775 }, 6776 [ACTION_OF_SET_VLAN_VID] = { 6777 .name = "of_set_vlan_vid", 6778 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 6779 .priv = PRIV_ACTION 6780 (OF_SET_VLAN_VID, 6781 sizeof(struct rte_flow_action_of_set_vlan_vid)), 6782 .next = NEXT(action_of_set_vlan_vid), 6783 .call = parse_vc, 6784 }, 6785 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 6786 .name = "vlan_vid", 6787 .help = "VLAN id", 6788 .next = NEXT(action_of_set_vlan_vid, 6789 NEXT_ENTRY(COMMON_UNSIGNED)), 6790 .args = ARGS(ARGS_ENTRY_HTON 6791 (struct rte_flow_action_of_set_vlan_vid, 6792 vlan_vid)), 6793 .call = parse_vc_conf, 6794 }, 6795 [ACTION_OF_SET_VLAN_PCP] = { 6796 .name = "of_set_vlan_pcp", 6797 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 6798 .priv = PRIV_ACTION 6799 (OF_SET_VLAN_PCP, 6800 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 6801 .next = NEXT(action_of_set_vlan_pcp), 6802 .call = parse_vc, 6803 }, 6804 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 6805 .name = "vlan_pcp", 6806 .help = "VLAN priority", 6807 .next = NEXT(action_of_set_vlan_pcp, 6808 NEXT_ENTRY(COMMON_UNSIGNED)), 6809 .args = ARGS(ARGS_ENTRY_HTON 6810 (struct rte_flow_action_of_set_vlan_pcp, 6811 vlan_pcp)), 6812 .call = parse_vc_conf, 6813 }, 6814 [ACTION_OF_POP_MPLS] = { 6815 .name = "of_pop_mpls", 6816 .help = "OpenFlow's OFPAT_POP_MPLS", 6817 .priv = PRIV_ACTION(OF_POP_MPLS, 6818 sizeof(struct rte_flow_action_of_pop_mpls)), 6819 .next = NEXT(action_of_pop_mpls), 6820 .call = parse_vc, 6821 }, 6822 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 6823 .name = "ethertype", 6824 .help = "EtherType", 6825 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6826 .args = ARGS(ARGS_ENTRY_HTON 6827 (struct rte_flow_action_of_pop_mpls, 6828 ethertype)), 6829 .call = parse_vc_conf, 6830 }, 6831 [ACTION_OF_PUSH_MPLS] = { 6832 .name = "of_push_mpls", 6833 .help = "OpenFlow's OFPAT_PUSH_MPLS", 6834 .priv = PRIV_ACTION 6835 (OF_PUSH_MPLS, 6836 sizeof(struct rte_flow_action_of_push_mpls)), 6837 .next = NEXT(action_of_push_mpls), 6838 .call = parse_vc, 6839 }, 6840 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 6841 .name = "ethertype", 6842 .help = "EtherType", 6843 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6844 .args = ARGS(ARGS_ENTRY_HTON 6845 (struct rte_flow_action_of_push_mpls, 6846 ethertype)), 6847 .call = parse_vc_conf, 6848 }, 6849 [ACTION_VXLAN_ENCAP] = { 6850 .name = "vxlan_encap", 6851 .help = "VXLAN encapsulation, uses configuration set by \"set" 6852 " vxlan\"", 6853 .priv = PRIV_ACTION(VXLAN_ENCAP, 6854 sizeof(struct action_vxlan_encap_data)), 6855 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6856 .call = parse_vc_action_vxlan_encap, 6857 }, 6858 [ACTION_VXLAN_DECAP] = { 6859 .name = "vxlan_decap", 6860 .help = "Performs a decapsulation action by stripping all" 6861 " headers of the VXLAN tunnel network overlay from the" 6862 " matched flow.", 6863 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 6864 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6865 .call = parse_vc, 6866 }, 6867 [ACTION_NVGRE_ENCAP] = { 6868 .name = "nvgre_encap", 6869 .help = "NVGRE encapsulation, uses configuration set by \"set" 6870 " nvgre\"", 6871 .priv = PRIV_ACTION(NVGRE_ENCAP, 6872 sizeof(struct action_nvgre_encap_data)), 6873 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6874 .call = parse_vc_action_nvgre_encap, 6875 }, 6876 [ACTION_NVGRE_DECAP] = { 6877 .name = "nvgre_decap", 6878 .help = "Performs a decapsulation action by stripping all" 6879 " headers of the NVGRE tunnel network overlay from the" 6880 " matched flow.", 6881 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 6882 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6883 .call = parse_vc, 6884 }, 6885 [ACTION_L2_ENCAP] = { 6886 .name = "l2_encap", 6887 .help = "l2 encap, uses configuration set by" 6888 " \"set l2_encap\"", 6889 .priv = PRIV_ACTION(RAW_ENCAP, 6890 sizeof(struct action_raw_encap_data)), 6891 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6892 .call = parse_vc_action_l2_encap, 6893 }, 6894 [ACTION_L2_DECAP] = { 6895 .name = "l2_decap", 6896 .help = "l2 decap, uses configuration set by" 6897 " \"set l2_decap\"", 6898 .priv = PRIV_ACTION(RAW_DECAP, 6899 sizeof(struct action_raw_decap_data)), 6900 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6901 .call = parse_vc_action_l2_decap, 6902 }, 6903 [ACTION_MPLSOGRE_ENCAP] = { 6904 .name = "mplsogre_encap", 6905 .help = "mplsogre encapsulation, uses configuration set by" 6906 " \"set mplsogre_encap\"", 6907 .priv = PRIV_ACTION(RAW_ENCAP, 6908 sizeof(struct action_raw_encap_data)), 6909 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6910 .call = parse_vc_action_mplsogre_encap, 6911 }, 6912 [ACTION_MPLSOGRE_DECAP] = { 6913 .name = "mplsogre_decap", 6914 .help = "mplsogre decapsulation, uses configuration set by" 6915 " \"set mplsogre_decap\"", 6916 .priv = PRIV_ACTION(RAW_DECAP, 6917 sizeof(struct action_raw_decap_data)), 6918 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6919 .call = parse_vc_action_mplsogre_decap, 6920 }, 6921 [ACTION_MPLSOUDP_ENCAP] = { 6922 .name = "mplsoudp_encap", 6923 .help = "mplsoudp encapsulation, uses configuration set by" 6924 " \"set mplsoudp_encap\"", 6925 .priv = PRIV_ACTION(RAW_ENCAP, 6926 sizeof(struct action_raw_encap_data)), 6927 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6928 .call = parse_vc_action_mplsoudp_encap, 6929 }, 6930 [ACTION_MPLSOUDP_DECAP] = { 6931 .name = "mplsoudp_decap", 6932 .help = "mplsoudp decapsulation, uses configuration set by" 6933 " \"set mplsoudp_decap\"", 6934 .priv = PRIV_ACTION(RAW_DECAP, 6935 sizeof(struct action_raw_decap_data)), 6936 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6937 .call = parse_vc_action_mplsoudp_decap, 6938 }, 6939 [ACTION_SET_IPV4_SRC] = { 6940 .name = "set_ipv4_src", 6941 .help = "Set a new IPv4 source address in the outermost" 6942 " IPv4 header", 6943 .priv = PRIV_ACTION(SET_IPV4_SRC, 6944 sizeof(struct rte_flow_action_set_ipv4)), 6945 .next = NEXT(action_set_ipv4_src), 6946 .call = parse_vc, 6947 }, 6948 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 6949 .name = "ipv4_addr", 6950 .help = "new IPv4 source address to set", 6951 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 6952 .args = ARGS(ARGS_ENTRY_HTON 6953 (struct rte_flow_action_set_ipv4, ipv4_addr)), 6954 .call = parse_vc_conf, 6955 }, 6956 [ACTION_SET_IPV4_DST] = { 6957 .name = "set_ipv4_dst", 6958 .help = "Set a new IPv4 destination address in the outermost" 6959 " IPv4 header", 6960 .priv = PRIV_ACTION(SET_IPV4_DST, 6961 sizeof(struct rte_flow_action_set_ipv4)), 6962 .next = NEXT(action_set_ipv4_dst), 6963 .call = parse_vc, 6964 }, 6965 [ACTION_SET_IPV4_DST_IPV4_DST] = { 6966 .name = "ipv4_addr", 6967 .help = "new IPv4 destination address to set", 6968 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 6969 .args = ARGS(ARGS_ENTRY_HTON 6970 (struct rte_flow_action_set_ipv4, ipv4_addr)), 6971 .call = parse_vc_conf, 6972 }, 6973 [ACTION_SET_IPV6_SRC] = { 6974 .name = "set_ipv6_src", 6975 .help = "Set a new IPv6 source address in the outermost" 6976 " IPv6 header", 6977 .priv = PRIV_ACTION(SET_IPV6_SRC, 6978 sizeof(struct rte_flow_action_set_ipv6)), 6979 .next = NEXT(action_set_ipv6_src), 6980 .call = parse_vc, 6981 }, 6982 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 6983 .name = "ipv6_addr", 6984 .help = "new IPv6 source address to set", 6985 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 6986 .args = ARGS(ARGS_ENTRY_HTON 6987 (struct rte_flow_action_set_ipv6, ipv6_addr)), 6988 .call = parse_vc_conf, 6989 }, 6990 [ACTION_SET_IPV6_DST] = { 6991 .name = "set_ipv6_dst", 6992 .help = "Set a new IPv6 destination address in the outermost" 6993 " IPv6 header", 6994 .priv = PRIV_ACTION(SET_IPV6_DST, 6995 sizeof(struct rte_flow_action_set_ipv6)), 6996 .next = NEXT(action_set_ipv6_dst), 6997 .call = parse_vc, 6998 }, 6999 [ACTION_SET_IPV6_DST_IPV6_DST] = { 7000 .name = "ipv6_addr", 7001 .help = "new IPv6 destination address to set", 7002 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7003 .args = ARGS(ARGS_ENTRY_HTON 7004 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7005 .call = parse_vc_conf, 7006 }, 7007 [ACTION_SET_TP_SRC] = { 7008 .name = "set_tp_src", 7009 .help = "set a new source port number in the outermost" 7010 " TCP/UDP header", 7011 .priv = PRIV_ACTION(SET_TP_SRC, 7012 sizeof(struct rte_flow_action_set_tp)), 7013 .next = NEXT(action_set_tp_src), 7014 .call = parse_vc, 7015 }, 7016 [ACTION_SET_TP_SRC_TP_SRC] = { 7017 .name = "port", 7018 .help = "new source port number to set", 7019 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 7020 .args = ARGS(ARGS_ENTRY_HTON 7021 (struct rte_flow_action_set_tp, port)), 7022 .call = parse_vc_conf, 7023 }, 7024 [ACTION_SET_TP_DST] = { 7025 .name = "set_tp_dst", 7026 .help = "set a new destination port number in the outermost" 7027 " TCP/UDP header", 7028 .priv = PRIV_ACTION(SET_TP_DST, 7029 sizeof(struct rte_flow_action_set_tp)), 7030 .next = NEXT(action_set_tp_dst), 7031 .call = parse_vc, 7032 }, 7033 [ACTION_SET_TP_DST_TP_DST] = { 7034 .name = "port", 7035 .help = "new destination port number to set", 7036 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 7037 .args = ARGS(ARGS_ENTRY_HTON 7038 (struct rte_flow_action_set_tp, port)), 7039 .call = parse_vc_conf, 7040 }, 7041 [ACTION_MAC_SWAP] = { 7042 .name = "mac_swap", 7043 .help = "Swap the source and destination MAC addresses" 7044 " in the outermost Ethernet header", 7045 .priv = PRIV_ACTION(MAC_SWAP, 0), 7046 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7047 .call = parse_vc, 7048 }, 7049 [ACTION_DEC_TTL] = { 7050 .name = "dec_ttl", 7051 .help = "decrease network TTL if available", 7052 .priv = PRIV_ACTION(DEC_TTL, 0), 7053 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7054 .call = parse_vc, 7055 }, 7056 [ACTION_SET_TTL] = { 7057 .name = "set_ttl", 7058 .help = "set ttl value", 7059 .priv = PRIV_ACTION(SET_TTL, 7060 sizeof(struct rte_flow_action_set_ttl)), 7061 .next = NEXT(action_set_ttl), 7062 .call = parse_vc, 7063 }, 7064 [ACTION_SET_TTL_TTL] = { 7065 .name = "ttl_value", 7066 .help = "new ttl value to set", 7067 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 7068 .args = ARGS(ARGS_ENTRY_HTON 7069 (struct rte_flow_action_set_ttl, ttl_value)), 7070 .call = parse_vc_conf, 7071 }, 7072 [ACTION_SET_MAC_SRC] = { 7073 .name = "set_mac_src", 7074 .help = "set source mac address", 7075 .priv = PRIV_ACTION(SET_MAC_SRC, 7076 sizeof(struct rte_flow_action_set_mac)), 7077 .next = NEXT(action_set_mac_src), 7078 .call = parse_vc, 7079 }, 7080 [ACTION_SET_MAC_SRC_MAC_SRC] = { 7081 .name = "mac_addr", 7082 .help = "new source mac address", 7083 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 7084 .args = ARGS(ARGS_ENTRY_HTON 7085 (struct rte_flow_action_set_mac, mac_addr)), 7086 .call = parse_vc_conf, 7087 }, 7088 [ACTION_SET_MAC_DST] = { 7089 .name = "set_mac_dst", 7090 .help = "set destination mac address", 7091 .priv = PRIV_ACTION(SET_MAC_DST, 7092 sizeof(struct rte_flow_action_set_mac)), 7093 .next = NEXT(action_set_mac_dst), 7094 .call = parse_vc, 7095 }, 7096 [ACTION_SET_MAC_DST_MAC_DST] = { 7097 .name = "mac_addr", 7098 .help = "new destination mac address to set", 7099 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 7100 .args = ARGS(ARGS_ENTRY_HTON 7101 (struct rte_flow_action_set_mac, mac_addr)), 7102 .call = parse_vc_conf, 7103 }, 7104 [ACTION_INC_TCP_SEQ] = { 7105 .name = "inc_tcp_seq", 7106 .help = "increase TCP sequence number", 7107 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 7108 .next = NEXT(action_inc_tcp_seq), 7109 .call = parse_vc, 7110 }, 7111 [ACTION_INC_TCP_SEQ_VALUE] = { 7112 .name = "value", 7113 .help = "the value to increase TCP sequence number by", 7114 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7115 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7116 .call = parse_vc_conf, 7117 }, 7118 [ACTION_DEC_TCP_SEQ] = { 7119 .name = "dec_tcp_seq", 7120 .help = "decrease TCP sequence number", 7121 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 7122 .next = NEXT(action_dec_tcp_seq), 7123 .call = parse_vc, 7124 }, 7125 [ACTION_DEC_TCP_SEQ_VALUE] = { 7126 .name = "value", 7127 .help = "the value to decrease TCP sequence number by", 7128 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7129 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7130 .call = parse_vc_conf, 7131 }, 7132 [ACTION_INC_TCP_ACK] = { 7133 .name = "inc_tcp_ack", 7134 .help = "increase TCP acknowledgment number", 7135 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 7136 .next = NEXT(action_inc_tcp_ack), 7137 .call = parse_vc, 7138 }, 7139 [ACTION_INC_TCP_ACK_VALUE] = { 7140 .name = "value", 7141 .help = "the value to increase TCP acknowledgment number by", 7142 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7143 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7144 .call = parse_vc_conf, 7145 }, 7146 [ACTION_DEC_TCP_ACK] = { 7147 .name = "dec_tcp_ack", 7148 .help = "decrease TCP acknowledgment number", 7149 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 7150 .next = NEXT(action_dec_tcp_ack), 7151 .call = parse_vc, 7152 }, 7153 [ACTION_DEC_TCP_ACK_VALUE] = { 7154 .name = "value", 7155 .help = "the value to decrease TCP acknowledgment number by", 7156 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7157 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7158 .call = parse_vc_conf, 7159 }, 7160 [ACTION_RAW_ENCAP] = { 7161 .name = "raw_encap", 7162 .help = "encapsulation data, defined by set raw_encap", 7163 .priv = PRIV_ACTION(RAW_ENCAP, 7164 sizeof(struct action_raw_encap_data)), 7165 .next = NEXT(action_raw_encap), 7166 .call = parse_vc_action_raw_encap, 7167 }, 7168 [ACTION_RAW_ENCAP_SIZE] = { 7169 .name = "size", 7170 .help = "raw encap size", 7171 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7172 NEXT_ENTRY(COMMON_UNSIGNED)), 7173 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_raw_encap, size)), 7174 .call = parse_vc_conf, 7175 }, 7176 [ACTION_RAW_ENCAP_INDEX] = { 7177 .name = "index", 7178 .help = "the index of raw_encap_confs", 7179 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 7180 }, 7181 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 7182 .name = "{index}", 7183 .type = "UNSIGNED", 7184 .help = "unsigned integer value", 7185 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7186 .call = parse_vc_action_raw_encap_index, 7187 .comp = comp_set_raw_index, 7188 }, 7189 [ACTION_RAW_DECAP] = { 7190 .name = "raw_decap", 7191 .help = "decapsulation data, defined by set raw_encap", 7192 .priv = PRIV_ACTION(RAW_DECAP, 7193 sizeof(struct action_raw_decap_data)), 7194 .next = NEXT(action_raw_decap), 7195 .call = parse_vc_action_raw_decap, 7196 }, 7197 [ACTION_RAW_DECAP_INDEX] = { 7198 .name = "index", 7199 .help = "the index of raw_encap_confs", 7200 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 7201 }, 7202 [ACTION_RAW_DECAP_INDEX_VALUE] = { 7203 .name = "{index}", 7204 .type = "UNSIGNED", 7205 .help = "unsigned integer value", 7206 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7207 .call = parse_vc_action_raw_decap_index, 7208 .comp = comp_set_raw_index, 7209 }, 7210 [ACTION_MODIFY_FIELD] = { 7211 .name = "modify_field", 7212 .help = "modify destination field with data from source field", 7213 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 7214 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 7215 .call = parse_vc, 7216 }, 7217 [ACTION_MODIFY_FIELD_OP] = { 7218 .name = "op", 7219 .help = "operation type", 7220 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 7221 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 7222 .call = parse_vc_conf, 7223 }, 7224 [ACTION_MODIFY_FIELD_OP_VALUE] = { 7225 .name = "{operation}", 7226 .help = "operation type value", 7227 .call = parse_vc_modify_field_op, 7228 .comp = comp_set_modify_field_op, 7229 }, 7230 [ACTION_MODIFY_FIELD_DST_TYPE] = { 7231 .name = "dst_type", 7232 .help = "destination field type", 7233 .next = NEXT(action_modify_field_dst, 7234 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 7235 .call = parse_vc_conf, 7236 }, 7237 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 7238 .name = "{dst_type}", 7239 .help = "destination field type value", 7240 .call = parse_vc_modify_field_id, 7241 .comp = comp_set_modify_field_id, 7242 }, 7243 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 7244 .name = "dst_level", 7245 .help = "destination field level", 7246 .next = NEXT(action_modify_field_dst, 7247 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), 7248 .call = parse_vc_conf, 7249 }, 7250 [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { 7251 .name = "{dst_level}", 7252 .help = "destination field level value", 7253 .call = parse_vc_modify_field_level, 7254 .comp = comp_none, 7255 }, 7256 [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { 7257 .name = "dst_tag_index", 7258 .help = "destination field tag array", 7259 .next = NEXT(action_modify_field_dst, 7260 NEXT_ENTRY(COMMON_UNSIGNED)), 7261 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7262 dst.tag_index)), 7263 .call = parse_vc_conf, 7264 }, 7265 [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { 7266 .name = "dst_type_id", 7267 .help = "destination field type ID", 7268 .next = NEXT(action_modify_field_dst, 7269 NEXT_ENTRY(COMMON_UNSIGNED)), 7270 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7271 dst.type)), 7272 .call = parse_vc_conf, 7273 }, 7274 [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { 7275 .name = "dst_class", 7276 .help = "destination field class ID", 7277 .next = NEXT(action_modify_field_dst, 7278 NEXT_ENTRY(COMMON_UNSIGNED)), 7279 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7280 dst.class_id)), 7281 .call = parse_vc_conf, 7282 }, 7283 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 7284 .name = "dst_offset", 7285 .help = "destination field bit offset", 7286 .next = NEXT(action_modify_field_dst, 7287 NEXT_ENTRY(COMMON_UNSIGNED)), 7288 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7289 dst.offset)), 7290 .call = parse_vc_conf, 7291 }, 7292 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 7293 .name = "src_type", 7294 .help = "source field type", 7295 .next = NEXT(action_modify_field_src, 7296 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 7297 .call = parse_vc_conf, 7298 }, 7299 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 7300 .name = "{src_type}", 7301 .help = "source field type value", 7302 .call = parse_vc_modify_field_id, 7303 .comp = comp_set_modify_field_id, 7304 }, 7305 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 7306 .name = "src_level", 7307 .help = "source field level", 7308 .next = NEXT(action_modify_field_src, 7309 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), 7310 .call = parse_vc_conf, 7311 }, 7312 [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { 7313 .name = "{src_level}", 7314 .help = "source field level value", 7315 .call = parse_vc_modify_field_level, 7316 .comp = comp_none, 7317 }, 7318 [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { 7319 .name = "stc_tag_index", 7320 .help = "source field tag array", 7321 .next = NEXT(action_modify_field_src, 7322 NEXT_ENTRY(COMMON_UNSIGNED)), 7323 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7324 src.tag_index)), 7325 .call = parse_vc_conf, 7326 }, 7327 [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { 7328 .name = "src_type_id", 7329 .help = "source field type ID", 7330 .next = NEXT(action_modify_field_src, 7331 NEXT_ENTRY(COMMON_UNSIGNED)), 7332 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7333 src.type)), 7334 .call = parse_vc_conf, 7335 }, 7336 [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { 7337 .name = "src_class", 7338 .help = "source field class ID", 7339 .next = NEXT(action_modify_field_src, 7340 NEXT_ENTRY(COMMON_UNSIGNED)), 7341 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7342 src.class_id)), 7343 .call = parse_vc_conf, 7344 }, 7345 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 7346 .name = "src_offset", 7347 .help = "source field bit offset", 7348 .next = NEXT(action_modify_field_src, 7349 NEXT_ENTRY(COMMON_UNSIGNED)), 7350 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7351 src.offset)), 7352 .call = parse_vc_conf, 7353 }, 7354 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 7355 .name = "src_value", 7356 .help = "source immediate value", 7357 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7358 NEXT_ENTRY(COMMON_HEX)), 7359 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 7360 ARGS_ENTRY_ARB(0, 0), 7361 ARGS_ENTRY(struct rte_flow_action_modify_field, 7362 src.value)), 7363 .call = parse_vc_conf, 7364 }, 7365 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 7366 .name = "src_ptr", 7367 .help = "pointer to source immediate value", 7368 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7369 NEXT_ENTRY(COMMON_HEX)), 7370 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7371 src.pvalue), 7372 ARGS_ENTRY_ARB(0, 0), 7373 ARGS_ENTRY_ARB 7374 (sizeof(struct rte_flow_action_modify_field), 7375 FLOW_FIELD_PATTERN_SIZE)), 7376 .call = parse_vc_conf, 7377 }, 7378 [ACTION_MODIFY_FIELD_WIDTH] = { 7379 .name = "width", 7380 .help = "number of bits to copy", 7381 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7382 NEXT_ENTRY(COMMON_UNSIGNED)), 7383 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7384 width)), 7385 .call = parse_vc_conf, 7386 }, 7387 [ACTION_SEND_TO_KERNEL] = { 7388 .name = "send_to_kernel", 7389 .help = "send packets to kernel", 7390 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 7391 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7392 .call = parse_vc, 7393 }, 7394 [ACTION_IPV6_EXT_REMOVE] = { 7395 .name = "ipv6_ext_remove", 7396 .help = "IPv6 extension type, defined by set ipv6_ext_remove", 7397 .priv = PRIV_ACTION(IPV6_EXT_REMOVE, 7398 sizeof(struct action_ipv6_ext_remove_data)), 7399 .next = NEXT(action_ipv6_ext_remove), 7400 .call = parse_vc_action_ipv6_ext_remove, 7401 }, 7402 [ACTION_IPV6_EXT_REMOVE_INDEX] = { 7403 .name = "index", 7404 .help = "the index of ipv6_ext_remove", 7405 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), 7406 }, 7407 [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { 7408 .name = "{index}", 7409 .type = "UNSIGNED", 7410 .help = "unsigned integer value", 7411 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7412 .call = parse_vc_action_ipv6_ext_remove_index, 7413 .comp = comp_set_ipv6_ext_index, 7414 }, 7415 [ACTION_IPV6_EXT_PUSH] = { 7416 .name = "ipv6_ext_push", 7417 .help = "IPv6 extension data, defined by set ipv6_ext_push", 7418 .priv = PRIV_ACTION(IPV6_EXT_PUSH, 7419 sizeof(struct action_ipv6_ext_push_data)), 7420 .next = NEXT(action_ipv6_ext_push), 7421 .call = parse_vc_action_ipv6_ext_push, 7422 }, 7423 [ACTION_IPV6_EXT_PUSH_INDEX] = { 7424 .name = "index", 7425 .help = "the index of ipv6_ext_push", 7426 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), 7427 }, 7428 [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { 7429 .name = "{index}", 7430 .type = "UNSIGNED", 7431 .help = "unsigned integer value", 7432 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7433 .call = parse_vc_action_ipv6_ext_push_index, 7434 .comp = comp_set_ipv6_ext_index, 7435 }, 7436 [ACTION_NAT64] = { 7437 .name = "nat64", 7438 .help = "NAT64 IP headers translation", 7439 .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), 7440 .next = NEXT(action_nat64), 7441 .call = parse_vc, 7442 }, 7443 [ACTION_NAT64_MODE] = { 7444 .name = "type", 7445 .help = "NAT64 translation type", 7446 .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), 7447 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), 7448 .call = parse_vc_conf, 7449 }, 7450 /* Top level command. */ 7451 [SET] = { 7452 .name = "set", 7453 .help = "set raw encap/decap/sample data", 7454 .type = "set raw_encap|raw_decap <index> <pattern>" 7455 " or set sample_actions <index> <action>", 7456 .next = NEXT(NEXT_ENTRY 7457 (SET_RAW_ENCAP, 7458 SET_RAW_DECAP, 7459 SET_SAMPLE_ACTIONS, 7460 SET_IPV6_EXT_REMOVE, 7461 SET_IPV6_EXT_PUSH)), 7462 .call = parse_set_init, 7463 }, 7464 /* Sub-level commands. */ 7465 [SET_RAW_ENCAP] = { 7466 .name = "raw_encap", 7467 .help = "set raw encap data", 7468 .next = NEXT(next_set_raw), 7469 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7470 (offsetof(struct buffer, port), 7471 sizeof(((struct buffer *)0)->port), 7472 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7473 .call = parse_set_raw_encap_decap, 7474 }, 7475 [SET_RAW_DECAP] = { 7476 .name = "raw_decap", 7477 .help = "set raw decap data", 7478 .next = NEXT(next_set_raw), 7479 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7480 (offsetof(struct buffer, port), 7481 sizeof(((struct buffer *)0)->port), 7482 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7483 .call = parse_set_raw_encap_decap, 7484 }, 7485 [SET_RAW_INDEX] = { 7486 .name = "{index}", 7487 .type = "COMMON_UNSIGNED", 7488 .help = "index of raw_encap/raw_decap data", 7489 .next = NEXT(next_item), 7490 .call = parse_port, 7491 }, 7492 [SET_SAMPLE_INDEX] = { 7493 .name = "{index}", 7494 .type = "UNSIGNED", 7495 .help = "index of sample actions", 7496 .next = NEXT(next_action_sample), 7497 .call = parse_port, 7498 }, 7499 [SET_SAMPLE_ACTIONS] = { 7500 .name = "sample_actions", 7501 .help = "set sample actions list", 7502 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 7503 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7504 (offsetof(struct buffer, port), 7505 sizeof(((struct buffer *)0)->port), 7506 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 7507 .call = parse_set_sample_action, 7508 }, 7509 [SET_IPV6_EXT_PUSH] = { 7510 .name = "ipv6_ext_push", 7511 .help = "set IPv6 extension header", 7512 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7513 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7514 (offsetof(struct buffer, port), 7515 sizeof(((struct buffer *)0)->port), 7516 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7517 .call = parse_set_ipv6_ext_action, 7518 }, 7519 [SET_IPV6_EXT_REMOVE] = { 7520 .name = "ipv6_ext_remove", 7521 .help = "set IPv6 extension header", 7522 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7523 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7524 (offsetof(struct buffer, port), 7525 sizeof(((struct buffer *)0)->port), 7526 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7527 .call = parse_set_ipv6_ext_action, 7528 }, 7529 [SET_IPV6_EXT_INDEX] = { 7530 .name = "{index}", 7531 .type = "UNSIGNED", 7532 .help = "index of ipv6 extension push/remove actions", 7533 .next = NEXT(item_ipv6_push_ext), 7534 .call = parse_port, 7535 }, 7536 [ITEM_IPV6_PUSH_REMOVE_EXT] = { 7537 .name = "ipv6_ext", 7538 .help = "set IPv6 extension header", 7539 .priv = PRIV_ITEM(IPV6_EXT, 7540 sizeof(struct rte_flow_item_ipv6_ext)), 7541 .next = NEXT(item_ipv6_push_ext_type), 7542 .call = parse_vc, 7543 }, 7544 [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { 7545 .name = "type", 7546 .help = "set IPv6 extension type", 7547 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 7548 next_hdr)), 7549 .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), 7550 item_param), 7551 }, 7552 [ACTION_SET_TAG] = { 7553 .name = "set_tag", 7554 .help = "set tag", 7555 .priv = PRIV_ACTION(SET_TAG, 7556 sizeof(struct rte_flow_action_set_tag)), 7557 .next = NEXT(action_set_tag), 7558 .call = parse_vc, 7559 }, 7560 [ACTION_SET_TAG_INDEX] = { 7561 .name = "index", 7562 .help = "index of tag array", 7563 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7564 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 7565 .call = parse_vc_conf, 7566 }, 7567 [ACTION_SET_TAG_DATA] = { 7568 .name = "data", 7569 .help = "tag value", 7570 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7571 .args = ARGS(ARGS_ENTRY 7572 (struct rte_flow_action_set_tag, data)), 7573 .call = parse_vc_conf, 7574 }, 7575 [ACTION_SET_TAG_MASK] = { 7576 .name = "mask", 7577 .help = "mask for tag value", 7578 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7579 .args = ARGS(ARGS_ENTRY 7580 (struct rte_flow_action_set_tag, mask)), 7581 .call = parse_vc_conf, 7582 }, 7583 [ACTION_SET_META] = { 7584 .name = "set_meta", 7585 .help = "set metadata", 7586 .priv = PRIV_ACTION(SET_META, 7587 sizeof(struct rte_flow_action_set_meta)), 7588 .next = NEXT(action_set_meta), 7589 .call = parse_vc_action_set_meta, 7590 }, 7591 [ACTION_SET_META_DATA] = { 7592 .name = "data", 7593 .help = "metadata value", 7594 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7595 .args = ARGS(ARGS_ENTRY 7596 (struct rte_flow_action_set_meta, data)), 7597 .call = parse_vc_conf, 7598 }, 7599 [ACTION_SET_META_MASK] = { 7600 .name = "mask", 7601 .help = "mask for metadata value", 7602 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7603 .args = ARGS(ARGS_ENTRY 7604 (struct rte_flow_action_set_meta, mask)), 7605 .call = parse_vc_conf, 7606 }, 7607 [ACTION_SET_IPV4_DSCP] = { 7608 .name = "set_ipv4_dscp", 7609 .help = "set DSCP value", 7610 .priv = PRIV_ACTION(SET_IPV4_DSCP, 7611 sizeof(struct rte_flow_action_set_dscp)), 7612 .next = NEXT(action_set_ipv4_dscp), 7613 .call = parse_vc, 7614 }, 7615 [ACTION_SET_IPV4_DSCP_VALUE] = { 7616 .name = "dscp_value", 7617 .help = "new IPv4 DSCP value to set", 7618 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7619 .args = ARGS(ARGS_ENTRY 7620 (struct rte_flow_action_set_dscp, dscp)), 7621 .call = parse_vc_conf, 7622 }, 7623 [ACTION_SET_IPV6_DSCP] = { 7624 .name = "set_ipv6_dscp", 7625 .help = "set DSCP value", 7626 .priv = PRIV_ACTION(SET_IPV6_DSCP, 7627 sizeof(struct rte_flow_action_set_dscp)), 7628 .next = NEXT(action_set_ipv6_dscp), 7629 .call = parse_vc, 7630 }, 7631 [ACTION_SET_IPV6_DSCP_VALUE] = { 7632 .name = "dscp_value", 7633 .help = "new IPv6 DSCP value to set", 7634 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7635 .args = ARGS(ARGS_ENTRY 7636 (struct rte_flow_action_set_dscp, dscp)), 7637 .call = parse_vc_conf, 7638 }, 7639 [ACTION_AGE] = { 7640 .name = "age", 7641 .help = "set a specific metadata header", 7642 .next = NEXT(action_age), 7643 .priv = PRIV_ACTION(AGE, 7644 sizeof(struct rte_flow_action_age)), 7645 .call = parse_vc, 7646 }, 7647 [ACTION_AGE_TIMEOUT] = { 7648 .name = "timeout", 7649 .help = "flow age timeout value", 7650 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 7651 timeout, 24)), 7652 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 7653 .call = parse_vc_conf, 7654 }, 7655 [ACTION_AGE_UPDATE] = { 7656 .name = "age_update", 7657 .help = "update aging parameter", 7658 .next = NEXT(action_age_update), 7659 .priv = PRIV_ACTION(AGE, 7660 sizeof(struct rte_flow_update_age)), 7661 .call = parse_vc, 7662 }, 7663 [ACTION_AGE_UPDATE_TIMEOUT] = { 7664 .name = "timeout", 7665 .help = "age timeout update value", 7666 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7667 timeout, 24)), 7668 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7669 .call = parse_vc_conf_timeout, 7670 }, 7671 [ACTION_AGE_UPDATE_TOUCH] = { 7672 .name = "touch", 7673 .help = "this flow is touched", 7674 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), 7675 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7676 touch, 1)), 7677 .call = parse_vc_conf, 7678 }, 7679 [ACTION_SAMPLE] = { 7680 .name = "sample", 7681 .help = "set a sample action", 7682 .next = NEXT(action_sample), 7683 .priv = PRIV_ACTION(SAMPLE, 7684 sizeof(struct action_sample_data)), 7685 .call = parse_vc_action_sample, 7686 }, 7687 [ACTION_SAMPLE_RATIO] = { 7688 .name = "ratio", 7689 .help = "flow sample ratio value", 7690 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 7691 .args = ARGS(ARGS_ENTRY_ARB 7692 (offsetof(struct action_sample_data, conf) + 7693 offsetof(struct rte_flow_action_sample, ratio), 7694 sizeof(((struct rte_flow_action_sample *)0)-> 7695 ratio))), 7696 }, 7697 [ACTION_SAMPLE_INDEX] = { 7698 .name = "index", 7699 .help = "the index of sample actions list", 7700 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 7701 }, 7702 [ACTION_SAMPLE_INDEX_VALUE] = { 7703 .name = "{index}", 7704 .type = "COMMON_UNSIGNED", 7705 .help = "unsigned integer value", 7706 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7707 .call = parse_vc_action_sample_index, 7708 .comp = comp_set_sample_index, 7709 }, 7710 [ACTION_CONNTRACK] = { 7711 .name = "conntrack", 7712 .help = "create a conntrack object", 7713 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7714 .priv = PRIV_ACTION(CONNTRACK, 7715 sizeof(struct rte_flow_action_conntrack)), 7716 .call = parse_vc, 7717 }, 7718 [ACTION_CONNTRACK_UPDATE] = { 7719 .name = "conntrack_update", 7720 .help = "update a conntrack object", 7721 .next = NEXT(action_update_conntrack), 7722 .priv = PRIV_ACTION(CONNTRACK, 7723 sizeof(struct rte_flow_modify_conntrack)), 7724 .call = parse_vc, 7725 }, 7726 [ACTION_CONNTRACK_UPDATE_DIR] = { 7727 .name = "dir", 7728 .help = "update a conntrack object direction", 7729 .next = NEXT(action_update_conntrack), 7730 .call = parse_vc_action_conntrack_update, 7731 }, 7732 [ACTION_CONNTRACK_UPDATE_CTX] = { 7733 .name = "ctx", 7734 .help = "update a conntrack object context", 7735 .next = NEXT(action_update_conntrack), 7736 .call = parse_vc_action_conntrack_update, 7737 }, 7738 [ACTION_PORT_REPRESENTOR] = { 7739 .name = "port_representor", 7740 .help = "at embedded switch level, send matching traffic to the given ethdev", 7741 .priv = PRIV_ACTION(PORT_REPRESENTOR, 7742 sizeof(struct rte_flow_action_ethdev)), 7743 .next = NEXT(action_port_representor), 7744 .call = parse_vc, 7745 }, 7746 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 7747 .name = "port_id", 7748 .help = "ethdev port ID", 7749 .next = NEXT(action_port_representor, 7750 NEXT_ENTRY(COMMON_UNSIGNED)), 7751 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7752 port_id)), 7753 .call = parse_vc_conf, 7754 }, 7755 [ACTION_REPRESENTED_PORT] = { 7756 .name = "represented_port", 7757 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 7758 .priv = PRIV_ACTION(REPRESENTED_PORT, 7759 sizeof(struct rte_flow_action_ethdev)), 7760 .next = NEXT(action_represented_port), 7761 .call = parse_vc, 7762 }, 7763 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 7764 .name = "ethdev_port_id", 7765 .help = "ethdev port ID", 7766 .next = NEXT(action_represented_port, 7767 NEXT_ENTRY(COMMON_UNSIGNED)), 7768 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7769 port_id)), 7770 .call = parse_vc_conf, 7771 }, 7772 /* Indirect action destroy arguments. */ 7773 [INDIRECT_ACTION_DESTROY_ID] = { 7774 .name = "action_id", 7775 .help = "specify a indirect action id to destroy", 7776 .next = NEXT(next_ia_destroy_attr, 7777 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7778 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 7779 args.ia_destroy.action_id)), 7780 .call = parse_ia_destroy, 7781 }, 7782 /* Indirect action create arguments. */ 7783 [INDIRECT_ACTION_CREATE_ID] = { 7784 .name = "action_id", 7785 .help = "specify a indirect action id to create", 7786 .next = NEXT(next_ia_create_attr, 7787 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7788 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 7789 }, 7790 [ACTION_INDIRECT] = { 7791 .name = "indirect", 7792 .help = "apply indirect action by id", 7793 .priv = PRIV_ACTION(INDIRECT, 0), 7794 .next = NEXT(next_ia), 7795 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7796 .call = parse_vc, 7797 }, 7798 [ACTION_INDIRECT_LIST] = { 7799 .name = "indirect_list", 7800 .help = "apply indirect list action by id", 7801 .priv = PRIV_ACTION(INDIRECT_LIST, 7802 sizeof(struct 7803 rte_flow_action_indirect_list)), 7804 .next = NEXT(next_ial), 7805 .call = parse_vc, 7806 }, 7807 [ACTION_INDIRECT_LIST_HANDLE] = { 7808 .name = "handle", 7809 .help = "indirect list handle", 7810 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), 7811 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7812 }, 7813 [ACTION_INDIRECT_LIST_CONF] = { 7814 .name = "conf", 7815 .help = "indirect list configuration", 7816 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), 7817 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7818 }, 7819 [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { 7820 .type = "UNSIGNED", 7821 .help = "unsigned integer value", 7822 .call = parse_indlst_id2ptr, 7823 }, 7824 [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { 7825 .type = "UNSIGNED", 7826 .help = "unsigned integer value", 7827 .call = parse_indlst_id2ptr, 7828 }, 7829 [ACTION_SHARED_INDIRECT] = { 7830 .name = "shared_indirect", 7831 .help = "apply indirect action by id and port", 7832 .priv = PRIV_ACTION(INDIRECT, 0), 7833 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), 7834 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), 7835 ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7836 .call = parse_vc, 7837 }, 7838 [INDIRECT_ACTION_PORT] = { 7839 .name = "{indirect_action_port}", 7840 .type = "INDIRECT_ACTION_PORT", 7841 .help = "indirect action port", 7842 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 7843 .call = parse_ia_port, 7844 .comp = comp_none, 7845 }, 7846 [INDIRECT_ACTION_ID2PTR] = { 7847 .name = "{action_id}", 7848 .type = "INDIRECT_ACTION_ID", 7849 .help = "indirect action id", 7850 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7851 .call = parse_ia_id2ptr, 7852 .comp = comp_none, 7853 }, 7854 [INDIRECT_ACTION_INGRESS] = { 7855 .name = "ingress", 7856 .help = "affect rule to ingress", 7857 .next = NEXT(next_ia_create_attr), 7858 .call = parse_ia, 7859 }, 7860 [INDIRECT_ACTION_EGRESS] = { 7861 .name = "egress", 7862 .help = "affect rule to egress", 7863 .next = NEXT(next_ia_create_attr), 7864 .call = parse_ia, 7865 }, 7866 [INDIRECT_ACTION_TRANSFER] = { 7867 .name = "transfer", 7868 .help = "affect rule to transfer", 7869 .next = NEXT(next_ia_create_attr), 7870 .call = parse_ia, 7871 }, 7872 [INDIRECT_ACTION_SPEC] = { 7873 .name = "action", 7874 .help = "specify action to create indirect handle", 7875 .next = NEXT(next_action), 7876 }, 7877 [INDIRECT_ACTION_LIST] = { 7878 .name = "list", 7879 .help = "specify actions for indirect handle list", 7880 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7881 .call = parse_ia, 7882 }, 7883 [INDIRECT_ACTION_FLOW_CONF] = { 7884 .name = "flow_conf", 7885 .help = "specify actions configuration for indirect handle list", 7886 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7887 .call = parse_ia, 7888 }, 7889 [ACTION_POL_G] = { 7890 .name = "g_actions", 7891 .help = "submit a list of associated actions for green", 7892 .next = NEXT(next_action), 7893 .call = parse_mp, 7894 }, 7895 [ACTION_POL_Y] = { 7896 .name = "y_actions", 7897 .help = "submit a list of associated actions for yellow", 7898 .next = NEXT(next_action), 7899 }, 7900 [ACTION_POL_R] = { 7901 .name = "r_actions", 7902 .help = "submit a list of associated actions for red", 7903 .next = NEXT(next_action), 7904 }, 7905 [ACTION_QUOTA_CREATE] = { 7906 .name = "quota_create", 7907 .help = "create quota action", 7908 .priv = PRIV_ACTION(QUOTA, 7909 sizeof(struct rte_flow_action_quota)), 7910 .next = NEXT(action_quota_create), 7911 .call = parse_vc 7912 }, 7913 [ACTION_QUOTA_CREATE_LIMIT] = { 7914 .name = "limit", 7915 .help = "quota limit", 7916 .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), 7917 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), 7918 .call = parse_vc_conf 7919 }, 7920 [ACTION_QUOTA_CREATE_MODE] = { 7921 .name = "mode", 7922 .help = "quota mode", 7923 .next = NEXT(action_quota_create, 7924 NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), 7925 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), 7926 .call = parse_vc_conf 7927 }, 7928 [ACTION_QUOTA_CREATE_MODE_NAME] = { 7929 .name = "mode_name", 7930 .help = "quota mode name", 7931 .call = parse_quota_mode_name, 7932 .comp = comp_quota_mode_name 7933 }, 7934 [ACTION_QUOTA_QU] = { 7935 .name = "quota_update", 7936 .help = "update quota action", 7937 .priv = PRIV_ACTION(QUOTA, 7938 sizeof(struct rte_flow_update_quota)), 7939 .next = NEXT(action_quota_update), 7940 .call = parse_vc 7941 }, 7942 [ACTION_QUOTA_QU_LIMIT] = { 7943 .name = "limit", 7944 .help = "quota limit", 7945 .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7946 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), 7947 .call = parse_vc_conf 7948 }, 7949 [ACTION_QUOTA_QU_UPDATE_OP] = { 7950 .name = "update_op", 7951 .help = "query update op SET|ADD", 7952 .next = NEXT(action_quota_update, 7953 NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), 7954 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), 7955 .call = parse_vc_conf 7956 }, 7957 [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { 7958 .name = "update_op_name", 7959 .help = "quota update op name", 7960 .call = parse_quota_update_name, 7961 .comp = comp_quota_update_name 7962 }, 7963 7964 /* Top-level command. */ 7965 [ADD] = { 7966 .name = "add", 7967 .type = "port meter policy {port_id} {arg}", 7968 .help = "add port meter policy", 7969 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 7970 .call = parse_init, 7971 }, 7972 /* Sub-level commands. */ 7973 [ITEM_POL_PORT] = { 7974 .name = "port", 7975 .help = "add port meter policy", 7976 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 7977 }, 7978 [ITEM_POL_METER] = { 7979 .name = "meter", 7980 .help = "add port meter policy", 7981 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 7982 }, 7983 [ITEM_POL_POLICY] = { 7984 .name = "policy", 7985 .help = "add port meter policy", 7986 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 7987 NEXT_ENTRY(ACTION_POL_Y), 7988 NEXT_ENTRY(ACTION_POL_G), 7989 NEXT_ENTRY(COMMON_POLICY_ID), 7990 NEXT_ENTRY(COMMON_PORT_ID)), 7991 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 7992 ARGS_ENTRY(struct buffer, port)), 7993 .call = parse_mp, 7994 }, 7995 [ITEM_AGGR_AFFINITY] = { 7996 .name = "aggr_affinity", 7997 .help = "match on the aggregated port receiving the packets", 7998 .priv = PRIV_ITEM(AGGR_AFFINITY, 7999 sizeof(struct rte_flow_item_aggr_affinity)), 8000 .next = NEXT(item_aggr_affinity), 8001 .call = parse_vc, 8002 }, 8003 [ITEM_AGGR_AFFINITY_VALUE] = { 8004 .name = "affinity", 8005 .help = "aggregated affinity value", 8006 .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), 8007 item_param), 8008 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, 8009 affinity)), 8010 }, 8011 [ITEM_TX_QUEUE] = { 8012 .name = "tx_queue", 8013 .help = "match on the tx queue of send packet", 8014 .priv = PRIV_ITEM(TX_QUEUE, 8015 sizeof(struct rte_flow_item_tx_queue)), 8016 .next = NEXT(item_tx_queue), 8017 .call = parse_vc, 8018 }, 8019 [ITEM_TX_QUEUE_VALUE] = { 8020 .name = "tx_queue_value", 8021 .help = "tx queue value", 8022 .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), 8023 item_param), 8024 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, 8025 tx_queue)), 8026 }, 8027 }; 8028 8029 /** Remove and return last entry from argument stack. */ 8030 static const struct arg * 8031 pop_args(struct context *ctx) 8032 { 8033 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 8034 } 8035 8036 /** Add entry on top of the argument stack. */ 8037 static int 8038 push_args(struct context *ctx, const struct arg *arg) 8039 { 8040 if (ctx->args_num == CTX_STACK_SIZE) 8041 return -1; 8042 ctx->args[ctx->args_num++] = arg; 8043 return 0; 8044 } 8045 8046 /** Spread value into buffer according to bit-mask. */ 8047 static size_t 8048 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 8049 { 8050 uint32_t i = arg->size; 8051 uint32_t end = 0; 8052 int sub = 1; 8053 int add = 0; 8054 size_t len = 0; 8055 8056 if (!arg->mask) 8057 return 0; 8058 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8059 if (!arg->hton) { 8060 i = 0; 8061 end = arg->size; 8062 sub = 0; 8063 add = 1; 8064 } 8065 #endif 8066 while (i != end) { 8067 unsigned int shift = 0; 8068 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 8069 8070 for (shift = 0; arg->mask[i] >> shift; ++shift) { 8071 if (!(arg->mask[i] & (1 << shift))) 8072 continue; 8073 ++len; 8074 if (!dst) 8075 continue; 8076 *buf &= ~(1 << shift); 8077 *buf |= (val & 1) << shift; 8078 val >>= 1; 8079 } 8080 i += add; 8081 } 8082 return len; 8083 } 8084 8085 /** Compare a string with a partial one of a given length. */ 8086 static int 8087 strcmp_partial(const char *full, const char *partial, size_t partial_len) 8088 { 8089 int r = strncmp(full, partial, partial_len); 8090 8091 if (r) 8092 return r; 8093 if (strlen(full) <= partial_len) 8094 return 0; 8095 return full[partial_len]; 8096 } 8097 8098 /** 8099 * Parse a prefix length and generate a bit-mask. 8100 * 8101 * Last argument (ctx->args) is retrieved to determine mask size, storage 8102 * location and whether the result must use network byte ordering. 8103 */ 8104 static int 8105 parse_prefix(struct context *ctx, const struct token *token, 8106 const char *str, unsigned int len, 8107 void *buf, unsigned int size) 8108 { 8109 const struct arg *arg = pop_args(ctx); 8110 static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff"; 8111 char *end; 8112 uintmax_t u; 8113 unsigned int bytes; 8114 unsigned int extra; 8115 8116 (void)token; 8117 /* Argument is expected. */ 8118 if (!arg) 8119 return -1; 8120 errno = 0; 8121 u = strtoumax(str, &end, 0); 8122 if (errno || (size_t)(end - str) != len) 8123 goto error; 8124 if (arg->mask) { 8125 uintmax_t v = 0; 8126 8127 extra = arg_entry_bf_fill(NULL, 0, arg); 8128 if (u > extra) 8129 goto error; 8130 if (!ctx->object) 8131 return len; 8132 extra -= u; 8133 while (u--) 8134 (v <<= 1, v |= 1); 8135 v <<= extra; 8136 if (!arg_entry_bf_fill(ctx->object, v, arg) || 8137 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 8138 goto error; 8139 return len; 8140 } 8141 bytes = u / 8; 8142 extra = u % 8; 8143 size = arg->size; 8144 if (bytes > size || bytes + !!extra > size) 8145 goto error; 8146 if (!ctx->object) 8147 return len; 8148 buf = (uint8_t *)ctx->object + arg->offset; 8149 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8150 if (!arg->hton) { 8151 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 8152 memset(buf, 0x00, size - bytes); 8153 if (extra) 8154 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 8155 } else 8156 #endif 8157 { 8158 memset(buf, 0xff, bytes); 8159 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 8160 if (extra) 8161 ((uint8_t *)buf)[bytes] = conv[extra]; 8162 } 8163 if (ctx->objmask) 8164 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 8165 return len; 8166 error: 8167 push_args(ctx, arg); 8168 return -1; 8169 } 8170 8171 /** Default parsing function for token name matching. */ 8172 static int 8173 parse_default(struct context *ctx, const struct token *token, 8174 const char *str, unsigned int len, 8175 void *buf, unsigned int size) 8176 { 8177 (void)ctx; 8178 (void)buf; 8179 (void)size; 8180 if (strcmp_partial(token->name, str, len)) 8181 return -1; 8182 return len; 8183 } 8184 8185 /** Parse flow command, initialize output buffer for subsequent tokens. */ 8186 static int 8187 parse_init(struct context *ctx, const struct token *token, 8188 const char *str, unsigned int len, 8189 void *buf, unsigned int size) 8190 { 8191 struct buffer *out = buf; 8192 8193 /* Token name must match. */ 8194 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8195 return -1; 8196 /* Nothing else to do if there is no buffer. */ 8197 if (!out) 8198 return len; 8199 /* Make sure buffer is large enough. */ 8200 if (size < sizeof(*out)) 8201 return -1; 8202 /* Initialize buffer. */ 8203 memset(out, 0x00, sizeof(*out)); 8204 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 8205 ctx->objdata = 0; 8206 ctx->object = out; 8207 ctx->objmask = NULL; 8208 return len; 8209 } 8210 8211 /** Parse tokens for indirect action commands. */ 8212 static int 8213 parse_ia(struct context *ctx, const struct token *token, 8214 const char *str, unsigned int len, 8215 void *buf, unsigned int size) 8216 { 8217 struct buffer *out = buf; 8218 8219 /* Token name must match. */ 8220 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8221 return -1; 8222 /* Nothing else to do if there is no buffer. */ 8223 if (!out) 8224 return len; 8225 if (!out->command) { 8226 if (ctx->curr != INDIRECT_ACTION) 8227 return -1; 8228 if (sizeof(*out) > size) 8229 return -1; 8230 out->command = ctx->curr; 8231 ctx->objdata = 0; 8232 ctx->object = out; 8233 ctx->objmask = NULL; 8234 out->args.vc.data = (uint8_t *)out + size; 8235 return len; 8236 } 8237 switch (ctx->curr) { 8238 case INDIRECT_ACTION_CREATE: 8239 case INDIRECT_ACTION_UPDATE: 8240 case INDIRECT_ACTION_QUERY_UPDATE: 8241 out->args.vc.actions = 8242 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8243 sizeof(double)); 8244 out->args.vc.attr.group = UINT32_MAX; 8245 /* fallthrough */ 8246 case INDIRECT_ACTION_QUERY: 8247 out->command = ctx->curr; 8248 ctx->objdata = 0; 8249 ctx->object = out; 8250 ctx->objmask = NULL; 8251 return len; 8252 case INDIRECT_ACTION_EGRESS: 8253 out->args.vc.attr.egress = 1; 8254 return len; 8255 case INDIRECT_ACTION_INGRESS: 8256 out->args.vc.attr.ingress = 1; 8257 return len; 8258 case INDIRECT_ACTION_TRANSFER: 8259 out->args.vc.attr.transfer = 1; 8260 return len; 8261 case INDIRECT_ACTION_QU_MODE: 8262 return len; 8263 case INDIRECT_ACTION_LIST: 8264 out->command = INDIRECT_ACTION_LIST_CREATE; 8265 return len; 8266 case INDIRECT_ACTION_FLOW_CONF: 8267 out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; 8268 return len; 8269 default: 8270 return -1; 8271 } 8272 } 8273 8274 8275 /** Parse tokens for indirect action destroy command. */ 8276 static int 8277 parse_ia_destroy(struct context *ctx, const struct token *token, 8278 const char *str, unsigned int len, 8279 void *buf, unsigned int size) 8280 { 8281 struct buffer *out = buf; 8282 uint32_t *action_id; 8283 8284 /* Token name must match. */ 8285 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8286 return -1; 8287 /* Nothing else to do if there is no buffer. */ 8288 if (!out) 8289 return len; 8290 if (!out->command || out->command == INDIRECT_ACTION) { 8291 if (ctx->curr != INDIRECT_ACTION_DESTROY) 8292 return -1; 8293 if (sizeof(*out) > size) 8294 return -1; 8295 out->command = ctx->curr; 8296 ctx->objdata = 0; 8297 ctx->object = out; 8298 ctx->objmask = NULL; 8299 out->args.ia_destroy.action_id = 8300 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8301 sizeof(double)); 8302 return len; 8303 } 8304 action_id = out->args.ia_destroy.action_id 8305 + out->args.ia_destroy.action_id_n++; 8306 if ((uint8_t *)action_id > (uint8_t *)out + size) 8307 return -1; 8308 ctx->objdata = 0; 8309 ctx->object = action_id; 8310 ctx->objmask = NULL; 8311 return len; 8312 } 8313 8314 /** Parse tokens for indirect action commands. */ 8315 static int 8316 parse_qia(struct context *ctx, const struct token *token, 8317 const char *str, unsigned int len, 8318 void *buf, unsigned int size) 8319 { 8320 struct buffer *out = buf; 8321 8322 /* Token name must match. */ 8323 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8324 return -1; 8325 /* Nothing else to do if there is no buffer. */ 8326 if (!out) 8327 return len; 8328 if (!out->command) { 8329 if (ctx->curr != QUEUE) 8330 return -1; 8331 if (sizeof(*out) > size) 8332 return -1; 8333 out->args.vc.data = (uint8_t *)out + size; 8334 return len; 8335 } 8336 switch (ctx->curr) { 8337 case QUEUE_INDIRECT_ACTION: 8338 return len; 8339 case QUEUE_INDIRECT_ACTION_CREATE: 8340 case QUEUE_INDIRECT_ACTION_UPDATE: 8341 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 8342 out->args.vc.actions = 8343 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8344 sizeof(double)); 8345 out->args.vc.attr.group = UINT32_MAX; 8346 /* fallthrough */ 8347 case QUEUE_INDIRECT_ACTION_QUERY: 8348 out->command = ctx->curr; 8349 ctx->objdata = 0; 8350 ctx->object = out; 8351 ctx->objmask = NULL; 8352 return len; 8353 case QUEUE_INDIRECT_ACTION_EGRESS: 8354 out->args.vc.attr.egress = 1; 8355 return len; 8356 case QUEUE_INDIRECT_ACTION_INGRESS: 8357 out->args.vc.attr.ingress = 1; 8358 return len; 8359 case QUEUE_INDIRECT_ACTION_TRANSFER: 8360 out->args.vc.attr.transfer = 1; 8361 return len; 8362 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 8363 return len; 8364 case QUEUE_INDIRECT_ACTION_QU_MODE: 8365 return len; 8366 case QUEUE_INDIRECT_ACTION_LIST: 8367 out->command = QUEUE_INDIRECT_ACTION_LIST_CREATE; 8368 return len; 8369 default: 8370 return -1; 8371 } 8372 } 8373 8374 /** Parse tokens for indirect action destroy command. */ 8375 static int 8376 parse_qia_destroy(struct context *ctx, const struct token *token, 8377 const char *str, unsigned int len, 8378 void *buf, unsigned int size) 8379 { 8380 struct buffer *out = buf; 8381 uint32_t *action_id; 8382 8383 /* Token name must match. */ 8384 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8385 return -1; 8386 /* Nothing else to do if there is no buffer. */ 8387 if (!out) 8388 return len; 8389 if (!out->command || out->command == QUEUE) { 8390 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 8391 return -1; 8392 if (sizeof(*out) > size) 8393 return -1; 8394 out->command = ctx->curr; 8395 ctx->objdata = 0; 8396 ctx->object = out; 8397 ctx->objmask = NULL; 8398 out->args.ia_destroy.action_id = 8399 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8400 sizeof(double)); 8401 return len; 8402 } 8403 switch (ctx->curr) { 8404 case QUEUE_INDIRECT_ACTION: 8405 out->command = ctx->curr; 8406 ctx->objdata = 0; 8407 ctx->object = out; 8408 ctx->objmask = NULL; 8409 return len; 8410 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 8411 action_id = out->args.ia_destroy.action_id 8412 + out->args.ia_destroy.action_id_n++; 8413 if ((uint8_t *)action_id > (uint8_t *)out + size) 8414 return -1; 8415 ctx->objdata = 0; 8416 ctx->object = action_id; 8417 ctx->objmask = NULL; 8418 return len; 8419 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 8420 return len; 8421 default: 8422 return -1; 8423 } 8424 } 8425 8426 /** Parse tokens for meter policy action commands. */ 8427 static int 8428 parse_mp(struct context *ctx, const struct token *token, 8429 const char *str, unsigned int len, 8430 void *buf, unsigned int size) 8431 { 8432 struct buffer *out = buf; 8433 8434 /* Token name must match. */ 8435 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8436 return -1; 8437 /* Nothing else to do if there is no buffer. */ 8438 if (!out) 8439 return len; 8440 if (!out->command) { 8441 if (ctx->curr != ITEM_POL_POLICY) 8442 return -1; 8443 if (sizeof(*out) > size) 8444 return -1; 8445 out->command = ctx->curr; 8446 ctx->objdata = 0; 8447 ctx->object = out; 8448 ctx->objmask = NULL; 8449 out->args.vc.data = (uint8_t *)out + size; 8450 return len; 8451 } 8452 switch (ctx->curr) { 8453 case ACTION_POL_G: 8454 out->args.vc.actions = 8455 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8456 sizeof(double)); 8457 out->command = ctx->curr; 8458 ctx->objdata = 0; 8459 ctx->object = out; 8460 ctx->objmask = NULL; 8461 return len; 8462 default: 8463 return -1; 8464 } 8465 } 8466 8467 /** Parse tokens for validate/create commands. */ 8468 static int 8469 parse_vc(struct context *ctx, const struct token *token, 8470 const char *str, unsigned int len, 8471 void *buf, unsigned int size) 8472 { 8473 struct buffer *out = buf; 8474 uint8_t *data; 8475 uint32_t data_size; 8476 8477 /* Token name must match. */ 8478 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8479 return -1; 8480 /* Nothing else to do if there is no buffer. */ 8481 if (!out) 8482 return len; 8483 if (!out->command) { 8484 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 8485 ctx->curr != PATTERN_TEMPLATE_CREATE && 8486 ctx->curr != ACTIONS_TEMPLATE_CREATE) 8487 return -1; 8488 if (sizeof(*out) > size) 8489 return -1; 8490 out->command = ctx->curr; 8491 ctx->objdata = 0; 8492 ctx->object = out; 8493 ctx->objmask = NULL; 8494 out->args.vc.data = (uint8_t *)out + size; 8495 return len; 8496 } 8497 ctx->objdata = 0; 8498 switch (ctx->curr) { 8499 default: 8500 ctx->object = &out->args.vc.attr; 8501 break; 8502 case VC_TUNNEL_SET: 8503 case VC_TUNNEL_MATCH: 8504 ctx->object = &out->args.vc.tunnel_ops; 8505 break; 8506 case VC_USER_ID: 8507 ctx->object = out; 8508 break; 8509 } 8510 ctx->objmask = NULL; 8511 switch (ctx->curr) { 8512 case VC_GROUP: 8513 case VC_PRIORITY: 8514 case VC_USER_ID: 8515 return len; 8516 case VC_TUNNEL_SET: 8517 out->args.vc.tunnel_ops.enabled = 1; 8518 out->args.vc.tunnel_ops.actions = 1; 8519 return len; 8520 case VC_TUNNEL_MATCH: 8521 out->args.vc.tunnel_ops.enabled = 1; 8522 out->args.vc.tunnel_ops.items = 1; 8523 return len; 8524 case VC_INGRESS: 8525 out->args.vc.attr.ingress = 1; 8526 return len; 8527 case VC_EGRESS: 8528 out->args.vc.attr.egress = 1; 8529 return len; 8530 case VC_TRANSFER: 8531 out->args.vc.attr.transfer = 1; 8532 return len; 8533 case ITEM_PATTERN: 8534 out->args.vc.pattern = 8535 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8536 sizeof(double)); 8537 ctx->object = out->args.vc.pattern; 8538 ctx->objmask = NULL; 8539 return len; 8540 case ITEM_END: 8541 if ((out->command == VALIDATE || out->command == CREATE) && 8542 ctx->last) 8543 return -1; 8544 if (out->command == PATTERN_TEMPLATE_CREATE && 8545 !ctx->last) 8546 return -1; 8547 break; 8548 case ACTIONS: 8549 out->args.vc.actions = out->args.vc.pattern ? 8550 (void *)RTE_ALIGN_CEIL((uintptr_t) 8551 (out->args.vc.pattern + 8552 out->args.vc.pattern_n), 8553 sizeof(double)) : 8554 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8555 sizeof(double)); 8556 ctx->object = out->args.vc.actions; 8557 ctx->objmask = NULL; 8558 return len; 8559 default: 8560 if (!token->priv) 8561 return -1; 8562 break; 8563 } 8564 if (!out->args.vc.actions) { 8565 const struct parse_item_priv *priv = token->priv; 8566 struct rte_flow_item *item = 8567 out->args.vc.pattern + out->args.vc.pattern_n; 8568 8569 data_size = priv->size * 3; /* spec, last, mask */ 8570 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8571 (out->args.vc.data - data_size), 8572 sizeof(double)); 8573 if ((uint8_t *)item + sizeof(*item) > data) 8574 return -1; 8575 *item = (struct rte_flow_item){ 8576 .type = priv->type, 8577 }; 8578 ++out->args.vc.pattern_n; 8579 ctx->object = item; 8580 ctx->objmask = NULL; 8581 } else { 8582 const struct parse_action_priv *priv = token->priv; 8583 struct rte_flow_action *action = 8584 out->args.vc.actions + out->args.vc.actions_n; 8585 8586 data_size = priv->size; /* configuration */ 8587 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8588 (out->args.vc.data - data_size), 8589 sizeof(double)); 8590 if ((uint8_t *)action + sizeof(*action) > data) 8591 return -1; 8592 *action = (struct rte_flow_action){ 8593 .type = priv->type, 8594 .conf = data_size ? data : NULL, 8595 }; 8596 ++out->args.vc.actions_n; 8597 ctx->object = action; 8598 ctx->objmask = NULL; 8599 } 8600 memset(data, 0, data_size); 8601 out->args.vc.data = data; 8602 ctx->objdata = data_size; 8603 return len; 8604 } 8605 8606 /** Parse pattern item parameter type. */ 8607 static int 8608 parse_vc_spec(struct context *ctx, const struct token *token, 8609 const char *str, unsigned int len, 8610 void *buf, unsigned int size) 8611 { 8612 struct buffer *out = buf; 8613 struct rte_flow_item *item; 8614 uint32_t data_size; 8615 int index; 8616 int objmask = 0; 8617 8618 (void)size; 8619 /* Token name must match. */ 8620 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8621 return -1; 8622 /* Parse parameter types. */ 8623 switch (ctx->curr) { 8624 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 8625 8626 case ITEM_PARAM_IS: 8627 index = 0; 8628 objmask = 1; 8629 break; 8630 case ITEM_PARAM_SPEC: 8631 index = 0; 8632 break; 8633 case ITEM_PARAM_LAST: 8634 index = 1; 8635 break; 8636 case ITEM_PARAM_PREFIX: 8637 /* Modify next token to expect a prefix. */ 8638 if (ctx->next_num < 2) 8639 return -1; 8640 ctx->next[ctx->next_num - 2] = prefix; 8641 /* Fall through. */ 8642 case ITEM_PARAM_MASK: 8643 index = 2; 8644 break; 8645 default: 8646 return -1; 8647 } 8648 /* Nothing else to do if there is no buffer. */ 8649 if (!out) 8650 return len; 8651 if (!out->args.vc.pattern_n) 8652 return -1; 8653 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8654 data_size = ctx->objdata / 3; /* spec, last, mask */ 8655 /* Point to selected object. */ 8656 ctx->object = out->args.vc.data + (data_size * index); 8657 if (objmask) { 8658 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 8659 item->mask = ctx->objmask; 8660 } else 8661 ctx->objmask = NULL; 8662 /* Update relevant item pointer. */ 8663 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 8664 ctx->object; 8665 return len; 8666 } 8667 8668 /** Parse action configuration field. */ 8669 static int 8670 parse_vc_conf(struct context *ctx, const struct token *token, 8671 const char *str, unsigned int len, 8672 void *buf, unsigned int size) 8673 { 8674 struct buffer *out = buf; 8675 8676 (void)size; 8677 /* Token name must match. */ 8678 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8679 return -1; 8680 /* Nothing else to do if there is no buffer. */ 8681 if (!out) 8682 return len; 8683 /* Point to selected object. */ 8684 ctx->object = out->args.vc.data; 8685 ctx->objmask = NULL; 8686 return len; 8687 } 8688 8689 /** Parse action configuration field. */ 8690 static int 8691 parse_vc_conf_timeout(struct context *ctx, const struct token *token, 8692 const char *str, unsigned int len, 8693 void *buf, unsigned int size) 8694 { 8695 struct buffer *out = buf; 8696 struct rte_flow_update_age *update; 8697 8698 (void)size; 8699 if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) 8700 return -1; 8701 /* Token name must match. */ 8702 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8703 return -1; 8704 /* Nothing else to do if there is no buffer. */ 8705 if (!out) 8706 return len; 8707 /* Point to selected object. */ 8708 ctx->object = out->args.vc.data; 8709 ctx->objmask = NULL; 8710 /* Update the timeout is valid. */ 8711 update = (struct rte_flow_update_age *)out->args.vc.data; 8712 update->timeout_valid = 1; 8713 return len; 8714 } 8715 8716 /** Parse eCPRI common header type field. */ 8717 static int 8718 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 8719 const char *str, unsigned int len, 8720 void *buf, unsigned int size) 8721 { 8722 struct rte_flow_item_ecpri *ecpri; 8723 struct rte_flow_item_ecpri *ecpri_mask; 8724 struct rte_flow_item *item; 8725 uint32_t data_size; 8726 uint8_t msg_type; 8727 struct buffer *out = buf; 8728 const struct arg *arg; 8729 8730 (void)size; 8731 /* Token name must match. */ 8732 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8733 return -1; 8734 switch (ctx->curr) { 8735 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 8736 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 8737 break; 8738 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 8739 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 8740 break; 8741 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 8742 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 8743 break; 8744 default: 8745 return -1; 8746 } 8747 if (!ctx->object) 8748 return len; 8749 arg = pop_args(ctx); 8750 if (!arg) 8751 return -1; 8752 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 8753 ecpri->hdr.common.type = msg_type; 8754 data_size = ctx->objdata / 3; /* spec, last, mask */ 8755 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 8756 (data_size * 2)); 8757 ecpri_mask->hdr.common.type = 0xFF; 8758 if (arg->hton) { 8759 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 8760 ecpri_mask->hdr.common.u32 = 8761 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 8762 } 8763 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8764 item->spec = ecpri; 8765 item->mask = ecpri_mask; 8766 return len; 8767 } 8768 8769 /** Parse L2TPv2 common header type field. */ 8770 static int 8771 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, 8772 const char *str, unsigned int len, 8773 void *buf, unsigned int size) 8774 { 8775 struct rte_flow_item_l2tpv2 *l2tpv2; 8776 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 8777 struct rte_flow_item *item; 8778 uint32_t data_size; 8779 uint16_t msg_type = 0; 8780 struct buffer *out = buf; 8781 const struct arg *arg; 8782 8783 (void)size; 8784 /* Token name must match. */ 8785 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8786 return -1; 8787 switch (ctx->curr) { 8788 case ITEM_L2TPV2_TYPE_DATA: 8789 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 8790 break; 8791 case ITEM_L2TPV2_TYPE_DATA_L: 8792 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 8793 break; 8794 case ITEM_L2TPV2_TYPE_DATA_S: 8795 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 8796 break; 8797 case ITEM_L2TPV2_TYPE_DATA_O: 8798 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 8799 break; 8800 case ITEM_L2TPV2_TYPE_DATA_L_S: 8801 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 8802 break; 8803 case ITEM_L2TPV2_TYPE_CTRL: 8804 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 8805 break; 8806 default: 8807 return -1; 8808 } 8809 if (!ctx->object) 8810 return len; 8811 arg = pop_args(ctx); 8812 if (!arg) 8813 return -1; 8814 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 8815 l2tpv2->hdr.common.flags_version |= msg_type; 8816 data_size = ctx->objdata / 3; /* spec, last, mask */ 8817 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 8818 (data_size * 2)); 8819 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 8820 if (arg->hton) { 8821 l2tpv2->hdr.common.flags_version = 8822 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 8823 l2tpv2_mask->hdr.common.flags_version = 8824 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 8825 } 8826 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8827 item->spec = l2tpv2; 8828 item->mask = l2tpv2_mask; 8829 return len; 8830 } 8831 8832 /** Parse operation for compare match item. */ 8833 static int 8834 parse_vc_compare_op(struct context *ctx, const struct token *token, 8835 const char *str, unsigned int len, void *buf, 8836 unsigned int size) 8837 { 8838 struct rte_flow_item_compare *compare_item; 8839 unsigned int i; 8840 8841 (void)token; 8842 (void)buf; 8843 (void)size; 8844 if (ctx->curr != ITEM_COMPARE_OP_VALUE) 8845 return -1; 8846 for (i = 0; compare_ops[i]; ++i) 8847 if (!strcmp_partial(compare_ops[i], str, len)) 8848 break; 8849 if (!compare_ops[i]) 8850 return -1; 8851 if (!ctx->object) 8852 return len; 8853 compare_item = ctx->object; 8854 compare_item->operation = (enum rte_flow_item_compare_op)i; 8855 return len; 8856 } 8857 8858 /** Parse id for compare match item. */ 8859 static int 8860 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 8861 const char *str, unsigned int len, void *buf, 8862 unsigned int size) 8863 { 8864 struct rte_flow_item_compare *compare_item; 8865 unsigned int i; 8866 8867 (void)token; 8868 (void)buf; 8869 (void)size; 8870 if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE && 8871 ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE) 8872 return -1; 8873 for (i = 0; flow_field_ids[i]; ++i) 8874 if (!strcmp_partial(flow_field_ids[i], str, len)) 8875 break; 8876 if (!flow_field_ids[i]) 8877 return -1; 8878 if (!ctx->object) 8879 return len; 8880 compare_item = ctx->object; 8881 if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE) 8882 compare_item->a.field = (enum rte_flow_field_id)i; 8883 else 8884 compare_item->b.field = (enum rte_flow_field_id)i; 8885 return len; 8886 } 8887 8888 /** Parse level for compare match item. */ 8889 static int 8890 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 8891 const char *str, unsigned int len, void *buf, 8892 unsigned int size) 8893 { 8894 struct rte_flow_item_compare *compare_item; 8895 struct flex_item *fp = NULL; 8896 uint32_t val; 8897 struct buffer *out = buf; 8898 char *end; 8899 8900 (void)token; 8901 (void)size; 8902 if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 8903 ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE) 8904 return -1; 8905 if (!ctx->object) 8906 return len; 8907 compare_item = ctx->object; 8908 errno = 0; 8909 val = strtoumax(str, &end, 0); 8910 if (errno || (size_t)(end - str) != len) 8911 return -1; 8912 /* No need to validate action template mask value */ 8913 if (out->args.vc.masks) { 8914 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) 8915 compare_item->a.level = val; 8916 else 8917 compare_item->b.level = val; 8918 return len; 8919 } 8920 if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 8921 compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) || 8922 (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE && 8923 compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 8924 if (val >= FLEX_MAX_PARSERS_NUM) { 8925 printf("Bad flex item handle\n"); 8926 return -1; 8927 } 8928 fp = flex_items[ctx->port][val]; 8929 if (!fp) { 8930 printf("Bad flex item handle\n"); 8931 return -1; 8932 } 8933 } 8934 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) { 8935 if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM) 8936 compare_item->a.level = val; 8937 else 8938 compare_item->a.flex_handle = fp->flex_handle; 8939 } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) { 8940 if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM) 8941 compare_item->b.level = val; 8942 else 8943 compare_item->b.flex_handle = fp->flex_handle; 8944 } 8945 return len; 8946 } 8947 8948 /** Parse meter color action type. */ 8949 static int 8950 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 8951 const char *str, unsigned int len, 8952 void *buf, unsigned int size) 8953 { 8954 struct rte_flow_action *action_data; 8955 struct rte_flow_action_meter_color *conf; 8956 enum rte_color color; 8957 8958 (void)buf; 8959 (void)size; 8960 /* Token name must match. */ 8961 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8962 return -1; 8963 switch (ctx->curr) { 8964 case ACTION_METER_COLOR_GREEN: 8965 color = RTE_COLOR_GREEN; 8966 break; 8967 case ACTION_METER_COLOR_YELLOW: 8968 color = RTE_COLOR_YELLOW; 8969 break; 8970 case ACTION_METER_COLOR_RED: 8971 color = RTE_COLOR_RED; 8972 break; 8973 default: 8974 return -1; 8975 } 8976 8977 if (!ctx->object) 8978 return len; 8979 action_data = ctx->object; 8980 conf = (struct rte_flow_action_meter_color *) 8981 (uintptr_t)(action_data->conf); 8982 conf->color = color; 8983 return len; 8984 } 8985 8986 /** Parse RSS action. */ 8987 static int 8988 parse_vc_action_rss(struct context *ctx, const struct token *token, 8989 const char *str, unsigned int len, 8990 void *buf, unsigned int size) 8991 { 8992 struct buffer *out = buf; 8993 struct rte_flow_action *action; 8994 struct action_rss_data *action_rss_data; 8995 unsigned int i; 8996 int ret; 8997 8998 ret = parse_vc(ctx, token, str, len, buf, size); 8999 if (ret < 0) 9000 return ret; 9001 /* Nothing else to do if there is no buffer. */ 9002 if (!out) 9003 return ret; 9004 if (!out->args.vc.actions_n) 9005 return -1; 9006 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9007 /* Point to selected object. */ 9008 ctx->object = out->args.vc.data; 9009 ctx->objmask = NULL; 9010 /* Set up default configuration. */ 9011 action_rss_data = ctx->object; 9012 *action_rss_data = (struct action_rss_data){ 9013 .conf = (struct rte_flow_action_rss){ 9014 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 9015 .level = 0, 9016 .types = rss_hf, 9017 .key_len = 0, 9018 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 9019 .key = NULL, 9020 .queue = action_rss_data->queue, 9021 }, 9022 .queue = { 0 }, 9023 }; 9024 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 9025 action_rss_data->queue[i] = i; 9026 action->conf = &action_rss_data->conf; 9027 return ret; 9028 } 9029 9030 /** 9031 * Parse func field for RSS action. 9032 * 9033 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 9034 * ACTION_RSS_FUNC_* index that called this function. 9035 */ 9036 static int 9037 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 9038 const char *str, unsigned int len, 9039 void *buf, unsigned int size) 9040 { 9041 struct action_rss_data *action_rss_data; 9042 enum rte_eth_hash_function func; 9043 9044 (void)buf; 9045 (void)size; 9046 /* Token name must match. */ 9047 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9048 return -1; 9049 switch (ctx->curr) { 9050 case ACTION_RSS_FUNC_DEFAULT: 9051 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 9052 break; 9053 case ACTION_RSS_FUNC_TOEPLITZ: 9054 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 9055 break; 9056 case ACTION_RSS_FUNC_SIMPLE_XOR: 9057 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 9058 break; 9059 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 9060 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 9061 break; 9062 default: 9063 return -1; 9064 } 9065 if (!ctx->object) 9066 return len; 9067 action_rss_data = ctx->object; 9068 action_rss_data->conf.func = func; 9069 return len; 9070 } 9071 9072 /** 9073 * Parse type field for RSS action. 9074 * 9075 * Valid tokens are type field names and the "end" token. 9076 */ 9077 static int 9078 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 9079 const char *str, unsigned int len, 9080 void *buf, unsigned int size) 9081 { 9082 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 9083 struct action_rss_data *action_rss_data; 9084 unsigned int i; 9085 9086 (void)token; 9087 (void)buf; 9088 (void)size; 9089 if (ctx->curr != ACTION_RSS_TYPE) 9090 return -1; 9091 if (!(ctx->objdata >> 16) && ctx->object) { 9092 action_rss_data = ctx->object; 9093 action_rss_data->conf.types = 0; 9094 } 9095 if (!strcmp_partial("end", str, len)) { 9096 ctx->objdata &= 0xffff; 9097 return len; 9098 } 9099 for (i = 0; rss_type_table[i].str; ++i) 9100 if (!strcmp_partial(rss_type_table[i].str, str, len)) 9101 break; 9102 if (!rss_type_table[i].str) 9103 return -1; 9104 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 9105 /* Repeat token. */ 9106 if (ctx->next_num == RTE_DIM(ctx->next)) 9107 return -1; 9108 ctx->next[ctx->next_num++] = next; 9109 if (!ctx->object) 9110 return len; 9111 action_rss_data = ctx->object; 9112 action_rss_data->conf.types |= rss_type_table[i].rss_type; 9113 return len; 9114 } 9115 9116 /** 9117 * Parse queue field for RSS action. 9118 * 9119 * Valid tokens are queue indices and the "end" token. 9120 */ 9121 static int 9122 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 9123 const char *str, unsigned int len, 9124 void *buf, unsigned int size) 9125 { 9126 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 9127 struct action_rss_data *action_rss_data; 9128 const struct arg *arg; 9129 int ret; 9130 int i; 9131 9132 (void)token; 9133 (void)buf; 9134 (void)size; 9135 if (ctx->curr != ACTION_RSS_QUEUE) 9136 return -1; 9137 i = ctx->objdata >> 16; 9138 if (!strcmp_partial("end", str, len)) { 9139 ctx->objdata &= 0xffff; 9140 goto end; 9141 } 9142 if (i >= ACTION_RSS_QUEUE_NUM) 9143 return -1; 9144 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 9145 i * sizeof(action_rss_data->queue[i]), 9146 sizeof(action_rss_data->queue[i])); 9147 if (push_args(ctx, arg)) 9148 return -1; 9149 ret = parse_int(ctx, token, str, len, NULL, 0); 9150 if (ret < 0) { 9151 pop_args(ctx); 9152 return -1; 9153 } 9154 ++i; 9155 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 9156 /* Repeat token. */ 9157 if (ctx->next_num == RTE_DIM(ctx->next)) 9158 return -1; 9159 ctx->next[ctx->next_num++] = next; 9160 end: 9161 if (!ctx->object) 9162 return len; 9163 action_rss_data = ctx->object; 9164 action_rss_data->conf.queue_num = i; 9165 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 9166 return len; 9167 } 9168 9169 /** Setup VXLAN encap configuration. */ 9170 static int 9171 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 9172 { 9173 /* Set up default configuration. */ 9174 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 9175 .conf = (struct rte_flow_action_vxlan_encap){ 9176 .definition = action_vxlan_encap_data->items, 9177 }, 9178 .items = { 9179 { 9180 .type = RTE_FLOW_ITEM_TYPE_ETH, 9181 .spec = &action_vxlan_encap_data->item_eth, 9182 .mask = &rte_flow_item_eth_mask, 9183 }, 9184 { 9185 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9186 .spec = &action_vxlan_encap_data->item_vlan, 9187 .mask = &rte_flow_item_vlan_mask, 9188 }, 9189 { 9190 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9191 .spec = &action_vxlan_encap_data->item_ipv4, 9192 .mask = &rte_flow_item_ipv4_mask, 9193 }, 9194 { 9195 .type = RTE_FLOW_ITEM_TYPE_UDP, 9196 .spec = &action_vxlan_encap_data->item_udp, 9197 .mask = &rte_flow_item_udp_mask, 9198 }, 9199 { 9200 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 9201 .spec = &action_vxlan_encap_data->item_vxlan, 9202 .mask = &rte_flow_item_vxlan_mask, 9203 }, 9204 { 9205 .type = RTE_FLOW_ITEM_TYPE_END, 9206 }, 9207 }, 9208 .item_eth.hdr.ether_type = 0, 9209 .item_vlan = { 9210 .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, 9211 .hdr.eth_proto = 0, 9212 }, 9213 .item_ipv4.hdr = { 9214 .src_addr = vxlan_encap_conf.ipv4_src, 9215 .dst_addr = vxlan_encap_conf.ipv4_dst, 9216 }, 9217 .item_udp.hdr = { 9218 .src_port = vxlan_encap_conf.udp_src, 9219 .dst_port = vxlan_encap_conf.udp_dst, 9220 }, 9221 .item_vxlan.hdr.flags = 0, 9222 }; 9223 memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9224 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9225 memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, 9226 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9227 if (!vxlan_encap_conf.select_ipv4) { 9228 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 9229 &vxlan_encap_conf.ipv6_src, 9230 sizeof(vxlan_encap_conf.ipv6_src)); 9231 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 9232 &vxlan_encap_conf.ipv6_dst, 9233 sizeof(vxlan_encap_conf.ipv6_dst)); 9234 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 9235 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9236 .spec = &action_vxlan_encap_data->item_ipv6, 9237 .mask = &rte_flow_item_ipv6_mask, 9238 }; 9239 } 9240 if (!vxlan_encap_conf.select_vlan) 9241 action_vxlan_encap_data->items[1].type = 9242 RTE_FLOW_ITEM_TYPE_VOID; 9243 if (vxlan_encap_conf.select_tos_ttl) { 9244 if (vxlan_encap_conf.select_ipv4) { 9245 static struct rte_flow_item_ipv4 ipv4_mask_tos; 9246 9247 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 9248 sizeof(ipv4_mask_tos)); 9249 ipv4_mask_tos.hdr.type_of_service = 0xff; 9250 ipv4_mask_tos.hdr.time_to_live = 0xff; 9251 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 9252 vxlan_encap_conf.ip_tos; 9253 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 9254 vxlan_encap_conf.ip_ttl; 9255 action_vxlan_encap_data->items[2].mask = 9256 &ipv4_mask_tos; 9257 } else { 9258 static struct rte_flow_item_ipv6 ipv6_mask_tos; 9259 9260 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 9261 sizeof(ipv6_mask_tos)); 9262 ipv6_mask_tos.hdr.vtc_flow |= 9263 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 9264 ipv6_mask_tos.hdr.hop_limits = 0xff; 9265 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 9266 rte_cpu_to_be_32 9267 ((uint32_t)vxlan_encap_conf.ip_tos << 9268 RTE_IPV6_HDR_TC_SHIFT); 9269 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 9270 vxlan_encap_conf.ip_ttl; 9271 action_vxlan_encap_data->items[2].mask = 9272 &ipv6_mask_tos; 9273 } 9274 } 9275 memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, 9276 RTE_DIM(vxlan_encap_conf.vni)); 9277 return 0; 9278 } 9279 9280 /** Parse VXLAN encap action. */ 9281 static int 9282 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 9283 const char *str, unsigned int len, 9284 void *buf, unsigned int size) 9285 { 9286 struct buffer *out = buf; 9287 struct rte_flow_action *action; 9288 struct action_vxlan_encap_data *action_vxlan_encap_data; 9289 int ret; 9290 9291 ret = parse_vc(ctx, token, str, len, buf, size); 9292 if (ret < 0) 9293 return ret; 9294 /* Nothing else to do if there is no buffer. */ 9295 if (!out) 9296 return ret; 9297 if (!out->args.vc.actions_n) 9298 return -1; 9299 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9300 /* Point to selected object. */ 9301 ctx->object = out->args.vc.data; 9302 ctx->objmask = NULL; 9303 action_vxlan_encap_data = ctx->object; 9304 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 9305 action->conf = &action_vxlan_encap_data->conf; 9306 return ret; 9307 } 9308 9309 /** Setup NVGRE encap configuration. */ 9310 static int 9311 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 9312 { 9313 /* Set up default configuration. */ 9314 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 9315 .conf = (struct rte_flow_action_nvgre_encap){ 9316 .definition = action_nvgre_encap_data->items, 9317 }, 9318 .items = { 9319 { 9320 .type = RTE_FLOW_ITEM_TYPE_ETH, 9321 .spec = &action_nvgre_encap_data->item_eth, 9322 .mask = &rte_flow_item_eth_mask, 9323 }, 9324 { 9325 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9326 .spec = &action_nvgre_encap_data->item_vlan, 9327 .mask = &rte_flow_item_vlan_mask, 9328 }, 9329 { 9330 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9331 .spec = &action_nvgre_encap_data->item_ipv4, 9332 .mask = &rte_flow_item_ipv4_mask, 9333 }, 9334 { 9335 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 9336 .spec = &action_nvgre_encap_data->item_nvgre, 9337 .mask = &rte_flow_item_nvgre_mask, 9338 }, 9339 { 9340 .type = RTE_FLOW_ITEM_TYPE_END, 9341 }, 9342 }, 9343 .item_eth.hdr.ether_type = 0, 9344 .item_vlan = { 9345 .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, 9346 .hdr.eth_proto = 0, 9347 }, 9348 .item_ipv4.hdr = { 9349 .src_addr = nvgre_encap_conf.ipv4_src, 9350 .dst_addr = nvgre_encap_conf.ipv4_dst, 9351 }, 9352 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 9353 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 9354 .item_nvgre.flow_id = 0, 9355 }; 9356 memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9357 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9358 memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, 9359 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9360 if (!nvgre_encap_conf.select_ipv4) { 9361 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 9362 &nvgre_encap_conf.ipv6_src, 9363 sizeof(nvgre_encap_conf.ipv6_src)); 9364 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 9365 &nvgre_encap_conf.ipv6_dst, 9366 sizeof(nvgre_encap_conf.ipv6_dst)); 9367 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 9368 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9369 .spec = &action_nvgre_encap_data->item_ipv6, 9370 .mask = &rte_flow_item_ipv6_mask, 9371 }; 9372 } 9373 if (!nvgre_encap_conf.select_vlan) 9374 action_nvgre_encap_data->items[1].type = 9375 RTE_FLOW_ITEM_TYPE_VOID; 9376 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 9377 RTE_DIM(nvgre_encap_conf.tni)); 9378 return 0; 9379 } 9380 9381 /** Parse NVGRE encap action. */ 9382 static int 9383 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 9384 const char *str, unsigned int len, 9385 void *buf, unsigned int size) 9386 { 9387 struct buffer *out = buf; 9388 struct rte_flow_action *action; 9389 struct action_nvgre_encap_data *action_nvgre_encap_data; 9390 int ret; 9391 9392 ret = parse_vc(ctx, token, str, len, buf, size); 9393 if (ret < 0) 9394 return ret; 9395 /* Nothing else to do if there is no buffer. */ 9396 if (!out) 9397 return ret; 9398 if (!out->args.vc.actions_n) 9399 return -1; 9400 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9401 /* Point to selected object. */ 9402 ctx->object = out->args.vc.data; 9403 ctx->objmask = NULL; 9404 action_nvgre_encap_data = ctx->object; 9405 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 9406 action->conf = &action_nvgre_encap_data->conf; 9407 return ret; 9408 } 9409 9410 /** Parse l2 encap action. */ 9411 static int 9412 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 9413 const char *str, unsigned int len, 9414 void *buf, unsigned int size) 9415 { 9416 struct buffer *out = buf; 9417 struct rte_flow_action *action; 9418 struct action_raw_encap_data *action_encap_data; 9419 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9420 struct rte_flow_item_vlan vlan = { 9421 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9422 .hdr.eth_proto = 0, 9423 }; 9424 uint8_t *header; 9425 int ret; 9426 9427 ret = parse_vc(ctx, token, str, len, buf, size); 9428 if (ret < 0) 9429 return ret; 9430 /* Nothing else to do if there is no buffer. */ 9431 if (!out) 9432 return ret; 9433 if (!out->args.vc.actions_n) 9434 return -1; 9435 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9436 /* Point to selected object. */ 9437 ctx->object = out->args.vc.data; 9438 ctx->objmask = NULL; 9439 /* Copy the headers to the buffer. */ 9440 action_encap_data = ctx->object; 9441 *action_encap_data = (struct action_raw_encap_data) { 9442 .conf = (struct rte_flow_action_raw_encap){ 9443 .data = action_encap_data->data, 9444 }, 9445 .data = {}, 9446 }; 9447 header = action_encap_data->data; 9448 if (l2_encap_conf.select_vlan) 9449 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9450 else if (l2_encap_conf.select_ipv4) 9451 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9452 else 9453 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9454 memcpy(eth.hdr.dst_addr.addr_bytes, 9455 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9456 memcpy(eth.hdr.src_addr.addr_bytes, 9457 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9458 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9459 header += sizeof(struct rte_ether_hdr); 9460 if (l2_encap_conf.select_vlan) { 9461 if (l2_encap_conf.select_ipv4) 9462 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9463 else 9464 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9465 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9466 header += sizeof(struct rte_vlan_hdr); 9467 } 9468 action_encap_data->conf.size = header - 9469 action_encap_data->data; 9470 action->conf = &action_encap_data->conf; 9471 return ret; 9472 } 9473 9474 /** Parse l2 decap action. */ 9475 static int 9476 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 9477 const char *str, unsigned int len, 9478 void *buf, unsigned int size) 9479 { 9480 struct buffer *out = buf; 9481 struct rte_flow_action *action; 9482 struct action_raw_decap_data *action_decap_data; 9483 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9484 struct rte_flow_item_vlan vlan = { 9485 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9486 .hdr.eth_proto = 0, 9487 }; 9488 uint8_t *header; 9489 int ret; 9490 9491 ret = parse_vc(ctx, token, str, len, buf, size); 9492 if (ret < 0) 9493 return ret; 9494 /* Nothing else to do if there is no buffer. */ 9495 if (!out) 9496 return ret; 9497 if (!out->args.vc.actions_n) 9498 return -1; 9499 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9500 /* Point to selected object. */ 9501 ctx->object = out->args.vc.data; 9502 ctx->objmask = NULL; 9503 /* Copy the headers to the buffer. */ 9504 action_decap_data = ctx->object; 9505 *action_decap_data = (struct action_raw_decap_data) { 9506 .conf = (struct rte_flow_action_raw_decap){ 9507 .data = action_decap_data->data, 9508 }, 9509 .data = {}, 9510 }; 9511 header = action_decap_data->data; 9512 if (l2_decap_conf.select_vlan) 9513 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9514 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9515 header += sizeof(struct rte_ether_hdr); 9516 if (l2_decap_conf.select_vlan) { 9517 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9518 header += sizeof(struct rte_vlan_hdr); 9519 } 9520 action_decap_data->conf.size = header - 9521 action_decap_data->data; 9522 action->conf = &action_decap_data->conf; 9523 return ret; 9524 } 9525 9526 #define ETHER_TYPE_MPLS_UNICAST 0x8847 9527 9528 /** Parse MPLSOGRE encap action. */ 9529 static int 9530 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 9531 const char *str, unsigned int len, 9532 void *buf, unsigned int size) 9533 { 9534 struct buffer *out = buf; 9535 struct rte_flow_action *action; 9536 struct action_raw_encap_data *action_encap_data; 9537 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9538 struct rte_flow_item_vlan vlan = { 9539 .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, 9540 .hdr.eth_proto = 0, 9541 }; 9542 struct rte_flow_item_ipv4 ipv4 = { 9543 .hdr = { 9544 .src_addr = mplsogre_encap_conf.ipv4_src, 9545 .dst_addr = mplsogre_encap_conf.ipv4_dst, 9546 .next_proto_id = IPPROTO_GRE, 9547 .version_ihl = RTE_IPV4_VHL_DEF, 9548 .time_to_live = IPDEFTTL, 9549 }, 9550 }; 9551 struct rte_flow_item_ipv6 ipv6 = { 9552 .hdr = { 9553 .proto = IPPROTO_GRE, 9554 .hop_limits = IPDEFTTL, 9555 }, 9556 }; 9557 struct rte_flow_item_gre gre = { 9558 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9559 }; 9560 struct rte_flow_item_mpls mpls = { 9561 .ttl = 0, 9562 }; 9563 uint8_t *header; 9564 int ret; 9565 9566 ret = parse_vc(ctx, token, str, len, buf, size); 9567 if (ret < 0) 9568 return ret; 9569 /* Nothing else to do if there is no buffer. */ 9570 if (!out) 9571 return ret; 9572 if (!out->args.vc.actions_n) 9573 return -1; 9574 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9575 /* Point to selected object. */ 9576 ctx->object = out->args.vc.data; 9577 ctx->objmask = NULL; 9578 /* Copy the headers to the buffer. */ 9579 action_encap_data = ctx->object; 9580 *action_encap_data = (struct action_raw_encap_data) { 9581 .conf = (struct rte_flow_action_raw_encap){ 9582 .data = action_encap_data->data, 9583 }, 9584 .data = {}, 9585 .preserve = {}, 9586 }; 9587 header = action_encap_data->data; 9588 if (mplsogre_encap_conf.select_vlan) 9589 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9590 else if (mplsogre_encap_conf.select_ipv4) 9591 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9592 else 9593 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9594 memcpy(eth.hdr.dst_addr.addr_bytes, 9595 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9596 memcpy(eth.hdr.src_addr.addr_bytes, 9597 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9598 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9599 header += sizeof(struct rte_ether_hdr); 9600 if (mplsogre_encap_conf.select_vlan) { 9601 if (mplsogre_encap_conf.select_ipv4) 9602 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9603 else 9604 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9605 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9606 header += sizeof(struct rte_vlan_hdr); 9607 } 9608 if (mplsogre_encap_conf.select_ipv4) { 9609 memcpy(header, &ipv4, sizeof(ipv4)); 9610 header += sizeof(ipv4); 9611 } else { 9612 memcpy(&ipv6.hdr.src_addr, 9613 &mplsogre_encap_conf.ipv6_src, 9614 sizeof(mplsogre_encap_conf.ipv6_src)); 9615 memcpy(&ipv6.hdr.dst_addr, 9616 &mplsogre_encap_conf.ipv6_dst, 9617 sizeof(mplsogre_encap_conf.ipv6_dst)); 9618 memcpy(header, &ipv6, sizeof(ipv6)); 9619 header += sizeof(ipv6); 9620 } 9621 memcpy(header, &gre, sizeof(gre)); 9622 header += sizeof(gre); 9623 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 9624 RTE_DIM(mplsogre_encap_conf.label)); 9625 mpls.label_tc_s[2] |= 0x1; 9626 memcpy(header, &mpls, sizeof(mpls)); 9627 header += sizeof(mpls); 9628 action_encap_data->conf.size = header - 9629 action_encap_data->data; 9630 action->conf = &action_encap_data->conf; 9631 return ret; 9632 } 9633 9634 /** Parse MPLSOGRE decap action. */ 9635 static int 9636 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 9637 const char *str, unsigned int len, 9638 void *buf, unsigned int size) 9639 { 9640 struct buffer *out = buf; 9641 struct rte_flow_action *action; 9642 struct action_raw_decap_data *action_decap_data; 9643 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9644 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9645 struct rte_flow_item_ipv4 ipv4 = { 9646 .hdr = { 9647 .next_proto_id = IPPROTO_GRE, 9648 }, 9649 }; 9650 struct rte_flow_item_ipv6 ipv6 = { 9651 .hdr = { 9652 .proto = IPPROTO_GRE, 9653 }, 9654 }; 9655 struct rte_flow_item_gre gre = { 9656 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9657 }; 9658 struct rte_flow_item_mpls mpls; 9659 uint8_t *header; 9660 int ret; 9661 9662 ret = parse_vc(ctx, token, str, len, buf, size); 9663 if (ret < 0) 9664 return ret; 9665 /* Nothing else to do if there is no buffer. */ 9666 if (!out) 9667 return ret; 9668 if (!out->args.vc.actions_n) 9669 return -1; 9670 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9671 /* Point to selected object. */ 9672 ctx->object = out->args.vc.data; 9673 ctx->objmask = NULL; 9674 /* Copy the headers to the buffer. */ 9675 action_decap_data = ctx->object; 9676 *action_decap_data = (struct action_raw_decap_data) { 9677 .conf = (struct rte_flow_action_raw_decap){ 9678 .data = action_decap_data->data, 9679 }, 9680 .data = {}, 9681 }; 9682 header = action_decap_data->data; 9683 if (mplsogre_decap_conf.select_vlan) 9684 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9685 else if (mplsogre_encap_conf.select_ipv4) 9686 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9687 else 9688 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9689 memcpy(eth.hdr.dst_addr.addr_bytes, 9690 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9691 memcpy(eth.hdr.src_addr.addr_bytes, 9692 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9693 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9694 header += sizeof(struct rte_ether_hdr); 9695 if (mplsogre_encap_conf.select_vlan) { 9696 if (mplsogre_encap_conf.select_ipv4) 9697 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9698 else 9699 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9700 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9701 header += sizeof(struct rte_vlan_hdr); 9702 } 9703 if (mplsogre_encap_conf.select_ipv4) { 9704 memcpy(header, &ipv4, sizeof(ipv4)); 9705 header += sizeof(ipv4); 9706 } else { 9707 memcpy(header, &ipv6, sizeof(ipv6)); 9708 header += sizeof(ipv6); 9709 } 9710 memcpy(header, &gre, sizeof(gre)); 9711 header += sizeof(gre); 9712 memset(&mpls, 0, sizeof(mpls)); 9713 memcpy(header, &mpls, sizeof(mpls)); 9714 header += sizeof(mpls); 9715 action_decap_data->conf.size = header - 9716 action_decap_data->data; 9717 action->conf = &action_decap_data->conf; 9718 return ret; 9719 } 9720 9721 /** Parse MPLSOUDP encap action. */ 9722 static int 9723 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 9724 const char *str, unsigned int len, 9725 void *buf, unsigned int size) 9726 { 9727 struct buffer *out = buf; 9728 struct rte_flow_action *action; 9729 struct action_raw_encap_data *action_encap_data; 9730 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9731 struct rte_flow_item_vlan vlan = { 9732 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9733 .hdr.eth_proto = 0, 9734 }; 9735 struct rte_flow_item_ipv4 ipv4 = { 9736 .hdr = { 9737 .src_addr = mplsoudp_encap_conf.ipv4_src, 9738 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 9739 .next_proto_id = IPPROTO_UDP, 9740 .version_ihl = RTE_IPV4_VHL_DEF, 9741 .time_to_live = IPDEFTTL, 9742 }, 9743 }; 9744 struct rte_flow_item_ipv6 ipv6 = { 9745 .hdr = { 9746 .proto = IPPROTO_UDP, 9747 .hop_limits = IPDEFTTL, 9748 }, 9749 }; 9750 struct rte_flow_item_udp udp = { 9751 .hdr = { 9752 .src_port = mplsoudp_encap_conf.udp_src, 9753 .dst_port = mplsoudp_encap_conf.udp_dst, 9754 }, 9755 }; 9756 struct rte_flow_item_mpls mpls; 9757 uint8_t *header; 9758 int ret; 9759 9760 ret = parse_vc(ctx, token, str, len, buf, size); 9761 if (ret < 0) 9762 return ret; 9763 /* Nothing else to do if there is no buffer. */ 9764 if (!out) 9765 return ret; 9766 if (!out->args.vc.actions_n) 9767 return -1; 9768 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9769 /* Point to selected object. */ 9770 ctx->object = out->args.vc.data; 9771 ctx->objmask = NULL; 9772 /* Copy the headers to the buffer. */ 9773 action_encap_data = ctx->object; 9774 *action_encap_data = (struct action_raw_encap_data) { 9775 .conf = (struct rte_flow_action_raw_encap){ 9776 .data = action_encap_data->data, 9777 }, 9778 .data = {}, 9779 .preserve = {}, 9780 }; 9781 header = action_encap_data->data; 9782 if (mplsoudp_encap_conf.select_vlan) 9783 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9784 else if (mplsoudp_encap_conf.select_ipv4) 9785 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9786 else 9787 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9788 memcpy(eth.hdr.dst_addr.addr_bytes, 9789 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9790 memcpy(eth.hdr.src_addr.addr_bytes, 9791 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9792 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9793 header += sizeof(struct rte_ether_hdr); 9794 if (mplsoudp_encap_conf.select_vlan) { 9795 if (mplsoudp_encap_conf.select_ipv4) 9796 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9797 else 9798 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9799 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9800 header += sizeof(struct rte_vlan_hdr); 9801 } 9802 if (mplsoudp_encap_conf.select_ipv4) { 9803 memcpy(header, &ipv4, sizeof(ipv4)); 9804 header += sizeof(ipv4); 9805 } else { 9806 memcpy(&ipv6.hdr.src_addr, 9807 &mplsoudp_encap_conf.ipv6_src, 9808 sizeof(mplsoudp_encap_conf.ipv6_src)); 9809 memcpy(&ipv6.hdr.dst_addr, 9810 &mplsoudp_encap_conf.ipv6_dst, 9811 sizeof(mplsoudp_encap_conf.ipv6_dst)); 9812 memcpy(header, &ipv6, sizeof(ipv6)); 9813 header += sizeof(ipv6); 9814 } 9815 memcpy(header, &udp, sizeof(udp)); 9816 header += sizeof(udp); 9817 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 9818 RTE_DIM(mplsoudp_encap_conf.label)); 9819 mpls.label_tc_s[2] |= 0x1; 9820 memcpy(header, &mpls, sizeof(mpls)); 9821 header += sizeof(mpls); 9822 action_encap_data->conf.size = header - 9823 action_encap_data->data; 9824 action->conf = &action_encap_data->conf; 9825 return ret; 9826 } 9827 9828 /** Parse MPLSOUDP decap action. */ 9829 static int 9830 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 9831 const char *str, unsigned int len, 9832 void *buf, unsigned int size) 9833 { 9834 struct buffer *out = buf; 9835 struct rte_flow_action *action; 9836 struct action_raw_decap_data *action_decap_data; 9837 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9838 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9839 struct rte_flow_item_ipv4 ipv4 = { 9840 .hdr = { 9841 .next_proto_id = IPPROTO_UDP, 9842 }, 9843 }; 9844 struct rte_flow_item_ipv6 ipv6 = { 9845 .hdr = { 9846 .proto = IPPROTO_UDP, 9847 }, 9848 }; 9849 struct rte_flow_item_udp udp = { 9850 .hdr = { 9851 .dst_port = rte_cpu_to_be_16(6635), 9852 }, 9853 }; 9854 struct rte_flow_item_mpls mpls; 9855 uint8_t *header; 9856 int ret; 9857 9858 ret = parse_vc(ctx, token, str, len, buf, size); 9859 if (ret < 0) 9860 return ret; 9861 /* Nothing else to do if there is no buffer. */ 9862 if (!out) 9863 return ret; 9864 if (!out->args.vc.actions_n) 9865 return -1; 9866 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9867 /* Point to selected object. */ 9868 ctx->object = out->args.vc.data; 9869 ctx->objmask = NULL; 9870 /* Copy the headers to the buffer. */ 9871 action_decap_data = ctx->object; 9872 *action_decap_data = (struct action_raw_decap_data) { 9873 .conf = (struct rte_flow_action_raw_decap){ 9874 .data = action_decap_data->data, 9875 }, 9876 .data = {}, 9877 }; 9878 header = action_decap_data->data; 9879 if (mplsoudp_decap_conf.select_vlan) 9880 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9881 else if (mplsoudp_encap_conf.select_ipv4) 9882 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9883 else 9884 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9885 memcpy(eth.hdr.dst_addr.addr_bytes, 9886 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9887 memcpy(eth.hdr.src_addr.addr_bytes, 9888 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9889 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9890 header += sizeof(struct rte_ether_hdr); 9891 if (mplsoudp_encap_conf.select_vlan) { 9892 if (mplsoudp_encap_conf.select_ipv4) 9893 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9894 else 9895 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9896 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9897 header += sizeof(struct rte_vlan_hdr); 9898 } 9899 if (mplsoudp_encap_conf.select_ipv4) { 9900 memcpy(header, &ipv4, sizeof(ipv4)); 9901 header += sizeof(ipv4); 9902 } else { 9903 memcpy(header, &ipv6, sizeof(ipv6)); 9904 header += sizeof(ipv6); 9905 } 9906 memcpy(header, &udp, sizeof(udp)); 9907 header += sizeof(udp); 9908 memset(&mpls, 0, sizeof(mpls)); 9909 memcpy(header, &mpls, sizeof(mpls)); 9910 header += sizeof(mpls); 9911 action_decap_data->conf.size = header - 9912 action_decap_data->data; 9913 action->conf = &action_decap_data->conf; 9914 return ret; 9915 } 9916 9917 static int 9918 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 9919 const char *str, unsigned int len, void *buf, 9920 unsigned int size) 9921 { 9922 struct action_raw_decap_data *action_raw_decap_data; 9923 struct rte_flow_action *action; 9924 const struct arg *arg; 9925 struct buffer *out = buf; 9926 int ret; 9927 uint16_t idx; 9928 9929 RTE_SET_USED(token); 9930 RTE_SET_USED(buf); 9931 RTE_SET_USED(size); 9932 arg = ARGS_ENTRY_ARB_BOUNDED 9933 (offsetof(struct action_raw_decap_data, idx), 9934 sizeof(((struct action_raw_decap_data *)0)->idx), 9935 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 9936 if (push_args(ctx, arg)) 9937 return -1; 9938 ret = parse_int(ctx, token, str, len, NULL, 0); 9939 if (ret < 0) { 9940 pop_args(ctx); 9941 return -1; 9942 } 9943 if (!ctx->object) 9944 return len; 9945 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9946 action_raw_decap_data = ctx->object; 9947 idx = action_raw_decap_data->idx; 9948 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 9949 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 9950 action->conf = &action_raw_decap_data->conf; 9951 return len; 9952 } 9953 9954 9955 static int 9956 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 9957 const char *str, unsigned int len, void *buf, 9958 unsigned int size) 9959 { 9960 struct action_raw_encap_data *action_raw_encap_data; 9961 struct rte_flow_action *action; 9962 const struct arg *arg; 9963 struct buffer *out = buf; 9964 int ret; 9965 uint16_t idx; 9966 9967 RTE_SET_USED(token); 9968 RTE_SET_USED(buf); 9969 RTE_SET_USED(size); 9970 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 9971 return -1; 9972 arg = ARGS_ENTRY_ARB_BOUNDED 9973 (offsetof(struct action_raw_encap_data, idx), 9974 sizeof(((struct action_raw_encap_data *)0)->idx), 9975 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 9976 if (push_args(ctx, arg)) 9977 return -1; 9978 ret = parse_int(ctx, token, str, len, NULL, 0); 9979 if (ret < 0) { 9980 pop_args(ctx); 9981 return -1; 9982 } 9983 if (!ctx->object) 9984 return len; 9985 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9986 action_raw_encap_data = ctx->object; 9987 idx = action_raw_encap_data->idx; 9988 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 9989 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 9990 action_raw_encap_data->conf.preserve = NULL; 9991 action->conf = &action_raw_encap_data->conf; 9992 return len; 9993 } 9994 9995 static int 9996 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 9997 const char *str, unsigned int len, void *buf, 9998 unsigned int size) 9999 { 10000 struct buffer *out = buf; 10001 int ret; 10002 10003 ret = parse_vc(ctx, token, str, len, buf, size); 10004 if (ret < 0) 10005 return ret; 10006 /* Nothing else to do if there is no buffer. */ 10007 if (!out) 10008 return ret; 10009 if (!out->args.vc.actions_n) 10010 return -1; 10011 /* Point to selected object. */ 10012 ctx->object = out->args.vc.data; 10013 ctx->objmask = NULL; 10014 return ret; 10015 } 10016 10017 static int 10018 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 10019 const char *str, unsigned int len, void *buf, 10020 unsigned int size) 10021 { 10022 struct buffer *out = buf; 10023 struct rte_flow_action *action; 10024 struct action_raw_decap_data *action_raw_decap_data = NULL; 10025 int ret; 10026 10027 ret = parse_vc(ctx, token, str, len, buf, size); 10028 if (ret < 0) 10029 return ret; 10030 /* Nothing else to do if there is no buffer. */ 10031 if (!out) 10032 return ret; 10033 if (!out->args.vc.actions_n) 10034 return -1; 10035 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10036 /* Point to selected object. */ 10037 ctx->object = out->args.vc.data; 10038 ctx->objmask = NULL; 10039 /* Copy the headers to the buffer. */ 10040 action_raw_decap_data = ctx->object; 10041 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 10042 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 10043 action->conf = &action_raw_decap_data->conf; 10044 return ret; 10045 } 10046 10047 static int 10048 parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 10049 const char *str, unsigned int len, void *buf, 10050 unsigned int size) 10051 { 10052 struct buffer *out = buf; 10053 struct rte_flow_action *action; 10054 struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; 10055 int ret; 10056 10057 ret = parse_vc(ctx, token, str, len, buf, size); 10058 if (ret < 0) 10059 return ret; 10060 /* Nothing else to do if there is no buffer. */ 10061 if (!out) 10062 return ret; 10063 if (!out->args.vc.actions_n) 10064 return -1; 10065 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10066 /* Point to selected object. */ 10067 ctx->object = out->args.vc.data; 10068 ctx->objmask = NULL; 10069 /* Copy the headers to the buffer. */ 10070 ipv6_ext_remove_data = ctx->object; 10071 ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; 10072 action->conf = &ipv6_ext_remove_data->conf; 10073 return ret; 10074 } 10075 10076 static int 10077 parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, 10078 const char *str, unsigned int len, void *buf, 10079 unsigned int size) 10080 { 10081 struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; 10082 struct rte_flow_action *action; 10083 const struct arg *arg; 10084 struct buffer *out = buf; 10085 int ret; 10086 uint16_t idx; 10087 10088 RTE_SET_USED(token); 10089 RTE_SET_USED(buf); 10090 RTE_SET_USED(size); 10091 arg = ARGS_ENTRY_ARB_BOUNDED 10092 (offsetof(struct action_ipv6_ext_remove_data, idx), 10093 sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), 10094 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10095 if (push_args(ctx, arg)) 10096 return -1; 10097 ret = parse_int(ctx, token, str, len, NULL, 0); 10098 if (ret < 0) { 10099 pop_args(ctx); 10100 return -1; 10101 } 10102 if (!ctx->object) 10103 return len; 10104 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10105 action_ipv6_ext_remove_data = ctx->object; 10106 idx = action_ipv6_ext_remove_data->idx; 10107 action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; 10108 action->conf = &action_ipv6_ext_remove_data->conf; 10109 return len; 10110 } 10111 10112 static int 10113 parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 10114 const char *str, unsigned int len, void *buf, 10115 unsigned int size) 10116 { 10117 struct buffer *out = buf; 10118 struct rte_flow_action *action; 10119 struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; 10120 int ret; 10121 10122 ret = parse_vc(ctx, token, str, len, buf, size); 10123 if (ret < 0) 10124 return ret; 10125 /* Nothing else to do if there is no buffer. */ 10126 if (!out) 10127 return ret; 10128 if (!out->args.vc.actions_n) 10129 return -1; 10130 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10131 /* Point to selected object. */ 10132 ctx->object = out->args.vc.data; 10133 ctx->objmask = NULL; 10134 /* Copy the headers to the buffer. */ 10135 ipv6_ext_push_data = ctx->object; 10136 ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; 10137 ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; 10138 ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; 10139 action->conf = &ipv6_ext_push_data->conf; 10140 return ret; 10141 } 10142 10143 static int 10144 parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, 10145 const char *str, unsigned int len, void *buf, 10146 unsigned int size) 10147 { 10148 struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; 10149 struct rte_flow_action *action; 10150 const struct arg *arg; 10151 struct buffer *out = buf; 10152 int ret; 10153 uint16_t idx; 10154 10155 RTE_SET_USED(token); 10156 RTE_SET_USED(buf); 10157 RTE_SET_USED(size); 10158 arg = ARGS_ENTRY_ARB_BOUNDED 10159 (offsetof(struct action_ipv6_ext_push_data, idx), 10160 sizeof(((struct action_ipv6_ext_push_data *)0)->idx), 10161 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10162 if (push_args(ctx, arg)) 10163 return -1; 10164 ret = parse_int(ctx, token, str, len, NULL, 0); 10165 if (ret < 0) { 10166 pop_args(ctx); 10167 return -1; 10168 } 10169 if (!ctx->object) 10170 return len; 10171 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10172 action_ipv6_ext_push_data = ctx->object; 10173 idx = action_ipv6_ext_push_data->idx; 10174 action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; 10175 action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; 10176 action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; 10177 action->conf = &action_ipv6_ext_push_data->conf; 10178 return len; 10179 } 10180 10181 static int 10182 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 10183 const char *str, unsigned int len, void *buf, 10184 unsigned int size) 10185 { 10186 int ret; 10187 10188 ret = parse_vc(ctx, token, str, len, buf, size); 10189 if (ret < 0) 10190 return ret; 10191 ret = rte_flow_dynf_metadata_register(); 10192 if (ret < 0) 10193 return -1; 10194 return len; 10195 } 10196 10197 static int 10198 parse_vc_action_sample(struct context *ctx, const struct token *token, 10199 const char *str, unsigned int len, void *buf, 10200 unsigned int size) 10201 { 10202 struct buffer *out = buf; 10203 struct rte_flow_action *action; 10204 struct action_sample_data *action_sample_data = NULL; 10205 static struct rte_flow_action end_action = { 10206 RTE_FLOW_ACTION_TYPE_END, 0 10207 }; 10208 int ret; 10209 10210 ret = parse_vc(ctx, token, str, len, buf, size); 10211 if (ret < 0) 10212 return ret; 10213 /* Nothing else to do if there is no buffer. */ 10214 if (!out) 10215 return ret; 10216 if (!out->args.vc.actions_n) 10217 return -1; 10218 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10219 /* Point to selected object. */ 10220 ctx->object = out->args.vc.data; 10221 ctx->objmask = NULL; 10222 /* Copy the headers to the buffer. */ 10223 action_sample_data = ctx->object; 10224 action_sample_data->conf.actions = &end_action; 10225 action->conf = &action_sample_data->conf; 10226 return ret; 10227 } 10228 10229 static int 10230 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 10231 const char *str, unsigned int len, void *buf, 10232 unsigned int size) 10233 { 10234 struct action_sample_data *action_sample_data; 10235 struct rte_flow_action *action; 10236 const struct arg *arg; 10237 struct buffer *out = buf; 10238 int ret; 10239 uint16_t idx; 10240 10241 RTE_SET_USED(token); 10242 RTE_SET_USED(buf); 10243 RTE_SET_USED(size); 10244 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 10245 return -1; 10246 arg = ARGS_ENTRY_ARB_BOUNDED 10247 (offsetof(struct action_sample_data, idx), 10248 sizeof(((struct action_sample_data *)0)->idx), 10249 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 10250 if (push_args(ctx, arg)) 10251 return -1; 10252 ret = parse_int(ctx, token, str, len, NULL, 0); 10253 if (ret < 0) { 10254 pop_args(ctx); 10255 return -1; 10256 } 10257 if (!ctx->object) 10258 return len; 10259 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10260 action_sample_data = ctx->object; 10261 idx = action_sample_data->idx; 10262 action_sample_data->conf.actions = raw_sample_confs[idx].data; 10263 action->conf = &action_sample_data->conf; 10264 return len; 10265 } 10266 10267 /** Parse operation for modify_field command. */ 10268 static int 10269 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 10270 const char *str, unsigned int len, void *buf, 10271 unsigned int size) 10272 { 10273 struct rte_flow_action_modify_field *action_modify_field; 10274 unsigned int i; 10275 10276 (void)token; 10277 (void)buf; 10278 (void)size; 10279 if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) 10280 return -1; 10281 for (i = 0; modify_field_ops[i]; ++i) 10282 if (!strcmp_partial(modify_field_ops[i], str, len)) 10283 break; 10284 if (!modify_field_ops[i]) 10285 return -1; 10286 if (!ctx->object) 10287 return len; 10288 action_modify_field = ctx->object; 10289 action_modify_field->operation = (enum rte_flow_modify_op)i; 10290 return len; 10291 } 10292 10293 /** Parse id for modify_field command. */ 10294 static int 10295 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 10296 const char *str, unsigned int len, void *buf, 10297 unsigned int size) 10298 { 10299 struct rte_flow_action_modify_field *action_modify_field; 10300 unsigned int i; 10301 10302 (void)token; 10303 (void)buf; 10304 (void)size; 10305 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 10306 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 10307 return -1; 10308 for (i = 0; flow_field_ids[i]; ++i) 10309 if (!strcmp_partial(flow_field_ids[i], str, len)) 10310 break; 10311 if (!flow_field_ids[i]) 10312 return -1; 10313 if (!ctx->object) 10314 return len; 10315 action_modify_field = ctx->object; 10316 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 10317 action_modify_field->dst.field = (enum rte_flow_field_id)i; 10318 else 10319 action_modify_field->src.field = (enum rte_flow_field_id)i; 10320 return len; 10321 } 10322 10323 /** Parse level for modify_field command. */ 10324 static int 10325 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 10326 const char *str, unsigned int len, void *buf, 10327 unsigned int size) 10328 { 10329 struct rte_flow_action_modify_field *action; 10330 struct flex_item *fp = NULL; 10331 uint32_t val; 10332 struct buffer *out = buf; 10333 char *end; 10334 10335 (void)token; 10336 (void)size; 10337 if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10338 ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) 10339 return -1; 10340 if (!ctx->object) 10341 return len; 10342 action = ctx->object; 10343 errno = 0; 10344 val = strtoumax(str, &end, 0); 10345 if (errno || (size_t)(end - str) != len) 10346 return -1; 10347 /* No need to validate action template mask value */ 10348 if (out->args.vc.masks) { 10349 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) 10350 action->dst.level = val; 10351 else 10352 action->src.level = val; 10353 return len; 10354 } 10355 if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10356 action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || 10357 (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && 10358 action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 10359 if (val >= FLEX_MAX_PARSERS_NUM) { 10360 printf("Bad flex item handle\n"); 10361 return -1; 10362 } 10363 fp = flex_items[ctx->port][val]; 10364 if (!fp) { 10365 printf("Bad flex item handle\n"); 10366 return -1; 10367 } 10368 } 10369 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { 10370 if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) 10371 action->dst.level = val; 10372 else 10373 action->dst.flex_handle = fp->flex_handle; 10374 } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { 10375 if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) 10376 action->src.level = val; 10377 else 10378 action->src.flex_handle = fp->flex_handle; 10379 } 10380 return len; 10381 } 10382 10383 /** Parse the conntrack update, not a rte_flow_action. */ 10384 static int 10385 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 10386 const char *str, unsigned int len, void *buf, 10387 unsigned int size) 10388 { 10389 struct buffer *out = buf; 10390 struct rte_flow_modify_conntrack *ct_modify = NULL; 10391 10392 (void)size; 10393 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 10394 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 10395 return -1; 10396 /* Token name must match. */ 10397 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10398 return -1; 10399 /* Nothing else to do if there is no buffer. */ 10400 if (!out) 10401 return len; 10402 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 10403 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 10404 ct_modify->new_ct.is_original_dir = 10405 conntrack_context.is_original_dir; 10406 ct_modify->direction = 1; 10407 } else { 10408 uint32_t old_dir; 10409 10410 old_dir = ct_modify->new_ct.is_original_dir; 10411 memcpy(&ct_modify->new_ct, &conntrack_context, 10412 sizeof(conntrack_context)); 10413 ct_modify->new_ct.is_original_dir = old_dir; 10414 ct_modify->state = 1; 10415 } 10416 return len; 10417 } 10418 10419 /** Parse tokens for destroy command. */ 10420 static int 10421 parse_destroy(struct context *ctx, const struct token *token, 10422 const char *str, unsigned int len, 10423 void *buf, unsigned int size) 10424 { 10425 struct buffer *out = buf; 10426 10427 /* Token name must match. */ 10428 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10429 return -1; 10430 /* Nothing else to do if there is no buffer. */ 10431 if (!out) 10432 return len; 10433 if (!out->command) { 10434 if (ctx->curr != DESTROY) 10435 return -1; 10436 if (sizeof(*out) > size) 10437 return -1; 10438 out->command = ctx->curr; 10439 ctx->objdata = 0; 10440 ctx->object = out; 10441 ctx->objmask = NULL; 10442 out->args.destroy.rule = 10443 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10444 sizeof(double)); 10445 return len; 10446 } 10447 if (ctx->curr == DESTROY_IS_USER_ID) { 10448 out->args.destroy.is_user_id = true; 10449 return len; 10450 } 10451 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 10452 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 10453 return -1; 10454 ctx->objdata = 0; 10455 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 10456 ctx->objmask = NULL; 10457 return len; 10458 } 10459 10460 /** Parse tokens for flush command. */ 10461 static int 10462 parse_flush(struct context *ctx, const struct token *token, 10463 const char *str, unsigned int len, 10464 void *buf, unsigned int size) 10465 { 10466 struct buffer *out = buf; 10467 10468 /* Token name must match. */ 10469 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10470 return -1; 10471 /* Nothing else to do if there is no buffer. */ 10472 if (!out) 10473 return len; 10474 if (!out->command) { 10475 if (ctx->curr != FLUSH) 10476 return -1; 10477 if (sizeof(*out) > size) 10478 return -1; 10479 out->command = ctx->curr; 10480 ctx->objdata = 0; 10481 ctx->object = out; 10482 ctx->objmask = NULL; 10483 } 10484 return len; 10485 } 10486 10487 /** Parse tokens for dump command. */ 10488 static int 10489 parse_dump(struct context *ctx, const struct token *token, 10490 const char *str, unsigned int len, 10491 void *buf, unsigned int size) 10492 { 10493 struct buffer *out = buf; 10494 10495 /* Token name must match. */ 10496 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10497 return -1; 10498 /* Nothing else to do if there is no buffer. */ 10499 if (!out) 10500 return len; 10501 if (!out->command) { 10502 if (ctx->curr != DUMP) 10503 return -1; 10504 if (sizeof(*out) > size) 10505 return -1; 10506 out->command = ctx->curr; 10507 ctx->objdata = 0; 10508 ctx->object = out; 10509 ctx->objmask = NULL; 10510 return len; 10511 } 10512 switch (ctx->curr) { 10513 case DUMP_ALL: 10514 case DUMP_ONE: 10515 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 10516 out->command = ctx->curr; 10517 ctx->objdata = 0; 10518 ctx->object = out; 10519 ctx->objmask = NULL; 10520 return len; 10521 case DUMP_IS_USER_ID: 10522 out->args.dump.is_user_id = true; 10523 return len; 10524 default: 10525 return -1; 10526 } 10527 } 10528 10529 /** Parse tokens for query command. */ 10530 static int 10531 parse_query(struct context *ctx, const struct token *token, 10532 const char *str, unsigned int len, 10533 void *buf, unsigned int size) 10534 { 10535 struct buffer *out = buf; 10536 10537 /* Token name must match. */ 10538 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10539 return -1; 10540 /* Nothing else to do if there is no buffer. */ 10541 if (!out) 10542 return len; 10543 if (!out->command) { 10544 if (ctx->curr != QUERY) 10545 return -1; 10546 if (sizeof(*out) > size) 10547 return -1; 10548 out->command = ctx->curr; 10549 ctx->objdata = 0; 10550 ctx->object = out; 10551 ctx->objmask = NULL; 10552 } 10553 if (ctx->curr == QUERY_IS_USER_ID) { 10554 out->args.query.is_user_id = true; 10555 return len; 10556 } 10557 return len; 10558 } 10559 10560 /** Parse action names. */ 10561 static int 10562 parse_action(struct context *ctx, const struct token *token, 10563 const char *str, unsigned int len, 10564 void *buf, unsigned int size) 10565 { 10566 struct buffer *out = buf; 10567 const struct arg *arg = pop_args(ctx); 10568 unsigned int i; 10569 10570 (void)size; 10571 /* Argument is expected. */ 10572 if (!arg) 10573 return -1; 10574 /* Parse action name. */ 10575 for (i = 0; next_action[i]; ++i) { 10576 const struct parse_action_priv *priv; 10577 10578 token = &token_list[next_action[i]]; 10579 if (strcmp_partial(token->name, str, len)) 10580 continue; 10581 priv = token->priv; 10582 if (!priv) 10583 goto error; 10584 if (out) 10585 memcpy((uint8_t *)ctx->object + arg->offset, 10586 &priv->type, 10587 arg->size); 10588 return len; 10589 } 10590 error: 10591 push_args(ctx, arg); 10592 return -1; 10593 } 10594 10595 /** Parse tokens for list command. */ 10596 static int 10597 parse_list(struct context *ctx, const struct token *token, 10598 const char *str, unsigned int len, 10599 void *buf, unsigned int size) 10600 { 10601 struct buffer *out = buf; 10602 10603 /* Token name must match. */ 10604 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10605 return -1; 10606 /* Nothing else to do if there is no buffer. */ 10607 if (!out) 10608 return len; 10609 if (!out->command) { 10610 if (ctx->curr != LIST) 10611 return -1; 10612 if (sizeof(*out) > size) 10613 return -1; 10614 out->command = ctx->curr; 10615 ctx->objdata = 0; 10616 ctx->object = out; 10617 ctx->objmask = NULL; 10618 out->args.list.group = 10619 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10620 sizeof(double)); 10621 return len; 10622 } 10623 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 10624 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 10625 return -1; 10626 ctx->objdata = 0; 10627 ctx->object = out->args.list.group + out->args.list.group_n++; 10628 ctx->objmask = NULL; 10629 return len; 10630 } 10631 10632 /** Parse tokens for list all aged flows command. */ 10633 static int 10634 parse_aged(struct context *ctx, const struct token *token, 10635 const char *str, unsigned int len, 10636 void *buf, unsigned int size) 10637 { 10638 struct buffer *out = buf; 10639 10640 /* Token name must match. */ 10641 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10642 return -1; 10643 /* Nothing else to do if there is no buffer. */ 10644 if (!out) 10645 return len; 10646 if (!out->command || out->command == QUEUE) { 10647 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 10648 return -1; 10649 if (sizeof(*out) > size) 10650 return -1; 10651 out->command = ctx->curr; 10652 ctx->objdata = 0; 10653 ctx->object = out; 10654 ctx->objmask = NULL; 10655 } 10656 if (ctx->curr == AGED_DESTROY) 10657 out->args.aged.destroy = 1; 10658 return len; 10659 } 10660 10661 /** Parse tokens for isolate command. */ 10662 static int 10663 parse_isolate(struct context *ctx, const struct token *token, 10664 const char *str, unsigned int len, 10665 void *buf, unsigned int size) 10666 { 10667 struct buffer *out = buf; 10668 10669 /* Token name must match. */ 10670 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10671 return -1; 10672 /* Nothing else to do if there is no buffer. */ 10673 if (!out) 10674 return len; 10675 if (!out->command) { 10676 if (ctx->curr != ISOLATE) 10677 return -1; 10678 if (sizeof(*out) > size) 10679 return -1; 10680 out->command = ctx->curr; 10681 ctx->objdata = 0; 10682 ctx->object = out; 10683 ctx->objmask = NULL; 10684 } 10685 return len; 10686 } 10687 10688 /** Parse tokens for info/configure command. */ 10689 static int 10690 parse_configure(struct context *ctx, const struct token *token, 10691 const char *str, unsigned int len, 10692 void *buf, unsigned int size) 10693 { 10694 struct buffer *out = buf; 10695 10696 /* Token name must match. */ 10697 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10698 return -1; 10699 /* Nothing else to do if there is no buffer. */ 10700 if (!out) 10701 return len; 10702 if (!out->command) { 10703 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 10704 return -1; 10705 if (sizeof(*out) > size) 10706 return -1; 10707 out->command = ctx->curr; 10708 ctx->objdata = 0; 10709 ctx->object = out; 10710 ctx->objmask = NULL; 10711 } 10712 return len; 10713 } 10714 10715 /** Parse tokens for template create command. */ 10716 static int 10717 parse_template(struct context *ctx, const struct token *token, 10718 const char *str, unsigned int len, 10719 void *buf, unsigned int size) 10720 { 10721 struct buffer *out = buf; 10722 10723 /* Token name must match. */ 10724 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10725 return -1; 10726 /* Nothing else to do if there is no buffer. */ 10727 if (!out) 10728 return len; 10729 if (!out->command) { 10730 if (ctx->curr != PATTERN_TEMPLATE && 10731 ctx->curr != ACTIONS_TEMPLATE) 10732 return -1; 10733 if (sizeof(*out) > size) 10734 return -1; 10735 out->command = ctx->curr; 10736 ctx->objdata = 0; 10737 ctx->object = out; 10738 ctx->objmask = NULL; 10739 out->args.vc.data = (uint8_t *)out + size; 10740 return len; 10741 } 10742 switch (ctx->curr) { 10743 case PATTERN_TEMPLATE_CREATE: 10744 out->args.vc.pattern = 10745 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10746 sizeof(double)); 10747 out->args.vc.pat_templ_id = UINT32_MAX; 10748 out->command = ctx->curr; 10749 ctx->objdata = 0; 10750 ctx->object = out; 10751 ctx->objmask = NULL; 10752 return len; 10753 case PATTERN_TEMPLATE_EGRESS: 10754 out->args.vc.attr.egress = 1; 10755 return len; 10756 case PATTERN_TEMPLATE_INGRESS: 10757 out->args.vc.attr.ingress = 1; 10758 return len; 10759 case PATTERN_TEMPLATE_TRANSFER: 10760 out->args.vc.attr.transfer = 1; 10761 return len; 10762 case ACTIONS_TEMPLATE_CREATE: 10763 out->args.vc.act_templ_id = UINT32_MAX; 10764 out->command = ctx->curr; 10765 ctx->objdata = 0; 10766 ctx->object = out; 10767 ctx->objmask = NULL; 10768 return len; 10769 case ACTIONS_TEMPLATE_SPEC: 10770 out->args.vc.actions = 10771 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10772 sizeof(double)); 10773 ctx->object = out->args.vc.actions; 10774 ctx->objmask = NULL; 10775 return len; 10776 case ACTIONS_TEMPLATE_MASK: 10777 out->args.vc.masks = 10778 (void *)RTE_ALIGN_CEIL((uintptr_t) 10779 (out->args.vc.actions + 10780 out->args.vc.actions_n), 10781 sizeof(double)); 10782 ctx->object = out->args.vc.masks; 10783 ctx->objmask = NULL; 10784 return len; 10785 case ACTIONS_TEMPLATE_EGRESS: 10786 out->args.vc.attr.egress = 1; 10787 return len; 10788 case ACTIONS_TEMPLATE_INGRESS: 10789 out->args.vc.attr.ingress = 1; 10790 return len; 10791 case ACTIONS_TEMPLATE_TRANSFER: 10792 out->args.vc.attr.transfer = 1; 10793 return len; 10794 default: 10795 return -1; 10796 } 10797 } 10798 10799 /** Parse tokens for template destroy command. */ 10800 static int 10801 parse_template_destroy(struct context *ctx, const struct token *token, 10802 const char *str, unsigned int len, 10803 void *buf, unsigned int size) 10804 { 10805 struct buffer *out = buf; 10806 uint32_t *template_id; 10807 10808 /* Token name must match. */ 10809 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10810 return -1; 10811 /* Nothing else to do if there is no buffer. */ 10812 if (!out) 10813 return len; 10814 if (!out->command || 10815 out->command == PATTERN_TEMPLATE || 10816 out->command == ACTIONS_TEMPLATE) { 10817 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 10818 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 10819 return -1; 10820 if (sizeof(*out) > size) 10821 return -1; 10822 out->command = ctx->curr; 10823 ctx->objdata = 0; 10824 ctx->object = out; 10825 ctx->objmask = NULL; 10826 out->args.templ_destroy.template_id = 10827 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10828 sizeof(double)); 10829 return len; 10830 } 10831 template_id = out->args.templ_destroy.template_id 10832 + out->args.templ_destroy.template_id_n++; 10833 if ((uint8_t *)template_id > (uint8_t *)out + size) 10834 return -1; 10835 ctx->objdata = 0; 10836 ctx->object = template_id; 10837 ctx->objmask = NULL; 10838 return len; 10839 } 10840 10841 /** Parse tokens for table create command. */ 10842 static int 10843 parse_table(struct context *ctx, const struct token *token, 10844 const char *str, unsigned int len, 10845 void *buf, unsigned int size) 10846 { 10847 struct buffer *out = buf; 10848 uint32_t *template_id; 10849 10850 /* Token name must match. */ 10851 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10852 return -1; 10853 /* Nothing else to do if there is no buffer. */ 10854 if (!out) 10855 return len; 10856 if (!out->command) { 10857 if (ctx->curr != TABLE) 10858 return -1; 10859 if (sizeof(*out) > size) 10860 return -1; 10861 out->command = ctx->curr; 10862 ctx->objdata = 0; 10863 ctx->object = out; 10864 ctx->objmask = NULL; 10865 return len; 10866 } 10867 switch (ctx->curr) { 10868 case TABLE_CREATE: 10869 case TABLE_RESIZE: 10870 out->command = ctx->curr; 10871 ctx->objdata = 0; 10872 ctx->object = out; 10873 ctx->objmask = NULL; 10874 out->args.table.id = UINT32_MAX; 10875 return len; 10876 case TABLE_PATTERN_TEMPLATE: 10877 out->args.table.pat_templ_id = 10878 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10879 sizeof(double)); 10880 template_id = out->args.table.pat_templ_id 10881 + out->args.table.pat_templ_id_n++; 10882 if ((uint8_t *)template_id > (uint8_t *)out + size) 10883 return -1; 10884 ctx->objdata = 0; 10885 ctx->object = template_id; 10886 ctx->objmask = NULL; 10887 return len; 10888 case TABLE_ACTIONS_TEMPLATE: 10889 out->args.table.act_templ_id = 10890 (void *)RTE_ALIGN_CEIL((uintptr_t) 10891 (out->args.table.pat_templ_id + 10892 out->args.table.pat_templ_id_n), 10893 sizeof(double)); 10894 template_id = out->args.table.act_templ_id 10895 + out->args.table.act_templ_id_n++; 10896 if ((uint8_t *)template_id > (uint8_t *)out + size) 10897 return -1; 10898 ctx->objdata = 0; 10899 ctx->object = template_id; 10900 ctx->objmask = NULL; 10901 return len; 10902 case TABLE_INGRESS: 10903 out->args.table.attr.flow_attr.ingress = 1; 10904 return len; 10905 case TABLE_EGRESS: 10906 out->args.table.attr.flow_attr.egress = 1; 10907 return len; 10908 case TABLE_TRANSFER: 10909 out->args.table.attr.flow_attr.transfer = 1; 10910 return len; 10911 case TABLE_TRANSFER_WIRE_ORIG: 10912 if (!out->args.table.attr.flow_attr.transfer) 10913 return -1; 10914 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; 10915 return len; 10916 case TABLE_TRANSFER_VPORT_ORIG: 10917 if (!out->args.table.attr.flow_attr.transfer) 10918 return -1; 10919 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; 10920 return len; 10921 case TABLE_RESIZABLE: 10922 out->args.table.attr.specialize |= 10923 RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE; 10924 return len; 10925 case TABLE_RULES_NUMBER: 10926 ctx->objdata = 0; 10927 ctx->object = out; 10928 ctx->objmask = NULL; 10929 return len; 10930 case TABLE_RESIZE_ID: 10931 case TABLE_RESIZE_RULES_NUMBER: 10932 return len; 10933 default: 10934 return -1; 10935 } 10936 } 10937 10938 /** Parse tokens for table destroy command. */ 10939 static int 10940 parse_table_destroy(struct context *ctx, const struct token *token, 10941 const char *str, unsigned int len, 10942 void *buf, unsigned int size) 10943 { 10944 struct buffer *out = buf; 10945 uint32_t *table_id; 10946 10947 /* Token name must match. */ 10948 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10949 return -1; 10950 /* Nothing else to do if there is no buffer. */ 10951 if (!out) 10952 return len; 10953 if (!out->command || out->command == TABLE) { 10954 if (ctx->curr != TABLE_DESTROY && 10955 ctx->curr != TABLE_RESIZE_COMPLETE) 10956 return -1; 10957 if (sizeof(*out) > size) 10958 return -1; 10959 out->command = ctx->curr; 10960 ctx->objdata = 0; 10961 ctx->object = out; 10962 ctx->objmask = NULL; 10963 out->args.table_destroy.table_id = 10964 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10965 sizeof(double)); 10966 return len; 10967 } 10968 table_id = out->args.table_destroy.table_id 10969 + out->args.table_destroy.table_id_n++; 10970 if ((uint8_t *)table_id > (uint8_t *)out + size) 10971 return -1; 10972 ctx->objdata = 0; 10973 ctx->object = table_id; 10974 ctx->objmask = NULL; 10975 return len; 10976 } 10977 10978 /** Parse tokens for queue create commands. */ 10979 static int 10980 parse_qo(struct context *ctx, const struct token *token, 10981 const char *str, unsigned int len, 10982 void *buf, unsigned int size) 10983 { 10984 struct buffer *out = buf; 10985 10986 /* Token name must match. */ 10987 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10988 return -1; 10989 /* Nothing else to do if there is no buffer. */ 10990 if (!out) 10991 return len; 10992 if (!out->command) { 10993 if (ctx->curr != QUEUE) 10994 return -1; 10995 if (sizeof(*out) > size) 10996 return -1; 10997 out->command = ctx->curr; 10998 ctx->objdata = 0; 10999 ctx->object = out; 11000 ctx->objmask = NULL; 11001 out->args.vc.data = (uint8_t *)out + size; 11002 return len; 11003 } 11004 switch (ctx->curr) { 11005 case QUEUE_CREATE: 11006 case QUEUE_UPDATE: 11007 out->command = ctx->curr; 11008 ctx->objdata = 0; 11009 ctx->object = out; 11010 ctx->objmask = NULL; 11011 out->args.vc.rule_id = UINT32_MAX; 11012 return len; 11013 case QUEUE_TEMPLATE_TABLE: 11014 case QUEUE_PATTERN_TEMPLATE: 11015 case QUEUE_ACTIONS_TEMPLATE: 11016 case QUEUE_CREATE_POSTPONE: 11017 case QUEUE_RULE_ID: 11018 case QUEUE_UPDATE_ID: 11019 return len; 11020 case ITEM_PATTERN: 11021 out->args.vc.pattern = 11022 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11023 sizeof(double)); 11024 ctx->object = out->args.vc.pattern; 11025 ctx->objmask = NULL; 11026 return len; 11027 case ACTIONS: 11028 out->args.vc.actions = 11029 (void *)RTE_ALIGN_CEIL((uintptr_t) 11030 (out->args.vc.pattern + 11031 out->args.vc.pattern_n), 11032 sizeof(double)); 11033 ctx->object = out->args.vc.actions; 11034 ctx->objmask = NULL; 11035 return len; 11036 default: 11037 return -1; 11038 } 11039 } 11040 11041 /** Parse tokens for queue destroy command. */ 11042 static int 11043 parse_qo_destroy(struct context *ctx, const struct token *token, 11044 const char *str, unsigned int len, 11045 void *buf, unsigned int size) 11046 { 11047 struct buffer *out = buf; 11048 uint64_t *flow_id; 11049 11050 /* Token name must match. */ 11051 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11052 return -1; 11053 /* Nothing else to do if there is no buffer. */ 11054 if (!out) 11055 return len; 11056 if (!out->command || out->command == QUEUE) { 11057 if (ctx->curr != QUEUE_DESTROY && 11058 ctx->curr != QUEUE_FLOW_UPDATE_RESIZED) 11059 return -1; 11060 if (sizeof(*out) > size) 11061 return -1; 11062 out->command = ctx->curr; 11063 ctx->objdata = 0; 11064 ctx->object = out; 11065 ctx->objmask = NULL; 11066 out->args.destroy.rule = 11067 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11068 sizeof(double)); 11069 return len; 11070 } 11071 switch (ctx->curr) { 11072 case QUEUE_DESTROY_ID: 11073 flow_id = out->args.destroy.rule 11074 + out->args.destroy.rule_n++; 11075 if ((uint8_t *)flow_id > (uint8_t *)out + size) 11076 return -1; 11077 ctx->objdata = 0; 11078 ctx->object = flow_id; 11079 ctx->objmask = NULL; 11080 return len; 11081 case QUEUE_DESTROY_POSTPONE: 11082 return len; 11083 default: 11084 return -1; 11085 } 11086 } 11087 11088 /** Parse tokens for push queue command. */ 11089 static int 11090 parse_push(struct context *ctx, const struct token *token, 11091 const char *str, unsigned int len, 11092 void *buf, unsigned int size) 11093 { 11094 struct buffer *out = buf; 11095 11096 /* Token name must match. */ 11097 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11098 return -1; 11099 /* Nothing else to do if there is no buffer. */ 11100 if (!out) 11101 return len; 11102 if (!out->command) { 11103 if (ctx->curr != PUSH) 11104 return -1; 11105 if (sizeof(*out) > size) 11106 return -1; 11107 out->command = ctx->curr; 11108 ctx->objdata = 0; 11109 ctx->object = out; 11110 ctx->objmask = NULL; 11111 out->args.vc.data = (uint8_t *)out + size; 11112 } 11113 return len; 11114 } 11115 11116 /** Parse tokens for pull command. */ 11117 static int 11118 parse_pull(struct context *ctx, const struct token *token, 11119 const char *str, unsigned int len, 11120 void *buf, unsigned int size) 11121 { 11122 struct buffer *out = buf; 11123 11124 /* Token name must match. */ 11125 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11126 return -1; 11127 /* Nothing else to do if there is no buffer. */ 11128 if (!out) 11129 return len; 11130 if (!out->command) { 11131 if (ctx->curr != PULL) 11132 return -1; 11133 if (sizeof(*out) > size) 11134 return -1; 11135 out->command = ctx->curr; 11136 ctx->objdata = 0; 11137 ctx->object = out; 11138 ctx->objmask = NULL; 11139 out->args.vc.data = (uint8_t *)out + size; 11140 } 11141 return len; 11142 } 11143 11144 /** Parse tokens for hash calculation commands. */ 11145 static int 11146 parse_hash(struct context *ctx, const struct token *token, 11147 const char *str, unsigned int len, 11148 void *buf, unsigned int size) 11149 { 11150 struct buffer *out = buf; 11151 11152 /* Token name must match. */ 11153 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11154 return -1; 11155 /* Nothing else to do if there is no buffer. */ 11156 if (!out) 11157 return len; 11158 if (!out->command) { 11159 if (ctx->curr != HASH) 11160 return -1; 11161 if (sizeof(*out) > size) 11162 return -1; 11163 out->command = ctx->curr; 11164 ctx->objdata = 0; 11165 ctx->object = out; 11166 ctx->objmask = NULL; 11167 out->args.vc.data = (uint8_t *)out + size; 11168 return len; 11169 } 11170 switch (ctx->curr) { 11171 case HASH_CALC_TABLE: 11172 case HASH_CALC_PATTERN_INDEX: 11173 return len; 11174 case ITEM_PATTERN: 11175 out->args.vc.pattern = 11176 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11177 sizeof(double)); 11178 ctx->object = out->args.vc.pattern; 11179 ctx->objmask = NULL; 11180 return len; 11181 case HASH_CALC_ENCAP: 11182 out->args.vc.encap_hash = 1; 11183 return len; 11184 case ENCAP_HASH_FIELD_SRC_PORT: 11185 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT; 11186 return len; 11187 case ENCAP_HASH_FIELD_GRE_FLOW_ID: 11188 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID; 11189 return len; 11190 default: 11191 return -1; 11192 } 11193 } 11194 11195 static int 11196 parse_group(struct context *ctx, const struct token *token, 11197 const char *str, unsigned int len, 11198 void *buf, unsigned int size) 11199 { 11200 struct buffer *out = buf; 11201 11202 /* Token name must match. */ 11203 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11204 return -1; 11205 /* Nothing else to do if there is no buffer. */ 11206 if (!out) 11207 return len; 11208 if (!out->command) { 11209 if (ctx->curr != FLOW_GROUP) 11210 return -1; 11211 if (sizeof(*out) > size) 11212 return -1; 11213 out->command = ctx->curr; 11214 ctx->objdata = 0; 11215 ctx->object = out; 11216 ctx->objmask = NULL; 11217 out->args.vc.data = (uint8_t *)out + size; 11218 return len; 11219 } 11220 switch (ctx->curr) { 11221 case GROUP_INGRESS: 11222 out->args.vc.attr.ingress = 1; 11223 return len; 11224 case GROUP_EGRESS: 11225 out->args.vc.attr.egress = 1; 11226 return len; 11227 case GROUP_TRANSFER: 11228 out->args.vc.attr.transfer = 1; 11229 return len; 11230 case GROUP_SET_MISS_ACTIONS: 11231 out->command = ctx->curr; 11232 ctx->objdata = 0; 11233 ctx->object = out; 11234 ctx->objmask = NULL; 11235 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11236 sizeof(double)); 11237 return len; 11238 default: 11239 return -1; 11240 } 11241 } 11242 11243 static int 11244 parse_flex(struct context *ctx, const struct token *token, 11245 const char *str, unsigned int len, 11246 void *buf, unsigned int size) 11247 { 11248 struct buffer *out = buf; 11249 11250 /* Token name must match. */ 11251 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11252 return -1; 11253 /* Nothing else to do if there is no buffer. */ 11254 if (!out) 11255 return len; 11256 if (out->command == ZERO) { 11257 if (ctx->curr != FLEX) 11258 return -1; 11259 if (sizeof(*out) > size) 11260 return -1; 11261 out->command = ctx->curr; 11262 ctx->objdata = 0; 11263 ctx->object = out; 11264 ctx->objmask = NULL; 11265 } else { 11266 switch (ctx->curr) { 11267 default: 11268 break; 11269 case FLEX_ITEM_INIT: 11270 case FLEX_ITEM_CREATE: 11271 case FLEX_ITEM_DESTROY: 11272 out->command = ctx->curr; 11273 break; 11274 } 11275 } 11276 11277 return len; 11278 } 11279 11280 static int 11281 parse_tunnel(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 != TUNNEL) 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 } else { 11303 switch (ctx->curr) { 11304 default: 11305 break; 11306 case TUNNEL_CREATE: 11307 case TUNNEL_DESTROY: 11308 case TUNNEL_LIST: 11309 out->command = ctx->curr; 11310 break; 11311 case TUNNEL_CREATE_TYPE: 11312 case TUNNEL_DESTROY_ID: 11313 ctx->object = &out->args.vc.tunnel_ops; 11314 break; 11315 } 11316 } 11317 11318 return len; 11319 } 11320 11321 /** 11322 * Parse signed/unsigned integers 8 to 64-bit long. 11323 * 11324 * Last argument (ctx->args) is retrieved to determine integer type and 11325 * storage location. 11326 */ 11327 static int 11328 parse_int(struct context *ctx, const struct token *token, 11329 const char *str, unsigned int len, 11330 void *buf, unsigned int size) 11331 { 11332 const struct arg *arg = pop_args(ctx); 11333 uintmax_t u; 11334 char *end; 11335 11336 (void)token; 11337 /* Argument is expected. */ 11338 if (!arg) 11339 return -1; 11340 errno = 0; 11341 u = arg->sign ? 11342 (uintmax_t)strtoimax(str, &end, 0) : 11343 strtoumax(str, &end, 0); 11344 if (errno || (size_t)(end - str) != len) 11345 goto error; 11346 if (arg->bounded && 11347 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 11348 (intmax_t)u > (intmax_t)arg->max)) || 11349 (!arg->sign && (u < arg->min || u > arg->max)))) 11350 goto error; 11351 if (!ctx->object) 11352 return len; 11353 if (arg->mask) { 11354 if (!arg_entry_bf_fill(ctx->object, u, arg) || 11355 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 11356 goto error; 11357 return len; 11358 } 11359 buf = (uint8_t *)ctx->object + arg->offset; 11360 size = arg->size; 11361 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 11362 return -1; 11363 objmask: 11364 switch (size) { 11365 case sizeof(uint8_t): 11366 *(uint8_t *)buf = u; 11367 break; 11368 case sizeof(uint16_t): 11369 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 11370 break; 11371 case sizeof(uint8_t [3]): 11372 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 11373 if (!arg->hton) { 11374 ((uint8_t *)buf)[0] = u; 11375 ((uint8_t *)buf)[1] = u >> 8; 11376 ((uint8_t *)buf)[2] = u >> 16; 11377 break; 11378 } 11379 #endif 11380 ((uint8_t *)buf)[0] = u >> 16; 11381 ((uint8_t *)buf)[1] = u >> 8; 11382 ((uint8_t *)buf)[2] = u; 11383 break; 11384 case sizeof(uint32_t): 11385 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 11386 break; 11387 case sizeof(uint64_t): 11388 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 11389 break; 11390 default: 11391 goto error; 11392 } 11393 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 11394 u = -1; 11395 buf = (uint8_t *)ctx->objmask + arg->offset; 11396 goto objmask; 11397 } 11398 return len; 11399 error: 11400 push_args(ctx, arg); 11401 return -1; 11402 } 11403 11404 /** 11405 * Parse a string. 11406 * 11407 * Three arguments (ctx->args) are retrieved from the stack to store data, 11408 * its actual length and address (in that order). 11409 */ 11410 static int 11411 parse_string(struct context *ctx, const struct token *token, 11412 const char *str, unsigned int len, 11413 void *buf, unsigned int size) 11414 { 11415 const struct arg *arg_data = pop_args(ctx); 11416 const struct arg *arg_len = pop_args(ctx); 11417 const struct arg *arg_addr = pop_args(ctx); 11418 char tmp[16]; /* Ought to be enough. */ 11419 int ret; 11420 11421 /* Arguments are expected. */ 11422 if (!arg_data) 11423 return -1; 11424 if (!arg_len) { 11425 push_args(ctx, arg_data); 11426 return -1; 11427 } 11428 if (!arg_addr) { 11429 push_args(ctx, arg_len); 11430 push_args(ctx, arg_data); 11431 return -1; 11432 } 11433 size = arg_data->size; 11434 /* Bit-mask fill is not supported. */ 11435 if (arg_data->mask || size < len) 11436 goto error; 11437 if (!ctx->object) 11438 return len; 11439 /* Let parse_int() fill length information first. */ 11440 ret = snprintf(tmp, sizeof(tmp), "%u", len); 11441 if (ret < 0) 11442 goto error; 11443 push_args(ctx, arg_len); 11444 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11445 if (ret < 0) { 11446 pop_args(ctx); 11447 goto error; 11448 } 11449 buf = (uint8_t *)ctx->object + arg_data->offset; 11450 /* Output buffer is not necessarily NUL-terminated. */ 11451 memcpy(buf, str, len); 11452 memset((uint8_t *)buf + len, 0x00, size - len); 11453 if (ctx->objmask) 11454 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11455 /* Save address if requested. */ 11456 if (arg_addr->size) { 11457 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11458 (void *[]){ 11459 (uint8_t *)ctx->object + arg_data->offset 11460 }, 11461 arg_addr->size); 11462 if (ctx->objmask) 11463 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11464 (void *[]){ 11465 (uint8_t *)ctx->objmask + arg_data->offset 11466 }, 11467 arg_addr->size); 11468 } 11469 return len; 11470 error: 11471 push_args(ctx, arg_addr); 11472 push_args(ctx, arg_len); 11473 push_args(ctx, arg_data); 11474 return -1; 11475 } 11476 11477 static int 11478 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 11479 { 11480 const uint8_t *head = dst; 11481 uint32_t left; 11482 11483 if (*size == 0) 11484 return -1; 11485 11486 left = *size; 11487 11488 /* Convert chars to bytes */ 11489 while (left) { 11490 char tmp[3], *end = tmp; 11491 uint32_t read_lim = left & 1 ? 1 : 2; 11492 11493 snprintf(tmp, read_lim + 1, "%s", src); 11494 *dst = strtoul(tmp, &end, 16); 11495 if (*end) { 11496 *dst = 0; 11497 *size = (uint32_t)(dst - head); 11498 return -1; 11499 } 11500 left -= read_lim; 11501 src += read_lim; 11502 dst++; 11503 } 11504 *dst = 0; 11505 *size = (uint32_t)(dst - head); 11506 return 0; 11507 } 11508 11509 static int 11510 parse_hex(struct context *ctx, const struct token *token, 11511 const char *str, unsigned int len, 11512 void *buf, unsigned int size) 11513 { 11514 const struct arg *arg_data = pop_args(ctx); 11515 const struct arg *arg_len = pop_args(ctx); 11516 const struct arg *arg_addr = pop_args(ctx); 11517 char tmp[16]; /* Ought to be enough. */ 11518 int ret; 11519 unsigned int hexlen = len; 11520 unsigned int length = 256; 11521 uint8_t hex_tmp[length]; 11522 11523 /* Arguments are expected. */ 11524 if (!arg_data) 11525 return -1; 11526 if (!arg_len) { 11527 push_args(ctx, arg_data); 11528 return -1; 11529 } 11530 if (!arg_addr) { 11531 push_args(ctx, arg_len); 11532 push_args(ctx, arg_data); 11533 return -1; 11534 } 11535 size = arg_data->size; 11536 /* Bit-mask fill is not supported. */ 11537 if (arg_data->mask) 11538 goto error; 11539 if (!ctx->object) 11540 return len; 11541 11542 /* translate bytes string to array. */ 11543 if (str[0] == '0' && ((str[1] == 'x') || 11544 (str[1] == 'X'))) { 11545 str += 2; 11546 hexlen -= 2; 11547 } 11548 if (hexlen > length) 11549 goto error; 11550 ret = parse_hex_string(str, hex_tmp, &hexlen); 11551 if (ret < 0) 11552 goto error; 11553 /* Check the converted binary fits into data buffer. */ 11554 if (hexlen > size) 11555 goto error; 11556 /* Let parse_int() fill length information first. */ 11557 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 11558 if (ret < 0) 11559 goto error; 11560 /* Save length if requested. */ 11561 if (arg_len->size) { 11562 push_args(ctx, arg_len); 11563 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11564 if (ret < 0) { 11565 pop_args(ctx); 11566 goto error; 11567 } 11568 } 11569 buf = (uint8_t *)ctx->object + arg_data->offset; 11570 /* Output buffer is not necessarily NUL-terminated. */ 11571 memcpy(buf, hex_tmp, hexlen); 11572 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 11573 if (ctx->objmask) 11574 memset((uint8_t *)ctx->objmask + arg_data->offset, 11575 0xff, hexlen); 11576 /* Save address if requested. */ 11577 if (arg_addr->size) { 11578 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11579 (void *[]){ 11580 (uint8_t *)ctx->object + arg_data->offset 11581 }, 11582 arg_addr->size); 11583 if (ctx->objmask) 11584 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11585 (void *[]){ 11586 (uint8_t *)ctx->objmask + arg_data->offset 11587 }, 11588 arg_addr->size); 11589 } 11590 return len; 11591 error: 11592 push_args(ctx, arg_addr); 11593 push_args(ctx, arg_len); 11594 push_args(ctx, arg_data); 11595 return -1; 11596 11597 } 11598 11599 /** 11600 * Parse a zero-ended string. 11601 */ 11602 static int 11603 parse_string0(struct context *ctx, const struct token *token __rte_unused, 11604 const char *str, unsigned int len, 11605 void *buf, unsigned int size) 11606 { 11607 const struct arg *arg_data = pop_args(ctx); 11608 11609 /* Arguments are expected. */ 11610 if (!arg_data) 11611 return -1; 11612 size = arg_data->size; 11613 /* Bit-mask fill is not supported. */ 11614 if (arg_data->mask || size < len + 1) 11615 goto error; 11616 if (!ctx->object) 11617 return len; 11618 buf = (uint8_t *)ctx->object + arg_data->offset; 11619 strncpy(buf, str, len); 11620 if (ctx->objmask) 11621 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11622 return len; 11623 error: 11624 push_args(ctx, arg_data); 11625 return -1; 11626 } 11627 11628 /** 11629 * Parse a MAC address. 11630 * 11631 * Last argument (ctx->args) is retrieved to determine storage size and 11632 * location. 11633 */ 11634 static int 11635 parse_mac_addr(struct context *ctx, const struct token *token, 11636 const char *str, unsigned int len, 11637 void *buf, unsigned int size) 11638 { 11639 const struct arg *arg = pop_args(ctx); 11640 struct rte_ether_addr tmp; 11641 int ret; 11642 11643 (void)token; 11644 /* Argument is expected. */ 11645 if (!arg) 11646 return -1; 11647 size = arg->size; 11648 /* Bit-mask fill is not supported. */ 11649 if (arg->mask || size != sizeof(tmp)) 11650 goto error; 11651 /* Only network endian is supported. */ 11652 if (!arg->hton) 11653 goto error; 11654 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 11655 if (ret < 0 || (unsigned int)ret != len) 11656 goto error; 11657 if (!ctx->object) 11658 return len; 11659 buf = (uint8_t *)ctx->object + arg->offset; 11660 memcpy(buf, &tmp, size); 11661 if (ctx->objmask) 11662 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11663 return len; 11664 error: 11665 push_args(ctx, arg); 11666 return -1; 11667 } 11668 11669 /** 11670 * Parse an IPv4 address. 11671 * 11672 * Last argument (ctx->args) is retrieved to determine storage size and 11673 * location. 11674 */ 11675 static int 11676 parse_ipv4_addr(struct context *ctx, const struct token *token, 11677 const char *str, unsigned int len, 11678 void *buf, unsigned int size) 11679 { 11680 const struct arg *arg = pop_args(ctx); 11681 char str2[len + 1]; 11682 struct in_addr tmp; 11683 int ret; 11684 11685 /* Argument is expected. */ 11686 if (!arg) 11687 return -1; 11688 size = arg->size; 11689 /* Bit-mask fill is not supported. */ 11690 if (arg->mask || size != sizeof(tmp)) 11691 goto error; 11692 /* Only network endian is supported. */ 11693 if (!arg->hton) 11694 goto error; 11695 memcpy(str2, str, len); 11696 str2[len] = '\0'; 11697 ret = inet_pton(AF_INET, str2, &tmp); 11698 if (ret != 1) { 11699 /* Attempt integer parsing. */ 11700 push_args(ctx, arg); 11701 return parse_int(ctx, token, str, len, buf, size); 11702 } 11703 if (!ctx->object) 11704 return len; 11705 buf = (uint8_t *)ctx->object + arg->offset; 11706 memcpy(buf, &tmp, size); 11707 if (ctx->objmask) 11708 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11709 return len; 11710 error: 11711 push_args(ctx, arg); 11712 return -1; 11713 } 11714 11715 /** 11716 * Parse an IPv6 address. 11717 * 11718 * Last argument (ctx->args) is retrieved to determine storage size and 11719 * location. 11720 */ 11721 static int 11722 parse_ipv6_addr(struct context *ctx, const struct token *token, 11723 const char *str, unsigned int len, 11724 void *buf, unsigned int size) 11725 { 11726 const struct arg *arg = pop_args(ctx); 11727 char str2[len + 1]; 11728 struct in6_addr tmp; 11729 int ret; 11730 11731 (void)token; 11732 /* Argument is expected. */ 11733 if (!arg) 11734 return -1; 11735 size = arg->size; 11736 /* Bit-mask fill is not supported. */ 11737 if (arg->mask || size != sizeof(tmp)) 11738 goto error; 11739 /* Only network endian is supported. */ 11740 if (!arg->hton) 11741 goto error; 11742 memcpy(str2, str, len); 11743 str2[len] = '\0'; 11744 ret = inet_pton(AF_INET6, str2, &tmp); 11745 if (ret != 1) 11746 goto error; 11747 if (!ctx->object) 11748 return len; 11749 buf = (uint8_t *)ctx->object + arg->offset; 11750 memcpy(buf, &tmp, size); 11751 if (ctx->objmask) 11752 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11753 return len; 11754 error: 11755 push_args(ctx, arg); 11756 return -1; 11757 } 11758 11759 /** Boolean values (even indices stand for false). */ 11760 static const char *const boolean_name[] = { 11761 "0", "1", 11762 "false", "true", 11763 "no", "yes", 11764 "N", "Y", 11765 "off", "on", 11766 NULL, 11767 }; 11768 11769 /** 11770 * Parse a boolean value. 11771 * 11772 * Last argument (ctx->args) is retrieved to determine storage size and 11773 * location. 11774 */ 11775 static int 11776 parse_boolean(struct context *ctx, const struct token *token, 11777 const char *str, unsigned int len, 11778 void *buf, unsigned int size) 11779 { 11780 const struct arg *arg = pop_args(ctx); 11781 unsigned int i; 11782 int ret; 11783 11784 /* Argument is expected. */ 11785 if (!arg) 11786 return -1; 11787 for (i = 0; boolean_name[i]; ++i) 11788 if (!strcmp_partial(boolean_name[i], str, len)) 11789 break; 11790 /* Process token as integer. */ 11791 if (boolean_name[i]) 11792 str = i & 1 ? "1" : "0"; 11793 push_args(ctx, arg); 11794 ret = parse_int(ctx, token, str, strlen(str), buf, size); 11795 return ret > 0 ? (int)len : ret; 11796 } 11797 11798 /** Parse port and update context. */ 11799 static int 11800 parse_port(struct context *ctx, const struct token *token, 11801 const char *str, unsigned int len, 11802 void *buf, unsigned int size) 11803 { 11804 struct buffer *out = &(struct buffer){ .port = 0 }; 11805 int ret; 11806 11807 if (buf) 11808 out = buf; 11809 else { 11810 ctx->objdata = 0; 11811 ctx->object = out; 11812 ctx->objmask = NULL; 11813 size = sizeof(*out); 11814 } 11815 ret = parse_int(ctx, token, str, len, out, size); 11816 if (ret >= 0) 11817 ctx->port = out->port; 11818 if (!buf) 11819 ctx->object = NULL; 11820 return ret; 11821 } 11822 11823 /** Parse tokens for shared indirect actions. */ 11824 static int 11825 parse_ia_port(struct context *ctx, const struct token *token, 11826 const char *str, unsigned int len, 11827 void *buf, unsigned int size) 11828 { 11829 struct rte_flow_action *action = ctx->object; 11830 uint32_t id; 11831 int ret; 11832 11833 (void)buf; 11834 (void)size; 11835 ctx->objdata = 0; 11836 ctx->object = &id; 11837 ctx->objmask = NULL; 11838 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11839 ctx->object = action; 11840 if (ret != (int)len) 11841 return ret; 11842 /* set indirect action */ 11843 if (action) 11844 action->conf = (void *)(uintptr_t)id; 11845 return ret; 11846 } 11847 11848 static int 11849 parse_ia_id2ptr(struct context *ctx, const struct token *token, 11850 const char *str, unsigned int len, 11851 void *buf, unsigned int size) 11852 { 11853 struct rte_flow_action *action = ctx->object; 11854 uint32_t id; 11855 int ret; 11856 11857 (void)buf; 11858 (void)size; 11859 ctx->objdata = 0; 11860 ctx->object = &id; 11861 ctx->objmask = NULL; 11862 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11863 ctx->object = action; 11864 if (ret != (int)len) 11865 return ret; 11866 /* set indirect action */ 11867 if (action) { 11868 portid_t port_id = ctx->port; 11869 if (ctx->prev == INDIRECT_ACTION_PORT) 11870 port_id = (portid_t)(uintptr_t)action->conf; 11871 action->conf = port_action_handle_get_by_id(port_id, id); 11872 ret = (action->conf) ? ret : -1; 11873 } 11874 return ret; 11875 } 11876 11877 static int 11878 parse_indlst_id2ptr(struct context *ctx, const struct token *token, 11879 const char *str, unsigned int len, 11880 __rte_unused void *buf, __rte_unused unsigned int size) 11881 { 11882 struct rte_flow_action *action = ctx->object; 11883 struct rte_flow_action_indirect_list *action_conf; 11884 const struct indlst_conf *indlst_conf; 11885 uint32_t id; 11886 int ret; 11887 11888 if (!action) 11889 return -1; 11890 ctx->objdata = 0; 11891 ctx->object = &id; 11892 ctx->objmask = NULL; 11893 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11894 if (ret != (int)len) 11895 return ret; 11896 ctx->object = action; 11897 action_conf = (void *)(uintptr_t)action->conf; 11898 action_conf->conf = NULL; 11899 switch (ctx->curr) { 11900 case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: 11901 action_conf->handle = (typeof(action_conf->handle)) 11902 port_action_handle_get_by_id(ctx->port, id); 11903 if (!action_conf->handle) { 11904 printf("no indirect list handle for id %u\n", id); 11905 return -1; 11906 } 11907 break; 11908 case INDIRECT_LIST_ACTION_ID2PTR_CONF: 11909 indlst_conf = indirect_action_list_conf_get(id); 11910 if (!indlst_conf) 11911 return -1; 11912 action_conf->conf = (const void **)indlst_conf->conf; 11913 break; 11914 default: 11915 break; 11916 } 11917 return ret; 11918 } 11919 11920 static int 11921 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 11922 const char *str, unsigned int len, 11923 void *buf, unsigned int size) 11924 { 11925 struct rte_flow_action *action = ctx->object; 11926 struct rte_flow_action_meter_mark *meter; 11927 struct rte_flow_meter_profile *profile = NULL; 11928 uint32_t id = 0; 11929 int ret; 11930 11931 (void)buf; 11932 (void)size; 11933 ctx->objdata = 0; 11934 ctx->object = &id; 11935 ctx->objmask = NULL; 11936 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11937 ctx->object = action; 11938 if (ret != (int)len) 11939 return ret; 11940 /* set meter profile */ 11941 if (action) { 11942 meter = (struct rte_flow_action_meter_mark *) 11943 (uintptr_t)(action->conf); 11944 profile = port_meter_profile_get_by_id(ctx->port, id); 11945 meter->profile = profile; 11946 ret = (profile) ? ret : -1; 11947 } 11948 return ret; 11949 } 11950 11951 static int 11952 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 11953 const char *str, unsigned int len, 11954 void *buf, unsigned int size) 11955 { 11956 struct rte_flow_action *action = ctx->object; 11957 struct rte_flow_action_meter_mark *meter; 11958 struct rte_flow_meter_policy *policy = NULL; 11959 uint32_t id = 0; 11960 int ret; 11961 11962 (void)buf; 11963 (void)size; 11964 ctx->objdata = 0; 11965 ctx->object = &id; 11966 ctx->objmask = NULL; 11967 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11968 ctx->object = action; 11969 if (ret != (int)len) 11970 return ret; 11971 /* set meter policy */ 11972 if (action) { 11973 meter = (struct rte_flow_action_meter_mark *) 11974 (uintptr_t)(action->conf); 11975 policy = port_meter_policy_get_by_id(ctx->port, id); 11976 meter->policy = policy; 11977 ret = (policy) ? ret : -1; 11978 } 11979 return ret; 11980 } 11981 11982 /** Parse set command, initialize output buffer for subsequent tokens. */ 11983 static int 11984 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 11985 const char *str, unsigned int len, 11986 void *buf, unsigned int size) 11987 { 11988 struct buffer *out = buf; 11989 11990 /* Token name must match. */ 11991 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11992 return -1; 11993 /* Nothing else to do if there is no buffer. */ 11994 if (!out) 11995 return len; 11996 /* Make sure buffer is large enough. */ 11997 if (size < sizeof(*out)) 11998 return -1; 11999 ctx->objdata = 0; 12000 ctx->objmask = NULL; 12001 ctx->object = out; 12002 if (!out->command) 12003 return -1; 12004 out->command = ctx->curr; 12005 /* For encap/decap we need is pattern */ 12006 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12007 sizeof(double)); 12008 return len; 12009 } 12010 12011 /** Parse set command, initialize output buffer for subsequent tokens. */ 12012 static int 12013 parse_set_sample_action(struct context *ctx, const struct token *token, 12014 const char *str, unsigned int len, 12015 void *buf, unsigned int size) 12016 { 12017 struct buffer *out = buf; 12018 12019 /* Token name must match. */ 12020 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12021 return -1; 12022 /* Nothing else to do if there is no buffer. */ 12023 if (!out) 12024 return len; 12025 /* Make sure buffer is large enough. */ 12026 if (size < sizeof(*out)) 12027 return -1; 12028 ctx->objdata = 0; 12029 ctx->objmask = NULL; 12030 ctx->object = out; 12031 if (!out->command) 12032 return -1; 12033 out->command = ctx->curr; 12034 /* For sampler we need is actions */ 12035 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12036 sizeof(double)); 12037 return len; 12038 } 12039 12040 /** Parse set command, initialize output buffer for subsequent tokens. */ 12041 static int 12042 parse_set_ipv6_ext_action(struct context *ctx, const struct token *token, 12043 const char *str, unsigned int len, 12044 void *buf, unsigned int size) 12045 { 12046 struct buffer *out = buf; 12047 12048 /* Token name must match. */ 12049 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12050 return -1; 12051 /* Nothing else to do if there is no buffer. */ 12052 if (!out) 12053 return len; 12054 /* Make sure buffer is large enough. */ 12055 if (size < sizeof(*out)) 12056 return -1; 12057 ctx->objdata = 0; 12058 ctx->objmask = NULL; 12059 ctx->object = out; 12060 if (!out->command) 12061 return -1; 12062 out->command = ctx->curr; 12063 /* For ipv6_ext_push/remove we need is pattern */ 12064 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12065 sizeof(double)); 12066 return len; 12067 } 12068 12069 /** 12070 * Parse set raw_encap/raw_decap command, 12071 * initialize output buffer for subsequent tokens. 12072 */ 12073 static int 12074 parse_set_init(struct context *ctx, const struct token *token, 12075 const char *str, unsigned int len, 12076 void *buf, unsigned int size) 12077 { 12078 struct buffer *out = buf; 12079 12080 /* Token name must match. */ 12081 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12082 return -1; 12083 /* Nothing else to do if there is no buffer. */ 12084 if (!out) 12085 return len; 12086 /* Make sure buffer is large enough. */ 12087 if (size < sizeof(*out)) 12088 return -1; 12089 /* Initialize buffer. */ 12090 memset(out, 0x00, sizeof(*out)); 12091 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 12092 ctx->objdata = 0; 12093 ctx->object = out; 12094 ctx->objmask = NULL; 12095 if (!out->command) { 12096 if (ctx->curr != SET) 12097 return -1; 12098 if (sizeof(*out) > size) 12099 return -1; 12100 out->command = ctx->curr; 12101 out->args.vc.data = (uint8_t *)out + size; 12102 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12103 sizeof(double)); 12104 } 12105 return len; 12106 } 12107 12108 /* 12109 * Replace testpmd handles in a flex flow item with real values. 12110 */ 12111 static int 12112 parse_flex_handle(struct context *ctx, const struct token *token, 12113 const char *str, unsigned int len, 12114 void *buf, unsigned int size) 12115 { 12116 struct rte_flow_item_flex *spec, *mask; 12117 const struct rte_flow_item_flex *src_spec, *src_mask; 12118 const struct arg *arg = pop_args(ctx); 12119 uint32_t offset; 12120 uint16_t handle; 12121 int ret; 12122 12123 if (!arg) { 12124 printf("Bad environment\n"); 12125 return -1; 12126 } 12127 offset = arg->offset; 12128 push_args(ctx, arg); 12129 ret = parse_int(ctx, token, str, len, buf, size); 12130 if (ret <= 0 || !ctx->object) 12131 return ret; 12132 if (ctx->port >= RTE_MAX_ETHPORTS) { 12133 printf("Bad port\n"); 12134 return -1; 12135 } 12136 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 12137 const struct flex_item *fp; 12138 spec = ctx->object; 12139 handle = (uint16_t)(uintptr_t)spec->handle; 12140 if (handle >= FLEX_MAX_PARSERS_NUM) { 12141 printf("Bad flex item handle\n"); 12142 return -1; 12143 } 12144 fp = flex_items[ctx->port][handle]; 12145 if (!fp) { 12146 printf("Bad flex item handle\n"); 12147 return -1; 12148 } 12149 spec->handle = fp->flex_handle; 12150 mask = spec + 2; /* spec, last, mask */ 12151 mask->handle = fp->flex_handle; 12152 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 12153 handle = (uint16_t)(uintptr_t) 12154 ((struct rte_flow_item_flex *)ctx->object)->pattern; 12155 if (handle >= FLEX_MAX_PATTERNS_NUM) { 12156 printf("Bad pattern handle\n"); 12157 return -1; 12158 } 12159 src_spec = &flex_patterns[handle].spec; 12160 src_mask = &flex_patterns[handle].mask; 12161 spec = ctx->object; 12162 mask = spec + 2; /* spec, last, mask */ 12163 /* fill flow rule spec and mask parameters */ 12164 spec->length = src_spec->length; 12165 spec->pattern = src_spec->pattern; 12166 mask->length = src_mask->length; 12167 mask->pattern = src_mask->pattern; 12168 } else { 12169 printf("Bad arguments - unknown flex item offset\n"); 12170 return -1; 12171 } 12172 return ret; 12173 } 12174 12175 /** Parse Meter color name */ 12176 static int 12177 parse_meter_color(struct context *ctx, const struct token *token, 12178 const char *str, unsigned int len, void *buf, 12179 unsigned int size) 12180 { 12181 struct rte_flow_item_meter_color *meter_color; 12182 unsigned int i; 12183 12184 (void)token; 12185 (void)buf; 12186 (void)size; 12187 for (i = 0; meter_colors[i]; ++i) 12188 if (!strcmp_partial(meter_colors[i], str, len)) 12189 break; 12190 if (!meter_colors[i]) 12191 return -1; 12192 if (!ctx->object) 12193 return len; 12194 meter_color = ctx->object; 12195 meter_color->color = (enum rte_color)i; 12196 return len; 12197 } 12198 12199 /** Parse Insertion Table Type name */ 12200 static int 12201 parse_insertion_table_type(struct context *ctx, const struct token *token, 12202 const char *str, unsigned int len, void *buf, 12203 unsigned int size) 12204 { 12205 const struct arg *arg = pop_args(ctx); 12206 unsigned int i; 12207 char tmp[2]; 12208 int ret; 12209 12210 (void)size; 12211 /* Argument is expected. */ 12212 if (!arg) 12213 return -1; 12214 for (i = 0; table_insertion_types[i]; ++i) 12215 if (!strcmp_partial(table_insertion_types[i], str, len)) 12216 break; 12217 if (!table_insertion_types[i]) 12218 return -1; 12219 push_args(ctx, arg); 12220 snprintf(tmp, sizeof(tmp), "%u", i); 12221 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12222 return ret > 0 ? (int)len : ret; 12223 } 12224 12225 /** Parse Hash Calculation Table Type name */ 12226 static int 12227 parse_hash_table_type(struct context *ctx, const struct token *token, 12228 const char *str, unsigned int len, void *buf, 12229 unsigned int size) 12230 { 12231 const struct arg *arg = pop_args(ctx); 12232 unsigned int i; 12233 char tmp[2]; 12234 int ret; 12235 12236 (void)size; 12237 /* Argument is expected. */ 12238 if (!arg) 12239 return -1; 12240 for (i = 0; table_hash_funcs[i]; ++i) 12241 if (!strcmp_partial(table_hash_funcs[i], str, len)) 12242 break; 12243 if (!table_hash_funcs[i]) 12244 return -1; 12245 push_args(ctx, arg); 12246 snprintf(tmp, sizeof(tmp), "%u", i); 12247 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12248 return ret > 0 ? (int)len : ret; 12249 } 12250 12251 static int 12252 parse_name_to_index(struct context *ctx, const struct token *token, 12253 const char *str, unsigned int len, void *buf, 12254 unsigned int size, 12255 const char *const names[], size_t names_size, uint32_t *dst) 12256 { 12257 int ret; 12258 uint32_t i; 12259 12260 RTE_SET_USED(token); 12261 RTE_SET_USED(buf); 12262 RTE_SET_USED(size); 12263 if (!ctx->object) 12264 return len; 12265 for (i = 0; i < names_size; i++) { 12266 if (!names[i]) 12267 continue; 12268 ret = strcmp_partial(names[i], str, 12269 RTE_MIN(len, strlen(names[i]))); 12270 if (!ret) { 12271 *dst = i; 12272 return len; 12273 } 12274 } 12275 return -1; 12276 } 12277 12278 static const char *const quota_mode_names[] = { 12279 NULL, 12280 [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", 12281 [RTE_FLOW_QUOTA_MODE_L2] = "l2", 12282 [RTE_FLOW_QUOTA_MODE_L3] = "l3" 12283 }; 12284 12285 static const char *const quota_state_names[] = { 12286 [RTE_FLOW_QUOTA_STATE_PASS] = "pass", 12287 [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" 12288 }; 12289 12290 static const char *const quota_update_names[] = { 12291 [RTE_FLOW_UPDATE_QUOTA_SET] = "set", 12292 [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" 12293 }; 12294 12295 static const char *const query_update_mode_names[] = { 12296 [RTE_FLOW_QU_QUERY_FIRST] = "query_first", 12297 [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" 12298 }; 12299 12300 static int 12301 parse_quota_state_name(struct context *ctx, const struct token *token, 12302 const char *str, unsigned int len, void *buf, 12303 unsigned int size) 12304 { 12305 struct rte_flow_item_quota *quota = ctx->object; 12306 12307 return parse_name_to_index(ctx, token, str, len, buf, size, 12308 quota_state_names, 12309 RTE_DIM(quota_state_names), 12310 (uint32_t *)"a->state); 12311 } 12312 12313 static int 12314 parse_quota_mode_name(struct context *ctx, const struct token *token, 12315 const char *str, unsigned int len, void *buf, 12316 unsigned int size) 12317 { 12318 struct rte_flow_action_quota *quota = ctx->object; 12319 12320 return parse_name_to_index(ctx, token, str, len, buf, size, 12321 quota_mode_names, 12322 RTE_DIM(quota_mode_names), 12323 (uint32_t *)"a->mode); 12324 } 12325 12326 static int 12327 parse_quota_update_name(struct context *ctx, const struct token *token, 12328 const char *str, unsigned int len, void *buf, 12329 unsigned int size) 12330 { 12331 struct rte_flow_update_quota *update = ctx->object; 12332 12333 return parse_name_to_index(ctx, token, str, len, buf, size, 12334 quota_update_names, 12335 RTE_DIM(quota_update_names), 12336 (uint32_t *)&update->op); 12337 } 12338 12339 static int 12340 parse_qu_mode_name(struct context *ctx, const struct token *token, 12341 const char *str, unsigned int len, void *buf, 12342 unsigned int size) 12343 { 12344 struct buffer *out = ctx->object; 12345 12346 return parse_name_to_index(ctx, token, str, len, buf, size, 12347 query_update_mode_names, 12348 RTE_DIM(query_update_mode_names), 12349 (uint32_t *)&out->args.ia.qu_mode); 12350 } 12351 12352 /** No completion. */ 12353 static int 12354 comp_none(struct context *ctx, const struct token *token, 12355 unsigned int ent, char *buf, unsigned int size) 12356 { 12357 (void)ctx; 12358 (void)token; 12359 (void)ent; 12360 (void)buf; 12361 (void)size; 12362 return 0; 12363 } 12364 12365 /** Complete boolean values. */ 12366 static int 12367 comp_boolean(struct context *ctx, const struct token *token, 12368 unsigned int ent, char *buf, unsigned int size) 12369 { 12370 unsigned int i; 12371 12372 (void)ctx; 12373 (void)token; 12374 for (i = 0; boolean_name[i]; ++i) 12375 if (buf && i == ent) 12376 return strlcpy(buf, boolean_name[i], size); 12377 if (buf) 12378 return -1; 12379 return i; 12380 } 12381 12382 /** Complete action names. */ 12383 static int 12384 comp_action(struct context *ctx, const struct token *token, 12385 unsigned int ent, char *buf, unsigned int size) 12386 { 12387 unsigned int i; 12388 12389 (void)ctx; 12390 (void)token; 12391 for (i = 0; next_action[i]; ++i) 12392 if (buf && i == ent) 12393 return strlcpy(buf, token_list[next_action[i]].name, 12394 size); 12395 if (buf) 12396 return -1; 12397 return i; 12398 } 12399 12400 /** Complete available ports. */ 12401 static int 12402 comp_port(struct context *ctx, const struct token *token, 12403 unsigned int ent, char *buf, unsigned int size) 12404 { 12405 unsigned int i = 0; 12406 portid_t p; 12407 12408 (void)ctx; 12409 (void)token; 12410 RTE_ETH_FOREACH_DEV(p) { 12411 if (buf && i == ent) 12412 return snprintf(buf, size, "%u", p); 12413 ++i; 12414 } 12415 if (buf) 12416 return -1; 12417 return i; 12418 } 12419 12420 /** Complete available rule IDs. */ 12421 static int 12422 comp_rule_id(struct context *ctx, const struct token *token, 12423 unsigned int ent, char *buf, unsigned int size) 12424 { 12425 unsigned int i = 0; 12426 struct rte_port *port; 12427 struct port_flow *pf; 12428 12429 (void)token; 12430 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12431 ctx->port == (portid_t)RTE_PORT_ALL) 12432 return -1; 12433 port = &ports[ctx->port]; 12434 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 12435 if (buf && i == ent) 12436 return snprintf(buf, size, "%"PRIu64, pf->id); 12437 ++i; 12438 } 12439 if (buf) 12440 return -1; 12441 return i; 12442 } 12443 12444 /** Complete operation for compare match item. */ 12445 static int 12446 comp_set_compare_op(struct context *ctx, const struct token *token, 12447 unsigned int ent, char *buf, unsigned int size) 12448 { 12449 RTE_SET_USED(ctx); 12450 RTE_SET_USED(token); 12451 if (!buf) 12452 return RTE_DIM(compare_ops); 12453 if (ent < RTE_DIM(compare_ops) - 1) 12454 return strlcpy(buf, compare_ops[ent], size); 12455 return -1; 12456 } 12457 12458 /** Complete field id for compare match item. */ 12459 static int 12460 comp_set_compare_field_id(struct context *ctx, const struct token *token, 12461 unsigned int ent, char *buf, unsigned int size) 12462 { 12463 const char *name; 12464 12465 RTE_SET_USED(token); 12466 if (!buf) 12467 return RTE_DIM(flow_field_ids); 12468 if (ent >= RTE_DIM(flow_field_ids) - 1) 12469 return -1; 12470 name = flow_field_ids[ent]; 12471 if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE || 12472 (strcmp(name, "pointer") && strcmp(name, "value"))) 12473 return strlcpy(buf, name, size); 12474 return -1; 12475 } 12476 12477 /** Complete type field for RSS action. */ 12478 static int 12479 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 12480 unsigned int ent, char *buf, unsigned int size) 12481 { 12482 unsigned int i; 12483 12484 (void)ctx; 12485 (void)token; 12486 for (i = 0; rss_type_table[i].str; ++i) 12487 ; 12488 if (!buf) 12489 return i + 1; 12490 if (ent < i) 12491 return strlcpy(buf, rss_type_table[ent].str, size); 12492 if (ent == i) 12493 return snprintf(buf, size, "end"); 12494 return -1; 12495 } 12496 12497 /** Complete queue field for RSS action. */ 12498 static int 12499 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 12500 unsigned int ent, char *buf, unsigned int size) 12501 { 12502 (void)ctx; 12503 (void)token; 12504 if (!buf) 12505 return nb_rxq + 1; 12506 if (ent < nb_rxq) 12507 return snprintf(buf, size, "%u", ent); 12508 if (ent == nb_rxq) 12509 return snprintf(buf, size, "end"); 12510 return -1; 12511 } 12512 12513 /** Complete index number for set raw_encap/raw_decap commands. */ 12514 static int 12515 comp_set_raw_index(struct context *ctx, const struct token *token, 12516 unsigned int ent, char *buf, unsigned int size) 12517 { 12518 uint16_t idx = 0; 12519 uint16_t nb = 0; 12520 12521 RTE_SET_USED(ctx); 12522 RTE_SET_USED(token); 12523 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 12524 if (buf && idx == ent) 12525 return snprintf(buf, size, "%u", idx); 12526 ++nb; 12527 } 12528 return nb; 12529 } 12530 12531 /** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ 12532 static int 12533 comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 12534 unsigned int ent, char *buf, unsigned int size) 12535 { 12536 uint16_t idx = 0; 12537 uint16_t nb = 0; 12538 12539 RTE_SET_USED(ctx); 12540 RTE_SET_USED(token); 12541 for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { 12542 if (buf && idx == ent) 12543 return snprintf(buf, size, "%u", idx); 12544 ++nb; 12545 } 12546 return nb; 12547 } 12548 12549 /** Complete index number for set raw_encap/raw_decap commands. */ 12550 static int 12551 comp_set_sample_index(struct context *ctx, const struct token *token, 12552 unsigned int ent, char *buf, unsigned int size) 12553 { 12554 uint16_t idx = 0; 12555 uint16_t nb = 0; 12556 12557 RTE_SET_USED(ctx); 12558 RTE_SET_USED(token); 12559 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 12560 if (buf && idx == ent) 12561 return snprintf(buf, size, "%u", idx); 12562 ++nb; 12563 } 12564 return nb; 12565 } 12566 12567 /** Complete operation for modify_field command. */ 12568 static int 12569 comp_set_modify_field_op(struct context *ctx, const struct token *token, 12570 unsigned int ent, char *buf, unsigned int size) 12571 { 12572 RTE_SET_USED(ctx); 12573 RTE_SET_USED(token); 12574 if (!buf) 12575 return RTE_DIM(modify_field_ops); 12576 if (ent < RTE_DIM(modify_field_ops) - 1) 12577 return strlcpy(buf, modify_field_ops[ent], size); 12578 return -1; 12579 } 12580 12581 /** Complete field id for modify_field command. */ 12582 static int 12583 comp_set_modify_field_id(struct context *ctx, const struct token *token, 12584 unsigned int ent, char *buf, unsigned int size) 12585 { 12586 const char *name; 12587 12588 RTE_SET_USED(token); 12589 if (!buf) 12590 return RTE_DIM(flow_field_ids); 12591 if (ent >= RTE_DIM(flow_field_ids) - 1) 12592 return -1; 12593 name = flow_field_ids[ent]; 12594 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 12595 (strcmp(name, "pointer") && strcmp(name, "value"))) 12596 return strlcpy(buf, name, size); 12597 return -1; 12598 } 12599 12600 /** Complete available pattern template IDs. */ 12601 static int 12602 comp_pattern_template_id(struct context *ctx, const struct token *token, 12603 unsigned int ent, char *buf, unsigned int size) 12604 { 12605 unsigned int i = 0; 12606 struct rte_port *port; 12607 struct port_template *pt; 12608 12609 (void)token; 12610 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12611 ctx->port == (portid_t)RTE_PORT_ALL) 12612 return -1; 12613 port = &ports[ctx->port]; 12614 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 12615 if (buf && i == ent) 12616 return snprintf(buf, size, "%u", pt->id); 12617 ++i; 12618 } 12619 if (buf) 12620 return -1; 12621 return i; 12622 } 12623 12624 /** Complete available actions template IDs. */ 12625 static int 12626 comp_actions_template_id(struct context *ctx, const struct token *token, 12627 unsigned int ent, char *buf, unsigned int size) 12628 { 12629 unsigned int i = 0; 12630 struct rte_port *port; 12631 struct port_template *pt; 12632 12633 (void)token; 12634 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12635 ctx->port == (portid_t)RTE_PORT_ALL) 12636 return -1; 12637 port = &ports[ctx->port]; 12638 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 12639 if (buf && i == ent) 12640 return snprintf(buf, size, "%u", pt->id); 12641 ++i; 12642 } 12643 if (buf) 12644 return -1; 12645 return i; 12646 } 12647 12648 /** Complete available table IDs. */ 12649 static int 12650 comp_table_id(struct context *ctx, const struct token *token, 12651 unsigned int ent, char *buf, unsigned int size) 12652 { 12653 unsigned int i = 0; 12654 struct rte_port *port; 12655 struct port_table *pt; 12656 12657 (void)token; 12658 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12659 ctx->port == (portid_t)RTE_PORT_ALL) 12660 return -1; 12661 port = &ports[ctx->port]; 12662 for (pt = port->table_list; pt != NULL; pt = pt->next) { 12663 if (buf && i == ent) 12664 return snprintf(buf, size, "%u", pt->id); 12665 ++i; 12666 } 12667 if (buf) 12668 return -1; 12669 return i; 12670 } 12671 12672 /** Complete available queue IDs. */ 12673 static int 12674 comp_queue_id(struct context *ctx, const struct token *token, 12675 unsigned int ent, char *buf, unsigned int size) 12676 { 12677 unsigned int i = 0; 12678 struct rte_port *port; 12679 12680 (void)token; 12681 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12682 ctx->port == (portid_t)RTE_PORT_ALL) 12683 return -1; 12684 port = &ports[ctx->port]; 12685 for (i = 0; i < port->queue_nb; i++) { 12686 if (buf && i == ent) 12687 return snprintf(buf, size, "%u", i); 12688 } 12689 if (buf) 12690 return -1; 12691 return i; 12692 } 12693 12694 static int 12695 comp_names_to_index(struct context *ctx, const struct token *token, 12696 unsigned int ent, char *buf, unsigned int size, 12697 const char *const names[], size_t names_size) 12698 { 12699 RTE_SET_USED(ctx); 12700 RTE_SET_USED(token); 12701 if (!buf) 12702 return names_size; 12703 if (names[ent] && ent < names_size) 12704 return rte_strscpy(buf, names[ent], size); 12705 return -1; 12706 12707 } 12708 12709 /** Complete available Meter colors. */ 12710 static int 12711 comp_meter_color(struct context *ctx, const struct token *token, 12712 unsigned int ent, char *buf, unsigned int size) 12713 { 12714 RTE_SET_USED(ctx); 12715 RTE_SET_USED(token); 12716 if (!buf) 12717 return RTE_DIM(meter_colors); 12718 if (ent < RTE_DIM(meter_colors) - 1) 12719 return strlcpy(buf, meter_colors[ent], size); 12720 return -1; 12721 } 12722 12723 /** Complete available Insertion Table types. */ 12724 static int 12725 comp_insertion_table_type(struct context *ctx, const struct token *token, 12726 unsigned int ent, char *buf, unsigned int size) 12727 { 12728 RTE_SET_USED(ctx); 12729 RTE_SET_USED(token); 12730 if (!buf) 12731 return RTE_DIM(table_insertion_types); 12732 if (ent < RTE_DIM(table_insertion_types) - 1) 12733 return rte_strscpy(buf, table_insertion_types[ent], size); 12734 return -1; 12735 } 12736 12737 /** Complete available Hash Calculation Table types. */ 12738 static int 12739 comp_hash_table_type(struct context *ctx, const struct token *token, 12740 unsigned int ent, char *buf, unsigned int size) 12741 { 12742 RTE_SET_USED(ctx); 12743 RTE_SET_USED(token); 12744 if (!buf) 12745 return RTE_DIM(table_hash_funcs); 12746 if (ent < RTE_DIM(table_hash_funcs) - 1) 12747 return rte_strscpy(buf, table_hash_funcs[ent], size); 12748 return -1; 12749 } 12750 12751 static int 12752 comp_quota_state_name(struct context *ctx, const struct token *token, 12753 unsigned int ent, char *buf, unsigned int size) 12754 { 12755 return comp_names_to_index(ctx, token, ent, buf, size, 12756 quota_state_names, 12757 RTE_DIM(quota_state_names)); 12758 } 12759 12760 static int 12761 comp_quota_mode_name(struct context *ctx, const struct token *token, 12762 unsigned int ent, char *buf, unsigned int size) 12763 { 12764 return comp_names_to_index(ctx, token, ent, buf, size, 12765 quota_mode_names, 12766 RTE_DIM(quota_mode_names)); 12767 } 12768 12769 static int 12770 comp_quota_update_name(struct context *ctx, const struct token *token, 12771 unsigned int ent, char *buf, unsigned int size) 12772 { 12773 return comp_names_to_index(ctx, token, ent, buf, size, 12774 quota_update_names, 12775 RTE_DIM(quota_update_names)); 12776 } 12777 12778 static int 12779 comp_qu_mode_name(struct context *ctx, const struct token *token, 12780 unsigned int ent, char *buf, unsigned int size) 12781 { 12782 return comp_names_to_index(ctx, token, ent, buf, size, 12783 query_update_mode_names, 12784 RTE_DIM(query_update_mode_names)); 12785 } 12786 12787 /** Internal context. */ 12788 static struct context cmd_flow_context; 12789 12790 /** Global parser instance (cmdline API). */ 12791 cmdline_parse_inst_t cmd_flow; 12792 cmdline_parse_inst_t cmd_set_raw; 12793 12794 /** Initialize context. */ 12795 static void 12796 cmd_flow_context_init(struct context *ctx) 12797 { 12798 /* A full memset() is not necessary. */ 12799 ctx->curr = ZERO; 12800 ctx->prev = ZERO; 12801 ctx->next_num = 0; 12802 ctx->args_num = 0; 12803 ctx->eol = 0; 12804 ctx->last = 0; 12805 ctx->port = 0; 12806 ctx->objdata = 0; 12807 ctx->object = NULL; 12808 ctx->objmask = NULL; 12809 } 12810 12811 /** Parse a token (cmdline API). */ 12812 static int 12813 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 12814 unsigned int size) 12815 { 12816 struct context *ctx = &cmd_flow_context; 12817 const struct token *token; 12818 const enum index *list; 12819 int len; 12820 int i; 12821 12822 (void)hdr; 12823 token = &token_list[ctx->curr]; 12824 /* Check argument length. */ 12825 ctx->eol = 0; 12826 ctx->last = 1; 12827 for (len = 0; src[len]; ++len) 12828 if (src[len] == '#' || isspace(src[len])) 12829 break; 12830 if (!len) 12831 return -1; 12832 /* Last argument and EOL detection. */ 12833 for (i = len; src[i]; ++i) 12834 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 12835 break; 12836 else if (!isspace(src[i])) { 12837 ctx->last = 0; 12838 break; 12839 } 12840 for (; src[i]; ++i) 12841 if (src[i] == '\r' || src[i] == '\n') { 12842 ctx->eol = 1; 12843 break; 12844 } 12845 /* Initialize context if necessary. */ 12846 if (!ctx->next_num) { 12847 if (!token->next) 12848 return 0; 12849 ctx->next[ctx->next_num++] = token->next[0]; 12850 } 12851 /* Process argument through candidates. */ 12852 ctx->prev = ctx->curr; 12853 list = ctx->next[ctx->next_num - 1]; 12854 for (i = 0; list[i]; ++i) { 12855 const struct token *next = &token_list[list[i]]; 12856 int tmp; 12857 12858 ctx->curr = list[i]; 12859 if (next->call) 12860 tmp = next->call(ctx, next, src, len, result, size); 12861 else 12862 tmp = parse_default(ctx, next, src, len, result, size); 12863 if (tmp == -1 || tmp != len) 12864 continue; 12865 token = next; 12866 break; 12867 } 12868 if (!list[i]) 12869 return -1; 12870 --ctx->next_num; 12871 /* Push subsequent tokens if any. */ 12872 if (token->next) 12873 for (i = 0; token->next[i]; ++i) { 12874 if (ctx->next_num == RTE_DIM(ctx->next)) 12875 return -1; 12876 ctx->next[ctx->next_num++] = token->next[i]; 12877 } 12878 /* Push arguments if any. */ 12879 if (token->args) 12880 for (i = 0; token->args[i]; ++i) { 12881 if (ctx->args_num == RTE_DIM(ctx->args)) 12882 return -1; 12883 ctx->args[ctx->args_num++] = token->args[i]; 12884 } 12885 return len; 12886 } 12887 12888 int 12889 flow_parse(const char *src, void *result, unsigned int size, 12890 struct rte_flow_attr **attr, 12891 struct rte_flow_item **pattern, struct rte_flow_action **actions) 12892 { 12893 int ret; 12894 struct context saved_flow_ctx = cmd_flow_context; 12895 12896 cmd_flow_context_init(&cmd_flow_context); 12897 do { 12898 ret = cmd_flow_parse(NULL, src, result, size); 12899 if (ret > 0) { 12900 src += ret; 12901 while (isspace(*src)) 12902 src++; 12903 } 12904 } while (ret > 0 && strlen(src)); 12905 cmd_flow_context = saved_flow_ctx; 12906 *attr = &((struct buffer *)result)->args.vc.attr; 12907 *pattern = ((struct buffer *)result)->args.vc.pattern; 12908 *actions = ((struct buffer *)result)->args.vc.actions; 12909 return (ret >= 0 && !strlen(src)) ? 0 : -1; 12910 } 12911 12912 /** Return number of completion entries (cmdline API). */ 12913 static int 12914 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 12915 { 12916 struct context *ctx = &cmd_flow_context; 12917 const struct token *token = &token_list[ctx->curr]; 12918 const enum index *list; 12919 int i; 12920 12921 (void)hdr; 12922 /* Count number of tokens in current list. */ 12923 if (ctx->next_num) 12924 list = ctx->next[ctx->next_num - 1]; 12925 else 12926 list = token->next[0]; 12927 for (i = 0; list[i]; ++i) 12928 ; 12929 if (!i) 12930 return 0; 12931 /* 12932 * If there is a single token, use its completion callback, otherwise 12933 * return the number of entries. 12934 */ 12935 token = &token_list[list[0]]; 12936 if (i == 1 && token->comp) { 12937 /* Save index for cmd_flow_get_help(). */ 12938 ctx->prev = list[0]; 12939 return token->comp(ctx, token, 0, NULL, 0); 12940 } 12941 return i; 12942 } 12943 12944 /** Return a completion entry (cmdline API). */ 12945 static int 12946 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 12947 char *dst, unsigned int size) 12948 { 12949 struct context *ctx = &cmd_flow_context; 12950 const struct token *token = &token_list[ctx->curr]; 12951 const enum index *list; 12952 int i; 12953 12954 (void)hdr; 12955 /* Count number of tokens in current list. */ 12956 if (ctx->next_num) 12957 list = ctx->next[ctx->next_num - 1]; 12958 else 12959 list = token->next[0]; 12960 for (i = 0; list[i]; ++i) 12961 ; 12962 if (!i) 12963 return -1; 12964 /* If there is a single token, use its completion callback. */ 12965 token = &token_list[list[0]]; 12966 if (i == 1 && token->comp) { 12967 /* Save index for cmd_flow_get_help(). */ 12968 ctx->prev = list[0]; 12969 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 12970 } 12971 /* Otherwise make sure the index is valid and use defaults. */ 12972 if (index >= i) 12973 return -1; 12974 token = &token_list[list[index]]; 12975 strlcpy(dst, token->name, size); 12976 /* Save index for cmd_flow_get_help(). */ 12977 ctx->prev = list[index]; 12978 return 0; 12979 } 12980 12981 /** Populate help strings for current token (cmdline API). */ 12982 static int 12983 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 12984 { 12985 struct context *ctx = &cmd_flow_context; 12986 const struct token *token = &token_list[ctx->prev]; 12987 12988 (void)hdr; 12989 if (!size) 12990 return -1; 12991 /* Set token type and update global help with details. */ 12992 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 12993 if (token->help) 12994 cmd_flow.help_str = token->help; 12995 else 12996 cmd_flow.help_str = token->name; 12997 return 0; 12998 } 12999 13000 /** Token definition template (cmdline API). */ 13001 static struct cmdline_token_hdr cmd_flow_token_hdr = { 13002 .ops = &(struct cmdline_token_ops){ 13003 .parse = cmd_flow_parse, 13004 .complete_get_nb = cmd_flow_complete_get_nb, 13005 .complete_get_elt = cmd_flow_complete_get_elt, 13006 .get_help = cmd_flow_get_help, 13007 }, 13008 .offset = 0, 13009 }; 13010 13011 /** Populate the next dynamic token. */ 13012 static void 13013 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 13014 cmdline_parse_token_hdr_t **hdr_inst) 13015 { 13016 struct context *ctx = &cmd_flow_context; 13017 13018 /* Always reinitialize context before requesting the first token. */ 13019 if (!(hdr_inst - cmd_flow.tokens)) 13020 cmd_flow_context_init(ctx); 13021 /* Return NULL when no more tokens are expected. */ 13022 if (!ctx->next_num && ctx->curr) { 13023 *hdr = NULL; 13024 return; 13025 } 13026 /* Determine if command should end here. */ 13027 if (ctx->eol && ctx->last && ctx->next_num) { 13028 const enum index *list = ctx->next[ctx->next_num - 1]; 13029 int i; 13030 13031 for (i = 0; list[i]; ++i) { 13032 if (list[i] != END) 13033 continue; 13034 *hdr = NULL; 13035 return; 13036 } 13037 } 13038 *hdr = &cmd_flow_token_hdr; 13039 } 13040 13041 static SLIST_HEAD(, indlst_conf) indlst_conf_head = 13042 SLIST_HEAD_INITIALIZER(); 13043 13044 static void 13045 indirect_action_flow_conf_create(const struct buffer *in) 13046 { 13047 int len, ret; 13048 uint32_t i; 13049 struct indlst_conf *indlst_conf = NULL; 13050 size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); 13051 struct rte_flow_action *src = in->args.vc.actions; 13052 13053 if (!in->args.vc.actions_n) 13054 goto end; 13055 len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); 13056 if (len <= 0) 13057 goto end; 13058 len = RTE_ALIGN(len, 16); 13059 13060 indlst_conf = calloc(1, base + len + 13061 in->args.vc.actions_n * sizeof(uintptr_t)); 13062 if (!indlst_conf) 13063 goto end; 13064 indlst_conf->id = in->args.vc.attr.group; 13065 indlst_conf->conf_num = in->args.vc.actions_n - 1; 13066 indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); 13067 ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, 13068 len, src, NULL); 13069 if (ret <= 0) { 13070 free(indlst_conf); 13071 indlst_conf = NULL; 13072 goto end; 13073 } 13074 indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); 13075 for (i = 0; i < indlst_conf->conf_num; i++) 13076 indlst_conf->conf[i] = indlst_conf->actions[i].conf; 13077 SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); 13078 end: 13079 if (indlst_conf) 13080 printf("created indirect action list configuration %u\n", 13081 in->args.vc.attr.group); 13082 else 13083 printf("cannot create indirect action list configuration %u\n", 13084 in->args.vc.attr.group); 13085 } 13086 13087 static const struct indlst_conf * 13088 indirect_action_list_conf_get(uint32_t conf_id) 13089 { 13090 const struct indlst_conf *conf; 13091 13092 SLIST_FOREACH(conf, &indlst_conf_head, next) { 13093 if (conf->id == conf_id) 13094 return conf; 13095 } 13096 return NULL; 13097 } 13098 13099 /** Dispatch parsed buffer to function calls. */ 13100 static void 13101 cmd_flow_parsed(const struct buffer *in) 13102 { 13103 switch (in->command) { 13104 case INFO: 13105 port_flow_get_info(in->port); 13106 break; 13107 case CONFIGURE: 13108 port_flow_configure(in->port, 13109 &in->args.configure.port_attr, 13110 in->args.configure.nb_queue, 13111 &in->args.configure.queue_attr); 13112 break; 13113 case PATTERN_TEMPLATE_CREATE: 13114 port_flow_pattern_template_create(in->port, 13115 in->args.vc.pat_templ_id, 13116 &((const struct rte_flow_pattern_template_attr) { 13117 .relaxed_matching = in->args.vc.attr.reserved, 13118 .ingress = in->args.vc.attr.ingress, 13119 .egress = in->args.vc.attr.egress, 13120 .transfer = in->args.vc.attr.transfer, 13121 }), 13122 in->args.vc.pattern); 13123 break; 13124 case PATTERN_TEMPLATE_DESTROY: 13125 port_flow_pattern_template_destroy(in->port, 13126 in->args.templ_destroy.template_id_n, 13127 in->args.templ_destroy.template_id); 13128 break; 13129 case ACTIONS_TEMPLATE_CREATE: 13130 port_flow_actions_template_create(in->port, 13131 in->args.vc.act_templ_id, 13132 &((const struct rte_flow_actions_template_attr) { 13133 .ingress = in->args.vc.attr.ingress, 13134 .egress = in->args.vc.attr.egress, 13135 .transfer = in->args.vc.attr.transfer, 13136 }), 13137 in->args.vc.actions, 13138 in->args.vc.masks); 13139 break; 13140 case ACTIONS_TEMPLATE_DESTROY: 13141 port_flow_actions_template_destroy(in->port, 13142 in->args.templ_destroy.template_id_n, 13143 in->args.templ_destroy.template_id); 13144 break; 13145 case TABLE_CREATE: 13146 port_flow_template_table_create(in->port, in->args.table.id, 13147 &in->args.table.attr, in->args.table.pat_templ_id_n, 13148 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 13149 in->args.table.act_templ_id); 13150 break; 13151 case TABLE_DESTROY: 13152 port_flow_template_table_destroy(in->port, 13153 in->args.table_destroy.table_id_n, 13154 in->args.table_destroy.table_id); 13155 break; 13156 case TABLE_RESIZE_COMPLETE: 13157 port_flow_template_table_resize_complete 13158 (in->port, in->args.table_destroy.table_id[0]); 13159 break; 13160 case GROUP_SET_MISS_ACTIONS: 13161 port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, 13162 in->args.vc.actions); 13163 break; 13164 case TABLE_RESIZE: 13165 port_flow_template_table_resize(in->port, in->args.table.id, 13166 in->args.table.attr.nb_flows); 13167 break; 13168 case QUEUE_CREATE: 13169 port_queue_flow_create(in->port, in->queue, in->postpone, 13170 in->args.vc.table_id, in->args.vc.rule_id, 13171 in->args.vc.pat_templ_id, in->args.vc.act_templ_id, 13172 in->args.vc.pattern, in->args.vc.actions); 13173 break; 13174 case QUEUE_DESTROY: 13175 port_queue_flow_destroy(in->port, in->queue, in->postpone, 13176 in->args.destroy.rule_n, 13177 in->args.destroy.rule); 13178 break; 13179 case QUEUE_FLOW_UPDATE_RESIZED: 13180 port_queue_flow_update_resized(in->port, in->queue, 13181 in->postpone, 13182 in->args.destroy.rule[0]); 13183 break; 13184 case QUEUE_UPDATE: 13185 port_queue_flow_update(in->port, in->queue, in->postpone, 13186 in->args.vc.rule_id, in->args.vc.act_templ_id, 13187 in->args.vc.actions); 13188 break; 13189 case PUSH: 13190 port_queue_flow_push(in->port, in->queue); 13191 break; 13192 case PULL: 13193 port_queue_flow_pull(in->port, in->queue); 13194 break; 13195 case HASH: 13196 if (!in->args.vc.encap_hash) 13197 port_flow_hash_calc(in->port, in->args.vc.table_id, 13198 in->args.vc.pat_templ_id, 13199 in->args.vc.pattern); 13200 else 13201 port_flow_hash_calc_encap(in->port, in->args.vc.field, 13202 in->args.vc.pattern); 13203 break; 13204 case QUEUE_AGED: 13205 port_queue_flow_aged(in->port, in->queue, 13206 in->args.aged.destroy); 13207 break; 13208 case QUEUE_INDIRECT_ACTION_CREATE: 13209 case QUEUE_INDIRECT_ACTION_LIST_CREATE: 13210 port_queue_action_handle_create( 13211 in->port, in->queue, in->postpone, 13212 in->args.vc.attr.group, 13213 &((const struct rte_flow_indir_action_conf) { 13214 .ingress = in->args.vc.attr.ingress, 13215 .egress = in->args.vc.attr.egress, 13216 .transfer = in->args.vc.attr.transfer, 13217 }), 13218 in->args.vc.actions); 13219 break; 13220 case QUEUE_INDIRECT_ACTION_DESTROY: 13221 port_queue_action_handle_destroy(in->port, 13222 in->queue, in->postpone, 13223 in->args.ia_destroy.action_id_n, 13224 in->args.ia_destroy.action_id); 13225 break; 13226 case QUEUE_INDIRECT_ACTION_UPDATE: 13227 port_queue_action_handle_update(in->port, 13228 in->queue, in->postpone, 13229 in->args.vc.attr.group, 13230 in->args.vc.actions); 13231 break; 13232 case QUEUE_INDIRECT_ACTION_QUERY: 13233 port_queue_action_handle_query(in->port, 13234 in->queue, in->postpone, 13235 in->args.ia.action_id); 13236 break; 13237 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 13238 port_queue_action_handle_query_update(in->port, in->queue, 13239 in->postpone, 13240 in->args.ia.action_id, 13241 in->args.ia.qu_mode, 13242 in->args.vc.actions); 13243 break; 13244 case INDIRECT_ACTION_CREATE: 13245 case INDIRECT_ACTION_LIST_CREATE: 13246 port_action_handle_create( 13247 in->port, in->args.vc.attr.group, 13248 in->command == INDIRECT_ACTION_LIST_CREATE, 13249 &((const struct rte_flow_indir_action_conf) { 13250 .ingress = in->args.vc.attr.ingress, 13251 .egress = in->args.vc.attr.egress, 13252 .transfer = in->args.vc.attr.transfer, 13253 }), 13254 in->args.vc.actions); 13255 break; 13256 case INDIRECT_ACTION_FLOW_CONF_CREATE: 13257 indirect_action_flow_conf_create(in); 13258 break; 13259 case INDIRECT_ACTION_DESTROY: 13260 port_action_handle_destroy(in->port, 13261 in->args.ia_destroy.action_id_n, 13262 in->args.ia_destroy.action_id); 13263 break; 13264 case INDIRECT_ACTION_UPDATE: 13265 port_action_handle_update(in->port, in->args.vc.attr.group, 13266 in->args.vc.actions); 13267 break; 13268 case INDIRECT_ACTION_QUERY: 13269 port_action_handle_query(in->port, in->args.ia.action_id); 13270 break; 13271 case INDIRECT_ACTION_QUERY_UPDATE: 13272 port_action_handle_query_update(in->port, 13273 in->args.ia.action_id, 13274 in->args.ia.qu_mode, 13275 in->args.vc.actions); 13276 break; 13277 case VALIDATE: 13278 port_flow_validate(in->port, &in->args.vc.attr, 13279 in->args.vc.pattern, in->args.vc.actions, 13280 &in->args.vc.tunnel_ops); 13281 break; 13282 case CREATE: 13283 port_flow_create(in->port, &in->args.vc.attr, 13284 in->args.vc.pattern, in->args.vc.actions, 13285 &in->args.vc.tunnel_ops, in->args.vc.user_id); 13286 break; 13287 case DESTROY: 13288 port_flow_destroy(in->port, in->args.destroy.rule_n, 13289 in->args.destroy.rule, 13290 in->args.destroy.is_user_id); 13291 break; 13292 case FLUSH: 13293 port_flow_flush(in->port); 13294 break; 13295 case DUMP_ONE: 13296 case DUMP_ALL: 13297 port_flow_dump(in->port, in->args.dump.mode, 13298 in->args.dump.rule, in->args.dump.file, 13299 in->args.dump.is_user_id); 13300 break; 13301 case QUERY: 13302 port_flow_query(in->port, in->args.query.rule, 13303 &in->args.query.action, 13304 in->args.query.is_user_id); 13305 break; 13306 case LIST: 13307 port_flow_list(in->port, in->args.list.group_n, 13308 in->args.list.group); 13309 break; 13310 case ISOLATE: 13311 port_flow_isolate(in->port, in->args.isolate.set); 13312 break; 13313 case AGED: 13314 port_flow_aged(in->port, in->args.aged.destroy); 13315 break; 13316 case TUNNEL_CREATE: 13317 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 13318 break; 13319 case TUNNEL_DESTROY: 13320 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 13321 break; 13322 case TUNNEL_LIST: 13323 port_flow_tunnel_list(in->port); 13324 break; 13325 case ACTION_POL_G: 13326 port_meter_policy_add(in->port, in->args.policy.policy_id, 13327 in->args.vc.actions); 13328 break; 13329 case FLEX_ITEM_CREATE: 13330 flex_item_create(in->port, in->args.flex.token, 13331 in->args.flex.filename); 13332 break; 13333 case FLEX_ITEM_DESTROY: 13334 flex_item_destroy(in->port, in->args.flex.token); 13335 break; 13336 default: 13337 break; 13338 } 13339 fflush(stdout); 13340 } 13341 13342 /** Token generator and output processing callback (cmdline API). */ 13343 static void 13344 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 13345 { 13346 if (cl == NULL) 13347 cmd_flow_tok(arg0, arg2); 13348 else 13349 cmd_flow_parsed(arg0); 13350 } 13351 13352 /** Global parser instance (cmdline API). */ 13353 cmdline_parse_inst_t cmd_flow = { 13354 .f = cmd_flow_cb, 13355 .data = NULL, /**< Unused. */ 13356 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 13357 .tokens = { 13358 NULL, 13359 }, /**< Tokens are returned by cmd_flow_tok(). */ 13360 }; 13361 13362 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 13363 13364 static void 13365 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 13366 { 13367 struct rte_ipv4_hdr *ipv4; 13368 struct rte_ether_hdr *eth; 13369 struct rte_ipv6_hdr *ipv6; 13370 struct rte_vxlan_hdr *vxlan; 13371 struct rte_vxlan_gpe_hdr *gpe; 13372 struct rte_flow_item_nvgre *nvgre; 13373 uint32_t ipv6_vtc_flow; 13374 13375 switch (item->type) { 13376 case RTE_FLOW_ITEM_TYPE_ETH: 13377 eth = (struct rte_ether_hdr *)buf; 13378 if (next_proto) 13379 eth->ether_type = rte_cpu_to_be_16(next_proto); 13380 break; 13381 case RTE_FLOW_ITEM_TYPE_IPV4: 13382 ipv4 = (struct rte_ipv4_hdr *)buf; 13383 if (!ipv4->version_ihl) 13384 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 13385 if (next_proto && ipv4->next_proto_id == 0) 13386 ipv4->next_proto_id = (uint8_t)next_proto; 13387 break; 13388 case RTE_FLOW_ITEM_TYPE_IPV6: 13389 ipv6 = (struct rte_ipv6_hdr *)buf; 13390 if (next_proto && ipv6->proto == 0) 13391 ipv6->proto = (uint8_t)next_proto; 13392 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 13393 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 13394 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 13395 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 13396 break; 13397 case RTE_FLOW_ITEM_TYPE_VXLAN: 13398 vxlan = (struct rte_vxlan_hdr *)buf; 13399 vxlan->vx_flags = 0x08; 13400 break; 13401 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13402 gpe = (struct rte_vxlan_gpe_hdr *)buf; 13403 gpe->vx_flags = 0x0C; 13404 break; 13405 case RTE_FLOW_ITEM_TYPE_NVGRE: 13406 nvgre = (struct rte_flow_item_nvgre *)buf; 13407 nvgre->protocol = rte_cpu_to_be_16(0x6558); 13408 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 13409 break; 13410 default: 13411 break; 13412 } 13413 } 13414 13415 /** Helper of get item's default mask. */ 13416 static const void * 13417 flow_item_default_mask(const struct rte_flow_item *item) 13418 { 13419 const void *mask = NULL; 13420 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 13421 static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { 13422 .hdr = { 13423 .next_hdr = 0xff, 13424 .type = 0xff, 13425 .segments_left = 0xff, 13426 }, 13427 }; 13428 13429 switch (item->type) { 13430 case RTE_FLOW_ITEM_TYPE_ANY: 13431 mask = &rte_flow_item_any_mask; 13432 break; 13433 case RTE_FLOW_ITEM_TYPE_PORT_ID: 13434 mask = &rte_flow_item_port_id_mask; 13435 break; 13436 case RTE_FLOW_ITEM_TYPE_RAW: 13437 mask = &rte_flow_item_raw_mask; 13438 break; 13439 case RTE_FLOW_ITEM_TYPE_ETH: 13440 mask = &rte_flow_item_eth_mask; 13441 break; 13442 case RTE_FLOW_ITEM_TYPE_VLAN: 13443 mask = &rte_flow_item_vlan_mask; 13444 break; 13445 case RTE_FLOW_ITEM_TYPE_IPV4: 13446 mask = &rte_flow_item_ipv4_mask; 13447 break; 13448 case RTE_FLOW_ITEM_TYPE_IPV6: 13449 mask = &rte_flow_item_ipv6_mask; 13450 break; 13451 case RTE_FLOW_ITEM_TYPE_ICMP: 13452 mask = &rte_flow_item_icmp_mask; 13453 break; 13454 case RTE_FLOW_ITEM_TYPE_UDP: 13455 mask = &rte_flow_item_udp_mask; 13456 break; 13457 case RTE_FLOW_ITEM_TYPE_TCP: 13458 mask = &rte_flow_item_tcp_mask; 13459 break; 13460 case RTE_FLOW_ITEM_TYPE_SCTP: 13461 mask = &rte_flow_item_sctp_mask; 13462 break; 13463 case RTE_FLOW_ITEM_TYPE_VXLAN: 13464 mask = &rte_flow_item_vxlan_mask; 13465 break; 13466 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13467 mask = &rte_flow_item_vxlan_gpe_mask; 13468 break; 13469 case RTE_FLOW_ITEM_TYPE_E_TAG: 13470 mask = &rte_flow_item_e_tag_mask; 13471 break; 13472 case RTE_FLOW_ITEM_TYPE_NVGRE: 13473 mask = &rte_flow_item_nvgre_mask; 13474 break; 13475 case RTE_FLOW_ITEM_TYPE_MPLS: 13476 mask = &rte_flow_item_mpls_mask; 13477 break; 13478 case RTE_FLOW_ITEM_TYPE_GRE: 13479 mask = &rte_flow_item_gre_mask; 13480 break; 13481 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13482 mask = &gre_key_default_mask; 13483 break; 13484 case RTE_FLOW_ITEM_TYPE_META: 13485 mask = &rte_flow_item_meta_mask; 13486 break; 13487 case RTE_FLOW_ITEM_TYPE_RANDOM: 13488 mask = &rte_flow_item_random_mask; 13489 break; 13490 case RTE_FLOW_ITEM_TYPE_FUZZY: 13491 mask = &rte_flow_item_fuzzy_mask; 13492 break; 13493 case RTE_FLOW_ITEM_TYPE_GTP: 13494 mask = &rte_flow_item_gtp_mask; 13495 break; 13496 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13497 mask = &rte_flow_item_gtp_psc_mask; 13498 break; 13499 case RTE_FLOW_ITEM_TYPE_GENEVE: 13500 mask = &rte_flow_item_geneve_mask; 13501 break; 13502 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13503 mask = &rte_flow_item_geneve_opt_mask; 13504 break; 13505 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 13506 mask = &rte_flow_item_pppoe_proto_id_mask; 13507 break; 13508 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13509 mask = &rte_flow_item_l2tpv3oip_mask; 13510 break; 13511 case RTE_FLOW_ITEM_TYPE_ESP: 13512 mask = &rte_flow_item_esp_mask; 13513 break; 13514 case RTE_FLOW_ITEM_TYPE_AH: 13515 mask = &rte_flow_item_ah_mask; 13516 break; 13517 case RTE_FLOW_ITEM_TYPE_PFCP: 13518 mask = &rte_flow_item_pfcp_mask; 13519 break; 13520 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 13521 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 13522 mask = &rte_flow_item_ethdev_mask; 13523 break; 13524 case RTE_FLOW_ITEM_TYPE_L2TPV2: 13525 mask = &rte_flow_item_l2tpv2_mask; 13526 break; 13527 case RTE_FLOW_ITEM_TYPE_PPP: 13528 mask = &rte_flow_item_ppp_mask; 13529 break; 13530 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 13531 mask = &rte_flow_item_meter_color_mask; 13532 break; 13533 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13534 mask = &ipv6_routing_ext_default_mask; 13535 break; 13536 case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: 13537 mask = &rte_flow_item_aggr_affinity_mask; 13538 break; 13539 case RTE_FLOW_ITEM_TYPE_TX_QUEUE: 13540 mask = &rte_flow_item_tx_queue_mask; 13541 break; 13542 case RTE_FLOW_ITEM_TYPE_IB_BTH: 13543 mask = &rte_flow_item_ib_bth_mask; 13544 break; 13545 case RTE_FLOW_ITEM_TYPE_PTYPE: 13546 mask = &rte_flow_item_ptype_mask; 13547 break; 13548 default: 13549 break; 13550 } 13551 return mask; 13552 } 13553 13554 /** Dispatch parsed buffer to function calls. */ 13555 static void 13556 cmd_set_ipv6_ext_parsed(const struct buffer *in) 13557 { 13558 uint32_t n = in->args.vc.pattern_n; 13559 int i = 0; 13560 struct rte_flow_item *item = NULL; 13561 size_t size = 0; 13562 uint8_t *data = NULL; 13563 uint8_t *type = NULL; 13564 size_t *total_size = NULL; 13565 uint16_t idx = in->port; /* We borrow port field as index */ 13566 struct rte_flow_item_ipv6_routing_ext *ext; 13567 const struct rte_flow_item_ipv6_ext *ipv6_ext; 13568 13569 RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || 13570 in->command == SET_IPV6_EXT_REMOVE); 13571 13572 if (in->command == SET_IPV6_EXT_REMOVE) { 13573 if (n != 1 || in->args.vc.pattern->type != 13574 RTE_FLOW_ITEM_TYPE_IPV6_EXT) { 13575 fprintf(stderr, "Error - Not supported item\n"); 13576 return; 13577 } 13578 type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; 13579 item = in->args.vc.pattern; 13580 ipv6_ext = item->spec; 13581 *type = ipv6_ext->next_hdr; 13582 return; 13583 } 13584 13585 total_size = &ipv6_ext_push_confs[idx].size; 13586 data = (uint8_t *)&ipv6_ext_push_confs[idx].data; 13587 type = (uint8_t *)&ipv6_ext_push_confs[idx].type; 13588 13589 *total_size = 0; 13590 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13591 for (i = n - 1 ; i >= 0; --i) { 13592 item = in->args.vc.pattern + i; 13593 switch (item->type) { 13594 case RTE_FLOW_ITEM_TYPE_IPV6_EXT: 13595 ipv6_ext = item->spec; 13596 *type = ipv6_ext->next_hdr; 13597 break; 13598 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13599 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13600 if (!ext->hdr.hdr_len) { 13601 size = sizeof(struct rte_ipv6_routing_ext) + 13602 (ext->hdr.segments_left << 4); 13603 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13604 /* Indicate no TLV once SRH. */ 13605 if (ext->hdr.type == 4) 13606 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13607 } else { 13608 size = sizeof(struct rte_ipv6_routing_ext) + 13609 (ext->hdr.hdr_len << 3); 13610 } 13611 *total_size += size; 13612 memcpy(data, ext, size); 13613 break; 13614 default: 13615 fprintf(stderr, "Error - Not supported item\n"); 13616 goto error; 13617 } 13618 } 13619 RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); 13620 return; 13621 error: 13622 *total_size = 0; 13623 memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); 13624 } 13625 13626 /** Dispatch parsed buffer to function calls. */ 13627 static void 13628 cmd_set_raw_parsed_sample(const struct buffer *in) 13629 { 13630 uint32_t n = in->args.vc.actions_n; 13631 uint32_t i = 0; 13632 struct rte_flow_action *action = NULL; 13633 struct rte_flow_action *data = NULL; 13634 const struct rte_flow_action_rss *rss = NULL; 13635 size_t size = 0; 13636 uint16_t idx = in->port; /* We borrow port field as index */ 13637 uint32_t max_size = sizeof(struct rte_flow_action) * 13638 ACTION_SAMPLE_ACTIONS_NUM; 13639 13640 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 13641 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 13642 memset(data, 0x00, max_size); 13643 for (; i <= n - 1; i++) { 13644 action = in->args.vc.actions + i; 13645 if (action->type == RTE_FLOW_ACTION_TYPE_END) 13646 break; 13647 switch (action->type) { 13648 case RTE_FLOW_ACTION_TYPE_MARK: 13649 size = sizeof(struct rte_flow_action_mark); 13650 rte_memcpy(&sample_mark[idx], 13651 (const void *)action->conf, size); 13652 action->conf = &sample_mark[idx]; 13653 break; 13654 case RTE_FLOW_ACTION_TYPE_COUNT: 13655 size = sizeof(struct rte_flow_action_count); 13656 rte_memcpy(&sample_count[idx], 13657 (const void *)action->conf, size); 13658 action->conf = &sample_count[idx]; 13659 break; 13660 case RTE_FLOW_ACTION_TYPE_QUEUE: 13661 size = sizeof(struct rte_flow_action_queue); 13662 rte_memcpy(&sample_queue[idx], 13663 (const void *)action->conf, size); 13664 action->conf = &sample_queue[idx]; 13665 break; 13666 case RTE_FLOW_ACTION_TYPE_RSS: 13667 size = sizeof(struct rte_flow_action_rss); 13668 rss = action->conf; 13669 rte_memcpy(&sample_rss_data[idx].conf, 13670 (const void *)rss, size); 13671 if (rss->key_len && rss->key) { 13672 sample_rss_data[idx].conf.key = 13673 sample_rss_data[idx].key; 13674 rte_memcpy((void *)((uintptr_t) 13675 sample_rss_data[idx].conf.key), 13676 (const void *)rss->key, 13677 sizeof(uint8_t) * rss->key_len); 13678 } 13679 if (rss->queue_num && rss->queue) { 13680 sample_rss_data[idx].conf.queue = 13681 sample_rss_data[idx].queue; 13682 rte_memcpy((void *)((uintptr_t) 13683 sample_rss_data[idx].conf.queue), 13684 (const void *)rss->queue, 13685 sizeof(uint16_t) * rss->queue_num); 13686 } 13687 action->conf = &sample_rss_data[idx].conf; 13688 break; 13689 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 13690 size = sizeof(struct rte_flow_action_raw_encap); 13691 rte_memcpy(&sample_encap[idx], 13692 (const void *)action->conf, size); 13693 action->conf = &sample_encap[idx]; 13694 break; 13695 case RTE_FLOW_ACTION_TYPE_PORT_ID: 13696 size = sizeof(struct rte_flow_action_port_id); 13697 rte_memcpy(&sample_port_id[idx], 13698 (const void *)action->conf, size); 13699 action->conf = &sample_port_id[idx]; 13700 break; 13701 case RTE_FLOW_ACTION_TYPE_PF: 13702 break; 13703 case RTE_FLOW_ACTION_TYPE_VF: 13704 size = sizeof(struct rte_flow_action_vf); 13705 rte_memcpy(&sample_vf[idx], 13706 (const void *)action->conf, size); 13707 action->conf = &sample_vf[idx]; 13708 break; 13709 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 13710 size = sizeof(struct rte_flow_action_vxlan_encap); 13711 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 13712 action->conf = &sample_vxlan_encap[idx].conf; 13713 break; 13714 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 13715 size = sizeof(struct rte_flow_action_nvgre_encap); 13716 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 13717 action->conf = &sample_nvgre_encap[idx]; 13718 break; 13719 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 13720 size = sizeof(struct rte_flow_action_ethdev); 13721 rte_memcpy(&sample_port_representor[idx], 13722 (const void *)action->conf, size); 13723 action->conf = &sample_port_representor[idx]; 13724 break; 13725 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 13726 size = sizeof(struct rte_flow_action_ethdev); 13727 rte_memcpy(&sample_represented_port[idx], 13728 (const void *)action->conf, size); 13729 action->conf = &sample_represented_port[idx]; 13730 break; 13731 default: 13732 fprintf(stderr, "Error - Not supported action\n"); 13733 return; 13734 } 13735 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 13736 data++; 13737 } 13738 } 13739 13740 /** Dispatch parsed buffer to function calls. */ 13741 static void 13742 cmd_set_raw_parsed(const struct buffer *in) 13743 { 13744 uint32_t n = in->args.vc.pattern_n; 13745 int i = 0; 13746 struct rte_flow_item *item = NULL; 13747 size_t size = 0; 13748 uint8_t *data = NULL; 13749 uint8_t *data_tail = NULL; 13750 size_t *total_size = NULL; 13751 uint16_t upper_layer = 0; 13752 uint16_t proto = 0; 13753 uint16_t idx = in->port; /* We borrow port field as index */ 13754 int gtp_psc = -1; /* GTP PSC option index. */ 13755 const void *src_spec; 13756 13757 if (in->command == SET_SAMPLE_ACTIONS) 13758 return cmd_set_raw_parsed_sample(in); 13759 else if (in->command == SET_IPV6_EXT_PUSH || 13760 in->command == SET_IPV6_EXT_REMOVE) 13761 return cmd_set_ipv6_ext_parsed(in); 13762 RTE_ASSERT(in->command == SET_RAW_ENCAP || 13763 in->command == SET_RAW_DECAP); 13764 if (in->command == SET_RAW_ENCAP) { 13765 total_size = &raw_encap_confs[idx].size; 13766 data = (uint8_t *)&raw_encap_confs[idx].data; 13767 } else { 13768 total_size = &raw_decap_confs[idx].size; 13769 data = (uint8_t *)&raw_decap_confs[idx].data; 13770 } 13771 *total_size = 0; 13772 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13773 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 13774 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 13775 for (i = n - 1 ; i >= 0; --i) { 13776 const struct rte_flow_item_gtp *gtp; 13777 const struct rte_flow_item_geneve_opt *opt; 13778 struct rte_flow_item_ipv6_routing_ext *ext; 13779 13780 item = in->args.vc.pattern + i; 13781 if (item->spec == NULL) 13782 item->spec = flow_item_default_mask(item); 13783 src_spec = item->spec; 13784 switch (item->type) { 13785 case RTE_FLOW_ITEM_TYPE_ETH: 13786 size = sizeof(struct rte_ether_hdr); 13787 break; 13788 case RTE_FLOW_ITEM_TYPE_VLAN: 13789 size = sizeof(struct rte_vlan_hdr); 13790 proto = RTE_ETHER_TYPE_VLAN; 13791 break; 13792 case RTE_FLOW_ITEM_TYPE_IPV4: 13793 size = sizeof(struct rte_ipv4_hdr); 13794 proto = RTE_ETHER_TYPE_IPV4; 13795 break; 13796 case RTE_FLOW_ITEM_TYPE_IPV6: 13797 size = sizeof(struct rte_ipv6_hdr); 13798 proto = RTE_ETHER_TYPE_IPV6; 13799 break; 13800 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13801 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13802 if (!ext->hdr.hdr_len) { 13803 size = sizeof(struct rte_ipv6_routing_ext) + 13804 (ext->hdr.segments_left << 4); 13805 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13806 /* SRv6 without TLV. */ 13807 if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) 13808 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13809 } else { 13810 size = sizeof(struct rte_ipv6_routing_ext) + 13811 (ext->hdr.hdr_len << 3); 13812 } 13813 proto = IPPROTO_ROUTING; 13814 break; 13815 case RTE_FLOW_ITEM_TYPE_UDP: 13816 size = sizeof(struct rte_udp_hdr); 13817 proto = 0x11; 13818 break; 13819 case RTE_FLOW_ITEM_TYPE_TCP: 13820 size = sizeof(struct rte_tcp_hdr); 13821 proto = 0x06; 13822 break; 13823 case RTE_FLOW_ITEM_TYPE_VXLAN: 13824 size = sizeof(struct rte_vxlan_hdr); 13825 break; 13826 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13827 size = sizeof(struct rte_vxlan_gpe_hdr); 13828 break; 13829 case RTE_FLOW_ITEM_TYPE_GRE: 13830 size = sizeof(struct rte_gre_hdr); 13831 proto = 0x2F; 13832 break; 13833 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13834 size = sizeof(rte_be32_t); 13835 proto = 0x0; 13836 break; 13837 case RTE_FLOW_ITEM_TYPE_MPLS: 13838 size = sizeof(struct rte_mpls_hdr); 13839 proto = 0x0; 13840 break; 13841 case RTE_FLOW_ITEM_TYPE_NVGRE: 13842 size = sizeof(struct rte_flow_item_nvgre); 13843 proto = 0x2F; 13844 break; 13845 case RTE_FLOW_ITEM_TYPE_GENEVE: 13846 size = sizeof(struct rte_geneve_hdr); 13847 break; 13848 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13849 opt = (const struct rte_flow_item_geneve_opt *) 13850 item->spec; 13851 size = offsetof(struct rte_flow_item_geneve_opt, 13852 option_len) + sizeof(uint8_t); 13853 if (opt->option_len && opt->data) { 13854 *total_size += opt->option_len * 13855 sizeof(uint32_t); 13856 rte_memcpy(data_tail - (*total_size), 13857 opt->data, 13858 opt->option_len * sizeof(uint32_t)); 13859 } 13860 break; 13861 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13862 size = sizeof(rte_be32_t); 13863 proto = 0x73; 13864 break; 13865 case RTE_FLOW_ITEM_TYPE_ESP: 13866 size = sizeof(struct rte_esp_hdr); 13867 proto = 0x32; 13868 break; 13869 case RTE_FLOW_ITEM_TYPE_AH: 13870 size = sizeof(struct rte_flow_item_ah); 13871 proto = 0x33; 13872 break; 13873 case RTE_FLOW_ITEM_TYPE_GTP: 13874 if (gtp_psc < 0) { 13875 size = sizeof(struct rte_gtp_hdr); 13876 break; 13877 } 13878 if (gtp_psc != i + 1) { 13879 fprintf(stderr, 13880 "Error - GTP PSC does not follow GTP\n"); 13881 goto error; 13882 } 13883 gtp = item->spec; 13884 if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { 13885 /* Only E flag should be set. */ 13886 fprintf(stderr, 13887 "Error - GTP unsupported flags\n"); 13888 goto error; 13889 } else { 13890 struct rte_gtp_hdr_ext_word ext_word = { 13891 .next_ext = 0x85 13892 }; 13893 13894 /* We have to add GTP header extra word. */ 13895 *total_size += sizeof(ext_word); 13896 rte_memcpy(data_tail - (*total_size), 13897 &ext_word, sizeof(ext_word)); 13898 } 13899 size = sizeof(struct rte_gtp_hdr); 13900 break; 13901 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13902 if (gtp_psc >= 0) { 13903 fprintf(stderr, 13904 "Error - Multiple GTP PSC items\n"); 13905 goto error; 13906 } else { 13907 const struct rte_flow_item_gtp_psc 13908 *opt = item->spec; 13909 struct rte_gtp_psc_generic_hdr *hdr; 13910 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 13911 sizeof(int32_t)); 13912 13913 *total_size += hdr_size; 13914 hdr = (typeof(hdr))(data_tail - (*total_size)); 13915 memset(hdr, 0, hdr_size); 13916 *hdr = opt->hdr; 13917 hdr->ext_hdr_len = 1; 13918 gtp_psc = i; 13919 size = 0; 13920 } 13921 break; 13922 case RTE_FLOW_ITEM_TYPE_PFCP: 13923 size = sizeof(struct rte_flow_item_pfcp); 13924 break; 13925 case RTE_FLOW_ITEM_TYPE_FLEX: 13926 if (item->spec != NULL) { 13927 size = ((const struct rte_flow_item_flex *)item->spec)->length; 13928 src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; 13929 } else { 13930 size = 0; 13931 src_spec = NULL; 13932 } 13933 break; 13934 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 13935 size = 0; 13936 if (item->spec) { 13937 const struct rte_flow_item_gre_opt 13938 *opt = item->spec; 13939 if (opt->checksum_rsvd.checksum) { 13940 *total_size += 13941 sizeof(opt->checksum_rsvd); 13942 rte_memcpy(data_tail - (*total_size), 13943 &opt->checksum_rsvd, 13944 sizeof(opt->checksum_rsvd)); 13945 } 13946 if (opt->key.key) { 13947 *total_size += sizeof(opt->key.key); 13948 rte_memcpy(data_tail - (*total_size), 13949 &opt->key.key, 13950 sizeof(opt->key.key)); 13951 } 13952 if (opt->sequence.sequence) { 13953 *total_size += sizeof(opt->sequence.sequence); 13954 rte_memcpy(data_tail - (*total_size), 13955 &opt->sequence.sequence, 13956 sizeof(opt->sequence.sequence)); 13957 } 13958 } 13959 proto = 0x2F; 13960 break; 13961 default: 13962 fprintf(stderr, "Error - Not supported item\n"); 13963 goto error; 13964 } 13965 if (size) { 13966 *total_size += size; 13967 rte_memcpy(data_tail - (*total_size), src_spec, size); 13968 /* update some fields which cannot be set by cmdline */ 13969 update_fields((data_tail - (*total_size)), item, 13970 upper_layer); 13971 upper_layer = proto; 13972 } 13973 } 13974 if (verbose_level & 0x1) 13975 printf("total data size is %zu\n", (*total_size)); 13976 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 13977 memmove(data, (data_tail - (*total_size)), *total_size); 13978 return; 13979 13980 error: 13981 *total_size = 0; 13982 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13983 } 13984 13985 /** Populate help strings for current token (cmdline API). */ 13986 static int 13987 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 13988 unsigned int size) 13989 { 13990 struct context *ctx = &cmd_flow_context; 13991 const struct token *token = &token_list[ctx->prev]; 13992 13993 (void)hdr; 13994 if (!size) 13995 return -1; 13996 /* Set token type and update global help with details. */ 13997 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 13998 if (token->help) 13999 cmd_set_raw.help_str = token->help; 14000 else 14001 cmd_set_raw.help_str = token->name; 14002 return 0; 14003 } 14004 14005 /** Token definition template (cmdline API). */ 14006 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 14007 .ops = &(struct cmdline_token_ops){ 14008 .parse = cmd_flow_parse, 14009 .complete_get_nb = cmd_flow_complete_get_nb, 14010 .complete_get_elt = cmd_flow_complete_get_elt, 14011 .get_help = cmd_set_raw_get_help, 14012 }, 14013 .offset = 0, 14014 }; 14015 14016 /** Populate the next dynamic token. */ 14017 static void 14018 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 14019 cmdline_parse_token_hdr_t **hdr_inst) 14020 { 14021 struct context *ctx = &cmd_flow_context; 14022 14023 /* Always reinitialize context before requesting the first token. */ 14024 if (!(hdr_inst - cmd_set_raw.tokens)) { 14025 cmd_flow_context_init(ctx); 14026 ctx->curr = START_SET; 14027 } 14028 /* Return NULL when no more tokens are expected. */ 14029 if (!ctx->next_num && (ctx->curr != START_SET)) { 14030 *hdr = NULL; 14031 return; 14032 } 14033 /* Determine if command should end here. */ 14034 if (ctx->eol && ctx->last && ctx->next_num) { 14035 const enum index *list = ctx->next[ctx->next_num - 1]; 14036 int i; 14037 14038 for (i = 0; list[i]; ++i) { 14039 if (list[i] != END) 14040 continue; 14041 *hdr = NULL; 14042 return; 14043 } 14044 } 14045 *hdr = &cmd_set_raw_token_hdr; 14046 } 14047 14048 /** Token generator and output processing callback (cmdline API). */ 14049 static void 14050 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 14051 { 14052 if (cl == NULL) 14053 cmd_set_raw_tok(arg0, arg2); 14054 else 14055 cmd_set_raw_parsed(arg0); 14056 } 14057 14058 /** Global parser instance (cmdline API). */ 14059 cmdline_parse_inst_t cmd_set_raw = { 14060 .f = cmd_set_raw_cb, 14061 .data = NULL, /**< Unused. */ 14062 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 14063 .tokens = { 14064 NULL, 14065 }, /**< Tokens are returned by cmd_flow_tok(). */ 14066 }; 14067 14068 /* *** display raw_encap/raw_decap buf */ 14069 struct cmd_show_set_raw_result { 14070 cmdline_fixed_string_t cmd_show; 14071 cmdline_fixed_string_t cmd_what; 14072 cmdline_fixed_string_t cmd_all; 14073 uint16_t cmd_index; 14074 }; 14075 14076 static void 14077 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 14078 { 14079 struct cmd_show_set_raw_result *res = parsed_result; 14080 uint16_t index = res->cmd_index; 14081 uint8_t all = 0; 14082 uint8_t *raw_data = NULL; 14083 size_t raw_size = 0; 14084 char title[16] = {0}; 14085 14086 RTE_SET_USED(cl); 14087 RTE_SET_USED(data); 14088 if (!strcmp(res->cmd_all, "all")) { 14089 all = 1; 14090 index = 0; 14091 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 14092 fprintf(stderr, "index should be 0-%u\n", 14093 RAW_ENCAP_CONFS_MAX_NUM - 1); 14094 return; 14095 } 14096 do { 14097 if (!strcmp(res->cmd_what, "raw_encap")) { 14098 raw_data = (uint8_t *)&raw_encap_confs[index].data; 14099 raw_size = raw_encap_confs[index].size; 14100 snprintf(title, 16, "\nindex: %u", index); 14101 rte_hexdump(stdout, title, raw_data, raw_size); 14102 } else { 14103 raw_data = (uint8_t *)&raw_decap_confs[index].data; 14104 raw_size = raw_decap_confs[index].size; 14105 snprintf(title, 16, "\nindex: %u", index); 14106 rte_hexdump(stdout, title, raw_data, raw_size); 14107 } 14108 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 14109 } 14110 14111 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 14112 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14113 cmd_show, "show"); 14114 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 14115 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14116 cmd_what, "raw_encap#raw_decap"); 14117 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 14118 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 14119 cmd_index, RTE_UINT16); 14120 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 14121 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14122 cmd_all, "all"); 14123 cmdline_parse_inst_t cmd_show_set_raw = { 14124 .f = cmd_show_set_raw_parsed, 14125 .data = NULL, 14126 .help_str = "show <raw_encap|raw_decap> <index>", 14127 .tokens = { 14128 (void *)&cmd_show_set_raw_cmd_show, 14129 (void *)&cmd_show_set_raw_cmd_what, 14130 (void *)&cmd_show_set_raw_cmd_index, 14131 NULL, 14132 }, 14133 }; 14134 cmdline_parse_inst_t cmd_show_set_raw_all = { 14135 .f = cmd_show_set_raw_parsed, 14136 .data = NULL, 14137 .help_str = "show <raw_encap|raw_decap> all", 14138 .tokens = { 14139 (void *)&cmd_show_set_raw_cmd_show, 14140 (void *)&cmd_show_set_raw_cmd_what, 14141 (void *)&cmd_show_set_raw_cmd_all, 14142 NULL, 14143 }, 14144 }; 14145