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 ITEM_VXLAN_GPE_PROTO, 395 ITEM_VXLAN_FIRST_RSVD, 396 ITEM_VXLAN_SECND_RSVD, 397 ITEM_VXLAN_THIRD_RSVD, 398 ITEM_VXLAN_LAST_RSVD, 399 ITEM_E_TAG, 400 ITEM_E_TAG_GRP_ECID_B, 401 ITEM_NVGRE, 402 ITEM_NVGRE_TNI, 403 ITEM_MPLS, 404 ITEM_MPLS_LABEL, 405 ITEM_MPLS_TC, 406 ITEM_MPLS_S, 407 ITEM_MPLS_TTL, 408 ITEM_GRE, 409 ITEM_GRE_PROTO, 410 ITEM_GRE_C_RSVD0_VER, 411 ITEM_GRE_C_BIT, 412 ITEM_GRE_K_BIT, 413 ITEM_GRE_S_BIT, 414 ITEM_FUZZY, 415 ITEM_FUZZY_THRESH, 416 ITEM_GTP, 417 ITEM_GTP_FLAGS, 418 ITEM_GTP_MSG_TYPE, 419 ITEM_GTP_TEID, 420 ITEM_GTPC, 421 ITEM_GTPU, 422 ITEM_GENEVE, 423 ITEM_GENEVE_VNI, 424 ITEM_GENEVE_PROTO, 425 ITEM_GENEVE_OPTLEN, 426 ITEM_ARP_ETH_IPV4, 427 ITEM_ARP_ETH_IPV4_SHA, 428 ITEM_ARP_ETH_IPV4_SPA, 429 ITEM_ARP_ETH_IPV4_THA, 430 ITEM_ARP_ETH_IPV4_TPA, 431 ITEM_IPV6_EXT, 432 ITEM_IPV6_EXT_NEXT_HDR, 433 ITEM_IPV6_FRAG_EXT, 434 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 435 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 436 ITEM_IPV6_FRAG_EXT_ID, 437 ITEM_ICMP6, 438 ITEM_ICMP6_TYPE, 439 ITEM_ICMP6_CODE, 440 ITEM_ICMP6_ECHO_REQUEST, 441 ITEM_ICMP6_ECHO_REQUEST_ID, 442 ITEM_ICMP6_ECHO_REQUEST_SEQ, 443 ITEM_ICMP6_ECHO_REPLY, 444 ITEM_ICMP6_ECHO_REPLY_ID, 445 ITEM_ICMP6_ECHO_REPLY_SEQ, 446 ITEM_ICMP6_ND_NS, 447 ITEM_ICMP6_ND_NS_TARGET_ADDR, 448 ITEM_ICMP6_ND_NA, 449 ITEM_ICMP6_ND_NA_TARGET_ADDR, 450 ITEM_ICMP6_ND_OPT, 451 ITEM_ICMP6_ND_OPT_TYPE, 452 ITEM_ICMP6_ND_OPT_SLA_ETH, 453 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 454 ITEM_ICMP6_ND_OPT_TLA_ETH, 455 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 456 ITEM_META, 457 ITEM_META_DATA, 458 ITEM_RANDOM, 459 ITEM_RANDOM_VALUE, 460 ITEM_GRE_KEY, 461 ITEM_GRE_KEY_VALUE, 462 ITEM_GRE_OPTION, 463 ITEM_GRE_OPTION_CHECKSUM, 464 ITEM_GRE_OPTION_KEY, 465 ITEM_GRE_OPTION_SEQUENCE, 466 ITEM_GTP_PSC, 467 ITEM_GTP_PSC_QFI, 468 ITEM_GTP_PSC_PDU_T, 469 ITEM_PPPOES, 470 ITEM_PPPOED, 471 ITEM_PPPOE_SEID, 472 ITEM_PPPOE_PROTO_ID, 473 ITEM_HIGIG2, 474 ITEM_HIGIG2_CLASSIFICATION, 475 ITEM_HIGIG2_VID, 476 ITEM_TAG, 477 ITEM_TAG_DATA, 478 ITEM_TAG_INDEX, 479 ITEM_L2TPV3OIP, 480 ITEM_L2TPV3OIP_SESSION_ID, 481 ITEM_ESP, 482 ITEM_ESP_SPI, 483 ITEM_AH, 484 ITEM_AH_SPI, 485 ITEM_PFCP, 486 ITEM_PFCP_S_FIELD, 487 ITEM_PFCP_SEID, 488 ITEM_ECPRI, 489 ITEM_ECPRI_COMMON, 490 ITEM_ECPRI_COMMON_TYPE, 491 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 492 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 493 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 494 ITEM_ECPRI_MSG_IQ_DATA_PCID, 495 ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 496 ITEM_ECPRI_MSG_DLY_MSR_MSRID, 497 ITEM_GENEVE_OPT, 498 ITEM_GENEVE_OPT_CLASS, 499 ITEM_GENEVE_OPT_TYPE, 500 ITEM_GENEVE_OPT_LENGTH, 501 ITEM_GENEVE_OPT_DATA, 502 ITEM_INTEGRITY, 503 ITEM_INTEGRITY_LEVEL, 504 ITEM_INTEGRITY_VALUE, 505 ITEM_CONNTRACK, 506 ITEM_POL_PORT, 507 ITEM_POL_METER, 508 ITEM_POL_POLICY, 509 ITEM_PORT_REPRESENTOR, 510 ITEM_PORT_REPRESENTOR_PORT_ID, 511 ITEM_REPRESENTED_PORT, 512 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 513 ITEM_FLEX, 514 ITEM_FLEX_ITEM_HANDLE, 515 ITEM_FLEX_PATTERN_HANDLE, 516 ITEM_L2TPV2, 517 ITEM_L2TPV2_TYPE, 518 ITEM_L2TPV2_TYPE_DATA, 519 ITEM_L2TPV2_TYPE_DATA_L, 520 ITEM_L2TPV2_TYPE_DATA_S, 521 ITEM_L2TPV2_TYPE_DATA_O, 522 ITEM_L2TPV2_TYPE_DATA_L_S, 523 ITEM_L2TPV2_TYPE_CTRL, 524 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 525 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 526 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 527 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 528 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 529 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 530 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 531 ITEM_L2TPV2_MSG_DATA_S_NS, 532 ITEM_L2TPV2_MSG_DATA_S_NR, 533 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 534 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 535 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 536 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 537 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 538 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 539 ITEM_L2TPV2_MSG_DATA_L_S_NS, 540 ITEM_L2TPV2_MSG_DATA_L_S_NR, 541 ITEM_L2TPV2_MSG_CTRL_LENGTH, 542 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 543 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 544 ITEM_L2TPV2_MSG_CTRL_NS, 545 ITEM_L2TPV2_MSG_CTRL_NR, 546 ITEM_PPP, 547 ITEM_PPP_ADDR, 548 ITEM_PPP_CTRL, 549 ITEM_PPP_PROTO_ID, 550 ITEM_METER, 551 ITEM_METER_COLOR, 552 ITEM_METER_COLOR_NAME, 553 ITEM_QUOTA, 554 ITEM_QUOTA_STATE, 555 ITEM_QUOTA_STATE_NAME, 556 ITEM_AGGR_AFFINITY, 557 ITEM_AGGR_AFFINITY_VALUE, 558 ITEM_TX_QUEUE, 559 ITEM_TX_QUEUE_VALUE, 560 ITEM_IB_BTH, 561 ITEM_IB_BTH_OPCODE, 562 ITEM_IB_BTH_PKEY, 563 ITEM_IB_BTH_DST_QPN, 564 ITEM_IB_BTH_PSN, 565 ITEM_IPV6_PUSH_REMOVE_EXT, 566 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 567 ITEM_PTYPE, 568 ITEM_PTYPE_VALUE, 569 ITEM_NSH, 570 ITEM_COMPARE, 571 ITEM_COMPARE_OP, 572 ITEM_COMPARE_OP_VALUE, 573 ITEM_COMPARE_FIELD_A_TYPE, 574 ITEM_COMPARE_FIELD_A_TYPE_VALUE, 575 ITEM_COMPARE_FIELD_A_LEVEL, 576 ITEM_COMPARE_FIELD_A_LEVEL_VALUE, 577 ITEM_COMPARE_FIELD_A_TAG_INDEX, 578 ITEM_COMPARE_FIELD_A_TYPE_ID, 579 ITEM_COMPARE_FIELD_A_CLASS_ID, 580 ITEM_COMPARE_FIELD_A_OFFSET, 581 ITEM_COMPARE_FIELD_B_TYPE, 582 ITEM_COMPARE_FIELD_B_TYPE_VALUE, 583 ITEM_COMPARE_FIELD_B_LEVEL, 584 ITEM_COMPARE_FIELD_B_LEVEL_VALUE, 585 ITEM_COMPARE_FIELD_B_TAG_INDEX, 586 ITEM_COMPARE_FIELD_B_TYPE_ID, 587 ITEM_COMPARE_FIELD_B_CLASS_ID, 588 ITEM_COMPARE_FIELD_B_OFFSET, 589 ITEM_COMPARE_FIELD_B_VALUE, 590 ITEM_COMPARE_FIELD_B_POINTER, 591 ITEM_COMPARE_FIELD_WIDTH, 592 593 /* Validate/create actions. */ 594 ACTIONS, 595 ACTION_NEXT, 596 ACTION_END, 597 ACTION_VOID, 598 ACTION_PASSTHRU, 599 ACTION_SKIP_CMAN, 600 ACTION_JUMP, 601 ACTION_JUMP_GROUP, 602 ACTION_MARK, 603 ACTION_MARK_ID, 604 ACTION_FLAG, 605 ACTION_QUEUE, 606 ACTION_QUEUE_INDEX, 607 ACTION_DROP, 608 ACTION_COUNT, 609 ACTION_COUNT_ID, 610 ACTION_RSS, 611 ACTION_RSS_FUNC, 612 ACTION_RSS_LEVEL, 613 ACTION_RSS_FUNC_DEFAULT, 614 ACTION_RSS_FUNC_TOEPLITZ, 615 ACTION_RSS_FUNC_SIMPLE_XOR, 616 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, 617 ACTION_RSS_TYPES, 618 ACTION_RSS_TYPE, 619 ACTION_RSS_KEY, 620 ACTION_RSS_KEY_LEN, 621 ACTION_RSS_QUEUES, 622 ACTION_RSS_QUEUE, 623 ACTION_PF, 624 ACTION_VF, 625 ACTION_VF_ORIGINAL, 626 ACTION_VF_ID, 627 ACTION_PORT_ID, 628 ACTION_PORT_ID_ORIGINAL, 629 ACTION_PORT_ID_ID, 630 ACTION_METER, 631 ACTION_METER_COLOR, 632 ACTION_METER_COLOR_TYPE, 633 ACTION_METER_COLOR_GREEN, 634 ACTION_METER_COLOR_YELLOW, 635 ACTION_METER_COLOR_RED, 636 ACTION_METER_ID, 637 ACTION_METER_MARK, 638 ACTION_METER_PROFILE, 639 ACTION_METER_PROFILE_ID2PTR, 640 ACTION_METER_POLICY, 641 ACTION_METER_POLICY_ID2PTR, 642 ACTION_METER_COLOR_MODE, 643 ACTION_METER_STATE, 644 ACTION_OF_DEC_NW_TTL, 645 ACTION_OF_POP_VLAN, 646 ACTION_OF_PUSH_VLAN, 647 ACTION_OF_PUSH_VLAN_ETHERTYPE, 648 ACTION_OF_SET_VLAN_VID, 649 ACTION_OF_SET_VLAN_VID_VLAN_VID, 650 ACTION_OF_SET_VLAN_PCP, 651 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 652 ACTION_OF_POP_MPLS, 653 ACTION_OF_POP_MPLS_ETHERTYPE, 654 ACTION_OF_PUSH_MPLS, 655 ACTION_OF_PUSH_MPLS_ETHERTYPE, 656 ACTION_VXLAN_ENCAP, 657 ACTION_VXLAN_DECAP, 658 ACTION_NVGRE_ENCAP, 659 ACTION_NVGRE_DECAP, 660 ACTION_L2_ENCAP, 661 ACTION_L2_DECAP, 662 ACTION_MPLSOGRE_ENCAP, 663 ACTION_MPLSOGRE_DECAP, 664 ACTION_MPLSOUDP_ENCAP, 665 ACTION_MPLSOUDP_DECAP, 666 ACTION_SET_IPV4_SRC, 667 ACTION_SET_IPV4_SRC_IPV4_SRC, 668 ACTION_SET_IPV4_DST, 669 ACTION_SET_IPV4_DST_IPV4_DST, 670 ACTION_SET_IPV6_SRC, 671 ACTION_SET_IPV6_SRC_IPV6_SRC, 672 ACTION_SET_IPV6_DST, 673 ACTION_SET_IPV6_DST_IPV6_DST, 674 ACTION_SET_TP_SRC, 675 ACTION_SET_TP_SRC_TP_SRC, 676 ACTION_SET_TP_DST, 677 ACTION_SET_TP_DST_TP_DST, 678 ACTION_MAC_SWAP, 679 ACTION_DEC_TTL, 680 ACTION_SET_TTL, 681 ACTION_SET_TTL_TTL, 682 ACTION_SET_MAC_SRC, 683 ACTION_SET_MAC_SRC_MAC_SRC, 684 ACTION_SET_MAC_DST, 685 ACTION_SET_MAC_DST_MAC_DST, 686 ACTION_INC_TCP_SEQ, 687 ACTION_INC_TCP_SEQ_VALUE, 688 ACTION_DEC_TCP_SEQ, 689 ACTION_DEC_TCP_SEQ_VALUE, 690 ACTION_INC_TCP_ACK, 691 ACTION_INC_TCP_ACK_VALUE, 692 ACTION_DEC_TCP_ACK, 693 ACTION_DEC_TCP_ACK_VALUE, 694 ACTION_RAW_ENCAP, 695 ACTION_RAW_DECAP, 696 ACTION_RAW_ENCAP_SIZE, 697 ACTION_RAW_ENCAP_INDEX, 698 ACTION_RAW_ENCAP_INDEX_VALUE, 699 ACTION_RAW_DECAP_INDEX, 700 ACTION_RAW_DECAP_INDEX_VALUE, 701 ACTION_SET_TAG, 702 ACTION_SET_TAG_DATA, 703 ACTION_SET_TAG_INDEX, 704 ACTION_SET_TAG_MASK, 705 ACTION_SET_META, 706 ACTION_SET_META_DATA, 707 ACTION_SET_META_MASK, 708 ACTION_SET_IPV4_DSCP, 709 ACTION_SET_IPV4_DSCP_VALUE, 710 ACTION_SET_IPV6_DSCP, 711 ACTION_SET_IPV6_DSCP_VALUE, 712 ACTION_AGE, 713 ACTION_AGE_TIMEOUT, 714 ACTION_AGE_UPDATE, 715 ACTION_AGE_UPDATE_TIMEOUT, 716 ACTION_AGE_UPDATE_TOUCH, 717 ACTION_SAMPLE, 718 ACTION_SAMPLE_RATIO, 719 ACTION_SAMPLE_INDEX, 720 ACTION_SAMPLE_INDEX_VALUE, 721 ACTION_INDIRECT, 722 ACTION_INDIRECT_LIST, 723 ACTION_INDIRECT_LIST_HANDLE, 724 ACTION_INDIRECT_LIST_CONF, 725 INDIRECT_LIST_ACTION_ID2PTR_HANDLE, 726 INDIRECT_LIST_ACTION_ID2PTR_CONF, 727 ACTION_SHARED_INDIRECT, 728 INDIRECT_ACTION_PORT, 729 INDIRECT_ACTION_ID2PTR, 730 ACTION_MODIFY_FIELD, 731 ACTION_MODIFY_FIELD_OP, 732 ACTION_MODIFY_FIELD_OP_VALUE, 733 ACTION_MODIFY_FIELD_DST_TYPE, 734 ACTION_MODIFY_FIELD_DST_TYPE_VALUE, 735 ACTION_MODIFY_FIELD_DST_LEVEL, 736 ACTION_MODIFY_FIELD_DST_LEVEL_VALUE, 737 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 738 ACTION_MODIFY_FIELD_DST_TYPE_ID, 739 ACTION_MODIFY_FIELD_DST_CLASS_ID, 740 ACTION_MODIFY_FIELD_DST_OFFSET, 741 ACTION_MODIFY_FIELD_SRC_TYPE, 742 ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, 743 ACTION_MODIFY_FIELD_SRC_LEVEL, 744 ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE, 745 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 746 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 747 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 748 ACTION_MODIFY_FIELD_SRC_OFFSET, 749 ACTION_MODIFY_FIELD_SRC_VALUE, 750 ACTION_MODIFY_FIELD_SRC_POINTER, 751 ACTION_MODIFY_FIELD_WIDTH, 752 ACTION_CONNTRACK, 753 ACTION_CONNTRACK_UPDATE, 754 ACTION_CONNTRACK_UPDATE_DIR, 755 ACTION_CONNTRACK_UPDATE_CTX, 756 ACTION_POL_G, 757 ACTION_POL_Y, 758 ACTION_POL_R, 759 ACTION_PORT_REPRESENTOR, 760 ACTION_PORT_REPRESENTOR_PORT_ID, 761 ACTION_REPRESENTED_PORT, 762 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 763 ACTION_SEND_TO_KERNEL, 764 ACTION_QUOTA_CREATE, 765 ACTION_QUOTA_CREATE_LIMIT, 766 ACTION_QUOTA_CREATE_MODE, 767 ACTION_QUOTA_CREATE_MODE_NAME, 768 ACTION_QUOTA_QU, 769 ACTION_QUOTA_QU_LIMIT, 770 ACTION_QUOTA_QU_UPDATE_OP, 771 ACTION_QUOTA_QU_UPDATE_OP_NAME, 772 ACTION_IPV6_EXT_REMOVE, 773 ACTION_IPV6_EXT_REMOVE_INDEX, 774 ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, 775 ACTION_IPV6_EXT_PUSH, 776 ACTION_IPV6_EXT_PUSH_INDEX, 777 ACTION_IPV6_EXT_PUSH_INDEX_VALUE, 778 ACTION_NAT64, 779 ACTION_NAT64_MODE, 780 }; 781 782 /** Maximum size for pattern in struct rte_flow_item_raw. */ 783 #define ITEM_RAW_PATTERN_SIZE 512 784 785 /** Maximum size for GENEVE option data pattern in bytes. */ 786 #define ITEM_GENEVE_OPT_DATA_SIZE 124 787 788 /** Storage size for struct rte_flow_item_raw including pattern. */ 789 #define ITEM_RAW_SIZE \ 790 (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) 791 792 static const char *const compare_ops[] = { 793 "eq", "ne", "lt", "le", "gt", "ge", NULL 794 }; 795 796 /** Maximum size for external pattern in struct rte_flow_field_data. */ 797 #define FLOW_FIELD_PATTERN_SIZE 32 798 799 /** Storage size for struct rte_flow_action_modify_field including pattern. */ 800 #define ACTION_MODIFY_SIZE \ 801 (sizeof(struct rte_flow_action_modify_field) + \ 802 FLOW_FIELD_PATTERN_SIZE) 803 804 /** Maximum number of queue indices in struct rte_flow_action_rss. */ 805 #define ACTION_RSS_QUEUE_NUM 128 806 807 /** Storage for struct rte_flow_action_rss including external data. */ 808 struct action_rss_data { 809 struct rte_flow_action_rss conf; 810 uint8_t key[RSS_HASH_KEY_LENGTH]; 811 uint16_t queue[ACTION_RSS_QUEUE_NUM]; 812 }; 813 814 /** Maximum data size in struct rte_flow_action_raw_encap. */ 815 #define ACTION_RAW_ENCAP_MAX_DATA 512 816 #define RAW_ENCAP_CONFS_MAX_NUM 8 817 818 /** Storage for struct rte_flow_action_raw_encap. */ 819 struct raw_encap_conf { 820 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 821 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 822 size_t size; 823 }; 824 825 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 826 827 /** Storage for struct rte_flow_action_raw_encap including external data. */ 828 struct action_raw_encap_data { 829 struct rte_flow_action_raw_encap conf; 830 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 831 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 832 uint16_t idx; 833 }; 834 835 /** Storage for struct rte_flow_action_raw_decap. */ 836 struct raw_decap_conf { 837 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 838 size_t size; 839 }; 840 841 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 842 843 /** Storage for struct rte_flow_action_raw_decap including external data. */ 844 struct action_raw_decap_data { 845 struct rte_flow_action_raw_decap conf; 846 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 847 uint16_t idx; 848 }; 849 850 /** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ 851 #define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 852 #define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 853 854 /** Storage for struct rte_flow_action_ipv6_ext_push. */ 855 struct ipv6_ext_push_conf { 856 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 857 size_t size; 858 uint8_t type; 859 }; 860 861 struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 862 863 /** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ 864 struct action_ipv6_ext_push_data { 865 struct rte_flow_action_ipv6_ext_push conf; 866 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 867 uint8_t type; 868 uint16_t idx; 869 }; 870 871 /** Storage for struct rte_flow_action_ipv6_ext_remove. */ 872 struct ipv6_ext_remove_conf { 873 struct rte_flow_action_ipv6_ext_remove conf; 874 uint8_t type; 875 }; 876 877 struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 878 879 /** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ 880 struct action_ipv6_ext_remove_data { 881 struct rte_flow_action_ipv6_ext_remove conf; 882 uint8_t type; 883 uint16_t idx; 884 }; 885 886 struct vxlan_encap_conf vxlan_encap_conf = { 887 .select_ipv4 = 1, 888 .select_vlan = 0, 889 .select_tos_ttl = 0, 890 .vni = "\x00\x00\x00", 891 .udp_src = 0, 892 .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), 893 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 894 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 895 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 896 "\x00\x00\x00\x00\x00\x00\x00\x01", 897 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 898 "\x00\x00\x00\x00\x00\x00\x11\x11", 899 .vlan_tci = 0, 900 .ip_tos = 0, 901 .ip_ttl = 255, 902 .eth_src = "\x00\x00\x00\x00\x00\x00", 903 .eth_dst = "\xff\xff\xff\xff\xff\xff", 904 }; 905 906 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */ 907 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6 908 909 /** Storage for struct rte_flow_action_vxlan_encap including external data. */ 910 struct action_vxlan_encap_data { 911 struct rte_flow_action_vxlan_encap conf; 912 struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; 913 struct rte_flow_item_eth item_eth; 914 struct rte_flow_item_vlan item_vlan; 915 union { 916 struct rte_flow_item_ipv4 item_ipv4; 917 struct rte_flow_item_ipv6 item_ipv6; 918 }; 919 struct rte_flow_item_udp item_udp; 920 struct rte_flow_item_vxlan item_vxlan; 921 }; 922 923 struct nvgre_encap_conf nvgre_encap_conf = { 924 .select_ipv4 = 1, 925 .select_vlan = 0, 926 .tni = "\x00\x00\x00", 927 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 928 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 929 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 930 "\x00\x00\x00\x00\x00\x00\x00\x01", 931 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 932 "\x00\x00\x00\x00\x00\x00\x11\x11", 933 .vlan_tci = 0, 934 .eth_src = "\x00\x00\x00\x00\x00\x00", 935 .eth_dst = "\xff\xff\xff\xff\xff\xff", 936 }; 937 938 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */ 939 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 940 941 /** Storage for struct rte_flow_action_nvgre_encap including external data. */ 942 struct action_nvgre_encap_data { 943 struct rte_flow_action_nvgre_encap conf; 944 struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; 945 struct rte_flow_item_eth item_eth; 946 struct rte_flow_item_vlan item_vlan; 947 union { 948 struct rte_flow_item_ipv4 item_ipv4; 949 struct rte_flow_item_ipv6 item_ipv6; 950 }; 951 struct rte_flow_item_nvgre item_nvgre; 952 }; 953 954 struct l2_encap_conf l2_encap_conf; 955 956 struct l2_decap_conf l2_decap_conf; 957 958 struct mplsogre_encap_conf mplsogre_encap_conf; 959 960 struct mplsogre_decap_conf mplsogre_decap_conf; 961 962 struct mplsoudp_encap_conf mplsoudp_encap_conf; 963 964 struct mplsoudp_decap_conf mplsoudp_decap_conf; 965 966 struct rte_flow_action_conntrack conntrack_context; 967 968 #define ACTION_SAMPLE_ACTIONS_NUM 10 969 #define RAW_SAMPLE_CONFS_MAX_NUM 8 970 /** Storage for struct rte_flow_action_sample including external data. */ 971 struct action_sample_data { 972 struct rte_flow_action_sample conf; 973 uint32_t idx; 974 }; 975 /** Storage for struct rte_flow_action_sample. */ 976 struct raw_sample_conf { 977 struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; 978 }; 979 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; 980 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; 981 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; 982 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; 983 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; 984 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 985 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 986 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 987 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; 988 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; 989 struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; 990 struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; 991 992 static const char *const modify_field_ops[] = { 993 "set", "add", "sub", NULL 994 }; 995 996 static const char *const flow_field_ids[] = { 997 "start", "mac_dst", "mac_src", 998 "vlan_type", "vlan_id", "mac_type", 999 "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", 1000 "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", 1001 "tcp_port_src", "tcp_port_dst", 1002 "tcp_seq_num", "tcp_ack_num", "tcp_flags", 1003 "udp_port_src", "udp_port_dst", 1004 "vxlan_vni", "geneve_vni", "gtp_teid", 1005 "tag", "mark", "meta", "pointer", "value", 1006 "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", 1007 "ipv6_proto", 1008 "flex_item", 1009 "hash_result", 1010 "geneve_opt_type", "geneve_opt_class", "geneve_opt_data", "mpls", 1011 "tcp_data_off", "ipv4_ihl", "ipv4_total_len", "ipv6_payload_len", 1012 "ipv4_proto", 1013 "ipv6_flow_label", "ipv6_traffic_class", 1014 "esp_spi", "esp_seq_num", "esp_proto", 1015 "random", 1016 "vxlan_last_rsvd", 1017 NULL 1018 }; 1019 1020 static const char *const meter_colors[] = { 1021 "green", "yellow", "red", "all", NULL 1022 }; 1023 1024 static const char *const table_insertion_types[] = { 1025 "pattern", "index", NULL 1026 }; 1027 1028 static const char *const table_hash_funcs[] = { 1029 "default", "linear", "crc32", "crc16", NULL 1030 }; 1031 1032 #define RAW_IPSEC_CONFS_MAX_NUM 8 1033 1034 /** Maximum number of subsequent tokens and arguments on the stack. */ 1035 #define CTX_STACK_SIZE 16 1036 1037 /** Parser context. */ 1038 struct context { 1039 /** Stack of subsequent token lists to process. */ 1040 const enum index *next[CTX_STACK_SIZE]; 1041 /** Arguments for stacked tokens. */ 1042 const void *args[CTX_STACK_SIZE]; 1043 enum index curr; /**< Current token index. */ 1044 enum index prev; /**< Index of the last token seen. */ 1045 int next_num; /**< Number of entries in next[]. */ 1046 int args_num; /**< Number of entries in args[]. */ 1047 uint32_t eol:1; /**< EOL has been detected. */ 1048 uint32_t last:1; /**< No more arguments. */ 1049 portid_t port; /**< Current port ID (for completions). */ 1050 uint32_t objdata; /**< Object-specific data. */ 1051 void *object; /**< Address of current object for relative offsets. */ 1052 void *objmask; /**< Object a full mask must be written to. */ 1053 }; 1054 1055 /** Token argument. */ 1056 struct arg { 1057 uint32_t hton:1; /**< Use network byte ordering. */ 1058 uint32_t sign:1; /**< Value is signed. */ 1059 uint32_t bounded:1; /**< Value is bounded. */ 1060 uintmax_t min; /**< Minimum value if bounded. */ 1061 uintmax_t max; /**< Maximum value if bounded. */ 1062 uint32_t offset; /**< Relative offset from ctx->object. */ 1063 uint32_t size; /**< Field size. */ 1064 const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ 1065 }; 1066 1067 /** Parser token definition. */ 1068 struct token { 1069 /** Type displayed during completion (defaults to "TOKEN"). */ 1070 const char *type; 1071 /** Help displayed during completion (defaults to token name). */ 1072 const char *help; 1073 /** Private data used by parser functions. */ 1074 const void *priv; 1075 /** 1076 * Lists of subsequent tokens to push on the stack. Each call to the 1077 * parser consumes the last entry of that stack. 1078 */ 1079 const enum index *const *next; 1080 /** Arguments stack for subsequent tokens that need them. */ 1081 const struct arg *const *args; 1082 /** 1083 * Token-processing callback, returns -1 in case of error, the 1084 * length of the matched string otherwise. If NULL, attempts to 1085 * match the token name. 1086 * 1087 * If buf is not NULL, the result should be stored in it according 1088 * to context. An error is returned if not large enough. 1089 */ 1090 int (*call)(struct context *ctx, const struct token *token, 1091 const char *str, unsigned int len, 1092 void *buf, unsigned int size); 1093 /** 1094 * Callback that provides possible values for this token, used for 1095 * completion. Returns -1 in case of error, the number of possible 1096 * values otherwise. If NULL, the token name is used. 1097 * 1098 * If buf is not NULL, entry index ent is written to buf and the 1099 * full length of the entry is returned (same behavior as 1100 * snprintf()). 1101 */ 1102 int (*comp)(struct context *ctx, const struct token *token, 1103 unsigned int ent, char *buf, unsigned int size); 1104 /** Mandatory token name, no default value. */ 1105 const char *name; 1106 }; 1107 1108 /** Static initializer for the next field. */ 1109 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } 1110 1111 /** Static initializer for a NEXT() entry. */ 1112 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } 1113 1114 /** Static initializer for the args field. */ 1115 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } 1116 1117 /** Static initializer for ARGS() to target a field. */ 1118 #define ARGS_ENTRY(s, f) \ 1119 (&(const struct arg){ \ 1120 .offset = offsetof(s, f), \ 1121 .size = sizeof(((s *)0)->f), \ 1122 }) 1123 1124 /** Static initializer for ARGS() to target a bit-field. */ 1125 #define ARGS_ENTRY_BF(s, f, b) \ 1126 (&(const struct arg){ \ 1127 .size = sizeof(s), \ 1128 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ 1129 }) 1130 1131 /** Static initializer for ARGS() to target a field with limits. */ 1132 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \ 1133 (&(const struct arg){ \ 1134 .bounded = 1, \ 1135 .min = (i), \ 1136 .max = (a), \ 1137 .offset = offsetof(s, f), \ 1138 .size = sizeof(((s *)0)->f), \ 1139 }) 1140 1141 /** Static initializer for ARGS() to target an arbitrary bit-mask. */ 1142 #define ARGS_ENTRY_MASK(s, f, m) \ 1143 (&(const struct arg){ \ 1144 .offset = offsetof(s, f), \ 1145 .size = sizeof(((s *)0)->f), \ 1146 .mask = (const void *)(m), \ 1147 }) 1148 1149 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ 1150 #define ARGS_ENTRY_MASK_HTON(s, f, m) \ 1151 (&(const struct arg){ \ 1152 .hton = 1, \ 1153 .offset = offsetof(s, f), \ 1154 .size = sizeof(((s *)0)->f), \ 1155 .mask = (const void *)(m), \ 1156 }) 1157 1158 /** Static initializer for ARGS() to target a pointer. */ 1159 #define ARGS_ENTRY_PTR(s, f) \ 1160 (&(const struct arg){ \ 1161 .size = sizeof(*((s *)0)->f), \ 1162 }) 1163 1164 /** Static initializer for ARGS() with arbitrary offset and size. */ 1165 #define ARGS_ENTRY_ARB(o, s) \ 1166 (&(const struct arg){ \ 1167 .offset = (o), \ 1168 .size = (s), \ 1169 }) 1170 1171 /** Same as ARGS_ENTRY_ARB() with bounded values. */ 1172 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ 1173 (&(const struct arg){ \ 1174 .bounded = 1, \ 1175 .min = (i), \ 1176 .max = (a), \ 1177 .offset = (o), \ 1178 .size = (s), \ 1179 }) 1180 1181 /** Same as ARGS_ENTRY() using network byte ordering. */ 1182 #define ARGS_ENTRY_HTON(s, f) \ 1183 (&(const struct arg){ \ 1184 .hton = 1, \ 1185 .offset = offsetof(s, f), \ 1186 .size = sizeof(((s *)0)->f), \ 1187 }) 1188 1189 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ 1190 #define ARG_ENTRY_HTON(s) \ 1191 (&(const struct arg){ \ 1192 .hton = 1, \ 1193 .offset = 0, \ 1194 .size = sizeof(s), \ 1195 }) 1196 1197 /** Parser output buffer layout expected by cmd_flow_parsed(). */ 1198 struct buffer { 1199 enum index command; /**< Flow command. */ 1200 portid_t port; /**< Affected port ID. */ 1201 queueid_t queue; /** Async queue ID. */ 1202 bool postpone; /** Postpone async operation */ 1203 union { 1204 struct { 1205 struct rte_flow_port_attr port_attr; 1206 uint32_t nb_queue; 1207 struct rte_flow_queue_attr queue_attr; 1208 } configure; /**< Configuration arguments. */ 1209 struct { 1210 uint32_t *template_id; 1211 uint32_t template_id_n; 1212 } templ_destroy; /**< Template destroy arguments. */ 1213 struct { 1214 uint32_t id; 1215 struct rte_flow_template_table_attr attr; 1216 uint32_t *pat_templ_id; 1217 uint32_t pat_templ_id_n; 1218 uint32_t *act_templ_id; 1219 uint32_t act_templ_id_n; 1220 } table; /**< Table arguments. */ 1221 struct { 1222 uint32_t *table_id; 1223 uint32_t table_id_n; 1224 } table_destroy; /**< Template destroy arguments. */ 1225 struct { 1226 uint32_t *action_id; 1227 uint32_t action_id_n; 1228 } ia_destroy; /**< Indirect action destroy arguments. */ 1229 struct { 1230 uint32_t action_id; 1231 enum rte_flow_query_update_mode qu_mode; 1232 } ia; /* Indirect action query arguments */ 1233 struct { 1234 uint32_t table_id; 1235 uint32_t pat_templ_id; 1236 uint32_t rule_id; 1237 uint32_t act_templ_id; 1238 struct rte_flow_attr attr; 1239 struct tunnel_ops tunnel_ops; 1240 uintptr_t user_id; 1241 struct rte_flow_item *pattern; 1242 struct rte_flow_action *actions; 1243 struct rte_flow_action *masks; 1244 uint32_t pattern_n; 1245 uint32_t actions_n; 1246 uint8_t *data; 1247 enum rte_flow_encap_hash_field field; 1248 uint8_t encap_hash; 1249 } vc; /**< Validate/create arguments. */ 1250 struct { 1251 uint64_t *rule; 1252 uint64_t rule_n; 1253 bool is_user_id; 1254 } destroy; /**< Destroy arguments. */ 1255 struct { 1256 char file[128]; 1257 bool mode; 1258 uint64_t rule; 1259 bool is_user_id; 1260 } dump; /**< Dump arguments. */ 1261 struct { 1262 uint64_t rule; 1263 struct rte_flow_action action; 1264 bool is_user_id; 1265 } query; /**< Query arguments. */ 1266 struct { 1267 uint32_t *group; 1268 uint32_t group_n; 1269 } list; /**< List arguments. */ 1270 struct { 1271 int set; 1272 } isolate; /**< Isolated mode arguments. */ 1273 struct { 1274 int destroy; 1275 } aged; /**< Aged arguments. */ 1276 struct { 1277 uint32_t policy_id; 1278 } policy;/**< Policy arguments. */ 1279 struct { 1280 uint16_t token; 1281 uintptr_t uintptr; 1282 char filename[128]; 1283 } flex; /**< Flex arguments*/ 1284 } args; /**< Command arguments. */ 1285 }; 1286 1287 /** Private data for pattern items. */ 1288 struct parse_item_priv { 1289 enum rte_flow_item_type type; /**< Item type. */ 1290 uint32_t size; /**< Size of item specification structure. */ 1291 }; 1292 1293 #define PRIV_ITEM(t, s) \ 1294 (&(const struct parse_item_priv){ \ 1295 .type = RTE_FLOW_ITEM_TYPE_ ## t, \ 1296 .size = s, \ 1297 }) 1298 1299 /** Private data for actions. */ 1300 struct parse_action_priv { 1301 enum rte_flow_action_type type; /**< Action type. */ 1302 uint32_t size; /**< Size of action configuration structure. */ 1303 }; 1304 1305 #define PRIV_ACTION(t, s) \ 1306 (&(const struct parse_action_priv){ \ 1307 .type = RTE_FLOW_ACTION_TYPE_ ## t, \ 1308 .size = s, \ 1309 }) 1310 1311 static const enum index next_flex_item[] = { 1312 FLEX_ITEM_INIT, 1313 FLEX_ITEM_CREATE, 1314 FLEX_ITEM_DESTROY, 1315 ZERO, 1316 }; 1317 1318 static const enum index next_config_attr[] = { 1319 CONFIG_QUEUES_NUMBER, 1320 CONFIG_QUEUES_SIZE, 1321 CONFIG_COUNTERS_NUMBER, 1322 CONFIG_AGING_OBJECTS_NUMBER, 1323 CONFIG_METERS_NUMBER, 1324 CONFIG_CONN_TRACK_NUMBER, 1325 CONFIG_QUOTAS_NUMBER, 1326 CONFIG_FLAGS, 1327 CONFIG_HOST_PORT, 1328 END, 1329 ZERO, 1330 }; 1331 1332 static const enum index next_pt_subcmd[] = { 1333 PATTERN_TEMPLATE_CREATE, 1334 PATTERN_TEMPLATE_DESTROY, 1335 ZERO, 1336 }; 1337 1338 static const enum index next_pt_attr[] = { 1339 PATTERN_TEMPLATE_CREATE_ID, 1340 PATTERN_TEMPLATE_RELAXED_MATCHING, 1341 PATTERN_TEMPLATE_INGRESS, 1342 PATTERN_TEMPLATE_EGRESS, 1343 PATTERN_TEMPLATE_TRANSFER, 1344 PATTERN_TEMPLATE_SPEC, 1345 ZERO, 1346 }; 1347 1348 static const enum index next_pt_destroy_attr[] = { 1349 PATTERN_TEMPLATE_DESTROY_ID, 1350 END, 1351 ZERO, 1352 }; 1353 1354 static const enum index next_at_subcmd[] = { 1355 ACTIONS_TEMPLATE_CREATE, 1356 ACTIONS_TEMPLATE_DESTROY, 1357 ZERO, 1358 }; 1359 1360 static const enum index next_at_attr[] = { 1361 ACTIONS_TEMPLATE_CREATE_ID, 1362 ACTIONS_TEMPLATE_INGRESS, 1363 ACTIONS_TEMPLATE_EGRESS, 1364 ACTIONS_TEMPLATE_TRANSFER, 1365 ACTIONS_TEMPLATE_SPEC, 1366 ZERO, 1367 }; 1368 1369 static const enum index next_at_destroy_attr[] = { 1370 ACTIONS_TEMPLATE_DESTROY_ID, 1371 END, 1372 ZERO, 1373 }; 1374 1375 static const enum index next_group_attr[] = { 1376 GROUP_INGRESS, 1377 GROUP_EGRESS, 1378 GROUP_TRANSFER, 1379 GROUP_SET_MISS_ACTIONS, 1380 ZERO, 1381 }; 1382 1383 static const enum index next_table_subcmd[] = { 1384 TABLE_CREATE, 1385 TABLE_DESTROY, 1386 TABLE_RESIZE, 1387 TABLE_RESIZE_COMPLETE, 1388 ZERO, 1389 }; 1390 1391 static const enum index next_table_attr[] = { 1392 TABLE_CREATE_ID, 1393 TABLE_GROUP, 1394 TABLE_INSERTION_TYPE, 1395 TABLE_HASH_FUNC, 1396 TABLE_PRIORITY, 1397 TABLE_INGRESS, 1398 TABLE_EGRESS, 1399 TABLE_TRANSFER, 1400 TABLE_TRANSFER_WIRE_ORIG, 1401 TABLE_TRANSFER_VPORT_ORIG, 1402 TABLE_RESIZABLE, 1403 TABLE_RULES_NUMBER, 1404 TABLE_PATTERN_TEMPLATE, 1405 TABLE_ACTIONS_TEMPLATE, 1406 END, 1407 ZERO, 1408 }; 1409 1410 static const enum index next_table_destroy_attr[] = { 1411 TABLE_DESTROY_ID, 1412 END, 1413 ZERO, 1414 }; 1415 1416 static const enum index next_queue_subcmd[] = { 1417 QUEUE_CREATE, 1418 QUEUE_DESTROY, 1419 QUEUE_FLOW_UPDATE_RESIZED, 1420 QUEUE_UPDATE, 1421 QUEUE_AGED, 1422 QUEUE_INDIRECT_ACTION, 1423 ZERO, 1424 }; 1425 1426 static const enum index next_queue_destroy_attr[] = { 1427 QUEUE_DESTROY_ID, 1428 END, 1429 ZERO, 1430 }; 1431 1432 static const enum index next_qia_subcmd[] = { 1433 QUEUE_INDIRECT_ACTION_CREATE, 1434 QUEUE_INDIRECT_ACTION_UPDATE, 1435 QUEUE_INDIRECT_ACTION_DESTROY, 1436 QUEUE_INDIRECT_ACTION_QUERY, 1437 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 1438 ZERO, 1439 }; 1440 1441 static const enum index next_qia_create_attr[] = { 1442 QUEUE_INDIRECT_ACTION_CREATE_ID, 1443 QUEUE_INDIRECT_ACTION_INGRESS, 1444 QUEUE_INDIRECT_ACTION_EGRESS, 1445 QUEUE_INDIRECT_ACTION_TRANSFER, 1446 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 1447 QUEUE_INDIRECT_ACTION_SPEC, 1448 QUEUE_INDIRECT_ACTION_LIST, 1449 ZERO, 1450 }; 1451 1452 static const enum index next_qia_update_attr[] = { 1453 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1454 QUEUE_INDIRECT_ACTION_SPEC, 1455 ZERO, 1456 }; 1457 1458 static const enum index next_qia_destroy_attr[] = { 1459 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 1460 QUEUE_INDIRECT_ACTION_DESTROY_ID, 1461 END, 1462 ZERO, 1463 }; 1464 1465 static const enum index next_qia_query_attr[] = { 1466 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 1467 END, 1468 ZERO, 1469 }; 1470 1471 static const enum index next_ia_create_attr[] = { 1472 INDIRECT_ACTION_CREATE_ID, 1473 INDIRECT_ACTION_INGRESS, 1474 INDIRECT_ACTION_EGRESS, 1475 INDIRECT_ACTION_TRANSFER, 1476 INDIRECT_ACTION_SPEC, 1477 INDIRECT_ACTION_LIST, 1478 INDIRECT_ACTION_FLOW_CONF, 1479 ZERO, 1480 }; 1481 1482 static const enum index next_ia[] = { 1483 INDIRECT_ACTION_ID2PTR, 1484 ACTION_NEXT, 1485 ZERO 1486 }; 1487 1488 static const enum index next_ial[] = { 1489 ACTION_INDIRECT_LIST_HANDLE, 1490 ACTION_INDIRECT_LIST_CONF, 1491 ACTION_NEXT, 1492 ZERO 1493 }; 1494 1495 static const enum index next_qia_qu_attr[] = { 1496 QUEUE_INDIRECT_ACTION_QU_MODE, 1497 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1498 INDIRECT_ACTION_SPEC, 1499 ZERO 1500 }; 1501 1502 static const enum index next_ia_qu_attr[] = { 1503 INDIRECT_ACTION_QU_MODE, 1504 INDIRECT_ACTION_SPEC, 1505 ZERO 1506 }; 1507 1508 static const enum index next_dump_subcmd[] = { 1509 DUMP_ALL, 1510 DUMP_ONE, 1511 DUMP_IS_USER_ID, 1512 ZERO, 1513 }; 1514 1515 static const enum index next_ia_subcmd[] = { 1516 INDIRECT_ACTION_CREATE, 1517 INDIRECT_ACTION_UPDATE, 1518 INDIRECT_ACTION_DESTROY, 1519 INDIRECT_ACTION_QUERY, 1520 INDIRECT_ACTION_QUERY_UPDATE, 1521 ZERO, 1522 }; 1523 1524 static const enum index next_vc_attr[] = { 1525 VC_GROUP, 1526 VC_PRIORITY, 1527 VC_INGRESS, 1528 VC_EGRESS, 1529 VC_TRANSFER, 1530 VC_TUNNEL_SET, 1531 VC_TUNNEL_MATCH, 1532 VC_USER_ID, 1533 ITEM_PATTERN, 1534 ZERO, 1535 }; 1536 1537 static const enum index next_destroy_attr[] = { 1538 DESTROY_RULE, 1539 DESTROY_IS_USER_ID, 1540 END, 1541 ZERO, 1542 }; 1543 1544 static const enum index next_dump_attr[] = { 1545 COMMON_FILE_PATH, 1546 END, 1547 ZERO, 1548 }; 1549 1550 static const enum index next_query_attr[] = { 1551 QUERY_IS_USER_ID, 1552 END, 1553 ZERO, 1554 }; 1555 1556 static const enum index next_list_attr[] = { 1557 LIST_GROUP, 1558 END, 1559 ZERO, 1560 }; 1561 1562 static const enum index next_aged_attr[] = { 1563 AGED_DESTROY, 1564 END, 1565 ZERO, 1566 }; 1567 1568 static const enum index next_ia_destroy_attr[] = { 1569 INDIRECT_ACTION_DESTROY_ID, 1570 END, 1571 ZERO, 1572 }; 1573 1574 static const enum index next_async_insert_subcmd[] = { 1575 QUEUE_PATTERN_TEMPLATE, 1576 QUEUE_RULE_ID, 1577 ZERO, 1578 }; 1579 1580 static const enum index item_param[] = { 1581 ITEM_PARAM_IS, 1582 ITEM_PARAM_SPEC, 1583 ITEM_PARAM_LAST, 1584 ITEM_PARAM_MASK, 1585 ITEM_PARAM_PREFIX, 1586 ZERO, 1587 }; 1588 1589 static const enum index next_item[] = { 1590 ITEM_END, 1591 ITEM_VOID, 1592 ITEM_INVERT, 1593 ITEM_ANY, 1594 ITEM_PORT_ID, 1595 ITEM_MARK, 1596 ITEM_RAW, 1597 ITEM_ETH, 1598 ITEM_VLAN, 1599 ITEM_IPV4, 1600 ITEM_IPV6, 1601 ITEM_ICMP, 1602 ITEM_UDP, 1603 ITEM_TCP, 1604 ITEM_SCTP, 1605 ITEM_VXLAN, 1606 ITEM_E_TAG, 1607 ITEM_NVGRE, 1608 ITEM_MPLS, 1609 ITEM_GRE, 1610 ITEM_FUZZY, 1611 ITEM_GTP, 1612 ITEM_GTPC, 1613 ITEM_GTPU, 1614 ITEM_GENEVE, 1615 ITEM_ARP_ETH_IPV4, 1616 ITEM_IPV6_EXT, 1617 ITEM_IPV6_FRAG_EXT, 1618 ITEM_IPV6_ROUTING_EXT, 1619 ITEM_ICMP6, 1620 ITEM_ICMP6_ECHO_REQUEST, 1621 ITEM_ICMP6_ECHO_REPLY, 1622 ITEM_ICMP6_ND_NS, 1623 ITEM_ICMP6_ND_NA, 1624 ITEM_ICMP6_ND_OPT, 1625 ITEM_ICMP6_ND_OPT_SLA_ETH, 1626 ITEM_ICMP6_ND_OPT_TLA_ETH, 1627 ITEM_META, 1628 ITEM_RANDOM, 1629 ITEM_GRE_KEY, 1630 ITEM_GRE_OPTION, 1631 ITEM_GTP_PSC, 1632 ITEM_PPPOES, 1633 ITEM_PPPOED, 1634 ITEM_PPPOE_PROTO_ID, 1635 ITEM_HIGIG2, 1636 ITEM_TAG, 1637 ITEM_L2TPV3OIP, 1638 ITEM_ESP, 1639 ITEM_AH, 1640 ITEM_PFCP, 1641 ITEM_ECPRI, 1642 ITEM_GENEVE_OPT, 1643 ITEM_INTEGRITY, 1644 ITEM_CONNTRACK, 1645 ITEM_PORT_REPRESENTOR, 1646 ITEM_REPRESENTED_PORT, 1647 ITEM_FLEX, 1648 ITEM_L2TPV2, 1649 ITEM_PPP, 1650 ITEM_METER, 1651 ITEM_QUOTA, 1652 ITEM_AGGR_AFFINITY, 1653 ITEM_TX_QUEUE, 1654 ITEM_IB_BTH, 1655 ITEM_PTYPE, 1656 ITEM_NSH, 1657 ITEM_COMPARE, 1658 END_SET, 1659 ZERO, 1660 }; 1661 1662 static const enum index item_fuzzy[] = { 1663 ITEM_FUZZY_THRESH, 1664 ITEM_NEXT, 1665 ZERO, 1666 }; 1667 1668 static const enum index item_any[] = { 1669 ITEM_ANY_NUM, 1670 ITEM_NEXT, 1671 ZERO, 1672 }; 1673 1674 static const enum index item_port_id[] = { 1675 ITEM_PORT_ID_ID, 1676 ITEM_NEXT, 1677 ZERO, 1678 }; 1679 1680 static const enum index item_mark[] = { 1681 ITEM_MARK_ID, 1682 ITEM_NEXT, 1683 ZERO, 1684 }; 1685 1686 static const enum index item_raw[] = { 1687 ITEM_RAW_RELATIVE, 1688 ITEM_RAW_SEARCH, 1689 ITEM_RAW_OFFSET, 1690 ITEM_RAW_LIMIT, 1691 ITEM_RAW_PATTERN, 1692 ITEM_RAW_PATTERN_HEX, 1693 ITEM_NEXT, 1694 ZERO, 1695 }; 1696 1697 static const enum index item_eth[] = { 1698 ITEM_ETH_DST, 1699 ITEM_ETH_SRC, 1700 ITEM_ETH_TYPE, 1701 ITEM_ETH_HAS_VLAN, 1702 ITEM_NEXT, 1703 ZERO, 1704 }; 1705 1706 static const enum index item_vlan[] = { 1707 ITEM_VLAN_TCI, 1708 ITEM_VLAN_PCP, 1709 ITEM_VLAN_DEI, 1710 ITEM_VLAN_VID, 1711 ITEM_VLAN_INNER_TYPE, 1712 ITEM_VLAN_HAS_MORE_VLAN, 1713 ITEM_NEXT, 1714 ZERO, 1715 }; 1716 1717 static const enum index item_ipv4[] = { 1718 ITEM_IPV4_VER_IHL, 1719 ITEM_IPV4_TOS, 1720 ITEM_IPV4_LENGTH, 1721 ITEM_IPV4_ID, 1722 ITEM_IPV4_FRAGMENT_OFFSET, 1723 ITEM_IPV4_TTL, 1724 ITEM_IPV4_PROTO, 1725 ITEM_IPV4_SRC, 1726 ITEM_IPV4_DST, 1727 ITEM_NEXT, 1728 ZERO, 1729 }; 1730 1731 static const enum index item_ipv6[] = { 1732 ITEM_IPV6_TC, 1733 ITEM_IPV6_FLOW, 1734 ITEM_IPV6_LEN, 1735 ITEM_IPV6_PROTO, 1736 ITEM_IPV6_HOP, 1737 ITEM_IPV6_SRC, 1738 ITEM_IPV6_DST, 1739 ITEM_IPV6_HAS_FRAG_EXT, 1740 ITEM_IPV6_ROUTING_EXT, 1741 ITEM_NEXT, 1742 ZERO, 1743 }; 1744 1745 static const enum index item_ipv6_routing_ext[] = { 1746 ITEM_IPV6_ROUTING_EXT_TYPE, 1747 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 1748 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 1749 ITEM_NEXT, 1750 ZERO, 1751 }; 1752 1753 static const enum index item_icmp[] = { 1754 ITEM_ICMP_TYPE, 1755 ITEM_ICMP_CODE, 1756 ITEM_ICMP_IDENT, 1757 ITEM_ICMP_SEQ, 1758 ITEM_NEXT, 1759 ZERO, 1760 }; 1761 1762 static const enum index item_udp[] = { 1763 ITEM_UDP_SRC, 1764 ITEM_UDP_DST, 1765 ITEM_NEXT, 1766 ZERO, 1767 }; 1768 1769 static const enum index item_tcp[] = { 1770 ITEM_TCP_SRC, 1771 ITEM_TCP_DST, 1772 ITEM_TCP_FLAGS, 1773 ITEM_NEXT, 1774 ZERO, 1775 }; 1776 1777 static const enum index item_sctp[] = { 1778 ITEM_SCTP_SRC, 1779 ITEM_SCTP_DST, 1780 ITEM_SCTP_TAG, 1781 ITEM_SCTP_CKSUM, 1782 ITEM_NEXT, 1783 ZERO, 1784 }; 1785 1786 static const enum index item_vxlan[] = { 1787 ITEM_VXLAN_VNI, 1788 ITEM_VXLAN_FLAG_G, 1789 ITEM_VXLAN_FLAG_VER, 1790 ITEM_VXLAN_FLAG_I, 1791 ITEM_VXLAN_FLAG_P, 1792 ITEM_VXLAN_FLAG_B, 1793 ITEM_VXLAN_FLAG_O, 1794 ITEM_VXLAN_FLAG_D, 1795 ITEM_VXLAN_FLAG_A, 1796 ITEM_VXLAN_GBP_ID, 1797 ITEM_VXLAN_GPE_PROTO, 1798 ITEM_VXLAN_FIRST_RSVD, 1799 ITEM_VXLAN_SECND_RSVD, 1800 ITEM_VXLAN_THIRD_RSVD, 1801 ITEM_VXLAN_LAST_RSVD, 1802 ITEM_NEXT, 1803 ZERO, 1804 }; 1805 1806 static const enum index item_e_tag[] = { 1807 ITEM_E_TAG_GRP_ECID_B, 1808 ITEM_NEXT, 1809 ZERO, 1810 }; 1811 1812 static const enum index item_nvgre[] = { 1813 ITEM_NVGRE_TNI, 1814 ITEM_NEXT, 1815 ZERO, 1816 }; 1817 1818 static const enum index item_mpls[] = { 1819 ITEM_MPLS_LABEL, 1820 ITEM_MPLS_TC, 1821 ITEM_MPLS_S, 1822 ITEM_MPLS_TTL, 1823 ITEM_NEXT, 1824 ZERO, 1825 }; 1826 1827 static const enum index item_gre[] = { 1828 ITEM_GRE_PROTO, 1829 ITEM_GRE_C_RSVD0_VER, 1830 ITEM_GRE_C_BIT, 1831 ITEM_GRE_K_BIT, 1832 ITEM_GRE_S_BIT, 1833 ITEM_NEXT, 1834 ZERO, 1835 }; 1836 1837 static const enum index item_gre_key[] = { 1838 ITEM_GRE_KEY_VALUE, 1839 ITEM_NEXT, 1840 ZERO, 1841 }; 1842 1843 static const enum index item_gre_option[] = { 1844 ITEM_GRE_OPTION_CHECKSUM, 1845 ITEM_GRE_OPTION_KEY, 1846 ITEM_GRE_OPTION_SEQUENCE, 1847 ITEM_NEXT, 1848 ZERO, 1849 }; 1850 1851 static const enum index item_gtp[] = { 1852 ITEM_GTP_FLAGS, 1853 ITEM_GTP_MSG_TYPE, 1854 ITEM_GTP_TEID, 1855 ITEM_NEXT, 1856 ZERO, 1857 }; 1858 1859 static const enum index item_geneve[] = { 1860 ITEM_GENEVE_VNI, 1861 ITEM_GENEVE_PROTO, 1862 ITEM_GENEVE_OPTLEN, 1863 ITEM_NEXT, 1864 ZERO, 1865 }; 1866 1867 static const enum index item_arp_eth_ipv4[] = { 1868 ITEM_ARP_ETH_IPV4_SHA, 1869 ITEM_ARP_ETH_IPV4_SPA, 1870 ITEM_ARP_ETH_IPV4_THA, 1871 ITEM_ARP_ETH_IPV4_TPA, 1872 ITEM_NEXT, 1873 ZERO, 1874 }; 1875 1876 static const enum index item_ipv6_ext[] = { 1877 ITEM_IPV6_EXT_NEXT_HDR, 1878 ITEM_NEXT, 1879 ZERO, 1880 }; 1881 1882 static const enum index item_ipv6_frag_ext[] = { 1883 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 1884 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 1885 ITEM_IPV6_FRAG_EXT_ID, 1886 ITEM_NEXT, 1887 ZERO, 1888 }; 1889 1890 static const enum index item_icmp6[] = { 1891 ITEM_ICMP6_TYPE, 1892 ITEM_ICMP6_CODE, 1893 ITEM_NEXT, 1894 ZERO, 1895 }; 1896 1897 static const enum index item_icmp6_echo_request[] = { 1898 ITEM_ICMP6_ECHO_REQUEST_ID, 1899 ITEM_ICMP6_ECHO_REQUEST_SEQ, 1900 ITEM_NEXT, 1901 ZERO, 1902 }; 1903 1904 static const enum index item_icmp6_echo_reply[] = { 1905 ITEM_ICMP6_ECHO_REPLY_ID, 1906 ITEM_ICMP6_ECHO_REPLY_SEQ, 1907 ITEM_NEXT, 1908 ZERO, 1909 }; 1910 1911 static const enum index item_icmp6_nd_ns[] = { 1912 ITEM_ICMP6_ND_NS_TARGET_ADDR, 1913 ITEM_NEXT, 1914 ZERO, 1915 }; 1916 1917 static const enum index item_icmp6_nd_na[] = { 1918 ITEM_ICMP6_ND_NA_TARGET_ADDR, 1919 ITEM_NEXT, 1920 ZERO, 1921 }; 1922 1923 static const enum index item_icmp6_nd_opt[] = { 1924 ITEM_ICMP6_ND_OPT_TYPE, 1925 ITEM_NEXT, 1926 ZERO, 1927 }; 1928 1929 static const enum index item_icmp6_nd_opt_sla_eth[] = { 1930 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 1931 ITEM_NEXT, 1932 ZERO, 1933 }; 1934 1935 static const enum index item_icmp6_nd_opt_tla_eth[] = { 1936 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 1937 ITEM_NEXT, 1938 ZERO, 1939 }; 1940 1941 static const enum index item_meta[] = { 1942 ITEM_META_DATA, 1943 ITEM_NEXT, 1944 ZERO, 1945 }; 1946 1947 static const enum index item_random[] = { 1948 ITEM_RANDOM_VALUE, 1949 ITEM_NEXT, 1950 ZERO, 1951 }; 1952 1953 static const enum index item_gtp_psc[] = { 1954 ITEM_GTP_PSC_QFI, 1955 ITEM_GTP_PSC_PDU_T, 1956 ITEM_NEXT, 1957 ZERO, 1958 }; 1959 1960 static const enum index item_pppoed[] = { 1961 ITEM_PPPOE_SEID, 1962 ITEM_NEXT, 1963 ZERO, 1964 }; 1965 1966 static const enum index item_pppoes[] = { 1967 ITEM_PPPOE_SEID, 1968 ITEM_NEXT, 1969 ZERO, 1970 }; 1971 1972 static const enum index item_pppoe_proto_id[] = { 1973 ITEM_NEXT, 1974 ZERO, 1975 }; 1976 1977 static const enum index item_higig2[] = { 1978 ITEM_HIGIG2_CLASSIFICATION, 1979 ITEM_HIGIG2_VID, 1980 ITEM_NEXT, 1981 ZERO, 1982 }; 1983 1984 static const enum index item_esp[] = { 1985 ITEM_ESP_SPI, 1986 ITEM_NEXT, 1987 ZERO, 1988 }; 1989 1990 static const enum index item_ah[] = { 1991 ITEM_AH_SPI, 1992 ITEM_NEXT, 1993 ZERO, 1994 }; 1995 1996 static const enum index item_pfcp[] = { 1997 ITEM_PFCP_S_FIELD, 1998 ITEM_PFCP_SEID, 1999 ITEM_NEXT, 2000 ZERO, 2001 }; 2002 2003 static const enum index next_set_raw[] = { 2004 SET_RAW_INDEX, 2005 ITEM_ETH, 2006 ZERO, 2007 }; 2008 2009 static const enum index item_tag[] = { 2010 ITEM_TAG_DATA, 2011 ITEM_TAG_INDEX, 2012 ITEM_NEXT, 2013 ZERO, 2014 }; 2015 2016 static const enum index item_l2tpv3oip[] = { 2017 ITEM_L2TPV3OIP_SESSION_ID, 2018 ITEM_NEXT, 2019 ZERO, 2020 }; 2021 2022 static const enum index item_ecpri[] = { 2023 ITEM_ECPRI_COMMON, 2024 ITEM_NEXT, 2025 ZERO, 2026 }; 2027 2028 static const enum index item_ecpri_common[] = { 2029 ITEM_ECPRI_COMMON_TYPE, 2030 ZERO, 2031 }; 2032 2033 static const enum index item_ecpri_common_type[] = { 2034 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 2035 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 2036 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 2037 ZERO, 2038 }; 2039 2040 static const enum index item_geneve_opt[] = { 2041 ITEM_GENEVE_OPT_CLASS, 2042 ITEM_GENEVE_OPT_TYPE, 2043 ITEM_GENEVE_OPT_LENGTH, 2044 ITEM_GENEVE_OPT_DATA, 2045 ITEM_NEXT, 2046 ZERO, 2047 }; 2048 2049 static const enum index item_integrity[] = { 2050 ITEM_INTEGRITY_LEVEL, 2051 ITEM_INTEGRITY_VALUE, 2052 ZERO, 2053 }; 2054 2055 static const enum index item_integrity_lv[] = { 2056 ITEM_INTEGRITY_LEVEL, 2057 ITEM_INTEGRITY_VALUE, 2058 ITEM_NEXT, 2059 ZERO, 2060 }; 2061 2062 static const enum index item_port_representor[] = { 2063 ITEM_PORT_REPRESENTOR_PORT_ID, 2064 ITEM_NEXT, 2065 ZERO, 2066 }; 2067 2068 static const enum index item_represented_port[] = { 2069 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 2070 ITEM_NEXT, 2071 ZERO, 2072 }; 2073 2074 static const enum index item_flex[] = { 2075 ITEM_FLEX_PATTERN_HANDLE, 2076 ITEM_FLEX_ITEM_HANDLE, 2077 ITEM_NEXT, 2078 ZERO, 2079 }; 2080 2081 static const enum index item_l2tpv2[] = { 2082 ITEM_L2TPV2_TYPE, 2083 ITEM_NEXT, 2084 ZERO, 2085 }; 2086 2087 static const enum index item_l2tpv2_type[] = { 2088 ITEM_L2TPV2_TYPE_DATA, 2089 ITEM_L2TPV2_TYPE_DATA_L, 2090 ITEM_L2TPV2_TYPE_DATA_S, 2091 ITEM_L2TPV2_TYPE_DATA_O, 2092 ITEM_L2TPV2_TYPE_DATA_L_S, 2093 ITEM_L2TPV2_TYPE_CTRL, 2094 ZERO, 2095 }; 2096 2097 static const enum index item_l2tpv2_type_data[] = { 2098 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 2099 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 2100 ITEM_NEXT, 2101 ZERO, 2102 }; 2103 2104 static const enum index item_l2tpv2_type_data_l[] = { 2105 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 2106 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 2107 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 2108 ITEM_NEXT, 2109 ZERO, 2110 }; 2111 2112 static const enum index item_l2tpv2_type_data_s[] = { 2113 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 2114 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 2115 ITEM_L2TPV2_MSG_DATA_S_NS, 2116 ITEM_L2TPV2_MSG_DATA_S_NR, 2117 ITEM_NEXT, 2118 ZERO, 2119 }; 2120 2121 static const enum index item_l2tpv2_type_data_o[] = { 2122 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 2123 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 2124 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 2125 ITEM_NEXT, 2126 ZERO, 2127 }; 2128 2129 static const enum index item_l2tpv2_type_data_l_s[] = { 2130 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 2131 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 2132 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 2133 ITEM_L2TPV2_MSG_DATA_L_S_NS, 2134 ITEM_L2TPV2_MSG_DATA_L_S_NR, 2135 ITEM_NEXT, 2136 ZERO, 2137 }; 2138 2139 static const enum index item_l2tpv2_type_ctrl[] = { 2140 ITEM_L2TPV2_MSG_CTRL_LENGTH, 2141 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 2142 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 2143 ITEM_L2TPV2_MSG_CTRL_NS, 2144 ITEM_L2TPV2_MSG_CTRL_NR, 2145 ITEM_NEXT, 2146 ZERO, 2147 }; 2148 2149 static const enum index item_ppp[] = { 2150 ITEM_PPP_ADDR, 2151 ITEM_PPP_CTRL, 2152 ITEM_PPP_PROTO_ID, 2153 ITEM_NEXT, 2154 ZERO, 2155 }; 2156 2157 static const enum index item_meter[] = { 2158 ITEM_METER_COLOR, 2159 ITEM_NEXT, 2160 ZERO, 2161 }; 2162 2163 static const enum index item_quota[] = { 2164 ITEM_QUOTA_STATE, 2165 ITEM_NEXT, 2166 ZERO, 2167 }; 2168 2169 static const enum index item_aggr_affinity[] = { 2170 ITEM_AGGR_AFFINITY_VALUE, 2171 ITEM_NEXT, 2172 ZERO, 2173 }; 2174 2175 static const enum index item_tx_queue[] = { 2176 ITEM_TX_QUEUE_VALUE, 2177 ITEM_NEXT, 2178 ZERO, 2179 }; 2180 2181 static const enum index item_ib_bth[] = { 2182 ITEM_IB_BTH_OPCODE, 2183 ITEM_IB_BTH_PKEY, 2184 ITEM_IB_BTH_DST_QPN, 2185 ITEM_IB_BTH_PSN, 2186 ITEM_NEXT, 2187 ZERO, 2188 }; 2189 2190 static const enum index item_ptype[] = { 2191 ITEM_PTYPE_VALUE, 2192 ITEM_NEXT, 2193 ZERO, 2194 }; 2195 2196 static const enum index item_nsh[] = { 2197 ITEM_NEXT, 2198 ZERO, 2199 }; 2200 2201 static const enum index item_compare_field[] = { 2202 ITEM_COMPARE_OP, 2203 ITEM_COMPARE_FIELD_A_TYPE, 2204 ITEM_COMPARE_FIELD_B_TYPE, 2205 ITEM_NEXT, 2206 ZERO, 2207 }; 2208 2209 static const enum index compare_field_a[] = { 2210 ITEM_COMPARE_FIELD_A_TYPE, 2211 ITEM_COMPARE_FIELD_A_LEVEL, 2212 ITEM_COMPARE_FIELD_A_TAG_INDEX, 2213 ITEM_COMPARE_FIELD_A_TYPE_ID, 2214 ITEM_COMPARE_FIELD_A_CLASS_ID, 2215 ITEM_COMPARE_FIELD_A_OFFSET, 2216 ITEM_COMPARE_FIELD_B_TYPE, 2217 ZERO, 2218 }; 2219 2220 static const enum index compare_field_b[] = { 2221 ITEM_COMPARE_FIELD_B_TYPE, 2222 ITEM_COMPARE_FIELD_B_LEVEL, 2223 ITEM_COMPARE_FIELD_B_TAG_INDEX, 2224 ITEM_COMPARE_FIELD_B_TYPE_ID, 2225 ITEM_COMPARE_FIELD_B_CLASS_ID, 2226 ITEM_COMPARE_FIELD_B_OFFSET, 2227 ITEM_COMPARE_FIELD_B_VALUE, 2228 ITEM_COMPARE_FIELD_B_POINTER, 2229 ITEM_COMPARE_FIELD_WIDTH, 2230 ZERO, 2231 }; 2232 2233 static const enum index next_action[] = { 2234 ACTION_END, 2235 ACTION_VOID, 2236 ACTION_PASSTHRU, 2237 ACTION_SKIP_CMAN, 2238 ACTION_JUMP, 2239 ACTION_MARK, 2240 ACTION_FLAG, 2241 ACTION_QUEUE, 2242 ACTION_DROP, 2243 ACTION_COUNT, 2244 ACTION_RSS, 2245 ACTION_PF, 2246 ACTION_VF, 2247 ACTION_PORT_ID, 2248 ACTION_METER, 2249 ACTION_METER_COLOR, 2250 ACTION_METER_MARK, 2251 ACTION_OF_DEC_NW_TTL, 2252 ACTION_OF_POP_VLAN, 2253 ACTION_OF_PUSH_VLAN, 2254 ACTION_OF_SET_VLAN_VID, 2255 ACTION_OF_SET_VLAN_PCP, 2256 ACTION_OF_POP_MPLS, 2257 ACTION_OF_PUSH_MPLS, 2258 ACTION_VXLAN_ENCAP, 2259 ACTION_VXLAN_DECAP, 2260 ACTION_NVGRE_ENCAP, 2261 ACTION_NVGRE_DECAP, 2262 ACTION_L2_ENCAP, 2263 ACTION_L2_DECAP, 2264 ACTION_MPLSOGRE_ENCAP, 2265 ACTION_MPLSOGRE_DECAP, 2266 ACTION_MPLSOUDP_ENCAP, 2267 ACTION_MPLSOUDP_DECAP, 2268 ACTION_SET_IPV4_SRC, 2269 ACTION_SET_IPV4_DST, 2270 ACTION_SET_IPV6_SRC, 2271 ACTION_SET_IPV6_DST, 2272 ACTION_SET_TP_SRC, 2273 ACTION_SET_TP_DST, 2274 ACTION_MAC_SWAP, 2275 ACTION_DEC_TTL, 2276 ACTION_SET_TTL, 2277 ACTION_SET_MAC_SRC, 2278 ACTION_SET_MAC_DST, 2279 ACTION_INC_TCP_SEQ, 2280 ACTION_DEC_TCP_SEQ, 2281 ACTION_INC_TCP_ACK, 2282 ACTION_DEC_TCP_ACK, 2283 ACTION_RAW_ENCAP, 2284 ACTION_RAW_DECAP, 2285 ACTION_SET_TAG, 2286 ACTION_SET_META, 2287 ACTION_SET_IPV4_DSCP, 2288 ACTION_SET_IPV6_DSCP, 2289 ACTION_AGE, 2290 ACTION_AGE_UPDATE, 2291 ACTION_SAMPLE, 2292 ACTION_INDIRECT, 2293 ACTION_INDIRECT_LIST, 2294 ACTION_SHARED_INDIRECT, 2295 ACTION_MODIFY_FIELD, 2296 ACTION_CONNTRACK, 2297 ACTION_CONNTRACK_UPDATE, 2298 ACTION_PORT_REPRESENTOR, 2299 ACTION_REPRESENTED_PORT, 2300 ACTION_SEND_TO_KERNEL, 2301 ACTION_QUOTA_CREATE, 2302 ACTION_QUOTA_QU, 2303 ACTION_IPV6_EXT_REMOVE, 2304 ACTION_IPV6_EXT_PUSH, 2305 ACTION_NAT64, 2306 ZERO, 2307 }; 2308 2309 static const enum index action_quota_create[] = { 2310 ACTION_QUOTA_CREATE_LIMIT, 2311 ACTION_QUOTA_CREATE_MODE, 2312 ACTION_NEXT, 2313 ZERO 2314 }; 2315 2316 static const enum index action_quota_update[] = { 2317 ACTION_QUOTA_QU_LIMIT, 2318 ACTION_QUOTA_QU_UPDATE_OP, 2319 ACTION_NEXT, 2320 ZERO 2321 }; 2322 2323 static const enum index action_mark[] = { 2324 ACTION_MARK_ID, 2325 ACTION_NEXT, 2326 ZERO, 2327 }; 2328 2329 static const enum index action_queue[] = { 2330 ACTION_QUEUE_INDEX, 2331 ACTION_NEXT, 2332 ZERO, 2333 }; 2334 2335 static const enum index action_count[] = { 2336 ACTION_COUNT_ID, 2337 ACTION_NEXT, 2338 ZERO, 2339 }; 2340 2341 static const enum index action_rss[] = { 2342 ACTION_RSS_FUNC, 2343 ACTION_RSS_LEVEL, 2344 ACTION_RSS_TYPES, 2345 ACTION_RSS_KEY, 2346 ACTION_RSS_KEY_LEN, 2347 ACTION_RSS_QUEUES, 2348 ACTION_NEXT, 2349 ZERO, 2350 }; 2351 2352 static const enum index action_vf[] = { 2353 ACTION_VF_ORIGINAL, 2354 ACTION_VF_ID, 2355 ACTION_NEXT, 2356 ZERO, 2357 }; 2358 2359 static const enum index action_port_id[] = { 2360 ACTION_PORT_ID_ORIGINAL, 2361 ACTION_PORT_ID_ID, 2362 ACTION_NEXT, 2363 ZERO, 2364 }; 2365 2366 static const enum index action_meter[] = { 2367 ACTION_METER_ID, 2368 ACTION_NEXT, 2369 ZERO, 2370 }; 2371 2372 static const enum index action_meter_color[] = { 2373 ACTION_METER_COLOR_TYPE, 2374 ACTION_NEXT, 2375 ZERO, 2376 }; 2377 2378 static const enum index action_meter_mark[] = { 2379 ACTION_METER_PROFILE, 2380 ACTION_METER_POLICY, 2381 ACTION_METER_COLOR_MODE, 2382 ACTION_METER_STATE, 2383 ACTION_NEXT, 2384 ZERO, 2385 }; 2386 2387 static const enum index action_of_push_vlan[] = { 2388 ACTION_OF_PUSH_VLAN_ETHERTYPE, 2389 ACTION_NEXT, 2390 ZERO, 2391 }; 2392 2393 static const enum index action_of_set_vlan_vid[] = { 2394 ACTION_OF_SET_VLAN_VID_VLAN_VID, 2395 ACTION_NEXT, 2396 ZERO, 2397 }; 2398 2399 static const enum index action_of_set_vlan_pcp[] = { 2400 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 2401 ACTION_NEXT, 2402 ZERO, 2403 }; 2404 2405 static const enum index action_of_pop_mpls[] = { 2406 ACTION_OF_POP_MPLS_ETHERTYPE, 2407 ACTION_NEXT, 2408 ZERO, 2409 }; 2410 2411 static const enum index action_of_push_mpls[] = { 2412 ACTION_OF_PUSH_MPLS_ETHERTYPE, 2413 ACTION_NEXT, 2414 ZERO, 2415 }; 2416 2417 static const enum index action_set_ipv4_src[] = { 2418 ACTION_SET_IPV4_SRC_IPV4_SRC, 2419 ACTION_NEXT, 2420 ZERO, 2421 }; 2422 2423 static const enum index action_set_mac_src[] = { 2424 ACTION_SET_MAC_SRC_MAC_SRC, 2425 ACTION_NEXT, 2426 ZERO, 2427 }; 2428 2429 static const enum index action_set_ipv4_dst[] = { 2430 ACTION_SET_IPV4_DST_IPV4_DST, 2431 ACTION_NEXT, 2432 ZERO, 2433 }; 2434 2435 static const enum index action_set_ipv6_src[] = { 2436 ACTION_SET_IPV6_SRC_IPV6_SRC, 2437 ACTION_NEXT, 2438 ZERO, 2439 }; 2440 2441 static const enum index action_set_ipv6_dst[] = { 2442 ACTION_SET_IPV6_DST_IPV6_DST, 2443 ACTION_NEXT, 2444 ZERO, 2445 }; 2446 2447 static const enum index action_set_tp_src[] = { 2448 ACTION_SET_TP_SRC_TP_SRC, 2449 ACTION_NEXT, 2450 ZERO, 2451 }; 2452 2453 static const enum index action_set_tp_dst[] = { 2454 ACTION_SET_TP_DST_TP_DST, 2455 ACTION_NEXT, 2456 ZERO, 2457 }; 2458 2459 static const enum index action_set_ttl[] = { 2460 ACTION_SET_TTL_TTL, 2461 ACTION_NEXT, 2462 ZERO, 2463 }; 2464 2465 static const enum index action_jump[] = { 2466 ACTION_JUMP_GROUP, 2467 ACTION_NEXT, 2468 ZERO, 2469 }; 2470 2471 static const enum index action_set_mac_dst[] = { 2472 ACTION_SET_MAC_DST_MAC_DST, 2473 ACTION_NEXT, 2474 ZERO, 2475 }; 2476 2477 static const enum index action_inc_tcp_seq[] = { 2478 ACTION_INC_TCP_SEQ_VALUE, 2479 ACTION_NEXT, 2480 ZERO, 2481 }; 2482 2483 static const enum index action_dec_tcp_seq[] = { 2484 ACTION_DEC_TCP_SEQ_VALUE, 2485 ACTION_NEXT, 2486 ZERO, 2487 }; 2488 2489 static const enum index action_inc_tcp_ack[] = { 2490 ACTION_INC_TCP_ACK_VALUE, 2491 ACTION_NEXT, 2492 ZERO, 2493 }; 2494 2495 static const enum index action_dec_tcp_ack[] = { 2496 ACTION_DEC_TCP_ACK_VALUE, 2497 ACTION_NEXT, 2498 ZERO, 2499 }; 2500 2501 static const enum index action_raw_encap[] = { 2502 ACTION_RAW_ENCAP_SIZE, 2503 ACTION_RAW_ENCAP_INDEX, 2504 ACTION_NEXT, 2505 ZERO, 2506 }; 2507 2508 static const enum index action_raw_decap[] = { 2509 ACTION_RAW_DECAP_INDEX, 2510 ACTION_NEXT, 2511 ZERO, 2512 }; 2513 2514 static const enum index action_ipv6_ext_remove[] = { 2515 ACTION_IPV6_EXT_REMOVE_INDEX, 2516 ACTION_NEXT, 2517 ZERO, 2518 }; 2519 2520 static const enum index action_ipv6_ext_push[] = { 2521 ACTION_IPV6_EXT_PUSH_INDEX, 2522 ACTION_NEXT, 2523 ZERO, 2524 }; 2525 2526 static const enum index action_set_tag[] = { 2527 ACTION_SET_TAG_DATA, 2528 ACTION_SET_TAG_INDEX, 2529 ACTION_SET_TAG_MASK, 2530 ACTION_NEXT, 2531 ZERO, 2532 }; 2533 2534 static const enum index action_set_meta[] = { 2535 ACTION_SET_META_DATA, 2536 ACTION_SET_META_MASK, 2537 ACTION_NEXT, 2538 ZERO, 2539 }; 2540 2541 static const enum index action_set_ipv4_dscp[] = { 2542 ACTION_SET_IPV4_DSCP_VALUE, 2543 ACTION_NEXT, 2544 ZERO, 2545 }; 2546 2547 static const enum index action_set_ipv6_dscp[] = { 2548 ACTION_SET_IPV6_DSCP_VALUE, 2549 ACTION_NEXT, 2550 ZERO, 2551 }; 2552 2553 static const enum index action_age[] = { 2554 ACTION_AGE, 2555 ACTION_AGE_TIMEOUT, 2556 ACTION_NEXT, 2557 ZERO, 2558 }; 2559 2560 static const enum index action_age_update[] = { 2561 ACTION_AGE_UPDATE, 2562 ACTION_AGE_UPDATE_TIMEOUT, 2563 ACTION_AGE_UPDATE_TOUCH, 2564 ACTION_NEXT, 2565 ZERO, 2566 }; 2567 2568 static const enum index action_sample[] = { 2569 ACTION_SAMPLE, 2570 ACTION_SAMPLE_RATIO, 2571 ACTION_SAMPLE_INDEX, 2572 ACTION_NEXT, 2573 ZERO, 2574 }; 2575 2576 static const enum index next_action_sample[] = { 2577 ACTION_QUEUE, 2578 ACTION_RSS, 2579 ACTION_MARK, 2580 ACTION_COUNT, 2581 ACTION_PORT_ID, 2582 ACTION_RAW_ENCAP, 2583 ACTION_VXLAN_ENCAP, 2584 ACTION_NVGRE_ENCAP, 2585 ACTION_REPRESENTED_PORT, 2586 ACTION_PORT_REPRESENTOR, 2587 ACTION_NEXT, 2588 ZERO, 2589 }; 2590 2591 static const enum index item_ipv6_push_ext[] = { 2592 ITEM_IPV6_PUSH_REMOVE_EXT, 2593 ZERO, 2594 }; 2595 2596 static const enum index item_ipv6_push_ext_type[] = { 2597 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 2598 ZERO, 2599 }; 2600 2601 static const enum index item_ipv6_push_ext_header[] = { 2602 ITEM_IPV6_ROUTING_EXT, 2603 ITEM_NEXT, 2604 ZERO, 2605 }; 2606 2607 static const enum index action_modify_field_dst[] = { 2608 ACTION_MODIFY_FIELD_DST_LEVEL, 2609 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 2610 ACTION_MODIFY_FIELD_DST_TYPE_ID, 2611 ACTION_MODIFY_FIELD_DST_CLASS_ID, 2612 ACTION_MODIFY_FIELD_DST_OFFSET, 2613 ACTION_MODIFY_FIELD_SRC_TYPE, 2614 ZERO, 2615 }; 2616 2617 static const enum index action_modify_field_src[] = { 2618 ACTION_MODIFY_FIELD_SRC_LEVEL, 2619 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 2620 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 2621 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 2622 ACTION_MODIFY_FIELD_SRC_OFFSET, 2623 ACTION_MODIFY_FIELD_SRC_VALUE, 2624 ACTION_MODIFY_FIELD_SRC_POINTER, 2625 ACTION_MODIFY_FIELD_WIDTH, 2626 ZERO, 2627 }; 2628 2629 static const enum index action_update_conntrack[] = { 2630 ACTION_CONNTRACK_UPDATE_DIR, 2631 ACTION_CONNTRACK_UPDATE_CTX, 2632 ACTION_NEXT, 2633 ZERO, 2634 }; 2635 2636 static const enum index action_port_representor[] = { 2637 ACTION_PORT_REPRESENTOR_PORT_ID, 2638 ACTION_NEXT, 2639 ZERO, 2640 }; 2641 2642 static const enum index action_represented_port[] = { 2643 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 2644 ACTION_NEXT, 2645 ZERO, 2646 }; 2647 2648 static const enum index action_nat64[] = { 2649 ACTION_NAT64_MODE, 2650 ACTION_NEXT, 2651 ZERO, 2652 }; 2653 2654 static const enum index next_hash_subcmd[] = { 2655 HASH_CALC_TABLE, 2656 HASH_CALC_ENCAP, 2657 ZERO, 2658 }; 2659 2660 static const enum index next_hash_encap_dest_subcmd[] = { 2661 ENCAP_HASH_FIELD_SRC_PORT, 2662 ENCAP_HASH_FIELD_GRE_FLOW_ID, 2663 ZERO, 2664 }; 2665 2666 static int parse_set_raw_encap_decap(struct context *, const struct token *, 2667 const char *, unsigned int, 2668 void *, unsigned int); 2669 static int parse_set_sample_action(struct context *, const struct token *, 2670 const char *, unsigned int, 2671 void *, unsigned int); 2672 static int parse_set_ipv6_ext_action(struct context *, const struct token *, 2673 const char *, unsigned int, 2674 void *, unsigned int); 2675 static int parse_set_init(struct context *, const struct token *, 2676 const char *, unsigned int, 2677 void *, unsigned int); 2678 static int 2679 parse_flex_handle(struct context *, const struct token *, 2680 const char *, unsigned int, void *, unsigned int); 2681 static int parse_init(struct context *, const struct token *, 2682 const char *, unsigned int, 2683 void *, unsigned int); 2684 static int parse_vc(struct context *, const struct token *, 2685 const char *, unsigned int, 2686 void *, unsigned int); 2687 static int parse_vc_spec(struct context *, const struct token *, 2688 const char *, unsigned int, void *, unsigned int); 2689 static int parse_vc_conf(struct context *, const struct token *, 2690 const char *, unsigned int, void *, unsigned int); 2691 static int parse_vc_conf_timeout(struct context *, const struct token *, 2692 const char *, unsigned int, void *, 2693 unsigned int); 2694 static int parse_vc_item_ecpri_type(struct context *, const struct token *, 2695 const char *, unsigned int, 2696 void *, unsigned int); 2697 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, 2698 const char *, unsigned int, 2699 void *, unsigned int); 2700 static int parse_vc_action_meter_color_type(struct context *, 2701 const struct token *, 2702 const char *, unsigned int, void *, 2703 unsigned int); 2704 static int parse_vc_action_rss(struct context *, const struct token *, 2705 const char *, unsigned int, void *, 2706 unsigned int); 2707 static int parse_vc_action_rss_func(struct context *, const struct token *, 2708 const char *, unsigned int, void *, 2709 unsigned int); 2710 static int parse_vc_action_rss_type(struct context *, const struct token *, 2711 const char *, unsigned int, void *, 2712 unsigned int); 2713 static int parse_vc_action_rss_queue(struct context *, const struct token *, 2714 const char *, unsigned int, void *, 2715 unsigned int); 2716 static int parse_vc_action_vxlan_encap(struct context *, const struct token *, 2717 const char *, unsigned int, void *, 2718 unsigned int); 2719 static int parse_vc_action_nvgre_encap(struct context *, const struct token *, 2720 const char *, unsigned int, void *, 2721 unsigned int); 2722 static int parse_vc_action_l2_encap(struct context *, const struct token *, 2723 const char *, unsigned int, void *, 2724 unsigned int); 2725 static int parse_vc_action_l2_decap(struct context *, const struct token *, 2726 const char *, unsigned int, void *, 2727 unsigned int); 2728 static int parse_vc_action_mplsogre_encap(struct context *, 2729 const struct token *, const char *, 2730 unsigned int, void *, unsigned int); 2731 static int parse_vc_action_mplsogre_decap(struct context *, 2732 const struct token *, const char *, 2733 unsigned int, void *, unsigned int); 2734 static int parse_vc_action_mplsoudp_encap(struct context *, 2735 const struct token *, const char *, 2736 unsigned int, void *, unsigned int); 2737 static int parse_vc_action_mplsoudp_decap(struct context *, 2738 const struct token *, const char *, 2739 unsigned int, void *, unsigned int); 2740 static int parse_vc_action_raw_encap(struct context *, 2741 const struct token *, const char *, 2742 unsigned int, void *, unsigned int); 2743 static int parse_vc_action_raw_decap(struct context *, 2744 const struct token *, const char *, 2745 unsigned int, void *, unsigned int); 2746 static int parse_vc_action_raw_encap_index(struct context *, 2747 const struct token *, const char *, 2748 unsigned int, void *, unsigned int); 2749 static int parse_vc_action_raw_decap_index(struct context *, 2750 const struct token *, const char *, 2751 unsigned int, void *, unsigned int); 2752 static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 2753 const char *str, unsigned int len, void *buf, 2754 unsigned int size); 2755 static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, 2756 const struct token *token, 2757 const char *str, unsigned int len, 2758 void *buf, 2759 unsigned int size); 2760 static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 2761 const char *str, unsigned int len, void *buf, 2762 unsigned int size); 2763 static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, 2764 const struct token *token, 2765 const char *str, unsigned int len, 2766 void *buf, 2767 unsigned int size); 2768 static int parse_vc_action_set_meta(struct context *ctx, 2769 const struct token *token, const char *str, 2770 unsigned int len, void *buf, 2771 unsigned int size); 2772 static int parse_vc_action_sample(struct context *ctx, 2773 const struct token *token, const char *str, 2774 unsigned int len, void *buf, 2775 unsigned int size); 2776 static int 2777 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 2778 const char *str, unsigned int len, void *buf, 2779 unsigned int size); 2780 static int 2781 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 2782 const char *str, unsigned int len, void *buf, 2783 unsigned int size); 2784 static int 2785 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 2786 const char *str, unsigned int len, void *buf, 2787 unsigned int size); 2788 static int 2789 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 2790 const char *str, unsigned int len, void *buf, 2791 unsigned int size); 2792 static int 2793 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 2794 const char *str, unsigned int len, void *buf, 2795 unsigned int size); 2796 static int parse_destroy(struct context *, const struct token *, 2797 const char *, unsigned int, 2798 void *, unsigned int); 2799 static int parse_flush(struct context *, const struct token *, 2800 const char *, unsigned int, 2801 void *, unsigned int); 2802 static int parse_dump(struct context *, const struct token *, 2803 const char *, unsigned int, 2804 void *, unsigned int); 2805 static int parse_query(struct context *, const struct token *, 2806 const char *, unsigned int, 2807 void *, unsigned int); 2808 static int parse_action(struct context *, const struct token *, 2809 const char *, unsigned int, 2810 void *, unsigned int); 2811 static int parse_list(struct context *, const struct token *, 2812 const char *, unsigned int, 2813 void *, unsigned int); 2814 static int parse_aged(struct context *, const struct token *, 2815 const char *, unsigned int, 2816 void *, unsigned int); 2817 static int parse_isolate(struct context *, const struct token *, 2818 const char *, unsigned int, 2819 void *, unsigned int); 2820 static int parse_configure(struct context *, const struct token *, 2821 const char *, unsigned int, 2822 void *, unsigned int); 2823 static int parse_template(struct context *, const struct token *, 2824 const char *, unsigned int, 2825 void *, unsigned int); 2826 static int parse_template_destroy(struct context *, const struct token *, 2827 const char *, unsigned int, 2828 void *, unsigned int); 2829 static int parse_table(struct context *, const struct token *, 2830 const char *, unsigned int, void *, unsigned int); 2831 static int parse_table_destroy(struct context *, const struct token *, 2832 const char *, unsigned int, 2833 void *, unsigned int); 2834 static int parse_qo(struct context *, const struct token *, 2835 const char *, unsigned int, 2836 void *, unsigned int); 2837 static int parse_qo_destroy(struct context *, const struct token *, 2838 const char *, unsigned int, 2839 void *, unsigned int); 2840 static int parse_qia(struct context *, const struct token *, 2841 const char *, unsigned int, 2842 void *, unsigned int); 2843 static int parse_qia_destroy(struct context *, const struct token *, 2844 const char *, unsigned int, 2845 void *, unsigned int); 2846 static int parse_push(struct context *, const struct token *, 2847 const char *, unsigned int, 2848 void *, unsigned int); 2849 static int parse_pull(struct context *, const struct token *, 2850 const char *, unsigned int, 2851 void *, unsigned int); 2852 static int parse_group(struct context *, const struct token *, 2853 const char *, unsigned int, 2854 void *, unsigned int); 2855 static int parse_hash(struct context *, const struct token *, 2856 const char *, unsigned int, 2857 void *, unsigned int); 2858 static int parse_tunnel(struct context *, const struct token *, 2859 const char *, unsigned int, 2860 void *, unsigned int); 2861 static int parse_flex(struct context *, const struct token *, 2862 const char *, unsigned int, void *, unsigned int); 2863 static int parse_int(struct context *, const struct token *, 2864 const char *, unsigned int, 2865 void *, unsigned int); 2866 static int parse_prefix(struct context *, const struct token *, 2867 const char *, unsigned int, 2868 void *, unsigned int); 2869 static int parse_boolean(struct context *, const struct token *, 2870 const char *, unsigned int, 2871 void *, unsigned int); 2872 static int parse_string(struct context *, const struct token *, 2873 const char *, unsigned int, 2874 void *, unsigned int); 2875 static int parse_hex(struct context *ctx, const struct token *token, 2876 const char *str, unsigned int len, 2877 void *buf, unsigned int size); 2878 static int parse_string0(struct context *, const struct token *, 2879 const char *, unsigned int, 2880 void *, unsigned int); 2881 static int parse_mac_addr(struct context *, const struct token *, 2882 const char *, unsigned int, 2883 void *, unsigned int); 2884 static int parse_ipv4_addr(struct context *, const struct token *, 2885 const char *, unsigned int, 2886 void *, unsigned int); 2887 static int parse_ipv6_addr(struct context *, const struct token *, 2888 const char *, unsigned int, 2889 void *, unsigned int); 2890 static int parse_port(struct context *, const struct token *, 2891 const char *, unsigned int, 2892 void *, unsigned int); 2893 static int parse_ia(struct context *, const struct token *, 2894 const char *, unsigned int, 2895 void *, unsigned int); 2896 static int parse_ia_destroy(struct context *ctx, const struct token *token, 2897 const char *str, unsigned int len, 2898 void *buf, unsigned int size); 2899 static int parse_ia_id2ptr(struct context *ctx, const struct token *token, 2900 const char *str, unsigned int len, void *buf, 2901 unsigned int size); 2902 2903 static int parse_indlst_id2ptr(struct context *ctx, const struct token *token, 2904 const char *str, unsigned int len, void *buf, 2905 unsigned int size); 2906 static int parse_ia_port(struct context *ctx, const struct token *token, 2907 const char *str, unsigned int len, void *buf, 2908 unsigned int size); 2909 static int parse_mp(struct context *, const struct token *, 2910 const char *, unsigned int, 2911 void *, unsigned int); 2912 static int parse_meter_profile_id2ptr(struct context *ctx, 2913 const struct token *token, 2914 const char *str, unsigned int len, 2915 void *buf, unsigned int size); 2916 static int parse_meter_policy_id2ptr(struct context *ctx, 2917 const struct token *token, 2918 const char *str, unsigned int len, 2919 void *buf, unsigned int size); 2920 static int parse_meter_color(struct context *ctx, const struct token *token, 2921 const char *str, unsigned int len, void *buf, 2922 unsigned int size); 2923 static int parse_insertion_table_type(struct context *ctx, const struct token *token, 2924 const char *str, unsigned int len, void *buf, 2925 unsigned int size); 2926 static int parse_hash_table_type(struct context *ctx, const struct token *token, 2927 const char *str, unsigned int len, void *buf, 2928 unsigned int size); 2929 static int 2930 parse_quota_state_name(struct context *ctx, const struct token *token, 2931 const char *str, unsigned int len, void *buf, 2932 unsigned int size); 2933 static int 2934 parse_quota_mode_name(struct context *ctx, const struct token *token, 2935 const char *str, unsigned int len, void *buf, 2936 unsigned int size); 2937 static int 2938 parse_quota_update_name(struct context *ctx, const struct token *token, 2939 const char *str, unsigned int len, void *buf, 2940 unsigned int size); 2941 static int 2942 parse_qu_mode_name(struct context *ctx, const struct token *token, 2943 const char *str, unsigned int len, void *buf, 2944 unsigned int size); 2945 static int comp_none(struct context *, const struct token *, 2946 unsigned int, char *, unsigned int); 2947 static int comp_boolean(struct context *, const struct token *, 2948 unsigned int, char *, unsigned int); 2949 static int comp_action(struct context *, const struct token *, 2950 unsigned int, char *, unsigned int); 2951 static int comp_port(struct context *, const struct token *, 2952 unsigned int, char *, unsigned int); 2953 static int comp_rule_id(struct context *, const struct token *, 2954 unsigned int, char *, unsigned int); 2955 static int comp_vc_action_rss_type(struct context *, const struct token *, 2956 unsigned int, char *, unsigned int); 2957 static int comp_vc_action_rss_queue(struct context *, const struct token *, 2958 unsigned int, char *, unsigned int); 2959 static int comp_set_raw_index(struct context *, const struct token *, 2960 unsigned int, char *, unsigned int); 2961 static int comp_set_sample_index(struct context *, const struct token *, 2962 unsigned int, char *, unsigned int); 2963 static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 2964 unsigned int ent, char *buf, unsigned int size); 2965 static int comp_set_modify_field_op(struct context *, const struct token *, 2966 unsigned int, char *, unsigned int); 2967 static int comp_set_modify_field_id(struct context *, const struct token *, 2968 unsigned int, char *, unsigned int); 2969 static int comp_pattern_template_id(struct context *, const struct token *, 2970 unsigned int, char *, unsigned int); 2971 static int comp_actions_template_id(struct context *, const struct token *, 2972 unsigned int, char *, unsigned int); 2973 static int comp_table_id(struct context *, const struct token *, 2974 unsigned int, char *, unsigned int); 2975 static int comp_queue_id(struct context *, const struct token *, 2976 unsigned int, char *, unsigned int); 2977 static int comp_meter_color(struct context *, const struct token *, 2978 unsigned int, char *, unsigned int); 2979 static int comp_insertion_table_type(struct context *, const struct token *, 2980 unsigned int, char *, unsigned int); 2981 static int comp_hash_table_type(struct context *, const struct token *, 2982 unsigned int, char *, unsigned int); 2983 static int 2984 comp_quota_state_name(struct context *ctx, const struct token *token, 2985 unsigned int ent, char *buf, unsigned int size); 2986 static int 2987 comp_quota_mode_name(struct context *ctx, const struct token *token, 2988 unsigned int ent, char *buf, unsigned int size); 2989 static int 2990 comp_quota_update_name(struct context *ctx, const struct token *token, 2991 unsigned int ent, char *buf, unsigned int size); 2992 static int 2993 comp_qu_mode_name(struct context *ctx, const struct token *token, 2994 unsigned int ent, char *buf, unsigned int size); 2995 static int 2996 comp_set_compare_field_id(struct context *ctx, const struct token *token, 2997 unsigned int ent, char *buf, unsigned int size); 2998 static int 2999 comp_set_compare_op(struct context *ctx, const struct token *token, 3000 unsigned int ent, char *buf, unsigned int size); 3001 static int 3002 parse_vc_compare_op(struct context *ctx, const struct token *token, 3003 const char *str, unsigned int len, void *buf, 3004 unsigned int size); 3005 static int 3006 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 3007 const char *str, unsigned int len, void *buf, 3008 unsigned int size); 3009 static int 3010 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 3011 const char *str, unsigned int len, void *buf, 3012 unsigned int size); 3013 3014 struct indlst_conf { 3015 uint32_t id; 3016 uint32_t conf_num; 3017 struct rte_flow_action *actions; 3018 const void **conf; 3019 SLIST_ENTRY(indlst_conf) next; 3020 }; 3021 3022 static const struct indlst_conf *indirect_action_list_conf_get(uint32_t conf_id); 3023 3024 /** Token definitions. */ 3025 static const struct token token_list[] = { 3026 /* Special tokens. */ 3027 [ZERO] = { 3028 .name = "ZERO", 3029 .help = "null entry, abused as the entry point", 3030 .next = NEXT(NEXT_ENTRY(FLOW, ADD)), 3031 }, 3032 [END] = { 3033 .name = "", 3034 .type = "RETURN", 3035 .help = "command may end here", 3036 }, 3037 [START_SET] = { 3038 .name = "START_SET", 3039 .help = "null entry, abused as the entry point for set", 3040 .next = NEXT(NEXT_ENTRY(SET)), 3041 }, 3042 [END_SET] = { 3043 .name = "end_set", 3044 .type = "RETURN", 3045 .help = "set command may end here", 3046 }, 3047 /* Common tokens. */ 3048 [COMMON_INTEGER] = { 3049 .name = "{int}", 3050 .type = "INTEGER", 3051 .help = "integer value", 3052 .call = parse_int, 3053 .comp = comp_none, 3054 }, 3055 [COMMON_UNSIGNED] = { 3056 .name = "{unsigned}", 3057 .type = "UNSIGNED", 3058 .help = "unsigned integer value", 3059 .call = parse_int, 3060 .comp = comp_none, 3061 }, 3062 [COMMON_PREFIX] = { 3063 .name = "{prefix}", 3064 .type = "PREFIX", 3065 .help = "prefix length for bit-mask", 3066 .call = parse_prefix, 3067 .comp = comp_none, 3068 }, 3069 [COMMON_BOOLEAN] = { 3070 .name = "{boolean}", 3071 .type = "BOOLEAN", 3072 .help = "any boolean value", 3073 .call = parse_boolean, 3074 .comp = comp_boolean, 3075 }, 3076 [COMMON_STRING] = { 3077 .name = "{string}", 3078 .type = "STRING", 3079 .help = "fixed string", 3080 .call = parse_string, 3081 .comp = comp_none, 3082 }, 3083 [COMMON_HEX] = { 3084 .name = "{hex}", 3085 .type = "HEX", 3086 .help = "fixed string", 3087 .call = parse_hex, 3088 }, 3089 [COMMON_FILE_PATH] = { 3090 .name = "{file path}", 3091 .type = "STRING", 3092 .help = "file path", 3093 .call = parse_string0, 3094 .comp = comp_none, 3095 }, 3096 [COMMON_MAC_ADDR] = { 3097 .name = "{MAC address}", 3098 .type = "MAC-48", 3099 .help = "standard MAC address notation", 3100 .call = parse_mac_addr, 3101 .comp = comp_none, 3102 }, 3103 [COMMON_IPV4_ADDR] = { 3104 .name = "{IPv4 address}", 3105 .type = "IPV4 ADDRESS", 3106 .help = "standard IPv4 address notation", 3107 .call = parse_ipv4_addr, 3108 .comp = comp_none, 3109 }, 3110 [COMMON_IPV6_ADDR] = { 3111 .name = "{IPv6 address}", 3112 .type = "IPV6 ADDRESS", 3113 .help = "standard IPv6 address notation", 3114 .call = parse_ipv6_addr, 3115 .comp = comp_none, 3116 }, 3117 [COMMON_RULE_ID] = { 3118 .name = "{rule id}", 3119 .type = "RULE ID", 3120 .help = "rule identifier", 3121 .call = parse_int, 3122 .comp = comp_rule_id, 3123 }, 3124 [COMMON_PORT_ID] = { 3125 .name = "{port_id}", 3126 .type = "PORT ID", 3127 .help = "port identifier", 3128 .call = parse_port, 3129 .comp = comp_port, 3130 }, 3131 [COMMON_GROUP_ID] = { 3132 .name = "{group_id}", 3133 .type = "GROUP ID", 3134 .help = "group identifier", 3135 .call = parse_int, 3136 .comp = comp_none, 3137 }, 3138 [COMMON_PRIORITY_LEVEL] = { 3139 .name = "{level}", 3140 .type = "PRIORITY", 3141 .help = "priority level", 3142 .call = parse_int, 3143 .comp = comp_none, 3144 }, 3145 [COMMON_INDIRECT_ACTION_ID] = { 3146 .name = "{indirect_action_id}", 3147 .type = "INDIRECT_ACTION_ID", 3148 .help = "indirect action id", 3149 .call = parse_int, 3150 .comp = comp_none, 3151 }, 3152 [COMMON_PROFILE_ID] = { 3153 .name = "{profile_id}", 3154 .type = "PROFILE_ID", 3155 .help = "profile id", 3156 .call = parse_int, 3157 .comp = comp_none, 3158 }, 3159 [COMMON_POLICY_ID] = { 3160 .name = "{policy_id}", 3161 .type = "POLICY_ID", 3162 .help = "policy id", 3163 .call = parse_int, 3164 .comp = comp_none, 3165 }, 3166 [COMMON_FLEX_TOKEN] = { 3167 .name = "{flex token}", 3168 .type = "flex token", 3169 .help = "flex token", 3170 .call = parse_int, 3171 .comp = comp_none, 3172 }, 3173 [COMMON_FLEX_HANDLE] = { 3174 .name = "{flex handle}", 3175 .type = "FLEX HANDLE", 3176 .help = "fill flex item data", 3177 .call = parse_flex_handle, 3178 .comp = comp_none, 3179 }, 3180 [COMMON_PATTERN_TEMPLATE_ID] = { 3181 .name = "{pattern_template_id}", 3182 .type = "PATTERN_TEMPLATE_ID", 3183 .help = "pattern template id", 3184 .call = parse_int, 3185 .comp = comp_pattern_template_id, 3186 }, 3187 [COMMON_ACTIONS_TEMPLATE_ID] = { 3188 .name = "{actions_template_id}", 3189 .type = "ACTIONS_TEMPLATE_ID", 3190 .help = "actions template id", 3191 .call = parse_int, 3192 .comp = comp_actions_template_id, 3193 }, 3194 [COMMON_TABLE_ID] = { 3195 .name = "{table_id}", 3196 .type = "TABLE_ID", 3197 .help = "table id", 3198 .call = parse_int, 3199 .comp = comp_table_id, 3200 }, 3201 [COMMON_QUEUE_ID] = { 3202 .name = "{queue_id}", 3203 .type = "QUEUE_ID", 3204 .help = "queue id", 3205 .call = parse_int, 3206 .comp = comp_queue_id, 3207 }, 3208 /* Top-level command. */ 3209 [FLOW] = { 3210 .name = "flow", 3211 .type = "{command} {port_id} [{arg} [...]]", 3212 .help = "manage ingress/egress flow rules", 3213 .next = NEXT(NEXT_ENTRY 3214 (INFO, 3215 CONFIGURE, 3216 PATTERN_TEMPLATE, 3217 ACTIONS_TEMPLATE, 3218 TABLE, 3219 FLOW_GROUP, 3220 INDIRECT_ACTION, 3221 VALIDATE, 3222 CREATE, 3223 DESTROY, 3224 UPDATE, 3225 FLUSH, 3226 DUMP, 3227 LIST, 3228 AGED, 3229 QUERY, 3230 ISOLATE, 3231 TUNNEL, 3232 FLEX, 3233 QUEUE, 3234 PUSH, 3235 PULL, 3236 HASH)), 3237 .call = parse_init, 3238 }, 3239 /* Top-level command. */ 3240 [INFO] = { 3241 .name = "info", 3242 .help = "get information about flow engine", 3243 .next = NEXT(NEXT_ENTRY(END), 3244 NEXT_ENTRY(COMMON_PORT_ID)), 3245 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3246 .call = parse_configure, 3247 }, 3248 /* Top-level command. */ 3249 [CONFIGURE] = { 3250 .name = "configure", 3251 .help = "configure flow engine", 3252 .next = NEXT(next_config_attr, 3253 NEXT_ENTRY(COMMON_PORT_ID)), 3254 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3255 .call = parse_configure, 3256 }, 3257 /* Configure arguments. */ 3258 [CONFIG_QUEUES_NUMBER] = { 3259 .name = "queues_number", 3260 .help = "number of queues", 3261 .next = NEXT(next_config_attr, 3262 NEXT_ENTRY(COMMON_UNSIGNED)), 3263 .args = ARGS(ARGS_ENTRY(struct buffer, 3264 args.configure.nb_queue)), 3265 }, 3266 [CONFIG_QUEUES_SIZE] = { 3267 .name = "queues_size", 3268 .help = "number of elements in queues", 3269 .next = NEXT(next_config_attr, 3270 NEXT_ENTRY(COMMON_UNSIGNED)), 3271 .args = ARGS(ARGS_ENTRY(struct buffer, 3272 args.configure.queue_attr.size)), 3273 }, 3274 [CONFIG_COUNTERS_NUMBER] = { 3275 .name = "counters_number", 3276 .help = "number of counters", 3277 .next = NEXT(next_config_attr, 3278 NEXT_ENTRY(COMMON_UNSIGNED)), 3279 .args = ARGS(ARGS_ENTRY(struct buffer, 3280 args.configure.port_attr.nb_counters)), 3281 }, 3282 [CONFIG_AGING_OBJECTS_NUMBER] = { 3283 .name = "aging_counters_number", 3284 .help = "number of aging objects", 3285 .next = NEXT(next_config_attr, 3286 NEXT_ENTRY(COMMON_UNSIGNED)), 3287 .args = ARGS(ARGS_ENTRY(struct buffer, 3288 args.configure.port_attr.nb_aging_objects)), 3289 }, 3290 [CONFIG_QUOTAS_NUMBER] = { 3291 .name = "quotas_number", 3292 .help = "number of quotas", 3293 .next = NEXT(next_config_attr, 3294 NEXT_ENTRY(COMMON_UNSIGNED)), 3295 .args = ARGS(ARGS_ENTRY(struct buffer, 3296 args.configure.port_attr.nb_quotas)), 3297 }, 3298 [CONFIG_METERS_NUMBER] = { 3299 .name = "meters_number", 3300 .help = "number of meters", 3301 .next = NEXT(next_config_attr, 3302 NEXT_ENTRY(COMMON_UNSIGNED)), 3303 .args = ARGS(ARGS_ENTRY(struct buffer, 3304 args.configure.port_attr.nb_meters)), 3305 }, 3306 [CONFIG_CONN_TRACK_NUMBER] = { 3307 .name = "conn_tracks_number", 3308 .help = "number of connection trackings", 3309 .next = NEXT(next_config_attr, 3310 NEXT_ENTRY(COMMON_UNSIGNED)), 3311 .args = ARGS(ARGS_ENTRY(struct buffer, 3312 args.configure.port_attr.nb_conn_tracks)), 3313 }, 3314 [CONFIG_FLAGS] = { 3315 .name = "flags", 3316 .help = "configuration flags", 3317 .next = NEXT(next_config_attr, 3318 NEXT_ENTRY(COMMON_UNSIGNED)), 3319 .args = ARGS(ARGS_ENTRY(struct buffer, 3320 args.configure.port_attr.flags)), 3321 }, 3322 [CONFIG_HOST_PORT] = { 3323 .name = "host_port", 3324 .help = "host port for shared objects", 3325 .next = NEXT(next_config_attr, 3326 NEXT_ENTRY(COMMON_UNSIGNED)), 3327 .args = ARGS(ARGS_ENTRY(struct buffer, 3328 args.configure.port_attr.host_port_id)), 3329 }, 3330 /* Top-level command. */ 3331 [PATTERN_TEMPLATE] = { 3332 .name = "pattern_template", 3333 .type = "{command} {port_id} [{arg} [...]]", 3334 .help = "manage pattern templates", 3335 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3336 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3337 .call = parse_template, 3338 }, 3339 /* Sub-level commands. */ 3340 [PATTERN_TEMPLATE_CREATE] = { 3341 .name = "create", 3342 .help = "create pattern template", 3343 .next = NEXT(next_pt_attr), 3344 .call = parse_template, 3345 }, 3346 [PATTERN_TEMPLATE_DESTROY] = { 3347 .name = "destroy", 3348 .help = "destroy pattern template", 3349 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), 3350 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3351 .call = parse_template_destroy, 3352 }, 3353 /* Pattern template arguments. */ 3354 [PATTERN_TEMPLATE_CREATE_ID] = { 3355 .name = "pattern_template_id", 3356 .help = "specify a pattern template id to create", 3357 .next = NEXT(next_pt_attr, 3358 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3359 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), 3360 }, 3361 [PATTERN_TEMPLATE_DESTROY_ID] = { 3362 .name = "pattern_template", 3363 .help = "specify a pattern template id to destroy", 3364 .next = NEXT(next_pt_destroy_attr, 3365 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3366 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3367 args.templ_destroy.template_id)), 3368 .call = parse_template_destroy, 3369 }, 3370 [PATTERN_TEMPLATE_RELAXED_MATCHING] = { 3371 .name = "relaxed", 3372 .help = "is matching relaxed", 3373 .next = NEXT(next_pt_attr, 3374 NEXT_ENTRY(COMMON_BOOLEAN)), 3375 .args = ARGS(ARGS_ENTRY_BF(struct buffer, 3376 args.vc.attr.reserved, 1)), 3377 }, 3378 [PATTERN_TEMPLATE_INGRESS] = { 3379 .name = "ingress", 3380 .help = "attribute pattern to ingress", 3381 .next = NEXT(next_pt_attr), 3382 .call = parse_template, 3383 }, 3384 [PATTERN_TEMPLATE_EGRESS] = { 3385 .name = "egress", 3386 .help = "attribute pattern to egress", 3387 .next = NEXT(next_pt_attr), 3388 .call = parse_template, 3389 }, 3390 [PATTERN_TEMPLATE_TRANSFER] = { 3391 .name = "transfer", 3392 .help = "attribute pattern to transfer", 3393 .next = NEXT(next_pt_attr), 3394 .call = parse_template, 3395 }, 3396 [PATTERN_TEMPLATE_SPEC] = { 3397 .name = "template", 3398 .help = "specify item to create pattern template", 3399 .next = NEXT(next_item), 3400 }, 3401 /* Top-level command. */ 3402 [ACTIONS_TEMPLATE] = { 3403 .name = "actions_template", 3404 .type = "{command} {port_id} [{arg} [...]]", 3405 .help = "manage actions templates", 3406 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3407 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3408 .call = parse_template, 3409 }, 3410 /* Sub-level commands. */ 3411 [ACTIONS_TEMPLATE_CREATE] = { 3412 .name = "create", 3413 .help = "create actions template", 3414 .next = NEXT(next_at_attr), 3415 .call = parse_template, 3416 }, 3417 [ACTIONS_TEMPLATE_DESTROY] = { 3418 .name = "destroy", 3419 .help = "destroy actions template", 3420 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), 3421 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3422 .call = parse_template_destroy, 3423 }, 3424 /* Actions template arguments. */ 3425 [ACTIONS_TEMPLATE_CREATE_ID] = { 3426 .name = "actions_template_id", 3427 .help = "specify an actions template id to create", 3428 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), 3429 NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), 3430 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3431 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), 3432 }, 3433 [ACTIONS_TEMPLATE_DESTROY_ID] = { 3434 .name = "actions_template", 3435 .help = "specify an actions template id to destroy", 3436 .next = NEXT(next_at_destroy_attr, 3437 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3438 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3439 args.templ_destroy.template_id)), 3440 .call = parse_template_destroy, 3441 }, 3442 [ACTIONS_TEMPLATE_INGRESS] = { 3443 .name = "ingress", 3444 .help = "attribute actions to ingress", 3445 .next = NEXT(next_at_attr), 3446 .call = parse_template, 3447 }, 3448 [ACTIONS_TEMPLATE_EGRESS] = { 3449 .name = "egress", 3450 .help = "attribute actions to egress", 3451 .next = NEXT(next_at_attr), 3452 .call = parse_template, 3453 }, 3454 [ACTIONS_TEMPLATE_TRANSFER] = { 3455 .name = "transfer", 3456 .help = "attribute actions to transfer", 3457 .next = NEXT(next_at_attr), 3458 .call = parse_template, 3459 }, 3460 [ACTIONS_TEMPLATE_SPEC] = { 3461 .name = "template", 3462 .help = "specify action to create actions template", 3463 .next = NEXT(next_action), 3464 .call = parse_template, 3465 }, 3466 [ACTIONS_TEMPLATE_MASK] = { 3467 .name = "mask", 3468 .help = "specify action mask to create actions template", 3469 .next = NEXT(next_action), 3470 .call = parse_template, 3471 }, 3472 /* Top-level command. */ 3473 [TABLE] = { 3474 .name = "template_table", 3475 .type = "{command} {port_id} [{arg} [...]]", 3476 .help = "manage template tables", 3477 .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3478 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3479 .call = parse_table, 3480 }, 3481 /* Sub-level commands. */ 3482 [TABLE_CREATE] = { 3483 .name = "create", 3484 .help = "create template table", 3485 .next = NEXT(next_table_attr), 3486 .call = parse_table, 3487 }, 3488 [TABLE_DESTROY] = { 3489 .name = "destroy", 3490 .help = "destroy template table", 3491 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3492 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3493 .call = parse_table_destroy, 3494 }, 3495 [TABLE_RESIZE] = { 3496 .name = "resize", 3497 .help = "resize template table", 3498 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_ID)), 3499 .call = parse_table 3500 }, 3501 [TABLE_RESIZE_COMPLETE] = { 3502 .name = "resize_complete", 3503 .help = "complete table resize", 3504 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3505 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3506 .call = parse_table_destroy, 3507 }, 3508 /* Table arguments. */ 3509 [TABLE_CREATE_ID] = { 3510 .name = "table_id", 3511 .help = "specify table id to create", 3512 .next = NEXT(next_table_attr, 3513 NEXT_ENTRY(COMMON_TABLE_ID)), 3514 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3515 }, 3516 [TABLE_DESTROY_ID] = { 3517 .name = "table", 3518 .help = "table id", 3519 .next = NEXT(next_table_destroy_attr, 3520 NEXT_ENTRY(COMMON_TABLE_ID)), 3521 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3522 args.table_destroy.table_id)), 3523 .call = parse_table_destroy, 3524 }, 3525 [TABLE_RESIZE_ID] = { 3526 .name = "table_resize_id", 3527 .help = "table resize id", 3528 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_RULES_NUMBER), 3529 NEXT_ENTRY(COMMON_TABLE_ID)), 3530 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3531 .call = parse_table 3532 }, 3533 [TABLE_RESIZE_RULES_NUMBER] = { 3534 .name = "table_resize_rules_num", 3535 .help = "table resize rules number", 3536 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_UNSIGNED)), 3537 .args = ARGS(ARGS_ENTRY(struct buffer, 3538 args.table.attr.nb_flows)), 3539 .call = parse_table 3540 }, 3541 [TABLE_INSERTION_TYPE] = { 3542 .name = "insertion_type", 3543 .help = "specify insertion type", 3544 .next = NEXT(next_table_attr, 3545 NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)), 3546 .args = ARGS(ARGS_ENTRY(struct buffer, 3547 args.table.attr.insertion_type)), 3548 }, 3549 [TABLE_INSERTION_TYPE_NAME] = { 3550 .name = "insertion_type_name", 3551 .help = "insertion type name", 3552 .call = parse_insertion_table_type, 3553 .comp = comp_insertion_table_type, 3554 }, 3555 [TABLE_HASH_FUNC] = { 3556 .name = "hash_func", 3557 .help = "specify hash calculation function", 3558 .next = NEXT(next_table_attr, 3559 NEXT_ENTRY(TABLE_HASH_FUNC_NAME)), 3560 .args = ARGS(ARGS_ENTRY(struct buffer, 3561 args.table.attr.hash_func)), 3562 }, 3563 [TABLE_HASH_FUNC_NAME] = { 3564 .name = "hash_func_name", 3565 .help = "hash calculation function name", 3566 .call = parse_hash_table_type, 3567 .comp = comp_hash_table_type, 3568 }, 3569 [TABLE_GROUP] = { 3570 .name = "group", 3571 .help = "specify a group", 3572 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3573 .args = ARGS(ARGS_ENTRY(struct buffer, 3574 args.table.attr.flow_attr.group)), 3575 }, 3576 [TABLE_PRIORITY] = { 3577 .name = "priority", 3578 .help = "specify a priority level", 3579 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 3580 .args = ARGS(ARGS_ENTRY(struct buffer, 3581 args.table.attr.flow_attr.priority)), 3582 }, 3583 [TABLE_EGRESS] = { 3584 .name = "egress", 3585 .help = "affect rule to egress", 3586 .next = NEXT(next_table_attr), 3587 .call = parse_table, 3588 }, 3589 [TABLE_INGRESS] = { 3590 .name = "ingress", 3591 .help = "affect rule to ingress", 3592 .next = NEXT(next_table_attr), 3593 .call = parse_table, 3594 }, 3595 [TABLE_TRANSFER] = { 3596 .name = "transfer", 3597 .help = "affect rule to transfer", 3598 .next = NEXT(next_table_attr), 3599 .call = parse_table, 3600 }, 3601 [TABLE_TRANSFER_WIRE_ORIG] = { 3602 .name = "wire_orig", 3603 .help = "affect rule direction to transfer", 3604 .next = NEXT(next_table_attr), 3605 .call = parse_table, 3606 }, 3607 [TABLE_TRANSFER_VPORT_ORIG] = { 3608 .name = "vport_orig", 3609 .help = "affect rule direction to transfer", 3610 .next = NEXT(next_table_attr), 3611 .call = parse_table, 3612 }, 3613 [TABLE_RESIZABLE] = { 3614 .name = "resizable", 3615 .help = "set resizable attribute", 3616 .next = NEXT(next_table_attr), 3617 .call = parse_table, 3618 }, 3619 [TABLE_RULES_NUMBER] = { 3620 .name = "rules_number", 3621 .help = "number of rules in table", 3622 .next = NEXT(next_table_attr, 3623 NEXT_ENTRY(COMMON_UNSIGNED)), 3624 .args = ARGS(ARGS_ENTRY(struct buffer, 3625 args.table.attr.nb_flows)), 3626 .call = parse_table, 3627 }, 3628 [TABLE_PATTERN_TEMPLATE] = { 3629 .name = "pattern_template", 3630 .help = "specify pattern template id", 3631 .next = NEXT(next_table_attr, 3632 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3633 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3634 args.table.pat_templ_id)), 3635 .call = parse_table, 3636 }, 3637 [TABLE_ACTIONS_TEMPLATE] = { 3638 .name = "actions_template", 3639 .help = "specify actions template id", 3640 .next = NEXT(next_table_attr, 3641 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3642 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3643 args.table.act_templ_id)), 3644 .call = parse_table, 3645 }, 3646 /* Top-level command. */ 3647 [FLOW_GROUP] = { 3648 .name = "group", 3649 .help = "manage flow groups", 3650 .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), 3651 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3652 .call = parse_group, 3653 }, 3654 /* Sub-level commands. */ 3655 [GROUP_SET_MISS_ACTIONS] = { 3656 .name = "set_miss_actions", 3657 .help = "set group miss actions", 3658 .next = NEXT(next_action), 3659 .call = parse_group, 3660 }, 3661 /* Group arguments */ 3662 [GROUP_ID] = { 3663 .name = "group_id", 3664 .help = "group id", 3665 .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3666 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3667 }, 3668 [GROUP_INGRESS] = { 3669 .name = "ingress", 3670 .help = "group ingress attr", 3671 .next = NEXT(next_group_attr), 3672 .call = parse_group, 3673 }, 3674 [GROUP_EGRESS] = { 3675 .name = "egress", 3676 .help = "group egress attr", 3677 .next = NEXT(next_group_attr), 3678 .call = parse_group, 3679 }, 3680 [GROUP_TRANSFER] = { 3681 .name = "transfer", 3682 .help = "group transfer attr", 3683 .next = NEXT(next_group_attr), 3684 .call = parse_group, 3685 }, 3686 /* Top-level command. */ 3687 [QUEUE] = { 3688 .name = "queue", 3689 .help = "queue a flow rule operation", 3690 .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3691 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3692 .call = parse_qo, 3693 }, 3694 /* Sub-level commands. */ 3695 [QUEUE_CREATE] = { 3696 .name = "create", 3697 .help = "create a flow rule", 3698 .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), 3699 NEXT_ENTRY(COMMON_QUEUE_ID)), 3700 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3701 .call = parse_qo, 3702 }, 3703 [QUEUE_DESTROY] = { 3704 .name = "destroy", 3705 .help = "destroy a flow rule", 3706 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3707 NEXT_ENTRY(COMMON_QUEUE_ID)), 3708 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3709 .call = parse_qo_destroy, 3710 }, 3711 [QUEUE_FLOW_UPDATE_RESIZED] = { 3712 .name = "update_resized", 3713 .help = "update a flow after table resize", 3714 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3715 NEXT_ENTRY(COMMON_QUEUE_ID)), 3716 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3717 .call = parse_qo_destroy, 3718 }, 3719 [QUEUE_UPDATE] = { 3720 .name = "update", 3721 .help = "update a flow rule", 3722 .next = NEXT(NEXT_ENTRY(QUEUE_UPDATE_ID), 3723 NEXT_ENTRY(COMMON_QUEUE_ID)), 3724 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3725 .call = parse_qo, 3726 }, 3727 [QUEUE_AGED] = { 3728 .name = "aged", 3729 .help = "list and destroy aged flows", 3730 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), 3731 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3732 .call = parse_aged, 3733 }, 3734 [QUEUE_INDIRECT_ACTION] = { 3735 .name = "indirect_action", 3736 .help = "queue indirect actions", 3737 .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), 3738 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3739 .call = parse_qia, 3740 }, 3741 /* Queue arguments. */ 3742 [QUEUE_TEMPLATE_TABLE] = { 3743 .name = "template_table", 3744 .help = "specify table id", 3745 .next = NEXT(next_async_insert_subcmd, 3746 NEXT_ENTRY(COMMON_TABLE_ID)), 3747 .args = ARGS(ARGS_ENTRY(struct buffer, 3748 args.vc.table_id)), 3749 .call = parse_qo, 3750 }, 3751 [QUEUE_PATTERN_TEMPLATE] = { 3752 .name = "pattern_template", 3753 .help = "specify pattern template index", 3754 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3755 NEXT_ENTRY(COMMON_UNSIGNED)), 3756 .args = ARGS(ARGS_ENTRY(struct buffer, 3757 args.vc.pat_templ_id)), 3758 .call = parse_qo, 3759 }, 3760 [QUEUE_ACTIONS_TEMPLATE] = { 3761 .name = "actions_template", 3762 .help = "specify actions template index", 3763 .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), 3764 NEXT_ENTRY(COMMON_UNSIGNED)), 3765 .args = ARGS(ARGS_ENTRY(struct buffer, 3766 args.vc.act_templ_id)), 3767 .call = parse_qo, 3768 }, 3769 [QUEUE_RULE_ID] = { 3770 .name = "rule_index", 3771 .help = "specify flow rule index", 3772 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3773 NEXT_ENTRY(COMMON_UNSIGNED)), 3774 .args = ARGS(ARGS_ENTRY(struct buffer, 3775 args.vc.rule_id)), 3776 .call = parse_qo, 3777 }, 3778 [QUEUE_CREATE_POSTPONE] = { 3779 .name = "postpone", 3780 .help = "postpone create operation", 3781 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3782 NEXT_ENTRY(COMMON_BOOLEAN)), 3783 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3784 .call = parse_qo, 3785 }, 3786 [QUEUE_DESTROY_POSTPONE] = { 3787 .name = "postpone", 3788 .help = "postpone destroy operation", 3789 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3790 NEXT_ENTRY(COMMON_BOOLEAN)), 3791 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3792 .call = parse_qo_destroy, 3793 }, 3794 [QUEUE_DESTROY_ID] = { 3795 .name = "rule", 3796 .help = "specify rule id to destroy", 3797 .next = NEXT(next_queue_destroy_attr, 3798 NEXT_ENTRY(COMMON_UNSIGNED)), 3799 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3800 args.destroy.rule)), 3801 .call = parse_qo_destroy, 3802 }, 3803 [QUEUE_UPDATE_ID] = { 3804 .name = "rule", 3805 .help = "specify rule id to update", 3806 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3807 NEXT_ENTRY(COMMON_UNSIGNED)), 3808 .args = ARGS(ARGS_ENTRY(struct buffer, 3809 args.vc.rule_id)), 3810 .call = parse_qo, 3811 }, 3812 /* Queue indirect action arguments */ 3813 [QUEUE_INDIRECT_ACTION_CREATE] = { 3814 .name = "create", 3815 .help = "create indirect action", 3816 .next = NEXT(next_qia_create_attr), 3817 .call = parse_qia, 3818 }, 3819 [QUEUE_INDIRECT_ACTION_UPDATE] = { 3820 .name = "update", 3821 .help = "update indirect action", 3822 .next = NEXT(next_qia_update_attr, 3823 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3824 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3825 .call = parse_qia, 3826 }, 3827 [QUEUE_INDIRECT_ACTION_DESTROY] = { 3828 .name = "destroy", 3829 .help = "destroy indirect action", 3830 .next = NEXT(next_qia_destroy_attr), 3831 .call = parse_qia_destroy, 3832 }, 3833 [QUEUE_INDIRECT_ACTION_QUERY] = { 3834 .name = "query", 3835 .help = "query indirect action", 3836 .next = NEXT(next_qia_query_attr, 3837 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3838 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3839 .call = parse_qia, 3840 }, 3841 /* Indirect action destroy arguments. */ 3842 [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { 3843 .name = "postpone", 3844 .help = "postpone destroy operation", 3845 .next = NEXT(next_qia_destroy_attr, 3846 NEXT_ENTRY(COMMON_BOOLEAN)), 3847 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3848 }, 3849 [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { 3850 .name = "action_id", 3851 .help = "specify a indirect action id to destroy", 3852 .next = NEXT(next_qia_destroy_attr, 3853 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3854 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3855 args.ia_destroy.action_id)), 3856 .call = parse_qia_destroy, 3857 }, 3858 [QUEUE_INDIRECT_ACTION_QUERY_UPDATE] = { 3859 .name = "query_update", 3860 .help = "indirect query [and|or] update action", 3861 .next = NEXT(next_qia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3862 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3863 .call = parse_qia 3864 }, 3865 [QUEUE_INDIRECT_ACTION_QU_MODE] = { 3866 .name = "mode", 3867 .help = "indirect query [and|or] update action", 3868 .next = NEXT(next_qia_qu_attr, 3869 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 3870 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 3871 .call = parse_qia 3872 }, 3873 /* Indirect action update arguments. */ 3874 [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { 3875 .name = "postpone", 3876 .help = "postpone update operation", 3877 .next = NEXT(next_qia_update_attr, 3878 NEXT_ENTRY(COMMON_BOOLEAN)), 3879 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3880 }, 3881 /* Indirect action update arguments. */ 3882 [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { 3883 .name = "postpone", 3884 .help = "postpone query operation", 3885 .next = NEXT(next_qia_query_attr, 3886 NEXT_ENTRY(COMMON_BOOLEAN)), 3887 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3888 }, 3889 /* Indirect action create arguments. */ 3890 [QUEUE_INDIRECT_ACTION_CREATE_ID] = { 3891 .name = "action_id", 3892 .help = "specify a indirect action id to create", 3893 .next = NEXT(next_qia_create_attr, 3894 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3895 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3896 }, 3897 [QUEUE_INDIRECT_ACTION_INGRESS] = { 3898 .name = "ingress", 3899 .help = "affect rule to ingress", 3900 .next = NEXT(next_qia_create_attr), 3901 .call = parse_qia, 3902 }, 3903 [QUEUE_INDIRECT_ACTION_EGRESS] = { 3904 .name = "egress", 3905 .help = "affect rule to egress", 3906 .next = NEXT(next_qia_create_attr), 3907 .call = parse_qia, 3908 }, 3909 [QUEUE_INDIRECT_ACTION_TRANSFER] = { 3910 .name = "transfer", 3911 .help = "affect rule to transfer", 3912 .next = NEXT(next_qia_create_attr), 3913 .call = parse_qia, 3914 }, 3915 [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { 3916 .name = "postpone", 3917 .help = "postpone create operation", 3918 .next = NEXT(next_qia_create_attr, 3919 NEXT_ENTRY(COMMON_BOOLEAN)), 3920 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3921 }, 3922 [QUEUE_INDIRECT_ACTION_SPEC] = { 3923 .name = "action", 3924 .help = "specify action to create indirect handle", 3925 .next = NEXT(next_action), 3926 }, 3927 [QUEUE_INDIRECT_ACTION_LIST] = { 3928 .name = "list", 3929 .help = "specify actions for indirect handle list", 3930 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 3931 .call = parse_qia, 3932 }, 3933 /* Top-level command. */ 3934 [PUSH] = { 3935 .name = "push", 3936 .help = "push enqueued operations", 3937 .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3938 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3939 .call = parse_push, 3940 }, 3941 /* Sub-level commands. */ 3942 [PUSH_QUEUE] = { 3943 .name = "queue", 3944 .help = "specify queue id", 3945 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3946 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3947 }, 3948 /* Top-level command. */ 3949 [PULL] = { 3950 .name = "pull", 3951 .help = "pull flow operations results", 3952 .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3953 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3954 .call = parse_pull, 3955 }, 3956 /* Sub-level commands. */ 3957 [PULL_QUEUE] = { 3958 .name = "queue", 3959 .help = "specify queue id", 3960 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3961 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3962 }, 3963 /* Top-level command. */ 3964 [HASH] = { 3965 .name = "hash", 3966 .help = "calculate hash for a given pattern in a given template table", 3967 .next = NEXT(next_hash_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3968 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3969 .call = parse_hash, 3970 }, 3971 /* Sub-level commands. */ 3972 [HASH_CALC_TABLE] = { 3973 .name = "template_table", 3974 .help = "specify table id", 3975 .next = NEXT(NEXT_ENTRY(HASH_CALC_PATTERN_INDEX), 3976 NEXT_ENTRY(COMMON_TABLE_ID)), 3977 .args = ARGS(ARGS_ENTRY(struct buffer, 3978 args.vc.table_id)), 3979 .call = parse_hash, 3980 }, 3981 [HASH_CALC_ENCAP] = { 3982 .name = "encap", 3983 .help = "calculates encap hash", 3984 .next = NEXT(next_hash_encap_dest_subcmd), 3985 .call = parse_hash, 3986 }, 3987 [HASH_CALC_PATTERN_INDEX] = { 3988 .name = "pattern_template", 3989 .help = "specify pattern template id", 3990 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3991 NEXT_ENTRY(COMMON_UNSIGNED)), 3992 .args = ARGS(ARGS_ENTRY(struct buffer, 3993 args.vc.pat_templ_id)), 3994 .call = parse_hash, 3995 }, 3996 [ENCAP_HASH_FIELD_SRC_PORT] = { 3997 .name = "hash_field_sport", 3998 .help = "the encap hash field is src port", 3999 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 4000 .call = parse_hash, 4001 }, 4002 [ENCAP_HASH_FIELD_GRE_FLOW_ID] = { 4003 .name = "hash_field_flow_id", 4004 .help = "the encap hash field is NVGRE flow id", 4005 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 4006 .call = parse_hash, 4007 }, 4008 /* Top-level command. */ 4009 [INDIRECT_ACTION] = { 4010 .name = "indirect_action", 4011 .type = "{command} {port_id} [{arg} [...]]", 4012 .help = "manage indirect actions", 4013 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4014 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4015 .call = parse_ia, 4016 }, 4017 /* Sub-level commands. */ 4018 [INDIRECT_ACTION_CREATE] = { 4019 .name = "create", 4020 .help = "create indirect action", 4021 .next = NEXT(next_ia_create_attr), 4022 .call = parse_ia, 4023 }, 4024 [INDIRECT_ACTION_UPDATE] = { 4025 .name = "update", 4026 .help = "update indirect action", 4027 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), 4028 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4029 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 4030 .call = parse_ia, 4031 }, 4032 [INDIRECT_ACTION_DESTROY] = { 4033 .name = "destroy", 4034 .help = "destroy indirect action", 4035 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), 4036 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4037 .call = parse_ia_destroy, 4038 }, 4039 [INDIRECT_ACTION_QUERY] = { 4040 .name = "query", 4041 .help = "query indirect action", 4042 .next = NEXT(NEXT_ENTRY(END), 4043 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4044 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4045 .call = parse_ia, 4046 }, 4047 [INDIRECT_ACTION_QUERY_UPDATE] = { 4048 .name = "query_update", 4049 .help = "query [and|or] update", 4050 .next = NEXT(next_ia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4051 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4052 .call = parse_ia 4053 }, 4054 [INDIRECT_ACTION_QU_MODE] = { 4055 .name = "mode", 4056 .help = "query_update mode", 4057 .next = NEXT(next_ia_qu_attr, 4058 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 4059 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 4060 .call = parse_ia, 4061 }, 4062 [INDIRECT_ACTION_QU_MODE_NAME] = { 4063 .name = "mode_name", 4064 .help = "query-update mode name", 4065 .call = parse_qu_mode_name, 4066 .comp = comp_qu_mode_name, 4067 }, 4068 [VALIDATE] = { 4069 .name = "validate", 4070 .help = "check whether a flow rule can be created", 4071 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4072 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4073 .call = parse_vc, 4074 }, 4075 [CREATE] = { 4076 .name = "create", 4077 .help = "create a flow rule", 4078 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4079 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4080 .call = parse_vc, 4081 }, 4082 [DESTROY] = { 4083 .name = "destroy", 4084 .help = "destroy specific flow rules", 4085 .next = NEXT(next_destroy_attr, 4086 NEXT_ENTRY(COMMON_PORT_ID)), 4087 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4088 .call = parse_destroy, 4089 }, 4090 [UPDATE] = { 4091 .name = "update", 4092 .help = "update a flow rule with new actions", 4093 .next = NEXT(NEXT_ENTRY(VC_IS_USER_ID, END), 4094 NEXT_ENTRY(ACTIONS), 4095 NEXT_ENTRY(COMMON_RULE_ID), 4096 NEXT_ENTRY(COMMON_PORT_ID)), 4097 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.rule_id), 4098 ARGS_ENTRY(struct buffer, port)), 4099 .call = parse_vc, 4100 }, 4101 [FLUSH] = { 4102 .name = "flush", 4103 .help = "destroy all flow rules", 4104 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4105 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4106 .call = parse_flush, 4107 }, 4108 [DUMP] = { 4109 .name = "dump", 4110 .help = "dump single/all flow rules to file", 4111 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4112 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4113 .call = parse_dump, 4114 }, 4115 [QUERY] = { 4116 .name = "query", 4117 .help = "query an existing flow rule", 4118 .next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION), 4119 NEXT_ENTRY(COMMON_RULE_ID), 4120 NEXT_ENTRY(COMMON_PORT_ID)), 4121 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), 4122 ARGS_ENTRY(struct buffer, args.query.rule), 4123 ARGS_ENTRY(struct buffer, port)), 4124 .call = parse_query, 4125 }, 4126 [LIST] = { 4127 .name = "list", 4128 .help = "list existing flow rules", 4129 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4130 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4131 .call = parse_list, 4132 }, 4133 [AGED] = { 4134 .name = "aged", 4135 .help = "list and destroy aged flows", 4136 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4137 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4138 .call = parse_aged, 4139 }, 4140 [ISOLATE] = { 4141 .name = "isolate", 4142 .help = "restrict ingress traffic to the defined flow rules", 4143 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), 4144 NEXT_ENTRY(COMMON_PORT_ID)), 4145 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), 4146 ARGS_ENTRY(struct buffer, port)), 4147 .call = parse_isolate, 4148 }, 4149 [FLEX] = { 4150 .name = "flex_item", 4151 .help = "flex item API", 4152 .next = NEXT(next_flex_item), 4153 .call = parse_flex, 4154 }, 4155 [FLEX_ITEM_INIT] = { 4156 .name = "init", 4157 .help = "flex item init", 4158 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4159 ARGS_ENTRY(struct buffer, port)), 4160 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4161 NEXT_ENTRY(COMMON_PORT_ID)), 4162 .call = parse_flex 4163 }, 4164 [FLEX_ITEM_CREATE] = { 4165 .name = "create", 4166 .help = "flex item create", 4167 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), 4168 ARGS_ENTRY(struct buffer, args.flex.token), 4169 ARGS_ENTRY(struct buffer, port)), 4170 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), 4171 NEXT_ENTRY(COMMON_FLEX_TOKEN), 4172 NEXT_ENTRY(COMMON_PORT_ID)), 4173 .call = parse_flex 4174 }, 4175 [FLEX_ITEM_DESTROY] = { 4176 .name = "destroy", 4177 .help = "flex item destroy", 4178 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4179 ARGS_ENTRY(struct buffer, port)), 4180 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4181 NEXT_ENTRY(COMMON_PORT_ID)), 4182 .call = parse_flex 4183 }, 4184 [TUNNEL] = { 4185 .name = "tunnel", 4186 .help = "new tunnel API", 4187 .next = NEXT(NEXT_ENTRY 4188 (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), 4189 .call = parse_tunnel, 4190 }, 4191 /* Tunnel arguments. */ 4192 [TUNNEL_CREATE] = { 4193 .name = "create", 4194 .help = "create new tunnel object", 4195 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), 4196 NEXT_ENTRY(COMMON_PORT_ID)), 4197 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4198 .call = parse_tunnel, 4199 }, 4200 [TUNNEL_CREATE_TYPE] = { 4201 .name = "type", 4202 .help = "create new tunnel", 4203 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), 4204 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), 4205 .call = parse_tunnel, 4206 }, 4207 [TUNNEL_DESTROY] = { 4208 .name = "destroy", 4209 .help = "destroy tunnel", 4210 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), 4211 NEXT_ENTRY(COMMON_PORT_ID)), 4212 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4213 .call = parse_tunnel, 4214 }, 4215 [TUNNEL_DESTROY_ID] = { 4216 .name = "id", 4217 .help = "tunnel identifier to destroy", 4218 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), 4219 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4220 .call = parse_tunnel, 4221 }, 4222 [TUNNEL_LIST] = { 4223 .name = "list", 4224 .help = "list existing tunnels", 4225 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4226 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4227 .call = parse_tunnel, 4228 }, 4229 /* Destroy arguments. */ 4230 [DESTROY_RULE] = { 4231 .name = "rule", 4232 .help = "specify a rule identifier", 4233 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4234 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), 4235 .call = parse_destroy, 4236 }, 4237 [DESTROY_IS_USER_ID] = { 4238 .name = "user_id", 4239 .help = "rule identifier is user-id", 4240 .next = NEXT(next_destroy_attr), 4241 .call = parse_destroy, 4242 }, 4243 /* Dump arguments. */ 4244 [DUMP_ALL] = { 4245 .name = "all", 4246 .help = "dump all", 4247 .next = NEXT(next_dump_attr), 4248 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), 4249 .call = parse_dump, 4250 }, 4251 [DUMP_ONE] = { 4252 .name = "rule", 4253 .help = "dump one rule", 4254 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4255 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), 4256 ARGS_ENTRY(struct buffer, args.dump.rule)), 4257 .call = parse_dump, 4258 }, 4259 [DUMP_IS_USER_ID] = { 4260 .name = "user_id", 4261 .help = "rule identifier is user-id", 4262 .next = NEXT(next_dump_subcmd), 4263 .call = parse_dump, 4264 }, 4265 /* Query arguments. */ 4266 [QUERY_ACTION] = { 4267 .name = "{action}", 4268 .type = "ACTION", 4269 .help = "action to query, must be part of the rule", 4270 .call = parse_action, 4271 .comp = comp_action, 4272 }, 4273 [QUERY_IS_USER_ID] = { 4274 .name = "user_id", 4275 .help = "rule identifier is user-id", 4276 .next = NEXT(next_query_attr), 4277 .call = parse_query, 4278 }, 4279 /* List arguments. */ 4280 [LIST_GROUP] = { 4281 .name = "group", 4282 .help = "specify a group", 4283 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4284 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), 4285 .call = parse_list, 4286 }, 4287 [AGED_DESTROY] = { 4288 .name = "destroy", 4289 .help = "specify aged flows need be destroyed", 4290 .call = parse_aged, 4291 .comp = comp_none, 4292 }, 4293 /* Validate/create attributes. */ 4294 [VC_GROUP] = { 4295 .name = "group", 4296 .help = "specify a group", 4297 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4298 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), 4299 .call = parse_vc, 4300 }, 4301 [VC_PRIORITY] = { 4302 .name = "priority", 4303 .help = "specify a priority level", 4304 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 4305 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), 4306 .call = parse_vc, 4307 }, 4308 [VC_INGRESS] = { 4309 .name = "ingress", 4310 .help = "affect rule to ingress", 4311 .next = NEXT(next_vc_attr), 4312 .call = parse_vc, 4313 }, 4314 [VC_EGRESS] = { 4315 .name = "egress", 4316 .help = "affect rule to egress", 4317 .next = NEXT(next_vc_attr), 4318 .call = parse_vc, 4319 }, 4320 [VC_TRANSFER] = { 4321 .name = "transfer", 4322 .help = "apply rule directly to endpoints found in pattern", 4323 .next = NEXT(next_vc_attr), 4324 .call = parse_vc, 4325 }, 4326 [VC_TUNNEL_SET] = { 4327 .name = "tunnel_set", 4328 .help = "tunnel steer rule", 4329 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4330 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4331 .call = parse_vc, 4332 }, 4333 [VC_TUNNEL_MATCH] = { 4334 .name = "tunnel_match", 4335 .help = "tunnel match rule", 4336 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4337 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4338 .call = parse_vc, 4339 }, 4340 [VC_USER_ID] = { 4341 .name = "user_id", 4342 .help = "specify a user id to create", 4343 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4344 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)), 4345 .call = parse_vc, 4346 }, 4347 [VC_IS_USER_ID] = { 4348 .name = "user_id", 4349 .help = "rule identifier is user-id", 4350 .call = parse_vc, 4351 }, 4352 /* Validate/create pattern. */ 4353 [ITEM_PATTERN] = { 4354 .name = "pattern", 4355 .help = "submit a list of pattern items", 4356 .next = NEXT(next_item), 4357 .call = parse_vc, 4358 }, 4359 [ITEM_PARAM_IS] = { 4360 .name = "is", 4361 .help = "match value perfectly (with full bit-mask)", 4362 .call = parse_vc_spec, 4363 }, 4364 [ITEM_PARAM_SPEC] = { 4365 .name = "spec", 4366 .help = "match value according to configured bit-mask", 4367 .call = parse_vc_spec, 4368 }, 4369 [ITEM_PARAM_LAST] = { 4370 .name = "last", 4371 .help = "specify upper bound to establish a range", 4372 .call = parse_vc_spec, 4373 }, 4374 [ITEM_PARAM_MASK] = { 4375 .name = "mask", 4376 .help = "specify bit-mask with relevant bits set to one", 4377 .call = parse_vc_spec, 4378 }, 4379 [ITEM_PARAM_PREFIX] = { 4380 .name = "prefix", 4381 .help = "generate bit-mask from a prefix length", 4382 .call = parse_vc_spec, 4383 }, 4384 [ITEM_NEXT] = { 4385 .name = "/", 4386 .help = "specify next pattern item", 4387 .next = NEXT(next_item), 4388 }, 4389 [ITEM_END] = { 4390 .name = "end", 4391 .help = "end list of pattern items", 4392 .priv = PRIV_ITEM(END, 0), 4393 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 4394 .call = parse_vc, 4395 }, 4396 [ITEM_VOID] = { 4397 .name = "void", 4398 .help = "no-op pattern item", 4399 .priv = PRIV_ITEM(VOID, 0), 4400 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4401 .call = parse_vc, 4402 }, 4403 [ITEM_INVERT] = { 4404 .name = "invert", 4405 .help = "perform actions when pattern does not match", 4406 .priv = PRIV_ITEM(INVERT, 0), 4407 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4408 .call = parse_vc, 4409 }, 4410 [ITEM_ANY] = { 4411 .name = "any", 4412 .help = "match any protocol for the current layer", 4413 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), 4414 .next = NEXT(item_any), 4415 .call = parse_vc, 4416 }, 4417 [ITEM_ANY_NUM] = { 4418 .name = "num", 4419 .help = "number of layers covered", 4420 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4421 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), 4422 }, 4423 [ITEM_PORT_ID] = { 4424 .name = "port_id", 4425 .help = "match traffic from/to a given DPDK port ID", 4426 .priv = PRIV_ITEM(PORT_ID, 4427 sizeof(struct rte_flow_item_port_id)), 4428 .next = NEXT(item_port_id), 4429 .call = parse_vc, 4430 }, 4431 [ITEM_PORT_ID_ID] = { 4432 .name = "id", 4433 .help = "DPDK port ID", 4434 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), 4435 item_param), 4436 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), 4437 }, 4438 [ITEM_MARK] = { 4439 .name = "mark", 4440 .help = "match traffic against value set in previously matched rule", 4441 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), 4442 .next = NEXT(item_mark), 4443 .call = parse_vc, 4444 }, 4445 [ITEM_MARK_ID] = { 4446 .name = "id", 4447 .help = "Integer value to match against", 4448 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), 4449 item_param), 4450 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), 4451 }, 4452 [ITEM_RAW] = { 4453 .name = "raw", 4454 .help = "match an arbitrary byte string", 4455 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), 4456 .next = NEXT(item_raw), 4457 .call = parse_vc, 4458 }, 4459 [ITEM_RAW_RELATIVE] = { 4460 .name = "relative", 4461 .help = "look for pattern after the previous item", 4462 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4463 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4464 relative, 1)), 4465 }, 4466 [ITEM_RAW_SEARCH] = { 4467 .name = "search", 4468 .help = "search pattern from offset (see also limit)", 4469 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4470 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4471 search, 1)), 4472 }, 4473 [ITEM_RAW_OFFSET] = { 4474 .name = "offset", 4475 .help = "absolute or relative offset for pattern", 4476 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), 4477 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), 4478 }, 4479 [ITEM_RAW_LIMIT] = { 4480 .name = "limit", 4481 .help = "search area limit for start of pattern", 4482 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4483 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), 4484 }, 4485 [ITEM_RAW_PATTERN] = { 4486 .name = "pattern", 4487 .help = "byte string to look for", 4488 .next = NEXT(item_raw, 4489 NEXT_ENTRY(COMMON_STRING), 4490 NEXT_ENTRY(ITEM_PARAM_IS, 4491 ITEM_PARAM_SPEC, 4492 ITEM_PARAM_MASK)), 4493 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4494 ARGS_ENTRY(struct rte_flow_item_raw, length), 4495 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4496 ITEM_RAW_PATTERN_SIZE)), 4497 }, 4498 [ITEM_RAW_PATTERN_HEX] = { 4499 .name = "pattern_hex", 4500 .help = "hex string to look for", 4501 .next = NEXT(item_raw, 4502 NEXT_ENTRY(COMMON_HEX), 4503 NEXT_ENTRY(ITEM_PARAM_IS, 4504 ITEM_PARAM_SPEC, 4505 ITEM_PARAM_MASK)), 4506 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4507 ARGS_ENTRY(struct rte_flow_item_raw, length), 4508 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4509 ITEM_RAW_PATTERN_SIZE)), 4510 }, 4511 [ITEM_ETH] = { 4512 .name = "eth", 4513 .help = "match Ethernet header", 4514 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), 4515 .next = NEXT(item_eth), 4516 .call = parse_vc, 4517 }, 4518 [ITEM_ETH_DST] = { 4519 .name = "dst", 4520 .help = "destination MAC", 4521 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4522 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), 4523 }, 4524 [ITEM_ETH_SRC] = { 4525 .name = "src", 4526 .help = "source MAC", 4527 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4528 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), 4529 }, 4530 [ITEM_ETH_TYPE] = { 4531 .name = "type", 4532 .help = "EtherType", 4533 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4534 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), 4535 }, 4536 [ITEM_ETH_HAS_VLAN] = { 4537 .name = "has_vlan", 4538 .help = "packet header contains VLAN", 4539 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4540 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, 4541 has_vlan, 1)), 4542 }, 4543 [ITEM_VLAN] = { 4544 .name = "vlan", 4545 .help = "match 802.1Q/ad VLAN tag", 4546 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), 4547 .next = NEXT(item_vlan), 4548 .call = parse_vc, 4549 }, 4550 [ITEM_VLAN_TCI] = { 4551 .name = "tci", 4552 .help = "tag control information", 4553 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4554 item_param), 4555 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, hdr.vlan_tci)), 4556 }, 4557 [ITEM_VLAN_PCP] = { 4558 .name = "pcp", 4559 .help = "priority code point", 4560 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4561 item_param), 4562 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4563 hdr.vlan_tci, "\xe0\x00")), 4564 }, 4565 [ITEM_VLAN_DEI] = { 4566 .name = "dei", 4567 .help = "drop eligible indicator", 4568 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4569 item_param), 4570 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4571 hdr.vlan_tci, "\x10\x00")), 4572 }, 4573 [ITEM_VLAN_VID] = { 4574 .name = "vid", 4575 .help = "VLAN identifier", 4576 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4577 item_param), 4578 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4579 hdr.vlan_tci, "\x0f\xff")), 4580 }, 4581 [ITEM_VLAN_INNER_TYPE] = { 4582 .name = "inner_type", 4583 .help = "inner EtherType", 4584 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4585 item_param), 4586 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, 4587 hdr.eth_proto)), 4588 }, 4589 [ITEM_VLAN_HAS_MORE_VLAN] = { 4590 .name = "has_more_vlan", 4591 .help = "packet header contains another VLAN", 4592 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4593 item_param), 4594 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, 4595 has_more_vlan, 1)), 4596 }, 4597 [ITEM_IPV4] = { 4598 .name = "ipv4", 4599 .help = "match IPv4 header", 4600 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), 4601 .next = NEXT(item_ipv4), 4602 .call = parse_vc, 4603 }, 4604 [ITEM_IPV4_VER_IHL] = { 4605 .name = "version_ihl", 4606 .help = "match header length", 4607 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4608 item_param), 4609 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, 4610 hdr.version_ihl)), 4611 }, 4612 [ITEM_IPV4_TOS] = { 4613 .name = "tos", 4614 .help = "type of service", 4615 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4616 item_param), 4617 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4618 hdr.type_of_service)), 4619 }, 4620 [ITEM_IPV4_LENGTH] = { 4621 .name = "length", 4622 .help = "total length", 4623 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4624 item_param), 4625 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4626 hdr.total_length)), 4627 }, 4628 [ITEM_IPV4_ID] = { 4629 .name = "packet_id", 4630 .help = "fragment packet id", 4631 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4632 item_param), 4633 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4634 hdr.packet_id)), 4635 }, 4636 [ITEM_IPV4_FRAGMENT_OFFSET] = { 4637 .name = "fragment_offset", 4638 .help = "fragmentation flags and fragment offset", 4639 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4640 item_param), 4641 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4642 hdr.fragment_offset)), 4643 }, 4644 [ITEM_IPV4_TTL] = { 4645 .name = "ttl", 4646 .help = "time to live", 4647 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4648 item_param), 4649 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4650 hdr.time_to_live)), 4651 }, 4652 [ITEM_IPV4_PROTO] = { 4653 .name = "proto", 4654 .help = "next protocol ID", 4655 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4656 item_param), 4657 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4658 hdr.next_proto_id)), 4659 }, 4660 [ITEM_IPV4_SRC] = { 4661 .name = "src", 4662 .help = "source address", 4663 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4664 item_param), 4665 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4666 hdr.src_addr)), 4667 }, 4668 [ITEM_IPV4_DST] = { 4669 .name = "dst", 4670 .help = "destination address", 4671 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4672 item_param), 4673 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4674 hdr.dst_addr)), 4675 }, 4676 [ITEM_IPV6] = { 4677 .name = "ipv6", 4678 .help = "match IPv6 header", 4679 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), 4680 .next = NEXT(item_ipv6), 4681 .call = parse_vc, 4682 }, 4683 [ITEM_IPV6_TC] = { 4684 .name = "tc", 4685 .help = "traffic class", 4686 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4687 item_param), 4688 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4689 hdr.vtc_flow, 4690 "\x0f\xf0\x00\x00")), 4691 }, 4692 [ITEM_IPV6_FLOW] = { 4693 .name = "flow", 4694 .help = "flow label", 4695 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4696 item_param), 4697 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4698 hdr.vtc_flow, 4699 "\x00\x0f\xff\xff")), 4700 }, 4701 [ITEM_IPV6_LEN] = { 4702 .name = "length", 4703 .help = "payload length", 4704 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4705 item_param), 4706 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4707 hdr.payload_len)), 4708 }, 4709 [ITEM_IPV6_PROTO] = { 4710 .name = "proto", 4711 .help = "protocol (next header)", 4712 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4713 item_param), 4714 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4715 hdr.proto)), 4716 }, 4717 [ITEM_IPV6_HOP] = { 4718 .name = "hop", 4719 .help = "hop limit", 4720 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4721 item_param), 4722 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4723 hdr.hop_limits)), 4724 }, 4725 [ITEM_IPV6_SRC] = { 4726 .name = "src", 4727 .help = "source address", 4728 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4729 item_param), 4730 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4731 hdr.src_addr)), 4732 }, 4733 [ITEM_IPV6_DST] = { 4734 .name = "dst", 4735 .help = "destination address", 4736 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4737 item_param), 4738 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4739 hdr.dst_addr)), 4740 }, 4741 [ITEM_IPV6_HAS_FRAG_EXT] = { 4742 .name = "has_frag_ext", 4743 .help = "fragment packet attribute", 4744 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4745 item_param), 4746 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, 4747 has_frag_ext, 1)), 4748 }, 4749 [ITEM_IPV6_ROUTING_EXT] = { 4750 .name = "ipv6_routing_ext", 4751 .help = "match IPv6 routing extension header", 4752 .priv = PRIV_ITEM(IPV6_ROUTING_EXT, 4753 sizeof(struct rte_flow_item_ipv6_routing_ext)), 4754 .next = NEXT(item_ipv6_routing_ext), 4755 .call = parse_vc, 4756 }, 4757 [ITEM_IPV6_ROUTING_EXT_TYPE] = { 4758 .name = "ext_type", 4759 .help = "match IPv6 routing extension header type", 4760 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4761 item_param), 4762 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4763 hdr.type)), 4764 }, 4765 [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = { 4766 .name = "ext_next_hdr", 4767 .help = "match IPv6 routing extension header next header type", 4768 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4769 item_param), 4770 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4771 hdr.next_hdr)), 4772 }, 4773 [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = { 4774 .name = "ext_seg_left", 4775 .help = "match IPv6 routing extension header segment left", 4776 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4777 item_param), 4778 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4779 hdr.segments_left)), 4780 }, 4781 [ITEM_ICMP] = { 4782 .name = "icmp", 4783 .help = "match ICMP header", 4784 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), 4785 .next = NEXT(item_icmp), 4786 .call = parse_vc, 4787 }, 4788 [ITEM_ICMP_TYPE] = { 4789 .name = "type", 4790 .help = "ICMP packet type", 4791 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4792 item_param), 4793 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4794 hdr.icmp_type)), 4795 }, 4796 [ITEM_ICMP_CODE] = { 4797 .name = "code", 4798 .help = "ICMP packet code", 4799 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4800 item_param), 4801 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4802 hdr.icmp_code)), 4803 }, 4804 [ITEM_ICMP_IDENT] = { 4805 .name = "ident", 4806 .help = "ICMP packet identifier", 4807 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4808 item_param), 4809 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4810 hdr.icmp_ident)), 4811 }, 4812 [ITEM_ICMP_SEQ] = { 4813 .name = "seq", 4814 .help = "ICMP packet sequence number", 4815 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4816 item_param), 4817 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4818 hdr.icmp_seq_nb)), 4819 }, 4820 [ITEM_UDP] = { 4821 .name = "udp", 4822 .help = "match UDP header", 4823 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), 4824 .next = NEXT(item_udp), 4825 .call = parse_vc, 4826 }, 4827 [ITEM_UDP_SRC] = { 4828 .name = "src", 4829 .help = "UDP source port", 4830 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), 4831 item_param), 4832 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4833 hdr.src_port)), 4834 }, 4835 [ITEM_UDP_DST] = { 4836 .name = "dst", 4837 .help = "UDP destination port", 4838 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4839 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4840 hdr.dst_port)), 4841 }, 4842 [ITEM_TCP] = { 4843 .name = "tcp", 4844 .help = "match TCP header", 4845 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), 4846 .next = NEXT(item_tcp), 4847 .call = parse_vc, 4848 }, 4849 [ITEM_TCP_SRC] = { 4850 .name = "src", 4851 .help = "TCP source port", 4852 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4853 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4854 hdr.src_port)), 4855 }, 4856 [ITEM_TCP_DST] = { 4857 .name = "dst", 4858 .help = "TCP destination port", 4859 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4860 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4861 hdr.dst_port)), 4862 }, 4863 [ITEM_TCP_FLAGS] = { 4864 .name = "flags", 4865 .help = "TCP flags", 4866 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4867 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4868 hdr.tcp_flags)), 4869 }, 4870 [ITEM_SCTP] = { 4871 .name = "sctp", 4872 .help = "match SCTP header", 4873 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), 4874 .next = NEXT(item_sctp), 4875 .call = parse_vc, 4876 }, 4877 [ITEM_SCTP_SRC] = { 4878 .name = "src", 4879 .help = "SCTP source port", 4880 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4881 item_param), 4882 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4883 hdr.src_port)), 4884 }, 4885 [ITEM_SCTP_DST] = { 4886 .name = "dst", 4887 .help = "SCTP destination port", 4888 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4889 item_param), 4890 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4891 hdr.dst_port)), 4892 }, 4893 [ITEM_SCTP_TAG] = { 4894 .name = "tag", 4895 .help = "validation tag", 4896 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4897 item_param), 4898 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4899 hdr.tag)), 4900 }, 4901 [ITEM_SCTP_CKSUM] = { 4902 .name = "cksum", 4903 .help = "checksum", 4904 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4905 item_param), 4906 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4907 hdr.cksum)), 4908 }, 4909 [ITEM_VXLAN] = { 4910 .name = "vxlan", 4911 .help = "match VXLAN header", 4912 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), 4913 .next = NEXT(item_vxlan), 4914 .call = parse_vc, 4915 }, 4916 [ITEM_VXLAN_VNI] = { 4917 .name = "vni", 4918 .help = "VXLAN identifier", 4919 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4920 item_param), 4921 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), 4922 }, 4923 [ITEM_VXLAN_FLAG_G] = { 4924 .name = "flag_g", 4925 .help = "VXLAN GBP bit", 4926 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4927 item_param), 4928 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4929 hdr.flag_g, 1)), 4930 }, 4931 [ITEM_VXLAN_FLAG_VER] = { 4932 .name = "flag_ver", 4933 .help = "VXLAN GPE version", 4934 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4935 item_param), 4936 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4937 hdr.flag_ver, 2)), 4938 }, 4939 [ITEM_VXLAN_FLAG_I] = { 4940 .name = "flag_i", 4941 .help = "VXLAN Instance bit", 4942 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4943 item_param), 4944 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4945 hdr.flag_i, 1)), 4946 }, 4947 [ITEM_VXLAN_FLAG_P] = { 4948 .name = "flag_p", 4949 .help = "VXLAN GPE Next Protocol bit", 4950 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4951 item_param), 4952 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4953 hdr.flag_p, 1)), 4954 }, 4955 [ITEM_VXLAN_FLAG_B] = { 4956 .name = "flag_b", 4957 .help = "VXLAN GPE Ingress-Replicated BUM", 4958 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4959 item_param), 4960 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4961 hdr.flag_b, 1)), 4962 }, 4963 [ITEM_VXLAN_FLAG_O] = { 4964 .name = "flag_o", 4965 .help = "VXLAN GPE OAM Packet bit", 4966 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4967 item_param), 4968 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4969 hdr.flag_o, 1)), 4970 }, 4971 [ITEM_VXLAN_FLAG_D] = { 4972 .name = "flag_d", 4973 .help = "VXLAN GBP Don't Learn bit", 4974 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4975 item_param), 4976 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4977 hdr.flag_d, 1)), 4978 }, 4979 [ITEM_VXLAN_FLAG_A] = { 4980 .name = "flag_a", 4981 .help = "VXLAN GBP Applied bit", 4982 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4983 item_param), 4984 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vxlan, 4985 hdr.flag_a, 1)), 4986 }, 4987 [ITEM_VXLAN_GBP_ID] = { 4988 .name = "group_policy_id", 4989 .help = "VXLAN GBP ID", 4990 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4991 item_param), 4992 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 4993 hdr.policy_id)), 4994 }, 4995 [ITEM_VXLAN_GPE_PROTO] = { 4996 .name = "protocol", 4997 .help = "VXLAN GPE next protocol", 4998 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4999 item_param), 5000 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5001 hdr.proto)), 5002 }, 5003 [ITEM_VXLAN_FIRST_RSVD] = { 5004 .name = "first_rsvd", 5005 .help = "VXLAN rsvd0 first byte", 5006 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5007 item_param), 5008 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5009 hdr.rsvd0[0])), 5010 }, 5011 [ITEM_VXLAN_SECND_RSVD] = { 5012 .name = "second_rsvd", 5013 .help = "VXLAN rsvd0 second byte", 5014 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5015 item_param), 5016 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5017 hdr.rsvd0[1])), 5018 }, 5019 [ITEM_VXLAN_THIRD_RSVD] = { 5020 .name = "third_rsvd", 5021 .help = "VXLAN rsvd0 third byte", 5022 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5023 item_param), 5024 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5025 hdr.rsvd0[2])), 5026 }, 5027 [ITEM_VXLAN_LAST_RSVD] = { 5028 .name = "last_rsvd", 5029 .help = "VXLAN last reserved byte", 5030 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 5031 item_param), 5032 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 5033 hdr.last_rsvd)), 5034 }, 5035 [ITEM_E_TAG] = { 5036 .name = "e_tag", 5037 .help = "match E-Tag header", 5038 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), 5039 .next = NEXT(item_e_tag), 5040 .call = parse_vc, 5041 }, 5042 [ITEM_E_TAG_GRP_ECID_B] = { 5043 .name = "grp_ecid_b", 5044 .help = "GRP and E-CID base", 5045 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5046 item_param), 5047 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, 5048 rsvd_grp_ecid_b, 5049 "\x3f\xff")), 5050 }, 5051 [ITEM_NVGRE] = { 5052 .name = "nvgre", 5053 .help = "match NVGRE header", 5054 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), 5055 .next = NEXT(item_nvgre), 5056 .call = parse_vc, 5057 }, 5058 [ITEM_NVGRE_TNI] = { 5059 .name = "tni", 5060 .help = "virtual subnet ID", 5061 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), 5062 item_param), 5063 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), 5064 }, 5065 [ITEM_MPLS] = { 5066 .name = "mpls", 5067 .help = "match MPLS header", 5068 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), 5069 .next = NEXT(item_mpls), 5070 .call = parse_vc, 5071 }, 5072 [ITEM_MPLS_LABEL] = { 5073 .name = "label", 5074 .help = "MPLS label", 5075 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5076 item_param), 5077 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5078 label_tc_s, 5079 "\xff\xff\xf0")), 5080 }, 5081 [ITEM_MPLS_TC] = { 5082 .name = "tc", 5083 .help = "MPLS Traffic Class", 5084 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5085 item_param), 5086 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5087 label_tc_s, 5088 "\x00\x00\x0e")), 5089 }, 5090 [ITEM_MPLS_S] = { 5091 .name = "s", 5092 .help = "MPLS Bottom-of-Stack", 5093 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5094 item_param), 5095 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 5096 label_tc_s, 5097 "\x00\x00\x01")), 5098 }, 5099 [ITEM_MPLS_TTL] = { 5100 .name = "ttl", 5101 .help = "MPLS Time-to-Live", 5102 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 5103 item_param), 5104 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls, ttl)), 5105 }, 5106 [ITEM_GRE] = { 5107 .name = "gre", 5108 .help = "match GRE header", 5109 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), 5110 .next = NEXT(item_gre), 5111 .call = parse_vc, 5112 }, 5113 [ITEM_GRE_PROTO] = { 5114 .name = "protocol", 5115 .help = "GRE protocol type", 5116 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5117 item_param), 5118 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5119 protocol)), 5120 }, 5121 [ITEM_GRE_C_RSVD0_VER] = { 5122 .name = "c_rsvd0_ver", 5123 .help = 5124 "checksum (1b), undefined (1b), key bit (1b)," 5125 " sequence number (1b), reserved 0 (9b)," 5126 " version (3b)", 5127 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5128 item_param), 5129 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5130 c_rsvd0_ver)), 5131 }, 5132 [ITEM_GRE_C_BIT] = { 5133 .name = "c_bit", 5134 .help = "checksum bit (C)", 5135 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), 5136 item_param), 5137 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5138 c_rsvd0_ver, 5139 "\x80\x00\x00\x00")), 5140 }, 5141 [ITEM_GRE_S_BIT] = { 5142 .name = "s_bit", 5143 .help = "sequence number bit (S)", 5144 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5145 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5146 c_rsvd0_ver, 5147 "\x10\x00\x00\x00")), 5148 }, 5149 [ITEM_GRE_K_BIT] = { 5150 .name = "k_bit", 5151 .help = "key bit (K)", 5152 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5153 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5154 c_rsvd0_ver, 5155 "\x20\x00\x00\x00")), 5156 }, 5157 [ITEM_FUZZY] = { 5158 .name = "fuzzy", 5159 .help = "fuzzy pattern match, expect faster than default", 5160 .priv = PRIV_ITEM(FUZZY, 5161 sizeof(struct rte_flow_item_fuzzy)), 5162 .next = NEXT(item_fuzzy), 5163 .call = parse_vc, 5164 }, 5165 [ITEM_FUZZY_THRESH] = { 5166 .name = "thresh", 5167 .help = "match accuracy threshold", 5168 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), 5169 item_param), 5170 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, 5171 thresh)), 5172 }, 5173 [ITEM_GTP] = { 5174 .name = "gtp", 5175 .help = "match GTP header", 5176 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), 5177 .next = NEXT(item_gtp), 5178 .call = parse_vc, 5179 }, 5180 [ITEM_GTP_FLAGS] = { 5181 .name = "v_pt_rsv_flags", 5182 .help = "GTP flags", 5183 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5184 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, 5185 hdr.gtp_hdr_info)), 5186 }, 5187 [ITEM_GTP_MSG_TYPE] = { 5188 .name = "msg_type", 5189 .help = "GTP message type", 5190 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5191 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), 5192 }, 5193 [ITEM_GTP_TEID] = { 5194 .name = "teid", 5195 .help = "tunnel endpoint identifier", 5196 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5197 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), 5198 }, 5199 [ITEM_GTPC] = { 5200 .name = "gtpc", 5201 .help = "match GTP header", 5202 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), 5203 .next = NEXT(item_gtp), 5204 .call = parse_vc, 5205 }, 5206 [ITEM_GTPU] = { 5207 .name = "gtpu", 5208 .help = "match GTP header", 5209 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), 5210 .next = NEXT(item_gtp), 5211 .call = parse_vc, 5212 }, 5213 [ITEM_GENEVE] = { 5214 .name = "geneve", 5215 .help = "match GENEVE header", 5216 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), 5217 .next = NEXT(item_geneve), 5218 .call = parse_vc, 5219 }, 5220 [ITEM_GENEVE_VNI] = { 5221 .name = "vni", 5222 .help = "virtual network identifier", 5223 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5224 item_param), 5225 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), 5226 }, 5227 [ITEM_GENEVE_PROTO] = { 5228 .name = "protocol", 5229 .help = "GENEVE protocol type", 5230 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5231 item_param), 5232 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, 5233 protocol)), 5234 }, 5235 [ITEM_GENEVE_OPTLEN] = { 5236 .name = "optlen", 5237 .help = "GENEVE options length in dwords", 5238 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5239 item_param), 5240 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, 5241 ver_opt_len_o_c_rsvd0, 5242 "\x3f\x00")), 5243 }, 5244 [ITEM_ARP_ETH_IPV4] = { 5245 .name = "arp_eth_ipv4", 5246 .help = "match ARP header for Ethernet/IPv4", 5247 .priv = PRIV_ITEM(ARP_ETH_IPV4, 5248 sizeof(struct rte_flow_item_arp_eth_ipv4)), 5249 .next = NEXT(item_arp_eth_ipv4), 5250 .call = parse_vc, 5251 }, 5252 [ITEM_ARP_ETH_IPV4_SHA] = { 5253 .name = "sha", 5254 .help = "sender hardware address", 5255 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5256 item_param), 5257 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5258 hdr.arp_data.arp_sha)), 5259 }, 5260 [ITEM_ARP_ETH_IPV4_SPA] = { 5261 .name = "spa", 5262 .help = "sender IPv4 address", 5263 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5264 item_param), 5265 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5266 hdr.arp_data.arp_sip)), 5267 }, 5268 [ITEM_ARP_ETH_IPV4_THA] = { 5269 .name = "tha", 5270 .help = "target hardware address", 5271 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5272 item_param), 5273 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5274 hdr.arp_data.arp_tha)), 5275 }, 5276 [ITEM_ARP_ETH_IPV4_TPA] = { 5277 .name = "tpa", 5278 .help = "target IPv4 address", 5279 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5280 item_param), 5281 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5282 hdr.arp_data.arp_tip)), 5283 }, 5284 [ITEM_IPV6_EXT] = { 5285 .name = "ipv6_ext", 5286 .help = "match presence of any IPv6 extension header", 5287 .priv = PRIV_ITEM(IPV6_EXT, 5288 sizeof(struct rte_flow_item_ipv6_ext)), 5289 .next = NEXT(item_ipv6_ext), 5290 .call = parse_vc, 5291 }, 5292 [ITEM_IPV6_EXT_NEXT_HDR] = { 5293 .name = "next_hdr", 5294 .help = "next header", 5295 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5296 item_param), 5297 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 5298 next_hdr)), 5299 }, 5300 [ITEM_IPV6_FRAG_EXT] = { 5301 .name = "ipv6_frag_ext", 5302 .help = "match presence of IPv6 fragment extension header", 5303 .priv = PRIV_ITEM(IPV6_FRAG_EXT, 5304 sizeof(struct rte_flow_item_ipv6_frag_ext)), 5305 .next = NEXT(item_ipv6_frag_ext), 5306 .call = parse_vc, 5307 }, 5308 [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { 5309 .name = "next_hdr", 5310 .help = "next header", 5311 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5312 item_param), 5313 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, 5314 hdr.next_header)), 5315 }, 5316 [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { 5317 .name = "frag_data", 5318 .help = "fragment flags and offset", 5319 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5320 item_param), 5321 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5322 hdr.frag_data)), 5323 }, 5324 [ITEM_IPV6_FRAG_EXT_ID] = { 5325 .name = "packet_id", 5326 .help = "fragment packet id", 5327 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5328 item_param), 5329 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5330 hdr.id)), 5331 }, 5332 [ITEM_ICMP6] = { 5333 .name = "icmp6", 5334 .help = "match any ICMPv6 header", 5335 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), 5336 .next = NEXT(item_icmp6), 5337 .call = parse_vc, 5338 }, 5339 [ITEM_ICMP6_TYPE] = { 5340 .name = "type", 5341 .help = "ICMPv6 type", 5342 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5343 item_param), 5344 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5345 type)), 5346 }, 5347 [ITEM_ICMP6_CODE] = { 5348 .name = "code", 5349 .help = "ICMPv6 code", 5350 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5351 item_param), 5352 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5353 code)), 5354 }, 5355 [ITEM_ICMP6_ECHO_REQUEST] = { 5356 .name = "icmp6_echo_request", 5357 .help = "match ICMPv6 echo request", 5358 .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, 5359 sizeof(struct rte_flow_item_icmp6_echo)), 5360 .next = NEXT(item_icmp6_echo_request), 5361 .call = parse_vc, 5362 }, 5363 [ITEM_ICMP6_ECHO_REQUEST_ID] = { 5364 .name = "ident", 5365 .help = "ICMPv6 echo request identifier", 5366 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5367 item_param), 5368 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5369 hdr.identifier)), 5370 }, 5371 [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { 5372 .name = "seq", 5373 .help = "ICMPv6 echo request sequence", 5374 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5375 item_param), 5376 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5377 hdr.sequence)), 5378 }, 5379 [ITEM_ICMP6_ECHO_REPLY] = { 5380 .name = "icmp6_echo_reply", 5381 .help = "match ICMPv6 echo reply", 5382 .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, 5383 sizeof(struct rte_flow_item_icmp6_echo)), 5384 .next = NEXT(item_icmp6_echo_reply), 5385 .call = parse_vc, 5386 }, 5387 [ITEM_ICMP6_ECHO_REPLY_ID] = { 5388 .name = "ident", 5389 .help = "ICMPv6 echo reply identifier", 5390 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5391 item_param), 5392 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5393 hdr.identifier)), 5394 }, 5395 [ITEM_ICMP6_ECHO_REPLY_SEQ] = { 5396 .name = "seq", 5397 .help = "ICMPv6 echo reply sequence", 5398 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5399 item_param), 5400 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5401 hdr.sequence)), 5402 }, 5403 [ITEM_ICMP6_ND_NS] = { 5404 .name = "icmp6_nd_ns", 5405 .help = "match ICMPv6 neighbor discovery solicitation", 5406 .priv = PRIV_ITEM(ICMP6_ND_NS, 5407 sizeof(struct rte_flow_item_icmp6_nd_ns)), 5408 .next = NEXT(item_icmp6_nd_ns), 5409 .call = parse_vc, 5410 }, 5411 [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { 5412 .name = "target_addr", 5413 .help = "target address", 5414 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), 5415 item_param), 5416 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, 5417 target_addr)), 5418 }, 5419 [ITEM_ICMP6_ND_NA] = { 5420 .name = "icmp6_nd_na", 5421 .help = "match ICMPv6 neighbor discovery advertisement", 5422 .priv = PRIV_ITEM(ICMP6_ND_NA, 5423 sizeof(struct rte_flow_item_icmp6_nd_na)), 5424 .next = NEXT(item_icmp6_nd_na), 5425 .call = parse_vc, 5426 }, 5427 [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { 5428 .name = "target_addr", 5429 .help = "target address", 5430 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), 5431 item_param), 5432 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, 5433 target_addr)), 5434 }, 5435 [ITEM_ICMP6_ND_OPT] = { 5436 .name = "icmp6_nd_opt", 5437 .help = "match presence of any ICMPv6 neighbor discovery" 5438 " option", 5439 .priv = PRIV_ITEM(ICMP6_ND_OPT, 5440 sizeof(struct rte_flow_item_icmp6_nd_opt)), 5441 .next = NEXT(item_icmp6_nd_opt), 5442 .call = parse_vc, 5443 }, 5444 [ITEM_ICMP6_ND_OPT_TYPE] = { 5445 .name = "type", 5446 .help = "ND option type", 5447 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5448 item_param), 5449 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, 5450 type)), 5451 }, 5452 [ITEM_ICMP6_ND_OPT_SLA_ETH] = { 5453 .name = "icmp6_nd_opt_sla_eth", 5454 .help = "match ICMPv6 neighbor discovery source Ethernet" 5455 " link-layer address option", 5456 .priv = PRIV_ITEM 5457 (ICMP6_ND_OPT_SLA_ETH, 5458 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), 5459 .next = NEXT(item_icmp6_nd_opt_sla_eth), 5460 .call = parse_vc, 5461 }, 5462 [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { 5463 .name = "sla", 5464 .help = "source Ethernet LLA", 5465 .next = NEXT(item_icmp6_nd_opt_sla_eth, 5466 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5467 .args = ARGS(ARGS_ENTRY_HTON 5468 (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), 5469 }, 5470 [ITEM_ICMP6_ND_OPT_TLA_ETH] = { 5471 .name = "icmp6_nd_opt_tla_eth", 5472 .help = "match ICMPv6 neighbor discovery target Ethernet" 5473 " link-layer address option", 5474 .priv = PRIV_ITEM 5475 (ICMP6_ND_OPT_TLA_ETH, 5476 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), 5477 .next = NEXT(item_icmp6_nd_opt_tla_eth), 5478 .call = parse_vc, 5479 }, 5480 [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { 5481 .name = "tla", 5482 .help = "target Ethernet LLA", 5483 .next = NEXT(item_icmp6_nd_opt_tla_eth, 5484 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5485 .args = ARGS(ARGS_ENTRY_HTON 5486 (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), 5487 }, 5488 [ITEM_META] = { 5489 .name = "meta", 5490 .help = "match metadata header", 5491 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), 5492 .next = NEXT(item_meta), 5493 .call = parse_vc, 5494 }, 5495 [ITEM_META_DATA] = { 5496 .name = "data", 5497 .help = "metadata value", 5498 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), 5499 item_param), 5500 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, 5501 data, "\xff\xff\xff\xff")), 5502 }, 5503 [ITEM_RANDOM] = { 5504 .name = "random", 5505 .help = "match random value", 5506 .priv = PRIV_ITEM(RANDOM, sizeof(struct rte_flow_item_random)), 5507 .next = NEXT(item_random), 5508 .call = parse_vc, 5509 }, 5510 [ITEM_RANDOM_VALUE] = { 5511 .name = "value", 5512 .help = "random value", 5513 .next = NEXT(item_random, NEXT_ENTRY(COMMON_UNSIGNED), 5514 item_param), 5515 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_random, 5516 value, "\xff\xff")), 5517 }, 5518 [ITEM_GRE_KEY] = { 5519 .name = "gre_key", 5520 .help = "match GRE key", 5521 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), 5522 .next = NEXT(item_gre_key), 5523 .call = parse_vc, 5524 }, 5525 [ITEM_GRE_KEY_VALUE] = { 5526 .name = "value", 5527 .help = "key value", 5528 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), 5529 item_param), 5530 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5531 }, 5532 [ITEM_GRE_OPTION] = { 5533 .name = "gre_option", 5534 .help = "match GRE optional fields", 5535 .priv = PRIV_ITEM(GRE_OPTION, 5536 sizeof(struct rte_flow_item_gre_opt)), 5537 .next = NEXT(item_gre_option), 5538 .call = parse_vc, 5539 }, 5540 [ITEM_GRE_OPTION_CHECKSUM] = { 5541 .name = "checksum", 5542 .help = "match GRE checksum", 5543 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5544 item_param), 5545 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5546 checksum_rsvd.checksum)), 5547 }, 5548 [ITEM_GRE_OPTION_KEY] = { 5549 .name = "key", 5550 .help = "match GRE key", 5551 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5552 item_param), 5553 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5554 key.key)), 5555 }, 5556 [ITEM_GRE_OPTION_SEQUENCE] = { 5557 .name = "sequence", 5558 .help = "match GRE sequence", 5559 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5560 item_param), 5561 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5562 sequence.sequence)), 5563 }, 5564 [ITEM_GTP_PSC] = { 5565 .name = "gtp_psc", 5566 .help = "match GTP extension header with type 0x85", 5567 .priv = PRIV_ITEM(GTP_PSC, 5568 sizeof(struct rte_flow_item_gtp_psc)), 5569 .next = NEXT(item_gtp_psc), 5570 .call = parse_vc, 5571 }, 5572 [ITEM_GTP_PSC_QFI] = { 5573 .name = "qfi", 5574 .help = "QoS flow identifier", 5575 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5576 item_param), 5577 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5578 hdr.qfi, 6)), 5579 }, 5580 [ITEM_GTP_PSC_PDU_T] = { 5581 .name = "pdu_t", 5582 .help = "PDU type", 5583 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5584 item_param), 5585 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5586 hdr.type, 4)), 5587 }, 5588 [ITEM_PPPOES] = { 5589 .name = "pppoes", 5590 .help = "match PPPoE session header", 5591 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), 5592 .next = NEXT(item_pppoes), 5593 .call = parse_vc, 5594 }, 5595 [ITEM_PPPOED] = { 5596 .name = "pppoed", 5597 .help = "match PPPoE discovery header", 5598 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), 5599 .next = NEXT(item_pppoed), 5600 .call = parse_vc, 5601 }, 5602 [ITEM_PPPOE_SEID] = { 5603 .name = "seid", 5604 .help = "session identifier", 5605 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), 5606 item_param), 5607 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, 5608 session_id)), 5609 }, 5610 [ITEM_PPPOE_PROTO_ID] = { 5611 .name = "pppoe_proto_id", 5612 .help = "match PPPoE session protocol identifier", 5613 .priv = PRIV_ITEM(PPPOE_PROTO_ID, 5614 sizeof(struct rte_flow_item_pppoe_proto_id)), 5615 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED), 5616 item_param), 5617 .args = ARGS(ARGS_ENTRY_HTON 5618 (struct rte_flow_item_pppoe_proto_id, proto_id)), 5619 .call = parse_vc, 5620 }, 5621 [ITEM_HIGIG2] = { 5622 .name = "higig2", 5623 .help = "matches higig2 header", 5624 .priv = PRIV_ITEM(HIGIG2, 5625 sizeof(struct rte_flow_item_higig2_hdr)), 5626 .next = NEXT(item_higig2), 5627 .call = parse_vc, 5628 }, 5629 [ITEM_HIGIG2_CLASSIFICATION] = { 5630 .name = "classification", 5631 .help = "matches classification of higig2 header", 5632 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5633 item_param), 5634 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5635 hdr.ppt1.classification)), 5636 }, 5637 [ITEM_HIGIG2_VID] = { 5638 .name = "vid", 5639 .help = "matches vid of higig2 header", 5640 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5641 item_param), 5642 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5643 hdr.ppt1.vid)), 5644 }, 5645 [ITEM_TAG] = { 5646 .name = "tag", 5647 .help = "match tag value", 5648 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), 5649 .next = NEXT(item_tag), 5650 .call = parse_vc, 5651 }, 5652 [ITEM_TAG_DATA] = { 5653 .name = "data", 5654 .help = "tag value to match", 5655 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5656 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), 5657 }, 5658 [ITEM_TAG_INDEX] = { 5659 .name = "index", 5660 .help = "index of tag array to match", 5661 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5662 NEXT_ENTRY(ITEM_PARAM_IS)), 5663 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), 5664 }, 5665 [ITEM_L2TPV3OIP] = { 5666 .name = "l2tpv3oip", 5667 .help = "match L2TPv3 over IP header", 5668 .priv = PRIV_ITEM(L2TPV3OIP, 5669 sizeof(struct rte_flow_item_l2tpv3oip)), 5670 .next = NEXT(item_l2tpv3oip), 5671 .call = parse_vc, 5672 }, 5673 [ITEM_L2TPV3OIP_SESSION_ID] = { 5674 .name = "session_id", 5675 .help = "session identifier", 5676 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), 5677 item_param), 5678 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, 5679 session_id)), 5680 }, 5681 [ITEM_ESP] = { 5682 .name = "esp", 5683 .help = "match ESP header", 5684 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), 5685 .next = NEXT(item_esp), 5686 .call = parse_vc, 5687 }, 5688 [ITEM_ESP_SPI] = { 5689 .name = "spi", 5690 .help = "security policy index", 5691 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5692 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, 5693 hdr.spi)), 5694 }, 5695 [ITEM_AH] = { 5696 .name = "ah", 5697 .help = "match AH header", 5698 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), 5699 .next = NEXT(item_ah), 5700 .call = parse_vc, 5701 }, 5702 [ITEM_AH_SPI] = { 5703 .name = "spi", 5704 .help = "security parameters index", 5705 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5706 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), 5707 }, 5708 [ITEM_PFCP] = { 5709 .name = "pfcp", 5710 .help = "match pfcp header", 5711 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), 5712 .next = NEXT(item_pfcp), 5713 .call = parse_vc, 5714 }, 5715 [ITEM_PFCP_S_FIELD] = { 5716 .name = "s_field", 5717 .help = "S field", 5718 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5719 item_param), 5720 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, 5721 s_field)), 5722 }, 5723 [ITEM_PFCP_SEID] = { 5724 .name = "seid", 5725 .help = "session endpoint identifier", 5726 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5727 item_param), 5728 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), 5729 }, 5730 [ITEM_ECPRI] = { 5731 .name = "ecpri", 5732 .help = "match eCPRI header", 5733 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), 5734 .next = NEXT(item_ecpri), 5735 .call = parse_vc, 5736 }, 5737 [ITEM_ECPRI_COMMON] = { 5738 .name = "common", 5739 .help = "eCPRI common header", 5740 .next = NEXT(item_ecpri_common), 5741 }, 5742 [ITEM_ECPRI_COMMON_TYPE] = { 5743 .name = "type", 5744 .help = "type of common header", 5745 .next = NEXT(item_ecpri_common_type), 5746 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), 5747 }, 5748 [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { 5749 .name = "iq_data", 5750 .help = "Type #0: IQ Data", 5751 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5752 ITEM_NEXT)), 5753 .call = parse_vc_item_ecpri_type, 5754 }, 5755 [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { 5756 .name = "pc_id", 5757 .help = "Physical Channel ID", 5758 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5759 ITEM_ECPRI_COMMON, ITEM_NEXT), 5760 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5761 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5762 hdr.type0.pc_id)), 5763 }, 5764 [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { 5765 .name = "rtc_ctrl", 5766 .help = "Type #2: Real-Time Control Data", 5767 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5768 ITEM_NEXT)), 5769 .call = parse_vc_item_ecpri_type, 5770 }, 5771 [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { 5772 .name = "rtc_id", 5773 .help = "Real-Time Control Data ID", 5774 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5775 ITEM_ECPRI_COMMON, ITEM_NEXT), 5776 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5777 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5778 hdr.type2.rtc_id)), 5779 }, 5780 [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { 5781 .name = "delay_measure", 5782 .help = "Type #5: One-Way Delay Measurement", 5783 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5784 ITEM_NEXT)), 5785 .call = parse_vc_item_ecpri_type, 5786 }, 5787 [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { 5788 .name = "msr_id", 5789 .help = "Measurement ID", 5790 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5791 ITEM_ECPRI_COMMON, ITEM_NEXT), 5792 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5793 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5794 hdr.type5.msr_id)), 5795 }, 5796 [ITEM_GENEVE_OPT] = { 5797 .name = "geneve-opt", 5798 .help = "GENEVE header option", 5799 .priv = PRIV_ITEM(GENEVE_OPT, 5800 sizeof(struct rte_flow_item_geneve_opt) + 5801 ITEM_GENEVE_OPT_DATA_SIZE), 5802 .next = NEXT(item_geneve_opt), 5803 .call = parse_vc, 5804 }, 5805 [ITEM_GENEVE_OPT_CLASS] = { 5806 .name = "class", 5807 .help = "GENEVE option class", 5808 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5809 item_param), 5810 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, 5811 option_class)), 5812 }, 5813 [ITEM_GENEVE_OPT_TYPE] = { 5814 .name = "type", 5815 .help = "GENEVE option type", 5816 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5817 item_param), 5818 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, 5819 option_type)), 5820 }, 5821 [ITEM_GENEVE_OPT_LENGTH] = { 5822 .name = "length", 5823 .help = "GENEVE option data length (in 32b words)", 5824 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5825 item_param), 5826 .args = ARGS(ARGS_ENTRY_BOUNDED( 5827 struct rte_flow_item_geneve_opt, option_len, 5828 0, 31)), 5829 }, 5830 [ITEM_GENEVE_OPT_DATA] = { 5831 .name = "data", 5832 .help = "GENEVE option data pattern", 5833 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), 5834 item_param), 5835 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), 5836 ARGS_ENTRY_ARB(0, 0), 5837 ARGS_ENTRY_ARB 5838 (sizeof(struct rte_flow_item_geneve_opt), 5839 ITEM_GENEVE_OPT_DATA_SIZE)), 5840 }, 5841 [ITEM_INTEGRITY] = { 5842 .name = "integrity", 5843 .help = "match packet integrity", 5844 .priv = PRIV_ITEM(INTEGRITY, 5845 sizeof(struct rte_flow_item_integrity)), 5846 .next = NEXT(item_integrity), 5847 .call = parse_vc, 5848 }, 5849 [ITEM_INTEGRITY_LEVEL] = { 5850 .name = "level", 5851 .help = "integrity level", 5852 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5853 item_param), 5854 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), 5855 }, 5856 [ITEM_INTEGRITY_VALUE] = { 5857 .name = "value", 5858 .help = "integrity value", 5859 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5860 item_param), 5861 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), 5862 }, 5863 [ITEM_CONNTRACK] = { 5864 .name = "conntrack", 5865 .help = "conntrack state", 5866 .priv = PRIV_ITEM(CONNTRACK, 5867 sizeof(struct rte_flow_item_conntrack)), 5868 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 5869 item_param), 5870 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 5871 .call = parse_vc, 5872 }, 5873 [ITEM_PORT_REPRESENTOR] = { 5874 .name = "port_representor", 5875 .help = "match traffic entering the embedded switch from the given ethdev", 5876 .priv = PRIV_ITEM(PORT_REPRESENTOR, 5877 sizeof(struct rte_flow_item_ethdev)), 5878 .next = NEXT(item_port_representor), 5879 .call = parse_vc, 5880 }, 5881 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 5882 .name = "port_id", 5883 .help = "ethdev port ID", 5884 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 5885 item_param), 5886 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5887 }, 5888 [ITEM_REPRESENTED_PORT] = { 5889 .name = "represented_port", 5890 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 5891 .priv = PRIV_ITEM(REPRESENTED_PORT, 5892 sizeof(struct rte_flow_item_ethdev)), 5893 .next = NEXT(item_represented_port), 5894 .call = parse_vc, 5895 }, 5896 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 5897 .name = "ethdev_port_id", 5898 .help = "ethdev port ID", 5899 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 5900 item_param), 5901 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5902 }, 5903 [ITEM_FLEX] = { 5904 .name = "flex", 5905 .help = "match flex header", 5906 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 5907 .next = NEXT(item_flex), 5908 .call = parse_vc, 5909 }, 5910 [ITEM_FLEX_ITEM_HANDLE] = { 5911 .name = "item", 5912 .help = "flex item handle", 5913 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5914 NEXT_ENTRY(ITEM_PARAM_IS)), 5915 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 5916 }, 5917 [ITEM_FLEX_PATTERN_HANDLE] = { 5918 .name = "pattern", 5919 .help = "flex pattern handle", 5920 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5921 NEXT_ENTRY(ITEM_PARAM_IS)), 5922 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 5923 }, 5924 [ITEM_L2TPV2] = { 5925 .name = "l2tpv2", 5926 .help = "match L2TPv2 header", 5927 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 5928 .next = NEXT(item_l2tpv2), 5929 .call = parse_vc, 5930 }, 5931 [ITEM_L2TPV2_TYPE] = { 5932 .name = "type", 5933 .help = "type of l2tpv2", 5934 .next = NEXT(item_l2tpv2_type), 5935 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 5936 }, 5937 [ITEM_L2TPV2_TYPE_DATA] = { 5938 .name = "data", 5939 .help = "Type #7: data message without any options", 5940 .next = NEXT(item_l2tpv2_type_data), 5941 .call = parse_vc_item_l2tpv2_type, 5942 }, 5943 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 5944 .name = "tunnel_id", 5945 .help = "tunnel identifier", 5946 .next = NEXT(item_l2tpv2_type_data, 5947 NEXT_ENTRY(COMMON_UNSIGNED), 5948 item_param), 5949 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5950 hdr.type7.tunnel_id)), 5951 }, 5952 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 5953 .name = "session_id", 5954 .help = "session identifier", 5955 .next = NEXT(item_l2tpv2_type_data, 5956 NEXT_ENTRY(COMMON_UNSIGNED), 5957 item_param), 5958 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5959 hdr.type7.session_id)), 5960 }, 5961 [ITEM_L2TPV2_TYPE_DATA_L] = { 5962 .name = "data_l", 5963 .help = "Type #6: data message with length option", 5964 .next = NEXT(item_l2tpv2_type_data_l), 5965 .call = parse_vc_item_l2tpv2_type, 5966 }, 5967 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 5968 .name = "length", 5969 .help = "message length", 5970 .next = NEXT(item_l2tpv2_type_data_l, 5971 NEXT_ENTRY(COMMON_UNSIGNED), 5972 item_param), 5973 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5974 hdr.type6.length)), 5975 }, 5976 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 5977 .name = "tunnel_id", 5978 .help = "tunnel identifier", 5979 .next = NEXT(item_l2tpv2_type_data_l, 5980 NEXT_ENTRY(COMMON_UNSIGNED), 5981 item_param), 5982 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5983 hdr.type6.tunnel_id)), 5984 }, 5985 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 5986 .name = "session_id", 5987 .help = "session identifier", 5988 .next = NEXT(item_l2tpv2_type_data_l, 5989 NEXT_ENTRY(COMMON_UNSIGNED), 5990 item_param), 5991 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5992 hdr.type6.session_id)), 5993 }, 5994 [ITEM_L2TPV2_TYPE_DATA_S] = { 5995 .name = "data_s", 5996 .help = "Type #5: data message with ns, nr option", 5997 .next = NEXT(item_l2tpv2_type_data_s), 5998 .call = parse_vc_item_l2tpv2_type, 5999 }, 6000 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 6001 .name = "tunnel_id", 6002 .help = "tunnel identifier", 6003 .next = NEXT(item_l2tpv2_type_data_s, 6004 NEXT_ENTRY(COMMON_UNSIGNED), 6005 item_param), 6006 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6007 hdr.type5.tunnel_id)), 6008 }, 6009 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 6010 .name = "session_id", 6011 .help = "session identifier", 6012 .next = NEXT(item_l2tpv2_type_data_s, 6013 NEXT_ENTRY(COMMON_UNSIGNED), 6014 item_param), 6015 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6016 hdr.type5.session_id)), 6017 }, 6018 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 6019 .name = "ns", 6020 .help = "sequence number for message", 6021 .next = NEXT(item_l2tpv2_type_data_s, 6022 NEXT_ENTRY(COMMON_UNSIGNED), 6023 item_param), 6024 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6025 hdr.type5.ns)), 6026 }, 6027 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 6028 .name = "nr", 6029 .help = "sequence number for next receive message", 6030 .next = NEXT(item_l2tpv2_type_data_s, 6031 NEXT_ENTRY(COMMON_UNSIGNED), 6032 item_param), 6033 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6034 hdr.type5.nr)), 6035 }, 6036 [ITEM_L2TPV2_TYPE_DATA_O] = { 6037 .name = "data_o", 6038 .help = "Type #4: data message with offset option", 6039 .next = NEXT(item_l2tpv2_type_data_o), 6040 .call = parse_vc_item_l2tpv2_type, 6041 }, 6042 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 6043 .name = "tunnel_id", 6044 .help = "tunnel identifier", 6045 .next = NEXT(item_l2tpv2_type_data_o, 6046 NEXT_ENTRY(COMMON_UNSIGNED), 6047 item_param), 6048 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6049 hdr.type4.tunnel_id)), 6050 }, 6051 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 6052 .name = "session_id", 6053 .help = "session identifier", 6054 .next = NEXT(item_l2tpv2_type_data_o, 6055 NEXT_ENTRY(COMMON_UNSIGNED), 6056 item_param), 6057 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6058 hdr.type5.session_id)), 6059 }, 6060 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 6061 .name = "offset_size", 6062 .help = "the size of offset padding", 6063 .next = NEXT(item_l2tpv2_type_data_o, 6064 NEXT_ENTRY(COMMON_UNSIGNED), 6065 item_param), 6066 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6067 hdr.type4.offset_size)), 6068 }, 6069 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 6070 .name = "data_l_s", 6071 .help = "Type #3: data message contains length, ns, nr " 6072 "options", 6073 .next = NEXT(item_l2tpv2_type_data_l_s), 6074 .call = parse_vc_item_l2tpv2_type, 6075 }, 6076 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 6077 .name = "length", 6078 .help = "message length", 6079 .next = NEXT(item_l2tpv2_type_data_l_s, 6080 NEXT_ENTRY(COMMON_UNSIGNED), 6081 item_param), 6082 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6083 hdr.type3.length)), 6084 }, 6085 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 6086 .name = "tunnel_id", 6087 .help = "tunnel identifier", 6088 .next = NEXT(item_l2tpv2_type_data_l_s, 6089 NEXT_ENTRY(COMMON_UNSIGNED), 6090 item_param), 6091 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6092 hdr.type3.tunnel_id)), 6093 }, 6094 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 6095 .name = "session_id", 6096 .help = "session identifier", 6097 .next = NEXT(item_l2tpv2_type_data_l_s, 6098 NEXT_ENTRY(COMMON_UNSIGNED), 6099 item_param), 6100 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6101 hdr.type3.session_id)), 6102 }, 6103 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 6104 .name = "ns", 6105 .help = "sequence number for message", 6106 .next = NEXT(item_l2tpv2_type_data_l_s, 6107 NEXT_ENTRY(COMMON_UNSIGNED), 6108 item_param), 6109 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6110 hdr.type3.ns)), 6111 }, 6112 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 6113 .name = "nr", 6114 .help = "sequence number for next receive message", 6115 .next = NEXT(item_l2tpv2_type_data_l_s, 6116 NEXT_ENTRY(COMMON_UNSIGNED), 6117 item_param), 6118 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6119 hdr.type3.nr)), 6120 }, 6121 [ITEM_L2TPV2_TYPE_CTRL] = { 6122 .name = "control", 6123 .help = "Type #3: conrtol message contains length, ns, nr " 6124 "options", 6125 .next = NEXT(item_l2tpv2_type_ctrl), 6126 .call = parse_vc_item_l2tpv2_type, 6127 }, 6128 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 6129 .name = "length", 6130 .help = "message length", 6131 .next = NEXT(item_l2tpv2_type_ctrl, 6132 NEXT_ENTRY(COMMON_UNSIGNED), 6133 item_param), 6134 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6135 hdr.type3.length)), 6136 }, 6137 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 6138 .name = "tunnel_id", 6139 .help = "tunnel identifier", 6140 .next = NEXT(item_l2tpv2_type_ctrl, 6141 NEXT_ENTRY(COMMON_UNSIGNED), 6142 item_param), 6143 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6144 hdr.type3.tunnel_id)), 6145 }, 6146 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 6147 .name = "session_id", 6148 .help = "session identifier", 6149 .next = NEXT(item_l2tpv2_type_ctrl, 6150 NEXT_ENTRY(COMMON_UNSIGNED), 6151 item_param), 6152 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6153 hdr.type3.session_id)), 6154 }, 6155 [ITEM_L2TPV2_MSG_CTRL_NS] = { 6156 .name = "ns", 6157 .help = "sequence number for message", 6158 .next = NEXT(item_l2tpv2_type_ctrl, 6159 NEXT_ENTRY(COMMON_UNSIGNED), 6160 item_param), 6161 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6162 hdr.type3.ns)), 6163 }, 6164 [ITEM_L2TPV2_MSG_CTRL_NR] = { 6165 .name = "nr", 6166 .help = "sequence number for next receive message", 6167 .next = NEXT(item_l2tpv2_type_ctrl, 6168 NEXT_ENTRY(COMMON_UNSIGNED), 6169 item_param), 6170 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6171 hdr.type3.nr)), 6172 }, 6173 [ITEM_PPP] = { 6174 .name = "ppp", 6175 .help = "match PPP header", 6176 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 6177 .next = NEXT(item_ppp), 6178 .call = parse_vc, 6179 }, 6180 [ITEM_PPP_ADDR] = { 6181 .name = "addr", 6182 .help = "PPP address", 6183 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6184 item_param), 6185 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 6186 }, 6187 [ITEM_PPP_CTRL] = { 6188 .name = "ctrl", 6189 .help = "PPP control", 6190 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6191 item_param), 6192 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 6193 }, 6194 [ITEM_PPP_PROTO_ID] = { 6195 .name = "proto_id", 6196 .help = "PPP protocol identifier", 6197 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6198 item_param), 6199 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 6200 hdr.proto_id)), 6201 }, 6202 [ITEM_METER] = { 6203 .name = "meter", 6204 .help = "match meter color", 6205 .priv = PRIV_ITEM(METER_COLOR, 6206 sizeof(struct rte_flow_item_meter_color)), 6207 .next = NEXT(item_meter), 6208 .call = parse_vc, 6209 }, 6210 [ITEM_METER_COLOR] = { 6211 .name = "color", 6212 .help = "meter color", 6213 .next = NEXT(item_meter, 6214 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 6215 item_param), 6216 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 6217 color)), 6218 }, 6219 [ITEM_METER_COLOR_NAME] = { 6220 .name = "color_name", 6221 .help = "meter color name", 6222 .call = parse_meter_color, 6223 .comp = comp_meter_color, 6224 }, 6225 [ITEM_QUOTA] = { 6226 .name = "quota", 6227 .help = "match quota", 6228 .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), 6229 .next = NEXT(item_quota), 6230 .call = parse_vc 6231 }, 6232 [ITEM_QUOTA_STATE] = { 6233 .name = "quota_state", 6234 .help = "quota state", 6235 .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), 6236 NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), 6237 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) 6238 }, 6239 [ITEM_QUOTA_STATE_NAME] = { 6240 .name = "state_name", 6241 .help = "quota state name", 6242 .call = parse_quota_state_name, 6243 .comp = comp_quota_state_name 6244 }, 6245 [ITEM_IB_BTH] = { 6246 .name = "ib_bth", 6247 .help = "match ib bth fields", 6248 .priv = PRIV_ITEM(IB_BTH, 6249 sizeof(struct rte_flow_item_ib_bth)), 6250 .next = NEXT(item_ib_bth), 6251 .call = parse_vc, 6252 }, 6253 [ITEM_IB_BTH_OPCODE] = { 6254 .name = "opcode", 6255 .help = "match ib bth opcode", 6256 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6257 item_param), 6258 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6259 hdr.opcode)), 6260 }, 6261 [ITEM_IB_BTH_PKEY] = { 6262 .name = "pkey", 6263 .help = "partition key", 6264 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6265 item_param), 6266 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6267 hdr.pkey)), 6268 }, 6269 [ITEM_IB_BTH_DST_QPN] = { 6270 .name = "dst_qp", 6271 .help = "destination qp", 6272 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6273 item_param), 6274 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6275 hdr.dst_qp)), 6276 }, 6277 [ITEM_IB_BTH_PSN] = { 6278 .name = "psn", 6279 .help = "packet sequence number", 6280 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6281 item_param), 6282 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6283 hdr.psn)), 6284 }, 6285 [ITEM_PTYPE] = { 6286 .name = "ptype", 6287 .help = "match L2/L3/L4 and tunnel information", 6288 .priv = PRIV_ITEM(PTYPE, 6289 sizeof(struct rte_flow_item_ptype)), 6290 .next = NEXT(item_ptype), 6291 .call = parse_vc, 6292 }, 6293 [ITEM_PTYPE_VALUE] = { 6294 .name = "packet_type", 6295 .help = "packet type as defined in rte_mbuf_ptype", 6296 .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), 6297 item_param), 6298 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), 6299 }, 6300 [ITEM_NSH] = { 6301 .name = "nsh", 6302 .help = "match NSH header", 6303 .priv = PRIV_ITEM(NSH, 6304 sizeof(struct rte_flow_item_nsh)), 6305 .next = NEXT(item_nsh), 6306 .call = parse_vc, 6307 }, 6308 [ITEM_COMPARE] = { 6309 .name = "compare", 6310 .help = "match with the comparison result", 6311 .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)), 6312 .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)), 6313 .call = parse_vc, 6314 }, 6315 [ITEM_COMPARE_OP] = { 6316 .name = "op", 6317 .help = "operation type", 6318 .next = NEXT(item_compare_field, 6319 NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param), 6320 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)), 6321 }, 6322 [ITEM_COMPARE_OP_VALUE] = { 6323 .name = "{operation}", 6324 .help = "operation type value", 6325 .call = parse_vc_compare_op, 6326 .comp = comp_set_compare_op, 6327 }, 6328 [ITEM_COMPARE_FIELD_A_TYPE] = { 6329 .name = "a_type", 6330 .help = "compared field type", 6331 .next = NEXT(compare_field_a, 6332 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param), 6333 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)), 6334 }, 6335 [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = { 6336 .name = "{a_type}", 6337 .help = "compared field type value", 6338 .call = parse_vc_compare_field_id, 6339 .comp = comp_set_compare_field_id, 6340 }, 6341 [ITEM_COMPARE_FIELD_A_LEVEL] = { 6342 .name = "a_level", 6343 .help = "compared field level", 6344 .next = NEXT(compare_field_a, 6345 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param), 6346 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)), 6347 }, 6348 [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = { 6349 .name = "{a_level}", 6350 .help = "compared field level value", 6351 .call = parse_vc_compare_field_level, 6352 .comp = comp_none, 6353 }, 6354 [ITEM_COMPARE_FIELD_A_TAG_INDEX] = { 6355 .name = "a_tag_index", 6356 .help = "compared field tag array", 6357 .next = NEXT(compare_field_a, 6358 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6359 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6360 a.tag_index)), 6361 }, 6362 [ITEM_COMPARE_FIELD_A_TYPE_ID] = { 6363 .name = "a_type_id", 6364 .help = "compared field type ID", 6365 .next = NEXT(compare_field_a, 6366 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6367 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6368 a.type)), 6369 }, 6370 [ITEM_COMPARE_FIELD_A_CLASS_ID] = { 6371 .name = "a_class", 6372 .help = "compared field class ID", 6373 .next = NEXT(compare_field_a, 6374 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6375 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6376 a.class_id)), 6377 }, 6378 [ITEM_COMPARE_FIELD_A_OFFSET] = { 6379 .name = "a_offset", 6380 .help = "compared field bit offset", 6381 .next = NEXT(compare_field_a, 6382 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6383 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6384 a.offset)), 6385 }, 6386 [ITEM_COMPARE_FIELD_B_TYPE] = { 6387 .name = "b_type", 6388 .help = "comparator field type", 6389 .next = NEXT(compare_field_b, 6390 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param), 6391 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6392 b.field)), 6393 }, 6394 [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = { 6395 .name = "{b_type}", 6396 .help = "comparator field type value", 6397 .call = parse_vc_compare_field_id, 6398 .comp = comp_set_compare_field_id, 6399 }, 6400 [ITEM_COMPARE_FIELD_B_LEVEL] = { 6401 .name = "b_level", 6402 .help = "comparator field level", 6403 .next = NEXT(compare_field_b, 6404 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param), 6405 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6406 b.level)), 6407 }, 6408 [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = { 6409 .name = "{b_level}", 6410 .help = "comparator field level value", 6411 .call = parse_vc_compare_field_level, 6412 .comp = comp_none, 6413 }, 6414 [ITEM_COMPARE_FIELD_B_TAG_INDEX] = { 6415 .name = "b_tag_index", 6416 .help = "comparator field tag array", 6417 .next = NEXT(compare_field_b, 6418 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6419 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6420 b.tag_index)), 6421 }, 6422 [ITEM_COMPARE_FIELD_B_TYPE_ID] = { 6423 .name = "b_type_id", 6424 .help = "comparator field type ID", 6425 .next = NEXT(compare_field_b, 6426 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6427 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6428 b.type)), 6429 }, 6430 [ITEM_COMPARE_FIELD_B_CLASS_ID] = { 6431 .name = "b_class", 6432 .help = "comparator field class ID", 6433 .next = NEXT(compare_field_b, 6434 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6435 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6436 b.class_id)), 6437 }, 6438 [ITEM_COMPARE_FIELD_B_OFFSET] = { 6439 .name = "b_offset", 6440 .help = "comparator field bit offset", 6441 .next = NEXT(compare_field_b, 6442 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6443 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6444 b.offset)), 6445 }, 6446 [ITEM_COMPARE_FIELD_B_VALUE] = { 6447 .name = "b_value", 6448 .help = "comparator immediate value", 6449 .next = NEXT(compare_field_b, 6450 NEXT_ENTRY(COMMON_HEX), item_param), 6451 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6452 ARGS_ENTRY_ARB(0, 0), 6453 ARGS_ENTRY(struct rte_flow_item_compare, 6454 b.value)), 6455 }, 6456 [ITEM_COMPARE_FIELD_B_POINTER] = { 6457 .name = "b_ptr", 6458 .help = "pointer to comparator immediate value", 6459 .next = NEXT(compare_field_b, 6460 NEXT_ENTRY(COMMON_HEX), item_param), 6461 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6462 b.pvalue), 6463 ARGS_ENTRY_ARB(0, 0), 6464 ARGS_ENTRY_ARB 6465 (sizeof(struct rte_flow_item_compare), 6466 FLOW_FIELD_PATTERN_SIZE)), 6467 }, 6468 [ITEM_COMPARE_FIELD_WIDTH] = { 6469 .name = "width", 6470 .help = "number of bits to compare", 6471 .next = NEXT(item_compare_field, 6472 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6473 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6474 width)), 6475 }, 6476 6477 /* Validate/create actions. */ 6478 [ACTIONS] = { 6479 .name = "actions", 6480 .help = "submit a list of associated actions", 6481 .next = NEXT(next_action), 6482 .call = parse_vc, 6483 }, 6484 [ACTION_NEXT] = { 6485 .name = "/", 6486 .help = "specify next action", 6487 .next = NEXT(next_action), 6488 }, 6489 [ACTION_END] = { 6490 .name = "end", 6491 .help = "end list of actions", 6492 .priv = PRIV_ACTION(END, 0), 6493 .call = parse_vc, 6494 }, 6495 [ACTION_VOID] = { 6496 .name = "void", 6497 .help = "no-op action", 6498 .priv = PRIV_ACTION(VOID, 0), 6499 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6500 .call = parse_vc, 6501 }, 6502 [ACTION_PASSTHRU] = { 6503 .name = "passthru", 6504 .help = "let subsequent rule process matched packets", 6505 .priv = PRIV_ACTION(PASSTHRU, 0), 6506 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6507 .call = parse_vc, 6508 }, 6509 [ACTION_SKIP_CMAN] = { 6510 .name = "skip_cman", 6511 .help = "bypass cman on received packets", 6512 .priv = PRIV_ACTION(SKIP_CMAN, 0), 6513 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6514 .call = parse_vc, 6515 }, 6516 [ACTION_JUMP] = { 6517 .name = "jump", 6518 .help = "redirect traffic to a given group", 6519 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 6520 .next = NEXT(action_jump), 6521 .call = parse_vc, 6522 }, 6523 [ACTION_JUMP_GROUP] = { 6524 .name = "group", 6525 .help = "group to redirect traffic to", 6526 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 6527 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 6528 .call = parse_vc_conf, 6529 }, 6530 [ACTION_MARK] = { 6531 .name = "mark", 6532 .help = "attach 32 bit value to packets", 6533 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 6534 .next = NEXT(action_mark), 6535 .call = parse_vc, 6536 }, 6537 [ACTION_MARK_ID] = { 6538 .name = "id", 6539 .help = "32 bit value to return with packets", 6540 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6541 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 6542 .call = parse_vc_conf, 6543 }, 6544 [ACTION_FLAG] = { 6545 .name = "flag", 6546 .help = "flag packets", 6547 .priv = PRIV_ACTION(FLAG, 0), 6548 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6549 .call = parse_vc, 6550 }, 6551 [ACTION_QUEUE] = { 6552 .name = "queue", 6553 .help = "assign packets to a given queue index", 6554 .priv = PRIV_ACTION(QUEUE, 6555 sizeof(struct rte_flow_action_queue)), 6556 .next = NEXT(action_queue), 6557 .call = parse_vc, 6558 }, 6559 [ACTION_QUEUE_INDEX] = { 6560 .name = "index", 6561 .help = "queue index to use", 6562 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 6563 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 6564 .call = parse_vc_conf, 6565 }, 6566 [ACTION_DROP] = { 6567 .name = "drop", 6568 .help = "drop packets (note: passthru has priority)", 6569 .priv = PRIV_ACTION(DROP, 0), 6570 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6571 .call = parse_vc, 6572 }, 6573 [ACTION_COUNT] = { 6574 .name = "count", 6575 .help = "enable counters for this rule", 6576 .priv = PRIV_ACTION(COUNT, 6577 sizeof(struct rte_flow_action_count)), 6578 .next = NEXT(action_count), 6579 .call = parse_vc, 6580 }, 6581 [ACTION_COUNT_ID] = { 6582 .name = "identifier", 6583 .help = "counter identifier to use", 6584 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 6585 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 6586 .call = parse_vc_conf, 6587 }, 6588 [ACTION_RSS] = { 6589 .name = "rss", 6590 .help = "spread packets among several queues", 6591 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 6592 .next = NEXT(action_rss), 6593 .call = parse_vc_action_rss, 6594 }, 6595 [ACTION_RSS_FUNC] = { 6596 .name = "func", 6597 .help = "RSS hash function to apply", 6598 .next = NEXT(action_rss, 6599 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 6600 ACTION_RSS_FUNC_TOEPLITZ, 6601 ACTION_RSS_FUNC_SIMPLE_XOR, 6602 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 6603 }, 6604 [ACTION_RSS_FUNC_DEFAULT] = { 6605 .name = "default", 6606 .help = "default hash function", 6607 .call = parse_vc_action_rss_func, 6608 }, 6609 [ACTION_RSS_FUNC_TOEPLITZ] = { 6610 .name = "toeplitz", 6611 .help = "Toeplitz hash function", 6612 .call = parse_vc_action_rss_func, 6613 }, 6614 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 6615 .name = "simple_xor", 6616 .help = "simple XOR hash function", 6617 .call = parse_vc_action_rss_func, 6618 }, 6619 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 6620 .name = "symmetric_toeplitz", 6621 .help = "Symmetric Toeplitz hash function", 6622 .call = parse_vc_action_rss_func, 6623 }, 6624 [ACTION_RSS_LEVEL] = { 6625 .name = "level", 6626 .help = "encapsulation level for \"types\"", 6627 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6628 .args = ARGS(ARGS_ENTRY_ARB 6629 (offsetof(struct action_rss_data, conf) + 6630 offsetof(struct rte_flow_action_rss, level), 6631 sizeof(((struct rte_flow_action_rss *)0)-> 6632 level))), 6633 }, 6634 [ACTION_RSS_TYPES] = { 6635 .name = "types", 6636 .help = "specific RSS hash types", 6637 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 6638 }, 6639 [ACTION_RSS_TYPE] = { 6640 .name = "{type}", 6641 .help = "RSS hash type", 6642 .call = parse_vc_action_rss_type, 6643 .comp = comp_vc_action_rss_type, 6644 }, 6645 [ACTION_RSS_KEY] = { 6646 .name = "key", 6647 .help = "RSS hash key", 6648 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 6649 .args = ARGS(ARGS_ENTRY_ARB 6650 (offsetof(struct action_rss_data, conf) + 6651 offsetof(struct rte_flow_action_rss, key), 6652 sizeof(((struct rte_flow_action_rss *)0)->key)), 6653 ARGS_ENTRY_ARB 6654 (offsetof(struct action_rss_data, conf) + 6655 offsetof(struct rte_flow_action_rss, key_len), 6656 sizeof(((struct rte_flow_action_rss *)0)-> 6657 key_len)), 6658 ARGS_ENTRY(struct action_rss_data, key)), 6659 }, 6660 [ACTION_RSS_KEY_LEN] = { 6661 .name = "key_len", 6662 .help = "RSS hash key length in bytes", 6663 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6664 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6665 (offsetof(struct action_rss_data, conf) + 6666 offsetof(struct rte_flow_action_rss, key_len), 6667 sizeof(((struct rte_flow_action_rss *)0)-> 6668 key_len), 6669 0, 6670 RSS_HASH_KEY_LENGTH)), 6671 }, 6672 [ACTION_RSS_QUEUES] = { 6673 .name = "queues", 6674 .help = "queue indices to use", 6675 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 6676 .call = parse_vc_conf, 6677 }, 6678 [ACTION_RSS_QUEUE] = { 6679 .name = "{queue}", 6680 .help = "queue index", 6681 .call = parse_vc_action_rss_queue, 6682 .comp = comp_vc_action_rss_queue, 6683 }, 6684 [ACTION_PF] = { 6685 .name = "pf", 6686 .help = "direct traffic to physical function", 6687 .priv = PRIV_ACTION(PF, 0), 6688 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6689 .call = parse_vc, 6690 }, 6691 [ACTION_VF] = { 6692 .name = "vf", 6693 .help = "direct traffic to a virtual function ID", 6694 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 6695 .next = NEXT(action_vf), 6696 .call = parse_vc, 6697 }, 6698 [ACTION_VF_ORIGINAL] = { 6699 .name = "original", 6700 .help = "use original VF ID if possible", 6701 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 6702 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 6703 original, 1)), 6704 .call = parse_vc_conf, 6705 }, 6706 [ACTION_VF_ID] = { 6707 .name = "id", 6708 .help = "VF ID", 6709 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 6710 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 6711 .call = parse_vc_conf, 6712 }, 6713 [ACTION_PORT_ID] = { 6714 .name = "port_id", 6715 .help = "direct matching traffic to a given DPDK port ID", 6716 .priv = PRIV_ACTION(PORT_ID, 6717 sizeof(struct rte_flow_action_port_id)), 6718 .next = NEXT(action_port_id), 6719 .call = parse_vc, 6720 }, 6721 [ACTION_PORT_ID_ORIGINAL] = { 6722 .name = "original", 6723 .help = "use original DPDK port ID if possible", 6724 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 6725 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 6726 original, 1)), 6727 .call = parse_vc_conf, 6728 }, 6729 [ACTION_PORT_ID_ID] = { 6730 .name = "id", 6731 .help = "DPDK port ID", 6732 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 6733 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 6734 .call = parse_vc_conf, 6735 }, 6736 [ACTION_METER] = { 6737 .name = "meter", 6738 .help = "meter the directed packets at given id", 6739 .priv = PRIV_ACTION(METER, 6740 sizeof(struct rte_flow_action_meter)), 6741 .next = NEXT(action_meter), 6742 .call = parse_vc, 6743 }, 6744 [ACTION_METER_COLOR] = { 6745 .name = "color", 6746 .help = "meter color for the packets", 6747 .priv = PRIV_ACTION(METER_COLOR, 6748 sizeof(struct rte_flow_action_meter_color)), 6749 .next = NEXT(action_meter_color), 6750 .call = parse_vc, 6751 }, 6752 [ACTION_METER_COLOR_TYPE] = { 6753 .name = "type", 6754 .help = "specific meter color", 6755 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6756 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 6757 ACTION_METER_COLOR_YELLOW, 6758 ACTION_METER_COLOR_RED)), 6759 }, 6760 [ACTION_METER_COLOR_GREEN] = { 6761 .name = "green", 6762 .help = "meter color green", 6763 .call = parse_vc_action_meter_color_type, 6764 }, 6765 [ACTION_METER_COLOR_YELLOW] = { 6766 .name = "yellow", 6767 .help = "meter color yellow", 6768 .call = parse_vc_action_meter_color_type, 6769 }, 6770 [ACTION_METER_COLOR_RED] = { 6771 .name = "red", 6772 .help = "meter color red", 6773 .call = parse_vc_action_meter_color_type, 6774 }, 6775 [ACTION_METER_ID] = { 6776 .name = "mtr_id", 6777 .help = "meter id to use", 6778 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 6779 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 6780 .call = parse_vc_conf, 6781 }, 6782 [ACTION_METER_MARK] = { 6783 .name = "meter_mark", 6784 .help = "meter the directed packets using profile and policy", 6785 .priv = PRIV_ACTION(METER_MARK, 6786 sizeof(struct rte_flow_action_meter_mark)), 6787 .next = NEXT(action_meter_mark), 6788 .call = parse_vc, 6789 }, 6790 [ACTION_METER_PROFILE] = { 6791 .name = "mtr_profile", 6792 .help = "meter profile id to use", 6793 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 6794 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6795 }, 6796 [ACTION_METER_PROFILE_ID2PTR] = { 6797 .name = "{mtr_profile_id}", 6798 .type = "PROFILE_ID", 6799 .help = "meter profile id", 6800 .next = NEXT(action_meter_mark), 6801 .call = parse_meter_profile_id2ptr, 6802 .comp = comp_none, 6803 }, 6804 [ACTION_METER_POLICY] = { 6805 .name = "mtr_policy", 6806 .help = "meter policy id to use", 6807 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 6808 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6809 }, 6810 [ACTION_METER_POLICY_ID2PTR] = { 6811 .name = "{mtr_policy_id}", 6812 .type = "POLICY_ID", 6813 .help = "meter policy id", 6814 .next = NEXT(action_meter_mark), 6815 .call = parse_meter_policy_id2ptr, 6816 .comp = comp_none, 6817 }, 6818 [ACTION_METER_COLOR_MODE] = { 6819 .name = "mtr_color_mode", 6820 .help = "meter color awareness mode", 6821 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6822 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 6823 .call = parse_vc_conf, 6824 }, 6825 [ACTION_METER_STATE] = { 6826 .name = "mtr_state", 6827 .help = "meter state", 6828 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6829 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 6830 .call = parse_vc_conf, 6831 }, 6832 [ACTION_OF_DEC_NW_TTL] = { 6833 .name = "of_dec_nw_ttl", 6834 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 6835 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 6836 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6837 .call = parse_vc, 6838 }, 6839 [ACTION_OF_POP_VLAN] = { 6840 .name = "of_pop_vlan", 6841 .help = "OpenFlow's OFPAT_POP_VLAN", 6842 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 6843 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6844 .call = parse_vc, 6845 }, 6846 [ACTION_OF_PUSH_VLAN] = { 6847 .name = "of_push_vlan", 6848 .help = "OpenFlow's OFPAT_PUSH_VLAN", 6849 .priv = PRIV_ACTION 6850 (OF_PUSH_VLAN, 6851 sizeof(struct rte_flow_action_of_push_vlan)), 6852 .next = NEXT(action_of_push_vlan), 6853 .call = parse_vc, 6854 }, 6855 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 6856 .name = "ethertype", 6857 .help = "EtherType", 6858 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 6859 .args = ARGS(ARGS_ENTRY_HTON 6860 (struct rte_flow_action_of_push_vlan, 6861 ethertype)), 6862 .call = parse_vc_conf, 6863 }, 6864 [ACTION_OF_SET_VLAN_VID] = { 6865 .name = "of_set_vlan_vid", 6866 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 6867 .priv = PRIV_ACTION 6868 (OF_SET_VLAN_VID, 6869 sizeof(struct rte_flow_action_of_set_vlan_vid)), 6870 .next = NEXT(action_of_set_vlan_vid), 6871 .call = parse_vc, 6872 }, 6873 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 6874 .name = "vlan_vid", 6875 .help = "VLAN id", 6876 .next = NEXT(action_of_set_vlan_vid, 6877 NEXT_ENTRY(COMMON_UNSIGNED)), 6878 .args = ARGS(ARGS_ENTRY_HTON 6879 (struct rte_flow_action_of_set_vlan_vid, 6880 vlan_vid)), 6881 .call = parse_vc_conf, 6882 }, 6883 [ACTION_OF_SET_VLAN_PCP] = { 6884 .name = "of_set_vlan_pcp", 6885 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 6886 .priv = PRIV_ACTION 6887 (OF_SET_VLAN_PCP, 6888 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 6889 .next = NEXT(action_of_set_vlan_pcp), 6890 .call = parse_vc, 6891 }, 6892 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 6893 .name = "vlan_pcp", 6894 .help = "VLAN priority", 6895 .next = NEXT(action_of_set_vlan_pcp, 6896 NEXT_ENTRY(COMMON_UNSIGNED)), 6897 .args = ARGS(ARGS_ENTRY_HTON 6898 (struct rte_flow_action_of_set_vlan_pcp, 6899 vlan_pcp)), 6900 .call = parse_vc_conf, 6901 }, 6902 [ACTION_OF_POP_MPLS] = { 6903 .name = "of_pop_mpls", 6904 .help = "OpenFlow's OFPAT_POP_MPLS", 6905 .priv = PRIV_ACTION(OF_POP_MPLS, 6906 sizeof(struct rte_flow_action_of_pop_mpls)), 6907 .next = NEXT(action_of_pop_mpls), 6908 .call = parse_vc, 6909 }, 6910 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 6911 .name = "ethertype", 6912 .help = "EtherType", 6913 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6914 .args = ARGS(ARGS_ENTRY_HTON 6915 (struct rte_flow_action_of_pop_mpls, 6916 ethertype)), 6917 .call = parse_vc_conf, 6918 }, 6919 [ACTION_OF_PUSH_MPLS] = { 6920 .name = "of_push_mpls", 6921 .help = "OpenFlow's OFPAT_PUSH_MPLS", 6922 .priv = PRIV_ACTION 6923 (OF_PUSH_MPLS, 6924 sizeof(struct rte_flow_action_of_push_mpls)), 6925 .next = NEXT(action_of_push_mpls), 6926 .call = parse_vc, 6927 }, 6928 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 6929 .name = "ethertype", 6930 .help = "EtherType", 6931 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6932 .args = ARGS(ARGS_ENTRY_HTON 6933 (struct rte_flow_action_of_push_mpls, 6934 ethertype)), 6935 .call = parse_vc_conf, 6936 }, 6937 [ACTION_VXLAN_ENCAP] = { 6938 .name = "vxlan_encap", 6939 .help = "VXLAN encapsulation, uses configuration set by \"set" 6940 " vxlan\"", 6941 .priv = PRIV_ACTION(VXLAN_ENCAP, 6942 sizeof(struct action_vxlan_encap_data)), 6943 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6944 .call = parse_vc_action_vxlan_encap, 6945 }, 6946 [ACTION_VXLAN_DECAP] = { 6947 .name = "vxlan_decap", 6948 .help = "Performs a decapsulation action by stripping all" 6949 " headers of the VXLAN tunnel network overlay from the" 6950 " matched flow.", 6951 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 6952 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6953 .call = parse_vc, 6954 }, 6955 [ACTION_NVGRE_ENCAP] = { 6956 .name = "nvgre_encap", 6957 .help = "NVGRE encapsulation, uses configuration set by \"set" 6958 " nvgre\"", 6959 .priv = PRIV_ACTION(NVGRE_ENCAP, 6960 sizeof(struct action_nvgre_encap_data)), 6961 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6962 .call = parse_vc_action_nvgre_encap, 6963 }, 6964 [ACTION_NVGRE_DECAP] = { 6965 .name = "nvgre_decap", 6966 .help = "Performs a decapsulation action by stripping all" 6967 " headers of the NVGRE tunnel network overlay from the" 6968 " matched flow.", 6969 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 6970 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6971 .call = parse_vc, 6972 }, 6973 [ACTION_L2_ENCAP] = { 6974 .name = "l2_encap", 6975 .help = "l2 encap, uses configuration set by" 6976 " \"set l2_encap\"", 6977 .priv = PRIV_ACTION(RAW_ENCAP, 6978 sizeof(struct action_raw_encap_data)), 6979 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6980 .call = parse_vc_action_l2_encap, 6981 }, 6982 [ACTION_L2_DECAP] = { 6983 .name = "l2_decap", 6984 .help = "l2 decap, uses configuration set by" 6985 " \"set l2_decap\"", 6986 .priv = PRIV_ACTION(RAW_DECAP, 6987 sizeof(struct action_raw_decap_data)), 6988 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6989 .call = parse_vc_action_l2_decap, 6990 }, 6991 [ACTION_MPLSOGRE_ENCAP] = { 6992 .name = "mplsogre_encap", 6993 .help = "mplsogre encapsulation, uses configuration set by" 6994 " \"set mplsogre_encap\"", 6995 .priv = PRIV_ACTION(RAW_ENCAP, 6996 sizeof(struct action_raw_encap_data)), 6997 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6998 .call = parse_vc_action_mplsogre_encap, 6999 }, 7000 [ACTION_MPLSOGRE_DECAP] = { 7001 .name = "mplsogre_decap", 7002 .help = "mplsogre decapsulation, uses configuration set by" 7003 " \"set mplsogre_decap\"", 7004 .priv = PRIV_ACTION(RAW_DECAP, 7005 sizeof(struct action_raw_decap_data)), 7006 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7007 .call = parse_vc_action_mplsogre_decap, 7008 }, 7009 [ACTION_MPLSOUDP_ENCAP] = { 7010 .name = "mplsoudp_encap", 7011 .help = "mplsoudp encapsulation, uses configuration set by" 7012 " \"set mplsoudp_encap\"", 7013 .priv = PRIV_ACTION(RAW_ENCAP, 7014 sizeof(struct action_raw_encap_data)), 7015 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7016 .call = parse_vc_action_mplsoudp_encap, 7017 }, 7018 [ACTION_MPLSOUDP_DECAP] = { 7019 .name = "mplsoudp_decap", 7020 .help = "mplsoudp decapsulation, uses configuration set by" 7021 " \"set mplsoudp_decap\"", 7022 .priv = PRIV_ACTION(RAW_DECAP, 7023 sizeof(struct action_raw_decap_data)), 7024 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7025 .call = parse_vc_action_mplsoudp_decap, 7026 }, 7027 [ACTION_SET_IPV4_SRC] = { 7028 .name = "set_ipv4_src", 7029 .help = "Set a new IPv4 source address in the outermost" 7030 " IPv4 header", 7031 .priv = PRIV_ACTION(SET_IPV4_SRC, 7032 sizeof(struct rte_flow_action_set_ipv4)), 7033 .next = NEXT(action_set_ipv4_src), 7034 .call = parse_vc, 7035 }, 7036 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 7037 .name = "ipv4_addr", 7038 .help = "new IPv4 source address to set", 7039 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 7040 .args = ARGS(ARGS_ENTRY_HTON 7041 (struct rte_flow_action_set_ipv4, ipv4_addr)), 7042 .call = parse_vc_conf, 7043 }, 7044 [ACTION_SET_IPV4_DST] = { 7045 .name = "set_ipv4_dst", 7046 .help = "Set a new IPv4 destination address in the outermost" 7047 " IPv4 header", 7048 .priv = PRIV_ACTION(SET_IPV4_DST, 7049 sizeof(struct rte_flow_action_set_ipv4)), 7050 .next = NEXT(action_set_ipv4_dst), 7051 .call = parse_vc, 7052 }, 7053 [ACTION_SET_IPV4_DST_IPV4_DST] = { 7054 .name = "ipv4_addr", 7055 .help = "new IPv4 destination address to set", 7056 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 7057 .args = ARGS(ARGS_ENTRY_HTON 7058 (struct rte_flow_action_set_ipv4, ipv4_addr)), 7059 .call = parse_vc_conf, 7060 }, 7061 [ACTION_SET_IPV6_SRC] = { 7062 .name = "set_ipv6_src", 7063 .help = "Set a new IPv6 source address in the outermost" 7064 " IPv6 header", 7065 .priv = PRIV_ACTION(SET_IPV6_SRC, 7066 sizeof(struct rte_flow_action_set_ipv6)), 7067 .next = NEXT(action_set_ipv6_src), 7068 .call = parse_vc, 7069 }, 7070 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 7071 .name = "ipv6_addr", 7072 .help = "new IPv6 source address to set", 7073 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7074 .args = ARGS(ARGS_ENTRY_HTON 7075 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7076 .call = parse_vc_conf, 7077 }, 7078 [ACTION_SET_IPV6_DST] = { 7079 .name = "set_ipv6_dst", 7080 .help = "Set a new IPv6 destination address in the outermost" 7081 " IPv6 header", 7082 .priv = PRIV_ACTION(SET_IPV6_DST, 7083 sizeof(struct rte_flow_action_set_ipv6)), 7084 .next = NEXT(action_set_ipv6_dst), 7085 .call = parse_vc, 7086 }, 7087 [ACTION_SET_IPV6_DST_IPV6_DST] = { 7088 .name = "ipv6_addr", 7089 .help = "new IPv6 destination address to set", 7090 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7091 .args = ARGS(ARGS_ENTRY_HTON 7092 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7093 .call = parse_vc_conf, 7094 }, 7095 [ACTION_SET_TP_SRC] = { 7096 .name = "set_tp_src", 7097 .help = "set a new source port number in the outermost" 7098 " TCP/UDP header", 7099 .priv = PRIV_ACTION(SET_TP_SRC, 7100 sizeof(struct rte_flow_action_set_tp)), 7101 .next = NEXT(action_set_tp_src), 7102 .call = parse_vc, 7103 }, 7104 [ACTION_SET_TP_SRC_TP_SRC] = { 7105 .name = "port", 7106 .help = "new source port number to set", 7107 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 7108 .args = ARGS(ARGS_ENTRY_HTON 7109 (struct rte_flow_action_set_tp, port)), 7110 .call = parse_vc_conf, 7111 }, 7112 [ACTION_SET_TP_DST] = { 7113 .name = "set_tp_dst", 7114 .help = "set a new destination port number in the outermost" 7115 " TCP/UDP header", 7116 .priv = PRIV_ACTION(SET_TP_DST, 7117 sizeof(struct rte_flow_action_set_tp)), 7118 .next = NEXT(action_set_tp_dst), 7119 .call = parse_vc, 7120 }, 7121 [ACTION_SET_TP_DST_TP_DST] = { 7122 .name = "port", 7123 .help = "new destination port number to set", 7124 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 7125 .args = ARGS(ARGS_ENTRY_HTON 7126 (struct rte_flow_action_set_tp, port)), 7127 .call = parse_vc_conf, 7128 }, 7129 [ACTION_MAC_SWAP] = { 7130 .name = "mac_swap", 7131 .help = "Swap the source and destination MAC addresses" 7132 " in the outermost Ethernet header", 7133 .priv = PRIV_ACTION(MAC_SWAP, 0), 7134 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7135 .call = parse_vc, 7136 }, 7137 [ACTION_DEC_TTL] = { 7138 .name = "dec_ttl", 7139 .help = "decrease network TTL if available", 7140 .priv = PRIV_ACTION(DEC_TTL, 0), 7141 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7142 .call = parse_vc, 7143 }, 7144 [ACTION_SET_TTL] = { 7145 .name = "set_ttl", 7146 .help = "set ttl value", 7147 .priv = PRIV_ACTION(SET_TTL, 7148 sizeof(struct rte_flow_action_set_ttl)), 7149 .next = NEXT(action_set_ttl), 7150 .call = parse_vc, 7151 }, 7152 [ACTION_SET_TTL_TTL] = { 7153 .name = "ttl_value", 7154 .help = "new ttl value to set", 7155 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 7156 .args = ARGS(ARGS_ENTRY_HTON 7157 (struct rte_flow_action_set_ttl, ttl_value)), 7158 .call = parse_vc_conf, 7159 }, 7160 [ACTION_SET_MAC_SRC] = { 7161 .name = "set_mac_src", 7162 .help = "set source mac address", 7163 .priv = PRIV_ACTION(SET_MAC_SRC, 7164 sizeof(struct rte_flow_action_set_mac)), 7165 .next = NEXT(action_set_mac_src), 7166 .call = parse_vc, 7167 }, 7168 [ACTION_SET_MAC_SRC_MAC_SRC] = { 7169 .name = "mac_addr", 7170 .help = "new source mac address", 7171 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 7172 .args = ARGS(ARGS_ENTRY_HTON 7173 (struct rte_flow_action_set_mac, mac_addr)), 7174 .call = parse_vc_conf, 7175 }, 7176 [ACTION_SET_MAC_DST] = { 7177 .name = "set_mac_dst", 7178 .help = "set destination mac address", 7179 .priv = PRIV_ACTION(SET_MAC_DST, 7180 sizeof(struct rte_flow_action_set_mac)), 7181 .next = NEXT(action_set_mac_dst), 7182 .call = parse_vc, 7183 }, 7184 [ACTION_SET_MAC_DST_MAC_DST] = { 7185 .name = "mac_addr", 7186 .help = "new destination mac address to set", 7187 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 7188 .args = ARGS(ARGS_ENTRY_HTON 7189 (struct rte_flow_action_set_mac, mac_addr)), 7190 .call = parse_vc_conf, 7191 }, 7192 [ACTION_INC_TCP_SEQ] = { 7193 .name = "inc_tcp_seq", 7194 .help = "increase TCP sequence number", 7195 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 7196 .next = NEXT(action_inc_tcp_seq), 7197 .call = parse_vc, 7198 }, 7199 [ACTION_INC_TCP_SEQ_VALUE] = { 7200 .name = "value", 7201 .help = "the value to increase TCP sequence number by", 7202 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7203 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7204 .call = parse_vc_conf, 7205 }, 7206 [ACTION_DEC_TCP_SEQ] = { 7207 .name = "dec_tcp_seq", 7208 .help = "decrease TCP sequence number", 7209 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 7210 .next = NEXT(action_dec_tcp_seq), 7211 .call = parse_vc, 7212 }, 7213 [ACTION_DEC_TCP_SEQ_VALUE] = { 7214 .name = "value", 7215 .help = "the value to decrease TCP sequence number by", 7216 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7217 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7218 .call = parse_vc_conf, 7219 }, 7220 [ACTION_INC_TCP_ACK] = { 7221 .name = "inc_tcp_ack", 7222 .help = "increase TCP acknowledgment number", 7223 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 7224 .next = NEXT(action_inc_tcp_ack), 7225 .call = parse_vc, 7226 }, 7227 [ACTION_INC_TCP_ACK_VALUE] = { 7228 .name = "value", 7229 .help = "the value to increase TCP acknowledgment number by", 7230 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7231 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7232 .call = parse_vc_conf, 7233 }, 7234 [ACTION_DEC_TCP_ACK] = { 7235 .name = "dec_tcp_ack", 7236 .help = "decrease TCP acknowledgment number", 7237 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 7238 .next = NEXT(action_dec_tcp_ack), 7239 .call = parse_vc, 7240 }, 7241 [ACTION_DEC_TCP_ACK_VALUE] = { 7242 .name = "value", 7243 .help = "the value to decrease TCP acknowledgment number by", 7244 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7245 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7246 .call = parse_vc_conf, 7247 }, 7248 [ACTION_RAW_ENCAP] = { 7249 .name = "raw_encap", 7250 .help = "encapsulation data, defined by set raw_encap", 7251 .priv = PRIV_ACTION(RAW_ENCAP, 7252 sizeof(struct action_raw_encap_data)), 7253 .next = NEXT(action_raw_encap), 7254 .call = parse_vc_action_raw_encap, 7255 }, 7256 [ACTION_RAW_ENCAP_SIZE] = { 7257 .name = "size", 7258 .help = "raw encap size", 7259 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7260 NEXT_ENTRY(COMMON_UNSIGNED)), 7261 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_raw_encap, size)), 7262 .call = parse_vc_conf, 7263 }, 7264 [ACTION_RAW_ENCAP_INDEX] = { 7265 .name = "index", 7266 .help = "the index of raw_encap_confs", 7267 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 7268 }, 7269 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 7270 .name = "{index}", 7271 .type = "UNSIGNED", 7272 .help = "unsigned integer value", 7273 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7274 .call = parse_vc_action_raw_encap_index, 7275 .comp = comp_set_raw_index, 7276 }, 7277 [ACTION_RAW_DECAP] = { 7278 .name = "raw_decap", 7279 .help = "decapsulation data, defined by set raw_encap", 7280 .priv = PRIV_ACTION(RAW_DECAP, 7281 sizeof(struct action_raw_decap_data)), 7282 .next = NEXT(action_raw_decap), 7283 .call = parse_vc_action_raw_decap, 7284 }, 7285 [ACTION_RAW_DECAP_INDEX] = { 7286 .name = "index", 7287 .help = "the index of raw_encap_confs", 7288 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 7289 }, 7290 [ACTION_RAW_DECAP_INDEX_VALUE] = { 7291 .name = "{index}", 7292 .type = "UNSIGNED", 7293 .help = "unsigned integer value", 7294 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7295 .call = parse_vc_action_raw_decap_index, 7296 .comp = comp_set_raw_index, 7297 }, 7298 [ACTION_MODIFY_FIELD] = { 7299 .name = "modify_field", 7300 .help = "modify destination field with data from source field", 7301 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 7302 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 7303 .call = parse_vc, 7304 }, 7305 [ACTION_MODIFY_FIELD_OP] = { 7306 .name = "op", 7307 .help = "operation type", 7308 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 7309 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 7310 .call = parse_vc_conf, 7311 }, 7312 [ACTION_MODIFY_FIELD_OP_VALUE] = { 7313 .name = "{operation}", 7314 .help = "operation type value", 7315 .call = parse_vc_modify_field_op, 7316 .comp = comp_set_modify_field_op, 7317 }, 7318 [ACTION_MODIFY_FIELD_DST_TYPE] = { 7319 .name = "dst_type", 7320 .help = "destination field type", 7321 .next = NEXT(action_modify_field_dst, 7322 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 7323 .call = parse_vc_conf, 7324 }, 7325 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 7326 .name = "{dst_type}", 7327 .help = "destination field type value", 7328 .call = parse_vc_modify_field_id, 7329 .comp = comp_set_modify_field_id, 7330 }, 7331 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 7332 .name = "dst_level", 7333 .help = "destination field level", 7334 .next = NEXT(action_modify_field_dst, 7335 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), 7336 .call = parse_vc_conf, 7337 }, 7338 [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { 7339 .name = "{dst_level}", 7340 .help = "destination field level value", 7341 .call = parse_vc_modify_field_level, 7342 .comp = comp_none, 7343 }, 7344 [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { 7345 .name = "dst_tag_index", 7346 .help = "destination field tag array", 7347 .next = NEXT(action_modify_field_dst, 7348 NEXT_ENTRY(COMMON_UNSIGNED)), 7349 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7350 dst.tag_index)), 7351 .call = parse_vc_conf, 7352 }, 7353 [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { 7354 .name = "dst_type_id", 7355 .help = "destination field type ID", 7356 .next = NEXT(action_modify_field_dst, 7357 NEXT_ENTRY(COMMON_UNSIGNED)), 7358 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7359 dst.type)), 7360 .call = parse_vc_conf, 7361 }, 7362 [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { 7363 .name = "dst_class", 7364 .help = "destination field class ID", 7365 .next = NEXT(action_modify_field_dst, 7366 NEXT_ENTRY(COMMON_UNSIGNED)), 7367 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7368 dst.class_id)), 7369 .call = parse_vc_conf, 7370 }, 7371 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 7372 .name = "dst_offset", 7373 .help = "destination field bit offset", 7374 .next = NEXT(action_modify_field_dst, 7375 NEXT_ENTRY(COMMON_UNSIGNED)), 7376 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7377 dst.offset)), 7378 .call = parse_vc_conf, 7379 }, 7380 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 7381 .name = "src_type", 7382 .help = "source field type", 7383 .next = NEXT(action_modify_field_src, 7384 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 7385 .call = parse_vc_conf, 7386 }, 7387 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 7388 .name = "{src_type}", 7389 .help = "source field type value", 7390 .call = parse_vc_modify_field_id, 7391 .comp = comp_set_modify_field_id, 7392 }, 7393 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 7394 .name = "src_level", 7395 .help = "source field level", 7396 .next = NEXT(action_modify_field_src, 7397 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), 7398 .call = parse_vc_conf, 7399 }, 7400 [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { 7401 .name = "{src_level}", 7402 .help = "source field level value", 7403 .call = parse_vc_modify_field_level, 7404 .comp = comp_none, 7405 }, 7406 [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { 7407 .name = "src_tag_index", 7408 .help = "source field tag array", 7409 .next = NEXT(action_modify_field_src, 7410 NEXT_ENTRY(COMMON_UNSIGNED)), 7411 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7412 src.tag_index)), 7413 .call = parse_vc_conf, 7414 }, 7415 [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { 7416 .name = "src_type_id", 7417 .help = "source field type ID", 7418 .next = NEXT(action_modify_field_src, 7419 NEXT_ENTRY(COMMON_UNSIGNED)), 7420 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7421 src.type)), 7422 .call = parse_vc_conf, 7423 }, 7424 [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { 7425 .name = "src_class", 7426 .help = "source field class ID", 7427 .next = NEXT(action_modify_field_src, 7428 NEXT_ENTRY(COMMON_UNSIGNED)), 7429 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7430 src.class_id)), 7431 .call = parse_vc_conf, 7432 }, 7433 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 7434 .name = "src_offset", 7435 .help = "source field bit offset", 7436 .next = NEXT(action_modify_field_src, 7437 NEXT_ENTRY(COMMON_UNSIGNED)), 7438 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7439 src.offset)), 7440 .call = parse_vc_conf, 7441 }, 7442 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 7443 .name = "src_value", 7444 .help = "source immediate value", 7445 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7446 NEXT_ENTRY(COMMON_HEX)), 7447 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 7448 ARGS_ENTRY_ARB(0, 0), 7449 ARGS_ENTRY(struct rte_flow_action_modify_field, 7450 src.value)), 7451 .call = parse_vc_conf, 7452 }, 7453 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 7454 .name = "src_ptr", 7455 .help = "pointer to source immediate value", 7456 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7457 NEXT_ENTRY(COMMON_HEX)), 7458 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7459 src.pvalue), 7460 ARGS_ENTRY_ARB(0, 0), 7461 ARGS_ENTRY_ARB 7462 (sizeof(struct rte_flow_action_modify_field), 7463 FLOW_FIELD_PATTERN_SIZE)), 7464 .call = parse_vc_conf, 7465 }, 7466 [ACTION_MODIFY_FIELD_WIDTH] = { 7467 .name = "width", 7468 .help = "number of bits to copy", 7469 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7470 NEXT_ENTRY(COMMON_UNSIGNED)), 7471 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7472 width)), 7473 .call = parse_vc_conf, 7474 }, 7475 [ACTION_SEND_TO_KERNEL] = { 7476 .name = "send_to_kernel", 7477 .help = "send packets to kernel", 7478 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 7479 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7480 .call = parse_vc, 7481 }, 7482 [ACTION_IPV6_EXT_REMOVE] = { 7483 .name = "ipv6_ext_remove", 7484 .help = "IPv6 extension type, defined by set ipv6_ext_remove", 7485 .priv = PRIV_ACTION(IPV6_EXT_REMOVE, 7486 sizeof(struct action_ipv6_ext_remove_data)), 7487 .next = NEXT(action_ipv6_ext_remove), 7488 .call = parse_vc_action_ipv6_ext_remove, 7489 }, 7490 [ACTION_IPV6_EXT_REMOVE_INDEX] = { 7491 .name = "index", 7492 .help = "the index of ipv6_ext_remove", 7493 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), 7494 }, 7495 [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { 7496 .name = "{index}", 7497 .type = "UNSIGNED", 7498 .help = "unsigned integer value", 7499 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7500 .call = parse_vc_action_ipv6_ext_remove_index, 7501 .comp = comp_set_ipv6_ext_index, 7502 }, 7503 [ACTION_IPV6_EXT_PUSH] = { 7504 .name = "ipv6_ext_push", 7505 .help = "IPv6 extension data, defined by set ipv6_ext_push", 7506 .priv = PRIV_ACTION(IPV6_EXT_PUSH, 7507 sizeof(struct action_ipv6_ext_push_data)), 7508 .next = NEXT(action_ipv6_ext_push), 7509 .call = parse_vc_action_ipv6_ext_push, 7510 }, 7511 [ACTION_IPV6_EXT_PUSH_INDEX] = { 7512 .name = "index", 7513 .help = "the index of ipv6_ext_push", 7514 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), 7515 }, 7516 [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { 7517 .name = "{index}", 7518 .type = "UNSIGNED", 7519 .help = "unsigned integer value", 7520 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7521 .call = parse_vc_action_ipv6_ext_push_index, 7522 .comp = comp_set_ipv6_ext_index, 7523 }, 7524 [ACTION_NAT64] = { 7525 .name = "nat64", 7526 .help = "NAT64 IP headers translation", 7527 .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), 7528 .next = NEXT(action_nat64), 7529 .call = parse_vc, 7530 }, 7531 [ACTION_NAT64_MODE] = { 7532 .name = "type", 7533 .help = "NAT64 translation type", 7534 .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), 7535 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), 7536 .call = parse_vc_conf, 7537 }, 7538 /* Top level command. */ 7539 [SET] = { 7540 .name = "set", 7541 .help = "set raw encap/decap/sample data", 7542 .type = "set raw_encap|raw_decap <index> <pattern>" 7543 " or set sample_actions <index> <action>", 7544 .next = NEXT(NEXT_ENTRY 7545 (SET_RAW_ENCAP, 7546 SET_RAW_DECAP, 7547 SET_SAMPLE_ACTIONS, 7548 SET_IPV6_EXT_REMOVE, 7549 SET_IPV6_EXT_PUSH)), 7550 .call = parse_set_init, 7551 }, 7552 /* Sub-level commands. */ 7553 [SET_RAW_ENCAP] = { 7554 .name = "raw_encap", 7555 .help = "set raw encap data", 7556 .next = NEXT(next_set_raw), 7557 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7558 (offsetof(struct buffer, port), 7559 sizeof(((struct buffer *)0)->port), 7560 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7561 .call = parse_set_raw_encap_decap, 7562 }, 7563 [SET_RAW_DECAP] = { 7564 .name = "raw_decap", 7565 .help = "set raw decap data", 7566 .next = NEXT(next_set_raw), 7567 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7568 (offsetof(struct buffer, port), 7569 sizeof(((struct buffer *)0)->port), 7570 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7571 .call = parse_set_raw_encap_decap, 7572 }, 7573 [SET_RAW_INDEX] = { 7574 .name = "{index}", 7575 .type = "COMMON_UNSIGNED", 7576 .help = "index of raw_encap/raw_decap data", 7577 .next = NEXT(next_item), 7578 .call = parse_port, 7579 }, 7580 [SET_SAMPLE_INDEX] = { 7581 .name = "{index}", 7582 .type = "UNSIGNED", 7583 .help = "index of sample actions", 7584 .next = NEXT(next_action_sample), 7585 .call = parse_port, 7586 }, 7587 [SET_SAMPLE_ACTIONS] = { 7588 .name = "sample_actions", 7589 .help = "set sample actions list", 7590 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 7591 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7592 (offsetof(struct buffer, port), 7593 sizeof(((struct buffer *)0)->port), 7594 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 7595 .call = parse_set_sample_action, 7596 }, 7597 [SET_IPV6_EXT_PUSH] = { 7598 .name = "ipv6_ext_push", 7599 .help = "set IPv6 extension header", 7600 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7601 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7602 (offsetof(struct buffer, port), 7603 sizeof(((struct buffer *)0)->port), 7604 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7605 .call = parse_set_ipv6_ext_action, 7606 }, 7607 [SET_IPV6_EXT_REMOVE] = { 7608 .name = "ipv6_ext_remove", 7609 .help = "set IPv6 extension header", 7610 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7611 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7612 (offsetof(struct buffer, port), 7613 sizeof(((struct buffer *)0)->port), 7614 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7615 .call = parse_set_ipv6_ext_action, 7616 }, 7617 [SET_IPV6_EXT_INDEX] = { 7618 .name = "{index}", 7619 .type = "UNSIGNED", 7620 .help = "index of ipv6 extension push/remove actions", 7621 .next = NEXT(item_ipv6_push_ext), 7622 .call = parse_port, 7623 }, 7624 [ITEM_IPV6_PUSH_REMOVE_EXT] = { 7625 .name = "ipv6_ext", 7626 .help = "set IPv6 extension header", 7627 .priv = PRIV_ITEM(IPV6_EXT, 7628 sizeof(struct rte_flow_item_ipv6_ext)), 7629 .next = NEXT(item_ipv6_push_ext_type), 7630 .call = parse_vc, 7631 }, 7632 [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { 7633 .name = "type", 7634 .help = "set IPv6 extension type", 7635 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 7636 next_hdr)), 7637 .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), 7638 item_param), 7639 }, 7640 [ACTION_SET_TAG] = { 7641 .name = "set_tag", 7642 .help = "set tag", 7643 .priv = PRIV_ACTION(SET_TAG, 7644 sizeof(struct rte_flow_action_set_tag)), 7645 .next = NEXT(action_set_tag), 7646 .call = parse_vc, 7647 }, 7648 [ACTION_SET_TAG_INDEX] = { 7649 .name = "index", 7650 .help = "index of tag array", 7651 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7652 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 7653 .call = parse_vc_conf, 7654 }, 7655 [ACTION_SET_TAG_DATA] = { 7656 .name = "data", 7657 .help = "tag value", 7658 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7659 .args = ARGS(ARGS_ENTRY 7660 (struct rte_flow_action_set_tag, data)), 7661 .call = parse_vc_conf, 7662 }, 7663 [ACTION_SET_TAG_MASK] = { 7664 .name = "mask", 7665 .help = "mask for tag value", 7666 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7667 .args = ARGS(ARGS_ENTRY 7668 (struct rte_flow_action_set_tag, mask)), 7669 .call = parse_vc_conf, 7670 }, 7671 [ACTION_SET_META] = { 7672 .name = "set_meta", 7673 .help = "set metadata", 7674 .priv = PRIV_ACTION(SET_META, 7675 sizeof(struct rte_flow_action_set_meta)), 7676 .next = NEXT(action_set_meta), 7677 .call = parse_vc_action_set_meta, 7678 }, 7679 [ACTION_SET_META_DATA] = { 7680 .name = "data", 7681 .help = "metadata value", 7682 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7683 .args = ARGS(ARGS_ENTRY 7684 (struct rte_flow_action_set_meta, data)), 7685 .call = parse_vc_conf, 7686 }, 7687 [ACTION_SET_META_MASK] = { 7688 .name = "mask", 7689 .help = "mask for metadata value", 7690 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7691 .args = ARGS(ARGS_ENTRY 7692 (struct rte_flow_action_set_meta, mask)), 7693 .call = parse_vc_conf, 7694 }, 7695 [ACTION_SET_IPV4_DSCP] = { 7696 .name = "set_ipv4_dscp", 7697 .help = "set DSCP value", 7698 .priv = PRIV_ACTION(SET_IPV4_DSCP, 7699 sizeof(struct rte_flow_action_set_dscp)), 7700 .next = NEXT(action_set_ipv4_dscp), 7701 .call = parse_vc, 7702 }, 7703 [ACTION_SET_IPV4_DSCP_VALUE] = { 7704 .name = "dscp_value", 7705 .help = "new IPv4 DSCP value to set", 7706 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7707 .args = ARGS(ARGS_ENTRY 7708 (struct rte_flow_action_set_dscp, dscp)), 7709 .call = parse_vc_conf, 7710 }, 7711 [ACTION_SET_IPV6_DSCP] = { 7712 .name = "set_ipv6_dscp", 7713 .help = "set DSCP value", 7714 .priv = PRIV_ACTION(SET_IPV6_DSCP, 7715 sizeof(struct rte_flow_action_set_dscp)), 7716 .next = NEXT(action_set_ipv6_dscp), 7717 .call = parse_vc, 7718 }, 7719 [ACTION_SET_IPV6_DSCP_VALUE] = { 7720 .name = "dscp_value", 7721 .help = "new IPv6 DSCP value to set", 7722 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7723 .args = ARGS(ARGS_ENTRY 7724 (struct rte_flow_action_set_dscp, dscp)), 7725 .call = parse_vc_conf, 7726 }, 7727 [ACTION_AGE] = { 7728 .name = "age", 7729 .help = "set a specific metadata header", 7730 .next = NEXT(action_age), 7731 .priv = PRIV_ACTION(AGE, 7732 sizeof(struct rte_flow_action_age)), 7733 .call = parse_vc, 7734 }, 7735 [ACTION_AGE_TIMEOUT] = { 7736 .name = "timeout", 7737 .help = "flow age timeout value", 7738 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 7739 timeout, 24)), 7740 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 7741 .call = parse_vc_conf, 7742 }, 7743 [ACTION_AGE_UPDATE] = { 7744 .name = "age_update", 7745 .help = "update aging parameter", 7746 .next = NEXT(action_age_update), 7747 .priv = PRIV_ACTION(AGE, 7748 sizeof(struct rte_flow_update_age)), 7749 .call = parse_vc, 7750 }, 7751 [ACTION_AGE_UPDATE_TIMEOUT] = { 7752 .name = "timeout", 7753 .help = "age timeout update value", 7754 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7755 timeout, 24)), 7756 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7757 .call = parse_vc_conf_timeout, 7758 }, 7759 [ACTION_AGE_UPDATE_TOUCH] = { 7760 .name = "touch", 7761 .help = "this flow is touched", 7762 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), 7763 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7764 touch, 1)), 7765 .call = parse_vc_conf, 7766 }, 7767 [ACTION_SAMPLE] = { 7768 .name = "sample", 7769 .help = "set a sample action", 7770 .next = NEXT(action_sample), 7771 .priv = PRIV_ACTION(SAMPLE, 7772 sizeof(struct action_sample_data)), 7773 .call = parse_vc_action_sample, 7774 }, 7775 [ACTION_SAMPLE_RATIO] = { 7776 .name = "ratio", 7777 .help = "flow sample ratio value", 7778 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 7779 .args = ARGS(ARGS_ENTRY_ARB 7780 (offsetof(struct action_sample_data, conf) + 7781 offsetof(struct rte_flow_action_sample, ratio), 7782 sizeof(((struct rte_flow_action_sample *)0)-> 7783 ratio))), 7784 }, 7785 [ACTION_SAMPLE_INDEX] = { 7786 .name = "index", 7787 .help = "the index of sample actions list", 7788 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 7789 }, 7790 [ACTION_SAMPLE_INDEX_VALUE] = { 7791 .name = "{index}", 7792 .type = "COMMON_UNSIGNED", 7793 .help = "unsigned integer value", 7794 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7795 .call = parse_vc_action_sample_index, 7796 .comp = comp_set_sample_index, 7797 }, 7798 [ACTION_CONNTRACK] = { 7799 .name = "conntrack", 7800 .help = "create a conntrack object", 7801 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7802 .priv = PRIV_ACTION(CONNTRACK, 7803 sizeof(struct rte_flow_action_conntrack)), 7804 .call = parse_vc, 7805 }, 7806 [ACTION_CONNTRACK_UPDATE] = { 7807 .name = "conntrack_update", 7808 .help = "update a conntrack object", 7809 .next = NEXT(action_update_conntrack), 7810 .priv = PRIV_ACTION(CONNTRACK, 7811 sizeof(struct rte_flow_modify_conntrack)), 7812 .call = parse_vc, 7813 }, 7814 [ACTION_CONNTRACK_UPDATE_DIR] = { 7815 .name = "dir", 7816 .help = "update a conntrack object direction", 7817 .next = NEXT(action_update_conntrack), 7818 .call = parse_vc_action_conntrack_update, 7819 }, 7820 [ACTION_CONNTRACK_UPDATE_CTX] = { 7821 .name = "ctx", 7822 .help = "update a conntrack object context", 7823 .next = NEXT(action_update_conntrack), 7824 .call = parse_vc_action_conntrack_update, 7825 }, 7826 [ACTION_PORT_REPRESENTOR] = { 7827 .name = "port_representor", 7828 .help = "at embedded switch level, send matching traffic to the given ethdev", 7829 .priv = PRIV_ACTION(PORT_REPRESENTOR, 7830 sizeof(struct rte_flow_action_ethdev)), 7831 .next = NEXT(action_port_representor), 7832 .call = parse_vc, 7833 }, 7834 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 7835 .name = "port_id", 7836 .help = "ethdev port ID", 7837 .next = NEXT(action_port_representor, 7838 NEXT_ENTRY(COMMON_UNSIGNED)), 7839 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7840 port_id)), 7841 .call = parse_vc_conf, 7842 }, 7843 [ACTION_REPRESENTED_PORT] = { 7844 .name = "represented_port", 7845 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 7846 .priv = PRIV_ACTION(REPRESENTED_PORT, 7847 sizeof(struct rte_flow_action_ethdev)), 7848 .next = NEXT(action_represented_port), 7849 .call = parse_vc, 7850 }, 7851 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 7852 .name = "ethdev_port_id", 7853 .help = "ethdev port ID", 7854 .next = NEXT(action_represented_port, 7855 NEXT_ENTRY(COMMON_UNSIGNED)), 7856 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7857 port_id)), 7858 .call = parse_vc_conf, 7859 }, 7860 /* Indirect action destroy arguments. */ 7861 [INDIRECT_ACTION_DESTROY_ID] = { 7862 .name = "action_id", 7863 .help = "specify a indirect action id to destroy", 7864 .next = NEXT(next_ia_destroy_attr, 7865 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7866 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 7867 args.ia_destroy.action_id)), 7868 .call = parse_ia_destroy, 7869 }, 7870 /* Indirect action create arguments. */ 7871 [INDIRECT_ACTION_CREATE_ID] = { 7872 .name = "action_id", 7873 .help = "specify a indirect action id to create", 7874 .next = NEXT(next_ia_create_attr, 7875 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7876 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 7877 }, 7878 [ACTION_INDIRECT] = { 7879 .name = "indirect", 7880 .help = "apply indirect action by id", 7881 .priv = PRIV_ACTION(INDIRECT, 0), 7882 .next = NEXT(next_ia), 7883 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7884 .call = parse_vc, 7885 }, 7886 [ACTION_INDIRECT_LIST] = { 7887 .name = "indirect_list", 7888 .help = "apply indirect list action by id", 7889 .priv = PRIV_ACTION(INDIRECT_LIST, 7890 sizeof(struct 7891 rte_flow_action_indirect_list)), 7892 .next = NEXT(next_ial), 7893 .call = parse_vc, 7894 }, 7895 [ACTION_INDIRECT_LIST_HANDLE] = { 7896 .name = "handle", 7897 .help = "indirect list handle", 7898 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), 7899 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7900 }, 7901 [ACTION_INDIRECT_LIST_CONF] = { 7902 .name = "conf", 7903 .help = "indirect list configuration", 7904 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), 7905 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7906 }, 7907 [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { 7908 .type = "UNSIGNED", 7909 .help = "unsigned integer value", 7910 .call = parse_indlst_id2ptr, 7911 .comp = comp_none, 7912 }, 7913 [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { 7914 .type = "UNSIGNED", 7915 .help = "unsigned integer value", 7916 .call = parse_indlst_id2ptr, 7917 .comp = comp_none, 7918 }, 7919 [ACTION_SHARED_INDIRECT] = { 7920 .name = "shared_indirect", 7921 .help = "apply indirect action by id and port", 7922 .priv = PRIV_ACTION(INDIRECT, 0), 7923 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), 7924 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), 7925 ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7926 .call = parse_vc, 7927 }, 7928 [INDIRECT_ACTION_PORT] = { 7929 .name = "{indirect_action_port}", 7930 .type = "INDIRECT_ACTION_PORT", 7931 .help = "indirect action port", 7932 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 7933 .call = parse_ia_port, 7934 .comp = comp_none, 7935 }, 7936 [INDIRECT_ACTION_ID2PTR] = { 7937 .name = "{action_id}", 7938 .type = "INDIRECT_ACTION_ID", 7939 .help = "indirect action id", 7940 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7941 .call = parse_ia_id2ptr, 7942 .comp = comp_none, 7943 }, 7944 [INDIRECT_ACTION_INGRESS] = { 7945 .name = "ingress", 7946 .help = "affect rule to ingress", 7947 .next = NEXT(next_ia_create_attr), 7948 .call = parse_ia, 7949 }, 7950 [INDIRECT_ACTION_EGRESS] = { 7951 .name = "egress", 7952 .help = "affect rule to egress", 7953 .next = NEXT(next_ia_create_attr), 7954 .call = parse_ia, 7955 }, 7956 [INDIRECT_ACTION_TRANSFER] = { 7957 .name = "transfer", 7958 .help = "affect rule to transfer", 7959 .next = NEXT(next_ia_create_attr), 7960 .call = parse_ia, 7961 }, 7962 [INDIRECT_ACTION_SPEC] = { 7963 .name = "action", 7964 .help = "specify action to create indirect handle", 7965 .next = NEXT(next_action), 7966 }, 7967 [INDIRECT_ACTION_LIST] = { 7968 .name = "list", 7969 .help = "specify actions for indirect handle list", 7970 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7971 .call = parse_ia, 7972 }, 7973 [INDIRECT_ACTION_FLOW_CONF] = { 7974 .name = "flow_conf", 7975 .help = "specify actions configuration for indirect handle list", 7976 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7977 .call = parse_ia, 7978 }, 7979 [ACTION_POL_G] = { 7980 .name = "g_actions", 7981 .help = "submit a list of associated actions for green", 7982 .next = NEXT(next_action), 7983 .call = parse_mp, 7984 }, 7985 [ACTION_POL_Y] = { 7986 .name = "y_actions", 7987 .help = "submit a list of associated actions for yellow", 7988 .next = NEXT(next_action), 7989 }, 7990 [ACTION_POL_R] = { 7991 .name = "r_actions", 7992 .help = "submit a list of associated actions for red", 7993 .next = NEXT(next_action), 7994 }, 7995 [ACTION_QUOTA_CREATE] = { 7996 .name = "quota_create", 7997 .help = "create quota action", 7998 .priv = PRIV_ACTION(QUOTA, 7999 sizeof(struct rte_flow_action_quota)), 8000 .next = NEXT(action_quota_create), 8001 .call = parse_vc 8002 }, 8003 [ACTION_QUOTA_CREATE_LIMIT] = { 8004 .name = "limit", 8005 .help = "quota limit", 8006 .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), 8007 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), 8008 .call = parse_vc_conf 8009 }, 8010 [ACTION_QUOTA_CREATE_MODE] = { 8011 .name = "mode", 8012 .help = "quota mode", 8013 .next = NEXT(action_quota_create, 8014 NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), 8015 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), 8016 .call = parse_vc_conf 8017 }, 8018 [ACTION_QUOTA_CREATE_MODE_NAME] = { 8019 .name = "mode_name", 8020 .help = "quota mode name", 8021 .call = parse_quota_mode_name, 8022 .comp = comp_quota_mode_name 8023 }, 8024 [ACTION_QUOTA_QU] = { 8025 .name = "quota_update", 8026 .help = "update quota action", 8027 .priv = PRIV_ACTION(QUOTA, 8028 sizeof(struct rte_flow_update_quota)), 8029 .next = NEXT(action_quota_update), 8030 .call = parse_vc 8031 }, 8032 [ACTION_QUOTA_QU_LIMIT] = { 8033 .name = "limit", 8034 .help = "quota limit", 8035 .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), 8036 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), 8037 .call = parse_vc_conf 8038 }, 8039 [ACTION_QUOTA_QU_UPDATE_OP] = { 8040 .name = "update_op", 8041 .help = "query update op SET|ADD", 8042 .next = NEXT(action_quota_update, 8043 NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), 8044 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), 8045 .call = parse_vc_conf 8046 }, 8047 [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { 8048 .name = "update_op_name", 8049 .help = "quota update op name", 8050 .call = parse_quota_update_name, 8051 .comp = comp_quota_update_name 8052 }, 8053 8054 /* Top-level command. */ 8055 [ADD] = { 8056 .name = "add", 8057 .type = "port meter policy {port_id} {arg}", 8058 .help = "add port meter policy", 8059 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 8060 .call = parse_init, 8061 }, 8062 /* Sub-level commands. */ 8063 [ITEM_POL_PORT] = { 8064 .name = "port", 8065 .help = "add port meter policy", 8066 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 8067 }, 8068 [ITEM_POL_METER] = { 8069 .name = "meter", 8070 .help = "add port meter policy", 8071 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 8072 }, 8073 [ITEM_POL_POLICY] = { 8074 .name = "policy", 8075 .help = "add port meter policy", 8076 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 8077 NEXT_ENTRY(ACTION_POL_Y), 8078 NEXT_ENTRY(ACTION_POL_G), 8079 NEXT_ENTRY(COMMON_POLICY_ID), 8080 NEXT_ENTRY(COMMON_PORT_ID)), 8081 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 8082 ARGS_ENTRY(struct buffer, port)), 8083 .call = parse_mp, 8084 }, 8085 [ITEM_AGGR_AFFINITY] = { 8086 .name = "aggr_affinity", 8087 .help = "match on the aggregated port receiving the packets", 8088 .priv = PRIV_ITEM(AGGR_AFFINITY, 8089 sizeof(struct rte_flow_item_aggr_affinity)), 8090 .next = NEXT(item_aggr_affinity), 8091 .call = parse_vc, 8092 }, 8093 [ITEM_AGGR_AFFINITY_VALUE] = { 8094 .name = "affinity", 8095 .help = "aggregated affinity value", 8096 .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), 8097 item_param), 8098 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, 8099 affinity)), 8100 }, 8101 [ITEM_TX_QUEUE] = { 8102 .name = "tx_queue", 8103 .help = "match on the tx queue of send packet", 8104 .priv = PRIV_ITEM(TX_QUEUE, 8105 sizeof(struct rte_flow_item_tx_queue)), 8106 .next = NEXT(item_tx_queue), 8107 .call = parse_vc, 8108 }, 8109 [ITEM_TX_QUEUE_VALUE] = { 8110 .name = "tx_queue_value", 8111 .help = "tx queue value", 8112 .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), 8113 item_param), 8114 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, 8115 tx_queue)), 8116 }, 8117 }; 8118 8119 /** Remove and return last entry from argument stack. */ 8120 static const struct arg * 8121 pop_args(struct context *ctx) 8122 { 8123 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 8124 } 8125 8126 /** Add entry on top of the argument stack. */ 8127 static int 8128 push_args(struct context *ctx, const struct arg *arg) 8129 { 8130 if (ctx->args_num == CTX_STACK_SIZE) 8131 return -1; 8132 ctx->args[ctx->args_num++] = arg; 8133 return 0; 8134 } 8135 8136 /** Spread value into buffer according to bit-mask. */ 8137 static size_t 8138 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 8139 { 8140 uint32_t i = arg->size; 8141 uint32_t end = 0; 8142 int sub = 1; 8143 int add = 0; 8144 size_t len = 0; 8145 8146 if (!arg->mask) 8147 return 0; 8148 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8149 if (!arg->hton) { 8150 i = 0; 8151 end = arg->size; 8152 sub = 0; 8153 add = 1; 8154 } 8155 #endif 8156 while (i != end) { 8157 unsigned int shift = 0; 8158 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 8159 8160 for (shift = 0; arg->mask[i] >> shift; ++shift) { 8161 if (!(arg->mask[i] & (1 << shift))) 8162 continue; 8163 ++len; 8164 if (!dst) 8165 continue; 8166 *buf &= ~(1 << shift); 8167 *buf |= (val & 1) << shift; 8168 val >>= 1; 8169 } 8170 i += add; 8171 } 8172 return len; 8173 } 8174 8175 /** Compare a string with a partial one of a given length. */ 8176 static int 8177 strcmp_partial(const char *full, const char *partial, size_t partial_len) 8178 { 8179 int r = strncmp(full, partial, partial_len); 8180 8181 if (r) 8182 return r; 8183 if (strlen(full) <= partial_len) 8184 return 0; 8185 return full[partial_len]; 8186 } 8187 8188 /** 8189 * Parse a prefix length and generate a bit-mask. 8190 * 8191 * Last argument (ctx->args) is retrieved to determine mask size, storage 8192 * location and whether the result must use network byte ordering. 8193 */ 8194 static int 8195 parse_prefix(struct context *ctx, const struct token *token, 8196 const char *str, unsigned int len, 8197 void *buf, unsigned int size) 8198 { 8199 const struct arg *arg = pop_args(ctx); 8200 static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff"; 8201 char *end; 8202 uintmax_t u; 8203 unsigned int bytes; 8204 unsigned int extra; 8205 8206 (void)token; 8207 /* Argument is expected. */ 8208 if (!arg) 8209 return -1; 8210 errno = 0; 8211 u = strtoumax(str, &end, 0); 8212 if (errno || (size_t)(end - str) != len) 8213 goto error; 8214 if (arg->mask) { 8215 uintmax_t v = 0; 8216 8217 extra = arg_entry_bf_fill(NULL, 0, arg); 8218 if (u > extra) 8219 goto error; 8220 if (!ctx->object) 8221 return len; 8222 extra -= u; 8223 while (u--) 8224 (v <<= 1, v |= 1); 8225 v <<= extra; 8226 if (!arg_entry_bf_fill(ctx->object, v, arg) || 8227 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 8228 goto error; 8229 return len; 8230 } 8231 bytes = u / 8; 8232 extra = u % 8; 8233 size = arg->size; 8234 if (bytes > size || bytes + !!extra > size) 8235 goto error; 8236 if (!ctx->object) 8237 return len; 8238 buf = (uint8_t *)ctx->object + arg->offset; 8239 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8240 if (!arg->hton) { 8241 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 8242 memset(buf, 0x00, size - bytes); 8243 if (extra) 8244 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 8245 } else 8246 #endif 8247 { 8248 memset(buf, 0xff, bytes); 8249 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 8250 if (extra) 8251 ((uint8_t *)buf)[bytes] = conv[extra]; 8252 } 8253 if (ctx->objmask) 8254 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 8255 return len; 8256 error: 8257 push_args(ctx, arg); 8258 return -1; 8259 } 8260 8261 /** Default parsing function for token name matching. */ 8262 static int 8263 parse_default(struct context *ctx, const struct token *token, 8264 const char *str, unsigned int len, 8265 void *buf, unsigned int size) 8266 { 8267 (void)ctx; 8268 (void)buf; 8269 (void)size; 8270 if (strcmp_partial(token->name, str, len)) 8271 return -1; 8272 return len; 8273 } 8274 8275 /** Parse flow command, initialize output buffer for subsequent tokens. */ 8276 static int 8277 parse_init(struct context *ctx, const struct token *token, 8278 const char *str, unsigned int len, 8279 void *buf, unsigned int size) 8280 { 8281 struct buffer *out = buf; 8282 8283 /* Token name must match. */ 8284 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8285 return -1; 8286 /* Nothing else to do if there is no buffer. */ 8287 if (!out) 8288 return len; 8289 /* Make sure buffer is large enough. */ 8290 if (size < sizeof(*out)) 8291 return -1; 8292 /* Initialize buffer. */ 8293 memset(out, 0x00, sizeof(*out)); 8294 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 8295 ctx->objdata = 0; 8296 ctx->object = out; 8297 ctx->objmask = NULL; 8298 return len; 8299 } 8300 8301 /** Parse tokens for indirect action commands. */ 8302 static int 8303 parse_ia(struct context *ctx, const struct token *token, 8304 const char *str, unsigned int len, 8305 void *buf, unsigned int size) 8306 { 8307 struct buffer *out = buf; 8308 8309 /* Token name must match. */ 8310 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8311 return -1; 8312 /* Nothing else to do if there is no buffer. */ 8313 if (!out) 8314 return len; 8315 if (!out->command) { 8316 if (ctx->curr != INDIRECT_ACTION) 8317 return -1; 8318 if (sizeof(*out) > size) 8319 return -1; 8320 out->command = ctx->curr; 8321 ctx->objdata = 0; 8322 ctx->object = out; 8323 ctx->objmask = NULL; 8324 out->args.vc.data = (uint8_t *)out + size; 8325 return len; 8326 } 8327 switch (ctx->curr) { 8328 case INDIRECT_ACTION_CREATE: 8329 case INDIRECT_ACTION_UPDATE: 8330 case INDIRECT_ACTION_QUERY_UPDATE: 8331 out->args.vc.actions = 8332 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8333 sizeof(double)); 8334 out->args.vc.attr.group = UINT32_MAX; 8335 /* fallthrough */ 8336 case INDIRECT_ACTION_QUERY: 8337 out->command = ctx->curr; 8338 ctx->objdata = 0; 8339 ctx->object = out; 8340 ctx->objmask = NULL; 8341 return len; 8342 case INDIRECT_ACTION_EGRESS: 8343 out->args.vc.attr.egress = 1; 8344 return len; 8345 case INDIRECT_ACTION_INGRESS: 8346 out->args.vc.attr.ingress = 1; 8347 return len; 8348 case INDIRECT_ACTION_TRANSFER: 8349 out->args.vc.attr.transfer = 1; 8350 return len; 8351 case INDIRECT_ACTION_QU_MODE: 8352 return len; 8353 case INDIRECT_ACTION_LIST: 8354 out->command = INDIRECT_ACTION_LIST_CREATE; 8355 return len; 8356 case INDIRECT_ACTION_FLOW_CONF: 8357 out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; 8358 return len; 8359 default: 8360 return -1; 8361 } 8362 } 8363 8364 8365 /** Parse tokens for indirect action destroy command. */ 8366 static int 8367 parse_ia_destroy(struct context *ctx, const struct token *token, 8368 const char *str, unsigned int len, 8369 void *buf, unsigned int size) 8370 { 8371 struct buffer *out = buf; 8372 uint32_t *action_id; 8373 8374 /* Token name must match. */ 8375 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8376 return -1; 8377 /* Nothing else to do if there is no buffer. */ 8378 if (!out) 8379 return len; 8380 if (!out->command || out->command == INDIRECT_ACTION) { 8381 if (ctx->curr != INDIRECT_ACTION_DESTROY) 8382 return -1; 8383 if (sizeof(*out) > size) 8384 return -1; 8385 out->command = ctx->curr; 8386 ctx->objdata = 0; 8387 ctx->object = out; 8388 ctx->objmask = NULL; 8389 out->args.ia_destroy.action_id = 8390 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8391 sizeof(double)); 8392 return len; 8393 } 8394 action_id = out->args.ia_destroy.action_id 8395 + out->args.ia_destroy.action_id_n++; 8396 if ((uint8_t *)action_id > (uint8_t *)out + size) 8397 return -1; 8398 ctx->objdata = 0; 8399 ctx->object = action_id; 8400 ctx->objmask = NULL; 8401 return len; 8402 } 8403 8404 /** Parse tokens for indirect action commands. */ 8405 static int 8406 parse_qia(struct context *ctx, const struct token *token, 8407 const char *str, unsigned int len, 8408 void *buf, unsigned int size) 8409 { 8410 struct buffer *out = buf; 8411 8412 /* Token name must match. */ 8413 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8414 return -1; 8415 /* Nothing else to do if there is no buffer. */ 8416 if (!out) 8417 return len; 8418 if (!out->command) { 8419 if (ctx->curr != QUEUE) 8420 return -1; 8421 if (sizeof(*out) > size) 8422 return -1; 8423 out->args.vc.data = (uint8_t *)out + size; 8424 return len; 8425 } 8426 switch (ctx->curr) { 8427 case QUEUE_INDIRECT_ACTION: 8428 return len; 8429 case QUEUE_INDIRECT_ACTION_CREATE: 8430 case QUEUE_INDIRECT_ACTION_UPDATE: 8431 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 8432 out->args.vc.actions = 8433 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8434 sizeof(double)); 8435 out->args.vc.attr.group = UINT32_MAX; 8436 /* fallthrough */ 8437 case QUEUE_INDIRECT_ACTION_QUERY: 8438 out->command = ctx->curr; 8439 ctx->objdata = 0; 8440 ctx->object = out; 8441 ctx->objmask = NULL; 8442 return len; 8443 case QUEUE_INDIRECT_ACTION_EGRESS: 8444 out->args.vc.attr.egress = 1; 8445 return len; 8446 case QUEUE_INDIRECT_ACTION_INGRESS: 8447 out->args.vc.attr.ingress = 1; 8448 return len; 8449 case QUEUE_INDIRECT_ACTION_TRANSFER: 8450 out->args.vc.attr.transfer = 1; 8451 return len; 8452 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 8453 return len; 8454 case QUEUE_INDIRECT_ACTION_QU_MODE: 8455 return len; 8456 case QUEUE_INDIRECT_ACTION_LIST: 8457 out->command = QUEUE_INDIRECT_ACTION_LIST_CREATE; 8458 return len; 8459 default: 8460 return -1; 8461 } 8462 } 8463 8464 /** Parse tokens for indirect action destroy command. */ 8465 static int 8466 parse_qia_destroy(struct context *ctx, const struct token *token, 8467 const char *str, unsigned int len, 8468 void *buf, unsigned int size) 8469 { 8470 struct buffer *out = buf; 8471 uint32_t *action_id; 8472 8473 /* Token name must match. */ 8474 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8475 return -1; 8476 /* Nothing else to do if there is no buffer. */ 8477 if (!out) 8478 return len; 8479 if (!out->command || out->command == QUEUE) { 8480 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 8481 return -1; 8482 if (sizeof(*out) > size) 8483 return -1; 8484 out->command = ctx->curr; 8485 ctx->objdata = 0; 8486 ctx->object = out; 8487 ctx->objmask = NULL; 8488 out->args.ia_destroy.action_id = 8489 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8490 sizeof(double)); 8491 return len; 8492 } 8493 switch (ctx->curr) { 8494 case QUEUE_INDIRECT_ACTION: 8495 out->command = ctx->curr; 8496 ctx->objdata = 0; 8497 ctx->object = out; 8498 ctx->objmask = NULL; 8499 return len; 8500 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 8501 action_id = out->args.ia_destroy.action_id 8502 + out->args.ia_destroy.action_id_n++; 8503 if ((uint8_t *)action_id > (uint8_t *)out + size) 8504 return -1; 8505 ctx->objdata = 0; 8506 ctx->object = action_id; 8507 ctx->objmask = NULL; 8508 return len; 8509 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 8510 return len; 8511 default: 8512 return -1; 8513 } 8514 } 8515 8516 /** Parse tokens for meter policy action commands. */ 8517 static int 8518 parse_mp(struct context *ctx, const struct token *token, 8519 const char *str, unsigned int len, 8520 void *buf, unsigned int size) 8521 { 8522 struct buffer *out = buf; 8523 8524 /* Token name must match. */ 8525 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8526 return -1; 8527 /* Nothing else to do if there is no buffer. */ 8528 if (!out) 8529 return len; 8530 if (!out->command) { 8531 if (ctx->curr != ITEM_POL_POLICY) 8532 return -1; 8533 if (sizeof(*out) > size) 8534 return -1; 8535 out->command = ctx->curr; 8536 ctx->objdata = 0; 8537 ctx->object = out; 8538 ctx->objmask = NULL; 8539 out->args.vc.data = (uint8_t *)out + size; 8540 return len; 8541 } 8542 switch (ctx->curr) { 8543 case ACTION_POL_G: 8544 out->args.vc.actions = 8545 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8546 sizeof(double)); 8547 out->command = ctx->curr; 8548 ctx->objdata = 0; 8549 ctx->object = out; 8550 ctx->objmask = NULL; 8551 return len; 8552 default: 8553 return -1; 8554 } 8555 } 8556 8557 /** Parse tokens for validate/create commands. */ 8558 static int 8559 parse_vc(struct context *ctx, const struct token *token, 8560 const char *str, unsigned int len, 8561 void *buf, unsigned int size) 8562 { 8563 struct buffer *out = buf; 8564 uint8_t *data; 8565 uint32_t data_size; 8566 8567 /* Token name must match. */ 8568 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8569 return -1; 8570 /* Nothing else to do if there is no buffer. */ 8571 if (!out) 8572 return len; 8573 if (!out->command) { 8574 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 8575 ctx->curr != PATTERN_TEMPLATE_CREATE && 8576 ctx->curr != ACTIONS_TEMPLATE_CREATE && 8577 ctx->curr != UPDATE) 8578 return -1; 8579 if (ctx->curr == UPDATE) 8580 out->args.vc.pattern = 8581 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8582 sizeof(double)); 8583 if (sizeof(*out) > size) 8584 return -1; 8585 out->command = ctx->curr; 8586 ctx->objdata = 0; 8587 ctx->object = out; 8588 ctx->objmask = NULL; 8589 out->args.vc.data = (uint8_t *)out + size; 8590 return len; 8591 } 8592 ctx->objdata = 0; 8593 switch (ctx->curr) { 8594 default: 8595 ctx->object = &out->args.vc.attr; 8596 break; 8597 case VC_TUNNEL_SET: 8598 case VC_TUNNEL_MATCH: 8599 ctx->object = &out->args.vc.tunnel_ops; 8600 break; 8601 case VC_USER_ID: 8602 ctx->object = out; 8603 break; 8604 } 8605 ctx->objmask = NULL; 8606 switch (ctx->curr) { 8607 case VC_GROUP: 8608 case VC_PRIORITY: 8609 case VC_USER_ID: 8610 return len; 8611 case VC_TUNNEL_SET: 8612 out->args.vc.tunnel_ops.enabled = 1; 8613 out->args.vc.tunnel_ops.actions = 1; 8614 return len; 8615 case VC_TUNNEL_MATCH: 8616 out->args.vc.tunnel_ops.enabled = 1; 8617 out->args.vc.tunnel_ops.items = 1; 8618 return len; 8619 case VC_INGRESS: 8620 out->args.vc.attr.ingress = 1; 8621 return len; 8622 case VC_EGRESS: 8623 out->args.vc.attr.egress = 1; 8624 return len; 8625 case VC_TRANSFER: 8626 out->args.vc.attr.transfer = 1; 8627 return len; 8628 case ITEM_PATTERN: 8629 out->args.vc.pattern = 8630 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8631 sizeof(double)); 8632 ctx->object = out->args.vc.pattern; 8633 ctx->objmask = NULL; 8634 return len; 8635 case ITEM_END: 8636 if ((out->command == VALIDATE || out->command == CREATE) && 8637 ctx->last) 8638 return -1; 8639 if (out->command == PATTERN_TEMPLATE_CREATE && 8640 !ctx->last) 8641 return -1; 8642 break; 8643 case ACTIONS: 8644 out->args.vc.actions = out->args.vc.pattern ? 8645 (void *)RTE_ALIGN_CEIL((uintptr_t) 8646 (out->args.vc.pattern + 8647 out->args.vc.pattern_n), 8648 sizeof(double)) : 8649 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8650 sizeof(double)); 8651 ctx->object = out->args.vc.actions; 8652 ctx->objmask = NULL; 8653 return len; 8654 case VC_IS_USER_ID: 8655 out->args.vc.user_id = true; 8656 return len; 8657 default: 8658 if (!token->priv) 8659 return -1; 8660 break; 8661 } 8662 if (!out->args.vc.actions) { 8663 const struct parse_item_priv *priv = token->priv; 8664 struct rte_flow_item *item = 8665 out->args.vc.pattern + out->args.vc.pattern_n; 8666 8667 data_size = priv->size * 3; /* spec, last, mask */ 8668 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8669 (out->args.vc.data - data_size), 8670 sizeof(double)); 8671 if ((uint8_t *)item + sizeof(*item) > data) 8672 return -1; 8673 *item = (struct rte_flow_item){ 8674 .type = priv->type, 8675 }; 8676 ++out->args.vc.pattern_n; 8677 ctx->object = item; 8678 ctx->objmask = NULL; 8679 } else { 8680 const struct parse_action_priv *priv = token->priv; 8681 struct rte_flow_action *action = 8682 out->args.vc.actions + out->args.vc.actions_n; 8683 8684 data_size = priv->size; /* configuration */ 8685 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8686 (out->args.vc.data - data_size), 8687 sizeof(double)); 8688 if ((uint8_t *)action + sizeof(*action) > data) 8689 return -1; 8690 *action = (struct rte_flow_action){ 8691 .type = priv->type, 8692 .conf = data_size ? data : NULL, 8693 }; 8694 ++out->args.vc.actions_n; 8695 ctx->object = action; 8696 ctx->objmask = NULL; 8697 } 8698 memset(data, 0, data_size); 8699 out->args.vc.data = data; 8700 ctx->objdata = data_size; 8701 return len; 8702 } 8703 8704 /** Parse pattern item parameter type. */ 8705 static int 8706 parse_vc_spec(struct context *ctx, const struct token *token, 8707 const char *str, unsigned int len, 8708 void *buf, unsigned int size) 8709 { 8710 struct buffer *out = buf; 8711 struct rte_flow_item *item; 8712 uint32_t data_size; 8713 int index; 8714 int objmask = 0; 8715 8716 (void)size; 8717 /* Token name must match. */ 8718 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8719 return -1; 8720 /* Parse parameter types. */ 8721 switch (ctx->curr) { 8722 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 8723 8724 case ITEM_PARAM_IS: 8725 index = 0; 8726 objmask = 1; 8727 break; 8728 case ITEM_PARAM_SPEC: 8729 index = 0; 8730 break; 8731 case ITEM_PARAM_LAST: 8732 index = 1; 8733 break; 8734 case ITEM_PARAM_PREFIX: 8735 /* Modify next token to expect a prefix. */ 8736 if (ctx->next_num < 2) 8737 return -1; 8738 ctx->next[ctx->next_num - 2] = prefix; 8739 /* Fall through. */ 8740 case ITEM_PARAM_MASK: 8741 index = 2; 8742 break; 8743 default: 8744 return -1; 8745 } 8746 /* Nothing else to do if there is no buffer. */ 8747 if (!out) 8748 return len; 8749 if (!out->args.vc.pattern_n) 8750 return -1; 8751 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8752 data_size = ctx->objdata / 3; /* spec, last, mask */ 8753 /* Point to selected object. */ 8754 ctx->object = out->args.vc.data + (data_size * index); 8755 if (objmask) { 8756 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 8757 item->mask = ctx->objmask; 8758 } else 8759 ctx->objmask = NULL; 8760 /* Update relevant item pointer. */ 8761 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 8762 ctx->object; 8763 return len; 8764 } 8765 8766 /** Parse action configuration field. */ 8767 static int 8768 parse_vc_conf(struct context *ctx, const struct token *token, 8769 const char *str, unsigned int len, 8770 void *buf, unsigned int size) 8771 { 8772 struct buffer *out = buf; 8773 8774 (void)size; 8775 /* Token name must match. */ 8776 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8777 return -1; 8778 /* Nothing else to do if there is no buffer. */ 8779 if (!out) 8780 return len; 8781 /* Point to selected object. */ 8782 ctx->object = out->args.vc.data; 8783 ctx->objmask = NULL; 8784 return len; 8785 } 8786 8787 /** Parse action configuration field. */ 8788 static int 8789 parse_vc_conf_timeout(struct context *ctx, const struct token *token, 8790 const char *str, unsigned int len, 8791 void *buf, unsigned int size) 8792 { 8793 struct buffer *out = buf; 8794 struct rte_flow_update_age *update; 8795 8796 (void)size; 8797 if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) 8798 return -1; 8799 /* Token name must match. */ 8800 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8801 return -1; 8802 /* Nothing else to do if there is no buffer. */ 8803 if (!out) 8804 return len; 8805 /* Point to selected object. */ 8806 ctx->object = out->args.vc.data; 8807 ctx->objmask = NULL; 8808 /* Update the timeout is valid. */ 8809 update = (struct rte_flow_update_age *)out->args.vc.data; 8810 update->timeout_valid = 1; 8811 return len; 8812 } 8813 8814 /** Parse eCPRI common header type field. */ 8815 static int 8816 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 8817 const char *str, unsigned int len, 8818 void *buf, unsigned int size) 8819 { 8820 struct rte_flow_item_ecpri *ecpri; 8821 struct rte_flow_item_ecpri *ecpri_mask; 8822 struct rte_flow_item *item; 8823 uint32_t data_size; 8824 uint8_t msg_type; 8825 struct buffer *out = buf; 8826 const struct arg *arg; 8827 8828 (void)size; 8829 /* Token name must match. */ 8830 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8831 return -1; 8832 switch (ctx->curr) { 8833 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 8834 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 8835 break; 8836 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 8837 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 8838 break; 8839 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 8840 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 8841 break; 8842 default: 8843 return -1; 8844 } 8845 if (!ctx->object) 8846 return len; 8847 arg = pop_args(ctx); 8848 if (!arg) 8849 return -1; 8850 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 8851 ecpri->hdr.common.type = msg_type; 8852 data_size = ctx->objdata / 3; /* spec, last, mask */ 8853 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 8854 (data_size * 2)); 8855 ecpri_mask->hdr.common.type = 0xFF; 8856 if (arg->hton) { 8857 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 8858 ecpri_mask->hdr.common.u32 = 8859 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 8860 } 8861 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8862 item->spec = ecpri; 8863 item->mask = ecpri_mask; 8864 return len; 8865 } 8866 8867 /** Parse L2TPv2 common header type field. */ 8868 static int 8869 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, 8870 const char *str, unsigned int len, 8871 void *buf, unsigned int size) 8872 { 8873 struct rte_flow_item_l2tpv2 *l2tpv2; 8874 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 8875 struct rte_flow_item *item; 8876 uint32_t data_size; 8877 uint16_t msg_type = 0; 8878 struct buffer *out = buf; 8879 const struct arg *arg; 8880 8881 (void)size; 8882 /* Token name must match. */ 8883 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8884 return -1; 8885 switch (ctx->curr) { 8886 case ITEM_L2TPV2_TYPE_DATA: 8887 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 8888 break; 8889 case ITEM_L2TPV2_TYPE_DATA_L: 8890 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 8891 break; 8892 case ITEM_L2TPV2_TYPE_DATA_S: 8893 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 8894 break; 8895 case ITEM_L2TPV2_TYPE_DATA_O: 8896 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 8897 break; 8898 case ITEM_L2TPV2_TYPE_DATA_L_S: 8899 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 8900 break; 8901 case ITEM_L2TPV2_TYPE_CTRL: 8902 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 8903 break; 8904 default: 8905 return -1; 8906 } 8907 if (!ctx->object) 8908 return len; 8909 arg = pop_args(ctx); 8910 if (!arg) 8911 return -1; 8912 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 8913 l2tpv2->hdr.common.flags_version |= msg_type; 8914 data_size = ctx->objdata / 3; /* spec, last, mask */ 8915 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 8916 (data_size * 2)); 8917 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 8918 if (arg->hton) { 8919 l2tpv2->hdr.common.flags_version = 8920 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 8921 l2tpv2_mask->hdr.common.flags_version = 8922 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 8923 } 8924 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8925 item->spec = l2tpv2; 8926 item->mask = l2tpv2_mask; 8927 return len; 8928 } 8929 8930 /** Parse operation for compare match item. */ 8931 static int 8932 parse_vc_compare_op(struct context *ctx, const struct token *token, 8933 const char *str, unsigned int len, void *buf, 8934 unsigned int size) 8935 { 8936 struct rte_flow_item_compare *compare_item; 8937 unsigned int i; 8938 8939 (void)token; 8940 (void)buf; 8941 (void)size; 8942 if (ctx->curr != ITEM_COMPARE_OP_VALUE) 8943 return -1; 8944 for (i = 0; compare_ops[i]; ++i) 8945 if (!strcmp_partial(compare_ops[i], str, len)) 8946 break; 8947 if (!compare_ops[i]) 8948 return -1; 8949 if (!ctx->object) 8950 return len; 8951 compare_item = ctx->object; 8952 compare_item->operation = (enum rte_flow_item_compare_op)i; 8953 return len; 8954 } 8955 8956 /** Parse id for compare match item. */ 8957 static int 8958 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 8959 const char *str, unsigned int len, void *buf, 8960 unsigned int size) 8961 { 8962 struct rte_flow_item_compare *compare_item; 8963 unsigned int i; 8964 8965 (void)token; 8966 (void)buf; 8967 (void)size; 8968 if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE && 8969 ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE) 8970 return -1; 8971 for (i = 0; flow_field_ids[i]; ++i) 8972 if (!strcmp_partial(flow_field_ids[i], str, len)) 8973 break; 8974 if (!flow_field_ids[i]) 8975 return -1; 8976 if (!ctx->object) 8977 return len; 8978 compare_item = ctx->object; 8979 if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE) 8980 compare_item->a.field = (enum rte_flow_field_id)i; 8981 else 8982 compare_item->b.field = (enum rte_flow_field_id)i; 8983 return len; 8984 } 8985 8986 /** Parse level for compare match item. */ 8987 static int 8988 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 8989 const char *str, unsigned int len, void *buf, 8990 unsigned int size) 8991 { 8992 struct rte_flow_item_compare *compare_item; 8993 struct flex_item *fp = NULL; 8994 uint32_t val; 8995 struct buffer *out = buf; 8996 char *end; 8997 8998 (void)token; 8999 (void)size; 9000 if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 9001 ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE) 9002 return -1; 9003 if (!ctx->object) 9004 return len; 9005 compare_item = ctx->object; 9006 errno = 0; 9007 val = strtoumax(str, &end, 0); 9008 if (errno || (size_t)(end - str) != len) 9009 return -1; 9010 /* No need to validate action template mask value */ 9011 if (out->args.vc.masks) { 9012 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) 9013 compare_item->a.level = val; 9014 else 9015 compare_item->b.level = val; 9016 return len; 9017 } 9018 if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 9019 compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) || 9020 (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE && 9021 compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 9022 if (val >= FLEX_MAX_PARSERS_NUM) { 9023 printf("Bad flex item handle\n"); 9024 return -1; 9025 } 9026 fp = flex_items[ctx->port][val]; 9027 if (!fp) { 9028 printf("Bad flex item handle\n"); 9029 return -1; 9030 } 9031 } 9032 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) { 9033 if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM) 9034 compare_item->a.level = val; 9035 else 9036 compare_item->a.flex_handle = fp->flex_handle; 9037 } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) { 9038 if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM) 9039 compare_item->b.level = val; 9040 else 9041 compare_item->b.flex_handle = fp->flex_handle; 9042 } 9043 return len; 9044 } 9045 9046 /** Parse meter color action type. */ 9047 static int 9048 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 9049 const char *str, unsigned int len, 9050 void *buf, unsigned int size) 9051 { 9052 struct rte_flow_action *action_data; 9053 struct rte_flow_action_meter_color *conf; 9054 enum rte_color color; 9055 9056 (void)buf; 9057 (void)size; 9058 /* Token name must match. */ 9059 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9060 return -1; 9061 switch (ctx->curr) { 9062 case ACTION_METER_COLOR_GREEN: 9063 color = RTE_COLOR_GREEN; 9064 break; 9065 case ACTION_METER_COLOR_YELLOW: 9066 color = RTE_COLOR_YELLOW; 9067 break; 9068 case ACTION_METER_COLOR_RED: 9069 color = RTE_COLOR_RED; 9070 break; 9071 default: 9072 return -1; 9073 } 9074 9075 if (!ctx->object) 9076 return len; 9077 action_data = ctx->object; 9078 conf = (struct rte_flow_action_meter_color *) 9079 (uintptr_t)(action_data->conf); 9080 conf->color = color; 9081 return len; 9082 } 9083 9084 /** Parse RSS action. */ 9085 static int 9086 parse_vc_action_rss(struct context *ctx, const struct token *token, 9087 const char *str, unsigned int len, 9088 void *buf, unsigned int size) 9089 { 9090 struct buffer *out = buf; 9091 struct rte_flow_action *action; 9092 struct action_rss_data *action_rss_data; 9093 unsigned int i; 9094 int ret; 9095 9096 ret = parse_vc(ctx, token, str, len, buf, size); 9097 if (ret < 0) 9098 return ret; 9099 /* Nothing else to do if there is no buffer. */ 9100 if (!out) 9101 return ret; 9102 if (!out->args.vc.actions_n) 9103 return -1; 9104 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9105 /* Point to selected object. */ 9106 ctx->object = out->args.vc.data; 9107 ctx->objmask = NULL; 9108 /* Set up default configuration. */ 9109 action_rss_data = ctx->object; 9110 *action_rss_data = (struct action_rss_data){ 9111 .conf = (struct rte_flow_action_rss){ 9112 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 9113 .level = 0, 9114 .types = rss_hf, 9115 .key_len = 0, 9116 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 9117 .key = NULL, 9118 .queue = action_rss_data->queue, 9119 }, 9120 .queue = { 0 }, 9121 }; 9122 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 9123 action_rss_data->queue[i] = i; 9124 action->conf = &action_rss_data->conf; 9125 return ret; 9126 } 9127 9128 /** 9129 * Parse func field for RSS action. 9130 * 9131 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 9132 * ACTION_RSS_FUNC_* index that called this function. 9133 */ 9134 static int 9135 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 9136 const char *str, unsigned int len, 9137 void *buf, unsigned int size) 9138 { 9139 struct action_rss_data *action_rss_data; 9140 enum rte_eth_hash_function func; 9141 9142 (void)buf; 9143 (void)size; 9144 /* Token name must match. */ 9145 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9146 return -1; 9147 switch (ctx->curr) { 9148 case ACTION_RSS_FUNC_DEFAULT: 9149 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 9150 break; 9151 case ACTION_RSS_FUNC_TOEPLITZ: 9152 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 9153 break; 9154 case ACTION_RSS_FUNC_SIMPLE_XOR: 9155 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 9156 break; 9157 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 9158 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 9159 break; 9160 default: 9161 return -1; 9162 } 9163 if (!ctx->object) 9164 return len; 9165 action_rss_data = ctx->object; 9166 action_rss_data->conf.func = func; 9167 return len; 9168 } 9169 9170 /** 9171 * Parse type field for RSS action. 9172 * 9173 * Valid tokens are type field names and the "end" token. 9174 */ 9175 static int 9176 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 9177 const char *str, unsigned int len, 9178 void *buf, unsigned int size) 9179 { 9180 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 9181 struct action_rss_data *action_rss_data; 9182 unsigned int i; 9183 9184 (void)token; 9185 (void)buf; 9186 (void)size; 9187 if (ctx->curr != ACTION_RSS_TYPE) 9188 return -1; 9189 if (!(ctx->objdata >> 16) && ctx->object) { 9190 action_rss_data = ctx->object; 9191 action_rss_data->conf.types = 0; 9192 } 9193 if (!strcmp_partial("end", str, len)) { 9194 ctx->objdata &= 0xffff; 9195 return len; 9196 } 9197 for (i = 0; rss_type_table[i].str; ++i) 9198 if (!strcmp_partial(rss_type_table[i].str, str, len)) 9199 break; 9200 if (!rss_type_table[i].str) 9201 return -1; 9202 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 9203 /* Repeat token. */ 9204 if (ctx->next_num == RTE_DIM(ctx->next)) 9205 return -1; 9206 ctx->next[ctx->next_num++] = next; 9207 if (!ctx->object) 9208 return len; 9209 action_rss_data = ctx->object; 9210 action_rss_data->conf.types |= rss_type_table[i].rss_type; 9211 return len; 9212 } 9213 9214 /** 9215 * Parse queue field for RSS action. 9216 * 9217 * Valid tokens are queue indices and the "end" token. 9218 */ 9219 static int 9220 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 9221 const char *str, unsigned int len, 9222 void *buf, unsigned int size) 9223 { 9224 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 9225 struct action_rss_data *action_rss_data; 9226 const struct arg *arg; 9227 int ret; 9228 int i; 9229 9230 (void)token; 9231 (void)buf; 9232 (void)size; 9233 if (ctx->curr != ACTION_RSS_QUEUE) 9234 return -1; 9235 i = ctx->objdata >> 16; 9236 if (!strcmp_partial("end", str, len)) { 9237 ctx->objdata &= 0xffff; 9238 goto end; 9239 } 9240 if (i >= ACTION_RSS_QUEUE_NUM) 9241 return -1; 9242 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 9243 i * sizeof(action_rss_data->queue[i]), 9244 sizeof(action_rss_data->queue[i])); 9245 if (push_args(ctx, arg)) 9246 return -1; 9247 ret = parse_int(ctx, token, str, len, NULL, 0); 9248 if (ret < 0) { 9249 pop_args(ctx); 9250 return -1; 9251 } 9252 ++i; 9253 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 9254 /* Repeat token. */ 9255 if (ctx->next_num == RTE_DIM(ctx->next)) 9256 return -1; 9257 ctx->next[ctx->next_num++] = next; 9258 end: 9259 if (!ctx->object) 9260 return len; 9261 action_rss_data = ctx->object; 9262 action_rss_data->conf.queue_num = i; 9263 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 9264 return len; 9265 } 9266 9267 /** Setup VXLAN encap configuration. */ 9268 static int 9269 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 9270 { 9271 /* Set up default configuration. */ 9272 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 9273 .conf = (struct rte_flow_action_vxlan_encap){ 9274 .definition = action_vxlan_encap_data->items, 9275 }, 9276 .items = { 9277 { 9278 .type = RTE_FLOW_ITEM_TYPE_ETH, 9279 .spec = &action_vxlan_encap_data->item_eth, 9280 .mask = &rte_flow_item_eth_mask, 9281 }, 9282 { 9283 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9284 .spec = &action_vxlan_encap_data->item_vlan, 9285 .mask = &rte_flow_item_vlan_mask, 9286 }, 9287 { 9288 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9289 .spec = &action_vxlan_encap_data->item_ipv4, 9290 .mask = &rte_flow_item_ipv4_mask, 9291 }, 9292 { 9293 .type = RTE_FLOW_ITEM_TYPE_UDP, 9294 .spec = &action_vxlan_encap_data->item_udp, 9295 .mask = &rte_flow_item_udp_mask, 9296 }, 9297 { 9298 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 9299 .spec = &action_vxlan_encap_data->item_vxlan, 9300 .mask = &rte_flow_item_vxlan_mask, 9301 }, 9302 { 9303 .type = RTE_FLOW_ITEM_TYPE_END, 9304 }, 9305 }, 9306 .item_eth.hdr.ether_type = 0, 9307 .item_vlan = { 9308 .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, 9309 .hdr.eth_proto = 0, 9310 }, 9311 .item_ipv4.hdr = { 9312 .src_addr = vxlan_encap_conf.ipv4_src, 9313 .dst_addr = vxlan_encap_conf.ipv4_dst, 9314 }, 9315 .item_udp.hdr = { 9316 .src_port = vxlan_encap_conf.udp_src, 9317 .dst_port = vxlan_encap_conf.udp_dst, 9318 }, 9319 .item_vxlan.hdr.flags = 0, 9320 }; 9321 memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9322 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9323 memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, 9324 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9325 if (!vxlan_encap_conf.select_ipv4) { 9326 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 9327 &vxlan_encap_conf.ipv6_src, 9328 sizeof(vxlan_encap_conf.ipv6_src)); 9329 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 9330 &vxlan_encap_conf.ipv6_dst, 9331 sizeof(vxlan_encap_conf.ipv6_dst)); 9332 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 9333 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9334 .spec = &action_vxlan_encap_data->item_ipv6, 9335 .mask = &rte_flow_item_ipv6_mask, 9336 }; 9337 } 9338 if (!vxlan_encap_conf.select_vlan) 9339 action_vxlan_encap_data->items[1].type = 9340 RTE_FLOW_ITEM_TYPE_VOID; 9341 if (vxlan_encap_conf.select_tos_ttl) { 9342 if (vxlan_encap_conf.select_ipv4) { 9343 static struct rte_flow_item_ipv4 ipv4_mask_tos; 9344 9345 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 9346 sizeof(ipv4_mask_tos)); 9347 ipv4_mask_tos.hdr.type_of_service = 0xff; 9348 ipv4_mask_tos.hdr.time_to_live = 0xff; 9349 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 9350 vxlan_encap_conf.ip_tos; 9351 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 9352 vxlan_encap_conf.ip_ttl; 9353 action_vxlan_encap_data->items[2].mask = 9354 &ipv4_mask_tos; 9355 } else { 9356 static struct rte_flow_item_ipv6 ipv6_mask_tos; 9357 9358 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 9359 sizeof(ipv6_mask_tos)); 9360 ipv6_mask_tos.hdr.vtc_flow |= 9361 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 9362 ipv6_mask_tos.hdr.hop_limits = 0xff; 9363 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 9364 rte_cpu_to_be_32 9365 ((uint32_t)vxlan_encap_conf.ip_tos << 9366 RTE_IPV6_HDR_TC_SHIFT); 9367 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 9368 vxlan_encap_conf.ip_ttl; 9369 action_vxlan_encap_data->items[2].mask = 9370 &ipv6_mask_tos; 9371 } 9372 } 9373 memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, 9374 RTE_DIM(vxlan_encap_conf.vni)); 9375 return 0; 9376 } 9377 9378 /** Parse VXLAN encap action. */ 9379 static int 9380 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 9381 const char *str, unsigned int len, 9382 void *buf, unsigned int size) 9383 { 9384 struct buffer *out = buf; 9385 struct rte_flow_action *action; 9386 struct action_vxlan_encap_data *action_vxlan_encap_data; 9387 int ret; 9388 9389 ret = parse_vc(ctx, token, str, len, buf, size); 9390 if (ret < 0) 9391 return ret; 9392 /* Nothing else to do if there is no buffer. */ 9393 if (!out) 9394 return ret; 9395 if (!out->args.vc.actions_n) 9396 return -1; 9397 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9398 /* Point to selected object. */ 9399 ctx->object = out->args.vc.data; 9400 ctx->objmask = NULL; 9401 action_vxlan_encap_data = ctx->object; 9402 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 9403 action->conf = &action_vxlan_encap_data->conf; 9404 return ret; 9405 } 9406 9407 /** Setup NVGRE encap configuration. */ 9408 static int 9409 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 9410 { 9411 /* Set up default configuration. */ 9412 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 9413 .conf = (struct rte_flow_action_nvgre_encap){ 9414 .definition = action_nvgre_encap_data->items, 9415 }, 9416 .items = { 9417 { 9418 .type = RTE_FLOW_ITEM_TYPE_ETH, 9419 .spec = &action_nvgre_encap_data->item_eth, 9420 .mask = &rte_flow_item_eth_mask, 9421 }, 9422 { 9423 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9424 .spec = &action_nvgre_encap_data->item_vlan, 9425 .mask = &rte_flow_item_vlan_mask, 9426 }, 9427 { 9428 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9429 .spec = &action_nvgre_encap_data->item_ipv4, 9430 .mask = &rte_flow_item_ipv4_mask, 9431 }, 9432 { 9433 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 9434 .spec = &action_nvgre_encap_data->item_nvgre, 9435 .mask = &rte_flow_item_nvgre_mask, 9436 }, 9437 { 9438 .type = RTE_FLOW_ITEM_TYPE_END, 9439 }, 9440 }, 9441 .item_eth.hdr.ether_type = 0, 9442 .item_vlan = { 9443 .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, 9444 .hdr.eth_proto = 0, 9445 }, 9446 .item_ipv4.hdr = { 9447 .src_addr = nvgre_encap_conf.ipv4_src, 9448 .dst_addr = nvgre_encap_conf.ipv4_dst, 9449 }, 9450 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 9451 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 9452 .item_nvgre.flow_id = 0, 9453 }; 9454 memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9455 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9456 memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, 9457 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9458 if (!nvgre_encap_conf.select_ipv4) { 9459 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 9460 &nvgre_encap_conf.ipv6_src, 9461 sizeof(nvgre_encap_conf.ipv6_src)); 9462 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 9463 &nvgre_encap_conf.ipv6_dst, 9464 sizeof(nvgre_encap_conf.ipv6_dst)); 9465 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 9466 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9467 .spec = &action_nvgre_encap_data->item_ipv6, 9468 .mask = &rte_flow_item_ipv6_mask, 9469 }; 9470 } 9471 if (!nvgre_encap_conf.select_vlan) 9472 action_nvgre_encap_data->items[1].type = 9473 RTE_FLOW_ITEM_TYPE_VOID; 9474 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 9475 RTE_DIM(nvgre_encap_conf.tni)); 9476 return 0; 9477 } 9478 9479 /** Parse NVGRE encap action. */ 9480 static int 9481 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 9482 const char *str, unsigned int len, 9483 void *buf, unsigned int size) 9484 { 9485 struct buffer *out = buf; 9486 struct rte_flow_action *action; 9487 struct action_nvgre_encap_data *action_nvgre_encap_data; 9488 int ret; 9489 9490 ret = parse_vc(ctx, token, str, len, buf, size); 9491 if (ret < 0) 9492 return ret; 9493 /* Nothing else to do if there is no buffer. */ 9494 if (!out) 9495 return ret; 9496 if (!out->args.vc.actions_n) 9497 return -1; 9498 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9499 /* Point to selected object. */ 9500 ctx->object = out->args.vc.data; 9501 ctx->objmask = NULL; 9502 action_nvgre_encap_data = ctx->object; 9503 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 9504 action->conf = &action_nvgre_encap_data->conf; 9505 return ret; 9506 } 9507 9508 /** Parse l2 encap action. */ 9509 static int 9510 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 9511 const char *str, unsigned int len, 9512 void *buf, unsigned int size) 9513 { 9514 struct buffer *out = buf; 9515 struct rte_flow_action *action; 9516 struct action_raw_encap_data *action_encap_data; 9517 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9518 struct rte_flow_item_vlan vlan = { 9519 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9520 .hdr.eth_proto = 0, 9521 }; 9522 uint8_t *header; 9523 int ret; 9524 9525 ret = parse_vc(ctx, token, str, len, buf, size); 9526 if (ret < 0) 9527 return ret; 9528 /* Nothing else to do if there is no buffer. */ 9529 if (!out) 9530 return ret; 9531 if (!out->args.vc.actions_n) 9532 return -1; 9533 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9534 /* Point to selected object. */ 9535 ctx->object = out->args.vc.data; 9536 ctx->objmask = NULL; 9537 /* Copy the headers to the buffer. */ 9538 action_encap_data = ctx->object; 9539 *action_encap_data = (struct action_raw_encap_data) { 9540 .conf = (struct rte_flow_action_raw_encap){ 9541 .data = action_encap_data->data, 9542 }, 9543 .data = {}, 9544 }; 9545 header = action_encap_data->data; 9546 if (l2_encap_conf.select_vlan) 9547 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9548 else if (l2_encap_conf.select_ipv4) 9549 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9550 else 9551 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9552 memcpy(eth.hdr.dst_addr.addr_bytes, 9553 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9554 memcpy(eth.hdr.src_addr.addr_bytes, 9555 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9556 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9557 header += sizeof(struct rte_ether_hdr); 9558 if (l2_encap_conf.select_vlan) { 9559 if (l2_encap_conf.select_ipv4) 9560 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9561 else 9562 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9563 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9564 header += sizeof(struct rte_vlan_hdr); 9565 } 9566 action_encap_data->conf.size = header - 9567 action_encap_data->data; 9568 action->conf = &action_encap_data->conf; 9569 return ret; 9570 } 9571 9572 /** Parse l2 decap action. */ 9573 static int 9574 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 9575 const char *str, unsigned int len, 9576 void *buf, unsigned int size) 9577 { 9578 struct buffer *out = buf; 9579 struct rte_flow_action *action; 9580 struct action_raw_decap_data *action_decap_data; 9581 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9582 struct rte_flow_item_vlan vlan = { 9583 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9584 .hdr.eth_proto = 0, 9585 }; 9586 uint8_t *header; 9587 int ret; 9588 9589 ret = parse_vc(ctx, token, str, len, buf, size); 9590 if (ret < 0) 9591 return ret; 9592 /* Nothing else to do if there is no buffer. */ 9593 if (!out) 9594 return ret; 9595 if (!out->args.vc.actions_n) 9596 return -1; 9597 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9598 /* Point to selected object. */ 9599 ctx->object = out->args.vc.data; 9600 ctx->objmask = NULL; 9601 /* Copy the headers to the buffer. */ 9602 action_decap_data = ctx->object; 9603 *action_decap_data = (struct action_raw_decap_data) { 9604 .conf = (struct rte_flow_action_raw_decap){ 9605 .data = action_decap_data->data, 9606 }, 9607 .data = {}, 9608 }; 9609 header = action_decap_data->data; 9610 if (l2_decap_conf.select_vlan) 9611 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9612 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9613 header += sizeof(struct rte_ether_hdr); 9614 if (l2_decap_conf.select_vlan) { 9615 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9616 header += sizeof(struct rte_vlan_hdr); 9617 } 9618 action_decap_data->conf.size = header - 9619 action_decap_data->data; 9620 action->conf = &action_decap_data->conf; 9621 return ret; 9622 } 9623 9624 #define ETHER_TYPE_MPLS_UNICAST 0x8847 9625 9626 /** Parse MPLSOGRE encap action. */ 9627 static int 9628 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 9629 const char *str, unsigned int len, 9630 void *buf, unsigned int size) 9631 { 9632 struct buffer *out = buf; 9633 struct rte_flow_action *action; 9634 struct action_raw_encap_data *action_encap_data; 9635 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9636 struct rte_flow_item_vlan vlan = { 9637 .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, 9638 .hdr.eth_proto = 0, 9639 }; 9640 struct rte_flow_item_ipv4 ipv4 = { 9641 .hdr = { 9642 .src_addr = mplsogre_encap_conf.ipv4_src, 9643 .dst_addr = mplsogre_encap_conf.ipv4_dst, 9644 .next_proto_id = IPPROTO_GRE, 9645 .version_ihl = RTE_IPV4_VHL_DEF, 9646 .time_to_live = IPDEFTTL, 9647 }, 9648 }; 9649 struct rte_flow_item_ipv6 ipv6 = { 9650 .hdr = { 9651 .proto = IPPROTO_GRE, 9652 .hop_limits = IPDEFTTL, 9653 }, 9654 }; 9655 struct rte_flow_item_gre gre = { 9656 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9657 }; 9658 struct rte_flow_item_mpls mpls = { 9659 .ttl = 0, 9660 }; 9661 uint8_t *header; 9662 int ret; 9663 9664 ret = parse_vc(ctx, token, str, len, buf, size); 9665 if (ret < 0) 9666 return ret; 9667 /* Nothing else to do if there is no buffer. */ 9668 if (!out) 9669 return ret; 9670 if (!out->args.vc.actions_n) 9671 return -1; 9672 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9673 /* Point to selected object. */ 9674 ctx->object = out->args.vc.data; 9675 ctx->objmask = NULL; 9676 /* Copy the headers to the buffer. */ 9677 action_encap_data = ctx->object; 9678 *action_encap_data = (struct action_raw_encap_data) { 9679 .conf = (struct rte_flow_action_raw_encap){ 9680 .data = action_encap_data->data, 9681 }, 9682 .data = {}, 9683 .preserve = {}, 9684 }; 9685 header = action_encap_data->data; 9686 if (mplsogre_encap_conf.select_vlan) 9687 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9688 else if (mplsogre_encap_conf.select_ipv4) 9689 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9690 else 9691 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9692 memcpy(eth.hdr.dst_addr.addr_bytes, 9693 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9694 memcpy(eth.hdr.src_addr.addr_bytes, 9695 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9696 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9697 header += sizeof(struct rte_ether_hdr); 9698 if (mplsogre_encap_conf.select_vlan) { 9699 if (mplsogre_encap_conf.select_ipv4) 9700 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9701 else 9702 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9703 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9704 header += sizeof(struct rte_vlan_hdr); 9705 } 9706 if (mplsogre_encap_conf.select_ipv4) { 9707 memcpy(header, &ipv4, sizeof(ipv4)); 9708 header += sizeof(ipv4); 9709 } else { 9710 memcpy(&ipv6.hdr.src_addr, 9711 &mplsogre_encap_conf.ipv6_src, 9712 sizeof(mplsogre_encap_conf.ipv6_src)); 9713 memcpy(&ipv6.hdr.dst_addr, 9714 &mplsogre_encap_conf.ipv6_dst, 9715 sizeof(mplsogre_encap_conf.ipv6_dst)); 9716 memcpy(header, &ipv6, sizeof(ipv6)); 9717 header += sizeof(ipv6); 9718 } 9719 memcpy(header, &gre, sizeof(gre)); 9720 header += sizeof(gre); 9721 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 9722 RTE_DIM(mplsogre_encap_conf.label)); 9723 mpls.label_tc_s[2] |= 0x1; 9724 memcpy(header, &mpls, sizeof(mpls)); 9725 header += sizeof(mpls); 9726 action_encap_data->conf.size = header - 9727 action_encap_data->data; 9728 action->conf = &action_encap_data->conf; 9729 return ret; 9730 } 9731 9732 /** Parse MPLSOGRE decap action. */ 9733 static int 9734 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 9735 const char *str, unsigned int len, 9736 void *buf, unsigned int size) 9737 { 9738 struct buffer *out = buf; 9739 struct rte_flow_action *action; 9740 struct action_raw_decap_data *action_decap_data; 9741 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9742 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9743 struct rte_flow_item_ipv4 ipv4 = { 9744 .hdr = { 9745 .next_proto_id = IPPROTO_GRE, 9746 }, 9747 }; 9748 struct rte_flow_item_ipv6 ipv6 = { 9749 .hdr = { 9750 .proto = IPPROTO_GRE, 9751 }, 9752 }; 9753 struct rte_flow_item_gre gre = { 9754 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9755 }; 9756 struct rte_flow_item_mpls mpls; 9757 uint8_t *header; 9758 int ret; 9759 9760 ret = parse_vc(ctx, token, str, len, buf, size); 9761 if (ret < 0) 9762 return ret; 9763 /* Nothing else to do if there is no buffer. */ 9764 if (!out) 9765 return ret; 9766 if (!out->args.vc.actions_n) 9767 return -1; 9768 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9769 /* Point to selected object. */ 9770 ctx->object = out->args.vc.data; 9771 ctx->objmask = NULL; 9772 /* Copy the headers to the buffer. */ 9773 action_decap_data = ctx->object; 9774 *action_decap_data = (struct action_raw_decap_data) { 9775 .conf = (struct rte_flow_action_raw_decap){ 9776 .data = action_decap_data->data, 9777 }, 9778 .data = {}, 9779 }; 9780 header = action_decap_data->data; 9781 if (mplsogre_decap_conf.select_vlan) 9782 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9783 else if (mplsogre_encap_conf.select_ipv4) 9784 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9785 else 9786 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9787 memcpy(eth.hdr.dst_addr.addr_bytes, 9788 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9789 memcpy(eth.hdr.src_addr.addr_bytes, 9790 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9791 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9792 header += sizeof(struct rte_ether_hdr); 9793 if (mplsogre_encap_conf.select_vlan) { 9794 if (mplsogre_encap_conf.select_ipv4) 9795 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9796 else 9797 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9798 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9799 header += sizeof(struct rte_vlan_hdr); 9800 } 9801 if (mplsogre_encap_conf.select_ipv4) { 9802 memcpy(header, &ipv4, sizeof(ipv4)); 9803 header += sizeof(ipv4); 9804 } else { 9805 memcpy(header, &ipv6, sizeof(ipv6)); 9806 header += sizeof(ipv6); 9807 } 9808 memcpy(header, &gre, sizeof(gre)); 9809 header += sizeof(gre); 9810 memset(&mpls, 0, sizeof(mpls)); 9811 memcpy(header, &mpls, sizeof(mpls)); 9812 header += sizeof(mpls); 9813 action_decap_data->conf.size = header - 9814 action_decap_data->data; 9815 action->conf = &action_decap_data->conf; 9816 return ret; 9817 } 9818 9819 /** Parse MPLSOUDP encap action. */ 9820 static int 9821 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 9822 const char *str, unsigned int len, 9823 void *buf, unsigned int size) 9824 { 9825 struct buffer *out = buf; 9826 struct rte_flow_action *action; 9827 struct action_raw_encap_data *action_encap_data; 9828 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9829 struct rte_flow_item_vlan vlan = { 9830 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9831 .hdr.eth_proto = 0, 9832 }; 9833 struct rte_flow_item_ipv4 ipv4 = { 9834 .hdr = { 9835 .src_addr = mplsoudp_encap_conf.ipv4_src, 9836 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 9837 .next_proto_id = IPPROTO_UDP, 9838 .version_ihl = RTE_IPV4_VHL_DEF, 9839 .time_to_live = IPDEFTTL, 9840 }, 9841 }; 9842 struct rte_flow_item_ipv6 ipv6 = { 9843 .hdr = { 9844 .proto = IPPROTO_UDP, 9845 .hop_limits = IPDEFTTL, 9846 }, 9847 }; 9848 struct rte_flow_item_udp udp = { 9849 .hdr = { 9850 .src_port = mplsoudp_encap_conf.udp_src, 9851 .dst_port = mplsoudp_encap_conf.udp_dst, 9852 }, 9853 }; 9854 struct rte_flow_item_mpls mpls; 9855 uint8_t *header; 9856 int ret; 9857 9858 ret = parse_vc(ctx, token, str, len, buf, size); 9859 if (ret < 0) 9860 return ret; 9861 /* Nothing else to do if there is no buffer. */ 9862 if (!out) 9863 return ret; 9864 if (!out->args.vc.actions_n) 9865 return -1; 9866 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9867 /* Point to selected object. */ 9868 ctx->object = out->args.vc.data; 9869 ctx->objmask = NULL; 9870 /* Copy the headers to the buffer. */ 9871 action_encap_data = ctx->object; 9872 *action_encap_data = (struct action_raw_encap_data) { 9873 .conf = (struct rte_flow_action_raw_encap){ 9874 .data = action_encap_data->data, 9875 }, 9876 .data = {}, 9877 .preserve = {}, 9878 }; 9879 header = action_encap_data->data; 9880 if (mplsoudp_encap_conf.select_vlan) 9881 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9882 else if (mplsoudp_encap_conf.select_ipv4) 9883 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9884 else 9885 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9886 memcpy(eth.hdr.dst_addr.addr_bytes, 9887 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9888 memcpy(eth.hdr.src_addr.addr_bytes, 9889 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9890 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9891 header += sizeof(struct rte_ether_hdr); 9892 if (mplsoudp_encap_conf.select_vlan) { 9893 if (mplsoudp_encap_conf.select_ipv4) 9894 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9895 else 9896 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9897 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9898 header += sizeof(struct rte_vlan_hdr); 9899 } 9900 if (mplsoudp_encap_conf.select_ipv4) { 9901 memcpy(header, &ipv4, sizeof(ipv4)); 9902 header += sizeof(ipv4); 9903 } else { 9904 memcpy(&ipv6.hdr.src_addr, 9905 &mplsoudp_encap_conf.ipv6_src, 9906 sizeof(mplsoudp_encap_conf.ipv6_src)); 9907 memcpy(&ipv6.hdr.dst_addr, 9908 &mplsoudp_encap_conf.ipv6_dst, 9909 sizeof(mplsoudp_encap_conf.ipv6_dst)); 9910 memcpy(header, &ipv6, sizeof(ipv6)); 9911 header += sizeof(ipv6); 9912 } 9913 memcpy(header, &udp, sizeof(udp)); 9914 header += sizeof(udp); 9915 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 9916 RTE_DIM(mplsoudp_encap_conf.label)); 9917 mpls.label_tc_s[2] |= 0x1; 9918 memcpy(header, &mpls, sizeof(mpls)); 9919 header += sizeof(mpls); 9920 action_encap_data->conf.size = header - 9921 action_encap_data->data; 9922 action->conf = &action_encap_data->conf; 9923 return ret; 9924 } 9925 9926 /** Parse MPLSOUDP decap action. */ 9927 static int 9928 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 9929 const char *str, unsigned int len, 9930 void *buf, unsigned int size) 9931 { 9932 struct buffer *out = buf; 9933 struct rte_flow_action *action; 9934 struct action_raw_decap_data *action_decap_data; 9935 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9936 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9937 struct rte_flow_item_ipv4 ipv4 = { 9938 .hdr = { 9939 .next_proto_id = IPPROTO_UDP, 9940 }, 9941 }; 9942 struct rte_flow_item_ipv6 ipv6 = { 9943 .hdr = { 9944 .proto = IPPROTO_UDP, 9945 }, 9946 }; 9947 struct rte_flow_item_udp udp = { 9948 .hdr = { 9949 .dst_port = rte_cpu_to_be_16(6635), 9950 }, 9951 }; 9952 struct rte_flow_item_mpls mpls; 9953 uint8_t *header; 9954 int ret; 9955 9956 ret = parse_vc(ctx, token, str, len, buf, size); 9957 if (ret < 0) 9958 return ret; 9959 /* Nothing else to do if there is no buffer. */ 9960 if (!out) 9961 return ret; 9962 if (!out->args.vc.actions_n) 9963 return -1; 9964 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9965 /* Point to selected object. */ 9966 ctx->object = out->args.vc.data; 9967 ctx->objmask = NULL; 9968 /* Copy the headers to the buffer. */ 9969 action_decap_data = ctx->object; 9970 *action_decap_data = (struct action_raw_decap_data) { 9971 .conf = (struct rte_flow_action_raw_decap){ 9972 .data = action_decap_data->data, 9973 }, 9974 .data = {}, 9975 }; 9976 header = action_decap_data->data; 9977 if (mplsoudp_decap_conf.select_vlan) 9978 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9979 else if (mplsoudp_encap_conf.select_ipv4) 9980 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9981 else 9982 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9983 memcpy(eth.hdr.dst_addr.addr_bytes, 9984 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9985 memcpy(eth.hdr.src_addr.addr_bytes, 9986 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9987 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9988 header += sizeof(struct rte_ether_hdr); 9989 if (mplsoudp_encap_conf.select_vlan) { 9990 if (mplsoudp_encap_conf.select_ipv4) 9991 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9992 else 9993 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9994 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9995 header += sizeof(struct rte_vlan_hdr); 9996 } 9997 if (mplsoudp_encap_conf.select_ipv4) { 9998 memcpy(header, &ipv4, sizeof(ipv4)); 9999 header += sizeof(ipv4); 10000 } else { 10001 memcpy(header, &ipv6, sizeof(ipv6)); 10002 header += sizeof(ipv6); 10003 } 10004 memcpy(header, &udp, sizeof(udp)); 10005 header += sizeof(udp); 10006 memset(&mpls, 0, sizeof(mpls)); 10007 memcpy(header, &mpls, sizeof(mpls)); 10008 header += sizeof(mpls); 10009 action_decap_data->conf.size = header - 10010 action_decap_data->data; 10011 action->conf = &action_decap_data->conf; 10012 return ret; 10013 } 10014 10015 static int 10016 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 10017 const char *str, unsigned int len, void *buf, 10018 unsigned int size) 10019 { 10020 struct action_raw_decap_data *action_raw_decap_data; 10021 struct rte_flow_action *action; 10022 const struct arg *arg; 10023 struct buffer *out = buf; 10024 int ret; 10025 uint16_t idx; 10026 10027 RTE_SET_USED(token); 10028 RTE_SET_USED(buf); 10029 RTE_SET_USED(size); 10030 arg = ARGS_ENTRY_ARB_BOUNDED 10031 (offsetof(struct action_raw_decap_data, idx), 10032 sizeof(((struct action_raw_decap_data *)0)->idx), 10033 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10034 if (push_args(ctx, arg)) 10035 return -1; 10036 ret = parse_int(ctx, token, str, len, NULL, 0); 10037 if (ret < 0) { 10038 pop_args(ctx); 10039 return -1; 10040 } 10041 if (!ctx->object) 10042 return len; 10043 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10044 action_raw_decap_data = ctx->object; 10045 idx = action_raw_decap_data->idx; 10046 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 10047 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 10048 action->conf = &action_raw_decap_data->conf; 10049 return len; 10050 } 10051 10052 10053 static int 10054 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 10055 const char *str, unsigned int len, void *buf, 10056 unsigned int size) 10057 { 10058 struct action_raw_encap_data *action_raw_encap_data; 10059 struct rte_flow_action *action; 10060 const struct arg *arg; 10061 struct buffer *out = buf; 10062 int ret; 10063 uint16_t idx; 10064 10065 RTE_SET_USED(token); 10066 RTE_SET_USED(buf); 10067 RTE_SET_USED(size); 10068 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 10069 return -1; 10070 arg = ARGS_ENTRY_ARB_BOUNDED 10071 (offsetof(struct action_raw_encap_data, idx), 10072 sizeof(((struct action_raw_encap_data *)0)->idx), 10073 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10074 if (push_args(ctx, arg)) 10075 return -1; 10076 ret = parse_int(ctx, token, str, len, NULL, 0); 10077 if (ret < 0) { 10078 pop_args(ctx); 10079 return -1; 10080 } 10081 if (!ctx->object) 10082 return len; 10083 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10084 action_raw_encap_data = ctx->object; 10085 idx = action_raw_encap_data->idx; 10086 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 10087 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 10088 action_raw_encap_data->conf.preserve = NULL; 10089 action->conf = &action_raw_encap_data->conf; 10090 return len; 10091 } 10092 10093 static int 10094 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 10095 const char *str, unsigned int len, void *buf, 10096 unsigned int size) 10097 { 10098 struct buffer *out = buf; 10099 int ret; 10100 10101 ret = parse_vc(ctx, token, str, len, buf, size); 10102 if (ret < 0) 10103 return ret; 10104 /* Nothing else to do if there is no buffer. */ 10105 if (!out) 10106 return ret; 10107 if (!out->args.vc.actions_n) 10108 return -1; 10109 /* Point to selected object. */ 10110 ctx->object = out->args.vc.data; 10111 ctx->objmask = NULL; 10112 return ret; 10113 } 10114 10115 static int 10116 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 10117 const char *str, unsigned int len, void *buf, 10118 unsigned int size) 10119 { 10120 struct buffer *out = buf; 10121 struct rte_flow_action *action; 10122 struct action_raw_decap_data *action_raw_decap_data = NULL; 10123 int ret; 10124 10125 ret = parse_vc(ctx, token, str, len, buf, size); 10126 if (ret < 0) 10127 return ret; 10128 /* Nothing else to do if there is no buffer. */ 10129 if (!out) 10130 return ret; 10131 if (!out->args.vc.actions_n) 10132 return -1; 10133 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10134 /* Point to selected object. */ 10135 ctx->object = out->args.vc.data; 10136 ctx->objmask = NULL; 10137 /* Copy the headers to the buffer. */ 10138 action_raw_decap_data = ctx->object; 10139 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 10140 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 10141 action->conf = &action_raw_decap_data->conf; 10142 return ret; 10143 } 10144 10145 static int 10146 parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 10147 const char *str, unsigned int len, void *buf, 10148 unsigned int size) 10149 { 10150 struct buffer *out = buf; 10151 struct rte_flow_action *action; 10152 struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; 10153 int ret; 10154 10155 ret = parse_vc(ctx, token, str, len, buf, size); 10156 if (ret < 0) 10157 return ret; 10158 /* Nothing else to do if there is no buffer. */ 10159 if (!out) 10160 return ret; 10161 if (!out->args.vc.actions_n) 10162 return -1; 10163 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10164 /* Point to selected object. */ 10165 ctx->object = out->args.vc.data; 10166 ctx->objmask = NULL; 10167 /* Copy the headers to the buffer. */ 10168 ipv6_ext_remove_data = ctx->object; 10169 ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; 10170 action->conf = &ipv6_ext_remove_data->conf; 10171 return ret; 10172 } 10173 10174 static int 10175 parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, 10176 const char *str, unsigned int len, void *buf, 10177 unsigned int size) 10178 { 10179 struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; 10180 struct rte_flow_action *action; 10181 const struct arg *arg; 10182 struct buffer *out = buf; 10183 int ret; 10184 uint16_t idx; 10185 10186 RTE_SET_USED(token); 10187 RTE_SET_USED(buf); 10188 RTE_SET_USED(size); 10189 arg = ARGS_ENTRY_ARB_BOUNDED 10190 (offsetof(struct action_ipv6_ext_remove_data, idx), 10191 sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), 10192 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10193 if (push_args(ctx, arg)) 10194 return -1; 10195 ret = parse_int(ctx, token, str, len, NULL, 0); 10196 if (ret < 0) { 10197 pop_args(ctx); 10198 return -1; 10199 } 10200 if (!ctx->object) 10201 return len; 10202 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10203 action_ipv6_ext_remove_data = ctx->object; 10204 idx = action_ipv6_ext_remove_data->idx; 10205 action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; 10206 action->conf = &action_ipv6_ext_remove_data->conf; 10207 return len; 10208 } 10209 10210 static int 10211 parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 10212 const char *str, unsigned int len, void *buf, 10213 unsigned int size) 10214 { 10215 struct buffer *out = buf; 10216 struct rte_flow_action *action; 10217 struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; 10218 int ret; 10219 10220 ret = parse_vc(ctx, token, str, len, buf, size); 10221 if (ret < 0) 10222 return ret; 10223 /* Nothing else to do if there is no buffer. */ 10224 if (!out) 10225 return ret; 10226 if (!out->args.vc.actions_n) 10227 return -1; 10228 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10229 /* Point to selected object. */ 10230 ctx->object = out->args.vc.data; 10231 ctx->objmask = NULL; 10232 /* Copy the headers to the buffer. */ 10233 ipv6_ext_push_data = ctx->object; 10234 ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; 10235 ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; 10236 ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; 10237 action->conf = &ipv6_ext_push_data->conf; 10238 return ret; 10239 } 10240 10241 static int 10242 parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, 10243 const char *str, unsigned int len, void *buf, 10244 unsigned int size) 10245 { 10246 struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; 10247 struct rte_flow_action *action; 10248 const struct arg *arg; 10249 struct buffer *out = buf; 10250 int ret; 10251 uint16_t idx; 10252 10253 RTE_SET_USED(token); 10254 RTE_SET_USED(buf); 10255 RTE_SET_USED(size); 10256 arg = ARGS_ENTRY_ARB_BOUNDED 10257 (offsetof(struct action_ipv6_ext_push_data, idx), 10258 sizeof(((struct action_ipv6_ext_push_data *)0)->idx), 10259 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10260 if (push_args(ctx, arg)) 10261 return -1; 10262 ret = parse_int(ctx, token, str, len, NULL, 0); 10263 if (ret < 0) { 10264 pop_args(ctx); 10265 return -1; 10266 } 10267 if (!ctx->object) 10268 return len; 10269 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10270 action_ipv6_ext_push_data = ctx->object; 10271 idx = action_ipv6_ext_push_data->idx; 10272 action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; 10273 action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; 10274 action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; 10275 action->conf = &action_ipv6_ext_push_data->conf; 10276 return len; 10277 } 10278 10279 static int 10280 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 10281 const char *str, unsigned int len, void *buf, 10282 unsigned int size) 10283 { 10284 int ret; 10285 10286 ret = parse_vc(ctx, token, str, len, buf, size); 10287 if (ret < 0) 10288 return ret; 10289 ret = rte_flow_dynf_metadata_register(); 10290 if (ret < 0) 10291 return -1; 10292 return len; 10293 } 10294 10295 static int 10296 parse_vc_action_sample(struct context *ctx, const struct token *token, 10297 const char *str, unsigned int len, void *buf, 10298 unsigned int size) 10299 { 10300 struct buffer *out = buf; 10301 struct rte_flow_action *action; 10302 struct action_sample_data *action_sample_data = NULL; 10303 static struct rte_flow_action end_action = { 10304 RTE_FLOW_ACTION_TYPE_END, 0 10305 }; 10306 int ret; 10307 10308 ret = parse_vc(ctx, token, str, len, buf, size); 10309 if (ret < 0) 10310 return ret; 10311 /* Nothing else to do if there is no buffer. */ 10312 if (!out) 10313 return ret; 10314 if (!out->args.vc.actions_n) 10315 return -1; 10316 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10317 /* Point to selected object. */ 10318 ctx->object = out->args.vc.data; 10319 ctx->objmask = NULL; 10320 /* Copy the headers to the buffer. */ 10321 action_sample_data = ctx->object; 10322 action_sample_data->conf.actions = &end_action; 10323 action->conf = &action_sample_data->conf; 10324 return ret; 10325 } 10326 10327 static int 10328 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 10329 const char *str, unsigned int len, void *buf, 10330 unsigned int size) 10331 { 10332 struct action_sample_data *action_sample_data; 10333 struct rte_flow_action *action; 10334 const struct arg *arg; 10335 struct buffer *out = buf; 10336 int ret; 10337 uint16_t idx; 10338 10339 RTE_SET_USED(token); 10340 RTE_SET_USED(buf); 10341 RTE_SET_USED(size); 10342 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 10343 return -1; 10344 arg = ARGS_ENTRY_ARB_BOUNDED 10345 (offsetof(struct action_sample_data, idx), 10346 sizeof(((struct action_sample_data *)0)->idx), 10347 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 10348 if (push_args(ctx, arg)) 10349 return -1; 10350 ret = parse_int(ctx, token, str, len, NULL, 0); 10351 if (ret < 0) { 10352 pop_args(ctx); 10353 return -1; 10354 } 10355 if (!ctx->object) 10356 return len; 10357 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10358 action_sample_data = ctx->object; 10359 idx = action_sample_data->idx; 10360 action_sample_data->conf.actions = raw_sample_confs[idx].data; 10361 action->conf = &action_sample_data->conf; 10362 return len; 10363 } 10364 10365 /** Parse operation for modify_field command. */ 10366 static int 10367 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 10368 const char *str, unsigned int len, void *buf, 10369 unsigned int size) 10370 { 10371 struct rte_flow_action_modify_field *action_modify_field; 10372 unsigned int i; 10373 10374 (void)token; 10375 (void)buf; 10376 (void)size; 10377 if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) 10378 return -1; 10379 for (i = 0; modify_field_ops[i]; ++i) 10380 if (!strcmp_partial(modify_field_ops[i], str, len)) 10381 break; 10382 if (!modify_field_ops[i]) 10383 return -1; 10384 if (!ctx->object) 10385 return len; 10386 action_modify_field = ctx->object; 10387 action_modify_field->operation = (enum rte_flow_modify_op)i; 10388 return len; 10389 } 10390 10391 /** Parse id for modify_field command. */ 10392 static int 10393 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 10394 const char *str, unsigned int len, void *buf, 10395 unsigned int size) 10396 { 10397 struct rte_flow_action_modify_field *action_modify_field; 10398 unsigned int i; 10399 10400 (void)token; 10401 (void)buf; 10402 (void)size; 10403 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 10404 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 10405 return -1; 10406 for (i = 0; flow_field_ids[i]; ++i) 10407 if (!strcmp_partial(flow_field_ids[i], str, len)) 10408 break; 10409 if (!flow_field_ids[i]) 10410 return -1; 10411 if (!ctx->object) 10412 return len; 10413 action_modify_field = ctx->object; 10414 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 10415 action_modify_field->dst.field = (enum rte_flow_field_id)i; 10416 else 10417 action_modify_field->src.field = (enum rte_flow_field_id)i; 10418 return len; 10419 } 10420 10421 /** Parse level for modify_field command. */ 10422 static int 10423 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 10424 const char *str, unsigned int len, void *buf, 10425 unsigned int size) 10426 { 10427 struct rte_flow_action_modify_field *action; 10428 struct flex_item *fp = NULL; 10429 uint32_t val; 10430 struct buffer *out = buf; 10431 char *end; 10432 10433 (void)token; 10434 (void)size; 10435 if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10436 ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) 10437 return -1; 10438 if (!ctx->object) 10439 return len; 10440 action = ctx->object; 10441 errno = 0; 10442 val = strtoumax(str, &end, 0); 10443 if (errno || (size_t)(end - str) != len) 10444 return -1; 10445 /* No need to validate action template mask value */ 10446 if (out->args.vc.masks) { 10447 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) 10448 action->dst.level = val; 10449 else 10450 action->src.level = val; 10451 return len; 10452 } 10453 if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10454 action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || 10455 (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && 10456 action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 10457 if (val >= FLEX_MAX_PARSERS_NUM) { 10458 printf("Bad flex item handle\n"); 10459 return -1; 10460 } 10461 fp = flex_items[ctx->port][val]; 10462 if (!fp) { 10463 printf("Bad flex item handle\n"); 10464 return -1; 10465 } 10466 } 10467 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { 10468 if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) 10469 action->dst.level = val; 10470 else 10471 action->dst.flex_handle = fp->flex_handle; 10472 } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { 10473 if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) 10474 action->src.level = val; 10475 else 10476 action->src.flex_handle = fp->flex_handle; 10477 } 10478 return len; 10479 } 10480 10481 /** Parse the conntrack update, not a rte_flow_action. */ 10482 static int 10483 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 10484 const char *str, unsigned int len, void *buf, 10485 unsigned int size) 10486 { 10487 struct buffer *out = buf; 10488 struct rte_flow_modify_conntrack *ct_modify = NULL; 10489 10490 (void)size; 10491 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 10492 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 10493 return -1; 10494 /* Token name must match. */ 10495 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10496 return -1; 10497 /* Nothing else to do if there is no buffer. */ 10498 if (!out) 10499 return len; 10500 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 10501 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 10502 ct_modify->new_ct.is_original_dir = 10503 conntrack_context.is_original_dir; 10504 ct_modify->direction = 1; 10505 } else { 10506 uint32_t old_dir; 10507 10508 old_dir = ct_modify->new_ct.is_original_dir; 10509 memcpy(&ct_modify->new_ct, &conntrack_context, 10510 sizeof(conntrack_context)); 10511 ct_modify->new_ct.is_original_dir = old_dir; 10512 ct_modify->state = 1; 10513 } 10514 return len; 10515 } 10516 10517 /** Parse tokens for destroy command. */ 10518 static int 10519 parse_destroy(struct context *ctx, const struct token *token, 10520 const char *str, unsigned int len, 10521 void *buf, unsigned int size) 10522 { 10523 struct buffer *out = buf; 10524 10525 /* Token name must match. */ 10526 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10527 return -1; 10528 /* Nothing else to do if there is no buffer. */ 10529 if (!out) 10530 return len; 10531 if (!out->command) { 10532 if (ctx->curr != DESTROY) 10533 return -1; 10534 if (sizeof(*out) > size) 10535 return -1; 10536 out->command = ctx->curr; 10537 ctx->objdata = 0; 10538 ctx->object = out; 10539 ctx->objmask = NULL; 10540 out->args.destroy.rule = 10541 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10542 sizeof(double)); 10543 return len; 10544 } 10545 if (ctx->curr == DESTROY_IS_USER_ID) { 10546 out->args.destroy.is_user_id = true; 10547 return len; 10548 } 10549 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 10550 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 10551 return -1; 10552 ctx->objdata = 0; 10553 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 10554 ctx->objmask = NULL; 10555 return len; 10556 } 10557 10558 /** Parse tokens for flush command. */ 10559 static int 10560 parse_flush(struct context *ctx, const struct token *token, 10561 const char *str, unsigned int len, 10562 void *buf, unsigned int size) 10563 { 10564 struct buffer *out = buf; 10565 10566 /* Token name must match. */ 10567 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10568 return -1; 10569 /* Nothing else to do if there is no buffer. */ 10570 if (!out) 10571 return len; 10572 if (!out->command) { 10573 if (ctx->curr != FLUSH) 10574 return -1; 10575 if (sizeof(*out) > size) 10576 return -1; 10577 out->command = ctx->curr; 10578 ctx->objdata = 0; 10579 ctx->object = out; 10580 ctx->objmask = NULL; 10581 } 10582 return len; 10583 } 10584 10585 /** Parse tokens for dump command. */ 10586 static int 10587 parse_dump(struct context *ctx, const struct token *token, 10588 const char *str, unsigned int len, 10589 void *buf, unsigned int size) 10590 { 10591 struct buffer *out = buf; 10592 10593 /* Token name must match. */ 10594 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10595 return -1; 10596 /* Nothing else to do if there is no buffer. */ 10597 if (!out) 10598 return len; 10599 if (!out->command) { 10600 if (ctx->curr != DUMP) 10601 return -1; 10602 if (sizeof(*out) > size) 10603 return -1; 10604 out->command = ctx->curr; 10605 ctx->objdata = 0; 10606 ctx->object = out; 10607 ctx->objmask = NULL; 10608 return len; 10609 } 10610 switch (ctx->curr) { 10611 case DUMP_ALL: 10612 case DUMP_ONE: 10613 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 10614 out->command = ctx->curr; 10615 ctx->objdata = 0; 10616 ctx->object = out; 10617 ctx->objmask = NULL; 10618 return len; 10619 case DUMP_IS_USER_ID: 10620 out->args.dump.is_user_id = true; 10621 return len; 10622 default: 10623 return -1; 10624 } 10625 } 10626 10627 /** Parse tokens for query command. */ 10628 static int 10629 parse_query(struct context *ctx, const struct token *token, 10630 const char *str, unsigned int len, 10631 void *buf, unsigned int size) 10632 { 10633 struct buffer *out = buf; 10634 10635 /* Token name must match. */ 10636 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10637 return -1; 10638 /* Nothing else to do if there is no buffer. */ 10639 if (!out) 10640 return len; 10641 if (!out->command) { 10642 if (ctx->curr != QUERY) 10643 return -1; 10644 if (sizeof(*out) > size) 10645 return -1; 10646 out->command = ctx->curr; 10647 ctx->objdata = 0; 10648 ctx->object = out; 10649 ctx->objmask = NULL; 10650 } 10651 if (ctx->curr == QUERY_IS_USER_ID) { 10652 out->args.query.is_user_id = true; 10653 return len; 10654 } 10655 return len; 10656 } 10657 10658 /** Parse action names. */ 10659 static int 10660 parse_action(struct context *ctx, const struct token *token, 10661 const char *str, unsigned int len, 10662 void *buf, unsigned int size) 10663 { 10664 struct buffer *out = buf; 10665 const struct arg *arg = pop_args(ctx); 10666 unsigned int i; 10667 10668 (void)size; 10669 /* Argument is expected. */ 10670 if (!arg) 10671 return -1; 10672 /* Parse action name. */ 10673 for (i = 0; next_action[i]; ++i) { 10674 const struct parse_action_priv *priv; 10675 10676 token = &token_list[next_action[i]]; 10677 if (strcmp_partial(token->name, str, len)) 10678 continue; 10679 priv = token->priv; 10680 if (!priv) 10681 goto error; 10682 if (out) 10683 memcpy((uint8_t *)ctx->object + arg->offset, 10684 &priv->type, 10685 arg->size); 10686 return len; 10687 } 10688 error: 10689 push_args(ctx, arg); 10690 return -1; 10691 } 10692 10693 /** Parse tokens for list command. */ 10694 static int 10695 parse_list(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 != LIST) 10709 return -1; 10710 if (sizeof(*out) > size) 10711 return -1; 10712 out->command = ctx->curr; 10713 ctx->objdata = 0; 10714 ctx->object = out; 10715 ctx->objmask = NULL; 10716 out->args.list.group = 10717 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10718 sizeof(double)); 10719 return len; 10720 } 10721 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 10722 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 10723 return -1; 10724 ctx->objdata = 0; 10725 ctx->object = out->args.list.group + out->args.list.group_n++; 10726 ctx->objmask = NULL; 10727 return len; 10728 } 10729 10730 /** Parse tokens for list all aged flows command. */ 10731 static int 10732 parse_aged(struct context *ctx, const struct token *token, 10733 const char *str, unsigned int len, 10734 void *buf, unsigned int size) 10735 { 10736 struct buffer *out = buf; 10737 10738 /* Token name must match. */ 10739 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10740 return -1; 10741 /* Nothing else to do if there is no buffer. */ 10742 if (!out) 10743 return len; 10744 if (!out->command || out->command == QUEUE) { 10745 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 10746 return -1; 10747 if (sizeof(*out) > size) 10748 return -1; 10749 out->command = ctx->curr; 10750 ctx->objdata = 0; 10751 ctx->object = out; 10752 ctx->objmask = NULL; 10753 } 10754 if (ctx->curr == AGED_DESTROY) 10755 out->args.aged.destroy = 1; 10756 return len; 10757 } 10758 10759 /** Parse tokens for isolate command. */ 10760 static int 10761 parse_isolate(struct context *ctx, const struct token *token, 10762 const char *str, unsigned int len, 10763 void *buf, unsigned int size) 10764 { 10765 struct buffer *out = buf; 10766 10767 /* Token name must match. */ 10768 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10769 return -1; 10770 /* Nothing else to do if there is no buffer. */ 10771 if (!out) 10772 return len; 10773 if (!out->command) { 10774 if (ctx->curr != ISOLATE) 10775 return -1; 10776 if (sizeof(*out) > size) 10777 return -1; 10778 out->command = ctx->curr; 10779 ctx->objdata = 0; 10780 ctx->object = out; 10781 ctx->objmask = NULL; 10782 } 10783 return len; 10784 } 10785 10786 /** Parse tokens for info/configure command. */ 10787 static int 10788 parse_configure(struct context *ctx, const struct token *token, 10789 const char *str, unsigned int len, 10790 void *buf, unsigned int size) 10791 { 10792 struct buffer *out = buf; 10793 10794 /* Token name must match. */ 10795 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10796 return -1; 10797 /* Nothing else to do if there is no buffer. */ 10798 if (!out) 10799 return len; 10800 if (!out->command) { 10801 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 10802 return -1; 10803 if (sizeof(*out) > size) 10804 return -1; 10805 out->command = ctx->curr; 10806 ctx->objdata = 0; 10807 ctx->object = out; 10808 ctx->objmask = NULL; 10809 } 10810 return len; 10811 } 10812 10813 /** Parse tokens for template create command. */ 10814 static int 10815 parse_template(struct context *ctx, const struct token *token, 10816 const char *str, unsigned int len, 10817 void *buf, unsigned int size) 10818 { 10819 struct buffer *out = buf; 10820 10821 /* Token name must match. */ 10822 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10823 return -1; 10824 /* Nothing else to do if there is no buffer. */ 10825 if (!out) 10826 return len; 10827 if (!out->command) { 10828 if (ctx->curr != PATTERN_TEMPLATE && 10829 ctx->curr != ACTIONS_TEMPLATE) 10830 return -1; 10831 if (sizeof(*out) > size) 10832 return -1; 10833 out->command = ctx->curr; 10834 ctx->objdata = 0; 10835 ctx->object = out; 10836 ctx->objmask = NULL; 10837 out->args.vc.data = (uint8_t *)out + size; 10838 return len; 10839 } 10840 switch (ctx->curr) { 10841 case PATTERN_TEMPLATE_CREATE: 10842 out->args.vc.pattern = 10843 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10844 sizeof(double)); 10845 out->args.vc.pat_templ_id = UINT32_MAX; 10846 out->command = ctx->curr; 10847 ctx->objdata = 0; 10848 ctx->object = out; 10849 ctx->objmask = NULL; 10850 return len; 10851 case PATTERN_TEMPLATE_EGRESS: 10852 out->args.vc.attr.egress = 1; 10853 return len; 10854 case PATTERN_TEMPLATE_INGRESS: 10855 out->args.vc.attr.ingress = 1; 10856 return len; 10857 case PATTERN_TEMPLATE_TRANSFER: 10858 out->args.vc.attr.transfer = 1; 10859 return len; 10860 case ACTIONS_TEMPLATE_CREATE: 10861 out->args.vc.act_templ_id = UINT32_MAX; 10862 out->command = ctx->curr; 10863 ctx->objdata = 0; 10864 ctx->object = out; 10865 ctx->objmask = NULL; 10866 return len; 10867 case ACTIONS_TEMPLATE_SPEC: 10868 out->args.vc.actions = 10869 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10870 sizeof(double)); 10871 ctx->object = out->args.vc.actions; 10872 ctx->objmask = NULL; 10873 return len; 10874 case ACTIONS_TEMPLATE_MASK: 10875 out->args.vc.masks = 10876 (void *)RTE_ALIGN_CEIL((uintptr_t) 10877 (out->args.vc.actions + 10878 out->args.vc.actions_n), 10879 sizeof(double)); 10880 ctx->object = out->args.vc.masks; 10881 ctx->objmask = NULL; 10882 return len; 10883 case ACTIONS_TEMPLATE_EGRESS: 10884 out->args.vc.attr.egress = 1; 10885 return len; 10886 case ACTIONS_TEMPLATE_INGRESS: 10887 out->args.vc.attr.ingress = 1; 10888 return len; 10889 case ACTIONS_TEMPLATE_TRANSFER: 10890 out->args.vc.attr.transfer = 1; 10891 return len; 10892 default: 10893 return -1; 10894 } 10895 } 10896 10897 /** Parse tokens for template destroy command. */ 10898 static int 10899 parse_template_destroy(struct context *ctx, const struct token *token, 10900 const char *str, unsigned int len, 10901 void *buf, unsigned int size) 10902 { 10903 struct buffer *out = buf; 10904 uint32_t *template_id; 10905 10906 /* Token name must match. */ 10907 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10908 return -1; 10909 /* Nothing else to do if there is no buffer. */ 10910 if (!out) 10911 return len; 10912 if (!out->command || 10913 out->command == PATTERN_TEMPLATE || 10914 out->command == ACTIONS_TEMPLATE) { 10915 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 10916 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 10917 return -1; 10918 if (sizeof(*out) > size) 10919 return -1; 10920 out->command = ctx->curr; 10921 ctx->objdata = 0; 10922 ctx->object = out; 10923 ctx->objmask = NULL; 10924 out->args.templ_destroy.template_id = 10925 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10926 sizeof(double)); 10927 return len; 10928 } 10929 template_id = out->args.templ_destroy.template_id 10930 + out->args.templ_destroy.template_id_n++; 10931 if ((uint8_t *)template_id > (uint8_t *)out + size) 10932 return -1; 10933 ctx->objdata = 0; 10934 ctx->object = template_id; 10935 ctx->objmask = NULL; 10936 return len; 10937 } 10938 10939 /** Parse tokens for table create command. */ 10940 static int 10941 parse_table(struct context *ctx, const struct token *token, 10942 const char *str, unsigned int len, 10943 void *buf, unsigned int size) 10944 { 10945 struct buffer *out = buf; 10946 uint32_t *template_id; 10947 10948 /* Token name must match. */ 10949 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10950 return -1; 10951 /* Nothing else to do if there is no buffer. */ 10952 if (!out) 10953 return len; 10954 if (!out->command) { 10955 if (ctx->curr != TABLE) 10956 return -1; 10957 if (sizeof(*out) > size) 10958 return -1; 10959 out->command = ctx->curr; 10960 ctx->objdata = 0; 10961 ctx->object = out; 10962 ctx->objmask = NULL; 10963 return len; 10964 } 10965 switch (ctx->curr) { 10966 case TABLE_CREATE: 10967 case TABLE_RESIZE: 10968 out->command = ctx->curr; 10969 ctx->objdata = 0; 10970 ctx->object = out; 10971 ctx->objmask = NULL; 10972 out->args.table.id = UINT32_MAX; 10973 return len; 10974 case TABLE_PATTERN_TEMPLATE: 10975 out->args.table.pat_templ_id = 10976 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10977 sizeof(double)); 10978 template_id = out->args.table.pat_templ_id 10979 + out->args.table.pat_templ_id_n++; 10980 if ((uint8_t *)template_id > (uint8_t *)out + size) 10981 return -1; 10982 ctx->objdata = 0; 10983 ctx->object = template_id; 10984 ctx->objmask = NULL; 10985 return len; 10986 case TABLE_ACTIONS_TEMPLATE: 10987 out->args.table.act_templ_id = 10988 (void *)RTE_ALIGN_CEIL((uintptr_t) 10989 (out->args.table.pat_templ_id + 10990 out->args.table.pat_templ_id_n), 10991 sizeof(double)); 10992 template_id = out->args.table.act_templ_id 10993 + out->args.table.act_templ_id_n++; 10994 if ((uint8_t *)template_id > (uint8_t *)out + size) 10995 return -1; 10996 ctx->objdata = 0; 10997 ctx->object = template_id; 10998 ctx->objmask = NULL; 10999 return len; 11000 case TABLE_INGRESS: 11001 out->args.table.attr.flow_attr.ingress = 1; 11002 return len; 11003 case TABLE_EGRESS: 11004 out->args.table.attr.flow_attr.egress = 1; 11005 return len; 11006 case TABLE_TRANSFER: 11007 out->args.table.attr.flow_attr.transfer = 1; 11008 return len; 11009 case TABLE_TRANSFER_WIRE_ORIG: 11010 if (!out->args.table.attr.flow_attr.transfer) 11011 return -1; 11012 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; 11013 return len; 11014 case TABLE_TRANSFER_VPORT_ORIG: 11015 if (!out->args.table.attr.flow_attr.transfer) 11016 return -1; 11017 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; 11018 return len; 11019 case TABLE_RESIZABLE: 11020 out->args.table.attr.specialize |= 11021 RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE; 11022 return len; 11023 case TABLE_RULES_NUMBER: 11024 ctx->objdata = 0; 11025 ctx->object = out; 11026 ctx->objmask = NULL; 11027 return len; 11028 case TABLE_RESIZE_ID: 11029 case TABLE_RESIZE_RULES_NUMBER: 11030 return len; 11031 default: 11032 return -1; 11033 } 11034 } 11035 11036 /** Parse tokens for table destroy command. */ 11037 static int 11038 parse_table_destroy(struct context *ctx, const struct token *token, 11039 const char *str, unsigned int len, 11040 void *buf, unsigned int size) 11041 { 11042 struct buffer *out = buf; 11043 uint32_t *table_id; 11044 11045 /* Token name must match. */ 11046 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11047 return -1; 11048 /* Nothing else to do if there is no buffer. */ 11049 if (!out) 11050 return len; 11051 if (!out->command || out->command == TABLE) { 11052 if (ctx->curr != TABLE_DESTROY && 11053 ctx->curr != TABLE_RESIZE_COMPLETE) 11054 return -1; 11055 if (sizeof(*out) > size) 11056 return -1; 11057 out->command = ctx->curr; 11058 ctx->objdata = 0; 11059 ctx->object = out; 11060 ctx->objmask = NULL; 11061 out->args.table_destroy.table_id = 11062 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11063 sizeof(double)); 11064 return len; 11065 } 11066 table_id = out->args.table_destroy.table_id 11067 + out->args.table_destroy.table_id_n++; 11068 if ((uint8_t *)table_id > (uint8_t *)out + size) 11069 return -1; 11070 ctx->objdata = 0; 11071 ctx->object = table_id; 11072 ctx->objmask = NULL; 11073 return len; 11074 } 11075 11076 /** Parse tokens for queue create commands. */ 11077 static int 11078 parse_qo(struct context *ctx, const struct token *token, 11079 const char *str, unsigned int len, 11080 void *buf, unsigned int size) 11081 { 11082 struct buffer *out = buf; 11083 11084 /* Token name must match. */ 11085 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11086 return -1; 11087 /* Nothing else to do if there is no buffer. */ 11088 if (!out) 11089 return len; 11090 if (!out->command) { 11091 if (ctx->curr != QUEUE) 11092 return -1; 11093 if (sizeof(*out) > size) 11094 return -1; 11095 out->command = ctx->curr; 11096 ctx->objdata = 0; 11097 ctx->object = out; 11098 ctx->objmask = NULL; 11099 out->args.vc.data = (uint8_t *)out + size; 11100 return len; 11101 } 11102 switch (ctx->curr) { 11103 case QUEUE_CREATE: 11104 case QUEUE_UPDATE: 11105 out->command = ctx->curr; 11106 ctx->objdata = 0; 11107 ctx->object = out; 11108 ctx->objmask = NULL; 11109 out->args.vc.rule_id = UINT32_MAX; 11110 return len; 11111 case QUEUE_TEMPLATE_TABLE: 11112 case QUEUE_PATTERN_TEMPLATE: 11113 case QUEUE_ACTIONS_TEMPLATE: 11114 case QUEUE_CREATE_POSTPONE: 11115 case QUEUE_RULE_ID: 11116 case QUEUE_UPDATE_ID: 11117 return len; 11118 case ITEM_PATTERN: 11119 out->args.vc.pattern = 11120 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11121 sizeof(double)); 11122 ctx->object = out->args.vc.pattern; 11123 ctx->objmask = NULL; 11124 return len; 11125 case ACTIONS: 11126 out->args.vc.actions = 11127 (void *)RTE_ALIGN_CEIL((uintptr_t) 11128 (out->args.vc.pattern + 11129 out->args.vc.pattern_n), 11130 sizeof(double)); 11131 ctx->object = out->args.vc.actions; 11132 ctx->objmask = NULL; 11133 return len; 11134 default: 11135 return -1; 11136 } 11137 } 11138 11139 /** Parse tokens for queue destroy command. */ 11140 static int 11141 parse_qo_destroy(struct context *ctx, const struct token *token, 11142 const char *str, unsigned int len, 11143 void *buf, unsigned int size) 11144 { 11145 struct buffer *out = buf; 11146 uint64_t *flow_id; 11147 11148 /* Token name must match. */ 11149 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11150 return -1; 11151 /* Nothing else to do if there is no buffer. */ 11152 if (!out) 11153 return len; 11154 if (!out->command || out->command == QUEUE) { 11155 if (ctx->curr != QUEUE_DESTROY && 11156 ctx->curr != QUEUE_FLOW_UPDATE_RESIZED) 11157 return -1; 11158 if (sizeof(*out) > size) 11159 return -1; 11160 out->command = ctx->curr; 11161 ctx->objdata = 0; 11162 ctx->object = out; 11163 ctx->objmask = NULL; 11164 out->args.destroy.rule = 11165 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11166 sizeof(double)); 11167 return len; 11168 } 11169 switch (ctx->curr) { 11170 case QUEUE_DESTROY_ID: 11171 flow_id = out->args.destroy.rule 11172 + out->args.destroy.rule_n++; 11173 if ((uint8_t *)flow_id > (uint8_t *)out + size) 11174 return -1; 11175 ctx->objdata = 0; 11176 ctx->object = flow_id; 11177 ctx->objmask = NULL; 11178 return len; 11179 case QUEUE_DESTROY_POSTPONE: 11180 return len; 11181 default: 11182 return -1; 11183 } 11184 } 11185 11186 /** Parse tokens for push queue command. */ 11187 static int 11188 parse_push(struct context *ctx, const struct token *token, 11189 const char *str, unsigned int len, 11190 void *buf, unsigned int size) 11191 { 11192 struct buffer *out = buf; 11193 11194 /* Token name must match. */ 11195 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11196 return -1; 11197 /* Nothing else to do if there is no buffer. */ 11198 if (!out) 11199 return len; 11200 if (!out->command) { 11201 if (ctx->curr != PUSH) 11202 return -1; 11203 if (sizeof(*out) > size) 11204 return -1; 11205 out->command = ctx->curr; 11206 ctx->objdata = 0; 11207 ctx->object = out; 11208 ctx->objmask = NULL; 11209 out->args.vc.data = (uint8_t *)out + size; 11210 } 11211 return len; 11212 } 11213 11214 /** Parse tokens for pull command. */ 11215 static int 11216 parse_pull(struct context *ctx, const struct token *token, 11217 const char *str, unsigned int len, 11218 void *buf, unsigned int size) 11219 { 11220 struct buffer *out = buf; 11221 11222 /* Token name must match. */ 11223 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11224 return -1; 11225 /* Nothing else to do if there is no buffer. */ 11226 if (!out) 11227 return len; 11228 if (!out->command) { 11229 if (ctx->curr != PULL) 11230 return -1; 11231 if (sizeof(*out) > size) 11232 return -1; 11233 out->command = ctx->curr; 11234 ctx->objdata = 0; 11235 ctx->object = out; 11236 ctx->objmask = NULL; 11237 out->args.vc.data = (uint8_t *)out + size; 11238 } 11239 return len; 11240 } 11241 11242 /** Parse tokens for hash calculation commands. */ 11243 static int 11244 parse_hash(struct context *ctx, const struct token *token, 11245 const char *str, unsigned int len, 11246 void *buf, unsigned int size) 11247 { 11248 struct buffer *out = buf; 11249 11250 /* Token name must match. */ 11251 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11252 return -1; 11253 /* Nothing else to do if there is no buffer. */ 11254 if (!out) 11255 return len; 11256 if (!out->command) { 11257 if (ctx->curr != HASH) 11258 return -1; 11259 if (sizeof(*out) > size) 11260 return -1; 11261 out->command = ctx->curr; 11262 ctx->objdata = 0; 11263 ctx->object = out; 11264 ctx->objmask = NULL; 11265 out->args.vc.data = (uint8_t *)out + size; 11266 return len; 11267 } 11268 switch (ctx->curr) { 11269 case HASH_CALC_TABLE: 11270 case HASH_CALC_PATTERN_INDEX: 11271 return len; 11272 case ITEM_PATTERN: 11273 out->args.vc.pattern = 11274 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11275 sizeof(double)); 11276 ctx->object = out->args.vc.pattern; 11277 ctx->objmask = NULL; 11278 return len; 11279 case HASH_CALC_ENCAP: 11280 out->args.vc.encap_hash = 1; 11281 return len; 11282 case ENCAP_HASH_FIELD_SRC_PORT: 11283 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT; 11284 return len; 11285 case ENCAP_HASH_FIELD_GRE_FLOW_ID: 11286 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID; 11287 return len; 11288 default: 11289 return -1; 11290 } 11291 } 11292 11293 static int 11294 parse_group(struct context *ctx, const struct token *token, 11295 const char *str, unsigned int len, 11296 void *buf, unsigned int size) 11297 { 11298 struct buffer *out = buf; 11299 11300 /* Token name must match. */ 11301 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11302 return -1; 11303 /* Nothing else to do if there is no buffer. */ 11304 if (!out) 11305 return len; 11306 if (!out->command) { 11307 if (ctx->curr != FLOW_GROUP) 11308 return -1; 11309 if (sizeof(*out) > size) 11310 return -1; 11311 out->command = ctx->curr; 11312 ctx->objdata = 0; 11313 ctx->object = out; 11314 ctx->objmask = NULL; 11315 out->args.vc.data = (uint8_t *)out + size; 11316 return len; 11317 } 11318 switch (ctx->curr) { 11319 case GROUP_INGRESS: 11320 out->args.vc.attr.ingress = 1; 11321 return len; 11322 case GROUP_EGRESS: 11323 out->args.vc.attr.egress = 1; 11324 return len; 11325 case GROUP_TRANSFER: 11326 out->args.vc.attr.transfer = 1; 11327 return len; 11328 case GROUP_SET_MISS_ACTIONS: 11329 out->command = ctx->curr; 11330 ctx->objdata = 0; 11331 ctx->object = out; 11332 ctx->objmask = NULL; 11333 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11334 sizeof(double)); 11335 return len; 11336 default: 11337 return -1; 11338 } 11339 } 11340 11341 static int 11342 parse_flex(struct context *ctx, const struct token *token, 11343 const char *str, unsigned int len, 11344 void *buf, unsigned int size) 11345 { 11346 struct buffer *out = buf; 11347 11348 /* Token name must match. */ 11349 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11350 return -1; 11351 /* Nothing else to do if there is no buffer. */ 11352 if (!out) 11353 return len; 11354 if (out->command == ZERO) { 11355 if (ctx->curr != FLEX) 11356 return -1; 11357 if (sizeof(*out) > size) 11358 return -1; 11359 out->command = ctx->curr; 11360 ctx->objdata = 0; 11361 ctx->object = out; 11362 ctx->objmask = NULL; 11363 } else { 11364 switch (ctx->curr) { 11365 default: 11366 break; 11367 case FLEX_ITEM_INIT: 11368 case FLEX_ITEM_CREATE: 11369 case FLEX_ITEM_DESTROY: 11370 out->command = ctx->curr; 11371 break; 11372 } 11373 } 11374 11375 return len; 11376 } 11377 11378 static int 11379 parse_tunnel(struct context *ctx, const struct token *token, 11380 const char *str, unsigned int len, 11381 void *buf, unsigned int size) 11382 { 11383 struct buffer *out = buf; 11384 11385 /* Token name must match. */ 11386 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11387 return -1; 11388 /* Nothing else to do if there is no buffer. */ 11389 if (!out) 11390 return len; 11391 if (!out->command) { 11392 if (ctx->curr != TUNNEL) 11393 return -1; 11394 if (sizeof(*out) > size) 11395 return -1; 11396 out->command = ctx->curr; 11397 ctx->objdata = 0; 11398 ctx->object = out; 11399 ctx->objmask = NULL; 11400 } else { 11401 switch (ctx->curr) { 11402 default: 11403 break; 11404 case TUNNEL_CREATE: 11405 case TUNNEL_DESTROY: 11406 case TUNNEL_LIST: 11407 out->command = ctx->curr; 11408 break; 11409 case TUNNEL_CREATE_TYPE: 11410 case TUNNEL_DESTROY_ID: 11411 ctx->object = &out->args.vc.tunnel_ops; 11412 break; 11413 } 11414 } 11415 11416 return len; 11417 } 11418 11419 /** 11420 * Parse signed/unsigned integers 8 to 64-bit long. 11421 * 11422 * Last argument (ctx->args) is retrieved to determine integer type and 11423 * storage location. 11424 */ 11425 static int 11426 parse_int(struct context *ctx, const struct token *token, 11427 const char *str, unsigned int len, 11428 void *buf, unsigned int size) 11429 { 11430 const struct arg *arg = pop_args(ctx); 11431 uintmax_t u; 11432 char *end; 11433 11434 (void)token; 11435 /* Argument is expected. */ 11436 if (!arg) 11437 return -1; 11438 errno = 0; 11439 u = arg->sign ? 11440 (uintmax_t)strtoimax(str, &end, 0) : 11441 strtoumax(str, &end, 0); 11442 if (errno || (size_t)(end - str) != len) 11443 goto error; 11444 if (arg->bounded && 11445 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 11446 (intmax_t)u > (intmax_t)arg->max)) || 11447 (!arg->sign && (u < arg->min || u > arg->max)))) 11448 goto error; 11449 if (!ctx->object) 11450 return len; 11451 if (arg->mask) { 11452 if (!arg_entry_bf_fill(ctx->object, u, arg) || 11453 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 11454 goto error; 11455 return len; 11456 } 11457 buf = (uint8_t *)ctx->object + arg->offset; 11458 size = arg->size; 11459 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 11460 return -1; 11461 objmask: 11462 switch (size) { 11463 case sizeof(uint8_t): 11464 *(uint8_t *)buf = u; 11465 break; 11466 case sizeof(uint16_t): 11467 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 11468 break; 11469 case sizeof(uint8_t [3]): 11470 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 11471 if (!arg->hton) { 11472 ((uint8_t *)buf)[0] = u; 11473 ((uint8_t *)buf)[1] = u >> 8; 11474 ((uint8_t *)buf)[2] = u >> 16; 11475 break; 11476 } 11477 #endif 11478 ((uint8_t *)buf)[0] = u >> 16; 11479 ((uint8_t *)buf)[1] = u >> 8; 11480 ((uint8_t *)buf)[2] = u; 11481 break; 11482 case sizeof(uint32_t): 11483 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 11484 break; 11485 case sizeof(uint64_t): 11486 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 11487 break; 11488 default: 11489 goto error; 11490 } 11491 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 11492 u = -1; 11493 buf = (uint8_t *)ctx->objmask + arg->offset; 11494 goto objmask; 11495 } 11496 return len; 11497 error: 11498 push_args(ctx, arg); 11499 return -1; 11500 } 11501 11502 /** 11503 * Parse a string. 11504 * 11505 * Three arguments (ctx->args) are retrieved from the stack to store data, 11506 * its actual length and address (in that order). 11507 */ 11508 static int 11509 parse_string(struct context *ctx, const struct token *token, 11510 const char *str, unsigned int len, 11511 void *buf, unsigned int size) 11512 { 11513 const struct arg *arg_data = pop_args(ctx); 11514 const struct arg *arg_len = pop_args(ctx); 11515 const struct arg *arg_addr = pop_args(ctx); 11516 char tmp[16]; /* Ought to be enough. */ 11517 int ret; 11518 11519 /* Arguments are expected. */ 11520 if (!arg_data) 11521 return -1; 11522 if (!arg_len) { 11523 push_args(ctx, arg_data); 11524 return -1; 11525 } 11526 if (!arg_addr) { 11527 push_args(ctx, arg_len); 11528 push_args(ctx, arg_data); 11529 return -1; 11530 } 11531 size = arg_data->size; 11532 /* Bit-mask fill is not supported. */ 11533 if (arg_data->mask || size < len) 11534 goto error; 11535 if (!ctx->object) 11536 return len; 11537 /* Let parse_int() fill length information first. */ 11538 ret = snprintf(tmp, sizeof(tmp), "%u", len); 11539 if (ret < 0) 11540 goto error; 11541 push_args(ctx, arg_len); 11542 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11543 if (ret < 0) { 11544 pop_args(ctx); 11545 goto error; 11546 } 11547 buf = (uint8_t *)ctx->object + arg_data->offset; 11548 /* Output buffer is not necessarily NUL-terminated. */ 11549 memcpy(buf, str, len); 11550 memset((uint8_t *)buf + len, 0x00, size - len); 11551 if (ctx->objmask) 11552 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11553 /* Save address if requested. */ 11554 if (arg_addr->size) { 11555 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11556 (void *[]){ 11557 (uint8_t *)ctx->object + arg_data->offset 11558 }, 11559 arg_addr->size); 11560 if (ctx->objmask) 11561 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11562 (void *[]){ 11563 (uint8_t *)ctx->objmask + arg_data->offset 11564 }, 11565 arg_addr->size); 11566 } 11567 return len; 11568 error: 11569 push_args(ctx, arg_addr); 11570 push_args(ctx, arg_len); 11571 push_args(ctx, arg_data); 11572 return -1; 11573 } 11574 11575 static int 11576 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 11577 { 11578 const uint8_t *head = dst; 11579 uint32_t left; 11580 11581 if (*size == 0) 11582 return -1; 11583 11584 left = *size; 11585 11586 /* Convert chars to bytes */ 11587 while (left) { 11588 char tmp[3], *end = tmp; 11589 uint32_t read_lim = left & 1 ? 1 : 2; 11590 11591 snprintf(tmp, read_lim + 1, "%s", src); 11592 *dst = strtoul(tmp, &end, 16); 11593 if (*end) { 11594 *dst = 0; 11595 *size = (uint32_t)(dst - head); 11596 return -1; 11597 } 11598 left -= read_lim; 11599 src += read_lim; 11600 dst++; 11601 } 11602 *dst = 0; 11603 *size = (uint32_t)(dst - head); 11604 return 0; 11605 } 11606 11607 static int 11608 parse_hex(struct context *ctx, const struct token *token, 11609 const char *str, unsigned int len, 11610 void *buf, unsigned int size) 11611 { 11612 const struct arg *arg_data = pop_args(ctx); 11613 const struct arg *arg_len = pop_args(ctx); 11614 const struct arg *arg_addr = pop_args(ctx); 11615 char tmp[16]; /* Ought to be enough. */ 11616 int ret; 11617 unsigned int hexlen = len; 11618 unsigned int length = 256; 11619 uint8_t hex_tmp[length]; 11620 11621 /* Arguments are expected. */ 11622 if (!arg_data) 11623 return -1; 11624 if (!arg_len) { 11625 push_args(ctx, arg_data); 11626 return -1; 11627 } 11628 if (!arg_addr) { 11629 push_args(ctx, arg_len); 11630 push_args(ctx, arg_data); 11631 return -1; 11632 } 11633 size = arg_data->size; 11634 /* Bit-mask fill is not supported. */ 11635 if (arg_data->mask) 11636 goto error; 11637 if (!ctx->object) 11638 return len; 11639 11640 /* translate bytes string to array. */ 11641 if (str[0] == '0' && ((str[1] == 'x') || 11642 (str[1] == 'X'))) { 11643 str += 2; 11644 hexlen -= 2; 11645 } 11646 if (hexlen > length) 11647 goto error; 11648 ret = parse_hex_string(str, hex_tmp, &hexlen); 11649 if (ret < 0) 11650 goto error; 11651 /* Check the converted binary fits into data buffer. */ 11652 if (hexlen > size) 11653 goto error; 11654 /* Let parse_int() fill length information first. */ 11655 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 11656 if (ret < 0) 11657 goto error; 11658 /* Save length if requested. */ 11659 if (arg_len->size) { 11660 push_args(ctx, arg_len); 11661 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11662 if (ret < 0) { 11663 pop_args(ctx); 11664 goto error; 11665 } 11666 } 11667 buf = (uint8_t *)ctx->object + arg_data->offset; 11668 /* Output buffer is not necessarily NUL-terminated. */ 11669 memcpy(buf, hex_tmp, hexlen); 11670 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 11671 if (ctx->objmask) 11672 memset((uint8_t *)ctx->objmask + arg_data->offset, 11673 0xff, hexlen); 11674 /* Save address if requested. */ 11675 if (arg_addr->size) { 11676 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11677 (void *[]){ 11678 (uint8_t *)ctx->object + arg_data->offset 11679 }, 11680 arg_addr->size); 11681 if (ctx->objmask) 11682 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11683 (void *[]){ 11684 (uint8_t *)ctx->objmask + arg_data->offset 11685 }, 11686 arg_addr->size); 11687 } 11688 return len; 11689 error: 11690 push_args(ctx, arg_addr); 11691 push_args(ctx, arg_len); 11692 push_args(ctx, arg_data); 11693 return -1; 11694 11695 } 11696 11697 /** 11698 * Parse a zero-ended string. 11699 */ 11700 static int 11701 parse_string0(struct context *ctx, const struct token *token __rte_unused, 11702 const char *str, unsigned int len, 11703 void *buf, unsigned int size) 11704 { 11705 const struct arg *arg_data = pop_args(ctx); 11706 11707 /* Arguments are expected. */ 11708 if (!arg_data) 11709 return -1; 11710 size = arg_data->size; 11711 /* Bit-mask fill is not supported. */ 11712 if (arg_data->mask || size < len + 1) 11713 goto error; 11714 if (!ctx->object) 11715 return len; 11716 buf = (uint8_t *)ctx->object + arg_data->offset; 11717 strncpy(buf, str, len); 11718 if (ctx->objmask) 11719 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11720 return len; 11721 error: 11722 push_args(ctx, arg_data); 11723 return -1; 11724 } 11725 11726 /** 11727 * Parse a MAC address. 11728 * 11729 * Last argument (ctx->args) is retrieved to determine storage size and 11730 * location. 11731 */ 11732 static int 11733 parse_mac_addr(struct context *ctx, const struct token *token, 11734 const char *str, unsigned int len, 11735 void *buf, unsigned int size) 11736 { 11737 const struct arg *arg = pop_args(ctx); 11738 struct rte_ether_addr tmp; 11739 int ret; 11740 11741 (void)token; 11742 /* Argument is expected. */ 11743 if (!arg) 11744 return -1; 11745 size = arg->size; 11746 /* Bit-mask fill is not supported. */ 11747 if (arg->mask || size != sizeof(tmp)) 11748 goto error; 11749 /* Only network endian is supported. */ 11750 if (!arg->hton) 11751 goto error; 11752 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 11753 if (ret < 0 || (unsigned int)ret != len) 11754 goto error; 11755 if (!ctx->object) 11756 return len; 11757 buf = (uint8_t *)ctx->object + arg->offset; 11758 memcpy(buf, &tmp, size); 11759 if (ctx->objmask) 11760 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11761 return len; 11762 error: 11763 push_args(ctx, arg); 11764 return -1; 11765 } 11766 11767 /** 11768 * Parse an IPv4 address. 11769 * 11770 * Last argument (ctx->args) is retrieved to determine storage size and 11771 * location. 11772 */ 11773 static int 11774 parse_ipv4_addr(struct context *ctx, const struct token *token, 11775 const char *str, unsigned int len, 11776 void *buf, unsigned int size) 11777 { 11778 const struct arg *arg = pop_args(ctx); 11779 char str2[len + 1]; 11780 struct in_addr tmp; 11781 int ret; 11782 11783 /* Argument is expected. */ 11784 if (!arg) 11785 return -1; 11786 size = arg->size; 11787 /* Bit-mask fill is not supported. */ 11788 if (arg->mask || size != sizeof(tmp)) 11789 goto error; 11790 /* Only network endian is supported. */ 11791 if (!arg->hton) 11792 goto error; 11793 memcpy(str2, str, len); 11794 str2[len] = '\0'; 11795 ret = inet_pton(AF_INET, str2, &tmp); 11796 if (ret != 1) { 11797 /* Attempt integer parsing. */ 11798 push_args(ctx, arg); 11799 return parse_int(ctx, token, str, len, buf, size); 11800 } 11801 if (!ctx->object) 11802 return len; 11803 buf = (uint8_t *)ctx->object + arg->offset; 11804 memcpy(buf, &tmp, size); 11805 if (ctx->objmask) 11806 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11807 return len; 11808 error: 11809 push_args(ctx, arg); 11810 return -1; 11811 } 11812 11813 /** 11814 * Parse an IPv6 address. 11815 * 11816 * Last argument (ctx->args) is retrieved to determine storage size and 11817 * location. 11818 */ 11819 static int 11820 parse_ipv6_addr(struct context *ctx, const struct token *token, 11821 const char *str, unsigned int len, 11822 void *buf, unsigned int size) 11823 { 11824 const struct arg *arg = pop_args(ctx); 11825 char str2[len + 1]; 11826 struct in6_addr tmp; 11827 int ret; 11828 11829 (void)token; 11830 /* Argument is expected. */ 11831 if (!arg) 11832 return -1; 11833 size = arg->size; 11834 /* Bit-mask fill is not supported. */ 11835 if (arg->mask || size != sizeof(tmp)) 11836 goto error; 11837 /* Only network endian is supported. */ 11838 if (!arg->hton) 11839 goto error; 11840 memcpy(str2, str, len); 11841 str2[len] = '\0'; 11842 ret = inet_pton(AF_INET6, str2, &tmp); 11843 if (ret != 1) 11844 goto error; 11845 if (!ctx->object) 11846 return len; 11847 buf = (uint8_t *)ctx->object + arg->offset; 11848 memcpy(buf, &tmp, size); 11849 if (ctx->objmask) 11850 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11851 return len; 11852 error: 11853 push_args(ctx, arg); 11854 return -1; 11855 } 11856 11857 /** Boolean values (even indices stand for false). */ 11858 static const char *const boolean_name[] = { 11859 "0", "1", 11860 "false", "true", 11861 "no", "yes", 11862 "N", "Y", 11863 "off", "on", 11864 NULL, 11865 }; 11866 11867 /** 11868 * Parse a boolean value. 11869 * 11870 * Last argument (ctx->args) is retrieved to determine storage size and 11871 * location. 11872 */ 11873 static int 11874 parse_boolean(struct context *ctx, const struct token *token, 11875 const char *str, unsigned int len, 11876 void *buf, unsigned int size) 11877 { 11878 const struct arg *arg = pop_args(ctx); 11879 unsigned int i; 11880 int ret; 11881 11882 /* Argument is expected. */ 11883 if (!arg) 11884 return -1; 11885 for (i = 0; boolean_name[i]; ++i) 11886 if (!strcmp_partial(boolean_name[i], str, len)) 11887 break; 11888 /* Process token as integer. */ 11889 if (boolean_name[i]) 11890 str = i & 1 ? "1" : "0"; 11891 push_args(ctx, arg); 11892 ret = parse_int(ctx, token, str, strlen(str), buf, size); 11893 return ret > 0 ? (int)len : ret; 11894 } 11895 11896 /** Parse port and update context. */ 11897 static int 11898 parse_port(struct context *ctx, const struct token *token, 11899 const char *str, unsigned int len, 11900 void *buf, unsigned int size) 11901 { 11902 struct buffer *out = &(struct buffer){ .port = 0 }; 11903 int ret; 11904 11905 if (buf) 11906 out = buf; 11907 else { 11908 ctx->objdata = 0; 11909 ctx->object = out; 11910 ctx->objmask = NULL; 11911 size = sizeof(*out); 11912 } 11913 ret = parse_int(ctx, token, str, len, out, size); 11914 if (ret >= 0) 11915 ctx->port = out->port; 11916 if (!buf) 11917 ctx->object = NULL; 11918 return ret; 11919 } 11920 11921 /** Parse tokens for shared indirect actions. */ 11922 static int 11923 parse_ia_port(struct context *ctx, const struct token *token, 11924 const char *str, unsigned int len, 11925 void *buf, unsigned int size) 11926 { 11927 struct rte_flow_action *action = ctx->object; 11928 uint32_t id; 11929 int ret; 11930 11931 (void)buf; 11932 (void)size; 11933 ctx->objdata = 0; 11934 ctx->object = &id; 11935 ctx->objmask = NULL; 11936 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11937 ctx->object = action; 11938 if (ret != (int)len) 11939 return ret; 11940 /* set indirect action */ 11941 if (action) 11942 action->conf = (void *)(uintptr_t)id; 11943 return ret; 11944 } 11945 11946 static int 11947 parse_ia_id2ptr(struct context *ctx, const struct token *token, 11948 const char *str, unsigned int len, 11949 void *buf, unsigned int size) 11950 { 11951 struct rte_flow_action *action = ctx->object; 11952 uint32_t id; 11953 int ret; 11954 11955 (void)buf; 11956 (void)size; 11957 ctx->objdata = 0; 11958 ctx->object = &id; 11959 ctx->objmask = NULL; 11960 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11961 ctx->object = action; 11962 if (ret != (int)len) 11963 return ret; 11964 /* set indirect action */ 11965 if (action) { 11966 portid_t port_id = ctx->port; 11967 if (ctx->prev == INDIRECT_ACTION_PORT) 11968 port_id = (portid_t)(uintptr_t)action->conf; 11969 action->conf = port_action_handle_get_by_id(port_id, id); 11970 ret = (action->conf) ? ret : -1; 11971 } 11972 return ret; 11973 } 11974 11975 static int 11976 parse_indlst_id2ptr(struct context *ctx, const struct token *token, 11977 const char *str, unsigned int len, 11978 __rte_unused void *buf, __rte_unused unsigned int size) 11979 { 11980 struct rte_flow_action *action = ctx->object; 11981 struct rte_flow_action_indirect_list *action_conf; 11982 const struct indlst_conf *indlst_conf; 11983 uint32_t id; 11984 int ret; 11985 11986 ctx->objdata = 0; 11987 ctx->object = &id; 11988 ctx->objmask = NULL; 11989 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11990 ctx->object = action; 11991 if (ret != (int)len) 11992 return ret; 11993 11994 /* set handle and conf */ 11995 if (action) { 11996 action_conf = (void *)(uintptr_t)action->conf; 11997 action_conf->conf = NULL; 11998 switch (ctx->curr) { 11999 case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: 12000 action_conf->handle = (typeof(action_conf->handle)) 12001 port_action_handle_get_by_id(ctx->port, id); 12002 if (!action_conf->handle) { 12003 printf("no indirect list handle for id %u\n", id); 12004 return -1; 12005 } 12006 break; 12007 case INDIRECT_LIST_ACTION_ID2PTR_CONF: 12008 indlst_conf = indirect_action_list_conf_get(id); 12009 if (!indlst_conf) 12010 return -1; 12011 action_conf->conf = (const void **)indlst_conf->conf; 12012 break; 12013 default: 12014 break; 12015 } 12016 } 12017 return ret; 12018 } 12019 12020 static int 12021 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 12022 const char *str, unsigned int len, 12023 void *buf, unsigned int size) 12024 { 12025 struct rte_flow_action *action = ctx->object; 12026 struct rte_flow_action_meter_mark *meter; 12027 struct rte_flow_meter_profile *profile = NULL; 12028 uint32_t id = 0; 12029 int ret; 12030 12031 (void)buf; 12032 (void)size; 12033 ctx->objdata = 0; 12034 ctx->object = &id; 12035 ctx->objmask = NULL; 12036 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12037 ctx->object = action; 12038 if (ret != (int)len) 12039 return ret; 12040 /* set meter profile */ 12041 if (action) { 12042 meter = (struct rte_flow_action_meter_mark *) 12043 (uintptr_t)(action->conf); 12044 profile = port_meter_profile_get_by_id(ctx->port, id); 12045 meter->profile = profile; 12046 ret = (profile) ? ret : -1; 12047 } 12048 return ret; 12049 } 12050 12051 static int 12052 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 12053 const char *str, unsigned int len, 12054 void *buf, unsigned int size) 12055 { 12056 struct rte_flow_action *action = ctx->object; 12057 struct rte_flow_action_meter_mark *meter; 12058 struct rte_flow_meter_policy *policy = NULL; 12059 uint32_t id = 0; 12060 int ret; 12061 12062 (void)buf; 12063 (void)size; 12064 ctx->objdata = 0; 12065 ctx->object = &id; 12066 ctx->objmask = NULL; 12067 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12068 ctx->object = action; 12069 if (ret != (int)len) 12070 return ret; 12071 /* set meter policy */ 12072 if (action) { 12073 meter = (struct rte_flow_action_meter_mark *) 12074 (uintptr_t)(action->conf); 12075 policy = port_meter_policy_get_by_id(ctx->port, id); 12076 meter->policy = policy; 12077 ret = (policy) ? ret : -1; 12078 } 12079 return ret; 12080 } 12081 12082 /** Parse set command, initialize output buffer for subsequent tokens. */ 12083 static int 12084 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 12085 const char *str, unsigned int len, 12086 void *buf, unsigned int size) 12087 { 12088 struct buffer *out = buf; 12089 12090 /* Token name must match. */ 12091 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12092 return -1; 12093 /* Nothing else to do if there is no buffer. */ 12094 if (!out) 12095 return len; 12096 /* Make sure buffer is large enough. */ 12097 if (size < sizeof(*out)) 12098 return -1; 12099 ctx->objdata = 0; 12100 ctx->objmask = NULL; 12101 ctx->object = out; 12102 if (!out->command) 12103 return -1; 12104 out->command = ctx->curr; 12105 /* For encap/decap we need is pattern */ 12106 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12107 sizeof(double)); 12108 return len; 12109 } 12110 12111 /** Parse set command, initialize output buffer for subsequent tokens. */ 12112 static int 12113 parse_set_sample_action(struct context *ctx, const struct token *token, 12114 const char *str, unsigned int len, 12115 void *buf, unsigned int size) 12116 { 12117 struct buffer *out = buf; 12118 12119 /* Token name must match. */ 12120 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12121 return -1; 12122 /* Nothing else to do if there is no buffer. */ 12123 if (!out) 12124 return len; 12125 /* Make sure buffer is large enough. */ 12126 if (size < sizeof(*out)) 12127 return -1; 12128 ctx->objdata = 0; 12129 ctx->objmask = NULL; 12130 ctx->object = out; 12131 if (!out->command) 12132 return -1; 12133 out->command = ctx->curr; 12134 /* For sampler we need is actions */ 12135 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12136 sizeof(double)); 12137 return len; 12138 } 12139 12140 /** Parse set command, initialize output buffer for subsequent tokens. */ 12141 static int 12142 parse_set_ipv6_ext_action(struct context *ctx, const struct token *token, 12143 const char *str, unsigned int len, 12144 void *buf, unsigned int size) 12145 { 12146 struct buffer *out = buf; 12147 12148 /* Token name must match. */ 12149 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12150 return -1; 12151 /* Nothing else to do if there is no buffer. */ 12152 if (!out) 12153 return len; 12154 /* Make sure buffer is large enough. */ 12155 if (size < sizeof(*out)) 12156 return -1; 12157 ctx->objdata = 0; 12158 ctx->objmask = NULL; 12159 ctx->object = out; 12160 if (!out->command) 12161 return -1; 12162 out->command = ctx->curr; 12163 /* For ipv6_ext_push/remove we need is pattern */ 12164 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12165 sizeof(double)); 12166 return len; 12167 } 12168 12169 /** 12170 * Parse set raw_encap/raw_decap command, 12171 * initialize output buffer for subsequent tokens. 12172 */ 12173 static int 12174 parse_set_init(struct context *ctx, const struct token *token, 12175 const char *str, unsigned int len, 12176 void *buf, unsigned int size) 12177 { 12178 struct buffer *out = buf; 12179 12180 /* Token name must match. */ 12181 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12182 return -1; 12183 /* Nothing else to do if there is no buffer. */ 12184 if (!out) 12185 return len; 12186 /* Make sure buffer is large enough. */ 12187 if (size < sizeof(*out)) 12188 return -1; 12189 /* Initialize buffer. */ 12190 memset(out, 0x00, sizeof(*out)); 12191 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 12192 ctx->objdata = 0; 12193 ctx->object = out; 12194 ctx->objmask = NULL; 12195 if (!out->command) { 12196 if (ctx->curr != SET) 12197 return -1; 12198 if (sizeof(*out) > size) 12199 return -1; 12200 out->command = ctx->curr; 12201 out->args.vc.data = (uint8_t *)out + size; 12202 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12203 sizeof(double)); 12204 } 12205 return len; 12206 } 12207 12208 /* 12209 * Replace testpmd handles in a flex flow item with real values. 12210 */ 12211 static int 12212 parse_flex_handle(struct context *ctx, const struct token *token, 12213 const char *str, unsigned int len, 12214 void *buf, unsigned int size) 12215 { 12216 struct rte_flow_item_flex *spec, *mask; 12217 const struct rte_flow_item_flex *src_spec, *src_mask; 12218 const struct arg *arg = pop_args(ctx); 12219 uint32_t offset; 12220 uint16_t handle; 12221 int ret; 12222 12223 if (!arg) { 12224 printf("Bad environment\n"); 12225 return -1; 12226 } 12227 offset = arg->offset; 12228 push_args(ctx, arg); 12229 ret = parse_int(ctx, token, str, len, buf, size); 12230 if (ret <= 0 || !ctx->object) 12231 return ret; 12232 if (ctx->port >= RTE_MAX_ETHPORTS) { 12233 printf("Bad port\n"); 12234 return -1; 12235 } 12236 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 12237 const struct flex_item *fp; 12238 spec = ctx->object; 12239 handle = (uint16_t)(uintptr_t)spec->handle; 12240 if (handle >= FLEX_MAX_PARSERS_NUM) { 12241 printf("Bad flex item handle\n"); 12242 return -1; 12243 } 12244 fp = flex_items[ctx->port][handle]; 12245 if (!fp) { 12246 printf("Bad flex item handle\n"); 12247 return -1; 12248 } 12249 spec->handle = fp->flex_handle; 12250 mask = spec + 2; /* spec, last, mask */ 12251 mask->handle = fp->flex_handle; 12252 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 12253 handle = (uint16_t)(uintptr_t) 12254 ((struct rte_flow_item_flex *)ctx->object)->pattern; 12255 if (handle >= FLEX_MAX_PATTERNS_NUM) { 12256 printf("Bad pattern handle\n"); 12257 return -1; 12258 } 12259 src_spec = &flex_patterns[handle].spec; 12260 src_mask = &flex_patterns[handle].mask; 12261 spec = ctx->object; 12262 mask = spec + 2; /* spec, last, mask */ 12263 /* fill flow rule spec and mask parameters */ 12264 spec->length = src_spec->length; 12265 spec->pattern = src_spec->pattern; 12266 mask->length = src_mask->length; 12267 mask->pattern = src_mask->pattern; 12268 } else { 12269 printf("Bad arguments - unknown flex item offset\n"); 12270 return -1; 12271 } 12272 return ret; 12273 } 12274 12275 /** Parse Meter color name */ 12276 static int 12277 parse_meter_color(struct context *ctx, const struct token *token, 12278 const char *str, unsigned int len, void *buf, 12279 unsigned int size) 12280 { 12281 struct rte_flow_item_meter_color *meter_color; 12282 unsigned int i; 12283 12284 (void)token; 12285 (void)buf; 12286 (void)size; 12287 for (i = 0; meter_colors[i]; ++i) 12288 if (!strcmp_partial(meter_colors[i], str, len)) 12289 break; 12290 if (!meter_colors[i]) 12291 return -1; 12292 if (!ctx->object) 12293 return len; 12294 meter_color = ctx->object; 12295 meter_color->color = (enum rte_color)i; 12296 return len; 12297 } 12298 12299 /** Parse Insertion Table Type name */ 12300 static int 12301 parse_insertion_table_type(struct context *ctx, const struct token *token, 12302 const char *str, unsigned int len, void *buf, 12303 unsigned int size) 12304 { 12305 const struct arg *arg = pop_args(ctx); 12306 unsigned int i; 12307 char tmp[2]; 12308 int ret; 12309 12310 (void)size; 12311 /* Argument is expected. */ 12312 if (!arg) 12313 return -1; 12314 for (i = 0; table_insertion_types[i]; ++i) 12315 if (!strcmp_partial(table_insertion_types[i], str, len)) 12316 break; 12317 if (!table_insertion_types[i]) 12318 return -1; 12319 push_args(ctx, arg); 12320 snprintf(tmp, sizeof(tmp), "%u", i); 12321 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12322 return ret > 0 ? (int)len : ret; 12323 } 12324 12325 /** Parse Hash Calculation Table Type name */ 12326 static int 12327 parse_hash_table_type(struct context *ctx, const struct token *token, 12328 const char *str, unsigned int len, void *buf, 12329 unsigned int size) 12330 { 12331 const struct arg *arg = pop_args(ctx); 12332 unsigned int i; 12333 char tmp[2]; 12334 int ret; 12335 12336 (void)size; 12337 /* Argument is expected. */ 12338 if (!arg) 12339 return -1; 12340 for (i = 0; table_hash_funcs[i]; ++i) 12341 if (!strcmp_partial(table_hash_funcs[i], str, len)) 12342 break; 12343 if (!table_hash_funcs[i]) 12344 return -1; 12345 push_args(ctx, arg); 12346 snprintf(tmp, sizeof(tmp), "%u", i); 12347 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12348 return ret > 0 ? (int)len : ret; 12349 } 12350 12351 static int 12352 parse_name_to_index(struct context *ctx, const struct token *token, 12353 const char *str, unsigned int len, void *buf, 12354 unsigned int size, 12355 const char *const names[], size_t names_size, uint32_t *dst) 12356 { 12357 int ret; 12358 uint32_t i; 12359 12360 RTE_SET_USED(token); 12361 RTE_SET_USED(buf); 12362 RTE_SET_USED(size); 12363 if (!ctx->object) 12364 return len; 12365 for (i = 0; i < names_size; i++) { 12366 if (!names[i]) 12367 continue; 12368 ret = strcmp_partial(names[i], str, 12369 RTE_MIN(len, strlen(names[i]))); 12370 if (!ret) { 12371 *dst = i; 12372 return len; 12373 } 12374 } 12375 return -1; 12376 } 12377 12378 static const char *const quota_mode_names[] = { 12379 NULL, 12380 [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", 12381 [RTE_FLOW_QUOTA_MODE_L2] = "l2", 12382 [RTE_FLOW_QUOTA_MODE_L3] = "l3" 12383 }; 12384 12385 static const char *const quota_state_names[] = { 12386 [RTE_FLOW_QUOTA_STATE_PASS] = "pass", 12387 [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" 12388 }; 12389 12390 static const char *const quota_update_names[] = { 12391 [RTE_FLOW_UPDATE_QUOTA_SET] = "set", 12392 [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" 12393 }; 12394 12395 static const char *const query_update_mode_names[] = { 12396 [RTE_FLOW_QU_QUERY_FIRST] = "query_first", 12397 [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" 12398 }; 12399 12400 static int 12401 parse_quota_state_name(struct context *ctx, const struct token *token, 12402 const char *str, unsigned int len, void *buf, 12403 unsigned int size) 12404 { 12405 struct rte_flow_item_quota *quota = ctx->object; 12406 12407 return parse_name_to_index(ctx, token, str, len, buf, size, 12408 quota_state_names, 12409 RTE_DIM(quota_state_names), 12410 (uint32_t *)"a->state); 12411 } 12412 12413 static int 12414 parse_quota_mode_name(struct context *ctx, const struct token *token, 12415 const char *str, unsigned int len, void *buf, 12416 unsigned int size) 12417 { 12418 struct rte_flow_action_quota *quota = ctx->object; 12419 12420 return parse_name_to_index(ctx, token, str, len, buf, size, 12421 quota_mode_names, 12422 RTE_DIM(quota_mode_names), 12423 (uint32_t *)"a->mode); 12424 } 12425 12426 static int 12427 parse_quota_update_name(struct context *ctx, const struct token *token, 12428 const char *str, unsigned int len, void *buf, 12429 unsigned int size) 12430 { 12431 struct rte_flow_update_quota *update = ctx->object; 12432 12433 return parse_name_to_index(ctx, token, str, len, buf, size, 12434 quota_update_names, 12435 RTE_DIM(quota_update_names), 12436 (uint32_t *)&update->op); 12437 } 12438 12439 static int 12440 parse_qu_mode_name(struct context *ctx, const struct token *token, 12441 const char *str, unsigned int len, void *buf, 12442 unsigned int size) 12443 { 12444 struct buffer *out = ctx->object; 12445 12446 return parse_name_to_index(ctx, token, str, len, buf, size, 12447 query_update_mode_names, 12448 RTE_DIM(query_update_mode_names), 12449 (uint32_t *)&out->args.ia.qu_mode); 12450 } 12451 12452 /** No completion. */ 12453 static int 12454 comp_none(struct context *ctx, const struct token *token, 12455 unsigned int ent, char *buf, unsigned int size) 12456 { 12457 (void)ctx; 12458 (void)token; 12459 (void)ent; 12460 (void)buf; 12461 (void)size; 12462 return 0; 12463 } 12464 12465 /** Complete boolean values. */ 12466 static int 12467 comp_boolean(struct context *ctx, const struct token *token, 12468 unsigned int ent, char *buf, unsigned int size) 12469 { 12470 unsigned int i; 12471 12472 (void)ctx; 12473 (void)token; 12474 for (i = 0; boolean_name[i]; ++i) 12475 if (buf && i == ent) 12476 return strlcpy(buf, boolean_name[i], size); 12477 if (buf) 12478 return -1; 12479 return i; 12480 } 12481 12482 /** Complete action names. */ 12483 static int 12484 comp_action(struct context *ctx, const struct token *token, 12485 unsigned int ent, char *buf, unsigned int size) 12486 { 12487 unsigned int i; 12488 12489 (void)ctx; 12490 (void)token; 12491 for (i = 0; next_action[i]; ++i) 12492 if (buf && i == ent) 12493 return strlcpy(buf, token_list[next_action[i]].name, 12494 size); 12495 if (buf) 12496 return -1; 12497 return i; 12498 } 12499 12500 /** Complete available ports. */ 12501 static int 12502 comp_port(struct context *ctx, const struct token *token, 12503 unsigned int ent, char *buf, unsigned int size) 12504 { 12505 unsigned int i = 0; 12506 portid_t p; 12507 12508 (void)ctx; 12509 (void)token; 12510 RTE_ETH_FOREACH_DEV(p) { 12511 if (buf && i == ent) 12512 return snprintf(buf, size, "%u", p); 12513 ++i; 12514 } 12515 if (buf) 12516 return -1; 12517 return i; 12518 } 12519 12520 /** Complete available rule IDs. */ 12521 static int 12522 comp_rule_id(struct context *ctx, const struct token *token, 12523 unsigned int ent, char *buf, unsigned int size) 12524 { 12525 unsigned int i = 0; 12526 struct rte_port *port; 12527 struct port_flow *pf; 12528 12529 (void)token; 12530 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12531 ctx->port == (portid_t)RTE_PORT_ALL) 12532 return -1; 12533 port = &ports[ctx->port]; 12534 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 12535 if (buf && i == ent) 12536 return snprintf(buf, size, "%"PRIu64, pf->id); 12537 ++i; 12538 } 12539 if (buf) 12540 return -1; 12541 return i; 12542 } 12543 12544 /** Complete operation for compare match item. */ 12545 static int 12546 comp_set_compare_op(struct context *ctx, const struct token *token, 12547 unsigned int ent, char *buf, unsigned int size) 12548 { 12549 RTE_SET_USED(ctx); 12550 RTE_SET_USED(token); 12551 if (!buf) 12552 return RTE_DIM(compare_ops); 12553 if (ent < RTE_DIM(compare_ops) - 1) 12554 return strlcpy(buf, compare_ops[ent], size); 12555 return -1; 12556 } 12557 12558 /** Complete field id for compare match item. */ 12559 static int 12560 comp_set_compare_field_id(struct context *ctx, const struct token *token, 12561 unsigned int ent, char *buf, unsigned int size) 12562 { 12563 const char *name; 12564 12565 RTE_SET_USED(token); 12566 if (!buf) 12567 return RTE_DIM(flow_field_ids); 12568 if (ent >= RTE_DIM(flow_field_ids) - 1) 12569 return -1; 12570 name = flow_field_ids[ent]; 12571 if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE || 12572 (strcmp(name, "pointer") && strcmp(name, "value"))) 12573 return strlcpy(buf, name, size); 12574 return -1; 12575 } 12576 12577 /** Complete type field for RSS action. */ 12578 static int 12579 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 12580 unsigned int ent, char *buf, unsigned int size) 12581 { 12582 unsigned int i; 12583 12584 (void)ctx; 12585 (void)token; 12586 for (i = 0; rss_type_table[i].str; ++i) 12587 ; 12588 if (!buf) 12589 return i + 1; 12590 if (ent < i) 12591 return strlcpy(buf, rss_type_table[ent].str, size); 12592 if (ent == i) 12593 return snprintf(buf, size, "end"); 12594 return -1; 12595 } 12596 12597 /** Complete queue field for RSS action. */ 12598 static int 12599 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 12600 unsigned int ent, char *buf, unsigned int size) 12601 { 12602 (void)ctx; 12603 (void)token; 12604 if (!buf) 12605 return nb_rxq + 1; 12606 if (ent < nb_rxq) 12607 return snprintf(buf, size, "%u", ent); 12608 if (ent == nb_rxq) 12609 return snprintf(buf, size, "end"); 12610 return -1; 12611 } 12612 12613 /** Complete index number for set raw_encap/raw_decap commands. */ 12614 static int 12615 comp_set_raw_index(struct context *ctx, const struct token *token, 12616 unsigned int ent, char *buf, unsigned int size) 12617 { 12618 uint16_t idx = 0; 12619 uint16_t nb = 0; 12620 12621 RTE_SET_USED(ctx); 12622 RTE_SET_USED(token); 12623 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 12624 if (buf && idx == ent) 12625 return snprintf(buf, size, "%u", idx); 12626 ++nb; 12627 } 12628 return nb; 12629 } 12630 12631 /** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ 12632 static int 12633 comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 12634 unsigned int ent, char *buf, unsigned int size) 12635 { 12636 uint16_t idx = 0; 12637 uint16_t nb = 0; 12638 12639 RTE_SET_USED(ctx); 12640 RTE_SET_USED(token); 12641 for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { 12642 if (buf && idx == ent) 12643 return snprintf(buf, size, "%u", idx); 12644 ++nb; 12645 } 12646 return nb; 12647 } 12648 12649 /** Complete index number for set raw_encap/raw_decap commands. */ 12650 static int 12651 comp_set_sample_index(struct context *ctx, const struct token *token, 12652 unsigned int ent, char *buf, unsigned int size) 12653 { 12654 uint16_t idx = 0; 12655 uint16_t nb = 0; 12656 12657 RTE_SET_USED(ctx); 12658 RTE_SET_USED(token); 12659 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 12660 if (buf && idx == ent) 12661 return snprintf(buf, size, "%u", idx); 12662 ++nb; 12663 } 12664 return nb; 12665 } 12666 12667 /** Complete operation for modify_field command. */ 12668 static int 12669 comp_set_modify_field_op(struct context *ctx, const struct token *token, 12670 unsigned int ent, char *buf, unsigned int size) 12671 { 12672 RTE_SET_USED(ctx); 12673 RTE_SET_USED(token); 12674 if (!buf) 12675 return RTE_DIM(modify_field_ops); 12676 if (ent < RTE_DIM(modify_field_ops) - 1) 12677 return strlcpy(buf, modify_field_ops[ent], size); 12678 return -1; 12679 } 12680 12681 /** Complete field id for modify_field command. */ 12682 static int 12683 comp_set_modify_field_id(struct context *ctx, const struct token *token, 12684 unsigned int ent, char *buf, unsigned int size) 12685 { 12686 const char *name; 12687 12688 RTE_SET_USED(token); 12689 if (!buf) 12690 return RTE_DIM(flow_field_ids); 12691 if (ent >= RTE_DIM(flow_field_ids) - 1) 12692 return -1; 12693 name = flow_field_ids[ent]; 12694 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 12695 (strcmp(name, "pointer") && strcmp(name, "value"))) 12696 return strlcpy(buf, name, size); 12697 return -1; 12698 } 12699 12700 /** Complete available pattern template IDs. */ 12701 static int 12702 comp_pattern_template_id(struct context *ctx, const struct token *token, 12703 unsigned int ent, char *buf, unsigned int size) 12704 { 12705 unsigned int i = 0; 12706 struct rte_port *port; 12707 struct port_template *pt; 12708 12709 (void)token; 12710 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12711 ctx->port == (portid_t)RTE_PORT_ALL) 12712 return -1; 12713 port = &ports[ctx->port]; 12714 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 12715 if (buf && i == ent) 12716 return snprintf(buf, size, "%u", pt->id); 12717 ++i; 12718 } 12719 if (buf) 12720 return -1; 12721 return i; 12722 } 12723 12724 /** Complete available actions template IDs. */ 12725 static int 12726 comp_actions_template_id(struct context *ctx, const struct token *token, 12727 unsigned int ent, char *buf, unsigned int size) 12728 { 12729 unsigned int i = 0; 12730 struct rte_port *port; 12731 struct port_template *pt; 12732 12733 (void)token; 12734 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12735 ctx->port == (portid_t)RTE_PORT_ALL) 12736 return -1; 12737 port = &ports[ctx->port]; 12738 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 12739 if (buf && i == ent) 12740 return snprintf(buf, size, "%u", pt->id); 12741 ++i; 12742 } 12743 if (buf) 12744 return -1; 12745 return i; 12746 } 12747 12748 /** Complete available table IDs. */ 12749 static int 12750 comp_table_id(struct context *ctx, const struct token *token, 12751 unsigned int ent, char *buf, unsigned int size) 12752 { 12753 unsigned int i = 0; 12754 struct rte_port *port; 12755 struct port_table *pt; 12756 12757 (void)token; 12758 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12759 ctx->port == (portid_t)RTE_PORT_ALL) 12760 return -1; 12761 port = &ports[ctx->port]; 12762 for (pt = port->table_list; pt != NULL; pt = pt->next) { 12763 if (buf && i == ent) 12764 return snprintf(buf, size, "%u", pt->id); 12765 ++i; 12766 } 12767 if (buf) 12768 return -1; 12769 return i; 12770 } 12771 12772 /** Complete available queue IDs. */ 12773 static int 12774 comp_queue_id(struct context *ctx, const struct token *token, 12775 unsigned int ent, char *buf, unsigned int size) 12776 { 12777 unsigned int i = 0; 12778 struct rte_port *port; 12779 12780 (void)token; 12781 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12782 ctx->port == (portid_t)RTE_PORT_ALL) 12783 return -1; 12784 port = &ports[ctx->port]; 12785 for (i = 0; i < port->queue_nb; i++) { 12786 if (buf && i == ent) 12787 return snprintf(buf, size, "%u", i); 12788 } 12789 if (buf) 12790 return -1; 12791 return i; 12792 } 12793 12794 static int 12795 comp_names_to_index(struct context *ctx, const struct token *token, 12796 unsigned int ent, char *buf, unsigned int size, 12797 const char *const names[], size_t names_size) 12798 { 12799 RTE_SET_USED(ctx); 12800 RTE_SET_USED(token); 12801 if (!buf) 12802 return names_size; 12803 if (names[ent] && ent < names_size) 12804 return rte_strscpy(buf, names[ent], size); 12805 return -1; 12806 12807 } 12808 12809 /** Complete available Meter colors. */ 12810 static int 12811 comp_meter_color(struct context *ctx, const struct token *token, 12812 unsigned int ent, char *buf, unsigned int size) 12813 { 12814 RTE_SET_USED(ctx); 12815 RTE_SET_USED(token); 12816 if (!buf) 12817 return RTE_DIM(meter_colors); 12818 if (ent < RTE_DIM(meter_colors) - 1) 12819 return strlcpy(buf, meter_colors[ent], size); 12820 return -1; 12821 } 12822 12823 /** Complete available Insertion Table types. */ 12824 static int 12825 comp_insertion_table_type(struct context *ctx, const struct token *token, 12826 unsigned int ent, char *buf, unsigned int size) 12827 { 12828 RTE_SET_USED(ctx); 12829 RTE_SET_USED(token); 12830 if (!buf) 12831 return RTE_DIM(table_insertion_types); 12832 if (ent < RTE_DIM(table_insertion_types) - 1) 12833 return rte_strscpy(buf, table_insertion_types[ent], size); 12834 return -1; 12835 } 12836 12837 /** Complete available Hash Calculation Table types. */ 12838 static int 12839 comp_hash_table_type(struct context *ctx, const struct token *token, 12840 unsigned int ent, char *buf, unsigned int size) 12841 { 12842 RTE_SET_USED(ctx); 12843 RTE_SET_USED(token); 12844 if (!buf) 12845 return RTE_DIM(table_hash_funcs); 12846 if (ent < RTE_DIM(table_hash_funcs) - 1) 12847 return rte_strscpy(buf, table_hash_funcs[ent], size); 12848 return -1; 12849 } 12850 12851 static int 12852 comp_quota_state_name(struct context *ctx, const struct token *token, 12853 unsigned int ent, char *buf, unsigned int size) 12854 { 12855 return comp_names_to_index(ctx, token, ent, buf, size, 12856 quota_state_names, 12857 RTE_DIM(quota_state_names)); 12858 } 12859 12860 static int 12861 comp_quota_mode_name(struct context *ctx, const struct token *token, 12862 unsigned int ent, char *buf, unsigned int size) 12863 { 12864 return comp_names_to_index(ctx, token, ent, buf, size, 12865 quota_mode_names, 12866 RTE_DIM(quota_mode_names)); 12867 } 12868 12869 static int 12870 comp_quota_update_name(struct context *ctx, const struct token *token, 12871 unsigned int ent, char *buf, unsigned int size) 12872 { 12873 return comp_names_to_index(ctx, token, ent, buf, size, 12874 quota_update_names, 12875 RTE_DIM(quota_update_names)); 12876 } 12877 12878 static int 12879 comp_qu_mode_name(struct context *ctx, const struct token *token, 12880 unsigned int ent, char *buf, unsigned int size) 12881 { 12882 return comp_names_to_index(ctx, token, ent, buf, size, 12883 query_update_mode_names, 12884 RTE_DIM(query_update_mode_names)); 12885 } 12886 12887 /** Internal context. */ 12888 static struct context cmd_flow_context; 12889 12890 /** Global parser instance (cmdline API). */ 12891 cmdline_parse_inst_t cmd_flow; 12892 cmdline_parse_inst_t cmd_set_raw; 12893 12894 /** Initialize context. */ 12895 static void 12896 cmd_flow_context_init(struct context *ctx) 12897 { 12898 /* A full memset() is not necessary. */ 12899 ctx->curr = ZERO; 12900 ctx->prev = ZERO; 12901 ctx->next_num = 0; 12902 ctx->args_num = 0; 12903 ctx->eol = 0; 12904 ctx->last = 0; 12905 ctx->port = 0; 12906 ctx->objdata = 0; 12907 ctx->object = NULL; 12908 ctx->objmask = NULL; 12909 } 12910 12911 /** Parse a token (cmdline API). */ 12912 static int 12913 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 12914 unsigned int size) 12915 { 12916 struct context *ctx = &cmd_flow_context; 12917 const struct token *token; 12918 const enum index *list; 12919 int len; 12920 int i; 12921 12922 (void)hdr; 12923 token = &token_list[ctx->curr]; 12924 /* Check argument length. */ 12925 ctx->eol = 0; 12926 ctx->last = 1; 12927 for (len = 0; src[len]; ++len) 12928 if (src[len] == '#' || isspace(src[len])) 12929 break; 12930 if (!len) 12931 return -1; 12932 /* Last argument and EOL detection. */ 12933 for (i = len; src[i]; ++i) 12934 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 12935 break; 12936 else if (!isspace(src[i])) { 12937 ctx->last = 0; 12938 break; 12939 } 12940 for (; src[i]; ++i) 12941 if (src[i] == '\r' || src[i] == '\n') { 12942 ctx->eol = 1; 12943 break; 12944 } 12945 /* Initialize context if necessary. */ 12946 if (!ctx->next_num) { 12947 if (!token->next) 12948 return 0; 12949 ctx->next[ctx->next_num++] = token->next[0]; 12950 } 12951 /* Process argument through candidates. */ 12952 ctx->prev = ctx->curr; 12953 list = ctx->next[ctx->next_num - 1]; 12954 for (i = 0; list[i]; ++i) { 12955 const struct token *next = &token_list[list[i]]; 12956 int tmp; 12957 12958 ctx->curr = list[i]; 12959 if (next->call) 12960 tmp = next->call(ctx, next, src, len, result, size); 12961 else 12962 tmp = parse_default(ctx, next, src, len, result, size); 12963 if (tmp == -1 || tmp != len) 12964 continue; 12965 token = next; 12966 break; 12967 } 12968 if (!list[i]) 12969 return -1; 12970 --ctx->next_num; 12971 /* Push subsequent tokens if any. */ 12972 if (token->next) 12973 for (i = 0; token->next[i]; ++i) { 12974 if (ctx->next_num == RTE_DIM(ctx->next)) 12975 return -1; 12976 ctx->next[ctx->next_num++] = token->next[i]; 12977 } 12978 /* Push arguments if any. */ 12979 if (token->args) 12980 for (i = 0; token->args[i]; ++i) { 12981 if (ctx->args_num == RTE_DIM(ctx->args)) 12982 return -1; 12983 ctx->args[ctx->args_num++] = token->args[i]; 12984 } 12985 return len; 12986 } 12987 12988 int 12989 flow_parse(const char *src, void *result, unsigned int size, 12990 struct rte_flow_attr **attr, 12991 struct rte_flow_item **pattern, struct rte_flow_action **actions) 12992 { 12993 int ret; 12994 struct context saved_flow_ctx = cmd_flow_context; 12995 12996 cmd_flow_context_init(&cmd_flow_context); 12997 do { 12998 ret = cmd_flow_parse(NULL, src, result, size); 12999 if (ret > 0) { 13000 src += ret; 13001 while (isspace(*src)) 13002 src++; 13003 } 13004 } while (ret > 0 && strlen(src)); 13005 cmd_flow_context = saved_flow_ctx; 13006 *attr = &((struct buffer *)result)->args.vc.attr; 13007 *pattern = ((struct buffer *)result)->args.vc.pattern; 13008 *actions = ((struct buffer *)result)->args.vc.actions; 13009 return (ret >= 0 && !strlen(src)) ? 0 : -1; 13010 } 13011 13012 /** Return number of completion entries (cmdline API). */ 13013 static int 13014 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 13015 { 13016 struct context *ctx = &cmd_flow_context; 13017 const struct token *token = &token_list[ctx->curr]; 13018 const enum index *list; 13019 int i; 13020 13021 (void)hdr; 13022 /* Count number of tokens in current list. */ 13023 if (ctx->next_num) 13024 list = ctx->next[ctx->next_num - 1]; 13025 else 13026 list = token->next[0]; 13027 for (i = 0; list[i]; ++i) 13028 ; 13029 if (!i) 13030 return 0; 13031 /* 13032 * If there is a single token, use its completion callback, otherwise 13033 * return the number of entries. 13034 */ 13035 token = &token_list[list[0]]; 13036 if (i == 1 && token->comp) { 13037 /* Save index for cmd_flow_get_help(). */ 13038 ctx->prev = list[0]; 13039 return token->comp(ctx, token, 0, NULL, 0); 13040 } 13041 return i; 13042 } 13043 13044 /** Return a completion entry (cmdline API). */ 13045 static int 13046 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 13047 char *dst, unsigned int size) 13048 { 13049 struct context *ctx = &cmd_flow_context; 13050 const struct token *token = &token_list[ctx->curr]; 13051 const enum index *list; 13052 int i; 13053 13054 (void)hdr; 13055 /* Count number of tokens in current list. */ 13056 if (ctx->next_num) 13057 list = ctx->next[ctx->next_num - 1]; 13058 else 13059 list = token->next[0]; 13060 for (i = 0; list[i]; ++i) 13061 ; 13062 if (!i) 13063 return -1; 13064 /* If there is a single token, use its completion callback. */ 13065 token = &token_list[list[0]]; 13066 if (i == 1 && token->comp) { 13067 /* Save index for cmd_flow_get_help(). */ 13068 ctx->prev = list[0]; 13069 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 13070 } 13071 /* Otherwise make sure the index is valid and use defaults. */ 13072 if (index >= i) 13073 return -1; 13074 token = &token_list[list[index]]; 13075 strlcpy(dst, token->name, size); 13076 /* Save index for cmd_flow_get_help(). */ 13077 ctx->prev = list[index]; 13078 return 0; 13079 } 13080 13081 /** Populate help strings for current token (cmdline API). */ 13082 static int 13083 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 13084 { 13085 struct context *ctx = &cmd_flow_context; 13086 const struct token *token = &token_list[ctx->prev]; 13087 13088 (void)hdr; 13089 if (!size) 13090 return -1; 13091 /* Set token type and update global help with details. */ 13092 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 13093 if (token->help) 13094 cmd_flow.help_str = token->help; 13095 else 13096 cmd_flow.help_str = token->name; 13097 return 0; 13098 } 13099 13100 /** Token definition template (cmdline API). */ 13101 static struct cmdline_token_hdr cmd_flow_token_hdr = { 13102 .ops = &(struct cmdline_token_ops){ 13103 .parse = cmd_flow_parse, 13104 .complete_get_nb = cmd_flow_complete_get_nb, 13105 .complete_get_elt = cmd_flow_complete_get_elt, 13106 .get_help = cmd_flow_get_help, 13107 }, 13108 .offset = 0, 13109 }; 13110 13111 /** Populate the next dynamic token. */ 13112 static void 13113 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 13114 cmdline_parse_token_hdr_t **hdr_inst) 13115 { 13116 struct context *ctx = &cmd_flow_context; 13117 13118 /* Always reinitialize context before requesting the first token. */ 13119 if (!(hdr_inst - cmd_flow.tokens)) 13120 cmd_flow_context_init(ctx); 13121 /* Return NULL when no more tokens are expected. */ 13122 if (!ctx->next_num && ctx->curr) { 13123 *hdr = NULL; 13124 return; 13125 } 13126 /* Determine if command should end here. */ 13127 if (ctx->eol && ctx->last && ctx->next_num) { 13128 const enum index *list = ctx->next[ctx->next_num - 1]; 13129 int i; 13130 13131 for (i = 0; list[i]; ++i) { 13132 if (list[i] != END) 13133 continue; 13134 *hdr = NULL; 13135 return; 13136 } 13137 } 13138 *hdr = &cmd_flow_token_hdr; 13139 } 13140 13141 static SLIST_HEAD(, indlst_conf) indlst_conf_head = 13142 SLIST_HEAD_INITIALIZER(); 13143 13144 static void 13145 indirect_action_flow_conf_create(const struct buffer *in) 13146 { 13147 int len, ret; 13148 uint32_t i; 13149 struct indlst_conf *indlst_conf = NULL; 13150 size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); 13151 struct rte_flow_action *src = in->args.vc.actions; 13152 13153 if (!in->args.vc.actions_n) 13154 goto end; 13155 len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); 13156 if (len <= 0) 13157 goto end; 13158 len = RTE_ALIGN(len, 16); 13159 13160 indlst_conf = calloc(1, base + len + 13161 in->args.vc.actions_n * sizeof(uintptr_t)); 13162 if (!indlst_conf) 13163 goto end; 13164 indlst_conf->id = in->args.vc.attr.group; 13165 indlst_conf->conf_num = in->args.vc.actions_n - 1; 13166 indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); 13167 ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, 13168 len, src, NULL); 13169 if (ret <= 0) { 13170 free(indlst_conf); 13171 indlst_conf = NULL; 13172 goto end; 13173 } 13174 indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); 13175 for (i = 0; i < indlst_conf->conf_num; i++) 13176 indlst_conf->conf[i] = indlst_conf->actions[i].conf; 13177 SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); 13178 end: 13179 if (indlst_conf) 13180 printf("created indirect action list configuration %u\n", 13181 in->args.vc.attr.group); 13182 else 13183 printf("cannot create indirect action list configuration %u\n", 13184 in->args.vc.attr.group); 13185 } 13186 13187 static const struct indlst_conf * 13188 indirect_action_list_conf_get(uint32_t conf_id) 13189 { 13190 const struct indlst_conf *conf; 13191 13192 SLIST_FOREACH(conf, &indlst_conf_head, next) { 13193 if (conf->id == conf_id) 13194 return conf; 13195 } 13196 return NULL; 13197 } 13198 13199 /** Dispatch parsed buffer to function calls. */ 13200 static void 13201 cmd_flow_parsed(const struct buffer *in) 13202 { 13203 switch (in->command) { 13204 case INFO: 13205 port_flow_get_info(in->port); 13206 break; 13207 case CONFIGURE: 13208 port_flow_configure(in->port, 13209 &in->args.configure.port_attr, 13210 in->args.configure.nb_queue, 13211 &in->args.configure.queue_attr); 13212 break; 13213 case PATTERN_TEMPLATE_CREATE: 13214 port_flow_pattern_template_create(in->port, 13215 in->args.vc.pat_templ_id, 13216 &((const struct rte_flow_pattern_template_attr) { 13217 .relaxed_matching = in->args.vc.attr.reserved, 13218 .ingress = in->args.vc.attr.ingress, 13219 .egress = in->args.vc.attr.egress, 13220 .transfer = in->args.vc.attr.transfer, 13221 }), 13222 in->args.vc.pattern); 13223 break; 13224 case PATTERN_TEMPLATE_DESTROY: 13225 port_flow_pattern_template_destroy(in->port, 13226 in->args.templ_destroy.template_id_n, 13227 in->args.templ_destroy.template_id); 13228 break; 13229 case ACTIONS_TEMPLATE_CREATE: 13230 port_flow_actions_template_create(in->port, 13231 in->args.vc.act_templ_id, 13232 &((const struct rte_flow_actions_template_attr) { 13233 .ingress = in->args.vc.attr.ingress, 13234 .egress = in->args.vc.attr.egress, 13235 .transfer = in->args.vc.attr.transfer, 13236 }), 13237 in->args.vc.actions, 13238 in->args.vc.masks); 13239 break; 13240 case ACTIONS_TEMPLATE_DESTROY: 13241 port_flow_actions_template_destroy(in->port, 13242 in->args.templ_destroy.template_id_n, 13243 in->args.templ_destroy.template_id); 13244 break; 13245 case TABLE_CREATE: 13246 port_flow_template_table_create(in->port, in->args.table.id, 13247 &in->args.table.attr, in->args.table.pat_templ_id_n, 13248 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 13249 in->args.table.act_templ_id); 13250 break; 13251 case TABLE_DESTROY: 13252 port_flow_template_table_destroy(in->port, 13253 in->args.table_destroy.table_id_n, 13254 in->args.table_destroy.table_id); 13255 break; 13256 case TABLE_RESIZE_COMPLETE: 13257 port_flow_template_table_resize_complete 13258 (in->port, in->args.table_destroy.table_id[0]); 13259 break; 13260 case GROUP_SET_MISS_ACTIONS: 13261 port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, 13262 in->args.vc.actions); 13263 break; 13264 case TABLE_RESIZE: 13265 port_flow_template_table_resize(in->port, in->args.table.id, 13266 in->args.table.attr.nb_flows); 13267 break; 13268 case QUEUE_CREATE: 13269 port_queue_flow_create(in->port, in->queue, in->postpone, 13270 in->args.vc.table_id, in->args.vc.rule_id, 13271 in->args.vc.pat_templ_id, in->args.vc.act_templ_id, 13272 in->args.vc.pattern, in->args.vc.actions); 13273 break; 13274 case QUEUE_DESTROY: 13275 port_queue_flow_destroy(in->port, in->queue, in->postpone, 13276 in->args.destroy.rule_n, 13277 in->args.destroy.rule); 13278 break; 13279 case QUEUE_FLOW_UPDATE_RESIZED: 13280 port_queue_flow_update_resized(in->port, in->queue, 13281 in->postpone, 13282 in->args.destroy.rule[0]); 13283 break; 13284 case QUEUE_UPDATE: 13285 port_queue_flow_update(in->port, in->queue, in->postpone, 13286 in->args.vc.rule_id, in->args.vc.act_templ_id, 13287 in->args.vc.actions); 13288 break; 13289 case PUSH: 13290 port_queue_flow_push(in->port, in->queue); 13291 break; 13292 case PULL: 13293 port_queue_flow_pull(in->port, in->queue); 13294 break; 13295 case HASH: 13296 if (!in->args.vc.encap_hash) 13297 port_flow_hash_calc(in->port, in->args.vc.table_id, 13298 in->args.vc.pat_templ_id, 13299 in->args.vc.pattern); 13300 else 13301 port_flow_hash_calc_encap(in->port, in->args.vc.field, 13302 in->args.vc.pattern); 13303 break; 13304 case QUEUE_AGED: 13305 port_queue_flow_aged(in->port, in->queue, 13306 in->args.aged.destroy); 13307 break; 13308 case QUEUE_INDIRECT_ACTION_CREATE: 13309 case QUEUE_INDIRECT_ACTION_LIST_CREATE: 13310 port_queue_action_handle_create( 13311 in->port, in->queue, in->postpone, 13312 in->args.vc.attr.group, 13313 in->command == QUEUE_INDIRECT_ACTION_LIST_CREATE, 13314 &((const struct rte_flow_indir_action_conf) { 13315 .ingress = in->args.vc.attr.ingress, 13316 .egress = in->args.vc.attr.egress, 13317 .transfer = in->args.vc.attr.transfer, 13318 }), 13319 in->args.vc.actions); 13320 break; 13321 case QUEUE_INDIRECT_ACTION_DESTROY: 13322 port_queue_action_handle_destroy(in->port, 13323 in->queue, in->postpone, 13324 in->args.ia_destroy.action_id_n, 13325 in->args.ia_destroy.action_id); 13326 break; 13327 case QUEUE_INDIRECT_ACTION_UPDATE: 13328 port_queue_action_handle_update(in->port, 13329 in->queue, in->postpone, 13330 in->args.vc.attr.group, 13331 in->args.vc.actions); 13332 break; 13333 case QUEUE_INDIRECT_ACTION_QUERY: 13334 port_queue_action_handle_query(in->port, 13335 in->queue, in->postpone, 13336 in->args.ia.action_id); 13337 break; 13338 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 13339 port_queue_action_handle_query_update(in->port, in->queue, 13340 in->postpone, 13341 in->args.ia.action_id, 13342 in->args.ia.qu_mode, 13343 in->args.vc.actions); 13344 break; 13345 case INDIRECT_ACTION_CREATE: 13346 case INDIRECT_ACTION_LIST_CREATE: 13347 port_action_handle_create( 13348 in->port, in->args.vc.attr.group, 13349 in->command == INDIRECT_ACTION_LIST_CREATE, 13350 &((const struct rte_flow_indir_action_conf) { 13351 .ingress = in->args.vc.attr.ingress, 13352 .egress = in->args.vc.attr.egress, 13353 .transfer = in->args.vc.attr.transfer, 13354 }), 13355 in->args.vc.actions); 13356 break; 13357 case INDIRECT_ACTION_FLOW_CONF_CREATE: 13358 indirect_action_flow_conf_create(in); 13359 break; 13360 case INDIRECT_ACTION_DESTROY: 13361 port_action_handle_destroy(in->port, 13362 in->args.ia_destroy.action_id_n, 13363 in->args.ia_destroy.action_id); 13364 break; 13365 case INDIRECT_ACTION_UPDATE: 13366 port_action_handle_update(in->port, in->args.vc.attr.group, 13367 in->args.vc.actions); 13368 break; 13369 case INDIRECT_ACTION_QUERY: 13370 port_action_handle_query(in->port, in->args.ia.action_id); 13371 break; 13372 case INDIRECT_ACTION_QUERY_UPDATE: 13373 port_action_handle_query_update(in->port, 13374 in->args.ia.action_id, 13375 in->args.ia.qu_mode, 13376 in->args.vc.actions); 13377 break; 13378 case VALIDATE: 13379 port_flow_validate(in->port, &in->args.vc.attr, 13380 in->args.vc.pattern, in->args.vc.actions, 13381 &in->args.vc.tunnel_ops); 13382 break; 13383 case CREATE: 13384 port_flow_create(in->port, &in->args.vc.attr, 13385 in->args.vc.pattern, in->args.vc.actions, 13386 &in->args.vc.tunnel_ops, in->args.vc.user_id); 13387 break; 13388 case DESTROY: 13389 port_flow_destroy(in->port, in->args.destroy.rule_n, 13390 in->args.destroy.rule, 13391 in->args.destroy.is_user_id); 13392 break; 13393 case UPDATE: 13394 port_flow_update(in->port, in->args.vc.rule_id, 13395 in->args.vc.actions, in->args.vc.user_id); 13396 break; 13397 case FLUSH: 13398 port_flow_flush(in->port); 13399 break; 13400 case DUMP_ONE: 13401 case DUMP_ALL: 13402 port_flow_dump(in->port, in->args.dump.mode, 13403 in->args.dump.rule, in->args.dump.file, 13404 in->args.dump.is_user_id); 13405 break; 13406 case QUERY: 13407 port_flow_query(in->port, in->args.query.rule, 13408 &in->args.query.action, 13409 in->args.query.is_user_id); 13410 break; 13411 case LIST: 13412 port_flow_list(in->port, in->args.list.group_n, 13413 in->args.list.group); 13414 break; 13415 case ISOLATE: 13416 port_flow_isolate(in->port, in->args.isolate.set); 13417 break; 13418 case AGED: 13419 port_flow_aged(in->port, in->args.aged.destroy); 13420 break; 13421 case TUNNEL_CREATE: 13422 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 13423 break; 13424 case TUNNEL_DESTROY: 13425 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 13426 break; 13427 case TUNNEL_LIST: 13428 port_flow_tunnel_list(in->port); 13429 break; 13430 case ACTION_POL_G: 13431 port_meter_policy_add(in->port, in->args.policy.policy_id, 13432 in->args.vc.actions); 13433 break; 13434 case FLEX_ITEM_CREATE: 13435 flex_item_create(in->port, in->args.flex.token, 13436 in->args.flex.filename); 13437 break; 13438 case FLEX_ITEM_DESTROY: 13439 flex_item_destroy(in->port, in->args.flex.token); 13440 break; 13441 default: 13442 break; 13443 } 13444 fflush(stdout); 13445 } 13446 13447 /** Token generator and output processing callback (cmdline API). */ 13448 static void 13449 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 13450 { 13451 if (cl == NULL) 13452 cmd_flow_tok(arg0, arg2); 13453 else 13454 cmd_flow_parsed(arg0); 13455 } 13456 13457 /** Global parser instance (cmdline API). */ 13458 cmdline_parse_inst_t cmd_flow = { 13459 .f = cmd_flow_cb, 13460 .data = NULL, /**< Unused. */ 13461 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 13462 .tokens = { 13463 NULL, 13464 }, /**< Tokens are returned by cmd_flow_tok(). */ 13465 }; 13466 13467 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 13468 13469 static void 13470 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 13471 { 13472 struct rte_ipv4_hdr *ipv4; 13473 struct rte_ether_hdr *eth; 13474 struct rte_ipv6_hdr *ipv6; 13475 struct rte_vxlan_hdr *vxlan; 13476 struct rte_vxlan_gpe_hdr *gpe; 13477 struct rte_flow_item_nvgre *nvgre; 13478 uint32_t ipv6_vtc_flow; 13479 13480 switch (item->type) { 13481 case RTE_FLOW_ITEM_TYPE_ETH: 13482 eth = (struct rte_ether_hdr *)buf; 13483 if (next_proto) 13484 eth->ether_type = rte_cpu_to_be_16(next_proto); 13485 break; 13486 case RTE_FLOW_ITEM_TYPE_IPV4: 13487 ipv4 = (struct rte_ipv4_hdr *)buf; 13488 if (!ipv4->version_ihl) 13489 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 13490 if (next_proto && ipv4->next_proto_id == 0) 13491 ipv4->next_proto_id = (uint8_t)next_proto; 13492 break; 13493 case RTE_FLOW_ITEM_TYPE_IPV6: 13494 ipv6 = (struct rte_ipv6_hdr *)buf; 13495 if (next_proto && ipv6->proto == 0) 13496 ipv6->proto = (uint8_t)next_proto; 13497 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 13498 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 13499 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 13500 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 13501 break; 13502 case RTE_FLOW_ITEM_TYPE_VXLAN: 13503 vxlan = (struct rte_vxlan_hdr *)buf; 13504 vxlan->vx_flags = 0x08; 13505 break; 13506 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13507 gpe = (struct rte_vxlan_gpe_hdr *)buf; 13508 gpe->vx_flags = 0x0C; 13509 break; 13510 case RTE_FLOW_ITEM_TYPE_NVGRE: 13511 nvgre = (struct rte_flow_item_nvgre *)buf; 13512 nvgre->protocol = rte_cpu_to_be_16(0x6558); 13513 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 13514 break; 13515 default: 13516 break; 13517 } 13518 } 13519 13520 /** Helper of get item's default mask. */ 13521 static const void * 13522 flow_item_default_mask(const struct rte_flow_item *item) 13523 { 13524 const void *mask = NULL; 13525 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 13526 static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { 13527 .hdr = { 13528 .next_hdr = 0xff, 13529 .type = 0xff, 13530 .segments_left = 0xff, 13531 }, 13532 }; 13533 13534 switch (item->type) { 13535 case RTE_FLOW_ITEM_TYPE_ANY: 13536 mask = &rte_flow_item_any_mask; 13537 break; 13538 case RTE_FLOW_ITEM_TYPE_PORT_ID: 13539 mask = &rte_flow_item_port_id_mask; 13540 break; 13541 case RTE_FLOW_ITEM_TYPE_RAW: 13542 mask = &rte_flow_item_raw_mask; 13543 break; 13544 case RTE_FLOW_ITEM_TYPE_ETH: 13545 mask = &rte_flow_item_eth_mask; 13546 break; 13547 case RTE_FLOW_ITEM_TYPE_VLAN: 13548 mask = &rte_flow_item_vlan_mask; 13549 break; 13550 case RTE_FLOW_ITEM_TYPE_IPV4: 13551 mask = &rte_flow_item_ipv4_mask; 13552 break; 13553 case RTE_FLOW_ITEM_TYPE_IPV6: 13554 mask = &rte_flow_item_ipv6_mask; 13555 break; 13556 case RTE_FLOW_ITEM_TYPE_ICMP: 13557 mask = &rte_flow_item_icmp_mask; 13558 break; 13559 case RTE_FLOW_ITEM_TYPE_UDP: 13560 mask = &rte_flow_item_udp_mask; 13561 break; 13562 case RTE_FLOW_ITEM_TYPE_TCP: 13563 mask = &rte_flow_item_tcp_mask; 13564 break; 13565 case RTE_FLOW_ITEM_TYPE_SCTP: 13566 mask = &rte_flow_item_sctp_mask; 13567 break; 13568 case RTE_FLOW_ITEM_TYPE_VXLAN: 13569 mask = &rte_flow_item_vxlan_mask; 13570 break; 13571 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13572 mask = &rte_flow_item_vxlan_gpe_mask; 13573 break; 13574 case RTE_FLOW_ITEM_TYPE_E_TAG: 13575 mask = &rte_flow_item_e_tag_mask; 13576 break; 13577 case RTE_FLOW_ITEM_TYPE_NVGRE: 13578 mask = &rte_flow_item_nvgre_mask; 13579 break; 13580 case RTE_FLOW_ITEM_TYPE_MPLS: 13581 mask = &rte_flow_item_mpls_mask; 13582 break; 13583 case RTE_FLOW_ITEM_TYPE_GRE: 13584 mask = &rte_flow_item_gre_mask; 13585 break; 13586 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13587 mask = &gre_key_default_mask; 13588 break; 13589 case RTE_FLOW_ITEM_TYPE_META: 13590 mask = &rte_flow_item_meta_mask; 13591 break; 13592 case RTE_FLOW_ITEM_TYPE_RANDOM: 13593 mask = &rte_flow_item_random_mask; 13594 break; 13595 case RTE_FLOW_ITEM_TYPE_FUZZY: 13596 mask = &rte_flow_item_fuzzy_mask; 13597 break; 13598 case RTE_FLOW_ITEM_TYPE_GTP: 13599 mask = &rte_flow_item_gtp_mask; 13600 break; 13601 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13602 mask = &rte_flow_item_gtp_psc_mask; 13603 break; 13604 case RTE_FLOW_ITEM_TYPE_GENEVE: 13605 mask = &rte_flow_item_geneve_mask; 13606 break; 13607 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13608 mask = &rte_flow_item_geneve_opt_mask; 13609 break; 13610 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 13611 mask = &rte_flow_item_pppoe_proto_id_mask; 13612 break; 13613 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13614 mask = &rte_flow_item_l2tpv3oip_mask; 13615 break; 13616 case RTE_FLOW_ITEM_TYPE_ESP: 13617 mask = &rte_flow_item_esp_mask; 13618 break; 13619 case RTE_FLOW_ITEM_TYPE_AH: 13620 mask = &rte_flow_item_ah_mask; 13621 break; 13622 case RTE_FLOW_ITEM_TYPE_PFCP: 13623 mask = &rte_flow_item_pfcp_mask; 13624 break; 13625 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 13626 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 13627 mask = &rte_flow_item_ethdev_mask; 13628 break; 13629 case RTE_FLOW_ITEM_TYPE_L2TPV2: 13630 mask = &rte_flow_item_l2tpv2_mask; 13631 break; 13632 case RTE_FLOW_ITEM_TYPE_PPP: 13633 mask = &rte_flow_item_ppp_mask; 13634 break; 13635 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 13636 mask = &rte_flow_item_meter_color_mask; 13637 break; 13638 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13639 mask = &ipv6_routing_ext_default_mask; 13640 break; 13641 case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: 13642 mask = &rte_flow_item_aggr_affinity_mask; 13643 break; 13644 case RTE_FLOW_ITEM_TYPE_TX_QUEUE: 13645 mask = &rte_flow_item_tx_queue_mask; 13646 break; 13647 case RTE_FLOW_ITEM_TYPE_IB_BTH: 13648 mask = &rte_flow_item_ib_bth_mask; 13649 break; 13650 case RTE_FLOW_ITEM_TYPE_PTYPE: 13651 mask = &rte_flow_item_ptype_mask; 13652 break; 13653 default: 13654 break; 13655 } 13656 return mask; 13657 } 13658 13659 /** Dispatch parsed buffer to function calls. */ 13660 static void 13661 cmd_set_ipv6_ext_parsed(const struct buffer *in) 13662 { 13663 uint32_t n = in->args.vc.pattern_n; 13664 int i = 0; 13665 struct rte_flow_item *item = NULL; 13666 size_t size = 0; 13667 uint8_t *data = NULL; 13668 uint8_t *type = NULL; 13669 size_t *total_size = NULL; 13670 uint16_t idx = in->port; /* We borrow port field as index */ 13671 struct rte_flow_item_ipv6_routing_ext *ext; 13672 const struct rte_flow_item_ipv6_ext *ipv6_ext; 13673 13674 RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || 13675 in->command == SET_IPV6_EXT_REMOVE); 13676 13677 if (in->command == SET_IPV6_EXT_REMOVE) { 13678 if (n != 1 || in->args.vc.pattern->type != 13679 RTE_FLOW_ITEM_TYPE_IPV6_EXT) { 13680 fprintf(stderr, "Error - Not supported item\n"); 13681 return; 13682 } 13683 type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; 13684 item = in->args.vc.pattern; 13685 ipv6_ext = item->spec; 13686 *type = ipv6_ext->next_hdr; 13687 return; 13688 } 13689 13690 total_size = &ipv6_ext_push_confs[idx].size; 13691 data = (uint8_t *)&ipv6_ext_push_confs[idx].data; 13692 type = (uint8_t *)&ipv6_ext_push_confs[idx].type; 13693 13694 *total_size = 0; 13695 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13696 for (i = n - 1 ; i >= 0; --i) { 13697 item = in->args.vc.pattern + i; 13698 switch (item->type) { 13699 case RTE_FLOW_ITEM_TYPE_IPV6_EXT: 13700 ipv6_ext = item->spec; 13701 *type = ipv6_ext->next_hdr; 13702 break; 13703 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13704 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13705 if (!ext->hdr.hdr_len) { 13706 size = sizeof(struct rte_ipv6_routing_ext) + 13707 (ext->hdr.segments_left << 4); 13708 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13709 /* Indicate no TLV once SRH. */ 13710 if (ext->hdr.type == 4) 13711 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13712 } else { 13713 size = sizeof(struct rte_ipv6_routing_ext) + 13714 (ext->hdr.hdr_len << 3); 13715 } 13716 *total_size += size; 13717 memcpy(data, ext, size); 13718 break; 13719 default: 13720 fprintf(stderr, "Error - Not supported item\n"); 13721 goto error; 13722 } 13723 } 13724 RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); 13725 return; 13726 error: 13727 *total_size = 0; 13728 memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); 13729 } 13730 13731 /** Dispatch parsed buffer to function calls. */ 13732 static void 13733 cmd_set_raw_parsed_sample(const struct buffer *in) 13734 { 13735 uint32_t n = in->args.vc.actions_n; 13736 uint32_t i = 0; 13737 struct rte_flow_action *action = NULL; 13738 struct rte_flow_action *data = NULL; 13739 const struct rte_flow_action_rss *rss = NULL; 13740 size_t size = 0; 13741 uint16_t idx = in->port; /* We borrow port field as index */ 13742 uint32_t max_size = sizeof(struct rte_flow_action) * 13743 ACTION_SAMPLE_ACTIONS_NUM; 13744 13745 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 13746 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 13747 memset(data, 0x00, max_size); 13748 for (; i <= n - 1; i++) { 13749 action = in->args.vc.actions + i; 13750 if (action->type == RTE_FLOW_ACTION_TYPE_END) 13751 break; 13752 switch (action->type) { 13753 case RTE_FLOW_ACTION_TYPE_MARK: 13754 size = sizeof(struct rte_flow_action_mark); 13755 rte_memcpy(&sample_mark[idx], 13756 (const void *)action->conf, size); 13757 action->conf = &sample_mark[idx]; 13758 break; 13759 case RTE_FLOW_ACTION_TYPE_COUNT: 13760 size = sizeof(struct rte_flow_action_count); 13761 rte_memcpy(&sample_count[idx], 13762 (const void *)action->conf, size); 13763 action->conf = &sample_count[idx]; 13764 break; 13765 case RTE_FLOW_ACTION_TYPE_QUEUE: 13766 size = sizeof(struct rte_flow_action_queue); 13767 rte_memcpy(&sample_queue[idx], 13768 (const void *)action->conf, size); 13769 action->conf = &sample_queue[idx]; 13770 break; 13771 case RTE_FLOW_ACTION_TYPE_RSS: 13772 size = sizeof(struct rte_flow_action_rss); 13773 rss = action->conf; 13774 rte_memcpy(&sample_rss_data[idx].conf, 13775 (const void *)rss, size); 13776 if (rss->key_len && rss->key) { 13777 sample_rss_data[idx].conf.key = 13778 sample_rss_data[idx].key; 13779 rte_memcpy((void *)((uintptr_t) 13780 sample_rss_data[idx].conf.key), 13781 (const void *)rss->key, 13782 sizeof(uint8_t) * rss->key_len); 13783 } 13784 if (rss->queue_num && rss->queue) { 13785 sample_rss_data[idx].conf.queue = 13786 sample_rss_data[idx].queue; 13787 rte_memcpy((void *)((uintptr_t) 13788 sample_rss_data[idx].conf.queue), 13789 (const void *)rss->queue, 13790 sizeof(uint16_t) * rss->queue_num); 13791 } 13792 action->conf = &sample_rss_data[idx].conf; 13793 break; 13794 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 13795 size = sizeof(struct rte_flow_action_raw_encap); 13796 rte_memcpy(&sample_encap[idx], 13797 (const void *)action->conf, size); 13798 action->conf = &sample_encap[idx]; 13799 break; 13800 case RTE_FLOW_ACTION_TYPE_PORT_ID: 13801 size = sizeof(struct rte_flow_action_port_id); 13802 rte_memcpy(&sample_port_id[idx], 13803 (const void *)action->conf, size); 13804 action->conf = &sample_port_id[idx]; 13805 break; 13806 case RTE_FLOW_ACTION_TYPE_PF: 13807 break; 13808 case RTE_FLOW_ACTION_TYPE_VF: 13809 size = sizeof(struct rte_flow_action_vf); 13810 rte_memcpy(&sample_vf[idx], 13811 (const void *)action->conf, size); 13812 action->conf = &sample_vf[idx]; 13813 break; 13814 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 13815 size = sizeof(struct rte_flow_action_vxlan_encap); 13816 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 13817 action->conf = &sample_vxlan_encap[idx].conf; 13818 break; 13819 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 13820 size = sizeof(struct rte_flow_action_nvgre_encap); 13821 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 13822 action->conf = &sample_nvgre_encap[idx]; 13823 break; 13824 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 13825 size = sizeof(struct rte_flow_action_ethdev); 13826 rte_memcpy(&sample_port_representor[idx], 13827 (const void *)action->conf, size); 13828 action->conf = &sample_port_representor[idx]; 13829 break; 13830 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 13831 size = sizeof(struct rte_flow_action_ethdev); 13832 rte_memcpy(&sample_represented_port[idx], 13833 (const void *)action->conf, size); 13834 action->conf = &sample_represented_port[idx]; 13835 break; 13836 default: 13837 fprintf(stderr, "Error - Not supported action\n"); 13838 return; 13839 } 13840 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 13841 data++; 13842 } 13843 } 13844 13845 /** Dispatch parsed buffer to function calls. */ 13846 static void 13847 cmd_set_raw_parsed(const struct buffer *in) 13848 { 13849 uint32_t n = in->args.vc.pattern_n; 13850 int i = 0; 13851 struct rte_flow_item *item = NULL; 13852 size_t size = 0; 13853 uint8_t *data = NULL; 13854 uint8_t *data_tail = NULL; 13855 size_t *total_size = NULL; 13856 uint16_t upper_layer = 0; 13857 uint16_t proto = 0; 13858 uint16_t idx = in->port; /* We borrow port field as index */ 13859 int gtp_psc = -1; /* GTP PSC option index. */ 13860 const void *src_spec; 13861 13862 if (in->command == SET_SAMPLE_ACTIONS) 13863 return cmd_set_raw_parsed_sample(in); 13864 else if (in->command == SET_IPV6_EXT_PUSH || 13865 in->command == SET_IPV6_EXT_REMOVE) 13866 return cmd_set_ipv6_ext_parsed(in); 13867 RTE_ASSERT(in->command == SET_RAW_ENCAP || 13868 in->command == SET_RAW_DECAP); 13869 if (in->command == SET_RAW_ENCAP) { 13870 total_size = &raw_encap_confs[idx].size; 13871 data = (uint8_t *)&raw_encap_confs[idx].data; 13872 } else { 13873 total_size = &raw_decap_confs[idx].size; 13874 data = (uint8_t *)&raw_decap_confs[idx].data; 13875 } 13876 *total_size = 0; 13877 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13878 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 13879 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 13880 for (i = n - 1 ; i >= 0; --i) { 13881 const struct rte_flow_item_gtp *gtp; 13882 const struct rte_flow_item_geneve_opt *opt; 13883 struct rte_flow_item_ipv6_routing_ext *ext; 13884 13885 item = in->args.vc.pattern + i; 13886 if (item->spec == NULL) 13887 item->spec = flow_item_default_mask(item); 13888 src_spec = item->spec; 13889 switch (item->type) { 13890 case RTE_FLOW_ITEM_TYPE_ETH: 13891 size = sizeof(struct rte_ether_hdr); 13892 break; 13893 case RTE_FLOW_ITEM_TYPE_VLAN: 13894 size = sizeof(struct rte_vlan_hdr); 13895 proto = RTE_ETHER_TYPE_VLAN; 13896 break; 13897 case RTE_FLOW_ITEM_TYPE_IPV4: 13898 size = sizeof(struct rte_ipv4_hdr); 13899 proto = RTE_ETHER_TYPE_IPV4; 13900 break; 13901 case RTE_FLOW_ITEM_TYPE_IPV6: 13902 size = sizeof(struct rte_ipv6_hdr); 13903 proto = RTE_ETHER_TYPE_IPV6; 13904 break; 13905 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13906 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13907 if (!ext->hdr.hdr_len) { 13908 size = sizeof(struct rte_ipv6_routing_ext) + 13909 (ext->hdr.segments_left << 4); 13910 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13911 /* SRv6 without TLV. */ 13912 if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) 13913 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13914 } else { 13915 size = sizeof(struct rte_ipv6_routing_ext) + 13916 (ext->hdr.hdr_len << 3); 13917 } 13918 proto = IPPROTO_ROUTING; 13919 break; 13920 case RTE_FLOW_ITEM_TYPE_UDP: 13921 size = sizeof(struct rte_udp_hdr); 13922 proto = 0x11; 13923 break; 13924 case RTE_FLOW_ITEM_TYPE_TCP: 13925 size = sizeof(struct rte_tcp_hdr); 13926 proto = 0x06; 13927 break; 13928 case RTE_FLOW_ITEM_TYPE_VXLAN: 13929 size = sizeof(struct rte_vxlan_hdr); 13930 break; 13931 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13932 size = sizeof(struct rte_vxlan_gpe_hdr); 13933 break; 13934 case RTE_FLOW_ITEM_TYPE_GRE: 13935 size = sizeof(struct rte_gre_hdr); 13936 proto = 0x2F; 13937 break; 13938 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13939 size = sizeof(rte_be32_t); 13940 proto = 0x0; 13941 break; 13942 case RTE_FLOW_ITEM_TYPE_MPLS: 13943 size = sizeof(struct rte_mpls_hdr); 13944 proto = 0x0; 13945 break; 13946 case RTE_FLOW_ITEM_TYPE_NVGRE: 13947 size = sizeof(struct rte_flow_item_nvgre); 13948 proto = 0x2F; 13949 break; 13950 case RTE_FLOW_ITEM_TYPE_GENEVE: 13951 size = sizeof(struct rte_geneve_hdr); 13952 break; 13953 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13954 opt = (const struct rte_flow_item_geneve_opt *) 13955 item->spec; 13956 size = offsetof(struct rte_flow_item_geneve_opt, 13957 option_len) + sizeof(uint8_t); 13958 if (opt->option_len && opt->data) { 13959 *total_size += opt->option_len * 13960 sizeof(uint32_t); 13961 rte_memcpy(data_tail - (*total_size), 13962 opt->data, 13963 opt->option_len * sizeof(uint32_t)); 13964 } 13965 break; 13966 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13967 size = sizeof(rte_be32_t); 13968 proto = 0x73; 13969 break; 13970 case RTE_FLOW_ITEM_TYPE_ESP: 13971 size = sizeof(struct rte_esp_hdr); 13972 proto = 0x32; 13973 break; 13974 case RTE_FLOW_ITEM_TYPE_AH: 13975 size = sizeof(struct rte_flow_item_ah); 13976 proto = 0x33; 13977 break; 13978 case RTE_FLOW_ITEM_TYPE_GTP: 13979 if (gtp_psc < 0) { 13980 size = sizeof(struct rte_gtp_hdr); 13981 break; 13982 } 13983 if (gtp_psc != i + 1) { 13984 fprintf(stderr, 13985 "Error - GTP PSC does not follow GTP\n"); 13986 goto error; 13987 } 13988 gtp = item->spec; 13989 if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { 13990 /* Only E flag should be set. */ 13991 fprintf(stderr, 13992 "Error - GTP unsupported flags\n"); 13993 goto error; 13994 } else { 13995 struct rte_gtp_hdr_ext_word ext_word = { 13996 .next_ext = 0x85 13997 }; 13998 13999 /* We have to add GTP header extra word. */ 14000 *total_size += sizeof(ext_word); 14001 rte_memcpy(data_tail - (*total_size), 14002 &ext_word, sizeof(ext_word)); 14003 } 14004 size = sizeof(struct rte_gtp_hdr); 14005 break; 14006 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 14007 if (gtp_psc >= 0) { 14008 fprintf(stderr, 14009 "Error - Multiple GTP PSC items\n"); 14010 goto error; 14011 } else { 14012 const struct rte_flow_item_gtp_psc 14013 *opt = item->spec; 14014 struct rte_gtp_psc_generic_hdr *hdr; 14015 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 14016 sizeof(int32_t)); 14017 14018 *total_size += hdr_size; 14019 hdr = (typeof(hdr))(data_tail - (*total_size)); 14020 memset(hdr, 0, hdr_size); 14021 *hdr = opt->hdr; 14022 hdr->ext_hdr_len = 1; 14023 gtp_psc = i; 14024 size = 0; 14025 } 14026 break; 14027 case RTE_FLOW_ITEM_TYPE_PFCP: 14028 size = sizeof(struct rte_flow_item_pfcp); 14029 break; 14030 case RTE_FLOW_ITEM_TYPE_FLEX: 14031 if (item->spec != NULL) { 14032 size = ((const struct rte_flow_item_flex *)item->spec)->length; 14033 src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; 14034 } else { 14035 size = 0; 14036 src_spec = NULL; 14037 } 14038 break; 14039 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 14040 size = 0; 14041 if (item->spec) { 14042 const struct rte_flow_item_gre_opt 14043 *opt = item->spec; 14044 if (opt->checksum_rsvd.checksum) { 14045 *total_size += 14046 sizeof(opt->checksum_rsvd); 14047 rte_memcpy(data_tail - (*total_size), 14048 &opt->checksum_rsvd, 14049 sizeof(opt->checksum_rsvd)); 14050 } 14051 if (opt->key.key) { 14052 *total_size += sizeof(opt->key.key); 14053 rte_memcpy(data_tail - (*total_size), 14054 &opt->key.key, 14055 sizeof(opt->key.key)); 14056 } 14057 if (opt->sequence.sequence) { 14058 *total_size += sizeof(opt->sequence.sequence); 14059 rte_memcpy(data_tail - (*total_size), 14060 &opt->sequence.sequence, 14061 sizeof(opt->sequence.sequence)); 14062 } 14063 } 14064 proto = 0x2F; 14065 break; 14066 default: 14067 fprintf(stderr, "Error - Not supported item\n"); 14068 goto error; 14069 } 14070 if (size) { 14071 *total_size += size; 14072 rte_memcpy(data_tail - (*total_size), src_spec, size); 14073 /* update some fields which cannot be set by cmdline */ 14074 update_fields((data_tail - (*total_size)), item, 14075 upper_layer); 14076 upper_layer = proto; 14077 } 14078 } 14079 if (verbose_level & 0x1) 14080 printf("total data size is %zu\n", (*total_size)); 14081 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 14082 memmove(data, (data_tail - (*total_size)), *total_size); 14083 return; 14084 14085 error: 14086 *total_size = 0; 14087 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 14088 } 14089 14090 /** Populate help strings for current token (cmdline API). */ 14091 static int 14092 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 14093 unsigned int size) 14094 { 14095 struct context *ctx = &cmd_flow_context; 14096 const struct token *token = &token_list[ctx->prev]; 14097 14098 (void)hdr; 14099 if (!size) 14100 return -1; 14101 /* Set token type and update global help with details. */ 14102 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 14103 if (token->help) 14104 cmd_set_raw.help_str = token->help; 14105 else 14106 cmd_set_raw.help_str = token->name; 14107 return 0; 14108 } 14109 14110 /** Token definition template (cmdline API). */ 14111 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 14112 .ops = &(struct cmdline_token_ops){ 14113 .parse = cmd_flow_parse, 14114 .complete_get_nb = cmd_flow_complete_get_nb, 14115 .complete_get_elt = cmd_flow_complete_get_elt, 14116 .get_help = cmd_set_raw_get_help, 14117 }, 14118 .offset = 0, 14119 }; 14120 14121 /** Populate the next dynamic token. */ 14122 static void 14123 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 14124 cmdline_parse_token_hdr_t **hdr_inst) 14125 { 14126 struct context *ctx = &cmd_flow_context; 14127 14128 /* Always reinitialize context before requesting the first token. */ 14129 if (!(hdr_inst - cmd_set_raw.tokens)) { 14130 cmd_flow_context_init(ctx); 14131 ctx->curr = START_SET; 14132 } 14133 /* Return NULL when no more tokens are expected. */ 14134 if (!ctx->next_num && (ctx->curr != START_SET)) { 14135 *hdr = NULL; 14136 return; 14137 } 14138 /* Determine if command should end here. */ 14139 if (ctx->eol && ctx->last && ctx->next_num) { 14140 const enum index *list = ctx->next[ctx->next_num - 1]; 14141 int i; 14142 14143 for (i = 0; list[i]; ++i) { 14144 if (list[i] != END) 14145 continue; 14146 *hdr = NULL; 14147 return; 14148 } 14149 } 14150 *hdr = &cmd_set_raw_token_hdr; 14151 } 14152 14153 /** Token generator and output processing callback (cmdline API). */ 14154 static void 14155 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 14156 { 14157 if (cl == NULL) 14158 cmd_set_raw_tok(arg0, arg2); 14159 else 14160 cmd_set_raw_parsed(arg0); 14161 } 14162 14163 /** Global parser instance (cmdline API). */ 14164 cmdline_parse_inst_t cmd_set_raw = { 14165 .f = cmd_set_raw_cb, 14166 .data = NULL, /**< Unused. */ 14167 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 14168 .tokens = { 14169 NULL, 14170 }, /**< Tokens are returned by cmd_flow_tok(). */ 14171 }; 14172 14173 /* *** display raw_encap/raw_decap buf */ 14174 struct cmd_show_set_raw_result { 14175 cmdline_fixed_string_t cmd_show; 14176 cmdline_fixed_string_t cmd_what; 14177 cmdline_fixed_string_t cmd_all; 14178 uint16_t cmd_index; 14179 }; 14180 14181 static void 14182 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 14183 { 14184 struct cmd_show_set_raw_result *res = parsed_result; 14185 uint16_t index = res->cmd_index; 14186 uint8_t all = 0; 14187 uint8_t *raw_data = NULL; 14188 size_t raw_size = 0; 14189 char title[16] = {0}; 14190 14191 RTE_SET_USED(cl); 14192 RTE_SET_USED(data); 14193 if (!strcmp(res->cmd_all, "all")) { 14194 all = 1; 14195 index = 0; 14196 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 14197 fprintf(stderr, "index should be 0-%u\n", 14198 RAW_ENCAP_CONFS_MAX_NUM - 1); 14199 return; 14200 } 14201 do { 14202 if (!strcmp(res->cmd_what, "raw_encap")) { 14203 raw_data = (uint8_t *)&raw_encap_confs[index].data; 14204 raw_size = raw_encap_confs[index].size; 14205 snprintf(title, 16, "\nindex: %u", index); 14206 rte_hexdump(stdout, title, raw_data, raw_size); 14207 } else { 14208 raw_data = (uint8_t *)&raw_decap_confs[index].data; 14209 raw_size = raw_decap_confs[index].size; 14210 snprintf(title, 16, "\nindex: %u", index); 14211 rte_hexdump(stdout, title, raw_data, raw_size); 14212 } 14213 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 14214 } 14215 14216 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 14217 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14218 cmd_show, "show"); 14219 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 14220 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14221 cmd_what, "raw_encap#raw_decap"); 14222 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 14223 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 14224 cmd_index, RTE_UINT16); 14225 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 14226 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14227 cmd_all, "all"); 14228 cmdline_parse_inst_t cmd_show_set_raw = { 14229 .f = cmd_show_set_raw_parsed, 14230 .data = NULL, 14231 .help_str = "show <raw_encap|raw_decap> <index>", 14232 .tokens = { 14233 (void *)&cmd_show_set_raw_cmd_show, 14234 (void *)&cmd_show_set_raw_cmd_what, 14235 (void *)&cmd_show_set_raw_cmd_index, 14236 NULL, 14237 }, 14238 }; 14239 cmdline_parse_inst_t cmd_show_set_raw_all = { 14240 .f = cmd_show_set_raw_parsed, 14241 .data = NULL, 14242 .help_str = "show <raw_encap|raw_decap> all", 14243 .tokens = { 14244 (void *)&cmd_show_set_raw_cmd_show, 14245 (void *)&cmd_show_set_raw_cmd_what, 14246 (void *)&cmd_show_set_raw_cmd_all, 14247 NULL, 14248 }, 14249 }; 14250