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_UPDATE, 138 QUEUE_AGED, 139 QUEUE_INDIRECT_ACTION, 140 141 /* Queue create arguments. */ 142 QUEUE_CREATE_POSTPONE, 143 QUEUE_TEMPLATE_TABLE, 144 QUEUE_PATTERN_TEMPLATE, 145 QUEUE_ACTIONS_TEMPLATE, 146 QUEUE_RULE_ID, 147 148 /* Queue destroy arguments. */ 149 QUEUE_DESTROY_ID, 150 QUEUE_DESTROY_POSTPONE, 151 152 /* Queue update arguments. */ 153 QUEUE_UPDATE_ID, 154 155 /* Queue indirect action arguments */ 156 QUEUE_INDIRECT_ACTION_CREATE, 157 QUEUE_INDIRECT_ACTION_LIST_CREATE, 158 QUEUE_INDIRECT_ACTION_UPDATE, 159 QUEUE_INDIRECT_ACTION_DESTROY, 160 QUEUE_INDIRECT_ACTION_QUERY, 161 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 162 163 /* Queue indirect action create arguments */ 164 QUEUE_INDIRECT_ACTION_CREATE_ID, 165 QUEUE_INDIRECT_ACTION_INGRESS, 166 QUEUE_INDIRECT_ACTION_EGRESS, 167 QUEUE_INDIRECT_ACTION_TRANSFER, 168 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 169 QUEUE_INDIRECT_ACTION_SPEC, 170 QUEUE_INDIRECT_ACTION_LIST, 171 172 /* Queue indirect action update arguments */ 173 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 174 175 /* Queue indirect action destroy arguments */ 176 QUEUE_INDIRECT_ACTION_DESTROY_ID, 177 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 178 179 /* Queue indirect action query arguments */ 180 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 181 182 /* Queue indirect action query_update arguments */ 183 QUEUE_INDIRECT_ACTION_QU_MODE, 184 185 /* Push arguments. */ 186 PUSH_QUEUE, 187 188 /* Pull arguments. */ 189 PULL_QUEUE, 190 191 /* Table arguments. */ 192 TABLE_CREATE, 193 TABLE_DESTROY, 194 TABLE_CREATE_ID, 195 TABLE_DESTROY_ID, 196 TABLE_INSERTION_TYPE, 197 TABLE_INSERTION_TYPE_NAME, 198 TABLE_HASH_FUNC, 199 TABLE_HASH_FUNC_NAME, 200 TABLE_GROUP, 201 TABLE_PRIORITY, 202 TABLE_INGRESS, 203 TABLE_EGRESS, 204 TABLE_TRANSFER, 205 TABLE_TRANSFER_WIRE_ORIG, 206 TABLE_TRANSFER_VPORT_ORIG, 207 TABLE_RULES_NUMBER, 208 TABLE_PATTERN_TEMPLATE, 209 TABLE_ACTIONS_TEMPLATE, 210 211 /* Group arguments */ 212 GROUP_ID, 213 GROUP_INGRESS, 214 GROUP_EGRESS, 215 GROUP_TRANSFER, 216 GROUP_SET_MISS_ACTIONS, 217 218 /* Hash calculation arguments. */ 219 HASH_CALC_TABLE, 220 HASH_CALC_PATTERN_INDEX, 221 HASH_CALC_PATTERN, 222 223 /* Tunnel arguments. */ 224 TUNNEL_CREATE, 225 TUNNEL_CREATE_TYPE, 226 TUNNEL_LIST, 227 TUNNEL_DESTROY, 228 TUNNEL_DESTROY_ID, 229 230 /* Destroy arguments. */ 231 DESTROY_RULE, 232 DESTROY_IS_USER_ID, 233 234 /* Query arguments. */ 235 QUERY_ACTION, 236 QUERY_IS_USER_ID, 237 238 /* List arguments. */ 239 LIST_GROUP, 240 241 /* Destroy aged flow arguments. */ 242 AGED_DESTROY, 243 244 /* Validate/create arguments. */ 245 VC_GROUP, 246 VC_PRIORITY, 247 VC_INGRESS, 248 VC_EGRESS, 249 VC_TRANSFER, 250 VC_TUNNEL_SET, 251 VC_TUNNEL_MATCH, 252 VC_USER_ID, 253 254 /* Dump arguments */ 255 DUMP_ALL, 256 DUMP_ONE, 257 DUMP_IS_USER_ID, 258 259 /* Configure arguments */ 260 CONFIG_QUEUES_NUMBER, 261 CONFIG_QUEUES_SIZE, 262 CONFIG_COUNTERS_NUMBER, 263 CONFIG_AGING_OBJECTS_NUMBER, 264 CONFIG_METERS_NUMBER, 265 CONFIG_CONN_TRACK_NUMBER, 266 CONFIG_QUOTAS_NUMBER, 267 CONFIG_FLAGS, 268 CONFIG_HOST_PORT, 269 270 /* Indirect action arguments */ 271 INDIRECT_ACTION_CREATE, 272 INDIRECT_ACTION_LIST_CREATE, 273 INDIRECT_ACTION_FLOW_CONF_CREATE, 274 INDIRECT_ACTION_UPDATE, 275 INDIRECT_ACTION_DESTROY, 276 INDIRECT_ACTION_QUERY, 277 INDIRECT_ACTION_QUERY_UPDATE, 278 279 /* Indirect action create arguments */ 280 INDIRECT_ACTION_CREATE_ID, 281 INDIRECT_ACTION_INGRESS, 282 INDIRECT_ACTION_EGRESS, 283 INDIRECT_ACTION_TRANSFER, 284 INDIRECT_ACTION_SPEC, 285 INDIRECT_ACTION_LIST, 286 INDIRECT_ACTION_FLOW_CONF, 287 288 /* Indirect action destroy arguments */ 289 INDIRECT_ACTION_DESTROY_ID, 290 291 /* Indirect action query-and-update arguments */ 292 INDIRECT_ACTION_QU_MODE, 293 INDIRECT_ACTION_QU_MODE_NAME, 294 295 /* Validate/create pattern. */ 296 ITEM_PATTERN, 297 ITEM_PARAM_IS, 298 ITEM_PARAM_SPEC, 299 ITEM_PARAM_LAST, 300 ITEM_PARAM_MASK, 301 ITEM_PARAM_PREFIX, 302 ITEM_NEXT, 303 ITEM_END, 304 ITEM_VOID, 305 ITEM_INVERT, 306 ITEM_ANY, 307 ITEM_ANY_NUM, 308 ITEM_PORT_ID, 309 ITEM_PORT_ID_ID, 310 ITEM_MARK, 311 ITEM_MARK_ID, 312 ITEM_RAW, 313 ITEM_RAW_RELATIVE, 314 ITEM_RAW_SEARCH, 315 ITEM_RAW_OFFSET, 316 ITEM_RAW_LIMIT, 317 ITEM_RAW_PATTERN, 318 ITEM_RAW_PATTERN_HEX, 319 ITEM_ETH, 320 ITEM_ETH_DST, 321 ITEM_ETH_SRC, 322 ITEM_ETH_TYPE, 323 ITEM_ETH_HAS_VLAN, 324 ITEM_VLAN, 325 ITEM_VLAN_TCI, 326 ITEM_VLAN_PCP, 327 ITEM_VLAN_DEI, 328 ITEM_VLAN_VID, 329 ITEM_VLAN_INNER_TYPE, 330 ITEM_VLAN_HAS_MORE_VLAN, 331 ITEM_IPV4, 332 ITEM_IPV4_VER_IHL, 333 ITEM_IPV4_TOS, 334 ITEM_IPV4_LENGTH, 335 ITEM_IPV4_ID, 336 ITEM_IPV4_FRAGMENT_OFFSET, 337 ITEM_IPV4_TTL, 338 ITEM_IPV4_PROTO, 339 ITEM_IPV4_SRC, 340 ITEM_IPV4_DST, 341 ITEM_IPV6, 342 ITEM_IPV6_TC, 343 ITEM_IPV6_FLOW, 344 ITEM_IPV6_LEN, 345 ITEM_IPV6_PROTO, 346 ITEM_IPV6_HOP, 347 ITEM_IPV6_SRC, 348 ITEM_IPV6_DST, 349 ITEM_IPV6_HAS_FRAG_EXT, 350 ITEM_IPV6_ROUTING_EXT, 351 ITEM_IPV6_ROUTING_EXT_TYPE, 352 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 353 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 354 ITEM_ICMP, 355 ITEM_ICMP_TYPE, 356 ITEM_ICMP_CODE, 357 ITEM_ICMP_IDENT, 358 ITEM_ICMP_SEQ, 359 ITEM_UDP, 360 ITEM_UDP_SRC, 361 ITEM_UDP_DST, 362 ITEM_TCP, 363 ITEM_TCP_SRC, 364 ITEM_TCP_DST, 365 ITEM_TCP_FLAGS, 366 ITEM_SCTP, 367 ITEM_SCTP_SRC, 368 ITEM_SCTP_DST, 369 ITEM_SCTP_TAG, 370 ITEM_SCTP_CKSUM, 371 ITEM_VXLAN, 372 ITEM_VXLAN_VNI, 373 ITEM_VXLAN_LAST_RSVD, 374 ITEM_E_TAG, 375 ITEM_E_TAG_GRP_ECID_B, 376 ITEM_NVGRE, 377 ITEM_NVGRE_TNI, 378 ITEM_MPLS, 379 ITEM_MPLS_LABEL, 380 ITEM_MPLS_TC, 381 ITEM_MPLS_S, 382 ITEM_MPLS_TTL, 383 ITEM_GRE, 384 ITEM_GRE_PROTO, 385 ITEM_GRE_C_RSVD0_VER, 386 ITEM_GRE_C_BIT, 387 ITEM_GRE_K_BIT, 388 ITEM_GRE_S_BIT, 389 ITEM_FUZZY, 390 ITEM_FUZZY_THRESH, 391 ITEM_GTP, 392 ITEM_GTP_FLAGS, 393 ITEM_GTP_MSG_TYPE, 394 ITEM_GTP_TEID, 395 ITEM_GTPC, 396 ITEM_GTPU, 397 ITEM_GENEVE, 398 ITEM_GENEVE_VNI, 399 ITEM_GENEVE_PROTO, 400 ITEM_GENEVE_OPTLEN, 401 ITEM_VXLAN_GPE, 402 ITEM_VXLAN_GPE_VNI, 403 ITEM_VXLAN_GPE_PROTO, 404 ITEM_ARP_ETH_IPV4, 405 ITEM_ARP_ETH_IPV4_SHA, 406 ITEM_ARP_ETH_IPV4_SPA, 407 ITEM_ARP_ETH_IPV4_THA, 408 ITEM_ARP_ETH_IPV4_TPA, 409 ITEM_IPV6_EXT, 410 ITEM_IPV6_EXT_NEXT_HDR, 411 ITEM_IPV6_FRAG_EXT, 412 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 413 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 414 ITEM_IPV6_FRAG_EXT_ID, 415 ITEM_ICMP6, 416 ITEM_ICMP6_TYPE, 417 ITEM_ICMP6_CODE, 418 ITEM_ICMP6_ECHO_REQUEST, 419 ITEM_ICMP6_ECHO_REQUEST_ID, 420 ITEM_ICMP6_ECHO_REQUEST_SEQ, 421 ITEM_ICMP6_ECHO_REPLY, 422 ITEM_ICMP6_ECHO_REPLY_ID, 423 ITEM_ICMP6_ECHO_REPLY_SEQ, 424 ITEM_ICMP6_ND_NS, 425 ITEM_ICMP6_ND_NS_TARGET_ADDR, 426 ITEM_ICMP6_ND_NA, 427 ITEM_ICMP6_ND_NA_TARGET_ADDR, 428 ITEM_ICMP6_ND_OPT, 429 ITEM_ICMP6_ND_OPT_TYPE, 430 ITEM_ICMP6_ND_OPT_SLA_ETH, 431 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 432 ITEM_ICMP6_ND_OPT_TLA_ETH, 433 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 434 ITEM_META, 435 ITEM_META_DATA, 436 ITEM_RANDOM, 437 ITEM_RANDOM_VALUE, 438 ITEM_GRE_KEY, 439 ITEM_GRE_KEY_VALUE, 440 ITEM_GRE_OPTION, 441 ITEM_GRE_OPTION_CHECKSUM, 442 ITEM_GRE_OPTION_KEY, 443 ITEM_GRE_OPTION_SEQUENCE, 444 ITEM_GTP_PSC, 445 ITEM_GTP_PSC_QFI, 446 ITEM_GTP_PSC_PDU_T, 447 ITEM_PPPOES, 448 ITEM_PPPOED, 449 ITEM_PPPOE_SEID, 450 ITEM_PPPOE_PROTO_ID, 451 ITEM_HIGIG2, 452 ITEM_HIGIG2_CLASSIFICATION, 453 ITEM_HIGIG2_VID, 454 ITEM_TAG, 455 ITEM_TAG_DATA, 456 ITEM_TAG_INDEX, 457 ITEM_L2TPV3OIP, 458 ITEM_L2TPV3OIP_SESSION_ID, 459 ITEM_ESP, 460 ITEM_ESP_SPI, 461 ITEM_AH, 462 ITEM_AH_SPI, 463 ITEM_PFCP, 464 ITEM_PFCP_S_FIELD, 465 ITEM_PFCP_SEID, 466 ITEM_ECPRI, 467 ITEM_ECPRI_COMMON, 468 ITEM_ECPRI_COMMON_TYPE, 469 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 470 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 471 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 472 ITEM_ECPRI_MSG_IQ_DATA_PCID, 473 ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 474 ITEM_ECPRI_MSG_DLY_MSR_MSRID, 475 ITEM_GENEVE_OPT, 476 ITEM_GENEVE_OPT_CLASS, 477 ITEM_GENEVE_OPT_TYPE, 478 ITEM_GENEVE_OPT_LENGTH, 479 ITEM_GENEVE_OPT_DATA, 480 ITEM_INTEGRITY, 481 ITEM_INTEGRITY_LEVEL, 482 ITEM_INTEGRITY_VALUE, 483 ITEM_CONNTRACK, 484 ITEM_POL_PORT, 485 ITEM_POL_METER, 486 ITEM_POL_POLICY, 487 ITEM_PORT_REPRESENTOR, 488 ITEM_PORT_REPRESENTOR_PORT_ID, 489 ITEM_REPRESENTED_PORT, 490 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 491 ITEM_FLEX, 492 ITEM_FLEX_ITEM_HANDLE, 493 ITEM_FLEX_PATTERN_HANDLE, 494 ITEM_L2TPV2, 495 ITEM_L2TPV2_TYPE, 496 ITEM_L2TPV2_TYPE_DATA, 497 ITEM_L2TPV2_TYPE_DATA_L, 498 ITEM_L2TPV2_TYPE_DATA_S, 499 ITEM_L2TPV2_TYPE_DATA_O, 500 ITEM_L2TPV2_TYPE_DATA_L_S, 501 ITEM_L2TPV2_TYPE_CTRL, 502 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 503 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 504 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 505 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 506 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 507 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 508 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 509 ITEM_L2TPV2_MSG_DATA_S_NS, 510 ITEM_L2TPV2_MSG_DATA_S_NR, 511 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 512 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 513 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 514 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 515 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 516 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 517 ITEM_L2TPV2_MSG_DATA_L_S_NS, 518 ITEM_L2TPV2_MSG_DATA_L_S_NR, 519 ITEM_L2TPV2_MSG_CTRL_LENGTH, 520 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 521 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 522 ITEM_L2TPV2_MSG_CTRL_NS, 523 ITEM_L2TPV2_MSG_CTRL_NR, 524 ITEM_PPP, 525 ITEM_PPP_ADDR, 526 ITEM_PPP_CTRL, 527 ITEM_PPP_PROTO_ID, 528 ITEM_METER, 529 ITEM_METER_COLOR, 530 ITEM_METER_COLOR_NAME, 531 ITEM_QUOTA, 532 ITEM_QUOTA_STATE, 533 ITEM_QUOTA_STATE_NAME, 534 ITEM_AGGR_AFFINITY, 535 ITEM_AGGR_AFFINITY_VALUE, 536 ITEM_TX_QUEUE, 537 ITEM_TX_QUEUE_VALUE, 538 ITEM_IB_BTH, 539 ITEM_IB_BTH_OPCODE, 540 ITEM_IB_BTH_PKEY, 541 ITEM_IB_BTH_DST_QPN, 542 ITEM_IB_BTH_PSN, 543 ITEM_IPV6_PUSH_REMOVE_EXT, 544 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 545 ITEM_PTYPE, 546 ITEM_PTYPE_VALUE, 547 ITEM_NSH, 548 549 /* Validate/create actions. */ 550 ACTIONS, 551 ACTION_NEXT, 552 ACTION_END, 553 ACTION_VOID, 554 ACTION_PASSTHRU, 555 ACTION_SKIP_CMAN, 556 ACTION_JUMP, 557 ACTION_JUMP_GROUP, 558 ACTION_MARK, 559 ACTION_MARK_ID, 560 ACTION_FLAG, 561 ACTION_QUEUE, 562 ACTION_QUEUE_INDEX, 563 ACTION_DROP, 564 ACTION_COUNT, 565 ACTION_COUNT_ID, 566 ACTION_RSS, 567 ACTION_RSS_FUNC, 568 ACTION_RSS_LEVEL, 569 ACTION_RSS_FUNC_DEFAULT, 570 ACTION_RSS_FUNC_TOEPLITZ, 571 ACTION_RSS_FUNC_SIMPLE_XOR, 572 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, 573 ACTION_RSS_TYPES, 574 ACTION_RSS_TYPE, 575 ACTION_RSS_KEY, 576 ACTION_RSS_KEY_LEN, 577 ACTION_RSS_QUEUES, 578 ACTION_RSS_QUEUE, 579 ACTION_PF, 580 ACTION_VF, 581 ACTION_VF_ORIGINAL, 582 ACTION_VF_ID, 583 ACTION_PORT_ID, 584 ACTION_PORT_ID_ORIGINAL, 585 ACTION_PORT_ID_ID, 586 ACTION_METER, 587 ACTION_METER_COLOR, 588 ACTION_METER_COLOR_TYPE, 589 ACTION_METER_COLOR_GREEN, 590 ACTION_METER_COLOR_YELLOW, 591 ACTION_METER_COLOR_RED, 592 ACTION_METER_ID, 593 ACTION_METER_MARK, 594 ACTION_METER_PROFILE, 595 ACTION_METER_PROFILE_ID2PTR, 596 ACTION_METER_POLICY, 597 ACTION_METER_POLICY_ID2PTR, 598 ACTION_METER_COLOR_MODE, 599 ACTION_METER_STATE, 600 ACTION_OF_DEC_NW_TTL, 601 ACTION_OF_POP_VLAN, 602 ACTION_OF_PUSH_VLAN, 603 ACTION_OF_PUSH_VLAN_ETHERTYPE, 604 ACTION_OF_SET_VLAN_VID, 605 ACTION_OF_SET_VLAN_VID_VLAN_VID, 606 ACTION_OF_SET_VLAN_PCP, 607 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 608 ACTION_OF_POP_MPLS, 609 ACTION_OF_POP_MPLS_ETHERTYPE, 610 ACTION_OF_PUSH_MPLS, 611 ACTION_OF_PUSH_MPLS_ETHERTYPE, 612 ACTION_VXLAN_ENCAP, 613 ACTION_VXLAN_DECAP, 614 ACTION_NVGRE_ENCAP, 615 ACTION_NVGRE_DECAP, 616 ACTION_L2_ENCAP, 617 ACTION_L2_DECAP, 618 ACTION_MPLSOGRE_ENCAP, 619 ACTION_MPLSOGRE_DECAP, 620 ACTION_MPLSOUDP_ENCAP, 621 ACTION_MPLSOUDP_DECAP, 622 ACTION_SET_IPV4_SRC, 623 ACTION_SET_IPV4_SRC_IPV4_SRC, 624 ACTION_SET_IPV4_DST, 625 ACTION_SET_IPV4_DST_IPV4_DST, 626 ACTION_SET_IPV6_SRC, 627 ACTION_SET_IPV6_SRC_IPV6_SRC, 628 ACTION_SET_IPV6_DST, 629 ACTION_SET_IPV6_DST_IPV6_DST, 630 ACTION_SET_TP_SRC, 631 ACTION_SET_TP_SRC_TP_SRC, 632 ACTION_SET_TP_DST, 633 ACTION_SET_TP_DST_TP_DST, 634 ACTION_MAC_SWAP, 635 ACTION_DEC_TTL, 636 ACTION_SET_TTL, 637 ACTION_SET_TTL_TTL, 638 ACTION_SET_MAC_SRC, 639 ACTION_SET_MAC_SRC_MAC_SRC, 640 ACTION_SET_MAC_DST, 641 ACTION_SET_MAC_DST_MAC_DST, 642 ACTION_INC_TCP_SEQ, 643 ACTION_INC_TCP_SEQ_VALUE, 644 ACTION_DEC_TCP_SEQ, 645 ACTION_DEC_TCP_SEQ_VALUE, 646 ACTION_INC_TCP_ACK, 647 ACTION_INC_TCP_ACK_VALUE, 648 ACTION_DEC_TCP_ACK, 649 ACTION_DEC_TCP_ACK_VALUE, 650 ACTION_RAW_ENCAP, 651 ACTION_RAW_DECAP, 652 ACTION_RAW_ENCAP_INDEX, 653 ACTION_RAW_ENCAP_INDEX_VALUE, 654 ACTION_RAW_DECAP_INDEX, 655 ACTION_RAW_DECAP_INDEX_VALUE, 656 ACTION_SET_TAG, 657 ACTION_SET_TAG_DATA, 658 ACTION_SET_TAG_INDEX, 659 ACTION_SET_TAG_MASK, 660 ACTION_SET_META, 661 ACTION_SET_META_DATA, 662 ACTION_SET_META_MASK, 663 ACTION_SET_IPV4_DSCP, 664 ACTION_SET_IPV4_DSCP_VALUE, 665 ACTION_SET_IPV6_DSCP, 666 ACTION_SET_IPV6_DSCP_VALUE, 667 ACTION_AGE, 668 ACTION_AGE_TIMEOUT, 669 ACTION_AGE_UPDATE, 670 ACTION_AGE_UPDATE_TIMEOUT, 671 ACTION_AGE_UPDATE_TOUCH, 672 ACTION_SAMPLE, 673 ACTION_SAMPLE_RATIO, 674 ACTION_SAMPLE_INDEX, 675 ACTION_SAMPLE_INDEX_VALUE, 676 ACTION_INDIRECT, 677 ACTION_INDIRECT_LIST, 678 ACTION_INDIRECT_LIST_HANDLE, 679 ACTION_INDIRECT_LIST_CONF, 680 INDIRECT_LIST_ACTION_ID2PTR_HANDLE, 681 INDIRECT_LIST_ACTION_ID2PTR_CONF, 682 ACTION_SHARED_INDIRECT, 683 INDIRECT_ACTION_PORT, 684 INDIRECT_ACTION_ID2PTR, 685 ACTION_MODIFY_FIELD, 686 ACTION_MODIFY_FIELD_OP, 687 ACTION_MODIFY_FIELD_OP_VALUE, 688 ACTION_MODIFY_FIELD_DST_TYPE, 689 ACTION_MODIFY_FIELD_DST_TYPE_VALUE, 690 ACTION_MODIFY_FIELD_DST_LEVEL, 691 ACTION_MODIFY_FIELD_DST_LEVEL_VALUE, 692 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 693 ACTION_MODIFY_FIELD_DST_TYPE_ID, 694 ACTION_MODIFY_FIELD_DST_CLASS_ID, 695 ACTION_MODIFY_FIELD_DST_OFFSET, 696 ACTION_MODIFY_FIELD_SRC_TYPE, 697 ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, 698 ACTION_MODIFY_FIELD_SRC_LEVEL, 699 ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE, 700 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 701 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 702 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 703 ACTION_MODIFY_FIELD_SRC_OFFSET, 704 ACTION_MODIFY_FIELD_SRC_VALUE, 705 ACTION_MODIFY_FIELD_SRC_POINTER, 706 ACTION_MODIFY_FIELD_WIDTH, 707 ACTION_CONNTRACK, 708 ACTION_CONNTRACK_UPDATE, 709 ACTION_CONNTRACK_UPDATE_DIR, 710 ACTION_CONNTRACK_UPDATE_CTX, 711 ACTION_POL_G, 712 ACTION_POL_Y, 713 ACTION_POL_R, 714 ACTION_PORT_REPRESENTOR, 715 ACTION_PORT_REPRESENTOR_PORT_ID, 716 ACTION_REPRESENTED_PORT, 717 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 718 ACTION_SEND_TO_KERNEL, 719 ACTION_QUOTA_CREATE, 720 ACTION_QUOTA_CREATE_LIMIT, 721 ACTION_QUOTA_CREATE_MODE, 722 ACTION_QUOTA_CREATE_MODE_NAME, 723 ACTION_QUOTA_QU, 724 ACTION_QUOTA_QU_LIMIT, 725 ACTION_QUOTA_QU_UPDATE_OP, 726 ACTION_QUOTA_QU_UPDATE_OP_NAME, 727 ACTION_IPV6_EXT_REMOVE, 728 ACTION_IPV6_EXT_REMOVE_INDEX, 729 ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, 730 ACTION_IPV6_EXT_PUSH, 731 ACTION_IPV6_EXT_PUSH_INDEX, 732 ACTION_IPV6_EXT_PUSH_INDEX_VALUE, 733 ACTION_NAT64, 734 ACTION_NAT64_MODE, 735 }; 736 737 /** Maximum size for pattern in struct rte_flow_item_raw. */ 738 #define ITEM_RAW_PATTERN_SIZE 512 739 740 /** Maximum size for GENEVE option data pattern in bytes. */ 741 #define ITEM_GENEVE_OPT_DATA_SIZE 124 742 743 /** Storage size for struct rte_flow_item_raw including pattern. */ 744 #define ITEM_RAW_SIZE \ 745 (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) 746 747 /** Maximum size for external pattern in struct rte_flow_action_modify_data. */ 748 #define ACTION_MODIFY_PATTERN_SIZE 32 749 750 /** Storage size for struct rte_flow_action_modify_field including pattern. */ 751 #define ACTION_MODIFY_SIZE \ 752 (sizeof(struct rte_flow_action_modify_field) + \ 753 ACTION_MODIFY_PATTERN_SIZE) 754 755 /** Maximum number of queue indices in struct rte_flow_action_rss. */ 756 #define ACTION_RSS_QUEUE_NUM 128 757 758 /** Storage for struct rte_flow_action_rss including external data. */ 759 struct action_rss_data { 760 struct rte_flow_action_rss conf; 761 uint8_t key[RSS_HASH_KEY_LENGTH]; 762 uint16_t queue[ACTION_RSS_QUEUE_NUM]; 763 }; 764 765 /** Maximum data size in struct rte_flow_action_raw_encap. */ 766 #define ACTION_RAW_ENCAP_MAX_DATA 512 767 #define RAW_ENCAP_CONFS_MAX_NUM 8 768 769 /** Storage for struct rte_flow_action_raw_encap. */ 770 struct raw_encap_conf { 771 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 772 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 773 size_t size; 774 }; 775 776 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 777 778 /** Storage for struct rte_flow_action_raw_encap including external data. */ 779 struct action_raw_encap_data { 780 struct rte_flow_action_raw_encap conf; 781 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 782 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 783 uint16_t idx; 784 }; 785 786 /** Storage for struct rte_flow_action_raw_decap. */ 787 struct raw_decap_conf { 788 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 789 size_t size; 790 }; 791 792 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 793 794 /** Storage for struct rte_flow_action_raw_decap including external data. */ 795 struct action_raw_decap_data { 796 struct rte_flow_action_raw_decap conf; 797 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 798 uint16_t idx; 799 }; 800 801 /** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ 802 #define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 803 #define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 804 805 /** Storage for struct rte_flow_action_ipv6_ext_push. */ 806 struct ipv6_ext_push_conf { 807 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 808 size_t size; 809 uint8_t type; 810 }; 811 812 struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 813 814 /** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ 815 struct action_ipv6_ext_push_data { 816 struct rte_flow_action_ipv6_ext_push conf; 817 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 818 uint8_t type; 819 uint16_t idx; 820 }; 821 822 /** Storage for struct rte_flow_action_ipv6_ext_remove. */ 823 struct ipv6_ext_remove_conf { 824 struct rte_flow_action_ipv6_ext_remove conf; 825 uint8_t type; 826 }; 827 828 struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 829 830 /** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ 831 struct action_ipv6_ext_remove_data { 832 struct rte_flow_action_ipv6_ext_remove conf; 833 uint8_t type; 834 uint16_t idx; 835 }; 836 837 struct vxlan_encap_conf vxlan_encap_conf = { 838 .select_ipv4 = 1, 839 .select_vlan = 0, 840 .select_tos_ttl = 0, 841 .vni = "\x00\x00\x00", 842 .udp_src = 0, 843 .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), 844 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 845 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 846 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 847 "\x00\x00\x00\x00\x00\x00\x00\x01", 848 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 849 "\x00\x00\x00\x00\x00\x00\x11\x11", 850 .vlan_tci = 0, 851 .ip_tos = 0, 852 .ip_ttl = 255, 853 .eth_src = "\x00\x00\x00\x00\x00\x00", 854 .eth_dst = "\xff\xff\xff\xff\xff\xff", 855 }; 856 857 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */ 858 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6 859 860 /** Storage for struct rte_flow_action_vxlan_encap including external data. */ 861 struct action_vxlan_encap_data { 862 struct rte_flow_action_vxlan_encap conf; 863 struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; 864 struct rte_flow_item_eth item_eth; 865 struct rte_flow_item_vlan item_vlan; 866 union { 867 struct rte_flow_item_ipv4 item_ipv4; 868 struct rte_flow_item_ipv6 item_ipv6; 869 }; 870 struct rte_flow_item_udp item_udp; 871 struct rte_flow_item_vxlan item_vxlan; 872 }; 873 874 struct nvgre_encap_conf nvgre_encap_conf = { 875 .select_ipv4 = 1, 876 .select_vlan = 0, 877 .tni = "\x00\x00\x00", 878 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 879 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 880 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 881 "\x00\x00\x00\x00\x00\x00\x00\x01", 882 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 883 "\x00\x00\x00\x00\x00\x00\x11\x11", 884 .vlan_tci = 0, 885 .eth_src = "\x00\x00\x00\x00\x00\x00", 886 .eth_dst = "\xff\xff\xff\xff\xff\xff", 887 }; 888 889 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */ 890 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 891 892 /** Storage for struct rte_flow_action_nvgre_encap including external data. */ 893 struct action_nvgre_encap_data { 894 struct rte_flow_action_nvgre_encap conf; 895 struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; 896 struct rte_flow_item_eth item_eth; 897 struct rte_flow_item_vlan item_vlan; 898 union { 899 struct rte_flow_item_ipv4 item_ipv4; 900 struct rte_flow_item_ipv6 item_ipv6; 901 }; 902 struct rte_flow_item_nvgre item_nvgre; 903 }; 904 905 struct l2_encap_conf l2_encap_conf; 906 907 struct l2_decap_conf l2_decap_conf; 908 909 struct mplsogre_encap_conf mplsogre_encap_conf; 910 911 struct mplsogre_decap_conf mplsogre_decap_conf; 912 913 struct mplsoudp_encap_conf mplsoudp_encap_conf; 914 915 struct mplsoudp_decap_conf mplsoudp_decap_conf; 916 917 struct rte_flow_action_conntrack conntrack_context; 918 919 #define ACTION_SAMPLE_ACTIONS_NUM 10 920 #define RAW_SAMPLE_CONFS_MAX_NUM 8 921 /** Storage for struct rte_flow_action_sample including external data. */ 922 struct action_sample_data { 923 struct rte_flow_action_sample conf; 924 uint32_t idx; 925 }; 926 /** Storage for struct rte_flow_action_sample. */ 927 struct raw_sample_conf { 928 struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; 929 }; 930 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; 931 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; 932 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; 933 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; 934 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; 935 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 936 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 937 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 938 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; 939 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; 940 struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; 941 struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; 942 943 static const char *const modify_field_ops[] = { 944 "set", "add", "sub", NULL 945 }; 946 947 static const char *const modify_field_ids[] = { 948 "start", "mac_dst", "mac_src", 949 "vlan_type", "vlan_id", "mac_type", 950 "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", 951 "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", 952 "tcp_port_src", "tcp_port_dst", 953 "tcp_seq_num", "tcp_ack_num", "tcp_flags", 954 "udp_port_src", "udp_port_dst", 955 "vxlan_vni", "geneve_vni", "gtp_teid", 956 "tag", "mark", "meta", "pointer", "value", 957 "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", 958 "ipv6_proto", 959 "flex_item", 960 "hash_result", 961 "geneve_opt_type", "geneve_opt_class", "geneve_opt_data", "mpls", 962 "tcp_data_off", "ipv4_ihl", "ipv4_total_len", "ipv6_payload_len", 963 "random", 964 NULL 965 }; 966 967 static const char *const meter_colors[] = { 968 "green", "yellow", "red", "all", NULL 969 }; 970 971 static const char *const table_insertion_types[] = { 972 "pattern", "index", NULL 973 }; 974 975 static const char *const table_hash_funcs[] = { 976 "default", "linear", "crc32", "crc16", NULL 977 }; 978 979 #define RAW_IPSEC_CONFS_MAX_NUM 8 980 981 /** Maximum number of subsequent tokens and arguments on the stack. */ 982 #define CTX_STACK_SIZE 16 983 984 /** Parser context. */ 985 struct context { 986 /** Stack of subsequent token lists to process. */ 987 const enum index *next[CTX_STACK_SIZE]; 988 /** Arguments for stacked tokens. */ 989 const void *args[CTX_STACK_SIZE]; 990 enum index curr; /**< Current token index. */ 991 enum index prev; /**< Index of the last token seen. */ 992 int next_num; /**< Number of entries in next[]. */ 993 int args_num; /**< Number of entries in args[]. */ 994 uint32_t eol:1; /**< EOL has been detected. */ 995 uint32_t last:1; /**< No more arguments. */ 996 portid_t port; /**< Current port ID (for completions). */ 997 uint32_t objdata; /**< Object-specific data. */ 998 void *object; /**< Address of current object for relative offsets. */ 999 void *objmask; /**< Object a full mask must be written to. */ 1000 }; 1001 1002 /** Token argument. */ 1003 struct arg { 1004 uint32_t hton:1; /**< Use network byte ordering. */ 1005 uint32_t sign:1; /**< Value is signed. */ 1006 uint32_t bounded:1; /**< Value is bounded. */ 1007 uintmax_t min; /**< Minimum value if bounded. */ 1008 uintmax_t max; /**< Maximum value if bounded. */ 1009 uint32_t offset; /**< Relative offset from ctx->object. */ 1010 uint32_t size; /**< Field size. */ 1011 const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ 1012 }; 1013 1014 /** Parser token definition. */ 1015 struct token { 1016 /** Type displayed during completion (defaults to "TOKEN"). */ 1017 const char *type; 1018 /** Help displayed during completion (defaults to token name). */ 1019 const char *help; 1020 /** Private data used by parser functions. */ 1021 const void *priv; 1022 /** 1023 * Lists of subsequent tokens to push on the stack. Each call to the 1024 * parser consumes the last entry of that stack. 1025 */ 1026 const enum index *const *next; 1027 /** Arguments stack for subsequent tokens that need them. */ 1028 const struct arg *const *args; 1029 /** 1030 * Token-processing callback, returns -1 in case of error, the 1031 * length of the matched string otherwise. If NULL, attempts to 1032 * match the token name. 1033 * 1034 * If buf is not NULL, the result should be stored in it according 1035 * to context. An error is returned if not large enough. 1036 */ 1037 int (*call)(struct context *ctx, const struct token *token, 1038 const char *str, unsigned int len, 1039 void *buf, unsigned int size); 1040 /** 1041 * Callback that provides possible values for this token, used for 1042 * completion. Returns -1 in case of error, the number of possible 1043 * values otherwise. If NULL, the token name is used. 1044 * 1045 * If buf is not NULL, entry index ent is written to buf and the 1046 * full length of the entry is returned (same behavior as 1047 * snprintf()). 1048 */ 1049 int (*comp)(struct context *ctx, const struct token *token, 1050 unsigned int ent, char *buf, unsigned int size); 1051 /** Mandatory token name, no default value. */ 1052 const char *name; 1053 }; 1054 1055 /** Static initializer for the next field. */ 1056 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } 1057 1058 /** Static initializer for a NEXT() entry. */ 1059 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } 1060 1061 /** Static initializer for the args field. */ 1062 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } 1063 1064 /** Static initializer for ARGS() to target a field. */ 1065 #define ARGS_ENTRY(s, f) \ 1066 (&(const struct arg){ \ 1067 .offset = offsetof(s, f), \ 1068 .size = sizeof(((s *)0)->f), \ 1069 }) 1070 1071 /** Static initializer for ARGS() to target a bit-field. */ 1072 #define ARGS_ENTRY_BF(s, f, b) \ 1073 (&(const struct arg){ \ 1074 .size = sizeof(s), \ 1075 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ 1076 }) 1077 1078 /** Static initializer for ARGS() to target a field with limits. */ 1079 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \ 1080 (&(const struct arg){ \ 1081 .bounded = 1, \ 1082 .min = (i), \ 1083 .max = (a), \ 1084 .offset = offsetof(s, f), \ 1085 .size = sizeof(((s *)0)->f), \ 1086 }) 1087 1088 /** Static initializer for ARGS() to target an arbitrary bit-mask. */ 1089 #define ARGS_ENTRY_MASK(s, f, m) \ 1090 (&(const struct arg){ \ 1091 .offset = offsetof(s, f), \ 1092 .size = sizeof(((s *)0)->f), \ 1093 .mask = (const void *)(m), \ 1094 }) 1095 1096 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ 1097 #define ARGS_ENTRY_MASK_HTON(s, f, m) \ 1098 (&(const struct arg){ \ 1099 .hton = 1, \ 1100 .offset = offsetof(s, f), \ 1101 .size = sizeof(((s *)0)->f), \ 1102 .mask = (const void *)(m), \ 1103 }) 1104 1105 /** Static initializer for ARGS() to target a pointer. */ 1106 #define ARGS_ENTRY_PTR(s, f) \ 1107 (&(const struct arg){ \ 1108 .size = sizeof(*((s *)0)->f), \ 1109 }) 1110 1111 /** Static initializer for ARGS() with arbitrary offset and size. */ 1112 #define ARGS_ENTRY_ARB(o, s) \ 1113 (&(const struct arg){ \ 1114 .offset = (o), \ 1115 .size = (s), \ 1116 }) 1117 1118 /** Same as ARGS_ENTRY_ARB() with bounded values. */ 1119 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ 1120 (&(const struct arg){ \ 1121 .bounded = 1, \ 1122 .min = (i), \ 1123 .max = (a), \ 1124 .offset = (o), \ 1125 .size = (s), \ 1126 }) 1127 1128 /** Same as ARGS_ENTRY() using network byte ordering. */ 1129 #define ARGS_ENTRY_HTON(s, f) \ 1130 (&(const struct arg){ \ 1131 .hton = 1, \ 1132 .offset = offsetof(s, f), \ 1133 .size = sizeof(((s *)0)->f), \ 1134 }) 1135 1136 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ 1137 #define ARG_ENTRY_HTON(s) \ 1138 (&(const struct arg){ \ 1139 .hton = 1, \ 1140 .offset = 0, \ 1141 .size = sizeof(s), \ 1142 }) 1143 1144 /** Parser output buffer layout expected by cmd_flow_parsed(). */ 1145 struct buffer { 1146 enum index command; /**< Flow command. */ 1147 portid_t port; /**< Affected port ID. */ 1148 queueid_t queue; /** Async queue ID. */ 1149 bool postpone; /** Postpone async operation */ 1150 union { 1151 struct { 1152 struct rte_flow_port_attr port_attr; 1153 uint32_t nb_queue; 1154 struct rte_flow_queue_attr queue_attr; 1155 } configure; /**< Configuration arguments. */ 1156 struct { 1157 uint32_t *template_id; 1158 uint32_t template_id_n; 1159 } templ_destroy; /**< Template destroy arguments. */ 1160 struct { 1161 uint32_t id; 1162 struct rte_flow_template_table_attr attr; 1163 uint32_t *pat_templ_id; 1164 uint32_t pat_templ_id_n; 1165 uint32_t *act_templ_id; 1166 uint32_t act_templ_id_n; 1167 } table; /**< Table arguments. */ 1168 struct { 1169 uint32_t *table_id; 1170 uint32_t table_id_n; 1171 } table_destroy; /**< Template destroy arguments. */ 1172 struct { 1173 uint32_t *action_id; 1174 uint32_t action_id_n; 1175 } ia_destroy; /**< Indirect action destroy arguments. */ 1176 struct { 1177 uint32_t action_id; 1178 enum rte_flow_query_update_mode qu_mode; 1179 } ia; /* Indirect action query arguments */ 1180 struct { 1181 uint32_t table_id; 1182 uint32_t pat_templ_id; 1183 uint32_t rule_id; 1184 uint32_t act_templ_id; 1185 struct rte_flow_attr attr; 1186 struct tunnel_ops tunnel_ops; 1187 uintptr_t user_id; 1188 struct rte_flow_item *pattern; 1189 struct rte_flow_action *actions; 1190 struct rte_flow_action *masks; 1191 uint32_t pattern_n; 1192 uint32_t actions_n; 1193 uint8_t *data; 1194 } vc; /**< Validate/create arguments. */ 1195 struct { 1196 uint64_t *rule; 1197 uint64_t rule_n; 1198 bool is_user_id; 1199 } destroy; /**< Destroy arguments. */ 1200 struct { 1201 char file[128]; 1202 bool mode; 1203 uint64_t rule; 1204 bool is_user_id; 1205 } dump; /**< Dump arguments. */ 1206 struct { 1207 uint64_t rule; 1208 struct rte_flow_action action; 1209 bool is_user_id; 1210 } query; /**< Query arguments. */ 1211 struct { 1212 uint32_t *group; 1213 uint32_t group_n; 1214 } list; /**< List arguments. */ 1215 struct { 1216 int set; 1217 } isolate; /**< Isolated mode arguments. */ 1218 struct { 1219 int destroy; 1220 } aged; /**< Aged arguments. */ 1221 struct { 1222 uint32_t policy_id; 1223 } policy;/**< Policy arguments. */ 1224 struct { 1225 uint16_t token; 1226 uintptr_t uintptr; 1227 char filename[128]; 1228 } flex; /**< Flex arguments*/ 1229 } args; /**< Command arguments. */ 1230 }; 1231 1232 /** Private data for pattern items. */ 1233 struct parse_item_priv { 1234 enum rte_flow_item_type type; /**< Item type. */ 1235 uint32_t size; /**< Size of item specification structure. */ 1236 }; 1237 1238 #define PRIV_ITEM(t, s) \ 1239 (&(const struct parse_item_priv){ \ 1240 .type = RTE_FLOW_ITEM_TYPE_ ## t, \ 1241 .size = s, \ 1242 }) 1243 1244 /** Private data for actions. */ 1245 struct parse_action_priv { 1246 enum rte_flow_action_type type; /**< Action type. */ 1247 uint32_t size; /**< Size of action configuration structure. */ 1248 }; 1249 1250 #define PRIV_ACTION(t, s) \ 1251 (&(const struct parse_action_priv){ \ 1252 .type = RTE_FLOW_ACTION_TYPE_ ## t, \ 1253 .size = s, \ 1254 }) 1255 1256 static const enum index next_flex_item[] = { 1257 FLEX_ITEM_INIT, 1258 FLEX_ITEM_CREATE, 1259 FLEX_ITEM_DESTROY, 1260 ZERO, 1261 }; 1262 1263 static const enum index next_config_attr[] = { 1264 CONFIG_QUEUES_NUMBER, 1265 CONFIG_QUEUES_SIZE, 1266 CONFIG_COUNTERS_NUMBER, 1267 CONFIG_AGING_OBJECTS_NUMBER, 1268 CONFIG_METERS_NUMBER, 1269 CONFIG_CONN_TRACK_NUMBER, 1270 CONFIG_QUOTAS_NUMBER, 1271 CONFIG_FLAGS, 1272 CONFIG_HOST_PORT, 1273 END, 1274 ZERO, 1275 }; 1276 1277 static const enum index next_pt_subcmd[] = { 1278 PATTERN_TEMPLATE_CREATE, 1279 PATTERN_TEMPLATE_DESTROY, 1280 ZERO, 1281 }; 1282 1283 static const enum index next_pt_attr[] = { 1284 PATTERN_TEMPLATE_CREATE_ID, 1285 PATTERN_TEMPLATE_RELAXED_MATCHING, 1286 PATTERN_TEMPLATE_INGRESS, 1287 PATTERN_TEMPLATE_EGRESS, 1288 PATTERN_TEMPLATE_TRANSFER, 1289 PATTERN_TEMPLATE_SPEC, 1290 ZERO, 1291 }; 1292 1293 static const enum index next_pt_destroy_attr[] = { 1294 PATTERN_TEMPLATE_DESTROY_ID, 1295 END, 1296 ZERO, 1297 }; 1298 1299 static const enum index next_at_subcmd[] = { 1300 ACTIONS_TEMPLATE_CREATE, 1301 ACTIONS_TEMPLATE_DESTROY, 1302 ZERO, 1303 }; 1304 1305 static const enum index next_at_attr[] = { 1306 ACTIONS_TEMPLATE_CREATE_ID, 1307 ACTIONS_TEMPLATE_INGRESS, 1308 ACTIONS_TEMPLATE_EGRESS, 1309 ACTIONS_TEMPLATE_TRANSFER, 1310 ACTIONS_TEMPLATE_SPEC, 1311 ZERO, 1312 }; 1313 1314 static const enum index next_at_destroy_attr[] = { 1315 ACTIONS_TEMPLATE_DESTROY_ID, 1316 END, 1317 ZERO, 1318 }; 1319 1320 static const enum index next_group_attr[] = { 1321 GROUP_INGRESS, 1322 GROUP_EGRESS, 1323 GROUP_TRANSFER, 1324 GROUP_SET_MISS_ACTIONS, 1325 ZERO, 1326 }; 1327 1328 static const enum index next_table_subcmd[] = { 1329 TABLE_CREATE, 1330 TABLE_DESTROY, 1331 ZERO, 1332 }; 1333 1334 static const enum index next_table_attr[] = { 1335 TABLE_CREATE_ID, 1336 TABLE_GROUP, 1337 TABLE_INSERTION_TYPE, 1338 TABLE_HASH_FUNC, 1339 TABLE_PRIORITY, 1340 TABLE_INGRESS, 1341 TABLE_EGRESS, 1342 TABLE_TRANSFER, 1343 TABLE_TRANSFER_WIRE_ORIG, 1344 TABLE_TRANSFER_VPORT_ORIG, 1345 TABLE_RULES_NUMBER, 1346 TABLE_PATTERN_TEMPLATE, 1347 TABLE_ACTIONS_TEMPLATE, 1348 END, 1349 ZERO, 1350 }; 1351 1352 static const enum index next_table_destroy_attr[] = { 1353 TABLE_DESTROY_ID, 1354 END, 1355 ZERO, 1356 }; 1357 1358 static const enum index next_queue_subcmd[] = { 1359 QUEUE_CREATE, 1360 QUEUE_DESTROY, 1361 QUEUE_UPDATE, 1362 QUEUE_AGED, 1363 QUEUE_INDIRECT_ACTION, 1364 ZERO, 1365 }; 1366 1367 static const enum index next_queue_destroy_attr[] = { 1368 QUEUE_DESTROY_ID, 1369 END, 1370 ZERO, 1371 }; 1372 1373 static const enum index next_qia_subcmd[] = { 1374 QUEUE_INDIRECT_ACTION_CREATE, 1375 QUEUE_INDIRECT_ACTION_UPDATE, 1376 QUEUE_INDIRECT_ACTION_DESTROY, 1377 QUEUE_INDIRECT_ACTION_QUERY, 1378 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 1379 ZERO, 1380 }; 1381 1382 static const enum index next_qia_create_attr[] = { 1383 QUEUE_INDIRECT_ACTION_CREATE_ID, 1384 QUEUE_INDIRECT_ACTION_INGRESS, 1385 QUEUE_INDIRECT_ACTION_EGRESS, 1386 QUEUE_INDIRECT_ACTION_TRANSFER, 1387 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 1388 QUEUE_INDIRECT_ACTION_SPEC, 1389 QUEUE_INDIRECT_ACTION_LIST, 1390 ZERO, 1391 }; 1392 1393 static const enum index next_qia_update_attr[] = { 1394 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1395 QUEUE_INDIRECT_ACTION_SPEC, 1396 ZERO, 1397 }; 1398 1399 static const enum index next_qia_destroy_attr[] = { 1400 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 1401 QUEUE_INDIRECT_ACTION_DESTROY_ID, 1402 END, 1403 ZERO, 1404 }; 1405 1406 static const enum index next_qia_query_attr[] = { 1407 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 1408 END, 1409 ZERO, 1410 }; 1411 1412 static const enum index next_ia_create_attr[] = { 1413 INDIRECT_ACTION_CREATE_ID, 1414 INDIRECT_ACTION_INGRESS, 1415 INDIRECT_ACTION_EGRESS, 1416 INDIRECT_ACTION_TRANSFER, 1417 INDIRECT_ACTION_SPEC, 1418 INDIRECT_ACTION_LIST, 1419 INDIRECT_ACTION_FLOW_CONF, 1420 ZERO, 1421 }; 1422 1423 static const enum index next_ia[] = { 1424 INDIRECT_ACTION_ID2PTR, 1425 ACTION_NEXT, 1426 ZERO 1427 }; 1428 1429 static const enum index next_ial[] = { 1430 ACTION_INDIRECT_LIST_HANDLE, 1431 ACTION_INDIRECT_LIST_CONF, 1432 ACTION_NEXT, 1433 ZERO 1434 }; 1435 1436 static const enum index next_qia_qu_attr[] = { 1437 QUEUE_INDIRECT_ACTION_QU_MODE, 1438 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1439 INDIRECT_ACTION_SPEC, 1440 ZERO 1441 }; 1442 1443 static const enum index next_ia_qu_attr[] = { 1444 INDIRECT_ACTION_QU_MODE, 1445 INDIRECT_ACTION_SPEC, 1446 ZERO 1447 }; 1448 1449 static const enum index next_dump_subcmd[] = { 1450 DUMP_ALL, 1451 DUMP_ONE, 1452 DUMP_IS_USER_ID, 1453 ZERO, 1454 }; 1455 1456 static const enum index next_ia_subcmd[] = { 1457 INDIRECT_ACTION_CREATE, 1458 INDIRECT_ACTION_UPDATE, 1459 INDIRECT_ACTION_DESTROY, 1460 INDIRECT_ACTION_QUERY, 1461 INDIRECT_ACTION_QUERY_UPDATE, 1462 ZERO, 1463 }; 1464 1465 static const enum index next_vc_attr[] = { 1466 VC_GROUP, 1467 VC_PRIORITY, 1468 VC_INGRESS, 1469 VC_EGRESS, 1470 VC_TRANSFER, 1471 VC_TUNNEL_SET, 1472 VC_TUNNEL_MATCH, 1473 VC_USER_ID, 1474 ITEM_PATTERN, 1475 ZERO, 1476 }; 1477 1478 static const enum index next_destroy_attr[] = { 1479 DESTROY_RULE, 1480 DESTROY_IS_USER_ID, 1481 END, 1482 ZERO, 1483 }; 1484 1485 static const enum index next_dump_attr[] = { 1486 COMMON_FILE_PATH, 1487 END, 1488 ZERO, 1489 }; 1490 1491 static const enum index next_query_attr[] = { 1492 QUERY_IS_USER_ID, 1493 END, 1494 ZERO, 1495 }; 1496 1497 static const enum index next_list_attr[] = { 1498 LIST_GROUP, 1499 END, 1500 ZERO, 1501 }; 1502 1503 static const enum index next_aged_attr[] = { 1504 AGED_DESTROY, 1505 END, 1506 ZERO, 1507 }; 1508 1509 static const enum index next_ia_destroy_attr[] = { 1510 INDIRECT_ACTION_DESTROY_ID, 1511 END, 1512 ZERO, 1513 }; 1514 1515 static const enum index next_async_insert_subcmd[] = { 1516 QUEUE_PATTERN_TEMPLATE, 1517 QUEUE_RULE_ID, 1518 ZERO, 1519 }; 1520 1521 static const enum index item_param[] = { 1522 ITEM_PARAM_IS, 1523 ITEM_PARAM_SPEC, 1524 ITEM_PARAM_LAST, 1525 ITEM_PARAM_MASK, 1526 ITEM_PARAM_PREFIX, 1527 ZERO, 1528 }; 1529 1530 static const enum index next_item[] = { 1531 ITEM_END, 1532 ITEM_VOID, 1533 ITEM_INVERT, 1534 ITEM_ANY, 1535 ITEM_PORT_ID, 1536 ITEM_MARK, 1537 ITEM_RAW, 1538 ITEM_ETH, 1539 ITEM_VLAN, 1540 ITEM_IPV4, 1541 ITEM_IPV6, 1542 ITEM_ICMP, 1543 ITEM_UDP, 1544 ITEM_TCP, 1545 ITEM_SCTP, 1546 ITEM_VXLAN, 1547 ITEM_E_TAG, 1548 ITEM_NVGRE, 1549 ITEM_MPLS, 1550 ITEM_GRE, 1551 ITEM_FUZZY, 1552 ITEM_GTP, 1553 ITEM_GTPC, 1554 ITEM_GTPU, 1555 ITEM_GENEVE, 1556 ITEM_VXLAN_GPE, 1557 ITEM_ARP_ETH_IPV4, 1558 ITEM_IPV6_EXT, 1559 ITEM_IPV6_FRAG_EXT, 1560 ITEM_IPV6_ROUTING_EXT, 1561 ITEM_ICMP6, 1562 ITEM_ICMP6_ECHO_REQUEST, 1563 ITEM_ICMP6_ECHO_REPLY, 1564 ITEM_ICMP6_ND_NS, 1565 ITEM_ICMP6_ND_NA, 1566 ITEM_ICMP6_ND_OPT, 1567 ITEM_ICMP6_ND_OPT_SLA_ETH, 1568 ITEM_ICMP6_ND_OPT_TLA_ETH, 1569 ITEM_META, 1570 ITEM_RANDOM, 1571 ITEM_GRE_KEY, 1572 ITEM_GRE_OPTION, 1573 ITEM_GTP_PSC, 1574 ITEM_PPPOES, 1575 ITEM_PPPOED, 1576 ITEM_PPPOE_PROTO_ID, 1577 ITEM_HIGIG2, 1578 ITEM_TAG, 1579 ITEM_L2TPV3OIP, 1580 ITEM_ESP, 1581 ITEM_AH, 1582 ITEM_PFCP, 1583 ITEM_ECPRI, 1584 ITEM_GENEVE_OPT, 1585 ITEM_INTEGRITY, 1586 ITEM_CONNTRACK, 1587 ITEM_PORT_REPRESENTOR, 1588 ITEM_REPRESENTED_PORT, 1589 ITEM_FLEX, 1590 ITEM_L2TPV2, 1591 ITEM_PPP, 1592 ITEM_METER, 1593 ITEM_QUOTA, 1594 ITEM_AGGR_AFFINITY, 1595 ITEM_TX_QUEUE, 1596 ITEM_IB_BTH, 1597 ITEM_PTYPE, 1598 ITEM_NSH, 1599 END_SET, 1600 ZERO, 1601 }; 1602 1603 static const enum index item_fuzzy[] = { 1604 ITEM_FUZZY_THRESH, 1605 ITEM_NEXT, 1606 ZERO, 1607 }; 1608 1609 static const enum index item_any[] = { 1610 ITEM_ANY_NUM, 1611 ITEM_NEXT, 1612 ZERO, 1613 }; 1614 1615 static const enum index item_port_id[] = { 1616 ITEM_PORT_ID_ID, 1617 ITEM_NEXT, 1618 ZERO, 1619 }; 1620 1621 static const enum index item_mark[] = { 1622 ITEM_MARK_ID, 1623 ITEM_NEXT, 1624 ZERO, 1625 }; 1626 1627 static const enum index item_raw[] = { 1628 ITEM_RAW_RELATIVE, 1629 ITEM_RAW_SEARCH, 1630 ITEM_RAW_OFFSET, 1631 ITEM_RAW_LIMIT, 1632 ITEM_RAW_PATTERN, 1633 ITEM_RAW_PATTERN_HEX, 1634 ITEM_NEXT, 1635 ZERO, 1636 }; 1637 1638 static const enum index item_eth[] = { 1639 ITEM_ETH_DST, 1640 ITEM_ETH_SRC, 1641 ITEM_ETH_TYPE, 1642 ITEM_ETH_HAS_VLAN, 1643 ITEM_NEXT, 1644 ZERO, 1645 }; 1646 1647 static const enum index item_vlan[] = { 1648 ITEM_VLAN_TCI, 1649 ITEM_VLAN_PCP, 1650 ITEM_VLAN_DEI, 1651 ITEM_VLAN_VID, 1652 ITEM_VLAN_INNER_TYPE, 1653 ITEM_VLAN_HAS_MORE_VLAN, 1654 ITEM_NEXT, 1655 ZERO, 1656 }; 1657 1658 static const enum index item_ipv4[] = { 1659 ITEM_IPV4_VER_IHL, 1660 ITEM_IPV4_TOS, 1661 ITEM_IPV4_LENGTH, 1662 ITEM_IPV4_ID, 1663 ITEM_IPV4_FRAGMENT_OFFSET, 1664 ITEM_IPV4_TTL, 1665 ITEM_IPV4_PROTO, 1666 ITEM_IPV4_SRC, 1667 ITEM_IPV4_DST, 1668 ITEM_NEXT, 1669 ZERO, 1670 }; 1671 1672 static const enum index item_ipv6[] = { 1673 ITEM_IPV6_TC, 1674 ITEM_IPV6_FLOW, 1675 ITEM_IPV6_LEN, 1676 ITEM_IPV6_PROTO, 1677 ITEM_IPV6_HOP, 1678 ITEM_IPV6_SRC, 1679 ITEM_IPV6_DST, 1680 ITEM_IPV6_HAS_FRAG_EXT, 1681 ITEM_IPV6_ROUTING_EXT, 1682 ITEM_NEXT, 1683 ZERO, 1684 }; 1685 1686 static const enum index item_ipv6_routing_ext[] = { 1687 ITEM_IPV6_ROUTING_EXT_TYPE, 1688 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 1689 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 1690 ITEM_NEXT, 1691 ZERO, 1692 }; 1693 1694 static const enum index item_icmp[] = { 1695 ITEM_ICMP_TYPE, 1696 ITEM_ICMP_CODE, 1697 ITEM_ICMP_IDENT, 1698 ITEM_ICMP_SEQ, 1699 ITEM_NEXT, 1700 ZERO, 1701 }; 1702 1703 static const enum index item_udp[] = { 1704 ITEM_UDP_SRC, 1705 ITEM_UDP_DST, 1706 ITEM_NEXT, 1707 ZERO, 1708 }; 1709 1710 static const enum index item_tcp[] = { 1711 ITEM_TCP_SRC, 1712 ITEM_TCP_DST, 1713 ITEM_TCP_FLAGS, 1714 ITEM_NEXT, 1715 ZERO, 1716 }; 1717 1718 static const enum index item_sctp[] = { 1719 ITEM_SCTP_SRC, 1720 ITEM_SCTP_DST, 1721 ITEM_SCTP_TAG, 1722 ITEM_SCTP_CKSUM, 1723 ITEM_NEXT, 1724 ZERO, 1725 }; 1726 1727 static const enum index item_vxlan[] = { 1728 ITEM_VXLAN_VNI, 1729 ITEM_VXLAN_LAST_RSVD, 1730 ITEM_NEXT, 1731 ZERO, 1732 }; 1733 1734 static const enum index item_e_tag[] = { 1735 ITEM_E_TAG_GRP_ECID_B, 1736 ITEM_NEXT, 1737 ZERO, 1738 }; 1739 1740 static const enum index item_nvgre[] = { 1741 ITEM_NVGRE_TNI, 1742 ITEM_NEXT, 1743 ZERO, 1744 }; 1745 1746 static const enum index item_mpls[] = { 1747 ITEM_MPLS_LABEL, 1748 ITEM_MPLS_TC, 1749 ITEM_MPLS_S, 1750 ITEM_MPLS_TTL, 1751 ITEM_NEXT, 1752 ZERO, 1753 }; 1754 1755 static const enum index item_gre[] = { 1756 ITEM_GRE_PROTO, 1757 ITEM_GRE_C_RSVD0_VER, 1758 ITEM_GRE_C_BIT, 1759 ITEM_GRE_K_BIT, 1760 ITEM_GRE_S_BIT, 1761 ITEM_NEXT, 1762 ZERO, 1763 }; 1764 1765 static const enum index item_gre_key[] = { 1766 ITEM_GRE_KEY_VALUE, 1767 ITEM_NEXT, 1768 ZERO, 1769 }; 1770 1771 static const enum index item_gre_option[] = { 1772 ITEM_GRE_OPTION_CHECKSUM, 1773 ITEM_GRE_OPTION_KEY, 1774 ITEM_GRE_OPTION_SEQUENCE, 1775 ITEM_NEXT, 1776 ZERO, 1777 }; 1778 1779 static const enum index item_gtp[] = { 1780 ITEM_GTP_FLAGS, 1781 ITEM_GTP_MSG_TYPE, 1782 ITEM_GTP_TEID, 1783 ITEM_NEXT, 1784 ZERO, 1785 }; 1786 1787 static const enum index item_geneve[] = { 1788 ITEM_GENEVE_VNI, 1789 ITEM_GENEVE_PROTO, 1790 ITEM_GENEVE_OPTLEN, 1791 ITEM_NEXT, 1792 ZERO, 1793 }; 1794 1795 static const enum index item_vxlan_gpe[] = { 1796 ITEM_VXLAN_GPE_VNI, 1797 ITEM_VXLAN_GPE_PROTO, 1798 ITEM_NEXT, 1799 ZERO, 1800 }; 1801 1802 static const enum index item_arp_eth_ipv4[] = { 1803 ITEM_ARP_ETH_IPV4_SHA, 1804 ITEM_ARP_ETH_IPV4_SPA, 1805 ITEM_ARP_ETH_IPV4_THA, 1806 ITEM_ARP_ETH_IPV4_TPA, 1807 ITEM_NEXT, 1808 ZERO, 1809 }; 1810 1811 static const enum index item_ipv6_ext[] = { 1812 ITEM_IPV6_EXT_NEXT_HDR, 1813 ITEM_NEXT, 1814 ZERO, 1815 }; 1816 1817 static const enum index item_ipv6_frag_ext[] = { 1818 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 1819 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 1820 ITEM_IPV6_FRAG_EXT_ID, 1821 ITEM_NEXT, 1822 ZERO, 1823 }; 1824 1825 static const enum index item_icmp6[] = { 1826 ITEM_ICMP6_TYPE, 1827 ITEM_ICMP6_CODE, 1828 ITEM_NEXT, 1829 ZERO, 1830 }; 1831 1832 static const enum index item_icmp6_echo_request[] = { 1833 ITEM_ICMP6_ECHO_REQUEST_ID, 1834 ITEM_ICMP6_ECHO_REQUEST_SEQ, 1835 ITEM_NEXT, 1836 ZERO, 1837 }; 1838 1839 static const enum index item_icmp6_echo_reply[] = { 1840 ITEM_ICMP6_ECHO_REPLY_ID, 1841 ITEM_ICMP6_ECHO_REPLY_SEQ, 1842 ITEM_NEXT, 1843 ZERO, 1844 }; 1845 1846 static const enum index item_icmp6_nd_ns[] = { 1847 ITEM_ICMP6_ND_NS_TARGET_ADDR, 1848 ITEM_NEXT, 1849 ZERO, 1850 }; 1851 1852 static const enum index item_icmp6_nd_na[] = { 1853 ITEM_ICMP6_ND_NA_TARGET_ADDR, 1854 ITEM_NEXT, 1855 ZERO, 1856 }; 1857 1858 static const enum index item_icmp6_nd_opt[] = { 1859 ITEM_ICMP6_ND_OPT_TYPE, 1860 ITEM_NEXT, 1861 ZERO, 1862 }; 1863 1864 static const enum index item_icmp6_nd_opt_sla_eth[] = { 1865 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 1866 ITEM_NEXT, 1867 ZERO, 1868 }; 1869 1870 static const enum index item_icmp6_nd_opt_tla_eth[] = { 1871 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 1872 ITEM_NEXT, 1873 ZERO, 1874 }; 1875 1876 static const enum index item_meta[] = { 1877 ITEM_META_DATA, 1878 ITEM_NEXT, 1879 ZERO, 1880 }; 1881 1882 static const enum index item_random[] = { 1883 ITEM_RANDOM_VALUE, 1884 ITEM_NEXT, 1885 ZERO, 1886 }; 1887 1888 static const enum index item_gtp_psc[] = { 1889 ITEM_GTP_PSC_QFI, 1890 ITEM_GTP_PSC_PDU_T, 1891 ITEM_NEXT, 1892 ZERO, 1893 }; 1894 1895 static const enum index item_pppoed[] = { 1896 ITEM_PPPOE_SEID, 1897 ITEM_NEXT, 1898 ZERO, 1899 }; 1900 1901 static const enum index item_pppoes[] = { 1902 ITEM_PPPOE_SEID, 1903 ITEM_NEXT, 1904 ZERO, 1905 }; 1906 1907 static const enum index item_pppoe_proto_id[] = { 1908 ITEM_NEXT, 1909 ZERO, 1910 }; 1911 1912 static const enum index item_higig2[] = { 1913 ITEM_HIGIG2_CLASSIFICATION, 1914 ITEM_HIGIG2_VID, 1915 ITEM_NEXT, 1916 ZERO, 1917 }; 1918 1919 static const enum index item_esp[] = { 1920 ITEM_ESP_SPI, 1921 ITEM_NEXT, 1922 ZERO, 1923 }; 1924 1925 static const enum index item_ah[] = { 1926 ITEM_AH_SPI, 1927 ITEM_NEXT, 1928 ZERO, 1929 }; 1930 1931 static const enum index item_pfcp[] = { 1932 ITEM_PFCP_S_FIELD, 1933 ITEM_PFCP_SEID, 1934 ITEM_NEXT, 1935 ZERO, 1936 }; 1937 1938 static const enum index next_set_raw[] = { 1939 SET_RAW_INDEX, 1940 ITEM_ETH, 1941 ZERO, 1942 }; 1943 1944 static const enum index item_tag[] = { 1945 ITEM_TAG_DATA, 1946 ITEM_TAG_INDEX, 1947 ITEM_NEXT, 1948 ZERO, 1949 }; 1950 1951 static const enum index item_l2tpv3oip[] = { 1952 ITEM_L2TPV3OIP_SESSION_ID, 1953 ITEM_NEXT, 1954 ZERO, 1955 }; 1956 1957 static const enum index item_ecpri[] = { 1958 ITEM_ECPRI_COMMON, 1959 ITEM_NEXT, 1960 ZERO, 1961 }; 1962 1963 static const enum index item_ecpri_common[] = { 1964 ITEM_ECPRI_COMMON_TYPE, 1965 ZERO, 1966 }; 1967 1968 static const enum index item_ecpri_common_type[] = { 1969 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 1970 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 1971 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 1972 ZERO, 1973 }; 1974 1975 static const enum index item_geneve_opt[] = { 1976 ITEM_GENEVE_OPT_CLASS, 1977 ITEM_GENEVE_OPT_TYPE, 1978 ITEM_GENEVE_OPT_LENGTH, 1979 ITEM_GENEVE_OPT_DATA, 1980 ITEM_NEXT, 1981 ZERO, 1982 }; 1983 1984 static const enum index item_integrity[] = { 1985 ITEM_INTEGRITY_LEVEL, 1986 ITEM_INTEGRITY_VALUE, 1987 ZERO, 1988 }; 1989 1990 static const enum index item_integrity_lv[] = { 1991 ITEM_INTEGRITY_LEVEL, 1992 ITEM_INTEGRITY_VALUE, 1993 ITEM_NEXT, 1994 ZERO, 1995 }; 1996 1997 static const enum index item_port_representor[] = { 1998 ITEM_PORT_REPRESENTOR_PORT_ID, 1999 ITEM_NEXT, 2000 ZERO, 2001 }; 2002 2003 static const enum index item_represented_port[] = { 2004 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 2005 ITEM_NEXT, 2006 ZERO, 2007 }; 2008 2009 static const enum index item_flex[] = { 2010 ITEM_FLEX_PATTERN_HANDLE, 2011 ITEM_FLEX_ITEM_HANDLE, 2012 ITEM_NEXT, 2013 ZERO, 2014 }; 2015 2016 static const enum index item_l2tpv2[] = { 2017 ITEM_L2TPV2_TYPE, 2018 ITEM_NEXT, 2019 ZERO, 2020 }; 2021 2022 static const enum index item_l2tpv2_type[] = { 2023 ITEM_L2TPV2_TYPE_DATA, 2024 ITEM_L2TPV2_TYPE_DATA_L, 2025 ITEM_L2TPV2_TYPE_DATA_S, 2026 ITEM_L2TPV2_TYPE_DATA_O, 2027 ITEM_L2TPV2_TYPE_DATA_L_S, 2028 ITEM_L2TPV2_TYPE_CTRL, 2029 ZERO, 2030 }; 2031 2032 static const enum index item_l2tpv2_type_data[] = { 2033 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 2034 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 2035 ITEM_NEXT, 2036 ZERO, 2037 }; 2038 2039 static const enum index item_l2tpv2_type_data_l[] = { 2040 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 2041 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 2042 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 2043 ITEM_NEXT, 2044 ZERO, 2045 }; 2046 2047 static const enum index item_l2tpv2_type_data_s[] = { 2048 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 2049 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 2050 ITEM_L2TPV2_MSG_DATA_S_NS, 2051 ITEM_L2TPV2_MSG_DATA_S_NR, 2052 ITEM_NEXT, 2053 ZERO, 2054 }; 2055 2056 static const enum index item_l2tpv2_type_data_o[] = { 2057 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 2058 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 2059 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 2060 ITEM_NEXT, 2061 ZERO, 2062 }; 2063 2064 static const enum index item_l2tpv2_type_data_l_s[] = { 2065 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 2066 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 2067 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 2068 ITEM_L2TPV2_MSG_DATA_L_S_NS, 2069 ITEM_L2TPV2_MSG_DATA_L_S_NR, 2070 ITEM_NEXT, 2071 ZERO, 2072 }; 2073 2074 static const enum index item_l2tpv2_type_ctrl[] = { 2075 ITEM_L2TPV2_MSG_CTRL_LENGTH, 2076 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 2077 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 2078 ITEM_L2TPV2_MSG_CTRL_NS, 2079 ITEM_L2TPV2_MSG_CTRL_NR, 2080 ITEM_NEXT, 2081 ZERO, 2082 }; 2083 2084 static const enum index item_ppp[] = { 2085 ITEM_PPP_ADDR, 2086 ITEM_PPP_CTRL, 2087 ITEM_PPP_PROTO_ID, 2088 ITEM_NEXT, 2089 ZERO, 2090 }; 2091 2092 static const enum index item_meter[] = { 2093 ITEM_METER_COLOR, 2094 ITEM_NEXT, 2095 ZERO, 2096 }; 2097 2098 static const enum index item_quota[] = { 2099 ITEM_QUOTA_STATE, 2100 ITEM_NEXT, 2101 ZERO, 2102 }; 2103 2104 static const enum index item_aggr_affinity[] = { 2105 ITEM_AGGR_AFFINITY_VALUE, 2106 ITEM_NEXT, 2107 ZERO, 2108 }; 2109 2110 static const enum index item_tx_queue[] = { 2111 ITEM_TX_QUEUE_VALUE, 2112 ITEM_NEXT, 2113 ZERO, 2114 }; 2115 2116 static const enum index item_ib_bth[] = { 2117 ITEM_IB_BTH_OPCODE, 2118 ITEM_IB_BTH_PKEY, 2119 ITEM_IB_BTH_DST_QPN, 2120 ITEM_IB_BTH_PSN, 2121 ITEM_NEXT, 2122 ZERO, 2123 }; 2124 2125 static const enum index item_ptype[] = { 2126 ITEM_PTYPE_VALUE, 2127 ITEM_NEXT, 2128 ZERO, 2129 }; 2130 2131 static const enum index item_nsh[] = { 2132 ITEM_NEXT, 2133 ZERO, 2134 }; 2135 2136 static const enum index next_action[] = { 2137 ACTION_END, 2138 ACTION_VOID, 2139 ACTION_PASSTHRU, 2140 ACTION_SKIP_CMAN, 2141 ACTION_JUMP, 2142 ACTION_MARK, 2143 ACTION_FLAG, 2144 ACTION_QUEUE, 2145 ACTION_DROP, 2146 ACTION_COUNT, 2147 ACTION_RSS, 2148 ACTION_PF, 2149 ACTION_VF, 2150 ACTION_PORT_ID, 2151 ACTION_METER, 2152 ACTION_METER_COLOR, 2153 ACTION_METER_MARK, 2154 ACTION_OF_DEC_NW_TTL, 2155 ACTION_OF_POP_VLAN, 2156 ACTION_OF_PUSH_VLAN, 2157 ACTION_OF_SET_VLAN_VID, 2158 ACTION_OF_SET_VLAN_PCP, 2159 ACTION_OF_POP_MPLS, 2160 ACTION_OF_PUSH_MPLS, 2161 ACTION_VXLAN_ENCAP, 2162 ACTION_VXLAN_DECAP, 2163 ACTION_NVGRE_ENCAP, 2164 ACTION_NVGRE_DECAP, 2165 ACTION_L2_ENCAP, 2166 ACTION_L2_DECAP, 2167 ACTION_MPLSOGRE_ENCAP, 2168 ACTION_MPLSOGRE_DECAP, 2169 ACTION_MPLSOUDP_ENCAP, 2170 ACTION_MPLSOUDP_DECAP, 2171 ACTION_SET_IPV4_SRC, 2172 ACTION_SET_IPV4_DST, 2173 ACTION_SET_IPV6_SRC, 2174 ACTION_SET_IPV6_DST, 2175 ACTION_SET_TP_SRC, 2176 ACTION_SET_TP_DST, 2177 ACTION_MAC_SWAP, 2178 ACTION_DEC_TTL, 2179 ACTION_SET_TTL, 2180 ACTION_SET_MAC_SRC, 2181 ACTION_SET_MAC_DST, 2182 ACTION_INC_TCP_SEQ, 2183 ACTION_DEC_TCP_SEQ, 2184 ACTION_INC_TCP_ACK, 2185 ACTION_DEC_TCP_ACK, 2186 ACTION_RAW_ENCAP, 2187 ACTION_RAW_DECAP, 2188 ACTION_SET_TAG, 2189 ACTION_SET_META, 2190 ACTION_SET_IPV4_DSCP, 2191 ACTION_SET_IPV6_DSCP, 2192 ACTION_AGE, 2193 ACTION_AGE_UPDATE, 2194 ACTION_SAMPLE, 2195 ACTION_INDIRECT, 2196 ACTION_INDIRECT_LIST, 2197 ACTION_SHARED_INDIRECT, 2198 ACTION_MODIFY_FIELD, 2199 ACTION_CONNTRACK, 2200 ACTION_CONNTRACK_UPDATE, 2201 ACTION_PORT_REPRESENTOR, 2202 ACTION_REPRESENTED_PORT, 2203 ACTION_SEND_TO_KERNEL, 2204 ACTION_QUOTA_CREATE, 2205 ACTION_QUOTA_QU, 2206 ACTION_IPV6_EXT_REMOVE, 2207 ACTION_IPV6_EXT_PUSH, 2208 ACTION_NAT64, 2209 ZERO, 2210 }; 2211 2212 static const enum index action_quota_create[] = { 2213 ACTION_QUOTA_CREATE_LIMIT, 2214 ACTION_QUOTA_CREATE_MODE, 2215 ACTION_NEXT, 2216 ZERO 2217 }; 2218 2219 static const enum index action_quota_update[] = { 2220 ACTION_QUOTA_QU_LIMIT, 2221 ACTION_QUOTA_QU_UPDATE_OP, 2222 ACTION_NEXT, 2223 ZERO 2224 }; 2225 2226 static const enum index action_mark[] = { 2227 ACTION_MARK_ID, 2228 ACTION_NEXT, 2229 ZERO, 2230 }; 2231 2232 static const enum index action_queue[] = { 2233 ACTION_QUEUE_INDEX, 2234 ACTION_NEXT, 2235 ZERO, 2236 }; 2237 2238 static const enum index action_count[] = { 2239 ACTION_COUNT_ID, 2240 ACTION_NEXT, 2241 ZERO, 2242 }; 2243 2244 static const enum index action_rss[] = { 2245 ACTION_RSS_FUNC, 2246 ACTION_RSS_LEVEL, 2247 ACTION_RSS_TYPES, 2248 ACTION_RSS_KEY, 2249 ACTION_RSS_KEY_LEN, 2250 ACTION_RSS_QUEUES, 2251 ACTION_NEXT, 2252 ZERO, 2253 }; 2254 2255 static const enum index action_vf[] = { 2256 ACTION_VF_ORIGINAL, 2257 ACTION_VF_ID, 2258 ACTION_NEXT, 2259 ZERO, 2260 }; 2261 2262 static const enum index action_port_id[] = { 2263 ACTION_PORT_ID_ORIGINAL, 2264 ACTION_PORT_ID_ID, 2265 ACTION_NEXT, 2266 ZERO, 2267 }; 2268 2269 static const enum index action_meter[] = { 2270 ACTION_METER_ID, 2271 ACTION_NEXT, 2272 ZERO, 2273 }; 2274 2275 static const enum index action_meter_color[] = { 2276 ACTION_METER_COLOR_TYPE, 2277 ACTION_NEXT, 2278 ZERO, 2279 }; 2280 2281 static const enum index action_meter_mark[] = { 2282 ACTION_METER_PROFILE, 2283 ACTION_METER_POLICY, 2284 ACTION_METER_COLOR_MODE, 2285 ACTION_METER_STATE, 2286 ACTION_NEXT, 2287 ZERO, 2288 }; 2289 2290 static const enum index action_of_push_vlan[] = { 2291 ACTION_OF_PUSH_VLAN_ETHERTYPE, 2292 ACTION_NEXT, 2293 ZERO, 2294 }; 2295 2296 static const enum index action_of_set_vlan_vid[] = { 2297 ACTION_OF_SET_VLAN_VID_VLAN_VID, 2298 ACTION_NEXT, 2299 ZERO, 2300 }; 2301 2302 static const enum index action_of_set_vlan_pcp[] = { 2303 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 2304 ACTION_NEXT, 2305 ZERO, 2306 }; 2307 2308 static const enum index action_of_pop_mpls[] = { 2309 ACTION_OF_POP_MPLS_ETHERTYPE, 2310 ACTION_NEXT, 2311 ZERO, 2312 }; 2313 2314 static const enum index action_of_push_mpls[] = { 2315 ACTION_OF_PUSH_MPLS_ETHERTYPE, 2316 ACTION_NEXT, 2317 ZERO, 2318 }; 2319 2320 static const enum index action_set_ipv4_src[] = { 2321 ACTION_SET_IPV4_SRC_IPV4_SRC, 2322 ACTION_NEXT, 2323 ZERO, 2324 }; 2325 2326 static const enum index action_set_mac_src[] = { 2327 ACTION_SET_MAC_SRC_MAC_SRC, 2328 ACTION_NEXT, 2329 ZERO, 2330 }; 2331 2332 static const enum index action_set_ipv4_dst[] = { 2333 ACTION_SET_IPV4_DST_IPV4_DST, 2334 ACTION_NEXT, 2335 ZERO, 2336 }; 2337 2338 static const enum index action_set_ipv6_src[] = { 2339 ACTION_SET_IPV6_SRC_IPV6_SRC, 2340 ACTION_NEXT, 2341 ZERO, 2342 }; 2343 2344 static const enum index action_set_ipv6_dst[] = { 2345 ACTION_SET_IPV6_DST_IPV6_DST, 2346 ACTION_NEXT, 2347 ZERO, 2348 }; 2349 2350 static const enum index action_set_tp_src[] = { 2351 ACTION_SET_TP_SRC_TP_SRC, 2352 ACTION_NEXT, 2353 ZERO, 2354 }; 2355 2356 static const enum index action_set_tp_dst[] = { 2357 ACTION_SET_TP_DST_TP_DST, 2358 ACTION_NEXT, 2359 ZERO, 2360 }; 2361 2362 static const enum index action_set_ttl[] = { 2363 ACTION_SET_TTL_TTL, 2364 ACTION_NEXT, 2365 ZERO, 2366 }; 2367 2368 static const enum index action_jump[] = { 2369 ACTION_JUMP_GROUP, 2370 ACTION_NEXT, 2371 ZERO, 2372 }; 2373 2374 static const enum index action_set_mac_dst[] = { 2375 ACTION_SET_MAC_DST_MAC_DST, 2376 ACTION_NEXT, 2377 ZERO, 2378 }; 2379 2380 static const enum index action_inc_tcp_seq[] = { 2381 ACTION_INC_TCP_SEQ_VALUE, 2382 ACTION_NEXT, 2383 ZERO, 2384 }; 2385 2386 static const enum index action_dec_tcp_seq[] = { 2387 ACTION_DEC_TCP_SEQ_VALUE, 2388 ACTION_NEXT, 2389 ZERO, 2390 }; 2391 2392 static const enum index action_inc_tcp_ack[] = { 2393 ACTION_INC_TCP_ACK_VALUE, 2394 ACTION_NEXT, 2395 ZERO, 2396 }; 2397 2398 static const enum index action_dec_tcp_ack[] = { 2399 ACTION_DEC_TCP_ACK_VALUE, 2400 ACTION_NEXT, 2401 ZERO, 2402 }; 2403 2404 static const enum index action_raw_encap[] = { 2405 ACTION_RAW_ENCAP_INDEX, 2406 ACTION_NEXT, 2407 ZERO, 2408 }; 2409 2410 static const enum index action_raw_decap[] = { 2411 ACTION_RAW_DECAP_INDEX, 2412 ACTION_NEXT, 2413 ZERO, 2414 }; 2415 2416 static const enum index action_ipv6_ext_remove[] = { 2417 ACTION_IPV6_EXT_REMOVE_INDEX, 2418 ACTION_NEXT, 2419 ZERO, 2420 }; 2421 2422 static const enum index action_ipv6_ext_push[] = { 2423 ACTION_IPV6_EXT_PUSH_INDEX, 2424 ACTION_NEXT, 2425 ZERO, 2426 }; 2427 2428 static const enum index action_set_tag[] = { 2429 ACTION_SET_TAG_DATA, 2430 ACTION_SET_TAG_INDEX, 2431 ACTION_SET_TAG_MASK, 2432 ACTION_NEXT, 2433 ZERO, 2434 }; 2435 2436 static const enum index action_set_meta[] = { 2437 ACTION_SET_META_DATA, 2438 ACTION_SET_META_MASK, 2439 ACTION_NEXT, 2440 ZERO, 2441 }; 2442 2443 static const enum index action_set_ipv4_dscp[] = { 2444 ACTION_SET_IPV4_DSCP_VALUE, 2445 ACTION_NEXT, 2446 ZERO, 2447 }; 2448 2449 static const enum index action_set_ipv6_dscp[] = { 2450 ACTION_SET_IPV6_DSCP_VALUE, 2451 ACTION_NEXT, 2452 ZERO, 2453 }; 2454 2455 static const enum index action_age[] = { 2456 ACTION_AGE, 2457 ACTION_AGE_TIMEOUT, 2458 ACTION_NEXT, 2459 ZERO, 2460 }; 2461 2462 static const enum index action_age_update[] = { 2463 ACTION_AGE_UPDATE, 2464 ACTION_AGE_UPDATE_TIMEOUT, 2465 ACTION_AGE_UPDATE_TOUCH, 2466 ACTION_NEXT, 2467 ZERO, 2468 }; 2469 2470 static const enum index action_sample[] = { 2471 ACTION_SAMPLE, 2472 ACTION_SAMPLE_RATIO, 2473 ACTION_SAMPLE_INDEX, 2474 ACTION_NEXT, 2475 ZERO, 2476 }; 2477 2478 static const enum index next_action_sample[] = { 2479 ACTION_QUEUE, 2480 ACTION_RSS, 2481 ACTION_MARK, 2482 ACTION_COUNT, 2483 ACTION_PORT_ID, 2484 ACTION_RAW_ENCAP, 2485 ACTION_VXLAN_ENCAP, 2486 ACTION_NVGRE_ENCAP, 2487 ACTION_REPRESENTED_PORT, 2488 ACTION_PORT_REPRESENTOR, 2489 ACTION_NEXT, 2490 ZERO, 2491 }; 2492 2493 static const enum index item_ipv6_push_ext[] = { 2494 ITEM_IPV6_PUSH_REMOVE_EXT, 2495 ZERO, 2496 }; 2497 2498 static const enum index item_ipv6_push_ext_type[] = { 2499 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 2500 ZERO, 2501 }; 2502 2503 static const enum index item_ipv6_push_ext_header[] = { 2504 ITEM_IPV6_ROUTING_EXT, 2505 ITEM_NEXT, 2506 ZERO, 2507 }; 2508 2509 static const enum index action_modify_field_dst[] = { 2510 ACTION_MODIFY_FIELD_DST_LEVEL, 2511 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 2512 ACTION_MODIFY_FIELD_DST_TYPE_ID, 2513 ACTION_MODIFY_FIELD_DST_CLASS_ID, 2514 ACTION_MODIFY_FIELD_DST_OFFSET, 2515 ACTION_MODIFY_FIELD_SRC_TYPE, 2516 ZERO, 2517 }; 2518 2519 static const enum index action_modify_field_src[] = { 2520 ACTION_MODIFY_FIELD_SRC_LEVEL, 2521 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 2522 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 2523 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 2524 ACTION_MODIFY_FIELD_SRC_OFFSET, 2525 ACTION_MODIFY_FIELD_SRC_VALUE, 2526 ACTION_MODIFY_FIELD_SRC_POINTER, 2527 ACTION_MODIFY_FIELD_WIDTH, 2528 ZERO, 2529 }; 2530 2531 static const enum index action_update_conntrack[] = { 2532 ACTION_CONNTRACK_UPDATE_DIR, 2533 ACTION_CONNTRACK_UPDATE_CTX, 2534 ACTION_NEXT, 2535 ZERO, 2536 }; 2537 2538 static const enum index action_port_representor[] = { 2539 ACTION_PORT_REPRESENTOR_PORT_ID, 2540 ACTION_NEXT, 2541 ZERO, 2542 }; 2543 2544 static const enum index action_represented_port[] = { 2545 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 2546 ACTION_NEXT, 2547 ZERO, 2548 }; 2549 2550 static const enum index action_nat64[] = { 2551 ACTION_NAT64_MODE, 2552 ACTION_NEXT, 2553 ZERO, 2554 }; 2555 2556 static int parse_set_raw_encap_decap(struct context *, const struct token *, 2557 const char *, unsigned int, 2558 void *, unsigned int); 2559 static int parse_set_sample_action(struct context *, const struct token *, 2560 const char *, unsigned int, 2561 void *, unsigned int); 2562 static int parse_set_ipv6_ext_action(struct context *, const struct token *, 2563 const char *, unsigned int, 2564 void *, unsigned int); 2565 static int parse_set_init(struct context *, const struct token *, 2566 const char *, unsigned int, 2567 void *, unsigned int); 2568 static int 2569 parse_flex_handle(struct context *, const struct token *, 2570 const char *, unsigned int, void *, unsigned int); 2571 static int parse_init(struct context *, const struct token *, 2572 const char *, unsigned int, 2573 void *, unsigned int); 2574 static int parse_vc(struct context *, const struct token *, 2575 const char *, unsigned int, 2576 void *, unsigned int); 2577 static int parse_vc_spec(struct context *, const struct token *, 2578 const char *, unsigned int, void *, unsigned int); 2579 static int parse_vc_conf(struct context *, const struct token *, 2580 const char *, unsigned int, void *, unsigned int); 2581 static int parse_vc_conf_timeout(struct context *, const struct token *, 2582 const char *, unsigned int, void *, 2583 unsigned int); 2584 static int parse_vc_item_ecpri_type(struct context *, const struct token *, 2585 const char *, unsigned int, 2586 void *, unsigned int); 2587 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, 2588 const char *, unsigned int, 2589 void *, unsigned int); 2590 static int parse_vc_action_meter_color_type(struct context *, 2591 const struct token *, 2592 const char *, unsigned int, void *, 2593 unsigned int); 2594 static int parse_vc_action_rss(struct context *, const struct token *, 2595 const char *, unsigned int, void *, 2596 unsigned int); 2597 static int parse_vc_action_rss_func(struct context *, const struct token *, 2598 const char *, unsigned int, void *, 2599 unsigned int); 2600 static int parse_vc_action_rss_type(struct context *, const struct token *, 2601 const char *, unsigned int, void *, 2602 unsigned int); 2603 static int parse_vc_action_rss_queue(struct context *, const struct token *, 2604 const char *, unsigned int, void *, 2605 unsigned int); 2606 static int parse_vc_action_vxlan_encap(struct context *, const struct token *, 2607 const char *, unsigned int, void *, 2608 unsigned int); 2609 static int parse_vc_action_nvgre_encap(struct context *, const struct token *, 2610 const char *, unsigned int, void *, 2611 unsigned int); 2612 static int parse_vc_action_l2_encap(struct context *, const struct token *, 2613 const char *, unsigned int, void *, 2614 unsigned int); 2615 static int parse_vc_action_l2_decap(struct context *, const struct token *, 2616 const char *, unsigned int, void *, 2617 unsigned int); 2618 static int parse_vc_action_mplsogre_encap(struct context *, 2619 const struct token *, const char *, 2620 unsigned int, void *, unsigned int); 2621 static int parse_vc_action_mplsogre_decap(struct context *, 2622 const struct token *, const char *, 2623 unsigned int, void *, unsigned int); 2624 static int parse_vc_action_mplsoudp_encap(struct context *, 2625 const struct token *, const char *, 2626 unsigned int, void *, unsigned int); 2627 static int parse_vc_action_mplsoudp_decap(struct context *, 2628 const struct token *, const char *, 2629 unsigned int, void *, unsigned int); 2630 static int parse_vc_action_raw_encap(struct context *, 2631 const struct token *, const char *, 2632 unsigned int, void *, unsigned int); 2633 static int parse_vc_action_raw_decap(struct context *, 2634 const struct token *, const char *, 2635 unsigned int, void *, unsigned int); 2636 static int parse_vc_action_raw_encap_index(struct context *, 2637 const struct token *, const char *, 2638 unsigned int, void *, unsigned int); 2639 static int parse_vc_action_raw_decap_index(struct context *, 2640 const struct token *, const char *, 2641 unsigned int, void *, unsigned int); 2642 static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 2643 const char *str, unsigned int len, void *buf, 2644 unsigned int size); 2645 static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, 2646 const struct token *token, 2647 const char *str, unsigned int len, 2648 void *buf, 2649 unsigned int size); 2650 static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 2651 const char *str, unsigned int len, void *buf, 2652 unsigned int size); 2653 static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, 2654 const struct token *token, 2655 const char *str, unsigned int len, 2656 void *buf, 2657 unsigned int size); 2658 static int parse_vc_action_set_meta(struct context *ctx, 2659 const struct token *token, const char *str, 2660 unsigned int len, void *buf, 2661 unsigned int size); 2662 static int parse_vc_action_sample(struct context *ctx, 2663 const struct token *token, const char *str, 2664 unsigned int len, void *buf, 2665 unsigned int size); 2666 static int 2667 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 2668 const char *str, unsigned int len, void *buf, 2669 unsigned int size); 2670 static int 2671 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 2672 const char *str, unsigned int len, void *buf, 2673 unsigned int size); 2674 static int 2675 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 2676 const char *str, unsigned int len, void *buf, 2677 unsigned int size); 2678 static int 2679 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 2680 const char *str, unsigned int len, void *buf, 2681 unsigned int size); 2682 static int 2683 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 2684 const char *str, unsigned int len, void *buf, 2685 unsigned int size); 2686 static int parse_destroy(struct context *, const struct token *, 2687 const char *, unsigned int, 2688 void *, unsigned int); 2689 static int parse_flush(struct context *, const struct token *, 2690 const char *, unsigned int, 2691 void *, unsigned int); 2692 static int parse_dump(struct context *, const struct token *, 2693 const char *, unsigned int, 2694 void *, unsigned int); 2695 static int parse_query(struct context *, const struct token *, 2696 const char *, unsigned int, 2697 void *, unsigned int); 2698 static int parse_action(struct context *, const struct token *, 2699 const char *, unsigned int, 2700 void *, unsigned int); 2701 static int parse_list(struct context *, const struct token *, 2702 const char *, unsigned int, 2703 void *, unsigned int); 2704 static int parse_aged(struct context *, const struct token *, 2705 const char *, unsigned int, 2706 void *, unsigned int); 2707 static int parse_isolate(struct context *, const struct token *, 2708 const char *, unsigned int, 2709 void *, unsigned int); 2710 static int parse_configure(struct context *, const struct token *, 2711 const char *, unsigned int, 2712 void *, unsigned int); 2713 static int parse_template(struct context *, const struct token *, 2714 const char *, unsigned int, 2715 void *, unsigned int); 2716 static int parse_template_destroy(struct context *, const struct token *, 2717 const char *, unsigned int, 2718 void *, unsigned int); 2719 static int parse_table(struct context *, const struct token *, 2720 const char *, unsigned int, void *, unsigned int); 2721 static int parse_table_destroy(struct context *, const struct token *, 2722 const char *, unsigned int, 2723 void *, unsigned int); 2724 static int parse_qo(struct context *, const struct token *, 2725 const char *, unsigned int, 2726 void *, unsigned int); 2727 static int parse_qo_destroy(struct context *, const struct token *, 2728 const char *, unsigned int, 2729 void *, unsigned int); 2730 static int parse_qia(struct context *, const struct token *, 2731 const char *, unsigned int, 2732 void *, unsigned int); 2733 static int parse_qia_destroy(struct context *, const struct token *, 2734 const char *, unsigned int, 2735 void *, unsigned int); 2736 static int parse_push(struct context *, const struct token *, 2737 const char *, unsigned int, 2738 void *, unsigned int); 2739 static int parse_pull(struct context *, const struct token *, 2740 const char *, unsigned int, 2741 void *, unsigned int); 2742 static int parse_group(struct context *, const struct token *, 2743 const char *, unsigned int, 2744 void *, unsigned int); 2745 static int parse_hash(struct context *, const struct token *, 2746 const char *, unsigned int, 2747 void *, unsigned int); 2748 static int parse_tunnel(struct context *, const struct token *, 2749 const char *, unsigned int, 2750 void *, unsigned int); 2751 static int parse_flex(struct context *, const struct token *, 2752 const char *, unsigned int, void *, unsigned int); 2753 static int parse_int(struct context *, const struct token *, 2754 const char *, unsigned int, 2755 void *, unsigned int); 2756 static int parse_prefix(struct context *, const struct token *, 2757 const char *, unsigned int, 2758 void *, unsigned int); 2759 static int parse_boolean(struct context *, const struct token *, 2760 const char *, unsigned int, 2761 void *, unsigned int); 2762 static int parse_string(struct context *, const struct token *, 2763 const char *, unsigned int, 2764 void *, unsigned int); 2765 static int parse_hex(struct context *ctx, const struct token *token, 2766 const char *str, unsigned int len, 2767 void *buf, unsigned int size); 2768 static int parse_string0(struct context *, const struct token *, 2769 const char *, unsigned int, 2770 void *, unsigned int); 2771 static int parse_mac_addr(struct context *, const struct token *, 2772 const char *, unsigned int, 2773 void *, unsigned int); 2774 static int parse_ipv4_addr(struct context *, const struct token *, 2775 const char *, unsigned int, 2776 void *, unsigned int); 2777 static int parse_ipv6_addr(struct context *, const struct token *, 2778 const char *, unsigned int, 2779 void *, unsigned int); 2780 static int parse_port(struct context *, const struct token *, 2781 const char *, unsigned int, 2782 void *, unsigned int); 2783 static int parse_ia(struct context *, const struct token *, 2784 const char *, unsigned int, 2785 void *, unsigned int); 2786 static int parse_ia_destroy(struct context *ctx, const struct token *token, 2787 const char *str, unsigned int len, 2788 void *buf, unsigned int size); 2789 static int parse_ia_id2ptr(struct context *ctx, const struct token *token, 2790 const char *str, unsigned int len, void *buf, 2791 unsigned int size); 2792 2793 static int parse_indlst_id2ptr(struct context *ctx, const struct token *token, 2794 const char *str, unsigned int len, void *buf, 2795 unsigned int size); 2796 static int parse_ia_port(struct context *ctx, const struct token *token, 2797 const char *str, unsigned int len, void *buf, 2798 unsigned int size); 2799 static int parse_mp(struct context *, const struct token *, 2800 const char *, unsigned int, 2801 void *, unsigned int); 2802 static int parse_meter_profile_id2ptr(struct context *ctx, 2803 const struct token *token, 2804 const char *str, unsigned int len, 2805 void *buf, unsigned int size); 2806 static int parse_meter_policy_id2ptr(struct context *ctx, 2807 const struct token *token, 2808 const char *str, unsigned int len, 2809 void *buf, unsigned int size); 2810 static int parse_meter_color(struct context *ctx, const struct token *token, 2811 const char *str, unsigned int len, void *buf, 2812 unsigned int size); 2813 static int parse_insertion_table_type(struct context *ctx, const struct token *token, 2814 const char *str, unsigned int len, void *buf, 2815 unsigned int size); 2816 static int parse_hash_table_type(struct context *ctx, const struct token *token, 2817 const char *str, unsigned int len, void *buf, 2818 unsigned int size); 2819 static int 2820 parse_quota_state_name(struct context *ctx, const struct token *token, 2821 const char *str, unsigned int len, void *buf, 2822 unsigned int size); 2823 static int 2824 parse_quota_mode_name(struct context *ctx, const struct token *token, 2825 const char *str, unsigned int len, void *buf, 2826 unsigned int size); 2827 static int 2828 parse_quota_update_name(struct context *ctx, const struct token *token, 2829 const char *str, unsigned int len, void *buf, 2830 unsigned int size); 2831 static int 2832 parse_qu_mode_name(struct context *ctx, const struct token *token, 2833 const char *str, unsigned int len, void *buf, 2834 unsigned int size); 2835 static int comp_none(struct context *, const struct token *, 2836 unsigned int, char *, unsigned int); 2837 static int comp_boolean(struct context *, const struct token *, 2838 unsigned int, char *, unsigned int); 2839 static int comp_action(struct context *, const struct token *, 2840 unsigned int, char *, unsigned int); 2841 static int comp_port(struct context *, const struct token *, 2842 unsigned int, char *, unsigned int); 2843 static int comp_rule_id(struct context *, const struct token *, 2844 unsigned int, char *, unsigned int); 2845 static int comp_vc_action_rss_type(struct context *, const struct token *, 2846 unsigned int, char *, unsigned int); 2847 static int comp_vc_action_rss_queue(struct context *, const struct token *, 2848 unsigned int, char *, unsigned int); 2849 static int comp_set_raw_index(struct context *, const struct token *, 2850 unsigned int, char *, unsigned int); 2851 static int comp_set_sample_index(struct context *, const struct token *, 2852 unsigned int, char *, unsigned int); 2853 static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 2854 unsigned int ent, char *buf, unsigned int size); 2855 static int comp_set_modify_field_op(struct context *, const struct token *, 2856 unsigned int, char *, unsigned int); 2857 static int comp_set_modify_field_id(struct context *, const struct token *, 2858 unsigned int, char *, unsigned int); 2859 static int comp_pattern_template_id(struct context *, const struct token *, 2860 unsigned int, char *, unsigned int); 2861 static int comp_actions_template_id(struct context *, const struct token *, 2862 unsigned int, char *, unsigned int); 2863 static int comp_table_id(struct context *, const struct token *, 2864 unsigned int, char *, unsigned int); 2865 static int comp_queue_id(struct context *, const struct token *, 2866 unsigned int, char *, unsigned int); 2867 static int comp_meter_color(struct context *, const struct token *, 2868 unsigned int, char *, unsigned int); 2869 static int comp_insertion_table_type(struct context *, const struct token *, 2870 unsigned int, char *, unsigned int); 2871 static int comp_hash_table_type(struct context *, const struct token *, 2872 unsigned int, char *, unsigned int); 2873 static int 2874 comp_quota_state_name(struct context *ctx, const struct token *token, 2875 unsigned int ent, char *buf, unsigned int size); 2876 static int 2877 comp_quota_mode_name(struct context *ctx, const struct token *token, 2878 unsigned int ent, char *buf, unsigned int size); 2879 static int 2880 comp_quota_update_name(struct context *ctx, const struct token *token, 2881 unsigned int ent, char *buf, unsigned int size); 2882 static int 2883 comp_qu_mode_name(struct context *ctx, const struct token *token, 2884 unsigned int ent, char *buf, unsigned int size); 2885 2886 struct indlst_conf { 2887 uint32_t id; 2888 uint32_t conf_num; 2889 struct rte_flow_action *actions; 2890 const void **conf; 2891 SLIST_ENTRY(indlst_conf) next; 2892 }; 2893 2894 static const struct indlst_conf *indirect_action_list_conf_get(uint32_t conf_id); 2895 2896 /** Token definitions. */ 2897 static const struct token token_list[] = { 2898 /* Special tokens. */ 2899 [ZERO] = { 2900 .name = "ZERO", 2901 .help = "null entry, abused as the entry point", 2902 .next = NEXT(NEXT_ENTRY(FLOW, ADD)), 2903 }, 2904 [END] = { 2905 .name = "", 2906 .type = "RETURN", 2907 .help = "command may end here", 2908 }, 2909 [START_SET] = { 2910 .name = "START_SET", 2911 .help = "null entry, abused as the entry point for set", 2912 .next = NEXT(NEXT_ENTRY(SET)), 2913 }, 2914 [END_SET] = { 2915 .name = "end_set", 2916 .type = "RETURN", 2917 .help = "set command may end here", 2918 }, 2919 /* Common tokens. */ 2920 [COMMON_INTEGER] = { 2921 .name = "{int}", 2922 .type = "INTEGER", 2923 .help = "integer value", 2924 .call = parse_int, 2925 .comp = comp_none, 2926 }, 2927 [COMMON_UNSIGNED] = { 2928 .name = "{unsigned}", 2929 .type = "UNSIGNED", 2930 .help = "unsigned integer value", 2931 .call = parse_int, 2932 .comp = comp_none, 2933 }, 2934 [COMMON_PREFIX] = { 2935 .name = "{prefix}", 2936 .type = "PREFIX", 2937 .help = "prefix length for bit-mask", 2938 .call = parse_prefix, 2939 .comp = comp_none, 2940 }, 2941 [COMMON_BOOLEAN] = { 2942 .name = "{boolean}", 2943 .type = "BOOLEAN", 2944 .help = "any boolean value", 2945 .call = parse_boolean, 2946 .comp = comp_boolean, 2947 }, 2948 [COMMON_STRING] = { 2949 .name = "{string}", 2950 .type = "STRING", 2951 .help = "fixed string", 2952 .call = parse_string, 2953 .comp = comp_none, 2954 }, 2955 [COMMON_HEX] = { 2956 .name = "{hex}", 2957 .type = "HEX", 2958 .help = "fixed string", 2959 .call = parse_hex, 2960 }, 2961 [COMMON_FILE_PATH] = { 2962 .name = "{file path}", 2963 .type = "STRING", 2964 .help = "file path", 2965 .call = parse_string0, 2966 .comp = comp_none, 2967 }, 2968 [COMMON_MAC_ADDR] = { 2969 .name = "{MAC address}", 2970 .type = "MAC-48", 2971 .help = "standard MAC address notation", 2972 .call = parse_mac_addr, 2973 .comp = comp_none, 2974 }, 2975 [COMMON_IPV4_ADDR] = { 2976 .name = "{IPv4 address}", 2977 .type = "IPV4 ADDRESS", 2978 .help = "standard IPv4 address notation", 2979 .call = parse_ipv4_addr, 2980 .comp = comp_none, 2981 }, 2982 [COMMON_IPV6_ADDR] = { 2983 .name = "{IPv6 address}", 2984 .type = "IPV6 ADDRESS", 2985 .help = "standard IPv6 address notation", 2986 .call = parse_ipv6_addr, 2987 .comp = comp_none, 2988 }, 2989 [COMMON_RULE_ID] = { 2990 .name = "{rule id}", 2991 .type = "RULE ID", 2992 .help = "rule identifier", 2993 .call = parse_int, 2994 .comp = comp_rule_id, 2995 }, 2996 [COMMON_PORT_ID] = { 2997 .name = "{port_id}", 2998 .type = "PORT ID", 2999 .help = "port identifier", 3000 .call = parse_port, 3001 .comp = comp_port, 3002 }, 3003 [COMMON_GROUP_ID] = { 3004 .name = "{group_id}", 3005 .type = "GROUP ID", 3006 .help = "group identifier", 3007 .call = parse_int, 3008 .comp = comp_none, 3009 }, 3010 [COMMON_PRIORITY_LEVEL] = { 3011 .name = "{level}", 3012 .type = "PRIORITY", 3013 .help = "priority level", 3014 .call = parse_int, 3015 .comp = comp_none, 3016 }, 3017 [COMMON_INDIRECT_ACTION_ID] = { 3018 .name = "{indirect_action_id}", 3019 .type = "INDIRECT_ACTION_ID", 3020 .help = "indirect action id", 3021 .call = parse_int, 3022 .comp = comp_none, 3023 }, 3024 [COMMON_PROFILE_ID] = { 3025 .name = "{profile_id}", 3026 .type = "PROFILE_ID", 3027 .help = "profile id", 3028 .call = parse_int, 3029 .comp = comp_none, 3030 }, 3031 [COMMON_POLICY_ID] = { 3032 .name = "{policy_id}", 3033 .type = "POLICY_ID", 3034 .help = "policy id", 3035 .call = parse_int, 3036 .comp = comp_none, 3037 }, 3038 [COMMON_FLEX_TOKEN] = { 3039 .name = "{flex token}", 3040 .type = "flex token", 3041 .help = "flex token", 3042 .call = parse_int, 3043 .comp = comp_none, 3044 }, 3045 [COMMON_FLEX_HANDLE] = { 3046 .name = "{flex handle}", 3047 .type = "FLEX HANDLE", 3048 .help = "fill flex item data", 3049 .call = parse_flex_handle, 3050 .comp = comp_none, 3051 }, 3052 [COMMON_PATTERN_TEMPLATE_ID] = { 3053 .name = "{pattern_template_id}", 3054 .type = "PATTERN_TEMPLATE_ID", 3055 .help = "pattern template id", 3056 .call = parse_int, 3057 .comp = comp_pattern_template_id, 3058 }, 3059 [COMMON_ACTIONS_TEMPLATE_ID] = { 3060 .name = "{actions_template_id}", 3061 .type = "ACTIONS_TEMPLATE_ID", 3062 .help = "actions template id", 3063 .call = parse_int, 3064 .comp = comp_actions_template_id, 3065 }, 3066 [COMMON_TABLE_ID] = { 3067 .name = "{table_id}", 3068 .type = "TABLE_ID", 3069 .help = "table id", 3070 .call = parse_int, 3071 .comp = comp_table_id, 3072 }, 3073 [COMMON_QUEUE_ID] = { 3074 .name = "{queue_id}", 3075 .type = "QUEUE_ID", 3076 .help = "queue id", 3077 .call = parse_int, 3078 .comp = comp_queue_id, 3079 }, 3080 /* Top-level command. */ 3081 [FLOW] = { 3082 .name = "flow", 3083 .type = "{command} {port_id} [{arg} [...]]", 3084 .help = "manage ingress/egress flow rules", 3085 .next = NEXT(NEXT_ENTRY 3086 (INFO, 3087 CONFIGURE, 3088 PATTERN_TEMPLATE, 3089 ACTIONS_TEMPLATE, 3090 TABLE, 3091 FLOW_GROUP, 3092 INDIRECT_ACTION, 3093 VALIDATE, 3094 CREATE, 3095 DESTROY, 3096 FLUSH, 3097 DUMP, 3098 LIST, 3099 AGED, 3100 QUERY, 3101 ISOLATE, 3102 TUNNEL, 3103 FLEX, 3104 QUEUE, 3105 PUSH, 3106 PULL, 3107 HASH)), 3108 .call = parse_init, 3109 }, 3110 /* Top-level command. */ 3111 [INFO] = { 3112 .name = "info", 3113 .help = "get information about flow engine", 3114 .next = NEXT(NEXT_ENTRY(END), 3115 NEXT_ENTRY(COMMON_PORT_ID)), 3116 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3117 .call = parse_configure, 3118 }, 3119 /* Top-level command. */ 3120 [CONFIGURE] = { 3121 .name = "configure", 3122 .help = "configure flow engine", 3123 .next = NEXT(next_config_attr, 3124 NEXT_ENTRY(COMMON_PORT_ID)), 3125 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3126 .call = parse_configure, 3127 }, 3128 /* Configure arguments. */ 3129 [CONFIG_QUEUES_NUMBER] = { 3130 .name = "queues_number", 3131 .help = "number of queues", 3132 .next = NEXT(next_config_attr, 3133 NEXT_ENTRY(COMMON_UNSIGNED)), 3134 .args = ARGS(ARGS_ENTRY(struct buffer, 3135 args.configure.nb_queue)), 3136 }, 3137 [CONFIG_QUEUES_SIZE] = { 3138 .name = "queues_size", 3139 .help = "number of elements in queues", 3140 .next = NEXT(next_config_attr, 3141 NEXT_ENTRY(COMMON_UNSIGNED)), 3142 .args = ARGS(ARGS_ENTRY(struct buffer, 3143 args.configure.queue_attr.size)), 3144 }, 3145 [CONFIG_COUNTERS_NUMBER] = { 3146 .name = "counters_number", 3147 .help = "number of counters", 3148 .next = NEXT(next_config_attr, 3149 NEXT_ENTRY(COMMON_UNSIGNED)), 3150 .args = ARGS(ARGS_ENTRY(struct buffer, 3151 args.configure.port_attr.nb_counters)), 3152 }, 3153 [CONFIG_AGING_OBJECTS_NUMBER] = { 3154 .name = "aging_counters_number", 3155 .help = "number of aging objects", 3156 .next = NEXT(next_config_attr, 3157 NEXT_ENTRY(COMMON_UNSIGNED)), 3158 .args = ARGS(ARGS_ENTRY(struct buffer, 3159 args.configure.port_attr.nb_aging_objects)), 3160 }, 3161 [CONFIG_QUOTAS_NUMBER] = { 3162 .name = "quotas_number", 3163 .help = "number of quotas", 3164 .next = NEXT(next_config_attr, 3165 NEXT_ENTRY(COMMON_UNSIGNED)), 3166 .args = ARGS(ARGS_ENTRY(struct buffer, 3167 args.configure.port_attr.nb_quotas)), 3168 }, 3169 [CONFIG_METERS_NUMBER] = { 3170 .name = "meters_number", 3171 .help = "number of meters", 3172 .next = NEXT(next_config_attr, 3173 NEXT_ENTRY(COMMON_UNSIGNED)), 3174 .args = ARGS(ARGS_ENTRY(struct buffer, 3175 args.configure.port_attr.nb_meters)), 3176 }, 3177 [CONFIG_CONN_TRACK_NUMBER] = { 3178 .name = "conn_tracks_number", 3179 .help = "number of connection trackings", 3180 .next = NEXT(next_config_attr, 3181 NEXT_ENTRY(COMMON_UNSIGNED)), 3182 .args = ARGS(ARGS_ENTRY(struct buffer, 3183 args.configure.port_attr.nb_conn_tracks)), 3184 }, 3185 [CONFIG_FLAGS] = { 3186 .name = "flags", 3187 .help = "configuration flags", 3188 .next = NEXT(next_config_attr, 3189 NEXT_ENTRY(COMMON_UNSIGNED)), 3190 .args = ARGS(ARGS_ENTRY(struct buffer, 3191 args.configure.port_attr.flags)), 3192 }, 3193 [CONFIG_HOST_PORT] = { 3194 .name = "host_port", 3195 .help = "host port for shared objects", 3196 .next = NEXT(next_config_attr, 3197 NEXT_ENTRY(COMMON_UNSIGNED)), 3198 .args = ARGS(ARGS_ENTRY(struct buffer, 3199 args.configure.port_attr.host_port_id)), 3200 }, 3201 /* Top-level command. */ 3202 [PATTERN_TEMPLATE] = { 3203 .name = "pattern_template", 3204 .type = "{command} {port_id} [{arg} [...]]", 3205 .help = "manage pattern templates", 3206 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3207 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3208 .call = parse_template, 3209 }, 3210 /* Sub-level commands. */ 3211 [PATTERN_TEMPLATE_CREATE] = { 3212 .name = "create", 3213 .help = "create pattern template", 3214 .next = NEXT(next_pt_attr), 3215 .call = parse_template, 3216 }, 3217 [PATTERN_TEMPLATE_DESTROY] = { 3218 .name = "destroy", 3219 .help = "destroy pattern template", 3220 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), 3221 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3222 .call = parse_template_destroy, 3223 }, 3224 /* Pattern template arguments. */ 3225 [PATTERN_TEMPLATE_CREATE_ID] = { 3226 .name = "pattern_template_id", 3227 .help = "specify a pattern template id to create", 3228 .next = NEXT(next_pt_attr, 3229 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3230 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), 3231 }, 3232 [PATTERN_TEMPLATE_DESTROY_ID] = { 3233 .name = "pattern_template", 3234 .help = "specify a pattern template id to destroy", 3235 .next = NEXT(next_pt_destroy_attr, 3236 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3237 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3238 args.templ_destroy.template_id)), 3239 .call = parse_template_destroy, 3240 }, 3241 [PATTERN_TEMPLATE_RELAXED_MATCHING] = { 3242 .name = "relaxed", 3243 .help = "is matching relaxed", 3244 .next = NEXT(next_pt_attr, 3245 NEXT_ENTRY(COMMON_BOOLEAN)), 3246 .args = ARGS(ARGS_ENTRY_BF(struct buffer, 3247 args.vc.attr.reserved, 1)), 3248 }, 3249 [PATTERN_TEMPLATE_INGRESS] = { 3250 .name = "ingress", 3251 .help = "attribute pattern to ingress", 3252 .next = NEXT(next_pt_attr), 3253 .call = parse_template, 3254 }, 3255 [PATTERN_TEMPLATE_EGRESS] = { 3256 .name = "egress", 3257 .help = "attribute pattern to egress", 3258 .next = NEXT(next_pt_attr), 3259 .call = parse_template, 3260 }, 3261 [PATTERN_TEMPLATE_TRANSFER] = { 3262 .name = "transfer", 3263 .help = "attribute pattern to transfer", 3264 .next = NEXT(next_pt_attr), 3265 .call = parse_template, 3266 }, 3267 [PATTERN_TEMPLATE_SPEC] = { 3268 .name = "template", 3269 .help = "specify item to create pattern template", 3270 .next = NEXT(next_item), 3271 }, 3272 /* Top-level command. */ 3273 [ACTIONS_TEMPLATE] = { 3274 .name = "actions_template", 3275 .type = "{command} {port_id} [{arg} [...]]", 3276 .help = "manage actions templates", 3277 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3278 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3279 .call = parse_template, 3280 }, 3281 /* Sub-level commands. */ 3282 [ACTIONS_TEMPLATE_CREATE] = { 3283 .name = "create", 3284 .help = "create actions template", 3285 .next = NEXT(next_at_attr), 3286 .call = parse_template, 3287 }, 3288 [ACTIONS_TEMPLATE_DESTROY] = { 3289 .name = "destroy", 3290 .help = "destroy actions template", 3291 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), 3292 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3293 .call = parse_template_destroy, 3294 }, 3295 /* Actions template arguments. */ 3296 [ACTIONS_TEMPLATE_CREATE_ID] = { 3297 .name = "actions_template_id", 3298 .help = "specify an actions template id to create", 3299 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), 3300 NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), 3301 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3302 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), 3303 }, 3304 [ACTIONS_TEMPLATE_DESTROY_ID] = { 3305 .name = "actions_template", 3306 .help = "specify an actions template id to destroy", 3307 .next = NEXT(next_at_destroy_attr, 3308 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3309 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3310 args.templ_destroy.template_id)), 3311 .call = parse_template_destroy, 3312 }, 3313 [ACTIONS_TEMPLATE_INGRESS] = { 3314 .name = "ingress", 3315 .help = "attribute actions to ingress", 3316 .next = NEXT(next_at_attr), 3317 .call = parse_template, 3318 }, 3319 [ACTIONS_TEMPLATE_EGRESS] = { 3320 .name = "egress", 3321 .help = "attribute actions to egress", 3322 .next = NEXT(next_at_attr), 3323 .call = parse_template, 3324 }, 3325 [ACTIONS_TEMPLATE_TRANSFER] = { 3326 .name = "transfer", 3327 .help = "attribute actions to transfer", 3328 .next = NEXT(next_at_attr), 3329 .call = parse_template, 3330 }, 3331 [ACTIONS_TEMPLATE_SPEC] = { 3332 .name = "template", 3333 .help = "specify action to create actions template", 3334 .next = NEXT(next_action), 3335 .call = parse_template, 3336 }, 3337 [ACTIONS_TEMPLATE_MASK] = { 3338 .name = "mask", 3339 .help = "specify action mask to create actions template", 3340 .next = NEXT(next_action), 3341 .call = parse_template, 3342 }, 3343 /* Top-level command. */ 3344 [TABLE] = { 3345 .name = "template_table", 3346 .type = "{command} {port_id} [{arg} [...]]", 3347 .help = "manage template tables", 3348 .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3349 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3350 .call = parse_table, 3351 }, 3352 /* Sub-level commands. */ 3353 [TABLE_CREATE] = { 3354 .name = "create", 3355 .help = "create template table", 3356 .next = NEXT(next_table_attr), 3357 .call = parse_table, 3358 }, 3359 [TABLE_DESTROY] = { 3360 .name = "destroy", 3361 .help = "destroy template table", 3362 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3363 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3364 .call = parse_table_destroy, 3365 }, 3366 /* Table arguments. */ 3367 [TABLE_CREATE_ID] = { 3368 .name = "table_id", 3369 .help = "specify table id to create", 3370 .next = NEXT(next_table_attr, 3371 NEXT_ENTRY(COMMON_TABLE_ID)), 3372 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3373 }, 3374 [TABLE_DESTROY_ID] = { 3375 .name = "table", 3376 .help = "specify table id to destroy", 3377 .next = NEXT(next_table_destroy_attr, 3378 NEXT_ENTRY(COMMON_TABLE_ID)), 3379 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3380 args.table_destroy.table_id)), 3381 .call = parse_table_destroy, 3382 }, 3383 [TABLE_INSERTION_TYPE] = { 3384 .name = "insertion_type", 3385 .help = "specify insertion type", 3386 .next = NEXT(next_table_attr, 3387 NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)), 3388 .args = ARGS(ARGS_ENTRY(struct buffer, 3389 args.table.attr.insertion_type)), 3390 }, 3391 [TABLE_INSERTION_TYPE_NAME] = { 3392 .name = "insertion_type_name", 3393 .help = "insertion type name", 3394 .call = parse_insertion_table_type, 3395 .comp = comp_insertion_table_type, 3396 }, 3397 [TABLE_HASH_FUNC] = { 3398 .name = "hash_func", 3399 .help = "specify hash calculation function", 3400 .next = NEXT(next_table_attr, 3401 NEXT_ENTRY(TABLE_HASH_FUNC_NAME)), 3402 .args = ARGS(ARGS_ENTRY(struct buffer, 3403 args.table.attr.hash_func)), 3404 }, 3405 [TABLE_HASH_FUNC_NAME] = { 3406 .name = "hash_func_name", 3407 .help = "hash calculation function name", 3408 .call = parse_hash_table_type, 3409 .comp = comp_hash_table_type, 3410 }, 3411 [TABLE_GROUP] = { 3412 .name = "group", 3413 .help = "specify a group", 3414 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3415 .args = ARGS(ARGS_ENTRY(struct buffer, 3416 args.table.attr.flow_attr.group)), 3417 }, 3418 [TABLE_PRIORITY] = { 3419 .name = "priority", 3420 .help = "specify a priority level", 3421 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 3422 .args = ARGS(ARGS_ENTRY(struct buffer, 3423 args.table.attr.flow_attr.priority)), 3424 }, 3425 [TABLE_EGRESS] = { 3426 .name = "egress", 3427 .help = "affect rule to egress", 3428 .next = NEXT(next_table_attr), 3429 .call = parse_table, 3430 }, 3431 [TABLE_INGRESS] = { 3432 .name = "ingress", 3433 .help = "affect rule to ingress", 3434 .next = NEXT(next_table_attr), 3435 .call = parse_table, 3436 }, 3437 [TABLE_TRANSFER] = { 3438 .name = "transfer", 3439 .help = "affect rule to transfer", 3440 .next = NEXT(next_table_attr), 3441 .call = parse_table, 3442 }, 3443 [TABLE_TRANSFER_WIRE_ORIG] = { 3444 .name = "wire_orig", 3445 .help = "affect rule direction to transfer", 3446 .next = NEXT(next_table_attr), 3447 .call = parse_table, 3448 }, 3449 [TABLE_TRANSFER_VPORT_ORIG] = { 3450 .name = "vport_orig", 3451 .help = "affect rule direction to transfer", 3452 .next = NEXT(next_table_attr), 3453 .call = parse_table, 3454 }, 3455 [TABLE_RULES_NUMBER] = { 3456 .name = "rules_number", 3457 .help = "number of rules in table", 3458 .next = NEXT(next_table_attr, 3459 NEXT_ENTRY(COMMON_UNSIGNED)), 3460 .args = ARGS(ARGS_ENTRY(struct buffer, 3461 args.table.attr.nb_flows)), 3462 .call = parse_table, 3463 }, 3464 [TABLE_PATTERN_TEMPLATE] = { 3465 .name = "pattern_template", 3466 .help = "specify pattern template id", 3467 .next = NEXT(next_table_attr, 3468 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3469 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3470 args.table.pat_templ_id)), 3471 .call = parse_table, 3472 }, 3473 [TABLE_ACTIONS_TEMPLATE] = { 3474 .name = "actions_template", 3475 .help = "specify actions template id", 3476 .next = NEXT(next_table_attr, 3477 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3478 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3479 args.table.act_templ_id)), 3480 .call = parse_table, 3481 }, 3482 /* Top-level command. */ 3483 [FLOW_GROUP] = { 3484 .name = "group", 3485 .help = "manage flow groups", 3486 .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), 3487 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3488 .call = parse_group, 3489 }, 3490 /* Sub-level commands. */ 3491 [GROUP_SET_MISS_ACTIONS] = { 3492 .name = "set_miss_actions", 3493 .help = "set group miss actions", 3494 .next = NEXT(next_action), 3495 .call = parse_group, 3496 }, 3497 /* Group arguments */ 3498 [GROUP_ID] = { 3499 .name = "group_id", 3500 .help = "group id", 3501 .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3502 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3503 }, 3504 [GROUP_INGRESS] = { 3505 .name = "ingress", 3506 .help = "group ingress attr", 3507 .next = NEXT(next_group_attr), 3508 .call = parse_group, 3509 }, 3510 [GROUP_EGRESS] = { 3511 .name = "egress", 3512 .help = "group egress attr", 3513 .next = NEXT(next_group_attr), 3514 .call = parse_group, 3515 }, 3516 [GROUP_TRANSFER] = { 3517 .name = "transfer", 3518 .help = "group transfer attr", 3519 .next = NEXT(next_group_attr), 3520 .call = parse_group, 3521 }, 3522 /* Top-level command. */ 3523 [QUEUE] = { 3524 .name = "queue", 3525 .help = "queue a flow rule operation", 3526 .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3527 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3528 .call = parse_qo, 3529 }, 3530 /* Sub-level commands. */ 3531 [QUEUE_CREATE] = { 3532 .name = "create", 3533 .help = "create a flow rule", 3534 .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), 3535 NEXT_ENTRY(COMMON_QUEUE_ID)), 3536 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3537 .call = parse_qo, 3538 }, 3539 [QUEUE_DESTROY] = { 3540 .name = "destroy", 3541 .help = "destroy a flow rule", 3542 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3543 NEXT_ENTRY(COMMON_QUEUE_ID)), 3544 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3545 .call = parse_qo_destroy, 3546 }, 3547 [QUEUE_UPDATE] = { 3548 .name = "update", 3549 .help = "update a flow rule", 3550 .next = NEXT(NEXT_ENTRY(QUEUE_UPDATE_ID), 3551 NEXT_ENTRY(COMMON_QUEUE_ID)), 3552 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3553 .call = parse_qo, 3554 }, 3555 [QUEUE_AGED] = { 3556 .name = "aged", 3557 .help = "list and destroy aged flows", 3558 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), 3559 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3560 .call = parse_aged, 3561 }, 3562 [QUEUE_INDIRECT_ACTION] = { 3563 .name = "indirect_action", 3564 .help = "queue indirect actions", 3565 .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), 3566 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3567 .call = parse_qia, 3568 }, 3569 /* Queue arguments. */ 3570 [QUEUE_TEMPLATE_TABLE] = { 3571 .name = "template_table", 3572 .help = "specify table id", 3573 .next = NEXT(next_async_insert_subcmd, 3574 NEXT_ENTRY(COMMON_TABLE_ID)), 3575 .args = ARGS(ARGS_ENTRY(struct buffer, 3576 args.vc.table_id)), 3577 .call = parse_qo, 3578 }, 3579 [QUEUE_PATTERN_TEMPLATE] = { 3580 .name = "pattern_template", 3581 .help = "specify pattern template index", 3582 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3583 NEXT_ENTRY(COMMON_UNSIGNED)), 3584 .args = ARGS(ARGS_ENTRY(struct buffer, 3585 args.vc.pat_templ_id)), 3586 .call = parse_qo, 3587 }, 3588 [QUEUE_ACTIONS_TEMPLATE] = { 3589 .name = "actions_template", 3590 .help = "specify actions template index", 3591 .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), 3592 NEXT_ENTRY(COMMON_UNSIGNED)), 3593 .args = ARGS(ARGS_ENTRY(struct buffer, 3594 args.vc.act_templ_id)), 3595 .call = parse_qo, 3596 }, 3597 [QUEUE_RULE_ID] = { 3598 .name = "rule_index", 3599 .help = "specify flow rule index", 3600 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3601 NEXT_ENTRY(COMMON_UNSIGNED)), 3602 .args = ARGS(ARGS_ENTRY(struct buffer, 3603 args.vc.rule_id)), 3604 .call = parse_qo, 3605 }, 3606 [QUEUE_CREATE_POSTPONE] = { 3607 .name = "postpone", 3608 .help = "postpone create operation", 3609 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3610 NEXT_ENTRY(COMMON_BOOLEAN)), 3611 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3612 .call = parse_qo, 3613 }, 3614 [QUEUE_DESTROY_POSTPONE] = { 3615 .name = "postpone", 3616 .help = "postpone destroy operation", 3617 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3618 NEXT_ENTRY(COMMON_BOOLEAN)), 3619 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3620 .call = parse_qo_destroy, 3621 }, 3622 [QUEUE_DESTROY_ID] = { 3623 .name = "rule", 3624 .help = "specify rule id to destroy", 3625 .next = NEXT(next_queue_destroy_attr, 3626 NEXT_ENTRY(COMMON_UNSIGNED)), 3627 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3628 args.destroy.rule)), 3629 .call = parse_qo_destroy, 3630 }, 3631 [QUEUE_UPDATE_ID] = { 3632 .name = "rule", 3633 .help = "specify rule id to update", 3634 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3635 NEXT_ENTRY(COMMON_UNSIGNED)), 3636 .args = ARGS(ARGS_ENTRY(struct buffer, 3637 args.vc.rule_id)), 3638 .call = parse_qo, 3639 }, 3640 /* Queue indirect action arguments */ 3641 [QUEUE_INDIRECT_ACTION_CREATE] = { 3642 .name = "create", 3643 .help = "create indirect action", 3644 .next = NEXT(next_qia_create_attr), 3645 .call = parse_qia, 3646 }, 3647 [QUEUE_INDIRECT_ACTION_UPDATE] = { 3648 .name = "update", 3649 .help = "update indirect action", 3650 .next = NEXT(next_qia_update_attr, 3651 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3652 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3653 .call = parse_qia, 3654 }, 3655 [QUEUE_INDIRECT_ACTION_DESTROY] = { 3656 .name = "destroy", 3657 .help = "destroy indirect action", 3658 .next = NEXT(next_qia_destroy_attr), 3659 .call = parse_qia_destroy, 3660 }, 3661 [QUEUE_INDIRECT_ACTION_QUERY] = { 3662 .name = "query", 3663 .help = "query indirect action", 3664 .next = NEXT(next_qia_query_attr, 3665 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3666 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3667 .call = parse_qia, 3668 }, 3669 /* Indirect action destroy arguments. */ 3670 [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { 3671 .name = "postpone", 3672 .help = "postpone destroy operation", 3673 .next = NEXT(next_qia_destroy_attr, 3674 NEXT_ENTRY(COMMON_BOOLEAN)), 3675 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3676 }, 3677 [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { 3678 .name = "action_id", 3679 .help = "specify a indirect action id to destroy", 3680 .next = NEXT(next_qia_destroy_attr, 3681 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3682 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3683 args.ia_destroy.action_id)), 3684 .call = parse_qia_destroy, 3685 }, 3686 [QUEUE_INDIRECT_ACTION_QUERY_UPDATE] = { 3687 .name = "query_update", 3688 .help = "indirect query [and|or] update action", 3689 .next = NEXT(next_qia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3690 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3691 .call = parse_qia 3692 }, 3693 [QUEUE_INDIRECT_ACTION_QU_MODE] = { 3694 .name = "mode", 3695 .help = "indirect query [and|or] update action", 3696 .next = NEXT(next_qia_qu_attr, 3697 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 3698 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 3699 .call = parse_qia 3700 }, 3701 /* Indirect action update arguments. */ 3702 [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { 3703 .name = "postpone", 3704 .help = "postpone update operation", 3705 .next = NEXT(next_qia_update_attr, 3706 NEXT_ENTRY(COMMON_BOOLEAN)), 3707 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3708 }, 3709 /* Indirect action update arguments. */ 3710 [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { 3711 .name = "postpone", 3712 .help = "postpone query operation", 3713 .next = NEXT(next_qia_query_attr, 3714 NEXT_ENTRY(COMMON_BOOLEAN)), 3715 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3716 }, 3717 /* Indirect action create arguments. */ 3718 [QUEUE_INDIRECT_ACTION_CREATE_ID] = { 3719 .name = "action_id", 3720 .help = "specify a indirect action id to create", 3721 .next = NEXT(next_qia_create_attr, 3722 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3723 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3724 }, 3725 [QUEUE_INDIRECT_ACTION_INGRESS] = { 3726 .name = "ingress", 3727 .help = "affect rule to ingress", 3728 .next = NEXT(next_qia_create_attr), 3729 .call = parse_qia, 3730 }, 3731 [QUEUE_INDIRECT_ACTION_EGRESS] = { 3732 .name = "egress", 3733 .help = "affect rule to egress", 3734 .next = NEXT(next_qia_create_attr), 3735 .call = parse_qia, 3736 }, 3737 [QUEUE_INDIRECT_ACTION_TRANSFER] = { 3738 .name = "transfer", 3739 .help = "affect rule to transfer", 3740 .next = NEXT(next_qia_create_attr), 3741 .call = parse_qia, 3742 }, 3743 [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { 3744 .name = "postpone", 3745 .help = "postpone create operation", 3746 .next = NEXT(next_qia_create_attr, 3747 NEXT_ENTRY(COMMON_BOOLEAN)), 3748 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3749 }, 3750 [QUEUE_INDIRECT_ACTION_SPEC] = { 3751 .name = "action", 3752 .help = "specify action to create indirect handle", 3753 .next = NEXT(next_action), 3754 }, 3755 [QUEUE_INDIRECT_ACTION_LIST] = { 3756 .name = "list", 3757 .help = "specify actions for indirect handle list", 3758 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 3759 .call = parse_qia, 3760 }, 3761 /* Top-level command. */ 3762 [PUSH] = { 3763 .name = "push", 3764 .help = "push enqueued operations", 3765 .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3766 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3767 .call = parse_push, 3768 }, 3769 /* Sub-level commands. */ 3770 [PUSH_QUEUE] = { 3771 .name = "queue", 3772 .help = "specify queue id", 3773 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3774 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3775 }, 3776 /* Top-level command. */ 3777 [PULL] = { 3778 .name = "pull", 3779 .help = "pull flow operations results", 3780 .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3781 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3782 .call = parse_pull, 3783 }, 3784 /* Sub-level commands. */ 3785 [PULL_QUEUE] = { 3786 .name = "queue", 3787 .help = "specify queue id", 3788 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3789 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3790 }, 3791 /* Top-level command. */ 3792 [HASH] = { 3793 .name = "hash", 3794 .help = "calculate hash for a given pattern in a given template table", 3795 .next = NEXT(NEXT_ENTRY(HASH_CALC_TABLE), NEXT_ENTRY(COMMON_PORT_ID)), 3796 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3797 .call = parse_hash, 3798 }, 3799 /* Sub-level commands. */ 3800 [HASH_CALC_TABLE] = { 3801 .name = "template_table", 3802 .help = "specify table id", 3803 .next = NEXT(NEXT_ENTRY(HASH_CALC_PATTERN_INDEX), 3804 NEXT_ENTRY(COMMON_TABLE_ID)), 3805 .args = ARGS(ARGS_ENTRY(struct buffer, 3806 args.vc.table_id)), 3807 .call = parse_hash, 3808 }, 3809 [HASH_CALC_PATTERN_INDEX] = { 3810 .name = "pattern_template", 3811 .help = "specify pattern template id", 3812 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3813 NEXT_ENTRY(COMMON_UNSIGNED)), 3814 .args = ARGS(ARGS_ENTRY(struct buffer, 3815 args.vc.pat_templ_id)), 3816 .call = parse_hash, 3817 }, 3818 /* Top-level command. */ 3819 [INDIRECT_ACTION] = { 3820 .name = "indirect_action", 3821 .type = "{command} {port_id} [{arg} [...]]", 3822 .help = "manage indirect actions", 3823 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3824 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3825 .call = parse_ia, 3826 }, 3827 /* Sub-level commands. */ 3828 [INDIRECT_ACTION_CREATE] = { 3829 .name = "create", 3830 .help = "create indirect action", 3831 .next = NEXT(next_ia_create_attr), 3832 .call = parse_ia, 3833 }, 3834 [INDIRECT_ACTION_UPDATE] = { 3835 .name = "update", 3836 .help = "update indirect action", 3837 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), 3838 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3839 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3840 .call = parse_ia, 3841 }, 3842 [INDIRECT_ACTION_DESTROY] = { 3843 .name = "destroy", 3844 .help = "destroy indirect action", 3845 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), 3846 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3847 .call = parse_ia_destroy, 3848 }, 3849 [INDIRECT_ACTION_QUERY] = { 3850 .name = "query", 3851 .help = "query indirect action", 3852 .next = NEXT(NEXT_ENTRY(END), 3853 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3854 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3855 .call = parse_ia, 3856 }, 3857 [INDIRECT_ACTION_QUERY_UPDATE] = { 3858 .name = "query_update", 3859 .help = "query [and|or] update", 3860 .next = NEXT(next_ia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3861 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3862 .call = parse_ia 3863 }, 3864 [INDIRECT_ACTION_QU_MODE] = { 3865 .name = "mode", 3866 .help = "query_update mode", 3867 .next = NEXT(next_ia_qu_attr, 3868 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 3869 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 3870 .call = parse_ia, 3871 }, 3872 [INDIRECT_ACTION_QU_MODE_NAME] = { 3873 .name = "mode_name", 3874 .help = "query-update mode name", 3875 .call = parse_qu_mode_name, 3876 .comp = comp_qu_mode_name, 3877 }, 3878 [VALIDATE] = { 3879 .name = "validate", 3880 .help = "check whether a flow rule can be created", 3881 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 3882 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3883 .call = parse_vc, 3884 }, 3885 [CREATE] = { 3886 .name = "create", 3887 .help = "create a flow rule", 3888 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 3889 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3890 .call = parse_vc, 3891 }, 3892 [DESTROY] = { 3893 .name = "destroy", 3894 .help = "destroy specific flow rules", 3895 .next = NEXT(next_destroy_attr, 3896 NEXT_ENTRY(COMMON_PORT_ID)), 3897 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3898 .call = parse_destroy, 3899 }, 3900 [FLUSH] = { 3901 .name = "flush", 3902 .help = "destroy all flow rules", 3903 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 3904 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3905 .call = parse_flush, 3906 }, 3907 [DUMP] = { 3908 .name = "dump", 3909 .help = "dump single/all flow rules to file", 3910 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3911 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3912 .call = parse_dump, 3913 }, 3914 [QUERY] = { 3915 .name = "query", 3916 .help = "query an existing flow rule", 3917 .next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION), 3918 NEXT_ENTRY(COMMON_RULE_ID), 3919 NEXT_ENTRY(COMMON_PORT_ID)), 3920 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), 3921 ARGS_ENTRY(struct buffer, args.query.rule), 3922 ARGS_ENTRY(struct buffer, port)), 3923 .call = parse_query, 3924 }, 3925 [LIST] = { 3926 .name = "list", 3927 .help = "list existing flow rules", 3928 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), 3929 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3930 .call = parse_list, 3931 }, 3932 [AGED] = { 3933 .name = "aged", 3934 .help = "list and destroy aged flows", 3935 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)), 3936 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3937 .call = parse_aged, 3938 }, 3939 [ISOLATE] = { 3940 .name = "isolate", 3941 .help = "restrict ingress traffic to the defined flow rules", 3942 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), 3943 NEXT_ENTRY(COMMON_PORT_ID)), 3944 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), 3945 ARGS_ENTRY(struct buffer, port)), 3946 .call = parse_isolate, 3947 }, 3948 [FLEX] = { 3949 .name = "flex_item", 3950 .help = "flex item API", 3951 .next = NEXT(next_flex_item), 3952 .call = parse_flex, 3953 }, 3954 [FLEX_ITEM_INIT] = { 3955 .name = "init", 3956 .help = "flex item init", 3957 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 3958 ARGS_ENTRY(struct buffer, port)), 3959 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 3960 NEXT_ENTRY(COMMON_PORT_ID)), 3961 .call = parse_flex 3962 }, 3963 [FLEX_ITEM_CREATE] = { 3964 .name = "create", 3965 .help = "flex item create", 3966 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), 3967 ARGS_ENTRY(struct buffer, args.flex.token), 3968 ARGS_ENTRY(struct buffer, port)), 3969 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), 3970 NEXT_ENTRY(COMMON_FLEX_TOKEN), 3971 NEXT_ENTRY(COMMON_PORT_ID)), 3972 .call = parse_flex 3973 }, 3974 [FLEX_ITEM_DESTROY] = { 3975 .name = "destroy", 3976 .help = "flex item destroy", 3977 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 3978 ARGS_ENTRY(struct buffer, port)), 3979 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 3980 NEXT_ENTRY(COMMON_PORT_ID)), 3981 .call = parse_flex 3982 }, 3983 [TUNNEL] = { 3984 .name = "tunnel", 3985 .help = "new tunnel API", 3986 .next = NEXT(NEXT_ENTRY 3987 (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), 3988 .call = parse_tunnel, 3989 }, 3990 /* Tunnel arguments. */ 3991 [TUNNEL_CREATE] = { 3992 .name = "create", 3993 .help = "create new tunnel object", 3994 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), 3995 NEXT_ENTRY(COMMON_PORT_ID)), 3996 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3997 .call = parse_tunnel, 3998 }, 3999 [TUNNEL_CREATE_TYPE] = { 4000 .name = "type", 4001 .help = "create new tunnel", 4002 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), 4003 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), 4004 .call = parse_tunnel, 4005 }, 4006 [TUNNEL_DESTROY] = { 4007 .name = "destroy", 4008 .help = "destroy tunnel", 4009 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), 4010 NEXT_ENTRY(COMMON_PORT_ID)), 4011 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4012 .call = parse_tunnel, 4013 }, 4014 [TUNNEL_DESTROY_ID] = { 4015 .name = "id", 4016 .help = "tunnel identifier to destroy", 4017 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), 4018 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4019 .call = parse_tunnel, 4020 }, 4021 [TUNNEL_LIST] = { 4022 .name = "list", 4023 .help = "list existing tunnels", 4024 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4025 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4026 .call = parse_tunnel, 4027 }, 4028 /* Destroy arguments. */ 4029 [DESTROY_RULE] = { 4030 .name = "rule", 4031 .help = "specify a rule identifier", 4032 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4033 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), 4034 .call = parse_destroy, 4035 }, 4036 [DESTROY_IS_USER_ID] = { 4037 .name = "user_id", 4038 .help = "rule identifier is user-id", 4039 .next = NEXT(next_destroy_attr), 4040 .call = parse_destroy, 4041 }, 4042 /* Dump arguments. */ 4043 [DUMP_ALL] = { 4044 .name = "all", 4045 .help = "dump all", 4046 .next = NEXT(next_dump_attr), 4047 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), 4048 .call = parse_dump, 4049 }, 4050 [DUMP_ONE] = { 4051 .name = "rule", 4052 .help = "dump one rule", 4053 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4054 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), 4055 ARGS_ENTRY(struct buffer, args.dump.rule)), 4056 .call = parse_dump, 4057 }, 4058 [DUMP_IS_USER_ID] = { 4059 .name = "user_id", 4060 .help = "rule identifier is user-id", 4061 .next = NEXT(next_dump_subcmd), 4062 .call = parse_dump, 4063 }, 4064 /* Query arguments. */ 4065 [QUERY_ACTION] = { 4066 .name = "{action}", 4067 .type = "ACTION", 4068 .help = "action to query, must be part of the rule", 4069 .call = parse_action, 4070 .comp = comp_action, 4071 }, 4072 [QUERY_IS_USER_ID] = { 4073 .name = "user_id", 4074 .help = "rule identifier is user-id", 4075 .next = NEXT(next_query_attr), 4076 .call = parse_query, 4077 }, 4078 /* List arguments. */ 4079 [LIST_GROUP] = { 4080 .name = "group", 4081 .help = "specify a group", 4082 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4083 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), 4084 .call = parse_list, 4085 }, 4086 [AGED_DESTROY] = { 4087 .name = "destroy", 4088 .help = "specify aged flows need be destroyed", 4089 .call = parse_aged, 4090 .comp = comp_none, 4091 }, 4092 /* Validate/create attributes. */ 4093 [VC_GROUP] = { 4094 .name = "group", 4095 .help = "specify a group", 4096 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4097 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), 4098 .call = parse_vc, 4099 }, 4100 [VC_PRIORITY] = { 4101 .name = "priority", 4102 .help = "specify a priority level", 4103 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 4104 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), 4105 .call = parse_vc, 4106 }, 4107 [VC_INGRESS] = { 4108 .name = "ingress", 4109 .help = "affect rule to ingress", 4110 .next = NEXT(next_vc_attr), 4111 .call = parse_vc, 4112 }, 4113 [VC_EGRESS] = { 4114 .name = "egress", 4115 .help = "affect rule to egress", 4116 .next = NEXT(next_vc_attr), 4117 .call = parse_vc, 4118 }, 4119 [VC_TRANSFER] = { 4120 .name = "transfer", 4121 .help = "apply rule directly to endpoints found in pattern", 4122 .next = NEXT(next_vc_attr), 4123 .call = parse_vc, 4124 }, 4125 [VC_TUNNEL_SET] = { 4126 .name = "tunnel_set", 4127 .help = "tunnel steer rule", 4128 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4129 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4130 .call = parse_vc, 4131 }, 4132 [VC_TUNNEL_MATCH] = { 4133 .name = "tunnel_match", 4134 .help = "tunnel match rule", 4135 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4136 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4137 .call = parse_vc, 4138 }, 4139 [VC_USER_ID] = { 4140 .name = "user_id", 4141 .help = "specify a user id to create", 4142 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4143 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)), 4144 .call = parse_vc, 4145 }, 4146 /* Validate/create pattern. */ 4147 [ITEM_PATTERN] = { 4148 .name = "pattern", 4149 .help = "submit a list of pattern items", 4150 .next = NEXT(next_item), 4151 .call = parse_vc, 4152 }, 4153 [ITEM_PARAM_IS] = { 4154 .name = "is", 4155 .help = "match value perfectly (with full bit-mask)", 4156 .call = parse_vc_spec, 4157 }, 4158 [ITEM_PARAM_SPEC] = { 4159 .name = "spec", 4160 .help = "match value according to configured bit-mask", 4161 .call = parse_vc_spec, 4162 }, 4163 [ITEM_PARAM_LAST] = { 4164 .name = "last", 4165 .help = "specify upper bound to establish a range", 4166 .call = parse_vc_spec, 4167 }, 4168 [ITEM_PARAM_MASK] = { 4169 .name = "mask", 4170 .help = "specify bit-mask with relevant bits set to one", 4171 .call = parse_vc_spec, 4172 }, 4173 [ITEM_PARAM_PREFIX] = { 4174 .name = "prefix", 4175 .help = "generate bit-mask from a prefix length", 4176 .call = parse_vc_spec, 4177 }, 4178 [ITEM_NEXT] = { 4179 .name = "/", 4180 .help = "specify next pattern item", 4181 .next = NEXT(next_item), 4182 }, 4183 [ITEM_END] = { 4184 .name = "end", 4185 .help = "end list of pattern items", 4186 .priv = PRIV_ITEM(END, 0), 4187 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 4188 .call = parse_vc, 4189 }, 4190 [ITEM_VOID] = { 4191 .name = "void", 4192 .help = "no-op pattern item", 4193 .priv = PRIV_ITEM(VOID, 0), 4194 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4195 .call = parse_vc, 4196 }, 4197 [ITEM_INVERT] = { 4198 .name = "invert", 4199 .help = "perform actions when pattern does not match", 4200 .priv = PRIV_ITEM(INVERT, 0), 4201 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4202 .call = parse_vc, 4203 }, 4204 [ITEM_ANY] = { 4205 .name = "any", 4206 .help = "match any protocol for the current layer", 4207 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), 4208 .next = NEXT(item_any), 4209 .call = parse_vc, 4210 }, 4211 [ITEM_ANY_NUM] = { 4212 .name = "num", 4213 .help = "number of layers covered", 4214 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4215 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), 4216 }, 4217 [ITEM_PORT_ID] = { 4218 .name = "port_id", 4219 .help = "match traffic from/to a given DPDK port ID", 4220 .priv = PRIV_ITEM(PORT_ID, 4221 sizeof(struct rte_flow_item_port_id)), 4222 .next = NEXT(item_port_id), 4223 .call = parse_vc, 4224 }, 4225 [ITEM_PORT_ID_ID] = { 4226 .name = "id", 4227 .help = "DPDK port ID", 4228 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), 4229 item_param), 4230 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), 4231 }, 4232 [ITEM_MARK] = { 4233 .name = "mark", 4234 .help = "match traffic against value set in previously matched rule", 4235 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), 4236 .next = NEXT(item_mark), 4237 .call = parse_vc, 4238 }, 4239 [ITEM_MARK_ID] = { 4240 .name = "id", 4241 .help = "Integer value to match against", 4242 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), 4243 item_param), 4244 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), 4245 }, 4246 [ITEM_RAW] = { 4247 .name = "raw", 4248 .help = "match an arbitrary byte string", 4249 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), 4250 .next = NEXT(item_raw), 4251 .call = parse_vc, 4252 }, 4253 [ITEM_RAW_RELATIVE] = { 4254 .name = "relative", 4255 .help = "look for pattern after the previous item", 4256 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4257 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4258 relative, 1)), 4259 }, 4260 [ITEM_RAW_SEARCH] = { 4261 .name = "search", 4262 .help = "search pattern from offset (see also limit)", 4263 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4264 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4265 search, 1)), 4266 }, 4267 [ITEM_RAW_OFFSET] = { 4268 .name = "offset", 4269 .help = "absolute or relative offset for pattern", 4270 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), 4271 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), 4272 }, 4273 [ITEM_RAW_LIMIT] = { 4274 .name = "limit", 4275 .help = "search area limit for start of pattern", 4276 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4277 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), 4278 }, 4279 [ITEM_RAW_PATTERN] = { 4280 .name = "pattern", 4281 .help = "byte string to look for", 4282 .next = NEXT(item_raw, 4283 NEXT_ENTRY(COMMON_STRING), 4284 NEXT_ENTRY(ITEM_PARAM_IS, 4285 ITEM_PARAM_SPEC, 4286 ITEM_PARAM_MASK)), 4287 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4288 ARGS_ENTRY(struct rte_flow_item_raw, length), 4289 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4290 ITEM_RAW_PATTERN_SIZE)), 4291 }, 4292 [ITEM_RAW_PATTERN_HEX] = { 4293 .name = "pattern_hex", 4294 .help = "hex string to look for", 4295 .next = NEXT(item_raw, 4296 NEXT_ENTRY(COMMON_HEX), 4297 NEXT_ENTRY(ITEM_PARAM_IS, 4298 ITEM_PARAM_SPEC, 4299 ITEM_PARAM_MASK)), 4300 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4301 ARGS_ENTRY(struct rte_flow_item_raw, length), 4302 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4303 ITEM_RAW_PATTERN_SIZE)), 4304 }, 4305 [ITEM_ETH] = { 4306 .name = "eth", 4307 .help = "match Ethernet header", 4308 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), 4309 .next = NEXT(item_eth), 4310 .call = parse_vc, 4311 }, 4312 [ITEM_ETH_DST] = { 4313 .name = "dst", 4314 .help = "destination MAC", 4315 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4316 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), 4317 }, 4318 [ITEM_ETH_SRC] = { 4319 .name = "src", 4320 .help = "source MAC", 4321 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4322 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), 4323 }, 4324 [ITEM_ETH_TYPE] = { 4325 .name = "type", 4326 .help = "EtherType", 4327 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4328 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), 4329 }, 4330 [ITEM_ETH_HAS_VLAN] = { 4331 .name = "has_vlan", 4332 .help = "packet header contains VLAN", 4333 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4334 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, 4335 has_vlan, 1)), 4336 }, 4337 [ITEM_VLAN] = { 4338 .name = "vlan", 4339 .help = "match 802.1Q/ad VLAN tag", 4340 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), 4341 .next = NEXT(item_vlan), 4342 .call = parse_vc, 4343 }, 4344 [ITEM_VLAN_TCI] = { 4345 .name = "tci", 4346 .help = "tag control information", 4347 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4348 item_param), 4349 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, hdr.vlan_tci)), 4350 }, 4351 [ITEM_VLAN_PCP] = { 4352 .name = "pcp", 4353 .help = "priority code point", 4354 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4355 item_param), 4356 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4357 hdr.vlan_tci, "\xe0\x00")), 4358 }, 4359 [ITEM_VLAN_DEI] = { 4360 .name = "dei", 4361 .help = "drop eligible indicator", 4362 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4363 item_param), 4364 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4365 hdr.vlan_tci, "\x10\x00")), 4366 }, 4367 [ITEM_VLAN_VID] = { 4368 .name = "vid", 4369 .help = "VLAN identifier", 4370 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4371 item_param), 4372 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4373 hdr.vlan_tci, "\x0f\xff")), 4374 }, 4375 [ITEM_VLAN_INNER_TYPE] = { 4376 .name = "inner_type", 4377 .help = "inner EtherType", 4378 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4379 item_param), 4380 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, 4381 hdr.eth_proto)), 4382 }, 4383 [ITEM_VLAN_HAS_MORE_VLAN] = { 4384 .name = "has_more_vlan", 4385 .help = "packet header contains another VLAN", 4386 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4387 item_param), 4388 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, 4389 has_more_vlan, 1)), 4390 }, 4391 [ITEM_IPV4] = { 4392 .name = "ipv4", 4393 .help = "match IPv4 header", 4394 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), 4395 .next = NEXT(item_ipv4), 4396 .call = parse_vc, 4397 }, 4398 [ITEM_IPV4_VER_IHL] = { 4399 .name = "version_ihl", 4400 .help = "match header length", 4401 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4402 item_param), 4403 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, 4404 hdr.version_ihl)), 4405 }, 4406 [ITEM_IPV4_TOS] = { 4407 .name = "tos", 4408 .help = "type of service", 4409 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4410 item_param), 4411 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4412 hdr.type_of_service)), 4413 }, 4414 [ITEM_IPV4_LENGTH] = { 4415 .name = "length", 4416 .help = "total length", 4417 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4418 item_param), 4419 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4420 hdr.total_length)), 4421 }, 4422 [ITEM_IPV4_ID] = { 4423 .name = "packet_id", 4424 .help = "fragment packet id", 4425 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4426 item_param), 4427 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4428 hdr.packet_id)), 4429 }, 4430 [ITEM_IPV4_FRAGMENT_OFFSET] = { 4431 .name = "fragment_offset", 4432 .help = "fragmentation flags and fragment offset", 4433 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4434 item_param), 4435 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4436 hdr.fragment_offset)), 4437 }, 4438 [ITEM_IPV4_TTL] = { 4439 .name = "ttl", 4440 .help = "time to live", 4441 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4442 item_param), 4443 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4444 hdr.time_to_live)), 4445 }, 4446 [ITEM_IPV4_PROTO] = { 4447 .name = "proto", 4448 .help = "next protocol ID", 4449 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4450 item_param), 4451 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4452 hdr.next_proto_id)), 4453 }, 4454 [ITEM_IPV4_SRC] = { 4455 .name = "src", 4456 .help = "source address", 4457 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4458 item_param), 4459 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4460 hdr.src_addr)), 4461 }, 4462 [ITEM_IPV4_DST] = { 4463 .name = "dst", 4464 .help = "destination address", 4465 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4466 item_param), 4467 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4468 hdr.dst_addr)), 4469 }, 4470 [ITEM_IPV6] = { 4471 .name = "ipv6", 4472 .help = "match IPv6 header", 4473 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), 4474 .next = NEXT(item_ipv6), 4475 .call = parse_vc, 4476 }, 4477 [ITEM_IPV6_TC] = { 4478 .name = "tc", 4479 .help = "traffic class", 4480 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4481 item_param), 4482 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4483 hdr.vtc_flow, 4484 "\x0f\xf0\x00\x00")), 4485 }, 4486 [ITEM_IPV6_FLOW] = { 4487 .name = "flow", 4488 .help = "flow label", 4489 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4490 item_param), 4491 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4492 hdr.vtc_flow, 4493 "\x00\x0f\xff\xff")), 4494 }, 4495 [ITEM_IPV6_LEN] = { 4496 .name = "length", 4497 .help = "payload length", 4498 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4499 item_param), 4500 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4501 hdr.payload_len)), 4502 }, 4503 [ITEM_IPV6_PROTO] = { 4504 .name = "proto", 4505 .help = "protocol (next header)", 4506 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4507 item_param), 4508 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4509 hdr.proto)), 4510 }, 4511 [ITEM_IPV6_HOP] = { 4512 .name = "hop", 4513 .help = "hop limit", 4514 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4515 item_param), 4516 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4517 hdr.hop_limits)), 4518 }, 4519 [ITEM_IPV6_SRC] = { 4520 .name = "src", 4521 .help = "source address", 4522 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4523 item_param), 4524 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4525 hdr.src_addr)), 4526 }, 4527 [ITEM_IPV6_DST] = { 4528 .name = "dst", 4529 .help = "destination address", 4530 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4531 item_param), 4532 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4533 hdr.dst_addr)), 4534 }, 4535 [ITEM_IPV6_HAS_FRAG_EXT] = { 4536 .name = "has_frag_ext", 4537 .help = "fragment packet attribute", 4538 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4539 item_param), 4540 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, 4541 has_frag_ext, 1)), 4542 }, 4543 [ITEM_IPV6_ROUTING_EXT] = { 4544 .name = "ipv6_routing_ext", 4545 .help = "match IPv6 routing extension header", 4546 .priv = PRIV_ITEM(IPV6_ROUTING_EXT, 4547 sizeof(struct rte_flow_item_ipv6_routing_ext)), 4548 .next = NEXT(item_ipv6_routing_ext), 4549 .call = parse_vc, 4550 }, 4551 [ITEM_IPV6_ROUTING_EXT_TYPE] = { 4552 .name = "ext_type", 4553 .help = "match IPv6 routing extension header type", 4554 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4555 item_param), 4556 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4557 hdr.type)), 4558 }, 4559 [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = { 4560 .name = "ext_next_hdr", 4561 .help = "match IPv6 routing extension header next header type", 4562 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4563 item_param), 4564 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4565 hdr.next_hdr)), 4566 }, 4567 [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = { 4568 .name = "ext_seg_left", 4569 .help = "match IPv6 routing extension header segment left", 4570 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4571 item_param), 4572 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4573 hdr.segments_left)), 4574 }, 4575 [ITEM_ICMP] = { 4576 .name = "icmp", 4577 .help = "match ICMP header", 4578 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), 4579 .next = NEXT(item_icmp), 4580 .call = parse_vc, 4581 }, 4582 [ITEM_ICMP_TYPE] = { 4583 .name = "type", 4584 .help = "ICMP packet type", 4585 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4586 item_param), 4587 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4588 hdr.icmp_type)), 4589 }, 4590 [ITEM_ICMP_CODE] = { 4591 .name = "code", 4592 .help = "ICMP packet code", 4593 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4594 item_param), 4595 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4596 hdr.icmp_code)), 4597 }, 4598 [ITEM_ICMP_IDENT] = { 4599 .name = "ident", 4600 .help = "ICMP packet identifier", 4601 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4602 item_param), 4603 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4604 hdr.icmp_ident)), 4605 }, 4606 [ITEM_ICMP_SEQ] = { 4607 .name = "seq", 4608 .help = "ICMP packet sequence number", 4609 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4610 item_param), 4611 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4612 hdr.icmp_seq_nb)), 4613 }, 4614 [ITEM_UDP] = { 4615 .name = "udp", 4616 .help = "match UDP header", 4617 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), 4618 .next = NEXT(item_udp), 4619 .call = parse_vc, 4620 }, 4621 [ITEM_UDP_SRC] = { 4622 .name = "src", 4623 .help = "UDP source port", 4624 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), 4625 item_param), 4626 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4627 hdr.src_port)), 4628 }, 4629 [ITEM_UDP_DST] = { 4630 .name = "dst", 4631 .help = "UDP destination port", 4632 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4633 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4634 hdr.dst_port)), 4635 }, 4636 [ITEM_TCP] = { 4637 .name = "tcp", 4638 .help = "match TCP header", 4639 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), 4640 .next = NEXT(item_tcp), 4641 .call = parse_vc, 4642 }, 4643 [ITEM_TCP_SRC] = { 4644 .name = "src", 4645 .help = "TCP source port", 4646 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4647 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4648 hdr.src_port)), 4649 }, 4650 [ITEM_TCP_DST] = { 4651 .name = "dst", 4652 .help = "TCP destination port", 4653 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4654 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4655 hdr.dst_port)), 4656 }, 4657 [ITEM_TCP_FLAGS] = { 4658 .name = "flags", 4659 .help = "TCP flags", 4660 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4661 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4662 hdr.tcp_flags)), 4663 }, 4664 [ITEM_SCTP] = { 4665 .name = "sctp", 4666 .help = "match SCTP header", 4667 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), 4668 .next = NEXT(item_sctp), 4669 .call = parse_vc, 4670 }, 4671 [ITEM_SCTP_SRC] = { 4672 .name = "src", 4673 .help = "SCTP source port", 4674 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4675 item_param), 4676 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4677 hdr.src_port)), 4678 }, 4679 [ITEM_SCTP_DST] = { 4680 .name = "dst", 4681 .help = "SCTP destination port", 4682 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4683 item_param), 4684 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4685 hdr.dst_port)), 4686 }, 4687 [ITEM_SCTP_TAG] = { 4688 .name = "tag", 4689 .help = "validation tag", 4690 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4691 item_param), 4692 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4693 hdr.tag)), 4694 }, 4695 [ITEM_SCTP_CKSUM] = { 4696 .name = "cksum", 4697 .help = "checksum", 4698 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4699 item_param), 4700 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4701 hdr.cksum)), 4702 }, 4703 [ITEM_VXLAN] = { 4704 .name = "vxlan", 4705 .help = "match VXLAN header", 4706 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), 4707 .next = NEXT(item_vxlan), 4708 .call = parse_vc, 4709 }, 4710 [ITEM_VXLAN_VNI] = { 4711 .name = "vni", 4712 .help = "VXLAN identifier", 4713 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4714 item_param), 4715 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), 4716 }, 4717 [ITEM_VXLAN_LAST_RSVD] = { 4718 .name = "last_rsvd", 4719 .help = "VXLAN last reserved bits", 4720 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4721 item_param), 4722 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 4723 hdr.rsvd1)), 4724 }, 4725 [ITEM_E_TAG] = { 4726 .name = "e_tag", 4727 .help = "match E-Tag header", 4728 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), 4729 .next = NEXT(item_e_tag), 4730 .call = parse_vc, 4731 }, 4732 [ITEM_E_TAG_GRP_ECID_B] = { 4733 .name = "grp_ecid_b", 4734 .help = "GRP and E-CID base", 4735 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), 4736 item_param), 4737 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, 4738 rsvd_grp_ecid_b, 4739 "\x3f\xff")), 4740 }, 4741 [ITEM_NVGRE] = { 4742 .name = "nvgre", 4743 .help = "match NVGRE header", 4744 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), 4745 .next = NEXT(item_nvgre), 4746 .call = parse_vc, 4747 }, 4748 [ITEM_NVGRE_TNI] = { 4749 .name = "tni", 4750 .help = "virtual subnet ID", 4751 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), 4752 item_param), 4753 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), 4754 }, 4755 [ITEM_MPLS] = { 4756 .name = "mpls", 4757 .help = "match MPLS header", 4758 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), 4759 .next = NEXT(item_mpls), 4760 .call = parse_vc, 4761 }, 4762 [ITEM_MPLS_LABEL] = { 4763 .name = "label", 4764 .help = "MPLS label", 4765 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4766 item_param), 4767 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4768 label_tc_s, 4769 "\xff\xff\xf0")), 4770 }, 4771 [ITEM_MPLS_TC] = { 4772 .name = "tc", 4773 .help = "MPLS Traffic Class", 4774 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4775 item_param), 4776 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4777 label_tc_s, 4778 "\x00\x00\x0e")), 4779 }, 4780 [ITEM_MPLS_S] = { 4781 .name = "s", 4782 .help = "MPLS Bottom-of-Stack", 4783 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4784 item_param), 4785 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4786 label_tc_s, 4787 "\x00\x00\x01")), 4788 }, 4789 [ITEM_MPLS_TTL] = { 4790 .name = "ttl", 4791 .help = "MPLS Time-to-Live", 4792 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4793 item_param), 4794 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls, ttl)), 4795 }, 4796 [ITEM_GRE] = { 4797 .name = "gre", 4798 .help = "match GRE header", 4799 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), 4800 .next = NEXT(item_gre), 4801 .call = parse_vc, 4802 }, 4803 [ITEM_GRE_PROTO] = { 4804 .name = "protocol", 4805 .help = "GRE protocol type", 4806 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 4807 item_param), 4808 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 4809 protocol)), 4810 }, 4811 [ITEM_GRE_C_RSVD0_VER] = { 4812 .name = "c_rsvd0_ver", 4813 .help = 4814 "checksum (1b), undefined (1b), key bit (1b)," 4815 " sequence number (1b), reserved 0 (9b)," 4816 " version (3b)", 4817 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 4818 item_param), 4819 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 4820 c_rsvd0_ver)), 4821 }, 4822 [ITEM_GRE_C_BIT] = { 4823 .name = "c_bit", 4824 .help = "checksum bit (C)", 4825 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), 4826 item_param), 4827 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 4828 c_rsvd0_ver, 4829 "\x80\x00\x00\x00")), 4830 }, 4831 [ITEM_GRE_S_BIT] = { 4832 .name = "s_bit", 4833 .help = "sequence number bit (S)", 4834 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4835 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 4836 c_rsvd0_ver, 4837 "\x10\x00\x00\x00")), 4838 }, 4839 [ITEM_GRE_K_BIT] = { 4840 .name = "k_bit", 4841 .help = "key bit (K)", 4842 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4843 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 4844 c_rsvd0_ver, 4845 "\x20\x00\x00\x00")), 4846 }, 4847 [ITEM_FUZZY] = { 4848 .name = "fuzzy", 4849 .help = "fuzzy pattern match, expect faster than default", 4850 .priv = PRIV_ITEM(FUZZY, 4851 sizeof(struct rte_flow_item_fuzzy)), 4852 .next = NEXT(item_fuzzy), 4853 .call = parse_vc, 4854 }, 4855 [ITEM_FUZZY_THRESH] = { 4856 .name = "thresh", 4857 .help = "match accuracy threshold", 4858 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), 4859 item_param), 4860 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, 4861 thresh)), 4862 }, 4863 [ITEM_GTP] = { 4864 .name = "gtp", 4865 .help = "match GTP header", 4866 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), 4867 .next = NEXT(item_gtp), 4868 .call = parse_vc, 4869 }, 4870 [ITEM_GTP_FLAGS] = { 4871 .name = "v_pt_rsv_flags", 4872 .help = "GTP flags", 4873 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4874 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, 4875 hdr.gtp_hdr_info)), 4876 }, 4877 [ITEM_GTP_MSG_TYPE] = { 4878 .name = "msg_type", 4879 .help = "GTP message type", 4880 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4881 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), 4882 }, 4883 [ITEM_GTP_TEID] = { 4884 .name = "teid", 4885 .help = "tunnel endpoint identifier", 4886 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4887 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), 4888 }, 4889 [ITEM_GTPC] = { 4890 .name = "gtpc", 4891 .help = "match GTP header", 4892 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), 4893 .next = NEXT(item_gtp), 4894 .call = parse_vc, 4895 }, 4896 [ITEM_GTPU] = { 4897 .name = "gtpu", 4898 .help = "match GTP header", 4899 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), 4900 .next = NEXT(item_gtp), 4901 .call = parse_vc, 4902 }, 4903 [ITEM_GENEVE] = { 4904 .name = "geneve", 4905 .help = "match GENEVE header", 4906 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), 4907 .next = NEXT(item_geneve), 4908 .call = parse_vc, 4909 }, 4910 [ITEM_GENEVE_VNI] = { 4911 .name = "vni", 4912 .help = "virtual network identifier", 4913 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 4914 item_param), 4915 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), 4916 }, 4917 [ITEM_GENEVE_PROTO] = { 4918 .name = "protocol", 4919 .help = "GENEVE protocol type", 4920 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 4921 item_param), 4922 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, 4923 protocol)), 4924 }, 4925 [ITEM_GENEVE_OPTLEN] = { 4926 .name = "optlen", 4927 .help = "GENEVE options length in dwords", 4928 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 4929 item_param), 4930 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, 4931 ver_opt_len_o_c_rsvd0, 4932 "\x3f\x00")), 4933 }, 4934 [ITEM_VXLAN_GPE] = { 4935 .name = "vxlan-gpe", 4936 .help = "match VXLAN-GPE header", 4937 .priv = PRIV_ITEM(VXLAN_GPE, 4938 sizeof(struct rte_flow_item_vxlan_gpe)), 4939 .next = NEXT(item_vxlan_gpe), 4940 .call = parse_vc, 4941 }, 4942 [ITEM_VXLAN_GPE_VNI] = { 4943 .name = "vni", 4944 .help = "VXLAN-GPE identifier", 4945 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 4946 item_param), 4947 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 4948 hdr.vni)), 4949 }, 4950 [ITEM_VXLAN_GPE_PROTO] = { 4951 .name = "protocol", 4952 .help = "VXLAN-GPE next protocol", 4953 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 4954 item_param), 4955 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 4956 protocol)), 4957 }, 4958 [ITEM_ARP_ETH_IPV4] = { 4959 .name = "arp_eth_ipv4", 4960 .help = "match ARP header for Ethernet/IPv4", 4961 .priv = PRIV_ITEM(ARP_ETH_IPV4, 4962 sizeof(struct rte_flow_item_arp_eth_ipv4)), 4963 .next = NEXT(item_arp_eth_ipv4), 4964 .call = parse_vc, 4965 }, 4966 [ITEM_ARP_ETH_IPV4_SHA] = { 4967 .name = "sha", 4968 .help = "sender hardware address", 4969 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 4970 item_param), 4971 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 4972 hdr.arp_data.arp_sha)), 4973 }, 4974 [ITEM_ARP_ETH_IPV4_SPA] = { 4975 .name = "spa", 4976 .help = "sender IPv4 address", 4977 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4978 item_param), 4979 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 4980 hdr.arp_data.arp_sip)), 4981 }, 4982 [ITEM_ARP_ETH_IPV4_THA] = { 4983 .name = "tha", 4984 .help = "target hardware address", 4985 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 4986 item_param), 4987 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 4988 hdr.arp_data.arp_tha)), 4989 }, 4990 [ITEM_ARP_ETH_IPV4_TPA] = { 4991 .name = "tpa", 4992 .help = "target IPv4 address", 4993 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4994 item_param), 4995 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 4996 hdr.arp_data.arp_tip)), 4997 }, 4998 [ITEM_IPV6_EXT] = { 4999 .name = "ipv6_ext", 5000 .help = "match presence of any IPv6 extension header", 5001 .priv = PRIV_ITEM(IPV6_EXT, 5002 sizeof(struct rte_flow_item_ipv6_ext)), 5003 .next = NEXT(item_ipv6_ext), 5004 .call = parse_vc, 5005 }, 5006 [ITEM_IPV6_EXT_NEXT_HDR] = { 5007 .name = "next_hdr", 5008 .help = "next header", 5009 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5010 item_param), 5011 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 5012 next_hdr)), 5013 }, 5014 [ITEM_IPV6_FRAG_EXT] = { 5015 .name = "ipv6_frag_ext", 5016 .help = "match presence of IPv6 fragment extension header", 5017 .priv = PRIV_ITEM(IPV6_FRAG_EXT, 5018 sizeof(struct rte_flow_item_ipv6_frag_ext)), 5019 .next = NEXT(item_ipv6_frag_ext), 5020 .call = parse_vc, 5021 }, 5022 [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { 5023 .name = "next_hdr", 5024 .help = "next header", 5025 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5026 item_param), 5027 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, 5028 hdr.next_header)), 5029 }, 5030 [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { 5031 .name = "frag_data", 5032 .help = "fragment flags and offset", 5033 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5034 item_param), 5035 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5036 hdr.frag_data)), 5037 }, 5038 [ITEM_IPV6_FRAG_EXT_ID] = { 5039 .name = "packet_id", 5040 .help = "fragment packet id", 5041 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5042 item_param), 5043 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5044 hdr.id)), 5045 }, 5046 [ITEM_ICMP6] = { 5047 .name = "icmp6", 5048 .help = "match any ICMPv6 header", 5049 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), 5050 .next = NEXT(item_icmp6), 5051 .call = parse_vc, 5052 }, 5053 [ITEM_ICMP6_TYPE] = { 5054 .name = "type", 5055 .help = "ICMPv6 type", 5056 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5057 item_param), 5058 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5059 type)), 5060 }, 5061 [ITEM_ICMP6_CODE] = { 5062 .name = "code", 5063 .help = "ICMPv6 code", 5064 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5065 item_param), 5066 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5067 code)), 5068 }, 5069 [ITEM_ICMP6_ECHO_REQUEST] = { 5070 .name = "icmp6_echo_request", 5071 .help = "match ICMPv6 echo request", 5072 .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, 5073 sizeof(struct rte_flow_item_icmp6_echo)), 5074 .next = NEXT(item_icmp6_echo_request), 5075 .call = parse_vc, 5076 }, 5077 [ITEM_ICMP6_ECHO_REQUEST_ID] = { 5078 .name = "ident", 5079 .help = "ICMPv6 echo request identifier", 5080 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5081 item_param), 5082 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5083 hdr.identifier)), 5084 }, 5085 [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { 5086 .name = "seq", 5087 .help = "ICMPv6 echo request sequence", 5088 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5089 item_param), 5090 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5091 hdr.sequence)), 5092 }, 5093 [ITEM_ICMP6_ECHO_REPLY] = { 5094 .name = "icmp6_echo_reply", 5095 .help = "match ICMPv6 echo reply", 5096 .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, 5097 sizeof(struct rte_flow_item_icmp6_echo)), 5098 .next = NEXT(item_icmp6_echo_reply), 5099 .call = parse_vc, 5100 }, 5101 [ITEM_ICMP6_ECHO_REPLY_ID] = { 5102 .name = "ident", 5103 .help = "ICMPv6 echo reply identifier", 5104 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5105 item_param), 5106 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5107 hdr.identifier)), 5108 }, 5109 [ITEM_ICMP6_ECHO_REPLY_SEQ] = { 5110 .name = "seq", 5111 .help = "ICMPv6 echo reply sequence", 5112 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5113 item_param), 5114 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5115 hdr.sequence)), 5116 }, 5117 [ITEM_ICMP6_ND_NS] = { 5118 .name = "icmp6_nd_ns", 5119 .help = "match ICMPv6 neighbor discovery solicitation", 5120 .priv = PRIV_ITEM(ICMP6_ND_NS, 5121 sizeof(struct rte_flow_item_icmp6_nd_ns)), 5122 .next = NEXT(item_icmp6_nd_ns), 5123 .call = parse_vc, 5124 }, 5125 [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { 5126 .name = "target_addr", 5127 .help = "target address", 5128 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), 5129 item_param), 5130 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, 5131 target_addr)), 5132 }, 5133 [ITEM_ICMP6_ND_NA] = { 5134 .name = "icmp6_nd_na", 5135 .help = "match ICMPv6 neighbor discovery advertisement", 5136 .priv = PRIV_ITEM(ICMP6_ND_NA, 5137 sizeof(struct rte_flow_item_icmp6_nd_na)), 5138 .next = NEXT(item_icmp6_nd_na), 5139 .call = parse_vc, 5140 }, 5141 [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { 5142 .name = "target_addr", 5143 .help = "target address", 5144 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), 5145 item_param), 5146 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, 5147 target_addr)), 5148 }, 5149 [ITEM_ICMP6_ND_OPT] = { 5150 .name = "icmp6_nd_opt", 5151 .help = "match presence of any ICMPv6 neighbor discovery" 5152 " option", 5153 .priv = PRIV_ITEM(ICMP6_ND_OPT, 5154 sizeof(struct rte_flow_item_icmp6_nd_opt)), 5155 .next = NEXT(item_icmp6_nd_opt), 5156 .call = parse_vc, 5157 }, 5158 [ITEM_ICMP6_ND_OPT_TYPE] = { 5159 .name = "type", 5160 .help = "ND option type", 5161 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5162 item_param), 5163 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, 5164 type)), 5165 }, 5166 [ITEM_ICMP6_ND_OPT_SLA_ETH] = { 5167 .name = "icmp6_nd_opt_sla_eth", 5168 .help = "match ICMPv6 neighbor discovery source Ethernet" 5169 " link-layer address option", 5170 .priv = PRIV_ITEM 5171 (ICMP6_ND_OPT_SLA_ETH, 5172 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), 5173 .next = NEXT(item_icmp6_nd_opt_sla_eth), 5174 .call = parse_vc, 5175 }, 5176 [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { 5177 .name = "sla", 5178 .help = "source Ethernet LLA", 5179 .next = NEXT(item_icmp6_nd_opt_sla_eth, 5180 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5181 .args = ARGS(ARGS_ENTRY_HTON 5182 (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), 5183 }, 5184 [ITEM_ICMP6_ND_OPT_TLA_ETH] = { 5185 .name = "icmp6_nd_opt_tla_eth", 5186 .help = "match ICMPv6 neighbor discovery target Ethernet" 5187 " link-layer address option", 5188 .priv = PRIV_ITEM 5189 (ICMP6_ND_OPT_TLA_ETH, 5190 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), 5191 .next = NEXT(item_icmp6_nd_opt_tla_eth), 5192 .call = parse_vc, 5193 }, 5194 [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { 5195 .name = "tla", 5196 .help = "target Ethernet LLA", 5197 .next = NEXT(item_icmp6_nd_opt_tla_eth, 5198 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5199 .args = ARGS(ARGS_ENTRY_HTON 5200 (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), 5201 }, 5202 [ITEM_META] = { 5203 .name = "meta", 5204 .help = "match metadata header", 5205 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), 5206 .next = NEXT(item_meta), 5207 .call = parse_vc, 5208 }, 5209 [ITEM_META_DATA] = { 5210 .name = "data", 5211 .help = "metadata value", 5212 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), 5213 item_param), 5214 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, 5215 data, "\xff\xff\xff\xff")), 5216 }, 5217 [ITEM_RANDOM] = { 5218 .name = "random", 5219 .help = "match random value", 5220 .priv = PRIV_ITEM(RANDOM, sizeof(struct rte_flow_item_random)), 5221 .next = NEXT(item_random), 5222 .call = parse_vc, 5223 }, 5224 [ITEM_RANDOM_VALUE] = { 5225 .name = "value", 5226 .help = "random value", 5227 .next = NEXT(item_random, NEXT_ENTRY(COMMON_UNSIGNED), 5228 item_param), 5229 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_random, 5230 value, "\xff\xff")), 5231 }, 5232 [ITEM_GRE_KEY] = { 5233 .name = "gre_key", 5234 .help = "match GRE key", 5235 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), 5236 .next = NEXT(item_gre_key), 5237 .call = parse_vc, 5238 }, 5239 [ITEM_GRE_KEY_VALUE] = { 5240 .name = "value", 5241 .help = "key value", 5242 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), 5243 item_param), 5244 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5245 }, 5246 [ITEM_GRE_OPTION] = { 5247 .name = "gre_option", 5248 .help = "match GRE optional fields", 5249 .priv = PRIV_ITEM(GRE_OPTION, 5250 sizeof(struct rte_flow_item_gre_opt)), 5251 .next = NEXT(item_gre_option), 5252 .call = parse_vc, 5253 }, 5254 [ITEM_GRE_OPTION_CHECKSUM] = { 5255 .name = "checksum", 5256 .help = "match GRE checksum", 5257 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5258 item_param), 5259 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5260 checksum_rsvd.checksum)), 5261 }, 5262 [ITEM_GRE_OPTION_KEY] = { 5263 .name = "key", 5264 .help = "match GRE key", 5265 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5266 item_param), 5267 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5268 key.key)), 5269 }, 5270 [ITEM_GRE_OPTION_SEQUENCE] = { 5271 .name = "sequence", 5272 .help = "match GRE sequence", 5273 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5274 item_param), 5275 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5276 sequence.sequence)), 5277 }, 5278 [ITEM_GTP_PSC] = { 5279 .name = "gtp_psc", 5280 .help = "match GTP extension header with type 0x85", 5281 .priv = PRIV_ITEM(GTP_PSC, 5282 sizeof(struct rte_flow_item_gtp_psc)), 5283 .next = NEXT(item_gtp_psc), 5284 .call = parse_vc, 5285 }, 5286 [ITEM_GTP_PSC_QFI] = { 5287 .name = "qfi", 5288 .help = "QoS flow identifier", 5289 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5290 item_param), 5291 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5292 hdr.qfi, 6)), 5293 }, 5294 [ITEM_GTP_PSC_PDU_T] = { 5295 .name = "pdu_t", 5296 .help = "PDU type", 5297 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5298 item_param), 5299 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5300 hdr.type, 4)), 5301 }, 5302 [ITEM_PPPOES] = { 5303 .name = "pppoes", 5304 .help = "match PPPoE session header", 5305 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), 5306 .next = NEXT(item_pppoes), 5307 .call = parse_vc, 5308 }, 5309 [ITEM_PPPOED] = { 5310 .name = "pppoed", 5311 .help = "match PPPoE discovery header", 5312 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), 5313 .next = NEXT(item_pppoed), 5314 .call = parse_vc, 5315 }, 5316 [ITEM_PPPOE_SEID] = { 5317 .name = "seid", 5318 .help = "session identifier", 5319 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), 5320 item_param), 5321 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, 5322 session_id)), 5323 }, 5324 [ITEM_PPPOE_PROTO_ID] = { 5325 .name = "pppoe_proto_id", 5326 .help = "match PPPoE session protocol identifier", 5327 .priv = PRIV_ITEM(PPPOE_PROTO_ID, 5328 sizeof(struct rte_flow_item_pppoe_proto_id)), 5329 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED), 5330 item_param), 5331 .args = ARGS(ARGS_ENTRY_HTON 5332 (struct rte_flow_item_pppoe_proto_id, proto_id)), 5333 .call = parse_vc, 5334 }, 5335 [ITEM_HIGIG2] = { 5336 .name = "higig2", 5337 .help = "matches higig2 header", 5338 .priv = PRIV_ITEM(HIGIG2, 5339 sizeof(struct rte_flow_item_higig2_hdr)), 5340 .next = NEXT(item_higig2), 5341 .call = parse_vc, 5342 }, 5343 [ITEM_HIGIG2_CLASSIFICATION] = { 5344 .name = "classification", 5345 .help = "matches classification of higig2 header", 5346 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5347 item_param), 5348 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5349 hdr.ppt1.classification)), 5350 }, 5351 [ITEM_HIGIG2_VID] = { 5352 .name = "vid", 5353 .help = "matches vid of higig2 header", 5354 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5355 item_param), 5356 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5357 hdr.ppt1.vid)), 5358 }, 5359 [ITEM_TAG] = { 5360 .name = "tag", 5361 .help = "match tag value", 5362 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), 5363 .next = NEXT(item_tag), 5364 .call = parse_vc, 5365 }, 5366 [ITEM_TAG_DATA] = { 5367 .name = "data", 5368 .help = "tag value to match", 5369 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5370 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), 5371 }, 5372 [ITEM_TAG_INDEX] = { 5373 .name = "index", 5374 .help = "index of tag array to match", 5375 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5376 NEXT_ENTRY(ITEM_PARAM_IS)), 5377 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), 5378 }, 5379 [ITEM_L2TPV3OIP] = { 5380 .name = "l2tpv3oip", 5381 .help = "match L2TPv3 over IP header", 5382 .priv = PRIV_ITEM(L2TPV3OIP, 5383 sizeof(struct rte_flow_item_l2tpv3oip)), 5384 .next = NEXT(item_l2tpv3oip), 5385 .call = parse_vc, 5386 }, 5387 [ITEM_L2TPV3OIP_SESSION_ID] = { 5388 .name = "session_id", 5389 .help = "session identifier", 5390 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), 5391 item_param), 5392 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, 5393 session_id)), 5394 }, 5395 [ITEM_ESP] = { 5396 .name = "esp", 5397 .help = "match ESP header", 5398 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), 5399 .next = NEXT(item_esp), 5400 .call = parse_vc, 5401 }, 5402 [ITEM_ESP_SPI] = { 5403 .name = "spi", 5404 .help = "security policy index", 5405 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5406 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, 5407 hdr.spi)), 5408 }, 5409 [ITEM_AH] = { 5410 .name = "ah", 5411 .help = "match AH header", 5412 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), 5413 .next = NEXT(item_ah), 5414 .call = parse_vc, 5415 }, 5416 [ITEM_AH_SPI] = { 5417 .name = "spi", 5418 .help = "security parameters index", 5419 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5420 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), 5421 }, 5422 [ITEM_PFCP] = { 5423 .name = "pfcp", 5424 .help = "match pfcp header", 5425 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), 5426 .next = NEXT(item_pfcp), 5427 .call = parse_vc, 5428 }, 5429 [ITEM_PFCP_S_FIELD] = { 5430 .name = "s_field", 5431 .help = "S field", 5432 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5433 item_param), 5434 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, 5435 s_field)), 5436 }, 5437 [ITEM_PFCP_SEID] = { 5438 .name = "seid", 5439 .help = "session endpoint identifier", 5440 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5441 item_param), 5442 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), 5443 }, 5444 [ITEM_ECPRI] = { 5445 .name = "ecpri", 5446 .help = "match eCPRI header", 5447 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), 5448 .next = NEXT(item_ecpri), 5449 .call = parse_vc, 5450 }, 5451 [ITEM_ECPRI_COMMON] = { 5452 .name = "common", 5453 .help = "eCPRI common header", 5454 .next = NEXT(item_ecpri_common), 5455 }, 5456 [ITEM_ECPRI_COMMON_TYPE] = { 5457 .name = "type", 5458 .help = "type of common header", 5459 .next = NEXT(item_ecpri_common_type), 5460 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), 5461 }, 5462 [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { 5463 .name = "iq_data", 5464 .help = "Type #0: IQ Data", 5465 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5466 ITEM_NEXT)), 5467 .call = parse_vc_item_ecpri_type, 5468 }, 5469 [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { 5470 .name = "pc_id", 5471 .help = "Physical Channel ID", 5472 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5473 ITEM_ECPRI_COMMON, ITEM_NEXT), 5474 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5475 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5476 hdr.type0.pc_id)), 5477 }, 5478 [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { 5479 .name = "rtc_ctrl", 5480 .help = "Type #2: Real-Time Control Data", 5481 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5482 ITEM_NEXT)), 5483 .call = parse_vc_item_ecpri_type, 5484 }, 5485 [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { 5486 .name = "rtc_id", 5487 .help = "Real-Time Control Data ID", 5488 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5489 ITEM_ECPRI_COMMON, ITEM_NEXT), 5490 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5491 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5492 hdr.type2.rtc_id)), 5493 }, 5494 [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { 5495 .name = "delay_measure", 5496 .help = "Type #5: One-Way Delay Measurement", 5497 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5498 ITEM_NEXT)), 5499 .call = parse_vc_item_ecpri_type, 5500 }, 5501 [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { 5502 .name = "msr_id", 5503 .help = "Measurement ID", 5504 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5505 ITEM_ECPRI_COMMON, ITEM_NEXT), 5506 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5507 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5508 hdr.type5.msr_id)), 5509 }, 5510 [ITEM_GENEVE_OPT] = { 5511 .name = "geneve-opt", 5512 .help = "GENEVE header option", 5513 .priv = PRIV_ITEM(GENEVE_OPT, 5514 sizeof(struct rte_flow_item_geneve_opt) + 5515 ITEM_GENEVE_OPT_DATA_SIZE), 5516 .next = NEXT(item_geneve_opt), 5517 .call = parse_vc, 5518 }, 5519 [ITEM_GENEVE_OPT_CLASS] = { 5520 .name = "class", 5521 .help = "GENEVE option class", 5522 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5523 item_param), 5524 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, 5525 option_class)), 5526 }, 5527 [ITEM_GENEVE_OPT_TYPE] = { 5528 .name = "type", 5529 .help = "GENEVE option type", 5530 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5531 item_param), 5532 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, 5533 option_type)), 5534 }, 5535 [ITEM_GENEVE_OPT_LENGTH] = { 5536 .name = "length", 5537 .help = "GENEVE option data length (in 32b words)", 5538 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5539 item_param), 5540 .args = ARGS(ARGS_ENTRY_BOUNDED( 5541 struct rte_flow_item_geneve_opt, option_len, 5542 0, 31)), 5543 }, 5544 [ITEM_GENEVE_OPT_DATA] = { 5545 .name = "data", 5546 .help = "GENEVE option data pattern", 5547 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), 5548 item_param), 5549 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), 5550 ARGS_ENTRY_ARB(0, 0), 5551 ARGS_ENTRY_ARB 5552 (sizeof(struct rte_flow_item_geneve_opt), 5553 ITEM_GENEVE_OPT_DATA_SIZE)), 5554 }, 5555 [ITEM_INTEGRITY] = { 5556 .name = "integrity", 5557 .help = "match packet integrity", 5558 .priv = PRIV_ITEM(INTEGRITY, 5559 sizeof(struct rte_flow_item_integrity)), 5560 .next = NEXT(item_integrity), 5561 .call = parse_vc, 5562 }, 5563 [ITEM_INTEGRITY_LEVEL] = { 5564 .name = "level", 5565 .help = "integrity level", 5566 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5567 item_param), 5568 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), 5569 }, 5570 [ITEM_INTEGRITY_VALUE] = { 5571 .name = "value", 5572 .help = "integrity value", 5573 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5574 item_param), 5575 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), 5576 }, 5577 [ITEM_CONNTRACK] = { 5578 .name = "conntrack", 5579 .help = "conntrack state", 5580 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 5581 item_param), 5582 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 5583 }, 5584 [ITEM_PORT_REPRESENTOR] = { 5585 .name = "port_representor", 5586 .help = "match traffic entering the embedded switch from the given ethdev", 5587 .priv = PRIV_ITEM(PORT_REPRESENTOR, 5588 sizeof(struct rte_flow_item_ethdev)), 5589 .next = NEXT(item_port_representor), 5590 .call = parse_vc, 5591 }, 5592 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 5593 .name = "port_id", 5594 .help = "ethdev port ID", 5595 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 5596 item_param), 5597 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5598 }, 5599 [ITEM_REPRESENTED_PORT] = { 5600 .name = "represented_port", 5601 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 5602 .priv = PRIV_ITEM(REPRESENTED_PORT, 5603 sizeof(struct rte_flow_item_ethdev)), 5604 .next = NEXT(item_represented_port), 5605 .call = parse_vc, 5606 }, 5607 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 5608 .name = "ethdev_port_id", 5609 .help = "ethdev port ID", 5610 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 5611 item_param), 5612 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5613 }, 5614 [ITEM_FLEX] = { 5615 .name = "flex", 5616 .help = "match flex header", 5617 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 5618 .next = NEXT(item_flex), 5619 .call = parse_vc, 5620 }, 5621 [ITEM_FLEX_ITEM_HANDLE] = { 5622 .name = "item", 5623 .help = "flex item handle", 5624 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5625 NEXT_ENTRY(ITEM_PARAM_IS)), 5626 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 5627 }, 5628 [ITEM_FLEX_PATTERN_HANDLE] = { 5629 .name = "pattern", 5630 .help = "flex pattern handle", 5631 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5632 NEXT_ENTRY(ITEM_PARAM_IS)), 5633 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 5634 }, 5635 [ITEM_L2TPV2] = { 5636 .name = "l2tpv2", 5637 .help = "match L2TPv2 header", 5638 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 5639 .next = NEXT(item_l2tpv2), 5640 .call = parse_vc, 5641 }, 5642 [ITEM_L2TPV2_TYPE] = { 5643 .name = "type", 5644 .help = "type of l2tpv2", 5645 .next = NEXT(item_l2tpv2_type), 5646 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 5647 }, 5648 [ITEM_L2TPV2_TYPE_DATA] = { 5649 .name = "data", 5650 .help = "Type #7: data message without any options", 5651 .next = NEXT(item_l2tpv2_type_data), 5652 .call = parse_vc_item_l2tpv2_type, 5653 }, 5654 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 5655 .name = "tunnel_id", 5656 .help = "tunnel identifier", 5657 .next = NEXT(item_l2tpv2_type_data, 5658 NEXT_ENTRY(COMMON_UNSIGNED), 5659 item_param), 5660 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5661 hdr.type7.tunnel_id)), 5662 }, 5663 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 5664 .name = "session_id", 5665 .help = "session identifier", 5666 .next = NEXT(item_l2tpv2_type_data, 5667 NEXT_ENTRY(COMMON_UNSIGNED), 5668 item_param), 5669 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5670 hdr.type7.session_id)), 5671 }, 5672 [ITEM_L2TPV2_TYPE_DATA_L] = { 5673 .name = "data_l", 5674 .help = "Type #6: data message with length option", 5675 .next = NEXT(item_l2tpv2_type_data_l), 5676 .call = parse_vc_item_l2tpv2_type, 5677 }, 5678 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 5679 .name = "length", 5680 .help = "message length", 5681 .next = NEXT(item_l2tpv2_type_data_l, 5682 NEXT_ENTRY(COMMON_UNSIGNED), 5683 item_param), 5684 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5685 hdr.type6.length)), 5686 }, 5687 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 5688 .name = "tunnel_id", 5689 .help = "tunnel identifier", 5690 .next = NEXT(item_l2tpv2_type_data_l, 5691 NEXT_ENTRY(COMMON_UNSIGNED), 5692 item_param), 5693 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5694 hdr.type6.tunnel_id)), 5695 }, 5696 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 5697 .name = "session_id", 5698 .help = "session identifier", 5699 .next = NEXT(item_l2tpv2_type_data_l, 5700 NEXT_ENTRY(COMMON_UNSIGNED), 5701 item_param), 5702 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5703 hdr.type6.session_id)), 5704 }, 5705 [ITEM_L2TPV2_TYPE_DATA_S] = { 5706 .name = "data_s", 5707 .help = "Type #5: data message with ns, nr option", 5708 .next = NEXT(item_l2tpv2_type_data_s), 5709 .call = parse_vc_item_l2tpv2_type, 5710 }, 5711 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 5712 .name = "tunnel_id", 5713 .help = "tunnel identifier", 5714 .next = NEXT(item_l2tpv2_type_data_s, 5715 NEXT_ENTRY(COMMON_UNSIGNED), 5716 item_param), 5717 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5718 hdr.type5.tunnel_id)), 5719 }, 5720 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 5721 .name = "session_id", 5722 .help = "session identifier", 5723 .next = NEXT(item_l2tpv2_type_data_s, 5724 NEXT_ENTRY(COMMON_UNSIGNED), 5725 item_param), 5726 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5727 hdr.type5.session_id)), 5728 }, 5729 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 5730 .name = "ns", 5731 .help = "sequence number for message", 5732 .next = NEXT(item_l2tpv2_type_data_s, 5733 NEXT_ENTRY(COMMON_UNSIGNED), 5734 item_param), 5735 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5736 hdr.type5.ns)), 5737 }, 5738 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 5739 .name = "nr", 5740 .help = "sequence number for next receive message", 5741 .next = NEXT(item_l2tpv2_type_data_s, 5742 NEXT_ENTRY(COMMON_UNSIGNED), 5743 item_param), 5744 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5745 hdr.type5.nr)), 5746 }, 5747 [ITEM_L2TPV2_TYPE_DATA_O] = { 5748 .name = "data_o", 5749 .help = "Type #4: data message with offset option", 5750 .next = NEXT(item_l2tpv2_type_data_o), 5751 .call = parse_vc_item_l2tpv2_type, 5752 }, 5753 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 5754 .name = "tunnel_id", 5755 .help = "tunnel identifier", 5756 .next = NEXT(item_l2tpv2_type_data_o, 5757 NEXT_ENTRY(COMMON_UNSIGNED), 5758 item_param), 5759 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5760 hdr.type4.tunnel_id)), 5761 }, 5762 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 5763 .name = "session_id", 5764 .help = "session identifier", 5765 .next = NEXT(item_l2tpv2_type_data_o, 5766 NEXT_ENTRY(COMMON_UNSIGNED), 5767 item_param), 5768 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5769 hdr.type5.session_id)), 5770 }, 5771 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 5772 .name = "offset_size", 5773 .help = "the size of offset padding", 5774 .next = NEXT(item_l2tpv2_type_data_o, 5775 NEXT_ENTRY(COMMON_UNSIGNED), 5776 item_param), 5777 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5778 hdr.type4.offset_size)), 5779 }, 5780 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 5781 .name = "data_l_s", 5782 .help = "Type #3: data message contains length, ns, nr " 5783 "options", 5784 .next = NEXT(item_l2tpv2_type_data_l_s), 5785 .call = parse_vc_item_l2tpv2_type, 5786 }, 5787 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 5788 .name = "length", 5789 .help = "message length", 5790 .next = NEXT(item_l2tpv2_type_data_l_s, 5791 NEXT_ENTRY(COMMON_UNSIGNED), 5792 item_param), 5793 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5794 hdr.type3.length)), 5795 }, 5796 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 5797 .name = "tunnel_id", 5798 .help = "tunnel identifier", 5799 .next = NEXT(item_l2tpv2_type_data_l_s, 5800 NEXT_ENTRY(COMMON_UNSIGNED), 5801 item_param), 5802 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5803 hdr.type3.tunnel_id)), 5804 }, 5805 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 5806 .name = "session_id", 5807 .help = "session identifier", 5808 .next = NEXT(item_l2tpv2_type_data_l_s, 5809 NEXT_ENTRY(COMMON_UNSIGNED), 5810 item_param), 5811 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5812 hdr.type3.session_id)), 5813 }, 5814 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 5815 .name = "ns", 5816 .help = "sequence number for message", 5817 .next = NEXT(item_l2tpv2_type_data_l_s, 5818 NEXT_ENTRY(COMMON_UNSIGNED), 5819 item_param), 5820 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5821 hdr.type3.ns)), 5822 }, 5823 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 5824 .name = "nr", 5825 .help = "sequence number for next receive message", 5826 .next = NEXT(item_l2tpv2_type_data_l_s, 5827 NEXT_ENTRY(COMMON_UNSIGNED), 5828 item_param), 5829 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5830 hdr.type3.nr)), 5831 }, 5832 [ITEM_L2TPV2_TYPE_CTRL] = { 5833 .name = "control", 5834 .help = "Type #3: conrtol message contains length, ns, nr " 5835 "options", 5836 .next = NEXT(item_l2tpv2_type_ctrl), 5837 .call = parse_vc_item_l2tpv2_type, 5838 }, 5839 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 5840 .name = "length", 5841 .help = "message length", 5842 .next = NEXT(item_l2tpv2_type_ctrl, 5843 NEXT_ENTRY(COMMON_UNSIGNED), 5844 item_param), 5845 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5846 hdr.type3.length)), 5847 }, 5848 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 5849 .name = "tunnel_id", 5850 .help = "tunnel identifier", 5851 .next = NEXT(item_l2tpv2_type_ctrl, 5852 NEXT_ENTRY(COMMON_UNSIGNED), 5853 item_param), 5854 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5855 hdr.type3.tunnel_id)), 5856 }, 5857 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 5858 .name = "session_id", 5859 .help = "session identifier", 5860 .next = NEXT(item_l2tpv2_type_ctrl, 5861 NEXT_ENTRY(COMMON_UNSIGNED), 5862 item_param), 5863 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5864 hdr.type3.session_id)), 5865 }, 5866 [ITEM_L2TPV2_MSG_CTRL_NS] = { 5867 .name = "ns", 5868 .help = "sequence number for message", 5869 .next = NEXT(item_l2tpv2_type_ctrl, 5870 NEXT_ENTRY(COMMON_UNSIGNED), 5871 item_param), 5872 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5873 hdr.type3.ns)), 5874 }, 5875 [ITEM_L2TPV2_MSG_CTRL_NR] = { 5876 .name = "nr", 5877 .help = "sequence number for next receive message", 5878 .next = NEXT(item_l2tpv2_type_ctrl, 5879 NEXT_ENTRY(COMMON_UNSIGNED), 5880 item_param), 5881 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5882 hdr.type3.nr)), 5883 }, 5884 [ITEM_PPP] = { 5885 .name = "ppp", 5886 .help = "match PPP header", 5887 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 5888 .next = NEXT(item_ppp), 5889 .call = parse_vc, 5890 }, 5891 [ITEM_PPP_ADDR] = { 5892 .name = "addr", 5893 .help = "PPP address", 5894 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 5895 item_param), 5896 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 5897 }, 5898 [ITEM_PPP_CTRL] = { 5899 .name = "ctrl", 5900 .help = "PPP control", 5901 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 5902 item_param), 5903 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 5904 }, 5905 [ITEM_PPP_PROTO_ID] = { 5906 .name = "proto_id", 5907 .help = "PPP protocol identifier", 5908 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 5909 item_param), 5910 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 5911 hdr.proto_id)), 5912 }, 5913 [ITEM_METER] = { 5914 .name = "meter", 5915 .help = "match meter color", 5916 .priv = PRIV_ITEM(METER_COLOR, 5917 sizeof(struct rte_flow_item_meter_color)), 5918 .next = NEXT(item_meter), 5919 .call = parse_vc, 5920 }, 5921 [ITEM_METER_COLOR] = { 5922 .name = "color", 5923 .help = "meter color", 5924 .next = NEXT(item_meter, 5925 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 5926 item_param), 5927 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 5928 color)), 5929 }, 5930 [ITEM_METER_COLOR_NAME] = { 5931 .name = "color_name", 5932 .help = "meter color name", 5933 .call = parse_meter_color, 5934 .comp = comp_meter_color, 5935 }, 5936 [ITEM_QUOTA] = { 5937 .name = "quota", 5938 .help = "match quota", 5939 .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), 5940 .next = NEXT(item_quota), 5941 .call = parse_vc 5942 }, 5943 [ITEM_QUOTA_STATE] = { 5944 .name = "quota_state", 5945 .help = "quota state", 5946 .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), 5947 NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), 5948 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) 5949 }, 5950 [ITEM_QUOTA_STATE_NAME] = { 5951 .name = "state_name", 5952 .help = "quota state name", 5953 .call = parse_quota_state_name, 5954 .comp = comp_quota_state_name 5955 }, 5956 [ITEM_IB_BTH] = { 5957 .name = "ib_bth", 5958 .help = "match ib bth fields", 5959 .priv = PRIV_ITEM(IB_BTH, 5960 sizeof(struct rte_flow_item_ib_bth)), 5961 .next = NEXT(item_ib_bth), 5962 .call = parse_vc, 5963 }, 5964 [ITEM_IB_BTH_OPCODE] = { 5965 .name = "opcode", 5966 .help = "match ib bth opcode", 5967 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 5968 item_param), 5969 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 5970 hdr.opcode)), 5971 }, 5972 [ITEM_IB_BTH_PKEY] = { 5973 .name = "pkey", 5974 .help = "partition key", 5975 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 5976 item_param), 5977 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 5978 hdr.pkey)), 5979 }, 5980 [ITEM_IB_BTH_DST_QPN] = { 5981 .name = "dst_qp", 5982 .help = "destination qp", 5983 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 5984 item_param), 5985 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 5986 hdr.dst_qp)), 5987 }, 5988 [ITEM_IB_BTH_PSN] = { 5989 .name = "psn", 5990 .help = "packet sequence number", 5991 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 5992 item_param), 5993 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 5994 hdr.psn)), 5995 }, 5996 [ITEM_PTYPE] = { 5997 .name = "ptype", 5998 .help = "match L2/L3/L4 and tunnel information", 5999 .priv = PRIV_ITEM(PTYPE, 6000 sizeof(struct rte_flow_item_ptype)), 6001 .next = NEXT(item_ptype), 6002 .call = parse_vc, 6003 }, 6004 [ITEM_PTYPE_VALUE] = { 6005 .name = "packet_type", 6006 .help = "packet type as defined in rte_mbuf_ptype", 6007 .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), 6008 item_param), 6009 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), 6010 }, 6011 [ITEM_NSH] = { 6012 .name = "nsh", 6013 .help = "match NSH header", 6014 .priv = PRIV_ITEM(NSH, 6015 sizeof(struct rte_flow_item_nsh)), 6016 .next = NEXT(item_nsh), 6017 .call = parse_vc, 6018 }, 6019 6020 /* Validate/create actions. */ 6021 [ACTIONS] = { 6022 .name = "actions", 6023 .help = "submit a list of associated actions", 6024 .next = NEXT(next_action), 6025 .call = parse_vc, 6026 }, 6027 [ACTION_NEXT] = { 6028 .name = "/", 6029 .help = "specify next action", 6030 .next = NEXT(next_action), 6031 }, 6032 [ACTION_END] = { 6033 .name = "end", 6034 .help = "end list of actions", 6035 .priv = PRIV_ACTION(END, 0), 6036 .call = parse_vc, 6037 }, 6038 [ACTION_VOID] = { 6039 .name = "void", 6040 .help = "no-op action", 6041 .priv = PRIV_ACTION(VOID, 0), 6042 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6043 .call = parse_vc, 6044 }, 6045 [ACTION_PASSTHRU] = { 6046 .name = "passthru", 6047 .help = "let subsequent rule process matched packets", 6048 .priv = PRIV_ACTION(PASSTHRU, 0), 6049 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6050 .call = parse_vc, 6051 }, 6052 [ACTION_SKIP_CMAN] = { 6053 .name = "skip_cman", 6054 .help = "bypass cman on received packets", 6055 .priv = PRIV_ACTION(SKIP_CMAN, 0), 6056 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6057 .call = parse_vc, 6058 }, 6059 [ACTION_JUMP] = { 6060 .name = "jump", 6061 .help = "redirect traffic to a given group", 6062 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 6063 .next = NEXT(action_jump), 6064 .call = parse_vc, 6065 }, 6066 [ACTION_JUMP_GROUP] = { 6067 .name = "group", 6068 .help = "group to redirect traffic to", 6069 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 6070 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 6071 .call = parse_vc_conf, 6072 }, 6073 [ACTION_MARK] = { 6074 .name = "mark", 6075 .help = "attach 32 bit value to packets", 6076 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 6077 .next = NEXT(action_mark), 6078 .call = parse_vc, 6079 }, 6080 [ACTION_MARK_ID] = { 6081 .name = "id", 6082 .help = "32 bit value to return with packets", 6083 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6084 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 6085 .call = parse_vc_conf, 6086 }, 6087 [ACTION_FLAG] = { 6088 .name = "flag", 6089 .help = "flag packets", 6090 .priv = PRIV_ACTION(FLAG, 0), 6091 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6092 .call = parse_vc, 6093 }, 6094 [ACTION_QUEUE] = { 6095 .name = "queue", 6096 .help = "assign packets to a given queue index", 6097 .priv = PRIV_ACTION(QUEUE, 6098 sizeof(struct rte_flow_action_queue)), 6099 .next = NEXT(action_queue), 6100 .call = parse_vc, 6101 }, 6102 [ACTION_QUEUE_INDEX] = { 6103 .name = "index", 6104 .help = "queue index to use", 6105 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 6106 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 6107 .call = parse_vc_conf, 6108 }, 6109 [ACTION_DROP] = { 6110 .name = "drop", 6111 .help = "drop packets (note: passthru has priority)", 6112 .priv = PRIV_ACTION(DROP, 0), 6113 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6114 .call = parse_vc, 6115 }, 6116 [ACTION_COUNT] = { 6117 .name = "count", 6118 .help = "enable counters for this rule", 6119 .priv = PRIV_ACTION(COUNT, 6120 sizeof(struct rte_flow_action_count)), 6121 .next = NEXT(action_count), 6122 .call = parse_vc, 6123 }, 6124 [ACTION_COUNT_ID] = { 6125 .name = "identifier", 6126 .help = "counter identifier to use", 6127 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 6128 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 6129 .call = parse_vc_conf, 6130 }, 6131 [ACTION_RSS] = { 6132 .name = "rss", 6133 .help = "spread packets among several queues", 6134 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 6135 .next = NEXT(action_rss), 6136 .call = parse_vc_action_rss, 6137 }, 6138 [ACTION_RSS_FUNC] = { 6139 .name = "func", 6140 .help = "RSS hash function to apply", 6141 .next = NEXT(action_rss, 6142 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 6143 ACTION_RSS_FUNC_TOEPLITZ, 6144 ACTION_RSS_FUNC_SIMPLE_XOR, 6145 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 6146 }, 6147 [ACTION_RSS_FUNC_DEFAULT] = { 6148 .name = "default", 6149 .help = "default hash function", 6150 .call = parse_vc_action_rss_func, 6151 }, 6152 [ACTION_RSS_FUNC_TOEPLITZ] = { 6153 .name = "toeplitz", 6154 .help = "Toeplitz hash function", 6155 .call = parse_vc_action_rss_func, 6156 }, 6157 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 6158 .name = "simple_xor", 6159 .help = "simple XOR hash function", 6160 .call = parse_vc_action_rss_func, 6161 }, 6162 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 6163 .name = "symmetric_toeplitz", 6164 .help = "Symmetric Toeplitz hash function", 6165 .call = parse_vc_action_rss_func, 6166 }, 6167 [ACTION_RSS_LEVEL] = { 6168 .name = "level", 6169 .help = "encapsulation level for \"types\"", 6170 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6171 .args = ARGS(ARGS_ENTRY_ARB 6172 (offsetof(struct action_rss_data, conf) + 6173 offsetof(struct rte_flow_action_rss, level), 6174 sizeof(((struct rte_flow_action_rss *)0)-> 6175 level))), 6176 }, 6177 [ACTION_RSS_TYPES] = { 6178 .name = "types", 6179 .help = "specific RSS hash types", 6180 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 6181 }, 6182 [ACTION_RSS_TYPE] = { 6183 .name = "{type}", 6184 .help = "RSS hash type", 6185 .call = parse_vc_action_rss_type, 6186 .comp = comp_vc_action_rss_type, 6187 }, 6188 [ACTION_RSS_KEY] = { 6189 .name = "key", 6190 .help = "RSS hash key", 6191 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 6192 .args = ARGS(ARGS_ENTRY_ARB 6193 (offsetof(struct action_rss_data, conf) + 6194 offsetof(struct rte_flow_action_rss, key), 6195 sizeof(((struct rte_flow_action_rss *)0)->key)), 6196 ARGS_ENTRY_ARB 6197 (offsetof(struct action_rss_data, conf) + 6198 offsetof(struct rte_flow_action_rss, key_len), 6199 sizeof(((struct rte_flow_action_rss *)0)-> 6200 key_len)), 6201 ARGS_ENTRY(struct action_rss_data, key)), 6202 }, 6203 [ACTION_RSS_KEY_LEN] = { 6204 .name = "key_len", 6205 .help = "RSS hash key length in bytes", 6206 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6207 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6208 (offsetof(struct action_rss_data, conf) + 6209 offsetof(struct rte_flow_action_rss, key_len), 6210 sizeof(((struct rte_flow_action_rss *)0)-> 6211 key_len), 6212 0, 6213 RSS_HASH_KEY_LENGTH)), 6214 }, 6215 [ACTION_RSS_QUEUES] = { 6216 .name = "queues", 6217 .help = "queue indices to use", 6218 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 6219 .call = parse_vc_conf, 6220 }, 6221 [ACTION_RSS_QUEUE] = { 6222 .name = "{queue}", 6223 .help = "queue index", 6224 .call = parse_vc_action_rss_queue, 6225 .comp = comp_vc_action_rss_queue, 6226 }, 6227 [ACTION_PF] = { 6228 .name = "pf", 6229 .help = "direct traffic to physical function", 6230 .priv = PRIV_ACTION(PF, 0), 6231 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6232 .call = parse_vc, 6233 }, 6234 [ACTION_VF] = { 6235 .name = "vf", 6236 .help = "direct traffic to a virtual function ID", 6237 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 6238 .next = NEXT(action_vf), 6239 .call = parse_vc, 6240 }, 6241 [ACTION_VF_ORIGINAL] = { 6242 .name = "original", 6243 .help = "use original VF ID if possible", 6244 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 6245 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 6246 original, 1)), 6247 .call = parse_vc_conf, 6248 }, 6249 [ACTION_VF_ID] = { 6250 .name = "id", 6251 .help = "VF ID", 6252 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 6253 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 6254 .call = parse_vc_conf, 6255 }, 6256 [ACTION_PORT_ID] = { 6257 .name = "port_id", 6258 .help = "direct matching traffic to a given DPDK port ID", 6259 .priv = PRIV_ACTION(PORT_ID, 6260 sizeof(struct rte_flow_action_port_id)), 6261 .next = NEXT(action_port_id), 6262 .call = parse_vc, 6263 }, 6264 [ACTION_PORT_ID_ORIGINAL] = { 6265 .name = "original", 6266 .help = "use original DPDK port ID if possible", 6267 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 6268 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 6269 original, 1)), 6270 .call = parse_vc_conf, 6271 }, 6272 [ACTION_PORT_ID_ID] = { 6273 .name = "id", 6274 .help = "DPDK port ID", 6275 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 6276 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 6277 .call = parse_vc_conf, 6278 }, 6279 [ACTION_METER] = { 6280 .name = "meter", 6281 .help = "meter the directed packets at given id", 6282 .priv = PRIV_ACTION(METER, 6283 sizeof(struct rte_flow_action_meter)), 6284 .next = NEXT(action_meter), 6285 .call = parse_vc, 6286 }, 6287 [ACTION_METER_COLOR] = { 6288 .name = "color", 6289 .help = "meter color for the packets", 6290 .priv = PRIV_ACTION(METER_COLOR, 6291 sizeof(struct rte_flow_action_meter_color)), 6292 .next = NEXT(action_meter_color), 6293 .call = parse_vc, 6294 }, 6295 [ACTION_METER_COLOR_TYPE] = { 6296 .name = "type", 6297 .help = "specific meter color", 6298 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6299 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 6300 ACTION_METER_COLOR_YELLOW, 6301 ACTION_METER_COLOR_RED)), 6302 }, 6303 [ACTION_METER_COLOR_GREEN] = { 6304 .name = "green", 6305 .help = "meter color green", 6306 .call = parse_vc_action_meter_color_type, 6307 }, 6308 [ACTION_METER_COLOR_YELLOW] = { 6309 .name = "yellow", 6310 .help = "meter color yellow", 6311 .call = parse_vc_action_meter_color_type, 6312 }, 6313 [ACTION_METER_COLOR_RED] = { 6314 .name = "red", 6315 .help = "meter color red", 6316 .call = parse_vc_action_meter_color_type, 6317 }, 6318 [ACTION_METER_ID] = { 6319 .name = "mtr_id", 6320 .help = "meter id to use", 6321 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 6322 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 6323 .call = parse_vc_conf, 6324 }, 6325 [ACTION_METER_MARK] = { 6326 .name = "meter_mark", 6327 .help = "meter the directed packets using profile and policy", 6328 .priv = PRIV_ACTION(METER_MARK, 6329 sizeof(struct rte_flow_action_meter_mark)), 6330 .next = NEXT(action_meter_mark), 6331 .call = parse_vc, 6332 }, 6333 [ACTION_METER_PROFILE] = { 6334 .name = "mtr_profile", 6335 .help = "meter profile id to use", 6336 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 6337 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6338 }, 6339 [ACTION_METER_PROFILE_ID2PTR] = { 6340 .name = "{mtr_profile_id}", 6341 .type = "PROFILE_ID", 6342 .help = "meter profile id", 6343 .next = NEXT(action_meter_mark), 6344 .call = parse_meter_profile_id2ptr, 6345 .comp = comp_none, 6346 }, 6347 [ACTION_METER_POLICY] = { 6348 .name = "mtr_policy", 6349 .help = "meter policy id to use", 6350 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 6351 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6352 }, 6353 [ACTION_METER_POLICY_ID2PTR] = { 6354 .name = "{mtr_policy_id}", 6355 .type = "POLICY_ID", 6356 .help = "meter policy id", 6357 .next = NEXT(action_meter_mark), 6358 .call = parse_meter_policy_id2ptr, 6359 .comp = comp_none, 6360 }, 6361 [ACTION_METER_COLOR_MODE] = { 6362 .name = "mtr_color_mode", 6363 .help = "meter color awareness mode", 6364 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6365 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 6366 .call = parse_vc_conf, 6367 }, 6368 [ACTION_METER_STATE] = { 6369 .name = "mtr_state", 6370 .help = "meter state", 6371 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6372 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 6373 .call = parse_vc_conf, 6374 }, 6375 [ACTION_OF_DEC_NW_TTL] = { 6376 .name = "of_dec_nw_ttl", 6377 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 6378 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 6379 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6380 .call = parse_vc, 6381 }, 6382 [ACTION_OF_POP_VLAN] = { 6383 .name = "of_pop_vlan", 6384 .help = "OpenFlow's OFPAT_POP_VLAN", 6385 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 6386 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6387 .call = parse_vc, 6388 }, 6389 [ACTION_OF_PUSH_VLAN] = { 6390 .name = "of_push_vlan", 6391 .help = "OpenFlow's OFPAT_PUSH_VLAN", 6392 .priv = PRIV_ACTION 6393 (OF_PUSH_VLAN, 6394 sizeof(struct rte_flow_action_of_push_vlan)), 6395 .next = NEXT(action_of_push_vlan), 6396 .call = parse_vc, 6397 }, 6398 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 6399 .name = "ethertype", 6400 .help = "EtherType", 6401 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 6402 .args = ARGS(ARGS_ENTRY_HTON 6403 (struct rte_flow_action_of_push_vlan, 6404 ethertype)), 6405 .call = parse_vc_conf, 6406 }, 6407 [ACTION_OF_SET_VLAN_VID] = { 6408 .name = "of_set_vlan_vid", 6409 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 6410 .priv = PRIV_ACTION 6411 (OF_SET_VLAN_VID, 6412 sizeof(struct rte_flow_action_of_set_vlan_vid)), 6413 .next = NEXT(action_of_set_vlan_vid), 6414 .call = parse_vc, 6415 }, 6416 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 6417 .name = "vlan_vid", 6418 .help = "VLAN id", 6419 .next = NEXT(action_of_set_vlan_vid, 6420 NEXT_ENTRY(COMMON_UNSIGNED)), 6421 .args = ARGS(ARGS_ENTRY_HTON 6422 (struct rte_flow_action_of_set_vlan_vid, 6423 vlan_vid)), 6424 .call = parse_vc_conf, 6425 }, 6426 [ACTION_OF_SET_VLAN_PCP] = { 6427 .name = "of_set_vlan_pcp", 6428 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 6429 .priv = PRIV_ACTION 6430 (OF_SET_VLAN_PCP, 6431 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 6432 .next = NEXT(action_of_set_vlan_pcp), 6433 .call = parse_vc, 6434 }, 6435 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 6436 .name = "vlan_pcp", 6437 .help = "VLAN priority", 6438 .next = NEXT(action_of_set_vlan_pcp, 6439 NEXT_ENTRY(COMMON_UNSIGNED)), 6440 .args = ARGS(ARGS_ENTRY_HTON 6441 (struct rte_flow_action_of_set_vlan_pcp, 6442 vlan_pcp)), 6443 .call = parse_vc_conf, 6444 }, 6445 [ACTION_OF_POP_MPLS] = { 6446 .name = "of_pop_mpls", 6447 .help = "OpenFlow's OFPAT_POP_MPLS", 6448 .priv = PRIV_ACTION(OF_POP_MPLS, 6449 sizeof(struct rte_flow_action_of_pop_mpls)), 6450 .next = NEXT(action_of_pop_mpls), 6451 .call = parse_vc, 6452 }, 6453 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 6454 .name = "ethertype", 6455 .help = "EtherType", 6456 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6457 .args = ARGS(ARGS_ENTRY_HTON 6458 (struct rte_flow_action_of_pop_mpls, 6459 ethertype)), 6460 .call = parse_vc_conf, 6461 }, 6462 [ACTION_OF_PUSH_MPLS] = { 6463 .name = "of_push_mpls", 6464 .help = "OpenFlow's OFPAT_PUSH_MPLS", 6465 .priv = PRIV_ACTION 6466 (OF_PUSH_MPLS, 6467 sizeof(struct rte_flow_action_of_push_mpls)), 6468 .next = NEXT(action_of_push_mpls), 6469 .call = parse_vc, 6470 }, 6471 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 6472 .name = "ethertype", 6473 .help = "EtherType", 6474 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6475 .args = ARGS(ARGS_ENTRY_HTON 6476 (struct rte_flow_action_of_push_mpls, 6477 ethertype)), 6478 .call = parse_vc_conf, 6479 }, 6480 [ACTION_VXLAN_ENCAP] = { 6481 .name = "vxlan_encap", 6482 .help = "VXLAN encapsulation, uses configuration set by \"set" 6483 " vxlan\"", 6484 .priv = PRIV_ACTION(VXLAN_ENCAP, 6485 sizeof(struct action_vxlan_encap_data)), 6486 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6487 .call = parse_vc_action_vxlan_encap, 6488 }, 6489 [ACTION_VXLAN_DECAP] = { 6490 .name = "vxlan_decap", 6491 .help = "Performs a decapsulation action by stripping all" 6492 " headers of the VXLAN tunnel network overlay from the" 6493 " matched flow.", 6494 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 6495 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6496 .call = parse_vc, 6497 }, 6498 [ACTION_NVGRE_ENCAP] = { 6499 .name = "nvgre_encap", 6500 .help = "NVGRE encapsulation, uses configuration set by \"set" 6501 " nvgre\"", 6502 .priv = PRIV_ACTION(NVGRE_ENCAP, 6503 sizeof(struct action_nvgre_encap_data)), 6504 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6505 .call = parse_vc_action_nvgre_encap, 6506 }, 6507 [ACTION_NVGRE_DECAP] = { 6508 .name = "nvgre_decap", 6509 .help = "Performs a decapsulation action by stripping all" 6510 " headers of the NVGRE tunnel network overlay from the" 6511 " matched flow.", 6512 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 6513 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6514 .call = parse_vc, 6515 }, 6516 [ACTION_L2_ENCAP] = { 6517 .name = "l2_encap", 6518 .help = "l2 encap, uses configuration set by" 6519 " \"set l2_encap\"", 6520 .priv = PRIV_ACTION(RAW_ENCAP, 6521 sizeof(struct action_raw_encap_data)), 6522 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6523 .call = parse_vc_action_l2_encap, 6524 }, 6525 [ACTION_L2_DECAP] = { 6526 .name = "l2_decap", 6527 .help = "l2 decap, uses configuration set by" 6528 " \"set l2_decap\"", 6529 .priv = PRIV_ACTION(RAW_DECAP, 6530 sizeof(struct action_raw_decap_data)), 6531 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6532 .call = parse_vc_action_l2_decap, 6533 }, 6534 [ACTION_MPLSOGRE_ENCAP] = { 6535 .name = "mplsogre_encap", 6536 .help = "mplsogre encapsulation, uses configuration set by" 6537 " \"set mplsogre_encap\"", 6538 .priv = PRIV_ACTION(RAW_ENCAP, 6539 sizeof(struct action_raw_encap_data)), 6540 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6541 .call = parse_vc_action_mplsogre_encap, 6542 }, 6543 [ACTION_MPLSOGRE_DECAP] = { 6544 .name = "mplsogre_decap", 6545 .help = "mplsogre decapsulation, uses configuration set by" 6546 " \"set mplsogre_decap\"", 6547 .priv = PRIV_ACTION(RAW_DECAP, 6548 sizeof(struct action_raw_decap_data)), 6549 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6550 .call = parse_vc_action_mplsogre_decap, 6551 }, 6552 [ACTION_MPLSOUDP_ENCAP] = { 6553 .name = "mplsoudp_encap", 6554 .help = "mplsoudp encapsulation, uses configuration set by" 6555 " \"set mplsoudp_encap\"", 6556 .priv = PRIV_ACTION(RAW_ENCAP, 6557 sizeof(struct action_raw_encap_data)), 6558 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6559 .call = parse_vc_action_mplsoudp_encap, 6560 }, 6561 [ACTION_MPLSOUDP_DECAP] = { 6562 .name = "mplsoudp_decap", 6563 .help = "mplsoudp decapsulation, uses configuration set by" 6564 " \"set mplsoudp_decap\"", 6565 .priv = PRIV_ACTION(RAW_DECAP, 6566 sizeof(struct action_raw_decap_data)), 6567 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6568 .call = parse_vc_action_mplsoudp_decap, 6569 }, 6570 [ACTION_SET_IPV4_SRC] = { 6571 .name = "set_ipv4_src", 6572 .help = "Set a new IPv4 source address in the outermost" 6573 " IPv4 header", 6574 .priv = PRIV_ACTION(SET_IPV4_SRC, 6575 sizeof(struct rte_flow_action_set_ipv4)), 6576 .next = NEXT(action_set_ipv4_src), 6577 .call = parse_vc, 6578 }, 6579 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 6580 .name = "ipv4_addr", 6581 .help = "new IPv4 source address to set", 6582 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 6583 .args = ARGS(ARGS_ENTRY_HTON 6584 (struct rte_flow_action_set_ipv4, ipv4_addr)), 6585 .call = parse_vc_conf, 6586 }, 6587 [ACTION_SET_IPV4_DST] = { 6588 .name = "set_ipv4_dst", 6589 .help = "Set a new IPv4 destination address in the outermost" 6590 " IPv4 header", 6591 .priv = PRIV_ACTION(SET_IPV4_DST, 6592 sizeof(struct rte_flow_action_set_ipv4)), 6593 .next = NEXT(action_set_ipv4_dst), 6594 .call = parse_vc, 6595 }, 6596 [ACTION_SET_IPV4_DST_IPV4_DST] = { 6597 .name = "ipv4_addr", 6598 .help = "new IPv4 destination address to set", 6599 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 6600 .args = ARGS(ARGS_ENTRY_HTON 6601 (struct rte_flow_action_set_ipv4, ipv4_addr)), 6602 .call = parse_vc_conf, 6603 }, 6604 [ACTION_SET_IPV6_SRC] = { 6605 .name = "set_ipv6_src", 6606 .help = "Set a new IPv6 source address in the outermost" 6607 " IPv6 header", 6608 .priv = PRIV_ACTION(SET_IPV6_SRC, 6609 sizeof(struct rte_flow_action_set_ipv6)), 6610 .next = NEXT(action_set_ipv6_src), 6611 .call = parse_vc, 6612 }, 6613 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 6614 .name = "ipv6_addr", 6615 .help = "new IPv6 source address to set", 6616 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 6617 .args = ARGS(ARGS_ENTRY_HTON 6618 (struct rte_flow_action_set_ipv6, ipv6_addr)), 6619 .call = parse_vc_conf, 6620 }, 6621 [ACTION_SET_IPV6_DST] = { 6622 .name = "set_ipv6_dst", 6623 .help = "Set a new IPv6 destination address in the outermost" 6624 " IPv6 header", 6625 .priv = PRIV_ACTION(SET_IPV6_DST, 6626 sizeof(struct rte_flow_action_set_ipv6)), 6627 .next = NEXT(action_set_ipv6_dst), 6628 .call = parse_vc, 6629 }, 6630 [ACTION_SET_IPV6_DST_IPV6_DST] = { 6631 .name = "ipv6_addr", 6632 .help = "new IPv6 destination address to set", 6633 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 6634 .args = ARGS(ARGS_ENTRY_HTON 6635 (struct rte_flow_action_set_ipv6, ipv6_addr)), 6636 .call = parse_vc_conf, 6637 }, 6638 [ACTION_SET_TP_SRC] = { 6639 .name = "set_tp_src", 6640 .help = "set a new source port number in the outermost" 6641 " TCP/UDP header", 6642 .priv = PRIV_ACTION(SET_TP_SRC, 6643 sizeof(struct rte_flow_action_set_tp)), 6644 .next = NEXT(action_set_tp_src), 6645 .call = parse_vc, 6646 }, 6647 [ACTION_SET_TP_SRC_TP_SRC] = { 6648 .name = "port", 6649 .help = "new source port number to set", 6650 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 6651 .args = ARGS(ARGS_ENTRY_HTON 6652 (struct rte_flow_action_set_tp, port)), 6653 .call = parse_vc_conf, 6654 }, 6655 [ACTION_SET_TP_DST] = { 6656 .name = "set_tp_dst", 6657 .help = "set a new destination port number in the outermost" 6658 " TCP/UDP header", 6659 .priv = PRIV_ACTION(SET_TP_DST, 6660 sizeof(struct rte_flow_action_set_tp)), 6661 .next = NEXT(action_set_tp_dst), 6662 .call = parse_vc, 6663 }, 6664 [ACTION_SET_TP_DST_TP_DST] = { 6665 .name = "port", 6666 .help = "new destination port number to set", 6667 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 6668 .args = ARGS(ARGS_ENTRY_HTON 6669 (struct rte_flow_action_set_tp, port)), 6670 .call = parse_vc_conf, 6671 }, 6672 [ACTION_MAC_SWAP] = { 6673 .name = "mac_swap", 6674 .help = "Swap the source and destination MAC addresses" 6675 " in the outermost Ethernet header", 6676 .priv = PRIV_ACTION(MAC_SWAP, 0), 6677 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6678 .call = parse_vc, 6679 }, 6680 [ACTION_DEC_TTL] = { 6681 .name = "dec_ttl", 6682 .help = "decrease network TTL if available", 6683 .priv = PRIV_ACTION(DEC_TTL, 0), 6684 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6685 .call = parse_vc, 6686 }, 6687 [ACTION_SET_TTL] = { 6688 .name = "set_ttl", 6689 .help = "set ttl value", 6690 .priv = PRIV_ACTION(SET_TTL, 6691 sizeof(struct rte_flow_action_set_ttl)), 6692 .next = NEXT(action_set_ttl), 6693 .call = parse_vc, 6694 }, 6695 [ACTION_SET_TTL_TTL] = { 6696 .name = "ttl_value", 6697 .help = "new ttl value to set", 6698 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 6699 .args = ARGS(ARGS_ENTRY_HTON 6700 (struct rte_flow_action_set_ttl, ttl_value)), 6701 .call = parse_vc_conf, 6702 }, 6703 [ACTION_SET_MAC_SRC] = { 6704 .name = "set_mac_src", 6705 .help = "set source mac address", 6706 .priv = PRIV_ACTION(SET_MAC_SRC, 6707 sizeof(struct rte_flow_action_set_mac)), 6708 .next = NEXT(action_set_mac_src), 6709 .call = parse_vc, 6710 }, 6711 [ACTION_SET_MAC_SRC_MAC_SRC] = { 6712 .name = "mac_addr", 6713 .help = "new source mac address", 6714 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 6715 .args = ARGS(ARGS_ENTRY_HTON 6716 (struct rte_flow_action_set_mac, mac_addr)), 6717 .call = parse_vc_conf, 6718 }, 6719 [ACTION_SET_MAC_DST] = { 6720 .name = "set_mac_dst", 6721 .help = "set destination mac address", 6722 .priv = PRIV_ACTION(SET_MAC_DST, 6723 sizeof(struct rte_flow_action_set_mac)), 6724 .next = NEXT(action_set_mac_dst), 6725 .call = parse_vc, 6726 }, 6727 [ACTION_SET_MAC_DST_MAC_DST] = { 6728 .name = "mac_addr", 6729 .help = "new destination mac address to set", 6730 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 6731 .args = ARGS(ARGS_ENTRY_HTON 6732 (struct rte_flow_action_set_mac, mac_addr)), 6733 .call = parse_vc_conf, 6734 }, 6735 [ACTION_INC_TCP_SEQ] = { 6736 .name = "inc_tcp_seq", 6737 .help = "increase TCP sequence number", 6738 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 6739 .next = NEXT(action_inc_tcp_seq), 6740 .call = parse_vc, 6741 }, 6742 [ACTION_INC_TCP_SEQ_VALUE] = { 6743 .name = "value", 6744 .help = "the value to increase TCP sequence number by", 6745 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 6746 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 6747 .call = parse_vc_conf, 6748 }, 6749 [ACTION_DEC_TCP_SEQ] = { 6750 .name = "dec_tcp_seq", 6751 .help = "decrease TCP sequence number", 6752 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 6753 .next = NEXT(action_dec_tcp_seq), 6754 .call = parse_vc, 6755 }, 6756 [ACTION_DEC_TCP_SEQ_VALUE] = { 6757 .name = "value", 6758 .help = "the value to decrease TCP sequence number by", 6759 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 6760 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 6761 .call = parse_vc_conf, 6762 }, 6763 [ACTION_INC_TCP_ACK] = { 6764 .name = "inc_tcp_ack", 6765 .help = "increase TCP acknowledgment number", 6766 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 6767 .next = NEXT(action_inc_tcp_ack), 6768 .call = parse_vc, 6769 }, 6770 [ACTION_INC_TCP_ACK_VALUE] = { 6771 .name = "value", 6772 .help = "the value to increase TCP acknowledgment number by", 6773 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 6774 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 6775 .call = parse_vc_conf, 6776 }, 6777 [ACTION_DEC_TCP_ACK] = { 6778 .name = "dec_tcp_ack", 6779 .help = "decrease TCP acknowledgment number", 6780 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 6781 .next = NEXT(action_dec_tcp_ack), 6782 .call = parse_vc, 6783 }, 6784 [ACTION_DEC_TCP_ACK_VALUE] = { 6785 .name = "value", 6786 .help = "the value to decrease TCP acknowledgment number by", 6787 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 6788 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 6789 .call = parse_vc_conf, 6790 }, 6791 [ACTION_RAW_ENCAP] = { 6792 .name = "raw_encap", 6793 .help = "encapsulation data, defined by set raw_encap", 6794 .priv = PRIV_ACTION(RAW_ENCAP, 6795 sizeof(struct action_raw_encap_data)), 6796 .next = NEXT(action_raw_encap), 6797 .call = parse_vc_action_raw_encap, 6798 }, 6799 [ACTION_RAW_ENCAP_INDEX] = { 6800 .name = "index", 6801 .help = "the index of raw_encap_confs", 6802 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 6803 }, 6804 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 6805 .name = "{index}", 6806 .type = "UNSIGNED", 6807 .help = "unsigned integer value", 6808 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6809 .call = parse_vc_action_raw_encap_index, 6810 .comp = comp_set_raw_index, 6811 }, 6812 [ACTION_RAW_DECAP] = { 6813 .name = "raw_decap", 6814 .help = "decapsulation data, defined by set raw_encap", 6815 .priv = PRIV_ACTION(RAW_DECAP, 6816 sizeof(struct action_raw_decap_data)), 6817 .next = NEXT(action_raw_decap), 6818 .call = parse_vc_action_raw_decap, 6819 }, 6820 [ACTION_RAW_DECAP_INDEX] = { 6821 .name = "index", 6822 .help = "the index of raw_encap_confs", 6823 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 6824 }, 6825 [ACTION_RAW_DECAP_INDEX_VALUE] = { 6826 .name = "{index}", 6827 .type = "UNSIGNED", 6828 .help = "unsigned integer value", 6829 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6830 .call = parse_vc_action_raw_decap_index, 6831 .comp = comp_set_raw_index, 6832 }, 6833 [ACTION_MODIFY_FIELD] = { 6834 .name = "modify_field", 6835 .help = "modify destination field with data from source field", 6836 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 6837 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 6838 .call = parse_vc, 6839 }, 6840 [ACTION_MODIFY_FIELD_OP] = { 6841 .name = "op", 6842 .help = "operation type", 6843 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 6844 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 6845 .call = parse_vc_conf, 6846 }, 6847 [ACTION_MODIFY_FIELD_OP_VALUE] = { 6848 .name = "{operation}", 6849 .help = "operation type value", 6850 .call = parse_vc_modify_field_op, 6851 .comp = comp_set_modify_field_op, 6852 }, 6853 [ACTION_MODIFY_FIELD_DST_TYPE] = { 6854 .name = "dst_type", 6855 .help = "destination field type", 6856 .next = NEXT(action_modify_field_dst, 6857 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 6858 .call = parse_vc_conf, 6859 }, 6860 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 6861 .name = "{dst_type}", 6862 .help = "destination field type value", 6863 .call = parse_vc_modify_field_id, 6864 .comp = comp_set_modify_field_id, 6865 }, 6866 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 6867 .name = "dst_level", 6868 .help = "destination field level", 6869 .next = NEXT(action_modify_field_dst, 6870 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), 6871 .call = parse_vc_conf, 6872 }, 6873 [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { 6874 .name = "{dst_level}", 6875 .help = "destination field level value", 6876 .call = parse_vc_modify_field_level, 6877 .comp = comp_none, 6878 }, 6879 [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { 6880 .name = "dst_tag_index", 6881 .help = "destination field tag array", 6882 .next = NEXT(action_modify_field_dst, 6883 NEXT_ENTRY(COMMON_UNSIGNED)), 6884 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 6885 dst.tag_index)), 6886 .call = parse_vc_conf, 6887 }, 6888 [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { 6889 .name = "dst_type_id", 6890 .help = "destination field type ID", 6891 .next = NEXT(action_modify_field_dst, 6892 NEXT_ENTRY(COMMON_UNSIGNED)), 6893 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 6894 dst.type)), 6895 .call = parse_vc_conf, 6896 }, 6897 [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { 6898 .name = "dst_class", 6899 .help = "destination field class ID", 6900 .next = NEXT(action_modify_field_dst, 6901 NEXT_ENTRY(COMMON_UNSIGNED)), 6902 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 6903 dst.class_id)), 6904 .call = parse_vc_conf, 6905 }, 6906 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 6907 .name = "dst_offset", 6908 .help = "destination field bit offset", 6909 .next = NEXT(action_modify_field_dst, 6910 NEXT_ENTRY(COMMON_UNSIGNED)), 6911 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 6912 dst.offset)), 6913 .call = parse_vc_conf, 6914 }, 6915 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 6916 .name = "src_type", 6917 .help = "source field type", 6918 .next = NEXT(action_modify_field_src, 6919 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 6920 .call = parse_vc_conf, 6921 }, 6922 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 6923 .name = "{src_type}", 6924 .help = "source field type value", 6925 .call = parse_vc_modify_field_id, 6926 .comp = comp_set_modify_field_id, 6927 }, 6928 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 6929 .name = "src_level", 6930 .help = "source field level", 6931 .next = NEXT(action_modify_field_src, 6932 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), 6933 .call = parse_vc_conf, 6934 }, 6935 [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { 6936 .name = "{src_level}", 6937 .help = "source field level value", 6938 .call = parse_vc_modify_field_level, 6939 .comp = comp_none, 6940 }, 6941 [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { 6942 .name = "stc_tag_index", 6943 .help = "source field tag array", 6944 .next = NEXT(action_modify_field_src, 6945 NEXT_ENTRY(COMMON_UNSIGNED)), 6946 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 6947 src.tag_index)), 6948 .call = parse_vc_conf, 6949 }, 6950 [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { 6951 .name = "src_type_id", 6952 .help = "source field type ID", 6953 .next = NEXT(action_modify_field_src, 6954 NEXT_ENTRY(COMMON_UNSIGNED)), 6955 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 6956 src.type)), 6957 .call = parse_vc_conf, 6958 }, 6959 [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { 6960 .name = "src_class", 6961 .help = "source field class ID", 6962 .next = NEXT(action_modify_field_src, 6963 NEXT_ENTRY(COMMON_UNSIGNED)), 6964 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 6965 src.class_id)), 6966 .call = parse_vc_conf, 6967 }, 6968 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 6969 .name = "src_offset", 6970 .help = "source field bit offset", 6971 .next = NEXT(action_modify_field_src, 6972 NEXT_ENTRY(COMMON_UNSIGNED)), 6973 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 6974 src.offset)), 6975 .call = parse_vc_conf, 6976 }, 6977 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 6978 .name = "src_value", 6979 .help = "source immediate value", 6980 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 6981 NEXT_ENTRY(COMMON_HEX)), 6982 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6983 ARGS_ENTRY_ARB(0, 0), 6984 ARGS_ENTRY(struct rte_flow_action_modify_field, 6985 src.value)), 6986 .call = parse_vc_conf, 6987 }, 6988 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 6989 .name = "src_ptr", 6990 .help = "pointer to source immediate value", 6991 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 6992 NEXT_ENTRY(COMMON_HEX)), 6993 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 6994 src.pvalue), 6995 ARGS_ENTRY_ARB(0, 0), 6996 ARGS_ENTRY_ARB 6997 (sizeof(struct rte_flow_action_modify_field), 6998 ACTION_MODIFY_PATTERN_SIZE)), 6999 .call = parse_vc_conf, 7000 }, 7001 [ACTION_MODIFY_FIELD_WIDTH] = { 7002 .name = "width", 7003 .help = "number of bits to copy", 7004 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7005 NEXT_ENTRY(COMMON_UNSIGNED)), 7006 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7007 width)), 7008 .call = parse_vc_conf, 7009 }, 7010 [ACTION_SEND_TO_KERNEL] = { 7011 .name = "send_to_kernel", 7012 .help = "send packets to kernel", 7013 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 7014 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7015 .call = parse_vc, 7016 }, 7017 [ACTION_IPV6_EXT_REMOVE] = { 7018 .name = "ipv6_ext_remove", 7019 .help = "IPv6 extension type, defined by set ipv6_ext_remove", 7020 .priv = PRIV_ACTION(IPV6_EXT_REMOVE, 7021 sizeof(struct action_ipv6_ext_remove_data)), 7022 .next = NEXT(action_ipv6_ext_remove), 7023 .call = parse_vc_action_ipv6_ext_remove, 7024 }, 7025 [ACTION_IPV6_EXT_REMOVE_INDEX] = { 7026 .name = "index", 7027 .help = "the index of ipv6_ext_remove", 7028 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), 7029 }, 7030 [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { 7031 .name = "{index}", 7032 .type = "UNSIGNED", 7033 .help = "unsigned integer value", 7034 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7035 .call = parse_vc_action_ipv6_ext_remove_index, 7036 .comp = comp_set_ipv6_ext_index, 7037 }, 7038 [ACTION_IPV6_EXT_PUSH] = { 7039 .name = "ipv6_ext_push", 7040 .help = "IPv6 extension data, defined by set ipv6_ext_push", 7041 .priv = PRIV_ACTION(IPV6_EXT_PUSH, 7042 sizeof(struct action_ipv6_ext_push_data)), 7043 .next = NEXT(action_ipv6_ext_push), 7044 .call = parse_vc_action_ipv6_ext_push, 7045 }, 7046 [ACTION_IPV6_EXT_PUSH_INDEX] = { 7047 .name = "index", 7048 .help = "the index of ipv6_ext_push", 7049 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), 7050 }, 7051 [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { 7052 .name = "{index}", 7053 .type = "UNSIGNED", 7054 .help = "unsigned integer value", 7055 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7056 .call = parse_vc_action_ipv6_ext_push_index, 7057 .comp = comp_set_ipv6_ext_index, 7058 }, 7059 [ACTION_NAT64] = { 7060 .name = "nat64", 7061 .help = "NAT64 IP headers translation", 7062 .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), 7063 .next = NEXT(action_nat64), 7064 .call = parse_vc, 7065 }, 7066 [ACTION_NAT64_MODE] = { 7067 .name = "type", 7068 .help = "NAT64 translation type", 7069 .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), 7070 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), 7071 .call = parse_vc_conf, 7072 }, 7073 /* Top level command. */ 7074 [SET] = { 7075 .name = "set", 7076 .help = "set raw encap/decap/sample data", 7077 .type = "set raw_encap|raw_decap <index> <pattern>" 7078 " or set sample_actions <index> <action>", 7079 .next = NEXT(NEXT_ENTRY 7080 (SET_RAW_ENCAP, 7081 SET_RAW_DECAP, 7082 SET_SAMPLE_ACTIONS, 7083 SET_IPV6_EXT_REMOVE, 7084 SET_IPV6_EXT_PUSH)), 7085 .call = parse_set_init, 7086 }, 7087 /* Sub-level commands. */ 7088 [SET_RAW_ENCAP] = { 7089 .name = "raw_encap", 7090 .help = "set raw encap data", 7091 .next = NEXT(next_set_raw), 7092 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7093 (offsetof(struct buffer, port), 7094 sizeof(((struct buffer *)0)->port), 7095 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7096 .call = parse_set_raw_encap_decap, 7097 }, 7098 [SET_RAW_DECAP] = { 7099 .name = "raw_decap", 7100 .help = "set raw decap data", 7101 .next = NEXT(next_set_raw), 7102 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7103 (offsetof(struct buffer, port), 7104 sizeof(((struct buffer *)0)->port), 7105 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7106 .call = parse_set_raw_encap_decap, 7107 }, 7108 [SET_RAW_INDEX] = { 7109 .name = "{index}", 7110 .type = "COMMON_UNSIGNED", 7111 .help = "index of raw_encap/raw_decap data", 7112 .next = NEXT(next_item), 7113 .call = parse_port, 7114 }, 7115 [SET_SAMPLE_INDEX] = { 7116 .name = "{index}", 7117 .type = "UNSIGNED", 7118 .help = "index of sample actions", 7119 .next = NEXT(next_action_sample), 7120 .call = parse_port, 7121 }, 7122 [SET_SAMPLE_ACTIONS] = { 7123 .name = "sample_actions", 7124 .help = "set sample actions list", 7125 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 7126 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7127 (offsetof(struct buffer, port), 7128 sizeof(((struct buffer *)0)->port), 7129 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 7130 .call = parse_set_sample_action, 7131 }, 7132 [SET_IPV6_EXT_PUSH] = { 7133 .name = "ipv6_ext_push", 7134 .help = "set IPv6 extension header", 7135 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7136 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7137 (offsetof(struct buffer, port), 7138 sizeof(((struct buffer *)0)->port), 7139 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7140 .call = parse_set_ipv6_ext_action, 7141 }, 7142 [SET_IPV6_EXT_REMOVE] = { 7143 .name = "ipv6_ext_remove", 7144 .help = "set IPv6 extension header", 7145 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7146 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7147 (offsetof(struct buffer, port), 7148 sizeof(((struct buffer *)0)->port), 7149 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7150 .call = parse_set_ipv6_ext_action, 7151 }, 7152 [SET_IPV6_EXT_INDEX] = { 7153 .name = "{index}", 7154 .type = "UNSIGNED", 7155 .help = "index of ipv6 extension push/remove actions", 7156 .next = NEXT(item_ipv6_push_ext), 7157 .call = parse_port, 7158 }, 7159 [ITEM_IPV6_PUSH_REMOVE_EXT] = { 7160 .name = "ipv6_ext", 7161 .help = "set IPv6 extension header", 7162 .priv = PRIV_ITEM(IPV6_EXT, 7163 sizeof(struct rte_flow_item_ipv6_ext)), 7164 .next = NEXT(item_ipv6_push_ext_type), 7165 .call = parse_vc, 7166 }, 7167 [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { 7168 .name = "type", 7169 .help = "set IPv6 extension type", 7170 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 7171 next_hdr)), 7172 .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), 7173 item_param), 7174 }, 7175 [ACTION_SET_TAG] = { 7176 .name = "set_tag", 7177 .help = "set tag", 7178 .priv = PRIV_ACTION(SET_TAG, 7179 sizeof(struct rte_flow_action_set_tag)), 7180 .next = NEXT(action_set_tag), 7181 .call = parse_vc, 7182 }, 7183 [ACTION_SET_TAG_INDEX] = { 7184 .name = "index", 7185 .help = "index of tag array", 7186 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7187 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 7188 .call = parse_vc_conf, 7189 }, 7190 [ACTION_SET_TAG_DATA] = { 7191 .name = "data", 7192 .help = "tag value", 7193 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7194 .args = ARGS(ARGS_ENTRY 7195 (struct rte_flow_action_set_tag, data)), 7196 .call = parse_vc_conf, 7197 }, 7198 [ACTION_SET_TAG_MASK] = { 7199 .name = "mask", 7200 .help = "mask for tag value", 7201 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7202 .args = ARGS(ARGS_ENTRY 7203 (struct rte_flow_action_set_tag, mask)), 7204 .call = parse_vc_conf, 7205 }, 7206 [ACTION_SET_META] = { 7207 .name = "set_meta", 7208 .help = "set metadata", 7209 .priv = PRIV_ACTION(SET_META, 7210 sizeof(struct rte_flow_action_set_meta)), 7211 .next = NEXT(action_set_meta), 7212 .call = parse_vc_action_set_meta, 7213 }, 7214 [ACTION_SET_META_DATA] = { 7215 .name = "data", 7216 .help = "metadata value", 7217 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7218 .args = ARGS(ARGS_ENTRY 7219 (struct rte_flow_action_set_meta, data)), 7220 .call = parse_vc_conf, 7221 }, 7222 [ACTION_SET_META_MASK] = { 7223 .name = "mask", 7224 .help = "mask for metadata value", 7225 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7226 .args = ARGS(ARGS_ENTRY 7227 (struct rte_flow_action_set_meta, mask)), 7228 .call = parse_vc_conf, 7229 }, 7230 [ACTION_SET_IPV4_DSCP] = { 7231 .name = "set_ipv4_dscp", 7232 .help = "set DSCP value", 7233 .priv = PRIV_ACTION(SET_IPV4_DSCP, 7234 sizeof(struct rte_flow_action_set_dscp)), 7235 .next = NEXT(action_set_ipv4_dscp), 7236 .call = parse_vc, 7237 }, 7238 [ACTION_SET_IPV4_DSCP_VALUE] = { 7239 .name = "dscp_value", 7240 .help = "new IPv4 DSCP value to set", 7241 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7242 .args = ARGS(ARGS_ENTRY 7243 (struct rte_flow_action_set_dscp, dscp)), 7244 .call = parse_vc_conf, 7245 }, 7246 [ACTION_SET_IPV6_DSCP] = { 7247 .name = "set_ipv6_dscp", 7248 .help = "set DSCP value", 7249 .priv = PRIV_ACTION(SET_IPV6_DSCP, 7250 sizeof(struct rte_flow_action_set_dscp)), 7251 .next = NEXT(action_set_ipv6_dscp), 7252 .call = parse_vc, 7253 }, 7254 [ACTION_SET_IPV6_DSCP_VALUE] = { 7255 .name = "dscp_value", 7256 .help = "new IPv6 DSCP value to set", 7257 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7258 .args = ARGS(ARGS_ENTRY 7259 (struct rte_flow_action_set_dscp, dscp)), 7260 .call = parse_vc_conf, 7261 }, 7262 [ACTION_AGE] = { 7263 .name = "age", 7264 .help = "set a specific metadata header", 7265 .next = NEXT(action_age), 7266 .priv = PRIV_ACTION(AGE, 7267 sizeof(struct rte_flow_action_age)), 7268 .call = parse_vc, 7269 }, 7270 [ACTION_AGE_TIMEOUT] = { 7271 .name = "timeout", 7272 .help = "flow age timeout value", 7273 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 7274 timeout, 24)), 7275 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 7276 .call = parse_vc_conf, 7277 }, 7278 [ACTION_AGE_UPDATE] = { 7279 .name = "age_update", 7280 .help = "update aging parameter", 7281 .next = NEXT(action_age_update), 7282 .priv = PRIV_ACTION(AGE, 7283 sizeof(struct rte_flow_update_age)), 7284 .call = parse_vc, 7285 }, 7286 [ACTION_AGE_UPDATE_TIMEOUT] = { 7287 .name = "timeout", 7288 .help = "age timeout update value", 7289 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7290 timeout, 24)), 7291 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7292 .call = parse_vc_conf_timeout, 7293 }, 7294 [ACTION_AGE_UPDATE_TOUCH] = { 7295 .name = "touch", 7296 .help = "this flow is touched", 7297 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), 7298 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7299 touch, 1)), 7300 .call = parse_vc_conf, 7301 }, 7302 [ACTION_SAMPLE] = { 7303 .name = "sample", 7304 .help = "set a sample action", 7305 .next = NEXT(action_sample), 7306 .priv = PRIV_ACTION(SAMPLE, 7307 sizeof(struct action_sample_data)), 7308 .call = parse_vc_action_sample, 7309 }, 7310 [ACTION_SAMPLE_RATIO] = { 7311 .name = "ratio", 7312 .help = "flow sample ratio value", 7313 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 7314 .args = ARGS(ARGS_ENTRY_ARB 7315 (offsetof(struct action_sample_data, conf) + 7316 offsetof(struct rte_flow_action_sample, ratio), 7317 sizeof(((struct rte_flow_action_sample *)0)-> 7318 ratio))), 7319 }, 7320 [ACTION_SAMPLE_INDEX] = { 7321 .name = "index", 7322 .help = "the index of sample actions list", 7323 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 7324 }, 7325 [ACTION_SAMPLE_INDEX_VALUE] = { 7326 .name = "{index}", 7327 .type = "COMMON_UNSIGNED", 7328 .help = "unsigned integer value", 7329 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7330 .call = parse_vc_action_sample_index, 7331 .comp = comp_set_sample_index, 7332 }, 7333 [ACTION_CONNTRACK] = { 7334 .name = "conntrack", 7335 .help = "create a conntrack object", 7336 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7337 .priv = PRIV_ACTION(CONNTRACK, 7338 sizeof(struct rte_flow_action_conntrack)), 7339 .call = parse_vc, 7340 }, 7341 [ACTION_CONNTRACK_UPDATE] = { 7342 .name = "conntrack_update", 7343 .help = "update a conntrack object", 7344 .next = NEXT(action_update_conntrack), 7345 .priv = PRIV_ACTION(CONNTRACK, 7346 sizeof(struct rte_flow_modify_conntrack)), 7347 .call = parse_vc, 7348 }, 7349 [ACTION_CONNTRACK_UPDATE_DIR] = { 7350 .name = "dir", 7351 .help = "update a conntrack object direction", 7352 .next = NEXT(action_update_conntrack), 7353 .call = parse_vc_action_conntrack_update, 7354 }, 7355 [ACTION_CONNTRACK_UPDATE_CTX] = { 7356 .name = "ctx", 7357 .help = "update a conntrack object context", 7358 .next = NEXT(action_update_conntrack), 7359 .call = parse_vc_action_conntrack_update, 7360 }, 7361 [ACTION_PORT_REPRESENTOR] = { 7362 .name = "port_representor", 7363 .help = "at embedded switch level, send matching traffic to the given ethdev", 7364 .priv = PRIV_ACTION(PORT_REPRESENTOR, 7365 sizeof(struct rte_flow_action_ethdev)), 7366 .next = NEXT(action_port_representor), 7367 .call = parse_vc, 7368 }, 7369 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 7370 .name = "port_id", 7371 .help = "ethdev port ID", 7372 .next = NEXT(action_port_representor, 7373 NEXT_ENTRY(COMMON_UNSIGNED)), 7374 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7375 port_id)), 7376 .call = parse_vc_conf, 7377 }, 7378 [ACTION_REPRESENTED_PORT] = { 7379 .name = "represented_port", 7380 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 7381 .priv = PRIV_ACTION(REPRESENTED_PORT, 7382 sizeof(struct rte_flow_action_ethdev)), 7383 .next = NEXT(action_represented_port), 7384 .call = parse_vc, 7385 }, 7386 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 7387 .name = "ethdev_port_id", 7388 .help = "ethdev port ID", 7389 .next = NEXT(action_represented_port, 7390 NEXT_ENTRY(COMMON_UNSIGNED)), 7391 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7392 port_id)), 7393 .call = parse_vc_conf, 7394 }, 7395 /* Indirect action destroy arguments. */ 7396 [INDIRECT_ACTION_DESTROY_ID] = { 7397 .name = "action_id", 7398 .help = "specify a indirect action id to destroy", 7399 .next = NEXT(next_ia_destroy_attr, 7400 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7401 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 7402 args.ia_destroy.action_id)), 7403 .call = parse_ia_destroy, 7404 }, 7405 /* Indirect action create arguments. */ 7406 [INDIRECT_ACTION_CREATE_ID] = { 7407 .name = "action_id", 7408 .help = "specify a indirect action id to create", 7409 .next = NEXT(next_ia_create_attr, 7410 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7411 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 7412 }, 7413 [ACTION_INDIRECT] = { 7414 .name = "indirect", 7415 .help = "apply indirect action by id", 7416 .priv = PRIV_ACTION(INDIRECT, 0), 7417 .next = NEXT(next_ia), 7418 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7419 .call = parse_vc, 7420 }, 7421 [ACTION_INDIRECT_LIST] = { 7422 .name = "indirect_list", 7423 .help = "apply indirect list action by id", 7424 .priv = PRIV_ACTION(INDIRECT_LIST, 7425 sizeof(struct 7426 rte_flow_action_indirect_list)), 7427 .next = NEXT(next_ial), 7428 .call = parse_vc, 7429 }, 7430 [ACTION_INDIRECT_LIST_HANDLE] = { 7431 .name = "handle", 7432 .help = "indirect list handle", 7433 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), 7434 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7435 }, 7436 [ACTION_INDIRECT_LIST_CONF] = { 7437 .name = "conf", 7438 .help = "indirect list configuration", 7439 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), 7440 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7441 }, 7442 [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { 7443 .type = "UNSIGNED", 7444 .help = "unsigned integer value", 7445 .call = parse_indlst_id2ptr, 7446 }, 7447 [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { 7448 .type = "UNSIGNED", 7449 .help = "unsigned integer value", 7450 .call = parse_indlst_id2ptr, 7451 }, 7452 [ACTION_SHARED_INDIRECT] = { 7453 .name = "shared_indirect", 7454 .help = "apply indirect action by id and port", 7455 .priv = PRIV_ACTION(INDIRECT, 0), 7456 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), 7457 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), 7458 ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7459 .call = parse_vc, 7460 }, 7461 [INDIRECT_ACTION_PORT] = { 7462 .name = "{indirect_action_port}", 7463 .type = "INDIRECT_ACTION_PORT", 7464 .help = "indirect action port", 7465 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 7466 .call = parse_ia_port, 7467 .comp = comp_none, 7468 }, 7469 [INDIRECT_ACTION_ID2PTR] = { 7470 .name = "{action_id}", 7471 .type = "INDIRECT_ACTION_ID", 7472 .help = "indirect action id", 7473 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7474 .call = parse_ia_id2ptr, 7475 .comp = comp_none, 7476 }, 7477 [INDIRECT_ACTION_INGRESS] = { 7478 .name = "ingress", 7479 .help = "affect rule to ingress", 7480 .next = NEXT(next_ia_create_attr), 7481 .call = parse_ia, 7482 }, 7483 [INDIRECT_ACTION_EGRESS] = { 7484 .name = "egress", 7485 .help = "affect rule to egress", 7486 .next = NEXT(next_ia_create_attr), 7487 .call = parse_ia, 7488 }, 7489 [INDIRECT_ACTION_TRANSFER] = { 7490 .name = "transfer", 7491 .help = "affect rule to transfer", 7492 .next = NEXT(next_ia_create_attr), 7493 .call = parse_ia, 7494 }, 7495 [INDIRECT_ACTION_SPEC] = { 7496 .name = "action", 7497 .help = "specify action to create indirect handle", 7498 .next = NEXT(next_action), 7499 }, 7500 [INDIRECT_ACTION_LIST] = { 7501 .name = "list", 7502 .help = "specify actions for indirect handle list", 7503 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7504 .call = parse_ia, 7505 }, 7506 [INDIRECT_ACTION_FLOW_CONF] = { 7507 .name = "flow_conf", 7508 .help = "specify actions configuration for indirect handle list", 7509 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7510 .call = parse_ia, 7511 }, 7512 [ACTION_POL_G] = { 7513 .name = "g_actions", 7514 .help = "submit a list of associated actions for green", 7515 .next = NEXT(next_action), 7516 .call = parse_mp, 7517 }, 7518 [ACTION_POL_Y] = { 7519 .name = "y_actions", 7520 .help = "submit a list of associated actions for yellow", 7521 .next = NEXT(next_action), 7522 }, 7523 [ACTION_POL_R] = { 7524 .name = "r_actions", 7525 .help = "submit a list of associated actions for red", 7526 .next = NEXT(next_action), 7527 }, 7528 [ACTION_QUOTA_CREATE] = { 7529 .name = "quota_create", 7530 .help = "create quota action", 7531 .priv = PRIV_ACTION(QUOTA, 7532 sizeof(struct rte_flow_action_quota)), 7533 .next = NEXT(action_quota_create), 7534 .call = parse_vc 7535 }, 7536 [ACTION_QUOTA_CREATE_LIMIT] = { 7537 .name = "limit", 7538 .help = "quota limit", 7539 .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), 7540 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), 7541 .call = parse_vc_conf 7542 }, 7543 [ACTION_QUOTA_CREATE_MODE] = { 7544 .name = "mode", 7545 .help = "quota mode", 7546 .next = NEXT(action_quota_create, 7547 NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), 7548 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), 7549 .call = parse_vc_conf 7550 }, 7551 [ACTION_QUOTA_CREATE_MODE_NAME] = { 7552 .name = "mode_name", 7553 .help = "quota mode name", 7554 .call = parse_quota_mode_name, 7555 .comp = comp_quota_mode_name 7556 }, 7557 [ACTION_QUOTA_QU] = { 7558 .name = "quota_update", 7559 .help = "update quota action", 7560 .priv = PRIV_ACTION(QUOTA, 7561 sizeof(struct rte_flow_update_quota)), 7562 .next = NEXT(action_quota_update), 7563 .call = parse_vc 7564 }, 7565 [ACTION_QUOTA_QU_LIMIT] = { 7566 .name = "limit", 7567 .help = "quota limit", 7568 .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7569 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), 7570 .call = parse_vc_conf 7571 }, 7572 [ACTION_QUOTA_QU_UPDATE_OP] = { 7573 .name = "update_op", 7574 .help = "query update op SET|ADD", 7575 .next = NEXT(action_quota_update, 7576 NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), 7577 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), 7578 .call = parse_vc_conf 7579 }, 7580 [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { 7581 .name = "update_op_name", 7582 .help = "quota update op name", 7583 .call = parse_quota_update_name, 7584 .comp = comp_quota_update_name 7585 }, 7586 7587 /* Top-level command. */ 7588 [ADD] = { 7589 .name = "add", 7590 .type = "port meter policy {port_id} {arg}", 7591 .help = "add port meter policy", 7592 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 7593 .call = parse_init, 7594 }, 7595 /* Sub-level commands. */ 7596 [ITEM_POL_PORT] = { 7597 .name = "port", 7598 .help = "add port meter policy", 7599 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 7600 }, 7601 [ITEM_POL_METER] = { 7602 .name = "meter", 7603 .help = "add port meter policy", 7604 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 7605 }, 7606 [ITEM_POL_POLICY] = { 7607 .name = "policy", 7608 .help = "add port meter policy", 7609 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 7610 NEXT_ENTRY(ACTION_POL_Y), 7611 NEXT_ENTRY(ACTION_POL_G), 7612 NEXT_ENTRY(COMMON_POLICY_ID), 7613 NEXT_ENTRY(COMMON_PORT_ID)), 7614 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 7615 ARGS_ENTRY(struct buffer, port)), 7616 .call = parse_mp, 7617 }, 7618 [ITEM_AGGR_AFFINITY] = { 7619 .name = "aggr_affinity", 7620 .help = "match on the aggregated port receiving the packets", 7621 .priv = PRIV_ITEM(AGGR_AFFINITY, 7622 sizeof(struct rte_flow_item_aggr_affinity)), 7623 .next = NEXT(item_aggr_affinity), 7624 .call = parse_vc, 7625 }, 7626 [ITEM_AGGR_AFFINITY_VALUE] = { 7627 .name = "affinity", 7628 .help = "aggregated affinity value", 7629 .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), 7630 item_param), 7631 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, 7632 affinity)), 7633 }, 7634 [ITEM_TX_QUEUE] = { 7635 .name = "tx_queue", 7636 .help = "match on the tx queue of send packet", 7637 .priv = PRIV_ITEM(TX_QUEUE, 7638 sizeof(struct rte_flow_item_tx_queue)), 7639 .next = NEXT(item_tx_queue), 7640 .call = parse_vc, 7641 }, 7642 [ITEM_TX_QUEUE_VALUE] = { 7643 .name = "tx_queue_value", 7644 .help = "tx queue value", 7645 .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), 7646 item_param), 7647 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, 7648 tx_queue)), 7649 }, 7650 }; 7651 7652 /** Remove and return last entry from argument stack. */ 7653 static const struct arg * 7654 pop_args(struct context *ctx) 7655 { 7656 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 7657 } 7658 7659 /** Add entry on top of the argument stack. */ 7660 static int 7661 push_args(struct context *ctx, const struct arg *arg) 7662 { 7663 if (ctx->args_num == CTX_STACK_SIZE) 7664 return -1; 7665 ctx->args[ctx->args_num++] = arg; 7666 return 0; 7667 } 7668 7669 /** Spread value into buffer according to bit-mask. */ 7670 static size_t 7671 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 7672 { 7673 uint32_t i = arg->size; 7674 uint32_t end = 0; 7675 int sub = 1; 7676 int add = 0; 7677 size_t len = 0; 7678 7679 if (!arg->mask) 7680 return 0; 7681 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 7682 if (!arg->hton) { 7683 i = 0; 7684 end = arg->size; 7685 sub = 0; 7686 add = 1; 7687 } 7688 #endif 7689 while (i != end) { 7690 unsigned int shift = 0; 7691 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 7692 7693 for (shift = 0; arg->mask[i] >> shift; ++shift) { 7694 if (!(arg->mask[i] & (1 << shift))) 7695 continue; 7696 ++len; 7697 if (!dst) 7698 continue; 7699 *buf &= ~(1 << shift); 7700 *buf |= (val & 1) << shift; 7701 val >>= 1; 7702 } 7703 i += add; 7704 } 7705 return len; 7706 } 7707 7708 /** Compare a string with a partial one of a given length. */ 7709 static int 7710 strcmp_partial(const char *full, const char *partial, size_t partial_len) 7711 { 7712 int r = strncmp(full, partial, partial_len); 7713 7714 if (r) 7715 return r; 7716 if (strlen(full) <= partial_len) 7717 return 0; 7718 return full[partial_len]; 7719 } 7720 7721 /** 7722 * Parse a prefix length and generate a bit-mask. 7723 * 7724 * Last argument (ctx->args) is retrieved to determine mask size, storage 7725 * location and whether the result must use network byte ordering. 7726 */ 7727 static int 7728 parse_prefix(struct context *ctx, const struct token *token, 7729 const char *str, unsigned int len, 7730 void *buf, unsigned int size) 7731 { 7732 const struct arg *arg = pop_args(ctx); 7733 static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff"; 7734 char *end; 7735 uintmax_t u; 7736 unsigned int bytes; 7737 unsigned int extra; 7738 7739 (void)token; 7740 /* Argument is expected. */ 7741 if (!arg) 7742 return -1; 7743 errno = 0; 7744 u = strtoumax(str, &end, 0); 7745 if (errno || (size_t)(end - str) != len) 7746 goto error; 7747 if (arg->mask) { 7748 uintmax_t v = 0; 7749 7750 extra = arg_entry_bf_fill(NULL, 0, arg); 7751 if (u > extra) 7752 goto error; 7753 if (!ctx->object) 7754 return len; 7755 extra -= u; 7756 while (u--) 7757 (v <<= 1, v |= 1); 7758 v <<= extra; 7759 if (!arg_entry_bf_fill(ctx->object, v, arg) || 7760 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 7761 goto error; 7762 return len; 7763 } 7764 bytes = u / 8; 7765 extra = u % 8; 7766 size = arg->size; 7767 if (bytes > size || bytes + !!extra > size) 7768 goto error; 7769 if (!ctx->object) 7770 return len; 7771 buf = (uint8_t *)ctx->object + arg->offset; 7772 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 7773 if (!arg->hton) { 7774 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 7775 memset(buf, 0x00, size - bytes); 7776 if (extra) 7777 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 7778 } else 7779 #endif 7780 { 7781 memset(buf, 0xff, bytes); 7782 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 7783 if (extra) 7784 ((uint8_t *)buf)[bytes] = conv[extra]; 7785 } 7786 if (ctx->objmask) 7787 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 7788 return len; 7789 error: 7790 push_args(ctx, arg); 7791 return -1; 7792 } 7793 7794 /** Default parsing function for token name matching. */ 7795 static int 7796 parse_default(struct context *ctx, const struct token *token, 7797 const char *str, unsigned int len, 7798 void *buf, unsigned int size) 7799 { 7800 (void)ctx; 7801 (void)buf; 7802 (void)size; 7803 if (strcmp_partial(token->name, str, len)) 7804 return -1; 7805 return len; 7806 } 7807 7808 /** Parse flow command, initialize output buffer for subsequent tokens. */ 7809 static int 7810 parse_init(struct context *ctx, const struct token *token, 7811 const char *str, unsigned int len, 7812 void *buf, unsigned int size) 7813 { 7814 struct buffer *out = buf; 7815 7816 /* Token name must match. */ 7817 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 7818 return -1; 7819 /* Nothing else to do if there is no buffer. */ 7820 if (!out) 7821 return len; 7822 /* Make sure buffer is large enough. */ 7823 if (size < sizeof(*out)) 7824 return -1; 7825 /* Initialize buffer. */ 7826 memset(out, 0x00, sizeof(*out)); 7827 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 7828 ctx->objdata = 0; 7829 ctx->object = out; 7830 ctx->objmask = NULL; 7831 return len; 7832 } 7833 7834 /** Parse tokens for indirect action commands. */ 7835 static int 7836 parse_ia(struct context *ctx, const struct token *token, 7837 const char *str, unsigned int len, 7838 void *buf, unsigned int size) 7839 { 7840 struct buffer *out = buf; 7841 7842 /* Token name must match. */ 7843 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 7844 return -1; 7845 /* Nothing else to do if there is no buffer. */ 7846 if (!out) 7847 return len; 7848 if (!out->command) { 7849 if (ctx->curr != INDIRECT_ACTION) 7850 return -1; 7851 if (sizeof(*out) > size) 7852 return -1; 7853 out->command = ctx->curr; 7854 ctx->objdata = 0; 7855 ctx->object = out; 7856 ctx->objmask = NULL; 7857 out->args.vc.data = (uint8_t *)out + size; 7858 return len; 7859 } 7860 switch (ctx->curr) { 7861 case INDIRECT_ACTION_CREATE: 7862 case INDIRECT_ACTION_UPDATE: 7863 case INDIRECT_ACTION_QUERY_UPDATE: 7864 out->args.vc.actions = 7865 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 7866 sizeof(double)); 7867 out->args.vc.attr.group = UINT32_MAX; 7868 /* fallthrough */ 7869 case INDIRECT_ACTION_QUERY: 7870 out->command = ctx->curr; 7871 ctx->objdata = 0; 7872 ctx->object = out; 7873 ctx->objmask = NULL; 7874 return len; 7875 case INDIRECT_ACTION_EGRESS: 7876 out->args.vc.attr.egress = 1; 7877 return len; 7878 case INDIRECT_ACTION_INGRESS: 7879 out->args.vc.attr.ingress = 1; 7880 return len; 7881 case INDIRECT_ACTION_TRANSFER: 7882 out->args.vc.attr.transfer = 1; 7883 return len; 7884 case INDIRECT_ACTION_QU_MODE: 7885 return len; 7886 case INDIRECT_ACTION_LIST: 7887 out->command = INDIRECT_ACTION_LIST_CREATE; 7888 return len; 7889 case INDIRECT_ACTION_FLOW_CONF: 7890 out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; 7891 return len; 7892 default: 7893 return -1; 7894 } 7895 } 7896 7897 7898 /** Parse tokens for indirect action destroy command. */ 7899 static int 7900 parse_ia_destroy(struct context *ctx, const struct token *token, 7901 const char *str, unsigned int len, 7902 void *buf, unsigned int size) 7903 { 7904 struct buffer *out = buf; 7905 uint32_t *action_id; 7906 7907 /* Token name must match. */ 7908 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 7909 return -1; 7910 /* Nothing else to do if there is no buffer. */ 7911 if (!out) 7912 return len; 7913 if (!out->command || out->command == INDIRECT_ACTION) { 7914 if (ctx->curr != INDIRECT_ACTION_DESTROY) 7915 return -1; 7916 if (sizeof(*out) > size) 7917 return -1; 7918 out->command = ctx->curr; 7919 ctx->objdata = 0; 7920 ctx->object = out; 7921 ctx->objmask = NULL; 7922 out->args.ia_destroy.action_id = 7923 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 7924 sizeof(double)); 7925 return len; 7926 } 7927 action_id = out->args.ia_destroy.action_id 7928 + out->args.ia_destroy.action_id_n++; 7929 if ((uint8_t *)action_id > (uint8_t *)out + size) 7930 return -1; 7931 ctx->objdata = 0; 7932 ctx->object = action_id; 7933 ctx->objmask = NULL; 7934 return len; 7935 } 7936 7937 /** Parse tokens for indirect action commands. */ 7938 static int 7939 parse_qia(struct context *ctx, const struct token *token, 7940 const char *str, unsigned int len, 7941 void *buf, unsigned int size) 7942 { 7943 struct buffer *out = buf; 7944 7945 /* Token name must match. */ 7946 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 7947 return -1; 7948 /* Nothing else to do if there is no buffer. */ 7949 if (!out) 7950 return len; 7951 if (!out->command) { 7952 if (ctx->curr != QUEUE) 7953 return -1; 7954 if (sizeof(*out) > size) 7955 return -1; 7956 out->args.vc.data = (uint8_t *)out + size; 7957 return len; 7958 } 7959 switch (ctx->curr) { 7960 case QUEUE_INDIRECT_ACTION: 7961 return len; 7962 case QUEUE_INDIRECT_ACTION_CREATE: 7963 case QUEUE_INDIRECT_ACTION_UPDATE: 7964 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 7965 out->args.vc.actions = 7966 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 7967 sizeof(double)); 7968 out->args.vc.attr.group = UINT32_MAX; 7969 /* fallthrough */ 7970 case QUEUE_INDIRECT_ACTION_QUERY: 7971 out->command = ctx->curr; 7972 ctx->objdata = 0; 7973 ctx->object = out; 7974 ctx->objmask = NULL; 7975 return len; 7976 case QUEUE_INDIRECT_ACTION_EGRESS: 7977 out->args.vc.attr.egress = 1; 7978 return len; 7979 case QUEUE_INDIRECT_ACTION_INGRESS: 7980 out->args.vc.attr.ingress = 1; 7981 return len; 7982 case QUEUE_INDIRECT_ACTION_TRANSFER: 7983 out->args.vc.attr.transfer = 1; 7984 return len; 7985 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 7986 return len; 7987 case QUEUE_INDIRECT_ACTION_QU_MODE: 7988 return len; 7989 case QUEUE_INDIRECT_ACTION_LIST: 7990 out->command = QUEUE_INDIRECT_ACTION_LIST_CREATE; 7991 return len; 7992 default: 7993 return -1; 7994 } 7995 } 7996 7997 /** Parse tokens for indirect action destroy command. */ 7998 static int 7999 parse_qia_destroy(struct context *ctx, const struct token *token, 8000 const char *str, unsigned int len, 8001 void *buf, unsigned int size) 8002 { 8003 struct buffer *out = buf; 8004 uint32_t *action_id; 8005 8006 /* Token name must match. */ 8007 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8008 return -1; 8009 /* Nothing else to do if there is no buffer. */ 8010 if (!out) 8011 return len; 8012 if (!out->command || out->command == QUEUE) { 8013 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 8014 return -1; 8015 if (sizeof(*out) > size) 8016 return -1; 8017 out->command = ctx->curr; 8018 ctx->objdata = 0; 8019 ctx->object = out; 8020 ctx->objmask = NULL; 8021 out->args.ia_destroy.action_id = 8022 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8023 sizeof(double)); 8024 return len; 8025 } 8026 switch (ctx->curr) { 8027 case QUEUE_INDIRECT_ACTION: 8028 out->command = ctx->curr; 8029 ctx->objdata = 0; 8030 ctx->object = out; 8031 ctx->objmask = NULL; 8032 return len; 8033 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 8034 action_id = out->args.ia_destroy.action_id 8035 + out->args.ia_destroy.action_id_n++; 8036 if ((uint8_t *)action_id > (uint8_t *)out + size) 8037 return -1; 8038 ctx->objdata = 0; 8039 ctx->object = action_id; 8040 ctx->objmask = NULL; 8041 return len; 8042 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 8043 return len; 8044 default: 8045 return -1; 8046 } 8047 } 8048 8049 /** Parse tokens for meter policy action commands. */ 8050 static int 8051 parse_mp(struct context *ctx, const struct token *token, 8052 const char *str, unsigned int len, 8053 void *buf, unsigned int size) 8054 { 8055 struct buffer *out = buf; 8056 8057 /* Token name must match. */ 8058 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8059 return -1; 8060 /* Nothing else to do if there is no buffer. */ 8061 if (!out) 8062 return len; 8063 if (!out->command) { 8064 if (ctx->curr != ITEM_POL_POLICY) 8065 return -1; 8066 if (sizeof(*out) > size) 8067 return -1; 8068 out->command = ctx->curr; 8069 ctx->objdata = 0; 8070 ctx->object = out; 8071 ctx->objmask = NULL; 8072 out->args.vc.data = (uint8_t *)out + size; 8073 return len; 8074 } 8075 switch (ctx->curr) { 8076 case ACTION_POL_G: 8077 out->args.vc.actions = 8078 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8079 sizeof(double)); 8080 out->command = ctx->curr; 8081 ctx->objdata = 0; 8082 ctx->object = out; 8083 ctx->objmask = NULL; 8084 return len; 8085 default: 8086 return -1; 8087 } 8088 } 8089 8090 /** Parse tokens for validate/create commands. */ 8091 static int 8092 parse_vc(struct context *ctx, const struct token *token, 8093 const char *str, unsigned int len, 8094 void *buf, unsigned int size) 8095 { 8096 struct buffer *out = buf; 8097 uint8_t *data; 8098 uint32_t data_size; 8099 8100 /* Token name must match. */ 8101 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8102 return -1; 8103 /* Nothing else to do if there is no buffer. */ 8104 if (!out) 8105 return len; 8106 if (!out->command) { 8107 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 8108 ctx->curr != PATTERN_TEMPLATE_CREATE && 8109 ctx->curr != ACTIONS_TEMPLATE_CREATE) 8110 return -1; 8111 if (sizeof(*out) > size) 8112 return -1; 8113 out->command = ctx->curr; 8114 ctx->objdata = 0; 8115 ctx->object = out; 8116 ctx->objmask = NULL; 8117 out->args.vc.data = (uint8_t *)out + size; 8118 return len; 8119 } 8120 ctx->objdata = 0; 8121 switch (ctx->curr) { 8122 default: 8123 ctx->object = &out->args.vc.attr; 8124 break; 8125 case VC_TUNNEL_SET: 8126 case VC_TUNNEL_MATCH: 8127 ctx->object = &out->args.vc.tunnel_ops; 8128 break; 8129 case VC_USER_ID: 8130 ctx->object = out; 8131 break; 8132 } 8133 ctx->objmask = NULL; 8134 switch (ctx->curr) { 8135 case VC_GROUP: 8136 case VC_PRIORITY: 8137 case VC_USER_ID: 8138 return len; 8139 case VC_TUNNEL_SET: 8140 out->args.vc.tunnel_ops.enabled = 1; 8141 out->args.vc.tunnel_ops.actions = 1; 8142 return len; 8143 case VC_TUNNEL_MATCH: 8144 out->args.vc.tunnel_ops.enabled = 1; 8145 out->args.vc.tunnel_ops.items = 1; 8146 return len; 8147 case VC_INGRESS: 8148 out->args.vc.attr.ingress = 1; 8149 return len; 8150 case VC_EGRESS: 8151 out->args.vc.attr.egress = 1; 8152 return len; 8153 case VC_TRANSFER: 8154 out->args.vc.attr.transfer = 1; 8155 return len; 8156 case ITEM_PATTERN: 8157 out->args.vc.pattern = 8158 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8159 sizeof(double)); 8160 ctx->object = out->args.vc.pattern; 8161 ctx->objmask = NULL; 8162 return len; 8163 case ITEM_END: 8164 if ((out->command == VALIDATE || out->command == CREATE) && 8165 ctx->last) 8166 return -1; 8167 if (out->command == PATTERN_TEMPLATE_CREATE && 8168 !ctx->last) 8169 return -1; 8170 break; 8171 case ACTIONS: 8172 out->args.vc.actions = out->args.vc.pattern ? 8173 (void *)RTE_ALIGN_CEIL((uintptr_t) 8174 (out->args.vc.pattern + 8175 out->args.vc.pattern_n), 8176 sizeof(double)) : 8177 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8178 sizeof(double)); 8179 ctx->object = out->args.vc.actions; 8180 ctx->objmask = NULL; 8181 return len; 8182 default: 8183 if (!token->priv) 8184 return -1; 8185 break; 8186 } 8187 if (!out->args.vc.actions) { 8188 const struct parse_item_priv *priv = token->priv; 8189 struct rte_flow_item *item = 8190 out->args.vc.pattern + out->args.vc.pattern_n; 8191 8192 data_size = priv->size * 3; /* spec, last, mask */ 8193 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8194 (out->args.vc.data - data_size), 8195 sizeof(double)); 8196 if ((uint8_t *)item + sizeof(*item) > data) 8197 return -1; 8198 *item = (struct rte_flow_item){ 8199 .type = priv->type, 8200 }; 8201 ++out->args.vc.pattern_n; 8202 ctx->object = item; 8203 ctx->objmask = NULL; 8204 } else { 8205 const struct parse_action_priv *priv = token->priv; 8206 struct rte_flow_action *action = 8207 out->args.vc.actions + out->args.vc.actions_n; 8208 8209 data_size = priv->size; /* configuration */ 8210 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8211 (out->args.vc.data - data_size), 8212 sizeof(double)); 8213 if ((uint8_t *)action + sizeof(*action) > data) 8214 return -1; 8215 *action = (struct rte_flow_action){ 8216 .type = priv->type, 8217 .conf = data_size ? data : NULL, 8218 }; 8219 ++out->args.vc.actions_n; 8220 ctx->object = action; 8221 ctx->objmask = NULL; 8222 } 8223 memset(data, 0, data_size); 8224 out->args.vc.data = data; 8225 ctx->objdata = data_size; 8226 return len; 8227 } 8228 8229 /** Parse pattern item parameter type. */ 8230 static int 8231 parse_vc_spec(struct context *ctx, const struct token *token, 8232 const char *str, unsigned int len, 8233 void *buf, unsigned int size) 8234 { 8235 struct buffer *out = buf; 8236 struct rte_flow_item *item; 8237 uint32_t data_size; 8238 int index; 8239 int objmask = 0; 8240 8241 (void)size; 8242 /* Token name must match. */ 8243 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8244 return -1; 8245 /* Parse parameter types. */ 8246 switch (ctx->curr) { 8247 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 8248 8249 case ITEM_PARAM_IS: 8250 index = 0; 8251 objmask = 1; 8252 break; 8253 case ITEM_PARAM_SPEC: 8254 index = 0; 8255 break; 8256 case ITEM_PARAM_LAST: 8257 index = 1; 8258 break; 8259 case ITEM_PARAM_PREFIX: 8260 /* Modify next token to expect a prefix. */ 8261 if (ctx->next_num < 2) 8262 return -1; 8263 ctx->next[ctx->next_num - 2] = prefix; 8264 /* Fall through. */ 8265 case ITEM_PARAM_MASK: 8266 index = 2; 8267 break; 8268 default: 8269 return -1; 8270 } 8271 /* Nothing else to do if there is no buffer. */ 8272 if (!out) 8273 return len; 8274 if (!out->args.vc.pattern_n) 8275 return -1; 8276 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8277 data_size = ctx->objdata / 3; /* spec, last, mask */ 8278 /* Point to selected object. */ 8279 ctx->object = out->args.vc.data + (data_size * index); 8280 if (objmask) { 8281 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 8282 item->mask = ctx->objmask; 8283 } else 8284 ctx->objmask = NULL; 8285 /* Update relevant item pointer. */ 8286 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 8287 ctx->object; 8288 return len; 8289 } 8290 8291 /** Parse action configuration field. */ 8292 static int 8293 parse_vc_conf(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 (void)size; 8300 /* Token name must match. */ 8301 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8302 return -1; 8303 /* Nothing else to do if there is no buffer. */ 8304 if (!out) 8305 return len; 8306 /* Point to selected object. */ 8307 ctx->object = out->args.vc.data; 8308 ctx->objmask = NULL; 8309 return len; 8310 } 8311 8312 /** Parse action configuration field. */ 8313 static int 8314 parse_vc_conf_timeout(struct context *ctx, const struct token *token, 8315 const char *str, unsigned int len, 8316 void *buf, unsigned int size) 8317 { 8318 struct buffer *out = buf; 8319 struct rte_flow_update_age *update; 8320 8321 (void)size; 8322 if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) 8323 return -1; 8324 /* Token name must match. */ 8325 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8326 return -1; 8327 /* Nothing else to do if there is no buffer. */ 8328 if (!out) 8329 return len; 8330 /* Point to selected object. */ 8331 ctx->object = out->args.vc.data; 8332 ctx->objmask = NULL; 8333 /* Update the timeout is valid. */ 8334 update = (struct rte_flow_update_age *)out->args.vc.data; 8335 update->timeout_valid = 1; 8336 return len; 8337 } 8338 8339 /** Parse eCPRI common header type field. */ 8340 static int 8341 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 8342 const char *str, unsigned int len, 8343 void *buf, unsigned int size) 8344 { 8345 struct rte_flow_item_ecpri *ecpri; 8346 struct rte_flow_item_ecpri *ecpri_mask; 8347 struct rte_flow_item *item; 8348 uint32_t data_size; 8349 uint8_t msg_type; 8350 struct buffer *out = buf; 8351 const struct arg *arg; 8352 8353 (void)size; 8354 /* Token name must match. */ 8355 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8356 return -1; 8357 switch (ctx->curr) { 8358 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 8359 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 8360 break; 8361 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 8362 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 8363 break; 8364 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 8365 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 8366 break; 8367 default: 8368 return -1; 8369 } 8370 if (!ctx->object) 8371 return len; 8372 arg = pop_args(ctx); 8373 if (!arg) 8374 return -1; 8375 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 8376 ecpri->hdr.common.type = msg_type; 8377 data_size = ctx->objdata / 3; /* spec, last, mask */ 8378 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 8379 (data_size * 2)); 8380 ecpri_mask->hdr.common.type = 0xFF; 8381 if (arg->hton) { 8382 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 8383 ecpri_mask->hdr.common.u32 = 8384 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 8385 } 8386 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8387 item->spec = ecpri; 8388 item->mask = ecpri_mask; 8389 return len; 8390 } 8391 8392 /** Parse L2TPv2 common header type field. */ 8393 static int 8394 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, 8395 const char *str, unsigned int len, 8396 void *buf, unsigned int size) 8397 { 8398 struct rte_flow_item_l2tpv2 *l2tpv2; 8399 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 8400 struct rte_flow_item *item; 8401 uint32_t data_size; 8402 uint16_t msg_type = 0; 8403 struct buffer *out = buf; 8404 const struct arg *arg; 8405 8406 (void)size; 8407 /* Token name must match. */ 8408 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8409 return -1; 8410 switch (ctx->curr) { 8411 case ITEM_L2TPV2_TYPE_DATA: 8412 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 8413 break; 8414 case ITEM_L2TPV2_TYPE_DATA_L: 8415 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 8416 break; 8417 case ITEM_L2TPV2_TYPE_DATA_S: 8418 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 8419 break; 8420 case ITEM_L2TPV2_TYPE_DATA_O: 8421 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 8422 break; 8423 case ITEM_L2TPV2_TYPE_DATA_L_S: 8424 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 8425 break; 8426 case ITEM_L2TPV2_TYPE_CTRL: 8427 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 8428 break; 8429 default: 8430 return -1; 8431 } 8432 if (!ctx->object) 8433 return len; 8434 arg = pop_args(ctx); 8435 if (!arg) 8436 return -1; 8437 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 8438 l2tpv2->hdr.common.flags_version |= msg_type; 8439 data_size = ctx->objdata / 3; /* spec, last, mask */ 8440 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 8441 (data_size * 2)); 8442 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 8443 if (arg->hton) { 8444 l2tpv2->hdr.common.flags_version = 8445 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 8446 l2tpv2_mask->hdr.common.flags_version = 8447 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 8448 } 8449 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8450 item->spec = l2tpv2; 8451 item->mask = l2tpv2_mask; 8452 return len; 8453 } 8454 8455 /** Parse meter color action type. */ 8456 static int 8457 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 8458 const char *str, unsigned int len, 8459 void *buf, unsigned int size) 8460 { 8461 struct rte_flow_action *action_data; 8462 struct rte_flow_action_meter_color *conf; 8463 enum rte_color color; 8464 8465 (void)buf; 8466 (void)size; 8467 /* Token name must match. */ 8468 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8469 return -1; 8470 switch (ctx->curr) { 8471 case ACTION_METER_COLOR_GREEN: 8472 color = RTE_COLOR_GREEN; 8473 break; 8474 case ACTION_METER_COLOR_YELLOW: 8475 color = RTE_COLOR_YELLOW; 8476 break; 8477 case ACTION_METER_COLOR_RED: 8478 color = RTE_COLOR_RED; 8479 break; 8480 default: 8481 return -1; 8482 } 8483 8484 if (!ctx->object) 8485 return len; 8486 action_data = ctx->object; 8487 conf = (struct rte_flow_action_meter_color *) 8488 (uintptr_t)(action_data->conf); 8489 conf->color = color; 8490 return len; 8491 } 8492 8493 /** Parse RSS action. */ 8494 static int 8495 parse_vc_action_rss(struct context *ctx, const struct token *token, 8496 const char *str, unsigned int len, 8497 void *buf, unsigned int size) 8498 { 8499 struct buffer *out = buf; 8500 struct rte_flow_action *action; 8501 struct action_rss_data *action_rss_data; 8502 unsigned int i; 8503 int ret; 8504 8505 ret = parse_vc(ctx, token, str, len, buf, size); 8506 if (ret < 0) 8507 return ret; 8508 /* Nothing else to do if there is no buffer. */ 8509 if (!out) 8510 return ret; 8511 if (!out->args.vc.actions_n) 8512 return -1; 8513 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8514 /* Point to selected object. */ 8515 ctx->object = out->args.vc.data; 8516 ctx->objmask = NULL; 8517 /* Set up default configuration. */ 8518 action_rss_data = ctx->object; 8519 *action_rss_data = (struct action_rss_data){ 8520 .conf = (struct rte_flow_action_rss){ 8521 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 8522 .level = 0, 8523 .types = rss_hf, 8524 .key_len = 0, 8525 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 8526 .key = NULL, 8527 .queue = action_rss_data->queue, 8528 }, 8529 .queue = { 0 }, 8530 }; 8531 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 8532 action_rss_data->queue[i] = i; 8533 action->conf = &action_rss_data->conf; 8534 return ret; 8535 } 8536 8537 /** 8538 * Parse func field for RSS action. 8539 * 8540 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 8541 * ACTION_RSS_FUNC_* index that called this function. 8542 */ 8543 static int 8544 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 8545 const char *str, unsigned int len, 8546 void *buf, unsigned int size) 8547 { 8548 struct action_rss_data *action_rss_data; 8549 enum rte_eth_hash_function func; 8550 8551 (void)buf; 8552 (void)size; 8553 /* Token name must match. */ 8554 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8555 return -1; 8556 switch (ctx->curr) { 8557 case ACTION_RSS_FUNC_DEFAULT: 8558 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 8559 break; 8560 case ACTION_RSS_FUNC_TOEPLITZ: 8561 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 8562 break; 8563 case ACTION_RSS_FUNC_SIMPLE_XOR: 8564 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 8565 break; 8566 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 8567 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 8568 break; 8569 default: 8570 return -1; 8571 } 8572 if (!ctx->object) 8573 return len; 8574 action_rss_data = ctx->object; 8575 action_rss_data->conf.func = func; 8576 return len; 8577 } 8578 8579 /** 8580 * Parse type field for RSS action. 8581 * 8582 * Valid tokens are type field names and the "end" token. 8583 */ 8584 static int 8585 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 8586 const char *str, unsigned int len, 8587 void *buf, unsigned int size) 8588 { 8589 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 8590 struct action_rss_data *action_rss_data; 8591 unsigned int i; 8592 8593 (void)token; 8594 (void)buf; 8595 (void)size; 8596 if (ctx->curr != ACTION_RSS_TYPE) 8597 return -1; 8598 if (!(ctx->objdata >> 16) && ctx->object) { 8599 action_rss_data = ctx->object; 8600 action_rss_data->conf.types = 0; 8601 } 8602 if (!strcmp_partial("end", str, len)) { 8603 ctx->objdata &= 0xffff; 8604 return len; 8605 } 8606 for (i = 0; rss_type_table[i].str; ++i) 8607 if (!strcmp_partial(rss_type_table[i].str, str, len)) 8608 break; 8609 if (!rss_type_table[i].str) 8610 return -1; 8611 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 8612 /* Repeat token. */ 8613 if (ctx->next_num == RTE_DIM(ctx->next)) 8614 return -1; 8615 ctx->next[ctx->next_num++] = next; 8616 if (!ctx->object) 8617 return len; 8618 action_rss_data = ctx->object; 8619 action_rss_data->conf.types |= rss_type_table[i].rss_type; 8620 return len; 8621 } 8622 8623 /** 8624 * Parse queue field for RSS action. 8625 * 8626 * Valid tokens are queue indices and the "end" token. 8627 */ 8628 static int 8629 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 8630 const char *str, unsigned int len, 8631 void *buf, unsigned int size) 8632 { 8633 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 8634 struct action_rss_data *action_rss_data; 8635 const struct arg *arg; 8636 int ret; 8637 int i; 8638 8639 (void)token; 8640 (void)buf; 8641 (void)size; 8642 if (ctx->curr != ACTION_RSS_QUEUE) 8643 return -1; 8644 i = ctx->objdata >> 16; 8645 if (!strcmp_partial("end", str, len)) { 8646 ctx->objdata &= 0xffff; 8647 goto end; 8648 } 8649 if (i >= ACTION_RSS_QUEUE_NUM) 8650 return -1; 8651 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 8652 i * sizeof(action_rss_data->queue[i]), 8653 sizeof(action_rss_data->queue[i])); 8654 if (push_args(ctx, arg)) 8655 return -1; 8656 ret = parse_int(ctx, token, str, len, NULL, 0); 8657 if (ret < 0) { 8658 pop_args(ctx); 8659 return -1; 8660 } 8661 ++i; 8662 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 8663 /* Repeat token. */ 8664 if (ctx->next_num == RTE_DIM(ctx->next)) 8665 return -1; 8666 ctx->next[ctx->next_num++] = next; 8667 end: 8668 if (!ctx->object) 8669 return len; 8670 action_rss_data = ctx->object; 8671 action_rss_data->conf.queue_num = i; 8672 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 8673 return len; 8674 } 8675 8676 /** Setup VXLAN encap configuration. */ 8677 static int 8678 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 8679 { 8680 /* Set up default configuration. */ 8681 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 8682 .conf = (struct rte_flow_action_vxlan_encap){ 8683 .definition = action_vxlan_encap_data->items, 8684 }, 8685 .items = { 8686 { 8687 .type = RTE_FLOW_ITEM_TYPE_ETH, 8688 .spec = &action_vxlan_encap_data->item_eth, 8689 .mask = &rte_flow_item_eth_mask, 8690 }, 8691 { 8692 .type = RTE_FLOW_ITEM_TYPE_VLAN, 8693 .spec = &action_vxlan_encap_data->item_vlan, 8694 .mask = &rte_flow_item_vlan_mask, 8695 }, 8696 { 8697 .type = RTE_FLOW_ITEM_TYPE_IPV4, 8698 .spec = &action_vxlan_encap_data->item_ipv4, 8699 .mask = &rte_flow_item_ipv4_mask, 8700 }, 8701 { 8702 .type = RTE_FLOW_ITEM_TYPE_UDP, 8703 .spec = &action_vxlan_encap_data->item_udp, 8704 .mask = &rte_flow_item_udp_mask, 8705 }, 8706 { 8707 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 8708 .spec = &action_vxlan_encap_data->item_vxlan, 8709 .mask = &rte_flow_item_vxlan_mask, 8710 }, 8711 { 8712 .type = RTE_FLOW_ITEM_TYPE_END, 8713 }, 8714 }, 8715 .item_eth.hdr.ether_type = 0, 8716 .item_vlan = { 8717 .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, 8718 .hdr.eth_proto = 0, 8719 }, 8720 .item_ipv4.hdr = { 8721 .src_addr = vxlan_encap_conf.ipv4_src, 8722 .dst_addr = vxlan_encap_conf.ipv4_dst, 8723 }, 8724 .item_udp.hdr = { 8725 .src_port = vxlan_encap_conf.udp_src, 8726 .dst_port = vxlan_encap_conf.udp_dst, 8727 }, 8728 .item_vxlan.hdr.flags = 0, 8729 }; 8730 memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, 8731 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 8732 memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, 8733 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 8734 if (!vxlan_encap_conf.select_ipv4) { 8735 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 8736 &vxlan_encap_conf.ipv6_src, 8737 sizeof(vxlan_encap_conf.ipv6_src)); 8738 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 8739 &vxlan_encap_conf.ipv6_dst, 8740 sizeof(vxlan_encap_conf.ipv6_dst)); 8741 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 8742 .type = RTE_FLOW_ITEM_TYPE_IPV6, 8743 .spec = &action_vxlan_encap_data->item_ipv6, 8744 .mask = &rte_flow_item_ipv6_mask, 8745 }; 8746 } 8747 if (!vxlan_encap_conf.select_vlan) 8748 action_vxlan_encap_data->items[1].type = 8749 RTE_FLOW_ITEM_TYPE_VOID; 8750 if (vxlan_encap_conf.select_tos_ttl) { 8751 if (vxlan_encap_conf.select_ipv4) { 8752 static struct rte_flow_item_ipv4 ipv4_mask_tos; 8753 8754 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 8755 sizeof(ipv4_mask_tos)); 8756 ipv4_mask_tos.hdr.type_of_service = 0xff; 8757 ipv4_mask_tos.hdr.time_to_live = 0xff; 8758 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 8759 vxlan_encap_conf.ip_tos; 8760 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 8761 vxlan_encap_conf.ip_ttl; 8762 action_vxlan_encap_data->items[2].mask = 8763 &ipv4_mask_tos; 8764 } else { 8765 static struct rte_flow_item_ipv6 ipv6_mask_tos; 8766 8767 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 8768 sizeof(ipv6_mask_tos)); 8769 ipv6_mask_tos.hdr.vtc_flow |= 8770 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 8771 ipv6_mask_tos.hdr.hop_limits = 0xff; 8772 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 8773 rte_cpu_to_be_32 8774 ((uint32_t)vxlan_encap_conf.ip_tos << 8775 RTE_IPV6_HDR_TC_SHIFT); 8776 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 8777 vxlan_encap_conf.ip_ttl; 8778 action_vxlan_encap_data->items[2].mask = 8779 &ipv6_mask_tos; 8780 } 8781 } 8782 memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, 8783 RTE_DIM(vxlan_encap_conf.vni)); 8784 return 0; 8785 } 8786 8787 /** Parse VXLAN encap action. */ 8788 static int 8789 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 8790 const char *str, unsigned int len, 8791 void *buf, unsigned int size) 8792 { 8793 struct buffer *out = buf; 8794 struct rte_flow_action *action; 8795 struct action_vxlan_encap_data *action_vxlan_encap_data; 8796 int ret; 8797 8798 ret = parse_vc(ctx, token, str, len, buf, size); 8799 if (ret < 0) 8800 return ret; 8801 /* Nothing else to do if there is no buffer. */ 8802 if (!out) 8803 return ret; 8804 if (!out->args.vc.actions_n) 8805 return -1; 8806 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8807 /* Point to selected object. */ 8808 ctx->object = out->args.vc.data; 8809 ctx->objmask = NULL; 8810 action_vxlan_encap_data = ctx->object; 8811 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 8812 action->conf = &action_vxlan_encap_data->conf; 8813 return ret; 8814 } 8815 8816 /** Setup NVGRE encap configuration. */ 8817 static int 8818 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 8819 { 8820 /* Set up default configuration. */ 8821 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 8822 .conf = (struct rte_flow_action_nvgre_encap){ 8823 .definition = action_nvgre_encap_data->items, 8824 }, 8825 .items = { 8826 { 8827 .type = RTE_FLOW_ITEM_TYPE_ETH, 8828 .spec = &action_nvgre_encap_data->item_eth, 8829 .mask = &rte_flow_item_eth_mask, 8830 }, 8831 { 8832 .type = RTE_FLOW_ITEM_TYPE_VLAN, 8833 .spec = &action_nvgre_encap_data->item_vlan, 8834 .mask = &rte_flow_item_vlan_mask, 8835 }, 8836 { 8837 .type = RTE_FLOW_ITEM_TYPE_IPV4, 8838 .spec = &action_nvgre_encap_data->item_ipv4, 8839 .mask = &rte_flow_item_ipv4_mask, 8840 }, 8841 { 8842 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 8843 .spec = &action_nvgre_encap_data->item_nvgre, 8844 .mask = &rte_flow_item_nvgre_mask, 8845 }, 8846 { 8847 .type = RTE_FLOW_ITEM_TYPE_END, 8848 }, 8849 }, 8850 .item_eth.hdr.ether_type = 0, 8851 .item_vlan = { 8852 .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, 8853 .hdr.eth_proto = 0, 8854 }, 8855 .item_ipv4.hdr = { 8856 .src_addr = nvgre_encap_conf.ipv4_src, 8857 .dst_addr = nvgre_encap_conf.ipv4_dst, 8858 }, 8859 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 8860 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 8861 .item_nvgre.flow_id = 0, 8862 }; 8863 memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, 8864 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 8865 memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, 8866 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 8867 if (!nvgre_encap_conf.select_ipv4) { 8868 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 8869 &nvgre_encap_conf.ipv6_src, 8870 sizeof(nvgre_encap_conf.ipv6_src)); 8871 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 8872 &nvgre_encap_conf.ipv6_dst, 8873 sizeof(nvgre_encap_conf.ipv6_dst)); 8874 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 8875 .type = RTE_FLOW_ITEM_TYPE_IPV6, 8876 .spec = &action_nvgre_encap_data->item_ipv6, 8877 .mask = &rte_flow_item_ipv6_mask, 8878 }; 8879 } 8880 if (!nvgre_encap_conf.select_vlan) 8881 action_nvgre_encap_data->items[1].type = 8882 RTE_FLOW_ITEM_TYPE_VOID; 8883 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 8884 RTE_DIM(nvgre_encap_conf.tni)); 8885 return 0; 8886 } 8887 8888 /** Parse NVGRE encap action. */ 8889 static int 8890 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 8891 const char *str, unsigned int len, 8892 void *buf, unsigned int size) 8893 { 8894 struct buffer *out = buf; 8895 struct rte_flow_action *action; 8896 struct action_nvgre_encap_data *action_nvgre_encap_data; 8897 int ret; 8898 8899 ret = parse_vc(ctx, token, str, len, buf, size); 8900 if (ret < 0) 8901 return ret; 8902 /* Nothing else to do if there is no buffer. */ 8903 if (!out) 8904 return ret; 8905 if (!out->args.vc.actions_n) 8906 return -1; 8907 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8908 /* Point to selected object. */ 8909 ctx->object = out->args.vc.data; 8910 ctx->objmask = NULL; 8911 action_nvgre_encap_data = ctx->object; 8912 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 8913 action->conf = &action_nvgre_encap_data->conf; 8914 return ret; 8915 } 8916 8917 /** Parse l2 encap action. */ 8918 static int 8919 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 8920 const char *str, unsigned int len, 8921 void *buf, unsigned int size) 8922 { 8923 struct buffer *out = buf; 8924 struct rte_flow_action *action; 8925 struct action_raw_encap_data *action_encap_data; 8926 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 8927 struct rte_flow_item_vlan vlan = { 8928 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 8929 .hdr.eth_proto = 0, 8930 }; 8931 uint8_t *header; 8932 int ret; 8933 8934 ret = parse_vc(ctx, token, str, len, buf, size); 8935 if (ret < 0) 8936 return ret; 8937 /* Nothing else to do if there is no buffer. */ 8938 if (!out) 8939 return ret; 8940 if (!out->args.vc.actions_n) 8941 return -1; 8942 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8943 /* Point to selected object. */ 8944 ctx->object = out->args.vc.data; 8945 ctx->objmask = NULL; 8946 /* Copy the headers to the buffer. */ 8947 action_encap_data = ctx->object; 8948 *action_encap_data = (struct action_raw_encap_data) { 8949 .conf = (struct rte_flow_action_raw_encap){ 8950 .data = action_encap_data->data, 8951 }, 8952 .data = {}, 8953 }; 8954 header = action_encap_data->data; 8955 if (l2_encap_conf.select_vlan) 8956 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 8957 else if (l2_encap_conf.select_ipv4) 8958 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 8959 else 8960 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 8961 memcpy(eth.hdr.dst_addr.addr_bytes, 8962 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 8963 memcpy(eth.hdr.src_addr.addr_bytes, 8964 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 8965 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 8966 header += sizeof(struct rte_ether_hdr); 8967 if (l2_encap_conf.select_vlan) { 8968 if (l2_encap_conf.select_ipv4) 8969 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 8970 else 8971 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 8972 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 8973 header += sizeof(struct rte_vlan_hdr); 8974 } 8975 action_encap_data->conf.size = header - 8976 action_encap_data->data; 8977 action->conf = &action_encap_data->conf; 8978 return ret; 8979 } 8980 8981 /** Parse l2 decap action. */ 8982 static int 8983 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 8984 const char *str, unsigned int len, 8985 void *buf, unsigned int size) 8986 { 8987 struct buffer *out = buf; 8988 struct rte_flow_action *action; 8989 struct action_raw_decap_data *action_decap_data; 8990 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 8991 struct rte_flow_item_vlan vlan = { 8992 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 8993 .hdr.eth_proto = 0, 8994 }; 8995 uint8_t *header; 8996 int ret; 8997 8998 ret = parse_vc(ctx, token, str, len, buf, size); 8999 if (ret < 0) 9000 return ret; 9001 /* Nothing else to do if there is no buffer. */ 9002 if (!out) 9003 return ret; 9004 if (!out->args.vc.actions_n) 9005 return -1; 9006 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9007 /* Point to selected object. */ 9008 ctx->object = out->args.vc.data; 9009 ctx->objmask = NULL; 9010 /* Copy the headers to the buffer. */ 9011 action_decap_data = ctx->object; 9012 *action_decap_data = (struct action_raw_decap_data) { 9013 .conf = (struct rte_flow_action_raw_decap){ 9014 .data = action_decap_data->data, 9015 }, 9016 .data = {}, 9017 }; 9018 header = action_decap_data->data; 9019 if (l2_decap_conf.select_vlan) 9020 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9021 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9022 header += sizeof(struct rte_ether_hdr); 9023 if (l2_decap_conf.select_vlan) { 9024 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9025 header += sizeof(struct rte_vlan_hdr); 9026 } 9027 action_decap_data->conf.size = header - 9028 action_decap_data->data; 9029 action->conf = &action_decap_data->conf; 9030 return ret; 9031 } 9032 9033 #define ETHER_TYPE_MPLS_UNICAST 0x8847 9034 9035 /** Parse MPLSOGRE encap action. */ 9036 static int 9037 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 9038 const char *str, unsigned int len, 9039 void *buf, unsigned int size) 9040 { 9041 struct buffer *out = buf; 9042 struct rte_flow_action *action; 9043 struct action_raw_encap_data *action_encap_data; 9044 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9045 struct rte_flow_item_vlan vlan = { 9046 .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, 9047 .hdr.eth_proto = 0, 9048 }; 9049 struct rte_flow_item_ipv4 ipv4 = { 9050 .hdr = { 9051 .src_addr = mplsogre_encap_conf.ipv4_src, 9052 .dst_addr = mplsogre_encap_conf.ipv4_dst, 9053 .next_proto_id = IPPROTO_GRE, 9054 .version_ihl = RTE_IPV4_VHL_DEF, 9055 .time_to_live = IPDEFTTL, 9056 }, 9057 }; 9058 struct rte_flow_item_ipv6 ipv6 = { 9059 .hdr = { 9060 .proto = IPPROTO_GRE, 9061 .hop_limits = IPDEFTTL, 9062 }, 9063 }; 9064 struct rte_flow_item_gre gre = { 9065 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9066 }; 9067 struct rte_flow_item_mpls mpls = { 9068 .ttl = 0, 9069 }; 9070 uint8_t *header; 9071 int ret; 9072 9073 ret = parse_vc(ctx, token, str, len, buf, size); 9074 if (ret < 0) 9075 return ret; 9076 /* Nothing else to do if there is no buffer. */ 9077 if (!out) 9078 return ret; 9079 if (!out->args.vc.actions_n) 9080 return -1; 9081 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9082 /* Point to selected object. */ 9083 ctx->object = out->args.vc.data; 9084 ctx->objmask = NULL; 9085 /* Copy the headers to the buffer. */ 9086 action_encap_data = ctx->object; 9087 *action_encap_data = (struct action_raw_encap_data) { 9088 .conf = (struct rte_flow_action_raw_encap){ 9089 .data = action_encap_data->data, 9090 }, 9091 .data = {}, 9092 .preserve = {}, 9093 }; 9094 header = action_encap_data->data; 9095 if (mplsogre_encap_conf.select_vlan) 9096 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9097 else if (mplsogre_encap_conf.select_ipv4) 9098 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9099 else 9100 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9101 memcpy(eth.hdr.dst_addr.addr_bytes, 9102 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9103 memcpy(eth.hdr.src_addr.addr_bytes, 9104 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9105 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9106 header += sizeof(struct rte_ether_hdr); 9107 if (mplsogre_encap_conf.select_vlan) { 9108 if (mplsogre_encap_conf.select_ipv4) 9109 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9110 else 9111 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9112 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9113 header += sizeof(struct rte_vlan_hdr); 9114 } 9115 if (mplsogre_encap_conf.select_ipv4) { 9116 memcpy(header, &ipv4, sizeof(ipv4)); 9117 header += sizeof(ipv4); 9118 } else { 9119 memcpy(&ipv6.hdr.src_addr, 9120 &mplsogre_encap_conf.ipv6_src, 9121 sizeof(mplsogre_encap_conf.ipv6_src)); 9122 memcpy(&ipv6.hdr.dst_addr, 9123 &mplsogre_encap_conf.ipv6_dst, 9124 sizeof(mplsogre_encap_conf.ipv6_dst)); 9125 memcpy(header, &ipv6, sizeof(ipv6)); 9126 header += sizeof(ipv6); 9127 } 9128 memcpy(header, &gre, sizeof(gre)); 9129 header += sizeof(gre); 9130 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 9131 RTE_DIM(mplsogre_encap_conf.label)); 9132 mpls.label_tc_s[2] |= 0x1; 9133 memcpy(header, &mpls, sizeof(mpls)); 9134 header += sizeof(mpls); 9135 action_encap_data->conf.size = header - 9136 action_encap_data->data; 9137 action->conf = &action_encap_data->conf; 9138 return ret; 9139 } 9140 9141 /** Parse MPLSOGRE decap action. */ 9142 static int 9143 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 9144 const char *str, unsigned int len, 9145 void *buf, unsigned int size) 9146 { 9147 struct buffer *out = buf; 9148 struct rte_flow_action *action; 9149 struct action_raw_decap_data *action_decap_data; 9150 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9151 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9152 struct rte_flow_item_ipv4 ipv4 = { 9153 .hdr = { 9154 .next_proto_id = IPPROTO_GRE, 9155 }, 9156 }; 9157 struct rte_flow_item_ipv6 ipv6 = { 9158 .hdr = { 9159 .proto = IPPROTO_GRE, 9160 }, 9161 }; 9162 struct rte_flow_item_gre gre = { 9163 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9164 }; 9165 struct rte_flow_item_mpls mpls; 9166 uint8_t *header; 9167 int ret; 9168 9169 ret = parse_vc(ctx, token, str, len, buf, size); 9170 if (ret < 0) 9171 return ret; 9172 /* Nothing else to do if there is no buffer. */ 9173 if (!out) 9174 return ret; 9175 if (!out->args.vc.actions_n) 9176 return -1; 9177 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9178 /* Point to selected object. */ 9179 ctx->object = out->args.vc.data; 9180 ctx->objmask = NULL; 9181 /* Copy the headers to the buffer. */ 9182 action_decap_data = ctx->object; 9183 *action_decap_data = (struct action_raw_decap_data) { 9184 .conf = (struct rte_flow_action_raw_decap){ 9185 .data = action_decap_data->data, 9186 }, 9187 .data = {}, 9188 }; 9189 header = action_decap_data->data; 9190 if (mplsogre_decap_conf.select_vlan) 9191 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9192 else if (mplsogre_encap_conf.select_ipv4) 9193 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9194 else 9195 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9196 memcpy(eth.hdr.dst_addr.addr_bytes, 9197 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9198 memcpy(eth.hdr.src_addr.addr_bytes, 9199 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9200 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9201 header += sizeof(struct rte_ether_hdr); 9202 if (mplsogre_encap_conf.select_vlan) { 9203 if (mplsogre_encap_conf.select_ipv4) 9204 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9205 else 9206 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9207 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9208 header += sizeof(struct rte_vlan_hdr); 9209 } 9210 if (mplsogre_encap_conf.select_ipv4) { 9211 memcpy(header, &ipv4, sizeof(ipv4)); 9212 header += sizeof(ipv4); 9213 } else { 9214 memcpy(header, &ipv6, sizeof(ipv6)); 9215 header += sizeof(ipv6); 9216 } 9217 memcpy(header, &gre, sizeof(gre)); 9218 header += sizeof(gre); 9219 memset(&mpls, 0, sizeof(mpls)); 9220 memcpy(header, &mpls, sizeof(mpls)); 9221 header += sizeof(mpls); 9222 action_decap_data->conf.size = header - 9223 action_decap_data->data; 9224 action->conf = &action_decap_data->conf; 9225 return ret; 9226 } 9227 9228 /** Parse MPLSOUDP encap action. */ 9229 static int 9230 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 9231 const char *str, unsigned int len, 9232 void *buf, unsigned int size) 9233 { 9234 struct buffer *out = buf; 9235 struct rte_flow_action *action; 9236 struct action_raw_encap_data *action_encap_data; 9237 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9238 struct rte_flow_item_vlan vlan = { 9239 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9240 .hdr.eth_proto = 0, 9241 }; 9242 struct rte_flow_item_ipv4 ipv4 = { 9243 .hdr = { 9244 .src_addr = mplsoudp_encap_conf.ipv4_src, 9245 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 9246 .next_proto_id = IPPROTO_UDP, 9247 .version_ihl = RTE_IPV4_VHL_DEF, 9248 .time_to_live = IPDEFTTL, 9249 }, 9250 }; 9251 struct rte_flow_item_ipv6 ipv6 = { 9252 .hdr = { 9253 .proto = IPPROTO_UDP, 9254 .hop_limits = IPDEFTTL, 9255 }, 9256 }; 9257 struct rte_flow_item_udp udp = { 9258 .hdr = { 9259 .src_port = mplsoudp_encap_conf.udp_src, 9260 .dst_port = mplsoudp_encap_conf.udp_dst, 9261 }, 9262 }; 9263 struct rte_flow_item_mpls mpls; 9264 uint8_t *header; 9265 int ret; 9266 9267 ret = parse_vc(ctx, token, str, len, buf, size); 9268 if (ret < 0) 9269 return ret; 9270 /* Nothing else to do if there is no buffer. */ 9271 if (!out) 9272 return ret; 9273 if (!out->args.vc.actions_n) 9274 return -1; 9275 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9276 /* Point to selected object. */ 9277 ctx->object = out->args.vc.data; 9278 ctx->objmask = NULL; 9279 /* Copy the headers to the buffer. */ 9280 action_encap_data = ctx->object; 9281 *action_encap_data = (struct action_raw_encap_data) { 9282 .conf = (struct rte_flow_action_raw_encap){ 9283 .data = action_encap_data->data, 9284 }, 9285 .data = {}, 9286 .preserve = {}, 9287 }; 9288 header = action_encap_data->data; 9289 if (mplsoudp_encap_conf.select_vlan) 9290 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9291 else if (mplsoudp_encap_conf.select_ipv4) 9292 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9293 else 9294 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9295 memcpy(eth.hdr.dst_addr.addr_bytes, 9296 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9297 memcpy(eth.hdr.src_addr.addr_bytes, 9298 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9299 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9300 header += sizeof(struct rte_ether_hdr); 9301 if (mplsoudp_encap_conf.select_vlan) { 9302 if (mplsoudp_encap_conf.select_ipv4) 9303 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9304 else 9305 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9306 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9307 header += sizeof(struct rte_vlan_hdr); 9308 } 9309 if (mplsoudp_encap_conf.select_ipv4) { 9310 memcpy(header, &ipv4, sizeof(ipv4)); 9311 header += sizeof(ipv4); 9312 } else { 9313 memcpy(&ipv6.hdr.src_addr, 9314 &mplsoudp_encap_conf.ipv6_src, 9315 sizeof(mplsoudp_encap_conf.ipv6_src)); 9316 memcpy(&ipv6.hdr.dst_addr, 9317 &mplsoudp_encap_conf.ipv6_dst, 9318 sizeof(mplsoudp_encap_conf.ipv6_dst)); 9319 memcpy(header, &ipv6, sizeof(ipv6)); 9320 header += sizeof(ipv6); 9321 } 9322 memcpy(header, &udp, sizeof(udp)); 9323 header += sizeof(udp); 9324 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 9325 RTE_DIM(mplsoudp_encap_conf.label)); 9326 mpls.label_tc_s[2] |= 0x1; 9327 memcpy(header, &mpls, sizeof(mpls)); 9328 header += sizeof(mpls); 9329 action_encap_data->conf.size = header - 9330 action_encap_data->data; 9331 action->conf = &action_encap_data->conf; 9332 return ret; 9333 } 9334 9335 /** Parse MPLSOUDP decap action. */ 9336 static int 9337 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 9338 const char *str, unsigned int len, 9339 void *buf, unsigned int size) 9340 { 9341 struct buffer *out = buf; 9342 struct rte_flow_action *action; 9343 struct action_raw_decap_data *action_decap_data; 9344 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9345 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9346 struct rte_flow_item_ipv4 ipv4 = { 9347 .hdr = { 9348 .next_proto_id = IPPROTO_UDP, 9349 }, 9350 }; 9351 struct rte_flow_item_ipv6 ipv6 = { 9352 .hdr = { 9353 .proto = IPPROTO_UDP, 9354 }, 9355 }; 9356 struct rte_flow_item_udp udp = { 9357 .hdr = { 9358 .dst_port = rte_cpu_to_be_16(6635), 9359 }, 9360 }; 9361 struct rte_flow_item_mpls mpls; 9362 uint8_t *header; 9363 int ret; 9364 9365 ret = parse_vc(ctx, token, str, len, buf, size); 9366 if (ret < 0) 9367 return ret; 9368 /* Nothing else to do if there is no buffer. */ 9369 if (!out) 9370 return ret; 9371 if (!out->args.vc.actions_n) 9372 return -1; 9373 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9374 /* Point to selected object. */ 9375 ctx->object = out->args.vc.data; 9376 ctx->objmask = NULL; 9377 /* Copy the headers to the buffer. */ 9378 action_decap_data = ctx->object; 9379 *action_decap_data = (struct action_raw_decap_data) { 9380 .conf = (struct rte_flow_action_raw_decap){ 9381 .data = action_decap_data->data, 9382 }, 9383 .data = {}, 9384 }; 9385 header = action_decap_data->data; 9386 if (mplsoudp_decap_conf.select_vlan) 9387 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9388 else if (mplsoudp_encap_conf.select_ipv4) 9389 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9390 else 9391 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9392 memcpy(eth.hdr.dst_addr.addr_bytes, 9393 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9394 memcpy(eth.hdr.src_addr.addr_bytes, 9395 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9396 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9397 header += sizeof(struct rte_ether_hdr); 9398 if (mplsoudp_encap_conf.select_vlan) { 9399 if (mplsoudp_encap_conf.select_ipv4) 9400 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9401 else 9402 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9403 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9404 header += sizeof(struct rte_vlan_hdr); 9405 } 9406 if (mplsoudp_encap_conf.select_ipv4) { 9407 memcpy(header, &ipv4, sizeof(ipv4)); 9408 header += sizeof(ipv4); 9409 } else { 9410 memcpy(header, &ipv6, sizeof(ipv6)); 9411 header += sizeof(ipv6); 9412 } 9413 memcpy(header, &udp, sizeof(udp)); 9414 header += sizeof(udp); 9415 memset(&mpls, 0, sizeof(mpls)); 9416 memcpy(header, &mpls, sizeof(mpls)); 9417 header += sizeof(mpls); 9418 action_decap_data->conf.size = header - 9419 action_decap_data->data; 9420 action->conf = &action_decap_data->conf; 9421 return ret; 9422 } 9423 9424 static int 9425 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 9426 const char *str, unsigned int len, void *buf, 9427 unsigned int size) 9428 { 9429 struct action_raw_decap_data *action_raw_decap_data; 9430 struct rte_flow_action *action; 9431 const struct arg *arg; 9432 struct buffer *out = buf; 9433 int ret; 9434 uint16_t idx; 9435 9436 RTE_SET_USED(token); 9437 RTE_SET_USED(buf); 9438 RTE_SET_USED(size); 9439 arg = ARGS_ENTRY_ARB_BOUNDED 9440 (offsetof(struct action_raw_decap_data, idx), 9441 sizeof(((struct action_raw_decap_data *)0)->idx), 9442 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 9443 if (push_args(ctx, arg)) 9444 return -1; 9445 ret = parse_int(ctx, token, str, len, NULL, 0); 9446 if (ret < 0) { 9447 pop_args(ctx); 9448 return -1; 9449 } 9450 if (!ctx->object) 9451 return len; 9452 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9453 action_raw_decap_data = ctx->object; 9454 idx = action_raw_decap_data->idx; 9455 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 9456 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 9457 action->conf = &action_raw_decap_data->conf; 9458 return len; 9459 } 9460 9461 9462 static int 9463 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 9464 const char *str, unsigned int len, void *buf, 9465 unsigned int size) 9466 { 9467 struct action_raw_encap_data *action_raw_encap_data; 9468 struct rte_flow_action *action; 9469 const struct arg *arg; 9470 struct buffer *out = buf; 9471 int ret; 9472 uint16_t idx; 9473 9474 RTE_SET_USED(token); 9475 RTE_SET_USED(buf); 9476 RTE_SET_USED(size); 9477 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 9478 return -1; 9479 arg = ARGS_ENTRY_ARB_BOUNDED 9480 (offsetof(struct action_raw_encap_data, idx), 9481 sizeof(((struct action_raw_encap_data *)0)->idx), 9482 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 9483 if (push_args(ctx, arg)) 9484 return -1; 9485 ret = parse_int(ctx, token, str, len, NULL, 0); 9486 if (ret < 0) { 9487 pop_args(ctx); 9488 return -1; 9489 } 9490 if (!ctx->object) 9491 return len; 9492 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9493 action_raw_encap_data = ctx->object; 9494 idx = action_raw_encap_data->idx; 9495 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 9496 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 9497 action_raw_encap_data->conf.preserve = NULL; 9498 action->conf = &action_raw_encap_data->conf; 9499 return len; 9500 } 9501 9502 static int 9503 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 9504 const char *str, unsigned int len, void *buf, 9505 unsigned int size) 9506 { 9507 struct buffer *out = buf; 9508 struct rte_flow_action *action; 9509 struct action_raw_encap_data *action_raw_encap_data = NULL; 9510 int ret; 9511 9512 ret = parse_vc(ctx, token, str, len, buf, size); 9513 if (ret < 0) 9514 return ret; 9515 /* Nothing else to do if there is no buffer. */ 9516 if (!out) 9517 return ret; 9518 if (!out->args.vc.actions_n) 9519 return -1; 9520 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9521 /* Point to selected object. */ 9522 ctx->object = out->args.vc.data; 9523 ctx->objmask = NULL; 9524 /* Copy the headers to the buffer. */ 9525 action_raw_encap_data = ctx->object; 9526 action_raw_encap_data->conf.data = raw_encap_confs[0].data; 9527 action_raw_encap_data->conf.preserve = NULL; 9528 action_raw_encap_data->conf.size = raw_encap_confs[0].size; 9529 action->conf = &action_raw_encap_data->conf; 9530 return ret; 9531 } 9532 9533 static int 9534 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 9535 const char *str, unsigned int len, void *buf, 9536 unsigned int size) 9537 { 9538 struct buffer *out = buf; 9539 struct rte_flow_action *action; 9540 struct action_raw_decap_data *action_raw_decap_data = NULL; 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_raw_decap_data = ctx->object; 9557 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 9558 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 9559 action->conf = &action_raw_decap_data->conf; 9560 return ret; 9561 } 9562 9563 static int 9564 parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 9565 const char *str, unsigned int len, void *buf, 9566 unsigned int size) 9567 { 9568 struct buffer *out = buf; 9569 struct rte_flow_action *action; 9570 struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; 9571 int ret; 9572 9573 ret = parse_vc(ctx, token, str, len, buf, size); 9574 if (ret < 0) 9575 return ret; 9576 /* Nothing else to do if there is no buffer. */ 9577 if (!out) 9578 return ret; 9579 if (!out->args.vc.actions_n) 9580 return -1; 9581 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9582 /* Point to selected object. */ 9583 ctx->object = out->args.vc.data; 9584 ctx->objmask = NULL; 9585 /* Copy the headers to the buffer. */ 9586 ipv6_ext_remove_data = ctx->object; 9587 ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; 9588 action->conf = &ipv6_ext_remove_data->conf; 9589 return ret; 9590 } 9591 9592 static int 9593 parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, 9594 const char *str, unsigned int len, void *buf, 9595 unsigned int size) 9596 { 9597 struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; 9598 struct rte_flow_action *action; 9599 const struct arg *arg; 9600 struct buffer *out = buf; 9601 int ret; 9602 uint16_t idx; 9603 9604 RTE_SET_USED(token); 9605 RTE_SET_USED(buf); 9606 RTE_SET_USED(size); 9607 arg = ARGS_ENTRY_ARB_BOUNDED 9608 (offsetof(struct action_ipv6_ext_remove_data, idx), 9609 sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), 9610 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 9611 if (push_args(ctx, arg)) 9612 return -1; 9613 ret = parse_int(ctx, token, str, len, NULL, 0); 9614 if (ret < 0) { 9615 pop_args(ctx); 9616 return -1; 9617 } 9618 if (!ctx->object) 9619 return len; 9620 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9621 action_ipv6_ext_remove_data = ctx->object; 9622 idx = action_ipv6_ext_remove_data->idx; 9623 action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; 9624 action->conf = &action_ipv6_ext_remove_data->conf; 9625 return len; 9626 } 9627 9628 static int 9629 parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 9630 const char *str, unsigned int len, void *buf, 9631 unsigned int size) 9632 { 9633 struct buffer *out = buf; 9634 struct rte_flow_action *action; 9635 struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; 9636 int ret; 9637 9638 ret = parse_vc(ctx, token, str, len, buf, size); 9639 if (ret < 0) 9640 return ret; 9641 /* Nothing else to do if there is no buffer. */ 9642 if (!out) 9643 return ret; 9644 if (!out->args.vc.actions_n) 9645 return -1; 9646 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9647 /* Point to selected object. */ 9648 ctx->object = out->args.vc.data; 9649 ctx->objmask = NULL; 9650 /* Copy the headers to the buffer. */ 9651 ipv6_ext_push_data = ctx->object; 9652 ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; 9653 ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; 9654 ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; 9655 action->conf = &ipv6_ext_push_data->conf; 9656 return ret; 9657 } 9658 9659 static int 9660 parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, 9661 const char *str, unsigned int len, void *buf, 9662 unsigned int size) 9663 { 9664 struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; 9665 struct rte_flow_action *action; 9666 const struct arg *arg; 9667 struct buffer *out = buf; 9668 int ret; 9669 uint16_t idx; 9670 9671 RTE_SET_USED(token); 9672 RTE_SET_USED(buf); 9673 RTE_SET_USED(size); 9674 arg = ARGS_ENTRY_ARB_BOUNDED 9675 (offsetof(struct action_ipv6_ext_push_data, idx), 9676 sizeof(((struct action_ipv6_ext_push_data *)0)->idx), 9677 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 9678 if (push_args(ctx, arg)) 9679 return -1; 9680 ret = parse_int(ctx, token, str, len, NULL, 0); 9681 if (ret < 0) { 9682 pop_args(ctx); 9683 return -1; 9684 } 9685 if (!ctx->object) 9686 return len; 9687 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9688 action_ipv6_ext_push_data = ctx->object; 9689 idx = action_ipv6_ext_push_data->idx; 9690 action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; 9691 action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; 9692 action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; 9693 action->conf = &action_ipv6_ext_push_data->conf; 9694 return len; 9695 } 9696 9697 static int 9698 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 9699 const char *str, unsigned int len, void *buf, 9700 unsigned int size) 9701 { 9702 int ret; 9703 9704 ret = parse_vc(ctx, token, str, len, buf, size); 9705 if (ret < 0) 9706 return ret; 9707 ret = rte_flow_dynf_metadata_register(); 9708 if (ret < 0) 9709 return -1; 9710 return len; 9711 } 9712 9713 static int 9714 parse_vc_action_sample(struct context *ctx, const struct token *token, 9715 const char *str, unsigned int len, void *buf, 9716 unsigned int size) 9717 { 9718 struct buffer *out = buf; 9719 struct rte_flow_action *action; 9720 struct action_sample_data *action_sample_data = NULL; 9721 static struct rte_flow_action end_action = { 9722 RTE_FLOW_ACTION_TYPE_END, 0 9723 }; 9724 int ret; 9725 9726 ret = parse_vc(ctx, token, str, len, buf, size); 9727 if (ret < 0) 9728 return ret; 9729 /* Nothing else to do if there is no buffer. */ 9730 if (!out) 9731 return ret; 9732 if (!out->args.vc.actions_n) 9733 return -1; 9734 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9735 /* Point to selected object. */ 9736 ctx->object = out->args.vc.data; 9737 ctx->objmask = NULL; 9738 /* Copy the headers to the buffer. */ 9739 action_sample_data = ctx->object; 9740 action_sample_data->conf.actions = &end_action; 9741 action->conf = &action_sample_data->conf; 9742 return ret; 9743 } 9744 9745 static int 9746 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 9747 const char *str, unsigned int len, void *buf, 9748 unsigned int size) 9749 { 9750 struct action_sample_data *action_sample_data; 9751 struct rte_flow_action *action; 9752 const struct arg *arg; 9753 struct buffer *out = buf; 9754 int ret; 9755 uint16_t idx; 9756 9757 RTE_SET_USED(token); 9758 RTE_SET_USED(buf); 9759 RTE_SET_USED(size); 9760 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 9761 return -1; 9762 arg = ARGS_ENTRY_ARB_BOUNDED 9763 (offsetof(struct action_sample_data, idx), 9764 sizeof(((struct action_sample_data *)0)->idx), 9765 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 9766 if (push_args(ctx, arg)) 9767 return -1; 9768 ret = parse_int(ctx, token, str, len, NULL, 0); 9769 if (ret < 0) { 9770 pop_args(ctx); 9771 return -1; 9772 } 9773 if (!ctx->object) 9774 return len; 9775 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9776 action_sample_data = ctx->object; 9777 idx = action_sample_data->idx; 9778 action_sample_data->conf.actions = raw_sample_confs[idx].data; 9779 action->conf = &action_sample_data->conf; 9780 return len; 9781 } 9782 9783 /** Parse operation for modify_field command. */ 9784 static int 9785 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 9786 const char *str, unsigned int len, void *buf, 9787 unsigned int size) 9788 { 9789 struct rte_flow_action_modify_field *action_modify_field; 9790 unsigned int i; 9791 9792 (void)token; 9793 (void)buf; 9794 (void)size; 9795 if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) 9796 return -1; 9797 for (i = 0; modify_field_ops[i]; ++i) 9798 if (!strcmp_partial(modify_field_ops[i], str, len)) 9799 break; 9800 if (!modify_field_ops[i]) 9801 return -1; 9802 if (!ctx->object) 9803 return len; 9804 action_modify_field = ctx->object; 9805 action_modify_field->operation = (enum rte_flow_modify_op)i; 9806 return len; 9807 } 9808 9809 /** Parse id for modify_field command. */ 9810 static int 9811 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 9812 const char *str, unsigned int len, void *buf, 9813 unsigned int size) 9814 { 9815 struct rte_flow_action_modify_field *action_modify_field; 9816 unsigned int i; 9817 9818 (void)token; 9819 (void)buf; 9820 (void)size; 9821 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 9822 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 9823 return -1; 9824 for (i = 0; modify_field_ids[i]; ++i) 9825 if (!strcmp_partial(modify_field_ids[i], str, len)) 9826 break; 9827 if (!modify_field_ids[i]) 9828 return -1; 9829 if (!ctx->object) 9830 return len; 9831 action_modify_field = ctx->object; 9832 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 9833 action_modify_field->dst.field = (enum rte_flow_field_id)i; 9834 else 9835 action_modify_field->src.field = (enum rte_flow_field_id)i; 9836 return len; 9837 } 9838 9839 /** Parse level for modify_field command. */ 9840 static int 9841 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 9842 const char *str, unsigned int len, void *buf, 9843 unsigned int size) 9844 { 9845 struct rte_flow_action_modify_field *action; 9846 struct flex_item *fp = NULL; 9847 uint32_t val; 9848 struct buffer *out = buf; 9849 char *end; 9850 9851 (void)token; 9852 (void)size; 9853 if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 9854 ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) 9855 return -1; 9856 if (!ctx->object) 9857 return len; 9858 action = ctx->object; 9859 errno = 0; 9860 val = strtoumax(str, &end, 0); 9861 if (errno || (size_t)(end - str) != len) 9862 return -1; 9863 /* No need to validate action template mask value */ 9864 if (out->args.vc.masks) { 9865 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) 9866 action->dst.level = val; 9867 else 9868 action->src.level = val; 9869 return len; 9870 } 9871 if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 9872 action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || 9873 (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && 9874 action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 9875 if (val >= FLEX_MAX_PARSERS_NUM) { 9876 printf("Bad flex item handle\n"); 9877 return -1; 9878 } 9879 fp = flex_items[ctx->port][val]; 9880 if (!fp) { 9881 printf("Bad flex item handle\n"); 9882 return -1; 9883 } 9884 } 9885 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { 9886 if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) 9887 action->dst.level = val; 9888 else 9889 action->dst.flex_handle = fp->flex_handle; 9890 } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { 9891 if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) 9892 action->src.level = val; 9893 else 9894 action->src.flex_handle = fp->flex_handle; 9895 } 9896 return len; 9897 } 9898 9899 /** Parse the conntrack update, not a rte_flow_action. */ 9900 static int 9901 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 9902 const char *str, unsigned int len, void *buf, 9903 unsigned int size) 9904 { 9905 struct buffer *out = buf; 9906 struct rte_flow_modify_conntrack *ct_modify = NULL; 9907 9908 (void)size; 9909 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 9910 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 9911 return -1; 9912 /* Token name must match. */ 9913 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9914 return -1; 9915 /* Nothing else to do if there is no buffer. */ 9916 if (!out) 9917 return len; 9918 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 9919 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 9920 ct_modify->new_ct.is_original_dir = 9921 conntrack_context.is_original_dir; 9922 ct_modify->direction = 1; 9923 } else { 9924 uint32_t old_dir; 9925 9926 old_dir = ct_modify->new_ct.is_original_dir; 9927 memcpy(&ct_modify->new_ct, &conntrack_context, 9928 sizeof(conntrack_context)); 9929 ct_modify->new_ct.is_original_dir = old_dir; 9930 ct_modify->state = 1; 9931 } 9932 return len; 9933 } 9934 9935 /** Parse tokens for destroy command. */ 9936 static int 9937 parse_destroy(struct context *ctx, const struct token *token, 9938 const char *str, unsigned int len, 9939 void *buf, unsigned int size) 9940 { 9941 struct buffer *out = buf; 9942 9943 /* Token name must match. */ 9944 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9945 return -1; 9946 /* Nothing else to do if there is no buffer. */ 9947 if (!out) 9948 return len; 9949 if (!out->command) { 9950 if (ctx->curr != DESTROY) 9951 return -1; 9952 if (sizeof(*out) > size) 9953 return -1; 9954 out->command = ctx->curr; 9955 ctx->objdata = 0; 9956 ctx->object = out; 9957 ctx->objmask = NULL; 9958 out->args.destroy.rule = 9959 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 9960 sizeof(double)); 9961 return len; 9962 } 9963 if (ctx->curr == DESTROY_IS_USER_ID) { 9964 out->args.destroy.is_user_id = true; 9965 return len; 9966 } 9967 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 9968 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 9969 return -1; 9970 ctx->objdata = 0; 9971 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 9972 ctx->objmask = NULL; 9973 return len; 9974 } 9975 9976 /** Parse tokens for flush command. */ 9977 static int 9978 parse_flush(struct context *ctx, const struct token *token, 9979 const char *str, unsigned int len, 9980 void *buf, unsigned int size) 9981 { 9982 struct buffer *out = buf; 9983 9984 /* Token name must match. */ 9985 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9986 return -1; 9987 /* Nothing else to do if there is no buffer. */ 9988 if (!out) 9989 return len; 9990 if (!out->command) { 9991 if (ctx->curr != FLUSH) 9992 return -1; 9993 if (sizeof(*out) > size) 9994 return -1; 9995 out->command = ctx->curr; 9996 ctx->objdata = 0; 9997 ctx->object = out; 9998 ctx->objmask = NULL; 9999 } 10000 return len; 10001 } 10002 10003 /** Parse tokens for dump command. */ 10004 static int 10005 parse_dump(struct context *ctx, const struct token *token, 10006 const char *str, unsigned int len, 10007 void *buf, unsigned int size) 10008 { 10009 struct buffer *out = buf; 10010 10011 /* Token name must match. */ 10012 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10013 return -1; 10014 /* Nothing else to do if there is no buffer. */ 10015 if (!out) 10016 return len; 10017 if (!out->command) { 10018 if (ctx->curr != DUMP) 10019 return -1; 10020 if (sizeof(*out) > size) 10021 return -1; 10022 out->command = ctx->curr; 10023 ctx->objdata = 0; 10024 ctx->object = out; 10025 ctx->objmask = NULL; 10026 return len; 10027 } 10028 switch (ctx->curr) { 10029 case DUMP_ALL: 10030 case DUMP_ONE: 10031 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 10032 out->command = ctx->curr; 10033 ctx->objdata = 0; 10034 ctx->object = out; 10035 ctx->objmask = NULL; 10036 return len; 10037 case DUMP_IS_USER_ID: 10038 out->args.dump.is_user_id = true; 10039 return len; 10040 default: 10041 return -1; 10042 } 10043 } 10044 10045 /** Parse tokens for query command. */ 10046 static int 10047 parse_query(struct context *ctx, const struct token *token, 10048 const char *str, unsigned int len, 10049 void *buf, unsigned int size) 10050 { 10051 struct buffer *out = buf; 10052 10053 /* Token name must match. */ 10054 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10055 return -1; 10056 /* Nothing else to do if there is no buffer. */ 10057 if (!out) 10058 return len; 10059 if (!out->command) { 10060 if (ctx->curr != QUERY) 10061 return -1; 10062 if (sizeof(*out) > size) 10063 return -1; 10064 out->command = ctx->curr; 10065 ctx->objdata = 0; 10066 ctx->object = out; 10067 ctx->objmask = NULL; 10068 } 10069 if (ctx->curr == QUERY_IS_USER_ID) { 10070 out->args.query.is_user_id = true; 10071 return len; 10072 } 10073 return len; 10074 } 10075 10076 /** Parse action names. */ 10077 static int 10078 parse_action(struct context *ctx, const struct token *token, 10079 const char *str, unsigned int len, 10080 void *buf, unsigned int size) 10081 { 10082 struct buffer *out = buf; 10083 const struct arg *arg = pop_args(ctx); 10084 unsigned int i; 10085 10086 (void)size; 10087 /* Argument is expected. */ 10088 if (!arg) 10089 return -1; 10090 /* Parse action name. */ 10091 for (i = 0; next_action[i]; ++i) { 10092 const struct parse_action_priv *priv; 10093 10094 token = &token_list[next_action[i]]; 10095 if (strcmp_partial(token->name, str, len)) 10096 continue; 10097 priv = token->priv; 10098 if (!priv) 10099 goto error; 10100 if (out) 10101 memcpy((uint8_t *)ctx->object + arg->offset, 10102 &priv->type, 10103 arg->size); 10104 return len; 10105 } 10106 error: 10107 push_args(ctx, arg); 10108 return -1; 10109 } 10110 10111 /** Parse tokens for list command. */ 10112 static int 10113 parse_list(struct context *ctx, const struct token *token, 10114 const char *str, unsigned int len, 10115 void *buf, unsigned int size) 10116 { 10117 struct buffer *out = buf; 10118 10119 /* Token name must match. */ 10120 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10121 return -1; 10122 /* Nothing else to do if there is no buffer. */ 10123 if (!out) 10124 return len; 10125 if (!out->command) { 10126 if (ctx->curr != LIST) 10127 return -1; 10128 if (sizeof(*out) > size) 10129 return -1; 10130 out->command = ctx->curr; 10131 ctx->objdata = 0; 10132 ctx->object = out; 10133 ctx->objmask = NULL; 10134 out->args.list.group = 10135 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10136 sizeof(double)); 10137 return len; 10138 } 10139 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 10140 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 10141 return -1; 10142 ctx->objdata = 0; 10143 ctx->object = out->args.list.group + out->args.list.group_n++; 10144 ctx->objmask = NULL; 10145 return len; 10146 } 10147 10148 /** Parse tokens for list all aged flows command. */ 10149 static int 10150 parse_aged(struct context *ctx, const struct token *token, 10151 const char *str, unsigned int len, 10152 void *buf, unsigned int size) 10153 { 10154 struct buffer *out = buf; 10155 10156 /* Token name must match. */ 10157 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10158 return -1; 10159 /* Nothing else to do if there is no buffer. */ 10160 if (!out) 10161 return len; 10162 if (!out->command || out->command == QUEUE) { 10163 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 10164 return -1; 10165 if (sizeof(*out) > size) 10166 return -1; 10167 out->command = ctx->curr; 10168 ctx->objdata = 0; 10169 ctx->object = out; 10170 ctx->objmask = NULL; 10171 } 10172 if (ctx->curr == AGED_DESTROY) 10173 out->args.aged.destroy = 1; 10174 return len; 10175 } 10176 10177 /** Parse tokens for isolate command. */ 10178 static int 10179 parse_isolate(struct context *ctx, const struct token *token, 10180 const char *str, unsigned int len, 10181 void *buf, unsigned int size) 10182 { 10183 struct buffer *out = buf; 10184 10185 /* Token name must match. */ 10186 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10187 return -1; 10188 /* Nothing else to do if there is no buffer. */ 10189 if (!out) 10190 return len; 10191 if (!out->command) { 10192 if (ctx->curr != ISOLATE) 10193 return -1; 10194 if (sizeof(*out) > size) 10195 return -1; 10196 out->command = ctx->curr; 10197 ctx->objdata = 0; 10198 ctx->object = out; 10199 ctx->objmask = NULL; 10200 } 10201 return len; 10202 } 10203 10204 /** Parse tokens for info/configure command. */ 10205 static int 10206 parse_configure(struct context *ctx, const struct token *token, 10207 const char *str, unsigned int len, 10208 void *buf, unsigned int size) 10209 { 10210 struct buffer *out = buf; 10211 10212 /* Token name must match. */ 10213 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10214 return -1; 10215 /* Nothing else to do if there is no buffer. */ 10216 if (!out) 10217 return len; 10218 if (!out->command) { 10219 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 10220 return -1; 10221 if (sizeof(*out) > size) 10222 return -1; 10223 out->command = ctx->curr; 10224 ctx->objdata = 0; 10225 ctx->object = out; 10226 ctx->objmask = NULL; 10227 } 10228 return len; 10229 } 10230 10231 /** Parse tokens for template create command. */ 10232 static int 10233 parse_template(struct context *ctx, const struct token *token, 10234 const char *str, unsigned int len, 10235 void *buf, unsigned int size) 10236 { 10237 struct buffer *out = buf; 10238 10239 /* Token name must match. */ 10240 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10241 return -1; 10242 /* Nothing else to do if there is no buffer. */ 10243 if (!out) 10244 return len; 10245 if (!out->command) { 10246 if (ctx->curr != PATTERN_TEMPLATE && 10247 ctx->curr != ACTIONS_TEMPLATE) 10248 return -1; 10249 if (sizeof(*out) > size) 10250 return -1; 10251 out->command = ctx->curr; 10252 ctx->objdata = 0; 10253 ctx->object = out; 10254 ctx->objmask = NULL; 10255 out->args.vc.data = (uint8_t *)out + size; 10256 return len; 10257 } 10258 switch (ctx->curr) { 10259 case PATTERN_TEMPLATE_CREATE: 10260 out->args.vc.pattern = 10261 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10262 sizeof(double)); 10263 out->args.vc.pat_templ_id = UINT32_MAX; 10264 out->command = ctx->curr; 10265 ctx->objdata = 0; 10266 ctx->object = out; 10267 ctx->objmask = NULL; 10268 return len; 10269 case PATTERN_TEMPLATE_EGRESS: 10270 out->args.vc.attr.egress = 1; 10271 return len; 10272 case PATTERN_TEMPLATE_INGRESS: 10273 out->args.vc.attr.ingress = 1; 10274 return len; 10275 case PATTERN_TEMPLATE_TRANSFER: 10276 out->args.vc.attr.transfer = 1; 10277 return len; 10278 case ACTIONS_TEMPLATE_CREATE: 10279 out->args.vc.act_templ_id = UINT32_MAX; 10280 out->command = ctx->curr; 10281 ctx->objdata = 0; 10282 ctx->object = out; 10283 ctx->objmask = NULL; 10284 return len; 10285 case ACTIONS_TEMPLATE_SPEC: 10286 out->args.vc.actions = 10287 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10288 sizeof(double)); 10289 ctx->object = out->args.vc.actions; 10290 ctx->objmask = NULL; 10291 return len; 10292 case ACTIONS_TEMPLATE_MASK: 10293 out->args.vc.masks = 10294 (void *)RTE_ALIGN_CEIL((uintptr_t) 10295 (out->args.vc.actions + 10296 out->args.vc.actions_n), 10297 sizeof(double)); 10298 ctx->object = out->args.vc.masks; 10299 ctx->objmask = NULL; 10300 return len; 10301 case ACTIONS_TEMPLATE_EGRESS: 10302 out->args.vc.attr.egress = 1; 10303 return len; 10304 case ACTIONS_TEMPLATE_INGRESS: 10305 out->args.vc.attr.ingress = 1; 10306 return len; 10307 case ACTIONS_TEMPLATE_TRANSFER: 10308 out->args.vc.attr.transfer = 1; 10309 return len; 10310 default: 10311 return -1; 10312 } 10313 } 10314 10315 /** Parse tokens for template destroy command. */ 10316 static int 10317 parse_template_destroy(struct context *ctx, const struct token *token, 10318 const char *str, unsigned int len, 10319 void *buf, unsigned int size) 10320 { 10321 struct buffer *out = buf; 10322 uint32_t *template_id; 10323 10324 /* Token name must match. */ 10325 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10326 return -1; 10327 /* Nothing else to do if there is no buffer. */ 10328 if (!out) 10329 return len; 10330 if (!out->command || 10331 out->command == PATTERN_TEMPLATE || 10332 out->command == ACTIONS_TEMPLATE) { 10333 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 10334 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 10335 return -1; 10336 if (sizeof(*out) > size) 10337 return -1; 10338 out->command = ctx->curr; 10339 ctx->objdata = 0; 10340 ctx->object = out; 10341 ctx->objmask = NULL; 10342 out->args.templ_destroy.template_id = 10343 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10344 sizeof(double)); 10345 return len; 10346 } 10347 template_id = out->args.templ_destroy.template_id 10348 + out->args.templ_destroy.template_id_n++; 10349 if ((uint8_t *)template_id > (uint8_t *)out + size) 10350 return -1; 10351 ctx->objdata = 0; 10352 ctx->object = template_id; 10353 ctx->objmask = NULL; 10354 return len; 10355 } 10356 10357 /** Parse tokens for table create command. */ 10358 static int 10359 parse_table(struct context *ctx, const struct token *token, 10360 const char *str, unsigned int len, 10361 void *buf, unsigned int size) 10362 { 10363 struct buffer *out = buf; 10364 uint32_t *template_id; 10365 10366 /* Token name must match. */ 10367 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10368 return -1; 10369 /* Nothing else to do if there is no buffer. */ 10370 if (!out) 10371 return len; 10372 if (!out->command) { 10373 if (ctx->curr != TABLE) 10374 return -1; 10375 if (sizeof(*out) > size) 10376 return -1; 10377 out->command = ctx->curr; 10378 ctx->objdata = 0; 10379 ctx->object = out; 10380 ctx->objmask = NULL; 10381 return len; 10382 } 10383 switch (ctx->curr) { 10384 case TABLE_CREATE: 10385 out->command = ctx->curr; 10386 ctx->objdata = 0; 10387 ctx->object = out; 10388 ctx->objmask = NULL; 10389 out->args.table.id = UINT32_MAX; 10390 return len; 10391 case TABLE_PATTERN_TEMPLATE: 10392 out->args.table.pat_templ_id = 10393 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10394 sizeof(double)); 10395 template_id = out->args.table.pat_templ_id 10396 + out->args.table.pat_templ_id_n++; 10397 if ((uint8_t *)template_id > (uint8_t *)out + size) 10398 return -1; 10399 ctx->objdata = 0; 10400 ctx->object = template_id; 10401 ctx->objmask = NULL; 10402 return len; 10403 case TABLE_ACTIONS_TEMPLATE: 10404 out->args.table.act_templ_id = 10405 (void *)RTE_ALIGN_CEIL((uintptr_t) 10406 (out->args.table.pat_templ_id + 10407 out->args.table.pat_templ_id_n), 10408 sizeof(double)); 10409 template_id = out->args.table.act_templ_id 10410 + out->args.table.act_templ_id_n++; 10411 if ((uint8_t *)template_id > (uint8_t *)out + size) 10412 return -1; 10413 ctx->objdata = 0; 10414 ctx->object = template_id; 10415 ctx->objmask = NULL; 10416 return len; 10417 case TABLE_INGRESS: 10418 out->args.table.attr.flow_attr.ingress = 1; 10419 return len; 10420 case TABLE_EGRESS: 10421 out->args.table.attr.flow_attr.egress = 1; 10422 return len; 10423 case TABLE_TRANSFER: 10424 out->args.table.attr.flow_attr.transfer = 1; 10425 return len; 10426 case TABLE_TRANSFER_WIRE_ORIG: 10427 if (!out->args.table.attr.flow_attr.transfer) 10428 return -1; 10429 out->args.table.attr.specialize = RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; 10430 return len; 10431 case TABLE_TRANSFER_VPORT_ORIG: 10432 if (!out->args.table.attr.flow_attr.transfer) 10433 return -1; 10434 out->args.table.attr.specialize = RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; 10435 return len; 10436 case TABLE_RULES_NUMBER: 10437 ctx->objdata = 0; 10438 ctx->object = out; 10439 ctx->objmask = NULL; 10440 return len; 10441 default: 10442 return -1; 10443 } 10444 } 10445 10446 /** Parse tokens for table destroy command. */ 10447 static int 10448 parse_table_destroy(struct context *ctx, const struct token *token, 10449 const char *str, unsigned int len, 10450 void *buf, unsigned int size) 10451 { 10452 struct buffer *out = buf; 10453 uint32_t *table_id; 10454 10455 /* Token name must match. */ 10456 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10457 return -1; 10458 /* Nothing else to do if there is no buffer. */ 10459 if (!out) 10460 return len; 10461 if (!out->command || out->command == TABLE) { 10462 if (ctx->curr != TABLE_DESTROY) 10463 return -1; 10464 if (sizeof(*out) > size) 10465 return -1; 10466 out->command = ctx->curr; 10467 ctx->objdata = 0; 10468 ctx->object = out; 10469 ctx->objmask = NULL; 10470 out->args.table_destroy.table_id = 10471 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10472 sizeof(double)); 10473 return len; 10474 } 10475 table_id = out->args.table_destroy.table_id 10476 + out->args.table_destroy.table_id_n++; 10477 if ((uint8_t *)table_id > (uint8_t *)out + size) 10478 return -1; 10479 ctx->objdata = 0; 10480 ctx->object = table_id; 10481 ctx->objmask = NULL; 10482 return len; 10483 } 10484 10485 /** Parse tokens for queue create commands. */ 10486 static int 10487 parse_qo(struct context *ctx, const struct token *token, 10488 const char *str, unsigned int len, 10489 void *buf, unsigned int size) 10490 { 10491 struct buffer *out = buf; 10492 10493 /* Token name must match. */ 10494 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10495 return -1; 10496 /* Nothing else to do if there is no buffer. */ 10497 if (!out) 10498 return len; 10499 if (!out->command) { 10500 if (ctx->curr != QUEUE) 10501 return -1; 10502 if (sizeof(*out) > size) 10503 return -1; 10504 out->command = ctx->curr; 10505 ctx->objdata = 0; 10506 ctx->object = out; 10507 ctx->objmask = NULL; 10508 out->args.vc.data = (uint8_t *)out + size; 10509 return len; 10510 } 10511 switch (ctx->curr) { 10512 case QUEUE_CREATE: 10513 case QUEUE_UPDATE: 10514 out->command = ctx->curr; 10515 ctx->objdata = 0; 10516 ctx->object = out; 10517 ctx->objmask = NULL; 10518 out->args.vc.rule_id = UINT32_MAX; 10519 return len; 10520 case QUEUE_TEMPLATE_TABLE: 10521 case QUEUE_PATTERN_TEMPLATE: 10522 case QUEUE_ACTIONS_TEMPLATE: 10523 case QUEUE_CREATE_POSTPONE: 10524 case QUEUE_RULE_ID: 10525 case QUEUE_UPDATE_ID: 10526 return len; 10527 case ITEM_PATTERN: 10528 out->args.vc.pattern = 10529 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10530 sizeof(double)); 10531 ctx->object = out->args.vc.pattern; 10532 ctx->objmask = NULL; 10533 return len; 10534 case ACTIONS: 10535 out->args.vc.actions = 10536 (void *)RTE_ALIGN_CEIL((uintptr_t) 10537 (out->args.vc.pattern + 10538 out->args.vc.pattern_n), 10539 sizeof(double)); 10540 ctx->object = out->args.vc.actions; 10541 ctx->objmask = NULL; 10542 return len; 10543 default: 10544 return -1; 10545 } 10546 } 10547 10548 /** Parse tokens for queue destroy command. */ 10549 static int 10550 parse_qo_destroy(struct context *ctx, const struct token *token, 10551 const char *str, unsigned int len, 10552 void *buf, unsigned int size) 10553 { 10554 struct buffer *out = buf; 10555 uint64_t *flow_id; 10556 10557 /* Token name must match. */ 10558 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10559 return -1; 10560 /* Nothing else to do if there is no buffer. */ 10561 if (!out) 10562 return len; 10563 if (!out->command || out->command == QUEUE) { 10564 if (ctx->curr != QUEUE_DESTROY) 10565 return -1; 10566 if (sizeof(*out) > size) 10567 return -1; 10568 out->command = ctx->curr; 10569 ctx->objdata = 0; 10570 ctx->object = out; 10571 ctx->objmask = NULL; 10572 out->args.destroy.rule = 10573 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10574 sizeof(double)); 10575 return len; 10576 } 10577 switch (ctx->curr) { 10578 case QUEUE_DESTROY_ID: 10579 flow_id = out->args.destroy.rule 10580 + out->args.destroy.rule_n++; 10581 if ((uint8_t *)flow_id > (uint8_t *)out + size) 10582 return -1; 10583 ctx->objdata = 0; 10584 ctx->object = flow_id; 10585 ctx->objmask = NULL; 10586 return len; 10587 case QUEUE_DESTROY_POSTPONE: 10588 return len; 10589 default: 10590 return -1; 10591 } 10592 } 10593 10594 /** Parse tokens for push queue command. */ 10595 static int 10596 parse_push(struct context *ctx, const struct token *token, 10597 const char *str, unsigned int len, 10598 void *buf, unsigned int size) 10599 { 10600 struct buffer *out = buf; 10601 10602 /* Token name must match. */ 10603 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10604 return -1; 10605 /* Nothing else to do if there is no buffer. */ 10606 if (!out) 10607 return len; 10608 if (!out->command) { 10609 if (ctx->curr != PUSH) 10610 return -1; 10611 if (sizeof(*out) > size) 10612 return -1; 10613 out->command = ctx->curr; 10614 ctx->objdata = 0; 10615 ctx->object = out; 10616 ctx->objmask = NULL; 10617 out->args.vc.data = (uint8_t *)out + size; 10618 } 10619 return len; 10620 } 10621 10622 /** Parse tokens for pull command. */ 10623 static int 10624 parse_pull(struct context *ctx, const struct token *token, 10625 const char *str, unsigned int len, 10626 void *buf, unsigned int size) 10627 { 10628 struct buffer *out = buf; 10629 10630 /* Token name must match. */ 10631 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10632 return -1; 10633 /* Nothing else to do if there is no buffer. */ 10634 if (!out) 10635 return len; 10636 if (!out->command) { 10637 if (ctx->curr != PULL) 10638 return -1; 10639 if (sizeof(*out) > size) 10640 return -1; 10641 out->command = ctx->curr; 10642 ctx->objdata = 0; 10643 ctx->object = out; 10644 ctx->objmask = NULL; 10645 out->args.vc.data = (uint8_t *)out + size; 10646 } 10647 return len; 10648 } 10649 10650 /** Parse tokens for hash calculation commands. */ 10651 static int 10652 parse_hash(struct context *ctx, const struct token *token, 10653 const char *str, unsigned int len, 10654 void *buf, unsigned int size) 10655 { 10656 struct buffer *out = buf; 10657 10658 /* Token name must match. */ 10659 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10660 return -1; 10661 /* Nothing else to do if there is no buffer. */ 10662 if (!out) 10663 return len; 10664 if (!out->command) { 10665 if (ctx->curr != HASH) 10666 return -1; 10667 if (sizeof(*out) > size) 10668 return -1; 10669 out->command = ctx->curr; 10670 ctx->objdata = 0; 10671 ctx->object = out; 10672 ctx->objmask = NULL; 10673 out->args.vc.data = (uint8_t *)out + size; 10674 return len; 10675 } 10676 switch (ctx->curr) { 10677 case HASH_CALC_TABLE: 10678 case HASH_CALC_PATTERN_INDEX: 10679 return len; 10680 case ITEM_PATTERN: 10681 out->args.vc.pattern = 10682 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10683 sizeof(double)); 10684 ctx->object = out->args.vc.pattern; 10685 ctx->objmask = NULL; 10686 return len; 10687 default: 10688 return -1; 10689 } 10690 } 10691 10692 static int 10693 parse_group(struct context *ctx, const struct token *token, 10694 const char *str, unsigned int len, 10695 void *buf, unsigned int size) 10696 { 10697 struct buffer *out = buf; 10698 10699 /* Token name must match. */ 10700 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10701 return -1; 10702 /* Nothing else to do if there is no buffer. */ 10703 if (!out) 10704 return len; 10705 if (!out->command) { 10706 if (ctx->curr != FLOW_GROUP) 10707 return -1; 10708 if (sizeof(*out) > size) 10709 return -1; 10710 out->command = ctx->curr; 10711 ctx->objdata = 0; 10712 ctx->object = out; 10713 ctx->objmask = NULL; 10714 out->args.vc.data = (uint8_t *)out + size; 10715 return len; 10716 } 10717 switch (ctx->curr) { 10718 case GROUP_INGRESS: 10719 out->args.vc.attr.ingress = 1; 10720 return len; 10721 case GROUP_EGRESS: 10722 out->args.vc.attr.egress = 1; 10723 return len; 10724 case GROUP_TRANSFER: 10725 out->args.vc.attr.transfer = 1; 10726 return len; 10727 case GROUP_SET_MISS_ACTIONS: 10728 out->command = ctx->curr; 10729 ctx->objdata = 0; 10730 ctx->object = out; 10731 ctx->objmask = NULL; 10732 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10733 sizeof(double)); 10734 return len; 10735 default: 10736 return -1; 10737 } 10738 } 10739 10740 static int 10741 parse_flex(struct context *ctx, const struct token *token, 10742 const char *str, unsigned int len, 10743 void *buf, unsigned int size) 10744 { 10745 struct buffer *out = buf; 10746 10747 /* Token name must match. */ 10748 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10749 return -1; 10750 /* Nothing else to do if there is no buffer. */ 10751 if (!out) 10752 return len; 10753 if (out->command == ZERO) { 10754 if (ctx->curr != FLEX) 10755 return -1; 10756 if (sizeof(*out) > size) 10757 return -1; 10758 out->command = ctx->curr; 10759 ctx->objdata = 0; 10760 ctx->object = out; 10761 ctx->objmask = NULL; 10762 } else { 10763 switch (ctx->curr) { 10764 default: 10765 break; 10766 case FLEX_ITEM_INIT: 10767 case FLEX_ITEM_CREATE: 10768 case FLEX_ITEM_DESTROY: 10769 out->command = ctx->curr; 10770 break; 10771 } 10772 } 10773 10774 return len; 10775 } 10776 10777 static int 10778 parse_tunnel(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 10784 /* Token name must match. */ 10785 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10786 return -1; 10787 /* Nothing else to do if there is no buffer. */ 10788 if (!out) 10789 return len; 10790 if (!out->command) { 10791 if (ctx->curr != TUNNEL) 10792 return -1; 10793 if (sizeof(*out) > size) 10794 return -1; 10795 out->command = ctx->curr; 10796 ctx->objdata = 0; 10797 ctx->object = out; 10798 ctx->objmask = NULL; 10799 } else { 10800 switch (ctx->curr) { 10801 default: 10802 break; 10803 case TUNNEL_CREATE: 10804 case TUNNEL_DESTROY: 10805 case TUNNEL_LIST: 10806 out->command = ctx->curr; 10807 break; 10808 case TUNNEL_CREATE_TYPE: 10809 case TUNNEL_DESTROY_ID: 10810 ctx->object = &out->args.vc.tunnel_ops; 10811 break; 10812 } 10813 } 10814 10815 return len; 10816 } 10817 10818 /** 10819 * Parse signed/unsigned integers 8 to 64-bit long. 10820 * 10821 * Last argument (ctx->args) is retrieved to determine integer type and 10822 * storage location. 10823 */ 10824 static int 10825 parse_int(struct context *ctx, const struct token *token, 10826 const char *str, unsigned int len, 10827 void *buf, unsigned int size) 10828 { 10829 const struct arg *arg = pop_args(ctx); 10830 uintmax_t u; 10831 char *end; 10832 10833 (void)token; 10834 /* Argument is expected. */ 10835 if (!arg) 10836 return -1; 10837 errno = 0; 10838 u = arg->sign ? 10839 (uintmax_t)strtoimax(str, &end, 0) : 10840 strtoumax(str, &end, 0); 10841 if (errno || (size_t)(end - str) != len) 10842 goto error; 10843 if (arg->bounded && 10844 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 10845 (intmax_t)u > (intmax_t)arg->max)) || 10846 (!arg->sign && (u < arg->min || u > arg->max)))) 10847 goto error; 10848 if (!ctx->object) 10849 return len; 10850 if (arg->mask) { 10851 if (!arg_entry_bf_fill(ctx->object, u, arg) || 10852 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 10853 goto error; 10854 return len; 10855 } 10856 buf = (uint8_t *)ctx->object + arg->offset; 10857 size = arg->size; 10858 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 10859 return -1; 10860 objmask: 10861 switch (size) { 10862 case sizeof(uint8_t): 10863 *(uint8_t *)buf = u; 10864 break; 10865 case sizeof(uint16_t): 10866 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 10867 break; 10868 case sizeof(uint8_t [3]): 10869 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 10870 if (!arg->hton) { 10871 ((uint8_t *)buf)[0] = u; 10872 ((uint8_t *)buf)[1] = u >> 8; 10873 ((uint8_t *)buf)[2] = u >> 16; 10874 break; 10875 } 10876 #endif 10877 ((uint8_t *)buf)[0] = u >> 16; 10878 ((uint8_t *)buf)[1] = u >> 8; 10879 ((uint8_t *)buf)[2] = u; 10880 break; 10881 case sizeof(uint32_t): 10882 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 10883 break; 10884 case sizeof(uint64_t): 10885 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 10886 break; 10887 default: 10888 goto error; 10889 } 10890 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 10891 u = -1; 10892 buf = (uint8_t *)ctx->objmask + arg->offset; 10893 goto objmask; 10894 } 10895 return len; 10896 error: 10897 push_args(ctx, arg); 10898 return -1; 10899 } 10900 10901 /** 10902 * Parse a string. 10903 * 10904 * Three arguments (ctx->args) are retrieved from the stack to store data, 10905 * its actual length and address (in that order). 10906 */ 10907 static int 10908 parse_string(struct context *ctx, const struct token *token, 10909 const char *str, unsigned int len, 10910 void *buf, unsigned int size) 10911 { 10912 const struct arg *arg_data = pop_args(ctx); 10913 const struct arg *arg_len = pop_args(ctx); 10914 const struct arg *arg_addr = pop_args(ctx); 10915 char tmp[16]; /* Ought to be enough. */ 10916 int ret; 10917 10918 /* Arguments are expected. */ 10919 if (!arg_data) 10920 return -1; 10921 if (!arg_len) { 10922 push_args(ctx, arg_data); 10923 return -1; 10924 } 10925 if (!arg_addr) { 10926 push_args(ctx, arg_len); 10927 push_args(ctx, arg_data); 10928 return -1; 10929 } 10930 size = arg_data->size; 10931 /* Bit-mask fill is not supported. */ 10932 if (arg_data->mask || size < len) 10933 goto error; 10934 if (!ctx->object) 10935 return len; 10936 /* Let parse_int() fill length information first. */ 10937 ret = snprintf(tmp, sizeof(tmp), "%u", len); 10938 if (ret < 0) 10939 goto error; 10940 push_args(ctx, arg_len); 10941 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 10942 if (ret < 0) { 10943 pop_args(ctx); 10944 goto error; 10945 } 10946 buf = (uint8_t *)ctx->object + arg_data->offset; 10947 /* Output buffer is not necessarily NUL-terminated. */ 10948 memcpy(buf, str, len); 10949 memset((uint8_t *)buf + len, 0x00, size - len); 10950 if (ctx->objmask) 10951 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 10952 /* Save address if requested. */ 10953 if (arg_addr->size) { 10954 memcpy((uint8_t *)ctx->object + arg_addr->offset, 10955 (void *[]){ 10956 (uint8_t *)ctx->object + arg_data->offset 10957 }, 10958 arg_addr->size); 10959 if (ctx->objmask) 10960 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 10961 (void *[]){ 10962 (uint8_t *)ctx->objmask + arg_data->offset 10963 }, 10964 arg_addr->size); 10965 } 10966 return len; 10967 error: 10968 push_args(ctx, arg_addr); 10969 push_args(ctx, arg_len); 10970 push_args(ctx, arg_data); 10971 return -1; 10972 } 10973 10974 static int 10975 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 10976 { 10977 const uint8_t *head = dst; 10978 uint32_t left; 10979 10980 if (*size == 0) 10981 return -1; 10982 10983 left = *size; 10984 10985 /* Convert chars to bytes */ 10986 while (left) { 10987 char tmp[3], *end = tmp; 10988 uint32_t read_lim = left & 1 ? 1 : 2; 10989 10990 snprintf(tmp, read_lim + 1, "%s", src); 10991 *dst = strtoul(tmp, &end, 16); 10992 if (*end) { 10993 *dst = 0; 10994 *size = (uint32_t)(dst - head); 10995 return -1; 10996 } 10997 left -= read_lim; 10998 src += read_lim; 10999 dst++; 11000 } 11001 *dst = 0; 11002 *size = (uint32_t)(dst - head); 11003 return 0; 11004 } 11005 11006 static int 11007 parse_hex(struct context *ctx, const struct token *token, 11008 const char *str, unsigned int len, 11009 void *buf, unsigned int size) 11010 { 11011 const struct arg *arg_data = pop_args(ctx); 11012 const struct arg *arg_len = pop_args(ctx); 11013 const struct arg *arg_addr = pop_args(ctx); 11014 char tmp[16]; /* Ought to be enough. */ 11015 int ret; 11016 unsigned int hexlen = len; 11017 unsigned int length = 256; 11018 uint8_t hex_tmp[length]; 11019 11020 /* Arguments are expected. */ 11021 if (!arg_data) 11022 return -1; 11023 if (!arg_len) { 11024 push_args(ctx, arg_data); 11025 return -1; 11026 } 11027 if (!arg_addr) { 11028 push_args(ctx, arg_len); 11029 push_args(ctx, arg_data); 11030 return -1; 11031 } 11032 size = arg_data->size; 11033 /* Bit-mask fill is not supported. */ 11034 if (arg_data->mask) 11035 goto error; 11036 if (!ctx->object) 11037 return len; 11038 11039 /* translate bytes string to array. */ 11040 if (str[0] == '0' && ((str[1] == 'x') || 11041 (str[1] == 'X'))) { 11042 str += 2; 11043 hexlen -= 2; 11044 } 11045 if (hexlen > length) 11046 goto error; 11047 ret = parse_hex_string(str, hex_tmp, &hexlen); 11048 if (ret < 0) 11049 goto error; 11050 /* Check the converted binary fits into data buffer. */ 11051 if (hexlen > size) 11052 goto error; 11053 /* Let parse_int() fill length information first. */ 11054 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 11055 if (ret < 0) 11056 goto error; 11057 /* Save length if requested. */ 11058 if (arg_len->size) { 11059 push_args(ctx, arg_len); 11060 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11061 if (ret < 0) { 11062 pop_args(ctx); 11063 goto error; 11064 } 11065 } 11066 buf = (uint8_t *)ctx->object + arg_data->offset; 11067 /* Output buffer is not necessarily NUL-terminated. */ 11068 memcpy(buf, hex_tmp, hexlen); 11069 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 11070 if (ctx->objmask) 11071 memset((uint8_t *)ctx->objmask + arg_data->offset, 11072 0xff, hexlen); 11073 /* Save address if requested. */ 11074 if (arg_addr->size) { 11075 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11076 (void *[]){ 11077 (uint8_t *)ctx->object + arg_data->offset 11078 }, 11079 arg_addr->size); 11080 if (ctx->objmask) 11081 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11082 (void *[]){ 11083 (uint8_t *)ctx->objmask + arg_data->offset 11084 }, 11085 arg_addr->size); 11086 } 11087 return len; 11088 error: 11089 push_args(ctx, arg_addr); 11090 push_args(ctx, arg_len); 11091 push_args(ctx, arg_data); 11092 return -1; 11093 11094 } 11095 11096 /** 11097 * Parse a zero-ended string. 11098 */ 11099 static int 11100 parse_string0(struct context *ctx, const struct token *token __rte_unused, 11101 const char *str, unsigned int len, 11102 void *buf, unsigned int size) 11103 { 11104 const struct arg *arg_data = pop_args(ctx); 11105 11106 /* Arguments are expected. */ 11107 if (!arg_data) 11108 return -1; 11109 size = arg_data->size; 11110 /* Bit-mask fill is not supported. */ 11111 if (arg_data->mask || size < len + 1) 11112 goto error; 11113 if (!ctx->object) 11114 return len; 11115 buf = (uint8_t *)ctx->object + arg_data->offset; 11116 strncpy(buf, str, len); 11117 if (ctx->objmask) 11118 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11119 return len; 11120 error: 11121 push_args(ctx, arg_data); 11122 return -1; 11123 } 11124 11125 /** 11126 * Parse a MAC address. 11127 * 11128 * Last argument (ctx->args) is retrieved to determine storage size and 11129 * location. 11130 */ 11131 static int 11132 parse_mac_addr(struct context *ctx, const struct token *token, 11133 const char *str, unsigned int len, 11134 void *buf, unsigned int size) 11135 { 11136 const struct arg *arg = pop_args(ctx); 11137 struct rte_ether_addr tmp; 11138 int ret; 11139 11140 (void)token; 11141 /* Argument is expected. */ 11142 if (!arg) 11143 return -1; 11144 size = arg->size; 11145 /* Bit-mask fill is not supported. */ 11146 if (arg->mask || size != sizeof(tmp)) 11147 goto error; 11148 /* Only network endian is supported. */ 11149 if (!arg->hton) 11150 goto error; 11151 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 11152 if (ret < 0 || (unsigned int)ret != len) 11153 goto error; 11154 if (!ctx->object) 11155 return len; 11156 buf = (uint8_t *)ctx->object + arg->offset; 11157 memcpy(buf, &tmp, size); 11158 if (ctx->objmask) 11159 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11160 return len; 11161 error: 11162 push_args(ctx, arg); 11163 return -1; 11164 } 11165 11166 /** 11167 * Parse an IPv4 address. 11168 * 11169 * Last argument (ctx->args) is retrieved to determine storage size and 11170 * location. 11171 */ 11172 static int 11173 parse_ipv4_addr(struct context *ctx, const struct token *token, 11174 const char *str, unsigned int len, 11175 void *buf, unsigned int size) 11176 { 11177 const struct arg *arg = pop_args(ctx); 11178 char str2[len + 1]; 11179 struct in_addr tmp; 11180 int ret; 11181 11182 /* Argument is expected. */ 11183 if (!arg) 11184 return -1; 11185 size = arg->size; 11186 /* Bit-mask fill is not supported. */ 11187 if (arg->mask || size != sizeof(tmp)) 11188 goto error; 11189 /* Only network endian is supported. */ 11190 if (!arg->hton) 11191 goto error; 11192 memcpy(str2, str, len); 11193 str2[len] = '\0'; 11194 ret = inet_pton(AF_INET, str2, &tmp); 11195 if (ret != 1) { 11196 /* Attempt integer parsing. */ 11197 push_args(ctx, arg); 11198 return parse_int(ctx, token, str, len, buf, size); 11199 } 11200 if (!ctx->object) 11201 return len; 11202 buf = (uint8_t *)ctx->object + arg->offset; 11203 memcpy(buf, &tmp, size); 11204 if (ctx->objmask) 11205 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11206 return len; 11207 error: 11208 push_args(ctx, arg); 11209 return -1; 11210 } 11211 11212 /** 11213 * Parse an IPv6 address. 11214 * 11215 * Last argument (ctx->args) is retrieved to determine storage size and 11216 * location. 11217 */ 11218 static int 11219 parse_ipv6_addr(struct context *ctx, const struct token *token, 11220 const char *str, unsigned int len, 11221 void *buf, unsigned int size) 11222 { 11223 const struct arg *arg = pop_args(ctx); 11224 char str2[len + 1]; 11225 struct in6_addr tmp; 11226 int ret; 11227 11228 (void)token; 11229 /* Argument is expected. */ 11230 if (!arg) 11231 return -1; 11232 size = arg->size; 11233 /* Bit-mask fill is not supported. */ 11234 if (arg->mask || size != sizeof(tmp)) 11235 goto error; 11236 /* Only network endian is supported. */ 11237 if (!arg->hton) 11238 goto error; 11239 memcpy(str2, str, len); 11240 str2[len] = '\0'; 11241 ret = inet_pton(AF_INET6, str2, &tmp); 11242 if (ret != 1) 11243 goto error; 11244 if (!ctx->object) 11245 return len; 11246 buf = (uint8_t *)ctx->object + arg->offset; 11247 memcpy(buf, &tmp, size); 11248 if (ctx->objmask) 11249 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11250 return len; 11251 error: 11252 push_args(ctx, arg); 11253 return -1; 11254 } 11255 11256 /** Boolean values (even indices stand for false). */ 11257 static const char *const boolean_name[] = { 11258 "0", "1", 11259 "false", "true", 11260 "no", "yes", 11261 "N", "Y", 11262 "off", "on", 11263 NULL, 11264 }; 11265 11266 /** 11267 * Parse a boolean value. 11268 * 11269 * Last argument (ctx->args) is retrieved to determine storage size and 11270 * location. 11271 */ 11272 static int 11273 parse_boolean(struct context *ctx, const struct token *token, 11274 const char *str, unsigned int len, 11275 void *buf, unsigned int size) 11276 { 11277 const struct arg *arg = pop_args(ctx); 11278 unsigned int i; 11279 int ret; 11280 11281 /* Argument is expected. */ 11282 if (!arg) 11283 return -1; 11284 for (i = 0; boolean_name[i]; ++i) 11285 if (!strcmp_partial(boolean_name[i], str, len)) 11286 break; 11287 /* Process token as integer. */ 11288 if (boolean_name[i]) 11289 str = i & 1 ? "1" : "0"; 11290 push_args(ctx, arg); 11291 ret = parse_int(ctx, token, str, strlen(str), buf, size); 11292 return ret > 0 ? (int)len : ret; 11293 } 11294 11295 /** Parse port and update context. */ 11296 static int 11297 parse_port(struct context *ctx, const struct token *token, 11298 const char *str, unsigned int len, 11299 void *buf, unsigned int size) 11300 { 11301 struct buffer *out = &(struct buffer){ .port = 0 }; 11302 int ret; 11303 11304 if (buf) 11305 out = buf; 11306 else { 11307 ctx->objdata = 0; 11308 ctx->object = out; 11309 ctx->objmask = NULL; 11310 size = sizeof(*out); 11311 } 11312 ret = parse_int(ctx, token, str, len, out, size); 11313 if (ret >= 0) 11314 ctx->port = out->port; 11315 if (!buf) 11316 ctx->object = NULL; 11317 return ret; 11318 } 11319 11320 /** Parse tokens for shared indirect actions. */ 11321 static int 11322 parse_ia_port(struct context *ctx, const struct token *token, 11323 const char *str, unsigned int len, 11324 void *buf, unsigned int size) 11325 { 11326 struct rte_flow_action *action = ctx->object; 11327 uint32_t id; 11328 int ret; 11329 11330 (void)buf; 11331 (void)size; 11332 ctx->objdata = 0; 11333 ctx->object = &id; 11334 ctx->objmask = NULL; 11335 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11336 ctx->object = action; 11337 if (ret != (int)len) 11338 return ret; 11339 /* set indirect action */ 11340 if (action) 11341 action->conf = (void *)(uintptr_t)id; 11342 return ret; 11343 } 11344 11345 static int 11346 parse_ia_id2ptr(struct context *ctx, const struct token *token, 11347 const char *str, unsigned int len, 11348 void *buf, unsigned int size) 11349 { 11350 struct rte_flow_action *action = ctx->object; 11351 uint32_t id; 11352 int ret; 11353 11354 (void)buf; 11355 (void)size; 11356 ctx->objdata = 0; 11357 ctx->object = &id; 11358 ctx->objmask = NULL; 11359 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11360 ctx->object = action; 11361 if (ret != (int)len) 11362 return ret; 11363 /* set indirect action */ 11364 if (action) { 11365 portid_t port_id = ctx->port; 11366 if (ctx->prev == INDIRECT_ACTION_PORT) 11367 port_id = (portid_t)(uintptr_t)action->conf; 11368 action->conf = port_action_handle_get_by_id(port_id, id); 11369 ret = (action->conf) ? ret : -1; 11370 } 11371 return ret; 11372 } 11373 11374 static int 11375 parse_indlst_id2ptr(struct context *ctx, const struct token *token, 11376 const char *str, unsigned int len, 11377 __rte_unused void *buf, __rte_unused unsigned int size) 11378 { 11379 struct rte_flow_action *action = ctx->object; 11380 struct rte_flow_action_indirect_list *action_conf; 11381 const struct indlst_conf *indlst_conf; 11382 uint32_t id; 11383 int ret; 11384 11385 if (!action) 11386 return -1; 11387 ctx->objdata = 0; 11388 ctx->object = &id; 11389 ctx->objmask = NULL; 11390 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11391 if (ret != (int)len) 11392 return ret; 11393 ctx->object = action; 11394 action_conf = (void *)(uintptr_t)action->conf; 11395 action_conf->conf = NULL; 11396 switch (ctx->curr) { 11397 case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: 11398 action_conf->handle = (typeof(action_conf->handle)) 11399 port_action_handle_get_by_id(ctx->port, id); 11400 if (!action_conf->handle) { 11401 printf("no indirect list handle for id %u\n", id); 11402 return -1; 11403 } 11404 break; 11405 case INDIRECT_LIST_ACTION_ID2PTR_CONF: 11406 indlst_conf = indirect_action_list_conf_get(id); 11407 if (!indlst_conf) 11408 return -1; 11409 action_conf->conf = (const void **)indlst_conf->conf; 11410 break; 11411 default: 11412 break; 11413 } 11414 return ret; 11415 } 11416 11417 static int 11418 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 11419 const char *str, unsigned int len, 11420 void *buf, unsigned int size) 11421 { 11422 struct rte_flow_action *action = ctx->object; 11423 struct rte_flow_action_meter_mark *meter; 11424 struct rte_flow_meter_profile *profile = NULL; 11425 uint32_t id = 0; 11426 int ret; 11427 11428 (void)buf; 11429 (void)size; 11430 ctx->objdata = 0; 11431 ctx->object = &id; 11432 ctx->objmask = NULL; 11433 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11434 ctx->object = action; 11435 if (ret != (int)len) 11436 return ret; 11437 /* set meter profile */ 11438 if (action) { 11439 meter = (struct rte_flow_action_meter_mark *) 11440 (uintptr_t)(action->conf); 11441 profile = port_meter_profile_get_by_id(ctx->port, id); 11442 meter->profile = profile; 11443 ret = (profile) ? ret : -1; 11444 } 11445 return ret; 11446 } 11447 11448 static int 11449 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 11450 const char *str, unsigned int len, 11451 void *buf, unsigned int size) 11452 { 11453 struct rte_flow_action *action = ctx->object; 11454 struct rte_flow_action_meter_mark *meter; 11455 struct rte_flow_meter_policy *policy = NULL; 11456 uint32_t id = 0; 11457 int ret; 11458 11459 (void)buf; 11460 (void)size; 11461 ctx->objdata = 0; 11462 ctx->object = &id; 11463 ctx->objmask = NULL; 11464 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11465 ctx->object = action; 11466 if (ret != (int)len) 11467 return ret; 11468 /* set meter policy */ 11469 if (action) { 11470 meter = (struct rte_flow_action_meter_mark *) 11471 (uintptr_t)(action->conf); 11472 policy = port_meter_policy_get_by_id(ctx->port, id); 11473 meter->policy = policy; 11474 ret = (policy) ? ret : -1; 11475 } 11476 return ret; 11477 } 11478 11479 /** Parse set command, initialize output buffer for subsequent tokens. */ 11480 static int 11481 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 11482 const char *str, unsigned int len, 11483 void *buf, unsigned int size) 11484 { 11485 struct buffer *out = buf; 11486 11487 /* Token name must match. */ 11488 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11489 return -1; 11490 /* Nothing else to do if there is no buffer. */ 11491 if (!out) 11492 return len; 11493 /* Make sure buffer is large enough. */ 11494 if (size < sizeof(*out)) 11495 return -1; 11496 ctx->objdata = 0; 11497 ctx->objmask = NULL; 11498 ctx->object = out; 11499 if (!out->command) 11500 return -1; 11501 out->command = ctx->curr; 11502 /* For encap/decap we need is pattern */ 11503 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11504 sizeof(double)); 11505 return len; 11506 } 11507 11508 /** Parse set command, initialize output buffer for subsequent tokens. */ 11509 static int 11510 parse_set_sample_action(struct context *ctx, const struct token *token, 11511 const char *str, unsigned int len, 11512 void *buf, unsigned int size) 11513 { 11514 struct buffer *out = buf; 11515 11516 /* Token name must match. */ 11517 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11518 return -1; 11519 /* Nothing else to do if there is no buffer. */ 11520 if (!out) 11521 return len; 11522 /* Make sure buffer is large enough. */ 11523 if (size < sizeof(*out)) 11524 return -1; 11525 ctx->objdata = 0; 11526 ctx->objmask = NULL; 11527 ctx->object = out; 11528 if (!out->command) 11529 return -1; 11530 out->command = ctx->curr; 11531 /* For sampler we need is actions */ 11532 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11533 sizeof(double)); 11534 return len; 11535 } 11536 11537 /** Parse set command, initialize output buffer for subsequent tokens. */ 11538 static int 11539 parse_set_ipv6_ext_action(struct context *ctx, const struct token *token, 11540 const char *str, unsigned int len, 11541 void *buf, unsigned int size) 11542 { 11543 struct buffer *out = buf; 11544 11545 /* Token name must match. */ 11546 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11547 return -1; 11548 /* Nothing else to do if there is no buffer. */ 11549 if (!out) 11550 return len; 11551 /* Make sure buffer is large enough. */ 11552 if (size < sizeof(*out)) 11553 return -1; 11554 ctx->objdata = 0; 11555 ctx->objmask = NULL; 11556 ctx->object = out; 11557 if (!out->command) 11558 return -1; 11559 out->command = ctx->curr; 11560 /* For ipv6_ext_push/remove we need is pattern */ 11561 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11562 sizeof(double)); 11563 return len; 11564 } 11565 11566 /** 11567 * Parse set raw_encap/raw_decap command, 11568 * initialize output buffer for subsequent tokens. 11569 */ 11570 static int 11571 parse_set_init(struct context *ctx, const struct token *token, 11572 const char *str, unsigned int len, 11573 void *buf, unsigned int size) 11574 { 11575 struct buffer *out = buf; 11576 11577 /* Token name must match. */ 11578 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11579 return -1; 11580 /* Nothing else to do if there is no buffer. */ 11581 if (!out) 11582 return len; 11583 /* Make sure buffer is large enough. */ 11584 if (size < sizeof(*out)) 11585 return -1; 11586 /* Initialize buffer. */ 11587 memset(out, 0x00, sizeof(*out)); 11588 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 11589 ctx->objdata = 0; 11590 ctx->object = out; 11591 ctx->objmask = NULL; 11592 if (!out->command) { 11593 if (ctx->curr != SET) 11594 return -1; 11595 if (sizeof(*out) > size) 11596 return -1; 11597 out->command = ctx->curr; 11598 out->args.vc.data = (uint8_t *)out + size; 11599 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11600 sizeof(double)); 11601 } 11602 return len; 11603 } 11604 11605 /* 11606 * Replace testpmd handles in a flex flow item with real values. 11607 */ 11608 static int 11609 parse_flex_handle(struct context *ctx, const struct token *token, 11610 const char *str, unsigned int len, 11611 void *buf, unsigned int size) 11612 { 11613 struct rte_flow_item_flex *spec, *mask; 11614 const struct rte_flow_item_flex *src_spec, *src_mask; 11615 const struct arg *arg = pop_args(ctx); 11616 uint32_t offset; 11617 uint16_t handle; 11618 int ret; 11619 11620 if (!arg) { 11621 printf("Bad environment\n"); 11622 return -1; 11623 } 11624 offset = arg->offset; 11625 push_args(ctx, arg); 11626 ret = parse_int(ctx, token, str, len, buf, size); 11627 if (ret <= 0 || !ctx->object) 11628 return ret; 11629 if (ctx->port >= RTE_MAX_ETHPORTS) { 11630 printf("Bad port\n"); 11631 return -1; 11632 } 11633 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 11634 const struct flex_item *fp; 11635 spec = ctx->object; 11636 handle = (uint16_t)(uintptr_t)spec->handle; 11637 if (handle >= FLEX_MAX_PARSERS_NUM) { 11638 printf("Bad flex item handle\n"); 11639 return -1; 11640 } 11641 fp = flex_items[ctx->port][handle]; 11642 if (!fp) { 11643 printf("Bad flex item handle\n"); 11644 return -1; 11645 } 11646 spec->handle = fp->flex_handle; 11647 mask = spec + 2; /* spec, last, mask */ 11648 mask->handle = fp->flex_handle; 11649 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 11650 handle = (uint16_t)(uintptr_t) 11651 ((struct rte_flow_item_flex *)ctx->object)->pattern; 11652 if (handle >= FLEX_MAX_PATTERNS_NUM) { 11653 printf("Bad pattern handle\n"); 11654 return -1; 11655 } 11656 src_spec = &flex_patterns[handle].spec; 11657 src_mask = &flex_patterns[handle].mask; 11658 spec = ctx->object; 11659 mask = spec + 2; /* spec, last, mask */ 11660 /* fill flow rule spec and mask parameters */ 11661 spec->length = src_spec->length; 11662 spec->pattern = src_spec->pattern; 11663 mask->length = src_mask->length; 11664 mask->pattern = src_mask->pattern; 11665 } else { 11666 printf("Bad arguments - unknown flex item offset\n"); 11667 return -1; 11668 } 11669 return ret; 11670 } 11671 11672 /** Parse Meter color name */ 11673 static int 11674 parse_meter_color(struct context *ctx, const struct token *token, 11675 const char *str, unsigned int len, void *buf, 11676 unsigned int size) 11677 { 11678 struct rte_flow_item_meter_color *meter_color; 11679 unsigned int i; 11680 11681 (void)token; 11682 (void)buf; 11683 (void)size; 11684 for (i = 0; meter_colors[i]; ++i) 11685 if (!strcmp_partial(meter_colors[i], str, len)) 11686 break; 11687 if (!meter_colors[i]) 11688 return -1; 11689 if (!ctx->object) 11690 return len; 11691 meter_color = ctx->object; 11692 meter_color->color = (enum rte_color)i; 11693 return len; 11694 } 11695 11696 /** Parse Insertion Table Type name */ 11697 static int 11698 parse_insertion_table_type(struct context *ctx, const struct token *token, 11699 const char *str, unsigned int len, void *buf, 11700 unsigned int size) 11701 { 11702 const struct arg *arg = pop_args(ctx); 11703 unsigned int i; 11704 char tmp[2]; 11705 int ret; 11706 11707 (void)size; 11708 /* Argument is expected. */ 11709 if (!arg) 11710 return -1; 11711 for (i = 0; table_insertion_types[i]; ++i) 11712 if (!strcmp_partial(table_insertion_types[i], str, len)) 11713 break; 11714 if (!table_insertion_types[i]) 11715 return -1; 11716 push_args(ctx, arg); 11717 snprintf(tmp, sizeof(tmp), "%u", i); 11718 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 11719 return ret > 0 ? (int)len : ret; 11720 } 11721 11722 /** Parse Hash Calculation Table Type name */ 11723 static int 11724 parse_hash_table_type(struct context *ctx, const struct token *token, 11725 const char *str, unsigned int len, void *buf, 11726 unsigned int size) 11727 { 11728 const struct arg *arg = pop_args(ctx); 11729 unsigned int i; 11730 char tmp[2]; 11731 int ret; 11732 11733 (void)size; 11734 /* Argument is expected. */ 11735 if (!arg) 11736 return -1; 11737 for (i = 0; table_hash_funcs[i]; ++i) 11738 if (!strcmp_partial(table_hash_funcs[i], str, len)) 11739 break; 11740 if (!table_hash_funcs[i]) 11741 return -1; 11742 push_args(ctx, arg); 11743 snprintf(tmp, sizeof(tmp), "%u", i); 11744 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 11745 return ret > 0 ? (int)len : ret; 11746 } 11747 11748 static int 11749 parse_name_to_index(struct context *ctx, const struct token *token, 11750 const char *str, unsigned int len, void *buf, 11751 unsigned int size, 11752 const char *const names[], size_t names_size, uint32_t *dst) 11753 { 11754 int ret; 11755 uint32_t i; 11756 11757 RTE_SET_USED(token); 11758 RTE_SET_USED(buf); 11759 RTE_SET_USED(size); 11760 if (!ctx->object) 11761 return len; 11762 for (i = 0; i < names_size; i++) { 11763 if (!names[i]) 11764 continue; 11765 ret = strcmp_partial(names[i], str, 11766 RTE_MIN(len, strlen(names[i]))); 11767 if (!ret) { 11768 *dst = i; 11769 return len; 11770 } 11771 } 11772 return -1; 11773 } 11774 11775 static const char *const quota_mode_names[] = { 11776 NULL, 11777 [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", 11778 [RTE_FLOW_QUOTA_MODE_L2] = "l2", 11779 [RTE_FLOW_QUOTA_MODE_L3] = "l3" 11780 }; 11781 11782 static const char *const quota_state_names[] = { 11783 [RTE_FLOW_QUOTA_STATE_PASS] = "pass", 11784 [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" 11785 }; 11786 11787 static const char *const quota_update_names[] = { 11788 [RTE_FLOW_UPDATE_QUOTA_SET] = "set", 11789 [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" 11790 }; 11791 11792 static const char *const query_update_mode_names[] = { 11793 [RTE_FLOW_QU_QUERY_FIRST] = "query_first", 11794 [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" 11795 }; 11796 11797 static int 11798 parse_quota_state_name(struct context *ctx, const struct token *token, 11799 const char *str, unsigned int len, void *buf, 11800 unsigned int size) 11801 { 11802 struct rte_flow_item_quota *quota = ctx->object; 11803 11804 return parse_name_to_index(ctx, token, str, len, buf, size, 11805 quota_state_names, 11806 RTE_DIM(quota_state_names), 11807 (uint32_t *)"a->state); 11808 } 11809 11810 static int 11811 parse_quota_mode_name(struct context *ctx, const struct token *token, 11812 const char *str, unsigned int len, void *buf, 11813 unsigned int size) 11814 { 11815 struct rte_flow_action_quota *quota = ctx->object; 11816 11817 return parse_name_to_index(ctx, token, str, len, buf, size, 11818 quota_mode_names, 11819 RTE_DIM(quota_mode_names), 11820 (uint32_t *)"a->mode); 11821 } 11822 11823 static int 11824 parse_quota_update_name(struct context *ctx, const struct token *token, 11825 const char *str, unsigned int len, void *buf, 11826 unsigned int size) 11827 { 11828 struct rte_flow_update_quota *update = ctx->object; 11829 11830 return parse_name_to_index(ctx, token, str, len, buf, size, 11831 quota_update_names, 11832 RTE_DIM(quota_update_names), 11833 (uint32_t *)&update->op); 11834 } 11835 11836 static int 11837 parse_qu_mode_name(struct context *ctx, const struct token *token, 11838 const char *str, unsigned int len, void *buf, 11839 unsigned int size) 11840 { 11841 struct buffer *out = ctx->object; 11842 11843 return parse_name_to_index(ctx, token, str, len, buf, size, 11844 query_update_mode_names, 11845 RTE_DIM(query_update_mode_names), 11846 (uint32_t *)&out->args.ia.qu_mode); 11847 } 11848 11849 /** No completion. */ 11850 static int 11851 comp_none(struct context *ctx, const struct token *token, 11852 unsigned int ent, char *buf, unsigned int size) 11853 { 11854 (void)ctx; 11855 (void)token; 11856 (void)ent; 11857 (void)buf; 11858 (void)size; 11859 return 0; 11860 } 11861 11862 /** Complete boolean values. */ 11863 static int 11864 comp_boolean(struct context *ctx, const struct token *token, 11865 unsigned int ent, char *buf, unsigned int size) 11866 { 11867 unsigned int i; 11868 11869 (void)ctx; 11870 (void)token; 11871 for (i = 0; boolean_name[i]; ++i) 11872 if (buf && i == ent) 11873 return strlcpy(buf, boolean_name[i], size); 11874 if (buf) 11875 return -1; 11876 return i; 11877 } 11878 11879 /** Complete action names. */ 11880 static int 11881 comp_action(struct context *ctx, const struct token *token, 11882 unsigned int ent, char *buf, unsigned int size) 11883 { 11884 unsigned int i; 11885 11886 (void)ctx; 11887 (void)token; 11888 for (i = 0; next_action[i]; ++i) 11889 if (buf && i == ent) 11890 return strlcpy(buf, token_list[next_action[i]].name, 11891 size); 11892 if (buf) 11893 return -1; 11894 return i; 11895 } 11896 11897 /** Complete available ports. */ 11898 static int 11899 comp_port(struct context *ctx, const struct token *token, 11900 unsigned int ent, char *buf, unsigned int size) 11901 { 11902 unsigned int i = 0; 11903 portid_t p; 11904 11905 (void)ctx; 11906 (void)token; 11907 RTE_ETH_FOREACH_DEV(p) { 11908 if (buf && i == ent) 11909 return snprintf(buf, size, "%u", p); 11910 ++i; 11911 } 11912 if (buf) 11913 return -1; 11914 return i; 11915 } 11916 11917 /** Complete available rule IDs. */ 11918 static int 11919 comp_rule_id(struct context *ctx, const struct token *token, 11920 unsigned int ent, char *buf, unsigned int size) 11921 { 11922 unsigned int i = 0; 11923 struct rte_port *port; 11924 struct port_flow *pf; 11925 11926 (void)token; 11927 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 11928 ctx->port == (portid_t)RTE_PORT_ALL) 11929 return -1; 11930 port = &ports[ctx->port]; 11931 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 11932 if (buf && i == ent) 11933 return snprintf(buf, size, "%"PRIu64, pf->id); 11934 ++i; 11935 } 11936 if (buf) 11937 return -1; 11938 return i; 11939 } 11940 11941 /** Complete type field for RSS action. */ 11942 static int 11943 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 11944 unsigned int ent, char *buf, unsigned int size) 11945 { 11946 unsigned int i; 11947 11948 (void)ctx; 11949 (void)token; 11950 for (i = 0; rss_type_table[i].str; ++i) 11951 ; 11952 if (!buf) 11953 return i + 1; 11954 if (ent < i) 11955 return strlcpy(buf, rss_type_table[ent].str, size); 11956 if (ent == i) 11957 return snprintf(buf, size, "end"); 11958 return -1; 11959 } 11960 11961 /** Complete queue field for RSS action. */ 11962 static int 11963 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 11964 unsigned int ent, char *buf, unsigned int size) 11965 { 11966 (void)ctx; 11967 (void)token; 11968 if (!buf) 11969 return nb_rxq + 1; 11970 if (ent < nb_rxq) 11971 return snprintf(buf, size, "%u", ent); 11972 if (ent == nb_rxq) 11973 return snprintf(buf, size, "end"); 11974 return -1; 11975 } 11976 11977 /** Complete index number for set raw_encap/raw_decap commands. */ 11978 static int 11979 comp_set_raw_index(struct context *ctx, const struct token *token, 11980 unsigned int ent, char *buf, unsigned int size) 11981 { 11982 uint16_t idx = 0; 11983 uint16_t nb = 0; 11984 11985 RTE_SET_USED(ctx); 11986 RTE_SET_USED(token); 11987 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 11988 if (buf && idx == ent) 11989 return snprintf(buf, size, "%u", idx); 11990 ++nb; 11991 } 11992 return nb; 11993 } 11994 11995 /** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ 11996 static int 11997 comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 11998 unsigned int ent, char *buf, unsigned int size) 11999 { 12000 uint16_t idx = 0; 12001 uint16_t nb = 0; 12002 12003 RTE_SET_USED(ctx); 12004 RTE_SET_USED(token); 12005 for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { 12006 if (buf && idx == ent) 12007 return snprintf(buf, size, "%u", idx); 12008 ++nb; 12009 } 12010 return nb; 12011 } 12012 12013 /** Complete index number for set raw_encap/raw_decap commands. */ 12014 static int 12015 comp_set_sample_index(struct context *ctx, const struct token *token, 12016 unsigned int ent, char *buf, unsigned int size) 12017 { 12018 uint16_t idx = 0; 12019 uint16_t nb = 0; 12020 12021 RTE_SET_USED(ctx); 12022 RTE_SET_USED(token); 12023 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 12024 if (buf && idx == ent) 12025 return snprintf(buf, size, "%u", idx); 12026 ++nb; 12027 } 12028 return nb; 12029 } 12030 12031 /** Complete operation for modify_field command. */ 12032 static int 12033 comp_set_modify_field_op(struct context *ctx, const struct token *token, 12034 unsigned int ent, char *buf, unsigned int size) 12035 { 12036 RTE_SET_USED(ctx); 12037 RTE_SET_USED(token); 12038 if (!buf) 12039 return RTE_DIM(modify_field_ops); 12040 if (ent < RTE_DIM(modify_field_ops) - 1) 12041 return strlcpy(buf, modify_field_ops[ent], size); 12042 return -1; 12043 } 12044 12045 /** Complete field id for modify_field command. */ 12046 static int 12047 comp_set_modify_field_id(struct context *ctx, const struct token *token, 12048 unsigned int ent, char *buf, unsigned int size) 12049 { 12050 const char *name; 12051 12052 RTE_SET_USED(token); 12053 if (!buf) 12054 return RTE_DIM(modify_field_ids); 12055 if (ent >= RTE_DIM(modify_field_ids) - 1) 12056 return -1; 12057 name = modify_field_ids[ent]; 12058 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 12059 (strcmp(name, "pointer") && strcmp(name, "value"))) 12060 return strlcpy(buf, name, size); 12061 return -1; 12062 } 12063 12064 /** Complete available pattern template IDs. */ 12065 static int 12066 comp_pattern_template_id(struct context *ctx, const struct token *token, 12067 unsigned int ent, char *buf, unsigned int size) 12068 { 12069 unsigned int i = 0; 12070 struct rte_port *port; 12071 struct port_template *pt; 12072 12073 (void)token; 12074 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12075 ctx->port == (portid_t)RTE_PORT_ALL) 12076 return -1; 12077 port = &ports[ctx->port]; 12078 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 12079 if (buf && i == ent) 12080 return snprintf(buf, size, "%u", pt->id); 12081 ++i; 12082 } 12083 if (buf) 12084 return -1; 12085 return i; 12086 } 12087 12088 /** Complete available actions template IDs. */ 12089 static int 12090 comp_actions_template_id(struct context *ctx, const struct token *token, 12091 unsigned int ent, char *buf, unsigned int size) 12092 { 12093 unsigned int i = 0; 12094 struct rte_port *port; 12095 struct port_template *pt; 12096 12097 (void)token; 12098 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12099 ctx->port == (portid_t)RTE_PORT_ALL) 12100 return -1; 12101 port = &ports[ctx->port]; 12102 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 12103 if (buf && i == ent) 12104 return snprintf(buf, size, "%u", pt->id); 12105 ++i; 12106 } 12107 if (buf) 12108 return -1; 12109 return i; 12110 } 12111 12112 /** Complete available table IDs. */ 12113 static int 12114 comp_table_id(struct context *ctx, const struct token *token, 12115 unsigned int ent, char *buf, unsigned int size) 12116 { 12117 unsigned int i = 0; 12118 struct rte_port *port; 12119 struct port_table *pt; 12120 12121 (void)token; 12122 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12123 ctx->port == (portid_t)RTE_PORT_ALL) 12124 return -1; 12125 port = &ports[ctx->port]; 12126 for (pt = port->table_list; pt != NULL; pt = pt->next) { 12127 if (buf && i == ent) 12128 return snprintf(buf, size, "%u", pt->id); 12129 ++i; 12130 } 12131 if (buf) 12132 return -1; 12133 return i; 12134 } 12135 12136 /** Complete available queue IDs. */ 12137 static int 12138 comp_queue_id(struct context *ctx, const struct token *token, 12139 unsigned int ent, char *buf, unsigned int size) 12140 { 12141 unsigned int i = 0; 12142 struct rte_port *port; 12143 12144 (void)token; 12145 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12146 ctx->port == (portid_t)RTE_PORT_ALL) 12147 return -1; 12148 port = &ports[ctx->port]; 12149 for (i = 0; i < port->queue_nb; i++) { 12150 if (buf && i == ent) 12151 return snprintf(buf, size, "%u", i); 12152 } 12153 if (buf) 12154 return -1; 12155 return i; 12156 } 12157 12158 static int 12159 comp_names_to_index(struct context *ctx, const struct token *token, 12160 unsigned int ent, char *buf, unsigned int size, 12161 const char *const names[], size_t names_size) 12162 { 12163 RTE_SET_USED(ctx); 12164 RTE_SET_USED(token); 12165 if (!buf) 12166 return names_size; 12167 if (names[ent] && ent < names_size) 12168 return rte_strscpy(buf, names[ent], size); 12169 return -1; 12170 12171 } 12172 12173 /** Complete available Meter colors. */ 12174 static int 12175 comp_meter_color(struct context *ctx, const struct token *token, 12176 unsigned int ent, char *buf, unsigned int size) 12177 { 12178 RTE_SET_USED(ctx); 12179 RTE_SET_USED(token); 12180 if (!buf) 12181 return RTE_DIM(meter_colors); 12182 if (ent < RTE_DIM(meter_colors) - 1) 12183 return strlcpy(buf, meter_colors[ent], size); 12184 return -1; 12185 } 12186 12187 /** Complete available Insertion Table types. */ 12188 static int 12189 comp_insertion_table_type(struct context *ctx, const struct token *token, 12190 unsigned int ent, char *buf, unsigned int size) 12191 { 12192 RTE_SET_USED(ctx); 12193 RTE_SET_USED(token); 12194 if (!buf) 12195 return RTE_DIM(table_insertion_types); 12196 if (ent < RTE_DIM(table_insertion_types) - 1) 12197 return rte_strscpy(buf, table_insertion_types[ent], size); 12198 return -1; 12199 } 12200 12201 /** Complete available Hash Calculation Table types. */ 12202 static int 12203 comp_hash_table_type(struct context *ctx, const struct token *token, 12204 unsigned int ent, char *buf, unsigned int size) 12205 { 12206 RTE_SET_USED(ctx); 12207 RTE_SET_USED(token); 12208 if (!buf) 12209 return RTE_DIM(table_hash_funcs); 12210 if (ent < RTE_DIM(table_hash_funcs) - 1) 12211 return rte_strscpy(buf, table_hash_funcs[ent], size); 12212 return -1; 12213 } 12214 12215 static int 12216 comp_quota_state_name(struct context *ctx, const struct token *token, 12217 unsigned int ent, char *buf, unsigned int size) 12218 { 12219 return comp_names_to_index(ctx, token, ent, buf, size, 12220 quota_state_names, 12221 RTE_DIM(quota_state_names)); 12222 } 12223 12224 static int 12225 comp_quota_mode_name(struct context *ctx, const struct token *token, 12226 unsigned int ent, char *buf, unsigned int size) 12227 { 12228 return comp_names_to_index(ctx, token, ent, buf, size, 12229 quota_mode_names, 12230 RTE_DIM(quota_mode_names)); 12231 } 12232 12233 static int 12234 comp_quota_update_name(struct context *ctx, const struct token *token, 12235 unsigned int ent, char *buf, unsigned int size) 12236 { 12237 return comp_names_to_index(ctx, token, ent, buf, size, 12238 quota_update_names, 12239 RTE_DIM(quota_update_names)); 12240 } 12241 12242 static int 12243 comp_qu_mode_name(struct context *ctx, const struct token *token, 12244 unsigned int ent, char *buf, unsigned int size) 12245 { 12246 return comp_names_to_index(ctx, token, ent, buf, size, 12247 query_update_mode_names, 12248 RTE_DIM(query_update_mode_names)); 12249 } 12250 12251 /** Internal context. */ 12252 static struct context cmd_flow_context; 12253 12254 /** Global parser instance (cmdline API). */ 12255 cmdline_parse_inst_t cmd_flow; 12256 cmdline_parse_inst_t cmd_set_raw; 12257 12258 /** Initialize context. */ 12259 static void 12260 cmd_flow_context_init(struct context *ctx) 12261 { 12262 /* A full memset() is not necessary. */ 12263 ctx->curr = ZERO; 12264 ctx->prev = ZERO; 12265 ctx->next_num = 0; 12266 ctx->args_num = 0; 12267 ctx->eol = 0; 12268 ctx->last = 0; 12269 ctx->port = 0; 12270 ctx->objdata = 0; 12271 ctx->object = NULL; 12272 ctx->objmask = NULL; 12273 } 12274 12275 /** Parse a token (cmdline API). */ 12276 static int 12277 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 12278 unsigned int size) 12279 { 12280 struct context *ctx = &cmd_flow_context; 12281 const struct token *token; 12282 const enum index *list; 12283 int len; 12284 int i; 12285 12286 (void)hdr; 12287 token = &token_list[ctx->curr]; 12288 /* Check argument length. */ 12289 ctx->eol = 0; 12290 ctx->last = 1; 12291 for (len = 0; src[len]; ++len) 12292 if (src[len] == '#' || isspace(src[len])) 12293 break; 12294 if (!len) 12295 return -1; 12296 /* Last argument and EOL detection. */ 12297 for (i = len; src[i]; ++i) 12298 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 12299 break; 12300 else if (!isspace(src[i])) { 12301 ctx->last = 0; 12302 break; 12303 } 12304 for (; src[i]; ++i) 12305 if (src[i] == '\r' || src[i] == '\n') { 12306 ctx->eol = 1; 12307 break; 12308 } 12309 /* Initialize context if necessary. */ 12310 if (!ctx->next_num) { 12311 if (!token->next) 12312 return 0; 12313 ctx->next[ctx->next_num++] = token->next[0]; 12314 } 12315 /* Process argument through candidates. */ 12316 ctx->prev = ctx->curr; 12317 list = ctx->next[ctx->next_num - 1]; 12318 for (i = 0; list[i]; ++i) { 12319 const struct token *next = &token_list[list[i]]; 12320 int tmp; 12321 12322 ctx->curr = list[i]; 12323 if (next->call) 12324 tmp = next->call(ctx, next, src, len, result, size); 12325 else 12326 tmp = parse_default(ctx, next, src, len, result, size); 12327 if (tmp == -1 || tmp != len) 12328 continue; 12329 token = next; 12330 break; 12331 } 12332 if (!list[i]) 12333 return -1; 12334 --ctx->next_num; 12335 /* Push subsequent tokens if any. */ 12336 if (token->next) 12337 for (i = 0; token->next[i]; ++i) { 12338 if (ctx->next_num == RTE_DIM(ctx->next)) 12339 return -1; 12340 ctx->next[ctx->next_num++] = token->next[i]; 12341 } 12342 /* Push arguments if any. */ 12343 if (token->args) 12344 for (i = 0; token->args[i]; ++i) { 12345 if (ctx->args_num == RTE_DIM(ctx->args)) 12346 return -1; 12347 ctx->args[ctx->args_num++] = token->args[i]; 12348 } 12349 return len; 12350 } 12351 12352 int 12353 flow_parse(const char *src, void *result, unsigned int size, 12354 struct rte_flow_attr **attr, 12355 struct rte_flow_item **pattern, struct rte_flow_action **actions) 12356 { 12357 int ret; 12358 struct context saved_flow_ctx = cmd_flow_context; 12359 12360 cmd_flow_context_init(&cmd_flow_context); 12361 do { 12362 ret = cmd_flow_parse(NULL, src, result, size); 12363 if (ret > 0) { 12364 src += ret; 12365 while (isspace(*src)) 12366 src++; 12367 } 12368 } while (ret > 0 && strlen(src)); 12369 cmd_flow_context = saved_flow_ctx; 12370 *attr = &((struct buffer *)result)->args.vc.attr; 12371 *pattern = ((struct buffer *)result)->args.vc.pattern; 12372 *actions = ((struct buffer *)result)->args.vc.actions; 12373 return (ret >= 0 && !strlen(src)) ? 0 : -1; 12374 } 12375 12376 /** Return number of completion entries (cmdline API). */ 12377 static int 12378 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 12379 { 12380 struct context *ctx = &cmd_flow_context; 12381 const struct token *token = &token_list[ctx->curr]; 12382 const enum index *list; 12383 int i; 12384 12385 (void)hdr; 12386 /* Count number of tokens in current list. */ 12387 if (ctx->next_num) 12388 list = ctx->next[ctx->next_num - 1]; 12389 else 12390 list = token->next[0]; 12391 for (i = 0; list[i]; ++i) 12392 ; 12393 if (!i) 12394 return 0; 12395 /* 12396 * If there is a single token, use its completion callback, otherwise 12397 * return the number of entries. 12398 */ 12399 token = &token_list[list[0]]; 12400 if (i == 1 && token->comp) { 12401 /* Save index for cmd_flow_get_help(). */ 12402 ctx->prev = list[0]; 12403 return token->comp(ctx, token, 0, NULL, 0); 12404 } 12405 return i; 12406 } 12407 12408 /** Return a completion entry (cmdline API). */ 12409 static int 12410 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 12411 char *dst, unsigned int size) 12412 { 12413 struct context *ctx = &cmd_flow_context; 12414 const struct token *token = &token_list[ctx->curr]; 12415 const enum index *list; 12416 int i; 12417 12418 (void)hdr; 12419 /* Count number of tokens in current list. */ 12420 if (ctx->next_num) 12421 list = ctx->next[ctx->next_num - 1]; 12422 else 12423 list = token->next[0]; 12424 for (i = 0; list[i]; ++i) 12425 ; 12426 if (!i) 12427 return -1; 12428 /* If there is a single token, use its completion callback. */ 12429 token = &token_list[list[0]]; 12430 if (i == 1 && token->comp) { 12431 /* Save index for cmd_flow_get_help(). */ 12432 ctx->prev = list[0]; 12433 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 12434 } 12435 /* Otherwise make sure the index is valid and use defaults. */ 12436 if (index >= i) 12437 return -1; 12438 token = &token_list[list[index]]; 12439 strlcpy(dst, token->name, size); 12440 /* Save index for cmd_flow_get_help(). */ 12441 ctx->prev = list[index]; 12442 return 0; 12443 } 12444 12445 /** Populate help strings for current token (cmdline API). */ 12446 static int 12447 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 12448 { 12449 struct context *ctx = &cmd_flow_context; 12450 const struct token *token = &token_list[ctx->prev]; 12451 12452 (void)hdr; 12453 if (!size) 12454 return -1; 12455 /* Set token type and update global help with details. */ 12456 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 12457 if (token->help) 12458 cmd_flow.help_str = token->help; 12459 else 12460 cmd_flow.help_str = token->name; 12461 return 0; 12462 } 12463 12464 /** Token definition template (cmdline API). */ 12465 static struct cmdline_token_hdr cmd_flow_token_hdr = { 12466 .ops = &(struct cmdline_token_ops){ 12467 .parse = cmd_flow_parse, 12468 .complete_get_nb = cmd_flow_complete_get_nb, 12469 .complete_get_elt = cmd_flow_complete_get_elt, 12470 .get_help = cmd_flow_get_help, 12471 }, 12472 .offset = 0, 12473 }; 12474 12475 /** Populate the next dynamic token. */ 12476 static void 12477 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 12478 cmdline_parse_token_hdr_t **hdr_inst) 12479 { 12480 struct context *ctx = &cmd_flow_context; 12481 12482 /* Always reinitialize context before requesting the first token. */ 12483 if (!(hdr_inst - cmd_flow.tokens)) 12484 cmd_flow_context_init(ctx); 12485 /* Return NULL when no more tokens are expected. */ 12486 if (!ctx->next_num && ctx->curr) { 12487 *hdr = NULL; 12488 return; 12489 } 12490 /* Determine if command should end here. */ 12491 if (ctx->eol && ctx->last && ctx->next_num) { 12492 const enum index *list = ctx->next[ctx->next_num - 1]; 12493 int i; 12494 12495 for (i = 0; list[i]; ++i) { 12496 if (list[i] != END) 12497 continue; 12498 *hdr = NULL; 12499 return; 12500 } 12501 } 12502 *hdr = &cmd_flow_token_hdr; 12503 } 12504 12505 static SLIST_HEAD(, indlst_conf) indlst_conf_head = 12506 SLIST_HEAD_INITIALIZER(); 12507 12508 static void 12509 indirect_action_flow_conf_create(const struct buffer *in) 12510 { 12511 int len, ret; 12512 uint32_t i; 12513 struct indlst_conf *indlst_conf = NULL; 12514 size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); 12515 struct rte_flow_action *src = in->args.vc.actions; 12516 12517 if (!in->args.vc.actions_n) 12518 goto end; 12519 len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); 12520 if (len <= 0) 12521 goto end; 12522 len = RTE_ALIGN(len, 16); 12523 12524 indlst_conf = calloc(1, base + len + 12525 in->args.vc.actions_n * sizeof(uintptr_t)); 12526 if (!indlst_conf) 12527 goto end; 12528 indlst_conf->id = in->args.vc.attr.group; 12529 indlst_conf->conf_num = in->args.vc.actions_n - 1; 12530 indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); 12531 ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, 12532 len, src, NULL); 12533 if (ret <= 0) { 12534 free(indlst_conf); 12535 indlst_conf = NULL; 12536 goto end; 12537 } 12538 indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); 12539 for (i = 0; i < indlst_conf->conf_num; i++) 12540 indlst_conf->conf[i] = indlst_conf->actions[i].conf; 12541 SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); 12542 end: 12543 if (indlst_conf) 12544 printf("created indirect action list configuration %u\n", 12545 in->args.vc.attr.group); 12546 else 12547 printf("cannot create indirect action list configuration %u\n", 12548 in->args.vc.attr.group); 12549 } 12550 12551 static const struct indlst_conf * 12552 indirect_action_list_conf_get(uint32_t conf_id) 12553 { 12554 const struct indlst_conf *conf; 12555 12556 SLIST_FOREACH(conf, &indlst_conf_head, next) { 12557 if (conf->id == conf_id) 12558 return conf; 12559 } 12560 return NULL; 12561 } 12562 12563 /** Dispatch parsed buffer to function calls. */ 12564 static void 12565 cmd_flow_parsed(const struct buffer *in) 12566 { 12567 switch (in->command) { 12568 case INFO: 12569 port_flow_get_info(in->port); 12570 break; 12571 case CONFIGURE: 12572 port_flow_configure(in->port, 12573 &in->args.configure.port_attr, 12574 in->args.configure.nb_queue, 12575 &in->args.configure.queue_attr); 12576 break; 12577 case PATTERN_TEMPLATE_CREATE: 12578 port_flow_pattern_template_create(in->port, 12579 in->args.vc.pat_templ_id, 12580 &((const struct rte_flow_pattern_template_attr) { 12581 .relaxed_matching = in->args.vc.attr.reserved, 12582 .ingress = in->args.vc.attr.ingress, 12583 .egress = in->args.vc.attr.egress, 12584 .transfer = in->args.vc.attr.transfer, 12585 }), 12586 in->args.vc.pattern); 12587 break; 12588 case PATTERN_TEMPLATE_DESTROY: 12589 port_flow_pattern_template_destroy(in->port, 12590 in->args.templ_destroy.template_id_n, 12591 in->args.templ_destroy.template_id); 12592 break; 12593 case ACTIONS_TEMPLATE_CREATE: 12594 port_flow_actions_template_create(in->port, 12595 in->args.vc.act_templ_id, 12596 &((const struct rte_flow_actions_template_attr) { 12597 .ingress = in->args.vc.attr.ingress, 12598 .egress = in->args.vc.attr.egress, 12599 .transfer = in->args.vc.attr.transfer, 12600 }), 12601 in->args.vc.actions, 12602 in->args.vc.masks); 12603 break; 12604 case ACTIONS_TEMPLATE_DESTROY: 12605 port_flow_actions_template_destroy(in->port, 12606 in->args.templ_destroy.template_id_n, 12607 in->args.templ_destroy.template_id); 12608 break; 12609 case TABLE_CREATE: 12610 port_flow_template_table_create(in->port, in->args.table.id, 12611 &in->args.table.attr, in->args.table.pat_templ_id_n, 12612 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 12613 in->args.table.act_templ_id); 12614 break; 12615 case TABLE_DESTROY: 12616 port_flow_template_table_destroy(in->port, 12617 in->args.table_destroy.table_id_n, 12618 in->args.table_destroy.table_id); 12619 break; 12620 case GROUP_SET_MISS_ACTIONS: 12621 port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, 12622 in->args.vc.actions); 12623 break; 12624 case QUEUE_CREATE: 12625 port_queue_flow_create(in->port, in->queue, in->postpone, 12626 in->args.vc.table_id, in->args.vc.rule_id, 12627 in->args.vc.pat_templ_id, in->args.vc.act_templ_id, 12628 in->args.vc.pattern, in->args.vc.actions); 12629 break; 12630 case QUEUE_DESTROY: 12631 port_queue_flow_destroy(in->port, in->queue, in->postpone, 12632 in->args.destroy.rule_n, 12633 in->args.destroy.rule); 12634 break; 12635 case QUEUE_UPDATE: 12636 port_queue_flow_update(in->port, in->queue, in->postpone, 12637 in->args.vc.rule_id, in->args.vc.act_templ_id, 12638 in->args.vc.actions); 12639 break; 12640 case PUSH: 12641 port_queue_flow_push(in->port, in->queue); 12642 break; 12643 case PULL: 12644 port_queue_flow_pull(in->port, in->queue); 12645 break; 12646 case HASH: 12647 port_flow_hash_calc(in->port, in->args.vc.table_id, 12648 in->args.vc.pat_templ_id, 12649 in->args.vc.pattern); 12650 break; 12651 case QUEUE_AGED: 12652 port_queue_flow_aged(in->port, in->queue, 12653 in->args.aged.destroy); 12654 break; 12655 case QUEUE_INDIRECT_ACTION_CREATE: 12656 case QUEUE_INDIRECT_ACTION_LIST_CREATE: 12657 port_queue_action_handle_create( 12658 in->port, in->queue, in->postpone, 12659 in->args.vc.attr.group, 12660 &((const struct rte_flow_indir_action_conf) { 12661 .ingress = in->args.vc.attr.ingress, 12662 .egress = in->args.vc.attr.egress, 12663 .transfer = in->args.vc.attr.transfer, 12664 }), 12665 in->args.vc.actions); 12666 break; 12667 case QUEUE_INDIRECT_ACTION_DESTROY: 12668 port_queue_action_handle_destroy(in->port, 12669 in->queue, in->postpone, 12670 in->args.ia_destroy.action_id_n, 12671 in->args.ia_destroy.action_id); 12672 break; 12673 case QUEUE_INDIRECT_ACTION_UPDATE: 12674 port_queue_action_handle_update(in->port, 12675 in->queue, in->postpone, 12676 in->args.vc.attr.group, 12677 in->args.vc.actions); 12678 break; 12679 case QUEUE_INDIRECT_ACTION_QUERY: 12680 port_queue_action_handle_query(in->port, 12681 in->queue, in->postpone, 12682 in->args.ia.action_id); 12683 break; 12684 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 12685 port_queue_action_handle_query_update(in->port, in->queue, 12686 in->postpone, 12687 in->args.ia.action_id, 12688 in->args.ia.qu_mode, 12689 in->args.vc.actions); 12690 break; 12691 case INDIRECT_ACTION_CREATE: 12692 case INDIRECT_ACTION_LIST_CREATE: 12693 port_action_handle_create( 12694 in->port, in->args.vc.attr.group, 12695 in->command == INDIRECT_ACTION_LIST_CREATE, 12696 &((const struct rte_flow_indir_action_conf) { 12697 .ingress = in->args.vc.attr.ingress, 12698 .egress = in->args.vc.attr.egress, 12699 .transfer = in->args.vc.attr.transfer, 12700 }), 12701 in->args.vc.actions); 12702 break; 12703 case INDIRECT_ACTION_FLOW_CONF_CREATE: 12704 indirect_action_flow_conf_create(in); 12705 break; 12706 case INDIRECT_ACTION_DESTROY: 12707 port_action_handle_destroy(in->port, 12708 in->args.ia_destroy.action_id_n, 12709 in->args.ia_destroy.action_id); 12710 break; 12711 case INDIRECT_ACTION_UPDATE: 12712 port_action_handle_update(in->port, in->args.vc.attr.group, 12713 in->args.vc.actions); 12714 break; 12715 case INDIRECT_ACTION_QUERY: 12716 port_action_handle_query(in->port, in->args.ia.action_id); 12717 break; 12718 case INDIRECT_ACTION_QUERY_UPDATE: 12719 port_action_handle_query_update(in->port, 12720 in->args.ia.action_id, 12721 in->args.ia.qu_mode, 12722 in->args.vc.actions); 12723 break; 12724 case VALIDATE: 12725 port_flow_validate(in->port, &in->args.vc.attr, 12726 in->args.vc.pattern, in->args.vc.actions, 12727 &in->args.vc.tunnel_ops); 12728 break; 12729 case CREATE: 12730 port_flow_create(in->port, &in->args.vc.attr, 12731 in->args.vc.pattern, in->args.vc.actions, 12732 &in->args.vc.tunnel_ops, in->args.vc.user_id); 12733 break; 12734 case DESTROY: 12735 port_flow_destroy(in->port, in->args.destroy.rule_n, 12736 in->args.destroy.rule, 12737 in->args.destroy.is_user_id); 12738 break; 12739 case FLUSH: 12740 port_flow_flush(in->port); 12741 break; 12742 case DUMP_ONE: 12743 case DUMP_ALL: 12744 port_flow_dump(in->port, in->args.dump.mode, 12745 in->args.dump.rule, in->args.dump.file, 12746 in->args.dump.is_user_id); 12747 break; 12748 case QUERY: 12749 port_flow_query(in->port, in->args.query.rule, 12750 &in->args.query.action, 12751 in->args.query.is_user_id); 12752 break; 12753 case LIST: 12754 port_flow_list(in->port, in->args.list.group_n, 12755 in->args.list.group); 12756 break; 12757 case ISOLATE: 12758 port_flow_isolate(in->port, in->args.isolate.set); 12759 break; 12760 case AGED: 12761 port_flow_aged(in->port, in->args.aged.destroy); 12762 break; 12763 case TUNNEL_CREATE: 12764 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 12765 break; 12766 case TUNNEL_DESTROY: 12767 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 12768 break; 12769 case TUNNEL_LIST: 12770 port_flow_tunnel_list(in->port); 12771 break; 12772 case ACTION_POL_G: 12773 port_meter_policy_add(in->port, in->args.policy.policy_id, 12774 in->args.vc.actions); 12775 break; 12776 case FLEX_ITEM_CREATE: 12777 flex_item_create(in->port, in->args.flex.token, 12778 in->args.flex.filename); 12779 break; 12780 case FLEX_ITEM_DESTROY: 12781 flex_item_destroy(in->port, in->args.flex.token); 12782 break; 12783 default: 12784 break; 12785 } 12786 fflush(stdout); 12787 } 12788 12789 /** Token generator and output processing callback (cmdline API). */ 12790 static void 12791 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 12792 { 12793 if (cl == NULL) 12794 cmd_flow_tok(arg0, arg2); 12795 else 12796 cmd_flow_parsed(arg0); 12797 } 12798 12799 /** Global parser instance (cmdline API). */ 12800 cmdline_parse_inst_t cmd_flow = { 12801 .f = cmd_flow_cb, 12802 .data = NULL, /**< Unused. */ 12803 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 12804 .tokens = { 12805 NULL, 12806 }, /**< Tokens are returned by cmd_flow_tok(). */ 12807 }; 12808 12809 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 12810 12811 static void 12812 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 12813 { 12814 struct rte_ipv4_hdr *ipv4; 12815 struct rte_ether_hdr *eth; 12816 struct rte_ipv6_hdr *ipv6; 12817 struct rte_vxlan_hdr *vxlan; 12818 struct rte_vxlan_gpe_hdr *gpe; 12819 struct rte_flow_item_nvgre *nvgre; 12820 uint32_t ipv6_vtc_flow; 12821 12822 switch (item->type) { 12823 case RTE_FLOW_ITEM_TYPE_ETH: 12824 eth = (struct rte_ether_hdr *)buf; 12825 if (next_proto) 12826 eth->ether_type = rte_cpu_to_be_16(next_proto); 12827 break; 12828 case RTE_FLOW_ITEM_TYPE_IPV4: 12829 ipv4 = (struct rte_ipv4_hdr *)buf; 12830 if (!ipv4->version_ihl) 12831 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 12832 if (next_proto && ipv4->next_proto_id == 0) 12833 ipv4->next_proto_id = (uint8_t)next_proto; 12834 break; 12835 case RTE_FLOW_ITEM_TYPE_IPV6: 12836 ipv6 = (struct rte_ipv6_hdr *)buf; 12837 if (next_proto && ipv6->proto == 0) 12838 ipv6->proto = (uint8_t)next_proto; 12839 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 12840 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 12841 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 12842 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 12843 break; 12844 case RTE_FLOW_ITEM_TYPE_VXLAN: 12845 vxlan = (struct rte_vxlan_hdr *)buf; 12846 vxlan->vx_flags = 0x08; 12847 break; 12848 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 12849 gpe = (struct rte_vxlan_gpe_hdr *)buf; 12850 gpe->vx_flags = 0x0C; 12851 break; 12852 case RTE_FLOW_ITEM_TYPE_NVGRE: 12853 nvgre = (struct rte_flow_item_nvgre *)buf; 12854 nvgre->protocol = rte_cpu_to_be_16(0x6558); 12855 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 12856 break; 12857 default: 12858 break; 12859 } 12860 } 12861 12862 /** Helper of get item's default mask. */ 12863 static const void * 12864 flow_item_default_mask(const struct rte_flow_item *item) 12865 { 12866 const void *mask = NULL; 12867 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 12868 static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { 12869 .hdr = { 12870 .next_hdr = 0xff, 12871 .type = 0xff, 12872 .segments_left = 0xff, 12873 }, 12874 }; 12875 12876 switch (item->type) { 12877 case RTE_FLOW_ITEM_TYPE_ANY: 12878 mask = &rte_flow_item_any_mask; 12879 break; 12880 case RTE_FLOW_ITEM_TYPE_PORT_ID: 12881 mask = &rte_flow_item_port_id_mask; 12882 break; 12883 case RTE_FLOW_ITEM_TYPE_RAW: 12884 mask = &rte_flow_item_raw_mask; 12885 break; 12886 case RTE_FLOW_ITEM_TYPE_ETH: 12887 mask = &rte_flow_item_eth_mask; 12888 break; 12889 case RTE_FLOW_ITEM_TYPE_VLAN: 12890 mask = &rte_flow_item_vlan_mask; 12891 break; 12892 case RTE_FLOW_ITEM_TYPE_IPV4: 12893 mask = &rte_flow_item_ipv4_mask; 12894 break; 12895 case RTE_FLOW_ITEM_TYPE_IPV6: 12896 mask = &rte_flow_item_ipv6_mask; 12897 break; 12898 case RTE_FLOW_ITEM_TYPE_ICMP: 12899 mask = &rte_flow_item_icmp_mask; 12900 break; 12901 case RTE_FLOW_ITEM_TYPE_UDP: 12902 mask = &rte_flow_item_udp_mask; 12903 break; 12904 case RTE_FLOW_ITEM_TYPE_TCP: 12905 mask = &rte_flow_item_tcp_mask; 12906 break; 12907 case RTE_FLOW_ITEM_TYPE_SCTP: 12908 mask = &rte_flow_item_sctp_mask; 12909 break; 12910 case RTE_FLOW_ITEM_TYPE_VXLAN: 12911 mask = &rte_flow_item_vxlan_mask; 12912 break; 12913 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 12914 mask = &rte_flow_item_vxlan_gpe_mask; 12915 break; 12916 case RTE_FLOW_ITEM_TYPE_E_TAG: 12917 mask = &rte_flow_item_e_tag_mask; 12918 break; 12919 case RTE_FLOW_ITEM_TYPE_NVGRE: 12920 mask = &rte_flow_item_nvgre_mask; 12921 break; 12922 case RTE_FLOW_ITEM_TYPE_MPLS: 12923 mask = &rte_flow_item_mpls_mask; 12924 break; 12925 case RTE_FLOW_ITEM_TYPE_GRE: 12926 mask = &rte_flow_item_gre_mask; 12927 break; 12928 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 12929 mask = &gre_key_default_mask; 12930 break; 12931 case RTE_FLOW_ITEM_TYPE_META: 12932 mask = &rte_flow_item_meta_mask; 12933 break; 12934 case RTE_FLOW_ITEM_TYPE_RANDOM: 12935 mask = &rte_flow_item_random_mask; 12936 break; 12937 case RTE_FLOW_ITEM_TYPE_FUZZY: 12938 mask = &rte_flow_item_fuzzy_mask; 12939 break; 12940 case RTE_FLOW_ITEM_TYPE_GTP: 12941 mask = &rte_flow_item_gtp_mask; 12942 break; 12943 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 12944 mask = &rte_flow_item_gtp_psc_mask; 12945 break; 12946 case RTE_FLOW_ITEM_TYPE_GENEVE: 12947 mask = &rte_flow_item_geneve_mask; 12948 break; 12949 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 12950 mask = &rte_flow_item_geneve_opt_mask; 12951 break; 12952 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 12953 mask = &rte_flow_item_pppoe_proto_id_mask; 12954 break; 12955 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 12956 mask = &rte_flow_item_l2tpv3oip_mask; 12957 break; 12958 case RTE_FLOW_ITEM_TYPE_ESP: 12959 mask = &rte_flow_item_esp_mask; 12960 break; 12961 case RTE_FLOW_ITEM_TYPE_AH: 12962 mask = &rte_flow_item_ah_mask; 12963 break; 12964 case RTE_FLOW_ITEM_TYPE_PFCP: 12965 mask = &rte_flow_item_pfcp_mask; 12966 break; 12967 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 12968 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 12969 mask = &rte_flow_item_ethdev_mask; 12970 break; 12971 case RTE_FLOW_ITEM_TYPE_L2TPV2: 12972 mask = &rte_flow_item_l2tpv2_mask; 12973 break; 12974 case RTE_FLOW_ITEM_TYPE_PPP: 12975 mask = &rte_flow_item_ppp_mask; 12976 break; 12977 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 12978 mask = &rte_flow_item_meter_color_mask; 12979 break; 12980 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 12981 mask = &ipv6_routing_ext_default_mask; 12982 break; 12983 case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: 12984 mask = &rte_flow_item_aggr_affinity_mask; 12985 break; 12986 case RTE_FLOW_ITEM_TYPE_TX_QUEUE: 12987 mask = &rte_flow_item_tx_queue_mask; 12988 break; 12989 case RTE_FLOW_ITEM_TYPE_IB_BTH: 12990 mask = &rte_flow_item_ib_bth_mask; 12991 break; 12992 case RTE_FLOW_ITEM_TYPE_PTYPE: 12993 mask = &rte_flow_item_ptype_mask; 12994 break; 12995 default: 12996 break; 12997 } 12998 return mask; 12999 } 13000 13001 /** Dispatch parsed buffer to function calls. */ 13002 static void 13003 cmd_set_ipv6_ext_parsed(const struct buffer *in) 13004 { 13005 uint32_t n = in->args.vc.pattern_n; 13006 int i = 0; 13007 struct rte_flow_item *item = NULL; 13008 size_t size = 0; 13009 uint8_t *data = NULL; 13010 uint8_t *type = NULL; 13011 size_t *total_size = NULL; 13012 uint16_t idx = in->port; /* We borrow port field as index */ 13013 struct rte_flow_item_ipv6_routing_ext *ext; 13014 const struct rte_flow_item_ipv6_ext *ipv6_ext; 13015 13016 RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || 13017 in->command == SET_IPV6_EXT_REMOVE); 13018 13019 if (in->command == SET_IPV6_EXT_REMOVE) { 13020 if (n != 1 || in->args.vc.pattern->type != 13021 RTE_FLOW_ITEM_TYPE_IPV6_EXT) { 13022 fprintf(stderr, "Error - Not supported item\n"); 13023 return; 13024 } 13025 type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; 13026 item = in->args.vc.pattern; 13027 ipv6_ext = item->spec; 13028 *type = ipv6_ext->next_hdr; 13029 return; 13030 } 13031 13032 total_size = &ipv6_ext_push_confs[idx].size; 13033 data = (uint8_t *)&ipv6_ext_push_confs[idx].data; 13034 type = (uint8_t *)&ipv6_ext_push_confs[idx].type; 13035 13036 *total_size = 0; 13037 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13038 for (i = n - 1 ; i >= 0; --i) { 13039 item = in->args.vc.pattern + i; 13040 switch (item->type) { 13041 case RTE_FLOW_ITEM_TYPE_IPV6_EXT: 13042 ipv6_ext = item->spec; 13043 *type = ipv6_ext->next_hdr; 13044 break; 13045 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13046 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13047 if (!ext->hdr.hdr_len) { 13048 size = sizeof(struct rte_ipv6_routing_ext) + 13049 (ext->hdr.segments_left << 4); 13050 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13051 /* Indicate no TLV once SRH. */ 13052 if (ext->hdr.type == 4) 13053 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13054 } else { 13055 size = sizeof(struct rte_ipv6_routing_ext) + 13056 (ext->hdr.hdr_len << 3); 13057 } 13058 *total_size += size; 13059 memcpy(data, ext, size); 13060 break; 13061 default: 13062 fprintf(stderr, "Error - Not supported item\n"); 13063 goto error; 13064 } 13065 } 13066 RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); 13067 return; 13068 error: 13069 *total_size = 0; 13070 memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); 13071 } 13072 13073 /** Dispatch parsed buffer to function calls. */ 13074 static void 13075 cmd_set_raw_parsed_sample(const struct buffer *in) 13076 { 13077 uint32_t n = in->args.vc.actions_n; 13078 uint32_t i = 0; 13079 struct rte_flow_action *action = NULL; 13080 struct rte_flow_action *data = NULL; 13081 const struct rte_flow_action_rss *rss = NULL; 13082 size_t size = 0; 13083 uint16_t idx = in->port; /* We borrow port field as index */ 13084 uint32_t max_size = sizeof(struct rte_flow_action) * 13085 ACTION_SAMPLE_ACTIONS_NUM; 13086 13087 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 13088 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 13089 memset(data, 0x00, max_size); 13090 for (; i <= n - 1; i++) { 13091 action = in->args.vc.actions + i; 13092 if (action->type == RTE_FLOW_ACTION_TYPE_END) 13093 break; 13094 switch (action->type) { 13095 case RTE_FLOW_ACTION_TYPE_MARK: 13096 size = sizeof(struct rte_flow_action_mark); 13097 rte_memcpy(&sample_mark[idx], 13098 (const void *)action->conf, size); 13099 action->conf = &sample_mark[idx]; 13100 break; 13101 case RTE_FLOW_ACTION_TYPE_COUNT: 13102 size = sizeof(struct rte_flow_action_count); 13103 rte_memcpy(&sample_count[idx], 13104 (const void *)action->conf, size); 13105 action->conf = &sample_count[idx]; 13106 break; 13107 case RTE_FLOW_ACTION_TYPE_QUEUE: 13108 size = sizeof(struct rte_flow_action_queue); 13109 rte_memcpy(&sample_queue[idx], 13110 (const void *)action->conf, size); 13111 action->conf = &sample_queue[idx]; 13112 break; 13113 case RTE_FLOW_ACTION_TYPE_RSS: 13114 size = sizeof(struct rte_flow_action_rss); 13115 rss = action->conf; 13116 rte_memcpy(&sample_rss_data[idx].conf, 13117 (const void *)rss, size); 13118 if (rss->key_len && rss->key) { 13119 sample_rss_data[idx].conf.key = 13120 sample_rss_data[idx].key; 13121 rte_memcpy((void *)((uintptr_t) 13122 sample_rss_data[idx].conf.key), 13123 (const void *)rss->key, 13124 sizeof(uint8_t) * rss->key_len); 13125 } 13126 if (rss->queue_num && rss->queue) { 13127 sample_rss_data[idx].conf.queue = 13128 sample_rss_data[idx].queue; 13129 rte_memcpy((void *)((uintptr_t) 13130 sample_rss_data[idx].conf.queue), 13131 (const void *)rss->queue, 13132 sizeof(uint16_t) * rss->queue_num); 13133 } 13134 action->conf = &sample_rss_data[idx].conf; 13135 break; 13136 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 13137 size = sizeof(struct rte_flow_action_raw_encap); 13138 rte_memcpy(&sample_encap[idx], 13139 (const void *)action->conf, size); 13140 action->conf = &sample_encap[idx]; 13141 break; 13142 case RTE_FLOW_ACTION_TYPE_PORT_ID: 13143 size = sizeof(struct rte_flow_action_port_id); 13144 rte_memcpy(&sample_port_id[idx], 13145 (const void *)action->conf, size); 13146 action->conf = &sample_port_id[idx]; 13147 break; 13148 case RTE_FLOW_ACTION_TYPE_PF: 13149 break; 13150 case RTE_FLOW_ACTION_TYPE_VF: 13151 size = sizeof(struct rte_flow_action_vf); 13152 rte_memcpy(&sample_vf[idx], 13153 (const void *)action->conf, size); 13154 action->conf = &sample_vf[idx]; 13155 break; 13156 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 13157 size = sizeof(struct rte_flow_action_vxlan_encap); 13158 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 13159 action->conf = &sample_vxlan_encap[idx].conf; 13160 break; 13161 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 13162 size = sizeof(struct rte_flow_action_nvgre_encap); 13163 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 13164 action->conf = &sample_nvgre_encap[idx]; 13165 break; 13166 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 13167 size = sizeof(struct rte_flow_action_ethdev); 13168 rte_memcpy(&sample_port_representor[idx], 13169 (const void *)action->conf, size); 13170 action->conf = &sample_port_representor[idx]; 13171 break; 13172 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 13173 size = sizeof(struct rte_flow_action_ethdev); 13174 rte_memcpy(&sample_represented_port[idx], 13175 (const void *)action->conf, size); 13176 action->conf = &sample_represented_port[idx]; 13177 break; 13178 default: 13179 fprintf(stderr, "Error - Not supported action\n"); 13180 return; 13181 } 13182 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 13183 data++; 13184 } 13185 } 13186 13187 /** Dispatch parsed buffer to function calls. */ 13188 static void 13189 cmd_set_raw_parsed(const struct buffer *in) 13190 { 13191 uint32_t n = in->args.vc.pattern_n; 13192 int i = 0; 13193 struct rte_flow_item *item = NULL; 13194 size_t size = 0; 13195 uint8_t *data = NULL; 13196 uint8_t *data_tail = NULL; 13197 size_t *total_size = NULL; 13198 uint16_t upper_layer = 0; 13199 uint16_t proto = 0; 13200 uint16_t idx = in->port; /* We borrow port field as index */ 13201 int gtp_psc = -1; /* GTP PSC option index. */ 13202 const void *src_spec; 13203 13204 if (in->command == SET_SAMPLE_ACTIONS) 13205 return cmd_set_raw_parsed_sample(in); 13206 else if (in->command == SET_IPV6_EXT_PUSH || 13207 in->command == SET_IPV6_EXT_REMOVE) 13208 return cmd_set_ipv6_ext_parsed(in); 13209 RTE_ASSERT(in->command == SET_RAW_ENCAP || 13210 in->command == SET_RAW_DECAP); 13211 if (in->command == SET_RAW_ENCAP) { 13212 total_size = &raw_encap_confs[idx].size; 13213 data = (uint8_t *)&raw_encap_confs[idx].data; 13214 } else { 13215 total_size = &raw_decap_confs[idx].size; 13216 data = (uint8_t *)&raw_decap_confs[idx].data; 13217 } 13218 *total_size = 0; 13219 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13220 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 13221 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 13222 for (i = n - 1 ; i >= 0; --i) { 13223 const struct rte_flow_item_gtp *gtp; 13224 const struct rte_flow_item_geneve_opt *opt; 13225 struct rte_flow_item_ipv6_routing_ext *ext; 13226 13227 item = in->args.vc.pattern + i; 13228 if (item->spec == NULL) 13229 item->spec = flow_item_default_mask(item); 13230 src_spec = item->spec; 13231 switch (item->type) { 13232 case RTE_FLOW_ITEM_TYPE_ETH: 13233 size = sizeof(struct rte_ether_hdr); 13234 break; 13235 case RTE_FLOW_ITEM_TYPE_VLAN: 13236 size = sizeof(struct rte_vlan_hdr); 13237 proto = RTE_ETHER_TYPE_VLAN; 13238 break; 13239 case RTE_FLOW_ITEM_TYPE_IPV4: 13240 size = sizeof(struct rte_ipv4_hdr); 13241 proto = RTE_ETHER_TYPE_IPV4; 13242 break; 13243 case RTE_FLOW_ITEM_TYPE_IPV6: 13244 size = sizeof(struct rte_ipv6_hdr); 13245 proto = RTE_ETHER_TYPE_IPV6; 13246 break; 13247 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13248 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13249 if (!ext->hdr.hdr_len) { 13250 size = sizeof(struct rte_ipv6_routing_ext) + 13251 (ext->hdr.segments_left << 4); 13252 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13253 /* SRv6 without TLV. */ 13254 if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) 13255 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13256 } else { 13257 size = sizeof(struct rte_ipv6_routing_ext) + 13258 (ext->hdr.hdr_len << 3); 13259 } 13260 proto = IPPROTO_ROUTING; 13261 break; 13262 case RTE_FLOW_ITEM_TYPE_UDP: 13263 size = sizeof(struct rte_udp_hdr); 13264 proto = 0x11; 13265 break; 13266 case RTE_FLOW_ITEM_TYPE_TCP: 13267 size = sizeof(struct rte_tcp_hdr); 13268 proto = 0x06; 13269 break; 13270 case RTE_FLOW_ITEM_TYPE_VXLAN: 13271 size = sizeof(struct rte_vxlan_hdr); 13272 break; 13273 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13274 size = sizeof(struct rte_vxlan_gpe_hdr); 13275 break; 13276 case RTE_FLOW_ITEM_TYPE_GRE: 13277 size = sizeof(struct rte_gre_hdr); 13278 proto = 0x2F; 13279 break; 13280 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13281 size = sizeof(rte_be32_t); 13282 proto = 0x0; 13283 break; 13284 case RTE_FLOW_ITEM_TYPE_MPLS: 13285 size = sizeof(struct rte_mpls_hdr); 13286 proto = 0x0; 13287 break; 13288 case RTE_FLOW_ITEM_TYPE_NVGRE: 13289 size = sizeof(struct rte_flow_item_nvgre); 13290 proto = 0x2F; 13291 break; 13292 case RTE_FLOW_ITEM_TYPE_GENEVE: 13293 size = sizeof(struct rte_geneve_hdr); 13294 break; 13295 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13296 opt = (const struct rte_flow_item_geneve_opt *) 13297 item->spec; 13298 size = offsetof(struct rte_flow_item_geneve_opt, 13299 option_len) + sizeof(uint8_t); 13300 if (opt->option_len && opt->data) { 13301 *total_size += opt->option_len * 13302 sizeof(uint32_t); 13303 rte_memcpy(data_tail - (*total_size), 13304 opt->data, 13305 opt->option_len * sizeof(uint32_t)); 13306 } 13307 break; 13308 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13309 size = sizeof(rte_be32_t); 13310 proto = 0x73; 13311 break; 13312 case RTE_FLOW_ITEM_TYPE_ESP: 13313 size = sizeof(struct rte_esp_hdr); 13314 proto = 0x32; 13315 break; 13316 case RTE_FLOW_ITEM_TYPE_AH: 13317 size = sizeof(struct rte_flow_item_ah); 13318 proto = 0x33; 13319 break; 13320 case RTE_FLOW_ITEM_TYPE_GTP: 13321 if (gtp_psc < 0) { 13322 size = sizeof(struct rte_gtp_hdr); 13323 break; 13324 } 13325 if (gtp_psc != i + 1) { 13326 fprintf(stderr, 13327 "Error - GTP PSC does not follow GTP\n"); 13328 goto error; 13329 } 13330 gtp = item->spec; 13331 if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { 13332 /* Only E flag should be set. */ 13333 fprintf(stderr, 13334 "Error - GTP unsupported flags\n"); 13335 goto error; 13336 } else { 13337 struct rte_gtp_hdr_ext_word ext_word = { 13338 .next_ext = 0x85 13339 }; 13340 13341 /* We have to add GTP header extra word. */ 13342 *total_size += sizeof(ext_word); 13343 rte_memcpy(data_tail - (*total_size), 13344 &ext_word, sizeof(ext_word)); 13345 } 13346 size = sizeof(struct rte_gtp_hdr); 13347 break; 13348 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13349 if (gtp_psc >= 0) { 13350 fprintf(stderr, 13351 "Error - Multiple GTP PSC items\n"); 13352 goto error; 13353 } else { 13354 const struct rte_flow_item_gtp_psc 13355 *opt = item->spec; 13356 struct rte_gtp_psc_generic_hdr *hdr; 13357 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 13358 sizeof(int32_t)); 13359 13360 *total_size += hdr_size; 13361 hdr = (typeof(hdr))(data_tail - (*total_size)); 13362 memset(hdr, 0, hdr_size); 13363 *hdr = opt->hdr; 13364 hdr->ext_hdr_len = 1; 13365 gtp_psc = i; 13366 size = 0; 13367 } 13368 break; 13369 case RTE_FLOW_ITEM_TYPE_PFCP: 13370 size = sizeof(struct rte_flow_item_pfcp); 13371 break; 13372 case RTE_FLOW_ITEM_TYPE_FLEX: 13373 if (item->spec != NULL) { 13374 size = ((const struct rte_flow_item_flex *)item->spec)->length; 13375 src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; 13376 } else { 13377 size = 0; 13378 src_spec = NULL; 13379 } 13380 break; 13381 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 13382 size = 0; 13383 if (item->spec) { 13384 const struct rte_flow_item_gre_opt 13385 *opt = item->spec; 13386 if (opt->checksum_rsvd.checksum) { 13387 *total_size += 13388 sizeof(opt->checksum_rsvd); 13389 rte_memcpy(data_tail - (*total_size), 13390 &opt->checksum_rsvd, 13391 sizeof(opt->checksum_rsvd)); 13392 } 13393 if (opt->key.key) { 13394 *total_size += sizeof(opt->key.key); 13395 rte_memcpy(data_tail - (*total_size), 13396 &opt->key.key, 13397 sizeof(opt->key.key)); 13398 } 13399 if (opt->sequence.sequence) { 13400 *total_size += sizeof(opt->sequence.sequence); 13401 rte_memcpy(data_tail - (*total_size), 13402 &opt->sequence.sequence, 13403 sizeof(opt->sequence.sequence)); 13404 } 13405 } 13406 proto = 0x2F; 13407 break; 13408 default: 13409 fprintf(stderr, "Error - Not supported item\n"); 13410 goto error; 13411 } 13412 if (size) { 13413 *total_size += size; 13414 rte_memcpy(data_tail - (*total_size), src_spec, size); 13415 /* update some fields which cannot be set by cmdline */ 13416 update_fields((data_tail - (*total_size)), item, 13417 upper_layer); 13418 upper_layer = proto; 13419 } 13420 } 13421 if (verbose_level & 0x1) 13422 printf("total data size is %zu\n", (*total_size)); 13423 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 13424 memmove(data, (data_tail - (*total_size)), *total_size); 13425 return; 13426 13427 error: 13428 *total_size = 0; 13429 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13430 } 13431 13432 /** Populate help strings for current token (cmdline API). */ 13433 static int 13434 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 13435 unsigned int size) 13436 { 13437 struct context *ctx = &cmd_flow_context; 13438 const struct token *token = &token_list[ctx->prev]; 13439 13440 (void)hdr; 13441 if (!size) 13442 return -1; 13443 /* Set token type and update global help with details. */ 13444 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 13445 if (token->help) 13446 cmd_set_raw.help_str = token->help; 13447 else 13448 cmd_set_raw.help_str = token->name; 13449 return 0; 13450 } 13451 13452 /** Token definition template (cmdline API). */ 13453 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 13454 .ops = &(struct cmdline_token_ops){ 13455 .parse = cmd_flow_parse, 13456 .complete_get_nb = cmd_flow_complete_get_nb, 13457 .complete_get_elt = cmd_flow_complete_get_elt, 13458 .get_help = cmd_set_raw_get_help, 13459 }, 13460 .offset = 0, 13461 }; 13462 13463 /** Populate the next dynamic token. */ 13464 static void 13465 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 13466 cmdline_parse_token_hdr_t **hdr_inst) 13467 { 13468 struct context *ctx = &cmd_flow_context; 13469 13470 /* Always reinitialize context before requesting the first token. */ 13471 if (!(hdr_inst - cmd_set_raw.tokens)) { 13472 cmd_flow_context_init(ctx); 13473 ctx->curr = START_SET; 13474 } 13475 /* Return NULL when no more tokens are expected. */ 13476 if (!ctx->next_num && (ctx->curr != START_SET)) { 13477 *hdr = NULL; 13478 return; 13479 } 13480 /* Determine if command should end here. */ 13481 if (ctx->eol && ctx->last && ctx->next_num) { 13482 const enum index *list = ctx->next[ctx->next_num - 1]; 13483 int i; 13484 13485 for (i = 0; list[i]; ++i) { 13486 if (list[i] != END) 13487 continue; 13488 *hdr = NULL; 13489 return; 13490 } 13491 } 13492 *hdr = &cmd_set_raw_token_hdr; 13493 } 13494 13495 /** Token generator and output processing callback (cmdline API). */ 13496 static void 13497 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 13498 { 13499 if (cl == NULL) 13500 cmd_set_raw_tok(arg0, arg2); 13501 else 13502 cmd_set_raw_parsed(arg0); 13503 } 13504 13505 /** Global parser instance (cmdline API). */ 13506 cmdline_parse_inst_t cmd_set_raw = { 13507 .f = cmd_set_raw_cb, 13508 .data = NULL, /**< Unused. */ 13509 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 13510 .tokens = { 13511 NULL, 13512 }, /**< Tokens are returned by cmd_flow_tok(). */ 13513 }; 13514 13515 /* *** display raw_encap/raw_decap buf */ 13516 struct cmd_show_set_raw_result { 13517 cmdline_fixed_string_t cmd_show; 13518 cmdline_fixed_string_t cmd_what; 13519 cmdline_fixed_string_t cmd_all; 13520 uint16_t cmd_index; 13521 }; 13522 13523 static void 13524 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 13525 { 13526 struct cmd_show_set_raw_result *res = parsed_result; 13527 uint16_t index = res->cmd_index; 13528 uint8_t all = 0; 13529 uint8_t *raw_data = NULL; 13530 size_t raw_size = 0; 13531 char title[16] = {0}; 13532 13533 RTE_SET_USED(cl); 13534 RTE_SET_USED(data); 13535 if (!strcmp(res->cmd_all, "all")) { 13536 all = 1; 13537 index = 0; 13538 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 13539 fprintf(stderr, "index should be 0-%u\n", 13540 RAW_ENCAP_CONFS_MAX_NUM - 1); 13541 return; 13542 } 13543 do { 13544 if (!strcmp(res->cmd_what, "raw_encap")) { 13545 raw_data = (uint8_t *)&raw_encap_confs[index].data; 13546 raw_size = raw_encap_confs[index].size; 13547 snprintf(title, 16, "\nindex: %u", index); 13548 rte_hexdump(stdout, title, raw_data, raw_size); 13549 } else { 13550 raw_data = (uint8_t *)&raw_decap_confs[index].data; 13551 raw_size = raw_decap_confs[index].size; 13552 snprintf(title, 16, "\nindex: %u", index); 13553 rte_hexdump(stdout, title, raw_data, raw_size); 13554 } 13555 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 13556 } 13557 13558 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 13559 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 13560 cmd_show, "show"); 13561 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 13562 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 13563 cmd_what, "raw_encap#raw_decap"); 13564 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 13565 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 13566 cmd_index, RTE_UINT16); 13567 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 13568 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 13569 cmd_all, "all"); 13570 cmdline_parse_inst_t cmd_show_set_raw = { 13571 .f = cmd_show_set_raw_parsed, 13572 .data = NULL, 13573 .help_str = "show <raw_encap|raw_decap> <index>", 13574 .tokens = { 13575 (void *)&cmd_show_set_raw_cmd_show, 13576 (void *)&cmd_show_set_raw_cmd_what, 13577 (void *)&cmd_show_set_raw_cmd_index, 13578 NULL, 13579 }, 13580 }; 13581 cmdline_parse_inst_t cmd_show_set_raw_all = { 13582 .f = cmd_show_set_raw_parsed, 13583 .data = NULL, 13584 .help_str = "show <raw_encap|raw_decap> all", 13585 .tokens = { 13586 (void *)&cmd_show_set_raw_cmd_show, 13587 (void *)&cmd_show_set_raw_cmd_what, 13588 (void *)&cmd_show_set_raw_cmd_all, 13589 NULL, 13590 }, 13591 }; 13592