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_FLAG_G, 386 ITEM_VXLAN_FLAG_VER, 387 ITEM_VXLAN_FLAG_I, 388 ITEM_VXLAN_FLAG_P, 389 ITEM_VXLAN_FLAG_B, 390 ITEM_VXLAN_FLAG_O, 391 ITEM_VXLAN_FLAG_D, 392 ITEM_VXLAN_FLAG_A, 393 ITEM_VXLAN_GBP_ID, 394 /* Used for "struct rte_vxlan_hdr", GPE Next protocol */ 395 ITEM_VXLAN_GPE_PROTO, 396 ITEM_VXLAN_FIRST_RSVD, 397 ITEM_VXLAN_SECND_RSVD, 398 ITEM_VXLAN_THIRD_RSVD, 399 ITEM_VXLAN_LAST_RSVD, 400 ITEM_E_TAG, 401 ITEM_E_TAG_GRP_ECID_B, 402 ITEM_NVGRE, 403 ITEM_NVGRE_TNI, 404 ITEM_MPLS, 405 ITEM_MPLS_LABEL, 406 ITEM_MPLS_TC, 407 ITEM_MPLS_S, 408 ITEM_MPLS_TTL, 409 ITEM_GRE, 410 ITEM_GRE_PROTO, 411 ITEM_GRE_C_RSVD0_VER, 412 ITEM_GRE_C_BIT, 413 ITEM_GRE_K_BIT, 414 ITEM_GRE_S_BIT, 415 ITEM_FUZZY, 416 ITEM_FUZZY_THRESH, 417 ITEM_GTP, 418 ITEM_GTP_FLAGS, 419 ITEM_GTP_MSG_TYPE, 420 ITEM_GTP_TEID, 421 ITEM_GTPC, 422 ITEM_GTPU, 423 ITEM_GENEVE, 424 ITEM_GENEVE_VNI, 425 ITEM_GENEVE_PROTO, 426 ITEM_GENEVE_OPTLEN, 427 ITEM_VXLAN_GPE, 428 ITEM_VXLAN_GPE_VNI, 429 /* Used for "struct rte_vxlan_gpe_hdr", deprecated, prefer ITEM_VXLAN_GPE_PROTO */ 430 ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR, 431 ITEM_VXLAN_GPE_FLAGS, 432 ITEM_VXLAN_GPE_RSVD0, 433 ITEM_VXLAN_GPE_RSVD1, 434 ITEM_ARP_ETH_IPV4, 435 ITEM_ARP_ETH_IPV4_SHA, 436 ITEM_ARP_ETH_IPV4_SPA, 437 ITEM_ARP_ETH_IPV4_THA, 438 ITEM_ARP_ETH_IPV4_TPA, 439 ITEM_IPV6_EXT, 440 ITEM_IPV6_EXT_NEXT_HDR, 441 ITEM_IPV6_FRAG_EXT, 442 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 443 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 444 ITEM_IPV6_FRAG_EXT_ID, 445 ITEM_ICMP6, 446 ITEM_ICMP6_TYPE, 447 ITEM_ICMP6_CODE, 448 ITEM_ICMP6_ECHO_REQUEST, 449 ITEM_ICMP6_ECHO_REQUEST_ID, 450 ITEM_ICMP6_ECHO_REQUEST_SEQ, 451 ITEM_ICMP6_ECHO_REPLY, 452 ITEM_ICMP6_ECHO_REPLY_ID, 453 ITEM_ICMP6_ECHO_REPLY_SEQ, 454 ITEM_ICMP6_ND_NS, 455 ITEM_ICMP6_ND_NS_TARGET_ADDR, 456 ITEM_ICMP6_ND_NA, 457 ITEM_ICMP6_ND_NA_TARGET_ADDR, 458 ITEM_ICMP6_ND_OPT, 459 ITEM_ICMP6_ND_OPT_TYPE, 460 ITEM_ICMP6_ND_OPT_SLA_ETH, 461 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 462 ITEM_ICMP6_ND_OPT_TLA_ETH, 463 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 464 ITEM_META, 465 ITEM_META_DATA, 466 ITEM_RANDOM, 467 ITEM_RANDOM_VALUE, 468 ITEM_GRE_KEY, 469 ITEM_GRE_KEY_VALUE, 470 ITEM_GRE_OPTION, 471 ITEM_GRE_OPTION_CHECKSUM, 472 ITEM_GRE_OPTION_KEY, 473 ITEM_GRE_OPTION_SEQUENCE, 474 ITEM_GTP_PSC, 475 ITEM_GTP_PSC_QFI, 476 ITEM_GTP_PSC_PDU_T, 477 ITEM_PPPOES, 478 ITEM_PPPOED, 479 ITEM_PPPOE_SEID, 480 ITEM_PPPOE_PROTO_ID, 481 ITEM_HIGIG2, 482 ITEM_HIGIG2_CLASSIFICATION, 483 ITEM_HIGIG2_VID, 484 ITEM_TAG, 485 ITEM_TAG_DATA, 486 ITEM_TAG_INDEX, 487 ITEM_L2TPV3OIP, 488 ITEM_L2TPV3OIP_SESSION_ID, 489 ITEM_ESP, 490 ITEM_ESP_SPI, 491 ITEM_AH, 492 ITEM_AH_SPI, 493 ITEM_PFCP, 494 ITEM_PFCP_S_FIELD, 495 ITEM_PFCP_SEID, 496 ITEM_ECPRI, 497 ITEM_ECPRI_COMMON, 498 ITEM_ECPRI_COMMON_TYPE, 499 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 500 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 501 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 502 ITEM_ECPRI_MSG_IQ_DATA_PCID, 503 ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 504 ITEM_ECPRI_MSG_DLY_MSR_MSRID, 505 ITEM_GENEVE_OPT, 506 ITEM_GENEVE_OPT_CLASS, 507 ITEM_GENEVE_OPT_TYPE, 508 ITEM_GENEVE_OPT_LENGTH, 509 ITEM_GENEVE_OPT_DATA, 510 ITEM_INTEGRITY, 511 ITEM_INTEGRITY_LEVEL, 512 ITEM_INTEGRITY_VALUE, 513 ITEM_CONNTRACK, 514 ITEM_POL_PORT, 515 ITEM_POL_METER, 516 ITEM_POL_POLICY, 517 ITEM_PORT_REPRESENTOR, 518 ITEM_PORT_REPRESENTOR_PORT_ID, 519 ITEM_REPRESENTED_PORT, 520 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 521 ITEM_FLEX, 522 ITEM_FLEX_ITEM_HANDLE, 523 ITEM_FLEX_PATTERN_HANDLE, 524 ITEM_L2TPV2, 525 ITEM_L2TPV2_TYPE, 526 ITEM_L2TPV2_TYPE_DATA, 527 ITEM_L2TPV2_TYPE_DATA_L, 528 ITEM_L2TPV2_TYPE_DATA_S, 529 ITEM_L2TPV2_TYPE_DATA_O, 530 ITEM_L2TPV2_TYPE_DATA_L_S, 531 ITEM_L2TPV2_TYPE_CTRL, 532 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 533 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 534 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 535 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 536 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 537 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 538 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 539 ITEM_L2TPV2_MSG_DATA_S_NS, 540 ITEM_L2TPV2_MSG_DATA_S_NR, 541 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 542 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 543 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 544 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 545 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 546 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 547 ITEM_L2TPV2_MSG_DATA_L_S_NS, 548 ITEM_L2TPV2_MSG_DATA_L_S_NR, 549 ITEM_L2TPV2_MSG_CTRL_LENGTH, 550 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 551 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 552 ITEM_L2TPV2_MSG_CTRL_NS, 553 ITEM_L2TPV2_MSG_CTRL_NR, 554 ITEM_PPP, 555 ITEM_PPP_ADDR, 556 ITEM_PPP_CTRL, 557 ITEM_PPP_PROTO_ID, 558 ITEM_METER, 559 ITEM_METER_COLOR, 560 ITEM_METER_COLOR_NAME, 561 ITEM_QUOTA, 562 ITEM_QUOTA_STATE, 563 ITEM_QUOTA_STATE_NAME, 564 ITEM_AGGR_AFFINITY, 565 ITEM_AGGR_AFFINITY_VALUE, 566 ITEM_TX_QUEUE, 567 ITEM_TX_QUEUE_VALUE, 568 ITEM_IB_BTH, 569 ITEM_IB_BTH_OPCODE, 570 ITEM_IB_BTH_PKEY, 571 ITEM_IB_BTH_DST_QPN, 572 ITEM_IB_BTH_PSN, 573 ITEM_IPV6_PUSH_REMOVE_EXT, 574 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 575 ITEM_PTYPE, 576 ITEM_PTYPE_VALUE, 577 ITEM_NSH, 578 ITEM_COMPARE, 579 ITEM_COMPARE_OP, 580 ITEM_COMPARE_OP_VALUE, 581 ITEM_COMPARE_FIELD_A_TYPE, 582 ITEM_COMPARE_FIELD_A_TYPE_VALUE, 583 ITEM_COMPARE_FIELD_A_LEVEL, 584 ITEM_COMPARE_FIELD_A_LEVEL_VALUE, 585 ITEM_COMPARE_FIELD_A_TAG_INDEX, 586 ITEM_COMPARE_FIELD_A_TYPE_ID, 587 ITEM_COMPARE_FIELD_A_CLASS_ID, 588 ITEM_COMPARE_FIELD_A_OFFSET, 589 ITEM_COMPARE_FIELD_B_TYPE, 590 ITEM_COMPARE_FIELD_B_TYPE_VALUE, 591 ITEM_COMPARE_FIELD_B_LEVEL, 592 ITEM_COMPARE_FIELD_B_LEVEL_VALUE, 593 ITEM_COMPARE_FIELD_B_TAG_INDEX, 594 ITEM_COMPARE_FIELD_B_TYPE_ID, 595 ITEM_COMPARE_FIELD_B_CLASS_ID, 596 ITEM_COMPARE_FIELD_B_OFFSET, 597 ITEM_COMPARE_FIELD_B_VALUE, 598 ITEM_COMPARE_FIELD_B_POINTER, 599 ITEM_COMPARE_FIELD_WIDTH, 600 601 /* Validate/create actions. */ 602 ACTIONS, 603 ACTION_NEXT, 604 ACTION_END, 605 ACTION_VOID, 606 ACTION_PASSTHRU, 607 ACTION_SKIP_CMAN, 608 ACTION_JUMP, 609 ACTION_JUMP_GROUP, 610 ACTION_MARK, 611 ACTION_MARK_ID, 612 ACTION_FLAG, 613 ACTION_QUEUE, 614 ACTION_QUEUE_INDEX, 615 ACTION_DROP, 616 ACTION_COUNT, 617 ACTION_COUNT_ID, 618 ACTION_RSS, 619 ACTION_RSS_FUNC, 620 ACTION_RSS_LEVEL, 621 ACTION_RSS_FUNC_DEFAULT, 622 ACTION_RSS_FUNC_TOEPLITZ, 623 ACTION_RSS_FUNC_SIMPLE_XOR, 624 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, 625 ACTION_RSS_TYPES, 626 ACTION_RSS_TYPE, 627 ACTION_RSS_KEY, 628 ACTION_RSS_KEY_LEN, 629 ACTION_RSS_QUEUES, 630 ACTION_RSS_QUEUE, 631 ACTION_PF, 632 ACTION_VF, 633 ACTION_VF_ORIGINAL, 634 ACTION_VF_ID, 635 ACTION_PORT_ID, 636 ACTION_PORT_ID_ORIGINAL, 637 ACTION_PORT_ID_ID, 638 ACTION_METER, 639 ACTION_METER_COLOR, 640 ACTION_METER_COLOR_TYPE, 641 ACTION_METER_COLOR_GREEN, 642 ACTION_METER_COLOR_YELLOW, 643 ACTION_METER_COLOR_RED, 644 ACTION_METER_ID, 645 ACTION_METER_MARK, 646 ACTION_METER_PROFILE, 647 ACTION_METER_PROFILE_ID2PTR, 648 ACTION_METER_POLICY, 649 ACTION_METER_POLICY_ID2PTR, 650 ACTION_METER_COLOR_MODE, 651 ACTION_METER_STATE, 652 ACTION_OF_DEC_NW_TTL, 653 ACTION_OF_POP_VLAN, 654 ACTION_OF_PUSH_VLAN, 655 ACTION_OF_PUSH_VLAN_ETHERTYPE, 656 ACTION_OF_SET_VLAN_VID, 657 ACTION_OF_SET_VLAN_VID_VLAN_VID, 658 ACTION_OF_SET_VLAN_PCP, 659 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 660 ACTION_OF_POP_MPLS, 661 ACTION_OF_POP_MPLS_ETHERTYPE, 662 ACTION_OF_PUSH_MPLS, 663 ACTION_OF_PUSH_MPLS_ETHERTYPE, 664 ACTION_VXLAN_ENCAP, 665 ACTION_VXLAN_DECAP, 666 ACTION_NVGRE_ENCAP, 667 ACTION_NVGRE_DECAP, 668 ACTION_L2_ENCAP, 669 ACTION_L2_DECAP, 670 ACTION_MPLSOGRE_ENCAP, 671 ACTION_MPLSOGRE_DECAP, 672 ACTION_MPLSOUDP_ENCAP, 673 ACTION_MPLSOUDP_DECAP, 674 ACTION_SET_IPV4_SRC, 675 ACTION_SET_IPV4_SRC_IPV4_SRC, 676 ACTION_SET_IPV4_DST, 677 ACTION_SET_IPV4_DST_IPV4_DST, 678 ACTION_SET_IPV6_SRC, 679 ACTION_SET_IPV6_SRC_IPV6_SRC, 680 ACTION_SET_IPV6_DST, 681 ACTION_SET_IPV6_DST_IPV6_DST, 682 ACTION_SET_TP_SRC, 683 ACTION_SET_TP_SRC_TP_SRC, 684 ACTION_SET_TP_DST, 685 ACTION_SET_TP_DST_TP_DST, 686 ACTION_MAC_SWAP, 687 ACTION_DEC_TTL, 688 ACTION_SET_TTL, 689 ACTION_SET_TTL_TTL, 690 ACTION_SET_MAC_SRC, 691 ACTION_SET_MAC_SRC_MAC_SRC, 692 ACTION_SET_MAC_DST, 693 ACTION_SET_MAC_DST_MAC_DST, 694 ACTION_INC_TCP_SEQ, 695 ACTION_INC_TCP_SEQ_VALUE, 696 ACTION_DEC_TCP_SEQ, 697 ACTION_DEC_TCP_SEQ_VALUE, 698 ACTION_INC_TCP_ACK, 699 ACTION_INC_TCP_ACK_VALUE, 700 ACTION_DEC_TCP_ACK, 701 ACTION_DEC_TCP_ACK_VALUE, 702 ACTION_RAW_ENCAP, 703 ACTION_RAW_DECAP, 704 ACTION_RAW_ENCAP_SIZE, 705 ACTION_RAW_ENCAP_INDEX, 706 ACTION_RAW_ENCAP_INDEX_VALUE, 707 ACTION_RAW_DECAP_INDEX, 708 ACTION_RAW_DECAP_INDEX_VALUE, 709 ACTION_SET_TAG, 710 ACTION_SET_TAG_DATA, 711 ACTION_SET_TAG_INDEX, 712 ACTION_SET_TAG_MASK, 713 ACTION_SET_META, 714 ACTION_SET_META_DATA, 715 ACTION_SET_META_MASK, 716 ACTION_SET_IPV4_DSCP, 717 ACTION_SET_IPV4_DSCP_VALUE, 718 ACTION_SET_IPV6_DSCP, 719 ACTION_SET_IPV6_DSCP_VALUE, 720 ACTION_AGE, 721 ACTION_AGE_TIMEOUT, 722 ACTION_AGE_UPDATE, 723 ACTION_AGE_UPDATE_TIMEOUT, 724 ACTION_AGE_UPDATE_TOUCH, 725 ACTION_SAMPLE, 726 ACTION_SAMPLE_RATIO, 727 ACTION_SAMPLE_INDEX, 728 ACTION_SAMPLE_INDEX_VALUE, 729 ACTION_INDIRECT, 730 ACTION_INDIRECT_LIST, 731 ACTION_INDIRECT_LIST_HANDLE, 732 ACTION_INDIRECT_LIST_CONF, 733 INDIRECT_LIST_ACTION_ID2PTR_HANDLE, 734 INDIRECT_LIST_ACTION_ID2PTR_CONF, 735 ACTION_SHARED_INDIRECT, 736 INDIRECT_ACTION_PORT, 737 INDIRECT_ACTION_ID2PTR, 738 ACTION_MODIFY_FIELD, 739 ACTION_MODIFY_FIELD_OP, 740 ACTION_MODIFY_FIELD_OP_VALUE, 741 ACTION_MODIFY_FIELD_DST_TYPE, 742 ACTION_MODIFY_FIELD_DST_TYPE_VALUE, 743 ACTION_MODIFY_FIELD_DST_LEVEL, 744 ACTION_MODIFY_FIELD_DST_LEVEL_VALUE, 745 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 746 ACTION_MODIFY_FIELD_DST_TYPE_ID, 747 ACTION_MODIFY_FIELD_DST_CLASS_ID, 748 ACTION_MODIFY_FIELD_DST_OFFSET, 749 ACTION_MODIFY_FIELD_SRC_TYPE, 750 ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, 751 ACTION_MODIFY_FIELD_SRC_LEVEL, 752 ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE, 753 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 754 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 755 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 756 ACTION_MODIFY_FIELD_SRC_OFFSET, 757 ACTION_MODIFY_FIELD_SRC_VALUE, 758 ACTION_MODIFY_FIELD_SRC_POINTER, 759 ACTION_MODIFY_FIELD_WIDTH, 760 ACTION_CONNTRACK, 761 ACTION_CONNTRACK_UPDATE, 762 ACTION_CONNTRACK_UPDATE_DIR, 763 ACTION_CONNTRACK_UPDATE_CTX, 764 ACTION_POL_G, 765 ACTION_POL_Y, 766 ACTION_POL_R, 767 ACTION_PORT_REPRESENTOR, 768 ACTION_PORT_REPRESENTOR_PORT_ID, 769 ACTION_REPRESENTED_PORT, 770 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 771 ACTION_SEND_TO_KERNEL, 772 ACTION_QUOTA_CREATE, 773 ACTION_QUOTA_CREATE_LIMIT, 774 ACTION_QUOTA_CREATE_MODE, 775 ACTION_QUOTA_CREATE_MODE_NAME, 776 ACTION_QUOTA_QU, 777 ACTION_QUOTA_QU_LIMIT, 778 ACTION_QUOTA_QU_UPDATE_OP, 779 ACTION_QUOTA_QU_UPDATE_OP_NAME, 780 ACTION_IPV6_EXT_REMOVE, 781 ACTION_IPV6_EXT_REMOVE_INDEX, 782 ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, 783 ACTION_IPV6_EXT_PUSH, 784 ACTION_IPV6_EXT_PUSH_INDEX, 785 ACTION_IPV6_EXT_PUSH_INDEX_VALUE, 786 ACTION_NAT64, 787 ACTION_NAT64_MODE, 788 ACTION_JUMP_TO_TABLE_INDEX, 789 ACTION_JUMP_TO_TABLE_INDEX_TABLE, 790 ACTION_JUMP_TO_TABLE_INDEX_INDEX, 791 }; 792 793 /** Maximum size for pattern in struct rte_flow_item_raw. */ 794 #define ITEM_RAW_PATTERN_SIZE 512 795 796 /** Maximum size for GENEVE option data pattern in bytes. */ 797 #define ITEM_GENEVE_OPT_DATA_SIZE 124 798 799 /** Storage size for struct rte_flow_item_raw including pattern. */ 800 #define ITEM_RAW_SIZE \ 801 (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) 802 803 static const char *const compare_ops[] = { 804 "eq", "ne", "lt", "le", "gt", "ge", NULL 805 }; 806 807 /** Maximum size for external pattern in struct rte_flow_field_data. */ 808 #define FLOW_FIELD_PATTERN_SIZE 32 809 810 /** Storage size for struct rte_flow_action_modify_field including pattern. */ 811 #define ACTION_MODIFY_SIZE \ 812 (sizeof(struct rte_flow_action_modify_field) + \ 813 FLOW_FIELD_PATTERN_SIZE) 814 815 /** Maximum number of queue indices in struct rte_flow_action_rss. */ 816 #define ACTION_RSS_QUEUE_NUM 128 817 818 /** Storage for struct rte_flow_action_rss including external data. */ 819 struct action_rss_data { 820 struct rte_flow_action_rss conf; 821 uint8_t key[RSS_HASH_KEY_LENGTH]; 822 uint16_t queue[ACTION_RSS_QUEUE_NUM]; 823 }; 824 825 /** Maximum data size in struct rte_flow_action_raw_encap. */ 826 #define ACTION_RAW_ENCAP_MAX_DATA 512 827 #define RAW_ENCAP_CONFS_MAX_NUM 8 828 829 /** Storage for struct rte_flow_action_raw_encap. */ 830 struct raw_encap_conf { 831 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 832 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 833 size_t size; 834 }; 835 836 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 837 838 /** Storage for struct rte_flow_action_raw_encap including external data. */ 839 struct action_raw_encap_data { 840 struct rte_flow_action_raw_encap conf; 841 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 842 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 843 uint16_t idx; 844 }; 845 846 /** Storage for struct rte_flow_action_raw_decap. */ 847 struct raw_decap_conf { 848 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 849 size_t size; 850 }; 851 852 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 853 854 /** Storage for struct rte_flow_action_raw_decap including external data. */ 855 struct action_raw_decap_data { 856 struct rte_flow_action_raw_decap conf; 857 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 858 uint16_t idx; 859 }; 860 861 /** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ 862 #define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 863 #define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 864 865 /** Storage for struct rte_flow_action_ipv6_ext_push. */ 866 struct ipv6_ext_push_conf { 867 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 868 size_t size; 869 uint8_t type; 870 }; 871 872 struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 873 874 /** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ 875 struct action_ipv6_ext_push_data { 876 struct rte_flow_action_ipv6_ext_push conf; 877 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 878 uint8_t type; 879 uint16_t idx; 880 }; 881 882 /** Storage for struct rte_flow_action_ipv6_ext_remove. */ 883 struct ipv6_ext_remove_conf { 884 struct rte_flow_action_ipv6_ext_remove conf; 885 uint8_t type; 886 }; 887 888 struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 889 890 /** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ 891 struct action_ipv6_ext_remove_data { 892 struct rte_flow_action_ipv6_ext_remove conf; 893 uint8_t type; 894 uint16_t idx; 895 }; 896 897 struct vxlan_encap_conf vxlan_encap_conf = { 898 .select_ipv4 = 1, 899 .select_vlan = 0, 900 .select_tos_ttl = 0, 901 .vni = { 0x00, 0x00, 0x00 }, 902 .udp_src = 0, 903 .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), 904 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 905 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 906 .ipv6_src = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 907 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, 908 .ipv6_dst = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 909 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11 }, 910 .vlan_tci = 0, 911 .ip_tos = 0, 912 .ip_ttl = 255, 913 .eth_src = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 914 .eth_dst = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 915 }; 916 917 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */ 918 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6 919 920 /** Storage for struct rte_flow_action_vxlan_encap including external data. */ 921 struct action_vxlan_encap_data { 922 struct rte_flow_action_vxlan_encap conf; 923 struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; 924 struct rte_flow_item_eth item_eth; 925 struct rte_flow_item_vlan item_vlan; 926 union { 927 struct rte_flow_item_ipv4 item_ipv4; 928 struct rte_flow_item_ipv6 item_ipv6; 929 }; 930 struct rte_flow_item_udp item_udp; 931 struct rte_flow_item_vxlan item_vxlan; 932 }; 933 934 struct nvgre_encap_conf nvgre_encap_conf = { 935 .select_ipv4 = 1, 936 .select_vlan = 0, 937 .tni = { 0x00, 0x00, 0x00 }, 938 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 939 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 940 .ipv6_src = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 941 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, 942 .ipv6_dst = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 943 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11 }, 944 .vlan_tci = 0, 945 .eth_src = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 946 .eth_dst = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 947 }; 948 949 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */ 950 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 951 952 /** Storage for struct rte_flow_action_nvgre_encap including external data. */ 953 struct action_nvgre_encap_data { 954 struct rte_flow_action_nvgre_encap conf; 955 struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; 956 struct rte_flow_item_eth item_eth; 957 struct rte_flow_item_vlan item_vlan; 958 union { 959 struct rte_flow_item_ipv4 item_ipv4; 960 struct rte_flow_item_ipv6 item_ipv6; 961 }; 962 struct rte_flow_item_nvgre item_nvgre; 963 }; 964 965 struct l2_encap_conf l2_encap_conf; 966 967 struct l2_decap_conf l2_decap_conf; 968 969 struct mplsogre_encap_conf mplsogre_encap_conf; 970 971 struct mplsogre_decap_conf mplsogre_decap_conf; 972 973 struct mplsoudp_encap_conf mplsoudp_encap_conf; 974 975 struct mplsoudp_decap_conf mplsoudp_decap_conf; 976 977 struct rte_flow_action_conntrack conntrack_context; 978 979 #define ACTION_SAMPLE_ACTIONS_NUM 10 980 #define RAW_SAMPLE_CONFS_MAX_NUM 8 981 /** Storage for struct rte_flow_action_sample including external data. */ 982 struct action_sample_data { 983 struct rte_flow_action_sample conf; 984 uint32_t idx; 985 }; 986 /** Storage for struct rte_flow_action_sample. */ 987 struct raw_sample_conf { 988 struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; 989 }; 990 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; 991 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; 992 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; 993 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; 994 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; 995 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 996 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 997 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 998 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; 999 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; 1000 struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; 1001 struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; 1002 1003 static const char *const modify_field_ops[] = { 1004 "set", "add", "sub", NULL 1005 }; 1006 1007 static const char *const flow_field_ids[] = { 1008 "start", "mac_dst", "mac_src", 1009 "vlan_type", "vlan_id", "mac_type", 1010 "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", 1011 "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", 1012 "tcp_port_src", "tcp_port_dst", 1013 "tcp_seq_num", "tcp_ack_num", "tcp_flags", 1014 "udp_port_src", "udp_port_dst", 1015 "vxlan_vni", "geneve_vni", "gtp_teid", 1016 "tag", "mark", "meta", "pointer", "value", 1017 "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", 1018 "ipv6_proto", 1019 "flex_item", 1020 "hash_result", 1021 "geneve_opt_type", "geneve_opt_class", "geneve_opt_data", "mpls", 1022 "tcp_data_off", "ipv4_ihl", "ipv4_total_len", "ipv6_payload_len", 1023 "ipv4_proto", 1024 "ipv6_flow_label", "ipv6_traffic_class", 1025 "esp_spi", "esp_seq_num", "esp_proto", 1026 "random", 1027 "vxlan_last_rsvd", 1028 NULL 1029 }; 1030 1031 static const char *const meter_colors[] = { 1032 "green", "yellow", "red", "all", NULL 1033 }; 1034 1035 static const char *const table_insertion_types[] = { 1036 "pattern", "index", "index_with_pattern", NULL 1037 }; 1038 1039 static const char *const table_hash_funcs[] = { 1040 "default", "linear", "crc32", "crc16", NULL 1041 }; 1042 1043 #define RAW_IPSEC_CONFS_MAX_NUM 8 1044 1045 /** Maximum number of subsequent tokens and arguments on the stack. */ 1046 #define CTX_STACK_SIZE 16 1047 1048 /** Parser context. */ 1049 struct context { 1050 /** Stack of subsequent token lists to process. */ 1051 const enum index *next[CTX_STACK_SIZE]; 1052 /** Arguments for stacked tokens. */ 1053 const void *args[CTX_STACK_SIZE]; 1054 enum index curr; /**< Current token index. */ 1055 enum index prev; /**< Index of the last token seen. */ 1056 int next_num; /**< Number of entries in next[]. */ 1057 int args_num; /**< Number of entries in args[]. */ 1058 uint32_t eol:1; /**< EOL has been detected. */ 1059 uint32_t last:1; /**< No more arguments. */ 1060 portid_t port; /**< Current port ID (for completions). */ 1061 uint32_t objdata; /**< Object-specific data. */ 1062 void *object; /**< Address of current object for relative offsets. */ 1063 void *objmask; /**< Object a full mask must be written to. */ 1064 }; 1065 1066 /** Token argument. */ 1067 struct arg { 1068 uint32_t hton:1; /**< Use network byte ordering. */ 1069 uint32_t sign:1; /**< Value is signed. */ 1070 uint32_t bounded:1; /**< Value is bounded. */ 1071 uintmax_t min; /**< Minimum value if bounded. */ 1072 uintmax_t max; /**< Maximum value if bounded. */ 1073 uint32_t offset; /**< Relative offset from ctx->object. */ 1074 uint32_t size; /**< Field size. */ 1075 const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ 1076 }; 1077 1078 /** Parser token definition. */ 1079 struct token { 1080 /** Type displayed during completion (defaults to "TOKEN"). */ 1081 const char *type; 1082 /** Help displayed during completion (defaults to token name). */ 1083 const char *help; 1084 /** Private data used by parser functions. */ 1085 const void *priv; 1086 /** 1087 * Lists of subsequent tokens to push on the stack. Each call to the 1088 * parser consumes the last entry of that stack. 1089 */ 1090 const enum index *const *next; 1091 /** Arguments stack for subsequent tokens that need them. */ 1092 const struct arg *const *args; 1093 /** 1094 * Token-processing callback, returns -1 in case of error, the 1095 * length of the matched string otherwise. If NULL, attempts to 1096 * match the token name. 1097 * 1098 * If buf is not NULL, the result should be stored in it according 1099 * to context. An error is returned if not large enough. 1100 */ 1101 int (*call)(struct context *ctx, const struct token *token, 1102 const char *str, unsigned int len, 1103 void *buf, unsigned int size); 1104 /** 1105 * Callback that provides possible values for this token, used for 1106 * completion. Returns -1 in case of error, the number of possible 1107 * values otherwise. If NULL, the token name is used. 1108 * 1109 * If buf is not NULL, entry index ent is written to buf and the 1110 * full length of the entry is returned (same behavior as 1111 * snprintf()). 1112 */ 1113 int (*comp)(struct context *ctx, const struct token *token, 1114 unsigned int ent, char *buf, unsigned int size); 1115 /** Mandatory token name, no default value. */ 1116 const char *name; 1117 }; 1118 1119 /** Static initializer for the next field. */ 1120 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } 1121 1122 /** Static initializer for a NEXT() entry. */ 1123 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } 1124 1125 /** Static initializer for the args field. */ 1126 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } 1127 1128 /** Static initializer for ARGS() to target a field. */ 1129 #define ARGS_ENTRY(s, f) \ 1130 (&(const struct arg){ \ 1131 .offset = offsetof(s, f), \ 1132 .size = sizeof(((s *)0)->f), \ 1133 }) 1134 1135 /** Static initializer for ARGS() to target a bit-field. */ 1136 #define ARGS_ENTRY_BF(s, f, b) \ 1137 (&(const struct arg){ \ 1138 .size = sizeof(s), \ 1139 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ 1140 }) 1141 1142 /** Static initializer for ARGS() to target a field with limits. */ 1143 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \ 1144 (&(const struct arg){ \ 1145 .bounded = 1, \ 1146 .min = (i), \ 1147 .max = (a), \ 1148 .offset = offsetof(s, f), \ 1149 .size = sizeof(((s *)0)->f), \ 1150 }) 1151 1152 /** Static initializer for ARGS() to target an arbitrary bit-mask. */ 1153 #define ARGS_ENTRY_MASK(s, f, m) \ 1154 (&(const struct arg){ \ 1155 .offset = offsetof(s, f), \ 1156 .size = sizeof(((s *)0)->f), \ 1157 .mask = (const void *)(m), \ 1158 }) 1159 1160 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ 1161 #define ARGS_ENTRY_MASK_HTON(s, f, m) \ 1162 (&(const struct arg){ \ 1163 .hton = 1, \ 1164 .offset = offsetof(s, f), \ 1165 .size = sizeof(((s *)0)->f), \ 1166 .mask = (const void *)(m), \ 1167 }) 1168 1169 /** Static initializer for ARGS() to target a pointer. */ 1170 #define ARGS_ENTRY_PTR(s, f) \ 1171 (&(const struct arg){ \ 1172 .size = sizeof(*((s *)0)->f), \ 1173 }) 1174 1175 /** Static initializer for ARGS() with arbitrary offset and size. */ 1176 #define ARGS_ENTRY_ARB(o, s) \ 1177 (&(const struct arg){ \ 1178 .offset = (o), \ 1179 .size = (s), \ 1180 }) 1181 1182 /** Same as ARGS_ENTRY_ARB() with bounded values. */ 1183 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ 1184 (&(const struct arg){ \ 1185 .bounded = 1, \ 1186 .min = (i), \ 1187 .max = (a), \ 1188 .offset = (o), \ 1189 .size = (s), \ 1190 }) 1191 1192 /** Same as ARGS_ENTRY() using network byte ordering. */ 1193 #define ARGS_ENTRY_HTON(s, f) \ 1194 (&(const struct arg){ \ 1195 .hton = 1, \ 1196 .offset = offsetof(s, f), \ 1197 .size = sizeof(((s *)0)->f), \ 1198 }) 1199 1200 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ 1201 #define ARG_ENTRY_HTON(s) \ 1202 (&(const struct arg){ \ 1203 .hton = 1, \ 1204 .offset = 0, \ 1205 .size = sizeof(s), \ 1206 }) 1207 1208 /** Parser output buffer layout expected by cmd_flow_parsed(). */ 1209 struct buffer { 1210 enum index command; /**< Flow command. */ 1211 portid_t port; /**< Affected port ID. */ 1212 queueid_t queue; /** Async queue ID. */ 1213 bool postpone; /** Postpone async operation */ 1214 union { 1215 struct { 1216 struct rte_flow_port_attr port_attr; 1217 uint32_t nb_queue; 1218 struct rte_flow_queue_attr queue_attr; 1219 } configure; /**< Configuration arguments. */ 1220 struct { 1221 uint32_t *template_id; 1222 uint32_t template_id_n; 1223 } templ_destroy; /**< Template destroy arguments. */ 1224 struct { 1225 uint32_t id; 1226 struct rte_flow_template_table_attr attr; 1227 uint32_t *pat_templ_id; 1228 uint32_t pat_templ_id_n; 1229 uint32_t *act_templ_id; 1230 uint32_t act_templ_id_n; 1231 } table; /**< Table arguments. */ 1232 struct { 1233 uint32_t *table_id; 1234 uint32_t table_id_n; 1235 } table_destroy; /**< Template destroy arguments. */ 1236 struct { 1237 uint32_t *action_id; 1238 uint32_t action_id_n; 1239 } ia_destroy; /**< Indirect action destroy arguments. */ 1240 struct { 1241 uint32_t action_id; 1242 enum rte_flow_query_update_mode qu_mode; 1243 } ia; /* Indirect action query arguments */ 1244 struct { 1245 uint32_t table_id; 1246 uint32_t pat_templ_id; 1247 uint32_t rule_id; 1248 uint32_t act_templ_id; 1249 struct rte_flow_attr attr; 1250 struct tunnel_ops tunnel_ops; 1251 uintptr_t user_id; 1252 struct rte_flow_item *pattern; 1253 struct rte_flow_action *actions; 1254 struct rte_flow_action *masks; 1255 uint32_t pattern_n; 1256 uint32_t actions_n; 1257 uint8_t *data; 1258 enum rte_flow_encap_hash_field field; 1259 uint8_t encap_hash; 1260 } vc; /**< Validate/create arguments. */ 1261 struct { 1262 uint64_t *rule; 1263 uint64_t rule_n; 1264 bool is_user_id; 1265 } destroy; /**< Destroy arguments. */ 1266 struct { 1267 char file[128]; 1268 bool mode; 1269 uint64_t rule; 1270 bool is_user_id; 1271 } dump; /**< Dump arguments. */ 1272 struct { 1273 uint64_t rule; 1274 struct rte_flow_action action; 1275 bool is_user_id; 1276 } query; /**< Query arguments. */ 1277 struct { 1278 uint32_t *group; 1279 uint32_t group_n; 1280 } list; /**< List arguments. */ 1281 struct { 1282 int set; 1283 } isolate; /**< Isolated mode arguments. */ 1284 struct { 1285 int destroy; 1286 } aged; /**< Aged arguments. */ 1287 struct { 1288 uint32_t policy_id; 1289 } policy;/**< Policy arguments. */ 1290 struct { 1291 uint16_t token; 1292 uintptr_t uintptr; 1293 char filename[128]; 1294 } flex; /**< Flex arguments*/ 1295 } args; /**< Command arguments. */ 1296 }; 1297 1298 /** Private data for pattern items. */ 1299 struct parse_item_priv { 1300 enum rte_flow_item_type type; /**< Item type. */ 1301 uint32_t size; /**< Size of item specification structure. */ 1302 }; 1303 1304 #define PRIV_ITEM(t, s) \ 1305 (&(const struct parse_item_priv){ \ 1306 .type = RTE_FLOW_ITEM_TYPE_ ## t, \ 1307 .size = s, \ 1308 }) 1309 1310 /** Private data for actions. */ 1311 struct parse_action_priv { 1312 enum rte_flow_action_type type; /**< Action type. */ 1313 uint32_t size; /**< Size of action configuration structure. */ 1314 }; 1315 1316 #define PRIV_ACTION(t, s) \ 1317 (&(const struct parse_action_priv){ \ 1318 .type = RTE_FLOW_ACTION_TYPE_ ## t, \ 1319 .size = s, \ 1320 }) 1321 1322 static const enum index next_flex_item[] = { 1323 FLEX_ITEM_INIT, 1324 FLEX_ITEM_CREATE, 1325 FLEX_ITEM_DESTROY, 1326 ZERO, 1327 }; 1328 1329 static const enum index next_config_attr[] = { 1330 CONFIG_QUEUES_NUMBER, 1331 CONFIG_QUEUES_SIZE, 1332 CONFIG_COUNTERS_NUMBER, 1333 CONFIG_AGING_OBJECTS_NUMBER, 1334 CONFIG_METERS_NUMBER, 1335 CONFIG_CONN_TRACK_NUMBER, 1336 CONFIG_QUOTAS_NUMBER, 1337 CONFIG_FLAGS, 1338 CONFIG_HOST_PORT, 1339 END, 1340 ZERO, 1341 }; 1342 1343 static const enum index next_pt_subcmd[] = { 1344 PATTERN_TEMPLATE_CREATE, 1345 PATTERN_TEMPLATE_DESTROY, 1346 ZERO, 1347 }; 1348 1349 static const enum index next_pt_attr[] = { 1350 PATTERN_TEMPLATE_CREATE_ID, 1351 PATTERN_TEMPLATE_RELAXED_MATCHING, 1352 PATTERN_TEMPLATE_INGRESS, 1353 PATTERN_TEMPLATE_EGRESS, 1354 PATTERN_TEMPLATE_TRANSFER, 1355 PATTERN_TEMPLATE_SPEC, 1356 ZERO, 1357 }; 1358 1359 static const enum index next_pt_destroy_attr[] = { 1360 PATTERN_TEMPLATE_DESTROY_ID, 1361 END, 1362 ZERO, 1363 }; 1364 1365 static const enum index next_at_subcmd[] = { 1366 ACTIONS_TEMPLATE_CREATE, 1367 ACTIONS_TEMPLATE_DESTROY, 1368 ZERO, 1369 }; 1370 1371 static const enum index next_at_attr[] = { 1372 ACTIONS_TEMPLATE_CREATE_ID, 1373 ACTIONS_TEMPLATE_INGRESS, 1374 ACTIONS_TEMPLATE_EGRESS, 1375 ACTIONS_TEMPLATE_TRANSFER, 1376 ACTIONS_TEMPLATE_SPEC, 1377 ZERO, 1378 }; 1379 1380 static const enum index next_at_destroy_attr[] = { 1381 ACTIONS_TEMPLATE_DESTROY_ID, 1382 END, 1383 ZERO, 1384 }; 1385 1386 static const enum index next_group_attr[] = { 1387 GROUP_INGRESS, 1388 GROUP_EGRESS, 1389 GROUP_TRANSFER, 1390 GROUP_SET_MISS_ACTIONS, 1391 ZERO, 1392 }; 1393 1394 static const enum index next_table_subcmd[] = { 1395 TABLE_CREATE, 1396 TABLE_DESTROY, 1397 TABLE_RESIZE, 1398 TABLE_RESIZE_COMPLETE, 1399 ZERO, 1400 }; 1401 1402 static const enum index next_table_attr[] = { 1403 TABLE_CREATE_ID, 1404 TABLE_GROUP, 1405 TABLE_INSERTION_TYPE, 1406 TABLE_HASH_FUNC, 1407 TABLE_PRIORITY, 1408 TABLE_INGRESS, 1409 TABLE_EGRESS, 1410 TABLE_TRANSFER, 1411 TABLE_TRANSFER_WIRE_ORIG, 1412 TABLE_TRANSFER_VPORT_ORIG, 1413 TABLE_RESIZABLE, 1414 TABLE_RULES_NUMBER, 1415 TABLE_PATTERN_TEMPLATE, 1416 TABLE_ACTIONS_TEMPLATE, 1417 END, 1418 ZERO, 1419 }; 1420 1421 static const enum index next_table_destroy_attr[] = { 1422 TABLE_DESTROY_ID, 1423 END, 1424 ZERO, 1425 }; 1426 1427 static const enum index next_queue_subcmd[] = { 1428 QUEUE_CREATE, 1429 QUEUE_DESTROY, 1430 QUEUE_FLOW_UPDATE_RESIZED, 1431 QUEUE_UPDATE, 1432 QUEUE_AGED, 1433 QUEUE_INDIRECT_ACTION, 1434 ZERO, 1435 }; 1436 1437 static const enum index next_queue_destroy_attr[] = { 1438 QUEUE_DESTROY_ID, 1439 END, 1440 ZERO, 1441 }; 1442 1443 static const enum index next_qia_subcmd[] = { 1444 QUEUE_INDIRECT_ACTION_CREATE, 1445 QUEUE_INDIRECT_ACTION_UPDATE, 1446 QUEUE_INDIRECT_ACTION_DESTROY, 1447 QUEUE_INDIRECT_ACTION_QUERY, 1448 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 1449 ZERO, 1450 }; 1451 1452 static const enum index next_qia_create_attr[] = { 1453 QUEUE_INDIRECT_ACTION_CREATE_ID, 1454 QUEUE_INDIRECT_ACTION_INGRESS, 1455 QUEUE_INDIRECT_ACTION_EGRESS, 1456 QUEUE_INDIRECT_ACTION_TRANSFER, 1457 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 1458 QUEUE_INDIRECT_ACTION_SPEC, 1459 QUEUE_INDIRECT_ACTION_LIST, 1460 ZERO, 1461 }; 1462 1463 static const enum index next_qia_update_attr[] = { 1464 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1465 QUEUE_INDIRECT_ACTION_SPEC, 1466 ZERO, 1467 }; 1468 1469 static const enum index next_qia_destroy_attr[] = { 1470 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 1471 QUEUE_INDIRECT_ACTION_DESTROY_ID, 1472 END, 1473 ZERO, 1474 }; 1475 1476 static const enum index next_qia_query_attr[] = { 1477 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 1478 END, 1479 ZERO, 1480 }; 1481 1482 static const enum index next_ia_create_attr[] = { 1483 INDIRECT_ACTION_CREATE_ID, 1484 INDIRECT_ACTION_INGRESS, 1485 INDIRECT_ACTION_EGRESS, 1486 INDIRECT_ACTION_TRANSFER, 1487 INDIRECT_ACTION_SPEC, 1488 INDIRECT_ACTION_LIST, 1489 INDIRECT_ACTION_FLOW_CONF, 1490 ZERO, 1491 }; 1492 1493 static const enum index next_ia[] = { 1494 INDIRECT_ACTION_ID2PTR, 1495 ACTION_NEXT, 1496 ZERO 1497 }; 1498 1499 static const enum index next_ial[] = { 1500 ACTION_INDIRECT_LIST_HANDLE, 1501 ACTION_INDIRECT_LIST_CONF, 1502 ACTION_NEXT, 1503 ZERO 1504 }; 1505 1506 static const enum index next_qia_qu_attr[] = { 1507 QUEUE_INDIRECT_ACTION_QU_MODE, 1508 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1509 INDIRECT_ACTION_SPEC, 1510 ZERO 1511 }; 1512 1513 static const enum index next_ia_qu_attr[] = { 1514 INDIRECT_ACTION_QU_MODE, 1515 INDIRECT_ACTION_SPEC, 1516 ZERO 1517 }; 1518 1519 static const enum index next_dump_subcmd[] = { 1520 DUMP_ALL, 1521 DUMP_ONE, 1522 DUMP_IS_USER_ID, 1523 ZERO, 1524 }; 1525 1526 static const enum index next_ia_subcmd[] = { 1527 INDIRECT_ACTION_CREATE, 1528 INDIRECT_ACTION_UPDATE, 1529 INDIRECT_ACTION_DESTROY, 1530 INDIRECT_ACTION_QUERY, 1531 INDIRECT_ACTION_QUERY_UPDATE, 1532 ZERO, 1533 }; 1534 1535 static const enum index next_vc_attr[] = { 1536 VC_GROUP, 1537 VC_PRIORITY, 1538 VC_INGRESS, 1539 VC_EGRESS, 1540 VC_TRANSFER, 1541 VC_TUNNEL_SET, 1542 VC_TUNNEL_MATCH, 1543 VC_USER_ID, 1544 ITEM_PATTERN, 1545 ZERO, 1546 }; 1547 1548 static const enum index next_destroy_attr[] = { 1549 DESTROY_RULE, 1550 DESTROY_IS_USER_ID, 1551 END, 1552 ZERO, 1553 }; 1554 1555 static const enum index next_dump_attr[] = { 1556 COMMON_FILE_PATH, 1557 END, 1558 ZERO, 1559 }; 1560 1561 static const enum index next_query_attr[] = { 1562 QUERY_IS_USER_ID, 1563 END, 1564 ZERO, 1565 }; 1566 1567 static const enum index next_list_attr[] = { 1568 LIST_GROUP, 1569 END, 1570 ZERO, 1571 }; 1572 1573 static const enum index next_aged_attr[] = { 1574 AGED_DESTROY, 1575 END, 1576 ZERO, 1577 }; 1578 1579 static const enum index next_ia_destroy_attr[] = { 1580 INDIRECT_ACTION_DESTROY_ID, 1581 END, 1582 ZERO, 1583 }; 1584 1585 static const enum index next_async_insert_subcmd[] = { 1586 QUEUE_PATTERN_TEMPLATE, 1587 QUEUE_RULE_ID, 1588 ZERO, 1589 }; 1590 1591 static const enum index next_async_pattern_subcmd[] = { 1592 QUEUE_PATTERN_TEMPLATE, 1593 QUEUE_ACTIONS_TEMPLATE, 1594 ZERO, 1595 }; 1596 1597 static const enum index item_param[] = { 1598 ITEM_PARAM_IS, 1599 ITEM_PARAM_SPEC, 1600 ITEM_PARAM_LAST, 1601 ITEM_PARAM_MASK, 1602 ITEM_PARAM_PREFIX, 1603 ZERO, 1604 }; 1605 1606 static const enum index next_item[] = { 1607 ITEM_END, 1608 ITEM_VOID, 1609 ITEM_INVERT, 1610 ITEM_ANY, 1611 ITEM_PORT_ID, 1612 ITEM_MARK, 1613 ITEM_RAW, 1614 ITEM_ETH, 1615 ITEM_VLAN, 1616 ITEM_IPV4, 1617 ITEM_IPV6, 1618 ITEM_ICMP, 1619 ITEM_UDP, 1620 ITEM_TCP, 1621 ITEM_SCTP, 1622 ITEM_VXLAN, 1623 ITEM_E_TAG, 1624 ITEM_NVGRE, 1625 ITEM_MPLS, 1626 ITEM_GRE, 1627 ITEM_FUZZY, 1628 ITEM_GTP, 1629 ITEM_GTPC, 1630 ITEM_GTPU, 1631 ITEM_GENEVE, 1632 ITEM_VXLAN_GPE, 1633 ITEM_ARP_ETH_IPV4, 1634 ITEM_IPV6_EXT, 1635 ITEM_IPV6_FRAG_EXT, 1636 ITEM_IPV6_ROUTING_EXT, 1637 ITEM_ICMP6, 1638 ITEM_ICMP6_ECHO_REQUEST, 1639 ITEM_ICMP6_ECHO_REPLY, 1640 ITEM_ICMP6_ND_NS, 1641 ITEM_ICMP6_ND_NA, 1642 ITEM_ICMP6_ND_OPT, 1643 ITEM_ICMP6_ND_OPT_SLA_ETH, 1644 ITEM_ICMP6_ND_OPT_TLA_ETH, 1645 ITEM_META, 1646 ITEM_RANDOM, 1647 ITEM_GRE_KEY, 1648 ITEM_GRE_OPTION, 1649 ITEM_GTP_PSC, 1650 ITEM_PPPOES, 1651 ITEM_PPPOED, 1652 ITEM_PPPOE_PROTO_ID, 1653 ITEM_HIGIG2, 1654 ITEM_TAG, 1655 ITEM_L2TPV3OIP, 1656 ITEM_ESP, 1657 ITEM_AH, 1658 ITEM_PFCP, 1659 ITEM_ECPRI, 1660 ITEM_GENEVE_OPT, 1661 ITEM_INTEGRITY, 1662 ITEM_CONNTRACK, 1663 ITEM_PORT_REPRESENTOR, 1664 ITEM_REPRESENTED_PORT, 1665 ITEM_FLEX, 1666 ITEM_L2TPV2, 1667 ITEM_PPP, 1668 ITEM_METER, 1669 ITEM_QUOTA, 1670 ITEM_AGGR_AFFINITY, 1671 ITEM_TX_QUEUE, 1672 ITEM_IB_BTH, 1673 ITEM_PTYPE, 1674 ITEM_NSH, 1675 ITEM_COMPARE, 1676 END_SET, 1677 ZERO, 1678 }; 1679 1680 static const enum index item_fuzzy[] = { 1681 ITEM_FUZZY_THRESH, 1682 ITEM_NEXT, 1683 ZERO, 1684 }; 1685 1686 static const enum index item_any[] = { 1687 ITEM_ANY_NUM, 1688 ITEM_NEXT, 1689 ZERO, 1690 }; 1691 1692 static const enum index item_port_id[] = { 1693 ITEM_PORT_ID_ID, 1694 ITEM_NEXT, 1695 ZERO, 1696 }; 1697 1698 static const enum index item_mark[] = { 1699 ITEM_MARK_ID, 1700 ITEM_NEXT, 1701 ZERO, 1702 }; 1703 1704 static const enum index item_raw[] = { 1705 ITEM_RAW_RELATIVE, 1706 ITEM_RAW_SEARCH, 1707 ITEM_RAW_OFFSET, 1708 ITEM_RAW_LIMIT, 1709 ITEM_RAW_PATTERN, 1710 ITEM_RAW_PATTERN_HEX, 1711 ITEM_NEXT, 1712 ZERO, 1713 }; 1714 1715 static const enum index item_eth[] = { 1716 ITEM_ETH_DST, 1717 ITEM_ETH_SRC, 1718 ITEM_ETH_TYPE, 1719 ITEM_ETH_HAS_VLAN, 1720 ITEM_NEXT, 1721 ZERO, 1722 }; 1723 1724 static const enum index item_vlan[] = { 1725 ITEM_VLAN_TCI, 1726 ITEM_VLAN_PCP, 1727 ITEM_VLAN_DEI, 1728 ITEM_VLAN_VID, 1729 ITEM_VLAN_INNER_TYPE, 1730 ITEM_VLAN_HAS_MORE_VLAN, 1731 ITEM_NEXT, 1732 ZERO, 1733 }; 1734 1735 static const enum index item_ipv4[] = { 1736 ITEM_IPV4_VER_IHL, 1737 ITEM_IPV4_TOS, 1738 ITEM_IPV4_LENGTH, 1739 ITEM_IPV4_ID, 1740 ITEM_IPV4_FRAGMENT_OFFSET, 1741 ITEM_IPV4_TTL, 1742 ITEM_IPV4_PROTO, 1743 ITEM_IPV4_SRC, 1744 ITEM_IPV4_DST, 1745 ITEM_NEXT, 1746 ZERO, 1747 }; 1748 1749 static const enum index item_ipv6[] = { 1750 ITEM_IPV6_TC, 1751 ITEM_IPV6_FLOW, 1752 ITEM_IPV6_LEN, 1753 ITEM_IPV6_PROTO, 1754 ITEM_IPV6_HOP, 1755 ITEM_IPV6_SRC, 1756 ITEM_IPV6_DST, 1757 ITEM_IPV6_HAS_FRAG_EXT, 1758 ITEM_IPV6_ROUTING_EXT, 1759 ITEM_NEXT, 1760 ZERO, 1761 }; 1762 1763 static const enum index item_ipv6_routing_ext[] = { 1764 ITEM_IPV6_ROUTING_EXT_TYPE, 1765 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 1766 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 1767 ITEM_NEXT, 1768 ZERO, 1769 }; 1770 1771 static const enum index item_icmp[] = { 1772 ITEM_ICMP_TYPE, 1773 ITEM_ICMP_CODE, 1774 ITEM_ICMP_IDENT, 1775 ITEM_ICMP_SEQ, 1776 ITEM_NEXT, 1777 ZERO, 1778 }; 1779 1780 static const enum index item_udp[] = { 1781 ITEM_UDP_SRC, 1782 ITEM_UDP_DST, 1783 ITEM_NEXT, 1784 ZERO, 1785 }; 1786 1787 static const enum index item_tcp[] = { 1788 ITEM_TCP_SRC, 1789 ITEM_TCP_DST, 1790 ITEM_TCP_FLAGS, 1791 ITEM_NEXT, 1792 ZERO, 1793 }; 1794 1795 static const enum index item_sctp[] = { 1796 ITEM_SCTP_SRC, 1797 ITEM_SCTP_DST, 1798 ITEM_SCTP_TAG, 1799 ITEM_SCTP_CKSUM, 1800 ITEM_NEXT, 1801 ZERO, 1802 }; 1803 1804 static const enum index item_vxlan[] = { 1805 ITEM_VXLAN_VNI, 1806 ITEM_VXLAN_FLAG_G, 1807 ITEM_VXLAN_FLAG_VER, 1808 ITEM_VXLAN_FLAG_I, 1809 ITEM_VXLAN_FLAG_P, 1810 ITEM_VXLAN_FLAG_B, 1811 ITEM_VXLAN_FLAG_O, 1812 ITEM_VXLAN_FLAG_D, 1813 ITEM_VXLAN_FLAG_A, 1814 ITEM_VXLAN_GBP_ID, 1815 ITEM_VXLAN_GPE_PROTO, 1816 ITEM_VXLAN_FIRST_RSVD, 1817 ITEM_VXLAN_SECND_RSVD, 1818 ITEM_VXLAN_THIRD_RSVD, 1819 ITEM_VXLAN_LAST_RSVD, 1820 ITEM_NEXT, 1821 ZERO, 1822 }; 1823 1824 static const enum index item_e_tag[] = { 1825 ITEM_E_TAG_GRP_ECID_B, 1826 ITEM_NEXT, 1827 ZERO, 1828 }; 1829 1830 static const enum index item_nvgre[] = { 1831 ITEM_NVGRE_TNI, 1832 ITEM_NEXT, 1833 ZERO, 1834 }; 1835 1836 static const enum index item_mpls[] = { 1837 ITEM_MPLS_LABEL, 1838 ITEM_MPLS_TC, 1839 ITEM_MPLS_S, 1840 ITEM_MPLS_TTL, 1841 ITEM_NEXT, 1842 ZERO, 1843 }; 1844 1845 static const enum index item_gre[] = { 1846 ITEM_GRE_PROTO, 1847 ITEM_GRE_C_RSVD0_VER, 1848 ITEM_GRE_C_BIT, 1849 ITEM_GRE_K_BIT, 1850 ITEM_GRE_S_BIT, 1851 ITEM_NEXT, 1852 ZERO, 1853 }; 1854 1855 static const enum index item_gre_key[] = { 1856 ITEM_GRE_KEY_VALUE, 1857 ITEM_NEXT, 1858 ZERO, 1859 }; 1860 1861 static const enum index item_gre_option[] = { 1862 ITEM_GRE_OPTION_CHECKSUM, 1863 ITEM_GRE_OPTION_KEY, 1864 ITEM_GRE_OPTION_SEQUENCE, 1865 ITEM_NEXT, 1866 ZERO, 1867 }; 1868 1869 static const enum index item_gtp[] = { 1870 ITEM_GTP_FLAGS, 1871 ITEM_GTP_MSG_TYPE, 1872 ITEM_GTP_TEID, 1873 ITEM_NEXT, 1874 ZERO, 1875 }; 1876 1877 static const enum index item_geneve[] = { 1878 ITEM_GENEVE_VNI, 1879 ITEM_GENEVE_PROTO, 1880 ITEM_GENEVE_OPTLEN, 1881 ITEM_NEXT, 1882 ZERO, 1883 }; 1884 1885 static const enum index item_vxlan_gpe[] = { 1886 ITEM_VXLAN_GPE_VNI, 1887 ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR, 1888 ITEM_VXLAN_GPE_FLAGS, 1889 ITEM_VXLAN_GPE_RSVD0, 1890 ITEM_VXLAN_GPE_RSVD1, 1891 ITEM_NEXT, 1892 ZERO, 1893 }; 1894 1895 static const enum index item_arp_eth_ipv4[] = { 1896 ITEM_ARP_ETH_IPV4_SHA, 1897 ITEM_ARP_ETH_IPV4_SPA, 1898 ITEM_ARP_ETH_IPV4_THA, 1899 ITEM_ARP_ETH_IPV4_TPA, 1900 ITEM_NEXT, 1901 ZERO, 1902 }; 1903 1904 static const enum index item_ipv6_ext[] = { 1905 ITEM_IPV6_EXT_NEXT_HDR, 1906 ITEM_NEXT, 1907 ZERO, 1908 }; 1909 1910 static const enum index item_ipv6_frag_ext[] = { 1911 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 1912 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 1913 ITEM_IPV6_FRAG_EXT_ID, 1914 ITEM_NEXT, 1915 ZERO, 1916 }; 1917 1918 static const enum index item_icmp6[] = { 1919 ITEM_ICMP6_TYPE, 1920 ITEM_ICMP6_CODE, 1921 ITEM_NEXT, 1922 ZERO, 1923 }; 1924 1925 static const enum index item_icmp6_echo_request[] = { 1926 ITEM_ICMP6_ECHO_REQUEST_ID, 1927 ITEM_ICMP6_ECHO_REQUEST_SEQ, 1928 ITEM_NEXT, 1929 ZERO, 1930 }; 1931 1932 static const enum index item_icmp6_echo_reply[] = { 1933 ITEM_ICMP6_ECHO_REPLY_ID, 1934 ITEM_ICMP6_ECHO_REPLY_SEQ, 1935 ITEM_NEXT, 1936 ZERO, 1937 }; 1938 1939 static const enum index item_icmp6_nd_ns[] = { 1940 ITEM_ICMP6_ND_NS_TARGET_ADDR, 1941 ITEM_NEXT, 1942 ZERO, 1943 }; 1944 1945 static const enum index item_icmp6_nd_na[] = { 1946 ITEM_ICMP6_ND_NA_TARGET_ADDR, 1947 ITEM_NEXT, 1948 ZERO, 1949 }; 1950 1951 static const enum index item_icmp6_nd_opt[] = { 1952 ITEM_ICMP6_ND_OPT_TYPE, 1953 ITEM_NEXT, 1954 ZERO, 1955 }; 1956 1957 static const enum index item_icmp6_nd_opt_sla_eth[] = { 1958 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 1959 ITEM_NEXT, 1960 ZERO, 1961 }; 1962 1963 static const enum index item_icmp6_nd_opt_tla_eth[] = { 1964 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 1965 ITEM_NEXT, 1966 ZERO, 1967 }; 1968 1969 static const enum index item_meta[] = { 1970 ITEM_META_DATA, 1971 ITEM_NEXT, 1972 ZERO, 1973 }; 1974 1975 static const enum index item_random[] = { 1976 ITEM_RANDOM_VALUE, 1977 ITEM_NEXT, 1978 ZERO, 1979 }; 1980 1981 static const enum index item_gtp_psc[] = { 1982 ITEM_GTP_PSC_QFI, 1983 ITEM_GTP_PSC_PDU_T, 1984 ITEM_NEXT, 1985 ZERO, 1986 }; 1987 1988 static const enum index item_pppoed[] = { 1989 ITEM_PPPOE_SEID, 1990 ITEM_NEXT, 1991 ZERO, 1992 }; 1993 1994 static const enum index item_pppoes[] = { 1995 ITEM_PPPOE_SEID, 1996 ITEM_NEXT, 1997 ZERO, 1998 }; 1999 2000 static const enum index item_pppoe_proto_id[] = { 2001 ITEM_NEXT, 2002 ZERO, 2003 }; 2004 2005 static const enum index item_higig2[] = { 2006 ITEM_HIGIG2_CLASSIFICATION, 2007 ITEM_HIGIG2_VID, 2008 ITEM_NEXT, 2009 ZERO, 2010 }; 2011 2012 static const enum index item_esp[] = { 2013 ITEM_ESP_SPI, 2014 ITEM_NEXT, 2015 ZERO, 2016 }; 2017 2018 static const enum index item_ah[] = { 2019 ITEM_AH_SPI, 2020 ITEM_NEXT, 2021 ZERO, 2022 }; 2023 2024 static const enum index item_pfcp[] = { 2025 ITEM_PFCP_S_FIELD, 2026 ITEM_PFCP_SEID, 2027 ITEM_NEXT, 2028 ZERO, 2029 }; 2030 2031 static const enum index next_set_raw[] = { 2032 SET_RAW_INDEX, 2033 ITEM_ETH, 2034 ZERO, 2035 }; 2036 2037 static const enum index item_tag[] = { 2038 ITEM_TAG_DATA, 2039 ITEM_TAG_INDEX, 2040 ITEM_NEXT, 2041 ZERO, 2042 }; 2043 2044 static const enum index item_l2tpv3oip[] = { 2045 ITEM_L2TPV3OIP_SESSION_ID, 2046 ITEM_NEXT, 2047 ZERO, 2048 }; 2049 2050 static const enum index item_ecpri[] = { 2051 ITEM_ECPRI_COMMON, 2052 ITEM_NEXT, 2053 ZERO, 2054 }; 2055 2056 static const enum index item_ecpri_common[] = { 2057 ITEM_ECPRI_COMMON_TYPE, 2058 ZERO, 2059 }; 2060 2061 static const enum index item_ecpri_common_type[] = { 2062 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 2063 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 2064 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 2065 ZERO, 2066 }; 2067 2068 static const enum index item_geneve_opt[] = { 2069 ITEM_GENEVE_OPT_CLASS, 2070 ITEM_GENEVE_OPT_TYPE, 2071 ITEM_GENEVE_OPT_LENGTH, 2072 ITEM_GENEVE_OPT_DATA, 2073 ITEM_NEXT, 2074 ZERO, 2075 }; 2076 2077 static const enum index item_integrity[] = { 2078 ITEM_INTEGRITY_LEVEL, 2079 ITEM_INTEGRITY_VALUE, 2080 ZERO, 2081 }; 2082 2083 static const enum index item_integrity_lv[] = { 2084 ITEM_INTEGRITY_LEVEL, 2085 ITEM_INTEGRITY_VALUE, 2086 ITEM_NEXT, 2087 ZERO, 2088 }; 2089 2090 static const enum index item_port_representor[] = { 2091 ITEM_PORT_REPRESENTOR_PORT_ID, 2092 ITEM_NEXT, 2093 ZERO, 2094 }; 2095 2096 static const enum index item_represented_port[] = { 2097 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 2098 ITEM_NEXT, 2099 ZERO, 2100 }; 2101 2102 static const enum index item_flex[] = { 2103 ITEM_FLEX_PATTERN_HANDLE, 2104 ITEM_FLEX_ITEM_HANDLE, 2105 ITEM_NEXT, 2106 ZERO, 2107 }; 2108 2109 static const enum index item_l2tpv2[] = { 2110 ITEM_L2TPV2_TYPE, 2111 ITEM_NEXT, 2112 ZERO, 2113 }; 2114 2115 static const enum index item_l2tpv2_type[] = { 2116 ITEM_L2TPV2_TYPE_DATA, 2117 ITEM_L2TPV2_TYPE_DATA_L, 2118 ITEM_L2TPV2_TYPE_DATA_S, 2119 ITEM_L2TPV2_TYPE_DATA_O, 2120 ITEM_L2TPV2_TYPE_DATA_L_S, 2121 ITEM_L2TPV2_TYPE_CTRL, 2122 ZERO, 2123 }; 2124 2125 static const enum index item_l2tpv2_type_data[] = { 2126 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 2127 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 2128 ITEM_NEXT, 2129 ZERO, 2130 }; 2131 2132 static const enum index item_l2tpv2_type_data_l[] = { 2133 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 2134 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 2135 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 2136 ITEM_NEXT, 2137 ZERO, 2138 }; 2139 2140 static const enum index item_l2tpv2_type_data_s[] = { 2141 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 2142 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 2143 ITEM_L2TPV2_MSG_DATA_S_NS, 2144 ITEM_L2TPV2_MSG_DATA_S_NR, 2145 ITEM_NEXT, 2146 ZERO, 2147 }; 2148 2149 static const enum index item_l2tpv2_type_data_o[] = { 2150 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 2151 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 2152 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 2153 ITEM_NEXT, 2154 ZERO, 2155 }; 2156 2157 static const enum index item_l2tpv2_type_data_l_s[] = { 2158 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 2159 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 2160 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 2161 ITEM_L2TPV2_MSG_DATA_L_S_NS, 2162 ITEM_L2TPV2_MSG_DATA_L_S_NR, 2163 ITEM_NEXT, 2164 ZERO, 2165 }; 2166 2167 static const enum index item_l2tpv2_type_ctrl[] = { 2168 ITEM_L2TPV2_MSG_CTRL_LENGTH, 2169 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 2170 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 2171 ITEM_L2TPV2_MSG_CTRL_NS, 2172 ITEM_L2TPV2_MSG_CTRL_NR, 2173 ITEM_NEXT, 2174 ZERO, 2175 }; 2176 2177 static const enum index item_ppp[] = { 2178 ITEM_PPP_ADDR, 2179 ITEM_PPP_CTRL, 2180 ITEM_PPP_PROTO_ID, 2181 ITEM_NEXT, 2182 ZERO, 2183 }; 2184 2185 static const enum index item_meter[] = { 2186 ITEM_METER_COLOR, 2187 ITEM_NEXT, 2188 ZERO, 2189 }; 2190 2191 static const enum index item_quota[] = { 2192 ITEM_QUOTA_STATE, 2193 ITEM_NEXT, 2194 ZERO, 2195 }; 2196 2197 static const enum index item_aggr_affinity[] = { 2198 ITEM_AGGR_AFFINITY_VALUE, 2199 ITEM_NEXT, 2200 ZERO, 2201 }; 2202 2203 static const enum index item_tx_queue[] = { 2204 ITEM_TX_QUEUE_VALUE, 2205 ITEM_NEXT, 2206 ZERO, 2207 }; 2208 2209 static const enum index item_ib_bth[] = { 2210 ITEM_IB_BTH_OPCODE, 2211 ITEM_IB_BTH_PKEY, 2212 ITEM_IB_BTH_DST_QPN, 2213 ITEM_IB_BTH_PSN, 2214 ITEM_NEXT, 2215 ZERO, 2216 }; 2217 2218 static const enum index item_ptype[] = { 2219 ITEM_PTYPE_VALUE, 2220 ITEM_NEXT, 2221 ZERO, 2222 }; 2223 2224 static const enum index item_nsh[] = { 2225 ITEM_NEXT, 2226 ZERO, 2227 }; 2228 2229 static const enum index item_compare_field[] = { 2230 ITEM_COMPARE_OP, 2231 ITEM_COMPARE_FIELD_A_TYPE, 2232 ITEM_COMPARE_FIELD_B_TYPE, 2233 ITEM_NEXT, 2234 ZERO, 2235 }; 2236 2237 static const enum index compare_field_a[] = { 2238 ITEM_COMPARE_FIELD_A_TYPE, 2239 ITEM_COMPARE_FIELD_A_LEVEL, 2240 ITEM_COMPARE_FIELD_A_TAG_INDEX, 2241 ITEM_COMPARE_FIELD_A_TYPE_ID, 2242 ITEM_COMPARE_FIELD_A_CLASS_ID, 2243 ITEM_COMPARE_FIELD_A_OFFSET, 2244 ITEM_COMPARE_FIELD_B_TYPE, 2245 ZERO, 2246 }; 2247 2248 static const enum index compare_field_b[] = { 2249 ITEM_COMPARE_FIELD_B_TYPE, 2250 ITEM_COMPARE_FIELD_B_LEVEL, 2251 ITEM_COMPARE_FIELD_B_TAG_INDEX, 2252 ITEM_COMPARE_FIELD_B_TYPE_ID, 2253 ITEM_COMPARE_FIELD_B_CLASS_ID, 2254 ITEM_COMPARE_FIELD_B_OFFSET, 2255 ITEM_COMPARE_FIELD_B_VALUE, 2256 ITEM_COMPARE_FIELD_B_POINTER, 2257 ITEM_COMPARE_FIELD_WIDTH, 2258 ZERO, 2259 }; 2260 2261 static const enum index next_action[] = { 2262 ACTION_END, 2263 ACTION_VOID, 2264 ACTION_PASSTHRU, 2265 ACTION_SKIP_CMAN, 2266 ACTION_JUMP, 2267 ACTION_MARK, 2268 ACTION_FLAG, 2269 ACTION_QUEUE, 2270 ACTION_DROP, 2271 ACTION_COUNT, 2272 ACTION_RSS, 2273 ACTION_PF, 2274 ACTION_VF, 2275 ACTION_PORT_ID, 2276 ACTION_METER, 2277 ACTION_METER_COLOR, 2278 ACTION_METER_MARK, 2279 ACTION_OF_DEC_NW_TTL, 2280 ACTION_OF_POP_VLAN, 2281 ACTION_OF_PUSH_VLAN, 2282 ACTION_OF_SET_VLAN_VID, 2283 ACTION_OF_SET_VLAN_PCP, 2284 ACTION_OF_POP_MPLS, 2285 ACTION_OF_PUSH_MPLS, 2286 ACTION_VXLAN_ENCAP, 2287 ACTION_VXLAN_DECAP, 2288 ACTION_NVGRE_ENCAP, 2289 ACTION_NVGRE_DECAP, 2290 ACTION_L2_ENCAP, 2291 ACTION_L2_DECAP, 2292 ACTION_MPLSOGRE_ENCAP, 2293 ACTION_MPLSOGRE_DECAP, 2294 ACTION_MPLSOUDP_ENCAP, 2295 ACTION_MPLSOUDP_DECAP, 2296 ACTION_SET_IPV4_SRC, 2297 ACTION_SET_IPV4_DST, 2298 ACTION_SET_IPV6_SRC, 2299 ACTION_SET_IPV6_DST, 2300 ACTION_SET_TP_SRC, 2301 ACTION_SET_TP_DST, 2302 ACTION_MAC_SWAP, 2303 ACTION_DEC_TTL, 2304 ACTION_SET_TTL, 2305 ACTION_SET_MAC_SRC, 2306 ACTION_SET_MAC_DST, 2307 ACTION_INC_TCP_SEQ, 2308 ACTION_DEC_TCP_SEQ, 2309 ACTION_INC_TCP_ACK, 2310 ACTION_DEC_TCP_ACK, 2311 ACTION_RAW_ENCAP, 2312 ACTION_RAW_DECAP, 2313 ACTION_SET_TAG, 2314 ACTION_SET_META, 2315 ACTION_SET_IPV4_DSCP, 2316 ACTION_SET_IPV6_DSCP, 2317 ACTION_AGE, 2318 ACTION_AGE_UPDATE, 2319 ACTION_SAMPLE, 2320 ACTION_INDIRECT, 2321 ACTION_INDIRECT_LIST, 2322 ACTION_SHARED_INDIRECT, 2323 ACTION_MODIFY_FIELD, 2324 ACTION_CONNTRACK, 2325 ACTION_CONNTRACK_UPDATE, 2326 ACTION_PORT_REPRESENTOR, 2327 ACTION_REPRESENTED_PORT, 2328 ACTION_SEND_TO_KERNEL, 2329 ACTION_QUOTA_CREATE, 2330 ACTION_QUOTA_QU, 2331 ACTION_IPV6_EXT_REMOVE, 2332 ACTION_IPV6_EXT_PUSH, 2333 ACTION_NAT64, 2334 ACTION_JUMP_TO_TABLE_INDEX, 2335 ZERO, 2336 }; 2337 2338 static const enum index action_quota_create[] = { 2339 ACTION_QUOTA_CREATE_LIMIT, 2340 ACTION_QUOTA_CREATE_MODE, 2341 ACTION_NEXT, 2342 ZERO 2343 }; 2344 2345 static const enum index action_quota_update[] = { 2346 ACTION_QUOTA_QU_LIMIT, 2347 ACTION_QUOTA_QU_UPDATE_OP, 2348 ACTION_NEXT, 2349 ZERO 2350 }; 2351 2352 static const enum index action_mark[] = { 2353 ACTION_MARK_ID, 2354 ACTION_NEXT, 2355 ZERO, 2356 }; 2357 2358 static const enum index action_queue[] = { 2359 ACTION_QUEUE_INDEX, 2360 ACTION_NEXT, 2361 ZERO, 2362 }; 2363 2364 static const enum index action_count[] = { 2365 ACTION_COUNT_ID, 2366 ACTION_NEXT, 2367 ZERO, 2368 }; 2369 2370 static const enum index action_rss[] = { 2371 ACTION_RSS_FUNC, 2372 ACTION_RSS_LEVEL, 2373 ACTION_RSS_TYPES, 2374 ACTION_RSS_KEY, 2375 ACTION_RSS_KEY_LEN, 2376 ACTION_RSS_QUEUES, 2377 ACTION_NEXT, 2378 ZERO, 2379 }; 2380 2381 static const enum index action_vf[] = { 2382 ACTION_VF_ORIGINAL, 2383 ACTION_VF_ID, 2384 ACTION_NEXT, 2385 ZERO, 2386 }; 2387 2388 static const enum index action_port_id[] = { 2389 ACTION_PORT_ID_ORIGINAL, 2390 ACTION_PORT_ID_ID, 2391 ACTION_NEXT, 2392 ZERO, 2393 }; 2394 2395 static const enum index action_meter[] = { 2396 ACTION_METER_ID, 2397 ACTION_NEXT, 2398 ZERO, 2399 }; 2400 2401 static const enum index action_meter_color[] = { 2402 ACTION_METER_COLOR_TYPE, 2403 ACTION_NEXT, 2404 ZERO, 2405 }; 2406 2407 static const enum index action_meter_mark[] = { 2408 ACTION_METER_PROFILE, 2409 ACTION_METER_POLICY, 2410 ACTION_METER_COLOR_MODE, 2411 ACTION_METER_STATE, 2412 ACTION_NEXT, 2413 ZERO, 2414 }; 2415 2416 static const enum index action_of_push_vlan[] = { 2417 ACTION_OF_PUSH_VLAN_ETHERTYPE, 2418 ACTION_NEXT, 2419 ZERO, 2420 }; 2421 2422 static const enum index action_of_set_vlan_vid[] = { 2423 ACTION_OF_SET_VLAN_VID_VLAN_VID, 2424 ACTION_NEXT, 2425 ZERO, 2426 }; 2427 2428 static const enum index action_of_set_vlan_pcp[] = { 2429 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 2430 ACTION_NEXT, 2431 ZERO, 2432 }; 2433 2434 static const enum index action_of_pop_mpls[] = { 2435 ACTION_OF_POP_MPLS_ETHERTYPE, 2436 ACTION_NEXT, 2437 ZERO, 2438 }; 2439 2440 static const enum index action_of_push_mpls[] = { 2441 ACTION_OF_PUSH_MPLS_ETHERTYPE, 2442 ACTION_NEXT, 2443 ZERO, 2444 }; 2445 2446 static const enum index action_set_ipv4_src[] = { 2447 ACTION_SET_IPV4_SRC_IPV4_SRC, 2448 ACTION_NEXT, 2449 ZERO, 2450 }; 2451 2452 static const enum index action_set_mac_src[] = { 2453 ACTION_SET_MAC_SRC_MAC_SRC, 2454 ACTION_NEXT, 2455 ZERO, 2456 }; 2457 2458 static const enum index action_set_ipv4_dst[] = { 2459 ACTION_SET_IPV4_DST_IPV4_DST, 2460 ACTION_NEXT, 2461 ZERO, 2462 }; 2463 2464 static const enum index action_set_ipv6_src[] = { 2465 ACTION_SET_IPV6_SRC_IPV6_SRC, 2466 ACTION_NEXT, 2467 ZERO, 2468 }; 2469 2470 static const enum index action_set_ipv6_dst[] = { 2471 ACTION_SET_IPV6_DST_IPV6_DST, 2472 ACTION_NEXT, 2473 ZERO, 2474 }; 2475 2476 static const enum index action_set_tp_src[] = { 2477 ACTION_SET_TP_SRC_TP_SRC, 2478 ACTION_NEXT, 2479 ZERO, 2480 }; 2481 2482 static const enum index action_set_tp_dst[] = { 2483 ACTION_SET_TP_DST_TP_DST, 2484 ACTION_NEXT, 2485 ZERO, 2486 }; 2487 2488 static const enum index action_set_ttl[] = { 2489 ACTION_SET_TTL_TTL, 2490 ACTION_NEXT, 2491 ZERO, 2492 }; 2493 2494 static const enum index action_jump[] = { 2495 ACTION_JUMP_GROUP, 2496 ACTION_NEXT, 2497 ZERO, 2498 }; 2499 2500 static const enum index action_set_mac_dst[] = { 2501 ACTION_SET_MAC_DST_MAC_DST, 2502 ACTION_NEXT, 2503 ZERO, 2504 }; 2505 2506 static const enum index action_inc_tcp_seq[] = { 2507 ACTION_INC_TCP_SEQ_VALUE, 2508 ACTION_NEXT, 2509 ZERO, 2510 }; 2511 2512 static const enum index action_dec_tcp_seq[] = { 2513 ACTION_DEC_TCP_SEQ_VALUE, 2514 ACTION_NEXT, 2515 ZERO, 2516 }; 2517 2518 static const enum index action_inc_tcp_ack[] = { 2519 ACTION_INC_TCP_ACK_VALUE, 2520 ACTION_NEXT, 2521 ZERO, 2522 }; 2523 2524 static const enum index action_dec_tcp_ack[] = { 2525 ACTION_DEC_TCP_ACK_VALUE, 2526 ACTION_NEXT, 2527 ZERO, 2528 }; 2529 2530 static const enum index action_raw_encap[] = { 2531 ACTION_RAW_ENCAP_SIZE, 2532 ACTION_RAW_ENCAP_INDEX, 2533 ACTION_NEXT, 2534 ZERO, 2535 }; 2536 2537 static const enum index action_raw_decap[] = { 2538 ACTION_RAW_DECAP_INDEX, 2539 ACTION_NEXT, 2540 ZERO, 2541 }; 2542 2543 static const enum index action_ipv6_ext_remove[] = { 2544 ACTION_IPV6_EXT_REMOVE_INDEX, 2545 ACTION_NEXT, 2546 ZERO, 2547 }; 2548 2549 static const enum index action_ipv6_ext_push[] = { 2550 ACTION_IPV6_EXT_PUSH_INDEX, 2551 ACTION_NEXT, 2552 ZERO, 2553 }; 2554 2555 static const enum index action_set_tag[] = { 2556 ACTION_SET_TAG_DATA, 2557 ACTION_SET_TAG_INDEX, 2558 ACTION_SET_TAG_MASK, 2559 ACTION_NEXT, 2560 ZERO, 2561 }; 2562 2563 static const enum index action_set_meta[] = { 2564 ACTION_SET_META_DATA, 2565 ACTION_SET_META_MASK, 2566 ACTION_NEXT, 2567 ZERO, 2568 }; 2569 2570 static const enum index action_set_ipv4_dscp[] = { 2571 ACTION_SET_IPV4_DSCP_VALUE, 2572 ACTION_NEXT, 2573 ZERO, 2574 }; 2575 2576 static const enum index action_set_ipv6_dscp[] = { 2577 ACTION_SET_IPV6_DSCP_VALUE, 2578 ACTION_NEXT, 2579 ZERO, 2580 }; 2581 2582 static const enum index action_age[] = { 2583 ACTION_AGE, 2584 ACTION_AGE_TIMEOUT, 2585 ACTION_NEXT, 2586 ZERO, 2587 }; 2588 2589 static const enum index action_age_update[] = { 2590 ACTION_AGE_UPDATE, 2591 ACTION_AGE_UPDATE_TIMEOUT, 2592 ACTION_AGE_UPDATE_TOUCH, 2593 ACTION_NEXT, 2594 ZERO, 2595 }; 2596 2597 static const enum index action_sample[] = { 2598 ACTION_SAMPLE, 2599 ACTION_SAMPLE_RATIO, 2600 ACTION_SAMPLE_INDEX, 2601 ACTION_NEXT, 2602 ZERO, 2603 }; 2604 2605 static const enum index next_action_sample[] = { 2606 ACTION_QUEUE, 2607 ACTION_RSS, 2608 ACTION_MARK, 2609 ACTION_COUNT, 2610 ACTION_PORT_ID, 2611 ACTION_RAW_ENCAP, 2612 ACTION_VXLAN_ENCAP, 2613 ACTION_NVGRE_ENCAP, 2614 ACTION_REPRESENTED_PORT, 2615 ACTION_PORT_REPRESENTOR, 2616 ACTION_NEXT, 2617 ZERO, 2618 }; 2619 2620 static const enum index item_ipv6_push_ext[] = { 2621 ITEM_IPV6_PUSH_REMOVE_EXT, 2622 ZERO, 2623 }; 2624 2625 static const enum index item_ipv6_push_ext_type[] = { 2626 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 2627 ZERO, 2628 }; 2629 2630 static const enum index item_ipv6_push_ext_header[] = { 2631 ITEM_IPV6_ROUTING_EXT, 2632 ITEM_NEXT, 2633 ZERO, 2634 }; 2635 2636 static const enum index action_modify_field_dst[] = { 2637 ACTION_MODIFY_FIELD_DST_LEVEL, 2638 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 2639 ACTION_MODIFY_FIELD_DST_TYPE_ID, 2640 ACTION_MODIFY_FIELD_DST_CLASS_ID, 2641 ACTION_MODIFY_FIELD_DST_OFFSET, 2642 ACTION_MODIFY_FIELD_SRC_TYPE, 2643 ZERO, 2644 }; 2645 2646 static const enum index action_modify_field_src[] = { 2647 ACTION_MODIFY_FIELD_SRC_LEVEL, 2648 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 2649 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 2650 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 2651 ACTION_MODIFY_FIELD_SRC_OFFSET, 2652 ACTION_MODIFY_FIELD_SRC_VALUE, 2653 ACTION_MODIFY_FIELD_SRC_POINTER, 2654 ACTION_MODIFY_FIELD_WIDTH, 2655 ZERO, 2656 }; 2657 2658 static const enum index action_update_conntrack[] = { 2659 ACTION_CONNTRACK_UPDATE_DIR, 2660 ACTION_CONNTRACK_UPDATE_CTX, 2661 ACTION_NEXT, 2662 ZERO, 2663 }; 2664 2665 static const enum index action_port_representor[] = { 2666 ACTION_PORT_REPRESENTOR_PORT_ID, 2667 ACTION_NEXT, 2668 ZERO, 2669 }; 2670 2671 static const enum index action_represented_port[] = { 2672 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 2673 ACTION_NEXT, 2674 ZERO, 2675 }; 2676 2677 static const enum index action_nat64[] = { 2678 ACTION_NAT64_MODE, 2679 ACTION_NEXT, 2680 ZERO, 2681 }; 2682 2683 static const enum index next_hash_subcmd[] = { 2684 HASH_CALC_TABLE, 2685 HASH_CALC_ENCAP, 2686 ZERO, 2687 }; 2688 2689 static const enum index next_hash_encap_dest_subcmd[] = { 2690 ENCAP_HASH_FIELD_SRC_PORT, 2691 ENCAP_HASH_FIELD_GRE_FLOW_ID, 2692 ZERO, 2693 }; 2694 2695 static const enum index action_jump_to_table_index[] = { 2696 ACTION_JUMP_TO_TABLE_INDEX_TABLE, 2697 ACTION_JUMP_TO_TABLE_INDEX_INDEX, 2698 ACTION_NEXT, 2699 ZERO, 2700 }; 2701 2702 static int parse_set_raw_encap_decap(struct context *, const struct token *, 2703 const char *, unsigned int, 2704 void *, unsigned int); 2705 static int parse_set_sample_action(struct context *, const struct token *, 2706 const char *, unsigned int, 2707 void *, unsigned int); 2708 static int parse_set_ipv6_ext_action(struct context *, const struct token *, 2709 const char *, unsigned int, 2710 void *, unsigned int); 2711 static int parse_set_init(struct context *, const struct token *, 2712 const char *, unsigned int, 2713 void *, unsigned int); 2714 static int 2715 parse_flex_handle(struct context *, const struct token *, 2716 const char *, unsigned int, void *, unsigned int); 2717 static int parse_init(struct context *, const struct token *, 2718 const char *, unsigned int, 2719 void *, unsigned int); 2720 static int parse_vc(struct context *, const struct token *, 2721 const char *, unsigned int, 2722 void *, unsigned int); 2723 static int parse_vc_spec(struct context *, const struct token *, 2724 const char *, unsigned int, void *, unsigned int); 2725 static int parse_vc_conf(struct context *, const struct token *, 2726 const char *, unsigned int, void *, unsigned int); 2727 static int parse_vc_conf_timeout(struct context *, const struct token *, 2728 const char *, unsigned int, void *, 2729 unsigned int); 2730 static int parse_vc_item_ecpri_type(struct context *, const struct token *, 2731 const char *, unsigned int, 2732 void *, unsigned int); 2733 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, 2734 const char *, unsigned int, 2735 void *, unsigned int); 2736 static int parse_vc_action_meter_color_type(struct context *, 2737 const struct token *, 2738 const char *, unsigned int, void *, 2739 unsigned int); 2740 static int parse_vc_action_rss(struct context *, const struct token *, 2741 const char *, unsigned int, void *, 2742 unsigned int); 2743 static int parse_vc_action_rss_func(struct context *, const struct token *, 2744 const char *, unsigned int, void *, 2745 unsigned int); 2746 static int parse_vc_action_rss_type(struct context *, const struct token *, 2747 const char *, unsigned int, void *, 2748 unsigned int); 2749 static int parse_vc_action_rss_queue(struct context *, const struct token *, 2750 const char *, unsigned int, void *, 2751 unsigned int); 2752 static int parse_vc_action_vxlan_encap(struct context *, const struct token *, 2753 const char *, unsigned int, void *, 2754 unsigned int); 2755 static int parse_vc_action_nvgre_encap(struct context *, const struct token *, 2756 const char *, unsigned int, void *, 2757 unsigned int); 2758 static int parse_vc_action_l2_encap(struct context *, const struct token *, 2759 const char *, unsigned int, void *, 2760 unsigned int); 2761 static int parse_vc_action_l2_decap(struct context *, const struct token *, 2762 const char *, unsigned int, void *, 2763 unsigned int); 2764 static int parse_vc_action_mplsogre_encap(struct context *, 2765 const struct token *, const char *, 2766 unsigned int, void *, unsigned int); 2767 static int parse_vc_action_mplsogre_decap(struct context *, 2768 const struct token *, const char *, 2769 unsigned int, void *, unsigned int); 2770 static int parse_vc_action_mplsoudp_encap(struct context *, 2771 const struct token *, const char *, 2772 unsigned int, void *, unsigned int); 2773 static int parse_vc_action_mplsoudp_decap(struct context *, 2774 const struct token *, const char *, 2775 unsigned int, void *, unsigned int); 2776 static int parse_vc_action_raw_encap(struct context *, 2777 const struct token *, const char *, 2778 unsigned int, void *, unsigned int); 2779 static int parse_vc_action_raw_decap(struct context *, 2780 const struct token *, const char *, 2781 unsigned int, void *, unsigned int); 2782 static int parse_vc_action_raw_encap_index(struct context *, 2783 const struct token *, const char *, 2784 unsigned int, void *, unsigned int); 2785 static int parse_vc_action_raw_decap_index(struct context *, 2786 const struct token *, const char *, 2787 unsigned int, void *, unsigned int); 2788 static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 2789 const char *str, unsigned int len, void *buf, 2790 unsigned int size); 2791 static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, 2792 const struct token *token, 2793 const char *str, unsigned int len, 2794 void *buf, 2795 unsigned int size); 2796 static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 2797 const char *str, unsigned int len, void *buf, 2798 unsigned int size); 2799 static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, 2800 const struct token *token, 2801 const char *str, unsigned int len, 2802 void *buf, 2803 unsigned int size); 2804 static int parse_vc_action_set_meta(struct context *ctx, 2805 const struct token *token, const char *str, 2806 unsigned int len, void *buf, 2807 unsigned int size); 2808 static int parse_vc_action_sample(struct context *ctx, 2809 const struct token *token, const char *str, 2810 unsigned int len, void *buf, 2811 unsigned int size); 2812 static int 2813 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 2814 const char *str, unsigned int len, void *buf, 2815 unsigned int size); 2816 static int 2817 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 2818 const char *str, unsigned int len, void *buf, 2819 unsigned int size); 2820 static int 2821 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 2822 const char *str, unsigned int len, void *buf, 2823 unsigned int size); 2824 static int 2825 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 2826 const char *str, unsigned int len, void *buf, 2827 unsigned int size); 2828 static int 2829 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 2830 const char *str, unsigned int len, void *buf, 2831 unsigned int size); 2832 static int parse_destroy(struct context *, const struct token *, 2833 const char *, unsigned int, 2834 void *, unsigned int); 2835 static int parse_flush(struct context *, const struct token *, 2836 const char *, unsigned int, 2837 void *, unsigned int); 2838 static int parse_dump(struct context *, const struct token *, 2839 const char *, unsigned int, 2840 void *, unsigned int); 2841 static int parse_query(struct context *, const struct token *, 2842 const char *, unsigned int, 2843 void *, unsigned int); 2844 static int parse_action(struct context *, const struct token *, 2845 const char *, unsigned int, 2846 void *, unsigned int); 2847 static int parse_list(struct context *, const struct token *, 2848 const char *, unsigned int, 2849 void *, unsigned int); 2850 static int parse_aged(struct context *, const struct token *, 2851 const char *, unsigned int, 2852 void *, unsigned int); 2853 static int parse_isolate(struct context *, const struct token *, 2854 const char *, unsigned int, 2855 void *, unsigned int); 2856 static int parse_configure(struct context *, const struct token *, 2857 const char *, unsigned int, 2858 void *, unsigned int); 2859 static int parse_template(struct context *, const struct token *, 2860 const char *, unsigned int, 2861 void *, unsigned int); 2862 static int parse_template_destroy(struct context *, const struct token *, 2863 const char *, unsigned int, 2864 void *, unsigned int); 2865 static int parse_table(struct context *, const struct token *, 2866 const char *, unsigned int, void *, unsigned int); 2867 static int parse_table_destroy(struct context *, const struct token *, 2868 const char *, unsigned int, 2869 void *, unsigned int); 2870 static int parse_qo(struct context *, const struct token *, 2871 const char *, unsigned int, 2872 void *, unsigned int); 2873 static int parse_qo_destroy(struct context *, const struct token *, 2874 const char *, unsigned int, 2875 void *, unsigned int); 2876 static int parse_qia(struct context *, const struct token *, 2877 const char *, unsigned int, 2878 void *, unsigned int); 2879 static int parse_qia_destroy(struct context *, const struct token *, 2880 const char *, unsigned int, 2881 void *, unsigned int); 2882 static int parse_push(struct context *, const struct token *, 2883 const char *, unsigned int, 2884 void *, unsigned int); 2885 static int parse_pull(struct context *, const struct token *, 2886 const char *, unsigned int, 2887 void *, unsigned int); 2888 static int parse_group(struct context *, const struct token *, 2889 const char *, unsigned int, 2890 void *, unsigned int); 2891 static int parse_hash(struct context *, const struct token *, 2892 const char *, unsigned int, 2893 void *, unsigned int); 2894 static int parse_tunnel(struct context *, const struct token *, 2895 const char *, unsigned int, 2896 void *, unsigned int); 2897 static int parse_flex(struct context *, const struct token *, 2898 const char *, unsigned int, void *, unsigned int); 2899 static int parse_int(struct context *, const struct token *, 2900 const char *, unsigned int, 2901 void *, unsigned int); 2902 static int parse_prefix(struct context *, const struct token *, 2903 const char *, unsigned int, 2904 void *, unsigned int); 2905 static int parse_boolean(struct context *, const struct token *, 2906 const char *, unsigned int, 2907 void *, unsigned int); 2908 static int parse_string(struct context *, const struct token *, 2909 const char *, unsigned int, 2910 void *, unsigned int); 2911 static int parse_hex(struct context *ctx, const struct token *token, 2912 const char *str, unsigned int len, 2913 void *buf, unsigned int size); 2914 static int parse_string0(struct context *, const struct token *, 2915 const char *, unsigned int, 2916 void *, unsigned int); 2917 static int parse_mac_addr(struct context *, const struct token *, 2918 const char *, unsigned int, 2919 void *, unsigned int); 2920 static int parse_ipv4_addr(struct context *, const struct token *, 2921 const char *, unsigned int, 2922 void *, unsigned int); 2923 static int parse_ipv6_addr(struct context *, const struct token *, 2924 const char *, unsigned int, 2925 void *, unsigned int); 2926 static int parse_port(struct context *, const struct token *, 2927 const char *, unsigned int, 2928 void *, unsigned int); 2929 static int parse_ia(struct context *, const struct token *, 2930 const char *, unsigned int, 2931 void *, unsigned int); 2932 static int parse_ia_destroy(struct context *ctx, const struct token *token, 2933 const char *str, unsigned int len, 2934 void *buf, unsigned int size); 2935 static int parse_ia_id2ptr(struct context *ctx, const struct token *token, 2936 const char *str, unsigned int len, void *buf, 2937 unsigned int size); 2938 2939 static int parse_indlst_id2ptr(struct context *ctx, const struct token *token, 2940 const char *str, unsigned int len, void *buf, 2941 unsigned int size); 2942 static int parse_ia_port(struct context *ctx, const struct token *token, 2943 const char *str, unsigned int len, void *buf, 2944 unsigned int size); 2945 static int parse_mp(struct context *, const struct token *, 2946 const char *, unsigned int, 2947 void *, unsigned int); 2948 static int parse_meter_profile_id2ptr(struct context *ctx, 2949 const struct token *token, 2950 const char *str, unsigned int len, 2951 void *buf, unsigned int size); 2952 static int parse_meter_policy_id2ptr(struct context *ctx, 2953 const struct token *token, 2954 const char *str, unsigned int len, 2955 void *buf, unsigned int size); 2956 static int parse_meter_color(struct context *ctx, const struct token *token, 2957 const char *str, unsigned int len, void *buf, 2958 unsigned int size); 2959 static int parse_insertion_table_type(struct context *ctx, const struct token *token, 2960 const char *str, unsigned int len, void *buf, 2961 unsigned int size); 2962 static int parse_hash_table_type(struct context *ctx, const struct token *token, 2963 const char *str, unsigned int len, void *buf, 2964 unsigned int size); 2965 static int 2966 parse_quota_state_name(struct context *ctx, const struct token *token, 2967 const char *str, unsigned int len, void *buf, 2968 unsigned int size); 2969 static int 2970 parse_quota_mode_name(struct context *ctx, const struct token *token, 2971 const char *str, unsigned int len, void *buf, 2972 unsigned int size); 2973 static int 2974 parse_quota_update_name(struct context *ctx, const struct token *token, 2975 const char *str, unsigned int len, void *buf, 2976 unsigned int size); 2977 static int 2978 parse_qu_mode_name(struct context *ctx, const struct token *token, 2979 const char *str, unsigned int len, void *buf, 2980 unsigned int size); 2981 static int comp_none(struct context *, const struct token *, 2982 unsigned int, char *, unsigned int); 2983 static int comp_boolean(struct context *, const struct token *, 2984 unsigned int, char *, unsigned int); 2985 static int comp_action(struct context *, const struct token *, 2986 unsigned int, char *, unsigned int); 2987 static int comp_port(struct context *, const struct token *, 2988 unsigned int, char *, unsigned int); 2989 static int comp_rule_id(struct context *, const struct token *, 2990 unsigned int, char *, unsigned int); 2991 static int comp_vc_action_rss_type(struct context *, const struct token *, 2992 unsigned int, char *, unsigned int); 2993 static int comp_vc_action_rss_queue(struct context *, const struct token *, 2994 unsigned int, char *, unsigned int); 2995 static int comp_set_raw_index(struct context *, const struct token *, 2996 unsigned int, char *, unsigned int); 2997 static int comp_set_sample_index(struct context *, const struct token *, 2998 unsigned int, char *, unsigned int); 2999 static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 3000 unsigned int ent, char *buf, unsigned int size); 3001 static int comp_set_modify_field_op(struct context *, const struct token *, 3002 unsigned int, char *, unsigned int); 3003 static int comp_set_modify_field_id(struct context *, const struct token *, 3004 unsigned int, char *, unsigned int); 3005 static int comp_pattern_template_id(struct context *, const struct token *, 3006 unsigned int, char *, unsigned int); 3007 static int comp_actions_template_id(struct context *, const struct token *, 3008 unsigned int, char *, unsigned int); 3009 static int comp_table_id(struct context *, const struct token *, 3010 unsigned int, char *, unsigned int); 3011 static int comp_queue_id(struct context *, const struct token *, 3012 unsigned int, char *, unsigned int); 3013 static int comp_meter_color(struct context *, const struct token *, 3014 unsigned int, char *, unsigned int); 3015 static int comp_insertion_table_type(struct context *, const struct token *, 3016 unsigned int, char *, unsigned int); 3017 static int comp_hash_table_type(struct context *, const struct token *, 3018 unsigned int, char *, unsigned int); 3019 static int 3020 comp_quota_state_name(struct context *ctx, const struct token *token, 3021 unsigned int ent, char *buf, unsigned int size); 3022 static int 3023 comp_quota_mode_name(struct context *ctx, const struct token *token, 3024 unsigned int ent, char *buf, unsigned int size); 3025 static int 3026 comp_quota_update_name(struct context *ctx, const struct token *token, 3027 unsigned int ent, char *buf, unsigned int size); 3028 static int 3029 comp_qu_mode_name(struct context *ctx, const struct token *token, 3030 unsigned int ent, char *buf, unsigned int size); 3031 static int 3032 comp_set_compare_field_id(struct context *ctx, const struct token *token, 3033 unsigned int ent, char *buf, unsigned int size); 3034 static int 3035 comp_set_compare_op(struct context *ctx, const struct token *token, 3036 unsigned int ent, char *buf, unsigned int size); 3037 static int 3038 parse_vc_compare_op(struct context *ctx, const struct token *token, 3039 const char *str, unsigned int len, void *buf, 3040 unsigned int size); 3041 static int 3042 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 3043 const char *str, unsigned int len, void *buf, 3044 unsigned int size); 3045 static int 3046 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 3047 const char *str, unsigned int len, void *buf, 3048 unsigned int size); 3049 3050 struct indlst_conf { 3051 uint32_t id; 3052 uint32_t conf_num; 3053 struct rte_flow_action *actions; 3054 const void **conf; 3055 SLIST_ENTRY(indlst_conf) next; 3056 }; 3057 3058 static const struct indlst_conf *indirect_action_list_conf_get(uint32_t conf_id); 3059 3060 /** Token definitions. */ 3061 static const struct token token_list[] = { 3062 /* Special tokens. */ 3063 [ZERO] = { 3064 .name = "ZERO", 3065 .help = "null entry, abused as the entry point", 3066 .next = NEXT(NEXT_ENTRY(FLOW, ADD)), 3067 }, 3068 [END] = { 3069 .name = "", 3070 .type = "RETURN", 3071 .help = "command may end here", 3072 }, 3073 [START_SET] = { 3074 .name = "START_SET", 3075 .help = "null entry, abused as the entry point for set", 3076 .next = NEXT(NEXT_ENTRY(SET)), 3077 }, 3078 [END_SET] = { 3079 .name = "end_set", 3080 .type = "RETURN", 3081 .help = "set command may end here", 3082 }, 3083 /* Common tokens. */ 3084 [COMMON_INTEGER] = { 3085 .name = "{int}", 3086 .type = "INTEGER", 3087 .help = "integer value", 3088 .call = parse_int, 3089 .comp = comp_none, 3090 }, 3091 [COMMON_UNSIGNED] = { 3092 .name = "{unsigned}", 3093 .type = "UNSIGNED", 3094 .help = "unsigned integer value", 3095 .call = parse_int, 3096 .comp = comp_none, 3097 }, 3098 [COMMON_PREFIX] = { 3099 .name = "{prefix}", 3100 .type = "PREFIX", 3101 .help = "prefix length for bit-mask", 3102 .call = parse_prefix, 3103 .comp = comp_none, 3104 }, 3105 [COMMON_BOOLEAN] = { 3106 .name = "{boolean}", 3107 .type = "BOOLEAN", 3108 .help = "any boolean value", 3109 .call = parse_boolean, 3110 .comp = comp_boolean, 3111 }, 3112 [COMMON_STRING] = { 3113 .name = "{string}", 3114 .type = "STRING", 3115 .help = "fixed string", 3116 .call = parse_string, 3117 .comp = comp_none, 3118 }, 3119 [COMMON_HEX] = { 3120 .name = "{hex}", 3121 .type = "HEX", 3122 .help = "fixed string", 3123 .call = parse_hex, 3124 }, 3125 [COMMON_FILE_PATH] = { 3126 .name = "{file path}", 3127 .type = "STRING", 3128 .help = "file path", 3129 .call = parse_string0, 3130 .comp = comp_none, 3131 }, 3132 [COMMON_MAC_ADDR] = { 3133 .name = "{MAC address}", 3134 .type = "MAC-48", 3135 .help = "standard MAC address notation", 3136 .call = parse_mac_addr, 3137 .comp = comp_none, 3138 }, 3139 [COMMON_IPV4_ADDR] = { 3140 .name = "{IPv4 address}", 3141 .type = "IPV4 ADDRESS", 3142 .help = "standard IPv4 address notation", 3143 .call = parse_ipv4_addr, 3144 .comp = comp_none, 3145 }, 3146 [COMMON_IPV6_ADDR] = { 3147 .name = "{IPv6 address}", 3148 .type = "IPV6 ADDRESS", 3149 .help = "standard IPv6 address notation", 3150 .call = parse_ipv6_addr, 3151 .comp = comp_none, 3152 }, 3153 [COMMON_RULE_ID] = { 3154 .name = "{rule id}", 3155 .type = "RULE ID", 3156 .help = "rule identifier", 3157 .call = parse_int, 3158 .comp = comp_rule_id, 3159 }, 3160 [COMMON_PORT_ID] = { 3161 .name = "{port_id}", 3162 .type = "PORT ID", 3163 .help = "port identifier", 3164 .call = parse_port, 3165 .comp = comp_port, 3166 }, 3167 [COMMON_GROUP_ID] = { 3168 .name = "{group_id}", 3169 .type = "GROUP ID", 3170 .help = "group identifier", 3171 .call = parse_int, 3172 .comp = comp_none, 3173 }, 3174 [COMMON_PRIORITY_LEVEL] = { 3175 .name = "{level}", 3176 .type = "PRIORITY", 3177 .help = "priority level", 3178 .call = parse_int, 3179 .comp = comp_none, 3180 }, 3181 [COMMON_INDIRECT_ACTION_ID] = { 3182 .name = "{indirect_action_id}", 3183 .type = "INDIRECT_ACTION_ID", 3184 .help = "indirect action id", 3185 .call = parse_int, 3186 .comp = comp_none, 3187 }, 3188 [COMMON_PROFILE_ID] = { 3189 .name = "{profile_id}", 3190 .type = "PROFILE_ID", 3191 .help = "profile id", 3192 .call = parse_int, 3193 .comp = comp_none, 3194 }, 3195 [COMMON_POLICY_ID] = { 3196 .name = "{policy_id}", 3197 .type = "POLICY_ID", 3198 .help = "policy id", 3199 .call = parse_int, 3200 .comp = comp_none, 3201 }, 3202 [COMMON_FLEX_TOKEN] = { 3203 .name = "{flex token}", 3204 .type = "flex token", 3205 .help = "flex token", 3206 .call = parse_int, 3207 .comp = comp_none, 3208 }, 3209 [COMMON_FLEX_HANDLE] = { 3210 .name = "{flex handle}", 3211 .type = "FLEX HANDLE", 3212 .help = "fill flex item data", 3213 .call = parse_flex_handle, 3214 .comp = comp_none, 3215 }, 3216 [COMMON_PATTERN_TEMPLATE_ID] = { 3217 .name = "{pattern_template_id}", 3218 .type = "PATTERN_TEMPLATE_ID", 3219 .help = "pattern template id", 3220 .call = parse_int, 3221 .comp = comp_pattern_template_id, 3222 }, 3223 [COMMON_ACTIONS_TEMPLATE_ID] = { 3224 .name = "{actions_template_id}", 3225 .type = "ACTIONS_TEMPLATE_ID", 3226 .help = "actions template id", 3227 .call = parse_int, 3228 .comp = comp_actions_template_id, 3229 }, 3230 [COMMON_TABLE_ID] = { 3231 .name = "{table_id}", 3232 .type = "TABLE_ID", 3233 .help = "table id", 3234 .call = parse_int, 3235 .comp = comp_table_id, 3236 }, 3237 [COMMON_QUEUE_ID] = { 3238 .name = "{queue_id}", 3239 .type = "QUEUE_ID", 3240 .help = "queue id", 3241 .call = parse_int, 3242 .comp = comp_queue_id, 3243 }, 3244 /* Top-level command. */ 3245 [FLOW] = { 3246 .name = "flow", 3247 .type = "{command} {port_id} [{arg} [...]]", 3248 .help = "manage ingress/egress flow rules", 3249 .next = NEXT(NEXT_ENTRY 3250 (INFO, 3251 CONFIGURE, 3252 PATTERN_TEMPLATE, 3253 ACTIONS_TEMPLATE, 3254 TABLE, 3255 FLOW_GROUP, 3256 INDIRECT_ACTION, 3257 VALIDATE, 3258 CREATE, 3259 DESTROY, 3260 UPDATE, 3261 FLUSH, 3262 DUMP, 3263 LIST, 3264 AGED, 3265 QUERY, 3266 ISOLATE, 3267 TUNNEL, 3268 FLEX, 3269 QUEUE, 3270 PUSH, 3271 PULL, 3272 HASH)), 3273 .call = parse_init, 3274 }, 3275 /* Top-level command. */ 3276 [INFO] = { 3277 .name = "info", 3278 .help = "get information about flow engine", 3279 .next = NEXT(NEXT_ENTRY(END), 3280 NEXT_ENTRY(COMMON_PORT_ID)), 3281 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3282 .call = parse_configure, 3283 }, 3284 /* Top-level command. */ 3285 [CONFIGURE] = { 3286 .name = "configure", 3287 .help = "configure flow engine", 3288 .next = NEXT(next_config_attr, 3289 NEXT_ENTRY(COMMON_PORT_ID)), 3290 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3291 .call = parse_configure, 3292 }, 3293 /* Configure arguments. */ 3294 [CONFIG_QUEUES_NUMBER] = { 3295 .name = "queues_number", 3296 .help = "number of queues", 3297 .next = NEXT(next_config_attr, 3298 NEXT_ENTRY(COMMON_UNSIGNED)), 3299 .args = ARGS(ARGS_ENTRY(struct buffer, 3300 args.configure.nb_queue)), 3301 }, 3302 [CONFIG_QUEUES_SIZE] = { 3303 .name = "queues_size", 3304 .help = "number of elements in queues", 3305 .next = NEXT(next_config_attr, 3306 NEXT_ENTRY(COMMON_UNSIGNED)), 3307 .args = ARGS(ARGS_ENTRY(struct buffer, 3308 args.configure.queue_attr.size)), 3309 }, 3310 [CONFIG_COUNTERS_NUMBER] = { 3311 .name = "counters_number", 3312 .help = "number of counters", 3313 .next = NEXT(next_config_attr, 3314 NEXT_ENTRY(COMMON_UNSIGNED)), 3315 .args = ARGS(ARGS_ENTRY(struct buffer, 3316 args.configure.port_attr.nb_counters)), 3317 }, 3318 [CONFIG_AGING_OBJECTS_NUMBER] = { 3319 .name = "aging_counters_number", 3320 .help = "number of aging objects", 3321 .next = NEXT(next_config_attr, 3322 NEXT_ENTRY(COMMON_UNSIGNED)), 3323 .args = ARGS(ARGS_ENTRY(struct buffer, 3324 args.configure.port_attr.nb_aging_objects)), 3325 }, 3326 [CONFIG_QUOTAS_NUMBER] = { 3327 .name = "quotas_number", 3328 .help = "number of quotas", 3329 .next = NEXT(next_config_attr, 3330 NEXT_ENTRY(COMMON_UNSIGNED)), 3331 .args = ARGS(ARGS_ENTRY(struct buffer, 3332 args.configure.port_attr.nb_quotas)), 3333 }, 3334 [CONFIG_METERS_NUMBER] = { 3335 .name = "meters_number", 3336 .help = "number of meters", 3337 .next = NEXT(next_config_attr, 3338 NEXT_ENTRY(COMMON_UNSIGNED)), 3339 .args = ARGS(ARGS_ENTRY(struct buffer, 3340 args.configure.port_attr.nb_meters)), 3341 }, 3342 [CONFIG_CONN_TRACK_NUMBER] = { 3343 .name = "conn_tracks_number", 3344 .help = "number of connection trackings", 3345 .next = NEXT(next_config_attr, 3346 NEXT_ENTRY(COMMON_UNSIGNED)), 3347 .args = ARGS(ARGS_ENTRY(struct buffer, 3348 args.configure.port_attr.nb_conn_tracks)), 3349 }, 3350 [CONFIG_FLAGS] = { 3351 .name = "flags", 3352 .help = "configuration flags", 3353 .next = NEXT(next_config_attr, 3354 NEXT_ENTRY(COMMON_UNSIGNED)), 3355 .args = ARGS(ARGS_ENTRY(struct buffer, 3356 args.configure.port_attr.flags)), 3357 }, 3358 [CONFIG_HOST_PORT] = { 3359 .name = "host_port", 3360 .help = "host port for shared objects", 3361 .next = NEXT(next_config_attr, 3362 NEXT_ENTRY(COMMON_UNSIGNED)), 3363 .args = ARGS(ARGS_ENTRY(struct buffer, 3364 args.configure.port_attr.host_port_id)), 3365 }, 3366 /* Top-level command. */ 3367 [PATTERN_TEMPLATE] = { 3368 .name = "pattern_template", 3369 .type = "{command} {port_id} [{arg} [...]]", 3370 .help = "manage pattern templates", 3371 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3372 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3373 .call = parse_template, 3374 }, 3375 /* Sub-level commands. */ 3376 [PATTERN_TEMPLATE_CREATE] = { 3377 .name = "create", 3378 .help = "create pattern template", 3379 .next = NEXT(next_pt_attr), 3380 .call = parse_template, 3381 }, 3382 [PATTERN_TEMPLATE_DESTROY] = { 3383 .name = "destroy", 3384 .help = "destroy pattern template", 3385 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), 3386 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3387 .call = parse_template_destroy, 3388 }, 3389 /* Pattern template arguments. */ 3390 [PATTERN_TEMPLATE_CREATE_ID] = { 3391 .name = "pattern_template_id", 3392 .help = "specify a pattern template id to create", 3393 .next = NEXT(next_pt_attr, 3394 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3395 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), 3396 }, 3397 [PATTERN_TEMPLATE_DESTROY_ID] = { 3398 .name = "pattern_template", 3399 .help = "specify a pattern template id to destroy", 3400 .next = NEXT(next_pt_destroy_attr, 3401 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3402 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3403 args.templ_destroy.template_id)), 3404 .call = parse_template_destroy, 3405 }, 3406 [PATTERN_TEMPLATE_RELAXED_MATCHING] = { 3407 .name = "relaxed", 3408 .help = "is matching relaxed", 3409 .next = NEXT(next_pt_attr, 3410 NEXT_ENTRY(COMMON_BOOLEAN)), 3411 .args = ARGS(ARGS_ENTRY_BF(struct buffer, 3412 args.vc.attr.reserved, 1)), 3413 }, 3414 [PATTERN_TEMPLATE_INGRESS] = { 3415 .name = "ingress", 3416 .help = "attribute pattern to ingress", 3417 .next = NEXT(next_pt_attr), 3418 .call = parse_template, 3419 }, 3420 [PATTERN_TEMPLATE_EGRESS] = { 3421 .name = "egress", 3422 .help = "attribute pattern to egress", 3423 .next = NEXT(next_pt_attr), 3424 .call = parse_template, 3425 }, 3426 [PATTERN_TEMPLATE_TRANSFER] = { 3427 .name = "transfer", 3428 .help = "attribute pattern to transfer", 3429 .next = NEXT(next_pt_attr), 3430 .call = parse_template, 3431 }, 3432 [PATTERN_TEMPLATE_SPEC] = { 3433 .name = "template", 3434 .help = "specify item to create pattern template", 3435 .next = NEXT(next_item), 3436 }, 3437 /* Top-level command. */ 3438 [ACTIONS_TEMPLATE] = { 3439 .name = "actions_template", 3440 .type = "{command} {port_id} [{arg} [...]]", 3441 .help = "manage actions templates", 3442 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3443 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3444 .call = parse_template, 3445 }, 3446 /* Sub-level commands. */ 3447 [ACTIONS_TEMPLATE_CREATE] = { 3448 .name = "create", 3449 .help = "create actions template", 3450 .next = NEXT(next_at_attr), 3451 .call = parse_template, 3452 }, 3453 [ACTIONS_TEMPLATE_DESTROY] = { 3454 .name = "destroy", 3455 .help = "destroy actions template", 3456 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), 3457 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3458 .call = parse_template_destroy, 3459 }, 3460 /* Actions template arguments. */ 3461 [ACTIONS_TEMPLATE_CREATE_ID] = { 3462 .name = "actions_template_id", 3463 .help = "specify an actions template id to create", 3464 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), 3465 NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), 3466 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3467 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), 3468 }, 3469 [ACTIONS_TEMPLATE_DESTROY_ID] = { 3470 .name = "actions_template", 3471 .help = "specify an actions template id to destroy", 3472 .next = NEXT(next_at_destroy_attr, 3473 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3474 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3475 args.templ_destroy.template_id)), 3476 .call = parse_template_destroy, 3477 }, 3478 [ACTIONS_TEMPLATE_INGRESS] = { 3479 .name = "ingress", 3480 .help = "attribute actions to ingress", 3481 .next = NEXT(next_at_attr), 3482 .call = parse_template, 3483 }, 3484 [ACTIONS_TEMPLATE_EGRESS] = { 3485 .name = "egress", 3486 .help = "attribute actions to egress", 3487 .next = NEXT(next_at_attr), 3488 .call = parse_template, 3489 }, 3490 [ACTIONS_TEMPLATE_TRANSFER] = { 3491 .name = "transfer", 3492 .help = "attribute actions to transfer", 3493 .next = NEXT(next_at_attr), 3494 .call = parse_template, 3495 }, 3496 [ACTIONS_TEMPLATE_SPEC] = { 3497 .name = "template", 3498 .help = "specify action to create actions template", 3499 .next = NEXT(next_action), 3500 .call = parse_template, 3501 }, 3502 [ACTIONS_TEMPLATE_MASK] = { 3503 .name = "mask", 3504 .help = "specify action mask to create actions template", 3505 .next = NEXT(next_action), 3506 .call = parse_template, 3507 }, 3508 /* Top-level command. */ 3509 [TABLE] = { 3510 .name = "template_table", 3511 .type = "{command} {port_id} [{arg} [...]]", 3512 .help = "manage template tables", 3513 .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3514 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3515 .call = parse_table, 3516 }, 3517 /* Sub-level commands. */ 3518 [TABLE_CREATE] = { 3519 .name = "create", 3520 .help = "create template table", 3521 .next = NEXT(next_table_attr), 3522 .call = parse_table, 3523 }, 3524 [TABLE_DESTROY] = { 3525 .name = "destroy", 3526 .help = "destroy template table", 3527 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3528 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3529 .call = parse_table_destroy, 3530 }, 3531 [TABLE_RESIZE] = { 3532 .name = "resize", 3533 .help = "resize template table", 3534 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_ID)), 3535 .call = parse_table 3536 }, 3537 [TABLE_RESIZE_COMPLETE] = { 3538 .name = "resize_complete", 3539 .help = "complete table resize", 3540 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3541 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3542 .call = parse_table_destroy, 3543 }, 3544 /* Table arguments. */ 3545 [TABLE_CREATE_ID] = { 3546 .name = "table_id", 3547 .help = "specify table id to create", 3548 .next = NEXT(next_table_attr, 3549 NEXT_ENTRY(COMMON_TABLE_ID)), 3550 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3551 }, 3552 [TABLE_DESTROY_ID] = { 3553 .name = "table", 3554 .help = "table id", 3555 .next = NEXT(next_table_destroy_attr, 3556 NEXT_ENTRY(COMMON_TABLE_ID)), 3557 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3558 args.table_destroy.table_id)), 3559 .call = parse_table_destroy, 3560 }, 3561 [TABLE_RESIZE_ID] = { 3562 .name = "table_resize_id", 3563 .help = "table resize id", 3564 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_RULES_NUMBER), 3565 NEXT_ENTRY(COMMON_TABLE_ID)), 3566 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3567 .call = parse_table 3568 }, 3569 [TABLE_RESIZE_RULES_NUMBER] = { 3570 .name = "table_resize_rules_num", 3571 .help = "table resize rules number", 3572 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_UNSIGNED)), 3573 .args = ARGS(ARGS_ENTRY(struct buffer, 3574 args.table.attr.nb_flows)), 3575 .call = parse_table 3576 }, 3577 [TABLE_INSERTION_TYPE] = { 3578 .name = "insertion_type", 3579 .help = "specify insertion type", 3580 .next = NEXT(next_table_attr, 3581 NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)), 3582 .args = ARGS(ARGS_ENTRY(struct buffer, 3583 args.table.attr.insertion_type)), 3584 }, 3585 [TABLE_INSERTION_TYPE_NAME] = { 3586 .name = "insertion_type_name", 3587 .help = "insertion type name", 3588 .call = parse_insertion_table_type, 3589 .comp = comp_insertion_table_type, 3590 }, 3591 [TABLE_HASH_FUNC] = { 3592 .name = "hash_func", 3593 .help = "specify hash calculation function", 3594 .next = NEXT(next_table_attr, 3595 NEXT_ENTRY(TABLE_HASH_FUNC_NAME)), 3596 .args = ARGS(ARGS_ENTRY(struct buffer, 3597 args.table.attr.hash_func)), 3598 }, 3599 [TABLE_HASH_FUNC_NAME] = { 3600 .name = "hash_func_name", 3601 .help = "hash calculation function name", 3602 .call = parse_hash_table_type, 3603 .comp = comp_hash_table_type, 3604 }, 3605 [TABLE_GROUP] = { 3606 .name = "group", 3607 .help = "specify a group", 3608 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3609 .args = ARGS(ARGS_ENTRY(struct buffer, 3610 args.table.attr.flow_attr.group)), 3611 }, 3612 [TABLE_PRIORITY] = { 3613 .name = "priority", 3614 .help = "specify a priority level", 3615 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 3616 .args = ARGS(ARGS_ENTRY(struct buffer, 3617 args.table.attr.flow_attr.priority)), 3618 }, 3619 [TABLE_EGRESS] = { 3620 .name = "egress", 3621 .help = "affect rule to egress", 3622 .next = NEXT(next_table_attr), 3623 .call = parse_table, 3624 }, 3625 [TABLE_INGRESS] = { 3626 .name = "ingress", 3627 .help = "affect rule to ingress", 3628 .next = NEXT(next_table_attr), 3629 .call = parse_table, 3630 }, 3631 [TABLE_TRANSFER] = { 3632 .name = "transfer", 3633 .help = "affect rule to transfer", 3634 .next = NEXT(next_table_attr), 3635 .call = parse_table, 3636 }, 3637 [TABLE_TRANSFER_WIRE_ORIG] = { 3638 .name = "wire_orig", 3639 .help = "affect rule direction to transfer", 3640 .next = NEXT(next_table_attr), 3641 .call = parse_table, 3642 }, 3643 [TABLE_TRANSFER_VPORT_ORIG] = { 3644 .name = "vport_orig", 3645 .help = "affect rule direction to transfer", 3646 .next = NEXT(next_table_attr), 3647 .call = parse_table, 3648 }, 3649 [TABLE_RESIZABLE] = { 3650 .name = "resizable", 3651 .help = "set resizable attribute", 3652 .next = NEXT(next_table_attr), 3653 .call = parse_table, 3654 }, 3655 [TABLE_RULES_NUMBER] = { 3656 .name = "rules_number", 3657 .help = "number of rules in table", 3658 .next = NEXT(next_table_attr, 3659 NEXT_ENTRY(COMMON_UNSIGNED)), 3660 .args = ARGS(ARGS_ENTRY(struct buffer, 3661 args.table.attr.nb_flows)), 3662 .call = parse_table, 3663 }, 3664 [TABLE_PATTERN_TEMPLATE] = { 3665 .name = "pattern_template", 3666 .help = "specify pattern template id", 3667 .next = NEXT(next_table_attr, 3668 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3669 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3670 args.table.pat_templ_id)), 3671 .call = parse_table, 3672 }, 3673 [TABLE_ACTIONS_TEMPLATE] = { 3674 .name = "actions_template", 3675 .help = "specify actions template id", 3676 .next = NEXT(next_table_attr, 3677 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3678 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3679 args.table.act_templ_id)), 3680 .call = parse_table, 3681 }, 3682 /* Top-level command. */ 3683 [FLOW_GROUP] = { 3684 .name = "group", 3685 .help = "manage flow groups", 3686 .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), 3687 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3688 .call = parse_group, 3689 }, 3690 /* Sub-level commands. */ 3691 [GROUP_SET_MISS_ACTIONS] = { 3692 .name = "set_miss_actions", 3693 .help = "set group miss actions", 3694 .next = NEXT(next_action), 3695 .call = parse_group, 3696 }, 3697 /* Group arguments */ 3698 [GROUP_ID] = { 3699 .name = "group_id", 3700 .help = "group id", 3701 .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3702 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3703 }, 3704 [GROUP_INGRESS] = { 3705 .name = "ingress", 3706 .help = "group ingress attr", 3707 .next = NEXT(next_group_attr), 3708 .call = parse_group, 3709 }, 3710 [GROUP_EGRESS] = { 3711 .name = "egress", 3712 .help = "group egress attr", 3713 .next = NEXT(next_group_attr), 3714 .call = parse_group, 3715 }, 3716 [GROUP_TRANSFER] = { 3717 .name = "transfer", 3718 .help = "group transfer attr", 3719 .next = NEXT(next_group_attr), 3720 .call = parse_group, 3721 }, 3722 /* Top-level command. */ 3723 [QUEUE] = { 3724 .name = "queue", 3725 .help = "queue a flow rule operation", 3726 .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3727 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3728 .call = parse_qo, 3729 }, 3730 /* Sub-level commands. */ 3731 [QUEUE_CREATE] = { 3732 .name = "create", 3733 .help = "create a flow rule", 3734 .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), 3735 NEXT_ENTRY(COMMON_QUEUE_ID)), 3736 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3737 .call = parse_qo, 3738 }, 3739 [QUEUE_DESTROY] = { 3740 .name = "destroy", 3741 .help = "destroy a flow rule", 3742 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_POSTPONE), 3743 NEXT_ENTRY(COMMON_QUEUE_ID)), 3744 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3745 .call = parse_qo_destroy, 3746 }, 3747 [QUEUE_FLOW_UPDATE_RESIZED] = { 3748 .name = "update_resized", 3749 .help = "update a flow after table resize", 3750 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3751 NEXT_ENTRY(COMMON_QUEUE_ID)), 3752 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3753 .call = parse_qo_destroy, 3754 }, 3755 [QUEUE_UPDATE] = { 3756 .name = "update", 3757 .help = "update a flow rule", 3758 .next = NEXT(NEXT_ENTRY(QUEUE_UPDATE_ID), 3759 NEXT_ENTRY(COMMON_QUEUE_ID)), 3760 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3761 .call = parse_qo, 3762 }, 3763 [QUEUE_AGED] = { 3764 .name = "aged", 3765 .help = "list and destroy aged flows", 3766 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), 3767 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3768 .call = parse_aged, 3769 }, 3770 [QUEUE_INDIRECT_ACTION] = { 3771 .name = "indirect_action", 3772 .help = "queue indirect actions", 3773 .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), 3774 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3775 .call = parse_qia, 3776 }, 3777 /* Queue arguments. */ 3778 [QUEUE_TEMPLATE_TABLE] = { 3779 .name = "template_table", 3780 .help = "specify table id", 3781 .next = NEXT(next_async_insert_subcmd, 3782 NEXT_ENTRY(COMMON_TABLE_ID)), 3783 .args = ARGS(ARGS_ENTRY(struct buffer, 3784 args.vc.table_id)), 3785 .call = parse_qo, 3786 }, 3787 [QUEUE_PATTERN_TEMPLATE] = { 3788 .name = "pattern_template", 3789 .help = "specify pattern template index", 3790 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3791 NEXT_ENTRY(COMMON_UNSIGNED)), 3792 .args = ARGS(ARGS_ENTRY(struct buffer, 3793 args.vc.pat_templ_id)), 3794 .call = parse_qo, 3795 }, 3796 [QUEUE_ACTIONS_TEMPLATE] = { 3797 .name = "actions_template", 3798 .help = "specify actions template index", 3799 .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), 3800 NEXT_ENTRY(COMMON_UNSIGNED)), 3801 .args = ARGS(ARGS_ENTRY(struct buffer, 3802 args.vc.act_templ_id)), 3803 .call = parse_qo, 3804 }, 3805 [QUEUE_RULE_ID] = { 3806 .name = "rule_index", 3807 .help = "specify flow rule index", 3808 .next = NEXT(next_async_pattern_subcmd, 3809 NEXT_ENTRY(COMMON_UNSIGNED)), 3810 .args = ARGS(ARGS_ENTRY(struct buffer, 3811 args.vc.rule_id)), 3812 .call = parse_qo, 3813 }, 3814 [QUEUE_CREATE_POSTPONE] = { 3815 .name = "postpone", 3816 .help = "postpone create operation", 3817 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3818 NEXT_ENTRY(COMMON_BOOLEAN)), 3819 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3820 .call = parse_qo, 3821 }, 3822 [QUEUE_DESTROY_POSTPONE] = { 3823 .name = "postpone", 3824 .help = "postpone destroy operation", 3825 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3826 NEXT_ENTRY(COMMON_BOOLEAN)), 3827 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3828 .call = parse_qo_destroy, 3829 }, 3830 [QUEUE_DESTROY_ID] = { 3831 .name = "rule", 3832 .help = "specify rule id to destroy", 3833 .next = NEXT(next_queue_destroy_attr, 3834 NEXT_ENTRY(COMMON_UNSIGNED)), 3835 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3836 args.destroy.rule)), 3837 .call = parse_qo_destroy, 3838 }, 3839 [QUEUE_UPDATE_ID] = { 3840 .name = "rule", 3841 .help = "specify rule id to update", 3842 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3843 NEXT_ENTRY(COMMON_UNSIGNED)), 3844 .args = ARGS(ARGS_ENTRY(struct buffer, 3845 args.vc.rule_id)), 3846 .call = parse_qo, 3847 }, 3848 /* Queue indirect action arguments */ 3849 [QUEUE_INDIRECT_ACTION_CREATE] = { 3850 .name = "create", 3851 .help = "create indirect action", 3852 .next = NEXT(next_qia_create_attr), 3853 .call = parse_qia, 3854 }, 3855 [QUEUE_INDIRECT_ACTION_UPDATE] = { 3856 .name = "update", 3857 .help = "update indirect action", 3858 .next = NEXT(next_qia_update_attr, 3859 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3860 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3861 .call = parse_qia, 3862 }, 3863 [QUEUE_INDIRECT_ACTION_DESTROY] = { 3864 .name = "destroy", 3865 .help = "destroy indirect action", 3866 .next = NEXT(next_qia_destroy_attr), 3867 .call = parse_qia_destroy, 3868 }, 3869 [QUEUE_INDIRECT_ACTION_QUERY] = { 3870 .name = "query", 3871 .help = "query indirect action", 3872 .next = NEXT(next_qia_query_attr, 3873 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3874 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3875 .call = parse_qia, 3876 }, 3877 /* Indirect action destroy arguments. */ 3878 [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { 3879 .name = "postpone", 3880 .help = "postpone destroy operation", 3881 .next = NEXT(next_qia_destroy_attr, 3882 NEXT_ENTRY(COMMON_BOOLEAN)), 3883 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3884 }, 3885 [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { 3886 .name = "action_id", 3887 .help = "specify a indirect action id to destroy", 3888 .next = NEXT(next_qia_destroy_attr, 3889 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3890 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3891 args.ia_destroy.action_id)), 3892 .call = parse_qia_destroy, 3893 }, 3894 [QUEUE_INDIRECT_ACTION_QUERY_UPDATE] = { 3895 .name = "query_update", 3896 .help = "indirect query [and|or] update action", 3897 .next = NEXT(next_qia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3898 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3899 .call = parse_qia 3900 }, 3901 [QUEUE_INDIRECT_ACTION_QU_MODE] = { 3902 .name = "mode", 3903 .help = "indirect query [and|or] update action", 3904 .next = NEXT(next_qia_qu_attr, 3905 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 3906 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 3907 .call = parse_qia 3908 }, 3909 /* Indirect action update arguments. */ 3910 [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { 3911 .name = "postpone", 3912 .help = "postpone update operation", 3913 .next = NEXT(next_qia_update_attr, 3914 NEXT_ENTRY(COMMON_BOOLEAN)), 3915 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3916 }, 3917 /* Indirect action update arguments. */ 3918 [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { 3919 .name = "postpone", 3920 .help = "postpone query operation", 3921 .next = NEXT(next_qia_query_attr, 3922 NEXT_ENTRY(COMMON_BOOLEAN)), 3923 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3924 }, 3925 /* Indirect action create arguments. */ 3926 [QUEUE_INDIRECT_ACTION_CREATE_ID] = { 3927 .name = "action_id", 3928 .help = "specify a indirect action id to create", 3929 .next = NEXT(next_qia_create_attr, 3930 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3931 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3932 }, 3933 [QUEUE_INDIRECT_ACTION_INGRESS] = { 3934 .name = "ingress", 3935 .help = "affect rule to ingress", 3936 .next = NEXT(next_qia_create_attr), 3937 .call = parse_qia, 3938 }, 3939 [QUEUE_INDIRECT_ACTION_EGRESS] = { 3940 .name = "egress", 3941 .help = "affect rule to egress", 3942 .next = NEXT(next_qia_create_attr), 3943 .call = parse_qia, 3944 }, 3945 [QUEUE_INDIRECT_ACTION_TRANSFER] = { 3946 .name = "transfer", 3947 .help = "affect rule to transfer", 3948 .next = NEXT(next_qia_create_attr), 3949 .call = parse_qia, 3950 }, 3951 [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { 3952 .name = "postpone", 3953 .help = "postpone create operation", 3954 .next = NEXT(next_qia_create_attr, 3955 NEXT_ENTRY(COMMON_BOOLEAN)), 3956 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3957 }, 3958 [QUEUE_INDIRECT_ACTION_SPEC] = { 3959 .name = "action", 3960 .help = "specify action to create indirect handle", 3961 .next = NEXT(next_action), 3962 }, 3963 [QUEUE_INDIRECT_ACTION_LIST] = { 3964 .name = "list", 3965 .help = "specify actions for indirect handle list", 3966 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 3967 .call = parse_qia, 3968 }, 3969 /* Top-level command. */ 3970 [PUSH] = { 3971 .name = "push", 3972 .help = "push enqueued operations", 3973 .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3974 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3975 .call = parse_push, 3976 }, 3977 /* Sub-level commands. */ 3978 [PUSH_QUEUE] = { 3979 .name = "queue", 3980 .help = "specify queue id", 3981 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3982 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3983 }, 3984 /* Top-level command. */ 3985 [PULL] = { 3986 .name = "pull", 3987 .help = "pull flow operations results", 3988 .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3989 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3990 .call = parse_pull, 3991 }, 3992 /* Sub-level commands. */ 3993 [PULL_QUEUE] = { 3994 .name = "queue", 3995 .help = "specify queue id", 3996 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3997 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3998 }, 3999 /* Top-level command. */ 4000 [HASH] = { 4001 .name = "hash", 4002 .help = "calculate hash for a given pattern in a given template table", 4003 .next = NEXT(next_hash_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4004 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4005 .call = parse_hash, 4006 }, 4007 /* Sub-level commands. */ 4008 [HASH_CALC_TABLE] = { 4009 .name = "template_table", 4010 .help = "specify table id", 4011 .next = NEXT(NEXT_ENTRY(HASH_CALC_PATTERN_INDEX), 4012 NEXT_ENTRY(COMMON_TABLE_ID)), 4013 .args = ARGS(ARGS_ENTRY(struct buffer, 4014 args.vc.table_id)), 4015 .call = parse_hash, 4016 }, 4017 [HASH_CALC_ENCAP] = { 4018 .name = "encap", 4019 .help = "calculates encap hash", 4020 .next = NEXT(next_hash_encap_dest_subcmd), 4021 .call = parse_hash, 4022 }, 4023 [HASH_CALC_PATTERN_INDEX] = { 4024 .name = "pattern_template", 4025 .help = "specify pattern template id", 4026 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 4027 NEXT_ENTRY(COMMON_UNSIGNED)), 4028 .args = ARGS(ARGS_ENTRY(struct buffer, 4029 args.vc.pat_templ_id)), 4030 .call = parse_hash, 4031 }, 4032 [ENCAP_HASH_FIELD_SRC_PORT] = { 4033 .name = "hash_field_sport", 4034 .help = "the encap hash field is src port", 4035 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 4036 .call = parse_hash, 4037 }, 4038 [ENCAP_HASH_FIELD_GRE_FLOW_ID] = { 4039 .name = "hash_field_flow_id", 4040 .help = "the encap hash field is NVGRE flow id", 4041 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 4042 .call = parse_hash, 4043 }, 4044 /* Top-level command. */ 4045 [INDIRECT_ACTION] = { 4046 .name = "indirect_action", 4047 .type = "{command} {port_id} [{arg} [...]]", 4048 .help = "manage indirect actions", 4049 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4050 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4051 .call = parse_ia, 4052 }, 4053 /* Sub-level commands. */ 4054 [INDIRECT_ACTION_CREATE] = { 4055 .name = "create", 4056 .help = "create indirect action", 4057 .next = NEXT(next_ia_create_attr), 4058 .call = parse_ia, 4059 }, 4060 [INDIRECT_ACTION_UPDATE] = { 4061 .name = "update", 4062 .help = "update indirect action", 4063 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), 4064 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4065 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 4066 .call = parse_ia, 4067 }, 4068 [INDIRECT_ACTION_DESTROY] = { 4069 .name = "destroy", 4070 .help = "destroy indirect action", 4071 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), 4072 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4073 .call = parse_ia_destroy, 4074 }, 4075 [INDIRECT_ACTION_QUERY] = { 4076 .name = "query", 4077 .help = "query indirect action", 4078 .next = NEXT(NEXT_ENTRY(END), 4079 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4080 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4081 .call = parse_ia, 4082 }, 4083 [INDIRECT_ACTION_QUERY_UPDATE] = { 4084 .name = "query_update", 4085 .help = "query [and|or] update", 4086 .next = NEXT(next_ia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4087 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4088 .call = parse_ia 4089 }, 4090 [INDIRECT_ACTION_QU_MODE] = { 4091 .name = "mode", 4092 .help = "query_update mode", 4093 .next = NEXT(next_ia_qu_attr, 4094 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 4095 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 4096 .call = parse_ia, 4097 }, 4098 [INDIRECT_ACTION_QU_MODE_NAME] = { 4099 .name = "mode_name", 4100 .help = "query-update mode name", 4101 .call = parse_qu_mode_name, 4102 .comp = comp_qu_mode_name, 4103 }, 4104 [VALIDATE] = { 4105 .name = "validate", 4106 .help = "check whether a flow rule can be created", 4107 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4108 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4109 .call = parse_vc, 4110 }, 4111 [CREATE] = { 4112 .name = "create", 4113 .help = "create a flow rule", 4114 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4115 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4116 .call = parse_vc, 4117 }, 4118 [DESTROY] = { 4119 .name = "destroy", 4120 .help = "destroy specific flow rules", 4121 .next = NEXT(next_destroy_attr, 4122 NEXT_ENTRY(COMMON_PORT_ID)), 4123 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4124 .call = parse_destroy, 4125 }, 4126 [UPDATE] = { 4127 .name = "update", 4128 .help = "update a flow rule with new actions", 4129 .next = NEXT(NEXT_ENTRY(VC_IS_USER_ID, END), 4130 NEXT_ENTRY(ACTIONS), 4131 NEXT_ENTRY(COMMON_RULE_ID), 4132 NEXT_ENTRY(COMMON_PORT_ID)), 4133 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.rule_id), 4134 ARGS_ENTRY(struct buffer, port)), 4135 .call = parse_vc, 4136 }, 4137 [FLUSH] = { 4138 .name = "flush", 4139 .help = "destroy all flow rules", 4140 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4141 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4142 .call = parse_flush, 4143 }, 4144 [DUMP] = { 4145 .name = "dump", 4146 .help = "dump single/all flow rules to file", 4147 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4148 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4149 .call = parse_dump, 4150 }, 4151 [QUERY] = { 4152 .name = "query", 4153 .help = "query an existing flow rule", 4154 .next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION), 4155 NEXT_ENTRY(COMMON_RULE_ID), 4156 NEXT_ENTRY(COMMON_PORT_ID)), 4157 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), 4158 ARGS_ENTRY(struct buffer, args.query.rule), 4159 ARGS_ENTRY(struct buffer, port)), 4160 .call = parse_query, 4161 }, 4162 [LIST] = { 4163 .name = "list", 4164 .help = "list existing flow rules", 4165 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4166 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4167 .call = parse_list, 4168 }, 4169 [AGED] = { 4170 .name = "aged", 4171 .help = "list and destroy aged flows", 4172 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4173 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4174 .call = parse_aged, 4175 }, 4176 [ISOLATE] = { 4177 .name = "isolate", 4178 .help = "restrict ingress traffic to the defined flow rules", 4179 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), 4180 NEXT_ENTRY(COMMON_PORT_ID)), 4181 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), 4182 ARGS_ENTRY(struct buffer, port)), 4183 .call = parse_isolate, 4184 }, 4185 [FLEX] = { 4186 .name = "flex_item", 4187 .help = "flex item API", 4188 .next = NEXT(next_flex_item), 4189 .call = parse_flex, 4190 }, 4191 [FLEX_ITEM_INIT] = { 4192 .name = "init", 4193 .help = "flex item init", 4194 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4195 ARGS_ENTRY(struct buffer, port)), 4196 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4197 NEXT_ENTRY(COMMON_PORT_ID)), 4198 .call = parse_flex 4199 }, 4200 [FLEX_ITEM_CREATE] = { 4201 .name = "create", 4202 .help = "flex item create", 4203 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), 4204 ARGS_ENTRY(struct buffer, args.flex.token), 4205 ARGS_ENTRY(struct buffer, port)), 4206 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), 4207 NEXT_ENTRY(COMMON_FLEX_TOKEN), 4208 NEXT_ENTRY(COMMON_PORT_ID)), 4209 .call = parse_flex 4210 }, 4211 [FLEX_ITEM_DESTROY] = { 4212 .name = "destroy", 4213 .help = "flex item destroy", 4214 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4215 ARGS_ENTRY(struct buffer, port)), 4216 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4217 NEXT_ENTRY(COMMON_PORT_ID)), 4218 .call = parse_flex 4219 }, 4220 [TUNNEL] = { 4221 .name = "tunnel", 4222 .help = "new tunnel API", 4223 .next = NEXT(NEXT_ENTRY 4224 (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), 4225 .call = parse_tunnel, 4226 }, 4227 /* Tunnel arguments. */ 4228 [TUNNEL_CREATE] = { 4229 .name = "create", 4230 .help = "create new tunnel object", 4231 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), 4232 NEXT_ENTRY(COMMON_PORT_ID)), 4233 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4234 .call = parse_tunnel, 4235 }, 4236 [TUNNEL_CREATE_TYPE] = { 4237 .name = "type", 4238 .help = "create new tunnel", 4239 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), 4240 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), 4241 .call = parse_tunnel, 4242 }, 4243 [TUNNEL_DESTROY] = { 4244 .name = "destroy", 4245 .help = "destroy tunnel", 4246 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), 4247 NEXT_ENTRY(COMMON_PORT_ID)), 4248 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4249 .call = parse_tunnel, 4250 }, 4251 [TUNNEL_DESTROY_ID] = { 4252 .name = "id", 4253 .help = "tunnel identifier to destroy", 4254 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), 4255 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4256 .call = parse_tunnel, 4257 }, 4258 [TUNNEL_LIST] = { 4259 .name = "list", 4260 .help = "list existing tunnels", 4261 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4262 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4263 .call = parse_tunnel, 4264 }, 4265 /* Destroy arguments. */ 4266 [DESTROY_RULE] = { 4267 .name = "rule", 4268 .help = "specify a rule identifier", 4269 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4270 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), 4271 .call = parse_destroy, 4272 }, 4273 [DESTROY_IS_USER_ID] = { 4274 .name = "user_id", 4275 .help = "rule identifier is user-id", 4276 .next = NEXT(next_destroy_attr), 4277 .call = parse_destroy, 4278 }, 4279 /* Dump arguments. */ 4280 [DUMP_ALL] = { 4281 .name = "all", 4282 .help = "dump all", 4283 .next = NEXT(next_dump_attr), 4284 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), 4285 .call = parse_dump, 4286 }, 4287 [DUMP_ONE] = { 4288 .name = "rule", 4289 .help = "dump one rule", 4290 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4291 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), 4292 ARGS_ENTRY(struct buffer, args.dump.rule)), 4293 .call = parse_dump, 4294 }, 4295 [DUMP_IS_USER_ID] = { 4296 .name = "user_id", 4297 .help = "rule identifier is user-id", 4298 .next = NEXT(next_dump_subcmd), 4299 .call = parse_dump, 4300 }, 4301 /* Query arguments. */ 4302 [QUERY_ACTION] = { 4303 .name = "{action}", 4304 .type = "ACTION", 4305 .help = "action to query, must be part of the rule", 4306 .call = parse_action, 4307 .comp = comp_action, 4308 }, 4309 [QUERY_IS_USER_ID] = { 4310 .name = "user_id", 4311 .help = "rule identifier is user-id", 4312 .next = NEXT(next_query_attr), 4313 .call = parse_query, 4314 }, 4315 /* List arguments. */ 4316 [LIST_GROUP] = { 4317 .name = "group", 4318 .help = "specify a group", 4319 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4320 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), 4321 .call = parse_list, 4322 }, 4323 [AGED_DESTROY] = { 4324 .name = "destroy", 4325 .help = "specify aged flows need be destroyed", 4326 .call = parse_aged, 4327 .comp = comp_none, 4328 }, 4329 /* Validate/create attributes. */ 4330 [VC_GROUP] = { 4331 .name = "group", 4332 .help = "specify a group", 4333 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4334 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), 4335 .call = parse_vc, 4336 }, 4337 [VC_PRIORITY] = { 4338 .name = "priority", 4339 .help = "specify a priority level", 4340 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 4341 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), 4342 .call = parse_vc, 4343 }, 4344 [VC_INGRESS] = { 4345 .name = "ingress", 4346 .help = "affect rule to ingress", 4347 .next = NEXT(next_vc_attr), 4348 .call = parse_vc, 4349 }, 4350 [VC_EGRESS] = { 4351 .name = "egress", 4352 .help = "affect rule to egress", 4353 .next = NEXT(next_vc_attr), 4354 .call = parse_vc, 4355 }, 4356 [VC_TRANSFER] = { 4357 .name = "transfer", 4358 .help = "apply rule directly to endpoints found in pattern", 4359 .next = NEXT(next_vc_attr), 4360 .call = parse_vc, 4361 }, 4362 [VC_TUNNEL_SET] = { 4363 .name = "tunnel_set", 4364 .help = "tunnel steer rule", 4365 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4366 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4367 .call = parse_vc, 4368 }, 4369 [VC_TUNNEL_MATCH] = { 4370 .name = "tunnel_match", 4371 .help = "tunnel match rule", 4372 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4373 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4374 .call = parse_vc, 4375 }, 4376 [VC_USER_ID] = { 4377 .name = "user_id", 4378 .help = "specify a user id to create", 4379 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4380 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)), 4381 .call = parse_vc, 4382 }, 4383 [VC_IS_USER_ID] = { 4384 .name = "user_id", 4385 .help = "rule identifier is user-id", 4386 .call = parse_vc, 4387 }, 4388 /* Validate/create pattern. */ 4389 [ITEM_PATTERN] = { 4390 .name = "pattern", 4391 .help = "submit a list of pattern items", 4392 .next = NEXT(next_item), 4393 .call = parse_vc, 4394 }, 4395 [ITEM_PARAM_IS] = { 4396 .name = "is", 4397 .help = "match value perfectly (with full bit-mask)", 4398 .call = parse_vc_spec, 4399 }, 4400 [ITEM_PARAM_SPEC] = { 4401 .name = "spec", 4402 .help = "match value according to configured bit-mask", 4403 .call = parse_vc_spec, 4404 }, 4405 [ITEM_PARAM_LAST] = { 4406 .name = "last", 4407 .help = "specify upper bound to establish a range", 4408 .call = parse_vc_spec, 4409 }, 4410 [ITEM_PARAM_MASK] = { 4411 .name = "mask", 4412 .help = "specify bit-mask with relevant bits set to one", 4413 .call = parse_vc_spec, 4414 }, 4415 [ITEM_PARAM_PREFIX] = { 4416 .name = "prefix", 4417 .help = "generate bit-mask from a prefix length", 4418 .call = parse_vc_spec, 4419 }, 4420 [ITEM_NEXT] = { 4421 .name = "/", 4422 .help = "specify next pattern item", 4423 .next = NEXT(next_item), 4424 }, 4425 [ITEM_END] = { 4426 .name = "end", 4427 .help = "end list of pattern items", 4428 .priv = PRIV_ITEM(END, 0), 4429 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 4430 .call = parse_vc, 4431 }, 4432 [ITEM_VOID] = { 4433 .name = "void", 4434 .help = "no-op pattern item", 4435 .priv = PRIV_ITEM(VOID, 0), 4436 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4437 .call = parse_vc, 4438 }, 4439 [ITEM_INVERT] = { 4440 .name = "invert", 4441 .help = "perform actions when pattern does not match", 4442 .priv = PRIV_ITEM(INVERT, 0), 4443 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4444 .call = parse_vc, 4445 }, 4446 [ITEM_ANY] = { 4447 .name = "any", 4448 .help = "match any protocol for the current layer", 4449 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), 4450 .next = NEXT(item_any), 4451 .call = parse_vc, 4452 }, 4453 [ITEM_ANY_NUM] = { 4454 .name = "num", 4455 .help = "number of layers covered", 4456 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4457 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), 4458 }, 4459 [ITEM_PORT_ID] = { 4460 .name = "port_id", 4461 .help = "match traffic from/to a given DPDK port ID", 4462 .priv = PRIV_ITEM(PORT_ID, 4463 sizeof(struct rte_flow_item_port_id)), 4464 .next = NEXT(item_port_id), 4465 .call = parse_vc, 4466 }, 4467 [ITEM_PORT_ID_ID] = { 4468 .name = "id", 4469 .help = "DPDK port ID", 4470 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), 4471 item_param), 4472 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), 4473 }, 4474 [ITEM_MARK] = { 4475 .name = "mark", 4476 .help = "match traffic against value set in previously matched rule", 4477 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), 4478 .next = NEXT(item_mark), 4479 .call = parse_vc, 4480 }, 4481 [ITEM_MARK_ID] = { 4482 .name = "id", 4483 .help = "Integer value to match against", 4484 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), 4485 item_param), 4486 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), 4487 }, 4488 [ITEM_RAW] = { 4489 .name = "raw", 4490 .help = "match an arbitrary byte string", 4491 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), 4492 .next = NEXT(item_raw), 4493 .call = parse_vc, 4494 }, 4495 [ITEM_RAW_RELATIVE] = { 4496 .name = "relative", 4497 .help = "look for pattern after the previous item", 4498 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4499 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4500 relative, 1)), 4501 }, 4502 [ITEM_RAW_SEARCH] = { 4503 .name = "search", 4504 .help = "search pattern from offset (see also limit)", 4505 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4506 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4507 search, 1)), 4508 }, 4509 [ITEM_RAW_OFFSET] = { 4510 .name = "offset", 4511 .help = "absolute or relative offset for pattern", 4512 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), 4513 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), 4514 }, 4515 [ITEM_RAW_LIMIT] = { 4516 .name = "limit", 4517 .help = "search area limit for start of pattern", 4518 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4519 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), 4520 }, 4521 [ITEM_RAW_PATTERN] = { 4522 .name = "pattern", 4523 .help = "byte string to look for", 4524 .next = NEXT(item_raw, 4525 NEXT_ENTRY(COMMON_STRING), 4526 NEXT_ENTRY(ITEM_PARAM_IS, 4527 ITEM_PARAM_SPEC, 4528 ITEM_PARAM_MASK)), 4529 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4530 ARGS_ENTRY(struct rte_flow_item_raw, length), 4531 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4532 ITEM_RAW_PATTERN_SIZE)), 4533 }, 4534 [ITEM_RAW_PATTERN_HEX] = { 4535 .name = "pattern_hex", 4536 .help = "hex string to look for", 4537 .next = NEXT(item_raw, 4538 NEXT_ENTRY(COMMON_HEX), 4539 NEXT_ENTRY(ITEM_PARAM_IS, 4540 ITEM_PARAM_SPEC, 4541 ITEM_PARAM_MASK)), 4542 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4543 ARGS_ENTRY(struct rte_flow_item_raw, length), 4544 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4545 ITEM_RAW_PATTERN_SIZE)), 4546 }, 4547 [ITEM_ETH] = { 4548 .name = "eth", 4549 .help = "match Ethernet header", 4550 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), 4551 .next = NEXT(item_eth), 4552 .call = parse_vc, 4553 }, 4554 [ITEM_ETH_DST] = { 4555 .name = "dst", 4556 .help = "destination MAC", 4557 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4558 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), 4559 }, 4560 [ITEM_ETH_SRC] = { 4561 .name = "src", 4562 .help = "source MAC", 4563 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4564 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), 4565 }, 4566 [ITEM_ETH_TYPE] = { 4567 .name = "type", 4568 .help = "EtherType", 4569 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4570 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), 4571 }, 4572 [ITEM_ETH_HAS_VLAN] = { 4573 .name = "has_vlan", 4574 .help = "packet header contains VLAN", 4575 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4576 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, 4577 has_vlan, 1)), 4578 }, 4579 [ITEM_VLAN] = { 4580 .name = "vlan", 4581 .help = "match 802.1Q/ad VLAN tag", 4582 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), 4583 .next = NEXT(item_vlan), 4584 .call = parse_vc, 4585 }, 4586 [ITEM_VLAN_TCI] = { 4587 .name = "tci", 4588 .help = "tag control information", 4589 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4590 item_param), 4591 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, hdr.vlan_tci)), 4592 }, 4593 [ITEM_VLAN_PCP] = { 4594 .name = "pcp", 4595 .help = "priority code point", 4596 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4597 item_param), 4598 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4599 hdr.vlan_tci, "\xe0\x00")), 4600 }, 4601 [ITEM_VLAN_DEI] = { 4602 .name = "dei", 4603 .help = "drop eligible indicator", 4604 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4605 item_param), 4606 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4607 hdr.vlan_tci, "\x10\x00")), 4608 }, 4609 [ITEM_VLAN_VID] = { 4610 .name = "vid", 4611 .help = "VLAN identifier", 4612 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4613 item_param), 4614 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4615 hdr.vlan_tci, "\x0f\xff")), 4616 }, 4617 [ITEM_VLAN_INNER_TYPE] = { 4618 .name = "inner_type", 4619 .help = "inner EtherType", 4620 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4621 item_param), 4622 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, 4623 hdr.eth_proto)), 4624 }, 4625 [ITEM_VLAN_HAS_MORE_VLAN] = { 4626 .name = "has_more_vlan", 4627 .help = "packet header contains another VLAN", 4628 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4629 item_param), 4630 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, 4631 has_more_vlan, 1)), 4632 }, 4633 [ITEM_IPV4] = { 4634 .name = "ipv4", 4635 .help = "match IPv4 header", 4636 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), 4637 .next = NEXT(item_ipv4), 4638 .call = parse_vc, 4639 }, 4640 [ITEM_IPV4_VER_IHL] = { 4641 .name = "version_ihl", 4642 .help = "match header length", 4643 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4644 item_param), 4645 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, 4646 hdr.version_ihl)), 4647 }, 4648 [ITEM_IPV4_TOS] = { 4649 .name = "tos", 4650 .help = "type of service", 4651 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4652 item_param), 4653 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4654 hdr.type_of_service)), 4655 }, 4656 [ITEM_IPV4_LENGTH] = { 4657 .name = "length", 4658 .help = "total length", 4659 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4660 item_param), 4661 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4662 hdr.total_length)), 4663 }, 4664 [ITEM_IPV4_ID] = { 4665 .name = "packet_id", 4666 .help = "fragment packet id", 4667 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4668 item_param), 4669 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4670 hdr.packet_id)), 4671 }, 4672 [ITEM_IPV4_FRAGMENT_OFFSET] = { 4673 .name = "fragment_offset", 4674 .help = "fragmentation flags and fragment offset", 4675 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4676 item_param), 4677 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4678 hdr.fragment_offset)), 4679 }, 4680 [ITEM_IPV4_TTL] = { 4681 .name = "ttl", 4682 .help = "time to live", 4683 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4684 item_param), 4685 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4686 hdr.time_to_live)), 4687 }, 4688 [ITEM_IPV4_PROTO] = { 4689 .name = "proto", 4690 .help = "next protocol ID", 4691 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4692 item_param), 4693 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4694 hdr.next_proto_id)), 4695 }, 4696 [ITEM_IPV4_SRC] = { 4697 .name = "src", 4698 .help = "source address", 4699 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4700 item_param), 4701 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4702 hdr.src_addr)), 4703 }, 4704 [ITEM_IPV4_DST] = { 4705 .name = "dst", 4706 .help = "destination address", 4707 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4708 item_param), 4709 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4710 hdr.dst_addr)), 4711 }, 4712 [ITEM_IPV6] = { 4713 .name = "ipv6", 4714 .help = "match IPv6 header", 4715 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), 4716 .next = NEXT(item_ipv6), 4717 .call = parse_vc, 4718 }, 4719 [ITEM_IPV6_TC] = { 4720 .name = "tc", 4721 .help = "traffic class", 4722 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4723 item_param), 4724 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4725 hdr.vtc_flow, 4726 "\x0f\xf0\x00\x00")), 4727 }, 4728 [ITEM_IPV6_FLOW] = { 4729 .name = "flow", 4730 .help = "flow label", 4731 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4732 item_param), 4733 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4734 hdr.vtc_flow, 4735 "\x00\x0f\xff\xff")), 4736 }, 4737 [ITEM_IPV6_LEN] = { 4738 .name = "length", 4739 .help = "payload length", 4740 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4741 item_param), 4742 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4743 hdr.payload_len)), 4744 }, 4745 [ITEM_IPV6_PROTO] = { 4746 .name = "proto", 4747 .help = "protocol (next header)", 4748 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4749 item_param), 4750 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4751 hdr.proto)), 4752 }, 4753 [ITEM_IPV6_HOP] = { 4754 .name = "hop", 4755 .help = "hop limit", 4756 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4757 item_param), 4758 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4759 hdr.hop_limits)), 4760 }, 4761 [ITEM_IPV6_SRC] = { 4762 .name = "src", 4763 .help = "source address", 4764 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4765 item_param), 4766 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4767 hdr.src_addr)), 4768 }, 4769 [ITEM_IPV6_DST] = { 4770 .name = "dst", 4771 .help = "destination address", 4772 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4773 item_param), 4774 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4775 hdr.dst_addr)), 4776 }, 4777 [ITEM_IPV6_HAS_FRAG_EXT] = { 4778 .name = "has_frag_ext", 4779 .help = "fragment packet attribute", 4780 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4781 item_param), 4782 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, 4783 has_frag_ext, 1)), 4784 }, 4785 [ITEM_IPV6_ROUTING_EXT] = { 4786 .name = "ipv6_routing_ext", 4787 .help = "match IPv6 routing extension header", 4788 .priv = PRIV_ITEM(IPV6_ROUTING_EXT, 4789 sizeof(struct rte_flow_item_ipv6_routing_ext)), 4790 .next = NEXT(item_ipv6_routing_ext), 4791 .call = parse_vc, 4792 }, 4793 [ITEM_IPV6_ROUTING_EXT_TYPE] = { 4794 .name = "ext_type", 4795 .help = "match IPv6 routing extension header type", 4796 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4797 item_param), 4798 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4799 hdr.type)), 4800 }, 4801 [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = { 4802 .name = "ext_next_hdr", 4803 .help = "match IPv6 routing extension header next header type", 4804 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4805 item_param), 4806 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4807 hdr.next_hdr)), 4808 }, 4809 [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = { 4810 .name = "ext_seg_left", 4811 .help = "match IPv6 routing extension header segment left", 4812 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4813 item_param), 4814 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4815 hdr.segments_left)), 4816 }, 4817 [ITEM_ICMP] = { 4818 .name = "icmp", 4819 .help = "match ICMP header", 4820 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), 4821 .next = NEXT(item_icmp), 4822 .call = parse_vc, 4823 }, 4824 [ITEM_ICMP_TYPE] = { 4825 .name = "type", 4826 .help = "ICMP packet type", 4827 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4828 item_param), 4829 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4830 hdr.icmp_type)), 4831 }, 4832 [ITEM_ICMP_CODE] = { 4833 .name = "code", 4834 .help = "ICMP packet code", 4835 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4836 item_param), 4837 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4838 hdr.icmp_code)), 4839 }, 4840 [ITEM_ICMP_IDENT] = { 4841 .name = "ident", 4842 .help = "ICMP packet identifier", 4843 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4844 item_param), 4845 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4846 hdr.icmp_ident)), 4847 }, 4848 [ITEM_ICMP_SEQ] = { 4849 .name = "seq", 4850 .help = "ICMP packet sequence number", 4851 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4852 item_param), 4853 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4854 hdr.icmp_seq_nb)), 4855 }, 4856 [ITEM_UDP] = { 4857 .name = "udp", 4858 .help = "match UDP header", 4859 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), 4860 .next = NEXT(item_udp), 4861 .call = parse_vc, 4862 }, 4863 [ITEM_UDP_SRC] = { 4864 .name = "src", 4865 .help = "UDP source port", 4866 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), 4867 item_param), 4868 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4869 hdr.src_port)), 4870 }, 4871 [ITEM_UDP_DST] = { 4872 .name = "dst", 4873 .help = "UDP destination port", 4874 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4875 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4876 hdr.dst_port)), 4877 }, 4878 [ITEM_TCP] = { 4879 .name = "tcp", 4880 .help = "match TCP header", 4881 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), 4882 .next = NEXT(item_tcp), 4883 .call = parse_vc, 4884 }, 4885 [ITEM_TCP_SRC] = { 4886 .name = "src", 4887 .help = "TCP source port", 4888 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4889 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4890 hdr.src_port)), 4891 }, 4892 [ITEM_TCP_DST] = { 4893 .name = "dst", 4894 .help = "TCP destination port", 4895 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4896 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4897 hdr.dst_port)), 4898 }, 4899 [ITEM_TCP_FLAGS] = { 4900 .name = "flags", 4901 .help = "TCP flags", 4902 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4903 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4904 hdr.tcp_flags)), 4905 }, 4906 [ITEM_SCTP] = { 4907 .name = "sctp", 4908 .help = "match SCTP header", 4909 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), 4910 .next = NEXT(item_sctp), 4911 .call = parse_vc, 4912 }, 4913 [ITEM_SCTP_SRC] = { 4914 .name = "src", 4915 .help = "SCTP source port", 4916 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4917 item_param), 4918 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4919 hdr.src_port)), 4920 }, 4921 [ITEM_SCTP_DST] = { 4922 .name = "dst", 4923 .help = "SCTP destination port", 4924 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4925 item_param), 4926 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4927 hdr.dst_port)), 4928 }, 4929 [ITEM_SCTP_TAG] = { 4930 .name = "tag", 4931 .help = "validation tag", 4932 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4933 item_param), 4934 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4935 hdr.tag)), 4936 }, 4937 [ITEM_SCTP_CKSUM] = { 4938 .name = "cksum", 4939 .help = "checksum", 4940 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4941 item_param), 4942 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4943 hdr.cksum)), 4944 }, 4945 [ITEM_VXLAN] = { 4946 .name = "vxlan", 4947 .help = "match VXLAN header", 4948 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), 4949 .next = NEXT(item_vxlan), 4950 .call = parse_vc, 4951 }, 4952 [ITEM_VXLAN_VNI] = { 4953 .name = "vni", 4954 .help = "VXLAN identifier", 4955 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4956 item_param), 4957 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), 4958 }, 4959 [ITEM_VXLAN_FLAG_G] = { 4960 .name = "flag_g", 4961 .help = "VXLAN GBP bit", 4962 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4963 item_param), 4964 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4965 hdr.flag_g, 1)), 4966 }, 4967 [ITEM_VXLAN_FLAG_VER] = { 4968 .name = "flag_ver", 4969 .help = "VXLAN GPE version", 4970 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4971 item_param), 4972 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4973 hdr.flag_ver, 2)), 4974 }, 4975 [ITEM_VXLAN_FLAG_I] = { 4976 .name = "flag_i", 4977 .help = "VXLAN Instance bit", 4978 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4979 item_param), 4980 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4981 hdr.flag_i, 1)), 4982 }, 4983 [ITEM_VXLAN_FLAG_P] = { 4984 .name = "flag_p", 4985 .help = "VXLAN GPE Next Protocol bit", 4986 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4987 item_param), 4988 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4989 hdr.flag_p, 1)), 4990 }, 4991 [ITEM_VXLAN_FLAG_B] = { 4992 .name = "flag_b", 4993 .help = "VXLAN GPE Ingress-Replicated BUM", 4994 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4995 item_param), 4996 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4997 hdr.flag_b, 1)), 4998 }, 4999 [ITEM_VXLAN_FLAG_O] = { 5000 .name = "flag_o", 5001 .help = "VXLAN GPE OAM Packet bit", 5002 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5003 item_param), 5004 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 5005 hdr.flag_o, 1)), 5006 }, 5007 [ITEM_VXLAN_FLAG_D] = { 5008 .name = "flag_d", 5009 .help = "VXLAN GBP Don't Learn bit", 5010 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5011 item_param), 5012 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 5013 hdr.flag_d, 1)), 5014 }, 5015 [ITEM_VXLAN_FLAG_A] = { 5016 .name = "flag_a", 5017 .help = "VXLAN GBP Applied bit", 5018 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5019 item_param), 5020 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 5021 hdr.flag_a, 1)), 5022 }, 5023 [ITEM_VXLAN_GBP_ID] = { 5024 .name = "group_policy_id", 5025 .help = "VXLAN GBP ID", 5026 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5027 item_param), 5028 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5029 hdr.policy_id)), 5030 }, 5031 [ITEM_VXLAN_GPE_PROTO] = { 5032 .name = "protocol", 5033 .help = "VXLAN GPE next protocol", 5034 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5035 item_param), 5036 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5037 hdr.proto)), 5038 }, 5039 [ITEM_VXLAN_FIRST_RSVD] = { 5040 .name = "first_rsvd", 5041 .help = "VXLAN rsvd0 first byte", 5042 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5043 item_param), 5044 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5045 hdr.rsvd0[0])), 5046 }, 5047 [ITEM_VXLAN_SECND_RSVD] = { 5048 .name = "second_rsvd", 5049 .help = "VXLAN rsvd0 second byte", 5050 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5051 item_param), 5052 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5053 hdr.rsvd0[1])), 5054 }, 5055 [ITEM_VXLAN_THIRD_RSVD] = { 5056 .name = "third_rsvd", 5057 .help = "VXLAN rsvd0 third byte", 5058 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5059 item_param), 5060 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5061 hdr.rsvd0[2])), 5062 }, 5063 [ITEM_VXLAN_LAST_RSVD] = { 5064 .name = "last_rsvd", 5065 .help = "VXLAN last reserved byte", 5066 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5067 item_param), 5068 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5069 hdr.last_rsvd)), 5070 }, 5071 [ITEM_E_TAG] = { 5072 .name = "e_tag", 5073 .help = "match E-Tag header", 5074 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), 5075 .next = NEXT(item_e_tag), 5076 .call = parse_vc, 5077 }, 5078 [ITEM_E_TAG_GRP_ECID_B] = { 5079 .name = "grp_ecid_b", 5080 .help = "GRP and E-CID base", 5081 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5082 item_param), 5083 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, 5084 rsvd_grp_ecid_b, 5085 "\x3f\xff")), 5086 }, 5087 [ITEM_NVGRE] = { 5088 .name = "nvgre", 5089 .help = "match NVGRE header", 5090 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), 5091 .next = NEXT(item_nvgre), 5092 .call = parse_vc, 5093 }, 5094 [ITEM_NVGRE_TNI] = { 5095 .name = "tni", 5096 .help = "virtual subnet ID", 5097 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), 5098 item_param), 5099 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), 5100 }, 5101 [ITEM_MPLS] = { 5102 .name = "mpls", 5103 .help = "match MPLS header", 5104 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), 5105 .next = NEXT(item_mpls), 5106 .call = parse_vc, 5107 }, 5108 [ITEM_MPLS_LABEL] = { 5109 .name = "label", 5110 .help = "MPLS label", 5111 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5112 item_param), 5113 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5114 label_tc_s, 5115 "\xff\xff\xf0")), 5116 }, 5117 [ITEM_MPLS_TC] = { 5118 .name = "tc", 5119 .help = "MPLS Traffic Class", 5120 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5121 item_param), 5122 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5123 label_tc_s, 5124 "\x00\x00\x0e")), 5125 }, 5126 [ITEM_MPLS_S] = { 5127 .name = "s", 5128 .help = "MPLS Bottom-of-Stack", 5129 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5130 item_param), 5131 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5132 label_tc_s, 5133 "\x00\x00\x01")), 5134 }, 5135 [ITEM_MPLS_TTL] = { 5136 .name = "ttl", 5137 .help = "MPLS Time-to-Live", 5138 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5139 item_param), 5140 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls, ttl)), 5141 }, 5142 [ITEM_GRE] = { 5143 .name = "gre", 5144 .help = "match GRE header", 5145 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), 5146 .next = NEXT(item_gre), 5147 .call = parse_vc, 5148 }, 5149 [ITEM_GRE_PROTO] = { 5150 .name = "protocol", 5151 .help = "GRE protocol type", 5152 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5153 item_param), 5154 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5155 protocol)), 5156 }, 5157 [ITEM_GRE_C_RSVD0_VER] = { 5158 .name = "c_rsvd0_ver", 5159 .help = 5160 "checksum (1b), undefined (1b), key bit (1b)," 5161 " sequence number (1b), reserved 0 (9b)," 5162 " version (3b)", 5163 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5164 item_param), 5165 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5166 c_rsvd0_ver)), 5167 }, 5168 [ITEM_GRE_C_BIT] = { 5169 .name = "c_bit", 5170 .help = "checksum bit (C)", 5171 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), 5172 item_param), 5173 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5174 c_rsvd0_ver, 5175 "\x80\x00\x00\x00")), 5176 }, 5177 [ITEM_GRE_S_BIT] = { 5178 .name = "s_bit", 5179 .help = "sequence number bit (S)", 5180 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5181 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5182 c_rsvd0_ver, 5183 "\x10\x00\x00\x00")), 5184 }, 5185 [ITEM_GRE_K_BIT] = { 5186 .name = "k_bit", 5187 .help = "key bit (K)", 5188 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5189 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5190 c_rsvd0_ver, 5191 "\x20\x00\x00\x00")), 5192 }, 5193 [ITEM_FUZZY] = { 5194 .name = "fuzzy", 5195 .help = "fuzzy pattern match, expect faster than default", 5196 .priv = PRIV_ITEM(FUZZY, 5197 sizeof(struct rte_flow_item_fuzzy)), 5198 .next = NEXT(item_fuzzy), 5199 .call = parse_vc, 5200 }, 5201 [ITEM_FUZZY_THRESH] = { 5202 .name = "thresh", 5203 .help = "match accuracy threshold", 5204 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), 5205 item_param), 5206 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, 5207 thresh)), 5208 }, 5209 [ITEM_GTP] = { 5210 .name = "gtp", 5211 .help = "match GTP header", 5212 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), 5213 .next = NEXT(item_gtp), 5214 .call = parse_vc, 5215 }, 5216 [ITEM_GTP_FLAGS] = { 5217 .name = "v_pt_rsv_flags", 5218 .help = "GTP flags", 5219 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5220 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, 5221 hdr.gtp_hdr_info)), 5222 }, 5223 [ITEM_GTP_MSG_TYPE] = { 5224 .name = "msg_type", 5225 .help = "GTP message type", 5226 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5227 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), 5228 }, 5229 [ITEM_GTP_TEID] = { 5230 .name = "teid", 5231 .help = "tunnel endpoint identifier", 5232 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5233 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), 5234 }, 5235 [ITEM_GTPC] = { 5236 .name = "gtpc", 5237 .help = "match GTP header", 5238 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), 5239 .next = NEXT(item_gtp), 5240 .call = parse_vc, 5241 }, 5242 [ITEM_GTPU] = { 5243 .name = "gtpu", 5244 .help = "match GTP header", 5245 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), 5246 .next = NEXT(item_gtp), 5247 .call = parse_vc, 5248 }, 5249 [ITEM_GENEVE] = { 5250 .name = "geneve", 5251 .help = "match GENEVE header", 5252 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), 5253 .next = NEXT(item_geneve), 5254 .call = parse_vc, 5255 }, 5256 [ITEM_GENEVE_VNI] = { 5257 .name = "vni", 5258 .help = "virtual network identifier", 5259 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5260 item_param), 5261 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), 5262 }, 5263 [ITEM_GENEVE_PROTO] = { 5264 .name = "protocol", 5265 .help = "GENEVE protocol type", 5266 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5267 item_param), 5268 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, 5269 protocol)), 5270 }, 5271 [ITEM_GENEVE_OPTLEN] = { 5272 .name = "optlen", 5273 .help = "GENEVE options length in dwords", 5274 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5275 item_param), 5276 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, 5277 ver_opt_len_o_c_rsvd0, 5278 "\x3f\x00")), 5279 }, 5280 [ITEM_VXLAN_GPE] = { 5281 .name = "vxlan-gpe", 5282 .help = "match VXLAN-GPE header", 5283 .priv = PRIV_ITEM(VXLAN_GPE, 5284 sizeof(struct rte_flow_item_vxlan_gpe)), 5285 .next = NEXT(item_vxlan_gpe), 5286 .call = parse_vc, 5287 }, 5288 [ITEM_VXLAN_GPE_VNI] = { 5289 .name = "vni", 5290 .help = "VXLAN-GPE identifier", 5291 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5292 item_param), 5293 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5294 hdr.vni)), 5295 }, 5296 [ITEM_VXLAN_GPE_PROTO_IN_DEPRECATED_VXLAN_GPE_HDR] = { 5297 .name = "protocol", 5298 .help = "VXLAN-GPE next protocol", 5299 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5300 item_param), 5301 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5302 protocol)), 5303 }, 5304 [ITEM_VXLAN_GPE_FLAGS] = { 5305 .name = "flags", 5306 .help = "VXLAN-GPE flags", 5307 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5308 item_param), 5309 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5310 flags)), 5311 }, 5312 [ITEM_VXLAN_GPE_RSVD0] = { 5313 .name = "rsvd0", 5314 .help = "VXLAN-GPE rsvd0", 5315 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5316 item_param), 5317 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5318 rsvd0)), 5319 }, 5320 [ITEM_VXLAN_GPE_RSVD1] = { 5321 .name = "rsvd1", 5322 .help = "VXLAN-GPE rsvd1", 5323 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5324 item_param), 5325 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5326 rsvd1)), 5327 }, 5328 [ITEM_ARP_ETH_IPV4] = { 5329 .name = "arp_eth_ipv4", 5330 .help = "match ARP header for Ethernet/IPv4", 5331 .priv = PRIV_ITEM(ARP_ETH_IPV4, 5332 sizeof(struct rte_flow_item_arp_eth_ipv4)), 5333 .next = NEXT(item_arp_eth_ipv4), 5334 .call = parse_vc, 5335 }, 5336 [ITEM_ARP_ETH_IPV4_SHA] = { 5337 .name = "sha", 5338 .help = "sender hardware address", 5339 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5340 item_param), 5341 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5342 hdr.arp_data.arp_sha)), 5343 }, 5344 [ITEM_ARP_ETH_IPV4_SPA] = { 5345 .name = "spa", 5346 .help = "sender IPv4 address", 5347 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5348 item_param), 5349 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5350 hdr.arp_data.arp_sip)), 5351 }, 5352 [ITEM_ARP_ETH_IPV4_THA] = { 5353 .name = "tha", 5354 .help = "target hardware address", 5355 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5356 item_param), 5357 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5358 hdr.arp_data.arp_tha)), 5359 }, 5360 [ITEM_ARP_ETH_IPV4_TPA] = { 5361 .name = "tpa", 5362 .help = "target IPv4 address", 5363 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5364 item_param), 5365 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5366 hdr.arp_data.arp_tip)), 5367 }, 5368 [ITEM_IPV6_EXT] = { 5369 .name = "ipv6_ext", 5370 .help = "match presence of any IPv6 extension header", 5371 .priv = PRIV_ITEM(IPV6_EXT, 5372 sizeof(struct rte_flow_item_ipv6_ext)), 5373 .next = NEXT(item_ipv6_ext), 5374 .call = parse_vc, 5375 }, 5376 [ITEM_IPV6_EXT_NEXT_HDR] = { 5377 .name = "next_hdr", 5378 .help = "next header", 5379 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5380 item_param), 5381 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 5382 next_hdr)), 5383 }, 5384 [ITEM_IPV6_FRAG_EXT] = { 5385 .name = "ipv6_frag_ext", 5386 .help = "match presence of IPv6 fragment extension header", 5387 .priv = PRIV_ITEM(IPV6_FRAG_EXT, 5388 sizeof(struct rte_flow_item_ipv6_frag_ext)), 5389 .next = NEXT(item_ipv6_frag_ext), 5390 .call = parse_vc, 5391 }, 5392 [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { 5393 .name = "next_hdr", 5394 .help = "next header", 5395 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5396 item_param), 5397 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, 5398 hdr.next_header)), 5399 }, 5400 [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { 5401 .name = "frag_data", 5402 .help = "fragment flags and offset", 5403 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5404 item_param), 5405 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5406 hdr.frag_data)), 5407 }, 5408 [ITEM_IPV6_FRAG_EXT_ID] = { 5409 .name = "packet_id", 5410 .help = "fragment packet id", 5411 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5412 item_param), 5413 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5414 hdr.id)), 5415 }, 5416 [ITEM_ICMP6] = { 5417 .name = "icmp6", 5418 .help = "match any ICMPv6 header", 5419 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), 5420 .next = NEXT(item_icmp6), 5421 .call = parse_vc, 5422 }, 5423 [ITEM_ICMP6_TYPE] = { 5424 .name = "type", 5425 .help = "ICMPv6 type", 5426 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5427 item_param), 5428 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5429 type)), 5430 }, 5431 [ITEM_ICMP6_CODE] = { 5432 .name = "code", 5433 .help = "ICMPv6 code", 5434 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5435 item_param), 5436 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5437 code)), 5438 }, 5439 [ITEM_ICMP6_ECHO_REQUEST] = { 5440 .name = "icmp6_echo_request", 5441 .help = "match ICMPv6 echo request", 5442 .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, 5443 sizeof(struct rte_flow_item_icmp6_echo)), 5444 .next = NEXT(item_icmp6_echo_request), 5445 .call = parse_vc, 5446 }, 5447 [ITEM_ICMP6_ECHO_REQUEST_ID] = { 5448 .name = "ident", 5449 .help = "ICMPv6 echo request identifier", 5450 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5451 item_param), 5452 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5453 hdr.identifier)), 5454 }, 5455 [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { 5456 .name = "seq", 5457 .help = "ICMPv6 echo request sequence", 5458 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5459 item_param), 5460 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5461 hdr.sequence)), 5462 }, 5463 [ITEM_ICMP6_ECHO_REPLY] = { 5464 .name = "icmp6_echo_reply", 5465 .help = "match ICMPv6 echo reply", 5466 .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, 5467 sizeof(struct rte_flow_item_icmp6_echo)), 5468 .next = NEXT(item_icmp6_echo_reply), 5469 .call = parse_vc, 5470 }, 5471 [ITEM_ICMP6_ECHO_REPLY_ID] = { 5472 .name = "ident", 5473 .help = "ICMPv6 echo reply identifier", 5474 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5475 item_param), 5476 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5477 hdr.identifier)), 5478 }, 5479 [ITEM_ICMP6_ECHO_REPLY_SEQ] = { 5480 .name = "seq", 5481 .help = "ICMPv6 echo reply sequence", 5482 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5483 item_param), 5484 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5485 hdr.sequence)), 5486 }, 5487 [ITEM_ICMP6_ND_NS] = { 5488 .name = "icmp6_nd_ns", 5489 .help = "match ICMPv6 neighbor discovery solicitation", 5490 .priv = PRIV_ITEM(ICMP6_ND_NS, 5491 sizeof(struct rte_flow_item_icmp6_nd_ns)), 5492 .next = NEXT(item_icmp6_nd_ns), 5493 .call = parse_vc, 5494 }, 5495 [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { 5496 .name = "target_addr", 5497 .help = "target address", 5498 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), 5499 item_param), 5500 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, 5501 target_addr)), 5502 }, 5503 [ITEM_ICMP6_ND_NA] = { 5504 .name = "icmp6_nd_na", 5505 .help = "match ICMPv6 neighbor discovery advertisement", 5506 .priv = PRIV_ITEM(ICMP6_ND_NA, 5507 sizeof(struct rte_flow_item_icmp6_nd_na)), 5508 .next = NEXT(item_icmp6_nd_na), 5509 .call = parse_vc, 5510 }, 5511 [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { 5512 .name = "target_addr", 5513 .help = "target address", 5514 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), 5515 item_param), 5516 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, 5517 target_addr)), 5518 }, 5519 [ITEM_ICMP6_ND_OPT] = { 5520 .name = "icmp6_nd_opt", 5521 .help = "match presence of any ICMPv6 neighbor discovery" 5522 " option", 5523 .priv = PRIV_ITEM(ICMP6_ND_OPT, 5524 sizeof(struct rte_flow_item_icmp6_nd_opt)), 5525 .next = NEXT(item_icmp6_nd_opt), 5526 .call = parse_vc, 5527 }, 5528 [ITEM_ICMP6_ND_OPT_TYPE] = { 5529 .name = "type", 5530 .help = "ND option type", 5531 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5532 item_param), 5533 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, 5534 type)), 5535 }, 5536 [ITEM_ICMP6_ND_OPT_SLA_ETH] = { 5537 .name = "icmp6_nd_opt_sla_eth", 5538 .help = "match ICMPv6 neighbor discovery source Ethernet" 5539 " link-layer address option", 5540 .priv = PRIV_ITEM 5541 (ICMP6_ND_OPT_SLA_ETH, 5542 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), 5543 .next = NEXT(item_icmp6_nd_opt_sla_eth), 5544 .call = parse_vc, 5545 }, 5546 [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { 5547 .name = "sla", 5548 .help = "source Ethernet LLA", 5549 .next = NEXT(item_icmp6_nd_opt_sla_eth, 5550 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5551 .args = ARGS(ARGS_ENTRY_HTON 5552 (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), 5553 }, 5554 [ITEM_ICMP6_ND_OPT_TLA_ETH] = { 5555 .name = "icmp6_nd_opt_tla_eth", 5556 .help = "match ICMPv6 neighbor discovery target Ethernet" 5557 " link-layer address option", 5558 .priv = PRIV_ITEM 5559 (ICMP6_ND_OPT_TLA_ETH, 5560 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), 5561 .next = NEXT(item_icmp6_nd_opt_tla_eth), 5562 .call = parse_vc, 5563 }, 5564 [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { 5565 .name = "tla", 5566 .help = "target Ethernet LLA", 5567 .next = NEXT(item_icmp6_nd_opt_tla_eth, 5568 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5569 .args = ARGS(ARGS_ENTRY_HTON 5570 (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), 5571 }, 5572 [ITEM_META] = { 5573 .name = "meta", 5574 .help = "match metadata header", 5575 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), 5576 .next = NEXT(item_meta), 5577 .call = parse_vc, 5578 }, 5579 [ITEM_META_DATA] = { 5580 .name = "data", 5581 .help = "metadata value", 5582 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), 5583 item_param), 5584 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, 5585 data, "\xff\xff\xff\xff")), 5586 }, 5587 [ITEM_RANDOM] = { 5588 .name = "random", 5589 .help = "match random value", 5590 .priv = PRIV_ITEM(RANDOM, sizeof(struct rte_flow_item_random)), 5591 .next = NEXT(item_random), 5592 .call = parse_vc, 5593 }, 5594 [ITEM_RANDOM_VALUE] = { 5595 .name = "value", 5596 .help = "random value", 5597 .next = NEXT(item_random, NEXT_ENTRY(COMMON_UNSIGNED), 5598 item_param), 5599 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_random, 5600 value, "\xff\xff")), 5601 }, 5602 [ITEM_GRE_KEY] = { 5603 .name = "gre_key", 5604 .help = "match GRE key", 5605 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), 5606 .next = NEXT(item_gre_key), 5607 .call = parse_vc, 5608 }, 5609 [ITEM_GRE_KEY_VALUE] = { 5610 .name = "value", 5611 .help = "key value", 5612 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), 5613 item_param), 5614 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5615 }, 5616 [ITEM_GRE_OPTION] = { 5617 .name = "gre_option", 5618 .help = "match GRE optional fields", 5619 .priv = PRIV_ITEM(GRE_OPTION, 5620 sizeof(struct rte_flow_item_gre_opt)), 5621 .next = NEXT(item_gre_option), 5622 .call = parse_vc, 5623 }, 5624 [ITEM_GRE_OPTION_CHECKSUM] = { 5625 .name = "checksum", 5626 .help = "match GRE checksum", 5627 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5628 item_param), 5629 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5630 checksum_rsvd.checksum)), 5631 }, 5632 [ITEM_GRE_OPTION_KEY] = { 5633 .name = "key", 5634 .help = "match GRE key", 5635 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5636 item_param), 5637 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5638 key.key)), 5639 }, 5640 [ITEM_GRE_OPTION_SEQUENCE] = { 5641 .name = "sequence", 5642 .help = "match GRE sequence", 5643 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5644 item_param), 5645 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5646 sequence.sequence)), 5647 }, 5648 [ITEM_GTP_PSC] = { 5649 .name = "gtp_psc", 5650 .help = "match GTP extension header with type 0x85", 5651 .priv = PRIV_ITEM(GTP_PSC, 5652 sizeof(struct rte_flow_item_gtp_psc)), 5653 .next = NEXT(item_gtp_psc), 5654 .call = parse_vc, 5655 }, 5656 [ITEM_GTP_PSC_QFI] = { 5657 .name = "qfi", 5658 .help = "QoS flow identifier", 5659 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5660 item_param), 5661 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5662 hdr.qfi, 6)), 5663 }, 5664 [ITEM_GTP_PSC_PDU_T] = { 5665 .name = "pdu_t", 5666 .help = "PDU type", 5667 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5668 item_param), 5669 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5670 hdr.type, 4)), 5671 }, 5672 [ITEM_PPPOES] = { 5673 .name = "pppoes", 5674 .help = "match PPPoE session header", 5675 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), 5676 .next = NEXT(item_pppoes), 5677 .call = parse_vc, 5678 }, 5679 [ITEM_PPPOED] = { 5680 .name = "pppoed", 5681 .help = "match PPPoE discovery header", 5682 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), 5683 .next = NEXT(item_pppoed), 5684 .call = parse_vc, 5685 }, 5686 [ITEM_PPPOE_SEID] = { 5687 .name = "seid", 5688 .help = "session identifier", 5689 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), 5690 item_param), 5691 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, 5692 session_id)), 5693 }, 5694 [ITEM_PPPOE_PROTO_ID] = { 5695 .name = "pppoe_proto_id", 5696 .help = "match PPPoE session protocol identifier", 5697 .priv = PRIV_ITEM(PPPOE_PROTO_ID, 5698 sizeof(struct rte_flow_item_pppoe_proto_id)), 5699 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED), 5700 item_param), 5701 .args = ARGS(ARGS_ENTRY_HTON 5702 (struct rte_flow_item_pppoe_proto_id, proto_id)), 5703 .call = parse_vc, 5704 }, 5705 [ITEM_HIGIG2] = { 5706 .name = "higig2", 5707 .help = "matches higig2 header", 5708 .priv = PRIV_ITEM(HIGIG2, 5709 sizeof(struct rte_flow_item_higig2_hdr)), 5710 .next = NEXT(item_higig2), 5711 .call = parse_vc, 5712 }, 5713 [ITEM_HIGIG2_CLASSIFICATION] = { 5714 .name = "classification", 5715 .help = "matches classification of higig2 header", 5716 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5717 item_param), 5718 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5719 hdr.ppt1.classification)), 5720 }, 5721 [ITEM_HIGIG2_VID] = { 5722 .name = "vid", 5723 .help = "matches vid of higig2 header", 5724 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5725 item_param), 5726 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5727 hdr.ppt1.vid)), 5728 }, 5729 [ITEM_TAG] = { 5730 .name = "tag", 5731 .help = "match tag value", 5732 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), 5733 .next = NEXT(item_tag), 5734 .call = parse_vc, 5735 }, 5736 [ITEM_TAG_DATA] = { 5737 .name = "data", 5738 .help = "tag value to match", 5739 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5740 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), 5741 }, 5742 [ITEM_TAG_INDEX] = { 5743 .name = "index", 5744 .help = "index of tag array to match", 5745 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5746 NEXT_ENTRY(ITEM_PARAM_IS)), 5747 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), 5748 }, 5749 [ITEM_L2TPV3OIP] = { 5750 .name = "l2tpv3oip", 5751 .help = "match L2TPv3 over IP header", 5752 .priv = PRIV_ITEM(L2TPV3OIP, 5753 sizeof(struct rte_flow_item_l2tpv3oip)), 5754 .next = NEXT(item_l2tpv3oip), 5755 .call = parse_vc, 5756 }, 5757 [ITEM_L2TPV3OIP_SESSION_ID] = { 5758 .name = "session_id", 5759 .help = "session identifier", 5760 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), 5761 item_param), 5762 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, 5763 session_id)), 5764 }, 5765 [ITEM_ESP] = { 5766 .name = "esp", 5767 .help = "match ESP header", 5768 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), 5769 .next = NEXT(item_esp), 5770 .call = parse_vc, 5771 }, 5772 [ITEM_ESP_SPI] = { 5773 .name = "spi", 5774 .help = "security policy index", 5775 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5776 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, 5777 hdr.spi)), 5778 }, 5779 [ITEM_AH] = { 5780 .name = "ah", 5781 .help = "match AH header", 5782 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), 5783 .next = NEXT(item_ah), 5784 .call = parse_vc, 5785 }, 5786 [ITEM_AH_SPI] = { 5787 .name = "spi", 5788 .help = "security parameters index", 5789 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5790 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), 5791 }, 5792 [ITEM_PFCP] = { 5793 .name = "pfcp", 5794 .help = "match pfcp header", 5795 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), 5796 .next = NEXT(item_pfcp), 5797 .call = parse_vc, 5798 }, 5799 [ITEM_PFCP_S_FIELD] = { 5800 .name = "s_field", 5801 .help = "S field", 5802 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5803 item_param), 5804 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, 5805 s_field)), 5806 }, 5807 [ITEM_PFCP_SEID] = { 5808 .name = "seid", 5809 .help = "session endpoint identifier", 5810 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5811 item_param), 5812 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), 5813 }, 5814 [ITEM_ECPRI] = { 5815 .name = "ecpri", 5816 .help = "match eCPRI header", 5817 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), 5818 .next = NEXT(item_ecpri), 5819 .call = parse_vc, 5820 }, 5821 [ITEM_ECPRI_COMMON] = { 5822 .name = "common", 5823 .help = "eCPRI common header", 5824 .next = NEXT(item_ecpri_common), 5825 }, 5826 [ITEM_ECPRI_COMMON_TYPE] = { 5827 .name = "type", 5828 .help = "type of common header", 5829 .next = NEXT(item_ecpri_common_type), 5830 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), 5831 }, 5832 [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { 5833 .name = "iq_data", 5834 .help = "Type #0: IQ Data", 5835 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5836 ITEM_NEXT)), 5837 .call = parse_vc_item_ecpri_type, 5838 }, 5839 [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { 5840 .name = "pc_id", 5841 .help = "Physical Channel ID", 5842 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5843 ITEM_ECPRI_COMMON, ITEM_NEXT), 5844 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5845 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5846 hdr.type0.pc_id)), 5847 }, 5848 [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { 5849 .name = "rtc_ctrl", 5850 .help = "Type #2: Real-Time Control Data", 5851 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5852 ITEM_NEXT)), 5853 .call = parse_vc_item_ecpri_type, 5854 }, 5855 [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { 5856 .name = "rtc_id", 5857 .help = "Real-Time Control Data ID", 5858 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5859 ITEM_ECPRI_COMMON, ITEM_NEXT), 5860 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5861 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5862 hdr.type2.rtc_id)), 5863 }, 5864 [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { 5865 .name = "delay_measure", 5866 .help = "Type #5: One-Way Delay Measurement", 5867 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5868 ITEM_NEXT)), 5869 .call = parse_vc_item_ecpri_type, 5870 }, 5871 [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { 5872 .name = "msr_id", 5873 .help = "Measurement ID", 5874 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5875 ITEM_ECPRI_COMMON, ITEM_NEXT), 5876 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5877 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5878 hdr.type5.msr_id)), 5879 }, 5880 [ITEM_GENEVE_OPT] = { 5881 .name = "geneve-opt", 5882 .help = "GENEVE header option", 5883 .priv = PRIV_ITEM(GENEVE_OPT, 5884 sizeof(struct rte_flow_item_geneve_opt) + 5885 ITEM_GENEVE_OPT_DATA_SIZE), 5886 .next = NEXT(item_geneve_opt), 5887 .call = parse_vc, 5888 }, 5889 [ITEM_GENEVE_OPT_CLASS] = { 5890 .name = "class", 5891 .help = "GENEVE option class", 5892 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5893 item_param), 5894 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, 5895 option_class)), 5896 }, 5897 [ITEM_GENEVE_OPT_TYPE] = { 5898 .name = "type", 5899 .help = "GENEVE option type", 5900 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5901 item_param), 5902 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, 5903 option_type)), 5904 }, 5905 [ITEM_GENEVE_OPT_LENGTH] = { 5906 .name = "length", 5907 .help = "GENEVE option data length (in 32b words)", 5908 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5909 item_param), 5910 .args = ARGS(ARGS_ENTRY_BOUNDED( 5911 struct rte_flow_item_geneve_opt, option_len, 5912 0, 31)), 5913 }, 5914 [ITEM_GENEVE_OPT_DATA] = { 5915 .name = "data", 5916 .help = "GENEVE option data pattern", 5917 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), 5918 item_param), 5919 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), 5920 ARGS_ENTRY_ARB(0, 0), 5921 ARGS_ENTRY_ARB 5922 (sizeof(struct rte_flow_item_geneve_opt), 5923 ITEM_GENEVE_OPT_DATA_SIZE)), 5924 }, 5925 [ITEM_INTEGRITY] = { 5926 .name = "integrity", 5927 .help = "match packet integrity", 5928 .priv = PRIV_ITEM(INTEGRITY, 5929 sizeof(struct rte_flow_item_integrity)), 5930 .next = NEXT(item_integrity), 5931 .call = parse_vc, 5932 }, 5933 [ITEM_INTEGRITY_LEVEL] = { 5934 .name = "level", 5935 .help = "integrity level", 5936 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5937 item_param), 5938 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), 5939 }, 5940 [ITEM_INTEGRITY_VALUE] = { 5941 .name = "value", 5942 .help = "integrity value", 5943 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5944 item_param), 5945 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), 5946 }, 5947 [ITEM_CONNTRACK] = { 5948 .name = "conntrack", 5949 .help = "conntrack state", 5950 .priv = PRIV_ITEM(CONNTRACK, 5951 sizeof(struct rte_flow_item_conntrack)), 5952 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 5953 item_param), 5954 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 5955 .call = parse_vc, 5956 }, 5957 [ITEM_PORT_REPRESENTOR] = { 5958 .name = "port_representor", 5959 .help = "match traffic entering the embedded switch from the given ethdev", 5960 .priv = PRIV_ITEM(PORT_REPRESENTOR, 5961 sizeof(struct rte_flow_item_ethdev)), 5962 .next = NEXT(item_port_representor), 5963 .call = parse_vc, 5964 }, 5965 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 5966 .name = "port_id", 5967 .help = "ethdev port ID", 5968 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 5969 item_param), 5970 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5971 }, 5972 [ITEM_REPRESENTED_PORT] = { 5973 .name = "represented_port", 5974 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 5975 .priv = PRIV_ITEM(REPRESENTED_PORT, 5976 sizeof(struct rte_flow_item_ethdev)), 5977 .next = NEXT(item_represented_port), 5978 .call = parse_vc, 5979 }, 5980 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 5981 .name = "ethdev_port_id", 5982 .help = "ethdev port ID", 5983 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 5984 item_param), 5985 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5986 }, 5987 [ITEM_FLEX] = { 5988 .name = "flex", 5989 .help = "match flex header", 5990 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 5991 .next = NEXT(item_flex), 5992 .call = parse_vc, 5993 }, 5994 [ITEM_FLEX_ITEM_HANDLE] = { 5995 .name = "item", 5996 .help = "flex item handle", 5997 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5998 NEXT_ENTRY(ITEM_PARAM_IS)), 5999 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 6000 }, 6001 [ITEM_FLEX_PATTERN_HANDLE] = { 6002 .name = "pattern", 6003 .help = "flex pattern handle", 6004 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 6005 NEXT_ENTRY(ITEM_PARAM_IS)), 6006 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 6007 }, 6008 [ITEM_L2TPV2] = { 6009 .name = "l2tpv2", 6010 .help = "match L2TPv2 header", 6011 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 6012 .next = NEXT(item_l2tpv2), 6013 .call = parse_vc, 6014 }, 6015 [ITEM_L2TPV2_TYPE] = { 6016 .name = "type", 6017 .help = "type of l2tpv2", 6018 .next = NEXT(item_l2tpv2_type), 6019 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 6020 }, 6021 [ITEM_L2TPV2_TYPE_DATA] = { 6022 .name = "data", 6023 .help = "Type #7: data message without any options", 6024 .next = NEXT(item_l2tpv2_type_data), 6025 .call = parse_vc_item_l2tpv2_type, 6026 }, 6027 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 6028 .name = "tunnel_id", 6029 .help = "tunnel identifier", 6030 .next = NEXT(item_l2tpv2_type_data, 6031 NEXT_ENTRY(COMMON_UNSIGNED), 6032 item_param), 6033 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6034 hdr.type7.tunnel_id)), 6035 }, 6036 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 6037 .name = "session_id", 6038 .help = "session identifier", 6039 .next = NEXT(item_l2tpv2_type_data, 6040 NEXT_ENTRY(COMMON_UNSIGNED), 6041 item_param), 6042 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6043 hdr.type7.session_id)), 6044 }, 6045 [ITEM_L2TPV2_TYPE_DATA_L] = { 6046 .name = "data_l", 6047 .help = "Type #6: data message with length option", 6048 .next = NEXT(item_l2tpv2_type_data_l), 6049 .call = parse_vc_item_l2tpv2_type, 6050 }, 6051 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 6052 .name = "length", 6053 .help = "message length", 6054 .next = NEXT(item_l2tpv2_type_data_l, 6055 NEXT_ENTRY(COMMON_UNSIGNED), 6056 item_param), 6057 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6058 hdr.type6.length)), 6059 }, 6060 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 6061 .name = "tunnel_id", 6062 .help = "tunnel identifier", 6063 .next = NEXT(item_l2tpv2_type_data_l, 6064 NEXT_ENTRY(COMMON_UNSIGNED), 6065 item_param), 6066 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6067 hdr.type6.tunnel_id)), 6068 }, 6069 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 6070 .name = "session_id", 6071 .help = "session identifier", 6072 .next = NEXT(item_l2tpv2_type_data_l, 6073 NEXT_ENTRY(COMMON_UNSIGNED), 6074 item_param), 6075 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6076 hdr.type6.session_id)), 6077 }, 6078 [ITEM_L2TPV2_TYPE_DATA_S] = { 6079 .name = "data_s", 6080 .help = "Type #5: data message with ns, nr option", 6081 .next = NEXT(item_l2tpv2_type_data_s), 6082 .call = parse_vc_item_l2tpv2_type, 6083 }, 6084 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 6085 .name = "tunnel_id", 6086 .help = "tunnel identifier", 6087 .next = NEXT(item_l2tpv2_type_data_s, 6088 NEXT_ENTRY(COMMON_UNSIGNED), 6089 item_param), 6090 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6091 hdr.type5.tunnel_id)), 6092 }, 6093 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 6094 .name = "session_id", 6095 .help = "session identifier", 6096 .next = NEXT(item_l2tpv2_type_data_s, 6097 NEXT_ENTRY(COMMON_UNSIGNED), 6098 item_param), 6099 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6100 hdr.type5.session_id)), 6101 }, 6102 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 6103 .name = "ns", 6104 .help = "sequence number for message", 6105 .next = NEXT(item_l2tpv2_type_data_s, 6106 NEXT_ENTRY(COMMON_UNSIGNED), 6107 item_param), 6108 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6109 hdr.type5.ns)), 6110 }, 6111 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 6112 .name = "nr", 6113 .help = "sequence number for next receive message", 6114 .next = NEXT(item_l2tpv2_type_data_s, 6115 NEXT_ENTRY(COMMON_UNSIGNED), 6116 item_param), 6117 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6118 hdr.type5.nr)), 6119 }, 6120 [ITEM_L2TPV2_TYPE_DATA_O] = { 6121 .name = "data_o", 6122 .help = "Type #4: data message with offset option", 6123 .next = NEXT(item_l2tpv2_type_data_o), 6124 .call = parse_vc_item_l2tpv2_type, 6125 }, 6126 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 6127 .name = "tunnel_id", 6128 .help = "tunnel identifier", 6129 .next = NEXT(item_l2tpv2_type_data_o, 6130 NEXT_ENTRY(COMMON_UNSIGNED), 6131 item_param), 6132 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6133 hdr.type4.tunnel_id)), 6134 }, 6135 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 6136 .name = "session_id", 6137 .help = "session identifier", 6138 .next = NEXT(item_l2tpv2_type_data_o, 6139 NEXT_ENTRY(COMMON_UNSIGNED), 6140 item_param), 6141 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6142 hdr.type5.session_id)), 6143 }, 6144 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 6145 .name = "offset_size", 6146 .help = "the size of offset padding", 6147 .next = NEXT(item_l2tpv2_type_data_o, 6148 NEXT_ENTRY(COMMON_UNSIGNED), 6149 item_param), 6150 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6151 hdr.type4.offset_size)), 6152 }, 6153 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 6154 .name = "data_l_s", 6155 .help = "Type #3: data message contains length, ns, nr " 6156 "options", 6157 .next = NEXT(item_l2tpv2_type_data_l_s), 6158 .call = parse_vc_item_l2tpv2_type, 6159 }, 6160 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 6161 .name = "length", 6162 .help = "message length", 6163 .next = NEXT(item_l2tpv2_type_data_l_s, 6164 NEXT_ENTRY(COMMON_UNSIGNED), 6165 item_param), 6166 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6167 hdr.type3.length)), 6168 }, 6169 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 6170 .name = "tunnel_id", 6171 .help = "tunnel identifier", 6172 .next = NEXT(item_l2tpv2_type_data_l_s, 6173 NEXT_ENTRY(COMMON_UNSIGNED), 6174 item_param), 6175 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6176 hdr.type3.tunnel_id)), 6177 }, 6178 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 6179 .name = "session_id", 6180 .help = "session identifier", 6181 .next = NEXT(item_l2tpv2_type_data_l_s, 6182 NEXT_ENTRY(COMMON_UNSIGNED), 6183 item_param), 6184 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6185 hdr.type3.session_id)), 6186 }, 6187 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 6188 .name = "ns", 6189 .help = "sequence number for message", 6190 .next = NEXT(item_l2tpv2_type_data_l_s, 6191 NEXT_ENTRY(COMMON_UNSIGNED), 6192 item_param), 6193 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6194 hdr.type3.ns)), 6195 }, 6196 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 6197 .name = "nr", 6198 .help = "sequence number for next receive message", 6199 .next = NEXT(item_l2tpv2_type_data_l_s, 6200 NEXT_ENTRY(COMMON_UNSIGNED), 6201 item_param), 6202 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6203 hdr.type3.nr)), 6204 }, 6205 [ITEM_L2TPV2_TYPE_CTRL] = { 6206 .name = "control", 6207 .help = "Type #3: conrtol message contains length, ns, nr " 6208 "options", 6209 .next = NEXT(item_l2tpv2_type_ctrl), 6210 .call = parse_vc_item_l2tpv2_type, 6211 }, 6212 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 6213 .name = "length", 6214 .help = "message length", 6215 .next = NEXT(item_l2tpv2_type_ctrl, 6216 NEXT_ENTRY(COMMON_UNSIGNED), 6217 item_param), 6218 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6219 hdr.type3.length)), 6220 }, 6221 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 6222 .name = "tunnel_id", 6223 .help = "tunnel identifier", 6224 .next = NEXT(item_l2tpv2_type_ctrl, 6225 NEXT_ENTRY(COMMON_UNSIGNED), 6226 item_param), 6227 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6228 hdr.type3.tunnel_id)), 6229 }, 6230 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 6231 .name = "session_id", 6232 .help = "session identifier", 6233 .next = NEXT(item_l2tpv2_type_ctrl, 6234 NEXT_ENTRY(COMMON_UNSIGNED), 6235 item_param), 6236 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6237 hdr.type3.session_id)), 6238 }, 6239 [ITEM_L2TPV2_MSG_CTRL_NS] = { 6240 .name = "ns", 6241 .help = "sequence number for message", 6242 .next = NEXT(item_l2tpv2_type_ctrl, 6243 NEXT_ENTRY(COMMON_UNSIGNED), 6244 item_param), 6245 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6246 hdr.type3.ns)), 6247 }, 6248 [ITEM_L2TPV2_MSG_CTRL_NR] = { 6249 .name = "nr", 6250 .help = "sequence number for next receive message", 6251 .next = NEXT(item_l2tpv2_type_ctrl, 6252 NEXT_ENTRY(COMMON_UNSIGNED), 6253 item_param), 6254 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6255 hdr.type3.nr)), 6256 }, 6257 [ITEM_PPP] = { 6258 .name = "ppp", 6259 .help = "match PPP header", 6260 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 6261 .next = NEXT(item_ppp), 6262 .call = parse_vc, 6263 }, 6264 [ITEM_PPP_ADDR] = { 6265 .name = "addr", 6266 .help = "PPP address", 6267 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6268 item_param), 6269 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 6270 }, 6271 [ITEM_PPP_CTRL] = { 6272 .name = "ctrl", 6273 .help = "PPP control", 6274 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6275 item_param), 6276 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 6277 }, 6278 [ITEM_PPP_PROTO_ID] = { 6279 .name = "proto_id", 6280 .help = "PPP protocol identifier", 6281 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6282 item_param), 6283 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 6284 hdr.proto_id)), 6285 }, 6286 [ITEM_METER] = { 6287 .name = "meter", 6288 .help = "match meter color", 6289 .priv = PRIV_ITEM(METER_COLOR, 6290 sizeof(struct rte_flow_item_meter_color)), 6291 .next = NEXT(item_meter), 6292 .call = parse_vc, 6293 }, 6294 [ITEM_METER_COLOR] = { 6295 .name = "color", 6296 .help = "meter color", 6297 .next = NEXT(item_meter, 6298 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 6299 item_param), 6300 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 6301 color)), 6302 }, 6303 [ITEM_METER_COLOR_NAME] = { 6304 .name = "color_name", 6305 .help = "meter color name", 6306 .call = parse_meter_color, 6307 .comp = comp_meter_color, 6308 }, 6309 [ITEM_QUOTA] = { 6310 .name = "quota", 6311 .help = "match quota", 6312 .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), 6313 .next = NEXT(item_quota), 6314 .call = parse_vc 6315 }, 6316 [ITEM_QUOTA_STATE] = { 6317 .name = "quota_state", 6318 .help = "quota state", 6319 .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), 6320 NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), 6321 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) 6322 }, 6323 [ITEM_QUOTA_STATE_NAME] = { 6324 .name = "state_name", 6325 .help = "quota state name", 6326 .call = parse_quota_state_name, 6327 .comp = comp_quota_state_name 6328 }, 6329 [ITEM_IB_BTH] = { 6330 .name = "ib_bth", 6331 .help = "match ib bth fields", 6332 .priv = PRIV_ITEM(IB_BTH, 6333 sizeof(struct rte_flow_item_ib_bth)), 6334 .next = NEXT(item_ib_bth), 6335 .call = parse_vc, 6336 }, 6337 [ITEM_IB_BTH_OPCODE] = { 6338 .name = "opcode", 6339 .help = "match ib bth opcode", 6340 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6341 item_param), 6342 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6343 hdr.opcode)), 6344 }, 6345 [ITEM_IB_BTH_PKEY] = { 6346 .name = "pkey", 6347 .help = "partition key", 6348 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6349 item_param), 6350 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6351 hdr.pkey)), 6352 }, 6353 [ITEM_IB_BTH_DST_QPN] = { 6354 .name = "dst_qp", 6355 .help = "destination qp", 6356 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6357 item_param), 6358 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6359 hdr.dst_qp)), 6360 }, 6361 [ITEM_IB_BTH_PSN] = { 6362 .name = "psn", 6363 .help = "packet sequence number", 6364 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6365 item_param), 6366 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6367 hdr.psn)), 6368 }, 6369 [ITEM_PTYPE] = { 6370 .name = "ptype", 6371 .help = "match L2/L3/L4 and tunnel information", 6372 .priv = PRIV_ITEM(PTYPE, 6373 sizeof(struct rte_flow_item_ptype)), 6374 .next = NEXT(item_ptype), 6375 .call = parse_vc, 6376 }, 6377 [ITEM_PTYPE_VALUE] = { 6378 .name = "packet_type", 6379 .help = "packet type as defined in rte_mbuf_ptype", 6380 .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), 6381 item_param), 6382 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), 6383 }, 6384 [ITEM_NSH] = { 6385 .name = "nsh", 6386 .help = "match NSH header", 6387 .priv = PRIV_ITEM(NSH, 6388 sizeof(struct rte_flow_item_nsh)), 6389 .next = NEXT(item_nsh), 6390 .call = parse_vc, 6391 }, 6392 [ITEM_COMPARE] = { 6393 .name = "compare", 6394 .help = "match with the comparison result", 6395 .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)), 6396 .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)), 6397 .call = parse_vc, 6398 }, 6399 [ITEM_COMPARE_OP] = { 6400 .name = "op", 6401 .help = "operation type", 6402 .next = NEXT(item_compare_field, 6403 NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param), 6404 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)), 6405 }, 6406 [ITEM_COMPARE_OP_VALUE] = { 6407 .name = "{operation}", 6408 .help = "operation type value", 6409 .call = parse_vc_compare_op, 6410 .comp = comp_set_compare_op, 6411 }, 6412 [ITEM_COMPARE_FIELD_A_TYPE] = { 6413 .name = "a_type", 6414 .help = "compared field type", 6415 .next = NEXT(compare_field_a, 6416 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param), 6417 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)), 6418 }, 6419 [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = { 6420 .name = "{a_type}", 6421 .help = "compared field type value", 6422 .call = parse_vc_compare_field_id, 6423 .comp = comp_set_compare_field_id, 6424 }, 6425 [ITEM_COMPARE_FIELD_A_LEVEL] = { 6426 .name = "a_level", 6427 .help = "compared field level", 6428 .next = NEXT(compare_field_a, 6429 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param), 6430 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)), 6431 }, 6432 [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = { 6433 .name = "{a_level}", 6434 .help = "compared field level value", 6435 .call = parse_vc_compare_field_level, 6436 .comp = comp_none, 6437 }, 6438 [ITEM_COMPARE_FIELD_A_TAG_INDEX] = { 6439 .name = "a_tag_index", 6440 .help = "compared field tag array", 6441 .next = NEXT(compare_field_a, 6442 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6443 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6444 a.tag_index)), 6445 }, 6446 [ITEM_COMPARE_FIELD_A_TYPE_ID] = { 6447 .name = "a_type_id", 6448 .help = "compared field type ID", 6449 .next = NEXT(compare_field_a, 6450 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6451 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6452 a.type)), 6453 }, 6454 [ITEM_COMPARE_FIELD_A_CLASS_ID] = { 6455 .name = "a_class", 6456 .help = "compared field class ID", 6457 .next = NEXT(compare_field_a, 6458 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6459 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6460 a.class_id)), 6461 }, 6462 [ITEM_COMPARE_FIELD_A_OFFSET] = { 6463 .name = "a_offset", 6464 .help = "compared field bit offset", 6465 .next = NEXT(compare_field_a, 6466 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6467 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6468 a.offset)), 6469 }, 6470 [ITEM_COMPARE_FIELD_B_TYPE] = { 6471 .name = "b_type", 6472 .help = "comparator field type", 6473 .next = NEXT(compare_field_b, 6474 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param), 6475 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6476 b.field)), 6477 }, 6478 [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = { 6479 .name = "{b_type}", 6480 .help = "comparator field type value", 6481 .call = parse_vc_compare_field_id, 6482 .comp = comp_set_compare_field_id, 6483 }, 6484 [ITEM_COMPARE_FIELD_B_LEVEL] = { 6485 .name = "b_level", 6486 .help = "comparator field level", 6487 .next = NEXT(compare_field_b, 6488 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param), 6489 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6490 b.level)), 6491 }, 6492 [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = { 6493 .name = "{b_level}", 6494 .help = "comparator field level value", 6495 .call = parse_vc_compare_field_level, 6496 .comp = comp_none, 6497 }, 6498 [ITEM_COMPARE_FIELD_B_TAG_INDEX] = { 6499 .name = "b_tag_index", 6500 .help = "comparator field tag array", 6501 .next = NEXT(compare_field_b, 6502 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6503 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6504 b.tag_index)), 6505 }, 6506 [ITEM_COMPARE_FIELD_B_TYPE_ID] = { 6507 .name = "b_type_id", 6508 .help = "comparator field type ID", 6509 .next = NEXT(compare_field_b, 6510 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6511 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6512 b.type)), 6513 }, 6514 [ITEM_COMPARE_FIELD_B_CLASS_ID] = { 6515 .name = "b_class", 6516 .help = "comparator field class ID", 6517 .next = NEXT(compare_field_b, 6518 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6519 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6520 b.class_id)), 6521 }, 6522 [ITEM_COMPARE_FIELD_B_OFFSET] = { 6523 .name = "b_offset", 6524 .help = "comparator field bit offset", 6525 .next = NEXT(compare_field_b, 6526 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6527 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6528 b.offset)), 6529 }, 6530 [ITEM_COMPARE_FIELD_B_VALUE] = { 6531 .name = "b_value", 6532 .help = "comparator immediate value", 6533 .next = NEXT(compare_field_b, 6534 NEXT_ENTRY(COMMON_HEX), item_param), 6535 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6536 ARGS_ENTRY_ARB(0, 0), 6537 ARGS_ENTRY(struct rte_flow_item_compare, 6538 b.value)), 6539 }, 6540 [ITEM_COMPARE_FIELD_B_POINTER] = { 6541 .name = "b_ptr", 6542 .help = "pointer to comparator immediate value", 6543 .next = NEXT(compare_field_b, 6544 NEXT_ENTRY(COMMON_HEX), item_param), 6545 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6546 b.pvalue), 6547 ARGS_ENTRY_ARB(0, 0), 6548 ARGS_ENTRY_ARB 6549 (sizeof(struct rte_flow_item_compare), 6550 FLOW_FIELD_PATTERN_SIZE)), 6551 }, 6552 [ITEM_COMPARE_FIELD_WIDTH] = { 6553 .name = "width", 6554 .help = "number of bits to compare", 6555 .next = NEXT(item_compare_field, 6556 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6557 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6558 width)), 6559 }, 6560 6561 /* Validate/create actions. */ 6562 [ACTIONS] = { 6563 .name = "actions", 6564 .help = "submit a list of associated actions", 6565 .next = NEXT(next_action), 6566 .call = parse_vc, 6567 }, 6568 [ACTION_NEXT] = { 6569 .name = "/", 6570 .help = "specify next action", 6571 .next = NEXT(next_action), 6572 }, 6573 [ACTION_END] = { 6574 .name = "end", 6575 .help = "end list of actions", 6576 .priv = PRIV_ACTION(END, 0), 6577 .call = parse_vc, 6578 }, 6579 [ACTION_VOID] = { 6580 .name = "void", 6581 .help = "no-op action", 6582 .priv = PRIV_ACTION(VOID, 0), 6583 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6584 .call = parse_vc, 6585 }, 6586 [ACTION_PASSTHRU] = { 6587 .name = "passthru", 6588 .help = "let subsequent rule process matched packets", 6589 .priv = PRIV_ACTION(PASSTHRU, 0), 6590 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6591 .call = parse_vc, 6592 }, 6593 [ACTION_SKIP_CMAN] = { 6594 .name = "skip_cman", 6595 .help = "bypass cman on received packets", 6596 .priv = PRIV_ACTION(SKIP_CMAN, 0), 6597 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6598 .call = parse_vc, 6599 }, 6600 [ACTION_JUMP] = { 6601 .name = "jump", 6602 .help = "redirect traffic to a given group", 6603 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 6604 .next = NEXT(action_jump), 6605 .call = parse_vc, 6606 }, 6607 [ACTION_JUMP_GROUP] = { 6608 .name = "group", 6609 .help = "group to redirect traffic to", 6610 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 6611 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 6612 .call = parse_vc_conf, 6613 }, 6614 [ACTION_MARK] = { 6615 .name = "mark", 6616 .help = "attach 32 bit value to packets", 6617 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 6618 .next = NEXT(action_mark), 6619 .call = parse_vc, 6620 }, 6621 [ACTION_MARK_ID] = { 6622 .name = "id", 6623 .help = "32 bit value to return with packets", 6624 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6625 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 6626 .call = parse_vc_conf, 6627 }, 6628 [ACTION_FLAG] = { 6629 .name = "flag", 6630 .help = "flag packets", 6631 .priv = PRIV_ACTION(FLAG, 0), 6632 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6633 .call = parse_vc, 6634 }, 6635 [ACTION_QUEUE] = { 6636 .name = "queue", 6637 .help = "assign packets to a given queue index", 6638 .priv = PRIV_ACTION(QUEUE, 6639 sizeof(struct rte_flow_action_queue)), 6640 .next = NEXT(action_queue), 6641 .call = parse_vc, 6642 }, 6643 [ACTION_QUEUE_INDEX] = { 6644 .name = "index", 6645 .help = "queue index to use", 6646 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 6647 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 6648 .call = parse_vc_conf, 6649 }, 6650 [ACTION_DROP] = { 6651 .name = "drop", 6652 .help = "drop packets (note: passthru has priority)", 6653 .priv = PRIV_ACTION(DROP, 0), 6654 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6655 .call = parse_vc, 6656 }, 6657 [ACTION_COUNT] = { 6658 .name = "count", 6659 .help = "enable counters for this rule", 6660 .priv = PRIV_ACTION(COUNT, 6661 sizeof(struct rte_flow_action_count)), 6662 .next = NEXT(action_count), 6663 .call = parse_vc, 6664 }, 6665 [ACTION_COUNT_ID] = { 6666 .name = "identifier", 6667 .help = "counter identifier to use", 6668 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 6669 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 6670 .call = parse_vc_conf, 6671 }, 6672 [ACTION_RSS] = { 6673 .name = "rss", 6674 .help = "spread packets among several queues", 6675 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 6676 .next = NEXT(action_rss), 6677 .call = parse_vc_action_rss, 6678 }, 6679 [ACTION_RSS_FUNC] = { 6680 .name = "func", 6681 .help = "RSS hash function to apply", 6682 .next = NEXT(action_rss, 6683 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 6684 ACTION_RSS_FUNC_TOEPLITZ, 6685 ACTION_RSS_FUNC_SIMPLE_XOR, 6686 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 6687 }, 6688 [ACTION_RSS_FUNC_DEFAULT] = { 6689 .name = "default", 6690 .help = "default hash function", 6691 .call = parse_vc_action_rss_func, 6692 }, 6693 [ACTION_RSS_FUNC_TOEPLITZ] = { 6694 .name = "toeplitz", 6695 .help = "Toeplitz hash function", 6696 .call = parse_vc_action_rss_func, 6697 }, 6698 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 6699 .name = "simple_xor", 6700 .help = "simple XOR hash function", 6701 .call = parse_vc_action_rss_func, 6702 }, 6703 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 6704 .name = "symmetric_toeplitz", 6705 .help = "Symmetric Toeplitz hash function", 6706 .call = parse_vc_action_rss_func, 6707 }, 6708 [ACTION_RSS_LEVEL] = { 6709 .name = "level", 6710 .help = "encapsulation level for \"types\"", 6711 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6712 .args = ARGS(ARGS_ENTRY_ARB 6713 (offsetof(struct action_rss_data, conf) + 6714 offsetof(struct rte_flow_action_rss, level), 6715 sizeof(((struct rte_flow_action_rss *)0)-> 6716 level))), 6717 }, 6718 [ACTION_RSS_TYPES] = { 6719 .name = "types", 6720 .help = "specific RSS hash types", 6721 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 6722 }, 6723 [ACTION_RSS_TYPE] = { 6724 .name = "{type}", 6725 .help = "RSS hash type", 6726 .call = parse_vc_action_rss_type, 6727 .comp = comp_vc_action_rss_type, 6728 }, 6729 [ACTION_RSS_KEY] = { 6730 .name = "key", 6731 .help = "RSS hash key", 6732 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 6733 .args = ARGS(ARGS_ENTRY_ARB 6734 (offsetof(struct action_rss_data, conf) + 6735 offsetof(struct rte_flow_action_rss, key), 6736 sizeof(((struct rte_flow_action_rss *)0)->key)), 6737 ARGS_ENTRY_ARB 6738 (offsetof(struct action_rss_data, conf) + 6739 offsetof(struct rte_flow_action_rss, key_len), 6740 sizeof(((struct rte_flow_action_rss *)0)-> 6741 key_len)), 6742 ARGS_ENTRY(struct action_rss_data, key)), 6743 }, 6744 [ACTION_RSS_KEY_LEN] = { 6745 .name = "key_len", 6746 .help = "RSS hash key length in bytes", 6747 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6748 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6749 (offsetof(struct action_rss_data, conf) + 6750 offsetof(struct rte_flow_action_rss, key_len), 6751 sizeof(((struct rte_flow_action_rss *)0)-> 6752 key_len), 6753 0, 6754 RSS_HASH_KEY_LENGTH)), 6755 }, 6756 [ACTION_RSS_QUEUES] = { 6757 .name = "queues", 6758 .help = "queue indices to use", 6759 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 6760 .call = parse_vc_conf, 6761 }, 6762 [ACTION_RSS_QUEUE] = { 6763 .name = "{queue}", 6764 .help = "queue index", 6765 .call = parse_vc_action_rss_queue, 6766 .comp = comp_vc_action_rss_queue, 6767 }, 6768 [ACTION_PF] = { 6769 .name = "pf", 6770 .help = "direct traffic to physical function", 6771 .priv = PRIV_ACTION(PF, 0), 6772 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6773 .call = parse_vc, 6774 }, 6775 [ACTION_VF] = { 6776 .name = "vf", 6777 .help = "direct traffic to a virtual function ID", 6778 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 6779 .next = NEXT(action_vf), 6780 .call = parse_vc, 6781 }, 6782 [ACTION_VF_ORIGINAL] = { 6783 .name = "original", 6784 .help = "use original VF ID if possible", 6785 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 6786 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 6787 original, 1)), 6788 .call = parse_vc_conf, 6789 }, 6790 [ACTION_VF_ID] = { 6791 .name = "id", 6792 .help = "VF ID", 6793 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 6794 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 6795 .call = parse_vc_conf, 6796 }, 6797 [ACTION_PORT_ID] = { 6798 .name = "port_id", 6799 .help = "direct matching traffic to a given DPDK port ID", 6800 .priv = PRIV_ACTION(PORT_ID, 6801 sizeof(struct rte_flow_action_port_id)), 6802 .next = NEXT(action_port_id), 6803 .call = parse_vc, 6804 }, 6805 [ACTION_PORT_ID_ORIGINAL] = { 6806 .name = "original", 6807 .help = "use original DPDK port ID if possible", 6808 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 6809 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 6810 original, 1)), 6811 .call = parse_vc_conf, 6812 }, 6813 [ACTION_PORT_ID_ID] = { 6814 .name = "id", 6815 .help = "DPDK port ID", 6816 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 6817 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 6818 .call = parse_vc_conf, 6819 }, 6820 [ACTION_METER] = { 6821 .name = "meter", 6822 .help = "meter the directed packets at given id", 6823 .priv = PRIV_ACTION(METER, 6824 sizeof(struct rte_flow_action_meter)), 6825 .next = NEXT(action_meter), 6826 .call = parse_vc, 6827 }, 6828 [ACTION_METER_COLOR] = { 6829 .name = "color", 6830 .help = "meter color for the packets", 6831 .priv = PRIV_ACTION(METER_COLOR, 6832 sizeof(struct rte_flow_action_meter_color)), 6833 .next = NEXT(action_meter_color), 6834 .call = parse_vc, 6835 }, 6836 [ACTION_METER_COLOR_TYPE] = { 6837 .name = "type", 6838 .help = "specific meter color", 6839 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6840 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 6841 ACTION_METER_COLOR_YELLOW, 6842 ACTION_METER_COLOR_RED)), 6843 }, 6844 [ACTION_METER_COLOR_GREEN] = { 6845 .name = "green", 6846 .help = "meter color green", 6847 .call = parse_vc_action_meter_color_type, 6848 }, 6849 [ACTION_METER_COLOR_YELLOW] = { 6850 .name = "yellow", 6851 .help = "meter color yellow", 6852 .call = parse_vc_action_meter_color_type, 6853 }, 6854 [ACTION_METER_COLOR_RED] = { 6855 .name = "red", 6856 .help = "meter color red", 6857 .call = parse_vc_action_meter_color_type, 6858 }, 6859 [ACTION_METER_ID] = { 6860 .name = "mtr_id", 6861 .help = "meter id to use", 6862 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 6863 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 6864 .call = parse_vc_conf, 6865 }, 6866 [ACTION_METER_MARK] = { 6867 .name = "meter_mark", 6868 .help = "meter the directed packets using profile and policy", 6869 .priv = PRIV_ACTION(METER_MARK, 6870 sizeof(struct rte_flow_action_meter_mark)), 6871 .next = NEXT(action_meter_mark), 6872 .call = parse_vc, 6873 }, 6874 [ACTION_METER_PROFILE] = { 6875 .name = "mtr_profile", 6876 .help = "meter profile id to use", 6877 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 6878 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6879 }, 6880 [ACTION_METER_PROFILE_ID2PTR] = { 6881 .name = "{mtr_profile_id}", 6882 .type = "PROFILE_ID", 6883 .help = "meter profile id", 6884 .next = NEXT(action_meter_mark), 6885 .call = parse_meter_profile_id2ptr, 6886 .comp = comp_none, 6887 }, 6888 [ACTION_METER_POLICY] = { 6889 .name = "mtr_policy", 6890 .help = "meter policy id to use", 6891 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 6892 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6893 }, 6894 [ACTION_METER_POLICY_ID2PTR] = { 6895 .name = "{mtr_policy_id}", 6896 .type = "POLICY_ID", 6897 .help = "meter policy id", 6898 .next = NEXT(action_meter_mark), 6899 .call = parse_meter_policy_id2ptr, 6900 .comp = comp_none, 6901 }, 6902 [ACTION_METER_COLOR_MODE] = { 6903 .name = "mtr_color_mode", 6904 .help = "meter color awareness mode", 6905 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6906 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 6907 .call = parse_vc_conf, 6908 }, 6909 [ACTION_METER_STATE] = { 6910 .name = "mtr_state", 6911 .help = "meter state", 6912 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6913 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 6914 .call = parse_vc_conf, 6915 }, 6916 [ACTION_OF_DEC_NW_TTL] = { 6917 .name = "of_dec_nw_ttl", 6918 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 6919 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 6920 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6921 .call = parse_vc, 6922 }, 6923 [ACTION_OF_POP_VLAN] = { 6924 .name = "of_pop_vlan", 6925 .help = "OpenFlow's OFPAT_POP_VLAN", 6926 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 6927 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6928 .call = parse_vc, 6929 }, 6930 [ACTION_OF_PUSH_VLAN] = { 6931 .name = "of_push_vlan", 6932 .help = "OpenFlow's OFPAT_PUSH_VLAN", 6933 .priv = PRIV_ACTION 6934 (OF_PUSH_VLAN, 6935 sizeof(struct rte_flow_action_of_push_vlan)), 6936 .next = NEXT(action_of_push_vlan), 6937 .call = parse_vc, 6938 }, 6939 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 6940 .name = "ethertype", 6941 .help = "EtherType", 6942 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 6943 .args = ARGS(ARGS_ENTRY_HTON 6944 (struct rte_flow_action_of_push_vlan, 6945 ethertype)), 6946 .call = parse_vc_conf, 6947 }, 6948 [ACTION_OF_SET_VLAN_VID] = { 6949 .name = "of_set_vlan_vid", 6950 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 6951 .priv = PRIV_ACTION 6952 (OF_SET_VLAN_VID, 6953 sizeof(struct rte_flow_action_of_set_vlan_vid)), 6954 .next = NEXT(action_of_set_vlan_vid), 6955 .call = parse_vc, 6956 }, 6957 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 6958 .name = "vlan_vid", 6959 .help = "VLAN id", 6960 .next = NEXT(action_of_set_vlan_vid, 6961 NEXT_ENTRY(COMMON_UNSIGNED)), 6962 .args = ARGS(ARGS_ENTRY_HTON 6963 (struct rte_flow_action_of_set_vlan_vid, 6964 vlan_vid)), 6965 .call = parse_vc_conf, 6966 }, 6967 [ACTION_OF_SET_VLAN_PCP] = { 6968 .name = "of_set_vlan_pcp", 6969 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 6970 .priv = PRIV_ACTION 6971 (OF_SET_VLAN_PCP, 6972 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 6973 .next = NEXT(action_of_set_vlan_pcp), 6974 .call = parse_vc, 6975 }, 6976 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 6977 .name = "vlan_pcp", 6978 .help = "VLAN priority", 6979 .next = NEXT(action_of_set_vlan_pcp, 6980 NEXT_ENTRY(COMMON_UNSIGNED)), 6981 .args = ARGS(ARGS_ENTRY_HTON 6982 (struct rte_flow_action_of_set_vlan_pcp, 6983 vlan_pcp)), 6984 .call = parse_vc_conf, 6985 }, 6986 [ACTION_OF_POP_MPLS] = { 6987 .name = "of_pop_mpls", 6988 .help = "OpenFlow's OFPAT_POP_MPLS", 6989 .priv = PRIV_ACTION(OF_POP_MPLS, 6990 sizeof(struct rte_flow_action_of_pop_mpls)), 6991 .next = NEXT(action_of_pop_mpls), 6992 .call = parse_vc, 6993 }, 6994 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 6995 .name = "ethertype", 6996 .help = "EtherType", 6997 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6998 .args = ARGS(ARGS_ENTRY_HTON 6999 (struct rte_flow_action_of_pop_mpls, 7000 ethertype)), 7001 .call = parse_vc_conf, 7002 }, 7003 [ACTION_OF_PUSH_MPLS] = { 7004 .name = "of_push_mpls", 7005 .help = "OpenFlow's OFPAT_PUSH_MPLS", 7006 .priv = PRIV_ACTION 7007 (OF_PUSH_MPLS, 7008 sizeof(struct rte_flow_action_of_push_mpls)), 7009 .next = NEXT(action_of_push_mpls), 7010 .call = parse_vc, 7011 }, 7012 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 7013 .name = "ethertype", 7014 .help = "EtherType", 7015 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 7016 .args = ARGS(ARGS_ENTRY_HTON 7017 (struct rte_flow_action_of_push_mpls, 7018 ethertype)), 7019 .call = parse_vc_conf, 7020 }, 7021 [ACTION_VXLAN_ENCAP] = { 7022 .name = "vxlan_encap", 7023 .help = "VXLAN encapsulation, uses configuration set by \"set" 7024 " vxlan\"", 7025 .priv = PRIV_ACTION(VXLAN_ENCAP, 7026 sizeof(struct action_vxlan_encap_data)), 7027 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7028 .call = parse_vc_action_vxlan_encap, 7029 }, 7030 [ACTION_VXLAN_DECAP] = { 7031 .name = "vxlan_decap", 7032 .help = "Performs a decapsulation action by stripping all" 7033 " headers of the VXLAN tunnel network overlay from the" 7034 " matched flow.", 7035 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 7036 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7037 .call = parse_vc, 7038 }, 7039 [ACTION_NVGRE_ENCAP] = { 7040 .name = "nvgre_encap", 7041 .help = "NVGRE encapsulation, uses configuration set by \"set" 7042 " nvgre\"", 7043 .priv = PRIV_ACTION(NVGRE_ENCAP, 7044 sizeof(struct action_nvgre_encap_data)), 7045 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7046 .call = parse_vc_action_nvgre_encap, 7047 }, 7048 [ACTION_NVGRE_DECAP] = { 7049 .name = "nvgre_decap", 7050 .help = "Performs a decapsulation action by stripping all" 7051 " headers of the NVGRE tunnel network overlay from the" 7052 " matched flow.", 7053 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 7054 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7055 .call = parse_vc, 7056 }, 7057 [ACTION_L2_ENCAP] = { 7058 .name = "l2_encap", 7059 .help = "l2 encap, uses configuration set by" 7060 " \"set l2_encap\"", 7061 .priv = PRIV_ACTION(RAW_ENCAP, 7062 sizeof(struct action_raw_encap_data)), 7063 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7064 .call = parse_vc_action_l2_encap, 7065 }, 7066 [ACTION_L2_DECAP] = { 7067 .name = "l2_decap", 7068 .help = "l2 decap, uses configuration set by" 7069 " \"set l2_decap\"", 7070 .priv = PRIV_ACTION(RAW_DECAP, 7071 sizeof(struct action_raw_decap_data)), 7072 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7073 .call = parse_vc_action_l2_decap, 7074 }, 7075 [ACTION_MPLSOGRE_ENCAP] = { 7076 .name = "mplsogre_encap", 7077 .help = "mplsogre encapsulation, uses configuration set by" 7078 " \"set mplsogre_encap\"", 7079 .priv = PRIV_ACTION(RAW_ENCAP, 7080 sizeof(struct action_raw_encap_data)), 7081 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7082 .call = parse_vc_action_mplsogre_encap, 7083 }, 7084 [ACTION_MPLSOGRE_DECAP] = { 7085 .name = "mplsogre_decap", 7086 .help = "mplsogre decapsulation, uses configuration set by" 7087 " \"set mplsogre_decap\"", 7088 .priv = PRIV_ACTION(RAW_DECAP, 7089 sizeof(struct action_raw_decap_data)), 7090 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7091 .call = parse_vc_action_mplsogre_decap, 7092 }, 7093 [ACTION_MPLSOUDP_ENCAP] = { 7094 .name = "mplsoudp_encap", 7095 .help = "mplsoudp encapsulation, uses configuration set by" 7096 " \"set mplsoudp_encap\"", 7097 .priv = PRIV_ACTION(RAW_ENCAP, 7098 sizeof(struct action_raw_encap_data)), 7099 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7100 .call = parse_vc_action_mplsoudp_encap, 7101 }, 7102 [ACTION_MPLSOUDP_DECAP] = { 7103 .name = "mplsoudp_decap", 7104 .help = "mplsoudp decapsulation, uses configuration set by" 7105 " \"set mplsoudp_decap\"", 7106 .priv = PRIV_ACTION(RAW_DECAP, 7107 sizeof(struct action_raw_decap_data)), 7108 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7109 .call = parse_vc_action_mplsoudp_decap, 7110 }, 7111 [ACTION_SET_IPV4_SRC] = { 7112 .name = "set_ipv4_src", 7113 .help = "Set a new IPv4 source address in the outermost" 7114 " IPv4 header", 7115 .priv = PRIV_ACTION(SET_IPV4_SRC, 7116 sizeof(struct rte_flow_action_set_ipv4)), 7117 .next = NEXT(action_set_ipv4_src), 7118 .call = parse_vc, 7119 }, 7120 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 7121 .name = "ipv4_addr", 7122 .help = "new IPv4 source address to set", 7123 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 7124 .args = ARGS(ARGS_ENTRY_HTON 7125 (struct rte_flow_action_set_ipv4, ipv4_addr)), 7126 .call = parse_vc_conf, 7127 }, 7128 [ACTION_SET_IPV4_DST] = { 7129 .name = "set_ipv4_dst", 7130 .help = "Set a new IPv4 destination address in the outermost" 7131 " IPv4 header", 7132 .priv = PRIV_ACTION(SET_IPV4_DST, 7133 sizeof(struct rte_flow_action_set_ipv4)), 7134 .next = NEXT(action_set_ipv4_dst), 7135 .call = parse_vc, 7136 }, 7137 [ACTION_SET_IPV4_DST_IPV4_DST] = { 7138 .name = "ipv4_addr", 7139 .help = "new IPv4 destination address to set", 7140 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 7141 .args = ARGS(ARGS_ENTRY_HTON 7142 (struct rte_flow_action_set_ipv4, ipv4_addr)), 7143 .call = parse_vc_conf, 7144 }, 7145 [ACTION_SET_IPV6_SRC] = { 7146 .name = "set_ipv6_src", 7147 .help = "Set a new IPv6 source address in the outermost" 7148 " IPv6 header", 7149 .priv = PRIV_ACTION(SET_IPV6_SRC, 7150 sizeof(struct rte_flow_action_set_ipv6)), 7151 .next = NEXT(action_set_ipv6_src), 7152 .call = parse_vc, 7153 }, 7154 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 7155 .name = "ipv6_addr", 7156 .help = "new IPv6 source address to set", 7157 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7158 .args = ARGS(ARGS_ENTRY_HTON 7159 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7160 .call = parse_vc_conf, 7161 }, 7162 [ACTION_SET_IPV6_DST] = { 7163 .name = "set_ipv6_dst", 7164 .help = "Set a new IPv6 destination address in the outermost" 7165 " IPv6 header", 7166 .priv = PRIV_ACTION(SET_IPV6_DST, 7167 sizeof(struct rte_flow_action_set_ipv6)), 7168 .next = NEXT(action_set_ipv6_dst), 7169 .call = parse_vc, 7170 }, 7171 [ACTION_SET_IPV6_DST_IPV6_DST] = { 7172 .name = "ipv6_addr", 7173 .help = "new IPv6 destination address to set", 7174 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7175 .args = ARGS(ARGS_ENTRY_HTON 7176 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7177 .call = parse_vc_conf, 7178 }, 7179 [ACTION_SET_TP_SRC] = { 7180 .name = "set_tp_src", 7181 .help = "set a new source port number in the outermost" 7182 " TCP/UDP header", 7183 .priv = PRIV_ACTION(SET_TP_SRC, 7184 sizeof(struct rte_flow_action_set_tp)), 7185 .next = NEXT(action_set_tp_src), 7186 .call = parse_vc, 7187 }, 7188 [ACTION_SET_TP_SRC_TP_SRC] = { 7189 .name = "port", 7190 .help = "new source port number to set", 7191 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 7192 .args = ARGS(ARGS_ENTRY_HTON 7193 (struct rte_flow_action_set_tp, port)), 7194 .call = parse_vc_conf, 7195 }, 7196 [ACTION_SET_TP_DST] = { 7197 .name = "set_tp_dst", 7198 .help = "set a new destination port number in the outermost" 7199 " TCP/UDP header", 7200 .priv = PRIV_ACTION(SET_TP_DST, 7201 sizeof(struct rte_flow_action_set_tp)), 7202 .next = NEXT(action_set_tp_dst), 7203 .call = parse_vc, 7204 }, 7205 [ACTION_SET_TP_DST_TP_DST] = { 7206 .name = "port", 7207 .help = "new destination port number to set", 7208 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 7209 .args = ARGS(ARGS_ENTRY_HTON 7210 (struct rte_flow_action_set_tp, port)), 7211 .call = parse_vc_conf, 7212 }, 7213 [ACTION_MAC_SWAP] = { 7214 .name = "mac_swap", 7215 .help = "Swap the source and destination MAC addresses" 7216 " in the outermost Ethernet header", 7217 .priv = PRIV_ACTION(MAC_SWAP, 0), 7218 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7219 .call = parse_vc, 7220 }, 7221 [ACTION_DEC_TTL] = { 7222 .name = "dec_ttl", 7223 .help = "decrease network TTL if available", 7224 .priv = PRIV_ACTION(DEC_TTL, 0), 7225 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7226 .call = parse_vc, 7227 }, 7228 [ACTION_SET_TTL] = { 7229 .name = "set_ttl", 7230 .help = "set ttl value", 7231 .priv = PRIV_ACTION(SET_TTL, 7232 sizeof(struct rte_flow_action_set_ttl)), 7233 .next = NEXT(action_set_ttl), 7234 .call = parse_vc, 7235 }, 7236 [ACTION_SET_TTL_TTL] = { 7237 .name = "ttl_value", 7238 .help = "new ttl value to set", 7239 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 7240 .args = ARGS(ARGS_ENTRY_HTON 7241 (struct rte_flow_action_set_ttl, ttl_value)), 7242 .call = parse_vc_conf, 7243 }, 7244 [ACTION_SET_MAC_SRC] = { 7245 .name = "set_mac_src", 7246 .help = "set source mac address", 7247 .priv = PRIV_ACTION(SET_MAC_SRC, 7248 sizeof(struct rte_flow_action_set_mac)), 7249 .next = NEXT(action_set_mac_src), 7250 .call = parse_vc, 7251 }, 7252 [ACTION_SET_MAC_SRC_MAC_SRC] = { 7253 .name = "mac_addr", 7254 .help = "new source mac address", 7255 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 7256 .args = ARGS(ARGS_ENTRY_HTON 7257 (struct rte_flow_action_set_mac, mac_addr)), 7258 .call = parse_vc_conf, 7259 }, 7260 [ACTION_SET_MAC_DST] = { 7261 .name = "set_mac_dst", 7262 .help = "set destination mac address", 7263 .priv = PRIV_ACTION(SET_MAC_DST, 7264 sizeof(struct rte_flow_action_set_mac)), 7265 .next = NEXT(action_set_mac_dst), 7266 .call = parse_vc, 7267 }, 7268 [ACTION_SET_MAC_DST_MAC_DST] = { 7269 .name = "mac_addr", 7270 .help = "new destination mac address to set", 7271 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 7272 .args = ARGS(ARGS_ENTRY_HTON 7273 (struct rte_flow_action_set_mac, mac_addr)), 7274 .call = parse_vc_conf, 7275 }, 7276 [ACTION_INC_TCP_SEQ] = { 7277 .name = "inc_tcp_seq", 7278 .help = "increase TCP sequence number", 7279 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 7280 .next = NEXT(action_inc_tcp_seq), 7281 .call = parse_vc, 7282 }, 7283 [ACTION_INC_TCP_SEQ_VALUE] = { 7284 .name = "value", 7285 .help = "the value to increase TCP sequence number by", 7286 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7287 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7288 .call = parse_vc_conf, 7289 }, 7290 [ACTION_DEC_TCP_SEQ] = { 7291 .name = "dec_tcp_seq", 7292 .help = "decrease TCP sequence number", 7293 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 7294 .next = NEXT(action_dec_tcp_seq), 7295 .call = parse_vc, 7296 }, 7297 [ACTION_DEC_TCP_SEQ_VALUE] = { 7298 .name = "value", 7299 .help = "the value to decrease TCP sequence number by", 7300 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7301 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7302 .call = parse_vc_conf, 7303 }, 7304 [ACTION_INC_TCP_ACK] = { 7305 .name = "inc_tcp_ack", 7306 .help = "increase TCP acknowledgment number", 7307 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 7308 .next = NEXT(action_inc_tcp_ack), 7309 .call = parse_vc, 7310 }, 7311 [ACTION_INC_TCP_ACK_VALUE] = { 7312 .name = "value", 7313 .help = "the value to increase TCP acknowledgment number by", 7314 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7315 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7316 .call = parse_vc_conf, 7317 }, 7318 [ACTION_DEC_TCP_ACK] = { 7319 .name = "dec_tcp_ack", 7320 .help = "decrease TCP acknowledgment number", 7321 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 7322 .next = NEXT(action_dec_tcp_ack), 7323 .call = parse_vc, 7324 }, 7325 [ACTION_DEC_TCP_ACK_VALUE] = { 7326 .name = "value", 7327 .help = "the value to decrease TCP acknowledgment number by", 7328 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7329 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7330 .call = parse_vc_conf, 7331 }, 7332 [ACTION_RAW_ENCAP] = { 7333 .name = "raw_encap", 7334 .help = "encapsulation data, defined by set raw_encap", 7335 .priv = PRIV_ACTION(RAW_ENCAP, 7336 sizeof(struct action_raw_encap_data)), 7337 .next = NEXT(action_raw_encap), 7338 .call = parse_vc_action_raw_encap, 7339 }, 7340 [ACTION_RAW_ENCAP_SIZE] = { 7341 .name = "size", 7342 .help = "raw encap size", 7343 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7344 NEXT_ENTRY(COMMON_UNSIGNED)), 7345 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_raw_encap, size)), 7346 .call = parse_vc_conf, 7347 }, 7348 [ACTION_RAW_ENCAP_INDEX] = { 7349 .name = "index", 7350 .help = "the index of raw_encap_confs", 7351 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 7352 }, 7353 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 7354 .name = "{index}", 7355 .type = "UNSIGNED", 7356 .help = "unsigned integer value", 7357 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7358 .call = parse_vc_action_raw_encap_index, 7359 .comp = comp_set_raw_index, 7360 }, 7361 [ACTION_RAW_DECAP] = { 7362 .name = "raw_decap", 7363 .help = "decapsulation data, defined by set raw_encap", 7364 .priv = PRIV_ACTION(RAW_DECAP, 7365 sizeof(struct action_raw_decap_data)), 7366 .next = NEXT(action_raw_decap), 7367 .call = parse_vc_action_raw_decap, 7368 }, 7369 [ACTION_RAW_DECAP_INDEX] = { 7370 .name = "index", 7371 .help = "the index of raw_encap_confs", 7372 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 7373 }, 7374 [ACTION_RAW_DECAP_INDEX_VALUE] = { 7375 .name = "{index}", 7376 .type = "UNSIGNED", 7377 .help = "unsigned integer value", 7378 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7379 .call = parse_vc_action_raw_decap_index, 7380 .comp = comp_set_raw_index, 7381 }, 7382 [ACTION_MODIFY_FIELD] = { 7383 .name = "modify_field", 7384 .help = "modify destination field with data from source field", 7385 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 7386 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 7387 .call = parse_vc, 7388 }, 7389 [ACTION_MODIFY_FIELD_OP] = { 7390 .name = "op", 7391 .help = "operation type", 7392 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 7393 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 7394 .call = parse_vc_conf, 7395 }, 7396 [ACTION_MODIFY_FIELD_OP_VALUE] = { 7397 .name = "{operation}", 7398 .help = "operation type value", 7399 .call = parse_vc_modify_field_op, 7400 .comp = comp_set_modify_field_op, 7401 }, 7402 [ACTION_MODIFY_FIELD_DST_TYPE] = { 7403 .name = "dst_type", 7404 .help = "destination field type", 7405 .next = NEXT(action_modify_field_dst, 7406 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 7407 .call = parse_vc_conf, 7408 }, 7409 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 7410 .name = "{dst_type}", 7411 .help = "destination field type value", 7412 .call = parse_vc_modify_field_id, 7413 .comp = comp_set_modify_field_id, 7414 }, 7415 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 7416 .name = "dst_level", 7417 .help = "destination field level", 7418 .next = NEXT(action_modify_field_dst, 7419 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), 7420 .call = parse_vc_conf, 7421 }, 7422 [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { 7423 .name = "{dst_level}", 7424 .help = "destination field level value", 7425 .call = parse_vc_modify_field_level, 7426 .comp = comp_none, 7427 }, 7428 [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { 7429 .name = "dst_tag_index", 7430 .help = "destination field tag array", 7431 .next = NEXT(action_modify_field_dst, 7432 NEXT_ENTRY(COMMON_UNSIGNED)), 7433 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7434 dst.tag_index)), 7435 .call = parse_vc_conf, 7436 }, 7437 [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { 7438 .name = "dst_type_id", 7439 .help = "destination field type ID", 7440 .next = NEXT(action_modify_field_dst, 7441 NEXT_ENTRY(COMMON_UNSIGNED)), 7442 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7443 dst.type)), 7444 .call = parse_vc_conf, 7445 }, 7446 [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { 7447 .name = "dst_class", 7448 .help = "destination field class ID", 7449 .next = NEXT(action_modify_field_dst, 7450 NEXT_ENTRY(COMMON_UNSIGNED)), 7451 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7452 dst.class_id)), 7453 .call = parse_vc_conf, 7454 }, 7455 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 7456 .name = "dst_offset", 7457 .help = "destination field bit offset", 7458 .next = NEXT(action_modify_field_dst, 7459 NEXT_ENTRY(COMMON_UNSIGNED)), 7460 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7461 dst.offset)), 7462 .call = parse_vc_conf, 7463 }, 7464 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 7465 .name = "src_type", 7466 .help = "source field type", 7467 .next = NEXT(action_modify_field_src, 7468 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 7469 .call = parse_vc_conf, 7470 }, 7471 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 7472 .name = "{src_type}", 7473 .help = "source field type value", 7474 .call = parse_vc_modify_field_id, 7475 .comp = comp_set_modify_field_id, 7476 }, 7477 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 7478 .name = "src_level", 7479 .help = "source field level", 7480 .next = NEXT(action_modify_field_src, 7481 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), 7482 .call = parse_vc_conf, 7483 }, 7484 [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { 7485 .name = "{src_level}", 7486 .help = "source field level value", 7487 .call = parse_vc_modify_field_level, 7488 .comp = comp_none, 7489 }, 7490 [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { 7491 .name = "src_tag_index", 7492 .help = "source field tag array", 7493 .next = NEXT(action_modify_field_src, 7494 NEXT_ENTRY(COMMON_UNSIGNED)), 7495 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7496 src.tag_index)), 7497 .call = parse_vc_conf, 7498 }, 7499 [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { 7500 .name = "src_type_id", 7501 .help = "source field type ID", 7502 .next = NEXT(action_modify_field_src, 7503 NEXT_ENTRY(COMMON_UNSIGNED)), 7504 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7505 src.type)), 7506 .call = parse_vc_conf, 7507 }, 7508 [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { 7509 .name = "src_class", 7510 .help = "source field class ID", 7511 .next = NEXT(action_modify_field_src, 7512 NEXT_ENTRY(COMMON_UNSIGNED)), 7513 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7514 src.class_id)), 7515 .call = parse_vc_conf, 7516 }, 7517 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 7518 .name = "src_offset", 7519 .help = "source field bit offset", 7520 .next = NEXT(action_modify_field_src, 7521 NEXT_ENTRY(COMMON_UNSIGNED)), 7522 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7523 src.offset)), 7524 .call = parse_vc_conf, 7525 }, 7526 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 7527 .name = "src_value", 7528 .help = "source immediate value", 7529 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7530 NEXT_ENTRY(COMMON_HEX)), 7531 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 7532 ARGS_ENTRY_ARB(0, 0), 7533 ARGS_ENTRY(struct rte_flow_action_modify_field, 7534 src.value)), 7535 .call = parse_vc_conf, 7536 }, 7537 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 7538 .name = "src_ptr", 7539 .help = "pointer to source immediate value", 7540 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7541 NEXT_ENTRY(COMMON_HEX)), 7542 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7543 src.pvalue), 7544 ARGS_ENTRY_ARB(0, 0), 7545 ARGS_ENTRY_ARB 7546 (sizeof(struct rte_flow_action_modify_field), 7547 FLOW_FIELD_PATTERN_SIZE)), 7548 .call = parse_vc_conf, 7549 }, 7550 [ACTION_MODIFY_FIELD_WIDTH] = { 7551 .name = "width", 7552 .help = "number of bits to copy", 7553 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7554 NEXT_ENTRY(COMMON_UNSIGNED)), 7555 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7556 width)), 7557 .call = parse_vc_conf, 7558 }, 7559 [ACTION_SEND_TO_KERNEL] = { 7560 .name = "send_to_kernel", 7561 .help = "send packets to kernel", 7562 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 7563 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7564 .call = parse_vc, 7565 }, 7566 [ACTION_IPV6_EXT_REMOVE] = { 7567 .name = "ipv6_ext_remove", 7568 .help = "IPv6 extension type, defined by set ipv6_ext_remove", 7569 .priv = PRIV_ACTION(IPV6_EXT_REMOVE, 7570 sizeof(struct action_ipv6_ext_remove_data)), 7571 .next = NEXT(action_ipv6_ext_remove), 7572 .call = parse_vc_action_ipv6_ext_remove, 7573 }, 7574 [ACTION_IPV6_EXT_REMOVE_INDEX] = { 7575 .name = "index", 7576 .help = "the index of ipv6_ext_remove", 7577 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), 7578 }, 7579 [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { 7580 .name = "{index}", 7581 .type = "UNSIGNED", 7582 .help = "unsigned integer value", 7583 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7584 .call = parse_vc_action_ipv6_ext_remove_index, 7585 .comp = comp_set_ipv6_ext_index, 7586 }, 7587 [ACTION_IPV6_EXT_PUSH] = { 7588 .name = "ipv6_ext_push", 7589 .help = "IPv6 extension data, defined by set ipv6_ext_push", 7590 .priv = PRIV_ACTION(IPV6_EXT_PUSH, 7591 sizeof(struct action_ipv6_ext_push_data)), 7592 .next = NEXT(action_ipv6_ext_push), 7593 .call = parse_vc_action_ipv6_ext_push, 7594 }, 7595 [ACTION_IPV6_EXT_PUSH_INDEX] = { 7596 .name = "index", 7597 .help = "the index of ipv6_ext_push", 7598 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), 7599 }, 7600 [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { 7601 .name = "{index}", 7602 .type = "UNSIGNED", 7603 .help = "unsigned integer value", 7604 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7605 .call = parse_vc_action_ipv6_ext_push_index, 7606 .comp = comp_set_ipv6_ext_index, 7607 }, 7608 [ACTION_NAT64] = { 7609 .name = "nat64", 7610 .help = "NAT64 IP headers translation", 7611 .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), 7612 .next = NEXT(action_nat64), 7613 .call = parse_vc, 7614 }, 7615 [ACTION_NAT64_MODE] = { 7616 .name = "type", 7617 .help = "NAT64 translation type", 7618 .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), 7619 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), 7620 .call = parse_vc_conf, 7621 }, 7622 [ACTION_JUMP_TO_TABLE_INDEX] = { 7623 .name = "jump_to_table_index", 7624 .help = "Jump to table index", 7625 .priv = PRIV_ACTION(JUMP_TO_TABLE_INDEX, 7626 sizeof(struct rte_flow_action_jump_to_table_index)), 7627 .next = NEXT(action_jump_to_table_index), 7628 .call = parse_vc, 7629 }, 7630 [ACTION_JUMP_TO_TABLE_INDEX_TABLE] = { 7631 .name = "table", 7632 .help = "table to redirect traffic to", 7633 .next = NEXT(action_jump_to_table_index, NEXT_ENTRY(COMMON_UNSIGNED)), 7634 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump_to_table_index, table)), 7635 .call = parse_vc_conf, 7636 }, 7637 [ACTION_JUMP_TO_TABLE_INDEX_INDEX] = { 7638 .name = "index", 7639 .help = "rule index to redirect traffic to", 7640 .next = NEXT(action_jump_to_table_index, NEXT_ENTRY(COMMON_UNSIGNED)), 7641 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump_to_table_index, index)), 7642 .call = parse_vc_conf, 7643 }, 7644 7645 /* Top level command. */ 7646 [SET] = { 7647 .name = "set", 7648 .help = "set raw encap/decap/sample data", 7649 .type = "set raw_encap|raw_decap <index> <pattern>" 7650 " or set sample_actions <index> <action>", 7651 .next = NEXT(NEXT_ENTRY 7652 (SET_RAW_ENCAP, 7653 SET_RAW_DECAP, 7654 SET_SAMPLE_ACTIONS, 7655 SET_IPV6_EXT_REMOVE, 7656 SET_IPV6_EXT_PUSH)), 7657 .call = parse_set_init, 7658 }, 7659 /* Sub-level commands. */ 7660 [SET_RAW_ENCAP] = { 7661 .name = "raw_encap", 7662 .help = "set raw encap data", 7663 .next = NEXT(next_set_raw), 7664 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7665 (offsetof(struct buffer, port), 7666 sizeof(((struct buffer *)0)->port), 7667 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7668 .call = parse_set_raw_encap_decap, 7669 }, 7670 [SET_RAW_DECAP] = { 7671 .name = "raw_decap", 7672 .help = "set raw decap data", 7673 .next = NEXT(next_set_raw), 7674 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7675 (offsetof(struct buffer, port), 7676 sizeof(((struct buffer *)0)->port), 7677 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7678 .call = parse_set_raw_encap_decap, 7679 }, 7680 [SET_RAW_INDEX] = { 7681 .name = "{index}", 7682 .type = "COMMON_UNSIGNED", 7683 .help = "index of raw_encap/raw_decap data", 7684 .next = NEXT(next_item), 7685 .call = parse_port, 7686 }, 7687 [SET_SAMPLE_INDEX] = { 7688 .name = "{index}", 7689 .type = "UNSIGNED", 7690 .help = "index of sample actions", 7691 .next = NEXT(next_action_sample), 7692 .call = parse_port, 7693 }, 7694 [SET_SAMPLE_ACTIONS] = { 7695 .name = "sample_actions", 7696 .help = "set sample actions list", 7697 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 7698 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7699 (offsetof(struct buffer, port), 7700 sizeof(((struct buffer *)0)->port), 7701 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 7702 .call = parse_set_sample_action, 7703 }, 7704 [SET_IPV6_EXT_PUSH] = { 7705 .name = "ipv6_ext_push", 7706 .help = "set IPv6 extension header", 7707 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7708 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7709 (offsetof(struct buffer, port), 7710 sizeof(((struct buffer *)0)->port), 7711 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7712 .call = parse_set_ipv6_ext_action, 7713 }, 7714 [SET_IPV6_EXT_REMOVE] = { 7715 .name = "ipv6_ext_remove", 7716 .help = "set IPv6 extension header", 7717 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7718 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7719 (offsetof(struct buffer, port), 7720 sizeof(((struct buffer *)0)->port), 7721 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7722 .call = parse_set_ipv6_ext_action, 7723 }, 7724 [SET_IPV6_EXT_INDEX] = { 7725 .name = "{index}", 7726 .type = "UNSIGNED", 7727 .help = "index of ipv6 extension push/remove actions", 7728 .next = NEXT(item_ipv6_push_ext), 7729 .call = parse_port, 7730 }, 7731 [ITEM_IPV6_PUSH_REMOVE_EXT] = { 7732 .name = "ipv6_ext", 7733 .help = "set IPv6 extension header", 7734 .priv = PRIV_ITEM(IPV6_EXT, 7735 sizeof(struct rte_flow_item_ipv6_ext)), 7736 .next = NEXT(item_ipv6_push_ext_type), 7737 .call = parse_vc, 7738 }, 7739 [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { 7740 .name = "type", 7741 .help = "set IPv6 extension type", 7742 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 7743 next_hdr)), 7744 .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), 7745 item_param), 7746 }, 7747 [ACTION_SET_TAG] = { 7748 .name = "set_tag", 7749 .help = "set tag", 7750 .priv = PRIV_ACTION(SET_TAG, 7751 sizeof(struct rte_flow_action_set_tag)), 7752 .next = NEXT(action_set_tag), 7753 .call = parse_vc, 7754 }, 7755 [ACTION_SET_TAG_INDEX] = { 7756 .name = "index", 7757 .help = "index of tag array", 7758 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7759 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 7760 .call = parse_vc_conf, 7761 }, 7762 [ACTION_SET_TAG_DATA] = { 7763 .name = "data", 7764 .help = "tag value", 7765 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7766 .args = ARGS(ARGS_ENTRY 7767 (struct rte_flow_action_set_tag, data)), 7768 .call = parse_vc_conf, 7769 }, 7770 [ACTION_SET_TAG_MASK] = { 7771 .name = "mask", 7772 .help = "mask for tag value", 7773 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7774 .args = ARGS(ARGS_ENTRY 7775 (struct rte_flow_action_set_tag, mask)), 7776 .call = parse_vc_conf, 7777 }, 7778 [ACTION_SET_META] = { 7779 .name = "set_meta", 7780 .help = "set metadata", 7781 .priv = PRIV_ACTION(SET_META, 7782 sizeof(struct rte_flow_action_set_meta)), 7783 .next = NEXT(action_set_meta), 7784 .call = parse_vc_action_set_meta, 7785 }, 7786 [ACTION_SET_META_DATA] = { 7787 .name = "data", 7788 .help = "metadata value", 7789 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7790 .args = ARGS(ARGS_ENTRY 7791 (struct rte_flow_action_set_meta, data)), 7792 .call = parse_vc_conf, 7793 }, 7794 [ACTION_SET_META_MASK] = { 7795 .name = "mask", 7796 .help = "mask for metadata value", 7797 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7798 .args = ARGS(ARGS_ENTRY 7799 (struct rte_flow_action_set_meta, mask)), 7800 .call = parse_vc_conf, 7801 }, 7802 [ACTION_SET_IPV4_DSCP] = { 7803 .name = "set_ipv4_dscp", 7804 .help = "set DSCP value", 7805 .priv = PRIV_ACTION(SET_IPV4_DSCP, 7806 sizeof(struct rte_flow_action_set_dscp)), 7807 .next = NEXT(action_set_ipv4_dscp), 7808 .call = parse_vc, 7809 }, 7810 [ACTION_SET_IPV4_DSCP_VALUE] = { 7811 .name = "dscp_value", 7812 .help = "new IPv4 DSCP value to set", 7813 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7814 .args = ARGS(ARGS_ENTRY 7815 (struct rte_flow_action_set_dscp, dscp)), 7816 .call = parse_vc_conf, 7817 }, 7818 [ACTION_SET_IPV6_DSCP] = { 7819 .name = "set_ipv6_dscp", 7820 .help = "set DSCP value", 7821 .priv = PRIV_ACTION(SET_IPV6_DSCP, 7822 sizeof(struct rte_flow_action_set_dscp)), 7823 .next = NEXT(action_set_ipv6_dscp), 7824 .call = parse_vc, 7825 }, 7826 [ACTION_SET_IPV6_DSCP_VALUE] = { 7827 .name = "dscp_value", 7828 .help = "new IPv6 DSCP value to set", 7829 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7830 .args = ARGS(ARGS_ENTRY 7831 (struct rte_flow_action_set_dscp, dscp)), 7832 .call = parse_vc_conf, 7833 }, 7834 [ACTION_AGE] = { 7835 .name = "age", 7836 .help = "set a specific metadata header", 7837 .next = NEXT(action_age), 7838 .priv = PRIV_ACTION(AGE, 7839 sizeof(struct rte_flow_action_age)), 7840 .call = parse_vc, 7841 }, 7842 [ACTION_AGE_TIMEOUT] = { 7843 .name = "timeout", 7844 .help = "flow age timeout value", 7845 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 7846 timeout, 24)), 7847 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 7848 .call = parse_vc_conf, 7849 }, 7850 [ACTION_AGE_UPDATE] = { 7851 .name = "age_update", 7852 .help = "update aging parameter", 7853 .next = NEXT(action_age_update), 7854 .priv = PRIV_ACTION(AGE, 7855 sizeof(struct rte_flow_update_age)), 7856 .call = parse_vc, 7857 }, 7858 [ACTION_AGE_UPDATE_TIMEOUT] = { 7859 .name = "timeout", 7860 .help = "age timeout update value", 7861 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7862 timeout, 24)), 7863 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7864 .call = parse_vc_conf_timeout, 7865 }, 7866 [ACTION_AGE_UPDATE_TOUCH] = { 7867 .name = "touch", 7868 .help = "this flow is touched", 7869 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), 7870 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7871 touch, 1)), 7872 .call = parse_vc_conf, 7873 }, 7874 [ACTION_SAMPLE] = { 7875 .name = "sample", 7876 .help = "set a sample action", 7877 .next = NEXT(action_sample), 7878 .priv = PRIV_ACTION(SAMPLE, 7879 sizeof(struct action_sample_data)), 7880 .call = parse_vc_action_sample, 7881 }, 7882 [ACTION_SAMPLE_RATIO] = { 7883 .name = "ratio", 7884 .help = "flow sample ratio value", 7885 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 7886 .args = ARGS(ARGS_ENTRY_ARB 7887 (offsetof(struct action_sample_data, conf) + 7888 offsetof(struct rte_flow_action_sample, ratio), 7889 sizeof(((struct rte_flow_action_sample *)0)-> 7890 ratio))), 7891 }, 7892 [ACTION_SAMPLE_INDEX] = { 7893 .name = "index", 7894 .help = "the index of sample actions list", 7895 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 7896 }, 7897 [ACTION_SAMPLE_INDEX_VALUE] = { 7898 .name = "{index}", 7899 .type = "COMMON_UNSIGNED", 7900 .help = "unsigned integer value", 7901 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7902 .call = parse_vc_action_sample_index, 7903 .comp = comp_set_sample_index, 7904 }, 7905 [ACTION_CONNTRACK] = { 7906 .name = "conntrack", 7907 .help = "create a conntrack object", 7908 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7909 .priv = PRIV_ACTION(CONNTRACK, 7910 sizeof(struct rte_flow_action_conntrack)), 7911 .call = parse_vc, 7912 }, 7913 [ACTION_CONNTRACK_UPDATE] = { 7914 .name = "conntrack_update", 7915 .help = "update a conntrack object", 7916 .next = NEXT(action_update_conntrack), 7917 .priv = PRIV_ACTION(CONNTRACK, 7918 sizeof(struct rte_flow_modify_conntrack)), 7919 .call = parse_vc, 7920 }, 7921 [ACTION_CONNTRACK_UPDATE_DIR] = { 7922 .name = "dir", 7923 .help = "update a conntrack object direction", 7924 .next = NEXT(action_update_conntrack), 7925 .call = parse_vc_action_conntrack_update, 7926 }, 7927 [ACTION_CONNTRACK_UPDATE_CTX] = { 7928 .name = "ctx", 7929 .help = "update a conntrack object context", 7930 .next = NEXT(action_update_conntrack), 7931 .call = parse_vc_action_conntrack_update, 7932 }, 7933 [ACTION_PORT_REPRESENTOR] = { 7934 .name = "port_representor", 7935 .help = "at embedded switch level, send matching traffic to the given ethdev", 7936 .priv = PRIV_ACTION(PORT_REPRESENTOR, 7937 sizeof(struct rte_flow_action_ethdev)), 7938 .next = NEXT(action_port_representor), 7939 .call = parse_vc, 7940 }, 7941 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 7942 .name = "port_id", 7943 .help = "ethdev port ID", 7944 .next = NEXT(action_port_representor, 7945 NEXT_ENTRY(COMMON_UNSIGNED)), 7946 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7947 port_id)), 7948 .call = parse_vc_conf, 7949 }, 7950 [ACTION_REPRESENTED_PORT] = { 7951 .name = "represented_port", 7952 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 7953 .priv = PRIV_ACTION(REPRESENTED_PORT, 7954 sizeof(struct rte_flow_action_ethdev)), 7955 .next = NEXT(action_represented_port), 7956 .call = parse_vc, 7957 }, 7958 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 7959 .name = "ethdev_port_id", 7960 .help = "ethdev port ID", 7961 .next = NEXT(action_represented_port, 7962 NEXT_ENTRY(COMMON_UNSIGNED)), 7963 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7964 port_id)), 7965 .call = parse_vc_conf, 7966 }, 7967 /* Indirect action destroy arguments. */ 7968 [INDIRECT_ACTION_DESTROY_ID] = { 7969 .name = "action_id", 7970 .help = "specify a indirect action id to destroy", 7971 .next = NEXT(next_ia_destroy_attr, 7972 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7973 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 7974 args.ia_destroy.action_id)), 7975 .call = parse_ia_destroy, 7976 }, 7977 /* Indirect action create arguments. */ 7978 [INDIRECT_ACTION_CREATE_ID] = { 7979 .name = "action_id", 7980 .help = "specify a indirect action id to create", 7981 .next = NEXT(next_ia_create_attr, 7982 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7983 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 7984 }, 7985 [ACTION_INDIRECT] = { 7986 .name = "indirect", 7987 .help = "apply indirect action by id", 7988 .priv = PRIV_ACTION(INDIRECT, 0), 7989 .next = NEXT(next_ia), 7990 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7991 .call = parse_vc, 7992 }, 7993 [ACTION_INDIRECT_LIST] = { 7994 .name = "indirect_list", 7995 .help = "apply indirect list action by id", 7996 .priv = PRIV_ACTION(INDIRECT_LIST, 7997 sizeof(struct 7998 rte_flow_action_indirect_list)), 7999 .next = NEXT(next_ial), 8000 .call = parse_vc, 8001 }, 8002 [ACTION_INDIRECT_LIST_HANDLE] = { 8003 .name = "handle", 8004 .help = "indirect list handle", 8005 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), 8006 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 8007 }, 8008 [ACTION_INDIRECT_LIST_CONF] = { 8009 .name = "conf", 8010 .help = "indirect list configuration", 8011 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), 8012 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 8013 }, 8014 [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { 8015 .type = "UNSIGNED", 8016 .help = "unsigned integer value", 8017 .call = parse_indlst_id2ptr, 8018 .comp = comp_none, 8019 }, 8020 [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { 8021 .type = "UNSIGNED", 8022 .help = "unsigned integer value", 8023 .call = parse_indlst_id2ptr, 8024 .comp = comp_none, 8025 }, 8026 [ACTION_SHARED_INDIRECT] = { 8027 .name = "shared_indirect", 8028 .help = "apply indirect action by id and port", 8029 .priv = PRIV_ACTION(INDIRECT, 0), 8030 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), 8031 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), 8032 ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 8033 .call = parse_vc, 8034 }, 8035 [INDIRECT_ACTION_PORT] = { 8036 .name = "{indirect_action_port}", 8037 .type = "INDIRECT_ACTION_PORT", 8038 .help = "indirect action port", 8039 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 8040 .call = parse_ia_port, 8041 .comp = comp_none, 8042 }, 8043 [INDIRECT_ACTION_ID2PTR] = { 8044 .name = "{action_id}", 8045 .type = "INDIRECT_ACTION_ID", 8046 .help = "indirect action id", 8047 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 8048 .call = parse_ia_id2ptr, 8049 .comp = comp_none, 8050 }, 8051 [INDIRECT_ACTION_INGRESS] = { 8052 .name = "ingress", 8053 .help = "affect rule to ingress", 8054 .next = NEXT(next_ia_create_attr), 8055 .call = parse_ia, 8056 }, 8057 [INDIRECT_ACTION_EGRESS] = { 8058 .name = "egress", 8059 .help = "affect rule to egress", 8060 .next = NEXT(next_ia_create_attr), 8061 .call = parse_ia, 8062 }, 8063 [INDIRECT_ACTION_TRANSFER] = { 8064 .name = "transfer", 8065 .help = "affect rule to transfer", 8066 .next = NEXT(next_ia_create_attr), 8067 .call = parse_ia, 8068 }, 8069 [INDIRECT_ACTION_SPEC] = { 8070 .name = "action", 8071 .help = "specify action to create indirect handle", 8072 .next = NEXT(next_action), 8073 }, 8074 [INDIRECT_ACTION_LIST] = { 8075 .name = "list", 8076 .help = "specify actions for indirect handle list", 8077 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 8078 .call = parse_ia, 8079 }, 8080 [INDIRECT_ACTION_FLOW_CONF] = { 8081 .name = "flow_conf", 8082 .help = "specify actions configuration for indirect handle list", 8083 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 8084 .call = parse_ia, 8085 }, 8086 [ACTION_POL_G] = { 8087 .name = "g_actions", 8088 .help = "submit a list of associated actions for green", 8089 .next = NEXT(next_action), 8090 .call = parse_mp, 8091 }, 8092 [ACTION_POL_Y] = { 8093 .name = "y_actions", 8094 .help = "submit a list of associated actions for yellow", 8095 .next = NEXT(next_action), 8096 }, 8097 [ACTION_POL_R] = { 8098 .name = "r_actions", 8099 .help = "submit a list of associated actions for red", 8100 .next = NEXT(next_action), 8101 }, 8102 [ACTION_QUOTA_CREATE] = { 8103 .name = "quota_create", 8104 .help = "create quota action", 8105 .priv = PRIV_ACTION(QUOTA, 8106 sizeof(struct rte_flow_action_quota)), 8107 .next = NEXT(action_quota_create), 8108 .call = parse_vc 8109 }, 8110 [ACTION_QUOTA_CREATE_LIMIT] = { 8111 .name = "limit", 8112 .help = "quota limit", 8113 .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), 8114 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), 8115 .call = parse_vc_conf 8116 }, 8117 [ACTION_QUOTA_CREATE_MODE] = { 8118 .name = "mode", 8119 .help = "quota mode", 8120 .next = NEXT(action_quota_create, 8121 NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), 8122 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), 8123 .call = parse_vc_conf 8124 }, 8125 [ACTION_QUOTA_CREATE_MODE_NAME] = { 8126 .name = "mode_name", 8127 .help = "quota mode name", 8128 .call = parse_quota_mode_name, 8129 .comp = comp_quota_mode_name 8130 }, 8131 [ACTION_QUOTA_QU] = { 8132 .name = "quota_update", 8133 .help = "update quota action", 8134 .priv = PRIV_ACTION(QUOTA, 8135 sizeof(struct rte_flow_update_quota)), 8136 .next = NEXT(action_quota_update), 8137 .call = parse_vc 8138 }, 8139 [ACTION_QUOTA_QU_LIMIT] = { 8140 .name = "limit", 8141 .help = "quota limit", 8142 .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), 8143 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), 8144 .call = parse_vc_conf 8145 }, 8146 [ACTION_QUOTA_QU_UPDATE_OP] = { 8147 .name = "update_op", 8148 .help = "query update op SET|ADD", 8149 .next = NEXT(action_quota_update, 8150 NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), 8151 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), 8152 .call = parse_vc_conf 8153 }, 8154 [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { 8155 .name = "update_op_name", 8156 .help = "quota update op name", 8157 .call = parse_quota_update_name, 8158 .comp = comp_quota_update_name 8159 }, 8160 8161 /* Top-level command. */ 8162 [ADD] = { 8163 .name = "add", 8164 .type = "port meter policy {port_id} {arg}", 8165 .help = "add port meter policy", 8166 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 8167 .call = parse_init, 8168 }, 8169 /* Sub-level commands. */ 8170 [ITEM_POL_PORT] = { 8171 .name = "port", 8172 .help = "add port meter policy", 8173 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 8174 }, 8175 [ITEM_POL_METER] = { 8176 .name = "meter", 8177 .help = "add port meter policy", 8178 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 8179 }, 8180 [ITEM_POL_POLICY] = { 8181 .name = "policy", 8182 .help = "add port meter policy", 8183 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 8184 NEXT_ENTRY(ACTION_POL_Y), 8185 NEXT_ENTRY(ACTION_POL_G), 8186 NEXT_ENTRY(COMMON_POLICY_ID), 8187 NEXT_ENTRY(COMMON_PORT_ID)), 8188 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 8189 ARGS_ENTRY(struct buffer, port)), 8190 .call = parse_mp, 8191 }, 8192 [ITEM_AGGR_AFFINITY] = { 8193 .name = "aggr_affinity", 8194 .help = "match on the aggregated port receiving the packets", 8195 .priv = PRIV_ITEM(AGGR_AFFINITY, 8196 sizeof(struct rte_flow_item_aggr_affinity)), 8197 .next = NEXT(item_aggr_affinity), 8198 .call = parse_vc, 8199 }, 8200 [ITEM_AGGR_AFFINITY_VALUE] = { 8201 .name = "affinity", 8202 .help = "aggregated affinity value", 8203 .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), 8204 item_param), 8205 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, 8206 affinity)), 8207 }, 8208 [ITEM_TX_QUEUE] = { 8209 .name = "tx_queue", 8210 .help = "match on the tx queue of send packet", 8211 .priv = PRIV_ITEM(TX_QUEUE, 8212 sizeof(struct rte_flow_item_tx_queue)), 8213 .next = NEXT(item_tx_queue), 8214 .call = parse_vc, 8215 }, 8216 [ITEM_TX_QUEUE_VALUE] = { 8217 .name = "tx_queue_value", 8218 .help = "tx queue value", 8219 .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), 8220 item_param), 8221 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, 8222 tx_queue)), 8223 }, 8224 }; 8225 8226 /** Remove and return last entry from argument stack. */ 8227 static const struct arg * 8228 pop_args(struct context *ctx) 8229 { 8230 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 8231 } 8232 8233 /** Add entry on top of the argument stack. */ 8234 static int 8235 push_args(struct context *ctx, const struct arg *arg) 8236 { 8237 if (ctx->args_num == CTX_STACK_SIZE) 8238 return -1; 8239 ctx->args[ctx->args_num++] = arg; 8240 return 0; 8241 } 8242 8243 /** Spread value into buffer according to bit-mask. */ 8244 static size_t 8245 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 8246 { 8247 uint32_t i = arg->size; 8248 uint32_t end = 0; 8249 int sub = 1; 8250 int add = 0; 8251 size_t len = 0; 8252 8253 if (!arg->mask) 8254 return 0; 8255 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8256 if (!arg->hton) { 8257 i = 0; 8258 end = arg->size; 8259 sub = 0; 8260 add = 1; 8261 } 8262 #endif 8263 while (i != end) { 8264 unsigned int shift = 0; 8265 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 8266 8267 for (shift = 0; arg->mask[i] >> shift; ++shift) { 8268 if (!(arg->mask[i] & (1 << shift))) 8269 continue; 8270 ++len; 8271 if (!dst) 8272 continue; 8273 *buf &= ~(1 << shift); 8274 *buf |= (val & 1) << shift; 8275 val >>= 1; 8276 } 8277 i += add; 8278 } 8279 return len; 8280 } 8281 8282 /** Compare a string with a partial one of a given length. */ 8283 static int 8284 strcmp_partial(const char *full, const char *partial, size_t partial_len) 8285 { 8286 int r = strncmp(full, partial, partial_len); 8287 8288 if (r) 8289 return r; 8290 if (strlen(full) <= partial_len) 8291 return 0; 8292 return full[partial_len]; 8293 } 8294 8295 /** 8296 * Parse a prefix length and generate a bit-mask. 8297 * 8298 * Last argument (ctx->args) is retrieved to determine mask size, storage 8299 * location and whether the result must use network byte ordering. 8300 */ 8301 static int 8302 parse_prefix(struct context *ctx, const struct token *token, 8303 const char *str, unsigned int len, 8304 void *buf, unsigned int size) 8305 { 8306 const struct arg *arg = pop_args(ctx); 8307 static const uint8_t conv[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 8308 0xf8, 0xfc, 0xfe, 0xff }; 8309 char *end; 8310 uintmax_t u; 8311 unsigned int bytes; 8312 unsigned int extra; 8313 8314 (void)token; 8315 /* Argument is expected. */ 8316 if (!arg) 8317 return -1; 8318 errno = 0; 8319 u = strtoumax(str, &end, 0); 8320 if (errno || (size_t)(end - str) != len) 8321 goto error; 8322 if (arg->mask) { 8323 uintmax_t v = 0; 8324 8325 extra = arg_entry_bf_fill(NULL, 0, arg); 8326 if (u > extra) 8327 goto error; 8328 if (!ctx->object) 8329 return len; 8330 extra -= u; 8331 while (u--) 8332 (v <<= 1, v |= 1); 8333 v <<= extra; 8334 if (!arg_entry_bf_fill(ctx->object, v, arg) || 8335 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 8336 goto error; 8337 return len; 8338 } 8339 bytes = u / 8; 8340 extra = u % 8; 8341 size = arg->size; 8342 if (bytes > size || bytes + !!extra > size) 8343 goto error; 8344 if (!ctx->object) 8345 return len; 8346 buf = (uint8_t *)ctx->object + arg->offset; 8347 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8348 if (!arg->hton) { 8349 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 8350 memset(buf, 0x00, size - bytes); 8351 if (extra) 8352 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 8353 } else 8354 #endif 8355 { 8356 memset(buf, 0xff, bytes); 8357 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 8358 if (extra) 8359 ((uint8_t *)buf)[bytes] = conv[extra]; 8360 } 8361 if (ctx->objmask) 8362 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 8363 return len; 8364 error: 8365 push_args(ctx, arg); 8366 return -1; 8367 } 8368 8369 /** Default parsing function for token name matching. */ 8370 static int 8371 parse_default(struct context *ctx, const struct token *token, 8372 const char *str, unsigned int len, 8373 void *buf, unsigned int size) 8374 { 8375 (void)ctx; 8376 (void)buf; 8377 (void)size; 8378 if (strcmp_partial(token->name, str, len)) 8379 return -1; 8380 return len; 8381 } 8382 8383 /** Parse flow command, initialize output buffer for subsequent tokens. */ 8384 static int 8385 parse_init(struct context *ctx, const struct token *token, 8386 const char *str, unsigned int len, 8387 void *buf, unsigned int size) 8388 { 8389 struct buffer *out = buf; 8390 8391 /* Token name must match. */ 8392 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8393 return -1; 8394 /* Nothing else to do if there is no buffer. */ 8395 if (!out) 8396 return len; 8397 /* Make sure buffer is large enough. */ 8398 if (size < sizeof(*out)) 8399 return -1; 8400 /* Initialize buffer. */ 8401 memset(out, 0x00, sizeof(*out)); 8402 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 8403 ctx->objdata = 0; 8404 ctx->object = out; 8405 ctx->objmask = NULL; 8406 return len; 8407 } 8408 8409 /** Parse tokens for indirect action commands. */ 8410 static int 8411 parse_ia(struct context *ctx, const struct token *token, 8412 const char *str, unsigned int len, 8413 void *buf, unsigned int size) 8414 { 8415 struct buffer *out = buf; 8416 8417 /* Token name must match. */ 8418 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8419 return -1; 8420 /* Nothing else to do if there is no buffer. */ 8421 if (!out) 8422 return len; 8423 if (!out->command) { 8424 if (ctx->curr != INDIRECT_ACTION) 8425 return -1; 8426 if (sizeof(*out) > size) 8427 return -1; 8428 out->command = ctx->curr; 8429 ctx->objdata = 0; 8430 ctx->object = out; 8431 ctx->objmask = NULL; 8432 out->args.vc.data = (uint8_t *)out + size; 8433 return len; 8434 } 8435 switch (ctx->curr) { 8436 case INDIRECT_ACTION_CREATE: 8437 case INDIRECT_ACTION_UPDATE: 8438 case INDIRECT_ACTION_QUERY_UPDATE: 8439 out->args.vc.actions = 8440 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8441 sizeof(double)); 8442 out->args.vc.attr.group = UINT32_MAX; 8443 /* fallthrough */ 8444 case INDIRECT_ACTION_QUERY: 8445 out->command = ctx->curr; 8446 ctx->objdata = 0; 8447 ctx->object = out; 8448 ctx->objmask = NULL; 8449 return len; 8450 case INDIRECT_ACTION_EGRESS: 8451 out->args.vc.attr.egress = 1; 8452 return len; 8453 case INDIRECT_ACTION_INGRESS: 8454 out->args.vc.attr.ingress = 1; 8455 return len; 8456 case INDIRECT_ACTION_TRANSFER: 8457 out->args.vc.attr.transfer = 1; 8458 return len; 8459 case INDIRECT_ACTION_QU_MODE: 8460 return len; 8461 case INDIRECT_ACTION_LIST: 8462 out->command = INDIRECT_ACTION_LIST_CREATE; 8463 return len; 8464 case INDIRECT_ACTION_FLOW_CONF: 8465 out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; 8466 return len; 8467 default: 8468 return -1; 8469 } 8470 } 8471 8472 8473 /** Parse tokens for indirect action destroy command. */ 8474 static int 8475 parse_ia_destroy(struct context *ctx, const struct token *token, 8476 const char *str, unsigned int len, 8477 void *buf, unsigned int size) 8478 { 8479 struct buffer *out = buf; 8480 uint32_t *action_id; 8481 8482 /* Token name must match. */ 8483 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8484 return -1; 8485 /* Nothing else to do if there is no buffer. */ 8486 if (!out) 8487 return len; 8488 if (!out->command || out->command == INDIRECT_ACTION) { 8489 if (ctx->curr != INDIRECT_ACTION_DESTROY) 8490 return -1; 8491 if (sizeof(*out) > size) 8492 return -1; 8493 out->command = ctx->curr; 8494 ctx->objdata = 0; 8495 ctx->object = out; 8496 ctx->objmask = NULL; 8497 out->args.ia_destroy.action_id = 8498 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8499 sizeof(double)); 8500 return len; 8501 } 8502 action_id = out->args.ia_destroy.action_id 8503 + out->args.ia_destroy.action_id_n++; 8504 if ((uint8_t *)action_id > (uint8_t *)out + size) 8505 return -1; 8506 ctx->objdata = 0; 8507 ctx->object = action_id; 8508 ctx->objmask = NULL; 8509 return len; 8510 } 8511 8512 /** Parse tokens for indirect action commands. */ 8513 static int 8514 parse_qia(struct context *ctx, const struct token *token, 8515 const char *str, unsigned int len, 8516 void *buf, unsigned int size) 8517 { 8518 struct buffer *out = buf; 8519 8520 /* Token name must match. */ 8521 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8522 return -1; 8523 /* Nothing else to do if there is no buffer. */ 8524 if (!out) 8525 return len; 8526 if (!out->command) { 8527 if (ctx->curr != QUEUE) 8528 return -1; 8529 if (sizeof(*out) > size) 8530 return -1; 8531 out->args.vc.data = (uint8_t *)out + size; 8532 return len; 8533 } 8534 switch (ctx->curr) { 8535 case QUEUE_INDIRECT_ACTION: 8536 return len; 8537 case QUEUE_INDIRECT_ACTION_CREATE: 8538 case QUEUE_INDIRECT_ACTION_UPDATE: 8539 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 8540 out->args.vc.actions = 8541 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8542 sizeof(double)); 8543 out->args.vc.attr.group = UINT32_MAX; 8544 /* fallthrough */ 8545 case QUEUE_INDIRECT_ACTION_QUERY: 8546 out->command = ctx->curr; 8547 ctx->objdata = 0; 8548 ctx->object = out; 8549 ctx->objmask = NULL; 8550 return len; 8551 case QUEUE_INDIRECT_ACTION_EGRESS: 8552 out->args.vc.attr.egress = 1; 8553 return len; 8554 case QUEUE_INDIRECT_ACTION_INGRESS: 8555 out->args.vc.attr.ingress = 1; 8556 return len; 8557 case QUEUE_INDIRECT_ACTION_TRANSFER: 8558 out->args.vc.attr.transfer = 1; 8559 return len; 8560 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 8561 return len; 8562 case QUEUE_INDIRECT_ACTION_QU_MODE: 8563 return len; 8564 case QUEUE_INDIRECT_ACTION_LIST: 8565 out->command = QUEUE_INDIRECT_ACTION_LIST_CREATE; 8566 return len; 8567 default: 8568 return -1; 8569 } 8570 } 8571 8572 /** Parse tokens for indirect action destroy command. */ 8573 static int 8574 parse_qia_destroy(struct context *ctx, const struct token *token, 8575 const char *str, unsigned int len, 8576 void *buf, unsigned int size) 8577 { 8578 struct buffer *out = buf; 8579 uint32_t *action_id; 8580 8581 /* Token name must match. */ 8582 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8583 return -1; 8584 /* Nothing else to do if there is no buffer. */ 8585 if (!out) 8586 return len; 8587 if (!out->command || out->command == QUEUE) { 8588 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 8589 return -1; 8590 if (sizeof(*out) > size) 8591 return -1; 8592 out->command = ctx->curr; 8593 ctx->objdata = 0; 8594 ctx->object = out; 8595 ctx->objmask = NULL; 8596 out->args.ia_destroy.action_id = 8597 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8598 sizeof(double)); 8599 return len; 8600 } 8601 switch (ctx->curr) { 8602 case QUEUE_INDIRECT_ACTION: 8603 out->command = ctx->curr; 8604 ctx->objdata = 0; 8605 ctx->object = out; 8606 ctx->objmask = NULL; 8607 return len; 8608 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 8609 action_id = out->args.ia_destroy.action_id 8610 + out->args.ia_destroy.action_id_n++; 8611 if ((uint8_t *)action_id > (uint8_t *)out + size) 8612 return -1; 8613 ctx->objdata = 0; 8614 ctx->object = action_id; 8615 ctx->objmask = NULL; 8616 return len; 8617 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 8618 return len; 8619 default: 8620 return -1; 8621 } 8622 } 8623 8624 /** Parse tokens for meter policy action commands. */ 8625 static int 8626 parse_mp(struct context *ctx, const struct token *token, 8627 const char *str, unsigned int len, 8628 void *buf, unsigned int size) 8629 { 8630 struct buffer *out = buf; 8631 8632 /* Token name must match. */ 8633 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8634 return -1; 8635 /* Nothing else to do if there is no buffer. */ 8636 if (!out) 8637 return len; 8638 if (!out->command) { 8639 if (ctx->curr != ITEM_POL_POLICY) 8640 return -1; 8641 if (sizeof(*out) > size) 8642 return -1; 8643 out->command = ctx->curr; 8644 ctx->objdata = 0; 8645 ctx->object = out; 8646 ctx->objmask = NULL; 8647 out->args.vc.data = (uint8_t *)out + size; 8648 return len; 8649 } 8650 switch (ctx->curr) { 8651 case ACTION_POL_G: 8652 out->args.vc.actions = 8653 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8654 sizeof(double)); 8655 out->command = ctx->curr; 8656 ctx->objdata = 0; 8657 ctx->object = out; 8658 ctx->objmask = NULL; 8659 return len; 8660 default: 8661 return -1; 8662 } 8663 } 8664 8665 /** Parse tokens for validate/create commands. */ 8666 static int 8667 parse_vc(struct context *ctx, const struct token *token, 8668 const char *str, unsigned int len, 8669 void *buf, unsigned int size) 8670 { 8671 struct buffer *out = buf; 8672 uint8_t *data; 8673 uint32_t data_size; 8674 8675 /* Token name must match. */ 8676 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8677 return -1; 8678 /* Nothing else to do if there is no buffer. */ 8679 if (!out) 8680 return len; 8681 if (!out->command) { 8682 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 8683 ctx->curr != PATTERN_TEMPLATE_CREATE && 8684 ctx->curr != ACTIONS_TEMPLATE_CREATE && 8685 ctx->curr != UPDATE) 8686 return -1; 8687 if (ctx->curr == UPDATE) 8688 out->args.vc.pattern = 8689 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8690 sizeof(double)); 8691 if (sizeof(*out) > size) 8692 return -1; 8693 out->command = ctx->curr; 8694 ctx->objdata = 0; 8695 ctx->object = out; 8696 ctx->objmask = NULL; 8697 out->args.vc.data = (uint8_t *)out + size; 8698 return len; 8699 } 8700 ctx->objdata = 0; 8701 switch (ctx->curr) { 8702 default: 8703 ctx->object = &out->args.vc.attr; 8704 break; 8705 case VC_TUNNEL_SET: 8706 case VC_TUNNEL_MATCH: 8707 ctx->object = &out->args.vc.tunnel_ops; 8708 break; 8709 case VC_USER_ID: 8710 ctx->object = out; 8711 break; 8712 } 8713 ctx->objmask = NULL; 8714 switch (ctx->curr) { 8715 case VC_GROUP: 8716 case VC_PRIORITY: 8717 case VC_USER_ID: 8718 return len; 8719 case VC_TUNNEL_SET: 8720 out->args.vc.tunnel_ops.enabled = 1; 8721 out->args.vc.tunnel_ops.actions = 1; 8722 return len; 8723 case VC_TUNNEL_MATCH: 8724 out->args.vc.tunnel_ops.enabled = 1; 8725 out->args.vc.tunnel_ops.items = 1; 8726 return len; 8727 case VC_INGRESS: 8728 out->args.vc.attr.ingress = 1; 8729 return len; 8730 case VC_EGRESS: 8731 out->args.vc.attr.egress = 1; 8732 return len; 8733 case VC_TRANSFER: 8734 out->args.vc.attr.transfer = 1; 8735 return len; 8736 case ITEM_PATTERN: 8737 out->args.vc.pattern = 8738 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8739 sizeof(double)); 8740 ctx->object = out->args.vc.pattern; 8741 ctx->objmask = NULL; 8742 return len; 8743 case ITEM_END: 8744 if ((out->command == VALIDATE || out->command == CREATE) && 8745 ctx->last) 8746 return -1; 8747 if (out->command == PATTERN_TEMPLATE_CREATE && 8748 !ctx->last) 8749 return -1; 8750 break; 8751 case ACTIONS: 8752 out->args.vc.actions = out->args.vc.pattern ? 8753 (void *)RTE_ALIGN_CEIL((uintptr_t) 8754 (out->args.vc.pattern + 8755 out->args.vc.pattern_n), 8756 sizeof(double)) : 8757 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8758 sizeof(double)); 8759 ctx->object = out->args.vc.actions; 8760 ctx->objmask = NULL; 8761 return len; 8762 case VC_IS_USER_ID: 8763 out->args.vc.user_id = true; 8764 return len; 8765 default: 8766 if (!token->priv) 8767 return -1; 8768 break; 8769 } 8770 if (!out->args.vc.actions) { 8771 const struct parse_item_priv *priv = token->priv; 8772 struct rte_flow_item *item = 8773 out->args.vc.pattern + out->args.vc.pattern_n; 8774 8775 data_size = priv->size * 3; /* spec, last, mask */ 8776 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8777 (out->args.vc.data - data_size), 8778 sizeof(double)); 8779 if ((uint8_t *)item + sizeof(*item) > data) 8780 return -1; 8781 *item = (struct rte_flow_item){ 8782 .type = priv->type, 8783 }; 8784 ++out->args.vc.pattern_n; 8785 ctx->object = item; 8786 ctx->objmask = NULL; 8787 } else { 8788 const struct parse_action_priv *priv = token->priv; 8789 struct rte_flow_action *action = 8790 out->args.vc.actions + out->args.vc.actions_n; 8791 8792 data_size = priv->size; /* configuration */ 8793 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8794 (out->args.vc.data - data_size), 8795 sizeof(double)); 8796 if ((uint8_t *)action + sizeof(*action) > data) 8797 return -1; 8798 *action = (struct rte_flow_action){ 8799 .type = priv->type, 8800 .conf = data_size ? data : NULL, 8801 }; 8802 ++out->args.vc.actions_n; 8803 ctx->object = action; 8804 ctx->objmask = NULL; 8805 } 8806 memset(data, 0, data_size); 8807 out->args.vc.data = data; 8808 ctx->objdata = data_size; 8809 return len; 8810 } 8811 8812 /** Parse pattern item parameter type. */ 8813 static int 8814 parse_vc_spec(struct context *ctx, const struct token *token, 8815 const char *str, unsigned int len, 8816 void *buf, unsigned int size) 8817 { 8818 struct buffer *out = buf; 8819 struct rte_flow_item *item; 8820 uint32_t data_size; 8821 int index; 8822 int objmask = 0; 8823 8824 (void)size; 8825 /* Token name must match. */ 8826 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8827 return -1; 8828 /* Parse parameter types. */ 8829 switch (ctx->curr) { 8830 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 8831 8832 case ITEM_PARAM_IS: 8833 index = 0; 8834 objmask = 1; 8835 break; 8836 case ITEM_PARAM_SPEC: 8837 index = 0; 8838 break; 8839 case ITEM_PARAM_LAST: 8840 index = 1; 8841 break; 8842 case ITEM_PARAM_PREFIX: 8843 /* Modify next token to expect a prefix. */ 8844 if (ctx->next_num < 2) 8845 return -1; 8846 ctx->next[ctx->next_num - 2] = prefix; 8847 /* Fall through. */ 8848 case ITEM_PARAM_MASK: 8849 index = 2; 8850 break; 8851 default: 8852 return -1; 8853 } 8854 /* Nothing else to do if there is no buffer. */ 8855 if (!out) 8856 return len; 8857 if (!out->args.vc.pattern_n) 8858 return -1; 8859 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8860 data_size = ctx->objdata / 3; /* spec, last, mask */ 8861 /* Point to selected object. */ 8862 ctx->object = out->args.vc.data + (data_size * index); 8863 if (objmask) { 8864 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 8865 item->mask = ctx->objmask; 8866 } else 8867 ctx->objmask = NULL; 8868 /* Update relevant item pointer. */ 8869 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 8870 ctx->object; 8871 return len; 8872 } 8873 8874 /** Parse action configuration field. */ 8875 static int 8876 parse_vc_conf(struct context *ctx, const struct token *token, 8877 const char *str, unsigned int len, 8878 void *buf, unsigned int size) 8879 { 8880 struct buffer *out = buf; 8881 8882 (void)size; 8883 /* Token name must match. */ 8884 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8885 return -1; 8886 /* Nothing else to do if there is no buffer. */ 8887 if (!out) 8888 return len; 8889 /* Point to selected object. */ 8890 ctx->object = out->args.vc.data; 8891 ctx->objmask = NULL; 8892 return len; 8893 } 8894 8895 /** Parse action configuration field. */ 8896 static int 8897 parse_vc_conf_timeout(struct context *ctx, const struct token *token, 8898 const char *str, unsigned int len, 8899 void *buf, unsigned int size) 8900 { 8901 struct buffer *out = buf; 8902 struct rte_flow_update_age *update; 8903 8904 (void)size; 8905 if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) 8906 return -1; 8907 /* Token name must match. */ 8908 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8909 return -1; 8910 /* Nothing else to do if there is no buffer. */ 8911 if (!out) 8912 return len; 8913 /* Point to selected object. */ 8914 ctx->object = out->args.vc.data; 8915 ctx->objmask = NULL; 8916 /* Update the timeout is valid. */ 8917 update = (struct rte_flow_update_age *)out->args.vc.data; 8918 update->timeout_valid = 1; 8919 return len; 8920 } 8921 8922 /** Parse eCPRI common header type field. */ 8923 static int 8924 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 8925 const char *str, unsigned int len, 8926 void *buf, unsigned int size) 8927 { 8928 struct rte_flow_item_ecpri *ecpri; 8929 struct rte_flow_item_ecpri *ecpri_mask; 8930 struct rte_flow_item *item; 8931 uint32_t data_size; 8932 uint8_t msg_type; 8933 struct buffer *out = buf; 8934 const struct arg *arg; 8935 8936 (void)size; 8937 /* Token name must match. */ 8938 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8939 return -1; 8940 switch (ctx->curr) { 8941 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 8942 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 8943 break; 8944 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 8945 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 8946 break; 8947 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 8948 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 8949 break; 8950 default: 8951 return -1; 8952 } 8953 if (!ctx->object) 8954 return len; 8955 arg = pop_args(ctx); 8956 if (!arg) 8957 return -1; 8958 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 8959 ecpri->hdr.common.type = msg_type; 8960 data_size = ctx->objdata / 3; /* spec, last, mask */ 8961 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 8962 (data_size * 2)); 8963 ecpri_mask->hdr.common.type = 0xFF; 8964 if (arg->hton) { 8965 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 8966 ecpri_mask->hdr.common.u32 = 8967 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 8968 } 8969 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8970 item->spec = ecpri; 8971 item->mask = ecpri_mask; 8972 return len; 8973 } 8974 8975 /** Parse L2TPv2 common header type field. */ 8976 static int 8977 parse_vc_item_l2tpv2_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_item_l2tpv2 *l2tpv2; 8982 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 8983 struct rte_flow_item *item; 8984 uint32_t data_size; 8985 uint16_t msg_type = 0; 8986 struct buffer *out = buf; 8987 const struct arg *arg; 8988 8989 (void)size; 8990 /* Token name must match. */ 8991 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8992 return -1; 8993 switch (ctx->curr) { 8994 case ITEM_L2TPV2_TYPE_DATA: 8995 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 8996 break; 8997 case ITEM_L2TPV2_TYPE_DATA_L: 8998 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 8999 break; 9000 case ITEM_L2TPV2_TYPE_DATA_S: 9001 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 9002 break; 9003 case ITEM_L2TPV2_TYPE_DATA_O: 9004 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 9005 break; 9006 case ITEM_L2TPV2_TYPE_DATA_L_S: 9007 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 9008 break; 9009 case ITEM_L2TPV2_TYPE_CTRL: 9010 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 9011 break; 9012 default: 9013 return -1; 9014 } 9015 if (!ctx->object) 9016 return len; 9017 arg = pop_args(ctx); 9018 if (!arg) 9019 return -1; 9020 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 9021 l2tpv2->hdr.common.flags_version |= msg_type; 9022 data_size = ctx->objdata / 3; /* spec, last, mask */ 9023 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 9024 (data_size * 2)); 9025 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 9026 if (arg->hton) { 9027 l2tpv2->hdr.common.flags_version = 9028 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 9029 l2tpv2_mask->hdr.common.flags_version = 9030 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 9031 } 9032 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 9033 item->spec = l2tpv2; 9034 item->mask = l2tpv2_mask; 9035 return len; 9036 } 9037 9038 /** Parse operation for compare match item. */ 9039 static int 9040 parse_vc_compare_op(struct context *ctx, const struct token *token, 9041 const char *str, unsigned int len, void *buf, 9042 unsigned int size) 9043 { 9044 struct rte_flow_item_compare *compare_item; 9045 unsigned int i; 9046 9047 (void)token; 9048 (void)buf; 9049 (void)size; 9050 if (ctx->curr != ITEM_COMPARE_OP_VALUE) 9051 return -1; 9052 for (i = 0; compare_ops[i]; ++i) 9053 if (!strcmp_partial(compare_ops[i], str, len)) 9054 break; 9055 if (!compare_ops[i]) 9056 return -1; 9057 if (!ctx->object) 9058 return len; 9059 compare_item = ctx->object; 9060 compare_item->operation = (enum rte_flow_item_compare_op)i; 9061 return len; 9062 } 9063 9064 /** Parse id for compare match item. */ 9065 static int 9066 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 9067 const char *str, unsigned int len, void *buf, 9068 unsigned int size) 9069 { 9070 struct rte_flow_item_compare *compare_item; 9071 unsigned int i; 9072 9073 (void)token; 9074 (void)buf; 9075 (void)size; 9076 if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE && 9077 ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE) 9078 return -1; 9079 for (i = 0; flow_field_ids[i]; ++i) 9080 if (!strcmp_partial(flow_field_ids[i], str, len)) 9081 break; 9082 if (!flow_field_ids[i]) 9083 return -1; 9084 if (!ctx->object) 9085 return len; 9086 compare_item = ctx->object; 9087 if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE) 9088 compare_item->a.field = (enum rte_flow_field_id)i; 9089 else 9090 compare_item->b.field = (enum rte_flow_field_id)i; 9091 return len; 9092 } 9093 9094 /** Parse level for compare match item. */ 9095 static int 9096 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 9097 const char *str, unsigned int len, void *buf, 9098 unsigned int size) 9099 { 9100 struct rte_flow_item_compare *compare_item; 9101 struct flex_item *fp = NULL; 9102 uint32_t val; 9103 struct buffer *out = buf; 9104 char *end; 9105 9106 (void)token; 9107 (void)size; 9108 if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 9109 ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE) 9110 return -1; 9111 if (!ctx->object) 9112 return len; 9113 compare_item = ctx->object; 9114 errno = 0; 9115 val = strtoumax(str, &end, 0); 9116 if (errno || (size_t)(end - str) != len) 9117 return -1; 9118 /* No need to validate action template mask value */ 9119 if (out->args.vc.masks) { 9120 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) 9121 compare_item->a.level = val; 9122 else 9123 compare_item->b.level = val; 9124 return len; 9125 } 9126 if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 9127 compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) || 9128 (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE && 9129 compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 9130 if (val >= FLEX_MAX_PARSERS_NUM) { 9131 printf("Bad flex item handle\n"); 9132 return -1; 9133 } 9134 fp = flex_items[ctx->port][val]; 9135 if (!fp) { 9136 printf("Bad flex item handle\n"); 9137 return -1; 9138 } 9139 } 9140 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) { 9141 if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM) 9142 compare_item->a.level = val; 9143 else 9144 compare_item->a.flex_handle = fp->flex_handle; 9145 } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) { 9146 if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM) 9147 compare_item->b.level = val; 9148 else 9149 compare_item->b.flex_handle = fp->flex_handle; 9150 } 9151 return len; 9152 } 9153 9154 /** Parse meter color action type. */ 9155 static int 9156 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 9157 const char *str, unsigned int len, 9158 void *buf, unsigned int size) 9159 { 9160 struct rte_flow_action *action_data; 9161 struct rte_flow_action_meter_color *conf; 9162 enum rte_color color; 9163 9164 (void)buf; 9165 (void)size; 9166 /* Token name must match. */ 9167 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9168 return -1; 9169 switch (ctx->curr) { 9170 case ACTION_METER_COLOR_GREEN: 9171 color = RTE_COLOR_GREEN; 9172 break; 9173 case ACTION_METER_COLOR_YELLOW: 9174 color = RTE_COLOR_YELLOW; 9175 break; 9176 case ACTION_METER_COLOR_RED: 9177 color = RTE_COLOR_RED; 9178 break; 9179 default: 9180 return -1; 9181 } 9182 9183 if (!ctx->object) 9184 return len; 9185 action_data = ctx->object; 9186 conf = (struct rte_flow_action_meter_color *) 9187 (uintptr_t)(action_data->conf); 9188 conf->color = color; 9189 return len; 9190 } 9191 9192 /** Parse RSS action. */ 9193 static int 9194 parse_vc_action_rss(struct context *ctx, const struct token *token, 9195 const char *str, unsigned int len, 9196 void *buf, unsigned int size) 9197 { 9198 struct buffer *out = buf; 9199 struct rte_flow_action *action; 9200 struct action_rss_data *action_rss_data; 9201 unsigned int i; 9202 int ret; 9203 9204 ret = parse_vc(ctx, token, str, len, buf, size); 9205 if (ret < 0) 9206 return ret; 9207 /* Nothing else to do if there is no buffer. */ 9208 if (!out) 9209 return ret; 9210 if (!out->args.vc.actions_n) 9211 return -1; 9212 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9213 /* Point to selected object. */ 9214 ctx->object = out->args.vc.data; 9215 ctx->objmask = NULL; 9216 /* Set up default configuration. */ 9217 action_rss_data = ctx->object; 9218 *action_rss_data = (struct action_rss_data){ 9219 .conf = (struct rte_flow_action_rss){ 9220 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 9221 .level = 0, 9222 .types = rss_hf, 9223 .key_len = 0, 9224 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 9225 .key = NULL, 9226 .queue = action_rss_data->queue, 9227 }, 9228 .queue = { 0 }, 9229 }; 9230 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 9231 action_rss_data->queue[i] = i; 9232 action->conf = &action_rss_data->conf; 9233 return ret; 9234 } 9235 9236 /** 9237 * Parse func field for RSS action. 9238 * 9239 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 9240 * ACTION_RSS_FUNC_* index that called this function. 9241 */ 9242 static int 9243 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 9244 const char *str, unsigned int len, 9245 void *buf, unsigned int size) 9246 { 9247 struct action_rss_data *action_rss_data; 9248 enum rte_eth_hash_function func; 9249 9250 (void)buf; 9251 (void)size; 9252 /* Token name must match. */ 9253 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9254 return -1; 9255 switch (ctx->curr) { 9256 case ACTION_RSS_FUNC_DEFAULT: 9257 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 9258 break; 9259 case ACTION_RSS_FUNC_TOEPLITZ: 9260 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 9261 break; 9262 case ACTION_RSS_FUNC_SIMPLE_XOR: 9263 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 9264 break; 9265 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 9266 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 9267 break; 9268 default: 9269 return -1; 9270 } 9271 if (!ctx->object) 9272 return len; 9273 action_rss_data = ctx->object; 9274 action_rss_data->conf.func = func; 9275 return len; 9276 } 9277 9278 /** 9279 * Parse type field for RSS action. 9280 * 9281 * Valid tokens are type field names and the "end" token. 9282 */ 9283 static int 9284 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 9285 const char *str, unsigned int len, 9286 void *buf, unsigned int size) 9287 { 9288 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 9289 struct action_rss_data *action_rss_data; 9290 unsigned int i; 9291 9292 (void)token; 9293 (void)buf; 9294 (void)size; 9295 if (ctx->curr != ACTION_RSS_TYPE) 9296 return -1; 9297 if (!(ctx->objdata >> 16) && ctx->object) { 9298 action_rss_data = ctx->object; 9299 action_rss_data->conf.types = 0; 9300 } 9301 if (!strcmp_partial("end", str, len)) { 9302 ctx->objdata &= 0xffff; 9303 return len; 9304 } 9305 for (i = 0; rss_type_table[i].str; ++i) 9306 if (!strcmp_partial(rss_type_table[i].str, str, len)) 9307 break; 9308 if (!rss_type_table[i].str) 9309 return -1; 9310 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 9311 /* Repeat token. */ 9312 if (ctx->next_num == RTE_DIM(ctx->next)) 9313 return -1; 9314 ctx->next[ctx->next_num++] = next; 9315 if (!ctx->object) 9316 return len; 9317 action_rss_data = ctx->object; 9318 action_rss_data->conf.types |= rss_type_table[i].rss_type; 9319 return len; 9320 } 9321 9322 /** 9323 * Parse queue field for RSS action. 9324 * 9325 * Valid tokens are queue indices and the "end" token. 9326 */ 9327 static int 9328 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 9329 const char *str, unsigned int len, 9330 void *buf, unsigned int size) 9331 { 9332 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 9333 struct action_rss_data *action_rss_data; 9334 const struct arg *arg; 9335 int ret; 9336 int i; 9337 9338 (void)token; 9339 (void)buf; 9340 (void)size; 9341 if (ctx->curr != ACTION_RSS_QUEUE) 9342 return -1; 9343 i = ctx->objdata >> 16; 9344 if (!strcmp_partial("end", str, len)) { 9345 ctx->objdata &= 0xffff; 9346 goto end; 9347 } 9348 if (i >= ACTION_RSS_QUEUE_NUM) 9349 return -1; 9350 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 9351 i * sizeof(action_rss_data->queue[i]), 9352 sizeof(action_rss_data->queue[i])); 9353 if (push_args(ctx, arg)) 9354 return -1; 9355 ret = parse_int(ctx, token, str, len, NULL, 0); 9356 if (ret < 0) { 9357 pop_args(ctx); 9358 return -1; 9359 } 9360 ++i; 9361 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 9362 /* Repeat token. */ 9363 if (ctx->next_num == RTE_DIM(ctx->next)) 9364 return -1; 9365 ctx->next[ctx->next_num++] = next; 9366 end: 9367 if (!ctx->object) 9368 return len; 9369 action_rss_data = ctx->object; 9370 action_rss_data->conf.queue_num = i; 9371 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 9372 return len; 9373 } 9374 9375 /** Setup VXLAN encap configuration. */ 9376 static int 9377 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 9378 { 9379 /* Set up default configuration. */ 9380 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 9381 .conf = (struct rte_flow_action_vxlan_encap){ 9382 .definition = action_vxlan_encap_data->items, 9383 }, 9384 .items = { 9385 { 9386 .type = RTE_FLOW_ITEM_TYPE_ETH, 9387 .spec = &action_vxlan_encap_data->item_eth, 9388 .mask = &rte_flow_item_eth_mask, 9389 }, 9390 { 9391 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9392 .spec = &action_vxlan_encap_data->item_vlan, 9393 .mask = &rte_flow_item_vlan_mask, 9394 }, 9395 { 9396 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9397 .spec = &action_vxlan_encap_data->item_ipv4, 9398 .mask = &rte_flow_item_ipv4_mask, 9399 }, 9400 { 9401 .type = RTE_FLOW_ITEM_TYPE_UDP, 9402 .spec = &action_vxlan_encap_data->item_udp, 9403 .mask = &rte_flow_item_udp_mask, 9404 }, 9405 { 9406 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 9407 .spec = &action_vxlan_encap_data->item_vxlan, 9408 .mask = &rte_flow_item_vxlan_mask, 9409 }, 9410 { 9411 .type = RTE_FLOW_ITEM_TYPE_END, 9412 }, 9413 }, 9414 .item_eth.hdr.ether_type = 0, 9415 .item_vlan = { 9416 .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, 9417 .hdr.eth_proto = 0, 9418 }, 9419 .item_ipv4.hdr = { 9420 .src_addr = vxlan_encap_conf.ipv4_src, 9421 .dst_addr = vxlan_encap_conf.ipv4_dst, 9422 }, 9423 .item_udp.hdr = { 9424 .src_port = vxlan_encap_conf.udp_src, 9425 .dst_port = vxlan_encap_conf.udp_dst, 9426 }, 9427 .item_vxlan.hdr.flags = 0, 9428 }; 9429 memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9430 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9431 memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, 9432 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9433 if (!vxlan_encap_conf.select_ipv4) { 9434 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 9435 &vxlan_encap_conf.ipv6_src, 9436 sizeof(vxlan_encap_conf.ipv6_src)); 9437 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 9438 &vxlan_encap_conf.ipv6_dst, 9439 sizeof(vxlan_encap_conf.ipv6_dst)); 9440 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 9441 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9442 .spec = &action_vxlan_encap_data->item_ipv6, 9443 .mask = &rte_flow_item_ipv6_mask, 9444 }; 9445 } 9446 if (!vxlan_encap_conf.select_vlan) 9447 action_vxlan_encap_data->items[1].type = 9448 RTE_FLOW_ITEM_TYPE_VOID; 9449 if (vxlan_encap_conf.select_tos_ttl) { 9450 if (vxlan_encap_conf.select_ipv4) { 9451 static struct rte_flow_item_ipv4 ipv4_mask_tos; 9452 9453 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 9454 sizeof(ipv4_mask_tos)); 9455 ipv4_mask_tos.hdr.type_of_service = 0xff; 9456 ipv4_mask_tos.hdr.time_to_live = 0xff; 9457 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 9458 vxlan_encap_conf.ip_tos; 9459 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 9460 vxlan_encap_conf.ip_ttl; 9461 action_vxlan_encap_data->items[2].mask = 9462 &ipv4_mask_tos; 9463 } else { 9464 static struct rte_flow_item_ipv6 ipv6_mask_tos; 9465 9466 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 9467 sizeof(ipv6_mask_tos)); 9468 ipv6_mask_tos.hdr.vtc_flow |= 9469 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 9470 ipv6_mask_tos.hdr.hop_limits = 0xff; 9471 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 9472 rte_cpu_to_be_32 9473 ((uint32_t)vxlan_encap_conf.ip_tos << 9474 RTE_IPV6_HDR_TC_SHIFT); 9475 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 9476 vxlan_encap_conf.ip_ttl; 9477 action_vxlan_encap_data->items[2].mask = 9478 &ipv6_mask_tos; 9479 } 9480 } 9481 memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, 9482 RTE_DIM(vxlan_encap_conf.vni)); 9483 return 0; 9484 } 9485 9486 /** Parse VXLAN encap action. */ 9487 static int 9488 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 9489 const char *str, unsigned int len, 9490 void *buf, unsigned int size) 9491 { 9492 struct buffer *out = buf; 9493 struct rte_flow_action *action; 9494 struct action_vxlan_encap_data *action_vxlan_encap_data; 9495 int ret; 9496 9497 ret = parse_vc(ctx, token, str, len, buf, size); 9498 if (ret < 0) 9499 return ret; 9500 /* Nothing else to do if there is no buffer. */ 9501 if (!out) 9502 return ret; 9503 if (!out->args.vc.actions_n) 9504 return -1; 9505 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9506 /* Point to selected object. */ 9507 ctx->object = out->args.vc.data; 9508 ctx->objmask = NULL; 9509 action_vxlan_encap_data = ctx->object; 9510 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 9511 action->conf = &action_vxlan_encap_data->conf; 9512 return ret; 9513 } 9514 9515 /** Setup NVGRE encap configuration. */ 9516 static int 9517 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 9518 { 9519 /* Set up default configuration. */ 9520 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 9521 .conf = (struct rte_flow_action_nvgre_encap){ 9522 .definition = action_nvgre_encap_data->items, 9523 }, 9524 .items = { 9525 { 9526 .type = RTE_FLOW_ITEM_TYPE_ETH, 9527 .spec = &action_nvgre_encap_data->item_eth, 9528 .mask = &rte_flow_item_eth_mask, 9529 }, 9530 { 9531 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9532 .spec = &action_nvgre_encap_data->item_vlan, 9533 .mask = &rte_flow_item_vlan_mask, 9534 }, 9535 { 9536 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9537 .spec = &action_nvgre_encap_data->item_ipv4, 9538 .mask = &rte_flow_item_ipv4_mask, 9539 }, 9540 { 9541 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 9542 .spec = &action_nvgre_encap_data->item_nvgre, 9543 .mask = &rte_flow_item_nvgre_mask, 9544 }, 9545 { 9546 .type = RTE_FLOW_ITEM_TYPE_END, 9547 }, 9548 }, 9549 .item_eth.hdr.ether_type = 0, 9550 .item_vlan = { 9551 .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, 9552 .hdr.eth_proto = 0, 9553 }, 9554 .item_ipv4.hdr = { 9555 .src_addr = nvgre_encap_conf.ipv4_src, 9556 .dst_addr = nvgre_encap_conf.ipv4_dst, 9557 }, 9558 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 9559 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 9560 .item_nvgre.flow_id = 0, 9561 }; 9562 memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9563 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9564 memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, 9565 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9566 if (!nvgre_encap_conf.select_ipv4) { 9567 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 9568 &nvgre_encap_conf.ipv6_src, 9569 sizeof(nvgre_encap_conf.ipv6_src)); 9570 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 9571 &nvgre_encap_conf.ipv6_dst, 9572 sizeof(nvgre_encap_conf.ipv6_dst)); 9573 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 9574 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9575 .spec = &action_nvgre_encap_data->item_ipv6, 9576 .mask = &rte_flow_item_ipv6_mask, 9577 }; 9578 } 9579 if (!nvgre_encap_conf.select_vlan) 9580 action_nvgre_encap_data->items[1].type = 9581 RTE_FLOW_ITEM_TYPE_VOID; 9582 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 9583 RTE_DIM(nvgre_encap_conf.tni)); 9584 return 0; 9585 } 9586 9587 /** Parse NVGRE encap action. */ 9588 static int 9589 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 9590 const char *str, unsigned int len, 9591 void *buf, unsigned int size) 9592 { 9593 struct buffer *out = buf; 9594 struct rte_flow_action *action; 9595 struct action_nvgre_encap_data *action_nvgre_encap_data; 9596 int ret; 9597 9598 ret = parse_vc(ctx, token, str, len, buf, size); 9599 if (ret < 0) 9600 return ret; 9601 /* Nothing else to do if there is no buffer. */ 9602 if (!out) 9603 return ret; 9604 if (!out->args.vc.actions_n) 9605 return -1; 9606 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9607 /* Point to selected object. */ 9608 ctx->object = out->args.vc.data; 9609 ctx->objmask = NULL; 9610 action_nvgre_encap_data = ctx->object; 9611 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 9612 action->conf = &action_nvgre_encap_data->conf; 9613 return ret; 9614 } 9615 9616 /** Parse l2 encap action. */ 9617 static int 9618 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 9619 const char *str, unsigned int len, 9620 void *buf, unsigned int size) 9621 { 9622 struct buffer *out = buf; 9623 struct rte_flow_action *action; 9624 struct action_raw_encap_data *action_encap_data; 9625 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9626 struct rte_flow_item_vlan vlan = { 9627 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9628 .hdr.eth_proto = 0, 9629 }; 9630 uint8_t *header; 9631 int ret; 9632 9633 ret = parse_vc(ctx, token, str, len, buf, size); 9634 if (ret < 0) 9635 return ret; 9636 /* Nothing else to do if there is no buffer. */ 9637 if (!out) 9638 return ret; 9639 if (!out->args.vc.actions_n) 9640 return -1; 9641 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9642 /* Point to selected object. */ 9643 ctx->object = out->args.vc.data; 9644 ctx->objmask = NULL; 9645 /* Copy the headers to the buffer. */ 9646 action_encap_data = ctx->object; 9647 *action_encap_data = (struct action_raw_encap_data) { 9648 .conf = (struct rte_flow_action_raw_encap){ 9649 .data = action_encap_data->data, 9650 }, 9651 .data = {}, 9652 }; 9653 header = action_encap_data->data; 9654 if (l2_encap_conf.select_vlan) 9655 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9656 else if (l2_encap_conf.select_ipv4) 9657 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9658 else 9659 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9660 memcpy(eth.hdr.dst_addr.addr_bytes, 9661 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9662 memcpy(eth.hdr.src_addr.addr_bytes, 9663 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9664 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9665 header += sizeof(struct rte_ether_hdr); 9666 if (l2_encap_conf.select_vlan) { 9667 if (l2_encap_conf.select_ipv4) 9668 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9669 else 9670 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9671 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9672 header += sizeof(struct rte_vlan_hdr); 9673 } 9674 action_encap_data->conf.size = header - 9675 action_encap_data->data; 9676 action->conf = &action_encap_data->conf; 9677 return ret; 9678 } 9679 9680 /** Parse l2 decap action. */ 9681 static int 9682 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 9683 const char *str, unsigned int len, 9684 void *buf, unsigned int size) 9685 { 9686 struct buffer *out = buf; 9687 struct rte_flow_action *action; 9688 struct action_raw_decap_data *action_decap_data; 9689 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9690 struct rte_flow_item_vlan vlan = { 9691 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9692 .hdr.eth_proto = 0, 9693 }; 9694 uint8_t *header; 9695 int ret; 9696 9697 ret = parse_vc(ctx, token, str, len, buf, size); 9698 if (ret < 0) 9699 return ret; 9700 /* Nothing else to do if there is no buffer. */ 9701 if (!out) 9702 return ret; 9703 if (!out->args.vc.actions_n) 9704 return -1; 9705 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9706 /* Point to selected object. */ 9707 ctx->object = out->args.vc.data; 9708 ctx->objmask = NULL; 9709 /* Copy the headers to the buffer. */ 9710 action_decap_data = ctx->object; 9711 *action_decap_data = (struct action_raw_decap_data) { 9712 .conf = (struct rte_flow_action_raw_decap){ 9713 .data = action_decap_data->data, 9714 }, 9715 .data = {}, 9716 }; 9717 header = action_decap_data->data; 9718 if (l2_decap_conf.select_vlan) 9719 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9720 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9721 header += sizeof(struct rte_ether_hdr); 9722 if (l2_decap_conf.select_vlan) { 9723 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9724 header += sizeof(struct rte_vlan_hdr); 9725 } 9726 action_decap_data->conf.size = header - 9727 action_decap_data->data; 9728 action->conf = &action_decap_data->conf; 9729 return ret; 9730 } 9731 9732 #define ETHER_TYPE_MPLS_UNICAST 0x8847 9733 9734 /** Parse MPLSOGRE encap action. */ 9735 static int 9736 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 9737 const char *str, unsigned int len, 9738 void *buf, unsigned int size) 9739 { 9740 struct buffer *out = buf; 9741 struct rte_flow_action *action; 9742 struct action_raw_encap_data *action_encap_data; 9743 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9744 struct rte_flow_item_vlan vlan = { 9745 .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, 9746 .hdr.eth_proto = 0, 9747 }; 9748 struct rte_flow_item_ipv4 ipv4 = { 9749 .hdr = { 9750 .src_addr = mplsogre_encap_conf.ipv4_src, 9751 .dst_addr = mplsogre_encap_conf.ipv4_dst, 9752 .next_proto_id = IPPROTO_GRE, 9753 .version_ihl = RTE_IPV4_VHL_DEF, 9754 .time_to_live = IPDEFTTL, 9755 }, 9756 }; 9757 struct rte_flow_item_ipv6 ipv6 = { 9758 .hdr = { 9759 .proto = IPPROTO_GRE, 9760 .hop_limits = IPDEFTTL, 9761 }, 9762 }; 9763 struct rte_flow_item_gre gre = { 9764 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9765 }; 9766 struct rte_flow_item_mpls mpls = { 9767 .ttl = 0, 9768 }; 9769 uint8_t *header; 9770 int ret; 9771 9772 ret = parse_vc(ctx, token, str, len, buf, size); 9773 if (ret < 0) 9774 return ret; 9775 /* Nothing else to do if there is no buffer. */ 9776 if (!out) 9777 return ret; 9778 if (!out->args.vc.actions_n) 9779 return -1; 9780 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9781 /* Point to selected object. */ 9782 ctx->object = out->args.vc.data; 9783 ctx->objmask = NULL; 9784 /* Copy the headers to the buffer. */ 9785 action_encap_data = ctx->object; 9786 *action_encap_data = (struct action_raw_encap_data) { 9787 .conf = (struct rte_flow_action_raw_encap){ 9788 .data = action_encap_data->data, 9789 }, 9790 .data = {}, 9791 .preserve = {}, 9792 }; 9793 header = action_encap_data->data; 9794 if (mplsogre_encap_conf.select_vlan) 9795 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9796 else if (mplsogre_encap_conf.select_ipv4) 9797 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9798 else 9799 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9800 memcpy(eth.hdr.dst_addr.addr_bytes, 9801 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9802 memcpy(eth.hdr.src_addr.addr_bytes, 9803 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9804 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9805 header += sizeof(struct rte_ether_hdr); 9806 if (mplsogre_encap_conf.select_vlan) { 9807 if (mplsogre_encap_conf.select_ipv4) 9808 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9809 else 9810 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9811 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9812 header += sizeof(struct rte_vlan_hdr); 9813 } 9814 if (mplsogre_encap_conf.select_ipv4) { 9815 memcpy(header, &ipv4, sizeof(ipv4)); 9816 header += sizeof(ipv4); 9817 } else { 9818 memcpy(&ipv6.hdr.src_addr, 9819 &mplsogre_encap_conf.ipv6_src, 9820 sizeof(mplsogre_encap_conf.ipv6_src)); 9821 memcpy(&ipv6.hdr.dst_addr, 9822 &mplsogre_encap_conf.ipv6_dst, 9823 sizeof(mplsogre_encap_conf.ipv6_dst)); 9824 memcpy(header, &ipv6, sizeof(ipv6)); 9825 header += sizeof(ipv6); 9826 } 9827 memcpy(header, &gre, sizeof(gre)); 9828 header += sizeof(gre); 9829 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 9830 RTE_DIM(mplsogre_encap_conf.label)); 9831 mpls.label_tc_s[2] |= 0x1; 9832 memcpy(header, &mpls, sizeof(mpls)); 9833 header += sizeof(mpls); 9834 action_encap_data->conf.size = header - 9835 action_encap_data->data; 9836 action->conf = &action_encap_data->conf; 9837 return ret; 9838 } 9839 9840 /** Parse MPLSOGRE decap action. */ 9841 static int 9842 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 9843 const char *str, unsigned int len, 9844 void *buf, unsigned int size) 9845 { 9846 struct buffer *out = buf; 9847 struct rte_flow_action *action; 9848 struct action_raw_decap_data *action_decap_data; 9849 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9850 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9851 struct rte_flow_item_ipv4 ipv4 = { 9852 .hdr = { 9853 .next_proto_id = IPPROTO_GRE, 9854 }, 9855 }; 9856 struct rte_flow_item_ipv6 ipv6 = { 9857 .hdr = { 9858 .proto = IPPROTO_GRE, 9859 }, 9860 }; 9861 struct rte_flow_item_gre gre = { 9862 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9863 }; 9864 struct rte_flow_item_mpls mpls; 9865 uint8_t *header; 9866 int ret; 9867 9868 ret = parse_vc(ctx, token, str, len, buf, size); 9869 if (ret < 0) 9870 return ret; 9871 /* Nothing else to do if there is no buffer. */ 9872 if (!out) 9873 return ret; 9874 if (!out->args.vc.actions_n) 9875 return -1; 9876 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9877 /* Point to selected object. */ 9878 ctx->object = out->args.vc.data; 9879 ctx->objmask = NULL; 9880 /* Copy the headers to the buffer. */ 9881 action_decap_data = ctx->object; 9882 *action_decap_data = (struct action_raw_decap_data) { 9883 .conf = (struct rte_flow_action_raw_decap){ 9884 .data = action_decap_data->data, 9885 }, 9886 .data = {}, 9887 }; 9888 header = action_decap_data->data; 9889 if (mplsogre_decap_conf.select_vlan) 9890 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9891 else if (mplsogre_encap_conf.select_ipv4) 9892 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9893 else 9894 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9895 memcpy(eth.hdr.dst_addr.addr_bytes, 9896 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9897 memcpy(eth.hdr.src_addr.addr_bytes, 9898 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9899 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9900 header += sizeof(struct rte_ether_hdr); 9901 if (mplsogre_encap_conf.select_vlan) { 9902 if (mplsogre_encap_conf.select_ipv4) 9903 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9904 else 9905 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9906 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9907 header += sizeof(struct rte_vlan_hdr); 9908 } 9909 if (mplsogre_encap_conf.select_ipv4) { 9910 memcpy(header, &ipv4, sizeof(ipv4)); 9911 header += sizeof(ipv4); 9912 } else { 9913 memcpy(header, &ipv6, sizeof(ipv6)); 9914 header += sizeof(ipv6); 9915 } 9916 memcpy(header, &gre, sizeof(gre)); 9917 header += sizeof(gre); 9918 memset(&mpls, 0, sizeof(mpls)); 9919 memcpy(header, &mpls, sizeof(mpls)); 9920 header += sizeof(mpls); 9921 action_decap_data->conf.size = header - 9922 action_decap_data->data; 9923 action->conf = &action_decap_data->conf; 9924 return ret; 9925 } 9926 9927 /** Parse MPLSOUDP encap action. */ 9928 static int 9929 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 9930 const char *str, unsigned int len, 9931 void *buf, unsigned int size) 9932 { 9933 struct buffer *out = buf; 9934 struct rte_flow_action *action; 9935 struct action_raw_encap_data *action_encap_data; 9936 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9937 struct rte_flow_item_vlan vlan = { 9938 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9939 .hdr.eth_proto = 0, 9940 }; 9941 struct rte_flow_item_ipv4 ipv4 = { 9942 .hdr = { 9943 .src_addr = mplsoudp_encap_conf.ipv4_src, 9944 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 9945 .next_proto_id = IPPROTO_UDP, 9946 .version_ihl = RTE_IPV4_VHL_DEF, 9947 .time_to_live = IPDEFTTL, 9948 }, 9949 }; 9950 struct rte_flow_item_ipv6 ipv6 = { 9951 .hdr = { 9952 .proto = IPPROTO_UDP, 9953 .hop_limits = IPDEFTTL, 9954 }, 9955 }; 9956 struct rte_flow_item_udp udp = { 9957 .hdr = { 9958 .src_port = mplsoudp_encap_conf.udp_src, 9959 .dst_port = mplsoudp_encap_conf.udp_dst, 9960 }, 9961 }; 9962 struct rte_flow_item_mpls mpls; 9963 uint8_t *header; 9964 int ret; 9965 9966 ret = parse_vc(ctx, token, str, len, buf, size); 9967 if (ret < 0) 9968 return ret; 9969 /* Nothing else to do if there is no buffer. */ 9970 if (!out) 9971 return ret; 9972 if (!out->args.vc.actions_n) 9973 return -1; 9974 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9975 /* Point to selected object. */ 9976 ctx->object = out->args.vc.data; 9977 ctx->objmask = NULL; 9978 /* Copy the headers to the buffer. */ 9979 action_encap_data = ctx->object; 9980 *action_encap_data = (struct action_raw_encap_data) { 9981 .conf = (struct rte_flow_action_raw_encap){ 9982 .data = action_encap_data->data, 9983 }, 9984 .data = {}, 9985 .preserve = {}, 9986 }; 9987 header = action_encap_data->data; 9988 if (mplsoudp_encap_conf.select_vlan) 9989 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9990 else if (mplsoudp_encap_conf.select_ipv4) 9991 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9992 else 9993 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9994 memcpy(eth.hdr.dst_addr.addr_bytes, 9995 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9996 memcpy(eth.hdr.src_addr.addr_bytes, 9997 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9998 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9999 header += sizeof(struct rte_ether_hdr); 10000 if (mplsoudp_encap_conf.select_vlan) { 10001 if (mplsoudp_encap_conf.select_ipv4) 10002 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 10003 else 10004 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 10005 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 10006 header += sizeof(struct rte_vlan_hdr); 10007 } 10008 if (mplsoudp_encap_conf.select_ipv4) { 10009 memcpy(header, &ipv4, sizeof(ipv4)); 10010 header += sizeof(ipv4); 10011 } else { 10012 memcpy(&ipv6.hdr.src_addr, 10013 &mplsoudp_encap_conf.ipv6_src, 10014 sizeof(mplsoudp_encap_conf.ipv6_src)); 10015 memcpy(&ipv6.hdr.dst_addr, 10016 &mplsoudp_encap_conf.ipv6_dst, 10017 sizeof(mplsoudp_encap_conf.ipv6_dst)); 10018 memcpy(header, &ipv6, sizeof(ipv6)); 10019 header += sizeof(ipv6); 10020 } 10021 memcpy(header, &udp, sizeof(udp)); 10022 header += sizeof(udp); 10023 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 10024 RTE_DIM(mplsoudp_encap_conf.label)); 10025 mpls.label_tc_s[2] |= 0x1; 10026 memcpy(header, &mpls, sizeof(mpls)); 10027 header += sizeof(mpls); 10028 action_encap_data->conf.size = header - 10029 action_encap_data->data; 10030 action->conf = &action_encap_data->conf; 10031 return ret; 10032 } 10033 10034 /** Parse MPLSOUDP decap action. */ 10035 static int 10036 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 10037 const char *str, unsigned int len, 10038 void *buf, unsigned int size) 10039 { 10040 struct buffer *out = buf; 10041 struct rte_flow_action *action; 10042 struct action_raw_decap_data *action_decap_data; 10043 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 10044 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 10045 struct rte_flow_item_ipv4 ipv4 = { 10046 .hdr = { 10047 .next_proto_id = IPPROTO_UDP, 10048 }, 10049 }; 10050 struct rte_flow_item_ipv6 ipv6 = { 10051 .hdr = { 10052 .proto = IPPROTO_UDP, 10053 }, 10054 }; 10055 struct rte_flow_item_udp udp = { 10056 .hdr = { 10057 .dst_port = rte_cpu_to_be_16(6635), 10058 }, 10059 }; 10060 struct rte_flow_item_mpls mpls; 10061 uint8_t *header; 10062 int ret; 10063 10064 ret = parse_vc(ctx, token, str, len, buf, size); 10065 if (ret < 0) 10066 return ret; 10067 /* Nothing else to do if there is no buffer. */ 10068 if (!out) 10069 return ret; 10070 if (!out->args.vc.actions_n) 10071 return -1; 10072 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10073 /* Point to selected object. */ 10074 ctx->object = out->args.vc.data; 10075 ctx->objmask = NULL; 10076 /* Copy the headers to the buffer. */ 10077 action_decap_data = ctx->object; 10078 *action_decap_data = (struct action_raw_decap_data) { 10079 .conf = (struct rte_flow_action_raw_decap){ 10080 .data = action_decap_data->data, 10081 }, 10082 .data = {}, 10083 }; 10084 header = action_decap_data->data; 10085 if (mplsoudp_decap_conf.select_vlan) 10086 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 10087 else if (mplsoudp_encap_conf.select_ipv4) 10088 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 10089 else 10090 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 10091 memcpy(eth.hdr.dst_addr.addr_bytes, 10092 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 10093 memcpy(eth.hdr.src_addr.addr_bytes, 10094 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 10095 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 10096 header += sizeof(struct rte_ether_hdr); 10097 if (mplsoudp_encap_conf.select_vlan) { 10098 if (mplsoudp_encap_conf.select_ipv4) 10099 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 10100 else 10101 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 10102 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 10103 header += sizeof(struct rte_vlan_hdr); 10104 } 10105 if (mplsoudp_encap_conf.select_ipv4) { 10106 memcpy(header, &ipv4, sizeof(ipv4)); 10107 header += sizeof(ipv4); 10108 } else { 10109 memcpy(header, &ipv6, sizeof(ipv6)); 10110 header += sizeof(ipv6); 10111 } 10112 memcpy(header, &udp, sizeof(udp)); 10113 header += sizeof(udp); 10114 memset(&mpls, 0, sizeof(mpls)); 10115 memcpy(header, &mpls, sizeof(mpls)); 10116 header += sizeof(mpls); 10117 action_decap_data->conf.size = header - 10118 action_decap_data->data; 10119 action->conf = &action_decap_data->conf; 10120 return ret; 10121 } 10122 10123 static int 10124 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 10125 const char *str, unsigned int len, void *buf, 10126 unsigned int size) 10127 { 10128 struct action_raw_decap_data *action_raw_decap_data; 10129 struct rte_flow_action *action; 10130 const struct arg *arg; 10131 struct buffer *out = buf; 10132 int ret; 10133 uint16_t idx; 10134 10135 RTE_SET_USED(token); 10136 RTE_SET_USED(buf); 10137 RTE_SET_USED(size); 10138 arg = ARGS_ENTRY_ARB_BOUNDED 10139 (offsetof(struct action_raw_decap_data, idx), 10140 sizeof(((struct action_raw_decap_data *)0)->idx), 10141 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10142 if (push_args(ctx, arg)) 10143 return -1; 10144 ret = parse_int(ctx, token, str, len, NULL, 0); 10145 if (ret < 0) { 10146 pop_args(ctx); 10147 return -1; 10148 } 10149 if (!ctx->object) 10150 return len; 10151 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10152 action_raw_decap_data = ctx->object; 10153 idx = action_raw_decap_data->idx; 10154 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 10155 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 10156 action->conf = &action_raw_decap_data->conf; 10157 return len; 10158 } 10159 10160 10161 static int 10162 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 10163 const char *str, unsigned int len, void *buf, 10164 unsigned int size) 10165 { 10166 struct action_raw_encap_data *action_raw_encap_data; 10167 struct rte_flow_action *action; 10168 const struct arg *arg; 10169 struct buffer *out = buf; 10170 int ret; 10171 uint16_t idx; 10172 10173 RTE_SET_USED(token); 10174 RTE_SET_USED(buf); 10175 RTE_SET_USED(size); 10176 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 10177 return -1; 10178 arg = ARGS_ENTRY_ARB_BOUNDED 10179 (offsetof(struct action_raw_encap_data, idx), 10180 sizeof(((struct action_raw_encap_data *)0)->idx), 10181 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10182 if (push_args(ctx, arg)) 10183 return -1; 10184 ret = parse_int(ctx, token, str, len, NULL, 0); 10185 if (ret < 0) { 10186 pop_args(ctx); 10187 return -1; 10188 } 10189 if (!ctx->object) 10190 return len; 10191 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10192 action_raw_encap_data = ctx->object; 10193 idx = action_raw_encap_data->idx; 10194 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 10195 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 10196 action_raw_encap_data->conf.preserve = NULL; 10197 action->conf = &action_raw_encap_data->conf; 10198 return len; 10199 } 10200 10201 static int 10202 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 10203 const char *str, unsigned int len, void *buf, 10204 unsigned int size) 10205 { 10206 struct buffer *out = buf; 10207 int ret; 10208 10209 ret = parse_vc(ctx, token, str, len, buf, size); 10210 if (ret < 0) 10211 return ret; 10212 /* Nothing else to do if there is no buffer. */ 10213 if (!out) 10214 return ret; 10215 if (!out->args.vc.actions_n) 10216 return -1; 10217 /* Point to selected object. */ 10218 ctx->object = out->args.vc.data; 10219 ctx->objmask = NULL; 10220 return ret; 10221 } 10222 10223 static int 10224 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 10225 const char *str, unsigned int len, void *buf, 10226 unsigned int size) 10227 { 10228 struct buffer *out = buf; 10229 struct rte_flow_action *action; 10230 struct action_raw_decap_data *action_raw_decap_data = NULL; 10231 int ret; 10232 10233 ret = parse_vc(ctx, token, str, len, buf, size); 10234 if (ret < 0) 10235 return ret; 10236 /* Nothing else to do if there is no buffer. */ 10237 if (!out) 10238 return ret; 10239 if (!out->args.vc.actions_n) 10240 return -1; 10241 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10242 /* Point to selected object. */ 10243 ctx->object = out->args.vc.data; 10244 ctx->objmask = NULL; 10245 /* Copy the headers to the buffer. */ 10246 action_raw_decap_data = ctx->object; 10247 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 10248 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 10249 action->conf = &action_raw_decap_data->conf; 10250 return ret; 10251 } 10252 10253 static int 10254 parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 10255 const char *str, unsigned int len, void *buf, 10256 unsigned int size) 10257 { 10258 struct buffer *out = buf; 10259 struct rte_flow_action *action; 10260 struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; 10261 int ret; 10262 10263 ret = parse_vc(ctx, token, str, len, buf, size); 10264 if (ret < 0) 10265 return ret; 10266 /* Nothing else to do if there is no buffer. */ 10267 if (!out) 10268 return ret; 10269 if (!out->args.vc.actions_n) 10270 return -1; 10271 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10272 /* Point to selected object. */ 10273 ctx->object = out->args.vc.data; 10274 ctx->objmask = NULL; 10275 /* Copy the headers to the buffer. */ 10276 ipv6_ext_remove_data = ctx->object; 10277 ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; 10278 action->conf = &ipv6_ext_remove_data->conf; 10279 return ret; 10280 } 10281 10282 static int 10283 parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, 10284 const char *str, unsigned int len, void *buf, 10285 unsigned int size) 10286 { 10287 struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; 10288 struct rte_flow_action *action; 10289 const struct arg *arg; 10290 struct buffer *out = buf; 10291 int ret; 10292 uint16_t idx; 10293 10294 RTE_SET_USED(token); 10295 RTE_SET_USED(buf); 10296 RTE_SET_USED(size); 10297 arg = ARGS_ENTRY_ARB_BOUNDED 10298 (offsetof(struct action_ipv6_ext_remove_data, idx), 10299 sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), 10300 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10301 if (push_args(ctx, arg)) 10302 return -1; 10303 ret = parse_int(ctx, token, str, len, NULL, 0); 10304 if (ret < 0) { 10305 pop_args(ctx); 10306 return -1; 10307 } 10308 if (!ctx->object) 10309 return len; 10310 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10311 action_ipv6_ext_remove_data = ctx->object; 10312 idx = action_ipv6_ext_remove_data->idx; 10313 action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; 10314 action->conf = &action_ipv6_ext_remove_data->conf; 10315 return len; 10316 } 10317 10318 static int 10319 parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 10320 const char *str, unsigned int len, void *buf, 10321 unsigned int size) 10322 { 10323 struct buffer *out = buf; 10324 struct rte_flow_action *action; 10325 struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; 10326 int ret; 10327 10328 ret = parse_vc(ctx, token, str, len, buf, size); 10329 if (ret < 0) 10330 return ret; 10331 /* Nothing else to do if there is no buffer. */ 10332 if (!out) 10333 return ret; 10334 if (!out->args.vc.actions_n) 10335 return -1; 10336 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10337 /* Point to selected object. */ 10338 ctx->object = out->args.vc.data; 10339 ctx->objmask = NULL; 10340 /* Copy the headers to the buffer. */ 10341 ipv6_ext_push_data = ctx->object; 10342 ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; 10343 ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; 10344 ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; 10345 action->conf = &ipv6_ext_push_data->conf; 10346 return ret; 10347 } 10348 10349 static int 10350 parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, 10351 const char *str, unsigned int len, void *buf, 10352 unsigned int size) 10353 { 10354 struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; 10355 struct rte_flow_action *action; 10356 const struct arg *arg; 10357 struct buffer *out = buf; 10358 int ret; 10359 uint16_t idx; 10360 10361 RTE_SET_USED(token); 10362 RTE_SET_USED(buf); 10363 RTE_SET_USED(size); 10364 arg = ARGS_ENTRY_ARB_BOUNDED 10365 (offsetof(struct action_ipv6_ext_push_data, idx), 10366 sizeof(((struct action_ipv6_ext_push_data *)0)->idx), 10367 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10368 if (push_args(ctx, arg)) 10369 return -1; 10370 ret = parse_int(ctx, token, str, len, NULL, 0); 10371 if (ret < 0) { 10372 pop_args(ctx); 10373 return -1; 10374 } 10375 if (!ctx->object) 10376 return len; 10377 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10378 action_ipv6_ext_push_data = ctx->object; 10379 idx = action_ipv6_ext_push_data->idx; 10380 action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; 10381 action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; 10382 action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; 10383 action->conf = &action_ipv6_ext_push_data->conf; 10384 return len; 10385 } 10386 10387 static int 10388 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 10389 const char *str, unsigned int len, void *buf, 10390 unsigned int size) 10391 { 10392 int ret; 10393 10394 ret = parse_vc(ctx, token, str, len, buf, size); 10395 if (ret < 0) 10396 return ret; 10397 ret = rte_flow_dynf_metadata_register(); 10398 if (ret < 0) 10399 return -1; 10400 return len; 10401 } 10402 10403 static int 10404 parse_vc_action_sample(struct context *ctx, const struct token *token, 10405 const char *str, unsigned int len, void *buf, 10406 unsigned int size) 10407 { 10408 struct buffer *out = buf; 10409 struct rte_flow_action *action; 10410 struct action_sample_data *action_sample_data = NULL; 10411 static struct rte_flow_action end_action = { 10412 RTE_FLOW_ACTION_TYPE_END, 0 10413 }; 10414 int ret; 10415 10416 ret = parse_vc(ctx, token, str, len, buf, size); 10417 if (ret < 0) 10418 return ret; 10419 /* Nothing else to do if there is no buffer. */ 10420 if (!out) 10421 return ret; 10422 if (!out->args.vc.actions_n) 10423 return -1; 10424 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10425 /* Point to selected object. */ 10426 ctx->object = out->args.vc.data; 10427 ctx->objmask = NULL; 10428 /* Copy the headers to the buffer. */ 10429 action_sample_data = ctx->object; 10430 action_sample_data->conf.actions = &end_action; 10431 action->conf = &action_sample_data->conf; 10432 return ret; 10433 } 10434 10435 static int 10436 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 10437 const char *str, unsigned int len, void *buf, 10438 unsigned int size) 10439 { 10440 struct action_sample_data *action_sample_data; 10441 struct rte_flow_action *action; 10442 const struct arg *arg; 10443 struct buffer *out = buf; 10444 int ret; 10445 uint16_t idx; 10446 10447 RTE_SET_USED(token); 10448 RTE_SET_USED(buf); 10449 RTE_SET_USED(size); 10450 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 10451 return -1; 10452 arg = ARGS_ENTRY_ARB_BOUNDED 10453 (offsetof(struct action_sample_data, idx), 10454 sizeof(((struct action_sample_data *)0)->idx), 10455 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 10456 if (push_args(ctx, arg)) 10457 return -1; 10458 ret = parse_int(ctx, token, str, len, NULL, 0); 10459 if (ret < 0) { 10460 pop_args(ctx); 10461 return -1; 10462 } 10463 if (!ctx->object) 10464 return len; 10465 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10466 action_sample_data = ctx->object; 10467 idx = action_sample_data->idx; 10468 action_sample_data->conf.actions = raw_sample_confs[idx].data; 10469 action->conf = &action_sample_data->conf; 10470 return len; 10471 } 10472 10473 /** Parse operation for modify_field command. */ 10474 static int 10475 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 10476 const char *str, unsigned int len, void *buf, 10477 unsigned int size) 10478 { 10479 struct rte_flow_action_modify_field *action_modify_field; 10480 unsigned int i; 10481 10482 (void)token; 10483 (void)buf; 10484 (void)size; 10485 if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) 10486 return -1; 10487 for (i = 0; modify_field_ops[i]; ++i) 10488 if (!strcmp_partial(modify_field_ops[i], str, len)) 10489 break; 10490 if (!modify_field_ops[i]) 10491 return -1; 10492 if (!ctx->object) 10493 return len; 10494 action_modify_field = ctx->object; 10495 action_modify_field->operation = (enum rte_flow_modify_op)i; 10496 return len; 10497 } 10498 10499 /** Parse id for modify_field command. */ 10500 static int 10501 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 10502 const char *str, unsigned int len, void *buf, 10503 unsigned int size) 10504 { 10505 struct rte_flow_action_modify_field *action_modify_field; 10506 unsigned int i; 10507 10508 (void)token; 10509 (void)buf; 10510 (void)size; 10511 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 10512 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 10513 return -1; 10514 for (i = 0; flow_field_ids[i]; ++i) 10515 if (!strcmp_partial(flow_field_ids[i], str, len)) 10516 break; 10517 if (!flow_field_ids[i]) 10518 return -1; 10519 if (!ctx->object) 10520 return len; 10521 action_modify_field = ctx->object; 10522 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 10523 action_modify_field->dst.field = (enum rte_flow_field_id)i; 10524 else 10525 action_modify_field->src.field = (enum rte_flow_field_id)i; 10526 return len; 10527 } 10528 10529 /** Parse level for modify_field command. */ 10530 static int 10531 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 10532 const char *str, unsigned int len, void *buf, 10533 unsigned int size) 10534 { 10535 struct rte_flow_action_modify_field *action; 10536 struct flex_item *fp = NULL; 10537 uint32_t val; 10538 struct buffer *out = buf; 10539 char *end; 10540 10541 (void)token; 10542 (void)size; 10543 if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10544 ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) 10545 return -1; 10546 if (!ctx->object) 10547 return len; 10548 action = ctx->object; 10549 errno = 0; 10550 val = strtoumax(str, &end, 0); 10551 if (errno || (size_t)(end - str) != len) 10552 return -1; 10553 /* No need to validate action template mask value */ 10554 if (out->args.vc.masks) { 10555 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) 10556 action->dst.level = val; 10557 else 10558 action->src.level = val; 10559 return len; 10560 } 10561 if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10562 action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || 10563 (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && 10564 action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 10565 if (val >= FLEX_MAX_PARSERS_NUM) { 10566 printf("Bad flex item handle\n"); 10567 return -1; 10568 } 10569 fp = flex_items[ctx->port][val]; 10570 if (!fp) { 10571 printf("Bad flex item handle\n"); 10572 return -1; 10573 } 10574 } 10575 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { 10576 if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) 10577 action->dst.level = val; 10578 else 10579 action->dst.flex_handle = fp->flex_handle; 10580 } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { 10581 if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) 10582 action->src.level = val; 10583 else 10584 action->src.flex_handle = fp->flex_handle; 10585 } 10586 return len; 10587 } 10588 10589 /** Parse the conntrack update, not a rte_flow_action. */ 10590 static int 10591 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 10592 const char *str, unsigned int len, void *buf, 10593 unsigned int size) 10594 { 10595 struct buffer *out = buf; 10596 struct rte_flow_modify_conntrack *ct_modify = NULL; 10597 10598 (void)size; 10599 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 10600 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 10601 return -1; 10602 /* Token name must match. */ 10603 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10604 return -1; 10605 /* Nothing else to do if there is no buffer. */ 10606 if (!out) 10607 return len; 10608 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 10609 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 10610 ct_modify->new_ct.is_original_dir = 10611 conntrack_context.is_original_dir; 10612 ct_modify->direction = 1; 10613 } else { 10614 uint32_t old_dir; 10615 10616 old_dir = ct_modify->new_ct.is_original_dir; 10617 memcpy(&ct_modify->new_ct, &conntrack_context, 10618 sizeof(conntrack_context)); 10619 ct_modify->new_ct.is_original_dir = old_dir; 10620 ct_modify->state = 1; 10621 } 10622 return len; 10623 } 10624 10625 /** Parse tokens for destroy command. */ 10626 static int 10627 parse_destroy(struct context *ctx, const struct token *token, 10628 const char *str, unsigned int len, 10629 void *buf, unsigned int size) 10630 { 10631 struct buffer *out = buf; 10632 10633 /* Token name must match. */ 10634 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10635 return -1; 10636 /* Nothing else to do if there is no buffer. */ 10637 if (!out) 10638 return len; 10639 if (!out->command) { 10640 if (ctx->curr != DESTROY) 10641 return -1; 10642 if (sizeof(*out) > size) 10643 return -1; 10644 out->command = ctx->curr; 10645 ctx->objdata = 0; 10646 ctx->object = out; 10647 ctx->objmask = NULL; 10648 out->args.destroy.rule = 10649 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10650 sizeof(double)); 10651 return len; 10652 } 10653 if (ctx->curr == DESTROY_IS_USER_ID) { 10654 out->args.destroy.is_user_id = true; 10655 return len; 10656 } 10657 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 10658 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 10659 return -1; 10660 ctx->objdata = 0; 10661 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 10662 ctx->objmask = NULL; 10663 return len; 10664 } 10665 10666 /** Parse tokens for flush command. */ 10667 static int 10668 parse_flush(struct context *ctx, const struct token *token, 10669 const char *str, unsigned int len, 10670 void *buf, unsigned int size) 10671 { 10672 struct buffer *out = buf; 10673 10674 /* Token name must match. */ 10675 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10676 return -1; 10677 /* Nothing else to do if there is no buffer. */ 10678 if (!out) 10679 return len; 10680 if (!out->command) { 10681 if (ctx->curr != FLUSH) 10682 return -1; 10683 if (sizeof(*out) > size) 10684 return -1; 10685 out->command = ctx->curr; 10686 ctx->objdata = 0; 10687 ctx->object = out; 10688 ctx->objmask = NULL; 10689 } 10690 return len; 10691 } 10692 10693 /** Parse tokens for dump command. */ 10694 static int 10695 parse_dump(struct context *ctx, const struct token *token, 10696 const char *str, unsigned int len, 10697 void *buf, unsigned int size) 10698 { 10699 struct buffer *out = buf; 10700 10701 /* Token name must match. */ 10702 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10703 return -1; 10704 /* Nothing else to do if there is no buffer. */ 10705 if (!out) 10706 return len; 10707 if (!out->command) { 10708 if (ctx->curr != DUMP) 10709 return -1; 10710 if (sizeof(*out) > size) 10711 return -1; 10712 out->command = ctx->curr; 10713 ctx->objdata = 0; 10714 ctx->object = out; 10715 ctx->objmask = NULL; 10716 return len; 10717 } 10718 switch (ctx->curr) { 10719 case DUMP_ALL: 10720 case DUMP_ONE: 10721 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 10722 out->command = ctx->curr; 10723 ctx->objdata = 0; 10724 ctx->object = out; 10725 ctx->objmask = NULL; 10726 return len; 10727 case DUMP_IS_USER_ID: 10728 out->args.dump.is_user_id = true; 10729 return len; 10730 default: 10731 return -1; 10732 } 10733 } 10734 10735 /** Parse tokens for query command. */ 10736 static int 10737 parse_query(struct context *ctx, const struct token *token, 10738 const char *str, unsigned int len, 10739 void *buf, unsigned int size) 10740 { 10741 struct buffer *out = buf; 10742 10743 /* Token name must match. */ 10744 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10745 return -1; 10746 /* Nothing else to do if there is no buffer. */ 10747 if (!out) 10748 return len; 10749 if (!out->command) { 10750 if (ctx->curr != QUERY) 10751 return -1; 10752 if (sizeof(*out) > size) 10753 return -1; 10754 out->command = ctx->curr; 10755 ctx->objdata = 0; 10756 ctx->object = out; 10757 ctx->objmask = NULL; 10758 } 10759 if (ctx->curr == QUERY_IS_USER_ID) { 10760 out->args.query.is_user_id = true; 10761 return len; 10762 } 10763 return len; 10764 } 10765 10766 /** Parse action names. */ 10767 static int 10768 parse_action(struct context *ctx, const struct token *token, 10769 const char *str, unsigned int len, 10770 void *buf, unsigned int size) 10771 { 10772 struct buffer *out = buf; 10773 const struct arg *arg = pop_args(ctx); 10774 unsigned int i; 10775 10776 (void)size; 10777 /* Argument is expected. */ 10778 if (!arg) 10779 return -1; 10780 /* Parse action name. */ 10781 for (i = 0; next_action[i]; ++i) { 10782 const struct parse_action_priv *priv; 10783 10784 token = &token_list[next_action[i]]; 10785 if (strcmp_partial(token->name, str, len)) 10786 continue; 10787 priv = token->priv; 10788 if (!priv) 10789 goto error; 10790 if (out) 10791 memcpy((uint8_t *)ctx->object + arg->offset, 10792 &priv->type, 10793 arg->size); 10794 return len; 10795 } 10796 error: 10797 push_args(ctx, arg); 10798 return -1; 10799 } 10800 10801 /** Parse tokens for list command. */ 10802 static int 10803 parse_list(struct context *ctx, const struct token *token, 10804 const char *str, unsigned int len, 10805 void *buf, unsigned int size) 10806 { 10807 struct buffer *out = buf; 10808 10809 /* Token name must match. */ 10810 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10811 return -1; 10812 /* Nothing else to do if there is no buffer. */ 10813 if (!out) 10814 return len; 10815 if (!out->command) { 10816 if (ctx->curr != LIST) 10817 return -1; 10818 if (sizeof(*out) > size) 10819 return -1; 10820 out->command = ctx->curr; 10821 ctx->objdata = 0; 10822 ctx->object = out; 10823 ctx->objmask = NULL; 10824 out->args.list.group = 10825 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10826 sizeof(double)); 10827 return len; 10828 } 10829 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 10830 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 10831 return -1; 10832 ctx->objdata = 0; 10833 ctx->object = out->args.list.group + out->args.list.group_n++; 10834 ctx->objmask = NULL; 10835 return len; 10836 } 10837 10838 /** Parse tokens for list all aged flows command. */ 10839 static int 10840 parse_aged(struct context *ctx, const struct token *token, 10841 const char *str, unsigned int len, 10842 void *buf, unsigned int size) 10843 { 10844 struct buffer *out = buf; 10845 10846 /* Token name must match. */ 10847 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10848 return -1; 10849 /* Nothing else to do if there is no buffer. */ 10850 if (!out) 10851 return len; 10852 if (!out->command || out->command == QUEUE) { 10853 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 10854 return -1; 10855 if (sizeof(*out) > size) 10856 return -1; 10857 out->command = ctx->curr; 10858 ctx->objdata = 0; 10859 ctx->object = out; 10860 ctx->objmask = NULL; 10861 } 10862 if (ctx->curr == AGED_DESTROY) 10863 out->args.aged.destroy = 1; 10864 return len; 10865 } 10866 10867 /** Parse tokens for isolate command. */ 10868 static int 10869 parse_isolate(struct context *ctx, const struct token *token, 10870 const char *str, unsigned int len, 10871 void *buf, unsigned int size) 10872 { 10873 struct buffer *out = buf; 10874 10875 /* Token name must match. */ 10876 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10877 return -1; 10878 /* Nothing else to do if there is no buffer. */ 10879 if (!out) 10880 return len; 10881 if (!out->command) { 10882 if (ctx->curr != ISOLATE) 10883 return -1; 10884 if (sizeof(*out) > size) 10885 return -1; 10886 out->command = ctx->curr; 10887 ctx->objdata = 0; 10888 ctx->object = out; 10889 ctx->objmask = NULL; 10890 } 10891 return len; 10892 } 10893 10894 /** Parse tokens for info/configure command. */ 10895 static int 10896 parse_configure(struct context *ctx, const struct token *token, 10897 const char *str, unsigned int len, 10898 void *buf, unsigned int size) 10899 { 10900 struct buffer *out = buf; 10901 10902 /* Token name must match. */ 10903 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10904 return -1; 10905 /* Nothing else to do if there is no buffer. */ 10906 if (!out) 10907 return len; 10908 if (!out->command) { 10909 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 10910 return -1; 10911 if (sizeof(*out) > size) 10912 return -1; 10913 out->command = ctx->curr; 10914 ctx->objdata = 0; 10915 ctx->object = out; 10916 ctx->objmask = NULL; 10917 } 10918 return len; 10919 } 10920 10921 /** Parse tokens for template create command. */ 10922 static int 10923 parse_template(struct context *ctx, const struct token *token, 10924 const char *str, unsigned int len, 10925 void *buf, unsigned int size) 10926 { 10927 struct buffer *out = buf; 10928 10929 /* Token name must match. */ 10930 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10931 return -1; 10932 /* Nothing else to do if there is no buffer. */ 10933 if (!out) 10934 return len; 10935 if (!out->command) { 10936 if (ctx->curr != PATTERN_TEMPLATE && 10937 ctx->curr != ACTIONS_TEMPLATE) 10938 return -1; 10939 if (sizeof(*out) > size) 10940 return -1; 10941 out->command = ctx->curr; 10942 ctx->objdata = 0; 10943 ctx->object = out; 10944 ctx->objmask = NULL; 10945 out->args.vc.data = (uint8_t *)out + size; 10946 return len; 10947 } 10948 switch (ctx->curr) { 10949 case PATTERN_TEMPLATE_CREATE: 10950 out->args.vc.pattern = 10951 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10952 sizeof(double)); 10953 out->args.vc.pat_templ_id = UINT32_MAX; 10954 out->command = ctx->curr; 10955 ctx->objdata = 0; 10956 ctx->object = out; 10957 ctx->objmask = NULL; 10958 return len; 10959 case PATTERN_TEMPLATE_EGRESS: 10960 out->args.vc.attr.egress = 1; 10961 return len; 10962 case PATTERN_TEMPLATE_INGRESS: 10963 out->args.vc.attr.ingress = 1; 10964 return len; 10965 case PATTERN_TEMPLATE_TRANSFER: 10966 out->args.vc.attr.transfer = 1; 10967 return len; 10968 case ACTIONS_TEMPLATE_CREATE: 10969 out->args.vc.act_templ_id = UINT32_MAX; 10970 out->command = ctx->curr; 10971 ctx->objdata = 0; 10972 ctx->object = out; 10973 ctx->objmask = NULL; 10974 return len; 10975 case ACTIONS_TEMPLATE_SPEC: 10976 out->args.vc.actions = 10977 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10978 sizeof(double)); 10979 ctx->object = out->args.vc.actions; 10980 ctx->objmask = NULL; 10981 return len; 10982 case ACTIONS_TEMPLATE_MASK: 10983 out->args.vc.masks = 10984 (void *)RTE_ALIGN_CEIL((uintptr_t) 10985 (out->args.vc.actions + 10986 out->args.vc.actions_n), 10987 sizeof(double)); 10988 ctx->object = out->args.vc.masks; 10989 ctx->objmask = NULL; 10990 return len; 10991 case ACTIONS_TEMPLATE_EGRESS: 10992 out->args.vc.attr.egress = 1; 10993 return len; 10994 case ACTIONS_TEMPLATE_INGRESS: 10995 out->args.vc.attr.ingress = 1; 10996 return len; 10997 case ACTIONS_TEMPLATE_TRANSFER: 10998 out->args.vc.attr.transfer = 1; 10999 return len; 11000 default: 11001 return -1; 11002 } 11003 } 11004 11005 /** Parse tokens for template destroy command. */ 11006 static int 11007 parse_template_destroy(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 uint32_t *template_id; 11013 11014 /* Token name must match. */ 11015 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11016 return -1; 11017 /* Nothing else to do if there is no buffer. */ 11018 if (!out) 11019 return len; 11020 if (!out->command || 11021 out->command == PATTERN_TEMPLATE || 11022 out->command == ACTIONS_TEMPLATE) { 11023 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 11024 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 11025 return -1; 11026 if (sizeof(*out) > size) 11027 return -1; 11028 out->command = ctx->curr; 11029 ctx->objdata = 0; 11030 ctx->object = out; 11031 ctx->objmask = NULL; 11032 out->args.templ_destroy.template_id = 11033 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11034 sizeof(double)); 11035 return len; 11036 } 11037 template_id = out->args.templ_destroy.template_id 11038 + out->args.templ_destroy.template_id_n++; 11039 if ((uint8_t *)template_id > (uint8_t *)out + size) 11040 return -1; 11041 ctx->objdata = 0; 11042 ctx->object = template_id; 11043 ctx->objmask = NULL; 11044 return len; 11045 } 11046 11047 /** Parse tokens for table create command. */ 11048 static int 11049 parse_table(struct context *ctx, const struct token *token, 11050 const char *str, unsigned int len, 11051 void *buf, unsigned int size) 11052 { 11053 struct buffer *out = buf; 11054 uint32_t *template_id; 11055 11056 /* Token name must match. */ 11057 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11058 return -1; 11059 /* Nothing else to do if there is no buffer. */ 11060 if (!out) 11061 return len; 11062 if (!out->command) { 11063 if (ctx->curr != TABLE) 11064 return -1; 11065 if (sizeof(*out) > size) 11066 return -1; 11067 out->command = ctx->curr; 11068 ctx->objdata = 0; 11069 ctx->object = out; 11070 ctx->objmask = NULL; 11071 return len; 11072 } 11073 switch (ctx->curr) { 11074 case TABLE_CREATE: 11075 case TABLE_RESIZE: 11076 out->command = ctx->curr; 11077 ctx->objdata = 0; 11078 ctx->object = out; 11079 ctx->objmask = NULL; 11080 out->args.table.id = UINT32_MAX; 11081 return len; 11082 case TABLE_PATTERN_TEMPLATE: 11083 out->args.table.pat_templ_id = 11084 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11085 sizeof(double)); 11086 template_id = out->args.table.pat_templ_id 11087 + out->args.table.pat_templ_id_n++; 11088 if ((uint8_t *)template_id > (uint8_t *)out + size) 11089 return -1; 11090 ctx->objdata = 0; 11091 ctx->object = template_id; 11092 ctx->objmask = NULL; 11093 return len; 11094 case TABLE_ACTIONS_TEMPLATE: 11095 out->args.table.act_templ_id = 11096 (void *)RTE_ALIGN_CEIL((uintptr_t) 11097 (out->args.table.pat_templ_id + 11098 out->args.table.pat_templ_id_n), 11099 sizeof(double)); 11100 template_id = out->args.table.act_templ_id 11101 + out->args.table.act_templ_id_n++; 11102 if ((uint8_t *)template_id > (uint8_t *)out + size) 11103 return -1; 11104 ctx->objdata = 0; 11105 ctx->object = template_id; 11106 ctx->objmask = NULL; 11107 return len; 11108 case TABLE_INGRESS: 11109 out->args.table.attr.flow_attr.ingress = 1; 11110 return len; 11111 case TABLE_EGRESS: 11112 out->args.table.attr.flow_attr.egress = 1; 11113 return len; 11114 case TABLE_TRANSFER: 11115 out->args.table.attr.flow_attr.transfer = 1; 11116 return len; 11117 case TABLE_TRANSFER_WIRE_ORIG: 11118 if (!out->args.table.attr.flow_attr.transfer) 11119 return -1; 11120 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; 11121 return len; 11122 case TABLE_TRANSFER_VPORT_ORIG: 11123 if (!out->args.table.attr.flow_attr.transfer) 11124 return -1; 11125 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; 11126 return len; 11127 case TABLE_RESIZABLE: 11128 out->args.table.attr.specialize |= 11129 RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE; 11130 return len; 11131 case TABLE_RULES_NUMBER: 11132 ctx->objdata = 0; 11133 ctx->object = out; 11134 ctx->objmask = NULL; 11135 return len; 11136 case TABLE_RESIZE_ID: 11137 case TABLE_RESIZE_RULES_NUMBER: 11138 return len; 11139 default: 11140 return -1; 11141 } 11142 } 11143 11144 /** Parse tokens for table destroy command. */ 11145 static int 11146 parse_table_destroy(struct context *ctx, const struct token *token, 11147 const char *str, unsigned int len, 11148 void *buf, unsigned int size) 11149 { 11150 struct buffer *out = buf; 11151 uint32_t *table_id; 11152 11153 /* Token name must match. */ 11154 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11155 return -1; 11156 /* Nothing else to do if there is no buffer. */ 11157 if (!out) 11158 return len; 11159 if (!out->command || out->command == TABLE) { 11160 if (ctx->curr != TABLE_DESTROY && 11161 ctx->curr != TABLE_RESIZE_COMPLETE) 11162 return -1; 11163 if (sizeof(*out) > size) 11164 return -1; 11165 out->command = ctx->curr; 11166 ctx->objdata = 0; 11167 ctx->object = out; 11168 ctx->objmask = NULL; 11169 out->args.table_destroy.table_id = 11170 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11171 sizeof(double)); 11172 return len; 11173 } 11174 table_id = out->args.table_destroy.table_id 11175 + out->args.table_destroy.table_id_n++; 11176 if ((uint8_t *)table_id > (uint8_t *)out + size) 11177 return -1; 11178 ctx->objdata = 0; 11179 ctx->object = table_id; 11180 ctx->objmask = NULL; 11181 return len; 11182 } 11183 11184 /** Parse tokens for queue create commands. */ 11185 static int 11186 parse_qo(struct context *ctx, const struct token *token, 11187 const char *str, unsigned int len, 11188 void *buf, unsigned int size) 11189 { 11190 struct buffer *out = buf; 11191 11192 /* Token name must match. */ 11193 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11194 return -1; 11195 /* Nothing else to do if there is no buffer. */ 11196 if (!out) 11197 return len; 11198 if (!out->command) { 11199 if (ctx->curr != QUEUE) 11200 return -1; 11201 if (sizeof(*out) > size) 11202 return -1; 11203 out->command = ctx->curr; 11204 ctx->objdata = 0; 11205 ctx->object = out; 11206 ctx->objmask = NULL; 11207 out->args.vc.data = (uint8_t *)out + size; 11208 return len; 11209 } 11210 switch (ctx->curr) { 11211 case QUEUE_CREATE: 11212 case QUEUE_UPDATE: 11213 out->command = ctx->curr; 11214 ctx->objdata = 0; 11215 ctx->object = out; 11216 ctx->objmask = NULL; 11217 out->args.vc.rule_id = UINT32_MAX; 11218 return len; 11219 case QUEUE_TEMPLATE_TABLE: 11220 case QUEUE_PATTERN_TEMPLATE: 11221 case QUEUE_ACTIONS_TEMPLATE: 11222 case QUEUE_CREATE_POSTPONE: 11223 case QUEUE_RULE_ID: 11224 case QUEUE_UPDATE_ID: 11225 return len; 11226 case ITEM_PATTERN: 11227 out->args.vc.pattern = 11228 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11229 sizeof(double)); 11230 ctx->object = out->args.vc.pattern; 11231 ctx->objmask = NULL; 11232 return len; 11233 case ACTIONS: 11234 out->args.vc.actions = 11235 (void *)RTE_ALIGN_CEIL((uintptr_t) 11236 (out->args.vc.pattern + 11237 out->args.vc.pattern_n), 11238 sizeof(double)); 11239 ctx->object = out->args.vc.actions; 11240 ctx->objmask = NULL; 11241 return len; 11242 default: 11243 return -1; 11244 } 11245 } 11246 11247 /** Parse tokens for queue destroy command. */ 11248 static int 11249 parse_qo_destroy(struct context *ctx, const struct token *token, 11250 const char *str, unsigned int len, 11251 void *buf, unsigned int size) 11252 { 11253 struct buffer *out = buf; 11254 uint64_t *flow_id; 11255 11256 /* Token name must match. */ 11257 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11258 return -1; 11259 /* Nothing else to do if there is no buffer. */ 11260 if (!out) 11261 return len; 11262 if (!out->command || out->command == QUEUE) { 11263 if (ctx->curr != QUEUE_DESTROY && 11264 ctx->curr != QUEUE_FLOW_UPDATE_RESIZED) 11265 return -1; 11266 if (sizeof(*out) > size) 11267 return -1; 11268 out->command = ctx->curr; 11269 ctx->objdata = 0; 11270 ctx->object = out; 11271 ctx->objmask = NULL; 11272 out->args.destroy.rule = 11273 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11274 sizeof(double)); 11275 return len; 11276 } 11277 switch (ctx->curr) { 11278 case QUEUE_DESTROY_ID: 11279 flow_id = out->args.destroy.rule 11280 + out->args.destroy.rule_n++; 11281 if ((uint8_t *)flow_id > (uint8_t *)out + size) 11282 return -1; 11283 ctx->objdata = 0; 11284 ctx->object = flow_id; 11285 ctx->objmask = NULL; 11286 return len; 11287 case QUEUE_DESTROY_POSTPONE: 11288 return len; 11289 default: 11290 return -1; 11291 } 11292 } 11293 11294 /** Parse tokens for push queue command. */ 11295 static int 11296 parse_push(struct context *ctx, const struct token *token, 11297 const char *str, unsigned int len, 11298 void *buf, unsigned int size) 11299 { 11300 struct buffer *out = buf; 11301 11302 /* Token name must match. */ 11303 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11304 return -1; 11305 /* Nothing else to do if there is no buffer. */ 11306 if (!out) 11307 return len; 11308 if (!out->command) { 11309 if (ctx->curr != PUSH) 11310 return -1; 11311 if (sizeof(*out) > size) 11312 return -1; 11313 out->command = ctx->curr; 11314 ctx->objdata = 0; 11315 ctx->object = out; 11316 ctx->objmask = NULL; 11317 out->args.vc.data = (uint8_t *)out + size; 11318 } 11319 return len; 11320 } 11321 11322 /** Parse tokens for pull command. */ 11323 static int 11324 parse_pull(struct context *ctx, const struct token *token, 11325 const char *str, unsigned int len, 11326 void *buf, unsigned int size) 11327 { 11328 struct buffer *out = buf; 11329 11330 /* Token name must match. */ 11331 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11332 return -1; 11333 /* Nothing else to do if there is no buffer. */ 11334 if (!out) 11335 return len; 11336 if (!out->command) { 11337 if (ctx->curr != PULL) 11338 return -1; 11339 if (sizeof(*out) > size) 11340 return -1; 11341 out->command = ctx->curr; 11342 ctx->objdata = 0; 11343 ctx->object = out; 11344 ctx->objmask = NULL; 11345 out->args.vc.data = (uint8_t *)out + size; 11346 } 11347 return len; 11348 } 11349 11350 /** Parse tokens for hash calculation commands. */ 11351 static int 11352 parse_hash(struct context *ctx, const struct token *token, 11353 const char *str, unsigned int len, 11354 void *buf, unsigned int size) 11355 { 11356 struct buffer *out = buf; 11357 11358 /* Token name must match. */ 11359 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11360 return -1; 11361 /* Nothing else to do if there is no buffer. */ 11362 if (!out) 11363 return len; 11364 if (!out->command) { 11365 if (ctx->curr != HASH) 11366 return -1; 11367 if (sizeof(*out) > size) 11368 return -1; 11369 out->command = ctx->curr; 11370 ctx->objdata = 0; 11371 ctx->object = out; 11372 ctx->objmask = NULL; 11373 out->args.vc.data = (uint8_t *)out + size; 11374 return len; 11375 } 11376 switch (ctx->curr) { 11377 case HASH_CALC_TABLE: 11378 case HASH_CALC_PATTERN_INDEX: 11379 return len; 11380 case ITEM_PATTERN: 11381 out->args.vc.pattern = 11382 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11383 sizeof(double)); 11384 ctx->object = out->args.vc.pattern; 11385 ctx->objmask = NULL; 11386 return len; 11387 case HASH_CALC_ENCAP: 11388 out->args.vc.encap_hash = 1; 11389 return len; 11390 case ENCAP_HASH_FIELD_SRC_PORT: 11391 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT; 11392 return len; 11393 case ENCAP_HASH_FIELD_GRE_FLOW_ID: 11394 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID; 11395 return len; 11396 default: 11397 return -1; 11398 } 11399 } 11400 11401 static int 11402 parse_group(struct context *ctx, const struct token *token, 11403 const char *str, unsigned int len, 11404 void *buf, unsigned int size) 11405 { 11406 struct buffer *out = buf; 11407 11408 /* Token name must match. */ 11409 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11410 return -1; 11411 /* Nothing else to do if there is no buffer. */ 11412 if (!out) 11413 return len; 11414 if (!out->command) { 11415 if (ctx->curr != FLOW_GROUP) 11416 return -1; 11417 if (sizeof(*out) > size) 11418 return -1; 11419 out->command = ctx->curr; 11420 ctx->objdata = 0; 11421 ctx->object = out; 11422 ctx->objmask = NULL; 11423 out->args.vc.data = (uint8_t *)out + size; 11424 return len; 11425 } 11426 switch (ctx->curr) { 11427 case GROUP_INGRESS: 11428 out->args.vc.attr.ingress = 1; 11429 return len; 11430 case GROUP_EGRESS: 11431 out->args.vc.attr.egress = 1; 11432 return len; 11433 case GROUP_TRANSFER: 11434 out->args.vc.attr.transfer = 1; 11435 return len; 11436 case GROUP_SET_MISS_ACTIONS: 11437 out->command = ctx->curr; 11438 ctx->objdata = 0; 11439 ctx->object = out; 11440 ctx->objmask = NULL; 11441 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11442 sizeof(double)); 11443 return len; 11444 default: 11445 return -1; 11446 } 11447 } 11448 11449 static int 11450 parse_flex(struct context *ctx, const struct token *token, 11451 const char *str, unsigned int len, 11452 void *buf, unsigned int size) 11453 { 11454 struct buffer *out = buf; 11455 11456 /* Token name must match. */ 11457 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11458 return -1; 11459 /* Nothing else to do if there is no buffer. */ 11460 if (!out) 11461 return len; 11462 if (out->command == ZERO) { 11463 if (ctx->curr != FLEX) 11464 return -1; 11465 if (sizeof(*out) > size) 11466 return -1; 11467 out->command = ctx->curr; 11468 ctx->objdata = 0; 11469 ctx->object = out; 11470 ctx->objmask = NULL; 11471 } else { 11472 switch (ctx->curr) { 11473 default: 11474 break; 11475 case FLEX_ITEM_INIT: 11476 case FLEX_ITEM_CREATE: 11477 case FLEX_ITEM_DESTROY: 11478 out->command = ctx->curr; 11479 break; 11480 } 11481 } 11482 11483 return len; 11484 } 11485 11486 static int 11487 parse_tunnel(struct context *ctx, const struct token *token, 11488 const char *str, unsigned int len, 11489 void *buf, unsigned int size) 11490 { 11491 struct buffer *out = buf; 11492 11493 /* Token name must match. */ 11494 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11495 return -1; 11496 /* Nothing else to do if there is no buffer. */ 11497 if (!out) 11498 return len; 11499 if (!out->command) { 11500 if (ctx->curr != TUNNEL) 11501 return -1; 11502 if (sizeof(*out) > size) 11503 return -1; 11504 out->command = ctx->curr; 11505 ctx->objdata = 0; 11506 ctx->object = out; 11507 ctx->objmask = NULL; 11508 } else { 11509 switch (ctx->curr) { 11510 default: 11511 break; 11512 case TUNNEL_CREATE: 11513 case TUNNEL_DESTROY: 11514 case TUNNEL_LIST: 11515 out->command = ctx->curr; 11516 break; 11517 case TUNNEL_CREATE_TYPE: 11518 case TUNNEL_DESTROY_ID: 11519 ctx->object = &out->args.vc.tunnel_ops; 11520 break; 11521 } 11522 } 11523 11524 return len; 11525 } 11526 11527 /** 11528 * Parse signed/unsigned integers 8 to 64-bit long. 11529 * 11530 * Last argument (ctx->args) is retrieved to determine integer type and 11531 * storage location. 11532 */ 11533 static int 11534 parse_int(struct context *ctx, const struct token *token, 11535 const char *str, unsigned int len, 11536 void *buf, unsigned int size) 11537 { 11538 const struct arg *arg = pop_args(ctx); 11539 uintmax_t u; 11540 char *end; 11541 11542 (void)token; 11543 /* Argument is expected. */ 11544 if (!arg) 11545 return -1; 11546 errno = 0; 11547 u = arg->sign ? 11548 (uintmax_t)strtoimax(str, &end, 0) : 11549 strtoumax(str, &end, 0); 11550 if (errno || (size_t)(end - str) != len) 11551 goto error; 11552 if (arg->bounded && 11553 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 11554 (intmax_t)u > (intmax_t)arg->max)) || 11555 (!arg->sign && (u < arg->min || u > arg->max)))) 11556 goto error; 11557 if (!ctx->object) 11558 return len; 11559 if (arg->mask) { 11560 if (!arg_entry_bf_fill(ctx->object, u, arg) || 11561 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 11562 goto error; 11563 return len; 11564 } 11565 buf = (uint8_t *)ctx->object + arg->offset; 11566 size = arg->size; 11567 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 11568 return -1; 11569 objmask: 11570 switch (size) { 11571 case sizeof(uint8_t): 11572 *(uint8_t *)buf = u; 11573 break; 11574 case sizeof(uint16_t): 11575 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 11576 break; 11577 case sizeof(uint8_t [3]): 11578 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 11579 if (!arg->hton) { 11580 ((uint8_t *)buf)[0] = u; 11581 ((uint8_t *)buf)[1] = u >> 8; 11582 ((uint8_t *)buf)[2] = u >> 16; 11583 break; 11584 } 11585 #endif 11586 ((uint8_t *)buf)[0] = u >> 16; 11587 ((uint8_t *)buf)[1] = u >> 8; 11588 ((uint8_t *)buf)[2] = u; 11589 break; 11590 case sizeof(uint32_t): 11591 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 11592 break; 11593 case sizeof(uint64_t): 11594 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 11595 break; 11596 default: 11597 goto error; 11598 } 11599 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 11600 u = -1; 11601 buf = (uint8_t *)ctx->objmask + arg->offset; 11602 goto objmask; 11603 } 11604 return len; 11605 error: 11606 push_args(ctx, arg); 11607 return -1; 11608 } 11609 11610 /** 11611 * Parse a string. 11612 * 11613 * Three arguments (ctx->args) are retrieved from the stack to store data, 11614 * its actual length and address (in that order). 11615 */ 11616 static int 11617 parse_string(struct context *ctx, const struct token *token, 11618 const char *str, unsigned int len, 11619 void *buf, unsigned int size) 11620 { 11621 const struct arg *arg_data = pop_args(ctx); 11622 const struct arg *arg_len = pop_args(ctx); 11623 const struct arg *arg_addr = pop_args(ctx); 11624 char tmp[16]; /* Ought to be enough. */ 11625 int ret; 11626 11627 /* Arguments are expected. */ 11628 if (!arg_data) 11629 return -1; 11630 if (!arg_len) { 11631 push_args(ctx, arg_data); 11632 return -1; 11633 } 11634 if (!arg_addr) { 11635 push_args(ctx, arg_len); 11636 push_args(ctx, arg_data); 11637 return -1; 11638 } 11639 size = arg_data->size; 11640 /* Bit-mask fill is not supported. */ 11641 if (arg_data->mask || size < len) 11642 goto error; 11643 if (!ctx->object) 11644 return len; 11645 /* Let parse_int() fill length information first. */ 11646 ret = snprintf(tmp, sizeof(tmp), "%u", len); 11647 if (ret < 0) 11648 goto error; 11649 push_args(ctx, arg_len); 11650 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11651 if (ret < 0) { 11652 pop_args(ctx); 11653 goto error; 11654 } 11655 buf = (uint8_t *)ctx->object + arg_data->offset; 11656 /* Output buffer is not necessarily NUL-terminated. */ 11657 memcpy(buf, str, len); 11658 memset((uint8_t *)buf + len, 0x00, size - len); 11659 if (ctx->objmask) 11660 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11661 /* Save address if requested. */ 11662 if (arg_addr->size) { 11663 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11664 (void *[]){ 11665 (uint8_t *)ctx->object + arg_data->offset 11666 }, 11667 arg_addr->size); 11668 if (ctx->objmask) 11669 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11670 (void *[]){ 11671 (uint8_t *)ctx->objmask + arg_data->offset 11672 }, 11673 arg_addr->size); 11674 } 11675 return len; 11676 error: 11677 push_args(ctx, arg_addr); 11678 push_args(ctx, arg_len); 11679 push_args(ctx, arg_data); 11680 return -1; 11681 } 11682 11683 static int 11684 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 11685 { 11686 const uint8_t *head = dst; 11687 uint32_t left; 11688 11689 if (*size == 0) 11690 return -1; 11691 11692 left = *size; 11693 11694 /* Convert chars to bytes */ 11695 while (left) { 11696 char tmp[3], *end = tmp; 11697 uint32_t read_lim = left & 1 ? 1 : 2; 11698 11699 snprintf(tmp, read_lim + 1, "%s", src); 11700 *dst = strtoul(tmp, &end, 16); 11701 if (*end) { 11702 *dst = 0; 11703 *size = (uint32_t)(dst - head); 11704 return -1; 11705 } 11706 left -= read_lim; 11707 src += read_lim; 11708 dst++; 11709 } 11710 *dst = 0; 11711 *size = (uint32_t)(dst - head); 11712 return 0; 11713 } 11714 11715 static int 11716 parse_hex(struct context *ctx, const struct token *token, 11717 const char *str, unsigned int len, 11718 void *buf, unsigned int size) 11719 { 11720 const struct arg *arg_data = pop_args(ctx); 11721 const struct arg *arg_len = pop_args(ctx); 11722 const struct arg *arg_addr = pop_args(ctx); 11723 char tmp[16]; /* Ought to be enough. */ 11724 int ret; 11725 unsigned int hexlen = len; 11726 unsigned int length = 256; 11727 uint8_t hex_tmp[length]; 11728 11729 /* Arguments are expected. */ 11730 if (!arg_data) 11731 return -1; 11732 if (!arg_len) { 11733 push_args(ctx, arg_data); 11734 return -1; 11735 } 11736 if (!arg_addr) { 11737 push_args(ctx, arg_len); 11738 push_args(ctx, arg_data); 11739 return -1; 11740 } 11741 size = arg_data->size; 11742 /* Bit-mask fill is not supported. */ 11743 if (arg_data->mask) 11744 goto error; 11745 if (!ctx->object) 11746 return len; 11747 11748 /* translate bytes string to array. */ 11749 if (str[0] == '0' && ((str[1] == 'x') || 11750 (str[1] == 'X'))) { 11751 str += 2; 11752 hexlen -= 2; 11753 } 11754 if (hexlen > length) 11755 goto error; 11756 ret = parse_hex_string(str, hex_tmp, &hexlen); 11757 if (ret < 0) 11758 goto error; 11759 /* Check the converted binary fits into data buffer. */ 11760 if (hexlen > size) 11761 goto error; 11762 /* Let parse_int() fill length information first. */ 11763 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 11764 if (ret < 0) 11765 goto error; 11766 /* Save length if requested. */ 11767 if (arg_len->size) { 11768 push_args(ctx, arg_len); 11769 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11770 if (ret < 0) { 11771 pop_args(ctx); 11772 goto error; 11773 } 11774 } 11775 buf = (uint8_t *)ctx->object + arg_data->offset; 11776 /* Output buffer is not necessarily NUL-terminated. */ 11777 memcpy(buf, hex_tmp, hexlen); 11778 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 11779 if (ctx->objmask) 11780 memset((uint8_t *)ctx->objmask + arg_data->offset, 11781 0xff, hexlen); 11782 /* Save address if requested. */ 11783 if (arg_addr->size) { 11784 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11785 (void *[]){ 11786 (uint8_t *)ctx->object + arg_data->offset 11787 }, 11788 arg_addr->size); 11789 if (ctx->objmask) 11790 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11791 (void *[]){ 11792 (uint8_t *)ctx->objmask + arg_data->offset 11793 }, 11794 arg_addr->size); 11795 } 11796 return len; 11797 error: 11798 push_args(ctx, arg_addr); 11799 push_args(ctx, arg_len); 11800 push_args(ctx, arg_data); 11801 return -1; 11802 11803 } 11804 11805 /** 11806 * Parse a zero-ended string. 11807 */ 11808 static int 11809 parse_string0(struct context *ctx, const struct token *token __rte_unused, 11810 const char *str, unsigned int len, 11811 void *buf, unsigned int size) 11812 { 11813 const struct arg *arg_data = pop_args(ctx); 11814 11815 /* Arguments are expected. */ 11816 if (!arg_data) 11817 return -1; 11818 size = arg_data->size; 11819 /* Bit-mask fill is not supported. */ 11820 if (arg_data->mask || size < len + 1) 11821 goto error; 11822 if (!ctx->object) 11823 return len; 11824 buf = (uint8_t *)ctx->object + arg_data->offset; 11825 strncpy(buf, str, len); 11826 if (ctx->objmask) 11827 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11828 return len; 11829 error: 11830 push_args(ctx, arg_data); 11831 return -1; 11832 } 11833 11834 /** 11835 * Parse a MAC address. 11836 * 11837 * Last argument (ctx->args) is retrieved to determine storage size and 11838 * location. 11839 */ 11840 static int 11841 parse_mac_addr(struct context *ctx, const struct token *token, 11842 const char *str, unsigned int len, 11843 void *buf, unsigned int size) 11844 { 11845 const struct arg *arg = pop_args(ctx); 11846 struct rte_ether_addr tmp; 11847 int ret; 11848 11849 (void)token; 11850 /* Argument is expected. */ 11851 if (!arg) 11852 return -1; 11853 size = arg->size; 11854 /* Bit-mask fill is not supported. */ 11855 if (arg->mask || size != sizeof(tmp)) 11856 goto error; 11857 /* Only network endian is supported. */ 11858 if (!arg->hton) 11859 goto error; 11860 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 11861 if (ret < 0 || (unsigned int)ret != len) 11862 goto error; 11863 if (!ctx->object) 11864 return len; 11865 buf = (uint8_t *)ctx->object + arg->offset; 11866 memcpy(buf, &tmp, size); 11867 if (ctx->objmask) 11868 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11869 return len; 11870 error: 11871 push_args(ctx, arg); 11872 return -1; 11873 } 11874 11875 /** 11876 * Parse an IPv4 address. 11877 * 11878 * Last argument (ctx->args) is retrieved to determine storage size and 11879 * location. 11880 */ 11881 static int 11882 parse_ipv4_addr(struct context *ctx, const struct token *token, 11883 const char *str, unsigned int len, 11884 void *buf, unsigned int size) 11885 { 11886 const struct arg *arg = pop_args(ctx); 11887 char str2[len + 1]; 11888 struct in_addr tmp; 11889 int ret; 11890 11891 /* Argument is expected. */ 11892 if (!arg) 11893 return -1; 11894 size = arg->size; 11895 /* Bit-mask fill is not supported. */ 11896 if (arg->mask || size != sizeof(tmp)) 11897 goto error; 11898 /* Only network endian is supported. */ 11899 if (!arg->hton) 11900 goto error; 11901 memcpy(str2, str, len); 11902 str2[len] = '\0'; 11903 ret = inet_pton(AF_INET, str2, &tmp); 11904 if (ret != 1) { 11905 /* Attempt integer parsing. */ 11906 push_args(ctx, arg); 11907 return parse_int(ctx, token, str, len, buf, size); 11908 } 11909 if (!ctx->object) 11910 return len; 11911 buf = (uint8_t *)ctx->object + arg->offset; 11912 memcpy(buf, &tmp, size); 11913 if (ctx->objmask) 11914 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11915 return len; 11916 error: 11917 push_args(ctx, arg); 11918 return -1; 11919 } 11920 11921 /** 11922 * Parse an IPv6 address. 11923 * 11924 * Last argument (ctx->args) is retrieved to determine storage size and 11925 * location. 11926 */ 11927 static int 11928 parse_ipv6_addr(struct context *ctx, const struct token *token, 11929 const char *str, unsigned int len, 11930 void *buf, unsigned int size) 11931 { 11932 const struct arg *arg = pop_args(ctx); 11933 char str2[len + 1]; 11934 struct in6_addr tmp; 11935 int ret; 11936 11937 (void)token; 11938 /* Argument is expected. */ 11939 if (!arg) 11940 return -1; 11941 size = arg->size; 11942 /* Bit-mask fill is not supported. */ 11943 if (arg->mask || size != sizeof(tmp)) 11944 goto error; 11945 /* Only network endian is supported. */ 11946 if (!arg->hton) 11947 goto error; 11948 memcpy(str2, str, len); 11949 str2[len] = '\0'; 11950 ret = inet_pton(AF_INET6, str2, &tmp); 11951 if (ret != 1) 11952 goto error; 11953 if (!ctx->object) 11954 return len; 11955 buf = (uint8_t *)ctx->object + arg->offset; 11956 memcpy(buf, &tmp, size); 11957 if (ctx->objmask) 11958 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11959 return len; 11960 error: 11961 push_args(ctx, arg); 11962 return -1; 11963 } 11964 11965 /** Boolean values (even indices stand for false). */ 11966 static const char *const boolean_name[] = { 11967 "0", "1", 11968 "false", "true", 11969 "no", "yes", 11970 "N", "Y", 11971 "off", "on", 11972 NULL, 11973 }; 11974 11975 /** 11976 * Parse a boolean value. 11977 * 11978 * Last argument (ctx->args) is retrieved to determine storage size and 11979 * location. 11980 */ 11981 static int 11982 parse_boolean(struct context *ctx, const struct token *token, 11983 const char *str, unsigned int len, 11984 void *buf, unsigned int size) 11985 { 11986 const struct arg *arg = pop_args(ctx); 11987 unsigned int i; 11988 int ret; 11989 11990 /* Argument is expected. */ 11991 if (!arg) 11992 return -1; 11993 for (i = 0; boolean_name[i]; ++i) 11994 if (!strcmp_partial(boolean_name[i], str, len)) 11995 break; 11996 /* Process token as integer. */ 11997 if (boolean_name[i]) 11998 str = i & 1 ? "1" : "0"; 11999 push_args(ctx, arg); 12000 ret = parse_int(ctx, token, str, strlen(str), buf, size); 12001 return ret > 0 ? (int)len : ret; 12002 } 12003 12004 /** Parse port and update context. */ 12005 static int 12006 parse_port(struct context *ctx, const struct token *token, 12007 const char *str, unsigned int len, 12008 void *buf, unsigned int size) 12009 { 12010 struct buffer *out = &(struct buffer){ .port = 0 }; 12011 int ret; 12012 12013 if (buf) 12014 out = buf; 12015 else { 12016 ctx->objdata = 0; 12017 ctx->object = out; 12018 ctx->objmask = NULL; 12019 size = sizeof(*out); 12020 } 12021 ret = parse_int(ctx, token, str, len, out, size); 12022 if (ret >= 0) 12023 ctx->port = out->port; 12024 if (!buf) 12025 ctx->object = NULL; 12026 return ret; 12027 } 12028 12029 /** Parse tokens for shared indirect actions. */ 12030 static int 12031 parse_ia_port(struct context *ctx, const struct token *token, 12032 const char *str, unsigned int len, 12033 void *buf, unsigned int size) 12034 { 12035 struct rte_flow_action *action = ctx->object; 12036 uint32_t id; 12037 int ret; 12038 12039 (void)buf; 12040 (void)size; 12041 ctx->objdata = 0; 12042 ctx->object = &id; 12043 ctx->objmask = NULL; 12044 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12045 ctx->object = action; 12046 if (ret != (int)len) 12047 return ret; 12048 /* set indirect action */ 12049 if (action) 12050 action->conf = (void *)(uintptr_t)id; 12051 return ret; 12052 } 12053 12054 static int 12055 parse_ia_id2ptr(struct context *ctx, const struct token *token, 12056 const char *str, unsigned int len, 12057 void *buf, unsigned int size) 12058 { 12059 struct rte_flow_action *action = ctx->object; 12060 uint32_t id; 12061 int ret; 12062 12063 (void)buf; 12064 (void)size; 12065 ctx->objdata = 0; 12066 ctx->object = &id; 12067 ctx->objmask = NULL; 12068 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12069 ctx->object = action; 12070 if (ret != (int)len) 12071 return ret; 12072 /* set indirect action */ 12073 if (action) { 12074 portid_t port_id = ctx->port; 12075 if (ctx->prev == INDIRECT_ACTION_PORT) 12076 port_id = (portid_t)(uintptr_t)action->conf; 12077 action->conf = port_action_handle_get_by_id(port_id, id); 12078 ret = (action->conf) ? ret : -1; 12079 } 12080 return ret; 12081 } 12082 12083 static int 12084 parse_indlst_id2ptr(struct context *ctx, const struct token *token, 12085 const char *str, unsigned int len, 12086 __rte_unused void *buf, __rte_unused unsigned int size) 12087 { 12088 struct rte_flow_action *action = ctx->object; 12089 struct rte_flow_action_indirect_list *action_conf; 12090 const struct indlst_conf *indlst_conf; 12091 uint32_t id; 12092 int ret; 12093 12094 ctx->objdata = 0; 12095 ctx->object = &id; 12096 ctx->objmask = NULL; 12097 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12098 ctx->object = action; 12099 if (ret != (int)len) 12100 return ret; 12101 12102 /* set handle and conf */ 12103 if (action) { 12104 action_conf = (void *)(uintptr_t)action->conf; 12105 action_conf->conf = NULL; 12106 switch (ctx->curr) { 12107 case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: 12108 action_conf->handle = (typeof(action_conf->handle)) 12109 port_action_handle_get_by_id(ctx->port, id); 12110 if (!action_conf->handle) { 12111 printf("no indirect list handle for id %u\n", id); 12112 return -1; 12113 } 12114 break; 12115 case INDIRECT_LIST_ACTION_ID2PTR_CONF: 12116 indlst_conf = indirect_action_list_conf_get(id); 12117 if (!indlst_conf) 12118 return -1; 12119 action_conf->conf = (const void **)indlst_conf->conf; 12120 break; 12121 default: 12122 break; 12123 } 12124 } 12125 return ret; 12126 } 12127 12128 static int 12129 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 12130 const char *str, unsigned int len, 12131 void *buf, unsigned int size) 12132 { 12133 struct rte_flow_action *action = ctx->object; 12134 struct rte_flow_action_meter_mark *meter; 12135 struct rte_flow_meter_profile *profile = NULL; 12136 uint32_t id = 0; 12137 int ret; 12138 12139 (void)buf; 12140 (void)size; 12141 ctx->objdata = 0; 12142 ctx->object = &id; 12143 ctx->objmask = NULL; 12144 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12145 ctx->object = action; 12146 if (ret != (int)len) 12147 return ret; 12148 /* set meter profile */ 12149 if (action) { 12150 meter = (struct rte_flow_action_meter_mark *) 12151 (uintptr_t)(action->conf); 12152 profile = port_meter_profile_get_by_id(ctx->port, id); 12153 meter->profile = profile; 12154 ret = (profile) ? ret : -1; 12155 } 12156 return ret; 12157 } 12158 12159 static int 12160 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 12161 const char *str, unsigned int len, 12162 void *buf, unsigned int size) 12163 { 12164 struct rte_flow_action *action = ctx->object; 12165 struct rte_flow_action_meter_mark *meter; 12166 struct rte_flow_meter_policy *policy = NULL; 12167 uint32_t id = 0; 12168 int ret; 12169 12170 (void)buf; 12171 (void)size; 12172 ctx->objdata = 0; 12173 ctx->object = &id; 12174 ctx->objmask = NULL; 12175 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12176 ctx->object = action; 12177 if (ret != (int)len) 12178 return ret; 12179 /* set meter policy */ 12180 if (action) { 12181 meter = (struct rte_flow_action_meter_mark *) 12182 (uintptr_t)(action->conf); 12183 policy = port_meter_policy_get_by_id(ctx->port, id); 12184 meter->policy = policy; 12185 ret = (policy) ? ret : -1; 12186 } 12187 return ret; 12188 } 12189 12190 /** Parse set command, initialize output buffer for subsequent tokens. */ 12191 static int 12192 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 12193 const char *str, unsigned int len, 12194 void *buf, unsigned int size) 12195 { 12196 struct buffer *out = buf; 12197 12198 /* Token name must match. */ 12199 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12200 return -1; 12201 /* Nothing else to do if there is no buffer. */ 12202 if (!out) 12203 return len; 12204 /* Make sure buffer is large enough. */ 12205 if (size < sizeof(*out)) 12206 return -1; 12207 ctx->objdata = 0; 12208 ctx->objmask = NULL; 12209 ctx->object = out; 12210 if (!out->command) 12211 return -1; 12212 out->command = ctx->curr; 12213 /* For encap/decap we need is pattern */ 12214 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12215 sizeof(double)); 12216 return len; 12217 } 12218 12219 /** Parse set command, initialize output buffer for subsequent tokens. */ 12220 static int 12221 parse_set_sample_action(struct context *ctx, const struct token *token, 12222 const char *str, unsigned int len, 12223 void *buf, unsigned int size) 12224 { 12225 struct buffer *out = buf; 12226 12227 /* Token name must match. */ 12228 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12229 return -1; 12230 /* Nothing else to do if there is no buffer. */ 12231 if (!out) 12232 return len; 12233 /* Make sure buffer is large enough. */ 12234 if (size < sizeof(*out)) 12235 return -1; 12236 ctx->objdata = 0; 12237 ctx->objmask = NULL; 12238 ctx->object = out; 12239 if (!out->command) 12240 return -1; 12241 out->command = ctx->curr; 12242 /* For sampler we need is actions */ 12243 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12244 sizeof(double)); 12245 return len; 12246 } 12247 12248 /** Parse set command, initialize output buffer for subsequent tokens. */ 12249 static int 12250 parse_set_ipv6_ext_action(struct context *ctx, const struct token *token, 12251 const char *str, unsigned int len, 12252 void *buf, unsigned int size) 12253 { 12254 struct buffer *out = buf; 12255 12256 /* Token name must match. */ 12257 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12258 return -1; 12259 /* Nothing else to do if there is no buffer. */ 12260 if (!out) 12261 return len; 12262 /* Make sure buffer is large enough. */ 12263 if (size < sizeof(*out)) 12264 return -1; 12265 ctx->objdata = 0; 12266 ctx->objmask = NULL; 12267 ctx->object = out; 12268 if (!out->command) 12269 return -1; 12270 out->command = ctx->curr; 12271 /* For ipv6_ext_push/remove we need is pattern */ 12272 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12273 sizeof(double)); 12274 return len; 12275 } 12276 12277 /** 12278 * Parse set raw_encap/raw_decap command, 12279 * initialize output buffer for subsequent tokens. 12280 */ 12281 static int 12282 parse_set_init(struct context *ctx, const struct token *token, 12283 const char *str, unsigned int len, 12284 void *buf, unsigned int size) 12285 { 12286 struct buffer *out = buf; 12287 12288 /* Token name must match. */ 12289 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12290 return -1; 12291 /* Nothing else to do if there is no buffer. */ 12292 if (!out) 12293 return len; 12294 /* Make sure buffer is large enough. */ 12295 if (size < sizeof(*out)) 12296 return -1; 12297 /* Initialize buffer. */ 12298 memset(out, 0x00, sizeof(*out)); 12299 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 12300 ctx->objdata = 0; 12301 ctx->object = out; 12302 ctx->objmask = NULL; 12303 if (!out->command) { 12304 if (ctx->curr != SET) 12305 return -1; 12306 if (sizeof(*out) > size) 12307 return -1; 12308 out->command = ctx->curr; 12309 out->args.vc.data = (uint8_t *)out + size; 12310 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12311 sizeof(double)); 12312 } 12313 return len; 12314 } 12315 12316 /* 12317 * Replace testpmd handles in a flex flow item with real values. 12318 */ 12319 static int 12320 parse_flex_handle(struct context *ctx, const struct token *token, 12321 const char *str, unsigned int len, 12322 void *buf, unsigned int size) 12323 { 12324 struct rte_flow_item_flex *spec, *mask; 12325 const struct rte_flow_item_flex *src_spec, *src_mask; 12326 const struct arg *arg = pop_args(ctx); 12327 uint32_t offset; 12328 uint16_t handle; 12329 int ret; 12330 12331 if (!arg) { 12332 printf("Bad environment\n"); 12333 return -1; 12334 } 12335 offset = arg->offset; 12336 push_args(ctx, arg); 12337 ret = parse_int(ctx, token, str, len, buf, size); 12338 if (ret <= 0 || !ctx->object) 12339 return ret; 12340 if (ctx->port >= RTE_MAX_ETHPORTS) { 12341 printf("Bad port\n"); 12342 return -1; 12343 } 12344 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 12345 const struct flex_item *fp; 12346 spec = ctx->object; 12347 handle = (uint16_t)(uintptr_t)spec->handle; 12348 if (handle >= FLEX_MAX_PARSERS_NUM) { 12349 printf("Bad flex item handle\n"); 12350 return -1; 12351 } 12352 fp = flex_items[ctx->port][handle]; 12353 if (!fp) { 12354 printf("Bad flex item handle\n"); 12355 return -1; 12356 } 12357 spec->handle = fp->flex_handle; 12358 mask = spec + 2; /* spec, last, mask */ 12359 mask->handle = fp->flex_handle; 12360 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 12361 handle = (uint16_t)(uintptr_t) 12362 ((struct rte_flow_item_flex *)ctx->object)->pattern; 12363 if (handle >= FLEX_MAX_PATTERNS_NUM) { 12364 printf("Bad pattern handle\n"); 12365 return -1; 12366 } 12367 src_spec = &flex_patterns[handle].spec; 12368 src_mask = &flex_patterns[handle].mask; 12369 spec = ctx->object; 12370 mask = spec + 2; /* spec, last, mask */ 12371 /* fill flow rule spec and mask parameters */ 12372 spec->length = src_spec->length; 12373 spec->pattern = src_spec->pattern; 12374 mask->length = src_mask->length; 12375 mask->pattern = src_mask->pattern; 12376 } else { 12377 printf("Bad arguments - unknown flex item offset\n"); 12378 return -1; 12379 } 12380 return ret; 12381 } 12382 12383 /** Parse Meter color name */ 12384 static int 12385 parse_meter_color(struct context *ctx, const struct token *token, 12386 const char *str, unsigned int len, void *buf, 12387 unsigned int size) 12388 { 12389 struct rte_flow_item_meter_color *meter_color; 12390 unsigned int i; 12391 12392 (void)token; 12393 (void)buf; 12394 (void)size; 12395 for (i = 0; meter_colors[i]; ++i) 12396 if (!strcmp_partial(meter_colors[i], str, len)) 12397 break; 12398 if (!meter_colors[i]) 12399 return -1; 12400 if (!ctx->object) 12401 return len; 12402 meter_color = ctx->object; 12403 meter_color->color = (enum rte_color)i; 12404 return len; 12405 } 12406 12407 /** Parse Insertion Table Type name */ 12408 static int 12409 parse_insertion_table_type(struct context *ctx, const struct token *token, 12410 const char *str, unsigned int len, void *buf, 12411 unsigned int size) 12412 { 12413 const struct arg *arg = pop_args(ctx); 12414 unsigned int i; 12415 char tmp[2]; 12416 int ret; 12417 12418 (void)size; 12419 /* Argument is expected. */ 12420 if (!arg) 12421 return -1; 12422 for (i = 0; table_insertion_types[i]; ++i) 12423 if (!strcmp_partial(table_insertion_types[i], str, len)) 12424 break; 12425 if (!table_insertion_types[i]) 12426 return -1; 12427 push_args(ctx, arg); 12428 snprintf(tmp, sizeof(tmp), "%u", i); 12429 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12430 return ret > 0 ? (int)len : ret; 12431 } 12432 12433 /** Parse Hash Calculation Table Type name */ 12434 static int 12435 parse_hash_table_type(struct context *ctx, const struct token *token, 12436 const char *str, unsigned int len, void *buf, 12437 unsigned int size) 12438 { 12439 const struct arg *arg = pop_args(ctx); 12440 unsigned int i; 12441 char tmp[2]; 12442 int ret; 12443 12444 (void)size; 12445 /* Argument is expected. */ 12446 if (!arg) 12447 return -1; 12448 for (i = 0; table_hash_funcs[i]; ++i) 12449 if (!strcmp_partial(table_hash_funcs[i], str, len)) 12450 break; 12451 if (!table_hash_funcs[i]) 12452 return -1; 12453 push_args(ctx, arg); 12454 snprintf(tmp, sizeof(tmp), "%u", i); 12455 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12456 return ret > 0 ? (int)len : ret; 12457 } 12458 12459 static int 12460 parse_name_to_index(struct context *ctx, const struct token *token, 12461 const char *str, unsigned int len, void *buf, 12462 unsigned int size, 12463 const char *const names[], size_t names_size, uint32_t *dst) 12464 { 12465 int ret; 12466 uint32_t i; 12467 12468 RTE_SET_USED(token); 12469 RTE_SET_USED(buf); 12470 RTE_SET_USED(size); 12471 if (!ctx->object) 12472 return len; 12473 for (i = 0; i < names_size; i++) { 12474 if (!names[i]) 12475 continue; 12476 ret = strcmp_partial(names[i], str, 12477 RTE_MIN(len, strlen(names[i]))); 12478 if (!ret) { 12479 *dst = i; 12480 return len; 12481 } 12482 } 12483 return -1; 12484 } 12485 12486 static const char *const quota_mode_names[] = { 12487 NULL, 12488 [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", 12489 [RTE_FLOW_QUOTA_MODE_L2] = "l2", 12490 [RTE_FLOW_QUOTA_MODE_L3] = "l3" 12491 }; 12492 12493 static const char *const quota_state_names[] = { 12494 [RTE_FLOW_QUOTA_STATE_PASS] = "pass", 12495 [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" 12496 }; 12497 12498 static const char *const quota_update_names[] = { 12499 [RTE_FLOW_UPDATE_QUOTA_SET] = "set", 12500 [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" 12501 }; 12502 12503 static const char *const query_update_mode_names[] = { 12504 [RTE_FLOW_QU_QUERY_FIRST] = "query_first", 12505 [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" 12506 }; 12507 12508 static int 12509 parse_quota_state_name(struct context *ctx, const struct token *token, 12510 const char *str, unsigned int len, void *buf, 12511 unsigned int size) 12512 { 12513 struct rte_flow_item_quota *quota = ctx->object; 12514 12515 return parse_name_to_index(ctx, token, str, len, buf, size, 12516 quota_state_names, 12517 RTE_DIM(quota_state_names), 12518 (uint32_t *)"a->state); 12519 } 12520 12521 static int 12522 parse_quota_mode_name(struct context *ctx, const struct token *token, 12523 const char *str, unsigned int len, void *buf, 12524 unsigned int size) 12525 { 12526 struct rte_flow_action_quota *quota = ctx->object; 12527 12528 return parse_name_to_index(ctx, token, str, len, buf, size, 12529 quota_mode_names, 12530 RTE_DIM(quota_mode_names), 12531 (uint32_t *)"a->mode); 12532 } 12533 12534 static int 12535 parse_quota_update_name(struct context *ctx, const struct token *token, 12536 const char *str, unsigned int len, void *buf, 12537 unsigned int size) 12538 { 12539 struct rte_flow_update_quota *update = ctx->object; 12540 12541 return parse_name_to_index(ctx, token, str, len, buf, size, 12542 quota_update_names, 12543 RTE_DIM(quota_update_names), 12544 (uint32_t *)&update->op); 12545 } 12546 12547 static int 12548 parse_qu_mode_name(struct context *ctx, const struct token *token, 12549 const char *str, unsigned int len, void *buf, 12550 unsigned int size) 12551 { 12552 struct buffer *out = ctx->object; 12553 12554 return parse_name_to_index(ctx, token, str, len, buf, size, 12555 query_update_mode_names, 12556 RTE_DIM(query_update_mode_names), 12557 (uint32_t *)&out->args.ia.qu_mode); 12558 } 12559 12560 /** No completion. */ 12561 static int 12562 comp_none(struct context *ctx, const struct token *token, 12563 unsigned int ent, char *buf, unsigned int size) 12564 { 12565 (void)ctx; 12566 (void)token; 12567 (void)ent; 12568 (void)buf; 12569 (void)size; 12570 return 0; 12571 } 12572 12573 /** Complete boolean values. */ 12574 static int 12575 comp_boolean(struct context *ctx, const struct token *token, 12576 unsigned int ent, char *buf, unsigned int size) 12577 { 12578 unsigned int i; 12579 12580 (void)ctx; 12581 (void)token; 12582 for (i = 0; boolean_name[i]; ++i) 12583 if (buf && i == ent) 12584 return strlcpy(buf, boolean_name[i], size); 12585 if (buf) 12586 return -1; 12587 return i; 12588 } 12589 12590 /** Complete action names. */ 12591 static int 12592 comp_action(struct context *ctx, const struct token *token, 12593 unsigned int ent, char *buf, unsigned int size) 12594 { 12595 unsigned int i; 12596 12597 (void)ctx; 12598 (void)token; 12599 for (i = 0; next_action[i]; ++i) 12600 if (buf && i == ent) 12601 return strlcpy(buf, token_list[next_action[i]].name, 12602 size); 12603 if (buf) 12604 return -1; 12605 return i; 12606 } 12607 12608 /** Complete available ports. */ 12609 static int 12610 comp_port(struct context *ctx, const struct token *token, 12611 unsigned int ent, char *buf, unsigned int size) 12612 { 12613 unsigned int i = 0; 12614 portid_t p; 12615 12616 (void)ctx; 12617 (void)token; 12618 RTE_ETH_FOREACH_DEV(p) { 12619 if (buf && i == ent) 12620 return snprintf(buf, size, "%u", p); 12621 ++i; 12622 } 12623 if (buf) 12624 return -1; 12625 return i; 12626 } 12627 12628 /** Complete available rule IDs. */ 12629 static int 12630 comp_rule_id(struct context *ctx, const struct token *token, 12631 unsigned int ent, char *buf, unsigned int size) 12632 { 12633 unsigned int i = 0; 12634 struct rte_port *port; 12635 struct port_flow *pf; 12636 12637 (void)token; 12638 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12639 ctx->port == (portid_t)RTE_PORT_ALL) 12640 return -1; 12641 port = &ports[ctx->port]; 12642 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 12643 if (buf && i == ent) 12644 return snprintf(buf, size, "%"PRIu64, pf->id); 12645 ++i; 12646 } 12647 if (buf) 12648 return -1; 12649 return i; 12650 } 12651 12652 /** Complete operation for compare match item. */ 12653 static int 12654 comp_set_compare_op(struct context *ctx, const struct token *token, 12655 unsigned int ent, char *buf, unsigned int size) 12656 { 12657 RTE_SET_USED(ctx); 12658 RTE_SET_USED(token); 12659 if (!buf) 12660 return RTE_DIM(compare_ops); 12661 if (ent < RTE_DIM(compare_ops) - 1) 12662 return strlcpy(buf, compare_ops[ent], size); 12663 return -1; 12664 } 12665 12666 /** Complete field id for compare match item. */ 12667 static int 12668 comp_set_compare_field_id(struct context *ctx, const struct token *token, 12669 unsigned int ent, char *buf, unsigned int size) 12670 { 12671 const char *name; 12672 12673 RTE_SET_USED(token); 12674 if (!buf) 12675 return RTE_DIM(flow_field_ids); 12676 if (ent >= RTE_DIM(flow_field_ids) - 1) 12677 return -1; 12678 name = flow_field_ids[ent]; 12679 if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE || 12680 (strcmp(name, "pointer") && strcmp(name, "value"))) 12681 return strlcpy(buf, name, size); 12682 return -1; 12683 } 12684 12685 /** Complete type field for RSS action. */ 12686 static int 12687 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 12688 unsigned int ent, char *buf, unsigned int size) 12689 { 12690 unsigned int i; 12691 12692 (void)ctx; 12693 (void)token; 12694 for (i = 0; rss_type_table[i].str; ++i) 12695 ; 12696 if (!buf) 12697 return i + 1; 12698 if (ent < i) 12699 return strlcpy(buf, rss_type_table[ent].str, size); 12700 if (ent == i) 12701 return snprintf(buf, size, "end"); 12702 return -1; 12703 } 12704 12705 /** Complete queue field for RSS action. */ 12706 static int 12707 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 12708 unsigned int ent, char *buf, unsigned int size) 12709 { 12710 (void)ctx; 12711 (void)token; 12712 if (!buf) 12713 return nb_rxq + 1; 12714 if (ent < nb_rxq) 12715 return snprintf(buf, size, "%u", ent); 12716 if (ent == nb_rxq) 12717 return snprintf(buf, size, "end"); 12718 return -1; 12719 } 12720 12721 /** Complete index number for set raw_encap/raw_decap commands. */ 12722 static int 12723 comp_set_raw_index(struct context *ctx, const struct token *token, 12724 unsigned int ent, char *buf, unsigned int size) 12725 { 12726 uint16_t idx = 0; 12727 uint16_t nb = 0; 12728 12729 RTE_SET_USED(ctx); 12730 RTE_SET_USED(token); 12731 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 12732 if (buf && idx == ent) 12733 return snprintf(buf, size, "%u", idx); 12734 ++nb; 12735 } 12736 return nb; 12737 } 12738 12739 /** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ 12740 static int 12741 comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 12742 unsigned int ent, char *buf, unsigned int size) 12743 { 12744 uint16_t idx = 0; 12745 uint16_t nb = 0; 12746 12747 RTE_SET_USED(ctx); 12748 RTE_SET_USED(token); 12749 for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { 12750 if (buf && idx == ent) 12751 return snprintf(buf, size, "%u", idx); 12752 ++nb; 12753 } 12754 return nb; 12755 } 12756 12757 /** Complete index number for set raw_encap/raw_decap commands. */ 12758 static int 12759 comp_set_sample_index(struct context *ctx, const struct token *token, 12760 unsigned int ent, char *buf, unsigned int size) 12761 { 12762 uint16_t idx = 0; 12763 uint16_t nb = 0; 12764 12765 RTE_SET_USED(ctx); 12766 RTE_SET_USED(token); 12767 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 12768 if (buf && idx == ent) 12769 return snprintf(buf, size, "%u", idx); 12770 ++nb; 12771 } 12772 return nb; 12773 } 12774 12775 /** Complete operation for modify_field command. */ 12776 static int 12777 comp_set_modify_field_op(struct context *ctx, const struct token *token, 12778 unsigned int ent, char *buf, unsigned int size) 12779 { 12780 RTE_SET_USED(ctx); 12781 RTE_SET_USED(token); 12782 if (!buf) 12783 return RTE_DIM(modify_field_ops); 12784 if (ent < RTE_DIM(modify_field_ops) - 1) 12785 return strlcpy(buf, modify_field_ops[ent], size); 12786 return -1; 12787 } 12788 12789 /** Complete field id for modify_field command. */ 12790 static int 12791 comp_set_modify_field_id(struct context *ctx, const struct token *token, 12792 unsigned int ent, char *buf, unsigned int size) 12793 { 12794 const char *name; 12795 12796 RTE_SET_USED(token); 12797 if (!buf) 12798 return RTE_DIM(flow_field_ids); 12799 if (ent >= RTE_DIM(flow_field_ids) - 1) 12800 return -1; 12801 name = flow_field_ids[ent]; 12802 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 12803 (strcmp(name, "pointer") && strcmp(name, "value"))) 12804 return strlcpy(buf, name, size); 12805 return -1; 12806 } 12807 12808 /** Complete available pattern template IDs. */ 12809 static int 12810 comp_pattern_template_id(struct context *ctx, const struct token *token, 12811 unsigned int ent, char *buf, unsigned int size) 12812 { 12813 unsigned int i = 0; 12814 struct rte_port *port; 12815 struct port_template *pt; 12816 12817 (void)token; 12818 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12819 ctx->port == (portid_t)RTE_PORT_ALL) 12820 return -1; 12821 port = &ports[ctx->port]; 12822 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 12823 if (buf && i == ent) 12824 return snprintf(buf, size, "%u", pt->id); 12825 ++i; 12826 } 12827 if (buf) 12828 return -1; 12829 return i; 12830 } 12831 12832 /** Complete available actions template IDs. */ 12833 static int 12834 comp_actions_template_id(struct context *ctx, const struct token *token, 12835 unsigned int ent, char *buf, unsigned int size) 12836 { 12837 unsigned int i = 0; 12838 struct rte_port *port; 12839 struct port_template *pt; 12840 12841 (void)token; 12842 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12843 ctx->port == (portid_t)RTE_PORT_ALL) 12844 return -1; 12845 port = &ports[ctx->port]; 12846 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 12847 if (buf && i == ent) 12848 return snprintf(buf, size, "%u", pt->id); 12849 ++i; 12850 } 12851 if (buf) 12852 return -1; 12853 return i; 12854 } 12855 12856 /** Complete available table IDs. */ 12857 static int 12858 comp_table_id(struct context *ctx, const struct token *token, 12859 unsigned int ent, char *buf, unsigned int size) 12860 { 12861 unsigned int i = 0; 12862 struct rte_port *port; 12863 struct port_table *pt; 12864 12865 (void)token; 12866 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12867 ctx->port == (portid_t)RTE_PORT_ALL) 12868 return -1; 12869 port = &ports[ctx->port]; 12870 for (pt = port->table_list; pt != NULL; pt = pt->next) { 12871 if (buf && i == ent) 12872 return snprintf(buf, size, "%u", pt->id); 12873 ++i; 12874 } 12875 if (buf) 12876 return -1; 12877 return i; 12878 } 12879 12880 /** Complete available queue IDs. */ 12881 static int 12882 comp_queue_id(struct context *ctx, const struct token *token, 12883 unsigned int ent, char *buf, unsigned int size) 12884 { 12885 unsigned int i = 0; 12886 struct rte_port *port; 12887 12888 (void)token; 12889 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12890 ctx->port == (portid_t)RTE_PORT_ALL) 12891 return -1; 12892 port = &ports[ctx->port]; 12893 for (i = 0; i < port->queue_nb; i++) { 12894 if (buf && i == ent) 12895 return snprintf(buf, size, "%u", i); 12896 } 12897 if (buf) 12898 return -1; 12899 return i; 12900 } 12901 12902 static int 12903 comp_names_to_index(struct context *ctx, const struct token *token, 12904 unsigned int ent, char *buf, unsigned int size, 12905 const char *const names[], size_t names_size) 12906 { 12907 RTE_SET_USED(ctx); 12908 RTE_SET_USED(token); 12909 if (!buf) 12910 return names_size; 12911 if (names[ent] && ent < names_size) 12912 return rte_strscpy(buf, names[ent], size); 12913 return -1; 12914 12915 } 12916 12917 /** Complete available Meter colors. */ 12918 static int 12919 comp_meter_color(struct context *ctx, const struct token *token, 12920 unsigned int ent, char *buf, unsigned int size) 12921 { 12922 RTE_SET_USED(ctx); 12923 RTE_SET_USED(token); 12924 if (!buf) 12925 return RTE_DIM(meter_colors); 12926 if (ent < RTE_DIM(meter_colors) - 1) 12927 return strlcpy(buf, meter_colors[ent], size); 12928 return -1; 12929 } 12930 12931 /** Complete available Insertion Table types. */ 12932 static int 12933 comp_insertion_table_type(struct context *ctx, const struct token *token, 12934 unsigned int ent, char *buf, unsigned int size) 12935 { 12936 RTE_SET_USED(ctx); 12937 RTE_SET_USED(token); 12938 if (!buf) 12939 return RTE_DIM(table_insertion_types); 12940 if (ent < RTE_DIM(table_insertion_types) - 1) 12941 return rte_strscpy(buf, table_insertion_types[ent], size); 12942 return -1; 12943 } 12944 12945 /** Complete available Hash Calculation Table types. */ 12946 static int 12947 comp_hash_table_type(struct context *ctx, const struct token *token, 12948 unsigned int ent, char *buf, unsigned int size) 12949 { 12950 RTE_SET_USED(ctx); 12951 RTE_SET_USED(token); 12952 if (!buf) 12953 return RTE_DIM(table_hash_funcs); 12954 if (ent < RTE_DIM(table_hash_funcs) - 1) 12955 return rte_strscpy(buf, table_hash_funcs[ent], size); 12956 return -1; 12957 } 12958 12959 static int 12960 comp_quota_state_name(struct context *ctx, const struct token *token, 12961 unsigned int ent, char *buf, unsigned int size) 12962 { 12963 return comp_names_to_index(ctx, token, ent, buf, size, 12964 quota_state_names, 12965 RTE_DIM(quota_state_names)); 12966 } 12967 12968 static int 12969 comp_quota_mode_name(struct context *ctx, const struct token *token, 12970 unsigned int ent, char *buf, unsigned int size) 12971 { 12972 return comp_names_to_index(ctx, token, ent, buf, size, 12973 quota_mode_names, 12974 RTE_DIM(quota_mode_names)); 12975 } 12976 12977 static int 12978 comp_quota_update_name(struct context *ctx, const struct token *token, 12979 unsigned int ent, char *buf, unsigned int size) 12980 { 12981 return comp_names_to_index(ctx, token, ent, buf, size, 12982 quota_update_names, 12983 RTE_DIM(quota_update_names)); 12984 } 12985 12986 static int 12987 comp_qu_mode_name(struct context *ctx, const struct token *token, 12988 unsigned int ent, char *buf, unsigned int size) 12989 { 12990 return comp_names_to_index(ctx, token, ent, buf, size, 12991 query_update_mode_names, 12992 RTE_DIM(query_update_mode_names)); 12993 } 12994 12995 /** Internal context. */ 12996 static struct context cmd_flow_context; 12997 12998 /** Global parser instance (cmdline API). */ 12999 cmdline_parse_inst_t cmd_flow; 13000 cmdline_parse_inst_t cmd_set_raw; 13001 13002 /** Initialize context. */ 13003 static void 13004 cmd_flow_context_init(struct context *ctx) 13005 { 13006 /* A full memset() is not necessary. */ 13007 ctx->curr = ZERO; 13008 ctx->prev = ZERO; 13009 ctx->next_num = 0; 13010 ctx->args_num = 0; 13011 ctx->eol = 0; 13012 ctx->last = 0; 13013 ctx->port = 0; 13014 ctx->objdata = 0; 13015 ctx->object = NULL; 13016 ctx->objmask = NULL; 13017 } 13018 13019 /** Parse a token (cmdline API). */ 13020 static int 13021 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 13022 unsigned int size) 13023 { 13024 struct context *ctx = &cmd_flow_context; 13025 const struct token *token; 13026 const enum index *list; 13027 int len; 13028 int i; 13029 13030 (void)hdr; 13031 token = &token_list[ctx->curr]; 13032 /* Check argument length. */ 13033 ctx->eol = 0; 13034 ctx->last = 1; 13035 for (len = 0; src[len]; ++len) 13036 if (src[len] == '#' || isspace(src[len])) 13037 break; 13038 if (!len) 13039 return -1; 13040 /* Last argument and EOL detection. */ 13041 for (i = len; src[i]; ++i) 13042 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 13043 break; 13044 else if (!isspace(src[i])) { 13045 ctx->last = 0; 13046 break; 13047 } 13048 for (; src[i]; ++i) 13049 if (src[i] == '\r' || src[i] == '\n') { 13050 ctx->eol = 1; 13051 break; 13052 } 13053 /* Initialize context if necessary. */ 13054 if (!ctx->next_num) { 13055 if (!token->next) 13056 return 0; 13057 ctx->next[ctx->next_num++] = token->next[0]; 13058 } 13059 /* Process argument through candidates. */ 13060 ctx->prev = ctx->curr; 13061 list = ctx->next[ctx->next_num - 1]; 13062 for (i = 0; list[i]; ++i) { 13063 const struct token *next = &token_list[list[i]]; 13064 int tmp; 13065 13066 ctx->curr = list[i]; 13067 if (next->call) 13068 tmp = next->call(ctx, next, src, len, result, size); 13069 else 13070 tmp = parse_default(ctx, next, src, len, result, size); 13071 if (tmp == -1 || tmp != len) 13072 continue; 13073 token = next; 13074 break; 13075 } 13076 if (!list[i]) 13077 return -1; 13078 --ctx->next_num; 13079 /* Push subsequent tokens if any. */ 13080 if (token->next) 13081 for (i = 0; token->next[i]; ++i) { 13082 if (ctx->next_num == RTE_DIM(ctx->next)) 13083 return -1; 13084 ctx->next[ctx->next_num++] = token->next[i]; 13085 } 13086 /* Push arguments if any. */ 13087 if (token->args) 13088 for (i = 0; token->args[i]; ++i) { 13089 if (ctx->args_num == RTE_DIM(ctx->args)) 13090 return -1; 13091 ctx->args[ctx->args_num++] = token->args[i]; 13092 } 13093 return len; 13094 } 13095 13096 int 13097 flow_parse(const char *src, void *result, unsigned int size, 13098 struct rte_flow_attr **attr, 13099 struct rte_flow_item **pattern, struct rte_flow_action **actions) 13100 { 13101 int ret; 13102 struct context saved_flow_ctx = cmd_flow_context; 13103 13104 cmd_flow_context_init(&cmd_flow_context); 13105 do { 13106 ret = cmd_flow_parse(NULL, src, result, size); 13107 if (ret > 0) { 13108 src += ret; 13109 while (isspace(*src)) 13110 src++; 13111 } 13112 } while (ret > 0 && strlen(src)); 13113 cmd_flow_context = saved_flow_ctx; 13114 *attr = &((struct buffer *)result)->args.vc.attr; 13115 *pattern = ((struct buffer *)result)->args.vc.pattern; 13116 *actions = ((struct buffer *)result)->args.vc.actions; 13117 return (ret >= 0 && !strlen(src)) ? 0 : -1; 13118 } 13119 13120 /** Return number of completion entries (cmdline API). */ 13121 static int 13122 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 13123 { 13124 struct context *ctx = &cmd_flow_context; 13125 const struct token *token = &token_list[ctx->curr]; 13126 const enum index *list; 13127 int i; 13128 13129 (void)hdr; 13130 /* Count number of tokens in current list. */ 13131 if (ctx->next_num) 13132 list = ctx->next[ctx->next_num - 1]; 13133 else 13134 list = token->next[0]; 13135 for (i = 0; list[i]; ++i) 13136 ; 13137 if (!i) 13138 return 0; 13139 /* 13140 * If there is a single token, use its completion callback, otherwise 13141 * return the number of entries. 13142 */ 13143 token = &token_list[list[0]]; 13144 if (i == 1 && token->comp) { 13145 /* Save index for cmd_flow_get_help(). */ 13146 ctx->prev = list[0]; 13147 return token->comp(ctx, token, 0, NULL, 0); 13148 } 13149 return i; 13150 } 13151 13152 /** Return a completion entry (cmdline API). */ 13153 static int 13154 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 13155 char *dst, unsigned int size) 13156 { 13157 struct context *ctx = &cmd_flow_context; 13158 const struct token *token = &token_list[ctx->curr]; 13159 const enum index *list; 13160 int i; 13161 13162 (void)hdr; 13163 /* Count number of tokens in current list. */ 13164 if (ctx->next_num) 13165 list = ctx->next[ctx->next_num - 1]; 13166 else 13167 list = token->next[0]; 13168 for (i = 0; list[i]; ++i) 13169 ; 13170 if (!i) 13171 return -1; 13172 /* If there is a single token, use its completion callback. */ 13173 token = &token_list[list[0]]; 13174 if (i == 1 && token->comp) { 13175 /* Save index for cmd_flow_get_help(). */ 13176 ctx->prev = list[0]; 13177 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 13178 } 13179 /* Otherwise make sure the index is valid and use defaults. */ 13180 if (index >= i) 13181 return -1; 13182 token = &token_list[list[index]]; 13183 strlcpy(dst, token->name, size); 13184 /* Save index for cmd_flow_get_help(). */ 13185 ctx->prev = list[index]; 13186 return 0; 13187 } 13188 13189 /** Populate help strings for current token (cmdline API). */ 13190 static int 13191 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 13192 { 13193 struct context *ctx = &cmd_flow_context; 13194 const struct token *token = &token_list[ctx->prev]; 13195 13196 (void)hdr; 13197 if (!size) 13198 return -1; 13199 /* Set token type and update global help with details. */ 13200 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 13201 if (token->help) 13202 cmd_flow.help_str = token->help; 13203 else 13204 cmd_flow.help_str = token->name; 13205 return 0; 13206 } 13207 13208 /** Token definition template (cmdline API). */ 13209 static struct cmdline_token_hdr cmd_flow_token_hdr = { 13210 .ops = &(struct cmdline_token_ops){ 13211 .parse = cmd_flow_parse, 13212 .complete_get_nb = cmd_flow_complete_get_nb, 13213 .complete_get_elt = cmd_flow_complete_get_elt, 13214 .get_help = cmd_flow_get_help, 13215 }, 13216 .offset = 0, 13217 }; 13218 13219 /** Populate the next dynamic token. */ 13220 static void 13221 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 13222 cmdline_parse_token_hdr_t **hdr_inst) 13223 { 13224 struct context *ctx = &cmd_flow_context; 13225 13226 /* Always reinitialize context before requesting the first token. */ 13227 if (!(hdr_inst - cmd_flow.tokens)) 13228 cmd_flow_context_init(ctx); 13229 /* Return NULL when no more tokens are expected. */ 13230 if (!ctx->next_num && ctx->curr) { 13231 *hdr = NULL; 13232 return; 13233 } 13234 /* Determine if command should end here. */ 13235 if (ctx->eol && ctx->last && ctx->next_num) { 13236 const enum index *list = ctx->next[ctx->next_num - 1]; 13237 int i; 13238 13239 for (i = 0; list[i]; ++i) { 13240 if (list[i] != END) 13241 continue; 13242 *hdr = NULL; 13243 return; 13244 } 13245 } 13246 *hdr = &cmd_flow_token_hdr; 13247 } 13248 13249 static SLIST_HEAD(, indlst_conf) indlst_conf_head = 13250 SLIST_HEAD_INITIALIZER(); 13251 13252 static void 13253 indirect_action_flow_conf_create(const struct buffer *in) 13254 { 13255 int len, ret; 13256 uint32_t i; 13257 struct indlst_conf *indlst_conf = NULL; 13258 size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); 13259 struct rte_flow_action *src = in->args.vc.actions; 13260 13261 if (!in->args.vc.actions_n) 13262 goto end; 13263 len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); 13264 if (len <= 0) 13265 goto end; 13266 len = RTE_ALIGN(len, 16); 13267 13268 indlst_conf = calloc(1, base + len + 13269 in->args.vc.actions_n * sizeof(uintptr_t)); 13270 if (!indlst_conf) 13271 goto end; 13272 indlst_conf->id = in->args.vc.attr.group; 13273 indlst_conf->conf_num = in->args.vc.actions_n - 1; 13274 indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); 13275 ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, 13276 len, src, NULL); 13277 if (ret <= 0) { 13278 free(indlst_conf); 13279 indlst_conf = NULL; 13280 goto end; 13281 } 13282 indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); 13283 for (i = 0; i < indlst_conf->conf_num; i++) 13284 indlst_conf->conf[i] = indlst_conf->actions[i].conf; 13285 SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); 13286 end: 13287 if (indlst_conf) 13288 printf("created indirect action list configuration %u\n", 13289 in->args.vc.attr.group); 13290 else 13291 printf("cannot create indirect action list configuration %u\n", 13292 in->args.vc.attr.group); 13293 } 13294 13295 static const struct indlst_conf * 13296 indirect_action_list_conf_get(uint32_t conf_id) 13297 { 13298 const struct indlst_conf *conf; 13299 13300 SLIST_FOREACH(conf, &indlst_conf_head, next) { 13301 if (conf->id == conf_id) 13302 return conf; 13303 } 13304 return NULL; 13305 } 13306 13307 /** Dispatch parsed buffer to function calls. */ 13308 static void 13309 cmd_flow_parsed(const struct buffer *in) 13310 { 13311 switch (in->command) { 13312 case INFO: 13313 port_flow_get_info(in->port); 13314 break; 13315 case CONFIGURE: 13316 port_flow_configure(in->port, 13317 &in->args.configure.port_attr, 13318 in->args.configure.nb_queue, 13319 &in->args.configure.queue_attr); 13320 break; 13321 case PATTERN_TEMPLATE_CREATE: 13322 port_flow_pattern_template_create(in->port, 13323 in->args.vc.pat_templ_id, 13324 &((const struct rte_flow_pattern_template_attr) { 13325 .relaxed_matching = in->args.vc.attr.reserved, 13326 .ingress = in->args.vc.attr.ingress, 13327 .egress = in->args.vc.attr.egress, 13328 .transfer = in->args.vc.attr.transfer, 13329 }), 13330 in->args.vc.pattern); 13331 break; 13332 case PATTERN_TEMPLATE_DESTROY: 13333 port_flow_pattern_template_destroy(in->port, 13334 in->args.templ_destroy.template_id_n, 13335 in->args.templ_destroy.template_id); 13336 break; 13337 case ACTIONS_TEMPLATE_CREATE: 13338 port_flow_actions_template_create(in->port, 13339 in->args.vc.act_templ_id, 13340 &((const struct rte_flow_actions_template_attr) { 13341 .ingress = in->args.vc.attr.ingress, 13342 .egress = in->args.vc.attr.egress, 13343 .transfer = in->args.vc.attr.transfer, 13344 }), 13345 in->args.vc.actions, 13346 in->args.vc.masks); 13347 break; 13348 case ACTIONS_TEMPLATE_DESTROY: 13349 port_flow_actions_template_destroy(in->port, 13350 in->args.templ_destroy.template_id_n, 13351 in->args.templ_destroy.template_id); 13352 break; 13353 case TABLE_CREATE: 13354 port_flow_template_table_create(in->port, in->args.table.id, 13355 &in->args.table.attr, in->args.table.pat_templ_id_n, 13356 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 13357 in->args.table.act_templ_id); 13358 break; 13359 case TABLE_DESTROY: 13360 port_flow_template_table_destroy(in->port, 13361 in->args.table_destroy.table_id_n, 13362 in->args.table_destroy.table_id); 13363 break; 13364 case TABLE_RESIZE_COMPLETE: 13365 port_flow_template_table_resize_complete 13366 (in->port, in->args.table_destroy.table_id[0]); 13367 break; 13368 case GROUP_SET_MISS_ACTIONS: 13369 port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, 13370 in->args.vc.actions); 13371 break; 13372 case TABLE_RESIZE: 13373 port_flow_template_table_resize(in->port, in->args.table.id, 13374 in->args.table.attr.nb_flows); 13375 break; 13376 case QUEUE_CREATE: 13377 port_queue_flow_create(in->port, in->queue, in->postpone, 13378 in->args.vc.table_id, in->args.vc.rule_id, 13379 in->args.vc.pat_templ_id, in->args.vc.act_templ_id, 13380 in->args.vc.pattern, in->args.vc.actions); 13381 break; 13382 case QUEUE_DESTROY: 13383 port_queue_flow_destroy(in->port, in->queue, in->postpone, 13384 in->args.destroy.rule_n, 13385 in->args.destroy.rule); 13386 break; 13387 case QUEUE_FLOW_UPDATE_RESIZED: 13388 port_queue_flow_update_resized(in->port, in->queue, 13389 in->postpone, 13390 in->args.destroy.rule[0]); 13391 break; 13392 case QUEUE_UPDATE: 13393 port_queue_flow_update(in->port, in->queue, in->postpone, 13394 in->args.vc.rule_id, in->args.vc.act_templ_id, 13395 in->args.vc.actions); 13396 break; 13397 case PUSH: 13398 port_queue_flow_push(in->port, in->queue); 13399 break; 13400 case PULL: 13401 port_queue_flow_pull(in->port, in->queue); 13402 break; 13403 case HASH: 13404 if (!in->args.vc.encap_hash) 13405 port_flow_hash_calc(in->port, in->args.vc.table_id, 13406 in->args.vc.pat_templ_id, 13407 in->args.vc.pattern); 13408 else 13409 port_flow_hash_calc_encap(in->port, in->args.vc.field, 13410 in->args.vc.pattern); 13411 break; 13412 case QUEUE_AGED: 13413 port_queue_flow_aged(in->port, in->queue, 13414 in->args.aged.destroy); 13415 break; 13416 case QUEUE_INDIRECT_ACTION_CREATE: 13417 case QUEUE_INDIRECT_ACTION_LIST_CREATE: 13418 port_queue_action_handle_create( 13419 in->port, in->queue, in->postpone, 13420 in->args.vc.attr.group, 13421 in->command == QUEUE_INDIRECT_ACTION_LIST_CREATE, 13422 &((const struct rte_flow_indir_action_conf) { 13423 .ingress = in->args.vc.attr.ingress, 13424 .egress = in->args.vc.attr.egress, 13425 .transfer = in->args.vc.attr.transfer, 13426 }), 13427 in->args.vc.actions); 13428 break; 13429 case QUEUE_INDIRECT_ACTION_DESTROY: 13430 port_queue_action_handle_destroy(in->port, 13431 in->queue, in->postpone, 13432 in->args.ia_destroy.action_id_n, 13433 in->args.ia_destroy.action_id); 13434 break; 13435 case QUEUE_INDIRECT_ACTION_UPDATE: 13436 port_queue_action_handle_update(in->port, 13437 in->queue, in->postpone, 13438 in->args.vc.attr.group, 13439 in->args.vc.actions); 13440 break; 13441 case QUEUE_INDIRECT_ACTION_QUERY: 13442 port_queue_action_handle_query(in->port, 13443 in->queue, in->postpone, 13444 in->args.ia.action_id); 13445 break; 13446 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 13447 port_queue_action_handle_query_update(in->port, in->queue, 13448 in->postpone, 13449 in->args.ia.action_id, 13450 in->args.ia.qu_mode, 13451 in->args.vc.actions); 13452 break; 13453 case INDIRECT_ACTION_CREATE: 13454 case INDIRECT_ACTION_LIST_CREATE: 13455 port_action_handle_create( 13456 in->port, in->args.vc.attr.group, 13457 in->command == INDIRECT_ACTION_LIST_CREATE, 13458 &((const struct rte_flow_indir_action_conf) { 13459 .ingress = in->args.vc.attr.ingress, 13460 .egress = in->args.vc.attr.egress, 13461 .transfer = in->args.vc.attr.transfer, 13462 }), 13463 in->args.vc.actions); 13464 break; 13465 case INDIRECT_ACTION_FLOW_CONF_CREATE: 13466 indirect_action_flow_conf_create(in); 13467 break; 13468 case INDIRECT_ACTION_DESTROY: 13469 port_action_handle_destroy(in->port, 13470 in->args.ia_destroy.action_id_n, 13471 in->args.ia_destroy.action_id); 13472 break; 13473 case INDIRECT_ACTION_UPDATE: 13474 port_action_handle_update(in->port, in->args.vc.attr.group, 13475 in->args.vc.actions); 13476 break; 13477 case INDIRECT_ACTION_QUERY: 13478 port_action_handle_query(in->port, in->args.ia.action_id); 13479 break; 13480 case INDIRECT_ACTION_QUERY_UPDATE: 13481 port_action_handle_query_update(in->port, 13482 in->args.ia.action_id, 13483 in->args.ia.qu_mode, 13484 in->args.vc.actions); 13485 break; 13486 case VALIDATE: 13487 port_flow_validate(in->port, &in->args.vc.attr, 13488 in->args.vc.pattern, in->args.vc.actions, 13489 &in->args.vc.tunnel_ops); 13490 break; 13491 case CREATE: 13492 port_flow_create(in->port, &in->args.vc.attr, 13493 in->args.vc.pattern, in->args.vc.actions, 13494 &in->args.vc.tunnel_ops, in->args.vc.user_id); 13495 break; 13496 case DESTROY: 13497 port_flow_destroy(in->port, in->args.destroy.rule_n, 13498 in->args.destroy.rule, 13499 in->args.destroy.is_user_id); 13500 break; 13501 case UPDATE: 13502 port_flow_update(in->port, in->args.vc.rule_id, 13503 in->args.vc.actions, in->args.vc.user_id); 13504 break; 13505 case FLUSH: 13506 port_flow_flush(in->port); 13507 break; 13508 case DUMP_ONE: 13509 case DUMP_ALL: 13510 port_flow_dump(in->port, in->args.dump.mode, 13511 in->args.dump.rule, in->args.dump.file, 13512 in->args.dump.is_user_id); 13513 break; 13514 case QUERY: 13515 port_flow_query(in->port, in->args.query.rule, 13516 &in->args.query.action, 13517 in->args.query.is_user_id); 13518 break; 13519 case LIST: 13520 port_flow_list(in->port, in->args.list.group_n, 13521 in->args.list.group); 13522 break; 13523 case ISOLATE: 13524 port_flow_isolate(in->port, in->args.isolate.set); 13525 break; 13526 case AGED: 13527 port_flow_aged(in->port, in->args.aged.destroy); 13528 break; 13529 case TUNNEL_CREATE: 13530 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 13531 break; 13532 case TUNNEL_DESTROY: 13533 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 13534 break; 13535 case TUNNEL_LIST: 13536 port_flow_tunnel_list(in->port); 13537 break; 13538 case ACTION_POL_G: 13539 port_meter_policy_add(in->port, in->args.policy.policy_id, 13540 in->args.vc.actions); 13541 break; 13542 case FLEX_ITEM_CREATE: 13543 flex_item_create(in->port, in->args.flex.token, 13544 in->args.flex.filename); 13545 break; 13546 case FLEX_ITEM_DESTROY: 13547 flex_item_destroy(in->port, in->args.flex.token); 13548 break; 13549 default: 13550 break; 13551 } 13552 fflush(stdout); 13553 } 13554 13555 /** Token generator and output processing callback (cmdline API). */ 13556 static void 13557 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 13558 { 13559 if (cl == NULL) 13560 cmd_flow_tok(arg0, arg2); 13561 else 13562 cmd_flow_parsed(arg0); 13563 } 13564 13565 /** Global parser instance (cmdline API). */ 13566 cmdline_parse_inst_t cmd_flow = { 13567 .f = cmd_flow_cb, 13568 .data = NULL, /**< Unused. */ 13569 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 13570 .tokens = { 13571 NULL, 13572 }, /**< Tokens are returned by cmd_flow_tok(). */ 13573 }; 13574 13575 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 13576 13577 static void 13578 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 13579 { 13580 struct rte_ipv4_hdr *ipv4; 13581 struct rte_ether_hdr *eth; 13582 struct rte_ipv6_hdr *ipv6; 13583 struct rte_vxlan_hdr *vxlan; 13584 struct rte_vxlan_gpe_hdr *gpe; 13585 struct rte_flow_item_nvgre *nvgre; 13586 uint32_t ipv6_vtc_flow; 13587 13588 switch (item->type) { 13589 case RTE_FLOW_ITEM_TYPE_ETH: 13590 eth = (struct rte_ether_hdr *)buf; 13591 if (next_proto) 13592 eth->ether_type = rte_cpu_to_be_16(next_proto); 13593 break; 13594 case RTE_FLOW_ITEM_TYPE_IPV4: 13595 ipv4 = (struct rte_ipv4_hdr *)buf; 13596 if (!ipv4->version_ihl) 13597 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 13598 if (next_proto && ipv4->next_proto_id == 0) 13599 ipv4->next_proto_id = (uint8_t)next_proto; 13600 break; 13601 case RTE_FLOW_ITEM_TYPE_IPV6: 13602 ipv6 = (struct rte_ipv6_hdr *)buf; 13603 if (next_proto && ipv6->proto == 0) 13604 ipv6->proto = (uint8_t)next_proto; 13605 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 13606 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 13607 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 13608 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 13609 break; 13610 case RTE_FLOW_ITEM_TYPE_VXLAN: 13611 vxlan = (struct rte_vxlan_hdr *)buf; 13612 vxlan->vx_flags = 0x08; 13613 break; 13614 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13615 gpe = (struct rte_vxlan_gpe_hdr *)buf; 13616 gpe->vx_flags = 0x0C; 13617 break; 13618 case RTE_FLOW_ITEM_TYPE_NVGRE: 13619 nvgre = (struct rte_flow_item_nvgre *)buf; 13620 nvgre->protocol = rte_cpu_to_be_16(0x6558); 13621 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 13622 break; 13623 default: 13624 break; 13625 } 13626 } 13627 13628 /** Helper of get item's default mask. */ 13629 static const void * 13630 flow_item_default_mask(const struct rte_flow_item *item) 13631 { 13632 const void *mask = NULL; 13633 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 13634 static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { 13635 .hdr = { 13636 .next_hdr = 0xff, 13637 .type = 0xff, 13638 .segments_left = 0xff, 13639 }, 13640 }; 13641 13642 switch (item->type) { 13643 case RTE_FLOW_ITEM_TYPE_ANY: 13644 mask = &rte_flow_item_any_mask; 13645 break; 13646 case RTE_FLOW_ITEM_TYPE_PORT_ID: 13647 mask = &rte_flow_item_port_id_mask; 13648 break; 13649 case RTE_FLOW_ITEM_TYPE_RAW: 13650 mask = &rte_flow_item_raw_mask; 13651 break; 13652 case RTE_FLOW_ITEM_TYPE_ETH: 13653 mask = &rte_flow_item_eth_mask; 13654 break; 13655 case RTE_FLOW_ITEM_TYPE_VLAN: 13656 mask = &rte_flow_item_vlan_mask; 13657 break; 13658 case RTE_FLOW_ITEM_TYPE_IPV4: 13659 mask = &rte_flow_item_ipv4_mask; 13660 break; 13661 case RTE_FLOW_ITEM_TYPE_IPV6: 13662 mask = &rte_flow_item_ipv6_mask; 13663 break; 13664 case RTE_FLOW_ITEM_TYPE_ICMP: 13665 mask = &rte_flow_item_icmp_mask; 13666 break; 13667 case RTE_FLOW_ITEM_TYPE_UDP: 13668 mask = &rte_flow_item_udp_mask; 13669 break; 13670 case RTE_FLOW_ITEM_TYPE_TCP: 13671 mask = &rte_flow_item_tcp_mask; 13672 break; 13673 case RTE_FLOW_ITEM_TYPE_SCTP: 13674 mask = &rte_flow_item_sctp_mask; 13675 break; 13676 case RTE_FLOW_ITEM_TYPE_VXLAN: 13677 mask = &rte_flow_item_vxlan_mask; 13678 break; 13679 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13680 mask = &rte_flow_item_vxlan_gpe_mask; 13681 break; 13682 case RTE_FLOW_ITEM_TYPE_E_TAG: 13683 mask = &rte_flow_item_e_tag_mask; 13684 break; 13685 case RTE_FLOW_ITEM_TYPE_NVGRE: 13686 mask = &rte_flow_item_nvgre_mask; 13687 break; 13688 case RTE_FLOW_ITEM_TYPE_MPLS: 13689 mask = &rte_flow_item_mpls_mask; 13690 break; 13691 case RTE_FLOW_ITEM_TYPE_GRE: 13692 mask = &rte_flow_item_gre_mask; 13693 break; 13694 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13695 mask = &gre_key_default_mask; 13696 break; 13697 case RTE_FLOW_ITEM_TYPE_META: 13698 mask = &rte_flow_item_meta_mask; 13699 break; 13700 case RTE_FLOW_ITEM_TYPE_RANDOM: 13701 mask = &rte_flow_item_random_mask; 13702 break; 13703 case RTE_FLOW_ITEM_TYPE_FUZZY: 13704 mask = &rte_flow_item_fuzzy_mask; 13705 break; 13706 case RTE_FLOW_ITEM_TYPE_GTP: 13707 mask = &rte_flow_item_gtp_mask; 13708 break; 13709 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13710 mask = &rte_flow_item_gtp_psc_mask; 13711 break; 13712 case RTE_FLOW_ITEM_TYPE_GENEVE: 13713 mask = &rte_flow_item_geneve_mask; 13714 break; 13715 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13716 mask = &rte_flow_item_geneve_opt_mask; 13717 break; 13718 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 13719 mask = &rte_flow_item_pppoe_proto_id_mask; 13720 break; 13721 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13722 mask = &rte_flow_item_l2tpv3oip_mask; 13723 break; 13724 case RTE_FLOW_ITEM_TYPE_ESP: 13725 mask = &rte_flow_item_esp_mask; 13726 break; 13727 case RTE_FLOW_ITEM_TYPE_AH: 13728 mask = &rte_flow_item_ah_mask; 13729 break; 13730 case RTE_FLOW_ITEM_TYPE_PFCP: 13731 mask = &rte_flow_item_pfcp_mask; 13732 break; 13733 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 13734 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 13735 mask = &rte_flow_item_ethdev_mask; 13736 break; 13737 case RTE_FLOW_ITEM_TYPE_L2TPV2: 13738 mask = &rte_flow_item_l2tpv2_mask; 13739 break; 13740 case RTE_FLOW_ITEM_TYPE_PPP: 13741 mask = &rte_flow_item_ppp_mask; 13742 break; 13743 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 13744 mask = &rte_flow_item_meter_color_mask; 13745 break; 13746 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13747 mask = &ipv6_routing_ext_default_mask; 13748 break; 13749 case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: 13750 mask = &rte_flow_item_aggr_affinity_mask; 13751 break; 13752 case RTE_FLOW_ITEM_TYPE_TX_QUEUE: 13753 mask = &rte_flow_item_tx_queue_mask; 13754 break; 13755 case RTE_FLOW_ITEM_TYPE_IB_BTH: 13756 mask = &rte_flow_item_ib_bth_mask; 13757 break; 13758 case RTE_FLOW_ITEM_TYPE_PTYPE: 13759 mask = &rte_flow_item_ptype_mask; 13760 break; 13761 default: 13762 break; 13763 } 13764 return mask; 13765 } 13766 13767 /** Dispatch parsed buffer to function calls. */ 13768 static void 13769 cmd_set_ipv6_ext_parsed(const struct buffer *in) 13770 { 13771 uint32_t n = in->args.vc.pattern_n; 13772 int i = 0; 13773 struct rte_flow_item *item = NULL; 13774 size_t size = 0; 13775 uint8_t *data = NULL; 13776 uint8_t *type = NULL; 13777 size_t *total_size = NULL; 13778 uint16_t idx = in->port; /* We borrow port field as index */ 13779 struct rte_flow_item_ipv6_routing_ext *ext; 13780 const struct rte_flow_item_ipv6_ext *ipv6_ext; 13781 13782 RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || 13783 in->command == SET_IPV6_EXT_REMOVE); 13784 13785 if (in->command == SET_IPV6_EXT_REMOVE) { 13786 if (n != 1 || in->args.vc.pattern->type != 13787 RTE_FLOW_ITEM_TYPE_IPV6_EXT) { 13788 fprintf(stderr, "Error - Not supported item\n"); 13789 return; 13790 } 13791 type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; 13792 item = in->args.vc.pattern; 13793 ipv6_ext = item->spec; 13794 *type = ipv6_ext->next_hdr; 13795 return; 13796 } 13797 13798 total_size = &ipv6_ext_push_confs[idx].size; 13799 data = (uint8_t *)&ipv6_ext_push_confs[idx].data; 13800 type = (uint8_t *)&ipv6_ext_push_confs[idx].type; 13801 13802 *total_size = 0; 13803 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13804 for (i = n - 1 ; i >= 0; --i) { 13805 item = in->args.vc.pattern + i; 13806 switch (item->type) { 13807 case RTE_FLOW_ITEM_TYPE_IPV6_EXT: 13808 ipv6_ext = item->spec; 13809 *type = ipv6_ext->next_hdr; 13810 break; 13811 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13812 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13813 if (!ext->hdr.hdr_len) { 13814 size = sizeof(struct rte_ipv6_routing_ext) + 13815 (ext->hdr.segments_left << 4); 13816 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13817 /* Indicate no TLV once SRH. */ 13818 if (ext->hdr.type == 4) 13819 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13820 } else { 13821 size = sizeof(struct rte_ipv6_routing_ext) + 13822 (ext->hdr.hdr_len << 3); 13823 } 13824 *total_size += size; 13825 memcpy(data, ext, size); 13826 break; 13827 default: 13828 fprintf(stderr, "Error - Not supported item\n"); 13829 goto error; 13830 } 13831 } 13832 RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); 13833 return; 13834 error: 13835 *total_size = 0; 13836 memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); 13837 } 13838 13839 /** Dispatch parsed buffer to function calls. */ 13840 static void 13841 cmd_set_raw_parsed_sample(const struct buffer *in) 13842 { 13843 uint32_t n = in->args.vc.actions_n; 13844 uint32_t i = 0; 13845 struct rte_flow_action *action = NULL; 13846 struct rte_flow_action *data = NULL; 13847 const struct rte_flow_action_rss *rss = NULL; 13848 size_t size = 0; 13849 uint16_t idx = in->port; /* We borrow port field as index */ 13850 uint32_t max_size = sizeof(struct rte_flow_action) * 13851 ACTION_SAMPLE_ACTIONS_NUM; 13852 13853 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 13854 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 13855 memset(data, 0x00, max_size); 13856 for (; i <= n - 1; i++) { 13857 action = in->args.vc.actions + i; 13858 if (action->type == RTE_FLOW_ACTION_TYPE_END) 13859 break; 13860 switch (action->type) { 13861 case RTE_FLOW_ACTION_TYPE_MARK: 13862 size = sizeof(struct rte_flow_action_mark); 13863 rte_memcpy(&sample_mark[idx], 13864 (const void *)action->conf, size); 13865 action->conf = &sample_mark[idx]; 13866 break; 13867 case RTE_FLOW_ACTION_TYPE_COUNT: 13868 size = sizeof(struct rte_flow_action_count); 13869 rte_memcpy(&sample_count[idx], 13870 (const void *)action->conf, size); 13871 action->conf = &sample_count[idx]; 13872 break; 13873 case RTE_FLOW_ACTION_TYPE_QUEUE: 13874 size = sizeof(struct rte_flow_action_queue); 13875 rte_memcpy(&sample_queue[idx], 13876 (const void *)action->conf, size); 13877 action->conf = &sample_queue[idx]; 13878 break; 13879 case RTE_FLOW_ACTION_TYPE_RSS: 13880 size = sizeof(struct rte_flow_action_rss); 13881 rss = action->conf; 13882 rte_memcpy(&sample_rss_data[idx].conf, 13883 (const void *)rss, size); 13884 if (rss->key_len && rss->key) { 13885 sample_rss_data[idx].conf.key = 13886 sample_rss_data[idx].key; 13887 rte_memcpy((void *)((uintptr_t) 13888 sample_rss_data[idx].conf.key), 13889 (const void *)rss->key, 13890 sizeof(uint8_t) * rss->key_len); 13891 } 13892 if (rss->queue_num && rss->queue) { 13893 sample_rss_data[idx].conf.queue = 13894 sample_rss_data[idx].queue; 13895 rte_memcpy((void *)((uintptr_t) 13896 sample_rss_data[idx].conf.queue), 13897 (const void *)rss->queue, 13898 sizeof(uint16_t) * rss->queue_num); 13899 } 13900 action->conf = &sample_rss_data[idx].conf; 13901 break; 13902 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 13903 size = sizeof(struct rte_flow_action_raw_encap); 13904 rte_memcpy(&sample_encap[idx], 13905 (const void *)action->conf, size); 13906 action->conf = &sample_encap[idx]; 13907 break; 13908 case RTE_FLOW_ACTION_TYPE_PORT_ID: 13909 size = sizeof(struct rte_flow_action_port_id); 13910 rte_memcpy(&sample_port_id[idx], 13911 (const void *)action->conf, size); 13912 action->conf = &sample_port_id[idx]; 13913 break; 13914 case RTE_FLOW_ACTION_TYPE_PF: 13915 break; 13916 case RTE_FLOW_ACTION_TYPE_VF: 13917 size = sizeof(struct rte_flow_action_vf); 13918 rte_memcpy(&sample_vf[idx], 13919 (const void *)action->conf, size); 13920 action->conf = &sample_vf[idx]; 13921 break; 13922 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 13923 size = sizeof(struct rte_flow_action_vxlan_encap); 13924 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 13925 action->conf = &sample_vxlan_encap[idx].conf; 13926 break; 13927 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 13928 size = sizeof(struct rte_flow_action_nvgre_encap); 13929 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 13930 action->conf = &sample_nvgre_encap[idx]; 13931 break; 13932 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 13933 size = sizeof(struct rte_flow_action_ethdev); 13934 rte_memcpy(&sample_port_representor[idx], 13935 (const void *)action->conf, size); 13936 action->conf = &sample_port_representor[idx]; 13937 break; 13938 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 13939 size = sizeof(struct rte_flow_action_ethdev); 13940 rte_memcpy(&sample_represented_port[idx], 13941 (const void *)action->conf, size); 13942 action->conf = &sample_represented_port[idx]; 13943 break; 13944 default: 13945 fprintf(stderr, "Error - Not supported action\n"); 13946 return; 13947 } 13948 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 13949 data++; 13950 } 13951 } 13952 13953 /** Dispatch parsed buffer to function calls. */ 13954 static void 13955 cmd_set_raw_parsed(const struct buffer *in) 13956 { 13957 uint32_t n = in->args.vc.pattern_n; 13958 int i = 0; 13959 struct rte_flow_item *item = NULL; 13960 size_t size = 0; 13961 uint8_t *data = NULL; 13962 uint8_t *data_tail = NULL; 13963 size_t *total_size = NULL; 13964 uint16_t upper_layer = 0; 13965 uint16_t proto = 0; 13966 uint16_t idx = in->port; /* We borrow port field as index */ 13967 int gtp_psc = -1; /* GTP PSC option index. */ 13968 const void *src_spec; 13969 13970 if (in->command == SET_SAMPLE_ACTIONS) 13971 return cmd_set_raw_parsed_sample(in); 13972 else if (in->command == SET_IPV6_EXT_PUSH || 13973 in->command == SET_IPV6_EXT_REMOVE) 13974 return cmd_set_ipv6_ext_parsed(in); 13975 RTE_ASSERT(in->command == SET_RAW_ENCAP || 13976 in->command == SET_RAW_DECAP); 13977 if (in->command == SET_RAW_ENCAP) { 13978 total_size = &raw_encap_confs[idx].size; 13979 data = (uint8_t *)&raw_encap_confs[idx].data; 13980 } else { 13981 total_size = &raw_decap_confs[idx].size; 13982 data = (uint8_t *)&raw_decap_confs[idx].data; 13983 } 13984 *total_size = 0; 13985 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13986 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 13987 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 13988 for (i = n - 1 ; i >= 0; --i) { 13989 const struct rte_flow_item_gtp *gtp; 13990 const struct rte_flow_item_geneve_opt *opt; 13991 struct rte_flow_item_ipv6_routing_ext *ext; 13992 13993 item = in->args.vc.pattern + i; 13994 if (item->spec == NULL) 13995 item->spec = flow_item_default_mask(item); 13996 src_spec = item->spec; 13997 switch (item->type) { 13998 case RTE_FLOW_ITEM_TYPE_ETH: 13999 size = sizeof(struct rte_ether_hdr); 14000 break; 14001 case RTE_FLOW_ITEM_TYPE_VLAN: 14002 size = sizeof(struct rte_vlan_hdr); 14003 proto = RTE_ETHER_TYPE_VLAN; 14004 break; 14005 case RTE_FLOW_ITEM_TYPE_IPV4: 14006 size = sizeof(struct rte_ipv4_hdr); 14007 proto = RTE_ETHER_TYPE_IPV4; 14008 break; 14009 case RTE_FLOW_ITEM_TYPE_IPV6: 14010 size = sizeof(struct rte_ipv6_hdr); 14011 proto = RTE_ETHER_TYPE_IPV6; 14012 break; 14013 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 14014 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 14015 if (!ext->hdr.hdr_len) { 14016 size = sizeof(struct rte_ipv6_routing_ext) + 14017 (ext->hdr.segments_left << 4); 14018 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 14019 /* SRv6 without TLV. */ 14020 if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) 14021 ext->hdr.last_entry = ext->hdr.segments_left - 1; 14022 } else { 14023 size = sizeof(struct rte_ipv6_routing_ext) + 14024 (ext->hdr.hdr_len << 3); 14025 } 14026 proto = IPPROTO_ROUTING; 14027 break; 14028 case RTE_FLOW_ITEM_TYPE_UDP: 14029 size = sizeof(struct rte_udp_hdr); 14030 proto = 0x11; 14031 break; 14032 case RTE_FLOW_ITEM_TYPE_TCP: 14033 size = sizeof(struct rte_tcp_hdr); 14034 proto = 0x06; 14035 break; 14036 case RTE_FLOW_ITEM_TYPE_VXLAN: 14037 size = sizeof(struct rte_vxlan_hdr); 14038 break; 14039 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 14040 size = sizeof(struct rte_vxlan_gpe_hdr); 14041 break; 14042 case RTE_FLOW_ITEM_TYPE_GRE: 14043 size = sizeof(struct rte_gre_hdr); 14044 proto = 0x2F; 14045 break; 14046 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 14047 size = sizeof(rte_be32_t); 14048 proto = 0x0; 14049 break; 14050 case RTE_FLOW_ITEM_TYPE_MPLS: 14051 size = sizeof(struct rte_mpls_hdr); 14052 proto = 0x0; 14053 break; 14054 case RTE_FLOW_ITEM_TYPE_NVGRE: 14055 size = sizeof(struct rte_flow_item_nvgre); 14056 proto = 0x2F; 14057 break; 14058 case RTE_FLOW_ITEM_TYPE_GENEVE: 14059 size = sizeof(struct rte_geneve_hdr); 14060 break; 14061 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 14062 opt = (const struct rte_flow_item_geneve_opt *) 14063 item->spec; 14064 size = offsetof(struct rte_flow_item_geneve_opt, 14065 option_len) + sizeof(uint8_t); 14066 if (opt->option_len && opt->data) { 14067 *total_size += opt->option_len * 14068 sizeof(uint32_t); 14069 rte_memcpy(data_tail - (*total_size), 14070 opt->data, 14071 opt->option_len * sizeof(uint32_t)); 14072 } 14073 break; 14074 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 14075 size = sizeof(rte_be32_t); 14076 proto = 0x73; 14077 break; 14078 case RTE_FLOW_ITEM_TYPE_ESP: 14079 size = sizeof(struct rte_esp_hdr); 14080 proto = 0x32; 14081 break; 14082 case RTE_FLOW_ITEM_TYPE_AH: 14083 size = sizeof(struct rte_flow_item_ah); 14084 proto = 0x33; 14085 break; 14086 case RTE_FLOW_ITEM_TYPE_GTP: 14087 if (gtp_psc < 0) { 14088 size = sizeof(struct rte_gtp_hdr); 14089 break; 14090 } 14091 if (gtp_psc != i + 1) { 14092 fprintf(stderr, 14093 "Error - GTP PSC does not follow GTP\n"); 14094 goto error; 14095 } 14096 gtp = item->spec; 14097 if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { 14098 /* Only E flag should be set. */ 14099 fprintf(stderr, 14100 "Error - GTP unsupported flags\n"); 14101 goto error; 14102 } else { 14103 struct rte_gtp_hdr_ext_word ext_word = { 14104 .next_ext = 0x85 14105 }; 14106 14107 /* We have to add GTP header extra word. */ 14108 *total_size += sizeof(ext_word); 14109 rte_memcpy(data_tail - (*total_size), 14110 &ext_word, sizeof(ext_word)); 14111 } 14112 size = sizeof(struct rte_gtp_hdr); 14113 break; 14114 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 14115 if (gtp_psc >= 0) { 14116 fprintf(stderr, 14117 "Error - Multiple GTP PSC items\n"); 14118 goto error; 14119 } else { 14120 const struct rte_flow_item_gtp_psc 14121 *opt = item->spec; 14122 struct rte_gtp_psc_generic_hdr *hdr; 14123 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 14124 sizeof(int32_t)); 14125 14126 *total_size += hdr_size; 14127 hdr = (typeof(hdr))(data_tail - (*total_size)); 14128 memset(hdr, 0, hdr_size); 14129 *hdr = opt->hdr; 14130 hdr->ext_hdr_len = 1; 14131 gtp_psc = i; 14132 size = 0; 14133 } 14134 break; 14135 case RTE_FLOW_ITEM_TYPE_PFCP: 14136 size = sizeof(struct rte_flow_item_pfcp); 14137 break; 14138 case RTE_FLOW_ITEM_TYPE_FLEX: 14139 if (item->spec != NULL) { 14140 size = ((const struct rte_flow_item_flex *)item->spec)->length; 14141 src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; 14142 } else { 14143 size = 0; 14144 src_spec = NULL; 14145 } 14146 break; 14147 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 14148 size = 0; 14149 if (item->spec) { 14150 const struct rte_flow_item_gre_opt 14151 *opt = item->spec; 14152 if (opt->checksum_rsvd.checksum) { 14153 *total_size += 14154 sizeof(opt->checksum_rsvd); 14155 rte_memcpy(data_tail - (*total_size), 14156 &opt->checksum_rsvd, 14157 sizeof(opt->checksum_rsvd)); 14158 } 14159 if (opt->key.key) { 14160 *total_size += sizeof(opt->key.key); 14161 rte_memcpy(data_tail - (*total_size), 14162 &opt->key.key, 14163 sizeof(opt->key.key)); 14164 } 14165 if (opt->sequence.sequence) { 14166 *total_size += sizeof(opt->sequence.sequence); 14167 rte_memcpy(data_tail - (*total_size), 14168 &opt->sequence.sequence, 14169 sizeof(opt->sequence.sequence)); 14170 } 14171 } 14172 proto = 0x2F; 14173 break; 14174 default: 14175 fprintf(stderr, "Error - Not supported item\n"); 14176 goto error; 14177 } 14178 if (size) { 14179 *total_size += size; 14180 rte_memcpy(data_tail - (*total_size), src_spec, size); 14181 /* update some fields which cannot be set by cmdline */ 14182 update_fields((data_tail - (*total_size)), item, 14183 upper_layer); 14184 upper_layer = proto; 14185 } 14186 } 14187 if (verbose_level & 0x1) 14188 printf("total data size is %zu\n", (*total_size)); 14189 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 14190 memmove(data, (data_tail - (*total_size)), *total_size); 14191 return; 14192 14193 error: 14194 *total_size = 0; 14195 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 14196 } 14197 14198 /** Populate help strings for current token (cmdline API). */ 14199 static int 14200 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 14201 unsigned int size) 14202 { 14203 struct context *ctx = &cmd_flow_context; 14204 const struct token *token = &token_list[ctx->prev]; 14205 14206 (void)hdr; 14207 if (!size) 14208 return -1; 14209 /* Set token type and update global help with details. */ 14210 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 14211 if (token->help) 14212 cmd_set_raw.help_str = token->help; 14213 else 14214 cmd_set_raw.help_str = token->name; 14215 return 0; 14216 } 14217 14218 /** Token definition template (cmdline API). */ 14219 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 14220 .ops = &(struct cmdline_token_ops){ 14221 .parse = cmd_flow_parse, 14222 .complete_get_nb = cmd_flow_complete_get_nb, 14223 .complete_get_elt = cmd_flow_complete_get_elt, 14224 .get_help = cmd_set_raw_get_help, 14225 }, 14226 .offset = 0, 14227 }; 14228 14229 /** Populate the next dynamic token. */ 14230 static void 14231 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 14232 cmdline_parse_token_hdr_t **hdr_inst) 14233 { 14234 struct context *ctx = &cmd_flow_context; 14235 14236 /* Always reinitialize context before requesting the first token. */ 14237 if (!(hdr_inst - cmd_set_raw.tokens)) { 14238 cmd_flow_context_init(ctx); 14239 ctx->curr = START_SET; 14240 } 14241 /* Return NULL when no more tokens are expected. */ 14242 if (!ctx->next_num && (ctx->curr != START_SET)) { 14243 *hdr = NULL; 14244 return; 14245 } 14246 /* Determine if command should end here. */ 14247 if (ctx->eol && ctx->last && ctx->next_num) { 14248 const enum index *list = ctx->next[ctx->next_num - 1]; 14249 int i; 14250 14251 for (i = 0; list[i]; ++i) { 14252 if (list[i] != END) 14253 continue; 14254 *hdr = NULL; 14255 return; 14256 } 14257 } 14258 *hdr = &cmd_set_raw_token_hdr; 14259 } 14260 14261 /** Token generator and output processing callback (cmdline API). */ 14262 static void 14263 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 14264 { 14265 if (cl == NULL) 14266 cmd_set_raw_tok(arg0, arg2); 14267 else 14268 cmd_set_raw_parsed(arg0); 14269 } 14270 14271 /** Global parser instance (cmdline API). */ 14272 cmdline_parse_inst_t cmd_set_raw = { 14273 .f = cmd_set_raw_cb, 14274 .data = NULL, /**< Unused. */ 14275 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 14276 .tokens = { 14277 NULL, 14278 }, /**< Tokens are returned by cmd_flow_tok(). */ 14279 }; 14280 14281 /* *** display raw_encap/raw_decap buf */ 14282 struct cmd_show_set_raw_result { 14283 cmdline_fixed_string_t cmd_show; 14284 cmdline_fixed_string_t cmd_what; 14285 cmdline_fixed_string_t cmd_all; 14286 uint16_t cmd_index; 14287 }; 14288 14289 static void 14290 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 14291 { 14292 struct cmd_show_set_raw_result *res = parsed_result; 14293 uint16_t index = res->cmd_index; 14294 uint8_t all = 0; 14295 uint8_t *raw_data = NULL; 14296 size_t raw_size = 0; 14297 char title[16] = {0}; 14298 14299 RTE_SET_USED(cl); 14300 RTE_SET_USED(data); 14301 if (!strcmp(res->cmd_all, "all")) { 14302 all = 1; 14303 index = 0; 14304 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 14305 fprintf(stderr, "index should be 0-%u\n", 14306 RAW_ENCAP_CONFS_MAX_NUM - 1); 14307 return; 14308 } 14309 do { 14310 if (!strcmp(res->cmd_what, "raw_encap")) { 14311 raw_data = (uint8_t *)&raw_encap_confs[index].data; 14312 raw_size = raw_encap_confs[index].size; 14313 snprintf(title, 16, "\nindex: %u", index); 14314 rte_hexdump(stdout, title, raw_data, raw_size); 14315 } else { 14316 raw_data = (uint8_t *)&raw_decap_confs[index].data; 14317 raw_size = raw_decap_confs[index].size; 14318 snprintf(title, 16, "\nindex: %u", index); 14319 rte_hexdump(stdout, title, raw_data, raw_size); 14320 } 14321 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 14322 } 14323 14324 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 14325 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14326 cmd_show, "show"); 14327 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 14328 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14329 cmd_what, "raw_encap#raw_decap"); 14330 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 14331 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 14332 cmd_index, RTE_UINT16); 14333 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 14334 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14335 cmd_all, "all"); 14336 cmdline_parse_inst_t cmd_show_set_raw = { 14337 .f = cmd_show_set_raw_parsed, 14338 .data = NULL, 14339 .help_str = "show <raw_encap|raw_decap> <index>", 14340 .tokens = { 14341 (void *)&cmd_show_set_raw_cmd_show, 14342 (void *)&cmd_show_set_raw_cmd_what, 14343 (void *)&cmd_show_set_raw_cmd_index, 14344 NULL, 14345 }, 14346 }; 14347 cmdline_parse_inst_t cmd_show_set_raw_all = { 14348 .f = cmd_show_set_raw_parsed, 14349 .data = NULL, 14350 .help_str = "show <raw_encap|raw_decap> all", 14351 .tokens = { 14352 (void *)&cmd_show_set_raw_cmd_show, 14353 (void *)&cmd_show_set_raw_cmd_what, 14354 (void *)&cmd_show_set_raw_cmd_all, 14355 NULL, 14356 }, 14357 }; 14358