1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2016 6WIND S.A. 3 * Copyright 2016 Mellanox Technologies, Ltd 4 */ 5 6 #include <stddef.h> 7 #include <stdint.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <inttypes.h> 11 #include <errno.h> 12 #include <ctype.h> 13 #include <string.h> 14 15 #include <rte_string_fns.h> 16 #include <rte_common.h> 17 #include <rte_ethdev.h> 18 #include <rte_byteorder.h> 19 #include <cmdline_parse.h> 20 #include <cmdline_parse_etheraddr.h> 21 #include <cmdline_parse_string.h> 22 #include <cmdline_parse_num.h> 23 #include <rte_flow.h> 24 #include <rte_hexdump.h> 25 #include <rte_vxlan.h> 26 #include <rte_gre.h> 27 #include <rte_mpls.h> 28 #include <rte_gtp.h> 29 #include <rte_geneve.h> 30 31 #include "testpmd.h" 32 33 /** Parser token indices. */ 34 enum index { 35 /* Special tokens. */ 36 ZERO = 0, 37 END, 38 START_SET, 39 END_SET, 40 41 /* Common tokens. */ 42 COMMON_INTEGER, 43 COMMON_UNSIGNED, 44 COMMON_PREFIX, 45 COMMON_BOOLEAN, 46 COMMON_STRING, 47 COMMON_HEX, 48 COMMON_FILE_PATH, 49 COMMON_MAC_ADDR, 50 COMMON_IPV4_ADDR, 51 COMMON_IPV6_ADDR, 52 COMMON_RULE_ID, 53 COMMON_PORT_ID, 54 COMMON_GROUP_ID, 55 COMMON_PRIORITY_LEVEL, 56 COMMON_INDIRECT_ACTION_ID, 57 COMMON_PROFILE_ID, 58 COMMON_POLICY_ID, 59 COMMON_FLEX_HANDLE, 60 COMMON_FLEX_TOKEN, 61 COMMON_PATTERN_TEMPLATE_ID, 62 COMMON_ACTIONS_TEMPLATE_ID, 63 COMMON_TABLE_ID, 64 COMMON_QUEUE_ID, 65 66 /* TOP-level command. */ 67 ADD, 68 69 /* Top-level command. */ 70 SET, 71 /* Sub-leve commands. */ 72 SET_RAW_ENCAP, 73 SET_RAW_DECAP, 74 SET_RAW_INDEX, 75 SET_SAMPLE_ACTIONS, 76 SET_SAMPLE_INDEX, 77 SET_IPV6_EXT_REMOVE, 78 SET_IPV6_EXT_PUSH, 79 SET_IPV6_EXT_INDEX, 80 81 /* Top-level command. */ 82 FLOW, 83 /* Sub-level commands. */ 84 INFO, 85 CONFIGURE, 86 PATTERN_TEMPLATE, 87 ACTIONS_TEMPLATE, 88 TABLE, 89 FLOW_GROUP, 90 INDIRECT_ACTION, 91 VALIDATE, 92 CREATE, 93 DESTROY, 94 FLUSH, 95 DUMP, 96 QUERY, 97 LIST, 98 AGED, 99 ISOLATE, 100 TUNNEL, 101 FLEX, 102 QUEUE, 103 PUSH, 104 PULL, 105 HASH, 106 107 /* Flex arguments */ 108 FLEX_ITEM_INIT, 109 FLEX_ITEM_CREATE, 110 FLEX_ITEM_DESTROY, 111 112 /* Pattern template arguments. */ 113 PATTERN_TEMPLATE_CREATE, 114 PATTERN_TEMPLATE_DESTROY, 115 PATTERN_TEMPLATE_CREATE_ID, 116 PATTERN_TEMPLATE_DESTROY_ID, 117 PATTERN_TEMPLATE_RELAXED_MATCHING, 118 PATTERN_TEMPLATE_INGRESS, 119 PATTERN_TEMPLATE_EGRESS, 120 PATTERN_TEMPLATE_TRANSFER, 121 PATTERN_TEMPLATE_SPEC, 122 123 /* Actions template arguments. */ 124 ACTIONS_TEMPLATE_CREATE, 125 ACTIONS_TEMPLATE_DESTROY, 126 ACTIONS_TEMPLATE_CREATE_ID, 127 ACTIONS_TEMPLATE_DESTROY_ID, 128 ACTIONS_TEMPLATE_INGRESS, 129 ACTIONS_TEMPLATE_EGRESS, 130 ACTIONS_TEMPLATE_TRANSFER, 131 ACTIONS_TEMPLATE_SPEC, 132 ACTIONS_TEMPLATE_MASK, 133 134 /* Queue arguments. */ 135 QUEUE_CREATE, 136 QUEUE_DESTROY, 137 QUEUE_FLOW_UPDATE_RESIZED, 138 QUEUE_UPDATE, 139 QUEUE_AGED, 140 QUEUE_INDIRECT_ACTION, 141 142 /* Queue create arguments. */ 143 QUEUE_CREATE_POSTPONE, 144 QUEUE_TEMPLATE_TABLE, 145 QUEUE_PATTERN_TEMPLATE, 146 QUEUE_ACTIONS_TEMPLATE, 147 QUEUE_RULE_ID, 148 149 /* Queue destroy arguments. */ 150 QUEUE_DESTROY_ID, 151 QUEUE_DESTROY_POSTPONE, 152 153 /* Queue update arguments. */ 154 QUEUE_UPDATE_ID, 155 156 /* Queue indirect action arguments */ 157 QUEUE_INDIRECT_ACTION_CREATE, 158 QUEUE_INDIRECT_ACTION_LIST_CREATE, 159 QUEUE_INDIRECT_ACTION_UPDATE, 160 QUEUE_INDIRECT_ACTION_DESTROY, 161 QUEUE_INDIRECT_ACTION_QUERY, 162 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 163 164 /* Queue indirect action create arguments */ 165 QUEUE_INDIRECT_ACTION_CREATE_ID, 166 QUEUE_INDIRECT_ACTION_INGRESS, 167 QUEUE_INDIRECT_ACTION_EGRESS, 168 QUEUE_INDIRECT_ACTION_TRANSFER, 169 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 170 QUEUE_INDIRECT_ACTION_SPEC, 171 QUEUE_INDIRECT_ACTION_LIST, 172 173 /* Queue indirect action update arguments */ 174 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 175 176 /* Queue indirect action destroy arguments */ 177 QUEUE_INDIRECT_ACTION_DESTROY_ID, 178 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 179 180 /* Queue indirect action query arguments */ 181 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 182 183 /* Queue indirect action query_update arguments */ 184 QUEUE_INDIRECT_ACTION_QU_MODE, 185 186 /* Push arguments. */ 187 PUSH_QUEUE, 188 189 /* Pull arguments. */ 190 PULL_QUEUE, 191 192 /* Table arguments. */ 193 TABLE_CREATE, 194 TABLE_DESTROY, 195 TABLE_RESIZE, 196 TABLE_RESIZE_COMPLETE, 197 TABLE_CREATE_ID, 198 TABLE_DESTROY_ID, 199 TABLE_RESIZE_ID, 200 TABLE_RESIZE_RULES_NUMBER, 201 TABLE_INSERTION_TYPE, 202 TABLE_INSERTION_TYPE_NAME, 203 TABLE_HASH_FUNC, 204 TABLE_HASH_FUNC_NAME, 205 TABLE_GROUP, 206 TABLE_PRIORITY, 207 TABLE_INGRESS, 208 TABLE_EGRESS, 209 TABLE_TRANSFER, 210 TABLE_TRANSFER_WIRE_ORIG, 211 TABLE_TRANSFER_VPORT_ORIG, 212 TABLE_RESIZABLE, 213 TABLE_RULES_NUMBER, 214 TABLE_PATTERN_TEMPLATE, 215 TABLE_ACTIONS_TEMPLATE, 216 217 /* Group arguments */ 218 GROUP_ID, 219 GROUP_INGRESS, 220 GROUP_EGRESS, 221 GROUP_TRANSFER, 222 GROUP_SET_MISS_ACTIONS, 223 224 /* Hash calculation arguments. */ 225 HASH_CALC_TABLE, 226 HASH_CALC_PATTERN_INDEX, 227 HASH_CALC_PATTERN, 228 HASH_CALC_ENCAP, 229 HASH_CALC_DEST, 230 ENCAP_HASH_FIELD_SRC_PORT, 231 ENCAP_HASH_FIELD_GRE_FLOW_ID, 232 233 /* Tunnel arguments. */ 234 TUNNEL_CREATE, 235 TUNNEL_CREATE_TYPE, 236 TUNNEL_LIST, 237 TUNNEL_DESTROY, 238 TUNNEL_DESTROY_ID, 239 240 /* Destroy arguments. */ 241 DESTROY_RULE, 242 DESTROY_IS_USER_ID, 243 244 /* Query arguments. */ 245 QUERY_ACTION, 246 QUERY_IS_USER_ID, 247 248 /* List arguments. */ 249 LIST_GROUP, 250 251 /* Destroy aged flow arguments. */ 252 AGED_DESTROY, 253 254 /* Validate/create arguments. */ 255 VC_GROUP, 256 VC_PRIORITY, 257 VC_INGRESS, 258 VC_EGRESS, 259 VC_TRANSFER, 260 VC_TUNNEL_SET, 261 VC_TUNNEL_MATCH, 262 VC_USER_ID, 263 264 /* Dump arguments */ 265 DUMP_ALL, 266 DUMP_ONE, 267 DUMP_IS_USER_ID, 268 269 /* Configure arguments */ 270 CONFIG_QUEUES_NUMBER, 271 CONFIG_QUEUES_SIZE, 272 CONFIG_COUNTERS_NUMBER, 273 CONFIG_AGING_OBJECTS_NUMBER, 274 CONFIG_METERS_NUMBER, 275 CONFIG_CONN_TRACK_NUMBER, 276 CONFIG_QUOTAS_NUMBER, 277 CONFIG_FLAGS, 278 CONFIG_HOST_PORT, 279 280 /* Indirect action arguments */ 281 INDIRECT_ACTION_CREATE, 282 INDIRECT_ACTION_LIST_CREATE, 283 INDIRECT_ACTION_FLOW_CONF_CREATE, 284 INDIRECT_ACTION_UPDATE, 285 INDIRECT_ACTION_DESTROY, 286 INDIRECT_ACTION_QUERY, 287 INDIRECT_ACTION_QUERY_UPDATE, 288 289 /* Indirect action create arguments */ 290 INDIRECT_ACTION_CREATE_ID, 291 INDIRECT_ACTION_INGRESS, 292 INDIRECT_ACTION_EGRESS, 293 INDIRECT_ACTION_TRANSFER, 294 INDIRECT_ACTION_SPEC, 295 INDIRECT_ACTION_LIST, 296 INDIRECT_ACTION_FLOW_CONF, 297 298 /* Indirect action destroy arguments */ 299 INDIRECT_ACTION_DESTROY_ID, 300 301 /* Indirect action query-and-update arguments */ 302 INDIRECT_ACTION_QU_MODE, 303 INDIRECT_ACTION_QU_MODE_NAME, 304 305 /* Validate/create pattern. */ 306 ITEM_PATTERN, 307 ITEM_PARAM_IS, 308 ITEM_PARAM_SPEC, 309 ITEM_PARAM_LAST, 310 ITEM_PARAM_MASK, 311 ITEM_PARAM_PREFIX, 312 ITEM_NEXT, 313 ITEM_END, 314 ITEM_VOID, 315 ITEM_INVERT, 316 ITEM_ANY, 317 ITEM_ANY_NUM, 318 ITEM_PORT_ID, 319 ITEM_PORT_ID_ID, 320 ITEM_MARK, 321 ITEM_MARK_ID, 322 ITEM_RAW, 323 ITEM_RAW_RELATIVE, 324 ITEM_RAW_SEARCH, 325 ITEM_RAW_OFFSET, 326 ITEM_RAW_LIMIT, 327 ITEM_RAW_PATTERN, 328 ITEM_RAW_PATTERN_HEX, 329 ITEM_ETH, 330 ITEM_ETH_DST, 331 ITEM_ETH_SRC, 332 ITEM_ETH_TYPE, 333 ITEM_ETH_HAS_VLAN, 334 ITEM_VLAN, 335 ITEM_VLAN_TCI, 336 ITEM_VLAN_PCP, 337 ITEM_VLAN_DEI, 338 ITEM_VLAN_VID, 339 ITEM_VLAN_INNER_TYPE, 340 ITEM_VLAN_HAS_MORE_VLAN, 341 ITEM_IPV4, 342 ITEM_IPV4_VER_IHL, 343 ITEM_IPV4_TOS, 344 ITEM_IPV4_LENGTH, 345 ITEM_IPV4_ID, 346 ITEM_IPV4_FRAGMENT_OFFSET, 347 ITEM_IPV4_TTL, 348 ITEM_IPV4_PROTO, 349 ITEM_IPV4_SRC, 350 ITEM_IPV4_DST, 351 ITEM_IPV6, 352 ITEM_IPV6_TC, 353 ITEM_IPV6_FLOW, 354 ITEM_IPV6_LEN, 355 ITEM_IPV6_PROTO, 356 ITEM_IPV6_HOP, 357 ITEM_IPV6_SRC, 358 ITEM_IPV6_DST, 359 ITEM_IPV6_HAS_FRAG_EXT, 360 ITEM_IPV6_ROUTING_EXT, 361 ITEM_IPV6_ROUTING_EXT_TYPE, 362 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 363 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 364 ITEM_ICMP, 365 ITEM_ICMP_TYPE, 366 ITEM_ICMP_CODE, 367 ITEM_ICMP_IDENT, 368 ITEM_ICMP_SEQ, 369 ITEM_UDP, 370 ITEM_UDP_SRC, 371 ITEM_UDP_DST, 372 ITEM_TCP, 373 ITEM_TCP_SRC, 374 ITEM_TCP_DST, 375 ITEM_TCP_FLAGS, 376 ITEM_SCTP, 377 ITEM_SCTP_SRC, 378 ITEM_SCTP_DST, 379 ITEM_SCTP_TAG, 380 ITEM_SCTP_CKSUM, 381 ITEM_VXLAN, 382 ITEM_VXLAN_VNI, 383 ITEM_VXLAN_LAST_RSVD, 384 ITEM_E_TAG, 385 ITEM_E_TAG_GRP_ECID_B, 386 ITEM_NVGRE, 387 ITEM_NVGRE_TNI, 388 ITEM_MPLS, 389 ITEM_MPLS_LABEL, 390 ITEM_MPLS_TC, 391 ITEM_MPLS_S, 392 ITEM_MPLS_TTL, 393 ITEM_GRE, 394 ITEM_GRE_PROTO, 395 ITEM_GRE_C_RSVD0_VER, 396 ITEM_GRE_C_BIT, 397 ITEM_GRE_K_BIT, 398 ITEM_GRE_S_BIT, 399 ITEM_FUZZY, 400 ITEM_FUZZY_THRESH, 401 ITEM_GTP, 402 ITEM_GTP_FLAGS, 403 ITEM_GTP_MSG_TYPE, 404 ITEM_GTP_TEID, 405 ITEM_GTPC, 406 ITEM_GTPU, 407 ITEM_GENEVE, 408 ITEM_GENEVE_VNI, 409 ITEM_GENEVE_PROTO, 410 ITEM_GENEVE_OPTLEN, 411 ITEM_VXLAN_GPE, 412 ITEM_VXLAN_GPE_VNI, 413 ITEM_VXLAN_GPE_PROTO, 414 ITEM_VXLAN_GPE_FLAGS, 415 ITEM_ARP_ETH_IPV4, 416 ITEM_ARP_ETH_IPV4_SHA, 417 ITEM_ARP_ETH_IPV4_SPA, 418 ITEM_ARP_ETH_IPV4_THA, 419 ITEM_ARP_ETH_IPV4_TPA, 420 ITEM_IPV6_EXT, 421 ITEM_IPV6_EXT_NEXT_HDR, 422 ITEM_IPV6_FRAG_EXT, 423 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 424 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 425 ITEM_IPV6_FRAG_EXT_ID, 426 ITEM_ICMP6, 427 ITEM_ICMP6_TYPE, 428 ITEM_ICMP6_CODE, 429 ITEM_ICMP6_ECHO_REQUEST, 430 ITEM_ICMP6_ECHO_REQUEST_ID, 431 ITEM_ICMP6_ECHO_REQUEST_SEQ, 432 ITEM_ICMP6_ECHO_REPLY, 433 ITEM_ICMP6_ECHO_REPLY_ID, 434 ITEM_ICMP6_ECHO_REPLY_SEQ, 435 ITEM_ICMP6_ND_NS, 436 ITEM_ICMP6_ND_NS_TARGET_ADDR, 437 ITEM_ICMP6_ND_NA, 438 ITEM_ICMP6_ND_NA_TARGET_ADDR, 439 ITEM_ICMP6_ND_OPT, 440 ITEM_ICMP6_ND_OPT_TYPE, 441 ITEM_ICMP6_ND_OPT_SLA_ETH, 442 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 443 ITEM_ICMP6_ND_OPT_TLA_ETH, 444 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 445 ITEM_META, 446 ITEM_META_DATA, 447 ITEM_RANDOM, 448 ITEM_RANDOM_VALUE, 449 ITEM_GRE_KEY, 450 ITEM_GRE_KEY_VALUE, 451 ITEM_GRE_OPTION, 452 ITEM_GRE_OPTION_CHECKSUM, 453 ITEM_GRE_OPTION_KEY, 454 ITEM_GRE_OPTION_SEQUENCE, 455 ITEM_GTP_PSC, 456 ITEM_GTP_PSC_QFI, 457 ITEM_GTP_PSC_PDU_T, 458 ITEM_PPPOES, 459 ITEM_PPPOED, 460 ITEM_PPPOE_SEID, 461 ITEM_PPPOE_PROTO_ID, 462 ITEM_HIGIG2, 463 ITEM_HIGIG2_CLASSIFICATION, 464 ITEM_HIGIG2_VID, 465 ITEM_TAG, 466 ITEM_TAG_DATA, 467 ITEM_TAG_INDEX, 468 ITEM_L2TPV3OIP, 469 ITEM_L2TPV3OIP_SESSION_ID, 470 ITEM_ESP, 471 ITEM_ESP_SPI, 472 ITEM_AH, 473 ITEM_AH_SPI, 474 ITEM_PFCP, 475 ITEM_PFCP_S_FIELD, 476 ITEM_PFCP_SEID, 477 ITEM_ECPRI, 478 ITEM_ECPRI_COMMON, 479 ITEM_ECPRI_COMMON_TYPE, 480 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 481 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 482 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 483 ITEM_ECPRI_MSG_IQ_DATA_PCID, 484 ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 485 ITEM_ECPRI_MSG_DLY_MSR_MSRID, 486 ITEM_GENEVE_OPT, 487 ITEM_GENEVE_OPT_CLASS, 488 ITEM_GENEVE_OPT_TYPE, 489 ITEM_GENEVE_OPT_LENGTH, 490 ITEM_GENEVE_OPT_DATA, 491 ITEM_INTEGRITY, 492 ITEM_INTEGRITY_LEVEL, 493 ITEM_INTEGRITY_VALUE, 494 ITEM_CONNTRACK, 495 ITEM_POL_PORT, 496 ITEM_POL_METER, 497 ITEM_POL_POLICY, 498 ITEM_PORT_REPRESENTOR, 499 ITEM_PORT_REPRESENTOR_PORT_ID, 500 ITEM_REPRESENTED_PORT, 501 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 502 ITEM_FLEX, 503 ITEM_FLEX_ITEM_HANDLE, 504 ITEM_FLEX_PATTERN_HANDLE, 505 ITEM_L2TPV2, 506 ITEM_L2TPV2_TYPE, 507 ITEM_L2TPV2_TYPE_DATA, 508 ITEM_L2TPV2_TYPE_DATA_L, 509 ITEM_L2TPV2_TYPE_DATA_S, 510 ITEM_L2TPV2_TYPE_DATA_O, 511 ITEM_L2TPV2_TYPE_DATA_L_S, 512 ITEM_L2TPV2_TYPE_CTRL, 513 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 514 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 515 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 516 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 517 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 518 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 519 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 520 ITEM_L2TPV2_MSG_DATA_S_NS, 521 ITEM_L2TPV2_MSG_DATA_S_NR, 522 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 523 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 524 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 525 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 526 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 527 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 528 ITEM_L2TPV2_MSG_DATA_L_S_NS, 529 ITEM_L2TPV2_MSG_DATA_L_S_NR, 530 ITEM_L2TPV2_MSG_CTRL_LENGTH, 531 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 532 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 533 ITEM_L2TPV2_MSG_CTRL_NS, 534 ITEM_L2TPV2_MSG_CTRL_NR, 535 ITEM_PPP, 536 ITEM_PPP_ADDR, 537 ITEM_PPP_CTRL, 538 ITEM_PPP_PROTO_ID, 539 ITEM_METER, 540 ITEM_METER_COLOR, 541 ITEM_METER_COLOR_NAME, 542 ITEM_QUOTA, 543 ITEM_QUOTA_STATE, 544 ITEM_QUOTA_STATE_NAME, 545 ITEM_AGGR_AFFINITY, 546 ITEM_AGGR_AFFINITY_VALUE, 547 ITEM_TX_QUEUE, 548 ITEM_TX_QUEUE_VALUE, 549 ITEM_IB_BTH, 550 ITEM_IB_BTH_OPCODE, 551 ITEM_IB_BTH_PKEY, 552 ITEM_IB_BTH_DST_QPN, 553 ITEM_IB_BTH_PSN, 554 ITEM_IPV6_PUSH_REMOVE_EXT, 555 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 556 ITEM_PTYPE, 557 ITEM_PTYPE_VALUE, 558 ITEM_NSH, 559 ITEM_COMPARE, 560 ITEM_COMPARE_OP, 561 ITEM_COMPARE_OP_VALUE, 562 ITEM_COMPARE_FIELD_A_TYPE, 563 ITEM_COMPARE_FIELD_A_TYPE_VALUE, 564 ITEM_COMPARE_FIELD_A_LEVEL, 565 ITEM_COMPARE_FIELD_A_LEVEL_VALUE, 566 ITEM_COMPARE_FIELD_A_TAG_INDEX, 567 ITEM_COMPARE_FIELD_A_TYPE_ID, 568 ITEM_COMPARE_FIELD_A_CLASS_ID, 569 ITEM_COMPARE_FIELD_A_OFFSET, 570 ITEM_COMPARE_FIELD_B_TYPE, 571 ITEM_COMPARE_FIELD_B_TYPE_VALUE, 572 ITEM_COMPARE_FIELD_B_LEVEL, 573 ITEM_COMPARE_FIELD_B_LEVEL_VALUE, 574 ITEM_COMPARE_FIELD_B_TAG_INDEX, 575 ITEM_COMPARE_FIELD_B_TYPE_ID, 576 ITEM_COMPARE_FIELD_B_CLASS_ID, 577 ITEM_COMPARE_FIELD_B_OFFSET, 578 ITEM_COMPARE_FIELD_B_VALUE, 579 ITEM_COMPARE_FIELD_B_POINTER, 580 ITEM_COMPARE_FIELD_WIDTH, 581 582 /* Validate/create actions. */ 583 ACTIONS, 584 ACTION_NEXT, 585 ACTION_END, 586 ACTION_VOID, 587 ACTION_PASSTHRU, 588 ACTION_SKIP_CMAN, 589 ACTION_JUMP, 590 ACTION_JUMP_GROUP, 591 ACTION_MARK, 592 ACTION_MARK_ID, 593 ACTION_FLAG, 594 ACTION_QUEUE, 595 ACTION_QUEUE_INDEX, 596 ACTION_DROP, 597 ACTION_COUNT, 598 ACTION_COUNT_ID, 599 ACTION_RSS, 600 ACTION_RSS_FUNC, 601 ACTION_RSS_LEVEL, 602 ACTION_RSS_FUNC_DEFAULT, 603 ACTION_RSS_FUNC_TOEPLITZ, 604 ACTION_RSS_FUNC_SIMPLE_XOR, 605 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, 606 ACTION_RSS_TYPES, 607 ACTION_RSS_TYPE, 608 ACTION_RSS_KEY, 609 ACTION_RSS_KEY_LEN, 610 ACTION_RSS_QUEUES, 611 ACTION_RSS_QUEUE, 612 ACTION_PF, 613 ACTION_VF, 614 ACTION_VF_ORIGINAL, 615 ACTION_VF_ID, 616 ACTION_PORT_ID, 617 ACTION_PORT_ID_ORIGINAL, 618 ACTION_PORT_ID_ID, 619 ACTION_METER, 620 ACTION_METER_COLOR, 621 ACTION_METER_COLOR_TYPE, 622 ACTION_METER_COLOR_GREEN, 623 ACTION_METER_COLOR_YELLOW, 624 ACTION_METER_COLOR_RED, 625 ACTION_METER_ID, 626 ACTION_METER_MARK, 627 ACTION_METER_PROFILE, 628 ACTION_METER_PROFILE_ID2PTR, 629 ACTION_METER_POLICY, 630 ACTION_METER_POLICY_ID2PTR, 631 ACTION_METER_COLOR_MODE, 632 ACTION_METER_STATE, 633 ACTION_OF_DEC_NW_TTL, 634 ACTION_OF_POP_VLAN, 635 ACTION_OF_PUSH_VLAN, 636 ACTION_OF_PUSH_VLAN_ETHERTYPE, 637 ACTION_OF_SET_VLAN_VID, 638 ACTION_OF_SET_VLAN_VID_VLAN_VID, 639 ACTION_OF_SET_VLAN_PCP, 640 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 641 ACTION_OF_POP_MPLS, 642 ACTION_OF_POP_MPLS_ETHERTYPE, 643 ACTION_OF_PUSH_MPLS, 644 ACTION_OF_PUSH_MPLS_ETHERTYPE, 645 ACTION_VXLAN_ENCAP, 646 ACTION_VXLAN_DECAP, 647 ACTION_NVGRE_ENCAP, 648 ACTION_NVGRE_DECAP, 649 ACTION_L2_ENCAP, 650 ACTION_L2_DECAP, 651 ACTION_MPLSOGRE_ENCAP, 652 ACTION_MPLSOGRE_DECAP, 653 ACTION_MPLSOUDP_ENCAP, 654 ACTION_MPLSOUDP_DECAP, 655 ACTION_SET_IPV4_SRC, 656 ACTION_SET_IPV4_SRC_IPV4_SRC, 657 ACTION_SET_IPV4_DST, 658 ACTION_SET_IPV4_DST_IPV4_DST, 659 ACTION_SET_IPV6_SRC, 660 ACTION_SET_IPV6_SRC_IPV6_SRC, 661 ACTION_SET_IPV6_DST, 662 ACTION_SET_IPV6_DST_IPV6_DST, 663 ACTION_SET_TP_SRC, 664 ACTION_SET_TP_SRC_TP_SRC, 665 ACTION_SET_TP_DST, 666 ACTION_SET_TP_DST_TP_DST, 667 ACTION_MAC_SWAP, 668 ACTION_DEC_TTL, 669 ACTION_SET_TTL, 670 ACTION_SET_TTL_TTL, 671 ACTION_SET_MAC_SRC, 672 ACTION_SET_MAC_SRC_MAC_SRC, 673 ACTION_SET_MAC_DST, 674 ACTION_SET_MAC_DST_MAC_DST, 675 ACTION_INC_TCP_SEQ, 676 ACTION_INC_TCP_SEQ_VALUE, 677 ACTION_DEC_TCP_SEQ, 678 ACTION_DEC_TCP_SEQ_VALUE, 679 ACTION_INC_TCP_ACK, 680 ACTION_INC_TCP_ACK_VALUE, 681 ACTION_DEC_TCP_ACK, 682 ACTION_DEC_TCP_ACK_VALUE, 683 ACTION_RAW_ENCAP, 684 ACTION_RAW_DECAP, 685 ACTION_RAW_ENCAP_SIZE, 686 ACTION_RAW_ENCAP_INDEX, 687 ACTION_RAW_ENCAP_INDEX_VALUE, 688 ACTION_RAW_DECAP_INDEX, 689 ACTION_RAW_DECAP_INDEX_VALUE, 690 ACTION_SET_TAG, 691 ACTION_SET_TAG_DATA, 692 ACTION_SET_TAG_INDEX, 693 ACTION_SET_TAG_MASK, 694 ACTION_SET_META, 695 ACTION_SET_META_DATA, 696 ACTION_SET_META_MASK, 697 ACTION_SET_IPV4_DSCP, 698 ACTION_SET_IPV4_DSCP_VALUE, 699 ACTION_SET_IPV6_DSCP, 700 ACTION_SET_IPV6_DSCP_VALUE, 701 ACTION_AGE, 702 ACTION_AGE_TIMEOUT, 703 ACTION_AGE_UPDATE, 704 ACTION_AGE_UPDATE_TIMEOUT, 705 ACTION_AGE_UPDATE_TOUCH, 706 ACTION_SAMPLE, 707 ACTION_SAMPLE_RATIO, 708 ACTION_SAMPLE_INDEX, 709 ACTION_SAMPLE_INDEX_VALUE, 710 ACTION_INDIRECT, 711 ACTION_INDIRECT_LIST, 712 ACTION_INDIRECT_LIST_HANDLE, 713 ACTION_INDIRECT_LIST_CONF, 714 INDIRECT_LIST_ACTION_ID2PTR_HANDLE, 715 INDIRECT_LIST_ACTION_ID2PTR_CONF, 716 ACTION_SHARED_INDIRECT, 717 INDIRECT_ACTION_PORT, 718 INDIRECT_ACTION_ID2PTR, 719 ACTION_MODIFY_FIELD, 720 ACTION_MODIFY_FIELD_OP, 721 ACTION_MODIFY_FIELD_OP_VALUE, 722 ACTION_MODIFY_FIELD_DST_TYPE, 723 ACTION_MODIFY_FIELD_DST_TYPE_VALUE, 724 ACTION_MODIFY_FIELD_DST_LEVEL, 725 ACTION_MODIFY_FIELD_DST_LEVEL_VALUE, 726 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 727 ACTION_MODIFY_FIELD_DST_TYPE_ID, 728 ACTION_MODIFY_FIELD_DST_CLASS_ID, 729 ACTION_MODIFY_FIELD_DST_OFFSET, 730 ACTION_MODIFY_FIELD_SRC_TYPE, 731 ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, 732 ACTION_MODIFY_FIELD_SRC_LEVEL, 733 ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE, 734 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 735 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 736 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 737 ACTION_MODIFY_FIELD_SRC_OFFSET, 738 ACTION_MODIFY_FIELD_SRC_VALUE, 739 ACTION_MODIFY_FIELD_SRC_POINTER, 740 ACTION_MODIFY_FIELD_WIDTH, 741 ACTION_CONNTRACK, 742 ACTION_CONNTRACK_UPDATE, 743 ACTION_CONNTRACK_UPDATE_DIR, 744 ACTION_CONNTRACK_UPDATE_CTX, 745 ACTION_POL_G, 746 ACTION_POL_Y, 747 ACTION_POL_R, 748 ACTION_PORT_REPRESENTOR, 749 ACTION_PORT_REPRESENTOR_PORT_ID, 750 ACTION_REPRESENTED_PORT, 751 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 752 ACTION_SEND_TO_KERNEL, 753 ACTION_QUOTA_CREATE, 754 ACTION_QUOTA_CREATE_LIMIT, 755 ACTION_QUOTA_CREATE_MODE, 756 ACTION_QUOTA_CREATE_MODE_NAME, 757 ACTION_QUOTA_QU, 758 ACTION_QUOTA_QU_LIMIT, 759 ACTION_QUOTA_QU_UPDATE_OP, 760 ACTION_QUOTA_QU_UPDATE_OP_NAME, 761 ACTION_IPV6_EXT_REMOVE, 762 ACTION_IPV6_EXT_REMOVE_INDEX, 763 ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, 764 ACTION_IPV6_EXT_PUSH, 765 ACTION_IPV6_EXT_PUSH_INDEX, 766 ACTION_IPV6_EXT_PUSH_INDEX_VALUE, 767 ACTION_NAT64, 768 ACTION_NAT64_MODE, 769 }; 770 771 /** Maximum size for pattern in struct rte_flow_item_raw. */ 772 #define ITEM_RAW_PATTERN_SIZE 512 773 774 /** Maximum size for GENEVE option data pattern in bytes. */ 775 #define ITEM_GENEVE_OPT_DATA_SIZE 124 776 777 /** Storage size for struct rte_flow_item_raw including pattern. */ 778 #define ITEM_RAW_SIZE \ 779 (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) 780 781 static const char *const compare_ops[] = { 782 "eq", "ne", "lt", "le", "gt", "ge", NULL 783 }; 784 785 /** Maximum size for external pattern in struct rte_flow_field_data. */ 786 #define FLOW_FIELD_PATTERN_SIZE 32 787 788 /** Storage size for struct rte_flow_action_modify_field including pattern. */ 789 #define ACTION_MODIFY_SIZE \ 790 (sizeof(struct rte_flow_action_modify_field) + \ 791 FLOW_FIELD_PATTERN_SIZE) 792 793 /** Maximum number of queue indices in struct rte_flow_action_rss. */ 794 #define ACTION_RSS_QUEUE_NUM 128 795 796 /** Storage for struct rte_flow_action_rss including external data. */ 797 struct action_rss_data { 798 struct rte_flow_action_rss conf; 799 uint8_t key[RSS_HASH_KEY_LENGTH]; 800 uint16_t queue[ACTION_RSS_QUEUE_NUM]; 801 }; 802 803 /** Maximum data size in struct rte_flow_action_raw_encap. */ 804 #define ACTION_RAW_ENCAP_MAX_DATA 512 805 #define RAW_ENCAP_CONFS_MAX_NUM 8 806 807 /** Storage for struct rte_flow_action_raw_encap. */ 808 struct raw_encap_conf { 809 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 810 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 811 size_t size; 812 }; 813 814 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 815 816 /** Storage for struct rte_flow_action_raw_encap including external data. */ 817 struct action_raw_encap_data { 818 struct rte_flow_action_raw_encap conf; 819 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 820 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 821 uint16_t idx; 822 }; 823 824 /** Storage for struct rte_flow_action_raw_decap. */ 825 struct raw_decap_conf { 826 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 827 size_t size; 828 }; 829 830 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 831 832 /** Storage for struct rte_flow_action_raw_decap including external data. */ 833 struct action_raw_decap_data { 834 struct rte_flow_action_raw_decap conf; 835 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 836 uint16_t idx; 837 }; 838 839 /** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ 840 #define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 841 #define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 842 843 /** Storage for struct rte_flow_action_ipv6_ext_push. */ 844 struct ipv6_ext_push_conf { 845 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 846 size_t size; 847 uint8_t type; 848 }; 849 850 struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 851 852 /** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ 853 struct action_ipv6_ext_push_data { 854 struct rte_flow_action_ipv6_ext_push conf; 855 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 856 uint8_t type; 857 uint16_t idx; 858 }; 859 860 /** Storage for struct rte_flow_action_ipv6_ext_remove. */ 861 struct ipv6_ext_remove_conf { 862 struct rte_flow_action_ipv6_ext_remove conf; 863 uint8_t type; 864 }; 865 866 struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 867 868 /** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ 869 struct action_ipv6_ext_remove_data { 870 struct rte_flow_action_ipv6_ext_remove conf; 871 uint8_t type; 872 uint16_t idx; 873 }; 874 875 struct vxlan_encap_conf vxlan_encap_conf = { 876 .select_ipv4 = 1, 877 .select_vlan = 0, 878 .select_tos_ttl = 0, 879 .vni = "\x00\x00\x00", 880 .udp_src = 0, 881 .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), 882 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 883 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 884 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 885 "\x00\x00\x00\x00\x00\x00\x00\x01", 886 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 887 "\x00\x00\x00\x00\x00\x00\x11\x11", 888 .vlan_tci = 0, 889 .ip_tos = 0, 890 .ip_ttl = 255, 891 .eth_src = "\x00\x00\x00\x00\x00\x00", 892 .eth_dst = "\xff\xff\xff\xff\xff\xff", 893 }; 894 895 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */ 896 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6 897 898 /** Storage for struct rte_flow_action_vxlan_encap including external data. */ 899 struct action_vxlan_encap_data { 900 struct rte_flow_action_vxlan_encap conf; 901 struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; 902 struct rte_flow_item_eth item_eth; 903 struct rte_flow_item_vlan item_vlan; 904 union { 905 struct rte_flow_item_ipv4 item_ipv4; 906 struct rte_flow_item_ipv6 item_ipv6; 907 }; 908 struct rte_flow_item_udp item_udp; 909 struct rte_flow_item_vxlan item_vxlan; 910 }; 911 912 struct nvgre_encap_conf nvgre_encap_conf = { 913 .select_ipv4 = 1, 914 .select_vlan = 0, 915 .tni = "\x00\x00\x00", 916 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 917 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 918 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 919 "\x00\x00\x00\x00\x00\x00\x00\x01", 920 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 921 "\x00\x00\x00\x00\x00\x00\x11\x11", 922 .vlan_tci = 0, 923 .eth_src = "\x00\x00\x00\x00\x00\x00", 924 .eth_dst = "\xff\xff\xff\xff\xff\xff", 925 }; 926 927 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */ 928 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 929 930 /** Storage for struct rte_flow_action_nvgre_encap including external data. */ 931 struct action_nvgre_encap_data { 932 struct rte_flow_action_nvgre_encap conf; 933 struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; 934 struct rte_flow_item_eth item_eth; 935 struct rte_flow_item_vlan item_vlan; 936 union { 937 struct rte_flow_item_ipv4 item_ipv4; 938 struct rte_flow_item_ipv6 item_ipv6; 939 }; 940 struct rte_flow_item_nvgre item_nvgre; 941 }; 942 943 struct l2_encap_conf l2_encap_conf; 944 945 struct l2_decap_conf l2_decap_conf; 946 947 struct mplsogre_encap_conf mplsogre_encap_conf; 948 949 struct mplsogre_decap_conf mplsogre_decap_conf; 950 951 struct mplsoudp_encap_conf mplsoudp_encap_conf; 952 953 struct mplsoudp_decap_conf mplsoudp_decap_conf; 954 955 struct rte_flow_action_conntrack conntrack_context; 956 957 #define ACTION_SAMPLE_ACTIONS_NUM 10 958 #define RAW_SAMPLE_CONFS_MAX_NUM 8 959 /** Storage for struct rte_flow_action_sample including external data. */ 960 struct action_sample_data { 961 struct rte_flow_action_sample conf; 962 uint32_t idx; 963 }; 964 /** Storage for struct rte_flow_action_sample. */ 965 struct raw_sample_conf { 966 struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; 967 }; 968 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; 969 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; 970 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; 971 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; 972 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; 973 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 974 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 975 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 976 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; 977 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; 978 struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; 979 struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; 980 981 static const char *const modify_field_ops[] = { 982 "set", "add", "sub", NULL 983 }; 984 985 static const char *const flow_field_ids[] = { 986 "start", "mac_dst", "mac_src", 987 "vlan_type", "vlan_id", "mac_type", 988 "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", 989 "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", 990 "tcp_port_src", "tcp_port_dst", 991 "tcp_seq_num", "tcp_ack_num", "tcp_flags", 992 "udp_port_src", "udp_port_dst", 993 "vxlan_vni", "geneve_vni", "gtp_teid", 994 "tag", "mark", "meta", "pointer", "value", 995 "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", 996 "ipv6_proto", 997 "flex_item", 998 "hash_result", 999 "geneve_opt_type", "geneve_opt_class", "geneve_opt_data", "mpls", 1000 "tcp_data_off", "ipv4_ihl", "ipv4_total_len", "ipv6_payload_len", 1001 "random", 1002 NULL 1003 }; 1004 1005 static const char *const meter_colors[] = { 1006 "green", "yellow", "red", "all", NULL 1007 }; 1008 1009 static const char *const table_insertion_types[] = { 1010 "pattern", "index", NULL 1011 }; 1012 1013 static const char *const table_hash_funcs[] = { 1014 "default", "linear", "crc32", "crc16", NULL 1015 }; 1016 1017 #define RAW_IPSEC_CONFS_MAX_NUM 8 1018 1019 /** Maximum number of subsequent tokens and arguments on the stack. */ 1020 #define CTX_STACK_SIZE 16 1021 1022 /** Parser context. */ 1023 struct context { 1024 /** Stack of subsequent token lists to process. */ 1025 const enum index *next[CTX_STACK_SIZE]; 1026 /** Arguments for stacked tokens. */ 1027 const void *args[CTX_STACK_SIZE]; 1028 enum index curr; /**< Current token index. */ 1029 enum index prev; /**< Index of the last token seen. */ 1030 int next_num; /**< Number of entries in next[]. */ 1031 int args_num; /**< Number of entries in args[]. */ 1032 uint32_t eol:1; /**< EOL has been detected. */ 1033 uint32_t last:1; /**< No more arguments. */ 1034 portid_t port; /**< Current port ID (for completions). */ 1035 uint32_t objdata; /**< Object-specific data. */ 1036 void *object; /**< Address of current object for relative offsets. */ 1037 void *objmask; /**< Object a full mask must be written to. */ 1038 }; 1039 1040 /** Token argument. */ 1041 struct arg { 1042 uint32_t hton:1; /**< Use network byte ordering. */ 1043 uint32_t sign:1; /**< Value is signed. */ 1044 uint32_t bounded:1; /**< Value is bounded. */ 1045 uintmax_t min; /**< Minimum value if bounded. */ 1046 uintmax_t max; /**< Maximum value if bounded. */ 1047 uint32_t offset; /**< Relative offset from ctx->object. */ 1048 uint32_t size; /**< Field size. */ 1049 const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ 1050 }; 1051 1052 /** Parser token definition. */ 1053 struct token { 1054 /** Type displayed during completion (defaults to "TOKEN"). */ 1055 const char *type; 1056 /** Help displayed during completion (defaults to token name). */ 1057 const char *help; 1058 /** Private data used by parser functions. */ 1059 const void *priv; 1060 /** 1061 * Lists of subsequent tokens to push on the stack. Each call to the 1062 * parser consumes the last entry of that stack. 1063 */ 1064 const enum index *const *next; 1065 /** Arguments stack for subsequent tokens that need them. */ 1066 const struct arg *const *args; 1067 /** 1068 * Token-processing callback, returns -1 in case of error, the 1069 * length of the matched string otherwise. If NULL, attempts to 1070 * match the token name. 1071 * 1072 * If buf is not NULL, the result should be stored in it according 1073 * to context. An error is returned if not large enough. 1074 */ 1075 int (*call)(struct context *ctx, const struct token *token, 1076 const char *str, unsigned int len, 1077 void *buf, unsigned int size); 1078 /** 1079 * Callback that provides possible values for this token, used for 1080 * completion. Returns -1 in case of error, the number of possible 1081 * values otherwise. If NULL, the token name is used. 1082 * 1083 * If buf is not NULL, entry index ent is written to buf and the 1084 * full length of the entry is returned (same behavior as 1085 * snprintf()). 1086 */ 1087 int (*comp)(struct context *ctx, const struct token *token, 1088 unsigned int ent, char *buf, unsigned int size); 1089 /** Mandatory token name, no default value. */ 1090 const char *name; 1091 }; 1092 1093 /** Static initializer for the next field. */ 1094 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } 1095 1096 /** Static initializer for a NEXT() entry. */ 1097 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } 1098 1099 /** Static initializer for the args field. */ 1100 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } 1101 1102 /** Static initializer for ARGS() to target a field. */ 1103 #define ARGS_ENTRY(s, f) \ 1104 (&(const struct arg){ \ 1105 .offset = offsetof(s, f), \ 1106 .size = sizeof(((s *)0)->f), \ 1107 }) 1108 1109 /** Static initializer for ARGS() to target a bit-field. */ 1110 #define ARGS_ENTRY_BF(s, f, b) \ 1111 (&(const struct arg){ \ 1112 .size = sizeof(s), \ 1113 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ 1114 }) 1115 1116 /** Static initializer for ARGS() to target a field with limits. */ 1117 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \ 1118 (&(const struct arg){ \ 1119 .bounded = 1, \ 1120 .min = (i), \ 1121 .max = (a), \ 1122 .offset = offsetof(s, f), \ 1123 .size = sizeof(((s *)0)->f), \ 1124 }) 1125 1126 /** Static initializer for ARGS() to target an arbitrary bit-mask. */ 1127 #define ARGS_ENTRY_MASK(s, f, m) \ 1128 (&(const struct arg){ \ 1129 .offset = offsetof(s, f), \ 1130 .size = sizeof(((s *)0)->f), \ 1131 .mask = (const void *)(m), \ 1132 }) 1133 1134 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ 1135 #define ARGS_ENTRY_MASK_HTON(s, f, m) \ 1136 (&(const struct arg){ \ 1137 .hton = 1, \ 1138 .offset = offsetof(s, f), \ 1139 .size = sizeof(((s *)0)->f), \ 1140 .mask = (const void *)(m), \ 1141 }) 1142 1143 /** Static initializer for ARGS() to target a pointer. */ 1144 #define ARGS_ENTRY_PTR(s, f) \ 1145 (&(const struct arg){ \ 1146 .size = sizeof(*((s *)0)->f), \ 1147 }) 1148 1149 /** Static initializer for ARGS() with arbitrary offset and size. */ 1150 #define ARGS_ENTRY_ARB(o, s) \ 1151 (&(const struct arg){ \ 1152 .offset = (o), \ 1153 .size = (s), \ 1154 }) 1155 1156 /** Same as ARGS_ENTRY_ARB() with bounded values. */ 1157 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ 1158 (&(const struct arg){ \ 1159 .bounded = 1, \ 1160 .min = (i), \ 1161 .max = (a), \ 1162 .offset = (o), \ 1163 .size = (s), \ 1164 }) 1165 1166 /** Same as ARGS_ENTRY() using network byte ordering. */ 1167 #define ARGS_ENTRY_HTON(s, f) \ 1168 (&(const struct arg){ \ 1169 .hton = 1, \ 1170 .offset = offsetof(s, f), \ 1171 .size = sizeof(((s *)0)->f), \ 1172 }) 1173 1174 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ 1175 #define ARG_ENTRY_HTON(s) \ 1176 (&(const struct arg){ \ 1177 .hton = 1, \ 1178 .offset = 0, \ 1179 .size = sizeof(s), \ 1180 }) 1181 1182 /** Parser output buffer layout expected by cmd_flow_parsed(). */ 1183 struct buffer { 1184 enum index command; /**< Flow command. */ 1185 portid_t port; /**< Affected port ID. */ 1186 queueid_t queue; /** Async queue ID. */ 1187 bool postpone; /** Postpone async operation */ 1188 union { 1189 struct { 1190 struct rte_flow_port_attr port_attr; 1191 uint32_t nb_queue; 1192 struct rte_flow_queue_attr queue_attr; 1193 } configure; /**< Configuration arguments. */ 1194 struct { 1195 uint32_t *template_id; 1196 uint32_t template_id_n; 1197 } templ_destroy; /**< Template destroy arguments. */ 1198 struct { 1199 uint32_t id; 1200 struct rte_flow_template_table_attr attr; 1201 uint32_t *pat_templ_id; 1202 uint32_t pat_templ_id_n; 1203 uint32_t *act_templ_id; 1204 uint32_t act_templ_id_n; 1205 } table; /**< Table arguments. */ 1206 struct { 1207 uint32_t *table_id; 1208 uint32_t table_id_n; 1209 } table_destroy; /**< Template destroy arguments. */ 1210 struct { 1211 uint32_t *action_id; 1212 uint32_t action_id_n; 1213 } ia_destroy; /**< Indirect action destroy arguments. */ 1214 struct { 1215 uint32_t action_id; 1216 enum rte_flow_query_update_mode qu_mode; 1217 } ia; /* Indirect action query arguments */ 1218 struct { 1219 uint32_t table_id; 1220 uint32_t pat_templ_id; 1221 uint32_t rule_id; 1222 uint32_t act_templ_id; 1223 struct rte_flow_attr attr; 1224 struct tunnel_ops tunnel_ops; 1225 uintptr_t user_id; 1226 struct rte_flow_item *pattern; 1227 struct rte_flow_action *actions; 1228 struct rte_flow_action *masks; 1229 uint32_t pattern_n; 1230 uint32_t actions_n; 1231 uint8_t *data; 1232 enum rte_flow_encap_hash_field field; 1233 uint8_t encap_hash; 1234 } vc; /**< Validate/create arguments. */ 1235 struct { 1236 uint64_t *rule; 1237 uint64_t rule_n; 1238 bool is_user_id; 1239 } destroy; /**< Destroy arguments. */ 1240 struct { 1241 char file[128]; 1242 bool mode; 1243 uint64_t rule; 1244 bool is_user_id; 1245 } dump; /**< Dump arguments. */ 1246 struct { 1247 uint64_t rule; 1248 struct rte_flow_action action; 1249 bool is_user_id; 1250 } query; /**< Query arguments. */ 1251 struct { 1252 uint32_t *group; 1253 uint32_t group_n; 1254 } list; /**< List arguments. */ 1255 struct { 1256 int set; 1257 } isolate; /**< Isolated mode arguments. */ 1258 struct { 1259 int destroy; 1260 } aged; /**< Aged arguments. */ 1261 struct { 1262 uint32_t policy_id; 1263 } policy;/**< Policy arguments. */ 1264 struct { 1265 uint16_t token; 1266 uintptr_t uintptr; 1267 char filename[128]; 1268 } flex; /**< Flex arguments*/ 1269 } args; /**< Command arguments. */ 1270 }; 1271 1272 /** Private data for pattern items. */ 1273 struct parse_item_priv { 1274 enum rte_flow_item_type type; /**< Item type. */ 1275 uint32_t size; /**< Size of item specification structure. */ 1276 }; 1277 1278 #define PRIV_ITEM(t, s) \ 1279 (&(const struct parse_item_priv){ \ 1280 .type = RTE_FLOW_ITEM_TYPE_ ## t, \ 1281 .size = s, \ 1282 }) 1283 1284 /** Private data for actions. */ 1285 struct parse_action_priv { 1286 enum rte_flow_action_type type; /**< Action type. */ 1287 uint32_t size; /**< Size of action configuration structure. */ 1288 }; 1289 1290 #define PRIV_ACTION(t, s) \ 1291 (&(const struct parse_action_priv){ \ 1292 .type = RTE_FLOW_ACTION_TYPE_ ## t, \ 1293 .size = s, \ 1294 }) 1295 1296 static const enum index next_flex_item[] = { 1297 FLEX_ITEM_INIT, 1298 FLEX_ITEM_CREATE, 1299 FLEX_ITEM_DESTROY, 1300 ZERO, 1301 }; 1302 1303 static const enum index next_config_attr[] = { 1304 CONFIG_QUEUES_NUMBER, 1305 CONFIG_QUEUES_SIZE, 1306 CONFIG_COUNTERS_NUMBER, 1307 CONFIG_AGING_OBJECTS_NUMBER, 1308 CONFIG_METERS_NUMBER, 1309 CONFIG_CONN_TRACK_NUMBER, 1310 CONFIG_QUOTAS_NUMBER, 1311 CONFIG_FLAGS, 1312 CONFIG_HOST_PORT, 1313 END, 1314 ZERO, 1315 }; 1316 1317 static const enum index next_pt_subcmd[] = { 1318 PATTERN_TEMPLATE_CREATE, 1319 PATTERN_TEMPLATE_DESTROY, 1320 ZERO, 1321 }; 1322 1323 static const enum index next_pt_attr[] = { 1324 PATTERN_TEMPLATE_CREATE_ID, 1325 PATTERN_TEMPLATE_RELAXED_MATCHING, 1326 PATTERN_TEMPLATE_INGRESS, 1327 PATTERN_TEMPLATE_EGRESS, 1328 PATTERN_TEMPLATE_TRANSFER, 1329 PATTERN_TEMPLATE_SPEC, 1330 ZERO, 1331 }; 1332 1333 static const enum index next_pt_destroy_attr[] = { 1334 PATTERN_TEMPLATE_DESTROY_ID, 1335 END, 1336 ZERO, 1337 }; 1338 1339 static const enum index next_at_subcmd[] = { 1340 ACTIONS_TEMPLATE_CREATE, 1341 ACTIONS_TEMPLATE_DESTROY, 1342 ZERO, 1343 }; 1344 1345 static const enum index next_at_attr[] = { 1346 ACTIONS_TEMPLATE_CREATE_ID, 1347 ACTIONS_TEMPLATE_INGRESS, 1348 ACTIONS_TEMPLATE_EGRESS, 1349 ACTIONS_TEMPLATE_TRANSFER, 1350 ACTIONS_TEMPLATE_SPEC, 1351 ZERO, 1352 }; 1353 1354 static const enum index next_at_destroy_attr[] = { 1355 ACTIONS_TEMPLATE_DESTROY_ID, 1356 END, 1357 ZERO, 1358 }; 1359 1360 static const enum index next_group_attr[] = { 1361 GROUP_INGRESS, 1362 GROUP_EGRESS, 1363 GROUP_TRANSFER, 1364 GROUP_SET_MISS_ACTIONS, 1365 ZERO, 1366 }; 1367 1368 static const enum index next_table_subcmd[] = { 1369 TABLE_CREATE, 1370 TABLE_DESTROY, 1371 TABLE_RESIZE, 1372 TABLE_RESIZE_COMPLETE, 1373 ZERO, 1374 }; 1375 1376 static const enum index next_table_attr[] = { 1377 TABLE_CREATE_ID, 1378 TABLE_GROUP, 1379 TABLE_INSERTION_TYPE, 1380 TABLE_HASH_FUNC, 1381 TABLE_PRIORITY, 1382 TABLE_INGRESS, 1383 TABLE_EGRESS, 1384 TABLE_TRANSFER, 1385 TABLE_TRANSFER_WIRE_ORIG, 1386 TABLE_TRANSFER_VPORT_ORIG, 1387 TABLE_RESIZABLE, 1388 TABLE_RULES_NUMBER, 1389 TABLE_PATTERN_TEMPLATE, 1390 TABLE_ACTIONS_TEMPLATE, 1391 END, 1392 ZERO, 1393 }; 1394 1395 static const enum index next_table_destroy_attr[] = { 1396 TABLE_DESTROY_ID, 1397 END, 1398 ZERO, 1399 }; 1400 1401 static const enum index next_queue_subcmd[] = { 1402 QUEUE_CREATE, 1403 QUEUE_DESTROY, 1404 QUEUE_FLOW_UPDATE_RESIZED, 1405 QUEUE_UPDATE, 1406 QUEUE_AGED, 1407 QUEUE_INDIRECT_ACTION, 1408 ZERO, 1409 }; 1410 1411 static const enum index next_queue_destroy_attr[] = { 1412 QUEUE_DESTROY_ID, 1413 END, 1414 ZERO, 1415 }; 1416 1417 static const enum index next_qia_subcmd[] = { 1418 QUEUE_INDIRECT_ACTION_CREATE, 1419 QUEUE_INDIRECT_ACTION_UPDATE, 1420 QUEUE_INDIRECT_ACTION_DESTROY, 1421 QUEUE_INDIRECT_ACTION_QUERY, 1422 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 1423 ZERO, 1424 }; 1425 1426 static const enum index next_qia_create_attr[] = { 1427 QUEUE_INDIRECT_ACTION_CREATE_ID, 1428 QUEUE_INDIRECT_ACTION_INGRESS, 1429 QUEUE_INDIRECT_ACTION_EGRESS, 1430 QUEUE_INDIRECT_ACTION_TRANSFER, 1431 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 1432 QUEUE_INDIRECT_ACTION_SPEC, 1433 QUEUE_INDIRECT_ACTION_LIST, 1434 ZERO, 1435 }; 1436 1437 static const enum index next_qia_update_attr[] = { 1438 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1439 QUEUE_INDIRECT_ACTION_SPEC, 1440 ZERO, 1441 }; 1442 1443 static const enum index next_qia_destroy_attr[] = { 1444 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 1445 QUEUE_INDIRECT_ACTION_DESTROY_ID, 1446 END, 1447 ZERO, 1448 }; 1449 1450 static const enum index next_qia_query_attr[] = { 1451 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 1452 END, 1453 ZERO, 1454 }; 1455 1456 static const enum index next_ia_create_attr[] = { 1457 INDIRECT_ACTION_CREATE_ID, 1458 INDIRECT_ACTION_INGRESS, 1459 INDIRECT_ACTION_EGRESS, 1460 INDIRECT_ACTION_TRANSFER, 1461 INDIRECT_ACTION_SPEC, 1462 INDIRECT_ACTION_LIST, 1463 INDIRECT_ACTION_FLOW_CONF, 1464 ZERO, 1465 }; 1466 1467 static const enum index next_ia[] = { 1468 INDIRECT_ACTION_ID2PTR, 1469 ACTION_NEXT, 1470 ZERO 1471 }; 1472 1473 static const enum index next_ial[] = { 1474 ACTION_INDIRECT_LIST_HANDLE, 1475 ACTION_INDIRECT_LIST_CONF, 1476 ACTION_NEXT, 1477 ZERO 1478 }; 1479 1480 static const enum index next_qia_qu_attr[] = { 1481 QUEUE_INDIRECT_ACTION_QU_MODE, 1482 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1483 INDIRECT_ACTION_SPEC, 1484 ZERO 1485 }; 1486 1487 static const enum index next_ia_qu_attr[] = { 1488 INDIRECT_ACTION_QU_MODE, 1489 INDIRECT_ACTION_SPEC, 1490 ZERO 1491 }; 1492 1493 static const enum index next_dump_subcmd[] = { 1494 DUMP_ALL, 1495 DUMP_ONE, 1496 DUMP_IS_USER_ID, 1497 ZERO, 1498 }; 1499 1500 static const enum index next_ia_subcmd[] = { 1501 INDIRECT_ACTION_CREATE, 1502 INDIRECT_ACTION_UPDATE, 1503 INDIRECT_ACTION_DESTROY, 1504 INDIRECT_ACTION_QUERY, 1505 INDIRECT_ACTION_QUERY_UPDATE, 1506 ZERO, 1507 }; 1508 1509 static const enum index next_vc_attr[] = { 1510 VC_GROUP, 1511 VC_PRIORITY, 1512 VC_INGRESS, 1513 VC_EGRESS, 1514 VC_TRANSFER, 1515 VC_TUNNEL_SET, 1516 VC_TUNNEL_MATCH, 1517 VC_USER_ID, 1518 ITEM_PATTERN, 1519 ZERO, 1520 }; 1521 1522 static const enum index next_destroy_attr[] = { 1523 DESTROY_RULE, 1524 DESTROY_IS_USER_ID, 1525 END, 1526 ZERO, 1527 }; 1528 1529 static const enum index next_dump_attr[] = { 1530 COMMON_FILE_PATH, 1531 END, 1532 ZERO, 1533 }; 1534 1535 static const enum index next_query_attr[] = { 1536 QUERY_IS_USER_ID, 1537 END, 1538 ZERO, 1539 }; 1540 1541 static const enum index next_list_attr[] = { 1542 LIST_GROUP, 1543 END, 1544 ZERO, 1545 }; 1546 1547 static const enum index next_aged_attr[] = { 1548 AGED_DESTROY, 1549 END, 1550 ZERO, 1551 }; 1552 1553 static const enum index next_ia_destroy_attr[] = { 1554 INDIRECT_ACTION_DESTROY_ID, 1555 END, 1556 ZERO, 1557 }; 1558 1559 static const enum index next_async_insert_subcmd[] = { 1560 QUEUE_PATTERN_TEMPLATE, 1561 QUEUE_RULE_ID, 1562 ZERO, 1563 }; 1564 1565 static const enum index item_param[] = { 1566 ITEM_PARAM_IS, 1567 ITEM_PARAM_SPEC, 1568 ITEM_PARAM_LAST, 1569 ITEM_PARAM_MASK, 1570 ITEM_PARAM_PREFIX, 1571 ZERO, 1572 }; 1573 1574 static const enum index next_item[] = { 1575 ITEM_END, 1576 ITEM_VOID, 1577 ITEM_INVERT, 1578 ITEM_ANY, 1579 ITEM_PORT_ID, 1580 ITEM_MARK, 1581 ITEM_RAW, 1582 ITEM_ETH, 1583 ITEM_VLAN, 1584 ITEM_IPV4, 1585 ITEM_IPV6, 1586 ITEM_ICMP, 1587 ITEM_UDP, 1588 ITEM_TCP, 1589 ITEM_SCTP, 1590 ITEM_VXLAN, 1591 ITEM_E_TAG, 1592 ITEM_NVGRE, 1593 ITEM_MPLS, 1594 ITEM_GRE, 1595 ITEM_FUZZY, 1596 ITEM_GTP, 1597 ITEM_GTPC, 1598 ITEM_GTPU, 1599 ITEM_GENEVE, 1600 ITEM_VXLAN_GPE, 1601 ITEM_ARP_ETH_IPV4, 1602 ITEM_IPV6_EXT, 1603 ITEM_IPV6_FRAG_EXT, 1604 ITEM_IPV6_ROUTING_EXT, 1605 ITEM_ICMP6, 1606 ITEM_ICMP6_ECHO_REQUEST, 1607 ITEM_ICMP6_ECHO_REPLY, 1608 ITEM_ICMP6_ND_NS, 1609 ITEM_ICMP6_ND_NA, 1610 ITEM_ICMP6_ND_OPT, 1611 ITEM_ICMP6_ND_OPT_SLA_ETH, 1612 ITEM_ICMP6_ND_OPT_TLA_ETH, 1613 ITEM_META, 1614 ITEM_RANDOM, 1615 ITEM_GRE_KEY, 1616 ITEM_GRE_OPTION, 1617 ITEM_GTP_PSC, 1618 ITEM_PPPOES, 1619 ITEM_PPPOED, 1620 ITEM_PPPOE_PROTO_ID, 1621 ITEM_HIGIG2, 1622 ITEM_TAG, 1623 ITEM_L2TPV3OIP, 1624 ITEM_ESP, 1625 ITEM_AH, 1626 ITEM_PFCP, 1627 ITEM_ECPRI, 1628 ITEM_GENEVE_OPT, 1629 ITEM_INTEGRITY, 1630 ITEM_CONNTRACK, 1631 ITEM_PORT_REPRESENTOR, 1632 ITEM_REPRESENTED_PORT, 1633 ITEM_FLEX, 1634 ITEM_L2TPV2, 1635 ITEM_PPP, 1636 ITEM_METER, 1637 ITEM_QUOTA, 1638 ITEM_AGGR_AFFINITY, 1639 ITEM_TX_QUEUE, 1640 ITEM_IB_BTH, 1641 ITEM_PTYPE, 1642 ITEM_NSH, 1643 ITEM_COMPARE, 1644 END_SET, 1645 ZERO, 1646 }; 1647 1648 static const enum index item_fuzzy[] = { 1649 ITEM_FUZZY_THRESH, 1650 ITEM_NEXT, 1651 ZERO, 1652 }; 1653 1654 static const enum index item_any[] = { 1655 ITEM_ANY_NUM, 1656 ITEM_NEXT, 1657 ZERO, 1658 }; 1659 1660 static const enum index item_port_id[] = { 1661 ITEM_PORT_ID_ID, 1662 ITEM_NEXT, 1663 ZERO, 1664 }; 1665 1666 static const enum index item_mark[] = { 1667 ITEM_MARK_ID, 1668 ITEM_NEXT, 1669 ZERO, 1670 }; 1671 1672 static const enum index item_raw[] = { 1673 ITEM_RAW_RELATIVE, 1674 ITEM_RAW_SEARCH, 1675 ITEM_RAW_OFFSET, 1676 ITEM_RAW_LIMIT, 1677 ITEM_RAW_PATTERN, 1678 ITEM_RAW_PATTERN_HEX, 1679 ITEM_NEXT, 1680 ZERO, 1681 }; 1682 1683 static const enum index item_eth[] = { 1684 ITEM_ETH_DST, 1685 ITEM_ETH_SRC, 1686 ITEM_ETH_TYPE, 1687 ITEM_ETH_HAS_VLAN, 1688 ITEM_NEXT, 1689 ZERO, 1690 }; 1691 1692 static const enum index item_vlan[] = { 1693 ITEM_VLAN_TCI, 1694 ITEM_VLAN_PCP, 1695 ITEM_VLAN_DEI, 1696 ITEM_VLAN_VID, 1697 ITEM_VLAN_INNER_TYPE, 1698 ITEM_VLAN_HAS_MORE_VLAN, 1699 ITEM_NEXT, 1700 ZERO, 1701 }; 1702 1703 static const enum index item_ipv4[] = { 1704 ITEM_IPV4_VER_IHL, 1705 ITEM_IPV4_TOS, 1706 ITEM_IPV4_LENGTH, 1707 ITEM_IPV4_ID, 1708 ITEM_IPV4_FRAGMENT_OFFSET, 1709 ITEM_IPV4_TTL, 1710 ITEM_IPV4_PROTO, 1711 ITEM_IPV4_SRC, 1712 ITEM_IPV4_DST, 1713 ITEM_NEXT, 1714 ZERO, 1715 }; 1716 1717 static const enum index item_ipv6[] = { 1718 ITEM_IPV6_TC, 1719 ITEM_IPV6_FLOW, 1720 ITEM_IPV6_LEN, 1721 ITEM_IPV6_PROTO, 1722 ITEM_IPV6_HOP, 1723 ITEM_IPV6_SRC, 1724 ITEM_IPV6_DST, 1725 ITEM_IPV6_HAS_FRAG_EXT, 1726 ITEM_IPV6_ROUTING_EXT, 1727 ITEM_NEXT, 1728 ZERO, 1729 }; 1730 1731 static const enum index item_ipv6_routing_ext[] = { 1732 ITEM_IPV6_ROUTING_EXT_TYPE, 1733 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 1734 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 1735 ITEM_NEXT, 1736 ZERO, 1737 }; 1738 1739 static const enum index item_icmp[] = { 1740 ITEM_ICMP_TYPE, 1741 ITEM_ICMP_CODE, 1742 ITEM_ICMP_IDENT, 1743 ITEM_ICMP_SEQ, 1744 ITEM_NEXT, 1745 ZERO, 1746 }; 1747 1748 static const enum index item_udp[] = { 1749 ITEM_UDP_SRC, 1750 ITEM_UDP_DST, 1751 ITEM_NEXT, 1752 ZERO, 1753 }; 1754 1755 static const enum index item_tcp[] = { 1756 ITEM_TCP_SRC, 1757 ITEM_TCP_DST, 1758 ITEM_TCP_FLAGS, 1759 ITEM_NEXT, 1760 ZERO, 1761 }; 1762 1763 static const enum index item_sctp[] = { 1764 ITEM_SCTP_SRC, 1765 ITEM_SCTP_DST, 1766 ITEM_SCTP_TAG, 1767 ITEM_SCTP_CKSUM, 1768 ITEM_NEXT, 1769 ZERO, 1770 }; 1771 1772 static const enum index item_vxlan[] = { 1773 ITEM_VXLAN_VNI, 1774 ITEM_VXLAN_LAST_RSVD, 1775 ITEM_NEXT, 1776 ZERO, 1777 }; 1778 1779 static const enum index item_e_tag[] = { 1780 ITEM_E_TAG_GRP_ECID_B, 1781 ITEM_NEXT, 1782 ZERO, 1783 }; 1784 1785 static const enum index item_nvgre[] = { 1786 ITEM_NVGRE_TNI, 1787 ITEM_NEXT, 1788 ZERO, 1789 }; 1790 1791 static const enum index item_mpls[] = { 1792 ITEM_MPLS_LABEL, 1793 ITEM_MPLS_TC, 1794 ITEM_MPLS_S, 1795 ITEM_MPLS_TTL, 1796 ITEM_NEXT, 1797 ZERO, 1798 }; 1799 1800 static const enum index item_gre[] = { 1801 ITEM_GRE_PROTO, 1802 ITEM_GRE_C_RSVD0_VER, 1803 ITEM_GRE_C_BIT, 1804 ITEM_GRE_K_BIT, 1805 ITEM_GRE_S_BIT, 1806 ITEM_NEXT, 1807 ZERO, 1808 }; 1809 1810 static const enum index item_gre_key[] = { 1811 ITEM_GRE_KEY_VALUE, 1812 ITEM_NEXT, 1813 ZERO, 1814 }; 1815 1816 static const enum index item_gre_option[] = { 1817 ITEM_GRE_OPTION_CHECKSUM, 1818 ITEM_GRE_OPTION_KEY, 1819 ITEM_GRE_OPTION_SEQUENCE, 1820 ITEM_NEXT, 1821 ZERO, 1822 }; 1823 1824 static const enum index item_gtp[] = { 1825 ITEM_GTP_FLAGS, 1826 ITEM_GTP_MSG_TYPE, 1827 ITEM_GTP_TEID, 1828 ITEM_NEXT, 1829 ZERO, 1830 }; 1831 1832 static const enum index item_geneve[] = { 1833 ITEM_GENEVE_VNI, 1834 ITEM_GENEVE_PROTO, 1835 ITEM_GENEVE_OPTLEN, 1836 ITEM_NEXT, 1837 ZERO, 1838 }; 1839 1840 static const enum index item_vxlan_gpe[] = { 1841 ITEM_VXLAN_GPE_VNI, 1842 ITEM_VXLAN_GPE_PROTO, 1843 ITEM_VXLAN_GPE_FLAGS, 1844 ITEM_NEXT, 1845 ZERO, 1846 }; 1847 1848 static const enum index item_arp_eth_ipv4[] = { 1849 ITEM_ARP_ETH_IPV4_SHA, 1850 ITEM_ARP_ETH_IPV4_SPA, 1851 ITEM_ARP_ETH_IPV4_THA, 1852 ITEM_ARP_ETH_IPV4_TPA, 1853 ITEM_NEXT, 1854 ZERO, 1855 }; 1856 1857 static const enum index item_ipv6_ext[] = { 1858 ITEM_IPV6_EXT_NEXT_HDR, 1859 ITEM_NEXT, 1860 ZERO, 1861 }; 1862 1863 static const enum index item_ipv6_frag_ext[] = { 1864 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 1865 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 1866 ITEM_IPV6_FRAG_EXT_ID, 1867 ITEM_NEXT, 1868 ZERO, 1869 }; 1870 1871 static const enum index item_icmp6[] = { 1872 ITEM_ICMP6_TYPE, 1873 ITEM_ICMP6_CODE, 1874 ITEM_NEXT, 1875 ZERO, 1876 }; 1877 1878 static const enum index item_icmp6_echo_request[] = { 1879 ITEM_ICMP6_ECHO_REQUEST_ID, 1880 ITEM_ICMP6_ECHO_REQUEST_SEQ, 1881 ITEM_NEXT, 1882 ZERO, 1883 }; 1884 1885 static const enum index item_icmp6_echo_reply[] = { 1886 ITEM_ICMP6_ECHO_REPLY_ID, 1887 ITEM_ICMP6_ECHO_REPLY_SEQ, 1888 ITEM_NEXT, 1889 ZERO, 1890 }; 1891 1892 static const enum index item_icmp6_nd_ns[] = { 1893 ITEM_ICMP6_ND_NS_TARGET_ADDR, 1894 ITEM_NEXT, 1895 ZERO, 1896 }; 1897 1898 static const enum index item_icmp6_nd_na[] = { 1899 ITEM_ICMP6_ND_NA_TARGET_ADDR, 1900 ITEM_NEXT, 1901 ZERO, 1902 }; 1903 1904 static const enum index item_icmp6_nd_opt[] = { 1905 ITEM_ICMP6_ND_OPT_TYPE, 1906 ITEM_NEXT, 1907 ZERO, 1908 }; 1909 1910 static const enum index item_icmp6_nd_opt_sla_eth[] = { 1911 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 1912 ITEM_NEXT, 1913 ZERO, 1914 }; 1915 1916 static const enum index item_icmp6_nd_opt_tla_eth[] = { 1917 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 1918 ITEM_NEXT, 1919 ZERO, 1920 }; 1921 1922 static const enum index item_meta[] = { 1923 ITEM_META_DATA, 1924 ITEM_NEXT, 1925 ZERO, 1926 }; 1927 1928 static const enum index item_random[] = { 1929 ITEM_RANDOM_VALUE, 1930 ITEM_NEXT, 1931 ZERO, 1932 }; 1933 1934 static const enum index item_gtp_psc[] = { 1935 ITEM_GTP_PSC_QFI, 1936 ITEM_GTP_PSC_PDU_T, 1937 ITEM_NEXT, 1938 ZERO, 1939 }; 1940 1941 static const enum index item_pppoed[] = { 1942 ITEM_PPPOE_SEID, 1943 ITEM_NEXT, 1944 ZERO, 1945 }; 1946 1947 static const enum index item_pppoes[] = { 1948 ITEM_PPPOE_SEID, 1949 ITEM_NEXT, 1950 ZERO, 1951 }; 1952 1953 static const enum index item_pppoe_proto_id[] = { 1954 ITEM_NEXT, 1955 ZERO, 1956 }; 1957 1958 static const enum index item_higig2[] = { 1959 ITEM_HIGIG2_CLASSIFICATION, 1960 ITEM_HIGIG2_VID, 1961 ITEM_NEXT, 1962 ZERO, 1963 }; 1964 1965 static const enum index item_esp[] = { 1966 ITEM_ESP_SPI, 1967 ITEM_NEXT, 1968 ZERO, 1969 }; 1970 1971 static const enum index item_ah[] = { 1972 ITEM_AH_SPI, 1973 ITEM_NEXT, 1974 ZERO, 1975 }; 1976 1977 static const enum index item_pfcp[] = { 1978 ITEM_PFCP_S_FIELD, 1979 ITEM_PFCP_SEID, 1980 ITEM_NEXT, 1981 ZERO, 1982 }; 1983 1984 static const enum index next_set_raw[] = { 1985 SET_RAW_INDEX, 1986 ITEM_ETH, 1987 ZERO, 1988 }; 1989 1990 static const enum index item_tag[] = { 1991 ITEM_TAG_DATA, 1992 ITEM_TAG_INDEX, 1993 ITEM_NEXT, 1994 ZERO, 1995 }; 1996 1997 static const enum index item_l2tpv3oip[] = { 1998 ITEM_L2TPV3OIP_SESSION_ID, 1999 ITEM_NEXT, 2000 ZERO, 2001 }; 2002 2003 static const enum index item_ecpri[] = { 2004 ITEM_ECPRI_COMMON, 2005 ITEM_NEXT, 2006 ZERO, 2007 }; 2008 2009 static const enum index item_ecpri_common[] = { 2010 ITEM_ECPRI_COMMON_TYPE, 2011 ZERO, 2012 }; 2013 2014 static const enum index item_ecpri_common_type[] = { 2015 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 2016 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 2017 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 2018 ZERO, 2019 }; 2020 2021 static const enum index item_geneve_opt[] = { 2022 ITEM_GENEVE_OPT_CLASS, 2023 ITEM_GENEVE_OPT_TYPE, 2024 ITEM_GENEVE_OPT_LENGTH, 2025 ITEM_GENEVE_OPT_DATA, 2026 ITEM_NEXT, 2027 ZERO, 2028 }; 2029 2030 static const enum index item_integrity[] = { 2031 ITEM_INTEGRITY_LEVEL, 2032 ITEM_INTEGRITY_VALUE, 2033 ZERO, 2034 }; 2035 2036 static const enum index item_integrity_lv[] = { 2037 ITEM_INTEGRITY_LEVEL, 2038 ITEM_INTEGRITY_VALUE, 2039 ITEM_NEXT, 2040 ZERO, 2041 }; 2042 2043 static const enum index item_port_representor[] = { 2044 ITEM_PORT_REPRESENTOR_PORT_ID, 2045 ITEM_NEXT, 2046 ZERO, 2047 }; 2048 2049 static const enum index item_represented_port[] = { 2050 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 2051 ITEM_NEXT, 2052 ZERO, 2053 }; 2054 2055 static const enum index item_flex[] = { 2056 ITEM_FLEX_PATTERN_HANDLE, 2057 ITEM_FLEX_ITEM_HANDLE, 2058 ITEM_NEXT, 2059 ZERO, 2060 }; 2061 2062 static const enum index item_l2tpv2[] = { 2063 ITEM_L2TPV2_TYPE, 2064 ITEM_NEXT, 2065 ZERO, 2066 }; 2067 2068 static const enum index item_l2tpv2_type[] = { 2069 ITEM_L2TPV2_TYPE_DATA, 2070 ITEM_L2TPV2_TYPE_DATA_L, 2071 ITEM_L2TPV2_TYPE_DATA_S, 2072 ITEM_L2TPV2_TYPE_DATA_O, 2073 ITEM_L2TPV2_TYPE_DATA_L_S, 2074 ITEM_L2TPV2_TYPE_CTRL, 2075 ZERO, 2076 }; 2077 2078 static const enum index item_l2tpv2_type_data[] = { 2079 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 2080 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 2081 ITEM_NEXT, 2082 ZERO, 2083 }; 2084 2085 static const enum index item_l2tpv2_type_data_l[] = { 2086 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 2087 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 2088 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 2089 ITEM_NEXT, 2090 ZERO, 2091 }; 2092 2093 static const enum index item_l2tpv2_type_data_s[] = { 2094 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 2095 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 2096 ITEM_L2TPV2_MSG_DATA_S_NS, 2097 ITEM_L2TPV2_MSG_DATA_S_NR, 2098 ITEM_NEXT, 2099 ZERO, 2100 }; 2101 2102 static const enum index item_l2tpv2_type_data_o[] = { 2103 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 2104 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 2105 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 2106 ITEM_NEXT, 2107 ZERO, 2108 }; 2109 2110 static const enum index item_l2tpv2_type_data_l_s[] = { 2111 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 2112 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 2113 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 2114 ITEM_L2TPV2_MSG_DATA_L_S_NS, 2115 ITEM_L2TPV2_MSG_DATA_L_S_NR, 2116 ITEM_NEXT, 2117 ZERO, 2118 }; 2119 2120 static const enum index item_l2tpv2_type_ctrl[] = { 2121 ITEM_L2TPV2_MSG_CTRL_LENGTH, 2122 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 2123 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 2124 ITEM_L2TPV2_MSG_CTRL_NS, 2125 ITEM_L2TPV2_MSG_CTRL_NR, 2126 ITEM_NEXT, 2127 ZERO, 2128 }; 2129 2130 static const enum index item_ppp[] = { 2131 ITEM_PPP_ADDR, 2132 ITEM_PPP_CTRL, 2133 ITEM_PPP_PROTO_ID, 2134 ITEM_NEXT, 2135 ZERO, 2136 }; 2137 2138 static const enum index item_meter[] = { 2139 ITEM_METER_COLOR, 2140 ITEM_NEXT, 2141 ZERO, 2142 }; 2143 2144 static const enum index item_quota[] = { 2145 ITEM_QUOTA_STATE, 2146 ITEM_NEXT, 2147 ZERO, 2148 }; 2149 2150 static const enum index item_aggr_affinity[] = { 2151 ITEM_AGGR_AFFINITY_VALUE, 2152 ITEM_NEXT, 2153 ZERO, 2154 }; 2155 2156 static const enum index item_tx_queue[] = { 2157 ITEM_TX_QUEUE_VALUE, 2158 ITEM_NEXT, 2159 ZERO, 2160 }; 2161 2162 static const enum index item_ib_bth[] = { 2163 ITEM_IB_BTH_OPCODE, 2164 ITEM_IB_BTH_PKEY, 2165 ITEM_IB_BTH_DST_QPN, 2166 ITEM_IB_BTH_PSN, 2167 ITEM_NEXT, 2168 ZERO, 2169 }; 2170 2171 static const enum index item_ptype[] = { 2172 ITEM_PTYPE_VALUE, 2173 ITEM_NEXT, 2174 ZERO, 2175 }; 2176 2177 static const enum index item_nsh[] = { 2178 ITEM_NEXT, 2179 ZERO, 2180 }; 2181 2182 static const enum index item_compare_field[] = { 2183 ITEM_COMPARE_OP, 2184 ITEM_COMPARE_FIELD_A_TYPE, 2185 ITEM_COMPARE_FIELD_B_TYPE, 2186 ITEM_NEXT, 2187 ZERO, 2188 }; 2189 2190 static const enum index compare_field_a[] = { 2191 ITEM_COMPARE_FIELD_A_TYPE, 2192 ITEM_COMPARE_FIELD_A_LEVEL, 2193 ITEM_COMPARE_FIELD_A_TAG_INDEX, 2194 ITEM_COMPARE_FIELD_A_TYPE_ID, 2195 ITEM_COMPARE_FIELD_A_CLASS_ID, 2196 ITEM_COMPARE_FIELD_A_OFFSET, 2197 ITEM_COMPARE_FIELD_B_TYPE, 2198 ZERO, 2199 }; 2200 2201 static const enum index compare_field_b[] = { 2202 ITEM_COMPARE_FIELD_B_TYPE, 2203 ITEM_COMPARE_FIELD_B_LEVEL, 2204 ITEM_COMPARE_FIELD_B_TAG_INDEX, 2205 ITEM_COMPARE_FIELD_B_TYPE_ID, 2206 ITEM_COMPARE_FIELD_B_CLASS_ID, 2207 ITEM_COMPARE_FIELD_B_OFFSET, 2208 ITEM_COMPARE_FIELD_B_VALUE, 2209 ITEM_COMPARE_FIELD_B_POINTER, 2210 ITEM_COMPARE_FIELD_WIDTH, 2211 ZERO, 2212 }; 2213 2214 static const enum index next_action[] = { 2215 ACTION_END, 2216 ACTION_VOID, 2217 ACTION_PASSTHRU, 2218 ACTION_SKIP_CMAN, 2219 ACTION_JUMP, 2220 ACTION_MARK, 2221 ACTION_FLAG, 2222 ACTION_QUEUE, 2223 ACTION_DROP, 2224 ACTION_COUNT, 2225 ACTION_RSS, 2226 ACTION_PF, 2227 ACTION_VF, 2228 ACTION_PORT_ID, 2229 ACTION_METER, 2230 ACTION_METER_COLOR, 2231 ACTION_METER_MARK, 2232 ACTION_OF_DEC_NW_TTL, 2233 ACTION_OF_POP_VLAN, 2234 ACTION_OF_PUSH_VLAN, 2235 ACTION_OF_SET_VLAN_VID, 2236 ACTION_OF_SET_VLAN_PCP, 2237 ACTION_OF_POP_MPLS, 2238 ACTION_OF_PUSH_MPLS, 2239 ACTION_VXLAN_ENCAP, 2240 ACTION_VXLAN_DECAP, 2241 ACTION_NVGRE_ENCAP, 2242 ACTION_NVGRE_DECAP, 2243 ACTION_L2_ENCAP, 2244 ACTION_L2_DECAP, 2245 ACTION_MPLSOGRE_ENCAP, 2246 ACTION_MPLSOGRE_DECAP, 2247 ACTION_MPLSOUDP_ENCAP, 2248 ACTION_MPLSOUDP_DECAP, 2249 ACTION_SET_IPV4_SRC, 2250 ACTION_SET_IPV4_DST, 2251 ACTION_SET_IPV6_SRC, 2252 ACTION_SET_IPV6_DST, 2253 ACTION_SET_TP_SRC, 2254 ACTION_SET_TP_DST, 2255 ACTION_MAC_SWAP, 2256 ACTION_DEC_TTL, 2257 ACTION_SET_TTL, 2258 ACTION_SET_MAC_SRC, 2259 ACTION_SET_MAC_DST, 2260 ACTION_INC_TCP_SEQ, 2261 ACTION_DEC_TCP_SEQ, 2262 ACTION_INC_TCP_ACK, 2263 ACTION_DEC_TCP_ACK, 2264 ACTION_RAW_ENCAP, 2265 ACTION_RAW_DECAP, 2266 ACTION_SET_TAG, 2267 ACTION_SET_META, 2268 ACTION_SET_IPV4_DSCP, 2269 ACTION_SET_IPV6_DSCP, 2270 ACTION_AGE, 2271 ACTION_AGE_UPDATE, 2272 ACTION_SAMPLE, 2273 ACTION_INDIRECT, 2274 ACTION_INDIRECT_LIST, 2275 ACTION_SHARED_INDIRECT, 2276 ACTION_MODIFY_FIELD, 2277 ACTION_CONNTRACK, 2278 ACTION_CONNTRACK_UPDATE, 2279 ACTION_PORT_REPRESENTOR, 2280 ACTION_REPRESENTED_PORT, 2281 ACTION_SEND_TO_KERNEL, 2282 ACTION_QUOTA_CREATE, 2283 ACTION_QUOTA_QU, 2284 ACTION_IPV6_EXT_REMOVE, 2285 ACTION_IPV6_EXT_PUSH, 2286 ACTION_NAT64, 2287 ZERO, 2288 }; 2289 2290 static const enum index action_quota_create[] = { 2291 ACTION_QUOTA_CREATE_LIMIT, 2292 ACTION_QUOTA_CREATE_MODE, 2293 ACTION_NEXT, 2294 ZERO 2295 }; 2296 2297 static const enum index action_quota_update[] = { 2298 ACTION_QUOTA_QU_LIMIT, 2299 ACTION_QUOTA_QU_UPDATE_OP, 2300 ACTION_NEXT, 2301 ZERO 2302 }; 2303 2304 static const enum index action_mark[] = { 2305 ACTION_MARK_ID, 2306 ACTION_NEXT, 2307 ZERO, 2308 }; 2309 2310 static const enum index action_queue[] = { 2311 ACTION_QUEUE_INDEX, 2312 ACTION_NEXT, 2313 ZERO, 2314 }; 2315 2316 static const enum index action_count[] = { 2317 ACTION_COUNT_ID, 2318 ACTION_NEXT, 2319 ZERO, 2320 }; 2321 2322 static const enum index action_rss[] = { 2323 ACTION_RSS_FUNC, 2324 ACTION_RSS_LEVEL, 2325 ACTION_RSS_TYPES, 2326 ACTION_RSS_KEY, 2327 ACTION_RSS_KEY_LEN, 2328 ACTION_RSS_QUEUES, 2329 ACTION_NEXT, 2330 ZERO, 2331 }; 2332 2333 static const enum index action_vf[] = { 2334 ACTION_VF_ORIGINAL, 2335 ACTION_VF_ID, 2336 ACTION_NEXT, 2337 ZERO, 2338 }; 2339 2340 static const enum index action_port_id[] = { 2341 ACTION_PORT_ID_ORIGINAL, 2342 ACTION_PORT_ID_ID, 2343 ACTION_NEXT, 2344 ZERO, 2345 }; 2346 2347 static const enum index action_meter[] = { 2348 ACTION_METER_ID, 2349 ACTION_NEXT, 2350 ZERO, 2351 }; 2352 2353 static const enum index action_meter_color[] = { 2354 ACTION_METER_COLOR_TYPE, 2355 ACTION_NEXT, 2356 ZERO, 2357 }; 2358 2359 static const enum index action_meter_mark[] = { 2360 ACTION_METER_PROFILE, 2361 ACTION_METER_POLICY, 2362 ACTION_METER_COLOR_MODE, 2363 ACTION_METER_STATE, 2364 ACTION_NEXT, 2365 ZERO, 2366 }; 2367 2368 static const enum index action_of_push_vlan[] = { 2369 ACTION_OF_PUSH_VLAN_ETHERTYPE, 2370 ACTION_NEXT, 2371 ZERO, 2372 }; 2373 2374 static const enum index action_of_set_vlan_vid[] = { 2375 ACTION_OF_SET_VLAN_VID_VLAN_VID, 2376 ACTION_NEXT, 2377 ZERO, 2378 }; 2379 2380 static const enum index action_of_set_vlan_pcp[] = { 2381 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 2382 ACTION_NEXT, 2383 ZERO, 2384 }; 2385 2386 static const enum index action_of_pop_mpls[] = { 2387 ACTION_OF_POP_MPLS_ETHERTYPE, 2388 ACTION_NEXT, 2389 ZERO, 2390 }; 2391 2392 static const enum index action_of_push_mpls[] = { 2393 ACTION_OF_PUSH_MPLS_ETHERTYPE, 2394 ACTION_NEXT, 2395 ZERO, 2396 }; 2397 2398 static const enum index action_set_ipv4_src[] = { 2399 ACTION_SET_IPV4_SRC_IPV4_SRC, 2400 ACTION_NEXT, 2401 ZERO, 2402 }; 2403 2404 static const enum index action_set_mac_src[] = { 2405 ACTION_SET_MAC_SRC_MAC_SRC, 2406 ACTION_NEXT, 2407 ZERO, 2408 }; 2409 2410 static const enum index action_set_ipv4_dst[] = { 2411 ACTION_SET_IPV4_DST_IPV4_DST, 2412 ACTION_NEXT, 2413 ZERO, 2414 }; 2415 2416 static const enum index action_set_ipv6_src[] = { 2417 ACTION_SET_IPV6_SRC_IPV6_SRC, 2418 ACTION_NEXT, 2419 ZERO, 2420 }; 2421 2422 static const enum index action_set_ipv6_dst[] = { 2423 ACTION_SET_IPV6_DST_IPV6_DST, 2424 ACTION_NEXT, 2425 ZERO, 2426 }; 2427 2428 static const enum index action_set_tp_src[] = { 2429 ACTION_SET_TP_SRC_TP_SRC, 2430 ACTION_NEXT, 2431 ZERO, 2432 }; 2433 2434 static const enum index action_set_tp_dst[] = { 2435 ACTION_SET_TP_DST_TP_DST, 2436 ACTION_NEXT, 2437 ZERO, 2438 }; 2439 2440 static const enum index action_set_ttl[] = { 2441 ACTION_SET_TTL_TTL, 2442 ACTION_NEXT, 2443 ZERO, 2444 }; 2445 2446 static const enum index action_jump[] = { 2447 ACTION_JUMP_GROUP, 2448 ACTION_NEXT, 2449 ZERO, 2450 }; 2451 2452 static const enum index action_set_mac_dst[] = { 2453 ACTION_SET_MAC_DST_MAC_DST, 2454 ACTION_NEXT, 2455 ZERO, 2456 }; 2457 2458 static const enum index action_inc_tcp_seq[] = { 2459 ACTION_INC_TCP_SEQ_VALUE, 2460 ACTION_NEXT, 2461 ZERO, 2462 }; 2463 2464 static const enum index action_dec_tcp_seq[] = { 2465 ACTION_DEC_TCP_SEQ_VALUE, 2466 ACTION_NEXT, 2467 ZERO, 2468 }; 2469 2470 static const enum index action_inc_tcp_ack[] = { 2471 ACTION_INC_TCP_ACK_VALUE, 2472 ACTION_NEXT, 2473 ZERO, 2474 }; 2475 2476 static const enum index action_dec_tcp_ack[] = { 2477 ACTION_DEC_TCP_ACK_VALUE, 2478 ACTION_NEXT, 2479 ZERO, 2480 }; 2481 2482 static const enum index action_raw_encap[] = { 2483 ACTION_RAW_ENCAP_SIZE, 2484 ACTION_RAW_ENCAP_INDEX, 2485 ACTION_NEXT, 2486 ZERO, 2487 }; 2488 2489 static const enum index action_raw_decap[] = { 2490 ACTION_RAW_DECAP_INDEX, 2491 ACTION_NEXT, 2492 ZERO, 2493 }; 2494 2495 static const enum index action_ipv6_ext_remove[] = { 2496 ACTION_IPV6_EXT_REMOVE_INDEX, 2497 ACTION_NEXT, 2498 ZERO, 2499 }; 2500 2501 static const enum index action_ipv6_ext_push[] = { 2502 ACTION_IPV6_EXT_PUSH_INDEX, 2503 ACTION_NEXT, 2504 ZERO, 2505 }; 2506 2507 static const enum index action_set_tag[] = { 2508 ACTION_SET_TAG_DATA, 2509 ACTION_SET_TAG_INDEX, 2510 ACTION_SET_TAG_MASK, 2511 ACTION_NEXT, 2512 ZERO, 2513 }; 2514 2515 static const enum index action_set_meta[] = { 2516 ACTION_SET_META_DATA, 2517 ACTION_SET_META_MASK, 2518 ACTION_NEXT, 2519 ZERO, 2520 }; 2521 2522 static const enum index action_set_ipv4_dscp[] = { 2523 ACTION_SET_IPV4_DSCP_VALUE, 2524 ACTION_NEXT, 2525 ZERO, 2526 }; 2527 2528 static const enum index action_set_ipv6_dscp[] = { 2529 ACTION_SET_IPV6_DSCP_VALUE, 2530 ACTION_NEXT, 2531 ZERO, 2532 }; 2533 2534 static const enum index action_age[] = { 2535 ACTION_AGE, 2536 ACTION_AGE_TIMEOUT, 2537 ACTION_NEXT, 2538 ZERO, 2539 }; 2540 2541 static const enum index action_age_update[] = { 2542 ACTION_AGE_UPDATE, 2543 ACTION_AGE_UPDATE_TIMEOUT, 2544 ACTION_AGE_UPDATE_TOUCH, 2545 ACTION_NEXT, 2546 ZERO, 2547 }; 2548 2549 static const enum index action_sample[] = { 2550 ACTION_SAMPLE, 2551 ACTION_SAMPLE_RATIO, 2552 ACTION_SAMPLE_INDEX, 2553 ACTION_NEXT, 2554 ZERO, 2555 }; 2556 2557 static const enum index next_action_sample[] = { 2558 ACTION_QUEUE, 2559 ACTION_RSS, 2560 ACTION_MARK, 2561 ACTION_COUNT, 2562 ACTION_PORT_ID, 2563 ACTION_RAW_ENCAP, 2564 ACTION_VXLAN_ENCAP, 2565 ACTION_NVGRE_ENCAP, 2566 ACTION_REPRESENTED_PORT, 2567 ACTION_PORT_REPRESENTOR, 2568 ACTION_NEXT, 2569 ZERO, 2570 }; 2571 2572 static const enum index item_ipv6_push_ext[] = { 2573 ITEM_IPV6_PUSH_REMOVE_EXT, 2574 ZERO, 2575 }; 2576 2577 static const enum index item_ipv6_push_ext_type[] = { 2578 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 2579 ZERO, 2580 }; 2581 2582 static const enum index item_ipv6_push_ext_header[] = { 2583 ITEM_IPV6_ROUTING_EXT, 2584 ITEM_NEXT, 2585 ZERO, 2586 }; 2587 2588 static const enum index action_modify_field_dst[] = { 2589 ACTION_MODIFY_FIELD_DST_LEVEL, 2590 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 2591 ACTION_MODIFY_FIELD_DST_TYPE_ID, 2592 ACTION_MODIFY_FIELD_DST_CLASS_ID, 2593 ACTION_MODIFY_FIELD_DST_OFFSET, 2594 ACTION_MODIFY_FIELD_SRC_TYPE, 2595 ZERO, 2596 }; 2597 2598 static const enum index action_modify_field_src[] = { 2599 ACTION_MODIFY_FIELD_SRC_LEVEL, 2600 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 2601 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 2602 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 2603 ACTION_MODIFY_FIELD_SRC_OFFSET, 2604 ACTION_MODIFY_FIELD_SRC_VALUE, 2605 ACTION_MODIFY_FIELD_SRC_POINTER, 2606 ACTION_MODIFY_FIELD_WIDTH, 2607 ZERO, 2608 }; 2609 2610 static const enum index action_update_conntrack[] = { 2611 ACTION_CONNTRACK_UPDATE_DIR, 2612 ACTION_CONNTRACK_UPDATE_CTX, 2613 ACTION_NEXT, 2614 ZERO, 2615 }; 2616 2617 static const enum index action_port_representor[] = { 2618 ACTION_PORT_REPRESENTOR_PORT_ID, 2619 ACTION_NEXT, 2620 ZERO, 2621 }; 2622 2623 static const enum index action_represented_port[] = { 2624 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 2625 ACTION_NEXT, 2626 ZERO, 2627 }; 2628 2629 static const enum index action_nat64[] = { 2630 ACTION_NAT64_MODE, 2631 ACTION_NEXT, 2632 ZERO, 2633 }; 2634 2635 static const enum index next_hash_subcmd[] = { 2636 HASH_CALC_TABLE, 2637 HASH_CALC_ENCAP, 2638 ZERO, 2639 }; 2640 2641 static const enum index next_hash_encap_dest_subcmd[] = { 2642 ENCAP_HASH_FIELD_SRC_PORT, 2643 ENCAP_HASH_FIELD_GRE_FLOW_ID, 2644 ZERO, 2645 }; 2646 2647 static int parse_set_raw_encap_decap(struct context *, const struct token *, 2648 const char *, unsigned int, 2649 void *, unsigned int); 2650 static int parse_set_sample_action(struct context *, const struct token *, 2651 const char *, unsigned int, 2652 void *, unsigned int); 2653 static int parse_set_ipv6_ext_action(struct context *, const struct token *, 2654 const char *, unsigned int, 2655 void *, unsigned int); 2656 static int parse_set_init(struct context *, const struct token *, 2657 const char *, unsigned int, 2658 void *, unsigned int); 2659 static int 2660 parse_flex_handle(struct context *, const struct token *, 2661 const char *, unsigned int, void *, unsigned int); 2662 static int parse_init(struct context *, const struct token *, 2663 const char *, unsigned int, 2664 void *, unsigned int); 2665 static int parse_vc(struct context *, const struct token *, 2666 const char *, unsigned int, 2667 void *, unsigned int); 2668 static int parse_vc_spec(struct context *, const struct token *, 2669 const char *, unsigned int, void *, unsigned int); 2670 static int parse_vc_conf(struct context *, const struct token *, 2671 const char *, unsigned int, void *, unsigned int); 2672 static int parse_vc_conf_timeout(struct context *, const struct token *, 2673 const char *, unsigned int, void *, 2674 unsigned int); 2675 static int parse_vc_item_ecpri_type(struct context *, const struct token *, 2676 const char *, unsigned int, 2677 void *, unsigned int); 2678 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, 2679 const char *, unsigned int, 2680 void *, unsigned int); 2681 static int parse_vc_action_meter_color_type(struct context *, 2682 const struct token *, 2683 const char *, unsigned int, void *, 2684 unsigned int); 2685 static int parse_vc_action_rss(struct context *, const struct token *, 2686 const char *, unsigned int, void *, 2687 unsigned int); 2688 static int parse_vc_action_rss_func(struct context *, const struct token *, 2689 const char *, unsigned int, void *, 2690 unsigned int); 2691 static int parse_vc_action_rss_type(struct context *, const struct token *, 2692 const char *, unsigned int, void *, 2693 unsigned int); 2694 static int parse_vc_action_rss_queue(struct context *, const struct token *, 2695 const char *, unsigned int, void *, 2696 unsigned int); 2697 static int parse_vc_action_vxlan_encap(struct context *, const struct token *, 2698 const char *, unsigned int, void *, 2699 unsigned int); 2700 static int parse_vc_action_nvgre_encap(struct context *, const struct token *, 2701 const char *, unsigned int, void *, 2702 unsigned int); 2703 static int parse_vc_action_l2_encap(struct context *, const struct token *, 2704 const char *, unsigned int, void *, 2705 unsigned int); 2706 static int parse_vc_action_l2_decap(struct context *, const struct token *, 2707 const char *, unsigned int, void *, 2708 unsigned int); 2709 static int parse_vc_action_mplsogre_encap(struct context *, 2710 const struct token *, const char *, 2711 unsigned int, void *, unsigned int); 2712 static int parse_vc_action_mplsogre_decap(struct context *, 2713 const struct token *, const char *, 2714 unsigned int, void *, unsigned int); 2715 static int parse_vc_action_mplsoudp_encap(struct context *, 2716 const struct token *, const char *, 2717 unsigned int, void *, unsigned int); 2718 static int parse_vc_action_mplsoudp_decap(struct context *, 2719 const struct token *, const char *, 2720 unsigned int, void *, unsigned int); 2721 static int parse_vc_action_raw_encap(struct context *, 2722 const struct token *, const char *, 2723 unsigned int, void *, unsigned int); 2724 static int parse_vc_action_raw_decap(struct context *, 2725 const struct token *, const char *, 2726 unsigned int, void *, unsigned int); 2727 static int parse_vc_action_raw_encap_index(struct context *, 2728 const struct token *, const char *, 2729 unsigned int, void *, unsigned int); 2730 static int parse_vc_action_raw_decap_index(struct context *, 2731 const struct token *, const char *, 2732 unsigned int, void *, unsigned int); 2733 static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 2734 const char *str, unsigned int len, void *buf, 2735 unsigned int size); 2736 static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, 2737 const struct token *token, 2738 const char *str, unsigned int len, 2739 void *buf, 2740 unsigned int size); 2741 static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 2742 const char *str, unsigned int len, void *buf, 2743 unsigned int size); 2744 static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, 2745 const struct token *token, 2746 const char *str, unsigned int len, 2747 void *buf, 2748 unsigned int size); 2749 static int parse_vc_action_set_meta(struct context *ctx, 2750 const struct token *token, const char *str, 2751 unsigned int len, void *buf, 2752 unsigned int size); 2753 static int parse_vc_action_sample(struct context *ctx, 2754 const struct token *token, const char *str, 2755 unsigned int len, void *buf, 2756 unsigned int size); 2757 static int 2758 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 2759 const char *str, unsigned int len, void *buf, 2760 unsigned int size); 2761 static int 2762 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 2763 const char *str, unsigned int len, void *buf, 2764 unsigned int size); 2765 static int 2766 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 2767 const char *str, unsigned int len, void *buf, 2768 unsigned int size); 2769 static int 2770 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 2771 const char *str, unsigned int len, void *buf, 2772 unsigned int size); 2773 static int 2774 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 2775 const char *str, unsigned int len, void *buf, 2776 unsigned int size); 2777 static int parse_destroy(struct context *, const struct token *, 2778 const char *, unsigned int, 2779 void *, unsigned int); 2780 static int parse_flush(struct context *, const struct token *, 2781 const char *, unsigned int, 2782 void *, unsigned int); 2783 static int parse_dump(struct context *, const struct token *, 2784 const char *, unsigned int, 2785 void *, unsigned int); 2786 static int parse_query(struct context *, const struct token *, 2787 const char *, unsigned int, 2788 void *, unsigned int); 2789 static int parse_action(struct context *, const struct token *, 2790 const char *, unsigned int, 2791 void *, unsigned int); 2792 static int parse_list(struct context *, const struct token *, 2793 const char *, unsigned int, 2794 void *, unsigned int); 2795 static int parse_aged(struct context *, const struct token *, 2796 const char *, unsigned int, 2797 void *, unsigned int); 2798 static int parse_isolate(struct context *, const struct token *, 2799 const char *, unsigned int, 2800 void *, unsigned int); 2801 static int parse_configure(struct context *, const struct token *, 2802 const char *, unsigned int, 2803 void *, unsigned int); 2804 static int parse_template(struct context *, const struct token *, 2805 const char *, unsigned int, 2806 void *, unsigned int); 2807 static int parse_template_destroy(struct context *, const struct token *, 2808 const char *, unsigned int, 2809 void *, unsigned int); 2810 static int parse_table(struct context *, const struct token *, 2811 const char *, unsigned int, void *, unsigned int); 2812 static int parse_table_destroy(struct context *, const struct token *, 2813 const char *, unsigned int, 2814 void *, unsigned int); 2815 static int parse_qo(struct context *, const struct token *, 2816 const char *, unsigned int, 2817 void *, unsigned int); 2818 static int parse_qo_destroy(struct context *, const struct token *, 2819 const char *, unsigned int, 2820 void *, unsigned int); 2821 static int parse_qia(struct context *, const struct token *, 2822 const char *, unsigned int, 2823 void *, unsigned int); 2824 static int parse_qia_destroy(struct context *, const struct token *, 2825 const char *, unsigned int, 2826 void *, unsigned int); 2827 static int parse_push(struct context *, const struct token *, 2828 const char *, unsigned int, 2829 void *, unsigned int); 2830 static int parse_pull(struct context *, const struct token *, 2831 const char *, unsigned int, 2832 void *, unsigned int); 2833 static int parse_group(struct context *, const struct token *, 2834 const char *, unsigned int, 2835 void *, unsigned int); 2836 static int parse_hash(struct context *, const struct token *, 2837 const char *, unsigned int, 2838 void *, unsigned int); 2839 static int parse_tunnel(struct context *, const struct token *, 2840 const char *, unsigned int, 2841 void *, unsigned int); 2842 static int parse_flex(struct context *, const struct token *, 2843 const char *, unsigned int, void *, unsigned int); 2844 static int parse_int(struct context *, const struct token *, 2845 const char *, unsigned int, 2846 void *, unsigned int); 2847 static int parse_prefix(struct context *, const struct token *, 2848 const char *, unsigned int, 2849 void *, unsigned int); 2850 static int parse_boolean(struct context *, const struct token *, 2851 const char *, unsigned int, 2852 void *, unsigned int); 2853 static int parse_string(struct context *, const struct token *, 2854 const char *, unsigned int, 2855 void *, unsigned int); 2856 static int parse_hex(struct context *ctx, const struct token *token, 2857 const char *str, unsigned int len, 2858 void *buf, unsigned int size); 2859 static int parse_string0(struct context *, const struct token *, 2860 const char *, unsigned int, 2861 void *, unsigned int); 2862 static int parse_mac_addr(struct context *, const struct token *, 2863 const char *, unsigned int, 2864 void *, unsigned int); 2865 static int parse_ipv4_addr(struct context *, const struct token *, 2866 const char *, unsigned int, 2867 void *, unsigned int); 2868 static int parse_ipv6_addr(struct context *, const struct token *, 2869 const char *, unsigned int, 2870 void *, unsigned int); 2871 static int parse_port(struct context *, const struct token *, 2872 const char *, unsigned int, 2873 void *, unsigned int); 2874 static int parse_ia(struct context *, const struct token *, 2875 const char *, unsigned int, 2876 void *, unsigned int); 2877 static int parse_ia_destroy(struct context *ctx, const struct token *token, 2878 const char *str, unsigned int len, 2879 void *buf, unsigned int size); 2880 static int parse_ia_id2ptr(struct context *ctx, const struct token *token, 2881 const char *str, unsigned int len, void *buf, 2882 unsigned int size); 2883 2884 static int parse_indlst_id2ptr(struct context *ctx, const struct token *token, 2885 const char *str, unsigned int len, void *buf, 2886 unsigned int size); 2887 static int parse_ia_port(struct context *ctx, const struct token *token, 2888 const char *str, unsigned int len, void *buf, 2889 unsigned int size); 2890 static int parse_mp(struct context *, const struct token *, 2891 const char *, unsigned int, 2892 void *, unsigned int); 2893 static int parse_meter_profile_id2ptr(struct context *ctx, 2894 const struct token *token, 2895 const char *str, unsigned int len, 2896 void *buf, unsigned int size); 2897 static int parse_meter_policy_id2ptr(struct context *ctx, 2898 const struct token *token, 2899 const char *str, unsigned int len, 2900 void *buf, unsigned int size); 2901 static int parse_meter_color(struct context *ctx, const struct token *token, 2902 const char *str, unsigned int len, void *buf, 2903 unsigned int size); 2904 static int parse_insertion_table_type(struct context *ctx, const struct token *token, 2905 const char *str, unsigned int len, void *buf, 2906 unsigned int size); 2907 static int parse_hash_table_type(struct context *ctx, const struct token *token, 2908 const char *str, unsigned int len, void *buf, 2909 unsigned int size); 2910 static int 2911 parse_quota_state_name(struct context *ctx, const struct token *token, 2912 const char *str, unsigned int len, void *buf, 2913 unsigned int size); 2914 static int 2915 parse_quota_mode_name(struct context *ctx, const struct token *token, 2916 const char *str, unsigned int len, void *buf, 2917 unsigned int size); 2918 static int 2919 parse_quota_update_name(struct context *ctx, const struct token *token, 2920 const char *str, unsigned int len, void *buf, 2921 unsigned int size); 2922 static int 2923 parse_qu_mode_name(struct context *ctx, const struct token *token, 2924 const char *str, unsigned int len, void *buf, 2925 unsigned int size); 2926 static int comp_none(struct context *, const struct token *, 2927 unsigned int, char *, unsigned int); 2928 static int comp_boolean(struct context *, const struct token *, 2929 unsigned int, char *, unsigned int); 2930 static int comp_action(struct context *, const struct token *, 2931 unsigned int, char *, unsigned int); 2932 static int comp_port(struct context *, const struct token *, 2933 unsigned int, char *, unsigned int); 2934 static int comp_rule_id(struct context *, const struct token *, 2935 unsigned int, char *, unsigned int); 2936 static int comp_vc_action_rss_type(struct context *, const struct token *, 2937 unsigned int, char *, unsigned int); 2938 static int comp_vc_action_rss_queue(struct context *, const struct token *, 2939 unsigned int, char *, unsigned int); 2940 static int comp_set_raw_index(struct context *, const struct token *, 2941 unsigned int, char *, unsigned int); 2942 static int comp_set_sample_index(struct context *, const struct token *, 2943 unsigned int, char *, unsigned int); 2944 static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 2945 unsigned int ent, char *buf, unsigned int size); 2946 static int comp_set_modify_field_op(struct context *, const struct token *, 2947 unsigned int, char *, unsigned int); 2948 static int comp_set_modify_field_id(struct context *, const struct token *, 2949 unsigned int, char *, unsigned int); 2950 static int comp_pattern_template_id(struct context *, const struct token *, 2951 unsigned int, char *, unsigned int); 2952 static int comp_actions_template_id(struct context *, const struct token *, 2953 unsigned int, char *, unsigned int); 2954 static int comp_table_id(struct context *, const struct token *, 2955 unsigned int, char *, unsigned int); 2956 static int comp_queue_id(struct context *, const struct token *, 2957 unsigned int, char *, unsigned int); 2958 static int comp_meter_color(struct context *, const struct token *, 2959 unsigned int, char *, unsigned int); 2960 static int comp_insertion_table_type(struct context *, const struct token *, 2961 unsigned int, char *, unsigned int); 2962 static int comp_hash_table_type(struct context *, const struct token *, 2963 unsigned int, char *, unsigned int); 2964 static int 2965 comp_quota_state_name(struct context *ctx, const struct token *token, 2966 unsigned int ent, char *buf, unsigned int size); 2967 static int 2968 comp_quota_mode_name(struct context *ctx, const struct token *token, 2969 unsigned int ent, char *buf, unsigned int size); 2970 static int 2971 comp_quota_update_name(struct context *ctx, const struct token *token, 2972 unsigned int ent, char *buf, unsigned int size); 2973 static int 2974 comp_qu_mode_name(struct context *ctx, const struct token *token, 2975 unsigned int ent, char *buf, unsigned int size); 2976 static int 2977 comp_set_compare_field_id(struct context *ctx, const struct token *token, 2978 unsigned int ent, char *buf, unsigned int size); 2979 static int 2980 comp_set_compare_op(struct context *ctx, const struct token *token, 2981 unsigned int ent, char *buf, unsigned int size); 2982 static int 2983 parse_vc_compare_op(struct context *ctx, const struct token *token, 2984 const char *str, unsigned int len, void *buf, 2985 unsigned int size); 2986 static int 2987 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 2988 const char *str, unsigned int len, void *buf, 2989 unsigned int size); 2990 static int 2991 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 2992 const char *str, unsigned int len, void *buf, 2993 unsigned int size); 2994 2995 struct indlst_conf { 2996 uint32_t id; 2997 uint32_t conf_num; 2998 struct rte_flow_action *actions; 2999 const void **conf; 3000 SLIST_ENTRY(indlst_conf) next; 3001 }; 3002 3003 static const struct indlst_conf *indirect_action_list_conf_get(uint32_t conf_id); 3004 3005 /** Token definitions. */ 3006 static const struct token token_list[] = { 3007 /* Special tokens. */ 3008 [ZERO] = { 3009 .name = "ZERO", 3010 .help = "null entry, abused as the entry point", 3011 .next = NEXT(NEXT_ENTRY(FLOW, ADD)), 3012 }, 3013 [END] = { 3014 .name = "", 3015 .type = "RETURN", 3016 .help = "command may end here", 3017 }, 3018 [START_SET] = { 3019 .name = "START_SET", 3020 .help = "null entry, abused as the entry point for set", 3021 .next = NEXT(NEXT_ENTRY(SET)), 3022 }, 3023 [END_SET] = { 3024 .name = "end_set", 3025 .type = "RETURN", 3026 .help = "set command may end here", 3027 }, 3028 /* Common tokens. */ 3029 [COMMON_INTEGER] = { 3030 .name = "{int}", 3031 .type = "INTEGER", 3032 .help = "integer value", 3033 .call = parse_int, 3034 .comp = comp_none, 3035 }, 3036 [COMMON_UNSIGNED] = { 3037 .name = "{unsigned}", 3038 .type = "UNSIGNED", 3039 .help = "unsigned integer value", 3040 .call = parse_int, 3041 .comp = comp_none, 3042 }, 3043 [COMMON_PREFIX] = { 3044 .name = "{prefix}", 3045 .type = "PREFIX", 3046 .help = "prefix length for bit-mask", 3047 .call = parse_prefix, 3048 .comp = comp_none, 3049 }, 3050 [COMMON_BOOLEAN] = { 3051 .name = "{boolean}", 3052 .type = "BOOLEAN", 3053 .help = "any boolean value", 3054 .call = parse_boolean, 3055 .comp = comp_boolean, 3056 }, 3057 [COMMON_STRING] = { 3058 .name = "{string}", 3059 .type = "STRING", 3060 .help = "fixed string", 3061 .call = parse_string, 3062 .comp = comp_none, 3063 }, 3064 [COMMON_HEX] = { 3065 .name = "{hex}", 3066 .type = "HEX", 3067 .help = "fixed string", 3068 .call = parse_hex, 3069 }, 3070 [COMMON_FILE_PATH] = { 3071 .name = "{file path}", 3072 .type = "STRING", 3073 .help = "file path", 3074 .call = parse_string0, 3075 .comp = comp_none, 3076 }, 3077 [COMMON_MAC_ADDR] = { 3078 .name = "{MAC address}", 3079 .type = "MAC-48", 3080 .help = "standard MAC address notation", 3081 .call = parse_mac_addr, 3082 .comp = comp_none, 3083 }, 3084 [COMMON_IPV4_ADDR] = { 3085 .name = "{IPv4 address}", 3086 .type = "IPV4 ADDRESS", 3087 .help = "standard IPv4 address notation", 3088 .call = parse_ipv4_addr, 3089 .comp = comp_none, 3090 }, 3091 [COMMON_IPV6_ADDR] = { 3092 .name = "{IPv6 address}", 3093 .type = "IPV6 ADDRESS", 3094 .help = "standard IPv6 address notation", 3095 .call = parse_ipv6_addr, 3096 .comp = comp_none, 3097 }, 3098 [COMMON_RULE_ID] = { 3099 .name = "{rule id}", 3100 .type = "RULE ID", 3101 .help = "rule identifier", 3102 .call = parse_int, 3103 .comp = comp_rule_id, 3104 }, 3105 [COMMON_PORT_ID] = { 3106 .name = "{port_id}", 3107 .type = "PORT ID", 3108 .help = "port identifier", 3109 .call = parse_port, 3110 .comp = comp_port, 3111 }, 3112 [COMMON_GROUP_ID] = { 3113 .name = "{group_id}", 3114 .type = "GROUP ID", 3115 .help = "group identifier", 3116 .call = parse_int, 3117 .comp = comp_none, 3118 }, 3119 [COMMON_PRIORITY_LEVEL] = { 3120 .name = "{level}", 3121 .type = "PRIORITY", 3122 .help = "priority level", 3123 .call = parse_int, 3124 .comp = comp_none, 3125 }, 3126 [COMMON_INDIRECT_ACTION_ID] = { 3127 .name = "{indirect_action_id}", 3128 .type = "INDIRECT_ACTION_ID", 3129 .help = "indirect action id", 3130 .call = parse_int, 3131 .comp = comp_none, 3132 }, 3133 [COMMON_PROFILE_ID] = { 3134 .name = "{profile_id}", 3135 .type = "PROFILE_ID", 3136 .help = "profile id", 3137 .call = parse_int, 3138 .comp = comp_none, 3139 }, 3140 [COMMON_POLICY_ID] = { 3141 .name = "{policy_id}", 3142 .type = "POLICY_ID", 3143 .help = "policy id", 3144 .call = parse_int, 3145 .comp = comp_none, 3146 }, 3147 [COMMON_FLEX_TOKEN] = { 3148 .name = "{flex token}", 3149 .type = "flex token", 3150 .help = "flex token", 3151 .call = parse_int, 3152 .comp = comp_none, 3153 }, 3154 [COMMON_FLEX_HANDLE] = { 3155 .name = "{flex handle}", 3156 .type = "FLEX HANDLE", 3157 .help = "fill flex item data", 3158 .call = parse_flex_handle, 3159 .comp = comp_none, 3160 }, 3161 [COMMON_PATTERN_TEMPLATE_ID] = { 3162 .name = "{pattern_template_id}", 3163 .type = "PATTERN_TEMPLATE_ID", 3164 .help = "pattern template id", 3165 .call = parse_int, 3166 .comp = comp_pattern_template_id, 3167 }, 3168 [COMMON_ACTIONS_TEMPLATE_ID] = { 3169 .name = "{actions_template_id}", 3170 .type = "ACTIONS_TEMPLATE_ID", 3171 .help = "actions template id", 3172 .call = parse_int, 3173 .comp = comp_actions_template_id, 3174 }, 3175 [COMMON_TABLE_ID] = { 3176 .name = "{table_id}", 3177 .type = "TABLE_ID", 3178 .help = "table id", 3179 .call = parse_int, 3180 .comp = comp_table_id, 3181 }, 3182 [COMMON_QUEUE_ID] = { 3183 .name = "{queue_id}", 3184 .type = "QUEUE_ID", 3185 .help = "queue id", 3186 .call = parse_int, 3187 .comp = comp_queue_id, 3188 }, 3189 /* Top-level command. */ 3190 [FLOW] = { 3191 .name = "flow", 3192 .type = "{command} {port_id} [{arg} [...]]", 3193 .help = "manage ingress/egress flow rules", 3194 .next = NEXT(NEXT_ENTRY 3195 (INFO, 3196 CONFIGURE, 3197 PATTERN_TEMPLATE, 3198 ACTIONS_TEMPLATE, 3199 TABLE, 3200 FLOW_GROUP, 3201 INDIRECT_ACTION, 3202 VALIDATE, 3203 CREATE, 3204 DESTROY, 3205 FLUSH, 3206 DUMP, 3207 LIST, 3208 AGED, 3209 QUERY, 3210 ISOLATE, 3211 TUNNEL, 3212 FLEX, 3213 QUEUE, 3214 PUSH, 3215 PULL, 3216 HASH)), 3217 .call = parse_init, 3218 }, 3219 /* Top-level command. */ 3220 [INFO] = { 3221 .name = "info", 3222 .help = "get information about flow engine", 3223 .next = NEXT(NEXT_ENTRY(END), 3224 NEXT_ENTRY(COMMON_PORT_ID)), 3225 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3226 .call = parse_configure, 3227 }, 3228 /* Top-level command. */ 3229 [CONFIGURE] = { 3230 .name = "configure", 3231 .help = "configure flow engine", 3232 .next = NEXT(next_config_attr, 3233 NEXT_ENTRY(COMMON_PORT_ID)), 3234 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3235 .call = parse_configure, 3236 }, 3237 /* Configure arguments. */ 3238 [CONFIG_QUEUES_NUMBER] = { 3239 .name = "queues_number", 3240 .help = "number of queues", 3241 .next = NEXT(next_config_attr, 3242 NEXT_ENTRY(COMMON_UNSIGNED)), 3243 .args = ARGS(ARGS_ENTRY(struct buffer, 3244 args.configure.nb_queue)), 3245 }, 3246 [CONFIG_QUEUES_SIZE] = { 3247 .name = "queues_size", 3248 .help = "number of elements in queues", 3249 .next = NEXT(next_config_attr, 3250 NEXT_ENTRY(COMMON_UNSIGNED)), 3251 .args = ARGS(ARGS_ENTRY(struct buffer, 3252 args.configure.queue_attr.size)), 3253 }, 3254 [CONFIG_COUNTERS_NUMBER] = { 3255 .name = "counters_number", 3256 .help = "number of counters", 3257 .next = NEXT(next_config_attr, 3258 NEXT_ENTRY(COMMON_UNSIGNED)), 3259 .args = ARGS(ARGS_ENTRY(struct buffer, 3260 args.configure.port_attr.nb_counters)), 3261 }, 3262 [CONFIG_AGING_OBJECTS_NUMBER] = { 3263 .name = "aging_counters_number", 3264 .help = "number of aging objects", 3265 .next = NEXT(next_config_attr, 3266 NEXT_ENTRY(COMMON_UNSIGNED)), 3267 .args = ARGS(ARGS_ENTRY(struct buffer, 3268 args.configure.port_attr.nb_aging_objects)), 3269 }, 3270 [CONFIG_QUOTAS_NUMBER] = { 3271 .name = "quotas_number", 3272 .help = "number of quotas", 3273 .next = NEXT(next_config_attr, 3274 NEXT_ENTRY(COMMON_UNSIGNED)), 3275 .args = ARGS(ARGS_ENTRY(struct buffer, 3276 args.configure.port_attr.nb_quotas)), 3277 }, 3278 [CONFIG_METERS_NUMBER] = { 3279 .name = "meters_number", 3280 .help = "number of meters", 3281 .next = NEXT(next_config_attr, 3282 NEXT_ENTRY(COMMON_UNSIGNED)), 3283 .args = ARGS(ARGS_ENTRY(struct buffer, 3284 args.configure.port_attr.nb_meters)), 3285 }, 3286 [CONFIG_CONN_TRACK_NUMBER] = { 3287 .name = "conn_tracks_number", 3288 .help = "number of connection trackings", 3289 .next = NEXT(next_config_attr, 3290 NEXT_ENTRY(COMMON_UNSIGNED)), 3291 .args = ARGS(ARGS_ENTRY(struct buffer, 3292 args.configure.port_attr.nb_conn_tracks)), 3293 }, 3294 [CONFIG_FLAGS] = { 3295 .name = "flags", 3296 .help = "configuration flags", 3297 .next = NEXT(next_config_attr, 3298 NEXT_ENTRY(COMMON_UNSIGNED)), 3299 .args = ARGS(ARGS_ENTRY(struct buffer, 3300 args.configure.port_attr.flags)), 3301 }, 3302 [CONFIG_HOST_PORT] = { 3303 .name = "host_port", 3304 .help = "host port for shared objects", 3305 .next = NEXT(next_config_attr, 3306 NEXT_ENTRY(COMMON_UNSIGNED)), 3307 .args = ARGS(ARGS_ENTRY(struct buffer, 3308 args.configure.port_attr.host_port_id)), 3309 }, 3310 /* Top-level command. */ 3311 [PATTERN_TEMPLATE] = { 3312 .name = "pattern_template", 3313 .type = "{command} {port_id} [{arg} [...]]", 3314 .help = "manage pattern templates", 3315 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3316 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3317 .call = parse_template, 3318 }, 3319 /* Sub-level commands. */ 3320 [PATTERN_TEMPLATE_CREATE] = { 3321 .name = "create", 3322 .help = "create pattern template", 3323 .next = NEXT(next_pt_attr), 3324 .call = parse_template, 3325 }, 3326 [PATTERN_TEMPLATE_DESTROY] = { 3327 .name = "destroy", 3328 .help = "destroy pattern template", 3329 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), 3330 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3331 .call = parse_template_destroy, 3332 }, 3333 /* Pattern template arguments. */ 3334 [PATTERN_TEMPLATE_CREATE_ID] = { 3335 .name = "pattern_template_id", 3336 .help = "specify a pattern template id to create", 3337 .next = NEXT(next_pt_attr, 3338 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3339 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), 3340 }, 3341 [PATTERN_TEMPLATE_DESTROY_ID] = { 3342 .name = "pattern_template", 3343 .help = "specify a pattern template id to destroy", 3344 .next = NEXT(next_pt_destroy_attr, 3345 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3346 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3347 args.templ_destroy.template_id)), 3348 .call = parse_template_destroy, 3349 }, 3350 [PATTERN_TEMPLATE_RELAXED_MATCHING] = { 3351 .name = "relaxed", 3352 .help = "is matching relaxed", 3353 .next = NEXT(next_pt_attr, 3354 NEXT_ENTRY(COMMON_BOOLEAN)), 3355 .args = ARGS(ARGS_ENTRY_BF(struct buffer, 3356 args.vc.attr.reserved, 1)), 3357 }, 3358 [PATTERN_TEMPLATE_INGRESS] = { 3359 .name = "ingress", 3360 .help = "attribute pattern to ingress", 3361 .next = NEXT(next_pt_attr), 3362 .call = parse_template, 3363 }, 3364 [PATTERN_TEMPLATE_EGRESS] = { 3365 .name = "egress", 3366 .help = "attribute pattern to egress", 3367 .next = NEXT(next_pt_attr), 3368 .call = parse_template, 3369 }, 3370 [PATTERN_TEMPLATE_TRANSFER] = { 3371 .name = "transfer", 3372 .help = "attribute pattern to transfer", 3373 .next = NEXT(next_pt_attr), 3374 .call = parse_template, 3375 }, 3376 [PATTERN_TEMPLATE_SPEC] = { 3377 .name = "template", 3378 .help = "specify item to create pattern template", 3379 .next = NEXT(next_item), 3380 }, 3381 /* Top-level command. */ 3382 [ACTIONS_TEMPLATE] = { 3383 .name = "actions_template", 3384 .type = "{command} {port_id} [{arg} [...]]", 3385 .help = "manage actions templates", 3386 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3387 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3388 .call = parse_template, 3389 }, 3390 /* Sub-level commands. */ 3391 [ACTIONS_TEMPLATE_CREATE] = { 3392 .name = "create", 3393 .help = "create actions template", 3394 .next = NEXT(next_at_attr), 3395 .call = parse_template, 3396 }, 3397 [ACTIONS_TEMPLATE_DESTROY] = { 3398 .name = "destroy", 3399 .help = "destroy actions template", 3400 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), 3401 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3402 .call = parse_template_destroy, 3403 }, 3404 /* Actions template arguments. */ 3405 [ACTIONS_TEMPLATE_CREATE_ID] = { 3406 .name = "actions_template_id", 3407 .help = "specify an actions template id to create", 3408 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), 3409 NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), 3410 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3411 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), 3412 }, 3413 [ACTIONS_TEMPLATE_DESTROY_ID] = { 3414 .name = "actions_template", 3415 .help = "specify an actions template id to destroy", 3416 .next = NEXT(next_at_destroy_attr, 3417 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3418 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3419 args.templ_destroy.template_id)), 3420 .call = parse_template_destroy, 3421 }, 3422 [ACTIONS_TEMPLATE_INGRESS] = { 3423 .name = "ingress", 3424 .help = "attribute actions to ingress", 3425 .next = NEXT(next_at_attr), 3426 .call = parse_template, 3427 }, 3428 [ACTIONS_TEMPLATE_EGRESS] = { 3429 .name = "egress", 3430 .help = "attribute actions to egress", 3431 .next = NEXT(next_at_attr), 3432 .call = parse_template, 3433 }, 3434 [ACTIONS_TEMPLATE_TRANSFER] = { 3435 .name = "transfer", 3436 .help = "attribute actions to transfer", 3437 .next = NEXT(next_at_attr), 3438 .call = parse_template, 3439 }, 3440 [ACTIONS_TEMPLATE_SPEC] = { 3441 .name = "template", 3442 .help = "specify action to create actions template", 3443 .next = NEXT(next_action), 3444 .call = parse_template, 3445 }, 3446 [ACTIONS_TEMPLATE_MASK] = { 3447 .name = "mask", 3448 .help = "specify action mask to create actions template", 3449 .next = NEXT(next_action), 3450 .call = parse_template, 3451 }, 3452 /* Top-level command. */ 3453 [TABLE] = { 3454 .name = "template_table", 3455 .type = "{command} {port_id} [{arg} [...]]", 3456 .help = "manage template tables", 3457 .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3458 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3459 .call = parse_table, 3460 }, 3461 /* Sub-level commands. */ 3462 [TABLE_CREATE] = { 3463 .name = "create", 3464 .help = "create template table", 3465 .next = NEXT(next_table_attr), 3466 .call = parse_table, 3467 }, 3468 [TABLE_DESTROY] = { 3469 .name = "destroy", 3470 .help = "destroy template table", 3471 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3472 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3473 .call = parse_table_destroy, 3474 }, 3475 [TABLE_RESIZE] = { 3476 .name = "resize", 3477 .help = "resize template table", 3478 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_ID)), 3479 .call = parse_table 3480 }, 3481 [TABLE_RESIZE_COMPLETE] = { 3482 .name = "resize_complete", 3483 .help = "complete table resize", 3484 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3485 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3486 .call = parse_table_destroy, 3487 }, 3488 /* Table arguments. */ 3489 [TABLE_CREATE_ID] = { 3490 .name = "table_id", 3491 .help = "specify table id to create", 3492 .next = NEXT(next_table_attr, 3493 NEXT_ENTRY(COMMON_TABLE_ID)), 3494 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3495 }, 3496 [TABLE_DESTROY_ID] = { 3497 .name = "table", 3498 .help = "table id", 3499 .next = NEXT(next_table_destroy_attr, 3500 NEXT_ENTRY(COMMON_TABLE_ID)), 3501 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3502 args.table_destroy.table_id)), 3503 .call = parse_table_destroy, 3504 }, 3505 [TABLE_RESIZE_ID] = { 3506 .name = "table_resize_id", 3507 .help = "table resize id", 3508 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_RULES_NUMBER), 3509 NEXT_ENTRY(COMMON_TABLE_ID)), 3510 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3511 .call = parse_table 3512 }, 3513 [TABLE_RESIZE_RULES_NUMBER] = { 3514 .name = "table_resize_rules_num", 3515 .help = "table resize rules number", 3516 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_UNSIGNED)), 3517 .args = ARGS(ARGS_ENTRY(struct buffer, 3518 args.table.attr.nb_flows)), 3519 .call = parse_table 3520 }, 3521 [TABLE_INSERTION_TYPE] = { 3522 .name = "insertion_type", 3523 .help = "specify insertion type", 3524 .next = NEXT(next_table_attr, 3525 NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)), 3526 .args = ARGS(ARGS_ENTRY(struct buffer, 3527 args.table.attr.insertion_type)), 3528 }, 3529 [TABLE_INSERTION_TYPE_NAME] = { 3530 .name = "insertion_type_name", 3531 .help = "insertion type name", 3532 .call = parse_insertion_table_type, 3533 .comp = comp_insertion_table_type, 3534 }, 3535 [TABLE_HASH_FUNC] = { 3536 .name = "hash_func", 3537 .help = "specify hash calculation function", 3538 .next = NEXT(next_table_attr, 3539 NEXT_ENTRY(TABLE_HASH_FUNC_NAME)), 3540 .args = ARGS(ARGS_ENTRY(struct buffer, 3541 args.table.attr.hash_func)), 3542 }, 3543 [TABLE_HASH_FUNC_NAME] = { 3544 .name = "hash_func_name", 3545 .help = "hash calculation function name", 3546 .call = parse_hash_table_type, 3547 .comp = comp_hash_table_type, 3548 }, 3549 [TABLE_GROUP] = { 3550 .name = "group", 3551 .help = "specify a group", 3552 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3553 .args = ARGS(ARGS_ENTRY(struct buffer, 3554 args.table.attr.flow_attr.group)), 3555 }, 3556 [TABLE_PRIORITY] = { 3557 .name = "priority", 3558 .help = "specify a priority level", 3559 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 3560 .args = ARGS(ARGS_ENTRY(struct buffer, 3561 args.table.attr.flow_attr.priority)), 3562 }, 3563 [TABLE_EGRESS] = { 3564 .name = "egress", 3565 .help = "affect rule to egress", 3566 .next = NEXT(next_table_attr), 3567 .call = parse_table, 3568 }, 3569 [TABLE_INGRESS] = { 3570 .name = "ingress", 3571 .help = "affect rule to ingress", 3572 .next = NEXT(next_table_attr), 3573 .call = parse_table, 3574 }, 3575 [TABLE_TRANSFER] = { 3576 .name = "transfer", 3577 .help = "affect rule to transfer", 3578 .next = NEXT(next_table_attr), 3579 .call = parse_table, 3580 }, 3581 [TABLE_TRANSFER_WIRE_ORIG] = { 3582 .name = "wire_orig", 3583 .help = "affect rule direction to transfer", 3584 .next = NEXT(next_table_attr), 3585 .call = parse_table, 3586 }, 3587 [TABLE_TRANSFER_VPORT_ORIG] = { 3588 .name = "vport_orig", 3589 .help = "affect rule direction to transfer", 3590 .next = NEXT(next_table_attr), 3591 .call = parse_table, 3592 }, 3593 [TABLE_RESIZABLE] = { 3594 .name = "resizable", 3595 .help = "set resizable attribute", 3596 .next = NEXT(next_table_attr), 3597 .call = parse_table, 3598 }, 3599 [TABLE_RULES_NUMBER] = { 3600 .name = "rules_number", 3601 .help = "number of rules in table", 3602 .next = NEXT(next_table_attr, 3603 NEXT_ENTRY(COMMON_UNSIGNED)), 3604 .args = ARGS(ARGS_ENTRY(struct buffer, 3605 args.table.attr.nb_flows)), 3606 .call = parse_table, 3607 }, 3608 [TABLE_PATTERN_TEMPLATE] = { 3609 .name = "pattern_template", 3610 .help = "specify pattern template id", 3611 .next = NEXT(next_table_attr, 3612 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3613 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3614 args.table.pat_templ_id)), 3615 .call = parse_table, 3616 }, 3617 [TABLE_ACTIONS_TEMPLATE] = { 3618 .name = "actions_template", 3619 .help = "specify actions template id", 3620 .next = NEXT(next_table_attr, 3621 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3622 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3623 args.table.act_templ_id)), 3624 .call = parse_table, 3625 }, 3626 /* Top-level command. */ 3627 [FLOW_GROUP] = { 3628 .name = "group", 3629 .help = "manage flow groups", 3630 .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), 3631 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3632 .call = parse_group, 3633 }, 3634 /* Sub-level commands. */ 3635 [GROUP_SET_MISS_ACTIONS] = { 3636 .name = "set_miss_actions", 3637 .help = "set group miss actions", 3638 .next = NEXT(next_action), 3639 .call = parse_group, 3640 }, 3641 /* Group arguments */ 3642 [GROUP_ID] = { 3643 .name = "group_id", 3644 .help = "group id", 3645 .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3646 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3647 }, 3648 [GROUP_INGRESS] = { 3649 .name = "ingress", 3650 .help = "group ingress attr", 3651 .next = NEXT(next_group_attr), 3652 .call = parse_group, 3653 }, 3654 [GROUP_EGRESS] = { 3655 .name = "egress", 3656 .help = "group egress attr", 3657 .next = NEXT(next_group_attr), 3658 .call = parse_group, 3659 }, 3660 [GROUP_TRANSFER] = { 3661 .name = "transfer", 3662 .help = "group transfer attr", 3663 .next = NEXT(next_group_attr), 3664 .call = parse_group, 3665 }, 3666 /* Top-level command. */ 3667 [QUEUE] = { 3668 .name = "queue", 3669 .help = "queue a flow rule operation", 3670 .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3671 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3672 .call = parse_qo, 3673 }, 3674 /* Sub-level commands. */ 3675 [QUEUE_CREATE] = { 3676 .name = "create", 3677 .help = "create a flow rule", 3678 .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), 3679 NEXT_ENTRY(COMMON_QUEUE_ID)), 3680 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3681 .call = parse_qo, 3682 }, 3683 [QUEUE_DESTROY] = { 3684 .name = "destroy", 3685 .help = "destroy a flow rule", 3686 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3687 NEXT_ENTRY(COMMON_QUEUE_ID)), 3688 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3689 .call = parse_qo_destroy, 3690 }, 3691 [QUEUE_FLOW_UPDATE_RESIZED] = { 3692 .name = "update_resized", 3693 .help = "update a flow after table resize", 3694 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3695 NEXT_ENTRY(COMMON_QUEUE_ID)), 3696 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3697 .call = parse_qo_destroy, 3698 }, 3699 [QUEUE_UPDATE] = { 3700 .name = "update", 3701 .help = "update a flow rule", 3702 .next = NEXT(NEXT_ENTRY(QUEUE_UPDATE_ID), 3703 NEXT_ENTRY(COMMON_QUEUE_ID)), 3704 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3705 .call = parse_qo, 3706 }, 3707 [QUEUE_AGED] = { 3708 .name = "aged", 3709 .help = "list and destroy aged flows", 3710 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), 3711 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3712 .call = parse_aged, 3713 }, 3714 [QUEUE_INDIRECT_ACTION] = { 3715 .name = "indirect_action", 3716 .help = "queue indirect actions", 3717 .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), 3718 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3719 .call = parse_qia, 3720 }, 3721 /* Queue arguments. */ 3722 [QUEUE_TEMPLATE_TABLE] = { 3723 .name = "template_table", 3724 .help = "specify table id", 3725 .next = NEXT(next_async_insert_subcmd, 3726 NEXT_ENTRY(COMMON_TABLE_ID)), 3727 .args = ARGS(ARGS_ENTRY(struct buffer, 3728 args.vc.table_id)), 3729 .call = parse_qo, 3730 }, 3731 [QUEUE_PATTERN_TEMPLATE] = { 3732 .name = "pattern_template", 3733 .help = "specify pattern template index", 3734 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3735 NEXT_ENTRY(COMMON_UNSIGNED)), 3736 .args = ARGS(ARGS_ENTRY(struct buffer, 3737 args.vc.pat_templ_id)), 3738 .call = parse_qo, 3739 }, 3740 [QUEUE_ACTIONS_TEMPLATE] = { 3741 .name = "actions_template", 3742 .help = "specify actions template index", 3743 .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), 3744 NEXT_ENTRY(COMMON_UNSIGNED)), 3745 .args = ARGS(ARGS_ENTRY(struct buffer, 3746 args.vc.act_templ_id)), 3747 .call = parse_qo, 3748 }, 3749 [QUEUE_RULE_ID] = { 3750 .name = "rule_index", 3751 .help = "specify flow rule index", 3752 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3753 NEXT_ENTRY(COMMON_UNSIGNED)), 3754 .args = ARGS(ARGS_ENTRY(struct buffer, 3755 args.vc.rule_id)), 3756 .call = parse_qo, 3757 }, 3758 [QUEUE_CREATE_POSTPONE] = { 3759 .name = "postpone", 3760 .help = "postpone create operation", 3761 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3762 NEXT_ENTRY(COMMON_BOOLEAN)), 3763 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3764 .call = parse_qo, 3765 }, 3766 [QUEUE_DESTROY_POSTPONE] = { 3767 .name = "postpone", 3768 .help = "postpone destroy operation", 3769 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3770 NEXT_ENTRY(COMMON_BOOLEAN)), 3771 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3772 .call = parse_qo_destroy, 3773 }, 3774 [QUEUE_DESTROY_ID] = { 3775 .name = "rule", 3776 .help = "specify rule id to destroy", 3777 .next = NEXT(next_queue_destroy_attr, 3778 NEXT_ENTRY(COMMON_UNSIGNED)), 3779 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3780 args.destroy.rule)), 3781 .call = parse_qo_destroy, 3782 }, 3783 [QUEUE_UPDATE_ID] = { 3784 .name = "rule", 3785 .help = "specify rule id to update", 3786 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3787 NEXT_ENTRY(COMMON_UNSIGNED)), 3788 .args = ARGS(ARGS_ENTRY(struct buffer, 3789 args.vc.rule_id)), 3790 .call = parse_qo, 3791 }, 3792 /* Queue indirect action arguments */ 3793 [QUEUE_INDIRECT_ACTION_CREATE] = { 3794 .name = "create", 3795 .help = "create indirect action", 3796 .next = NEXT(next_qia_create_attr), 3797 .call = parse_qia, 3798 }, 3799 [QUEUE_INDIRECT_ACTION_UPDATE] = { 3800 .name = "update", 3801 .help = "update indirect action", 3802 .next = NEXT(next_qia_update_attr, 3803 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3804 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3805 .call = parse_qia, 3806 }, 3807 [QUEUE_INDIRECT_ACTION_DESTROY] = { 3808 .name = "destroy", 3809 .help = "destroy indirect action", 3810 .next = NEXT(next_qia_destroy_attr), 3811 .call = parse_qia_destroy, 3812 }, 3813 [QUEUE_INDIRECT_ACTION_QUERY] = { 3814 .name = "query", 3815 .help = "query indirect action", 3816 .next = NEXT(next_qia_query_attr, 3817 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3818 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3819 .call = parse_qia, 3820 }, 3821 /* Indirect action destroy arguments. */ 3822 [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { 3823 .name = "postpone", 3824 .help = "postpone destroy operation", 3825 .next = NEXT(next_qia_destroy_attr, 3826 NEXT_ENTRY(COMMON_BOOLEAN)), 3827 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3828 }, 3829 [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { 3830 .name = "action_id", 3831 .help = "specify a indirect action id to destroy", 3832 .next = NEXT(next_qia_destroy_attr, 3833 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3834 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3835 args.ia_destroy.action_id)), 3836 .call = parse_qia_destroy, 3837 }, 3838 [QUEUE_INDIRECT_ACTION_QUERY_UPDATE] = { 3839 .name = "query_update", 3840 .help = "indirect query [and|or] update action", 3841 .next = NEXT(next_qia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3842 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3843 .call = parse_qia 3844 }, 3845 [QUEUE_INDIRECT_ACTION_QU_MODE] = { 3846 .name = "mode", 3847 .help = "indirect query [and|or] update action", 3848 .next = NEXT(next_qia_qu_attr, 3849 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 3850 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 3851 .call = parse_qia 3852 }, 3853 /* Indirect action update arguments. */ 3854 [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { 3855 .name = "postpone", 3856 .help = "postpone update operation", 3857 .next = NEXT(next_qia_update_attr, 3858 NEXT_ENTRY(COMMON_BOOLEAN)), 3859 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3860 }, 3861 /* Indirect action update arguments. */ 3862 [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { 3863 .name = "postpone", 3864 .help = "postpone query operation", 3865 .next = NEXT(next_qia_query_attr, 3866 NEXT_ENTRY(COMMON_BOOLEAN)), 3867 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3868 }, 3869 /* Indirect action create arguments. */ 3870 [QUEUE_INDIRECT_ACTION_CREATE_ID] = { 3871 .name = "action_id", 3872 .help = "specify a indirect action id to create", 3873 .next = NEXT(next_qia_create_attr, 3874 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3875 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3876 }, 3877 [QUEUE_INDIRECT_ACTION_INGRESS] = { 3878 .name = "ingress", 3879 .help = "affect rule to ingress", 3880 .next = NEXT(next_qia_create_attr), 3881 .call = parse_qia, 3882 }, 3883 [QUEUE_INDIRECT_ACTION_EGRESS] = { 3884 .name = "egress", 3885 .help = "affect rule to egress", 3886 .next = NEXT(next_qia_create_attr), 3887 .call = parse_qia, 3888 }, 3889 [QUEUE_INDIRECT_ACTION_TRANSFER] = { 3890 .name = "transfer", 3891 .help = "affect rule to transfer", 3892 .next = NEXT(next_qia_create_attr), 3893 .call = parse_qia, 3894 }, 3895 [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { 3896 .name = "postpone", 3897 .help = "postpone create operation", 3898 .next = NEXT(next_qia_create_attr, 3899 NEXT_ENTRY(COMMON_BOOLEAN)), 3900 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3901 }, 3902 [QUEUE_INDIRECT_ACTION_SPEC] = { 3903 .name = "action", 3904 .help = "specify action to create indirect handle", 3905 .next = NEXT(next_action), 3906 }, 3907 [QUEUE_INDIRECT_ACTION_LIST] = { 3908 .name = "list", 3909 .help = "specify actions for indirect handle list", 3910 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 3911 .call = parse_qia, 3912 }, 3913 /* Top-level command. */ 3914 [PUSH] = { 3915 .name = "push", 3916 .help = "push enqueued operations", 3917 .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3918 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3919 .call = parse_push, 3920 }, 3921 /* Sub-level commands. */ 3922 [PUSH_QUEUE] = { 3923 .name = "queue", 3924 .help = "specify queue id", 3925 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3926 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3927 }, 3928 /* Top-level command. */ 3929 [PULL] = { 3930 .name = "pull", 3931 .help = "pull flow operations results", 3932 .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3933 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3934 .call = parse_pull, 3935 }, 3936 /* Sub-level commands. */ 3937 [PULL_QUEUE] = { 3938 .name = "queue", 3939 .help = "specify queue id", 3940 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3941 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3942 }, 3943 /* Top-level command. */ 3944 [HASH] = { 3945 .name = "hash", 3946 .help = "calculate hash for a given pattern in a given template table", 3947 .next = NEXT(next_hash_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3948 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3949 .call = parse_hash, 3950 }, 3951 /* Sub-level commands. */ 3952 [HASH_CALC_TABLE] = { 3953 .name = "template_table", 3954 .help = "specify table id", 3955 .next = NEXT(NEXT_ENTRY(HASH_CALC_PATTERN_INDEX), 3956 NEXT_ENTRY(COMMON_TABLE_ID)), 3957 .args = ARGS(ARGS_ENTRY(struct buffer, 3958 args.vc.table_id)), 3959 .call = parse_hash, 3960 }, 3961 [HASH_CALC_ENCAP] = { 3962 .name = "encap", 3963 .help = "calculates encap hash", 3964 .next = NEXT(next_hash_encap_dest_subcmd), 3965 .call = parse_hash, 3966 }, 3967 [HASH_CALC_PATTERN_INDEX] = { 3968 .name = "pattern_template", 3969 .help = "specify pattern template id", 3970 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3971 NEXT_ENTRY(COMMON_UNSIGNED)), 3972 .args = ARGS(ARGS_ENTRY(struct buffer, 3973 args.vc.pat_templ_id)), 3974 .call = parse_hash, 3975 }, 3976 [ENCAP_HASH_FIELD_SRC_PORT] = { 3977 .name = "hash_field_sport", 3978 .help = "the encap hash field is src port", 3979 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 3980 .call = parse_hash, 3981 }, 3982 [ENCAP_HASH_FIELD_GRE_FLOW_ID] = { 3983 .name = "hash_field_flow_id", 3984 .help = "the encap hash field is NVGRE flow id", 3985 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 3986 .call = parse_hash, 3987 }, 3988 /* Top-level command. */ 3989 [INDIRECT_ACTION] = { 3990 .name = "indirect_action", 3991 .type = "{command} {port_id} [{arg} [...]]", 3992 .help = "manage indirect actions", 3993 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3994 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3995 .call = parse_ia, 3996 }, 3997 /* Sub-level commands. */ 3998 [INDIRECT_ACTION_CREATE] = { 3999 .name = "create", 4000 .help = "create indirect action", 4001 .next = NEXT(next_ia_create_attr), 4002 .call = parse_ia, 4003 }, 4004 [INDIRECT_ACTION_UPDATE] = { 4005 .name = "update", 4006 .help = "update indirect action", 4007 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), 4008 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4009 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 4010 .call = parse_ia, 4011 }, 4012 [INDIRECT_ACTION_DESTROY] = { 4013 .name = "destroy", 4014 .help = "destroy indirect action", 4015 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), 4016 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4017 .call = parse_ia_destroy, 4018 }, 4019 [INDIRECT_ACTION_QUERY] = { 4020 .name = "query", 4021 .help = "query indirect action", 4022 .next = NEXT(NEXT_ENTRY(END), 4023 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4024 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4025 .call = parse_ia, 4026 }, 4027 [INDIRECT_ACTION_QUERY_UPDATE] = { 4028 .name = "query_update", 4029 .help = "query [and|or] update", 4030 .next = NEXT(next_ia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4031 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4032 .call = parse_ia 4033 }, 4034 [INDIRECT_ACTION_QU_MODE] = { 4035 .name = "mode", 4036 .help = "query_update mode", 4037 .next = NEXT(next_ia_qu_attr, 4038 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 4039 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 4040 .call = parse_ia, 4041 }, 4042 [INDIRECT_ACTION_QU_MODE_NAME] = { 4043 .name = "mode_name", 4044 .help = "query-update mode name", 4045 .call = parse_qu_mode_name, 4046 .comp = comp_qu_mode_name, 4047 }, 4048 [VALIDATE] = { 4049 .name = "validate", 4050 .help = "check whether a flow rule can be created", 4051 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4052 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4053 .call = parse_vc, 4054 }, 4055 [CREATE] = { 4056 .name = "create", 4057 .help = "create a flow rule", 4058 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4059 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4060 .call = parse_vc, 4061 }, 4062 [DESTROY] = { 4063 .name = "destroy", 4064 .help = "destroy specific flow rules", 4065 .next = NEXT(next_destroy_attr, 4066 NEXT_ENTRY(COMMON_PORT_ID)), 4067 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4068 .call = parse_destroy, 4069 }, 4070 [FLUSH] = { 4071 .name = "flush", 4072 .help = "destroy all flow rules", 4073 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4074 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4075 .call = parse_flush, 4076 }, 4077 [DUMP] = { 4078 .name = "dump", 4079 .help = "dump single/all flow rules to file", 4080 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4081 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4082 .call = parse_dump, 4083 }, 4084 [QUERY] = { 4085 .name = "query", 4086 .help = "query an existing flow rule", 4087 .next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION), 4088 NEXT_ENTRY(COMMON_RULE_ID), 4089 NEXT_ENTRY(COMMON_PORT_ID)), 4090 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), 4091 ARGS_ENTRY(struct buffer, args.query.rule), 4092 ARGS_ENTRY(struct buffer, port)), 4093 .call = parse_query, 4094 }, 4095 [LIST] = { 4096 .name = "list", 4097 .help = "list existing flow rules", 4098 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4099 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4100 .call = parse_list, 4101 }, 4102 [AGED] = { 4103 .name = "aged", 4104 .help = "list and destroy aged flows", 4105 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4106 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4107 .call = parse_aged, 4108 }, 4109 [ISOLATE] = { 4110 .name = "isolate", 4111 .help = "restrict ingress traffic to the defined flow rules", 4112 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), 4113 NEXT_ENTRY(COMMON_PORT_ID)), 4114 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), 4115 ARGS_ENTRY(struct buffer, port)), 4116 .call = parse_isolate, 4117 }, 4118 [FLEX] = { 4119 .name = "flex_item", 4120 .help = "flex item API", 4121 .next = NEXT(next_flex_item), 4122 .call = parse_flex, 4123 }, 4124 [FLEX_ITEM_INIT] = { 4125 .name = "init", 4126 .help = "flex item init", 4127 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4128 ARGS_ENTRY(struct buffer, port)), 4129 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4130 NEXT_ENTRY(COMMON_PORT_ID)), 4131 .call = parse_flex 4132 }, 4133 [FLEX_ITEM_CREATE] = { 4134 .name = "create", 4135 .help = "flex item create", 4136 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), 4137 ARGS_ENTRY(struct buffer, args.flex.token), 4138 ARGS_ENTRY(struct buffer, port)), 4139 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), 4140 NEXT_ENTRY(COMMON_FLEX_TOKEN), 4141 NEXT_ENTRY(COMMON_PORT_ID)), 4142 .call = parse_flex 4143 }, 4144 [FLEX_ITEM_DESTROY] = { 4145 .name = "destroy", 4146 .help = "flex item destroy", 4147 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4148 ARGS_ENTRY(struct buffer, port)), 4149 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4150 NEXT_ENTRY(COMMON_PORT_ID)), 4151 .call = parse_flex 4152 }, 4153 [TUNNEL] = { 4154 .name = "tunnel", 4155 .help = "new tunnel API", 4156 .next = NEXT(NEXT_ENTRY 4157 (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), 4158 .call = parse_tunnel, 4159 }, 4160 /* Tunnel arguments. */ 4161 [TUNNEL_CREATE] = { 4162 .name = "create", 4163 .help = "create new tunnel object", 4164 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), 4165 NEXT_ENTRY(COMMON_PORT_ID)), 4166 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4167 .call = parse_tunnel, 4168 }, 4169 [TUNNEL_CREATE_TYPE] = { 4170 .name = "type", 4171 .help = "create new tunnel", 4172 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), 4173 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), 4174 .call = parse_tunnel, 4175 }, 4176 [TUNNEL_DESTROY] = { 4177 .name = "destroy", 4178 .help = "destroy tunnel", 4179 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), 4180 NEXT_ENTRY(COMMON_PORT_ID)), 4181 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4182 .call = parse_tunnel, 4183 }, 4184 [TUNNEL_DESTROY_ID] = { 4185 .name = "id", 4186 .help = "tunnel identifier to destroy", 4187 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), 4188 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4189 .call = parse_tunnel, 4190 }, 4191 [TUNNEL_LIST] = { 4192 .name = "list", 4193 .help = "list existing tunnels", 4194 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4195 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4196 .call = parse_tunnel, 4197 }, 4198 /* Destroy arguments. */ 4199 [DESTROY_RULE] = { 4200 .name = "rule", 4201 .help = "specify a rule identifier", 4202 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4203 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), 4204 .call = parse_destroy, 4205 }, 4206 [DESTROY_IS_USER_ID] = { 4207 .name = "user_id", 4208 .help = "rule identifier is user-id", 4209 .next = NEXT(next_destroy_attr), 4210 .call = parse_destroy, 4211 }, 4212 /* Dump arguments. */ 4213 [DUMP_ALL] = { 4214 .name = "all", 4215 .help = "dump all", 4216 .next = NEXT(next_dump_attr), 4217 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), 4218 .call = parse_dump, 4219 }, 4220 [DUMP_ONE] = { 4221 .name = "rule", 4222 .help = "dump one rule", 4223 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4224 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), 4225 ARGS_ENTRY(struct buffer, args.dump.rule)), 4226 .call = parse_dump, 4227 }, 4228 [DUMP_IS_USER_ID] = { 4229 .name = "user_id", 4230 .help = "rule identifier is user-id", 4231 .next = NEXT(next_dump_subcmd), 4232 .call = parse_dump, 4233 }, 4234 /* Query arguments. */ 4235 [QUERY_ACTION] = { 4236 .name = "{action}", 4237 .type = "ACTION", 4238 .help = "action to query, must be part of the rule", 4239 .call = parse_action, 4240 .comp = comp_action, 4241 }, 4242 [QUERY_IS_USER_ID] = { 4243 .name = "user_id", 4244 .help = "rule identifier is user-id", 4245 .next = NEXT(next_query_attr), 4246 .call = parse_query, 4247 }, 4248 /* List arguments. */ 4249 [LIST_GROUP] = { 4250 .name = "group", 4251 .help = "specify a group", 4252 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4253 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), 4254 .call = parse_list, 4255 }, 4256 [AGED_DESTROY] = { 4257 .name = "destroy", 4258 .help = "specify aged flows need be destroyed", 4259 .call = parse_aged, 4260 .comp = comp_none, 4261 }, 4262 /* Validate/create attributes. */ 4263 [VC_GROUP] = { 4264 .name = "group", 4265 .help = "specify a group", 4266 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4267 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), 4268 .call = parse_vc, 4269 }, 4270 [VC_PRIORITY] = { 4271 .name = "priority", 4272 .help = "specify a priority level", 4273 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 4274 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), 4275 .call = parse_vc, 4276 }, 4277 [VC_INGRESS] = { 4278 .name = "ingress", 4279 .help = "affect rule to ingress", 4280 .next = NEXT(next_vc_attr), 4281 .call = parse_vc, 4282 }, 4283 [VC_EGRESS] = { 4284 .name = "egress", 4285 .help = "affect rule to egress", 4286 .next = NEXT(next_vc_attr), 4287 .call = parse_vc, 4288 }, 4289 [VC_TRANSFER] = { 4290 .name = "transfer", 4291 .help = "apply rule directly to endpoints found in pattern", 4292 .next = NEXT(next_vc_attr), 4293 .call = parse_vc, 4294 }, 4295 [VC_TUNNEL_SET] = { 4296 .name = "tunnel_set", 4297 .help = "tunnel steer rule", 4298 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4299 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4300 .call = parse_vc, 4301 }, 4302 [VC_TUNNEL_MATCH] = { 4303 .name = "tunnel_match", 4304 .help = "tunnel match rule", 4305 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4306 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4307 .call = parse_vc, 4308 }, 4309 [VC_USER_ID] = { 4310 .name = "user_id", 4311 .help = "specify a user id to create", 4312 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4313 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)), 4314 .call = parse_vc, 4315 }, 4316 /* Validate/create pattern. */ 4317 [ITEM_PATTERN] = { 4318 .name = "pattern", 4319 .help = "submit a list of pattern items", 4320 .next = NEXT(next_item), 4321 .call = parse_vc, 4322 }, 4323 [ITEM_PARAM_IS] = { 4324 .name = "is", 4325 .help = "match value perfectly (with full bit-mask)", 4326 .call = parse_vc_spec, 4327 }, 4328 [ITEM_PARAM_SPEC] = { 4329 .name = "spec", 4330 .help = "match value according to configured bit-mask", 4331 .call = parse_vc_spec, 4332 }, 4333 [ITEM_PARAM_LAST] = { 4334 .name = "last", 4335 .help = "specify upper bound to establish a range", 4336 .call = parse_vc_spec, 4337 }, 4338 [ITEM_PARAM_MASK] = { 4339 .name = "mask", 4340 .help = "specify bit-mask with relevant bits set to one", 4341 .call = parse_vc_spec, 4342 }, 4343 [ITEM_PARAM_PREFIX] = { 4344 .name = "prefix", 4345 .help = "generate bit-mask from a prefix length", 4346 .call = parse_vc_spec, 4347 }, 4348 [ITEM_NEXT] = { 4349 .name = "/", 4350 .help = "specify next pattern item", 4351 .next = NEXT(next_item), 4352 }, 4353 [ITEM_END] = { 4354 .name = "end", 4355 .help = "end list of pattern items", 4356 .priv = PRIV_ITEM(END, 0), 4357 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 4358 .call = parse_vc, 4359 }, 4360 [ITEM_VOID] = { 4361 .name = "void", 4362 .help = "no-op pattern item", 4363 .priv = PRIV_ITEM(VOID, 0), 4364 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4365 .call = parse_vc, 4366 }, 4367 [ITEM_INVERT] = { 4368 .name = "invert", 4369 .help = "perform actions when pattern does not match", 4370 .priv = PRIV_ITEM(INVERT, 0), 4371 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4372 .call = parse_vc, 4373 }, 4374 [ITEM_ANY] = { 4375 .name = "any", 4376 .help = "match any protocol for the current layer", 4377 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), 4378 .next = NEXT(item_any), 4379 .call = parse_vc, 4380 }, 4381 [ITEM_ANY_NUM] = { 4382 .name = "num", 4383 .help = "number of layers covered", 4384 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4385 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), 4386 }, 4387 [ITEM_PORT_ID] = { 4388 .name = "port_id", 4389 .help = "match traffic from/to a given DPDK port ID", 4390 .priv = PRIV_ITEM(PORT_ID, 4391 sizeof(struct rte_flow_item_port_id)), 4392 .next = NEXT(item_port_id), 4393 .call = parse_vc, 4394 }, 4395 [ITEM_PORT_ID_ID] = { 4396 .name = "id", 4397 .help = "DPDK port ID", 4398 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), 4399 item_param), 4400 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), 4401 }, 4402 [ITEM_MARK] = { 4403 .name = "mark", 4404 .help = "match traffic against value set in previously matched rule", 4405 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), 4406 .next = NEXT(item_mark), 4407 .call = parse_vc, 4408 }, 4409 [ITEM_MARK_ID] = { 4410 .name = "id", 4411 .help = "Integer value to match against", 4412 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), 4413 item_param), 4414 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), 4415 }, 4416 [ITEM_RAW] = { 4417 .name = "raw", 4418 .help = "match an arbitrary byte string", 4419 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), 4420 .next = NEXT(item_raw), 4421 .call = parse_vc, 4422 }, 4423 [ITEM_RAW_RELATIVE] = { 4424 .name = "relative", 4425 .help = "look for pattern after the previous item", 4426 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4427 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4428 relative, 1)), 4429 }, 4430 [ITEM_RAW_SEARCH] = { 4431 .name = "search", 4432 .help = "search pattern from offset (see also limit)", 4433 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4434 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4435 search, 1)), 4436 }, 4437 [ITEM_RAW_OFFSET] = { 4438 .name = "offset", 4439 .help = "absolute or relative offset for pattern", 4440 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), 4441 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), 4442 }, 4443 [ITEM_RAW_LIMIT] = { 4444 .name = "limit", 4445 .help = "search area limit for start of pattern", 4446 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4447 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), 4448 }, 4449 [ITEM_RAW_PATTERN] = { 4450 .name = "pattern", 4451 .help = "byte string to look for", 4452 .next = NEXT(item_raw, 4453 NEXT_ENTRY(COMMON_STRING), 4454 NEXT_ENTRY(ITEM_PARAM_IS, 4455 ITEM_PARAM_SPEC, 4456 ITEM_PARAM_MASK)), 4457 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4458 ARGS_ENTRY(struct rte_flow_item_raw, length), 4459 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4460 ITEM_RAW_PATTERN_SIZE)), 4461 }, 4462 [ITEM_RAW_PATTERN_HEX] = { 4463 .name = "pattern_hex", 4464 .help = "hex string to look for", 4465 .next = NEXT(item_raw, 4466 NEXT_ENTRY(COMMON_HEX), 4467 NEXT_ENTRY(ITEM_PARAM_IS, 4468 ITEM_PARAM_SPEC, 4469 ITEM_PARAM_MASK)), 4470 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4471 ARGS_ENTRY(struct rte_flow_item_raw, length), 4472 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4473 ITEM_RAW_PATTERN_SIZE)), 4474 }, 4475 [ITEM_ETH] = { 4476 .name = "eth", 4477 .help = "match Ethernet header", 4478 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), 4479 .next = NEXT(item_eth), 4480 .call = parse_vc, 4481 }, 4482 [ITEM_ETH_DST] = { 4483 .name = "dst", 4484 .help = "destination MAC", 4485 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4486 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), 4487 }, 4488 [ITEM_ETH_SRC] = { 4489 .name = "src", 4490 .help = "source MAC", 4491 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4492 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), 4493 }, 4494 [ITEM_ETH_TYPE] = { 4495 .name = "type", 4496 .help = "EtherType", 4497 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4498 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), 4499 }, 4500 [ITEM_ETH_HAS_VLAN] = { 4501 .name = "has_vlan", 4502 .help = "packet header contains VLAN", 4503 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4504 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, 4505 has_vlan, 1)), 4506 }, 4507 [ITEM_VLAN] = { 4508 .name = "vlan", 4509 .help = "match 802.1Q/ad VLAN tag", 4510 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), 4511 .next = NEXT(item_vlan), 4512 .call = parse_vc, 4513 }, 4514 [ITEM_VLAN_TCI] = { 4515 .name = "tci", 4516 .help = "tag control information", 4517 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4518 item_param), 4519 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, hdr.vlan_tci)), 4520 }, 4521 [ITEM_VLAN_PCP] = { 4522 .name = "pcp", 4523 .help = "priority code point", 4524 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4525 item_param), 4526 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4527 hdr.vlan_tci, "\xe0\x00")), 4528 }, 4529 [ITEM_VLAN_DEI] = { 4530 .name = "dei", 4531 .help = "drop eligible indicator", 4532 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4533 item_param), 4534 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4535 hdr.vlan_tci, "\x10\x00")), 4536 }, 4537 [ITEM_VLAN_VID] = { 4538 .name = "vid", 4539 .help = "VLAN identifier", 4540 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4541 item_param), 4542 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4543 hdr.vlan_tci, "\x0f\xff")), 4544 }, 4545 [ITEM_VLAN_INNER_TYPE] = { 4546 .name = "inner_type", 4547 .help = "inner EtherType", 4548 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4549 item_param), 4550 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, 4551 hdr.eth_proto)), 4552 }, 4553 [ITEM_VLAN_HAS_MORE_VLAN] = { 4554 .name = "has_more_vlan", 4555 .help = "packet header contains another VLAN", 4556 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4557 item_param), 4558 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, 4559 has_more_vlan, 1)), 4560 }, 4561 [ITEM_IPV4] = { 4562 .name = "ipv4", 4563 .help = "match IPv4 header", 4564 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), 4565 .next = NEXT(item_ipv4), 4566 .call = parse_vc, 4567 }, 4568 [ITEM_IPV4_VER_IHL] = { 4569 .name = "version_ihl", 4570 .help = "match header length", 4571 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4572 item_param), 4573 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, 4574 hdr.version_ihl)), 4575 }, 4576 [ITEM_IPV4_TOS] = { 4577 .name = "tos", 4578 .help = "type of service", 4579 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4580 item_param), 4581 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4582 hdr.type_of_service)), 4583 }, 4584 [ITEM_IPV4_LENGTH] = { 4585 .name = "length", 4586 .help = "total length", 4587 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4588 item_param), 4589 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4590 hdr.total_length)), 4591 }, 4592 [ITEM_IPV4_ID] = { 4593 .name = "packet_id", 4594 .help = "fragment packet id", 4595 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4596 item_param), 4597 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4598 hdr.packet_id)), 4599 }, 4600 [ITEM_IPV4_FRAGMENT_OFFSET] = { 4601 .name = "fragment_offset", 4602 .help = "fragmentation flags and fragment offset", 4603 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4604 item_param), 4605 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4606 hdr.fragment_offset)), 4607 }, 4608 [ITEM_IPV4_TTL] = { 4609 .name = "ttl", 4610 .help = "time to live", 4611 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4612 item_param), 4613 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4614 hdr.time_to_live)), 4615 }, 4616 [ITEM_IPV4_PROTO] = { 4617 .name = "proto", 4618 .help = "next protocol ID", 4619 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4620 item_param), 4621 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4622 hdr.next_proto_id)), 4623 }, 4624 [ITEM_IPV4_SRC] = { 4625 .name = "src", 4626 .help = "source address", 4627 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4628 item_param), 4629 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4630 hdr.src_addr)), 4631 }, 4632 [ITEM_IPV4_DST] = { 4633 .name = "dst", 4634 .help = "destination address", 4635 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4636 item_param), 4637 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4638 hdr.dst_addr)), 4639 }, 4640 [ITEM_IPV6] = { 4641 .name = "ipv6", 4642 .help = "match IPv6 header", 4643 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), 4644 .next = NEXT(item_ipv6), 4645 .call = parse_vc, 4646 }, 4647 [ITEM_IPV6_TC] = { 4648 .name = "tc", 4649 .help = "traffic class", 4650 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4651 item_param), 4652 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4653 hdr.vtc_flow, 4654 "\x0f\xf0\x00\x00")), 4655 }, 4656 [ITEM_IPV6_FLOW] = { 4657 .name = "flow", 4658 .help = "flow label", 4659 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4660 item_param), 4661 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4662 hdr.vtc_flow, 4663 "\x00\x0f\xff\xff")), 4664 }, 4665 [ITEM_IPV6_LEN] = { 4666 .name = "length", 4667 .help = "payload length", 4668 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4669 item_param), 4670 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4671 hdr.payload_len)), 4672 }, 4673 [ITEM_IPV6_PROTO] = { 4674 .name = "proto", 4675 .help = "protocol (next header)", 4676 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4677 item_param), 4678 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4679 hdr.proto)), 4680 }, 4681 [ITEM_IPV6_HOP] = { 4682 .name = "hop", 4683 .help = "hop limit", 4684 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4685 item_param), 4686 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4687 hdr.hop_limits)), 4688 }, 4689 [ITEM_IPV6_SRC] = { 4690 .name = "src", 4691 .help = "source address", 4692 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4693 item_param), 4694 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4695 hdr.src_addr)), 4696 }, 4697 [ITEM_IPV6_DST] = { 4698 .name = "dst", 4699 .help = "destination address", 4700 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4701 item_param), 4702 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4703 hdr.dst_addr)), 4704 }, 4705 [ITEM_IPV6_HAS_FRAG_EXT] = { 4706 .name = "has_frag_ext", 4707 .help = "fragment packet attribute", 4708 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4709 item_param), 4710 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, 4711 has_frag_ext, 1)), 4712 }, 4713 [ITEM_IPV6_ROUTING_EXT] = { 4714 .name = "ipv6_routing_ext", 4715 .help = "match IPv6 routing extension header", 4716 .priv = PRIV_ITEM(IPV6_ROUTING_EXT, 4717 sizeof(struct rte_flow_item_ipv6_routing_ext)), 4718 .next = NEXT(item_ipv6_routing_ext), 4719 .call = parse_vc, 4720 }, 4721 [ITEM_IPV6_ROUTING_EXT_TYPE] = { 4722 .name = "ext_type", 4723 .help = "match IPv6 routing extension header type", 4724 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4725 item_param), 4726 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4727 hdr.type)), 4728 }, 4729 [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = { 4730 .name = "ext_next_hdr", 4731 .help = "match IPv6 routing extension header next header type", 4732 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4733 item_param), 4734 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4735 hdr.next_hdr)), 4736 }, 4737 [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = { 4738 .name = "ext_seg_left", 4739 .help = "match IPv6 routing extension header segment left", 4740 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4741 item_param), 4742 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4743 hdr.segments_left)), 4744 }, 4745 [ITEM_ICMP] = { 4746 .name = "icmp", 4747 .help = "match ICMP header", 4748 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), 4749 .next = NEXT(item_icmp), 4750 .call = parse_vc, 4751 }, 4752 [ITEM_ICMP_TYPE] = { 4753 .name = "type", 4754 .help = "ICMP packet type", 4755 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4756 item_param), 4757 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4758 hdr.icmp_type)), 4759 }, 4760 [ITEM_ICMP_CODE] = { 4761 .name = "code", 4762 .help = "ICMP packet code", 4763 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4764 item_param), 4765 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4766 hdr.icmp_code)), 4767 }, 4768 [ITEM_ICMP_IDENT] = { 4769 .name = "ident", 4770 .help = "ICMP packet identifier", 4771 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4772 item_param), 4773 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4774 hdr.icmp_ident)), 4775 }, 4776 [ITEM_ICMP_SEQ] = { 4777 .name = "seq", 4778 .help = "ICMP packet sequence number", 4779 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4780 item_param), 4781 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4782 hdr.icmp_seq_nb)), 4783 }, 4784 [ITEM_UDP] = { 4785 .name = "udp", 4786 .help = "match UDP header", 4787 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), 4788 .next = NEXT(item_udp), 4789 .call = parse_vc, 4790 }, 4791 [ITEM_UDP_SRC] = { 4792 .name = "src", 4793 .help = "UDP source port", 4794 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), 4795 item_param), 4796 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4797 hdr.src_port)), 4798 }, 4799 [ITEM_UDP_DST] = { 4800 .name = "dst", 4801 .help = "UDP destination port", 4802 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4803 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4804 hdr.dst_port)), 4805 }, 4806 [ITEM_TCP] = { 4807 .name = "tcp", 4808 .help = "match TCP header", 4809 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), 4810 .next = NEXT(item_tcp), 4811 .call = parse_vc, 4812 }, 4813 [ITEM_TCP_SRC] = { 4814 .name = "src", 4815 .help = "TCP source port", 4816 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4817 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4818 hdr.src_port)), 4819 }, 4820 [ITEM_TCP_DST] = { 4821 .name = "dst", 4822 .help = "TCP destination port", 4823 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4824 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4825 hdr.dst_port)), 4826 }, 4827 [ITEM_TCP_FLAGS] = { 4828 .name = "flags", 4829 .help = "TCP flags", 4830 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4831 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4832 hdr.tcp_flags)), 4833 }, 4834 [ITEM_SCTP] = { 4835 .name = "sctp", 4836 .help = "match SCTP header", 4837 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), 4838 .next = NEXT(item_sctp), 4839 .call = parse_vc, 4840 }, 4841 [ITEM_SCTP_SRC] = { 4842 .name = "src", 4843 .help = "SCTP source port", 4844 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4845 item_param), 4846 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4847 hdr.src_port)), 4848 }, 4849 [ITEM_SCTP_DST] = { 4850 .name = "dst", 4851 .help = "SCTP destination port", 4852 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4853 item_param), 4854 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4855 hdr.dst_port)), 4856 }, 4857 [ITEM_SCTP_TAG] = { 4858 .name = "tag", 4859 .help = "validation tag", 4860 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4861 item_param), 4862 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4863 hdr.tag)), 4864 }, 4865 [ITEM_SCTP_CKSUM] = { 4866 .name = "cksum", 4867 .help = "checksum", 4868 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4869 item_param), 4870 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4871 hdr.cksum)), 4872 }, 4873 [ITEM_VXLAN] = { 4874 .name = "vxlan", 4875 .help = "match VXLAN header", 4876 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), 4877 .next = NEXT(item_vxlan), 4878 .call = parse_vc, 4879 }, 4880 [ITEM_VXLAN_VNI] = { 4881 .name = "vni", 4882 .help = "VXLAN identifier", 4883 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4884 item_param), 4885 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), 4886 }, 4887 [ITEM_VXLAN_LAST_RSVD] = { 4888 .name = "last_rsvd", 4889 .help = "VXLAN last reserved bits", 4890 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4891 item_param), 4892 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 4893 hdr.rsvd1)), 4894 }, 4895 [ITEM_E_TAG] = { 4896 .name = "e_tag", 4897 .help = "match E-Tag header", 4898 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), 4899 .next = NEXT(item_e_tag), 4900 .call = parse_vc, 4901 }, 4902 [ITEM_E_TAG_GRP_ECID_B] = { 4903 .name = "grp_ecid_b", 4904 .help = "GRP and E-CID base", 4905 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), 4906 item_param), 4907 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, 4908 rsvd_grp_ecid_b, 4909 "\x3f\xff")), 4910 }, 4911 [ITEM_NVGRE] = { 4912 .name = "nvgre", 4913 .help = "match NVGRE header", 4914 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), 4915 .next = NEXT(item_nvgre), 4916 .call = parse_vc, 4917 }, 4918 [ITEM_NVGRE_TNI] = { 4919 .name = "tni", 4920 .help = "virtual subnet ID", 4921 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), 4922 item_param), 4923 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), 4924 }, 4925 [ITEM_MPLS] = { 4926 .name = "mpls", 4927 .help = "match MPLS header", 4928 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), 4929 .next = NEXT(item_mpls), 4930 .call = parse_vc, 4931 }, 4932 [ITEM_MPLS_LABEL] = { 4933 .name = "label", 4934 .help = "MPLS label", 4935 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4936 item_param), 4937 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4938 label_tc_s, 4939 "\xff\xff\xf0")), 4940 }, 4941 [ITEM_MPLS_TC] = { 4942 .name = "tc", 4943 .help = "MPLS Traffic Class", 4944 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4945 item_param), 4946 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4947 label_tc_s, 4948 "\x00\x00\x0e")), 4949 }, 4950 [ITEM_MPLS_S] = { 4951 .name = "s", 4952 .help = "MPLS Bottom-of-Stack", 4953 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4954 item_param), 4955 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4956 label_tc_s, 4957 "\x00\x00\x01")), 4958 }, 4959 [ITEM_MPLS_TTL] = { 4960 .name = "ttl", 4961 .help = "MPLS Time-to-Live", 4962 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4963 item_param), 4964 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls, ttl)), 4965 }, 4966 [ITEM_GRE] = { 4967 .name = "gre", 4968 .help = "match GRE header", 4969 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), 4970 .next = NEXT(item_gre), 4971 .call = parse_vc, 4972 }, 4973 [ITEM_GRE_PROTO] = { 4974 .name = "protocol", 4975 .help = "GRE protocol type", 4976 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 4977 item_param), 4978 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 4979 protocol)), 4980 }, 4981 [ITEM_GRE_C_RSVD0_VER] = { 4982 .name = "c_rsvd0_ver", 4983 .help = 4984 "checksum (1b), undefined (1b), key bit (1b)," 4985 " sequence number (1b), reserved 0 (9b)," 4986 " version (3b)", 4987 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 4988 item_param), 4989 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 4990 c_rsvd0_ver)), 4991 }, 4992 [ITEM_GRE_C_BIT] = { 4993 .name = "c_bit", 4994 .help = "checksum bit (C)", 4995 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), 4996 item_param), 4997 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 4998 c_rsvd0_ver, 4999 "\x80\x00\x00\x00")), 5000 }, 5001 [ITEM_GRE_S_BIT] = { 5002 .name = "s_bit", 5003 .help = "sequence number bit (S)", 5004 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5005 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5006 c_rsvd0_ver, 5007 "\x10\x00\x00\x00")), 5008 }, 5009 [ITEM_GRE_K_BIT] = { 5010 .name = "k_bit", 5011 .help = "key bit (K)", 5012 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5013 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5014 c_rsvd0_ver, 5015 "\x20\x00\x00\x00")), 5016 }, 5017 [ITEM_FUZZY] = { 5018 .name = "fuzzy", 5019 .help = "fuzzy pattern match, expect faster than default", 5020 .priv = PRIV_ITEM(FUZZY, 5021 sizeof(struct rte_flow_item_fuzzy)), 5022 .next = NEXT(item_fuzzy), 5023 .call = parse_vc, 5024 }, 5025 [ITEM_FUZZY_THRESH] = { 5026 .name = "thresh", 5027 .help = "match accuracy threshold", 5028 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), 5029 item_param), 5030 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, 5031 thresh)), 5032 }, 5033 [ITEM_GTP] = { 5034 .name = "gtp", 5035 .help = "match GTP header", 5036 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), 5037 .next = NEXT(item_gtp), 5038 .call = parse_vc, 5039 }, 5040 [ITEM_GTP_FLAGS] = { 5041 .name = "v_pt_rsv_flags", 5042 .help = "GTP flags", 5043 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5044 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, 5045 hdr.gtp_hdr_info)), 5046 }, 5047 [ITEM_GTP_MSG_TYPE] = { 5048 .name = "msg_type", 5049 .help = "GTP message type", 5050 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5051 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), 5052 }, 5053 [ITEM_GTP_TEID] = { 5054 .name = "teid", 5055 .help = "tunnel endpoint identifier", 5056 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5057 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), 5058 }, 5059 [ITEM_GTPC] = { 5060 .name = "gtpc", 5061 .help = "match GTP header", 5062 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), 5063 .next = NEXT(item_gtp), 5064 .call = parse_vc, 5065 }, 5066 [ITEM_GTPU] = { 5067 .name = "gtpu", 5068 .help = "match GTP header", 5069 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), 5070 .next = NEXT(item_gtp), 5071 .call = parse_vc, 5072 }, 5073 [ITEM_GENEVE] = { 5074 .name = "geneve", 5075 .help = "match GENEVE header", 5076 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), 5077 .next = NEXT(item_geneve), 5078 .call = parse_vc, 5079 }, 5080 [ITEM_GENEVE_VNI] = { 5081 .name = "vni", 5082 .help = "virtual network identifier", 5083 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5084 item_param), 5085 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), 5086 }, 5087 [ITEM_GENEVE_PROTO] = { 5088 .name = "protocol", 5089 .help = "GENEVE protocol type", 5090 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5091 item_param), 5092 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, 5093 protocol)), 5094 }, 5095 [ITEM_GENEVE_OPTLEN] = { 5096 .name = "optlen", 5097 .help = "GENEVE options length in dwords", 5098 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5099 item_param), 5100 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, 5101 ver_opt_len_o_c_rsvd0, 5102 "\x3f\x00")), 5103 }, 5104 [ITEM_VXLAN_GPE] = { 5105 .name = "vxlan-gpe", 5106 .help = "match VXLAN-GPE header", 5107 .priv = PRIV_ITEM(VXLAN_GPE, 5108 sizeof(struct rte_flow_item_vxlan_gpe)), 5109 .next = NEXT(item_vxlan_gpe), 5110 .call = parse_vc, 5111 }, 5112 [ITEM_VXLAN_GPE_VNI] = { 5113 .name = "vni", 5114 .help = "VXLAN-GPE identifier", 5115 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5116 item_param), 5117 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5118 hdr.vni)), 5119 }, 5120 [ITEM_VXLAN_GPE_PROTO] = { 5121 .name = "protocol", 5122 .help = "VXLAN-GPE next protocol", 5123 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5124 item_param), 5125 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5126 protocol)), 5127 }, 5128 [ITEM_VXLAN_GPE_FLAGS] = { 5129 .name = "flags", 5130 .help = "VXLAN-GPE flags", 5131 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5132 item_param), 5133 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5134 flags)), 5135 }, 5136 [ITEM_ARP_ETH_IPV4] = { 5137 .name = "arp_eth_ipv4", 5138 .help = "match ARP header for Ethernet/IPv4", 5139 .priv = PRIV_ITEM(ARP_ETH_IPV4, 5140 sizeof(struct rte_flow_item_arp_eth_ipv4)), 5141 .next = NEXT(item_arp_eth_ipv4), 5142 .call = parse_vc, 5143 }, 5144 [ITEM_ARP_ETH_IPV4_SHA] = { 5145 .name = "sha", 5146 .help = "sender hardware address", 5147 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5148 item_param), 5149 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5150 hdr.arp_data.arp_sha)), 5151 }, 5152 [ITEM_ARP_ETH_IPV4_SPA] = { 5153 .name = "spa", 5154 .help = "sender IPv4 address", 5155 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5156 item_param), 5157 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5158 hdr.arp_data.arp_sip)), 5159 }, 5160 [ITEM_ARP_ETH_IPV4_THA] = { 5161 .name = "tha", 5162 .help = "target hardware address", 5163 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5164 item_param), 5165 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5166 hdr.arp_data.arp_tha)), 5167 }, 5168 [ITEM_ARP_ETH_IPV4_TPA] = { 5169 .name = "tpa", 5170 .help = "target IPv4 address", 5171 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5172 item_param), 5173 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5174 hdr.arp_data.arp_tip)), 5175 }, 5176 [ITEM_IPV6_EXT] = { 5177 .name = "ipv6_ext", 5178 .help = "match presence of any IPv6 extension header", 5179 .priv = PRIV_ITEM(IPV6_EXT, 5180 sizeof(struct rte_flow_item_ipv6_ext)), 5181 .next = NEXT(item_ipv6_ext), 5182 .call = parse_vc, 5183 }, 5184 [ITEM_IPV6_EXT_NEXT_HDR] = { 5185 .name = "next_hdr", 5186 .help = "next header", 5187 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5188 item_param), 5189 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 5190 next_hdr)), 5191 }, 5192 [ITEM_IPV6_FRAG_EXT] = { 5193 .name = "ipv6_frag_ext", 5194 .help = "match presence of IPv6 fragment extension header", 5195 .priv = PRIV_ITEM(IPV6_FRAG_EXT, 5196 sizeof(struct rte_flow_item_ipv6_frag_ext)), 5197 .next = NEXT(item_ipv6_frag_ext), 5198 .call = parse_vc, 5199 }, 5200 [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { 5201 .name = "next_hdr", 5202 .help = "next header", 5203 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5204 item_param), 5205 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, 5206 hdr.next_header)), 5207 }, 5208 [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { 5209 .name = "frag_data", 5210 .help = "fragment flags and offset", 5211 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5212 item_param), 5213 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5214 hdr.frag_data)), 5215 }, 5216 [ITEM_IPV6_FRAG_EXT_ID] = { 5217 .name = "packet_id", 5218 .help = "fragment packet id", 5219 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5220 item_param), 5221 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5222 hdr.id)), 5223 }, 5224 [ITEM_ICMP6] = { 5225 .name = "icmp6", 5226 .help = "match any ICMPv6 header", 5227 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), 5228 .next = NEXT(item_icmp6), 5229 .call = parse_vc, 5230 }, 5231 [ITEM_ICMP6_TYPE] = { 5232 .name = "type", 5233 .help = "ICMPv6 type", 5234 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5235 item_param), 5236 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5237 type)), 5238 }, 5239 [ITEM_ICMP6_CODE] = { 5240 .name = "code", 5241 .help = "ICMPv6 code", 5242 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5243 item_param), 5244 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5245 code)), 5246 }, 5247 [ITEM_ICMP6_ECHO_REQUEST] = { 5248 .name = "icmp6_echo_request", 5249 .help = "match ICMPv6 echo request", 5250 .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, 5251 sizeof(struct rte_flow_item_icmp6_echo)), 5252 .next = NEXT(item_icmp6_echo_request), 5253 .call = parse_vc, 5254 }, 5255 [ITEM_ICMP6_ECHO_REQUEST_ID] = { 5256 .name = "ident", 5257 .help = "ICMPv6 echo request identifier", 5258 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5259 item_param), 5260 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5261 hdr.identifier)), 5262 }, 5263 [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { 5264 .name = "seq", 5265 .help = "ICMPv6 echo request sequence", 5266 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5267 item_param), 5268 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5269 hdr.sequence)), 5270 }, 5271 [ITEM_ICMP6_ECHO_REPLY] = { 5272 .name = "icmp6_echo_reply", 5273 .help = "match ICMPv6 echo reply", 5274 .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, 5275 sizeof(struct rte_flow_item_icmp6_echo)), 5276 .next = NEXT(item_icmp6_echo_reply), 5277 .call = parse_vc, 5278 }, 5279 [ITEM_ICMP6_ECHO_REPLY_ID] = { 5280 .name = "ident", 5281 .help = "ICMPv6 echo reply identifier", 5282 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5283 item_param), 5284 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5285 hdr.identifier)), 5286 }, 5287 [ITEM_ICMP6_ECHO_REPLY_SEQ] = { 5288 .name = "seq", 5289 .help = "ICMPv6 echo reply sequence", 5290 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5291 item_param), 5292 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5293 hdr.sequence)), 5294 }, 5295 [ITEM_ICMP6_ND_NS] = { 5296 .name = "icmp6_nd_ns", 5297 .help = "match ICMPv6 neighbor discovery solicitation", 5298 .priv = PRIV_ITEM(ICMP6_ND_NS, 5299 sizeof(struct rte_flow_item_icmp6_nd_ns)), 5300 .next = NEXT(item_icmp6_nd_ns), 5301 .call = parse_vc, 5302 }, 5303 [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { 5304 .name = "target_addr", 5305 .help = "target address", 5306 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), 5307 item_param), 5308 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, 5309 target_addr)), 5310 }, 5311 [ITEM_ICMP6_ND_NA] = { 5312 .name = "icmp6_nd_na", 5313 .help = "match ICMPv6 neighbor discovery advertisement", 5314 .priv = PRIV_ITEM(ICMP6_ND_NA, 5315 sizeof(struct rte_flow_item_icmp6_nd_na)), 5316 .next = NEXT(item_icmp6_nd_na), 5317 .call = parse_vc, 5318 }, 5319 [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { 5320 .name = "target_addr", 5321 .help = "target address", 5322 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), 5323 item_param), 5324 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, 5325 target_addr)), 5326 }, 5327 [ITEM_ICMP6_ND_OPT] = { 5328 .name = "icmp6_nd_opt", 5329 .help = "match presence of any ICMPv6 neighbor discovery" 5330 " option", 5331 .priv = PRIV_ITEM(ICMP6_ND_OPT, 5332 sizeof(struct rte_flow_item_icmp6_nd_opt)), 5333 .next = NEXT(item_icmp6_nd_opt), 5334 .call = parse_vc, 5335 }, 5336 [ITEM_ICMP6_ND_OPT_TYPE] = { 5337 .name = "type", 5338 .help = "ND option type", 5339 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5340 item_param), 5341 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, 5342 type)), 5343 }, 5344 [ITEM_ICMP6_ND_OPT_SLA_ETH] = { 5345 .name = "icmp6_nd_opt_sla_eth", 5346 .help = "match ICMPv6 neighbor discovery source Ethernet" 5347 " link-layer address option", 5348 .priv = PRIV_ITEM 5349 (ICMP6_ND_OPT_SLA_ETH, 5350 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), 5351 .next = NEXT(item_icmp6_nd_opt_sla_eth), 5352 .call = parse_vc, 5353 }, 5354 [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { 5355 .name = "sla", 5356 .help = "source Ethernet LLA", 5357 .next = NEXT(item_icmp6_nd_opt_sla_eth, 5358 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5359 .args = ARGS(ARGS_ENTRY_HTON 5360 (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), 5361 }, 5362 [ITEM_ICMP6_ND_OPT_TLA_ETH] = { 5363 .name = "icmp6_nd_opt_tla_eth", 5364 .help = "match ICMPv6 neighbor discovery target Ethernet" 5365 " link-layer address option", 5366 .priv = PRIV_ITEM 5367 (ICMP6_ND_OPT_TLA_ETH, 5368 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), 5369 .next = NEXT(item_icmp6_nd_opt_tla_eth), 5370 .call = parse_vc, 5371 }, 5372 [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { 5373 .name = "tla", 5374 .help = "target Ethernet LLA", 5375 .next = NEXT(item_icmp6_nd_opt_tla_eth, 5376 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5377 .args = ARGS(ARGS_ENTRY_HTON 5378 (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), 5379 }, 5380 [ITEM_META] = { 5381 .name = "meta", 5382 .help = "match metadata header", 5383 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), 5384 .next = NEXT(item_meta), 5385 .call = parse_vc, 5386 }, 5387 [ITEM_META_DATA] = { 5388 .name = "data", 5389 .help = "metadata value", 5390 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), 5391 item_param), 5392 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, 5393 data, "\xff\xff\xff\xff")), 5394 }, 5395 [ITEM_RANDOM] = { 5396 .name = "random", 5397 .help = "match random value", 5398 .priv = PRIV_ITEM(RANDOM, sizeof(struct rte_flow_item_random)), 5399 .next = NEXT(item_random), 5400 .call = parse_vc, 5401 }, 5402 [ITEM_RANDOM_VALUE] = { 5403 .name = "value", 5404 .help = "random value", 5405 .next = NEXT(item_random, NEXT_ENTRY(COMMON_UNSIGNED), 5406 item_param), 5407 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_random, 5408 value, "\xff\xff")), 5409 }, 5410 [ITEM_GRE_KEY] = { 5411 .name = "gre_key", 5412 .help = "match GRE key", 5413 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), 5414 .next = NEXT(item_gre_key), 5415 .call = parse_vc, 5416 }, 5417 [ITEM_GRE_KEY_VALUE] = { 5418 .name = "value", 5419 .help = "key value", 5420 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), 5421 item_param), 5422 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5423 }, 5424 [ITEM_GRE_OPTION] = { 5425 .name = "gre_option", 5426 .help = "match GRE optional fields", 5427 .priv = PRIV_ITEM(GRE_OPTION, 5428 sizeof(struct rte_flow_item_gre_opt)), 5429 .next = NEXT(item_gre_option), 5430 .call = parse_vc, 5431 }, 5432 [ITEM_GRE_OPTION_CHECKSUM] = { 5433 .name = "checksum", 5434 .help = "match GRE checksum", 5435 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5436 item_param), 5437 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5438 checksum_rsvd.checksum)), 5439 }, 5440 [ITEM_GRE_OPTION_KEY] = { 5441 .name = "key", 5442 .help = "match GRE key", 5443 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5444 item_param), 5445 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5446 key.key)), 5447 }, 5448 [ITEM_GRE_OPTION_SEQUENCE] = { 5449 .name = "sequence", 5450 .help = "match GRE sequence", 5451 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5452 item_param), 5453 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5454 sequence.sequence)), 5455 }, 5456 [ITEM_GTP_PSC] = { 5457 .name = "gtp_psc", 5458 .help = "match GTP extension header with type 0x85", 5459 .priv = PRIV_ITEM(GTP_PSC, 5460 sizeof(struct rte_flow_item_gtp_psc)), 5461 .next = NEXT(item_gtp_psc), 5462 .call = parse_vc, 5463 }, 5464 [ITEM_GTP_PSC_QFI] = { 5465 .name = "qfi", 5466 .help = "QoS flow identifier", 5467 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5468 item_param), 5469 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5470 hdr.qfi, 6)), 5471 }, 5472 [ITEM_GTP_PSC_PDU_T] = { 5473 .name = "pdu_t", 5474 .help = "PDU type", 5475 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5476 item_param), 5477 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5478 hdr.type, 4)), 5479 }, 5480 [ITEM_PPPOES] = { 5481 .name = "pppoes", 5482 .help = "match PPPoE session header", 5483 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), 5484 .next = NEXT(item_pppoes), 5485 .call = parse_vc, 5486 }, 5487 [ITEM_PPPOED] = { 5488 .name = "pppoed", 5489 .help = "match PPPoE discovery header", 5490 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), 5491 .next = NEXT(item_pppoed), 5492 .call = parse_vc, 5493 }, 5494 [ITEM_PPPOE_SEID] = { 5495 .name = "seid", 5496 .help = "session identifier", 5497 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), 5498 item_param), 5499 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, 5500 session_id)), 5501 }, 5502 [ITEM_PPPOE_PROTO_ID] = { 5503 .name = "pppoe_proto_id", 5504 .help = "match PPPoE session protocol identifier", 5505 .priv = PRIV_ITEM(PPPOE_PROTO_ID, 5506 sizeof(struct rte_flow_item_pppoe_proto_id)), 5507 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED), 5508 item_param), 5509 .args = ARGS(ARGS_ENTRY_HTON 5510 (struct rte_flow_item_pppoe_proto_id, proto_id)), 5511 .call = parse_vc, 5512 }, 5513 [ITEM_HIGIG2] = { 5514 .name = "higig2", 5515 .help = "matches higig2 header", 5516 .priv = PRIV_ITEM(HIGIG2, 5517 sizeof(struct rte_flow_item_higig2_hdr)), 5518 .next = NEXT(item_higig2), 5519 .call = parse_vc, 5520 }, 5521 [ITEM_HIGIG2_CLASSIFICATION] = { 5522 .name = "classification", 5523 .help = "matches classification of higig2 header", 5524 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5525 item_param), 5526 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5527 hdr.ppt1.classification)), 5528 }, 5529 [ITEM_HIGIG2_VID] = { 5530 .name = "vid", 5531 .help = "matches vid of higig2 header", 5532 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5533 item_param), 5534 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5535 hdr.ppt1.vid)), 5536 }, 5537 [ITEM_TAG] = { 5538 .name = "tag", 5539 .help = "match tag value", 5540 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), 5541 .next = NEXT(item_tag), 5542 .call = parse_vc, 5543 }, 5544 [ITEM_TAG_DATA] = { 5545 .name = "data", 5546 .help = "tag value to match", 5547 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5548 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), 5549 }, 5550 [ITEM_TAG_INDEX] = { 5551 .name = "index", 5552 .help = "index of tag array to match", 5553 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5554 NEXT_ENTRY(ITEM_PARAM_IS)), 5555 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), 5556 }, 5557 [ITEM_L2TPV3OIP] = { 5558 .name = "l2tpv3oip", 5559 .help = "match L2TPv3 over IP header", 5560 .priv = PRIV_ITEM(L2TPV3OIP, 5561 sizeof(struct rte_flow_item_l2tpv3oip)), 5562 .next = NEXT(item_l2tpv3oip), 5563 .call = parse_vc, 5564 }, 5565 [ITEM_L2TPV3OIP_SESSION_ID] = { 5566 .name = "session_id", 5567 .help = "session identifier", 5568 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), 5569 item_param), 5570 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, 5571 session_id)), 5572 }, 5573 [ITEM_ESP] = { 5574 .name = "esp", 5575 .help = "match ESP header", 5576 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), 5577 .next = NEXT(item_esp), 5578 .call = parse_vc, 5579 }, 5580 [ITEM_ESP_SPI] = { 5581 .name = "spi", 5582 .help = "security policy index", 5583 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5584 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, 5585 hdr.spi)), 5586 }, 5587 [ITEM_AH] = { 5588 .name = "ah", 5589 .help = "match AH header", 5590 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), 5591 .next = NEXT(item_ah), 5592 .call = parse_vc, 5593 }, 5594 [ITEM_AH_SPI] = { 5595 .name = "spi", 5596 .help = "security parameters index", 5597 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5598 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), 5599 }, 5600 [ITEM_PFCP] = { 5601 .name = "pfcp", 5602 .help = "match pfcp header", 5603 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), 5604 .next = NEXT(item_pfcp), 5605 .call = parse_vc, 5606 }, 5607 [ITEM_PFCP_S_FIELD] = { 5608 .name = "s_field", 5609 .help = "S field", 5610 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5611 item_param), 5612 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, 5613 s_field)), 5614 }, 5615 [ITEM_PFCP_SEID] = { 5616 .name = "seid", 5617 .help = "session endpoint identifier", 5618 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5619 item_param), 5620 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), 5621 }, 5622 [ITEM_ECPRI] = { 5623 .name = "ecpri", 5624 .help = "match eCPRI header", 5625 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), 5626 .next = NEXT(item_ecpri), 5627 .call = parse_vc, 5628 }, 5629 [ITEM_ECPRI_COMMON] = { 5630 .name = "common", 5631 .help = "eCPRI common header", 5632 .next = NEXT(item_ecpri_common), 5633 }, 5634 [ITEM_ECPRI_COMMON_TYPE] = { 5635 .name = "type", 5636 .help = "type of common header", 5637 .next = NEXT(item_ecpri_common_type), 5638 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), 5639 }, 5640 [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { 5641 .name = "iq_data", 5642 .help = "Type #0: IQ Data", 5643 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5644 ITEM_NEXT)), 5645 .call = parse_vc_item_ecpri_type, 5646 }, 5647 [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { 5648 .name = "pc_id", 5649 .help = "Physical Channel ID", 5650 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5651 ITEM_ECPRI_COMMON, ITEM_NEXT), 5652 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5653 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5654 hdr.type0.pc_id)), 5655 }, 5656 [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { 5657 .name = "rtc_ctrl", 5658 .help = "Type #2: Real-Time Control Data", 5659 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5660 ITEM_NEXT)), 5661 .call = parse_vc_item_ecpri_type, 5662 }, 5663 [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { 5664 .name = "rtc_id", 5665 .help = "Real-Time Control Data ID", 5666 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5667 ITEM_ECPRI_COMMON, ITEM_NEXT), 5668 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5669 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5670 hdr.type2.rtc_id)), 5671 }, 5672 [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { 5673 .name = "delay_measure", 5674 .help = "Type #5: One-Way Delay Measurement", 5675 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5676 ITEM_NEXT)), 5677 .call = parse_vc_item_ecpri_type, 5678 }, 5679 [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { 5680 .name = "msr_id", 5681 .help = "Measurement ID", 5682 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5683 ITEM_ECPRI_COMMON, ITEM_NEXT), 5684 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5685 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5686 hdr.type5.msr_id)), 5687 }, 5688 [ITEM_GENEVE_OPT] = { 5689 .name = "geneve-opt", 5690 .help = "GENEVE header option", 5691 .priv = PRIV_ITEM(GENEVE_OPT, 5692 sizeof(struct rte_flow_item_geneve_opt) + 5693 ITEM_GENEVE_OPT_DATA_SIZE), 5694 .next = NEXT(item_geneve_opt), 5695 .call = parse_vc, 5696 }, 5697 [ITEM_GENEVE_OPT_CLASS] = { 5698 .name = "class", 5699 .help = "GENEVE option class", 5700 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5701 item_param), 5702 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, 5703 option_class)), 5704 }, 5705 [ITEM_GENEVE_OPT_TYPE] = { 5706 .name = "type", 5707 .help = "GENEVE option type", 5708 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5709 item_param), 5710 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, 5711 option_type)), 5712 }, 5713 [ITEM_GENEVE_OPT_LENGTH] = { 5714 .name = "length", 5715 .help = "GENEVE option data length (in 32b words)", 5716 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5717 item_param), 5718 .args = ARGS(ARGS_ENTRY_BOUNDED( 5719 struct rte_flow_item_geneve_opt, option_len, 5720 0, 31)), 5721 }, 5722 [ITEM_GENEVE_OPT_DATA] = { 5723 .name = "data", 5724 .help = "GENEVE option data pattern", 5725 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), 5726 item_param), 5727 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), 5728 ARGS_ENTRY_ARB(0, 0), 5729 ARGS_ENTRY_ARB 5730 (sizeof(struct rte_flow_item_geneve_opt), 5731 ITEM_GENEVE_OPT_DATA_SIZE)), 5732 }, 5733 [ITEM_INTEGRITY] = { 5734 .name = "integrity", 5735 .help = "match packet integrity", 5736 .priv = PRIV_ITEM(INTEGRITY, 5737 sizeof(struct rte_flow_item_integrity)), 5738 .next = NEXT(item_integrity), 5739 .call = parse_vc, 5740 }, 5741 [ITEM_INTEGRITY_LEVEL] = { 5742 .name = "level", 5743 .help = "integrity level", 5744 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5745 item_param), 5746 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), 5747 }, 5748 [ITEM_INTEGRITY_VALUE] = { 5749 .name = "value", 5750 .help = "integrity value", 5751 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5752 item_param), 5753 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), 5754 }, 5755 [ITEM_CONNTRACK] = { 5756 .name = "conntrack", 5757 .help = "conntrack state", 5758 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 5759 item_param), 5760 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 5761 }, 5762 [ITEM_PORT_REPRESENTOR] = { 5763 .name = "port_representor", 5764 .help = "match traffic entering the embedded switch from the given ethdev", 5765 .priv = PRIV_ITEM(PORT_REPRESENTOR, 5766 sizeof(struct rte_flow_item_ethdev)), 5767 .next = NEXT(item_port_representor), 5768 .call = parse_vc, 5769 }, 5770 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 5771 .name = "port_id", 5772 .help = "ethdev port ID", 5773 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 5774 item_param), 5775 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5776 }, 5777 [ITEM_REPRESENTED_PORT] = { 5778 .name = "represented_port", 5779 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 5780 .priv = PRIV_ITEM(REPRESENTED_PORT, 5781 sizeof(struct rte_flow_item_ethdev)), 5782 .next = NEXT(item_represented_port), 5783 .call = parse_vc, 5784 }, 5785 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 5786 .name = "ethdev_port_id", 5787 .help = "ethdev port ID", 5788 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 5789 item_param), 5790 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5791 }, 5792 [ITEM_FLEX] = { 5793 .name = "flex", 5794 .help = "match flex header", 5795 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 5796 .next = NEXT(item_flex), 5797 .call = parse_vc, 5798 }, 5799 [ITEM_FLEX_ITEM_HANDLE] = { 5800 .name = "item", 5801 .help = "flex item handle", 5802 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5803 NEXT_ENTRY(ITEM_PARAM_IS)), 5804 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 5805 }, 5806 [ITEM_FLEX_PATTERN_HANDLE] = { 5807 .name = "pattern", 5808 .help = "flex pattern handle", 5809 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5810 NEXT_ENTRY(ITEM_PARAM_IS)), 5811 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 5812 }, 5813 [ITEM_L2TPV2] = { 5814 .name = "l2tpv2", 5815 .help = "match L2TPv2 header", 5816 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 5817 .next = NEXT(item_l2tpv2), 5818 .call = parse_vc, 5819 }, 5820 [ITEM_L2TPV2_TYPE] = { 5821 .name = "type", 5822 .help = "type of l2tpv2", 5823 .next = NEXT(item_l2tpv2_type), 5824 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 5825 }, 5826 [ITEM_L2TPV2_TYPE_DATA] = { 5827 .name = "data", 5828 .help = "Type #7: data message without any options", 5829 .next = NEXT(item_l2tpv2_type_data), 5830 .call = parse_vc_item_l2tpv2_type, 5831 }, 5832 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 5833 .name = "tunnel_id", 5834 .help = "tunnel identifier", 5835 .next = NEXT(item_l2tpv2_type_data, 5836 NEXT_ENTRY(COMMON_UNSIGNED), 5837 item_param), 5838 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5839 hdr.type7.tunnel_id)), 5840 }, 5841 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 5842 .name = "session_id", 5843 .help = "session identifier", 5844 .next = NEXT(item_l2tpv2_type_data, 5845 NEXT_ENTRY(COMMON_UNSIGNED), 5846 item_param), 5847 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5848 hdr.type7.session_id)), 5849 }, 5850 [ITEM_L2TPV2_TYPE_DATA_L] = { 5851 .name = "data_l", 5852 .help = "Type #6: data message with length option", 5853 .next = NEXT(item_l2tpv2_type_data_l), 5854 .call = parse_vc_item_l2tpv2_type, 5855 }, 5856 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 5857 .name = "length", 5858 .help = "message length", 5859 .next = NEXT(item_l2tpv2_type_data_l, 5860 NEXT_ENTRY(COMMON_UNSIGNED), 5861 item_param), 5862 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5863 hdr.type6.length)), 5864 }, 5865 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 5866 .name = "tunnel_id", 5867 .help = "tunnel identifier", 5868 .next = NEXT(item_l2tpv2_type_data_l, 5869 NEXT_ENTRY(COMMON_UNSIGNED), 5870 item_param), 5871 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5872 hdr.type6.tunnel_id)), 5873 }, 5874 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 5875 .name = "session_id", 5876 .help = "session identifier", 5877 .next = NEXT(item_l2tpv2_type_data_l, 5878 NEXT_ENTRY(COMMON_UNSIGNED), 5879 item_param), 5880 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5881 hdr.type6.session_id)), 5882 }, 5883 [ITEM_L2TPV2_TYPE_DATA_S] = { 5884 .name = "data_s", 5885 .help = "Type #5: data message with ns, nr option", 5886 .next = NEXT(item_l2tpv2_type_data_s), 5887 .call = parse_vc_item_l2tpv2_type, 5888 }, 5889 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 5890 .name = "tunnel_id", 5891 .help = "tunnel identifier", 5892 .next = NEXT(item_l2tpv2_type_data_s, 5893 NEXT_ENTRY(COMMON_UNSIGNED), 5894 item_param), 5895 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5896 hdr.type5.tunnel_id)), 5897 }, 5898 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 5899 .name = "session_id", 5900 .help = "session identifier", 5901 .next = NEXT(item_l2tpv2_type_data_s, 5902 NEXT_ENTRY(COMMON_UNSIGNED), 5903 item_param), 5904 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5905 hdr.type5.session_id)), 5906 }, 5907 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 5908 .name = "ns", 5909 .help = "sequence number for message", 5910 .next = NEXT(item_l2tpv2_type_data_s, 5911 NEXT_ENTRY(COMMON_UNSIGNED), 5912 item_param), 5913 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5914 hdr.type5.ns)), 5915 }, 5916 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 5917 .name = "nr", 5918 .help = "sequence number for next receive message", 5919 .next = NEXT(item_l2tpv2_type_data_s, 5920 NEXT_ENTRY(COMMON_UNSIGNED), 5921 item_param), 5922 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5923 hdr.type5.nr)), 5924 }, 5925 [ITEM_L2TPV2_TYPE_DATA_O] = { 5926 .name = "data_o", 5927 .help = "Type #4: data message with offset option", 5928 .next = NEXT(item_l2tpv2_type_data_o), 5929 .call = parse_vc_item_l2tpv2_type, 5930 }, 5931 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 5932 .name = "tunnel_id", 5933 .help = "tunnel identifier", 5934 .next = NEXT(item_l2tpv2_type_data_o, 5935 NEXT_ENTRY(COMMON_UNSIGNED), 5936 item_param), 5937 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5938 hdr.type4.tunnel_id)), 5939 }, 5940 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 5941 .name = "session_id", 5942 .help = "session identifier", 5943 .next = NEXT(item_l2tpv2_type_data_o, 5944 NEXT_ENTRY(COMMON_UNSIGNED), 5945 item_param), 5946 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5947 hdr.type5.session_id)), 5948 }, 5949 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 5950 .name = "offset_size", 5951 .help = "the size of offset padding", 5952 .next = NEXT(item_l2tpv2_type_data_o, 5953 NEXT_ENTRY(COMMON_UNSIGNED), 5954 item_param), 5955 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5956 hdr.type4.offset_size)), 5957 }, 5958 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 5959 .name = "data_l_s", 5960 .help = "Type #3: data message contains length, ns, nr " 5961 "options", 5962 .next = NEXT(item_l2tpv2_type_data_l_s), 5963 .call = parse_vc_item_l2tpv2_type, 5964 }, 5965 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 5966 .name = "length", 5967 .help = "message length", 5968 .next = NEXT(item_l2tpv2_type_data_l_s, 5969 NEXT_ENTRY(COMMON_UNSIGNED), 5970 item_param), 5971 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5972 hdr.type3.length)), 5973 }, 5974 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 5975 .name = "tunnel_id", 5976 .help = "tunnel identifier", 5977 .next = NEXT(item_l2tpv2_type_data_l_s, 5978 NEXT_ENTRY(COMMON_UNSIGNED), 5979 item_param), 5980 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5981 hdr.type3.tunnel_id)), 5982 }, 5983 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 5984 .name = "session_id", 5985 .help = "session identifier", 5986 .next = NEXT(item_l2tpv2_type_data_l_s, 5987 NEXT_ENTRY(COMMON_UNSIGNED), 5988 item_param), 5989 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5990 hdr.type3.session_id)), 5991 }, 5992 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 5993 .name = "ns", 5994 .help = "sequence number for message", 5995 .next = NEXT(item_l2tpv2_type_data_l_s, 5996 NEXT_ENTRY(COMMON_UNSIGNED), 5997 item_param), 5998 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5999 hdr.type3.ns)), 6000 }, 6001 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 6002 .name = "nr", 6003 .help = "sequence number for next receive message", 6004 .next = NEXT(item_l2tpv2_type_data_l_s, 6005 NEXT_ENTRY(COMMON_UNSIGNED), 6006 item_param), 6007 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6008 hdr.type3.nr)), 6009 }, 6010 [ITEM_L2TPV2_TYPE_CTRL] = { 6011 .name = "control", 6012 .help = "Type #3: conrtol message contains length, ns, nr " 6013 "options", 6014 .next = NEXT(item_l2tpv2_type_ctrl), 6015 .call = parse_vc_item_l2tpv2_type, 6016 }, 6017 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 6018 .name = "length", 6019 .help = "message length", 6020 .next = NEXT(item_l2tpv2_type_ctrl, 6021 NEXT_ENTRY(COMMON_UNSIGNED), 6022 item_param), 6023 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6024 hdr.type3.length)), 6025 }, 6026 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 6027 .name = "tunnel_id", 6028 .help = "tunnel identifier", 6029 .next = NEXT(item_l2tpv2_type_ctrl, 6030 NEXT_ENTRY(COMMON_UNSIGNED), 6031 item_param), 6032 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6033 hdr.type3.tunnel_id)), 6034 }, 6035 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 6036 .name = "session_id", 6037 .help = "session identifier", 6038 .next = NEXT(item_l2tpv2_type_ctrl, 6039 NEXT_ENTRY(COMMON_UNSIGNED), 6040 item_param), 6041 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6042 hdr.type3.session_id)), 6043 }, 6044 [ITEM_L2TPV2_MSG_CTRL_NS] = { 6045 .name = "ns", 6046 .help = "sequence number for message", 6047 .next = NEXT(item_l2tpv2_type_ctrl, 6048 NEXT_ENTRY(COMMON_UNSIGNED), 6049 item_param), 6050 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6051 hdr.type3.ns)), 6052 }, 6053 [ITEM_L2TPV2_MSG_CTRL_NR] = { 6054 .name = "nr", 6055 .help = "sequence number for next receive message", 6056 .next = NEXT(item_l2tpv2_type_ctrl, 6057 NEXT_ENTRY(COMMON_UNSIGNED), 6058 item_param), 6059 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6060 hdr.type3.nr)), 6061 }, 6062 [ITEM_PPP] = { 6063 .name = "ppp", 6064 .help = "match PPP header", 6065 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 6066 .next = NEXT(item_ppp), 6067 .call = parse_vc, 6068 }, 6069 [ITEM_PPP_ADDR] = { 6070 .name = "addr", 6071 .help = "PPP address", 6072 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6073 item_param), 6074 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 6075 }, 6076 [ITEM_PPP_CTRL] = { 6077 .name = "ctrl", 6078 .help = "PPP control", 6079 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6080 item_param), 6081 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 6082 }, 6083 [ITEM_PPP_PROTO_ID] = { 6084 .name = "proto_id", 6085 .help = "PPP protocol identifier", 6086 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6087 item_param), 6088 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 6089 hdr.proto_id)), 6090 }, 6091 [ITEM_METER] = { 6092 .name = "meter", 6093 .help = "match meter color", 6094 .priv = PRIV_ITEM(METER_COLOR, 6095 sizeof(struct rte_flow_item_meter_color)), 6096 .next = NEXT(item_meter), 6097 .call = parse_vc, 6098 }, 6099 [ITEM_METER_COLOR] = { 6100 .name = "color", 6101 .help = "meter color", 6102 .next = NEXT(item_meter, 6103 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 6104 item_param), 6105 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 6106 color)), 6107 }, 6108 [ITEM_METER_COLOR_NAME] = { 6109 .name = "color_name", 6110 .help = "meter color name", 6111 .call = parse_meter_color, 6112 .comp = comp_meter_color, 6113 }, 6114 [ITEM_QUOTA] = { 6115 .name = "quota", 6116 .help = "match quota", 6117 .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), 6118 .next = NEXT(item_quota), 6119 .call = parse_vc 6120 }, 6121 [ITEM_QUOTA_STATE] = { 6122 .name = "quota_state", 6123 .help = "quota state", 6124 .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), 6125 NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), 6126 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) 6127 }, 6128 [ITEM_QUOTA_STATE_NAME] = { 6129 .name = "state_name", 6130 .help = "quota state name", 6131 .call = parse_quota_state_name, 6132 .comp = comp_quota_state_name 6133 }, 6134 [ITEM_IB_BTH] = { 6135 .name = "ib_bth", 6136 .help = "match ib bth fields", 6137 .priv = PRIV_ITEM(IB_BTH, 6138 sizeof(struct rte_flow_item_ib_bth)), 6139 .next = NEXT(item_ib_bth), 6140 .call = parse_vc, 6141 }, 6142 [ITEM_IB_BTH_OPCODE] = { 6143 .name = "opcode", 6144 .help = "match ib bth opcode", 6145 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6146 item_param), 6147 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6148 hdr.opcode)), 6149 }, 6150 [ITEM_IB_BTH_PKEY] = { 6151 .name = "pkey", 6152 .help = "partition key", 6153 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6154 item_param), 6155 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6156 hdr.pkey)), 6157 }, 6158 [ITEM_IB_BTH_DST_QPN] = { 6159 .name = "dst_qp", 6160 .help = "destination qp", 6161 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6162 item_param), 6163 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6164 hdr.dst_qp)), 6165 }, 6166 [ITEM_IB_BTH_PSN] = { 6167 .name = "psn", 6168 .help = "packet sequence number", 6169 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6170 item_param), 6171 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6172 hdr.psn)), 6173 }, 6174 [ITEM_PTYPE] = { 6175 .name = "ptype", 6176 .help = "match L2/L3/L4 and tunnel information", 6177 .priv = PRIV_ITEM(PTYPE, 6178 sizeof(struct rte_flow_item_ptype)), 6179 .next = NEXT(item_ptype), 6180 .call = parse_vc, 6181 }, 6182 [ITEM_PTYPE_VALUE] = { 6183 .name = "packet_type", 6184 .help = "packet type as defined in rte_mbuf_ptype", 6185 .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), 6186 item_param), 6187 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), 6188 }, 6189 [ITEM_NSH] = { 6190 .name = "nsh", 6191 .help = "match NSH header", 6192 .priv = PRIV_ITEM(NSH, 6193 sizeof(struct rte_flow_item_nsh)), 6194 .next = NEXT(item_nsh), 6195 .call = parse_vc, 6196 }, 6197 [ITEM_COMPARE] = { 6198 .name = "compare", 6199 .help = "match with the comparison result", 6200 .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)), 6201 .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)), 6202 .call = parse_vc, 6203 }, 6204 [ITEM_COMPARE_OP] = { 6205 .name = "op", 6206 .help = "operation type", 6207 .next = NEXT(item_compare_field, 6208 NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param), 6209 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)), 6210 }, 6211 [ITEM_COMPARE_OP_VALUE] = { 6212 .name = "{operation}", 6213 .help = "operation type value", 6214 .call = parse_vc_compare_op, 6215 .comp = comp_set_compare_op, 6216 }, 6217 [ITEM_COMPARE_FIELD_A_TYPE] = { 6218 .name = "a_type", 6219 .help = "compared field type", 6220 .next = NEXT(compare_field_a, 6221 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param), 6222 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)), 6223 }, 6224 [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = { 6225 .name = "{a_type}", 6226 .help = "compared field type value", 6227 .call = parse_vc_compare_field_id, 6228 .comp = comp_set_compare_field_id, 6229 }, 6230 [ITEM_COMPARE_FIELD_A_LEVEL] = { 6231 .name = "a_level", 6232 .help = "compared field level", 6233 .next = NEXT(compare_field_a, 6234 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param), 6235 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)), 6236 }, 6237 [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = { 6238 .name = "{a_level}", 6239 .help = "compared field level value", 6240 .call = parse_vc_compare_field_level, 6241 .comp = comp_none, 6242 }, 6243 [ITEM_COMPARE_FIELD_A_TAG_INDEX] = { 6244 .name = "a_tag_index", 6245 .help = "compared field tag array", 6246 .next = NEXT(compare_field_a, 6247 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6248 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6249 a.tag_index)), 6250 }, 6251 [ITEM_COMPARE_FIELD_A_TYPE_ID] = { 6252 .name = "a_type_id", 6253 .help = "compared field type ID", 6254 .next = NEXT(compare_field_a, 6255 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6256 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6257 a.type)), 6258 }, 6259 [ITEM_COMPARE_FIELD_A_CLASS_ID] = { 6260 .name = "a_class", 6261 .help = "compared field class ID", 6262 .next = NEXT(compare_field_a, 6263 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6264 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6265 a.class_id)), 6266 }, 6267 [ITEM_COMPARE_FIELD_A_OFFSET] = { 6268 .name = "a_offset", 6269 .help = "compared field bit offset", 6270 .next = NEXT(compare_field_a, 6271 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6272 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6273 a.offset)), 6274 }, 6275 [ITEM_COMPARE_FIELD_B_TYPE] = { 6276 .name = "b_type", 6277 .help = "comparator field type", 6278 .next = NEXT(compare_field_b, 6279 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param), 6280 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6281 b.field)), 6282 }, 6283 [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = { 6284 .name = "{b_type}", 6285 .help = "comparator field type value", 6286 .call = parse_vc_compare_field_id, 6287 .comp = comp_set_compare_field_id, 6288 }, 6289 [ITEM_COMPARE_FIELD_B_LEVEL] = { 6290 .name = "b_level", 6291 .help = "comparator field level", 6292 .next = NEXT(compare_field_b, 6293 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param), 6294 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6295 b.level)), 6296 }, 6297 [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = { 6298 .name = "{b_level}", 6299 .help = "comparator field level value", 6300 .call = parse_vc_compare_field_level, 6301 .comp = comp_none, 6302 }, 6303 [ITEM_COMPARE_FIELD_B_TAG_INDEX] = { 6304 .name = "b_tag_index", 6305 .help = "comparator field tag array", 6306 .next = NEXT(compare_field_b, 6307 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6308 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6309 b.tag_index)), 6310 }, 6311 [ITEM_COMPARE_FIELD_B_TYPE_ID] = { 6312 .name = "b_type_id", 6313 .help = "comparator field type ID", 6314 .next = NEXT(compare_field_b, 6315 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6316 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6317 b.type)), 6318 }, 6319 [ITEM_COMPARE_FIELD_B_CLASS_ID] = { 6320 .name = "b_class", 6321 .help = "comparator field class ID", 6322 .next = NEXT(compare_field_b, 6323 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6324 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6325 b.class_id)), 6326 }, 6327 [ITEM_COMPARE_FIELD_B_OFFSET] = { 6328 .name = "b_offset", 6329 .help = "comparator field bit offset", 6330 .next = NEXT(compare_field_b, 6331 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6332 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6333 b.offset)), 6334 }, 6335 [ITEM_COMPARE_FIELD_B_VALUE] = { 6336 .name = "b_value", 6337 .help = "comparator immediate value", 6338 .next = NEXT(compare_field_b, 6339 NEXT_ENTRY(COMMON_HEX), item_param), 6340 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6341 ARGS_ENTRY_ARB(0, 0), 6342 ARGS_ENTRY(struct rte_flow_item_compare, 6343 b.value)), 6344 }, 6345 [ITEM_COMPARE_FIELD_B_POINTER] = { 6346 .name = "b_ptr", 6347 .help = "pointer to comparator immediate value", 6348 .next = NEXT(compare_field_b, 6349 NEXT_ENTRY(COMMON_HEX), item_param), 6350 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6351 b.pvalue), 6352 ARGS_ENTRY_ARB(0, 0), 6353 ARGS_ENTRY_ARB 6354 (sizeof(struct rte_flow_item_compare), 6355 FLOW_FIELD_PATTERN_SIZE)), 6356 }, 6357 [ITEM_COMPARE_FIELD_WIDTH] = { 6358 .name = "width", 6359 .help = "number of bits to compare", 6360 .next = NEXT(item_compare_field, 6361 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6362 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6363 width)), 6364 }, 6365 6366 /* Validate/create actions. */ 6367 [ACTIONS] = { 6368 .name = "actions", 6369 .help = "submit a list of associated actions", 6370 .next = NEXT(next_action), 6371 .call = parse_vc, 6372 }, 6373 [ACTION_NEXT] = { 6374 .name = "/", 6375 .help = "specify next action", 6376 .next = NEXT(next_action), 6377 }, 6378 [ACTION_END] = { 6379 .name = "end", 6380 .help = "end list of actions", 6381 .priv = PRIV_ACTION(END, 0), 6382 .call = parse_vc, 6383 }, 6384 [ACTION_VOID] = { 6385 .name = "void", 6386 .help = "no-op action", 6387 .priv = PRIV_ACTION(VOID, 0), 6388 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6389 .call = parse_vc, 6390 }, 6391 [ACTION_PASSTHRU] = { 6392 .name = "passthru", 6393 .help = "let subsequent rule process matched packets", 6394 .priv = PRIV_ACTION(PASSTHRU, 0), 6395 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6396 .call = parse_vc, 6397 }, 6398 [ACTION_SKIP_CMAN] = { 6399 .name = "skip_cman", 6400 .help = "bypass cman on received packets", 6401 .priv = PRIV_ACTION(SKIP_CMAN, 0), 6402 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6403 .call = parse_vc, 6404 }, 6405 [ACTION_JUMP] = { 6406 .name = "jump", 6407 .help = "redirect traffic to a given group", 6408 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 6409 .next = NEXT(action_jump), 6410 .call = parse_vc, 6411 }, 6412 [ACTION_JUMP_GROUP] = { 6413 .name = "group", 6414 .help = "group to redirect traffic to", 6415 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 6416 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 6417 .call = parse_vc_conf, 6418 }, 6419 [ACTION_MARK] = { 6420 .name = "mark", 6421 .help = "attach 32 bit value to packets", 6422 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 6423 .next = NEXT(action_mark), 6424 .call = parse_vc, 6425 }, 6426 [ACTION_MARK_ID] = { 6427 .name = "id", 6428 .help = "32 bit value to return with packets", 6429 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6430 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 6431 .call = parse_vc_conf, 6432 }, 6433 [ACTION_FLAG] = { 6434 .name = "flag", 6435 .help = "flag packets", 6436 .priv = PRIV_ACTION(FLAG, 0), 6437 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6438 .call = parse_vc, 6439 }, 6440 [ACTION_QUEUE] = { 6441 .name = "queue", 6442 .help = "assign packets to a given queue index", 6443 .priv = PRIV_ACTION(QUEUE, 6444 sizeof(struct rte_flow_action_queue)), 6445 .next = NEXT(action_queue), 6446 .call = parse_vc, 6447 }, 6448 [ACTION_QUEUE_INDEX] = { 6449 .name = "index", 6450 .help = "queue index to use", 6451 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 6452 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 6453 .call = parse_vc_conf, 6454 }, 6455 [ACTION_DROP] = { 6456 .name = "drop", 6457 .help = "drop packets (note: passthru has priority)", 6458 .priv = PRIV_ACTION(DROP, 0), 6459 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6460 .call = parse_vc, 6461 }, 6462 [ACTION_COUNT] = { 6463 .name = "count", 6464 .help = "enable counters for this rule", 6465 .priv = PRIV_ACTION(COUNT, 6466 sizeof(struct rte_flow_action_count)), 6467 .next = NEXT(action_count), 6468 .call = parse_vc, 6469 }, 6470 [ACTION_COUNT_ID] = { 6471 .name = "identifier", 6472 .help = "counter identifier to use", 6473 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 6474 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 6475 .call = parse_vc_conf, 6476 }, 6477 [ACTION_RSS] = { 6478 .name = "rss", 6479 .help = "spread packets among several queues", 6480 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 6481 .next = NEXT(action_rss), 6482 .call = parse_vc_action_rss, 6483 }, 6484 [ACTION_RSS_FUNC] = { 6485 .name = "func", 6486 .help = "RSS hash function to apply", 6487 .next = NEXT(action_rss, 6488 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 6489 ACTION_RSS_FUNC_TOEPLITZ, 6490 ACTION_RSS_FUNC_SIMPLE_XOR, 6491 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 6492 }, 6493 [ACTION_RSS_FUNC_DEFAULT] = { 6494 .name = "default", 6495 .help = "default hash function", 6496 .call = parse_vc_action_rss_func, 6497 }, 6498 [ACTION_RSS_FUNC_TOEPLITZ] = { 6499 .name = "toeplitz", 6500 .help = "Toeplitz hash function", 6501 .call = parse_vc_action_rss_func, 6502 }, 6503 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 6504 .name = "simple_xor", 6505 .help = "simple XOR hash function", 6506 .call = parse_vc_action_rss_func, 6507 }, 6508 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 6509 .name = "symmetric_toeplitz", 6510 .help = "Symmetric Toeplitz hash function", 6511 .call = parse_vc_action_rss_func, 6512 }, 6513 [ACTION_RSS_LEVEL] = { 6514 .name = "level", 6515 .help = "encapsulation level for \"types\"", 6516 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6517 .args = ARGS(ARGS_ENTRY_ARB 6518 (offsetof(struct action_rss_data, conf) + 6519 offsetof(struct rte_flow_action_rss, level), 6520 sizeof(((struct rte_flow_action_rss *)0)-> 6521 level))), 6522 }, 6523 [ACTION_RSS_TYPES] = { 6524 .name = "types", 6525 .help = "specific RSS hash types", 6526 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 6527 }, 6528 [ACTION_RSS_TYPE] = { 6529 .name = "{type}", 6530 .help = "RSS hash type", 6531 .call = parse_vc_action_rss_type, 6532 .comp = comp_vc_action_rss_type, 6533 }, 6534 [ACTION_RSS_KEY] = { 6535 .name = "key", 6536 .help = "RSS hash key", 6537 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 6538 .args = ARGS(ARGS_ENTRY_ARB 6539 (offsetof(struct action_rss_data, conf) + 6540 offsetof(struct rte_flow_action_rss, key), 6541 sizeof(((struct rte_flow_action_rss *)0)->key)), 6542 ARGS_ENTRY_ARB 6543 (offsetof(struct action_rss_data, conf) + 6544 offsetof(struct rte_flow_action_rss, key_len), 6545 sizeof(((struct rte_flow_action_rss *)0)-> 6546 key_len)), 6547 ARGS_ENTRY(struct action_rss_data, key)), 6548 }, 6549 [ACTION_RSS_KEY_LEN] = { 6550 .name = "key_len", 6551 .help = "RSS hash key length in bytes", 6552 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6553 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6554 (offsetof(struct action_rss_data, conf) + 6555 offsetof(struct rte_flow_action_rss, key_len), 6556 sizeof(((struct rte_flow_action_rss *)0)-> 6557 key_len), 6558 0, 6559 RSS_HASH_KEY_LENGTH)), 6560 }, 6561 [ACTION_RSS_QUEUES] = { 6562 .name = "queues", 6563 .help = "queue indices to use", 6564 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 6565 .call = parse_vc_conf, 6566 }, 6567 [ACTION_RSS_QUEUE] = { 6568 .name = "{queue}", 6569 .help = "queue index", 6570 .call = parse_vc_action_rss_queue, 6571 .comp = comp_vc_action_rss_queue, 6572 }, 6573 [ACTION_PF] = { 6574 .name = "pf", 6575 .help = "direct traffic to physical function", 6576 .priv = PRIV_ACTION(PF, 0), 6577 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6578 .call = parse_vc, 6579 }, 6580 [ACTION_VF] = { 6581 .name = "vf", 6582 .help = "direct traffic to a virtual function ID", 6583 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 6584 .next = NEXT(action_vf), 6585 .call = parse_vc, 6586 }, 6587 [ACTION_VF_ORIGINAL] = { 6588 .name = "original", 6589 .help = "use original VF ID if possible", 6590 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 6591 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 6592 original, 1)), 6593 .call = parse_vc_conf, 6594 }, 6595 [ACTION_VF_ID] = { 6596 .name = "id", 6597 .help = "VF ID", 6598 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 6599 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 6600 .call = parse_vc_conf, 6601 }, 6602 [ACTION_PORT_ID] = { 6603 .name = "port_id", 6604 .help = "direct matching traffic to a given DPDK port ID", 6605 .priv = PRIV_ACTION(PORT_ID, 6606 sizeof(struct rte_flow_action_port_id)), 6607 .next = NEXT(action_port_id), 6608 .call = parse_vc, 6609 }, 6610 [ACTION_PORT_ID_ORIGINAL] = { 6611 .name = "original", 6612 .help = "use original DPDK port ID if possible", 6613 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 6614 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 6615 original, 1)), 6616 .call = parse_vc_conf, 6617 }, 6618 [ACTION_PORT_ID_ID] = { 6619 .name = "id", 6620 .help = "DPDK port ID", 6621 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 6622 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 6623 .call = parse_vc_conf, 6624 }, 6625 [ACTION_METER] = { 6626 .name = "meter", 6627 .help = "meter the directed packets at given id", 6628 .priv = PRIV_ACTION(METER, 6629 sizeof(struct rte_flow_action_meter)), 6630 .next = NEXT(action_meter), 6631 .call = parse_vc, 6632 }, 6633 [ACTION_METER_COLOR] = { 6634 .name = "color", 6635 .help = "meter color for the packets", 6636 .priv = PRIV_ACTION(METER_COLOR, 6637 sizeof(struct rte_flow_action_meter_color)), 6638 .next = NEXT(action_meter_color), 6639 .call = parse_vc, 6640 }, 6641 [ACTION_METER_COLOR_TYPE] = { 6642 .name = "type", 6643 .help = "specific meter color", 6644 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6645 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 6646 ACTION_METER_COLOR_YELLOW, 6647 ACTION_METER_COLOR_RED)), 6648 }, 6649 [ACTION_METER_COLOR_GREEN] = { 6650 .name = "green", 6651 .help = "meter color green", 6652 .call = parse_vc_action_meter_color_type, 6653 }, 6654 [ACTION_METER_COLOR_YELLOW] = { 6655 .name = "yellow", 6656 .help = "meter color yellow", 6657 .call = parse_vc_action_meter_color_type, 6658 }, 6659 [ACTION_METER_COLOR_RED] = { 6660 .name = "red", 6661 .help = "meter color red", 6662 .call = parse_vc_action_meter_color_type, 6663 }, 6664 [ACTION_METER_ID] = { 6665 .name = "mtr_id", 6666 .help = "meter id to use", 6667 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 6668 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 6669 .call = parse_vc_conf, 6670 }, 6671 [ACTION_METER_MARK] = { 6672 .name = "meter_mark", 6673 .help = "meter the directed packets using profile and policy", 6674 .priv = PRIV_ACTION(METER_MARK, 6675 sizeof(struct rte_flow_action_meter_mark)), 6676 .next = NEXT(action_meter_mark), 6677 .call = parse_vc, 6678 }, 6679 [ACTION_METER_PROFILE] = { 6680 .name = "mtr_profile", 6681 .help = "meter profile id to use", 6682 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 6683 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6684 }, 6685 [ACTION_METER_PROFILE_ID2PTR] = { 6686 .name = "{mtr_profile_id}", 6687 .type = "PROFILE_ID", 6688 .help = "meter profile id", 6689 .next = NEXT(action_meter_mark), 6690 .call = parse_meter_profile_id2ptr, 6691 .comp = comp_none, 6692 }, 6693 [ACTION_METER_POLICY] = { 6694 .name = "mtr_policy", 6695 .help = "meter policy id to use", 6696 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 6697 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6698 }, 6699 [ACTION_METER_POLICY_ID2PTR] = { 6700 .name = "{mtr_policy_id}", 6701 .type = "POLICY_ID", 6702 .help = "meter policy id", 6703 .next = NEXT(action_meter_mark), 6704 .call = parse_meter_policy_id2ptr, 6705 .comp = comp_none, 6706 }, 6707 [ACTION_METER_COLOR_MODE] = { 6708 .name = "mtr_color_mode", 6709 .help = "meter color awareness mode", 6710 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6711 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 6712 .call = parse_vc_conf, 6713 }, 6714 [ACTION_METER_STATE] = { 6715 .name = "mtr_state", 6716 .help = "meter state", 6717 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6718 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 6719 .call = parse_vc_conf, 6720 }, 6721 [ACTION_OF_DEC_NW_TTL] = { 6722 .name = "of_dec_nw_ttl", 6723 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 6724 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 6725 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6726 .call = parse_vc, 6727 }, 6728 [ACTION_OF_POP_VLAN] = { 6729 .name = "of_pop_vlan", 6730 .help = "OpenFlow's OFPAT_POP_VLAN", 6731 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 6732 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6733 .call = parse_vc, 6734 }, 6735 [ACTION_OF_PUSH_VLAN] = { 6736 .name = "of_push_vlan", 6737 .help = "OpenFlow's OFPAT_PUSH_VLAN", 6738 .priv = PRIV_ACTION 6739 (OF_PUSH_VLAN, 6740 sizeof(struct rte_flow_action_of_push_vlan)), 6741 .next = NEXT(action_of_push_vlan), 6742 .call = parse_vc, 6743 }, 6744 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 6745 .name = "ethertype", 6746 .help = "EtherType", 6747 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 6748 .args = ARGS(ARGS_ENTRY_HTON 6749 (struct rte_flow_action_of_push_vlan, 6750 ethertype)), 6751 .call = parse_vc_conf, 6752 }, 6753 [ACTION_OF_SET_VLAN_VID] = { 6754 .name = "of_set_vlan_vid", 6755 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 6756 .priv = PRIV_ACTION 6757 (OF_SET_VLAN_VID, 6758 sizeof(struct rte_flow_action_of_set_vlan_vid)), 6759 .next = NEXT(action_of_set_vlan_vid), 6760 .call = parse_vc, 6761 }, 6762 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 6763 .name = "vlan_vid", 6764 .help = "VLAN id", 6765 .next = NEXT(action_of_set_vlan_vid, 6766 NEXT_ENTRY(COMMON_UNSIGNED)), 6767 .args = ARGS(ARGS_ENTRY_HTON 6768 (struct rte_flow_action_of_set_vlan_vid, 6769 vlan_vid)), 6770 .call = parse_vc_conf, 6771 }, 6772 [ACTION_OF_SET_VLAN_PCP] = { 6773 .name = "of_set_vlan_pcp", 6774 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 6775 .priv = PRIV_ACTION 6776 (OF_SET_VLAN_PCP, 6777 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 6778 .next = NEXT(action_of_set_vlan_pcp), 6779 .call = parse_vc, 6780 }, 6781 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 6782 .name = "vlan_pcp", 6783 .help = "VLAN priority", 6784 .next = NEXT(action_of_set_vlan_pcp, 6785 NEXT_ENTRY(COMMON_UNSIGNED)), 6786 .args = ARGS(ARGS_ENTRY_HTON 6787 (struct rte_flow_action_of_set_vlan_pcp, 6788 vlan_pcp)), 6789 .call = parse_vc_conf, 6790 }, 6791 [ACTION_OF_POP_MPLS] = { 6792 .name = "of_pop_mpls", 6793 .help = "OpenFlow's OFPAT_POP_MPLS", 6794 .priv = PRIV_ACTION(OF_POP_MPLS, 6795 sizeof(struct rte_flow_action_of_pop_mpls)), 6796 .next = NEXT(action_of_pop_mpls), 6797 .call = parse_vc, 6798 }, 6799 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 6800 .name = "ethertype", 6801 .help = "EtherType", 6802 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6803 .args = ARGS(ARGS_ENTRY_HTON 6804 (struct rte_flow_action_of_pop_mpls, 6805 ethertype)), 6806 .call = parse_vc_conf, 6807 }, 6808 [ACTION_OF_PUSH_MPLS] = { 6809 .name = "of_push_mpls", 6810 .help = "OpenFlow's OFPAT_PUSH_MPLS", 6811 .priv = PRIV_ACTION 6812 (OF_PUSH_MPLS, 6813 sizeof(struct rte_flow_action_of_push_mpls)), 6814 .next = NEXT(action_of_push_mpls), 6815 .call = parse_vc, 6816 }, 6817 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 6818 .name = "ethertype", 6819 .help = "EtherType", 6820 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6821 .args = ARGS(ARGS_ENTRY_HTON 6822 (struct rte_flow_action_of_push_mpls, 6823 ethertype)), 6824 .call = parse_vc_conf, 6825 }, 6826 [ACTION_VXLAN_ENCAP] = { 6827 .name = "vxlan_encap", 6828 .help = "VXLAN encapsulation, uses configuration set by \"set" 6829 " vxlan\"", 6830 .priv = PRIV_ACTION(VXLAN_ENCAP, 6831 sizeof(struct action_vxlan_encap_data)), 6832 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6833 .call = parse_vc_action_vxlan_encap, 6834 }, 6835 [ACTION_VXLAN_DECAP] = { 6836 .name = "vxlan_decap", 6837 .help = "Performs a decapsulation action by stripping all" 6838 " headers of the VXLAN tunnel network overlay from the" 6839 " matched flow.", 6840 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 6841 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6842 .call = parse_vc, 6843 }, 6844 [ACTION_NVGRE_ENCAP] = { 6845 .name = "nvgre_encap", 6846 .help = "NVGRE encapsulation, uses configuration set by \"set" 6847 " nvgre\"", 6848 .priv = PRIV_ACTION(NVGRE_ENCAP, 6849 sizeof(struct action_nvgre_encap_data)), 6850 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6851 .call = parse_vc_action_nvgre_encap, 6852 }, 6853 [ACTION_NVGRE_DECAP] = { 6854 .name = "nvgre_decap", 6855 .help = "Performs a decapsulation action by stripping all" 6856 " headers of the NVGRE tunnel network overlay from the" 6857 " matched flow.", 6858 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 6859 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6860 .call = parse_vc, 6861 }, 6862 [ACTION_L2_ENCAP] = { 6863 .name = "l2_encap", 6864 .help = "l2 encap, uses configuration set by" 6865 " \"set l2_encap\"", 6866 .priv = PRIV_ACTION(RAW_ENCAP, 6867 sizeof(struct action_raw_encap_data)), 6868 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6869 .call = parse_vc_action_l2_encap, 6870 }, 6871 [ACTION_L2_DECAP] = { 6872 .name = "l2_decap", 6873 .help = "l2 decap, uses configuration set by" 6874 " \"set l2_decap\"", 6875 .priv = PRIV_ACTION(RAW_DECAP, 6876 sizeof(struct action_raw_decap_data)), 6877 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6878 .call = parse_vc_action_l2_decap, 6879 }, 6880 [ACTION_MPLSOGRE_ENCAP] = { 6881 .name = "mplsogre_encap", 6882 .help = "mplsogre encapsulation, uses configuration set by" 6883 " \"set mplsogre_encap\"", 6884 .priv = PRIV_ACTION(RAW_ENCAP, 6885 sizeof(struct action_raw_encap_data)), 6886 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6887 .call = parse_vc_action_mplsogre_encap, 6888 }, 6889 [ACTION_MPLSOGRE_DECAP] = { 6890 .name = "mplsogre_decap", 6891 .help = "mplsogre decapsulation, uses configuration set by" 6892 " \"set mplsogre_decap\"", 6893 .priv = PRIV_ACTION(RAW_DECAP, 6894 sizeof(struct action_raw_decap_data)), 6895 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6896 .call = parse_vc_action_mplsogre_decap, 6897 }, 6898 [ACTION_MPLSOUDP_ENCAP] = { 6899 .name = "mplsoudp_encap", 6900 .help = "mplsoudp encapsulation, uses configuration set by" 6901 " \"set mplsoudp_encap\"", 6902 .priv = PRIV_ACTION(RAW_ENCAP, 6903 sizeof(struct action_raw_encap_data)), 6904 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6905 .call = parse_vc_action_mplsoudp_encap, 6906 }, 6907 [ACTION_MPLSOUDP_DECAP] = { 6908 .name = "mplsoudp_decap", 6909 .help = "mplsoudp decapsulation, uses configuration set by" 6910 " \"set mplsoudp_decap\"", 6911 .priv = PRIV_ACTION(RAW_DECAP, 6912 sizeof(struct action_raw_decap_data)), 6913 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6914 .call = parse_vc_action_mplsoudp_decap, 6915 }, 6916 [ACTION_SET_IPV4_SRC] = { 6917 .name = "set_ipv4_src", 6918 .help = "Set a new IPv4 source address in the outermost" 6919 " IPv4 header", 6920 .priv = PRIV_ACTION(SET_IPV4_SRC, 6921 sizeof(struct rte_flow_action_set_ipv4)), 6922 .next = NEXT(action_set_ipv4_src), 6923 .call = parse_vc, 6924 }, 6925 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 6926 .name = "ipv4_addr", 6927 .help = "new IPv4 source address to set", 6928 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 6929 .args = ARGS(ARGS_ENTRY_HTON 6930 (struct rte_flow_action_set_ipv4, ipv4_addr)), 6931 .call = parse_vc_conf, 6932 }, 6933 [ACTION_SET_IPV4_DST] = { 6934 .name = "set_ipv4_dst", 6935 .help = "Set a new IPv4 destination address in the outermost" 6936 " IPv4 header", 6937 .priv = PRIV_ACTION(SET_IPV4_DST, 6938 sizeof(struct rte_flow_action_set_ipv4)), 6939 .next = NEXT(action_set_ipv4_dst), 6940 .call = parse_vc, 6941 }, 6942 [ACTION_SET_IPV4_DST_IPV4_DST] = { 6943 .name = "ipv4_addr", 6944 .help = "new IPv4 destination address to set", 6945 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 6946 .args = ARGS(ARGS_ENTRY_HTON 6947 (struct rte_flow_action_set_ipv4, ipv4_addr)), 6948 .call = parse_vc_conf, 6949 }, 6950 [ACTION_SET_IPV6_SRC] = { 6951 .name = "set_ipv6_src", 6952 .help = "Set a new IPv6 source address in the outermost" 6953 " IPv6 header", 6954 .priv = PRIV_ACTION(SET_IPV6_SRC, 6955 sizeof(struct rte_flow_action_set_ipv6)), 6956 .next = NEXT(action_set_ipv6_src), 6957 .call = parse_vc, 6958 }, 6959 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 6960 .name = "ipv6_addr", 6961 .help = "new IPv6 source address to set", 6962 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 6963 .args = ARGS(ARGS_ENTRY_HTON 6964 (struct rte_flow_action_set_ipv6, ipv6_addr)), 6965 .call = parse_vc_conf, 6966 }, 6967 [ACTION_SET_IPV6_DST] = { 6968 .name = "set_ipv6_dst", 6969 .help = "Set a new IPv6 destination address in the outermost" 6970 " IPv6 header", 6971 .priv = PRIV_ACTION(SET_IPV6_DST, 6972 sizeof(struct rte_flow_action_set_ipv6)), 6973 .next = NEXT(action_set_ipv6_dst), 6974 .call = parse_vc, 6975 }, 6976 [ACTION_SET_IPV6_DST_IPV6_DST] = { 6977 .name = "ipv6_addr", 6978 .help = "new IPv6 destination address to set", 6979 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 6980 .args = ARGS(ARGS_ENTRY_HTON 6981 (struct rte_flow_action_set_ipv6, ipv6_addr)), 6982 .call = parse_vc_conf, 6983 }, 6984 [ACTION_SET_TP_SRC] = { 6985 .name = "set_tp_src", 6986 .help = "set a new source port number in the outermost" 6987 " TCP/UDP header", 6988 .priv = PRIV_ACTION(SET_TP_SRC, 6989 sizeof(struct rte_flow_action_set_tp)), 6990 .next = NEXT(action_set_tp_src), 6991 .call = parse_vc, 6992 }, 6993 [ACTION_SET_TP_SRC_TP_SRC] = { 6994 .name = "port", 6995 .help = "new source port number to set", 6996 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 6997 .args = ARGS(ARGS_ENTRY_HTON 6998 (struct rte_flow_action_set_tp, port)), 6999 .call = parse_vc_conf, 7000 }, 7001 [ACTION_SET_TP_DST] = { 7002 .name = "set_tp_dst", 7003 .help = "set a new destination port number in the outermost" 7004 " TCP/UDP header", 7005 .priv = PRIV_ACTION(SET_TP_DST, 7006 sizeof(struct rte_flow_action_set_tp)), 7007 .next = NEXT(action_set_tp_dst), 7008 .call = parse_vc, 7009 }, 7010 [ACTION_SET_TP_DST_TP_DST] = { 7011 .name = "port", 7012 .help = "new destination port number to set", 7013 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 7014 .args = ARGS(ARGS_ENTRY_HTON 7015 (struct rte_flow_action_set_tp, port)), 7016 .call = parse_vc_conf, 7017 }, 7018 [ACTION_MAC_SWAP] = { 7019 .name = "mac_swap", 7020 .help = "Swap the source and destination MAC addresses" 7021 " in the outermost Ethernet header", 7022 .priv = PRIV_ACTION(MAC_SWAP, 0), 7023 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7024 .call = parse_vc, 7025 }, 7026 [ACTION_DEC_TTL] = { 7027 .name = "dec_ttl", 7028 .help = "decrease network TTL if available", 7029 .priv = PRIV_ACTION(DEC_TTL, 0), 7030 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7031 .call = parse_vc, 7032 }, 7033 [ACTION_SET_TTL] = { 7034 .name = "set_ttl", 7035 .help = "set ttl value", 7036 .priv = PRIV_ACTION(SET_TTL, 7037 sizeof(struct rte_flow_action_set_ttl)), 7038 .next = NEXT(action_set_ttl), 7039 .call = parse_vc, 7040 }, 7041 [ACTION_SET_TTL_TTL] = { 7042 .name = "ttl_value", 7043 .help = "new ttl value to set", 7044 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 7045 .args = ARGS(ARGS_ENTRY_HTON 7046 (struct rte_flow_action_set_ttl, ttl_value)), 7047 .call = parse_vc_conf, 7048 }, 7049 [ACTION_SET_MAC_SRC] = { 7050 .name = "set_mac_src", 7051 .help = "set source mac address", 7052 .priv = PRIV_ACTION(SET_MAC_SRC, 7053 sizeof(struct rte_flow_action_set_mac)), 7054 .next = NEXT(action_set_mac_src), 7055 .call = parse_vc, 7056 }, 7057 [ACTION_SET_MAC_SRC_MAC_SRC] = { 7058 .name = "mac_addr", 7059 .help = "new source mac address", 7060 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 7061 .args = ARGS(ARGS_ENTRY_HTON 7062 (struct rte_flow_action_set_mac, mac_addr)), 7063 .call = parse_vc_conf, 7064 }, 7065 [ACTION_SET_MAC_DST] = { 7066 .name = "set_mac_dst", 7067 .help = "set destination mac address", 7068 .priv = PRIV_ACTION(SET_MAC_DST, 7069 sizeof(struct rte_flow_action_set_mac)), 7070 .next = NEXT(action_set_mac_dst), 7071 .call = parse_vc, 7072 }, 7073 [ACTION_SET_MAC_DST_MAC_DST] = { 7074 .name = "mac_addr", 7075 .help = "new destination mac address to set", 7076 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 7077 .args = ARGS(ARGS_ENTRY_HTON 7078 (struct rte_flow_action_set_mac, mac_addr)), 7079 .call = parse_vc_conf, 7080 }, 7081 [ACTION_INC_TCP_SEQ] = { 7082 .name = "inc_tcp_seq", 7083 .help = "increase TCP sequence number", 7084 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 7085 .next = NEXT(action_inc_tcp_seq), 7086 .call = parse_vc, 7087 }, 7088 [ACTION_INC_TCP_SEQ_VALUE] = { 7089 .name = "value", 7090 .help = "the value to increase TCP sequence number by", 7091 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7092 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7093 .call = parse_vc_conf, 7094 }, 7095 [ACTION_DEC_TCP_SEQ] = { 7096 .name = "dec_tcp_seq", 7097 .help = "decrease TCP sequence number", 7098 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 7099 .next = NEXT(action_dec_tcp_seq), 7100 .call = parse_vc, 7101 }, 7102 [ACTION_DEC_TCP_SEQ_VALUE] = { 7103 .name = "value", 7104 .help = "the value to decrease TCP sequence number by", 7105 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7106 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7107 .call = parse_vc_conf, 7108 }, 7109 [ACTION_INC_TCP_ACK] = { 7110 .name = "inc_tcp_ack", 7111 .help = "increase TCP acknowledgment number", 7112 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 7113 .next = NEXT(action_inc_tcp_ack), 7114 .call = parse_vc, 7115 }, 7116 [ACTION_INC_TCP_ACK_VALUE] = { 7117 .name = "value", 7118 .help = "the value to increase TCP acknowledgment number by", 7119 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7120 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7121 .call = parse_vc_conf, 7122 }, 7123 [ACTION_DEC_TCP_ACK] = { 7124 .name = "dec_tcp_ack", 7125 .help = "decrease TCP acknowledgment number", 7126 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 7127 .next = NEXT(action_dec_tcp_ack), 7128 .call = parse_vc, 7129 }, 7130 [ACTION_DEC_TCP_ACK_VALUE] = { 7131 .name = "value", 7132 .help = "the value to decrease TCP acknowledgment number by", 7133 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7134 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7135 .call = parse_vc_conf, 7136 }, 7137 [ACTION_RAW_ENCAP] = { 7138 .name = "raw_encap", 7139 .help = "encapsulation data, defined by set raw_encap", 7140 .priv = PRIV_ACTION(RAW_ENCAP, 7141 sizeof(struct action_raw_encap_data)), 7142 .next = NEXT(action_raw_encap), 7143 .call = parse_vc_action_raw_encap, 7144 }, 7145 [ACTION_RAW_ENCAP_SIZE] = { 7146 .name = "size", 7147 .help = "raw encap size", 7148 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7149 NEXT_ENTRY(COMMON_UNSIGNED)), 7150 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_raw_encap, size)), 7151 .call = parse_vc_conf, 7152 }, 7153 [ACTION_RAW_ENCAP_INDEX] = { 7154 .name = "index", 7155 .help = "the index of raw_encap_confs", 7156 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 7157 }, 7158 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 7159 .name = "{index}", 7160 .type = "UNSIGNED", 7161 .help = "unsigned integer value", 7162 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7163 .call = parse_vc_action_raw_encap_index, 7164 .comp = comp_set_raw_index, 7165 }, 7166 [ACTION_RAW_DECAP] = { 7167 .name = "raw_decap", 7168 .help = "decapsulation data, defined by set raw_encap", 7169 .priv = PRIV_ACTION(RAW_DECAP, 7170 sizeof(struct action_raw_decap_data)), 7171 .next = NEXT(action_raw_decap), 7172 .call = parse_vc_action_raw_decap, 7173 }, 7174 [ACTION_RAW_DECAP_INDEX] = { 7175 .name = "index", 7176 .help = "the index of raw_encap_confs", 7177 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 7178 }, 7179 [ACTION_RAW_DECAP_INDEX_VALUE] = { 7180 .name = "{index}", 7181 .type = "UNSIGNED", 7182 .help = "unsigned integer value", 7183 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7184 .call = parse_vc_action_raw_decap_index, 7185 .comp = comp_set_raw_index, 7186 }, 7187 [ACTION_MODIFY_FIELD] = { 7188 .name = "modify_field", 7189 .help = "modify destination field with data from source field", 7190 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 7191 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 7192 .call = parse_vc, 7193 }, 7194 [ACTION_MODIFY_FIELD_OP] = { 7195 .name = "op", 7196 .help = "operation type", 7197 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 7198 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 7199 .call = parse_vc_conf, 7200 }, 7201 [ACTION_MODIFY_FIELD_OP_VALUE] = { 7202 .name = "{operation}", 7203 .help = "operation type value", 7204 .call = parse_vc_modify_field_op, 7205 .comp = comp_set_modify_field_op, 7206 }, 7207 [ACTION_MODIFY_FIELD_DST_TYPE] = { 7208 .name = "dst_type", 7209 .help = "destination field type", 7210 .next = NEXT(action_modify_field_dst, 7211 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 7212 .call = parse_vc_conf, 7213 }, 7214 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 7215 .name = "{dst_type}", 7216 .help = "destination field type value", 7217 .call = parse_vc_modify_field_id, 7218 .comp = comp_set_modify_field_id, 7219 }, 7220 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 7221 .name = "dst_level", 7222 .help = "destination field level", 7223 .next = NEXT(action_modify_field_dst, 7224 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), 7225 .call = parse_vc_conf, 7226 }, 7227 [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { 7228 .name = "{dst_level}", 7229 .help = "destination field level value", 7230 .call = parse_vc_modify_field_level, 7231 .comp = comp_none, 7232 }, 7233 [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { 7234 .name = "dst_tag_index", 7235 .help = "destination field tag array", 7236 .next = NEXT(action_modify_field_dst, 7237 NEXT_ENTRY(COMMON_UNSIGNED)), 7238 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7239 dst.tag_index)), 7240 .call = parse_vc_conf, 7241 }, 7242 [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { 7243 .name = "dst_type_id", 7244 .help = "destination field type ID", 7245 .next = NEXT(action_modify_field_dst, 7246 NEXT_ENTRY(COMMON_UNSIGNED)), 7247 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7248 dst.type)), 7249 .call = parse_vc_conf, 7250 }, 7251 [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { 7252 .name = "dst_class", 7253 .help = "destination field class ID", 7254 .next = NEXT(action_modify_field_dst, 7255 NEXT_ENTRY(COMMON_UNSIGNED)), 7256 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7257 dst.class_id)), 7258 .call = parse_vc_conf, 7259 }, 7260 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 7261 .name = "dst_offset", 7262 .help = "destination field bit offset", 7263 .next = NEXT(action_modify_field_dst, 7264 NEXT_ENTRY(COMMON_UNSIGNED)), 7265 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7266 dst.offset)), 7267 .call = parse_vc_conf, 7268 }, 7269 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 7270 .name = "src_type", 7271 .help = "source field type", 7272 .next = NEXT(action_modify_field_src, 7273 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 7274 .call = parse_vc_conf, 7275 }, 7276 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 7277 .name = "{src_type}", 7278 .help = "source field type value", 7279 .call = parse_vc_modify_field_id, 7280 .comp = comp_set_modify_field_id, 7281 }, 7282 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 7283 .name = "src_level", 7284 .help = "source field level", 7285 .next = NEXT(action_modify_field_src, 7286 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), 7287 .call = parse_vc_conf, 7288 }, 7289 [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { 7290 .name = "{src_level}", 7291 .help = "source field level value", 7292 .call = parse_vc_modify_field_level, 7293 .comp = comp_none, 7294 }, 7295 [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { 7296 .name = "stc_tag_index", 7297 .help = "source field tag array", 7298 .next = NEXT(action_modify_field_src, 7299 NEXT_ENTRY(COMMON_UNSIGNED)), 7300 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7301 src.tag_index)), 7302 .call = parse_vc_conf, 7303 }, 7304 [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { 7305 .name = "src_type_id", 7306 .help = "source field type ID", 7307 .next = NEXT(action_modify_field_src, 7308 NEXT_ENTRY(COMMON_UNSIGNED)), 7309 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7310 src.type)), 7311 .call = parse_vc_conf, 7312 }, 7313 [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { 7314 .name = "src_class", 7315 .help = "source field class ID", 7316 .next = NEXT(action_modify_field_src, 7317 NEXT_ENTRY(COMMON_UNSIGNED)), 7318 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7319 src.class_id)), 7320 .call = parse_vc_conf, 7321 }, 7322 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 7323 .name = "src_offset", 7324 .help = "source field bit offset", 7325 .next = NEXT(action_modify_field_src, 7326 NEXT_ENTRY(COMMON_UNSIGNED)), 7327 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7328 src.offset)), 7329 .call = parse_vc_conf, 7330 }, 7331 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 7332 .name = "src_value", 7333 .help = "source immediate value", 7334 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7335 NEXT_ENTRY(COMMON_HEX)), 7336 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 7337 ARGS_ENTRY_ARB(0, 0), 7338 ARGS_ENTRY(struct rte_flow_action_modify_field, 7339 src.value)), 7340 .call = parse_vc_conf, 7341 }, 7342 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 7343 .name = "src_ptr", 7344 .help = "pointer to source immediate value", 7345 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7346 NEXT_ENTRY(COMMON_HEX)), 7347 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7348 src.pvalue), 7349 ARGS_ENTRY_ARB(0, 0), 7350 ARGS_ENTRY_ARB 7351 (sizeof(struct rte_flow_action_modify_field), 7352 FLOW_FIELD_PATTERN_SIZE)), 7353 .call = parse_vc_conf, 7354 }, 7355 [ACTION_MODIFY_FIELD_WIDTH] = { 7356 .name = "width", 7357 .help = "number of bits to copy", 7358 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7359 NEXT_ENTRY(COMMON_UNSIGNED)), 7360 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7361 width)), 7362 .call = parse_vc_conf, 7363 }, 7364 [ACTION_SEND_TO_KERNEL] = { 7365 .name = "send_to_kernel", 7366 .help = "send packets to kernel", 7367 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 7368 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7369 .call = parse_vc, 7370 }, 7371 [ACTION_IPV6_EXT_REMOVE] = { 7372 .name = "ipv6_ext_remove", 7373 .help = "IPv6 extension type, defined by set ipv6_ext_remove", 7374 .priv = PRIV_ACTION(IPV6_EXT_REMOVE, 7375 sizeof(struct action_ipv6_ext_remove_data)), 7376 .next = NEXT(action_ipv6_ext_remove), 7377 .call = parse_vc_action_ipv6_ext_remove, 7378 }, 7379 [ACTION_IPV6_EXT_REMOVE_INDEX] = { 7380 .name = "index", 7381 .help = "the index of ipv6_ext_remove", 7382 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), 7383 }, 7384 [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { 7385 .name = "{index}", 7386 .type = "UNSIGNED", 7387 .help = "unsigned integer value", 7388 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7389 .call = parse_vc_action_ipv6_ext_remove_index, 7390 .comp = comp_set_ipv6_ext_index, 7391 }, 7392 [ACTION_IPV6_EXT_PUSH] = { 7393 .name = "ipv6_ext_push", 7394 .help = "IPv6 extension data, defined by set ipv6_ext_push", 7395 .priv = PRIV_ACTION(IPV6_EXT_PUSH, 7396 sizeof(struct action_ipv6_ext_push_data)), 7397 .next = NEXT(action_ipv6_ext_push), 7398 .call = parse_vc_action_ipv6_ext_push, 7399 }, 7400 [ACTION_IPV6_EXT_PUSH_INDEX] = { 7401 .name = "index", 7402 .help = "the index of ipv6_ext_push", 7403 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), 7404 }, 7405 [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { 7406 .name = "{index}", 7407 .type = "UNSIGNED", 7408 .help = "unsigned integer value", 7409 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7410 .call = parse_vc_action_ipv6_ext_push_index, 7411 .comp = comp_set_ipv6_ext_index, 7412 }, 7413 [ACTION_NAT64] = { 7414 .name = "nat64", 7415 .help = "NAT64 IP headers translation", 7416 .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), 7417 .next = NEXT(action_nat64), 7418 .call = parse_vc, 7419 }, 7420 [ACTION_NAT64_MODE] = { 7421 .name = "type", 7422 .help = "NAT64 translation type", 7423 .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), 7424 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), 7425 .call = parse_vc_conf, 7426 }, 7427 /* Top level command. */ 7428 [SET] = { 7429 .name = "set", 7430 .help = "set raw encap/decap/sample data", 7431 .type = "set raw_encap|raw_decap <index> <pattern>" 7432 " or set sample_actions <index> <action>", 7433 .next = NEXT(NEXT_ENTRY 7434 (SET_RAW_ENCAP, 7435 SET_RAW_DECAP, 7436 SET_SAMPLE_ACTIONS, 7437 SET_IPV6_EXT_REMOVE, 7438 SET_IPV6_EXT_PUSH)), 7439 .call = parse_set_init, 7440 }, 7441 /* Sub-level commands. */ 7442 [SET_RAW_ENCAP] = { 7443 .name = "raw_encap", 7444 .help = "set raw encap 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_DECAP] = { 7453 .name = "raw_decap", 7454 .help = "set raw decap data", 7455 .next = NEXT(next_set_raw), 7456 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7457 (offsetof(struct buffer, port), 7458 sizeof(((struct buffer *)0)->port), 7459 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7460 .call = parse_set_raw_encap_decap, 7461 }, 7462 [SET_RAW_INDEX] = { 7463 .name = "{index}", 7464 .type = "COMMON_UNSIGNED", 7465 .help = "index of raw_encap/raw_decap data", 7466 .next = NEXT(next_item), 7467 .call = parse_port, 7468 }, 7469 [SET_SAMPLE_INDEX] = { 7470 .name = "{index}", 7471 .type = "UNSIGNED", 7472 .help = "index of sample actions", 7473 .next = NEXT(next_action_sample), 7474 .call = parse_port, 7475 }, 7476 [SET_SAMPLE_ACTIONS] = { 7477 .name = "sample_actions", 7478 .help = "set sample actions list", 7479 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 7480 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7481 (offsetof(struct buffer, port), 7482 sizeof(((struct buffer *)0)->port), 7483 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 7484 .call = parse_set_sample_action, 7485 }, 7486 [SET_IPV6_EXT_PUSH] = { 7487 .name = "ipv6_ext_push", 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_REMOVE] = { 7497 .name = "ipv6_ext_remove", 7498 .help = "set IPv6 extension header", 7499 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7500 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7501 (offsetof(struct buffer, port), 7502 sizeof(((struct buffer *)0)->port), 7503 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7504 .call = parse_set_ipv6_ext_action, 7505 }, 7506 [SET_IPV6_EXT_INDEX] = { 7507 .name = "{index}", 7508 .type = "UNSIGNED", 7509 .help = "index of ipv6 extension push/remove actions", 7510 .next = NEXT(item_ipv6_push_ext), 7511 .call = parse_port, 7512 }, 7513 [ITEM_IPV6_PUSH_REMOVE_EXT] = { 7514 .name = "ipv6_ext", 7515 .help = "set IPv6 extension header", 7516 .priv = PRIV_ITEM(IPV6_EXT, 7517 sizeof(struct rte_flow_item_ipv6_ext)), 7518 .next = NEXT(item_ipv6_push_ext_type), 7519 .call = parse_vc, 7520 }, 7521 [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { 7522 .name = "type", 7523 .help = "set IPv6 extension type", 7524 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 7525 next_hdr)), 7526 .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), 7527 item_param), 7528 }, 7529 [ACTION_SET_TAG] = { 7530 .name = "set_tag", 7531 .help = "set tag", 7532 .priv = PRIV_ACTION(SET_TAG, 7533 sizeof(struct rte_flow_action_set_tag)), 7534 .next = NEXT(action_set_tag), 7535 .call = parse_vc, 7536 }, 7537 [ACTION_SET_TAG_INDEX] = { 7538 .name = "index", 7539 .help = "index of tag array", 7540 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7541 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 7542 .call = parse_vc_conf, 7543 }, 7544 [ACTION_SET_TAG_DATA] = { 7545 .name = "data", 7546 .help = "tag value", 7547 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7548 .args = ARGS(ARGS_ENTRY 7549 (struct rte_flow_action_set_tag, data)), 7550 .call = parse_vc_conf, 7551 }, 7552 [ACTION_SET_TAG_MASK] = { 7553 .name = "mask", 7554 .help = "mask for tag value", 7555 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7556 .args = ARGS(ARGS_ENTRY 7557 (struct rte_flow_action_set_tag, mask)), 7558 .call = parse_vc_conf, 7559 }, 7560 [ACTION_SET_META] = { 7561 .name = "set_meta", 7562 .help = "set metadata", 7563 .priv = PRIV_ACTION(SET_META, 7564 sizeof(struct rte_flow_action_set_meta)), 7565 .next = NEXT(action_set_meta), 7566 .call = parse_vc_action_set_meta, 7567 }, 7568 [ACTION_SET_META_DATA] = { 7569 .name = "data", 7570 .help = "metadata value", 7571 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7572 .args = ARGS(ARGS_ENTRY 7573 (struct rte_flow_action_set_meta, data)), 7574 .call = parse_vc_conf, 7575 }, 7576 [ACTION_SET_META_MASK] = { 7577 .name = "mask", 7578 .help = "mask for metadata value", 7579 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7580 .args = ARGS(ARGS_ENTRY 7581 (struct rte_flow_action_set_meta, mask)), 7582 .call = parse_vc_conf, 7583 }, 7584 [ACTION_SET_IPV4_DSCP] = { 7585 .name = "set_ipv4_dscp", 7586 .help = "set DSCP value", 7587 .priv = PRIV_ACTION(SET_IPV4_DSCP, 7588 sizeof(struct rte_flow_action_set_dscp)), 7589 .next = NEXT(action_set_ipv4_dscp), 7590 .call = parse_vc, 7591 }, 7592 [ACTION_SET_IPV4_DSCP_VALUE] = { 7593 .name = "dscp_value", 7594 .help = "new IPv4 DSCP value to set", 7595 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7596 .args = ARGS(ARGS_ENTRY 7597 (struct rte_flow_action_set_dscp, dscp)), 7598 .call = parse_vc_conf, 7599 }, 7600 [ACTION_SET_IPV6_DSCP] = { 7601 .name = "set_ipv6_dscp", 7602 .help = "set DSCP value", 7603 .priv = PRIV_ACTION(SET_IPV6_DSCP, 7604 sizeof(struct rte_flow_action_set_dscp)), 7605 .next = NEXT(action_set_ipv6_dscp), 7606 .call = parse_vc, 7607 }, 7608 [ACTION_SET_IPV6_DSCP_VALUE] = { 7609 .name = "dscp_value", 7610 .help = "new IPv6 DSCP value to set", 7611 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7612 .args = ARGS(ARGS_ENTRY 7613 (struct rte_flow_action_set_dscp, dscp)), 7614 .call = parse_vc_conf, 7615 }, 7616 [ACTION_AGE] = { 7617 .name = "age", 7618 .help = "set a specific metadata header", 7619 .next = NEXT(action_age), 7620 .priv = PRIV_ACTION(AGE, 7621 sizeof(struct rte_flow_action_age)), 7622 .call = parse_vc, 7623 }, 7624 [ACTION_AGE_TIMEOUT] = { 7625 .name = "timeout", 7626 .help = "flow age timeout value", 7627 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 7628 timeout, 24)), 7629 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 7630 .call = parse_vc_conf, 7631 }, 7632 [ACTION_AGE_UPDATE] = { 7633 .name = "age_update", 7634 .help = "update aging parameter", 7635 .next = NEXT(action_age_update), 7636 .priv = PRIV_ACTION(AGE, 7637 sizeof(struct rte_flow_update_age)), 7638 .call = parse_vc, 7639 }, 7640 [ACTION_AGE_UPDATE_TIMEOUT] = { 7641 .name = "timeout", 7642 .help = "age timeout update value", 7643 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7644 timeout, 24)), 7645 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7646 .call = parse_vc_conf_timeout, 7647 }, 7648 [ACTION_AGE_UPDATE_TOUCH] = { 7649 .name = "touch", 7650 .help = "this flow is touched", 7651 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), 7652 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7653 touch, 1)), 7654 .call = parse_vc_conf, 7655 }, 7656 [ACTION_SAMPLE] = { 7657 .name = "sample", 7658 .help = "set a sample action", 7659 .next = NEXT(action_sample), 7660 .priv = PRIV_ACTION(SAMPLE, 7661 sizeof(struct action_sample_data)), 7662 .call = parse_vc_action_sample, 7663 }, 7664 [ACTION_SAMPLE_RATIO] = { 7665 .name = "ratio", 7666 .help = "flow sample ratio value", 7667 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 7668 .args = ARGS(ARGS_ENTRY_ARB 7669 (offsetof(struct action_sample_data, conf) + 7670 offsetof(struct rte_flow_action_sample, ratio), 7671 sizeof(((struct rte_flow_action_sample *)0)-> 7672 ratio))), 7673 }, 7674 [ACTION_SAMPLE_INDEX] = { 7675 .name = "index", 7676 .help = "the index of sample actions list", 7677 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 7678 }, 7679 [ACTION_SAMPLE_INDEX_VALUE] = { 7680 .name = "{index}", 7681 .type = "COMMON_UNSIGNED", 7682 .help = "unsigned integer value", 7683 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7684 .call = parse_vc_action_sample_index, 7685 .comp = comp_set_sample_index, 7686 }, 7687 [ACTION_CONNTRACK] = { 7688 .name = "conntrack", 7689 .help = "create a conntrack object", 7690 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7691 .priv = PRIV_ACTION(CONNTRACK, 7692 sizeof(struct rte_flow_action_conntrack)), 7693 .call = parse_vc, 7694 }, 7695 [ACTION_CONNTRACK_UPDATE] = { 7696 .name = "conntrack_update", 7697 .help = "update a conntrack object", 7698 .next = NEXT(action_update_conntrack), 7699 .priv = PRIV_ACTION(CONNTRACK, 7700 sizeof(struct rte_flow_modify_conntrack)), 7701 .call = parse_vc, 7702 }, 7703 [ACTION_CONNTRACK_UPDATE_DIR] = { 7704 .name = "dir", 7705 .help = "update a conntrack object direction", 7706 .next = NEXT(action_update_conntrack), 7707 .call = parse_vc_action_conntrack_update, 7708 }, 7709 [ACTION_CONNTRACK_UPDATE_CTX] = { 7710 .name = "ctx", 7711 .help = "update a conntrack object context", 7712 .next = NEXT(action_update_conntrack), 7713 .call = parse_vc_action_conntrack_update, 7714 }, 7715 [ACTION_PORT_REPRESENTOR] = { 7716 .name = "port_representor", 7717 .help = "at embedded switch level, send matching traffic to the given ethdev", 7718 .priv = PRIV_ACTION(PORT_REPRESENTOR, 7719 sizeof(struct rte_flow_action_ethdev)), 7720 .next = NEXT(action_port_representor), 7721 .call = parse_vc, 7722 }, 7723 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 7724 .name = "port_id", 7725 .help = "ethdev port ID", 7726 .next = NEXT(action_port_representor, 7727 NEXT_ENTRY(COMMON_UNSIGNED)), 7728 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7729 port_id)), 7730 .call = parse_vc_conf, 7731 }, 7732 [ACTION_REPRESENTED_PORT] = { 7733 .name = "represented_port", 7734 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 7735 .priv = PRIV_ACTION(REPRESENTED_PORT, 7736 sizeof(struct rte_flow_action_ethdev)), 7737 .next = NEXT(action_represented_port), 7738 .call = parse_vc, 7739 }, 7740 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 7741 .name = "ethdev_port_id", 7742 .help = "ethdev port ID", 7743 .next = NEXT(action_represented_port, 7744 NEXT_ENTRY(COMMON_UNSIGNED)), 7745 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7746 port_id)), 7747 .call = parse_vc_conf, 7748 }, 7749 /* Indirect action destroy arguments. */ 7750 [INDIRECT_ACTION_DESTROY_ID] = { 7751 .name = "action_id", 7752 .help = "specify a indirect action id to destroy", 7753 .next = NEXT(next_ia_destroy_attr, 7754 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7755 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 7756 args.ia_destroy.action_id)), 7757 .call = parse_ia_destroy, 7758 }, 7759 /* Indirect action create arguments. */ 7760 [INDIRECT_ACTION_CREATE_ID] = { 7761 .name = "action_id", 7762 .help = "specify a indirect action id to create", 7763 .next = NEXT(next_ia_create_attr, 7764 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7765 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 7766 }, 7767 [ACTION_INDIRECT] = { 7768 .name = "indirect", 7769 .help = "apply indirect action by id", 7770 .priv = PRIV_ACTION(INDIRECT, 0), 7771 .next = NEXT(next_ia), 7772 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7773 .call = parse_vc, 7774 }, 7775 [ACTION_INDIRECT_LIST] = { 7776 .name = "indirect_list", 7777 .help = "apply indirect list action by id", 7778 .priv = PRIV_ACTION(INDIRECT_LIST, 7779 sizeof(struct 7780 rte_flow_action_indirect_list)), 7781 .next = NEXT(next_ial), 7782 .call = parse_vc, 7783 }, 7784 [ACTION_INDIRECT_LIST_HANDLE] = { 7785 .name = "handle", 7786 .help = "indirect list handle", 7787 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), 7788 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7789 }, 7790 [ACTION_INDIRECT_LIST_CONF] = { 7791 .name = "conf", 7792 .help = "indirect list configuration", 7793 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), 7794 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7795 }, 7796 [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { 7797 .type = "UNSIGNED", 7798 .help = "unsigned integer value", 7799 .call = parse_indlst_id2ptr, 7800 }, 7801 [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { 7802 .type = "UNSIGNED", 7803 .help = "unsigned integer value", 7804 .call = parse_indlst_id2ptr, 7805 }, 7806 [ACTION_SHARED_INDIRECT] = { 7807 .name = "shared_indirect", 7808 .help = "apply indirect action by id and port", 7809 .priv = PRIV_ACTION(INDIRECT, 0), 7810 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), 7811 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), 7812 ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7813 .call = parse_vc, 7814 }, 7815 [INDIRECT_ACTION_PORT] = { 7816 .name = "{indirect_action_port}", 7817 .type = "INDIRECT_ACTION_PORT", 7818 .help = "indirect action port", 7819 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 7820 .call = parse_ia_port, 7821 .comp = comp_none, 7822 }, 7823 [INDIRECT_ACTION_ID2PTR] = { 7824 .name = "{action_id}", 7825 .type = "INDIRECT_ACTION_ID", 7826 .help = "indirect action id", 7827 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7828 .call = parse_ia_id2ptr, 7829 .comp = comp_none, 7830 }, 7831 [INDIRECT_ACTION_INGRESS] = { 7832 .name = "ingress", 7833 .help = "affect rule to ingress", 7834 .next = NEXT(next_ia_create_attr), 7835 .call = parse_ia, 7836 }, 7837 [INDIRECT_ACTION_EGRESS] = { 7838 .name = "egress", 7839 .help = "affect rule to egress", 7840 .next = NEXT(next_ia_create_attr), 7841 .call = parse_ia, 7842 }, 7843 [INDIRECT_ACTION_TRANSFER] = { 7844 .name = "transfer", 7845 .help = "affect rule to transfer", 7846 .next = NEXT(next_ia_create_attr), 7847 .call = parse_ia, 7848 }, 7849 [INDIRECT_ACTION_SPEC] = { 7850 .name = "action", 7851 .help = "specify action to create indirect handle", 7852 .next = NEXT(next_action), 7853 }, 7854 [INDIRECT_ACTION_LIST] = { 7855 .name = "list", 7856 .help = "specify actions for indirect handle list", 7857 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7858 .call = parse_ia, 7859 }, 7860 [INDIRECT_ACTION_FLOW_CONF] = { 7861 .name = "flow_conf", 7862 .help = "specify actions configuration for indirect handle list", 7863 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7864 .call = parse_ia, 7865 }, 7866 [ACTION_POL_G] = { 7867 .name = "g_actions", 7868 .help = "submit a list of associated actions for green", 7869 .next = NEXT(next_action), 7870 .call = parse_mp, 7871 }, 7872 [ACTION_POL_Y] = { 7873 .name = "y_actions", 7874 .help = "submit a list of associated actions for yellow", 7875 .next = NEXT(next_action), 7876 }, 7877 [ACTION_POL_R] = { 7878 .name = "r_actions", 7879 .help = "submit a list of associated actions for red", 7880 .next = NEXT(next_action), 7881 }, 7882 [ACTION_QUOTA_CREATE] = { 7883 .name = "quota_create", 7884 .help = "create quota action", 7885 .priv = PRIV_ACTION(QUOTA, 7886 sizeof(struct rte_flow_action_quota)), 7887 .next = NEXT(action_quota_create), 7888 .call = parse_vc 7889 }, 7890 [ACTION_QUOTA_CREATE_LIMIT] = { 7891 .name = "limit", 7892 .help = "quota limit", 7893 .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), 7894 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), 7895 .call = parse_vc_conf 7896 }, 7897 [ACTION_QUOTA_CREATE_MODE] = { 7898 .name = "mode", 7899 .help = "quota mode", 7900 .next = NEXT(action_quota_create, 7901 NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), 7902 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), 7903 .call = parse_vc_conf 7904 }, 7905 [ACTION_QUOTA_CREATE_MODE_NAME] = { 7906 .name = "mode_name", 7907 .help = "quota mode name", 7908 .call = parse_quota_mode_name, 7909 .comp = comp_quota_mode_name 7910 }, 7911 [ACTION_QUOTA_QU] = { 7912 .name = "quota_update", 7913 .help = "update quota action", 7914 .priv = PRIV_ACTION(QUOTA, 7915 sizeof(struct rte_flow_update_quota)), 7916 .next = NEXT(action_quota_update), 7917 .call = parse_vc 7918 }, 7919 [ACTION_QUOTA_QU_LIMIT] = { 7920 .name = "limit", 7921 .help = "quota limit", 7922 .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7923 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), 7924 .call = parse_vc_conf 7925 }, 7926 [ACTION_QUOTA_QU_UPDATE_OP] = { 7927 .name = "update_op", 7928 .help = "query update op SET|ADD", 7929 .next = NEXT(action_quota_update, 7930 NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), 7931 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), 7932 .call = parse_vc_conf 7933 }, 7934 [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { 7935 .name = "update_op_name", 7936 .help = "quota update op name", 7937 .call = parse_quota_update_name, 7938 .comp = comp_quota_update_name 7939 }, 7940 7941 /* Top-level command. */ 7942 [ADD] = { 7943 .name = "add", 7944 .type = "port meter policy {port_id} {arg}", 7945 .help = "add port meter policy", 7946 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 7947 .call = parse_init, 7948 }, 7949 /* Sub-level commands. */ 7950 [ITEM_POL_PORT] = { 7951 .name = "port", 7952 .help = "add port meter policy", 7953 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 7954 }, 7955 [ITEM_POL_METER] = { 7956 .name = "meter", 7957 .help = "add port meter policy", 7958 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 7959 }, 7960 [ITEM_POL_POLICY] = { 7961 .name = "policy", 7962 .help = "add port meter policy", 7963 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 7964 NEXT_ENTRY(ACTION_POL_Y), 7965 NEXT_ENTRY(ACTION_POL_G), 7966 NEXT_ENTRY(COMMON_POLICY_ID), 7967 NEXT_ENTRY(COMMON_PORT_ID)), 7968 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 7969 ARGS_ENTRY(struct buffer, port)), 7970 .call = parse_mp, 7971 }, 7972 [ITEM_AGGR_AFFINITY] = { 7973 .name = "aggr_affinity", 7974 .help = "match on the aggregated port receiving the packets", 7975 .priv = PRIV_ITEM(AGGR_AFFINITY, 7976 sizeof(struct rte_flow_item_aggr_affinity)), 7977 .next = NEXT(item_aggr_affinity), 7978 .call = parse_vc, 7979 }, 7980 [ITEM_AGGR_AFFINITY_VALUE] = { 7981 .name = "affinity", 7982 .help = "aggregated affinity value", 7983 .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), 7984 item_param), 7985 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, 7986 affinity)), 7987 }, 7988 [ITEM_TX_QUEUE] = { 7989 .name = "tx_queue", 7990 .help = "match on the tx queue of send packet", 7991 .priv = PRIV_ITEM(TX_QUEUE, 7992 sizeof(struct rte_flow_item_tx_queue)), 7993 .next = NEXT(item_tx_queue), 7994 .call = parse_vc, 7995 }, 7996 [ITEM_TX_QUEUE_VALUE] = { 7997 .name = "tx_queue_value", 7998 .help = "tx queue value", 7999 .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), 8000 item_param), 8001 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, 8002 tx_queue)), 8003 }, 8004 }; 8005 8006 /** Remove and return last entry from argument stack. */ 8007 static const struct arg * 8008 pop_args(struct context *ctx) 8009 { 8010 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 8011 } 8012 8013 /** Add entry on top of the argument stack. */ 8014 static int 8015 push_args(struct context *ctx, const struct arg *arg) 8016 { 8017 if (ctx->args_num == CTX_STACK_SIZE) 8018 return -1; 8019 ctx->args[ctx->args_num++] = arg; 8020 return 0; 8021 } 8022 8023 /** Spread value into buffer according to bit-mask. */ 8024 static size_t 8025 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 8026 { 8027 uint32_t i = arg->size; 8028 uint32_t end = 0; 8029 int sub = 1; 8030 int add = 0; 8031 size_t len = 0; 8032 8033 if (!arg->mask) 8034 return 0; 8035 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8036 if (!arg->hton) { 8037 i = 0; 8038 end = arg->size; 8039 sub = 0; 8040 add = 1; 8041 } 8042 #endif 8043 while (i != end) { 8044 unsigned int shift = 0; 8045 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 8046 8047 for (shift = 0; arg->mask[i] >> shift; ++shift) { 8048 if (!(arg->mask[i] & (1 << shift))) 8049 continue; 8050 ++len; 8051 if (!dst) 8052 continue; 8053 *buf &= ~(1 << shift); 8054 *buf |= (val & 1) << shift; 8055 val >>= 1; 8056 } 8057 i += add; 8058 } 8059 return len; 8060 } 8061 8062 /** Compare a string with a partial one of a given length. */ 8063 static int 8064 strcmp_partial(const char *full, const char *partial, size_t partial_len) 8065 { 8066 int r = strncmp(full, partial, partial_len); 8067 8068 if (r) 8069 return r; 8070 if (strlen(full) <= partial_len) 8071 return 0; 8072 return full[partial_len]; 8073 } 8074 8075 /** 8076 * Parse a prefix length and generate a bit-mask. 8077 * 8078 * Last argument (ctx->args) is retrieved to determine mask size, storage 8079 * location and whether the result must use network byte ordering. 8080 */ 8081 static int 8082 parse_prefix(struct context *ctx, const struct token *token, 8083 const char *str, unsigned int len, 8084 void *buf, unsigned int size) 8085 { 8086 const struct arg *arg = pop_args(ctx); 8087 static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff"; 8088 char *end; 8089 uintmax_t u; 8090 unsigned int bytes; 8091 unsigned int extra; 8092 8093 (void)token; 8094 /* Argument is expected. */ 8095 if (!arg) 8096 return -1; 8097 errno = 0; 8098 u = strtoumax(str, &end, 0); 8099 if (errno || (size_t)(end - str) != len) 8100 goto error; 8101 if (arg->mask) { 8102 uintmax_t v = 0; 8103 8104 extra = arg_entry_bf_fill(NULL, 0, arg); 8105 if (u > extra) 8106 goto error; 8107 if (!ctx->object) 8108 return len; 8109 extra -= u; 8110 while (u--) 8111 (v <<= 1, v |= 1); 8112 v <<= extra; 8113 if (!arg_entry_bf_fill(ctx->object, v, arg) || 8114 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 8115 goto error; 8116 return len; 8117 } 8118 bytes = u / 8; 8119 extra = u % 8; 8120 size = arg->size; 8121 if (bytes > size || bytes + !!extra > size) 8122 goto error; 8123 if (!ctx->object) 8124 return len; 8125 buf = (uint8_t *)ctx->object + arg->offset; 8126 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8127 if (!arg->hton) { 8128 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 8129 memset(buf, 0x00, size - bytes); 8130 if (extra) 8131 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 8132 } else 8133 #endif 8134 { 8135 memset(buf, 0xff, bytes); 8136 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 8137 if (extra) 8138 ((uint8_t *)buf)[bytes] = conv[extra]; 8139 } 8140 if (ctx->objmask) 8141 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 8142 return len; 8143 error: 8144 push_args(ctx, arg); 8145 return -1; 8146 } 8147 8148 /** Default parsing function for token name matching. */ 8149 static int 8150 parse_default(struct context *ctx, const struct token *token, 8151 const char *str, unsigned int len, 8152 void *buf, unsigned int size) 8153 { 8154 (void)ctx; 8155 (void)buf; 8156 (void)size; 8157 if (strcmp_partial(token->name, str, len)) 8158 return -1; 8159 return len; 8160 } 8161 8162 /** Parse flow command, initialize output buffer for subsequent tokens. */ 8163 static int 8164 parse_init(struct context *ctx, const struct token *token, 8165 const char *str, unsigned int len, 8166 void *buf, unsigned int size) 8167 { 8168 struct buffer *out = buf; 8169 8170 /* Token name must match. */ 8171 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8172 return -1; 8173 /* Nothing else to do if there is no buffer. */ 8174 if (!out) 8175 return len; 8176 /* Make sure buffer is large enough. */ 8177 if (size < sizeof(*out)) 8178 return -1; 8179 /* Initialize buffer. */ 8180 memset(out, 0x00, sizeof(*out)); 8181 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 8182 ctx->objdata = 0; 8183 ctx->object = out; 8184 ctx->objmask = NULL; 8185 return len; 8186 } 8187 8188 /** Parse tokens for indirect action commands. */ 8189 static int 8190 parse_ia(struct context *ctx, const struct token *token, 8191 const char *str, unsigned int len, 8192 void *buf, unsigned int size) 8193 { 8194 struct buffer *out = buf; 8195 8196 /* Token name must match. */ 8197 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8198 return -1; 8199 /* Nothing else to do if there is no buffer. */ 8200 if (!out) 8201 return len; 8202 if (!out->command) { 8203 if (ctx->curr != INDIRECT_ACTION) 8204 return -1; 8205 if (sizeof(*out) > size) 8206 return -1; 8207 out->command = ctx->curr; 8208 ctx->objdata = 0; 8209 ctx->object = out; 8210 ctx->objmask = NULL; 8211 out->args.vc.data = (uint8_t *)out + size; 8212 return len; 8213 } 8214 switch (ctx->curr) { 8215 case INDIRECT_ACTION_CREATE: 8216 case INDIRECT_ACTION_UPDATE: 8217 case INDIRECT_ACTION_QUERY_UPDATE: 8218 out->args.vc.actions = 8219 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8220 sizeof(double)); 8221 out->args.vc.attr.group = UINT32_MAX; 8222 /* fallthrough */ 8223 case INDIRECT_ACTION_QUERY: 8224 out->command = ctx->curr; 8225 ctx->objdata = 0; 8226 ctx->object = out; 8227 ctx->objmask = NULL; 8228 return len; 8229 case INDIRECT_ACTION_EGRESS: 8230 out->args.vc.attr.egress = 1; 8231 return len; 8232 case INDIRECT_ACTION_INGRESS: 8233 out->args.vc.attr.ingress = 1; 8234 return len; 8235 case INDIRECT_ACTION_TRANSFER: 8236 out->args.vc.attr.transfer = 1; 8237 return len; 8238 case INDIRECT_ACTION_QU_MODE: 8239 return len; 8240 case INDIRECT_ACTION_LIST: 8241 out->command = INDIRECT_ACTION_LIST_CREATE; 8242 return len; 8243 case INDIRECT_ACTION_FLOW_CONF: 8244 out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; 8245 return len; 8246 default: 8247 return -1; 8248 } 8249 } 8250 8251 8252 /** Parse tokens for indirect action destroy command. */ 8253 static int 8254 parse_ia_destroy(struct context *ctx, const struct token *token, 8255 const char *str, unsigned int len, 8256 void *buf, unsigned int size) 8257 { 8258 struct buffer *out = buf; 8259 uint32_t *action_id; 8260 8261 /* Token name must match. */ 8262 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8263 return -1; 8264 /* Nothing else to do if there is no buffer. */ 8265 if (!out) 8266 return len; 8267 if (!out->command || out->command == INDIRECT_ACTION) { 8268 if (ctx->curr != INDIRECT_ACTION_DESTROY) 8269 return -1; 8270 if (sizeof(*out) > size) 8271 return -1; 8272 out->command = ctx->curr; 8273 ctx->objdata = 0; 8274 ctx->object = out; 8275 ctx->objmask = NULL; 8276 out->args.ia_destroy.action_id = 8277 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8278 sizeof(double)); 8279 return len; 8280 } 8281 action_id = out->args.ia_destroy.action_id 8282 + out->args.ia_destroy.action_id_n++; 8283 if ((uint8_t *)action_id > (uint8_t *)out + size) 8284 return -1; 8285 ctx->objdata = 0; 8286 ctx->object = action_id; 8287 ctx->objmask = NULL; 8288 return len; 8289 } 8290 8291 /** Parse tokens for indirect action commands. */ 8292 static int 8293 parse_qia(struct context *ctx, const struct token *token, 8294 const char *str, unsigned int len, 8295 void *buf, unsigned int size) 8296 { 8297 struct buffer *out = buf; 8298 8299 /* Token name must match. */ 8300 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8301 return -1; 8302 /* Nothing else to do if there is no buffer. */ 8303 if (!out) 8304 return len; 8305 if (!out->command) { 8306 if (ctx->curr != QUEUE) 8307 return -1; 8308 if (sizeof(*out) > size) 8309 return -1; 8310 out->args.vc.data = (uint8_t *)out + size; 8311 return len; 8312 } 8313 switch (ctx->curr) { 8314 case QUEUE_INDIRECT_ACTION: 8315 return len; 8316 case QUEUE_INDIRECT_ACTION_CREATE: 8317 case QUEUE_INDIRECT_ACTION_UPDATE: 8318 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 8319 out->args.vc.actions = 8320 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8321 sizeof(double)); 8322 out->args.vc.attr.group = UINT32_MAX; 8323 /* fallthrough */ 8324 case QUEUE_INDIRECT_ACTION_QUERY: 8325 out->command = ctx->curr; 8326 ctx->objdata = 0; 8327 ctx->object = out; 8328 ctx->objmask = NULL; 8329 return len; 8330 case QUEUE_INDIRECT_ACTION_EGRESS: 8331 out->args.vc.attr.egress = 1; 8332 return len; 8333 case QUEUE_INDIRECT_ACTION_INGRESS: 8334 out->args.vc.attr.ingress = 1; 8335 return len; 8336 case QUEUE_INDIRECT_ACTION_TRANSFER: 8337 out->args.vc.attr.transfer = 1; 8338 return len; 8339 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 8340 return len; 8341 case QUEUE_INDIRECT_ACTION_QU_MODE: 8342 return len; 8343 case QUEUE_INDIRECT_ACTION_LIST: 8344 out->command = QUEUE_INDIRECT_ACTION_LIST_CREATE; 8345 return len; 8346 default: 8347 return -1; 8348 } 8349 } 8350 8351 /** Parse tokens for indirect action destroy command. */ 8352 static int 8353 parse_qia_destroy(struct context *ctx, const struct token *token, 8354 const char *str, unsigned int len, 8355 void *buf, unsigned int size) 8356 { 8357 struct buffer *out = buf; 8358 uint32_t *action_id; 8359 8360 /* Token name must match. */ 8361 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8362 return -1; 8363 /* Nothing else to do if there is no buffer. */ 8364 if (!out) 8365 return len; 8366 if (!out->command || out->command == QUEUE) { 8367 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 8368 return -1; 8369 if (sizeof(*out) > size) 8370 return -1; 8371 out->command = ctx->curr; 8372 ctx->objdata = 0; 8373 ctx->object = out; 8374 ctx->objmask = NULL; 8375 out->args.ia_destroy.action_id = 8376 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8377 sizeof(double)); 8378 return len; 8379 } 8380 switch (ctx->curr) { 8381 case QUEUE_INDIRECT_ACTION: 8382 out->command = ctx->curr; 8383 ctx->objdata = 0; 8384 ctx->object = out; 8385 ctx->objmask = NULL; 8386 return len; 8387 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 8388 action_id = out->args.ia_destroy.action_id 8389 + out->args.ia_destroy.action_id_n++; 8390 if ((uint8_t *)action_id > (uint8_t *)out + size) 8391 return -1; 8392 ctx->objdata = 0; 8393 ctx->object = action_id; 8394 ctx->objmask = NULL; 8395 return len; 8396 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 8397 return len; 8398 default: 8399 return -1; 8400 } 8401 } 8402 8403 /** Parse tokens for meter policy action commands. */ 8404 static int 8405 parse_mp(struct context *ctx, const struct token *token, 8406 const char *str, unsigned int len, 8407 void *buf, unsigned int size) 8408 { 8409 struct buffer *out = buf; 8410 8411 /* Token name must match. */ 8412 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8413 return -1; 8414 /* Nothing else to do if there is no buffer. */ 8415 if (!out) 8416 return len; 8417 if (!out->command) { 8418 if (ctx->curr != ITEM_POL_POLICY) 8419 return -1; 8420 if (sizeof(*out) > size) 8421 return -1; 8422 out->command = ctx->curr; 8423 ctx->objdata = 0; 8424 ctx->object = out; 8425 ctx->objmask = NULL; 8426 out->args.vc.data = (uint8_t *)out + size; 8427 return len; 8428 } 8429 switch (ctx->curr) { 8430 case ACTION_POL_G: 8431 out->args.vc.actions = 8432 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8433 sizeof(double)); 8434 out->command = ctx->curr; 8435 ctx->objdata = 0; 8436 ctx->object = out; 8437 ctx->objmask = NULL; 8438 return len; 8439 default: 8440 return -1; 8441 } 8442 } 8443 8444 /** Parse tokens for validate/create commands. */ 8445 static int 8446 parse_vc(struct context *ctx, const struct token *token, 8447 const char *str, unsigned int len, 8448 void *buf, unsigned int size) 8449 { 8450 struct buffer *out = buf; 8451 uint8_t *data; 8452 uint32_t data_size; 8453 8454 /* Token name must match. */ 8455 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8456 return -1; 8457 /* Nothing else to do if there is no buffer. */ 8458 if (!out) 8459 return len; 8460 if (!out->command) { 8461 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 8462 ctx->curr != PATTERN_TEMPLATE_CREATE && 8463 ctx->curr != ACTIONS_TEMPLATE_CREATE) 8464 return -1; 8465 if (sizeof(*out) > size) 8466 return -1; 8467 out->command = ctx->curr; 8468 ctx->objdata = 0; 8469 ctx->object = out; 8470 ctx->objmask = NULL; 8471 out->args.vc.data = (uint8_t *)out + size; 8472 return len; 8473 } 8474 ctx->objdata = 0; 8475 switch (ctx->curr) { 8476 default: 8477 ctx->object = &out->args.vc.attr; 8478 break; 8479 case VC_TUNNEL_SET: 8480 case VC_TUNNEL_MATCH: 8481 ctx->object = &out->args.vc.tunnel_ops; 8482 break; 8483 case VC_USER_ID: 8484 ctx->object = out; 8485 break; 8486 } 8487 ctx->objmask = NULL; 8488 switch (ctx->curr) { 8489 case VC_GROUP: 8490 case VC_PRIORITY: 8491 case VC_USER_ID: 8492 return len; 8493 case VC_TUNNEL_SET: 8494 out->args.vc.tunnel_ops.enabled = 1; 8495 out->args.vc.tunnel_ops.actions = 1; 8496 return len; 8497 case VC_TUNNEL_MATCH: 8498 out->args.vc.tunnel_ops.enabled = 1; 8499 out->args.vc.tunnel_ops.items = 1; 8500 return len; 8501 case VC_INGRESS: 8502 out->args.vc.attr.ingress = 1; 8503 return len; 8504 case VC_EGRESS: 8505 out->args.vc.attr.egress = 1; 8506 return len; 8507 case VC_TRANSFER: 8508 out->args.vc.attr.transfer = 1; 8509 return len; 8510 case ITEM_PATTERN: 8511 out->args.vc.pattern = 8512 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8513 sizeof(double)); 8514 ctx->object = out->args.vc.pattern; 8515 ctx->objmask = NULL; 8516 return len; 8517 case ITEM_END: 8518 if ((out->command == VALIDATE || out->command == CREATE) && 8519 ctx->last) 8520 return -1; 8521 if (out->command == PATTERN_TEMPLATE_CREATE && 8522 !ctx->last) 8523 return -1; 8524 break; 8525 case ACTIONS: 8526 out->args.vc.actions = out->args.vc.pattern ? 8527 (void *)RTE_ALIGN_CEIL((uintptr_t) 8528 (out->args.vc.pattern + 8529 out->args.vc.pattern_n), 8530 sizeof(double)) : 8531 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8532 sizeof(double)); 8533 ctx->object = out->args.vc.actions; 8534 ctx->objmask = NULL; 8535 return len; 8536 default: 8537 if (!token->priv) 8538 return -1; 8539 break; 8540 } 8541 if (!out->args.vc.actions) { 8542 const struct parse_item_priv *priv = token->priv; 8543 struct rte_flow_item *item = 8544 out->args.vc.pattern + out->args.vc.pattern_n; 8545 8546 data_size = priv->size * 3; /* spec, last, mask */ 8547 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8548 (out->args.vc.data - data_size), 8549 sizeof(double)); 8550 if ((uint8_t *)item + sizeof(*item) > data) 8551 return -1; 8552 *item = (struct rte_flow_item){ 8553 .type = priv->type, 8554 }; 8555 ++out->args.vc.pattern_n; 8556 ctx->object = item; 8557 ctx->objmask = NULL; 8558 } else { 8559 const struct parse_action_priv *priv = token->priv; 8560 struct rte_flow_action *action = 8561 out->args.vc.actions + out->args.vc.actions_n; 8562 8563 data_size = priv->size; /* configuration */ 8564 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8565 (out->args.vc.data - data_size), 8566 sizeof(double)); 8567 if ((uint8_t *)action + sizeof(*action) > data) 8568 return -1; 8569 *action = (struct rte_flow_action){ 8570 .type = priv->type, 8571 .conf = data_size ? data : NULL, 8572 }; 8573 ++out->args.vc.actions_n; 8574 ctx->object = action; 8575 ctx->objmask = NULL; 8576 } 8577 memset(data, 0, data_size); 8578 out->args.vc.data = data; 8579 ctx->objdata = data_size; 8580 return len; 8581 } 8582 8583 /** Parse pattern item parameter type. */ 8584 static int 8585 parse_vc_spec(struct context *ctx, const struct token *token, 8586 const char *str, unsigned int len, 8587 void *buf, unsigned int size) 8588 { 8589 struct buffer *out = buf; 8590 struct rte_flow_item *item; 8591 uint32_t data_size; 8592 int index; 8593 int objmask = 0; 8594 8595 (void)size; 8596 /* Token name must match. */ 8597 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8598 return -1; 8599 /* Parse parameter types. */ 8600 switch (ctx->curr) { 8601 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 8602 8603 case ITEM_PARAM_IS: 8604 index = 0; 8605 objmask = 1; 8606 break; 8607 case ITEM_PARAM_SPEC: 8608 index = 0; 8609 break; 8610 case ITEM_PARAM_LAST: 8611 index = 1; 8612 break; 8613 case ITEM_PARAM_PREFIX: 8614 /* Modify next token to expect a prefix. */ 8615 if (ctx->next_num < 2) 8616 return -1; 8617 ctx->next[ctx->next_num - 2] = prefix; 8618 /* Fall through. */ 8619 case ITEM_PARAM_MASK: 8620 index = 2; 8621 break; 8622 default: 8623 return -1; 8624 } 8625 /* Nothing else to do if there is no buffer. */ 8626 if (!out) 8627 return len; 8628 if (!out->args.vc.pattern_n) 8629 return -1; 8630 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8631 data_size = ctx->objdata / 3; /* spec, last, mask */ 8632 /* Point to selected object. */ 8633 ctx->object = out->args.vc.data + (data_size * index); 8634 if (objmask) { 8635 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 8636 item->mask = ctx->objmask; 8637 } else 8638 ctx->objmask = NULL; 8639 /* Update relevant item pointer. */ 8640 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 8641 ctx->object; 8642 return len; 8643 } 8644 8645 /** Parse action configuration field. */ 8646 static int 8647 parse_vc_conf(struct context *ctx, const struct token *token, 8648 const char *str, unsigned int len, 8649 void *buf, unsigned int size) 8650 { 8651 struct buffer *out = buf; 8652 8653 (void)size; 8654 /* Token name must match. */ 8655 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8656 return -1; 8657 /* Nothing else to do if there is no buffer. */ 8658 if (!out) 8659 return len; 8660 /* Point to selected object. */ 8661 ctx->object = out->args.vc.data; 8662 ctx->objmask = NULL; 8663 return len; 8664 } 8665 8666 /** Parse action configuration field. */ 8667 static int 8668 parse_vc_conf_timeout(struct context *ctx, const struct token *token, 8669 const char *str, unsigned int len, 8670 void *buf, unsigned int size) 8671 { 8672 struct buffer *out = buf; 8673 struct rte_flow_update_age *update; 8674 8675 (void)size; 8676 if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) 8677 return -1; 8678 /* Token name must match. */ 8679 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8680 return -1; 8681 /* Nothing else to do if there is no buffer. */ 8682 if (!out) 8683 return len; 8684 /* Point to selected object. */ 8685 ctx->object = out->args.vc.data; 8686 ctx->objmask = NULL; 8687 /* Update the timeout is valid. */ 8688 update = (struct rte_flow_update_age *)out->args.vc.data; 8689 update->timeout_valid = 1; 8690 return len; 8691 } 8692 8693 /** Parse eCPRI common header type field. */ 8694 static int 8695 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 8696 const char *str, unsigned int len, 8697 void *buf, unsigned int size) 8698 { 8699 struct rte_flow_item_ecpri *ecpri; 8700 struct rte_flow_item_ecpri *ecpri_mask; 8701 struct rte_flow_item *item; 8702 uint32_t data_size; 8703 uint8_t msg_type; 8704 struct buffer *out = buf; 8705 const struct arg *arg; 8706 8707 (void)size; 8708 /* Token name must match. */ 8709 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8710 return -1; 8711 switch (ctx->curr) { 8712 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 8713 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 8714 break; 8715 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 8716 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 8717 break; 8718 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 8719 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 8720 break; 8721 default: 8722 return -1; 8723 } 8724 if (!ctx->object) 8725 return len; 8726 arg = pop_args(ctx); 8727 if (!arg) 8728 return -1; 8729 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 8730 ecpri->hdr.common.type = msg_type; 8731 data_size = ctx->objdata / 3; /* spec, last, mask */ 8732 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 8733 (data_size * 2)); 8734 ecpri_mask->hdr.common.type = 0xFF; 8735 if (arg->hton) { 8736 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 8737 ecpri_mask->hdr.common.u32 = 8738 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 8739 } 8740 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8741 item->spec = ecpri; 8742 item->mask = ecpri_mask; 8743 return len; 8744 } 8745 8746 /** Parse L2TPv2 common header type field. */ 8747 static int 8748 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, 8749 const char *str, unsigned int len, 8750 void *buf, unsigned int size) 8751 { 8752 struct rte_flow_item_l2tpv2 *l2tpv2; 8753 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 8754 struct rte_flow_item *item; 8755 uint32_t data_size; 8756 uint16_t msg_type = 0; 8757 struct buffer *out = buf; 8758 const struct arg *arg; 8759 8760 (void)size; 8761 /* Token name must match. */ 8762 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8763 return -1; 8764 switch (ctx->curr) { 8765 case ITEM_L2TPV2_TYPE_DATA: 8766 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 8767 break; 8768 case ITEM_L2TPV2_TYPE_DATA_L: 8769 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 8770 break; 8771 case ITEM_L2TPV2_TYPE_DATA_S: 8772 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 8773 break; 8774 case ITEM_L2TPV2_TYPE_DATA_O: 8775 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 8776 break; 8777 case ITEM_L2TPV2_TYPE_DATA_L_S: 8778 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 8779 break; 8780 case ITEM_L2TPV2_TYPE_CTRL: 8781 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 8782 break; 8783 default: 8784 return -1; 8785 } 8786 if (!ctx->object) 8787 return len; 8788 arg = pop_args(ctx); 8789 if (!arg) 8790 return -1; 8791 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 8792 l2tpv2->hdr.common.flags_version |= msg_type; 8793 data_size = ctx->objdata / 3; /* spec, last, mask */ 8794 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 8795 (data_size * 2)); 8796 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 8797 if (arg->hton) { 8798 l2tpv2->hdr.common.flags_version = 8799 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 8800 l2tpv2_mask->hdr.common.flags_version = 8801 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 8802 } 8803 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8804 item->spec = l2tpv2; 8805 item->mask = l2tpv2_mask; 8806 return len; 8807 } 8808 8809 /** Parse operation for compare match item. */ 8810 static int 8811 parse_vc_compare_op(struct context *ctx, const struct token *token, 8812 const char *str, unsigned int len, void *buf, 8813 unsigned int size) 8814 { 8815 struct rte_flow_item_compare *compare_item; 8816 unsigned int i; 8817 8818 (void)token; 8819 (void)buf; 8820 (void)size; 8821 if (ctx->curr != ITEM_COMPARE_OP_VALUE) 8822 return -1; 8823 for (i = 0; compare_ops[i]; ++i) 8824 if (!strcmp_partial(compare_ops[i], str, len)) 8825 break; 8826 if (!compare_ops[i]) 8827 return -1; 8828 if (!ctx->object) 8829 return len; 8830 compare_item = ctx->object; 8831 compare_item->operation = (enum rte_flow_item_compare_op)i; 8832 return len; 8833 } 8834 8835 /** Parse id for compare match item. */ 8836 static int 8837 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 8838 const char *str, unsigned int len, void *buf, 8839 unsigned int size) 8840 { 8841 struct rte_flow_item_compare *compare_item; 8842 unsigned int i; 8843 8844 (void)token; 8845 (void)buf; 8846 (void)size; 8847 if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE && 8848 ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE) 8849 return -1; 8850 for (i = 0; flow_field_ids[i]; ++i) 8851 if (!strcmp_partial(flow_field_ids[i], str, len)) 8852 break; 8853 if (!flow_field_ids[i]) 8854 return -1; 8855 if (!ctx->object) 8856 return len; 8857 compare_item = ctx->object; 8858 if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE) 8859 compare_item->a.field = (enum rte_flow_field_id)i; 8860 else 8861 compare_item->b.field = (enum rte_flow_field_id)i; 8862 return len; 8863 } 8864 8865 /** Parse level for compare match item. */ 8866 static int 8867 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 8868 const char *str, unsigned int len, void *buf, 8869 unsigned int size) 8870 { 8871 struct rte_flow_item_compare *compare_item; 8872 struct flex_item *fp = NULL; 8873 uint32_t val; 8874 struct buffer *out = buf; 8875 char *end; 8876 8877 (void)token; 8878 (void)size; 8879 if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 8880 ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE) 8881 return -1; 8882 if (!ctx->object) 8883 return len; 8884 compare_item = ctx->object; 8885 errno = 0; 8886 val = strtoumax(str, &end, 0); 8887 if (errno || (size_t)(end - str) != len) 8888 return -1; 8889 /* No need to validate action template mask value */ 8890 if (out->args.vc.masks) { 8891 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) 8892 compare_item->a.level = val; 8893 else 8894 compare_item->b.level = val; 8895 return len; 8896 } 8897 if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 8898 compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) || 8899 (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE && 8900 compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 8901 if (val >= FLEX_MAX_PARSERS_NUM) { 8902 printf("Bad flex item handle\n"); 8903 return -1; 8904 } 8905 fp = flex_items[ctx->port][val]; 8906 if (!fp) { 8907 printf("Bad flex item handle\n"); 8908 return -1; 8909 } 8910 } 8911 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) { 8912 if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM) 8913 compare_item->a.level = val; 8914 else 8915 compare_item->a.flex_handle = fp->flex_handle; 8916 } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) { 8917 if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM) 8918 compare_item->b.level = val; 8919 else 8920 compare_item->b.flex_handle = fp->flex_handle; 8921 } 8922 return len; 8923 } 8924 8925 /** Parse meter color action type. */ 8926 static int 8927 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 8928 const char *str, unsigned int len, 8929 void *buf, unsigned int size) 8930 { 8931 struct rte_flow_action *action_data; 8932 struct rte_flow_action_meter_color *conf; 8933 enum rte_color color; 8934 8935 (void)buf; 8936 (void)size; 8937 /* Token name must match. */ 8938 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8939 return -1; 8940 switch (ctx->curr) { 8941 case ACTION_METER_COLOR_GREEN: 8942 color = RTE_COLOR_GREEN; 8943 break; 8944 case ACTION_METER_COLOR_YELLOW: 8945 color = RTE_COLOR_YELLOW; 8946 break; 8947 case ACTION_METER_COLOR_RED: 8948 color = RTE_COLOR_RED; 8949 break; 8950 default: 8951 return -1; 8952 } 8953 8954 if (!ctx->object) 8955 return len; 8956 action_data = ctx->object; 8957 conf = (struct rte_flow_action_meter_color *) 8958 (uintptr_t)(action_data->conf); 8959 conf->color = color; 8960 return len; 8961 } 8962 8963 /** Parse RSS action. */ 8964 static int 8965 parse_vc_action_rss(struct context *ctx, const struct token *token, 8966 const char *str, unsigned int len, 8967 void *buf, unsigned int size) 8968 { 8969 struct buffer *out = buf; 8970 struct rte_flow_action *action; 8971 struct action_rss_data *action_rss_data; 8972 unsigned int i; 8973 int ret; 8974 8975 ret = parse_vc(ctx, token, str, len, buf, size); 8976 if (ret < 0) 8977 return ret; 8978 /* Nothing else to do if there is no buffer. */ 8979 if (!out) 8980 return ret; 8981 if (!out->args.vc.actions_n) 8982 return -1; 8983 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8984 /* Point to selected object. */ 8985 ctx->object = out->args.vc.data; 8986 ctx->objmask = NULL; 8987 /* Set up default configuration. */ 8988 action_rss_data = ctx->object; 8989 *action_rss_data = (struct action_rss_data){ 8990 .conf = (struct rte_flow_action_rss){ 8991 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 8992 .level = 0, 8993 .types = rss_hf, 8994 .key_len = 0, 8995 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 8996 .key = NULL, 8997 .queue = action_rss_data->queue, 8998 }, 8999 .queue = { 0 }, 9000 }; 9001 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 9002 action_rss_data->queue[i] = i; 9003 action->conf = &action_rss_data->conf; 9004 return ret; 9005 } 9006 9007 /** 9008 * Parse func field for RSS action. 9009 * 9010 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 9011 * ACTION_RSS_FUNC_* index that called this function. 9012 */ 9013 static int 9014 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 9015 const char *str, unsigned int len, 9016 void *buf, unsigned int size) 9017 { 9018 struct action_rss_data *action_rss_data; 9019 enum rte_eth_hash_function func; 9020 9021 (void)buf; 9022 (void)size; 9023 /* Token name must match. */ 9024 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9025 return -1; 9026 switch (ctx->curr) { 9027 case ACTION_RSS_FUNC_DEFAULT: 9028 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 9029 break; 9030 case ACTION_RSS_FUNC_TOEPLITZ: 9031 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 9032 break; 9033 case ACTION_RSS_FUNC_SIMPLE_XOR: 9034 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 9035 break; 9036 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 9037 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 9038 break; 9039 default: 9040 return -1; 9041 } 9042 if (!ctx->object) 9043 return len; 9044 action_rss_data = ctx->object; 9045 action_rss_data->conf.func = func; 9046 return len; 9047 } 9048 9049 /** 9050 * Parse type field for RSS action. 9051 * 9052 * Valid tokens are type field names and the "end" token. 9053 */ 9054 static int 9055 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 9056 const char *str, unsigned int len, 9057 void *buf, unsigned int size) 9058 { 9059 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 9060 struct action_rss_data *action_rss_data; 9061 unsigned int i; 9062 9063 (void)token; 9064 (void)buf; 9065 (void)size; 9066 if (ctx->curr != ACTION_RSS_TYPE) 9067 return -1; 9068 if (!(ctx->objdata >> 16) && ctx->object) { 9069 action_rss_data = ctx->object; 9070 action_rss_data->conf.types = 0; 9071 } 9072 if (!strcmp_partial("end", str, len)) { 9073 ctx->objdata &= 0xffff; 9074 return len; 9075 } 9076 for (i = 0; rss_type_table[i].str; ++i) 9077 if (!strcmp_partial(rss_type_table[i].str, str, len)) 9078 break; 9079 if (!rss_type_table[i].str) 9080 return -1; 9081 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 9082 /* Repeat token. */ 9083 if (ctx->next_num == RTE_DIM(ctx->next)) 9084 return -1; 9085 ctx->next[ctx->next_num++] = next; 9086 if (!ctx->object) 9087 return len; 9088 action_rss_data = ctx->object; 9089 action_rss_data->conf.types |= rss_type_table[i].rss_type; 9090 return len; 9091 } 9092 9093 /** 9094 * Parse queue field for RSS action. 9095 * 9096 * Valid tokens are queue indices and the "end" token. 9097 */ 9098 static int 9099 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 9100 const char *str, unsigned int len, 9101 void *buf, unsigned int size) 9102 { 9103 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 9104 struct action_rss_data *action_rss_data; 9105 const struct arg *arg; 9106 int ret; 9107 int i; 9108 9109 (void)token; 9110 (void)buf; 9111 (void)size; 9112 if (ctx->curr != ACTION_RSS_QUEUE) 9113 return -1; 9114 i = ctx->objdata >> 16; 9115 if (!strcmp_partial("end", str, len)) { 9116 ctx->objdata &= 0xffff; 9117 goto end; 9118 } 9119 if (i >= ACTION_RSS_QUEUE_NUM) 9120 return -1; 9121 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 9122 i * sizeof(action_rss_data->queue[i]), 9123 sizeof(action_rss_data->queue[i])); 9124 if (push_args(ctx, arg)) 9125 return -1; 9126 ret = parse_int(ctx, token, str, len, NULL, 0); 9127 if (ret < 0) { 9128 pop_args(ctx); 9129 return -1; 9130 } 9131 ++i; 9132 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 9133 /* Repeat token. */ 9134 if (ctx->next_num == RTE_DIM(ctx->next)) 9135 return -1; 9136 ctx->next[ctx->next_num++] = next; 9137 end: 9138 if (!ctx->object) 9139 return len; 9140 action_rss_data = ctx->object; 9141 action_rss_data->conf.queue_num = i; 9142 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 9143 return len; 9144 } 9145 9146 /** Setup VXLAN encap configuration. */ 9147 static int 9148 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 9149 { 9150 /* Set up default configuration. */ 9151 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 9152 .conf = (struct rte_flow_action_vxlan_encap){ 9153 .definition = action_vxlan_encap_data->items, 9154 }, 9155 .items = { 9156 { 9157 .type = RTE_FLOW_ITEM_TYPE_ETH, 9158 .spec = &action_vxlan_encap_data->item_eth, 9159 .mask = &rte_flow_item_eth_mask, 9160 }, 9161 { 9162 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9163 .spec = &action_vxlan_encap_data->item_vlan, 9164 .mask = &rte_flow_item_vlan_mask, 9165 }, 9166 { 9167 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9168 .spec = &action_vxlan_encap_data->item_ipv4, 9169 .mask = &rte_flow_item_ipv4_mask, 9170 }, 9171 { 9172 .type = RTE_FLOW_ITEM_TYPE_UDP, 9173 .spec = &action_vxlan_encap_data->item_udp, 9174 .mask = &rte_flow_item_udp_mask, 9175 }, 9176 { 9177 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 9178 .spec = &action_vxlan_encap_data->item_vxlan, 9179 .mask = &rte_flow_item_vxlan_mask, 9180 }, 9181 { 9182 .type = RTE_FLOW_ITEM_TYPE_END, 9183 }, 9184 }, 9185 .item_eth.hdr.ether_type = 0, 9186 .item_vlan = { 9187 .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, 9188 .hdr.eth_proto = 0, 9189 }, 9190 .item_ipv4.hdr = { 9191 .src_addr = vxlan_encap_conf.ipv4_src, 9192 .dst_addr = vxlan_encap_conf.ipv4_dst, 9193 }, 9194 .item_udp.hdr = { 9195 .src_port = vxlan_encap_conf.udp_src, 9196 .dst_port = vxlan_encap_conf.udp_dst, 9197 }, 9198 .item_vxlan.hdr.flags = 0, 9199 }; 9200 memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9201 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9202 memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, 9203 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9204 if (!vxlan_encap_conf.select_ipv4) { 9205 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 9206 &vxlan_encap_conf.ipv6_src, 9207 sizeof(vxlan_encap_conf.ipv6_src)); 9208 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 9209 &vxlan_encap_conf.ipv6_dst, 9210 sizeof(vxlan_encap_conf.ipv6_dst)); 9211 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 9212 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9213 .spec = &action_vxlan_encap_data->item_ipv6, 9214 .mask = &rte_flow_item_ipv6_mask, 9215 }; 9216 } 9217 if (!vxlan_encap_conf.select_vlan) 9218 action_vxlan_encap_data->items[1].type = 9219 RTE_FLOW_ITEM_TYPE_VOID; 9220 if (vxlan_encap_conf.select_tos_ttl) { 9221 if (vxlan_encap_conf.select_ipv4) { 9222 static struct rte_flow_item_ipv4 ipv4_mask_tos; 9223 9224 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 9225 sizeof(ipv4_mask_tos)); 9226 ipv4_mask_tos.hdr.type_of_service = 0xff; 9227 ipv4_mask_tos.hdr.time_to_live = 0xff; 9228 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 9229 vxlan_encap_conf.ip_tos; 9230 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 9231 vxlan_encap_conf.ip_ttl; 9232 action_vxlan_encap_data->items[2].mask = 9233 &ipv4_mask_tos; 9234 } else { 9235 static struct rte_flow_item_ipv6 ipv6_mask_tos; 9236 9237 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 9238 sizeof(ipv6_mask_tos)); 9239 ipv6_mask_tos.hdr.vtc_flow |= 9240 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 9241 ipv6_mask_tos.hdr.hop_limits = 0xff; 9242 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 9243 rte_cpu_to_be_32 9244 ((uint32_t)vxlan_encap_conf.ip_tos << 9245 RTE_IPV6_HDR_TC_SHIFT); 9246 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 9247 vxlan_encap_conf.ip_ttl; 9248 action_vxlan_encap_data->items[2].mask = 9249 &ipv6_mask_tos; 9250 } 9251 } 9252 memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, 9253 RTE_DIM(vxlan_encap_conf.vni)); 9254 return 0; 9255 } 9256 9257 /** Parse VXLAN encap action. */ 9258 static int 9259 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 9260 const char *str, unsigned int len, 9261 void *buf, unsigned int size) 9262 { 9263 struct buffer *out = buf; 9264 struct rte_flow_action *action; 9265 struct action_vxlan_encap_data *action_vxlan_encap_data; 9266 int ret; 9267 9268 ret = parse_vc(ctx, token, str, len, buf, size); 9269 if (ret < 0) 9270 return ret; 9271 /* Nothing else to do if there is no buffer. */ 9272 if (!out) 9273 return ret; 9274 if (!out->args.vc.actions_n) 9275 return -1; 9276 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9277 /* Point to selected object. */ 9278 ctx->object = out->args.vc.data; 9279 ctx->objmask = NULL; 9280 action_vxlan_encap_data = ctx->object; 9281 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 9282 action->conf = &action_vxlan_encap_data->conf; 9283 return ret; 9284 } 9285 9286 /** Setup NVGRE encap configuration. */ 9287 static int 9288 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 9289 { 9290 /* Set up default configuration. */ 9291 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 9292 .conf = (struct rte_flow_action_nvgre_encap){ 9293 .definition = action_nvgre_encap_data->items, 9294 }, 9295 .items = { 9296 { 9297 .type = RTE_FLOW_ITEM_TYPE_ETH, 9298 .spec = &action_nvgre_encap_data->item_eth, 9299 .mask = &rte_flow_item_eth_mask, 9300 }, 9301 { 9302 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9303 .spec = &action_nvgre_encap_data->item_vlan, 9304 .mask = &rte_flow_item_vlan_mask, 9305 }, 9306 { 9307 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9308 .spec = &action_nvgre_encap_data->item_ipv4, 9309 .mask = &rte_flow_item_ipv4_mask, 9310 }, 9311 { 9312 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 9313 .spec = &action_nvgre_encap_data->item_nvgre, 9314 .mask = &rte_flow_item_nvgre_mask, 9315 }, 9316 { 9317 .type = RTE_FLOW_ITEM_TYPE_END, 9318 }, 9319 }, 9320 .item_eth.hdr.ether_type = 0, 9321 .item_vlan = { 9322 .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, 9323 .hdr.eth_proto = 0, 9324 }, 9325 .item_ipv4.hdr = { 9326 .src_addr = nvgre_encap_conf.ipv4_src, 9327 .dst_addr = nvgre_encap_conf.ipv4_dst, 9328 }, 9329 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 9330 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 9331 .item_nvgre.flow_id = 0, 9332 }; 9333 memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9334 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9335 memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, 9336 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9337 if (!nvgre_encap_conf.select_ipv4) { 9338 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 9339 &nvgre_encap_conf.ipv6_src, 9340 sizeof(nvgre_encap_conf.ipv6_src)); 9341 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 9342 &nvgre_encap_conf.ipv6_dst, 9343 sizeof(nvgre_encap_conf.ipv6_dst)); 9344 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 9345 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9346 .spec = &action_nvgre_encap_data->item_ipv6, 9347 .mask = &rte_flow_item_ipv6_mask, 9348 }; 9349 } 9350 if (!nvgre_encap_conf.select_vlan) 9351 action_nvgre_encap_data->items[1].type = 9352 RTE_FLOW_ITEM_TYPE_VOID; 9353 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 9354 RTE_DIM(nvgre_encap_conf.tni)); 9355 return 0; 9356 } 9357 9358 /** Parse NVGRE encap action. */ 9359 static int 9360 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 9361 const char *str, unsigned int len, 9362 void *buf, unsigned int size) 9363 { 9364 struct buffer *out = buf; 9365 struct rte_flow_action *action; 9366 struct action_nvgre_encap_data *action_nvgre_encap_data; 9367 int ret; 9368 9369 ret = parse_vc(ctx, token, str, len, buf, size); 9370 if (ret < 0) 9371 return ret; 9372 /* Nothing else to do if there is no buffer. */ 9373 if (!out) 9374 return ret; 9375 if (!out->args.vc.actions_n) 9376 return -1; 9377 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9378 /* Point to selected object. */ 9379 ctx->object = out->args.vc.data; 9380 ctx->objmask = NULL; 9381 action_nvgre_encap_data = ctx->object; 9382 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 9383 action->conf = &action_nvgre_encap_data->conf; 9384 return ret; 9385 } 9386 9387 /** Parse l2 encap action. */ 9388 static int 9389 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 9390 const char *str, unsigned int len, 9391 void *buf, unsigned int size) 9392 { 9393 struct buffer *out = buf; 9394 struct rte_flow_action *action; 9395 struct action_raw_encap_data *action_encap_data; 9396 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9397 struct rte_flow_item_vlan vlan = { 9398 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9399 .hdr.eth_proto = 0, 9400 }; 9401 uint8_t *header; 9402 int ret; 9403 9404 ret = parse_vc(ctx, token, str, len, buf, size); 9405 if (ret < 0) 9406 return ret; 9407 /* Nothing else to do if there is no buffer. */ 9408 if (!out) 9409 return ret; 9410 if (!out->args.vc.actions_n) 9411 return -1; 9412 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9413 /* Point to selected object. */ 9414 ctx->object = out->args.vc.data; 9415 ctx->objmask = NULL; 9416 /* Copy the headers to the buffer. */ 9417 action_encap_data = ctx->object; 9418 *action_encap_data = (struct action_raw_encap_data) { 9419 .conf = (struct rte_flow_action_raw_encap){ 9420 .data = action_encap_data->data, 9421 }, 9422 .data = {}, 9423 }; 9424 header = action_encap_data->data; 9425 if (l2_encap_conf.select_vlan) 9426 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9427 else if (l2_encap_conf.select_ipv4) 9428 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9429 else 9430 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9431 memcpy(eth.hdr.dst_addr.addr_bytes, 9432 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9433 memcpy(eth.hdr.src_addr.addr_bytes, 9434 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9435 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9436 header += sizeof(struct rte_ether_hdr); 9437 if (l2_encap_conf.select_vlan) { 9438 if (l2_encap_conf.select_ipv4) 9439 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9440 else 9441 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9442 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9443 header += sizeof(struct rte_vlan_hdr); 9444 } 9445 action_encap_data->conf.size = header - 9446 action_encap_data->data; 9447 action->conf = &action_encap_data->conf; 9448 return ret; 9449 } 9450 9451 /** Parse l2 decap action. */ 9452 static int 9453 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 9454 const char *str, unsigned int len, 9455 void *buf, unsigned int size) 9456 { 9457 struct buffer *out = buf; 9458 struct rte_flow_action *action; 9459 struct action_raw_decap_data *action_decap_data; 9460 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9461 struct rte_flow_item_vlan vlan = { 9462 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9463 .hdr.eth_proto = 0, 9464 }; 9465 uint8_t *header; 9466 int ret; 9467 9468 ret = parse_vc(ctx, token, str, len, buf, size); 9469 if (ret < 0) 9470 return ret; 9471 /* Nothing else to do if there is no buffer. */ 9472 if (!out) 9473 return ret; 9474 if (!out->args.vc.actions_n) 9475 return -1; 9476 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9477 /* Point to selected object. */ 9478 ctx->object = out->args.vc.data; 9479 ctx->objmask = NULL; 9480 /* Copy the headers to the buffer. */ 9481 action_decap_data = ctx->object; 9482 *action_decap_data = (struct action_raw_decap_data) { 9483 .conf = (struct rte_flow_action_raw_decap){ 9484 .data = action_decap_data->data, 9485 }, 9486 .data = {}, 9487 }; 9488 header = action_decap_data->data; 9489 if (l2_decap_conf.select_vlan) 9490 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9491 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9492 header += sizeof(struct rte_ether_hdr); 9493 if (l2_decap_conf.select_vlan) { 9494 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9495 header += sizeof(struct rte_vlan_hdr); 9496 } 9497 action_decap_data->conf.size = header - 9498 action_decap_data->data; 9499 action->conf = &action_decap_data->conf; 9500 return ret; 9501 } 9502 9503 #define ETHER_TYPE_MPLS_UNICAST 0x8847 9504 9505 /** Parse MPLSOGRE encap action. */ 9506 static int 9507 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 9508 const char *str, unsigned int len, 9509 void *buf, unsigned int size) 9510 { 9511 struct buffer *out = buf; 9512 struct rte_flow_action *action; 9513 struct action_raw_encap_data *action_encap_data; 9514 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9515 struct rte_flow_item_vlan vlan = { 9516 .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, 9517 .hdr.eth_proto = 0, 9518 }; 9519 struct rte_flow_item_ipv4 ipv4 = { 9520 .hdr = { 9521 .src_addr = mplsogre_encap_conf.ipv4_src, 9522 .dst_addr = mplsogre_encap_conf.ipv4_dst, 9523 .next_proto_id = IPPROTO_GRE, 9524 .version_ihl = RTE_IPV4_VHL_DEF, 9525 .time_to_live = IPDEFTTL, 9526 }, 9527 }; 9528 struct rte_flow_item_ipv6 ipv6 = { 9529 .hdr = { 9530 .proto = IPPROTO_GRE, 9531 .hop_limits = IPDEFTTL, 9532 }, 9533 }; 9534 struct rte_flow_item_gre gre = { 9535 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9536 }; 9537 struct rte_flow_item_mpls mpls = { 9538 .ttl = 0, 9539 }; 9540 uint8_t *header; 9541 int ret; 9542 9543 ret = parse_vc(ctx, token, str, len, buf, size); 9544 if (ret < 0) 9545 return ret; 9546 /* Nothing else to do if there is no buffer. */ 9547 if (!out) 9548 return ret; 9549 if (!out->args.vc.actions_n) 9550 return -1; 9551 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9552 /* Point to selected object. */ 9553 ctx->object = out->args.vc.data; 9554 ctx->objmask = NULL; 9555 /* Copy the headers to the buffer. */ 9556 action_encap_data = ctx->object; 9557 *action_encap_data = (struct action_raw_encap_data) { 9558 .conf = (struct rte_flow_action_raw_encap){ 9559 .data = action_encap_data->data, 9560 }, 9561 .data = {}, 9562 .preserve = {}, 9563 }; 9564 header = action_encap_data->data; 9565 if (mplsogre_encap_conf.select_vlan) 9566 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9567 else if (mplsogre_encap_conf.select_ipv4) 9568 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9569 else 9570 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9571 memcpy(eth.hdr.dst_addr.addr_bytes, 9572 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9573 memcpy(eth.hdr.src_addr.addr_bytes, 9574 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9575 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9576 header += sizeof(struct rte_ether_hdr); 9577 if (mplsogre_encap_conf.select_vlan) { 9578 if (mplsogre_encap_conf.select_ipv4) 9579 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9580 else 9581 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9582 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9583 header += sizeof(struct rte_vlan_hdr); 9584 } 9585 if (mplsogre_encap_conf.select_ipv4) { 9586 memcpy(header, &ipv4, sizeof(ipv4)); 9587 header += sizeof(ipv4); 9588 } else { 9589 memcpy(&ipv6.hdr.src_addr, 9590 &mplsogre_encap_conf.ipv6_src, 9591 sizeof(mplsogre_encap_conf.ipv6_src)); 9592 memcpy(&ipv6.hdr.dst_addr, 9593 &mplsogre_encap_conf.ipv6_dst, 9594 sizeof(mplsogre_encap_conf.ipv6_dst)); 9595 memcpy(header, &ipv6, sizeof(ipv6)); 9596 header += sizeof(ipv6); 9597 } 9598 memcpy(header, &gre, sizeof(gre)); 9599 header += sizeof(gre); 9600 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 9601 RTE_DIM(mplsogre_encap_conf.label)); 9602 mpls.label_tc_s[2] |= 0x1; 9603 memcpy(header, &mpls, sizeof(mpls)); 9604 header += sizeof(mpls); 9605 action_encap_data->conf.size = header - 9606 action_encap_data->data; 9607 action->conf = &action_encap_data->conf; 9608 return ret; 9609 } 9610 9611 /** Parse MPLSOGRE decap action. */ 9612 static int 9613 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 9614 const char *str, unsigned int len, 9615 void *buf, unsigned int size) 9616 { 9617 struct buffer *out = buf; 9618 struct rte_flow_action *action; 9619 struct action_raw_decap_data *action_decap_data; 9620 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9621 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9622 struct rte_flow_item_ipv4 ipv4 = { 9623 .hdr = { 9624 .next_proto_id = IPPROTO_GRE, 9625 }, 9626 }; 9627 struct rte_flow_item_ipv6 ipv6 = { 9628 .hdr = { 9629 .proto = IPPROTO_GRE, 9630 }, 9631 }; 9632 struct rte_flow_item_gre gre = { 9633 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9634 }; 9635 struct rte_flow_item_mpls mpls; 9636 uint8_t *header; 9637 int ret; 9638 9639 ret = parse_vc(ctx, token, str, len, buf, size); 9640 if (ret < 0) 9641 return ret; 9642 /* Nothing else to do if there is no buffer. */ 9643 if (!out) 9644 return ret; 9645 if (!out->args.vc.actions_n) 9646 return -1; 9647 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9648 /* Point to selected object. */ 9649 ctx->object = out->args.vc.data; 9650 ctx->objmask = NULL; 9651 /* Copy the headers to the buffer. */ 9652 action_decap_data = ctx->object; 9653 *action_decap_data = (struct action_raw_decap_data) { 9654 .conf = (struct rte_flow_action_raw_decap){ 9655 .data = action_decap_data->data, 9656 }, 9657 .data = {}, 9658 }; 9659 header = action_decap_data->data; 9660 if (mplsogre_decap_conf.select_vlan) 9661 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9662 else if (mplsogre_encap_conf.select_ipv4) 9663 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9664 else 9665 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9666 memcpy(eth.hdr.dst_addr.addr_bytes, 9667 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9668 memcpy(eth.hdr.src_addr.addr_bytes, 9669 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9670 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9671 header += sizeof(struct rte_ether_hdr); 9672 if (mplsogre_encap_conf.select_vlan) { 9673 if (mplsogre_encap_conf.select_ipv4) 9674 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9675 else 9676 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9677 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9678 header += sizeof(struct rte_vlan_hdr); 9679 } 9680 if (mplsogre_encap_conf.select_ipv4) { 9681 memcpy(header, &ipv4, sizeof(ipv4)); 9682 header += sizeof(ipv4); 9683 } else { 9684 memcpy(header, &ipv6, sizeof(ipv6)); 9685 header += sizeof(ipv6); 9686 } 9687 memcpy(header, &gre, sizeof(gre)); 9688 header += sizeof(gre); 9689 memset(&mpls, 0, sizeof(mpls)); 9690 memcpy(header, &mpls, sizeof(mpls)); 9691 header += sizeof(mpls); 9692 action_decap_data->conf.size = header - 9693 action_decap_data->data; 9694 action->conf = &action_decap_data->conf; 9695 return ret; 9696 } 9697 9698 /** Parse MPLSOUDP encap action. */ 9699 static int 9700 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 9701 const char *str, unsigned int len, 9702 void *buf, unsigned int size) 9703 { 9704 struct buffer *out = buf; 9705 struct rte_flow_action *action; 9706 struct action_raw_encap_data *action_encap_data; 9707 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9708 struct rte_flow_item_vlan vlan = { 9709 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9710 .hdr.eth_proto = 0, 9711 }; 9712 struct rte_flow_item_ipv4 ipv4 = { 9713 .hdr = { 9714 .src_addr = mplsoudp_encap_conf.ipv4_src, 9715 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 9716 .next_proto_id = IPPROTO_UDP, 9717 .version_ihl = RTE_IPV4_VHL_DEF, 9718 .time_to_live = IPDEFTTL, 9719 }, 9720 }; 9721 struct rte_flow_item_ipv6 ipv6 = { 9722 .hdr = { 9723 .proto = IPPROTO_UDP, 9724 .hop_limits = IPDEFTTL, 9725 }, 9726 }; 9727 struct rte_flow_item_udp udp = { 9728 .hdr = { 9729 .src_port = mplsoudp_encap_conf.udp_src, 9730 .dst_port = mplsoudp_encap_conf.udp_dst, 9731 }, 9732 }; 9733 struct rte_flow_item_mpls mpls; 9734 uint8_t *header; 9735 int ret; 9736 9737 ret = parse_vc(ctx, token, str, len, buf, size); 9738 if (ret < 0) 9739 return ret; 9740 /* Nothing else to do if there is no buffer. */ 9741 if (!out) 9742 return ret; 9743 if (!out->args.vc.actions_n) 9744 return -1; 9745 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9746 /* Point to selected object. */ 9747 ctx->object = out->args.vc.data; 9748 ctx->objmask = NULL; 9749 /* Copy the headers to the buffer. */ 9750 action_encap_data = ctx->object; 9751 *action_encap_data = (struct action_raw_encap_data) { 9752 .conf = (struct rte_flow_action_raw_encap){ 9753 .data = action_encap_data->data, 9754 }, 9755 .data = {}, 9756 .preserve = {}, 9757 }; 9758 header = action_encap_data->data; 9759 if (mplsoudp_encap_conf.select_vlan) 9760 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9761 else if (mplsoudp_encap_conf.select_ipv4) 9762 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9763 else 9764 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9765 memcpy(eth.hdr.dst_addr.addr_bytes, 9766 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9767 memcpy(eth.hdr.src_addr.addr_bytes, 9768 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9769 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9770 header += sizeof(struct rte_ether_hdr); 9771 if (mplsoudp_encap_conf.select_vlan) { 9772 if (mplsoudp_encap_conf.select_ipv4) 9773 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9774 else 9775 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9776 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9777 header += sizeof(struct rte_vlan_hdr); 9778 } 9779 if (mplsoudp_encap_conf.select_ipv4) { 9780 memcpy(header, &ipv4, sizeof(ipv4)); 9781 header += sizeof(ipv4); 9782 } else { 9783 memcpy(&ipv6.hdr.src_addr, 9784 &mplsoudp_encap_conf.ipv6_src, 9785 sizeof(mplsoudp_encap_conf.ipv6_src)); 9786 memcpy(&ipv6.hdr.dst_addr, 9787 &mplsoudp_encap_conf.ipv6_dst, 9788 sizeof(mplsoudp_encap_conf.ipv6_dst)); 9789 memcpy(header, &ipv6, sizeof(ipv6)); 9790 header += sizeof(ipv6); 9791 } 9792 memcpy(header, &udp, sizeof(udp)); 9793 header += sizeof(udp); 9794 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 9795 RTE_DIM(mplsoudp_encap_conf.label)); 9796 mpls.label_tc_s[2] |= 0x1; 9797 memcpy(header, &mpls, sizeof(mpls)); 9798 header += sizeof(mpls); 9799 action_encap_data->conf.size = header - 9800 action_encap_data->data; 9801 action->conf = &action_encap_data->conf; 9802 return ret; 9803 } 9804 9805 /** Parse MPLSOUDP decap action. */ 9806 static int 9807 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 9808 const char *str, unsigned int len, 9809 void *buf, unsigned int size) 9810 { 9811 struct buffer *out = buf; 9812 struct rte_flow_action *action; 9813 struct action_raw_decap_data *action_decap_data; 9814 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9815 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9816 struct rte_flow_item_ipv4 ipv4 = { 9817 .hdr = { 9818 .next_proto_id = IPPROTO_UDP, 9819 }, 9820 }; 9821 struct rte_flow_item_ipv6 ipv6 = { 9822 .hdr = { 9823 .proto = IPPROTO_UDP, 9824 }, 9825 }; 9826 struct rte_flow_item_udp udp = { 9827 .hdr = { 9828 .dst_port = rte_cpu_to_be_16(6635), 9829 }, 9830 }; 9831 struct rte_flow_item_mpls mpls; 9832 uint8_t *header; 9833 int ret; 9834 9835 ret = parse_vc(ctx, token, str, len, buf, size); 9836 if (ret < 0) 9837 return ret; 9838 /* Nothing else to do if there is no buffer. */ 9839 if (!out) 9840 return ret; 9841 if (!out->args.vc.actions_n) 9842 return -1; 9843 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9844 /* Point to selected object. */ 9845 ctx->object = out->args.vc.data; 9846 ctx->objmask = NULL; 9847 /* Copy the headers to the buffer. */ 9848 action_decap_data = ctx->object; 9849 *action_decap_data = (struct action_raw_decap_data) { 9850 .conf = (struct rte_flow_action_raw_decap){ 9851 .data = action_decap_data->data, 9852 }, 9853 .data = {}, 9854 }; 9855 header = action_decap_data->data; 9856 if (mplsoudp_decap_conf.select_vlan) 9857 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9858 else if (mplsoudp_encap_conf.select_ipv4) 9859 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9860 else 9861 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9862 memcpy(eth.hdr.dst_addr.addr_bytes, 9863 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9864 memcpy(eth.hdr.src_addr.addr_bytes, 9865 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9866 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9867 header += sizeof(struct rte_ether_hdr); 9868 if (mplsoudp_encap_conf.select_vlan) { 9869 if (mplsoudp_encap_conf.select_ipv4) 9870 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9871 else 9872 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9873 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9874 header += sizeof(struct rte_vlan_hdr); 9875 } 9876 if (mplsoudp_encap_conf.select_ipv4) { 9877 memcpy(header, &ipv4, sizeof(ipv4)); 9878 header += sizeof(ipv4); 9879 } else { 9880 memcpy(header, &ipv6, sizeof(ipv6)); 9881 header += sizeof(ipv6); 9882 } 9883 memcpy(header, &udp, sizeof(udp)); 9884 header += sizeof(udp); 9885 memset(&mpls, 0, sizeof(mpls)); 9886 memcpy(header, &mpls, sizeof(mpls)); 9887 header += sizeof(mpls); 9888 action_decap_data->conf.size = header - 9889 action_decap_data->data; 9890 action->conf = &action_decap_data->conf; 9891 return ret; 9892 } 9893 9894 static int 9895 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 9896 const char *str, unsigned int len, void *buf, 9897 unsigned int size) 9898 { 9899 struct action_raw_decap_data *action_raw_decap_data; 9900 struct rte_flow_action *action; 9901 const struct arg *arg; 9902 struct buffer *out = buf; 9903 int ret; 9904 uint16_t idx; 9905 9906 RTE_SET_USED(token); 9907 RTE_SET_USED(buf); 9908 RTE_SET_USED(size); 9909 arg = ARGS_ENTRY_ARB_BOUNDED 9910 (offsetof(struct action_raw_decap_data, idx), 9911 sizeof(((struct action_raw_decap_data *)0)->idx), 9912 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 9913 if (push_args(ctx, arg)) 9914 return -1; 9915 ret = parse_int(ctx, token, str, len, NULL, 0); 9916 if (ret < 0) { 9917 pop_args(ctx); 9918 return -1; 9919 } 9920 if (!ctx->object) 9921 return len; 9922 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9923 action_raw_decap_data = ctx->object; 9924 idx = action_raw_decap_data->idx; 9925 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 9926 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 9927 action->conf = &action_raw_decap_data->conf; 9928 return len; 9929 } 9930 9931 9932 static int 9933 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 9934 const char *str, unsigned int len, void *buf, 9935 unsigned int size) 9936 { 9937 struct action_raw_encap_data *action_raw_encap_data; 9938 struct rte_flow_action *action; 9939 const struct arg *arg; 9940 struct buffer *out = buf; 9941 int ret; 9942 uint16_t idx; 9943 9944 RTE_SET_USED(token); 9945 RTE_SET_USED(buf); 9946 RTE_SET_USED(size); 9947 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 9948 return -1; 9949 arg = ARGS_ENTRY_ARB_BOUNDED 9950 (offsetof(struct action_raw_encap_data, idx), 9951 sizeof(((struct action_raw_encap_data *)0)->idx), 9952 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 9953 if (push_args(ctx, arg)) 9954 return -1; 9955 ret = parse_int(ctx, token, str, len, NULL, 0); 9956 if (ret < 0) { 9957 pop_args(ctx); 9958 return -1; 9959 } 9960 if (!ctx->object) 9961 return len; 9962 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9963 action_raw_encap_data = ctx->object; 9964 idx = action_raw_encap_data->idx; 9965 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 9966 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 9967 action_raw_encap_data->conf.preserve = NULL; 9968 action->conf = &action_raw_encap_data->conf; 9969 return len; 9970 } 9971 9972 static int 9973 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 9974 const char *str, unsigned int len, void *buf, 9975 unsigned int size) 9976 { 9977 struct buffer *out = buf; 9978 int ret; 9979 9980 ret = parse_vc(ctx, token, str, len, buf, size); 9981 if (ret < 0) 9982 return ret; 9983 /* Nothing else to do if there is no buffer. */ 9984 if (!out) 9985 return ret; 9986 if (!out->args.vc.actions_n) 9987 return -1; 9988 /* Point to selected object. */ 9989 ctx->object = out->args.vc.data; 9990 ctx->objmask = NULL; 9991 return ret; 9992 } 9993 9994 static int 9995 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 9996 const char *str, unsigned int len, void *buf, 9997 unsigned int size) 9998 { 9999 struct buffer *out = buf; 10000 struct rte_flow_action *action; 10001 struct action_raw_decap_data *action_raw_decap_data = NULL; 10002 int ret; 10003 10004 ret = parse_vc(ctx, token, str, len, buf, size); 10005 if (ret < 0) 10006 return ret; 10007 /* Nothing else to do if there is no buffer. */ 10008 if (!out) 10009 return ret; 10010 if (!out->args.vc.actions_n) 10011 return -1; 10012 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10013 /* Point to selected object. */ 10014 ctx->object = out->args.vc.data; 10015 ctx->objmask = NULL; 10016 /* Copy the headers to the buffer. */ 10017 action_raw_decap_data = ctx->object; 10018 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 10019 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 10020 action->conf = &action_raw_decap_data->conf; 10021 return ret; 10022 } 10023 10024 static int 10025 parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 10026 const char *str, unsigned int len, void *buf, 10027 unsigned int size) 10028 { 10029 struct buffer *out = buf; 10030 struct rte_flow_action *action; 10031 struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; 10032 int ret; 10033 10034 ret = parse_vc(ctx, token, str, len, buf, size); 10035 if (ret < 0) 10036 return ret; 10037 /* Nothing else to do if there is no buffer. */ 10038 if (!out) 10039 return ret; 10040 if (!out->args.vc.actions_n) 10041 return -1; 10042 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10043 /* Point to selected object. */ 10044 ctx->object = out->args.vc.data; 10045 ctx->objmask = NULL; 10046 /* Copy the headers to the buffer. */ 10047 ipv6_ext_remove_data = ctx->object; 10048 ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; 10049 action->conf = &ipv6_ext_remove_data->conf; 10050 return ret; 10051 } 10052 10053 static int 10054 parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, 10055 const char *str, unsigned int len, void *buf, 10056 unsigned int size) 10057 { 10058 struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; 10059 struct rte_flow_action *action; 10060 const struct arg *arg; 10061 struct buffer *out = buf; 10062 int ret; 10063 uint16_t idx; 10064 10065 RTE_SET_USED(token); 10066 RTE_SET_USED(buf); 10067 RTE_SET_USED(size); 10068 arg = ARGS_ENTRY_ARB_BOUNDED 10069 (offsetof(struct action_ipv6_ext_remove_data, idx), 10070 sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), 10071 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10072 if (push_args(ctx, arg)) 10073 return -1; 10074 ret = parse_int(ctx, token, str, len, NULL, 0); 10075 if (ret < 0) { 10076 pop_args(ctx); 10077 return -1; 10078 } 10079 if (!ctx->object) 10080 return len; 10081 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10082 action_ipv6_ext_remove_data = ctx->object; 10083 idx = action_ipv6_ext_remove_data->idx; 10084 action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; 10085 action->conf = &action_ipv6_ext_remove_data->conf; 10086 return len; 10087 } 10088 10089 static int 10090 parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 10091 const char *str, unsigned int len, void *buf, 10092 unsigned int size) 10093 { 10094 struct buffer *out = buf; 10095 struct rte_flow_action *action; 10096 struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; 10097 int ret; 10098 10099 ret = parse_vc(ctx, token, str, len, buf, size); 10100 if (ret < 0) 10101 return ret; 10102 /* Nothing else to do if there is no buffer. */ 10103 if (!out) 10104 return ret; 10105 if (!out->args.vc.actions_n) 10106 return -1; 10107 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10108 /* Point to selected object. */ 10109 ctx->object = out->args.vc.data; 10110 ctx->objmask = NULL; 10111 /* Copy the headers to the buffer. */ 10112 ipv6_ext_push_data = ctx->object; 10113 ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; 10114 ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; 10115 ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; 10116 action->conf = &ipv6_ext_push_data->conf; 10117 return ret; 10118 } 10119 10120 static int 10121 parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, 10122 const char *str, unsigned int len, void *buf, 10123 unsigned int size) 10124 { 10125 struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; 10126 struct rte_flow_action *action; 10127 const struct arg *arg; 10128 struct buffer *out = buf; 10129 int ret; 10130 uint16_t idx; 10131 10132 RTE_SET_USED(token); 10133 RTE_SET_USED(buf); 10134 RTE_SET_USED(size); 10135 arg = ARGS_ENTRY_ARB_BOUNDED 10136 (offsetof(struct action_ipv6_ext_push_data, idx), 10137 sizeof(((struct action_ipv6_ext_push_data *)0)->idx), 10138 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10139 if (push_args(ctx, arg)) 10140 return -1; 10141 ret = parse_int(ctx, token, str, len, NULL, 0); 10142 if (ret < 0) { 10143 pop_args(ctx); 10144 return -1; 10145 } 10146 if (!ctx->object) 10147 return len; 10148 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10149 action_ipv6_ext_push_data = ctx->object; 10150 idx = action_ipv6_ext_push_data->idx; 10151 action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; 10152 action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; 10153 action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; 10154 action->conf = &action_ipv6_ext_push_data->conf; 10155 return len; 10156 } 10157 10158 static int 10159 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 10160 const char *str, unsigned int len, void *buf, 10161 unsigned int size) 10162 { 10163 int ret; 10164 10165 ret = parse_vc(ctx, token, str, len, buf, size); 10166 if (ret < 0) 10167 return ret; 10168 ret = rte_flow_dynf_metadata_register(); 10169 if (ret < 0) 10170 return -1; 10171 return len; 10172 } 10173 10174 static int 10175 parse_vc_action_sample(struct context *ctx, const struct token *token, 10176 const char *str, unsigned int len, void *buf, 10177 unsigned int size) 10178 { 10179 struct buffer *out = buf; 10180 struct rte_flow_action *action; 10181 struct action_sample_data *action_sample_data = NULL; 10182 static struct rte_flow_action end_action = { 10183 RTE_FLOW_ACTION_TYPE_END, 0 10184 }; 10185 int ret; 10186 10187 ret = parse_vc(ctx, token, str, len, buf, size); 10188 if (ret < 0) 10189 return ret; 10190 /* Nothing else to do if there is no buffer. */ 10191 if (!out) 10192 return ret; 10193 if (!out->args.vc.actions_n) 10194 return -1; 10195 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10196 /* Point to selected object. */ 10197 ctx->object = out->args.vc.data; 10198 ctx->objmask = NULL; 10199 /* Copy the headers to the buffer. */ 10200 action_sample_data = ctx->object; 10201 action_sample_data->conf.actions = &end_action; 10202 action->conf = &action_sample_data->conf; 10203 return ret; 10204 } 10205 10206 static int 10207 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 10208 const char *str, unsigned int len, void *buf, 10209 unsigned int size) 10210 { 10211 struct action_sample_data *action_sample_data; 10212 struct rte_flow_action *action; 10213 const struct arg *arg; 10214 struct buffer *out = buf; 10215 int ret; 10216 uint16_t idx; 10217 10218 RTE_SET_USED(token); 10219 RTE_SET_USED(buf); 10220 RTE_SET_USED(size); 10221 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 10222 return -1; 10223 arg = ARGS_ENTRY_ARB_BOUNDED 10224 (offsetof(struct action_sample_data, idx), 10225 sizeof(((struct action_sample_data *)0)->idx), 10226 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 10227 if (push_args(ctx, arg)) 10228 return -1; 10229 ret = parse_int(ctx, token, str, len, NULL, 0); 10230 if (ret < 0) { 10231 pop_args(ctx); 10232 return -1; 10233 } 10234 if (!ctx->object) 10235 return len; 10236 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10237 action_sample_data = ctx->object; 10238 idx = action_sample_data->idx; 10239 action_sample_data->conf.actions = raw_sample_confs[idx].data; 10240 action->conf = &action_sample_data->conf; 10241 return len; 10242 } 10243 10244 /** Parse operation for modify_field command. */ 10245 static int 10246 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 10247 const char *str, unsigned int len, void *buf, 10248 unsigned int size) 10249 { 10250 struct rte_flow_action_modify_field *action_modify_field; 10251 unsigned int i; 10252 10253 (void)token; 10254 (void)buf; 10255 (void)size; 10256 if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) 10257 return -1; 10258 for (i = 0; modify_field_ops[i]; ++i) 10259 if (!strcmp_partial(modify_field_ops[i], str, len)) 10260 break; 10261 if (!modify_field_ops[i]) 10262 return -1; 10263 if (!ctx->object) 10264 return len; 10265 action_modify_field = ctx->object; 10266 action_modify_field->operation = (enum rte_flow_modify_op)i; 10267 return len; 10268 } 10269 10270 /** Parse id for modify_field command. */ 10271 static int 10272 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 10273 const char *str, unsigned int len, void *buf, 10274 unsigned int size) 10275 { 10276 struct rte_flow_action_modify_field *action_modify_field; 10277 unsigned int i; 10278 10279 (void)token; 10280 (void)buf; 10281 (void)size; 10282 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 10283 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 10284 return -1; 10285 for (i = 0; flow_field_ids[i]; ++i) 10286 if (!strcmp_partial(flow_field_ids[i], str, len)) 10287 break; 10288 if (!flow_field_ids[i]) 10289 return -1; 10290 if (!ctx->object) 10291 return len; 10292 action_modify_field = ctx->object; 10293 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 10294 action_modify_field->dst.field = (enum rte_flow_field_id)i; 10295 else 10296 action_modify_field->src.field = (enum rte_flow_field_id)i; 10297 return len; 10298 } 10299 10300 /** Parse level for modify_field command. */ 10301 static int 10302 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 10303 const char *str, unsigned int len, void *buf, 10304 unsigned int size) 10305 { 10306 struct rte_flow_action_modify_field *action; 10307 struct flex_item *fp = NULL; 10308 uint32_t val; 10309 struct buffer *out = buf; 10310 char *end; 10311 10312 (void)token; 10313 (void)size; 10314 if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10315 ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) 10316 return -1; 10317 if (!ctx->object) 10318 return len; 10319 action = ctx->object; 10320 errno = 0; 10321 val = strtoumax(str, &end, 0); 10322 if (errno || (size_t)(end - str) != len) 10323 return -1; 10324 /* No need to validate action template mask value */ 10325 if (out->args.vc.masks) { 10326 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) 10327 action->dst.level = val; 10328 else 10329 action->src.level = val; 10330 return len; 10331 } 10332 if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10333 action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || 10334 (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && 10335 action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 10336 if (val >= FLEX_MAX_PARSERS_NUM) { 10337 printf("Bad flex item handle\n"); 10338 return -1; 10339 } 10340 fp = flex_items[ctx->port][val]; 10341 if (!fp) { 10342 printf("Bad flex item handle\n"); 10343 return -1; 10344 } 10345 } 10346 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { 10347 if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) 10348 action->dst.level = val; 10349 else 10350 action->dst.flex_handle = fp->flex_handle; 10351 } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { 10352 if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) 10353 action->src.level = val; 10354 else 10355 action->src.flex_handle = fp->flex_handle; 10356 } 10357 return len; 10358 } 10359 10360 /** Parse the conntrack update, not a rte_flow_action. */ 10361 static int 10362 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 10363 const char *str, unsigned int len, void *buf, 10364 unsigned int size) 10365 { 10366 struct buffer *out = buf; 10367 struct rte_flow_modify_conntrack *ct_modify = NULL; 10368 10369 (void)size; 10370 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 10371 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 10372 return -1; 10373 /* Token name must match. */ 10374 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10375 return -1; 10376 /* Nothing else to do if there is no buffer. */ 10377 if (!out) 10378 return len; 10379 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 10380 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 10381 ct_modify->new_ct.is_original_dir = 10382 conntrack_context.is_original_dir; 10383 ct_modify->direction = 1; 10384 } else { 10385 uint32_t old_dir; 10386 10387 old_dir = ct_modify->new_ct.is_original_dir; 10388 memcpy(&ct_modify->new_ct, &conntrack_context, 10389 sizeof(conntrack_context)); 10390 ct_modify->new_ct.is_original_dir = old_dir; 10391 ct_modify->state = 1; 10392 } 10393 return len; 10394 } 10395 10396 /** Parse tokens for destroy command. */ 10397 static int 10398 parse_destroy(struct context *ctx, const struct token *token, 10399 const char *str, unsigned int len, 10400 void *buf, unsigned int size) 10401 { 10402 struct buffer *out = buf; 10403 10404 /* Token name must match. */ 10405 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10406 return -1; 10407 /* Nothing else to do if there is no buffer. */ 10408 if (!out) 10409 return len; 10410 if (!out->command) { 10411 if (ctx->curr != DESTROY) 10412 return -1; 10413 if (sizeof(*out) > size) 10414 return -1; 10415 out->command = ctx->curr; 10416 ctx->objdata = 0; 10417 ctx->object = out; 10418 ctx->objmask = NULL; 10419 out->args.destroy.rule = 10420 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10421 sizeof(double)); 10422 return len; 10423 } 10424 if (ctx->curr == DESTROY_IS_USER_ID) { 10425 out->args.destroy.is_user_id = true; 10426 return len; 10427 } 10428 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 10429 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 10430 return -1; 10431 ctx->objdata = 0; 10432 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 10433 ctx->objmask = NULL; 10434 return len; 10435 } 10436 10437 /** Parse tokens for flush command. */ 10438 static int 10439 parse_flush(struct context *ctx, const struct token *token, 10440 const char *str, unsigned int len, 10441 void *buf, unsigned int size) 10442 { 10443 struct buffer *out = buf; 10444 10445 /* Token name must match. */ 10446 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10447 return -1; 10448 /* Nothing else to do if there is no buffer. */ 10449 if (!out) 10450 return len; 10451 if (!out->command) { 10452 if (ctx->curr != FLUSH) 10453 return -1; 10454 if (sizeof(*out) > size) 10455 return -1; 10456 out->command = ctx->curr; 10457 ctx->objdata = 0; 10458 ctx->object = out; 10459 ctx->objmask = NULL; 10460 } 10461 return len; 10462 } 10463 10464 /** Parse tokens for dump command. */ 10465 static int 10466 parse_dump(struct context *ctx, const struct token *token, 10467 const char *str, unsigned int len, 10468 void *buf, unsigned int size) 10469 { 10470 struct buffer *out = buf; 10471 10472 /* Token name must match. */ 10473 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10474 return -1; 10475 /* Nothing else to do if there is no buffer. */ 10476 if (!out) 10477 return len; 10478 if (!out->command) { 10479 if (ctx->curr != DUMP) 10480 return -1; 10481 if (sizeof(*out) > size) 10482 return -1; 10483 out->command = ctx->curr; 10484 ctx->objdata = 0; 10485 ctx->object = out; 10486 ctx->objmask = NULL; 10487 return len; 10488 } 10489 switch (ctx->curr) { 10490 case DUMP_ALL: 10491 case DUMP_ONE: 10492 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 10493 out->command = ctx->curr; 10494 ctx->objdata = 0; 10495 ctx->object = out; 10496 ctx->objmask = NULL; 10497 return len; 10498 case DUMP_IS_USER_ID: 10499 out->args.dump.is_user_id = true; 10500 return len; 10501 default: 10502 return -1; 10503 } 10504 } 10505 10506 /** Parse tokens for query command. */ 10507 static int 10508 parse_query(struct context *ctx, const struct token *token, 10509 const char *str, unsigned int len, 10510 void *buf, unsigned int size) 10511 { 10512 struct buffer *out = buf; 10513 10514 /* Token name must match. */ 10515 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10516 return -1; 10517 /* Nothing else to do if there is no buffer. */ 10518 if (!out) 10519 return len; 10520 if (!out->command) { 10521 if (ctx->curr != QUERY) 10522 return -1; 10523 if (sizeof(*out) > size) 10524 return -1; 10525 out->command = ctx->curr; 10526 ctx->objdata = 0; 10527 ctx->object = out; 10528 ctx->objmask = NULL; 10529 } 10530 if (ctx->curr == QUERY_IS_USER_ID) { 10531 out->args.query.is_user_id = true; 10532 return len; 10533 } 10534 return len; 10535 } 10536 10537 /** Parse action names. */ 10538 static int 10539 parse_action(struct context *ctx, const struct token *token, 10540 const char *str, unsigned int len, 10541 void *buf, unsigned int size) 10542 { 10543 struct buffer *out = buf; 10544 const struct arg *arg = pop_args(ctx); 10545 unsigned int i; 10546 10547 (void)size; 10548 /* Argument is expected. */ 10549 if (!arg) 10550 return -1; 10551 /* Parse action name. */ 10552 for (i = 0; next_action[i]; ++i) { 10553 const struct parse_action_priv *priv; 10554 10555 token = &token_list[next_action[i]]; 10556 if (strcmp_partial(token->name, str, len)) 10557 continue; 10558 priv = token->priv; 10559 if (!priv) 10560 goto error; 10561 if (out) 10562 memcpy((uint8_t *)ctx->object + arg->offset, 10563 &priv->type, 10564 arg->size); 10565 return len; 10566 } 10567 error: 10568 push_args(ctx, arg); 10569 return -1; 10570 } 10571 10572 /** Parse tokens for list command. */ 10573 static int 10574 parse_list(struct context *ctx, const struct token *token, 10575 const char *str, unsigned int len, 10576 void *buf, unsigned int size) 10577 { 10578 struct buffer *out = buf; 10579 10580 /* Token name must match. */ 10581 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10582 return -1; 10583 /* Nothing else to do if there is no buffer. */ 10584 if (!out) 10585 return len; 10586 if (!out->command) { 10587 if (ctx->curr != LIST) 10588 return -1; 10589 if (sizeof(*out) > size) 10590 return -1; 10591 out->command = ctx->curr; 10592 ctx->objdata = 0; 10593 ctx->object = out; 10594 ctx->objmask = NULL; 10595 out->args.list.group = 10596 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10597 sizeof(double)); 10598 return len; 10599 } 10600 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 10601 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 10602 return -1; 10603 ctx->objdata = 0; 10604 ctx->object = out->args.list.group + out->args.list.group_n++; 10605 ctx->objmask = NULL; 10606 return len; 10607 } 10608 10609 /** Parse tokens for list all aged flows command. */ 10610 static int 10611 parse_aged(struct context *ctx, const struct token *token, 10612 const char *str, unsigned int len, 10613 void *buf, unsigned int size) 10614 { 10615 struct buffer *out = buf; 10616 10617 /* Token name must match. */ 10618 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10619 return -1; 10620 /* Nothing else to do if there is no buffer. */ 10621 if (!out) 10622 return len; 10623 if (!out->command || out->command == QUEUE) { 10624 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 10625 return -1; 10626 if (sizeof(*out) > size) 10627 return -1; 10628 out->command = ctx->curr; 10629 ctx->objdata = 0; 10630 ctx->object = out; 10631 ctx->objmask = NULL; 10632 } 10633 if (ctx->curr == AGED_DESTROY) 10634 out->args.aged.destroy = 1; 10635 return len; 10636 } 10637 10638 /** Parse tokens for isolate command. */ 10639 static int 10640 parse_isolate(struct context *ctx, const struct token *token, 10641 const char *str, unsigned int len, 10642 void *buf, unsigned int size) 10643 { 10644 struct buffer *out = buf; 10645 10646 /* Token name must match. */ 10647 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10648 return -1; 10649 /* Nothing else to do if there is no buffer. */ 10650 if (!out) 10651 return len; 10652 if (!out->command) { 10653 if (ctx->curr != ISOLATE) 10654 return -1; 10655 if (sizeof(*out) > size) 10656 return -1; 10657 out->command = ctx->curr; 10658 ctx->objdata = 0; 10659 ctx->object = out; 10660 ctx->objmask = NULL; 10661 } 10662 return len; 10663 } 10664 10665 /** Parse tokens for info/configure command. */ 10666 static int 10667 parse_configure(struct context *ctx, const struct token *token, 10668 const char *str, unsigned int len, 10669 void *buf, unsigned int size) 10670 { 10671 struct buffer *out = buf; 10672 10673 /* Token name must match. */ 10674 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10675 return -1; 10676 /* Nothing else to do if there is no buffer. */ 10677 if (!out) 10678 return len; 10679 if (!out->command) { 10680 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 10681 return -1; 10682 if (sizeof(*out) > size) 10683 return -1; 10684 out->command = ctx->curr; 10685 ctx->objdata = 0; 10686 ctx->object = out; 10687 ctx->objmask = NULL; 10688 } 10689 return len; 10690 } 10691 10692 /** Parse tokens for template create command. */ 10693 static int 10694 parse_template(struct context *ctx, const struct token *token, 10695 const char *str, unsigned int len, 10696 void *buf, unsigned int size) 10697 { 10698 struct buffer *out = buf; 10699 10700 /* Token name must match. */ 10701 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10702 return -1; 10703 /* Nothing else to do if there is no buffer. */ 10704 if (!out) 10705 return len; 10706 if (!out->command) { 10707 if (ctx->curr != PATTERN_TEMPLATE && 10708 ctx->curr != ACTIONS_TEMPLATE) 10709 return -1; 10710 if (sizeof(*out) > size) 10711 return -1; 10712 out->command = ctx->curr; 10713 ctx->objdata = 0; 10714 ctx->object = out; 10715 ctx->objmask = NULL; 10716 out->args.vc.data = (uint8_t *)out + size; 10717 return len; 10718 } 10719 switch (ctx->curr) { 10720 case PATTERN_TEMPLATE_CREATE: 10721 out->args.vc.pattern = 10722 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10723 sizeof(double)); 10724 out->args.vc.pat_templ_id = UINT32_MAX; 10725 out->command = ctx->curr; 10726 ctx->objdata = 0; 10727 ctx->object = out; 10728 ctx->objmask = NULL; 10729 return len; 10730 case PATTERN_TEMPLATE_EGRESS: 10731 out->args.vc.attr.egress = 1; 10732 return len; 10733 case PATTERN_TEMPLATE_INGRESS: 10734 out->args.vc.attr.ingress = 1; 10735 return len; 10736 case PATTERN_TEMPLATE_TRANSFER: 10737 out->args.vc.attr.transfer = 1; 10738 return len; 10739 case ACTIONS_TEMPLATE_CREATE: 10740 out->args.vc.act_templ_id = UINT32_MAX; 10741 out->command = ctx->curr; 10742 ctx->objdata = 0; 10743 ctx->object = out; 10744 ctx->objmask = NULL; 10745 return len; 10746 case ACTIONS_TEMPLATE_SPEC: 10747 out->args.vc.actions = 10748 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10749 sizeof(double)); 10750 ctx->object = out->args.vc.actions; 10751 ctx->objmask = NULL; 10752 return len; 10753 case ACTIONS_TEMPLATE_MASK: 10754 out->args.vc.masks = 10755 (void *)RTE_ALIGN_CEIL((uintptr_t) 10756 (out->args.vc.actions + 10757 out->args.vc.actions_n), 10758 sizeof(double)); 10759 ctx->object = out->args.vc.masks; 10760 ctx->objmask = NULL; 10761 return len; 10762 case ACTIONS_TEMPLATE_EGRESS: 10763 out->args.vc.attr.egress = 1; 10764 return len; 10765 case ACTIONS_TEMPLATE_INGRESS: 10766 out->args.vc.attr.ingress = 1; 10767 return len; 10768 case ACTIONS_TEMPLATE_TRANSFER: 10769 out->args.vc.attr.transfer = 1; 10770 return len; 10771 default: 10772 return -1; 10773 } 10774 } 10775 10776 /** Parse tokens for template destroy command. */ 10777 static int 10778 parse_template_destroy(struct context *ctx, const struct token *token, 10779 const char *str, unsigned int len, 10780 void *buf, unsigned int size) 10781 { 10782 struct buffer *out = buf; 10783 uint32_t *template_id; 10784 10785 /* Token name must match. */ 10786 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10787 return -1; 10788 /* Nothing else to do if there is no buffer. */ 10789 if (!out) 10790 return len; 10791 if (!out->command || 10792 out->command == PATTERN_TEMPLATE || 10793 out->command == ACTIONS_TEMPLATE) { 10794 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 10795 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 10796 return -1; 10797 if (sizeof(*out) > size) 10798 return -1; 10799 out->command = ctx->curr; 10800 ctx->objdata = 0; 10801 ctx->object = out; 10802 ctx->objmask = NULL; 10803 out->args.templ_destroy.template_id = 10804 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10805 sizeof(double)); 10806 return len; 10807 } 10808 template_id = out->args.templ_destroy.template_id 10809 + out->args.templ_destroy.template_id_n++; 10810 if ((uint8_t *)template_id > (uint8_t *)out + size) 10811 return -1; 10812 ctx->objdata = 0; 10813 ctx->object = template_id; 10814 ctx->objmask = NULL; 10815 return len; 10816 } 10817 10818 /** Parse tokens for table create command. */ 10819 static int 10820 parse_table(struct context *ctx, const struct token *token, 10821 const char *str, unsigned int len, 10822 void *buf, unsigned int size) 10823 { 10824 struct buffer *out = buf; 10825 uint32_t *template_id; 10826 10827 /* Token name must match. */ 10828 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10829 return -1; 10830 /* Nothing else to do if there is no buffer. */ 10831 if (!out) 10832 return len; 10833 if (!out->command) { 10834 if (ctx->curr != TABLE) 10835 return -1; 10836 if (sizeof(*out) > size) 10837 return -1; 10838 out->command = ctx->curr; 10839 ctx->objdata = 0; 10840 ctx->object = out; 10841 ctx->objmask = NULL; 10842 return len; 10843 } 10844 switch (ctx->curr) { 10845 case TABLE_CREATE: 10846 case TABLE_RESIZE: 10847 out->command = ctx->curr; 10848 ctx->objdata = 0; 10849 ctx->object = out; 10850 ctx->objmask = NULL; 10851 out->args.table.id = UINT32_MAX; 10852 return len; 10853 case TABLE_PATTERN_TEMPLATE: 10854 out->args.table.pat_templ_id = 10855 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10856 sizeof(double)); 10857 template_id = out->args.table.pat_templ_id 10858 + out->args.table.pat_templ_id_n++; 10859 if ((uint8_t *)template_id > (uint8_t *)out + size) 10860 return -1; 10861 ctx->objdata = 0; 10862 ctx->object = template_id; 10863 ctx->objmask = NULL; 10864 return len; 10865 case TABLE_ACTIONS_TEMPLATE: 10866 out->args.table.act_templ_id = 10867 (void *)RTE_ALIGN_CEIL((uintptr_t) 10868 (out->args.table.pat_templ_id + 10869 out->args.table.pat_templ_id_n), 10870 sizeof(double)); 10871 template_id = out->args.table.act_templ_id 10872 + out->args.table.act_templ_id_n++; 10873 if ((uint8_t *)template_id > (uint8_t *)out + size) 10874 return -1; 10875 ctx->objdata = 0; 10876 ctx->object = template_id; 10877 ctx->objmask = NULL; 10878 return len; 10879 case TABLE_INGRESS: 10880 out->args.table.attr.flow_attr.ingress = 1; 10881 return len; 10882 case TABLE_EGRESS: 10883 out->args.table.attr.flow_attr.egress = 1; 10884 return len; 10885 case TABLE_TRANSFER: 10886 out->args.table.attr.flow_attr.transfer = 1; 10887 return len; 10888 case TABLE_TRANSFER_WIRE_ORIG: 10889 if (!out->args.table.attr.flow_attr.transfer) 10890 return -1; 10891 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; 10892 return len; 10893 case TABLE_TRANSFER_VPORT_ORIG: 10894 if (!out->args.table.attr.flow_attr.transfer) 10895 return -1; 10896 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; 10897 return len; 10898 case TABLE_RESIZABLE: 10899 out->args.table.attr.specialize |= 10900 RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE; 10901 return len; 10902 case TABLE_RULES_NUMBER: 10903 ctx->objdata = 0; 10904 ctx->object = out; 10905 ctx->objmask = NULL; 10906 return len; 10907 case TABLE_RESIZE_ID: 10908 case TABLE_RESIZE_RULES_NUMBER: 10909 return len; 10910 default: 10911 return -1; 10912 } 10913 } 10914 10915 /** Parse tokens for table destroy command. */ 10916 static int 10917 parse_table_destroy(struct context *ctx, const struct token *token, 10918 const char *str, unsigned int len, 10919 void *buf, unsigned int size) 10920 { 10921 struct buffer *out = buf; 10922 uint32_t *table_id; 10923 10924 /* Token name must match. */ 10925 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10926 return -1; 10927 /* Nothing else to do if there is no buffer. */ 10928 if (!out) 10929 return len; 10930 if (!out->command || out->command == TABLE) { 10931 if (ctx->curr != TABLE_DESTROY && 10932 ctx->curr != TABLE_RESIZE_COMPLETE) 10933 return -1; 10934 if (sizeof(*out) > size) 10935 return -1; 10936 out->command = ctx->curr; 10937 ctx->objdata = 0; 10938 ctx->object = out; 10939 ctx->objmask = NULL; 10940 out->args.table_destroy.table_id = 10941 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10942 sizeof(double)); 10943 return len; 10944 } 10945 table_id = out->args.table_destroy.table_id 10946 + out->args.table_destroy.table_id_n++; 10947 if ((uint8_t *)table_id > (uint8_t *)out + size) 10948 return -1; 10949 ctx->objdata = 0; 10950 ctx->object = table_id; 10951 ctx->objmask = NULL; 10952 return len; 10953 } 10954 10955 /** Parse tokens for queue create commands. */ 10956 static int 10957 parse_qo(struct context *ctx, const struct token *token, 10958 const char *str, unsigned int len, 10959 void *buf, unsigned int size) 10960 { 10961 struct buffer *out = buf; 10962 10963 /* Token name must match. */ 10964 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10965 return -1; 10966 /* Nothing else to do if there is no buffer. */ 10967 if (!out) 10968 return len; 10969 if (!out->command) { 10970 if (ctx->curr != QUEUE) 10971 return -1; 10972 if (sizeof(*out) > size) 10973 return -1; 10974 out->command = ctx->curr; 10975 ctx->objdata = 0; 10976 ctx->object = out; 10977 ctx->objmask = NULL; 10978 out->args.vc.data = (uint8_t *)out + size; 10979 return len; 10980 } 10981 switch (ctx->curr) { 10982 case QUEUE_CREATE: 10983 case QUEUE_UPDATE: 10984 out->command = ctx->curr; 10985 ctx->objdata = 0; 10986 ctx->object = out; 10987 ctx->objmask = NULL; 10988 out->args.vc.rule_id = UINT32_MAX; 10989 return len; 10990 case QUEUE_TEMPLATE_TABLE: 10991 case QUEUE_PATTERN_TEMPLATE: 10992 case QUEUE_ACTIONS_TEMPLATE: 10993 case QUEUE_CREATE_POSTPONE: 10994 case QUEUE_RULE_ID: 10995 case QUEUE_UPDATE_ID: 10996 return len; 10997 case ITEM_PATTERN: 10998 out->args.vc.pattern = 10999 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11000 sizeof(double)); 11001 ctx->object = out->args.vc.pattern; 11002 ctx->objmask = NULL; 11003 return len; 11004 case ACTIONS: 11005 out->args.vc.actions = 11006 (void *)RTE_ALIGN_CEIL((uintptr_t) 11007 (out->args.vc.pattern + 11008 out->args.vc.pattern_n), 11009 sizeof(double)); 11010 ctx->object = out->args.vc.actions; 11011 ctx->objmask = NULL; 11012 return len; 11013 default: 11014 return -1; 11015 } 11016 } 11017 11018 /** Parse tokens for queue destroy command. */ 11019 static int 11020 parse_qo_destroy(struct context *ctx, const struct token *token, 11021 const char *str, unsigned int len, 11022 void *buf, unsigned int size) 11023 { 11024 struct buffer *out = buf; 11025 uint64_t *flow_id; 11026 11027 /* Token name must match. */ 11028 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11029 return -1; 11030 /* Nothing else to do if there is no buffer. */ 11031 if (!out) 11032 return len; 11033 if (!out->command || out->command == QUEUE) { 11034 if (ctx->curr != QUEUE_DESTROY && 11035 ctx->curr != QUEUE_FLOW_UPDATE_RESIZED) 11036 return -1; 11037 if (sizeof(*out) > size) 11038 return -1; 11039 out->command = ctx->curr; 11040 ctx->objdata = 0; 11041 ctx->object = out; 11042 ctx->objmask = NULL; 11043 out->args.destroy.rule = 11044 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11045 sizeof(double)); 11046 return len; 11047 } 11048 switch (ctx->curr) { 11049 case QUEUE_DESTROY_ID: 11050 flow_id = out->args.destroy.rule 11051 + out->args.destroy.rule_n++; 11052 if ((uint8_t *)flow_id > (uint8_t *)out + size) 11053 return -1; 11054 ctx->objdata = 0; 11055 ctx->object = flow_id; 11056 ctx->objmask = NULL; 11057 return len; 11058 case QUEUE_DESTROY_POSTPONE: 11059 return len; 11060 default: 11061 return -1; 11062 } 11063 } 11064 11065 /** Parse tokens for push queue command. */ 11066 static int 11067 parse_push(struct context *ctx, const struct token *token, 11068 const char *str, unsigned int len, 11069 void *buf, unsigned int size) 11070 { 11071 struct buffer *out = buf; 11072 11073 /* Token name must match. */ 11074 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11075 return -1; 11076 /* Nothing else to do if there is no buffer. */ 11077 if (!out) 11078 return len; 11079 if (!out->command) { 11080 if (ctx->curr != PUSH) 11081 return -1; 11082 if (sizeof(*out) > size) 11083 return -1; 11084 out->command = ctx->curr; 11085 ctx->objdata = 0; 11086 ctx->object = out; 11087 ctx->objmask = NULL; 11088 out->args.vc.data = (uint8_t *)out + size; 11089 } 11090 return len; 11091 } 11092 11093 /** Parse tokens for pull command. */ 11094 static int 11095 parse_pull(struct context *ctx, const struct token *token, 11096 const char *str, unsigned int len, 11097 void *buf, unsigned int size) 11098 { 11099 struct buffer *out = buf; 11100 11101 /* Token name must match. */ 11102 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11103 return -1; 11104 /* Nothing else to do if there is no buffer. */ 11105 if (!out) 11106 return len; 11107 if (!out->command) { 11108 if (ctx->curr != PULL) 11109 return -1; 11110 if (sizeof(*out) > size) 11111 return -1; 11112 out->command = ctx->curr; 11113 ctx->objdata = 0; 11114 ctx->object = out; 11115 ctx->objmask = NULL; 11116 out->args.vc.data = (uint8_t *)out + size; 11117 } 11118 return len; 11119 } 11120 11121 /** Parse tokens for hash calculation commands. */ 11122 static int 11123 parse_hash(struct context *ctx, const struct token *token, 11124 const char *str, unsigned int len, 11125 void *buf, unsigned int size) 11126 { 11127 struct buffer *out = buf; 11128 11129 /* Token name must match. */ 11130 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11131 return -1; 11132 /* Nothing else to do if there is no buffer. */ 11133 if (!out) 11134 return len; 11135 if (!out->command) { 11136 if (ctx->curr != HASH) 11137 return -1; 11138 if (sizeof(*out) > size) 11139 return -1; 11140 out->command = ctx->curr; 11141 ctx->objdata = 0; 11142 ctx->object = out; 11143 ctx->objmask = NULL; 11144 out->args.vc.data = (uint8_t *)out + size; 11145 return len; 11146 } 11147 switch (ctx->curr) { 11148 case HASH_CALC_TABLE: 11149 case HASH_CALC_PATTERN_INDEX: 11150 return len; 11151 case ITEM_PATTERN: 11152 out->args.vc.pattern = 11153 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11154 sizeof(double)); 11155 ctx->object = out->args.vc.pattern; 11156 ctx->objmask = NULL; 11157 return len; 11158 case HASH_CALC_ENCAP: 11159 out->args.vc.encap_hash = 1; 11160 return len; 11161 case ENCAP_HASH_FIELD_SRC_PORT: 11162 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT; 11163 return len; 11164 case ENCAP_HASH_FIELD_GRE_FLOW_ID: 11165 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID; 11166 return len; 11167 default: 11168 return -1; 11169 } 11170 } 11171 11172 static int 11173 parse_group(struct context *ctx, const struct token *token, 11174 const char *str, unsigned int len, 11175 void *buf, unsigned int size) 11176 { 11177 struct buffer *out = buf; 11178 11179 /* Token name must match. */ 11180 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11181 return -1; 11182 /* Nothing else to do if there is no buffer. */ 11183 if (!out) 11184 return len; 11185 if (!out->command) { 11186 if (ctx->curr != FLOW_GROUP) 11187 return -1; 11188 if (sizeof(*out) > size) 11189 return -1; 11190 out->command = ctx->curr; 11191 ctx->objdata = 0; 11192 ctx->object = out; 11193 ctx->objmask = NULL; 11194 out->args.vc.data = (uint8_t *)out + size; 11195 return len; 11196 } 11197 switch (ctx->curr) { 11198 case GROUP_INGRESS: 11199 out->args.vc.attr.ingress = 1; 11200 return len; 11201 case GROUP_EGRESS: 11202 out->args.vc.attr.egress = 1; 11203 return len; 11204 case GROUP_TRANSFER: 11205 out->args.vc.attr.transfer = 1; 11206 return len; 11207 case GROUP_SET_MISS_ACTIONS: 11208 out->command = ctx->curr; 11209 ctx->objdata = 0; 11210 ctx->object = out; 11211 ctx->objmask = NULL; 11212 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11213 sizeof(double)); 11214 return len; 11215 default: 11216 return -1; 11217 } 11218 } 11219 11220 static int 11221 parse_flex(struct context *ctx, const struct token *token, 11222 const char *str, unsigned int len, 11223 void *buf, unsigned int size) 11224 { 11225 struct buffer *out = buf; 11226 11227 /* Token name must match. */ 11228 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11229 return -1; 11230 /* Nothing else to do if there is no buffer. */ 11231 if (!out) 11232 return len; 11233 if (out->command == ZERO) { 11234 if (ctx->curr != FLEX) 11235 return -1; 11236 if (sizeof(*out) > size) 11237 return -1; 11238 out->command = ctx->curr; 11239 ctx->objdata = 0; 11240 ctx->object = out; 11241 ctx->objmask = NULL; 11242 } else { 11243 switch (ctx->curr) { 11244 default: 11245 break; 11246 case FLEX_ITEM_INIT: 11247 case FLEX_ITEM_CREATE: 11248 case FLEX_ITEM_DESTROY: 11249 out->command = ctx->curr; 11250 break; 11251 } 11252 } 11253 11254 return len; 11255 } 11256 11257 static int 11258 parse_tunnel(struct context *ctx, const struct token *token, 11259 const char *str, unsigned int len, 11260 void *buf, unsigned int size) 11261 { 11262 struct buffer *out = buf; 11263 11264 /* Token name must match. */ 11265 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11266 return -1; 11267 /* Nothing else to do if there is no buffer. */ 11268 if (!out) 11269 return len; 11270 if (!out->command) { 11271 if (ctx->curr != TUNNEL) 11272 return -1; 11273 if (sizeof(*out) > size) 11274 return -1; 11275 out->command = ctx->curr; 11276 ctx->objdata = 0; 11277 ctx->object = out; 11278 ctx->objmask = NULL; 11279 } else { 11280 switch (ctx->curr) { 11281 default: 11282 break; 11283 case TUNNEL_CREATE: 11284 case TUNNEL_DESTROY: 11285 case TUNNEL_LIST: 11286 out->command = ctx->curr; 11287 break; 11288 case TUNNEL_CREATE_TYPE: 11289 case TUNNEL_DESTROY_ID: 11290 ctx->object = &out->args.vc.tunnel_ops; 11291 break; 11292 } 11293 } 11294 11295 return len; 11296 } 11297 11298 /** 11299 * Parse signed/unsigned integers 8 to 64-bit long. 11300 * 11301 * Last argument (ctx->args) is retrieved to determine integer type and 11302 * storage location. 11303 */ 11304 static int 11305 parse_int(struct context *ctx, const struct token *token, 11306 const char *str, unsigned int len, 11307 void *buf, unsigned int size) 11308 { 11309 const struct arg *arg = pop_args(ctx); 11310 uintmax_t u; 11311 char *end; 11312 11313 (void)token; 11314 /* Argument is expected. */ 11315 if (!arg) 11316 return -1; 11317 errno = 0; 11318 u = arg->sign ? 11319 (uintmax_t)strtoimax(str, &end, 0) : 11320 strtoumax(str, &end, 0); 11321 if (errno || (size_t)(end - str) != len) 11322 goto error; 11323 if (arg->bounded && 11324 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 11325 (intmax_t)u > (intmax_t)arg->max)) || 11326 (!arg->sign && (u < arg->min || u > arg->max)))) 11327 goto error; 11328 if (!ctx->object) 11329 return len; 11330 if (arg->mask) { 11331 if (!arg_entry_bf_fill(ctx->object, u, arg) || 11332 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 11333 goto error; 11334 return len; 11335 } 11336 buf = (uint8_t *)ctx->object + arg->offset; 11337 size = arg->size; 11338 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 11339 return -1; 11340 objmask: 11341 switch (size) { 11342 case sizeof(uint8_t): 11343 *(uint8_t *)buf = u; 11344 break; 11345 case sizeof(uint16_t): 11346 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 11347 break; 11348 case sizeof(uint8_t [3]): 11349 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 11350 if (!arg->hton) { 11351 ((uint8_t *)buf)[0] = u; 11352 ((uint8_t *)buf)[1] = u >> 8; 11353 ((uint8_t *)buf)[2] = u >> 16; 11354 break; 11355 } 11356 #endif 11357 ((uint8_t *)buf)[0] = u >> 16; 11358 ((uint8_t *)buf)[1] = u >> 8; 11359 ((uint8_t *)buf)[2] = u; 11360 break; 11361 case sizeof(uint32_t): 11362 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 11363 break; 11364 case sizeof(uint64_t): 11365 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 11366 break; 11367 default: 11368 goto error; 11369 } 11370 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 11371 u = -1; 11372 buf = (uint8_t *)ctx->objmask + arg->offset; 11373 goto objmask; 11374 } 11375 return len; 11376 error: 11377 push_args(ctx, arg); 11378 return -1; 11379 } 11380 11381 /** 11382 * Parse a string. 11383 * 11384 * Three arguments (ctx->args) are retrieved from the stack to store data, 11385 * its actual length and address (in that order). 11386 */ 11387 static int 11388 parse_string(struct context *ctx, const struct token *token, 11389 const char *str, unsigned int len, 11390 void *buf, unsigned int size) 11391 { 11392 const struct arg *arg_data = pop_args(ctx); 11393 const struct arg *arg_len = pop_args(ctx); 11394 const struct arg *arg_addr = pop_args(ctx); 11395 char tmp[16]; /* Ought to be enough. */ 11396 int ret; 11397 11398 /* Arguments are expected. */ 11399 if (!arg_data) 11400 return -1; 11401 if (!arg_len) { 11402 push_args(ctx, arg_data); 11403 return -1; 11404 } 11405 if (!arg_addr) { 11406 push_args(ctx, arg_len); 11407 push_args(ctx, arg_data); 11408 return -1; 11409 } 11410 size = arg_data->size; 11411 /* Bit-mask fill is not supported. */ 11412 if (arg_data->mask || size < len) 11413 goto error; 11414 if (!ctx->object) 11415 return len; 11416 /* Let parse_int() fill length information first. */ 11417 ret = snprintf(tmp, sizeof(tmp), "%u", len); 11418 if (ret < 0) 11419 goto error; 11420 push_args(ctx, arg_len); 11421 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11422 if (ret < 0) { 11423 pop_args(ctx); 11424 goto error; 11425 } 11426 buf = (uint8_t *)ctx->object + arg_data->offset; 11427 /* Output buffer is not necessarily NUL-terminated. */ 11428 memcpy(buf, str, len); 11429 memset((uint8_t *)buf + len, 0x00, size - len); 11430 if (ctx->objmask) 11431 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11432 /* Save address if requested. */ 11433 if (arg_addr->size) { 11434 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11435 (void *[]){ 11436 (uint8_t *)ctx->object + arg_data->offset 11437 }, 11438 arg_addr->size); 11439 if (ctx->objmask) 11440 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11441 (void *[]){ 11442 (uint8_t *)ctx->objmask + arg_data->offset 11443 }, 11444 arg_addr->size); 11445 } 11446 return len; 11447 error: 11448 push_args(ctx, arg_addr); 11449 push_args(ctx, arg_len); 11450 push_args(ctx, arg_data); 11451 return -1; 11452 } 11453 11454 static int 11455 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 11456 { 11457 const uint8_t *head = dst; 11458 uint32_t left; 11459 11460 if (*size == 0) 11461 return -1; 11462 11463 left = *size; 11464 11465 /* Convert chars to bytes */ 11466 while (left) { 11467 char tmp[3], *end = tmp; 11468 uint32_t read_lim = left & 1 ? 1 : 2; 11469 11470 snprintf(tmp, read_lim + 1, "%s", src); 11471 *dst = strtoul(tmp, &end, 16); 11472 if (*end) { 11473 *dst = 0; 11474 *size = (uint32_t)(dst - head); 11475 return -1; 11476 } 11477 left -= read_lim; 11478 src += read_lim; 11479 dst++; 11480 } 11481 *dst = 0; 11482 *size = (uint32_t)(dst - head); 11483 return 0; 11484 } 11485 11486 static int 11487 parse_hex(struct context *ctx, const struct token *token, 11488 const char *str, unsigned int len, 11489 void *buf, unsigned int size) 11490 { 11491 const struct arg *arg_data = pop_args(ctx); 11492 const struct arg *arg_len = pop_args(ctx); 11493 const struct arg *arg_addr = pop_args(ctx); 11494 char tmp[16]; /* Ought to be enough. */ 11495 int ret; 11496 unsigned int hexlen = len; 11497 unsigned int length = 256; 11498 uint8_t hex_tmp[length]; 11499 11500 /* Arguments are expected. */ 11501 if (!arg_data) 11502 return -1; 11503 if (!arg_len) { 11504 push_args(ctx, arg_data); 11505 return -1; 11506 } 11507 if (!arg_addr) { 11508 push_args(ctx, arg_len); 11509 push_args(ctx, arg_data); 11510 return -1; 11511 } 11512 size = arg_data->size; 11513 /* Bit-mask fill is not supported. */ 11514 if (arg_data->mask) 11515 goto error; 11516 if (!ctx->object) 11517 return len; 11518 11519 /* translate bytes string to array. */ 11520 if (str[0] == '0' && ((str[1] == 'x') || 11521 (str[1] == 'X'))) { 11522 str += 2; 11523 hexlen -= 2; 11524 } 11525 if (hexlen > length) 11526 goto error; 11527 ret = parse_hex_string(str, hex_tmp, &hexlen); 11528 if (ret < 0) 11529 goto error; 11530 /* Check the converted binary fits into data buffer. */ 11531 if (hexlen > size) 11532 goto error; 11533 /* Let parse_int() fill length information first. */ 11534 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 11535 if (ret < 0) 11536 goto error; 11537 /* Save length if requested. */ 11538 if (arg_len->size) { 11539 push_args(ctx, arg_len); 11540 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11541 if (ret < 0) { 11542 pop_args(ctx); 11543 goto error; 11544 } 11545 } 11546 buf = (uint8_t *)ctx->object + arg_data->offset; 11547 /* Output buffer is not necessarily NUL-terminated. */ 11548 memcpy(buf, hex_tmp, hexlen); 11549 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 11550 if (ctx->objmask) 11551 memset((uint8_t *)ctx->objmask + arg_data->offset, 11552 0xff, hexlen); 11553 /* Save address if requested. */ 11554 if (arg_addr->size) { 11555 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11556 (void *[]){ 11557 (uint8_t *)ctx->object + arg_data->offset 11558 }, 11559 arg_addr->size); 11560 if (ctx->objmask) 11561 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11562 (void *[]){ 11563 (uint8_t *)ctx->objmask + arg_data->offset 11564 }, 11565 arg_addr->size); 11566 } 11567 return len; 11568 error: 11569 push_args(ctx, arg_addr); 11570 push_args(ctx, arg_len); 11571 push_args(ctx, arg_data); 11572 return -1; 11573 11574 } 11575 11576 /** 11577 * Parse a zero-ended string. 11578 */ 11579 static int 11580 parse_string0(struct context *ctx, const struct token *token __rte_unused, 11581 const char *str, unsigned int len, 11582 void *buf, unsigned int size) 11583 { 11584 const struct arg *arg_data = pop_args(ctx); 11585 11586 /* Arguments are expected. */ 11587 if (!arg_data) 11588 return -1; 11589 size = arg_data->size; 11590 /* Bit-mask fill is not supported. */ 11591 if (arg_data->mask || size < len + 1) 11592 goto error; 11593 if (!ctx->object) 11594 return len; 11595 buf = (uint8_t *)ctx->object + arg_data->offset; 11596 strncpy(buf, str, len); 11597 if (ctx->objmask) 11598 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11599 return len; 11600 error: 11601 push_args(ctx, arg_data); 11602 return -1; 11603 } 11604 11605 /** 11606 * Parse a MAC address. 11607 * 11608 * Last argument (ctx->args) is retrieved to determine storage size and 11609 * location. 11610 */ 11611 static int 11612 parse_mac_addr(struct context *ctx, const struct token *token, 11613 const char *str, unsigned int len, 11614 void *buf, unsigned int size) 11615 { 11616 const struct arg *arg = pop_args(ctx); 11617 struct rte_ether_addr tmp; 11618 int ret; 11619 11620 (void)token; 11621 /* Argument is expected. */ 11622 if (!arg) 11623 return -1; 11624 size = arg->size; 11625 /* Bit-mask fill is not supported. */ 11626 if (arg->mask || size != sizeof(tmp)) 11627 goto error; 11628 /* Only network endian is supported. */ 11629 if (!arg->hton) 11630 goto error; 11631 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 11632 if (ret < 0 || (unsigned int)ret != len) 11633 goto error; 11634 if (!ctx->object) 11635 return len; 11636 buf = (uint8_t *)ctx->object + arg->offset; 11637 memcpy(buf, &tmp, size); 11638 if (ctx->objmask) 11639 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11640 return len; 11641 error: 11642 push_args(ctx, arg); 11643 return -1; 11644 } 11645 11646 /** 11647 * Parse an IPv4 address. 11648 * 11649 * Last argument (ctx->args) is retrieved to determine storage size and 11650 * location. 11651 */ 11652 static int 11653 parse_ipv4_addr(struct context *ctx, const struct token *token, 11654 const char *str, unsigned int len, 11655 void *buf, unsigned int size) 11656 { 11657 const struct arg *arg = pop_args(ctx); 11658 char str2[len + 1]; 11659 struct in_addr tmp; 11660 int ret; 11661 11662 /* Argument is expected. */ 11663 if (!arg) 11664 return -1; 11665 size = arg->size; 11666 /* Bit-mask fill is not supported. */ 11667 if (arg->mask || size != sizeof(tmp)) 11668 goto error; 11669 /* Only network endian is supported. */ 11670 if (!arg->hton) 11671 goto error; 11672 memcpy(str2, str, len); 11673 str2[len] = '\0'; 11674 ret = inet_pton(AF_INET, str2, &tmp); 11675 if (ret != 1) { 11676 /* Attempt integer parsing. */ 11677 push_args(ctx, arg); 11678 return parse_int(ctx, token, str, len, buf, size); 11679 } 11680 if (!ctx->object) 11681 return len; 11682 buf = (uint8_t *)ctx->object + arg->offset; 11683 memcpy(buf, &tmp, size); 11684 if (ctx->objmask) 11685 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11686 return len; 11687 error: 11688 push_args(ctx, arg); 11689 return -1; 11690 } 11691 11692 /** 11693 * Parse an IPv6 address. 11694 * 11695 * Last argument (ctx->args) is retrieved to determine storage size and 11696 * location. 11697 */ 11698 static int 11699 parse_ipv6_addr(struct context *ctx, const struct token *token, 11700 const char *str, unsigned int len, 11701 void *buf, unsigned int size) 11702 { 11703 const struct arg *arg = pop_args(ctx); 11704 char str2[len + 1]; 11705 struct in6_addr tmp; 11706 int ret; 11707 11708 (void)token; 11709 /* Argument is expected. */ 11710 if (!arg) 11711 return -1; 11712 size = arg->size; 11713 /* Bit-mask fill is not supported. */ 11714 if (arg->mask || size != sizeof(tmp)) 11715 goto error; 11716 /* Only network endian is supported. */ 11717 if (!arg->hton) 11718 goto error; 11719 memcpy(str2, str, len); 11720 str2[len] = '\0'; 11721 ret = inet_pton(AF_INET6, str2, &tmp); 11722 if (ret != 1) 11723 goto error; 11724 if (!ctx->object) 11725 return len; 11726 buf = (uint8_t *)ctx->object + arg->offset; 11727 memcpy(buf, &tmp, size); 11728 if (ctx->objmask) 11729 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11730 return len; 11731 error: 11732 push_args(ctx, arg); 11733 return -1; 11734 } 11735 11736 /** Boolean values (even indices stand for false). */ 11737 static const char *const boolean_name[] = { 11738 "0", "1", 11739 "false", "true", 11740 "no", "yes", 11741 "N", "Y", 11742 "off", "on", 11743 NULL, 11744 }; 11745 11746 /** 11747 * Parse a boolean value. 11748 * 11749 * Last argument (ctx->args) is retrieved to determine storage size and 11750 * location. 11751 */ 11752 static int 11753 parse_boolean(struct context *ctx, const struct token *token, 11754 const char *str, unsigned int len, 11755 void *buf, unsigned int size) 11756 { 11757 const struct arg *arg = pop_args(ctx); 11758 unsigned int i; 11759 int ret; 11760 11761 /* Argument is expected. */ 11762 if (!arg) 11763 return -1; 11764 for (i = 0; boolean_name[i]; ++i) 11765 if (!strcmp_partial(boolean_name[i], str, len)) 11766 break; 11767 /* Process token as integer. */ 11768 if (boolean_name[i]) 11769 str = i & 1 ? "1" : "0"; 11770 push_args(ctx, arg); 11771 ret = parse_int(ctx, token, str, strlen(str), buf, size); 11772 return ret > 0 ? (int)len : ret; 11773 } 11774 11775 /** Parse port and update context. */ 11776 static int 11777 parse_port(struct context *ctx, const struct token *token, 11778 const char *str, unsigned int len, 11779 void *buf, unsigned int size) 11780 { 11781 struct buffer *out = &(struct buffer){ .port = 0 }; 11782 int ret; 11783 11784 if (buf) 11785 out = buf; 11786 else { 11787 ctx->objdata = 0; 11788 ctx->object = out; 11789 ctx->objmask = NULL; 11790 size = sizeof(*out); 11791 } 11792 ret = parse_int(ctx, token, str, len, out, size); 11793 if (ret >= 0) 11794 ctx->port = out->port; 11795 if (!buf) 11796 ctx->object = NULL; 11797 return ret; 11798 } 11799 11800 /** Parse tokens for shared indirect actions. */ 11801 static int 11802 parse_ia_port(struct context *ctx, const struct token *token, 11803 const char *str, unsigned int len, 11804 void *buf, unsigned int size) 11805 { 11806 struct rte_flow_action *action = ctx->object; 11807 uint32_t id; 11808 int ret; 11809 11810 (void)buf; 11811 (void)size; 11812 ctx->objdata = 0; 11813 ctx->object = &id; 11814 ctx->objmask = NULL; 11815 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11816 ctx->object = action; 11817 if (ret != (int)len) 11818 return ret; 11819 /* set indirect action */ 11820 if (action) 11821 action->conf = (void *)(uintptr_t)id; 11822 return ret; 11823 } 11824 11825 static int 11826 parse_ia_id2ptr(struct context *ctx, const struct token *token, 11827 const char *str, unsigned int len, 11828 void *buf, unsigned int size) 11829 { 11830 struct rte_flow_action *action = ctx->object; 11831 uint32_t id; 11832 int ret; 11833 11834 (void)buf; 11835 (void)size; 11836 ctx->objdata = 0; 11837 ctx->object = &id; 11838 ctx->objmask = NULL; 11839 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11840 ctx->object = action; 11841 if (ret != (int)len) 11842 return ret; 11843 /* set indirect action */ 11844 if (action) { 11845 portid_t port_id = ctx->port; 11846 if (ctx->prev == INDIRECT_ACTION_PORT) 11847 port_id = (portid_t)(uintptr_t)action->conf; 11848 action->conf = port_action_handle_get_by_id(port_id, id); 11849 ret = (action->conf) ? ret : -1; 11850 } 11851 return ret; 11852 } 11853 11854 static int 11855 parse_indlst_id2ptr(struct context *ctx, const struct token *token, 11856 const char *str, unsigned int len, 11857 __rte_unused void *buf, __rte_unused unsigned int size) 11858 { 11859 struct rte_flow_action *action = ctx->object; 11860 struct rte_flow_action_indirect_list *action_conf; 11861 const struct indlst_conf *indlst_conf; 11862 uint32_t id; 11863 int ret; 11864 11865 if (!action) 11866 return -1; 11867 ctx->objdata = 0; 11868 ctx->object = &id; 11869 ctx->objmask = NULL; 11870 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11871 if (ret != (int)len) 11872 return ret; 11873 ctx->object = action; 11874 action_conf = (void *)(uintptr_t)action->conf; 11875 action_conf->conf = NULL; 11876 switch (ctx->curr) { 11877 case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: 11878 action_conf->handle = (typeof(action_conf->handle)) 11879 port_action_handle_get_by_id(ctx->port, id); 11880 if (!action_conf->handle) { 11881 printf("no indirect list handle for id %u\n", id); 11882 return -1; 11883 } 11884 break; 11885 case INDIRECT_LIST_ACTION_ID2PTR_CONF: 11886 indlst_conf = indirect_action_list_conf_get(id); 11887 if (!indlst_conf) 11888 return -1; 11889 action_conf->conf = (const void **)indlst_conf->conf; 11890 break; 11891 default: 11892 break; 11893 } 11894 return ret; 11895 } 11896 11897 static int 11898 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 11899 const char *str, unsigned int len, 11900 void *buf, unsigned int size) 11901 { 11902 struct rte_flow_action *action = ctx->object; 11903 struct rte_flow_action_meter_mark *meter; 11904 struct rte_flow_meter_profile *profile = NULL; 11905 uint32_t id = 0; 11906 int ret; 11907 11908 (void)buf; 11909 (void)size; 11910 ctx->objdata = 0; 11911 ctx->object = &id; 11912 ctx->objmask = NULL; 11913 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11914 ctx->object = action; 11915 if (ret != (int)len) 11916 return ret; 11917 /* set meter profile */ 11918 if (action) { 11919 meter = (struct rte_flow_action_meter_mark *) 11920 (uintptr_t)(action->conf); 11921 profile = port_meter_profile_get_by_id(ctx->port, id); 11922 meter->profile = profile; 11923 ret = (profile) ? ret : -1; 11924 } 11925 return ret; 11926 } 11927 11928 static int 11929 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 11930 const char *str, unsigned int len, 11931 void *buf, unsigned int size) 11932 { 11933 struct rte_flow_action *action = ctx->object; 11934 struct rte_flow_action_meter_mark *meter; 11935 struct rte_flow_meter_policy *policy = NULL; 11936 uint32_t id = 0; 11937 int ret; 11938 11939 (void)buf; 11940 (void)size; 11941 ctx->objdata = 0; 11942 ctx->object = &id; 11943 ctx->objmask = NULL; 11944 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11945 ctx->object = action; 11946 if (ret != (int)len) 11947 return ret; 11948 /* set meter policy */ 11949 if (action) { 11950 meter = (struct rte_flow_action_meter_mark *) 11951 (uintptr_t)(action->conf); 11952 policy = port_meter_policy_get_by_id(ctx->port, id); 11953 meter->policy = policy; 11954 ret = (policy) ? ret : -1; 11955 } 11956 return ret; 11957 } 11958 11959 /** Parse set command, initialize output buffer for subsequent tokens. */ 11960 static int 11961 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 11962 const char *str, unsigned int len, 11963 void *buf, unsigned int size) 11964 { 11965 struct buffer *out = buf; 11966 11967 /* Token name must match. */ 11968 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11969 return -1; 11970 /* Nothing else to do if there is no buffer. */ 11971 if (!out) 11972 return len; 11973 /* Make sure buffer is large enough. */ 11974 if (size < sizeof(*out)) 11975 return -1; 11976 ctx->objdata = 0; 11977 ctx->objmask = NULL; 11978 ctx->object = out; 11979 if (!out->command) 11980 return -1; 11981 out->command = ctx->curr; 11982 /* For encap/decap we need is pattern */ 11983 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11984 sizeof(double)); 11985 return len; 11986 } 11987 11988 /** Parse set command, initialize output buffer for subsequent tokens. */ 11989 static int 11990 parse_set_sample_action(struct context *ctx, const struct token *token, 11991 const char *str, unsigned int len, 11992 void *buf, unsigned int size) 11993 { 11994 struct buffer *out = buf; 11995 11996 /* Token name must match. */ 11997 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11998 return -1; 11999 /* Nothing else to do if there is no buffer. */ 12000 if (!out) 12001 return len; 12002 /* Make sure buffer is large enough. */ 12003 if (size < sizeof(*out)) 12004 return -1; 12005 ctx->objdata = 0; 12006 ctx->objmask = NULL; 12007 ctx->object = out; 12008 if (!out->command) 12009 return -1; 12010 out->command = ctx->curr; 12011 /* For sampler we need is actions */ 12012 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12013 sizeof(double)); 12014 return len; 12015 } 12016 12017 /** Parse set command, initialize output buffer for subsequent tokens. */ 12018 static int 12019 parse_set_ipv6_ext_action(struct context *ctx, const struct token *token, 12020 const char *str, unsigned int len, 12021 void *buf, unsigned int size) 12022 { 12023 struct buffer *out = buf; 12024 12025 /* Token name must match. */ 12026 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12027 return -1; 12028 /* Nothing else to do if there is no buffer. */ 12029 if (!out) 12030 return len; 12031 /* Make sure buffer is large enough. */ 12032 if (size < sizeof(*out)) 12033 return -1; 12034 ctx->objdata = 0; 12035 ctx->objmask = NULL; 12036 ctx->object = out; 12037 if (!out->command) 12038 return -1; 12039 out->command = ctx->curr; 12040 /* For ipv6_ext_push/remove we need is pattern */ 12041 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12042 sizeof(double)); 12043 return len; 12044 } 12045 12046 /** 12047 * Parse set raw_encap/raw_decap command, 12048 * initialize output buffer for subsequent tokens. 12049 */ 12050 static int 12051 parse_set_init(struct context *ctx, const struct token *token, 12052 const char *str, unsigned int len, 12053 void *buf, unsigned int size) 12054 { 12055 struct buffer *out = buf; 12056 12057 /* Token name must match. */ 12058 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12059 return -1; 12060 /* Nothing else to do if there is no buffer. */ 12061 if (!out) 12062 return len; 12063 /* Make sure buffer is large enough. */ 12064 if (size < sizeof(*out)) 12065 return -1; 12066 /* Initialize buffer. */ 12067 memset(out, 0x00, sizeof(*out)); 12068 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 12069 ctx->objdata = 0; 12070 ctx->object = out; 12071 ctx->objmask = NULL; 12072 if (!out->command) { 12073 if (ctx->curr != SET) 12074 return -1; 12075 if (sizeof(*out) > size) 12076 return -1; 12077 out->command = ctx->curr; 12078 out->args.vc.data = (uint8_t *)out + size; 12079 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12080 sizeof(double)); 12081 } 12082 return len; 12083 } 12084 12085 /* 12086 * Replace testpmd handles in a flex flow item with real values. 12087 */ 12088 static int 12089 parse_flex_handle(struct context *ctx, const struct token *token, 12090 const char *str, unsigned int len, 12091 void *buf, unsigned int size) 12092 { 12093 struct rte_flow_item_flex *spec, *mask; 12094 const struct rte_flow_item_flex *src_spec, *src_mask; 12095 const struct arg *arg = pop_args(ctx); 12096 uint32_t offset; 12097 uint16_t handle; 12098 int ret; 12099 12100 if (!arg) { 12101 printf("Bad environment\n"); 12102 return -1; 12103 } 12104 offset = arg->offset; 12105 push_args(ctx, arg); 12106 ret = parse_int(ctx, token, str, len, buf, size); 12107 if (ret <= 0 || !ctx->object) 12108 return ret; 12109 if (ctx->port >= RTE_MAX_ETHPORTS) { 12110 printf("Bad port\n"); 12111 return -1; 12112 } 12113 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 12114 const struct flex_item *fp; 12115 spec = ctx->object; 12116 handle = (uint16_t)(uintptr_t)spec->handle; 12117 if (handle >= FLEX_MAX_PARSERS_NUM) { 12118 printf("Bad flex item handle\n"); 12119 return -1; 12120 } 12121 fp = flex_items[ctx->port][handle]; 12122 if (!fp) { 12123 printf("Bad flex item handle\n"); 12124 return -1; 12125 } 12126 spec->handle = fp->flex_handle; 12127 mask = spec + 2; /* spec, last, mask */ 12128 mask->handle = fp->flex_handle; 12129 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 12130 handle = (uint16_t)(uintptr_t) 12131 ((struct rte_flow_item_flex *)ctx->object)->pattern; 12132 if (handle >= FLEX_MAX_PATTERNS_NUM) { 12133 printf("Bad pattern handle\n"); 12134 return -1; 12135 } 12136 src_spec = &flex_patterns[handle].spec; 12137 src_mask = &flex_patterns[handle].mask; 12138 spec = ctx->object; 12139 mask = spec + 2; /* spec, last, mask */ 12140 /* fill flow rule spec and mask parameters */ 12141 spec->length = src_spec->length; 12142 spec->pattern = src_spec->pattern; 12143 mask->length = src_mask->length; 12144 mask->pattern = src_mask->pattern; 12145 } else { 12146 printf("Bad arguments - unknown flex item offset\n"); 12147 return -1; 12148 } 12149 return ret; 12150 } 12151 12152 /** Parse Meter color name */ 12153 static int 12154 parse_meter_color(struct context *ctx, const struct token *token, 12155 const char *str, unsigned int len, void *buf, 12156 unsigned int size) 12157 { 12158 struct rte_flow_item_meter_color *meter_color; 12159 unsigned int i; 12160 12161 (void)token; 12162 (void)buf; 12163 (void)size; 12164 for (i = 0; meter_colors[i]; ++i) 12165 if (!strcmp_partial(meter_colors[i], str, len)) 12166 break; 12167 if (!meter_colors[i]) 12168 return -1; 12169 if (!ctx->object) 12170 return len; 12171 meter_color = ctx->object; 12172 meter_color->color = (enum rte_color)i; 12173 return len; 12174 } 12175 12176 /** Parse Insertion Table Type name */ 12177 static int 12178 parse_insertion_table_type(struct context *ctx, const struct token *token, 12179 const char *str, unsigned int len, void *buf, 12180 unsigned int size) 12181 { 12182 const struct arg *arg = pop_args(ctx); 12183 unsigned int i; 12184 char tmp[2]; 12185 int ret; 12186 12187 (void)size; 12188 /* Argument is expected. */ 12189 if (!arg) 12190 return -1; 12191 for (i = 0; table_insertion_types[i]; ++i) 12192 if (!strcmp_partial(table_insertion_types[i], str, len)) 12193 break; 12194 if (!table_insertion_types[i]) 12195 return -1; 12196 push_args(ctx, arg); 12197 snprintf(tmp, sizeof(tmp), "%u", i); 12198 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12199 return ret > 0 ? (int)len : ret; 12200 } 12201 12202 /** Parse Hash Calculation Table Type name */ 12203 static int 12204 parse_hash_table_type(struct context *ctx, const struct token *token, 12205 const char *str, unsigned int len, void *buf, 12206 unsigned int size) 12207 { 12208 const struct arg *arg = pop_args(ctx); 12209 unsigned int i; 12210 char tmp[2]; 12211 int ret; 12212 12213 (void)size; 12214 /* Argument is expected. */ 12215 if (!arg) 12216 return -1; 12217 for (i = 0; table_hash_funcs[i]; ++i) 12218 if (!strcmp_partial(table_hash_funcs[i], str, len)) 12219 break; 12220 if (!table_hash_funcs[i]) 12221 return -1; 12222 push_args(ctx, arg); 12223 snprintf(tmp, sizeof(tmp), "%u", i); 12224 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12225 return ret > 0 ? (int)len : ret; 12226 } 12227 12228 static int 12229 parse_name_to_index(struct context *ctx, const struct token *token, 12230 const char *str, unsigned int len, void *buf, 12231 unsigned int size, 12232 const char *const names[], size_t names_size, uint32_t *dst) 12233 { 12234 int ret; 12235 uint32_t i; 12236 12237 RTE_SET_USED(token); 12238 RTE_SET_USED(buf); 12239 RTE_SET_USED(size); 12240 if (!ctx->object) 12241 return len; 12242 for (i = 0; i < names_size; i++) { 12243 if (!names[i]) 12244 continue; 12245 ret = strcmp_partial(names[i], str, 12246 RTE_MIN(len, strlen(names[i]))); 12247 if (!ret) { 12248 *dst = i; 12249 return len; 12250 } 12251 } 12252 return -1; 12253 } 12254 12255 static const char *const quota_mode_names[] = { 12256 NULL, 12257 [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", 12258 [RTE_FLOW_QUOTA_MODE_L2] = "l2", 12259 [RTE_FLOW_QUOTA_MODE_L3] = "l3" 12260 }; 12261 12262 static const char *const quota_state_names[] = { 12263 [RTE_FLOW_QUOTA_STATE_PASS] = "pass", 12264 [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" 12265 }; 12266 12267 static const char *const quota_update_names[] = { 12268 [RTE_FLOW_UPDATE_QUOTA_SET] = "set", 12269 [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" 12270 }; 12271 12272 static const char *const query_update_mode_names[] = { 12273 [RTE_FLOW_QU_QUERY_FIRST] = "query_first", 12274 [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" 12275 }; 12276 12277 static int 12278 parse_quota_state_name(struct context *ctx, const struct token *token, 12279 const char *str, unsigned int len, void *buf, 12280 unsigned int size) 12281 { 12282 struct rte_flow_item_quota *quota = ctx->object; 12283 12284 return parse_name_to_index(ctx, token, str, len, buf, size, 12285 quota_state_names, 12286 RTE_DIM(quota_state_names), 12287 (uint32_t *)"a->state); 12288 } 12289 12290 static int 12291 parse_quota_mode_name(struct context *ctx, const struct token *token, 12292 const char *str, unsigned int len, void *buf, 12293 unsigned int size) 12294 { 12295 struct rte_flow_action_quota *quota = ctx->object; 12296 12297 return parse_name_to_index(ctx, token, str, len, buf, size, 12298 quota_mode_names, 12299 RTE_DIM(quota_mode_names), 12300 (uint32_t *)"a->mode); 12301 } 12302 12303 static int 12304 parse_quota_update_name(struct context *ctx, const struct token *token, 12305 const char *str, unsigned int len, void *buf, 12306 unsigned int size) 12307 { 12308 struct rte_flow_update_quota *update = ctx->object; 12309 12310 return parse_name_to_index(ctx, token, str, len, buf, size, 12311 quota_update_names, 12312 RTE_DIM(quota_update_names), 12313 (uint32_t *)&update->op); 12314 } 12315 12316 static int 12317 parse_qu_mode_name(struct context *ctx, const struct token *token, 12318 const char *str, unsigned int len, void *buf, 12319 unsigned int size) 12320 { 12321 struct buffer *out = ctx->object; 12322 12323 return parse_name_to_index(ctx, token, str, len, buf, size, 12324 query_update_mode_names, 12325 RTE_DIM(query_update_mode_names), 12326 (uint32_t *)&out->args.ia.qu_mode); 12327 } 12328 12329 /** No completion. */ 12330 static int 12331 comp_none(struct context *ctx, const struct token *token, 12332 unsigned int ent, char *buf, unsigned int size) 12333 { 12334 (void)ctx; 12335 (void)token; 12336 (void)ent; 12337 (void)buf; 12338 (void)size; 12339 return 0; 12340 } 12341 12342 /** Complete boolean values. */ 12343 static int 12344 comp_boolean(struct context *ctx, const struct token *token, 12345 unsigned int ent, char *buf, unsigned int size) 12346 { 12347 unsigned int i; 12348 12349 (void)ctx; 12350 (void)token; 12351 for (i = 0; boolean_name[i]; ++i) 12352 if (buf && i == ent) 12353 return strlcpy(buf, boolean_name[i], size); 12354 if (buf) 12355 return -1; 12356 return i; 12357 } 12358 12359 /** Complete action names. */ 12360 static int 12361 comp_action(struct context *ctx, const struct token *token, 12362 unsigned int ent, char *buf, unsigned int size) 12363 { 12364 unsigned int i; 12365 12366 (void)ctx; 12367 (void)token; 12368 for (i = 0; next_action[i]; ++i) 12369 if (buf && i == ent) 12370 return strlcpy(buf, token_list[next_action[i]].name, 12371 size); 12372 if (buf) 12373 return -1; 12374 return i; 12375 } 12376 12377 /** Complete available ports. */ 12378 static int 12379 comp_port(struct context *ctx, const struct token *token, 12380 unsigned int ent, char *buf, unsigned int size) 12381 { 12382 unsigned int i = 0; 12383 portid_t p; 12384 12385 (void)ctx; 12386 (void)token; 12387 RTE_ETH_FOREACH_DEV(p) { 12388 if (buf && i == ent) 12389 return snprintf(buf, size, "%u", p); 12390 ++i; 12391 } 12392 if (buf) 12393 return -1; 12394 return i; 12395 } 12396 12397 /** Complete available rule IDs. */ 12398 static int 12399 comp_rule_id(struct context *ctx, const struct token *token, 12400 unsigned int ent, char *buf, unsigned int size) 12401 { 12402 unsigned int i = 0; 12403 struct rte_port *port; 12404 struct port_flow *pf; 12405 12406 (void)token; 12407 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12408 ctx->port == (portid_t)RTE_PORT_ALL) 12409 return -1; 12410 port = &ports[ctx->port]; 12411 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 12412 if (buf && i == ent) 12413 return snprintf(buf, size, "%"PRIu64, pf->id); 12414 ++i; 12415 } 12416 if (buf) 12417 return -1; 12418 return i; 12419 } 12420 12421 /** Complete operation for compare match item. */ 12422 static int 12423 comp_set_compare_op(struct context *ctx, const struct token *token, 12424 unsigned int ent, char *buf, unsigned int size) 12425 { 12426 RTE_SET_USED(ctx); 12427 RTE_SET_USED(token); 12428 if (!buf) 12429 return RTE_DIM(compare_ops); 12430 if (ent < RTE_DIM(compare_ops) - 1) 12431 return strlcpy(buf, compare_ops[ent], size); 12432 return -1; 12433 } 12434 12435 /** Complete field id for compare match item. */ 12436 static int 12437 comp_set_compare_field_id(struct context *ctx, const struct token *token, 12438 unsigned int ent, char *buf, unsigned int size) 12439 { 12440 const char *name; 12441 12442 RTE_SET_USED(token); 12443 if (!buf) 12444 return RTE_DIM(flow_field_ids); 12445 if (ent >= RTE_DIM(flow_field_ids) - 1) 12446 return -1; 12447 name = flow_field_ids[ent]; 12448 if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE || 12449 (strcmp(name, "pointer") && strcmp(name, "value"))) 12450 return strlcpy(buf, name, size); 12451 return -1; 12452 } 12453 12454 /** Complete type field for RSS action. */ 12455 static int 12456 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 12457 unsigned int ent, char *buf, unsigned int size) 12458 { 12459 unsigned int i; 12460 12461 (void)ctx; 12462 (void)token; 12463 for (i = 0; rss_type_table[i].str; ++i) 12464 ; 12465 if (!buf) 12466 return i + 1; 12467 if (ent < i) 12468 return strlcpy(buf, rss_type_table[ent].str, size); 12469 if (ent == i) 12470 return snprintf(buf, size, "end"); 12471 return -1; 12472 } 12473 12474 /** Complete queue field for RSS action. */ 12475 static int 12476 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 12477 unsigned int ent, char *buf, unsigned int size) 12478 { 12479 (void)ctx; 12480 (void)token; 12481 if (!buf) 12482 return nb_rxq + 1; 12483 if (ent < nb_rxq) 12484 return snprintf(buf, size, "%u", ent); 12485 if (ent == nb_rxq) 12486 return snprintf(buf, size, "end"); 12487 return -1; 12488 } 12489 12490 /** Complete index number for set raw_encap/raw_decap commands. */ 12491 static int 12492 comp_set_raw_index(struct context *ctx, const struct token *token, 12493 unsigned int ent, char *buf, unsigned int size) 12494 { 12495 uint16_t idx = 0; 12496 uint16_t nb = 0; 12497 12498 RTE_SET_USED(ctx); 12499 RTE_SET_USED(token); 12500 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 12501 if (buf && idx == ent) 12502 return snprintf(buf, size, "%u", idx); 12503 ++nb; 12504 } 12505 return nb; 12506 } 12507 12508 /** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ 12509 static int 12510 comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 12511 unsigned int ent, char *buf, unsigned int size) 12512 { 12513 uint16_t idx = 0; 12514 uint16_t nb = 0; 12515 12516 RTE_SET_USED(ctx); 12517 RTE_SET_USED(token); 12518 for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { 12519 if (buf && idx == ent) 12520 return snprintf(buf, size, "%u", idx); 12521 ++nb; 12522 } 12523 return nb; 12524 } 12525 12526 /** Complete index number for set raw_encap/raw_decap commands. */ 12527 static int 12528 comp_set_sample_index(struct context *ctx, const struct token *token, 12529 unsigned int ent, char *buf, unsigned int size) 12530 { 12531 uint16_t idx = 0; 12532 uint16_t nb = 0; 12533 12534 RTE_SET_USED(ctx); 12535 RTE_SET_USED(token); 12536 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 12537 if (buf && idx == ent) 12538 return snprintf(buf, size, "%u", idx); 12539 ++nb; 12540 } 12541 return nb; 12542 } 12543 12544 /** Complete operation for modify_field command. */ 12545 static int 12546 comp_set_modify_field_op(struct context *ctx, const struct token *token, 12547 unsigned int ent, char *buf, unsigned int size) 12548 { 12549 RTE_SET_USED(ctx); 12550 RTE_SET_USED(token); 12551 if (!buf) 12552 return RTE_DIM(modify_field_ops); 12553 if (ent < RTE_DIM(modify_field_ops) - 1) 12554 return strlcpy(buf, modify_field_ops[ent], size); 12555 return -1; 12556 } 12557 12558 /** Complete field id for modify_field command. */ 12559 static int 12560 comp_set_modify_field_id(struct context *ctx, const struct token *token, 12561 unsigned int ent, char *buf, unsigned int size) 12562 { 12563 const char *name; 12564 12565 RTE_SET_USED(token); 12566 if (!buf) 12567 return RTE_DIM(flow_field_ids); 12568 if (ent >= RTE_DIM(flow_field_ids) - 1) 12569 return -1; 12570 name = flow_field_ids[ent]; 12571 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 12572 (strcmp(name, "pointer") && strcmp(name, "value"))) 12573 return strlcpy(buf, name, size); 12574 return -1; 12575 } 12576 12577 /** Complete available pattern template IDs. */ 12578 static int 12579 comp_pattern_template_id(struct context *ctx, const struct token *token, 12580 unsigned int ent, char *buf, unsigned int size) 12581 { 12582 unsigned int i = 0; 12583 struct rte_port *port; 12584 struct port_template *pt; 12585 12586 (void)token; 12587 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12588 ctx->port == (portid_t)RTE_PORT_ALL) 12589 return -1; 12590 port = &ports[ctx->port]; 12591 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 12592 if (buf && i == ent) 12593 return snprintf(buf, size, "%u", pt->id); 12594 ++i; 12595 } 12596 if (buf) 12597 return -1; 12598 return i; 12599 } 12600 12601 /** Complete available actions template IDs. */ 12602 static int 12603 comp_actions_template_id(struct context *ctx, const struct token *token, 12604 unsigned int ent, char *buf, unsigned int size) 12605 { 12606 unsigned int i = 0; 12607 struct rte_port *port; 12608 struct port_template *pt; 12609 12610 (void)token; 12611 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12612 ctx->port == (portid_t)RTE_PORT_ALL) 12613 return -1; 12614 port = &ports[ctx->port]; 12615 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 12616 if (buf && i == ent) 12617 return snprintf(buf, size, "%u", pt->id); 12618 ++i; 12619 } 12620 if (buf) 12621 return -1; 12622 return i; 12623 } 12624 12625 /** Complete available table IDs. */ 12626 static int 12627 comp_table_id(struct context *ctx, const struct token *token, 12628 unsigned int ent, char *buf, unsigned int size) 12629 { 12630 unsigned int i = 0; 12631 struct rte_port *port; 12632 struct port_table *pt; 12633 12634 (void)token; 12635 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12636 ctx->port == (portid_t)RTE_PORT_ALL) 12637 return -1; 12638 port = &ports[ctx->port]; 12639 for (pt = port->table_list; pt != NULL; pt = pt->next) { 12640 if (buf && i == ent) 12641 return snprintf(buf, size, "%u", pt->id); 12642 ++i; 12643 } 12644 if (buf) 12645 return -1; 12646 return i; 12647 } 12648 12649 /** Complete available queue IDs. */ 12650 static int 12651 comp_queue_id(struct context *ctx, const struct token *token, 12652 unsigned int ent, char *buf, unsigned int size) 12653 { 12654 unsigned int i = 0; 12655 struct rte_port *port; 12656 12657 (void)token; 12658 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12659 ctx->port == (portid_t)RTE_PORT_ALL) 12660 return -1; 12661 port = &ports[ctx->port]; 12662 for (i = 0; i < port->queue_nb; i++) { 12663 if (buf && i == ent) 12664 return snprintf(buf, size, "%u", i); 12665 } 12666 if (buf) 12667 return -1; 12668 return i; 12669 } 12670 12671 static int 12672 comp_names_to_index(struct context *ctx, const struct token *token, 12673 unsigned int ent, char *buf, unsigned int size, 12674 const char *const names[], size_t names_size) 12675 { 12676 RTE_SET_USED(ctx); 12677 RTE_SET_USED(token); 12678 if (!buf) 12679 return names_size; 12680 if (names[ent] && ent < names_size) 12681 return rte_strscpy(buf, names[ent], size); 12682 return -1; 12683 12684 } 12685 12686 /** Complete available Meter colors. */ 12687 static int 12688 comp_meter_color(struct context *ctx, const struct token *token, 12689 unsigned int ent, char *buf, unsigned int size) 12690 { 12691 RTE_SET_USED(ctx); 12692 RTE_SET_USED(token); 12693 if (!buf) 12694 return RTE_DIM(meter_colors); 12695 if (ent < RTE_DIM(meter_colors) - 1) 12696 return strlcpy(buf, meter_colors[ent], size); 12697 return -1; 12698 } 12699 12700 /** Complete available Insertion Table types. */ 12701 static int 12702 comp_insertion_table_type(struct context *ctx, const struct token *token, 12703 unsigned int ent, char *buf, unsigned int size) 12704 { 12705 RTE_SET_USED(ctx); 12706 RTE_SET_USED(token); 12707 if (!buf) 12708 return RTE_DIM(table_insertion_types); 12709 if (ent < RTE_DIM(table_insertion_types) - 1) 12710 return rte_strscpy(buf, table_insertion_types[ent], size); 12711 return -1; 12712 } 12713 12714 /** Complete available Hash Calculation Table types. */ 12715 static int 12716 comp_hash_table_type(struct context *ctx, const struct token *token, 12717 unsigned int ent, char *buf, unsigned int size) 12718 { 12719 RTE_SET_USED(ctx); 12720 RTE_SET_USED(token); 12721 if (!buf) 12722 return RTE_DIM(table_hash_funcs); 12723 if (ent < RTE_DIM(table_hash_funcs) - 1) 12724 return rte_strscpy(buf, table_hash_funcs[ent], size); 12725 return -1; 12726 } 12727 12728 static int 12729 comp_quota_state_name(struct context *ctx, const struct token *token, 12730 unsigned int ent, char *buf, unsigned int size) 12731 { 12732 return comp_names_to_index(ctx, token, ent, buf, size, 12733 quota_state_names, 12734 RTE_DIM(quota_state_names)); 12735 } 12736 12737 static int 12738 comp_quota_mode_name(struct context *ctx, const struct token *token, 12739 unsigned int ent, char *buf, unsigned int size) 12740 { 12741 return comp_names_to_index(ctx, token, ent, buf, size, 12742 quota_mode_names, 12743 RTE_DIM(quota_mode_names)); 12744 } 12745 12746 static int 12747 comp_quota_update_name(struct context *ctx, const struct token *token, 12748 unsigned int ent, char *buf, unsigned int size) 12749 { 12750 return comp_names_to_index(ctx, token, ent, buf, size, 12751 quota_update_names, 12752 RTE_DIM(quota_update_names)); 12753 } 12754 12755 static int 12756 comp_qu_mode_name(struct context *ctx, const struct token *token, 12757 unsigned int ent, char *buf, unsigned int size) 12758 { 12759 return comp_names_to_index(ctx, token, ent, buf, size, 12760 query_update_mode_names, 12761 RTE_DIM(query_update_mode_names)); 12762 } 12763 12764 /** Internal context. */ 12765 static struct context cmd_flow_context; 12766 12767 /** Global parser instance (cmdline API). */ 12768 cmdline_parse_inst_t cmd_flow; 12769 cmdline_parse_inst_t cmd_set_raw; 12770 12771 /** Initialize context. */ 12772 static void 12773 cmd_flow_context_init(struct context *ctx) 12774 { 12775 /* A full memset() is not necessary. */ 12776 ctx->curr = ZERO; 12777 ctx->prev = ZERO; 12778 ctx->next_num = 0; 12779 ctx->args_num = 0; 12780 ctx->eol = 0; 12781 ctx->last = 0; 12782 ctx->port = 0; 12783 ctx->objdata = 0; 12784 ctx->object = NULL; 12785 ctx->objmask = NULL; 12786 } 12787 12788 /** Parse a token (cmdline API). */ 12789 static int 12790 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 12791 unsigned int size) 12792 { 12793 struct context *ctx = &cmd_flow_context; 12794 const struct token *token; 12795 const enum index *list; 12796 int len; 12797 int i; 12798 12799 (void)hdr; 12800 token = &token_list[ctx->curr]; 12801 /* Check argument length. */ 12802 ctx->eol = 0; 12803 ctx->last = 1; 12804 for (len = 0; src[len]; ++len) 12805 if (src[len] == '#' || isspace(src[len])) 12806 break; 12807 if (!len) 12808 return -1; 12809 /* Last argument and EOL detection. */ 12810 for (i = len; src[i]; ++i) 12811 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 12812 break; 12813 else if (!isspace(src[i])) { 12814 ctx->last = 0; 12815 break; 12816 } 12817 for (; src[i]; ++i) 12818 if (src[i] == '\r' || src[i] == '\n') { 12819 ctx->eol = 1; 12820 break; 12821 } 12822 /* Initialize context if necessary. */ 12823 if (!ctx->next_num) { 12824 if (!token->next) 12825 return 0; 12826 ctx->next[ctx->next_num++] = token->next[0]; 12827 } 12828 /* Process argument through candidates. */ 12829 ctx->prev = ctx->curr; 12830 list = ctx->next[ctx->next_num - 1]; 12831 for (i = 0; list[i]; ++i) { 12832 const struct token *next = &token_list[list[i]]; 12833 int tmp; 12834 12835 ctx->curr = list[i]; 12836 if (next->call) 12837 tmp = next->call(ctx, next, src, len, result, size); 12838 else 12839 tmp = parse_default(ctx, next, src, len, result, size); 12840 if (tmp == -1 || tmp != len) 12841 continue; 12842 token = next; 12843 break; 12844 } 12845 if (!list[i]) 12846 return -1; 12847 --ctx->next_num; 12848 /* Push subsequent tokens if any. */ 12849 if (token->next) 12850 for (i = 0; token->next[i]; ++i) { 12851 if (ctx->next_num == RTE_DIM(ctx->next)) 12852 return -1; 12853 ctx->next[ctx->next_num++] = token->next[i]; 12854 } 12855 /* Push arguments if any. */ 12856 if (token->args) 12857 for (i = 0; token->args[i]; ++i) { 12858 if (ctx->args_num == RTE_DIM(ctx->args)) 12859 return -1; 12860 ctx->args[ctx->args_num++] = token->args[i]; 12861 } 12862 return len; 12863 } 12864 12865 int 12866 flow_parse(const char *src, void *result, unsigned int size, 12867 struct rte_flow_attr **attr, 12868 struct rte_flow_item **pattern, struct rte_flow_action **actions) 12869 { 12870 int ret; 12871 struct context saved_flow_ctx = cmd_flow_context; 12872 12873 cmd_flow_context_init(&cmd_flow_context); 12874 do { 12875 ret = cmd_flow_parse(NULL, src, result, size); 12876 if (ret > 0) { 12877 src += ret; 12878 while (isspace(*src)) 12879 src++; 12880 } 12881 } while (ret > 0 && strlen(src)); 12882 cmd_flow_context = saved_flow_ctx; 12883 *attr = &((struct buffer *)result)->args.vc.attr; 12884 *pattern = ((struct buffer *)result)->args.vc.pattern; 12885 *actions = ((struct buffer *)result)->args.vc.actions; 12886 return (ret >= 0 && !strlen(src)) ? 0 : -1; 12887 } 12888 12889 /** Return number of completion entries (cmdline API). */ 12890 static int 12891 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 12892 { 12893 struct context *ctx = &cmd_flow_context; 12894 const struct token *token = &token_list[ctx->curr]; 12895 const enum index *list; 12896 int i; 12897 12898 (void)hdr; 12899 /* Count number of tokens in current list. */ 12900 if (ctx->next_num) 12901 list = ctx->next[ctx->next_num - 1]; 12902 else 12903 list = token->next[0]; 12904 for (i = 0; list[i]; ++i) 12905 ; 12906 if (!i) 12907 return 0; 12908 /* 12909 * If there is a single token, use its completion callback, otherwise 12910 * return the number of entries. 12911 */ 12912 token = &token_list[list[0]]; 12913 if (i == 1 && token->comp) { 12914 /* Save index for cmd_flow_get_help(). */ 12915 ctx->prev = list[0]; 12916 return token->comp(ctx, token, 0, NULL, 0); 12917 } 12918 return i; 12919 } 12920 12921 /** Return a completion entry (cmdline API). */ 12922 static int 12923 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 12924 char *dst, unsigned int size) 12925 { 12926 struct context *ctx = &cmd_flow_context; 12927 const struct token *token = &token_list[ctx->curr]; 12928 const enum index *list; 12929 int i; 12930 12931 (void)hdr; 12932 /* Count number of tokens in current list. */ 12933 if (ctx->next_num) 12934 list = ctx->next[ctx->next_num - 1]; 12935 else 12936 list = token->next[0]; 12937 for (i = 0; list[i]; ++i) 12938 ; 12939 if (!i) 12940 return -1; 12941 /* If there is a single token, use its completion callback. */ 12942 token = &token_list[list[0]]; 12943 if (i == 1 && token->comp) { 12944 /* Save index for cmd_flow_get_help(). */ 12945 ctx->prev = list[0]; 12946 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 12947 } 12948 /* Otherwise make sure the index is valid and use defaults. */ 12949 if (index >= i) 12950 return -1; 12951 token = &token_list[list[index]]; 12952 strlcpy(dst, token->name, size); 12953 /* Save index for cmd_flow_get_help(). */ 12954 ctx->prev = list[index]; 12955 return 0; 12956 } 12957 12958 /** Populate help strings for current token (cmdline API). */ 12959 static int 12960 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 12961 { 12962 struct context *ctx = &cmd_flow_context; 12963 const struct token *token = &token_list[ctx->prev]; 12964 12965 (void)hdr; 12966 if (!size) 12967 return -1; 12968 /* Set token type and update global help with details. */ 12969 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 12970 if (token->help) 12971 cmd_flow.help_str = token->help; 12972 else 12973 cmd_flow.help_str = token->name; 12974 return 0; 12975 } 12976 12977 /** Token definition template (cmdline API). */ 12978 static struct cmdline_token_hdr cmd_flow_token_hdr = { 12979 .ops = &(struct cmdline_token_ops){ 12980 .parse = cmd_flow_parse, 12981 .complete_get_nb = cmd_flow_complete_get_nb, 12982 .complete_get_elt = cmd_flow_complete_get_elt, 12983 .get_help = cmd_flow_get_help, 12984 }, 12985 .offset = 0, 12986 }; 12987 12988 /** Populate the next dynamic token. */ 12989 static void 12990 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 12991 cmdline_parse_token_hdr_t **hdr_inst) 12992 { 12993 struct context *ctx = &cmd_flow_context; 12994 12995 /* Always reinitialize context before requesting the first token. */ 12996 if (!(hdr_inst - cmd_flow.tokens)) 12997 cmd_flow_context_init(ctx); 12998 /* Return NULL when no more tokens are expected. */ 12999 if (!ctx->next_num && ctx->curr) { 13000 *hdr = NULL; 13001 return; 13002 } 13003 /* Determine if command should end here. */ 13004 if (ctx->eol && ctx->last && ctx->next_num) { 13005 const enum index *list = ctx->next[ctx->next_num - 1]; 13006 int i; 13007 13008 for (i = 0; list[i]; ++i) { 13009 if (list[i] != END) 13010 continue; 13011 *hdr = NULL; 13012 return; 13013 } 13014 } 13015 *hdr = &cmd_flow_token_hdr; 13016 } 13017 13018 static SLIST_HEAD(, indlst_conf) indlst_conf_head = 13019 SLIST_HEAD_INITIALIZER(); 13020 13021 static void 13022 indirect_action_flow_conf_create(const struct buffer *in) 13023 { 13024 int len, ret; 13025 uint32_t i; 13026 struct indlst_conf *indlst_conf = NULL; 13027 size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); 13028 struct rte_flow_action *src = in->args.vc.actions; 13029 13030 if (!in->args.vc.actions_n) 13031 goto end; 13032 len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); 13033 if (len <= 0) 13034 goto end; 13035 len = RTE_ALIGN(len, 16); 13036 13037 indlst_conf = calloc(1, base + len + 13038 in->args.vc.actions_n * sizeof(uintptr_t)); 13039 if (!indlst_conf) 13040 goto end; 13041 indlst_conf->id = in->args.vc.attr.group; 13042 indlst_conf->conf_num = in->args.vc.actions_n - 1; 13043 indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); 13044 ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, 13045 len, src, NULL); 13046 if (ret <= 0) { 13047 free(indlst_conf); 13048 indlst_conf = NULL; 13049 goto end; 13050 } 13051 indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); 13052 for (i = 0; i < indlst_conf->conf_num; i++) 13053 indlst_conf->conf[i] = indlst_conf->actions[i].conf; 13054 SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); 13055 end: 13056 if (indlst_conf) 13057 printf("created indirect action list configuration %u\n", 13058 in->args.vc.attr.group); 13059 else 13060 printf("cannot create indirect action list configuration %u\n", 13061 in->args.vc.attr.group); 13062 } 13063 13064 static const struct indlst_conf * 13065 indirect_action_list_conf_get(uint32_t conf_id) 13066 { 13067 const struct indlst_conf *conf; 13068 13069 SLIST_FOREACH(conf, &indlst_conf_head, next) { 13070 if (conf->id == conf_id) 13071 return conf; 13072 } 13073 return NULL; 13074 } 13075 13076 /** Dispatch parsed buffer to function calls. */ 13077 static void 13078 cmd_flow_parsed(const struct buffer *in) 13079 { 13080 switch (in->command) { 13081 case INFO: 13082 port_flow_get_info(in->port); 13083 break; 13084 case CONFIGURE: 13085 port_flow_configure(in->port, 13086 &in->args.configure.port_attr, 13087 in->args.configure.nb_queue, 13088 &in->args.configure.queue_attr); 13089 break; 13090 case PATTERN_TEMPLATE_CREATE: 13091 port_flow_pattern_template_create(in->port, 13092 in->args.vc.pat_templ_id, 13093 &((const struct rte_flow_pattern_template_attr) { 13094 .relaxed_matching = in->args.vc.attr.reserved, 13095 .ingress = in->args.vc.attr.ingress, 13096 .egress = in->args.vc.attr.egress, 13097 .transfer = in->args.vc.attr.transfer, 13098 }), 13099 in->args.vc.pattern); 13100 break; 13101 case PATTERN_TEMPLATE_DESTROY: 13102 port_flow_pattern_template_destroy(in->port, 13103 in->args.templ_destroy.template_id_n, 13104 in->args.templ_destroy.template_id); 13105 break; 13106 case ACTIONS_TEMPLATE_CREATE: 13107 port_flow_actions_template_create(in->port, 13108 in->args.vc.act_templ_id, 13109 &((const struct rte_flow_actions_template_attr) { 13110 .ingress = in->args.vc.attr.ingress, 13111 .egress = in->args.vc.attr.egress, 13112 .transfer = in->args.vc.attr.transfer, 13113 }), 13114 in->args.vc.actions, 13115 in->args.vc.masks); 13116 break; 13117 case ACTIONS_TEMPLATE_DESTROY: 13118 port_flow_actions_template_destroy(in->port, 13119 in->args.templ_destroy.template_id_n, 13120 in->args.templ_destroy.template_id); 13121 break; 13122 case TABLE_CREATE: 13123 port_flow_template_table_create(in->port, in->args.table.id, 13124 &in->args.table.attr, in->args.table.pat_templ_id_n, 13125 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 13126 in->args.table.act_templ_id); 13127 break; 13128 case TABLE_DESTROY: 13129 port_flow_template_table_destroy(in->port, 13130 in->args.table_destroy.table_id_n, 13131 in->args.table_destroy.table_id); 13132 break; 13133 case TABLE_RESIZE_COMPLETE: 13134 port_flow_template_table_resize_complete 13135 (in->port, in->args.table_destroy.table_id[0]); 13136 break; 13137 case GROUP_SET_MISS_ACTIONS: 13138 port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, 13139 in->args.vc.actions); 13140 break; 13141 case TABLE_RESIZE: 13142 port_flow_template_table_resize(in->port, in->args.table.id, 13143 in->args.table.attr.nb_flows); 13144 break; 13145 case QUEUE_CREATE: 13146 port_queue_flow_create(in->port, in->queue, in->postpone, 13147 in->args.vc.table_id, in->args.vc.rule_id, 13148 in->args.vc.pat_templ_id, in->args.vc.act_templ_id, 13149 in->args.vc.pattern, in->args.vc.actions); 13150 break; 13151 case QUEUE_DESTROY: 13152 port_queue_flow_destroy(in->port, in->queue, in->postpone, 13153 in->args.destroy.rule_n, 13154 in->args.destroy.rule); 13155 break; 13156 case QUEUE_FLOW_UPDATE_RESIZED: 13157 port_queue_flow_update_resized(in->port, in->queue, 13158 in->postpone, 13159 in->args.destroy.rule[0]); 13160 break; 13161 case QUEUE_UPDATE: 13162 port_queue_flow_update(in->port, in->queue, in->postpone, 13163 in->args.vc.rule_id, in->args.vc.act_templ_id, 13164 in->args.vc.actions); 13165 break; 13166 case PUSH: 13167 port_queue_flow_push(in->port, in->queue); 13168 break; 13169 case PULL: 13170 port_queue_flow_pull(in->port, in->queue); 13171 break; 13172 case HASH: 13173 if (!in->args.vc.encap_hash) 13174 port_flow_hash_calc(in->port, in->args.vc.table_id, 13175 in->args.vc.pat_templ_id, 13176 in->args.vc.pattern); 13177 else 13178 port_flow_hash_calc_encap(in->port, in->args.vc.field, 13179 in->args.vc.pattern); 13180 break; 13181 case QUEUE_AGED: 13182 port_queue_flow_aged(in->port, in->queue, 13183 in->args.aged.destroy); 13184 break; 13185 case QUEUE_INDIRECT_ACTION_CREATE: 13186 case QUEUE_INDIRECT_ACTION_LIST_CREATE: 13187 port_queue_action_handle_create( 13188 in->port, in->queue, in->postpone, 13189 in->args.vc.attr.group, 13190 &((const struct rte_flow_indir_action_conf) { 13191 .ingress = in->args.vc.attr.ingress, 13192 .egress = in->args.vc.attr.egress, 13193 .transfer = in->args.vc.attr.transfer, 13194 }), 13195 in->args.vc.actions); 13196 break; 13197 case QUEUE_INDIRECT_ACTION_DESTROY: 13198 port_queue_action_handle_destroy(in->port, 13199 in->queue, in->postpone, 13200 in->args.ia_destroy.action_id_n, 13201 in->args.ia_destroy.action_id); 13202 break; 13203 case QUEUE_INDIRECT_ACTION_UPDATE: 13204 port_queue_action_handle_update(in->port, 13205 in->queue, in->postpone, 13206 in->args.vc.attr.group, 13207 in->args.vc.actions); 13208 break; 13209 case QUEUE_INDIRECT_ACTION_QUERY: 13210 port_queue_action_handle_query(in->port, 13211 in->queue, in->postpone, 13212 in->args.ia.action_id); 13213 break; 13214 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 13215 port_queue_action_handle_query_update(in->port, in->queue, 13216 in->postpone, 13217 in->args.ia.action_id, 13218 in->args.ia.qu_mode, 13219 in->args.vc.actions); 13220 break; 13221 case INDIRECT_ACTION_CREATE: 13222 case INDIRECT_ACTION_LIST_CREATE: 13223 port_action_handle_create( 13224 in->port, in->args.vc.attr.group, 13225 in->command == INDIRECT_ACTION_LIST_CREATE, 13226 &((const struct rte_flow_indir_action_conf) { 13227 .ingress = in->args.vc.attr.ingress, 13228 .egress = in->args.vc.attr.egress, 13229 .transfer = in->args.vc.attr.transfer, 13230 }), 13231 in->args.vc.actions); 13232 break; 13233 case INDIRECT_ACTION_FLOW_CONF_CREATE: 13234 indirect_action_flow_conf_create(in); 13235 break; 13236 case INDIRECT_ACTION_DESTROY: 13237 port_action_handle_destroy(in->port, 13238 in->args.ia_destroy.action_id_n, 13239 in->args.ia_destroy.action_id); 13240 break; 13241 case INDIRECT_ACTION_UPDATE: 13242 port_action_handle_update(in->port, in->args.vc.attr.group, 13243 in->args.vc.actions); 13244 break; 13245 case INDIRECT_ACTION_QUERY: 13246 port_action_handle_query(in->port, in->args.ia.action_id); 13247 break; 13248 case INDIRECT_ACTION_QUERY_UPDATE: 13249 port_action_handle_query_update(in->port, 13250 in->args.ia.action_id, 13251 in->args.ia.qu_mode, 13252 in->args.vc.actions); 13253 break; 13254 case VALIDATE: 13255 port_flow_validate(in->port, &in->args.vc.attr, 13256 in->args.vc.pattern, in->args.vc.actions, 13257 &in->args.vc.tunnel_ops); 13258 break; 13259 case CREATE: 13260 port_flow_create(in->port, &in->args.vc.attr, 13261 in->args.vc.pattern, in->args.vc.actions, 13262 &in->args.vc.tunnel_ops, in->args.vc.user_id); 13263 break; 13264 case DESTROY: 13265 port_flow_destroy(in->port, in->args.destroy.rule_n, 13266 in->args.destroy.rule, 13267 in->args.destroy.is_user_id); 13268 break; 13269 case FLUSH: 13270 port_flow_flush(in->port); 13271 break; 13272 case DUMP_ONE: 13273 case DUMP_ALL: 13274 port_flow_dump(in->port, in->args.dump.mode, 13275 in->args.dump.rule, in->args.dump.file, 13276 in->args.dump.is_user_id); 13277 break; 13278 case QUERY: 13279 port_flow_query(in->port, in->args.query.rule, 13280 &in->args.query.action, 13281 in->args.query.is_user_id); 13282 break; 13283 case LIST: 13284 port_flow_list(in->port, in->args.list.group_n, 13285 in->args.list.group); 13286 break; 13287 case ISOLATE: 13288 port_flow_isolate(in->port, in->args.isolate.set); 13289 break; 13290 case AGED: 13291 port_flow_aged(in->port, in->args.aged.destroy); 13292 break; 13293 case TUNNEL_CREATE: 13294 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 13295 break; 13296 case TUNNEL_DESTROY: 13297 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 13298 break; 13299 case TUNNEL_LIST: 13300 port_flow_tunnel_list(in->port); 13301 break; 13302 case ACTION_POL_G: 13303 port_meter_policy_add(in->port, in->args.policy.policy_id, 13304 in->args.vc.actions); 13305 break; 13306 case FLEX_ITEM_CREATE: 13307 flex_item_create(in->port, in->args.flex.token, 13308 in->args.flex.filename); 13309 break; 13310 case FLEX_ITEM_DESTROY: 13311 flex_item_destroy(in->port, in->args.flex.token); 13312 break; 13313 default: 13314 break; 13315 } 13316 fflush(stdout); 13317 } 13318 13319 /** Token generator and output processing callback (cmdline API). */ 13320 static void 13321 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 13322 { 13323 if (cl == NULL) 13324 cmd_flow_tok(arg0, arg2); 13325 else 13326 cmd_flow_parsed(arg0); 13327 } 13328 13329 /** Global parser instance (cmdline API). */ 13330 cmdline_parse_inst_t cmd_flow = { 13331 .f = cmd_flow_cb, 13332 .data = NULL, /**< Unused. */ 13333 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 13334 .tokens = { 13335 NULL, 13336 }, /**< Tokens are returned by cmd_flow_tok(). */ 13337 }; 13338 13339 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 13340 13341 static void 13342 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 13343 { 13344 struct rte_ipv4_hdr *ipv4; 13345 struct rte_ether_hdr *eth; 13346 struct rte_ipv6_hdr *ipv6; 13347 struct rte_vxlan_hdr *vxlan; 13348 struct rte_vxlan_gpe_hdr *gpe; 13349 struct rte_flow_item_nvgre *nvgre; 13350 uint32_t ipv6_vtc_flow; 13351 13352 switch (item->type) { 13353 case RTE_FLOW_ITEM_TYPE_ETH: 13354 eth = (struct rte_ether_hdr *)buf; 13355 if (next_proto) 13356 eth->ether_type = rte_cpu_to_be_16(next_proto); 13357 break; 13358 case RTE_FLOW_ITEM_TYPE_IPV4: 13359 ipv4 = (struct rte_ipv4_hdr *)buf; 13360 if (!ipv4->version_ihl) 13361 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 13362 if (next_proto && ipv4->next_proto_id == 0) 13363 ipv4->next_proto_id = (uint8_t)next_proto; 13364 break; 13365 case RTE_FLOW_ITEM_TYPE_IPV6: 13366 ipv6 = (struct rte_ipv6_hdr *)buf; 13367 if (next_proto && ipv6->proto == 0) 13368 ipv6->proto = (uint8_t)next_proto; 13369 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 13370 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 13371 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 13372 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 13373 break; 13374 case RTE_FLOW_ITEM_TYPE_VXLAN: 13375 vxlan = (struct rte_vxlan_hdr *)buf; 13376 vxlan->vx_flags = 0x08; 13377 break; 13378 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13379 gpe = (struct rte_vxlan_gpe_hdr *)buf; 13380 gpe->vx_flags = 0x0C; 13381 break; 13382 case RTE_FLOW_ITEM_TYPE_NVGRE: 13383 nvgre = (struct rte_flow_item_nvgre *)buf; 13384 nvgre->protocol = rte_cpu_to_be_16(0x6558); 13385 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 13386 break; 13387 default: 13388 break; 13389 } 13390 } 13391 13392 /** Helper of get item's default mask. */ 13393 static const void * 13394 flow_item_default_mask(const struct rte_flow_item *item) 13395 { 13396 const void *mask = NULL; 13397 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 13398 static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { 13399 .hdr = { 13400 .next_hdr = 0xff, 13401 .type = 0xff, 13402 .segments_left = 0xff, 13403 }, 13404 }; 13405 13406 switch (item->type) { 13407 case RTE_FLOW_ITEM_TYPE_ANY: 13408 mask = &rte_flow_item_any_mask; 13409 break; 13410 case RTE_FLOW_ITEM_TYPE_PORT_ID: 13411 mask = &rte_flow_item_port_id_mask; 13412 break; 13413 case RTE_FLOW_ITEM_TYPE_RAW: 13414 mask = &rte_flow_item_raw_mask; 13415 break; 13416 case RTE_FLOW_ITEM_TYPE_ETH: 13417 mask = &rte_flow_item_eth_mask; 13418 break; 13419 case RTE_FLOW_ITEM_TYPE_VLAN: 13420 mask = &rte_flow_item_vlan_mask; 13421 break; 13422 case RTE_FLOW_ITEM_TYPE_IPV4: 13423 mask = &rte_flow_item_ipv4_mask; 13424 break; 13425 case RTE_FLOW_ITEM_TYPE_IPV6: 13426 mask = &rte_flow_item_ipv6_mask; 13427 break; 13428 case RTE_FLOW_ITEM_TYPE_ICMP: 13429 mask = &rte_flow_item_icmp_mask; 13430 break; 13431 case RTE_FLOW_ITEM_TYPE_UDP: 13432 mask = &rte_flow_item_udp_mask; 13433 break; 13434 case RTE_FLOW_ITEM_TYPE_TCP: 13435 mask = &rte_flow_item_tcp_mask; 13436 break; 13437 case RTE_FLOW_ITEM_TYPE_SCTP: 13438 mask = &rte_flow_item_sctp_mask; 13439 break; 13440 case RTE_FLOW_ITEM_TYPE_VXLAN: 13441 mask = &rte_flow_item_vxlan_mask; 13442 break; 13443 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13444 mask = &rte_flow_item_vxlan_gpe_mask; 13445 break; 13446 case RTE_FLOW_ITEM_TYPE_E_TAG: 13447 mask = &rte_flow_item_e_tag_mask; 13448 break; 13449 case RTE_FLOW_ITEM_TYPE_NVGRE: 13450 mask = &rte_flow_item_nvgre_mask; 13451 break; 13452 case RTE_FLOW_ITEM_TYPE_MPLS: 13453 mask = &rte_flow_item_mpls_mask; 13454 break; 13455 case RTE_FLOW_ITEM_TYPE_GRE: 13456 mask = &rte_flow_item_gre_mask; 13457 break; 13458 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13459 mask = &gre_key_default_mask; 13460 break; 13461 case RTE_FLOW_ITEM_TYPE_META: 13462 mask = &rte_flow_item_meta_mask; 13463 break; 13464 case RTE_FLOW_ITEM_TYPE_RANDOM: 13465 mask = &rte_flow_item_random_mask; 13466 break; 13467 case RTE_FLOW_ITEM_TYPE_FUZZY: 13468 mask = &rte_flow_item_fuzzy_mask; 13469 break; 13470 case RTE_FLOW_ITEM_TYPE_GTP: 13471 mask = &rte_flow_item_gtp_mask; 13472 break; 13473 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13474 mask = &rte_flow_item_gtp_psc_mask; 13475 break; 13476 case RTE_FLOW_ITEM_TYPE_GENEVE: 13477 mask = &rte_flow_item_geneve_mask; 13478 break; 13479 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13480 mask = &rte_flow_item_geneve_opt_mask; 13481 break; 13482 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 13483 mask = &rte_flow_item_pppoe_proto_id_mask; 13484 break; 13485 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13486 mask = &rte_flow_item_l2tpv3oip_mask; 13487 break; 13488 case RTE_FLOW_ITEM_TYPE_ESP: 13489 mask = &rte_flow_item_esp_mask; 13490 break; 13491 case RTE_FLOW_ITEM_TYPE_AH: 13492 mask = &rte_flow_item_ah_mask; 13493 break; 13494 case RTE_FLOW_ITEM_TYPE_PFCP: 13495 mask = &rte_flow_item_pfcp_mask; 13496 break; 13497 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 13498 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 13499 mask = &rte_flow_item_ethdev_mask; 13500 break; 13501 case RTE_FLOW_ITEM_TYPE_L2TPV2: 13502 mask = &rte_flow_item_l2tpv2_mask; 13503 break; 13504 case RTE_FLOW_ITEM_TYPE_PPP: 13505 mask = &rte_flow_item_ppp_mask; 13506 break; 13507 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 13508 mask = &rte_flow_item_meter_color_mask; 13509 break; 13510 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13511 mask = &ipv6_routing_ext_default_mask; 13512 break; 13513 case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: 13514 mask = &rte_flow_item_aggr_affinity_mask; 13515 break; 13516 case RTE_FLOW_ITEM_TYPE_TX_QUEUE: 13517 mask = &rte_flow_item_tx_queue_mask; 13518 break; 13519 case RTE_FLOW_ITEM_TYPE_IB_BTH: 13520 mask = &rte_flow_item_ib_bth_mask; 13521 break; 13522 case RTE_FLOW_ITEM_TYPE_PTYPE: 13523 mask = &rte_flow_item_ptype_mask; 13524 break; 13525 default: 13526 break; 13527 } 13528 return mask; 13529 } 13530 13531 /** Dispatch parsed buffer to function calls. */ 13532 static void 13533 cmd_set_ipv6_ext_parsed(const struct buffer *in) 13534 { 13535 uint32_t n = in->args.vc.pattern_n; 13536 int i = 0; 13537 struct rte_flow_item *item = NULL; 13538 size_t size = 0; 13539 uint8_t *data = NULL; 13540 uint8_t *type = NULL; 13541 size_t *total_size = NULL; 13542 uint16_t idx = in->port; /* We borrow port field as index */ 13543 struct rte_flow_item_ipv6_routing_ext *ext; 13544 const struct rte_flow_item_ipv6_ext *ipv6_ext; 13545 13546 RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || 13547 in->command == SET_IPV6_EXT_REMOVE); 13548 13549 if (in->command == SET_IPV6_EXT_REMOVE) { 13550 if (n != 1 || in->args.vc.pattern->type != 13551 RTE_FLOW_ITEM_TYPE_IPV6_EXT) { 13552 fprintf(stderr, "Error - Not supported item\n"); 13553 return; 13554 } 13555 type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; 13556 item = in->args.vc.pattern; 13557 ipv6_ext = item->spec; 13558 *type = ipv6_ext->next_hdr; 13559 return; 13560 } 13561 13562 total_size = &ipv6_ext_push_confs[idx].size; 13563 data = (uint8_t *)&ipv6_ext_push_confs[idx].data; 13564 type = (uint8_t *)&ipv6_ext_push_confs[idx].type; 13565 13566 *total_size = 0; 13567 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13568 for (i = n - 1 ; i >= 0; --i) { 13569 item = in->args.vc.pattern + i; 13570 switch (item->type) { 13571 case RTE_FLOW_ITEM_TYPE_IPV6_EXT: 13572 ipv6_ext = item->spec; 13573 *type = ipv6_ext->next_hdr; 13574 break; 13575 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13576 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13577 if (!ext->hdr.hdr_len) { 13578 size = sizeof(struct rte_ipv6_routing_ext) + 13579 (ext->hdr.segments_left << 4); 13580 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13581 /* Indicate no TLV once SRH. */ 13582 if (ext->hdr.type == 4) 13583 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13584 } else { 13585 size = sizeof(struct rte_ipv6_routing_ext) + 13586 (ext->hdr.hdr_len << 3); 13587 } 13588 *total_size += size; 13589 memcpy(data, ext, size); 13590 break; 13591 default: 13592 fprintf(stderr, "Error - Not supported item\n"); 13593 goto error; 13594 } 13595 } 13596 RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); 13597 return; 13598 error: 13599 *total_size = 0; 13600 memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); 13601 } 13602 13603 /** Dispatch parsed buffer to function calls. */ 13604 static void 13605 cmd_set_raw_parsed_sample(const struct buffer *in) 13606 { 13607 uint32_t n = in->args.vc.actions_n; 13608 uint32_t i = 0; 13609 struct rte_flow_action *action = NULL; 13610 struct rte_flow_action *data = NULL; 13611 const struct rte_flow_action_rss *rss = NULL; 13612 size_t size = 0; 13613 uint16_t idx = in->port; /* We borrow port field as index */ 13614 uint32_t max_size = sizeof(struct rte_flow_action) * 13615 ACTION_SAMPLE_ACTIONS_NUM; 13616 13617 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 13618 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 13619 memset(data, 0x00, max_size); 13620 for (; i <= n - 1; i++) { 13621 action = in->args.vc.actions + i; 13622 if (action->type == RTE_FLOW_ACTION_TYPE_END) 13623 break; 13624 switch (action->type) { 13625 case RTE_FLOW_ACTION_TYPE_MARK: 13626 size = sizeof(struct rte_flow_action_mark); 13627 rte_memcpy(&sample_mark[idx], 13628 (const void *)action->conf, size); 13629 action->conf = &sample_mark[idx]; 13630 break; 13631 case RTE_FLOW_ACTION_TYPE_COUNT: 13632 size = sizeof(struct rte_flow_action_count); 13633 rte_memcpy(&sample_count[idx], 13634 (const void *)action->conf, size); 13635 action->conf = &sample_count[idx]; 13636 break; 13637 case RTE_FLOW_ACTION_TYPE_QUEUE: 13638 size = sizeof(struct rte_flow_action_queue); 13639 rte_memcpy(&sample_queue[idx], 13640 (const void *)action->conf, size); 13641 action->conf = &sample_queue[idx]; 13642 break; 13643 case RTE_FLOW_ACTION_TYPE_RSS: 13644 size = sizeof(struct rte_flow_action_rss); 13645 rss = action->conf; 13646 rte_memcpy(&sample_rss_data[idx].conf, 13647 (const void *)rss, size); 13648 if (rss->key_len && rss->key) { 13649 sample_rss_data[idx].conf.key = 13650 sample_rss_data[idx].key; 13651 rte_memcpy((void *)((uintptr_t) 13652 sample_rss_data[idx].conf.key), 13653 (const void *)rss->key, 13654 sizeof(uint8_t) * rss->key_len); 13655 } 13656 if (rss->queue_num && rss->queue) { 13657 sample_rss_data[idx].conf.queue = 13658 sample_rss_data[idx].queue; 13659 rte_memcpy((void *)((uintptr_t) 13660 sample_rss_data[idx].conf.queue), 13661 (const void *)rss->queue, 13662 sizeof(uint16_t) * rss->queue_num); 13663 } 13664 action->conf = &sample_rss_data[idx].conf; 13665 break; 13666 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 13667 size = sizeof(struct rte_flow_action_raw_encap); 13668 rte_memcpy(&sample_encap[idx], 13669 (const void *)action->conf, size); 13670 action->conf = &sample_encap[idx]; 13671 break; 13672 case RTE_FLOW_ACTION_TYPE_PORT_ID: 13673 size = sizeof(struct rte_flow_action_port_id); 13674 rte_memcpy(&sample_port_id[idx], 13675 (const void *)action->conf, size); 13676 action->conf = &sample_port_id[idx]; 13677 break; 13678 case RTE_FLOW_ACTION_TYPE_PF: 13679 break; 13680 case RTE_FLOW_ACTION_TYPE_VF: 13681 size = sizeof(struct rte_flow_action_vf); 13682 rte_memcpy(&sample_vf[idx], 13683 (const void *)action->conf, size); 13684 action->conf = &sample_vf[idx]; 13685 break; 13686 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 13687 size = sizeof(struct rte_flow_action_vxlan_encap); 13688 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 13689 action->conf = &sample_vxlan_encap[idx].conf; 13690 break; 13691 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 13692 size = sizeof(struct rte_flow_action_nvgre_encap); 13693 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 13694 action->conf = &sample_nvgre_encap[idx]; 13695 break; 13696 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 13697 size = sizeof(struct rte_flow_action_ethdev); 13698 rte_memcpy(&sample_port_representor[idx], 13699 (const void *)action->conf, size); 13700 action->conf = &sample_port_representor[idx]; 13701 break; 13702 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 13703 size = sizeof(struct rte_flow_action_ethdev); 13704 rte_memcpy(&sample_represented_port[idx], 13705 (const void *)action->conf, size); 13706 action->conf = &sample_represented_port[idx]; 13707 break; 13708 default: 13709 fprintf(stderr, "Error - Not supported action\n"); 13710 return; 13711 } 13712 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 13713 data++; 13714 } 13715 } 13716 13717 /** Dispatch parsed buffer to function calls. */ 13718 static void 13719 cmd_set_raw_parsed(const struct buffer *in) 13720 { 13721 uint32_t n = in->args.vc.pattern_n; 13722 int i = 0; 13723 struct rte_flow_item *item = NULL; 13724 size_t size = 0; 13725 uint8_t *data = NULL; 13726 uint8_t *data_tail = NULL; 13727 size_t *total_size = NULL; 13728 uint16_t upper_layer = 0; 13729 uint16_t proto = 0; 13730 uint16_t idx = in->port; /* We borrow port field as index */ 13731 int gtp_psc = -1; /* GTP PSC option index. */ 13732 const void *src_spec; 13733 13734 if (in->command == SET_SAMPLE_ACTIONS) 13735 return cmd_set_raw_parsed_sample(in); 13736 else if (in->command == SET_IPV6_EXT_PUSH || 13737 in->command == SET_IPV6_EXT_REMOVE) 13738 return cmd_set_ipv6_ext_parsed(in); 13739 RTE_ASSERT(in->command == SET_RAW_ENCAP || 13740 in->command == SET_RAW_DECAP); 13741 if (in->command == SET_RAW_ENCAP) { 13742 total_size = &raw_encap_confs[idx].size; 13743 data = (uint8_t *)&raw_encap_confs[idx].data; 13744 } else { 13745 total_size = &raw_decap_confs[idx].size; 13746 data = (uint8_t *)&raw_decap_confs[idx].data; 13747 } 13748 *total_size = 0; 13749 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13750 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 13751 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 13752 for (i = n - 1 ; i >= 0; --i) { 13753 const struct rte_flow_item_gtp *gtp; 13754 const struct rte_flow_item_geneve_opt *opt; 13755 struct rte_flow_item_ipv6_routing_ext *ext; 13756 13757 item = in->args.vc.pattern + i; 13758 if (item->spec == NULL) 13759 item->spec = flow_item_default_mask(item); 13760 src_spec = item->spec; 13761 switch (item->type) { 13762 case RTE_FLOW_ITEM_TYPE_ETH: 13763 size = sizeof(struct rte_ether_hdr); 13764 break; 13765 case RTE_FLOW_ITEM_TYPE_VLAN: 13766 size = sizeof(struct rte_vlan_hdr); 13767 proto = RTE_ETHER_TYPE_VLAN; 13768 break; 13769 case RTE_FLOW_ITEM_TYPE_IPV4: 13770 size = sizeof(struct rte_ipv4_hdr); 13771 proto = RTE_ETHER_TYPE_IPV4; 13772 break; 13773 case RTE_FLOW_ITEM_TYPE_IPV6: 13774 size = sizeof(struct rte_ipv6_hdr); 13775 proto = RTE_ETHER_TYPE_IPV6; 13776 break; 13777 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13778 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13779 if (!ext->hdr.hdr_len) { 13780 size = sizeof(struct rte_ipv6_routing_ext) + 13781 (ext->hdr.segments_left << 4); 13782 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13783 /* SRv6 without TLV. */ 13784 if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) 13785 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13786 } else { 13787 size = sizeof(struct rte_ipv6_routing_ext) + 13788 (ext->hdr.hdr_len << 3); 13789 } 13790 proto = IPPROTO_ROUTING; 13791 break; 13792 case RTE_FLOW_ITEM_TYPE_UDP: 13793 size = sizeof(struct rte_udp_hdr); 13794 proto = 0x11; 13795 break; 13796 case RTE_FLOW_ITEM_TYPE_TCP: 13797 size = sizeof(struct rte_tcp_hdr); 13798 proto = 0x06; 13799 break; 13800 case RTE_FLOW_ITEM_TYPE_VXLAN: 13801 size = sizeof(struct rte_vxlan_hdr); 13802 break; 13803 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13804 size = sizeof(struct rte_vxlan_gpe_hdr); 13805 break; 13806 case RTE_FLOW_ITEM_TYPE_GRE: 13807 size = sizeof(struct rte_gre_hdr); 13808 proto = 0x2F; 13809 break; 13810 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13811 size = sizeof(rte_be32_t); 13812 proto = 0x0; 13813 break; 13814 case RTE_FLOW_ITEM_TYPE_MPLS: 13815 size = sizeof(struct rte_mpls_hdr); 13816 proto = 0x0; 13817 break; 13818 case RTE_FLOW_ITEM_TYPE_NVGRE: 13819 size = sizeof(struct rte_flow_item_nvgre); 13820 proto = 0x2F; 13821 break; 13822 case RTE_FLOW_ITEM_TYPE_GENEVE: 13823 size = sizeof(struct rte_geneve_hdr); 13824 break; 13825 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13826 opt = (const struct rte_flow_item_geneve_opt *) 13827 item->spec; 13828 size = offsetof(struct rte_flow_item_geneve_opt, 13829 option_len) + sizeof(uint8_t); 13830 if (opt->option_len && opt->data) { 13831 *total_size += opt->option_len * 13832 sizeof(uint32_t); 13833 rte_memcpy(data_tail - (*total_size), 13834 opt->data, 13835 opt->option_len * sizeof(uint32_t)); 13836 } 13837 break; 13838 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13839 size = sizeof(rte_be32_t); 13840 proto = 0x73; 13841 break; 13842 case RTE_FLOW_ITEM_TYPE_ESP: 13843 size = sizeof(struct rte_esp_hdr); 13844 proto = 0x32; 13845 break; 13846 case RTE_FLOW_ITEM_TYPE_AH: 13847 size = sizeof(struct rte_flow_item_ah); 13848 proto = 0x33; 13849 break; 13850 case RTE_FLOW_ITEM_TYPE_GTP: 13851 if (gtp_psc < 0) { 13852 size = sizeof(struct rte_gtp_hdr); 13853 break; 13854 } 13855 if (gtp_psc != i + 1) { 13856 fprintf(stderr, 13857 "Error - GTP PSC does not follow GTP\n"); 13858 goto error; 13859 } 13860 gtp = item->spec; 13861 if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { 13862 /* Only E flag should be set. */ 13863 fprintf(stderr, 13864 "Error - GTP unsupported flags\n"); 13865 goto error; 13866 } else { 13867 struct rte_gtp_hdr_ext_word ext_word = { 13868 .next_ext = 0x85 13869 }; 13870 13871 /* We have to add GTP header extra word. */ 13872 *total_size += sizeof(ext_word); 13873 rte_memcpy(data_tail - (*total_size), 13874 &ext_word, sizeof(ext_word)); 13875 } 13876 size = sizeof(struct rte_gtp_hdr); 13877 break; 13878 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13879 if (gtp_psc >= 0) { 13880 fprintf(stderr, 13881 "Error - Multiple GTP PSC items\n"); 13882 goto error; 13883 } else { 13884 const struct rte_flow_item_gtp_psc 13885 *opt = item->spec; 13886 struct rte_gtp_psc_generic_hdr *hdr; 13887 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 13888 sizeof(int32_t)); 13889 13890 *total_size += hdr_size; 13891 hdr = (typeof(hdr))(data_tail - (*total_size)); 13892 memset(hdr, 0, hdr_size); 13893 *hdr = opt->hdr; 13894 hdr->ext_hdr_len = 1; 13895 gtp_psc = i; 13896 size = 0; 13897 } 13898 break; 13899 case RTE_FLOW_ITEM_TYPE_PFCP: 13900 size = sizeof(struct rte_flow_item_pfcp); 13901 break; 13902 case RTE_FLOW_ITEM_TYPE_FLEX: 13903 if (item->spec != NULL) { 13904 size = ((const struct rte_flow_item_flex *)item->spec)->length; 13905 src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; 13906 } else { 13907 size = 0; 13908 src_spec = NULL; 13909 } 13910 break; 13911 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 13912 size = 0; 13913 if (item->spec) { 13914 const struct rte_flow_item_gre_opt 13915 *opt = item->spec; 13916 if (opt->checksum_rsvd.checksum) { 13917 *total_size += 13918 sizeof(opt->checksum_rsvd); 13919 rte_memcpy(data_tail - (*total_size), 13920 &opt->checksum_rsvd, 13921 sizeof(opt->checksum_rsvd)); 13922 } 13923 if (opt->key.key) { 13924 *total_size += sizeof(opt->key.key); 13925 rte_memcpy(data_tail - (*total_size), 13926 &opt->key.key, 13927 sizeof(opt->key.key)); 13928 } 13929 if (opt->sequence.sequence) { 13930 *total_size += sizeof(opt->sequence.sequence); 13931 rte_memcpy(data_tail - (*total_size), 13932 &opt->sequence.sequence, 13933 sizeof(opt->sequence.sequence)); 13934 } 13935 } 13936 proto = 0x2F; 13937 break; 13938 default: 13939 fprintf(stderr, "Error - Not supported item\n"); 13940 goto error; 13941 } 13942 if (size) { 13943 *total_size += size; 13944 rte_memcpy(data_tail - (*total_size), src_spec, size); 13945 /* update some fields which cannot be set by cmdline */ 13946 update_fields((data_tail - (*total_size)), item, 13947 upper_layer); 13948 upper_layer = proto; 13949 } 13950 } 13951 if (verbose_level & 0x1) 13952 printf("total data size is %zu\n", (*total_size)); 13953 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 13954 memmove(data, (data_tail - (*total_size)), *total_size); 13955 return; 13956 13957 error: 13958 *total_size = 0; 13959 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13960 } 13961 13962 /** Populate help strings for current token (cmdline API). */ 13963 static int 13964 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 13965 unsigned int size) 13966 { 13967 struct context *ctx = &cmd_flow_context; 13968 const struct token *token = &token_list[ctx->prev]; 13969 13970 (void)hdr; 13971 if (!size) 13972 return -1; 13973 /* Set token type and update global help with details. */ 13974 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 13975 if (token->help) 13976 cmd_set_raw.help_str = token->help; 13977 else 13978 cmd_set_raw.help_str = token->name; 13979 return 0; 13980 } 13981 13982 /** Token definition template (cmdline API). */ 13983 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 13984 .ops = &(struct cmdline_token_ops){ 13985 .parse = cmd_flow_parse, 13986 .complete_get_nb = cmd_flow_complete_get_nb, 13987 .complete_get_elt = cmd_flow_complete_get_elt, 13988 .get_help = cmd_set_raw_get_help, 13989 }, 13990 .offset = 0, 13991 }; 13992 13993 /** Populate the next dynamic token. */ 13994 static void 13995 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 13996 cmdline_parse_token_hdr_t **hdr_inst) 13997 { 13998 struct context *ctx = &cmd_flow_context; 13999 14000 /* Always reinitialize context before requesting the first token. */ 14001 if (!(hdr_inst - cmd_set_raw.tokens)) { 14002 cmd_flow_context_init(ctx); 14003 ctx->curr = START_SET; 14004 } 14005 /* Return NULL when no more tokens are expected. */ 14006 if (!ctx->next_num && (ctx->curr != START_SET)) { 14007 *hdr = NULL; 14008 return; 14009 } 14010 /* Determine if command should end here. */ 14011 if (ctx->eol && ctx->last && ctx->next_num) { 14012 const enum index *list = ctx->next[ctx->next_num - 1]; 14013 int i; 14014 14015 for (i = 0; list[i]; ++i) { 14016 if (list[i] != END) 14017 continue; 14018 *hdr = NULL; 14019 return; 14020 } 14021 } 14022 *hdr = &cmd_set_raw_token_hdr; 14023 } 14024 14025 /** Token generator and output processing callback (cmdline API). */ 14026 static void 14027 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 14028 { 14029 if (cl == NULL) 14030 cmd_set_raw_tok(arg0, arg2); 14031 else 14032 cmd_set_raw_parsed(arg0); 14033 } 14034 14035 /** Global parser instance (cmdline API). */ 14036 cmdline_parse_inst_t cmd_set_raw = { 14037 .f = cmd_set_raw_cb, 14038 .data = NULL, /**< Unused. */ 14039 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 14040 .tokens = { 14041 NULL, 14042 }, /**< Tokens are returned by cmd_flow_tok(). */ 14043 }; 14044 14045 /* *** display raw_encap/raw_decap buf */ 14046 struct cmd_show_set_raw_result { 14047 cmdline_fixed_string_t cmd_show; 14048 cmdline_fixed_string_t cmd_what; 14049 cmdline_fixed_string_t cmd_all; 14050 uint16_t cmd_index; 14051 }; 14052 14053 static void 14054 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 14055 { 14056 struct cmd_show_set_raw_result *res = parsed_result; 14057 uint16_t index = res->cmd_index; 14058 uint8_t all = 0; 14059 uint8_t *raw_data = NULL; 14060 size_t raw_size = 0; 14061 char title[16] = {0}; 14062 14063 RTE_SET_USED(cl); 14064 RTE_SET_USED(data); 14065 if (!strcmp(res->cmd_all, "all")) { 14066 all = 1; 14067 index = 0; 14068 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 14069 fprintf(stderr, "index should be 0-%u\n", 14070 RAW_ENCAP_CONFS_MAX_NUM - 1); 14071 return; 14072 } 14073 do { 14074 if (!strcmp(res->cmd_what, "raw_encap")) { 14075 raw_data = (uint8_t *)&raw_encap_confs[index].data; 14076 raw_size = raw_encap_confs[index].size; 14077 snprintf(title, 16, "\nindex: %u", index); 14078 rte_hexdump(stdout, title, raw_data, raw_size); 14079 } else { 14080 raw_data = (uint8_t *)&raw_decap_confs[index].data; 14081 raw_size = raw_decap_confs[index].size; 14082 snprintf(title, 16, "\nindex: %u", index); 14083 rte_hexdump(stdout, title, raw_data, raw_size); 14084 } 14085 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 14086 } 14087 14088 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 14089 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14090 cmd_show, "show"); 14091 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 14092 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14093 cmd_what, "raw_encap#raw_decap"); 14094 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 14095 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 14096 cmd_index, RTE_UINT16); 14097 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 14098 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14099 cmd_all, "all"); 14100 cmdline_parse_inst_t cmd_show_set_raw = { 14101 .f = cmd_show_set_raw_parsed, 14102 .data = NULL, 14103 .help_str = "show <raw_encap|raw_decap> <index>", 14104 .tokens = { 14105 (void *)&cmd_show_set_raw_cmd_show, 14106 (void *)&cmd_show_set_raw_cmd_what, 14107 (void *)&cmd_show_set_raw_cmd_index, 14108 NULL, 14109 }, 14110 }; 14111 cmdline_parse_inst_t cmd_show_set_raw_all = { 14112 .f = cmd_show_set_raw_parsed, 14113 .data = NULL, 14114 .help_str = "show <raw_encap|raw_decap> all", 14115 .tokens = { 14116 (void *)&cmd_show_set_raw_cmd_show, 14117 (void *)&cmd_show_set_raw_cmd_what, 14118 (void *)&cmd_show_set_raw_cmd_all, 14119 NULL, 14120 }, 14121 }; 14122