1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2016 6WIND S.A. 3 * Copyright 2016 Mellanox Technologies, Ltd 4 */ 5 6 #include <stddef.h> 7 #include <stdint.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <inttypes.h> 11 #include <errno.h> 12 #include <ctype.h> 13 #include <string.h> 14 15 #include <rte_string_fns.h> 16 #include <rte_common.h> 17 #include <rte_ethdev.h> 18 #include <rte_byteorder.h> 19 #include <cmdline_parse.h> 20 #include <cmdline_parse_etheraddr.h> 21 #include <cmdline_parse_string.h> 22 #include <cmdline_parse_num.h> 23 #include <rte_flow.h> 24 #include <rte_hexdump.h> 25 #include <rte_vxlan.h> 26 #include <rte_gre.h> 27 #include <rte_mpls.h> 28 #include <rte_gtp.h> 29 #include <rte_geneve.h> 30 31 #include "testpmd.h" 32 33 /** Parser token indices. */ 34 enum index { 35 /* Special tokens. */ 36 ZERO = 0, 37 END, 38 START_SET, 39 END_SET, 40 41 /* Common tokens. */ 42 COMMON_INTEGER, 43 COMMON_UNSIGNED, 44 COMMON_PREFIX, 45 COMMON_BOOLEAN, 46 COMMON_STRING, 47 COMMON_HEX, 48 COMMON_FILE_PATH, 49 COMMON_MAC_ADDR, 50 COMMON_IPV4_ADDR, 51 COMMON_IPV6_ADDR, 52 COMMON_RULE_ID, 53 COMMON_PORT_ID, 54 COMMON_GROUP_ID, 55 COMMON_PRIORITY_LEVEL, 56 COMMON_INDIRECT_ACTION_ID, 57 COMMON_PROFILE_ID, 58 COMMON_POLICY_ID, 59 COMMON_FLEX_HANDLE, 60 COMMON_FLEX_TOKEN, 61 COMMON_PATTERN_TEMPLATE_ID, 62 COMMON_ACTIONS_TEMPLATE_ID, 63 COMMON_TABLE_ID, 64 COMMON_QUEUE_ID, 65 66 /* TOP-level command. */ 67 ADD, 68 69 /* Top-level command. */ 70 SET, 71 /* Sub-leve commands. */ 72 SET_RAW_ENCAP, 73 SET_RAW_DECAP, 74 SET_RAW_INDEX, 75 SET_SAMPLE_ACTIONS, 76 SET_SAMPLE_INDEX, 77 SET_IPV6_EXT_REMOVE, 78 SET_IPV6_EXT_PUSH, 79 SET_IPV6_EXT_INDEX, 80 81 /* Top-level command. */ 82 FLOW, 83 /* Sub-level commands. */ 84 INFO, 85 CONFIGURE, 86 PATTERN_TEMPLATE, 87 ACTIONS_TEMPLATE, 88 TABLE, 89 FLOW_GROUP, 90 INDIRECT_ACTION, 91 VALIDATE, 92 CREATE, 93 DESTROY, 94 UPDATE, 95 FLUSH, 96 DUMP, 97 QUERY, 98 LIST, 99 AGED, 100 ISOLATE, 101 TUNNEL, 102 FLEX, 103 QUEUE, 104 PUSH, 105 PULL, 106 HASH, 107 108 /* Flex arguments */ 109 FLEX_ITEM_INIT, 110 FLEX_ITEM_CREATE, 111 FLEX_ITEM_DESTROY, 112 113 /* Pattern template arguments. */ 114 PATTERN_TEMPLATE_CREATE, 115 PATTERN_TEMPLATE_DESTROY, 116 PATTERN_TEMPLATE_CREATE_ID, 117 PATTERN_TEMPLATE_DESTROY_ID, 118 PATTERN_TEMPLATE_RELAXED_MATCHING, 119 PATTERN_TEMPLATE_INGRESS, 120 PATTERN_TEMPLATE_EGRESS, 121 PATTERN_TEMPLATE_TRANSFER, 122 PATTERN_TEMPLATE_SPEC, 123 124 /* Actions template arguments. */ 125 ACTIONS_TEMPLATE_CREATE, 126 ACTIONS_TEMPLATE_DESTROY, 127 ACTIONS_TEMPLATE_CREATE_ID, 128 ACTIONS_TEMPLATE_DESTROY_ID, 129 ACTIONS_TEMPLATE_INGRESS, 130 ACTIONS_TEMPLATE_EGRESS, 131 ACTIONS_TEMPLATE_TRANSFER, 132 ACTIONS_TEMPLATE_SPEC, 133 ACTIONS_TEMPLATE_MASK, 134 135 /* Queue arguments. */ 136 QUEUE_CREATE, 137 QUEUE_DESTROY, 138 QUEUE_FLOW_UPDATE_RESIZED, 139 QUEUE_UPDATE, 140 QUEUE_AGED, 141 QUEUE_INDIRECT_ACTION, 142 143 /* Queue create arguments. */ 144 QUEUE_CREATE_POSTPONE, 145 QUEUE_TEMPLATE_TABLE, 146 QUEUE_PATTERN_TEMPLATE, 147 QUEUE_ACTIONS_TEMPLATE, 148 QUEUE_RULE_ID, 149 150 /* Queue destroy arguments. */ 151 QUEUE_DESTROY_ID, 152 QUEUE_DESTROY_POSTPONE, 153 154 /* Queue update arguments. */ 155 QUEUE_UPDATE_ID, 156 157 /* Queue indirect action arguments */ 158 QUEUE_INDIRECT_ACTION_CREATE, 159 QUEUE_INDIRECT_ACTION_LIST_CREATE, 160 QUEUE_INDIRECT_ACTION_UPDATE, 161 QUEUE_INDIRECT_ACTION_DESTROY, 162 QUEUE_INDIRECT_ACTION_QUERY, 163 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 164 165 /* Queue indirect action create arguments */ 166 QUEUE_INDIRECT_ACTION_CREATE_ID, 167 QUEUE_INDIRECT_ACTION_INGRESS, 168 QUEUE_INDIRECT_ACTION_EGRESS, 169 QUEUE_INDIRECT_ACTION_TRANSFER, 170 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 171 QUEUE_INDIRECT_ACTION_SPEC, 172 QUEUE_INDIRECT_ACTION_LIST, 173 174 /* Queue indirect action update arguments */ 175 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 176 177 /* Queue indirect action destroy arguments */ 178 QUEUE_INDIRECT_ACTION_DESTROY_ID, 179 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 180 181 /* Queue indirect action query arguments */ 182 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 183 184 /* Queue indirect action query_update arguments */ 185 QUEUE_INDIRECT_ACTION_QU_MODE, 186 187 /* Push arguments. */ 188 PUSH_QUEUE, 189 190 /* Pull arguments. */ 191 PULL_QUEUE, 192 193 /* Table arguments. */ 194 TABLE_CREATE, 195 TABLE_DESTROY, 196 TABLE_RESIZE, 197 TABLE_RESIZE_COMPLETE, 198 TABLE_CREATE_ID, 199 TABLE_DESTROY_ID, 200 TABLE_RESIZE_ID, 201 TABLE_RESIZE_RULES_NUMBER, 202 TABLE_INSERTION_TYPE, 203 TABLE_INSERTION_TYPE_NAME, 204 TABLE_HASH_FUNC, 205 TABLE_HASH_FUNC_NAME, 206 TABLE_GROUP, 207 TABLE_PRIORITY, 208 TABLE_INGRESS, 209 TABLE_EGRESS, 210 TABLE_TRANSFER, 211 TABLE_TRANSFER_WIRE_ORIG, 212 TABLE_TRANSFER_VPORT_ORIG, 213 TABLE_RESIZABLE, 214 TABLE_RULES_NUMBER, 215 TABLE_PATTERN_TEMPLATE, 216 TABLE_ACTIONS_TEMPLATE, 217 218 /* Group arguments */ 219 GROUP_ID, 220 GROUP_INGRESS, 221 GROUP_EGRESS, 222 GROUP_TRANSFER, 223 GROUP_SET_MISS_ACTIONS, 224 225 /* Hash calculation arguments. */ 226 HASH_CALC_TABLE, 227 HASH_CALC_PATTERN_INDEX, 228 HASH_CALC_PATTERN, 229 HASH_CALC_ENCAP, 230 HASH_CALC_DEST, 231 ENCAP_HASH_FIELD_SRC_PORT, 232 ENCAP_HASH_FIELD_GRE_FLOW_ID, 233 234 /* Tunnel arguments. */ 235 TUNNEL_CREATE, 236 TUNNEL_CREATE_TYPE, 237 TUNNEL_LIST, 238 TUNNEL_DESTROY, 239 TUNNEL_DESTROY_ID, 240 241 /* Destroy arguments. */ 242 DESTROY_RULE, 243 DESTROY_IS_USER_ID, 244 245 /* Query arguments. */ 246 QUERY_ACTION, 247 QUERY_IS_USER_ID, 248 249 /* List arguments. */ 250 LIST_GROUP, 251 252 /* Destroy aged flow arguments. */ 253 AGED_DESTROY, 254 255 /* Validate/create arguments. */ 256 VC_GROUP, 257 VC_PRIORITY, 258 VC_INGRESS, 259 VC_EGRESS, 260 VC_TRANSFER, 261 VC_TUNNEL_SET, 262 VC_TUNNEL_MATCH, 263 VC_USER_ID, 264 VC_IS_USER_ID, 265 266 /* Dump arguments */ 267 DUMP_ALL, 268 DUMP_ONE, 269 DUMP_IS_USER_ID, 270 271 /* Configure arguments */ 272 CONFIG_QUEUES_NUMBER, 273 CONFIG_QUEUES_SIZE, 274 CONFIG_COUNTERS_NUMBER, 275 CONFIG_AGING_OBJECTS_NUMBER, 276 CONFIG_METERS_NUMBER, 277 CONFIG_CONN_TRACK_NUMBER, 278 CONFIG_QUOTAS_NUMBER, 279 CONFIG_FLAGS, 280 CONFIG_HOST_PORT, 281 282 /* Indirect action arguments */ 283 INDIRECT_ACTION_CREATE, 284 INDIRECT_ACTION_LIST_CREATE, 285 INDIRECT_ACTION_FLOW_CONF_CREATE, 286 INDIRECT_ACTION_UPDATE, 287 INDIRECT_ACTION_DESTROY, 288 INDIRECT_ACTION_QUERY, 289 INDIRECT_ACTION_QUERY_UPDATE, 290 291 /* Indirect action create arguments */ 292 INDIRECT_ACTION_CREATE_ID, 293 INDIRECT_ACTION_INGRESS, 294 INDIRECT_ACTION_EGRESS, 295 INDIRECT_ACTION_TRANSFER, 296 INDIRECT_ACTION_SPEC, 297 INDIRECT_ACTION_LIST, 298 INDIRECT_ACTION_FLOW_CONF, 299 300 /* Indirect action destroy arguments */ 301 INDIRECT_ACTION_DESTROY_ID, 302 303 /* Indirect action query-and-update arguments */ 304 INDIRECT_ACTION_QU_MODE, 305 INDIRECT_ACTION_QU_MODE_NAME, 306 307 /* Validate/create pattern. */ 308 ITEM_PATTERN, 309 ITEM_PARAM_IS, 310 ITEM_PARAM_SPEC, 311 ITEM_PARAM_LAST, 312 ITEM_PARAM_MASK, 313 ITEM_PARAM_PREFIX, 314 ITEM_NEXT, 315 ITEM_END, 316 ITEM_VOID, 317 ITEM_INVERT, 318 ITEM_ANY, 319 ITEM_ANY_NUM, 320 ITEM_PORT_ID, 321 ITEM_PORT_ID_ID, 322 ITEM_MARK, 323 ITEM_MARK_ID, 324 ITEM_RAW, 325 ITEM_RAW_RELATIVE, 326 ITEM_RAW_SEARCH, 327 ITEM_RAW_OFFSET, 328 ITEM_RAW_LIMIT, 329 ITEM_RAW_PATTERN, 330 ITEM_RAW_PATTERN_HEX, 331 ITEM_ETH, 332 ITEM_ETH_DST, 333 ITEM_ETH_SRC, 334 ITEM_ETH_TYPE, 335 ITEM_ETH_HAS_VLAN, 336 ITEM_VLAN, 337 ITEM_VLAN_TCI, 338 ITEM_VLAN_PCP, 339 ITEM_VLAN_DEI, 340 ITEM_VLAN_VID, 341 ITEM_VLAN_INNER_TYPE, 342 ITEM_VLAN_HAS_MORE_VLAN, 343 ITEM_IPV4, 344 ITEM_IPV4_VER_IHL, 345 ITEM_IPV4_TOS, 346 ITEM_IPV4_LENGTH, 347 ITEM_IPV4_ID, 348 ITEM_IPV4_FRAGMENT_OFFSET, 349 ITEM_IPV4_TTL, 350 ITEM_IPV4_PROTO, 351 ITEM_IPV4_SRC, 352 ITEM_IPV4_DST, 353 ITEM_IPV6, 354 ITEM_IPV6_TC, 355 ITEM_IPV6_FLOW, 356 ITEM_IPV6_LEN, 357 ITEM_IPV6_PROTO, 358 ITEM_IPV6_HOP, 359 ITEM_IPV6_SRC, 360 ITEM_IPV6_DST, 361 ITEM_IPV6_HAS_FRAG_EXT, 362 ITEM_IPV6_ROUTING_EXT, 363 ITEM_IPV6_ROUTING_EXT_TYPE, 364 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 365 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 366 ITEM_ICMP, 367 ITEM_ICMP_TYPE, 368 ITEM_ICMP_CODE, 369 ITEM_ICMP_IDENT, 370 ITEM_ICMP_SEQ, 371 ITEM_UDP, 372 ITEM_UDP_SRC, 373 ITEM_UDP_DST, 374 ITEM_TCP, 375 ITEM_TCP_SRC, 376 ITEM_TCP_DST, 377 ITEM_TCP_FLAGS, 378 ITEM_SCTP, 379 ITEM_SCTP_SRC, 380 ITEM_SCTP_DST, 381 ITEM_SCTP_TAG, 382 ITEM_SCTP_CKSUM, 383 ITEM_VXLAN, 384 ITEM_VXLAN_VNI, 385 ITEM_VXLAN_LAST_RSVD, 386 ITEM_E_TAG, 387 ITEM_E_TAG_GRP_ECID_B, 388 ITEM_NVGRE, 389 ITEM_NVGRE_TNI, 390 ITEM_MPLS, 391 ITEM_MPLS_LABEL, 392 ITEM_MPLS_TC, 393 ITEM_MPLS_S, 394 ITEM_MPLS_TTL, 395 ITEM_GRE, 396 ITEM_GRE_PROTO, 397 ITEM_GRE_C_RSVD0_VER, 398 ITEM_GRE_C_BIT, 399 ITEM_GRE_K_BIT, 400 ITEM_GRE_S_BIT, 401 ITEM_FUZZY, 402 ITEM_FUZZY_THRESH, 403 ITEM_GTP, 404 ITEM_GTP_FLAGS, 405 ITEM_GTP_MSG_TYPE, 406 ITEM_GTP_TEID, 407 ITEM_GTPC, 408 ITEM_GTPU, 409 ITEM_GENEVE, 410 ITEM_GENEVE_VNI, 411 ITEM_GENEVE_PROTO, 412 ITEM_GENEVE_OPTLEN, 413 ITEM_VXLAN_GPE, 414 ITEM_VXLAN_GPE_VNI, 415 ITEM_VXLAN_GPE_PROTO, 416 ITEM_VXLAN_GPE_FLAGS, 417 ITEM_VXLAN_GPE_RSVD0, 418 ITEM_VXLAN_GPE_RSVD1, 419 ITEM_ARP_ETH_IPV4, 420 ITEM_ARP_ETH_IPV4_SHA, 421 ITEM_ARP_ETH_IPV4_SPA, 422 ITEM_ARP_ETH_IPV4_THA, 423 ITEM_ARP_ETH_IPV4_TPA, 424 ITEM_IPV6_EXT, 425 ITEM_IPV6_EXT_NEXT_HDR, 426 ITEM_IPV6_FRAG_EXT, 427 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 428 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 429 ITEM_IPV6_FRAG_EXT_ID, 430 ITEM_ICMP6, 431 ITEM_ICMP6_TYPE, 432 ITEM_ICMP6_CODE, 433 ITEM_ICMP6_ECHO_REQUEST, 434 ITEM_ICMP6_ECHO_REQUEST_ID, 435 ITEM_ICMP6_ECHO_REQUEST_SEQ, 436 ITEM_ICMP6_ECHO_REPLY, 437 ITEM_ICMP6_ECHO_REPLY_ID, 438 ITEM_ICMP6_ECHO_REPLY_SEQ, 439 ITEM_ICMP6_ND_NS, 440 ITEM_ICMP6_ND_NS_TARGET_ADDR, 441 ITEM_ICMP6_ND_NA, 442 ITEM_ICMP6_ND_NA_TARGET_ADDR, 443 ITEM_ICMP6_ND_OPT, 444 ITEM_ICMP6_ND_OPT_TYPE, 445 ITEM_ICMP6_ND_OPT_SLA_ETH, 446 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 447 ITEM_ICMP6_ND_OPT_TLA_ETH, 448 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 449 ITEM_META, 450 ITEM_META_DATA, 451 ITEM_RANDOM, 452 ITEM_RANDOM_VALUE, 453 ITEM_GRE_KEY, 454 ITEM_GRE_KEY_VALUE, 455 ITEM_GRE_OPTION, 456 ITEM_GRE_OPTION_CHECKSUM, 457 ITEM_GRE_OPTION_KEY, 458 ITEM_GRE_OPTION_SEQUENCE, 459 ITEM_GTP_PSC, 460 ITEM_GTP_PSC_QFI, 461 ITEM_GTP_PSC_PDU_T, 462 ITEM_PPPOES, 463 ITEM_PPPOED, 464 ITEM_PPPOE_SEID, 465 ITEM_PPPOE_PROTO_ID, 466 ITEM_HIGIG2, 467 ITEM_HIGIG2_CLASSIFICATION, 468 ITEM_HIGIG2_VID, 469 ITEM_TAG, 470 ITEM_TAG_DATA, 471 ITEM_TAG_INDEX, 472 ITEM_L2TPV3OIP, 473 ITEM_L2TPV3OIP_SESSION_ID, 474 ITEM_ESP, 475 ITEM_ESP_SPI, 476 ITEM_AH, 477 ITEM_AH_SPI, 478 ITEM_PFCP, 479 ITEM_PFCP_S_FIELD, 480 ITEM_PFCP_SEID, 481 ITEM_ECPRI, 482 ITEM_ECPRI_COMMON, 483 ITEM_ECPRI_COMMON_TYPE, 484 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 485 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 486 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 487 ITEM_ECPRI_MSG_IQ_DATA_PCID, 488 ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 489 ITEM_ECPRI_MSG_DLY_MSR_MSRID, 490 ITEM_GENEVE_OPT, 491 ITEM_GENEVE_OPT_CLASS, 492 ITEM_GENEVE_OPT_TYPE, 493 ITEM_GENEVE_OPT_LENGTH, 494 ITEM_GENEVE_OPT_DATA, 495 ITEM_INTEGRITY, 496 ITEM_INTEGRITY_LEVEL, 497 ITEM_INTEGRITY_VALUE, 498 ITEM_CONNTRACK, 499 ITEM_POL_PORT, 500 ITEM_POL_METER, 501 ITEM_POL_POLICY, 502 ITEM_PORT_REPRESENTOR, 503 ITEM_PORT_REPRESENTOR_PORT_ID, 504 ITEM_REPRESENTED_PORT, 505 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 506 ITEM_FLEX, 507 ITEM_FLEX_ITEM_HANDLE, 508 ITEM_FLEX_PATTERN_HANDLE, 509 ITEM_L2TPV2, 510 ITEM_L2TPV2_TYPE, 511 ITEM_L2TPV2_TYPE_DATA, 512 ITEM_L2TPV2_TYPE_DATA_L, 513 ITEM_L2TPV2_TYPE_DATA_S, 514 ITEM_L2TPV2_TYPE_DATA_O, 515 ITEM_L2TPV2_TYPE_DATA_L_S, 516 ITEM_L2TPV2_TYPE_CTRL, 517 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 518 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 519 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 520 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 521 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 522 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 523 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 524 ITEM_L2TPV2_MSG_DATA_S_NS, 525 ITEM_L2TPV2_MSG_DATA_S_NR, 526 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 527 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 528 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 529 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 530 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 531 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 532 ITEM_L2TPV2_MSG_DATA_L_S_NS, 533 ITEM_L2TPV2_MSG_DATA_L_S_NR, 534 ITEM_L2TPV2_MSG_CTRL_LENGTH, 535 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 536 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 537 ITEM_L2TPV2_MSG_CTRL_NS, 538 ITEM_L2TPV2_MSG_CTRL_NR, 539 ITEM_PPP, 540 ITEM_PPP_ADDR, 541 ITEM_PPP_CTRL, 542 ITEM_PPP_PROTO_ID, 543 ITEM_METER, 544 ITEM_METER_COLOR, 545 ITEM_METER_COLOR_NAME, 546 ITEM_QUOTA, 547 ITEM_QUOTA_STATE, 548 ITEM_QUOTA_STATE_NAME, 549 ITEM_AGGR_AFFINITY, 550 ITEM_AGGR_AFFINITY_VALUE, 551 ITEM_TX_QUEUE, 552 ITEM_TX_QUEUE_VALUE, 553 ITEM_IB_BTH, 554 ITEM_IB_BTH_OPCODE, 555 ITEM_IB_BTH_PKEY, 556 ITEM_IB_BTH_DST_QPN, 557 ITEM_IB_BTH_PSN, 558 ITEM_IPV6_PUSH_REMOVE_EXT, 559 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 560 ITEM_PTYPE, 561 ITEM_PTYPE_VALUE, 562 ITEM_NSH, 563 ITEM_COMPARE, 564 ITEM_COMPARE_OP, 565 ITEM_COMPARE_OP_VALUE, 566 ITEM_COMPARE_FIELD_A_TYPE, 567 ITEM_COMPARE_FIELD_A_TYPE_VALUE, 568 ITEM_COMPARE_FIELD_A_LEVEL, 569 ITEM_COMPARE_FIELD_A_LEVEL_VALUE, 570 ITEM_COMPARE_FIELD_A_TAG_INDEX, 571 ITEM_COMPARE_FIELD_A_TYPE_ID, 572 ITEM_COMPARE_FIELD_A_CLASS_ID, 573 ITEM_COMPARE_FIELD_A_OFFSET, 574 ITEM_COMPARE_FIELD_B_TYPE, 575 ITEM_COMPARE_FIELD_B_TYPE_VALUE, 576 ITEM_COMPARE_FIELD_B_LEVEL, 577 ITEM_COMPARE_FIELD_B_LEVEL_VALUE, 578 ITEM_COMPARE_FIELD_B_TAG_INDEX, 579 ITEM_COMPARE_FIELD_B_TYPE_ID, 580 ITEM_COMPARE_FIELD_B_CLASS_ID, 581 ITEM_COMPARE_FIELD_B_OFFSET, 582 ITEM_COMPARE_FIELD_B_VALUE, 583 ITEM_COMPARE_FIELD_B_POINTER, 584 ITEM_COMPARE_FIELD_WIDTH, 585 586 /* Validate/create actions. */ 587 ACTIONS, 588 ACTION_NEXT, 589 ACTION_END, 590 ACTION_VOID, 591 ACTION_PASSTHRU, 592 ACTION_SKIP_CMAN, 593 ACTION_JUMP, 594 ACTION_JUMP_GROUP, 595 ACTION_MARK, 596 ACTION_MARK_ID, 597 ACTION_FLAG, 598 ACTION_QUEUE, 599 ACTION_QUEUE_INDEX, 600 ACTION_DROP, 601 ACTION_COUNT, 602 ACTION_COUNT_ID, 603 ACTION_RSS, 604 ACTION_RSS_FUNC, 605 ACTION_RSS_LEVEL, 606 ACTION_RSS_FUNC_DEFAULT, 607 ACTION_RSS_FUNC_TOEPLITZ, 608 ACTION_RSS_FUNC_SIMPLE_XOR, 609 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, 610 ACTION_RSS_TYPES, 611 ACTION_RSS_TYPE, 612 ACTION_RSS_KEY, 613 ACTION_RSS_KEY_LEN, 614 ACTION_RSS_QUEUES, 615 ACTION_RSS_QUEUE, 616 ACTION_PF, 617 ACTION_VF, 618 ACTION_VF_ORIGINAL, 619 ACTION_VF_ID, 620 ACTION_PORT_ID, 621 ACTION_PORT_ID_ORIGINAL, 622 ACTION_PORT_ID_ID, 623 ACTION_METER, 624 ACTION_METER_COLOR, 625 ACTION_METER_COLOR_TYPE, 626 ACTION_METER_COLOR_GREEN, 627 ACTION_METER_COLOR_YELLOW, 628 ACTION_METER_COLOR_RED, 629 ACTION_METER_ID, 630 ACTION_METER_MARK, 631 ACTION_METER_PROFILE, 632 ACTION_METER_PROFILE_ID2PTR, 633 ACTION_METER_POLICY, 634 ACTION_METER_POLICY_ID2PTR, 635 ACTION_METER_COLOR_MODE, 636 ACTION_METER_STATE, 637 ACTION_OF_DEC_NW_TTL, 638 ACTION_OF_POP_VLAN, 639 ACTION_OF_PUSH_VLAN, 640 ACTION_OF_PUSH_VLAN_ETHERTYPE, 641 ACTION_OF_SET_VLAN_VID, 642 ACTION_OF_SET_VLAN_VID_VLAN_VID, 643 ACTION_OF_SET_VLAN_PCP, 644 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 645 ACTION_OF_POP_MPLS, 646 ACTION_OF_POP_MPLS_ETHERTYPE, 647 ACTION_OF_PUSH_MPLS, 648 ACTION_OF_PUSH_MPLS_ETHERTYPE, 649 ACTION_VXLAN_ENCAP, 650 ACTION_VXLAN_DECAP, 651 ACTION_NVGRE_ENCAP, 652 ACTION_NVGRE_DECAP, 653 ACTION_L2_ENCAP, 654 ACTION_L2_DECAP, 655 ACTION_MPLSOGRE_ENCAP, 656 ACTION_MPLSOGRE_DECAP, 657 ACTION_MPLSOUDP_ENCAP, 658 ACTION_MPLSOUDP_DECAP, 659 ACTION_SET_IPV4_SRC, 660 ACTION_SET_IPV4_SRC_IPV4_SRC, 661 ACTION_SET_IPV4_DST, 662 ACTION_SET_IPV4_DST_IPV4_DST, 663 ACTION_SET_IPV6_SRC, 664 ACTION_SET_IPV6_SRC_IPV6_SRC, 665 ACTION_SET_IPV6_DST, 666 ACTION_SET_IPV6_DST_IPV6_DST, 667 ACTION_SET_TP_SRC, 668 ACTION_SET_TP_SRC_TP_SRC, 669 ACTION_SET_TP_DST, 670 ACTION_SET_TP_DST_TP_DST, 671 ACTION_MAC_SWAP, 672 ACTION_DEC_TTL, 673 ACTION_SET_TTL, 674 ACTION_SET_TTL_TTL, 675 ACTION_SET_MAC_SRC, 676 ACTION_SET_MAC_SRC_MAC_SRC, 677 ACTION_SET_MAC_DST, 678 ACTION_SET_MAC_DST_MAC_DST, 679 ACTION_INC_TCP_SEQ, 680 ACTION_INC_TCP_SEQ_VALUE, 681 ACTION_DEC_TCP_SEQ, 682 ACTION_DEC_TCP_SEQ_VALUE, 683 ACTION_INC_TCP_ACK, 684 ACTION_INC_TCP_ACK_VALUE, 685 ACTION_DEC_TCP_ACK, 686 ACTION_DEC_TCP_ACK_VALUE, 687 ACTION_RAW_ENCAP, 688 ACTION_RAW_DECAP, 689 ACTION_RAW_ENCAP_SIZE, 690 ACTION_RAW_ENCAP_INDEX, 691 ACTION_RAW_ENCAP_INDEX_VALUE, 692 ACTION_RAW_DECAP_INDEX, 693 ACTION_RAW_DECAP_INDEX_VALUE, 694 ACTION_SET_TAG, 695 ACTION_SET_TAG_DATA, 696 ACTION_SET_TAG_INDEX, 697 ACTION_SET_TAG_MASK, 698 ACTION_SET_META, 699 ACTION_SET_META_DATA, 700 ACTION_SET_META_MASK, 701 ACTION_SET_IPV4_DSCP, 702 ACTION_SET_IPV4_DSCP_VALUE, 703 ACTION_SET_IPV6_DSCP, 704 ACTION_SET_IPV6_DSCP_VALUE, 705 ACTION_AGE, 706 ACTION_AGE_TIMEOUT, 707 ACTION_AGE_UPDATE, 708 ACTION_AGE_UPDATE_TIMEOUT, 709 ACTION_AGE_UPDATE_TOUCH, 710 ACTION_SAMPLE, 711 ACTION_SAMPLE_RATIO, 712 ACTION_SAMPLE_INDEX, 713 ACTION_SAMPLE_INDEX_VALUE, 714 ACTION_INDIRECT, 715 ACTION_INDIRECT_LIST, 716 ACTION_INDIRECT_LIST_HANDLE, 717 ACTION_INDIRECT_LIST_CONF, 718 INDIRECT_LIST_ACTION_ID2PTR_HANDLE, 719 INDIRECT_LIST_ACTION_ID2PTR_CONF, 720 ACTION_SHARED_INDIRECT, 721 INDIRECT_ACTION_PORT, 722 INDIRECT_ACTION_ID2PTR, 723 ACTION_MODIFY_FIELD, 724 ACTION_MODIFY_FIELD_OP, 725 ACTION_MODIFY_FIELD_OP_VALUE, 726 ACTION_MODIFY_FIELD_DST_TYPE, 727 ACTION_MODIFY_FIELD_DST_TYPE_VALUE, 728 ACTION_MODIFY_FIELD_DST_LEVEL, 729 ACTION_MODIFY_FIELD_DST_LEVEL_VALUE, 730 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 731 ACTION_MODIFY_FIELD_DST_TYPE_ID, 732 ACTION_MODIFY_FIELD_DST_CLASS_ID, 733 ACTION_MODIFY_FIELD_DST_OFFSET, 734 ACTION_MODIFY_FIELD_SRC_TYPE, 735 ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, 736 ACTION_MODIFY_FIELD_SRC_LEVEL, 737 ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE, 738 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 739 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 740 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 741 ACTION_MODIFY_FIELD_SRC_OFFSET, 742 ACTION_MODIFY_FIELD_SRC_VALUE, 743 ACTION_MODIFY_FIELD_SRC_POINTER, 744 ACTION_MODIFY_FIELD_WIDTH, 745 ACTION_CONNTRACK, 746 ACTION_CONNTRACK_UPDATE, 747 ACTION_CONNTRACK_UPDATE_DIR, 748 ACTION_CONNTRACK_UPDATE_CTX, 749 ACTION_POL_G, 750 ACTION_POL_Y, 751 ACTION_POL_R, 752 ACTION_PORT_REPRESENTOR, 753 ACTION_PORT_REPRESENTOR_PORT_ID, 754 ACTION_REPRESENTED_PORT, 755 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 756 ACTION_SEND_TO_KERNEL, 757 ACTION_QUOTA_CREATE, 758 ACTION_QUOTA_CREATE_LIMIT, 759 ACTION_QUOTA_CREATE_MODE, 760 ACTION_QUOTA_CREATE_MODE_NAME, 761 ACTION_QUOTA_QU, 762 ACTION_QUOTA_QU_LIMIT, 763 ACTION_QUOTA_QU_UPDATE_OP, 764 ACTION_QUOTA_QU_UPDATE_OP_NAME, 765 ACTION_IPV6_EXT_REMOVE, 766 ACTION_IPV6_EXT_REMOVE_INDEX, 767 ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, 768 ACTION_IPV6_EXT_PUSH, 769 ACTION_IPV6_EXT_PUSH_INDEX, 770 ACTION_IPV6_EXT_PUSH_INDEX_VALUE, 771 ACTION_NAT64, 772 ACTION_NAT64_MODE, 773 }; 774 775 /** Maximum size for pattern in struct rte_flow_item_raw. */ 776 #define ITEM_RAW_PATTERN_SIZE 512 777 778 /** Maximum size for GENEVE option data pattern in bytes. */ 779 #define ITEM_GENEVE_OPT_DATA_SIZE 124 780 781 /** Storage size for struct rte_flow_item_raw including pattern. */ 782 #define ITEM_RAW_SIZE \ 783 (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) 784 785 static const char *const compare_ops[] = { 786 "eq", "ne", "lt", "le", "gt", "ge", NULL 787 }; 788 789 /** Maximum size for external pattern in struct rte_flow_field_data. */ 790 #define FLOW_FIELD_PATTERN_SIZE 32 791 792 /** Storage size for struct rte_flow_action_modify_field including pattern. */ 793 #define ACTION_MODIFY_SIZE \ 794 (sizeof(struct rte_flow_action_modify_field) + \ 795 FLOW_FIELD_PATTERN_SIZE) 796 797 /** Maximum number of queue indices in struct rte_flow_action_rss. */ 798 #define ACTION_RSS_QUEUE_NUM 128 799 800 /** Storage for struct rte_flow_action_rss including external data. */ 801 struct action_rss_data { 802 struct rte_flow_action_rss conf; 803 uint8_t key[RSS_HASH_KEY_LENGTH]; 804 uint16_t queue[ACTION_RSS_QUEUE_NUM]; 805 }; 806 807 /** Maximum data size in struct rte_flow_action_raw_encap. */ 808 #define ACTION_RAW_ENCAP_MAX_DATA 512 809 #define RAW_ENCAP_CONFS_MAX_NUM 8 810 811 /** Storage for struct rte_flow_action_raw_encap. */ 812 struct raw_encap_conf { 813 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 814 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 815 size_t size; 816 }; 817 818 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 819 820 /** Storage for struct rte_flow_action_raw_encap including external data. */ 821 struct action_raw_encap_data { 822 struct rte_flow_action_raw_encap conf; 823 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 824 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 825 uint16_t idx; 826 }; 827 828 /** Storage for struct rte_flow_action_raw_decap. */ 829 struct raw_decap_conf { 830 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 831 size_t size; 832 }; 833 834 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 835 836 /** Storage for struct rte_flow_action_raw_decap including external data. */ 837 struct action_raw_decap_data { 838 struct rte_flow_action_raw_decap conf; 839 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 840 uint16_t idx; 841 }; 842 843 /** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ 844 #define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 845 #define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 846 847 /** Storage for struct rte_flow_action_ipv6_ext_push. */ 848 struct ipv6_ext_push_conf { 849 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 850 size_t size; 851 uint8_t type; 852 }; 853 854 struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 855 856 /** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ 857 struct action_ipv6_ext_push_data { 858 struct rte_flow_action_ipv6_ext_push conf; 859 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 860 uint8_t type; 861 uint16_t idx; 862 }; 863 864 /** Storage for struct rte_flow_action_ipv6_ext_remove. */ 865 struct ipv6_ext_remove_conf { 866 struct rte_flow_action_ipv6_ext_remove conf; 867 uint8_t type; 868 }; 869 870 struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 871 872 /** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ 873 struct action_ipv6_ext_remove_data { 874 struct rte_flow_action_ipv6_ext_remove conf; 875 uint8_t type; 876 uint16_t idx; 877 }; 878 879 struct vxlan_encap_conf vxlan_encap_conf = { 880 .select_ipv4 = 1, 881 .select_vlan = 0, 882 .select_tos_ttl = 0, 883 .vni = "\x00\x00\x00", 884 .udp_src = 0, 885 .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), 886 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 887 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 888 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 889 "\x00\x00\x00\x00\x00\x00\x00\x01", 890 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 891 "\x00\x00\x00\x00\x00\x00\x11\x11", 892 .vlan_tci = 0, 893 .ip_tos = 0, 894 .ip_ttl = 255, 895 .eth_src = "\x00\x00\x00\x00\x00\x00", 896 .eth_dst = "\xff\xff\xff\xff\xff\xff", 897 }; 898 899 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */ 900 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6 901 902 /** Storage for struct rte_flow_action_vxlan_encap including external data. */ 903 struct action_vxlan_encap_data { 904 struct rte_flow_action_vxlan_encap conf; 905 struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; 906 struct rte_flow_item_eth item_eth; 907 struct rte_flow_item_vlan item_vlan; 908 union { 909 struct rte_flow_item_ipv4 item_ipv4; 910 struct rte_flow_item_ipv6 item_ipv6; 911 }; 912 struct rte_flow_item_udp item_udp; 913 struct rte_flow_item_vxlan item_vxlan; 914 }; 915 916 struct nvgre_encap_conf nvgre_encap_conf = { 917 .select_ipv4 = 1, 918 .select_vlan = 0, 919 .tni = "\x00\x00\x00", 920 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 921 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 922 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 923 "\x00\x00\x00\x00\x00\x00\x00\x01", 924 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 925 "\x00\x00\x00\x00\x00\x00\x11\x11", 926 .vlan_tci = 0, 927 .eth_src = "\x00\x00\x00\x00\x00\x00", 928 .eth_dst = "\xff\xff\xff\xff\xff\xff", 929 }; 930 931 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */ 932 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 933 934 /** Storage for struct rte_flow_action_nvgre_encap including external data. */ 935 struct action_nvgre_encap_data { 936 struct rte_flow_action_nvgre_encap conf; 937 struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; 938 struct rte_flow_item_eth item_eth; 939 struct rte_flow_item_vlan item_vlan; 940 union { 941 struct rte_flow_item_ipv4 item_ipv4; 942 struct rte_flow_item_ipv6 item_ipv6; 943 }; 944 struct rte_flow_item_nvgre item_nvgre; 945 }; 946 947 struct l2_encap_conf l2_encap_conf; 948 949 struct l2_decap_conf l2_decap_conf; 950 951 struct mplsogre_encap_conf mplsogre_encap_conf; 952 953 struct mplsogre_decap_conf mplsogre_decap_conf; 954 955 struct mplsoudp_encap_conf mplsoudp_encap_conf; 956 957 struct mplsoudp_decap_conf mplsoudp_decap_conf; 958 959 struct rte_flow_action_conntrack conntrack_context; 960 961 #define ACTION_SAMPLE_ACTIONS_NUM 10 962 #define RAW_SAMPLE_CONFS_MAX_NUM 8 963 /** Storage for struct rte_flow_action_sample including external data. */ 964 struct action_sample_data { 965 struct rte_flow_action_sample conf; 966 uint32_t idx; 967 }; 968 /** Storage for struct rte_flow_action_sample. */ 969 struct raw_sample_conf { 970 struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; 971 }; 972 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; 973 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; 974 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; 975 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; 976 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; 977 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 978 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 979 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 980 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; 981 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; 982 struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; 983 struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; 984 985 static const char *const modify_field_ops[] = { 986 "set", "add", "sub", NULL 987 }; 988 989 static const char *const flow_field_ids[] = { 990 "start", "mac_dst", "mac_src", 991 "vlan_type", "vlan_id", "mac_type", 992 "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", 993 "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", 994 "tcp_port_src", "tcp_port_dst", 995 "tcp_seq_num", "tcp_ack_num", "tcp_flags", 996 "udp_port_src", "udp_port_dst", 997 "vxlan_vni", "geneve_vni", "gtp_teid", 998 "tag", "mark", "meta", "pointer", "value", 999 "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", 1000 "ipv6_proto", 1001 "flex_item", 1002 "hash_result", 1003 "geneve_opt_type", "geneve_opt_class", "geneve_opt_data", "mpls", 1004 "tcp_data_off", "ipv4_ihl", "ipv4_total_len", "ipv6_payload_len", 1005 "random", 1006 "ipv4_proto", 1007 "esp_spi", "esp_seq_num", "esp_proto", 1008 "ipv6_flow_label", "ipv6_traffic_class", 1009 NULL 1010 }; 1011 1012 static const char *const meter_colors[] = { 1013 "green", "yellow", "red", "all", NULL 1014 }; 1015 1016 static const char *const table_insertion_types[] = { 1017 "pattern", "index", NULL 1018 }; 1019 1020 static const char *const table_hash_funcs[] = { 1021 "default", "linear", "crc32", "crc16", NULL 1022 }; 1023 1024 #define RAW_IPSEC_CONFS_MAX_NUM 8 1025 1026 /** Maximum number of subsequent tokens and arguments on the stack. */ 1027 #define CTX_STACK_SIZE 16 1028 1029 /** Parser context. */ 1030 struct context { 1031 /** Stack of subsequent token lists to process. */ 1032 const enum index *next[CTX_STACK_SIZE]; 1033 /** Arguments for stacked tokens. */ 1034 const void *args[CTX_STACK_SIZE]; 1035 enum index curr; /**< Current token index. */ 1036 enum index prev; /**< Index of the last token seen. */ 1037 int next_num; /**< Number of entries in next[]. */ 1038 int args_num; /**< Number of entries in args[]. */ 1039 uint32_t eol:1; /**< EOL has been detected. */ 1040 uint32_t last:1; /**< No more arguments. */ 1041 portid_t port; /**< Current port ID (for completions). */ 1042 uint32_t objdata; /**< Object-specific data. */ 1043 void *object; /**< Address of current object for relative offsets. */ 1044 void *objmask; /**< Object a full mask must be written to. */ 1045 }; 1046 1047 /** Token argument. */ 1048 struct arg { 1049 uint32_t hton:1; /**< Use network byte ordering. */ 1050 uint32_t sign:1; /**< Value is signed. */ 1051 uint32_t bounded:1; /**< Value is bounded. */ 1052 uintmax_t min; /**< Minimum value if bounded. */ 1053 uintmax_t max; /**< Maximum value if bounded. */ 1054 uint32_t offset; /**< Relative offset from ctx->object. */ 1055 uint32_t size; /**< Field size. */ 1056 const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ 1057 }; 1058 1059 /** Parser token definition. */ 1060 struct token { 1061 /** Type displayed during completion (defaults to "TOKEN"). */ 1062 const char *type; 1063 /** Help displayed during completion (defaults to token name). */ 1064 const char *help; 1065 /** Private data used by parser functions. */ 1066 const void *priv; 1067 /** 1068 * Lists of subsequent tokens to push on the stack. Each call to the 1069 * parser consumes the last entry of that stack. 1070 */ 1071 const enum index *const *next; 1072 /** Arguments stack for subsequent tokens that need them. */ 1073 const struct arg *const *args; 1074 /** 1075 * Token-processing callback, returns -1 in case of error, the 1076 * length of the matched string otherwise. If NULL, attempts to 1077 * match the token name. 1078 * 1079 * If buf is not NULL, the result should be stored in it according 1080 * to context. An error is returned if not large enough. 1081 */ 1082 int (*call)(struct context *ctx, const struct token *token, 1083 const char *str, unsigned int len, 1084 void *buf, unsigned int size); 1085 /** 1086 * Callback that provides possible values for this token, used for 1087 * completion. Returns -1 in case of error, the number of possible 1088 * values otherwise. If NULL, the token name is used. 1089 * 1090 * If buf is not NULL, entry index ent is written to buf and the 1091 * full length of the entry is returned (same behavior as 1092 * snprintf()). 1093 */ 1094 int (*comp)(struct context *ctx, const struct token *token, 1095 unsigned int ent, char *buf, unsigned int size); 1096 /** Mandatory token name, no default value. */ 1097 const char *name; 1098 }; 1099 1100 /** Static initializer for the next field. */ 1101 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } 1102 1103 /** Static initializer for a NEXT() entry. */ 1104 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } 1105 1106 /** Static initializer for the args field. */ 1107 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } 1108 1109 /** Static initializer for ARGS() to target a field. */ 1110 #define ARGS_ENTRY(s, f) \ 1111 (&(const struct arg){ \ 1112 .offset = offsetof(s, f), \ 1113 .size = sizeof(((s *)0)->f), \ 1114 }) 1115 1116 /** Static initializer for ARGS() to target a bit-field. */ 1117 #define ARGS_ENTRY_BF(s, f, b) \ 1118 (&(const struct arg){ \ 1119 .size = sizeof(s), \ 1120 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ 1121 }) 1122 1123 /** Static initializer for ARGS() to target a field with limits. */ 1124 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \ 1125 (&(const struct arg){ \ 1126 .bounded = 1, \ 1127 .min = (i), \ 1128 .max = (a), \ 1129 .offset = offsetof(s, f), \ 1130 .size = sizeof(((s *)0)->f), \ 1131 }) 1132 1133 /** Static initializer for ARGS() to target an arbitrary bit-mask. */ 1134 #define ARGS_ENTRY_MASK(s, f, m) \ 1135 (&(const struct arg){ \ 1136 .offset = offsetof(s, f), \ 1137 .size = sizeof(((s *)0)->f), \ 1138 .mask = (const void *)(m), \ 1139 }) 1140 1141 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ 1142 #define ARGS_ENTRY_MASK_HTON(s, f, m) \ 1143 (&(const struct arg){ \ 1144 .hton = 1, \ 1145 .offset = offsetof(s, f), \ 1146 .size = sizeof(((s *)0)->f), \ 1147 .mask = (const void *)(m), \ 1148 }) 1149 1150 /** Static initializer for ARGS() to target a pointer. */ 1151 #define ARGS_ENTRY_PTR(s, f) \ 1152 (&(const struct arg){ \ 1153 .size = sizeof(*((s *)0)->f), \ 1154 }) 1155 1156 /** Static initializer for ARGS() with arbitrary offset and size. */ 1157 #define ARGS_ENTRY_ARB(o, s) \ 1158 (&(const struct arg){ \ 1159 .offset = (o), \ 1160 .size = (s), \ 1161 }) 1162 1163 /** Same as ARGS_ENTRY_ARB() with bounded values. */ 1164 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ 1165 (&(const struct arg){ \ 1166 .bounded = 1, \ 1167 .min = (i), \ 1168 .max = (a), \ 1169 .offset = (o), \ 1170 .size = (s), \ 1171 }) 1172 1173 /** Same as ARGS_ENTRY() using network byte ordering. */ 1174 #define ARGS_ENTRY_HTON(s, f) \ 1175 (&(const struct arg){ \ 1176 .hton = 1, \ 1177 .offset = offsetof(s, f), \ 1178 .size = sizeof(((s *)0)->f), \ 1179 }) 1180 1181 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ 1182 #define ARG_ENTRY_HTON(s) \ 1183 (&(const struct arg){ \ 1184 .hton = 1, \ 1185 .offset = 0, \ 1186 .size = sizeof(s), \ 1187 }) 1188 1189 /** Parser output buffer layout expected by cmd_flow_parsed(). */ 1190 struct buffer { 1191 enum index command; /**< Flow command. */ 1192 portid_t port; /**< Affected port ID. */ 1193 queueid_t queue; /** Async queue ID. */ 1194 bool postpone; /** Postpone async operation */ 1195 union { 1196 struct { 1197 struct rte_flow_port_attr port_attr; 1198 uint32_t nb_queue; 1199 struct rte_flow_queue_attr queue_attr; 1200 } configure; /**< Configuration arguments. */ 1201 struct { 1202 uint32_t *template_id; 1203 uint32_t template_id_n; 1204 } templ_destroy; /**< Template destroy arguments. */ 1205 struct { 1206 uint32_t id; 1207 struct rte_flow_template_table_attr attr; 1208 uint32_t *pat_templ_id; 1209 uint32_t pat_templ_id_n; 1210 uint32_t *act_templ_id; 1211 uint32_t act_templ_id_n; 1212 } table; /**< Table arguments. */ 1213 struct { 1214 uint32_t *table_id; 1215 uint32_t table_id_n; 1216 } table_destroy; /**< Template destroy arguments. */ 1217 struct { 1218 uint32_t *action_id; 1219 uint32_t action_id_n; 1220 } ia_destroy; /**< Indirect action destroy arguments. */ 1221 struct { 1222 uint32_t action_id; 1223 enum rte_flow_query_update_mode qu_mode; 1224 } ia; /* Indirect action query arguments */ 1225 struct { 1226 uint32_t table_id; 1227 uint32_t pat_templ_id; 1228 uint32_t rule_id; 1229 uint32_t act_templ_id; 1230 struct rte_flow_attr attr; 1231 struct tunnel_ops tunnel_ops; 1232 uintptr_t user_id; 1233 struct rte_flow_item *pattern; 1234 struct rte_flow_action *actions; 1235 struct rte_flow_action *masks; 1236 uint32_t pattern_n; 1237 uint32_t actions_n; 1238 uint8_t *data; 1239 enum rte_flow_encap_hash_field field; 1240 uint8_t encap_hash; 1241 } vc; /**< Validate/create arguments. */ 1242 struct { 1243 uint64_t *rule; 1244 uint64_t rule_n; 1245 bool is_user_id; 1246 } destroy; /**< Destroy arguments. */ 1247 struct { 1248 char file[128]; 1249 bool mode; 1250 uint64_t rule; 1251 bool is_user_id; 1252 } dump; /**< Dump arguments. */ 1253 struct { 1254 uint64_t rule; 1255 struct rte_flow_action action; 1256 bool is_user_id; 1257 } query; /**< Query arguments. */ 1258 struct { 1259 uint32_t *group; 1260 uint32_t group_n; 1261 } list; /**< List arguments. */ 1262 struct { 1263 int set; 1264 } isolate; /**< Isolated mode arguments. */ 1265 struct { 1266 int destroy; 1267 } aged; /**< Aged arguments. */ 1268 struct { 1269 uint32_t policy_id; 1270 } policy;/**< Policy arguments. */ 1271 struct { 1272 uint16_t token; 1273 uintptr_t uintptr; 1274 char filename[128]; 1275 } flex; /**< Flex arguments*/ 1276 } args; /**< Command arguments. */ 1277 }; 1278 1279 /** Private data for pattern items. */ 1280 struct parse_item_priv { 1281 enum rte_flow_item_type type; /**< Item type. */ 1282 uint32_t size; /**< Size of item specification structure. */ 1283 }; 1284 1285 #define PRIV_ITEM(t, s) \ 1286 (&(const struct parse_item_priv){ \ 1287 .type = RTE_FLOW_ITEM_TYPE_ ## t, \ 1288 .size = s, \ 1289 }) 1290 1291 /** Private data for actions. */ 1292 struct parse_action_priv { 1293 enum rte_flow_action_type type; /**< Action type. */ 1294 uint32_t size; /**< Size of action configuration structure. */ 1295 }; 1296 1297 #define PRIV_ACTION(t, s) \ 1298 (&(const struct parse_action_priv){ \ 1299 .type = RTE_FLOW_ACTION_TYPE_ ## t, \ 1300 .size = s, \ 1301 }) 1302 1303 static const enum index next_flex_item[] = { 1304 FLEX_ITEM_INIT, 1305 FLEX_ITEM_CREATE, 1306 FLEX_ITEM_DESTROY, 1307 ZERO, 1308 }; 1309 1310 static const enum index next_config_attr[] = { 1311 CONFIG_QUEUES_NUMBER, 1312 CONFIG_QUEUES_SIZE, 1313 CONFIG_COUNTERS_NUMBER, 1314 CONFIG_AGING_OBJECTS_NUMBER, 1315 CONFIG_METERS_NUMBER, 1316 CONFIG_CONN_TRACK_NUMBER, 1317 CONFIG_QUOTAS_NUMBER, 1318 CONFIG_FLAGS, 1319 CONFIG_HOST_PORT, 1320 END, 1321 ZERO, 1322 }; 1323 1324 static const enum index next_pt_subcmd[] = { 1325 PATTERN_TEMPLATE_CREATE, 1326 PATTERN_TEMPLATE_DESTROY, 1327 ZERO, 1328 }; 1329 1330 static const enum index next_pt_attr[] = { 1331 PATTERN_TEMPLATE_CREATE_ID, 1332 PATTERN_TEMPLATE_RELAXED_MATCHING, 1333 PATTERN_TEMPLATE_INGRESS, 1334 PATTERN_TEMPLATE_EGRESS, 1335 PATTERN_TEMPLATE_TRANSFER, 1336 PATTERN_TEMPLATE_SPEC, 1337 ZERO, 1338 }; 1339 1340 static const enum index next_pt_destroy_attr[] = { 1341 PATTERN_TEMPLATE_DESTROY_ID, 1342 END, 1343 ZERO, 1344 }; 1345 1346 static const enum index next_at_subcmd[] = { 1347 ACTIONS_TEMPLATE_CREATE, 1348 ACTIONS_TEMPLATE_DESTROY, 1349 ZERO, 1350 }; 1351 1352 static const enum index next_at_attr[] = { 1353 ACTIONS_TEMPLATE_CREATE_ID, 1354 ACTIONS_TEMPLATE_INGRESS, 1355 ACTIONS_TEMPLATE_EGRESS, 1356 ACTIONS_TEMPLATE_TRANSFER, 1357 ACTIONS_TEMPLATE_SPEC, 1358 ZERO, 1359 }; 1360 1361 static const enum index next_at_destroy_attr[] = { 1362 ACTIONS_TEMPLATE_DESTROY_ID, 1363 END, 1364 ZERO, 1365 }; 1366 1367 static const enum index next_group_attr[] = { 1368 GROUP_INGRESS, 1369 GROUP_EGRESS, 1370 GROUP_TRANSFER, 1371 GROUP_SET_MISS_ACTIONS, 1372 ZERO, 1373 }; 1374 1375 static const enum index next_table_subcmd[] = { 1376 TABLE_CREATE, 1377 TABLE_DESTROY, 1378 TABLE_RESIZE, 1379 TABLE_RESIZE_COMPLETE, 1380 ZERO, 1381 }; 1382 1383 static const enum index next_table_attr[] = { 1384 TABLE_CREATE_ID, 1385 TABLE_GROUP, 1386 TABLE_INSERTION_TYPE, 1387 TABLE_HASH_FUNC, 1388 TABLE_PRIORITY, 1389 TABLE_INGRESS, 1390 TABLE_EGRESS, 1391 TABLE_TRANSFER, 1392 TABLE_TRANSFER_WIRE_ORIG, 1393 TABLE_TRANSFER_VPORT_ORIG, 1394 TABLE_RESIZABLE, 1395 TABLE_RULES_NUMBER, 1396 TABLE_PATTERN_TEMPLATE, 1397 TABLE_ACTIONS_TEMPLATE, 1398 END, 1399 ZERO, 1400 }; 1401 1402 static const enum index next_table_destroy_attr[] = { 1403 TABLE_DESTROY_ID, 1404 END, 1405 ZERO, 1406 }; 1407 1408 static const enum index next_queue_subcmd[] = { 1409 QUEUE_CREATE, 1410 QUEUE_DESTROY, 1411 QUEUE_FLOW_UPDATE_RESIZED, 1412 QUEUE_UPDATE, 1413 QUEUE_AGED, 1414 QUEUE_INDIRECT_ACTION, 1415 ZERO, 1416 }; 1417 1418 static const enum index next_queue_destroy_attr[] = { 1419 QUEUE_DESTROY_ID, 1420 END, 1421 ZERO, 1422 }; 1423 1424 static const enum index next_qia_subcmd[] = { 1425 QUEUE_INDIRECT_ACTION_CREATE, 1426 QUEUE_INDIRECT_ACTION_UPDATE, 1427 QUEUE_INDIRECT_ACTION_DESTROY, 1428 QUEUE_INDIRECT_ACTION_QUERY, 1429 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 1430 ZERO, 1431 }; 1432 1433 static const enum index next_qia_create_attr[] = { 1434 QUEUE_INDIRECT_ACTION_CREATE_ID, 1435 QUEUE_INDIRECT_ACTION_INGRESS, 1436 QUEUE_INDIRECT_ACTION_EGRESS, 1437 QUEUE_INDIRECT_ACTION_TRANSFER, 1438 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 1439 QUEUE_INDIRECT_ACTION_SPEC, 1440 QUEUE_INDIRECT_ACTION_LIST, 1441 ZERO, 1442 }; 1443 1444 static const enum index next_qia_update_attr[] = { 1445 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1446 QUEUE_INDIRECT_ACTION_SPEC, 1447 ZERO, 1448 }; 1449 1450 static const enum index next_qia_destroy_attr[] = { 1451 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 1452 QUEUE_INDIRECT_ACTION_DESTROY_ID, 1453 END, 1454 ZERO, 1455 }; 1456 1457 static const enum index next_qia_query_attr[] = { 1458 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 1459 END, 1460 ZERO, 1461 }; 1462 1463 static const enum index next_ia_create_attr[] = { 1464 INDIRECT_ACTION_CREATE_ID, 1465 INDIRECT_ACTION_INGRESS, 1466 INDIRECT_ACTION_EGRESS, 1467 INDIRECT_ACTION_TRANSFER, 1468 INDIRECT_ACTION_SPEC, 1469 INDIRECT_ACTION_LIST, 1470 INDIRECT_ACTION_FLOW_CONF, 1471 ZERO, 1472 }; 1473 1474 static const enum index next_ia[] = { 1475 INDIRECT_ACTION_ID2PTR, 1476 ACTION_NEXT, 1477 ZERO 1478 }; 1479 1480 static const enum index next_ial[] = { 1481 ACTION_INDIRECT_LIST_HANDLE, 1482 ACTION_INDIRECT_LIST_CONF, 1483 ACTION_NEXT, 1484 ZERO 1485 }; 1486 1487 static const enum index next_qia_qu_attr[] = { 1488 QUEUE_INDIRECT_ACTION_QU_MODE, 1489 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1490 INDIRECT_ACTION_SPEC, 1491 ZERO 1492 }; 1493 1494 static const enum index next_ia_qu_attr[] = { 1495 INDIRECT_ACTION_QU_MODE, 1496 INDIRECT_ACTION_SPEC, 1497 ZERO 1498 }; 1499 1500 static const enum index next_dump_subcmd[] = { 1501 DUMP_ALL, 1502 DUMP_ONE, 1503 DUMP_IS_USER_ID, 1504 ZERO, 1505 }; 1506 1507 static const enum index next_ia_subcmd[] = { 1508 INDIRECT_ACTION_CREATE, 1509 INDIRECT_ACTION_UPDATE, 1510 INDIRECT_ACTION_DESTROY, 1511 INDIRECT_ACTION_QUERY, 1512 INDIRECT_ACTION_QUERY_UPDATE, 1513 ZERO, 1514 }; 1515 1516 static const enum index next_vc_attr[] = { 1517 VC_GROUP, 1518 VC_PRIORITY, 1519 VC_INGRESS, 1520 VC_EGRESS, 1521 VC_TRANSFER, 1522 VC_TUNNEL_SET, 1523 VC_TUNNEL_MATCH, 1524 VC_USER_ID, 1525 ITEM_PATTERN, 1526 ZERO, 1527 }; 1528 1529 static const enum index next_destroy_attr[] = { 1530 DESTROY_RULE, 1531 DESTROY_IS_USER_ID, 1532 END, 1533 ZERO, 1534 }; 1535 1536 static const enum index next_dump_attr[] = { 1537 COMMON_FILE_PATH, 1538 END, 1539 ZERO, 1540 }; 1541 1542 static const enum index next_query_attr[] = { 1543 QUERY_IS_USER_ID, 1544 END, 1545 ZERO, 1546 }; 1547 1548 static const enum index next_list_attr[] = { 1549 LIST_GROUP, 1550 END, 1551 ZERO, 1552 }; 1553 1554 static const enum index next_aged_attr[] = { 1555 AGED_DESTROY, 1556 END, 1557 ZERO, 1558 }; 1559 1560 static const enum index next_ia_destroy_attr[] = { 1561 INDIRECT_ACTION_DESTROY_ID, 1562 END, 1563 ZERO, 1564 }; 1565 1566 static const enum index next_async_insert_subcmd[] = { 1567 QUEUE_PATTERN_TEMPLATE, 1568 QUEUE_RULE_ID, 1569 ZERO, 1570 }; 1571 1572 static const enum index item_param[] = { 1573 ITEM_PARAM_IS, 1574 ITEM_PARAM_SPEC, 1575 ITEM_PARAM_LAST, 1576 ITEM_PARAM_MASK, 1577 ITEM_PARAM_PREFIX, 1578 ZERO, 1579 }; 1580 1581 static const enum index next_item[] = { 1582 ITEM_END, 1583 ITEM_VOID, 1584 ITEM_INVERT, 1585 ITEM_ANY, 1586 ITEM_PORT_ID, 1587 ITEM_MARK, 1588 ITEM_RAW, 1589 ITEM_ETH, 1590 ITEM_VLAN, 1591 ITEM_IPV4, 1592 ITEM_IPV6, 1593 ITEM_ICMP, 1594 ITEM_UDP, 1595 ITEM_TCP, 1596 ITEM_SCTP, 1597 ITEM_VXLAN, 1598 ITEM_E_TAG, 1599 ITEM_NVGRE, 1600 ITEM_MPLS, 1601 ITEM_GRE, 1602 ITEM_FUZZY, 1603 ITEM_GTP, 1604 ITEM_GTPC, 1605 ITEM_GTPU, 1606 ITEM_GENEVE, 1607 ITEM_VXLAN_GPE, 1608 ITEM_ARP_ETH_IPV4, 1609 ITEM_IPV6_EXT, 1610 ITEM_IPV6_FRAG_EXT, 1611 ITEM_IPV6_ROUTING_EXT, 1612 ITEM_ICMP6, 1613 ITEM_ICMP6_ECHO_REQUEST, 1614 ITEM_ICMP6_ECHO_REPLY, 1615 ITEM_ICMP6_ND_NS, 1616 ITEM_ICMP6_ND_NA, 1617 ITEM_ICMP6_ND_OPT, 1618 ITEM_ICMP6_ND_OPT_SLA_ETH, 1619 ITEM_ICMP6_ND_OPT_TLA_ETH, 1620 ITEM_META, 1621 ITEM_RANDOM, 1622 ITEM_GRE_KEY, 1623 ITEM_GRE_OPTION, 1624 ITEM_GTP_PSC, 1625 ITEM_PPPOES, 1626 ITEM_PPPOED, 1627 ITEM_PPPOE_PROTO_ID, 1628 ITEM_HIGIG2, 1629 ITEM_TAG, 1630 ITEM_L2TPV3OIP, 1631 ITEM_ESP, 1632 ITEM_AH, 1633 ITEM_PFCP, 1634 ITEM_ECPRI, 1635 ITEM_GENEVE_OPT, 1636 ITEM_INTEGRITY, 1637 ITEM_CONNTRACK, 1638 ITEM_PORT_REPRESENTOR, 1639 ITEM_REPRESENTED_PORT, 1640 ITEM_FLEX, 1641 ITEM_L2TPV2, 1642 ITEM_PPP, 1643 ITEM_METER, 1644 ITEM_QUOTA, 1645 ITEM_AGGR_AFFINITY, 1646 ITEM_TX_QUEUE, 1647 ITEM_IB_BTH, 1648 ITEM_PTYPE, 1649 ITEM_NSH, 1650 ITEM_COMPARE, 1651 END_SET, 1652 ZERO, 1653 }; 1654 1655 static const enum index item_fuzzy[] = { 1656 ITEM_FUZZY_THRESH, 1657 ITEM_NEXT, 1658 ZERO, 1659 }; 1660 1661 static const enum index item_any[] = { 1662 ITEM_ANY_NUM, 1663 ITEM_NEXT, 1664 ZERO, 1665 }; 1666 1667 static const enum index item_port_id[] = { 1668 ITEM_PORT_ID_ID, 1669 ITEM_NEXT, 1670 ZERO, 1671 }; 1672 1673 static const enum index item_mark[] = { 1674 ITEM_MARK_ID, 1675 ITEM_NEXT, 1676 ZERO, 1677 }; 1678 1679 static const enum index item_raw[] = { 1680 ITEM_RAW_RELATIVE, 1681 ITEM_RAW_SEARCH, 1682 ITEM_RAW_OFFSET, 1683 ITEM_RAW_LIMIT, 1684 ITEM_RAW_PATTERN, 1685 ITEM_RAW_PATTERN_HEX, 1686 ITEM_NEXT, 1687 ZERO, 1688 }; 1689 1690 static const enum index item_eth[] = { 1691 ITEM_ETH_DST, 1692 ITEM_ETH_SRC, 1693 ITEM_ETH_TYPE, 1694 ITEM_ETH_HAS_VLAN, 1695 ITEM_NEXT, 1696 ZERO, 1697 }; 1698 1699 static const enum index item_vlan[] = { 1700 ITEM_VLAN_TCI, 1701 ITEM_VLAN_PCP, 1702 ITEM_VLAN_DEI, 1703 ITEM_VLAN_VID, 1704 ITEM_VLAN_INNER_TYPE, 1705 ITEM_VLAN_HAS_MORE_VLAN, 1706 ITEM_NEXT, 1707 ZERO, 1708 }; 1709 1710 static const enum index item_ipv4[] = { 1711 ITEM_IPV4_VER_IHL, 1712 ITEM_IPV4_TOS, 1713 ITEM_IPV4_LENGTH, 1714 ITEM_IPV4_ID, 1715 ITEM_IPV4_FRAGMENT_OFFSET, 1716 ITEM_IPV4_TTL, 1717 ITEM_IPV4_PROTO, 1718 ITEM_IPV4_SRC, 1719 ITEM_IPV4_DST, 1720 ITEM_NEXT, 1721 ZERO, 1722 }; 1723 1724 static const enum index item_ipv6[] = { 1725 ITEM_IPV6_TC, 1726 ITEM_IPV6_FLOW, 1727 ITEM_IPV6_LEN, 1728 ITEM_IPV6_PROTO, 1729 ITEM_IPV6_HOP, 1730 ITEM_IPV6_SRC, 1731 ITEM_IPV6_DST, 1732 ITEM_IPV6_HAS_FRAG_EXT, 1733 ITEM_IPV6_ROUTING_EXT, 1734 ITEM_NEXT, 1735 ZERO, 1736 }; 1737 1738 static const enum index item_ipv6_routing_ext[] = { 1739 ITEM_IPV6_ROUTING_EXT_TYPE, 1740 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 1741 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 1742 ITEM_NEXT, 1743 ZERO, 1744 }; 1745 1746 static const enum index item_icmp[] = { 1747 ITEM_ICMP_TYPE, 1748 ITEM_ICMP_CODE, 1749 ITEM_ICMP_IDENT, 1750 ITEM_ICMP_SEQ, 1751 ITEM_NEXT, 1752 ZERO, 1753 }; 1754 1755 static const enum index item_udp[] = { 1756 ITEM_UDP_SRC, 1757 ITEM_UDP_DST, 1758 ITEM_NEXT, 1759 ZERO, 1760 }; 1761 1762 static const enum index item_tcp[] = { 1763 ITEM_TCP_SRC, 1764 ITEM_TCP_DST, 1765 ITEM_TCP_FLAGS, 1766 ITEM_NEXT, 1767 ZERO, 1768 }; 1769 1770 static const enum index item_sctp[] = { 1771 ITEM_SCTP_SRC, 1772 ITEM_SCTP_DST, 1773 ITEM_SCTP_TAG, 1774 ITEM_SCTP_CKSUM, 1775 ITEM_NEXT, 1776 ZERO, 1777 }; 1778 1779 static const enum index item_vxlan[] = { 1780 ITEM_VXLAN_VNI, 1781 ITEM_VXLAN_LAST_RSVD, 1782 ITEM_NEXT, 1783 ZERO, 1784 }; 1785 1786 static const enum index item_e_tag[] = { 1787 ITEM_E_TAG_GRP_ECID_B, 1788 ITEM_NEXT, 1789 ZERO, 1790 }; 1791 1792 static const enum index item_nvgre[] = { 1793 ITEM_NVGRE_TNI, 1794 ITEM_NEXT, 1795 ZERO, 1796 }; 1797 1798 static const enum index item_mpls[] = { 1799 ITEM_MPLS_LABEL, 1800 ITEM_MPLS_TC, 1801 ITEM_MPLS_S, 1802 ITEM_MPLS_TTL, 1803 ITEM_NEXT, 1804 ZERO, 1805 }; 1806 1807 static const enum index item_gre[] = { 1808 ITEM_GRE_PROTO, 1809 ITEM_GRE_C_RSVD0_VER, 1810 ITEM_GRE_C_BIT, 1811 ITEM_GRE_K_BIT, 1812 ITEM_GRE_S_BIT, 1813 ITEM_NEXT, 1814 ZERO, 1815 }; 1816 1817 static const enum index item_gre_key[] = { 1818 ITEM_GRE_KEY_VALUE, 1819 ITEM_NEXT, 1820 ZERO, 1821 }; 1822 1823 static const enum index item_gre_option[] = { 1824 ITEM_GRE_OPTION_CHECKSUM, 1825 ITEM_GRE_OPTION_KEY, 1826 ITEM_GRE_OPTION_SEQUENCE, 1827 ITEM_NEXT, 1828 ZERO, 1829 }; 1830 1831 static const enum index item_gtp[] = { 1832 ITEM_GTP_FLAGS, 1833 ITEM_GTP_MSG_TYPE, 1834 ITEM_GTP_TEID, 1835 ITEM_NEXT, 1836 ZERO, 1837 }; 1838 1839 static const enum index item_geneve[] = { 1840 ITEM_GENEVE_VNI, 1841 ITEM_GENEVE_PROTO, 1842 ITEM_GENEVE_OPTLEN, 1843 ITEM_NEXT, 1844 ZERO, 1845 }; 1846 1847 static const enum index item_vxlan_gpe[] = { 1848 ITEM_VXLAN_GPE_VNI, 1849 ITEM_VXLAN_GPE_PROTO, 1850 ITEM_VXLAN_GPE_FLAGS, 1851 ITEM_VXLAN_GPE_RSVD0, 1852 ITEM_VXLAN_GPE_RSVD1, 1853 ITEM_NEXT, 1854 ZERO, 1855 }; 1856 1857 static const enum index item_arp_eth_ipv4[] = { 1858 ITEM_ARP_ETH_IPV4_SHA, 1859 ITEM_ARP_ETH_IPV4_SPA, 1860 ITEM_ARP_ETH_IPV4_THA, 1861 ITEM_ARP_ETH_IPV4_TPA, 1862 ITEM_NEXT, 1863 ZERO, 1864 }; 1865 1866 static const enum index item_ipv6_ext[] = { 1867 ITEM_IPV6_EXT_NEXT_HDR, 1868 ITEM_NEXT, 1869 ZERO, 1870 }; 1871 1872 static const enum index item_ipv6_frag_ext[] = { 1873 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 1874 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 1875 ITEM_IPV6_FRAG_EXT_ID, 1876 ITEM_NEXT, 1877 ZERO, 1878 }; 1879 1880 static const enum index item_icmp6[] = { 1881 ITEM_ICMP6_TYPE, 1882 ITEM_ICMP6_CODE, 1883 ITEM_NEXT, 1884 ZERO, 1885 }; 1886 1887 static const enum index item_icmp6_echo_request[] = { 1888 ITEM_ICMP6_ECHO_REQUEST_ID, 1889 ITEM_ICMP6_ECHO_REQUEST_SEQ, 1890 ITEM_NEXT, 1891 ZERO, 1892 }; 1893 1894 static const enum index item_icmp6_echo_reply[] = { 1895 ITEM_ICMP6_ECHO_REPLY_ID, 1896 ITEM_ICMP6_ECHO_REPLY_SEQ, 1897 ITEM_NEXT, 1898 ZERO, 1899 }; 1900 1901 static const enum index item_icmp6_nd_ns[] = { 1902 ITEM_ICMP6_ND_NS_TARGET_ADDR, 1903 ITEM_NEXT, 1904 ZERO, 1905 }; 1906 1907 static const enum index item_icmp6_nd_na[] = { 1908 ITEM_ICMP6_ND_NA_TARGET_ADDR, 1909 ITEM_NEXT, 1910 ZERO, 1911 }; 1912 1913 static const enum index item_icmp6_nd_opt[] = { 1914 ITEM_ICMP6_ND_OPT_TYPE, 1915 ITEM_NEXT, 1916 ZERO, 1917 }; 1918 1919 static const enum index item_icmp6_nd_opt_sla_eth[] = { 1920 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 1921 ITEM_NEXT, 1922 ZERO, 1923 }; 1924 1925 static const enum index item_icmp6_nd_opt_tla_eth[] = { 1926 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 1927 ITEM_NEXT, 1928 ZERO, 1929 }; 1930 1931 static const enum index item_meta[] = { 1932 ITEM_META_DATA, 1933 ITEM_NEXT, 1934 ZERO, 1935 }; 1936 1937 static const enum index item_random[] = { 1938 ITEM_RANDOM_VALUE, 1939 ITEM_NEXT, 1940 ZERO, 1941 }; 1942 1943 static const enum index item_gtp_psc[] = { 1944 ITEM_GTP_PSC_QFI, 1945 ITEM_GTP_PSC_PDU_T, 1946 ITEM_NEXT, 1947 ZERO, 1948 }; 1949 1950 static const enum index item_pppoed[] = { 1951 ITEM_PPPOE_SEID, 1952 ITEM_NEXT, 1953 ZERO, 1954 }; 1955 1956 static const enum index item_pppoes[] = { 1957 ITEM_PPPOE_SEID, 1958 ITEM_NEXT, 1959 ZERO, 1960 }; 1961 1962 static const enum index item_pppoe_proto_id[] = { 1963 ITEM_NEXT, 1964 ZERO, 1965 }; 1966 1967 static const enum index item_higig2[] = { 1968 ITEM_HIGIG2_CLASSIFICATION, 1969 ITEM_HIGIG2_VID, 1970 ITEM_NEXT, 1971 ZERO, 1972 }; 1973 1974 static const enum index item_esp[] = { 1975 ITEM_ESP_SPI, 1976 ITEM_NEXT, 1977 ZERO, 1978 }; 1979 1980 static const enum index item_ah[] = { 1981 ITEM_AH_SPI, 1982 ITEM_NEXT, 1983 ZERO, 1984 }; 1985 1986 static const enum index item_pfcp[] = { 1987 ITEM_PFCP_S_FIELD, 1988 ITEM_PFCP_SEID, 1989 ITEM_NEXT, 1990 ZERO, 1991 }; 1992 1993 static const enum index next_set_raw[] = { 1994 SET_RAW_INDEX, 1995 ITEM_ETH, 1996 ZERO, 1997 }; 1998 1999 static const enum index item_tag[] = { 2000 ITEM_TAG_DATA, 2001 ITEM_TAG_INDEX, 2002 ITEM_NEXT, 2003 ZERO, 2004 }; 2005 2006 static const enum index item_l2tpv3oip[] = { 2007 ITEM_L2TPV3OIP_SESSION_ID, 2008 ITEM_NEXT, 2009 ZERO, 2010 }; 2011 2012 static const enum index item_ecpri[] = { 2013 ITEM_ECPRI_COMMON, 2014 ITEM_NEXT, 2015 ZERO, 2016 }; 2017 2018 static const enum index item_ecpri_common[] = { 2019 ITEM_ECPRI_COMMON_TYPE, 2020 ZERO, 2021 }; 2022 2023 static const enum index item_ecpri_common_type[] = { 2024 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 2025 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 2026 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 2027 ZERO, 2028 }; 2029 2030 static const enum index item_geneve_opt[] = { 2031 ITEM_GENEVE_OPT_CLASS, 2032 ITEM_GENEVE_OPT_TYPE, 2033 ITEM_GENEVE_OPT_LENGTH, 2034 ITEM_GENEVE_OPT_DATA, 2035 ITEM_NEXT, 2036 ZERO, 2037 }; 2038 2039 static const enum index item_integrity[] = { 2040 ITEM_INTEGRITY_LEVEL, 2041 ITEM_INTEGRITY_VALUE, 2042 ZERO, 2043 }; 2044 2045 static const enum index item_integrity_lv[] = { 2046 ITEM_INTEGRITY_LEVEL, 2047 ITEM_INTEGRITY_VALUE, 2048 ITEM_NEXT, 2049 ZERO, 2050 }; 2051 2052 static const enum index item_port_representor[] = { 2053 ITEM_PORT_REPRESENTOR_PORT_ID, 2054 ITEM_NEXT, 2055 ZERO, 2056 }; 2057 2058 static const enum index item_represented_port[] = { 2059 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 2060 ITEM_NEXT, 2061 ZERO, 2062 }; 2063 2064 static const enum index item_flex[] = { 2065 ITEM_FLEX_PATTERN_HANDLE, 2066 ITEM_FLEX_ITEM_HANDLE, 2067 ITEM_NEXT, 2068 ZERO, 2069 }; 2070 2071 static const enum index item_l2tpv2[] = { 2072 ITEM_L2TPV2_TYPE, 2073 ITEM_NEXT, 2074 ZERO, 2075 }; 2076 2077 static const enum index item_l2tpv2_type[] = { 2078 ITEM_L2TPV2_TYPE_DATA, 2079 ITEM_L2TPV2_TYPE_DATA_L, 2080 ITEM_L2TPV2_TYPE_DATA_S, 2081 ITEM_L2TPV2_TYPE_DATA_O, 2082 ITEM_L2TPV2_TYPE_DATA_L_S, 2083 ITEM_L2TPV2_TYPE_CTRL, 2084 ZERO, 2085 }; 2086 2087 static const enum index item_l2tpv2_type_data[] = { 2088 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 2089 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 2090 ITEM_NEXT, 2091 ZERO, 2092 }; 2093 2094 static const enum index item_l2tpv2_type_data_l[] = { 2095 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 2096 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 2097 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 2098 ITEM_NEXT, 2099 ZERO, 2100 }; 2101 2102 static const enum index item_l2tpv2_type_data_s[] = { 2103 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 2104 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 2105 ITEM_L2TPV2_MSG_DATA_S_NS, 2106 ITEM_L2TPV2_MSG_DATA_S_NR, 2107 ITEM_NEXT, 2108 ZERO, 2109 }; 2110 2111 static const enum index item_l2tpv2_type_data_o[] = { 2112 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 2113 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 2114 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 2115 ITEM_NEXT, 2116 ZERO, 2117 }; 2118 2119 static const enum index item_l2tpv2_type_data_l_s[] = { 2120 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 2121 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 2122 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 2123 ITEM_L2TPV2_MSG_DATA_L_S_NS, 2124 ITEM_L2TPV2_MSG_DATA_L_S_NR, 2125 ITEM_NEXT, 2126 ZERO, 2127 }; 2128 2129 static const enum index item_l2tpv2_type_ctrl[] = { 2130 ITEM_L2TPV2_MSG_CTRL_LENGTH, 2131 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 2132 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 2133 ITEM_L2TPV2_MSG_CTRL_NS, 2134 ITEM_L2TPV2_MSG_CTRL_NR, 2135 ITEM_NEXT, 2136 ZERO, 2137 }; 2138 2139 static const enum index item_ppp[] = { 2140 ITEM_PPP_ADDR, 2141 ITEM_PPP_CTRL, 2142 ITEM_PPP_PROTO_ID, 2143 ITEM_NEXT, 2144 ZERO, 2145 }; 2146 2147 static const enum index item_meter[] = { 2148 ITEM_METER_COLOR, 2149 ITEM_NEXT, 2150 ZERO, 2151 }; 2152 2153 static const enum index item_quota[] = { 2154 ITEM_QUOTA_STATE, 2155 ITEM_NEXT, 2156 ZERO, 2157 }; 2158 2159 static const enum index item_aggr_affinity[] = { 2160 ITEM_AGGR_AFFINITY_VALUE, 2161 ITEM_NEXT, 2162 ZERO, 2163 }; 2164 2165 static const enum index item_tx_queue[] = { 2166 ITEM_TX_QUEUE_VALUE, 2167 ITEM_NEXT, 2168 ZERO, 2169 }; 2170 2171 static const enum index item_ib_bth[] = { 2172 ITEM_IB_BTH_OPCODE, 2173 ITEM_IB_BTH_PKEY, 2174 ITEM_IB_BTH_DST_QPN, 2175 ITEM_IB_BTH_PSN, 2176 ITEM_NEXT, 2177 ZERO, 2178 }; 2179 2180 static const enum index item_ptype[] = { 2181 ITEM_PTYPE_VALUE, 2182 ITEM_NEXT, 2183 ZERO, 2184 }; 2185 2186 static const enum index item_nsh[] = { 2187 ITEM_NEXT, 2188 ZERO, 2189 }; 2190 2191 static const enum index item_compare_field[] = { 2192 ITEM_COMPARE_OP, 2193 ITEM_COMPARE_FIELD_A_TYPE, 2194 ITEM_COMPARE_FIELD_B_TYPE, 2195 ITEM_NEXT, 2196 ZERO, 2197 }; 2198 2199 static const enum index compare_field_a[] = { 2200 ITEM_COMPARE_FIELD_A_TYPE, 2201 ITEM_COMPARE_FIELD_A_LEVEL, 2202 ITEM_COMPARE_FIELD_A_TAG_INDEX, 2203 ITEM_COMPARE_FIELD_A_TYPE_ID, 2204 ITEM_COMPARE_FIELD_A_CLASS_ID, 2205 ITEM_COMPARE_FIELD_A_OFFSET, 2206 ITEM_COMPARE_FIELD_B_TYPE, 2207 ZERO, 2208 }; 2209 2210 static const enum index compare_field_b[] = { 2211 ITEM_COMPARE_FIELD_B_TYPE, 2212 ITEM_COMPARE_FIELD_B_LEVEL, 2213 ITEM_COMPARE_FIELD_B_TAG_INDEX, 2214 ITEM_COMPARE_FIELD_B_TYPE_ID, 2215 ITEM_COMPARE_FIELD_B_CLASS_ID, 2216 ITEM_COMPARE_FIELD_B_OFFSET, 2217 ITEM_COMPARE_FIELD_B_VALUE, 2218 ITEM_COMPARE_FIELD_B_POINTER, 2219 ITEM_COMPARE_FIELD_WIDTH, 2220 ZERO, 2221 }; 2222 2223 static const enum index next_action[] = { 2224 ACTION_END, 2225 ACTION_VOID, 2226 ACTION_PASSTHRU, 2227 ACTION_SKIP_CMAN, 2228 ACTION_JUMP, 2229 ACTION_MARK, 2230 ACTION_FLAG, 2231 ACTION_QUEUE, 2232 ACTION_DROP, 2233 ACTION_COUNT, 2234 ACTION_RSS, 2235 ACTION_PF, 2236 ACTION_VF, 2237 ACTION_PORT_ID, 2238 ACTION_METER, 2239 ACTION_METER_COLOR, 2240 ACTION_METER_MARK, 2241 ACTION_OF_DEC_NW_TTL, 2242 ACTION_OF_POP_VLAN, 2243 ACTION_OF_PUSH_VLAN, 2244 ACTION_OF_SET_VLAN_VID, 2245 ACTION_OF_SET_VLAN_PCP, 2246 ACTION_OF_POP_MPLS, 2247 ACTION_OF_PUSH_MPLS, 2248 ACTION_VXLAN_ENCAP, 2249 ACTION_VXLAN_DECAP, 2250 ACTION_NVGRE_ENCAP, 2251 ACTION_NVGRE_DECAP, 2252 ACTION_L2_ENCAP, 2253 ACTION_L2_DECAP, 2254 ACTION_MPLSOGRE_ENCAP, 2255 ACTION_MPLSOGRE_DECAP, 2256 ACTION_MPLSOUDP_ENCAP, 2257 ACTION_MPLSOUDP_DECAP, 2258 ACTION_SET_IPV4_SRC, 2259 ACTION_SET_IPV4_DST, 2260 ACTION_SET_IPV6_SRC, 2261 ACTION_SET_IPV6_DST, 2262 ACTION_SET_TP_SRC, 2263 ACTION_SET_TP_DST, 2264 ACTION_MAC_SWAP, 2265 ACTION_DEC_TTL, 2266 ACTION_SET_TTL, 2267 ACTION_SET_MAC_SRC, 2268 ACTION_SET_MAC_DST, 2269 ACTION_INC_TCP_SEQ, 2270 ACTION_DEC_TCP_SEQ, 2271 ACTION_INC_TCP_ACK, 2272 ACTION_DEC_TCP_ACK, 2273 ACTION_RAW_ENCAP, 2274 ACTION_RAW_DECAP, 2275 ACTION_SET_TAG, 2276 ACTION_SET_META, 2277 ACTION_SET_IPV4_DSCP, 2278 ACTION_SET_IPV6_DSCP, 2279 ACTION_AGE, 2280 ACTION_AGE_UPDATE, 2281 ACTION_SAMPLE, 2282 ACTION_INDIRECT, 2283 ACTION_INDIRECT_LIST, 2284 ACTION_SHARED_INDIRECT, 2285 ACTION_MODIFY_FIELD, 2286 ACTION_CONNTRACK, 2287 ACTION_CONNTRACK_UPDATE, 2288 ACTION_PORT_REPRESENTOR, 2289 ACTION_REPRESENTED_PORT, 2290 ACTION_SEND_TO_KERNEL, 2291 ACTION_QUOTA_CREATE, 2292 ACTION_QUOTA_QU, 2293 ACTION_IPV6_EXT_REMOVE, 2294 ACTION_IPV6_EXT_PUSH, 2295 ACTION_NAT64, 2296 ZERO, 2297 }; 2298 2299 static const enum index action_quota_create[] = { 2300 ACTION_QUOTA_CREATE_LIMIT, 2301 ACTION_QUOTA_CREATE_MODE, 2302 ACTION_NEXT, 2303 ZERO 2304 }; 2305 2306 static const enum index action_quota_update[] = { 2307 ACTION_QUOTA_QU_LIMIT, 2308 ACTION_QUOTA_QU_UPDATE_OP, 2309 ACTION_NEXT, 2310 ZERO 2311 }; 2312 2313 static const enum index action_mark[] = { 2314 ACTION_MARK_ID, 2315 ACTION_NEXT, 2316 ZERO, 2317 }; 2318 2319 static const enum index action_queue[] = { 2320 ACTION_QUEUE_INDEX, 2321 ACTION_NEXT, 2322 ZERO, 2323 }; 2324 2325 static const enum index action_count[] = { 2326 ACTION_COUNT_ID, 2327 ACTION_NEXT, 2328 ZERO, 2329 }; 2330 2331 static const enum index action_rss[] = { 2332 ACTION_RSS_FUNC, 2333 ACTION_RSS_LEVEL, 2334 ACTION_RSS_TYPES, 2335 ACTION_RSS_KEY, 2336 ACTION_RSS_KEY_LEN, 2337 ACTION_RSS_QUEUES, 2338 ACTION_NEXT, 2339 ZERO, 2340 }; 2341 2342 static const enum index action_vf[] = { 2343 ACTION_VF_ORIGINAL, 2344 ACTION_VF_ID, 2345 ACTION_NEXT, 2346 ZERO, 2347 }; 2348 2349 static const enum index action_port_id[] = { 2350 ACTION_PORT_ID_ORIGINAL, 2351 ACTION_PORT_ID_ID, 2352 ACTION_NEXT, 2353 ZERO, 2354 }; 2355 2356 static const enum index action_meter[] = { 2357 ACTION_METER_ID, 2358 ACTION_NEXT, 2359 ZERO, 2360 }; 2361 2362 static const enum index action_meter_color[] = { 2363 ACTION_METER_COLOR_TYPE, 2364 ACTION_NEXT, 2365 ZERO, 2366 }; 2367 2368 static const enum index action_meter_mark[] = { 2369 ACTION_METER_PROFILE, 2370 ACTION_METER_POLICY, 2371 ACTION_METER_COLOR_MODE, 2372 ACTION_METER_STATE, 2373 ACTION_NEXT, 2374 ZERO, 2375 }; 2376 2377 static const enum index action_of_push_vlan[] = { 2378 ACTION_OF_PUSH_VLAN_ETHERTYPE, 2379 ACTION_NEXT, 2380 ZERO, 2381 }; 2382 2383 static const enum index action_of_set_vlan_vid[] = { 2384 ACTION_OF_SET_VLAN_VID_VLAN_VID, 2385 ACTION_NEXT, 2386 ZERO, 2387 }; 2388 2389 static const enum index action_of_set_vlan_pcp[] = { 2390 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 2391 ACTION_NEXT, 2392 ZERO, 2393 }; 2394 2395 static const enum index action_of_pop_mpls[] = { 2396 ACTION_OF_POP_MPLS_ETHERTYPE, 2397 ACTION_NEXT, 2398 ZERO, 2399 }; 2400 2401 static const enum index action_of_push_mpls[] = { 2402 ACTION_OF_PUSH_MPLS_ETHERTYPE, 2403 ACTION_NEXT, 2404 ZERO, 2405 }; 2406 2407 static const enum index action_set_ipv4_src[] = { 2408 ACTION_SET_IPV4_SRC_IPV4_SRC, 2409 ACTION_NEXT, 2410 ZERO, 2411 }; 2412 2413 static const enum index action_set_mac_src[] = { 2414 ACTION_SET_MAC_SRC_MAC_SRC, 2415 ACTION_NEXT, 2416 ZERO, 2417 }; 2418 2419 static const enum index action_set_ipv4_dst[] = { 2420 ACTION_SET_IPV4_DST_IPV4_DST, 2421 ACTION_NEXT, 2422 ZERO, 2423 }; 2424 2425 static const enum index action_set_ipv6_src[] = { 2426 ACTION_SET_IPV6_SRC_IPV6_SRC, 2427 ACTION_NEXT, 2428 ZERO, 2429 }; 2430 2431 static const enum index action_set_ipv6_dst[] = { 2432 ACTION_SET_IPV6_DST_IPV6_DST, 2433 ACTION_NEXT, 2434 ZERO, 2435 }; 2436 2437 static const enum index action_set_tp_src[] = { 2438 ACTION_SET_TP_SRC_TP_SRC, 2439 ACTION_NEXT, 2440 ZERO, 2441 }; 2442 2443 static const enum index action_set_tp_dst[] = { 2444 ACTION_SET_TP_DST_TP_DST, 2445 ACTION_NEXT, 2446 ZERO, 2447 }; 2448 2449 static const enum index action_set_ttl[] = { 2450 ACTION_SET_TTL_TTL, 2451 ACTION_NEXT, 2452 ZERO, 2453 }; 2454 2455 static const enum index action_jump[] = { 2456 ACTION_JUMP_GROUP, 2457 ACTION_NEXT, 2458 ZERO, 2459 }; 2460 2461 static const enum index action_set_mac_dst[] = { 2462 ACTION_SET_MAC_DST_MAC_DST, 2463 ACTION_NEXT, 2464 ZERO, 2465 }; 2466 2467 static const enum index action_inc_tcp_seq[] = { 2468 ACTION_INC_TCP_SEQ_VALUE, 2469 ACTION_NEXT, 2470 ZERO, 2471 }; 2472 2473 static const enum index action_dec_tcp_seq[] = { 2474 ACTION_DEC_TCP_SEQ_VALUE, 2475 ACTION_NEXT, 2476 ZERO, 2477 }; 2478 2479 static const enum index action_inc_tcp_ack[] = { 2480 ACTION_INC_TCP_ACK_VALUE, 2481 ACTION_NEXT, 2482 ZERO, 2483 }; 2484 2485 static const enum index action_dec_tcp_ack[] = { 2486 ACTION_DEC_TCP_ACK_VALUE, 2487 ACTION_NEXT, 2488 ZERO, 2489 }; 2490 2491 static const enum index action_raw_encap[] = { 2492 ACTION_RAW_ENCAP_SIZE, 2493 ACTION_RAW_ENCAP_INDEX, 2494 ACTION_NEXT, 2495 ZERO, 2496 }; 2497 2498 static const enum index action_raw_decap[] = { 2499 ACTION_RAW_DECAP_INDEX, 2500 ACTION_NEXT, 2501 ZERO, 2502 }; 2503 2504 static const enum index action_ipv6_ext_remove[] = { 2505 ACTION_IPV6_EXT_REMOVE_INDEX, 2506 ACTION_NEXT, 2507 ZERO, 2508 }; 2509 2510 static const enum index action_ipv6_ext_push[] = { 2511 ACTION_IPV6_EXT_PUSH_INDEX, 2512 ACTION_NEXT, 2513 ZERO, 2514 }; 2515 2516 static const enum index action_set_tag[] = { 2517 ACTION_SET_TAG_DATA, 2518 ACTION_SET_TAG_INDEX, 2519 ACTION_SET_TAG_MASK, 2520 ACTION_NEXT, 2521 ZERO, 2522 }; 2523 2524 static const enum index action_set_meta[] = { 2525 ACTION_SET_META_DATA, 2526 ACTION_SET_META_MASK, 2527 ACTION_NEXT, 2528 ZERO, 2529 }; 2530 2531 static const enum index action_set_ipv4_dscp[] = { 2532 ACTION_SET_IPV4_DSCP_VALUE, 2533 ACTION_NEXT, 2534 ZERO, 2535 }; 2536 2537 static const enum index action_set_ipv6_dscp[] = { 2538 ACTION_SET_IPV6_DSCP_VALUE, 2539 ACTION_NEXT, 2540 ZERO, 2541 }; 2542 2543 static const enum index action_age[] = { 2544 ACTION_AGE, 2545 ACTION_AGE_TIMEOUT, 2546 ACTION_NEXT, 2547 ZERO, 2548 }; 2549 2550 static const enum index action_age_update[] = { 2551 ACTION_AGE_UPDATE, 2552 ACTION_AGE_UPDATE_TIMEOUT, 2553 ACTION_AGE_UPDATE_TOUCH, 2554 ACTION_NEXT, 2555 ZERO, 2556 }; 2557 2558 static const enum index action_sample[] = { 2559 ACTION_SAMPLE, 2560 ACTION_SAMPLE_RATIO, 2561 ACTION_SAMPLE_INDEX, 2562 ACTION_NEXT, 2563 ZERO, 2564 }; 2565 2566 static const enum index next_action_sample[] = { 2567 ACTION_QUEUE, 2568 ACTION_RSS, 2569 ACTION_MARK, 2570 ACTION_COUNT, 2571 ACTION_PORT_ID, 2572 ACTION_RAW_ENCAP, 2573 ACTION_VXLAN_ENCAP, 2574 ACTION_NVGRE_ENCAP, 2575 ACTION_REPRESENTED_PORT, 2576 ACTION_PORT_REPRESENTOR, 2577 ACTION_NEXT, 2578 ZERO, 2579 }; 2580 2581 static const enum index item_ipv6_push_ext[] = { 2582 ITEM_IPV6_PUSH_REMOVE_EXT, 2583 ZERO, 2584 }; 2585 2586 static const enum index item_ipv6_push_ext_type[] = { 2587 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 2588 ZERO, 2589 }; 2590 2591 static const enum index item_ipv6_push_ext_header[] = { 2592 ITEM_IPV6_ROUTING_EXT, 2593 ITEM_NEXT, 2594 ZERO, 2595 }; 2596 2597 static const enum index action_modify_field_dst[] = { 2598 ACTION_MODIFY_FIELD_DST_LEVEL, 2599 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 2600 ACTION_MODIFY_FIELD_DST_TYPE_ID, 2601 ACTION_MODIFY_FIELD_DST_CLASS_ID, 2602 ACTION_MODIFY_FIELD_DST_OFFSET, 2603 ACTION_MODIFY_FIELD_SRC_TYPE, 2604 ZERO, 2605 }; 2606 2607 static const enum index action_modify_field_src[] = { 2608 ACTION_MODIFY_FIELD_SRC_LEVEL, 2609 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 2610 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 2611 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 2612 ACTION_MODIFY_FIELD_SRC_OFFSET, 2613 ACTION_MODIFY_FIELD_SRC_VALUE, 2614 ACTION_MODIFY_FIELD_SRC_POINTER, 2615 ACTION_MODIFY_FIELD_WIDTH, 2616 ZERO, 2617 }; 2618 2619 static const enum index action_update_conntrack[] = { 2620 ACTION_CONNTRACK_UPDATE_DIR, 2621 ACTION_CONNTRACK_UPDATE_CTX, 2622 ACTION_NEXT, 2623 ZERO, 2624 }; 2625 2626 static const enum index action_port_representor[] = { 2627 ACTION_PORT_REPRESENTOR_PORT_ID, 2628 ACTION_NEXT, 2629 ZERO, 2630 }; 2631 2632 static const enum index action_represented_port[] = { 2633 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 2634 ACTION_NEXT, 2635 ZERO, 2636 }; 2637 2638 static const enum index action_nat64[] = { 2639 ACTION_NAT64_MODE, 2640 ACTION_NEXT, 2641 ZERO, 2642 }; 2643 2644 static const enum index next_hash_subcmd[] = { 2645 HASH_CALC_TABLE, 2646 HASH_CALC_ENCAP, 2647 ZERO, 2648 }; 2649 2650 static const enum index next_hash_encap_dest_subcmd[] = { 2651 ENCAP_HASH_FIELD_SRC_PORT, 2652 ENCAP_HASH_FIELD_GRE_FLOW_ID, 2653 ZERO, 2654 }; 2655 2656 static int parse_set_raw_encap_decap(struct context *, const struct token *, 2657 const char *, unsigned int, 2658 void *, unsigned int); 2659 static int parse_set_sample_action(struct context *, const struct token *, 2660 const char *, unsigned int, 2661 void *, unsigned int); 2662 static int parse_set_ipv6_ext_action(struct context *, const struct token *, 2663 const char *, unsigned int, 2664 void *, unsigned int); 2665 static int parse_set_init(struct context *, const struct token *, 2666 const char *, unsigned int, 2667 void *, unsigned int); 2668 static int 2669 parse_flex_handle(struct context *, const struct token *, 2670 const char *, unsigned int, void *, unsigned int); 2671 static int parse_init(struct context *, const struct token *, 2672 const char *, unsigned int, 2673 void *, unsigned int); 2674 static int parse_vc(struct context *, const struct token *, 2675 const char *, unsigned int, 2676 void *, unsigned int); 2677 static int parse_vc_spec(struct context *, const struct token *, 2678 const char *, unsigned int, void *, unsigned int); 2679 static int parse_vc_conf(struct context *, const struct token *, 2680 const char *, unsigned int, void *, unsigned int); 2681 static int parse_vc_conf_timeout(struct context *, const struct token *, 2682 const char *, unsigned int, void *, 2683 unsigned int); 2684 static int parse_vc_item_ecpri_type(struct context *, const struct token *, 2685 const char *, unsigned int, 2686 void *, unsigned int); 2687 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, 2688 const char *, unsigned int, 2689 void *, unsigned int); 2690 static int parse_vc_action_meter_color_type(struct context *, 2691 const struct token *, 2692 const char *, unsigned int, void *, 2693 unsigned int); 2694 static int parse_vc_action_rss(struct context *, const struct token *, 2695 const char *, unsigned int, void *, 2696 unsigned int); 2697 static int parse_vc_action_rss_func(struct context *, const struct token *, 2698 const char *, unsigned int, void *, 2699 unsigned int); 2700 static int parse_vc_action_rss_type(struct context *, const struct token *, 2701 const char *, unsigned int, void *, 2702 unsigned int); 2703 static int parse_vc_action_rss_queue(struct context *, const struct token *, 2704 const char *, unsigned int, void *, 2705 unsigned int); 2706 static int parse_vc_action_vxlan_encap(struct context *, const struct token *, 2707 const char *, unsigned int, void *, 2708 unsigned int); 2709 static int parse_vc_action_nvgre_encap(struct context *, const struct token *, 2710 const char *, unsigned int, void *, 2711 unsigned int); 2712 static int parse_vc_action_l2_encap(struct context *, const struct token *, 2713 const char *, unsigned int, void *, 2714 unsigned int); 2715 static int parse_vc_action_l2_decap(struct context *, const struct token *, 2716 const char *, unsigned int, void *, 2717 unsigned int); 2718 static int parse_vc_action_mplsogre_encap(struct context *, 2719 const struct token *, const char *, 2720 unsigned int, void *, unsigned int); 2721 static int parse_vc_action_mplsogre_decap(struct context *, 2722 const struct token *, const char *, 2723 unsigned int, void *, unsigned int); 2724 static int parse_vc_action_mplsoudp_encap(struct context *, 2725 const struct token *, const char *, 2726 unsigned int, void *, unsigned int); 2727 static int parse_vc_action_mplsoudp_decap(struct context *, 2728 const struct token *, const char *, 2729 unsigned int, void *, unsigned int); 2730 static int parse_vc_action_raw_encap(struct context *, 2731 const struct token *, const char *, 2732 unsigned int, void *, unsigned int); 2733 static int parse_vc_action_raw_decap(struct context *, 2734 const struct token *, const char *, 2735 unsigned int, void *, unsigned int); 2736 static int parse_vc_action_raw_encap_index(struct context *, 2737 const struct token *, const char *, 2738 unsigned int, void *, unsigned int); 2739 static int parse_vc_action_raw_decap_index(struct context *, 2740 const struct token *, const char *, 2741 unsigned int, void *, unsigned int); 2742 static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 2743 const char *str, unsigned int len, void *buf, 2744 unsigned int size); 2745 static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, 2746 const struct token *token, 2747 const char *str, unsigned int len, 2748 void *buf, 2749 unsigned int size); 2750 static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 2751 const char *str, unsigned int len, void *buf, 2752 unsigned int size); 2753 static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, 2754 const struct token *token, 2755 const char *str, unsigned int len, 2756 void *buf, 2757 unsigned int size); 2758 static int parse_vc_action_set_meta(struct context *ctx, 2759 const struct token *token, const char *str, 2760 unsigned int len, void *buf, 2761 unsigned int size); 2762 static int parse_vc_action_sample(struct context *ctx, 2763 const struct token *token, const char *str, 2764 unsigned int len, void *buf, 2765 unsigned int size); 2766 static int 2767 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 2768 const char *str, unsigned int len, void *buf, 2769 unsigned int size); 2770 static int 2771 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 2772 const char *str, unsigned int len, void *buf, 2773 unsigned int size); 2774 static int 2775 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 2776 const char *str, unsigned int len, void *buf, 2777 unsigned int size); 2778 static int 2779 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 2780 const char *str, unsigned int len, void *buf, 2781 unsigned int size); 2782 static int 2783 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 2784 const char *str, unsigned int len, void *buf, 2785 unsigned int size); 2786 static int parse_destroy(struct context *, const struct token *, 2787 const char *, unsigned int, 2788 void *, unsigned int); 2789 static int parse_flush(struct context *, const struct token *, 2790 const char *, unsigned int, 2791 void *, unsigned int); 2792 static int parse_dump(struct context *, const struct token *, 2793 const char *, unsigned int, 2794 void *, unsigned int); 2795 static int parse_query(struct context *, const struct token *, 2796 const char *, unsigned int, 2797 void *, unsigned int); 2798 static int parse_action(struct context *, const struct token *, 2799 const char *, unsigned int, 2800 void *, unsigned int); 2801 static int parse_list(struct context *, const struct token *, 2802 const char *, unsigned int, 2803 void *, unsigned int); 2804 static int parse_aged(struct context *, const struct token *, 2805 const char *, unsigned int, 2806 void *, unsigned int); 2807 static int parse_isolate(struct context *, const struct token *, 2808 const char *, unsigned int, 2809 void *, unsigned int); 2810 static int parse_configure(struct context *, const struct token *, 2811 const char *, unsigned int, 2812 void *, unsigned int); 2813 static int parse_template(struct context *, const struct token *, 2814 const char *, unsigned int, 2815 void *, unsigned int); 2816 static int parse_template_destroy(struct context *, const struct token *, 2817 const char *, unsigned int, 2818 void *, unsigned int); 2819 static int parse_table(struct context *, const struct token *, 2820 const char *, unsigned int, void *, unsigned int); 2821 static int parse_table_destroy(struct context *, const struct token *, 2822 const char *, unsigned int, 2823 void *, unsigned int); 2824 static int parse_qo(struct context *, const struct token *, 2825 const char *, unsigned int, 2826 void *, unsigned int); 2827 static int parse_qo_destroy(struct context *, const struct token *, 2828 const char *, unsigned int, 2829 void *, unsigned int); 2830 static int parse_qia(struct context *, const struct token *, 2831 const char *, unsigned int, 2832 void *, unsigned int); 2833 static int parse_qia_destroy(struct context *, const struct token *, 2834 const char *, unsigned int, 2835 void *, unsigned int); 2836 static int parse_push(struct context *, const struct token *, 2837 const char *, unsigned int, 2838 void *, unsigned int); 2839 static int parse_pull(struct context *, const struct token *, 2840 const char *, unsigned int, 2841 void *, unsigned int); 2842 static int parse_group(struct context *, const struct token *, 2843 const char *, unsigned int, 2844 void *, unsigned int); 2845 static int parse_hash(struct context *, const struct token *, 2846 const char *, unsigned int, 2847 void *, unsigned int); 2848 static int parse_tunnel(struct context *, const struct token *, 2849 const char *, unsigned int, 2850 void *, unsigned int); 2851 static int parse_flex(struct context *, const struct token *, 2852 const char *, unsigned int, void *, unsigned int); 2853 static int parse_int(struct context *, const struct token *, 2854 const char *, unsigned int, 2855 void *, unsigned int); 2856 static int parse_prefix(struct context *, const struct token *, 2857 const char *, unsigned int, 2858 void *, unsigned int); 2859 static int parse_boolean(struct context *, const struct token *, 2860 const char *, unsigned int, 2861 void *, unsigned int); 2862 static int parse_string(struct context *, const struct token *, 2863 const char *, unsigned int, 2864 void *, unsigned int); 2865 static int parse_hex(struct context *ctx, const struct token *token, 2866 const char *str, unsigned int len, 2867 void *buf, unsigned int size); 2868 static int parse_string0(struct context *, const struct token *, 2869 const char *, unsigned int, 2870 void *, unsigned int); 2871 static int parse_mac_addr(struct context *, const struct token *, 2872 const char *, unsigned int, 2873 void *, unsigned int); 2874 static int parse_ipv4_addr(struct context *, const struct token *, 2875 const char *, unsigned int, 2876 void *, unsigned int); 2877 static int parse_ipv6_addr(struct context *, const struct token *, 2878 const char *, unsigned int, 2879 void *, unsigned int); 2880 static int parse_port(struct context *, const struct token *, 2881 const char *, unsigned int, 2882 void *, unsigned int); 2883 static int parse_ia(struct context *, const struct token *, 2884 const char *, unsigned int, 2885 void *, unsigned int); 2886 static int parse_ia_destroy(struct context *ctx, const struct token *token, 2887 const char *str, unsigned int len, 2888 void *buf, unsigned int size); 2889 static int parse_ia_id2ptr(struct context *ctx, const struct token *token, 2890 const char *str, unsigned int len, void *buf, 2891 unsigned int size); 2892 2893 static int parse_indlst_id2ptr(struct context *ctx, const struct token *token, 2894 const char *str, unsigned int len, void *buf, 2895 unsigned int size); 2896 static int parse_ia_port(struct context *ctx, const struct token *token, 2897 const char *str, unsigned int len, void *buf, 2898 unsigned int size); 2899 static int parse_mp(struct context *, const struct token *, 2900 const char *, unsigned int, 2901 void *, unsigned int); 2902 static int parse_meter_profile_id2ptr(struct context *ctx, 2903 const struct token *token, 2904 const char *str, unsigned int len, 2905 void *buf, unsigned int size); 2906 static int parse_meter_policy_id2ptr(struct context *ctx, 2907 const struct token *token, 2908 const char *str, unsigned int len, 2909 void *buf, unsigned int size); 2910 static int parse_meter_color(struct context *ctx, const struct token *token, 2911 const char *str, unsigned int len, void *buf, 2912 unsigned int size); 2913 static int parse_insertion_table_type(struct context *ctx, const struct token *token, 2914 const char *str, unsigned int len, void *buf, 2915 unsigned int size); 2916 static int parse_hash_table_type(struct context *ctx, const struct token *token, 2917 const char *str, unsigned int len, void *buf, 2918 unsigned int size); 2919 static int 2920 parse_quota_state_name(struct context *ctx, const struct token *token, 2921 const char *str, unsigned int len, void *buf, 2922 unsigned int size); 2923 static int 2924 parse_quota_mode_name(struct context *ctx, const struct token *token, 2925 const char *str, unsigned int len, void *buf, 2926 unsigned int size); 2927 static int 2928 parse_quota_update_name(struct context *ctx, const struct token *token, 2929 const char *str, unsigned int len, void *buf, 2930 unsigned int size); 2931 static int 2932 parse_qu_mode_name(struct context *ctx, const struct token *token, 2933 const char *str, unsigned int len, void *buf, 2934 unsigned int size); 2935 static int comp_none(struct context *, const struct token *, 2936 unsigned int, char *, unsigned int); 2937 static int comp_boolean(struct context *, const struct token *, 2938 unsigned int, char *, unsigned int); 2939 static int comp_action(struct context *, const struct token *, 2940 unsigned int, char *, unsigned int); 2941 static int comp_port(struct context *, const struct token *, 2942 unsigned int, char *, unsigned int); 2943 static int comp_rule_id(struct context *, const struct token *, 2944 unsigned int, char *, unsigned int); 2945 static int comp_vc_action_rss_type(struct context *, const struct token *, 2946 unsigned int, char *, unsigned int); 2947 static int comp_vc_action_rss_queue(struct context *, const struct token *, 2948 unsigned int, char *, unsigned int); 2949 static int comp_set_raw_index(struct context *, const struct token *, 2950 unsigned int, char *, unsigned int); 2951 static int comp_set_sample_index(struct context *, const struct token *, 2952 unsigned int, char *, unsigned int); 2953 static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 2954 unsigned int ent, char *buf, unsigned int size); 2955 static int comp_set_modify_field_op(struct context *, const struct token *, 2956 unsigned int, char *, unsigned int); 2957 static int comp_set_modify_field_id(struct context *, const struct token *, 2958 unsigned int, char *, unsigned int); 2959 static int comp_pattern_template_id(struct context *, const struct token *, 2960 unsigned int, char *, unsigned int); 2961 static int comp_actions_template_id(struct context *, const struct token *, 2962 unsigned int, char *, unsigned int); 2963 static int comp_table_id(struct context *, const struct token *, 2964 unsigned int, char *, unsigned int); 2965 static int comp_queue_id(struct context *, const struct token *, 2966 unsigned int, char *, unsigned int); 2967 static int comp_meter_color(struct context *, const struct token *, 2968 unsigned int, char *, unsigned int); 2969 static int comp_insertion_table_type(struct context *, const struct token *, 2970 unsigned int, char *, unsigned int); 2971 static int comp_hash_table_type(struct context *, const struct token *, 2972 unsigned int, char *, unsigned int); 2973 static int 2974 comp_quota_state_name(struct context *ctx, const struct token *token, 2975 unsigned int ent, char *buf, unsigned int size); 2976 static int 2977 comp_quota_mode_name(struct context *ctx, const struct token *token, 2978 unsigned int ent, char *buf, unsigned int size); 2979 static int 2980 comp_quota_update_name(struct context *ctx, const struct token *token, 2981 unsigned int ent, char *buf, unsigned int size); 2982 static int 2983 comp_qu_mode_name(struct context *ctx, const struct token *token, 2984 unsigned int ent, char *buf, unsigned int size); 2985 static int 2986 comp_set_compare_field_id(struct context *ctx, const struct token *token, 2987 unsigned int ent, char *buf, unsigned int size); 2988 static int 2989 comp_set_compare_op(struct context *ctx, const struct token *token, 2990 unsigned int ent, char *buf, unsigned int size); 2991 static int 2992 parse_vc_compare_op(struct context *ctx, const struct token *token, 2993 const char *str, unsigned int len, void *buf, 2994 unsigned int size); 2995 static int 2996 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 2997 const char *str, unsigned int len, void *buf, 2998 unsigned int size); 2999 static int 3000 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 3001 const char *str, unsigned int len, void *buf, 3002 unsigned int size); 3003 3004 struct indlst_conf { 3005 uint32_t id; 3006 uint32_t conf_num; 3007 struct rte_flow_action *actions; 3008 const void **conf; 3009 SLIST_ENTRY(indlst_conf) next; 3010 }; 3011 3012 static const struct indlst_conf *indirect_action_list_conf_get(uint32_t conf_id); 3013 3014 /** Token definitions. */ 3015 static const struct token token_list[] = { 3016 /* Special tokens. */ 3017 [ZERO] = { 3018 .name = "ZERO", 3019 .help = "null entry, abused as the entry point", 3020 .next = NEXT(NEXT_ENTRY(FLOW, ADD)), 3021 }, 3022 [END] = { 3023 .name = "", 3024 .type = "RETURN", 3025 .help = "command may end here", 3026 }, 3027 [START_SET] = { 3028 .name = "START_SET", 3029 .help = "null entry, abused as the entry point for set", 3030 .next = NEXT(NEXT_ENTRY(SET)), 3031 }, 3032 [END_SET] = { 3033 .name = "end_set", 3034 .type = "RETURN", 3035 .help = "set command may end here", 3036 }, 3037 /* Common tokens. */ 3038 [COMMON_INTEGER] = { 3039 .name = "{int}", 3040 .type = "INTEGER", 3041 .help = "integer value", 3042 .call = parse_int, 3043 .comp = comp_none, 3044 }, 3045 [COMMON_UNSIGNED] = { 3046 .name = "{unsigned}", 3047 .type = "UNSIGNED", 3048 .help = "unsigned integer value", 3049 .call = parse_int, 3050 .comp = comp_none, 3051 }, 3052 [COMMON_PREFIX] = { 3053 .name = "{prefix}", 3054 .type = "PREFIX", 3055 .help = "prefix length for bit-mask", 3056 .call = parse_prefix, 3057 .comp = comp_none, 3058 }, 3059 [COMMON_BOOLEAN] = { 3060 .name = "{boolean}", 3061 .type = "BOOLEAN", 3062 .help = "any boolean value", 3063 .call = parse_boolean, 3064 .comp = comp_boolean, 3065 }, 3066 [COMMON_STRING] = { 3067 .name = "{string}", 3068 .type = "STRING", 3069 .help = "fixed string", 3070 .call = parse_string, 3071 .comp = comp_none, 3072 }, 3073 [COMMON_HEX] = { 3074 .name = "{hex}", 3075 .type = "HEX", 3076 .help = "fixed string", 3077 .call = parse_hex, 3078 }, 3079 [COMMON_FILE_PATH] = { 3080 .name = "{file path}", 3081 .type = "STRING", 3082 .help = "file path", 3083 .call = parse_string0, 3084 .comp = comp_none, 3085 }, 3086 [COMMON_MAC_ADDR] = { 3087 .name = "{MAC address}", 3088 .type = "MAC-48", 3089 .help = "standard MAC address notation", 3090 .call = parse_mac_addr, 3091 .comp = comp_none, 3092 }, 3093 [COMMON_IPV4_ADDR] = { 3094 .name = "{IPv4 address}", 3095 .type = "IPV4 ADDRESS", 3096 .help = "standard IPv4 address notation", 3097 .call = parse_ipv4_addr, 3098 .comp = comp_none, 3099 }, 3100 [COMMON_IPV6_ADDR] = { 3101 .name = "{IPv6 address}", 3102 .type = "IPV6 ADDRESS", 3103 .help = "standard IPv6 address notation", 3104 .call = parse_ipv6_addr, 3105 .comp = comp_none, 3106 }, 3107 [COMMON_RULE_ID] = { 3108 .name = "{rule id}", 3109 .type = "RULE ID", 3110 .help = "rule identifier", 3111 .call = parse_int, 3112 .comp = comp_rule_id, 3113 }, 3114 [COMMON_PORT_ID] = { 3115 .name = "{port_id}", 3116 .type = "PORT ID", 3117 .help = "port identifier", 3118 .call = parse_port, 3119 .comp = comp_port, 3120 }, 3121 [COMMON_GROUP_ID] = { 3122 .name = "{group_id}", 3123 .type = "GROUP ID", 3124 .help = "group identifier", 3125 .call = parse_int, 3126 .comp = comp_none, 3127 }, 3128 [COMMON_PRIORITY_LEVEL] = { 3129 .name = "{level}", 3130 .type = "PRIORITY", 3131 .help = "priority level", 3132 .call = parse_int, 3133 .comp = comp_none, 3134 }, 3135 [COMMON_INDIRECT_ACTION_ID] = { 3136 .name = "{indirect_action_id}", 3137 .type = "INDIRECT_ACTION_ID", 3138 .help = "indirect action id", 3139 .call = parse_int, 3140 .comp = comp_none, 3141 }, 3142 [COMMON_PROFILE_ID] = { 3143 .name = "{profile_id}", 3144 .type = "PROFILE_ID", 3145 .help = "profile id", 3146 .call = parse_int, 3147 .comp = comp_none, 3148 }, 3149 [COMMON_POLICY_ID] = { 3150 .name = "{policy_id}", 3151 .type = "POLICY_ID", 3152 .help = "policy id", 3153 .call = parse_int, 3154 .comp = comp_none, 3155 }, 3156 [COMMON_FLEX_TOKEN] = { 3157 .name = "{flex token}", 3158 .type = "flex token", 3159 .help = "flex token", 3160 .call = parse_int, 3161 .comp = comp_none, 3162 }, 3163 [COMMON_FLEX_HANDLE] = { 3164 .name = "{flex handle}", 3165 .type = "FLEX HANDLE", 3166 .help = "fill flex item data", 3167 .call = parse_flex_handle, 3168 .comp = comp_none, 3169 }, 3170 [COMMON_PATTERN_TEMPLATE_ID] = { 3171 .name = "{pattern_template_id}", 3172 .type = "PATTERN_TEMPLATE_ID", 3173 .help = "pattern template id", 3174 .call = parse_int, 3175 .comp = comp_pattern_template_id, 3176 }, 3177 [COMMON_ACTIONS_TEMPLATE_ID] = { 3178 .name = "{actions_template_id}", 3179 .type = "ACTIONS_TEMPLATE_ID", 3180 .help = "actions template id", 3181 .call = parse_int, 3182 .comp = comp_actions_template_id, 3183 }, 3184 [COMMON_TABLE_ID] = { 3185 .name = "{table_id}", 3186 .type = "TABLE_ID", 3187 .help = "table id", 3188 .call = parse_int, 3189 .comp = comp_table_id, 3190 }, 3191 [COMMON_QUEUE_ID] = { 3192 .name = "{queue_id}", 3193 .type = "QUEUE_ID", 3194 .help = "queue id", 3195 .call = parse_int, 3196 .comp = comp_queue_id, 3197 }, 3198 /* Top-level command. */ 3199 [FLOW] = { 3200 .name = "flow", 3201 .type = "{command} {port_id} [{arg} [...]]", 3202 .help = "manage ingress/egress flow rules", 3203 .next = NEXT(NEXT_ENTRY 3204 (INFO, 3205 CONFIGURE, 3206 PATTERN_TEMPLATE, 3207 ACTIONS_TEMPLATE, 3208 TABLE, 3209 FLOW_GROUP, 3210 INDIRECT_ACTION, 3211 VALIDATE, 3212 CREATE, 3213 DESTROY, 3214 UPDATE, 3215 FLUSH, 3216 DUMP, 3217 LIST, 3218 AGED, 3219 QUERY, 3220 ISOLATE, 3221 TUNNEL, 3222 FLEX, 3223 QUEUE, 3224 PUSH, 3225 PULL, 3226 HASH)), 3227 .call = parse_init, 3228 }, 3229 /* Top-level command. */ 3230 [INFO] = { 3231 .name = "info", 3232 .help = "get information about flow engine", 3233 .next = NEXT(NEXT_ENTRY(END), 3234 NEXT_ENTRY(COMMON_PORT_ID)), 3235 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3236 .call = parse_configure, 3237 }, 3238 /* Top-level command. */ 3239 [CONFIGURE] = { 3240 .name = "configure", 3241 .help = "configure flow engine", 3242 .next = NEXT(next_config_attr, 3243 NEXT_ENTRY(COMMON_PORT_ID)), 3244 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3245 .call = parse_configure, 3246 }, 3247 /* Configure arguments. */ 3248 [CONFIG_QUEUES_NUMBER] = { 3249 .name = "queues_number", 3250 .help = "number of queues", 3251 .next = NEXT(next_config_attr, 3252 NEXT_ENTRY(COMMON_UNSIGNED)), 3253 .args = ARGS(ARGS_ENTRY(struct buffer, 3254 args.configure.nb_queue)), 3255 }, 3256 [CONFIG_QUEUES_SIZE] = { 3257 .name = "queues_size", 3258 .help = "number of elements in queues", 3259 .next = NEXT(next_config_attr, 3260 NEXT_ENTRY(COMMON_UNSIGNED)), 3261 .args = ARGS(ARGS_ENTRY(struct buffer, 3262 args.configure.queue_attr.size)), 3263 }, 3264 [CONFIG_COUNTERS_NUMBER] = { 3265 .name = "counters_number", 3266 .help = "number of counters", 3267 .next = NEXT(next_config_attr, 3268 NEXT_ENTRY(COMMON_UNSIGNED)), 3269 .args = ARGS(ARGS_ENTRY(struct buffer, 3270 args.configure.port_attr.nb_counters)), 3271 }, 3272 [CONFIG_AGING_OBJECTS_NUMBER] = { 3273 .name = "aging_counters_number", 3274 .help = "number of aging objects", 3275 .next = NEXT(next_config_attr, 3276 NEXT_ENTRY(COMMON_UNSIGNED)), 3277 .args = ARGS(ARGS_ENTRY(struct buffer, 3278 args.configure.port_attr.nb_aging_objects)), 3279 }, 3280 [CONFIG_QUOTAS_NUMBER] = { 3281 .name = "quotas_number", 3282 .help = "number of quotas", 3283 .next = NEXT(next_config_attr, 3284 NEXT_ENTRY(COMMON_UNSIGNED)), 3285 .args = ARGS(ARGS_ENTRY(struct buffer, 3286 args.configure.port_attr.nb_quotas)), 3287 }, 3288 [CONFIG_METERS_NUMBER] = { 3289 .name = "meters_number", 3290 .help = "number of meters", 3291 .next = NEXT(next_config_attr, 3292 NEXT_ENTRY(COMMON_UNSIGNED)), 3293 .args = ARGS(ARGS_ENTRY(struct buffer, 3294 args.configure.port_attr.nb_meters)), 3295 }, 3296 [CONFIG_CONN_TRACK_NUMBER] = { 3297 .name = "conn_tracks_number", 3298 .help = "number of connection trackings", 3299 .next = NEXT(next_config_attr, 3300 NEXT_ENTRY(COMMON_UNSIGNED)), 3301 .args = ARGS(ARGS_ENTRY(struct buffer, 3302 args.configure.port_attr.nb_conn_tracks)), 3303 }, 3304 [CONFIG_FLAGS] = { 3305 .name = "flags", 3306 .help = "configuration flags", 3307 .next = NEXT(next_config_attr, 3308 NEXT_ENTRY(COMMON_UNSIGNED)), 3309 .args = ARGS(ARGS_ENTRY(struct buffer, 3310 args.configure.port_attr.flags)), 3311 }, 3312 [CONFIG_HOST_PORT] = { 3313 .name = "host_port", 3314 .help = "host port for shared objects", 3315 .next = NEXT(next_config_attr, 3316 NEXT_ENTRY(COMMON_UNSIGNED)), 3317 .args = ARGS(ARGS_ENTRY(struct buffer, 3318 args.configure.port_attr.host_port_id)), 3319 }, 3320 /* Top-level command. */ 3321 [PATTERN_TEMPLATE] = { 3322 .name = "pattern_template", 3323 .type = "{command} {port_id} [{arg} [...]]", 3324 .help = "manage pattern templates", 3325 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3326 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3327 .call = parse_template, 3328 }, 3329 /* Sub-level commands. */ 3330 [PATTERN_TEMPLATE_CREATE] = { 3331 .name = "create", 3332 .help = "create pattern template", 3333 .next = NEXT(next_pt_attr), 3334 .call = parse_template, 3335 }, 3336 [PATTERN_TEMPLATE_DESTROY] = { 3337 .name = "destroy", 3338 .help = "destroy pattern template", 3339 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), 3340 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3341 .call = parse_template_destroy, 3342 }, 3343 /* Pattern template arguments. */ 3344 [PATTERN_TEMPLATE_CREATE_ID] = { 3345 .name = "pattern_template_id", 3346 .help = "specify a pattern template id to create", 3347 .next = NEXT(next_pt_attr, 3348 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3349 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), 3350 }, 3351 [PATTERN_TEMPLATE_DESTROY_ID] = { 3352 .name = "pattern_template", 3353 .help = "specify a pattern template id to destroy", 3354 .next = NEXT(next_pt_destroy_attr, 3355 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3356 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3357 args.templ_destroy.template_id)), 3358 .call = parse_template_destroy, 3359 }, 3360 [PATTERN_TEMPLATE_RELAXED_MATCHING] = { 3361 .name = "relaxed", 3362 .help = "is matching relaxed", 3363 .next = NEXT(next_pt_attr, 3364 NEXT_ENTRY(COMMON_BOOLEAN)), 3365 .args = ARGS(ARGS_ENTRY_BF(struct buffer, 3366 args.vc.attr.reserved, 1)), 3367 }, 3368 [PATTERN_TEMPLATE_INGRESS] = { 3369 .name = "ingress", 3370 .help = "attribute pattern to ingress", 3371 .next = NEXT(next_pt_attr), 3372 .call = parse_template, 3373 }, 3374 [PATTERN_TEMPLATE_EGRESS] = { 3375 .name = "egress", 3376 .help = "attribute pattern to egress", 3377 .next = NEXT(next_pt_attr), 3378 .call = parse_template, 3379 }, 3380 [PATTERN_TEMPLATE_TRANSFER] = { 3381 .name = "transfer", 3382 .help = "attribute pattern to transfer", 3383 .next = NEXT(next_pt_attr), 3384 .call = parse_template, 3385 }, 3386 [PATTERN_TEMPLATE_SPEC] = { 3387 .name = "template", 3388 .help = "specify item to create pattern template", 3389 .next = NEXT(next_item), 3390 }, 3391 /* Top-level command. */ 3392 [ACTIONS_TEMPLATE] = { 3393 .name = "actions_template", 3394 .type = "{command} {port_id} [{arg} [...]]", 3395 .help = "manage actions templates", 3396 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3397 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3398 .call = parse_template, 3399 }, 3400 /* Sub-level commands. */ 3401 [ACTIONS_TEMPLATE_CREATE] = { 3402 .name = "create", 3403 .help = "create actions template", 3404 .next = NEXT(next_at_attr), 3405 .call = parse_template, 3406 }, 3407 [ACTIONS_TEMPLATE_DESTROY] = { 3408 .name = "destroy", 3409 .help = "destroy actions template", 3410 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), 3411 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3412 .call = parse_template_destroy, 3413 }, 3414 /* Actions template arguments. */ 3415 [ACTIONS_TEMPLATE_CREATE_ID] = { 3416 .name = "actions_template_id", 3417 .help = "specify an actions template id to create", 3418 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), 3419 NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), 3420 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3421 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), 3422 }, 3423 [ACTIONS_TEMPLATE_DESTROY_ID] = { 3424 .name = "actions_template", 3425 .help = "specify an actions template id to destroy", 3426 .next = NEXT(next_at_destroy_attr, 3427 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3428 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3429 args.templ_destroy.template_id)), 3430 .call = parse_template_destroy, 3431 }, 3432 [ACTIONS_TEMPLATE_INGRESS] = { 3433 .name = "ingress", 3434 .help = "attribute actions to ingress", 3435 .next = NEXT(next_at_attr), 3436 .call = parse_template, 3437 }, 3438 [ACTIONS_TEMPLATE_EGRESS] = { 3439 .name = "egress", 3440 .help = "attribute actions to egress", 3441 .next = NEXT(next_at_attr), 3442 .call = parse_template, 3443 }, 3444 [ACTIONS_TEMPLATE_TRANSFER] = { 3445 .name = "transfer", 3446 .help = "attribute actions to transfer", 3447 .next = NEXT(next_at_attr), 3448 .call = parse_template, 3449 }, 3450 [ACTIONS_TEMPLATE_SPEC] = { 3451 .name = "template", 3452 .help = "specify action to create actions template", 3453 .next = NEXT(next_action), 3454 .call = parse_template, 3455 }, 3456 [ACTIONS_TEMPLATE_MASK] = { 3457 .name = "mask", 3458 .help = "specify action mask to create actions template", 3459 .next = NEXT(next_action), 3460 .call = parse_template, 3461 }, 3462 /* Top-level command. */ 3463 [TABLE] = { 3464 .name = "template_table", 3465 .type = "{command} {port_id} [{arg} [...]]", 3466 .help = "manage template tables", 3467 .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3468 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3469 .call = parse_table, 3470 }, 3471 /* Sub-level commands. */ 3472 [TABLE_CREATE] = { 3473 .name = "create", 3474 .help = "create template table", 3475 .next = NEXT(next_table_attr), 3476 .call = parse_table, 3477 }, 3478 [TABLE_DESTROY] = { 3479 .name = "destroy", 3480 .help = "destroy template table", 3481 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3482 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3483 .call = parse_table_destroy, 3484 }, 3485 [TABLE_RESIZE] = { 3486 .name = "resize", 3487 .help = "resize template table", 3488 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_ID)), 3489 .call = parse_table 3490 }, 3491 [TABLE_RESIZE_COMPLETE] = { 3492 .name = "resize_complete", 3493 .help = "complete table resize", 3494 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3495 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3496 .call = parse_table_destroy, 3497 }, 3498 /* Table arguments. */ 3499 [TABLE_CREATE_ID] = { 3500 .name = "table_id", 3501 .help = "specify table id to create", 3502 .next = NEXT(next_table_attr, 3503 NEXT_ENTRY(COMMON_TABLE_ID)), 3504 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3505 }, 3506 [TABLE_DESTROY_ID] = { 3507 .name = "table", 3508 .help = "table id", 3509 .next = NEXT(next_table_destroy_attr, 3510 NEXT_ENTRY(COMMON_TABLE_ID)), 3511 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3512 args.table_destroy.table_id)), 3513 .call = parse_table_destroy, 3514 }, 3515 [TABLE_RESIZE_ID] = { 3516 .name = "table_resize_id", 3517 .help = "table resize id", 3518 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_RULES_NUMBER), 3519 NEXT_ENTRY(COMMON_TABLE_ID)), 3520 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3521 .call = parse_table 3522 }, 3523 [TABLE_RESIZE_RULES_NUMBER] = { 3524 .name = "table_resize_rules_num", 3525 .help = "table resize rules number", 3526 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_UNSIGNED)), 3527 .args = ARGS(ARGS_ENTRY(struct buffer, 3528 args.table.attr.nb_flows)), 3529 .call = parse_table 3530 }, 3531 [TABLE_INSERTION_TYPE] = { 3532 .name = "insertion_type", 3533 .help = "specify insertion type", 3534 .next = NEXT(next_table_attr, 3535 NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)), 3536 .args = ARGS(ARGS_ENTRY(struct buffer, 3537 args.table.attr.insertion_type)), 3538 }, 3539 [TABLE_INSERTION_TYPE_NAME] = { 3540 .name = "insertion_type_name", 3541 .help = "insertion type name", 3542 .call = parse_insertion_table_type, 3543 .comp = comp_insertion_table_type, 3544 }, 3545 [TABLE_HASH_FUNC] = { 3546 .name = "hash_func", 3547 .help = "specify hash calculation function", 3548 .next = NEXT(next_table_attr, 3549 NEXT_ENTRY(TABLE_HASH_FUNC_NAME)), 3550 .args = ARGS(ARGS_ENTRY(struct buffer, 3551 args.table.attr.hash_func)), 3552 }, 3553 [TABLE_HASH_FUNC_NAME] = { 3554 .name = "hash_func_name", 3555 .help = "hash calculation function name", 3556 .call = parse_hash_table_type, 3557 .comp = comp_hash_table_type, 3558 }, 3559 [TABLE_GROUP] = { 3560 .name = "group", 3561 .help = "specify a group", 3562 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3563 .args = ARGS(ARGS_ENTRY(struct buffer, 3564 args.table.attr.flow_attr.group)), 3565 }, 3566 [TABLE_PRIORITY] = { 3567 .name = "priority", 3568 .help = "specify a priority level", 3569 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 3570 .args = ARGS(ARGS_ENTRY(struct buffer, 3571 args.table.attr.flow_attr.priority)), 3572 }, 3573 [TABLE_EGRESS] = { 3574 .name = "egress", 3575 .help = "affect rule to egress", 3576 .next = NEXT(next_table_attr), 3577 .call = parse_table, 3578 }, 3579 [TABLE_INGRESS] = { 3580 .name = "ingress", 3581 .help = "affect rule to ingress", 3582 .next = NEXT(next_table_attr), 3583 .call = parse_table, 3584 }, 3585 [TABLE_TRANSFER] = { 3586 .name = "transfer", 3587 .help = "affect rule to transfer", 3588 .next = NEXT(next_table_attr), 3589 .call = parse_table, 3590 }, 3591 [TABLE_TRANSFER_WIRE_ORIG] = { 3592 .name = "wire_orig", 3593 .help = "affect rule direction to transfer", 3594 .next = NEXT(next_table_attr), 3595 .call = parse_table, 3596 }, 3597 [TABLE_TRANSFER_VPORT_ORIG] = { 3598 .name = "vport_orig", 3599 .help = "affect rule direction to transfer", 3600 .next = NEXT(next_table_attr), 3601 .call = parse_table, 3602 }, 3603 [TABLE_RESIZABLE] = { 3604 .name = "resizable", 3605 .help = "set resizable attribute", 3606 .next = NEXT(next_table_attr), 3607 .call = parse_table, 3608 }, 3609 [TABLE_RULES_NUMBER] = { 3610 .name = "rules_number", 3611 .help = "number of rules in table", 3612 .next = NEXT(next_table_attr, 3613 NEXT_ENTRY(COMMON_UNSIGNED)), 3614 .args = ARGS(ARGS_ENTRY(struct buffer, 3615 args.table.attr.nb_flows)), 3616 .call = parse_table, 3617 }, 3618 [TABLE_PATTERN_TEMPLATE] = { 3619 .name = "pattern_template", 3620 .help = "specify pattern template id", 3621 .next = NEXT(next_table_attr, 3622 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3623 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3624 args.table.pat_templ_id)), 3625 .call = parse_table, 3626 }, 3627 [TABLE_ACTIONS_TEMPLATE] = { 3628 .name = "actions_template", 3629 .help = "specify actions template id", 3630 .next = NEXT(next_table_attr, 3631 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3632 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3633 args.table.act_templ_id)), 3634 .call = parse_table, 3635 }, 3636 /* Top-level command. */ 3637 [FLOW_GROUP] = { 3638 .name = "group", 3639 .help = "manage flow groups", 3640 .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), 3641 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3642 .call = parse_group, 3643 }, 3644 /* Sub-level commands. */ 3645 [GROUP_SET_MISS_ACTIONS] = { 3646 .name = "set_miss_actions", 3647 .help = "set group miss actions", 3648 .next = NEXT(next_action), 3649 .call = parse_group, 3650 }, 3651 /* Group arguments */ 3652 [GROUP_ID] = { 3653 .name = "group_id", 3654 .help = "group id", 3655 .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3656 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3657 }, 3658 [GROUP_INGRESS] = { 3659 .name = "ingress", 3660 .help = "group ingress attr", 3661 .next = NEXT(next_group_attr), 3662 .call = parse_group, 3663 }, 3664 [GROUP_EGRESS] = { 3665 .name = "egress", 3666 .help = "group egress attr", 3667 .next = NEXT(next_group_attr), 3668 .call = parse_group, 3669 }, 3670 [GROUP_TRANSFER] = { 3671 .name = "transfer", 3672 .help = "group transfer attr", 3673 .next = NEXT(next_group_attr), 3674 .call = parse_group, 3675 }, 3676 /* Top-level command. */ 3677 [QUEUE] = { 3678 .name = "queue", 3679 .help = "queue a flow rule operation", 3680 .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3681 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3682 .call = parse_qo, 3683 }, 3684 /* Sub-level commands. */ 3685 [QUEUE_CREATE] = { 3686 .name = "create", 3687 .help = "create a flow rule", 3688 .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), 3689 NEXT_ENTRY(COMMON_QUEUE_ID)), 3690 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3691 .call = parse_qo, 3692 }, 3693 [QUEUE_DESTROY] = { 3694 .name = "destroy", 3695 .help = "destroy a flow rule", 3696 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3697 NEXT_ENTRY(COMMON_QUEUE_ID)), 3698 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3699 .call = parse_qo_destroy, 3700 }, 3701 [QUEUE_FLOW_UPDATE_RESIZED] = { 3702 .name = "update_resized", 3703 .help = "update a flow after table resize", 3704 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3705 NEXT_ENTRY(COMMON_QUEUE_ID)), 3706 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3707 .call = parse_qo_destroy, 3708 }, 3709 [QUEUE_UPDATE] = { 3710 .name = "update", 3711 .help = "update a flow rule", 3712 .next = NEXT(NEXT_ENTRY(QUEUE_UPDATE_ID), 3713 NEXT_ENTRY(COMMON_QUEUE_ID)), 3714 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3715 .call = parse_qo, 3716 }, 3717 [QUEUE_AGED] = { 3718 .name = "aged", 3719 .help = "list and destroy aged flows", 3720 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), 3721 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3722 .call = parse_aged, 3723 }, 3724 [QUEUE_INDIRECT_ACTION] = { 3725 .name = "indirect_action", 3726 .help = "queue indirect actions", 3727 .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), 3728 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3729 .call = parse_qia, 3730 }, 3731 /* Queue arguments. */ 3732 [QUEUE_TEMPLATE_TABLE] = { 3733 .name = "template_table", 3734 .help = "specify table id", 3735 .next = NEXT(next_async_insert_subcmd, 3736 NEXT_ENTRY(COMMON_TABLE_ID)), 3737 .args = ARGS(ARGS_ENTRY(struct buffer, 3738 args.vc.table_id)), 3739 .call = parse_qo, 3740 }, 3741 [QUEUE_PATTERN_TEMPLATE] = { 3742 .name = "pattern_template", 3743 .help = "specify pattern template index", 3744 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3745 NEXT_ENTRY(COMMON_UNSIGNED)), 3746 .args = ARGS(ARGS_ENTRY(struct buffer, 3747 args.vc.pat_templ_id)), 3748 .call = parse_qo, 3749 }, 3750 [QUEUE_ACTIONS_TEMPLATE] = { 3751 .name = "actions_template", 3752 .help = "specify actions template index", 3753 .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), 3754 NEXT_ENTRY(COMMON_UNSIGNED)), 3755 .args = ARGS(ARGS_ENTRY(struct buffer, 3756 args.vc.act_templ_id)), 3757 .call = parse_qo, 3758 }, 3759 [QUEUE_RULE_ID] = { 3760 .name = "rule_index", 3761 .help = "specify flow rule index", 3762 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3763 NEXT_ENTRY(COMMON_UNSIGNED)), 3764 .args = ARGS(ARGS_ENTRY(struct buffer, 3765 args.vc.rule_id)), 3766 .call = parse_qo, 3767 }, 3768 [QUEUE_CREATE_POSTPONE] = { 3769 .name = "postpone", 3770 .help = "postpone create operation", 3771 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3772 NEXT_ENTRY(COMMON_BOOLEAN)), 3773 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3774 .call = parse_qo, 3775 }, 3776 [QUEUE_DESTROY_POSTPONE] = { 3777 .name = "postpone", 3778 .help = "postpone destroy operation", 3779 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3780 NEXT_ENTRY(COMMON_BOOLEAN)), 3781 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3782 .call = parse_qo_destroy, 3783 }, 3784 [QUEUE_DESTROY_ID] = { 3785 .name = "rule", 3786 .help = "specify rule id to destroy", 3787 .next = NEXT(next_queue_destroy_attr, 3788 NEXT_ENTRY(COMMON_UNSIGNED)), 3789 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3790 args.destroy.rule)), 3791 .call = parse_qo_destroy, 3792 }, 3793 [QUEUE_UPDATE_ID] = { 3794 .name = "rule", 3795 .help = "specify rule id to update", 3796 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3797 NEXT_ENTRY(COMMON_UNSIGNED)), 3798 .args = ARGS(ARGS_ENTRY(struct buffer, 3799 args.vc.rule_id)), 3800 .call = parse_qo, 3801 }, 3802 /* Queue indirect action arguments */ 3803 [QUEUE_INDIRECT_ACTION_CREATE] = { 3804 .name = "create", 3805 .help = "create indirect action", 3806 .next = NEXT(next_qia_create_attr), 3807 .call = parse_qia, 3808 }, 3809 [QUEUE_INDIRECT_ACTION_UPDATE] = { 3810 .name = "update", 3811 .help = "update indirect action", 3812 .next = NEXT(next_qia_update_attr, 3813 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3814 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3815 .call = parse_qia, 3816 }, 3817 [QUEUE_INDIRECT_ACTION_DESTROY] = { 3818 .name = "destroy", 3819 .help = "destroy indirect action", 3820 .next = NEXT(next_qia_destroy_attr), 3821 .call = parse_qia_destroy, 3822 }, 3823 [QUEUE_INDIRECT_ACTION_QUERY] = { 3824 .name = "query", 3825 .help = "query indirect action", 3826 .next = NEXT(next_qia_query_attr, 3827 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3828 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3829 .call = parse_qia, 3830 }, 3831 /* Indirect action destroy arguments. */ 3832 [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { 3833 .name = "postpone", 3834 .help = "postpone destroy operation", 3835 .next = NEXT(next_qia_destroy_attr, 3836 NEXT_ENTRY(COMMON_BOOLEAN)), 3837 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3838 }, 3839 [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { 3840 .name = "action_id", 3841 .help = "specify a indirect action id to destroy", 3842 .next = NEXT(next_qia_destroy_attr, 3843 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3844 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3845 args.ia_destroy.action_id)), 3846 .call = parse_qia_destroy, 3847 }, 3848 [QUEUE_INDIRECT_ACTION_QUERY_UPDATE] = { 3849 .name = "query_update", 3850 .help = "indirect query [and|or] update action", 3851 .next = NEXT(next_qia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3852 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3853 .call = parse_qia 3854 }, 3855 [QUEUE_INDIRECT_ACTION_QU_MODE] = { 3856 .name = "mode", 3857 .help = "indirect query [and|or] update action", 3858 .next = NEXT(next_qia_qu_attr, 3859 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 3860 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 3861 .call = parse_qia 3862 }, 3863 /* Indirect action update arguments. */ 3864 [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { 3865 .name = "postpone", 3866 .help = "postpone update operation", 3867 .next = NEXT(next_qia_update_attr, 3868 NEXT_ENTRY(COMMON_BOOLEAN)), 3869 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3870 }, 3871 /* Indirect action update arguments. */ 3872 [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { 3873 .name = "postpone", 3874 .help = "postpone query operation", 3875 .next = NEXT(next_qia_query_attr, 3876 NEXT_ENTRY(COMMON_BOOLEAN)), 3877 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3878 }, 3879 /* Indirect action create arguments. */ 3880 [QUEUE_INDIRECT_ACTION_CREATE_ID] = { 3881 .name = "action_id", 3882 .help = "specify a indirect action id to create", 3883 .next = NEXT(next_qia_create_attr, 3884 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3885 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3886 }, 3887 [QUEUE_INDIRECT_ACTION_INGRESS] = { 3888 .name = "ingress", 3889 .help = "affect rule to ingress", 3890 .next = NEXT(next_qia_create_attr), 3891 .call = parse_qia, 3892 }, 3893 [QUEUE_INDIRECT_ACTION_EGRESS] = { 3894 .name = "egress", 3895 .help = "affect rule to egress", 3896 .next = NEXT(next_qia_create_attr), 3897 .call = parse_qia, 3898 }, 3899 [QUEUE_INDIRECT_ACTION_TRANSFER] = { 3900 .name = "transfer", 3901 .help = "affect rule to transfer", 3902 .next = NEXT(next_qia_create_attr), 3903 .call = parse_qia, 3904 }, 3905 [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { 3906 .name = "postpone", 3907 .help = "postpone create operation", 3908 .next = NEXT(next_qia_create_attr, 3909 NEXT_ENTRY(COMMON_BOOLEAN)), 3910 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3911 }, 3912 [QUEUE_INDIRECT_ACTION_SPEC] = { 3913 .name = "action", 3914 .help = "specify action to create indirect handle", 3915 .next = NEXT(next_action), 3916 }, 3917 [QUEUE_INDIRECT_ACTION_LIST] = { 3918 .name = "list", 3919 .help = "specify actions for indirect handle list", 3920 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 3921 .call = parse_qia, 3922 }, 3923 /* Top-level command. */ 3924 [PUSH] = { 3925 .name = "push", 3926 .help = "push enqueued operations", 3927 .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3928 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3929 .call = parse_push, 3930 }, 3931 /* Sub-level commands. */ 3932 [PUSH_QUEUE] = { 3933 .name = "queue", 3934 .help = "specify queue id", 3935 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3936 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3937 }, 3938 /* Top-level command. */ 3939 [PULL] = { 3940 .name = "pull", 3941 .help = "pull flow operations results", 3942 .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3943 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3944 .call = parse_pull, 3945 }, 3946 /* Sub-level commands. */ 3947 [PULL_QUEUE] = { 3948 .name = "queue", 3949 .help = "specify queue id", 3950 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3951 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3952 }, 3953 /* Top-level command. */ 3954 [HASH] = { 3955 .name = "hash", 3956 .help = "calculate hash for a given pattern in a given template table", 3957 .next = NEXT(next_hash_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3958 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3959 .call = parse_hash, 3960 }, 3961 /* Sub-level commands. */ 3962 [HASH_CALC_TABLE] = { 3963 .name = "template_table", 3964 .help = "specify table id", 3965 .next = NEXT(NEXT_ENTRY(HASH_CALC_PATTERN_INDEX), 3966 NEXT_ENTRY(COMMON_TABLE_ID)), 3967 .args = ARGS(ARGS_ENTRY(struct buffer, 3968 args.vc.table_id)), 3969 .call = parse_hash, 3970 }, 3971 [HASH_CALC_ENCAP] = { 3972 .name = "encap", 3973 .help = "calculates encap hash", 3974 .next = NEXT(next_hash_encap_dest_subcmd), 3975 .call = parse_hash, 3976 }, 3977 [HASH_CALC_PATTERN_INDEX] = { 3978 .name = "pattern_template", 3979 .help = "specify pattern template id", 3980 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3981 NEXT_ENTRY(COMMON_UNSIGNED)), 3982 .args = ARGS(ARGS_ENTRY(struct buffer, 3983 args.vc.pat_templ_id)), 3984 .call = parse_hash, 3985 }, 3986 [ENCAP_HASH_FIELD_SRC_PORT] = { 3987 .name = "hash_field_sport", 3988 .help = "the encap hash field is src port", 3989 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 3990 .call = parse_hash, 3991 }, 3992 [ENCAP_HASH_FIELD_GRE_FLOW_ID] = { 3993 .name = "hash_field_flow_id", 3994 .help = "the encap hash field is NVGRE flow id", 3995 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 3996 .call = parse_hash, 3997 }, 3998 /* Top-level command. */ 3999 [INDIRECT_ACTION] = { 4000 .name = "indirect_action", 4001 .type = "{command} {port_id} [{arg} [...]]", 4002 .help = "manage indirect actions", 4003 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4004 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4005 .call = parse_ia, 4006 }, 4007 /* Sub-level commands. */ 4008 [INDIRECT_ACTION_CREATE] = { 4009 .name = "create", 4010 .help = "create indirect action", 4011 .next = NEXT(next_ia_create_attr), 4012 .call = parse_ia, 4013 }, 4014 [INDIRECT_ACTION_UPDATE] = { 4015 .name = "update", 4016 .help = "update indirect action", 4017 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), 4018 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4019 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 4020 .call = parse_ia, 4021 }, 4022 [INDIRECT_ACTION_DESTROY] = { 4023 .name = "destroy", 4024 .help = "destroy indirect action", 4025 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), 4026 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4027 .call = parse_ia_destroy, 4028 }, 4029 [INDIRECT_ACTION_QUERY] = { 4030 .name = "query", 4031 .help = "query indirect action", 4032 .next = NEXT(NEXT_ENTRY(END), 4033 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4034 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4035 .call = parse_ia, 4036 }, 4037 [INDIRECT_ACTION_QUERY_UPDATE] = { 4038 .name = "query_update", 4039 .help = "query [and|or] update", 4040 .next = NEXT(next_ia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4041 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4042 .call = parse_ia 4043 }, 4044 [INDIRECT_ACTION_QU_MODE] = { 4045 .name = "mode", 4046 .help = "query_update mode", 4047 .next = NEXT(next_ia_qu_attr, 4048 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 4049 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 4050 .call = parse_ia, 4051 }, 4052 [INDIRECT_ACTION_QU_MODE_NAME] = { 4053 .name = "mode_name", 4054 .help = "query-update mode name", 4055 .call = parse_qu_mode_name, 4056 .comp = comp_qu_mode_name, 4057 }, 4058 [VALIDATE] = { 4059 .name = "validate", 4060 .help = "check whether a flow rule can be created", 4061 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4062 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4063 .call = parse_vc, 4064 }, 4065 [CREATE] = { 4066 .name = "create", 4067 .help = "create a flow rule", 4068 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4069 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4070 .call = parse_vc, 4071 }, 4072 [DESTROY] = { 4073 .name = "destroy", 4074 .help = "destroy specific flow rules", 4075 .next = NEXT(next_destroy_attr, 4076 NEXT_ENTRY(COMMON_PORT_ID)), 4077 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4078 .call = parse_destroy, 4079 }, 4080 [UPDATE] = { 4081 .name = "update", 4082 .help = "update a flow rule with new actions", 4083 .next = NEXT(NEXT_ENTRY(VC_IS_USER_ID, END), 4084 NEXT_ENTRY(ACTIONS), 4085 NEXT_ENTRY(COMMON_RULE_ID), 4086 NEXT_ENTRY(COMMON_PORT_ID)), 4087 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.rule_id), 4088 ARGS_ENTRY(struct buffer, port)), 4089 .call = parse_vc, 4090 }, 4091 [FLUSH] = { 4092 .name = "flush", 4093 .help = "destroy all flow rules", 4094 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4095 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4096 .call = parse_flush, 4097 }, 4098 [DUMP] = { 4099 .name = "dump", 4100 .help = "dump single/all flow rules to file", 4101 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4102 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4103 .call = parse_dump, 4104 }, 4105 [QUERY] = { 4106 .name = "query", 4107 .help = "query an existing flow rule", 4108 .next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION), 4109 NEXT_ENTRY(COMMON_RULE_ID), 4110 NEXT_ENTRY(COMMON_PORT_ID)), 4111 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), 4112 ARGS_ENTRY(struct buffer, args.query.rule), 4113 ARGS_ENTRY(struct buffer, port)), 4114 .call = parse_query, 4115 }, 4116 [LIST] = { 4117 .name = "list", 4118 .help = "list existing flow rules", 4119 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4120 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4121 .call = parse_list, 4122 }, 4123 [AGED] = { 4124 .name = "aged", 4125 .help = "list and destroy aged flows", 4126 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4127 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4128 .call = parse_aged, 4129 }, 4130 [ISOLATE] = { 4131 .name = "isolate", 4132 .help = "restrict ingress traffic to the defined flow rules", 4133 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), 4134 NEXT_ENTRY(COMMON_PORT_ID)), 4135 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), 4136 ARGS_ENTRY(struct buffer, port)), 4137 .call = parse_isolate, 4138 }, 4139 [FLEX] = { 4140 .name = "flex_item", 4141 .help = "flex item API", 4142 .next = NEXT(next_flex_item), 4143 .call = parse_flex, 4144 }, 4145 [FLEX_ITEM_INIT] = { 4146 .name = "init", 4147 .help = "flex item init", 4148 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4149 ARGS_ENTRY(struct buffer, port)), 4150 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4151 NEXT_ENTRY(COMMON_PORT_ID)), 4152 .call = parse_flex 4153 }, 4154 [FLEX_ITEM_CREATE] = { 4155 .name = "create", 4156 .help = "flex item create", 4157 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), 4158 ARGS_ENTRY(struct buffer, args.flex.token), 4159 ARGS_ENTRY(struct buffer, port)), 4160 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), 4161 NEXT_ENTRY(COMMON_FLEX_TOKEN), 4162 NEXT_ENTRY(COMMON_PORT_ID)), 4163 .call = parse_flex 4164 }, 4165 [FLEX_ITEM_DESTROY] = { 4166 .name = "destroy", 4167 .help = "flex item destroy", 4168 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4169 ARGS_ENTRY(struct buffer, port)), 4170 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4171 NEXT_ENTRY(COMMON_PORT_ID)), 4172 .call = parse_flex 4173 }, 4174 [TUNNEL] = { 4175 .name = "tunnel", 4176 .help = "new tunnel API", 4177 .next = NEXT(NEXT_ENTRY 4178 (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), 4179 .call = parse_tunnel, 4180 }, 4181 /* Tunnel arguments. */ 4182 [TUNNEL_CREATE] = { 4183 .name = "create", 4184 .help = "create new tunnel object", 4185 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), 4186 NEXT_ENTRY(COMMON_PORT_ID)), 4187 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4188 .call = parse_tunnel, 4189 }, 4190 [TUNNEL_CREATE_TYPE] = { 4191 .name = "type", 4192 .help = "create new tunnel", 4193 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), 4194 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), 4195 .call = parse_tunnel, 4196 }, 4197 [TUNNEL_DESTROY] = { 4198 .name = "destroy", 4199 .help = "destroy tunnel", 4200 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), 4201 NEXT_ENTRY(COMMON_PORT_ID)), 4202 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4203 .call = parse_tunnel, 4204 }, 4205 [TUNNEL_DESTROY_ID] = { 4206 .name = "id", 4207 .help = "tunnel identifier to destroy", 4208 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), 4209 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4210 .call = parse_tunnel, 4211 }, 4212 [TUNNEL_LIST] = { 4213 .name = "list", 4214 .help = "list existing tunnels", 4215 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4216 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4217 .call = parse_tunnel, 4218 }, 4219 /* Destroy arguments. */ 4220 [DESTROY_RULE] = { 4221 .name = "rule", 4222 .help = "specify a rule identifier", 4223 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4224 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), 4225 .call = parse_destroy, 4226 }, 4227 [DESTROY_IS_USER_ID] = { 4228 .name = "user_id", 4229 .help = "rule identifier is user-id", 4230 .next = NEXT(next_destroy_attr), 4231 .call = parse_destroy, 4232 }, 4233 /* Dump arguments. */ 4234 [DUMP_ALL] = { 4235 .name = "all", 4236 .help = "dump all", 4237 .next = NEXT(next_dump_attr), 4238 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), 4239 .call = parse_dump, 4240 }, 4241 [DUMP_ONE] = { 4242 .name = "rule", 4243 .help = "dump one rule", 4244 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4245 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), 4246 ARGS_ENTRY(struct buffer, args.dump.rule)), 4247 .call = parse_dump, 4248 }, 4249 [DUMP_IS_USER_ID] = { 4250 .name = "user_id", 4251 .help = "rule identifier is user-id", 4252 .next = NEXT(next_dump_subcmd), 4253 .call = parse_dump, 4254 }, 4255 /* Query arguments. */ 4256 [QUERY_ACTION] = { 4257 .name = "{action}", 4258 .type = "ACTION", 4259 .help = "action to query, must be part of the rule", 4260 .call = parse_action, 4261 .comp = comp_action, 4262 }, 4263 [QUERY_IS_USER_ID] = { 4264 .name = "user_id", 4265 .help = "rule identifier is user-id", 4266 .next = NEXT(next_query_attr), 4267 .call = parse_query, 4268 }, 4269 /* List arguments. */ 4270 [LIST_GROUP] = { 4271 .name = "group", 4272 .help = "specify a group", 4273 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4274 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), 4275 .call = parse_list, 4276 }, 4277 [AGED_DESTROY] = { 4278 .name = "destroy", 4279 .help = "specify aged flows need be destroyed", 4280 .call = parse_aged, 4281 .comp = comp_none, 4282 }, 4283 /* Validate/create attributes. */ 4284 [VC_GROUP] = { 4285 .name = "group", 4286 .help = "specify a group", 4287 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4288 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), 4289 .call = parse_vc, 4290 }, 4291 [VC_PRIORITY] = { 4292 .name = "priority", 4293 .help = "specify a priority level", 4294 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 4295 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), 4296 .call = parse_vc, 4297 }, 4298 [VC_INGRESS] = { 4299 .name = "ingress", 4300 .help = "affect rule to ingress", 4301 .next = NEXT(next_vc_attr), 4302 .call = parse_vc, 4303 }, 4304 [VC_EGRESS] = { 4305 .name = "egress", 4306 .help = "affect rule to egress", 4307 .next = NEXT(next_vc_attr), 4308 .call = parse_vc, 4309 }, 4310 [VC_TRANSFER] = { 4311 .name = "transfer", 4312 .help = "apply rule directly to endpoints found in pattern", 4313 .next = NEXT(next_vc_attr), 4314 .call = parse_vc, 4315 }, 4316 [VC_TUNNEL_SET] = { 4317 .name = "tunnel_set", 4318 .help = "tunnel steer rule", 4319 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4320 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4321 .call = parse_vc, 4322 }, 4323 [VC_TUNNEL_MATCH] = { 4324 .name = "tunnel_match", 4325 .help = "tunnel match rule", 4326 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4327 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4328 .call = parse_vc, 4329 }, 4330 [VC_USER_ID] = { 4331 .name = "user_id", 4332 .help = "specify a user id to create", 4333 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4334 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)), 4335 .call = parse_vc, 4336 }, 4337 [VC_IS_USER_ID] = { 4338 .name = "user_id", 4339 .help = "rule identifier is user-id", 4340 .call = parse_vc, 4341 }, 4342 /* Validate/create pattern. */ 4343 [ITEM_PATTERN] = { 4344 .name = "pattern", 4345 .help = "submit a list of pattern items", 4346 .next = NEXT(next_item), 4347 .call = parse_vc, 4348 }, 4349 [ITEM_PARAM_IS] = { 4350 .name = "is", 4351 .help = "match value perfectly (with full bit-mask)", 4352 .call = parse_vc_spec, 4353 }, 4354 [ITEM_PARAM_SPEC] = { 4355 .name = "spec", 4356 .help = "match value according to configured bit-mask", 4357 .call = parse_vc_spec, 4358 }, 4359 [ITEM_PARAM_LAST] = { 4360 .name = "last", 4361 .help = "specify upper bound to establish a range", 4362 .call = parse_vc_spec, 4363 }, 4364 [ITEM_PARAM_MASK] = { 4365 .name = "mask", 4366 .help = "specify bit-mask with relevant bits set to one", 4367 .call = parse_vc_spec, 4368 }, 4369 [ITEM_PARAM_PREFIX] = { 4370 .name = "prefix", 4371 .help = "generate bit-mask from a prefix length", 4372 .call = parse_vc_spec, 4373 }, 4374 [ITEM_NEXT] = { 4375 .name = "/", 4376 .help = "specify next pattern item", 4377 .next = NEXT(next_item), 4378 }, 4379 [ITEM_END] = { 4380 .name = "end", 4381 .help = "end list of pattern items", 4382 .priv = PRIV_ITEM(END, 0), 4383 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 4384 .call = parse_vc, 4385 }, 4386 [ITEM_VOID] = { 4387 .name = "void", 4388 .help = "no-op pattern item", 4389 .priv = PRIV_ITEM(VOID, 0), 4390 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4391 .call = parse_vc, 4392 }, 4393 [ITEM_INVERT] = { 4394 .name = "invert", 4395 .help = "perform actions when pattern does not match", 4396 .priv = PRIV_ITEM(INVERT, 0), 4397 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4398 .call = parse_vc, 4399 }, 4400 [ITEM_ANY] = { 4401 .name = "any", 4402 .help = "match any protocol for the current layer", 4403 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), 4404 .next = NEXT(item_any), 4405 .call = parse_vc, 4406 }, 4407 [ITEM_ANY_NUM] = { 4408 .name = "num", 4409 .help = "number of layers covered", 4410 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4411 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), 4412 }, 4413 [ITEM_PORT_ID] = { 4414 .name = "port_id", 4415 .help = "match traffic from/to a given DPDK port ID", 4416 .priv = PRIV_ITEM(PORT_ID, 4417 sizeof(struct rte_flow_item_port_id)), 4418 .next = NEXT(item_port_id), 4419 .call = parse_vc, 4420 }, 4421 [ITEM_PORT_ID_ID] = { 4422 .name = "id", 4423 .help = "DPDK port ID", 4424 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), 4425 item_param), 4426 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), 4427 }, 4428 [ITEM_MARK] = { 4429 .name = "mark", 4430 .help = "match traffic against value set in previously matched rule", 4431 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), 4432 .next = NEXT(item_mark), 4433 .call = parse_vc, 4434 }, 4435 [ITEM_MARK_ID] = { 4436 .name = "id", 4437 .help = "Integer value to match against", 4438 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), 4439 item_param), 4440 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), 4441 }, 4442 [ITEM_RAW] = { 4443 .name = "raw", 4444 .help = "match an arbitrary byte string", 4445 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), 4446 .next = NEXT(item_raw), 4447 .call = parse_vc, 4448 }, 4449 [ITEM_RAW_RELATIVE] = { 4450 .name = "relative", 4451 .help = "look for pattern after the previous item", 4452 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4453 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4454 relative, 1)), 4455 }, 4456 [ITEM_RAW_SEARCH] = { 4457 .name = "search", 4458 .help = "search pattern from offset (see also limit)", 4459 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4460 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4461 search, 1)), 4462 }, 4463 [ITEM_RAW_OFFSET] = { 4464 .name = "offset", 4465 .help = "absolute or relative offset for pattern", 4466 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), 4467 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), 4468 }, 4469 [ITEM_RAW_LIMIT] = { 4470 .name = "limit", 4471 .help = "search area limit for start of pattern", 4472 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4473 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), 4474 }, 4475 [ITEM_RAW_PATTERN] = { 4476 .name = "pattern", 4477 .help = "byte string to look for", 4478 .next = NEXT(item_raw, 4479 NEXT_ENTRY(COMMON_STRING), 4480 NEXT_ENTRY(ITEM_PARAM_IS, 4481 ITEM_PARAM_SPEC, 4482 ITEM_PARAM_MASK)), 4483 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4484 ARGS_ENTRY(struct rte_flow_item_raw, length), 4485 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4486 ITEM_RAW_PATTERN_SIZE)), 4487 }, 4488 [ITEM_RAW_PATTERN_HEX] = { 4489 .name = "pattern_hex", 4490 .help = "hex string to look for", 4491 .next = NEXT(item_raw, 4492 NEXT_ENTRY(COMMON_HEX), 4493 NEXT_ENTRY(ITEM_PARAM_IS, 4494 ITEM_PARAM_SPEC, 4495 ITEM_PARAM_MASK)), 4496 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4497 ARGS_ENTRY(struct rte_flow_item_raw, length), 4498 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4499 ITEM_RAW_PATTERN_SIZE)), 4500 }, 4501 [ITEM_ETH] = { 4502 .name = "eth", 4503 .help = "match Ethernet header", 4504 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), 4505 .next = NEXT(item_eth), 4506 .call = parse_vc, 4507 }, 4508 [ITEM_ETH_DST] = { 4509 .name = "dst", 4510 .help = "destination MAC", 4511 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4512 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), 4513 }, 4514 [ITEM_ETH_SRC] = { 4515 .name = "src", 4516 .help = "source MAC", 4517 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4518 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), 4519 }, 4520 [ITEM_ETH_TYPE] = { 4521 .name = "type", 4522 .help = "EtherType", 4523 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4524 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), 4525 }, 4526 [ITEM_ETH_HAS_VLAN] = { 4527 .name = "has_vlan", 4528 .help = "packet header contains VLAN", 4529 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4530 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, 4531 has_vlan, 1)), 4532 }, 4533 [ITEM_VLAN] = { 4534 .name = "vlan", 4535 .help = "match 802.1Q/ad VLAN tag", 4536 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), 4537 .next = NEXT(item_vlan), 4538 .call = parse_vc, 4539 }, 4540 [ITEM_VLAN_TCI] = { 4541 .name = "tci", 4542 .help = "tag control information", 4543 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4544 item_param), 4545 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, hdr.vlan_tci)), 4546 }, 4547 [ITEM_VLAN_PCP] = { 4548 .name = "pcp", 4549 .help = "priority code point", 4550 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4551 item_param), 4552 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4553 hdr.vlan_tci, "\xe0\x00")), 4554 }, 4555 [ITEM_VLAN_DEI] = { 4556 .name = "dei", 4557 .help = "drop eligible indicator", 4558 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4559 item_param), 4560 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4561 hdr.vlan_tci, "\x10\x00")), 4562 }, 4563 [ITEM_VLAN_VID] = { 4564 .name = "vid", 4565 .help = "VLAN identifier", 4566 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4567 item_param), 4568 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4569 hdr.vlan_tci, "\x0f\xff")), 4570 }, 4571 [ITEM_VLAN_INNER_TYPE] = { 4572 .name = "inner_type", 4573 .help = "inner EtherType", 4574 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4575 item_param), 4576 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, 4577 hdr.eth_proto)), 4578 }, 4579 [ITEM_VLAN_HAS_MORE_VLAN] = { 4580 .name = "has_more_vlan", 4581 .help = "packet header contains another VLAN", 4582 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4583 item_param), 4584 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, 4585 has_more_vlan, 1)), 4586 }, 4587 [ITEM_IPV4] = { 4588 .name = "ipv4", 4589 .help = "match IPv4 header", 4590 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), 4591 .next = NEXT(item_ipv4), 4592 .call = parse_vc, 4593 }, 4594 [ITEM_IPV4_VER_IHL] = { 4595 .name = "version_ihl", 4596 .help = "match header length", 4597 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4598 item_param), 4599 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, 4600 hdr.version_ihl)), 4601 }, 4602 [ITEM_IPV4_TOS] = { 4603 .name = "tos", 4604 .help = "type of service", 4605 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4606 item_param), 4607 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4608 hdr.type_of_service)), 4609 }, 4610 [ITEM_IPV4_LENGTH] = { 4611 .name = "length", 4612 .help = "total length", 4613 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4614 item_param), 4615 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4616 hdr.total_length)), 4617 }, 4618 [ITEM_IPV4_ID] = { 4619 .name = "packet_id", 4620 .help = "fragment packet id", 4621 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4622 item_param), 4623 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4624 hdr.packet_id)), 4625 }, 4626 [ITEM_IPV4_FRAGMENT_OFFSET] = { 4627 .name = "fragment_offset", 4628 .help = "fragmentation flags and fragment offset", 4629 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4630 item_param), 4631 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4632 hdr.fragment_offset)), 4633 }, 4634 [ITEM_IPV4_TTL] = { 4635 .name = "ttl", 4636 .help = "time to live", 4637 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4638 item_param), 4639 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4640 hdr.time_to_live)), 4641 }, 4642 [ITEM_IPV4_PROTO] = { 4643 .name = "proto", 4644 .help = "next protocol ID", 4645 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4646 item_param), 4647 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4648 hdr.next_proto_id)), 4649 }, 4650 [ITEM_IPV4_SRC] = { 4651 .name = "src", 4652 .help = "source address", 4653 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4654 item_param), 4655 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4656 hdr.src_addr)), 4657 }, 4658 [ITEM_IPV4_DST] = { 4659 .name = "dst", 4660 .help = "destination address", 4661 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4662 item_param), 4663 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4664 hdr.dst_addr)), 4665 }, 4666 [ITEM_IPV6] = { 4667 .name = "ipv6", 4668 .help = "match IPv6 header", 4669 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), 4670 .next = NEXT(item_ipv6), 4671 .call = parse_vc, 4672 }, 4673 [ITEM_IPV6_TC] = { 4674 .name = "tc", 4675 .help = "traffic class", 4676 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4677 item_param), 4678 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4679 hdr.vtc_flow, 4680 "\x0f\xf0\x00\x00")), 4681 }, 4682 [ITEM_IPV6_FLOW] = { 4683 .name = "flow", 4684 .help = "flow label", 4685 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4686 item_param), 4687 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4688 hdr.vtc_flow, 4689 "\x00\x0f\xff\xff")), 4690 }, 4691 [ITEM_IPV6_LEN] = { 4692 .name = "length", 4693 .help = "payload length", 4694 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4695 item_param), 4696 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4697 hdr.payload_len)), 4698 }, 4699 [ITEM_IPV6_PROTO] = { 4700 .name = "proto", 4701 .help = "protocol (next header)", 4702 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4703 item_param), 4704 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4705 hdr.proto)), 4706 }, 4707 [ITEM_IPV6_HOP] = { 4708 .name = "hop", 4709 .help = "hop limit", 4710 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4711 item_param), 4712 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4713 hdr.hop_limits)), 4714 }, 4715 [ITEM_IPV6_SRC] = { 4716 .name = "src", 4717 .help = "source address", 4718 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4719 item_param), 4720 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4721 hdr.src_addr)), 4722 }, 4723 [ITEM_IPV6_DST] = { 4724 .name = "dst", 4725 .help = "destination address", 4726 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4727 item_param), 4728 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4729 hdr.dst_addr)), 4730 }, 4731 [ITEM_IPV6_HAS_FRAG_EXT] = { 4732 .name = "has_frag_ext", 4733 .help = "fragment packet attribute", 4734 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4735 item_param), 4736 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, 4737 has_frag_ext, 1)), 4738 }, 4739 [ITEM_IPV6_ROUTING_EXT] = { 4740 .name = "ipv6_routing_ext", 4741 .help = "match IPv6 routing extension header", 4742 .priv = PRIV_ITEM(IPV6_ROUTING_EXT, 4743 sizeof(struct rte_flow_item_ipv6_routing_ext)), 4744 .next = NEXT(item_ipv6_routing_ext), 4745 .call = parse_vc, 4746 }, 4747 [ITEM_IPV6_ROUTING_EXT_TYPE] = { 4748 .name = "ext_type", 4749 .help = "match IPv6 routing extension header type", 4750 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4751 item_param), 4752 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4753 hdr.type)), 4754 }, 4755 [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = { 4756 .name = "ext_next_hdr", 4757 .help = "match IPv6 routing extension header next header type", 4758 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4759 item_param), 4760 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4761 hdr.next_hdr)), 4762 }, 4763 [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = { 4764 .name = "ext_seg_left", 4765 .help = "match IPv6 routing extension header segment left", 4766 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4767 item_param), 4768 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4769 hdr.segments_left)), 4770 }, 4771 [ITEM_ICMP] = { 4772 .name = "icmp", 4773 .help = "match ICMP header", 4774 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), 4775 .next = NEXT(item_icmp), 4776 .call = parse_vc, 4777 }, 4778 [ITEM_ICMP_TYPE] = { 4779 .name = "type", 4780 .help = "ICMP packet type", 4781 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4782 item_param), 4783 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4784 hdr.icmp_type)), 4785 }, 4786 [ITEM_ICMP_CODE] = { 4787 .name = "code", 4788 .help = "ICMP packet code", 4789 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4790 item_param), 4791 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4792 hdr.icmp_code)), 4793 }, 4794 [ITEM_ICMP_IDENT] = { 4795 .name = "ident", 4796 .help = "ICMP packet identifier", 4797 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4798 item_param), 4799 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4800 hdr.icmp_ident)), 4801 }, 4802 [ITEM_ICMP_SEQ] = { 4803 .name = "seq", 4804 .help = "ICMP packet sequence number", 4805 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4806 item_param), 4807 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4808 hdr.icmp_seq_nb)), 4809 }, 4810 [ITEM_UDP] = { 4811 .name = "udp", 4812 .help = "match UDP header", 4813 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), 4814 .next = NEXT(item_udp), 4815 .call = parse_vc, 4816 }, 4817 [ITEM_UDP_SRC] = { 4818 .name = "src", 4819 .help = "UDP source port", 4820 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), 4821 item_param), 4822 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4823 hdr.src_port)), 4824 }, 4825 [ITEM_UDP_DST] = { 4826 .name = "dst", 4827 .help = "UDP destination port", 4828 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4829 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4830 hdr.dst_port)), 4831 }, 4832 [ITEM_TCP] = { 4833 .name = "tcp", 4834 .help = "match TCP header", 4835 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), 4836 .next = NEXT(item_tcp), 4837 .call = parse_vc, 4838 }, 4839 [ITEM_TCP_SRC] = { 4840 .name = "src", 4841 .help = "TCP source port", 4842 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4843 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4844 hdr.src_port)), 4845 }, 4846 [ITEM_TCP_DST] = { 4847 .name = "dst", 4848 .help = "TCP destination port", 4849 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4850 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4851 hdr.dst_port)), 4852 }, 4853 [ITEM_TCP_FLAGS] = { 4854 .name = "flags", 4855 .help = "TCP flags", 4856 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4857 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4858 hdr.tcp_flags)), 4859 }, 4860 [ITEM_SCTP] = { 4861 .name = "sctp", 4862 .help = "match SCTP header", 4863 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), 4864 .next = NEXT(item_sctp), 4865 .call = parse_vc, 4866 }, 4867 [ITEM_SCTP_SRC] = { 4868 .name = "src", 4869 .help = "SCTP source port", 4870 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4871 item_param), 4872 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4873 hdr.src_port)), 4874 }, 4875 [ITEM_SCTP_DST] = { 4876 .name = "dst", 4877 .help = "SCTP destination port", 4878 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4879 item_param), 4880 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4881 hdr.dst_port)), 4882 }, 4883 [ITEM_SCTP_TAG] = { 4884 .name = "tag", 4885 .help = "validation tag", 4886 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4887 item_param), 4888 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4889 hdr.tag)), 4890 }, 4891 [ITEM_SCTP_CKSUM] = { 4892 .name = "cksum", 4893 .help = "checksum", 4894 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4895 item_param), 4896 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4897 hdr.cksum)), 4898 }, 4899 [ITEM_VXLAN] = { 4900 .name = "vxlan", 4901 .help = "match VXLAN header", 4902 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), 4903 .next = NEXT(item_vxlan), 4904 .call = parse_vc, 4905 }, 4906 [ITEM_VXLAN_VNI] = { 4907 .name = "vni", 4908 .help = "VXLAN identifier", 4909 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4910 item_param), 4911 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), 4912 }, 4913 [ITEM_VXLAN_LAST_RSVD] = { 4914 .name = "last_rsvd", 4915 .help = "VXLAN last reserved bits", 4916 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4917 item_param), 4918 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 4919 hdr.rsvd1)), 4920 }, 4921 [ITEM_E_TAG] = { 4922 .name = "e_tag", 4923 .help = "match E-Tag header", 4924 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), 4925 .next = NEXT(item_e_tag), 4926 .call = parse_vc, 4927 }, 4928 [ITEM_E_TAG_GRP_ECID_B] = { 4929 .name = "grp_ecid_b", 4930 .help = "GRP and E-CID base", 4931 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), 4932 item_param), 4933 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, 4934 rsvd_grp_ecid_b, 4935 "\x3f\xff")), 4936 }, 4937 [ITEM_NVGRE] = { 4938 .name = "nvgre", 4939 .help = "match NVGRE header", 4940 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), 4941 .next = NEXT(item_nvgre), 4942 .call = parse_vc, 4943 }, 4944 [ITEM_NVGRE_TNI] = { 4945 .name = "tni", 4946 .help = "virtual subnet ID", 4947 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), 4948 item_param), 4949 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), 4950 }, 4951 [ITEM_MPLS] = { 4952 .name = "mpls", 4953 .help = "match MPLS header", 4954 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), 4955 .next = NEXT(item_mpls), 4956 .call = parse_vc, 4957 }, 4958 [ITEM_MPLS_LABEL] = { 4959 .name = "label", 4960 .help = "MPLS label", 4961 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4962 item_param), 4963 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4964 label_tc_s, 4965 "\xff\xff\xf0")), 4966 }, 4967 [ITEM_MPLS_TC] = { 4968 .name = "tc", 4969 .help = "MPLS Traffic Class", 4970 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4971 item_param), 4972 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4973 label_tc_s, 4974 "\x00\x00\x0e")), 4975 }, 4976 [ITEM_MPLS_S] = { 4977 .name = "s", 4978 .help = "MPLS Bottom-of-Stack", 4979 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4980 item_param), 4981 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4982 label_tc_s, 4983 "\x00\x00\x01")), 4984 }, 4985 [ITEM_MPLS_TTL] = { 4986 .name = "ttl", 4987 .help = "MPLS Time-to-Live", 4988 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4989 item_param), 4990 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls, ttl)), 4991 }, 4992 [ITEM_GRE] = { 4993 .name = "gre", 4994 .help = "match GRE header", 4995 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), 4996 .next = NEXT(item_gre), 4997 .call = parse_vc, 4998 }, 4999 [ITEM_GRE_PROTO] = { 5000 .name = "protocol", 5001 .help = "GRE protocol type", 5002 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5003 item_param), 5004 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5005 protocol)), 5006 }, 5007 [ITEM_GRE_C_RSVD0_VER] = { 5008 .name = "c_rsvd0_ver", 5009 .help = 5010 "checksum (1b), undefined (1b), key bit (1b)," 5011 " sequence number (1b), reserved 0 (9b)," 5012 " version (3b)", 5013 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5014 item_param), 5015 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5016 c_rsvd0_ver)), 5017 }, 5018 [ITEM_GRE_C_BIT] = { 5019 .name = "c_bit", 5020 .help = "checksum bit (C)", 5021 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), 5022 item_param), 5023 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5024 c_rsvd0_ver, 5025 "\x80\x00\x00\x00")), 5026 }, 5027 [ITEM_GRE_S_BIT] = { 5028 .name = "s_bit", 5029 .help = "sequence number bit (S)", 5030 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5031 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5032 c_rsvd0_ver, 5033 "\x10\x00\x00\x00")), 5034 }, 5035 [ITEM_GRE_K_BIT] = { 5036 .name = "k_bit", 5037 .help = "key bit (K)", 5038 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5039 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5040 c_rsvd0_ver, 5041 "\x20\x00\x00\x00")), 5042 }, 5043 [ITEM_FUZZY] = { 5044 .name = "fuzzy", 5045 .help = "fuzzy pattern match, expect faster than default", 5046 .priv = PRIV_ITEM(FUZZY, 5047 sizeof(struct rte_flow_item_fuzzy)), 5048 .next = NEXT(item_fuzzy), 5049 .call = parse_vc, 5050 }, 5051 [ITEM_FUZZY_THRESH] = { 5052 .name = "thresh", 5053 .help = "match accuracy threshold", 5054 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), 5055 item_param), 5056 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, 5057 thresh)), 5058 }, 5059 [ITEM_GTP] = { 5060 .name = "gtp", 5061 .help = "match GTP header", 5062 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), 5063 .next = NEXT(item_gtp), 5064 .call = parse_vc, 5065 }, 5066 [ITEM_GTP_FLAGS] = { 5067 .name = "v_pt_rsv_flags", 5068 .help = "GTP flags", 5069 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5070 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, 5071 hdr.gtp_hdr_info)), 5072 }, 5073 [ITEM_GTP_MSG_TYPE] = { 5074 .name = "msg_type", 5075 .help = "GTP message type", 5076 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5077 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), 5078 }, 5079 [ITEM_GTP_TEID] = { 5080 .name = "teid", 5081 .help = "tunnel endpoint identifier", 5082 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5083 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), 5084 }, 5085 [ITEM_GTPC] = { 5086 .name = "gtpc", 5087 .help = "match GTP header", 5088 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), 5089 .next = NEXT(item_gtp), 5090 .call = parse_vc, 5091 }, 5092 [ITEM_GTPU] = { 5093 .name = "gtpu", 5094 .help = "match GTP header", 5095 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), 5096 .next = NEXT(item_gtp), 5097 .call = parse_vc, 5098 }, 5099 [ITEM_GENEVE] = { 5100 .name = "geneve", 5101 .help = "match GENEVE header", 5102 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), 5103 .next = NEXT(item_geneve), 5104 .call = parse_vc, 5105 }, 5106 [ITEM_GENEVE_VNI] = { 5107 .name = "vni", 5108 .help = "virtual network identifier", 5109 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5110 item_param), 5111 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), 5112 }, 5113 [ITEM_GENEVE_PROTO] = { 5114 .name = "protocol", 5115 .help = "GENEVE protocol type", 5116 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5117 item_param), 5118 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, 5119 protocol)), 5120 }, 5121 [ITEM_GENEVE_OPTLEN] = { 5122 .name = "optlen", 5123 .help = "GENEVE options length in dwords", 5124 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5125 item_param), 5126 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, 5127 ver_opt_len_o_c_rsvd0, 5128 "\x3f\x00")), 5129 }, 5130 [ITEM_VXLAN_GPE] = { 5131 .name = "vxlan-gpe", 5132 .help = "match VXLAN-GPE header", 5133 .priv = PRIV_ITEM(VXLAN_GPE, 5134 sizeof(struct rte_flow_item_vxlan_gpe)), 5135 .next = NEXT(item_vxlan_gpe), 5136 .call = parse_vc, 5137 }, 5138 [ITEM_VXLAN_GPE_VNI] = { 5139 .name = "vni", 5140 .help = "VXLAN-GPE identifier", 5141 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5142 item_param), 5143 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5144 hdr.vni)), 5145 }, 5146 [ITEM_VXLAN_GPE_PROTO] = { 5147 .name = "protocol", 5148 .help = "VXLAN-GPE next protocol", 5149 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5150 item_param), 5151 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5152 protocol)), 5153 }, 5154 [ITEM_VXLAN_GPE_FLAGS] = { 5155 .name = "flags", 5156 .help = "VXLAN-GPE flags", 5157 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5158 item_param), 5159 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5160 flags)), 5161 }, 5162 [ITEM_VXLAN_GPE_RSVD0] = { 5163 .name = "rsvd0", 5164 .help = "VXLAN-GPE rsvd0", 5165 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5166 item_param), 5167 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5168 rsvd0)), 5169 }, 5170 [ITEM_VXLAN_GPE_RSVD1] = { 5171 .name = "rsvd1", 5172 .help = "VXLAN-GPE rsvd1", 5173 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5174 item_param), 5175 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5176 rsvd1)), 5177 }, 5178 [ITEM_ARP_ETH_IPV4] = { 5179 .name = "arp_eth_ipv4", 5180 .help = "match ARP header for Ethernet/IPv4", 5181 .priv = PRIV_ITEM(ARP_ETH_IPV4, 5182 sizeof(struct rte_flow_item_arp_eth_ipv4)), 5183 .next = NEXT(item_arp_eth_ipv4), 5184 .call = parse_vc, 5185 }, 5186 [ITEM_ARP_ETH_IPV4_SHA] = { 5187 .name = "sha", 5188 .help = "sender hardware address", 5189 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5190 item_param), 5191 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5192 hdr.arp_data.arp_sha)), 5193 }, 5194 [ITEM_ARP_ETH_IPV4_SPA] = { 5195 .name = "spa", 5196 .help = "sender IPv4 address", 5197 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5198 item_param), 5199 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5200 hdr.arp_data.arp_sip)), 5201 }, 5202 [ITEM_ARP_ETH_IPV4_THA] = { 5203 .name = "tha", 5204 .help = "target hardware address", 5205 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5206 item_param), 5207 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5208 hdr.arp_data.arp_tha)), 5209 }, 5210 [ITEM_ARP_ETH_IPV4_TPA] = { 5211 .name = "tpa", 5212 .help = "target IPv4 address", 5213 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5214 item_param), 5215 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5216 hdr.arp_data.arp_tip)), 5217 }, 5218 [ITEM_IPV6_EXT] = { 5219 .name = "ipv6_ext", 5220 .help = "match presence of any IPv6 extension header", 5221 .priv = PRIV_ITEM(IPV6_EXT, 5222 sizeof(struct rte_flow_item_ipv6_ext)), 5223 .next = NEXT(item_ipv6_ext), 5224 .call = parse_vc, 5225 }, 5226 [ITEM_IPV6_EXT_NEXT_HDR] = { 5227 .name = "next_hdr", 5228 .help = "next header", 5229 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5230 item_param), 5231 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 5232 next_hdr)), 5233 }, 5234 [ITEM_IPV6_FRAG_EXT] = { 5235 .name = "ipv6_frag_ext", 5236 .help = "match presence of IPv6 fragment extension header", 5237 .priv = PRIV_ITEM(IPV6_FRAG_EXT, 5238 sizeof(struct rte_flow_item_ipv6_frag_ext)), 5239 .next = NEXT(item_ipv6_frag_ext), 5240 .call = parse_vc, 5241 }, 5242 [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { 5243 .name = "next_hdr", 5244 .help = "next header", 5245 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5246 item_param), 5247 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, 5248 hdr.next_header)), 5249 }, 5250 [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { 5251 .name = "frag_data", 5252 .help = "fragment flags and offset", 5253 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5254 item_param), 5255 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5256 hdr.frag_data)), 5257 }, 5258 [ITEM_IPV6_FRAG_EXT_ID] = { 5259 .name = "packet_id", 5260 .help = "fragment packet id", 5261 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5262 item_param), 5263 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5264 hdr.id)), 5265 }, 5266 [ITEM_ICMP6] = { 5267 .name = "icmp6", 5268 .help = "match any ICMPv6 header", 5269 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), 5270 .next = NEXT(item_icmp6), 5271 .call = parse_vc, 5272 }, 5273 [ITEM_ICMP6_TYPE] = { 5274 .name = "type", 5275 .help = "ICMPv6 type", 5276 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5277 item_param), 5278 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5279 type)), 5280 }, 5281 [ITEM_ICMP6_CODE] = { 5282 .name = "code", 5283 .help = "ICMPv6 code", 5284 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5285 item_param), 5286 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5287 code)), 5288 }, 5289 [ITEM_ICMP6_ECHO_REQUEST] = { 5290 .name = "icmp6_echo_request", 5291 .help = "match ICMPv6 echo request", 5292 .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, 5293 sizeof(struct rte_flow_item_icmp6_echo)), 5294 .next = NEXT(item_icmp6_echo_request), 5295 .call = parse_vc, 5296 }, 5297 [ITEM_ICMP6_ECHO_REQUEST_ID] = { 5298 .name = "ident", 5299 .help = "ICMPv6 echo request identifier", 5300 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5301 item_param), 5302 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5303 hdr.identifier)), 5304 }, 5305 [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { 5306 .name = "seq", 5307 .help = "ICMPv6 echo request sequence", 5308 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5309 item_param), 5310 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5311 hdr.sequence)), 5312 }, 5313 [ITEM_ICMP6_ECHO_REPLY] = { 5314 .name = "icmp6_echo_reply", 5315 .help = "match ICMPv6 echo reply", 5316 .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, 5317 sizeof(struct rte_flow_item_icmp6_echo)), 5318 .next = NEXT(item_icmp6_echo_reply), 5319 .call = parse_vc, 5320 }, 5321 [ITEM_ICMP6_ECHO_REPLY_ID] = { 5322 .name = "ident", 5323 .help = "ICMPv6 echo reply identifier", 5324 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5325 item_param), 5326 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5327 hdr.identifier)), 5328 }, 5329 [ITEM_ICMP6_ECHO_REPLY_SEQ] = { 5330 .name = "seq", 5331 .help = "ICMPv6 echo reply sequence", 5332 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5333 item_param), 5334 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5335 hdr.sequence)), 5336 }, 5337 [ITEM_ICMP6_ND_NS] = { 5338 .name = "icmp6_nd_ns", 5339 .help = "match ICMPv6 neighbor discovery solicitation", 5340 .priv = PRIV_ITEM(ICMP6_ND_NS, 5341 sizeof(struct rte_flow_item_icmp6_nd_ns)), 5342 .next = NEXT(item_icmp6_nd_ns), 5343 .call = parse_vc, 5344 }, 5345 [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { 5346 .name = "target_addr", 5347 .help = "target address", 5348 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), 5349 item_param), 5350 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, 5351 target_addr)), 5352 }, 5353 [ITEM_ICMP6_ND_NA] = { 5354 .name = "icmp6_nd_na", 5355 .help = "match ICMPv6 neighbor discovery advertisement", 5356 .priv = PRIV_ITEM(ICMP6_ND_NA, 5357 sizeof(struct rte_flow_item_icmp6_nd_na)), 5358 .next = NEXT(item_icmp6_nd_na), 5359 .call = parse_vc, 5360 }, 5361 [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { 5362 .name = "target_addr", 5363 .help = "target address", 5364 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), 5365 item_param), 5366 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, 5367 target_addr)), 5368 }, 5369 [ITEM_ICMP6_ND_OPT] = { 5370 .name = "icmp6_nd_opt", 5371 .help = "match presence of any ICMPv6 neighbor discovery" 5372 " option", 5373 .priv = PRIV_ITEM(ICMP6_ND_OPT, 5374 sizeof(struct rte_flow_item_icmp6_nd_opt)), 5375 .next = NEXT(item_icmp6_nd_opt), 5376 .call = parse_vc, 5377 }, 5378 [ITEM_ICMP6_ND_OPT_TYPE] = { 5379 .name = "type", 5380 .help = "ND option type", 5381 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5382 item_param), 5383 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, 5384 type)), 5385 }, 5386 [ITEM_ICMP6_ND_OPT_SLA_ETH] = { 5387 .name = "icmp6_nd_opt_sla_eth", 5388 .help = "match ICMPv6 neighbor discovery source Ethernet" 5389 " link-layer address option", 5390 .priv = PRIV_ITEM 5391 (ICMP6_ND_OPT_SLA_ETH, 5392 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), 5393 .next = NEXT(item_icmp6_nd_opt_sla_eth), 5394 .call = parse_vc, 5395 }, 5396 [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { 5397 .name = "sla", 5398 .help = "source Ethernet LLA", 5399 .next = NEXT(item_icmp6_nd_opt_sla_eth, 5400 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5401 .args = ARGS(ARGS_ENTRY_HTON 5402 (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), 5403 }, 5404 [ITEM_ICMP6_ND_OPT_TLA_ETH] = { 5405 .name = "icmp6_nd_opt_tla_eth", 5406 .help = "match ICMPv6 neighbor discovery target Ethernet" 5407 " link-layer address option", 5408 .priv = PRIV_ITEM 5409 (ICMP6_ND_OPT_TLA_ETH, 5410 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), 5411 .next = NEXT(item_icmp6_nd_opt_tla_eth), 5412 .call = parse_vc, 5413 }, 5414 [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { 5415 .name = "tla", 5416 .help = "target Ethernet LLA", 5417 .next = NEXT(item_icmp6_nd_opt_tla_eth, 5418 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5419 .args = ARGS(ARGS_ENTRY_HTON 5420 (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), 5421 }, 5422 [ITEM_META] = { 5423 .name = "meta", 5424 .help = "match metadata header", 5425 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), 5426 .next = NEXT(item_meta), 5427 .call = parse_vc, 5428 }, 5429 [ITEM_META_DATA] = { 5430 .name = "data", 5431 .help = "metadata value", 5432 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), 5433 item_param), 5434 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, 5435 data, "\xff\xff\xff\xff")), 5436 }, 5437 [ITEM_RANDOM] = { 5438 .name = "random", 5439 .help = "match random value", 5440 .priv = PRIV_ITEM(RANDOM, sizeof(struct rte_flow_item_random)), 5441 .next = NEXT(item_random), 5442 .call = parse_vc, 5443 }, 5444 [ITEM_RANDOM_VALUE] = { 5445 .name = "value", 5446 .help = "random value", 5447 .next = NEXT(item_random, NEXT_ENTRY(COMMON_UNSIGNED), 5448 item_param), 5449 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_random, 5450 value, "\xff\xff")), 5451 }, 5452 [ITEM_GRE_KEY] = { 5453 .name = "gre_key", 5454 .help = "match GRE key", 5455 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), 5456 .next = NEXT(item_gre_key), 5457 .call = parse_vc, 5458 }, 5459 [ITEM_GRE_KEY_VALUE] = { 5460 .name = "value", 5461 .help = "key value", 5462 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), 5463 item_param), 5464 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5465 }, 5466 [ITEM_GRE_OPTION] = { 5467 .name = "gre_option", 5468 .help = "match GRE optional fields", 5469 .priv = PRIV_ITEM(GRE_OPTION, 5470 sizeof(struct rte_flow_item_gre_opt)), 5471 .next = NEXT(item_gre_option), 5472 .call = parse_vc, 5473 }, 5474 [ITEM_GRE_OPTION_CHECKSUM] = { 5475 .name = "checksum", 5476 .help = "match GRE checksum", 5477 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5478 item_param), 5479 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5480 checksum_rsvd.checksum)), 5481 }, 5482 [ITEM_GRE_OPTION_KEY] = { 5483 .name = "key", 5484 .help = "match GRE key", 5485 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5486 item_param), 5487 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5488 key.key)), 5489 }, 5490 [ITEM_GRE_OPTION_SEQUENCE] = { 5491 .name = "sequence", 5492 .help = "match GRE sequence", 5493 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5494 item_param), 5495 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5496 sequence.sequence)), 5497 }, 5498 [ITEM_GTP_PSC] = { 5499 .name = "gtp_psc", 5500 .help = "match GTP extension header with type 0x85", 5501 .priv = PRIV_ITEM(GTP_PSC, 5502 sizeof(struct rte_flow_item_gtp_psc)), 5503 .next = NEXT(item_gtp_psc), 5504 .call = parse_vc, 5505 }, 5506 [ITEM_GTP_PSC_QFI] = { 5507 .name = "qfi", 5508 .help = "QoS flow identifier", 5509 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5510 item_param), 5511 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5512 hdr.qfi, 6)), 5513 }, 5514 [ITEM_GTP_PSC_PDU_T] = { 5515 .name = "pdu_t", 5516 .help = "PDU type", 5517 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5518 item_param), 5519 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5520 hdr.type, 4)), 5521 }, 5522 [ITEM_PPPOES] = { 5523 .name = "pppoes", 5524 .help = "match PPPoE session header", 5525 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), 5526 .next = NEXT(item_pppoes), 5527 .call = parse_vc, 5528 }, 5529 [ITEM_PPPOED] = { 5530 .name = "pppoed", 5531 .help = "match PPPoE discovery header", 5532 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), 5533 .next = NEXT(item_pppoed), 5534 .call = parse_vc, 5535 }, 5536 [ITEM_PPPOE_SEID] = { 5537 .name = "seid", 5538 .help = "session identifier", 5539 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), 5540 item_param), 5541 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, 5542 session_id)), 5543 }, 5544 [ITEM_PPPOE_PROTO_ID] = { 5545 .name = "pppoe_proto_id", 5546 .help = "match PPPoE session protocol identifier", 5547 .priv = PRIV_ITEM(PPPOE_PROTO_ID, 5548 sizeof(struct rte_flow_item_pppoe_proto_id)), 5549 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED), 5550 item_param), 5551 .args = ARGS(ARGS_ENTRY_HTON 5552 (struct rte_flow_item_pppoe_proto_id, proto_id)), 5553 .call = parse_vc, 5554 }, 5555 [ITEM_HIGIG2] = { 5556 .name = "higig2", 5557 .help = "matches higig2 header", 5558 .priv = PRIV_ITEM(HIGIG2, 5559 sizeof(struct rte_flow_item_higig2_hdr)), 5560 .next = NEXT(item_higig2), 5561 .call = parse_vc, 5562 }, 5563 [ITEM_HIGIG2_CLASSIFICATION] = { 5564 .name = "classification", 5565 .help = "matches classification of higig2 header", 5566 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5567 item_param), 5568 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5569 hdr.ppt1.classification)), 5570 }, 5571 [ITEM_HIGIG2_VID] = { 5572 .name = "vid", 5573 .help = "matches vid of higig2 header", 5574 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5575 item_param), 5576 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5577 hdr.ppt1.vid)), 5578 }, 5579 [ITEM_TAG] = { 5580 .name = "tag", 5581 .help = "match tag value", 5582 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), 5583 .next = NEXT(item_tag), 5584 .call = parse_vc, 5585 }, 5586 [ITEM_TAG_DATA] = { 5587 .name = "data", 5588 .help = "tag value to match", 5589 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5590 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), 5591 }, 5592 [ITEM_TAG_INDEX] = { 5593 .name = "index", 5594 .help = "index of tag array to match", 5595 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5596 NEXT_ENTRY(ITEM_PARAM_IS)), 5597 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), 5598 }, 5599 [ITEM_L2TPV3OIP] = { 5600 .name = "l2tpv3oip", 5601 .help = "match L2TPv3 over IP header", 5602 .priv = PRIV_ITEM(L2TPV3OIP, 5603 sizeof(struct rte_flow_item_l2tpv3oip)), 5604 .next = NEXT(item_l2tpv3oip), 5605 .call = parse_vc, 5606 }, 5607 [ITEM_L2TPV3OIP_SESSION_ID] = { 5608 .name = "session_id", 5609 .help = "session identifier", 5610 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), 5611 item_param), 5612 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, 5613 session_id)), 5614 }, 5615 [ITEM_ESP] = { 5616 .name = "esp", 5617 .help = "match ESP header", 5618 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), 5619 .next = NEXT(item_esp), 5620 .call = parse_vc, 5621 }, 5622 [ITEM_ESP_SPI] = { 5623 .name = "spi", 5624 .help = "security policy index", 5625 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5626 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, 5627 hdr.spi)), 5628 }, 5629 [ITEM_AH] = { 5630 .name = "ah", 5631 .help = "match AH header", 5632 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), 5633 .next = NEXT(item_ah), 5634 .call = parse_vc, 5635 }, 5636 [ITEM_AH_SPI] = { 5637 .name = "spi", 5638 .help = "security parameters index", 5639 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5640 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), 5641 }, 5642 [ITEM_PFCP] = { 5643 .name = "pfcp", 5644 .help = "match pfcp header", 5645 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), 5646 .next = NEXT(item_pfcp), 5647 .call = parse_vc, 5648 }, 5649 [ITEM_PFCP_S_FIELD] = { 5650 .name = "s_field", 5651 .help = "S field", 5652 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5653 item_param), 5654 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, 5655 s_field)), 5656 }, 5657 [ITEM_PFCP_SEID] = { 5658 .name = "seid", 5659 .help = "session endpoint identifier", 5660 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5661 item_param), 5662 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), 5663 }, 5664 [ITEM_ECPRI] = { 5665 .name = "ecpri", 5666 .help = "match eCPRI header", 5667 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), 5668 .next = NEXT(item_ecpri), 5669 .call = parse_vc, 5670 }, 5671 [ITEM_ECPRI_COMMON] = { 5672 .name = "common", 5673 .help = "eCPRI common header", 5674 .next = NEXT(item_ecpri_common), 5675 }, 5676 [ITEM_ECPRI_COMMON_TYPE] = { 5677 .name = "type", 5678 .help = "type of common header", 5679 .next = NEXT(item_ecpri_common_type), 5680 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), 5681 }, 5682 [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { 5683 .name = "iq_data", 5684 .help = "Type #0: IQ Data", 5685 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5686 ITEM_NEXT)), 5687 .call = parse_vc_item_ecpri_type, 5688 }, 5689 [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { 5690 .name = "pc_id", 5691 .help = "Physical Channel ID", 5692 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5693 ITEM_ECPRI_COMMON, ITEM_NEXT), 5694 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5695 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5696 hdr.type0.pc_id)), 5697 }, 5698 [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { 5699 .name = "rtc_ctrl", 5700 .help = "Type #2: Real-Time Control Data", 5701 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5702 ITEM_NEXT)), 5703 .call = parse_vc_item_ecpri_type, 5704 }, 5705 [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { 5706 .name = "rtc_id", 5707 .help = "Real-Time Control Data ID", 5708 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5709 ITEM_ECPRI_COMMON, ITEM_NEXT), 5710 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5711 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5712 hdr.type2.rtc_id)), 5713 }, 5714 [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { 5715 .name = "delay_measure", 5716 .help = "Type #5: One-Way Delay Measurement", 5717 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5718 ITEM_NEXT)), 5719 .call = parse_vc_item_ecpri_type, 5720 }, 5721 [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { 5722 .name = "msr_id", 5723 .help = "Measurement ID", 5724 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5725 ITEM_ECPRI_COMMON, ITEM_NEXT), 5726 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5727 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5728 hdr.type5.msr_id)), 5729 }, 5730 [ITEM_GENEVE_OPT] = { 5731 .name = "geneve-opt", 5732 .help = "GENEVE header option", 5733 .priv = PRIV_ITEM(GENEVE_OPT, 5734 sizeof(struct rte_flow_item_geneve_opt) + 5735 ITEM_GENEVE_OPT_DATA_SIZE), 5736 .next = NEXT(item_geneve_opt), 5737 .call = parse_vc, 5738 }, 5739 [ITEM_GENEVE_OPT_CLASS] = { 5740 .name = "class", 5741 .help = "GENEVE option class", 5742 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5743 item_param), 5744 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, 5745 option_class)), 5746 }, 5747 [ITEM_GENEVE_OPT_TYPE] = { 5748 .name = "type", 5749 .help = "GENEVE option type", 5750 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5751 item_param), 5752 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, 5753 option_type)), 5754 }, 5755 [ITEM_GENEVE_OPT_LENGTH] = { 5756 .name = "length", 5757 .help = "GENEVE option data length (in 32b words)", 5758 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5759 item_param), 5760 .args = ARGS(ARGS_ENTRY_BOUNDED( 5761 struct rte_flow_item_geneve_opt, option_len, 5762 0, 31)), 5763 }, 5764 [ITEM_GENEVE_OPT_DATA] = { 5765 .name = "data", 5766 .help = "GENEVE option data pattern", 5767 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), 5768 item_param), 5769 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), 5770 ARGS_ENTRY_ARB(0, 0), 5771 ARGS_ENTRY_ARB 5772 (sizeof(struct rte_flow_item_geneve_opt), 5773 ITEM_GENEVE_OPT_DATA_SIZE)), 5774 }, 5775 [ITEM_INTEGRITY] = { 5776 .name = "integrity", 5777 .help = "match packet integrity", 5778 .priv = PRIV_ITEM(INTEGRITY, 5779 sizeof(struct rte_flow_item_integrity)), 5780 .next = NEXT(item_integrity), 5781 .call = parse_vc, 5782 }, 5783 [ITEM_INTEGRITY_LEVEL] = { 5784 .name = "level", 5785 .help = "integrity level", 5786 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5787 item_param), 5788 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), 5789 }, 5790 [ITEM_INTEGRITY_VALUE] = { 5791 .name = "value", 5792 .help = "integrity value", 5793 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5794 item_param), 5795 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), 5796 }, 5797 [ITEM_CONNTRACK] = { 5798 .name = "conntrack", 5799 .help = "conntrack state", 5800 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 5801 item_param), 5802 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 5803 }, 5804 [ITEM_PORT_REPRESENTOR] = { 5805 .name = "port_representor", 5806 .help = "match traffic entering the embedded switch from the given ethdev", 5807 .priv = PRIV_ITEM(PORT_REPRESENTOR, 5808 sizeof(struct rte_flow_item_ethdev)), 5809 .next = NEXT(item_port_representor), 5810 .call = parse_vc, 5811 }, 5812 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 5813 .name = "port_id", 5814 .help = "ethdev port ID", 5815 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 5816 item_param), 5817 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5818 }, 5819 [ITEM_REPRESENTED_PORT] = { 5820 .name = "represented_port", 5821 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 5822 .priv = PRIV_ITEM(REPRESENTED_PORT, 5823 sizeof(struct rte_flow_item_ethdev)), 5824 .next = NEXT(item_represented_port), 5825 .call = parse_vc, 5826 }, 5827 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 5828 .name = "ethdev_port_id", 5829 .help = "ethdev port ID", 5830 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 5831 item_param), 5832 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5833 }, 5834 [ITEM_FLEX] = { 5835 .name = "flex", 5836 .help = "match flex header", 5837 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 5838 .next = NEXT(item_flex), 5839 .call = parse_vc, 5840 }, 5841 [ITEM_FLEX_ITEM_HANDLE] = { 5842 .name = "item", 5843 .help = "flex item handle", 5844 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5845 NEXT_ENTRY(ITEM_PARAM_IS)), 5846 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 5847 }, 5848 [ITEM_FLEX_PATTERN_HANDLE] = { 5849 .name = "pattern", 5850 .help = "flex pattern handle", 5851 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5852 NEXT_ENTRY(ITEM_PARAM_IS)), 5853 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 5854 }, 5855 [ITEM_L2TPV2] = { 5856 .name = "l2tpv2", 5857 .help = "match L2TPv2 header", 5858 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 5859 .next = NEXT(item_l2tpv2), 5860 .call = parse_vc, 5861 }, 5862 [ITEM_L2TPV2_TYPE] = { 5863 .name = "type", 5864 .help = "type of l2tpv2", 5865 .next = NEXT(item_l2tpv2_type), 5866 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 5867 }, 5868 [ITEM_L2TPV2_TYPE_DATA] = { 5869 .name = "data", 5870 .help = "Type #7: data message without any options", 5871 .next = NEXT(item_l2tpv2_type_data), 5872 .call = parse_vc_item_l2tpv2_type, 5873 }, 5874 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 5875 .name = "tunnel_id", 5876 .help = "tunnel identifier", 5877 .next = NEXT(item_l2tpv2_type_data, 5878 NEXT_ENTRY(COMMON_UNSIGNED), 5879 item_param), 5880 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5881 hdr.type7.tunnel_id)), 5882 }, 5883 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 5884 .name = "session_id", 5885 .help = "session identifier", 5886 .next = NEXT(item_l2tpv2_type_data, 5887 NEXT_ENTRY(COMMON_UNSIGNED), 5888 item_param), 5889 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5890 hdr.type7.session_id)), 5891 }, 5892 [ITEM_L2TPV2_TYPE_DATA_L] = { 5893 .name = "data_l", 5894 .help = "Type #6: data message with length option", 5895 .next = NEXT(item_l2tpv2_type_data_l), 5896 .call = parse_vc_item_l2tpv2_type, 5897 }, 5898 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 5899 .name = "length", 5900 .help = "message length", 5901 .next = NEXT(item_l2tpv2_type_data_l, 5902 NEXT_ENTRY(COMMON_UNSIGNED), 5903 item_param), 5904 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5905 hdr.type6.length)), 5906 }, 5907 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 5908 .name = "tunnel_id", 5909 .help = "tunnel identifier", 5910 .next = NEXT(item_l2tpv2_type_data_l, 5911 NEXT_ENTRY(COMMON_UNSIGNED), 5912 item_param), 5913 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5914 hdr.type6.tunnel_id)), 5915 }, 5916 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 5917 .name = "session_id", 5918 .help = "session identifier", 5919 .next = NEXT(item_l2tpv2_type_data_l, 5920 NEXT_ENTRY(COMMON_UNSIGNED), 5921 item_param), 5922 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5923 hdr.type6.session_id)), 5924 }, 5925 [ITEM_L2TPV2_TYPE_DATA_S] = { 5926 .name = "data_s", 5927 .help = "Type #5: data message with ns, nr option", 5928 .next = NEXT(item_l2tpv2_type_data_s), 5929 .call = parse_vc_item_l2tpv2_type, 5930 }, 5931 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 5932 .name = "tunnel_id", 5933 .help = "tunnel identifier", 5934 .next = NEXT(item_l2tpv2_type_data_s, 5935 NEXT_ENTRY(COMMON_UNSIGNED), 5936 item_param), 5937 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5938 hdr.type5.tunnel_id)), 5939 }, 5940 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 5941 .name = "session_id", 5942 .help = "session identifier", 5943 .next = NEXT(item_l2tpv2_type_data_s, 5944 NEXT_ENTRY(COMMON_UNSIGNED), 5945 item_param), 5946 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5947 hdr.type5.session_id)), 5948 }, 5949 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 5950 .name = "ns", 5951 .help = "sequence number for message", 5952 .next = NEXT(item_l2tpv2_type_data_s, 5953 NEXT_ENTRY(COMMON_UNSIGNED), 5954 item_param), 5955 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5956 hdr.type5.ns)), 5957 }, 5958 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 5959 .name = "nr", 5960 .help = "sequence number for next receive message", 5961 .next = NEXT(item_l2tpv2_type_data_s, 5962 NEXT_ENTRY(COMMON_UNSIGNED), 5963 item_param), 5964 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5965 hdr.type5.nr)), 5966 }, 5967 [ITEM_L2TPV2_TYPE_DATA_O] = { 5968 .name = "data_o", 5969 .help = "Type #4: data message with offset option", 5970 .next = NEXT(item_l2tpv2_type_data_o), 5971 .call = parse_vc_item_l2tpv2_type, 5972 }, 5973 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 5974 .name = "tunnel_id", 5975 .help = "tunnel identifier", 5976 .next = NEXT(item_l2tpv2_type_data_o, 5977 NEXT_ENTRY(COMMON_UNSIGNED), 5978 item_param), 5979 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5980 hdr.type4.tunnel_id)), 5981 }, 5982 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 5983 .name = "session_id", 5984 .help = "session identifier", 5985 .next = NEXT(item_l2tpv2_type_data_o, 5986 NEXT_ENTRY(COMMON_UNSIGNED), 5987 item_param), 5988 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5989 hdr.type5.session_id)), 5990 }, 5991 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 5992 .name = "offset_size", 5993 .help = "the size of offset padding", 5994 .next = NEXT(item_l2tpv2_type_data_o, 5995 NEXT_ENTRY(COMMON_UNSIGNED), 5996 item_param), 5997 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5998 hdr.type4.offset_size)), 5999 }, 6000 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 6001 .name = "data_l_s", 6002 .help = "Type #3: data message contains length, ns, nr " 6003 "options", 6004 .next = NEXT(item_l2tpv2_type_data_l_s), 6005 .call = parse_vc_item_l2tpv2_type, 6006 }, 6007 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 6008 .name = "length", 6009 .help = "message length", 6010 .next = NEXT(item_l2tpv2_type_data_l_s, 6011 NEXT_ENTRY(COMMON_UNSIGNED), 6012 item_param), 6013 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6014 hdr.type3.length)), 6015 }, 6016 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 6017 .name = "tunnel_id", 6018 .help = "tunnel identifier", 6019 .next = NEXT(item_l2tpv2_type_data_l_s, 6020 NEXT_ENTRY(COMMON_UNSIGNED), 6021 item_param), 6022 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6023 hdr.type3.tunnel_id)), 6024 }, 6025 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 6026 .name = "session_id", 6027 .help = "session identifier", 6028 .next = NEXT(item_l2tpv2_type_data_l_s, 6029 NEXT_ENTRY(COMMON_UNSIGNED), 6030 item_param), 6031 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6032 hdr.type3.session_id)), 6033 }, 6034 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 6035 .name = "ns", 6036 .help = "sequence number for message", 6037 .next = NEXT(item_l2tpv2_type_data_l_s, 6038 NEXT_ENTRY(COMMON_UNSIGNED), 6039 item_param), 6040 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6041 hdr.type3.ns)), 6042 }, 6043 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 6044 .name = "nr", 6045 .help = "sequence number for next receive message", 6046 .next = NEXT(item_l2tpv2_type_data_l_s, 6047 NEXT_ENTRY(COMMON_UNSIGNED), 6048 item_param), 6049 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6050 hdr.type3.nr)), 6051 }, 6052 [ITEM_L2TPV2_TYPE_CTRL] = { 6053 .name = "control", 6054 .help = "Type #3: conrtol message contains length, ns, nr " 6055 "options", 6056 .next = NEXT(item_l2tpv2_type_ctrl), 6057 .call = parse_vc_item_l2tpv2_type, 6058 }, 6059 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 6060 .name = "length", 6061 .help = "message length", 6062 .next = NEXT(item_l2tpv2_type_ctrl, 6063 NEXT_ENTRY(COMMON_UNSIGNED), 6064 item_param), 6065 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6066 hdr.type3.length)), 6067 }, 6068 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 6069 .name = "tunnel_id", 6070 .help = "tunnel identifier", 6071 .next = NEXT(item_l2tpv2_type_ctrl, 6072 NEXT_ENTRY(COMMON_UNSIGNED), 6073 item_param), 6074 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6075 hdr.type3.tunnel_id)), 6076 }, 6077 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 6078 .name = "session_id", 6079 .help = "session identifier", 6080 .next = NEXT(item_l2tpv2_type_ctrl, 6081 NEXT_ENTRY(COMMON_UNSIGNED), 6082 item_param), 6083 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6084 hdr.type3.session_id)), 6085 }, 6086 [ITEM_L2TPV2_MSG_CTRL_NS] = { 6087 .name = "ns", 6088 .help = "sequence number for message", 6089 .next = NEXT(item_l2tpv2_type_ctrl, 6090 NEXT_ENTRY(COMMON_UNSIGNED), 6091 item_param), 6092 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6093 hdr.type3.ns)), 6094 }, 6095 [ITEM_L2TPV2_MSG_CTRL_NR] = { 6096 .name = "nr", 6097 .help = "sequence number for next receive message", 6098 .next = NEXT(item_l2tpv2_type_ctrl, 6099 NEXT_ENTRY(COMMON_UNSIGNED), 6100 item_param), 6101 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6102 hdr.type3.nr)), 6103 }, 6104 [ITEM_PPP] = { 6105 .name = "ppp", 6106 .help = "match PPP header", 6107 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 6108 .next = NEXT(item_ppp), 6109 .call = parse_vc, 6110 }, 6111 [ITEM_PPP_ADDR] = { 6112 .name = "addr", 6113 .help = "PPP address", 6114 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6115 item_param), 6116 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 6117 }, 6118 [ITEM_PPP_CTRL] = { 6119 .name = "ctrl", 6120 .help = "PPP control", 6121 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6122 item_param), 6123 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 6124 }, 6125 [ITEM_PPP_PROTO_ID] = { 6126 .name = "proto_id", 6127 .help = "PPP protocol identifier", 6128 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6129 item_param), 6130 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 6131 hdr.proto_id)), 6132 }, 6133 [ITEM_METER] = { 6134 .name = "meter", 6135 .help = "match meter color", 6136 .priv = PRIV_ITEM(METER_COLOR, 6137 sizeof(struct rte_flow_item_meter_color)), 6138 .next = NEXT(item_meter), 6139 .call = parse_vc, 6140 }, 6141 [ITEM_METER_COLOR] = { 6142 .name = "color", 6143 .help = "meter color", 6144 .next = NEXT(item_meter, 6145 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 6146 item_param), 6147 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 6148 color)), 6149 }, 6150 [ITEM_METER_COLOR_NAME] = { 6151 .name = "color_name", 6152 .help = "meter color name", 6153 .call = parse_meter_color, 6154 .comp = comp_meter_color, 6155 }, 6156 [ITEM_QUOTA] = { 6157 .name = "quota", 6158 .help = "match quota", 6159 .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), 6160 .next = NEXT(item_quota), 6161 .call = parse_vc 6162 }, 6163 [ITEM_QUOTA_STATE] = { 6164 .name = "quota_state", 6165 .help = "quota state", 6166 .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), 6167 NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), 6168 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) 6169 }, 6170 [ITEM_QUOTA_STATE_NAME] = { 6171 .name = "state_name", 6172 .help = "quota state name", 6173 .call = parse_quota_state_name, 6174 .comp = comp_quota_state_name 6175 }, 6176 [ITEM_IB_BTH] = { 6177 .name = "ib_bth", 6178 .help = "match ib bth fields", 6179 .priv = PRIV_ITEM(IB_BTH, 6180 sizeof(struct rte_flow_item_ib_bth)), 6181 .next = NEXT(item_ib_bth), 6182 .call = parse_vc, 6183 }, 6184 [ITEM_IB_BTH_OPCODE] = { 6185 .name = "opcode", 6186 .help = "match ib bth opcode", 6187 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6188 item_param), 6189 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6190 hdr.opcode)), 6191 }, 6192 [ITEM_IB_BTH_PKEY] = { 6193 .name = "pkey", 6194 .help = "partition key", 6195 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6196 item_param), 6197 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6198 hdr.pkey)), 6199 }, 6200 [ITEM_IB_BTH_DST_QPN] = { 6201 .name = "dst_qp", 6202 .help = "destination qp", 6203 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6204 item_param), 6205 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6206 hdr.dst_qp)), 6207 }, 6208 [ITEM_IB_BTH_PSN] = { 6209 .name = "psn", 6210 .help = "packet sequence number", 6211 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6212 item_param), 6213 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6214 hdr.psn)), 6215 }, 6216 [ITEM_PTYPE] = { 6217 .name = "ptype", 6218 .help = "match L2/L3/L4 and tunnel information", 6219 .priv = PRIV_ITEM(PTYPE, 6220 sizeof(struct rte_flow_item_ptype)), 6221 .next = NEXT(item_ptype), 6222 .call = parse_vc, 6223 }, 6224 [ITEM_PTYPE_VALUE] = { 6225 .name = "packet_type", 6226 .help = "packet type as defined in rte_mbuf_ptype", 6227 .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), 6228 item_param), 6229 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), 6230 }, 6231 [ITEM_NSH] = { 6232 .name = "nsh", 6233 .help = "match NSH header", 6234 .priv = PRIV_ITEM(NSH, 6235 sizeof(struct rte_flow_item_nsh)), 6236 .next = NEXT(item_nsh), 6237 .call = parse_vc, 6238 }, 6239 [ITEM_COMPARE] = { 6240 .name = "compare", 6241 .help = "match with the comparison result", 6242 .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)), 6243 .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)), 6244 .call = parse_vc, 6245 }, 6246 [ITEM_COMPARE_OP] = { 6247 .name = "op", 6248 .help = "operation type", 6249 .next = NEXT(item_compare_field, 6250 NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param), 6251 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)), 6252 }, 6253 [ITEM_COMPARE_OP_VALUE] = { 6254 .name = "{operation}", 6255 .help = "operation type value", 6256 .call = parse_vc_compare_op, 6257 .comp = comp_set_compare_op, 6258 }, 6259 [ITEM_COMPARE_FIELD_A_TYPE] = { 6260 .name = "a_type", 6261 .help = "compared field type", 6262 .next = NEXT(compare_field_a, 6263 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param), 6264 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)), 6265 }, 6266 [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = { 6267 .name = "{a_type}", 6268 .help = "compared field type value", 6269 .call = parse_vc_compare_field_id, 6270 .comp = comp_set_compare_field_id, 6271 }, 6272 [ITEM_COMPARE_FIELD_A_LEVEL] = { 6273 .name = "a_level", 6274 .help = "compared field level", 6275 .next = NEXT(compare_field_a, 6276 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param), 6277 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)), 6278 }, 6279 [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = { 6280 .name = "{a_level}", 6281 .help = "compared field level value", 6282 .call = parse_vc_compare_field_level, 6283 .comp = comp_none, 6284 }, 6285 [ITEM_COMPARE_FIELD_A_TAG_INDEX] = { 6286 .name = "a_tag_index", 6287 .help = "compared field tag array", 6288 .next = NEXT(compare_field_a, 6289 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6290 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6291 a.tag_index)), 6292 }, 6293 [ITEM_COMPARE_FIELD_A_TYPE_ID] = { 6294 .name = "a_type_id", 6295 .help = "compared field type ID", 6296 .next = NEXT(compare_field_a, 6297 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6298 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6299 a.type)), 6300 }, 6301 [ITEM_COMPARE_FIELD_A_CLASS_ID] = { 6302 .name = "a_class", 6303 .help = "compared field class ID", 6304 .next = NEXT(compare_field_a, 6305 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6306 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6307 a.class_id)), 6308 }, 6309 [ITEM_COMPARE_FIELD_A_OFFSET] = { 6310 .name = "a_offset", 6311 .help = "compared field bit offset", 6312 .next = NEXT(compare_field_a, 6313 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6314 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6315 a.offset)), 6316 }, 6317 [ITEM_COMPARE_FIELD_B_TYPE] = { 6318 .name = "b_type", 6319 .help = "comparator field type", 6320 .next = NEXT(compare_field_b, 6321 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param), 6322 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6323 b.field)), 6324 }, 6325 [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = { 6326 .name = "{b_type}", 6327 .help = "comparator field type value", 6328 .call = parse_vc_compare_field_id, 6329 .comp = comp_set_compare_field_id, 6330 }, 6331 [ITEM_COMPARE_FIELD_B_LEVEL] = { 6332 .name = "b_level", 6333 .help = "comparator field level", 6334 .next = NEXT(compare_field_b, 6335 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param), 6336 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6337 b.level)), 6338 }, 6339 [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = { 6340 .name = "{b_level}", 6341 .help = "comparator field level value", 6342 .call = parse_vc_compare_field_level, 6343 .comp = comp_none, 6344 }, 6345 [ITEM_COMPARE_FIELD_B_TAG_INDEX] = { 6346 .name = "b_tag_index", 6347 .help = "comparator field tag array", 6348 .next = NEXT(compare_field_b, 6349 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6350 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6351 b.tag_index)), 6352 }, 6353 [ITEM_COMPARE_FIELD_B_TYPE_ID] = { 6354 .name = "b_type_id", 6355 .help = "comparator field type ID", 6356 .next = NEXT(compare_field_b, 6357 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6358 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6359 b.type)), 6360 }, 6361 [ITEM_COMPARE_FIELD_B_CLASS_ID] = { 6362 .name = "b_class", 6363 .help = "comparator field class ID", 6364 .next = NEXT(compare_field_b, 6365 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6366 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6367 b.class_id)), 6368 }, 6369 [ITEM_COMPARE_FIELD_B_OFFSET] = { 6370 .name = "b_offset", 6371 .help = "comparator field bit offset", 6372 .next = NEXT(compare_field_b, 6373 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6374 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6375 b.offset)), 6376 }, 6377 [ITEM_COMPARE_FIELD_B_VALUE] = { 6378 .name = "b_value", 6379 .help = "comparator immediate value", 6380 .next = NEXT(compare_field_b, 6381 NEXT_ENTRY(COMMON_HEX), item_param), 6382 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6383 ARGS_ENTRY_ARB(0, 0), 6384 ARGS_ENTRY(struct rte_flow_item_compare, 6385 b.value)), 6386 }, 6387 [ITEM_COMPARE_FIELD_B_POINTER] = { 6388 .name = "b_ptr", 6389 .help = "pointer to comparator immediate value", 6390 .next = NEXT(compare_field_b, 6391 NEXT_ENTRY(COMMON_HEX), item_param), 6392 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6393 b.pvalue), 6394 ARGS_ENTRY_ARB(0, 0), 6395 ARGS_ENTRY_ARB 6396 (sizeof(struct rte_flow_item_compare), 6397 FLOW_FIELD_PATTERN_SIZE)), 6398 }, 6399 [ITEM_COMPARE_FIELD_WIDTH] = { 6400 .name = "width", 6401 .help = "number of bits to compare", 6402 .next = NEXT(item_compare_field, 6403 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6404 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6405 width)), 6406 }, 6407 6408 /* Validate/create actions. */ 6409 [ACTIONS] = { 6410 .name = "actions", 6411 .help = "submit a list of associated actions", 6412 .next = NEXT(next_action), 6413 .call = parse_vc, 6414 }, 6415 [ACTION_NEXT] = { 6416 .name = "/", 6417 .help = "specify next action", 6418 .next = NEXT(next_action), 6419 }, 6420 [ACTION_END] = { 6421 .name = "end", 6422 .help = "end list of actions", 6423 .priv = PRIV_ACTION(END, 0), 6424 .call = parse_vc, 6425 }, 6426 [ACTION_VOID] = { 6427 .name = "void", 6428 .help = "no-op action", 6429 .priv = PRIV_ACTION(VOID, 0), 6430 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6431 .call = parse_vc, 6432 }, 6433 [ACTION_PASSTHRU] = { 6434 .name = "passthru", 6435 .help = "let subsequent rule process matched packets", 6436 .priv = PRIV_ACTION(PASSTHRU, 0), 6437 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6438 .call = parse_vc, 6439 }, 6440 [ACTION_SKIP_CMAN] = { 6441 .name = "skip_cman", 6442 .help = "bypass cman on received packets", 6443 .priv = PRIV_ACTION(SKIP_CMAN, 0), 6444 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6445 .call = parse_vc, 6446 }, 6447 [ACTION_JUMP] = { 6448 .name = "jump", 6449 .help = "redirect traffic to a given group", 6450 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 6451 .next = NEXT(action_jump), 6452 .call = parse_vc, 6453 }, 6454 [ACTION_JUMP_GROUP] = { 6455 .name = "group", 6456 .help = "group to redirect traffic to", 6457 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 6458 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 6459 .call = parse_vc_conf, 6460 }, 6461 [ACTION_MARK] = { 6462 .name = "mark", 6463 .help = "attach 32 bit value to packets", 6464 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 6465 .next = NEXT(action_mark), 6466 .call = parse_vc, 6467 }, 6468 [ACTION_MARK_ID] = { 6469 .name = "id", 6470 .help = "32 bit value to return with packets", 6471 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6472 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 6473 .call = parse_vc_conf, 6474 }, 6475 [ACTION_FLAG] = { 6476 .name = "flag", 6477 .help = "flag packets", 6478 .priv = PRIV_ACTION(FLAG, 0), 6479 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6480 .call = parse_vc, 6481 }, 6482 [ACTION_QUEUE] = { 6483 .name = "queue", 6484 .help = "assign packets to a given queue index", 6485 .priv = PRIV_ACTION(QUEUE, 6486 sizeof(struct rte_flow_action_queue)), 6487 .next = NEXT(action_queue), 6488 .call = parse_vc, 6489 }, 6490 [ACTION_QUEUE_INDEX] = { 6491 .name = "index", 6492 .help = "queue index to use", 6493 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 6494 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 6495 .call = parse_vc_conf, 6496 }, 6497 [ACTION_DROP] = { 6498 .name = "drop", 6499 .help = "drop packets (note: passthru has priority)", 6500 .priv = PRIV_ACTION(DROP, 0), 6501 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6502 .call = parse_vc, 6503 }, 6504 [ACTION_COUNT] = { 6505 .name = "count", 6506 .help = "enable counters for this rule", 6507 .priv = PRIV_ACTION(COUNT, 6508 sizeof(struct rte_flow_action_count)), 6509 .next = NEXT(action_count), 6510 .call = parse_vc, 6511 }, 6512 [ACTION_COUNT_ID] = { 6513 .name = "identifier", 6514 .help = "counter identifier to use", 6515 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 6516 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 6517 .call = parse_vc_conf, 6518 }, 6519 [ACTION_RSS] = { 6520 .name = "rss", 6521 .help = "spread packets among several queues", 6522 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 6523 .next = NEXT(action_rss), 6524 .call = parse_vc_action_rss, 6525 }, 6526 [ACTION_RSS_FUNC] = { 6527 .name = "func", 6528 .help = "RSS hash function to apply", 6529 .next = NEXT(action_rss, 6530 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 6531 ACTION_RSS_FUNC_TOEPLITZ, 6532 ACTION_RSS_FUNC_SIMPLE_XOR, 6533 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 6534 }, 6535 [ACTION_RSS_FUNC_DEFAULT] = { 6536 .name = "default", 6537 .help = "default hash function", 6538 .call = parse_vc_action_rss_func, 6539 }, 6540 [ACTION_RSS_FUNC_TOEPLITZ] = { 6541 .name = "toeplitz", 6542 .help = "Toeplitz hash function", 6543 .call = parse_vc_action_rss_func, 6544 }, 6545 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 6546 .name = "simple_xor", 6547 .help = "simple XOR hash function", 6548 .call = parse_vc_action_rss_func, 6549 }, 6550 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 6551 .name = "symmetric_toeplitz", 6552 .help = "Symmetric Toeplitz hash function", 6553 .call = parse_vc_action_rss_func, 6554 }, 6555 [ACTION_RSS_LEVEL] = { 6556 .name = "level", 6557 .help = "encapsulation level for \"types\"", 6558 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6559 .args = ARGS(ARGS_ENTRY_ARB 6560 (offsetof(struct action_rss_data, conf) + 6561 offsetof(struct rte_flow_action_rss, level), 6562 sizeof(((struct rte_flow_action_rss *)0)-> 6563 level))), 6564 }, 6565 [ACTION_RSS_TYPES] = { 6566 .name = "types", 6567 .help = "specific RSS hash types", 6568 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 6569 }, 6570 [ACTION_RSS_TYPE] = { 6571 .name = "{type}", 6572 .help = "RSS hash type", 6573 .call = parse_vc_action_rss_type, 6574 .comp = comp_vc_action_rss_type, 6575 }, 6576 [ACTION_RSS_KEY] = { 6577 .name = "key", 6578 .help = "RSS hash key", 6579 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 6580 .args = ARGS(ARGS_ENTRY_ARB 6581 (offsetof(struct action_rss_data, conf) + 6582 offsetof(struct rte_flow_action_rss, key), 6583 sizeof(((struct rte_flow_action_rss *)0)->key)), 6584 ARGS_ENTRY_ARB 6585 (offsetof(struct action_rss_data, conf) + 6586 offsetof(struct rte_flow_action_rss, key_len), 6587 sizeof(((struct rte_flow_action_rss *)0)-> 6588 key_len)), 6589 ARGS_ENTRY(struct action_rss_data, key)), 6590 }, 6591 [ACTION_RSS_KEY_LEN] = { 6592 .name = "key_len", 6593 .help = "RSS hash key length in bytes", 6594 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6595 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6596 (offsetof(struct action_rss_data, conf) + 6597 offsetof(struct rte_flow_action_rss, key_len), 6598 sizeof(((struct rte_flow_action_rss *)0)-> 6599 key_len), 6600 0, 6601 RSS_HASH_KEY_LENGTH)), 6602 }, 6603 [ACTION_RSS_QUEUES] = { 6604 .name = "queues", 6605 .help = "queue indices to use", 6606 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 6607 .call = parse_vc_conf, 6608 }, 6609 [ACTION_RSS_QUEUE] = { 6610 .name = "{queue}", 6611 .help = "queue index", 6612 .call = parse_vc_action_rss_queue, 6613 .comp = comp_vc_action_rss_queue, 6614 }, 6615 [ACTION_PF] = { 6616 .name = "pf", 6617 .help = "direct traffic to physical function", 6618 .priv = PRIV_ACTION(PF, 0), 6619 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6620 .call = parse_vc, 6621 }, 6622 [ACTION_VF] = { 6623 .name = "vf", 6624 .help = "direct traffic to a virtual function ID", 6625 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 6626 .next = NEXT(action_vf), 6627 .call = parse_vc, 6628 }, 6629 [ACTION_VF_ORIGINAL] = { 6630 .name = "original", 6631 .help = "use original VF ID if possible", 6632 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 6633 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 6634 original, 1)), 6635 .call = parse_vc_conf, 6636 }, 6637 [ACTION_VF_ID] = { 6638 .name = "id", 6639 .help = "VF ID", 6640 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 6641 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 6642 .call = parse_vc_conf, 6643 }, 6644 [ACTION_PORT_ID] = { 6645 .name = "port_id", 6646 .help = "direct matching traffic to a given DPDK port ID", 6647 .priv = PRIV_ACTION(PORT_ID, 6648 sizeof(struct rte_flow_action_port_id)), 6649 .next = NEXT(action_port_id), 6650 .call = parse_vc, 6651 }, 6652 [ACTION_PORT_ID_ORIGINAL] = { 6653 .name = "original", 6654 .help = "use original DPDK port ID if possible", 6655 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 6656 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 6657 original, 1)), 6658 .call = parse_vc_conf, 6659 }, 6660 [ACTION_PORT_ID_ID] = { 6661 .name = "id", 6662 .help = "DPDK port ID", 6663 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 6664 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 6665 .call = parse_vc_conf, 6666 }, 6667 [ACTION_METER] = { 6668 .name = "meter", 6669 .help = "meter the directed packets at given id", 6670 .priv = PRIV_ACTION(METER, 6671 sizeof(struct rte_flow_action_meter)), 6672 .next = NEXT(action_meter), 6673 .call = parse_vc, 6674 }, 6675 [ACTION_METER_COLOR] = { 6676 .name = "color", 6677 .help = "meter color for the packets", 6678 .priv = PRIV_ACTION(METER_COLOR, 6679 sizeof(struct rte_flow_action_meter_color)), 6680 .next = NEXT(action_meter_color), 6681 .call = parse_vc, 6682 }, 6683 [ACTION_METER_COLOR_TYPE] = { 6684 .name = "type", 6685 .help = "specific meter color", 6686 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6687 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 6688 ACTION_METER_COLOR_YELLOW, 6689 ACTION_METER_COLOR_RED)), 6690 }, 6691 [ACTION_METER_COLOR_GREEN] = { 6692 .name = "green", 6693 .help = "meter color green", 6694 .call = parse_vc_action_meter_color_type, 6695 }, 6696 [ACTION_METER_COLOR_YELLOW] = { 6697 .name = "yellow", 6698 .help = "meter color yellow", 6699 .call = parse_vc_action_meter_color_type, 6700 }, 6701 [ACTION_METER_COLOR_RED] = { 6702 .name = "red", 6703 .help = "meter color red", 6704 .call = parse_vc_action_meter_color_type, 6705 }, 6706 [ACTION_METER_ID] = { 6707 .name = "mtr_id", 6708 .help = "meter id to use", 6709 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 6710 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 6711 .call = parse_vc_conf, 6712 }, 6713 [ACTION_METER_MARK] = { 6714 .name = "meter_mark", 6715 .help = "meter the directed packets using profile and policy", 6716 .priv = PRIV_ACTION(METER_MARK, 6717 sizeof(struct rte_flow_action_meter_mark)), 6718 .next = NEXT(action_meter_mark), 6719 .call = parse_vc, 6720 }, 6721 [ACTION_METER_PROFILE] = { 6722 .name = "mtr_profile", 6723 .help = "meter profile id to use", 6724 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 6725 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6726 }, 6727 [ACTION_METER_PROFILE_ID2PTR] = { 6728 .name = "{mtr_profile_id}", 6729 .type = "PROFILE_ID", 6730 .help = "meter profile id", 6731 .next = NEXT(action_meter_mark), 6732 .call = parse_meter_profile_id2ptr, 6733 .comp = comp_none, 6734 }, 6735 [ACTION_METER_POLICY] = { 6736 .name = "mtr_policy", 6737 .help = "meter policy id to use", 6738 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 6739 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6740 }, 6741 [ACTION_METER_POLICY_ID2PTR] = { 6742 .name = "{mtr_policy_id}", 6743 .type = "POLICY_ID", 6744 .help = "meter policy id", 6745 .next = NEXT(action_meter_mark), 6746 .call = parse_meter_policy_id2ptr, 6747 .comp = comp_none, 6748 }, 6749 [ACTION_METER_COLOR_MODE] = { 6750 .name = "mtr_color_mode", 6751 .help = "meter color awareness mode", 6752 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6753 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 6754 .call = parse_vc_conf, 6755 }, 6756 [ACTION_METER_STATE] = { 6757 .name = "mtr_state", 6758 .help = "meter state", 6759 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6760 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 6761 .call = parse_vc_conf, 6762 }, 6763 [ACTION_OF_DEC_NW_TTL] = { 6764 .name = "of_dec_nw_ttl", 6765 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 6766 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 6767 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6768 .call = parse_vc, 6769 }, 6770 [ACTION_OF_POP_VLAN] = { 6771 .name = "of_pop_vlan", 6772 .help = "OpenFlow's OFPAT_POP_VLAN", 6773 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 6774 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6775 .call = parse_vc, 6776 }, 6777 [ACTION_OF_PUSH_VLAN] = { 6778 .name = "of_push_vlan", 6779 .help = "OpenFlow's OFPAT_PUSH_VLAN", 6780 .priv = PRIV_ACTION 6781 (OF_PUSH_VLAN, 6782 sizeof(struct rte_flow_action_of_push_vlan)), 6783 .next = NEXT(action_of_push_vlan), 6784 .call = parse_vc, 6785 }, 6786 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 6787 .name = "ethertype", 6788 .help = "EtherType", 6789 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 6790 .args = ARGS(ARGS_ENTRY_HTON 6791 (struct rte_flow_action_of_push_vlan, 6792 ethertype)), 6793 .call = parse_vc_conf, 6794 }, 6795 [ACTION_OF_SET_VLAN_VID] = { 6796 .name = "of_set_vlan_vid", 6797 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 6798 .priv = PRIV_ACTION 6799 (OF_SET_VLAN_VID, 6800 sizeof(struct rte_flow_action_of_set_vlan_vid)), 6801 .next = NEXT(action_of_set_vlan_vid), 6802 .call = parse_vc, 6803 }, 6804 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 6805 .name = "vlan_vid", 6806 .help = "VLAN id", 6807 .next = NEXT(action_of_set_vlan_vid, 6808 NEXT_ENTRY(COMMON_UNSIGNED)), 6809 .args = ARGS(ARGS_ENTRY_HTON 6810 (struct rte_flow_action_of_set_vlan_vid, 6811 vlan_vid)), 6812 .call = parse_vc_conf, 6813 }, 6814 [ACTION_OF_SET_VLAN_PCP] = { 6815 .name = "of_set_vlan_pcp", 6816 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 6817 .priv = PRIV_ACTION 6818 (OF_SET_VLAN_PCP, 6819 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 6820 .next = NEXT(action_of_set_vlan_pcp), 6821 .call = parse_vc, 6822 }, 6823 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 6824 .name = "vlan_pcp", 6825 .help = "VLAN priority", 6826 .next = NEXT(action_of_set_vlan_pcp, 6827 NEXT_ENTRY(COMMON_UNSIGNED)), 6828 .args = ARGS(ARGS_ENTRY_HTON 6829 (struct rte_flow_action_of_set_vlan_pcp, 6830 vlan_pcp)), 6831 .call = parse_vc_conf, 6832 }, 6833 [ACTION_OF_POP_MPLS] = { 6834 .name = "of_pop_mpls", 6835 .help = "OpenFlow's OFPAT_POP_MPLS", 6836 .priv = PRIV_ACTION(OF_POP_MPLS, 6837 sizeof(struct rte_flow_action_of_pop_mpls)), 6838 .next = NEXT(action_of_pop_mpls), 6839 .call = parse_vc, 6840 }, 6841 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 6842 .name = "ethertype", 6843 .help = "EtherType", 6844 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6845 .args = ARGS(ARGS_ENTRY_HTON 6846 (struct rte_flow_action_of_pop_mpls, 6847 ethertype)), 6848 .call = parse_vc_conf, 6849 }, 6850 [ACTION_OF_PUSH_MPLS] = { 6851 .name = "of_push_mpls", 6852 .help = "OpenFlow's OFPAT_PUSH_MPLS", 6853 .priv = PRIV_ACTION 6854 (OF_PUSH_MPLS, 6855 sizeof(struct rte_flow_action_of_push_mpls)), 6856 .next = NEXT(action_of_push_mpls), 6857 .call = parse_vc, 6858 }, 6859 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 6860 .name = "ethertype", 6861 .help = "EtherType", 6862 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6863 .args = ARGS(ARGS_ENTRY_HTON 6864 (struct rte_flow_action_of_push_mpls, 6865 ethertype)), 6866 .call = parse_vc_conf, 6867 }, 6868 [ACTION_VXLAN_ENCAP] = { 6869 .name = "vxlan_encap", 6870 .help = "VXLAN encapsulation, uses configuration set by \"set" 6871 " vxlan\"", 6872 .priv = PRIV_ACTION(VXLAN_ENCAP, 6873 sizeof(struct action_vxlan_encap_data)), 6874 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6875 .call = parse_vc_action_vxlan_encap, 6876 }, 6877 [ACTION_VXLAN_DECAP] = { 6878 .name = "vxlan_decap", 6879 .help = "Performs a decapsulation action by stripping all" 6880 " headers of the VXLAN tunnel network overlay from the" 6881 " matched flow.", 6882 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 6883 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6884 .call = parse_vc, 6885 }, 6886 [ACTION_NVGRE_ENCAP] = { 6887 .name = "nvgre_encap", 6888 .help = "NVGRE encapsulation, uses configuration set by \"set" 6889 " nvgre\"", 6890 .priv = PRIV_ACTION(NVGRE_ENCAP, 6891 sizeof(struct action_nvgre_encap_data)), 6892 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6893 .call = parse_vc_action_nvgre_encap, 6894 }, 6895 [ACTION_NVGRE_DECAP] = { 6896 .name = "nvgre_decap", 6897 .help = "Performs a decapsulation action by stripping all" 6898 " headers of the NVGRE tunnel network overlay from the" 6899 " matched flow.", 6900 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 6901 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6902 .call = parse_vc, 6903 }, 6904 [ACTION_L2_ENCAP] = { 6905 .name = "l2_encap", 6906 .help = "l2 encap, uses configuration set by" 6907 " \"set l2_encap\"", 6908 .priv = PRIV_ACTION(RAW_ENCAP, 6909 sizeof(struct action_raw_encap_data)), 6910 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6911 .call = parse_vc_action_l2_encap, 6912 }, 6913 [ACTION_L2_DECAP] = { 6914 .name = "l2_decap", 6915 .help = "l2 decap, uses configuration set by" 6916 " \"set l2_decap\"", 6917 .priv = PRIV_ACTION(RAW_DECAP, 6918 sizeof(struct action_raw_decap_data)), 6919 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6920 .call = parse_vc_action_l2_decap, 6921 }, 6922 [ACTION_MPLSOGRE_ENCAP] = { 6923 .name = "mplsogre_encap", 6924 .help = "mplsogre encapsulation, uses configuration set by" 6925 " \"set mplsogre_encap\"", 6926 .priv = PRIV_ACTION(RAW_ENCAP, 6927 sizeof(struct action_raw_encap_data)), 6928 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6929 .call = parse_vc_action_mplsogre_encap, 6930 }, 6931 [ACTION_MPLSOGRE_DECAP] = { 6932 .name = "mplsogre_decap", 6933 .help = "mplsogre decapsulation, uses configuration set by" 6934 " \"set mplsogre_decap\"", 6935 .priv = PRIV_ACTION(RAW_DECAP, 6936 sizeof(struct action_raw_decap_data)), 6937 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6938 .call = parse_vc_action_mplsogre_decap, 6939 }, 6940 [ACTION_MPLSOUDP_ENCAP] = { 6941 .name = "mplsoudp_encap", 6942 .help = "mplsoudp encapsulation, uses configuration set by" 6943 " \"set mplsoudp_encap\"", 6944 .priv = PRIV_ACTION(RAW_ENCAP, 6945 sizeof(struct action_raw_encap_data)), 6946 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6947 .call = parse_vc_action_mplsoudp_encap, 6948 }, 6949 [ACTION_MPLSOUDP_DECAP] = { 6950 .name = "mplsoudp_decap", 6951 .help = "mplsoudp decapsulation, uses configuration set by" 6952 " \"set mplsoudp_decap\"", 6953 .priv = PRIV_ACTION(RAW_DECAP, 6954 sizeof(struct action_raw_decap_data)), 6955 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6956 .call = parse_vc_action_mplsoudp_decap, 6957 }, 6958 [ACTION_SET_IPV4_SRC] = { 6959 .name = "set_ipv4_src", 6960 .help = "Set a new IPv4 source address in the outermost" 6961 " IPv4 header", 6962 .priv = PRIV_ACTION(SET_IPV4_SRC, 6963 sizeof(struct rte_flow_action_set_ipv4)), 6964 .next = NEXT(action_set_ipv4_src), 6965 .call = parse_vc, 6966 }, 6967 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 6968 .name = "ipv4_addr", 6969 .help = "new IPv4 source address to set", 6970 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 6971 .args = ARGS(ARGS_ENTRY_HTON 6972 (struct rte_flow_action_set_ipv4, ipv4_addr)), 6973 .call = parse_vc_conf, 6974 }, 6975 [ACTION_SET_IPV4_DST] = { 6976 .name = "set_ipv4_dst", 6977 .help = "Set a new IPv4 destination address in the outermost" 6978 " IPv4 header", 6979 .priv = PRIV_ACTION(SET_IPV4_DST, 6980 sizeof(struct rte_flow_action_set_ipv4)), 6981 .next = NEXT(action_set_ipv4_dst), 6982 .call = parse_vc, 6983 }, 6984 [ACTION_SET_IPV4_DST_IPV4_DST] = { 6985 .name = "ipv4_addr", 6986 .help = "new IPv4 destination address to set", 6987 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 6988 .args = ARGS(ARGS_ENTRY_HTON 6989 (struct rte_flow_action_set_ipv4, ipv4_addr)), 6990 .call = parse_vc_conf, 6991 }, 6992 [ACTION_SET_IPV6_SRC] = { 6993 .name = "set_ipv6_src", 6994 .help = "Set a new IPv6 source address in the outermost" 6995 " IPv6 header", 6996 .priv = PRIV_ACTION(SET_IPV6_SRC, 6997 sizeof(struct rte_flow_action_set_ipv6)), 6998 .next = NEXT(action_set_ipv6_src), 6999 .call = parse_vc, 7000 }, 7001 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 7002 .name = "ipv6_addr", 7003 .help = "new IPv6 source address to set", 7004 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7005 .args = ARGS(ARGS_ENTRY_HTON 7006 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7007 .call = parse_vc_conf, 7008 }, 7009 [ACTION_SET_IPV6_DST] = { 7010 .name = "set_ipv6_dst", 7011 .help = "Set a new IPv6 destination address in the outermost" 7012 " IPv6 header", 7013 .priv = PRIV_ACTION(SET_IPV6_DST, 7014 sizeof(struct rte_flow_action_set_ipv6)), 7015 .next = NEXT(action_set_ipv6_dst), 7016 .call = parse_vc, 7017 }, 7018 [ACTION_SET_IPV6_DST_IPV6_DST] = { 7019 .name = "ipv6_addr", 7020 .help = "new IPv6 destination address to set", 7021 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7022 .args = ARGS(ARGS_ENTRY_HTON 7023 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7024 .call = parse_vc_conf, 7025 }, 7026 [ACTION_SET_TP_SRC] = { 7027 .name = "set_tp_src", 7028 .help = "set a new source port number in the outermost" 7029 " TCP/UDP header", 7030 .priv = PRIV_ACTION(SET_TP_SRC, 7031 sizeof(struct rte_flow_action_set_tp)), 7032 .next = NEXT(action_set_tp_src), 7033 .call = parse_vc, 7034 }, 7035 [ACTION_SET_TP_SRC_TP_SRC] = { 7036 .name = "port", 7037 .help = "new source port number to set", 7038 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 7039 .args = ARGS(ARGS_ENTRY_HTON 7040 (struct rte_flow_action_set_tp, port)), 7041 .call = parse_vc_conf, 7042 }, 7043 [ACTION_SET_TP_DST] = { 7044 .name = "set_tp_dst", 7045 .help = "set a new destination port number in the outermost" 7046 " TCP/UDP header", 7047 .priv = PRIV_ACTION(SET_TP_DST, 7048 sizeof(struct rte_flow_action_set_tp)), 7049 .next = NEXT(action_set_tp_dst), 7050 .call = parse_vc, 7051 }, 7052 [ACTION_SET_TP_DST_TP_DST] = { 7053 .name = "port", 7054 .help = "new destination port number to set", 7055 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 7056 .args = ARGS(ARGS_ENTRY_HTON 7057 (struct rte_flow_action_set_tp, port)), 7058 .call = parse_vc_conf, 7059 }, 7060 [ACTION_MAC_SWAP] = { 7061 .name = "mac_swap", 7062 .help = "Swap the source and destination MAC addresses" 7063 " in the outermost Ethernet header", 7064 .priv = PRIV_ACTION(MAC_SWAP, 0), 7065 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7066 .call = parse_vc, 7067 }, 7068 [ACTION_DEC_TTL] = { 7069 .name = "dec_ttl", 7070 .help = "decrease network TTL if available", 7071 .priv = PRIV_ACTION(DEC_TTL, 0), 7072 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7073 .call = parse_vc, 7074 }, 7075 [ACTION_SET_TTL] = { 7076 .name = "set_ttl", 7077 .help = "set ttl value", 7078 .priv = PRIV_ACTION(SET_TTL, 7079 sizeof(struct rte_flow_action_set_ttl)), 7080 .next = NEXT(action_set_ttl), 7081 .call = parse_vc, 7082 }, 7083 [ACTION_SET_TTL_TTL] = { 7084 .name = "ttl_value", 7085 .help = "new ttl value to set", 7086 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 7087 .args = ARGS(ARGS_ENTRY_HTON 7088 (struct rte_flow_action_set_ttl, ttl_value)), 7089 .call = parse_vc_conf, 7090 }, 7091 [ACTION_SET_MAC_SRC] = { 7092 .name = "set_mac_src", 7093 .help = "set source mac address", 7094 .priv = PRIV_ACTION(SET_MAC_SRC, 7095 sizeof(struct rte_flow_action_set_mac)), 7096 .next = NEXT(action_set_mac_src), 7097 .call = parse_vc, 7098 }, 7099 [ACTION_SET_MAC_SRC_MAC_SRC] = { 7100 .name = "mac_addr", 7101 .help = "new source mac address", 7102 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 7103 .args = ARGS(ARGS_ENTRY_HTON 7104 (struct rte_flow_action_set_mac, mac_addr)), 7105 .call = parse_vc_conf, 7106 }, 7107 [ACTION_SET_MAC_DST] = { 7108 .name = "set_mac_dst", 7109 .help = "set destination mac address", 7110 .priv = PRIV_ACTION(SET_MAC_DST, 7111 sizeof(struct rte_flow_action_set_mac)), 7112 .next = NEXT(action_set_mac_dst), 7113 .call = parse_vc, 7114 }, 7115 [ACTION_SET_MAC_DST_MAC_DST] = { 7116 .name = "mac_addr", 7117 .help = "new destination mac address to set", 7118 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 7119 .args = ARGS(ARGS_ENTRY_HTON 7120 (struct rte_flow_action_set_mac, mac_addr)), 7121 .call = parse_vc_conf, 7122 }, 7123 [ACTION_INC_TCP_SEQ] = { 7124 .name = "inc_tcp_seq", 7125 .help = "increase TCP sequence number", 7126 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 7127 .next = NEXT(action_inc_tcp_seq), 7128 .call = parse_vc, 7129 }, 7130 [ACTION_INC_TCP_SEQ_VALUE] = { 7131 .name = "value", 7132 .help = "the value to increase TCP sequence number by", 7133 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7134 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7135 .call = parse_vc_conf, 7136 }, 7137 [ACTION_DEC_TCP_SEQ] = { 7138 .name = "dec_tcp_seq", 7139 .help = "decrease TCP sequence number", 7140 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 7141 .next = NEXT(action_dec_tcp_seq), 7142 .call = parse_vc, 7143 }, 7144 [ACTION_DEC_TCP_SEQ_VALUE] = { 7145 .name = "value", 7146 .help = "the value to decrease TCP sequence number by", 7147 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7148 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7149 .call = parse_vc_conf, 7150 }, 7151 [ACTION_INC_TCP_ACK] = { 7152 .name = "inc_tcp_ack", 7153 .help = "increase TCP acknowledgment number", 7154 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 7155 .next = NEXT(action_inc_tcp_ack), 7156 .call = parse_vc, 7157 }, 7158 [ACTION_INC_TCP_ACK_VALUE] = { 7159 .name = "value", 7160 .help = "the value to increase TCP acknowledgment number by", 7161 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7162 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7163 .call = parse_vc_conf, 7164 }, 7165 [ACTION_DEC_TCP_ACK] = { 7166 .name = "dec_tcp_ack", 7167 .help = "decrease TCP acknowledgment number", 7168 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 7169 .next = NEXT(action_dec_tcp_ack), 7170 .call = parse_vc, 7171 }, 7172 [ACTION_DEC_TCP_ACK_VALUE] = { 7173 .name = "value", 7174 .help = "the value to decrease TCP acknowledgment number by", 7175 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7176 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7177 .call = parse_vc_conf, 7178 }, 7179 [ACTION_RAW_ENCAP] = { 7180 .name = "raw_encap", 7181 .help = "encapsulation data, defined by set raw_encap", 7182 .priv = PRIV_ACTION(RAW_ENCAP, 7183 sizeof(struct action_raw_encap_data)), 7184 .next = NEXT(action_raw_encap), 7185 .call = parse_vc_action_raw_encap, 7186 }, 7187 [ACTION_RAW_ENCAP_SIZE] = { 7188 .name = "size", 7189 .help = "raw encap size", 7190 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7191 NEXT_ENTRY(COMMON_UNSIGNED)), 7192 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_raw_encap, size)), 7193 .call = parse_vc_conf, 7194 }, 7195 [ACTION_RAW_ENCAP_INDEX] = { 7196 .name = "index", 7197 .help = "the index of raw_encap_confs", 7198 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 7199 }, 7200 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 7201 .name = "{index}", 7202 .type = "UNSIGNED", 7203 .help = "unsigned integer value", 7204 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7205 .call = parse_vc_action_raw_encap_index, 7206 .comp = comp_set_raw_index, 7207 }, 7208 [ACTION_RAW_DECAP] = { 7209 .name = "raw_decap", 7210 .help = "decapsulation data, defined by set raw_encap", 7211 .priv = PRIV_ACTION(RAW_DECAP, 7212 sizeof(struct action_raw_decap_data)), 7213 .next = NEXT(action_raw_decap), 7214 .call = parse_vc_action_raw_decap, 7215 }, 7216 [ACTION_RAW_DECAP_INDEX] = { 7217 .name = "index", 7218 .help = "the index of raw_encap_confs", 7219 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 7220 }, 7221 [ACTION_RAW_DECAP_INDEX_VALUE] = { 7222 .name = "{index}", 7223 .type = "UNSIGNED", 7224 .help = "unsigned integer value", 7225 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7226 .call = parse_vc_action_raw_decap_index, 7227 .comp = comp_set_raw_index, 7228 }, 7229 [ACTION_MODIFY_FIELD] = { 7230 .name = "modify_field", 7231 .help = "modify destination field with data from source field", 7232 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 7233 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 7234 .call = parse_vc, 7235 }, 7236 [ACTION_MODIFY_FIELD_OP] = { 7237 .name = "op", 7238 .help = "operation type", 7239 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 7240 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 7241 .call = parse_vc_conf, 7242 }, 7243 [ACTION_MODIFY_FIELD_OP_VALUE] = { 7244 .name = "{operation}", 7245 .help = "operation type value", 7246 .call = parse_vc_modify_field_op, 7247 .comp = comp_set_modify_field_op, 7248 }, 7249 [ACTION_MODIFY_FIELD_DST_TYPE] = { 7250 .name = "dst_type", 7251 .help = "destination field type", 7252 .next = NEXT(action_modify_field_dst, 7253 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 7254 .call = parse_vc_conf, 7255 }, 7256 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 7257 .name = "{dst_type}", 7258 .help = "destination field type value", 7259 .call = parse_vc_modify_field_id, 7260 .comp = comp_set_modify_field_id, 7261 }, 7262 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 7263 .name = "dst_level", 7264 .help = "destination field level", 7265 .next = NEXT(action_modify_field_dst, 7266 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), 7267 .call = parse_vc_conf, 7268 }, 7269 [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { 7270 .name = "{dst_level}", 7271 .help = "destination field level value", 7272 .call = parse_vc_modify_field_level, 7273 .comp = comp_none, 7274 }, 7275 [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { 7276 .name = "dst_tag_index", 7277 .help = "destination field tag array", 7278 .next = NEXT(action_modify_field_dst, 7279 NEXT_ENTRY(COMMON_UNSIGNED)), 7280 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7281 dst.tag_index)), 7282 .call = parse_vc_conf, 7283 }, 7284 [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { 7285 .name = "dst_type_id", 7286 .help = "destination field type ID", 7287 .next = NEXT(action_modify_field_dst, 7288 NEXT_ENTRY(COMMON_UNSIGNED)), 7289 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7290 dst.type)), 7291 .call = parse_vc_conf, 7292 }, 7293 [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { 7294 .name = "dst_class", 7295 .help = "destination field class ID", 7296 .next = NEXT(action_modify_field_dst, 7297 NEXT_ENTRY(COMMON_UNSIGNED)), 7298 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7299 dst.class_id)), 7300 .call = parse_vc_conf, 7301 }, 7302 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 7303 .name = "dst_offset", 7304 .help = "destination field bit offset", 7305 .next = NEXT(action_modify_field_dst, 7306 NEXT_ENTRY(COMMON_UNSIGNED)), 7307 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7308 dst.offset)), 7309 .call = parse_vc_conf, 7310 }, 7311 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 7312 .name = "src_type", 7313 .help = "source field type", 7314 .next = NEXT(action_modify_field_src, 7315 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 7316 .call = parse_vc_conf, 7317 }, 7318 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 7319 .name = "{src_type}", 7320 .help = "source field type value", 7321 .call = parse_vc_modify_field_id, 7322 .comp = comp_set_modify_field_id, 7323 }, 7324 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 7325 .name = "src_level", 7326 .help = "source field level", 7327 .next = NEXT(action_modify_field_src, 7328 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), 7329 .call = parse_vc_conf, 7330 }, 7331 [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { 7332 .name = "{src_level}", 7333 .help = "source field level value", 7334 .call = parse_vc_modify_field_level, 7335 .comp = comp_none, 7336 }, 7337 [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { 7338 .name = "src_tag_index", 7339 .help = "source field tag array", 7340 .next = NEXT(action_modify_field_src, 7341 NEXT_ENTRY(COMMON_UNSIGNED)), 7342 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7343 src.tag_index)), 7344 .call = parse_vc_conf, 7345 }, 7346 [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { 7347 .name = "src_type_id", 7348 .help = "source field type ID", 7349 .next = NEXT(action_modify_field_src, 7350 NEXT_ENTRY(COMMON_UNSIGNED)), 7351 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7352 src.type)), 7353 .call = parse_vc_conf, 7354 }, 7355 [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { 7356 .name = "src_class", 7357 .help = "source field class ID", 7358 .next = NEXT(action_modify_field_src, 7359 NEXT_ENTRY(COMMON_UNSIGNED)), 7360 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7361 src.class_id)), 7362 .call = parse_vc_conf, 7363 }, 7364 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 7365 .name = "src_offset", 7366 .help = "source field bit offset", 7367 .next = NEXT(action_modify_field_src, 7368 NEXT_ENTRY(COMMON_UNSIGNED)), 7369 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7370 src.offset)), 7371 .call = parse_vc_conf, 7372 }, 7373 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 7374 .name = "src_value", 7375 .help = "source immediate value", 7376 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7377 NEXT_ENTRY(COMMON_HEX)), 7378 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 7379 ARGS_ENTRY_ARB(0, 0), 7380 ARGS_ENTRY(struct rte_flow_action_modify_field, 7381 src.value)), 7382 .call = parse_vc_conf, 7383 }, 7384 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 7385 .name = "src_ptr", 7386 .help = "pointer to source immediate value", 7387 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7388 NEXT_ENTRY(COMMON_HEX)), 7389 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7390 src.pvalue), 7391 ARGS_ENTRY_ARB(0, 0), 7392 ARGS_ENTRY_ARB 7393 (sizeof(struct rte_flow_action_modify_field), 7394 FLOW_FIELD_PATTERN_SIZE)), 7395 .call = parse_vc_conf, 7396 }, 7397 [ACTION_MODIFY_FIELD_WIDTH] = { 7398 .name = "width", 7399 .help = "number of bits to copy", 7400 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7401 NEXT_ENTRY(COMMON_UNSIGNED)), 7402 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7403 width)), 7404 .call = parse_vc_conf, 7405 }, 7406 [ACTION_SEND_TO_KERNEL] = { 7407 .name = "send_to_kernel", 7408 .help = "send packets to kernel", 7409 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 7410 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7411 .call = parse_vc, 7412 }, 7413 [ACTION_IPV6_EXT_REMOVE] = { 7414 .name = "ipv6_ext_remove", 7415 .help = "IPv6 extension type, defined by set ipv6_ext_remove", 7416 .priv = PRIV_ACTION(IPV6_EXT_REMOVE, 7417 sizeof(struct action_ipv6_ext_remove_data)), 7418 .next = NEXT(action_ipv6_ext_remove), 7419 .call = parse_vc_action_ipv6_ext_remove, 7420 }, 7421 [ACTION_IPV6_EXT_REMOVE_INDEX] = { 7422 .name = "index", 7423 .help = "the index of ipv6_ext_remove", 7424 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), 7425 }, 7426 [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { 7427 .name = "{index}", 7428 .type = "UNSIGNED", 7429 .help = "unsigned integer value", 7430 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7431 .call = parse_vc_action_ipv6_ext_remove_index, 7432 .comp = comp_set_ipv6_ext_index, 7433 }, 7434 [ACTION_IPV6_EXT_PUSH] = { 7435 .name = "ipv6_ext_push", 7436 .help = "IPv6 extension data, defined by set ipv6_ext_push", 7437 .priv = PRIV_ACTION(IPV6_EXT_PUSH, 7438 sizeof(struct action_ipv6_ext_push_data)), 7439 .next = NEXT(action_ipv6_ext_push), 7440 .call = parse_vc_action_ipv6_ext_push, 7441 }, 7442 [ACTION_IPV6_EXT_PUSH_INDEX] = { 7443 .name = "index", 7444 .help = "the index of ipv6_ext_push", 7445 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), 7446 }, 7447 [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { 7448 .name = "{index}", 7449 .type = "UNSIGNED", 7450 .help = "unsigned integer value", 7451 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7452 .call = parse_vc_action_ipv6_ext_push_index, 7453 .comp = comp_set_ipv6_ext_index, 7454 }, 7455 [ACTION_NAT64] = { 7456 .name = "nat64", 7457 .help = "NAT64 IP headers translation", 7458 .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), 7459 .next = NEXT(action_nat64), 7460 .call = parse_vc, 7461 }, 7462 [ACTION_NAT64_MODE] = { 7463 .name = "type", 7464 .help = "NAT64 translation type", 7465 .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), 7466 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), 7467 .call = parse_vc_conf, 7468 }, 7469 /* Top level command. */ 7470 [SET] = { 7471 .name = "set", 7472 .help = "set raw encap/decap/sample data", 7473 .type = "set raw_encap|raw_decap <index> <pattern>" 7474 " or set sample_actions <index> <action>", 7475 .next = NEXT(NEXT_ENTRY 7476 (SET_RAW_ENCAP, 7477 SET_RAW_DECAP, 7478 SET_SAMPLE_ACTIONS, 7479 SET_IPV6_EXT_REMOVE, 7480 SET_IPV6_EXT_PUSH)), 7481 .call = parse_set_init, 7482 }, 7483 /* Sub-level commands. */ 7484 [SET_RAW_ENCAP] = { 7485 .name = "raw_encap", 7486 .help = "set raw encap data", 7487 .next = NEXT(next_set_raw), 7488 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7489 (offsetof(struct buffer, port), 7490 sizeof(((struct buffer *)0)->port), 7491 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7492 .call = parse_set_raw_encap_decap, 7493 }, 7494 [SET_RAW_DECAP] = { 7495 .name = "raw_decap", 7496 .help = "set raw decap data", 7497 .next = NEXT(next_set_raw), 7498 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7499 (offsetof(struct buffer, port), 7500 sizeof(((struct buffer *)0)->port), 7501 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7502 .call = parse_set_raw_encap_decap, 7503 }, 7504 [SET_RAW_INDEX] = { 7505 .name = "{index}", 7506 .type = "COMMON_UNSIGNED", 7507 .help = "index of raw_encap/raw_decap data", 7508 .next = NEXT(next_item), 7509 .call = parse_port, 7510 }, 7511 [SET_SAMPLE_INDEX] = { 7512 .name = "{index}", 7513 .type = "UNSIGNED", 7514 .help = "index of sample actions", 7515 .next = NEXT(next_action_sample), 7516 .call = parse_port, 7517 }, 7518 [SET_SAMPLE_ACTIONS] = { 7519 .name = "sample_actions", 7520 .help = "set sample actions list", 7521 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 7522 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7523 (offsetof(struct buffer, port), 7524 sizeof(((struct buffer *)0)->port), 7525 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 7526 .call = parse_set_sample_action, 7527 }, 7528 [SET_IPV6_EXT_PUSH] = { 7529 .name = "ipv6_ext_push", 7530 .help = "set IPv6 extension header", 7531 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7532 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7533 (offsetof(struct buffer, port), 7534 sizeof(((struct buffer *)0)->port), 7535 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7536 .call = parse_set_ipv6_ext_action, 7537 }, 7538 [SET_IPV6_EXT_REMOVE] = { 7539 .name = "ipv6_ext_remove", 7540 .help = "set IPv6 extension header", 7541 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7542 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7543 (offsetof(struct buffer, port), 7544 sizeof(((struct buffer *)0)->port), 7545 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7546 .call = parse_set_ipv6_ext_action, 7547 }, 7548 [SET_IPV6_EXT_INDEX] = { 7549 .name = "{index}", 7550 .type = "UNSIGNED", 7551 .help = "index of ipv6 extension push/remove actions", 7552 .next = NEXT(item_ipv6_push_ext), 7553 .call = parse_port, 7554 }, 7555 [ITEM_IPV6_PUSH_REMOVE_EXT] = { 7556 .name = "ipv6_ext", 7557 .help = "set IPv6 extension header", 7558 .priv = PRIV_ITEM(IPV6_EXT, 7559 sizeof(struct rte_flow_item_ipv6_ext)), 7560 .next = NEXT(item_ipv6_push_ext_type), 7561 .call = parse_vc, 7562 }, 7563 [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { 7564 .name = "type", 7565 .help = "set IPv6 extension type", 7566 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 7567 next_hdr)), 7568 .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), 7569 item_param), 7570 }, 7571 [ACTION_SET_TAG] = { 7572 .name = "set_tag", 7573 .help = "set tag", 7574 .priv = PRIV_ACTION(SET_TAG, 7575 sizeof(struct rte_flow_action_set_tag)), 7576 .next = NEXT(action_set_tag), 7577 .call = parse_vc, 7578 }, 7579 [ACTION_SET_TAG_INDEX] = { 7580 .name = "index", 7581 .help = "index of tag array", 7582 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7583 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 7584 .call = parse_vc_conf, 7585 }, 7586 [ACTION_SET_TAG_DATA] = { 7587 .name = "data", 7588 .help = "tag value", 7589 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7590 .args = ARGS(ARGS_ENTRY 7591 (struct rte_flow_action_set_tag, data)), 7592 .call = parse_vc_conf, 7593 }, 7594 [ACTION_SET_TAG_MASK] = { 7595 .name = "mask", 7596 .help = "mask for tag value", 7597 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7598 .args = ARGS(ARGS_ENTRY 7599 (struct rte_flow_action_set_tag, mask)), 7600 .call = parse_vc_conf, 7601 }, 7602 [ACTION_SET_META] = { 7603 .name = "set_meta", 7604 .help = "set metadata", 7605 .priv = PRIV_ACTION(SET_META, 7606 sizeof(struct rte_flow_action_set_meta)), 7607 .next = NEXT(action_set_meta), 7608 .call = parse_vc_action_set_meta, 7609 }, 7610 [ACTION_SET_META_DATA] = { 7611 .name = "data", 7612 .help = "metadata value", 7613 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7614 .args = ARGS(ARGS_ENTRY 7615 (struct rte_flow_action_set_meta, data)), 7616 .call = parse_vc_conf, 7617 }, 7618 [ACTION_SET_META_MASK] = { 7619 .name = "mask", 7620 .help = "mask for metadata value", 7621 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7622 .args = ARGS(ARGS_ENTRY 7623 (struct rte_flow_action_set_meta, mask)), 7624 .call = parse_vc_conf, 7625 }, 7626 [ACTION_SET_IPV4_DSCP] = { 7627 .name = "set_ipv4_dscp", 7628 .help = "set DSCP value", 7629 .priv = PRIV_ACTION(SET_IPV4_DSCP, 7630 sizeof(struct rte_flow_action_set_dscp)), 7631 .next = NEXT(action_set_ipv4_dscp), 7632 .call = parse_vc, 7633 }, 7634 [ACTION_SET_IPV4_DSCP_VALUE] = { 7635 .name = "dscp_value", 7636 .help = "new IPv4 DSCP value to set", 7637 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7638 .args = ARGS(ARGS_ENTRY 7639 (struct rte_flow_action_set_dscp, dscp)), 7640 .call = parse_vc_conf, 7641 }, 7642 [ACTION_SET_IPV6_DSCP] = { 7643 .name = "set_ipv6_dscp", 7644 .help = "set DSCP value", 7645 .priv = PRIV_ACTION(SET_IPV6_DSCP, 7646 sizeof(struct rte_flow_action_set_dscp)), 7647 .next = NEXT(action_set_ipv6_dscp), 7648 .call = parse_vc, 7649 }, 7650 [ACTION_SET_IPV6_DSCP_VALUE] = { 7651 .name = "dscp_value", 7652 .help = "new IPv6 DSCP value to set", 7653 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7654 .args = ARGS(ARGS_ENTRY 7655 (struct rte_flow_action_set_dscp, dscp)), 7656 .call = parse_vc_conf, 7657 }, 7658 [ACTION_AGE] = { 7659 .name = "age", 7660 .help = "set a specific metadata header", 7661 .next = NEXT(action_age), 7662 .priv = PRIV_ACTION(AGE, 7663 sizeof(struct rte_flow_action_age)), 7664 .call = parse_vc, 7665 }, 7666 [ACTION_AGE_TIMEOUT] = { 7667 .name = "timeout", 7668 .help = "flow age timeout value", 7669 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 7670 timeout, 24)), 7671 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 7672 .call = parse_vc_conf, 7673 }, 7674 [ACTION_AGE_UPDATE] = { 7675 .name = "age_update", 7676 .help = "update aging parameter", 7677 .next = NEXT(action_age_update), 7678 .priv = PRIV_ACTION(AGE, 7679 sizeof(struct rte_flow_update_age)), 7680 .call = parse_vc, 7681 }, 7682 [ACTION_AGE_UPDATE_TIMEOUT] = { 7683 .name = "timeout", 7684 .help = "age timeout update value", 7685 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7686 timeout, 24)), 7687 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7688 .call = parse_vc_conf_timeout, 7689 }, 7690 [ACTION_AGE_UPDATE_TOUCH] = { 7691 .name = "touch", 7692 .help = "this flow is touched", 7693 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), 7694 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7695 touch, 1)), 7696 .call = parse_vc_conf, 7697 }, 7698 [ACTION_SAMPLE] = { 7699 .name = "sample", 7700 .help = "set a sample action", 7701 .next = NEXT(action_sample), 7702 .priv = PRIV_ACTION(SAMPLE, 7703 sizeof(struct action_sample_data)), 7704 .call = parse_vc_action_sample, 7705 }, 7706 [ACTION_SAMPLE_RATIO] = { 7707 .name = "ratio", 7708 .help = "flow sample ratio value", 7709 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 7710 .args = ARGS(ARGS_ENTRY_ARB 7711 (offsetof(struct action_sample_data, conf) + 7712 offsetof(struct rte_flow_action_sample, ratio), 7713 sizeof(((struct rte_flow_action_sample *)0)-> 7714 ratio))), 7715 }, 7716 [ACTION_SAMPLE_INDEX] = { 7717 .name = "index", 7718 .help = "the index of sample actions list", 7719 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 7720 }, 7721 [ACTION_SAMPLE_INDEX_VALUE] = { 7722 .name = "{index}", 7723 .type = "COMMON_UNSIGNED", 7724 .help = "unsigned integer value", 7725 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7726 .call = parse_vc_action_sample_index, 7727 .comp = comp_set_sample_index, 7728 }, 7729 [ACTION_CONNTRACK] = { 7730 .name = "conntrack", 7731 .help = "create a conntrack object", 7732 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7733 .priv = PRIV_ACTION(CONNTRACK, 7734 sizeof(struct rte_flow_action_conntrack)), 7735 .call = parse_vc, 7736 }, 7737 [ACTION_CONNTRACK_UPDATE] = { 7738 .name = "conntrack_update", 7739 .help = "update a conntrack object", 7740 .next = NEXT(action_update_conntrack), 7741 .priv = PRIV_ACTION(CONNTRACK, 7742 sizeof(struct rte_flow_modify_conntrack)), 7743 .call = parse_vc, 7744 }, 7745 [ACTION_CONNTRACK_UPDATE_DIR] = { 7746 .name = "dir", 7747 .help = "update a conntrack object direction", 7748 .next = NEXT(action_update_conntrack), 7749 .call = parse_vc_action_conntrack_update, 7750 }, 7751 [ACTION_CONNTRACK_UPDATE_CTX] = { 7752 .name = "ctx", 7753 .help = "update a conntrack object context", 7754 .next = NEXT(action_update_conntrack), 7755 .call = parse_vc_action_conntrack_update, 7756 }, 7757 [ACTION_PORT_REPRESENTOR] = { 7758 .name = "port_representor", 7759 .help = "at embedded switch level, send matching traffic to the given ethdev", 7760 .priv = PRIV_ACTION(PORT_REPRESENTOR, 7761 sizeof(struct rte_flow_action_ethdev)), 7762 .next = NEXT(action_port_representor), 7763 .call = parse_vc, 7764 }, 7765 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 7766 .name = "port_id", 7767 .help = "ethdev port ID", 7768 .next = NEXT(action_port_representor, 7769 NEXT_ENTRY(COMMON_UNSIGNED)), 7770 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7771 port_id)), 7772 .call = parse_vc_conf, 7773 }, 7774 [ACTION_REPRESENTED_PORT] = { 7775 .name = "represented_port", 7776 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 7777 .priv = PRIV_ACTION(REPRESENTED_PORT, 7778 sizeof(struct rte_flow_action_ethdev)), 7779 .next = NEXT(action_represented_port), 7780 .call = parse_vc, 7781 }, 7782 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 7783 .name = "ethdev_port_id", 7784 .help = "ethdev port ID", 7785 .next = NEXT(action_represented_port, 7786 NEXT_ENTRY(COMMON_UNSIGNED)), 7787 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7788 port_id)), 7789 .call = parse_vc_conf, 7790 }, 7791 /* Indirect action destroy arguments. */ 7792 [INDIRECT_ACTION_DESTROY_ID] = { 7793 .name = "action_id", 7794 .help = "specify a indirect action id to destroy", 7795 .next = NEXT(next_ia_destroy_attr, 7796 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7797 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 7798 args.ia_destroy.action_id)), 7799 .call = parse_ia_destroy, 7800 }, 7801 /* Indirect action create arguments. */ 7802 [INDIRECT_ACTION_CREATE_ID] = { 7803 .name = "action_id", 7804 .help = "specify a indirect action id to create", 7805 .next = NEXT(next_ia_create_attr, 7806 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7807 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 7808 }, 7809 [ACTION_INDIRECT] = { 7810 .name = "indirect", 7811 .help = "apply indirect action by id", 7812 .priv = PRIV_ACTION(INDIRECT, 0), 7813 .next = NEXT(next_ia), 7814 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7815 .call = parse_vc, 7816 }, 7817 [ACTION_INDIRECT_LIST] = { 7818 .name = "indirect_list", 7819 .help = "apply indirect list action by id", 7820 .priv = PRIV_ACTION(INDIRECT_LIST, 7821 sizeof(struct 7822 rte_flow_action_indirect_list)), 7823 .next = NEXT(next_ial), 7824 .call = parse_vc, 7825 }, 7826 [ACTION_INDIRECT_LIST_HANDLE] = { 7827 .name = "handle", 7828 .help = "indirect list handle", 7829 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), 7830 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7831 }, 7832 [ACTION_INDIRECT_LIST_CONF] = { 7833 .name = "conf", 7834 .help = "indirect list configuration", 7835 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), 7836 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7837 }, 7838 [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { 7839 .type = "UNSIGNED", 7840 .help = "unsigned integer value", 7841 .call = parse_indlst_id2ptr, 7842 }, 7843 [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { 7844 .type = "UNSIGNED", 7845 .help = "unsigned integer value", 7846 .call = parse_indlst_id2ptr, 7847 }, 7848 [ACTION_SHARED_INDIRECT] = { 7849 .name = "shared_indirect", 7850 .help = "apply indirect action by id and port", 7851 .priv = PRIV_ACTION(INDIRECT, 0), 7852 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), 7853 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), 7854 ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7855 .call = parse_vc, 7856 }, 7857 [INDIRECT_ACTION_PORT] = { 7858 .name = "{indirect_action_port}", 7859 .type = "INDIRECT_ACTION_PORT", 7860 .help = "indirect action port", 7861 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 7862 .call = parse_ia_port, 7863 .comp = comp_none, 7864 }, 7865 [INDIRECT_ACTION_ID2PTR] = { 7866 .name = "{action_id}", 7867 .type = "INDIRECT_ACTION_ID", 7868 .help = "indirect action id", 7869 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7870 .call = parse_ia_id2ptr, 7871 .comp = comp_none, 7872 }, 7873 [INDIRECT_ACTION_INGRESS] = { 7874 .name = "ingress", 7875 .help = "affect rule to ingress", 7876 .next = NEXT(next_ia_create_attr), 7877 .call = parse_ia, 7878 }, 7879 [INDIRECT_ACTION_EGRESS] = { 7880 .name = "egress", 7881 .help = "affect rule to egress", 7882 .next = NEXT(next_ia_create_attr), 7883 .call = parse_ia, 7884 }, 7885 [INDIRECT_ACTION_TRANSFER] = { 7886 .name = "transfer", 7887 .help = "affect rule to transfer", 7888 .next = NEXT(next_ia_create_attr), 7889 .call = parse_ia, 7890 }, 7891 [INDIRECT_ACTION_SPEC] = { 7892 .name = "action", 7893 .help = "specify action to create indirect handle", 7894 .next = NEXT(next_action), 7895 }, 7896 [INDIRECT_ACTION_LIST] = { 7897 .name = "list", 7898 .help = "specify actions for indirect handle list", 7899 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7900 .call = parse_ia, 7901 }, 7902 [INDIRECT_ACTION_FLOW_CONF] = { 7903 .name = "flow_conf", 7904 .help = "specify actions configuration for indirect handle list", 7905 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7906 .call = parse_ia, 7907 }, 7908 [ACTION_POL_G] = { 7909 .name = "g_actions", 7910 .help = "submit a list of associated actions for green", 7911 .next = NEXT(next_action), 7912 .call = parse_mp, 7913 }, 7914 [ACTION_POL_Y] = { 7915 .name = "y_actions", 7916 .help = "submit a list of associated actions for yellow", 7917 .next = NEXT(next_action), 7918 }, 7919 [ACTION_POL_R] = { 7920 .name = "r_actions", 7921 .help = "submit a list of associated actions for red", 7922 .next = NEXT(next_action), 7923 }, 7924 [ACTION_QUOTA_CREATE] = { 7925 .name = "quota_create", 7926 .help = "create quota action", 7927 .priv = PRIV_ACTION(QUOTA, 7928 sizeof(struct rte_flow_action_quota)), 7929 .next = NEXT(action_quota_create), 7930 .call = parse_vc 7931 }, 7932 [ACTION_QUOTA_CREATE_LIMIT] = { 7933 .name = "limit", 7934 .help = "quota limit", 7935 .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), 7936 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), 7937 .call = parse_vc_conf 7938 }, 7939 [ACTION_QUOTA_CREATE_MODE] = { 7940 .name = "mode", 7941 .help = "quota mode", 7942 .next = NEXT(action_quota_create, 7943 NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), 7944 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), 7945 .call = parse_vc_conf 7946 }, 7947 [ACTION_QUOTA_CREATE_MODE_NAME] = { 7948 .name = "mode_name", 7949 .help = "quota mode name", 7950 .call = parse_quota_mode_name, 7951 .comp = comp_quota_mode_name 7952 }, 7953 [ACTION_QUOTA_QU] = { 7954 .name = "quota_update", 7955 .help = "update quota action", 7956 .priv = PRIV_ACTION(QUOTA, 7957 sizeof(struct rte_flow_update_quota)), 7958 .next = NEXT(action_quota_update), 7959 .call = parse_vc 7960 }, 7961 [ACTION_QUOTA_QU_LIMIT] = { 7962 .name = "limit", 7963 .help = "quota limit", 7964 .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7965 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), 7966 .call = parse_vc_conf 7967 }, 7968 [ACTION_QUOTA_QU_UPDATE_OP] = { 7969 .name = "update_op", 7970 .help = "query update op SET|ADD", 7971 .next = NEXT(action_quota_update, 7972 NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), 7973 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), 7974 .call = parse_vc_conf 7975 }, 7976 [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { 7977 .name = "update_op_name", 7978 .help = "quota update op name", 7979 .call = parse_quota_update_name, 7980 .comp = comp_quota_update_name 7981 }, 7982 7983 /* Top-level command. */ 7984 [ADD] = { 7985 .name = "add", 7986 .type = "port meter policy {port_id} {arg}", 7987 .help = "add port meter policy", 7988 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 7989 .call = parse_init, 7990 }, 7991 /* Sub-level commands. */ 7992 [ITEM_POL_PORT] = { 7993 .name = "port", 7994 .help = "add port meter policy", 7995 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 7996 }, 7997 [ITEM_POL_METER] = { 7998 .name = "meter", 7999 .help = "add port meter policy", 8000 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 8001 }, 8002 [ITEM_POL_POLICY] = { 8003 .name = "policy", 8004 .help = "add port meter policy", 8005 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 8006 NEXT_ENTRY(ACTION_POL_Y), 8007 NEXT_ENTRY(ACTION_POL_G), 8008 NEXT_ENTRY(COMMON_POLICY_ID), 8009 NEXT_ENTRY(COMMON_PORT_ID)), 8010 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 8011 ARGS_ENTRY(struct buffer, port)), 8012 .call = parse_mp, 8013 }, 8014 [ITEM_AGGR_AFFINITY] = { 8015 .name = "aggr_affinity", 8016 .help = "match on the aggregated port receiving the packets", 8017 .priv = PRIV_ITEM(AGGR_AFFINITY, 8018 sizeof(struct rte_flow_item_aggr_affinity)), 8019 .next = NEXT(item_aggr_affinity), 8020 .call = parse_vc, 8021 }, 8022 [ITEM_AGGR_AFFINITY_VALUE] = { 8023 .name = "affinity", 8024 .help = "aggregated affinity value", 8025 .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), 8026 item_param), 8027 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, 8028 affinity)), 8029 }, 8030 [ITEM_TX_QUEUE] = { 8031 .name = "tx_queue", 8032 .help = "match on the tx queue of send packet", 8033 .priv = PRIV_ITEM(TX_QUEUE, 8034 sizeof(struct rte_flow_item_tx_queue)), 8035 .next = NEXT(item_tx_queue), 8036 .call = parse_vc, 8037 }, 8038 [ITEM_TX_QUEUE_VALUE] = { 8039 .name = "tx_queue_value", 8040 .help = "tx queue value", 8041 .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), 8042 item_param), 8043 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, 8044 tx_queue)), 8045 }, 8046 }; 8047 8048 /** Remove and return last entry from argument stack. */ 8049 static const struct arg * 8050 pop_args(struct context *ctx) 8051 { 8052 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 8053 } 8054 8055 /** Add entry on top of the argument stack. */ 8056 static int 8057 push_args(struct context *ctx, const struct arg *arg) 8058 { 8059 if (ctx->args_num == CTX_STACK_SIZE) 8060 return -1; 8061 ctx->args[ctx->args_num++] = arg; 8062 return 0; 8063 } 8064 8065 /** Spread value into buffer according to bit-mask. */ 8066 static size_t 8067 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 8068 { 8069 uint32_t i = arg->size; 8070 uint32_t end = 0; 8071 int sub = 1; 8072 int add = 0; 8073 size_t len = 0; 8074 8075 if (!arg->mask) 8076 return 0; 8077 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8078 if (!arg->hton) { 8079 i = 0; 8080 end = arg->size; 8081 sub = 0; 8082 add = 1; 8083 } 8084 #endif 8085 while (i != end) { 8086 unsigned int shift = 0; 8087 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 8088 8089 for (shift = 0; arg->mask[i] >> shift; ++shift) { 8090 if (!(arg->mask[i] & (1 << shift))) 8091 continue; 8092 ++len; 8093 if (!dst) 8094 continue; 8095 *buf &= ~(1 << shift); 8096 *buf |= (val & 1) << shift; 8097 val >>= 1; 8098 } 8099 i += add; 8100 } 8101 return len; 8102 } 8103 8104 /** Compare a string with a partial one of a given length. */ 8105 static int 8106 strcmp_partial(const char *full, const char *partial, size_t partial_len) 8107 { 8108 int r = strncmp(full, partial, partial_len); 8109 8110 if (r) 8111 return r; 8112 if (strlen(full) <= partial_len) 8113 return 0; 8114 return full[partial_len]; 8115 } 8116 8117 /** 8118 * Parse a prefix length and generate a bit-mask. 8119 * 8120 * Last argument (ctx->args) is retrieved to determine mask size, storage 8121 * location and whether the result must use network byte ordering. 8122 */ 8123 static int 8124 parse_prefix(struct context *ctx, const struct token *token, 8125 const char *str, unsigned int len, 8126 void *buf, unsigned int size) 8127 { 8128 const struct arg *arg = pop_args(ctx); 8129 static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff"; 8130 char *end; 8131 uintmax_t u; 8132 unsigned int bytes; 8133 unsigned int extra; 8134 8135 (void)token; 8136 /* Argument is expected. */ 8137 if (!arg) 8138 return -1; 8139 errno = 0; 8140 u = strtoumax(str, &end, 0); 8141 if (errno || (size_t)(end - str) != len) 8142 goto error; 8143 if (arg->mask) { 8144 uintmax_t v = 0; 8145 8146 extra = arg_entry_bf_fill(NULL, 0, arg); 8147 if (u > extra) 8148 goto error; 8149 if (!ctx->object) 8150 return len; 8151 extra -= u; 8152 while (u--) 8153 (v <<= 1, v |= 1); 8154 v <<= extra; 8155 if (!arg_entry_bf_fill(ctx->object, v, arg) || 8156 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 8157 goto error; 8158 return len; 8159 } 8160 bytes = u / 8; 8161 extra = u % 8; 8162 size = arg->size; 8163 if (bytes > size || bytes + !!extra > size) 8164 goto error; 8165 if (!ctx->object) 8166 return len; 8167 buf = (uint8_t *)ctx->object + arg->offset; 8168 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8169 if (!arg->hton) { 8170 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 8171 memset(buf, 0x00, size - bytes); 8172 if (extra) 8173 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 8174 } else 8175 #endif 8176 { 8177 memset(buf, 0xff, bytes); 8178 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 8179 if (extra) 8180 ((uint8_t *)buf)[bytes] = conv[extra]; 8181 } 8182 if (ctx->objmask) 8183 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 8184 return len; 8185 error: 8186 push_args(ctx, arg); 8187 return -1; 8188 } 8189 8190 /** Default parsing function for token name matching. */ 8191 static int 8192 parse_default(struct context *ctx, const struct token *token, 8193 const char *str, unsigned int len, 8194 void *buf, unsigned int size) 8195 { 8196 (void)ctx; 8197 (void)buf; 8198 (void)size; 8199 if (strcmp_partial(token->name, str, len)) 8200 return -1; 8201 return len; 8202 } 8203 8204 /** Parse flow command, initialize output buffer for subsequent tokens. */ 8205 static int 8206 parse_init(struct context *ctx, const struct token *token, 8207 const char *str, unsigned int len, 8208 void *buf, unsigned int size) 8209 { 8210 struct buffer *out = buf; 8211 8212 /* Token name must match. */ 8213 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8214 return -1; 8215 /* Nothing else to do if there is no buffer. */ 8216 if (!out) 8217 return len; 8218 /* Make sure buffer is large enough. */ 8219 if (size < sizeof(*out)) 8220 return -1; 8221 /* Initialize buffer. */ 8222 memset(out, 0x00, sizeof(*out)); 8223 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 8224 ctx->objdata = 0; 8225 ctx->object = out; 8226 ctx->objmask = NULL; 8227 return len; 8228 } 8229 8230 /** Parse tokens for indirect action commands. */ 8231 static int 8232 parse_ia(struct context *ctx, const struct token *token, 8233 const char *str, unsigned int len, 8234 void *buf, unsigned int size) 8235 { 8236 struct buffer *out = buf; 8237 8238 /* Token name must match. */ 8239 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8240 return -1; 8241 /* Nothing else to do if there is no buffer. */ 8242 if (!out) 8243 return len; 8244 if (!out->command) { 8245 if (ctx->curr != INDIRECT_ACTION) 8246 return -1; 8247 if (sizeof(*out) > size) 8248 return -1; 8249 out->command = ctx->curr; 8250 ctx->objdata = 0; 8251 ctx->object = out; 8252 ctx->objmask = NULL; 8253 out->args.vc.data = (uint8_t *)out + size; 8254 return len; 8255 } 8256 switch (ctx->curr) { 8257 case INDIRECT_ACTION_CREATE: 8258 case INDIRECT_ACTION_UPDATE: 8259 case INDIRECT_ACTION_QUERY_UPDATE: 8260 out->args.vc.actions = 8261 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8262 sizeof(double)); 8263 out->args.vc.attr.group = UINT32_MAX; 8264 /* fallthrough */ 8265 case INDIRECT_ACTION_QUERY: 8266 out->command = ctx->curr; 8267 ctx->objdata = 0; 8268 ctx->object = out; 8269 ctx->objmask = NULL; 8270 return len; 8271 case INDIRECT_ACTION_EGRESS: 8272 out->args.vc.attr.egress = 1; 8273 return len; 8274 case INDIRECT_ACTION_INGRESS: 8275 out->args.vc.attr.ingress = 1; 8276 return len; 8277 case INDIRECT_ACTION_TRANSFER: 8278 out->args.vc.attr.transfer = 1; 8279 return len; 8280 case INDIRECT_ACTION_QU_MODE: 8281 return len; 8282 case INDIRECT_ACTION_LIST: 8283 out->command = INDIRECT_ACTION_LIST_CREATE; 8284 return len; 8285 case INDIRECT_ACTION_FLOW_CONF: 8286 out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; 8287 return len; 8288 default: 8289 return -1; 8290 } 8291 } 8292 8293 8294 /** Parse tokens for indirect action destroy command. */ 8295 static int 8296 parse_ia_destroy(struct context *ctx, const struct token *token, 8297 const char *str, unsigned int len, 8298 void *buf, unsigned int size) 8299 { 8300 struct buffer *out = buf; 8301 uint32_t *action_id; 8302 8303 /* Token name must match. */ 8304 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8305 return -1; 8306 /* Nothing else to do if there is no buffer. */ 8307 if (!out) 8308 return len; 8309 if (!out->command || out->command == INDIRECT_ACTION) { 8310 if (ctx->curr != INDIRECT_ACTION_DESTROY) 8311 return -1; 8312 if (sizeof(*out) > size) 8313 return -1; 8314 out->command = ctx->curr; 8315 ctx->objdata = 0; 8316 ctx->object = out; 8317 ctx->objmask = NULL; 8318 out->args.ia_destroy.action_id = 8319 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8320 sizeof(double)); 8321 return len; 8322 } 8323 action_id = out->args.ia_destroy.action_id 8324 + out->args.ia_destroy.action_id_n++; 8325 if ((uint8_t *)action_id > (uint8_t *)out + size) 8326 return -1; 8327 ctx->objdata = 0; 8328 ctx->object = action_id; 8329 ctx->objmask = NULL; 8330 return len; 8331 } 8332 8333 /** Parse tokens for indirect action commands. */ 8334 static int 8335 parse_qia(struct context *ctx, const struct token *token, 8336 const char *str, unsigned int len, 8337 void *buf, unsigned int size) 8338 { 8339 struct buffer *out = buf; 8340 8341 /* Token name must match. */ 8342 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8343 return -1; 8344 /* Nothing else to do if there is no buffer. */ 8345 if (!out) 8346 return len; 8347 if (!out->command) { 8348 if (ctx->curr != QUEUE) 8349 return -1; 8350 if (sizeof(*out) > size) 8351 return -1; 8352 out->args.vc.data = (uint8_t *)out + size; 8353 return len; 8354 } 8355 switch (ctx->curr) { 8356 case QUEUE_INDIRECT_ACTION: 8357 return len; 8358 case QUEUE_INDIRECT_ACTION_CREATE: 8359 case QUEUE_INDIRECT_ACTION_UPDATE: 8360 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 8361 out->args.vc.actions = 8362 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8363 sizeof(double)); 8364 out->args.vc.attr.group = UINT32_MAX; 8365 /* fallthrough */ 8366 case QUEUE_INDIRECT_ACTION_QUERY: 8367 out->command = ctx->curr; 8368 ctx->objdata = 0; 8369 ctx->object = out; 8370 ctx->objmask = NULL; 8371 return len; 8372 case QUEUE_INDIRECT_ACTION_EGRESS: 8373 out->args.vc.attr.egress = 1; 8374 return len; 8375 case QUEUE_INDIRECT_ACTION_INGRESS: 8376 out->args.vc.attr.ingress = 1; 8377 return len; 8378 case QUEUE_INDIRECT_ACTION_TRANSFER: 8379 out->args.vc.attr.transfer = 1; 8380 return len; 8381 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 8382 return len; 8383 case QUEUE_INDIRECT_ACTION_QU_MODE: 8384 return len; 8385 case QUEUE_INDIRECT_ACTION_LIST: 8386 out->command = QUEUE_INDIRECT_ACTION_LIST_CREATE; 8387 return len; 8388 default: 8389 return -1; 8390 } 8391 } 8392 8393 /** Parse tokens for indirect action destroy command. */ 8394 static int 8395 parse_qia_destroy(struct context *ctx, const struct token *token, 8396 const char *str, unsigned int len, 8397 void *buf, unsigned int size) 8398 { 8399 struct buffer *out = buf; 8400 uint32_t *action_id; 8401 8402 /* Token name must match. */ 8403 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8404 return -1; 8405 /* Nothing else to do if there is no buffer. */ 8406 if (!out) 8407 return len; 8408 if (!out->command || out->command == QUEUE) { 8409 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 8410 return -1; 8411 if (sizeof(*out) > size) 8412 return -1; 8413 out->command = ctx->curr; 8414 ctx->objdata = 0; 8415 ctx->object = out; 8416 ctx->objmask = NULL; 8417 out->args.ia_destroy.action_id = 8418 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8419 sizeof(double)); 8420 return len; 8421 } 8422 switch (ctx->curr) { 8423 case QUEUE_INDIRECT_ACTION: 8424 out->command = ctx->curr; 8425 ctx->objdata = 0; 8426 ctx->object = out; 8427 ctx->objmask = NULL; 8428 return len; 8429 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 8430 action_id = out->args.ia_destroy.action_id 8431 + out->args.ia_destroy.action_id_n++; 8432 if ((uint8_t *)action_id > (uint8_t *)out + size) 8433 return -1; 8434 ctx->objdata = 0; 8435 ctx->object = action_id; 8436 ctx->objmask = NULL; 8437 return len; 8438 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 8439 return len; 8440 default: 8441 return -1; 8442 } 8443 } 8444 8445 /** Parse tokens for meter policy action commands. */ 8446 static int 8447 parse_mp(struct context *ctx, const struct token *token, 8448 const char *str, unsigned int len, 8449 void *buf, unsigned int size) 8450 { 8451 struct buffer *out = buf; 8452 8453 /* Token name must match. */ 8454 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8455 return -1; 8456 /* Nothing else to do if there is no buffer. */ 8457 if (!out) 8458 return len; 8459 if (!out->command) { 8460 if (ctx->curr != ITEM_POL_POLICY) 8461 return -1; 8462 if (sizeof(*out) > size) 8463 return -1; 8464 out->command = ctx->curr; 8465 ctx->objdata = 0; 8466 ctx->object = out; 8467 ctx->objmask = NULL; 8468 out->args.vc.data = (uint8_t *)out + size; 8469 return len; 8470 } 8471 switch (ctx->curr) { 8472 case ACTION_POL_G: 8473 out->args.vc.actions = 8474 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8475 sizeof(double)); 8476 out->command = ctx->curr; 8477 ctx->objdata = 0; 8478 ctx->object = out; 8479 ctx->objmask = NULL; 8480 return len; 8481 default: 8482 return -1; 8483 } 8484 } 8485 8486 /** Parse tokens for validate/create commands. */ 8487 static int 8488 parse_vc(struct context *ctx, const struct token *token, 8489 const char *str, unsigned int len, 8490 void *buf, unsigned int size) 8491 { 8492 struct buffer *out = buf; 8493 uint8_t *data; 8494 uint32_t data_size; 8495 8496 /* Token name must match. */ 8497 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8498 return -1; 8499 /* Nothing else to do if there is no buffer. */ 8500 if (!out) 8501 return len; 8502 if (!out->command) { 8503 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 8504 ctx->curr != PATTERN_TEMPLATE_CREATE && 8505 ctx->curr != ACTIONS_TEMPLATE_CREATE && 8506 ctx->curr != UPDATE) 8507 return -1; 8508 if (ctx->curr == UPDATE) 8509 out->args.vc.pattern = 8510 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8511 sizeof(double)); 8512 if (sizeof(*out) > size) 8513 return -1; 8514 out->command = ctx->curr; 8515 ctx->objdata = 0; 8516 ctx->object = out; 8517 ctx->objmask = NULL; 8518 out->args.vc.data = (uint8_t *)out + size; 8519 return len; 8520 } 8521 ctx->objdata = 0; 8522 switch (ctx->curr) { 8523 default: 8524 ctx->object = &out->args.vc.attr; 8525 break; 8526 case VC_TUNNEL_SET: 8527 case VC_TUNNEL_MATCH: 8528 ctx->object = &out->args.vc.tunnel_ops; 8529 break; 8530 case VC_USER_ID: 8531 ctx->object = out; 8532 break; 8533 } 8534 ctx->objmask = NULL; 8535 switch (ctx->curr) { 8536 case VC_GROUP: 8537 case VC_PRIORITY: 8538 case VC_USER_ID: 8539 return len; 8540 case VC_TUNNEL_SET: 8541 out->args.vc.tunnel_ops.enabled = 1; 8542 out->args.vc.tunnel_ops.actions = 1; 8543 return len; 8544 case VC_TUNNEL_MATCH: 8545 out->args.vc.tunnel_ops.enabled = 1; 8546 out->args.vc.tunnel_ops.items = 1; 8547 return len; 8548 case VC_INGRESS: 8549 out->args.vc.attr.ingress = 1; 8550 return len; 8551 case VC_EGRESS: 8552 out->args.vc.attr.egress = 1; 8553 return len; 8554 case VC_TRANSFER: 8555 out->args.vc.attr.transfer = 1; 8556 return len; 8557 case ITEM_PATTERN: 8558 out->args.vc.pattern = 8559 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8560 sizeof(double)); 8561 ctx->object = out->args.vc.pattern; 8562 ctx->objmask = NULL; 8563 return len; 8564 case ITEM_END: 8565 if ((out->command == VALIDATE || out->command == CREATE) && 8566 ctx->last) 8567 return -1; 8568 if (out->command == PATTERN_TEMPLATE_CREATE && 8569 !ctx->last) 8570 return -1; 8571 break; 8572 case ACTIONS: 8573 out->args.vc.actions = out->args.vc.pattern ? 8574 (void *)RTE_ALIGN_CEIL((uintptr_t) 8575 (out->args.vc.pattern + 8576 out->args.vc.pattern_n), 8577 sizeof(double)) : 8578 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8579 sizeof(double)); 8580 ctx->object = out->args.vc.actions; 8581 ctx->objmask = NULL; 8582 return len; 8583 case VC_IS_USER_ID: 8584 out->args.vc.user_id = true; 8585 return len; 8586 default: 8587 if (!token->priv) 8588 return -1; 8589 break; 8590 } 8591 if (!out->args.vc.actions) { 8592 const struct parse_item_priv *priv = token->priv; 8593 struct rte_flow_item *item = 8594 out->args.vc.pattern + out->args.vc.pattern_n; 8595 8596 data_size = priv->size * 3; /* spec, last, mask */ 8597 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8598 (out->args.vc.data - data_size), 8599 sizeof(double)); 8600 if ((uint8_t *)item + sizeof(*item) > data) 8601 return -1; 8602 *item = (struct rte_flow_item){ 8603 .type = priv->type, 8604 }; 8605 ++out->args.vc.pattern_n; 8606 ctx->object = item; 8607 ctx->objmask = NULL; 8608 } else { 8609 const struct parse_action_priv *priv = token->priv; 8610 struct rte_flow_action *action = 8611 out->args.vc.actions + out->args.vc.actions_n; 8612 8613 data_size = priv->size; /* configuration */ 8614 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8615 (out->args.vc.data - data_size), 8616 sizeof(double)); 8617 if ((uint8_t *)action + sizeof(*action) > data) 8618 return -1; 8619 *action = (struct rte_flow_action){ 8620 .type = priv->type, 8621 .conf = data_size ? data : NULL, 8622 }; 8623 ++out->args.vc.actions_n; 8624 ctx->object = action; 8625 ctx->objmask = NULL; 8626 } 8627 memset(data, 0, data_size); 8628 out->args.vc.data = data; 8629 ctx->objdata = data_size; 8630 return len; 8631 } 8632 8633 /** Parse pattern item parameter type. */ 8634 static int 8635 parse_vc_spec(struct context *ctx, const struct token *token, 8636 const char *str, unsigned int len, 8637 void *buf, unsigned int size) 8638 { 8639 struct buffer *out = buf; 8640 struct rte_flow_item *item; 8641 uint32_t data_size; 8642 int index; 8643 int objmask = 0; 8644 8645 (void)size; 8646 /* Token name must match. */ 8647 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8648 return -1; 8649 /* Parse parameter types. */ 8650 switch (ctx->curr) { 8651 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 8652 8653 case ITEM_PARAM_IS: 8654 index = 0; 8655 objmask = 1; 8656 break; 8657 case ITEM_PARAM_SPEC: 8658 index = 0; 8659 break; 8660 case ITEM_PARAM_LAST: 8661 index = 1; 8662 break; 8663 case ITEM_PARAM_PREFIX: 8664 /* Modify next token to expect a prefix. */ 8665 if (ctx->next_num < 2) 8666 return -1; 8667 ctx->next[ctx->next_num - 2] = prefix; 8668 /* Fall through. */ 8669 case ITEM_PARAM_MASK: 8670 index = 2; 8671 break; 8672 default: 8673 return -1; 8674 } 8675 /* Nothing else to do if there is no buffer. */ 8676 if (!out) 8677 return len; 8678 if (!out->args.vc.pattern_n) 8679 return -1; 8680 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8681 data_size = ctx->objdata / 3; /* spec, last, mask */ 8682 /* Point to selected object. */ 8683 ctx->object = out->args.vc.data + (data_size * index); 8684 if (objmask) { 8685 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 8686 item->mask = ctx->objmask; 8687 } else 8688 ctx->objmask = NULL; 8689 /* Update relevant item pointer. */ 8690 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 8691 ctx->object; 8692 return len; 8693 } 8694 8695 /** Parse action configuration field. */ 8696 static int 8697 parse_vc_conf(struct context *ctx, const struct token *token, 8698 const char *str, unsigned int len, 8699 void *buf, unsigned int size) 8700 { 8701 struct buffer *out = buf; 8702 8703 (void)size; 8704 /* Token name must match. */ 8705 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8706 return -1; 8707 /* Nothing else to do if there is no buffer. */ 8708 if (!out) 8709 return len; 8710 /* Point to selected object. */ 8711 ctx->object = out->args.vc.data; 8712 ctx->objmask = NULL; 8713 return len; 8714 } 8715 8716 /** Parse action configuration field. */ 8717 static int 8718 parse_vc_conf_timeout(struct context *ctx, const struct token *token, 8719 const char *str, unsigned int len, 8720 void *buf, unsigned int size) 8721 { 8722 struct buffer *out = buf; 8723 struct rte_flow_update_age *update; 8724 8725 (void)size; 8726 if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) 8727 return -1; 8728 /* Token name must match. */ 8729 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8730 return -1; 8731 /* Nothing else to do if there is no buffer. */ 8732 if (!out) 8733 return len; 8734 /* Point to selected object. */ 8735 ctx->object = out->args.vc.data; 8736 ctx->objmask = NULL; 8737 /* Update the timeout is valid. */ 8738 update = (struct rte_flow_update_age *)out->args.vc.data; 8739 update->timeout_valid = 1; 8740 return len; 8741 } 8742 8743 /** Parse eCPRI common header type field. */ 8744 static int 8745 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 8746 const char *str, unsigned int len, 8747 void *buf, unsigned int size) 8748 { 8749 struct rte_flow_item_ecpri *ecpri; 8750 struct rte_flow_item_ecpri *ecpri_mask; 8751 struct rte_flow_item *item; 8752 uint32_t data_size; 8753 uint8_t msg_type; 8754 struct buffer *out = buf; 8755 const struct arg *arg; 8756 8757 (void)size; 8758 /* Token name must match. */ 8759 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8760 return -1; 8761 switch (ctx->curr) { 8762 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 8763 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 8764 break; 8765 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 8766 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 8767 break; 8768 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 8769 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 8770 break; 8771 default: 8772 return -1; 8773 } 8774 if (!ctx->object) 8775 return len; 8776 arg = pop_args(ctx); 8777 if (!arg) 8778 return -1; 8779 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 8780 ecpri->hdr.common.type = msg_type; 8781 data_size = ctx->objdata / 3; /* spec, last, mask */ 8782 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 8783 (data_size * 2)); 8784 ecpri_mask->hdr.common.type = 0xFF; 8785 if (arg->hton) { 8786 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 8787 ecpri_mask->hdr.common.u32 = 8788 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 8789 } 8790 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8791 item->spec = ecpri; 8792 item->mask = ecpri_mask; 8793 return len; 8794 } 8795 8796 /** Parse L2TPv2 common header type field. */ 8797 static int 8798 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, 8799 const char *str, unsigned int len, 8800 void *buf, unsigned int size) 8801 { 8802 struct rte_flow_item_l2tpv2 *l2tpv2; 8803 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 8804 struct rte_flow_item *item; 8805 uint32_t data_size; 8806 uint16_t msg_type = 0; 8807 struct buffer *out = buf; 8808 const struct arg *arg; 8809 8810 (void)size; 8811 /* Token name must match. */ 8812 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8813 return -1; 8814 switch (ctx->curr) { 8815 case ITEM_L2TPV2_TYPE_DATA: 8816 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 8817 break; 8818 case ITEM_L2TPV2_TYPE_DATA_L: 8819 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 8820 break; 8821 case ITEM_L2TPV2_TYPE_DATA_S: 8822 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 8823 break; 8824 case ITEM_L2TPV2_TYPE_DATA_O: 8825 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 8826 break; 8827 case ITEM_L2TPV2_TYPE_DATA_L_S: 8828 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 8829 break; 8830 case ITEM_L2TPV2_TYPE_CTRL: 8831 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 8832 break; 8833 default: 8834 return -1; 8835 } 8836 if (!ctx->object) 8837 return len; 8838 arg = pop_args(ctx); 8839 if (!arg) 8840 return -1; 8841 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 8842 l2tpv2->hdr.common.flags_version |= msg_type; 8843 data_size = ctx->objdata / 3; /* spec, last, mask */ 8844 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 8845 (data_size * 2)); 8846 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 8847 if (arg->hton) { 8848 l2tpv2->hdr.common.flags_version = 8849 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 8850 l2tpv2_mask->hdr.common.flags_version = 8851 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 8852 } 8853 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8854 item->spec = l2tpv2; 8855 item->mask = l2tpv2_mask; 8856 return len; 8857 } 8858 8859 /** Parse operation for compare match item. */ 8860 static int 8861 parse_vc_compare_op(struct context *ctx, const struct token *token, 8862 const char *str, unsigned int len, void *buf, 8863 unsigned int size) 8864 { 8865 struct rte_flow_item_compare *compare_item; 8866 unsigned int i; 8867 8868 (void)token; 8869 (void)buf; 8870 (void)size; 8871 if (ctx->curr != ITEM_COMPARE_OP_VALUE) 8872 return -1; 8873 for (i = 0; compare_ops[i]; ++i) 8874 if (!strcmp_partial(compare_ops[i], str, len)) 8875 break; 8876 if (!compare_ops[i]) 8877 return -1; 8878 if (!ctx->object) 8879 return len; 8880 compare_item = ctx->object; 8881 compare_item->operation = (enum rte_flow_item_compare_op)i; 8882 return len; 8883 } 8884 8885 /** Parse id for compare match item. */ 8886 static int 8887 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 8888 const char *str, unsigned int len, void *buf, 8889 unsigned int size) 8890 { 8891 struct rte_flow_item_compare *compare_item; 8892 unsigned int i; 8893 8894 (void)token; 8895 (void)buf; 8896 (void)size; 8897 if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE && 8898 ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE) 8899 return -1; 8900 for (i = 0; flow_field_ids[i]; ++i) 8901 if (!strcmp_partial(flow_field_ids[i], str, len)) 8902 break; 8903 if (!flow_field_ids[i]) 8904 return -1; 8905 if (!ctx->object) 8906 return len; 8907 compare_item = ctx->object; 8908 if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE) 8909 compare_item->a.field = (enum rte_flow_field_id)i; 8910 else 8911 compare_item->b.field = (enum rte_flow_field_id)i; 8912 return len; 8913 } 8914 8915 /** Parse level for compare match item. */ 8916 static int 8917 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 8918 const char *str, unsigned int len, void *buf, 8919 unsigned int size) 8920 { 8921 struct rte_flow_item_compare *compare_item; 8922 struct flex_item *fp = NULL; 8923 uint32_t val; 8924 struct buffer *out = buf; 8925 char *end; 8926 8927 (void)token; 8928 (void)size; 8929 if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 8930 ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE) 8931 return -1; 8932 if (!ctx->object) 8933 return len; 8934 compare_item = ctx->object; 8935 errno = 0; 8936 val = strtoumax(str, &end, 0); 8937 if (errno || (size_t)(end - str) != len) 8938 return -1; 8939 /* No need to validate action template mask value */ 8940 if (out->args.vc.masks) { 8941 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) 8942 compare_item->a.level = val; 8943 else 8944 compare_item->b.level = val; 8945 return len; 8946 } 8947 if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 8948 compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) || 8949 (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE && 8950 compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 8951 if (val >= FLEX_MAX_PARSERS_NUM) { 8952 printf("Bad flex item handle\n"); 8953 return -1; 8954 } 8955 fp = flex_items[ctx->port][val]; 8956 if (!fp) { 8957 printf("Bad flex item handle\n"); 8958 return -1; 8959 } 8960 } 8961 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) { 8962 if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM) 8963 compare_item->a.level = val; 8964 else 8965 compare_item->a.flex_handle = fp->flex_handle; 8966 } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) { 8967 if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM) 8968 compare_item->b.level = val; 8969 else 8970 compare_item->b.flex_handle = fp->flex_handle; 8971 } 8972 return len; 8973 } 8974 8975 /** Parse meter color action type. */ 8976 static int 8977 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 8978 const char *str, unsigned int len, 8979 void *buf, unsigned int size) 8980 { 8981 struct rte_flow_action *action_data; 8982 struct rte_flow_action_meter_color *conf; 8983 enum rte_color color; 8984 8985 (void)buf; 8986 (void)size; 8987 /* Token name must match. */ 8988 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8989 return -1; 8990 switch (ctx->curr) { 8991 case ACTION_METER_COLOR_GREEN: 8992 color = RTE_COLOR_GREEN; 8993 break; 8994 case ACTION_METER_COLOR_YELLOW: 8995 color = RTE_COLOR_YELLOW; 8996 break; 8997 case ACTION_METER_COLOR_RED: 8998 color = RTE_COLOR_RED; 8999 break; 9000 default: 9001 return -1; 9002 } 9003 9004 if (!ctx->object) 9005 return len; 9006 action_data = ctx->object; 9007 conf = (struct rte_flow_action_meter_color *) 9008 (uintptr_t)(action_data->conf); 9009 conf->color = color; 9010 return len; 9011 } 9012 9013 /** Parse RSS action. */ 9014 static int 9015 parse_vc_action_rss(struct context *ctx, const struct token *token, 9016 const char *str, unsigned int len, 9017 void *buf, unsigned int size) 9018 { 9019 struct buffer *out = buf; 9020 struct rte_flow_action *action; 9021 struct action_rss_data *action_rss_data; 9022 unsigned int i; 9023 int ret; 9024 9025 ret = parse_vc(ctx, token, str, len, buf, size); 9026 if (ret < 0) 9027 return ret; 9028 /* Nothing else to do if there is no buffer. */ 9029 if (!out) 9030 return ret; 9031 if (!out->args.vc.actions_n) 9032 return -1; 9033 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9034 /* Point to selected object. */ 9035 ctx->object = out->args.vc.data; 9036 ctx->objmask = NULL; 9037 /* Set up default configuration. */ 9038 action_rss_data = ctx->object; 9039 *action_rss_data = (struct action_rss_data){ 9040 .conf = (struct rte_flow_action_rss){ 9041 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 9042 .level = 0, 9043 .types = rss_hf, 9044 .key_len = 0, 9045 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 9046 .key = NULL, 9047 .queue = action_rss_data->queue, 9048 }, 9049 .queue = { 0 }, 9050 }; 9051 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 9052 action_rss_data->queue[i] = i; 9053 action->conf = &action_rss_data->conf; 9054 return ret; 9055 } 9056 9057 /** 9058 * Parse func field for RSS action. 9059 * 9060 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 9061 * ACTION_RSS_FUNC_* index that called this function. 9062 */ 9063 static int 9064 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 9065 const char *str, unsigned int len, 9066 void *buf, unsigned int size) 9067 { 9068 struct action_rss_data *action_rss_data; 9069 enum rte_eth_hash_function func; 9070 9071 (void)buf; 9072 (void)size; 9073 /* Token name must match. */ 9074 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9075 return -1; 9076 switch (ctx->curr) { 9077 case ACTION_RSS_FUNC_DEFAULT: 9078 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 9079 break; 9080 case ACTION_RSS_FUNC_TOEPLITZ: 9081 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 9082 break; 9083 case ACTION_RSS_FUNC_SIMPLE_XOR: 9084 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 9085 break; 9086 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 9087 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 9088 break; 9089 default: 9090 return -1; 9091 } 9092 if (!ctx->object) 9093 return len; 9094 action_rss_data = ctx->object; 9095 action_rss_data->conf.func = func; 9096 return len; 9097 } 9098 9099 /** 9100 * Parse type field for RSS action. 9101 * 9102 * Valid tokens are type field names and the "end" token. 9103 */ 9104 static int 9105 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 9106 const char *str, unsigned int len, 9107 void *buf, unsigned int size) 9108 { 9109 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 9110 struct action_rss_data *action_rss_data; 9111 unsigned int i; 9112 9113 (void)token; 9114 (void)buf; 9115 (void)size; 9116 if (ctx->curr != ACTION_RSS_TYPE) 9117 return -1; 9118 if (!(ctx->objdata >> 16) && ctx->object) { 9119 action_rss_data = ctx->object; 9120 action_rss_data->conf.types = 0; 9121 } 9122 if (!strcmp_partial("end", str, len)) { 9123 ctx->objdata &= 0xffff; 9124 return len; 9125 } 9126 for (i = 0; rss_type_table[i].str; ++i) 9127 if (!strcmp_partial(rss_type_table[i].str, str, len)) 9128 break; 9129 if (!rss_type_table[i].str) 9130 return -1; 9131 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 9132 /* Repeat token. */ 9133 if (ctx->next_num == RTE_DIM(ctx->next)) 9134 return -1; 9135 ctx->next[ctx->next_num++] = next; 9136 if (!ctx->object) 9137 return len; 9138 action_rss_data = ctx->object; 9139 action_rss_data->conf.types |= rss_type_table[i].rss_type; 9140 return len; 9141 } 9142 9143 /** 9144 * Parse queue field for RSS action. 9145 * 9146 * Valid tokens are queue indices and the "end" token. 9147 */ 9148 static int 9149 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 9150 const char *str, unsigned int len, 9151 void *buf, unsigned int size) 9152 { 9153 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 9154 struct action_rss_data *action_rss_data; 9155 const struct arg *arg; 9156 int ret; 9157 int i; 9158 9159 (void)token; 9160 (void)buf; 9161 (void)size; 9162 if (ctx->curr != ACTION_RSS_QUEUE) 9163 return -1; 9164 i = ctx->objdata >> 16; 9165 if (!strcmp_partial("end", str, len)) { 9166 ctx->objdata &= 0xffff; 9167 goto end; 9168 } 9169 if (i >= ACTION_RSS_QUEUE_NUM) 9170 return -1; 9171 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 9172 i * sizeof(action_rss_data->queue[i]), 9173 sizeof(action_rss_data->queue[i])); 9174 if (push_args(ctx, arg)) 9175 return -1; 9176 ret = parse_int(ctx, token, str, len, NULL, 0); 9177 if (ret < 0) { 9178 pop_args(ctx); 9179 return -1; 9180 } 9181 ++i; 9182 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 9183 /* Repeat token. */ 9184 if (ctx->next_num == RTE_DIM(ctx->next)) 9185 return -1; 9186 ctx->next[ctx->next_num++] = next; 9187 end: 9188 if (!ctx->object) 9189 return len; 9190 action_rss_data = ctx->object; 9191 action_rss_data->conf.queue_num = i; 9192 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 9193 return len; 9194 } 9195 9196 /** Setup VXLAN encap configuration. */ 9197 static int 9198 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 9199 { 9200 /* Set up default configuration. */ 9201 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 9202 .conf = (struct rte_flow_action_vxlan_encap){ 9203 .definition = action_vxlan_encap_data->items, 9204 }, 9205 .items = { 9206 { 9207 .type = RTE_FLOW_ITEM_TYPE_ETH, 9208 .spec = &action_vxlan_encap_data->item_eth, 9209 .mask = &rte_flow_item_eth_mask, 9210 }, 9211 { 9212 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9213 .spec = &action_vxlan_encap_data->item_vlan, 9214 .mask = &rte_flow_item_vlan_mask, 9215 }, 9216 { 9217 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9218 .spec = &action_vxlan_encap_data->item_ipv4, 9219 .mask = &rte_flow_item_ipv4_mask, 9220 }, 9221 { 9222 .type = RTE_FLOW_ITEM_TYPE_UDP, 9223 .spec = &action_vxlan_encap_data->item_udp, 9224 .mask = &rte_flow_item_udp_mask, 9225 }, 9226 { 9227 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 9228 .spec = &action_vxlan_encap_data->item_vxlan, 9229 .mask = &rte_flow_item_vxlan_mask, 9230 }, 9231 { 9232 .type = RTE_FLOW_ITEM_TYPE_END, 9233 }, 9234 }, 9235 .item_eth.hdr.ether_type = 0, 9236 .item_vlan = { 9237 .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, 9238 .hdr.eth_proto = 0, 9239 }, 9240 .item_ipv4.hdr = { 9241 .src_addr = vxlan_encap_conf.ipv4_src, 9242 .dst_addr = vxlan_encap_conf.ipv4_dst, 9243 }, 9244 .item_udp.hdr = { 9245 .src_port = vxlan_encap_conf.udp_src, 9246 .dst_port = vxlan_encap_conf.udp_dst, 9247 }, 9248 .item_vxlan.hdr.flags = 0, 9249 }; 9250 memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9251 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9252 memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, 9253 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9254 if (!vxlan_encap_conf.select_ipv4) { 9255 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 9256 &vxlan_encap_conf.ipv6_src, 9257 sizeof(vxlan_encap_conf.ipv6_src)); 9258 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 9259 &vxlan_encap_conf.ipv6_dst, 9260 sizeof(vxlan_encap_conf.ipv6_dst)); 9261 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 9262 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9263 .spec = &action_vxlan_encap_data->item_ipv6, 9264 .mask = &rte_flow_item_ipv6_mask, 9265 }; 9266 } 9267 if (!vxlan_encap_conf.select_vlan) 9268 action_vxlan_encap_data->items[1].type = 9269 RTE_FLOW_ITEM_TYPE_VOID; 9270 if (vxlan_encap_conf.select_tos_ttl) { 9271 if (vxlan_encap_conf.select_ipv4) { 9272 static struct rte_flow_item_ipv4 ipv4_mask_tos; 9273 9274 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 9275 sizeof(ipv4_mask_tos)); 9276 ipv4_mask_tos.hdr.type_of_service = 0xff; 9277 ipv4_mask_tos.hdr.time_to_live = 0xff; 9278 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 9279 vxlan_encap_conf.ip_tos; 9280 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 9281 vxlan_encap_conf.ip_ttl; 9282 action_vxlan_encap_data->items[2].mask = 9283 &ipv4_mask_tos; 9284 } else { 9285 static struct rte_flow_item_ipv6 ipv6_mask_tos; 9286 9287 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 9288 sizeof(ipv6_mask_tos)); 9289 ipv6_mask_tos.hdr.vtc_flow |= 9290 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 9291 ipv6_mask_tos.hdr.hop_limits = 0xff; 9292 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 9293 rte_cpu_to_be_32 9294 ((uint32_t)vxlan_encap_conf.ip_tos << 9295 RTE_IPV6_HDR_TC_SHIFT); 9296 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 9297 vxlan_encap_conf.ip_ttl; 9298 action_vxlan_encap_data->items[2].mask = 9299 &ipv6_mask_tos; 9300 } 9301 } 9302 memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, 9303 RTE_DIM(vxlan_encap_conf.vni)); 9304 return 0; 9305 } 9306 9307 /** Parse VXLAN encap action. */ 9308 static int 9309 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 9310 const char *str, unsigned int len, 9311 void *buf, unsigned int size) 9312 { 9313 struct buffer *out = buf; 9314 struct rte_flow_action *action; 9315 struct action_vxlan_encap_data *action_vxlan_encap_data; 9316 int ret; 9317 9318 ret = parse_vc(ctx, token, str, len, buf, size); 9319 if (ret < 0) 9320 return ret; 9321 /* Nothing else to do if there is no buffer. */ 9322 if (!out) 9323 return ret; 9324 if (!out->args.vc.actions_n) 9325 return -1; 9326 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9327 /* Point to selected object. */ 9328 ctx->object = out->args.vc.data; 9329 ctx->objmask = NULL; 9330 action_vxlan_encap_data = ctx->object; 9331 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 9332 action->conf = &action_vxlan_encap_data->conf; 9333 return ret; 9334 } 9335 9336 /** Setup NVGRE encap configuration. */ 9337 static int 9338 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 9339 { 9340 /* Set up default configuration. */ 9341 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 9342 .conf = (struct rte_flow_action_nvgre_encap){ 9343 .definition = action_nvgre_encap_data->items, 9344 }, 9345 .items = { 9346 { 9347 .type = RTE_FLOW_ITEM_TYPE_ETH, 9348 .spec = &action_nvgre_encap_data->item_eth, 9349 .mask = &rte_flow_item_eth_mask, 9350 }, 9351 { 9352 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9353 .spec = &action_nvgre_encap_data->item_vlan, 9354 .mask = &rte_flow_item_vlan_mask, 9355 }, 9356 { 9357 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9358 .spec = &action_nvgre_encap_data->item_ipv4, 9359 .mask = &rte_flow_item_ipv4_mask, 9360 }, 9361 { 9362 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 9363 .spec = &action_nvgre_encap_data->item_nvgre, 9364 .mask = &rte_flow_item_nvgre_mask, 9365 }, 9366 { 9367 .type = RTE_FLOW_ITEM_TYPE_END, 9368 }, 9369 }, 9370 .item_eth.hdr.ether_type = 0, 9371 .item_vlan = { 9372 .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, 9373 .hdr.eth_proto = 0, 9374 }, 9375 .item_ipv4.hdr = { 9376 .src_addr = nvgre_encap_conf.ipv4_src, 9377 .dst_addr = nvgre_encap_conf.ipv4_dst, 9378 }, 9379 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 9380 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 9381 .item_nvgre.flow_id = 0, 9382 }; 9383 memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9384 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9385 memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, 9386 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9387 if (!nvgre_encap_conf.select_ipv4) { 9388 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 9389 &nvgre_encap_conf.ipv6_src, 9390 sizeof(nvgre_encap_conf.ipv6_src)); 9391 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 9392 &nvgre_encap_conf.ipv6_dst, 9393 sizeof(nvgre_encap_conf.ipv6_dst)); 9394 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 9395 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9396 .spec = &action_nvgre_encap_data->item_ipv6, 9397 .mask = &rte_flow_item_ipv6_mask, 9398 }; 9399 } 9400 if (!nvgre_encap_conf.select_vlan) 9401 action_nvgre_encap_data->items[1].type = 9402 RTE_FLOW_ITEM_TYPE_VOID; 9403 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 9404 RTE_DIM(nvgre_encap_conf.tni)); 9405 return 0; 9406 } 9407 9408 /** Parse NVGRE encap action. */ 9409 static int 9410 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 9411 const char *str, unsigned int len, 9412 void *buf, unsigned int size) 9413 { 9414 struct buffer *out = buf; 9415 struct rte_flow_action *action; 9416 struct action_nvgre_encap_data *action_nvgre_encap_data; 9417 int ret; 9418 9419 ret = parse_vc(ctx, token, str, len, buf, size); 9420 if (ret < 0) 9421 return ret; 9422 /* Nothing else to do if there is no buffer. */ 9423 if (!out) 9424 return ret; 9425 if (!out->args.vc.actions_n) 9426 return -1; 9427 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9428 /* Point to selected object. */ 9429 ctx->object = out->args.vc.data; 9430 ctx->objmask = NULL; 9431 action_nvgre_encap_data = ctx->object; 9432 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 9433 action->conf = &action_nvgre_encap_data->conf; 9434 return ret; 9435 } 9436 9437 /** Parse l2 encap action. */ 9438 static int 9439 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 9440 const char *str, unsigned int len, 9441 void *buf, unsigned int size) 9442 { 9443 struct buffer *out = buf; 9444 struct rte_flow_action *action; 9445 struct action_raw_encap_data *action_encap_data; 9446 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9447 struct rte_flow_item_vlan vlan = { 9448 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9449 .hdr.eth_proto = 0, 9450 }; 9451 uint8_t *header; 9452 int ret; 9453 9454 ret = parse_vc(ctx, token, str, len, buf, size); 9455 if (ret < 0) 9456 return ret; 9457 /* Nothing else to do if there is no buffer. */ 9458 if (!out) 9459 return ret; 9460 if (!out->args.vc.actions_n) 9461 return -1; 9462 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9463 /* Point to selected object. */ 9464 ctx->object = out->args.vc.data; 9465 ctx->objmask = NULL; 9466 /* Copy the headers to the buffer. */ 9467 action_encap_data = ctx->object; 9468 *action_encap_data = (struct action_raw_encap_data) { 9469 .conf = (struct rte_flow_action_raw_encap){ 9470 .data = action_encap_data->data, 9471 }, 9472 .data = {}, 9473 }; 9474 header = action_encap_data->data; 9475 if (l2_encap_conf.select_vlan) 9476 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9477 else if (l2_encap_conf.select_ipv4) 9478 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9479 else 9480 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9481 memcpy(eth.hdr.dst_addr.addr_bytes, 9482 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9483 memcpy(eth.hdr.src_addr.addr_bytes, 9484 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9485 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9486 header += sizeof(struct rte_ether_hdr); 9487 if (l2_encap_conf.select_vlan) { 9488 if (l2_encap_conf.select_ipv4) 9489 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9490 else 9491 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9492 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9493 header += sizeof(struct rte_vlan_hdr); 9494 } 9495 action_encap_data->conf.size = header - 9496 action_encap_data->data; 9497 action->conf = &action_encap_data->conf; 9498 return ret; 9499 } 9500 9501 /** Parse l2 decap action. */ 9502 static int 9503 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 9504 const char *str, unsigned int len, 9505 void *buf, unsigned int size) 9506 { 9507 struct buffer *out = buf; 9508 struct rte_flow_action *action; 9509 struct action_raw_decap_data *action_decap_data; 9510 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9511 struct rte_flow_item_vlan vlan = { 9512 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9513 .hdr.eth_proto = 0, 9514 }; 9515 uint8_t *header; 9516 int ret; 9517 9518 ret = parse_vc(ctx, token, str, len, buf, size); 9519 if (ret < 0) 9520 return ret; 9521 /* Nothing else to do if there is no buffer. */ 9522 if (!out) 9523 return ret; 9524 if (!out->args.vc.actions_n) 9525 return -1; 9526 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9527 /* Point to selected object. */ 9528 ctx->object = out->args.vc.data; 9529 ctx->objmask = NULL; 9530 /* Copy the headers to the buffer. */ 9531 action_decap_data = ctx->object; 9532 *action_decap_data = (struct action_raw_decap_data) { 9533 .conf = (struct rte_flow_action_raw_decap){ 9534 .data = action_decap_data->data, 9535 }, 9536 .data = {}, 9537 }; 9538 header = action_decap_data->data; 9539 if (l2_decap_conf.select_vlan) 9540 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9541 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9542 header += sizeof(struct rte_ether_hdr); 9543 if (l2_decap_conf.select_vlan) { 9544 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9545 header += sizeof(struct rte_vlan_hdr); 9546 } 9547 action_decap_data->conf.size = header - 9548 action_decap_data->data; 9549 action->conf = &action_decap_data->conf; 9550 return ret; 9551 } 9552 9553 #define ETHER_TYPE_MPLS_UNICAST 0x8847 9554 9555 /** Parse MPLSOGRE encap action. */ 9556 static int 9557 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 9558 const char *str, unsigned int len, 9559 void *buf, unsigned int size) 9560 { 9561 struct buffer *out = buf; 9562 struct rte_flow_action *action; 9563 struct action_raw_encap_data *action_encap_data; 9564 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9565 struct rte_flow_item_vlan vlan = { 9566 .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, 9567 .hdr.eth_proto = 0, 9568 }; 9569 struct rte_flow_item_ipv4 ipv4 = { 9570 .hdr = { 9571 .src_addr = mplsogre_encap_conf.ipv4_src, 9572 .dst_addr = mplsogre_encap_conf.ipv4_dst, 9573 .next_proto_id = IPPROTO_GRE, 9574 .version_ihl = RTE_IPV4_VHL_DEF, 9575 .time_to_live = IPDEFTTL, 9576 }, 9577 }; 9578 struct rte_flow_item_ipv6 ipv6 = { 9579 .hdr = { 9580 .proto = IPPROTO_GRE, 9581 .hop_limits = IPDEFTTL, 9582 }, 9583 }; 9584 struct rte_flow_item_gre gre = { 9585 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9586 }; 9587 struct rte_flow_item_mpls mpls = { 9588 .ttl = 0, 9589 }; 9590 uint8_t *header; 9591 int ret; 9592 9593 ret = parse_vc(ctx, token, str, len, buf, size); 9594 if (ret < 0) 9595 return ret; 9596 /* Nothing else to do if there is no buffer. */ 9597 if (!out) 9598 return ret; 9599 if (!out->args.vc.actions_n) 9600 return -1; 9601 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9602 /* Point to selected object. */ 9603 ctx->object = out->args.vc.data; 9604 ctx->objmask = NULL; 9605 /* Copy the headers to the buffer. */ 9606 action_encap_data = ctx->object; 9607 *action_encap_data = (struct action_raw_encap_data) { 9608 .conf = (struct rte_flow_action_raw_encap){ 9609 .data = action_encap_data->data, 9610 }, 9611 .data = {}, 9612 .preserve = {}, 9613 }; 9614 header = action_encap_data->data; 9615 if (mplsogre_encap_conf.select_vlan) 9616 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9617 else if (mplsogre_encap_conf.select_ipv4) 9618 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9619 else 9620 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9621 memcpy(eth.hdr.dst_addr.addr_bytes, 9622 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9623 memcpy(eth.hdr.src_addr.addr_bytes, 9624 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9625 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9626 header += sizeof(struct rte_ether_hdr); 9627 if (mplsogre_encap_conf.select_vlan) { 9628 if (mplsogre_encap_conf.select_ipv4) 9629 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9630 else 9631 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9632 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9633 header += sizeof(struct rte_vlan_hdr); 9634 } 9635 if (mplsogre_encap_conf.select_ipv4) { 9636 memcpy(header, &ipv4, sizeof(ipv4)); 9637 header += sizeof(ipv4); 9638 } else { 9639 memcpy(&ipv6.hdr.src_addr, 9640 &mplsogre_encap_conf.ipv6_src, 9641 sizeof(mplsogre_encap_conf.ipv6_src)); 9642 memcpy(&ipv6.hdr.dst_addr, 9643 &mplsogre_encap_conf.ipv6_dst, 9644 sizeof(mplsogre_encap_conf.ipv6_dst)); 9645 memcpy(header, &ipv6, sizeof(ipv6)); 9646 header += sizeof(ipv6); 9647 } 9648 memcpy(header, &gre, sizeof(gre)); 9649 header += sizeof(gre); 9650 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 9651 RTE_DIM(mplsogre_encap_conf.label)); 9652 mpls.label_tc_s[2] |= 0x1; 9653 memcpy(header, &mpls, sizeof(mpls)); 9654 header += sizeof(mpls); 9655 action_encap_data->conf.size = header - 9656 action_encap_data->data; 9657 action->conf = &action_encap_data->conf; 9658 return ret; 9659 } 9660 9661 /** Parse MPLSOGRE decap action. */ 9662 static int 9663 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 9664 const char *str, unsigned int len, 9665 void *buf, unsigned int size) 9666 { 9667 struct buffer *out = buf; 9668 struct rte_flow_action *action; 9669 struct action_raw_decap_data *action_decap_data; 9670 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9671 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9672 struct rte_flow_item_ipv4 ipv4 = { 9673 .hdr = { 9674 .next_proto_id = IPPROTO_GRE, 9675 }, 9676 }; 9677 struct rte_flow_item_ipv6 ipv6 = { 9678 .hdr = { 9679 .proto = IPPROTO_GRE, 9680 }, 9681 }; 9682 struct rte_flow_item_gre gre = { 9683 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9684 }; 9685 struct rte_flow_item_mpls mpls; 9686 uint8_t *header; 9687 int ret; 9688 9689 ret = parse_vc(ctx, token, str, len, buf, size); 9690 if (ret < 0) 9691 return ret; 9692 /* Nothing else to do if there is no buffer. */ 9693 if (!out) 9694 return ret; 9695 if (!out->args.vc.actions_n) 9696 return -1; 9697 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9698 /* Point to selected object. */ 9699 ctx->object = out->args.vc.data; 9700 ctx->objmask = NULL; 9701 /* Copy the headers to the buffer. */ 9702 action_decap_data = ctx->object; 9703 *action_decap_data = (struct action_raw_decap_data) { 9704 .conf = (struct rte_flow_action_raw_decap){ 9705 .data = action_decap_data->data, 9706 }, 9707 .data = {}, 9708 }; 9709 header = action_decap_data->data; 9710 if (mplsogre_decap_conf.select_vlan) 9711 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9712 else if (mplsogre_encap_conf.select_ipv4) 9713 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9714 else 9715 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9716 memcpy(eth.hdr.dst_addr.addr_bytes, 9717 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9718 memcpy(eth.hdr.src_addr.addr_bytes, 9719 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9720 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9721 header += sizeof(struct rte_ether_hdr); 9722 if (mplsogre_encap_conf.select_vlan) { 9723 if (mplsogre_encap_conf.select_ipv4) 9724 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9725 else 9726 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9727 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9728 header += sizeof(struct rte_vlan_hdr); 9729 } 9730 if (mplsogre_encap_conf.select_ipv4) { 9731 memcpy(header, &ipv4, sizeof(ipv4)); 9732 header += sizeof(ipv4); 9733 } else { 9734 memcpy(header, &ipv6, sizeof(ipv6)); 9735 header += sizeof(ipv6); 9736 } 9737 memcpy(header, &gre, sizeof(gre)); 9738 header += sizeof(gre); 9739 memset(&mpls, 0, sizeof(mpls)); 9740 memcpy(header, &mpls, sizeof(mpls)); 9741 header += sizeof(mpls); 9742 action_decap_data->conf.size = header - 9743 action_decap_data->data; 9744 action->conf = &action_decap_data->conf; 9745 return ret; 9746 } 9747 9748 /** Parse MPLSOUDP encap action. */ 9749 static int 9750 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 9751 const char *str, unsigned int len, 9752 void *buf, unsigned int size) 9753 { 9754 struct buffer *out = buf; 9755 struct rte_flow_action *action; 9756 struct action_raw_encap_data *action_encap_data; 9757 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9758 struct rte_flow_item_vlan vlan = { 9759 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9760 .hdr.eth_proto = 0, 9761 }; 9762 struct rte_flow_item_ipv4 ipv4 = { 9763 .hdr = { 9764 .src_addr = mplsoudp_encap_conf.ipv4_src, 9765 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 9766 .next_proto_id = IPPROTO_UDP, 9767 .version_ihl = RTE_IPV4_VHL_DEF, 9768 .time_to_live = IPDEFTTL, 9769 }, 9770 }; 9771 struct rte_flow_item_ipv6 ipv6 = { 9772 .hdr = { 9773 .proto = IPPROTO_UDP, 9774 .hop_limits = IPDEFTTL, 9775 }, 9776 }; 9777 struct rte_flow_item_udp udp = { 9778 .hdr = { 9779 .src_port = mplsoudp_encap_conf.udp_src, 9780 .dst_port = mplsoudp_encap_conf.udp_dst, 9781 }, 9782 }; 9783 struct rte_flow_item_mpls mpls; 9784 uint8_t *header; 9785 int ret; 9786 9787 ret = parse_vc(ctx, token, str, len, buf, size); 9788 if (ret < 0) 9789 return ret; 9790 /* Nothing else to do if there is no buffer. */ 9791 if (!out) 9792 return ret; 9793 if (!out->args.vc.actions_n) 9794 return -1; 9795 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9796 /* Point to selected object. */ 9797 ctx->object = out->args.vc.data; 9798 ctx->objmask = NULL; 9799 /* Copy the headers to the buffer. */ 9800 action_encap_data = ctx->object; 9801 *action_encap_data = (struct action_raw_encap_data) { 9802 .conf = (struct rte_flow_action_raw_encap){ 9803 .data = action_encap_data->data, 9804 }, 9805 .data = {}, 9806 .preserve = {}, 9807 }; 9808 header = action_encap_data->data; 9809 if (mplsoudp_encap_conf.select_vlan) 9810 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9811 else if (mplsoudp_encap_conf.select_ipv4) 9812 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9813 else 9814 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9815 memcpy(eth.hdr.dst_addr.addr_bytes, 9816 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9817 memcpy(eth.hdr.src_addr.addr_bytes, 9818 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9819 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9820 header += sizeof(struct rte_ether_hdr); 9821 if (mplsoudp_encap_conf.select_vlan) { 9822 if (mplsoudp_encap_conf.select_ipv4) 9823 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9824 else 9825 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9826 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9827 header += sizeof(struct rte_vlan_hdr); 9828 } 9829 if (mplsoudp_encap_conf.select_ipv4) { 9830 memcpy(header, &ipv4, sizeof(ipv4)); 9831 header += sizeof(ipv4); 9832 } else { 9833 memcpy(&ipv6.hdr.src_addr, 9834 &mplsoudp_encap_conf.ipv6_src, 9835 sizeof(mplsoudp_encap_conf.ipv6_src)); 9836 memcpy(&ipv6.hdr.dst_addr, 9837 &mplsoudp_encap_conf.ipv6_dst, 9838 sizeof(mplsoudp_encap_conf.ipv6_dst)); 9839 memcpy(header, &ipv6, sizeof(ipv6)); 9840 header += sizeof(ipv6); 9841 } 9842 memcpy(header, &udp, sizeof(udp)); 9843 header += sizeof(udp); 9844 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 9845 RTE_DIM(mplsoudp_encap_conf.label)); 9846 mpls.label_tc_s[2] |= 0x1; 9847 memcpy(header, &mpls, sizeof(mpls)); 9848 header += sizeof(mpls); 9849 action_encap_data->conf.size = header - 9850 action_encap_data->data; 9851 action->conf = &action_encap_data->conf; 9852 return ret; 9853 } 9854 9855 /** Parse MPLSOUDP decap action. */ 9856 static int 9857 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 9858 const char *str, unsigned int len, 9859 void *buf, unsigned int size) 9860 { 9861 struct buffer *out = buf; 9862 struct rte_flow_action *action; 9863 struct action_raw_decap_data *action_decap_data; 9864 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9865 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9866 struct rte_flow_item_ipv4 ipv4 = { 9867 .hdr = { 9868 .next_proto_id = IPPROTO_UDP, 9869 }, 9870 }; 9871 struct rte_flow_item_ipv6 ipv6 = { 9872 .hdr = { 9873 .proto = IPPROTO_UDP, 9874 }, 9875 }; 9876 struct rte_flow_item_udp udp = { 9877 .hdr = { 9878 .dst_port = rte_cpu_to_be_16(6635), 9879 }, 9880 }; 9881 struct rte_flow_item_mpls mpls; 9882 uint8_t *header; 9883 int ret; 9884 9885 ret = parse_vc(ctx, token, str, len, buf, size); 9886 if (ret < 0) 9887 return ret; 9888 /* Nothing else to do if there is no buffer. */ 9889 if (!out) 9890 return ret; 9891 if (!out->args.vc.actions_n) 9892 return -1; 9893 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9894 /* Point to selected object. */ 9895 ctx->object = out->args.vc.data; 9896 ctx->objmask = NULL; 9897 /* Copy the headers to the buffer. */ 9898 action_decap_data = ctx->object; 9899 *action_decap_data = (struct action_raw_decap_data) { 9900 .conf = (struct rte_flow_action_raw_decap){ 9901 .data = action_decap_data->data, 9902 }, 9903 .data = {}, 9904 }; 9905 header = action_decap_data->data; 9906 if (mplsoudp_decap_conf.select_vlan) 9907 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9908 else if (mplsoudp_encap_conf.select_ipv4) 9909 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9910 else 9911 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9912 memcpy(eth.hdr.dst_addr.addr_bytes, 9913 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9914 memcpy(eth.hdr.src_addr.addr_bytes, 9915 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9916 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9917 header += sizeof(struct rte_ether_hdr); 9918 if (mplsoudp_encap_conf.select_vlan) { 9919 if (mplsoudp_encap_conf.select_ipv4) 9920 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9921 else 9922 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9923 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9924 header += sizeof(struct rte_vlan_hdr); 9925 } 9926 if (mplsoudp_encap_conf.select_ipv4) { 9927 memcpy(header, &ipv4, sizeof(ipv4)); 9928 header += sizeof(ipv4); 9929 } else { 9930 memcpy(header, &ipv6, sizeof(ipv6)); 9931 header += sizeof(ipv6); 9932 } 9933 memcpy(header, &udp, sizeof(udp)); 9934 header += sizeof(udp); 9935 memset(&mpls, 0, sizeof(mpls)); 9936 memcpy(header, &mpls, sizeof(mpls)); 9937 header += sizeof(mpls); 9938 action_decap_data->conf.size = header - 9939 action_decap_data->data; 9940 action->conf = &action_decap_data->conf; 9941 return ret; 9942 } 9943 9944 static int 9945 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 9946 const char *str, unsigned int len, void *buf, 9947 unsigned int size) 9948 { 9949 struct action_raw_decap_data *action_raw_decap_data; 9950 struct rte_flow_action *action; 9951 const struct arg *arg; 9952 struct buffer *out = buf; 9953 int ret; 9954 uint16_t idx; 9955 9956 RTE_SET_USED(token); 9957 RTE_SET_USED(buf); 9958 RTE_SET_USED(size); 9959 arg = ARGS_ENTRY_ARB_BOUNDED 9960 (offsetof(struct action_raw_decap_data, idx), 9961 sizeof(((struct action_raw_decap_data *)0)->idx), 9962 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 9963 if (push_args(ctx, arg)) 9964 return -1; 9965 ret = parse_int(ctx, token, str, len, NULL, 0); 9966 if (ret < 0) { 9967 pop_args(ctx); 9968 return -1; 9969 } 9970 if (!ctx->object) 9971 return len; 9972 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9973 action_raw_decap_data = ctx->object; 9974 idx = action_raw_decap_data->idx; 9975 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 9976 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 9977 action->conf = &action_raw_decap_data->conf; 9978 return len; 9979 } 9980 9981 9982 static int 9983 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 9984 const char *str, unsigned int len, void *buf, 9985 unsigned int size) 9986 { 9987 struct action_raw_encap_data *action_raw_encap_data; 9988 struct rte_flow_action *action; 9989 const struct arg *arg; 9990 struct buffer *out = buf; 9991 int ret; 9992 uint16_t idx; 9993 9994 RTE_SET_USED(token); 9995 RTE_SET_USED(buf); 9996 RTE_SET_USED(size); 9997 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 9998 return -1; 9999 arg = ARGS_ENTRY_ARB_BOUNDED 10000 (offsetof(struct action_raw_encap_data, idx), 10001 sizeof(((struct action_raw_encap_data *)0)->idx), 10002 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10003 if (push_args(ctx, arg)) 10004 return -1; 10005 ret = parse_int(ctx, token, str, len, NULL, 0); 10006 if (ret < 0) { 10007 pop_args(ctx); 10008 return -1; 10009 } 10010 if (!ctx->object) 10011 return len; 10012 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10013 action_raw_encap_data = ctx->object; 10014 idx = action_raw_encap_data->idx; 10015 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 10016 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 10017 action_raw_encap_data->conf.preserve = NULL; 10018 action->conf = &action_raw_encap_data->conf; 10019 return len; 10020 } 10021 10022 static int 10023 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 10024 const char *str, unsigned int len, void *buf, 10025 unsigned int size) 10026 { 10027 struct buffer *out = buf; 10028 int ret; 10029 10030 ret = parse_vc(ctx, token, str, len, buf, size); 10031 if (ret < 0) 10032 return ret; 10033 /* Nothing else to do if there is no buffer. */ 10034 if (!out) 10035 return ret; 10036 if (!out->args.vc.actions_n) 10037 return -1; 10038 /* Point to selected object. */ 10039 ctx->object = out->args.vc.data; 10040 ctx->objmask = NULL; 10041 return ret; 10042 } 10043 10044 static int 10045 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 10046 const char *str, unsigned int len, void *buf, 10047 unsigned int size) 10048 { 10049 struct buffer *out = buf; 10050 struct rte_flow_action *action; 10051 struct action_raw_decap_data *action_raw_decap_data = NULL; 10052 int ret; 10053 10054 ret = parse_vc(ctx, token, str, len, buf, size); 10055 if (ret < 0) 10056 return ret; 10057 /* Nothing else to do if there is no buffer. */ 10058 if (!out) 10059 return ret; 10060 if (!out->args.vc.actions_n) 10061 return -1; 10062 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10063 /* Point to selected object. */ 10064 ctx->object = out->args.vc.data; 10065 ctx->objmask = NULL; 10066 /* Copy the headers to the buffer. */ 10067 action_raw_decap_data = ctx->object; 10068 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 10069 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 10070 action->conf = &action_raw_decap_data->conf; 10071 return ret; 10072 } 10073 10074 static int 10075 parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 10076 const char *str, unsigned int len, void *buf, 10077 unsigned int size) 10078 { 10079 struct buffer *out = buf; 10080 struct rte_flow_action *action; 10081 struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; 10082 int ret; 10083 10084 ret = parse_vc(ctx, token, str, len, buf, size); 10085 if (ret < 0) 10086 return ret; 10087 /* Nothing else to do if there is no buffer. */ 10088 if (!out) 10089 return ret; 10090 if (!out->args.vc.actions_n) 10091 return -1; 10092 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10093 /* Point to selected object. */ 10094 ctx->object = out->args.vc.data; 10095 ctx->objmask = NULL; 10096 /* Copy the headers to the buffer. */ 10097 ipv6_ext_remove_data = ctx->object; 10098 ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; 10099 action->conf = &ipv6_ext_remove_data->conf; 10100 return ret; 10101 } 10102 10103 static int 10104 parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, 10105 const char *str, unsigned int len, void *buf, 10106 unsigned int size) 10107 { 10108 struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; 10109 struct rte_flow_action *action; 10110 const struct arg *arg; 10111 struct buffer *out = buf; 10112 int ret; 10113 uint16_t idx; 10114 10115 RTE_SET_USED(token); 10116 RTE_SET_USED(buf); 10117 RTE_SET_USED(size); 10118 arg = ARGS_ENTRY_ARB_BOUNDED 10119 (offsetof(struct action_ipv6_ext_remove_data, idx), 10120 sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), 10121 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10122 if (push_args(ctx, arg)) 10123 return -1; 10124 ret = parse_int(ctx, token, str, len, NULL, 0); 10125 if (ret < 0) { 10126 pop_args(ctx); 10127 return -1; 10128 } 10129 if (!ctx->object) 10130 return len; 10131 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10132 action_ipv6_ext_remove_data = ctx->object; 10133 idx = action_ipv6_ext_remove_data->idx; 10134 action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; 10135 action->conf = &action_ipv6_ext_remove_data->conf; 10136 return len; 10137 } 10138 10139 static int 10140 parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 10141 const char *str, unsigned int len, void *buf, 10142 unsigned int size) 10143 { 10144 struct buffer *out = buf; 10145 struct rte_flow_action *action; 10146 struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; 10147 int ret; 10148 10149 ret = parse_vc(ctx, token, str, len, buf, size); 10150 if (ret < 0) 10151 return ret; 10152 /* Nothing else to do if there is no buffer. */ 10153 if (!out) 10154 return ret; 10155 if (!out->args.vc.actions_n) 10156 return -1; 10157 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10158 /* Point to selected object. */ 10159 ctx->object = out->args.vc.data; 10160 ctx->objmask = NULL; 10161 /* Copy the headers to the buffer. */ 10162 ipv6_ext_push_data = ctx->object; 10163 ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; 10164 ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; 10165 ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; 10166 action->conf = &ipv6_ext_push_data->conf; 10167 return ret; 10168 } 10169 10170 static int 10171 parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, 10172 const char *str, unsigned int len, void *buf, 10173 unsigned int size) 10174 { 10175 struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; 10176 struct rte_flow_action *action; 10177 const struct arg *arg; 10178 struct buffer *out = buf; 10179 int ret; 10180 uint16_t idx; 10181 10182 RTE_SET_USED(token); 10183 RTE_SET_USED(buf); 10184 RTE_SET_USED(size); 10185 arg = ARGS_ENTRY_ARB_BOUNDED 10186 (offsetof(struct action_ipv6_ext_push_data, idx), 10187 sizeof(((struct action_ipv6_ext_push_data *)0)->idx), 10188 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10189 if (push_args(ctx, arg)) 10190 return -1; 10191 ret = parse_int(ctx, token, str, len, NULL, 0); 10192 if (ret < 0) { 10193 pop_args(ctx); 10194 return -1; 10195 } 10196 if (!ctx->object) 10197 return len; 10198 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10199 action_ipv6_ext_push_data = ctx->object; 10200 idx = action_ipv6_ext_push_data->idx; 10201 action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; 10202 action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; 10203 action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; 10204 action->conf = &action_ipv6_ext_push_data->conf; 10205 return len; 10206 } 10207 10208 static int 10209 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 10210 const char *str, unsigned int len, void *buf, 10211 unsigned int size) 10212 { 10213 int ret; 10214 10215 ret = parse_vc(ctx, token, str, len, buf, size); 10216 if (ret < 0) 10217 return ret; 10218 ret = rte_flow_dynf_metadata_register(); 10219 if (ret < 0) 10220 return -1; 10221 return len; 10222 } 10223 10224 static int 10225 parse_vc_action_sample(struct context *ctx, const struct token *token, 10226 const char *str, unsigned int len, void *buf, 10227 unsigned int size) 10228 { 10229 struct buffer *out = buf; 10230 struct rte_flow_action *action; 10231 struct action_sample_data *action_sample_data = NULL; 10232 static struct rte_flow_action end_action = { 10233 RTE_FLOW_ACTION_TYPE_END, 0 10234 }; 10235 int ret; 10236 10237 ret = parse_vc(ctx, token, str, len, buf, size); 10238 if (ret < 0) 10239 return ret; 10240 /* Nothing else to do if there is no buffer. */ 10241 if (!out) 10242 return ret; 10243 if (!out->args.vc.actions_n) 10244 return -1; 10245 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10246 /* Point to selected object. */ 10247 ctx->object = out->args.vc.data; 10248 ctx->objmask = NULL; 10249 /* Copy the headers to the buffer. */ 10250 action_sample_data = ctx->object; 10251 action_sample_data->conf.actions = &end_action; 10252 action->conf = &action_sample_data->conf; 10253 return ret; 10254 } 10255 10256 static int 10257 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 10258 const char *str, unsigned int len, void *buf, 10259 unsigned int size) 10260 { 10261 struct action_sample_data *action_sample_data; 10262 struct rte_flow_action *action; 10263 const struct arg *arg; 10264 struct buffer *out = buf; 10265 int ret; 10266 uint16_t idx; 10267 10268 RTE_SET_USED(token); 10269 RTE_SET_USED(buf); 10270 RTE_SET_USED(size); 10271 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 10272 return -1; 10273 arg = ARGS_ENTRY_ARB_BOUNDED 10274 (offsetof(struct action_sample_data, idx), 10275 sizeof(((struct action_sample_data *)0)->idx), 10276 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 10277 if (push_args(ctx, arg)) 10278 return -1; 10279 ret = parse_int(ctx, token, str, len, NULL, 0); 10280 if (ret < 0) { 10281 pop_args(ctx); 10282 return -1; 10283 } 10284 if (!ctx->object) 10285 return len; 10286 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10287 action_sample_data = ctx->object; 10288 idx = action_sample_data->idx; 10289 action_sample_data->conf.actions = raw_sample_confs[idx].data; 10290 action->conf = &action_sample_data->conf; 10291 return len; 10292 } 10293 10294 /** Parse operation for modify_field command. */ 10295 static int 10296 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 10297 const char *str, unsigned int len, void *buf, 10298 unsigned int size) 10299 { 10300 struct rte_flow_action_modify_field *action_modify_field; 10301 unsigned int i; 10302 10303 (void)token; 10304 (void)buf; 10305 (void)size; 10306 if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) 10307 return -1; 10308 for (i = 0; modify_field_ops[i]; ++i) 10309 if (!strcmp_partial(modify_field_ops[i], str, len)) 10310 break; 10311 if (!modify_field_ops[i]) 10312 return -1; 10313 if (!ctx->object) 10314 return len; 10315 action_modify_field = ctx->object; 10316 action_modify_field->operation = (enum rte_flow_modify_op)i; 10317 return len; 10318 } 10319 10320 /** Parse id for modify_field command. */ 10321 static int 10322 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 10323 const char *str, unsigned int len, void *buf, 10324 unsigned int size) 10325 { 10326 struct rte_flow_action_modify_field *action_modify_field; 10327 unsigned int i; 10328 10329 (void)token; 10330 (void)buf; 10331 (void)size; 10332 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 10333 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 10334 return -1; 10335 for (i = 0; flow_field_ids[i]; ++i) 10336 if (!strcmp_partial(flow_field_ids[i], str, len)) 10337 break; 10338 if (!flow_field_ids[i]) 10339 return -1; 10340 if (!ctx->object) 10341 return len; 10342 action_modify_field = ctx->object; 10343 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 10344 action_modify_field->dst.field = (enum rte_flow_field_id)i; 10345 else 10346 action_modify_field->src.field = (enum rte_flow_field_id)i; 10347 return len; 10348 } 10349 10350 /** Parse level for modify_field command. */ 10351 static int 10352 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 10353 const char *str, unsigned int len, void *buf, 10354 unsigned int size) 10355 { 10356 struct rte_flow_action_modify_field *action; 10357 struct flex_item *fp = NULL; 10358 uint32_t val; 10359 struct buffer *out = buf; 10360 char *end; 10361 10362 (void)token; 10363 (void)size; 10364 if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10365 ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) 10366 return -1; 10367 if (!ctx->object) 10368 return len; 10369 action = ctx->object; 10370 errno = 0; 10371 val = strtoumax(str, &end, 0); 10372 if (errno || (size_t)(end - str) != len) 10373 return -1; 10374 /* No need to validate action template mask value */ 10375 if (out->args.vc.masks) { 10376 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) 10377 action->dst.level = val; 10378 else 10379 action->src.level = val; 10380 return len; 10381 } 10382 if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10383 action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || 10384 (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && 10385 action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 10386 if (val >= FLEX_MAX_PARSERS_NUM) { 10387 printf("Bad flex item handle\n"); 10388 return -1; 10389 } 10390 fp = flex_items[ctx->port][val]; 10391 if (!fp) { 10392 printf("Bad flex item handle\n"); 10393 return -1; 10394 } 10395 } 10396 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { 10397 if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) 10398 action->dst.level = val; 10399 else 10400 action->dst.flex_handle = fp->flex_handle; 10401 } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { 10402 if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) 10403 action->src.level = val; 10404 else 10405 action->src.flex_handle = fp->flex_handle; 10406 } 10407 return len; 10408 } 10409 10410 /** Parse the conntrack update, not a rte_flow_action. */ 10411 static int 10412 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 10413 const char *str, unsigned int len, void *buf, 10414 unsigned int size) 10415 { 10416 struct buffer *out = buf; 10417 struct rte_flow_modify_conntrack *ct_modify = NULL; 10418 10419 (void)size; 10420 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 10421 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 10422 return -1; 10423 /* Token name must match. */ 10424 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10425 return -1; 10426 /* Nothing else to do if there is no buffer. */ 10427 if (!out) 10428 return len; 10429 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 10430 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 10431 ct_modify->new_ct.is_original_dir = 10432 conntrack_context.is_original_dir; 10433 ct_modify->direction = 1; 10434 } else { 10435 uint32_t old_dir; 10436 10437 old_dir = ct_modify->new_ct.is_original_dir; 10438 memcpy(&ct_modify->new_ct, &conntrack_context, 10439 sizeof(conntrack_context)); 10440 ct_modify->new_ct.is_original_dir = old_dir; 10441 ct_modify->state = 1; 10442 } 10443 return len; 10444 } 10445 10446 /** Parse tokens for destroy command. */ 10447 static int 10448 parse_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 10454 /* Token name must match. */ 10455 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10456 return -1; 10457 /* Nothing else to do if there is no buffer. */ 10458 if (!out) 10459 return len; 10460 if (!out->command) { 10461 if (ctx->curr != DESTROY) 10462 return -1; 10463 if (sizeof(*out) > size) 10464 return -1; 10465 out->command = ctx->curr; 10466 ctx->objdata = 0; 10467 ctx->object = out; 10468 ctx->objmask = NULL; 10469 out->args.destroy.rule = 10470 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10471 sizeof(double)); 10472 return len; 10473 } 10474 if (ctx->curr == DESTROY_IS_USER_ID) { 10475 out->args.destroy.is_user_id = true; 10476 return len; 10477 } 10478 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 10479 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 10480 return -1; 10481 ctx->objdata = 0; 10482 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 10483 ctx->objmask = NULL; 10484 return len; 10485 } 10486 10487 /** Parse tokens for flush command. */ 10488 static int 10489 parse_flush(struct context *ctx, const struct token *token, 10490 const char *str, unsigned int len, 10491 void *buf, unsigned int size) 10492 { 10493 struct buffer *out = buf; 10494 10495 /* Token name must match. */ 10496 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10497 return -1; 10498 /* Nothing else to do if there is no buffer. */ 10499 if (!out) 10500 return len; 10501 if (!out->command) { 10502 if (ctx->curr != FLUSH) 10503 return -1; 10504 if (sizeof(*out) > size) 10505 return -1; 10506 out->command = ctx->curr; 10507 ctx->objdata = 0; 10508 ctx->object = out; 10509 ctx->objmask = NULL; 10510 } 10511 return len; 10512 } 10513 10514 /** Parse tokens for dump command. */ 10515 static int 10516 parse_dump(struct context *ctx, const struct token *token, 10517 const char *str, unsigned int len, 10518 void *buf, unsigned int size) 10519 { 10520 struct buffer *out = buf; 10521 10522 /* Token name must match. */ 10523 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10524 return -1; 10525 /* Nothing else to do if there is no buffer. */ 10526 if (!out) 10527 return len; 10528 if (!out->command) { 10529 if (ctx->curr != DUMP) 10530 return -1; 10531 if (sizeof(*out) > size) 10532 return -1; 10533 out->command = ctx->curr; 10534 ctx->objdata = 0; 10535 ctx->object = out; 10536 ctx->objmask = NULL; 10537 return len; 10538 } 10539 switch (ctx->curr) { 10540 case DUMP_ALL: 10541 case DUMP_ONE: 10542 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 10543 out->command = ctx->curr; 10544 ctx->objdata = 0; 10545 ctx->object = out; 10546 ctx->objmask = NULL; 10547 return len; 10548 case DUMP_IS_USER_ID: 10549 out->args.dump.is_user_id = true; 10550 return len; 10551 default: 10552 return -1; 10553 } 10554 } 10555 10556 /** Parse tokens for query command. */ 10557 static int 10558 parse_query(struct context *ctx, const struct token *token, 10559 const char *str, unsigned int len, 10560 void *buf, unsigned int size) 10561 { 10562 struct buffer *out = buf; 10563 10564 /* Token name must match. */ 10565 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10566 return -1; 10567 /* Nothing else to do if there is no buffer. */ 10568 if (!out) 10569 return len; 10570 if (!out->command) { 10571 if (ctx->curr != QUERY) 10572 return -1; 10573 if (sizeof(*out) > size) 10574 return -1; 10575 out->command = ctx->curr; 10576 ctx->objdata = 0; 10577 ctx->object = out; 10578 ctx->objmask = NULL; 10579 } 10580 if (ctx->curr == QUERY_IS_USER_ID) { 10581 out->args.query.is_user_id = true; 10582 return len; 10583 } 10584 return len; 10585 } 10586 10587 /** Parse action names. */ 10588 static int 10589 parse_action(struct context *ctx, const struct token *token, 10590 const char *str, unsigned int len, 10591 void *buf, unsigned int size) 10592 { 10593 struct buffer *out = buf; 10594 const struct arg *arg = pop_args(ctx); 10595 unsigned int i; 10596 10597 (void)size; 10598 /* Argument is expected. */ 10599 if (!arg) 10600 return -1; 10601 /* Parse action name. */ 10602 for (i = 0; next_action[i]; ++i) { 10603 const struct parse_action_priv *priv; 10604 10605 token = &token_list[next_action[i]]; 10606 if (strcmp_partial(token->name, str, len)) 10607 continue; 10608 priv = token->priv; 10609 if (!priv) 10610 goto error; 10611 if (out) 10612 memcpy((uint8_t *)ctx->object + arg->offset, 10613 &priv->type, 10614 arg->size); 10615 return len; 10616 } 10617 error: 10618 push_args(ctx, arg); 10619 return -1; 10620 } 10621 10622 /** Parse tokens for list command. */ 10623 static int 10624 parse_list(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 != LIST) 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.list.group = 10646 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10647 sizeof(double)); 10648 return len; 10649 } 10650 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 10651 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 10652 return -1; 10653 ctx->objdata = 0; 10654 ctx->object = out->args.list.group + out->args.list.group_n++; 10655 ctx->objmask = NULL; 10656 return len; 10657 } 10658 10659 /** Parse tokens for list all aged flows command. */ 10660 static int 10661 parse_aged(struct context *ctx, const struct token *token, 10662 const char *str, unsigned int len, 10663 void *buf, unsigned int size) 10664 { 10665 struct buffer *out = buf; 10666 10667 /* Token name must match. */ 10668 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10669 return -1; 10670 /* Nothing else to do if there is no buffer. */ 10671 if (!out) 10672 return len; 10673 if (!out->command || out->command == QUEUE) { 10674 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 10675 return -1; 10676 if (sizeof(*out) > size) 10677 return -1; 10678 out->command = ctx->curr; 10679 ctx->objdata = 0; 10680 ctx->object = out; 10681 ctx->objmask = NULL; 10682 } 10683 if (ctx->curr == AGED_DESTROY) 10684 out->args.aged.destroy = 1; 10685 return len; 10686 } 10687 10688 /** Parse tokens for isolate command. */ 10689 static int 10690 parse_isolate(struct context *ctx, const struct token *token, 10691 const char *str, unsigned int len, 10692 void *buf, unsigned int size) 10693 { 10694 struct buffer *out = buf; 10695 10696 /* Token name must match. */ 10697 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10698 return -1; 10699 /* Nothing else to do if there is no buffer. */ 10700 if (!out) 10701 return len; 10702 if (!out->command) { 10703 if (ctx->curr != ISOLATE) 10704 return -1; 10705 if (sizeof(*out) > size) 10706 return -1; 10707 out->command = ctx->curr; 10708 ctx->objdata = 0; 10709 ctx->object = out; 10710 ctx->objmask = NULL; 10711 } 10712 return len; 10713 } 10714 10715 /** Parse tokens for info/configure command. */ 10716 static int 10717 parse_configure(struct context *ctx, const struct token *token, 10718 const char *str, unsigned int len, 10719 void *buf, unsigned int size) 10720 { 10721 struct buffer *out = buf; 10722 10723 /* Token name must match. */ 10724 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10725 return -1; 10726 /* Nothing else to do if there is no buffer. */ 10727 if (!out) 10728 return len; 10729 if (!out->command) { 10730 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 10731 return -1; 10732 if (sizeof(*out) > size) 10733 return -1; 10734 out->command = ctx->curr; 10735 ctx->objdata = 0; 10736 ctx->object = out; 10737 ctx->objmask = NULL; 10738 } 10739 return len; 10740 } 10741 10742 /** Parse tokens for template create command. */ 10743 static int 10744 parse_template(struct context *ctx, const struct token *token, 10745 const char *str, unsigned int len, 10746 void *buf, unsigned int size) 10747 { 10748 struct buffer *out = buf; 10749 10750 /* Token name must match. */ 10751 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10752 return -1; 10753 /* Nothing else to do if there is no buffer. */ 10754 if (!out) 10755 return len; 10756 if (!out->command) { 10757 if (ctx->curr != PATTERN_TEMPLATE && 10758 ctx->curr != ACTIONS_TEMPLATE) 10759 return -1; 10760 if (sizeof(*out) > size) 10761 return -1; 10762 out->command = ctx->curr; 10763 ctx->objdata = 0; 10764 ctx->object = out; 10765 ctx->objmask = NULL; 10766 out->args.vc.data = (uint8_t *)out + size; 10767 return len; 10768 } 10769 switch (ctx->curr) { 10770 case PATTERN_TEMPLATE_CREATE: 10771 out->args.vc.pattern = 10772 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10773 sizeof(double)); 10774 out->args.vc.pat_templ_id = UINT32_MAX; 10775 out->command = ctx->curr; 10776 ctx->objdata = 0; 10777 ctx->object = out; 10778 ctx->objmask = NULL; 10779 return len; 10780 case PATTERN_TEMPLATE_EGRESS: 10781 out->args.vc.attr.egress = 1; 10782 return len; 10783 case PATTERN_TEMPLATE_INGRESS: 10784 out->args.vc.attr.ingress = 1; 10785 return len; 10786 case PATTERN_TEMPLATE_TRANSFER: 10787 out->args.vc.attr.transfer = 1; 10788 return len; 10789 case ACTIONS_TEMPLATE_CREATE: 10790 out->args.vc.act_templ_id = UINT32_MAX; 10791 out->command = ctx->curr; 10792 ctx->objdata = 0; 10793 ctx->object = out; 10794 ctx->objmask = NULL; 10795 return len; 10796 case ACTIONS_TEMPLATE_SPEC: 10797 out->args.vc.actions = 10798 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10799 sizeof(double)); 10800 ctx->object = out->args.vc.actions; 10801 ctx->objmask = NULL; 10802 return len; 10803 case ACTIONS_TEMPLATE_MASK: 10804 out->args.vc.masks = 10805 (void *)RTE_ALIGN_CEIL((uintptr_t) 10806 (out->args.vc.actions + 10807 out->args.vc.actions_n), 10808 sizeof(double)); 10809 ctx->object = out->args.vc.masks; 10810 ctx->objmask = NULL; 10811 return len; 10812 case ACTIONS_TEMPLATE_EGRESS: 10813 out->args.vc.attr.egress = 1; 10814 return len; 10815 case ACTIONS_TEMPLATE_INGRESS: 10816 out->args.vc.attr.ingress = 1; 10817 return len; 10818 case ACTIONS_TEMPLATE_TRANSFER: 10819 out->args.vc.attr.transfer = 1; 10820 return len; 10821 default: 10822 return -1; 10823 } 10824 } 10825 10826 /** Parse tokens for template destroy command. */ 10827 static int 10828 parse_template_destroy(struct context *ctx, const struct token *token, 10829 const char *str, unsigned int len, 10830 void *buf, unsigned int size) 10831 { 10832 struct buffer *out = buf; 10833 uint32_t *template_id; 10834 10835 /* Token name must match. */ 10836 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10837 return -1; 10838 /* Nothing else to do if there is no buffer. */ 10839 if (!out) 10840 return len; 10841 if (!out->command || 10842 out->command == PATTERN_TEMPLATE || 10843 out->command == ACTIONS_TEMPLATE) { 10844 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 10845 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 10846 return -1; 10847 if (sizeof(*out) > size) 10848 return -1; 10849 out->command = ctx->curr; 10850 ctx->objdata = 0; 10851 ctx->object = out; 10852 ctx->objmask = NULL; 10853 out->args.templ_destroy.template_id = 10854 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10855 sizeof(double)); 10856 return len; 10857 } 10858 template_id = out->args.templ_destroy.template_id 10859 + out->args.templ_destroy.template_id_n++; 10860 if ((uint8_t *)template_id > (uint8_t *)out + size) 10861 return -1; 10862 ctx->objdata = 0; 10863 ctx->object = template_id; 10864 ctx->objmask = NULL; 10865 return len; 10866 } 10867 10868 /** Parse tokens for table create command. */ 10869 static int 10870 parse_table(struct context *ctx, const struct token *token, 10871 const char *str, unsigned int len, 10872 void *buf, unsigned int size) 10873 { 10874 struct buffer *out = buf; 10875 uint32_t *template_id; 10876 10877 /* Token name must match. */ 10878 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10879 return -1; 10880 /* Nothing else to do if there is no buffer. */ 10881 if (!out) 10882 return len; 10883 if (!out->command) { 10884 if (ctx->curr != TABLE) 10885 return -1; 10886 if (sizeof(*out) > size) 10887 return -1; 10888 out->command = ctx->curr; 10889 ctx->objdata = 0; 10890 ctx->object = out; 10891 ctx->objmask = NULL; 10892 return len; 10893 } 10894 switch (ctx->curr) { 10895 case TABLE_CREATE: 10896 case TABLE_RESIZE: 10897 out->command = ctx->curr; 10898 ctx->objdata = 0; 10899 ctx->object = out; 10900 ctx->objmask = NULL; 10901 out->args.table.id = UINT32_MAX; 10902 return len; 10903 case TABLE_PATTERN_TEMPLATE: 10904 out->args.table.pat_templ_id = 10905 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10906 sizeof(double)); 10907 template_id = out->args.table.pat_templ_id 10908 + out->args.table.pat_templ_id_n++; 10909 if ((uint8_t *)template_id > (uint8_t *)out + size) 10910 return -1; 10911 ctx->objdata = 0; 10912 ctx->object = template_id; 10913 ctx->objmask = NULL; 10914 return len; 10915 case TABLE_ACTIONS_TEMPLATE: 10916 out->args.table.act_templ_id = 10917 (void *)RTE_ALIGN_CEIL((uintptr_t) 10918 (out->args.table.pat_templ_id + 10919 out->args.table.pat_templ_id_n), 10920 sizeof(double)); 10921 template_id = out->args.table.act_templ_id 10922 + out->args.table.act_templ_id_n++; 10923 if ((uint8_t *)template_id > (uint8_t *)out + size) 10924 return -1; 10925 ctx->objdata = 0; 10926 ctx->object = template_id; 10927 ctx->objmask = NULL; 10928 return len; 10929 case TABLE_INGRESS: 10930 out->args.table.attr.flow_attr.ingress = 1; 10931 return len; 10932 case TABLE_EGRESS: 10933 out->args.table.attr.flow_attr.egress = 1; 10934 return len; 10935 case TABLE_TRANSFER: 10936 out->args.table.attr.flow_attr.transfer = 1; 10937 return len; 10938 case TABLE_TRANSFER_WIRE_ORIG: 10939 if (!out->args.table.attr.flow_attr.transfer) 10940 return -1; 10941 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; 10942 return len; 10943 case TABLE_TRANSFER_VPORT_ORIG: 10944 if (!out->args.table.attr.flow_attr.transfer) 10945 return -1; 10946 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; 10947 return len; 10948 case TABLE_RESIZABLE: 10949 out->args.table.attr.specialize |= 10950 RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE; 10951 return len; 10952 case TABLE_RULES_NUMBER: 10953 ctx->objdata = 0; 10954 ctx->object = out; 10955 ctx->objmask = NULL; 10956 return len; 10957 case TABLE_RESIZE_ID: 10958 case TABLE_RESIZE_RULES_NUMBER: 10959 return len; 10960 default: 10961 return -1; 10962 } 10963 } 10964 10965 /** Parse tokens for table destroy command. */ 10966 static int 10967 parse_table_destroy(struct context *ctx, const struct token *token, 10968 const char *str, unsigned int len, 10969 void *buf, unsigned int size) 10970 { 10971 struct buffer *out = buf; 10972 uint32_t *table_id; 10973 10974 /* Token name must match. */ 10975 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10976 return -1; 10977 /* Nothing else to do if there is no buffer. */ 10978 if (!out) 10979 return len; 10980 if (!out->command || out->command == TABLE) { 10981 if (ctx->curr != TABLE_DESTROY && 10982 ctx->curr != TABLE_RESIZE_COMPLETE) 10983 return -1; 10984 if (sizeof(*out) > size) 10985 return -1; 10986 out->command = ctx->curr; 10987 ctx->objdata = 0; 10988 ctx->object = out; 10989 ctx->objmask = NULL; 10990 out->args.table_destroy.table_id = 10991 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10992 sizeof(double)); 10993 return len; 10994 } 10995 table_id = out->args.table_destroy.table_id 10996 + out->args.table_destroy.table_id_n++; 10997 if ((uint8_t *)table_id > (uint8_t *)out + size) 10998 return -1; 10999 ctx->objdata = 0; 11000 ctx->object = table_id; 11001 ctx->objmask = NULL; 11002 return len; 11003 } 11004 11005 /** Parse tokens for queue create commands. */ 11006 static int 11007 parse_qo(struct context *ctx, const struct token *token, 11008 const char *str, unsigned int len, 11009 void *buf, unsigned int size) 11010 { 11011 struct buffer *out = buf; 11012 11013 /* Token name must match. */ 11014 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11015 return -1; 11016 /* Nothing else to do if there is no buffer. */ 11017 if (!out) 11018 return len; 11019 if (!out->command) { 11020 if (ctx->curr != QUEUE) 11021 return -1; 11022 if (sizeof(*out) > size) 11023 return -1; 11024 out->command = ctx->curr; 11025 ctx->objdata = 0; 11026 ctx->object = out; 11027 ctx->objmask = NULL; 11028 out->args.vc.data = (uint8_t *)out + size; 11029 return len; 11030 } 11031 switch (ctx->curr) { 11032 case QUEUE_CREATE: 11033 case QUEUE_UPDATE: 11034 out->command = ctx->curr; 11035 ctx->objdata = 0; 11036 ctx->object = out; 11037 ctx->objmask = NULL; 11038 out->args.vc.rule_id = UINT32_MAX; 11039 return len; 11040 case QUEUE_TEMPLATE_TABLE: 11041 case QUEUE_PATTERN_TEMPLATE: 11042 case QUEUE_ACTIONS_TEMPLATE: 11043 case QUEUE_CREATE_POSTPONE: 11044 case QUEUE_RULE_ID: 11045 case QUEUE_UPDATE_ID: 11046 return len; 11047 case ITEM_PATTERN: 11048 out->args.vc.pattern = 11049 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11050 sizeof(double)); 11051 ctx->object = out->args.vc.pattern; 11052 ctx->objmask = NULL; 11053 return len; 11054 case ACTIONS: 11055 out->args.vc.actions = 11056 (void *)RTE_ALIGN_CEIL((uintptr_t) 11057 (out->args.vc.pattern + 11058 out->args.vc.pattern_n), 11059 sizeof(double)); 11060 ctx->object = out->args.vc.actions; 11061 ctx->objmask = NULL; 11062 return len; 11063 default: 11064 return -1; 11065 } 11066 } 11067 11068 /** Parse tokens for queue destroy command. */ 11069 static int 11070 parse_qo_destroy(struct context *ctx, const struct token *token, 11071 const char *str, unsigned int len, 11072 void *buf, unsigned int size) 11073 { 11074 struct buffer *out = buf; 11075 uint64_t *flow_id; 11076 11077 /* Token name must match. */ 11078 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11079 return -1; 11080 /* Nothing else to do if there is no buffer. */ 11081 if (!out) 11082 return len; 11083 if (!out->command || out->command == QUEUE) { 11084 if (ctx->curr != QUEUE_DESTROY && 11085 ctx->curr != QUEUE_FLOW_UPDATE_RESIZED) 11086 return -1; 11087 if (sizeof(*out) > size) 11088 return -1; 11089 out->command = ctx->curr; 11090 ctx->objdata = 0; 11091 ctx->object = out; 11092 ctx->objmask = NULL; 11093 out->args.destroy.rule = 11094 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11095 sizeof(double)); 11096 return len; 11097 } 11098 switch (ctx->curr) { 11099 case QUEUE_DESTROY_ID: 11100 flow_id = out->args.destroy.rule 11101 + out->args.destroy.rule_n++; 11102 if ((uint8_t *)flow_id > (uint8_t *)out + size) 11103 return -1; 11104 ctx->objdata = 0; 11105 ctx->object = flow_id; 11106 ctx->objmask = NULL; 11107 return len; 11108 case QUEUE_DESTROY_POSTPONE: 11109 return len; 11110 default: 11111 return -1; 11112 } 11113 } 11114 11115 /** Parse tokens for push queue command. */ 11116 static int 11117 parse_push(struct context *ctx, const struct token *token, 11118 const char *str, unsigned int len, 11119 void *buf, unsigned int size) 11120 { 11121 struct buffer *out = buf; 11122 11123 /* Token name must match. */ 11124 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11125 return -1; 11126 /* Nothing else to do if there is no buffer. */ 11127 if (!out) 11128 return len; 11129 if (!out->command) { 11130 if (ctx->curr != PUSH) 11131 return -1; 11132 if (sizeof(*out) > size) 11133 return -1; 11134 out->command = ctx->curr; 11135 ctx->objdata = 0; 11136 ctx->object = out; 11137 ctx->objmask = NULL; 11138 out->args.vc.data = (uint8_t *)out + size; 11139 } 11140 return len; 11141 } 11142 11143 /** Parse tokens for pull command. */ 11144 static int 11145 parse_pull(struct context *ctx, const struct token *token, 11146 const char *str, unsigned int len, 11147 void *buf, unsigned int size) 11148 { 11149 struct buffer *out = buf; 11150 11151 /* Token name must match. */ 11152 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11153 return -1; 11154 /* Nothing else to do if there is no buffer. */ 11155 if (!out) 11156 return len; 11157 if (!out->command) { 11158 if (ctx->curr != PULL) 11159 return -1; 11160 if (sizeof(*out) > size) 11161 return -1; 11162 out->command = ctx->curr; 11163 ctx->objdata = 0; 11164 ctx->object = out; 11165 ctx->objmask = NULL; 11166 out->args.vc.data = (uint8_t *)out + size; 11167 } 11168 return len; 11169 } 11170 11171 /** Parse tokens for hash calculation commands. */ 11172 static int 11173 parse_hash(struct context *ctx, const struct token *token, 11174 const char *str, unsigned int len, 11175 void *buf, unsigned int size) 11176 { 11177 struct buffer *out = buf; 11178 11179 /* Token name must match. */ 11180 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11181 return -1; 11182 /* Nothing else to do if there is no buffer. */ 11183 if (!out) 11184 return len; 11185 if (!out->command) { 11186 if (ctx->curr != HASH) 11187 return -1; 11188 if (sizeof(*out) > size) 11189 return -1; 11190 out->command = ctx->curr; 11191 ctx->objdata = 0; 11192 ctx->object = out; 11193 ctx->objmask = NULL; 11194 out->args.vc.data = (uint8_t *)out + size; 11195 return len; 11196 } 11197 switch (ctx->curr) { 11198 case HASH_CALC_TABLE: 11199 case HASH_CALC_PATTERN_INDEX: 11200 return len; 11201 case ITEM_PATTERN: 11202 out->args.vc.pattern = 11203 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11204 sizeof(double)); 11205 ctx->object = out->args.vc.pattern; 11206 ctx->objmask = NULL; 11207 return len; 11208 case HASH_CALC_ENCAP: 11209 out->args.vc.encap_hash = 1; 11210 return len; 11211 case ENCAP_HASH_FIELD_SRC_PORT: 11212 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT; 11213 return len; 11214 case ENCAP_HASH_FIELD_GRE_FLOW_ID: 11215 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID; 11216 return len; 11217 default: 11218 return -1; 11219 } 11220 } 11221 11222 static int 11223 parse_group(struct context *ctx, const struct token *token, 11224 const char *str, unsigned int len, 11225 void *buf, unsigned int size) 11226 { 11227 struct buffer *out = buf; 11228 11229 /* Token name must match. */ 11230 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11231 return -1; 11232 /* Nothing else to do if there is no buffer. */ 11233 if (!out) 11234 return len; 11235 if (!out->command) { 11236 if (ctx->curr != FLOW_GROUP) 11237 return -1; 11238 if (sizeof(*out) > size) 11239 return -1; 11240 out->command = ctx->curr; 11241 ctx->objdata = 0; 11242 ctx->object = out; 11243 ctx->objmask = NULL; 11244 out->args.vc.data = (uint8_t *)out + size; 11245 return len; 11246 } 11247 switch (ctx->curr) { 11248 case GROUP_INGRESS: 11249 out->args.vc.attr.ingress = 1; 11250 return len; 11251 case GROUP_EGRESS: 11252 out->args.vc.attr.egress = 1; 11253 return len; 11254 case GROUP_TRANSFER: 11255 out->args.vc.attr.transfer = 1; 11256 return len; 11257 case GROUP_SET_MISS_ACTIONS: 11258 out->command = ctx->curr; 11259 ctx->objdata = 0; 11260 ctx->object = out; 11261 ctx->objmask = NULL; 11262 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11263 sizeof(double)); 11264 return len; 11265 default: 11266 return -1; 11267 } 11268 } 11269 11270 static int 11271 parse_flex(struct context *ctx, const struct token *token, 11272 const char *str, unsigned int len, 11273 void *buf, unsigned int size) 11274 { 11275 struct buffer *out = buf; 11276 11277 /* Token name must match. */ 11278 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11279 return -1; 11280 /* Nothing else to do if there is no buffer. */ 11281 if (!out) 11282 return len; 11283 if (out->command == ZERO) { 11284 if (ctx->curr != FLEX) 11285 return -1; 11286 if (sizeof(*out) > size) 11287 return -1; 11288 out->command = ctx->curr; 11289 ctx->objdata = 0; 11290 ctx->object = out; 11291 ctx->objmask = NULL; 11292 } else { 11293 switch (ctx->curr) { 11294 default: 11295 break; 11296 case FLEX_ITEM_INIT: 11297 case FLEX_ITEM_CREATE: 11298 case FLEX_ITEM_DESTROY: 11299 out->command = ctx->curr; 11300 break; 11301 } 11302 } 11303 11304 return len; 11305 } 11306 11307 static int 11308 parse_tunnel(struct context *ctx, const struct token *token, 11309 const char *str, unsigned int len, 11310 void *buf, unsigned int size) 11311 { 11312 struct buffer *out = buf; 11313 11314 /* Token name must match. */ 11315 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11316 return -1; 11317 /* Nothing else to do if there is no buffer. */ 11318 if (!out) 11319 return len; 11320 if (!out->command) { 11321 if (ctx->curr != TUNNEL) 11322 return -1; 11323 if (sizeof(*out) > size) 11324 return -1; 11325 out->command = ctx->curr; 11326 ctx->objdata = 0; 11327 ctx->object = out; 11328 ctx->objmask = NULL; 11329 } else { 11330 switch (ctx->curr) { 11331 default: 11332 break; 11333 case TUNNEL_CREATE: 11334 case TUNNEL_DESTROY: 11335 case TUNNEL_LIST: 11336 out->command = ctx->curr; 11337 break; 11338 case TUNNEL_CREATE_TYPE: 11339 case TUNNEL_DESTROY_ID: 11340 ctx->object = &out->args.vc.tunnel_ops; 11341 break; 11342 } 11343 } 11344 11345 return len; 11346 } 11347 11348 /** 11349 * Parse signed/unsigned integers 8 to 64-bit long. 11350 * 11351 * Last argument (ctx->args) is retrieved to determine integer type and 11352 * storage location. 11353 */ 11354 static int 11355 parse_int(struct context *ctx, const struct token *token, 11356 const char *str, unsigned int len, 11357 void *buf, unsigned int size) 11358 { 11359 const struct arg *arg = pop_args(ctx); 11360 uintmax_t u; 11361 char *end; 11362 11363 (void)token; 11364 /* Argument is expected. */ 11365 if (!arg) 11366 return -1; 11367 errno = 0; 11368 u = arg->sign ? 11369 (uintmax_t)strtoimax(str, &end, 0) : 11370 strtoumax(str, &end, 0); 11371 if (errno || (size_t)(end - str) != len) 11372 goto error; 11373 if (arg->bounded && 11374 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 11375 (intmax_t)u > (intmax_t)arg->max)) || 11376 (!arg->sign && (u < arg->min || u > arg->max)))) 11377 goto error; 11378 if (!ctx->object) 11379 return len; 11380 if (arg->mask) { 11381 if (!arg_entry_bf_fill(ctx->object, u, arg) || 11382 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 11383 goto error; 11384 return len; 11385 } 11386 buf = (uint8_t *)ctx->object + arg->offset; 11387 size = arg->size; 11388 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 11389 return -1; 11390 objmask: 11391 switch (size) { 11392 case sizeof(uint8_t): 11393 *(uint8_t *)buf = u; 11394 break; 11395 case sizeof(uint16_t): 11396 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 11397 break; 11398 case sizeof(uint8_t [3]): 11399 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 11400 if (!arg->hton) { 11401 ((uint8_t *)buf)[0] = u; 11402 ((uint8_t *)buf)[1] = u >> 8; 11403 ((uint8_t *)buf)[2] = u >> 16; 11404 break; 11405 } 11406 #endif 11407 ((uint8_t *)buf)[0] = u >> 16; 11408 ((uint8_t *)buf)[1] = u >> 8; 11409 ((uint8_t *)buf)[2] = u; 11410 break; 11411 case sizeof(uint32_t): 11412 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 11413 break; 11414 case sizeof(uint64_t): 11415 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 11416 break; 11417 default: 11418 goto error; 11419 } 11420 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 11421 u = -1; 11422 buf = (uint8_t *)ctx->objmask + arg->offset; 11423 goto objmask; 11424 } 11425 return len; 11426 error: 11427 push_args(ctx, arg); 11428 return -1; 11429 } 11430 11431 /** 11432 * Parse a string. 11433 * 11434 * Three arguments (ctx->args) are retrieved from the stack to store data, 11435 * its actual length and address (in that order). 11436 */ 11437 static int 11438 parse_string(struct context *ctx, const struct token *token, 11439 const char *str, unsigned int len, 11440 void *buf, unsigned int size) 11441 { 11442 const struct arg *arg_data = pop_args(ctx); 11443 const struct arg *arg_len = pop_args(ctx); 11444 const struct arg *arg_addr = pop_args(ctx); 11445 char tmp[16]; /* Ought to be enough. */ 11446 int ret; 11447 11448 /* Arguments are expected. */ 11449 if (!arg_data) 11450 return -1; 11451 if (!arg_len) { 11452 push_args(ctx, arg_data); 11453 return -1; 11454 } 11455 if (!arg_addr) { 11456 push_args(ctx, arg_len); 11457 push_args(ctx, arg_data); 11458 return -1; 11459 } 11460 size = arg_data->size; 11461 /* Bit-mask fill is not supported. */ 11462 if (arg_data->mask || size < len) 11463 goto error; 11464 if (!ctx->object) 11465 return len; 11466 /* Let parse_int() fill length information first. */ 11467 ret = snprintf(tmp, sizeof(tmp), "%u", len); 11468 if (ret < 0) 11469 goto error; 11470 push_args(ctx, arg_len); 11471 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11472 if (ret < 0) { 11473 pop_args(ctx); 11474 goto error; 11475 } 11476 buf = (uint8_t *)ctx->object + arg_data->offset; 11477 /* Output buffer is not necessarily NUL-terminated. */ 11478 memcpy(buf, str, len); 11479 memset((uint8_t *)buf + len, 0x00, size - len); 11480 if (ctx->objmask) 11481 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11482 /* Save address if requested. */ 11483 if (arg_addr->size) { 11484 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11485 (void *[]){ 11486 (uint8_t *)ctx->object + arg_data->offset 11487 }, 11488 arg_addr->size); 11489 if (ctx->objmask) 11490 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11491 (void *[]){ 11492 (uint8_t *)ctx->objmask + arg_data->offset 11493 }, 11494 arg_addr->size); 11495 } 11496 return len; 11497 error: 11498 push_args(ctx, arg_addr); 11499 push_args(ctx, arg_len); 11500 push_args(ctx, arg_data); 11501 return -1; 11502 } 11503 11504 static int 11505 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 11506 { 11507 const uint8_t *head = dst; 11508 uint32_t left; 11509 11510 if (*size == 0) 11511 return -1; 11512 11513 left = *size; 11514 11515 /* Convert chars to bytes */ 11516 while (left) { 11517 char tmp[3], *end = tmp; 11518 uint32_t read_lim = left & 1 ? 1 : 2; 11519 11520 snprintf(tmp, read_lim + 1, "%s", src); 11521 *dst = strtoul(tmp, &end, 16); 11522 if (*end) { 11523 *dst = 0; 11524 *size = (uint32_t)(dst - head); 11525 return -1; 11526 } 11527 left -= read_lim; 11528 src += read_lim; 11529 dst++; 11530 } 11531 *dst = 0; 11532 *size = (uint32_t)(dst - head); 11533 return 0; 11534 } 11535 11536 static int 11537 parse_hex(struct context *ctx, const struct token *token, 11538 const char *str, unsigned int len, 11539 void *buf, unsigned int size) 11540 { 11541 const struct arg *arg_data = pop_args(ctx); 11542 const struct arg *arg_len = pop_args(ctx); 11543 const struct arg *arg_addr = pop_args(ctx); 11544 char tmp[16]; /* Ought to be enough. */ 11545 int ret; 11546 unsigned int hexlen = len; 11547 unsigned int length = 256; 11548 uint8_t hex_tmp[length]; 11549 11550 /* Arguments are expected. */ 11551 if (!arg_data) 11552 return -1; 11553 if (!arg_len) { 11554 push_args(ctx, arg_data); 11555 return -1; 11556 } 11557 if (!arg_addr) { 11558 push_args(ctx, arg_len); 11559 push_args(ctx, arg_data); 11560 return -1; 11561 } 11562 size = arg_data->size; 11563 /* Bit-mask fill is not supported. */ 11564 if (arg_data->mask) 11565 goto error; 11566 if (!ctx->object) 11567 return len; 11568 11569 /* translate bytes string to array. */ 11570 if (str[0] == '0' && ((str[1] == 'x') || 11571 (str[1] == 'X'))) { 11572 str += 2; 11573 hexlen -= 2; 11574 } 11575 if (hexlen > length) 11576 goto error; 11577 ret = parse_hex_string(str, hex_tmp, &hexlen); 11578 if (ret < 0) 11579 goto error; 11580 /* Check the converted binary fits into data buffer. */ 11581 if (hexlen > size) 11582 goto error; 11583 /* Let parse_int() fill length information first. */ 11584 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 11585 if (ret < 0) 11586 goto error; 11587 /* Save length if requested. */ 11588 if (arg_len->size) { 11589 push_args(ctx, arg_len); 11590 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11591 if (ret < 0) { 11592 pop_args(ctx); 11593 goto error; 11594 } 11595 } 11596 buf = (uint8_t *)ctx->object + arg_data->offset; 11597 /* Output buffer is not necessarily NUL-terminated. */ 11598 memcpy(buf, hex_tmp, hexlen); 11599 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 11600 if (ctx->objmask) 11601 memset((uint8_t *)ctx->objmask + arg_data->offset, 11602 0xff, hexlen); 11603 /* Save address if requested. */ 11604 if (arg_addr->size) { 11605 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11606 (void *[]){ 11607 (uint8_t *)ctx->object + arg_data->offset 11608 }, 11609 arg_addr->size); 11610 if (ctx->objmask) 11611 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11612 (void *[]){ 11613 (uint8_t *)ctx->objmask + arg_data->offset 11614 }, 11615 arg_addr->size); 11616 } 11617 return len; 11618 error: 11619 push_args(ctx, arg_addr); 11620 push_args(ctx, arg_len); 11621 push_args(ctx, arg_data); 11622 return -1; 11623 11624 } 11625 11626 /** 11627 * Parse a zero-ended string. 11628 */ 11629 static int 11630 parse_string0(struct context *ctx, const struct token *token __rte_unused, 11631 const char *str, unsigned int len, 11632 void *buf, unsigned int size) 11633 { 11634 const struct arg *arg_data = pop_args(ctx); 11635 11636 /* Arguments are expected. */ 11637 if (!arg_data) 11638 return -1; 11639 size = arg_data->size; 11640 /* Bit-mask fill is not supported. */ 11641 if (arg_data->mask || size < len + 1) 11642 goto error; 11643 if (!ctx->object) 11644 return len; 11645 buf = (uint8_t *)ctx->object + arg_data->offset; 11646 strncpy(buf, str, len); 11647 if (ctx->objmask) 11648 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11649 return len; 11650 error: 11651 push_args(ctx, arg_data); 11652 return -1; 11653 } 11654 11655 /** 11656 * Parse a MAC address. 11657 * 11658 * Last argument (ctx->args) is retrieved to determine storage size and 11659 * location. 11660 */ 11661 static int 11662 parse_mac_addr(struct context *ctx, const struct token *token, 11663 const char *str, unsigned int len, 11664 void *buf, unsigned int size) 11665 { 11666 const struct arg *arg = pop_args(ctx); 11667 struct rte_ether_addr tmp; 11668 int ret; 11669 11670 (void)token; 11671 /* Argument is expected. */ 11672 if (!arg) 11673 return -1; 11674 size = arg->size; 11675 /* Bit-mask fill is not supported. */ 11676 if (arg->mask || size != sizeof(tmp)) 11677 goto error; 11678 /* Only network endian is supported. */ 11679 if (!arg->hton) 11680 goto error; 11681 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 11682 if (ret < 0 || (unsigned int)ret != len) 11683 goto error; 11684 if (!ctx->object) 11685 return len; 11686 buf = (uint8_t *)ctx->object + arg->offset; 11687 memcpy(buf, &tmp, size); 11688 if (ctx->objmask) 11689 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11690 return len; 11691 error: 11692 push_args(ctx, arg); 11693 return -1; 11694 } 11695 11696 /** 11697 * Parse an IPv4 address. 11698 * 11699 * Last argument (ctx->args) is retrieved to determine storage size and 11700 * location. 11701 */ 11702 static int 11703 parse_ipv4_addr(struct context *ctx, const struct token *token, 11704 const char *str, unsigned int len, 11705 void *buf, unsigned int size) 11706 { 11707 const struct arg *arg = pop_args(ctx); 11708 char str2[len + 1]; 11709 struct in_addr tmp; 11710 int ret; 11711 11712 /* Argument is expected. */ 11713 if (!arg) 11714 return -1; 11715 size = arg->size; 11716 /* Bit-mask fill is not supported. */ 11717 if (arg->mask || size != sizeof(tmp)) 11718 goto error; 11719 /* Only network endian is supported. */ 11720 if (!arg->hton) 11721 goto error; 11722 memcpy(str2, str, len); 11723 str2[len] = '\0'; 11724 ret = inet_pton(AF_INET, str2, &tmp); 11725 if (ret != 1) { 11726 /* Attempt integer parsing. */ 11727 push_args(ctx, arg); 11728 return parse_int(ctx, token, str, len, buf, size); 11729 } 11730 if (!ctx->object) 11731 return len; 11732 buf = (uint8_t *)ctx->object + arg->offset; 11733 memcpy(buf, &tmp, size); 11734 if (ctx->objmask) 11735 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11736 return len; 11737 error: 11738 push_args(ctx, arg); 11739 return -1; 11740 } 11741 11742 /** 11743 * Parse an IPv6 address. 11744 * 11745 * Last argument (ctx->args) is retrieved to determine storage size and 11746 * location. 11747 */ 11748 static int 11749 parse_ipv6_addr(struct context *ctx, const struct token *token, 11750 const char *str, unsigned int len, 11751 void *buf, unsigned int size) 11752 { 11753 const struct arg *arg = pop_args(ctx); 11754 char str2[len + 1]; 11755 struct in6_addr tmp; 11756 int ret; 11757 11758 (void)token; 11759 /* Argument is expected. */ 11760 if (!arg) 11761 return -1; 11762 size = arg->size; 11763 /* Bit-mask fill is not supported. */ 11764 if (arg->mask || size != sizeof(tmp)) 11765 goto error; 11766 /* Only network endian is supported. */ 11767 if (!arg->hton) 11768 goto error; 11769 memcpy(str2, str, len); 11770 str2[len] = '\0'; 11771 ret = inet_pton(AF_INET6, str2, &tmp); 11772 if (ret != 1) 11773 goto error; 11774 if (!ctx->object) 11775 return len; 11776 buf = (uint8_t *)ctx->object + arg->offset; 11777 memcpy(buf, &tmp, size); 11778 if (ctx->objmask) 11779 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11780 return len; 11781 error: 11782 push_args(ctx, arg); 11783 return -1; 11784 } 11785 11786 /** Boolean values (even indices stand for false). */ 11787 static const char *const boolean_name[] = { 11788 "0", "1", 11789 "false", "true", 11790 "no", "yes", 11791 "N", "Y", 11792 "off", "on", 11793 NULL, 11794 }; 11795 11796 /** 11797 * Parse a boolean value. 11798 * 11799 * Last argument (ctx->args) is retrieved to determine storage size and 11800 * location. 11801 */ 11802 static int 11803 parse_boolean(struct context *ctx, const struct token *token, 11804 const char *str, unsigned int len, 11805 void *buf, unsigned int size) 11806 { 11807 const struct arg *arg = pop_args(ctx); 11808 unsigned int i; 11809 int ret; 11810 11811 /* Argument is expected. */ 11812 if (!arg) 11813 return -1; 11814 for (i = 0; boolean_name[i]; ++i) 11815 if (!strcmp_partial(boolean_name[i], str, len)) 11816 break; 11817 /* Process token as integer. */ 11818 if (boolean_name[i]) 11819 str = i & 1 ? "1" : "0"; 11820 push_args(ctx, arg); 11821 ret = parse_int(ctx, token, str, strlen(str), buf, size); 11822 return ret > 0 ? (int)len : ret; 11823 } 11824 11825 /** Parse port and update context. */ 11826 static int 11827 parse_port(struct context *ctx, const struct token *token, 11828 const char *str, unsigned int len, 11829 void *buf, unsigned int size) 11830 { 11831 struct buffer *out = &(struct buffer){ .port = 0 }; 11832 int ret; 11833 11834 if (buf) 11835 out = buf; 11836 else { 11837 ctx->objdata = 0; 11838 ctx->object = out; 11839 ctx->objmask = NULL; 11840 size = sizeof(*out); 11841 } 11842 ret = parse_int(ctx, token, str, len, out, size); 11843 if (ret >= 0) 11844 ctx->port = out->port; 11845 if (!buf) 11846 ctx->object = NULL; 11847 return ret; 11848 } 11849 11850 /** Parse tokens for shared indirect actions. */ 11851 static int 11852 parse_ia_port(struct context *ctx, const struct token *token, 11853 const char *str, unsigned int len, 11854 void *buf, unsigned int size) 11855 { 11856 struct rte_flow_action *action = ctx->object; 11857 uint32_t id; 11858 int ret; 11859 11860 (void)buf; 11861 (void)size; 11862 ctx->objdata = 0; 11863 ctx->object = &id; 11864 ctx->objmask = NULL; 11865 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11866 ctx->object = action; 11867 if (ret != (int)len) 11868 return ret; 11869 /* set indirect action */ 11870 if (action) 11871 action->conf = (void *)(uintptr_t)id; 11872 return ret; 11873 } 11874 11875 static int 11876 parse_ia_id2ptr(struct context *ctx, const struct token *token, 11877 const char *str, unsigned int len, 11878 void *buf, unsigned int size) 11879 { 11880 struct rte_flow_action *action = ctx->object; 11881 uint32_t id; 11882 int ret; 11883 11884 (void)buf; 11885 (void)size; 11886 ctx->objdata = 0; 11887 ctx->object = &id; 11888 ctx->objmask = NULL; 11889 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11890 ctx->object = action; 11891 if (ret != (int)len) 11892 return ret; 11893 /* set indirect action */ 11894 if (action) { 11895 portid_t port_id = ctx->port; 11896 if (ctx->prev == INDIRECT_ACTION_PORT) 11897 port_id = (portid_t)(uintptr_t)action->conf; 11898 action->conf = port_action_handle_get_by_id(port_id, id); 11899 ret = (action->conf) ? ret : -1; 11900 } 11901 return ret; 11902 } 11903 11904 static int 11905 parse_indlst_id2ptr(struct context *ctx, const struct token *token, 11906 const char *str, unsigned int len, 11907 __rte_unused void *buf, __rte_unused unsigned int size) 11908 { 11909 struct rte_flow_action *action = ctx->object; 11910 struct rte_flow_action_indirect_list *action_conf; 11911 const struct indlst_conf *indlst_conf; 11912 uint32_t id; 11913 int ret; 11914 11915 if (!action) 11916 return -1; 11917 ctx->objdata = 0; 11918 ctx->object = &id; 11919 ctx->objmask = NULL; 11920 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11921 if (ret != (int)len) 11922 return ret; 11923 ctx->object = action; 11924 action_conf = (void *)(uintptr_t)action->conf; 11925 action_conf->conf = NULL; 11926 switch (ctx->curr) { 11927 case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: 11928 action_conf->handle = (typeof(action_conf->handle)) 11929 port_action_handle_get_by_id(ctx->port, id); 11930 if (!action_conf->handle) { 11931 printf("no indirect list handle for id %u\n", id); 11932 return -1; 11933 } 11934 break; 11935 case INDIRECT_LIST_ACTION_ID2PTR_CONF: 11936 indlst_conf = indirect_action_list_conf_get(id); 11937 if (!indlst_conf) 11938 return -1; 11939 action_conf->conf = (const void **)indlst_conf->conf; 11940 break; 11941 default: 11942 break; 11943 } 11944 return ret; 11945 } 11946 11947 static int 11948 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 11949 const char *str, unsigned int len, 11950 void *buf, unsigned int size) 11951 { 11952 struct rte_flow_action *action = ctx->object; 11953 struct rte_flow_action_meter_mark *meter; 11954 struct rte_flow_meter_profile *profile = NULL; 11955 uint32_t id = 0; 11956 int ret; 11957 11958 (void)buf; 11959 (void)size; 11960 ctx->objdata = 0; 11961 ctx->object = &id; 11962 ctx->objmask = NULL; 11963 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11964 ctx->object = action; 11965 if (ret != (int)len) 11966 return ret; 11967 /* set meter profile */ 11968 if (action) { 11969 meter = (struct rte_flow_action_meter_mark *) 11970 (uintptr_t)(action->conf); 11971 profile = port_meter_profile_get_by_id(ctx->port, id); 11972 meter->profile = profile; 11973 ret = (profile) ? ret : -1; 11974 } 11975 return ret; 11976 } 11977 11978 static int 11979 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 11980 const char *str, unsigned int len, 11981 void *buf, unsigned int size) 11982 { 11983 struct rte_flow_action *action = ctx->object; 11984 struct rte_flow_action_meter_mark *meter; 11985 struct rte_flow_meter_policy *policy = NULL; 11986 uint32_t id = 0; 11987 int ret; 11988 11989 (void)buf; 11990 (void)size; 11991 ctx->objdata = 0; 11992 ctx->object = &id; 11993 ctx->objmask = NULL; 11994 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11995 ctx->object = action; 11996 if (ret != (int)len) 11997 return ret; 11998 /* set meter policy */ 11999 if (action) { 12000 meter = (struct rte_flow_action_meter_mark *) 12001 (uintptr_t)(action->conf); 12002 policy = port_meter_policy_get_by_id(ctx->port, id); 12003 meter->policy = policy; 12004 ret = (policy) ? ret : -1; 12005 } 12006 return ret; 12007 } 12008 12009 /** Parse set command, initialize output buffer for subsequent tokens. */ 12010 static int 12011 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 12012 const char *str, unsigned int len, 12013 void *buf, unsigned int size) 12014 { 12015 struct buffer *out = buf; 12016 12017 /* Token name must match. */ 12018 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12019 return -1; 12020 /* Nothing else to do if there is no buffer. */ 12021 if (!out) 12022 return len; 12023 /* Make sure buffer is large enough. */ 12024 if (size < sizeof(*out)) 12025 return -1; 12026 ctx->objdata = 0; 12027 ctx->objmask = NULL; 12028 ctx->object = out; 12029 if (!out->command) 12030 return -1; 12031 out->command = ctx->curr; 12032 /* For encap/decap we need is pattern */ 12033 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12034 sizeof(double)); 12035 return len; 12036 } 12037 12038 /** Parse set command, initialize output buffer for subsequent tokens. */ 12039 static int 12040 parse_set_sample_action(struct context *ctx, const struct token *token, 12041 const char *str, unsigned int len, 12042 void *buf, unsigned int size) 12043 { 12044 struct buffer *out = buf; 12045 12046 /* Token name must match. */ 12047 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12048 return -1; 12049 /* Nothing else to do if there is no buffer. */ 12050 if (!out) 12051 return len; 12052 /* Make sure buffer is large enough. */ 12053 if (size < sizeof(*out)) 12054 return -1; 12055 ctx->objdata = 0; 12056 ctx->objmask = NULL; 12057 ctx->object = out; 12058 if (!out->command) 12059 return -1; 12060 out->command = ctx->curr; 12061 /* For sampler we need is actions */ 12062 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12063 sizeof(double)); 12064 return len; 12065 } 12066 12067 /** Parse set command, initialize output buffer for subsequent tokens. */ 12068 static int 12069 parse_set_ipv6_ext_action(struct context *ctx, const struct token *token, 12070 const char *str, unsigned int len, 12071 void *buf, unsigned int size) 12072 { 12073 struct buffer *out = buf; 12074 12075 /* Token name must match. */ 12076 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12077 return -1; 12078 /* Nothing else to do if there is no buffer. */ 12079 if (!out) 12080 return len; 12081 /* Make sure buffer is large enough. */ 12082 if (size < sizeof(*out)) 12083 return -1; 12084 ctx->objdata = 0; 12085 ctx->objmask = NULL; 12086 ctx->object = out; 12087 if (!out->command) 12088 return -1; 12089 out->command = ctx->curr; 12090 /* For ipv6_ext_push/remove we need is pattern */ 12091 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12092 sizeof(double)); 12093 return len; 12094 } 12095 12096 /** 12097 * Parse set raw_encap/raw_decap command, 12098 * initialize output buffer for subsequent tokens. 12099 */ 12100 static int 12101 parse_set_init(struct context *ctx, const struct token *token, 12102 const char *str, unsigned int len, 12103 void *buf, unsigned int size) 12104 { 12105 struct buffer *out = buf; 12106 12107 /* Token name must match. */ 12108 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12109 return -1; 12110 /* Nothing else to do if there is no buffer. */ 12111 if (!out) 12112 return len; 12113 /* Make sure buffer is large enough. */ 12114 if (size < sizeof(*out)) 12115 return -1; 12116 /* Initialize buffer. */ 12117 memset(out, 0x00, sizeof(*out)); 12118 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 12119 ctx->objdata = 0; 12120 ctx->object = out; 12121 ctx->objmask = NULL; 12122 if (!out->command) { 12123 if (ctx->curr != SET) 12124 return -1; 12125 if (sizeof(*out) > size) 12126 return -1; 12127 out->command = ctx->curr; 12128 out->args.vc.data = (uint8_t *)out + size; 12129 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12130 sizeof(double)); 12131 } 12132 return len; 12133 } 12134 12135 /* 12136 * Replace testpmd handles in a flex flow item with real values. 12137 */ 12138 static int 12139 parse_flex_handle(struct context *ctx, const struct token *token, 12140 const char *str, unsigned int len, 12141 void *buf, unsigned int size) 12142 { 12143 struct rte_flow_item_flex *spec, *mask; 12144 const struct rte_flow_item_flex *src_spec, *src_mask; 12145 const struct arg *arg = pop_args(ctx); 12146 uint32_t offset; 12147 uint16_t handle; 12148 int ret; 12149 12150 if (!arg) { 12151 printf("Bad environment\n"); 12152 return -1; 12153 } 12154 offset = arg->offset; 12155 push_args(ctx, arg); 12156 ret = parse_int(ctx, token, str, len, buf, size); 12157 if (ret <= 0 || !ctx->object) 12158 return ret; 12159 if (ctx->port >= RTE_MAX_ETHPORTS) { 12160 printf("Bad port\n"); 12161 return -1; 12162 } 12163 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 12164 const struct flex_item *fp; 12165 spec = ctx->object; 12166 handle = (uint16_t)(uintptr_t)spec->handle; 12167 if (handle >= FLEX_MAX_PARSERS_NUM) { 12168 printf("Bad flex item handle\n"); 12169 return -1; 12170 } 12171 fp = flex_items[ctx->port][handle]; 12172 if (!fp) { 12173 printf("Bad flex item handle\n"); 12174 return -1; 12175 } 12176 spec->handle = fp->flex_handle; 12177 mask = spec + 2; /* spec, last, mask */ 12178 mask->handle = fp->flex_handle; 12179 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 12180 handle = (uint16_t)(uintptr_t) 12181 ((struct rte_flow_item_flex *)ctx->object)->pattern; 12182 if (handle >= FLEX_MAX_PATTERNS_NUM) { 12183 printf("Bad pattern handle\n"); 12184 return -1; 12185 } 12186 src_spec = &flex_patterns[handle].spec; 12187 src_mask = &flex_patterns[handle].mask; 12188 spec = ctx->object; 12189 mask = spec + 2; /* spec, last, mask */ 12190 /* fill flow rule spec and mask parameters */ 12191 spec->length = src_spec->length; 12192 spec->pattern = src_spec->pattern; 12193 mask->length = src_mask->length; 12194 mask->pattern = src_mask->pattern; 12195 } else { 12196 printf("Bad arguments - unknown flex item offset\n"); 12197 return -1; 12198 } 12199 return ret; 12200 } 12201 12202 /** Parse Meter color name */ 12203 static int 12204 parse_meter_color(struct context *ctx, const struct token *token, 12205 const char *str, unsigned int len, void *buf, 12206 unsigned int size) 12207 { 12208 struct rte_flow_item_meter_color *meter_color; 12209 unsigned int i; 12210 12211 (void)token; 12212 (void)buf; 12213 (void)size; 12214 for (i = 0; meter_colors[i]; ++i) 12215 if (!strcmp_partial(meter_colors[i], str, len)) 12216 break; 12217 if (!meter_colors[i]) 12218 return -1; 12219 if (!ctx->object) 12220 return len; 12221 meter_color = ctx->object; 12222 meter_color->color = (enum rte_color)i; 12223 return len; 12224 } 12225 12226 /** Parse Insertion Table Type name */ 12227 static int 12228 parse_insertion_table_type(struct context *ctx, const struct token *token, 12229 const char *str, unsigned int len, void *buf, 12230 unsigned int size) 12231 { 12232 const struct arg *arg = pop_args(ctx); 12233 unsigned int i; 12234 char tmp[2]; 12235 int ret; 12236 12237 (void)size; 12238 /* Argument is expected. */ 12239 if (!arg) 12240 return -1; 12241 for (i = 0; table_insertion_types[i]; ++i) 12242 if (!strcmp_partial(table_insertion_types[i], str, len)) 12243 break; 12244 if (!table_insertion_types[i]) 12245 return -1; 12246 push_args(ctx, arg); 12247 snprintf(tmp, sizeof(tmp), "%u", i); 12248 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12249 return ret > 0 ? (int)len : ret; 12250 } 12251 12252 /** Parse Hash Calculation Table Type name */ 12253 static int 12254 parse_hash_table_type(struct context *ctx, const struct token *token, 12255 const char *str, unsigned int len, void *buf, 12256 unsigned int size) 12257 { 12258 const struct arg *arg = pop_args(ctx); 12259 unsigned int i; 12260 char tmp[2]; 12261 int ret; 12262 12263 (void)size; 12264 /* Argument is expected. */ 12265 if (!arg) 12266 return -1; 12267 for (i = 0; table_hash_funcs[i]; ++i) 12268 if (!strcmp_partial(table_hash_funcs[i], str, len)) 12269 break; 12270 if (!table_hash_funcs[i]) 12271 return -1; 12272 push_args(ctx, arg); 12273 snprintf(tmp, sizeof(tmp), "%u", i); 12274 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12275 return ret > 0 ? (int)len : ret; 12276 } 12277 12278 static int 12279 parse_name_to_index(struct context *ctx, const struct token *token, 12280 const char *str, unsigned int len, void *buf, 12281 unsigned int size, 12282 const char *const names[], size_t names_size, uint32_t *dst) 12283 { 12284 int ret; 12285 uint32_t i; 12286 12287 RTE_SET_USED(token); 12288 RTE_SET_USED(buf); 12289 RTE_SET_USED(size); 12290 if (!ctx->object) 12291 return len; 12292 for (i = 0; i < names_size; i++) { 12293 if (!names[i]) 12294 continue; 12295 ret = strcmp_partial(names[i], str, 12296 RTE_MIN(len, strlen(names[i]))); 12297 if (!ret) { 12298 *dst = i; 12299 return len; 12300 } 12301 } 12302 return -1; 12303 } 12304 12305 static const char *const quota_mode_names[] = { 12306 NULL, 12307 [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", 12308 [RTE_FLOW_QUOTA_MODE_L2] = "l2", 12309 [RTE_FLOW_QUOTA_MODE_L3] = "l3" 12310 }; 12311 12312 static const char *const quota_state_names[] = { 12313 [RTE_FLOW_QUOTA_STATE_PASS] = "pass", 12314 [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" 12315 }; 12316 12317 static const char *const quota_update_names[] = { 12318 [RTE_FLOW_UPDATE_QUOTA_SET] = "set", 12319 [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" 12320 }; 12321 12322 static const char *const query_update_mode_names[] = { 12323 [RTE_FLOW_QU_QUERY_FIRST] = "query_first", 12324 [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" 12325 }; 12326 12327 static int 12328 parse_quota_state_name(struct context *ctx, const struct token *token, 12329 const char *str, unsigned int len, void *buf, 12330 unsigned int size) 12331 { 12332 struct rte_flow_item_quota *quota = ctx->object; 12333 12334 return parse_name_to_index(ctx, token, str, len, buf, size, 12335 quota_state_names, 12336 RTE_DIM(quota_state_names), 12337 (uint32_t *)"a->state); 12338 } 12339 12340 static int 12341 parse_quota_mode_name(struct context *ctx, const struct token *token, 12342 const char *str, unsigned int len, void *buf, 12343 unsigned int size) 12344 { 12345 struct rte_flow_action_quota *quota = ctx->object; 12346 12347 return parse_name_to_index(ctx, token, str, len, buf, size, 12348 quota_mode_names, 12349 RTE_DIM(quota_mode_names), 12350 (uint32_t *)"a->mode); 12351 } 12352 12353 static int 12354 parse_quota_update_name(struct context *ctx, const struct token *token, 12355 const char *str, unsigned int len, void *buf, 12356 unsigned int size) 12357 { 12358 struct rte_flow_update_quota *update = ctx->object; 12359 12360 return parse_name_to_index(ctx, token, str, len, buf, size, 12361 quota_update_names, 12362 RTE_DIM(quota_update_names), 12363 (uint32_t *)&update->op); 12364 } 12365 12366 static int 12367 parse_qu_mode_name(struct context *ctx, const struct token *token, 12368 const char *str, unsigned int len, void *buf, 12369 unsigned int size) 12370 { 12371 struct buffer *out = ctx->object; 12372 12373 return parse_name_to_index(ctx, token, str, len, buf, size, 12374 query_update_mode_names, 12375 RTE_DIM(query_update_mode_names), 12376 (uint32_t *)&out->args.ia.qu_mode); 12377 } 12378 12379 /** No completion. */ 12380 static int 12381 comp_none(struct context *ctx, const struct token *token, 12382 unsigned int ent, char *buf, unsigned int size) 12383 { 12384 (void)ctx; 12385 (void)token; 12386 (void)ent; 12387 (void)buf; 12388 (void)size; 12389 return 0; 12390 } 12391 12392 /** Complete boolean values. */ 12393 static int 12394 comp_boolean(struct context *ctx, const struct token *token, 12395 unsigned int ent, char *buf, unsigned int size) 12396 { 12397 unsigned int i; 12398 12399 (void)ctx; 12400 (void)token; 12401 for (i = 0; boolean_name[i]; ++i) 12402 if (buf && i == ent) 12403 return strlcpy(buf, boolean_name[i], size); 12404 if (buf) 12405 return -1; 12406 return i; 12407 } 12408 12409 /** Complete action names. */ 12410 static int 12411 comp_action(struct context *ctx, const struct token *token, 12412 unsigned int ent, char *buf, unsigned int size) 12413 { 12414 unsigned int i; 12415 12416 (void)ctx; 12417 (void)token; 12418 for (i = 0; next_action[i]; ++i) 12419 if (buf && i == ent) 12420 return strlcpy(buf, token_list[next_action[i]].name, 12421 size); 12422 if (buf) 12423 return -1; 12424 return i; 12425 } 12426 12427 /** Complete available ports. */ 12428 static int 12429 comp_port(struct context *ctx, const struct token *token, 12430 unsigned int ent, char *buf, unsigned int size) 12431 { 12432 unsigned int i = 0; 12433 portid_t p; 12434 12435 (void)ctx; 12436 (void)token; 12437 RTE_ETH_FOREACH_DEV(p) { 12438 if (buf && i == ent) 12439 return snprintf(buf, size, "%u", p); 12440 ++i; 12441 } 12442 if (buf) 12443 return -1; 12444 return i; 12445 } 12446 12447 /** Complete available rule IDs. */ 12448 static int 12449 comp_rule_id(struct context *ctx, const struct token *token, 12450 unsigned int ent, char *buf, unsigned int size) 12451 { 12452 unsigned int i = 0; 12453 struct rte_port *port; 12454 struct port_flow *pf; 12455 12456 (void)token; 12457 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12458 ctx->port == (portid_t)RTE_PORT_ALL) 12459 return -1; 12460 port = &ports[ctx->port]; 12461 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 12462 if (buf && i == ent) 12463 return snprintf(buf, size, "%"PRIu64, pf->id); 12464 ++i; 12465 } 12466 if (buf) 12467 return -1; 12468 return i; 12469 } 12470 12471 /** Complete operation for compare match item. */ 12472 static int 12473 comp_set_compare_op(struct context *ctx, const struct token *token, 12474 unsigned int ent, char *buf, unsigned int size) 12475 { 12476 RTE_SET_USED(ctx); 12477 RTE_SET_USED(token); 12478 if (!buf) 12479 return RTE_DIM(compare_ops); 12480 if (ent < RTE_DIM(compare_ops) - 1) 12481 return strlcpy(buf, compare_ops[ent], size); 12482 return -1; 12483 } 12484 12485 /** Complete field id for compare match item. */ 12486 static int 12487 comp_set_compare_field_id(struct context *ctx, const struct token *token, 12488 unsigned int ent, char *buf, unsigned int size) 12489 { 12490 const char *name; 12491 12492 RTE_SET_USED(token); 12493 if (!buf) 12494 return RTE_DIM(flow_field_ids); 12495 if (ent >= RTE_DIM(flow_field_ids) - 1) 12496 return -1; 12497 name = flow_field_ids[ent]; 12498 if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE || 12499 (strcmp(name, "pointer") && strcmp(name, "value"))) 12500 return strlcpy(buf, name, size); 12501 return -1; 12502 } 12503 12504 /** Complete type field for RSS action. */ 12505 static int 12506 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 12507 unsigned int ent, char *buf, unsigned int size) 12508 { 12509 unsigned int i; 12510 12511 (void)ctx; 12512 (void)token; 12513 for (i = 0; rss_type_table[i].str; ++i) 12514 ; 12515 if (!buf) 12516 return i + 1; 12517 if (ent < i) 12518 return strlcpy(buf, rss_type_table[ent].str, size); 12519 if (ent == i) 12520 return snprintf(buf, size, "end"); 12521 return -1; 12522 } 12523 12524 /** Complete queue field for RSS action. */ 12525 static int 12526 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 12527 unsigned int ent, char *buf, unsigned int size) 12528 { 12529 (void)ctx; 12530 (void)token; 12531 if (!buf) 12532 return nb_rxq + 1; 12533 if (ent < nb_rxq) 12534 return snprintf(buf, size, "%u", ent); 12535 if (ent == nb_rxq) 12536 return snprintf(buf, size, "end"); 12537 return -1; 12538 } 12539 12540 /** Complete index number for set raw_encap/raw_decap commands. */ 12541 static int 12542 comp_set_raw_index(struct context *ctx, const struct token *token, 12543 unsigned int ent, char *buf, unsigned int size) 12544 { 12545 uint16_t idx = 0; 12546 uint16_t nb = 0; 12547 12548 RTE_SET_USED(ctx); 12549 RTE_SET_USED(token); 12550 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 12551 if (buf && idx == ent) 12552 return snprintf(buf, size, "%u", idx); 12553 ++nb; 12554 } 12555 return nb; 12556 } 12557 12558 /** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ 12559 static int 12560 comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 12561 unsigned int ent, char *buf, unsigned int size) 12562 { 12563 uint16_t idx = 0; 12564 uint16_t nb = 0; 12565 12566 RTE_SET_USED(ctx); 12567 RTE_SET_USED(token); 12568 for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { 12569 if (buf && idx == ent) 12570 return snprintf(buf, size, "%u", idx); 12571 ++nb; 12572 } 12573 return nb; 12574 } 12575 12576 /** Complete index number for set raw_encap/raw_decap commands. */ 12577 static int 12578 comp_set_sample_index(struct context *ctx, const struct token *token, 12579 unsigned int ent, char *buf, unsigned int size) 12580 { 12581 uint16_t idx = 0; 12582 uint16_t nb = 0; 12583 12584 RTE_SET_USED(ctx); 12585 RTE_SET_USED(token); 12586 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 12587 if (buf && idx == ent) 12588 return snprintf(buf, size, "%u", idx); 12589 ++nb; 12590 } 12591 return nb; 12592 } 12593 12594 /** Complete operation for modify_field command. */ 12595 static int 12596 comp_set_modify_field_op(struct context *ctx, const struct token *token, 12597 unsigned int ent, char *buf, unsigned int size) 12598 { 12599 RTE_SET_USED(ctx); 12600 RTE_SET_USED(token); 12601 if (!buf) 12602 return RTE_DIM(modify_field_ops); 12603 if (ent < RTE_DIM(modify_field_ops) - 1) 12604 return strlcpy(buf, modify_field_ops[ent], size); 12605 return -1; 12606 } 12607 12608 /** Complete field id for modify_field command. */ 12609 static int 12610 comp_set_modify_field_id(struct context *ctx, const struct token *token, 12611 unsigned int ent, char *buf, unsigned int size) 12612 { 12613 const char *name; 12614 12615 RTE_SET_USED(token); 12616 if (!buf) 12617 return RTE_DIM(flow_field_ids); 12618 if (ent >= RTE_DIM(flow_field_ids) - 1) 12619 return -1; 12620 name = flow_field_ids[ent]; 12621 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 12622 (strcmp(name, "pointer") && strcmp(name, "value"))) 12623 return strlcpy(buf, name, size); 12624 return -1; 12625 } 12626 12627 /** Complete available pattern template IDs. */ 12628 static int 12629 comp_pattern_template_id(struct context *ctx, const struct token *token, 12630 unsigned int ent, char *buf, unsigned int size) 12631 { 12632 unsigned int i = 0; 12633 struct rte_port *port; 12634 struct port_template *pt; 12635 12636 (void)token; 12637 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12638 ctx->port == (portid_t)RTE_PORT_ALL) 12639 return -1; 12640 port = &ports[ctx->port]; 12641 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 12642 if (buf && i == ent) 12643 return snprintf(buf, size, "%u", pt->id); 12644 ++i; 12645 } 12646 if (buf) 12647 return -1; 12648 return i; 12649 } 12650 12651 /** Complete available actions template IDs. */ 12652 static int 12653 comp_actions_template_id(struct context *ctx, const struct token *token, 12654 unsigned int ent, char *buf, unsigned int size) 12655 { 12656 unsigned int i = 0; 12657 struct rte_port *port; 12658 struct port_template *pt; 12659 12660 (void)token; 12661 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12662 ctx->port == (portid_t)RTE_PORT_ALL) 12663 return -1; 12664 port = &ports[ctx->port]; 12665 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 12666 if (buf && i == ent) 12667 return snprintf(buf, size, "%u", pt->id); 12668 ++i; 12669 } 12670 if (buf) 12671 return -1; 12672 return i; 12673 } 12674 12675 /** Complete available table IDs. */ 12676 static int 12677 comp_table_id(struct context *ctx, const struct token *token, 12678 unsigned int ent, char *buf, unsigned int size) 12679 { 12680 unsigned int i = 0; 12681 struct rte_port *port; 12682 struct port_table *pt; 12683 12684 (void)token; 12685 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12686 ctx->port == (portid_t)RTE_PORT_ALL) 12687 return -1; 12688 port = &ports[ctx->port]; 12689 for (pt = port->table_list; pt != NULL; pt = pt->next) { 12690 if (buf && i == ent) 12691 return snprintf(buf, size, "%u", pt->id); 12692 ++i; 12693 } 12694 if (buf) 12695 return -1; 12696 return i; 12697 } 12698 12699 /** Complete available queue IDs. */ 12700 static int 12701 comp_queue_id(struct context *ctx, const struct token *token, 12702 unsigned int ent, char *buf, unsigned int size) 12703 { 12704 unsigned int i = 0; 12705 struct rte_port *port; 12706 12707 (void)token; 12708 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12709 ctx->port == (portid_t)RTE_PORT_ALL) 12710 return -1; 12711 port = &ports[ctx->port]; 12712 for (i = 0; i < port->queue_nb; i++) { 12713 if (buf && i == ent) 12714 return snprintf(buf, size, "%u", i); 12715 } 12716 if (buf) 12717 return -1; 12718 return i; 12719 } 12720 12721 static int 12722 comp_names_to_index(struct context *ctx, const struct token *token, 12723 unsigned int ent, char *buf, unsigned int size, 12724 const char *const names[], size_t names_size) 12725 { 12726 RTE_SET_USED(ctx); 12727 RTE_SET_USED(token); 12728 if (!buf) 12729 return names_size; 12730 if (names[ent] && ent < names_size) 12731 return rte_strscpy(buf, names[ent], size); 12732 return -1; 12733 12734 } 12735 12736 /** Complete available Meter colors. */ 12737 static int 12738 comp_meter_color(struct context *ctx, const struct token *token, 12739 unsigned int ent, char *buf, unsigned int size) 12740 { 12741 RTE_SET_USED(ctx); 12742 RTE_SET_USED(token); 12743 if (!buf) 12744 return RTE_DIM(meter_colors); 12745 if (ent < RTE_DIM(meter_colors) - 1) 12746 return strlcpy(buf, meter_colors[ent], size); 12747 return -1; 12748 } 12749 12750 /** Complete available Insertion Table types. */ 12751 static int 12752 comp_insertion_table_type(struct context *ctx, const struct token *token, 12753 unsigned int ent, char *buf, unsigned int size) 12754 { 12755 RTE_SET_USED(ctx); 12756 RTE_SET_USED(token); 12757 if (!buf) 12758 return RTE_DIM(table_insertion_types); 12759 if (ent < RTE_DIM(table_insertion_types) - 1) 12760 return rte_strscpy(buf, table_insertion_types[ent], size); 12761 return -1; 12762 } 12763 12764 /** Complete available Hash Calculation Table types. */ 12765 static int 12766 comp_hash_table_type(struct context *ctx, const struct token *token, 12767 unsigned int ent, char *buf, unsigned int size) 12768 { 12769 RTE_SET_USED(ctx); 12770 RTE_SET_USED(token); 12771 if (!buf) 12772 return RTE_DIM(table_hash_funcs); 12773 if (ent < RTE_DIM(table_hash_funcs) - 1) 12774 return rte_strscpy(buf, table_hash_funcs[ent], size); 12775 return -1; 12776 } 12777 12778 static int 12779 comp_quota_state_name(struct context *ctx, const struct token *token, 12780 unsigned int ent, char *buf, unsigned int size) 12781 { 12782 return comp_names_to_index(ctx, token, ent, buf, size, 12783 quota_state_names, 12784 RTE_DIM(quota_state_names)); 12785 } 12786 12787 static int 12788 comp_quota_mode_name(struct context *ctx, const struct token *token, 12789 unsigned int ent, char *buf, unsigned int size) 12790 { 12791 return comp_names_to_index(ctx, token, ent, buf, size, 12792 quota_mode_names, 12793 RTE_DIM(quota_mode_names)); 12794 } 12795 12796 static int 12797 comp_quota_update_name(struct context *ctx, const struct token *token, 12798 unsigned int ent, char *buf, unsigned int size) 12799 { 12800 return comp_names_to_index(ctx, token, ent, buf, size, 12801 quota_update_names, 12802 RTE_DIM(quota_update_names)); 12803 } 12804 12805 static int 12806 comp_qu_mode_name(struct context *ctx, const struct token *token, 12807 unsigned int ent, char *buf, unsigned int size) 12808 { 12809 return comp_names_to_index(ctx, token, ent, buf, size, 12810 query_update_mode_names, 12811 RTE_DIM(query_update_mode_names)); 12812 } 12813 12814 /** Internal context. */ 12815 static struct context cmd_flow_context; 12816 12817 /** Global parser instance (cmdline API). */ 12818 cmdline_parse_inst_t cmd_flow; 12819 cmdline_parse_inst_t cmd_set_raw; 12820 12821 /** Initialize context. */ 12822 static void 12823 cmd_flow_context_init(struct context *ctx) 12824 { 12825 /* A full memset() is not necessary. */ 12826 ctx->curr = ZERO; 12827 ctx->prev = ZERO; 12828 ctx->next_num = 0; 12829 ctx->args_num = 0; 12830 ctx->eol = 0; 12831 ctx->last = 0; 12832 ctx->port = 0; 12833 ctx->objdata = 0; 12834 ctx->object = NULL; 12835 ctx->objmask = NULL; 12836 } 12837 12838 /** Parse a token (cmdline API). */ 12839 static int 12840 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 12841 unsigned int size) 12842 { 12843 struct context *ctx = &cmd_flow_context; 12844 const struct token *token; 12845 const enum index *list; 12846 int len; 12847 int i; 12848 12849 (void)hdr; 12850 token = &token_list[ctx->curr]; 12851 /* Check argument length. */ 12852 ctx->eol = 0; 12853 ctx->last = 1; 12854 for (len = 0; src[len]; ++len) 12855 if (src[len] == '#' || isspace(src[len])) 12856 break; 12857 if (!len) 12858 return -1; 12859 /* Last argument and EOL detection. */ 12860 for (i = len; src[i]; ++i) 12861 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 12862 break; 12863 else if (!isspace(src[i])) { 12864 ctx->last = 0; 12865 break; 12866 } 12867 for (; src[i]; ++i) 12868 if (src[i] == '\r' || src[i] == '\n') { 12869 ctx->eol = 1; 12870 break; 12871 } 12872 /* Initialize context if necessary. */ 12873 if (!ctx->next_num) { 12874 if (!token->next) 12875 return 0; 12876 ctx->next[ctx->next_num++] = token->next[0]; 12877 } 12878 /* Process argument through candidates. */ 12879 ctx->prev = ctx->curr; 12880 list = ctx->next[ctx->next_num - 1]; 12881 for (i = 0; list[i]; ++i) { 12882 const struct token *next = &token_list[list[i]]; 12883 int tmp; 12884 12885 ctx->curr = list[i]; 12886 if (next->call) 12887 tmp = next->call(ctx, next, src, len, result, size); 12888 else 12889 tmp = parse_default(ctx, next, src, len, result, size); 12890 if (tmp == -1 || tmp != len) 12891 continue; 12892 token = next; 12893 break; 12894 } 12895 if (!list[i]) 12896 return -1; 12897 --ctx->next_num; 12898 /* Push subsequent tokens if any. */ 12899 if (token->next) 12900 for (i = 0; token->next[i]; ++i) { 12901 if (ctx->next_num == RTE_DIM(ctx->next)) 12902 return -1; 12903 ctx->next[ctx->next_num++] = token->next[i]; 12904 } 12905 /* Push arguments if any. */ 12906 if (token->args) 12907 for (i = 0; token->args[i]; ++i) { 12908 if (ctx->args_num == RTE_DIM(ctx->args)) 12909 return -1; 12910 ctx->args[ctx->args_num++] = token->args[i]; 12911 } 12912 return len; 12913 } 12914 12915 int 12916 flow_parse(const char *src, void *result, unsigned int size, 12917 struct rte_flow_attr **attr, 12918 struct rte_flow_item **pattern, struct rte_flow_action **actions) 12919 { 12920 int ret; 12921 struct context saved_flow_ctx = cmd_flow_context; 12922 12923 cmd_flow_context_init(&cmd_flow_context); 12924 do { 12925 ret = cmd_flow_parse(NULL, src, result, size); 12926 if (ret > 0) { 12927 src += ret; 12928 while (isspace(*src)) 12929 src++; 12930 } 12931 } while (ret > 0 && strlen(src)); 12932 cmd_flow_context = saved_flow_ctx; 12933 *attr = &((struct buffer *)result)->args.vc.attr; 12934 *pattern = ((struct buffer *)result)->args.vc.pattern; 12935 *actions = ((struct buffer *)result)->args.vc.actions; 12936 return (ret >= 0 && !strlen(src)) ? 0 : -1; 12937 } 12938 12939 /** Return number of completion entries (cmdline API). */ 12940 static int 12941 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 12942 { 12943 struct context *ctx = &cmd_flow_context; 12944 const struct token *token = &token_list[ctx->curr]; 12945 const enum index *list; 12946 int i; 12947 12948 (void)hdr; 12949 /* Count number of tokens in current list. */ 12950 if (ctx->next_num) 12951 list = ctx->next[ctx->next_num - 1]; 12952 else 12953 list = token->next[0]; 12954 for (i = 0; list[i]; ++i) 12955 ; 12956 if (!i) 12957 return 0; 12958 /* 12959 * If there is a single token, use its completion callback, otherwise 12960 * return the number of entries. 12961 */ 12962 token = &token_list[list[0]]; 12963 if (i == 1 && token->comp) { 12964 /* Save index for cmd_flow_get_help(). */ 12965 ctx->prev = list[0]; 12966 return token->comp(ctx, token, 0, NULL, 0); 12967 } 12968 return i; 12969 } 12970 12971 /** Return a completion entry (cmdline API). */ 12972 static int 12973 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 12974 char *dst, unsigned int size) 12975 { 12976 struct context *ctx = &cmd_flow_context; 12977 const struct token *token = &token_list[ctx->curr]; 12978 const enum index *list; 12979 int i; 12980 12981 (void)hdr; 12982 /* Count number of tokens in current list. */ 12983 if (ctx->next_num) 12984 list = ctx->next[ctx->next_num - 1]; 12985 else 12986 list = token->next[0]; 12987 for (i = 0; list[i]; ++i) 12988 ; 12989 if (!i) 12990 return -1; 12991 /* If there is a single token, use its completion callback. */ 12992 token = &token_list[list[0]]; 12993 if (i == 1 && token->comp) { 12994 /* Save index for cmd_flow_get_help(). */ 12995 ctx->prev = list[0]; 12996 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 12997 } 12998 /* Otherwise make sure the index is valid and use defaults. */ 12999 if (index >= i) 13000 return -1; 13001 token = &token_list[list[index]]; 13002 strlcpy(dst, token->name, size); 13003 /* Save index for cmd_flow_get_help(). */ 13004 ctx->prev = list[index]; 13005 return 0; 13006 } 13007 13008 /** Populate help strings for current token (cmdline API). */ 13009 static int 13010 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 13011 { 13012 struct context *ctx = &cmd_flow_context; 13013 const struct token *token = &token_list[ctx->prev]; 13014 13015 (void)hdr; 13016 if (!size) 13017 return -1; 13018 /* Set token type and update global help with details. */ 13019 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 13020 if (token->help) 13021 cmd_flow.help_str = token->help; 13022 else 13023 cmd_flow.help_str = token->name; 13024 return 0; 13025 } 13026 13027 /** Token definition template (cmdline API). */ 13028 static struct cmdline_token_hdr cmd_flow_token_hdr = { 13029 .ops = &(struct cmdline_token_ops){ 13030 .parse = cmd_flow_parse, 13031 .complete_get_nb = cmd_flow_complete_get_nb, 13032 .complete_get_elt = cmd_flow_complete_get_elt, 13033 .get_help = cmd_flow_get_help, 13034 }, 13035 .offset = 0, 13036 }; 13037 13038 /** Populate the next dynamic token. */ 13039 static void 13040 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 13041 cmdline_parse_token_hdr_t **hdr_inst) 13042 { 13043 struct context *ctx = &cmd_flow_context; 13044 13045 /* Always reinitialize context before requesting the first token. */ 13046 if (!(hdr_inst - cmd_flow.tokens)) 13047 cmd_flow_context_init(ctx); 13048 /* Return NULL when no more tokens are expected. */ 13049 if (!ctx->next_num && ctx->curr) { 13050 *hdr = NULL; 13051 return; 13052 } 13053 /* Determine if command should end here. */ 13054 if (ctx->eol && ctx->last && ctx->next_num) { 13055 const enum index *list = ctx->next[ctx->next_num - 1]; 13056 int i; 13057 13058 for (i = 0; list[i]; ++i) { 13059 if (list[i] != END) 13060 continue; 13061 *hdr = NULL; 13062 return; 13063 } 13064 } 13065 *hdr = &cmd_flow_token_hdr; 13066 } 13067 13068 static SLIST_HEAD(, indlst_conf) indlst_conf_head = 13069 SLIST_HEAD_INITIALIZER(); 13070 13071 static void 13072 indirect_action_flow_conf_create(const struct buffer *in) 13073 { 13074 int len, ret; 13075 uint32_t i; 13076 struct indlst_conf *indlst_conf = NULL; 13077 size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); 13078 struct rte_flow_action *src = in->args.vc.actions; 13079 13080 if (!in->args.vc.actions_n) 13081 goto end; 13082 len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); 13083 if (len <= 0) 13084 goto end; 13085 len = RTE_ALIGN(len, 16); 13086 13087 indlst_conf = calloc(1, base + len + 13088 in->args.vc.actions_n * sizeof(uintptr_t)); 13089 if (!indlst_conf) 13090 goto end; 13091 indlst_conf->id = in->args.vc.attr.group; 13092 indlst_conf->conf_num = in->args.vc.actions_n - 1; 13093 indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); 13094 ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, 13095 len, src, NULL); 13096 if (ret <= 0) { 13097 free(indlst_conf); 13098 indlst_conf = NULL; 13099 goto end; 13100 } 13101 indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); 13102 for (i = 0; i < indlst_conf->conf_num; i++) 13103 indlst_conf->conf[i] = indlst_conf->actions[i].conf; 13104 SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); 13105 end: 13106 if (indlst_conf) 13107 printf("created indirect action list configuration %u\n", 13108 in->args.vc.attr.group); 13109 else 13110 printf("cannot create indirect action list configuration %u\n", 13111 in->args.vc.attr.group); 13112 } 13113 13114 static const struct indlst_conf * 13115 indirect_action_list_conf_get(uint32_t conf_id) 13116 { 13117 const struct indlst_conf *conf; 13118 13119 SLIST_FOREACH(conf, &indlst_conf_head, next) { 13120 if (conf->id == conf_id) 13121 return conf; 13122 } 13123 return NULL; 13124 } 13125 13126 /** Dispatch parsed buffer to function calls. */ 13127 static void 13128 cmd_flow_parsed(const struct buffer *in) 13129 { 13130 switch (in->command) { 13131 case INFO: 13132 port_flow_get_info(in->port); 13133 break; 13134 case CONFIGURE: 13135 port_flow_configure(in->port, 13136 &in->args.configure.port_attr, 13137 in->args.configure.nb_queue, 13138 &in->args.configure.queue_attr); 13139 break; 13140 case PATTERN_TEMPLATE_CREATE: 13141 port_flow_pattern_template_create(in->port, 13142 in->args.vc.pat_templ_id, 13143 &((const struct rte_flow_pattern_template_attr) { 13144 .relaxed_matching = in->args.vc.attr.reserved, 13145 .ingress = in->args.vc.attr.ingress, 13146 .egress = in->args.vc.attr.egress, 13147 .transfer = in->args.vc.attr.transfer, 13148 }), 13149 in->args.vc.pattern); 13150 break; 13151 case PATTERN_TEMPLATE_DESTROY: 13152 port_flow_pattern_template_destroy(in->port, 13153 in->args.templ_destroy.template_id_n, 13154 in->args.templ_destroy.template_id); 13155 break; 13156 case ACTIONS_TEMPLATE_CREATE: 13157 port_flow_actions_template_create(in->port, 13158 in->args.vc.act_templ_id, 13159 &((const struct rte_flow_actions_template_attr) { 13160 .ingress = in->args.vc.attr.ingress, 13161 .egress = in->args.vc.attr.egress, 13162 .transfer = in->args.vc.attr.transfer, 13163 }), 13164 in->args.vc.actions, 13165 in->args.vc.masks); 13166 break; 13167 case ACTIONS_TEMPLATE_DESTROY: 13168 port_flow_actions_template_destroy(in->port, 13169 in->args.templ_destroy.template_id_n, 13170 in->args.templ_destroy.template_id); 13171 break; 13172 case TABLE_CREATE: 13173 port_flow_template_table_create(in->port, in->args.table.id, 13174 &in->args.table.attr, in->args.table.pat_templ_id_n, 13175 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 13176 in->args.table.act_templ_id); 13177 break; 13178 case TABLE_DESTROY: 13179 port_flow_template_table_destroy(in->port, 13180 in->args.table_destroy.table_id_n, 13181 in->args.table_destroy.table_id); 13182 break; 13183 case TABLE_RESIZE_COMPLETE: 13184 port_flow_template_table_resize_complete 13185 (in->port, in->args.table_destroy.table_id[0]); 13186 break; 13187 case GROUP_SET_MISS_ACTIONS: 13188 port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, 13189 in->args.vc.actions); 13190 break; 13191 case TABLE_RESIZE: 13192 port_flow_template_table_resize(in->port, in->args.table.id, 13193 in->args.table.attr.nb_flows); 13194 break; 13195 case QUEUE_CREATE: 13196 port_queue_flow_create(in->port, in->queue, in->postpone, 13197 in->args.vc.table_id, in->args.vc.rule_id, 13198 in->args.vc.pat_templ_id, in->args.vc.act_templ_id, 13199 in->args.vc.pattern, in->args.vc.actions); 13200 break; 13201 case QUEUE_DESTROY: 13202 port_queue_flow_destroy(in->port, in->queue, in->postpone, 13203 in->args.destroy.rule_n, 13204 in->args.destroy.rule); 13205 break; 13206 case QUEUE_FLOW_UPDATE_RESIZED: 13207 port_queue_flow_update_resized(in->port, in->queue, 13208 in->postpone, 13209 in->args.destroy.rule[0]); 13210 break; 13211 case QUEUE_UPDATE: 13212 port_queue_flow_update(in->port, in->queue, in->postpone, 13213 in->args.vc.rule_id, in->args.vc.act_templ_id, 13214 in->args.vc.actions); 13215 break; 13216 case PUSH: 13217 port_queue_flow_push(in->port, in->queue); 13218 break; 13219 case PULL: 13220 port_queue_flow_pull(in->port, in->queue); 13221 break; 13222 case HASH: 13223 if (!in->args.vc.encap_hash) 13224 port_flow_hash_calc(in->port, in->args.vc.table_id, 13225 in->args.vc.pat_templ_id, 13226 in->args.vc.pattern); 13227 else 13228 port_flow_hash_calc_encap(in->port, in->args.vc.field, 13229 in->args.vc.pattern); 13230 break; 13231 case QUEUE_AGED: 13232 port_queue_flow_aged(in->port, in->queue, 13233 in->args.aged.destroy); 13234 break; 13235 case QUEUE_INDIRECT_ACTION_CREATE: 13236 case QUEUE_INDIRECT_ACTION_LIST_CREATE: 13237 port_queue_action_handle_create( 13238 in->port, in->queue, in->postpone, 13239 in->args.vc.attr.group, 13240 &((const struct rte_flow_indir_action_conf) { 13241 .ingress = in->args.vc.attr.ingress, 13242 .egress = in->args.vc.attr.egress, 13243 .transfer = in->args.vc.attr.transfer, 13244 }), 13245 in->args.vc.actions); 13246 break; 13247 case QUEUE_INDIRECT_ACTION_DESTROY: 13248 port_queue_action_handle_destroy(in->port, 13249 in->queue, in->postpone, 13250 in->args.ia_destroy.action_id_n, 13251 in->args.ia_destroy.action_id); 13252 break; 13253 case QUEUE_INDIRECT_ACTION_UPDATE: 13254 port_queue_action_handle_update(in->port, 13255 in->queue, in->postpone, 13256 in->args.vc.attr.group, 13257 in->args.vc.actions); 13258 break; 13259 case QUEUE_INDIRECT_ACTION_QUERY: 13260 port_queue_action_handle_query(in->port, 13261 in->queue, in->postpone, 13262 in->args.ia.action_id); 13263 break; 13264 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 13265 port_queue_action_handle_query_update(in->port, in->queue, 13266 in->postpone, 13267 in->args.ia.action_id, 13268 in->args.ia.qu_mode, 13269 in->args.vc.actions); 13270 break; 13271 case INDIRECT_ACTION_CREATE: 13272 case INDIRECT_ACTION_LIST_CREATE: 13273 port_action_handle_create( 13274 in->port, in->args.vc.attr.group, 13275 in->command == INDIRECT_ACTION_LIST_CREATE, 13276 &((const struct rte_flow_indir_action_conf) { 13277 .ingress = in->args.vc.attr.ingress, 13278 .egress = in->args.vc.attr.egress, 13279 .transfer = in->args.vc.attr.transfer, 13280 }), 13281 in->args.vc.actions); 13282 break; 13283 case INDIRECT_ACTION_FLOW_CONF_CREATE: 13284 indirect_action_flow_conf_create(in); 13285 break; 13286 case INDIRECT_ACTION_DESTROY: 13287 port_action_handle_destroy(in->port, 13288 in->args.ia_destroy.action_id_n, 13289 in->args.ia_destroy.action_id); 13290 break; 13291 case INDIRECT_ACTION_UPDATE: 13292 port_action_handle_update(in->port, in->args.vc.attr.group, 13293 in->args.vc.actions); 13294 break; 13295 case INDIRECT_ACTION_QUERY: 13296 port_action_handle_query(in->port, in->args.ia.action_id); 13297 break; 13298 case INDIRECT_ACTION_QUERY_UPDATE: 13299 port_action_handle_query_update(in->port, 13300 in->args.ia.action_id, 13301 in->args.ia.qu_mode, 13302 in->args.vc.actions); 13303 break; 13304 case VALIDATE: 13305 port_flow_validate(in->port, &in->args.vc.attr, 13306 in->args.vc.pattern, in->args.vc.actions, 13307 &in->args.vc.tunnel_ops); 13308 break; 13309 case CREATE: 13310 port_flow_create(in->port, &in->args.vc.attr, 13311 in->args.vc.pattern, in->args.vc.actions, 13312 &in->args.vc.tunnel_ops, in->args.vc.user_id); 13313 break; 13314 case DESTROY: 13315 port_flow_destroy(in->port, in->args.destroy.rule_n, 13316 in->args.destroy.rule, 13317 in->args.destroy.is_user_id); 13318 break; 13319 case UPDATE: 13320 port_flow_update(in->port, in->args.vc.rule_id, 13321 in->args.vc.actions, in->args.vc.user_id); 13322 break; 13323 case FLUSH: 13324 port_flow_flush(in->port); 13325 break; 13326 case DUMP_ONE: 13327 case DUMP_ALL: 13328 port_flow_dump(in->port, in->args.dump.mode, 13329 in->args.dump.rule, in->args.dump.file, 13330 in->args.dump.is_user_id); 13331 break; 13332 case QUERY: 13333 port_flow_query(in->port, in->args.query.rule, 13334 &in->args.query.action, 13335 in->args.query.is_user_id); 13336 break; 13337 case LIST: 13338 port_flow_list(in->port, in->args.list.group_n, 13339 in->args.list.group); 13340 break; 13341 case ISOLATE: 13342 port_flow_isolate(in->port, in->args.isolate.set); 13343 break; 13344 case AGED: 13345 port_flow_aged(in->port, in->args.aged.destroy); 13346 break; 13347 case TUNNEL_CREATE: 13348 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 13349 break; 13350 case TUNNEL_DESTROY: 13351 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 13352 break; 13353 case TUNNEL_LIST: 13354 port_flow_tunnel_list(in->port); 13355 break; 13356 case ACTION_POL_G: 13357 port_meter_policy_add(in->port, in->args.policy.policy_id, 13358 in->args.vc.actions); 13359 break; 13360 case FLEX_ITEM_CREATE: 13361 flex_item_create(in->port, in->args.flex.token, 13362 in->args.flex.filename); 13363 break; 13364 case FLEX_ITEM_DESTROY: 13365 flex_item_destroy(in->port, in->args.flex.token); 13366 break; 13367 default: 13368 break; 13369 } 13370 fflush(stdout); 13371 } 13372 13373 /** Token generator and output processing callback (cmdline API). */ 13374 static void 13375 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 13376 { 13377 if (cl == NULL) 13378 cmd_flow_tok(arg0, arg2); 13379 else 13380 cmd_flow_parsed(arg0); 13381 } 13382 13383 /** Global parser instance (cmdline API). */ 13384 cmdline_parse_inst_t cmd_flow = { 13385 .f = cmd_flow_cb, 13386 .data = NULL, /**< Unused. */ 13387 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 13388 .tokens = { 13389 NULL, 13390 }, /**< Tokens are returned by cmd_flow_tok(). */ 13391 }; 13392 13393 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 13394 13395 static void 13396 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 13397 { 13398 struct rte_ipv4_hdr *ipv4; 13399 struct rte_ether_hdr *eth; 13400 struct rte_ipv6_hdr *ipv6; 13401 struct rte_vxlan_hdr *vxlan; 13402 struct rte_vxlan_gpe_hdr *gpe; 13403 struct rte_flow_item_nvgre *nvgre; 13404 uint32_t ipv6_vtc_flow; 13405 13406 switch (item->type) { 13407 case RTE_FLOW_ITEM_TYPE_ETH: 13408 eth = (struct rte_ether_hdr *)buf; 13409 if (next_proto) 13410 eth->ether_type = rte_cpu_to_be_16(next_proto); 13411 break; 13412 case RTE_FLOW_ITEM_TYPE_IPV4: 13413 ipv4 = (struct rte_ipv4_hdr *)buf; 13414 if (!ipv4->version_ihl) 13415 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 13416 if (next_proto && ipv4->next_proto_id == 0) 13417 ipv4->next_proto_id = (uint8_t)next_proto; 13418 break; 13419 case RTE_FLOW_ITEM_TYPE_IPV6: 13420 ipv6 = (struct rte_ipv6_hdr *)buf; 13421 if (next_proto && ipv6->proto == 0) 13422 ipv6->proto = (uint8_t)next_proto; 13423 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 13424 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 13425 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 13426 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 13427 break; 13428 case RTE_FLOW_ITEM_TYPE_VXLAN: 13429 vxlan = (struct rte_vxlan_hdr *)buf; 13430 vxlan->vx_flags = 0x08; 13431 break; 13432 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13433 gpe = (struct rte_vxlan_gpe_hdr *)buf; 13434 gpe->vx_flags = 0x0C; 13435 break; 13436 case RTE_FLOW_ITEM_TYPE_NVGRE: 13437 nvgre = (struct rte_flow_item_nvgre *)buf; 13438 nvgre->protocol = rte_cpu_to_be_16(0x6558); 13439 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 13440 break; 13441 default: 13442 break; 13443 } 13444 } 13445 13446 /** Helper of get item's default mask. */ 13447 static const void * 13448 flow_item_default_mask(const struct rte_flow_item *item) 13449 { 13450 const void *mask = NULL; 13451 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 13452 static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { 13453 .hdr = { 13454 .next_hdr = 0xff, 13455 .type = 0xff, 13456 .segments_left = 0xff, 13457 }, 13458 }; 13459 13460 switch (item->type) { 13461 case RTE_FLOW_ITEM_TYPE_ANY: 13462 mask = &rte_flow_item_any_mask; 13463 break; 13464 case RTE_FLOW_ITEM_TYPE_PORT_ID: 13465 mask = &rte_flow_item_port_id_mask; 13466 break; 13467 case RTE_FLOW_ITEM_TYPE_RAW: 13468 mask = &rte_flow_item_raw_mask; 13469 break; 13470 case RTE_FLOW_ITEM_TYPE_ETH: 13471 mask = &rte_flow_item_eth_mask; 13472 break; 13473 case RTE_FLOW_ITEM_TYPE_VLAN: 13474 mask = &rte_flow_item_vlan_mask; 13475 break; 13476 case RTE_FLOW_ITEM_TYPE_IPV4: 13477 mask = &rte_flow_item_ipv4_mask; 13478 break; 13479 case RTE_FLOW_ITEM_TYPE_IPV6: 13480 mask = &rte_flow_item_ipv6_mask; 13481 break; 13482 case RTE_FLOW_ITEM_TYPE_ICMP: 13483 mask = &rte_flow_item_icmp_mask; 13484 break; 13485 case RTE_FLOW_ITEM_TYPE_UDP: 13486 mask = &rte_flow_item_udp_mask; 13487 break; 13488 case RTE_FLOW_ITEM_TYPE_TCP: 13489 mask = &rte_flow_item_tcp_mask; 13490 break; 13491 case RTE_FLOW_ITEM_TYPE_SCTP: 13492 mask = &rte_flow_item_sctp_mask; 13493 break; 13494 case RTE_FLOW_ITEM_TYPE_VXLAN: 13495 mask = &rte_flow_item_vxlan_mask; 13496 break; 13497 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13498 mask = &rte_flow_item_vxlan_gpe_mask; 13499 break; 13500 case RTE_FLOW_ITEM_TYPE_E_TAG: 13501 mask = &rte_flow_item_e_tag_mask; 13502 break; 13503 case RTE_FLOW_ITEM_TYPE_NVGRE: 13504 mask = &rte_flow_item_nvgre_mask; 13505 break; 13506 case RTE_FLOW_ITEM_TYPE_MPLS: 13507 mask = &rte_flow_item_mpls_mask; 13508 break; 13509 case RTE_FLOW_ITEM_TYPE_GRE: 13510 mask = &rte_flow_item_gre_mask; 13511 break; 13512 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13513 mask = &gre_key_default_mask; 13514 break; 13515 case RTE_FLOW_ITEM_TYPE_META: 13516 mask = &rte_flow_item_meta_mask; 13517 break; 13518 case RTE_FLOW_ITEM_TYPE_RANDOM: 13519 mask = &rte_flow_item_random_mask; 13520 break; 13521 case RTE_FLOW_ITEM_TYPE_FUZZY: 13522 mask = &rte_flow_item_fuzzy_mask; 13523 break; 13524 case RTE_FLOW_ITEM_TYPE_GTP: 13525 mask = &rte_flow_item_gtp_mask; 13526 break; 13527 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13528 mask = &rte_flow_item_gtp_psc_mask; 13529 break; 13530 case RTE_FLOW_ITEM_TYPE_GENEVE: 13531 mask = &rte_flow_item_geneve_mask; 13532 break; 13533 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13534 mask = &rte_flow_item_geneve_opt_mask; 13535 break; 13536 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 13537 mask = &rte_flow_item_pppoe_proto_id_mask; 13538 break; 13539 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13540 mask = &rte_flow_item_l2tpv3oip_mask; 13541 break; 13542 case RTE_FLOW_ITEM_TYPE_ESP: 13543 mask = &rte_flow_item_esp_mask; 13544 break; 13545 case RTE_FLOW_ITEM_TYPE_AH: 13546 mask = &rte_flow_item_ah_mask; 13547 break; 13548 case RTE_FLOW_ITEM_TYPE_PFCP: 13549 mask = &rte_flow_item_pfcp_mask; 13550 break; 13551 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 13552 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 13553 mask = &rte_flow_item_ethdev_mask; 13554 break; 13555 case RTE_FLOW_ITEM_TYPE_L2TPV2: 13556 mask = &rte_flow_item_l2tpv2_mask; 13557 break; 13558 case RTE_FLOW_ITEM_TYPE_PPP: 13559 mask = &rte_flow_item_ppp_mask; 13560 break; 13561 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 13562 mask = &rte_flow_item_meter_color_mask; 13563 break; 13564 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13565 mask = &ipv6_routing_ext_default_mask; 13566 break; 13567 case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: 13568 mask = &rte_flow_item_aggr_affinity_mask; 13569 break; 13570 case RTE_FLOW_ITEM_TYPE_TX_QUEUE: 13571 mask = &rte_flow_item_tx_queue_mask; 13572 break; 13573 case RTE_FLOW_ITEM_TYPE_IB_BTH: 13574 mask = &rte_flow_item_ib_bth_mask; 13575 break; 13576 case RTE_FLOW_ITEM_TYPE_PTYPE: 13577 mask = &rte_flow_item_ptype_mask; 13578 break; 13579 default: 13580 break; 13581 } 13582 return mask; 13583 } 13584 13585 /** Dispatch parsed buffer to function calls. */ 13586 static void 13587 cmd_set_ipv6_ext_parsed(const struct buffer *in) 13588 { 13589 uint32_t n = in->args.vc.pattern_n; 13590 int i = 0; 13591 struct rte_flow_item *item = NULL; 13592 size_t size = 0; 13593 uint8_t *data = NULL; 13594 uint8_t *type = NULL; 13595 size_t *total_size = NULL; 13596 uint16_t idx = in->port; /* We borrow port field as index */ 13597 struct rte_flow_item_ipv6_routing_ext *ext; 13598 const struct rte_flow_item_ipv6_ext *ipv6_ext; 13599 13600 RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || 13601 in->command == SET_IPV6_EXT_REMOVE); 13602 13603 if (in->command == SET_IPV6_EXT_REMOVE) { 13604 if (n != 1 || in->args.vc.pattern->type != 13605 RTE_FLOW_ITEM_TYPE_IPV6_EXT) { 13606 fprintf(stderr, "Error - Not supported item\n"); 13607 return; 13608 } 13609 type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; 13610 item = in->args.vc.pattern; 13611 ipv6_ext = item->spec; 13612 *type = ipv6_ext->next_hdr; 13613 return; 13614 } 13615 13616 total_size = &ipv6_ext_push_confs[idx].size; 13617 data = (uint8_t *)&ipv6_ext_push_confs[idx].data; 13618 type = (uint8_t *)&ipv6_ext_push_confs[idx].type; 13619 13620 *total_size = 0; 13621 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13622 for (i = n - 1 ; i >= 0; --i) { 13623 item = in->args.vc.pattern + i; 13624 switch (item->type) { 13625 case RTE_FLOW_ITEM_TYPE_IPV6_EXT: 13626 ipv6_ext = item->spec; 13627 *type = ipv6_ext->next_hdr; 13628 break; 13629 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13630 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13631 if (!ext->hdr.hdr_len) { 13632 size = sizeof(struct rte_ipv6_routing_ext) + 13633 (ext->hdr.segments_left << 4); 13634 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13635 /* Indicate no TLV once SRH. */ 13636 if (ext->hdr.type == 4) 13637 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13638 } else { 13639 size = sizeof(struct rte_ipv6_routing_ext) + 13640 (ext->hdr.hdr_len << 3); 13641 } 13642 *total_size += size; 13643 memcpy(data, ext, size); 13644 break; 13645 default: 13646 fprintf(stderr, "Error - Not supported item\n"); 13647 goto error; 13648 } 13649 } 13650 RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); 13651 return; 13652 error: 13653 *total_size = 0; 13654 memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); 13655 } 13656 13657 /** Dispatch parsed buffer to function calls. */ 13658 static void 13659 cmd_set_raw_parsed_sample(const struct buffer *in) 13660 { 13661 uint32_t n = in->args.vc.actions_n; 13662 uint32_t i = 0; 13663 struct rte_flow_action *action = NULL; 13664 struct rte_flow_action *data = NULL; 13665 const struct rte_flow_action_rss *rss = NULL; 13666 size_t size = 0; 13667 uint16_t idx = in->port; /* We borrow port field as index */ 13668 uint32_t max_size = sizeof(struct rte_flow_action) * 13669 ACTION_SAMPLE_ACTIONS_NUM; 13670 13671 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 13672 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 13673 memset(data, 0x00, max_size); 13674 for (; i <= n - 1; i++) { 13675 action = in->args.vc.actions + i; 13676 if (action->type == RTE_FLOW_ACTION_TYPE_END) 13677 break; 13678 switch (action->type) { 13679 case RTE_FLOW_ACTION_TYPE_MARK: 13680 size = sizeof(struct rte_flow_action_mark); 13681 rte_memcpy(&sample_mark[idx], 13682 (const void *)action->conf, size); 13683 action->conf = &sample_mark[idx]; 13684 break; 13685 case RTE_FLOW_ACTION_TYPE_COUNT: 13686 size = sizeof(struct rte_flow_action_count); 13687 rte_memcpy(&sample_count[idx], 13688 (const void *)action->conf, size); 13689 action->conf = &sample_count[idx]; 13690 break; 13691 case RTE_FLOW_ACTION_TYPE_QUEUE: 13692 size = sizeof(struct rte_flow_action_queue); 13693 rte_memcpy(&sample_queue[idx], 13694 (const void *)action->conf, size); 13695 action->conf = &sample_queue[idx]; 13696 break; 13697 case RTE_FLOW_ACTION_TYPE_RSS: 13698 size = sizeof(struct rte_flow_action_rss); 13699 rss = action->conf; 13700 rte_memcpy(&sample_rss_data[idx].conf, 13701 (const void *)rss, size); 13702 if (rss->key_len && rss->key) { 13703 sample_rss_data[idx].conf.key = 13704 sample_rss_data[idx].key; 13705 rte_memcpy((void *)((uintptr_t) 13706 sample_rss_data[idx].conf.key), 13707 (const void *)rss->key, 13708 sizeof(uint8_t) * rss->key_len); 13709 } 13710 if (rss->queue_num && rss->queue) { 13711 sample_rss_data[idx].conf.queue = 13712 sample_rss_data[idx].queue; 13713 rte_memcpy((void *)((uintptr_t) 13714 sample_rss_data[idx].conf.queue), 13715 (const void *)rss->queue, 13716 sizeof(uint16_t) * rss->queue_num); 13717 } 13718 action->conf = &sample_rss_data[idx].conf; 13719 break; 13720 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 13721 size = sizeof(struct rte_flow_action_raw_encap); 13722 rte_memcpy(&sample_encap[idx], 13723 (const void *)action->conf, size); 13724 action->conf = &sample_encap[idx]; 13725 break; 13726 case RTE_FLOW_ACTION_TYPE_PORT_ID: 13727 size = sizeof(struct rte_flow_action_port_id); 13728 rte_memcpy(&sample_port_id[idx], 13729 (const void *)action->conf, size); 13730 action->conf = &sample_port_id[idx]; 13731 break; 13732 case RTE_FLOW_ACTION_TYPE_PF: 13733 break; 13734 case RTE_FLOW_ACTION_TYPE_VF: 13735 size = sizeof(struct rte_flow_action_vf); 13736 rte_memcpy(&sample_vf[idx], 13737 (const void *)action->conf, size); 13738 action->conf = &sample_vf[idx]; 13739 break; 13740 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 13741 size = sizeof(struct rte_flow_action_vxlan_encap); 13742 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 13743 action->conf = &sample_vxlan_encap[idx].conf; 13744 break; 13745 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 13746 size = sizeof(struct rte_flow_action_nvgre_encap); 13747 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 13748 action->conf = &sample_nvgre_encap[idx]; 13749 break; 13750 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 13751 size = sizeof(struct rte_flow_action_ethdev); 13752 rte_memcpy(&sample_port_representor[idx], 13753 (const void *)action->conf, size); 13754 action->conf = &sample_port_representor[idx]; 13755 break; 13756 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 13757 size = sizeof(struct rte_flow_action_ethdev); 13758 rte_memcpy(&sample_represented_port[idx], 13759 (const void *)action->conf, size); 13760 action->conf = &sample_represented_port[idx]; 13761 break; 13762 default: 13763 fprintf(stderr, "Error - Not supported action\n"); 13764 return; 13765 } 13766 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 13767 data++; 13768 } 13769 } 13770 13771 /** Dispatch parsed buffer to function calls. */ 13772 static void 13773 cmd_set_raw_parsed(const struct buffer *in) 13774 { 13775 uint32_t n = in->args.vc.pattern_n; 13776 int i = 0; 13777 struct rte_flow_item *item = NULL; 13778 size_t size = 0; 13779 uint8_t *data = NULL; 13780 uint8_t *data_tail = NULL; 13781 size_t *total_size = NULL; 13782 uint16_t upper_layer = 0; 13783 uint16_t proto = 0; 13784 uint16_t idx = in->port; /* We borrow port field as index */ 13785 int gtp_psc = -1; /* GTP PSC option index. */ 13786 const void *src_spec; 13787 13788 if (in->command == SET_SAMPLE_ACTIONS) 13789 return cmd_set_raw_parsed_sample(in); 13790 else if (in->command == SET_IPV6_EXT_PUSH || 13791 in->command == SET_IPV6_EXT_REMOVE) 13792 return cmd_set_ipv6_ext_parsed(in); 13793 RTE_ASSERT(in->command == SET_RAW_ENCAP || 13794 in->command == SET_RAW_DECAP); 13795 if (in->command == SET_RAW_ENCAP) { 13796 total_size = &raw_encap_confs[idx].size; 13797 data = (uint8_t *)&raw_encap_confs[idx].data; 13798 } else { 13799 total_size = &raw_decap_confs[idx].size; 13800 data = (uint8_t *)&raw_decap_confs[idx].data; 13801 } 13802 *total_size = 0; 13803 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13804 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 13805 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 13806 for (i = n - 1 ; i >= 0; --i) { 13807 const struct rte_flow_item_gtp *gtp; 13808 const struct rte_flow_item_geneve_opt *opt; 13809 struct rte_flow_item_ipv6_routing_ext *ext; 13810 13811 item = in->args.vc.pattern + i; 13812 if (item->spec == NULL) 13813 item->spec = flow_item_default_mask(item); 13814 src_spec = item->spec; 13815 switch (item->type) { 13816 case RTE_FLOW_ITEM_TYPE_ETH: 13817 size = sizeof(struct rte_ether_hdr); 13818 break; 13819 case RTE_FLOW_ITEM_TYPE_VLAN: 13820 size = sizeof(struct rte_vlan_hdr); 13821 proto = RTE_ETHER_TYPE_VLAN; 13822 break; 13823 case RTE_FLOW_ITEM_TYPE_IPV4: 13824 size = sizeof(struct rte_ipv4_hdr); 13825 proto = RTE_ETHER_TYPE_IPV4; 13826 break; 13827 case RTE_FLOW_ITEM_TYPE_IPV6: 13828 size = sizeof(struct rte_ipv6_hdr); 13829 proto = RTE_ETHER_TYPE_IPV6; 13830 break; 13831 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13832 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13833 if (!ext->hdr.hdr_len) { 13834 size = sizeof(struct rte_ipv6_routing_ext) + 13835 (ext->hdr.segments_left << 4); 13836 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13837 /* SRv6 without TLV. */ 13838 if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) 13839 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13840 } else { 13841 size = sizeof(struct rte_ipv6_routing_ext) + 13842 (ext->hdr.hdr_len << 3); 13843 } 13844 proto = IPPROTO_ROUTING; 13845 break; 13846 case RTE_FLOW_ITEM_TYPE_UDP: 13847 size = sizeof(struct rte_udp_hdr); 13848 proto = 0x11; 13849 break; 13850 case RTE_FLOW_ITEM_TYPE_TCP: 13851 size = sizeof(struct rte_tcp_hdr); 13852 proto = 0x06; 13853 break; 13854 case RTE_FLOW_ITEM_TYPE_VXLAN: 13855 size = sizeof(struct rte_vxlan_hdr); 13856 break; 13857 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13858 size = sizeof(struct rte_vxlan_gpe_hdr); 13859 break; 13860 case RTE_FLOW_ITEM_TYPE_GRE: 13861 size = sizeof(struct rte_gre_hdr); 13862 proto = 0x2F; 13863 break; 13864 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13865 size = sizeof(rte_be32_t); 13866 proto = 0x0; 13867 break; 13868 case RTE_FLOW_ITEM_TYPE_MPLS: 13869 size = sizeof(struct rte_mpls_hdr); 13870 proto = 0x0; 13871 break; 13872 case RTE_FLOW_ITEM_TYPE_NVGRE: 13873 size = sizeof(struct rte_flow_item_nvgre); 13874 proto = 0x2F; 13875 break; 13876 case RTE_FLOW_ITEM_TYPE_GENEVE: 13877 size = sizeof(struct rte_geneve_hdr); 13878 break; 13879 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13880 opt = (const struct rte_flow_item_geneve_opt *) 13881 item->spec; 13882 size = offsetof(struct rte_flow_item_geneve_opt, 13883 option_len) + sizeof(uint8_t); 13884 if (opt->option_len && opt->data) { 13885 *total_size += opt->option_len * 13886 sizeof(uint32_t); 13887 rte_memcpy(data_tail - (*total_size), 13888 opt->data, 13889 opt->option_len * sizeof(uint32_t)); 13890 } 13891 break; 13892 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13893 size = sizeof(rte_be32_t); 13894 proto = 0x73; 13895 break; 13896 case RTE_FLOW_ITEM_TYPE_ESP: 13897 size = sizeof(struct rte_esp_hdr); 13898 proto = 0x32; 13899 break; 13900 case RTE_FLOW_ITEM_TYPE_AH: 13901 size = sizeof(struct rte_flow_item_ah); 13902 proto = 0x33; 13903 break; 13904 case RTE_FLOW_ITEM_TYPE_GTP: 13905 if (gtp_psc < 0) { 13906 size = sizeof(struct rte_gtp_hdr); 13907 break; 13908 } 13909 if (gtp_psc != i + 1) { 13910 fprintf(stderr, 13911 "Error - GTP PSC does not follow GTP\n"); 13912 goto error; 13913 } 13914 gtp = item->spec; 13915 if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { 13916 /* Only E flag should be set. */ 13917 fprintf(stderr, 13918 "Error - GTP unsupported flags\n"); 13919 goto error; 13920 } else { 13921 struct rte_gtp_hdr_ext_word ext_word = { 13922 .next_ext = 0x85 13923 }; 13924 13925 /* We have to add GTP header extra word. */ 13926 *total_size += sizeof(ext_word); 13927 rte_memcpy(data_tail - (*total_size), 13928 &ext_word, sizeof(ext_word)); 13929 } 13930 size = sizeof(struct rte_gtp_hdr); 13931 break; 13932 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13933 if (gtp_psc >= 0) { 13934 fprintf(stderr, 13935 "Error - Multiple GTP PSC items\n"); 13936 goto error; 13937 } else { 13938 const struct rte_flow_item_gtp_psc 13939 *opt = item->spec; 13940 struct rte_gtp_psc_generic_hdr *hdr; 13941 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 13942 sizeof(int32_t)); 13943 13944 *total_size += hdr_size; 13945 hdr = (typeof(hdr))(data_tail - (*total_size)); 13946 memset(hdr, 0, hdr_size); 13947 *hdr = opt->hdr; 13948 hdr->ext_hdr_len = 1; 13949 gtp_psc = i; 13950 size = 0; 13951 } 13952 break; 13953 case RTE_FLOW_ITEM_TYPE_PFCP: 13954 size = sizeof(struct rte_flow_item_pfcp); 13955 break; 13956 case RTE_FLOW_ITEM_TYPE_FLEX: 13957 if (item->spec != NULL) { 13958 size = ((const struct rte_flow_item_flex *)item->spec)->length; 13959 src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; 13960 } else { 13961 size = 0; 13962 src_spec = NULL; 13963 } 13964 break; 13965 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 13966 size = 0; 13967 if (item->spec) { 13968 const struct rte_flow_item_gre_opt 13969 *opt = item->spec; 13970 if (opt->checksum_rsvd.checksum) { 13971 *total_size += 13972 sizeof(opt->checksum_rsvd); 13973 rte_memcpy(data_tail - (*total_size), 13974 &opt->checksum_rsvd, 13975 sizeof(opt->checksum_rsvd)); 13976 } 13977 if (opt->key.key) { 13978 *total_size += sizeof(opt->key.key); 13979 rte_memcpy(data_tail - (*total_size), 13980 &opt->key.key, 13981 sizeof(opt->key.key)); 13982 } 13983 if (opt->sequence.sequence) { 13984 *total_size += sizeof(opt->sequence.sequence); 13985 rte_memcpy(data_tail - (*total_size), 13986 &opt->sequence.sequence, 13987 sizeof(opt->sequence.sequence)); 13988 } 13989 } 13990 proto = 0x2F; 13991 break; 13992 default: 13993 fprintf(stderr, "Error - Not supported item\n"); 13994 goto error; 13995 } 13996 if (size) { 13997 *total_size += size; 13998 rte_memcpy(data_tail - (*total_size), src_spec, size); 13999 /* update some fields which cannot be set by cmdline */ 14000 update_fields((data_tail - (*total_size)), item, 14001 upper_layer); 14002 upper_layer = proto; 14003 } 14004 } 14005 if (verbose_level & 0x1) 14006 printf("total data size is %zu\n", (*total_size)); 14007 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 14008 memmove(data, (data_tail - (*total_size)), *total_size); 14009 return; 14010 14011 error: 14012 *total_size = 0; 14013 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 14014 } 14015 14016 /** Populate help strings for current token (cmdline API). */ 14017 static int 14018 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 14019 unsigned int size) 14020 { 14021 struct context *ctx = &cmd_flow_context; 14022 const struct token *token = &token_list[ctx->prev]; 14023 14024 (void)hdr; 14025 if (!size) 14026 return -1; 14027 /* Set token type and update global help with details. */ 14028 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 14029 if (token->help) 14030 cmd_set_raw.help_str = token->help; 14031 else 14032 cmd_set_raw.help_str = token->name; 14033 return 0; 14034 } 14035 14036 /** Token definition template (cmdline API). */ 14037 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 14038 .ops = &(struct cmdline_token_ops){ 14039 .parse = cmd_flow_parse, 14040 .complete_get_nb = cmd_flow_complete_get_nb, 14041 .complete_get_elt = cmd_flow_complete_get_elt, 14042 .get_help = cmd_set_raw_get_help, 14043 }, 14044 .offset = 0, 14045 }; 14046 14047 /** Populate the next dynamic token. */ 14048 static void 14049 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 14050 cmdline_parse_token_hdr_t **hdr_inst) 14051 { 14052 struct context *ctx = &cmd_flow_context; 14053 14054 /* Always reinitialize context before requesting the first token. */ 14055 if (!(hdr_inst - cmd_set_raw.tokens)) { 14056 cmd_flow_context_init(ctx); 14057 ctx->curr = START_SET; 14058 } 14059 /* Return NULL when no more tokens are expected. */ 14060 if (!ctx->next_num && (ctx->curr != START_SET)) { 14061 *hdr = NULL; 14062 return; 14063 } 14064 /* Determine if command should end here. */ 14065 if (ctx->eol && ctx->last && ctx->next_num) { 14066 const enum index *list = ctx->next[ctx->next_num - 1]; 14067 int i; 14068 14069 for (i = 0; list[i]; ++i) { 14070 if (list[i] != END) 14071 continue; 14072 *hdr = NULL; 14073 return; 14074 } 14075 } 14076 *hdr = &cmd_set_raw_token_hdr; 14077 } 14078 14079 /** Token generator and output processing callback (cmdline API). */ 14080 static void 14081 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 14082 { 14083 if (cl == NULL) 14084 cmd_set_raw_tok(arg0, arg2); 14085 else 14086 cmd_set_raw_parsed(arg0); 14087 } 14088 14089 /** Global parser instance (cmdline API). */ 14090 cmdline_parse_inst_t cmd_set_raw = { 14091 .f = cmd_set_raw_cb, 14092 .data = NULL, /**< Unused. */ 14093 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 14094 .tokens = { 14095 NULL, 14096 }, /**< Tokens are returned by cmd_flow_tok(). */ 14097 }; 14098 14099 /* *** display raw_encap/raw_decap buf */ 14100 struct cmd_show_set_raw_result { 14101 cmdline_fixed_string_t cmd_show; 14102 cmdline_fixed_string_t cmd_what; 14103 cmdline_fixed_string_t cmd_all; 14104 uint16_t cmd_index; 14105 }; 14106 14107 static void 14108 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 14109 { 14110 struct cmd_show_set_raw_result *res = parsed_result; 14111 uint16_t index = res->cmd_index; 14112 uint8_t all = 0; 14113 uint8_t *raw_data = NULL; 14114 size_t raw_size = 0; 14115 char title[16] = {0}; 14116 14117 RTE_SET_USED(cl); 14118 RTE_SET_USED(data); 14119 if (!strcmp(res->cmd_all, "all")) { 14120 all = 1; 14121 index = 0; 14122 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 14123 fprintf(stderr, "index should be 0-%u\n", 14124 RAW_ENCAP_CONFS_MAX_NUM - 1); 14125 return; 14126 } 14127 do { 14128 if (!strcmp(res->cmd_what, "raw_encap")) { 14129 raw_data = (uint8_t *)&raw_encap_confs[index].data; 14130 raw_size = raw_encap_confs[index].size; 14131 snprintf(title, 16, "\nindex: %u", index); 14132 rte_hexdump(stdout, title, raw_data, raw_size); 14133 } else { 14134 raw_data = (uint8_t *)&raw_decap_confs[index].data; 14135 raw_size = raw_decap_confs[index].size; 14136 snprintf(title, 16, "\nindex: %u", index); 14137 rte_hexdump(stdout, title, raw_data, raw_size); 14138 } 14139 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 14140 } 14141 14142 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 14143 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14144 cmd_show, "show"); 14145 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 14146 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14147 cmd_what, "raw_encap#raw_decap"); 14148 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 14149 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 14150 cmd_index, RTE_UINT16); 14151 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 14152 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14153 cmd_all, "all"); 14154 cmdline_parse_inst_t cmd_show_set_raw = { 14155 .f = cmd_show_set_raw_parsed, 14156 .data = NULL, 14157 .help_str = "show <raw_encap|raw_decap> <index>", 14158 .tokens = { 14159 (void *)&cmd_show_set_raw_cmd_show, 14160 (void *)&cmd_show_set_raw_cmd_what, 14161 (void *)&cmd_show_set_raw_cmd_index, 14162 NULL, 14163 }, 14164 }; 14165 cmdline_parse_inst_t cmd_show_set_raw_all = { 14166 .f = cmd_show_set_raw_parsed, 14167 .data = NULL, 14168 .help_str = "show <raw_encap|raw_decap> all", 14169 .tokens = { 14170 (void *)&cmd_show_set_raw_cmd_show, 14171 (void *)&cmd_show_set_raw_cmd_what, 14172 (void *)&cmd_show_set_raw_cmd_all, 14173 NULL, 14174 }, 14175 }; 14176