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_ARP_ETH_IPV4, 415 ITEM_ARP_ETH_IPV4_SHA, 416 ITEM_ARP_ETH_IPV4_SPA, 417 ITEM_ARP_ETH_IPV4_THA, 418 ITEM_ARP_ETH_IPV4_TPA, 419 ITEM_IPV6_EXT, 420 ITEM_IPV6_EXT_NEXT_HDR, 421 ITEM_IPV6_FRAG_EXT, 422 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 423 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 424 ITEM_IPV6_FRAG_EXT_ID, 425 ITEM_ICMP6, 426 ITEM_ICMP6_TYPE, 427 ITEM_ICMP6_CODE, 428 ITEM_ICMP6_ECHO_REQUEST, 429 ITEM_ICMP6_ECHO_REQUEST_ID, 430 ITEM_ICMP6_ECHO_REQUEST_SEQ, 431 ITEM_ICMP6_ECHO_REPLY, 432 ITEM_ICMP6_ECHO_REPLY_ID, 433 ITEM_ICMP6_ECHO_REPLY_SEQ, 434 ITEM_ICMP6_ND_NS, 435 ITEM_ICMP6_ND_NS_TARGET_ADDR, 436 ITEM_ICMP6_ND_NA, 437 ITEM_ICMP6_ND_NA_TARGET_ADDR, 438 ITEM_ICMP6_ND_OPT, 439 ITEM_ICMP6_ND_OPT_TYPE, 440 ITEM_ICMP6_ND_OPT_SLA_ETH, 441 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 442 ITEM_ICMP6_ND_OPT_TLA_ETH, 443 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 444 ITEM_META, 445 ITEM_META_DATA, 446 ITEM_RANDOM, 447 ITEM_RANDOM_VALUE, 448 ITEM_GRE_KEY, 449 ITEM_GRE_KEY_VALUE, 450 ITEM_GRE_OPTION, 451 ITEM_GRE_OPTION_CHECKSUM, 452 ITEM_GRE_OPTION_KEY, 453 ITEM_GRE_OPTION_SEQUENCE, 454 ITEM_GTP_PSC, 455 ITEM_GTP_PSC_QFI, 456 ITEM_GTP_PSC_PDU_T, 457 ITEM_PPPOES, 458 ITEM_PPPOED, 459 ITEM_PPPOE_SEID, 460 ITEM_PPPOE_PROTO_ID, 461 ITEM_HIGIG2, 462 ITEM_HIGIG2_CLASSIFICATION, 463 ITEM_HIGIG2_VID, 464 ITEM_TAG, 465 ITEM_TAG_DATA, 466 ITEM_TAG_INDEX, 467 ITEM_L2TPV3OIP, 468 ITEM_L2TPV3OIP_SESSION_ID, 469 ITEM_ESP, 470 ITEM_ESP_SPI, 471 ITEM_AH, 472 ITEM_AH_SPI, 473 ITEM_PFCP, 474 ITEM_PFCP_S_FIELD, 475 ITEM_PFCP_SEID, 476 ITEM_ECPRI, 477 ITEM_ECPRI_COMMON, 478 ITEM_ECPRI_COMMON_TYPE, 479 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 480 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 481 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 482 ITEM_ECPRI_MSG_IQ_DATA_PCID, 483 ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 484 ITEM_ECPRI_MSG_DLY_MSR_MSRID, 485 ITEM_GENEVE_OPT, 486 ITEM_GENEVE_OPT_CLASS, 487 ITEM_GENEVE_OPT_TYPE, 488 ITEM_GENEVE_OPT_LENGTH, 489 ITEM_GENEVE_OPT_DATA, 490 ITEM_INTEGRITY, 491 ITEM_INTEGRITY_LEVEL, 492 ITEM_INTEGRITY_VALUE, 493 ITEM_CONNTRACK, 494 ITEM_POL_PORT, 495 ITEM_POL_METER, 496 ITEM_POL_POLICY, 497 ITEM_PORT_REPRESENTOR, 498 ITEM_PORT_REPRESENTOR_PORT_ID, 499 ITEM_REPRESENTED_PORT, 500 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 501 ITEM_FLEX, 502 ITEM_FLEX_ITEM_HANDLE, 503 ITEM_FLEX_PATTERN_HANDLE, 504 ITEM_L2TPV2, 505 ITEM_L2TPV2_TYPE, 506 ITEM_L2TPV2_TYPE_DATA, 507 ITEM_L2TPV2_TYPE_DATA_L, 508 ITEM_L2TPV2_TYPE_DATA_S, 509 ITEM_L2TPV2_TYPE_DATA_O, 510 ITEM_L2TPV2_TYPE_DATA_L_S, 511 ITEM_L2TPV2_TYPE_CTRL, 512 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 513 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 514 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 515 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 516 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 517 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 518 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 519 ITEM_L2TPV2_MSG_DATA_S_NS, 520 ITEM_L2TPV2_MSG_DATA_S_NR, 521 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 522 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 523 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 524 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 525 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 526 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 527 ITEM_L2TPV2_MSG_DATA_L_S_NS, 528 ITEM_L2TPV2_MSG_DATA_L_S_NR, 529 ITEM_L2TPV2_MSG_CTRL_LENGTH, 530 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 531 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 532 ITEM_L2TPV2_MSG_CTRL_NS, 533 ITEM_L2TPV2_MSG_CTRL_NR, 534 ITEM_PPP, 535 ITEM_PPP_ADDR, 536 ITEM_PPP_CTRL, 537 ITEM_PPP_PROTO_ID, 538 ITEM_METER, 539 ITEM_METER_COLOR, 540 ITEM_METER_COLOR_NAME, 541 ITEM_QUOTA, 542 ITEM_QUOTA_STATE, 543 ITEM_QUOTA_STATE_NAME, 544 ITEM_AGGR_AFFINITY, 545 ITEM_AGGR_AFFINITY_VALUE, 546 ITEM_TX_QUEUE, 547 ITEM_TX_QUEUE_VALUE, 548 ITEM_IB_BTH, 549 ITEM_IB_BTH_OPCODE, 550 ITEM_IB_BTH_PKEY, 551 ITEM_IB_BTH_DST_QPN, 552 ITEM_IB_BTH_PSN, 553 ITEM_IPV6_PUSH_REMOVE_EXT, 554 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 555 ITEM_PTYPE, 556 ITEM_PTYPE_VALUE, 557 ITEM_NSH, 558 ITEM_COMPARE, 559 ITEM_COMPARE_OP, 560 ITEM_COMPARE_OP_VALUE, 561 ITEM_COMPARE_FIELD_A_TYPE, 562 ITEM_COMPARE_FIELD_A_TYPE_VALUE, 563 ITEM_COMPARE_FIELD_A_LEVEL, 564 ITEM_COMPARE_FIELD_A_LEVEL_VALUE, 565 ITEM_COMPARE_FIELD_A_TAG_INDEX, 566 ITEM_COMPARE_FIELD_A_TYPE_ID, 567 ITEM_COMPARE_FIELD_A_CLASS_ID, 568 ITEM_COMPARE_FIELD_A_OFFSET, 569 ITEM_COMPARE_FIELD_B_TYPE, 570 ITEM_COMPARE_FIELD_B_TYPE_VALUE, 571 ITEM_COMPARE_FIELD_B_LEVEL, 572 ITEM_COMPARE_FIELD_B_LEVEL_VALUE, 573 ITEM_COMPARE_FIELD_B_TAG_INDEX, 574 ITEM_COMPARE_FIELD_B_TYPE_ID, 575 ITEM_COMPARE_FIELD_B_CLASS_ID, 576 ITEM_COMPARE_FIELD_B_OFFSET, 577 ITEM_COMPARE_FIELD_B_VALUE, 578 ITEM_COMPARE_FIELD_B_POINTER, 579 ITEM_COMPARE_FIELD_WIDTH, 580 581 /* Validate/create actions. */ 582 ACTIONS, 583 ACTION_NEXT, 584 ACTION_END, 585 ACTION_VOID, 586 ACTION_PASSTHRU, 587 ACTION_SKIP_CMAN, 588 ACTION_JUMP, 589 ACTION_JUMP_GROUP, 590 ACTION_MARK, 591 ACTION_MARK_ID, 592 ACTION_FLAG, 593 ACTION_QUEUE, 594 ACTION_QUEUE_INDEX, 595 ACTION_DROP, 596 ACTION_COUNT, 597 ACTION_COUNT_ID, 598 ACTION_RSS, 599 ACTION_RSS_FUNC, 600 ACTION_RSS_LEVEL, 601 ACTION_RSS_FUNC_DEFAULT, 602 ACTION_RSS_FUNC_TOEPLITZ, 603 ACTION_RSS_FUNC_SIMPLE_XOR, 604 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, 605 ACTION_RSS_TYPES, 606 ACTION_RSS_TYPE, 607 ACTION_RSS_KEY, 608 ACTION_RSS_KEY_LEN, 609 ACTION_RSS_QUEUES, 610 ACTION_RSS_QUEUE, 611 ACTION_PF, 612 ACTION_VF, 613 ACTION_VF_ORIGINAL, 614 ACTION_VF_ID, 615 ACTION_PORT_ID, 616 ACTION_PORT_ID_ORIGINAL, 617 ACTION_PORT_ID_ID, 618 ACTION_METER, 619 ACTION_METER_COLOR, 620 ACTION_METER_COLOR_TYPE, 621 ACTION_METER_COLOR_GREEN, 622 ACTION_METER_COLOR_YELLOW, 623 ACTION_METER_COLOR_RED, 624 ACTION_METER_ID, 625 ACTION_METER_MARK, 626 ACTION_METER_PROFILE, 627 ACTION_METER_PROFILE_ID2PTR, 628 ACTION_METER_POLICY, 629 ACTION_METER_POLICY_ID2PTR, 630 ACTION_METER_COLOR_MODE, 631 ACTION_METER_STATE, 632 ACTION_OF_DEC_NW_TTL, 633 ACTION_OF_POP_VLAN, 634 ACTION_OF_PUSH_VLAN, 635 ACTION_OF_PUSH_VLAN_ETHERTYPE, 636 ACTION_OF_SET_VLAN_VID, 637 ACTION_OF_SET_VLAN_VID_VLAN_VID, 638 ACTION_OF_SET_VLAN_PCP, 639 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 640 ACTION_OF_POP_MPLS, 641 ACTION_OF_POP_MPLS_ETHERTYPE, 642 ACTION_OF_PUSH_MPLS, 643 ACTION_OF_PUSH_MPLS_ETHERTYPE, 644 ACTION_VXLAN_ENCAP, 645 ACTION_VXLAN_DECAP, 646 ACTION_NVGRE_ENCAP, 647 ACTION_NVGRE_DECAP, 648 ACTION_L2_ENCAP, 649 ACTION_L2_DECAP, 650 ACTION_MPLSOGRE_ENCAP, 651 ACTION_MPLSOGRE_DECAP, 652 ACTION_MPLSOUDP_ENCAP, 653 ACTION_MPLSOUDP_DECAP, 654 ACTION_SET_IPV4_SRC, 655 ACTION_SET_IPV4_SRC_IPV4_SRC, 656 ACTION_SET_IPV4_DST, 657 ACTION_SET_IPV4_DST_IPV4_DST, 658 ACTION_SET_IPV6_SRC, 659 ACTION_SET_IPV6_SRC_IPV6_SRC, 660 ACTION_SET_IPV6_DST, 661 ACTION_SET_IPV6_DST_IPV6_DST, 662 ACTION_SET_TP_SRC, 663 ACTION_SET_TP_SRC_TP_SRC, 664 ACTION_SET_TP_DST, 665 ACTION_SET_TP_DST_TP_DST, 666 ACTION_MAC_SWAP, 667 ACTION_DEC_TTL, 668 ACTION_SET_TTL, 669 ACTION_SET_TTL_TTL, 670 ACTION_SET_MAC_SRC, 671 ACTION_SET_MAC_SRC_MAC_SRC, 672 ACTION_SET_MAC_DST, 673 ACTION_SET_MAC_DST_MAC_DST, 674 ACTION_INC_TCP_SEQ, 675 ACTION_INC_TCP_SEQ_VALUE, 676 ACTION_DEC_TCP_SEQ, 677 ACTION_DEC_TCP_SEQ_VALUE, 678 ACTION_INC_TCP_ACK, 679 ACTION_INC_TCP_ACK_VALUE, 680 ACTION_DEC_TCP_ACK, 681 ACTION_DEC_TCP_ACK_VALUE, 682 ACTION_RAW_ENCAP, 683 ACTION_RAW_DECAP, 684 ACTION_RAW_ENCAP_SIZE, 685 ACTION_RAW_ENCAP_INDEX, 686 ACTION_RAW_ENCAP_INDEX_VALUE, 687 ACTION_RAW_DECAP_INDEX, 688 ACTION_RAW_DECAP_INDEX_VALUE, 689 ACTION_SET_TAG, 690 ACTION_SET_TAG_DATA, 691 ACTION_SET_TAG_INDEX, 692 ACTION_SET_TAG_MASK, 693 ACTION_SET_META, 694 ACTION_SET_META_DATA, 695 ACTION_SET_META_MASK, 696 ACTION_SET_IPV4_DSCP, 697 ACTION_SET_IPV4_DSCP_VALUE, 698 ACTION_SET_IPV6_DSCP, 699 ACTION_SET_IPV6_DSCP_VALUE, 700 ACTION_AGE, 701 ACTION_AGE_TIMEOUT, 702 ACTION_AGE_UPDATE, 703 ACTION_AGE_UPDATE_TIMEOUT, 704 ACTION_AGE_UPDATE_TOUCH, 705 ACTION_SAMPLE, 706 ACTION_SAMPLE_RATIO, 707 ACTION_SAMPLE_INDEX, 708 ACTION_SAMPLE_INDEX_VALUE, 709 ACTION_INDIRECT, 710 ACTION_INDIRECT_LIST, 711 ACTION_INDIRECT_LIST_HANDLE, 712 ACTION_INDIRECT_LIST_CONF, 713 INDIRECT_LIST_ACTION_ID2PTR_HANDLE, 714 INDIRECT_LIST_ACTION_ID2PTR_CONF, 715 ACTION_SHARED_INDIRECT, 716 INDIRECT_ACTION_PORT, 717 INDIRECT_ACTION_ID2PTR, 718 ACTION_MODIFY_FIELD, 719 ACTION_MODIFY_FIELD_OP, 720 ACTION_MODIFY_FIELD_OP_VALUE, 721 ACTION_MODIFY_FIELD_DST_TYPE, 722 ACTION_MODIFY_FIELD_DST_TYPE_VALUE, 723 ACTION_MODIFY_FIELD_DST_LEVEL, 724 ACTION_MODIFY_FIELD_DST_LEVEL_VALUE, 725 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 726 ACTION_MODIFY_FIELD_DST_TYPE_ID, 727 ACTION_MODIFY_FIELD_DST_CLASS_ID, 728 ACTION_MODIFY_FIELD_DST_OFFSET, 729 ACTION_MODIFY_FIELD_SRC_TYPE, 730 ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, 731 ACTION_MODIFY_FIELD_SRC_LEVEL, 732 ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE, 733 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 734 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 735 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 736 ACTION_MODIFY_FIELD_SRC_OFFSET, 737 ACTION_MODIFY_FIELD_SRC_VALUE, 738 ACTION_MODIFY_FIELD_SRC_POINTER, 739 ACTION_MODIFY_FIELD_WIDTH, 740 ACTION_CONNTRACK, 741 ACTION_CONNTRACK_UPDATE, 742 ACTION_CONNTRACK_UPDATE_DIR, 743 ACTION_CONNTRACK_UPDATE_CTX, 744 ACTION_POL_G, 745 ACTION_POL_Y, 746 ACTION_POL_R, 747 ACTION_PORT_REPRESENTOR, 748 ACTION_PORT_REPRESENTOR_PORT_ID, 749 ACTION_REPRESENTED_PORT, 750 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 751 ACTION_SEND_TO_KERNEL, 752 ACTION_QUOTA_CREATE, 753 ACTION_QUOTA_CREATE_LIMIT, 754 ACTION_QUOTA_CREATE_MODE, 755 ACTION_QUOTA_CREATE_MODE_NAME, 756 ACTION_QUOTA_QU, 757 ACTION_QUOTA_QU_LIMIT, 758 ACTION_QUOTA_QU_UPDATE_OP, 759 ACTION_QUOTA_QU_UPDATE_OP_NAME, 760 ACTION_IPV6_EXT_REMOVE, 761 ACTION_IPV6_EXT_REMOVE_INDEX, 762 ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, 763 ACTION_IPV6_EXT_PUSH, 764 ACTION_IPV6_EXT_PUSH_INDEX, 765 ACTION_IPV6_EXT_PUSH_INDEX_VALUE, 766 ACTION_NAT64, 767 ACTION_NAT64_MODE, 768 }; 769 770 /** Maximum size for pattern in struct rte_flow_item_raw. */ 771 #define ITEM_RAW_PATTERN_SIZE 512 772 773 /** Maximum size for GENEVE option data pattern in bytes. */ 774 #define ITEM_GENEVE_OPT_DATA_SIZE 124 775 776 /** Storage size for struct rte_flow_item_raw including pattern. */ 777 #define ITEM_RAW_SIZE \ 778 (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) 779 780 static const char *const compare_ops[] = { 781 "eq", "ne", "lt", "le", "gt", "ge", NULL 782 }; 783 784 /** Maximum size for external pattern in struct rte_flow_field_data. */ 785 #define FLOW_FIELD_PATTERN_SIZE 32 786 787 /** Storage size for struct rte_flow_action_modify_field including pattern. */ 788 #define ACTION_MODIFY_SIZE \ 789 (sizeof(struct rte_flow_action_modify_field) + \ 790 FLOW_FIELD_PATTERN_SIZE) 791 792 /** Maximum number of queue indices in struct rte_flow_action_rss. */ 793 #define ACTION_RSS_QUEUE_NUM 128 794 795 /** Storage for struct rte_flow_action_rss including external data. */ 796 struct action_rss_data { 797 struct rte_flow_action_rss conf; 798 uint8_t key[RSS_HASH_KEY_LENGTH]; 799 uint16_t queue[ACTION_RSS_QUEUE_NUM]; 800 }; 801 802 /** Maximum data size in struct rte_flow_action_raw_encap. */ 803 #define ACTION_RAW_ENCAP_MAX_DATA 512 804 #define RAW_ENCAP_CONFS_MAX_NUM 8 805 806 /** Storage for struct rte_flow_action_raw_encap. */ 807 struct raw_encap_conf { 808 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 809 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 810 size_t size; 811 }; 812 813 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 814 815 /** Storage for struct rte_flow_action_raw_encap including external data. */ 816 struct action_raw_encap_data { 817 struct rte_flow_action_raw_encap conf; 818 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 819 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 820 uint16_t idx; 821 }; 822 823 /** Storage for struct rte_flow_action_raw_decap. */ 824 struct raw_decap_conf { 825 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 826 size_t size; 827 }; 828 829 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 830 831 /** Storage for struct rte_flow_action_raw_decap including external data. */ 832 struct action_raw_decap_data { 833 struct rte_flow_action_raw_decap conf; 834 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 835 uint16_t idx; 836 }; 837 838 /** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ 839 #define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 840 #define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 841 842 /** Storage for struct rte_flow_action_ipv6_ext_push. */ 843 struct ipv6_ext_push_conf { 844 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 845 size_t size; 846 uint8_t type; 847 }; 848 849 struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 850 851 /** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ 852 struct action_ipv6_ext_push_data { 853 struct rte_flow_action_ipv6_ext_push conf; 854 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 855 uint8_t type; 856 uint16_t idx; 857 }; 858 859 /** Storage for struct rte_flow_action_ipv6_ext_remove. */ 860 struct ipv6_ext_remove_conf { 861 struct rte_flow_action_ipv6_ext_remove conf; 862 uint8_t type; 863 }; 864 865 struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 866 867 /** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ 868 struct action_ipv6_ext_remove_data { 869 struct rte_flow_action_ipv6_ext_remove conf; 870 uint8_t type; 871 uint16_t idx; 872 }; 873 874 struct vxlan_encap_conf vxlan_encap_conf = { 875 .select_ipv4 = 1, 876 .select_vlan = 0, 877 .select_tos_ttl = 0, 878 .vni = "\x00\x00\x00", 879 .udp_src = 0, 880 .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), 881 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 882 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 883 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 884 "\x00\x00\x00\x00\x00\x00\x00\x01", 885 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 886 "\x00\x00\x00\x00\x00\x00\x11\x11", 887 .vlan_tci = 0, 888 .ip_tos = 0, 889 .ip_ttl = 255, 890 .eth_src = "\x00\x00\x00\x00\x00\x00", 891 .eth_dst = "\xff\xff\xff\xff\xff\xff", 892 }; 893 894 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */ 895 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6 896 897 /** Storage for struct rte_flow_action_vxlan_encap including external data. */ 898 struct action_vxlan_encap_data { 899 struct rte_flow_action_vxlan_encap conf; 900 struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; 901 struct rte_flow_item_eth item_eth; 902 struct rte_flow_item_vlan item_vlan; 903 union { 904 struct rte_flow_item_ipv4 item_ipv4; 905 struct rte_flow_item_ipv6 item_ipv6; 906 }; 907 struct rte_flow_item_udp item_udp; 908 struct rte_flow_item_vxlan item_vxlan; 909 }; 910 911 struct nvgre_encap_conf nvgre_encap_conf = { 912 .select_ipv4 = 1, 913 .select_vlan = 0, 914 .tni = "\x00\x00\x00", 915 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 916 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 917 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 918 "\x00\x00\x00\x00\x00\x00\x00\x01", 919 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 920 "\x00\x00\x00\x00\x00\x00\x11\x11", 921 .vlan_tci = 0, 922 .eth_src = "\x00\x00\x00\x00\x00\x00", 923 .eth_dst = "\xff\xff\xff\xff\xff\xff", 924 }; 925 926 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */ 927 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 928 929 /** Storage for struct rte_flow_action_nvgre_encap including external data. */ 930 struct action_nvgre_encap_data { 931 struct rte_flow_action_nvgre_encap conf; 932 struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; 933 struct rte_flow_item_eth item_eth; 934 struct rte_flow_item_vlan item_vlan; 935 union { 936 struct rte_flow_item_ipv4 item_ipv4; 937 struct rte_flow_item_ipv6 item_ipv6; 938 }; 939 struct rte_flow_item_nvgre item_nvgre; 940 }; 941 942 struct l2_encap_conf l2_encap_conf; 943 944 struct l2_decap_conf l2_decap_conf; 945 946 struct mplsogre_encap_conf mplsogre_encap_conf; 947 948 struct mplsogre_decap_conf mplsogre_decap_conf; 949 950 struct mplsoudp_encap_conf mplsoudp_encap_conf; 951 952 struct mplsoudp_decap_conf mplsoudp_decap_conf; 953 954 struct rte_flow_action_conntrack conntrack_context; 955 956 #define ACTION_SAMPLE_ACTIONS_NUM 10 957 #define RAW_SAMPLE_CONFS_MAX_NUM 8 958 /** Storage for struct rte_flow_action_sample including external data. */ 959 struct action_sample_data { 960 struct rte_flow_action_sample conf; 961 uint32_t idx; 962 }; 963 /** Storage for struct rte_flow_action_sample. */ 964 struct raw_sample_conf { 965 struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; 966 }; 967 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; 968 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; 969 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; 970 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; 971 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; 972 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 973 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 974 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 975 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; 976 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; 977 struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; 978 struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; 979 980 static const char *const modify_field_ops[] = { 981 "set", "add", "sub", NULL 982 }; 983 984 static const char *const flow_field_ids[] = { 985 "start", "mac_dst", "mac_src", 986 "vlan_type", "vlan_id", "mac_type", 987 "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", 988 "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", 989 "tcp_port_src", "tcp_port_dst", 990 "tcp_seq_num", "tcp_ack_num", "tcp_flags", 991 "udp_port_src", "udp_port_dst", 992 "vxlan_vni", "geneve_vni", "gtp_teid", 993 "tag", "mark", "meta", "pointer", "value", 994 "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", 995 "ipv6_proto", 996 "flex_item", 997 "hash_result", 998 "geneve_opt_type", "geneve_opt_class", "geneve_opt_data", "mpls", 999 "tcp_data_off", "ipv4_ihl", "ipv4_total_len", "ipv6_payload_len", 1000 "random", 1001 NULL 1002 }; 1003 1004 static const char *const meter_colors[] = { 1005 "green", "yellow", "red", "all", NULL 1006 }; 1007 1008 static const char *const table_insertion_types[] = { 1009 "pattern", "index", NULL 1010 }; 1011 1012 static const char *const table_hash_funcs[] = { 1013 "default", "linear", "crc32", "crc16", NULL 1014 }; 1015 1016 #define RAW_IPSEC_CONFS_MAX_NUM 8 1017 1018 /** Maximum number of subsequent tokens and arguments on the stack. */ 1019 #define CTX_STACK_SIZE 16 1020 1021 /** Parser context. */ 1022 struct context { 1023 /** Stack of subsequent token lists to process. */ 1024 const enum index *next[CTX_STACK_SIZE]; 1025 /** Arguments for stacked tokens. */ 1026 const void *args[CTX_STACK_SIZE]; 1027 enum index curr; /**< Current token index. */ 1028 enum index prev; /**< Index of the last token seen. */ 1029 int next_num; /**< Number of entries in next[]. */ 1030 int args_num; /**< Number of entries in args[]. */ 1031 uint32_t eol:1; /**< EOL has been detected. */ 1032 uint32_t last:1; /**< No more arguments. */ 1033 portid_t port; /**< Current port ID (for completions). */ 1034 uint32_t objdata; /**< Object-specific data. */ 1035 void *object; /**< Address of current object for relative offsets. */ 1036 void *objmask; /**< Object a full mask must be written to. */ 1037 }; 1038 1039 /** Token argument. */ 1040 struct arg { 1041 uint32_t hton:1; /**< Use network byte ordering. */ 1042 uint32_t sign:1; /**< Value is signed. */ 1043 uint32_t bounded:1; /**< Value is bounded. */ 1044 uintmax_t min; /**< Minimum value if bounded. */ 1045 uintmax_t max; /**< Maximum value if bounded. */ 1046 uint32_t offset; /**< Relative offset from ctx->object. */ 1047 uint32_t size; /**< Field size. */ 1048 const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ 1049 }; 1050 1051 /** Parser token definition. */ 1052 struct token { 1053 /** Type displayed during completion (defaults to "TOKEN"). */ 1054 const char *type; 1055 /** Help displayed during completion (defaults to token name). */ 1056 const char *help; 1057 /** Private data used by parser functions. */ 1058 const void *priv; 1059 /** 1060 * Lists of subsequent tokens to push on the stack. Each call to the 1061 * parser consumes the last entry of that stack. 1062 */ 1063 const enum index *const *next; 1064 /** Arguments stack for subsequent tokens that need them. */ 1065 const struct arg *const *args; 1066 /** 1067 * Token-processing callback, returns -1 in case of error, the 1068 * length of the matched string otherwise. If NULL, attempts to 1069 * match the token name. 1070 * 1071 * If buf is not NULL, the result should be stored in it according 1072 * to context. An error is returned if not large enough. 1073 */ 1074 int (*call)(struct context *ctx, const struct token *token, 1075 const char *str, unsigned int len, 1076 void *buf, unsigned int size); 1077 /** 1078 * Callback that provides possible values for this token, used for 1079 * completion. Returns -1 in case of error, the number of possible 1080 * values otherwise. If NULL, the token name is used. 1081 * 1082 * If buf is not NULL, entry index ent is written to buf and the 1083 * full length of the entry is returned (same behavior as 1084 * snprintf()). 1085 */ 1086 int (*comp)(struct context *ctx, const struct token *token, 1087 unsigned int ent, char *buf, unsigned int size); 1088 /** Mandatory token name, no default value. */ 1089 const char *name; 1090 }; 1091 1092 /** Static initializer for the next field. */ 1093 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } 1094 1095 /** Static initializer for a NEXT() entry. */ 1096 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } 1097 1098 /** Static initializer for the args field. */ 1099 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } 1100 1101 /** Static initializer for ARGS() to target a field. */ 1102 #define ARGS_ENTRY(s, f) \ 1103 (&(const struct arg){ \ 1104 .offset = offsetof(s, f), \ 1105 .size = sizeof(((s *)0)->f), \ 1106 }) 1107 1108 /** Static initializer for ARGS() to target a bit-field. */ 1109 #define ARGS_ENTRY_BF(s, f, b) \ 1110 (&(const struct arg){ \ 1111 .size = sizeof(s), \ 1112 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ 1113 }) 1114 1115 /** Static initializer for ARGS() to target a field with limits. */ 1116 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \ 1117 (&(const struct arg){ \ 1118 .bounded = 1, \ 1119 .min = (i), \ 1120 .max = (a), \ 1121 .offset = offsetof(s, f), \ 1122 .size = sizeof(((s *)0)->f), \ 1123 }) 1124 1125 /** Static initializer for ARGS() to target an arbitrary bit-mask. */ 1126 #define ARGS_ENTRY_MASK(s, f, m) \ 1127 (&(const struct arg){ \ 1128 .offset = offsetof(s, f), \ 1129 .size = sizeof(((s *)0)->f), \ 1130 .mask = (const void *)(m), \ 1131 }) 1132 1133 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ 1134 #define ARGS_ENTRY_MASK_HTON(s, f, m) \ 1135 (&(const struct arg){ \ 1136 .hton = 1, \ 1137 .offset = offsetof(s, f), \ 1138 .size = sizeof(((s *)0)->f), \ 1139 .mask = (const void *)(m), \ 1140 }) 1141 1142 /** Static initializer for ARGS() to target a pointer. */ 1143 #define ARGS_ENTRY_PTR(s, f) \ 1144 (&(const struct arg){ \ 1145 .size = sizeof(*((s *)0)->f), \ 1146 }) 1147 1148 /** Static initializer for ARGS() with arbitrary offset and size. */ 1149 #define ARGS_ENTRY_ARB(o, s) \ 1150 (&(const struct arg){ \ 1151 .offset = (o), \ 1152 .size = (s), \ 1153 }) 1154 1155 /** Same as ARGS_ENTRY_ARB() with bounded values. */ 1156 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ 1157 (&(const struct arg){ \ 1158 .bounded = 1, \ 1159 .min = (i), \ 1160 .max = (a), \ 1161 .offset = (o), \ 1162 .size = (s), \ 1163 }) 1164 1165 /** Same as ARGS_ENTRY() using network byte ordering. */ 1166 #define ARGS_ENTRY_HTON(s, f) \ 1167 (&(const struct arg){ \ 1168 .hton = 1, \ 1169 .offset = offsetof(s, f), \ 1170 .size = sizeof(((s *)0)->f), \ 1171 }) 1172 1173 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ 1174 #define ARG_ENTRY_HTON(s) \ 1175 (&(const struct arg){ \ 1176 .hton = 1, \ 1177 .offset = 0, \ 1178 .size = sizeof(s), \ 1179 }) 1180 1181 /** Parser output buffer layout expected by cmd_flow_parsed(). */ 1182 struct buffer { 1183 enum index command; /**< Flow command. */ 1184 portid_t port; /**< Affected port ID. */ 1185 queueid_t queue; /** Async queue ID. */ 1186 bool postpone; /** Postpone async operation */ 1187 union { 1188 struct { 1189 struct rte_flow_port_attr port_attr; 1190 uint32_t nb_queue; 1191 struct rte_flow_queue_attr queue_attr; 1192 } configure; /**< Configuration arguments. */ 1193 struct { 1194 uint32_t *template_id; 1195 uint32_t template_id_n; 1196 } templ_destroy; /**< Template destroy arguments. */ 1197 struct { 1198 uint32_t id; 1199 struct rte_flow_template_table_attr attr; 1200 uint32_t *pat_templ_id; 1201 uint32_t pat_templ_id_n; 1202 uint32_t *act_templ_id; 1203 uint32_t act_templ_id_n; 1204 } table; /**< Table arguments. */ 1205 struct { 1206 uint32_t *table_id; 1207 uint32_t table_id_n; 1208 } table_destroy; /**< Template destroy arguments. */ 1209 struct { 1210 uint32_t *action_id; 1211 uint32_t action_id_n; 1212 } ia_destroy; /**< Indirect action destroy arguments. */ 1213 struct { 1214 uint32_t action_id; 1215 enum rte_flow_query_update_mode qu_mode; 1216 } ia; /* Indirect action query arguments */ 1217 struct { 1218 uint32_t table_id; 1219 uint32_t pat_templ_id; 1220 uint32_t rule_id; 1221 uint32_t act_templ_id; 1222 struct rte_flow_attr attr; 1223 struct tunnel_ops tunnel_ops; 1224 uintptr_t user_id; 1225 struct rte_flow_item *pattern; 1226 struct rte_flow_action *actions; 1227 struct rte_flow_action *masks; 1228 uint32_t pattern_n; 1229 uint32_t actions_n; 1230 uint8_t *data; 1231 enum rte_flow_encap_hash_field field; 1232 uint8_t encap_hash; 1233 } vc; /**< Validate/create arguments. */ 1234 struct { 1235 uint64_t *rule; 1236 uint64_t rule_n; 1237 bool is_user_id; 1238 } destroy; /**< Destroy arguments. */ 1239 struct { 1240 char file[128]; 1241 bool mode; 1242 uint64_t rule; 1243 bool is_user_id; 1244 } dump; /**< Dump arguments. */ 1245 struct { 1246 uint64_t rule; 1247 struct rte_flow_action action; 1248 bool is_user_id; 1249 } query; /**< Query arguments. */ 1250 struct { 1251 uint32_t *group; 1252 uint32_t group_n; 1253 } list; /**< List arguments. */ 1254 struct { 1255 int set; 1256 } isolate; /**< Isolated mode arguments. */ 1257 struct { 1258 int destroy; 1259 } aged; /**< Aged arguments. */ 1260 struct { 1261 uint32_t policy_id; 1262 } policy;/**< Policy arguments. */ 1263 struct { 1264 uint16_t token; 1265 uintptr_t uintptr; 1266 char filename[128]; 1267 } flex; /**< Flex arguments*/ 1268 } args; /**< Command arguments. */ 1269 }; 1270 1271 /** Private data for pattern items. */ 1272 struct parse_item_priv { 1273 enum rte_flow_item_type type; /**< Item type. */ 1274 uint32_t size; /**< Size of item specification structure. */ 1275 }; 1276 1277 #define PRIV_ITEM(t, s) \ 1278 (&(const struct parse_item_priv){ \ 1279 .type = RTE_FLOW_ITEM_TYPE_ ## t, \ 1280 .size = s, \ 1281 }) 1282 1283 /** Private data for actions. */ 1284 struct parse_action_priv { 1285 enum rte_flow_action_type type; /**< Action type. */ 1286 uint32_t size; /**< Size of action configuration structure. */ 1287 }; 1288 1289 #define PRIV_ACTION(t, s) \ 1290 (&(const struct parse_action_priv){ \ 1291 .type = RTE_FLOW_ACTION_TYPE_ ## t, \ 1292 .size = s, \ 1293 }) 1294 1295 static const enum index next_flex_item[] = { 1296 FLEX_ITEM_INIT, 1297 FLEX_ITEM_CREATE, 1298 FLEX_ITEM_DESTROY, 1299 ZERO, 1300 }; 1301 1302 static const enum index next_config_attr[] = { 1303 CONFIG_QUEUES_NUMBER, 1304 CONFIG_QUEUES_SIZE, 1305 CONFIG_COUNTERS_NUMBER, 1306 CONFIG_AGING_OBJECTS_NUMBER, 1307 CONFIG_METERS_NUMBER, 1308 CONFIG_CONN_TRACK_NUMBER, 1309 CONFIG_QUOTAS_NUMBER, 1310 CONFIG_FLAGS, 1311 CONFIG_HOST_PORT, 1312 END, 1313 ZERO, 1314 }; 1315 1316 static const enum index next_pt_subcmd[] = { 1317 PATTERN_TEMPLATE_CREATE, 1318 PATTERN_TEMPLATE_DESTROY, 1319 ZERO, 1320 }; 1321 1322 static const enum index next_pt_attr[] = { 1323 PATTERN_TEMPLATE_CREATE_ID, 1324 PATTERN_TEMPLATE_RELAXED_MATCHING, 1325 PATTERN_TEMPLATE_INGRESS, 1326 PATTERN_TEMPLATE_EGRESS, 1327 PATTERN_TEMPLATE_TRANSFER, 1328 PATTERN_TEMPLATE_SPEC, 1329 ZERO, 1330 }; 1331 1332 static const enum index next_pt_destroy_attr[] = { 1333 PATTERN_TEMPLATE_DESTROY_ID, 1334 END, 1335 ZERO, 1336 }; 1337 1338 static const enum index next_at_subcmd[] = { 1339 ACTIONS_TEMPLATE_CREATE, 1340 ACTIONS_TEMPLATE_DESTROY, 1341 ZERO, 1342 }; 1343 1344 static const enum index next_at_attr[] = { 1345 ACTIONS_TEMPLATE_CREATE_ID, 1346 ACTIONS_TEMPLATE_INGRESS, 1347 ACTIONS_TEMPLATE_EGRESS, 1348 ACTIONS_TEMPLATE_TRANSFER, 1349 ACTIONS_TEMPLATE_SPEC, 1350 ZERO, 1351 }; 1352 1353 static const enum index next_at_destroy_attr[] = { 1354 ACTIONS_TEMPLATE_DESTROY_ID, 1355 END, 1356 ZERO, 1357 }; 1358 1359 static const enum index next_group_attr[] = { 1360 GROUP_INGRESS, 1361 GROUP_EGRESS, 1362 GROUP_TRANSFER, 1363 GROUP_SET_MISS_ACTIONS, 1364 ZERO, 1365 }; 1366 1367 static const enum index next_table_subcmd[] = { 1368 TABLE_CREATE, 1369 TABLE_DESTROY, 1370 TABLE_RESIZE, 1371 TABLE_RESIZE_COMPLETE, 1372 ZERO, 1373 }; 1374 1375 static const enum index next_table_attr[] = { 1376 TABLE_CREATE_ID, 1377 TABLE_GROUP, 1378 TABLE_INSERTION_TYPE, 1379 TABLE_HASH_FUNC, 1380 TABLE_PRIORITY, 1381 TABLE_INGRESS, 1382 TABLE_EGRESS, 1383 TABLE_TRANSFER, 1384 TABLE_TRANSFER_WIRE_ORIG, 1385 TABLE_TRANSFER_VPORT_ORIG, 1386 TABLE_RESIZABLE, 1387 TABLE_RULES_NUMBER, 1388 TABLE_PATTERN_TEMPLATE, 1389 TABLE_ACTIONS_TEMPLATE, 1390 END, 1391 ZERO, 1392 }; 1393 1394 static const enum index next_table_destroy_attr[] = { 1395 TABLE_DESTROY_ID, 1396 END, 1397 ZERO, 1398 }; 1399 1400 static const enum index next_queue_subcmd[] = { 1401 QUEUE_CREATE, 1402 QUEUE_DESTROY, 1403 QUEUE_FLOW_UPDATE_RESIZED, 1404 QUEUE_UPDATE, 1405 QUEUE_AGED, 1406 QUEUE_INDIRECT_ACTION, 1407 ZERO, 1408 }; 1409 1410 static const enum index next_queue_destroy_attr[] = { 1411 QUEUE_DESTROY_ID, 1412 END, 1413 ZERO, 1414 }; 1415 1416 static const enum index next_qia_subcmd[] = { 1417 QUEUE_INDIRECT_ACTION_CREATE, 1418 QUEUE_INDIRECT_ACTION_UPDATE, 1419 QUEUE_INDIRECT_ACTION_DESTROY, 1420 QUEUE_INDIRECT_ACTION_QUERY, 1421 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 1422 ZERO, 1423 }; 1424 1425 static const enum index next_qia_create_attr[] = { 1426 QUEUE_INDIRECT_ACTION_CREATE_ID, 1427 QUEUE_INDIRECT_ACTION_INGRESS, 1428 QUEUE_INDIRECT_ACTION_EGRESS, 1429 QUEUE_INDIRECT_ACTION_TRANSFER, 1430 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 1431 QUEUE_INDIRECT_ACTION_SPEC, 1432 QUEUE_INDIRECT_ACTION_LIST, 1433 ZERO, 1434 }; 1435 1436 static const enum index next_qia_update_attr[] = { 1437 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1438 QUEUE_INDIRECT_ACTION_SPEC, 1439 ZERO, 1440 }; 1441 1442 static const enum index next_qia_destroy_attr[] = { 1443 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 1444 QUEUE_INDIRECT_ACTION_DESTROY_ID, 1445 END, 1446 ZERO, 1447 }; 1448 1449 static const enum index next_qia_query_attr[] = { 1450 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 1451 END, 1452 ZERO, 1453 }; 1454 1455 static const enum index next_ia_create_attr[] = { 1456 INDIRECT_ACTION_CREATE_ID, 1457 INDIRECT_ACTION_INGRESS, 1458 INDIRECT_ACTION_EGRESS, 1459 INDIRECT_ACTION_TRANSFER, 1460 INDIRECT_ACTION_SPEC, 1461 INDIRECT_ACTION_LIST, 1462 INDIRECT_ACTION_FLOW_CONF, 1463 ZERO, 1464 }; 1465 1466 static const enum index next_ia[] = { 1467 INDIRECT_ACTION_ID2PTR, 1468 ACTION_NEXT, 1469 ZERO 1470 }; 1471 1472 static const enum index next_ial[] = { 1473 ACTION_INDIRECT_LIST_HANDLE, 1474 ACTION_INDIRECT_LIST_CONF, 1475 ACTION_NEXT, 1476 ZERO 1477 }; 1478 1479 static const enum index next_qia_qu_attr[] = { 1480 QUEUE_INDIRECT_ACTION_QU_MODE, 1481 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1482 INDIRECT_ACTION_SPEC, 1483 ZERO 1484 }; 1485 1486 static const enum index next_ia_qu_attr[] = { 1487 INDIRECT_ACTION_QU_MODE, 1488 INDIRECT_ACTION_SPEC, 1489 ZERO 1490 }; 1491 1492 static const enum index next_dump_subcmd[] = { 1493 DUMP_ALL, 1494 DUMP_ONE, 1495 DUMP_IS_USER_ID, 1496 ZERO, 1497 }; 1498 1499 static const enum index next_ia_subcmd[] = { 1500 INDIRECT_ACTION_CREATE, 1501 INDIRECT_ACTION_UPDATE, 1502 INDIRECT_ACTION_DESTROY, 1503 INDIRECT_ACTION_QUERY, 1504 INDIRECT_ACTION_QUERY_UPDATE, 1505 ZERO, 1506 }; 1507 1508 static const enum index next_vc_attr[] = { 1509 VC_GROUP, 1510 VC_PRIORITY, 1511 VC_INGRESS, 1512 VC_EGRESS, 1513 VC_TRANSFER, 1514 VC_TUNNEL_SET, 1515 VC_TUNNEL_MATCH, 1516 VC_USER_ID, 1517 ITEM_PATTERN, 1518 ZERO, 1519 }; 1520 1521 static const enum index next_destroy_attr[] = { 1522 DESTROY_RULE, 1523 DESTROY_IS_USER_ID, 1524 END, 1525 ZERO, 1526 }; 1527 1528 static const enum index next_dump_attr[] = { 1529 COMMON_FILE_PATH, 1530 END, 1531 ZERO, 1532 }; 1533 1534 static const enum index next_query_attr[] = { 1535 QUERY_IS_USER_ID, 1536 END, 1537 ZERO, 1538 }; 1539 1540 static const enum index next_list_attr[] = { 1541 LIST_GROUP, 1542 END, 1543 ZERO, 1544 }; 1545 1546 static const enum index next_aged_attr[] = { 1547 AGED_DESTROY, 1548 END, 1549 ZERO, 1550 }; 1551 1552 static const enum index next_ia_destroy_attr[] = { 1553 INDIRECT_ACTION_DESTROY_ID, 1554 END, 1555 ZERO, 1556 }; 1557 1558 static const enum index next_async_insert_subcmd[] = { 1559 QUEUE_PATTERN_TEMPLATE, 1560 QUEUE_RULE_ID, 1561 ZERO, 1562 }; 1563 1564 static const enum index item_param[] = { 1565 ITEM_PARAM_IS, 1566 ITEM_PARAM_SPEC, 1567 ITEM_PARAM_LAST, 1568 ITEM_PARAM_MASK, 1569 ITEM_PARAM_PREFIX, 1570 ZERO, 1571 }; 1572 1573 static const enum index next_item[] = { 1574 ITEM_END, 1575 ITEM_VOID, 1576 ITEM_INVERT, 1577 ITEM_ANY, 1578 ITEM_PORT_ID, 1579 ITEM_MARK, 1580 ITEM_RAW, 1581 ITEM_ETH, 1582 ITEM_VLAN, 1583 ITEM_IPV4, 1584 ITEM_IPV6, 1585 ITEM_ICMP, 1586 ITEM_UDP, 1587 ITEM_TCP, 1588 ITEM_SCTP, 1589 ITEM_VXLAN, 1590 ITEM_E_TAG, 1591 ITEM_NVGRE, 1592 ITEM_MPLS, 1593 ITEM_GRE, 1594 ITEM_FUZZY, 1595 ITEM_GTP, 1596 ITEM_GTPC, 1597 ITEM_GTPU, 1598 ITEM_GENEVE, 1599 ITEM_VXLAN_GPE, 1600 ITEM_ARP_ETH_IPV4, 1601 ITEM_IPV6_EXT, 1602 ITEM_IPV6_FRAG_EXT, 1603 ITEM_IPV6_ROUTING_EXT, 1604 ITEM_ICMP6, 1605 ITEM_ICMP6_ECHO_REQUEST, 1606 ITEM_ICMP6_ECHO_REPLY, 1607 ITEM_ICMP6_ND_NS, 1608 ITEM_ICMP6_ND_NA, 1609 ITEM_ICMP6_ND_OPT, 1610 ITEM_ICMP6_ND_OPT_SLA_ETH, 1611 ITEM_ICMP6_ND_OPT_TLA_ETH, 1612 ITEM_META, 1613 ITEM_RANDOM, 1614 ITEM_GRE_KEY, 1615 ITEM_GRE_OPTION, 1616 ITEM_GTP_PSC, 1617 ITEM_PPPOES, 1618 ITEM_PPPOED, 1619 ITEM_PPPOE_PROTO_ID, 1620 ITEM_HIGIG2, 1621 ITEM_TAG, 1622 ITEM_L2TPV3OIP, 1623 ITEM_ESP, 1624 ITEM_AH, 1625 ITEM_PFCP, 1626 ITEM_ECPRI, 1627 ITEM_GENEVE_OPT, 1628 ITEM_INTEGRITY, 1629 ITEM_CONNTRACK, 1630 ITEM_PORT_REPRESENTOR, 1631 ITEM_REPRESENTED_PORT, 1632 ITEM_FLEX, 1633 ITEM_L2TPV2, 1634 ITEM_PPP, 1635 ITEM_METER, 1636 ITEM_QUOTA, 1637 ITEM_AGGR_AFFINITY, 1638 ITEM_TX_QUEUE, 1639 ITEM_IB_BTH, 1640 ITEM_PTYPE, 1641 ITEM_NSH, 1642 ITEM_COMPARE, 1643 END_SET, 1644 ZERO, 1645 }; 1646 1647 static const enum index item_fuzzy[] = { 1648 ITEM_FUZZY_THRESH, 1649 ITEM_NEXT, 1650 ZERO, 1651 }; 1652 1653 static const enum index item_any[] = { 1654 ITEM_ANY_NUM, 1655 ITEM_NEXT, 1656 ZERO, 1657 }; 1658 1659 static const enum index item_port_id[] = { 1660 ITEM_PORT_ID_ID, 1661 ITEM_NEXT, 1662 ZERO, 1663 }; 1664 1665 static const enum index item_mark[] = { 1666 ITEM_MARK_ID, 1667 ITEM_NEXT, 1668 ZERO, 1669 }; 1670 1671 static const enum index item_raw[] = { 1672 ITEM_RAW_RELATIVE, 1673 ITEM_RAW_SEARCH, 1674 ITEM_RAW_OFFSET, 1675 ITEM_RAW_LIMIT, 1676 ITEM_RAW_PATTERN, 1677 ITEM_RAW_PATTERN_HEX, 1678 ITEM_NEXT, 1679 ZERO, 1680 }; 1681 1682 static const enum index item_eth[] = { 1683 ITEM_ETH_DST, 1684 ITEM_ETH_SRC, 1685 ITEM_ETH_TYPE, 1686 ITEM_ETH_HAS_VLAN, 1687 ITEM_NEXT, 1688 ZERO, 1689 }; 1690 1691 static const enum index item_vlan[] = { 1692 ITEM_VLAN_TCI, 1693 ITEM_VLAN_PCP, 1694 ITEM_VLAN_DEI, 1695 ITEM_VLAN_VID, 1696 ITEM_VLAN_INNER_TYPE, 1697 ITEM_VLAN_HAS_MORE_VLAN, 1698 ITEM_NEXT, 1699 ZERO, 1700 }; 1701 1702 static const enum index item_ipv4[] = { 1703 ITEM_IPV4_VER_IHL, 1704 ITEM_IPV4_TOS, 1705 ITEM_IPV4_LENGTH, 1706 ITEM_IPV4_ID, 1707 ITEM_IPV4_FRAGMENT_OFFSET, 1708 ITEM_IPV4_TTL, 1709 ITEM_IPV4_PROTO, 1710 ITEM_IPV4_SRC, 1711 ITEM_IPV4_DST, 1712 ITEM_NEXT, 1713 ZERO, 1714 }; 1715 1716 static const enum index item_ipv6[] = { 1717 ITEM_IPV6_TC, 1718 ITEM_IPV6_FLOW, 1719 ITEM_IPV6_LEN, 1720 ITEM_IPV6_PROTO, 1721 ITEM_IPV6_HOP, 1722 ITEM_IPV6_SRC, 1723 ITEM_IPV6_DST, 1724 ITEM_IPV6_HAS_FRAG_EXT, 1725 ITEM_IPV6_ROUTING_EXT, 1726 ITEM_NEXT, 1727 ZERO, 1728 }; 1729 1730 static const enum index item_ipv6_routing_ext[] = { 1731 ITEM_IPV6_ROUTING_EXT_TYPE, 1732 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 1733 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 1734 ITEM_NEXT, 1735 ZERO, 1736 }; 1737 1738 static const enum index item_icmp[] = { 1739 ITEM_ICMP_TYPE, 1740 ITEM_ICMP_CODE, 1741 ITEM_ICMP_IDENT, 1742 ITEM_ICMP_SEQ, 1743 ITEM_NEXT, 1744 ZERO, 1745 }; 1746 1747 static const enum index item_udp[] = { 1748 ITEM_UDP_SRC, 1749 ITEM_UDP_DST, 1750 ITEM_NEXT, 1751 ZERO, 1752 }; 1753 1754 static const enum index item_tcp[] = { 1755 ITEM_TCP_SRC, 1756 ITEM_TCP_DST, 1757 ITEM_TCP_FLAGS, 1758 ITEM_NEXT, 1759 ZERO, 1760 }; 1761 1762 static const enum index item_sctp[] = { 1763 ITEM_SCTP_SRC, 1764 ITEM_SCTP_DST, 1765 ITEM_SCTP_TAG, 1766 ITEM_SCTP_CKSUM, 1767 ITEM_NEXT, 1768 ZERO, 1769 }; 1770 1771 static const enum index item_vxlan[] = { 1772 ITEM_VXLAN_VNI, 1773 ITEM_VXLAN_LAST_RSVD, 1774 ITEM_NEXT, 1775 ZERO, 1776 }; 1777 1778 static const enum index item_e_tag[] = { 1779 ITEM_E_TAG_GRP_ECID_B, 1780 ITEM_NEXT, 1781 ZERO, 1782 }; 1783 1784 static const enum index item_nvgre[] = { 1785 ITEM_NVGRE_TNI, 1786 ITEM_NEXT, 1787 ZERO, 1788 }; 1789 1790 static const enum index item_mpls[] = { 1791 ITEM_MPLS_LABEL, 1792 ITEM_MPLS_TC, 1793 ITEM_MPLS_S, 1794 ITEM_MPLS_TTL, 1795 ITEM_NEXT, 1796 ZERO, 1797 }; 1798 1799 static const enum index item_gre[] = { 1800 ITEM_GRE_PROTO, 1801 ITEM_GRE_C_RSVD0_VER, 1802 ITEM_GRE_C_BIT, 1803 ITEM_GRE_K_BIT, 1804 ITEM_GRE_S_BIT, 1805 ITEM_NEXT, 1806 ZERO, 1807 }; 1808 1809 static const enum index item_gre_key[] = { 1810 ITEM_GRE_KEY_VALUE, 1811 ITEM_NEXT, 1812 ZERO, 1813 }; 1814 1815 static const enum index item_gre_option[] = { 1816 ITEM_GRE_OPTION_CHECKSUM, 1817 ITEM_GRE_OPTION_KEY, 1818 ITEM_GRE_OPTION_SEQUENCE, 1819 ITEM_NEXT, 1820 ZERO, 1821 }; 1822 1823 static const enum index item_gtp[] = { 1824 ITEM_GTP_FLAGS, 1825 ITEM_GTP_MSG_TYPE, 1826 ITEM_GTP_TEID, 1827 ITEM_NEXT, 1828 ZERO, 1829 }; 1830 1831 static const enum index item_geneve[] = { 1832 ITEM_GENEVE_VNI, 1833 ITEM_GENEVE_PROTO, 1834 ITEM_GENEVE_OPTLEN, 1835 ITEM_NEXT, 1836 ZERO, 1837 }; 1838 1839 static const enum index item_vxlan_gpe[] = { 1840 ITEM_VXLAN_GPE_VNI, 1841 ITEM_VXLAN_GPE_PROTO, 1842 ITEM_NEXT, 1843 ZERO, 1844 }; 1845 1846 static const enum index item_arp_eth_ipv4[] = { 1847 ITEM_ARP_ETH_IPV4_SHA, 1848 ITEM_ARP_ETH_IPV4_SPA, 1849 ITEM_ARP_ETH_IPV4_THA, 1850 ITEM_ARP_ETH_IPV4_TPA, 1851 ITEM_NEXT, 1852 ZERO, 1853 }; 1854 1855 static const enum index item_ipv6_ext[] = { 1856 ITEM_IPV6_EXT_NEXT_HDR, 1857 ITEM_NEXT, 1858 ZERO, 1859 }; 1860 1861 static const enum index item_ipv6_frag_ext[] = { 1862 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 1863 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 1864 ITEM_IPV6_FRAG_EXT_ID, 1865 ITEM_NEXT, 1866 ZERO, 1867 }; 1868 1869 static const enum index item_icmp6[] = { 1870 ITEM_ICMP6_TYPE, 1871 ITEM_ICMP6_CODE, 1872 ITEM_NEXT, 1873 ZERO, 1874 }; 1875 1876 static const enum index item_icmp6_echo_request[] = { 1877 ITEM_ICMP6_ECHO_REQUEST_ID, 1878 ITEM_ICMP6_ECHO_REQUEST_SEQ, 1879 ITEM_NEXT, 1880 ZERO, 1881 }; 1882 1883 static const enum index item_icmp6_echo_reply[] = { 1884 ITEM_ICMP6_ECHO_REPLY_ID, 1885 ITEM_ICMP6_ECHO_REPLY_SEQ, 1886 ITEM_NEXT, 1887 ZERO, 1888 }; 1889 1890 static const enum index item_icmp6_nd_ns[] = { 1891 ITEM_ICMP6_ND_NS_TARGET_ADDR, 1892 ITEM_NEXT, 1893 ZERO, 1894 }; 1895 1896 static const enum index item_icmp6_nd_na[] = { 1897 ITEM_ICMP6_ND_NA_TARGET_ADDR, 1898 ITEM_NEXT, 1899 ZERO, 1900 }; 1901 1902 static const enum index item_icmp6_nd_opt[] = { 1903 ITEM_ICMP6_ND_OPT_TYPE, 1904 ITEM_NEXT, 1905 ZERO, 1906 }; 1907 1908 static const enum index item_icmp6_nd_opt_sla_eth[] = { 1909 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 1910 ITEM_NEXT, 1911 ZERO, 1912 }; 1913 1914 static const enum index item_icmp6_nd_opt_tla_eth[] = { 1915 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 1916 ITEM_NEXT, 1917 ZERO, 1918 }; 1919 1920 static const enum index item_meta[] = { 1921 ITEM_META_DATA, 1922 ITEM_NEXT, 1923 ZERO, 1924 }; 1925 1926 static const enum index item_random[] = { 1927 ITEM_RANDOM_VALUE, 1928 ITEM_NEXT, 1929 ZERO, 1930 }; 1931 1932 static const enum index item_gtp_psc[] = { 1933 ITEM_GTP_PSC_QFI, 1934 ITEM_GTP_PSC_PDU_T, 1935 ITEM_NEXT, 1936 ZERO, 1937 }; 1938 1939 static const enum index item_pppoed[] = { 1940 ITEM_PPPOE_SEID, 1941 ITEM_NEXT, 1942 ZERO, 1943 }; 1944 1945 static const enum index item_pppoes[] = { 1946 ITEM_PPPOE_SEID, 1947 ITEM_NEXT, 1948 ZERO, 1949 }; 1950 1951 static const enum index item_pppoe_proto_id[] = { 1952 ITEM_NEXT, 1953 ZERO, 1954 }; 1955 1956 static const enum index item_higig2[] = { 1957 ITEM_HIGIG2_CLASSIFICATION, 1958 ITEM_HIGIG2_VID, 1959 ITEM_NEXT, 1960 ZERO, 1961 }; 1962 1963 static const enum index item_esp[] = { 1964 ITEM_ESP_SPI, 1965 ITEM_NEXT, 1966 ZERO, 1967 }; 1968 1969 static const enum index item_ah[] = { 1970 ITEM_AH_SPI, 1971 ITEM_NEXT, 1972 ZERO, 1973 }; 1974 1975 static const enum index item_pfcp[] = { 1976 ITEM_PFCP_S_FIELD, 1977 ITEM_PFCP_SEID, 1978 ITEM_NEXT, 1979 ZERO, 1980 }; 1981 1982 static const enum index next_set_raw[] = { 1983 SET_RAW_INDEX, 1984 ITEM_ETH, 1985 ZERO, 1986 }; 1987 1988 static const enum index item_tag[] = { 1989 ITEM_TAG_DATA, 1990 ITEM_TAG_INDEX, 1991 ITEM_NEXT, 1992 ZERO, 1993 }; 1994 1995 static const enum index item_l2tpv3oip[] = { 1996 ITEM_L2TPV3OIP_SESSION_ID, 1997 ITEM_NEXT, 1998 ZERO, 1999 }; 2000 2001 static const enum index item_ecpri[] = { 2002 ITEM_ECPRI_COMMON, 2003 ITEM_NEXT, 2004 ZERO, 2005 }; 2006 2007 static const enum index item_ecpri_common[] = { 2008 ITEM_ECPRI_COMMON_TYPE, 2009 ZERO, 2010 }; 2011 2012 static const enum index item_ecpri_common_type[] = { 2013 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 2014 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 2015 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 2016 ZERO, 2017 }; 2018 2019 static const enum index item_geneve_opt[] = { 2020 ITEM_GENEVE_OPT_CLASS, 2021 ITEM_GENEVE_OPT_TYPE, 2022 ITEM_GENEVE_OPT_LENGTH, 2023 ITEM_GENEVE_OPT_DATA, 2024 ITEM_NEXT, 2025 ZERO, 2026 }; 2027 2028 static const enum index item_integrity[] = { 2029 ITEM_INTEGRITY_LEVEL, 2030 ITEM_INTEGRITY_VALUE, 2031 ZERO, 2032 }; 2033 2034 static const enum index item_integrity_lv[] = { 2035 ITEM_INTEGRITY_LEVEL, 2036 ITEM_INTEGRITY_VALUE, 2037 ITEM_NEXT, 2038 ZERO, 2039 }; 2040 2041 static const enum index item_port_representor[] = { 2042 ITEM_PORT_REPRESENTOR_PORT_ID, 2043 ITEM_NEXT, 2044 ZERO, 2045 }; 2046 2047 static const enum index item_represented_port[] = { 2048 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 2049 ITEM_NEXT, 2050 ZERO, 2051 }; 2052 2053 static const enum index item_flex[] = { 2054 ITEM_FLEX_PATTERN_HANDLE, 2055 ITEM_FLEX_ITEM_HANDLE, 2056 ITEM_NEXT, 2057 ZERO, 2058 }; 2059 2060 static const enum index item_l2tpv2[] = { 2061 ITEM_L2TPV2_TYPE, 2062 ITEM_NEXT, 2063 ZERO, 2064 }; 2065 2066 static const enum index item_l2tpv2_type[] = { 2067 ITEM_L2TPV2_TYPE_DATA, 2068 ITEM_L2TPV2_TYPE_DATA_L, 2069 ITEM_L2TPV2_TYPE_DATA_S, 2070 ITEM_L2TPV2_TYPE_DATA_O, 2071 ITEM_L2TPV2_TYPE_DATA_L_S, 2072 ITEM_L2TPV2_TYPE_CTRL, 2073 ZERO, 2074 }; 2075 2076 static const enum index item_l2tpv2_type_data[] = { 2077 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 2078 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 2079 ITEM_NEXT, 2080 ZERO, 2081 }; 2082 2083 static const enum index item_l2tpv2_type_data_l[] = { 2084 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 2085 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 2086 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 2087 ITEM_NEXT, 2088 ZERO, 2089 }; 2090 2091 static const enum index item_l2tpv2_type_data_s[] = { 2092 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 2093 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 2094 ITEM_L2TPV2_MSG_DATA_S_NS, 2095 ITEM_L2TPV2_MSG_DATA_S_NR, 2096 ITEM_NEXT, 2097 ZERO, 2098 }; 2099 2100 static const enum index item_l2tpv2_type_data_o[] = { 2101 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 2102 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 2103 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 2104 ITEM_NEXT, 2105 ZERO, 2106 }; 2107 2108 static const enum index item_l2tpv2_type_data_l_s[] = { 2109 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 2110 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 2111 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 2112 ITEM_L2TPV2_MSG_DATA_L_S_NS, 2113 ITEM_L2TPV2_MSG_DATA_L_S_NR, 2114 ITEM_NEXT, 2115 ZERO, 2116 }; 2117 2118 static const enum index item_l2tpv2_type_ctrl[] = { 2119 ITEM_L2TPV2_MSG_CTRL_LENGTH, 2120 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 2121 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 2122 ITEM_L2TPV2_MSG_CTRL_NS, 2123 ITEM_L2TPV2_MSG_CTRL_NR, 2124 ITEM_NEXT, 2125 ZERO, 2126 }; 2127 2128 static const enum index item_ppp[] = { 2129 ITEM_PPP_ADDR, 2130 ITEM_PPP_CTRL, 2131 ITEM_PPP_PROTO_ID, 2132 ITEM_NEXT, 2133 ZERO, 2134 }; 2135 2136 static const enum index item_meter[] = { 2137 ITEM_METER_COLOR, 2138 ITEM_NEXT, 2139 ZERO, 2140 }; 2141 2142 static const enum index item_quota[] = { 2143 ITEM_QUOTA_STATE, 2144 ITEM_NEXT, 2145 ZERO, 2146 }; 2147 2148 static const enum index item_aggr_affinity[] = { 2149 ITEM_AGGR_AFFINITY_VALUE, 2150 ITEM_NEXT, 2151 ZERO, 2152 }; 2153 2154 static const enum index item_tx_queue[] = { 2155 ITEM_TX_QUEUE_VALUE, 2156 ITEM_NEXT, 2157 ZERO, 2158 }; 2159 2160 static const enum index item_ib_bth[] = { 2161 ITEM_IB_BTH_OPCODE, 2162 ITEM_IB_BTH_PKEY, 2163 ITEM_IB_BTH_DST_QPN, 2164 ITEM_IB_BTH_PSN, 2165 ITEM_NEXT, 2166 ZERO, 2167 }; 2168 2169 static const enum index item_ptype[] = { 2170 ITEM_PTYPE_VALUE, 2171 ITEM_NEXT, 2172 ZERO, 2173 }; 2174 2175 static const enum index item_nsh[] = { 2176 ITEM_NEXT, 2177 ZERO, 2178 }; 2179 2180 static const enum index item_compare_field[] = { 2181 ITEM_COMPARE_OP, 2182 ITEM_COMPARE_FIELD_A_TYPE, 2183 ITEM_COMPARE_FIELD_B_TYPE, 2184 ITEM_NEXT, 2185 ZERO, 2186 }; 2187 2188 static const enum index compare_field_a[] = { 2189 ITEM_COMPARE_FIELD_A_TYPE, 2190 ITEM_COMPARE_FIELD_A_LEVEL, 2191 ITEM_COMPARE_FIELD_A_TAG_INDEX, 2192 ITEM_COMPARE_FIELD_A_TYPE_ID, 2193 ITEM_COMPARE_FIELD_A_CLASS_ID, 2194 ITEM_COMPARE_FIELD_A_OFFSET, 2195 ITEM_COMPARE_FIELD_B_TYPE, 2196 ZERO, 2197 }; 2198 2199 static const enum index compare_field_b[] = { 2200 ITEM_COMPARE_FIELD_B_TYPE, 2201 ITEM_COMPARE_FIELD_B_LEVEL, 2202 ITEM_COMPARE_FIELD_B_TAG_INDEX, 2203 ITEM_COMPARE_FIELD_B_TYPE_ID, 2204 ITEM_COMPARE_FIELD_B_CLASS_ID, 2205 ITEM_COMPARE_FIELD_B_OFFSET, 2206 ITEM_COMPARE_FIELD_B_VALUE, 2207 ITEM_COMPARE_FIELD_B_POINTER, 2208 ITEM_COMPARE_FIELD_WIDTH, 2209 ZERO, 2210 }; 2211 2212 static const enum index next_action[] = { 2213 ACTION_END, 2214 ACTION_VOID, 2215 ACTION_PASSTHRU, 2216 ACTION_SKIP_CMAN, 2217 ACTION_JUMP, 2218 ACTION_MARK, 2219 ACTION_FLAG, 2220 ACTION_QUEUE, 2221 ACTION_DROP, 2222 ACTION_COUNT, 2223 ACTION_RSS, 2224 ACTION_PF, 2225 ACTION_VF, 2226 ACTION_PORT_ID, 2227 ACTION_METER, 2228 ACTION_METER_COLOR, 2229 ACTION_METER_MARK, 2230 ACTION_OF_DEC_NW_TTL, 2231 ACTION_OF_POP_VLAN, 2232 ACTION_OF_PUSH_VLAN, 2233 ACTION_OF_SET_VLAN_VID, 2234 ACTION_OF_SET_VLAN_PCP, 2235 ACTION_OF_POP_MPLS, 2236 ACTION_OF_PUSH_MPLS, 2237 ACTION_VXLAN_ENCAP, 2238 ACTION_VXLAN_DECAP, 2239 ACTION_NVGRE_ENCAP, 2240 ACTION_NVGRE_DECAP, 2241 ACTION_L2_ENCAP, 2242 ACTION_L2_DECAP, 2243 ACTION_MPLSOGRE_ENCAP, 2244 ACTION_MPLSOGRE_DECAP, 2245 ACTION_MPLSOUDP_ENCAP, 2246 ACTION_MPLSOUDP_DECAP, 2247 ACTION_SET_IPV4_SRC, 2248 ACTION_SET_IPV4_DST, 2249 ACTION_SET_IPV6_SRC, 2250 ACTION_SET_IPV6_DST, 2251 ACTION_SET_TP_SRC, 2252 ACTION_SET_TP_DST, 2253 ACTION_MAC_SWAP, 2254 ACTION_DEC_TTL, 2255 ACTION_SET_TTL, 2256 ACTION_SET_MAC_SRC, 2257 ACTION_SET_MAC_DST, 2258 ACTION_INC_TCP_SEQ, 2259 ACTION_DEC_TCP_SEQ, 2260 ACTION_INC_TCP_ACK, 2261 ACTION_DEC_TCP_ACK, 2262 ACTION_RAW_ENCAP, 2263 ACTION_RAW_DECAP, 2264 ACTION_SET_TAG, 2265 ACTION_SET_META, 2266 ACTION_SET_IPV4_DSCP, 2267 ACTION_SET_IPV6_DSCP, 2268 ACTION_AGE, 2269 ACTION_AGE_UPDATE, 2270 ACTION_SAMPLE, 2271 ACTION_INDIRECT, 2272 ACTION_INDIRECT_LIST, 2273 ACTION_SHARED_INDIRECT, 2274 ACTION_MODIFY_FIELD, 2275 ACTION_CONNTRACK, 2276 ACTION_CONNTRACK_UPDATE, 2277 ACTION_PORT_REPRESENTOR, 2278 ACTION_REPRESENTED_PORT, 2279 ACTION_SEND_TO_KERNEL, 2280 ACTION_QUOTA_CREATE, 2281 ACTION_QUOTA_QU, 2282 ACTION_IPV6_EXT_REMOVE, 2283 ACTION_IPV6_EXT_PUSH, 2284 ACTION_NAT64, 2285 ZERO, 2286 }; 2287 2288 static const enum index action_quota_create[] = { 2289 ACTION_QUOTA_CREATE_LIMIT, 2290 ACTION_QUOTA_CREATE_MODE, 2291 ACTION_NEXT, 2292 ZERO 2293 }; 2294 2295 static const enum index action_quota_update[] = { 2296 ACTION_QUOTA_QU_LIMIT, 2297 ACTION_QUOTA_QU_UPDATE_OP, 2298 ACTION_NEXT, 2299 ZERO 2300 }; 2301 2302 static const enum index action_mark[] = { 2303 ACTION_MARK_ID, 2304 ACTION_NEXT, 2305 ZERO, 2306 }; 2307 2308 static const enum index action_queue[] = { 2309 ACTION_QUEUE_INDEX, 2310 ACTION_NEXT, 2311 ZERO, 2312 }; 2313 2314 static const enum index action_count[] = { 2315 ACTION_COUNT_ID, 2316 ACTION_NEXT, 2317 ZERO, 2318 }; 2319 2320 static const enum index action_rss[] = { 2321 ACTION_RSS_FUNC, 2322 ACTION_RSS_LEVEL, 2323 ACTION_RSS_TYPES, 2324 ACTION_RSS_KEY, 2325 ACTION_RSS_KEY_LEN, 2326 ACTION_RSS_QUEUES, 2327 ACTION_NEXT, 2328 ZERO, 2329 }; 2330 2331 static const enum index action_vf[] = { 2332 ACTION_VF_ORIGINAL, 2333 ACTION_VF_ID, 2334 ACTION_NEXT, 2335 ZERO, 2336 }; 2337 2338 static const enum index action_port_id[] = { 2339 ACTION_PORT_ID_ORIGINAL, 2340 ACTION_PORT_ID_ID, 2341 ACTION_NEXT, 2342 ZERO, 2343 }; 2344 2345 static const enum index action_meter[] = { 2346 ACTION_METER_ID, 2347 ACTION_NEXT, 2348 ZERO, 2349 }; 2350 2351 static const enum index action_meter_color[] = { 2352 ACTION_METER_COLOR_TYPE, 2353 ACTION_NEXT, 2354 ZERO, 2355 }; 2356 2357 static const enum index action_meter_mark[] = { 2358 ACTION_METER_PROFILE, 2359 ACTION_METER_POLICY, 2360 ACTION_METER_COLOR_MODE, 2361 ACTION_METER_STATE, 2362 ACTION_NEXT, 2363 ZERO, 2364 }; 2365 2366 static const enum index action_of_push_vlan[] = { 2367 ACTION_OF_PUSH_VLAN_ETHERTYPE, 2368 ACTION_NEXT, 2369 ZERO, 2370 }; 2371 2372 static const enum index action_of_set_vlan_vid[] = { 2373 ACTION_OF_SET_VLAN_VID_VLAN_VID, 2374 ACTION_NEXT, 2375 ZERO, 2376 }; 2377 2378 static const enum index action_of_set_vlan_pcp[] = { 2379 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 2380 ACTION_NEXT, 2381 ZERO, 2382 }; 2383 2384 static const enum index action_of_pop_mpls[] = { 2385 ACTION_OF_POP_MPLS_ETHERTYPE, 2386 ACTION_NEXT, 2387 ZERO, 2388 }; 2389 2390 static const enum index action_of_push_mpls[] = { 2391 ACTION_OF_PUSH_MPLS_ETHERTYPE, 2392 ACTION_NEXT, 2393 ZERO, 2394 }; 2395 2396 static const enum index action_set_ipv4_src[] = { 2397 ACTION_SET_IPV4_SRC_IPV4_SRC, 2398 ACTION_NEXT, 2399 ZERO, 2400 }; 2401 2402 static const enum index action_set_mac_src[] = { 2403 ACTION_SET_MAC_SRC_MAC_SRC, 2404 ACTION_NEXT, 2405 ZERO, 2406 }; 2407 2408 static const enum index action_set_ipv4_dst[] = { 2409 ACTION_SET_IPV4_DST_IPV4_DST, 2410 ACTION_NEXT, 2411 ZERO, 2412 }; 2413 2414 static const enum index action_set_ipv6_src[] = { 2415 ACTION_SET_IPV6_SRC_IPV6_SRC, 2416 ACTION_NEXT, 2417 ZERO, 2418 }; 2419 2420 static const enum index action_set_ipv6_dst[] = { 2421 ACTION_SET_IPV6_DST_IPV6_DST, 2422 ACTION_NEXT, 2423 ZERO, 2424 }; 2425 2426 static const enum index action_set_tp_src[] = { 2427 ACTION_SET_TP_SRC_TP_SRC, 2428 ACTION_NEXT, 2429 ZERO, 2430 }; 2431 2432 static const enum index action_set_tp_dst[] = { 2433 ACTION_SET_TP_DST_TP_DST, 2434 ACTION_NEXT, 2435 ZERO, 2436 }; 2437 2438 static const enum index action_set_ttl[] = { 2439 ACTION_SET_TTL_TTL, 2440 ACTION_NEXT, 2441 ZERO, 2442 }; 2443 2444 static const enum index action_jump[] = { 2445 ACTION_JUMP_GROUP, 2446 ACTION_NEXT, 2447 ZERO, 2448 }; 2449 2450 static const enum index action_set_mac_dst[] = { 2451 ACTION_SET_MAC_DST_MAC_DST, 2452 ACTION_NEXT, 2453 ZERO, 2454 }; 2455 2456 static const enum index action_inc_tcp_seq[] = { 2457 ACTION_INC_TCP_SEQ_VALUE, 2458 ACTION_NEXT, 2459 ZERO, 2460 }; 2461 2462 static const enum index action_dec_tcp_seq[] = { 2463 ACTION_DEC_TCP_SEQ_VALUE, 2464 ACTION_NEXT, 2465 ZERO, 2466 }; 2467 2468 static const enum index action_inc_tcp_ack[] = { 2469 ACTION_INC_TCP_ACK_VALUE, 2470 ACTION_NEXT, 2471 ZERO, 2472 }; 2473 2474 static const enum index action_dec_tcp_ack[] = { 2475 ACTION_DEC_TCP_ACK_VALUE, 2476 ACTION_NEXT, 2477 ZERO, 2478 }; 2479 2480 static const enum index action_raw_encap[] = { 2481 ACTION_RAW_ENCAP_SIZE, 2482 ACTION_RAW_ENCAP_INDEX, 2483 ACTION_NEXT, 2484 ZERO, 2485 }; 2486 2487 static const enum index action_raw_decap[] = { 2488 ACTION_RAW_DECAP_INDEX, 2489 ACTION_NEXT, 2490 ZERO, 2491 }; 2492 2493 static const enum index action_ipv6_ext_remove[] = { 2494 ACTION_IPV6_EXT_REMOVE_INDEX, 2495 ACTION_NEXT, 2496 ZERO, 2497 }; 2498 2499 static const enum index action_ipv6_ext_push[] = { 2500 ACTION_IPV6_EXT_PUSH_INDEX, 2501 ACTION_NEXT, 2502 ZERO, 2503 }; 2504 2505 static const enum index action_set_tag[] = { 2506 ACTION_SET_TAG_DATA, 2507 ACTION_SET_TAG_INDEX, 2508 ACTION_SET_TAG_MASK, 2509 ACTION_NEXT, 2510 ZERO, 2511 }; 2512 2513 static const enum index action_set_meta[] = { 2514 ACTION_SET_META_DATA, 2515 ACTION_SET_META_MASK, 2516 ACTION_NEXT, 2517 ZERO, 2518 }; 2519 2520 static const enum index action_set_ipv4_dscp[] = { 2521 ACTION_SET_IPV4_DSCP_VALUE, 2522 ACTION_NEXT, 2523 ZERO, 2524 }; 2525 2526 static const enum index action_set_ipv6_dscp[] = { 2527 ACTION_SET_IPV6_DSCP_VALUE, 2528 ACTION_NEXT, 2529 ZERO, 2530 }; 2531 2532 static const enum index action_age[] = { 2533 ACTION_AGE, 2534 ACTION_AGE_TIMEOUT, 2535 ACTION_NEXT, 2536 ZERO, 2537 }; 2538 2539 static const enum index action_age_update[] = { 2540 ACTION_AGE_UPDATE, 2541 ACTION_AGE_UPDATE_TIMEOUT, 2542 ACTION_AGE_UPDATE_TOUCH, 2543 ACTION_NEXT, 2544 ZERO, 2545 }; 2546 2547 static const enum index action_sample[] = { 2548 ACTION_SAMPLE, 2549 ACTION_SAMPLE_RATIO, 2550 ACTION_SAMPLE_INDEX, 2551 ACTION_NEXT, 2552 ZERO, 2553 }; 2554 2555 static const enum index next_action_sample[] = { 2556 ACTION_QUEUE, 2557 ACTION_RSS, 2558 ACTION_MARK, 2559 ACTION_COUNT, 2560 ACTION_PORT_ID, 2561 ACTION_RAW_ENCAP, 2562 ACTION_VXLAN_ENCAP, 2563 ACTION_NVGRE_ENCAP, 2564 ACTION_REPRESENTED_PORT, 2565 ACTION_PORT_REPRESENTOR, 2566 ACTION_NEXT, 2567 ZERO, 2568 }; 2569 2570 static const enum index item_ipv6_push_ext[] = { 2571 ITEM_IPV6_PUSH_REMOVE_EXT, 2572 ZERO, 2573 }; 2574 2575 static const enum index item_ipv6_push_ext_type[] = { 2576 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 2577 ZERO, 2578 }; 2579 2580 static const enum index item_ipv6_push_ext_header[] = { 2581 ITEM_IPV6_ROUTING_EXT, 2582 ITEM_NEXT, 2583 ZERO, 2584 }; 2585 2586 static const enum index action_modify_field_dst[] = { 2587 ACTION_MODIFY_FIELD_DST_LEVEL, 2588 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 2589 ACTION_MODIFY_FIELD_DST_TYPE_ID, 2590 ACTION_MODIFY_FIELD_DST_CLASS_ID, 2591 ACTION_MODIFY_FIELD_DST_OFFSET, 2592 ACTION_MODIFY_FIELD_SRC_TYPE, 2593 ZERO, 2594 }; 2595 2596 static const enum index action_modify_field_src[] = { 2597 ACTION_MODIFY_FIELD_SRC_LEVEL, 2598 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 2599 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 2600 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 2601 ACTION_MODIFY_FIELD_SRC_OFFSET, 2602 ACTION_MODIFY_FIELD_SRC_VALUE, 2603 ACTION_MODIFY_FIELD_SRC_POINTER, 2604 ACTION_MODIFY_FIELD_WIDTH, 2605 ZERO, 2606 }; 2607 2608 static const enum index action_update_conntrack[] = { 2609 ACTION_CONNTRACK_UPDATE_DIR, 2610 ACTION_CONNTRACK_UPDATE_CTX, 2611 ACTION_NEXT, 2612 ZERO, 2613 }; 2614 2615 static const enum index action_port_representor[] = { 2616 ACTION_PORT_REPRESENTOR_PORT_ID, 2617 ACTION_NEXT, 2618 ZERO, 2619 }; 2620 2621 static const enum index action_represented_port[] = { 2622 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 2623 ACTION_NEXT, 2624 ZERO, 2625 }; 2626 2627 static const enum index action_nat64[] = { 2628 ACTION_NAT64_MODE, 2629 ACTION_NEXT, 2630 ZERO, 2631 }; 2632 2633 static const enum index next_hash_subcmd[] = { 2634 HASH_CALC_TABLE, 2635 HASH_CALC_ENCAP, 2636 ZERO, 2637 }; 2638 2639 static const enum index next_hash_encap_dest_subcmd[] = { 2640 ENCAP_HASH_FIELD_SRC_PORT, 2641 ENCAP_HASH_FIELD_GRE_FLOW_ID, 2642 ZERO, 2643 }; 2644 2645 static int parse_set_raw_encap_decap(struct context *, const struct token *, 2646 const char *, unsigned int, 2647 void *, unsigned int); 2648 static int parse_set_sample_action(struct context *, const struct token *, 2649 const char *, unsigned int, 2650 void *, unsigned int); 2651 static int parse_set_ipv6_ext_action(struct context *, const struct token *, 2652 const char *, unsigned int, 2653 void *, unsigned int); 2654 static int parse_set_init(struct context *, const struct token *, 2655 const char *, unsigned int, 2656 void *, unsigned int); 2657 static int 2658 parse_flex_handle(struct context *, const struct token *, 2659 const char *, unsigned int, void *, unsigned int); 2660 static int parse_init(struct context *, const struct token *, 2661 const char *, unsigned int, 2662 void *, unsigned int); 2663 static int parse_vc(struct context *, const struct token *, 2664 const char *, unsigned int, 2665 void *, unsigned int); 2666 static int parse_vc_spec(struct context *, const struct token *, 2667 const char *, unsigned int, void *, unsigned int); 2668 static int parse_vc_conf(struct context *, const struct token *, 2669 const char *, unsigned int, void *, unsigned int); 2670 static int parse_vc_conf_timeout(struct context *, const struct token *, 2671 const char *, unsigned int, void *, 2672 unsigned int); 2673 static int parse_vc_item_ecpri_type(struct context *, const struct token *, 2674 const char *, unsigned int, 2675 void *, unsigned int); 2676 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, 2677 const char *, unsigned int, 2678 void *, unsigned int); 2679 static int parse_vc_action_meter_color_type(struct context *, 2680 const struct token *, 2681 const char *, unsigned int, void *, 2682 unsigned int); 2683 static int parse_vc_action_rss(struct context *, const struct token *, 2684 const char *, unsigned int, void *, 2685 unsigned int); 2686 static int parse_vc_action_rss_func(struct context *, const struct token *, 2687 const char *, unsigned int, void *, 2688 unsigned int); 2689 static int parse_vc_action_rss_type(struct context *, const struct token *, 2690 const char *, unsigned int, void *, 2691 unsigned int); 2692 static int parse_vc_action_rss_queue(struct context *, const struct token *, 2693 const char *, unsigned int, void *, 2694 unsigned int); 2695 static int parse_vc_action_vxlan_encap(struct context *, const struct token *, 2696 const char *, unsigned int, void *, 2697 unsigned int); 2698 static int parse_vc_action_nvgre_encap(struct context *, const struct token *, 2699 const char *, unsigned int, void *, 2700 unsigned int); 2701 static int parse_vc_action_l2_encap(struct context *, const struct token *, 2702 const char *, unsigned int, void *, 2703 unsigned int); 2704 static int parse_vc_action_l2_decap(struct context *, const struct token *, 2705 const char *, unsigned int, void *, 2706 unsigned int); 2707 static int parse_vc_action_mplsogre_encap(struct context *, 2708 const struct token *, const char *, 2709 unsigned int, void *, unsigned int); 2710 static int parse_vc_action_mplsogre_decap(struct context *, 2711 const struct token *, const char *, 2712 unsigned int, void *, unsigned int); 2713 static int parse_vc_action_mplsoudp_encap(struct context *, 2714 const struct token *, const char *, 2715 unsigned int, void *, unsigned int); 2716 static int parse_vc_action_mplsoudp_decap(struct context *, 2717 const struct token *, const char *, 2718 unsigned int, void *, unsigned int); 2719 static int parse_vc_action_raw_encap(struct context *, 2720 const struct token *, const char *, 2721 unsigned int, void *, unsigned int); 2722 static int parse_vc_action_raw_decap(struct context *, 2723 const struct token *, const char *, 2724 unsigned int, void *, unsigned int); 2725 static int parse_vc_action_raw_encap_index(struct context *, 2726 const struct token *, const char *, 2727 unsigned int, void *, unsigned int); 2728 static int parse_vc_action_raw_decap_index(struct context *, 2729 const struct token *, const char *, 2730 unsigned int, void *, unsigned int); 2731 static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 2732 const char *str, unsigned int len, void *buf, 2733 unsigned int size); 2734 static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, 2735 const struct token *token, 2736 const char *str, unsigned int len, 2737 void *buf, 2738 unsigned int size); 2739 static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 2740 const char *str, unsigned int len, void *buf, 2741 unsigned int size); 2742 static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, 2743 const struct token *token, 2744 const char *str, unsigned int len, 2745 void *buf, 2746 unsigned int size); 2747 static int parse_vc_action_set_meta(struct context *ctx, 2748 const struct token *token, const char *str, 2749 unsigned int len, void *buf, 2750 unsigned int size); 2751 static int parse_vc_action_sample(struct context *ctx, 2752 const struct token *token, const char *str, 2753 unsigned int len, void *buf, 2754 unsigned int size); 2755 static int 2756 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 2757 const char *str, unsigned int len, void *buf, 2758 unsigned int size); 2759 static int 2760 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 2761 const char *str, unsigned int len, void *buf, 2762 unsigned int size); 2763 static int 2764 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 2765 const char *str, unsigned int len, void *buf, 2766 unsigned int size); 2767 static int 2768 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 2769 const char *str, unsigned int len, void *buf, 2770 unsigned int size); 2771 static int 2772 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 2773 const char *str, unsigned int len, void *buf, 2774 unsigned int size); 2775 static int parse_destroy(struct context *, const struct token *, 2776 const char *, unsigned int, 2777 void *, unsigned int); 2778 static int parse_flush(struct context *, const struct token *, 2779 const char *, unsigned int, 2780 void *, unsigned int); 2781 static int parse_dump(struct context *, const struct token *, 2782 const char *, unsigned int, 2783 void *, unsigned int); 2784 static int parse_query(struct context *, const struct token *, 2785 const char *, unsigned int, 2786 void *, unsigned int); 2787 static int parse_action(struct context *, const struct token *, 2788 const char *, unsigned int, 2789 void *, unsigned int); 2790 static int parse_list(struct context *, const struct token *, 2791 const char *, unsigned int, 2792 void *, unsigned int); 2793 static int parse_aged(struct context *, const struct token *, 2794 const char *, unsigned int, 2795 void *, unsigned int); 2796 static int parse_isolate(struct context *, const struct token *, 2797 const char *, unsigned int, 2798 void *, unsigned int); 2799 static int parse_configure(struct context *, const struct token *, 2800 const char *, unsigned int, 2801 void *, unsigned int); 2802 static int parse_template(struct context *, const struct token *, 2803 const char *, unsigned int, 2804 void *, unsigned int); 2805 static int parse_template_destroy(struct context *, const struct token *, 2806 const char *, unsigned int, 2807 void *, unsigned int); 2808 static int parse_table(struct context *, const struct token *, 2809 const char *, unsigned int, void *, unsigned int); 2810 static int parse_table_destroy(struct context *, const struct token *, 2811 const char *, unsigned int, 2812 void *, unsigned int); 2813 static int parse_qo(struct context *, const struct token *, 2814 const char *, unsigned int, 2815 void *, unsigned int); 2816 static int parse_qo_destroy(struct context *, const struct token *, 2817 const char *, unsigned int, 2818 void *, unsigned int); 2819 static int parse_qia(struct context *, const struct token *, 2820 const char *, unsigned int, 2821 void *, unsigned int); 2822 static int parse_qia_destroy(struct context *, const struct token *, 2823 const char *, unsigned int, 2824 void *, unsigned int); 2825 static int parse_push(struct context *, const struct token *, 2826 const char *, unsigned int, 2827 void *, unsigned int); 2828 static int parse_pull(struct context *, const struct token *, 2829 const char *, unsigned int, 2830 void *, unsigned int); 2831 static int parse_group(struct context *, const struct token *, 2832 const char *, unsigned int, 2833 void *, unsigned int); 2834 static int parse_hash(struct context *, const struct token *, 2835 const char *, unsigned int, 2836 void *, unsigned int); 2837 static int parse_tunnel(struct context *, const struct token *, 2838 const char *, unsigned int, 2839 void *, unsigned int); 2840 static int parse_flex(struct context *, const struct token *, 2841 const char *, unsigned int, void *, unsigned int); 2842 static int parse_int(struct context *, const struct token *, 2843 const char *, unsigned int, 2844 void *, unsigned int); 2845 static int parse_prefix(struct context *, const struct token *, 2846 const char *, unsigned int, 2847 void *, unsigned int); 2848 static int parse_boolean(struct context *, const struct token *, 2849 const char *, unsigned int, 2850 void *, unsigned int); 2851 static int parse_string(struct context *, const struct token *, 2852 const char *, unsigned int, 2853 void *, unsigned int); 2854 static int parse_hex(struct context *ctx, const struct token *token, 2855 const char *str, unsigned int len, 2856 void *buf, unsigned int size); 2857 static int parse_string0(struct context *, const struct token *, 2858 const char *, unsigned int, 2859 void *, unsigned int); 2860 static int parse_mac_addr(struct context *, const struct token *, 2861 const char *, unsigned int, 2862 void *, unsigned int); 2863 static int parse_ipv4_addr(struct context *, const struct token *, 2864 const char *, unsigned int, 2865 void *, unsigned int); 2866 static int parse_ipv6_addr(struct context *, const struct token *, 2867 const char *, unsigned int, 2868 void *, unsigned int); 2869 static int parse_port(struct context *, const struct token *, 2870 const char *, unsigned int, 2871 void *, unsigned int); 2872 static int parse_ia(struct context *, const struct token *, 2873 const char *, unsigned int, 2874 void *, unsigned int); 2875 static int parse_ia_destroy(struct context *ctx, const struct token *token, 2876 const char *str, unsigned int len, 2877 void *buf, unsigned int size); 2878 static int parse_ia_id2ptr(struct context *ctx, const struct token *token, 2879 const char *str, unsigned int len, void *buf, 2880 unsigned int size); 2881 2882 static int parse_indlst_id2ptr(struct context *ctx, const struct token *token, 2883 const char *str, unsigned int len, void *buf, 2884 unsigned int size); 2885 static int parse_ia_port(struct context *ctx, const struct token *token, 2886 const char *str, unsigned int len, void *buf, 2887 unsigned int size); 2888 static int parse_mp(struct context *, const struct token *, 2889 const char *, unsigned int, 2890 void *, unsigned int); 2891 static int parse_meter_profile_id2ptr(struct context *ctx, 2892 const struct token *token, 2893 const char *str, unsigned int len, 2894 void *buf, unsigned int size); 2895 static int parse_meter_policy_id2ptr(struct context *ctx, 2896 const struct token *token, 2897 const char *str, unsigned int len, 2898 void *buf, unsigned int size); 2899 static int parse_meter_color(struct context *ctx, const struct token *token, 2900 const char *str, unsigned int len, void *buf, 2901 unsigned int size); 2902 static int parse_insertion_table_type(struct context *ctx, const struct token *token, 2903 const char *str, unsigned int len, void *buf, 2904 unsigned int size); 2905 static int parse_hash_table_type(struct context *ctx, const struct token *token, 2906 const char *str, unsigned int len, void *buf, 2907 unsigned int size); 2908 static int 2909 parse_quota_state_name(struct context *ctx, const struct token *token, 2910 const char *str, unsigned int len, void *buf, 2911 unsigned int size); 2912 static int 2913 parse_quota_mode_name(struct context *ctx, const struct token *token, 2914 const char *str, unsigned int len, void *buf, 2915 unsigned int size); 2916 static int 2917 parse_quota_update_name(struct context *ctx, const struct token *token, 2918 const char *str, unsigned int len, void *buf, 2919 unsigned int size); 2920 static int 2921 parse_qu_mode_name(struct context *ctx, const struct token *token, 2922 const char *str, unsigned int len, void *buf, 2923 unsigned int size); 2924 static int comp_none(struct context *, const struct token *, 2925 unsigned int, char *, unsigned int); 2926 static int comp_boolean(struct context *, const struct token *, 2927 unsigned int, char *, unsigned int); 2928 static int comp_action(struct context *, const struct token *, 2929 unsigned int, char *, unsigned int); 2930 static int comp_port(struct context *, const struct token *, 2931 unsigned int, char *, unsigned int); 2932 static int comp_rule_id(struct context *, const struct token *, 2933 unsigned int, char *, unsigned int); 2934 static int comp_vc_action_rss_type(struct context *, const struct token *, 2935 unsigned int, char *, unsigned int); 2936 static int comp_vc_action_rss_queue(struct context *, const struct token *, 2937 unsigned int, char *, unsigned int); 2938 static int comp_set_raw_index(struct context *, const struct token *, 2939 unsigned int, char *, unsigned int); 2940 static int comp_set_sample_index(struct context *, const struct token *, 2941 unsigned int, char *, unsigned int); 2942 static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 2943 unsigned int ent, char *buf, unsigned int size); 2944 static int comp_set_modify_field_op(struct context *, const struct token *, 2945 unsigned int, char *, unsigned int); 2946 static int comp_set_modify_field_id(struct context *, const struct token *, 2947 unsigned int, char *, unsigned int); 2948 static int comp_pattern_template_id(struct context *, const struct token *, 2949 unsigned int, char *, unsigned int); 2950 static int comp_actions_template_id(struct context *, const struct token *, 2951 unsigned int, char *, unsigned int); 2952 static int comp_table_id(struct context *, const struct token *, 2953 unsigned int, char *, unsigned int); 2954 static int comp_queue_id(struct context *, const struct token *, 2955 unsigned int, char *, unsigned int); 2956 static int comp_meter_color(struct context *, const struct token *, 2957 unsigned int, char *, unsigned int); 2958 static int comp_insertion_table_type(struct context *, const struct token *, 2959 unsigned int, char *, unsigned int); 2960 static int comp_hash_table_type(struct context *, const struct token *, 2961 unsigned int, char *, unsigned int); 2962 static int 2963 comp_quota_state_name(struct context *ctx, const struct token *token, 2964 unsigned int ent, char *buf, unsigned int size); 2965 static int 2966 comp_quota_mode_name(struct context *ctx, const struct token *token, 2967 unsigned int ent, char *buf, unsigned int size); 2968 static int 2969 comp_quota_update_name(struct context *ctx, const struct token *token, 2970 unsigned int ent, char *buf, unsigned int size); 2971 static int 2972 comp_qu_mode_name(struct context *ctx, const struct token *token, 2973 unsigned int ent, char *buf, unsigned int size); 2974 static int 2975 comp_set_compare_field_id(struct context *ctx, const struct token *token, 2976 unsigned int ent, char *buf, unsigned int size); 2977 static int 2978 comp_set_compare_op(struct context *ctx, const struct token *token, 2979 unsigned int ent, char *buf, unsigned int size); 2980 static int 2981 parse_vc_compare_op(struct context *ctx, const struct token *token, 2982 const char *str, unsigned int len, void *buf, 2983 unsigned int size); 2984 static int 2985 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 2986 const char *str, unsigned int len, void *buf, 2987 unsigned int size); 2988 static int 2989 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 2990 const char *str, unsigned int len, void *buf, 2991 unsigned int size); 2992 2993 struct indlst_conf { 2994 uint32_t id; 2995 uint32_t conf_num; 2996 struct rte_flow_action *actions; 2997 const void **conf; 2998 SLIST_ENTRY(indlst_conf) next; 2999 }; 3000 3001 static const struct indlst_conf *indirect_action_list_conf_get(uint32_t conf_id); 3002 3003 /** Token definitions. */ 3004 static const struct token token_list[] = { 3005 /* Special tokens. */ 3006 [ZERO] = { 3007 .name = "ZERO", 3008 .help = "null entry, abused as the entry point", 3009 .next = NEXT(NEXT_ENTRY(FLOW, ADD)), 3010 }, 3011 [END] = { 3012 .name = "", 3013 .type = "RETURN", 3014 .help = "command may end here", 3015 }, 3016 [START_SET] = { 3017 .name = "START_SET", 3018 .help = "null entry, abused as the entry point for set", 3019 .next = NEXT(NEXT_ENTRY(SET)), 3020 }, 3021 [END_SET] = { 3022 .name = "end_set", 3023 .type = "RETURN", 3024 .help = "set command may end here", 3025 }, 3026 /* Common tokens. */ 3027 [COMMON_INTEGER] = { 3028 .name = "{int}", 3029 .type = "INTEGER", 3030 .help = "integer value", 3031 .call = parse_int, 3032 .comp = comp_none, 3033 }, 3034 [COMMON_UNSIGNED] = { 3035 .name = "{unsigned}", 3036 .type = "UNSIGNED", 3037 .help = "unsigned integer value", 3038 .call = parse_int, 3039 .comp = comp_none, 3040 }, 3041 [COMMON_PREFIX] = { 3042 .name = "{prefix}", 3043 .type = "PREFIX", 3044 .help = "prefix length for bit-mask", 3045 .call = parse_prefix, 3046 .comp = comp_none, 3047 }, 3048 [COMMON_BOOLEAN] = { 3049 .name = "{boolean}", 3050 .type = "BOOLEAN", 3051 .help = "any boolean value", 3052 .call = parse_boolean, 3053 .comp = comp_boolean, 3054 }, 3055 [COMMON_STRING] = { 3056 .name = "{string}", 3057 .type = "STRING", 3058 .help = "fixed string", 3059 .call = parse_string, 3060 .comp = comp_none, 3061 }, 3062 [COMMON_HEX] = { 3063 .name = "{hex}", 3064 .type = "HEX", 3065 .help = "fixed string", 3066 .call = parse_hex, 3067 }, 3068 [COMMON_FILE_PATH] = { 3069 .name = "{file path}", 3070 .type = "STRING", 3071 .help = "file path", 3072 .call = parse_string0, 3073 .comp = comp_none, 3074 }, 3075 [COMMON_MAC_ADDR] = { 3076 .name = "{MAC address}", 3077 .type = "MAC-48", 3078 .help = "standard MAC address notation", 3079 .call = parse_mac_addr, 3080 .comp = comp_none, 3081 }, 3082 [COMMON_IPV4_ADDR] = { 3083 .name = "{IPv4 address}", 3084 .type = "IPV4 ADDRESS", 3085 .help = "standard IPv4 address notation", 3086 .call = parse_ipv4_addr, 3087 .comp = comp_none, 3088 }, 3089 [COMMON_IPV6_ADDR] = { 3090 .name = "{IPv6 address}", 3091 .type = "IPV6 ADDRESS", 3092 .help = "standard IPv6 address notation", 3093 .call = parse_ipv6_addr, 3094 .comp = comp_none, 3095 }, 3096 [COMMON_RULE_ID] = { 3097 .name = "{rule id}", 3098 .type = "RULE ID", 3099 .help = "rule identifier", 3100 .call = parse_int, 3101 .comp = comp_rule_id, 3102 }, 3103 [COMMON_PORT_ID] = { 3104 .name = "{port_id}", 3105 .type = "PORT ID", 3106 .help = "port identifier", 3107 .call = parse_port, 3108 .comp = comp_port, 3109 }, 3110 [COMMON_GROUP_ID] = { 3111 .name = "{group_id}", 3112 .type = "GROUP ID", 3113 .help = "group identifier", 3114 .call = parse_int, 3115 .comp = comp_none, 3116 }, 3117 [COMMON_PRIORITY_LEVEL] = { 3118 .name = "{level}", 3119 .type = "PRIORITY", 3120 .help = "priority level", 3121 .call = parse_int, 3122 .comp = comp_none, 3123 }, 3124 [COMMON_INDIRECT_ACTION_ID] = { 3125 .name = "{indirect_action_id}", 3126 .type = "INDIRECT_ACTION_ID", 3127 .help = "indirect action id", 3128 .call = parse_int, 3129 .comp = comp_none, 3130 }, 3131 [COMMON_PROFILE_ID] = { 3132 .name = "{profile_id}", 3133 .type = "PROFILE_ID", 3134 .help = "profile id", 3135 .call = parse_int, 3136 .comp = comp_none, 3137 }, 3138 [COMMON_POLICY_ID] = { 3139 .name = "{policy_id}", 3140 .type = "POLICY_ID", 3141 .help = "policy id", 3142 .call = parse_int, 3143 .comp = comp_none, 3144 }, 3145 [COMMON_FLEX_TOKEN] = { 3146 .name = "{flex token}", 3147 .type = "flex token", 3148 .help = "flex token", 3149 .call = parse_int, 3150 .comp = comp_none, 3151 }, 3152 [COMMON_FLEX_HANDLE] = { 3153 .name = "{flex handle}", 3154 .type = "FLEX HANDLE", 3155 .help = "fill flex item data", 3156 .call = parse_flex_handle, 3157 .comp = comp_none, 3158 }, 3159 [COMMON_PATTERN_TEMPLATE_ID] = { 3160 .name = "{pattern_template_id}", 3161 .type = "PATTERN_TEMPLATE_ID", 3162 .help = "pattern template id", 3163 .call = parse_int, 3164 .comp = comp_pattern_template_id, 3165 }, 3166 [COMMON_ACTIONS_TEMPLATE_ID] = { 3167 .name = "{actions_template_id}", 3168 .type = "ACTIONS_TEMPLATE_ID", 3169 .help = "actions template id", 3170 .call = parse_int, 3171 .comp = comp_actions_template_id, 3172 }, 3173 [COMMON_TABLE_ID] = { 3174 .name = "{table_id}", 3175 .type = "TABLE_ID", 3176 .help = "table id", 3177 .call = parse_int, 3178 .comp = comp_table_id, 3179 }, 3180 [COMMON_QUEUE_ID] = { 3181 .name = "{queue_id}", 3182 .type = "QUEUE_ID", 3183 .help = "queue id", 3184 .call = parse_int, 3185 .comp = comp_queue_id, 3186 }, 3187 /* Top-level command. */ 3188 [FLOW] = { 3189 .name = "flow", 3190 .type = "{command} {port_id} [{arg} [...]]", 3191 .help = "manage ingress/egress flow rules", 3192 .next = NEXT(NEXT_ENTRY 3193 (INFO, 3194 CONFIGURE, 3195 PATTERN_TEMPLATE, 3196 ACTIONS_TEMPLATE, 3197 TABLE, 3198 FLOW_GROUP, 3199 INDIRECT_ACTION, 3200 VALIDATE, 3201 CREATE, 3202 DESTROY, 3203 FLUSH, 3204 DUMP, 3205 LIST, 3206 AGED, 3207 QUERY, 3208 ISOLATE, 3209 TUNNEL, 3210 FLEX, 3211 QUEUE, 3212 PUSH, 3213 PULL, 3214 HASH)), 3215 .call = parse_init, 3216 }, 3217 /* Top-level command. */ 3218 [INFO] = { 3219 .name = "info", 3220 .help = "get information about flow engine", 3221 .next = NEXT(NEXT_ENTRY(END), 3222 NEXT_ENTRY(COMMON_PORT_ID)), 3223 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3224 .call = parse_configure, 3225 }, 3226 /* Top-level command. */ 3227 [CONFIGURE] = { 3228 .name = "configure", 3229 .help = "configure flow engine", 3230 .next = NEXT(next_config_attr, 3231 NEXT_ENTRY(COMMON_PORT_ID)), 3232 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3233 .call = parse_configure, 3234 }, 3235 /* Configure arguments. */ 3236 [CONFIG_QUEUES_NUMBER] = { 3237 .name = "queues_number", 3238 .help = "number of queues", 3239 .next = NEXT(next_config_attr, 3240 NEXT_ENTRY(COMMON_UNSIGNED)), 3241 .args = ARGS(ARGS_ENTRY(struct buffer, 3242 args.configure.nb_queue)), 3243 }, 3244 [CONFIG_QUEUES_SIZE] = { 3245 .name = "queues_size", 3246 .help = "number of elements in queues", 3247 .next = NEXT(next_config_attr, 3248 NEXT_ENTRY(COMMON_UNSIGNED)), 3249 .args = ARGS(ARGS_ENTRY(struct buffer, 3250 args.configure.queue_attr.size)), 3251 }, 3252 [CONFIG_COUNTERS_NUMBER] = { 3253 .name = "counters_number", 3254 .help = "number of counters", 3255 .next = NEXT(next_config_attr, 3256 NEXT_ENTRY(COMMON_UNSIGNED)), 3257 .args = ARGS(ARGS_ENTRY(struct buffer, 3258 args.configure.port_attr.nb_counters)), 3259 }, 3260 [CONFIG_AGING_OBJECTS_NUMBER] = { 3261 .name = "aging_counters_number", 3262 .help = "number of aging objects", 3263 .next = NEXT(next_config_attr, 3264 NEXT_ENTRY(COMMON_UNSIGNED)), 3265 .args = ARGS(ARGS_ENTRY(struct buffer, 3266 args.configure.port_attr.nb_aging_objects)), 3267 }, 3268 [CONFIG_QUOTAS_NUMBER] = { 3269 .name = "quotas_number", 3270 .help = "number of quotas", 3271 .next = NEXT(next_config_attr, 3272 NEXT_ENTRY(COMMON_UNSIGNED)), 3273 .args = ARGS(ARGS_ENTRY(struct buffer, 3274 args.configure.port_attr.nb_quotas)), 3275 }, 3276 [CONFIG_METERS_NUMBER] = { 3277 .name = "meters_number", 3278 .help = "number of meters", 3279 .next = NEXT(next_config_attr, 3280 NEXT_ENTRY(COMMON_UNSIGNED)), 3281 .args = ARGS(ARGS_ENTRY(struct buffer, 3282 args.configure.port_attr.nb_meters)), 3283 }, 3284 [CONFIG_CONN_TRACK_NUMBER] = { 3285 .name = "conn_tracks_number", 3286 .help = "number of connection trackings", 3287 .next = NEXT(next_config_attr, 3288 NEXT_ENTRY(COMMON_UNSIGNED)), 3289 .args = ARGS(ARGS_ENTRY(struct buffer, 3290 args.configure.port_attr.nb_conn_tracks)), 3291 }, 3292 [CONFIG_FLAGS] = { 3293 .name = "flags", 3294 .help = "configuration flags", 3295 .next = NEXT(next_config_attr, 3296 NEXT_ENTRY(COMMON_UNSIGNED)), 3297 .args = ARGS(ARGS_ENTRY(struct buffer, 3298 args.configure.port_attr.flags)), 3299 }, 3300 [CONFIG_HOST_PORT] = { 3301 .name = "host_port", 3302 .help = "host port for shared objects", 3303 .next = NEXT(next_config_attr, 3304 NEXT_ENTRY(COMMON_UNSIGNED)), 3305 .args = ARGS(ARGS_ENTRY(struct buffer, 3306 args.configure.port_attr.host_port_id)), 3307 }, 3308 /* Top-level command. */ 3309 [PATTERN_TEMPLATE] = { 3310 .name = "pattern_template", 3311 .type = "{command} {port_id} [{arg} [...]]", 3312 .help = "manage pattern templates", 3313 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3314 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3315 .call = parse_template, 3316 }, 3317 /* Sub-level commands. */ 3318 [PATTERN_TEMPLATE_CREATE] = { 3319 .name = "create", 3320 .help = "create pattern template", 3321 .next = NEXT(next_pt_attr), 3322 .call = parse_template, 3323 }, 3324 [PATTERN_TEMPLATE_DESTROY] = { 3325 .name = "destroy", 3326 .help = "destroy pattern template", 3327 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), 3328 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3329 .call = parse_template_destroy, 3330 }, 3331 /* Pattern template arguments. */ 3332 [PATTERN_TEMPLATE_CREATE_ID] = { 3333 .name = "pattern_template_id", 3334 .help = "specify a pattern template id to create", 3335 .next = NEXT(next_pt_attr, 3336 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3337 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), 3338 }, 3339 [PATTERN_TEMPLATE_DESTROY_ID] = { 3340 .name = "pattern_template", 3341 .help = "specify a pattern template id to destroy", 3342 .next = NEXT(next_pt_destroy_attr, 3343 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3344 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3345 args.templ_destroy.template_id)), 3346 .call = parse_template_destroy, 3347 }, 3348 [PATTERN_TEMPLATE_RELAXED_MATCHING] = { 3349 .name = "relaxed", 3350 .help = "is matching relaxed", 3351 .next = NEXT(next_pt_attr, 3352 NEXT_ENTRY(COMMON_BOOLEAN)), 3353 .args = ARGS(ARGS_ENTRY_BF(struct buffer, 3354 args.vc.attr.reserved, 1)), 3355 }, 3356 [PATTERN_TEMPLATE_INGRESS] = { 3357 .name = "ingress", 3358 .help = "attribute pattern to ingress", 3359 .next = NEXT(next_pt_attr), 3360 .call = parse_template, 3361 }, 3362 [PATTERN_TEMPLATE_EGRESS] = { 3363 .name = "egress", 3364 .help = "attribute pattern to egress", 3365 .next = NEXT(next_pt_attr), 3366 .call = parse_template, 3367 }, 3368 [PATTERN_TEMPLATE_TRANSFER] = { 3369 .name = "transfer", 3370 .help = "attribute pattern to transfer", 3371 .next = NEXT(next_pt_attr), 3372 .call = parse_template, 3373 }, 3374 [PATTERN_TEMPLATE_SPEC] = { 3375 .name = "template", 3376 .help = "specify item to create pattern template", 3377 .next = NEXT(next_item), 3378 }, 3379 /* Top-level command. */ 3380 [ACTIONS_TEMPLATE] = { 3381 .name = "actions_template", 3382 .type = "{command} {port_id} [{arg} [...]]", 3383 .help = "manage actions templates", 3384 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3385 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3386 .call = parse_template, 3387 }, 3388 /* Sub-level commands. */ 3389 [ACTIONS_TEMPLATE_CREATE] = { 3390 .name = "create", 3391 .help = "create actions template", 3392 .next = NEXT(next_at_attr), 3393 .call = parse_template, 3394 }, 3395 [ACTIONS_TEMPLATE_DESTROY] = { 3396 .name = "destroy", 3397 .help = "destroy actions template", 3398 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), 3399 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3400 .call = parse_template_destroy, 3401 }, 3402 /* Actions template arguments. */ 3403 [ACTIONS_TEMPLATE_CREATE_ID] = { 3404 .name = "actions_template_id", 3405 .help = "specify an actions template id to create", 3406 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), 3407 NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), 3408 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3409 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), 3410 }, 3411 [ACTIONS_TEMPLATE_DESTROY_ID] = { 3412 .name = "actions_template", 3413 .help = "specify an actions template id to destroy", 3414 .next = NEXT(next_at_destroy_attr, 3415 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3416 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3417 args.templ_destroy.template_id)), 3418 .call = parse_template_destroy, 3419 }, 3420 [ACTIONS_TEMPLATE_INGRESS] = { 3421 .name = "ingress", 3422 .help = "attribute actions to ingress", 3423 .next = NEXT(next_at_attr), 3424 .call = parse_template, 3425 }, 3426 [ACTIONS_TEMPLATE_EGRESS] = { 3427 .name = "egress", 3428 .help = "attribute actions to egress", 3429 .next = NEXT(next_at_attr), 3430 .call = parse_template, 3431 }, 3432 [ACTIONS_TEMPLATE_TRANSFER] = { 3433 .name = "transfer", 3434 .help = "attribute actions to transfer", 3435 .next = NEXT(next_at_attr), 3436 .call = parse_template, 3437 }, 3438 [ACTIONS_TEMPLATE_SPEC] = { 3439 .name = "template", 3440 .help = "specify action to create actions template", 3441 .next = NEXT(next_action), 3442 .call = parse_template, 3443 }, 3444 [ACTIONS_TEMPLATE_MASK] = { 3445 .name = "mask", 3446 .help = "specify action mask to create actions template", 3447 .next = NEXT(next_action), 3448 .call = parse_template, 3449 }, 3450 /* Top-level command. */ 3451 [TABLE] = { 3452 .name = "template_table", 3453 .type = "{command} {port_id} [{arg} [...]]", 3454 .help = "manage template tables", 3455 .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3456 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3457 .call = parse_table, 3458 }, 3459 /* Sub-level commands. */ 3460 [TABLE_CREATE] = { 3461 .name = "create", 3462 .help = "create template table", 3463 .next = NEXT(next_table_attr), 3464 .call = parse_table, 3465 }, 3466 [TABLE_DESTROY] = { 3467 .name = "destroy", 3468 .help = "destroy template table", 3469 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3470 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3471 .call = parse_table_destroy, 3472 }, 3473 [TABLE_RESIZE] = { 3474 .name = "resize", 3475 .help = "resize template table", 3476 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_ID)), 3477 .call = parse_table 3478 }, 3479 [TABLE_RESIZE_COMPLETE] = { 3480 .name = "resize_complete", 3481 .help = "complete table resize", 3482 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3483 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3484 .call = parse_table_destroy, 3485 }, 3486 /* Table arguments. */ 3487 [TABLE_CREATE_ID] = { 3488 .name = "table_id", 3489 .help = "specify table id to create", 3490 .next = NEXT(next_table_attr, 3491 NEXT_ENTRY(COMMON_TABLE_ID)), 3492 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3493 }, 3494 [TABLE_DESTROY_ID] = { 3495 .name = "table", 3496 .help = "table id", 3497 .next = NEXT(next_table_destroy_attr, 3498 NEXT_ENTRY(COMMON_TABLE_ID)), 3499 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3500 args.table_destroy.table_id)), 3501 .call = parse_table_destroy, 3502 }, 3503 [TABLE_RESIZE_ID] = { 3504 .name = "table_resize_id", 3505 .help = "table resize id", 3506 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_RULES_NUMBER), 3507 NEXT_ENTRY(COMMON_TABLE_ID)), 3508 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3509 .call = parse_table 3510 }, 3511 [TABLE_RESIZE_RULES_NUMBER] = { 3512 .name = "table_resize_rules_num", 3513 .help = "table resize rules number", 3514 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_UNSIGNED)), 3515 .args = ARGS(ARGS_ENTRY(struct buffer, 3516 args.table.attr.nb_flows)), 3517 .call = parse_table 3518 }, 3519 [TABLE_INSERTION_TYPE] = { 3520 .name = "insertion_type", 3521 .help = "specify insertion type", 3522 .next = NEXT(next_table_attr, 3523 NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)), 3524 .args = ARGS(ARGS_ENTRY(struct buffer, 3525 args.table.attr.insertion_type)), 3526 }, 3527 [TABLE_INSERTION_TYPE_NAME] = { 3528 .name = "insertion_type_name", 3529 .help = "insertion type name", 3530 .call = parse_insertion_table_type, 3531 .comp = comp_insertion_table_type, 3532 }, 3533 [TABLE_HASH_FUNC] = { 3534 .name = "hash_func", 3535 .help = "specify hash calculation function", 3536 .next = NEXT(next_table_attr, 3537 NEXT_ENTRY(TABLE_HASH_FUNC_NAME)), 3538 .args = ARGS(ARGS_ENTRY(struct buffer, 3539 args.table.attr.hash_func)), 3540 }, 3541 [TABLE_HASH_FUNC_NAME] = { 3542 .name = "hash_func_name", 3543 .help = "hash calculation function name", 3544 .call = parse_hash_table_type, 3545 .comp = comp_hash_table_type, 3546 }, 3547 [TABLE_GROUP] = { 3548 .name = "group", 3549 .help = "specify a group", 3550 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3551 .args = ARGS(ARGS_ENTRY(struct buffer, 3552 args.table.attr.flow_attr.group)), 3553 }, 3554 [TABLE_PRIORITY] = { 3555 .name = "priority", 3556 .help = "specify a priority level", 3557 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 3558 .args = ARGS(ARGS_ENTRY(struct buffer, 3559 args.table.attr.flow_attr.priority)), 3560 }, 3561 [TABLE_EGRESS] = { 3562 .name = "egress", 3563 .help = "affect rule to egress", 3564 .next = NEXT(next_table_attr), 3565 .call = parse_table, 3566 }, 3567 [TABLE_INGRESS] = { 3568 .name = "ingress", 3569 .help = "affect rule to ingress", 3570 .next = NEXT(next_table_attr), 3571 .call = parse_table, 3572 }, 3573 [TABLE_TRANSFER] = { 3574 .name = "transfer", 3575 .help = "affect rule to transfer", 3576 .next = NEXT(next_table_attr), 3577 .call = parse_table, 3578 }, 3579 [TABLE_TRANSFER_WIRE_ORIG] = { 3580 .name = "wire_orig", 3581 .help = "affect rule direction to transfer", 3582 .next = NEXT(next_table_attr), 3583 .call = parse_table, 3584 }, 3585 [TABLE_TRANSFER_VPORT_ORIG] = { 3586 .name = "vport_orig", 3587 .help = "affect rule direction to transfer", 3588 .next = NEXT(next_table_attr), 3589 .call = parse_table, 3590 }, 3591 [TABLE_RESIZABLE] = { 3592 .name = "resizable", 3593 .help = "set resizable attribute", 3594 .next = NEXT(next_table_attr), 3595 .call = parse_table, 3596 }, 3597 [TABLE_RULES_NUMBER] = { 3598 .name = "rules_number", 3599 .help = "number of rules in table", 3600 .next = NEXT(next_table_attr, 3601 NEXT_ENTRY(COMMON_UNSIGNED)), 3602 .args = ARGS(ARGS_ENTRY(struct buffer, 3603 args.table.attr.nb_flows)), 3604 .call = parse_table, 3605 }, 3606 [TABLE_PATTERN_TEMPLATE] = { 3607 .name = "pattern_template", 3608 .help = "specify pattern template id", 3609 .next = NEXT(next_table_attr, 3610 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3611 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3612 args.table.pat_templ_id)), 3613 .call = parse_table, 3614 }, 3615 [TABLE_ACTIONS_TEMPLATE] = { 3616 .name = "actions_template", 3617 .help = "specify actions template id", 3618 .next = NEXT(next_table_attr, 3619 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3620 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3621 args.table.act_templ_id)), 3622 .call = parse_table, 3623 }, 3624 /* Top-level command. */ 3625 [FLOW_GROUP] = { 3626 .name = "group", 3627 .help = "manage flow groups", 3628 .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), 3629 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3630 .call = parse_group, 3631 }, 3632 /* Sub-level commands. */ 3633 [GROUP_SET_MISS_ACTIONS] = { 3634 .name = "set_miss_actions", 3635 .help = "set group miss actions", 3636 .next = NEXT(next_action), 3637 .call = parse_group, 3638 }, 3639 /* Group arguments */ 3640 [GROUP_ID] = { 3641 .name = "group_id", 3642 .help = "group id", 3643 .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3644 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3645 }, 3646 [GROUP_INGRESS] = { 3647 .name = "ingress", 3648 .help = "group ingress attr", 3649 .next = NEXT(next_group_attr), 3650 .call = parse_group, 3651 }, 3652 [GROUP_EGRESS] = { 3653 .name = "egress", 3654 .help = "group egress attr", 3655 .next = NEXT(next_group_attr), 3656 .call = parse_group, 3657 }, 3658 [GROUP_TRANSFER] = { 3659 .name = "transfer", 3660 .help = "group transfer attr", 3661 .next = NEXT(next_group_attr), 3662 .call = parse_group, 3663 }, 3664 /* Top-level command. */ 3665 [QUEUE] = { 3666 .name = "queue", 3667 .help = "queue a flow rule operation", 3668 .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3669 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3670 .call = parse_qo, 3671 }, 3672 /* Sub-level commands. */ 3673 [QUEUE_CREATE] = { 3674 .name = "create", 3675 .help = "create a flow rule", 3676 .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), 3677 NEXT_ENTRY(COMMON_QUEUE_ID)), 3678 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3679 .call = parse_qo, 3680 }, 3681 [QUEUE_DESTROY] = { 3682 .name = "destroy", 3683 .help = "destroy a flow rule", 3684 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3685 NEXT_ENTRY(COMMON_QUEUE_ID)), 3686 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3687 .call = parse_qo_destroy, 3688 }, 3689 [QUEUE_FLOW_UPDATE_RESIZED] = { 3690 .name = "update_resized", 3691 .help = "update a flow after table resize", 3692 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3693 NEXT_ENTRY(COMMON_QUEUE_ID)), 3694 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3695 .call = parse_qo_destroy, 3696 }, 3697 [QUEUE_UPDATE] = { 3698 .name = "update", 3699 .help = "update a flow rule", 3700 .next = NEXT(NEXT_ENTRY(QUEUE_UPDATE_ID), 3701 NEXT_ENTRY(COMMON_QUEUE_ID)), 3702 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3703 .call = parse_qo, 3704 }, 3705 [QUEUE_AGED] = { 3706 .name = "aged", 3707 .help = "list and destroy aged flows", 3708 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), 3709 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3710 .call = parse_aged, 3711 }, 3712 [QUEUE_INDIRECT_ACTION] = { 3713 .name = "indirect_action", 3714 .help = "queue indirect actions", 3715 .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), 3716 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3717 .call = parse_qia, 3718 }, 3719 /* Queue arguments. */ 3720 [QUEUE_TEMPLATE_TABLE] = { 3721 .name = "template_table", 3722 .help = "specify table id", 3723 .next = NEXT(next_async_insert_subcmd, 3724 NEXT_ENTRY(COMMON_TABLE_ID)), 3725 .args = ARGS(ARGS_ENTRY(struct buffer, 3726 args.vc.table_id)), 3727 .call = parse_qo, 3728 }, 3729 [QUEUE_PATTERN_TEMPLATE] = { 3730 .name = "pattern_template", 3731 .help = "specify pattern template index", 3732 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3733 NEXT_ENTRY(COMMON_UNSIGNED)), 3734 .args = ARGS(ARGS_ENTRY(struct buffer, 3735 args.vc.pat_templ_id)), 3736 .call = parse_qo, 3737 }, 3738 [QUEUE_ACTIONS_TEMPLATE] = { 3739 .name = "actions_template", 3740 .help = "specify actions template index", 3741 .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), 3742 NEXT_ENTRY(COMMON_UNSIGNED)), 3743 .args = ARGS(ARGS_ENTRY(struct buffer, 3744 args.vc.act_templ_id)), 3745 .call = parse_qo, 3746 }, 3747 [QUEUE_RULE_ID] = { 3748 .name = "rule_index", 3749 .help = "specify flow rule index", 3750 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3751 NEXT_ENTRY(COMMON_UNSIGNED)), 3752 .args = ARGS(ARGS_ENTRY(struct buffer, 3753 args.vc.rule_id)), 3754 .call = parse_qo, 3755 }, 3756 [QUEUE_CREATE_POSTPONE] = { 3757 .name = "postpone", 3758 .help = "postpone create operation", 3759 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3760 NEXT_ENTRY(COMMON_BOOLEAN)), 3761 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3762 .call = parse_qo, 3763 }, 3764 [QUEUE_DESTROY_POSTPONE] = { 3765 .name = "postpone", 3766 .help = "postpone destroy operation", 3767 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3768 NEXT_ENTRY(COMMON_BOOLEAN)), 3769 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3770 .call = parse_qo_destroy, 3771 }, 3772 [QUEUE_DESTROY_ID] = { 3773 .name = "rule", 3774 .help = "specify rule id to destroy", 3775 .next = NEXT(next_queue_destroy_attr, 3776 NEXT_ENTRY(COMMON_UNSIGNED)), 3777 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3778 args.destroy.rule)), 3779 .call = parse_qo_destroy, 3780 }, 3781 [QUEUE_UPDATE_ID] = { 3782 .name = "rule", 3783 .help = "specify rule id to update", 3784 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3785 NEXT_ENTRY(COMMON_UNSIGNED)), 3786 .args = ARGS(ARGS_ENTRY(struct buffer, 3787 args.vc.rule_id)), 3788 .call = parse_qo, 3789 }, 3790 /* Queue indirect action arguments */ 3791 [QUEUE_INDIRECT_ACTION_CREATE] = { 3792 .name = "create", 3793 .help = "create indirect action", 3794 .next = NEXT(next_qia_create_attr), 3795 .call = parse_qia, 3796 }, 3797 [QUEUE_INDIRECT_ACTION_UPDATE] = { 3798 .name = "update", 3799 .help = "update indirect action", 3800 .next = NEXT(next_qia_update_attr, 3801 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3802 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3803 .call = parse_qia, 3804 }, 3805 [QUEUE_INDIRECT_ACTION_DESTROY] = { 3806 .name = "destroy", 3807 .help = "destroy indirect action", 3808 .next = NEXT(next_qia_destroy_attr), 3809 .call = parse_qia_destroy, 3810 }, 3811 [QUEUE_INDIRECT_ACTION_QUERY] = { 3812 .name = "query", 3813 .help = "query indirect action", 3814 .next = NEXT(next_qia_query_attr, 3815 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3816 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3817 .call = parse_qia, 3818 }, 3819 /* Indirect action destroy arguments. */ 3820 [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { 3821 .name = "postpone", 3822 .help = "postpone destroy operation", 3823 .next = NEXT(next_qia_destroy_attr, 3824 NEXT_ENTRY(COMMON_BOOLEAN)), 3825 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3826 }, 3827 [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { 3828 .name = "action_id", 3829 .help = "specify a indirect action id to destroy", 3830 .next = NEXT(next_qia_destroy_attr, 3831 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3832 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3833 args.ia_destroy.action_id)), 3834 .call = parse_qia_destroy, 3835 }, 3836 [QUEUE_INDIRECT_ACTION_QUERY_UPDATE] = { 3837 .name = "query_update", 3838 .help = "indirect query [and|or] update action", 3839 .next = NEXT(next_qia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3840 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3841 .call = parse_qia 3842 }, 3843 [QUEUE_INDIRECT_ACTION_QU_MODE] = { 3844 .name = "mode", 3845 .help = "indirect query [and|or] update action", 3846 .next = NEXT(next_qia_qu_attr, 3847 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 3848 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 3849 .call = parse_qia 3850 }, 3851 /* Indirect action update arguments. */ 3852 [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { 3853 .name = "postpone", 3854 .help = "postpone update operation", 3855 .next = NEXT(next_qia_update_attr, 3856 NEXT_ENTRY(COMMON_BOOLEAN)), 3857 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3858 }, 3859 /* Indirect action update arguments. */ 3860 [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { 3861 .name = "postpone", 3862 .help = "postpone query operation", 3863 .next = NEXT(next_qia_query_attr, 3864 NEXT_ENTRY(COMMON_BOOLEAN)), 3865 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3866 }, 3867 /* Indirect action create arguments. */ 3868 [QUEUE_INDIRECT_ACTION_CREATE_ID] = { 3869 .name = "action_id", 3870 .help = "specify a indirect action id to create", 3871 .next = NEXT(next_qia_create_attr, 3872 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3873 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3874 }, 3875 [QUEUE_INDIRECT_ACTION_INGRESS] = { 3876 .name = "ingress", 3877 .help = "affect rule to ingress", 3878 .next = NEXT(next_qia_create_attr), 3879 .call = parse_qia, 3880 }, 3881 [QUEUE_INDIRECT_ACTION_EGRESS] = { 3882 .name = "egress", 3883 .help = "affect rule to egress", 3884 .next = NEXT(next_qia_create_attr), 3885 .call = parse_qia, 3886 }, 3887 [QUEUE_INDIRECT_ACTION_TRANSFER] = { 3888 .name = "transfer", 3889 .help = "affect rule to transfer", 3890 .next = NEXT(next_qia_create_attr), 3891 .call = parse_qia, 3892 }, 3893 [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { 3894 .name = "postpone", 3895 .help = "postpone create operation", 3896 .next = NEXT(next_qia_create_attr, 3897 NEXT_ENTRY(COMMON_BOOLEAN)), 3898 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3899 }, 3900 [QUEUE_INDIRECT_ACTION_SPEC] = { 3901 .name = "action", 3902 .help = "specify action to create indirect handle", 3903 .next = NEXT(next_action), 3904 }, 3905 [QUEUE_INDIRECT_ACTION_LIST] = { 3906 .name = "list", 3907 .help = "specify actions for indirect handle list", 3908 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 3909 .call = parse_qia, 3910 }, 3911 /* Top-level command. */ 3912 [PUSH] = { 3913 .name = "push", 3914 .help = "push enqueued operations", 3915 .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3916 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3917 .call = parse_push, 3918 }, 3919 /* Sub-level commands. */ 3920 [PUSH_QUEUE] = { 3921 .name = "queue", 3922 .help = "specify queue id", 3923 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3924 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3925 }, 3926 /* Top-level command. */ 3927 [PULL] = { 3928 .name = "pull", 3929 .help = "pull flow operations results", 3930 .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3931 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3932 .call = parse_pull, 3933 }, 3934 /* Sub-level commands. */ 3935 [PULL_QUEUE] = { 3936 .name = "queue", 3937 .help = "specify queue id", 3938 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3939 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3940 }, 3941 /* Top-level command. */ 3942 [HASH] = { 3943 .name = "hash", 3944 .help = "calculate hash for a given pattern in a given template table", 3945 .next = NEXT(next_hash_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3946 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3947 .call = parse_hash, 3948 }, 3949 /* Sub-level commands. */ 3950 [HASH_CALC_TABLE] = { 3951 .name = "template_table", 3952 .help = "specify table id", 3953 .next = NEXT(NEXT_ENTRY(HASH_CALC_PATTERN_INDEX), 3954 NEXT_ENTRY(COMMON_TABLE_ID)), 3955 .args = ARGS(ARGS_ENTRY(struct buffer, 3956 args.vc.table_id)), 3957 .call = parse_hash, 3958 }, 3959 [HASH_CALC_ENCAP] = { 3960 .name = "encap", 3961 .help = "calculates encap hash", 3962 .next = NEXT(next_hash_encap_dest_subcmd), 3963 .call = parse_hash, 3964 }, 3965 [HASH_CALC_PATTERN_INDEX] = { 3966 .name = "pattern_template", 3967 .help = "specify pattern template id", 3968 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3969 NEXT_ENTRY(COMMON_UNSIGNED)), 3970 .args = ARGS(ARGS_ENTRY(struct buffer, 3971 args.vc.pat_templ_id)), 3972 .call = parse_hash, 3973 }, 3974 [ENCAP_HASH_FIELD_SRC_PORT] = { 3975 .name = "hash_field_sport", 3976 .help = "the encap hash field is src port", 3977 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 3978 .call = parse_hash, 3979 }, 3980 [ENCAP_HASH_FIELD_GRE_FLOW_ID] = { 3981 .name = "hash_field_flow_id", 3982 .help = "the encap hash field is NVGRE flow id", 3983 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 3984 .call = parse_hash, 3985 }, 3986 /* Top-level command. */ 3987 [INDIRECT_ACTION] = { 3988 .name = "indirect_action", 3989 .type = "{command} {port_id} [{arg} [...]]", 3990 .help = "manage indirect actions", 3991 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3992 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3993 .call = parse_ia, 3994 }, 3995 /* Sub-level commands. */ 3996 [INDIRECT_ACTION_CREATE] = { 3997 .name = "create", 3998 .help = "create indirect action", 3999 .next = NEXT(next_ia_create_attr), 4000 .call = parse_ia, 4001 }, 4002 [INDIRECT_ACTION_UPDATE] = { 4003 .name = "update", 4004 .help = "update indirect action", 4005 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), 4006 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4007 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 4008 .call = parse_ia, 4009 }, 4010 [INDIRECT_ACTION_DESTROY] = { 4011 .name = "destroy", 4012 .help = "destroy indirect action", 4013 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), 4014 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4015 .call = parse_ia_destroy, 4016 }, 4017 [INDIRECT_ACTION_QUERY] = { 4018 .name = "query", 4019 .help = "query indirect action", 4020 .next = NEXT(NEXT_ENTRY(END), 4021 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4022 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4023 .call = parse_ia, 4024 }, 4025 [INDIRECT_ACTION_QUERY_UPDATE] = { 4026 .name = "query_update", 4027 .help = "query [and|or] update", 4028 .next = NEXT(next_ia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4029 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4030 .call = parse_ia 4031 }, 4032 [INDIRECT_ACTION_QU_MODE] = { 4033 .name = "mode", 4034 .help = "query_update mode", 4035 .next = NEXT(next_ia_qu_attr, 4036 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 4037 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 4038 .call = parse_ia, 4039 }, 4040 [INDIRECT_ACTION_QU_MODE_NAME] = { 4041 .name = "mode_name", 4042 .help = "query-update mode name", 4043 .call = parse_qu_mode_name, 4044 .comp = comp_qu_mode_name, 4045 }, 4046 [VALIDATE] = { 4047 .name = "validate", 4048 .help = "check whether a flow rule can be created", 4049 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4050 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4051 .call = parse_vc, 4052 }, 4053 [CREATE] = { 4054 .name = "create", 4055 .help = "create a flow rule", 4056 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4057 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4058 .call = parse_vc, 4059 }, 4060 [DESTROY] = { 4061 .name = "destroy", 4062 .help = "destroy specific flow rules", 4063 .next = NEXT(next_destroy_attr, 4064 NEXT_ENTRY(COMMON_PORT_ID)), 4065 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4066 .call = parse_destroy, 4067 }, 4068 [FLUSH] = { 4069 .name = "flush", 4070 .help = "destroy all flow rules", 4071 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4072 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4073 .call = parse_flush, 4074 }, 4075 [DUMP] = { 4076 .name = "dump", 4077 .help = "dump single/all flow rules to file", 4078 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4079 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4080 .call = parse_dump, 4081 }, 4082 [QUERY] = { 4083 .name = "query", 4084 .help = "query an existing flow rule", 4085 .next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION), 4086 NEXT_ENTRY(COMMON_RULE_ID), 4087 NEXT_ENTRY(COMMON_PORT_ID)), 4088 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), 4089 ARGS_ENTRY(struct buffer, args.query.rule), 4090 ARGS_ENTRY(struct buffer, port)), 4091 .call = parse_query, 4092 }, 4093 [LIST] = { 4094 .name = "list", 4095 .help = "list existing flow rules", 4096 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4097 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4098 .call = parse_list, 4099 }, 4100 [AGED] = { 4101 .name = "aged", 4102 .help = "list and destroy aged flows", 4103 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4104 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4105 .call = parse_aged, 4106 }, 4107 [ISOLATE] = { 4108 .name = "isolate", 4109 .help = "restrict ingress traffic to the defined flow rules", 4110 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), 4111 NEXT_ENTRY(COMMON_PORT_ID)), 4112 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), 4113 ARGS_ENTRY(struct buffer, port)), 4114 .call = parse_isolate, 4115 }, 4116 [FLEX] = { 4117 .name = "flex_item", 4118 .help = "flex item API", 4119 .next = NEXT(next_flex_item), 4120 .call = parse_flex, 4121 }, 4122 [FLEX_ITEM_INIT] = { 4123 .name = "init", 4124 .help = "flex item init", 4125 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4126 ARGS_ENTRY(struct buffer, port)), 4127 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4128 NEXT_ENTRY(COMMON_PORT_ID)), 4129 .call = parse_flex 4130 }, 4131 [FLEX_ITEM_CREATE] = { 4132 .name = "create", 4133 .help = "flex item create", 4134 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), 4135 ARGS_ENTRY(struct buffer, args.flex.token), 4136 ARGS_ENTRY(struct buffer, port)), 4137 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), 4138 NEXT_ENTRY(COMMON_FLEX_TOKEN), 4139 NEXT_ENTRY(COMMON_PORT_ID)), 4140 .call = parse_flex 4141 }, 4142 [FLEX_ITEM_DESTROY] = { 4143 .name = "destroy", 4144 .help = "flex item destroy", 4145 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4146 ARGS_ENTRY(struct buffer, port)), 4147 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4148 NEXT_ENTRY(COMMON_PORT_ID)), 4149 .call = parse_flex 4150 }, 4151 [TUNNEL] = { 4152 .name = "tunnel", 4153 .help = "new tunnel API", 4154 .next = NEXT(NEXT_ENTRY 4155 (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), 4156 .call = parse_tunnel, 4157 }, 4158 /* Tunnel arguments. */ 4159 [TUNNEL_CREATE] = { 4160 .name = "create", 4161 .help = "create new tunnel object", 4162 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), 4163 NEXT_ENTRY(COMMON_PORT_ID)), 4164 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4165 .call = parse_tunnel, 4166 }, 4167 [TUNNEL_CREATE_TYPE] = { 4168 .name = "type", 4169 .help = "create new tunnel", 4170 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), 4171 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), 4172 .call = parse_tunnel, 4173 }, 4174 [TUNNEL_DESTROY] = { 4175 .name = "destroy", 4176 .help = "destroy tunnel", 4177 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), 4178 NEXT_ENTRY(COMMON_PORT_ID)), 4179 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4180 .call = parse_tunnel, 4181 }, 4182 [TUNNEL_DESTROY_ID] = { 4183 .name = "id", 4184 .help = "tunnel identifier to destroy", 4185 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), 4186 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4187 .call = parse_tunnel, 4188 }, 4189 [TUNNEL_LIST] = { 4190 .name = "list", 4191 .help = "list existing tunnels", 4192 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4193 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4194 .call = parse_tunnel, 4195 }, 4196 /* Destroy arguments. */ 4197 [DESTROY_RULE] = { 4198 .name = "rule", 4199 .help = "specify a rule identifier", 4200 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4201 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), 4202 .call = parse_destroy, 4203 }, 4204 [DESTROY_IS_USER_ID] = { 4205 .name = "user_id", 4206 .help = "rule identifier is user-id", 4207 .next = NEXT(next_destroy_attr), 4208 .call = parse_destroy, 4209 }, 4210 /* Dump arguments. */ 4211 [DUMP_ALL] = { 4212 .name = "all", 4213 .help = "dump all", 4214 .next = NEXT(next_dump_attr), 4215 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), 4216 .call = parse_dump, 4217 }, 4218 [DUMP_ONE] = { 4219 .name = "rule", 4220 .help = "dump one rule", 4221 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4222 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), 4223 ARGS_ENTRY(struct buffer, args.dump.rule)), 4224 .call = parse_dump, 4225 }, 4226 [DUMP_IS_USER_ID] = { 4227 .name = "user_id", 4228 .help = "rule identifier is user-id", 4229 .next = NEXT(next_dump_subcmd), 4230 .call = parse_dump, 4231 }, 4232 /* Query arguments. */ 4233 [QUERY_ACTION] = { 4234 .name = "{action}", 4235 .type = "ACTION", 4236 .help = "action to query, must be part of the rule", 4237 .call = parse_action, 4238 .comp = comp_action, 4239 }, 4240 [QUERY_IS_USER_ID] = { 4241 .name = "user_id", 4242 .help = "rule identifier is user-id", 4243 .next = NEXT(next_query_attr), 4244 .call = parse_query, 4245 }, 4246 /* List arguments. */ 4247 [LIST_GROUP] = { 4248 .name = "group", 4249 .help = "specify a group", 4250 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4251 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), 4252 .call = parse_list, 4253 }, 4254 [AGED_DESTROY] = { 4255 .name = "destroy", 4256 .help = "specify aged flows need be destroyed", 4257 .call = parse_aged, 4258 .comp = comp_none, 4259 }, 4260 /* Validate/create attributes. */ 4261 [VC_GROUP] = { 4262 .name = "group", 4263 .help = "specify a group", 4264 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4265 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), 4266 .call = parse_vc, 4267 }, 4268 [VC_PRIORITY] = { 4269 .name = "priority", 4270 .help = "specify a priority level", 4271 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 4272 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), 4273 .call = parse_vc, 4274 }, 4275 [VC_INGRESS] = { 4276 .name = "ingress", 4277 .help = "affect rule to ingress", 4278 .next = NEXT(next_vc_attr), 4279 .call = parse_vc, 4280 }, 4281 [VC_EGRESS] = { 4282 .name = "egress", 4283 .help = "affect rule to egress", 4284 .next = NEXT(next_vc_attr), 4285 .call = parse_vc, 4286 }, 4287 [VC_TRANSFER] = { 4288 .name = "transfer", 4289 .help = "apply rule directly to endpoints found in pattern", 4290 .next = NEXT(next_vc_attr), 4291 .call = parse_vc, 4292 }, 4293 [VC_TUNNEL_SET] = { 4294 .name = "tunnel_set", 4295 .help = "tunnel steer rule", 4296 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4297 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4298 .call = parse_vc, 4299 }, 4300 [VC_TUNNEL_MATCH] = { 4301 .name = "tunnel_match", 4302 .help = "tunnel match rule", 4303 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4304 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4305 .call = parse_vc, 4306 }, 4307 [VC_USER_ID] = { 4308 .name = "user_id", 4309 .help = "specify a user id to create", 4310 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4311 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)), 4312 .call = parse_vc, 4313 }, 4314 /* Validate/create pattern. */ 4315 [ITEM_PATTERN] = { 4316 .name = "pattern", 4317 .help = "submit a list of pattern items", 4318 .next = NEXT(next_item), 4319 .call = parse_vc, 4320 }, 4321 [ITEM_PARAM_IS] = { 4322 .name = "is", 4323 .help = "match value perfectly (with full bit-mask)", 4324 .call = parse_vc_spec, 4325 }, 4326 [ITEM_PARAM_SPEC] = { 4327 .name = "spec", 4328 .help = "match value according to configured bit-mask", 4329 .call = parse_vc_spec, 4330 }, 4331 [ITEM_PARAM_LAST] = { 4332 .name = "last", 4333 .help = "specify upper bound to establish a range", 4334 .call = parse_vc_spec, 4335 }, 4336 [ITEM_PARAM_MASK] = { 4337 .name = "mask", 4338 .help = "specify bit-mask with relevant bits set to one", 4339 .call = parse_vc_spec, 4340 }, 4341 [ITEM_PARAM_PREFIX] = { 4342 .name = "prefix", 4343 .help = "generate bit-mask from a prefix length", 4344 .call = parse_vc_spec, 4345 }, 4346 [ITEM_NEXT] = { 4347 .name = "/", 4348 .help = "specify next pattern item", 4349 .next = NEXT(next_item), 4350 }, 4351 [ITEM_END] = { 4352 .name = "end", 4353 .help = "end list of pattern items", 4354 .priv = PRIV_ITEM(END, 0), 4355 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 4356 .call = parse_vc, 4357 }, 4358 [ITEM_VOID] = { 4359 .name = "void", 4360 .help = "no-op pattern item", 4361 .priv = PRIV_ITEM(VOID, 0), 4362 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4363 .call = parse_vc, 4364 }, 4365 [ITEM_INVERT] = { 4366 .name = "invert", 4367 .help = "perform actions when pattern does not match", 4368 .priv = PRIV_ITEM(INVERT, 0), 4369 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4370 .call = parse_vc, 4371 }, 4372 [ITEM_ANY] = { 4373 .name = "any", 4374 .help = "match any protocol for the current layer", 4375 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), 4376 .next = NEXT(item_any), 4377 .call = parse_vc, 4378 }, 4379 [ITEM_ANY_NUM] = { 4380 .name = "num", 4381 .help = "number of layers covered", 4382 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4383 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), 4384 }, 4385 [ITEM_PORT_ID] = { 4386 .name = "port_id", 4387 .help = "match traffic from/to a given DPDK port ID", 4388 .priv = PRIV_ITEM(PORT_ID, 4389 sizeof(struct rte_flow_item_port_id)), 4390 .next = NEXT(item_port_id), 4391 .call = parse_vc, 4392 }, 4393 [ITEM_PORT_ID_ID] = { 4394 .name = "id", 4395 .help = "DPDK port ID", 4396 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), 4397 item_param), 4398 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), 4399 }, 4400 [ITEM_MARK] = { 4401 .name = "mark", 4402 .help = "match traffic against value set in previously matched rule", 4403 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), 4404 .next = NEXT(item_mark), 4405 .call = parse_vc, 4406 }, 4407 [ITEM_MARK_ID] = { 4408 .name = "id", 4409 .help = "Integer value to match against", 4410 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), 4411 item_param), 4412 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), 4413 }, 4414 [ITEM_RAW] = { 4415 .name = "raw", 4416 .help = "match an arbitrary byte string", 4417 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), 4418 .next = NEXT(item_raw), 4419 .call = parse_vc, 4420 }, 4421 [ITEM_RAW_RELATIVE] = { 4422 .name = "relative", 4423 .help = "look for pattern after the previous item", 4424 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4425 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4426 relative, 1)), 4427 }, 4428 [ITEM_RAW_SEARCH] = { 4429 .name = "search", 4430 .help = "search pattern from offset (see also limit)", 4431 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4432 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4433 search, 1)), 4434 }, 4435 [ITEM_RAW_OFFSET] = { 4436 .name = "offset", 4437 .help = "absolute or relative offset for pattern", 4438 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), 4439 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), 4440 }, 4441 [ITEM_RAW_LIMIT] = { 4442 .name = "limit", 4443 .help = "search area limit for start of pattern", 4444 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4445 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), 4446 }, 4447 [ITEM_RAW_PATTERN] = { 4448 .name = "pattern", 4449 .help = "byte string to look for", 4450 .next = NEXT(item_raw, 4451 NEXT_ENTRY(COMMON_STRING), 4452 NEXT_ENTRY(ITEM_PARAM_IS, 4453 ITEM_PARAM_SPEC, 4454 ITEM_PARAM_MASK)), 4455 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4456 ARGS_ENTRY(struct rte_flow_item_raw, length), 4457 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4458 ITEM_RAW_PATTERN_SIZE)), 4459 }, 4460 [ITEM_RAW_PATTERN_HEX] = { 4461 .name = "pattern_hex", 4462 .help = "hex string to look for", 4463 .next = NEXT(item_raw, 4464 NEXT_ENTRY(COMMON_HEX), 4465 NEXT_ENTRY(ITEM_PARAM_IS, 4466 ITEM_PARAM_SPEC, 4467 ITEM_PARAM_MASK)), 4468 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4469 ARGS_ENTRY(struct rte_flow_item_raw, length), 4470 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4471 ITEM_RAW_PATTERN_SIZE)), 4472 }, 4473 [ITEM_ETH] = { 4474 .name = "eth", 4475 .help = "match Ethernet header", 4476 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), 4477 .next = NEXT(item_eth), 4478 .call = parse_vc, 4479 }, 4480 [ITEM_ETH_DST] = { 4481 .name = "dst", 4482 .help = "destination MAC", 4483 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4484 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), 4485 }, 4486 [ITEM_ETH_SRC] = { 4487 .name = "src", 4488 .help = "source MAC", 4489 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4490 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), 4491 }, 4492 [ITEM_ETH_TYPE] = { 4493 .name = "type", 4494 .help = "EtherType", 4495 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4496 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), 4497 }, 4498 [ITEM_ETH_HAS_VLAN] = { 4499 .name = "has_vlan", 4500 .help = "packet header contains VLAN", 4501 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4502 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, 4503 has_vlan, 1)), 4504 }, 4505 [ITEM_VLAN] = { 4506 .name = "vlan", 4507 .help = "match 802.1Q/ad VLAN tag", 4508 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), 4509 .next = NEXT(item_vlan), 4510 .call = parse_vc, 4511 }, 4512 [ITEM_VLAN_TCI] = { 4513 .name = "tci", 4514 .help = "tag control information", 4515 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4516 item_param), 4517 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, hdr.vlan_tci)), 4518 }, 4519 [ITEM_VLAN_PCP] = { 4520 .name = "pcp", 4521 .help = "priority code point", 4522 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4523 item_param), 4524 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4525 hdr.vlan_tci, "\xe0\x00")), 4526 }, 4527 [ITEM_VLAN_DEI] = { 4528 .name = "dei", 4529 .help = "drop eligible indicator", 4530 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4531 item_param), 4532 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4533 hdr.vlan_tci, "\x10\x00")), 4534 }, 4535 [ITEM_VLAN_VID] = { 4536 .name = "vid", 4537 .help = "VLAN identifier", 4538 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4539 item_param), 4540 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4541 hdr.vlan_tci, "\x0f\xff")), 4542 }, 4543 [ITEM_VLAN_INNER_TYPE] = { 4544 .name = "inner_type", 4545 .help = "inner EtherType", 4546 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4547 item_param), 4548 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, 4549 hdr.eth_proto)), 4550 }, 4551 [ITEM_VLAN_HAS_MORE_VLAN] = { 4552 .name = "has_more_vlan", 4553 .help = "packet header contains another VLAN", 4554 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4555 item_param), 4556 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, 4557 has_more_vlan, 1)), 4558 }, 4559 [ITEM_IPV4] = { 4560 .name = "ipv4", 4561 .help = "match IPv4 header", 4562 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), 4563 .next = NEXT(item_ipv4), 4564 .call = parse_vc, 4565 }, 4566 [ITEM_IPV4_VER_IHL] = { 4567 .name = "version_ihl", 4568 .help = "match header length", 4569 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4570 item_param), 4571 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, 4572 hdr.version_ihl)), 4573 }, 4574 [ITEM_IPV4_TOS] = { 4575 .name = "tos", 4576 .help = "type of service", 4577 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4578 item_param), 4579 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4580 hdr.type_of_service)), 4581 }, 4582 [ITEM_IPV4_LENGTH] = { 4583 .name = "length", 4584 .help = "total length", 4585 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4586 item_param), 4587 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4588 hdr.total_length)), 4589 }, 4590 [ITEM_IPV4_ID] = { 4591 .name = "packet_id", 4592 .help = "fragment packet id", 4593 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4594 item_param), 4595 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4596 hdr.packet_id)), 4597 }, 4598 [ITEM_IPV4_FRAGMENT_OFFSET] = { 4599 .name = "fragment_offset", 4600 .help = "fragmentation flags and fragment offset", 4601 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4602 item_param), 4603 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4604 hdr.fragment_offset)), 4605 }, 4606 [ITEM_IPV4_TTL] = { 4607 .name = "ttl", 4608 .help = "time to live", 4609 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4610 item_param), 4611 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4612 hdr.time_to_live)), 4613 }, 4614 [ITEM_IPV4_PROTO] = { 4615 .name = "proto", 4616 .help = "next protocol ID", 4617 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4618 item_param), 4619 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4620 hdr.next_proto_id)), 4621 }, 4622 [ITEM_IPV4_SRC] = { 4623 .name = "src", 4624 .help = "source address", 4625 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4626 item_param), 4627 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4628 hdr.src_addr)), 4629 }, 4630 [ITEM_IPV4_DST] = { 4631 .name = "dst", 4632 .help = "destination address", 4633 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4634 item_param), 4635 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4636 hdr.dst_addr)), 4637 }, 4638 [ITEM_IPV6] = { 4639 .name = "ipv6", 4640 .help = "match IPv6 header", 4641 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), 4642 .next = NEXT(item_ipv6), 4643 .call = parse_vc, 4644 }, 4645 [ITEM_IPV6_TC] = { 4646 .name = "tc", 4647 .help = "traffic class", 4648 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4649 item_param), 4650 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4651 hdr.vtc_flow, 4652 "\x0f\xf0\x00\x00")), 4653 }, 4654 [ITEM_IPV6_FLOW] = { 4655 .name = "flow", 4656 .help = "flow label", 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 "\x00\x0f\xff\xff")), 4662 }, 4663 [ITEM_IPV6_LEN] = { 4664 .name = "length", 4665 .help = "payload length", 4666 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4667 item_param), 4668 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4669 hdr.payload_len)), 4670 }, 4671 [ITEM_IPV6_PROTO] = { 4672 .name = "proto", 4673 .help = "protocol (next header)", 4674 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4675 item_param), 4676 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4677 hdr.proto)), 4678 }, 4679 [ITEM_IPV6_HOP] = { 4680 .name = "hop", 4681 .help = "hop limit", 4682 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4683 item_param), 4684 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4685 hdr.hop_limits)), 4686 }, 4687 [ITEM_IPV6_SRC] = { 4688 .name = "src", 4689 .help = "source address", 4690 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4691 item_param), 4692 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4693 hdr.src_addr)), 4694 }, 4695 [ITEM_IPV6_DST] = { 4696 .name = "dst", 4697 .help = "destination address", 4698 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4699 item_param), 4700 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4701 hdr.dst_addr)), 4702 }, 4703 [ITEM_IPV6_HAS_FRAG_EXT] = { 4704 .name = "has_frag_ext", 4705 .help = "fragment packet attribute", 4706 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4707 item_param), 4708 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, 4709 has_frag_ext, 1)), 4710 }, 4711 [ITEM_IPV6_ROUTING_EXT] = { 4712 .name = "ipv6_routing_ext", 4713 .help = "match IPv6 routing extension header", 4714 .priv = PRIV_ITEM(IPV6_ROUTING_EXT, 4715 sizeof(struct rte_flow_item_ipv6_routing_ext)), 4716 .next = NEXT(item_ipv6_routing_ext), 4717 .call = parse_vc, 4718 }, 4719 [ITEM_IPV6_ROUTING_EXT_TYPE] = { 4720 .name = "ext_type", 4721 .help = "match IPv6 routing extension header type", 4722 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4723 item_param), 4724 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4725 hdr.type)), 4726 }, 4727 [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = { 4728 .name = "ext_next_hdr", 4729 .help = "match IPv6 routing extension header next header type", 4730 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4731 item_param), 4732 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4733 hdr.next_hdr)), 4734 }, 4735 [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = { 4736 .name = "ext_seg_left", 4737 .help = "match IPv6 routing extension header segment left", 4738 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4739 item_param), 4740 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4741 hdr.segments_left)), 4742 }, 4743 [ITEM_ICMP] = { 4744 .name = "icmp", 4745 .help = "match ICMP header", 4746 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), 4747 .next = NEXT(item_icmp), 4748 .call = parse_vc, 4749 }, 4750 [ITEM_ICMP_TYPE] = { 4751 .name = "type", 4752 .help = "ICMP packet type", 4753 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4754 item_param), 4755 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4756 hdr.icmp_type)), 4757 }, 4758 [ITEM_ICMP_CODE] = { 4759 .name = "code", 4760 .help = "ICMP packet code", 4761 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4762 item_param), 4763 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4764 hdr.icmp_code)), 4765 }, 4766 [ITEM_ICMP_IDENT] = { 4767 .name = "ident", 4768 .help = "ICMP packet identifier", 4769 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4770 item_param), 4771 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4772 hdr.icmp_ident)), 4773 }, 4774 [ITEM_ICMP_SEQ] = { 4775 .name = "seq", 4776 .help = "ICMP packet sequence number", 4777 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4778 item_param), 4779 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4780 hdr.icmp_seq_nb)), 4781 }, 4782 [ITEM_UDP] = { 4783 .name = "udp", 4784 .help = "match UDP header", 4785 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), 4786 .next = NEXT(item_udp), 4787 .call = parse_vc, 4788 }, 4789 [ITEM_UDP_SRC] = { 4790 .name = "src", 4791 .help = "UDP source port", 4792 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), 4793 item_param), 4794 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4795 hdr.src_port)), 4796 }, 4797 [ITEM_UDP_DST] = { 4798 .name = "dst", 4799 .help = "UDP destination port", 4800 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4801 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4802 hdr.dst_port)), 4803 }, 4804 [ITEM_TCP] = { 4805 .name = "tcp", 4806 .help = "match TCP header", 4807 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), 4808 .next = NEXT(item_tcp), 4809 .call = parse_vc, 4810 }, 4811 [ITEM_TCP_SRC] = { 4812 .name = "src", 4813 .help = "TCP source port", 4814 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4815 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4816 hdr.src_port)), 4817 }, 4818 [ITEM_TCP_DST] = { 4819 .name = "dst", 4820 .help = "TCP destination port", 4821 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4822 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4823 hdr.dst_port)), 4824 }, 4825 [ITEM_TCP_FLAGS] = { 4826 .name = "flags", 4827 .help = "TCP flags", 4828 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4829 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4830 hdr.tcp_flags)), 4831 }, 4832 [ITEM_SCTP] = { 4833 .name = "sctp", 4834 .help = "match SCTP header", 4835 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), 4836 .next = NEXT(item_sctp), 4837 .call = parse_vc, 4838 }, 4839 [ITEM_SCTP_SRC] = { 4840 .name = "src", 4841 .help = "SCTP source port", 4842 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4843 item_param), 4844 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4845 hdr.src_port)), 4846 }, 4847 [ITEM_SCTP_DST] = { 4848 .name = "dst", 4849 .help = "SCTP destination port", 4850 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4851 item_param), 4852 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4853 hdr.dst_port)), 4854 }, 4855 [ITEM_SCTP_TAG] = { 4856 .name = "tag", 4857 .help = "validation tag", 4858 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4859 item_param), 4860 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4861 hdr.tag)), 4862 }, 4863 [ITEM_SCTP_CKSUM] = { 4864 .name = "cksum", 4865 .help = "checksum", 4866 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4867 item_param), 4868 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4869 hdr.cksum)), 4870 }, 4871 [ITEM_VXLAN] = { 4872 .name = "vxlan", 4873 .help = "match VXLAN header", 4874 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), 4875 .next = NEXT(item_vxlan), 4876 .call = parse_vc, 4877 }, 4878 [ITEM_VXLAN_VNI] = { 4879 .name = "vni", 4880 .help = "VXLAN identifier", 4881 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4882 item_param), 4883 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), 4884 }, 4885 [ITEM_VXLAN_LAST_RSVD] = { 4886 .name = "last_rsvd", 4887 .help = "VXLAN last reserved bits", 4888 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4889 item_param), 4890 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 4891 hdr.rsvd1)), 4892 }, 4893 [ITEM_E_TAG] = { 4894 .name = "e_tag", 4895 .help = "match E-Tag header", 4896 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), 4897 .next = NEXT(item_e_tag), 4898 .call = parse_vc, 4899 }, 4900 [ITEM_E_TAG_GRP_ECID_B] = { 4901 .name = "grp_ecid_b", 4902 .help = "GRP and E-CID base", 4903 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), 4904 item_param), 4905 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, 4906 rsvd_grp_ecid_b, 4907 "\x3f\xff")), 4908 }, 4909 [ITEM_NVGRE] = { 4910 .name = "nvgre", 4911 .help = "match NVGRE header", 4912 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), 4913 .next = NEXT(item_nvgre), 4914 .call = parse_vc, 4915 }, 4916 [ITEM_NVGRE_TNI] = { 4917 .name = "tni", 4918 .help = "virtual subnet ID", 4919 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), 4920 item_param), 4921 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), 4922 }, 4923 [ITEM_MPLS] = { 4924 .name = "mpls", 4925 .help = "match MPLS header", 4926 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), 4927 .next = NEXT(item_mpls), 4928 .call = parse_vc, 4929 }, 4930 [ITEM_MPLS_LABEL] = { 4931 .name = "label", 4932 .help = "MPLS label", 4933 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4934 item_param), 4935 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4936 label_tc_s, 4937 "\xff\xff\xf0")), 4938 }, 4939 [ITEM_MPLS_TC] = { 4940 .name = "tc", 4941 .help = "MPLS Traffic Class", 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 "\x00\x00\x0e")), 4947 }, 4948 [ITEM_MPLS_S] = { 4949 .name = "s", 4950 .help = "MPLS Bottom-of-Stack", 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\x01")), 4956 }, 4957 [ITEM_MPLS_TTL] = { 4958 .name = "ttl", 4959 .help = "MPLS Time-to-Live", 4960 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4961 item_param), 4962 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls, ttl)), 4963 }, 4964 [ITEM_GRE] = { 4965 .name = "gre", 4966 .help = "match GRE header", 4967 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), 4968 .next = NEXT(item_gre), 4969 .call = parse_vc, 4970 }, 4971 [ITEM_GRE_PROTO] = { 4972 .name = "protocol", 4973 .help = "GRE protocol type", 4974 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 4975 item_param), 4976 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 4977 protocol)), 4978 }, 4979 [ITEM_GRE_C_RSVD0_VER] = { 4980 .name = "c_rsvd0_ver", 4981 .help = 4982 "checksum (1b), undefined (1b), key bit (1b)," 4983 " sequence number (1b), reserved 0 (9b)," 4984 " version (3b)", 4985 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 4986 item_param), 4987 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 4988 c_rsvd0_ver)), 4989 }, 4990 [ITEM_GRE_C_BIT] = { 4991 .name = "c_bit", 4992 .help = "checksum bit (C)", 4993 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), 4994 item_param), 4995 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 4996 c_rsvd0_ver, 4997 "\x80\x00\x00\x00")), 4998 }, 4999 [ITEM_GRE_S_BIT] = { 5000 .name = "s_bit", 5001 .help = "sequence number bit (S)", 5002 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5003 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5004 c_rsvd0_ver, 5005 "\x10\x00\x00\x00")), 5006 }, 5007 [ITEM_GRE_K_BIT] = { 5008 .name = "k_bit", 5009 .help = "key bit (K)", 5010 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5011 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5012 c_rsvd0_ver, 5013 "\x20\x00\x00\x00")), 5014 }, 5015 [ITEM_FUZZY] = { 5016 .name = "fuzzy", 5017 .help = "fuzzy pattern match, expect faster than default", 5018 .priv = PRIV_ITEM(FUZZY, 5019 sizeof(struct rte_flow_item_fuzzy)), 5020 .next = NEXT(item_fuzzy), 5021 .call = parse_vc, 5022 }, 5023 [ITEM_FUZZY_THRESH] = { 5024 .name = "thresh", 5025 .help = "match accuracy threshold", 5026 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), 5027 item_param), 5028 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, 5029 thresh)), 5030 }, 5031 [ITEM_GTP] = { 5032 .name = "gtp", 5033 .help = "match GTP header", 5034 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), 5035 .next = NEXT(item_gtp), 5036 .call = parse_vc, 5037 }, 5038 [ITEM_GTP_FLAGS] = { 5039 .name = "v_pt_rsv_flags", 5040 .help = "GTP flags", 5041 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5042 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, 5043 hdr.gtp_hdr_info)), 5044 }, 5045 [ITEM_GTP_MSG_TYPE] = { 5046 .name = "msg_type", 5047 .help = "GTP message type", 5048 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5049 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), 5050 }, 5051 [ITEM_GTP_TEID] = { 5052 .name = "teid", 5053 .help = "tunnel endpoint identifier", 5054 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5055 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), 5056 }, 5057 [ITEM_GTPC] = { 5058 .name = "gtpc", 5059 .help = "match GTP header", 5060 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), 5061 .next = NEXT(item_gtp), 5062 .call = parse_vc, 5063 }, 5064 [ITEM_GTPU] = { 5065 .name = "gtpu", 5066 .help = "match GTP header", 5067 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), 5068 .next = NEXT(item_gtp), 5069 .call = parse_vc, 5070 }, 5071 [ITEM_GENEVE] = { 5072 .name = "geneve", 5073 .help = "match GENEVE header", 5074 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), 5075 .next = NEXT(item_geneve), 5076 .call = parse_vc, 5077 }, 5078 [ITEM_GENEVE_VNI] = { 5079 .name = "vni", 5080 .help = "virtual network identifier", 5081 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5082 item_param), 5083 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), 5084 }, 5085 [ITEM_GENEVE_PROTO] = { 5086 .name = "protocol", 5087 .help = "GENEVE protocol type", 5088 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5089 item_param), 5090 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, 5091 protocol)), 5092 }, 5093 [ITEM_GENEVE_OPTLEN] = { 5094 .name = "optlen", 5095 .help = "GENEVE options length in dwords", 5096 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5097 item_param), 5098 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, 5099 ver_opt_len_o_c_rsvd0, 5100 "\x3f\x00")), 5101 }, 5102 [ITEM_VXLAN_GPE] = { 5103 .name = "vxlan-gpe", 5104 .help = "match VXLAN-GPE header", 5105 .priv = PRIV_ITEM(VXLAN_GPE, 5106 sizeof(struct rte_flow_item_vxlan_gpe)), 5107 .next = NEXT(item_vxlan_gpe), 5108 .call = parse_vc, 5109 }, 5110 [ITEM_VXLAN_GPE_VNI] = { 5111 .name = "vni", 5112 .help = "VXLAN-GPE identifier", 5113 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5114 item_param), 5115 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5116 hdr.vni)), 5117 }, 5118 [ITEM_VXLAN_GPE_PROTO] = { 5119 .name = "protocol", 5120 .help = "VXLAN-GPE next protocol", 5121 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5122 item_param), 5123 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5124 protocol)), 5125 }, 5126 [ITEM_ARP_ETH_IPV4] = { 5127 .name = "arp_eth_ipv4", 5128 .help = "match ARP header for Ethernet/IPv4", 5129 .priv = PRIV_ITEM(ARP_ETH_IPV4, 5130 sizeof(struct rte_flow_item_arp_eth_ipv4)), 5131 .next = NEXT(item_arp_eth_ipv4), 5132 .call = parse_vc, 5133 }, 5134 [ITEM_ARP_ETH_IPV4_SHA] = { 5135 .name = "sha", 5136 .help = "sender hardware address", 5137 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5138 item_param), 5139 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5140 hdr.arp_data.arp_sha)), 5141 }, 5142 [ITEM_ARP_ETH_IPV4_SPA] = { 5143 .name = "spa", 5144 .help = "sender IPv4 address", 5145 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5146 item_param), 5147 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5148 hdr.arp_data.arp_sip)), 5149 }, 5150 [ITEM_ARP_ETH_IPV4_THA] = { 5151 .name = "tha", 5152 .help = "target hardware address", 5153 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5154 item_param), 5155 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5156 hdr.arp_data.arp_tha)), 5157 }, 5158 [ITEM_ARP_ETH_IPV4_TPA] = { 5159 .name = "tpa", 5160 .help = "target IPv4 address", 5161 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5162 item_param), 5163 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5164 hdr.arp_data.arp_tip)), 5165 }, 5166 [ITEM_IPV6_EXT] = { 5167 .name = "ipv6_ext", 5168 .help = "match presence of any IPv6 extension header", 5169 .priv = PRIV_ITEM(IPV6_EXT, 5170 sizeof(struct rte_flow_item_ipv6_ext)), 5171 .next = NEXT(item_ipv6_ext), 5172 .call = parse_vc, 5173 }, 5174 [ITEM_IPV6_EXT_NEXT_HDR] = { 5175 .name = "next_hdr", 5176 .help = "next header", 5177 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5178 item_param), 5179 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 5180 next_hdr)), 5181 }, 5182 [ITEM_IPV6_FRAG_EXT] = { 5183 .name = "ipv6_frag_ext", 5184 .help = "match presence of IPv6 fragment extension header", 5185 .priv = PRIV_ITEM(IPV6_FRAG_EXT, 5186 sizeof(struct rte_flow_item_ipv6_frag_ext)), 5187 .next = NEXT(item_ipv6_frag_ext), 5188 .call = parse_vc, 5189 }, 5190 [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { 5191 .name = "next_hdr", 5192 .help = "next header", 5193 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5194 item_param), 5195 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, 5196 hdr.next_header)), 5197 }, 5198 [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { 5199 .name = "frag_data", 5200 .help = "fragment flags and offset", 5201 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5202 item_param), 5203 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5204 hdr.frag_data)), 5205 }, 5206 [ITEM_IPV6_FRAG_EXT_ID] = { 5207 .name = "packet_id", 5208 .help = "fragment packet id", 5209 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5210 item_param), 5211 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5212 hdr.id)), 5213 }, 5214 [ITEM_ICMP6] = { 5215 .name = "icmp6", 5216 .help = "match any ICMPv6 header", 5217 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), 5218 .next = NEXT(item_icmp6), 5219 .call = parse_vc, 5220 }, 5221 [ITEM_ICMP6_TYPE] = { 5222 .name = "type", 5223 .help = "ICMPv6 type", 5224 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5225 item_param), 5226 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5227 type)), 5228 }, 5229 [ITEM_ICMP6_CODE] = { 5230 .name = "code", 5231 .help = "ICMPv6 code", 5232 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5233 item_param), 5234 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5235 code)), 5236 }, 5237 [ITEM_ICMP6_ECHO_REQUEST] = { 5238 .name = "icmp6_echo_request", 5239 .help = "match ICMPv6 echo request", 5240 .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, 5241 sizeof(struct rte_flow_item_icmp6_echo)), 5242 .next = NEXT(item_icmp6_echo_request), 5243 .call = parse_vc, 5244 }, 5245 [ITEM_ICMP6_ECHO_REQUEST_ID] = { 5246 .name = "ident", 5247 .help = "ICMPv6 echo request identifier", 5248 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5249 item_param), 5250 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5251 hdr.identifier)), 5252 }, 5253 [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { 5254 .name = "seq", 5255 .help = "ICMPv6 echo request sequence", 5256 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5257 item_param), 5258 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5259 hdr.sequence)), 5260 }, 5261 [ITEM_ICMP6_ECHO_REPLY] = { 5262 .name = "icmp6_echo_reply", 5263 .help = "match ICMPv6 echo reply", 5264 .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, 5265 sizeof(struct rte_flow_item_icmp6_echo)), 5266 .next = NEXT(item_icmp6_echo_reply), 5267 .call = parse_vc, 5268 }, 5269 [ITEM_ICMP6_ECHO_REPLY_ID] = { 5270 .name = "ident", 5271 .help = "ICMPv6 echo reply identifier", 5272 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5273 item_param), 5274 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5275 hdr.identifier)), 5276 }, 5277 [ITEM_ICMP6_ECHO_REPLY_SEQ] = { 5278 .name = "seq", 5279 .help = "ICMPv6 echo reply sequence", 5280 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5281 item_param), 5282 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5283 hdr.sequence)), 5284 }, 5285 [ITEM_ICMP6_ND_NS] = { 5286 .name = "icmp6_nd_ns", 5287 .help = "match ICMPv6 neighbor discovery solicitation", 5288 .priv = PRIV_ITEM(ICMP6_ND_NS, 5289 sizeof(struct rte_flow_item_icmp6_nd_ns)), 5290 .next = NEXT(item_icmp6_nd_ns), 5291 .call = parse_vc, 5292 }, 5293 [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { 5294 .name = "target_addr", 5295 .help = "target address", 5296 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), 5297 item_param), 5298 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, 5299 target_addr)), 5300 }, 5301 [ITEM_ICMP6_ND_NA] = { 5302 .name = "icmp6_nd_na", 5303 .help = "match ICMPv6 neighbor discovery advertisement", 5304 .priv = PRIV_ITEM(ICMP6_ND_NA, 5305 sizeof(struct rte_flow_item_icmp6_nd_na)), 5306 .next = NEXT(item_icmp6_nd_na), 5307 .call = parse_vc, 5308 }, 5309 [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { 5310 .name = "target_addr", 5311 .help = "target address", 5312 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), 5313 item_param), 5314 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, 5315 target_addr)), 5316 }, 5317 [ITEM_ICMP6_ND_OPT] = { 5318 .name = "icmp6_nd_opt", 5319 .help = "match presence of any ICMPv6 neighbor discovery" 5320 " option", 5321 .priv = PRIV_ITEM(ICMP6_ND_OPT, 5322 sizeof(struct rte_flow_item_icmp6_nd_opt)), 5323 .next = NEXT(item_icmp6_nd_opt), 5324 .call = parse_vc, 5325 }, 5326 [ITEM_ICMP6_ND_OPT_TYPE] = { 5327 .name = "type", 5328 .help = "ND option type", 5329 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5330 item_param), 5331 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, 5332 type)), 5333 }, 5334 [ITEM_ICMP6_ND_OPT_SLA_ETH] = { 5335 .name = "icmp6_nd_opt_sla_eth", 5336 .help = "match ICMPv6 neighbor discovery source Ethernet" 5337 " link-layer address option", 5338 .priv = PRIV_ITEM 5339 (ICMP6_ND_OPT_SLA_ETH, 5340 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), 5341 .next = NEXT(item_icmp6_nd_opt_sla_eth), 5342 .call = parse_vc, 5343 }, 5344 [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { 5345 .name = "sla", 5346 .help = "source Ethernet LLA", 5347 .next = NEXT(item_icmp6_nd_opt_sla_eth, 5348 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5349 .args = ARGS(ARGS_ENTRY_HTON 5350 (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), 5351 }, 5352 [ITEM_ICMP6_ND_OPT_TLA_ETH] = { 5353 .name = "icmp6_nd_opt_tla_eth", 5354 .help = "match ICMPv6 neighbor discovery target Ethernet" 5355 " link-layer address option", 5356 .priv = PRIV_ITEM 5357 (ICMP6_ND_OPT_TLA_ETH, 5358 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), 5359 .next = NEXT(item_icmp6_nd_opt_tla_eth), 5360 .call = parse_vc, 5361 }, 5362 [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { 5363 .name = "tla", 5364 .help = "target Ethernet LLA", 5365 .next = NEXT(item_icmp6_nd_opt_tla_eth, 5366 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5367 .args = ARGS(ARGS_ENTRY_HTON 5368 (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), 5369 }, 5370 [ITEM_META] = { 5371 .name = "meta", 5372 .help = "match metadata header", 5373 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), 5374 .next = NEXT(item_meta), 5375 .call = parse_vc, 5376 }, 5377 [ITEM_META_DATA] = { 5378 .name = "data", 5379 .help = "metadata value", 5380 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), 5381 item_param), 5382 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, 5383 data, "\xff\xff\xff\xff")), 5384 }, 5385 [ITEM_RANDOM] = { 5386 .name = "random", 5387 .help = "match random value", 5388 .priv = PRIV_ITEM(RANDOM, sizeof(struct rte_flow_item_random)), 5389 .next = NEXT(item_random), 5390 .call = parse_vc, 5391 }, 5392 [ITEM_RANDOM_VALUE] = { 5393 .name = "value", 5394 .help = "random value", 5395 .next = NEXT(item_random, NEXT_ENTRY(COMMON_UNSIGNED), 5396 item_param), 5397 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_random, 5398 value, "\xff\xff")), 5399 }, 5400 [ITEM_GRE_KEY] = { 5401 .name = "gre_key", 5402 .help = "match GRE key", 5403 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), 5404 .next = NEXT(item_gre_key), 5405 .call = parse_vc, 5406 }, 5407 [ITEM_GRE_KEY_VALUE] = { 5408 .name = "value", 5409 .help = "key value", 5410 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), 5411 item_param), 5412 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5413 }, 5414 [ITEM_GRE_OPTION] = { 5415 .name = "gre_option", 5416 .help = "match GRE optional fields", 5417 .priv = PRIV_ITEM(GRE_OPTION, 5418 sizeof(struct rte_flow_item_gre_opt)), 5419 .next = NEXT(item_gre_option), 5420 .call = parse_vc, 5421 }, 5422 [ITEM_GRE_OPTION_CHECKSUM] = { 5423 .name = "checksum", 5424 .help = "match GRE checksum", 5425 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5426 item_param), 5427 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5428 checksum_rsvd.checksum)), 5429 }, 5430 [ITEM_GRE_OPTION_KEY] = { 5431 .name = "key", 5432 .help = "match GRE key", 5433 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5434 item_param), 5435 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5436 key.key)), 5437 }, 5438 [ITEM_GRE_OPTION_SEQUENCE] = { 5439 .name = "sequence", 5440 .help = "match GRE sequence", 5441 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5442 item_param), 5443 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5444 sequence.sequence)), 5445 }, 5446 [ITEM_GTP_PSC] = { 5447 .name = "gtp_psc", 5448 .help = "match GTP extension header with type 0x85", 5449 .priv = PRIV_ITEM(GTP_PSC, 5450 sizeof(struct rte_flow_item_gtp_psc)), 5451 .next = NEXT(item_gtp_psc), 5452 .call = parse_vc, 5453 }, 5454 [ITEM_GTP_PSC_QFI] = { 5455 .name = "qfi", 5456 .help = "QoS flow identifier", 5457 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5458 item_param), 5459 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5460 hdr.qfi, 6)), 5461 }, 5462 [ITEM_GTP_PSC_PDU_T] = { 5463 .name = "pdu_t", 5464 .help = "PDU type", 5465 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5466 item_param), 5467 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5468 hdr.type, 4)), 5469 }, 5470 [ITEM_PPPOES] = { 5471 .name = "pppoes", 5472 .help = "match PPPoE session header", 5473 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), 5474 .next = NEXT(item_pppoes), 5475 .call = parse_vc, 5476 }, 5477 [ITEM_PPPOED] = { 5478 .name = "pppoed", 5479 .help = "match PPPoE discovery header", 5480 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), 5481 .next = NEXT(item_pppoed), 5482 .call = parse_vc, 5483 }, 5484 [ITEM_PPPOE_SEID] = { 5485 .name = "seid", 5486 .help = "session identifier", 5487 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), 5488 item_param), 5489 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, 5490 session_id)), 5491 }, 5492 [ITEM_PPPOE_PROTO_ID] = { 5493 .name = "pppoe_proto_id", 5494 .help = "match PPPoE session protocol identifier", 5495 .priv = PRIV_ITEM(PPPOE_PROTO_ID, 5496 sizeof(struct rte_flow_item_pppoe_proto_id)), 5497 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED), 5498 item_param), 5499 .args = ARGS(ARGS_ENTRY_HTON 5500 (struct rte_flow_item_pppoe_proto_id, proto_id)), 5501 .call = parse_vc, 5502 }, 5503 [ITEM_HIGIG2] = { 5504 .name = "higig2", 5505 .help = "matches higig2 header", 5506 .priv = PRIV_ITEM(HIGIG2, 5507 sizeof(struct rte_flow_item_higig2_hdr)), 5508 .next = NEXT(item_higig2), 5509 .call = parse_vc, 5510 }, 5511 [ITEM_HIGIG2_CLASSIFICATION] = { 5512 .name = "classification", 5513 .help = "matches classification of higig2 header", 5514 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5515 item_param), 5516 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5517 hdr.ppt1.classification)), 5518 }, 5519 [ITEM_HIGIG2_VID] = { 5520 .name = "vid", 5521 .help = "matches vid of higig2 header", 5522 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5523 item_param), 5524 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5525 hdr.ppt1.vid)), 5526 }, 5527 [ITEM_TAG] = { 5528 .name = "tag", 5529 .help = "match tag value", 5530 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), 5531 .next = NEXT(item_tag), 5532 .call = parse_vc, 5533 }, 5534 [ITEM_TAG_DATA] = { 5535 .name = "data", 5536 .help = "tag value to match", 5537 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5538 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), 5539 }, 5540 [ITEM_TAG_INDEX] = { 5541 .name = "index", 5542 .help = "index of tag array to match", 5543 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5544 NEXT_ENTRY(ITEM_PARAM_IS)), 5545 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), 5546 }, 5547 [ITEM_L2TPV3OIP] = { 5548 .name = "l2tpv3oip", 5549 .help = "match L2TPv3 over IP header", 5550 .priv = PRIV_ITEM(L2TPV3OIP, 5551 sizeof(struct rte_flow_item_l2tpv3oip)), 5552 .next = NEXT(item_l2tpv3oip), 5553 .call = parse_vc, 5554 }, 5555 [ITEM_L2TPV3OIP_SESSION_ID] = { 5556 .name = "session_id", 5557 .help = "session identifier", 5558 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), 5559 item_param), 5560 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, 5561 session_id)), 5562 }, 5563 [ITEM_ESP] = { 5564 .name = "esp", 5565 .help = "match ESP header", 5566 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), 5567 .next = NEXT(item_esp), 5568 .call = parse_vc, 5569 }, 5570 [ITEM_ESP_SPI] = { 5571 .name = "spi", 5572 .help = "security policy index", 5573 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5574 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, 5575 hdr.spi)), 5576 }, 5577 [ITEM_AH] = { 5578 .name = "ah", 5579 .help = "match AH header", 5580 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), 5581 .next = NEXT(item_ah), 5582 .call = parse_vc, 5583 }, 5584 [ITEM_AH_SPI] = { 5585 .name = "spi", 5586 .help = "security parameters index", 5587 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5588 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), 5589 }, 5590 [ITEM_PFCP] = { 5591 .name = "pfcp", 5592 .help = "match pfcp header", 5593 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), 5594 .next = NEXT(item_pfcp), 5595 .call = parse_vc, 5596 }, 5597 [ITEM_PFCP_S_FIELD] = { 5598 .name = "s_field", 5599 .help = "S field", 5600 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5601 item_param), 5602 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, 5603 s_field)), 5604 }, 5605 [ITEM_PFCP_SEID] = { 5606 .name = "seid", 5607 .help = "session endpoint identifier", 5608 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5609 item_param), 5610 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), 5611 }, 5612 [ITEM_ECPRI] = { 5613 .name = "ecpri", 5614 .help = "match eCPRI header", 5615 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), 5616 .next = NEXT(item_ecpri), 5617 .call = parse_vc, 5618 }, 5619 [ITEM_ECPRI_COMMON] = { 5620 .name = "common", 5621 .help = "eCPRI common header", 5622 .next = NEXT(item_ecpri_common), 5623 }, 5624 [ITEM_ECPRI_COMMON_TYPE] = { 5625 .name = "type", 5626 .help = "type of common header", 5627 .next = NEXT(item_ecpri_common_type), 5628 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), 5629 }, 5630 [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { 5631 .name = "iq_data", 5632 .help = "Type #0: IQ Data", 5633 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5634 ITEM_NEXT)), 5635 .call = parse_vc_item_ecpri_type, 5636 }, 5637 [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { 5638 .name = "pc_id", 5639 .help = "Physical Channel ID", 5640 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5641 ITEM_ECPRI_COMMON, ITEM_NEXT), 5642 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5643 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5644 hdr.type0.pc_id)), 5645 }, 5646 [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { 5647 .name = "rtc_ctrl", 5648 .help = "Type #2: Real-Time Control Data", 5649 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5650 ITEM_NEXT)), 5651 .call = parse_vc_item_ecpri_type, 5652 }, 5653 [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { 5654 .name = "rtc_id", 5655 .help = "Real-Time Control Data ID", 5656 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5657 ITEM_ECPRI_COMMON, ITEM_NEXT), 5658 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5659 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5660 hdr.type2.rtc_id)), 5661 }, 5662 [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { 5663 .name = "delay_measure", 5664 .help = "Type #5: One-Way Delay Measurement", 5665 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5666 ITEM_NEXT)), 5667 .call = parse_vc_item_ecpri_type, 5668 }, 5669 [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { 5670 .name = "msr_id", 5671 .help = "Measurement ID", 5672 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5673 ITEM_ECPRI_COMMON, ITEM_NEXT), 5674 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5675 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5676 hdr.type5.msr_id)), 5677 }, 5678 [ITEM_GENEVE_OPT] = { 5679 .name = "geneve-opt", 5680 .help = "GENEVE header option", 5681 .priv = PRIV_ITEM(GENEVE_OPT, 5682 sizeof(struct rte_flow_item_geneve_opt) + 5683 ITEM_GENEVE_OPT_DATA_SIZE), 5684 .next = NEXT(item_geneve_opt), 5685 .call = parse_vc, 5686 }, 5687 [ITEM_GENEVE_OPT_CLASS] = { 5688 .name = "class", 5689 .help = "GENEVE option class", 5690 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5691 item_param), 5692 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, 5693 option_class)), 5694 }, 5695 [ITEM_GENEVE_OPT_TYPE] = { 5696 .name = "type", 5697 .help = "GENEVE option type", 5698 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5699 item_param), 5700 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, 5701 option_type)), 5702 }, 5703 [ITEM_GENEVE_OPT_LENGTH] = { 5704 .name = "length", 5705 .help = "GENEVE option data length (in 32b words)", 5706 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5707 item_param), 5708 .args = ARGS(ARGS_ENTRY_BOUNDED( 5709 struct rte_flow_item_geneve_opt, option_len, 5710 0, 31)), 5711 }, 5712 [ITEM_GENEVE_OPT_DATA] = { 5713 .name = "data", 5714 .help = "GENEVE option data pattern", 5715 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), 5716 item_param), 5717 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), 5718 ARGS_ENTRY_ARB(0, 0), 5719 ARGS_ENTRY_ARB 5720 (sizeof(struct rte_flow_item_geneve_opt), 5721 ITEM_GENEVE_OPT_DATA_SIZE)), 5722 }, 5723 [ITEM_INTEGRITY] = { 5724 .name = "integrity", 5725 .help = "match packet integrity", 5726 .priv = PRIV_ITEM(INTEGRITY, 5727 sizeof(struct rte_flow_item_integrity)), 5728 .next = NEXT(item_integrity), 5729 .call = parse_vc, 5730 }, 5731 [ITEM_INTEGRITY_LEVEL] = { 5732 .name = "level", 5733 .help = "integrity level", 5734 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5735 item_param), 5736 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), 5737 }, 5738 [ITEM_INTEGRITY_VALUE] = { 5739 .name = "value", 5740 .help = "integrity value", 5741 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5742 item_param), 5743 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), 5744 }, 5745 [ITEM_CONNTRACK] = { 5746 .name = "conntrack", 5747 .help = "conntrack state", 5748 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 5749 item_param), 5750 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 5751 }, 5752 [ITEM_PORT_REPRESENTOR] = { 5753 .name = "port_representor", 5754 .help = "match traffic entering the embedded switch from the given ethdev", 5755 .priv = PRIV_ITEM(PORT_REPRESENTOR, 5756 sizeof(struct rte_flow_item_ethdev)), 5757 .next = NEXT(item_port_representor), 5758 .call = parse_vc, 5759 }, 5760 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 5761 .name = "port_id", 5762 .help = "ethdev port ID", 5763 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 5764 item_param), 5765 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5766 }, 5767 [ITEM_REPRESENTED_PORT] = { 5768 .name = "represented_port", 5769 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 5770 .priv = PRIV_ITEM(REPRESENTED_PORT, 5771 sizeof(struct rte_flow_item_ethdev)), 5772 .next = NEXT(item_represented_port), 5773 .call = parse_vc, 5774 }, 5775 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 5776 .name = "ethdev_port_id", 5777 .help = "ethdev port ID", 5778 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 5779 item_param), 5780 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5781 }, 5782 [ITEM_FLEX] = { 5783 .name = "flex", 5784 .help = "match flex header", 5785 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 5786 .next = NEXT(item_flex), 5787 .call = parse_vc, 5788 }, 5789 [ITEM_FLEX_ITEM_HANDLE] = { 5790 .name = "item", 5791 .help = "flex item handle", 5792 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5793 NEXT_ENTRY(ITEM_PARAM_IS)), 5794 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 5795 }, 5796 [ITEM_FLEX_PATTERN_HANDLE] = { 5797 .name = "pattern", 5798 .help = "flex pattern handle", 5799 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5800 NEXT_ENTRY(ITEM_PARAM_IS)), 5801 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 5802 }, 5803 [ITEM_L2TPV2] = { 5804 .name = "l2tpv2", 5805 .help = "match L2TPv2 header", 5806 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 5807 .next = NEXT(item_l2tpv2), 5808 .call = parse_vc, 5809 }, 5810 [ITEM_L2TPV2_TYPE] = { 5811 .name = "type", 5812 .help = "type of l2tpv2", 5813 .next = NEXT(item_l2tpv2_type), 5814 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 5815 }, 5816 [ITEM_L2TPV2_TYPE_DATA] = { 5817 .name = "data", 5818 .help = "Type #7: data message without any options", 5819 .next = NEXT(item_l2tpv2_type_data), 5820 .call = parse_vc_item_l2tpv2_type, 5821 }, 5822 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 5823 .name = "tunnel_id", 5824 .help = "tunnel identifier", 5825 .next = NEXT(item_l2tpv2_type_data, 5826 NEXT_ENTRY(COMMON_UNSIGNED), 5827 item_param), 5828 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5829 hdr.type7.tunnel_id)), 5830 }, 5831 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 5832 .name = "session_id", 5833 .help = "session identifier", 5834 .next = NEXT(item_l2tpv2_type_data, 5835 NEXT_ENTRY(COMMON_UNSIGNED), 5836 item_param), 5837 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5838 hdr.type7.session_id)), 5839 }, 5840 [ITEM_L2TPV2_TYPE_DATA_L] = { 5841 .name = "data_l", 5842 .help = "Type #6: data message with length option", 5843 .next = NEXT(item_l2tpv2_type_data_l), 5844 .call = parse_vc_item_l2tpv2_type, 5845 }, 5846 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 5847 .name = "length", 5848 .help = "message length", 5849 .next = NEXT(item_l2tpv2_type_data_l, 5850 NEXT_ENTRY(COMMON_UNSIGNED), 5851 item_param), 5852 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5853 hdr.type6.length)), 5854 }, 5855 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 5856 .name = "tunnel_id", 5857 .help = "tunnel identifier", 5858 .next = NEXT(item_l2tpv2_type_data_l, 5859 NEXT_ENTRY(COMMON_UNSIGNED), 5860 item_param), 5861 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5862 hdr.type6.tunnel_id)), 5863 }, 5864 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 5865 .name = "session_id", 5866 .help = "session identifier", 5867 .next = NEXT(item_l2tpv2_type_data_l, 5868 NEXT_ENTRY(COMMON_UNSIGNED), 5869 item_param), 5870 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5871 hdr.type6.session_id)), 5872 }, 5873 [ITEM_L2TPV2_TYPE_DATA_S] = { 5874 .name = "data_s", 5875 .help = "Type #5: data message with ns, nr option", 5876 .next = NEXT(item_l2tpv2_type_data_s), 5877 .call = parse_vc_item_l2tpv2_type, 5878 }, 5879 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 5880 .name = "tunnel_id", 5881 .help = "tunnel identifier", 5882 .next = NEXT(item_l2tpv2_type_data_s, 5883 NEXT_ENTRY(COMMON_UNSIGNED), 5884 item_param), 5885 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5886 hdr.type5.tunnel_id)), 5887 }, 5888 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 5889 .name = "session_id", 5890 .help = "session identifier", 5891 .next = NEXT(item_l2tpv2_type_data_s, 5892 NEXT_ENTRY(COMMON_UNSIGNED), 5893 item_param), 5894 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5895 hdr.type5.session_id)), 5896 }, 5897 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 5898 .name = "ns", 5899 .help = "sequence number for message", 5900 .next = NEXT(item_l2tpv2_type_data_s, 5901 NEXT_ENTRY(COMMON_UNSIGNED), 5902 item_param), 5903 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5904 hdr.type5.ns)), 5905 }, 5906 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 5907 .name = "nr", 5908 .help = "sequence number for next receive message", 5909 .next = NEXT(item_l2tpv2_type_data_s, 5910 NEXT_ENTRY(COMMON_UNSIGNED), 5911 item_param), 5912 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5913 hdr.type5.nr)), 5914 }, 5915 [ITEM_L2TPV2_TYPE_DATA_O] = { 5916 .name = "data_o", 5917 .help = "Type #4: data message with offset option", 5918 .next = NEXT(item_l2tpv2_type_data_o), 5919 .call = parse_vc_item_l2tpv2_type, 5920 }, 5921 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 5922 .name = "tunnel_id", 5923 .help = "tunnel identifier", 5924 .next = NEXT(item_l2tpv2_type_data_o, 5925 NEXT_ENTRY(COMMON_UNSIGNED), 5926 item_param), 5927 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5928 hdr.type4.tunnel_id)), 5929 }, 5930 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 5931 .name = "session_id", 5932 .help = "session identifier", 5933 .next = NEXT(item_l2tpv2_type_data_o, 5934 NEXT_ENTRY(COMMON_UNSIGNED), 5935 item_param), 5936 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5937 hdr.type5.session_id)), 5938 }, 5939 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 5940 .name = "offset_size", 5941 .help = "the size of offset padding", 5942 .next = NEXT(item_l2tpv2_type_data_o, 5943 NEXT_ENTRY(COMMON_UNSIGNED), 5944 item_param), 5945 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5946 hdr.type4.offset_size)), 5947 }, 5948 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 5949 .name = "data_l_s", 5950 .help = "Type #3: data message contains length, ns, nr " 5951 "options", 5952 .next = NEXT(item_l2tpv2_type_data_l_s), 5953 .call = parse_vc_item_l2tpv2_type, 5954 }, 5955 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 5956 .name = "length", 5957 .help = "message length", 5958 .next = NEXT(item_l2tpv2_type_data_l_s, 5959 NEXT_ENTRY(COMMON_UNSIGNED), 5960 item_param), 5961 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5962 hdr.type3.length)), 5963 }, 5964 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 5965 .name = "tunnel_id", 5966 .help = "tunnel identifier", 5967 .next = NEXT(item_l2tpv2_type_data_l_s, 5968 NEXT_ENTRY(COMMON_UNSIGNED), 5969 item_param), 5970 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5971 hdr.type3.tunnel_id)), 5972 }, 5973 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 5974 .name = "session_id", 5975 .help = "session identifier", 5976 .next = NEXT(item_l2tpv2_type_data_l_s, 5977 NEXT_ENTRY(COMMON_UNSIGNED), 5978 item_param), 5979 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5980 hdr.type3.session_id)), 5981 }, 5982 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 5983 .name = "ns", 5984 .help = "sequence number for message", 5985 .next = NEXT(item_l2tpv2_type_data_l_s, 5986 NEXT_ENTRY(COMMON_UNSIGNED), 5987 item_param), 5988 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5989 hdr.type3.ns)), 5990 }, 5991 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 5992 .name = "nr", 5993 .help = "sequence number for next receive message", 5994 .next = NEXT(item_l2tpv2_type_data_l_s, 5995 NEXT_ENTRY(COMMON_UNSIGNED), 5996 item_param), 5997 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5998 hdr.type3.nr)), 5999 }, 6000 [ITEM_L2TPV2_TYPE_CTRL] = { 6001 .name = "control", 6002 .help = "Type #3: conrtol message contains length, ns, nr " 6003 "options", 6004 .next = NEXT(item_l2tpv2_type_ctrl), 6005 .call = parse_vc_item_l2tpv2_type, 6006 }, 6007 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 6008 .name = "length", 6009 .help = "message length", 6010 .next = NEXT(item_l2tpv2_type_ctrl, 6011 NEXT_ENTRY(COMMON_UNSIGNED), 6012 item_param), 6013 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6014 hdr.type3.length)), 6015 }, 6016 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 6017 .name = "tunnel_id", 6018 .help = "tunnel identifier", 6019 .next = NEXT(item_l2tpv2_type_ctrl, 6020 NEXT_ENTRY(COMMON_UNSIGNED), 6021 item_param), 6022 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6023 hdr.type3.tunnel_id)), 6024 }, 6025 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 6026 .name = "session_id", 6027 .help = "session identifier", 6028 .next = NEXT(item_l2tpv2_type_ctrl, 6029 NEXT_ENTRY(COMMON_UNSIGNED), 6030 item_param), 6031 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6032 hdr.type3.session_id)), 6033 }, 6034 [ITEM_L2TPV2_MSG_CTRL_NS] = { 6035 .name = "ns", 6036 .help = "sequence number for message", 6037 .next = NEXT(item_l2tpv2_type_ctrl, 6038 NEXT_ENTRY(COMMON_UNSIGNED), 6039 item_param), 6040 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6041 hdr.type3.ns)), 6042 }, 6043 [ITEM_L2TPV2_MSG_CTRL_NR] = { 6044 .name = "nr", 6045 .help = "sequence number for next receive message", 6046 .next = NEXT(item_l2tpv2_type_ctrl, 6047 NEXT_ENTRY(COMMON_UNSIGNED), 6048 item_param), 6049 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6050 hdr.type3.nr)), 6051 }, 6052 [ITEM_PPP] = { 6053 .name = "ppp", 6054 .help = "match PPP header", 6055 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 6056 .next = NEXT(item_ppp), 6057 .call = parse_vc, 6058 }, 6059 [ITEM_PPP_ADDR] = { 6060 .name = "addr", 6061 .help = "PPP address", 6062 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6063 item_param), 6064 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 6065 }, 6066 [ITEM_PPP_CTRL] = { 6067 .name = "ctrl", 6068 .help = "PPP control", 6069 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6070 item_param), 6071 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 6072 }, 6073 [ITEM_PPP_PROTO_ID] = { 6074 .name = "proto_id", 6075 .help = "PPP protocol identifier", 6076 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6077 item_param), 6078 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 6079 hdr.proto_id)), 6080 }, 6081 [ITEM_METER] = { 6082 .name = "meter", 6083 .help = "match meter color", 6084 .priv = PRIV_ITEM(METER_COLOR, 6085 sizeof(struct rte_flow_item_meter_color)), 6086 .next = NEXT(item_meter), 6087 .call = parse_vc, 6088 }, 6089 [ITEM_METER_COLOR] = { 6090 .name = "color", 6091 .help = "meter color", 6092 .next = NEXT(item_meter, 6093 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 6094 item_param), 6095 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 6096 color)), 6097 }, 6098 [ITEM_METER_COLOR_NAME] = { 6099 .name = "color_name", 6100 .help = "meter color name", 6101 .call = parse_meter_color, 6102 .comp = comp_meter_color, 6103 }, 6104 [ITEM_QUOTA] = { 6105 .name = "quota", 6106 .help = "match quota", 6107 .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), 6108 .next = NEXT(item_quota), 6109 .call = parse_vc 6110 }, 6111 [ITEM_QUOTA_STATE] = { 6112 .name = "quota_state", 6113 .help = "quota state", 6114 .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), 6115 NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), 6116 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) 6117 }, 6118 [ITEM_QUOTA_STATE_NAME] = { 6119 .name = "state_name", 6120 .help = "quota state name", 6121 .call = parse_quota_state_name, 6122 .comp = comp_quota_state_name 6123 }, 6124 [ITEM_IB_BTH] = { 6125 .name = "ib_bth", 6126 .help = "match ib bth fields", 6127 .priv = PRIV_ITEM(IB_BTH, 6128 sizeof(struct rte_flow_item_ib_bth)), 6129 .next = NEXT(item_ib_bth), 6130 .call = parse_vc, 6131 }, 6132 [ITEM_IB_BTH_OPCODE] = { 6133 .name = "opcode", 6134 .help = "match ib bth opcode", 6135 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6136 item_param), 6137 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6138 hdr.opcode)), 6139 }, 6140 [ITEM_IB_BTH_PKEY] = { 6141 .name = "pkey", 6142 .help = "partition key", 6143 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6144 item_param), 6145 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6146 hdr.pkey)), 6147 }, 6148 [ITEM_IB_BTH_DST_QPN] = { 6149 .name = "dst_qp", 6150 .help = "destination qp", 6151 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6152 item_param), 6153 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6154 hdr.dst_qp)), 6155 }, 6156 [ITEM_IB_BTH_PSN] = { 6157 .name = "psn", 6158 .help = "packet sequence number", 6159 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6160 item_param), 6161 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6162 hdr.psn)), 6163 }, 6164 [ITEM_PTYPE] = { 6165 .name = "ptype", 6166 .help = "match L2/L3/L4 and tunnel information", 6167 .priv = PRIV_ITEM(PTYPE, 6168 sizeof(struct rte_flow_item_ptype)), 6169 .next = NEXT(item_ptype), 6170 .call = parse_vc, 6171 }, 6172 [ITEM_PTYPE_VALUE] = { 6173 .name = "packet_type", 6174 .help = "packet type as defined in rte_mbuf_ptype", 6175 .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), 6176 item_param), 6177 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), 6178 }, 6179 [ITEM_NSH] = { 6180 .name = "nsh", 6181 .help = "match NSH header", 6182 .priv = PRIV_ITEM(NSH, 6183 sizeof(struct rte_flow_item_nsh)), 6184 .next = NEXT(item_nsh), 6185 .call = parse_vc, 6186 }, 6187 [ITEM_COMPARE] = { 6188 .name = "compare", 6189 .help = "match with the comparison result", 6190 .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)), 6191 .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)), 6192 .call = parse_vc, 6193 }, 6194 [ITEM_COMPARE_OP] = { 6195 .name = "op", 6196 .help = "operation type", 6197 .next = NEXT(item_compare_field, 6198 NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param), 6199 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)), 6200 }, 6201 [ITEM_COMPARE_OP_VALUE] = { 6202 .name = "{operation}", 6203 .help = "operation type value", 6204 .call = parse_vc_compare_op, 6205 .comp = comp_set_compare_op, 6206 }, 6207 [ITEM_COMPARE_FIELD_A_TYPE] = { 6208 .name = "a_type", 6209 .help = "compared field type", 6210 .next = NEXT(compare_field_a, 6211 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param), 6212 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)), 6213 }, 6214 [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = { 6215 .name = "{a_type}", 6216 .help = "compared field type value", 6217 .call = parse_vc_compare_field_id, 6218 .comp = comp_set_compare_field_id, 6219 }, 6220 [ITEM_COMPARE_FIELD_A_LEVEL] = { 6221 .name = "a_level", 6222 .help = "compared field level", 6223 .next = NEXT(compare_field_a, 6224 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param), 6225 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)), 6226 }, 6227 [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = { 6228 .name = "{a_level}", 6229 .help = "compared field level value", 6230 .call = parse_vc_compare_field_level, 6231 .comp = comp_none, 6232 }, 6233 [ITEM_COMPARE_FIELD_A_TAG_INDEX] = { 6234 .name = "a_tag_index", 6235 .help = "compared field tag array", 6236 .next = NEXT(compare_field_a, 6237 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6238 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6239 a.tag_index)), 6240 }, 6241 [ITEM_COMPARE_FIELD_A_TYPE_ID] = { 6242 .name = "a_type_id", 6243 .help = "compared field type ID", 6244 .next = NEXT(compare_field_a, 6245 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6246 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6247 a.type)), 6248 }, 6249 [ITEM_COMPARE_FIELD_A_CLASS_ID] = { 6250 .name = "a_class", 6251 .help = "compared field class ID", 6252 .next = NEXT(compare_field_a, 6253 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6254 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6255 a.class_id)), 6256 }, 6257 [ITEM_COMPARE_FIELD_A_OFFSET] = { 6258 .name = "a_offset", 6259 .help = "compared field bit offset", 6260 .next = NEXT(compare_field_a, 6261 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6262 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6263 a.offset)), 6264 }, 6265 [ITEM_COMPARE_FIELD_B_TYPE] = { 6266 .name = "b_type", 6267 .help = "comparator field type", 6268 .next = NEXT(compare_field_b, 6269 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param), 6270 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6271 b.field)), 6272 }, 6273 [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = { 6274 .name = "{b_type}", 6275 .help = "comparator field type value", 6276 .call = parse_vc_compare_field_id, 6277 .comp = comp_set_compare_field_id, 6278 }, 6279 [ITEM_COMPARE_FIELD_B_LEVEL] = { 6280 .name = "b_level", 6281 .help = "comparator field level", 6282 .next = NEXT(compare_field_b, 6283 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param), 6284 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6285 b.level)), 6286 }, 6287 [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = { 6288 .name = "{b_level}", 6289 .help = "comparator field level value", 6290 .call = parse_vc_compare_field_level, 6291 .comp = comp_none, 6292 }, 6293 [ITEM_COMPARE_FIELD_B_TAG_INDEX] = { 6294 .name = "b_tag_index", 6295 .help = "comparator field tag array", 6296 .next = NEXT(compare_field_b, 6297 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6298 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6299 b.tag_index)), 6300 }, 6301 [ITEM_COMPARE_FIELD_B_TYPE_ID] = { 6302 .name = "b_type_id", 6303 .help = "comparator field type ID", 6304 .next = NEXT(compare_field_b, 6305 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6306 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6307 b.type)), 6308 }, 6309 [ITEM_COMPARE_FIELD_B_CLASS_ID] = { 6310 .name = "b_class", 6311 .help = "comparator field class ID", 6312 .next = NEXT(compare_field_b, 6313 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6314 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6315 b.class_id)), 6316 }, 6317 [ITEM_COMPARE_FIELD_B_OFFSET] = { 6318 .name = "b_offset", 6319 .help = "comparator field bit offset", 6320 .next = NEXT(compare_field_b, 6321 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6322 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6323 b.offset)), 6324 }, 6325 [ITEM_COMPARE_FIELD_B_VALUE] = { 6326 .name = "b_value", 6327 .help = "comparator immediate value", 6328 .next = NEXT(compare_field_b, 6329 NEXT_ENTRY(COMMON_HEX), item_param), 6330 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6331 ARGS_ENTRY_ARB(0, 0), 6332 ARGS_ENTRY(struct rte_flow_item_compare, 6333 b.value)), 6334 }, 6335 [ITEM_COMPARE_FIELD_B_POINTER] = { 6336 .name = "b_ptr", 6337 .help = "pointer to comparator immediate value", 6338 .next = NEXT(compare_field_b, 6339 NEXT_ENTRY(COMMON_HEX), item_param), 6340 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6341 b.pvalue), 6342 ARGS_ENTRY_ARB(0, 0), 6343 ARGS_ENTRY_ARB 6344 (sizeof(struct rte_flow_item_compare), 6345 FLOW_FIELD_PATTERN_SIZE)), 6346 }, 6347 [ITEM_COMPARE_FIELD_WIDTH] = { 6348 .name = "width", 6349 .help = "number of bits to compare", 6350 .next = NEXT(item_compare_field, 6351 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6352 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6353 width)), 6354 }, 6355 6356 /* Validate/create actions. */ 6357 [ACTIONS] = { 6358 .name = "actions", 6359 .help = "submit a list of associated actions", 6360 .next = NEXT(next_action), 6361 .call = parse_vc, 6362 }, 6363 [ACTION_NEXT] = { 6364 .name = "/", 6365 .help = "specify next action", 6366 .next = NEXT(next_action), 6367 }, 6368 [ACTION_END] = { 6369 .name = "end", 6370 .help = "end list of actions", 6371 .priv = PRIV_ACTION(END, 0), 6372 .call = parse_vc, 6373 }, 6374 [ACTION_VOID] = { 6375 .name = "void", 6376 .help = "no-op action", 6377 .priv = PRIV_ACTION(VOID, 0), 6378 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6379 .call = parse_vc, 6380 }, 6381 [ACTION_PASSTHRU] = { 6382 .name = "passthru", 6383 .help = "let subsequent rule process matched packets", 6384 .priv = PRIV_ACTION(PASSTHRU, 0), 6385 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6386 .call = parse_vc, 6387 }, 6388 [ACTION_SKIP_CMAN] = { 6389 .name = "skip_cman", 6390 .help = "bypass cman on received packets", 6391 .priv = PRIV_ACTION(SKIP_CMAN, 0), 6392 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6393 .call = parse_vc, 6394 }, 6395 [ACTION_JUMP] = { 6396 .name = "jump", 6397 .help = "redirect traffic to a given group", 6398 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 6399 .next = NEXT(action_jump), 6400 .call = parse_vc, 6401 }, 6402 [ACTION_JUMP_GROUP] = { 6403 .name = "group", 6404 .help = "group to redirect traffic to", 6405 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 6406 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 6407 .call = parse_vc_conf, 6408 }, 6409 [ACTION_MARK] = { 6410 .name = "mark", 6411 .help = "attach 32 bit value to packets", 6412 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 6413 .next = NEXT(action_mark), 6414 .call = parse_vc, 6415 }, 6416 [ACTION_MARK_ID] = { 6417 .name = "id", 6418 .help = "32 bit value to return with packets", 6419 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6420 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 6421 .call = parse_vc_conf, 6422 }, 6423 [ACTION_FLAG] = { 6424 .name = "flag", 6425 .help = "flag packets", 6426 .priv = PRIV_ACTION(FLAG, 0), 6427 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6428 .call = parse_vc, 6429 }, 6430 [ACTION_QUEUE] = { 6431 .name = "queue", 6432 .help = "assign packets to a given queue index", 6433 .priv = PRIV_ACTION(QUEUE, 6434 sizeof(struct rte_flow_action_queue)), 6435 .next = NEXT(action_queue), 6436 .call = parse_vc, 6437 }, 6438 [ACTION_QUEUE_INDEX] = { 6439 .name = "index", 6440 .help = "queue index to use", 6441 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 6442 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 6443 .call = parse_vc_conf, 6444 }, 6445 [ACTION_DROP] = { 6446 .name = "drop", 6447 .help = "drop packets (note: passthru has priority)", 6448 .priv = PRIV_ACTION(DROP, 0), 6449 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6450 .call = parse_vc, 6451 }, 6452 [ACTION_COUNT] = { 6453 .name = "count", 6454 .help = "enable counters for this rule", 6455 .priv = PRIV_ACTION(COUNT, 6456 sizeof(struct rte_flow_action_count)), 6457 .next = NEXT(action_count), 6458 .call = parse_vc, 6459 }, 6460 [ACTION_COUNT_ID] = { 6461 .name = "identifier", 6462 .help = "counter identifier to use", 6463 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 6464 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 6465 .call = parse_vc_conf, 6466 }, 6467 [ACTION_RSS] = { 6468 .name = "rss", 6469 .help = "spread packets among several queues", 6470 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 6471 .next = NEXT(action_rss), 6472 .call = parse_vc_action_rss, 6473 }, 6474 [ACTION_RSS_FUNC] = { 6475 .name = "func", 6476 .help = "RSS hash function to apply", 6477 .next = NEXT(action_rss, 6478 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 6479 ACTION_RSS_FUNC_TOEPLITZ, 6480 ACTION_RSS_FUNC_SIMPLE_XOR, 6481 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 6482 }, 6483 [ACTION_RSS_FUNC_DEFAULT] = { 6484 .name = "default", 6485 .help = "default hash function", 6486 .call = parse_vc_action_rss_func, 6487 }, 6488 [ACTION_RSS_FUNC_TOEPLITZ] = { 6489 .name = "toeplitz", 6490 .help = "Toeplitz hash function", 6491 .call = parse_vc_action_rss_func, 6492 }, 6493 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 6494 .name = "simple_xor", 6495 .help = "simple XOR hash function", 6496 .call = parse_vc_action_rss_func, 6497 }, 6498 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 6499 .name = "symmetric_toeplitz", 6500 .help = "Symmetric Toeplitz hash function", 6501 .call = parse_vc_action_rss_func, 6502 }, 6503 [ACTION_RSS_LEVEL] = { 6504 .name = "level", 6505 .help = "encapsulation level for \"types\"", 6506 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6507 .args = ARGS(ARGS_ENTRY_ARB 6508 (offsetof(struct action_rss_data, conf) + 6509 offsetof(struct rte_flow_action_rss, level), 6510 sizeof(((struct rte_flow_action_rss *)0)-> 6511 level))), 6512 }, 6513 [ACTION_RSS_TYPES] = { 6514 .name = "types", 6515 .help = "specific RSS hash types", 6516 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 6517 }, 6518 [ACTION_RSS_TYPE] = { 6519 .name = "{type}", 6520 .help = "RSS hash type", 6521 .call = parse_vc_action_rss_type, 6522 .comp = comp_vc_action_rss_type, 6523 }, 6524 [ACTION_RSS_KEY] = { 6525 .name = "key", 6526 .help = "RSS hash key", 6527 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 6528 .args = ARGS(ARGS_ENTRY_ARB 6529 (offsetof(struct action_rss_data, conf) + 6530 offsetof(struct rte_flow_action_rss, key), 6531 sizeof(((struct rte_flow_action_rss *)0)->key)), 6532 ARGS_ENTRY_ARB 6533 (offsetof(struct action_rss_data, conf) + 6534 offsetof(struct rte_flow_action_rss, key_len), 6535 sizeof(((struct rte_flow_action_rss *)0)-> 6536 key_len)), 6537 ARGS_ENTRY(struct action_rss_data, key)), 6538 }, 6539 [ACTION_RSS_KEY_LEN] = { 6540 .name = "key_len", 6541 .help = "RSS hash key length in bytes", 6542 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6543 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6544 (offsetof(struct action_rss_data, conf) + 6545 offsetof(struct rte_flow_action_rss, key_len), 6546 sizeof(((struct rte_flow_action_rss *)0)-> 6547 key_len), 6548 0, 6549 RSS_HASH_KEY_LENGTH)), 6550 }, 6551 [ACTION_RSS_QUEUES] = { 6552 .name = "queues", 6553 .help = "queue indices to use", 6554 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 6555 .call = parse_vc_conf, 6556 }, 6557 [ACTION_RSS_QUEUE] = { 6558 .name = "{queue}", 6559 .help = "queue index", 6560 .call = parse_vc_action_rss_queue, 6561 .comp = comp_vc_action_rss_queue, 6562 }, 6563 [ACTION_PF] = { 6564 .name = "pf", 6565 .help = "direct traffic to physical function", 6566 .priv = PRIV_ACTION(PF, 0), 6567 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6568 .call = parse_vc, 6569 }, 6570 [ACTION_VF] = { 6571 .name = "vf", 6572 .help = "direct traffic to a virtual function ID", 6573 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 6574 .next = NEXT(action_vf), 6575 .call = parse_vc, 6576 }, 6577 [ACTION_VF_ORIGINAL] = { 6578 .name = "original", 6579 .help = "use original VF ID if possible", 6580 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 6581 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 6582 original, 1)), 6583 .call = parse_vc_conf, 6584 }, 6585 [ACTION_VF_ID] = { 6586 .name = "id", 6587 .help = "VF ID", 6588 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 6589 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 6590 .call = parse_vc_conf, 6591 }, 6592 [ACTION_PORT_ID] = { 6593 .name = "port_id", 6594 .help = "direct matching traffic to a given DPDK port ID", 6595 .priv = PRIV_ACTION(PORT_ID, 6596 sizeof(struct rte_flow_action_port_id)), 6597 .next = NEXT(action_port_id), 6598 .call = parse_vc, 6599 }, 6600 [ACTION_PORT_ID_ORIGINAL] = { 6601 .name = "original", 6602 .help = "use original DPDK port ID if possible", 6603 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 6604 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 6605 original, 1)), 6606 .call = parse_vc_conf, 6607 }, 6608 [ACTION_PORT_ID_ID] = { 6609 .name = "id", 6610 .help = "DPDK port ID", 6611 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 6612 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 6613 .call = parse_vc_conf, 6614 }, 6615 [ACTION_METER] = { 6616 .name = "meter", 6617 .help = "meter the directed packets at given id", 6618 .priv = PRIV_ACTION(METER, 6619 sizeof(struct rte_flow_action_meter)), 6620 .next = NEXT(action_meter), 6621 .call = parse_vc, 6622 }, 6623 [ACTION_METER_COLOR] = { 6624 .name = "color", 6625 .help = "meter color for the packets", 6626 .priv = PRIV_ACTION(METER_COLOR, 6627 sizeof(struct rte_flow_action_meter_color)), 6628 .next = NEXT(action_meter_color), 6629 .call = parse_vc, 6630 }, 6631 [ACTION_METER_COLOR_TYPE] = { 6632 .name = "type", 6633 .help = "specific meter color", 6634 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6635 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 6636 ACTION_METER_COLOR_YELLOW, 6637 ACTION_METER_COLOR_RED)), 6638 }, 6639 [ACTION_METER_COLOR_GREEN] = { 6640 .name = "green", 6641 .help = "meter color green", 6642 .call = parse_vc_action_meter_color_type, 6643 }, 6644 [ACTION_METER_COLOR_YELLOW] = { 6645 .name = "yellow", 6646 .help = "meter color yellow", 6647 .call = parse_vc_action_meter_color_type, 6648 }, 6649 [ACTION_METER_COLOR_RED] = { 6650 .name = "red", 6651 .help = "meter color red", 6652 .call = parse_vc_action_meter_color_type, 6653 }, 6654 [ACTION_METER_ID] = { 6655 .name = "mtr_id", 6656 .help = "meter id to use", 6657 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 6658 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 6659 .call = parse_vc_conf, 6660 }, 6661 [ACTION_METER_MARK] = { 6662 .name = "meter_mark", 6663 .help = "meter the directed packets using profile and policy", 6664 .priv = PRIV_ACTION(METER_MARK, 6665 sizeof(struct rte_flow_action_meter_mark)), 6666 .next = NEXT(action_meter_mark), 6667 .call = parse_vc, 6668 }, 6669 [ACTION_METER_PROFILE] = { 6670 .name = "mtr_profile", 6671 .help = "meter profile id to use", 6672 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 6673 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6674 }, 6675 [ACTION_METER_PROFILE_ID2PTR] = { 6676 .name = "{mtr_profile_id}", 6677 .type = "PROFILE_ID", 6678 .help = "meter profile id", 6679 .next = NEXT(action_meter_mark), 6680 .call = parse_meter_profile_id2ptr, 6681 .comp = comp_none, 6682 }, 6683 [ACTION_METER_POLICY] = { 6684 .name = "mtr_policy", 6685 .help = "meter policy id to use", 6686 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 6687 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6688 }, 6689 [ACTION_METER_POLICY_ID2PTR] = { 6690 .name = "{mtr_policy_id}", 6691 .type = "POLICY_ID", 6692 .help = "meter policy id", 6693 .next = NEXT(action_meter_mark), 6694 .call = parse_meter_policy_id2ptr, 6695 .comp = comp_none, 6696 }, 6697 [ACTION_METER_COLOR_MODE] = { 6698 .name = "mtr_color_mode", 6699 .help = "meter color awareness mode", 6700 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6701 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 6702 .call = parse_vc_conf, 6703 }, 6704 [ACTION_METER_STATE] = { 6705 .name = "mtr_state", 6706 .help = "meter state", 6707 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6708 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 6709 .call = parse_vc_conf, 6710 }, 6711 [ACTION_OF_DEC_NW_TTL] = { 6712 .name = "of_dec_nw_ttl", 6713 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 6714 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 6715 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6716 .call = parse_vc, 6717 }, 6718 [ACTION_OF_POP_VLAN] = { 6719 .name = "of_pop_vlan", 6720 .help = "OpenFlow's OFPAT_POP_VLAN", 6721 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 6722 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6723 .call = parse_vc, 6724 }, 6725 [ACTION_OF_PUSH_VLAN] = { 6726 .name = "of_push_vlan", 6727 .help = "OpenFlow's OFPAT_PUSH_VLAN", 6728 .priv = PRIV_ACTION 6729 (OF_PUSH_VLAN, 6730 sizeof(struct rte_flow_action_of_push_vlan)), 6731 .next = NEXT(action_of_push_vlan), 6732 .call = parse_vc, 6733 }, 6734 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 6735 .name = "ethertype", 6736 .help = "EtherType", 6737 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 6738 .args = ARGS(ARGS_ENTRY_HTON 6739 (struct rte_flow_action_of_push_vlan, 6740 ethertype)), 6741 .call = parse_vc_conf, 6742 }, 6743 [ACTION_OF_SET_VLAN_VID] = { 6744 .name = "of_set_vlan_vid", 6745 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 6746 .priv = PRIV_ACTION 6747 (OF_SET_VLAN_VID, 6748 sizeof(struct rte_flow_action_of_set_vlan_vid)), 6749 .next = NEXT(action_of_set_vlan_vid), 6750 .call = parse_vc, 6751 }, 6752 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 6753 .name = "vlan_vid", 6754 .help = "VLAN id", 6755 .next = NEXT(action_of_set_vlan_vid, 6756 NEXT_ENTRY(COMMON_UNSIGNED)), 6757 .args = ARGS(ARGS_ENTRY_HTON 6758 (struct rte_flow_action_of_set_vlan_vid, 6759 vlan_vid)), 6760 .call = parse_vc_conf, 6761 }, 6762 [ACTION_OF_SET_VLAN_PCP] = { 6763 .name = "of_set_vlan_pcp", 6764 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 6765 .priv = PRIV_ACTION 6766 (OF_SET_VLAN_PCP, 6767 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 6768 .next = NEXT(action_of_set_vlan_pcp), 6769 .call = parse_vc, 6770 }, 6771 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 6772 .name = "vlan_pcp", 6773 .help = "VLAN priority", 6774 .next = NEXT(action_of_set_vlan_pcp, 6775 NEXT_ENTRY(COMMON_UNSIGNED)), 6776 .args = ARGS(ARGS_ENTRY_HTON 6777 (struct rte_flow_action_of_set_vlan_pcp, 6778 vlan_pcp)), 6779 .call = parse_vc_conf, 6780 }, 6781 [ACTION_OF_POP_MPLS] = { 6782 .name = "of_pop_mpls", 6783 .help = "OpenFlow's OFPAT_POP_MPLS", 6784 .priv = PRIV_ACTION(OF_POP_MPLS, 6785 sizeof(struct rte_flow_action_of_pop_mpls)), 6786 .next = NEXT(action_of_pop_mpls), 6787 .call = parse_vc, 6788 }, 6789 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 6790 .name = "ethertype", 6791 .help = "EtherType", 6792 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6793 .args = ARGS(ARGS_ENTRY_HTON 6794 (struct rte_flow_action_of_pop_mpls, 6795 ethertype)), 6796 .call = parse_vc_conf, 6797 }, 6798 [ACTION_OF_PUSH_MPLS] = { 6799 .name = "of_push_mpls", 6800 .help = "OpenFlow's OFPAT_PUSH_MPLS", 6801 .priv = PRIV_ACTION 6802 (OF_PUSH_MPLS, 6803 sizeof(struct rte_flow_action_of_push_mpls)), 6804 .next = NEXT(action_of_push_mpls), 6805 .call = parse_vc, 6806 }, 6807 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 6808 .name = "ethertype", 6809 .help = "EtherType", 6810 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6811 .args = ARGS(ARGS_ENTRY_HTON 6812 (struct rte_flow_action_of_push_mpls, 6813 ethertype)), 6814 .call = parse_vc_conf, 6815 }, 6816 [ACTION_VXLAN_ENCAP] = { 6817 .name = "vxlan_encap", 6818 .help = "VXLAN encapsulation, uses configuration set by \"set" 6819 " vxlan\"", 6820 .priv = PRIV_ACTION(VXLAN_ENCAP, 6821 sizeof(struct action_vxlan_encap_data)), 6822 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6823 .call = parse_vc_action_vxlan_encap, 6824 }, 6825 [ACTION_VXLAN_DECAP] = { 6826 .name = "vxlan_decap", 6827 .help = "Performs a decapsulation action by stripping all" 6828 " headers of the VXLAN tunnel network overlay from the" 6829 " matched flow.", 6830 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 6831 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6832 .call = parse_vc, 6833 }, 6834 [ACTION_NVGRE_ENCAP] = { 6835 .name = "nvgre_encap", 6836 .help = "NVGRE encapsulation, uses configuration set by \"set" 6837 " nvgre\"", 6838 .priv = PRIV_ACTION(NVGRE_ENCAP, 6839 sizeof(struct action_nvgre_encap_data)), 6840 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6841 .call = parse_vc_action_nvgre_encap, 6842 }, 6843 [ACTION_NVGRE_DECAP] = { 6844 .name = "nvgre_decap", 6845 .help = "Performs a decapsulation action by stripping all" 6846 " headers of the NVGRE tunnel network overlay from the" 6847 " matched flow.", 6848 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 6849 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6850 .call = parse_vc, 6851 }, 6852 [ACTION_L2_ENCAP] = { 6853 .name = "l2_encap", 6854 .help = "l2 encap, uses configuration set by" 6855 " \"set l2_encap\"", 6856 .priv = PRIV_ACTION(RAW_ENCAP, 6857 sizeof(struct action_raw_encap_data)), 6858 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6859 .call = parse_vc_action_l2_encap, 6860 }, 6861 [ACTION_L2_DECAP] = { 6862 .name = "l2_decap", 6863 .help = "l2 decap, uses configuration set by" 6864 " \"set l2_decap\"", 6865 .priv = PRIV_ACTION(RAW_DECAP, 6866 sizeof(struct action_raw_decap_data)), 6867 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6868 .call = parse_vc_action_l2_decap, 6869 }, 6870 [ACTION_MPLSOGRE_ENCAP] = { 6871 .name = "mplsogre_encap", 6872 .help = "mplsogre encapsulation, uses configuration set by" 6873 " \"set mplsogre_encap\"", 6874 .priv = PRIV_ACTION(RAW_ENCAP, 6875 sizeof(struct action_raw_encap_data)), 6876 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6877 .call = parse_vc_action_mplsogre_encap, 6878 }, 6879 [ACTION_MPLSOGRE_DECAP] = { 6880 .name = "mplsogre_decap", 6881 .help = "mplsogre decapsulation, uses configuration set by" 6882 " \"set mplsogre_decap\"", 6883 .priv = PRIV_ACTION(RAW_DECAP, 6884 sizeof(struct action_raw_decap_data)), 6885 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6886 .call = parse_vc_action_mplsogre_decap, 6887 }, 6888 [ACTION_MPLSOUDP_ENCAP] = { 6889 .name = "mplsoudp_encap", 6890 .help = "mplsoudp encapsulation, uses configuration set by" 6891 " \"set mplsoudp_encap\"", 6892 .priv = PRIV_ACTION(RAW_ENCAP, 6893 sizeof(struct action_raw_encap_data)), 6894 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6895 .call = parse_vc_action_mplsoudp_encap, 6896 }, 6897 [ACTION_MPLSOUDP_DECAP] = { 6898 .name = "mplsoudp_decap", 6899 .help = "mplsoudp decapsulation, uses configuration set by" 6900 " \"set mplsoudp_decap\"", 6901 .priv = PRIV_ACTION(RAW_DECAP, 6902 sizeof(struct action_raw_decap_data)), 6903 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6904 .call = parse_vc_action_mplsoudp_decap, 6905 }, 6906 [ACTION_SET_IPV4_SRC] = { 6907 .name = "set_ipv4_src", 6908 .help = "Set a new IPv4 source address in the outermost" 6909 " IPv4 header", 6910 .priv = PRIV_ACTION(SET_IPV4_SRC, 6911 sizeof(struct rte_flow_action_set_ipv4)), 6912 .next = NEXT(action_set_ipv4_src), 6913 .call = parse_vc, 6914 }, 6915 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 6916 .name = "ipv4_addr", 6917 .help = "new IPv4 source address to set", 6918 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 6919 .args = ARGS(ARGS_ENTRY_HTON 6920 (struct rte_flow_action_set_ipv4, ipv4_addr)), 6921 .call = parse_vc_conf, 6922 }, 6923 [ACTION_SET_IPV4_DST] = { 6924 .name = "set_ipv4_dst", 6925 .help = "Set a new IPv4 destination address in the outermost" 6926 " IPv4 header", 6927 .priv = PRIV_ACTION(SET_IPV4_DST, 6928 sizeof(struct rte_flow_action_set_ipv4)), 6929 .next = NEXT(action_set_ipv4_dst), 6930 .call = parse_vc, 6931 }, 6932 [ACTION_SET_IPV4_DST_IPV4_DST] = { 6933 .name = "ipv4_addr", 6934 .help = "new IPv4 destination address to set", 6935 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 6936 .args = ARGS(ARGS_ENTRY_HTON 6937 (struct rte_flow_action_set_ipv4, ipv4_addr)), 6938 .call = parse_vc_conf, 6939 }, 6940 [ACTION_SET_IPV6_SRC] = { 6941 .name = "set_ipv6_src", 6942 .help = "Set a new IPv6 source address in the outermost" 6943 " IPv6 header", 6944 .priv = PRIV_ACTION(SET_IPV6_SRC, 6945 sizeof(struct rte_flow_action_set_ipv6)), 6946 .next = NEXT(action_set_ipv6_src), 6947 .call = parse_vc, 6948 }, 6949 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 6950 .name = "ipv6_addr", 6951 .help = "new IPv6 source address to set", 6952 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 6953 .args = ARGS(ARGS_ENTRY_HTON 6954 (struct rte_flow_action_set_ipv6, ipv6_addr)), 6955 .call = parse_vc_conf, 6956 }, 6957 [ACTION_SET_IPV6_DST] = { 6958 .name = "set_ipv6_dst", 6959 .help = "Set a new IPv6 destination address in the outermost" 6960 " IPv6 header", 6961 .priv = PRIV_ACTION(SET_IPV6_DST, 6962 sizeof(struct rte_flow_action_set_ipv6)), 6963 .next = NEXT(action_set_ipv6_dst), 6964 .call = parse_vc, 6965 }, 6966 [ACTION_SET_IPV6_DST_IPV6_DST] = { 6967 .name = "ipv6_addr", 6968 .help = "new IPv6 destination address to set", 6969 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 6970 .args = ARGS(ARGS_ENTRY_HTON 6971 (struct rte_flow_action_set_ipv6, ipv6_addr)), 6972 .call = parse_vc_conf, 6973 }, 6974 [ACTION_SET_TP_SRC] = { 6975 .name = "set_tp_src", 6976 .help = "set a new source port number in the outermost" 6977 " TCP/UDP header", 6978 .priv = PRIV_ACTION(SET_TP_SRC, 6979 sizeof(struct rte_flow_action_set_tp)), 6980 .next = NEXT(action_set_tp_src), 6981 .call = parse_vc, 6982 }, 6983 [ACTION_SET_TP_SRC_TP_SRC] = { 6984 .name = "port", 6985 .help = "new source port number to set", 6986 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 6987 .args = ARGS(ARGS_ENTRY_HTON 6988 (struct rte_flow_action_set_tp, port)), 6989 .call = parse_vc_conf, 6990 }, 6991 [ACTION_SET_TP_DST] = { 6992 .name = "set_tp_dst", 6993 .help = "set a new destination port number in the outermost" 6994 " TCP/UDP header", 6995 .priv = PRIV_ACTION(SET_TP_DST, 6996 sizeof(struct rte_flow_action_set_tp)), 6997 .next = NEXT(action_set_tp_dst), 6998 .call = parse_vc, 6999 }, 7000 [ACTION_SET_TP_DST_TP_DST] = { 7001 .name = "port", 7002 .help = "new destination port number to set", 7003 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 7004 .args = ARGS(ARGS_ENTRY_HTON 7005 (struct rte_flow_action_set_tp, port)), 7006 .call = parse_vc_conf, 7007 }, 7008 [ACTION_MAC_SWAP] = { 7009 .name = "mac_swap", 7010 .help = "Swap the source and destination MAC addresses" 7011 " in the outermost Ethernet header", 7012 .priv = PRIV_ACTION(MAC_SWAP, 0), 7013 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7014 .call = parse_vc, 7015 }, 7016 [ACTION_DEC_TTL] = { 7017 .name = "dec_ttl", 7018 .help = "decrease network TTL if available", 7019 .priv = PRIV_ACTION(DEC_TTL, 0), 7020 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7021 .call = parse_vc, 7022 }, 7023 [ACTION_SET_TTL] = { 7024 .name = "set_ttl", 7025 .help = "set ttl value", 7026 .priv = PRIV_ACTION(SET_TTL, 7027 sizeof(struct rte_flow_action_set_ttl)), 7028 .next = NEXT(action_set_ttl), 7029 .call = parse_vc, 7030 }, 7031 [ACTION_SET_TTL_TTL] = { 7032 .name = "ttl_value", 7033 .help = "new ttl value to set", 7034 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 7035 .args = ARGS(ARGS_ENTRY_HTON 7036 (struct rte_flow_action_set_ttl, ttl_value)), 7037 .call = parse_vc_conf, 7038 }, 7039 [ACTION_SET_MAC_SRC] = { 7040 .name = "set_mac_src", 7041 .help = "set source mac address", 7042 .priv = PRIV_ACTION(SET_MAC_SRC, 7043 sizeof(struct rte_flow_action_set_mac)), 7044 .next = NEXT(action_set_mac_src), 7045 .call = parse_vc, 7046 }, 7047 [ACTION_SET_MAC_SRC_MAC_SRC] = { 7048 .name = "mac_addr", 7049 .help = "new source mac address", 7050 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 7051 .args = ARGS(ARGS_ENTRY_HTON 7052 (struct rte_flow_action_set_mac, mac_addr)), 7053 .call = parse_vc_conf, 7054 }, 7055 [ACTION_SET_MAC_DST] = { 7056 .name = "set_mac_dst", 7057 .help = "set destination mac address", 7058 .priv = PRIV_ACTION(SET_MAC_DST, 7059 sizeof(struct rte_flow_action_set_mac)), 7060 .next = NEXT(action_set_mac_dst), 7061 .call = parse_vc, 7062 }, 7063 [ACTION_SET_MAC_DST_MAC_DST] = { 7064 .name = "mac_addr", 7065 .help = "new destination mac address to set", 7066 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 7067 .args = ARGS(ARGS_ENTRY_HTON 7068 (struct rte_flow_action_set_mac, mac_addr)), 7069 .call = parse_vc_conf, 7070 }, 7071 [ACTION_INC_TCP_SEQ] = { 7072 .name = "inc_tcp_seq", 7073 .help = "increase TCP sequence number", 7074 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 7075 .next = NEXT(action_inc_tcp_seq), 7076 .call = parse_vc, 7077 }, 7078 [ACTION_INC_TCP_SEQ_VALUE] = { 7079 .name = "value", 7080 .help = "the value to increase TCP sequence number by", 7081 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7082 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7083 .call = parse_vc_conf, 7084 }, 7085 [ACTION_DEC_TCP_SEQ] = { 7086 .name = "dec_tcp_seq", 7087 .help = "decrease TCP sequence number", 7088 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 7089 .next = NEXT(action_dec_tcp_seq), 7090 .call = parse_vc, 7091 }, 7092 [ACTION_DEC_TCP_SEQ_VALUE] = { 7093 .name = "value", 7094 .help = "the value to decrease TCP sequence number by", 7095 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7096 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7097 .call = parse_vc_conf, 7098 }, 7099 [ACTION_INC_TCP_ACK] = { 7100 .name = "inc_tcp_ack", 7101 .help = "increase TCP acknowledgment number", 7102 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 7103 .next = NEXT(action_inc_tcp_ack), 7104 .call = parse_vc, 7105 }, 7106 [ACTION_INC_TCP_ACK_VALUE] = { 7107 .name = "value", 7108 .help = "the value to increase TCP acknowledgment number by", 7109 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7110 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7111 .call = parse_vc_conf, 7112 }, 7113 [ACTION_DEC_TCP_ACK] = { 7114 .name = "dec_tcp_ack", 7115 .help = "decrease TCP acknowledgment number", 7116 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 7117 .next = NEXT(action_dec_tcp_ack), 7118 .call = parse_vc, 7119 }, 7120 [ACTION_DEC_TCP_ACK_VALUE] = { 7121 .name = "value", 7122 .help = "the value to decrease TCP acknowledgment number by", 7123 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7124 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7125 .call = parse_vc_conf, 7126 }, 7127 [ACTION_RAW_ENCAP] = { 7128 .name = "raw_encap", 7129 .help = "encapsulation data, defined by set raw_encap", 7130 .priv = PRIV_ACTION(RAW_ENCAP, 7131 sizeof(struct action_raw_encap_data)), 7132 .next = NEXT(action_raw_encap), 7133 .call = parse_vc_action_raw_encap, 7134 }, 7135 [ACTION_RAW_ENCAP_SIZE] = { 7136 .name = "size", 7137 .help = "raw encap size", 7138 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7139 NEXT_ENTRY(COMMON_UNSIGNED)), 7140 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_raw_encap, size)), 7141 .call = parse_vc_conf, 7142 }, 7143 [ACTION_RAW_ENCAP_INDEX] = { 7144 .name = "index", 7145 .help = "the index of raw_encap_confs", 7146 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 7147 }, 7148 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 7149 .name = "{index}", 7150 .type = "UNSIGNED", 7151 .help = "unsigned integer value", 7152 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7153 .call = parse_vc_action_raw_encap_index, 7154 .comp = comp_set_raw_index, 7155 }, 7156 [ACTION_RAW_DECAP] = { 7157 .name = "raw_decap", 7158 .help = "decapsulation data, defined by set raw_encap", 7159 .priv = PRIV_ACTION(RAW_DECAP, 7160 sizeof(struct action_raw_decap_data)), 7161 .next = NEXT(action_raw_decap), 7162 .call = parse_vc_action_raw_decap, 7163 }, 7164 [ACTION_RAW_DECAP_INDEX] = { 7165 .name = "index", 7166 .help = "the index of raw_encap_confs", 7167 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 7168 }, 7169 [ACTION_RAW_DECAP_INDEX_VALUE] = { 7170 .name = "{index}", 7171 .type = "UNSIGNED", 7172 .help = "unsigned integer value", 7173 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7174 .call = parse_vc_action_raw_decap_index, 7175 .comp = comp_set_raw_index, 7176 }, 7177 [ACTION_MODIFY_FIELD] = { 7178 .name = "modify_field", 7179 .help = "modify destination field with data from source field", 7180 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 7181 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 7182 .call = parse_vc, 7183 }, 7184 [ACTION_MODIFY_FIELD_OP] = { 7185 .name = "op", 7186 .help = "operation type", 7187 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 7188 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 7189 .call = parse_vc_conf, 7190 }, 7191 [ACTION_MODIFY_FIELD_OP_VALUE] = { 7192 .name = "{operation}", 7193 .help = "operation type value", 7194 .call = parse_vc_modify_field_op, 7195 .comp = comp_set_modify_field_op, 7196 }, 7197 [ACTION_MODIFY_FIELD_DST_TYPE] = { 7198 .name = "dst_type", 7199 .help = "destination field type", 7200 .next = NEXT(action_modify_field_dst, 7201 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 7202 .call = parse_vc_conf, 7203 }, 7204 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 7205 .name = "{dst_type}", 7206 .help = "destination field type value", 7207 .call = parse_vc_modify_field_id, 7208 .comp = comp_set_modify_field_id, 7209 }, 7210 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 7211 .name = "dst_level", 7212 .help = "destination field level", 7213 .next = NEXT(action_modify_field_dst, 7214 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), 7215 .call = parse_vc_conf, 7216 }, 7217 [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { 7218 .name = "{dst_level}", 7219 .help = "destination field level value", 7220 .call = parse_vc_modify_field_level, 7221 .comp = comp_none, 7222 }, 7223 [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { 7224 .name = "dst_tag_index", 7225 .help = "destination field tag array", 7226 .next = NEXT(action_modify_field_dst, 7227 NEXT_ENTRY(COMMON_UNSIGNED)), 7228 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7229 dst.tag_index)), 7230 .call = parse_vc_conf, 7231 }, 7232 [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { 7233 .name = "dst_type_id", 7234 .help = "destination field type ID", 7235 .next = NEXT(action_modify_field_dst, 7236 NEXT_ENTRY(COMMON_UNSIGNED)), 7237 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7238 dst.type)), 7239 .call = parse_vc_conf, 7240 }, 7241 [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { 7242 .name = "dst_class", 7243 .help = "destination field class ID", 7244 .next = NEXT(action_modify_field_dst, 7245 NEXT_ENTRY(COMMON_UNSIGNED)), 7246 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7247 dst.class_id)), 7248 .call = parse_vc_conf, 7249 }, 7250 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 7251 .name = "dst_offset", 7252 .help = "destination field bit offset", 7253 .next = NEXT(action_modify_field_dst, 7254 NEXT_ENTRY(COMMON_UNSIGNED)), 7255 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7256 dst.offset)), 7257 .call = parse_vc_conf, 7258 }, 7259 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 7260 .name = "src_type", 7261 .help = "source field type", 7262 .next = NEXT(action_modify_field_src, 7263 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 7264 .call = parse_vc_conf, 7265 }, 7266 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 7267 .name = "{src_type}", 7268 .help = "source field type value", 7269 .call = parse_vc_modify_field_id, 7270 .comp = comp_set_modify_field_id, 7271 }, 7272 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 7273 .name = "src_level", 7274 .help = "source field level", 7275 .next = NEXT(action_modify_field_src, 7276 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), 7277 .call = parse_vc_conf, 7278 }, 7279 [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { 7280 .name = "{src_level}", 7281 .help = "source field level value", 7282 .call = parse_vc_modify_field_level, 7283 .comp = comp_none, 7284 }, 7285 [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { 7286 .name = "stc_tag_index", 7287 .help = "source field tag array", 7288 .next = NEXT(action_modify_field_src, 7289 NEXT_ENTRY(COMMON_UNSIGNED)), 7290 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7291 src.tag_index)), 7292 .call = parse_vc_conf, 7293 }, 7294 [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { 7295 .name = "src_type_id", 7296 .help = "source field type ID", 7297 .next = NEXT(action_modify_field_src, 7298 NEXT_ENTRY(COMMON_UNSIGNED)), 7299 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7300 src.type)), 7301 .call = parse_vc_conf, 7302 }, 7303 [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { 7304 .name = "src_class", 7305 .help = "source field class ID", 7306 .next = NEXT(action_modify_field_src, 7307 NEXT_ENTRY(COMMON_UNSIGNED)), 7308 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7309 src.class_id)), 7310 .call = parse_vc_conf, 7311 }, 7312 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 7313 .name = "src_offset", 7314 .help = "source field bit offset", 7315 .next = NEXT(action_modify_field_src, 7316 NEXT_ENTRY(COMMON_UNSIGNED)), 7317 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7318 src.offset)), 7319 .call = parse_vc_conf, 7320 }, 7321 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 7322 .name = "src_value", 7323 .help = "source immediate value", 7324 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7325 NEXT_ENTRY(COMMON_HEX)), 7326 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 7327 ARGS_ENTRY_ARB(0, 0), 7328 ARGS_ENTRY(struct rte_flow_action_modify_field, 7329 src.value)), 7330 .call = parse_vc_conf, 7331 }, 7332 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 7333 .name = "src_ptr", 7334 .help = "pointer to source immediate value", 7335 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7336 NEXT_ENTRY(COMMON_HEX)), 7337 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7338 src.pvalue), 7339 ARGS_ENTRY_ARB(0, 0), 7340 ARGS_ENTRY_ARB 7341 (sizeof(struct rte_flow_action_modify_field), 7342 FLOW_FIELD_PATTERN_SIZE)), 7343 .call = parse_vc_conf, 7344 }, 7345 [ACTION_MODIFY_FIELD_WIDTH] = { 7346 .name = "width", 7347 .help = "number of bits to copy", 7348 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7349 NEXT_ENTRY(COMMON_UNSIGNED)), 7350 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7351 width)), 7352 .call = parse_vc_conf, 7353 }, 7354 [ACTION_SEND_TO_KERNEL] = { 7355 .name = "send_to_kernel", 7356 .help = "send packets to kernel", 7357 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 7358 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7359 .call = parse_vc, 7360 }, 7361 [ACTION_IPV6_EXT_REMOVE] = { 7362 .name = "ipv6_ext_remove", 7363 .help = "IPv6 extension type, defined by set ipv6_ext_remove", 7364 .priv = PRIV_ACTION(IPV6_EXT_REMOVE, 7365 sizeof(struct action_ipv6_ext_remove_data)), 7366 .next = NEXT(action_ipv6_ext_remove), 7367 .call = parse_vc_action_ipv6_ext_remove, 7368 }, 7369 [ACTION_IPV6_EXT_REMOVE_INDEX] = { 7370 .name = "index", 7371 .help = "the index of ipv6_ext_remove", 7372 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), 7373 }, 7374 [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { 7375 .name = "{index}", 7376 .type = "UNSIGNED", 7377 .help = "unsigned integer value", 7378 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7379 .call = parse_vc_action_ipv6_ext_remove_index, 7380 .comp = comp_set_ipv6_ext_index, 7381 }, 7382 [ACTION_IPV6_EXT_PUSH] = { 7383 .name = "ipv6_ext_push", 7384 .help = "IPv6 extension data, defined by set ipv6_ext_push", 7385 .priv = PRIV_ACTION(IPV6_EXT_PUSH, 7386 sizeof(struct action_ipv6_ext_push_data)), 7387 .next = NEXT(action_ipv6_ext_push), 7388 .call = parse_vc_action_ipv6_ext_push, 7389 }, 7390 [ACTION_IPV6_EXT_PUSH_INDEX] = { 7391 .name = "index", 7392 .help = "the index of ipv6_ext_push", 7393 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), 7394 }, 7395 [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { 7396 .name = "{index}", 7397 .type = "UNSIGNED", 7398 .help = "unsigned integer value", 7399 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7400 .call = parse_vc_action_ipv6_ext_push_index, 7401 .comp = comp_set_ipv6_ext_index, 7402 }, 7403 [ACTION_NAT64] = { 7404 .name = "nat64", 7405 .help = "NAT64 IP headers translation", 7406 .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), 7407 .next = NEXT(action_nat64), 7408 .call = parse_vc, 7409 }, 7410 [ACTION_NAT64_MODE] = { 7411 .name = "type", 7412 .help = "NAT64 translation type", 7413 .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), 7414 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), 7415 .call = parse_vc_conf, 7416 }, 7417 /* Top level command. */ 7418 [SET] = { 7419 .name = "set", 7420 .help = "set raw encap/decap/sample data", 7421 .type = "set raw_encap|raw_decap <index> <pattern>" 7422 " or set sample_actions <index> <action>", 7423 .next = NEXT(NEXT_ENTRY 7424 (SET_RAW_ENCAP, 7425 SET_RAW_DECAP, 7426 SET_SAMPLE_ACTIONS, 7427 SET_IPV6_EXT_REMOVE, 7428 SET_IPV6_EXT_PUSH)), 7429 .call = parse_set_init, 7430 }, 7431 /* Sub-level commands. */ 7432 [SET_RAW_ENCAP] = { 7433 .name = "raw_encap", 7434 .help = "set raw encap data", 7435 .next = NEXT(next_set_raw), 7436 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7437 (offsetof(struct buffer, port), 7438 sizeof(((struct buffer *)0)->port), 7439 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7440 .call = parse_set_raw_encap_decap, 7441 }, 7442 [SET_RAW_DECAP] = { 7443 .name = "raw_decap", 7444 .help = "set raw decap data", 7445 .next = NEXT(next_set_raw), 7446 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7447 (offsetof(struct buffer, port), 7448 sizeof(((struct buffer *)0)->port), 7449 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7450 .call = parse_set_raw_encap_decap, 7451 }, 7452 [SET_RAW_INDEX] = { 7453 .name = "{index}", 7454 .type = "COMMON_UNSIGNED", 7455 .help = "index of raw_encap/raw_decap data", 7456 .next = NEXT(next_item), 7457 .call = parse_port, 7458 }, 7459 [SET_SAMPLE_INDEX] = { 7460 .name = "{index}", 7461 .type = "UNSIGNED", 7462 .help = "index of sample actions", 7463 .next = NEXT(next_action_sample), 7464 .call = parse_port, 7465 }, 7466 [SET_SAMPLE_ACTIONS] = { 7467 .name = "sample_actions", 7468 .help = "set sample actions list", 7469 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 7470 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7471 (offsetof(struct buffer, port), 7472 sizeof(((struct buffer *)0)->port), 7473 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 7474 .call = parse_set_sample_action, 7475 }, 7476 [SET_IPV6_EXT_PUSH] = { 7477 .name = "ipv6_ext_push", 7478 .help = "set IPv6 extension header", 7479 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7480 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7481 (offsetof(struct buffer, port), 7482 sizeof(((struct buffer *)0)->port), 7483 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7484 .call = parse_set_ipv6_ext_action, 7485 }, 7486 [SET_IPV6_EXT_REMOVE] = { 7487 .name = "ipv6_ext_remove", 7488 .help = "set IPv6 extension header", 7489 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7490 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7491 (offsetof(struct buffer, port), 7492 sizeof(((struct buffer *)0)->port), 7493 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7494 .call = parse_set_ipv6_ext_action, 7495 }, 7496 [SET_IPV6_EXT_INDEX] = { 7497 .name = "{index}", 7498 .type = "UNSIGNED", 7499 .help = "index of ipv6 extension push/remove actions", 7500 .next = NEXT(item_ipv6_push_ext), 7501 .call = parse_port, 7502 }, 7503 [ITEM_IPV6_PUSH_REMOVE_EXT] = { 7504 .name = "ipv6_ext", 7505 .help = "set IPv6 extension header", 7506 .priv = PRIV_ITEM(IPV6_EXT, 7507 sizeof(struct rte_flow_item_ipv6_ext)), 7508 .next = NEXT(item_ipv6_push_ext_type), 7509 .call = parse_vc, 7510 }, 7511 [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { 7512 .name = "type", 7513 .help = "set IPv6 extension type", 7514 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 7515 next_hdr)), 7516 .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), 7517 item_param), 7518 }, 7519 [ACTION_SET_TAG] = { 7520 .name = "set_tag", 7521 .help = "set tag", 7522 .priv = PRIV_ACTION(SET_TAG, 7523 sizeof(struct rte_flow_action_set_tag)), 7524 .next = NEXT(action_set_tag), 7525 .call = parse_vc, 7526 }, 7527 [ACTION_SET_TAG_INDEX] = { 7528 .name = "index", 7529 .help = "index of tag array", 7530 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7531 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 7532 .call = parse_vc_conf, 7533 }, 7534 [ACTION_SET_TAG_DATA] = { 7535 .name = "data", 7536 .help = "tag value", 7537 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7538 .args = ARGS(ARGS_ENTRY 7539 (struct rte_flow_action_set_tag, data)), 7540 .call = parse_vc_conf, 7541 }, 7542 [ACTION_SET_TAG_MASK] = { 7543 .name = "mask", 7544 .help = "mask for tag value", 7545 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7546 .args = ARGS(ARGS_ENTRY 7547 (struct rte_flow_action_set_tag, mask)), 7548 .call = parse_vc_conf, 7549 }, 7550 [ACTION_SET_META] = { 7551 .name = "set_meta", 7552 .help = "set metadata", 7553 .priv = PRIV_ACTION(SET_META, 7554 sizeof(struct rte_flow_action_set_meta)), 7555 .next = NEXT(action_set_meta), 7556 .call = parse_vc_action_set_meta, 7557 }, 7558 [ACTION_SET_META_DATA] = { 7559 .name = "data", 7560 .help = "metadata value", 7561 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7562 .args = ARGS(ARGS_ENTRY 7563 (struct rte_flow_action_set_meta, data)), 7564 .call = parse_vc_conf, 7565 }, 7566 [ACTION_SET_META_MASK] = { 7567 .name = "mask", 7568 .help = "mask for metadata value", 7569 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7570 .args = ARGS(ARGS_ENTRY 7571 (struct rte_flow_action_set_meta, mask)), 7572 .call = parse_vc_conf, 7573 }, 7574 [ACTION_SET_IPV4_DSCP] = { 7575 .name = "set_ipv4_dscp", 7576 .help = "set DSCP value", 7577 .priv = PRIV_ACTION(SET_IPV4_DSCP, 7578 sizeof(struct rte_flow_action_set_dscp)), 7579 .next = NEXT(action_set_ipv4_dscp), 7580 .call = parse_vc, 7581 }, 7582 [ACTION_SET_IPV4_DSCP_VALUE] = { 7583 .name = "dscp_value", 7584 .help = "new IPv4 DSCP value to set", 7585 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7586 .args = ARGS(ARGS_ENTRY 7587 (struct rte_flow_action_set_dscp, dscp)), 7588 .call = parse_vc_conf, 7589 }, 7590 [ACTION_SET_IPV6_DSCP] = { 7591 .name = "set_ipv6_dscp", 7592 .help = "set DSCP value", 7593 .priv = PRIV_ACTION(SET_IPV6_DSCP, 7594 sizeof(struct rte_flow_action_set_dscp)), 7595 .next = NEXT(action_set_ipv6_dscp), 7596 .call = parse_vc, 7597 }, 7598 [ACTION_SET_IPV6_DSCP_VALUE] = { 7599 .name = "dscp_value", 7600 .help = "new IPv6 DSCP value to set", 7601 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7602 .args = ARGS(ARGS_ENTRY 7603 (struct rte_flow_action_set_dscp, dscp)), 7604 .call = parse_vc_conf, 7605 }, 7606 [ACTION_AGE] = { 7607 .name = "age", 7608 .help = "set a specific metadata header", 7609 .next = NEXT(action_age), 7610 .priv = PRIV_ACTION(AGE, 7611 sizeof(struct rte_flow_action_age)), 7612 .call = parse_vc, 7613 }, 7614 [ACTION_AGE_TIMEOUT] = { 7615 .name = "timeout", 7616 .help = "flow age timeout value", 7617 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 7618 timeout, 24)), 7619 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 7620 .call = parse_vc_conf, 7621 }, 7622 [ACTION_AGE_UPDATE] = { 7623 .name = "age_update", 7624 .help = "update aging parameter", 7625 .next = NEXT(action_age_update), 7626 .priv = PRIV_ACTION(AGE, 7627 sizeof(struct rte_flow_update_age)), 7628 .call = parse_vc, 7629 }, 7630 [ACTION_AGE_UPDATE_TIMEOUT] = { 7631 .name = "timeout", 7632 .help = "age timeout update value", 7633 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7634 timeout, 24)), 7635 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7636 .call = parse_vc_conf_timeout, 7637 }, 7638 [ACTION_AGE_UPDATE_TOUCH] = { 7639 .name = "touch", 7640 .help = "this flow is touched", 7641 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), 7642 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7643 touch, 1)), 7644 .call = parse_vc_conf, 7645 }, 7646 [ACTION_SAMPLE] = { 7647 .name = "sample", 7648 .help = "set a sample action", 7649 .next = NEXT(action_sample), 7650 .priv = PRIV_ACTION(SAMPLE, 7651 sizeof(struct action_sample_data)), 7652 .call = parse_vc_action_sample, 7653 }, 7654 [ACTION_SAMPLE_RATIO] = { 7655 .name = "ratio", 7656 .help = "flow sample ratio value", 7657 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 7658 .args = ARGS(ARGS_ENTRY_ARB 7659 (offsetof(struct action_sample_data, conf) + 7660 offsetof(struct rte_flow_action_sample, ratio), 7661 sizeof(((struct rte_flow_action_sample *)0)-> 7662 ratio))), 7663 }, 7664 [ACTION_SAMPLE_INDEX] = { 7665 .name = "index", 7666 .help = "the index of sample actions list", 7667 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 7668 }, 7669 [ACTION_SAMPLE_INDEX_VALUE] = { 7670 .name = "{index}", 7671 .type = "COMMON_UNSIGNED", 7672 .help = "unsigned integer value", 7673 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7674 .call = parse_vc_action_sample_index, 7675 .comp = comp_set_sample_index, 7676 }, 7677 [ACTION_CONNTRACK] = { 7678 .name = "conntrack", 7679 .help = "create a conntrack object", 7680 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7681 .priv = PRIV_ACTION(CONNTRACK, 7682 sizeof(struct rte_flow_action_conntrack)), 7683 .call = parse_vc, 7684 }, 7685 [ACTION_CONNTRACK_UPDATE] = { 7686 .name = "conntrack_update", 7687 .help = "update a conntrack object", 7688 .next = NEXT(action_update_conntrack), 7689 .priv = PRIV_ACTION(CONNTRACK, 7690 sizeof(struct rte_flow_modify_conntrack)), 7691 .call = parse_vc, 7692 }, 7693 [ACTION_CONNTRACK_UPDATE_DIR] = { 7694 .name = "dir", 7695 .help = "update a conntrack object direction", 7696 .next = NEXT(action_update_conntrack), 7697 .call = parse_vc_action_conntrack_update, 7698 }, 7699 [ACTION_CONNTRACK_UPDATE_CTX] = { 7700 .name = "ctx", 7701 .help = "update a conntrack object context", 7702 .next = NEXT(action_update_conntrack), 7703 .call = parse_vc_action_conntrack_update, 7704 }, 7705 [ACTION_PORT_REPRESENTOR] = { 7706 .name = "port_representor", 7707 .help = "at embedded switch level, send matching traffic to the given ethdev", 7708 .priv = PRIV_ACTION(PORT_REPRESENTOR, 7709 sizeof(struct rte_flow_action_ethdev)), 7710 .next = NEXT(action_port_representor), 7711 .call = parse_vc, 7712 }, 7713 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 7714 .name = "port_id", 7715 .help = "ethdev port ID", 7716 .next = NEXT(action_port_representor, 7717 NEXT_ENTRY(COMMON_UNSIGNED)), 7718 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7719 port_id)), 7720 .call = parse_vc_conf, 7721 }, 7722 [ACTION_REPRESENTED_PORT] = { 7723 .name = "represented_port", 7724 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 7725 .priv = PRIV_ACTION(REPRESENTED_PORT, 7726 sizeof(struct rte_flow_action_ethdev)), 7727 .next = NEXT(action_represented_port), 7728 .call = parse_vc, 7729 }, 7730 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 7731 .name = "ethdev_port_id", 7732 .help = "ethdev port ID", 7733 .next = NEXT(action_represented_port, 7734 NEXT_ENTRY(COMMON_UNSIGNED)), 7735 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7736 port_id)), 7737 .call = parse_vc_conf, 7738 }, 7739 /* Indirect action destroy arguments. */ 7740 [INDIRECT_ACTION_DESTROY_ID] = { 7741 .name = "action_id", 7742 .help = "specify a indirect action id to destroy", 7743 .next = NEXT(next_ia_destroy_attr, 7744 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7745 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 7746 args.ia_destroy.action_id)), 7747 .call = parse_ia_destroy, 7748 }, 7749 /* Indirect action create arguments. */ 7750 [INDIRECT_ACTION_CREATE_ID] = { 7751 .name = "action_id", 7752 .help = "specify a indirect action id to create", 7753 .next = NEXT(next_ia_create_attr, 7754 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7755 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 7756 }, 7757 [ACTION_INDIRECT] = { 7758 .name = "indirect", 7759 .help = "apply indirect action by id", 7760 .priv = PRIV_ACTION(INDIRECT, 0), 7761 .next = NEXT(next_ia), 7762 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7763 .call = parse_vc, 7764 }, 7765 [ACTION_INDIRECT_LIST] = { 7766 .name = "indirect_list", 7767 .help = "apply indirect list action by id", 7768 .priv = PRIV_ACTION(INDIRECT_LIST, 7769 sizeof(struct 7770 rte_flow_action_indirect_list)), 7771 .next = NEXT(next_ial), 7772 .call = parse_vc, 7773 }, 7774 [ACTION_INDIRECT_LIST_HANDLE] = { 7775 .name = "handle", 7776 .help = "indirect list handle", 7777 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), 7778 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7779 }, 7780 [ACTION_INDIRECT_LIST_CONF] = { 7781 .name = "conf", 7782 .help = "indirect list configuration", 7783 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), 7784 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7785 }, 7786 [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { 7787 .type = "UNSIGNED", 7788 .help = "unsigned integer value", 7789 .call = parse_indlst_id2ptr, 7790 }, 7791 [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { 7792 .type = "UNSIGNED", 7793 .help = "unsigned integer value", 7794 .call = parse_indlst_id2ptr, 7795 }, 7796 [ACTION_SHARED_INDIRECT] = { 7797 .name = "shared_indirect", 7798 .help = "apply indirect action by id and port", 7799 .priv = PRIV_ACTION(INDIRECT, 0), 7800 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), 7801 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), 7802 ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7803 .call = parse_vc, 7804 }, 7805 [INDIRECT_ACTION_PORT] = { 7806 .name = "{indirect_action_port}", 7807 .type = "INDIRECT_ACTION_PORT", 7808 .help = "indirect action port", 7809 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 7810 .call = parse_ia_port, 7811 .comp = comp_none, 7812 }, 7813 [INDIRECT_ACTION_ID2PTR] = { 7814 .name = "{action_id}", 7815 .type = "INDIRECT_ACTION_ID", 7816 .help = "indirect action id", 7817 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7818 .call = parse_ia_id2ptr, 7819 .comp = comp_none, 7820 }, 7821 [INDIRECT_ACTION_INGRESS] = { 7822 .name = "ingress", 7823 .help = "affect rule to ingress", 7824 .next = NEXT(next_ia_create_attr), 7825 .call = parse_ia, 7826 }, 7827 [INDIRECT_ACTION_EGRESS] = { 7828 .name = "egress", 7829 .help = "affect rule to egress", 7830 .next = NEXT(next_ia_create_attr), 7831 .call = parse_ia, 7832 }, 7833 [INDIRECT_ACTION_TRANSFER] = { 7834 .name = "transfer", 7835 .help = "affect rule to transfer", 7836 .next = NEXT(next_ia_create_attr), 7837 .call = parse_ia, 7838 }, 7839 [INDIRECT_ACTION_SPEC] = { 7840 .name = "action", 7841 .help = "specify action to create indirect handle", 7842 .next = NEXT(next_action), 7843 }, 7844 [INDIRECT_ACTION_LIST] = { 7845 .name = "list", 7846 .help = "specify actions for indirect handle list", 7847 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7848 .call = parse_ia, 7849 }, 7850 [INDIRECT_ACTION_FLOW_CONF] = { 7851 .name = "flow_conf", 7852 .help = "specify actions configuration for indirect handle list", 7853 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7854 .call = parse_ia, 7855 }, 7856 [ACTION_POL_G] = { 7857 .name = "g_actions", 7858 .help = "submit a list of associated actions for green", 7859 .next = NEXT(next_action), 7860 .call = parse_mp, 7861 }, 7862 [ACTION_POL_Y] = { 7863 .name = "y_actions", 7864 .help = "submit a list of associated actions for yellow", 7865 .next = NEXT(next_action), 7866 }, 7867 [ACTION_POL_R] = { 7868 .name = "r_actions", 7869 .help = "submit a list of associated actions for red", 7870 .next = NEXT(next_action), 7871 }, 7872 [ACTION_QUOTA_CREATE] = { 7873 .name = "quota_create", 7874 .help = "create quota action", 7875 .priv = PRIV_ACTION(QUOTA, 7876 sizeof(struct rte_flow_action_quota)), 7877 .next = NEXT(action_quota_create), 7878 .call = parse_vc 7879 }, 7880 [ACTION_QUOTA_CREATE_LIMIT] = { 7881 .name = "limit", 7882 .help = "quota limit", 7883 .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), 7884 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), 7885 .call = parse_vc_conf 7886 }, 7887 [ACTION_QUOTA_CREATE_MODE] = { 7888 .name = "mode", 7889 .help = "quota mode", 7890 .next = NEXT(action_quota_create, 7891 NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), 7892 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), 7893 .call = parse_vc_conf 7894 }, 7895 [ACTION_QUOTA_CREATE_MODE_NAME] = { 7896 .name = "mode_name", 7897 .help = "quota mode name", 7898 .call = parse_quota_mode_name, 7899 .comp = comp_quota_mode_name 7900 }, 7901 [ACTION_QUOTA_QU] = { 7902 .name = "quota_update", 7903 .help = "update quota action", 7904 .priv = PRIV_ACTION(QUOTA, 7905 sizeof(struct rte_flow_update_quota)), 7906 .next = NEXT(action_quota_update), 7907 .call = parse_vc 7908 }, 7909 [ACTION_QUOTA_QU_LIMIT] = { 7910 .name = "limit", 7911 .help = "quota limit", 7912 .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7913 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), 7914 .call = parse_vc_conf 7915 }, 7916 [ACTION_QUOTA_QU_UPDATE_OP] = { 7917 .name = "update_op", 7918 .help = "query update op SET|ADD", 7919 .next = NEXT(action_quota_update, 7920 NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), 7921 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), 7922 .call = parse_vc_conf 7923 }, 7924 [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { 7925 .name = "update_op_name", 7926 .help = "quota update op name", 7927 .call = parse_quota_update_name, 7928 .comp = comp_quota_update_name 7929 }, 7930 7931 /* Top-level command. */ 7932 [ADD] = { 7933 .name = "add", 7934 .type = "port meter policy {port_id} {arg}", 7935 .help = "add port meter policy", 7936 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 7937 .call = parse_init, 7938 }, 7939 /* Sub-level commands. */ 7940 [ITEM_POL_PORT] = { 7941 .name = "port", 7942 .help = "add port meter policy", 7943 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 7944 }, 7945 [ITEM_POL_METER] = { 7946 .name = "meter", 7947 .help = "add port meter policy", 7948 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 7949 }, 7950 [ITEM_POL_POLICY] = { 7951 .name = "policy", 7952 .help = "add port meter policy", 7953 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 7954 NEXT_ENTRY(ACTION_POL_Y), 7955 NEXT_ENTRY(ACTION_POL_G), 7956 NEXT_ENTRY(COMMON_POLICY_ID), 7957 NEXT_ENTRY(COMMON_PORT_ID)), 7958 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 7959 ARGS_ENTRY(struct buffer, port)), 7960 .call = parse_mp, 7961 }, 7962 [ITEM_AGGR_AFFINITY] = { 7963 .name = "aggr_affinity", 7964 .help = "match on the aggregated port receiving the packets", 7965 .priv = PRIV_ITEM(AGGR_AFFINITY, 7966 sizeof(struct rte_flow_item_aggr_affinity)), 7967 .next = NEXT(item_aggr_affinity), 7968 .call = parse_vc, 7969 }, 7970 [ITEM_AGGR_AFFINITY_VALUE] = { 7971 .name = "affinity", 7972 .help = "aggregated affinity value", 7973 .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), 7974 item_param), 7975 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, 7976 affinity)), 7977 }, 7978 [ITEM_TX_QUEUE] = { 7979 .name = "tx_queue", 7980 .help = "match on the tx queue of send packet", 7981 .priv = PRIV_ITEM(TX_QUEUE, 7982 sizeof(struct rte_flow_item_tx_queue)), 7983 .next = NEXT(item_tx_queue), 7984 .call = parse_vc, 7985 }, 7986 [ITEM_TX_QUEUE_VALUE] = { 7987 .name = "tx_queue_value", 7988 .help = "tx queue value", 7989 .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), 7990 item_param), 7991 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, 7992 tx_queue)), 7993 }, 7994 }; 7995 7996 /** Remove and return last entry from argument stack. */ 7997 static const struct arg * 7998 pop_args(struct context *ctx) 7999 { 8000 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 8001 } 8002 8003 /** Add entry on top of the argument stack. */ 8004 static int 8005 push_args(struct context *ctx, const struct arg *arg) 8006 { 8007 if (ctx->args_num == CTX_STACK_SIZE) 8008 return -1; 8009 ctx->args[ctx->args_num++] = arg; 8010 return 0; 8011 } 8012 8013 /** Spread value into buffer according to bit-mask. */ 8014 static size_t 8015 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 8016 { 8017 uint32_t i = arg->size; 8018 uint32_t end = 0; 8019 int sub = 1; 8020 int add = 0; 8021 size_t len = 0; 8022 8023 if (!arg->mask) 8024 return 0; 8025 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8026 if (!arg->hton) { 8027 i = 0; 8028 end = arg->size; 8029 sub = 0; 8030 add = 1; 8031 } 8032 #endif 8033 while (i != end) { 8034 unsigned int shift = 0; 8035 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 8036 8037 for (shift = 0; arg->mask[i] >> shift; ++shift) { 8038 if (!(arg->mask[i] & (1 << shift))) 8039 continue; 8040 ++len; 8041 if (!dst) 8042 continue; 8043 *buf &= ~(1 << shift); 8044 *buf |= (val & 1) << shift; 8045 val >>= 1; 8046 } 8047 i += add; 8048 } 8049 return len; 8050 } 8051 8052 /** Compare a string with a partial one of a given length. */ 8053 static int 8054 strcmp_partial(const char *full, const char *partial, size_t partial_len) 8055 { 8056 int r = strncmp(full, partial, partial_len); 8057 8058 if (r) 8059 return r; 8060 if (strlen(full) <= partial_len) 8061 return 0; 8062 return full[partial_len]; 8063 } 8064 8065 /** 8066 * Parse a prefix length and generate a bit-mask. 8067 * 8068 * Last argument (ctx->args) is retrieved to determine mask size, storage 8069 * location and whether the result must use network byte ordering. 8070 */ 8071 static int 8072 parse_prefix(struct context *ctx, const struct token *token, 8073 const char *str, unsigned int len, 8074 void *buf, unsigned int size) 8075 { 8076 const struct arg *arg = pop_args(ctx); 8077 static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff"; 8078 char *end; 8079 uintmax_t u; 8080 unsigned int bytes; 8081 unsigned int extra; 8082 8083 (void)token; 8084 /* Argument is expected. */ 8085 if (!arg) 8086 return -1; 8087 errno = 0; 8088 u = strtoumax(str, &end, 0); 8089 if (errno || (size_t)(end - str) != len) 8090 goto error; 8091 if (arg->mask) { 8092 uintmax_t v = 0; 8093 8094 extra = arg_entry_bf_fill(NULL, 0, arg); 8095 if (u > extra) 8096 goto error; 8097 if (!ctx->object) 8098 return len; 8099 extra -= u; 8100 while (u--) 8101 (v <<= 1, v |= 1); 8102 v <<= extra; 8103 if (!arg_entry_bf_fill(ctx->object, v, arg) || 8104 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 8105 goto error; 8106 return len; 8107 } 8108 bytes = u / 8; 8109 extra = u % 8; 8110 size = arg->size; 8111 if (bytes > size || bytes + !!extra > size) 8112 goto error; 8113 if (!ctx->object) 8114 return len; 8115 buf = (uint8_t *)ctx->object + arg->offset; 8116 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8117 if (!arg->hton) { 8118 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 8119 memset(buf, 0x00, size - bytes); 8120 if (extra) 8121 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 8122 } else 8123 #endif 8124 { 8125 memset(buf, 0xff, bytes); 8126 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 8127 if (extra) 8128 ((uint8_t *)buf)[bytes] = conv[extra]; 8129 } 8130 if (ctx->objmask) 8131 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 8132 return len; 8133 error: 8134 push_args(ctx, arg); 8135 return -1; 8136 } 8137 8138 /** Default parsing function for token name matching. */ 8139 static int 8140 parse_default(struct context *ctx, const struct token *token, 8141 const char *str, unsigned int len, 8142 void *buf, unsigned int size) 8143 { 8144 (void)ctx; 8145 (void)buf; 8146 (void)size; 8147 if (strcmp_partial(token->name, str, len)) 8148 return -1; 8149 return len; 8150 } 8151 8152 /** Parse flow command, initialize output buffer for subsequent tokens. */ 8153 static int 8154 parse_init(struct context *ctx, const struct token *token, 8155 const char *str, unsigned int len, 8156 void *buf, unsigned int size) 8157 { 8158 struct buffer *out = buf; 8159 8160 /* Token name must match. */ 8161 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8162 return -1; 8163 /* Nothing else to do if there is no buffer. */ 8164 if (!out) 8165 return len; 8166 /* Make sure buffer is large enough. */ 8167 if (size < sizeof(*out)) 8168 return -1; 8169 /* Initialize buffer. */ 8170 memset(out, 0x00, sizeof(*out)); 8171 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 8172 ctx->objdata = 0; 8173 ctx->object = out; 8174 ctx->objmask = NULL; 8175 return len; 8176 } 8177 8178 /** Parse tokens for indirect action commands. */ 8179 static int 8180 parse_ia(struct context *ctx, const struct token *token, 8181 const char *str, unsigned int len, 8182 void *buf, unsigned int size) 8183 { 8184 struct buffer *out = buf; 8185 8186 /* Token name must match. */ 8187 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8188 return -1; 8189 /* Nothing else to do if there is no buffer. */ 8190 if (!out) 8191 return len; 8192 if (!out->command) { 8193 if (ctx->curr != INDIRECT_ACTION) 8194 return -1; 8195 if (sizeof(*out) > size) 8196 return -1; 8197 out->command = ctx->curr; 8198 ctx->objdata = 0; 8199 ctx->object = out; 8200 ctx->objmask = NULL; 8201 out->args.vc.data = (uint8_t *)out + size; 8202 return len; 8203 } 8204 switch (ctx->curr) { 8205 case INDIRECT_ACTION_CREATE: 8206 case INDIRECT_ACTION_UPDATE: 8207 case INDIRECT_ACTION_QUERY_UPDATE: 8208 out->args.vc.actions = 8209 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8210 sizeof(double)); 8211 out->args.vc.attr.group = UINT32_MAX; 8212 /* fallthrough */ 8213 case INDIRECT_ACTION_QUERY: 8214 out->command = ctx->curr; 8215 ctx->objdata = 0; 8216 ctx->object = out; 8217 ctx->objmask = NULL; 8218 return len; 8219 case INDIRECT_ACTION_EGRESS: 8220 out->args.vc.attr.egress = 1; 8221 return len; 8222 case INDIRECT_ACTION_INGRESS: 8223 out->args.vc.attr.ingress = 1; 8224 return len; 8225 case INDIRECT_ACTION_TRANSFER: 8226 out->args.vc.attr.transfer = 1; 8227 return len; 8228 case INDIRECT_ACTION_QU_MODE: 8229 return len; 8230 case INDIRECT_ACTION_LIST: 8231 out->command = INDIRECT_ACTION_LIST_CREATE; 8232 return len; 8233 case INDIRECT_ACTION_FLOW_CONF: 8234 out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; 8235 return len; 8236 default: 8237 return -1; 8238 } 8239 } 8240 8241 8242 /** Parse tokens for indirect action destroy command. */ 8243 static int 8244 parse_ia_destroy(struct context *ctx, const struct token *token, 8245 const char *str, unsigned int len, 8246 void *buf, unsigned int size) 8247 { 8248 struct buffer *out = buf; 8249 uint32_t *action_id; 8250 8251 /* Token name must match. */ 8252 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8253 return -1; 8254 /* Nothing else to do if there is no buffer. */ 8255 if (!out) 8256 return len; 8257 if (!out->command || out->command == INDIRECT_ACTION) { 8258 if (ctx->curr != INDIRECT_ACTION_DESTROY) 8259 return -1; 8260 if (sizeof(*out) > size) 8261 return -1; 8262 out->command = ctx->curr; 8263 ctx->objdata = 0; 8264 ctx->object = out; 8265 ctx->objmask = NULL; 8266 out->args.ia_destroy.action_id = 8267 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8268 sizeof(double)); 8269 return len; 8270 } 8271 action_id = out->args.ia_destroy.action_id 8272 + out->args.ia_destroy.action_id_n++; 8273 if ((uint8_t *)action_id > (uint8_t *)out + size) 8274 return -1; 8275 ctx->objdata = 0; 8276 ctx->object = action_id; 8277 ctx->objmask = NULL; 8278 return len; 8279 } 8280 8281 /** Parse tokens for indirect action commands. */ 8282 static int 8283 parse_qia(struct context *ctx, const struct token *token, 8284 const char *str, unsigned int len, 8285 void *buf, unsigned int size) 8286 { 8287 struct buffer *out = buf; 8288 8289 /* Token name must match. */ 8290 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8291 return -1; 8292 /* Nothing else to do if there is no buffer. */ 8293 if (!out) 8294 return len; 8295 if (!out->command) { 8296 if (ctx->curr != QUEUE) 8297 return -1; 8298 if (sizeof(*out) > size) 8299 return -1; 8300 out->args.vc.data = (uint8_t *)out + size; 8301 return len; 8302 } 8303 switch (ctx->curr) { 8304 case QUEUE_INDIRECT_ACTION: 8305 return len; 8306 case QUEUE_INDIRECT_ACTION_CREATE: 8307 case QUEUE_INDIRECT_ACTION_UPDATE: 8308 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 8309 out->args.vc.actions = 8310 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8311 sizeof(double)); 8312 out->args.vc.attr.group = UINT32_MAX; 8313 /* fallthrough */ 8314 case QUEUE_INDIRECT_ACTION_QUERY: 8315 out->command = ctx->curr; 8316 ctx->objdata = 0; 8317 ctx->object = out; 8318 ctx->objmask = NULL; 8319 return len; 8320 case QUEUE_INDIRECT_ACTION_EGRESS: 8321 out->args.vc.attr.egress = 1; 8322 return len; 8323 case QUEUE_INDIRECT_ACTION_INGRESS: 8324 out->args.vc.attr.ingress = 1; 8325 return len; 8326 case QUEUE_INDIRECT_ACTION_TRANSFER: 8327 out->args.vc.attr.transfer = 1; 8328 return len; 8329 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 8330 return len; 8331 case QUEUE_INDIRECT_ACTION_QU_MODE: 8332 return len; 8333 case QUEUE_INDIRECT_ACTION_LIST: 8334 out->command = QUEUE_INDIRECT_ACTION_LIST_CREATE; 8335 return len; 8336 default: 8337 return -1; 8338 } 8339 } 8340 8341 /** Parse tokens for indirect action destroy command. */ 8342 static int 8343 parse_qia_destroy(struct context *ctx, const struct token *token, 8344 const char *str, unsigned int len, 8345 void *buf, unsigned int size) 8346 { 8347 struct buffer *out = buf; 8348 uint32_t *action_id; 8349 8350 /* Token name must match. */ 8351 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8352 return -1; 8353 /* Nothing else to do if there is no buffer. */ 8354 if (!out) 8355 return len; 8356 if (!out->command || out->command == QUEUE) { 8357 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 8358 return -1; 8359 if (sizeof(*out) > size) 8360 return -1; 8361 out->command = ctx->curr; 8362 ctx->objdata = 0; 8363 ctx->object = out; 8364 ctx->objmask = NULL; 8365 out->args.ia_destroy.action_id = 8366 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8367 sizeof(double)); 8368 return len; 8369 } 8370 switch (ctx->curr) { 8371 case QUEUE_INDIRECT_ACTION: 8372 out->command = ctx->curr; 8373 ctx->objdata = 0; 8374 ctx->object = out; 8375 ctx->objmask = NULL; 8376 return len; 8377 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 8378 action_id = out->args.ia_destroy.action_id 8379 + out->args.ia_destroy.action_id_n++; 8380 if ((uint8_t *)action_id > (uint8_t *)out + size) 8381 return -1; 8382 ctx->objdata = 0; 8383 ctx->object = action_id; 8384 ctx->objmask = NULL; 8385 return len; 8386 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 8387 return len; 8388 default: 8389 return -1; 8390 } 8391 } 8392 8393 /** Parse tokens for meter policy action commands. */ 8394 static int 8395 parse_mp(struct context *ctx, const struct token *token, 8396 const char *str, unsigned int len, 8397 void *buf, unsigned int size) 8398 { 8399 struct buffer *out = buf; 8400 8401 /* Token name must match. */ 8402 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8403 return -1; 8404 /* Nothing else to do if there is no buffer. */ 8405 if (!out) 8406 return len; 8407 if (!out->command) { 8408 if (ctx->curr != ITEM_POL_POLICY) 8409 return -1; 8410 if (sizeof(*out) > size) 8411 return -1; 8412 out->command = ctx->curr; 8413 ctx->objdata = 0; 8414 ctx->object = out; 8415 ctx->objmask = NULL; 8416 out->args.vc.data = (uint8_t *)out + size; 8417 return len; 8418 } 8419 switch (ctx->curr) { 8420 case ACTION_POL_G: 8421 out->args.vc.actions = 8422 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8423 sizeof(double)); 8424 out->command = ctx->curr; 8425 ctx->objdata = 0; 8426 ctx->object = out; 8427 ctx->objmask = NULL; 8428 return len; 8429 default: 8430 return -1; 8431 } 8432 } 8433 8434 /** Parse tokens for validate/create commands. */ 8435 static int 8436 parse_vc(struct context *ctx, const struct token *token, 8437 const char *str, unsigned int len, 8438 void *buf, unsigned int size) 8439 { 8440 struct buffer *out = buf; 8441 uint8_t *data; 8442 uint32_t data_size; 8443 8444 /* Token name must match. */ 8445 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8446 return -1; 8447 /* Nothing else to do if there is no buffer. */ 8448 if (!out) 8449 return len; 8450 if (!out->command) { 8451 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 8452 ctx->curr != PATTERN_TEMPLATE_CREATE && 8453 ctx->curr != ACTIONS_TEMPLATE_CREATE) 8454 return -1; 8455 if (sizeof(*out) > size) 8456 return -1; 8457 out->command = ctx->curr; 8458 ctx->objdata = 0; 8459 ctx->object = out; 8460 ctx->objmask = NULL; 8461 out->args.vc.data = (uint8_t *)out + size; 8462 return len; 8463 } 8464 ctx->objdata = 0; 8465 switch (ctx->curr) { 8466 default: 8467 ctx->object = &out->args.vc.attr; 8468 break; 8469 case VC_TUNNEL_SET: 8470 case VC_TUNNEL_MATCH: 8471 ctx->object = &out->args.vc.tunnel_ops; 8472 break; 8473 case VC_USER_ID: 8474 ctx->object = out; 8475 break; 8476 } 8477 ctx->objmask = NULL; 8478 switch (ctx->curr) { 8479 case VC_GROUP: 8480 case VC_PRIORITY: 8481 case VC_USER_ID: 8482 return len; 8483 case VC_TUNNEL_SET: 8484 out->args.vc.tunnel_ops.enabled = 1; 8485 out->args.vc.tunnel_ops.actions = 1; 8486 return len; 8487 case VC_TUNNEL_MATCH: 8488 out->args.vc.tunnel_ops.enabled = 1; 8489 out->args.vc.tunnel_ops.items = 1; 8490 return len; 8491 case VC_INGRESS: 8492 out->args.vc.attr.ingress = 1; 8493 return len; 8494 case VC_EGRESS: 8495 out->args.vc.attr.egress = 1; 8496 return len; 8497 case VC_TRANSFER: 8498 out->args.vc.attr.transfer = 1; 8499 return len; 8500 case ITEM_PATTERN: 8501 out->args.vc.pattern = 8502 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8503 sizeof(double)); 8504 ctx->object = out->args.vc.pattern; 8505 ctx->objmask = NULL; 8506 return len; 8507 case ITEM_END: 8508 if ((out->command == VALIDATE || out->command == CREATE) && 8509 ctx->last) 8510 return -1; 8511 if (out->command == PATTERN_TEMPLATE_CREATE && 8512 !ctx->last) 8513 return -1; 8514 break; 8515 case ACTIONS: 8516 out->args.vc.actions = out->args.vc.pattern ? 8517 (void *)RTE_ALIGN_CEIL((uintptr_t) 8518 (out->args.vc.pattern + 8519 out->args.vc.pattern_n), 8520 sizeof(double)) : 8521 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8522 sizeof(double)); 8523 ctx->object = out->args.vc.actions; 8524 ctx->objmask = NULL; 8525 return len; 8526 default: 8527 if (!token->priv) 8528 return -1; 8529 break; 8530 } 8531 if (!out->args.vc.actions) { 8532 const struct parse_item_priv *priv = token->priv; 8533 struct rte_flow_item *item = 8534 out->args.vc.pattern + out->args.vc.pattern_n; 8535 8536 data_size = priv->size * 3; /* spec, last, mask */ 8537 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8538 (out->args.vc.data - data_size), 8539 sizeof(double)); 8540 if ((uint8_t *)item + sizeof(*item) > data) 8541 return -1; 8542 *item = (struct rte_flow_item){ 8543 .type = priv->type, 8544 }; 8545 ++out->args.vc.pattern_n; 8546 ctx->object = item; 8547 ctx->objmask = NULL; 8548 } else { 8549 const struct parse_action_priv *priv = token->priv; 8550 struct rte_flow_action *action = 8551 out->args.vc.actions + out->args.vc.actions_n; 8552 8553 data_size = priv->size; /* configuration */ 8554 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8555 (out->args.vc.data - data_size), 8556 sizeof(double)); 8557 if ((uint8_t *)action + sizeof(*action) > data) 8558 return -1; 8559 *action = (struct rte_flow_action){ 8560 .type = priv->type, 8561 .conf = data_size ? data : NULL, 8562 }; 8563 ++out->args.vc.actions_n; 8564 ctx->object = action; 8565 ctx->objmask = NULL; 8566 } 8567 memset(data, 0, data_size); 8568 out->args.vc.data = data; 8569 ctx->objdata = data_size; 8570 return len; 8571 } 8572 8573 /** Parse pattern item parameter type. */ 8574 static int 8575 parse_vc_spec(struct context *ctx, const struct token *token, 8576 const char *str, unsigned int len, 8577 void *buf, unsigned int size) 8578 { 8579 struct buffer *out = buf; 8580 struct rte_flow_item *item; 8581 uint32_t data_size; 8582 int index; 8583 int objmask = 0; 8584 8585 (void)size; 8586 /* Token name must match. */ 8587 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8588 return -1; 8589 /* Parse parameter types. */ 8590 switch (ctx->curr) { 8591 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 8592 8593 case ITEM_PARAM_IS: 8594 index = 0; 8595 objmask = 1; 8596 break; 8597 case ITEM_PARAM_SPEC: 8598 index = 0; 8599 break; 8600 case ITEM_PARAM_LAST: 8601 index = 1; 8602 break; 8603 case ITEM_PARAM_PREFIX: 8604 /* Modify next token to expect a prefix. */ 8605 if (ctx->next_num < 2) 8606 return -1; 8607 ctx->next[ctx->next_num - 2] = prefix; 8608 /* Fall through. */ 8609 case ITEM_PARAM_MASK: 8610 index = 2; 8611 break; 8612 default: 8613 return -1; 8614 } 8615 /* Nothing else to do if there is no buffer. */ 8616 if (!out) 8617 return len; 8618 if (!out->args.vc.pattern_n) 8619 return -1; 8620 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8621 data_size = ctx->objdata / 3; /* spec, last, mask */ 8622 /* Point to selected object. */ 8623 ctx->object = out->args.vc.data + (data_size * index); 8624 if (objmask) { 8625 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 8626 item->mask = ctx->objmask; 8627 } else 8628 ctx->objmask = NULL; 8629 /* Update relevant item pointer. */ 8630 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 8631 ctx->object; 8632 return len; 8633 } 8634 8635 /** Parse action configuration field. */ 8636 static int 8637 parse_vc_conf(struct context *ctx, const struct token *token, 8638 const char *str, unsigned int len, 8639 void *buf, unsigned int size) 8640 { 8641 struct buffer *out = buf; 8642 8643 (void)size; 8644 /* Token name must match. */ 8645 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8646 return -1; 8647 /* Nothing else to do if there is no buffer. */ 8648 if (!out) 8649 return len; 8650 /* Point to selected object. */ 8651 ctx->object = out->args.vc.data; 8652 ctx->objmask = NULL; 8653 return len; 8654 } 8655 8656 /** Parse action configuration field. */ 8657 static int 8658 parse_vc_conf_timeout(struct context *ctx, const struct token *token, 8659 const char *str, unsigned int len, 8660 void *buf, unsigned int size) 8661 { 8662 struct buffer *out = buf; 8663 struct rte_flow_update_age *update; 8664 8665 (void)size; 8666 if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) 8667 return -1; 8668 /* Token name must match. */ 8669 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8670 return -1; 8671 /* Nothing else to do if there is no buffer. */ 8672 if (!out) 8673 return len; 8674 /* Point to selected object. */ 8675 ctx->object = out->args.vc.data; 8676 ctx->objmask = NULL; 8677 /* Update the timeout is valid. */ 8678 update = (struct rte_flow_update_age *)out->args.vc.data; 8679 update->timeout_valid = 1; 8680 return len; 8681 } 8682 8683 /** Parse eCPRI common header type field. */ 8684 static int 8685 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 8686 const char *str, unsigned int len, 8687 void *buf, unsigned int size) 8688 { 8689 struct rte_flow_item_ecpri *ecpri; 8690 struct rte_flow_item_ecpri *ecpri_mask; 8691 struct rte_flow_item *item; 8692 uint32_t data_size; 8693 uint8_t msg_type; 8694 struct buffer *out = buf; 8695 const struct arg *arg; 8696 8697 (void)size; 8698 /* Token name must match. */ 8699 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8700 return -1; 8701 switch (ctx->curr) { 8702 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 8703 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 8704 break; 8705 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 8706 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 8707 break; 8708 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 8709 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 8710 break; 8711 default: 8712 return -1; 8713 } 8714 if (!ctx->object) 8715 return len; 8716 arg = pop_args(ctx); 8717 if (!arg) 8718 return -1; 8719 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 8720 ecpri->hdr.common.type = msg_type; 8721 data_size = ctx->objdata / 3; /* spec, last, mask */ 8722 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 8723 (data_size * 2)); 8724 ecpri_mask->hdr.common.type = 0xFF; 8725 if (arg->hton) { 8726 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 8727 ecpri_mask->hdr.common.u32 = 8728 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 8729 } 8730 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8731 item->spec = ecpri; 8732 item->mask = ecpri_mask; 8733 return len; 8734 } 8735 8736 /** Parse L2TPv2 common header type field. */ 8737 static int 8738 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, 8739 const char *str, unsigned int len, 8740 void *buf, unsigned int size) 8741 { 8742 struct rte_flow_item_l2tpv2 *l2tpv2; 8743 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 8744 struct rte_flow_item *item; 8745 uint32_t data_size; 8746 uint16_t msg_type = 0; 8747 struct buffer *out = buf; 8748 const struct arg *arg; 8749 8750 (void)size; 8751 /* Token name must match. */ 8752 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8753 return -1; 8754 switch (ctx->curr) { 8755 case ITEM_L2TPV2_TYPE_DATA: 8756 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 8757 break; 8758 case ITEM_L2TPV2_TYPE_DATA_L: 8759 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 8760 break; 8761 case ITEM_L2TPV2_TYPE_DATA_S: 8762 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 8763 break; 8764 case ITEM_L2TPV2_TYPE_DATA_O: 8765 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 8766 break; 8767 case ITEM_L2TPV2_TYPE_DATA_L_S: 8768 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 8769 break; 8770 case ITEM_L2TPV2_TYPE_CTRL: 8771 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 8772 break; 8773 default: 8774 return -1; 8775 } 8776 if (!ctx->object) 8777 return len; 8778 arg = pop_args(ctx); 8779 if (!arg) 8780 return -1; 8781 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 8782 l2tpv2->hdr.common.flags_version |= msg_type; 8783 data_size = ctx->objdata / 3; /* spec, last, mask */ 8784 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 8785 (data_size * 2)); 8786 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 8787 if (arg->hton) { 8788 l2tpv2->hdr.common.flags_version = 8789 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 8790 l2tpv2_mask->hdr.common.flags_version = 8791 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 8792 } 8793 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8794 item->spec = l2tpv2; 8795 item->mask = l2tpv2_mask; 8796 return len; 8797 } 8798 8799 /** Parse operation for compare match item. */ 8800 static int 8801 parse_vc_compare_op(struct context *ctx, const struct token *token, 8802 const char *str, unsigned int len, void *buf, 8803 unsigned int size) 8804 { 8805 struct rte_flow_item_compare *compare_item; 8806 unsigned int i; 8807 8808 (void)token; 8809 (void)buf; 8810 (void)size; 8811 if (ctx->curr != ITEM_COMPARE_OP_VALUE) 8812 return -1; 8813 for (i = 0; compare_ops[i]; ++i) 8814 if (!strcmp_partial(compare_ops[i], str, len)) 8815 break; 8816 if (!compare_ops[i]) 8817 return -1; 8818 if (!ctx->object) 8819 return len; 8820 compare_item = ctx->object; 8821 compare_item->operation = (enum rte_flow_item_compare_op)i; 8822 return len; 8823 } 8824 8825 /** Parse id for compare match item. */ 8826 static int 8827 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 8828 const char *str, unsigned int len, void *buf, 8829 unsigned int size) 8830 { 8831 struct rte_flow_item_compare *compare_item; 8832 unsigned int i; 8833 8834 (void)token; 8835 (void)buf; 8836 (void)size; 8837 if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE && 8838 ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE) 8839 return -1; 8840 for (i = 0; flow_field_ids[i]; ++i) 8841 if (!strcmp_partial(flow_field_ids[i], str, len)) 8842 break; 8843 if (!flow_field_ids[i]) 8844 return -1; 8845 if (!ctx->object) 8846 return len; 8847 compare_item = ctx->object; 8848 if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE) 8849 compare_item->a.field = (enum rte_flow_field_id)i; 8850 else 8851 compare_item->b.field = (enum rte_flow_field_id)i; 8852 return len; 8853 } 8854 8855 /** Parse level for compare match item. */ 8856 static int 8857 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 8858 const char *str, unsigned int len, void *buf, 8859 unsigned int size) 8860 { 8861 struct rte_flow_item_compare *compare_item; 8862 struct flex_item *fp = NULL; 8863 uint32_t val; 8864 struct buffer *out = buf; 8865 char *end; 8866 8867 (void)token; 8868 (void)size; 8869 if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 8870 ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE) 8871 return -1; 8872 if (!ctx->object) 8873 return len; 8874 compare_item = ctx->object; 8875 errno = 0; 8876 val = strtoumax(str, &end, 0); 8877 if (errno || (size_t)(end - str) != len) 8878 return -1; 8879 /* No need to validate action template mask value */ 8880 if (out->args.vc.masks) { 8881 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) 8882 compare_item->a.level = val; 8883 else 8884 compare_item->b.level = val; 8885 return len; 8886 } 8887 if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 8888 compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) || 8889 (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE && 8890 compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 8891 if (val >= FLEX_MAX_PARSERS_NUM) { 8892 printf("Bad flex item handle\n"); 8893 return -1; 8894 } 8895 fp = flex_items[ctx->port][val]; 8896 if (!fp) { 8897 printf("Bad flex item handle\n"); 8898 return -1; 8899 } 8900 } 8901 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) { 8902 if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM) 8903 compare_item->a.level = val; 8904 else 8905 compare_item->a.flex_handle = fp->flex_handle; 8906 } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) { 8907 if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM) 8908 compare_item->b.level = val; 8909 else 8910 compare_item->b.flex_handle = fp->flex_handle; 8911 } 8912 return len; 8913 } 8914 8915 /** Parse meter color action type. */ 8916 static int 8917 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 8918 const char *str, unsigned int len, 8919 void *buf, unsigned int size) 8920 { 8921 struct rte_flow_action *action_data; 8922 struct rte_flow_action_meter_color *conf; 8923 enum rte_color color; 8924 8925 (void)buf; 8926 (void)size; 8927 /* Token name must match. */ 8928 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8929 return -1; 8930 switch (ctx->curr) { 8931 case ACTION_METER_COLOR_GREEN: 8932 color = RTE_COLOR_GREEN; 8933 break; 8934 case ACTION_METER_COLOR_YELLOW: 8935 color = RTE_COLOR_YELLOW; 8936 break; 8937 case ACTION_METER_COLOR_RED: 8938 color = RTE_COLOR_RED; 8939 break; 8940 default: 8941 return -1; 8942 } 8943 8944 if (!ctx->object) 8945 return len; 8946 action_data = ctx->object; 8947 conf = (struct rte_flow_action_meter_color *) 8948 (uintptr_t)(action_data->conf); 8949 conf->color = color; 8950 return len; 8951 } 8952 8953 /** Parse RSS action. */ 8954 static int 8955 parse_vc_action_rss(struct context *ctx, const struct token *token, 8956 const char *str, unsigned int len, 8957 void *buf, unsigned int size) 8958 { 8959 struct buffer *out = buf; 8960 struct rte_flow_action *action; 8961 struct action_rss_data *action_rss_data; 8962 unsigned int i; 8963 int ret; 8964 8965 ret = parse_vc(ctx, token, str, len, buf, size); 8966 if (ret < 0) 8967 return ret; 8968 /* Nothing else to do if there is no buffer. */ 8969 if (!out) 8970 return ret; 8971 if (!out->args.vc.actions_n) 8972 return -1; 8973 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8974 /* Point to selected object. */ 8975 ctx->object = out->args.vc.data; 8976 ctx->objmask = NULL; 8977 /* Set up default configuration. */ 8978 action_rss_data = ctx->object; 8979 *action_rss_data = (struct action_rss_data){ 8980 .conf = (struct rte_flow_action_rss){ 8981 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 8982 .level = 0, 8983 .types = rss_hf, 8984 .key_len = 0, 8985 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 8986 .key = NULL, 8987 .queue = action_rss_data->queue, 8988 }, 8989 .queue = { 0 }, 8990 }; 8991 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 8992 action_rss_data->queue[i] = i; 8993 action->conf = &action_rss_data->conf; 8994 return ret; 8995 } 8996 8997 /** 8998 * Parse func field for RSS action. 8999 * 9000 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 9001 * ACTION_RSS_FUNC_* index that called this function. 9002 */ 9003 static int 9004 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 9005 const char *str, unsigned int len, 9006 void *buf, unsigned int size) 9007 { 9008 struct action_rss_data *action_rss_data; 9009 enum rte_eth_hash_function func; 9010 9011 (void)buf; 9012 (void)size; 9013 /* Token name must match. */ 9014 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9015 return -1; 9016 switch (ctx->curr) { 9017 case ACTION_RSS_FUNC_DEFAULT: 9018 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 9019 break; 9020 case ACTION_RSS_FUNC_TOEPLITZ: 9021 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 9022 break; 9023 case ACTION_RSS_FUNC_SIMPLE_XOR: 9024 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 9025 break; 9026 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 9027 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 9028 break; 9029 default: 9030 return -1; 9031 } 9032 if (!ctx->object) 9033 return len; 9034 action_rss_data = ctx->object; 9035 action_rss_data->conf.func = func; 9036 return len; 9037 } 9038 9039 /** 9040 * Parse type field for RSS action. 9041 * 9042 * Valid tokens are type field names and the "end" token. 9043 */ 9044 static int 9045 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 9046 const char *str, unsigned int len, 9047 void *buf, unsigned int size) 9048 { 9049 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 9050 struct action_rss_data *action_rss_data; 9051 unsigned int i; 9052 9053 (void)token; 9054 (void)buf; 9055 (void)size; 9056 if (ctx->curr != ACTION_RSS_TYPE) 9057 return -1; 9058 if (!(ctx->objdata >> 16) && ctx->object) { 9059 action_rss_data = ctx->object; 9060 action_rss_data->conf.types = 0; 9061 } 9062 if (!strcmp_partial("end", str, len)) { 9063 ctx->objdata &= 0xffff; 9064 return len; 9065 } 9066 for (i = 0; rss_type_table[i].str; ++i) 9067 if (!strcmp_partial(rss_type_table[i].str, str, len)) 9068 break; 9069 if (!rss_type_table[i].str) 9070 return -1; 9071 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 9072 /* Repeat token. */ 9073 if (ctx->next_num == RTE_DIM(ctx->next)) 9074 return -1; 9075 ctx->next[ctx->next_num++] = next; 9076 if (!ctx->object) 9077 return len; 9078 action_rss_data = ctx->object; 9079 action_rss_data->conf.types |= rss_type_table[i].rss_type; 9080 return len; 9081 } 9082 9083 /** 9084 * Parse queue field for RSS action. 9085 * 9086 * Valid tokens are queue indices and the "end" token. 9087 */ 9088 static int 9089 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 9090 const char *str, unsigned int len, 9091 void *buf, unsigned int size) 9092 { 9093 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 9094 struct action_rss_data *action_rss_data; 9095 const struct arg *arg; 9096 int ret; 9097 int i; 9098 9099 (void)token; 9100 (void)buf; 9101 (void)size; 9102 if (ctx->curr != ACTION_RSS_QUEUE) 9103 return -1; 9104 i = ctx->objdata >> 16; 9105 if (!strcmp_partial("end", str, len)) { 9106 ctx->objdata &= 0xffff; 9107 goto end; 9108 } 9109 if (i >= ACTION_RSS_QUEUE_NUM) 9110 return -1; 9111 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 9112 i * sizeof(action_rss_data->queue[i]), 9113 sizeof(action_rss_data->queue[i])); 9114 if (push_args(ctx, arg)) 9115 return -1; 9116 ret = parse_int(ctx, token, str, len, NULL, 0); 9117 if (ret < 0) { 9118 pop_args(ctx); 9119 return -1; 9120 } 9121 ++i; 9122 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 9123 /* Repeat token. */ 9124 if (ctx->next_num == RTE_DIM(ctx->next)) 9125 return -1; 9126 ctx->next[ctx->next_num++] = next; 9127 end: 9128 if (!ctx->object) 9129 return len; 9130 action_rss_data = ctx->object; 9131 action_rss_data->conf.queue_num = i; 9132 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 9133 return len; 9134 } 9135 9136 /** Setup VXLAN encap configuration. */ 9137 static int 9138 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 9139 { 9140 /* Set up default configuration. */ 9141 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 9142 .conf = (struct rte_flow_action_vxlan_encap){ 9143 .definition = action_vxlan_encap_data->items, 9144 }, 9145 .items = { 9146 { 9147 .type = RTE_FLOW_ITEM_TYPE_ETH, 9148 .spec = &action_vxlan_encap_data->item_eth, 9149 .mask = &rte_flow_item_eth_mask, 9150 }, 9151 { 9152 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9153 .spec = &action_vxlan_encap_data->item_vlan, 9154 .mask = &rte_flow_item_vlan_mask, 9155 }, 9156 { 9157 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9158 .spec = &action_vxlan_encap_data->item_ipv4, 9159 .mask = &rte_flow_item_ipv4_mask, 9160 }, 9161 { 9162 .type = RTE_FLOW_ITEM_TYPE_UDP, 9163 .spec = &action_vxlan_encap_data->item_udp, 9164 .mask = &rte_flow_item_udp_mask, 9165 }, 9166 { 9167 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 9168 .spec = &action_vxlan_encap_data->item_vxlan, 9169 .mask = &rte_flow_item_vxlan_mask, 9170 }, 9171 { 9172 .type = RTE_FLOW_ITEM_TYPE_END, 9173 }, 9174 }, 9175 .item_eth.hdr.ether_type = 0, 9176 .item_vlan = { 9177 .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, 9178 .hdr.eth_proto = 0, 9179 }, 9180 .item_ipv4.hdr = { 9181 .src_addr = vxlan_encap_conf.ipv4_src, 9182 .dst_addr = vxlan_encap_conf.ipv4_dst, 9183 }, 9184 .item_udp.hdr = { 9185 .src_port = vxlan_encap_conf.udp_src, 9186 .dst_port = vxlan_encap_conf.udp_dst, 9187 }, 9188 .item_vxlan.hdr.flags = 0, 9189 }; 9190 memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9191 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9192 memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, 9193 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9194 if (!vxlan_encap_conf.select_ipv4) { 9195 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 9196 &vxlan_encap_conf.ipv6_src, 9197 sizeof(vxlan_encap_conf.ipv6_src)); 9198 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 9199 &vxlan_encap_conf.ipv6_dst, 9200 sizeof(vxlan_encap_conf.ipv6_dst)); 9201 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 9202 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9203 .spec = &action_vxlan_encap_data->item_ipv6, 9204 .mask = &rte_flow_item_ipv6_mask, 9205 }; 9206 } 9207 if (!vxlan_encap_conf.select_vlan) 9208 action_vxlan_encap_data->items[1].type = 9209 RTE_FLOW_ITEM_TYPE_VOID; 9210 if (vxlan_encap_conf.select_tos_ttl) { 9211 if (vxlan_encap_conf.select_ipv4) { 9212 static struct rte_flow_item_ipv4 ipv4_mask_tos; 9213 9214 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 9215 sizeof(ipv4_mask_tos)); 9216 ipv4_mask_tos.hdr.type_of_service = 0xff; 9217 ipv4_mask_tos.hdr.time_to_live = 0xff; 9218 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 9219 vxlan_encap_conf.ip_tos; 9220 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 9221 vxlan_encap_conf.ip_ttl; 9222 action_vxlan_encap_data->items[2].mask = 9223 &ipv4_mask_tos; 9224 } else { 9225 static struct rte_flow_item_ipv6 ipv6_mask_tos; 9226 9227 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 9228 sizeof(ipv6_mask_tos)); 9229 ipv6_mask_tos.hdr.vtc_flow |= 9230 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 9231 ipv6_mask_tos.hdr.hop_limits = 0xff; 9232 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 9233 rte_cpu_to_be_32 9234 ((uint32_t)vxlan_encap_conf.ip_tos << 9235 RTE_IPV6_HDR_TC_SHIFT); 9236 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 9237 vxlan_encap_conf.ip_ttl; 9238 action_vxlan_encap_data->items[2].mask = 9239 &ipv6_mask_tos; 9240 } 9241 } 9242 memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, 9243 RTE_DIM(vxlan_encap_conf.vni)); 9244 return 0; 9245 } 9246 9247 /** Parse VXLAN encap action. */ 9248 static int 9249 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 9250 const char *str, unsigned int len, 9251 void *buf, unsigned int size) 9252 { 9253 struct buffer *out = buf; 9254 struct rte_flow_action *action; 9255 struct action_vxlan_encap_data *action_vxlan_encap_data; 9256 int ret; 9257 9258 ret = parse_vc(ctx, token, str, len, buf, size); 9259 if (ret < 0) 9260 return ret; 9261 /* Nothing else to do if there is no buffer. */ 9262 if (!out) 9263 return ret; 9264 if (!out->args.vc.actions_n) 9265 return -1; 9266 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9267 /* Point to selected object. */ 9268 ctx->object = out->args.vc.data; 9269 ctx->objmask = NULL; 9270 action_vxlan_encap_data = ctx->object; 9271 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 9272 action->conf = &action_vxlan_encap_data->conf; 9273 return ret; 9274 } 9275 9276 /** Setup NVGRE encap configuration. */ 9277 static int 9278 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 9279 { 9280 /* Set up default configuration. */ 9281 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 9282 .conf = (struct rte_flow_action_nvgre_encap){ 9283 .definition = action_nvgre_encap_data->items, 9284 }, 9285 .items = { 9286 { 9287 .type = RTE_FLOW_ITEM_TYPE_ETH, 9288 .spec = &action_nvgre_encap_data->item_eth, 9289 .mask = &rte_flow_item_eth_mask, 9290 }, 9291 { 9292 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9293 .spec = &action_nvgre_encap_data->item_vlan, 9294 .mask = &rte_flow_item_vlan_mask, 9295 }, 9296 { 9297 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9298 .spec = &action_nvgre_encap_data->item_ipv4, 9299 .mask = &rte_flow_item_ipv4_mask, 9300 }, 9301 { 9302 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 9303 .spec = &action_nvgre_encap_data->item_nvgre, 9304 .mask = &rte_flow_item_nvgre_mask, 9305 }, 9306 { 9307 .type = RTE_FLOW_ITEM_TYPE_END, 9308 }, 9309 }, 9310 .item_eth.hdr.ether_type = 0, 9311 .item_vlan = { 9312 .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, 9313 .hdr.eth_proto = 0, 9314 }, 9315 .item_ipv4.hdr = { 9316 .src_addr = nvgre_encap_conf.ipv4_src, 9317 .dst_addr = nvgre_encap_conf.ipv4_dst, 9318 }, 9319 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 9320 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 9321 .item_nvgre.flow_id = 0, 9322 }; 9323 memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9324 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9325 memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, 9326 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9327 if (!nvgre_encap_conf.select_ipv4) { 9328 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 9329 &nvgre_encap_conf.ipv6_src, 9330 sizeof(nvgre_encap_conf.ipv6_src)); 9331 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 9332 &nvgre_encap_conf.ipv6_dst, 9333 sizeof(nvgre_encap_conf.ipv6_dst)); 9334 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 9335 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9336 .spec = &action_nvgre_encap_data->item_ipv6, 9337 .mask = &rte_flow_item_ipv6_mask, 9338 }; 9339 } 9340 if (!nvgre_encap_conf.select_vlan) 9341 action_nvgre_encap_data->items[1].type = 9342 RTE_FLOW_ITEM_TYPE_VOID; 9343 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 9344 RTE_DIM(nvgre_encap_conf.tni)); 9345 return 0; 9346 } 9347 9348 /** Parse NVGRE encap action. */ 9349 static int 9350 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 9351 const char *str, unsigned int len, 9352 void *buf, unsigned int size) 9353 { 9354 struct buffer *out = buf; 9355 struct rte_flow_action *action; 9356 struct action_nvgre_encap_data *action_nvgre_encap_data; 9357 int ret; 9358 9359 ret = parse_vc(ctx, token, str, len, buf, size); 9360 if (ret < 0) 9361 return ret; 9362 /* Nothing else to do if there is no buffer. */ 9363 if (!out) 9364 return ret; 9365 if (!out->args.vc.actions_n) 9366 return -1; 9367 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9368 /* Point to selected object. */ 9369 ctx->object = out->args.vc.data; 9370 ctx->objmask = NULL; 9371 action_nvgre_encap_data = ctx->object; 9372 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 9373 action->conf = &action_nvgre_encap_data->conf; 9374 return ret; 9375 } 9376 9377 /** Parse l2 encap action. */ 9378 static int 9379 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 9380 const char *str, unsigned int len, 9381 void *buf, unsigned int size) 9382 { 9383 struct buffer *out = buf; 9384 struct rte_flow_action *action; 9385 struct action_raw_encap_data *action_encap_data; 9386 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9387 struct rte_flow_item_vlan vlan = { 9388 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9389 .hdr.eth_proto = 0, 9390 }; 9391 uint8_t *header; 9392 int ret; 9393 9394 ret = parse_vc(ctx, token, str, len, buf, size); 9395 if (ret < 0) 9396 return ret; 9397 /* Nothing else to do if there is no buffer. */ 9398 if (!out) 9399 return ret; 9400 if (!out->args.vc.actions_n) 9401 return -1; 9402 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9403 /* Point to selected object. */ 9404 ctx->object = out->args.vc.data; 9405 ctx->objmask = NULL; 9406 /* Copy the headers to the buffer. */ 9407 action_encap_data = ctx->object; 9408 *action_encap_data = (struct action_raw_encap_data) { 9409 .conf = (struct rte_flow_action_raw_encap){ 9410 .data = action_encap_data->data, 9411 }, 9412 .data = {}, 9413 }; 9414 header = action_encap_data->data; 9415 if (l2_encap_conf.select_vlan) 9416 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9417 else if (l2_encap_conf.select_ipv4) 9418 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9419 else 9420 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9421 memcpy(eth.hdr.dst_addr.addr_bytes, 9422 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9423 memcpy(eth.hdr.src_addr.addr_bytes, 9424 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9425 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9426 header += sizeof(struct rte_ether_hdr); 9427 if (l2_encap_conf.select_vlan) { 9428 if (l2_encap_conf.select_ipv4) 9429 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9430 else 9431 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9432 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9433 header += sizeof(struct rte_vlan_hdr); 9434 } 9435 action_encap_data->conf.size = header - 9436 action_encap_data->data; 9437 action->conf = &action_encap_data->conf; 9438 return ret; 9439 } 9440 9441 /** Parse l2 decap action. */ 9442 static int 9443 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 9444 const char *str, unsigned int len, 9445 void *buf, unsigned int size) 9446 { 9447 struct buffer *out = buf; 9448 struct rte_flow_action *action; 9449 struct action_raw_decap_data *action_decap_data; 9450 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9451 struct rte_flow_item_vlan vlan = { 9452 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9453 .hdr.eth_proto = 0, 9454 }; 9455 uint8_t *header; 9456 int ret; 9457 9458 ret = parse_vc(ctx, token, str, len, buf, size); 9459 if (ret < 0) 9460 return ret; 9461 /* Nothing else to do if there is no buffer. */ 9462 if (!out) 9463 return ret; 9464 if (!out->args.vc.actions_n) 9465 return -1; 9466 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9467 /* Point to selected object. */ 9468 ctx->object = out->args.vc.data; 9469 ctx->objmask = NULL; 9470 /* Copy the headers to the buffer. */ 9471 action_decap_data = ctx->object; 9472 *action_decap_data = (struct action_raw_decap_data) { 9473 .conf = (struct rte_flow_action_raw_decap){ 9474 .data = action_decap_data->data, 9475 }, 9476 .data = {}, 9477 }; 9478 header = action_decap_data->data; 9479 if (l2_decap_conf.select_vlan) 9480 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9481 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9482 header += sizeof(struct rte_ether_hdr); 9483 if (l2_decap_conf.select_vlan) { 9484 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9485 header += sizeof(struct rte_vlan_hdr); 9486 } 9487 action_decap_data->conf.size = header - 9488 action_decap_data->data; 9489 action->conf = &action_decap_data->conf; 9490 return ret; 9491 } 9492 9493 #define ETHER_TYPE_MPLS_UNICAST 0x8847 9494 9495 /** Parse MPLSOGRE encap action. */ 9496 static int 9497 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 9498 const char *str, unsigned int len, 9499 void *buf, unsigned int size) 9500 { 9501 struct buffer *out = buf; 9502 struct rte_flow_action *action; 9503 struct action_raw_encap_data *action_encap_data; 9504 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9505 struct rte_flow_item_vlan vlan = { 9506 .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, 9507 .hdr.eth_proto = 0, 9508 }; 9509 struct rte_flow_item_ipv4 ipv4 = { 9510 .hdr = { 9511 .src_addr = mplsogre_encap_conf.ipv4_src, 9512 .dst_addr = mplsogre_encap_conf.ipv4_dst, 9513 .next_proto_id = IPPROTO_GRE, 9514 .version_ihl = RTE_IPV4_VHL_DEF, 9515 .time_to_live = IPDEFTTL, 9516 }, 9517 }; 9518 struct rte_flow_item_ipv6 ipv6 = { 9519 .hdr = { 9520 .proto = IPPROTO_GRE, 9521 .hop_limits = IPDEFTTL, 9522 }, 9523 }; 9524 struct rte_flow_item_gre gre = { 9525 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9526 }; 9527 struct rte_flow_item_mpls mpls = { 9528 .ttl = 0, 9529 }; 9530 uint8_t *header; 9531 int ret; 9532 9533 ret = parse_vc(ctx, token, str, len, buf, size); 9534 if (ret < 0) 9535 return ret; 9536 /* Nothing else to do if there is no buffer. */ 9537 if (!out) 9538 return ret; 9539 if (!out->args.vc.actions_n) 9540 return -1; 9541 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9542 /* Point to selected object. */ 9543 ctx->object = out->args.vc.data; 9544 ctx->objmask = NULL; 9545 /* Copy the headers to the buffer. */ 9546 action_encap_data = ctx->object; 9547 *action_encap_data = (struct action_raw_encap_data) { 9548 .conf = (struct rte_flow_action_raw_encap){ 9549 .data = action_encap_data->data, 9550 }, 9551 .data = {}, 9552 .preserve = {}, 9553 }; 9554 header = action_encap_data->data; 9555 if (mplsogre_encap_conf.select_vlan) 9556 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9557 else if (mplsogre_encap_conf.select_ipv4) 9558 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9559 else 9560 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9561 memcpy(eth.hdr.dst_addr.addr_bytes, 9562 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9563 memcpy(eth.hdr.src_addr.addr_bytes, 9564 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9565 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9566 header += sizeof(struct rte_ether_hdr); 9567 if (mplsogre_encap_conf.select_vlan) { 9568 if (mplsogre_encap_conf.select_ipv4) 9569 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9570 else 9571 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9572 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9573 header += sizeof(struct rte_vlan_hdr); 9574 } 9575 if (mplsogre_encap_conf.select_ipv4) { 9576 memcpy(header, &ipv4, sizeof(ipv4)); 9577 header += sizeof(ipv4); 9578 } else { 9579 memcpy(&ipv6.hdr.src_addr, 9580 &mplsogre_encap_conf.ipv6_src, 9581 sizeof(mplsogre_encap_conf.ipv6_src)); 9582 memcpy(&ipv6.hdr.dst_addr, 9583 &mplsogre_encap_conf.ipv6_dst, 9584 sizeof(mplsogre_encap_conf.ipv6_dst)); 9585 memcpy(header, &ipv6, sizeof(ipv6)); 9586 header += sizeof(ipv6); 9587 } 9588 memcpy(header, &gre, sizeof(gre)); 9589 header += sizeof(gre); 9590 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 9591 RTE_DIM(mplsogre_encap_conf.label)); 9592 mpls.label_tc_s[2] |= 0x1; 9593 memcpy(header, &mpls, sizeof(mpls)); 9594 header += sizeof(mpls); 9595 action_encap_data->conf.size = header - 9596 action_encap_data->data; 9597 action->conf = &action_encap_data->conf; 9598 return ret; 9599 } 9600 9601 /** Parse MPLSOGRE decap action. */ 9602 static int 9603 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 9604 const char *str, unsigned int len, 9605 void *buf, unsigned int size) 9606 { 9607 struct buffer *out = buf; 9608 struct rte_flow_action *action; 9609 struct action_raw_decap_data *action_decap_data; 9610 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9611 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9612 struct rte_flow_item_ipv4 ipv4 = { 9613 .hdr = { 9614 .next_proto_id = IPPROTO_GRE, 9615 }, 9616 }; 9617 struct rte_flow_item_ipv6 ipv6 = { 9618 .hdr = { 9619 .proto = IPPROTO_GRE, 9620 }, 9621 }; 9622 struct rte_flow_item_gre gre = { 9623 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9624 }; 9625 struct rte_flow_item_mpls mpls; 9626 uint8_t *header; 9627 int ret; 9628 9629 ret = parse_vc(ctx, token, str, len, buf, size); 9630 if (ret < 0) 9631 return ret; 9632 /* Nothing else to do if there is no buffer. */ 9633 if (!out) 9634 return ret; 9635 if (!out->args.vc.actions_n) 9636 return -1; 9637 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9638 /* Point to selected object. */ 9639 ctx->object = out->args.vc.data; 9640 ctx->objmask = NULL; 9641 /* Copy the headers to the buffer. */ 9642 action_decap_data = ctx->object; 9643 *action_decap_data = (struct action_raw_decap_data) { 9644 .conf = (struct rte_flow_action_raw_decap){ 9645 .data = action_decap_data->data, 9646 }, 9647 .data = {}, 9648 }; 9649 header = action_decap_data->data; 9650 if (mplsogre_decap_conf.select_vlan) 9651 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9652 else if (mplsogre_encap_conf.select_ipv4) 9653 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9654 else 9655 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9656 memcpy(eth.hdr.dst_addr.addr_bytes, 9657 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9658 memcpy(eth.hdr.src_addr.addr_bytes, 9659 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9660 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9661 header += sizeof(struct rte_ether_hdr); 9662 if (mplsogre_encap_conf.select_vlan) { 9663 if (mplsogre_encap_conf.select_ipv4) 9664 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9665 else 9666 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9667 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9668 header += sizeof(struct rte_vlan_hdr); 9669 } 9670 if (mplsogre_encap_conf.select_ipv4) { 9671 memcpy(header, &ipv4, sizeof(ipv4)); 9672 header += sizeof(ipv4); 9673 } else { 9674 memcpy(header, &ipv6, sizeof(ipv6)); 9675 header += sizeof(ipv6); 9676 } 9677 memcpy(header, &gre, sizeof(gre)); 9678 header += sizeof(gre); 9679 memset(&mpls, 0, sizeof(mpls)); 9680 memcpy(header, &mpls, sizeof(mpls)); 9681 header += sizeof(mpls); 9682 action_decap_data->conf.size = header - 9683 action_decap_data->data; 9684 action->conf = &action_decap_data->conf; 9685 return ret; 9686 } 9687 9688 /** Parse MPLSOUDP encap action. */ 9689 static int 9690 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 9691 const char *str, unsigned int len, 9692 void *buf, unsigned int size) 9693 { 9694 struct buffer *out = buf; 9695 struct rte_flow_action *action; 9696 struct action_raw_encap_data *action_encap_data; 9697 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9698 struct rte_flow_item_vlan vlan = { 9699 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9700 .hdr.eth_proto = 0, 9701 }; 9702 struct rte_flow_item_ipv4 ipv4 = { 9703 .hdr = { 9704 .src_addr = mplsoudp_encap_conf.ipv4_src, 9705 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 9706 .next_proto_id = IPPROTO_UDP, 9707 .version_ihl = RTE_IPV4_VHL_DEF, 9708 .time_to_live = IPDEFTTL, 9709 }, 9710 }; 9711 struct rte_flow_item_ipv6 ipv6 = { 9712 .hdr = { 9713 .proto = IPPROTO_UDP, 9714 .hop_limits = IPDEFTTL, 9715 }, 9716 }; 9717 struct rte_flow_item_udp udp = { 9718 .hdr = { 9719 .src_port = mplsoudp_encap_conf.udp_src, 9720 .dst_port = mplsoudp_encap_conf.udp_dst, 9721 }, 9722 }; 9723 struct rte_flow_item_mpls mpls; 9724 uint8_t *header; 9725 int ret; 9726 9727 ret = parse_vc(ctx, token, str, len, buf, size); 9728 if (ret < 0) 9729 return ret; 9730 /* Nothing else to do if there is no buffer. */ 9731 if (!out) 9732 return ret; 9733 if (!out->args.vc.actions_n) 9734 return -1; 9735 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9736 /* Point to selected object. */ 9737 ctx->object = out->args.vc.data; 9738 ctx->objmask = NULL; 9739 /* Copy the headers to the buffer. */ 9740 action_encap_data = ctx->object; 9741 *action_encap_data = (struct action_raw_encap_data) { 9742 .conf = (struct rte_flow_action_raw_encap){ 9743 .data = action_encap_data->data, 9744 }, 9745 .data = {}, 9746 .preserve = {}, 9747 }; 9748 header = action_encap_data->data; 9749 if (mplsoudp_encap_conf.select_vlan) 9750 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9751 else if (mplsoudp_encap_conf.select_ipv4) 9752 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9753 else 9754 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9755 memcpy(eth.hdr.dst_addr.addr_bytes, 9756 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9757 memcpy(eth.hdr.src_addr.addr_bytes, 9758 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9759 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9760 header += sizeof(struct rte_ether_hdr); 9761 if (mplsoudp_encap_conf.select_vlan) { 9762 if (mplsoudp_encap_conf.select_ipv4) 9763 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9764 else 9765 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9766 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9767 header += sizeof(struct rte_vlan_hdr); 9768 } 9769 if (mplsoudp_encap_conf.select_ipv4) { 9770 memcpy(header, &ipv4, sizeof(ipv4)); 9771 header += sizeof(ipv4); 9772 } else { 9773 memcpy(&ipv6.hdr.src_addr, 9774 &mplsoudp_encap_conf.ipv6_src, 9775 sizeof(mplsoudp_encap_conf.ipv6_src)); 9776 memcpy(&ipv6.hdr.dst_addr, 9777 &mplsoudp_encap_conf.ipv6_dst, 9778 sizeof(mplsoudp_encap_conf.ipv6_dst)); 9779 memcpy(header, &ipv6, sizeof(ipv6)); 9780 header += sizeof(ipv6); 9781 } 9782 memcpy(header, &udp, sizeof(udp)); 9783 header += sizeof(udp); 9784 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 9785 RTE_DIM(mplsoudp_encap_conf.label)); 9786 mpls.label_tc_s[2] |= 0x1; 9787 memcpy(header, &mpls, sizeof(mpls)); 9788 header += sizeof(mpls); 9789 action_encap_data->conf.size = header - 9790 action_encap_data->data; 9791 action->conf = &action_encap_data->conf; 9792 return ret; 9793 } 9794 9795 /** Parse MPLSOUDP decap action. */ 9796 static int 9797 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 9798 const char *str, unsigned int len, 9799 void *buf, unsigned int size) 9800 { 9801 struct buffer *out = buf; 9802 struct rte_flow_action *action; 9803 struct action_raw_decap_data *action_decap_data; 9804 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9805 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9806 struct rte_flow_item_ipv4 ipv4 = { 9807 .hdr = { 9808 .next_proto_id = IPPROTO_UDP, 9809 }, 9810 }; 9811 struct rte_flow_item_ipv6 ipv6 = { 9812 .hdr = { 9813 .proto = IPPROTO_UDP, 9814 }, 9815 }; 9816 struct rte_flow_item_udp udp = { 9817 .hdr = { 9818 .dst_port = rte_cpu_to_be_16(6635), 9819 }, 9820 }; 9821 struct rte_flow_item_mpls mpls; 9822 uint8_t *header; 9823 int ret; 9824 9825 ret = parse_vc(ctx, token, str, len, buf, size); 9826 if (ret < 0) 9827 return ret; 9828 /* Nothing else to do if there is no buffer. */ 9829 if (!out) 9830 return ret; 9831 if (!out->args.vc.actions_n) 9832 return -1; 9833 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9834 /* Point to selected object. */ 9835 ctx->object = out->args.vc.data; 9836 ctx->objmask = NULL; 9837 /* Copy the headers to the buffer. */ 9838 action_decap_data = ctx->object; 9839 *action_decap_data = (struct action_raw_decap_data) { 9840 .conf = (struct rte_flow_action_raw_decap){ 9841 .data = action_decap_data->data, 9842 }, 9843 .data = {}, 9844 }; 9845 header = action_decap_data->data; 9846 if (mplsoudp_decap_conf.select_vlan) 9847 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9848 else if (mplsoudp_encap_conf.select_ipv4) 9849 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9850 else 9851 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9852 memcpy(eth.hdr.dst_addr.addr_bytes, 9853 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9854 memcpy(eth.hdr.src_addr.addr_bytes, 9855 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9856 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9857 header += sizeof(struct rte_ether_hdr); 9858 if (mplsoudp_encap_conf.select_vlan) { 9859 if (mplsoudp_encap_conf.select_ipv4) 9860 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9861 else 9862 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9863 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9864 header += sizeof(struct rte_vlan_hdr); 9865 } 9866 if (mplsoudp_encap_conf.select_ipv4) { 9867 memcpy(header, &ipv4, sizeof(ipv4)); 9868 header += sizeof(ipv4); 9869 } else { 9870 memcpy(header, &ipv6, sizeof(ipv6)); 9871 header += sizeof(ipv6); 9872 } 9873 memcpy(header, &udp, sizeof(udp)); 9874 header += sizeof(udp); 9875 memset(&mpls, 0, sizeof(mpls)); 9876 memcpy(header, &mpls, sizeof(mpls)); 9877 header += sizeof(mpls); 9878 action_decap_data->conf.size = header - 9879 action_decap_data->data; 9880 action->conf = &action_decap_data->conf; 9881 return ret; 9882 } 9883 9884 static int 9885 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 9886 const char *str, unsigned int len, void *buf, 9887 unsigned int size) 9888 { 9889 struct action_raw_decap_data *action_raw_decap_data; 9890 struct rte_flow_action *action; 9891 const struct arg *arg; 9892 struct buffer *out = buf; 9893 int ret; 9894 uint16_t idx; 9895 9896 RTE_SET_USED(token); 9897 RTE_SET_USED(buf); 9898 RTE_SET_USED(size); 9899 arg = ARGS_ENTRY_ARB_BOUNDED 9900 (offsetof(struct action_raw_decap_data, idx), 9901 sizeof(((struct action_raw_decap_data *)0)->idx), 9902 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 9903 if (push_args(ctx, arg)) 9904 return -1; 9905 ret = parse_int(ctx, token, str, len, NULL, 0); 9906 if (ret < 0) { 9907 pop_args(ctx); 9908 return -1; 9909 } 9910 if (!ctx->object) 9911 return len; 9912 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9913 action_raw_decap_data = ctx->object; 9914 idx = action_raw_decap_data->idx; 9915 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 9916 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 9917 action->conf = &action_raw_decap_data->conf; 9918 return len; 9919 } 9920 9921 9922 static int 9923 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 9924 const char *str, unsigned int len, void *buf, 9925 unsigned int size) 9926 { 9927 struct action_raw_encap_data *action_raw_encap_data; 9928 struct rte_flow_action *action; 9929 const struct arg *arg; 9930 struct buffer *out = buf; 9931 int ret; 9932 uint16_t idx; 9933 9934 RTE_SET_USED(token); 9935 RTE_SET_USED(buf); 9936 RTE_SET_USED(size); 9937 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 9938 return -1; 9939 arg = ARGS_ENTRY_ARB_BOUNDED 9940 (offsetof(struct action_raw_encap_data, idx), 9941 sizeof(((struct action_raw_encap_data *)0)->idx), 9942 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 9943 if (push_args(ctx, arg)) 9944 return -1; 9945 ret = parse_int(ctx, token, str, len, NULL, 0); 9946 if (ret < 0) { 9947 pop_args(ctx); 9948 return -1; 9949 } 9950 if (!ctx->object) 9951 return len; 9952 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9953 action_raw_encap_data = ctx->object; 9954 idx = action_raw_encap_data->idx; 9955 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 9956 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 9957 action_raw_encap_data->conf.preserve = NULL; 9958 action->conf = &action_raw_encap_data->conf; 9959 return len; 9960 } 9961 9962 static int 9963 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 9964 const char *str, unsigned int len, void *buf, 9965 unsigned int size) 9966 { 9967 struct buffer *out = buf; 9968 int ret; 9969 9970 ret = parse_vc(ctx, token, str, len, buf, size); 9971 if (ret < 0) 9972 return ret; 9973 /* Nothing else to do if there is no buffer. */ 9974 if (!out) 9975 return ret; 9976 if (!out->args.vc.actions_n) 9977 return -1; 9978 /* Point to selected object. */ 9979 ctx->object = out->args.vc.data; 9980 ctx->objmask = NULL; 9981 return ret; 9982 } 9983 9984 static int 9985 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 9986 const char *str, unsigned int len, void *buf, 9987 unsigned int size) 9988 { 9989 struct buffer *out = buf; 9990 struct rte_flow_action *action; 9991 struct action_raw_decap_data *action_raw_decap_data = NULL; 9992 int ret; 9993 9994 ret = parse_vc(ctx, token, str, len, buf, size); 9995 if (ret < 0) 9996 return ret; 9997 /* Nothing else to do if there is no buffer. */ 9998 if (!out) 9999 return ret; 10000 if (!out->args.vc.actions_n) 10001 return -1; 10002 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10003 /* Point to selected object. */ 10004 ctx->object = out->args.vc.data; 10005 ctx->objmask = NULL; 10006 /* Copy the headers to the buffer. */ 10007 action_raw_decap_data = ctx->object; 10008 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 10009 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 10010 action->conf = &action_raw_decap_data->conf; 10011 return ret; 10012 } 10013 10014 static int 10015 parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 10016 const char *str, unsigned int len, void *buf, 10017 unsigned int size) 10018 { 10019 struct buffer *out = buf; 10020 struct rte_flow_action *action; 10021 struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; 10022 int ret; 10023 10024 ret = parse_vc(ctx, token, str, len, buf, size); 10025 if (ret < 0) 10026 return ret; 10027 /* Nothing else to do if there is no buffer. */ 10028 if (!out) 10029 return ret; 10030 if (!out->args.vc.actions_n) 10031 return -1; 10032 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10033 /* Point to selected object. */ 10034 ctx->object = out->args.vc.data; 10035 ctx->objmask = NULL; 10036 /* Copy the headers to the buffer. */ 10037 ipv6_ext_remove_data = ctx->object; 10038 ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; 10039 action->conf = &ipv6_ext_remove_data->conf; 10040 return ret; 10041 } 10042 10043 static int 10044 parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, 10045 const char *str, unsigned int len, void *buf, 10046 unsigned int size) 10047 { 10048 struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; 10049 struct rte_flow_action *action; 10050 const struct arg *arg; 10051 struct buffer *out = buf; 10052 int ret; 10053 uint16_t idx; 10054 10055 RTE_SET_USED(token); 10056 RTE_SET_USED(buf); 10057 RTE_SET_USED(size); 10058 arg = ARGS_ENTRY_ARB_BOUNDED 10059 (offsetof(struct action_ipv6_ext_remove_data, idx), 10060 sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), 10061 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10062 if (push_args(ctx, arg)) 10063 return -1; 10064 ret = parse_int(ctx, token, str, len, NULL, 0); 10065 if (ret < 0) { 10066 pop_args(ctx); 10067 return -1; 10068 } 10069 if (!ctx->object) 10070 return len; 10071 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10072 action_ipv6_ext_remove_data = ctx->object; 10073 idx = action_ipv6_ext_remove_data->idx; 10074 action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; 10075 action->conf = &action_ipv6_ext_remove_data->conf; 10076 return len; 10077 } 10078 10079 static int 10080 parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 10081 const char *str, unsigned int len, void *buf, 10082 unsigned int size) 10083 { 10084 struct buffer *out = buf; 10085 struct rte_flow_action *action; 10086 struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; 10087 int ret; 10088 10089 ret = parse_vc(ctx, token, str, len, buf, size); 10090 if (ret < 0) 10091 return ret; 10092 /* Nothing else to do if there is no buffer. */ 10093 if (!out) 10094 return ret; 10095 if (!out->args.vc.actions_n) 10096 return -1; 10097 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10098 /* Point to selected object. */ 10099 ctx->object = out->args.vc.data; 10100 ctx->objmask = NULL; 10101 /* Copy the headers to the buffer. */ 10102 ipv6_ext_push_data = ctx->object; 10103 ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; 10104 ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; 10105 ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; 10106 action->conf = &ipv6_ext_push_data->conf; 10107 return ret; 10108 } 10109 10110 static int 10111 parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, 10112 const char *str, unsigned int len, void *buf, 10113 unsigned int size) 10114 { 10115 struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; 10116 struct rte_flow_action *action; 10117 const struct arg *arg; 10118 struct buffer *out = buf; 10119 int ret; 10120 uint16_t idx; 10121 10122 RTE_SET_USED(token); 10123 RTE_SET_USED(buf); 10124 RTE_SET_USED(size); 10125 arg = ARGS_ENTRY_ARB_BOUNDED 10126 (offsetof(struct action_ipv6_ext_push_data, idx), 10127 sizeof(((struct action_ipv6_ext_push_data *)0)->idx), 10128 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10129 if (push_args(ctx, arg)) 10130 return -1; 10131 ret = parse_int(ctx, token, str, len, NULL, 0); 10132 if (ret < 0) { 10133 pop_args(ctx); 10134 return -1; 10135 } 10136 if (!ctx->object) 10137 return len; 10138 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10139 action_ipv6_ext_push_data = ctx->object; 10140 idx = action_ipv6_ext_push_data->idx; 10141 action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; 10142 action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; 10143 action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; 10144 action->conf = &action_ipv6_ext_push_data->conf; 10145 return len; 10146 } 10147 10148 static int 10149 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 10150 const char *str, unsigned int len, void *buf, 10151 unsigned int size) 10152 { 10153 int ret; 10154 10155 ret = parse_vc(ctx, token, str, len, buf, size); 10156 if (ret < 0) 10157 return ret; 10158 ret = rte_flow_dynf_metadata_register(); 10159 if (ret < 0) 10160 return -1; 10161 return len; 10162 } 10163 10164 static int 10165 parse_vc_action_sample(struct context *ctx, const struct token *token, 10166 const char *str, unsigned int len, void *buf, 10167 unsigned int size) 10168 { 10169 struct buffer *out = buf; 10170 struct rte_flow_action *action; 10171 struct action_sample_data *action_sample_data = NULL; 10172 static struct rte_flow_action end_action = { 10173 RTE_FLOW_ACTION_TYPE_END, 0 10174 }; 10175 int ret; 10176 10177 ret = parse_vc(ctx, token, str, len, buf, size); 10178 if (ret < 0) 10179 return ret; 10180 /* Nothing else to do if there is no buffer. */ 10181 if (!out) 10182 return ret; 10183 if (!out->args.vc.actions_n) 10184 return -1; 10185 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10186 /* Point to selected object. */ 10187 ctx->object = out->args.vc.data; 10188 ctx->objmask = NULL; 10189 /* Copy the headers to the buffer. */ 10190 action_sample_data = ctx->object; 10191 action_sample_data->conf.actions = &end_action; 10192 action->conf = &action_sample_data->conf; 10193 return ret; 10194 } 10195 10196 static int 10197 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 10198 const char *str, unsigned int len, void *buf, 10199 unsigned int size) 10200 { 10201 struct action_sample_data *action_sample_data; 10202 struct rte_flow_action *action; 10203 const struct arg *arg; 10204 struct buffer *out = buf; 10205 int ret; 10206 uint16_t idx; 10207 10208 RTE_SET_USED(token); 10209 RTE_SET_USED(buf); 10210 RTE_SET_USED(size); 10211 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 10212 return -1; 10213 arg = ARGS_ENTRY_ARB_BOUNDED 10214 (offsetof(struct action_sample_data, idx), 10215 sizeof(((struct action_sample_data *)0)->idx), 10216 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 10217 if (push_args(ctx, arg)) 10218 return -1; 10219 ret = parse_int(ctx, token, str, len, NULL, 0); 10220 if (ret < 0) { 10221 pop_args(ctx); 10222 return -1; 10223 } 10224 if (!ctx->object) 10225 return len; 10226 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10227 action_sample_data = ctx->object; 10228 idx = action_sample_data->idx; 10229 action_sample_data->conf.actions = raw_sample_confs[idx].data; 10230 action->conf = &action_sample_data->conf; 10231 return len; 10232 } 10233 10234 /** Parse operation for modify_field command. */ 10235 static int 10236 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 10237 const char *str, unsigned int len, void *buf, 10238 unsigned int size) 10239 { 10240 struct rte_flow_action_modify_field *action_modify_field; 10241 unsigned int i; 10242 10243 (void)token; 10244 (void)buf; 10245 (void)size; 10246 if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) 10247 return -1; 10248 for (i = 0; modify_field_ops[i]; ++i) 10249 if (!strcmp_partial(modify_field_ops[i], str, len)) 10250 break; 10251 if (!modify_field_ops[i]) 10252 return -1; 10253 if (!ctx->object) 10254 return len; 10255 action_modify_field = ctx->object; 10256 action_modify_field->operation = (enum rte_flow_modify_op)i; 10257 return len; 10258 } 10259 10260 /** Parse id for modify_field command. */ 10261 static int 10262 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 10263 const char *str, unsigned int len, void *buf, 10264 unsigned int size) 10265 { 10266 struct rte_flow_action_modify_field *action_modify_field; 10267 unsigned int i; 10268 10269 (void)token; 10270 (void)buf; 10271 (void)size; 10272 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 10273 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 10274 return -1; 10275 for (i = 0; flow_field_ids[i]; ++i) 10276 if (!strcmp_partial(flow_field_ids[i], str, len)) 10277 break; 10278 if (!flow_field_ids[i]) 10279 return -1; 10280 if (!ctx->object) 10281 return len; 10282 action_modify_field = ctx->object; 10283 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 10284 action_modify_field->dst.field = (enum rte_flow_field_id)i; 10285 else 10286 action_modify_field->src.field = (enum rte_flow_field_id)i; 10287 return len; 10288 } 10289 10290 /** Parse level for modify_field command. */ 10291 static int 10292 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 10293 const char *str, unsigned int len, void *buf, 10294 unsigned int size) 10295 { 10296 struct rte_flow_action_modify_field *action; 10297 struct flex_item *fp = NULL; 10298 uint32_t val; 10299 struct buffer *out = buf; 10300 char *end; 10301 10302 (void)token; 10303 (void)size; 10304 if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10305 ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) 10306 return -1; 10307 if (!ctx->object) 10308 return len; 10309 action = ctx->object; 10310 errno = 0; 10311 val = strtoumax(str, &end, 0); 10312 if (errno || (size_t)(end - str) != len) 10313 return -1; 10314 /* No need to validate action template mask value */ 10315 if (out->args.vc.masks) { 10316 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) 10317 action->dst.level = val; 10318 else 10319 action->src.level = val; 10320 return len; 10321 } 10322 if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10323 action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || 10324 (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && 10325 action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 10326 if (val >= FLEX_MAX_PARSERS_NUM) { 10327 printf("Bad flex item handle\n"); 10328 return -1; 10329 } 10330 fp = flex_items[ctx->port][val]; 10331 if (!fp) { 10332 printf("Bad flex item handle\n"); 10333 return -1; 10334 } 10335 } 10336 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { 10337 if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) 10338 action->dst.level = val; 10339 else 10340 action->dst.flex_handle = fp->flex_handle; 10341 } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { 10342 if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) 10343 action->src.level = val; 10344 else 10345 action->src.flex_handle = fp->flex_handle; 10346 } 10347 return len; 10348 } 10349 10350 /** Parse the conntrack update, not a rte_flow_action. */ 10351 static int 10352 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 10353 const char *str, unsigned int len, void *buf, 10354 unsigned int size) 10355 { 10356 struct buffer *out = buf; 10357 struct rte_flow_modify_conntrack *ct_modify = NULL; 10358 10359 (void)size; 10360 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 10361 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 10362 return -1; 10363 /* Token name must match. */ 10364 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10365 return -1; 10366 /* Nothing else to do if there is no buffer. */ 10367 if (!out) 10368 return len; 10369 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 10370 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 10371 ct_modify->new_ct.is_original_dir = 10372 conntrack_context.is_original_dir; 10373 ct_modify->direction = 1; 10374 } else { 10375 uint32_t old_dir; 10376 10377 old_dir = ct_modify->new_ct.is_original_dir; 10378 memcpy(&ct_modify->new_ct, &conntrack_context, 10379 sizeof(conntrack_context)); 10380 ct_modify->new_ct.is_original_dir = old_dir; 10381 ct_modify->state = 1; 10382 } 10383 return len; 10384 } 10385 10386 /** Parse tokens for destroy command. */ 10387 static int 10388 parse_destroy(struct context *ctx, const struct token *token, 10389 const char *str, unsigned int len, 10390 void *buf, unsigned int size) 10391 { 10392 struct buffer *out = buf; 10393 10394 /* Token name must match. */ 10395 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10396 return -1; 10397 /* Nothing else to do if there is no buffer. */ 10398 if (!out) 10399 return len; 10400 if (!out->command) { 10401 if (ctx->curr != DESTROY) 10402 return -1; 10403 if (sizeof(*out) > size) 10404 return -1; 10405 out->command = ctx->curr; 10406 ctx->objdata = 0; 10407 ctx->object = out; 10408 ctx->objmask = NULL; 10409 out->args.destroy.rule = 10410 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10411 sizeof(double)); 10412 return len; 10413 } 10414 if (ctx->curr == DESTROY_IS_USER_ID) { 10415 out->args.destroy.is_user_id = true; 10416 return len; 10417 } 10418 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 10419 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 10420 return -1; 10421 ctx->objdata = 0; 10422 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 10423 ctx->objmask = NULL; 10424 return len; 10425 } 10426 10427 /** Parse tokens for flush command. */ 10428 static int 10429 parse_flush(struct context *ctx, const struct token *token, 10430 const char *str, unsigned int len, 10431 void *buf, unsigned int size) 10432 { 10433 struct buffer *out = buf; 10434 10435 /* Token name must match. */ 10436 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10437 return -1; 10438 /* Nothing else to do if there is no buffer. */ 10439 if (!out) 10440 return len; 10441 if (!out->command) { 10442 if (ctx->curr != FLUSH) 10443 return -1; 10444 if (sizeof(*out) > size) 10445 return -1; 10446 out->command = ctx->curr; 10447 ctx->objdata = 0; 10448 ctx->object = out; 10449 ctx->objmask = NULL; 10450 } 10451 return len; 10452 } 10453 10454 /** Parse tokens for dump command. */ 10455 static int 10456 parse_dump(struct context *ctx, const struct token *token, 10457 const char *str, unsigned int len, 10458 void *buf, unsigned int size) 10459 { 10460 struct buffer *out = buf; 10461 10462 /* Token name must match. */ 10463 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10464 return -1; 10465 /* Nothing else to do if there is no buffer. */ 10466 if (!out) 10467 return len; 10468 if (!out->command) { 10469 if (ctx->curr != DUMP) 10470 return -1; 10471 if (sizeof(*out) > size) 10472 return -1; 10473 out->command = ctx->curr; 10474 ctx->objdata = 0; 10475 ctx->object = out; 10476 ctx->objmask = NULL; 10477 return len; 10478 } 10479 switch (ctx->curr) { 10480 case DUMP_ALL: 10481 case DUMP_ONE: 10482 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 10483 out->command = ctx->curr; 10484 ctx->objdata = 0; 10485 ctx->object = out; 10486 ctx->objmask = NULL; 10487 return len; 10488 case DUMP_IS_USER_ID: 10489 out->args.dump.is_user_id = true; 10490 return len; 10491 default: 10492 return -1; 10493 } 10494 } 10495 10496 /** Parse tokens for query command. */ 10497 static int 10498 parse_query(struct context *ctx, const struct token *token, 10499 const char *str, unsigned int len, 10500 void *buf, unsigned int size) 10501 { 10502 struct buffer *out = buf; 10503 10504 /* Token name must match. */ 10505 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10506 return -1; 10507 /* Nothing else to do if there is no buffer. */ 10508 if (!out) 10509 return len; 10510 if (!out->command) { 10511 if (ctx->curr != QUERY) 10512 return -1; 10513 if (sizeof(*out) > size) 10514 return -1; 10515 out->command = ctx->curr; 10516 ctx->objdata = 0; 10517 ctx->object = out; 10518 ctx->objmask = NULL; 10519 } 10520 if (ctx->curr == QUERY_IS_USER_ID) { 10521 out->args.query.is_user_id = true; 10522 return len; 10523 } 10524 return len; 10525 } 10526 10527 /** Parse action names. */ 10528 static int 10529 parse_action(struct context *ctx, const struct token *token, 10530 const char *str, unsigned int len, 10531 void *buf, unsigned int size) 10532 { 10533 struct buffer *out = buf; 10534 const struct arg *arg = pop_args(ctx); 10535 unsigned int i; 10536 10537 (void)size; 10538 /* Argument is expected. */ 10539 if (!arg) 10540 return -1; 10541 /* Parse action name. */ 10542 for (i = 0; next_action[i]; ++i) { 10543 const struct parse_action_priv *priv; 10544 10545 token = &token_list[next_action[i]]; 10546 if (strcmp_partial(token->name, str, len)) 10547 continue; 10548 priv = token->priv; 10549 if (!priv) 10550 goto error; 10551 if (out) 10552 memcpy((uint8_t *)ctx->object + arg->offset, 10553 &priv->type, 10554 arg->size); 10555 return len; 10556 } 10557 error: 10558 push_args(ctx, arg); 10559 return -1; 10560 } 10561 10562 /** Parse tokens for list command. */ 10563 static int 10564 parse_list(struct context *ctx, const struct token *token, 10565 const char *str, unsigned int len, 10566 void *buf, unsigned int size) 10567 { 10568 struct buffer *out = buf; 10569 10570 /* Token name must match. */ 10571 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10572 return -1; 10573 /* Nothing else to do if there is no buffer. */ 10574 if (!out) 10575 return len; 10576 if (!out->command) { 10577 if (ctx->curr != LIST) 10578 return -1; 10579 if (sizeof(*out) > size) 10580 return -1; 10581 out->command = ctx->curr; 10582 ctx->objdata = 0; 10583 ctx->object = out; 10584 ctx->objmask = NULL; 10585 out->args.list.group = 10586 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10587 sizeof(double)); 10588 return len; 10589 } 10590 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 10591 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 10592 return -1; 10593 ctx->objdata = 0; 10594 ctx->object = out->args.list.group + out->args.list.group_n++; 10595 ctx->objmask = NULL; 10596 return len; 10597 } 10598 10599 /** Parse tokens for list all aged flows command. */ 10600 static int 10601 parse_aged(struct context *ctx, const struct token *token, 10602 const char *str, unsigned int len, 10603 void *buf, unsigned int size) 10604 { 10605 struct buffer *out = buf; 10606 10607 /* Token name must match. */ 10608 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10609 return -1; 10610 /* Nothing else to do if there is no buffer. */ 10611 if (!out) 10612 return len; 10613 if (!out->command || out->command == QUEUE) { 10614 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 10615 return -1; 10616 if (sizeof(*out) > size) 10617 return -1; 10618 out->command = ctx->curr; 10619 ctx->objdata = 0; 10620 ctx->object = out; 10621 ctx->objmask = NULL; 10622 } 10623 if (ctx->curr == AGED_DESTROY) 10624 out->args.aged.destroy = 1; 10625 return len; 10626 } 10627 10628 /** Parse tokens for isolate command. */ 10629 static int 10630 parse_isolate(struct context *ctx, const struct token *token, 10631 const char *str, unsigned int len, 10632 void *buf, unsigned int size) 10633 { 10634 struct buffer *out = buf; 10635 10636 /* Token name must match. */ 10637 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10638 return -1; 10639 /* Nothing else to do if there is no buffer. */ 10640 if (!out) 10641 return len; 10642 if (!out->command) { 10643 if (ctx->curr != ISOLATE) 10644 return -1; 10645 if (sizeof(*out) > size) 10646 return -1; 10647 out->command = ctx->curr; 10648 ctx->objdata = 0; 10649 ctx->object = out; 10650 ctx->objmask = NULL; 10651 } 10652 return len; 10653 } 10654 10655 /** Parse tokens for info/configure command. */ 10656 static int 10657 parse_configure(struct context *ctx, const struct token *token, 10658 const char *str, unsigned int len, 10659 void *buf, unsigned int size) 10660 { 10661 struct buffer *out = buf; 10662 10663 /* Token name must match. */ 10664 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10665 return -1; 10666 /* Nothing else to do if there is no buffer. */ 10667 if (!out) 10668 return len; 10669 if (!out->command) { 10670 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 10671 return -1; 10672 if (sizeof(*out) > size) 10673 return -1; 10674 out->command = ctx->curr; 10675 ctx->objdata = 0; 10676 ctx->object = out; 10677 ctx->objmask = NULL; 10678 } 10679 return len; 10680 } 10681 10682 /** Parse tokens for template create command. */ 10683 static int 10684 parse_template(struct context *ctx, const struct token *token, 10685 const char *str, unsigned int len, 10686 void *buf, unsigned int size) 10687 { 10688 struct buffer *out = buf; 10689 10690 /* Token name must match. */ 10691 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10692 return -1; 10693 /* Nothing else to do if there is no buffer. */ 10694 if (!out) 10695 return len; 10696 if (!out->command) { 10697 if (ctx->curr != PATTERN_TEMPLATE && 10698 ctx->curr != ACTIONS_TEMPLATE) 10699 return -1; 10700 if (sizeof(*out) > size) 10701 return -1; 10702 out->command = ctx->curr; 10703 ctx->objdata = 0; 10704 ctx->object = out; 10705 ctx->objmask = NULL; 10706 out->args.vc.data = (uint8_t *)out + size; 10707 return len; 10708 } 10709 switch (ctx->curr) { 10710 case PATTERN_TEMPLATE_CREATE: 10711 out->args.vc.pattern = 10712 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10713 sizeof(double)); 10714 out->args.vc.pat_templ_id = UINT32_MAX; 10715 out->command = ctx->curr; 10716 ctx->objdata = 0; 10717 ctx->object = out; 10718 ctx->objmask = NULL; 10719 return len; 10720 case PATTERN_TEMPLATE_EGRESS: 10721 out->args.vc.attr.egress = 1; 10722 return len; 10723 case PATTERN_TEMPLATE_INGRESS: 10724 out->args.vc.attr.ingress = 1; 10725 return len; 10726 case PATTERN_TEMPLATE_TRANSFER: 10727 out->args.vc.attr.transfer = 1; 10728 return len; 10729 case ACTIONS_TEMPLATE_CREATE: 10730 out->args.vc.act_templ_id = UINT32_MAX; 10731 out->command = ctx->curr; 10732 ctx->objdata = 0; 10733 ctx->object = out; 10734 ctx->objmask = NULL; 10735 return len; 10736 case ACTIONS_TEMPLATE_SPEC: 10737 out->args.vc.actions = 10738 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10739 sizeof(double)); 10740 ctx->object = out->args.vc.actions; 10741 ctx->objmask = NULL; 10742 return len; 10743 case ACTIONS_TEMPLATE_MASK: 10744 out->args.vc.masks = 10745 (void *)RTE_ALIGN_CEIL((uintptr_t) 10746 (out->args.vc.actions + 10747 out->args.vc.actions_n), 10748 sizeof(double)); 10749 ctx->object = out->args.vc.masks; 10750 ctx->objmask = NULL; 10751 return len; 10752 case ACTIONS_TEMPLATE_EGRESS: 10753 out->args.vc.attr.egress = 1; 10754 return len; 10755 case ACTIONS_TEMPLATE_INGRESS: 10756 out->args.vc.attr.ingress = 1; 10757 return len; 10758 case ACTIONS_TEMPLATE_TRANSFER: 10759 out->args.vc.attr.transfer = 1; 10760 return len; 10761 default: 10762 return -1; 10763 } 10764 } 10765 10766 /** Parse tokens for template destroy command. */ 10767 static int 10768 parse_template_destroy(struct context *ctx, const struct token *token, 10769 const char *str, unsigned int len, 10770 void *buf, unsigned int size) 10771 { 10772 struct buffer *out = buf; 10773 uint32_t *template_id; 10774 10775 /* Token name must match. */ 10776 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10777 return -1; 10778 /* Nothing else to do if there is no buffer. */ 10779 if (!out) 10780 return len; 10781 if (!out->command || 10782 out->command == PATTERN_TEMPLATE || 10783 out->command == ACTIONS_TEMPLATE) { 10784 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 10785 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 10786 return -1; 10787 if (sizeof(*out) > size) 10788 return -1; 10789 out->command = ctx->curr; 10790 ctx->objdata = 0; 10791 ctx->object = out; 10792 ctx->objmask = NULL; 10793 out->args.templ_destroy.template_id = 10794 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10795 sizeof(double)); 10796 return len; 10797 } 10798 template_id = out->args.templ_destroy.template_id 10799 + out->args.templ_destroy.template_id_n++; 10800 if ((uint8_t *)template_id > (uint8_t *)out + size) 10801 return -1; 10802 ctx->objdata = 0; 10803 ctx->object = template_id; 10804 ctx->objmask = NULL; 10805 return len; 10806 } 10807 10808 /** Parse tokens for table create command. */ 10809 static int 10810 parse_table(struct context *ctx, const struct token *token, 10811 const char *str, unsigned int len, 10812 void *buf, unsigned int size) 10813 { 10814 struct buffer *out = buf; 10815 uint32_t *template_id; 10816 10817 /* Token name must match. */ 10818 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10819 return -1; 10820 /* Nothing else to do if there is no buffer. */ 10821 if (!out) 10822 return len; 10823 if (!out->command) { 10824 if (ctx->curr != TABLE) 10825 return -1; 10826 if (sizeof(*out) > size) 10827 return -1; 10828 out->command = ctx->curr; 10829 ctx->objdata = 0; 10830 ctx->object = out; 10831 ctx->objmask = NULL; 10832 return len; 10833 } 10834 switch (ctx->curr) { 10835 case TABLE_CREATE: 10836 case TABLE_RESIZE: 10837 out->command = ctx->curr; 10838 ctx->objdata = 0; 10839 ctx->object = out; 10840 ctx->objmask = NULL; 10841 out->args.table.id = UINT32_MAX; 10842 return len; 10843 case TABLE_PATTERN_TEMPLATE: 10844 out->args.table.pat_templ_id = 10845 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10846 sizeof(double)); 10847 template_id = out->args.table.pat_templ_id 10848 + out->args.table.pat_templ_id_n++; 10849 if ((uint8_t *)template_id > (uint8_t *)out + size) 10850 return -1; 10851 ctx->objdata = 0; 10852 ctx->object = template_id; 10853 ctx->objmask = NULL; 10854 return len; 10855 case TABLE_ACTIONS_TEMPLATE: 10856 out->args.table.act_templ_id = 10857 (void *)RTE_ALIGN_CEIL((uintptr_t) 10858 (out->args.table.pat_templ_id + 10859 out->args.table.pat_templ_id_n), 10860 sizeof(double)); 10861 template_id = out->args.table.act_templ_id 10862 + out->args.table.act_templ_id_n++; 10863 if ((uint8_t *)template_id > (uint8_t *)out + size) 10864 return -1; 10865 ctx->objdata = 0; 10866 ctx->object = template_id; 10867 ctx->objmask = NULL; 10868 return len; 10869 case TABLE_INGRESS: 10870 out->args.table.attr.flow_attr.ingress = 1; 10871 return len; 10872 case TABLE_EGRESS: 10873 out->args.table.attr.flow_attr.egress = 1; 10874 return len; 10875 case TABLE_TRANSFER: 10876 out->args.table.attr.flow_attr.transfer = 1; 10877 return len; 10878 case TABLE_TRANSFER_WIRE_ORIG: 10879 if (!out->args.table.attr.flow_attr.transfer) 10880 return -1; 10881 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; 10882 return len; 10883 case TABLE_TRANSFER_VPORT_ORIG: 10884 if (!out->args.table.attr.flow_attr.transfer) 10885 return -1; 10886 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; 10887 return len; 10888 case TABLE_RESIZABLE: 10889 out->args.table.attr.specialize |= 10890 RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE; 10891 return len; 10892 case TABLE_RULES_NUMBER: 10893 ctx->objdata = 0; 10894 ctx->object = out; 10895 ctx->objmask = NULL; 10896 return len; 10897 case TABLE_RESIZE_ID: 10898 case TABLE_RESIZE_RULES_NUMBER: 10899 return len; 10900 default: 10901 return -1; 10902 } 10903 } 10904 10905 /** Parse tokens for table destroy command. */ 10906 static int 10907 parse_table_destroy(struct context *ctx, const struct token *token, 10908 const char *str, unsigned int len, 10909 void *buf, unsigned int size) 10910 { 10911 struct buffer *out = buf; 10912 uint32_t *table_id; 10913 10914 /* Token name must match. */ 10915 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10916 return -1; 10917 /* Nothing else to do if there is no buffer. */ 10918 if (!out) 10919 return len; 10920 if (!out->command || out->command == TABLE) { 10921 if (ctx->curr != TABLE_DESTROY && 10922 ctx->curr != TABLE_RESIZE_COMPLETE) 10923 return -1; 10924 if (sizeof(*out) > size) 10925 return -1; 10926 out->command = ctx->curr; 10927 ctx->objdata = 0; 10928 ctx->object = out; 10929 ctx->objmask = NULL; 10930 out->args.table_destroy.table_id = 10931 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10932 sizeof(double)); 10933 return len; 10934 } 10935 table_id = out->args.table_destroy.table_id 10936 + out->args.table_destroy.table_id_n++; 10937 if ((uint8_t *)table_id > (uint8_t *)out + size) 10938 return -1; 10939 ctx->objdata = 0; 10940 ctx->object = table_id; 10941 ctx->objmask = NULL; 10942 return len; 10943 } 10944 10945 /** Parse tokens for queue create commands. */ 10946 static int 10947 parse_qo(struct context *ctx, const struct token *token, 10948 const char *str, unsigned int len, 10949 void *buf, unsigned int size) 10950 { 10951 struct buffer *out = buf; 10952 10953 /* Token name must match. */ 10954 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10955 return -1; 10956 /* Nothing else to do if there is no buffer. */ 10957 if (!out) 10958 return len; 10959 if (!out->command) { 10960 if (ctx->curr != QUEUE) 10961 return -1; 10962 if (sizeof(*out) > size) 10963 return -1; 10964 out->command = ctx->curr; 10965 ctx->objdata = 0; 10966 ctx->object = out; 10967 ctx->objmask = NULL; 10968 out->args.vc.data = (uint8_t *)out + size; 10969 return len; 10970 } 10971 switch (ctx->curr) { 10972 case QUEUE_CREATE: 10973 case QUEUE_UPDATE: 10974 out->command = ctx->curr; 10975 ctx->objdata = 0; 10976 ctx->object = out; 10977 ctx->objmask = NULL; 10978 out->args.vc.rule_id = UINT32_MAX; 10979 return len; 10980 case QUEUE_TEMPLATE_TABLE: 10981 case QUEUE_PATTERN_TEMPLATE: 10982 case QUEUE_ACTIONS_TEMPLATE: 10983 case QUEUE_CREATE_POSTPONE: 10984 case QUEUE_RULE_ID: 10985 case QUEUE_UPDATE_ID: 10986 return len; 10987 case ITEM_PATTERN: 10988 out->args.vc.pattern = 10989 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10990 sizeof(double)); 10991 ctx->object = out->args.vc.pattern; 10992 ctx->objmask = NULL; 10993 return len; 10994 case ACTIONS: 10995 out->args.vc.actions = 10996 (void *)RTE_ALIGN_CEIL((uintptr_t) 10997 (out->args.vc.pattern + 10998 out->args.vc.pattern_n), 10999 sizeof(double)); 11000 ctx->object = out->args.vc.actions; 11001 ctx->objmask = NULL; 11002 return len; 11003 default: 11004 return -1; 11005 } 11006 } 11007 11008 /** Parse tokens for queue destroy command. */ 11009 static int 11010 parse_qo_destroy(struct context *ctx, const struct token *token, 11011 const char *str, unsigned int len, 11012 void *buf, unsigned int size) 11013 { 11014 struct buffer *out = buf; 11015 uint64_t *flow_id; 11016 11017 /* Token name must match. */ 11018 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11019 return -1; 11020 /* Nothing else to do if there is no buffer. */ 11021 if (!out) 11022 return len; 11023 if (!out->command || out->command == QUEUE) { 11024 if (ctx->curr != QUEUE_DESTROY && 11025 ctx->curr != QUEUE_FLOW_UPDATE_RESIZED) 11026 return -1; 11027 if (sizeof(*out) > size) 11028 return -1; 11029 out->command = ctx->curr; 11030 ctx->objdata = 0; 11031 ctx->object = out; 11032 ctx->objmask = NULL; 11033 out->args.destroy.rule = 11034 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11035 sizeof(double)); 11036 return len; 11037 } 11038 switch (ctx->curr) { 11039 case QUEUE_DESTROY_ID: 11040 flow_id = out->args.destroy.rule 11041 + out->args.destroy.rule_n++; 11042 if ((uint8_t *)flow_id > (uint8_t *)out + size) 11043 return -1; 11044 ctx->objdata = 0; 11045 ctx->object = flow_id; 11046 ctx->objmask = NULL; 11047 return len; 11048 case QUEUE_DESTROY_POSTPONE: 11049 return len; 11050 default: 11051 return -1; 11052 } 11053 } 11054 11055 /** Parse tokens for push queue command. */ 11056 static int 11057 parse_push(struct context *ctx, const struct token *token, 11058 const char *str, unsigned int len, 11059 void *buf, unsigned int size) 11060 { 11061 struct buffer *out = buf; 11062 11063 /* Token name must match. */ 11064 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11065 return -1; 11066 /* Nothing else to do if there is no buffer. */ 11067 if (!out) 11068 return len; 11069 if (!out->command) { 11070 if (ctx->curr != PUSH) 11071 return -1; 11072 if (sizeof(*out) > size) 11073 return -1; 11074 out->command = ctx->curr; 11075 ctx->objdata = 0; 11076 ctx->object = out; 11077 ctx->objmask = NULL; 11078 out->args.vc.data = (uint8_t *)out + size; 11079 } 11080 return len; 11081 } 11082 11083 /** Parse tokens for pull command. */ 11084 static int 11085 parse_pull(struct context *ctx, const struct token *token, 11086 const char *str, unsigned int len, 11087 void *buf, unsigned int size) 11088 { 11089 struct buffer *out = buf; 11090 11091 /* Token name must match. */ 11092 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11093 return -1; 11094 /* Nothing else to do if there is no buffer. */ 11095 if (!out) 11096 return len; 11097 if (!out->command) { 11098 if (ctx->curr != PULL) 11099 return -1; 11100 if (sizeof(*out) > size) 11101 return -1; 11102 out->command = ctx->curr; 11103 ctx->objdata = 0; 11104 ctx->object = out; 11105 ctx->objmask = NULL; 11106 out->args.vc.data = (uint8_t *)out + size; 11107 } 11108 return len; 11109 } 11110 11111 /** Parse tokens for hash calculation commands. */ 11112 static int 11113 parse_hash(struct context *ctx, const struct token *token, 11114 const char *str, unsigned int len, 11115 void *buf, unsigned int size) 11116 { 11117 struct buffer *out = buf; 11118 11119 /* Token name must match. */ 11120 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11121 return -1; 11122 /* Nothing else to do if there is no buffer. */ 11123 if (!out) 11124 return len; 11125 if (!out->command) { 11126 if (ctx->curr != HASH) 11127 return -1; 11128 if (sizeof(*out) > size) 11129 return -1; 11130 out->command = ctx->curr; 11131 ctx->objdata = 0; 11132 ctx->object = out; 11133 ctx->objmask = NULL; 11134 out->args.vc.data = (uint8_t *)out + size; 11135 return len; 11136 } 11137 switch (ctx->curr) { 11138 case HASH_CALC_TABLE: 11139 case HASH_CALC_PATTERN_INDEX: 11140 return len; 11141 case ITEM_PATTERN: 11142 out->args.vc.pattern = 11143 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11144 sizeof(double)); 11145 ctx->object = out->args.vc.pattern; 11146 ctx->objmask = NULL; 11147 return len; 11148 case HASH_CALC_ENCAP: 11149 out->args.vc.encap_hash = 1; 11150 return len; 11151 case ENCAP_HASH_FIELD_SRC_PORT: 11152 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT; 11153 return len; 11154 case ENCAP_HASH_FIELD_GRE_FLOW_ID: 11155 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID; 11156 return len; 11157 default: 11158 return -1; 11159 } 11160 } 11161 11162 static int 11163 parse_group(struct context *ctx, const struct token *token, 11164 const char *str, unsigned int len, 11165 void *buf, unsigned int size) 11166 { 11167 struct buffer *out = buf; 11168 11169 /* Token name must match. */ 11170 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11171 return -1; 11172 /* Nothing else to do if there is no buffer. */ 11173 if (!out) 11174 return len; 11175 if (!out->command) { 11176 if (ctx->curr != FLOW_GROUP) 11177 return -1; 11178 if (sizeof(*out) > size) 11179 return -1; 11180 out->command = ctx->curr; 11181 ctx->objdata = 0; 11182 ctx->object = out; 11183 ctx->objmask = NULL; 11184 out->args.vc.data = (uint8_t *)out + size; 11185 return len; 11186 } 11187 switch (ctx->curr) { 11188 case GROUP_INGRESS: 11189 out->args.vc.attr.ingress = 1; 11190 return len; 11191 case GROUP_EGRESS: 11192 out->args.vc.attr.egress = 1; 11193 return len; 11194 case GROUP_TRANSFER: 11195 out->args.vc.attr.transfer = 1; 11196 return len; 11197 case GROUP_SET_MISS_ACTIONS: 11198 out->command = ctx->curr; 11199 ctx->objdata = 0; 11200 ctx->object = out; 11201 ctx->objmask = NULL; 11202 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11203 sizeof(double)); 11204 return len; 11205 default: 11206 return -1; 11207 } 11208 } 11209 11210 static int 11211 parse_flex(struct context *ctx, const struct token *token, 11212 const char *str, unsigned int len, 11213 void *buf, unsigned int size) 11214 { 11215 struct buffer *out = buf; 11216 11217 /* Token name must match. */ 11218 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11219 return -1; 11220 /* Nothing else to do if there is no buffer. */ 11221 if (!out) 11222 return len; 11223 if (out->command == ZERO) { 11224 if (ctx->curr != FLEX) 11225 return -1; 11226 if (sizeof(*out) > size) 11227 return -1; 11228 out->command = ctx->curr; 11229 ctx->objdata = 0; 11230 ctx->object = out; 11231 ctx->objmask = NULL; 11232 } else { 11233 switch (ctx->curr) { 11234 default: 11235 break; 11236 case FLEX_ITEM_INIT: 11237 case FLEX_ITEM_CREATE: 11238 case FLEX_ITEM_DESTROY: 11239 out->command = ctx->curr; 11240 break; 11241 } 11242 } 11243 11244 return len; 11245 } 11246 11247 static int 11248 parse_tunnel(struct context *ctx, const struct token *token, 11249 const char *str, unsigned int len, 11250 void *buf, unsigned int size) 11251 { 11252 struct buffer *out = buf; 11253 11254 /* Token name must match. */ 11255 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11256 return -1; 11257 /* Nothing else to do if there is no buffer. */ 11258 if (!out) 11259 return len; 11260 if (!out->command) { 11261 if (ctx->curr != TUNNEL) 11262 return -1; 11263 if (sizeof(*out) > size) 11264 return -1; 11265 out->command = ctx->curr; 11266 ctx->objdata = 0; 11267 ctx->object = out; 11268 ctx->objmask = NULL; 11269 } else { 11270 switch (ctx->curr) { 11271 default: 11272 break; 11273 case TUNNEL_CREATE: 11274 case TUNNEL_DESTROY: 11275 case TUNNEL_LIST: 11276 out->command = ctx->curr; 11277 break; 11278 case TUNNEL_CREATE_TYPE: 11279 case TUNNEL_DESTROY_ID: 11280 ctx->object = &out->args.vc.tunnel_ops; 11281 break; 11282 } 11283 } 11284 11285 return len; 11286 } 11287 11288 /** 11289 * Parse signed/unsigned integers 8 to 64-bit long. 11290 * 11291 * Last argument (ctx->args) is retrieved to determine integer type and 11292 * storage location. 11293 */ 11294 static int 11295 parse_int(struct context *ctx, const struct token *token, 11296 const char *str, unsigned int len, 11297 void *buf, unsigned int size) 11298 { 11299 const struct arg *arg = pop_args(ctx); 11300 uintmax_t u; 11301 char *end; 11302 11303 (void)token; 11304 /* Argument is expected. */ 11305 if (!arg) 11306 return -1; 11307 errno = 0; 11308 u = arg->sign ? 11309 (uintmax_t)strtoimax(str, &end, 0) : 11310 strtoumax(str, &end, 0); 11311 if (errno || (size_t)(end - str) != len) 11312 goto error; 11313 if (arg->bounded && 11314 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 11315 (intmax_t)u > (intmax_t)arg->max)) || 11316 (!arg->sign && (u < arg->min || u > arg->max)))) 11317 goto error; 11318 if (!ctx->object) 11319 return len; 11320 if (arg->mask) { 11321 if (!arg_entry_bf_fill(ctx->object, u, arg) || 11322 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 11323 goto error; 11324 return len; 11325 } 11326 buf = (uint8_t *)ctx->object + arg->offset; 11327 size = arg->size; 11328 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 11329 return -1; 11330 objmask: 11331 switch (size) { 11332 case sizeof(uint8_t): 11333 *(uint8_t *)buf = u; 11334 break; 11335 case sizeof(uint16_t): 11336 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 11337 break; 11338 case sizeof(uint8_t [3]): 11339 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 11340 if (!arg->hton) { 11341 ((uint8_t *)buf)[0] = u; 11342 ((uint8_t *)buf)[1] = u >> 8; 11343 ((uint8_t *)buf)[2] = u >> 16; 11344 break; 11345 } 11346 #endif 11347 ((uint8_t *)buf)[0] = u >> 16; 11348 ((uint8_t *)buf)[1] = u >> 8; 11349 ((uint8_t *)buf)[2] = u; 11350 break; 11351 case sizeof(uint32_t): 11352 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 11353 break; 11354 case sizeof(uint64_t): 11355 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 11356 break; 11357 default: 11358 goto error; 11359 } 11360 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 11361 u = -1; 11362 buf = (uint8_t *)ctx->objmask + arg->offset; 11363 goto objmask; 11364 } 11365 return len; 11366 error: 11367 push_args(ctx, arg); 11368 return -1; 11369 } 11370 11371 /** 11372 * Parse a string. 11373 * 11374 * Three arguments (ctx->args) are retrieved from the stack to store data, 11375 * its actual length and address (in that order). 11376 */ 11377 static int 11378 parse_string(struct context *ctx, const struct token *token, 11379 const char *str, unsigned int len, 11380 void *buf, unsigned int size) 11381 { 11382 const struct arg *arg_data = pop_args(ctx); 11383 const struct arg *arg_len = pop_args(ctx); 11384 const struct arg *arg_addr = pop_args(ctx); 11385 char tmp[16]; /* Ought to be enough. */ 11386 int ret; 11387 11388 /* Arguments are expected. */ 11389 if (!arg_data) 11390 return -1; 11391 if (!arg_len) { 11392 push_args(ctx, arg_data); 11393 return -1; 11394 } 11395 if (!arg_addr) { 11396 push_args(ctx, arg_len); 11397 push_args(ctx, arg_data); 11398 return -1; 11399 } 11400 size = arg_data->size; 11401 /* Bit-mask fill is not supported. */ 11402 if (arg_data->mask || size < len) 11403 goto error; 11404 if (!ctx->object) 11405 return len; 11406 /* Let parse_int() fill length information first. */ 11407 ret = snprintf(tmp, sizeof(tmp), "%u", len); 11408 if (ret < 0) 11409 goto error; 11410 push_args(ctx, arg_len); 11411 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11412 if (ret < 0) { 11413 pop_args(ctx); 11414 goto error; 11415 } 11416 buf = (uint8_t *)ctx->object + arg_data->offset; 11417 /* Output buffer is not necessarily NUL-terminated. */ 11418 memcpy(buf, str, len); 11419 memset((uint8_t *)buf + len, 0x00, size - len); 11420 if (ctx->objmask) 11421 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11422 /* Save address if requested. */ 11423 if (arg_addr->size) { 11424 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11425 (void *[]){ 11426 (uint8_t *)ctx->object + arg_data->offset 11427 }, 11428 arg_addr->size); 11429 if (ctx->objmask) 11430 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11431 (void *[]){ 11432 (uint8_t *)ctx->objmask + arg_data->offset 11433 }, 11434 arg_addr->size); 11435 } 11436 return len; 11437 error: 11438 push_args(ctx, arg_addr); 11439 push_args(ctx, arg_len); 11440 push_args(ctx, arg_data); 11441 return -1; 11442 } 11443 11444 static int 11445 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 11446 { 11447 const uint8_t *head = dst; 11448 uint32_t left; 11449 11450 if (*size == 0) 11451 return -1; 11452 11453 left = *size; 11454 11455 /* Convert chars to bytes */ 11456 while (left) { 11457 char tmp[3], *end = tmp; 11458 uint32_t read_lim = left & 1 ? 1 : 2; 11459 11460 snprintf(tmp, read_lim + 1, "%s", src); 11461 *dst = strtoul(tmp, &end, 16); 11462 if (*end) { 11463 *dst = 0; 11464 *size = (uint32_t)(dst - head); 11465 return -1; 11466 } 11467 left -= read_lim; 11468 src += read_lim; 11469 dst++; 11470 } 11471 *dst = 0; 11472 *size = (uint32_t)(dst - head); 11473 return 0; 11474 } 11475 11476 static int 11477 parse_hex(struct context *ctx, const struct token *token, 11478 const char *str, unsigned int len, 11479 void *buf, unsigned int size) 11480 { 11481 const struct arg *arg_data = pop_args(ctx); 11482 const struct arg *arg_len = pop_args(ctx); 11483 const struct arg *arg_addr = pop_args(ctx); 11484 char tmp[16]; /* Ought to be enough. */ 11485 int ret; 11486 unsigned int hexlen = len; 11487 unsigned int length = 256; 11488 uint8_t hex_tmp[length]; 11489 11490 /* Arguments are expected. */ 11491 if (!arg_data) 11492 return -1; 11493 if (!arg_len) { 11494 push_args(ctx, arg_data); 11495 return -1; 11496 } 11497 if (!arg_addr) { 11498 push_args(ctx, arg_len); 11499 push_args(ctx, arg_data); 11500 return -1; 11501 } 11502 size = arg_data->size; 11503 /* Bit-mask fill is not supported. */ 11504 if (arg_data->mask) 11505 goto error; 11506 if (!ctx->object) 11507 return len; 11508 11509 /* translate bytes string to array. */ 11510 if (str[0] == '0' && ((str[1] == 'x') || 11511 (str[1] == 'X'))) { 11512 str += 2; 11513 hexlen -= 2; 11514 } 11515 if (hexlen > length) 11516 goto error; 11517 ret = parse_hex_string(str, hex_tmp, &hexlen); 11518 if (ret < 0) 11519 goto error; 11520 /* Check the converted binary fits into data buffer. */ 11521 if (hexlen > size) 11522 goto error; 11523 /* Let parse_int() fill length information first. */ 11524 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 11525 if (ret < 0) 11526 goto error; 11527 /* Save length if requested. */ 11528 if (arg_len->size) { 11529 push_args(ctx, arg_len); 11530 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11531 if (ret < 0) { 11532 pop_args(ctx); 11533 goto error; 11534 } 11535 } 11536 buf = (uint8_t *)ctx->object + arg_data->offset; 11537 /* Output buffer is not necessarily NUL-terminated. */ 11538 memcpy(buf, hex_tmp, hexlen); 11539 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 11540 if (ctx->objmask) 11541 memset((uint8_t *)ctx->objmask + arg_data->offset, 11542 0xff, hexlen); 11543 /* Save address if requested. */ 11544 if (arg_addr->size) { 11545 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11546 (void *[]){ 11547 (uint8_t *)ctx->object + arg_data->offset 11548 }, 11549 arg_addr->size); 11550 if (ctx->objmask) 11551 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11552 (void *[]){ 11553 (uint8_t *)ctx->objmask + arg_data->offset 11554 }, 11555 arg_addr->size); 11556 } 11557 return len; 11558 error: 11559 push_args(ctx, arg_addr); 11560 push_args(ctx, arg_len); 11561 push_args(ctx, arg_data); 11562 return -1; 11563 11564 } 11565 11566 /** 11567 * Parse a zero-ended string. 11568 */ 11569 static int 11570 parse_string0(struct context *ctx, const struct token *token __rte_unused, 11571 const char *str, unsigned int len, 11572 void *buf, unsigned int size) 11573 { 11574 const struct arg *arg_data = pop_args(ctx); 11575 11576 /* Arguments are expected. */ 11577 if (!arg_data) 11578 return -1; 11579 size = arg_data->size; 11580 /* Bit-mask fill is not supported. */ 11581 if (arg_data->mask || size < len + 1) 11582 goto error; 11583 if (!ctx->object) 11584 return len; 11585 buf = (uint8_t *)ctx->object + arg_data->offset; 11586 strncpy(buf, str, len); 11587 if (ctx->objmask) 11588 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11589 return len; 11590 error: 11591 push_args(ctx, arg_data); 11592 return -1; 11593 } 11594 11595 /** 11596 * Parse a MAC address. 11597 * 11598 * Last argument (ctx->args) is retrieved to determine storage size and 11599 * location. 11600 */ 11601 static int 11602 parse_mac_addr(struct context *ctx, const struct token *token, 11603 const char *str, unsigned int len, 11604 void *buf, unsigned int size) 11605 { 11606 const struct arg *arg = pop_args(ctx); 11607 struct rte_ether_addr tmp; 11608 int ret; 11609 11610 (void)token; 11611 /* Argument is expected. */ 11612 if (!arg) 11613 return -1; 11614 size = arg->size; 11615 /* Bit-mask fill is not supported. */ 11616 if (arg->mask || size != sizeof(tmp)) 11617 goto error; 11618 /* Only network endian is supported. */ 11619 if (!arg->hton) 11620 goto error; 11621 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 11622 if (ret < 0 || (unsigned int)ret != len) 11623 goto error; 11624 if (!ctx->object) 11625 return len; 11626 buf = (uint8_t *)ctx->object + arg->offset; 11627 memcpy(buf, &tmp, size); 11628 if (ctx->objmask) 11629 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11630 return len; 11631 error: 11632 push_args(ctx, arg); 11633 return -1; 11634 } 11635 11636 /** 11637 * Parse an IPv4 address. 11638 * 11639 * Last argument (ctx->args) is retrieved to determine storage size and 11640 * location. 11641 */ 11642 static int 11643 parse_ipv4_addr(struct context *ctx, const struct token *token, 11644 const char *str, unsigned int len, 11645 void *buf, unsigned int size) 11646 { 11647 const struct arg *arg = pop_args(ctx); 11648 char str2[len + 1]; 11649 struct in_addr tmp; 11650 int ret; 11651 11652 /* Argument is expected. */ 11653 if (!arg) 11654 return -1; 11655 size = arg->size; 11656 /* Bit-mask fill is not supported. */ 11657 if (arg->mask || size != sizeof(tmp)) 11658 goto error; 11659 /* Only network endian is supported. */ 11660 if (!arg->hton) 11661 goto error; 11662 memcpy(str2, str, len); 11663 str2[len] = '\0'; 11664 ret = inet_pton(AF_INET, str2, &tmp); 11665 if (ret != 1) { 11666 /* Attempt integer parsing. */ 11667 push_args(ctx, arg); 11668 return parse_int(ctx, token, str, len, buf, size); 11669 } 11670 if (!ctx->object) 11671 return len; 11672 buf = (uint8_t *)ctx->object + arg->offset; 11673 memcpy(buf, &tmp, size); 11674 if (ctx->objmask) 11675 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11676 return len; 11677 error: 11678 push_args(ctx, arg); 11679 return -1; 11680 } 11681 11682 /** 11683 * Parse an IPv6 address. 11684 * 11685 * Last argument (ctx->args) is retrieved to determine storage size and 11686 * location. 11687 */ 11688 static int 11689 parse_ipv6_addr(struct context *ctx, const struct token *token, 11690 const char *str, unsigned int len, 11691 void *buf, unsigned int size) 11692 { 11693 const struct arg *arg = pop_args(ctx); 11694 char str2[len + 1]; 11695 struct in6_addr tmp; 11696 int ret; 11697 11698 (void)token; 11699 /* Argument is expected. */ 11700 if (!arg) 11701 return -1; 11702 size = arg->size; 11703 /* Bit-mask fill is not supported. */ 11704 if (arg->mask || size != sizeof(tmp)) 11705 goto error; 11706 /* Only network endian is supported. */ 11707 if (!arg->hton) 11708 goto error; 11709 memcpy(str2, str, len); 11710 str2[len] = '\0'; 11711 ret = inet_pton(AF_INET6, str2, &tmp); 11712 if (ret != 1) 11713 goto error; 11714 if (!ctx->object) 11715 return len; 11716 buf = (uint8_t *)ctx->object + arg->offset; 11717 memcpy(buf, &tmp, size); 11718 if (ctx->objmask) 11719 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11720 return len; 11721 error: 11722 push_args(ctx, arg); 11723 return -1; 11724 } 11725 11726 /** Boolean values (even indices stand for false). */ 11727 static const char *const boolean_name[] = { 11728 "0", "1", 11729 "false", "true", 11730 "no", "yes", 11731 "N", "Y", 11732 "off", "on", 11733 NULL, 11734 }; 11735 11736 /** 11737 * Parse a boolean value. 11738 * 11739 * Last argument (ctx->args) is retrieved to determine storage size and 11740 * location. 11741 */ 11742 static int 11743 parse_boolean(struct context *ctx, const struct token *token, 11744 const char *str, unsigned int len, 11745 void *buf, unsigned int size) 11746 { 11747 const struct arg *arg = pop_args(ctx); 11748 unsigned int i; 11749 int ret; 11750 11751 /* Argument is expected. */ 11752 if (!arg) 11753 return -1; 11754 for (i = 0; boolean_name[i]; ++i) 11755 if (!strcmp_partial(boolean_name[i], str, len)) 11756 break; 11757 /* Process token as integer. */ 11758 if (boolean_name[i]) 11759 str = i & 1 ? "1" : "0"; 11760 push_args(ctx, arg); 11761 ret = parse_int(ctx, token, str, strlen(str), buf, size); 11762 return ret > 0 ? (int)len : ret; 11763 } 11764 11765 /** Parse port and update context. */ 11766 static int 11767 parse_port(struct context *ctx, const struct token *token, 11768 const char *str, unsigned int len, 11769 void *buf, unsigned int size) 11770 { 11771 struct buffer *out = &(struct buffer){ .port = 0 }; 11772 int ret; 11773 11774 if (buf) 11775 out = buf; 11776 else { 11777 ctx->objdata = 0; 11778 ctx->object = out; 11779 ctx->objmask = NULL; 11780 size = sizeof(*out); 11781 } 11782 ret = parse_int(ctx, token, str, len, out, size); 11783 if (ret >= 0) 11784 ctx->port = out->port; 11785 if (!buf) 11786 ctx->object = NULL; 11787 return ret; 11788 } 11789 11790 /** Parse tokens for shared indirect actions. */ 11791 static int 11792 parse_ia_port(struct context *ctx, const struct token *token, 11793 const char *str, unsigned int len, 11794 void *buf, unsigned int size) 11795 { 11796 struct rte_flow_action *action = ctx->object; 11797 uint32_t id; 11798 int ret; 11799 11800 (void)buf; 11801 (void)size; 11802 ctx->objdata = 0; 11803 ctx->object = &id; 11804 ctx->objmask = NULL; 11805 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11806 ctx->object = action; 11807 if (ret != (int)len) 11808 return ret; 11809 /* set indirect action */ 11810 if (action) 11811 action->conf = (void *)(uintptr_t)id; 11812 return ret; 11813 } 11814 11815 static int 11816 parse_ia_id2ptr(struct context *ctx, const struct token *token, 11817 const char *str, unsigned int len, 11818 void *buf, unsigned int size) 11819 { 11820 struct rte_flow_action *action = ctx->object; 11821 uint32_t id; 11822 int ret; 11823 11824 (void)buf; 11825 (void)size; 11826 ctx->objdata = 0; 11827 ctx->object = &id; 11828 ctx->objmask = NULL; 11829 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11830 ctx->object = action; 11831 if (ret != (int)len) 11832 return ret; 11833 /* set indirect action */ 11834 if (action) { 11835 portid_t port_id = ctx->port; 11836 if (ctx->prev == INDIRECT_ACTION_PORT) 11837 port_id = (portid_t)(uintptr_t)action->conf; 11838 action->conf = port_action_handle_get_by_id(port_id, id); 11839 ret = (action->conf) ? ret : -1; 11840 } 11841 return ret; 11842 } 11843 11844 static int 11845 parse_indlst_id2ptr(struct context *ctx, const struct token *token, 11846 const char *str, unsigned int len, 11847 __rte_unused void *buf, __rte_unused unsigned int size) 11848 { 11849 struct rte_flow_action *action = ctx->object; 11850 struct rte_flow_action_indirect_list *action_conf; 11851 const struct indlst_conf *indlst_conf; 11852 uint32_t id; 11853 int ret; 11854 11855 if (!action) 11856 return -1; 11857 ctx->objdata = 0; 11858 ctx->object = &id; 11859 ctx->objmask = NULL; 11860 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11861 if (ret != (int)len) 11862 return ret; 11863 ctx->object = action; 11864 action_conf = (void *)(uintptr_t)action->conf; 11865 action_conf->conf = NULL; 11866 switch (ctx->curr) { 11867 case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: 11868 action_conf->handle = (typeof(action_conf->handle)) 11869 port_action_handle_get_by_id(ctx->port, id); 11870 if (!action_conf->handle) { 11871 printf("no indirect list handle for id %u\n", id); 11872 return -1; 11873 } 11874 break; 11875 case INDIRECT_LIST_ACTION_ID2PTR_CONF: 11876 indlst_conf = indirect_action_list_conf_get(id); 11877 if (!indlst_conf) 11878 return -1; 11879 action_conf->conf = (const void **)indlst_conf->conf; 11880 break; 11881 default: 11882 break; 11883 } 11884 return ret; 11885 } 11886 11887 static int 11888 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 11889 const char *str, unsigned int len, 11890 void *buf, unsigned int size) 11891 { 11892 struct rte_flow_action *action = ctx->object; 11893 struct rte_flow_action_meter_mark *meter; 11894 struct rte_flow_meter_profile *profile = NULL; 11895 uint32_t id = 0; 11896 int ret; 11897 11898 (void)buf; 11899 (void)size; 11900 ctx->objdata = 0; 11901 ctx->object = &id; 11902 ctx->objmask = NULL; 11903 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11904 ctx->object = action; 11905 if (ret != (int)len) 11906 return ret; 11907 /* set meter profile */ 11908 if (action) { 11909 meter = (struct rte_flow_action_meter_mark *) 11910 (uintptr_t)(action->conf); 11911 profile = port_meter_profile_get_by_id(ctx->port, id); 11912 meter->profile = profile; 11913 ret = (profile) ? ret : -1; 11914 } 11915 return ret; 11916 } 11917 11918 static int 11919 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 11920 const char *str, unsigned int len, 11921 void *buf, unsigned int size) 11922 { 11923 struct rte_flow_action *action = ctx->object; 11924 struct rte_flow_action_meter_mark *meter; 11925 struct rte_flow_meter_policy *policy = NULL; 11926 uint32_t id = 0; 11927 int ret; 11928 11929 (void)buf; 11930 (void)size; 11931 ctx->objdata = 0; 11932 ctx->object = &id; 11933 ctx->objmask = NULL; 11934 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11935 ctx->object = action; 11936 if (ret != (int)len) 11937 return ret; 11938 /* set meter policy */ 11939 if (action) { 11940 meter = (struct rte_flow_action_meter_mark *) 11941 (uintptr_t)(action->conf); 11942 policy = port_meter_policy_get_by_id(ctx->port, id); 11943 meter->policy = policy; 11944 ret = (policy) ? ret : -1; 11945 } 11946 return ret; 11947 } 11948 11949 /** Parse set command, initialize output buffer for subsequent tokens. */ 11950 static int 11951 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 11952 const char *str, unsigned int len, 11953 void *buf, unsigned int size) 11954 { 11955 struct buffer *out = buf; 11956 11957 /* Token name must match. */ 11958 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11959 return -1; 11960 /* Nothing else to do if there is no buffer. */ 11961 if (!out) 11962 return len; 11963 /* Make sure buffer is large enough. */ 11964 if (size < sizeof(*out)) 11965 return -1; 11966 ctx->objdata = 0; 11967 ctx->objmask = NULL; 11968 ctx->object = out; 11969 if (!out->command) 11970 return -1; 11971 out->command = ctx->curr; 11972 /* For encap/decap we need is pattern */ 11973 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11974 sizeof(double)); 11975 return len; 11976 } 11977 11978 /** Parse set command, initialize output buffer for subsequent tokens. */ 11979 static int 11980 parse_set_sample_action(struct context *ctx, const struct token *token, 11981 const char *str, unsigned int len, 11982 void *buf, unsigned int size) 11983 { 11984 struct buffer *out = buf; 11985 11986 /* Token name must match. */ 11987 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11988 return -1; 11989 /* Nothing else to do if there is no buffer. */ 11990 if (!out) 11991 return len; 11992 /* Make sure buffer is large enough. */ 11993 if (size < sizeof(*out)) 11994 return -1; 11995 ctx->objdata = 0; 11996 ctx->objmask = NULL; 11997 ctx->object = out; 11998 if (!out->command) 11999 return -1; 12000 out->command = ctx->curr; 12001 /* For sampler we need is actions */ 12002 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12003 sizeof(double)); 12004 return len; 12005 } 12006 12007 /** Parse set command, initialize output buffer for subsequent tokens. */ 12008 static int 12009 parse_set_ipv6_ext_action(struct context *ctx, const struct token *token, 12010 const char *str, unsigned int len, 12011 void *buf, unsigned int size) 12012 { 12013 struct buffer *out = buf; 12014 12015 /* Token name must match. */ 12016 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12017 return -1; 12018 /* Nothing else to do if there is no buffer. */ 12019 if (!out) 12020 return len; 12021 /* Make sure buffer is large enough. */ 12022 if (size < sizeof(*out)) 12023 return -1; 12024 ctx->objdata = 0; 12025 ctx->objmask = NULL; 12026 ctx->object = out; 12027 if (!out->command) 12028 return -1; 12029 out->command = ctx->curr; 12030 /* For ipv6_ext_push/remove we need is pattern */ 12031 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12032 sizeof(double)); 12033 return len; 12034 } 12035 12036 /** 12037 * Parse set raw_encap/raw_decap command, 12038 * initialize output buffer for subsequent tokens. 12039 */ 12040 static int 12041 parse_set_init(struct context *ctx, const struct token *token, 12042 const char *str, unsigned int len, 12043 void *buf, unsigned int size) 12044 { 12045 struct buffer *out = buf; 12046 12047 /* Token name must match. */ 12048 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12049 return -1; 12050 /* Nothing else to do if there is no buffer. */ 12051 if (!out) 12052 return len; 12053 /* Make sure buffer is large enough. */ 12054 if (size < sizeof(*out)) 12055 return -1; 12056 /* Initialize buffer. */ 12057 memset(out, 0x00, sizeof(*out)); 12058 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 12059 ctx->objdata = 0; 12060 ctx->object = out; 12061 ctx->objmask = NULL; 12062 if (!out->command) { 12063 if (ctx->curr != SET) 12064 return -1; 12065 if (sizeof(*out) > size) 12066 return -1; 12067 out->command = ctx->curr; 12068 out->args.vc.data = (uint8_t *)out + size; 12069 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12070 sizeof(double)); 12071 } 12072 return len; 12073 } 12074 12075 /* 12076 * Replace testpmd handles in a flex flow item with real values. 12077 */ 12078 static int 12079 parse_flex_handle(struct context *ctx, const struct token *token, 12080 const char *str, unsigned int len, 12081 void *buf, unsigned int size) 12082 { 12083 struct rte_flow_item_flex *spec, *mask; 12084 const struct rte_flow_item_flex *src_spec, *src_mask; 12085 const struct arg *arg = pop_args(ctx); 12086 uint32_t offset; 12087 uint16_t handle; 12088 int ret; 12089 12090 if (!arg) { 12091 printf("Bad environment\n"); 12092 return -1; 12093 } 12094 offset = arg->offset; 12095 push_args(ctx, arg); 12096 ret = parse_int(ctx, token, str, len, buf, size); 12097 if (ret <= 0 || !ctx->object) 12098 return ret; 12099 if (ctx->port >= RTE_MAX_ETHPORTS) { 12100 printf("Bad port\n"); 12101 return -1; 12102 } 12103 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 12104 const struct flex_item *fp; 12105 spec = ctx->object; 12106 handle = (uint16_t)(uintptr_t)spec->handle; 12107 if (handle >= FLEX_MAX_PARSERS_NUM) { 12108 printf("Bad flex item handle\n"); 12109 return -1; 12110 } 12111 fp = flex_items[ctx->port][handle]; 12112 if (!fp) { 12113 printf("Bad flex item handle\n"); 12114 return -1; 12115 } 12116 spec->handle = fp->flex_handle; 12117 mask = spec + 2; /* spec, last, mask */ 12118 mask->handle = fp->flex_handle; 12119 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 12120 handle = (uint16_t)(uintptr_t) 12121 ((struct rte_flow_item_flex *)ctx->object)->pattern; 12122 if (handle >= FLEX_MAX_PATTERNS_NUM) { 12123 printf("Bad pattern handle\n"); 12124 return -1; 12125 } 12126 src_spec = &flex_patterns[handle].spec; 12127 src_mask = &flex_patterns[handle].mask; 12128 spec = ctx->object; 12129 mask = spec + 2; /* spec, last, mask */ 12130 /* fill flow rule spec and mask parameters */ 12131 spec->length = src_spec->length; 12132 spec->pattern = src_spec->pattern; 12133 mask->length = src_mask->length; 12134 mask->pattern = src_mask->pattern; 12135 } else { 12136 printf("Bad arguments - unknown flex item offset\n"); 12137 return -1; 12138 } 12139 return ret; 12140 } 12141 12142 /** Parse Meter color name */ 12143 static int 12144 parse_meter_color(struct context *ctx, const struct token *token, 12145 const char *str, unsigned int len, void *buf, 12146 unsigned int size) 12147 { 12148 struct rte_flow_item_meter_color *meter_color; 12149 unsigned int i; 12150 12151 (void)token; 12152 (void)buf; 12153 (void)size; 12154 for (i = 0; meter_colors[i]; ++i) 12155 if (!strcmp_partial(meter_colors[i], str, len)) 12156 break; 12157 if (!meter_colors[i]) 12158 return -1; 12159 if (!ctx->object) 12160 return len; 12161 meter_color = ctx->object; 12162 meter_color->color = (enum rte_color)i; 12163 return len; 12164 } 12165 12166 /** Parse Insertion Table Type name */ 12167 static int 12168 parse_insertion_table_type(struct context *ctx, const struct token *token, 12169 const char *str, unsigned int len, void *buf, 12170 unsigned int size) 12171 { 12172 const struct arg *arg = pop_args(ctx); 12173 unsigned int i; 12174 char tmp[2]; 12175 int ret; 12176 12177 (void)size; 12178 /* Argument is expected. */ 12179 if (!arg) 12180 return -1; 12181 for (i = 0; table_insertion_types[i]; ++i) 12182 if (!strcmp_partial(table_insertion_types[i], str, len)) 12183 break; 12184 if (!table_insertion_types[i]) 12185 return -1; 12186 push_args(ctx, arg); 12187 snprintf(tmp, sizeof(tmp), "%u", i); 12188 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12189 return ret > 0 ? (int)len : ret; 12190 } 12191 12192 /** Parse Hash Calculation Table Type name */ 12193 static int 12194 parse_hash_table_type(struct context *ctx, const struct token *token, 12195 const char *str, unsigned int len, void *buf, 12196 unsigned int size) 12197 { 12198 const struct arg *arg = pop_args(ctx); 12199 unsigned int i; 12200 char tmp[2]; 12201 int ret; 12202 12203 (void)size; 12204 /* Argument is expected. */ 12205 if (!arg) 12206 return -1; 12207 for (i = 0; table_hash_funcs[i]; ++i) 12208 if (!strcmp_partial(table_hash_funcs[i], str, len)) 12209 break; 12210 if (!table_hash_funcs[i]) 12211 return -1; 12212 push_args(ctx, arg); 12213 snprintf(tmp, sizeof(tmp), "%u", i); 12214 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12215 return ret > 0 ? (int)len : ret; 12216 } 12217 12218 static int 12219 parse_name_to_index(struct context *ctx, const struct token *token, 12220 const char *str, unsigned int len, void *buf, 12221 unsigned int size, 12222 const char *const names[], size_t names_size, uint32_t *dst) 12223 { 12224 int ret; 12225 uint32_t i; 12226 12227 RTE_SET_USED(token); 12228 RTE_SET_USED(buf); 12229 RTE_SET_USED(size); 12230 if (!ctx->object) 12231 return len; 12232 for (i = 0; i < names_size; i++) { 12233 if (!names[i]) 12234 continue; 12235 ret = strcmp_partial(names[i], str, 12236 RTE_MIN(len, strlen(names[i]))); 12237 if (!ret) { 12238 *dst = i; 12239 return len; 12240 } 12241 } 12242 return -1; 12243 } 12244 12245 static const char *const quota_mode_names[] = { 12246 NULL, 12247 [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", 12248 [RTE_FLOW_QUOTA_MODE_L2] = "l2", 12249 [RTE_FLOW_QUOTA_MODE_L3] = "l3" 12250 }; 12251 12252 static const char *const quota_state_names[] = { 12253 [RTE_FLOW_QUOTA_STATE_PASS] = "pass", 12254 [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" 12255 }; 12256 12257 static const char *const quota_update_names[] = { 12258 [RTE_FLOW_UPDATE_QUOTA_SET] = "set", 12259 [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" 12260 }; 12261 12262 static const char *const query_update_mode_names[] = { 12263 [RTE_FLOW_QU_QUERY_FIRST] = "query_first", 12264 [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" 12265 }; 12266 12267 static int 12268 parse_quota_state_name(struct context *ctx, const struct token *token, 12269 const char *str, unsigned int len, void *buf, 12270 unsigned int size) 12271 { 12272 struct rte_flow_item_quota *quota = ctx->object; 12273 12274 return parse_name_to_index(ctx, token, str, len, buf, size, 12275 quota_state_names, 12276 RTE_DIM(quota_state_names), 12277 (uint32_t *)"a->state); 12278 } 12279 12280 static int 12281 parse_quota_mode_name(struct context *ctx, const struct token *token, 12282 const char *str, unsigned int len, void *buf, 12283 unsigned int size) 12284 { 12285 struct rte_flow_action_quota *quota = ctx->object; 12286 12287 return parse_name_to_index(ctx, token, str, len, buf, size, 12288 quota_mode_names, 12289 RTE_DIM(quota_mode_names), 12290 (uint32_t *)"a->mode); 12291 } 12292 12293 static int 12294 parse_quota_update_name(struct context *ctx, const struct token *token, 12295 const char *str, unsigned int len, void *buf, 12296 unsigned int size) 12297 { 12298 struct rte_flow_update_quota *update = ctx->object; 12299 12300 return parse_name_to_index(ctx, token, str, len, buf, size, 12301 quota_update_names, 12302 RTE_DIM(quota_update_names), 12303 (uint32_t *)&update->op); 12304 } 12305 12306 static int 12307 parse_qu_mode_name(struct context *ctx, const struct token *token, 12308 const char *str, unsigned int len, void *buf, 12309 unsigned int size) 12310 { 12311 struct buffer *out = ctx->object; 12312 12313 return parse_name_to_index(ctx, token, str, len, buf, size, 12314 query_update_mode_names, 12315 RTE_DIM(query_update_mode_names), 12316 (uint32_t *)&out->args.ia.qu_mode); 12317 } 12318 12319 /** No completion. */ 12320 static int 12321 comp_none(struct context *ctx, const struct token *token, 12322 unsigned int ent, char *buf, unsigned int size) 12323 { 12324 (void)ctx; 12325 (void)token; 12326 (void)ent; 12327 (void)buf; 12328 (void)size; 12329 return 0; 12330 } 12331 12332 /** Complete boolean values. */ 12333 static int 12334 comp_boolean(struct context *ctx, const struct token *token, 12335 unsigned int ent, char *buf, unsigned int size) 12336 { 12337 unsigned int i; 12338 12339 (void)ctx; 12340 (void)token; 12341 for (i = 0; boolean_name[i]; ++i) 12342 if (buf && i == ent) 12343 return strlcpy(buf, boolean_name[i], size); 12344 if (buf) 12345 return -1; 12346 return i; 12347 } 12348 12349 /** Complete action names. */ 12350 static int 12351 comp_action(struct context *ctx, const struct token *token, 12352 unsigned int ent, char *buf, unsigned int size) 12353 { 12354 unsigned int i; 12355 12356 (void)ctx; 12357 (void)token; 12358 for (i = 0; next_action[i]; ++i) 12359 if (buf && i == ent) 12360 return strlcpy(buf, token_list[next_action[i]].name, 12361 size); 12362 if (buf) 12363 return -1; 12364 return i; 12365 } 12366 12367 /** Complete available ports. */ 12368 static int 12369 comp_port(struct context *ctx, const struct token *token, 12370 unsigned int ent, char *buf, unsigned int size) 12371 { 12372 unsigned int i = 0; 12373 portid_t p; 12374 12375 (void)ctx; 12376 (void)token; 12377 RTE_ETH_FOREACH_DEV(p) { 12378 if (buf && i == ent) 12379 return snprintf(buf, size, "%u", p); 12380 ++i; 12381 } 12382 if (buf) 12383 return -1; 12384 return i; 12385 } 12386 12387 /** Complete available rule IDs. */ 12388 static int 12389 comp_rule_id(struct context *ctx, const struct token *token, 12390 unsigned int ent, char *buf, unsigned int size) 12391 { 12392 unsigned int i = 0; 12393 struct rte_port *port; 12394 struct port_flow *pf; 12395 12396 (void)token; 12397 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12398 ctx->port == (portid_t)RTE_PORT_ALL) 12399 return -1; 12400 port = &ports[ctx->port]; 12401 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 12402 if (buf && i == ent) 12403 return snprintf(buf, size, "%"PRIu64, pf->id); 12404 ++i; 12405 } 12406 if (buf) 12407 return -1; 12408 return i; 12409 } 12410 12411 /** Complete operation for compare match item. */ 12412 static int 12413 comp_set_compare_op(struct context *ctx, const struct token *token, 12414 unsigned int ent, char *buf, unsigned int size) 12415 { 12416 RTE_SET_USED(ctx); 12417 RTE_SET_USED(token); 12418 if (!buf) 12419 return RTE_DIM(compare_ops); 12420 if (ent < RTE_DIM(compare_ops) - 1) 12421 return strlcpy(buf, compare_ops[ent], size); 12422 return -1; 12423 } 12424 12425 /** Complete field id for compare match item. */ 12426 static int 12427 comp_set_compare_field_id(struct context *ctx, const struct token *token, 12428 unsigned int ent, char *buf, unsigned int size) 12429 { 12430 const char *name; 12431 12432 RTE_SET_USED(token); 12433 if (!buf) 12434 return RTE_DIM(flow_field_ids); 12435 if (ent >= RTE_DIM(flow_field_ids) - 1) 12436 return -1; 12437 name = flow_field_ids[ent]; 12438 if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE || 12439 (strcmp(name, "pointer") && strcmp(name, "value"))) 12440 return strlcpy(buf, name, size); 12441 return -1; 12442 } 12443 12444 /** Complete type field for RSS action. */ 12445 static int 12446 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 12447 unsigned int ent, char *buf, unsigned int size) 12448 { 12449 unsigned int i; 12450 12451 (void)ctx; 12452 (void)token; 12453 for (i = 0; rss_type_table[i].str; ++i) 12454 ; 12455 if (!buf) 12456 return i + 1; 12457 if (ent < i) 12458 return strlcpy(buf, rss_type_table[ent].str, size); 12459 if (ent == i) 12460 return snprintf(buf, size, "end"); 12461 return -1; 12462 } 12463 12464 /** Complete queue field for RSS action. */ 12465 static int 12466 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 12467 unsigned int ent, char *buf, unsigned int size) 12468 { 12469 (void)ctx; 12470 (void)token; 12471 if (!buf) 12472 return nb_rxq + 1; 12473 if (ent < nb_rxq) 12474 return snprintf(buf, size, "%u", ent); 12475 if (ent == nb_rxq) 12476 return snprintf(buf, size, "end"); 12477 return -1; 12478 } 12479 12480 /** Complete index number for set raw_encap/raw_decap commands. */ 12481 static int 12482 comp_set_raw_index(struct context *ctx, const struct token *token, 12483 unsigned int ent, char *buf, unsigned int size) 12484 { 12485 uint16_t idx = 0; 12486 uint16_t nb = 0; 12487 12488 RTE_SET_USED(ctx); 12489 RTE_SET_USED(token); 12490 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 12491 if (buf && idx == ent) 12492 return snprintf(buf, size, "%u", idx); 12493 ++nb; 12494 } 12495 return nb; 12496 } 12497 12498 /** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ 12499 static int 12500 comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 12501 unsigned int ent, char *buf, unsigned int size) 12502 { 12503 uint16_t idx = 0; 12504 uint16_t nb = 0; 12505 12506 RTE_SET_USED(ctx); 12507 RTE_SET_USED(token); 12508 for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { 12509 if (buf && idx == ent) 12510 return snprintf(buf, size, "%u", idx); 12511 ++nb; 12512 } 12513 return nb; 12514 } 12515 12516 /** Complete index number for set raw_encap/raw_decap commands. */ 12517 static int 12518 comp_set_sample_index(struct context *ctx, const struct token *token, 12519 unsigned int ent, char *buf, unsigned int size) 12520 { 12521 uint16_t idx = 0; 12522 uint16_t nb = 0; 12523 12524 RTE_SET_USED(ctx); 12525 RTE_SET_USED(token); 12526 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 12527 if (buf && idx == ent) 12528 return snprintf(buf, size, "%u", idx); 12529 ++nb; 12530 } 12531 return nb; 12532 } 12533 12534 /** Complete operation for modify_field command. */ 12535 static int 12536 comp_set_modify_field_op(struct context *ctx, const struct token *token, 12537 unsigned int ent, char *buf, unsigned int size) 12538 { 12539 RTE_SET_USED(ctx); 12540 RTE_SET_USED(token); 12541 if (!buf) 12542 return RTE_DIM(modify_field_ops); 12543 if (ent < RTE_DIM(modify_field_ops) - 1) 12544 return strlcpy(buf, modify_field_ops[ent], size); 12545 return -1; 12546 } 12547 12548 /** Complete field id for modify_field command. */ 12549 static int 12550 comp_set_modify_field_id(struct context *ctx, const struct token *token, 12551 unsigned int ent, char *buf, unsigned int size) 12552 { 12553 const char *name; 12554 12555 RTE_SET_USED(token); 12556 if (!buf) 12557 return RTE_DIM(flow_field_ids); 12558 if (ent >= RTE_DIM(flow_field_ids) - 1) 12559 return -1; 12560 name = flow_field_ids[ent]; 12561 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 12562 (strcmp(name, "pointer") && strcmp(name, "value"))) 12563 return strlcpy(buf, name, size); 12564 return -1; 12565 } 12566 12567 /** Complete available pattern template IDs. */ 12568 static int 12569 comp_pattern_template_id(struct context *ctx, const struct token *token, 12570 unsigned int ent, char *buf, unsigned int size) 12571 { 12572 unsigned int i = 0; 12573 struct rte_port *port; 12574 struct port_template *pt; 12575 12576 (void)token; 12577 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12578 ctx->port == (portid_t)RTE_PORT_ALL) 12579 return -1; 12580 port = &ports[ctx->port]; 12581 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 12582 if (buf && i == ent) 12583 return snprintf(buf, size, "%u", pt->id); 12584 ++i; 12585 } 12586 if (buf) 12587 return -1; 12588 return i; 12589 } 12590 12591 /** Complete available actions template IDs. */ 12592 static int 12593 comp_actions_template_id(struct context *ctx, const struct token *token, 12594 unsigned int ent, char *buf, unsigned int size) 12595 { 12596 unsigned int i = 0; 12597 struct rte_port *port; 12598 struct port_template *pt; 12599 12600 (void)token; 12601 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12602 ctx->port == (portid_t)RTE_PORT_ALL) 12603 return -1; 12604 port = &ports[ctx->port]; 12605 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 12606 if (buf && i == ent) 12607 return snprintf(buf, size, "%u", pt->id); 12608 ++i; 12609 } 12610 if (buf) 12611 return -1; 12612 return i; 12613 } 12614 12615 /** Complete available table IDs. */ 12616 static int 12617 comp_table_id(struct context *ctx, const struct token *token, 12618 unsigned int ent, char *buf, unsigned int size) 12619 { 12620 unsigned int i = 0; 12621 struct rte_port *port; 12622 struct port_table *pt; 12623 12624 (void)token; 12625 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12626 ctx->port == (portid_t)RTE_PORT_ALL) 12627 return -1; 12628 port = &ports[ctx->port]; 12629 for (pt = port->table_list; pt != NULL; pt = pt->next) { 12630 if (buf && i == ent) 12631 return snprintf(buf, size, "%u", pt->id); 12632 ++i; 12633 } 12634 if (buf) 12635 return -1; 12636 return i; 12637 } 12638 12639 /** Complete available queue IDs. */ 12640 static int 12641 comp_queue_id(struct context *ctx, const struct token *token, 12642 unsigned int ent, char *buf, unsigned int size) 12643 { 12644 unsigned int i = 0; 12645 struct rte_port *port; 12646 12647 (void)token; 12648 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12649 ctx->port == (portid_t)RTE_PORT_ALL) 12650 return -1; 12651 port = &ports[ctx->port]; 12652 for (i = 0; i < port->queue_nb; i++) { 12653 if (buf && i == ent) 12654 return snprintf(buf, size, "%u", i); 12655 } 12656 if (buf) 12657 return -1; 12658 return i; 12659 } 12660 12661 static int 12662 comp_names_to_index(struct context *ctx, const struct token *token, 12663 unsigned int ent, char *buf, unsigned int size, 12664 const char *const names[], size_t names_size) 12665 { 12666 RTE_SET_USED(ctx); 12667 RTE_SET_USED(token); 12668 if (!buf) 12669 return names_size; 12670 if (names[ent] && ent < names_size) 12671 return rte_strscpy(buf, names[ent], size); 12672 return -1; 12673 12674 } 12675 12676 /** Complete available Meter colors. */ 12677 static int 12678 comp_meter_color(struct context *ctx, const struct token *token, 12679 unsigned int ent, char *buf, unsigned int size) 12680 { 12681 RTE_SET_USED(ctx); 12682 RTE_SET_USED(token); 12683 if (!buf) 12684 return RTE_DIM(meter_colors); 12685 if (ent < RTE_DIM(meter_colors) - 1) 12686 return strlcpy(buf, meter_colors[ent], size); 12687 return -1; 12688 } 12689 12690 /** Complete available Insertion Table types. */ 12691 static int 12692 comp_insertion_table_type(struct context *ctx, const struct token *token, 12693 unsigned int ent, char *buf, unsigned int size) 12694 { 12695 RTE_SET_USED(ctx); 12696 RTE_SET_USED(token); 12697 if (!buf) 12698 return RTE_DIM(table_insertion_types); 12699 if (ent < RTE_DIM(table_insertion_types) - 1) 12700 return rte_strscpy(buf, table_insertion_types[ent], size); 12701 return -1; 12702 } 12703 12704 /** Complete available Hash Calculation Table types. */ 12705 static int 12706 comp_hash_table_type(struct context *ctx, const struct token *token, 12707 unsigned int ent, char *buf, unsigned int size) 12708 { 12709 RTE_SET_USED(ctx); 12710 RTE_SET_USED(token); 12711 if (!buf) 12712 return RTE_DIM(table_hash_funcs); 12713 if (ent < RTE_DIM(table_hash_funcs) - 1) 12714 return rte_strscpy(buf, table_hash_funcs[ent], size); 12715 return -1; 12716 } 12717 12718 static int 12719 comp_quota_state_name(struct context *ctx, const struct token *token, 12720 unsigned int ent, char *buf, unsigned int size) 12721 { 12722 return comp_names_to_index(ctx, token, ent, buf, size, 12723 quota_state_names, 12724 RTE_DIM(quota_state_names)); 12725 } 12726 12727 static int 12728 comp_quota_mode_name(struct context *ctx, const struct token *token, 12729 unsigned int ent, char *buf, unsigned int size) 12730 { 12731 return comp_names_to_index(ctx, token, ent, buf, size, 12732 quota_mode_names, 12733 RTE_DIM(quota_mode_names)); 12734 } 12735 12736 static int 12737 comp_quota_update_name(struct context *ctx, const struct token *token, 12738 unsigned int ent, char *buf, unsigned int size) 12739 { 12740 return comp_names_to_index(ctx, token, ent, buf, size, 12741 quota_update_names, 12742 RTE_DIM(quota_update_names)); 12743 } 12744 12745 static int 12746 comp_qu_mode_name(struct context *ctx, const struct token *token, 12747 unsigned int ent, char *buf, unsigned int size) 12748 { 12749 return comp_names_to_index(ctx, token, ent, buf, size, 12750 query_update_mode_names, 12751 RTE_DIM(query_update_mode_names)); 12752 } 12753 12754 /** Internal context. */ 12755 static struct context cmd_flow_context; 12756 12757 /** Global parser instance (cmdline API). */ 12758 cmdline_parse_inst_t cmd_flow; 12759 cmdline_parse_inst_t cmd_set_raw; 12760 12761 /** Initialize context. */ 12762 static void 12763 cmd_flow_context_init(struct context *ctx) 12764 { 12765 /* A full memset() is not necessary. */ 12766 ctx->curr = ZERO; 12767 ctx->prev = ZERO; 12768 ctx->next_num = 0; 12769 ctx->args_num = 0; 12770 ctx->eol = 0; 12771 ctx->last = 0; 12772 ctx->port = 0; 12773 ctx->objdata = 0; 12774 ctx->object = NULL; 12775 ctx->objmask = NULL; 12776 } 12777 12778 /** Parse a token (cmdline API). */ 12779 static int 12780 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 12781 unsigned int size) 12782 { 12783 struct context *ctx = &cmd_flow_context; 12784 const struct token *token; 12785 const enum index *list; 12786 int len; 12787 int i; 12788 12789 (void)hdr; 12790 token = &token_list[ctx->curr]; 12791 /* Check argument length. */ 12792 ctx->eol = 0; 12793 ctx->last = 1; 12794 for (len = 0; src[len]; ++len) 12795 if (src[len] == '#' || isspace(src[len])) 12796 break; 12797 if (!len) 12798 return -1; 12799 /* Last argument and EOL detection. */ 12800 for (i = len; src[i]; ++i) 12801 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 12802 break; 12803 else if (!isspace(src[i])) { 12804 ctx->last = 0; 12805 break; 12806 } 12807 for (; src[i]; ++i) 12808 if (src[i] == '\r' || src[i] == '\n') { 12809 ctx->eol = 1; 12810 break; 12811 } 12812 /* Initialize context if necessary. */ 12813 if (!ctx->next_num) { 12814 if (!token->next) 12815 return 0; 12816 ctx->next[ctx->next_num++] = token->next[0]; 12817 } 12818 /* Process argument through candidates. */ 12819 ctx->prev = ctx->curr; 12820 list = ctx->next[ctx->next_num - 1]; 12821 for (i = 0; list[i]; ++i) { 12822 const struct token *next = &token_list[list[i]]; 12823 int tmp; 12824 12825 ctx->curr = list[i]; 12826 if (next->call) 12827 tmp = next->call(ctx, next, src, len, result, size); 12828 else 12829 tmp = parse_default(ctx, next, src, len, result, size); 12830 if (tmp == -1 || tmp != len) 12831 continue; 12832 token = next; 12833 break; 12834 } 12835 if (!list[i]) 12836 return -1; 12837 --ctx->next_num; 12838 /* Push subsequent tokens if any. */ 12839 if (token->next) 12840 for (i = 0; token->next[i]; ++i) { 12841 if (ctx->next_num == RTE_DIM(ctx->next)) 12842 return -1; 12843 ctx->next[ctx->next_num++] = token->next[i]; 12844 } 12845 /* Push arguments if any. */ 12846 if (token->args) 12847 for (i = 0; token->args[i]; ++i) { 12848 if (ctx->args_num == RTE_DIM(ctx->args)) 12849 return -1; 12850 ctx->args[ctx->args_num++] = token->args[i]; 12851 } 12852 return len; 12853 } 12854 12855 int 12856 flow_parse(const char *src, void *result, unsigned int size, 12857 struct rte_flow_attr **attr, 12858 struct rte_flow_item **pattern, struct rte_flow_action **actions) 12859 { 12860 int ret; 12861 struct context saved_flow_ctx = cmd_flow_context; 12862 12863 cmd_flow_context_init(&cmd_flow_context); 12864 do { 12865 ret = cmd_flow_parse(NULL, src, result, size); 12866 if (ret > 0) { 12867 src += ret; 12868 while (isspace(*src)) 12869 src++; 12870 } 12871 } while (ret > 0 && strlen(src)); 12872 cmd_flow_context = saved_flow_ctx; 12873 *attr = &((struct buffer *)result)->args.vc.attr; 12874 *pattern = ((struct buffer *)result)->args.vc.pattern; 12875 *actions = ((struct buffer *)result)->args.vc.actions; 12876 return (ret >= 0 && !strlen(src)) ? 0 : -1; 12877 } 12878 12879 /** Return number of completion entries (cmdline API). */ 12880 static int 12881 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 12882 { 12883 struct context *ctx = &cmd_flow_context; 12884 const struct token *token = &token_list[ctx->curr]; 12885 const enum index *list; 12886 int i; 12887 12888 (void)hdr; 12889 /* Count number of tokens in current list. */ 12890 if (ctx->next_num) 12891 list = ctx->next[ctx->next_num - 1]; 12892 else 12893 list = token->next[0]; 12894 for (i = 0; list[i]; ++i) 12895 ; 12896 if (!i) 12897 return 0; 12898 /* 12899 * If there is a single token, use its completion callback, otherwise 12900 * return the number of entries. 12901 */ 12902 token = &token_list[list[0]]; 12903 if (i == 1 && token->comp) { 12904 /* Save index for cmd_flow_get_help(). */ 12905 ctx->prev = list[0]; 12906 return token->comp(ctx, token, 0, NULL, 0); 12907 } 12908 return i; 12909 } 12910 12911 /** Return a completion entry (cmdline API). */ 12912 static int 12913 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 12914 char *dst, unsigned int size) 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 -1; 12931 /* If there is a single token, use its completion callback. */ 12932 token = &token_list[list[0]]; 12933 if (i == 1 && token->comp) { 12934 /* Save index for cmd_flow_get_help(). */ 12935 ctx->prev = list[0]; 12936 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 12937 } 12938 /* Otherwise make sure the index is valid and use defaults. */ 12939 if (index >= i) 12940 return -1; 12941 token = &token_list[list[index]]; 12942 strlcpy(dst, token->name, size); 12943 /* Save index for cmd_flow_get_help(). */ 12944 ctx->prev = list[index]; 12945 return 0; 12946 } 12947 12948 /** Populate help strings for current token (cmdline API). */ 12949 static int 12950 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 12951 { 12952 struct context *ctx = &cmd_flow_context; 12953 const struct token *token = &token_list[ctx->prev]; 12954 12955 (void)hdr; 12956 if (!size) 12957 return -1; 12958 /* Set token type and update global help with details. */ 12959 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 12960 if (token->help) 12961 cmd_flow.help_str = token->help; 12962 else 12963 cmd_flow.help_str = token->name; 12964 return 0; 12965 } 12966 12967 /** Token definition template (cmdline API). */ 12968 static struct cmdline_token_hdr cmd_flow_token_hdr = { 12969 .ops = &(struct cmdline_token_ops){ 12970 .parse = cmd_flow_parse, 12971 .complete_get_nb = cmd_flow_complete_get_nb, 12972 .complete_get_elt = cmd_flow_complete_get_elt, 12973 .get_help = cmd_flow_get_help, 12974 }, 12975 .offset = 0, 12976 }; 12977 12978 /** Populate the next dynamic token. */ 12979 static void 12980 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 12981 cmdline_parse_token_hdr_t **hdr_inst) 12982 { 12983 struct context *ctx = &cmd_flow_context; 12984 12985 /* Always reinitialize context before requesting the first token. */ 12986 if (!(hdr_inst - cmd_flow.tokens)) 12987 cmd_flow_context_init(ctx); 12988 /* Return NULL when no more tokens are expected. */ 12989 if (!ctx->next_num && ctx->curr) { 12990 *hdr = NULL; 12991 return; 12992 } 12993 /* Determine if command should end here. */ 12994 if (ctx->eol && ctx->last && ctx->next_num) { 12995 const enum index *list = ctx->next[ctx->next_num - 1]; 12996 int i; 12997 12998 for (i = 0; list[i]; ++i) { 12999 if (list[i] != END) 13000 continue; 13001 *hdr = NULL; 13002 return; 13003 } 13004 } 13005 *hdr = &cmd_flow_token_hdr; 13006 } 13007 13008 static SLIST_HEAD(, indlst_conf) indlst_conf_head = 13009 SLIST_HEAD_INITIALIZER(); 13010 13011 static void 13012 indirect_action_flow_conf_create(const struct buffer *in) 13013 { 13014 int len, ret; 13015 uint32_t i; 13016 struct indlst_conf *indlst_conf = NULL; 13017 size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); 13018 struct rte_flow_action *src = in->args.vc.actions; 13019 13020 if (!in->args.vc.actions_n) 13021 goto end; 13022 len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); 13023 if (len <= 0) 13024 goto end; 13025 len = RTE_ALIGN(len, 16); 13026 13027 indlst_conf = calloc(1, base + len + 13028 in->args.vc.actions_n * sizeof(uintptr_t)); 13029 if (!indlst_conf) 13030 goto end; 13031 indlst_conf->id = in->args.vc.attr.group; 13032 indlst_conf->conf_num = in->args.vc.actions_n - 1; 13033 indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); 13034 ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, 13035 len, src, NULL); 13036 if (ret <= 0) { 13037 free(indlst_conf); 13038 indlst_conf = NULL; 13039 goto end; 13040 } 13041 indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); 13042 for (i = 0; i < indlst_conf->conf_num; i++) 13043 indlst_conf->conf[i] = indlst_conf->actions[i].conf; 13044 SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); 13045 end: 13046 if (indlst_conf) 13047 printf("created indirect action list configuration %u\n", 13048 in->args.vc.attr.group); 13049 else 13050 printf("cannot create indirect action list configuration %u\n", 13051 in->args.vc.attr.group); 13052 } 13053 13054 static const struct indlst_conf * 13055 indirect_action_list_conf_get(uint32_t conf_id) 13056 { 13057 const struct indlst_conf *conf; 13058 13059 SLIST_FOREACH(conf, &indlst_conf_head, next) { 13060 if (conf->id == conf_id) 13061 return conf; 13062 } 13063 return NULL; 13064 } 13065 13066 /** Dispatch parsed buffer to function calls. */ 13067 static void 13068 cmd_flow_parsed(const struct buffer *in) 13069 { 13070 switch (in->command) { 13071 case INFO: 13072 port_flow_get_info(in->port); 13073 break; 13074 case CONFIGURE: 13075 port_flow_configure(in->port, 13076 &in->args.configure.port_attr, 13077 in->args.configure.nb_queue, 13078 &in->args.configure.queue_attr); 13079 break; 13080 case PATTERN_TEMPLATE_CREATE: 13081 port_flow_pattern_template_create(in->port, 13082 in->args.vc.pat_templ_id, 13083 &((const struct rte_flow_pattern_template_attr) { 13084 .relaxed_matching = in->args.vc.attr.reserved, 13085 .ingress = in->args.vc.attr.ingress, 13086 .egress = in->args.vc.attr.egress, 13087 .transfer = in->args.vc.attr.transfer, 13088 }), 13089 in->args.vc.pattern); 13090 break; 13091 case PATTERN_TEMPLATE_DESTROY: 13092 port_flow_pattern_template_destroy(in->port, 13093 in->args.templ_destroy.template_id_n, 13094 in->args.templ_destroy.template_id); 13095 break; 13096 case ACTIONS_TEMPLATE_CREATE: 13097 port_flow_actions_template_create(in->port, 13098 in->args.vc.act_templ_id, 13099 &((const struct rte_flow_actions_template_attr) { 13100 .ingress = in->args.vc.attr.ingress, 13101 .egress = in->args.vc.attr.egress, 13102 .transfer = in->args.vc.attr.transfer, 13103 }), 13104 in->args.vc.actions, 13105 in->args.vc.masks); 13106 break; 13107 case ACTIONS_TEMPLATE_DESTROY: 13108 port_flow_actions_template_destroy(in->port, 13109 in->args.templ_destroy.template_id_n, 13110 in->args.templ_destroy.template_id); 13111 break; 13112 case TABLE_CREATE: 13113 port_flow_template_table_create(in->port, in->args.table.id, 13114 &in->args.table.attr, in->args.table.pat_templ_id_n, 13115 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 13116 in->args.table.act_templ_id); 13117 break; 13118 case TABLE_DESTROY: 13119 port_flow_template_table_destroy(in->port, 13120 in->args.table_destroy.table_id_n, 13121 in->args.table_destroy.table_id); 13122 break; 13123 case TABLE_RESIZE_COMPLETE: 13124 port_flow_template_table_resize_complete 13125 (in->port, in->args.table_destroy.table_id[0]); 13126 break; 13127 case GROUP_SET_MISS_ACTIONS: 13128 port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, 13129 in->args.vc.actions); 13130 break; 13131 case TABLE_RESIZE: 13132 port_flow_template_table_resize(in->port, in->args.table.id, 13133 in->args.table.attr.nb_flows); 13134 break; 13135 case QUEUE_CREATE: 13136 port_queue_flow_create(in->port, in->queue, in->postpone, 13137 in->args.vc.table_id, in->args.vc.rule_id, 13138 in->args.vc.pat_templ_id, in->args.vc.act_templ_id, 13139 in->args.vc.pattern, in->args.vc.actions); 13140 break; 13141 case QUEUE_DESTROY: 13142 port_queue_flow_destroy(in->port, in->queue, in->postpone, 13143 in->args.destroy.rule_n, 13144 in->args.destroy.rule); 13145 break; 13146 case QUEUE_FLOW_UPDATE_RESIZED: 13147 port_queue_flow_update_resized(in->port, in->queue, 13148 in->postpone, 13149 in->args.destroy.rule[0]); 13150 break; 13151 case QUEUE_UPDATE: 13152 port_queue_flow_update(in->port, in->queue, in->postpone, 13153 in->args.vc.rule_id, in->args.vc.act_templ_id, 13154 in->args.vc.actions); 13155 break; 13156 case PUSH: 13157 port_queue_flow_push(in->port, in->queue); 13158 break; 13159 case PULL: 13160 port_queue_flow_pull(in->port, in->queue); 13161 break; 13162 case HASH: 13163 if (!in->args.vc.encap_hash) 13164 port_flow_hash_calc(in->port, in->args.vc.table_id, 13165 in->args.vc.pat_templ_id, 13166 in->args.vc.pattern); 13167 else 13168 port_flow_hash_calc_encap(in->port, in->args.vc.field, 13169 in->args.vc.pattern); 13170 break; 13171 case QUEUE_AGED: 13172 port_queue_flow_aged(in->port, in->queue, 13173 in->args.aged.destroy); 13174 break; 13175 case QUEUE_INDIRECT_ACTION_CREATE: 13176 case QUEUE_INDIRECT_ACTION_LIST_CREATE: 13177 port_queue_action_handle_create( 13178 in->port, in->queue, in->postpone, 13179 in->args.vc.attr.group, 13180 &((const struct rte_flow_indir_action_conf) { 13181 .ingress = in->args.vc.attr.ingress, 13182 .egress = in->args.vc.attr.egress, 13183 .transfer = in->args.vc.attr.transfer, 13184 }), 13185 in->args.vc.actions); 13186 break; 13187 case QUEUE_INDIRECT_ACTION_DESTROY: 13188 port_queue_action_handle_destroy(in->port, 13189 in->queue, in->postpone, 13190 in->args.ia_destroy.action_id_n, 13191 in->args.ia_destroy.action_id); 13192 break; 13193 case QUEUE_INDIRECT_ACTION_UPDATE: 13194 port_queue_action_handle_update(in->port, 13195 in->queue, in->postpone, 13196 in->args.vc.attr.group, 13197 in->args.vc.actions); 13198 break; 13199 case QUEUE_INDIRECT_ACTION_QUERY: 13200 port_queue_action_handle_query(in->port, 13201 in->queue, in->postpone, 13202 in->args.ia.action_id); 13203 break; 13204 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 13205 port_queue_action_handle_query_update(in->port, in->queue, 13206 in->postpone, 13207 in->args.ia.action_id, 13208 in->args.ia.qu_mode, 13209 in->args.vc.actions); 13210 break; 13211 case INDIRECT_ACTION_CREATE: 13212 case INDIRECT_ACTION_LIST_CREATE: 13213 port_action_handle_create( 13214 in->port, in->args.vc.attr.group, 13215 in->command == INDIRECT_ACTION_LIST_CREATE, 13216 &((const struct rte_flow_indir_action_conf) { 13217 .ingress = in->args.vc.attr.ingress, 13218 .egress = in->args.vc.attr.egress, 13219 .transfer = in->args.vc.attr.transfer, 13220 }), 13221 in->args.vc.actions); 13222 break; 13223 case INDIRECT_ACTION_FLOW_CONF_CREATE: 13224 indirect_action_flow_conf_create(in); 13225 break; 13226 case INDIRECT_ACTION_DESTROY: 13227 port_action_handle_destroy(in->port, 13228 in->args.ia_destroy.action_id_n, 13229 in->args.ia_destroy.action_id); 13230 break; 13231 case INDIRECT_ACTION_UPDATE: 13232 port_action_handle_update(in->port, in->args.vc.attr.group, 13233 in->args.vc.actions); 13234 break; 13235 case INDIRECT_ACTION_QUERY: 13236 port_action_handle_query(in->port, in->args.ia.action_id); 13237 break; 13238 case INDIRECT_ACTION_QUERY_UPDATE: 13239 port_action_handle_query_update(in->port, 13240 in->args.ia.action_id, 13241 in->args.ia.qu_mode, 13242 in->args.vc.actions); 13243 break; 13244 case VALIDATE: 13245 port_flow_validate(in->port, &in->args.vc.attr, 13246 in->args.vc.pattern, in->args.vc.actions, 13247 &in->args.vc.tunnel_ops); 13248 break; 13249 case CREATE: 13250 port_flow_create(in->port, &in->args.vc.attr, 13251 in->args.vc.pattern, in->args.vc.actions, 13252 &in->args.vc.tunnel_ops, in->args.vc.user_id); 13253 break; 13254 case DESTROY: 13255 port_flow_destroy(in->port, in->args.destroy.rule_n, 13256 in->args.destroy.rule, 13257 in->args.destroy.is_user_id); 13258 break; 13259 case FLUSH: 13260 port_flow_flush(in->port); 13261 break; 13262 case DUMP_ONE: 13263 case DUMP_ALL: 13264 port_flow_dump(in->port, in->args.dump.mode, 13265 in->args.dump.rule, in->args.dump.file, 13266 in->args.dump.is_user_id); 13267 break; 13268 case QUERY: 13269 port_flow_query(in->port, in->args.query.rule, 13270 &in->args.query.action, 13271 in->args.query.is_user_id); 13272 break; 13273 case LIST: 13274 port_flow_list(in->port, in->args.list.group_n, 13275 in->args.list.group); 13276 break; 13277 case ISOLATE: 13278 port_flow_isolate(in->port, in->args.isolate.set); 13279 break; 13280 case AGED: 13281 port_flow_aged(in->port, in->args.aged.destroy); 13282 break; 13283 case TUNNEL_CREATE: 13284 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 13285 break; 13286 case TUNNEL_DESTROY: 13287 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 13288 break; 13289 case TUNNEL_LIST: 13290 port_flow_tunnel_list(in->port); 13291 break; 13292 case ACTION_POL_G: 13293 port_meter_policy_add(in->port, in->args.policy.policy_id, 13294 in->args.vc.actions); 13295 break; 13296 case FLEX_ITEM_CREATE: 13297 flex_item_create(in->port, in->args.flex.token, 13298 in->args.flex.filename); 13299 break; 13300 case FLEX_ITEM_DESTROY: 13301 flex_item_destroy(in->port, in->args.flex.token); 13302 break; 13303 default: 13304 break; 13305 } 13306 fflush(stdout); 13307 } 13308 13309 /** Token generator and output processing callback (cmdline API). */ 13310 static void 13311 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 13312 { 13313 if (cl == NULL) 13314 cmd_flow_tok(arg0, arg2); 13315 else 13316 cmd_flow_parsed(arg0); 13317 } 13318 13319 /** Global parser instance (cmdline API). */ 13320 cmdline_parse_inst_t cmd_flow = { 13321 .f = cmd_flow_cb, 13322 .data = NULL, /**< Unused. */ 13323 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 13324 .tokens = { 13325 NULL, 13326 }, /**< Tokens are returned by cmd_flow_tok(). */ 13327 }; 13328 13329 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 13330 13331 static void 13332 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 13333 { 13334 struct rte_ipv4_hdr *ipv4; 13335 struct rte_ether_hdr *eth; 13336 struct rte_ipv6_hdr *ipv6; 13337 struct rte_vxlan_hdr *vxlan; 13338 struct rte_vxlan_gpe_hdr *gpe; 13339 struct rte_flow_item_nvgre *nvgre; 13340 uint32_t ipv6_vtc_flow; 13341 13342 switch (item->type) { 13343 case RTE_FLOW_ITEM_TYPE_ETH: 13344 eth = (struct rte_ether_hdr *)buf; 13345 if (next_proto) 13346 eth->ether_type = rte_cpu_to_be_16(next_proto); 13347 break; 13348 case RTE_FLOW_ITEM_TYPE_IPV4: 13349 ipv4 = (struct rte_ipv4_hdr *)buf; 13350 if (!ipv4->version_ihl) 13351 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 13352 if (next_proto && ipv4->next_proto_id == 0) 13353 ipv4->next_proto_id = (uint8_t)next_proto; 13354 break; 13355 case RTE_FLOW_ITEM_TYPE_IPV6: 13356 ipv6 = (struct rte_ipv6_hdr *)buf; 13357 if (next_proto && ipv6->proto == 0) 13358 ipv6->proto = (uint8_t)next_proto; 13359 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 13360 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 13361 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 13362 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 13363 break; 13364 case RTE_FLOW_ITEM_TYPE_VXLAN: 13365 vxlan = (struct rte_vxlan_hdr *)buf; 13366 vxlan->vx_flags = 0x08; 13367 break; 13368 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13369 gpe = (struct rte_vxlan_gpe_hdr *)buf; 13370 gpe->vx_flags = 0x0C; 13371 break; 13372 case RTE_FLOW_ITEM_TYPE_NVGRE: 13373 nvgre = (struct rte_flow_item_nvgre *)buf; 13374 nvgre->protocol = rte_cpu_to_be_16(0x6558); 13375 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 13376 break; 13377 default: 13378 break; 13379 } 13380 } 13381 13382 /** Helper of get item's default mask. */ 13383 static const void * 13384 flow_item_default_mask(const struct rte_flow_item *item) 13385 { 13386 const void *mask = NULL; 13387 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 13388 static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { 13389 .hdr = { 13390 .next_hdr = 0xff, 13391 .type = 0xff, 13392 .segments_left = 0xff, 13393 }, 13394 }; 13395 13396 switch (item->type) { 13397 case RTE_FLOW_ITEM_TYPE_ANY: 13398 mask = &rte_flow_item_any_mask; 13399 break; 13400 case RTE_FLOW_ITEM_TYPE_PORT_ID: 13401 mask = &rte_flow_item_port_id_mask; 13402 break; 13403 case RTE_FLOW_ITEM_TYPE_RAW: 13404 mask = &rte_flow_item_raw_mask; 13405 break; 13406 case RTE_FLOW_ITEM_TYPE_ETH: 13407 mask = &rte_flow_item_eth_mask; 13408 break; 13409 case RTE_FLOW_ITEM_TYPE_VLAN: 13410 mask = &rte_flow_item_vlan_mask; 13411 break; 13412 case RTE_FLOW_ITEM_TYPE_IPV4: 13413 mask = &rte_flow_item_ipv4_mask; 13414 break; 13415 case RTE_FLOW_ITEM_TYPE_IPV6: 13416 mask = &rte_flow_item_ipv6_mask; 13417 break; 13418 case RTE_FLOW_ITEM_TYPE_ICMP: 13419 mask = &rte_flow_item_icmp_mask; 13420 break; 13421 case RTE_FLOW_ITEM_TYPE_UDP: 13422 mask = &rte_flow_item_udp_mask; 13423 break; 13424 case RTE_FLOW_ITEM_TYPE_TCP: 13425 mask = &rte_flow_item_tcp_mask; 13426 break; 13427 case RTE_FLOW_ITEM_TYPE_SCTP: 13428 mask = &rte_flow_item_sctp_mask; 13429 break; 13430 case RTE_FLOW_ITEM_TYPE_VXLAN: 13431 mask = &rte_flow_item_vxlan_mask; 13432 break; 13433 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13434 mask = &rte_flow_item_vxlan_gpe_mask; 13435 break; 13436 case RTE_FLOW_ITEM_TYPE_E_TAG: 13437 mask = &rte_flow_item_e_tag_mask; 13438 break; 13439 case RTE_FLOW_ITEM_TYPE_NVGRE: 13440 mask = &rte_flow_item_nvgre_mask; 13441 break; 13442 case RTE_FLOW_ITEM_TYPE_MPLS: 13443 mask = &rte_flow_item_mpls_mask; 13444 break; 13445 case RTE_FLOW_ITEM_TYPE_GRE: 13446 mask = &rte_flow_item_gre_mask; 13447 break; 13448 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13449 mask = &gre_key_default_mask; 13450 break; 13451 case RTE_FLOW_ITEM_TYPE_META: 13452 mask = &rte_flow_item_meta_mask; 13453 break; 13454 case RTE_FLOW_ITEM_TYPE_RANDOM: 13455 mask = &rte_flow_item_random_mask; 13456 break; 13457 case RTE_FLOW_ITEM_TYPE_FUZZY: 13458 mask = &rte_flow_item_fuzzy_mask; 13459 break; 13460 case RTE_FLOW_ITEM_TYPE_GTP: 13461 mask = &rte_flow_item_gtp_mask; 13462 break; 13463 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13464 mask = &rte_flow_item_gtp_psc_mask; 13465 break; 13466 case RTE_FLOW_ITEM_TYPE_GENEVE: 13467 mask = &rte_flow_item_geneve_mask; 13468 break; 13469 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13470 mask = &rte_flow_item_geneve_opt_mask; 13471 break; 13472 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 13473 mask = &rte_flow_item_pppoe_proto_id_mask; 13474 break; 13475 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13476 mask = &rte_flow_item_l2tpv3oip_mask; 13477 break; 13478 case RTE_FLOW_ITEM_TYPE_ESP: 13479 mask = &rte_flow_item_esp_mask; 13480 break; 13481 case RTE_FLOW_ITEM_TYPE_AH: 13482 mask = &rte_flow_item_ah_mask; 13483 break; 13484 case RTE_FLOW_ITEM_TYPE_PFCP: 13485 mask = &rte_flow_item_pfcp_mask; 13486 break; 13487 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 13488 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 13489 mask = &rte_flow_item_ethdev_mask; 13490 break; 13491 case RTE_FLOW_ITEM_TYPE_L2TPV2: 13492 mask = &rte_flow_item_l2tpv2_mask; 13493 break; 13494 case RTE_FLOW_ITEM_TYPE_PPP: 13495 mask = &rte_flow_item_ppp_mask; 13496 break; 13497 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 13498 mask = &rte_flow_item_meter_color_mask; 13499 break; 13500 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13501 mask = &ipv6_routing_ext_default_mask; 13502 break; 13503 case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: 13504 mask = &rte_flow_item_aggr_affinity_mask; 13505 break; 13506 case RTE_FLOW_ITEM_TYPE_TX_QUEUE: 13507 mask = &rte_flow_item_tx_queue_mask; 13508 break; 13509 case RTE_FLOW_ITEM_TYPE_IB_BTH: 13510 mask = &rte_flow_item_ib_bth_mask; 13511 break; 13512 case RTE_FLOW_ITEM_TYPE_PTYPE: 13513 mask = &rte_flow_item_ptype_mask; 13514 break; 13515 default: 13516 break; 13517 } 13518 return mask; 13519 } 13520 13521 /** Dispatch parsed buffer to function calls. */ 13522 static void 13523 cmd_set_ipv6_ext_parsed(const struct buffer *in) 13524 { 13525 uint32_t n = in->args.vc.pattern_n; 13526 int i = 0; 13527 struct rte_flow_item *item = NULL; 13528 size_t size = 0; 13529 uint8_t *data = NULL; 13530 uint8_t *type = NULL; 13531 size_t *total_size = NULL; 13532 uint16_t idx = in->port; /* We borrow port field as index */ 13533 struct rte_flow_item_ipv6_routing_ext *ext; 13534 const struct rte_flow_item_ipv6_ext *ipv6_ext; 13535 13536 RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || 13537 in->command == SET_IPV6_EXT_REMOVE); 13538 13539 if (in->command == SET_IPV6_EXT_REMOVE) { 13540 if (n != 1 || in->args.vc.pattern->type != 13541 RTE_FLOW_ITEM_TYPE_IPV6_EXT) { 13542 fprintf(stderr, "Error - Not supported item\n"); 13543 return; 13544 } 13545 type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; 13546 item = in->args.vc.pattern; 13547 ipv6_ext = item->spec; 13548 *type = ipv6_ext->next_hdr; 13549 return; 13550 } 13551 13552 total_size = &ipv6_ext_push_confs[idx].size; 13553 data = (uint8_t *)&ipv6_ext_push_confs[idx].data; 13554 type = (uint8_t *)&ipv6_ext_push_confs[idx].type; 13555 13556 *total_size = 0; 13557 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13558 for (i = n - 1 ; i >= 0; --i) { 13559 item = in->args.vc.pattern + i; 13560 switch (item->type) { 13561 case RTE_FLOW_ITEM_TYPE_IPV6_EXT: 13562 ipv6_ext = item->spec; 13563 *type = ipv6_ext->next_hdr; 13564 break; 13565 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13566 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13567 if (!ext->hdr.hdr_len) { 13568 size = sizeof(struct rte_ipv6_routing_ext) + 13569 (ext->hdr.segments_left << 4); 13570 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13571 /* Indicate no TLV once SRH. */ 13572 if (ext->hdr.type == 4) 13573 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13574 } else { 13575 size = sizeof(struct rte_ipv6_routing_ext) + 13576 (ext->hdr.hdr_len << 3); 13577 } 13578 *total_size += size; 13579 memcpy(data, ext, size); 13580 break; 13581 default: 13582 fprintf(stderr, "Error - Not supported item\n"); 13583 goto error; 13584 } 13585 } 13586 RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); 13587 return; 13588 error: 13589 *total_size = 0; 13590 memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); 13591 } 13592 13593 /** Dispatch parsed buffer to function calls. */ 13594 static void 13595 cmd_set_raw_parsed_sample(const struct buffer *in) 13596 { 13597 uint32_t n = in->args.vc.actions_n; 13598 uint32_t i = 0; 13599 struct rte_flow_action *action = NULL; 13600 struct rte_flow_action *data = NULL; 13601 const struct rte_flow_action_rss *rss = NULL; 13602 size_t size = 0; 13603 uint16_t idx = in->port; /* We borrow port field as index */ 13604 uint32_t max_size = sizeof(struct rte_flow_action) * 13605 ACTION_SAMPLE_ACTIONS_NUM; 13606 13607 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 13608 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 13609 memset(data, 0x00, max_size); 13610 for (; i <= n - 1; i++) { 13611 action = in->args.vc.actions + i; 13612 if (action->type == RTE_FLOW_ACTION_TYPE_END) 13613 break; 13614 switch (action->type) { 13615 case RTE_FLOW_ACTION_TYPE_MARK: 13616 size = sizeof(struct rte_flow_action_mark); 13617 rte_memcpy(&sample_mark[idx], 13618 (const void *)action->conf, size); 13619 action->conf = &sample_mark[idx]; 13620 break; 13621 case RTE_FLOW_ACTION_TYPE_COUNT: 13622 size = sizeof(struct rte_flow_action_count); 13623 rte_memcpy(&sample_count[idx], 13624 (const void *)action->conf, size); 13625 action->conf = &sample_count[idx]; 13626 break; 13627 case RTE_FLOW_ACTION_TYPE_QUEUE: 13628 size = sizeof(struct rte_flow_action_queue); 13629 rte_memcpy(&sample_queue[idx], 13630 (const void *)action->conf, size); 13631 action->conf = &sample_queue[idx]; 13632 break; 13633 case RTE_FLOW_ACTION_TYPE_RSS: 13634 size = sizeof(struct rte_flow_action_rss); 13635 rss = action->conf; 13636 rte_memcpy(&sample_rss_data[idx].conf, 13637 (const void *)rss, size); 13638 if (rss->key_len && rss->key) { 13639 sample_rss_data[idx].conf.key = 13640 sample_rss_data[idx].key; 13641 rte_memcpy((void *)((uintptr_t) 13642 sample_rss_data[idx].conf.key), 13643 (const void *)rss->key, 13644 sizeof(uint8_t) * rss->key_len); 13645 } 13646 if (rss->queue_num && rss->queue) { 13647 sample_rss_data[idx].conf.queue = 13648 sample_rss_data[idx].queue; 13649 rte_memcpy((void *)((uintptr_t) 13650 sample_rss_data[idx].conf.queue), 13651 (const void *)rss->queue, 13652 sizeof(uint16_t) * rss->queue_num); 13653 } 13654 action->conf = &sample_rss_data[idx].conf; 13655 break; 13656 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 13657 size = sizeof(struct rte_flow_action_raw_encap); 13658 rte_memcpy(&sample_encap[idx], 13659 (const void *)action->conf, size); 13660 action->conf = &sample_encap[idx]; 13661 break; 13662 case RTE_FLOW_ACTION_TYPE_PORT_ID: 13663 size = sizeof(struct rte_flow_action_port_id); 13664 rte_memcpy(&sample_port_id[idx], 13665 (const void *)action->conf, size); 13666 action->conf = &sample_port_id[idx]; 13667 break; 13668 case RTE_FLOW_ACTION_TYPE_PF: 13669 break; 13670 case RTE_FLOW_ACTION_TYPE_VF: 13671 size = sizeof(struct rte_flow_action_vf); 13672 rte_memcpy(&sample_vf[idx], 13673 (const void *)action->conf, size); 13674 action->conf = &sample_vf[idx]; 13675 break; 13676 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 13677 size = sizeof(struct rte_flow_action_vxlan_encap); 13678 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 13679 action->conf = &sample_vxlan_encap[idx].conf; 13680 break; 13681 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 13682 size = sizeof(struct rte_flow_action_nvgre_encap); 13683 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 13684 action->conf = &sample_nvgre_encap[idx]; 13685 break; 13686 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 13687 size = sizeof(struct rte_flow_action_ethdev); 13688 rte_memcpy(&sample_port_representor[idx], 13689 (const void *)action->conf, size); 13690 action->conf = &sample_port_representor[idx]; 13691 break; 13692 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 13693 size = sizeof(struct rte_flow_action_ethdev); 13694 rte_memcpy(&sample_represented_port[idx], 13695 (const void *)action->conf, size); 13696 action->conf = &sample_represented_port[idx]; 13697 break; 13698 default: 13699 fprintf(stderr, "Error - Not supported action\n"); 13700 return; 13701 } 13702 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 13703 data++; 13704 } 13705 } 13706 13707 /** Dispatch parsed buffer to function calls. */ 13708 static void 13709 cmd_set_raw_parsed(const struct buffer *in) 13710 { 13711 uint32_t n = in->args.vc.pattern_n; 13712 int i = 0; 13713 struct rte_flow_item *item = NULL; 13714 size_t size = 0; 13715 uint8_t *data = NULL; 13716 uint8_t *data_tail = NULL; 13717 size_t *total_size = NULL; 13718 uint16_t upper_layer = 0; 13719 uint16_t proto = 0; 13720 uint16_t idx = in->port; /* We borrow port field as index */ 13721 int gtp_psc = -1; /* GTP PSC option index. */ 13722 const void *src_spec; 13723 13724 if (in->command == SET_SAMPLE_ACTIONS) 13725 return cmd_set_raw_parsed_sample(in); 13726 else if (in->command == SET_IPV6_EXT_PUSH || 13727 in->command == SET_IPV6_EXT_REMOVE) 13728 return cmd_set_ipv6_ext_parsed(in); 13729 RTE_ASSERT(in->command == SET_RAW_ENCAP || 13730 in->command == SET_RAW_DECAP); 13731 if (in->command == SET_RAW_ENCAP) { 13732 total_size = &raw_encap_confs[idx].size; 13733 data = (uint8_t *)&raw_encap_confs[idx].data; 13734 } else { 13735 total_size = &raw_decap_confs[idx].size; 13736 data = (uint8_t *)&raw_decap_confs[idx].data; 13737 } 13738 *total_size = 0; 13739 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13740 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 13741 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 13742 for (i = n - 1 ; i >= 0; --i) { 13743 const struct rte_flow_item_gtp *gtp; 13744 const struct rte_flow_item_geneve_opt *opt; 13745 struct rte_flow_item_ipv6_routing_ext *ext; 13746 13747 item = in->args.vc.pattern + i; 13748 if (item->spec == NULL) 13749 item->spec = flow_item_default_mask(item); 13750 src_spec = item->spec; 13751 switch (item->type) { 13752 case RTE_FLOW_ITEM_TYPE_ETH: 13753 size = sizeof(struct rte_ether_hdr); 13754 break; 13755 case RTE_FLOW_ITEM_TYPE_VLAN: 13756 size = sizeof(struct rte_vlan_hdr); 13757 proto = RTE_ETHER_TYPE_VLAN; 13758 break; 13759 case RTE_FLOW_ITEM_TYPE_IPV4: 13760 size = sizeof(struct rte_ipv4_hdr); 13761 proto = RTE_ETHER_TYPE_IPV4; 13762 break; 13763 case RTE_FLOW_ITEM_TYPE_IPV6: 13764 size = sizeof(struct rte_ipv6_hdr); 13765 proto = RTE_ETHER_TYPE_IPV6; 13766 break; 13767 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13768 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13769 if (!ext->hdr.hdr_len) { 13770 size = sizeof(struct rte_ipv6_routing_ext) + 13771 (ext->hdr.segments_left << 4); 13772 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13773 /* SRv6 without TLV. */ 13774 if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) 13775 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13776 } else { 13777 size = sizeof(struct rte_ipv6_routing_ext) + 13778 (ext->hdr.hdr_len << 3); 13779 } 13780 proto = IPPROTO_ROUTING; 13781 break; 13782 case RTE_FLOW_ITEM_TYPE_UDP: 13783 size = sizeof(struct rte_udp_hdr); 13784 proto = 0x11; 13785 break; 13786 case RTE_FLOW_ITEM_TYPE_TCP: 13787 size = sizeof(struct rte_tcp_hdr); 13788 proto = 0x06; 13789 break; 13790 case RTE_FLOW_ITEM_TYPE_VXLAN: 13791 size = sizeof(struct rte_vxlan_hdr); 13792 break; 13793 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13794 size = sizeof(struct rte_vxlan_gpe_hdr); 13795 break; 13796 case RTE_FLOW_ITEM_TYPE_GRE: 13797 size = sizeof(struct rte_gre_hdr); 13798 proto = 0x2F; 13799 break; 13800 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13801 size = sizeof(rte_be32_t); 13802 proto = 0x0; 13803 break; 13804 case RTE_FLOW_ITEM_TYPE_MPLS: 13805 size = sizeof(struct rte_mpls_hdr); 13806 proto = 0x0; 13807 break; 13808 case RTE_FLOW_ITEM_TYPE_NVGRE: 13809 size = sizeof(struct rte_flow_item_nvgre); 13810 proto = 0x2F; 13811 break; 13812 case RTE_FLOW_ITEM_TYPE_GENEVE: 13813 size = sizeof(struct rte_geneve_hdr); 13814 break; 13815 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13816 opt = (const struct rte_flow_item_geneve_opt *) 13817 item->spec; 13818 size = offsetof(struct rte_flow_item_geneve_opt, 13819 option_len) + sizeof(uint8_t); 13820 if (opt->option_len && opt->data) { 13821 *total_size += opt->option_len * 13822 sizeof(uint32_t); 13823 rte_memcpy(data_tail - (*total_size), 13824 opt->data, 13825 opt->option_len * sizeof(uint32_t)); 13826 } 13827 break; 13828 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13829 size = sizeof(rte_be32_t); 13830 proto = 0x73; 13831 break; 13832 case RTE_FLOW_ITEM_TYPE_ESP: 13833 size = sizeof(struct rte_esp_hdr); 13834 proto = 0x32; 13835 break; 13836 case RTE_FLOW_ITEM_TYPE_AH: 13837 size = sizeof(struct rte_flow_item_ah); 13838 proto = 0x33; 13839 break; 13840 case RTE_FLOW_ITEM_TYPE_GTP: 13841 if (gtp_psc < 0) { 13842 size = sizeof(struct rte_gtp_hdr); 13843 break; 13844 } 13845 if (gtp_psc != i + 1) { 13846 fprintf(stderr, 13847 "Error - GTP PSC does not follow GTP\n"); 13848 goto error; 13849 } 13850 gtp = item->spec; 13851 if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { 13852 /* Only E flag should be set. */ 13853 fprintf(stderr, 13854 "Error - GTP unsupported flags\n"); 13855 goto error; 13856 } else { 13857 struct rte_gtp_hdr_ext_word ext_word = { 13858 .next_ext = 0x85 13859 }; 13860 13861 /* We have to add GTP header extra word. */ 13862 *total_size += sizeof(ext_word); 13863 rte_memcpy(data_tail - (*total_size), 13864 &ext_word, sizeof(ext_word)); 13865 } 13866 size = sizeof(struct rte_gtp_hdr); 13867 break; 13868 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13869 if (gtp_psc >= 0) { 13870 fprintf(stderr, 13871 "Error - Multiple GTP PSC items\n"); 13872 goto error; 13873 } else { 13874 const struct rte_flow_item_gtp_psc 13875 *opt = item->spec; 13876 struct rte_gtp_psc_generic_hdr *hdr; 13877 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 13878 sizeof(int32_t)); 13879 13880 *total_size += hdr_size; 13881 hdr = (typeof(hdr))(data_tail - (*total_size)); 13882 memset(hdr, 0, hdr_size); 13883 *hdr = opt->hdr; 13884 hdr->ext_hdr_len = 1; 13885 gtp_psc = i; 13886 size = 0; 13887 } 13888 break; 13889 case RTE_FLOW_ITEM_TYPE_PFCP: 13890 size = sizeof(struct rte_flow_item_pfcp); 13891 break; 13892 case RTE_FLOW_ITEM_TYPE_FLEX: 13893 if (item->spec != NULL) { 13894 size = ((const struct rte_flow_item_flex *)item->spec)->length; 13895 src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; 13896 } else { 13897 size = 0; 13898 src_spec = NULL; 13899 } 13900 break; 13901 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 13902 size = 0; 13903 if (item->spec) { 13904 const struct rte_flow_item_gre_opt 13905 *opt = item->spec; 13906 if (opt->checksum_rsvd.checksum) { 13907 *total_size += 13908 sizeof(opt->checksum_rsvd); 13909 rte_memcpy(data_tail - (*total_size), 13910 &opt->checksum_rsvd, 13911 sizeof(opt->checksum_rsvd)); 13912 } 13913 if (opt->key.key) { 13914 *total_size += sizeof(opt->key.key); 13915 rte_memcpy(data_tail - (*total_size), 13916 &opt->key.key, 13917 sizeof(opt->key.key)); 13918 } 13919 if (opt->sequence.sequence) { 13920 *total_size += sizeof(opt->sequence.sequence); 13921 rte_memcpy(data_tail - (*total_size), 13922 &opt->sequence.sequence, 13923 sizeof(opt->sequence.sequence)); 13924 } 13925 } 13926 proto = 0x2F; 13927 break; 13928 default: 13929 fprintf(stderr, "Error - Not supported item\n"); 13930 goto error; 13931 } 13932 if (size) { 13933 *total_size += size; 13934 rte_memcpy(data_tail - (*total_size), src_spec, size); 13935 /* update some fields which cannot be set by cmdline */ 13936 update_fields((data_tail - (*total_size)), item, 13937 upper_layer); 13938 upper_layer = proto; 13939 } 13940 } 13941 if (verbose_level & 0x1) 13942 printf("total data size is %zu\n", (*total_size)); 13943 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 13944 memmove(data, (data_tail - (*total_size)), *total_size); 13945 return; 13946 13947 error: 13948 *total_size = 0; 13949 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13950 } 13951 13952 /** Populate help strings for current token (cmdline API). */ 13953 static int 13954 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 13955 unsigned int size) 13956 { 13957 struct context *ctx = &cmd_flow_context; 13958 const struct token *token = &token_list[ctx->prev]; 13959 13960 (void)hdr; 13961 if (!size) 13962 return -1; 13963 /* Set token type and update global help with details. */ 13964 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 13965 if (token->help) 13966 cmd_set_raw.help_str = token->help; 13967 else 13968 cmd_set_raw.help_str = token->name; 13969 return 0; 13970 } 13971 13972 /** Token definition template (cmdline API). */ 13973 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 13974 .ops = &(struct cmdline_token_ops){ 13975 .parse = cmd_flow_parse, 13976 .complete_get_nb = cmd_flow_complete_get_nb, 13977 .complete_get_elt = cmd_flow_complete_get_elt, 13978 .get_help = cmd_set_raw_get_help, 13979 }, 13980 .offset = 0, 13981 }; 13982 13983 /** Populate the next dynamic token. */ 13984 static void 13985 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 13986 cmdline_parse_token_hdr_t **hdr_inst) 13987 { 13988 struct context *ctx = &cmd_flow_context; 13989 13990 /* Always reinitialize context before requesting the first token. */ 13991 if (!(hdr_inst - cmd_set_raw.tokens)) { 13992 cmd_flow_context_init(ctx); 13993 ctx->curr = START_SET; 13994 } 13995 /* Return NULL when no more tokens are expected. */ 13996 if (!ctx->next_num && (ctx->curr != START_SET)) { 13997 *hdr = NULL; 13998 return; 13999 } 14000 /* Determine if command should end here. */ 14001 if (ctx->eol && ctx->last && ctx->next_num) { 14002 const enum index *list = ctx->next[ctx->next_num - 1]; 14003 int i; 14004 14005 for (i = 0; list[i]; ++i) { 14006 if (list[i] != END) 14007 continue; 14008 *hdr = NULL; 14009 return; 14010 } 14011 } 14012 *hdr = &cmd_set_raw_token_hdr; 14013 } 14014 14015 /** Token generator and output processing callback (cmdline API). */ 14016 static void 14017 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 14018 { 14019 if (cl == NULL) 14020 cmd_set_raw_tok(arg0, arg2); 14021 else 14022 cmd_set_raw_parsed(arg0); 14023 } 14024 14025 /** Global parser instance (cmdline API). */ 14026 cmdline_parse_inst_t cmd_set_raw = { 14027 .f = cmd_set_raw_cb, 14028 .data = NULL, /**< Unused. */ 14029 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 14030 .tokens = { 14031 NULL, 14032 }, /**< Tokens are returned by cmd_flow_tok(). */ 14033 }; 14034 14035 /* *** display raw_encap/raw_decap buf */ 14036 struct cmd_show_set_raw_result { 14037 cmdline_fixed_string_t cmd_show; 14038 cmdline_fixed_string_t cmd_what; 14039 cmdline_fixed_string_t cmd_all; 14040 uint16_t cmd_index; 14041 }; 14042 14043 static void 14044 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 14045 { 14046 struct cmd_show_set_raw_result *res = parsed_result; 14047 uint16_t index = res->cmd_index; 14048 uint8_t all = 0; 14049 uint8_t *raw_data = NULL; 14050 size_t raw_size = 0; 14051 char title[16] = {0}; 14052 14053 RTE_SET_USED(cl); 14054 RTE_SET_USED(data); 14055 if (!strcmp(res->cmd_all, "all")) { 14056 all = 1; 14057 index = 0; 14058 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 14059 fprintf(stderr, "index should be 0-%u\n", 14060 RAW_ENCAP_CONFS_MAX_NUM - 1); 14061 return; 14062 } 14063 do { 14064 if (!strcmp(res->cmd_what, "raw_encap")) { 14065 raw_data = (uint8_t *)&raw_encap_confs[index].data; 14066 raw_size = raw_encap_confs[index].size; 14067 snprintf(title, 16, "\nindex: %u", index); 14068 rte_hexdump(stdout, title, raw_data, raw_size); 14069 } else { 14070 raw_data = (uint8_t *)&raw_decap_confs[index].data; 14071 raw_size = raw_decap_confs[index].size; 14072 snprintf(title, 16, "\nindex: %u", index); 14073 rte_hexdump(stdout, title, raw_data, raw_size); 14074 } 14075 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 14076 } 14077 14078 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 14079 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14080 cmd_show, "show"); 14081 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 14082 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14083 cmd_what, "raw_encap#raw_decap"); 14084 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 14085 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 14086 cmd_index, RTE_UINT16); 14087 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 14088 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14089 cmd_all, "all"); 14090 cmdline_parse_inst_t cmd_show_set_raw = { 14091 .f = cmd_show_set_raw_parsed, 14092 .data = NULL, 14093 .help_str = "show <raw_encap|raw_decap> <index>", 14094 .tokens = { 14095 (void *)&cmd_show_set_raw_cmd_show, 14096 (void *)&cmd_show_set_raw_cmd_what, 14097 (void *)&cmd_show_set_raw_cmd_index, 14098 NULL, 14099 }, 14100 }; 14101 cmdline_parse_inst_t cmd_show_set_raw_all = { 14102 .f = cmd_show_set_raw_parsed, 14103 .data = NULL, 14104 .help_str = "show <raw_encap|raw_decap> all", 14105 .tokens = { 14106 (void *)&cmd_show_set_raw_cmd_show, 14107 (void *)&cmd_show_set_raw_cmd_what, 14108 (void *)&cmd_show_set_raw_cmd_all, 14109 NULL, 14110 }, 14111 }; 14112