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 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 5867 item_param), 5868 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 5869 }, 5870 [ITEM_PORT_REPRESENTOR] = { 5871 .name = "port_representor", 5872 .help = "match traffic entering the embedded switch from the given ethdev", 5873 .priv = PRIV_ITEM(PORT_REPRESENTOR, 5874 sizeof(struct rte_flow_item_ethdev)), 5875 .next = NEXT(item_port_representor), 5876 .call = parse_vc, 5877 }, 5878 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 5879 .name = "port_id", 5880 .help = "ethdev port ID", 5881 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 5882 item_param), 5883 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5884 }, 5885 [ITEM_REPRESENTED_PORT] = { 5886 .name = "represented_port", 5887 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 5888 .priv = PRIV_ITEM(REPRESENTED_PORT, 5889 sizeof(struct rte_flow_item_ethdev)), 5890 .next = NEXT(item_represented_port), 5891 .call = parse_vc, 5892 }, 5893 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 5894 .name = "ethdev_port_id", 5895 .help = "ethdev port ID", 5896 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 5897 item_param), 5898 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5899 }, 5900 [ITEM_FLEX] = { 5901 .name = "flex", 5902 .help = "match flex header", 5903 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 5904 .next = NEXT(item_flex), 5905 .call = parse_vc, 5906 }, 5907 [ITEM_FLEX_ITEM_HANDLE] = { 5908 .name = "item", 5909 .help = "flex item handle", 5910 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5911 NEXT_ENTRY(ITEM_PARAM_IS)), 5912 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 5913 }, 5914 [ITEM_FLEX_PATTERN_HANDLE] = { 5915 .name = "pattern", 5916 .help = "flex pattern handle", 5917 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5918 NEXT_ENTRY(ITEM_PARAM_IS)), 5919 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 5920 }, 5921 [ITEM_L2TPV2] = { 5922 .name = "l2tpv2", 5923 .help = "match L2TPv2 header", 5924 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 5925 .next = NEXT(item_l2tpv2), 5926 .call = parse_vc, 5927 }, 5928 [ITEM_L2TPV2_TYPE] = { 5929 .name = "type", 5930 .help = "type of l2tpv2", 5931 .next = NEXT(item_l2tpv2_type), 5932 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 5933 }, 5934 [ITEM_L2TPV2_TYPE_DATA] = { 5935 .name = "data", 5936 .help = "Type #7: data message without any options", 5937 .next = NEXT(item_l2tpv2_type_data), 5938 .call = parse_vc_item_l2tpv2_type, 5939 }, 5940 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 5941 .name = "tunnel_id", 5942 .help = "tunnel identifier", 5943 .next = NEXT(item_l2tpv2_type_data, 5944 NEXT_ENTRY(COMMON_UNSIGNED), 5945 item_param), 5946 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5947 hdr.type7.tunnel_id)), 5948 }, 5949 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 5950 .name = "session_id", 5951 .help = "session identifier", 5952 .next = NEXT(item_l2tpv2_type_data, 5953 NEXT_ENTRY(COMMON_UNSIGNED), 5954 item_param), 5955 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5956 hdr.type7.session_id)), 5957 }, 5958 [ITEM_L2TPV2_TYPE_DATA_L] = { 5959 .name = "data_l", 5960 .help = "Type #6: data message with length option", 5961 .next = NEXT(item_l2tpv2_type_data_l), 5962 .call = parse_vc_item_l2tpv2_type, 5963 }, 5964 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 5965 .name = "length", 5966 .help = "message length", 5967 .next = NEXT(item_l2tpv2_type_data_l, 5968 NEXT_ENTRY(COMMON_UNSIGNED), 5969 item_param), 5970 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5971 hdr.type6.length)), 5972 }, 5973 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 5974 .name = "tunnel_id", 5975 .help = "tunnel identifier", 5976 .next = NEXT(item_l2tpv2_type_data_l, 5977 NEXT_ENTRY(COMMON_UNSIGNED), 5978 item_param), 5979 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5980 hdr.type6.tunnel_id)), 5981 }, 5982 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 5983 .name = "session_id", 5984 .help = "session identifier", 5985 .next = NEXT(item_l2tpv2_type_data_l, 5986 NEXT_ENTRY(COMMON_UNSIGNED), 5987 item_param), 5988 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5989 hdr.type6.session_id)), 5990 }, 5991 [ITEM_L2TPV2_TYPE_DATA_S] = { 5992 .name = "data_s", 5993 .help = "Type #5: data message with ns, nr option", 5994 .next = NEXT(item_l2tpv2_type_data_s), 5995 .call = parse_vc_item_l2tpv2_type, 5996 }, 5997 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 5998 .name = "tunnel_id", 5999 .help = "tunnel identifier", 6000 .next = NEXT(item_l2tpv2_type_data_s, 6001 NEXT_ENTRY(COMMON_UNSIGNED), 6002 item_param), 6003 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6004 hdr.type5.tunnel_id)), 6005 }, 6006 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 6007 .name = "session_id", 6008 .help = "session identifier", 6009 .next = NEXT(item_l2tpv2_type_data_s, 6010 NEXT_ENTRY(COMMON_UNSIGNED), 6011 item_param), 6012 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6013 hdr.type5.session_id)), 6014 }, 6015 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 6016 .name = "ns", 6017 .help = "sequence number for message", 6018 .next = NEXT(item_l2tpv2_type_data_s, 6019 NEXT_ENTRY(COMMON_UNSIGNED), 6020 item_param), 6021 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6022 hdr.type5.ns)), 6023 }, 6024 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 6025 .name = "nr", 6026 .help = "sequence number for next receive message", 6027 .next = NEXT(item_l2tpv2_type_data_s, 6028 NEXT_ENTRY(COMMON_UNSIGNED), 6029 item_param), 6030 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6031 hdr.type5.nr)), 6032 }, 6033 [ITEM_L2TPV2_TYPE_DATA_O] = { 6034 .name = "data_o", 6035 .help = "Type #4: data message with offset option", 6036 .next = NEXT(item_l2tpv2_type_data_o), 6037 .call = parse_vc_item_l2tpv2_type, 6038 }, 6039 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 6040 .name = "tunnel_id", 6041 .help = "tunnel identifier", 6042 .next = NEXT(item_l2tpv2_type_data_o, 6043 NEXT_ENTRY(COMMON_UNSIGNED), 6044 item_param), 6045 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6046 hdr.type4.tunnel_id)), 6047 }, 6048 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 6049 .name = "session_id", 6050 .help = "session identifier", 6051 .next = NEXT(item_l2tpv2_type_data_o, 6052 NEXT_ENTRY(COMMON_UNSIGNED), 6053 item_param), 6054 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6055 hdr.type5.session_id)), 6056 }, 6057 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 6058 .name = "offset_size", 6059 .help = "the size of offset padding", 6060 .next = NEXT(item_l2tpv2_type_data_o, 6061 NEXT_ENTRY(COMMON_UNSIGNED), 6062 item_param), 6063 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6064 hdr.type4.offset_size)), 6065 }, 6066 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 6067 .name = "data_l_s", 6068 .help = "Type #3: data message contains length, ns, nr " 6069 "options", 6070 .next = NEXT(item_l2tpv2_type_data_l_s), 6071 .call = parse_vc_item_l2tpv2_type, 6072 }, 6073 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 6074 .name = "length", 6075 .help = "message length", 6076 .next = NEXT(item_l2tpv2_type_data_l_s, 6077 NEXT_ENTRY(COMMON_UNSIGNED), 6078 item_param), 6079 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6080 hdr.type3.length)), 6081 }, 6082 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 6083 .name = "tunnel_id", 6084 .help = "tunnel identifier", 6085 .next = NEXT(item_l2tpv2_type_data_l_s, 6086 NEXT_ENTRY(COMMON_UNSIGNED), 6087 item_param), 6088 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6089 hdr.type3.tunnel_id)), 6090 }, 6091 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 6092 .name = "session_id", 6093 .help = "session identifier", 6094 .next = NEXT(item_l2tpv2_type_data_l_s, 6095 NEXT_ENTRY(COMMON_UNSIGNED), 6096 item_param), 6097 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6098 hdr.type3.session_id)), 6099 }, 6100 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 6101 .name = "ns", 6102 .help = "sequence number for message", 6103 .next = NEXT(item_l2tpv2_type_data_l_s, 6104 NEXT_ENTRY(COMMON_UNSIGNED), 6105 item_param), 6106 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6107 hdr.type3.ns)), 6108 }, 6109 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 6110 .name = "nr", 6111 .help = "sequence number for next receive message", 6112 .next = NEXT(item_l2tpv2_type_data_l_s, 6113 NEXT_ENTRY(COMMON_UNSIGNED), 6114 item_param), 6115 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6116 hdr.type3.nr)), 6117 }, 6118 [ITEM_L2TPV2_TYPE_CTRL] = { 6119 .name = "control", 6120 .help = "Type #3: conrtol message contains length, ns, nr " 6121 "options", 6122 .next = NEXT(item_l2tpv2_type_ctrl), 6123 .call = parse_vc_item_l2tpv2_type, 6124 }, 6125 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 6126 .name = "length", 6127 .help = "message length", 6128 .next = NEXT(item_l2tpv2_type_ctrl, 6129 NEXT_ENTRY(COMMON_UNSIGNED), 6130 item_param), 6131 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6132 hdr.type3.length)), 6133 }, 6134 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 6135 .name = "tunnel_id", 6136 .help = "tunnel identifier", 6137 .next = NEXT(item_l2tpv2_type_ctrl, 6138 NEXT_ENTRY(COMMON_UNSIGNED), 6139 item_param), 6140 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6141 hdr.type3.tunnel_id)), 6142 }, 6143 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 6144 .name = "session_id", 6145 .help = "session identifier", 6146 .next = NEXT(item_l2tpv2_type_ctrl, 6147 NEXT_ENTRY(COMMON_UNSIGNED), 6148 item_param), 6149 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6150 hdr.type3.session_id)), 6151 }, 6152 [ITEM_L2TPV2_MSG_CTRL_NS] = { 6153 .name = "ns", 6154 .help = "sequence number for message", 6155 .next = NEXT(item_l2tpv2_type_ctrl, 6156 NEXT_ENTRY(COMMON_UNSIGNED), 6157 item_param), 6158 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6159 hdr.type3.ns)), 6160 }, 6161 [ITEM_L2TPV2_MSG_CTRL_NR] = { 6162 .name = "nr", 6163 .help = "sequence number for next receive message", 6164 .next = NEXT(item_l2tpv2_type_ctrl, 6165 NEXT_ENTRY(COMMON_UNSIGNED), 6166 item_param), 6167 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6168 hdr.type3.nr)), 6169 }, 6170 [ITEM_PPP] = { 6171 .name = "ppp", 6172 .help = "match PPP header", 6173 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 6174 .next = NEXT(item_ppp), 6175 .call = parse_vc, 6176 }, 6177 [ITEM_PPP_ADDR] = { 6178 .name = "addr", 6179 .help = "PPP address", 6180 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6181 item_param), 6182 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 6183 }, 6184 [ITEM_PPP_CTRL] = { 6185 .name = "ctrl", 6186 .help = "PPP control", 6187 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6188 item_param), 6189 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 6190 }, 6191 [ITEM_PPP_PROTO_ID] = { 6192 .name = "proto_id", 6193 .help = "PPP protocol identifier", 6194 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6195 item_param), 6196 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 6197 hdr.proto_id)), 6198 }, 6199 [ITEM_METER] = { 6200 .name = "meter", 6201 .help = "match meter color", 6202 .priv = PRIV_ITEM(METER_COLOR, 6203 sizeof(struct rte_flow_item_meter_color)), 6204 .next = NEXT(item_meter), 6205 .call = parse_vc, 6206 }, 6207 [ITEM_METER_COLOR] = { 6208 .name = "color", 6209 .help = "meter color", 6210 .next = NEXT(item_meter, 6211 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 6212 item_param), 6213 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 6214 color)), 6215 }, 6216 [ITEM_METER_COLOR_NAME] = { 6217 .name = "color_name", 6218 .help = "meter color name", 6219 .call = parse_meter_color, 6220 .comp = comp_meter_color, 6221 }, 6222 [ITEM_QUOTA] = { 6223 .name = "quota", 6224 .help = "match quota", 6225 .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), 6226 .next = NEXT(item_quota), 6227 .call = parse_vc 6228 }, 6229 [ITEM_QUOTA_STATE] = { 6230 .name = "quota_state", 6231 .help = "quota state", 6232 .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), 6233 NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), 6234 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) 6235 }, 6236 [ITEM_QUOTA_STATE_NAME] = { 6237 .name = "state_name", 6238 .help = "quota state name", 6239 .call = parse_quota_state_name, 6240 .comp = comp_quota_state_name 6241 }, 6242 [ITEM_IB_BTH] = { 6243 .name = "ib_bth", 6244 .help = "match ib bth fields", 6245 .priv = PRIV_ITEM(IB_BTH, 6246 sizeof(struct rte_flow_item_ib_bth)), 6247 .next = NEXT(item_ib_bth), 6248 .call = parse_vc, 6249 }, 6250 [ITEM_IB_BTH_OPCODE] = { 6251 .name = "opcode", 6252 .help = "match ib bth opcode", 6253 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6254 item_param), 6255 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6256 hdr.opcode)), 6257 }, 6258 [ITEM_IB_BTH_PKEY] = { 6259 .name = "pkey", 6260 .help = "partition key", 6261 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6262 item_param), 6263 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6264 hdr.pkey)), 6265 }, 6266 [ITEM_IB_BTH_DST_QPN] = { 6267 .name = "dst_qp", 6268 .help = "destination qp", 6269 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6270 item_param), 6271 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6272 hdr.dst_qp)), 6273 }, 6274 [ITEM_IB_BTH_PSN] = { 6275 .name = "psn", 6276 .help = "packet sequence number", 6277 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6278 item_param), 6279 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6280 hdr.psn)), 6281 }, 6282 [ITEM_PTYPE] = { 6283 .name = "ptype", 6284 .help = "match L2/L3/L4 and tunnel information", 6285 .priv = PRIV_ITEM(PTYPE, 6286 sizeof(struct rte_flow_item_ptype)), 6287 .next = NEXT(item_ptype), 6288 .call = parse_vc, 6289 }, 6290 [ITEM_PTYPE_VALUE] = { 6291 .name = "packet_type", 6292 .help = "packet type as defined in rte_mbuf_ptype", 6293 .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), 6294 item_param), 6295 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), 6296 }, 6297 [ITEM_NSH] = { 6298 .name = "nsh", 6299 .help = "match NSH header", 6300 .priv = PRIV_ITEM(NSH, 6301 sizeof(struct rte_flow_item_nsh)), 6302 .next = NEXT(item_nsh), 6303 .call = parse_vc, 6304 }, 6305 [ITEM_COMPARE] = { 6306 .name = "compare", 6307 .help = "match with the comparison result", 6308 .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)), 6309 .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)), 6310 .call = parse_vc, 6311 }, 6312 [ITEM_COMPARE_OP] = { 6313 .name = "op", 6314 .help = "operation type", 6315 .next = NEXT(item_compare_field, 6316 NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param), 6317 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)), 6318 }, 6319 [ITEM_COMPARE_OP_VALUE] = { 6320 .name = "{operation}", 6321 .help = "operation type value", 6322 .call = parse_vc_compare_op, 6323 .comp = comp_set_compare_op, 6324 }, 6325 [ITEM_COMPARE_FIELD_A_TYPE] = { 6326 .name = "a_type", 6327 .help = "compared field type", 6328 .next = NEXT(compare_field_a, 6329 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param), 6330 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)), 6331 }, 6332 [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = { 6333 .name = "{a_type}", 6334 .help = "compared field type value", 6335 .call = parse_vc_compare_field_id, 6336 .comp = comp_set_compare_field_id, 6337 }, 6338 [ITEM_COMPARE_FIELD_A_LEVEL] = { 6339 .name = "a_level", 6340 .help = "compared field level", 6341 .next = NEXT(compare_field_a, 6342 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param), 6343 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)), 6344 }, 6345 [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = { 6346 .name = "{a_level}", 6347 .help = "compared field level value", 6348 .call = parse_vc_compare_field_level, 6349 .comp = comp_none, 6350 }, 6351 [ITEM_COMPARE_FIELD_A_TAG_INDEX] = { 6352 .name = "a_tag_index", 6353 .help = "compared field tag array", 6354 .next = NEXT(compare_field_a, 6355 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6356 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6357 a.tag_index)), 6358 }, 6359 [ITEM_COMPARE_FIELD_A_TYPE_ID] = { 6360 .name = "a_type_id", 6361 .help = "compared field type ID", 6362 .next = NEXT(compare_field_a, 6363 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6364 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6365 a.type)), 6366 }, 6367 [ITEM_COMPARE_FIELD_A_CLASS_ID] = { 6368 .name = "a_class", 6369 .help = "compared field class ID", 6370 .next = NEXT(compare_field_a, 6371 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6372 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6373 a.class_id)), 6374 }, 6375 [ITEM_COMPARE_FIELD_A_OFFSET] = { 6376 .name = "a_offset", 6377 .help = "compared field bit offset", 6378 .next = NEXT(compare_field_a, 6379 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6380 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6381 a.offset)), 6382 }, 6383 [ITEM_COMPARE_FIELD_B_TYPE] = { 6384 .name = "b_type", 6385 .help = "comparator field type", 6386 .next = NEXT(compare_field_b, 6387 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param), 6388 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6389 b.field)), 6390 }, 6391 [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = { 6392 .name = "{b_type}", 6393 .help = "comparator field type value", 6394 .call = parse_vc_compare_field_id, 6395 .comp = comp_set_compare_field_id, 6396 }, 6397 [ITEM_COMPARE_FIELD_B_LEVEL] = { 6398 .name = "b_level", 6399 .help = "comparator field level", 6400 .next = NEXT(compare_field_b, 6401 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param), 6402 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6403 b.level)), 6404 }, 6405 [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = { 6406 .name = "{b_level}", 6407 .help = "comparator field level value", 6408 .call = parse_vc_compare_field_level, 6409 .comp = comp_none, 6410 }, 6411 [ITEM_COMPARE_FIELD_B_TAG_INDEX] = { 6412 .name = "b_tag_index", 6413 .help = "comparator field tag array", 6414 .next = NEXT(compare_field_b, 6415 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6416 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6417 b.tag_index)), 6418 }, 6419 [ITEM_COMPARE_FIELD_B_TYPE_ID] = { 6420 .name = "b_type_id", 6421 .help = "comparator field type ID", 6422 .next = NEXT(compare_field_b, 6423 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6424 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6425 b.type)), 6426 }, 6427 [ITEM_COMPARE_FIELD_B_CLASS_ID] = { 6428 .name = "b_class", 6429 .help = "comparator field class ID", 6430 .next = NEXT(compare_field_b, 6431 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6432 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6433 b.class_id)), 6434 }, 6435 [ITEM_COMPARE_FIELD_B_OFFSET] = { 6436 .name = "b_offset", 6437 .help = "comparator field bit offset", 6438 .next = NEXT(compare_field_b, 6439 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6440 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6441 b.offset)), 6442 }, 6443 [ITEM_COMPARE_FIELD_B_VALUE] = { 6444 .name = "b_value", 6445 .help = "comparator immediate value", 6446 .next = NEXT(compare_field_b, 6447 NEXT_ENTRY(COMMON_HEX), item_param), 6448 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6449 ARGS_ENTRY_ARB(0, 0), 6450 ARGS_ENTRY(struct rte_flow_item_compare, 6451 b.value)), 6452 }, 6453 [ITEM_COMPARE_FIELD_B_POINTER] = { 6454 .name = "b_ptr", 6455 .help = "pointer to comparator immediate value", 6456 .next = NEXT(compare_field_b, 6457 NEXT_ENTRY(COMMON_HEX), item_param), 6458 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6459 b.pvalue), 6460 ARGS_ENTRY_ARB(0, 0), 6461 ARGS_ENTRY_ARB 6462 (sizeof(struct rte_flow_item_compare), 6463 FLOW_FIELD_PATTERN_SIZE)), 6464 }, 6465 [ITEM_COMPARE_FIELD_WIDTH] = { 6466 .name = "width", 6467 .help = "number of bits to compare", 6468 .next = NEXT(item_compare_field, 6469 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6470 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6471 width)), 6472 }, 6473 6474 /* Validate/create actions. */ 6475 [ACTIONS] = { 6476 .name = "actions", 6477 .help = "submit a list of associated actions", 6478 .next = NEXT(next_action), 6479 .call = parse_vc, 6480 }, 6481 [ACTION_NEXT] = { 6482 .name = "/", 6483 .help = "specify next action", 6484 .next = NEXT(next_action), 6485 }, 6486 [ACTION_END] = { 6487 .name = "end", 6488 .help = "end list of actions", 6489 .priv = PRIV_ACTION(END, 0), 6490 .call = parse_vc, 6491 }, 6492 [ACTION_VOID] = { 6493 .name = "void", 6494 .help = "no-op action", 6495 .priv = PRIV_ACTION(VOID, 0), 6496 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6497 .call = parse_vc, 6498 }, 6499 [ACTION_PASSTHRU] = { 6500 .name = "passthru", 6501 .help = "let subsequent rule process matched packets", 6502 .priv = PRIV_ACTION(PASSTHRU, 0), 6503 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6504 .call = parse_vc, 6505 }, 6506 [ACTION_SKIP_CMAN] = { 6507 .name = "skip_cman", 6508 .help = "bypass cman on received packets", 6509 .priv = PRIV_ACTION(SKIP_CMAN, 0), 6510 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6511 .call = parse_vc, 6512 }, 6513 [ACTION_JUMP] = { 6514 .name = "jump", 6515 .help = "redirect traffic to a given group", 6516 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 6517 .next = NEXT(action_jump), 6518 .call = parse_vc, 6519 }, 6520 [ACTION_JUMP_GROUP] = { 6521 .name = "group", 6522 .help = "group to redirect traffic to", 6523 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 6524 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 6525 .call = parse_vc_conf, 6526 }, 6527 [ACTION_MARK] = { 6528 .name = "mark", 6529 .help = "attach 32 bit value to packets", 6530 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 6531 .next = NEXT(action_mark), 6532 .call = parse_vc, 6533 }, 6534 [ACTION_MARK_ID] = { 6535 .name = "id", 6536 .help = "32 bit value to return with packets", 6537 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6538 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 6539 .call = parse_vc_conf, 6540 }, 6541 [ACTION_FLAG] = { 6542 .name = "flag", 6543 .help = "flag packets", 6544 .priv = PRIV_ACTION(FLAG, 0), 6545 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6546 .call = parse_vc, 6547 }, 6548 [ACTION_QUEUE] = { 6549 .name = "queue", 6550 .help = "assign packets to a given queue index", 6551 .priv = PRIV_ACTION(QUEUE, 6552 sizeof(struct rte_flow_action_queue)), 6553 .next = NEXT(action_queue), 6554 .call = parse_vc, 6555 }, 6556 [ACTION_QUEUE_INDEX] = { 6557 .name = "index", 6558 .help = "queue index to use", 6559 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 6560 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 6561 .call = parse_vc_conf, 6562 }, 6563 [ACTION_DROP] = { 6564 .name = "drop", 6565 .help = "drop packets (note: passthru has priority)", 6566 .priv = PRIV_ACTION(DROP, 0), 6567 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6568 .call = parse_vc, 6569 }, 6570 [ACTION_COUNT] = { 6571 .name = "count", 6572 .help = "enable counters for this rule", 6573 .priv = PRIV_ACTION(COUNT, 6574 sizeof(struct rte_flow_action_count)), 6575 .next = NEXT(action_count), 6576 .call = parse_vc, 6577 }, 6578 [ACTION_COUNT_ID] = { 6579 .name = "identifier", 6580 .help = "counter identifier to use", 6581 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 6582 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 6583 .call = parse_vc_conf, 6584 }, 6585 [ACTION_RSS] = { 6586 .name = "rss", 6587 .help = "spread packets among several queues", 6588 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 6589 .next = NEXT(action_rss), 6590 .call = parse_vc_action_rss, 6591 }, 6592 [ACTION_RSS_FUNC] = { 6593 .name = "func", 6594 .help = "RSS hash function to apply", 6595 .next = NEXT(action_rss, 6596 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 6597 ACTION_RSS_FUNC_TOEPLITZ, 6598 ACTION_RSS_FUNC_SIMPLE_XOR, 6599 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 6600 }, 6601 [ACTION_RSS_FUNC_DEFAULT] = { 6602 .name = "default", 6603 .help = "default hash function", 6604 .call = parse_vc_action_rss_func, 6605 }, 6606 [ACTION_RSS_FUNC_TOEPLITZ] = { 6607 .name = "toeplitz", 6608 .help = "Toeplitz hash function", 6609 .call = parse_vc_action_rss_func, 6610 }, 6611 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 6612 .name = "simple_xor", 6613 .help = "simple XOR hash function", 6614 .call = parse_vc_action_rss_func, 6615 }, 6616 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 6617 .name = "symmetric_toeplitz", 6618 .help = "Symmetric Toeplitz hash function", 6619 .call = parse_vc_action_rss_func, 6620 }, 6621 [ACTION_RSS_LEVEL] = { 6622 .name = "level", 6623 .help = "encapsulation level for \"types\"", 6624 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6625 .args = ARGS(ARGS_ENTRY_ARB 6626 (offsetof(struct action_rss_data, conf) + 6627 offsetof(struct rte_flow_action_rss, level), 6628 sizeof(((struct rte_flow_action_rss *)0)-> 6629 level))), 6630 }, 6631 [ACTION_RSS_TYPES] = { 6632 .name = "types", 6633 .help = "specific RSS hash types", 6634 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 6635 }, 6636 [ACTION_RSS_TYPE] = { 6637 .name = "{type}", 6638 .help = "RSS hash type", 6639 .call = parse_vc_action_rss_type, 6640 .comp = comp_vc_action_rss_type, 6641 }, 6642 [ACTION_RSS_KEY] = { 6643 .name = "key", 6644 .help = "RSS hash key", 6645 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 6646 .args = ARGS(ARGS_ENTRY_ARB 6647 (offsetof(struct action_rss_data, conf) + 6648 offsetof(struct rte_flow_action_rss, key), 6649 sizeof(((struct rte_flow_action_rss *)0)->key)), 6650 ARGS_ENTRY_ARB 6651 (offsetof(struct action_rss_data, conf) + 6652 offsetof(struct rte_flow_action_rss, key_len), 6653 sizeof(((struct rte_flow_action_rss *)0)-> 6654 key_len)), 6655 ARGS_ENTRY(struct action_rss_data, key)), 6656 }, 6657 [ACTION_RSS_KEY_LEN] = { 6658 .name = "key_len", 6659 .help = "RSS hash key length in bytes", 6660 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6661 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6662 (offsetof(struct action_rss_data, conf) + 6663 offsetof(struct rte_flow_action_rss, key_len), 6664 sizeof(((struct rte_flow_action_rss *)0)-> 6665 key_len), 6666 0, 6667 RSS_HASH_KEY_LENGTH)), 6668 }, 6669 [ACTION_RSS_QUEUES] = { 6670 .name = "queues", 6671 .help = "queue indices to use", 6672 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 6673 .call = parse_vc_conf, 6674 }, 6675 [ACTION_RSS_QUEUE] = { 6676 .name = "{queue}", 6677 .help = "queue index", 6678 .call = parse_vc_action_rss_queue, 6679 .comp = comp_vc_action_rss_queue, 6680 }, 6681 [ACTION_PF] = { 6682 .name = "pf", 6683 .help = "direct traffic to physical function", 6684 .priv = PRIV_ACTION(PF, 0), 6685 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6686 .call = parse_vc, 6687 }, 6688 [ACTION_VF] = { 6689 .name = "vf", 6690 .help = "direct traffic to a virtual function ID", 6691 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 6692 .next = NEXT(action_vf), 6693 .call = parse_vc, 6694 }, 6695 [ACTION_VF_ORIGINAL] = { 6696 .name = "original", 6697 .help = "use original VF ID if possible", 6698 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 6699 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 6700 original, 1)), 6701 .call = parse_vc_conf, 6702 }, 6703 [ACTION_VF_ID] = { 6704 .name = "id", 6705 .help = "VF ID", 6706 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 6707 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 6708 .call = parse_vc_conf, 6709 }, 6710 [ACTION_PORT_ID] = { 6711 .name = "port_id", 6712 .help = "direct matching traffic to a given DPDK port ID", 6713 .priv = PRIV_ACTION(PORT_ID, 6714 sizeof(struct rte_flow_action_port_id)), 6715 .next = NEXT(action_port_id), 6716 .call = parse_vc, 6717 }, 6718 [ACTION_PORT_ID_ORIGINAL] = { 6719 .name = "original", 6720 .help = "use original DPDK port ID if possible", 6721 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 6722 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 6723 original, 1)), 6724 .call = parse_vc_conf, 6725 }, 6726 [ACTION_PORT_ID_ID] = { 6727 .name = "id", 6728 .help = "DPDK port ID", 6729 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 6730 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 6731 .call = parse_vc_conf, 6732 }, 6733 [ACTION_METER] = { 6734 .name = "meter", 6735 .help = "meter the directed packets at given id", 6736 .priv = PRIV_ACTION(METER, 6737 sizeof(struct rte_flow_action_meter)), 6738 .next = NEXT(action_meter), 6739 .call = parse_vc, 6740 }, 6741 [ACTION_METER_COLOR] = { 6742 .name = "color", 6743 .help = "meter color for the packets", 6744 .priv = PRIV_ACTION(METER_COLOR, 6745 sizeof(struct rte_flow_action_meter_color)), 6746 .next = NEXT(action_meter_color), 6747 .call = parse_vc, 6748 }, 6749 [ACTION_METER_COLOR_TYPE] = { 6750 .name = "type", 6751 .help = "specific meter color", 6752 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6753 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 6754 ACTION_METER_COLOR_YELLOW, 6755 ACTION_METER_COLOR_RED)), 6756 }, 6757 [ACTION_METER_COLOR_GREEN] = { 6758 .name = "green", 6759 .help = "meter color green", 6760 .call = parse_vc_action_meter_color_type, 6761 }, 6762 [ACTION_METER_COLOR_YELLOW] = { 6763 .name = "yellow", 6764 .help = "meter color yellow", 6765 .call = parse_vc_action_meter_color_type, 6766 }, 6767 [ACTION_METER_COLOR_RED] = { 6768 .name = "red", 6769 .help = "meter color red", 6770 .call = parse_vc_action_meter_color_type, 6771 }, 6772 [ACTION_METER_ID] = { 6773 .name = "mtr_id", 6774 .help = "meter id to use", 6775 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 6776 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 6777 .call = parse_vc_conf, 6778 }, 6779 [ACTION_METER_MARK] = { 6780 .name = "meter_mark", 6781 .help = "meter the directed packets using profile and policy", 6782 .priv = PRIV_ACTION(METER_MARK, 6783 sizeof(struct rte_flow_action_meter_mark)), 6784 .next = NEXT(action_meter_mark), 6785 .call = parse_vc, 6786 }, 6787 [ACTION_METER_PROFILE] = { 6788 .name = "mtr_profile", 6789 .help = "meter profile id to use", 6790 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 6791 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6792 }, 6793 [ACTION_METER_PROFILE_ID2PTR] = { 6794 .name = "{mtr_profile_id}", 6795 .type = "PROFILE_ID", 6796 .help = "meter profile id", 6797 .next = NEXT(action_meter_mark), 6798 .call = parse_meter_profile_id2ptr, 6799 .comp = comp_none, 6800 }, 6801 [ACTION_METER_POLICY] = { 6802 .name = "mtr_policy", 6803 .help = "meter policy id to use", 6804 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 6805 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6806 }, 6807 [ACTION_METER_POLICY_ID2PTR] = { 6808 .name = "{mtr_policy_id}", 6809 .type = "POLICY_ID", 6810 .help = "meter policy id", 6811 .next = NEXT(action_meter_mark), 6812 .call = parse_meter_policy_id2ptr, 6813 .comp = comp_none, 6814 }, 6815 [ACTION_METER_COLOR_MODE] = { 6816 .name = "mtr_color_mode", 6817 .help = "meter color awareness mode", 6818 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6819 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 6820 .call = parse_vc_conf, 6821 }, 6822 [ACTION_METER_STATE] = { 6823 .name = "mtr_state", 6824 .help = "meter state", 6825 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6826 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 6827 .call = parse_vc_conf, 6828 }, 6829 [ACTION_OF_DEC_NW_TTL] = { 6830 .name = "of_dec_nw_ttl", 6831 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 6832 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 6833 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6834 .call = parse_vc, 6835 }, 6836 [ACTION_OF_POP_VLAN] = { 6837 .name = "of_pop_vlan", 6838 .help = "OpenFlow's OFPAT_POP_VLAN", 6839 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 6840 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6841 .call = parse_vc, 6842 }, 6843 [ACTION_OF_PUSH_VLAN] = { 6844 .name = "of_push_vlan", 6845 .help = "OpenFlow's OFPAT_PUSH_VLAN", 6846 .priv = PRIV_ACTION 6847 (OF_PUSH_VLAN, 6848 sizeof(struct rte_flow_action_of_push_vlan)), 6849 .next = NEXT(action_of_push_vlan), 6850 .call = parse_vc, 6851 }, 6852 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 6853 .name = "ethertype", 6854 .help = "EtherType", 6855 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 6856 .args = ARGS(ARGS_ENTRY_HTON 6857 (struct rte_flow_action_of_push_vlan, 6858 ethertype)), 6859 .call = parse_vc_conf, 6860 }, 6861 [ACTION_OF_SET_VLAN_VID] = { 6862 .name = "of_set_vlan_vid", 6863 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 6864 .priv = PRIV_ACTION 6865 (OF_SET_VLAN_VID, 6866 sizeof(struct rte_flow_action_of_set_vlan_vid)), 6867 .next = NEXT(action_of_set_vlan_vid), 6868 .call = parse_vc, 6869 }, 6870 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 6871 .name = "vlan_vid", 6872 .help = "VLAN id", 6873 .next = NEXT(action_of_set_vlan_vid, 6874 NEXT_ENTRY(COMMON_UNSIGNED)), 6875 .args = ARGS(ARGS_ENTRY_HTON 6876 (struct rte_flow_action_of_set_vlan_vid, 6877 vlan_vid)), 6878 .call = parse_vc_conf, 6879 }, 6880 [ACTION_OF_SET_VLAN_PCP] = { 6881 .name = "of_set_vlan_pcp", 6882 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 6883 .priv = PRIV_ACTION 6884 (OF_SET_VLAN_PCP, 6885 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 6886 .next = NEXT(action_of_set_vlan_pcp), 6887 .call = parse_vc, 6888 }, 6889 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 6890 .name = "vlan_pcp", 6891 .help = "VLAN priority", 6892 .next = NEXT(action_of_set_vlan_pcp, 6893 NEXT_ENTRY(COMMON_UNSIGNED)), 6894 .args = ARGS(ARGS_ENTRY_HTON 6895 (struct rte_flow_action_of_set_vlan_pcp, 6896 vlan_pcp)), 6897 .call = parse_vc_conf, 6898 }, 6899 [ACTION_OF_POP_MPLS] = { 6900 .name = "of_pop_mpls", 6901 .help = "OpenFlow's OFPAT_POP_MPLS", 6902 .priv = PRIV_ACTION(OF_POP_MPLS, 6903 sizeof(struct rte_flow_action_of_pop_mpls)), 6904 .next = NEXT(action_of_pop_mpls), 6905 .call = parse_vc, 6906 }, 6907 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 6908 .name = "ethertype", 6909 .help = "EtherType", 6910 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6911 .args = ARGS(ARGS_ENTRY_HTON 6912 (struct rte_flow_action_of_pop_mpls, 6913 ethertype)), 6914 .call = parse_vc_conf, 6915 }, 6916 [ACTION_OF_PUSH_MPLS] = { 6917 .name = "of_push_mpls", 6918 .help = "OpenFlow's OFPAT_PUSH_MPLS", 6919 .priv = PRIV_ACTION 6920 (OF_PUSH_MPLS, 6921 sizeof(struct rte_flow_action_of_push_mpls)), 6922 .next = NEXT(action_of_push_mpls), 6923 .call = parse_vc, 6924 }, 6925 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 6926 .name = "ethertype", 6927 .help = "EtherType", 6928 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6929 .args = ARGS(ARGS_ENTRY_HTON 6930 (struct rte_flow_action_of_push_mpls, 6931 ethertype)), 6932 .call = parse_vc_conf, 6933 }, 6934 [ACTION_VXLAN_ENCAP] = { 6935 .name = "vxlan_encap", 6936 .help = "VXLAN encapsulation, uses configuration set by \"set" 6937 " vxlan\"", 6938 .priv = PRIV_ACTION(VXLAN_ENCAP, 6939 sizeof(struct action_vxlan_encap_data)), 6940 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6941 .call = parse_vc_action_vxlan_encap, 6942 }, 6943 [ACTION_VXLAN_DECAP] = { 6944 .name = "vxlan_decap", 6945 .help = "Performs a decapsulation action by stripping all" 6946 " headers of the VXLAN tunnel network overlay from the" 6947 " matched flow.", 6948 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 6949 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6950 .call = parse_vc, 6951 }, 6952 [ACTION_NVGRE_ENCAP] = { 6953 .name = "nvgre_encap", 6954 .help = "NVGRE encapsulation, uses configuration set by \"set" 6955 " nvgre\"", 6956 .priv = PRIV_ACTION(NVGRE_ENCAP, 6957 sizeof(struct action_nvgre_encap_data)), 6958 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6959 .call = parse_vc_action_nvgre_encap, 6960 }, 6961 [ACTION_NVGRE_DECAP] = { 6962 .name = "nvgre_decap", 6963 .help = "Performs a decapsulation action by stripping all" 6964 " headers of the NVGRE tunnel network overlay from the" 6965 " matched flow.", 6966 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 6967 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6968 .call = parse_vc, 6969 }, 6970 [ACTION_L2_ENCAP] = { 6971 .name = "l2_encap", 6972 .help = "l2 encap, uses configuration set by" 6973 " \"set l2_encap\"", 6974 .priv = PRIV_ACTION(RAW_ENCAP, 6975 sizeof(struct action_raw_encap_data)), 6976 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6977 .call = parse_vc_action_l2_encap, 6978 }, 6979 [ACTION_L2_DECAP] = { 6980 .name = "l2_decap", 6981 .help = "l2 decap, uses configuration set by" 6982 " \"set l2_decap\"", 6983 .priv = PRIV_ACTION(RAW_DECAP, 6984 sizeof(struct action_raw_decap_data)), 6985 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6986 .call = parse_vc_action_l2_decap, 6987 }, 6988 [ACTION_MPLSOGRE_ENCAP] = { 6989 .name = "mplsogre_encap", 6990 .help = "mplsogre encapsulation, uses configuration set by" 6991 " \"set mplsogre_encap\"", 6992 .priv = PRIV_ACTION(RAW_ENCAP, 6993 sizeof(struct action_raw_encap_data)), 6994 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6995 .call = parse_vc_action_mplsogre_encap, 6996 }, 6997 [ACTION_MPLSOGRE_DECAP] = { 6998 .name = "mplsogre_decap", 6999 .help = "mplsogre decapsulation, uses configuration set by" 7000 " \"set mplsogre_decap\"", 7001 .priv = PRIV_ACTION(RAW_DECAP, 7002 sizeof(struct action_raw_decap_data)), 7003 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7004 .call = parse_vc_action_mplsogre_decap, 7005 }, 7006 [ACTION_MPLSOUDP_ENCAP] = { 7007 .name = "mplsoudp_encap", 7008 .help = "mplsoudp encapsulation, uses configuration set by" 7009 " \"set mplsoudp_encap\"", 7010 .priv = PRIV_ACTION(RAW_ENCAP, 7011 sizeof(struct action_raw_encap_data)), 7012 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7013 .call = parse_vc_action_mplsoudp_encap, 7014 }, 7015 [ACTION_MPLSOUDP_DECAP] = { 7016 .name = "mplsoudp_decap", 7017 .help = "mplsoudp decapsulation, uses configuration set by" 7018 " \"set mplsoudp_decap\"", 7019 .priv = PRIV_ACTION(RAW_DECAP, 7020 sizeof(struct action_raw_decap_data)), 7021 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7022 .call = parse_vc_action_mplsoudp_decap, 7023 }, 7024 [ACTION_SET_IPV4_SRC] = { 7025 .name = "set_ipv4_src", 7026 .help = "Set a new IPv4 source address in the outermost" 7027 " IPv4 header", 7028 .priv = PRIV_ACTION(SET_IPV4_SRC, 7029 sizeof(struct rte_flow_action_set_ipv4)), 7030 .next = NEXT(action_set_ipv4_src), 7031 .call = parse_vc, 7032 }, 7033 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 7034 .name = "ipv4_addr", 7035 .help = "new IPv4 source address to set", 7036 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 7037 .args = ARGS(ARGS_ENTRY_HTON 7038 (struct rte_flow_action_set_ipv4, ipv4_addr)), 7039 .call = parse_vc_conf, 7040 }, 7041 [ACTION_SET_IPV4_DST] = { 7042 .name = "set_ipv4_dst", 7043 .help = "Set a new IPv4 destination address in the outermost" 7044 " IPv4 header", 7045 .priv = PRIV_ACTION(SET_IPV4_DST, 7046 sizeof(struct rte_flow_action_set_ipv4)), 7047 .next = NEXT(action_set_ipv4_dst), 7048 .call = parse_vc, 7049 }, 7050 [ACTION_SET_IPV4_DST_IPV4_DST] = { 7051 .name = "ipv4_addr", 7052 .help = "new IPv4 destination address to set", 7053 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 7054 .args = ARGS(ARGS_ENTRY_HTON 7055 (struct rte_flow_action_set_ipv4, ipv4_addr)), 7056 .call = parse_vc_conf, 7057 }, 7058 [ACTION_SET_IPV6_SRC] = { 7059 .name = "set_ipv6_src", 7060 .help = "Set a new IPv6 source address in the outermost" 7061 " IPv6 header", 7062 .priv = PRIV_ACTION(SET_IPV6_SRC, 7063 sizeof(struct rte_flow_action_set_ipv6)), 7064 .next = NEXT(action_set_ipv6_src), 7065 .call = parse_vc, 7066 }, 7067 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 7068 .name = "ipv6_addr", 7069 .help = "new IPv6 source address to set", 7070 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7071 .args = ARGS(ARGS_ENTRY_HTON 7072 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7073 .call = parse_vc_conf, 7074 }, 7075 [ACTION_SET_IPV6_DST] = { 7076 .name = "set_ipv6_dst", 7077 .help = "Set a new IPv6 destination address in the outermost" 7078 " IPv6 header", 7079 .priv = PRIV_ACTION(SET_IPV6_DST, 7080 sizeof(struct rte_flow_action_set_ipv6)), 7081 .next = NEXT(action_set_ipv6_dst), 7082 .call = parse_vc, 7083 }, 7084 [ACTION_SET_IPV6_DST_IPV6_DST] = { 7085 .name = "ipv6_addr", 7086 .help = "new IPv6 destination address to set", 7087 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7088 .args = ARGS(ARGS_ENTRY_HTON 7089 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7090 .call = parse_vc_conf, 7091 }, 7092 [ACTION_SET_TP_SRC] = { 7093 .name = "set_tp_src", 7094 .help = "set a new source port number in the outermost" 7095 " TCP/UDP header", 7096 .priv = PRIV_ACTION(SET_TP_SRC, 7097 sizeof(struct rte_flow_action_set_tp)), 7098 .next = NEXT(action_set_tp_src), 7099 .call = parse_vc, 7100 }, 7101 [ACTION_SET_TP_SRC_TP_SRC] = { 7102 .name = "port", 7103 .help = "new source port number to set", 7104 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 7105 .args = ARGS(ARGS_ENTRY_HTON 7106 (struct rte_flow_action_set_tp, port)), 7107 .call = parse_vc_conf, 7108 }, 7109 [ACTION_SET_TP_DST] = { 7110 .name = "set_tp_dst", 7111 .help = "set a new destination port number in the outermost" 7112 " TCP/UDP header", 7113 .priv = PRIV_ACTION(SET_TP_DST, 7114 sizeof(struct rte_flow_action_set_tp)), 7115 .next = NEXT(action_set_tp_dst), 7116 .call = parse_vc, 7117 }, 7118 [ACTION_SET_TP_DST_TP_DST] = { 7119 .name = "port", 7120 .help = "new destination port number to set", 7121 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 7122 .args = ARGS(ARGS_ENTRY_HTON 7123 (struct rte_flow_action_set_tp, port)), 7124 .call = parse_vc_conf, 7125 }, 7126 [ACTION_MAC_SWAP] = { 7127 .name = "mac_swap", 7128 .help = "Swap the source and destination MAC addresses" 7129 " in the outermost Ethernet header", 7130 .priv = PRIV_ACTION(MAC_SWAP, 0), 7131 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7132 .call = parse_vc, 7133 }, 7134 [ACTION_DEC_TTL] = { 7135 .name = "dec_ttl", 7136 .help = "decrease network TTL if available", 7137 .priv = PRIV_ACTION(DEC_TTL, 0), 7138 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7139 .call = parse_vc, 7140 }, 7141 [ACTION_SET_TTL] = { 7142 .name = "set_ttl", 7143 .help = "set ttl value", 7144 .priv = PRIV_ACTION(SET_TTL, 7145 sizeof(struct rte_flow_action_set_ttl)), 7146 .next = NEXT(action_set_ttl), 7147 .call = parse_vc, 7148 }, 7149 [ACTION_SET_TTL_TTL] = { 7150 .name = "ttl_value", 7151 .help = "new ttl value to set", 7152 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 7153 .args = ARGS(ARGS_ENTRY_HTON 7154 (struct rte_flow_action_set_ttl, ttl_value)), 7155 .call = parse_vc_conf, 7156 }, 7157 [ACTION_SET_MAC_SRC] = { 7158 .name = "set_mac_src", 7159 .help = "set source mac address", 7160 .priv = PRIV_ACTION(SET_MAC_SRC, 7161 sizeof(struct rte_flow_action_set_mac)), 7162 .next = NEXT(action_set_mac_src), 7163 .call = parse_vc, 7164 }, 7165 [ACTION_SET_MAC_SRC_MAC_SRC] = { 7166 .name = "mac_addr", 7167 .help = "new source mac address", 7168 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 7169 .args = ARGS(ARGS_ENTRY_HTON 7170 (struct rte_flow_action_set_mac, mac_addr)), 7171 .call = parse_vc_conf, 7172 }, 7173 [ACTION_SET_MAC_DST] = { 7174 .name = "set_mac_dst", 7175 .help = "set destination mac address", 7176 .priv = PRIV_ACTION(SET_MAC_DST, 7177 sizeof(struct rte_flow_action_set_mac)), 7178 .next = NEXT(action_set_mac_dst), 7179 .call = parse_vc, 7180 }, 7181 [ACTION_SET_MAC_DST_MAC_DST] = { 7182 .name = "mac_addr", 7183 .help = "new destination mac address to set", 7184 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 7185 .args = ARGS(ARGS_ENTRY_HTON 7186 (struct rte_flow_action_set_mac, mac_addr)), 7187 .call = parse_vc_conf, 7188 }, 7189 [ACTION_INC_TCP_SEQ] = { 7190 .name = "inc_tcp_seq", 7191 .help = "increase TCP sequence number", 7192 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 7193 .next = NEXT(action_inc_tcp_seq), 7194 .call = parse_vc, 7195 }, 7196 [ACTION_INC_TCP_SEQ_VALUE] = { 7197 .name = "value", 7198 .help = "the value to increase TCP sequence number by", 7199 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7200 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7201 .call = parse_vc_conf, 7202 }, 7203 [ACTION_DEC_TCP_SEQ] = { 7204 .name = "dec_tcp_seq", 7205 .help = "decrease TCP sequence number", 7206 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 7207 .next = NEXT(action_dec_tcp_seq), 7208 .call = parse_vc, 7209 }, 7210 [ACTION_DEC_TCP_SEQ_VALUE] = { 7211 .name = "value", 7212 .help = "the value to decrease TCP sequence number by", 7213 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7214 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7215 .call = parse_vc_conf, 7216 }, 7217 [ACTION_INC_TCP_ACK] = { 7218 .name = "inc_tcp_ack", 7219 .help = "increase TCP acknowledgment number", 7220 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 7221 .next = NEXT(action_inc_tcp_ack), 7222 .call = parse_vc, 7223 }, 7224 [ACTION_INC_TCP_ACK_VALUE] = { 7225 .name = "value", 7226 .help = "the value to increase TCP acknowledgment number by", 7227 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7228 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7229 .call = parse_vc_conf, 7230 }, 7231 [ACTION_DEC_TCP_ACK] = { 7232 .name = "dec_tcp_ack", 7233 .help = "decrease TCP acknowledgment number", 7234 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 7235 .next = NEXT(action_dec_tcp_ack), 7236 .call = parse_vc, 7237 }, 7238 [ACTION_DEC_TCP_ACK_VALUE] = { 7239 .name = "value", 7240 .help = "the value to decrease TCP acknowledgment number by", 7241 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7242 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7243 .call = parse_vc_conf, 7244 }, 7245 [ACTION_RAW_ENCAP] = { 7246 .name = "raw_encap", 7247 .help = "encapsulation data, defined by set raw_encap", 7248 .priv = PRIV_ACTION(RAW_ENCAP, 7249 sizeof(struct action_raw_encap_data)), 7250 .next = NEXT(action_raw_encap), 7251 .call = parse_vc_action_raw_encap, 7252 }, 7253 [ACTION_RAW_ENCAP_SIZE] = { 7254 .name = "size", 7255 .help = "raw encap size", 7256 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7257 NEXT_ENTRY(COMMON_UNSIGNED)), 7258 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_raw_encap, size)), 7259 .call = parse_vc_conf, 7260 }, 7261 [ACTION_RAW_ENCAP_INDEX] = { 7262 .name = "index", 7263 .help = "the index of raw_encap_confs", 7264 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 7265 }, 7266 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 7267 .name = "{index}", 7268 .type = "UNSIGNED", 7269 .help = "unsigned integer value", 7270 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7271 .call = parse_vc_action_raw_encap_index, 7272 .comp = comp_set_raw_index, 7273 }, 7274 [ACTION_RAW_DECAP] = { 7275 .name = "raw_decap", 7276 .help = "decapsulation data, defined by set raw_encap", 7277 .priv = PRIV_ACTION(RAW_DECAP, 7278 sizeof(struct action_raw_decap_data)), 7279 .next = NEXT(action_raw_decap), 7280 .call = parse_vc_action_raw_decap, 7281 }, 7282 [ACTION_RAW_DECAP_INDEX] = { 7283 .name = "index", 7284 .help = "the index of raw_encap_confs", 7285 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 7286 }, 7287 [ACTION_RAW_DECAP_INDEX_VALUE] = { 7288 .name = "{index}", 7289 .type = "UNSIGNED", 7290 .help = "unsigned integer value", 7291 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7292 .call = parse_vc_action_raw_decap_index, 7293 .comp = comp_set_raw_index, 7294 }, 7295 [ACTION_MODIFY_FIELD] = { 7296 .name = "modify_field", 7297 .help = "modify destination field with data from source field", 7298 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 7299 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 7300 .call = parse_vc, 7301 }, 7302 [ACTION_MODIFY_FIELD_OP] = { 7303 .name = "op", 7304 .help = "operation type", 7305 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 7306 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 7307 .call = parse_vc_conf, 7308 }, 7309 [ACTION_MODIFY_FIELD_OP_VALUE] = { 7310 .name = "{operation}", 7311 .help = "operation type value", 7312 .call = parse_vc_modify_field_op, 7313 .comp = comp_set_modify_field_op, 7314 }, 7315 [ACTION_MODIFY_FIELD_DST_TYPE] = { 7316 .name = "dst_type", 7317 .help = "destination field type", 7318 .next = NEXT(action_modify_field_dst, 7319 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 7320 .call = parse_vc_conf, 7321 }, 7322 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 7323 .name = "{dst_type}", 7324 .help = "destination field type value", 7325 .call = parse_vc_modify_field_id, 7326 .comp = comp_set_modify_field_id, 7327 }, 7328 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 7329 .name = "dst_level", 7330 .help = "destination field level", 7331 .next = NEXT(action_modify_field_dst, 7332 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), 7333 .call = parse_vc_conf, 7334 }, 7335 [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { 7336 .name = "{dst_level}", 7337 .help = "destination field level value", 7338 .call = parse_vc_modify_field_level, 7339 .comp = comp_none, 7340 }, 7341 [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { 7342 .name = "dst_tag_index", 7343 .help = "destination field tag array", 7344 .next = NEXT(action_modify_field_dst, 7345 NEXT_ENTRY(COMMON_UNSIGNED)), 7346 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7347 dst.tag_index)), 7348 .call = parse_vc_conf, 7349 }, 7350 [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { 7351 .name = "dst_type_id", 7352 .help = "destination field type ID", 7353 .next = NEXT(action_modify_field_dst, 7354 NEXT_ENTRY(COMMON_UNSIGNED)), 7355 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7356 dst.type)), 7357 .call = parse_vc_conf, 7358 }, 7359 [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { 7360 .name = "dst_class", 7361 .help = "destination field class ID", 7362 .next = NEXT(action_modify_field_dst, 7363 NEXT_ENTRY(COMMON_UNSIGNED)), 7364 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7365 dst.class_id)), 7366 .call = parse_vc_conf, 7367 }, 7368 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 7369 .name = "dst_offset", 7370 .help = "destination field bit offset", 7371 .next = NEXT(action_modify_field_dst, 7372 NEXT_ENTRY(COMMON_UNSIGNED)), 7373 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7374 dst.offset)), 7375 .call = parse_vc_conf, 7376 }, 7377 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 7378 .name = "src_type", 7379 .help = "source field type", 7380 .next = NEXT(action_modify_field_src, 7381 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 7382 .call = parse_vc_conf, 7383 }, 7384 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 7385 .name = "{src_type}", 7386 .help = "source field type value", 7387 .call = parse_vc_modify_field_id, 7388 .comp = comp_set_modify_field_id, 7389 }, 7390 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 7391 .name = "src_level", 7392 .help = "source field level", 7393 .next = NEXT(action_modify_field_src, 7394 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), 7395 .call = parse_vc_conf, 7396 }, 7397 [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { 7398 .name = "{src_level}", 7399 .help = "source field level value", 7400 .call = parse_vc_modify_field_level, 7401 .comp = comp_none, 7402 }, 7403 [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { 7404 .name = "src_tag_index", 7405 .help = "source field tag array", 7406 .next = NEXT(action_modify_field_src, 7407 NEXT_ENTRY(COMMON_UNSIGNED)), 7408 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7409 src.tag_index)), 7410 .call = parse_vc_conf, 7411 }, 7412 [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { 7413 .name = "src_type_id", 7414 .help = "source field type ID", 7415 .next = NEXT(action_modify_field_src, 7416 NEXT_ENTRY(COMMON_UNSIGNED)), 7417 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7418 src.type)), 7419 .call = parse_vc_conf, 7420 }, 7421 [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { 7422 .name = "src_class", 7423 .help = "source field class ID", 7424 .next = NEXT(action_modify_field_src, 7425 NEXT_ENTRY(COMMON_UNSIGNED)), 7426 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7427 src.class_id)), 7428 .call = parse_vc_conf, 7429 }, 7430 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 7431 .name = "src_offset", 7432 .help = "source field bit offset", 7433 .next = NEXT(action_modify_field_src, 7434 NEXT_ENTRY(COMMON_UNSIGNED)), 7435 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7436 src.offset)), 7437 .call = parse_vc_conf, 7438 }, 7439 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 7440 .name = "src_value", 7441 .help = "source immediate value", 7442 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7443 NEXT_ENTRY(COMMON_HEX)), 7444 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 7445 ARGS_ENTRY_ARB(0, 0), 7446 ARGS_ENTRY(struct rte_flow_action_modify_field, 7447 src.value)), 7448 .call = parse_vc_conf, 7449 }, 7450 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 7451 .name = "src_ptr", 7452 .help = "pointer to source immediate value", 7453 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7454 NEXT_ENTRY(COMMON_HEX)), 7455 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7456 src.pvalue), 7457 ARGS_ENTRY_ARB(0, 0), 7458 ARGS_ENTRY_ARB 7459 (sizeof(struct rte_flow_action_modify_field), 7460 FLOW_FIELD_PATTERN_SIZE)), 7461 .call = parse_vc_conf, 7462 }, 7463 [ACTION_MODIFY_FIELD_WIDTH] = { 7464 .name = "width", 7465 .help = "number of bits to copy", 7466 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7467 NEXT_ENTRY(COMMON_UNSIGNED)), 7468 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7469 width)), 7470 .call = parse_vc_conf, 7471 }, 7472 [ACTION_SEND_TO_KERNEL] = { 7473 .name = "send_to_kernel", 7474 .help = "send packets to kernel", 7475 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 7476 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7477 .call = parse_vc, 7478 }, 7479 [ACTION_IPV6_EXT_REMOVE] = { 7480 .name = "ipv6_ext_remove", 7481 .help = "IPv6 extension type, defined by set ipv6_ext_remove", 7482 .priv = PRIV_ACTION(IPV6_EXT_REMOVE, 7483 sizeof(struct action_ipv6_ext_remove_data)), 7484 .next = NEXT(action_ipv6_ext_remove), 7485 .call = parse_vc_action_ipv6_ext_remove, 7486 }, 7487 [ACTION_IPV6_EXT_REMOVE_INDEX] = { 7488 .name = "index", 7489 .help = "the index of ipv6_ext_remove", 7490 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), 7491 }, 7492 [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { 7493 .name = "{index}", 7494 .type = "UNSIGNED", 7495 .help = "unsigned integer value", 7496 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7497 .call = parse_vc_action_ipv6_ext_remove_index, 7498 .comp = comp_set_ipv6_ext_index, 7499 }, 7500 [ACTION_IPV6_EXT_PUSH] = { 7501 .name = "ipv6_ext_push", 7502 .help = "IPv6 extension data, defined by set ipv6_ext_push", 7503 .priv = PRIV_ACTION(IPV6_EXT_PUSH, 7504 sizeof(struct action_ipv6_ext_push_data)), 7505 .next = NEXT(action_ipv6_ext_push), 7506 .call = parse_vc_action_ipv6_ext_push, 7507 }, 7508 [ACTION_IPV6_EXT_PUSH_INDEX] = { 7509 .name = "index", 7510 .help = "the index of ipv6_ext_push", 7511 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), 7512 }, 7513 [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { 7514 .name = "{index}", 7515 .type = "UNSIGNED", 7516 .help = "unsigned integer value", 7517 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7518 .call = parse_vc_action_ipv6_ext_push_index, 7519 .comp = comp_set_ipv6_ext_index, 7520 }, 7521 [ACTION_NAT64] = { 7522 .name = "nat64", 7523 .help = "NAT64 IP headers translation", 7524 .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), 7525 .next = NEXT(action_nat64), 7526 .call = parse_vc, 7527 }, 7528 [ACTION_NAT64_MODE] = { 7529 .name = "type", 7530 .help = "NAT64 translation type", 7531 .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), 7532 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), 7533 .call = parse_vc_conf, 7534 }, 7535 /* Top level command. */ 7536 [SET] = { 7537 .name = "set", 7538 .help = "set raw encap/decap/sample data", 7539 .type = "set raw_encap|raw_decap <index> <pattern>" 7540 " or set sample_actions <index> <action>", 7541 .next = NEXT(NEXT_ENTRY 7542 (SET_RAW_ENCAP, 7543 SET_RAW_DECAP, 7544 SET_SAMPLE_ACTIONS, 7545 SET_IPV6_EXT_REMOVE, 7546 SET_IPV6_EXT_PUSH)), 7547 .call = parse_set_init, 7548 }, 7549 /* Sub-level commands. */ 7550 [SET_RAW_ENCAP] = { 7551 .name = "raw_encap", 7552 .help = "set raw encap data", 7553 .next = NEXT(next_set_raw), 7554 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7555 (offsetof(struct buffer, port), 7556 sizeof(((struct buffer *)0)->port), 7557 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7558 .call = parse_set_raw_encap_decap, 7559 }, 7560 [SET_RAW_DECAP] = { 7561 .name = "raw_decap", 7562 .help = "set raw decap data", 7563 .next = NEXT(next_set_raw), 7564 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7565 (offsetof(struct buffer, port), 7566 sizeof(((struct buffer *)0)->port), 7567 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7568 .call = parse_set_raw_encap_decap, 7569 }, 7570 [SET_RAW_INDEX] = { 7571 .name = "{index}", 7572 .type = "COMMON_UNSIGNED", 7573 .help = "index of raw_encap/raw_decap data", 7574 .next = NEXT(next_item), 7575 .call = parse_port, 7576 }, 7577 [SET_SAMPLE_INDEX] = { 7578 .name = "{index}", 7579 .type = "UNSIGNED", 7580 .help = "index of sample actions", 7581 .next = NEXT(next_action_sample), 7582 .call = parse_port, 7583 }, 7584 [SET_SAMPLE_ACTIONS] = { 7585 .name = "sample_actions", 7586 .help = "set sample actions list", 7587 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 7588 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7589 (offsetof(struct buffer, port), 7590 sizeof(((struct buffer *)0)->port), 7591 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 7592 .call = parse_set_sample_action, 7593 }, 7594 [SET_IPV6_EXT_PUSH] = { 7595 .name = "ipv6_ext_push", 7596 .help = "set IPv6 extension header", 7597 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7598 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7599 (offsetof(struct buffer, port), 7600 sizeof(((struct buffer *)0)->port), 7601 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7602 .call = parse_set_ipv6_ext_action, 7603 }, 7604 [SET_IPV6_EXT_REMOVE] = { 7605 .name = "ipv6_ext_remove", 7606 .help = "set IPv6 extension header", 7607 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7608 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7609 (offsetof(struct buffer, port), 7610 sizeof(((struct buffer *)0)->port), 7611 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7612 .call = parse_set_ipv6_ext_action, 7613 }, 7614 [SET_IPV6_EXT_INDEX] = { 7615 .name = "{index}", 7616 .type = "UNSIGNED", 7617 .help = "index of ipv6 extension push/remove actions", 7618 .next = NEXT(item_ipv6_push_ext), 7619 .call = parse_port, 7620 }, 7621 [ITEM_IPV6_PUSH_REMOVE_EXT] = { 7622 .name = "ipv6_ext", 7623 .help = "set IPv6 extension header", 7624 .priv = PRIV_ITEM(IPV6_EXT, 7625 sizeof(struct rte_flow_item_ipv6_ext)), 7626 .next = NEXT(item_ipv6_push_ext_type), 7627 .call = parse_vc, 7628 }, 7629 [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { 7630 .name = "type", 7631 .help = "set IPv6 extension type", 7632 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 7633 next_hdr)), 7634 .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), 7635 item_param), 7636 }, 7637 [ACTION_SET_TAG] = { 7638 .name = "set_tag", 7639 .help = "set tag", 7640 .priv = PRIV_ACTION(SET_TAG, 7641 sizeof(struct rte_flow_action_set_tag)), 7642 .next = NEXT(action_set_tag), 7643 .call = parse_vc, 7644 }, 7645 [ACTION_SET_TAG_INDEX] = { 7646 .name = "index", 7647 .help = "index of tag array", 7648 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7649 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 7650 .call = parse_vc_conf, 7651 }, 7652 [ACTION_SET_TAG_DATA] = { 7653 .name = "data", 7654 .help = "tag value", 7655 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7656 .args = ARGS(ARGS_ENTRY 7657 (struct rte_flow_action_set_tag, data)), 7658 .call = parse_vc_conf, 7659 }, 7660 [ACTION_SET_TAG_MASK] = { 7661 .name = "mask", 7662 .help = "mask for tag value", 7663 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7664 .args = ARGS(ARGS_ENTRY 7665 (struct rte_flow_action_set_tag, mask)), 7666 .call = parse_vc_conf, 7667 }, 7668 [ACTION_SET_META] = { 7669 .name = "set_meta", 7670 .help = "set metadata", 7671 .priv = PRIV_ACTION(SET_META, 7672 sizeof(struct rte_flow_action_set_meta)), 7673 .next = NEXT(action_set_meta), 7674 .call = parse_vc_action_set_meta, 7675 }, 7676 [ACTION_SET_META_DATA] = { 7677 .name = "data", 7678 .help = "metadata value", 7679 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7680 .args = ARGS(ARGS_ENTRY 7681 (struct rte_flow_action_set_meta, data)), 7682 .call = parse_vc_conf, 7683 }, 7684 [ACTION_SET_META_MASK] = { 7685 .name = "mask", 7686 .help = "mask for metadata value", 7687 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7688 .args = ARGS(ARGS_ENTRY 7689 (struct rte_flow_action_set_meta, mask)), 7690 .call = parse_vc_conf, 7691 }, 7692 [ACTION_SET_IPV4_DSCP] = { 7693 .name = "set_ipv4_dscp", 7694 .help = "set DSCP value", 7695 .priv = PRIV_ACTION(SET_IPV4_DSCP, 7696 sizeof(struct rte_flow_action_set_dscp)), 7697 .next = NEXT(action_set_ipv4_dscp), 7698 .call = parse_vc, 7699 }, 7700 [ACTION_SET_IPV4_DSCP_VALUE] = { 7701 .name = "dscp_value", 7702 .help = "new IPv4 DSCP value to set", 7703 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7704 .args = ARGS(ARGS_ENTRY 7705 (struct rte_flow_action_set_dscp, dscp)), 7706 .call = parse_vc_conf, 7707 }, 7708 [ACTION_SET_IPV6_DSCP] = { 7709 .name = "set_ipv6_dscp", 7710 .help = "set DSCP value", 7711 .priv = PRIV_ACTION(SET_IPV6_DSCP, 7712 sizeof(struct rte_flow_action_set_dscp)), 7713 .next = NEXT(action_set_ipv6_dscp), 7714 .call = parse_vc, 7715 }, 7716 [ACTION_SET_IPV6_DSCP_VALUE] = { 7717 .name = "dscp_value", 7718 .help = "new IPv6 DSCP value to set", 7719 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7720 .args = ARGS(ARGS_ENTRY 7721 (struct rte_flow_action_set_dscp, dscp)), 7722 .call = parse_vc_conf, 7723 }, 7724 [ACTION_AGE] = { 7725 .name = "age", 7726 .help = "set a specific metadata header", 7727 .next = NEXT(action_age), 7728 .priv = PRIV_ACTION(AGE, 7729 sizeof(struct rte_flow_action_age)), 7730 .call = parse_vc, 7731 }, 7732 [ACTION_AGE_TIMEOUT] = { 7733 .name = "timeout", 7734 .help = "flow age timeout value", 7735 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 7736 timeout, 24)), 7737 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 7738 .call = parse_vc_conf, 7739 }, 7740 [ACTION_AGE_UPDATE] = { 7741 .name = "age_update", 7742 .help = "update aging parameter", 7743 .next = NEXT(action_age_update), 7744 .priv = PRIV_ACTION(AGE, 7745 sizeof(struct rte_flow_update_age)), 7746 .call = parse_vc, 7747 }, 7748 [ACTION_AGE_UPDATE_TIMEOUT] = { 7749 .name = "timeout", 7750 .help = "age timeout update value", 7751 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7752 timeout, 24)), 7753 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7754 .call = parse_vc_conf_timeout, 7755 }, 7756 [ACTION_AGE_UPDATE_TOUCH] = { 7757 .name = "touch", 7758 .help = "this flow is touched", 7759 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), 7760 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7761 touch, 1)), 7762 .call = parse_vc_conf, 7763 }, 7764 [ACTION_SAMPLE] = { 7765 .name = "sample", 7766 .help = "set a sample action", 7767 .next = NEXT(action_sample), 7768 .priv = PRIV_ACTION(SAMPLE, 7769 sizeof(struct action_sample_data)), 7770 .call = parse_vc_action_sample, 7771 }, 7772 [ACTION_SAMPLE_RATIO] = { 7773 .name = "ratio", 7774 .help = "flow sample ratio value", 7775 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 7776 .args = ARGS(ARGS_ENTRY_ARB 7777 (offsetof(struct action_sample_data, conf) + 7778 offsetof(struct rte_flow_action_sample, ratio), 7779 sizeof(((struct rte_flow_action_sample *)0)-> 7780 ratio))), 7781 }, 7782 [ACTION_SAMPLE_INDEX] = { 7783 .name = "index", 7784 .help = "the index of sample actions list", 7785 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 7786 }, 7787 [ACTION_SAMPLE_INDEX_VALUE] = { 7788 .name = "{index}", 7789 .type = "COMMON_UNSIGNED", 7790 .help = "unsigned integer value", 7791 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7792 .call = parse_vc_action_sample_index, 7793 .comp = comp_set_sample_index, 7794 }, 7795 [ACTION_CONNTRACK] = { 7796 .name = "conntrack", 7797 .help = "create a conntrack object", 7798 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7799 .priv = PRIV_ACTION(CONNTRACK, 7800 sizeof(struct rte_flow_action_conntrack)), 7801 .call = parse_vc, 7802 }, 7803 [ACTION_CONNTRACK_UPDATE] = { 7804 .name = "conntrack_update", 7805 .help = "update a conntrack object", 7806 .next = NEXT(action_update_conntrack), 7807 .priv = PRIV_ACTION(CONNTRACK, 7808 sizeof(struct rte_flow_modify_conntrack)), 7809 .call = parse_vc, 7810 }, 7811 [ACTION_CONNTRACK_UPDATE_DIR] = { 7812 .name = "dir", 7813 .help = "update a conntrack object direction", 7814 .next = NEXT(action_update_conntrack), 7815 .call = parse_vc_action_conntrack_update, 7816 }, 7817 [ACTION_CONNTRACK_UPDATE_CTX] = { 7818 .name = "ctx", 7819 .help = "update a conntrack object context", 7820 .next = NEXT(action_update_conntrack), 7821 .call = parse_vc_action_conntrack_update, 7822 }, 7823 [ACTION_PORT_REPRESENTOR] = { 7824 .name = "port_representor", 7825 .help = "at embedded switch level, send matching traffic to the given ethdev", 7826 .priv = PRIV_ACTION(PORT_REPRESENTOR, 7827 sizeof(struct rte_flow_action_ethdev)), 7828 .next = NEXT(action_port_representor), 7829 .call = parse_vc, 7830 }, 7831 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 7832 .name = "port_id", 7833 .help = "ethdev port ID", 7834 .next = NEXT(action_port_representor, 7835 NEXT_ENTRY(COMMON_UNSIGNED)), 7836 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7837 port_id)), 7838 .call = parse_vc_conf, 7839 }, 7840 [ACTION_REPRESENTED_PORT] = { 7841 .name = "represented_port", 7842 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 7843 .priv = PRIV_ACTION(REPRESENTED_PORT, 7844 sizeof(struct rte_flow_action_ethdev)), 7845 .next = NEXT(action_represented_port), 7846 .call = parse_vc, 7847 }, 7848 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 7849 .name = "ethdev_port_id", 7850 .help = "ethdev port ID", 7851 .next = NEXT(action_represented_port, 7852 NEXT_ENTRY(COMMON_UNSIGNED)), 7853 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7854 port_id)), 7855 .call = parse_vc_conf, 7856 }, 7857 /* Indirect action destroy arguments. */ 7858 [INDIRECT_ACTION_DESTROY_ID] = { 7859 .name = "action_id", 7860 .help = "specify a indirect action id to destroy", 7861 .next = NEXT(next_ia_destroy_attr, 7862 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7863 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 7864 args.ia_destroy.action_id)), 7865 .call = parse_ia_destroy, 7866 }, 7867 /* Indirect action create arguments. */ 7868 [INDIRECT_ACTION_CREATE_ID] = { 7869 .name = "action_id", 7870 .help = "specify a indirect action id to create", 7871 .next = NEXT(next_ia_create_attr, 7872 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7873 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 7874 }, 7875 [ACTION_INDIRECT] = { 7876 .name = "indirect", 7877 .help = "apply indirect action by id", 7878 .priv = PRIV_ACTION(INDIRECT, 0), 7879 .next = NEXT(next_ia), 7880 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7881 .call = parse_vc, 7882 }, 7883 [ACTION_INDIRECT_LIST] = { 7884 .name = "indirect_list", 7885 .help = "apply indirect list action by id", 7886 .priv = PRIV_ACTION(INDIRECT_LIST, 7887 sizeof(struct 7888 rte_flow_action_indirect_list)), 7889 .next = NEXT(next_ial), 7890 .call = parse_vc, 7891 }, 7892 [ACTION_INDIRECT_LIST_HANDLE] = { 7893 .name = "handle", 7894 .help = "indirect list handle", 7895 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), 7896 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7897 }, 7898 [ACTION_INDIRECT_LIST_CONF] = { 7899 .name = "conf", 7900 .help = "indirect list configuration", 7901 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), 7902 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7903 }, 7904 [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { 7905 .type = "UNSIGNED", 7906 .help = "unsigned integer value", 7907 .call = parse_indlst_id2ptr, 7908 .comp = comp_none, 7909 }, 7910 [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { 7911 .type = "UNSIGNED", 7912 .help = "unsigned integer value", 7913 .call = parse_indlst_id2ptr, 7914 .comp = comp_none, 7915 }, 7916 [ACTION_SHARED_INDIRECT] = { 7917 .name = "shared_indirect", 7918 .help = "apply indirect action by id and port", 7919 .priv = PRIV_ACTION(INDIRECT, 0), 7920 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), 7921 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), 7922 ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7923 .call = parse_vc, 7924 }, 7925 [INDIRECT_ACTION_PORT] = { 7926 .name = "{indirect_action_port}", 7927 .type = "INDIRECT_ACTION_PORT", 7928 .help = "indirect action port", 7929 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 7930 .call = parse_ia_port, 7931 .comp = comp_none, 7932 }, 7933 [INDIRECT_ACTION_ID2PTR] = { 7934 .name = "{action_id}", 7935 .type = "INDIRECT_ACTION_ID", 7936 .help = "indirect action id", 7937 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7938 .call = parse_ia_id2ptr, 7939 .comp = comp_none, 7940 }, 7941 [INDIRECT_ACTION_INGRESS] = { 7942 .name = "ingress", 7943 .help = "affect rule to ingress", 7944 .next = NEXT(next_ia_create_attr), 7945 .call = parse_ia, 7946 }, 7947 [INDIRECT_ACTION_EGRESS] = { 7948 .name = "egress", 7949 .help = "affect rule to egress", 7950 .next = NEXT(next_ia_create_attr), 7951 .call = parse_ia, 7952 }, 7953 [INDIRECT_ACTION_TRANSFER] = { 7954 .name = "transfer", 7955 .help = "affect rule to transfer", 7956 .next = NEXT(next_ia_create_attr), 7957 .call = parse_ia, 7958 }, 7959 [INDIRECT_ACTION_SPEC] = { 7960 .name = "action", 7961 .help = "specify action to create indirect handle", 7962 .next = NEXT(next_action), 7963 }, 7964 [INDIRECT_ACTION_LIST] = { 7965 .name = "list", 7966 .help = "specify actions for indirect handle list", 7967 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7968 .call = parse_ia, 7969 }, 7970 [INDIRECT_ACTION_FLOW_CONF] = { 7971 .name = "flow_conf", 7972 .help = "specify actions configuration for indirect handle list", 7973 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7974 .call = parse_ia, 7975 }, 7976 [ACTION_POL_G] = { 7977 .name = "g_actions", 7978 .help = "submit a list of associated actions for green", 7979 .next = NEXT(next_action), 7980 .call = parse_mp, 7981 }, 7982 [ACTION_POL_Y] = { 7983 .name = "y_actions", 7984 .help = "submit a list of associated actions for yellow", 7985 .next = NEXT(next_action), 7986 }, 7987 [ACTION_POL_R] = { 7988 .name = "r_actions", 7989 .help = "submit a list of associated actions for red", 7990 .next = NEXT(next_action), 7991 }, 7992 [ACTION_QUOTA_CREATE] = { 7993 .name = "quota_create", 7994 .help = "create quota action", 7995 .priv = PRIV_ACTION(QUOTA, 7996 sizeof(struct rte_flow_action_quota)), 7997 .next = NEXT(action_quota_create), 7998 .call = parse_vc 7999 }, 8000 [ACTION_QUOTA_CREATE_LIMIT] = { 8001 .name = "limit", 8002 .help = "quota limit", 8003 .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), 8004 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), 8005 .call = parse_vc_conf 8006 }, 8007 [ACTION_QUOTA_CREATE_MODE] = { 8008 .name = "mode", 8009 .help = "quota mode", 8010 .next = NEXT(action_quota_create, 8011 NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), 8012 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), 8013 .call = parse_vc_conf 8014 }, 8015 [ACTION_QUOTA_CREATE_MODE_NAME] = { 8016 .name = "mode_name", 8017 .help = "quota mode name", 8018 .call = parse_quota_mode_name, 8019 .comp = comp_quota_mode_name 8020 }, 8021 [ACTION_QUOTA_QU] = { 8022 .name = "quota_update", 8023 .help = "update quota action", 8024 .priv = PRIV_ACTION(QUOTA, 8025 sizeof(struct rte_flow_update_quota)), 8026 .next = NEXT(action_quota_update), 8027 .call = parse_vc 8028 }, 8029 [ACTION_QUOTA_QU_LIMIT] = { 8030 .name = "limit", 8031 .help = "quota limit", 8032 .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), 8033 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), 8034 .call = parse_vc_conf 8035 }, 8036 [ACTION_QUOTA_QU_UPDATE_OP] = { 8037 .name = "update_op", 8038 .help = "query update op SET|ADD", 8039 .next = NEXT(action_quota_update, 8040 NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), 8041 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), 8042 .call = parse_vc_conf 8043 }, 8044 [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { 8045 .name = "update_op_name", 8046 .help = "quota update op name", 8047 .call = parse_quota_update_name, 8048 .comp = comp_quota_update_name 8049 }, 8050 8051 /* Top-level command. */ 8052 [ADD] = { 8053 .name = "add", 8054 .type = "port meter policy {port_id} {arg}", 8055 .help = "add port meter policy", 8056 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 8057 .call = parse_init, 8058 }, 8059 /* Sub-level commands. */ 8060 [ITEM_POL_PORT] = { 8061 .name = "port", 8062 .help = "add port meter policy", 8063 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 8064 }, 8065 [ITEM_POL_METER] = { 8066 .name = "meter", 8067 .help = "add port meter policy", 8068 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 8069 }, 8070 [ITEM_POL_POLICY] = { 8071 .name = "policy", 8072 .help = "add port meter policy", 8073 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 8074 NEXT_ENTRY(ACTION_POL_Y), 8075 NEXT_ENTRY(ACTION_POL_G), 8076 NEXT_ENTRY(COMMON_POLICY_ID), 8077 NEXT_ENTRY(COMMON_PORT_ID)), 8078 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 8079 ARGS_ENTRY(struct buffer, port)), 8080 .call = parse_mp, 8081 }, 8082 [ITEM_AGGR_AFFINITY] = { 8083 .name = "aggr_affinity", 8084 .help = "match on the aggregated port receiving the packets", 8085 .priv = PRIV_ITEM(AGGR_AFFINITY, 8086 sizeof(struct rte_flow_item_aggr_affinity)), 8087 .next = NEXT(item_aggr_affinity), 8088 .call = parse_vc, 8089 }, 8090 [ITEM_AGGR_AFFINITY_VALUE] = { 8091 .name = "affinity", 8092 .help = "aggregated affinity value", 8093 .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), 8094 item_param), 8095 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, 8096 affinity)), 8097 }, 8098 [ITEM_TX_QUEUE] = { 8099 .name = "tx_queue", 8100 .help = "match on the tx queue of send packet", 8101 .priv = PRIV_ITEM(TX_QUEUE, 8102 sizeof(struct rte_flow_item_tx_queue)), 8103 .next = NEXT(item_tx_queue), 8104 .call = parse_vc, 8105 }, 8106 [ITEM_TX_QUEUE_VALUE] = { 8107 .name = "tx_queue_value", 8108 .help = "tx queue value", 8109 .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), 8110 item_param), 8111 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, 8112 tx_queue)), 8113 }, 8114 }; 8115 8116 /** Remove and return last entry from argument stack. */ 8117 static const struct arg * 8118 pop_args(struct context *ctx) 8119 { 8120 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 8121 } 8122 8123 /** Add entry on top of the argument stack. */ 8124 static int 8125 push_args(struct context *ctx, const struct arg *arg) 8126 { 8127 if (ctx->args_num == CTX_STACK_SIZE) 8128 return -1; 8129 ctx->args[ctx->args_num++] = arg; 8130 return 0; 8131 } 8132 8133 /** Spread value into buffer according to bit-mask. */ 8134 static size_t 8135 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 8136 { 8137 uint32_t i = arg->size; 8138 uint32_t end = 0; 8139 int sub = 1; 8140 int add = 0; 8141 size_t len = 0; 8142 8143 if (!arg->mask) 8144 return 0; 8145 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8146 if (!arg->hton) { 8147 i = 0; 8148 end = arg->size; 8149 sub = 0; 8150 add = 1; 8151 } 8152 #endif 8153 while (i != end) { 8154 unsigned int shift = 0; 8155 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 8156 8157 for (shift = 0; arg->mask[i] >> shift; ++shift) { 8158 if (!(arg->mask[i] & (1 << shift))) 8159 continue; 8160 ++len; 8161 if (!dst) 8162 continue; 8163 *buf &= ~(1 << shift); 8164 *buf |= (val & 1) << shift; 8165 val >>= 1; 8166 } 8167 i += add; 8168 } 8169 return len; 8170 } 8171 8172 /** Compare a string with a partial one of a given length. */ 8173 static int 8174 strcmp_partial(const char *full, const char *partial, size_t partial_len) 8175 { 8176 int r = strncmp(full, partial, partial_len); 8177 8178 if (r) 8179 return r; 8180 if (strlen(full) <= partial_len) 8181 return 0; 8182 return full[partial_len]; 8183 } 8184 8185 /** 8186 * Parse a prefix length and generate a bit-mask. 8187 * 8188 * Last argument (ctx->args) is retrieved to determine mask size, storage 8189 * location and whether the result must use network byte ordering. 8190 */ 8191 static int 8192 parse_prefix(struct context *ctx, const struct token *token, 8193 const char *str, unsigned int len, 8194 void *buf, unsigned int size) 8195 { 8196 const struct arg *arg = pop_args(ctx); 8197 static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff"; 8198 char *end; 8199 uintmax_t u; 8200 unsigned int bytes; 8201 unsigned int extra; 8202 8203 (void)token; 8204 /* Argument is expected. */ 8205 if (!arg) 8206 return -1; 8207 errno = 0; 8208 u = strtoumax(str, &end, 0); 8209 if (errno || (size_t)(end - str) != len) 8210 goto error; 8211 if (arg->mask) { 8212 uintmax_t v = 0; 8213 8214 extra = arg_entry_bf_fill(NULL, 0, arg); 8215 if (u > extra) 8216 goto error; 8217 if (!ctx->object) 8218 return len; 8219 extra -= u; 8220 while (u--) 8221 (v <<= 1, v |= 1); 8222 v <<= extra; 8223 if (!arg_entry_bf_fill(ctx->object, v, arg) || 8224 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 8225 goto error; 8226 return len; 8227 } 8228 bytes = u / 8; 8229 extra = u % 8; 8230 size = arg->size; 8231 if (bytes > size || bytes + !!extra > size) 8232 goto error; 8233 if (!ctx->object) 8234 return len; 8235 buf = (uint8_t *)ctx->object + arg->offset; 8236 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8237 if (!arg->hton) { 8238 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 8239 memset(buf, 0x00, size - bytes); 8240 if (extra) 8241 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 8242 } else 8243 #endif 8244 { 8245 memset(buf, 0xff, bytes); 8246 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 8247 if (extra) 8248 ((uint8_t *)buf)[bytes] = conv[extra]; 8249 } 8250 if (ctx->objmask) 8251 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 8252 return len; 8253 error: 8254 push_args(ctx, arg); 8255 return -1; 8256 } 8257 8258 /** Default parsing function for token name matching. */ 8259 static int 8260 parse_default(struct context *ctx, const struct token *token, 8261 const char *str, unsigned int len, 8262 void *buf, unsigned int size) 8263 { 8264 (void)ctx; 8265 (void)buf; 8266 (void)size; 8267 if (strcmp_partial(token->name, str, len)) 8268 return -1; 8269 return len; 8270 } 8271 8272 /** Parse flow command, initialize output buffer for subsequent tokens. */ 8273 static int 8274 parse_init(struct context *ctx, const struct token *token, 8275 const char *str, unsigned int len, 8276 void *buf, unsigned int size) 8277 { 8278 struct buffer *out = buf; 8279 8280 /* Token name must match. */ 8281 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8282 return -1; 8283 /* Nothing else to do if there is no buffer. */ 8284 if (!out) 8285 return len; 8286 /* Make sure buffer is large enough. */ 8287 if (size < sizeof(*out)) 8288 return -1; 8289 /* Initialize buffer. */ 8290 memset(out, 0x00, sizeof(*out)); 8291 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 8292 ctx->objdata = 0; 8293 ctx->object = out; 8294 ctx->objmask = NULL; 8295 return len; 8296 } 8297 8298 /** Parse tokens for indirect action commands. */ 8299 static int 8300 parse_ia(struct context *ctx, const struct token *token, 8301 const char *str, unsigned int len, 8302 void *buf, unsigned int size) 8303 { 8304 struct buffer *out = buf; 8305 8306 /* Token name must match. */ 8307 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8308 return -1; 8309 /* Nothing else to do if there is no buffer. */ 8310 if (!out) 8311 return len; 8312 if (!out->command) { 8313 if (ctx->curr != INDIRECT_ACTION) 8314 return -1; 8315 if (sizeof(*out) > size) 8316 return -1; 8317 out->command = ctx->curr; 8318 ctx->objdata = 0; 8319 ctx->object = out; 8320 ctx->objmask = NULL; 8321 out->args.vc.data = (uint8_t *)out + size; 8322 return len; 8323 } 8324 switch (ctx->curr) { 8325 case INDIRECT_ACTION_CREATE: 8326 case INDIRECT_ACTION_UPDATE: 8327 case INDIRECT_ACTION_QUERY_UPDATE: 8328 out->args.vc.actions = 8329 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8330 sizeof(double)); 8331 out->args.vc.attr.group = UINT32_MAX; 8332 /* fallthrough */ 8333 case INDIRECT_ACTION_QUERY: 8334 out->command = ctx->curr; 8335 ctx->objdata = 0; 8336 ctx->object = out; 8337 ctx->objmask = NULL; 8338 return len; 8339 case INDIRECT_ACTION_EGRESS: 8340 out->args.vc.attr.egress = 1; 8341 return len; 8342 case INDIRECT_ACTION_INGRESS: 8343 out->args.vc.attr.ingress = 1; 8344 return len; 8345 case INDIRECT_ACTION_TRANSFER: 8346 out->args.vc.attr.transfer = 1; 8347 return len; 8348 case INDIRECT_ACTION_QU_MODE: 8349 return len; 8350 case INDIRECT_ACTION_LIST: 8351 out->command = INDIRECT_ACTION_LIST_CREATE; 8352 return len; 8353 case INDIRECT_ACTION_FLOW_CONF: 8354 out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; 8355 return len; 8356 default: 8357 return -1; 8358 } 8359 } 8360 8361 8362 /** Parse tokens for indirect action destroy command. */ 8363 static int 8364 parse_ia_destroy(struct context *ctx, const struct token *token, 8365 const char *str, unsigned int len, 8366 void *buf, unsigned int size) 8367 { 8368 struct buffer *out = buf; 8369 uint32_t *action_id; 8370 8371 /* Token name must match. */ 8372 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8373 return -1; 8374 /* Nothing else to do if there is no buffer. */ 8375 if (!out) 8376 return len; 8377 if (!out->command || out->command == INDIRECT_ACTION) { 8378 if (ctx->curr != INDIRECT_ACTION_DESTROY) 8379 return -1; 8380 if (sizeof(*out) > size) 8381 return -1; 8382 out->command = ctx->curr; 8383 ctx->objdata = 0; 8384 ctx->object = out; 8385 ctx->objmask = NULL; 8386 out->args.ia_destroy.action_id = 8387 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8388 sizeof(double)); 8389 return len; 8390 } 8391 action_id = out->args.ia_destroy.action_id 8392 + out->args.ia_destroy.action_id_n++; 8393 if ((uint8_t *)action_id > (uint8_t *)out + size) 8394 return -1; 8395 ctx->objdata = 0; 8396 ctx->object = action_id; 8397 ctx->objmask = NULL; 8398 return len; 8399 } 8400 8401 /** Parse tokens for indirect action commands. */ 8402 static int 8403 parse_qia(struct context *ctx, const struct token *token, 8404 const char *str, unsigned int len, 8405 void *buf, unsigned int size) 8406 { 8407 struct buffer *out = buf; 8408 8409 /* Token name must match. */ 8410 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8411 return -1; 8412 /* Nothing else to do if there is no buffer. */ 8413 if (!out) 8414 return len; 8415 if (!out->command) { 8416 if (ctx->curr != QUEUE) 8417 return -1; 8418 if (sizeof(*out) > size) 8419 return -1; 8420 out->args.vc.data = (uint8_t *)out + size; 8421 return len; 8422 } 8423 switch (ctx->curr) { 8424 case QUEUE_INDIRECT_ACTION: 8425 return len; 8426 case QUEUE_INDIRECT_ACTION_CREATE: 8427 case QUEUE_INDIRECT_ACTION_UPDATE: 8428 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 8429 out->args.vc.actions = 8430 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8431 sizeof(double)); 8432 out->args.vc.attr.group = UINT32_MAX; 8433 /* fallthrough */ 8434 case QUEUE_INDIRECT_ACTION_QUERY: 8435 out->command = ctx->curr; 8436 ctx->objdata = 0; 8437 ctx->object = out; 8438 ctx->objmask = NULL; 8439 return len; 8440 case QUEUE_INDIRECT_ACTION_EGRESS: 8441 out->args.vc.attr.egress = 1; 8442 return len; 8443 case QUEUE_INDIRECT_ACTION_INGRESS: 8444 out->args.vc.attr.ingress = 1; 8445 return len; 8446 case QUEUE_INDIRECT_ACTION_TRANSFER: 8447 out->args.vc.attr.transfer = 1; 8448 return len; 8449 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 8450 return len; 8451 case QUEUE_INDIRECT_ACTION_QU_MODE: 8452 return len; 8453 case QUEUE_INDIRECT_ACTION_LIST: 8454 out->command = QUEUE_INDIRECT_ACTION_LIST_CREATE; 8455 return len; 8456 default: 8457 return -1; 8458 } 8459 } 8460 8461 /** Parse tokens for indirect action destroy command. */ 8462 static int 8463 parse_qia_destroy(struct context *ctx, const struct token *token, 8464 const char *str, unsigned int len, 8465 void *buf, unsigned int size) 8466 { 8467 struct buffer *out = buf; 8468 uint32_t *action_id; 8469 8470 /* Token name must match. */ 8471 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8472 return -1; 8473 /* Nothing else to do if there is no buffer. */ 8474 if (!out) 8475 return len; 8476 if (!out->command || out->command == QUEUE) { 8477 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 8478 return -1; 8479 if (sizeof(*out) > size) 8480 return -1; 8481 out->command = ctx->curr; 8482 ctx->objdata = 0; 8483 ctx->object = out; 8484 ctx->objmask = NULL; 8485 out->args.ia_destroy.action_id = 8486 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8487 sizeof(double)); 8488 return len; 8489 } 8490 switch (ctx->curr) { 8491 case QUEUE_INDIRECT_ACTION: 8492 out->command = ctx->curr; 8493 ctx->objdata = 0; 8494 ctx->object = out; 8495 ctx->objmask = NULL; 8496 return len; 8497 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 8498 action_id = out->args.ia_destroy.action_id 8499 + out->args.ia_destroy.action_id_n++; 8500 if ((uint8_t *)action_id > (uint8_t *)out + size) 8501 return -1; 8502 ctx->objdata = 0; 8503 ctx->object = action_id; 8504 ctx->objmask = NULL; 8505 return len; 8506 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 8507 return len; 8508 default: 8509 return -1; 8510 } 8511 } 8512 8513 /** Parse tokens for meter policy action commands. */ 8514 static int 8515 parse_mp(struct context *ctx, const struct token *token, 8516 const char *str, unsigned int len, 8517 void *buf, unsigned int size) 8518 { 8519 struct buffer *out = buf; 8520 8521 /* Token name must match. */ 8522 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8523 return -1; 8524 /* Nothing else to do if there is no buffer. */ 8525 if (!out) 8526 return len; 8527 if (!out->command) { 8528 if (ctx->curr != ITEM_POL_POLICY) 8529 return -1; 8530 if (sizeof(*out) > size) 8531 return -1; 8532 out->command = ctx->curr; 8533 ctx->objdata = 0; 8534 ctx->object = out; 8535 ctx->objmask = NULL; 8536 out->args.vc.data = (uint8_t *)out + size; 8537 return len; 8538 } 8539 switch (ctx->curr) { 8540 case ACTION_POL_G: 8541 out->args.vc.actions = 8542 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8543 sizeof(double)); 8544 out->command = ctx->curr; 8545 ctx->objdata = 0; 8546 ctx->object = out; 8547 ctx->objmask = NULL; 8548 return len; 8549 default: 8550 return -1; 8551 } 8552 } 8553 8554 /** Parse tokens for validate/create commands. */ 8555 static int 8556 parse_vc(struct context *ctx, const struct token *token, 8557 const char *str, unsigned int len, 8558 void *buf, unsigned int size) 8559 { 8560 struct buffer *out = buf; 8561 uint8_t *data; 8562 uint32_t data_size; 8563 8564 /* Token name must match. */ 8565 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8566 return -1; 8567 /* Nothing else to do if there is no buffer. */ 8568 if (!out) 8569 return len; 8570 if (!out->command) { 8571 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 8572 ctx->curr != PATTERN_TEMPLATE_CREATE && 8573 ctx->curr != ACTIONS_TEMPLATE_CREATE && 8574 ctx->curr != UPDATE) 8575 return -1; 8576 if (ctx->curr == UPDATE) 8577 out->args.vc.pattern = 8578 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8579 sizeof(double)); 8580 if (sizeof(*out) > size) 8581 return -1; 8582 out->command = ctx->curr; 8583 ctx->objdata = 0; 8584 ctx->object = out; 8585 ctx->objmask = NULL; 8586 out->args.vc.data = (uint8_t *)out + size; 8587 return len; 8588 } 8589 ctx->objdata = 0; 8590 switch (ctx->curr) { 8591 default: 8592 ctx->object = &out->args.vc.attr; 8593 break; 8594 case VC_TUNNEL_SET: 8595 case VC_TUNNEL_MATCH: 8596 ctx->object = &out->args.vc.tunnel_ops; 8597 break; 8598 case VC_USER_ID: 8599 ctx->object = out; 8600 break; 8601 } 8602 ctx->objmask = NULL; 8603 switch (ctx->curr) { 8604 case VC_GROUP: 8605 case VC_PRIORITY: 8606 case VC_USER_ID: 8607 return len; 8608 case VC_TUNNEL_SET: 8609 out->args.vc.tunnel_ops.enabled = 1; 8610 out->args.vc.tunnel_ops.actions = 1; 8611 return len; 8612 case VC_TUNNEL_MATCH: 8613 out->args.vc.tunnel_ops.enabled = 1; 8614 out->args.vc.tunnel_ops.items = 1; 8615 return len; 8616 case VC_INGRESS: 8617 out->args.vc.attr.ingress = 1; 8618 return len; 8619 case VC_EGRESS: 8620 out->args.vc.attr.egress = 1; 8621 return len; 8622 case VC_TRANSFER: 8623 out->args.vc.attr.transfer = 1; 8624 return len; 8625 case ITEM_PATTERN: 8626 out->args.vc.pattern = 8627 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8628 sizeof(double)); 8629 ctx->object = out->args.vc.pattern; 8630 ctx->objmask = NULL; 8631 return len; 8632 case ITEM_END: 8633 if ((out->command == VALIDATE || out->command == CREATE) && 8634 ctx->last) 8635 return -1; 8636 if (out->command == PATTERN_TEMPLATE_CREATE && 8637 !ctx->last) 8638 return -1; 8639 break; 8640 case ACTIONS: 8641 out->args.vc.actions = out->args.vc.pattern ? 8642 (void *)RTE_ALIGN_CEIL((uintptr_t) 8643 (out->args.vc.pattern + 8644 out->args.vc.pattern_n), 8645 sizeof(double)) : 8646 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8647 sizeof(double)); 8648 ctx->object = out->args.vc.actions; 8649 ctx->objmask = NULL; 8650 return len; 8651 case VC_IS_USER_ID: 8652 out->args.vc.user_id = true; 8653 return len; 8654 default: 8655 if (!token->priv) 8656 return -1; 8657 break; 8658 } 8659 if (!out->args.vc.actions) { 8660 const struct parse_item_priv *priv = token->priv; 8661 struct rte_flow_item *item = 8662 out->args.vc.pattern + out->args.vc.pattern_n; 8663 8664 data_size = priv->size * 3; /* spec, last, mask */ 8665 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8666 (out->args.vc.data - data_size), 8667 sizeof(double)); 8668 if ((uint8_t *)item + sizeof(*item) > data) 8669 return -1; 8670 *item = (struct rte_flow_item){ 8671 .type = priv->type, 8672 }; 8673 ++out->args.vc.pattern_n; 8674 ctx->object = item; 8675 ctx->objmask = NULL; 8676 } else { 8677 const struct parse_action_priv *priv = token->priv; 8678 struct rte_flow_action *action = 8679 out->args.vc.actions + out->args.vc.actions_n; 8680 8681 data_size = priv->size; /* configuration */ 8682 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8683 (out->args.vc.data - data_size), 8684 sizeof(double)); 8685 if ((uint8_t *)action + sizeof(*action) > data) 8686 return -1; 8687 *action = (struct rte_flow_action){ 8688 .type = priv->type, 8689 .conf = data_size ? data : NULL, 8690 }; 8691 ++out->args.vc.actions_n; 8692 ctx->object = action; 8693 ctx->objmask = NULL; 8694 } 8695 memset(data, 0, data_size); 8696 out->args.vc.data = data; 8697 ctx->objdata = data_size; 8698 return len; 8699 } 8700 8701 /** Parse pattern item parameter type. */ 8702 static int 8703 parse_vc_spec(struct context *ctx, const struct token *token, 8704 const char *str, unsigned int len, 8705 void *buf, unsigned int size) 8706 { 8707 struct buffer *out = buf; 8708 struct rte_flow_item *item; 8709 uint32_t data_size; 8710 int index; 8711 int objmask = 0; 8712 8713 (void)size; 8714 /* Token name must match. */ 8715 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8716 return -1; 8717 /* Parse parameter types. */ 8718 switch (ctx->curr) { 8719 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 8720 8721 case ITEM_PARAM_IS: 8722 index = 0; 8723 objmask = 1; 8724 break; 8725 case ITEM_PARAM_SPEC: 8726 index = 0; 8727 break; 8728 case ITEM_PARAM_LAST: 8729 index = 1; 8730 break; 8731 case ITEM_PARAM_PREFIX: 8732 /* Modify next token to expect a prefix. */ 8733 if (ctx->next_num < 2) 8734 return -1; 8735 ctx->next[ctx->next_num - 2] = prefix; 8736 /* Fall through. */ 8737 case ITEM_PARAM_MASK: 8738 index = 2; 8739 break; 8740 default: 8741 return -1; 8742 } 8743 /* Nothing else to do if there is no buffer. */ 8744 if (!out) 8745 return len; 8746 if (!out->args.vc.pattern_n) 8747 return -1; 8748 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8749 data_size = ctx->objdata / 3; /* spec, last, mask */ 8750 /* Point to selected object. */ 8751 ctx->object = out->args.vc.data + (data_size * index); 8752 if (objmask) { 8753 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 8754 item->mask = ctx->objmask; 8755 } else 8756 ctx->objmask = NULL; 8757 /* Update relevant item pointer. */ 8758 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 8759 ctx->object; 8760 return len; 8761 } 8762 8763 /** Parse action configuration field. */ 8764 static int 8765 parse_vc_conf(struct context *ctx, const struct token *token, 8766 const char *str, unsigned int len, 8767 void *buf, unsigned int size) 8768 { 8769 struct buffer *out = buf; 8770 8771 (void)size; 8772 /* Token name must match. */ 8773 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8774 return -1; 8775 /* Nothing else to do if there is no buffer. */ 8776 if (!out) 8777 return len; 8778 /* Point to selected object. */ 8779 ctx->object = out->args.vc.data; 8780 ctx->objmask = NULL; 8781 return len; 8782 } 8783 8784 /** Parse action configuration field. */ 8785 static int 8786 parse_vc_conf_timeout(struct context *ctx, const struct token *token, 8787 const char *str, unsigned int len, 8788 void *buf, unsigned int size) 8789 { 8790 struct buffer *out = buf; 8791 struct rte_flow_update_age *update; 8792 8793 (void)size; 8794 if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) 8795 return -1; 8796 /* Token name must match. */ 8797 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8798 return -1; 8799 /* Nothing else to do if there is no buffer. */ 8800 if (!out) 8801 return len; 8802 /* Point to selected object. */ 8803 ctx->object = out->args.vc.data; 8804 ctx->objmask = NULL; 8805 /* Update the timeout is valid. */ 8806 update = (struct rte_flow_update_age *)out->args.vc.data; 8807 update->timeout_valid = 1; 8808 return len; 8809 } 8810 8811 /** Parse eCPRI common header type field. */ 8812 static int 8813 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 8814 const char *str, unsigned int len, 8815 void *buf, unsigned int size) 8816 { 8817 struct rte_flow_item_ecpri *ecpri; 8818 struct rte_flow_item_ecpri *ecpri_mask; 8819 struct rte_flow_item *item; 8820 uint32_t data_size; 8821 uint8_t msg_type; 8822 struct buffer *out = buf; 8823 const struct arg *arg; 8824 8825 (void)size; 8826 /* Token name must match. */ 8827 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8828 return -1; 8829 switch (ctx->curr) { 8830 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 8831 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 8832 break; 8833 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 8834 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 8835 break; 8836 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 8837 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 8838 break; 8839 default: 8840 return -1; 8841 } 8842 if (!ctx->object) 8843 return len; 8844 arg = pop_args(ctx); 8845 if (!arg) 8846 return -1; 8847 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 8848 ecpri->hdr.common.type = msg_type; 8849 data_size = ctx->objdata / 3; /* spec, last, mask */ 8850 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 8851 (data_size * 2)); 8852 ecpri_mask->hdr.common.type = 0xFF; 8853 if (arg->hton) { 8854 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 8855 ecpri_mask->hdr.common.u32 = 8856 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 8857 } 8858 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8859 item->spec = ecpri; 8860 item->mask = ecpri_mask; 8861 return len; 8862 } 8863 8864 /** Parse L2TPv2 common header type field. */ 8865 static int 8866 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, 8867 const char *str, unsigned int len, 8868 void *buf, unsigned int size) 8869 { 8870 struct rte_flow_item_l2tpv2 *l2tpv2; 8871 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 8872 struct rte_flow_item *item; 8873 uint32_t data_size; 8874 uint16_t msg_type = 0; 8875 struct buffer *out = buf; 8876 const struct arg *arg; 8877 8878 (void)size; 8879 /* Token name must match. */ 8880 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8881 return -1; 8882 switch (ctx->curr) { 8883 case ITEM_L2TPV2_TYPE_DATA: 8884 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 8885 break; 8886 case ITEM_L2TPV2_TYPE_DATA_L: 8887 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 8888 break; 8889 case ITEM_L2TPV2_TYPE_DATA_S: 8890 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 8891 break; 8892 case ITEM_L2TPV2_TYPE_DATA_O: 8893 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 8894 break; 8895 case ITEM_L2TPV2_TYPE_DATA_L_S: 8896 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 8897 break; 8898 case ITEM_L2TPV2_TYPE_CTRL: 8899 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 8900 break; 8901 default: 8902 return -1; 8903 } 8904 if (!ctx->object) 8905 return len; 8906 arg = pop_args(ctx); 8907 if (!arg) 8908 return -1; 8909 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 8910 l2tpv2->hdr.common.flags_version |= msg_type; 8911 data_size = ctx->objdata / 3; /* spec, last, mask */ 8912 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 8913 (data_size * 2)); 8914 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 8915 if (arg->hton) { 8916 l2tpv2->hdr.common.flags_version = 8917 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 8918 l2tpv2_mask->hdr.common.flags_version = 8919 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 8920 } 8921 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8922 item->spec = l2tpv2; 8923 item->mask = l2tpv2_mask; 8924 return len; 8925 } 8926 8927 /** Parse operation for compare match item. */ 8928 static int 8929 parse_vc_compare_op(struct context *ctx, const struct token *token, 8930 const char *str, unsigned int len, void *buf, 8931 unsigned int size) 8932 { 8933 struct rte_flow_item_compare *compare_item; 8934 unsigned int i; 8935 8936 (void)token; 8937 (void)buf; 8938 (void)size; 8939 if (ctx->curr != ITEM_COMPARE_OP_VALUE) 8940 return -1; 8941 for (i = 0; compare_ops[i]; ++i) 8942 if (!strcmp_partial(compare_ops[i], str, len)) 8943 break; 8944 if (!compare_ops[i]) 8945 return -1; 8946 if (!ctx->object) 8947 return len; 8948 compare_item = ctx->object; 8949 compare_item->operation = (enum rte_flow_item_compare_op)i; 8950 return len; 8951 } 8952 8953 /** Parse id for compare match item. */ 8954 static int 8955 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 8956 const char *str, unsigned int len, void *buf, 8957 unsigned int size) 8958 { 8959 struct rte_flow_item_compare *compare_item; 8960 unsigned int i; 8961 8962 (void)token; 8963 (void)buf; 8964 (void)size; 8965 if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE && 8966 ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE) 8967 return -1; 8968 for (i = 0; flow_field_ids[i]; ++i) 8969 if (!strcmp_partial(flow_field_ids[i], str, len)) 8970 break; 8971 if (!flow_field_ids[i]) 8972 return -1; 8973 if (!ctx->object) 8974 return len; 8975 compare_item = ctx->object; 8976 if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE) 8977 compare_item->a.field = (enum rte_flow_field_id)i; 8978 else 8979 compare_item->b.field = (enum rte_flow_field_id)i; 8980 return len; 8981 } 8982 8983 /** Parse level for compare match item. */ 8984 static int 8985 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 8986 const char *str, unsigned int len, void *buf, 8987 unsigned int size) 8988 { 8989 struct rte_flow_item_compare *compare_item; 8990 struct flex_item *fp = NULL; 8991 uint32_t val; 8992 struct buffer *out = buf; 8993 char *end; 8994 8995 (void)token; 8996 (void)size; 8997 if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 8998 ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE) 8999 return -1; 9000 if (!ctx->object) 9001 return len; 9002 compare_item = ctx->object; 9003 errno = 0; 9004 val = strtoumax(str, &end, 0); 9005 if (errno || (size_t)(end - str) != len) 9006 return -1; 9007 /* No need to validate action template mask value */ 9008 if (out->args.vc.masks) { 9009 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) 9010 compare_item->a.level = val; 9011 else 9012 compare_item->b.level = val; 9013 return len; 9014 } 9015 if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 9016 compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) || 9017 (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE && 9018 compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 9019 if (val >= FLEX_MAX_PARSERS_NUM) { 9020 printf("Bad flex item handle\n"); 9021 return -1; 9022 } 9023 fp = flex_items[ctx->port][val]; 9024 if (!fp) { 9025 printf("Bad flex item handle\n"); 9026 return -1; 9027 } 9028 } 9029 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) { 9030 if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM) 9031 compare_item->a.level = val; 9032 else 9033 compare_item->a.flex_handle = fp->flex_handle; 9034 } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) { 9035 if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM) 9036 compare_item->b.level = val; 9037 else 9038 compare_item->b.flex_handle = fp->flex_handle; 9039 } 9040 return len; 9041 } 9042 9043 /** Parse meter color action type. */ 9044 static int 9045 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 9046 const char *str, unsigned int len, 9047 void *buf, unsigned int size) 9048 { 9049 struct rte_flow_action *action_data; 9050 struct rte_flow_action_meter_color *conf; 9051 enum rte_color color; 9052 9053 (void)buf; 9054 (void)size; 9055 /* Token name must match. */ 9056 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9057 return -1; 9058 switch (ctx->curr) { 9059 case ACTION_METER_COLOR_GREEN: 9060 color = RTE_COLOR_GREEN; 9061 break; 9062 case ACTION_METER_COLOR_YELLOW: 9063 color = RTE_COLOR_YELLOW; 9064 break; 9065 case ACTION_METER_COLOR_RED: 9066 color = RTE_COLOR_RED; 9067 break; 9068 default: 9069 return -1; 9070 } 9071 9072 if (!ctx->object) 9073 return len; 9074 action_data = ctx->object; 9075 conf = (struct rte_flow_action_meter_color *) 9076 (uintptr_t)(action_data->conf); 9077 conf->color = color; 9078 return len; 9079 } 9080 9081 /** Parse RSS action. */ 9082 static int 9083 parse_vc_action_rss(struct context *ctx, const struct token *token, 9084 const char *str, unsigned int len, 9085 void *buf, unsigned int size) 9086 { 9087 struct buffer *out = buf; 9088 struct rte_flow_action *action; 9089 struct action_rss_data *action_rss_data; 9090 unsigned int i; 9091 int ret; 9092 9093 ret = parse_vc(ctx, token, str, len, buf, size); 9094 if (ret < 0) 9095 return ret; 9096 /* Nothing else to do if there is no buffer. */ 9097 if (!out) 9098 return ret; 9099 if (!out->args.vc.actions_n) 9100 return -1; 9101 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9102 /* Point to selected object. */ 9103 ctx->object = out->args.vc.data; 9104 ctx->objmask = NULL; 9105 /* Set up default configuration. */ 9106 action_rss_data = ctx->object; 9107 *action_rss_data = (struct action_rss_data){ 9108 .conf = (struct rte_flow_action_rss){ 9109 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 9110 .level = 0, 9111 .types = rss_hf, 9112 .key_len = 0, 9113 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 9114 .key = NULL, 9115 .queue = action_rss_data->queue, 9116 }, 9117 .queue = { 0 }, 9118 }; 9119 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 9120 action_rss_data->queue[i] = i; 9121 action->conf = &action_rss_data->conf; 9122 return ret; 9123 } 9124 9125 /** 9126 * Parse func field for RSS action. 9127 * 9128 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 9129 * ACTION_RSS_FUNC_* index that called this function. 9130 */ 9131 static int 9132 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 9133 const char *str, unsigned int len, 9134 void *buf, unsigned int size) 9135 { 9136 struct action_rss_data *action_rss_data; 9137 enum rte_eth_hash_function func; 9138 9139 (void)buf; 9140 (void)size; 9141 /* Token name must match. */ 9142 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9143 return -1; 9144 switch (ctx->curr) { 9145 case ACTION_RSS_FUNC_DEFAULT: 9146 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 9147 break; 9148 case ACTION_RSS_FUNC_TOEPLITZ: 9149 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 9150 break; 9151 case ACTION_RSS_FUNC_SIMPLE_XOR: 9152 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 9153 break; 9154 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 9155 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 9156 break; 9157 default: 9158 return -1; 9159 } 9160 if (!ctx->object) 9161 return len; 9162 action_rss_data = ctx->object; 9163 action_rss_data->conf.func = func; 9164 return len; 9165 } 9166 9167 /** 9168 * Parse type field for RSS action. 9169 * 9170 * Valid tokens are type field names and the "end" token. 9171 */ 9172 static int 9173 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 9174 const char *str, unsigned int len, 9175 void *buf, unsigned int size) 9176 { 9177 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 9178 struct action_rss_data *action_rss_data; 9179 unsigned int i; 9180 9181 (void)token; 9182 (void)buf; 9183 (void)size; 9184 if (ctx->curr != ACTION_RSS_TYPE) 9185 return -1; 9186 if (!(ctx->objdata >> 16) && ctx->object) { 9187 action_rss_data = ctx->object; 9188 action_rss_data->conf.types = 0; 9189 } 9190 if (!strcmp_partial("end", str, len)) { 9191 ctx->objdata &= 0xffff; 9192 return len; 9193 } 9194 for (i = 0; rss_type_table[i].str; ++i) 9195 if (!strcmp_partial(rss_type_table[i].str, str, len)) 9196 break; 9197 if (!rss_type_table[i].str) 9198 return -1; 9199 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 9200 /* Repeat token. */ 9201 if (ctx->next_num == RTE_DIM(ctx->next)) 9202 return -1; 9203 ctx->next[ctx->next_num++] = next; 9204 if (!ctx->object) 9205 return len; 9206 action_rss_data = ctx->object; 9207 action_rss_data->conf.types |= rss_type_table[i].rss_type; 9208 return len; 9209 } 9210 9211 /** 9212 * Parse queue field for RSS action. 9213 * 9214 * Valid tokens are queue indices and the "end" token. 9215 */ 9216 static int 9217 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 9218 const char *str, unsigned int len, 9219 void *buf, unsigned int size) 9220 { 9221 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 9222 struct action_rss_data *action_rss_data; 9223 const struct arg *arg; 9224 int ret; 9225 int i; 9226 9227 (void)token; 9228 (void)buf; 9229 (void)size; 9230 if (ctx->curr != ACTION_RSS_QUEUE) 9231 return -1; 9232 i = ctx->objdata >> 16; 9233 if (!strcmp_partial("end", str, len)) { 9234 ctx->objdata &= 0xffff; 9235 goto end; 9236 } 9237 if (i >= ACTION_RSS_QUEUE_NUM) 9238 return -1; 9239 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 9240 i * sizeof(action_rss_data->queue[i]), 9241 sizeof(action_rss_data->queue[i])); 9242 if (push_args(ctx, arg)) 9243 return -1; 9244 ret = parse_int(ctx, token, str, len, NULL, 0); 9245 if (ret < 0) { 9246 pop_args(ctx); 9247 return -1; 9248 } 9249 ++i; 9250 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 9251 /* Repeat token. */ 9252 if (ctx->next_num == RTE_DIM(ctx->next)) 9253 return -1; 9254 ctx->next[ctx->next_num++] = next; 9255 end: 9256 if (!ctx->object) 9257 return len; 9258 action_rss_data = ctx->object; 9259 action_rss_data->conf.queue_num = i; 9260 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 9261 return len; 9262 } 9263 9264 /** Setup VXLAN encap configuration. */ 9265 static int 9266 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 9267 { 9268 /* Set up default configuration. */ 9269 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 9270 .conf = (struct rte_flow_action_vxlan_encap){ 9271 .definition = action_vxlan_encap_data->items, 9272 }, 9273 .items = { 9274 { 9275 .type = RTE_FLOW_ITEM_TYPE_ETH, 9276 .spec = &action_vxlan_encap_data->item_eth, 9277 .mask = &rte_flow_item_eth_mask, 9278 }, 9279 { 9280 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9281 .spec = &action_vxlan_encap_data->item_vlan, 9282 .mask = &rte_flow_item_vlan_mask, 9283 }, 9284 { 9285 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9286 .spec = &action_vxlan_encap_data->item_ipv4, 9287 .mask = &rte_flow_item_ipv4_mask, 9288 }, 9289 { 9290 .type = RTE_FLOW_ITEM_TYPE_UDP, 9291 .spec = &action_vxlan_encap_data->item_udp, 9292 .mask = &rte_flow_item_udp_mask, 9293 }, 9294 { 9295 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 9296 .spec = &action_vxlan_encap_data->item_vxlan, 9297 .mask = &rte_flow_item_vxlan_mask, 9298 }, 9299 { 9300 .type = RTE_FLOW_ITEM_TYPE_END, 9301 }, 9302 }, 9303 .item_eth.hdr.ether_type = 0, 9304 .item_vlan = { 9305 .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, 9306 .hdr.eth_proto = 0, 9307 }, 9308 .item_ipv4.hdr = { 9309 .src_addr = vxlan_encap_conf.ipv4_src, 9310 .dst_addr = vxlan_encap_conf.ipv4_dst, 9311 }, 9312 .item_udp.hdr = { 9313 .src_port = vxlan_encap_conf.udp_src, 9314 .dst_port = vxlan_encap_conf.udp_dst, 9315 }, 9316 .item_vxlan.hdr.flags = 0, 9317 }; 9318 memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9319 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9320 memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, 9321 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9322 if (!vxlan_encap_conf.select_ipv4) { 9323 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 9324 &vxlan_encap_conf.ipv6_src, 9325 sizeof(vxlan_encap_conf.ipv6_src)); 9326 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 9327 &vxlan_encap_conf.ipv6_dst, 9328 sizeof(vxlan_encap_conf.ipv6_dst)); 9329 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 9330 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9331 .spec = &action_vxlan_encap_data->item_ipv6, 9332 .mask = &rte_flow_item_ipv6_mask, 9333 }; 9334 } 9335 if (!vxlan_encap_conf.select_vlan) 9336 action_vxlan_encap_data->items[1].type = 9337 RTE_FLOW_ITEM_TYPE_VOID; 9338 if (vxlan_encap_conf.select_tos_ttl) { 9339 if (vxlan_encap_conf.select_ipv4) { 9340 static struct rte_flow_item_ipv4 ipv4_mask_tos; 9341 9342 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 9343 sizeof(ipv4_mask_tos)); 9344 ipv4_mask_tos.hdr.type_of_service = 0xff; 9345 ipv4_mask_tos.hdr.time_to_live = 0xff; 9346 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 9347 vxlan_encap_conf.ip_tos; 9348 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 9349 vxlan_encap_conf.ip_ttl; 9350 action_vxlan_encap_data->items[2].mask = 9351 &ipv4_mask_tos; 9352 } else { 9353 static struct rte_flow_item_ipv6 ipv6_mask_tos; 9354 9355 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 9356 sizeof(ipv6_mask_tos)); 9357 ipv6_mask_tos.hdr.vtc_flow |= 9358 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 9359 ipv6_mask_tos.hdr.hop_limits = 0xff; 9360 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 9361 rte_cpu_to_be_32 9362 ((uint32_t)vxlan_encap_conf.ip_tos << 9363 RTE_IPV6_HDR_TC_SHIFT); 9364 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 9365 vxlan_encap_conf.ip_ttl; 9366 action_vxlan_encap_data->items[2].mask = 9367 &ipv6_mask_tos; 9368 } 9369 } 9370 memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, 9371 RTE_DIM(vxlan_encap_conf.vni)); 9372 return 0; 9373 } 9374 9375 /** Parse VXLAN encap action. */ 9376 static int 9377 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 9378 const char *str, unsigned int len, 9379 void *buf, unsigned int size) 9380 { 9381 struct buffer *out = buf; 9382 struct rte_flow_action *action; 9383 struct action_vxlan_encap_data *action_vxlan_encap_data; 9384 int ret; 9385 9386 ret = parse_vc(ctx, token, str, len, buf, size); 9387 if (ret < 0) 9388 return ret; 9389 /* Nothing else to do if there is no buffer. */ 9390 if (!out) 9391 return ret; 9392 if (!out->args.vc.actions_n) 9393 return -1; 9394 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9395 /* Point to selected object. */ 9396 ctx->object = out->args.vc.data; 9397 ctx->objmask = NULL; 9398 action_vxlan_encap_data = ctx->object; 9399 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 9400 action->conf = &action_vxlan_encap_data->conf; 9401 return ret; 9402 } 9403 9404 /** Setup NVGRE encap configuration. */ 9405 static int 9406 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 9407 { 9408 /* Set up default configuration. */ 9409 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 9410 .conf = (struct rte_flow_action_nvgre_encap){ 9411 .definition = action_nvgre_encap_data->items, 9412 }, 9413 .items = { 9414 { 9415 .type = RTE_FLOW_ITEM_TYPE_ETH, 9416 .spec = &action_nvgre_encap_data->item_eth, 9417 .mask = &rte_flow_item_eth_mask, 9418 }, 9419 { 9420 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9421 .spec = &action_nvgre_encap_data->item_vlan, 9422 .mask = &rte_flow_item_vlan_mask, 9423 }, 9424 { 9425 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9426 .spec = &action_nvgre_encap_data->item_ipv4, 9427 .mask = &rte_flow_item_ipv4_mask, 9428 }, 9429 { 9430 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 9431 .spec = &action_nvgre_encap_data->item_nvgre, 9432 .mask = &rte_flow_item_nvgre_mask, 9433 }, 9434 { 9435 .type = RTE_FLOW_ITEM_TYPE_END, 9436 }, 9437 }, 9438 .item_eth.hdr.ether_type = 0, 9439 .item_vlan = { 9440 .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, 9441 .hdr.eth_proto = 0, 9442 }, 9443 .item_ipv4.hdr = { 9444 .src_addr = nvgre_encap_conf.ipv4_src, 9445 .dst_addr = nvgre_encap_conf.ipv4_dst, 9446 }, 9447 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 9448 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 9449 .item_nvgre.flow_id = 0, 9450 }; 9451 memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9452 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9453 memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, 9454 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9455 if (!nvgre_encap_conf.select_ipv4) { 9456 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 9457 &nvgre_encap_conf.ipv6_src, 9458 sizeof(nvgre_encap_conf.ipv6_src)); 9459 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 9460 &nvgre_encap_conf.ipv6_dst, 9461 sizeof(nvgre_encap_conf.ipv6_dst)); 9462 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 9463 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9464 .spec = &action_nvgre_encap_data->item_ipv6, 9465 .mask = &rte_flow_item_ipv6_mask, 9466 }; 9467 } 9468 if (!nvgre_encap_conf.select_vlan) 9469 action_nvgre_encap_data->items[1].type = 9470 RTE_FLOW_ITEM_TYPE_VOID; 9471 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 9472 RTE_DIM(nvgre_encap_conf.tni)); 9473 return 0; 9474 } 9475 9476 /** Parse NVGRE encap action. */ 9477 static int 9478 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 9479 const char *str, unsigned int len, 9480 void *buf, unsigned int size) 9481 { 9482 struct buffer *out = buf; 9483 struct rte_flow_action *action; 9484 struct action_nvgre_encap_data *action_nvgre_encap_data; 9485 int ret; 9486 9487 ret = parse_vc(ctx, token, str, len, buf, size); 9488 if (ret < 0) 9489 return ret; 9490 /* Nothing else to do if there is no buffer. */ 9491 if (!out) 9492 return ret; 9493 if (!out->args.vc.actions_n) 9494 return -1; 9495 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9496 /* Point to selected object. */ 9497 ctx->object = out->args.vc.data; 9498 ctx->objmask = NULL; 9499 action_nvgre_encap_data = ctx->object; 9500 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 9501 action->conf = &action_nvgre_encap_data->conf; 9502 return ret; 9503 } 9504 9505 /** Parse l2 encap action. */ 9506 static int 9507 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 9508 const char *str, unsigned int len, 9509 void *buf, unsigned int size) 9510 { 9511 struct buffer *out = buf; 9512 struct rte_flow_action *action; 9513 struct action_raw_encap_data *action_encap_data; 9514 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9515 struct rte_flow_item_vlan vlan = { 9516 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9517 .hdr.eth_proto = 0, 9518 }; 9519 uint8_t *header; 9520 int ret; 9521 9522 ret = parse_vc(ctx, token, str, len, buf, size); 9523 if (ret < 0) 9524 return ret; 9525 /* Nothing else to do if there is no buffer. */ 9526 if (!out) 9527 return ret; 9528 if (!out->args.vc.actions_n) 9529 return -1; 9530 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9531 /* Point to selected object. */ 9532 ctx->object = out->args.vc.data; 9533 ctx->objmask = NULL; 9534 /* Copy the headers to the buffer. */ 9535 action_encap_data = ctx->object; 9536 *action_encap_data = (struct action_raw_encap_data) { 9537 .conf = (struct rte_flow_action_raw_encap){ 9538 .data = action_encap_data->data, 9539 }, 9540 .data = {}, 9541 }; 9542 header = action_encap_data->data; 9543 if (l2_encap_conf.select_vlan) 9544 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9545 else if (l2_encap_conf.select_ipv4) 9546 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9547 else 9548 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9549 memcpy(eth.hdr.dst_addr.addr_bytes, 9550 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9551 memcpy(eth.hdr.src_addr.addr_bytes, 9552 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9553 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9554 header += sizeof(struct rte_ether_hdr); 9555 if (l2_encap_conf.select_vlan) { 9556 if (l2_encap_conf.select_ipv4) 9557 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9558 else 9559 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9560 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9561 header += sizeof(struct rte_vlan_hdr); 9562 } 9563 action_encap_data->conf.size = header - 9564 action_encap_data->data; 9565 action->conf = &action_encap_data->conf; 9566 return ret; 9567 } 9568 9569 /** Parse l2 decap action. */ 9570 static int 9571 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 9572 const char *str, unsigned int len, 9573 void *buf, unsigned int size) 9574 { 9575 struct buffer *out = buf; 9576 struct rte_flow_action *action; 9577 struct action_raw_decap_data *action_decap_data; 9578 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9579 struct rte_flow_item_vlan vlan = { 9580 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9581 .hdr.eth_proto = 0, 9582 }; 9583 uint8_t *header; 9584 int ret; 9585 9586 ret = parse_vc(ctx, token, str, len, buf, size); 9587 if (ret < 0) 9588 return ret; 9589 /* Nothing else to do if there is no buffer. */ 9590 if (!out) 9591 return ret; 9592 if (!out->args.vc.actions_n) 9593 return -1; 9594 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9595 /* Point to selected object. */ 9596 ctx->object = out->args.vc.data; 9597 ctx->objmask = NULL; 9598 /* Copy the headers to the buffer. */ 9599 action_decap_data = ctx->object; 9600 *action_decap_data = (struct action_raw_decap_data) { 9601 .conf = (struct rte_flow_action_raw_decap){ 9602 .data = action_decap_data->data, 9603 }, 9604 .data = {}, 9605 }; 9606 header = action_decap_data->data; 9607 if (l2_decap_conf.select_vlan) 9608 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9609 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9610 header += sizeof(struct rte_ether_hdr); 9611 if (l2_decap_conf.select_vlan) { 9612 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9613 header += sizeof(struct rte_vlan_hdr); 9614 } 9615 action_decap_data->conf.size = header - 9616 action_decap_data->data; 9617 action->conf = &action_decap_data->conf; 9618 return ret; 9619 } 9620 9621 #define ETHER_TYPE_MPLS_UNICAST 0x8847 9622 9623 /** Parse MPLSOGRE encap action. */ 9624 static int 9625 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 9626 const char *str, unsigned int len, 9627 void *buf, unsigned int size) 9628 { 9629 struct buffer *out = buf; 9630 struct rte_flow_action *action; 9631 struct action_raw_encap_data *action_encap_data; 9632 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9633 struct rte_flow_item_vlan vlan = { 9634 .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, 9635 .hdr.eth_proto = 0, 9636 }; 9637 struct rte_flow_item_ipv4 ipv4 = { 9638 .hdr = { 9639 .src_addr = mplsogre_encap_conf.ipv4_src, 9640 .dst_addr = mplsogre_encap_conf.ipv4_dst, 9641 .next_proto_id = IPPROTO_GRE, 9642 .version_ihl = RTE_IPV4_VHL_DEF, 9643 .time_to_live = IPDEFTTL, 9644 }, 9645 }; 9646 struct rte_flow_item_ipv6 ipv6 = { 9647 .hdr = { 9648 .proto = IPPROTO_GRE, 9649 .hop_limits = IPDEFTTL, 9650 }, 9651 }; 9652 struct rte_flow_item_gre gre = { 9653 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9654 }; 9655 struct rte_flow_item_mpls mpls = { 9656 .ttl = 0, 9657 }; 9658 uint8_t *header; 9659 int ret; 9660 9661 ret = parse_vc(ctx, token, str, len, buf, size); 9662 if (ret < 0) 9663 return ret; 9664 /* Nothing else to do if there is no buffer. */ 9665 if (!out) 9666 return ret; 9667 if (!out->args.vc.actions_n) 9668 return -1; 9669 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9670 /* Point to selected object. */ 9671 ctx->object = out->args.vc.data; 9672 ctx->objmask = NULL; 9673 /* Copy the headers to the buffer. */ 9674 action_encap_data = ctx->object; 9675 *action_encap_data = (struct action_raw_encap_data) { 9676 .conf = (struct rte_flow_action_raw_encap){ 9677 .data = action_encap_data->data, 9678 }, 9679 .data = {}, 9680 .preserve = {}, 9681 }; 9682 header = action_encap_data->data; 9683 if (mplsogre_encap_conf.select_vlan) 9684 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9685 else if (mplsogre_encap_conf.select_ipv4) 9686 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9687 else 9688 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9689 memcpy(eth.hdr.dst_addr.addr_bytes, 9690 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9691 memcpy(eth.hdr.src_addr.addr_bytes, 9692 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9693 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9694 header += sizeof(struct rte_ether_hdr); 9695 if (mplsogre_encap_conf.select_vlan) { 9696 if (mplsogre_encap_conf.select_ipv4) 9697 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9698 else 9699 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9700 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9701 header += sizeof(struct rte_vlan_hdr); 9702 } 9703 if (mplsogre_encap_conf.select_ipv4) { 9704 memcpy(header, &ipv4, sizeof(ipv4)); 9705 header += sizeof(ipv4); 9706 } else { 9707 memcpy(&ipv6.hdr.src_addr, 9708 &mplsogre_encap_conf.ipv6_src, 9709 sizeof(mplsogre_encap_conf.ipv6_src)); 9710 memcpy(&ipv6.hdr.dst_addr, 9711 &mplsogre_encap_conf.ipv6_dst, 9712 sizeof(mplsogre_encap_conf.ipv6_dst)); 9713 memcpy(header, &ipv6, sizeof(ipv6)); 9714 header += sizeof(ipv6); 9715 } 9716 memcpy(header, &gre, sizeof(gre)); 9717 header += sizeof(gre); 9718 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 9719 RTE_DIM(mplsogre_encap_conf.label)); 9720 mpls.label_tc_s[2] |= 0x1; 9721 memcpy(header, &mpls, sizeof(mpls)); 9722 header += sizeof(mpls); 9723 action_encap_data->conf.size = header - 9724 action_encap_data->data; 9725 action->conf = &action_encap_data->conf; 9726 return ret; 9727 } 9728 9729 /** Parse MPLSOGRE decap action. */ 9730 static int 9731 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 9732 const char *str, unsigned int len, 9733 void *buf, unsigned int size) 9734 { 9735 struct buffer *out = buf; 9736 struct rte_flow_action *action; 9737 struct action_raw_decap_data *action_decap_data; 9738 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9739 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9740 struct rte_flow_item_ipv4 ipv4 = { 9741 .hdr = { 9742 .next_proto_id = IPPROTO_GRE, 9743 }, 9744 }; 9745 struct rte_flow_item_ipv6 ipv6 = { 9746 .hdr = { 9747 .proto = IPPROTO_GRE, 9748 }, 9749 }; 9750 struct rte_flow_item_gre gre = { 9751 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9752 }; 9753 struct rte_flow_item_mpls mpls; 9754 uint8_t *header; 9755 int ret; 9756 9757 ret = parse_vc(ctx, token, str, len, buf, size); 9758 if (ret < 0) 9759 return ret; 9760 /* Nothing else to do if there is no buffer. */ 9761 if (!out) 9762 return ret; 9763 if (!out->args.vc.actions_n) 9764 return -1; 9765 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9766 /* Point to selected object. */ 9767 ctx->object = out->args.vc.data; 9768 ctx->objmask = NULL; 9769 /* Copy the headers to the buffer. */ 9770 action_decap_data = ctx->object; 9771 *action_decap_data = (struct action_raw_decap_data) { 9772 .conf = (struct rte_flow_action_raw_decap){ 9773 .data = action_decap_data->data, 9774 }, 9775 .data = {}, 9776 }; 9777 header = action_decap_data->data; 9778 if (mplsogre_decap_conf.select_vlan) 9779 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9780 else if (mplsogre_encap_conf.select_ipv4) 9781 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9782 else 9783 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9784 memcpy(eth.hdr.dst_addr.addr_bytes, 9785 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9786 memcpy(eth.hdr.src_addr.addr_bytes, 9787 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9788 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9789 header += sizeof(struct rte_ether_hdr); 9790 if (mplsogre_encap_conf.select_vlan) { 9791 if (mplsogre_encap_conf.select_ipv4) 9792 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9793 else 9794 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9795 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9796 header += sizeof(struct rte_vlan_hdr); 9797 } 9798 if (mplsogre_encap_conf.select_ipv4) { 9799 memcpy(header, &ipv4, sizeof(ipv4)); 9800 header += sizeof(ipv4); 9801 } else { 9802 memcpy(header, &ipv6, sizeof(ipv6)); 9803 header += sizeof(ipv6); 9804 } 9805 memcpy(header, &gre, sizeof(gre)); 9806 header += sizeof(gre); 9807 memset(&mpls, 0, sizeof(mpls)); 9808 memcpy(header, &mpls, sizeof(mpls)); 9809 header += sizeof(mpls); 9810 action_decap_data->conf.size = header - 9811 action_decap_data->data; 9812 action->conf = &action_decap_data->conf; 9813 return ret; 9814 } 9815 9816 /** Parse MPLSOUDP encap action. */ 9817 static int 9818 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 9819 const char *str, unsigned int len, 9820 void *buf, unsigned int size) 9821 { 9822 struct buffer *out = buf; 9823 struct rte_flow_action *action; 9824 struct action_raw_encap_data *action_encap_data; 9825 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9826 struct rte_flow_item_vlan vlan = { 9827 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9828 .hdr.eth_proto = 0, 9829 }; 9830 struct rte_flow_item_ipv4 ipv4 = { 9831 .hdr = { 9832 .src_addr = mplsoudp_encap_conf.ipv4_src, 9833 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 9834 .next_proto_id = IPPROTO_UDP, 9835 .version_ihl = RTE_IPV4_VHL_DEF, 9836 .time_to_live = IPDEFTTL, 9837 }, 9838 }; 9839 struct rte_flow_item_ipv6 ipv6 = { 9840 .hdr = { 9841 .proto = IPPROTO_UDP, 9842 .hop_limits = IPDEFTTL, 9843 }, 9844 }; 9845 struct rte_flow_item_udp udp = { 9846 .hdr = { 9847 .src_port = mplsoudp_encap_conf.udp_src, 9848 .dst_port = mplsoudp_encap_conf.udp_dst, 9849 }, 9850 }; 9851 struct rte_flow_item_mpls mpls; 9852 uint8_t *header; 9853 int ret; 9854 9855 ret = parse_vc(ctx, token, str, len, buf, size); 9856 if (ret < 0) 9857 return ret; 9858 /* Nothing else to do if there is no buffer. */ 9859 if (!out) 9860 return ret; 9861 if (!out->args.vc.actions_n) 9862 return -1; 9863 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9864 /* Point to selected object. */ 9865 ctx->object = out->args.vc.data; 9866 ctx->objmask = NULL; 9867 /* Copy the headers to the buffer. */ 9868 action_encap_data = ctx->object; 9869 *action_encap_data = (struct action_raw_encap_data) { 9870 .conf = (struct rte_flow_action_raw_encap){ 9871 .data = action_encap_data->data, 9872 }, 9873 .data = {}, 9874 .preserve = {}, 9875 }; 9876 header = action_encap_data->data; 9877 if (mplsoudp_encap_conf.select_vlan) 9878 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9879 else if (mplsoudp_encap_conf.select_ipv4) 9880 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9881 else 9882 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9883 memcpy(eth.hdr.dst_addr.addr_bytes, 9884 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9885 memcpy(eth.hdr.src_addr.addr_bytes, 9886 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9887 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9888 header += sizeof(struct rte_ether_hdr); 9889 if (mplsoudp_encap_conf.select_vlan) { 9890 if (mplsoudp_encap_conf.select_ipv4) 9891 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9892 else 9893 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9894 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9895 header += sizeof(struct rte_vlan_hdr); 9896 } 9897 if (mplsoudp_encap_conf.select_ipv4) { 9898 memcpy(header, &ipv4, sizeof(ipv4)); 9899 header += sizeof(ipv4); 9900 } else { 9901 memcpy(&ipv6.hdr.src_addr, 9902 &mplsoudp_encap_conf.ipv6_src, 9903 sizeof(mplsoudp_encap_conf.ipv6_src)); 9904 memcpy(&ipv6.hdr.dst_addr, 9905 &mplsoudp_encap_conf.ipv6_dst, 9906 sizeof(mplsoudp_encap_conf.ipv6_dst)); 9907 memcpy(header, &ipv6, sizeof(ipv6)); 9908 header += sizeof(ipv6); 9909 } 9910 memcpy(header, &udp, sizeof(udp)); 9911 header += sizeof(udp); 9912 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 9913 RTE_DIM(mplsoudp_encap_conf.label)); 9914 mpls.label_tc_s[2] |= 0x1; 9915 memcpy(header, &mpls, sizeof(mpls)); 9916 header += sizeof(mpls); 9917 action_encap_data->conf.size = header - 9918 action_encap_data->data; 9919 action->conf = &action_encap_data->conf; 9920 return ret; 9921 } 9922 9923 /** Parse MPLSOUDP decap action. */ 9924 static int 9925 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 9926 const char *str, unsigned int len, 9927 void *buf, unsigned int size) 9928 { 9929 struct buffer *out = buf; 9930 struct rte_flow_action *action; 9931 struct action_raw_decap_data *action_decap_data; 9932 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9933 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9934 struct rte_flow_item_ipv4 ipv4 = { 9935 .hdr = { 9936 .next_proto_id = IPPROTO_UDP, 9937 }, 9938 }; 9939 struct rte_flow_item_ipv6 ipv6 = { 9940 .hdr = { 9941 .proto = IPPROTO_UDP, 9942 }, 9943 }; 9944 struct rte_flow_item_udp udp = { 9945 .hdr = { 9946 .dst_port = rte_cpu_to_be_16(6635), 9947 }, 9948 }; 9949 struct rte_flow_item_mpls mpls; 9950 uint8_t *header; 9951 int ret; 9952 9953 ret = parse_vc(ctx, token, str, len, buf, size); 9954 if (ret < 0) 9955 return ret; 9956 /* Nothing else to do if there is no buffer. */ 9957 if (!out) 9958 return ret; 9959 if (!out->args.vc.actions_n) 9960 return -1; 9961 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9962 /* Point to selected object. */ 9963 ctx->object = out->args.vc.data; 9964 ctx->objmask = NULL; 9965 /* Copy the headers to the buffer. */ 9966 action_decap_data = ctx->object; 9967 *action_decap_data = (struct action_raw_decap_data) { 9968 .conf = (struct rte_flow_action_raw_decap){ 9969 .data = action_decap_data->data, 9970 }, 9971 .data = {}, 9972 }; 9973 header = action_decap_data->data; 9974 if (mplsoudp_decap_conf.select_vlan) 9975 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9976 else if (mplsoudp_encap_conf.select_ipv4) 9977 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9978 else 9979 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9980 memcpy(eth.hdr.dst_addr.addr_bytes, 9981 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9982 memcpy(eth.hdr.src_addr.addr_bytes, 9983 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9984 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9985 header += sizeof(struct rte_ether_hdr); 9986 if (mplsoudp_encap_conf.select_vlan) { 9987 if (mplsoudp_encap_conf.select_ipv4) 9988 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9989 else 9990 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9991 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9992 header += sizeof(struct rte_vlan_hdr); 9993 } 9994 if (mplsoudp_encap_conf.select_ipv4) { 9995 memcpy(header, &ipv4, sizeof(ipv4)); 9996 header += sizeof(ipv4); 9997 } else { 9998 memcpy(header, &ipv6, sizeof(ipv6)); 9999 header += sizeof(ipv6); 10000 } 10001 memcpy(header, &udp, sizeof(udp)); 10002 header += sizeof(udp); 10003 memset(&mpls, 0, sizeof(mpls)); 10004 memcpy(header, &mpls, sizeof(mpls)); 10005 header += sizeof(mpls); 10006 action_decap_data->conf.size = header - 10007 action_decap_data->data; 10008 action->conf = &action_decap_data->conf; 10009 return ret; 10010 } 10011 10012 static int 10013 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 10014 const char *str, unsigned int len, void *buf, 10015 unsigned int size) 10016 { 10017 struct action_raw_decap_data *action_raw_decap_data; 10018 struct rte_flow_action *action; 10019 const struct arg *arg; 10020 struct buffer *out = buf; 10021 int ret; 10022 uint16_t idx; 10023 10024 RTE_SET_USED(token); 10025 RTE_SET_USED(buf); 10026 RTE_SET_USED(size); 10027 arg = ARGS_ENTRY_ARB_BOUNDED 10028 (offsetof(struct action_raw_decap_data, idx), 10029 sizeof(((struct action_raw_decap_data *)0)->idx), 10030 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10031 if (push_args(ctx, arg)) 10032 return -1; 10033 ret = parse_int(ctx, token, str, len, NULL, 0); 10034 if (ret < 0) { 10035 pop_args(ctx); 10036 return -1; 10037 } 10038 if (!ctx->object) 10039 return len; 10040 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10041 action_raw_decap_data = ctx->object; 10042 idx = action_raw_decap_data->idx; 10043 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 10044 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 10045 action->conf = &action_raw_decap_data->conf; 10046 return len; 10047 } 10048 10049 10050 static int 10051 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 10052 const char *str, unsigned int len, void *buf, 10053 unsigned int size) 10054 { 10055 struct action_raw_encap_data *action_raw_encap_data; 10056 struct rte_flow_action *action; 10057 const struct arg *arg; 10058 struct buffer *out = buf; 10059 int ret; 10060 uint16_t idx; 10061 10062 RTE_SET_USED(token); 10063 RTE_SET_USED(buf); 10064 RTE_SET_USED(size); 10065 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 10066 return -1; 10067 arg = ARGS_ENTRY_ARB_BOUNDED 10068 (offsetof(struct action_raw_encap_data, idx), 10069 sizeof(((struct action_raw_encap_data *)0)->idx), 10070 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10071 if (push_args(ctx, arg)) 10072 return -1; 10073 ret = parse_int(ctx, token, str, len, NULL, 0); 10074 if (ret < 0) { 10075 pop_args(ctx); 10076 return -1; 10077 } 10078 if (!ctx->object) 10079 return len; 10080 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10081 action_raw_encap_data = ctx->object; 10082 idx = action_raw_encap_data->idx; 10083 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 10084 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 10085 action_raw_encap_data->conf.preserve = NULL; 10086 action->conf = &action_raw_encap_data->conf; 10087 return len; 10088 } 10089 10090 static int 10091 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 10092 const char *str, unsigned int len, void *buf, 10093 unsigned int size) 10094 { 10095 struct buffer *out = buf; 10096 int ret; 10097 10098 ret = parse_vc(ctx, token, str, len, buf, size); 10099 if (ret < 0) 10100 return ret; 10101 /* Nothing else to do if there is no buffer. */ 10102 if (!out) 10103 return ret; 10104 if (!out->args.vc.actions_n) 10105 return -1; 10106 /* Point to selected object. */ 10107 ctx->object = out->args.vc.data; 10108 ctx->objmask = NULL; 10109 return ret; 10110 } 10111 10112 static int 10113 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 10114 const char *str, unsigned int len, void *buf, 10115 unsigned int size) 10116 { 10117 struct buffer *out = buf; 10118 struct rte_flow_action *action; 10119 struct action_raw_decap_data *action_raw_decap_data = NULL; 10120 int ret; 10121 10122 ret = parse_vc(ctx, token, str, len, buf, size); 10123 if (ret < 0) 10124 return ret; 10125 /* Nothing else to do if there is no buffer. */ 10126 if (!out) 10127 return ret; 10128 if (!out->args.vc.actions_n) 10129 return -1; 10130 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10131 /* Point to selected object. */ 10132 ctx->object = out->args.vc.data; 10133 ctx->objmask = NULL; 10134 /* Copy the headers to the buffer. */ 10135 action_raw_decap_data = ctx->object; 10136 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 10137 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 10138 action->conf = &action_raw_decap_data->conf; 10139 return ret; 10140 } 10141 10142 static int 10143 parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 10144 const char *str, unsigned int len, void *buf, 10145 unsigned int size) 10146 { 10147 struct buffer *out = buf; 10148 struct rte_flow_action *action; 10149 struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; 10150 int ret; 10151 10152 ret = parse_vc(ctx, token, str, len, buf, size); 10153 if (ret < 0) 10154 return ret; 10155 /* Nothing else to do if there is no buffer. */ 10156 if (!out) 10157 return ret; 10158 if (!out->args.vc.actions_n) 10159 return -1; 10160 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10161 /* Point to selected object. */ 10162 ctx->object = out->args.vc.data; 10163 ctx->objmask = NULL; 10164 /* Copy the headers to the buffer. */ 10165 ipv6_ext_remove_data = ctx->object; 10166 ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; 10167 action->conf = &ipv6_ext_remove_data->conf; 10168 return ret; 10169 } 10170 10171 static int 10172 parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, 10173 const char *str, unsigned int len, void *buf, 10174 unsigned int size) 10175 { 10176 struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; 10177 struct rte_flow_action *action; 10178 const struct arg *arg; 10179 struct buffer *out = buf; 10180 int ret; 10181 uint16_t idx; 10182 10183 RTE_SET_USED(token); 10184 RTE_SET_USED(buf); 10185 RTE_SET_USED(size); 10186 arg = ARGS_ENTRY_ARB_BOUNDED 10187 (offsetof(struct action_ipv6_ext_remove_data, idx), 10188 sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), 10189 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10190 if (push_args(ctx, arg)) 10191 return -1; 10192 ret = parse_int(ctx, token, str, len, NULL, 0); 10193 if (ret < 0) { 10194 pop_args(ctx); 10195 return -1; 10196 } 10197 if (!ctx->object) 10198 return len; 10199 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10200 action_ipv6_ext_remove_data = ctx->object; 10201 idx = action_ipv6_ext_remove_data->idx; 10202 action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; 10203 action->conf = &action_ipv6_ext_remove_data->conf; 10204 return len; 10205 } 10206 10207 static int 10208 parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 10209 const char *str, unsigned int len, void *buf, 10210 unsigned int size) 10211 { 10212 struct buffer *out = buf; 10213 struct rte_flow_action *action; 10214 struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; 10215 int ret; 10216 10217 ret = parse_vc(ctx, token, str, len, buf, size); 10218 if (ret < 0) 10219 return ret; 10220 /* Nothing else to do if there is no buffer. */ 10221 if (!out) 10222 return ret; 10223 if (!out->args.vc.actions_n) 10224 return -1; 10225 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10226 /* Point to selected object. */ 10227 ctx->object = out->args.vc.data; 10228 ctx->objmask = NULL; 10229 /* Copy the headers to the buffer. */ 10230 ipv6_ext_push_data = ctx->object; 10231 ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; 10232 ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; 10233 ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; 10234 action->conf = &ipv6_ext_push_data->conf; 10235 return ret; 10236 } 10237 10238 static int 10239 parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, 10240 const char *str, unsigned int len, void *buf, 10241 unsigned int size) 10242 { 10243 struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; 10244 struct rte_flow_action *action; 10245 const struct arg *arg; 10246 struct buffer *out = buf; 10247 int ret; 10248 uint16_t idx; 10249 10250 RTE_SET_USED(token); 10251 RTE_SET_USED(buf); 10252 RTE_SET_USED(size); 10253 arg = ARGS_ENTRY_ARB_BOUNDED 10254 (offsetof(struct action_ipv6_ext_push_data, idx), 10255 sizeof(((struct action_ipv6_ext_push_data *)0)->idx), 10256 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10257 if (push_args(ctx, arg)) 10258 return -1; 10259 ret = parse_int(ctx, token, str, len, NULL, 0); 10260 if (ret < 0) { 10261 pop_args(ctx); 10262 return -1; 10263 } 10264 if (!ctx->object) 10265 return len; 10266 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10267 action_ipv6_ext_push_data = ctx->object; 10268 idx = action_ipv6_ext_push_data->idx; 10269 action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; 10270 action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; 10271 action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; 10272 action->conf = &action_ipv6_ext_push_data->conf; 10273 return len; 10274 } 10275 10276 static int 10277 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 10278 const char *str, unsigned int len, void *buf, 10279 unsigned int size) 10280 { 10281 int ret; 10282 10283 ret = parse_vc(ctx, token, str, len, buf, size); 10284 if (ret < 0) 10285 return ret; 10286 ret = rte_flow_dynf_metadata_register(); 10287 if (ret < 0) 10288 return -1; 10289 return len; 10290 } 10291 10292 static int 10293 parse_vc_action_sample(struct context *ctx, const struct token *token, 10294 const char *str, unsigned int len, void *buf, 10295 unsigned int size) 10296 { 10297 struct buffer *out = buf; 10298 struct rte_flow_action *action; 10299 struct action_sample_data *action_sample_data = NULL; 10300 static struct rte_flow_action end_action = { 10301 RTE_FLOW_ACTION_TYPE_END, 0 10302 }; 10303 int ret; 10304 10305 ret = parse_vc(ctx, token, str, len, buf, size); 10306 if (ret < 0) 10307 return ret; 10308 /* Nothing else to do if there is no buffer. */ 10309 if (!out) 10310 return ret; 10311 if (!out->args.vc.actions_n) 10312 return -1; 10313 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10314 /* Point to selected object. */ 10315 ctx->object = out->args.vc.data; 10316 ctx->objmask = NULL; 10317 /* Copy the headers to the buffer. */ 10318 action_sample_data = ctx->object; 10319 action_sample_data->conf.actions = &end_action; 10320 action->conf = &action_sample_data->conf; 10321 return ret; 10322 } 10323 10324 static int 10325 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 10326 const char *str, unsigned int len, void *buf, 10327 unsigned int size) 10328 { 10329 struct action_sample_data *action_sample_data; 10330 struct rte_flow_action *action; 10331 const struct arg *arg; 10332 struct buffer *out = buf; 10333 int ret; 10334 uint16_t idx; 10335 10336 RTE_SET_USED(token); 10337 RTE_SET_USED(buf); 10338 RTE_SET_USED(size); 10339 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 10340 return -1; 10341 arg = ARGS_ENTRY_ARB_BOUNDED 10342 (offsetof(struct action_sample_data, idx), 10343 sizeof(((struct action_sample_data *)0)->idx), 10344 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 10345 if (push_args(ctx, arg)) 10346 return -1; 10347 ret = parse_int(ctx, token, str, len, NULL, 0); 10348 if (ret < 0) { 10349 pop_args(ctx); 10350 return -1; 10351 } 10352 if (!ctx->object) 10353 return len; 10354 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10355 action_sample_data = ctx->object; 10356 idx = action_sample_data->idx; 10357 action_sample_data->conf.actions = raw_sample_confs[idx].data; 10358 action->conf = &action_sample_data->conf; 10359 return len; 10360 } 10361 10362 /** Parse operation for modify_field command. */ 10363 static int 10364 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 10365 const char *str, unsigned int len, void *buf, 10366 unsigned int size) 10367 { 10368 struct rte_flow_action_modify_field *action_modify_field; 10369 unsigned int i; 10370 10371 (void)token; 10372 (void)buf; 10373 (void)size; 10374 if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) 10375 return -1; 10376 for (i = 0; modify_field_ops[i]; ++i) 10377 if (!strcmp_partial(modify_field_ops[i], str, len)) 10378 break; 10379 if (!modify_field_ops[i]) 10380 return -1; 10381 if (!ctx->object) 10382 return len; 10383 action_modify_field = ctx->object; 10384 action_modify_field->operation = (enum rte_flow_modify_op)i; 10385 return len; 10386 } 10387 10388 /** Parse id for modify_field command. */ 10389 static int 10390 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 10391 const char *str, unsigned int len, void *buf, 10392 unsigned int size) 10393 { 10394 struct rte_flow_action_modify_field *action_modify_field; 10395 unsigned int i; 10396 10397 (void)token; 10398 (void)buf; 10399 (void)size; 10400 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 10401 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 10402 return -1; 10403 for (i = 0; flow_field_ids[i]; ++i) 10404 if (!strcmp_partial(flow_field_ids[i], str, len)) 10405 break; 10406 if (!flow_field_ids[i]) 10407 return -1; 10408 if (!ctx->object) 10409 return len; 10410 action_modify_field = ctx->object; 10411 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 10412 action_modify_field->dst.field = (enum rte_flow_field_id)i; 10413 else 10414 action_modify_field->src.field = (enum rte_flow_field_id)i; 10415 return len; 10416 } 10417 10418 /** Parse level for modify_field command. */ 10419 static int 10420 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 10421 const char *str, unsigned int len, void *buf, 10422 unsigned int size) 10423 { 10424 struct rte_flow_action_modify_field *action; 10425 struct flex_item *fp = NULL; 10426 uint32_t val; 10427 struct buffer *out = buf; 10428 char *end; 10429 10430 (void)token; 10431 (void)size; 10432 if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10433 ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) 10434 return -1; 10435 if (!ctx->object) 10436 return len; 10437 action = ctx->object; 10438 errno = 0; 10439 val = strtoumax(str, &end, 0); 10440 if (errno || (size_t)(end - str) != len) 10441 return -1; 10442 /* No need to validate action template mask value */ 10443 if (out->args.vc.masks) { 10444 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) 10445 action->dst.level = val; 10446 else 10447 action->src.level = val; 10448 return len; 10449 } 10450 if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10451 action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || 10452 (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && 10453 action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 10454 if (val >= FLEX_MAX_PARSERS_NUM) { 10455 printf("Bad flex item handle\n"); 10456 return -1; 10457 } 10458 fp = flex_items[ctx->port][val]; 10459 if (!fp) { 10460 printf("Bad flex item handle\n"); 10461 return -1; 10462 } 10463 } 10464 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { 10465 if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) 10466 action->dst.level = val; 10467 else 10468 action->dst.flex_handle = fp->flex_handle; 10469 } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { 10470 if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) 10471 action->src.level = val; 10472 else 10473 action->src.flex_handle = fp->flex_handle; 10474 } 10475 return len; 10476 } 10477 10478 /** Parse the conntrack update, not a rte_flow_action. */ 10479 static int 10480 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 10481 const char *str, unsigned int len, void *buf, 10482 unsigned int size) 10483 { 10484 struct buffer *out = buf; 10485 struct rte_flow_modify_conntrack *ct_modify = NULL; 10486 10487 (void)size; 10488 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 10489 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 10490 return -1; 10491 /* Token name must match. */ 10492 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10493 return -1; 10494 /* Nothing else to do if there is no buffer. */ 10495 if (!out) 10496 return len; 10497 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 10498 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 10499 ct_modify->new_ct.is_original_dir = 10500 conntrack_context.is_original_dir; 10501 ct_modify->direction = 1; 10502 } else { 10503 uint32_t old_dir; 10504 10505 old_dir = ct_modify->new_ct.is_original_dir; 10506 memcpy(&ct_modify->new_ct, &conntrack_context, 10507 sizeof(conntrack_context)); 10508 ct_modify->new_ct.is_original_dir = old_dir; 10509 ct_modify->state = 1; 10510 } 10511 return len; 10512 } 10513 10514 /** Parse tokens for destroy command. */ 10515 static int 10516 parse_destroy(struct context *ctx, const struct token *token, 10517 const char *str, unsigned int len, 10518 void *buf, unsigned int size) 10519 { 10520 struct buffer *out = buf; 10521 10522 /* Token name must match. */ 10523 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10524 return -1; 10525 /* Nothing else to do if there is no buffer. */ 10526 if (!out) 10527 return len; 10528 if (!out->command) { 10529 if (ctx->curr != DESTROY) 10530 return -1; 10531 if (sizeof(*out) > size) 10532 return -1; 10533 out->command = ctx->curr; 10534 ctx->objdata = 0; 10535 ctx->object = out; 10536 ctx->objmask = NULL; 10537 out->args.destroy.rule = 10538 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10539 sizeof(double)); 10540 return len; 10541 } 10542 if (ctx->curr == DESTROY_IS_USER_ID) { 10543 out->args.destroy.is_user_id = true; 10544 return len; 10545 } 10546 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 10547 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 10548 return -1; 10549 ctx->objdata = 0; 10550 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 10551 ctx->objmask = NULL; 10552 return len; 10553 } 10554 10555 /** Parse tokens for flush command. */ 10556 static int 10557 parse_flush(struct context *ctx, const struct token *token, 10558 const char *str, unsigned int len, 10559 void *buf, unsigned int size) 10560 { 10561 struct buffer *out = buf; 10562 10563 /* Token name must match. */ 10564 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10565 return -1; 10566 /* Nothing else to do if there is no buffer. */ 10567 if (!out) 10568 return len; 10569 if (!out->command) { 10570 if (ctx->curr != FLUSH) 10571 return -1; 10572 if (sizeof(*out) > size) 10573 return -1; 10574 out->command = ctx->curr; 10575 ctx->objdata = 0; 10576 ctx->object = out; 10577 ctx->objmask = NULL; 10578 } 10579 return len; 10580 } 10581 10582 /** Parse tokens for dump command. */ 10583 static int 10584 parse_dump(struct context *ctx, const struct token *token, 10585 const char *str, unsigned int len, 10586 void *buf, unsigned int size) 10587 { 10588 struct buffer *out = buf; 10589 10590 /* Token name must match. */ 10591 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10592 return -1; 10593 /* Nothing else to do if there is no buffer. */ 10594 if (!out) 10595 return len; 10596 if (!out->command) { 10597 if (ctx->curr != DUMP) 10598 return -1; 10599 if (sizeof(*out) > size) 10600 return -1; 10601 out->command = ctx->curr; 10602 ctx->objdata = 0; 10603 ctx->object = out; 10604 ctx->objmask = NULL; 10605 return len; 10606 } 10607 switch (ctx->curr) { 10608 case DUMP_ALL: 10609 case DUMP_ONE: 10610 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 10611 out->command = ctx->curr; 10612 ctx->objdata = 0; 10613 ctx->object = out; 10614 ctx->objmask = NULL; 10615 return len; 10616 case DUMP_IS_USER_ID: 10617 out->args.dump.is_user_id = true; 10618 return len; 10619 default: 10620 return -1; 10621 } 10622 } 10623 10624 /** Parse tokens for query command. */ 10625 static int 10626 parse_query(struct context *ctx, const struct token *token, 10627 const char *str, unsigned int len, 10628 void *buf, unsigned int size) 10629 { 10630 struct buffer *out = buf; 10631 10632 /* Token name must match. */ 10633 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10634 return -1; 10635 /* Nothing else to do if there is no buffer. */ 10636 if (!out) 10637 return len; 10638 if (!out->command) { 10639 if (ctx->curr != QUERY) 10640 return -1; 10641 if (sizeof(*out) > size) 10642 return -1; 10643 out->command = ctx->curr; 10644 ctx->objdata = 0; 10645 ctx->object = out; 10646 ctx->objmask = NULL; 10647 } 10648 if (ctx->curr == QUERY_IS_USER_ID) { 10649 out->args.query.is_user_id = true; 10650 return len; 10651 } 10652 return len; 10653 } 10654 10655 /** Parse action names. */ 10656 static int 10657 parse_action(struct context *ctx, const struct token *token, 10658 const char *str, unsigned int len, 10659 void *buf, unsigned int size) 10660 { 10661 struct buffer *out = buf; 10662 const struct arg *arg = pop_args(ctx); 10663 unsigned int i; 10664 10665 (void)size; 10666 /* Argument is expected. */ 10667 if (!arg) 10668 return -1; 10669 /* Parse action name. */ 10670 for (i = 0; next_action[i]; ++i) { 10671 const struct parse_action_priv *priv; 10672 10673 token = &token_list[next_action[i]]; 10674 if (strcmp_partial(token->name, str, len)) 10675 continue; 10676 priv = token->priv; 10677 if (!priv) 10678 goto error; 10679 if (out) 10680 memcpy((uint8_t *)ctx->object + arg->offset, 10681 &priv->type, 10682 arg->size); 10683 return len; 10684 } 10685 error: 10686 push_args(ctx, arg); 10687 return -1; 10688 } 10689 10690 /** Parse tokens for list command. */ 10691 static int 10692 parse_list(struct context *ctx, const struct token *token, 10693 const char *str, unsigned int len, 10694 void *buf, unsigned int size) 10695 { 10696 struct buffer *out = buf; 10697 10698 /* Token name must match. */ 10699 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10700 return -1; 10701 /* Nothing else to do if there is no buffer. */ 10702 if (!out) 10703 return len; 10704 if (!out->command) { 10705 if (ctx->curr != LIST) 10706 return -1; 10707 if (sizeof(*out) > size) 10708 return -1; 10709 out->command = ctx->curr; 10710 ctx->objdata = 0; 10711 ctx->object = out; 10712 ctx->objmask = NULL; 10713 out->args.list.group = 10714 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10715 sizeof(double)); 10716 return len; 10717 } 10718 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 10719 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 10720 return -1; 10721 ctx->objdata = 0; 10722 ctx->object = out->args.list.group + out->args.list.group_n++; 10723 ctx->objmask = NULL; 10724 return len; 10725 } 10726 10727 /** Parse tokens for list all aged flows command. */ 10728 static int 10729 parse_aged(struct context *ctx, const struct token *token, 10730 const char *str, unsigned int len, 10731 void *buf, unsigned int size) 10732 { 10733 struct buffer *out = buf; 10734 10735 /* Token name must match. */ 10736 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10737 return -1; 10738 /* Nothing else to do if there is no buffer. */ 10739 if (!out) 10740 return len; 10741 if (!out->command || out->command == QUEUE) { 10742 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 10743 return -1; 10744 if (sizeof(*out) > size) 10745 return -1; 10746 out->command = ctx->curr; 10747 ctx->objdata = 0; 10748 ctx->object = out; 10749 ctx->objmask = NULL; 10750 } 10751 if (ctx->curr == AGED_DESTROY) 10752 out->args.aged.destroy = 1; 10753 return len; 10754 } 10755 10756 /** Parse tokens for isolate command. */ 10757 static int 10758 parse_isolate(struct context *ctx, const struct token *token, 10759 const char *str, unsigned int len, 10760 void *buf, unsigned int size) 10761 { 10762 struct buffer *out = buf; 10763 10764 /* Token name must match. */ 10765 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10766 return -1; 10767 /* Nothing else to do if there is no buffer. */ 10768 if (!out) 10769 return len; 10770 if (!out->command) { 10771 if (ctx->curr != ISOLATE) 10772 return -1; 10773 if (sizeof(*out) > size) 10774 return -1; 10775 out->command = ctx->curr; 10776 ctx->objdata = 0; 10777 ctx->object = out; 10778 ctx->objmask = NULL; 10779 } 10780 return len; 10781 } 10782 10783 /** Parse tokens for info/configure command. */ 10784 static int 10785 parse_configure(struct context *ctx, const struct token *token, 10786 const char *str, unsigned int len, 10787 void *buf, unsigned int size) 10788 { 10789 struct buffer *out = buf; 10790 10791 /* Token name must match. */ 10792 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10793 return -1; 10794 /* Nothing else to do if there is no buffer. */ 10795 if (!out) 10796 return len; 10797 if (!out->command) { 10798 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 10799 return -1; 10800 if (sizeof(*out) > size) 10801 return -1; 10802 out->command = ctx->curr; 10803 ctx->objdata = 0; 10804 ctx->object = out; 10805 ctx->objmask = NULL; 10806 } 10807 return len; 10808 } 10809 10810 /** Parse tokens for template create command. */ 10811 static int 10812 parse_template(struct context *ctx, const struct token *token, 10813 const char *str, unsigned int len, 10814 void *buf, unsigned int size) 10815 { 10816 struct buffer *out = buf; 10817 10818 /* Token name must match. */ 10819 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10820 return -1; 10821 /* Nothing else to do if there is no buffer. */ 10822 if (!out) 10823 return len; 10824 if (!out->command) { 10825 if (ctx->curr != PATTERN_TEMPLATE && 10826 ctx->curr != ACTIONS_TEMPLATE) 10827 return -1; 10828 if (sizeof(*out) > size) 10829 return -1; 10830 out->command = ctx->curr; 10831 ctx->objdata = 0; 10832 ctx->object = out; 10833 ctx->objmask = NULL; 10834 out->args.vc.data = (uint8_t *)out + size; 10835 return len; 10836 } 10837 switch (ctx->curr) { 10838 case PATTERN_TEMPLATE_CREATE: 10839 out->args.vc.pattern = 10840 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10841 sizeof(double)); 10842 out->args.vc.pat_templ_id = UINT32_MAX; 10843 out->command = ctx->curr; 10844 ctx->objdata = 0; 10845 ctx->object = out; 10846 ctx->objmask = NULL; 10847 return len; 10848 case PATTERN_TEMPLATE_EGRESS: 10849 out->args.vc.attr.egress = 1; 10850 return len; 10851 case PATTERN_TEMPLATE_INGRESS: 10852 out->args.vc.attr.ingress = 1; 10853 return len; 10854 case PATTERN_TEMPLATE_TRANSFER: 10855 out->args.vc.attr.transfer = 1; 10856 return len; 10857 case ACTIONS_TEMPLATE_CREATE: 10858 out->args.vc.act_templ_id = UINT32_MAX; 10859 out->command = ctx->curr; 10860 ctx->objdata = 0; 10861 ctx->object = out; 10862 ctx->objmask = NULL; 10863 return len; 10864 case ACTIONS_TEMPLATE_SPEC: 10865 out->args.vc.actions = 10866 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10867 sizeof(double)); 10868 ctx->object = out->args.vc.actions; 10869 ctx->objmask = NULL; 10870 return len; 10871 case ACTIONS_TEMPLATE_MASK: 10872 out->args.vc.masks = 10873 (void *)RTE_ALIGN_CEIL((uintptr_t) 10874 (out->args.vc.actions + 10875 out->args.vc.actions_n), 10876 sizeof(double)); 10877 ctx->object = out->args.vc.masks; 10878 ctx->objmask = NULL; 10879 return len; 10880 case ACTIONS_TEMPLATE_EGRESS: 10881 out->args.vc.attr.egress = 1; 10882 return len; 10883 case ACTIONS_TEMPLATE_INGRESS: 10884 out->args.vc.attr.ingress = 1; 10885 return len; 10886 case ACTIONS_TEMPLATE_TRANSFER: 10887 out->args.vc.attr.transfer = 1; 10888 return len; 10889 default: 10890 return -1; 10891 } 10892 } 10893 10894 /** Parse tokens for template destroy command. */ 10895 static int 10896 parse_template_destroy(struct context *ctx, const struct token *token, 10897 const char *str, unsigned int len, 10898 void *buf, unsigned int size) 10899 { 10900 struct buffer *out = buf; 10901 uint32_t *template_id; 10902 10903 /* Token name must match. */ 10904 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10905 return -1; 10906 /* Nothing else to do if there is no buffer. */ 10907 if (!out) 10908 return len; 10909 if (!out->command || 10910 out->command == PATTERN_TEMPLATE || 10911 out->command == ACTIONS_TEMPLATE) { 10912 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 10913 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 10914 return -1; 10915 if (sizeof(*out) > size) 10916 return -1; 10917 out->command = ctx->curr; 10918 ctx->objdata = 0; 10919 ctx->object = out; 10920 ctx->objmask = NULL; 10921 out->args.templ_destroy.template_id = 10922 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10923 sizeof(double)); 10924 return len; 10925 } 10926 template_id = out->args.templ_destroy.template_id 10927 + out->args.templ_destroy.template_id_n++; 10928 if ((uint8_t *)template_id > (uint8_t *)out + size) 10929 return -1; 10930 ctx->objdata = 0; 10931 ctx->object = template_id; 10932 ctx->objmask = NULL; 10933 return len; 10934 } 10935 10936 /** Parse tokens for table create command. */ 10937 static int 10938 parse_table(struct context *ctx, const struct token *token, 10939 const char *str, unsigned int len, 10940 void *buf, unsigned int size) 10941 { 10942 struct buffer *out = buf; 10943 uint32_t *template_id; 10944 10945 /* Token name must match. */ 10946 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10947 return -1; 10948 /* Nothing else to do if there is no buffer. */ 10949 if (!out) 10950 return len; 10951 if (!out->command) { 10952 if (ctx->curr != TABLE) 10953 return -1; 10954 if (sizeof(*out) > size) 10955 return -1; 10956 out->command = ctx->curr; 10957 ctx->objdata = 0; 10958 ctx->object = out; 10959 ctx->objmask = NULL; 10960 return len; 10961 } 10962 switch (ctx->curr) { 10963 case TABLE_CREATE: 10964 case TABLE_RESIZE: 10965 out->command = ctx->curr; 10966 ctx->objdata = 0; 10967 ctx->object = out; 10968 ctx->objmask = NULL; 10969 out->args.table.id = UINT32_MAX; 10970 return len; 10971 case TABLE_PATTERN_TEMPLATE: 10972 out->args.table.pat_templ_id = 10973 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10974 sizeof(double)); 10975 template_id = out->args.table.pat_templ_id 10976 + out->args.table.pat_templ_id_n++; 10977 if ((uint8_t *)template_id > (uint8_t *)out + size) 10978 return -1; 10979 ctx->objdata = 0; 10980 ctx->object = template_id; 10981 ctx->objmask = NULL; 10982 return len; 10983 case TABLE_ACTIONS_TEMPLATE: 10984 out->args.table.act_templ_id = 10985 (void *)RTE_ALIGN_CEIL((uintptr_t) 10986 (out->args.table.pat_templ_id + 10987 out->args.table.pat_templ_id_n), 10988 sizeof(double)); 10989 template_id = out->args.table.act_templ_id 10990 + out->args.table.act_templ_id_n++; 10991 if ((uint8_t *)template_id > (uint8_t *)out + size) 10992 return -1; 10993 ctx->objdata = 0; 10994 ctx->object = template_id; 10995 ctx->objmask = NULL; 10996 return len; 10997 case TABLE_INGRESS: 10998 out->args.table.attr.flow_attr.ingress = 1; 10999 return len; 11000 case TABLE_EGRESS: 11001 out->args.table.attr.flow_attr.egress = 1; 11002 return len; 11003 case TABLE_TRANSFER: 11004 out->args.table.attr.flow_attr.transfer = 1; 11005 return len; 11006 case TABLE_TRANSFER_WIRE_ORIG: 11007 if (!out->args.table.attr.flow_attr.transfer) 11008 return -1; 11009 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; 11010 return len; 11011 case TABLE_TRANSFER_VPORT_ORIG: 11012 if (!out->args.table.attr.flow_attr.transfer) 11013 return -1; 11014 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; 11015 return len; 11016 case TABLE_RESIZABLE: 11017 out->args.table.attr.specialize |= 11018 RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE; 11019 return len; 11020 case TABLE_RULES_NUMBER: 11021 ctx->objdata = 0; 11022 ctx->object = out; 11023 ctx->objmask = NULL; 11024 return len; 11025 case TABLE_RESIZE_ID: 11026 case TABLE_RESIZE_RULES_NUMBER: 11027 return len; 11028 default: 11029 return -1; 11030 } 11031 } 11032 11033 /** Parse tokens for table destroy command. */ 11034 static int 11035 parse_table_destroy(struct context *ctx, const struct token *token, 11036 const char *str, unsigned int len, 11037 void *buf, unsigned int size) 11038 { 11039 struct buffer *out = buf; 11040 uint32_t *table_id; 11041 11042 /* Token name must match. */ 11043 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11044 return -1; 11045 /* Nothing else to do if there is no buffer. */ 11046 if (!out) 11047 return len; 11048 if (!out->command || out->command == TABLE) { 11049 if (ctx->curr != TABLE_DESTROY && 11050 ctx->curr != TABLE_RESIZE_COMPLETE) 11051 return -1; 11052 if (sizeof(*out) > size) 11053 return -1; 11054 out->command = ctx->curr; 11055 ctx->objdata = 0; 11056 ctx->object = out; 11057 ctx->objmask = NULL; 11058 out->args.table_destroy.table_id = 11059 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11060 sizeof(double)); 11061 return len; 11062 } 11063 table_id = out->args.table_destroy.table_id 11064 + out->args.table_destroy.table_id_n++; 11065 if ((uint8_t *)table_id > (uint8_t *)out + size) 11066 return -1; 11067 ctx->objdata = 0; 11068 ctx->object = table_id; 11069 ctx->objmask = NULL; 11070 return len; 11071 } 11072 11073 /** Parse tokens for queue create commands. */ 11074 static int 11075 parse_qo(struct context *ctx, const struct token *token, 11076 const char *str, unsigned int len, 11077 void *buf, unsigned int size) 11078 { 11079 struct buffer *out = buf; 11080 11081 /* Token name must match. */ 11082 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11083 return -1; 11084 /* Nothing else to do if there is no buffer. */ 11085 if (!out) 11086 return len; 11087 if (!out->command) { 11088 if (ctx->curr != QUEUE) 11089 return -1; 11090 if (sizeof(*out) > size) 11091 return -1; 11092 out->command = ctx->curr; 11093 ctx->objdata = 0; 11094 ctx->object = out; 11095 ctx->objmask = NULL; 11096 out->args.vc.data = (uint8_t *)out + size; 11097 return len; 11098 } 11099 switch (ctx->curr) { 11100 case QUEUE_CREATE: 11101 case QUEUE_UPDATE: 11102 out->command = ctx->curr; 11103 ctx->objdata = 0; 11104 ctx->object = out; 11105 ctx->objmask = NULL; 11106 out->args.vc.rule_id = UINT32_MAX; 11107 return len; 11108 case QUEUE_TEMPLATE_TABLE: 11109 case QUEUE_PATTERN_TEMPLATE: 11110 case QUEUE_ACTIONS_TEMPLATE: 11111 case QUEUE_CREATE_POSTPONE: 11112 case QUEUE_RULE_ID: 11113 case QUEUE_UPDATE_ID: 11114 return len; 11115 case ITEM_PATTERN: 11116 out->args.vc.pattern = 11117 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11118 sizeof(double)); 11119 ctx->object = out->args.vc.pattern; 11120 ctx->objmask = NULL; 11121 return len; 11122 case ACTIONS: 11123 out->args.vc.actions = 11124 (void *)RTE_ALIGN_CEIL((uintptr_t) 11125 (out->args.vc.pattern + 11126 out->args.vc.pattern_n), 11127 sizeof(double)); 11128 ctx->object = out->args.vc.actions; 11129 ctx->objmask = NULL; 11130 return len; 11131 default: 11132 return -1; 11133 } 11134 } 11135 11136 /** Parse tokens for queue destroy command. */ 11137 static int 11138 parse_qo_destroy(struct context *ctx, const struct token *token, 11139 const char *str, unsigned int len, 11140 void *buf, unsigned int size) 11141 { 11142 struct buffer *out = buf; 11143 uint64_t *flow_id; 11144 11145 /* Token name must match. */ 11146 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11147 return -1; 11148 /* Nothing else to do if there is no buffer. */ 11149 if (!out) 11150 return len; 11151 if (!out->command || out->command == QUEUE) { 11152 if (ctx->curr != QUEUE_DESTROY && 11153 ctx->curr != QUEUE_FLOW_UPDATE_RESIZED) 11154 return -1; 11155 if (sizeof(*out) > size) 11156 return -1; 11157 out->command = ctx->curr; 11158 ctx->objdata = 0; 11159 ctx->object = out; 11160 ctx->objmask = NULL; 11161 out->args.destroy.rule = 11162 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11163 sizeof(double)); 11164 return len; 11165 } 11166 switch (ctx->curr) { 11167 case QUEUE_DESTROY_ID: 11168 flow_id = out->args.destroy.rule 11169 + out->args.destroy.rule_n++; 11170 if ((uint8_t *)flow_id > (uint8_t *)out + size) 11171 return -1; 11172 ctx->objdata = 0; 11173 ctx->object = flow_id; 11174 ctx->objmask = NULL; 11175 return len; 11176 case QUEUE_DESTROY_POSTPONE: 11177 return len; 11178 default: 11179 return -1; 11180 } 11181 } 11182 11183 /** Parse tokens for push queue command. */ 11184 static int 11185 parse_push(struct context *ctx, const struct token *token, 11186 const char *str, unsigned int len, 11187 void *buf, unsigned int size) 11188 { 11189 struct buffer *out = buf; 11190 11191 /* Token name must match. */ 11192 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11193 return -1; 11194 /* Nothing else to do if there is no buffer. */ 11195 if (!out) 11196 return len; 11197 if (!out->command) { 11198 if (ctx->curr != PUSH) 11199 return -1; 11200 if (sizeof(*out) > size) 11201 return -1; 11202 out->command = ctx->curr; 11203 ctx->objdata = 0; 11204 ctx->object = out; 11205 ctx->objmask = NULL; 11206 out->args.vc.data = (uint8_t *)out + size; 11207 } 11208 return len; 11209 } 11210 11211 /** Parse tokens for pull command. */ 11212 static int 11213 parse_pull(struct context *ctx, const struct token *token, 11214 const char *str, unsigned int len, 11215 void *buf, unsigned int size) 11216 { 11217 struct buffer *out = buf; 11218 11219 /* Token name must match. */ 11220 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11221 return -1; 11222 /* Nothing else to do if there is no buffer. */ 11223 if (!out) 11224 return len; 11225 if (!out->command) { 11226 if (ctx->curr != PULL) 11227 return -1; 11228 if (sizeof(*out) > size) 11229 return -1; 11230 out->command = ctx->curr; 11231 ctx->objdata = 0; 11232 ctx->object = out; 11233 ctx->objmask = NULL; 11234 out->args.vc.data = (uint8_t *)out + size; 11235 } 11236 return len; 11237 } 11238 11239 /** Parse tokens for hash calculation commands. */ 11240 static int 11241 parse_hash(struct context *ctx, const struct token *token, 11242 const char *str, unsigned int len, 11243 void *buf, unsigned int size) 11244 { 11245 struct buffer *out = buf; 11246 11247 /* Token name must match. */ 11248 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11249 return -1; 11250 /* Nothing else to do if there is no buffer. */ 11251 if (!out) 11252 return len; 11253 if (!out->command) { 11254 if (ctx->curr != HASH) 11255 return -1; 11256 if (sizeof(*out) > size) 11257 return -1; 11258 out->command = ctx->curr; 11259 ctx->objdata = 0; 11260 ctx->object = out; 11261 ctx->objmask = NULL; 11262 out->args.vc.data = (uint8_t *)out + size; 11263 return len; 11264 } 11265 switch (ctx->curr) { 11266 case HASH_CALC_TABLE: 11267 case HASH_CALC_PATTERN_INDEX: 11268 return len; 11269 case ITEM_PATTERN: 11270 out->args.vc.pattern = 11271 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11272 sizeof(double)); 11273 ctx->object = out->args.vc.pattern; 11274 ctx->objmask = NULL; 11275 return len; 11276 case HASH_CALC_ENCAP: 11277 out->args.vc.encap_hash = 1; 11278 return len; 11279 case ENCAP_HASH_FIELD_SRC_PORT: 11280 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT; 11281 return len; 11282 case ENCAP_HASH_FIELD_GRE_FLOW_ID: 11283 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID; 11284 return len; 11285 default: 11286 return -1; 11287 } 11288 } 11289 11290 static int 11291 parse_group(struct context *ctx, const struct token *token, 11292 const char *str, unsigned int len, 11293 void *buf, unsigned int size) 11294 { 11295 struct buffer *out = buf; 11296 11297 /* Token name must match. */ 11298 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11299 return -1; 11300 /* Nothing else to do if there is no buffer. */ 11301 if (!out) 11302 return len; 11303 if (!out->command) { 11304 if (ctx->curr != FLOW_GROUP) 11305 return -1; 11306 if (sizeof(*out) > size) 11307 return -1; 11308 out->command = ctx->curr; 11309 ctx->objdata = 0; 11310 ctx->object = out; 11311 ctx->objmask = NULL; 11312 out->args.vc.data = (uint8_t *)out + size; 11313 return len; 11314 } 11315 switch (ctx->curr) { 11316 case GROUP_INGRESS: 11317 out->args.vc.attr.ingress = 1; 11318 return len; 11319 case GROUP_EGRESS: 11320 out->args.vc.attr.egress = 1; 11321 return len; 11322 case GROUP_TRANSFER: 11323 out->args.vc.attr.transfer = 1; 11324 return len; 11325 case GROUP_SET_MISS_ACTIONS: 11326 out->command = ctx->curr; 11327 ctx->objdata = 0; 11328 ctx->object = out; 11329 ctx->objmask = NULL; 11330 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11331 sizeof(double)); 11332 return len; 11333 default: 11334 return -1; 11335 } 11336 } 11337 11338 static int 11339 parse_flex(struct context *ctx, const struct token *token, 11340 const char *str, unsigned int len, 11341 void *buf, unsigned int size) 11342 { 11343 struct buffer *out = buf; 11344 11345 /* Token name must match. */ 11346 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11347 return -1; 11348 /* Nothing else to do if there is no buffer. */ 11349 if (!out) 11350 return len; 11351 if (out->command == ZERO) { 11352 if (ctx->curr != FLEX) 11353 return -1; 11354 if (sizeof(*out) > size) 11355 return -1; 11356 out->command = ctx->curr; 11357 ctx->objdata = 0; 11358 ctx->object = out; 11359 ctx->objmask = NULL; 11360 } else { 11361 switch (ctx->curr) { 11362 default: 11363 break; 11364 case FLEX_ITEM_INIT: 11365 case FLEX_ITEM_CREATE: 11366 case FLEX_ITEM_DESTROY: 11367 out->command = ctx->curr; 11368 break; 11369 } 11370 } 11371 11372 return len; 11373 } 11374 11375 static int 11376 parse_tunnel(struct context *ctx, const struct token *token, 11377 const char *str, unsigned int len, 11378 void *buf, unsigned int size) 11379 { 11380 struct buffer *out = buf; 11381 11382 /* Token name must match. */ 11383 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11384 return -1; 11385 /* Nothing else to do if there is no buffer. */ 11386 if (!out) 11387 return len; 11388 if (!out->command) { 11389 if (ctx->curr != TUNNEL) 11390 return -1; 11391 if (sizeof(*out) > size) 11392 return -1; 11393 out->command = ctx->curr; 11394 ctx->objdata = 0; 11395 ctx->object = out; 11396 ctx->objmask = NULL; 11397 } else { 11398 switch (ctx->curr) { 11399 default: 11400 break; 11401 case TUNNEL_CREATE: 11402 case TUNNEL_DESTROY: 11403 case TUNNEL_LIST: 11404 out->command = ctx->curr; 11405 break; 11406 case TUNNEL_CREATE_TYPE: 11407 case TUNNEL_DESTROY_ID: 11408 ctx->object = &out->args.vc.tunnel_ops; 11409 break; 11410 } 11411 } 11412 11413 return len; 11414 } 11415 11416 /** 11417 * Parse signed/unsigned integers 8 to 64-bit long. 11418 * 11419 * Last argument (ctx->args) is retrieved to determine integer type and 11420 * storage location. 11421 */ 11422 static int 11423 parse_int(struct context *ctx, const struct token *token, 11424 const char *str, unsigned int len, 11425 void *buf, unsigned int size) 11426 { 11427 const struct arg *arg = pop_args(ctx); 11428 uintmax_t u; 11429 char *end; 11430 11431 (void)token; 11432 /* Argument is expected. */ 11433 if (!arg) 11434 return -1; 11435 errno = 0; 11436 u = arg->sign ? 11437 (uintmax_t)strtoimax(str, &end, 0) : 11438 strtoumax(str, &end, 0); 11439 if (errno || (size_t)(end - str) != len) 11440 goto error; 11441 if (arg->bounded && 11442 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 11443 (intmax_t)u > (intmax_t)arg->max)) || 11444 (!arg->sign && (u < arg->min || u > arg->max)))) 11445 goto error; 11446 if (!ctx->object) 11447 return len; 11448 if (arg->mask) { 11449 if (!arg_entry_bf_fill(ctx->object, u, arg) || 11450 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 11451 goto error; 11452 return len; 11453 } 11454 buf = (uint8_t *)ctx->object + arg->offset; 11455 size = arg->size; 11456 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 11457 return -1; 11458 objmask: 11459 switch (size) { 11460 case sizeof(uint8_t): 11461 *(uint8_t *)buf = u; 11462 break; 11463 case sizeof(uint16_t): 11464 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 11465 break; 11466 case sizeof(uint8_t [3]): 11467 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 11468 if (!arg->hton) { 11469 ((uint8_t *)buf)[0] = u; 11470 ((uint8_t *)buf)[1] = u >> 8; 11471 ((uint8_t *)buf)[2] = u >> 16; 11472 break; 11473 } 11474 #endif 11475 ((uint8_t *)buf)[0] = u >> 16; 11476 ((uint8_t *)buf)[1] = u >> 8; 11477 ((uint8_t *)buf)[2] = u; 11478 break; 11479 case sizeof(uint32_t): 11480 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 11481 break; 11482 case sizeof(uint64_t): 11483 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 11484 break; 11485 default: 11486 goto error; 11487 } 11488 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 11489 u = -1; 11490 buf = (uint8_t *)ctx->objmask + arg->offset; 11491 goto objmask; 11492 } 11493 return len; 11494 error: 11495 push_args(ctx, arg); 11496 return -1; 11497 } 11498 11499 /** 11500 * Parse a string. 11501 * 11502 * Three arguments (ctx->args) are retrieved from the stack to store data, 11503 * its actual length and address (in that order). 11504 */ 11505 static int 11506 parse_string(struct context *ctx, const struct token *token, 11507 const char *str, unsigned int len, 11508 void *buf, unsigned int size) 11509 { 11510 const struct arg *arg_data = pop_args(ctx); 11511 const struct arg *arg_len = pop_args(ctx); 11512 const struct arg *arg_addr = pop_args(ctx); 11513 char tmp[16]; /* Ought to be enough. */ 11514 int ret; 11515 11516 /* Arguments are expected. */ 11517 if (!arg_data) 11518 return -1; 11519 if (!arg_len) { 11520 push_args(ctx, arg_data); 11521 return -1; 11522 } 11523 if (!arg_addr) { 11524 push_args(ctx, arg_len); 11525 push_args(ctx, arg_data); 11526 return -1; 11527 } 11528 size = arg_data->size; 11529 /* Bit-mask fill is not supported. */ 11530 if (arg_data->mask || size < len) 11531 goto error; 11532 if (!ctx->object) 11533 return len; 11534 /* Let parse_int() fill length information first. */ 11535 ret = snprintf(tmp, sizeof(tmp), "%u", len); 11536 if (ret < 0) 11537 goto error; 11538 push_args(ctx, arg_len); 11539 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11540 if (ret < 0) { 11541 pop_args(ctx); 11542 goto error; 11543 } 11544 buf = (uint8_t *)ctx->object + arg_data->offset; 11545 /* Output buffer is not necessarily NUL-terminated. */ 11546 memcpy(buf, str, len); 11547 memset((uint8_t *)buf + len, 0x00, size - len); 11548 if (ctx->objmask) 11549 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11550 /* Save address if requested. */ 11551 if (arg_addr->size) { 11552 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11553 (void *[]){ 11554 (uint8_t *)ctx->object + arg_data->offset 11555 }, 11556 arg_addr->size); 11557 if (ctx->objmask) 11558 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11559 (void *[]){ 11560 (uint8_t *)ctx->objmask + arg_data->offset 11561 }, 11562 arg_addr->size); 11563 } 11564 return len; 11565 error: 11566 push_args(ctx, arg_addr); 11567 push_args(ctx, arg_len); 11568 push_args(ctx, arg_data); 11569 return -1; 11570 } 11571 11572 static int 11573 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 11574 { 11575 const uint8_t *head = dst; 11576 uint32_t left; 11577 11578 if (*size == 0) 11579 return -1; 11580 11581 left = *size; 11582 11583 /* Convert chars to bytes */ 11584 while (left) { 11585 char tmp[3], *end = tmp; 11586 uint32_t read_lim = left & 1 ? 1 : 2; 11587 11588 snprintf(tmp, read_lim + 1, "%s", src); 11589 *dst = strtoul(tmp, &end, 16); 11590 if (*end) { 11591 *dst = 0; 11592 *size = (uint32_t)(dst - head); 11593 return -1; 11594 } 11595 left -= read_lim; 11596 src += read_lim; 11597 dst++; 11598 } 11599 *dst = 0; 11600 *size = (uint32_t)(dst - head); 11601 return 0; 11602 } 11603 11604 static int 11605 parse_hex(struct context *ctx, const struct token *token, 11606 const char *str, unsigned int len, 11607 void *buf, unsigned int size) 11608 { 11609 const struct arg *arg_data = pop_args(ctx); 11610 const struct arg *arg_len = pop_args(ctx); 11611 const struct arg *arg_addr = pop_args(ctx); 11612 char tmp[16]; /* Ought to be enough. */ 11613 int ret; 11614 unsigned int hexlen = len; 11615 unsigned int length = 256; 11616 uint8_t hex_tmp[length]; 11617 11618 /* Arguments are expected. */ 11619 if (!arg_data) 11620 return -1; 11621 if (!arg_len) { 11622 push_args(ctx, arg_data); 11623 return -1; 11624 } 11625 if (!arg_addr) { 11626 push_args(ctx, arg_len); 11627 push_args(ctx, arg_data); 11628 return -1; 11629 } 11630 size = arg_data->size; 11631 /* Bit-mask fill is not supported. */ 11632 if (arg_data->mask) 11633 goto error; 11634 if (!ctx->object) 11635 return len; 11636 11637 /* translate bytes string to array. */ 11638 if (str[0] == '0' && ((str[1] == 'x') || 11639 (str[1] == 'X'))) { 11640 str += 2; 11641 hexlen -= 2; 11642 } 11643 if (hexlen > length) 11644 goto error; 11645 ret = parse_hex_string(str, hex_tmp, &hexlen); 11646 if (ret < 0) 11647 goto error; 11648 /* Check the converted binary fits into data buffer. */ 11649 if (hexlen > size) 11650 goto error; 11651 /* Let parse_int() fill length information first. */ 11652 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 11653 if (ret < 0) 11654 goto error; 11655 /* Save length if requested. */ 11656 if (arg_len->size) { 11657 push_args(ctx, arg_len); 11658 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11659 if (ret < 0) { 11660 pop_args(ctx); 11661 goto error; 11662 } 11663 } 11664 buf = (uint8_t *)ctx->object + arg_data->offset; 11665 /* Output buffer is not necessarily NUL-terminated. */ 11666 memcpy(buf, hex_tmp, hexlen); 11667 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 11668 if (ctx->objmask) 11669 memset((uint8_t *)ctx->objmask + arg_data->offset, 11670 0xff, hexlen); 11671 /* Save address if requested. */ 11672 if (arg_addr->size) { 11673 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11674 (void *[]){ 11675 (uint8_t *)ctx->object + arg_data->offset 11676 }, 11677 arg_addr->size); 11678 if (ctx->objmask) 11679 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11680 (void *[]){ 11681 (uint8_t *)ctx->objmask + arg_data->offset 11682 }, 11683 arg_addr->size); 11684 } 11685 return len; 11686 error: 11687 push_args(ctx, arg_addr); 11688 push_args(ctx, arg_len); 11689 push_args(ctx, arg_data); 11690 return -1; 11691 11692 } 11693 11694 /** 11695 * Parse a zero-ended string. 11696 */ 11697 static int 11698 parse_string0(struct context *ctx, const struct token *token __rte_unused, 11699 const char *str, unsigned int len, 11700 void *buf, unsigned int size) 11701 { 11702 const struct arg *arg_data = pop_args(ctx); 11703 11704 /* Arguments are expected. */ 11705 if (!arg_data) 11706 return -1; 11707 size = arg_data->size; 11708 /* Bit-mask fill is not supported. */ 11709 if (arg_data->mask || size < len + 1) 11710 goto error; 11711 if (!ctx->object) 11712 return len; 11713 buf = (uint8_t *)ctx->object + arg_data->offset; 11714 strncpy(buf, str, len); 11715 if (ctx->objmask) 11716 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11717 return len; 11718 error: 11719 push_args(ctx, arg_data); 11720 return -1; 11721 } 11722 11723 /** 11724 * Parse a MAC address. 11725 * 11726 * Last argument (ctx->args) is retrieved to determine storage size and 11727 * location. 11728 */ 11729 static int 11730 parse_mac_addr(struct context *ctx, const struct token *token, 11731 const char *str, unsigned int len, 11732 void *buf, unsigned int size) 11733 { 11734 const struct arg *arg = pop_args(ctx); 11735 struct rte_ether_addr tmp; 11736 int ret; 11737 11738 (void)token; 11739 /* Argument is expected. */ 11740 if (!arg) 11741 return -1; 11742 size = arg->size; 11743 /* Bit-mask fill is not supported. */ 11744 if (arg->mask || size != sizeof(tmp)) 11745 goto error; 11746 /* Only network endian is supported. */ 11747 if (!arg->hton) 11748 goto error; 11749 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 11750 if (ret < 0 || (unsigned int)ret != len) 11751 goto error; 11752 if (!ctx->object) 11753 return len; 11754 buf = (uint8_t *)ctx->object + arg->offset; 11755 memcpy(buf, &tmp, size); 11756 if (ctx->objmask) 11757 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11758 return len; 11759 error: 11760 push_args(ctx, arg); 11761 return -1; 11762 } 11763 11764 /** 11765 * Parse an IPv4 address. 11766 * 11767 * Last argument (ctx->args) is retrieved to determine storage size and 11768 * location. 11769 */ 11770 static int 11771 parse_ipv4_addr(struct context *ctx, const struct token *token, 11772 const char *str, unsigned int len, 11773 void *buf, unsigned int size) 11774 { 11775 const struct arg *arg = pop_args(ctx); 11776 char str2[len + 1]; 11777 struct in_addr tmp; 11778 int ret; 11779 11780 /* Argument is expected. */ 11781 if (!arg) 11782 return -1; 11783 size = arg->size; 11784 /* Bit-mask fill is not supported. */ 11785 if (arg->mask || size != sizeof(tmp)) 11786 goto error; 11787 /* Only network endian is supported. */ 11788 if (!arg->hton) 11789 goto error; 11790 memcpy(str2, str, len); 11791 str2[len] = '\0'; 11792 ret = inet_pton(AF_INET, str2, &tmp); 11793 if (ret != 1) { 11794 /* Attempt integer parsing. */ 11795 push_args(ctx, arg); 11796 return parse_int(ctx, token, str, len, buf, size); 11797 } 11798 if (!ctx->object) 11799 return len; 11800 buf = (uint8_t *)ctx->object + arg->offset; 11801 memcpy(buf, &tmp, size); 11802 if (ctx->objmask) 11803 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11804 return len; 11805 error: 11806 push_args(ctx, arg); 11807 return -1; 11808 } 11809 11810 /** 11811 * Parse an IPv6 address. 11812 * 11813 * Last argument (ctx->args) is retrieved to determine storage size and 11814 * location. 11815 */ 11816 static int 11817 parse_ipv6_addr(struct context *ctx, const struct token *token, 11818 const char *str, unsigned int len, 11819 void *buf, unsigned int size) 11820 { 11821 const struct arg *arg = pop_args(ctx); 11822 char str2[len + 1]; 11823 struct in6_addr tmp; 11824 int ret; 11825 11826 (void)token; 11827 /* Argument is expected. */ 11828 if (!arg) 11829 return -1; 11830 size = arg->size; 11831 /* Bit-mask fill is not supported. */ 11832 if (arg->mask || size != sizeof(tmp)) 11833 goto error; 11834 /* Only network endian is supported. */ 11835 if (!arg->hton) 11836 goto error; 11837 memcpy(str2, str, len); 11838 str2[len] = '\0'; 11839 ret = inet_pton(AF_INET6, str2, &tmp); 11840 if (ret != 1) 11841 goto error; 11842 if (!ctx->object) 11843 return len; 11844 buf = (uint8_t *)ctx->object + arg->offset; 11845 memcpy(buf, &tmp, size); 11846 if (ctx->objmask) 11847 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11848 return len; 11849 error: 11850 push_args(ctx, arg); 11851 return -1; 11852 } 11853 11854 /** Boolean values (even indices stand for false). */ 11855 static const char *const boolean_name[] = { 11856 "0", "1", 11857 "false", "true", 11858 "no", "yes", 11859 "N", "Y", 11860 "off", "on", 11861 NULL, 11862 }; 11863 11864 /** 11865 * Parse a boolean value. 11866 * 11867 * Last argument (ctx->args) is retrieved to determine storage size and 11868 * location. 11869 */ 11870 static int 11871 parse_boolean(struct context *ctx, const struct token *token, 11872 const char *str, unsigned int len, 11873 void *buf, unsigned int size) 11874 { 11875 const struct arg *arg = pop_args(ctx); 11876 unsigned int i; 11877 int ret; 11878 11879 /* Argument is expected. */ 11880 if (!arg) 11881 return -1; 11882 for (i = 0; boolean_name[i]; ++i) 11883 if (!strcmp_partial(boolean_name[i], str, len)) 11884 break; 11885 /* Process token as integer. */ 11886 if (boolean_name[i]) 11887 str = i & 1 ? "1" : "0"; 11888 push_args(ctx, arg); 11889 ret = parse_int(ctx, token, str, strlen(str), buf, size); 11890 return ret > 0 ? (int)len : ret; 11891 } 11892 11893 /** Parse port and update context. */ 11894 static int 11895 parse_port(struct context *ctx, const struct token *token, 11896 const char *str, unsigned int len, 11897 void *buf, unsigned int size) 11898 { 11899 struct buffer *out = &(struct buffer){ .port = 0 }; 11900 int ret; 11901 11902 if (buf) 11903 out = buf; 11904 else { 11905 ctx->objdata = 0; 11906 ctx->object = out; 11907 ctx->objmask = NULL; 11908 size = sizeof(*out); 11909 } 11910 ret = parse_int(ctx, token, str, len, out, size); 11911 if (ret >= 0) 11912 ctx->port = out->port; 11913 if (!buf) 11914 ctx->object = NULL; 11915 return ret; 11916 } 11917 11918 /** Parse tokens for shared indirect actions. */ 11919 static int 11920 parse_ia_port(struct context *ctx, const struct token *token, 11921 const char *str, unsigned int len, 11922 void *buf, unsigned int size) 11923 { 11924 struct rte_flow_action *action = ctx->object; 11925 uint32_t id; 11926 int ret; 11927 11928 (void)buf; 11929 (void)size; 11930 ctx->objdata = 0; 11931 ctx->object = &id; 11932 ctx->objmask = NULL; 11933 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11934 ctx->object = action; 11935 if (ret != (int)len) 11936 return ret; 11937 /* set indirect action */ 11938 if (action) 11939 action->conf = (void *)(uintptr_t)id; 11940 return ret; 11941 } 11942 11943 static int 11944 parse_ia_id2ptr(struct context *ctx, const struct token *token, 11945 const char *str, unsigned int len, 11946 void *buf, unsigned int size) 11947 { 11948 struct rte_flow_action *action = ctx->object; 11949 uint32_t id; 11950 int ret; 11951 11952 (void)buf; 11953 (void)size; 11954 ctx->objdata = 0; 11955 ctx->object = &id; 11956 ctx->objmask = NULL; 11957 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11958 ctx->object = action; 11959 if (ret != (int)len) 11960 return ret; 11961 /* set indirect action */ 11962 if (action) { 11963 portid_t port_id = ctx->port; 11964 if (ctx->prev == INDIRECT_ACTION_PORT) 11965 port_id = (portid_t)(uintptr_t)action->conf; 11966 action->conf = port_action_handle_get_by_id(port_id, id); 11967 ret = (action->conf) ? ret : -1; 11968 } 11969 return ret; 11970 } 11971 11972 static int 11973 parse_indlst_id2ptr(struct context *ctx, const struct token *token, 11974 const char *str, unsigned int len, 11975 __rte_unused void *buf, __rte_unused unsigned int size) 11976 { 11977 struct rte_flow_action *action = ctx->object; 11978 struct rte_flow_action_indirect_list *action_conf; 11979 const struct indlst_conf *indlst_conf; 11980 uint32_t id; 11981 int ret; 11982 11983 ctx->objdata = 0; 11984 ctx->object = &id; 11985 ctx->objmask = NULL; 11986 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11987 ctx->object = action; 11988 if (ret != (int)len) 11989 return ret; 11990 11991 /* set handle and conf */ 11992 if (action) { 11993 action_conf = (void *)(uintptr_t)action->conf; 11994 action_conf->conf = NULL; 11995 switch (ctx->curr) { 11996 case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: 11997 action_conf->handle = (typeof(action_conf->handle)) 11998 port_action_handle_get_by_id(ctx->port, id); 11999 if (!action_conf->handle) { 12000 printf("no indirect list handle for id %u\n", id); 12001 return -1; 12002 } 12003 break; 12004 case INDIRECT_LIST_ACTION_ID2PTR_CONF: 12005 indlst_conf = indirect_action_list_conf_get(id); 12006 if (!indlst_conf) 12007 return -1; 12008 action_conf->conf = (const void **)indlst_conf->conf; 12009 break; 12010 default: 12011 break; 12012 } 12013 } 12014 return ret; 12015 } 12016 12017 static int 12018 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 12019 const char *str, unsigned int len, 12020 void *buf, unsigned int size) 12021 { 12022 struct rte_flow_action *action = ctx->object; 12023 struct rte_flow_action_meter_mark *meter; 12024 struct rte_flow_meter_profile *profile = NULL; 12025 uint32_t id = 0; 12026 int ret; 12027 12028 (void)buf; 12029 (void)size; 12030 ctx->objdata = 0; 12031 ctx->object = &id; 12032 ctx->objmask = NULL; 12033 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12034 ctx->object = action; 12035 if (ret != (int)len) 12036 return ret; 12037 /* set meter profile */ 12038 if (action) { 12039 meter = (struct rte_flow_action_meter_mark *) 12040 (uintptr_t)(action->conf); 12041 profile = port_meter_profile_get_by_id(ctx->port, id); 12042 meter->profile = profile; 12043 ret = (profile) ? ret : -1; 12044 } 12045 return ret; 12046 } 12047 12048 static int 12049 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 12050 const char *str, unsigned int len, 12051 void *buf, unsigned int size) 12052 { 12053 struct rte_flow_action *action = ctx->object; 12054 struct rte_flow_action_meter_mark *meter; 12055 struct rte_flow_meter_policy *policy = NULL; 12056 uint32_t id = 0; 12057 int ret; 12058 12059 (void)buf; 12060 (void)size; 12061 ctx->objdata = 0; 12062 ctx->object = &id; 12063 ctx->objmask = NULL; 12064 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 12065 ctx->object = action; 12066 if (ret != (int)len) 12067 return ret; 12068 /* set meter policy */ 12069 if (action) { 12070 meter = (struct rte_flow_action_meter_mark *) 12071 (uintptr_t)(action->conf); 12072 policy = port_meter_policy_get_by_id(ctx->port, id); 12073 meter->policy = policy; 12074 ret = (policy) ? ret : -1; 12075 } 12076 return ret; 12077 } 12078 12079 /** Parse set command, initialize output buffer for subsequent tokens. */ 12080 static int 12081 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 12082 const char *str, unsigned int len, 12083 void *buf, unsigned int size) 12084 { 12085 struct buffer *out = buf; 12086 12087 /* Token name must match. */ 12088 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12089 return -1; 12090 /* Nothing else to do if there is no buffer. */ 12091 if (!out) 12092 return len; 12093 /* Make sure buffer is large enough. */ 12094 if (size < sizeof(*out)) 12095 return -1; 12096 ctx->objdata = 0; 12097 ctx->objmask = NULL; 12098 ctx->object = out; 12099 if (!out->command) 12100 return -1; 12101 out->command = ctx->curr; 12102 /* For encap/decap we need is pattern */ 12103 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12104 sizeof(double)); 12105 return len; 12106 } 12107 12108 /** Parse set command, initialize output buffer for subsequent tokens. */ 12109 static int 12110 parse_set_sample_action(struct context *ctx, const struct token *token, 12111 const char *str, unsigned int len, 12112 void *buf, unsigned int size) 12113 { 12114 struct buffer *out = buf; 12115 12116 /* Token name must match. */ 12117 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12118 return -1; 12119 /* Nothing else to do if there is no buffer. */ 12120 if (!out) 12121 return len; 12122 /* Make sure buffer is large enough. */ 12123 if (size < sizeof(*out)) 12124 return -1; 12125 ctx->objdata = 0; 12126 ctx->objmask = NULL; 12127 ctx->object = out; 12128 if (!out->command) 12129 return -1; 12130 out->command = ctx->curr; 12131 /* For sampler we need is actions */ 12132 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12133 sizeof(double)); 12134 return len; 12135 } 12136 12137 /** Parse set command, initialize output buffer for subsequent tokens. */ 12138 static int 12139 parse_set_ipv6_ext_action(struct context *ctx, const struct token *token, 12140 const char *str, unsigned int len, 12141 void *buf, unsigned int size) 12142 { 12143 struct buffer *out = buf; 12144 12145 /* Token name must match. */ 12146 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12147 return -1; 12148 /* Nothing else to do if there is no buffer. */ 12149 if (!out) 12150 return len; 12151 /* Make sure buffer is large enough. */ 12152 if (size < sizeof(*out)) 12153 return -1; 12154 ctx->objdata = 0; 12155 ctx->objmask = NULL; 12156 ctx->object = out; 12157 if (!out->command) 12158 return -1; 12159 out->command = ctx->curr; 12160 /* For ipv6_ext_push/remove we need is pattern */ 12161 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12162 sizeof(double)); 12163 return len; 12164 } 12165 12166 /** 12167 * Parse set raw_encap/raw_decap command, 12168 * initialize output buffer for subsequent tokens. 12169 */ 12170 static int 12171 parse_set_init(struct context *ctx, const struct token *token, 12172 const char *str, unsigned int len, 12173 void *buf, unsigned int size) 12174 { 12175 struct buffer *out = buf; 12176 12177 /* Token name must match. */ 12178 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12179 return -1; 12180 /* Nothing else to do if there is no buffer. */ 12181 if (!out) 12182 return len; 12183 /* Make sure buffer is large enough. */ 12184 if (size < sizeof(*out)) 12185 return -1; 12186 /* Initialize buffer. */ 12187 memset(out, 0x00, sizeof(*out)); 12188 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 12189 ctx->objdata = 0; 12190 ctx->object = out; 12191 ctx->objmask = NULL; 12192 if (!out->command) { 12193 if (ctx->curr != SET) 12194 return -1; 12195 if (sizeof(*out) > size) 12196 return -1; 12197 out->command = ctx->curr; 12198 out->args.vc.data = (uint8_t *)out + size; 12199 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12200 sizeof(double)); 12201 } 12202 return len; 12203 } 12204 12205 /* 12206 * Replace testpmd handles in a flex flow item with real values. 12207 */ 12208 static int 12209 parse_flex_handle(struct context *ctx, const struct token *token, 12210 const char *str, unsigned int len, 12211 void *buf, unsigned int size) 12212 { 12213 struct rte_flow_item_flex *spec, *mask; 12214 const struct rte_flow_item_flex *src_spec, *src_mask; 12215 const struct arg *arg = pop_args(ctx); 12216 uint32_t offset; 12217 uint16_t handle; 12218 int ret; 12219 12220 if (!arg) { 12221 printf("Bad environment\n"); 12222 return -1; 12223 } 12224 offset = arg->offset; 12225 push_args(ctx, arg); 12226 ret = parse_int(ctx, token, str, len, buf, size); 12227 if (ret <= 0 || !ctx->object) 12228 return ret; 12229 if (ctx->port >= RTE_MAX_ETHPORTS) { 12230 printf("Bad port\n"); 12231 return -1; 12232 } 12233 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 12234 const struct flex_item *fp; 12235 spec = ctx->object; 12236 handle = (uint16_t)(uintptr_t)spec->handle; 12237 if (handle >= FLEX_MAX_PARSERS_NUM) { 12238 printf("Bad flex item handle\n"); 12239 return -1; 12240 } 12241 fp = flex_items[ctx->port][handle]; 12242 if (!fp) { 12243 printf("Bad flex item handle\n"); 12244 return -1; 12245 } 12246 spec->handle = fp->flex_handle; 12247 mask = spec + 2; /* spec, last, mask */ 12248 mask->handle = fp->flex_handle; 12249 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 12250 handle = (uint16_t)(uintptr_t) 12251 ((struct rte_flow_item_flex *)ctx->object)->pattern; 12252 if (handle >= FLEX_MAX_PATTERNS_NUM) { 12253 printf("Bad pattern handle\n"); 12254 return -1; 12255 } 12256 src_spec = &flex_patterns[handle].spec; 12257 src_mask = &flex_patterns[handle].mask; 12258 spec = ctx->object; 12259 mask = spec + 2; /* spec, last, mask */ 12260 /* fill flow rule spec and mask parameters */ 12261 spec->length = src_spec->length; 12262 spec->pattern = src_spec->pattern; 12263 mask->length = src_mask->length; 12264 mask->pattern = src_mask->pattern; 12265 } else { 12266 printf("Bad arguments - unknown flex item offset\n"); 12267 return -1; 12268 } 12269 return ret; 12270 } 12271 12272 /** Parse Meter color name */ 12273 static int 12274 parse_meter_color(struct context *ctx, const struct token *token, 12275 const char *str, unsigned int len, void *buf, 12276 unsigned int size) 12277 { 12278 struct rte_flow_item_meter_color *meter_color; 12279 unsigned int i; 12280 12281 (void)token; 12282 (void)buf; 12283 (void)size; 12284 for (i = 0; meter_colors[i]; ++i) 12285 if (!strcmp_partial(meter_colors[i], str, len)) 12286 break; 12287 if (!meter_colors[i]) 12288 return -1; 12289 if (!ctx->object) 12290 return len; 12291 meter_color = ctx->object; 12292 meter_color->color = (enum rte_color)i; 12293 return len; 12294 } 12295 12296 /** Parse Insertion Table Type name */ 12297 static int 12298 parse_insertion_table_type(struct context *ctx, const struct token *token, 12299 const char *str, unsigned int len, void *buf, 12300 unsigned int size) 12301 { 12302 const struct arg *arg = pop_args(ctx); 12303 unsigned int i; 12304 char tmp[2]; 12305 int ret; 12306 12307 (void)size; 12308 /* Argument is expected. */ 12309 if (!arg) 12310 return -1; 12311 for (i = 0; table_insertion_types[i]; ++i) 12312 if (!strcmp_partial(table_insertion_types[i], str, len)) 12313 break; 12314 if (!table_insertion_types[i]) 12315 return -1; 12316 push_args(ctx, arg); 12317 snprintf(tmp, sizeof(tmp), "%u", i); 12318 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12319 return ret > 0 ? (int)len : ret; 12320 } 12321 12322 /** Parse Hash Calculation Table Type name */ 12323 static int 12324 parse_hash_table_type(struct context *ctx, const struct token *token, 12325 const char *str, unsigned int len, void *buf, 12326 unsigned int size) 12327 { 12328 const struct arg *arg = pop_args(ctx); 12329 unsigned int i; 12330 char tmp[2]; 12331 int ret; 12332 12333 (void)size; 12334 /* Argument is expected. */ 12335 if (!arg) 12336 return -1; 12337 for (i = 0; table_hash_funcs[i]; ++i) 12338 if (!strcmp_partial(table_hash_funcs[i], str, len)) 12339 break; 12340 if (!table_hash_funcs[i]) 12341 return -1; 12342 push_args(ctx, arg); 12343 snprintf(tmp, sizeof(tmp), "%u", i); 12344 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12345 return ret > 0 ? (int)len : ret; 12346 } 12347 12348 static int 12349 parse_name_to_index(struct context *ctx, const struct token *token, 12350 const char *str, unsigned int len, void *buf, 12351 unsigned int size, 12352 const char *const names[], size_t names_size, uint32_t *dst) 12353 { 12354 int ret; 12355 uint32_t i; 12356 12357 RTE_SET_USED(token); 12358 RTE_SET_USED(buf); 12359 RTE_SET_USED(size); 12360 if (!ctx->object) 12361 return len; 12362 for (i = 0; i < names_size; i++) { 12363 if (!names[i]) 12364 continue; 12365 ret = strcmp_partial(names[i], str, 12366 RTE_MIN(len, strlen(names[i]))); 12367 if (!ret) { 12368 *dst = i; 12369 return len; 12370 } 12371 } 12372 return -1; 12373 } 12374 12375 static const char *const quota_mode_names[] = { 12376 NULL, 12377 [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", 12378 [RTE_FLOW_QUOTA_MODE_L2] = "l2", 12379 [RTE_FLOW_QUOTA_MODE_L3] = "l3" 12380 }; 12381 12382 static const char *const quota_state_names[] = { 12383 [RTE_FLOW_QUOTA_STATE_PASS] = "pass", 12384 [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" 12385 }; 12386 12387 static const char *const quota_update_names[] = { 12388 [RTE_FLOW_UPDATE_QUOTA_SET] = "set", 12389 [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" 12390 }; 12391 12392 static const char *const query_update_mode_names[] = { 12393 [RTE_FLOW_QU_QUERY_FIRST] = "query_first", 12394 [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" 12395 }; 12396 12397 static int 12398 parse_quota_state_name(struct context *ctx, const struct token *token, 12399 const char *str, unsigned int len, void *buf, 12400 unsigned int size) 12401 { 12402 struct rte_flow_item_quota *quota = ctx->object; 12403 12404 return parse_name_to_index(ctx, token, str, len, buf, size, 12405 quota_state_names, 12406 RTE_DIM(quota_state_names), 12407 (uint32_t *)"a->state); 12408 } 12409 12410 static int 12411 parse_quota_mode_name(struct context *ctx, const struct token *token, 12412 const char *str, unsigned int len, void *buf, 12413 unsigned int size) 12414 { 12415 struct rte_flow_action_quota *quota = ctx->object; 12416 12417 return parse_name_to_index(ctx, token, str, len, buf, size, 12418 quota_mode_names, 12419 RTE_DIM(quota_mode_names), 12420 (uint32_t *)"a->mode); 12421 } 12422 12423 static int 12424 parse_quota_update_name(struct context *ctx, const struct token *token, 12425 const char *str, unsigned int len, void *buf, 12426 unsigned int size) 12427 { 12428 struct rte_flow_update_quota *update = ctx->object; 12429 12430 return parse_name_to_index(ctx, token, str, len, buf, size, 12431 quota_update_names, 12432 RTE_DIM(quota_update_names), 12433 (uint32_t *)&update->op); 12434 } 12435 12436 static int 12437 parse_qu_mode_name(struct context *ctx, const struct token *token, 12438 const char *str, unsigned int len, void *buf, 12439 unsigned int size) 12440 { 12441 struct buffer *out = ctx->object; 12442 12443 return parse_name_to_index(ctx, token, str, len, buf, size, 12444 query_update_mode_names, 12445 RTE_DIM(query_update_mode_names), 12446 (uint32_t *)&out->args.ia.qu_mode); 12447 } 12448 12449 /** No completion. */ 12450 static int 12451 comp_none(struct context *ctx, const struct token *token, 12452 unsigned int ent, char *buf, unsigned int size) 12453 { 12454 (void)ctx; 12455 (void)token; 12456 (void)ent; 12457 (void)buf; 12458 (void)size; 12459 return 0; 12460 } 12461 12462 /** Complete boolean values. */ 12463 static int 12464 comp_boolean(struct context *ctx, const struct token *token, 12465 unsigned int ent, char *buf, unsigned int size) 12466 { 12467 unsigned int i; 12468 12469 (void)ctx; 12470 (void)token; 12471 for (i = 0; boolean_name[i]; ++i) 12472 if (buf && i == ent) 12473 return strlcpy(buf, boolean_name[i], size); 12474 if (buf) 12475 return -1; 12476 return i; 12477 } 12478 12479 /** Complete action names. */ 12480 static int 12481 comp_action(struct context *ctx, const struct token *token, 12482 unsigned int ent, char *buf, unsigned int size) 12483 { 12484 unsigned int i; 12485 12486 (void)ctx; 12487 (void)token; 12488 for (i = 0; next_action[i]; ++i) 12489 if (buf && i == ent) 12490 return strlcpy(buf, token_list[next_action[i]].name, 12491 size); 12492 if (buf) 12493 return -1; 12494 return i; 12495 } 12496 12497 /** Complete available ports. */ 12498 static int 12499 comp_port(struct context *ctx, const struct token *token, 12500 unsigned int ent, char *buf, unsigned int size) 12501 { 12502 unsigned int i = 0; 12503 portid_t p; 12504 12505 (void)ctx; 12506 (void)token; 12507 RTE_ETH_FOREACH_DEV(p) { 12508 if (buf && i == ent) 12509 return snprintf(buf, size, "%u", p); 12510 ++i; 12511 } 12512 if (buf) 12513 return -1; 12514 return i; 12515 } 12516 12517 /** Complete available rule IDs. */ 12518 static int 12519 comp_rule_id(struct context *ctx, const struct token *token, 12520 unsigned int ent, char *buf, unsigned int size) 12521 { 12522 unsigned int i = 0; 12523 struct rte_port *port; 12524 struct port_flow *pf; 12525 12526 (void)token; 12527 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12528 ctx->port == (portid_t)RTE_PORT_ALL) 12529 return -1; 12530 port = &ports[ctx->port]; 12531 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 12532 if (buf && i == ent) 12533 return snprintf(buf, size, "%"PRIu64, pf->id); 12534 ++i; 12535 } 12536 if (buf) 12537 return -1; 12538 return i; 12539 } 12540 12541 /** Complete operation for compare match item. */ 12542 static int 12543 comp_set_compare_op(struct context *ctx, const struct token *token, 12544 unsigned int ent, char *buf, unsigned int size) 12545 { 12546 RTE_SET_USED(ctx); 12547 RTE_SET_USED(token); 12548 if (!buf) 12549 return RTE_DIM(compare_ops); 12550 if (ent < RTE_DIM(compare_ops) - 1) 12551 return strlcpy(buf, compare_ops[ent], size); 12552 return -1; 12553 } 12554 12555 /** Complete field id for compare match item. */ 12556 static int 12557 comp_set_compare_field_id(struct context *ctx, const struct token *token, 12558 unsigned int ent, char *buf, unsigned int size) 12559 { 12560 const char *name; 12561 12562 RTE_SET_USED(token); 12563 if (!buf) 12564 return RTE_DIM(flow_field_ids); 12565 if (ent >= RTE_DIM(flow_field_ids) - 1) 12566 return -1; 12567 name = flow_field_ids[ent]; 12568 if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE || 12569 (strcmp(name, "pointer") && strcmp(name, "value"))) 12570 return strlcpy(buf, name, size); 12571 return -1; 12572 } 12573 12574 /** Complete type field for RSS action. */ 12575 static int 12576 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 12577 unsigned int ent, char *buf, unsigned int size) 12578 { 12579 unsigned int i; 12580 12581 (void)ctx; 12582 (void)token; 12583 for (i = 0; rss_type_table[i].str; ++i) 12584 ; 12585 if (!buf) 12586 return i + 1; 12587 if (ent < i) 12588 return strlcpy(buf, rss_type_table[ent].str, size); 12589 if (ent == i) 12590 return snprintf(buf, size, "end"); 12591 return -1; 12592 } 12593 12594 /** Complete queue field for RSS action. */ 12595 static int 12596 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 12597 unsigned int ent, char *buf, unsigned int size) 12598 { 12599 (void)ctx; 12600 (void)token; 12601 if (!buf) 12602 return nb_rxq + 1; 12603 if (ent < nb_rxq) 12604 return snprintf(buf, size, "%u", ent); 12605 if (ent == nb_rxq) 12606 return snprintf(buf, size, "end"); 12607 return -1; 12608 } 12609 12610 /** Complete index number for set raw_encap/raw_decap commands. */ 12611 static int 12612 comp_set_raw_index(struct context *ctx, const struct token *token, 12613 unsigned int ent, char *buf, unsigned int size) 12614 { 12615 uint16_t idx = 0; 12616 uint16_t nb = 0; 12617 12618 RTE_SET_USED(ctx); 12619 RTE_SET_USED(token); 12620 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 12621 if (buf && idx == ent) 12622 return snprintf(buf, size, "%u", idx); 12623 ++nb; 12624 } 12625 return nb; 12626 } 12627 12628 /** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ 12629 static int 12630 comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 12631 unsigned int ent, char *buf, unsigned int size) 12632 { 12633 uint16_t idx = 0; 12634 uint16_t nb = 0; 12635 12636 RTE_SET_USED(ctx); 12637 RTE_SET_USED(token); 12638 for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { 12639 if (buf && idx == ent) 12640 return snprintf(buf, size, "%u", idx); 12641 ++nb; 12642 } 12643 return nb; 12644 } 12645 12646 /** Complete index number for set raw_encap/raw_decap commands. */ 12647 static int 12648 comp_set_sample_index(struct context *ctx, const struct token *token, 12649 unsigned int ent, char *buf, unsigned int size) 12650 { 12651 uint16_t idx = 0; 12652 uint16_t nb = 0; 12653 12654 RTE_SET_USED(ctx); 12655 RTE_SET_USED(token); 12656 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 12657 if (buf && idx == ent) 12658 return snprintf(buf, size, "%u", idx); 12659 ++nb; 12660 } 12661 return nb; 12662 } 12663 12664 /** Complete operation for modify_field command. */ 12665 static int 12666 comp_set_modify_field_op(struct context *ctx, const struct token *token, 12667 unsigned int ent, char *buf, unsigned int size) 12668 { 12669 RTE_SET_USED(ctx); 12670 RTE_SET_USED(token); 12671 if (!buf) 12672 return RTE_DIM(modify_field_ops); 12673 if (ent < RTE_DIM(modify_field_ops) - 1) 12674 return strlcpy(buf, modify_field_ops[ent], size); 12675 return -1; 12676 } 12677 12678 /** Complete field id for modify_field command. */ 12679 static int 12680 comp_set_modify_field_id(struct context *ctx, const struct token *token, 12681 unsigned int ent, char *buf, unsigned int size) 12682 { 12683 const char *name; 12684 12685 RTE_SET_USED(token); 12686 if (!buf) 12687 return RTE_DIM(flow_field_ids); 12688 if (ent >= RTE_DIM(flow_field_ids) - 1) 12689 return -1; 12690 name = flow_field_ids[ent]; 12691 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 12692 (strcmp(name, "pointer") && strcmp(name, "value"))) 12693 return strlcpy(buf, name, size); 12694 return -1; 12695 } 12696 12697 /** Complete available pattern template IDs. */ 12698 static int 12699 comp_pattern_template_id(struct context *ctx, const struct token *token, 12700 unsigned int ent, char *buf, unsigned int size) 12701 { 12702 unsigned int i = 0; 12703 struct rte_port *port; 12704 struct port_template *pt; 12705 12706 (void)token; 12707 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12708 ctx->port == (portid_t)RTE_PORT_ALL) 12709 return -1; 12710 port = &ports[ctx->port]; 12711 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 12712 if (buf && i == ent) 12713 return snprintf(buf, size, "%u", pt->id); 12714 ++i; 12715 } 12716 if (buf) 12717 return -1; 12718 return i; 12719 } 12720 12721 /** Complete available actions template IDs. */ 12722 static int 12723 comp_actions_template_id(struct context *ctx, const struct token *token, 12724 unsigned int ent, char *buf, unsigned int size) 12725 { 12726 unsigned int i = 0; 12727 struct rte_port *port; 12728 struct port_template *pt; 12729 12730 (void)token; 12731 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12732 ctx->port == (portid_t)RTE_PORT_ALL) 12733 return -1; 12734 port = &ports[ctx->port]; 12735 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 12736 if (buf && i == ent) 12737 return snprintf(buf, size, "%u", pt->id); 12738 ++i; 12739 } 12740 if (buf) 12741 return -1; 12742 return i; 12743 } 12744 12745 /** Complete available table IDs. */ 12746 static int 12747 comp_table_id(struct context *ctx, const struct token *token, 12748 unsigned int ent, char *buf, unsigned int size) 12749 { 12750 unsigned int i = 0; 12751 struct rte_port *port; 12752 struct port_table *pt; 12753 12754 (void)token; 12755 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12756 ctx->port == (portid_t)RTE_PORT_ALL) 12757 return -1; 12758 port = &ports[ctx->port]; 12759 for (pt = port->table_list; pt != NULL; pt = pt->next) { 12760 if (buf && i == ent) 12761 return snprintf(buf, size, "%u", pt->id); 12762 ++i; 12763 } 12764 if (buf) 12765 return -1; 12766 return i; 12767 } 12768 12769 /** Complete available queue IDs. */ 12770 static int 12771 comp_queue_id(struct context *ctx, const struct token *token, 12772 unsigned int ent, char *buf, unsigned int size) 12773 { 12774 unsigned int i = 0; 12775 struct rte_port *port; 12776 12777 (void)token; 12778 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12779 ctx->port == (portid_t)RTE_PORT_ALL) 12780 return -1; 12781 port = &ports[ctx->port]; 12782 for (i = 0; i < port->queue_nb; i++) { 12783 if (buf && i == ent) 12784 return snprintf(buf, size, "%u", i); 12785 } 12786 if (buf) 12787 return -1; 12788 return i; 12789 } 12790 12791 static int 12792 comp_names_to_index(struct context *ctx, const struct token *token, 12793 unsigned int ent, char *buf, unsigned int size, 12794 const char *const names[], size_t names_size) 12795 { 12796 RTE_SET_USED(ctx); 12797 RTE_SET_USED(token); 12798 if (!buf) 12799 return names_size; 12800 if (names[ent] && ent < names_size) 12801 return rte_strscpy(buf, names[ent], size); 12802 return -1; 12803 12804 } 12805 12806 /** Complete available Meter colors. */ 12807 static int 12808 comp_meter_color(struct context *ctx, const struct token *token, 12809 unsigned int ent, char *buf, unsigned int size) 12810 { 12811 RTE_SET_USED(ctx); 12812 RTE_SET_USED(token); 12813 if (!buf) 12814 return RTE_DIM(meter_colors); 12815 if (ent < RTE_DIM(meter_colors) - 1) 12816 return strlcpy(buf, meter_colors[ent], size); 12817 return -1; 12818 } 12819 12820 /** Complete available Insertion Table types. */ 12821 static int 12822 comp_insertion_table_type(struct context *ctx, const struct token *token, 12823 unsigned int ent, char *buf, unsigned int size) 12824 { 12825 RTE_SET_USED(ctx); 12826 RTE_SET_USED(token); 12827 if (!buf) 12828 return RTE_DIM(table_insertion_types); 12829 if (ent < RTE_DIM(table_insertion_types) - 1) 12830 return rte_strscpy(buf, table_insertion_types[ent], size); 12831 return -1; 12832 } 12833 12834 /** Complete available Hash Calculation Table types. */ 12835 static int 12836 comp_hash_table_type(struct context *ctx, const struct token *token, 12837 unsigned int ent, char *buf, unsigned int size) 12838 { 12839 RTE_SET_USED(ctx); 12840 RTE_SET_USED(token); 12841 if (!buf) 12842 return RTE_DIM(table_hash_funcs); 12843 if (ent < RTE_DIM(table_hash_funcs) - 1) 12844 return rte_strscpy(buf, table_hash_funcs[ent], size); 12845 return -1; 12846 } 12847 12848 static int 12849 comp_quota_state_name(struct context *ctx, const struct token *token, 12850 unsigned int ent, char *buf, unsigned int size) 12851 { 12852 return comp_names_to_index(ctx, token, ent, buf, size, 12853 quota_state_names, 12854 RTE_DIM(quota_state_names)); 12855 } 12856 12857 static int 12858 comp_quota_mode_name(struct context *ctx, const struct token *token, 12859 unsigned int ent, char *buf, unsigned int size) 12860 { 12861 return comp_names_to_index(ctx, token, ent, buf, size, 12862 quota_mode_names, 12863 RTE_DIM(quota_mode_names)); 12864 } 12865 12866 static int 12867 comp_quota_update_name(struct context *ctx, const struct token *token, 12868 unsigned int ent, char *buf, unsigned int size) 12869 { 12870 return comp_names_to_index(ctx, token, ent, buf, size, 12871 quota_update_names, 12872 RTE_DIM(quota_update_names)); 12873 } 12874 12875 static int 12876 comp_qu_mode_name(struct context *ctx, const struct token *token, 12877 unsigned int ent, char *buf, unsigned int size) 12878 { 12879 return comp_names_to_index(ctx, token, ent, buf, size, 12880 query_update_mode_names, 12881 RTE_DIM(query_update_mode_names)); 12882 } 12883 12884 /** Internal context. */ 12885 static struct context cmd_flow_context; 12886 12887 /** Global parser instance (cmdline API). */ 12888 cmdline_parse_inst_t cmd_flow; 12889 cmdline_parse_inst_t cmd_set_raw; 12890 12891 /** Initialize context. */ 12892 static void 12893 cmd_flow_context_init(struct context *ctx) 12894 { 12895 /* A full memset() is not necessary. */ 12896 ctx->curr = ZERO; 12897 ctx->prev = ZERO; 12898 ctx->next_num = 0; 12899 ctx->args_num = 0; 12900 ctx->eol = 0; 12901 ctx->last = 0; 12902 ctx->port = 0; 12903 ctx->objdata = 0; 12904 ctx->object = NULL; 12905 ctx->objmask = NULL; 12906 } 12907 12908 /** Parse a token (cmdline API). */ 12909 static int 12910 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 12911 unsigned int size) 12912 { 12913 struct context *ctx = &cmd_flow_context; 12914 const struct token *token; 12915 const enum index *list; 12916 int len; 12917 int i; 12918 12919 (void)hdr; 12920 token = &token_list[ctx->curr]; 12921 /* Check argument length. */ 12922 ctx->eol = 0; 12923 ctx->last = 1; 12924 for (len = 0; src[len]; ++len) 12925 if (src[len] == '#' || isspace(src[len])) 12926 break; 12927 if (!len) 12928 return -1; 12929 /* Last argument and EOL detection. */ 12930 for (i = len; src[i]; ++i) 12931 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 12932 break; 12933 else if (!isspace(src[i])) { 12934 ctx->last = 0; 12935 break; 12936 } 12937 for (; src[i]; ++i) 12938 if (src[i] == '\r' || src[i] == '\n') { 12939 ctx->eol = 1; 12940 break; 12941 } 12942 /* Initialize context if necessary. */ 12943 if (!ctx->next_num) { 12944 if (!token->next) 12945 return 0; 12946 ctx->next[ctx->next_num++] = token->next[0]; 12947 } 12948 /* Process argument through candidates. */ 12949 ctx->prev = ctx->curr; 12950 list = ctx->next[ctx->next_num - 1]; 12951 for (i = 0; list[i]; ++i) { 12952 const struct token *next = &token_list[list[i]]; 12953 int tmp; 12954 12955 ctx->curr = list[i]; 12956 if (next->call) 12957 tmp = next->call(ctx, next, src, len, result, size); 12958 else 12959 tmp = parse_default(ctx, next, src, len, result, size); 12960 if (tmp == -1 || tmp != len) 12961 continue; 12962 token = next; 12963 break; 12964 } 12965 if (!list[i]) 12966 return -1; 12967 --ctx->next_num; 12968 /* Push subsequent tokens if any. */ 12969 if (token->next) 12970 for (i = 0; token->next[i]; ++i) { 12971 if (ctx->next_num == RTE_DIM(ctx->next)) 12972 return -1; 12973 ctx->next[ctx->next_num++] = token->next[i]; 12974 } 12975 /* Push arguments if any. */ 12976 if (token->args) 12977 for (i = 0; token->args[i]; ++i) { 12978 if (ctx->args_num == RTE_DIM(ctx->args)) 12979 return -1; 12980 ctx->args[ctx->args_num++] = token->args[i]; 12981 } 12982 return len; 12983 } 12984 12985 int 12986 flow_parse(const char *src, void *result, unsigned int size, 12987 struct rte_flow_attr **attr, 12988 struct rte_flow_item **pattern, struct rte_flow_action **actions) 12989 { 12990 int ret; 12991 struct context saved_flow_ctx = cmd_flow_context; 12992 12993 cmd_flow_context_init(&cmd_flow_context); 12994 do { 12995 ret = cmd_flow_parse(NULL, src, result, size); 12996 if (ret > 0) { 12997 src += ret; 12998 while (isspace(*src)) 12999 src++; 13000 } 13001 } while (ret > 0 && strlen(src)); 13002 cmd_flow_context = saved_flow_ctx; 13003 *attr = &((struct buffer *)result)->args.vc.attr; 13004 *pattern = ((struct buffer *)result)->args.vc.pattern; 13005 *actions = ((struct buffer *)result)->args.vc.actions; 13006 return (ret >= 0 && !strlen(src)) ? 0 : -1; 13007 } 13008 13009 /** Return number of completion entries (cmdline API). */ 13010 static int 13011 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 13012 { 13013 struct context *ctx = &cmd_flow_context; 13014 const struct token *token = &token_list[ctx->curr]; 13015 const enum index *list; 13016 int i; 13017 13018 (void)hdr; 13019 /* Count number of tokens in current list. */ 13020 if (ctx->next_num) 13021 list = ctx->next[ctx->next_num - 1]; 13022 else 13023 list = token->next[0]; 13024 for (i = 0; list[i]; ++i) 13025 ; 13026 if (!i) 13027 return 0; 13028 /* 13029 * If there is a single token, use its completion callback, otherwise 13030 * return the number of entries. 13031 */ 13032 token = &token_list[list[0]]; 13033 if (i == 1 && token->comp) { 13034 /* Save index for cmd_flow_get_help(). */ 13035 ctx->prev = list[0]; 13036 return token->comp(ctx, token, 0, NULL, 0); 13037 } 13038 return i; 13039 } 13040 13041 /** Return a completion entry (cmdline API). */ 13042 static int 13043 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 13044 char *dst, unsigned int size) 13045 { 13046 struct context *ctx = &cmd_flow_context; 13047 const struct token *token = &token_list[ctx->curr]; 13048 const enum index *list; 13049 int i; 13050 13051 (void)hdr; 13052 /* Count number of tokens in current list. */ 13053 if (ctx->next_num) 13054 list = ctx->next[ctx->next_num - 1]; 13055 else 13056 list = token->next[0]; 13057 for (i = 0; list[i]; ++i) 13058 ; 13059 if (!i) 13060 return -1; 13061 /* If there is a single token, use its completion callback. */ 13062 token = &token_list[list[0]]; 13063 if (i == 1 && token->comp) { 13064 /* Save index for cmd_flow_get_help(). */ 13065 ctx->prev = list[0]; 13066 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 13067 } 13068 /* Otherwise make sure the index is valid and use defaults. */ 13069 if (index >= i) 13070 return -1; 13071 token = &token_list[list[index]]; 13072 strlcpy(dst, token->name, size); 13073 /* Save index for cmd_flow_get_help(). */ 13074 ctx->prev = list[index]; 13075 return 0; 13076 } 13077 13078 /** Populate help strings for current token (cmdline API). */ 13079 static int 13080 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 13081 { 13082 struct context *ctx = &cmd_flow_context; 13083 const struct token *token = &token_list[ctx->prev]; 13084 13085 (void)hdr; 13086 if (!size) 13087 return -1; 13088 /* Set token type and update global help with details. */ 13089 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 13090 if (token->help) 13091 cmd_flow.help_str = token->help; 13092 else 13093 cmd_flow.help_str = token->name; 13094 return 0; 13095 } 13096 13097 /** Token definition template (cmdline API). */ 13098 static struct cmdline_token_hdr cmd_flow_token_hdr = { 13099 .ops = &(struct cmdline_token_ops){ 13100 .parse = cmd_flow_parse, 13101 .complete_get_nb = cmd_flow_complete_get_nb, 13102 .complete_get_elt = cmd_flow_complete_get_elt, 13103 .get_help = cmd_flow_get_help, 13104 }, 13105 .offset = 0, 13106 }; 13107 13108 /** Populate the next dynamic token. */ 13109 static void 13110 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 13111 cmdline_parse_token_hdr_t **hdr_inst) 13112 { 13113 struct context *ctx = &cmd_flow_context; 13114 13115 /* Always reinitialize context before requesting the first token. */ 13116 if (!(hdr_inst - cmd_flow.tokens)) 13117 cmd_flow_context_init(ctx); 13118 /* Return NULL when no more tokens are expected. */ 13119 if (!ctx->next_num && ctx->curr) { 13120 *hdr = NULL; 13121 return; 13122 } 13123 /* Determine if command should end here. */ 13124 if (ctx->eol && ctx->last && ctx->next_num) { 13125 const enum index *list = ctx->next[ctx->next_num - 1]; 13126 int i; 13127 13128 for (i = 0; list[i]; ++i) { 13129 if (list[i] != END) 13130 continue; 13131 *hdr = NULL; 13132 return; 13133 } 13134 } 13135 *hdr = &cmd_flow_token_hdr; 13136 } 13137 13138 static SLIST_HEAD(, indlst_conf) indlst_conf_head = 13139 SLIST_HEAD_INITIALIZER(); 13140 13141 static void 13142 indirect_action_flow_conf_create(const struct buffer *in) 13143 { 13144 int len, ret; 13145 uint32_t i; 13146 struct indlst_conf *indlst_conf = NULL; 13147 size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); 13148 struct rte_flow_action *src = in->args.vc.actions; 13149 13150 if (!in->args.vc.actions_n) 13151 goto end; 13152 len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); 13153 if (len <= 0) 13154 goto end; 13155 len = RTE_ALIGN(len, 16); 13156 13157 indlst_conf = calloc(1, base + len + 13158 in->args.vc.actions_n * sizeof(uintptr_t)); 13159 if (!indlst_conf) 13160 goto end; 13161 indlst_conf->id = in->args.vc.attr.group; 13162 indlst_conf->conf_num = in->args.vc.actions_n - 1; 13163 indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); 13164 ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, 13165 len, src, NULL); 13166 if (ret <= 0) { 13167 free(indlst_conf); 13168 indlst_conf = NULL; 13169 goto end; 13170 } 13171 indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); 13172 for (i = 0; i < indlst_conf->conf_num; i++) 13173 indlst_conf->conf[i] = indlst_conf->actions[i].conf; 13174 SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); 13175 end: 13176 if (indlst_conf) 13177 printf("created indirect action list configuration %u\n", 13178 in->args.vc.attr.group); 13179 else 13180 printf("cannot create indirect action list configuration %u\n", 13181 in->args.vc.attr.group); 13182 } 13183 13184 static const struct indlst_conf * 13185 indirect_action_list_conf_get(uint32_t conf_id) 13186 { 13187 const struct indlst_conf *conf; 13188 13189 SLIST_FOREACH(conf, &indlst_conf_head, next) { 13190 if (conf->id == conf_id) 13191 return conf; 13192 } 13193 return NULL; 13194 } 13195 13196 /** Dispatch parsed buffer to function calls. */ 13197 static void 13198 cmd_flow_parsed(const struct buffer *in) 13199 { 13200 switch (in->command) { 13201 case INFO: 13202 port_flow_get_info(in->port); 13203 break; 13204 case CONFIGURE: 13205 port_flow_configure(in->port, 13206 &in->args.configure.port_attr, 13207 in->args.configure.nb_queue, 13208 &in->args.configure.queue_attr); 13209 break; 13210 case PATTERN_TEMPLATE_CREATE: 13211 port_flow_pattern_template_create(in->port, 13212 in->args.vc.pat_templ_id, 13213 &((const struct rte_flow_pattern_template_attr) { 13214 .relaxed_matching = in->args.vc.attr.reserved, 13215 .ingress = in->args.vc.attr.ingress, 13216 .egress = in->args.vc.attr.egress, 13217 .transfer = in->args.vc.attr.transfer, 13218 }), 13219 in->args.vc.pattern); 13220 break; 13221 case PATTERN_TEMPLATE_DESTROY: 13222 port_flow_pattern_template_destroy(in->port, 13223 in->args.templ_destroy.template_id_n, 13224 in->args.templ_destroy.template_id); 13225 break; 13226 case ACTIONS_TEMPLATE_CREATE: 13227 port_flow_actions_template_create(in->port, 13228 in->args.vc.act_templ_id, 13229 &((const struct rte_flow_actions_template_attr) { 13230 .ingress = in->args.vc.attr.ingress, 13231 .egress = in->args.vc.attr.egress, 13232 .transfer = in->args.vc.attr.transfer, 13233 }), 13234 in->args.vc.actions, 13235 in->args.vc.masks); 13236 break; 13237 case ACTIONS_TEMPLATE_DESTROY: 13238 port_flow_actions_template_destroy(in->port, 13239 in->args.templ_destroy.template_id_n, 13240 in->args.templ_destroy.template_id); 13241 break; 13242 case TABLE_CREATE: 13243 port_flow_template_table_create(in->port, in->args.table.id, 13244 &in->args.table.attr, in->args.table.pat_templ_id_n, 13245 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 13246 in->args.table.act_templ_id); 13247 break; 13248 case TABLE_DESTROY: 13249 port_flow_template_table_destroy(in->port, 13250 in->args.table_destroy.table_id_n, 13251 in->args.table_destroy.table_id); 13252 break; 13253 case TABLE_RESIZE_COMPLETE: 13254 port_flow_template_table_resize_complete 13255 (in->port, in->args.table_destroy.table_id[0]); 13256 break; 13257 case GROUP_SET_MISS_ACTIONS: 13258 port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, 13259 in->args.vc.actions); 13260 break; 13261 case TABLE_RESIZE: 13262 port_flow_template_table_resize(in->port, in->args.table.id, 13263 in->args.table.attr.nb_flows); 13264 break; 13265 case QUEUE_CREATE: 13266 port_queue_flow_create(in->port, in->queue, in->postpone, 13267 in->args.vc.table_id, in->args.vc.rule_id, 13268 in->args.vc.pat_templ_id, in->args.vc.act_templ_id, 13269 in->args.vc.pattern, in->args.vc.actions); 13270 break; 13271 case QUEUE_DESTROY: 13272 port_queue_flow_destroy(in->port, in->queue, in->postpone, 13273 in->args.destroy.rule_n, 13274 in->args.destroy.rule); 13275 break; 13276 case QUEUE_FLOW_UPDATE_RESIZED: 13277 port_queue_flow_update_resized(in->port, in->queue, 13278 in->postpone, 13279 in->args.destroy.rule[0]); 13280 break; 13281 case QUEUE_UPDATE: 13282 port_queue_flow_update(in->port, in->queue, in->postpone, 13283 in->args.vc.rule_id, in->args.vc.act_templ_id, 13284 in->args.vc.actions); 13285 break; 13286 case PUSH: 13287 port_queue_flow_push(in->port, in->queue); 13288 break; 13289 case PULL: 13290 port_queue_flow_pull(in->port, in->queue); 13291 break; 13292 case HASH: 13293 if (!in->args.vc.encap_hash) 13294 port_flow_hash_calc(in->port, in->args.vc.table_id, 13295 in->args.vc.pat_templ_id, 13296 in->args.vc.pattern); 13297 else 13298 port_flow_hash_calc_encap(in->port, in->args.vc.field, 13299 in->args.vc.pattern); 13300 break; 13301 case QUEUE_AGED: 13302 port_queue_flow_aged(in->port, in->queue, 13303 in->args.aged.destroy); 13304 break; 13305 case QUEUE_INDIRECT_ACTION_CREATE: 13306 case QUEUE_INDIRECT_ACTION_LIST_CREATE: 13307 port_queue_action_handle_create( 13308 in->port, in->queue, in->postpone, 13309 in->args.vc.attr.group, 13310 in->command == QUEUE_INDIRECT_ACTION_LIST_CREATE, 13311 &((const struct rte_flow_indir_action_conf) { 13312 .ingress = in->args.vc.attr.ingress, 13313 .egress = in->args.vc.attr.egress, 13314 .transfer = in->args.vc.attr.transfer, 13315 }), 13316 in->args.vc.actions); 13317 break; 13318 case QUEUE_INDIRECT_ACTION_DESTROY: 13319 port_queue_action_handle_destroy(in->port, 13320 in->queue, in->postpone, 13321 in->args.ia_destroy.action_id_n, 13322 in->args.ia_destroy.action_id); 13323 break; 13324 case QUEUE_INDIRECT_ACTION_UPDATE: 13325 port_queue_action_handle_update(in->port, 13326 in->queue, in->postpone, 13327 in->args.vc.attr.group, 13328 in->args.vc.actions); 13329 break; 13330 case QUEUE_INDIRECT_ACTION_QUERY: 13331 port_queue_action_handle_query(in->port, 13332 in->queue, in->postpone, 13333 in->args.ia.action_id); 13334 break; 13335 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 13336 port_queue_action_handle_query_update(in->port, in->queue, 13337 in->postpone, 13338 in->args.ia.action_id, 13339 in->args.ia.qu_mode, 13340 in->args.vc.actions); 13341 break; 13342 case INDIRECT_ACTION_CREATE: 13343 case INDIRECT_ACTION_LIST_CREATE: 13344 port_action_handle_create( 13345 in->port, in->args.vc.attr.group, 13346 in->command == INDIRECT_ACTION_LIST_CREATE, 13347 &((const struct rte_flow_indir_action_conf) { 13348 .ingress = in->args.vc.attr.ingress, 13349 .egress = in->args.vc.attr.egress, 13350 .transfer = in->args.vc.attr.transfer, 13351 }), 13352 in->args.vc.actions); 13353 break; 13354 case INDIRECT_ACTION_FLOW_CONF_CREATE: 13355 indirect_action_flow_conf_create(in); 13356 break; 13357 case INDIRECT_ACTION_DESTROY: 13358 port_action_handle_destroy(in->port, 13359 in->args.ia_destroy.action_id_n, 13360 in->args.ia_destroy.action_id); 13361 break; 13362 case INDIRECT_ACTION_UPDATE: 13363 port_action_handle_update(in->port, in->args.vc.attr.group, 13364 in->args.vc.actions); 13365 break; 13366 case INDIRECT_ACTION_QUERY: 13367 port_action_handle_query(in->port, in->args.ia.action_id); 13368 break; 13369 case INDIRECT_ACTION_QUERY_UPDATE: 13370 port_action_handle_query_update(in->port, 13371 in->args.ia.action_id, 13372 in->args.ia.qu_mode, 13373 in->args.vc.actions); 13374 break; 13375 case VALIDATE: 13376 port_flow_validate(in->port, &in->args.vc.attr, 13377 in->args.vc.pattern, in->args.vc.actions, 13378 &in->args.vc.tunnel_ops); 13379 break; 13380 case CREATE: 13381 port_flow_create(in->port, &in->args.vc.attr, 13382 in->args.vc.pattern, in->args.vc.actions, 13383 &in->args.vc.tunnel_ops, in->args.vc.user_id); 13384 break; 13385 case DESTROY: 13386 port_flow_destroy(in->port, in->args.destroy.rule_n, 13387 in->args.destroy.rule, 13388 in->args.destroy.is_user_id); 13389 break; 13390 case UPDATE: 13391 port_flow_update(in->port, in->args.vc.rule_id, 13392 in->args.vc.actions, in->args.vc.user_id); 13393 break; 13394 case FLUSH: 13395 port_flow_flush(in->port); 13396 break; 13397 case DUMP_ONE: 13398 case DUMP_ALL: 13399 port_flow_dump(in->port, in->args.dump.mode, 13400 in->args.dump.rule, in->args.dump.file, 13401 in->args.dump.is_user_id); 13402 break; 13403 case QUERY: 13404 port_flow_query(in->port, in->args.query.rule, 13405 &in->args.query.action, 13406 in->args.query.is_user_id); 13407 break; 13408 case LIST: 13409 port_flow_list(in->port, in->args.list.group_n, 13410 in->args.list.group); 13411 break; 13412 case ISOLATE: 13413 port_flow_isolate(in->port, in->args.isolate.set); 13414 break; 13415 case AGED: 13416 port_flow_aged(in->port, in->args.aged.destroy); 13417 break; 13418 case TUNNEL_CREATE: 13419 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 13420 break; 13421 case TUNNEL_DESTROY: 13422 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 13423 break; 13424 case TUNNEL_LIST: 13425 port_flow_tunnel_list(in->port); 13426 break; 13427 case ACTION_POL_G: 13428 port_meter_policy_add(in->port, in->args.policy.policy_id, 13429 in->args.vc.actions); 13430 break; 13431 case FLEX_ITEM_CREATE: 13432 flex_item_create(in->port, in->args.flex.token, 13433 in->args.flex.filename); 13434 break; 13435 case FLEX_ITEM_DESTROY: 13436 flex_item_destroy(in->port, in->args.flex.token); 13437 break; 13438 default: 13439 break; 13440 } 13441 fflush(stdout); 13442 } 13443 13444 /** Token generator and output processing callback (cmdline API). */ 13445 static void 13446 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 13447 { 13448 if (cl == NULL) 13449 cmd_flow_tok(arg0, arg2); 13450 else 13451 cmd_flow_parsed(arg0); 13452 } 13453 13454 /** Global parser instance (cmdline API). */ 13455 cmdline_parse_inst_t cmd_flow = { 13456 .f = cmd_flow_cb, 13457 .data = NULL, /**< Unused. */ 13458 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 13459 .tokens = { 13460 NULL, 13461 }, /**< Tokens are returned by cmd_flow_tok(). */ 13462 }; 13463 13464 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 13465 13466 static void 13467 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 13468 { 13469 struct rte_ipv4_hdr *ipv4; 13470 struct rte_ether_hdr *eth; 13471 struct rte_ipv6_hdr *ipv6; 13472 struct rte_vxlan_hdr *vxlan; 13473 struct rte_vxlan_gpe_hdr *gpe; 13474 struct rte_flow_item_nvgre *nvgre; 13475 uint32_t ipv6_vtc_flow; 13476 13477 switch (item->type) { 13478 case RTE_FLOW_ITEM_TYPE_ETH: 13479 eth = (struct rte_ether_hdr *)buf; 13480 if (next_proto) 13481 eth->ether_type = rte_cpu_to_be_16(next_proto); 13482 break; 13483 case RTE_FLOW_ITEM_TYPE_IPV4: 13484 ipv4 = (struct rte_ipv4_hdr *)buf; 13485 if (!ipv4->version_ihl) 13486 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 13487 if (next_proto && ipv4->next_proto_id == 0) 13488 ipv4->next_proto_id = (uint8_t)next_proto; 13489 break; 13490 case RTE_FLOW_ITEM_TYPE_IPV6: 13491 ipv6 = (struct rte_ipv6_hdr *)buf; 13492 if (next_proto && ipv6->proto == 0) 13493 ipv6->proto = (uint8_t)next_proto; 13494 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 13495 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 13496 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 13497 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 13498 break; 13499 case RTE_FLOW_ITEM_TYPE_VXLAN: 13500 vxlan = (struct rte_vxlan_hdr *)buf; 13501 vxlan->vx_flags = 0x08; 13502 break; 13503 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13504 gpe = (struct rte_vxlan_gpe_hdr *)buf; 13505 gpe->vx_flags = 0x0C; 13506 break; 13507 case RTE_FLOW_ITEM_TYPE_NVGRE: 13508 nvgre = (struct rte_flow_item_nvgre *)buf; 13509 nvgre->protocol = rte_cpu_to_be_16(0x6558); 13510 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 13511 break; 13512 default: 13513 break; 13514 } 13515 } 13516 13517 /** Helper of get item's default mask. */ 13518 static const void * 13519 flow_item_default_mask(const struct rte_flow_item *item) 13520 { 13521 const void *mask = NULL; 13522 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 13523 static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { 13524 .hdr = { 13525 .next_hdr = 0xff, 13526 .type = 0xff, 13527 .segments_left = 0xff, 13528 }, 13529 }; 13530 13531 switch (item->type) { 13532 case RTE_FLOW_ITEM_TYPE_ANY: 13533 mask = &rte_flow_item_any_mask; 13534 break; 13535 case RTE_FLOW_ITEM_TYPE_PORT_ID: 13536 mask = &rte_flow_item_port_id_mask; 13537 break; 13538 case RTE_FLOW_ITEM_TYPE_RAW: 13539 mask = &rte_flow_item_raw_mask; 13540 break; 13541 case RTE_FLOW_ITEM_TYPE_ETH: 13542 mask = &rte_flow_item_eth_mask; 13543 break; 13544 case RTE_FLOW_ITEM_TYPE_VLAN: 13545 mask = &rte_flow_item_vlan_mask; 13546 break; 13547 case RTE_FLOW_ITEM_TYPE_IPV4: 13548 mask = &rte_flow_item_ipv4_mask; 13549 break; 13550 case RTE_FLOW_ITEM_TYPE_IPV6: 13551 mask = &rte_flow_item_ipv6_mask; 13552 break; 13553 case RTE_FLOW_ITEM_TYPE_ICMP: 13554 mask = &rte_flow_item_icmp_mask; 13555 break; 13556 case RTE_FLOW_ITEM_TYPE_UDP: 13557 mask = &rte_flow_item_udp_mask; 13558 break; 13559 case RTE_FLOW_ITEM_TYPE_TCP: 13560 mask = &rte_flow_item_tcp_mask; 13561 break; 13562 case RTE_FLOW_ITEM_TYPE_SCTP: 13563 mask = &rte_flow_item_sctp_mask; 13564 break; 13565 case RTE_FLOW_ITEM_TYPE_VXLAN: 13566 mask = &rte_flow_item_vxlan_mask; 13567 break; 13568 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13569 mask = &rte_flow_item_vxlan_gpe_mask; 13570 break; 13571 case RTE_FLOW_ITEM_TYPE_E_TAG: 13572 mask = &rte_flow_item_e_tag_mask; 13573 break; 13574 case RTE_FLOW_ITEM_TYPE_NVGRE: 13575 mask = &rte_flow_item_nvgre_mask; 13576 break; 13577 case RTE_FLOW_ITEM_TYPE_MPLS: 13578 mask = &rte_flow_item_mpls_mask; 13579 break; 13580 case RTE_FLOW_ITEM_TYPE_GRE: 13581 mask = &rte_flow_item_gre_mask; 13582 break; 13583 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13584 mask = &gre_key_default_mask; 13585 break; 13586 case RTE_FLOW_ITEM_TYPE_META: 13587 mask = &rte_flow_item_meta_mask; 13588 break; 13589 case RTE_FLOW_ITEM_TYPE_RANDOM: 13590 mask = &rte_flow_item_random_mask; 13591 break; 13592 case RTE_FLOW_ITEM_TYPE_FUZZY: 13593 mask = &rte_flow_item_fuzzy_mask; 13594 break; 13595 case RTE_FLOW_ITEM_TYPE_GTP: 13596 mask = &rte_flow_item_gtp_mask; 13597 break; 13598 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13599 mask = &rte_flow_item_gtp_psc_mask; 13600 break; 13601 case RTE_FLOW_ITEM_TYPE_GENEVE: 13602 mask = &rte_flow_item_geneve_mask; 13603 break; 13604 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13605 mask = &rte_flow_item_geneve_opt_mask; 13606 break; 13607 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 13608 mask = &rte_flow_item_pppoe_proto_id_mask; 13609 break; 13610 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13611 mask = &rte_flow_item_l2tpv3oip_mask; 13612 break; 13613 case RTE_FLOW_ITEM_TYPE_ESP: 13614 mask = &rte_flow_item_esp_mask; 13615 break; 13616 case RTE_FLOW_ITEM_TYPE_AH: 13617 mask = &rte_flow_item_ah_mask; 13618 break; 13619 case RTE_FLOW_ITEM_TYPE_PFCP: 13620 mask = &rte_flow_item_pfcp_mask; 13621 break; 13622 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 13623 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 13624 mask = &rte_flow_item_ethdev_mask; 13625 break; 13626 case RTE_FLOW_ITEM_TYPE_L2TPV2: 13627 mask = &rte_flow_item_l2tpv2_mask; 13628 break; 13629 case RTE_FLOW_ITEM_TYPE_PPP: 13630 mask = &rte_flow_item_ppp_mask; 13631 break; 13632 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 13633 mask = &rte_flow_item_meter_color_mask; 13634 break; 13635 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13636 mask = &ipv6_routing_ext_default_mask; 13637 break; 13638 case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: 13639 mask = &rte_flow_item_aggr_affinity_mask; 13640 break; 13641 case RTE_FLOW_ITEM_TYPE_TX_QUEUE: 13642 mask = &rte_flow_item_tx_queue_mask; 13643 break; 13644 case RTE_FLOW_ITEM_TYPE_IB_BTH: 13645 mask = &rte_flow_item_ib_bth_mask; 13646 break; 13647 case RTE_FLOW_ITEM_TYPE_PTYPE: 13648 mask = &rte_flow_item_ptype_mask; 13649 break; 13650 default: 13651 break; 13652 } 13653 return mask; 13654 } 13655 13656 /** Dispatch parsed buffer to function calls. */ 13657 static void 13658 cmd_set_ipv6_ext_parsed(const struct buffer *in) 13659 { 13660 uint32_t n = in->args.vc.pattern_n; 13661 int i = 0; 13662 struct rte_flow_item *item = NULL; 13663 size_t size = 0; 13664 uint8_t *data = NULL; 13665 uint8_t *type = NULL; 13666 size_t *total_size = NULL; 13667 uint16_t idx = in->port; /* We borrow port field as index */ 13668 struct rte_flow_item_ipv6_routing_ext *ext; 13669 const struct rte_flow_item_ipv6_ext *ipv6_ext; 13670 13671 RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || 13672 in->command == SET_IPV6_EXT_REMOVE); 13673 13674 if (in->command == SET_IPV6_EXT_REMOVE) { 13675 if (n != 1 || in->args.vc.pattern->type != 13676 RTE_FLOW_ITEM_TYPE_IPV6_EXT) { 13677 fprintf(stderr, "Error - Not supported item\n"); 13678 return; 13679 } 13680 type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; 13681 item = in->args.vc.pattern; 13682 ipv6_ext = item->spec; 13683 *type = ipv6_ext->next_hdr; 13684 return; 13685 } 13686 13687 total_size = &ipv6_ext_push_confs[idx].size; 13688 data = (uint8_t *)&ipv6_ext_push_confs[idx].data; 13689 type = (uint8_t *)&ipv6_ext_push_confs[idx].type; 13690 13691 *total_size = 0; 13692 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13693 for (i = n - 1 ; i >= 0; --i) { 13694 item = in->args.vc.pattern + i; 13695 switch (item->type) { 13696 case RTE_FLOW_ITEM_TYPE_IPV6_EXT: 13697 ipv6_ext = item->spec; 13698 *type = ipv6_ext->next_hdr; 13699 break; 13700 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13701 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13702 if (!ext->hdr.hdr_len) { 13703 size = sizeof(struct rte_ipv6_routing_ext) + 13704 (ext->hdr.segments_left << 4); 13705 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13706 /* Indicate no TLV once SRH. */ 13707 if (ext->hdr.type == 4) 13708 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13709 } else { 13710 size = sizeof(struct rte_ipv6_routing_ext) + 13711 (ext->hdr.hdr_len << 3); 13712 } 13713 *total_size += size; 13714 memcpy(data, ext, size); 13715 break; 13716 default: 13717 fprintf(stderr, "Error - Not supported item\n"); 13718 goto error; 13719 } 13720 } 13721 RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); 13722 return; 13723 error: 13724 *total_size = 0; 13725 memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); 13726 } 13727 13728 /** Dispatch parsed buffer to function calls. */ 13729 static void 13730 cmd_set_raw_parsed_sample(const struct buffer *in) 13731 { 13732 uint32_t n = in->args.vc.actions_n; 13733 uint32_t i = 0; 13734 struct rte_flow_action *action = NULL; 13735 struct rte_flow_action *data = NULL; 13736 const struct rte_flow_action_rss *rss = NULL; 13737 size_t size = 0; 13738 uint16_t idx = in->port; /* We borrow port field as index */ 13739 uint32_t max_size = sizeof(struct rte_flow_action) * 13740 ACTION_SAMPLE_ACTIONS_NUM; 13741 13742 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 13743 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 13744 memset(data, 0x00, max_size); 13745 for (; i <= n - 1; i++) { 13746 action = in->args.vc.actions + i; 13747 if (action->type == RTE_FLOW_ACTION_TYPE_END) 13748 break; 13749 switch (action->type) { 13750 case RTE_FLOW_ACTION_TYPE_MARK: 13751 size = sizeof(struct rte_flow_action_mark); 13752 rte_memcpy(&sample_mark[idx], 13753 (const void *)action->conf, size); 13754 action->conf = &sample_mark[idx]; 13755 break; 13756 case RTE_FLOW_ACTION_TYPE_COUNT: 13757 size = sizeof(struct rte_flow_action_count); 13758 rte_memcpy(&sample_count[idx], 13759 (const void *)action->conf, size); 13760 action->conf = &sample_count[idx]; 13761 break; 13762 case RTE_FLOW_ACTION_TYPE_QUEUE: 13763 size = sizeof(struct rte_flow_action_queue); 13764 rte_memcpy(&sample_queue[idx], 13765 (const void *)action->conf, size); 13766 action->conf = &sample_queue[idx]; 13767 break; 13768 case RTE_FLOW_ACTION_TYPE_RSS: 13769 size = sizeof(struct rte_flow_action_rss); 13770 rss = action->conf; 13771 rte_memcpy(&sample_rss_data[idx].conf, 13772 (const void *)rss, size); 13773 if (rss->key_len && rss->key) { 13774 sample_rss_data[idx].conf.key = 13775 sample_rss_data[idx].key; 13776 rte_memcpy((void *)((uintptr_t) 13777 sample_rss_data[idx].conf.key), 13778 (const void *)rss->key, 13779 sizeof(uint8_t) * rss->key_len); 13780 } 13781 if (rss->queue_num && rss->queue) { 13782 sample_rss_data[idx].conf.queue = 13783 sample_rss_data[idx].queue; 13784 rte_memcpy((void *)((uintptr_t) 13785 sample_rss_data[idx].conf.queue), 13786 (const void *)rss->queue, 13787 sizeof(uint16_t) * rss->queue_num); 13788 } 13789 action->conf = &sample_rss_data[idx].conf; 13790 break; 13791 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 13792 size = sizeof(struct rte_flow_action_raw_encap); 13793 rte_memcpy(&sample_encap[idx], 13794 (const void *)action->conf, size); 13795 action->conf = &sample_encap[idx]; 13796 break; 13797 case RTE_FLOW_ACTION_TYPE_PORT_ID: 13798 size = sizeof(struct rte_flow_action_port_id); 13799 rte_memcpy(&sample_port_id[idx], 13800 (const void *)action->conf, size); 13801 action->conf = &sample_port_id[idx]; 13802 break; 13803 case RTE_FLOW_ACTION_TYPE_PF: 13804 break; 13805 case RTE_FLOW_ACTION_TYPE_VF: 13806 size = sizeof(struct rte_flow_action_vf); 13807 rte_memcpy(&sample_vf[idx], 13808 (const void *)action->conf, size); 13809 action->conf = &sample_vf[idx]; 13810 break; 13811 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 13812 size = sizeof(struct rte_flow_action_vxlan_encap); 13813 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 13814 action->conf = &sample_vxlan_encap[idx].conf; 13815 break; 13816 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 13817 size = sizeof(struct rte_flow_action_nvgre_encap); 13818 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 13819 action->conf = &sample_nvgre_encap[idx]; 13820 break; 13821 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 13822 size = sizeof(struct rte_flow_action_ethdev); 13823 rte_memcpy(&sample_port_representor[idx], 13824 (const void *)action->conf, size); 13825 action->conf = &sample_port_representor[idx]; 13826 break; 13827 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 13828 size = sizeof(struct rte_flow_action_ethdev); 13829 rte_memcpy(&sample_represented_port[idx], 13830 (const void *)action->conf, size); 13831 action->conf = &sample_represented_port[idx]; 13832 break; 13833 default: 13834 fprintf(stderr, "Error - Not supported action\n"); 13835 return; 13836 } 13837 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 13838 data++; 13839 } 13840 } 13841 13842 /** Dispatch parsed buffer to function calls. */ 13843 static void 13844 cmd_set_raw_parsed(const struct buffer *in) 13845 { 13846 uint32_t n = in->args.vc.pattern_n; 13847 int i = 0; 13848 struct rte_flow_item *item = NULL; 13849 size_t size = 0; 13850 uint8_t *data = NULL; 13851 uint8_t *data_tail = NULL; 13852 size_t *total_size = NULL; 13853 uint16_t upper_layer = 0; 13854 uint16_t proto = 0; 13855 uint16_t idx = in->port; /* We borrow port field as index */ 13856 int gtp_psc = -1; /* GTP PSC option index. */ 13857 const void *src_spec; 13858 13859 if (in->command == SET_SAMPLE_ACTIONS) 13860 return cmd_set_raw_parsed_sample(in); 13861 else if (in->command == SET_IPV6_EXT_PUSH || 13862 in->command == SET_IPV6_EXT_REMOVE) 13863 return cmd_set_ipv6_ext_parsed(in); 13864 RTE_ASSERT(in->command == SET_RAW_ENCAP || 13865 in->command == SET_RAW_DECAP); 13866 if (in->command == SET_RAW_ENCAP) { 13867 total_size = &raw_encap_confs[idx].size; 13868 data = (uint8_t *)&raw_encap_confs[idx].data; 13869 } else { 13870 total_size = &raw_decap_confs[idx].size; 13871 data = (uint8_t *)&raw_decap_confs[idx].data; 13872 } 13873 *total_size = 0; 13874 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13875 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 13876 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 13877 for (i = n - 1 ; i >= 0; --i) { 13878 const struct rte_flow_item_gtp *gtp; 13879 const struct rte_flow_item_geneve_opt *opt; 13880 struct rte_flow_item_ipv6_routing_ext *ext; 13881 13882 item = in->args.vc.pattern + i; 13883 if (item->spec == NULL) 13884 item->spec = flow_item_default_mask(item); 13885 src_spec = item->spec; 13886 switch (item->type) { 13887 case RTE_FLOW_ITEM_TYPE_ETH: 13888 size = sizeof(struct rte_ether_hdr); 13889 break; 13890 case RTE_FLOW_ITEM_TYPE_VLAN: 13891 size = sizeof(struct rte_vlan_hdr); 13892 proto = RTE_ETHER_TYPE_VLAN; 13893 break; 13894 case RTE_FLOW_ITEM_TYPE_IPV4: 13895 size = sizeof(struct rte_ipv4_hdr); 13896 proto = RTE_ETHER_TYPE_IPV4; 13897 break; 13898 case RTE_FLOW_ITEM_TYPE_IPV6: 13899 size = sizeof(struct rte_ipv6_hdr); 13900 proto = RTE_ETHER_TYPE_IPV6; 13901 break; 13902 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13903 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13904 if (!ext->hdr.hdr_len) { 13905 size = sizeof(struct rte_ipv6_routing_ext) + 13906 (ext->hdr.segments_left << 4); 13907 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13908 /* SRv6 without TLV. */ 13909 if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) 13910 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13911 } else { 13912 size = sizeof(struct rte_ipv6_routing_ext) + 13913 (ext->hdr.hdr_len << 3); 13914 } 13915 proto = IPPROTO_ROUTING; 13916 break; 13917 case RTE_FLOW_ITEM_TYPE_UDP: 13918 size = sizeof(struct rte_udp_hdr); 13919 proto = 0x11; 13920 break; 13921 case RTE_FLOW_ITEM_TYPE_TCP: 13922 size = sizeof(struct rte_tcp_hdr); 13923 proto = 0x06; 13924 break; 13925 case RTE_FLOW_ITEM_TYPE_VXLAN: 13926 size = sizeof(struct rte_vxlan_hdr); 13927 break; 13928 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13929 size = sizeof(struct rte_vxlan_gpe_hdr); 13930 break; 13931 case RTE_FLOW_ITEM_TYPE_GRE: 13932 size = sizeof(struct rte_gre_hdr); 13933 proto = 0x2F; 13934 break; 13935 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13936 size = sizeof(rte_be32_t); 13937 proto = 0x0; 13938 break; 13939 case RTE_FLOW_ITEM_TYPE_MPLS: 13940 size = sizeof(struct rte_mpls_hdr); 13941 proto = 0x0; 13942 break; 13943 case RTE_FLOW_ITEM_TYPE_NVGRE: 13944 size = sizeof(struct rte_flow_item_nvgre); 13945 proto = 0x2F; 13946 break; 13947 case RTE_FLOW_ITEM_TYPE_GENEVE: 13948 size = sizeof(struct rte_geneve_hdr); 13949 break; 13950 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13951 opt = (const struct rte_flow_item_geneve_opt *) 13952 item->spec; 13953 size = offsetof(struct rte_flow_item_geneve_opt, 13954 option_len) + sizeof(uint8_t); 13955 if (opt->option_len && opt->data) { 13956 *total_size += opt->option_len * 13957 sizeof(uint32_t); 13958 rte_memcpy(data_tail - (*total_size), 13959 opt->data, 13960 opt->option_len * sizeof(uint32_t)); 13961 } 13962 break; 13963 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13964 size = sizeof(rte_be32_t); 13965 proto = 0x73; 13966 break; 13967 case RTE_FLOW_ITEM_TYPE_ESP: 13968 size = sizeof(struct rte_esp_hdr); 13969 proto = 0x32; 13970 break; 13971 case RTE_FLOW_ITEM_TYPE_AH: 13972 size = sizeof(struct rte_flow_item_ah); 13973 proto = 0x33; 13974 break; 13975 case RTE_FLOW_ITEM_TYPE_GTP: 13976 if (gtp_psc < 0) { 13977 size = sizeof(struct rte_gtp_hdr); 13978 break; 13979 } 13980 if (gtp_psc != i + 1) { 13981 fprintf(stderr, 13982 "Error - GTP PSC does not follow GTP\n"); 13983 goto error; 13984 } 13985 gtp = item->spec; 13986 if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { 13987 /* Only E flag should be set. */ 13988 fprintf(stderr, 13989 "Error - GTP unsupported flags\n"); 13990 goto error; 13991 } else { 13992 struct rte_gtp_hdr_ext_word ext_word = { 13993 .next_ext = 0x85 13994 }; 13995 13996 /* We have to add GTP header extra word. */ 13997 *total_size += sizeof(ext_word); 13998 rte_memcpy(data_tail - (*total_size), 13999 &ext_word, sizeof(ext_word)); 14000 } 14001 size = sizeof(struct rte_gtp_hdr); 14002 break; 14003 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 14004 if (gtp_psc >= 0) { 14005 fprintf(stderr, 14006 "Error - Multiple GTP PSC items\n"); 14007 goto error; 14008 } else { 14009 const struct rte_flow_item_gtp_psc 14010 *opt = item->spec; 14011 struct rte_gtp_psc_generic_hdr *hdr; 14012 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 14013 sizeof(int32_t)); 14014 14015 *total_size += hdr_size; 14016 hdr = (typeof(hdr))(data_tail - (*total_size)); 14017 memset(hdr, 0, hdr_size); 14018 *hdr = opt->hdr; 14019 hdr->ext_hdr_len = 1; 14020 gtp_psc = i; 14021 size = 0; 14022 } 14023 break; 14024 case RTE_FLOW_ITEM_TYPE_PFCP: 14025 size = sizeof(struct rte_flow_item_pfcp); 14026 break; 14027 case RTE_FLOW_ITEM_TYPE_FLEX: 14028 if (item->spec != NULL) { 14029 size = ((const struct rte_flow_item_flex *)item->spec)->length; 14030 src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; 14031 } else { 14032 size = 0; 14033 src_spec = NULL; 14034 } 14035 break; 14036 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 14037 size = 0; 14038 if (item->spec) { 14039 const struct rte_flow_item_gre_opt 14040 *opt = item->spec; 14041 if (opt->checksum_rsvd.checksum) { 14042 *total_size += 14043 sizeof(opt->checksum_rsvd); 14044 rte_memcpy(data_tail - (*total_size), 14045 &opt->checksum_rsvd, 14046 sizeof(opt->checksum_rsvd)); 14047 } 14048 if (opt->key.key) { 14049 *total_size += sizeof(opt->key.key); 14050 rte_memcpy(data_tail - (*total_size), 14051 &opt->key.key, 14052 sizeof(opt->key.key)); 14053 } 14054 if (opt->sequence.sequence) { 14055 *total_size += sizeof(opt->sequence.sequence); 14056 rte_memcpy(data_tail - (*total_size), 14057 &opt->sequence.sequence, 14058 sizeof(opt->sequence.sequence)); 14059 } 14060 } 14061 proto = 0x2F; 14062 break; 14063 default: 14064 fprintf(stderr, "Error - Not supported item\n"); 14065 goto error; 14066 } 14067 if (size) { 14068 *total_size += size; 14069 rte_memcpy(data_tail - (*total_size), src_spec, size); 14070 /* update some fields which cannot be set by cmdline */ 14071 update_fields((data_tail - (*total_size)), item, 14072 upper_layer); 14073 upper_layer = proto; 14074 } 14075 } 14076 if (verbose_level & 0x1) 14077 printf("total data size is %zu\n", (*total_size)); 14078 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 14079 memmove(data, (data_tail - (*total_size)), *total_size); 14080 return; 14081 14082 error: 14083 *total_size = 0; 14084 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 14085 } 14086 14087 /** Populate help strings for current token (cmdline API). */ 14088 static int 14089 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 14090 unsigned int size) 14091 { 14092 struct context *ctx = &cmd_flow_context; 14093 const struct token *token = &token_list[ctx->prev]; 14094 14095 (void)hdr; 14096 if (!size) 14097 return -1; 14098 /* Set token type and update global help with details. */ 14099 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 14100 if (token->help) 14101 cmd_set_raw.help_str = token->help; 14102 else 14103 cmd_set_raw.help_str = token->name; 14104 return 0; 14105 } 14106 14107 /** Token definition template (cmdline API). */ 14108 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 14109 .ops = &(struct cmdline_token_ops){ 14110 .parse = cmd_flow_parse, 14111 .complete_get_nb = cmd_flow_complete_get_nb, 14112 .complete_get_elt = cmd_flow_complete_get_elt, 14113 .get_help = cmd_set_raw_get_help, 14114 }, 14115 .offset = 0, 14116 }; 14117 14118 /** Populate the next dynamic token. */ 14119 static void 14120 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 14121 cmdline_parse_token_hdr_t **hdr_inst) 14122 { 14123 struct context *ctx = &cmd_flow_context; 14124 14125 /* Always reinitialize context before requesting the first token. */ 14126 if (!(hdr_inst - cmd_set_raw.tokens)) { 14127 cmd_flow_context_init(ctx); 14128 ctx->curr = START_SET; 14129 } 14130 /* Return NULL when no more tokens are expected. */ 14131 if (!ctx->next_num && (ctx->curr != START_SET)) { 14132 *hdr = NULL; 14133 return; 14134 } 14135 /* Determine if command should end here. */ 14136 if (ctx->eol && ctx->last && ctx->next_num) { 14137 const enum index *list = ctx->next[ctx->next_num - 1]; 14138 int i; 14139 14140 for (i = 0; list[i]; ++i) { 14141 if (list[i] != END) 14142 continue; 14143 *hdr = NULL; 14144 return; 14145 } 14146 } 14147 *hdr = &cmd_set_raw_token_hdr; 14148 } 14149 14150 /** Token generator and output processing callback (cmdline API). */ 14151 static void 14152 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 14153 { 14154 if (cl == NULL) 14155 cmd_set_raw_tok(arg0, arg2); 14156 else 14157 cmd_set_raw_parsed(arg0); 14158 } 14159 14160 /** Global parser instance (cmdline API). */ 14161 cmdline_parse_inst_t cmd_set_raw = { 14162 .f = cmd_set_raw_cb, 14163 .data = NULL, /**< Unused. */ 14164 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 14165 .tokens = { 14166 NULL, 14167 }, /**< Tokens are returned by cmd_flow_tok(). */ 14168 }; 14169 14170 /* *** display raw_encap/raw_decap buf */ 14171 struct cmd_show_set_raw_result { 14172 cmdline_fixed_string_t cmd_show; 14173 cmdline_fixed_string_t cmd_what; 14174 cmdline_fixed_string_t cmd_all; 14175 uint16_t cmd_index; 14176 }; 14177 14178 static void 14179 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 14180 { 14181 struct cmd_show_set_raw_result *res = parsed_result; 14182 uint16_t index = res->cmd_index; 14183 uint8_t all = 0; 14184 uint8_t *raw_data = NULL; 14185 size_t raw_size = 0; 14186 char title[16] = {0}; 14187 14188 RTE_SET_USED(cl); 14189 RTE_SET_USED(data); 14190 if (!strcmp(res->cmd_all, "all")) { 14191 all = 1; 14192 index = 0; 14193 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 14194 fprintf(stderr, "index should be 0-%u\n", 14195 RAW_ENCAP_CONFS_MAX_NUM - 1); 14196 return; 14197 } 14198 do { 14199 if (!strcmp(res->cmd_what, "raw_encap")) { 14200 raw_data = (uint8_t *)&raw_encap_confs[index].data; 14201 raw_size = raw_encap_confs[index].size; 14202 snprintf(title, 16, "\nindex: %u", index); 14203 rte_hexdump(stdout, title, raw_data, raw_size); 14204 } else { 14205 raw_data = (uint8_t *)&raw_decap_confs[index].data; 14206 raw_size = raw_decap_confs[index].size; 14207 snprintf(title, 16, "\nindex: %u", index); 14208 rte_hexdump(stdout, title, raw_data, raw_size); 14209 } 14210 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 14211 } 14212 14213 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 14214 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14215 cmd_show, "show"); 14216 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 14217 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14218 cmd_what, "raw_encap#raw_decap"); 14219 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 14220 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 14221 cmd_index, RTE_UINT16); 14222 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 14223 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14224 cmd_all, "all"); 14225 cmdline_parse_inst_t cmd_show_set_raw = { 14226 .f = cmd_show_set_raw_parsed, 14227 .data = NULL, 14228 .help_str = "show <raw_encap|raw_decap> <index>", 14229 .tokens = { 14230 (void *)&cmd_show_set_raw_cmd_show, 14231 (void *)&cmd_show_set_raw_cmd_what, 14232 (void *)&cmd_show_set_raw_cmd_index, 14233 NULL, 14234 }, 14235 }; 14236 cmdline_parse_inst_t cmd_show_set_raw_all = { 14237 .f = cmd_show_set_raw_parsed, 14238 .data = NULL, 14239 .help_str = "show <raw_encap|raw_decap> all", 14240 .tokens = { 14241 (void *)&cmd_show_set_raw_cmd_show, 14242 (void *)&cmd_show_set_raw_cmd_what, 14243 (void *)&cmd_show_set_raw_cmd_all, 14244 NULL, 14245 }, 14246 }; 14247