1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2016 6WIND S.A. 3 * Copyright 2016 Mellanox Technologies, Ltd 4 */ 5 6 #include <stddef.h> 7 #include <stdint.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <inttypes.h> 11 #include <errno.h> 12 #include <ctype.h> 13 #include <string.h> 14 15 #include <rte_string_fns.h> 16 #include <rte_common.h> 17 #include <rte_ethdev.h> 18 #include <rte_byteorder.h> 19 #include <cmdline_parse.h> 20 #include <cmdline_parse_etheraddr.h> 21 #include <cmdline_parse_string.h> 22 #include <cmdline_parse_num.h> 23 #include <rte_flow.h> 24 #include <rte_hexdump.h> 25 #include <rte_vxlan.h> 26 #include <rte_gre.h> 27 #include <rte_mpls.h> 28 #include <rte_gtp.h> 29 #include <rte_geneve.h> 30 31 #include "testpmd.h" 32 33 /** Parser token indices. */ 34 enum index { 35 /* Special tokens. */ 36 ZERO = 0, 37 END, 38 START_SET, 39 END_SET, 40 41 /* Common tokens. */ 42 COMMON_INTEGER, 43 COMMON_UNSIGNED, 44 COMMON_PREFIX, 45 COMMON_BOOLEAN, 46 COMMON_STRING, 47 COMMON_HEX, 48 COMMON_FILE_PATH, 49 COMMON_MAC_ADDR, 50 COMMON_IPV4_ADDR, 51 COMMON_IPV6_ADDR, 52 COMMON_RULE_ID, 53 COMMON_PORT_ID, 54 COMMON_GROUP_ID, 55 COMMON_PRIORITY_LEVEL, 56 COMMON_INDIRECT_ACTION_ID, 57 COMMON_PROFILE_ID, 58 COMMON_POLICY_ID, 59 COMMON_FLEX_HANDLE, 60 COMMON_FLEX_TOKEN, 61 COMMON_PATTERN_TEMPLATE_ID, 62 COMMON_ACTIONS_TEMPLATE_ID, 63 COMMON_TABLE_ID, 64 COMMON_QUEUE_ID, 65 66 /* TOP-level command. */ 67 ADD, 68 69 /* Top-level command. */ 70 SET, 71 /* Sub-leve commands. */ 72 SET_RAW_ENCAP, 73 SET_RAW_DECAP, 74 SET_RAW_INDEX, 75 SET_SAMPLE_ACTIONS, 76 SET_SAMPLE_INDEX, 77 SET_IPV6_EXT_REMOVE, 78 SET_IPV6_EXT_PUSH, 79 SET_IPV6_EXT_INDEX, 80 81 /* Top-level command. */ 82 FLOW, 83 /* Sub-level commands. */ 84 INFO, 85 CONFIGURE, 86 PATTERN_TEMPLATE, 87 ACTIONS_TEMPLATE, 88 TABLE, 89 FLOW_GROUP, 90 INDIRECT_ACTION, 91 VALIDATE, 92 CREATE, 93 DESTROY, 94 UPDATE, 95 FLUSH, 96 DUMP, 97 QUERY, 98 LIST, 99 AGED, 100 ISOLATE, 101 TUNNEL, 102 FLEX, 103 QUEUE, 104 PUSH, 105 PULL, 106 HASH, 107 108 /* Flex arguments */ 109 FLEX_ITEM_INIT, 110 FLEX_ITEM_CREATE, 111 FLEX_ITEM_DESTROY, 112 113 /* Pattern template arguments. */ 114 PATTERN_TEMPLATE_CREATE, 115 PATTERN_TEMPLATE_DESTROY, 116 PATTERN_TEMPLATE_CREATE_ID, 117 PATTERN_TEMPLATE_DESTROY_ID, 118 PATTERN_TEMPLATE_RELAXED_MATCHING, 119 PATTERN_TEMPLATE_INGRESS, 120 PATTERN_TEMPLATE_EGRESS, 121 PATTERN_TEMPLATE_TRANSFER, 122 PATTERN_TEMPLATE_SPEC, 123 124 /* Actions template arguments. */ 125 ACTIONS_TEMPLATE_CREATE, 126 ACTIONS_TEMPLATE_DESTROY, 127 ACTIONS_TEMPLATE_CREATE_ID, 128 ACTIONS_TEMPLATE_DESTROY_ID, 129 ACTIONS_TEMPLATE_INGRESS, 130 ACTIONS_TEMPLATE_EGRESS, 131 ACTIONS_TEMPLATE_TRANSFER, 132 ACTIONS_TEMPLATE_SPEC, 133 ACTIONS_TEMPLATE_MASK, 134 135 /* Queue arguments. */ 136 QUEUE_CREATE, 137 QUEUE_DESTROY, 138 QUEUE_FLOW_UPDATE_RESIZED, 139 QUEUE_UPDATE, 140 QUEUE_AGED, 141 QUEUE_INDIRECT_ACTION, 142 143 /* Queue create arguments. */ 144 QUEUE_CREATE_POSTPONE, 145 QUEUE_TEMPLATE_TABLE, 146 QUEUE_PATTERN_TEMPLATE, 147 QUEUE_ACTIONS_TEMPLATE, 148 QUEUE_RULE_ID, 149 150 /* Queue destroy arguments. */ 151 QUEUE_DESTROY_ID, 152 QUEUE_DESTROY_POSTPONE, 153 154 /* Queue update arguments. */ 155 QUEUE_UPDATE_ID, 156 157 /* Queue indirect action arguments */ 158 QUEUE_INDIRECT_ACTION_CREATE, 159 QUEUE_INDIRECT_ACTION_LIST_CREATE, 160 QUEUE_INDIRECT_ACTION_UPDATE, 161 QUEUE_INDIRECT_ACTION_DESTROY, 162 QUEUE_INDIRECT_ACTION_QUERY, 163 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 164 165 /* Queue indirect action create arguments */ 166 QUEUE_INDIRECT_ACTION_CREATE_ID, 167 QUEUE_INDIRECT_ACTION_INGRESS, 168 QUEUE_INDIRECT_ACTION_EGRESS, 169 QUEUE_INDIRECT_ACTION_TRANSFER, 170 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 171 QUEUE_INDIRECT_ACTION_SPEC, 172 QUEUE_INDIRECT_ACTION_LIST, 173 174 /* Queue indirect action update arguments */ 175 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 176 177 /* Queue indirect action destroy arguments */ 178 QUEUE_INDIRECT_ACTION_DESTROY_ID, 179 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 180 181 /* Queue indirect action query arguments */ 182 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 183 184 /* Queue indirect action query_update arguments */ 185 QUEUE_INDIRECT_ACTION_QU_MODE, 186 187 /* Push arguments. */ 188 PUSH_QUEUE, 189 190 /* Pull arguments. */ 191 PULL_QUEUE, 192 193 /* Table arguments. */ 194 TABLE_CREATE, 195 TABLE_DESTROY, 196 TABLE_RESIZE, 197 TABLE_RESIZE_COMPLETE, 198 TABLE_CREATE_ID, 199 TABLE_DESTROY_ID, 200 TABLE_RESIZE_ID, 201 TABLE_RESIZE_RULES_NUMBER, 202 TABLE_INSERTION_TYPE, 203 TABLE_INSERTION_TYPE_NAME, 204 TABLE_HASH_FUNC, 205 TABLE_HASH_FUNC_NAME, 206 TABLE_GROUP, 207 TABLE_PRIORITY, 208 TABLE_INGRESS, 209 TABLE_EGRESS, 210 TABLE_TRANSFER, 211 TABLE_TRANSFER_WIRE_ORIG, 212 TABLE_TRANSFER_VPORT_ORIG, 213 TABLE_RESIZABLE, 214 TABLE_RULES_NUMBER, 215 TABLE_PATTERN_TEMPLATE, 216 TABLE_ACTIONS_TEMPLATE, 217 218 /* Group arguments */ 219 GROUP_ID, 220 GROUP_INGRESS, 221 GROUP_EGRESS, 222 GROUP_TRANSFER, 223 GROUP_SET_MISS_ACTIONS, 224 225 /* Hash calculation arguments. */ 226 HASH_CALC_TABLE, 227 HASH_CALC_PATTERN_INDEX, 228 HASH_CALC_PATTERN, 229 HASH_CALC_ENCAP, 230 HASH_CALC_DEST, 231 ENCAP_HASH_FIELD_SRC_PORT, 232 ENCAP_HASH_FIELD_GRE_FLOW_ID, 233 234 /* Tunnel arguments. */ 235 TUNNEL_CREATE, 236 TUNNEL_CREATE_TYPE, 237 TUNNEL_LIST, 238 TUNNEL_DESTROY, 239 TUNNEL_DESTROY_ID, 240 241 /* Destroy arguments. */ 242 DESTROY_RULE, 243 DESTROY_IS_USER_ID, 244 245 /* Query arguments. */ 246 QUERY_ACTION, 247 QUERY_IS_USER_ID, 248 249 /* List arguments. */ 250 LIST_GROUP, 251 252 /* Destroy aged flow arguments. */ 253 AGED_DESTROY, 254 255 /* Validate/create arguments. */ 256 VC_GROUP, 257 VC_PRIORITY, 258 VC_INGRESS, 259 VC_EGRESS, 260 VC_TRANSFER, 261 VC_TUNNEL_SET, 262 VC_TUNNEL_MATCH, 263 VC_USER_ID, 264 VC_IS_USER_ID, 265 266 /* Dump arguments */ 267 DUMP_ALL, 268 DUMP_ONE, 269 DUMP_IS_USER_ID, 270 271 /* Configure arguments */ 272 CONFIG_QUEUES_NUMBER, 273 CONFIG_QUEUES_SIZE, 274 CONFIG_COUNTERS_NUMBER, 275 CONFIG_AGING_OBJECTS_NUMBER, 276 CONFIG_METERS_NUMBER, 277 CONFIG_CONN_TRACK_NUMBER, 278 CONFIG_QUOTAS_NUMBER, 279 CONFIG_FLAGS, 280 CONFIG_HOST_PORT, 281 282 /* Indirect action arguments */ 283 INDIRECT_ACTION_CREATE, 284 INDIRECT_ACTION_LIST_CREATE, 285 INDIRECT_ACTION_FLOW_CONF_CREATE, 286 INDIRECT_ACTION_UPDATE, 287 INDIRECT_ACTION_DESTROY, 288 INDIRECT_ACTION_QUERY, 289 INDIRECT_ACTION_QUERY_UPDATE, 290 291 /* Indirect action create arguments */ 292 INDIRECT_ACTION_CREATE_ID, 293 INDIRECT_ACTION_INGRESS, 294 INDIRECT_ACTION_EGRESS, 295 INDIRECT_ACTION_TRANSFER, 296 INDIRECT_ACTION_SPEC, 297 INDIRECT_ACTION_LIST, 298 INDIRECT_ACTION_FLOW_CONF, 299 300 /* Indirect action destroy arguments */ 301 INDIRECT_ACTION_DESTROY_ID, 302 303 /* Indirect action query-and-update arguments */ 304 INDIRECT_ACTION_QU_MODE, 305 INDIRECT_ACTION_QU_MODE_NAME, 306 307 /* Validate/create pattern. */ 308 ITEM_PATTERN, 309 ITEM_PARAM_IS, 310 ITEM_PARAM_SPEC, 311 ITEM_PARAM_LAST, 312 ITEM_PARAM_MASK, 313 ITEM_PARAM_PREFIX, 314 ITEM_NEXT, 315 ITEM_END, 316 ITEM_VOID, 317 ITEM_INVERT, 318 ITEM_ANY, 319 ITEM_ANY_NUM, 320 ITEM_PORT_ID, 321 ITEM_PORT_ID_ID, 322 ITEM_MARK, 323 ITEM_MARK_ID, 324 ITEM_RAW, 325 ITEM_RAW_RELATIVE, 326 ITEM_RAW_SEARCH, 327 ITEM_RAW_OFFSET, 328 ITEM_RAW_LIMIT, 329 ITEM_RAW_PATTERN, 330 ITEM_RAW_PATTERN_HEX, 331 ITEM_ETH, 332 ITEM_ETH_DST, 333 ITEM_ETH_SRC, 334 ITEM_ETH_TYPE, 335 ITEM_ETH_HAS_VLAN, 336 ITEM_VLAN, 337 ITEM_VLAN_TCI, 338 ITEM_VLAN_PCP, 339 ITEM_VLAN_DEI, 340 ITEM_VLAN_VID, 341 ITEM_VLAN_INNER_TYPE, 342 ITEM_VLAN_HAS_MORE_VLAN, 343 ITEM_IPV4, 344 ITEM_IPV4_VER_IHL, 345 ITEM_IPV4_TOS, 346 ITEM_IPV4_LENGTH, 347 ITEM_IPV4_ID, 348 ITEM_IPV4_FRAGMENT_OFFSET, 349 ITEM_IPV4_TTL, 350 ITEM_IPV4_PROTO, 351 ITEM_IPV4_SRC, 352 ITEM_IPV4_DST, 353 ITEM_IPV6, 354 ITEM_IPV6_TC, 355 ITEM_IPV6_FLOW, 356 ITEM_IPV6_LEN, 357 ITEM_IPV6_PROTO, 358 ITEM_IPV6_HOP, 359 ITEM_IPV6_SRC, 360 ITEM_IPV6_DST, 361 ITEM_IPV6_HAS_FRAG_EXT, 362 ITEM_IPV6_ROUTING_EXT, 363 ITEM_IPV6_ROUTING_EXT_TYPE, 364 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 365 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 366 ITEM_ICMP, 367 ITEM_ICMP_TYPE, 368 ITEM_ICMP_CODE, 369 ITEM_ICMP_IDENT, 370 ITEM_ICMP_SEQ, 371 ITEM_UDP, 372 ITEM_UDP_SRC, 373 ITEM_UDP_DST, 374 ITEM_TCP, 375 ITEM_TCP_SRC, 376 ITEM_TCP_DST, 377 ITEM_TCP_FLAGS, 378 ITEM_SCTP, 379 ITEM_SCTP_SRC, 380 ITEM_SCTP_DST, 381 ITEM_SCTP_TAG, 382 ITEM_SCTP_CKSUM, 383 ITEM_VXLAN, 384 ITEM_VXLAN_VNI, 385 ITEM_VXLAN_LAST_RSVD, 386 ITEM_E_TAG, 387 ITEM_E_TAG_GRP_ECID_B, 388 ITEM_NVGRE, 389 ITEM_NVGRE_TNI, 390 ITEM_MPLS, 391 ITEM_MPLS_LABEL, 392 ITEM_MPLS_TC, 393 ITEM_MPLS_S, 394 ITEM_MPLS_TTL, 395 ITEM_GRE, 396 ITEM_GRE_PROTO, 397 ITEM_GRE_C_RSVD0_VER, 398 ITEM_GRE_C_BIT, 399 ITEM_GRE_K_BIT, 400 ITEM_GRE_S_BIT, 401 ITEM_FUZZY, 402 ITEM_FUZZY_THRESH, 403 ITEM_GTP, 404 ITEM_GTP_FLAGS, 405 ITEM_GTP_MSG_TYPE, 406 ITEM_GTP_TEID, 407 ITEM_GTPC, 408 ITEM_GTPU, 409 ITEM_GENEVE, 410 ITEM_GENEVE_VNI, 411 ITEM_GENEVE_PROTO, 412 ITEM_GENEVE_OPTLEN, 413 ITEM_VXLAN_GPE, 414 ITEM_VXLAN_GPE_VNI, 415 ITEM_VXLAN_GPE_PROTO, 416 ITEM_VXLAN_GPE_FLAGS, 417 ITEM_VXLAN_GPE_RSVD0, 418 ITEM_VXLAN_GPE_RSVD1, 419 ITEM_ARP_ETH_IPV4, 420 ITEM_ARP_ETH_IPV4_SHA, 421 ITEM_ARP_ETH_IPV4_SPA, 422 ITEM_ARP_ETH_IPV4_THA, 423 ITEM_ARP_ETH_IPV4_TPA, 424 ITEM_IPV6_EXT, 425 ITEM_IPV6_EXT_NEXT_HDR, 426 ITEM_IPV6_FRAG_EXT, 427 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 428 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 429 ITEM_IPV6_FRAG_EXT_ID, 430 ITEM_ICMP6, 431 ITEM_ICMP6_TYPE, 432 ITEM_ICMP6_CODE, 433 ITEM_ICMP6_ECHO_REQUEST, 434 ITEM_ICMP6_ECHO_REQUEST_ID, 435 ITEM_ICMP6_ECHO_REQUEST_SEQ, 436 ITEM_ICMP6_ECHO_REPLY, 437 ITEM_ICMP6_ECHO_REPLY_ID, 438 ITEM_ICMP6_ECHO_REPLY_SEQ, 439 ITEM_ICMP6_ND_NS, 440 ITEM_ICMP6_ND_NS_TARGET_ADDR, 441 ITEM_ICMP6_ND_NA, 442 ITEM_ICMP6_ND_NA_TARGET_ADDR, 443 ITEM_ICMP6_ND_OPT, 444 ITEM_ICMP6_ND_OPT_TYPE, 445 ITEM_ICMP6_ND_OPT_SLA_ETH, 446 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 447 ITEM_ICMP6_ND_OPT_TLA_ETH, 448 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 449 ITEM_META, 450 ITEM_META_DATA, 451 ITEM_RANDOM, 452 ITEM_RANDOM_VALUE, 453 ITEM_GRE_KEY, 454 ITEM_GRE_KEY_VALUE, 455 ITEM_GRE_OPTION, 456 ITEM_GRE_OPTION_CHECKSUM, 457 ITEM_GRE_OPTION_KEY, 458 ITEM_GRE_OPTION_SEQUENCE, 459 ITEM_GTP_PSC, 460 ITEM_GTP_PSC_QFI, 461 ITEM_GTP_PSC_PDU_T, 462 ITEM_PPPOES, 463 ITEM_PPPOED, 464 ITEM_PPPOE_SEID, 465 ITEM_PPPOE_PROTO_ID, 466 ITEM_HIGIG2, 467 ITEM_HIGIG2_CLASSIFICATION, 468 ITEM_HIGIG2_VID, 469 ITEM_TAG, 470 ITEM_TAG_DATA, 471 ITEM_TAG_INDEX, 472 ITEM_L2TPV3OIP, 473 ITEM_L2TPV3OIP_SESSION_ID, 474 ITEM_ESP, 475 ITEM_ESP_SPI, 476 ITEM_AH, 477 ITEM_AH_SPI, 478 ITEM_PFCP, 479 ITEM_PFCP_S_FIELD, 480 ITEM_PFCP_SEID, 481 ITEM_ECPRI, 482 ITEM_ECPRI_COMMON, 483 ITEM_ECPRI_COMMON_TYPE, 484 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 485 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 486 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 487 ITEM_ECPRI_MSG_IQ_DATA_PCID, 488 ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 489 ITEM_ECPRI_MSG_DLY_MSR_MSRID, 490 ITEM_GENEVE_OPT, 491 ITEM_GENEVE_OPT_CLASS, 492 ITEM_GENEVE_OPT_TYPE, 493 ITEM_GENEVE_OPT_LENGTH, 494 ITEM_GENEVE_OPT_DATA, 495 ITEM_INTEGRITY, 496 ITEM_INTEGRITY_LEVEL, 497 ITEM_INTEGRITY_VALUE, 498 ITEM_CONNTRACK, 499 ITEM_POL_PORT, 500 ITEM_POL_METER, 501 ITEM_POL_POLICY, 502 ITEM_PORT_REPRESENTOR, 503 ITEM_PORT_REPRESENTOR_PORT_ID, 504 ITEM_REPRESENTED_PORT, 505 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 506 ITEM_FLEX, 507 ITEM_FLEX_ITEM_HANDLE, 508 ITEM_FLEX_PATTERN_HANDLE, 509 ITEM_L2TPV2, 510 ITEM_L2TPV2_TYPE, 511 ITEM_L2TPV2_TYPE_DATA, 512 ITEM_L2TPV2_TYPE_DATA_L, 513 ITEM_L2TPV2_TYPE_DATA_S, 514 ITEM_L2TPV2_TYPE_DATA_O, 515 ITEM_L2TPV2_TYPE_DATA_L_S, 516 ITEM_L2TPV2_TYPE_CTRL, 517 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 518 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 519 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 520 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 521 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 522 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 523 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 524 ITEM_L2TPV2_MSG_DATA_S_NS, 525 ITEM_L2TPV2_MSG_DATA_S_NR, 526 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 527 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 528 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 529 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 530 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 531 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 532 ITEM_L2TPV2_MSG_DATA_L_S_NS, 533 ITEM_L2TPV2_MSG_DATA_L_S_NR, 534 ITEM_L2TPV2_MSG_CTRL_LENGTH, 535 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 536 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 537 ITEM_L2TPV2_MSG_CTRL_NS, 538 ITEM_L2TPV2_MSG_CTRL_NR, 539 ITEM_PPP, 540 ITEM_PPP_ADDR, 541 ITEM_PPP_CTRL, 542 ITEM_PPP_PROTO_ID, 543 ITEM_METER, 544 ITEM_METER_COLOR, 545 ITEM_METER_COLOR_NAME, 546 ITEM_QUOTA, 547 ITEM_QUOTA_STATE, 548 ITEM_QUOTA_STATE_NAME, 549 ITEM_AGGR_AFFINITY, 550 ITEM_AGGR_AFFINITY_VALUE, 551 ITEM_TX_QUEUE, 552 ITEM_TX_QUEUE_VALUE, 553 ITEM_IB_BTH, 554 ITEM_IB_BTH_OPCODE, 555 ITEM_IB_BTH_PKEY, 556 ITEM_IB_BTH_DST_QPN, 557 ITEM_IB_BTH_PSN, 558 ITEM_IPV6_PUSH_REMOVE_EXT, 559 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 560 ITEM_PTYPE, 561 ITEM_PTYPE_VALUE, 562 ITEM_NSH, 563 ITEM_COMPARE, 564 ITEM_COMPARE_OP, 565 ITEM_COMPARE_OP_VALUE, 566 ITEM_COMPARE_FIELD_A_TYPE, 567 ITEM_COMPARE_FIELD_A_TYPE_VALUE, 568 ITEM_COMPARE_FIELD_A_LEVEL, 569 ITEM_COMPARE_FIELD_A_LEVEL_VALUE, 570 ITEM_COMPARE_FIELD_A_TAG_INDEX, 571 ITEM_COMPARE_FIELD_A_TYPE_ID, 572 ITEM_COMPARE_FIELD_A_CLASS_ID, 573 ITEM_COMPARE_FIELD_A_OFFSET, 574 ITEM_COMPARE_FIELD_B_TYPE, 575 ITEM_COMPARE_FIELD_B_TYPE_VALUE, 576 ITEM_COMPARE_FIELD_B_LEVEL, 577 ITEM_COMPARE_FIELD_B_LEVEL_VALUE, 578 ITEM_COMPARE_FIELD_B_TAG_INDEX, 579 ITEM_COMPARE_FIELD_B_TYPE_ID, 580 ITEM_COMPARE_FIELD_B_CLASS_ID, 581 ITEM_COMPARE_FIELD_B_OFFSET, 582 ITEM_COMPARE_FIELD_B_VALUE, 583 ITEM_COMPARE_FIELD_B_POINTER, 584 ITEM_COMPARE_FIELD_WIDTH, 585 586 /* Validate/create actions. */ 587 ACTIONS, 588 ACTION_NEXT, 589 ACTION_END, 590 ACTION_VOID, 591 ACTION_PASSTHRU, 592 ACTION_SKIP_CMAN, 593 ACTION_JUMP, 594 ACTION_JUMP_GROUP, 595 ACTION_MARK, 596 ACTION_MARK_ID, 597 ACTION_FLAG, 598 ACTION_QUEUE, 599 ACTION_QUEUE_INDEX, 600 ACTION_DROP, 601 ACTION_COUNT, 602 ACTION_COUNT_ID, 603 ACTION_RSS, 604 ACTION_RSS_FUNC, 605 ACTION_RSS_LEVEL, 606 ACTION_RSS_FUNC_DEFAULT, 607 ACTION_RSS_FUNC_TOEPLITZ, 608 ACTION_RSS_FUNC_SIMPLE_XOR, 609 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, 610 ACTION_RSS_TYPES, 611 ACTION_RSS_TYPE, 612 ACTION_RSS_KEY, 613 ACTION_RSS_KEY_LEN, 614 ACTION_RSS_QUEUES, 615 ACTION_RSS_QUEUE, 616 ACTION_PF, 617 ACTION_VF, 618 ACTION_VF_ORIGINAL, 619 ACTION_VF_ID, 620 ACTION_PORT_ID, 621 ACTION_PORT_ID_ORIGINAL, 622 ACTION_PORT_ID_ID, 623 ACTION_METER, 624 ACTION_METER_COLOR, 625 ACTION_METER_COLOR_TYPE, 626 ACTION_METER_COLOR_GREEN, 627 ACTION_METER_COLOR_YELLOW, 628 ACTION_METER_COLOR_RED, 629 ACTION_METER_ID, 630 ACTION_METER_MARK, 631 ACTION_METER_PROFILE, 632 ACTION_METER_PROFILE_ID2PTR, 633 ACTION_METER_POLICY, 634 ACTION_METER_POLICY_ID2PTR, 635 ACTION_METER_COLOR_MODE, 636 ACTION_METER_STATE, 637 ACTION_OF_DEC_NW_TTL, 638 ACTION_OF_POP_VLAN, 639 ACTION_OF_PUSH_VLAN, 640 ACTION_OF_PUSH_VLAN_ETHERTYPE, 641 ACTION_OF_SET_VLAN_VID, 642 ACTION_OF_SET_VLAN_VID_VLAN_VID, 643 ACTION_OF_SET_VLAN_PCP, 644 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 645 ACTION_OF_POP_MPLS, 646 ACTION_OF_POP_MPLS_ETHERTYPE, 647 ACTION_OF_PUSH_MPLS, 648 ACTION_OF_PUSH_MPLS_ETHERTYPE, 649 ACTION_VXLAN_ENCAP, 650 ACTION_VXLAN_DECAP, 651 ACTION_NVGRE_ENCAP, 652 ACTION_NVGRE_DECAP, 653 ACTION_L2_ENCAP, 654 ACTION_L2_DECAP, 655 ACTION_MPLSOGRE_ENCAP, 656 ACTION_MPLSOGRE_DECAP, 657 ACTION_MPLSOUDP_ENCAP, 658 ACTION_MPLSOUDP_DECAP, 659 ACTION_SET_IPV4_SRC, 660 ACTION_SET_IPV4_SRC_IPV4_SRC, 661 ACTION_SET_IPV4_DST, 662 ACTION_SET_IPV4_DST_IPV4_DST, 663 ACTION_SET_IPV6_SRC, 664 ACTION_SET_IPV6_SRC_IPV6_SRC, 665 ACTION_SET_IPV6_DST, 666 ACTION_SET_IPV6_DST_IPV6_DST, 667 ACTION_SET_TP_SRC, 668 ACTION_SET_TP_SRC_TP_SRC, 669 ACTION_SET_TP_DST, 670 ACTION_SET_TP_DST_TP_DST, 671 ACTION_MAC_SWAP, 672 ACTION_DEC_TTL, 673 ACTION_SET_TTL, 674 ACTION_SET_TTL_TTL, 675 ACTION_SET_MAC_SRC, 676 ACTION_SET_MAC_SRC_MAC_SRC, 677 ACTION_SET_MAC_DST, 678 ACTION_SET_MAC_DST_MAC_DST, 679 ACTION_INC_TCP_SEQ, 680 ACTION_INC_TCP_SEQ_VALUE, 681 ACTION_DEC_TCP_SEQ, 682 ACTION_DEC_TCP_SEQ_VALUE, 683 ACTION_INC_TCP_ACK, 684 ACTION_INC_TCP_ACK_VALUE, 685 ACTION_DEC_TCP_ACK, 686 ACTION_DEC_TCP_ACK_VALUE, 687 ACTION_RAW_ENCAP, 688 ACTION_RAW_DECAP, 689 ACTION_RAW_ENCAP_SIZE, 690 ACTION_RAW_ENCAP_INDEX, 691 ACTION_RAW_ENCAP_INDEX_VALUE, 692 ACTION_RAW_DECAP_INDEX, 693 ACTION_RAW_DECAP_INDEX_VALUE, 694 ACTION_SET_TAG, 695 ACTION_SET_TAG_DATA, 696 ACTION_SET_TAG_INDEX, 697 ACTION_SET_TAG_MASK, 698 ACTION_SET_META, 699 ACTION_SET_META_DATA, 700 ACTION_SET_META_MASK, 701 ACTION_SET_IPV4_DSCP, 702 ACTION_SET_IPV4_DSCP_VALUE, 703 ACTION_SET_IPV6_DSCP, 704 ACTION_SET_IPV6_DSCP_VALUE, 705 ACTION_AGE, 706 ACTION_AGE_TIMEOUT, 707 ACTION_AGE_UPDATE, 708 ACTION_AGE_UPDATE_TIMEOUT, 709 ACTION_AGE_UPDATE_TOUCH, 710 ACTION_SAMPLE, 711 ACTION_SAMPLE_RATIO, 712 ACTION_SAMPLE_INDEX, 713 ACTION_SAMPLE_INDEX_VALUE, 714 ACTION_INDIRECT, 715 ACTION_INDIRECT_LIST, 716 ACTION_INDIRECT_LIST_HANDLE, 717 ACTION_INDIRECT_LIST_CONF, 718 INDIRECT_LIST_ACTION_ID2PTR_HANDLE, 719 INDIRECT_LIST_ACTION_ID2PTR_CONF, 720 ACTION_SHARED_INDIRECT, 721 INDIRECT_ACTION_PORT, 722 INDIRECT_ACTION_ID2PTR, 723 ACTION_MODIFY_FIELD, 724 ACTION_MODIFY_FIELD_OP, 725 ACTION_MODIFY_FIELD_OP_VALUE, 726 ACTION_MODIFY_FIELD_DST_TYPE, 727 ACTION_MODIFY_FIELD_DST_TYPE_VALUE, 728 ACTION_MODIFY_FIELD_DST_LEVEL, 729 ACTION_MODIFY_FIELD_DST_LEVEL_VALUE, 730 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 731 ACTION_MODIFY_FIELD_DST_TYPE_ID, 732 ACTION_MODIFY_FIELD_DST_CLASS_ID, 733 ACTION_MODIFY_FIELD_DST_OFFSET, 734 ACTION_MODIFY_FIELD_SRC_TYPE, 735 ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, 736 ACTION_MODIFY_FIELD_SRC_LEVEL, 737 ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE, 738 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 739 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 740 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 741 ACTION_MODIFY_FIELD_SRC_OFFSET, 742 ACTION_MODIFY_FIELD_SRC_VALUE, 743 ACTION_MODIFY_FIELD_SRC_POINTER, 744 ACTION_MODIFY_FIELD_WIDTH, 745 ACTION_CONNTRACK, 746 ACTION_CONNTRACK_UPDATE, 747 ACTION_CONNTRACK_UPDATE_DIR, 748 ACTION_CONNTRACK_UPDATE_CTX, 749 ACTION_POL_G, 750 ACTION_POL_Y, 751 ACTION_POL_R, 752 ACTION_PORT_REPRESENTOR, 753 ACTION_PORT_REPRESENTOR_PORT_ID, 754 ACTION_REPRESENTED_PORT, 755 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 756 ACTION_SEND_TO_KERNEL, 757 ACTION_QUOTA_CREATE, 758 ACTION_QUOTA_CREATE_LIMIT, 759 ACTION_QUOTA_CREATE_MODE, 760 ACTION_QUOTA_CREATE_MODE_NAME, 761 ACTION_QUOTA_QU, 762 ACTION_QUOTA_QU_LIMIT, 763 ACTION_QUOTA_QU_UPDATE_OP, 764 ACTION_QUOTA_QU_UPDATE_OP_NAME, 765 ACTION_IPV6_EXT_REMOVE, 766 ACTION_IPV6_EXT_REMOVE_INDEX, 767 ACTION_IPV6_EXT_REMOVE_INDEX_VALUE, 768 ACTION_IPV6_EXT_PUSH, 769 ACTION_IPV6_EXT_PUSH_INDEX, 770 ACTION_IPV6_EXT_PUSH_INDEX_VALUE, 771 ACTION_NAT64, 772 ACTION_NAT64_MODE, 773 }; 774 775 /** Maximum size for pattern in struct rte_flow_item_raw. */ 776 #define ITEM_RAW_PATTERN_SIZE 512 777 778 /** Maximum size for GENEVE option data pattern in bytes. */ 779 #define ITEM_GENEVE_OPT_DATA_SIZE 124 780 781 /** Storage size for struct rte_flow_item_raw including pattern. */ 782 #define ITEM_RAW_SIZE \ 783 (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) 784 785 static const char *const compare_ops[] = { 786 "eq", "ne", "lt", "le", "gt", "ge", NULL 787 }; 788 789 /** Maximum size for external pattern in struct rte_flow_field_data. */ 790 #define FLOW_FIELD_PATTERN_SIZE 32 791 792 /** Storage size for struct rte_flow_action_modify_field including pattern. */ 793 #define ACTION_MODIFY_SIZE \ 794 (sizeof(struct rte_flow_action_modify_field) + \ 795 FLOW_FIELD_PATTERN_SIZE) 796 797 /** Maximum number of queue indices in struct rte_flow_action_rss. */ 798 #define ACTION_RSS_QUEUE_NUM 128 799 800 /** Storage for struct rte_flow_action_rss including external data. */ 801 struct action_rss_data { 802 struct rte_flow_action_rss conf; 803 uint8_t key[RSS_HASH_KEY_LENGTH]; 804 uint16_t queue[ACTION_RSS_QUEUE_NUM]; 805 }; 806 807 /** Maximum data size in struct rte_flow_action_raw_encap. */ 808 #define ACTION_RAW_ENCAP_MAX_DATA 512 809 #define RAW_ENCAP_CONFS_MAX_NUM 8 810 811 /** Storage for struct rte_flow_action_raw_encap. */ 812 struct raw_encap_conf { 813 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 814 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 815 size_t size; 816 }; 817 818 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 819 820 /** Storage for struct rte_flow_action_raw_encap including external data. */ 821 struct action_raw_encap_data { 822 struct rte_flow_action_raw_encap conf; 823 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 824 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 825 uint16_t idx; 826 }; 827 828 /** Storage for struct rte_flow_action_raw_decap. */ 829 struct raw_decap_conf { 830 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 831 size_t size; 832 }; 833 834 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 835 836 /** Storage for struct rte_flow_action_raw_decap including external data. */ 837 struct action_raw_decap_data { 838 struct rte_flow_action_raw_decap conf; 839 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 840 uint16_t idx; 841 }; 842 843 /** Maximum data size in struct rte_flow_action_ipv6_ext_push. */ 844 #define ACTION_IPV6_EXT_PUSH_MAX_DATA 512 845 #define IPV6_EXT_PUSH_CONFS_MAX_NUM 8 846 847 /** Storage for struct rte_flow_action_ipv6_ext_push. */ 848 struct ipv6_ext_push_conf { 849 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 850 size_t size; 851 uint8_t type; 852 }; 853 854 struct ipv6_ext_push_conf ipv6_ext_push_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 855 856 /** Storage for struct rte_flow_action_ipv6_ext_push including external data. */ 857 struct action_ipv6_ext_push_data { 858 struct rte_flow_action_ipv6_ext_push conf; 859 uint8_t data[ACTION_IPV6_EXT_PUSH_MAX_DATA]; 860 uint8_t type; 861 uint16_t idx; 862 }; 863 864 /** Storage for struct rte_flow_action_ipv6_ext_remove. */ 865 struct ipv6_ext_remove_conf { 866 struct rte_flow_action_ipv6_ext_remove conf; 867 uint8_t type; 868 }; 869 870 struct ipv6_ext_remove_conf ipv6_ext_remove_confs[IPV6_EXT_PUSH_CONFS_MAX_NUM]; 871 872 /** Storage for struct rte_flow_action_ipv6_ext_remove including external data. */ 873 struct action_ipv6_ext_remove_data { 874 struct rte_flow_action_ipv6_ext_remove conf; 875 uint8_t type; 876 uint16_t idx; 877 }; 878 879 struct vxlan_encap_conf vxlan_encap_conf = { 880 .select_ipv4 = 1, 881 .select_vlan = 0, 882 .select_tos_ttl = 0, 883 .vni = "\x00\x00\x00", 884 .udp_src = 0, 885 .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), 886 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 887 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 888 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 889 "\x00\x00\x00\x00\x00\x00\x00\x01", 890 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 891 "\x00\x00\x00\x00\x00\x00\x11\x11", 892 .vlan_tci = 0, 893 .ip_tos = 0, 894 .ip_ttl = 255, 895 .eth_src = "\x00\x00\x00\x00\x00\x00", 896 .eth_dst = "\xff\xff\xff\xff\xff\xff", 897 }; 898 899 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */ 900 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6 901 902 /** Storage for struct rte_flow_action_vxlan_encap including external data. */ 903 struct action_vxlan_encap_data { 904 struct rte_flow_action_vxlan_encap conf; 905 struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; 906 struct rte_flow_item_eth item_eth; 907 struct rte_flow_item_vlan item_vlan; 908 union { 909 struct rte_flow_item_ipv4 item_ipv4; 910 struct rte_flow_item_ipv6 item_ipv6; 911 }; 912 struct rte_flow_item_udp item_udp; 913 struct rte_flow_item_vxlan item_vxlan; 914 }; 915 916 struct nvgre_encap_conf nvgre_encap_conf = { 917 .select_ipv4 = 1, 918 .select_vlan = 0, 919 .tni = "\x00\x00\x00", 920 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 921 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 922 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 923 "\x00\x00\x00\x00\x00\x00\x00\x01", 924 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 925 "\x00\x00\x00\x00\x00\x00\x11\x11", 926 .vlan_tci = 0, 927 .eth_src = "\x00\x00\x00\x00\x00\x00", 928 .eth_dst = "\xff\xff\xff\xff\xff\xff", 929 }; 930 931 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */ 932 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 933 934 /** Storage for struct rte_flow_action_nvgre_encap including external data. */ 935 struct action_nvgre_encap_data { 936 struct rte_flow_action_nvgre_encap conf; 937 struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; 938 struct rte_flow_item_eth item_eth; 939 struct rte_flow_item_vlan item_vlan; 940 union { 941 struct rte_flow_item_ipv4 item_ipv4; 942 struct rte_flow_item_ipv6 item_ipv6; 943 }; 944 struct rte_flow_item_nvgre item_nvgre; 945 }; 946 947 struct l2_encap_conf l2_encap_conf; 948 949 struct l2_decap_conf l2_decap_conf; 950 951 struct mplsogre_encap_conf mplsogre_encap_conf; 952 953 struct mplsogre_decap_conf mplsogre_decap_conf; 954 955 struct mplsoudp_encap_conf mplsoudp_encap_conf; 956 957 struct mplsoudp_decap_conf mplsoudp_decap_conf; 958 959 struct rte_flow_action_conntrack conntrack_context; 960 961 #define ACTION_SAMPLE_ACTIONS_NUM 10 962 #define RAW_SAMPLE_CONFS_MAX_NUM 8 963 /** Storage for struct rte_flow_action_sample including external data. */ 964 struct action_sample_data { 965 struct rte_flow_action_sample conf; 966 uint32_t idx; 967 }; 968 /** Storage for struct rte_flow_action_sample. */ 969 struct raw_sample_conf { 970 struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; 971 }; 972 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; 973 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; 974 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; 975 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; 976 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; 977 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 978 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 979 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 980 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; 981 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; 982 struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; 983 struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; 984 985 static const char *const modify_field_ops[] = { 986 "set", "add", "sub", NULL 987 }; 988 989 static const char *const flow_field_ids[] = { 990 "start", "mac_dst", "mac_src", 991 "vlan_type", "vlan_id", "mac_type", 992 "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", 993 "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", 994 "tcp_port_src", "tcp_port_dst", 995 "tcp_seq_num", "tcp_ack_num", "tcp_flags", 996 "udp_port_src", "udp_port_dst", 997 "vxlan_vni", "geneve_vni", "gtp_teid", 998 "tag", "mark", "meta", "pointer", "value", 999 "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", 1000 "ipv6_proto", 1001 "flex_item", 1002 "hash_result", 1003 "geneve_opt_type", "geneve_opt_class", "geneve_opt_data", "mpls", 1004 "tcp_data_off", "ipv4_ihl", "ipv4_total_len", "ipv6_payload_len", 1005 "random", 1006 "ipv4_proto", 1007 "esp_spi", "esp_seq_num", "esp_proto", 1008 "ipv6_flow_label", "ipv6_traffic_class", 1009 NULL 1010 }; 1011 1012 static const char *const meter_colors[] = { 1013 "green", "yellow", "red", "all", NULL 1014 }; 1015 1016 static const char *const table_insertion_types[] = { 1017 "pattern", "index", NULL 1018 }; 1019 1020 static const char *const table_hash_funcs[] = { 1021 "default", "linear", "crc32", "crc16", NULL 1022 }; 1023 1024 #define RAW_IPSEC_CONFS_MAX_NUM 8 1025 1026 /** Maximum number of subsequent tokens and arguments on the stack. */ 1027 #define CTX_STACK_SIZE 16 1028 1029 /** Parser context. */ 1030 struct context { 1031 /** Stack of subsequent token lists to process. */ 1032 const enum index *next[CTX_STACK_SIZE]; 1033 /** Arguments for stacked tokens. */ 1034 const void *args[CTX_STACK_SIZE]; 1035 enum index curr; /**< Current token index. */ 1036 enum index prev; /**< Index of the last token seen. */ 1037 int next_num; /**< Number of entries in next[]. */ 1038 int args_num; /**< Number of entries in args[]. */ 1039 uint32_t eol:1; /**< EOL has been detected. */ 1040 uint32_t last:1; /**< No more arguments. */ 1041 portid_t port; /**< Current port ID (for completions). */ 1042 uint32_t objdata; /**< Object-specific data. */ 1043 void *object; /**< Address of current object for relative offsets. */ 1044 void *objmask; /**< Object a full mask must be written to. */ 1045 }; 1046 1047 /** Token argument. */ 1048 struct arg { 1049 uint32_t hton:1; /**< Use network byte ordering. */ 1050 uint32_t sign:1; /**< Value is signed. */ 1051 uint32_t bounded:1; /**< Value is bounded. */ 1052 uintmax_t min; /**< Minimum value if bounded. */ 1053 uintmax_t max; /**< Maximum value if bounded. */ 1054 uint32_t offset; /**< Relative offset from ctx->object. */ 1055 uint32_t size; /**< Field size. */ 1056 const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ 1057 }; 1058 1059 /** Parser token definition. */ 1060 struct token { 1061 /** Type displayed during completion (defaults to "TOKEN"). */ 1062 const char *type; 1063 /** Help displayed during completion (defaults to token name). */ 1064 const char *help; 1065 /** Private data used by parser functions. */ 1066 const void *priv; 1067 /** 1068 * Lists of subsequent tokens to push on the stack. Each call to the 1069 * parser consumes the last entry of that stack. 1070 */ 1071 const enum index *const *next; 1072 /** Arguments stack for subsequent tokens that need them. */ 1073 const struct arg *const *args; 1074 /** 1075 * Token-processing callback, returns -1 in case of error, the 1076 * length of the matched string otherwise. If NULL, attempts to 1077 * match the token name. 1078 * 1079 * If buf is not NULL, the result should be stored in it according 1080 * to context. An error is returned if not large enough. 1081 */ 1082 int (*call)(struct context *ctx, const struct token *token, 1083 const char *str, unsigned int len, 1084 void *buf, unsigned int size); 1085 /** 1086 * Callback that provides possible values for this token, used for 1087 * completion. Returns -1 in case of error, the number of possible 1088 * values otherwise. If NULL, the token name is used. 1089 * 1090 * If buf is not NULL, entry index ent is written to buf and the 1091 * full length of the entry is returned (same behavior as 1092 * snprintf()). 1093 */ 1094 int (*comp)(struct context *ctx, const struct token *token, 1095 unsigned int ent, char *buf, unsigned int size); 1096 /** Mandatory token name, no default value. */ 1097 const char *name; 1098 }; 1099 1100 /** Static initializer for the next field. */ 1101 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } 1102 1103 /** Static initializer for a NEXT() entry. */ 1104 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } 1105 1106 /** Static initializer for the args field. */ 1107 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } 1108 1109 /** Static initializer for ARGS() to target a field. */ 1110 #define ARGS_ENTRY(s, f) \ 1111 (&(const struct arg){ \ 1112 .offset = offsetof(s, f), \ 1113 .size = sizeof(((s *)0)->f), \ 1114 }) 1115 1116 /** Static initializer for ARGS() to target a bit-field. */ 1117 #define ARGS_ENTRY_BF(s, f, b) \ 1118 (&(const struct arg){ \ 1119 .size = sizeof(s), \ 1120 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ 1121 }) 1122 1123 /** Static initializer for ARGS() to target a field with limits. */ 1124 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \ 1125 (&(const struct arg){ \ 1126 .bounded = 1, \ 1127 .min = (i), \ 1128 .max = (a), \ 1129 .offset = offsetof(s, f), \ 1130 .size = sizeof(((s *)0)->f), \ 1131 }) 1132 1133 /** Static initializer for ARGS() to target an arbitrary bit-mask. */ 1134 #define ARGS_ENTRY_MASK(s, f, m) \ 1135 (&(const struct arg){ \ 1136 .offset = offsetof(s, f), \ 1137 .size = sizeof(((s *)0)->f), \ 1138 .mask = (const void *)(m), \ 1139 }) 1140 1141 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ 1142 #define ARGS_ENTRY_MASK_HTON(s, f, m) \ 1143 (&(const struct arg){ \ 1144 .hton = 1, \ 1145 .offset = offsetof(s, f), \ 1146 .size = sizeof(((s *)0)->f), \ 1147 .mask = (const void *)(m), \ 1148 }) 1149 1150 /** Static initializer for ARGS() to target a pointer. */ 1151 #define ARGS_ENTRY_PTR(s, f) \ 1152 (&(const struct arg){ \ 1153 .size = sizeof(*((s *)0)->f), \ 1154 }) 1155 1156 /** Static initializer for ARGS() with arbitrary offset and size. */ 1157 #define ARGS_ENTRY_ARB(o, s) \ 1158 (&(const struct arg){ \ 1159 .offset = (o), \ 1160 .size = (s), \ 1161 }) 1162 1163 /** Same as ARGS_ENTRY_ARB() with bounded values. */ 1164 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ 1165 (&(const struct arg){ \ 1166 .bounded = 1, \ 1167 .min = (i), \ 1168 .max = (a), \ 1169 .offset = (o), \ 1170 .size = (s), \ 1171 }) 1172 1173 /** Same as ARGS_ENTRY() using network byte ordering. */ 1174 #define ARGS_ENTRY_HTON(s, f) \ 1175 (&(const struct arg){ \ 1176 .hton = 1, \ 1177 .offset = offsetof(s, f), \ 1178 .size = sizeof(((s *)0)->f), \ 1179 }) 1180 1181 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ 1182 #define ARG_ENTRY_HTON(s) \ 1183 (&(const struct arg){ \ 1184 .hton = 1, \ 1185 .offset = 0, \ 1186 .size = sizeof(s), \ 1187 }) 1188 1189 /** Parser output buffer layout expected by cmd_flow_parsed(). */ 1190 struct buffer { 1191 enum index command; /**< Flow command. */ 1192 portid_t port; /**< Affected port ID. */ 1193 queueid_t queue; /** Async queue ID. */ 1194 bool postpone; /** Postpone async operation */ 1195 union { 1196 struct { 1197 struct rte_flow_port_attr port_attr; 1198 uint32_t nb_queue; 1199 struct rte_flow_queue_attr queue_attr; 1200 } configure; /**< Configuration arguments. */ 1201 struct { 1202 uint32_t *template_id; 1203 uint32_t template_id_n; 1204 } templ_destroy; /**< Template destroy arguments. */ 1205 struct { 1206 uint32_t id; 1207 struct rte_flow_template_table_attr attr; 1208 uint32_t *pat_templ_id; 1209 uint32_t pat_templ_id_n; 1210 uint32_t *act_templ_id; 1211 uint32_t act_templ_id_n; 1212 } table; /**< Table arguments. */ 1213 struct { 1214 uint32_t *table_id; 1215 uint32_t table_id_n; 1216 } table_destroy; /**< Template destroy arguments. */ 1217 struct { 1218 uint32_t *action_id; 1219 uint32_t action_id_n; 1220 } ia_destroy; /**< Indirect action destroy arguments. */ 1221 struct { 1222 uint32_t action_id; 1223 enum rte_flow_query_update_mode qu_mode; 1224 } ia; /* Indirect action query arguments */ 1225 struct { 1226 uint32_t table_id; 1227 uint32_t pat_templ_id; 1228 uint32_t rule_id; 1229 uint32_t act_templ_id; 1230 struct rte_flow_attr attr; 1231 struct tunnel_ops tunnel_ops; 1232 uintptr_t user_id; 1233 struct rte_flow_item *pattern; 1234 struct rte_flow_action *actions; 1235 struct rte_flow_action *masks; 1236 uint32_t pattern_n; 1237 uint32_t actions_n; 1238 uint8_t *data; 1239 enum rte_flow_encap_hash_field field; 1240 uint8_t encap_hash; 1241 } vc; /**< Validate/create arguments. */ 1242 struct { 1243 uint64_t *rule; 1244 uint64_t rule_n; 1245 bool is_user_id; 1246 } destroy; /**< Destroy arguments. */ 1247 struct { 1248 char file[128]; 1249 bool mode; 1250 uint64_t rule; 1251 bool is_user_id; 1252 } dump; /**< Dump arguments. */ 1253 struct { 1254 uint64_t rule; 1255 struct rte_flow_action action; 1256 bool is_user_id; 1257 } query; /**< Query arguments. */ 1258 struct { 1259 uint32_t *group; 1260 uint32_t group_n; 1261 } list; /**< List arguments. */ 1262 struct { 1263 int set; 1264 } isolate; /**< Isolated mode arguments. */ 1265 struct { 1266 int destroy; 1267 } aged; /**< Aged arguments. */ 1268 struct { 1269 uint32_t policy_id; 1270 } policy;/**< Policy arguments. */ 1271 struct { 1272 uint16_t token; 1273 uintptr_t uintptr; 1274 char filename[128]; 1275 } flex; /**< Flex arguments*/ 1276 } args; /**< Command arguments. */ 1277 }; 1278 1279 /** Private data for pattern items. */ 1280 struct parse_item_priv { 1281 enum rte_flow_item_type type; /**< Item type. */ 1282 uint32_t size; /**< Size of item specification structure. */ 1283 }; 1284 1285 #define PRIV_ITEM(t, s) \ 1286 (&(const struct parse_item_priv){ \ 1287 .type = RTE_FLOW_ITEM_TYPE_ ## t, \ 1288 .size = s, \ 1289 }) 1290 1291 /** Private data for actions. */ 1292 struct parse_action_priv { 1293 enum rte_flow_action_type type; /**< Action type. */ 1294 uint32_t size; /**< Size of action configuration structure. */ 1295 }; 1296 1297 #define PRIV_ACTION(t, s) \ 1298 (&(const struct parse_action_priv){ \ 1299 .type = RTE_FLOW_ACTION_TYPE_ ## t, \ 1300 .size = s, \ 1301 }) 1302 1303 static const enum index next_flex_item[] = { 1304 FLEX_ITEM_INIT, 1305 FLEX_ITEM_CREATE, 1306 FLEX_ITEM_DESTROY, 1307 ZERO, 1308 }; 1309 1310 static const enum index next_config_attr[] = { 1311 CONFIG_QUEUES_NUMBER, 1312 CONFIG_QUEUES_SIZE, 1313 CONFIG_COUNTERS_NUMBER, 1314 CONFIG_AGING_OBJECTS_NUMBER, 1315 CONFIG_METERS_NUMBER, 1316 CONFIG_CONN_TRACK_NUMBER, 1317 CONFIG_QUOTAS_NUMBER, 1318 CONFIG_FLAGS, 1319 CONFIG_HOST_PORT, 1320 END, 1321 ZERO, 1322 }; 1323 1324 static const enum index next_pt_subcmd[] = { 1325 PATTERN_TEMPLATE_CREATE, 1326 PATTERN_TEMPLATE_DESTROY, 1327 ZERO, 1328 }; 1329 1330 static const enum index next_pt_attr[] = { 1331 PATTERN_TEMPLATE_CREATE_ID, 1332 PATTERN_TEMPLATE_RELAXED_MATCHING, 1333 PATTERN_TEMPLATE_INGRESS, 1334 PATTERN_TEMPLATE_EGRESS, 1335 PATTERN_TEMPLATE_TRANSFER, 1336 PATTERN_TEMPLATE_SPEC, 1337 ZERO, 1338 }; 1339 1340 static const enum index next_pt_destroy_attr[] = { 1341 PATTERN_TEMPLATE_DESTROY_ID, 1342 END, 1343 ZERO, 1344 }; 1345 1346 static const enum index next_at_subcmd[] = { 1347 ACTIONS_TEMPLATE_CREATE, 1348 ACTIONS_TEMPLATE_DESTROY, 1349 ZERO, 1350 }; 1351 1352 static const enum index next_at_attr[] = { 1353 ACTIONS_TEMPLATE_CREATE_ID, 1354 ACTIONS_TEMPLATE_INGRESS, 1355 ACTIONS_TEMPLATE_EGRESS, 1356 ACTIONS_TEMPLATE_TRANSFER, 1357 ACTIONS_TEMPLATE_SPEC, 1358 ZERO, 1359 }; 1360 1361 static const enum index next_at_destroy_attr[] = { 1362 ACTIONS_TEMPLATE_DESTROY_ID, 1363 END, 1364 ZERO, 1365 }; 1366 1367 static const enum index next_group_attr[] = { 1368 GROUP_INGRESS, 1369 GROUP_EGRESS, 1370 GROUP_TRANSFER, 1371 GROUP_SET_MISS_ACTIONS, 1372 ZERO, 1373 }; 1374 1375 static const enum index next_table_subcmd[] = { 1376 TABLE_CREATE, 1377 TABLE_DESTROY, 1378 TABLE_RESIZE, 1379 TABLE_RESIZE_COMPLETE, 1380 ZERO, 1381 }; 1382 1383 static const enum index next_table_attr[] = { 1384 TABLE_CREATE_ID, 1385 TABLE_GROUP, 1386 TABLE_INSERTION_TYPE, 1387 TABLE_HASH_FUNC, 1388 TABLE_PRIORITY, 1389 TABLE_INGRESS, 1390 TABLE_EGRESS, 1391 TABLE_TRANSFER, 1392 TABLE_TRANSFER_WIRE_ORIG, 1393 TABLE_TRANSFER_VPORT_ORIG, 1394 TABLE_RESIZABLE, 1395 TABLE_RULES_NUMBER, 1396 TABLE_PATTERN_TEMPLATE, 1397 TABLE_ACTIONS_TEMPLATE, 1398 END, 1399 ZERO, 1400 }; 1401 1402 static const enum index next_table_destroy_attr[] = { 1403 TABLE_DESTROY_ID, 1404 END, 1405 ZERO, 1406 }; 1407 1408 static const enum index next_queue_subcmd[] = { 1409 QUEUE_CREATE, 1410 QUEUE_DESTROY, 1411 QUEUE_FLOW_UPDATE_RESIZED, 1412 QUEUE_UPDATE, 1413 QUEUE_AGED, 1414 QUEUE_INDIRECT_ACTION, 1415 ZERO, 1416 }; 1417 1418 static const enum index next_queue_destroy_attr[] = { 1419 QUEUE_DESTROY_ID, 1420 END, 1421 ZERO, 1422 }; 1423 1424 static const enum index next_qia_subcmd[] = { 1425 QUEUE_INDIRECT_ACTION_CREATE, 1426 QUEUE_INDIRECT_ACTION_UPDATE, 1427 QUEUE_INDIRECT_ACTION_DESTROY, 1428 QUEUE_INDIRECT_ACTION_QUERY, 1429 QUEUE_INDIRECT_ACTION_QUERY_UPDATE, 1430 ZERO, 1431 }; 1432 1433 static const enum index next_qia_create_attr[] = { 1434 QUEUE_INDIRECT_ACTION_CREATE_ID, 1435 QUEUE_INDIRECT_ACTION_INGRESS, 1436 QUEUE_INDIRECT_ACTION_EGRESS, 1437 QUEUE_INDIRECT_ACTION_TRANSFER, 1438 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 1439 QUEUE_INDIRECT_ACTION_SPEC, 1440 QUEUE_INDIRECT_ACTION_LIST, 1441 ZERO, 1442 }; 1443 1444 static const enum index next_qia_update_attr[] = { 1445 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1446 QUEUE_INDIRECT_ACTION_SPEC, 1447 ZERO, 1448 }; 1449 1450 static const enum index next_qia_destroy_attr[] = { 1451 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 1452 QUEUE_INDIRECT_ACTION_DESTROY_ID, 1453 END, 1454 ZERO, 1455 }; 1456 1457 static const enum index next_qia_query_attr[] = { 1458 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 1459 END, 1460 ZERO, 1461 }; 1462 1463 static const enum index next_ia_create_attr[] = { 1464 INDIRECT_ACTION_CREATE_ID, 1465 INDIRECT_ACTION_INGRESS, 1466 INDIRECT_ACTION_EGRESS, 1467 INDIRECT_ACTION_TRANSFER, 1468 INDIRECT_ACTION_SPEC, 1469 INDIRECT_ACTION_LIST, 1470 INDIRECT_ACTION_FLOW_CONF, 1471 ZERO, 1472 }; 1473 1474 static const enum index next_ia[] = { 1475 INDIRECT_ACTION_ID2PTR, 1476 ACTION_NEXT, 1477 ZERO 1478 }; 1479 1480 static const enum index next_ial[] = { 1481 ACTION_INDIRECT_LIST_HANDLE, 1482 ACTION_INDIRECT_LIST_CONF, 1483 ACTION_NEXT, 1484 ZERO 1485 }; 1486 1487 static const enum index next_qia_qu_attr[] = { 1488 QUEUE_INDIRECT_ACTION_QU_MODE, 1489 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1490 INDIRECT_ACTION_SPEC, 1491 ZERO 1492 }; 1493 1494 static const enum index next_ia_qu_attr[] = { 1495 INDIRECT_ACTION_QU_MODE, 1496 INDIRECT_ACTION_SPEC, 1497 ZERO 1498 }; 1499 1500 static const enum index next_dump_subcmd[] = { 1501 DUMP_ALL, 1502 DUMP_ONE, 1503 DUMP_IS_USER_ID, 1504 ZERO, 1505 }; 1506 1507 static const enum index next_ia_subcmd[] = { 1508 INDIRECT_ACTION_CREATE, 1509 INDIRECT_ACTION_UPDATE, 1510 INDIRECT_ACTION_DESTROY, 1511 INDIRECT_ACTION_QUERY, 1512 INDIRECT_ACTION_QUERY_UPDATE, 1513 ZERO, 1514 }; 1515 1516 static const enum index next_vc_attr[] = { 1517 VC_GROUP, 1518 VC_PRIORITY, 1519 VC_INGRESS, 1520 VC_EGRESS, 1521 VC_TRANSFER, 1522 VC_TUNNEL_SET, 1523 VC_TUNNEL_MATCH, 1524 VC_USER_ID, 1525 ITEM_PATTERN, 1526 ZERO, 1527 }; 1528 1529 static const enum index next_destroy_attr[] = { 1530 DESTROY_RULE, 1531 DESTROY_IS_USER_ID, 1532 END, 1533 ZERO, 1534 }; 1535 1536 static const enum index next_dump_attr[] = { 1537 COMMON_FILE_PATH, 1538 END, 1539 ZERO, 1540 }; 1541 1542 static const enum index next_query_attr[] = { 1543 QUERY_IS_USER_ID, 1544 END, 1545 ZERO, 1546 }; 1547 1548 static const enum index next_list_attr[] = { 1549 LIST_GROUP, 1550 END, 1551 ZERO, 1552 }; 1553 1554 static const enum index next_aged_attr[] = { 1555 AGED_DESTROY, 1556 END, 1557 ZERO, 1558 }; 1559 1560 static const enum index next_ia_destroy_attr[] = { 1561 INDIRECT_ACTION_DESTROY_ID, 1562 END, 1563 ZERO, 1564 }; 1565 1566 static const enum index next_async_insert_subcmd[] = { 1567 QUEUE_PATTERN_TEMPLATE, 1568 QUEUE_RULE_ID, 1569 ZERO, 1570 }; 1571 1572 static const enum index item_param[] = { 1573 ITEM_PARAM_IS, 1574 ITEM_PARAM_SPEC, 1575 ITEM_PARAM_LAST, 1576 ITEM_PARAM_MASK, 1577 ITEM_PARAM_PREFIX, 1578 ZERO, 1579 }; 1580 1581 static const enum index next_item[] = { 1582 ITEM_END, 1583 ITEM_VOID, 1584 ITEM_INVERT, 1585 ITEM_ANY, 1586 ITEM_PORT_ID, 1587 ITEM_MARK, 1588 ITEM_RAW, 1589 ITEM_ETH, 1590 ITEM_VLAN, 1591 ITEM_IPV4, 1592 ITEM_IPV6, 1593 ITEM_ICMP, 1594 ITEM_UDP, 1595 ITEM_TCP, 1596 ITEM_SCTP, 1597 ITEM_VXLAN, 1598 ITEM_E_TAG, 1599 ITEM_NVGRE, 1600 ITEM_MPLS, 1601 ITEM_GRE, 1602 ITEM_FUZZY, 1603 ITEM_GTP, 1604 ITEM_GTPC, 1605 ITEM_GTPU, 1606 ITEM_GENEVE, 1607 ITEM_VXLAN_GPE, 1608 ITEM_ARP_ETH_IPV4, 1609 ITEM_IPV6_EXT, 1610 ITEM_IPV6_FRAG_EXT, 1611 ITEM_IPV6_ROUTING_EXT, 1612 ITEM_ICMP6, 1613 ITEM_ICMP6_ECHO_REQUEST, 1614 ITEM_ICMP6_ECHO_REPLY, 1615 ITEM_ICMP6_ND_NS, 1616 ITEM_ICMP6_ND_NA, 1617 ITEM_ICMP6_ND_OPT, 1618 ITEM_ICMP6_ND_OPT_SLA_ETH, 1619 ITEM_ICMP6_ND_OPT_TLA_ETH, 1620 ITEM_META, 1621 ITEM_RANDOM, 1622 ITEM_GRE_KEY, 1623 ITEM_GRE_OPTION, 1624 ITEM_GTP_PSC, 1625 ITEM_PPPOES, 1626 ITEM_PPPOED, 1627 ITEM_PPPOE_PROTO_ID, 1628 ITEM_HIGIG2, 1629 ITEM_TAG, 1630 ITEM_L2TPV3OIP, 1631 ITEM_ESP, 1632 ITEM_AH, 1633 ITEM_PFCP, 1634 ITEM_ECPRI, 1635 ITEM_GENEVE_OPT, 1636 ITEM_INTEGRITY, 1637 ITEM_CONNTRACK, 1638 ITEM_PORT_REPRESENTOR, 1639 ITEM_REPRESENTED_PORT, 1640 ITEM_FLEX, 1641 ITEM_L2TPV2, 1642 ITEM_PPP, 1643 ITEM_METER, 1644 ITEM_QUOTA, 1645 ITEM_AGGR_AFFINITY, 1646 ITEM_TX_QUEUE, 1647 ITEM_IB_BTH, 1648 ITEM_PTYPE, 1649 ITEM_NSH, 1650 ITEM_COMPARE, 1651 END_SET, 1652 ZERO, 1653 }; 1654 1655 static const enum index item_fuzzy[] = { 1656 ITEM_FUZZY_THRESH, 1657 ITEM_NEXT, 1658 ZERO, 1659 }; 1660 1661 static const enum index item_any[] = { 1662 ITEM_ANY_NUM, 1663 ITEM_NEXT, 1664 ZERO, 1665 }; 1666 1667 static const enum index item_port_id[] = { 1668 ITEM_PORT_ID_ID, 1669 ITEM_NEXT, 1670 ZERO, 1671 }; 1672 1673 static const enum index item_mark[] = { 1674 ITEM_MARK_ID, 1675 ITEM_NEXT, 1676 ZERO, 1677 }; 1678 1679 static const enum index item_raw[] = { 1680 ITEM_RAW_RELATIVE, 1681 ITEM_RAW_SEARCH, 1682 ITEM_RAW_OFFSET, 1683 ITEM_RAW_LIMIT, 1684 ITEM_RAW_PATTERN, 1685 ITEM_RAW_PATTERN_HEX, 1686 ITEM_NEXT, 1687 ZERO, 1688 }; 1689 1690 static const enum index item_eth[] = { 1691 ITEM_ETH_DST, 1692 ITEM_ETH_SRC, 1693 ITEM_ETH_TYPE, 1694 ITEM_ETH_HAS_VLAN, 1695 ITEM_NEXT, 1696 ZERO, 1697 }; 1698 1699 static const enum index item_vlan[] = { 1700 ITEM_VLAN_TCI, 1701 ITEM_VLAN_PCP, 1702 ITEM_VLAN_DEI, 1703 ITEM_VLAN_VID, 1704 ITEM_VLAN_INNER_TYPE, 1705 ITEM_VLAN_HAS_MORE_VLAN, 1706 ITEM_NEXT, 1707 ZERO, 1708 }; 1709 1710 static const enum index item_ipv4[] = { 1711 ITEM_IPV4_VER_IHL, 1712 ITEM_IPV4_TOS, 1713 ITEM_IPV4_LENGTH, 1714 ITEM_IPV4_ID, 1715 ITEM_IPV4_FRAGMENT_OFFSET, 1716 ITEM_IPV4_TTL, 1717 ITEM_IPV4_PROTO, 1718 ITEM_IPV4_SRC, 1719 ITEM_IPV4_DST, 1720 ITEM_NEXT, 1721 ZERO, 1722 }; 1723 1724 static const enum index item_ipv6[] = { 1725 ITEM_IPV6_TC, 1726 ITEM_IPV6_FLOW, 1727 ITEM_IPV6_LEN, 1728 ITEM_IPV6_PROTO, 1729 ITEM_IPV6_HOP, 1730 ITEM_IPV6_SRC, 1731 ITEM_IPV6_DST, 1732 ITEM_IPV6_HAS_FRAG_EXT, 1733 ITEM_IPV6_ROUTING_EXT, 1734 ITEM_NEXT, 1735 ZERO, 1736 }; 1737 1738 static const enum index item_ipv6_routing_ext[] = { 1739 ITEM_IPV6_ROUTING_EXT_TYPE, 1740 ITEM_IPV6_ROUTING_EXT_NEXT_HDR, 1741 ITEM_IPV6_ROUTING_EXT_SEG_LEFT, 1742 ITEM_NEXT, 1743 ZERO, 1744 }; 1745 1746 static const enum index item_icmp[] = { 1747 ITEM_ICMP_TYPE, 1748 ITEM_ICMP_CODE, 1749 ITEM_ICMP_IDENT, 1750 ITEM_ICMP_SEQ, 1751 ITEM_NEXT, 1752 ZERO, 1753 }; 1754 1755 static const enum index item_udp[] = { 1756 ITEM_UDP_SRC, 1757 ITEM_UDP_DST, 1758 ITEM_NEXT, 1759 ZERO, 1760 }; 1761 1762 static const enum index item_tcp[] = { 1763 ITEM_TCP_SRC, 1764 ITEM_TCP_DST, 1765 ITEM_TCP_FLAGS, 1766 ITEM_NEXT, 1767 ZERO, 1768 }; 1769 1770 static const enum index item_sctp[] = { 1771 ITEM_SCTP_SRC, 1772 ITEM_SCTP_DST, 1773 ITEM_SCTP_TAG, 1774 ITEM_SCTP_CKSUM, 1775 ITEM_NEXT, 1776 ZERO, 1777 }; 1778 1779 static const enum index item_vxlan[] = { 1780 ITEM_VXLAN_VNI, 1781 ITEM_VXLAN_LAST_RSVD, 1782 ITEM_NEXT, 1783 ZERO, 1784 }; 1785 1786 static const enum index item_e_tag[] = { 1787 ITEM_E_TAG_GRP_ECID_B, 1788 ITEM_NEXT, 1789 ZERO, 1790 }; 1791 1792 static const enum index item_nvgre[] = { 1793 ITEM_NVGRE_TNI, 1794 ITEM_NEXT, 1795 ZERO, 1796 }; 1797 1798 static const enum index item_mpls[] = { 1799 ITEM_MPLS_LABEL, 1800 ITEM_MPLS_TC, 1801 ITEM_MPLS_S, 1802 ITEM_MPLS_TTL, 1803 ITEM_NEXT, 1804 ZERO, 1805 }; 1806 1807 static const enum index item_gre[] = { 1808 ITEM_GRE_PROTO, 1809 ITEM_GRE_C_RSVD0_VER, 1810 ITEM_GRE_C_BIT, 1811 ITEM_GRE_K_BIT, 1812 ITEM_GRE_S_BIT, 1813 ITEM_NEXT, 1814 ZERO, 1815 }; 1816 1817 static const enum index item_gre_key[] = { 1818 ITEM_GRE_KEY_VALUE, 1819 ITEM_NEXT, 1820 ZERO, 1821 }; 1822 1823 static const enum index item_gre_option[] = { 1824 ITEM_GRE_OPTION_CHECKSUM, 1825 ITEM_GRE_OPTION_KEY, 1826 ITEM_GRE_OPTION_SEQUENCE, 1827 ITEM_NEXT, 1828 ZERO, 1829 }; 1830 1831 static const enum index item_gtp[] = { 1832 ITEM_GTP_FLAGS, 1833 ITEM_GTP_MSG_TYPE, 1834 ITEM_GTP_TEID, 1835 ITEM_NEXT, 1836 ZERO, 1837 }; 1838 1839 static const enum index item_geneve[] = { 1840 ITEM_GENEVE_VNI, 1841 ITEM_GENEVE_PROTO, 1842 ITEM_GENEVE_OPTLEN, 1843 ITEM_NEXT, 1844 ZERO, 1845 }; 1846 1847 static const enum index item_vxlan_gpe[] = { 1848 ITEM_VXLAN_GPE_VNI, 1849 ITEM_VXLAN_GPE_PROTO, 1850 ITEM_VXLAN_GPE_FLAGS, 1851 ITEM_VXLAN_GPE_RSVD0, 1852 ITEM_VXLAN_GPE_RSVD1, 1853 ITEM_NEXT, 1854 ZERO, 1855 }; 1856 1857 static const enum index item_arp_eth_ipv4[] = { 1858 ITEM_ARP_ETH_IPV4_SHA, 1859 ITEM_ARP_ETH_IPV4_SPA, 1860 ITEM_ARP_ETH_IPV4_THA, 1861 ITEM_ARP_ETH_IPV4_TPA, 1862 ITEM_NEXT, 1863 ZERO, 1864 }; 1865 1866 static const enum index item_ipv6_ext[] = { 1867 ITEM_IPV6_EXT_NEXT_HDR, 1868 ITEM_NEXT, 1869 ZERO, 1870 }; 1871 1872 static const enum index item_ipv6_frag_ext[] = { 1873 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 1874 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 1875 ITEM_IPV6_FRAG_EXT_ID, 1876 ITEM_NEXT, 1877 ZERO, 1878 }; 1879 1880 static const enum index item_icmp6[] = { 1881 ITEM_ICMP6_TYPE, 1882 ITEM_ICMP6_CODE, 1883 ITEM_NEXT, 1884 ZERO, 1885 }; 1886 1887 static const enum index item_icmp6_echo_request[] = { 1888 ITEM_ICMP6_ECHO_REQUEST_ID, 1889 ITEM_ICMP6_ECHO_REQUEST_SEQ, 1890 ITEM_NEXT, 1891 ZERO, 1892 }; 1893 1894 static const enum index item_icmp6_echo_reply[] = { 1895 ITEM_ICMP6_ECHO_REPLY_ID, 1896 ITEM_ICMP6_ECHO_REPLY_SEQ, 1897 ITEM_NEXT, 1898 ZERO, 1899 }; 1900 1901 static const enum index item_icmp6_nd_ns[] = { 1902 ITEM_ICMP6_ND_NS_TARGET_ADDR, 1903 ITEM_NEXT, 1904 ZERO, 1905 }; 1906 1907 static const enum index item_icmp6_nd_na[] = { 1908 ITEM_ICMP6_ND_NA_TARGET_ADDR, 1909 ITEM_NEXT, 1910 ZERO, 1911 }; 1912 1913 static const enum index item_icmp6_nd_opt[] = { 1914 ITEM_ICMP6_ND_OPT_TYPE, 1915 ITEM_NEXT, 1916 ZERO, 1917 }; 1918 1919 static const enum index item_icmp6_nd_opt_sla_eth[] = { 1920 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 1921 ITEM_NEXT, 1922 ZERO, 1923 }; 1924 1925 static const enum index item_icmp6_nd_opt_tla_eth[] = { 1926 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 1927 ITEM_NEXT, 1928 ZERO, 1929 }; 1930 1931 static const enum index item_meta[] = { 1932 ITEM_META_DATA, 1933 ITEM_NEXT, 1934 ZERO, 1935 }; 1936 1937 static const enum index item_random[] = { 1938 ITEM_RANDOM_VALUE, 1939 ITEM_NEXT, 1940 ZERO, 1941 }; 1942 1943 static const enum index item_gtp_psc[] = { 1944 ITEM_GTP_PSC_QFI, 1945 ITEM_GTP_PSC_PDU_T, 1946 ITEM_NEXT, 1947 ZERO, 1948 }; 1949 1950 static const enum index item_pppoed[] = { 1951 ITEM_PPPOE_SEID, 1952 ITEM_NEXT, 1953 ZERO, 1954 }; 1955 1956 static const enum index item_pppoes[] = { 1957 ITEM_PPPOE_SEID, 1958 ITEM_NEXT, 1959 ZERO, 1960 }; 1961 1962 static const enum index item_pppoe_proto_id[] = { 1963 ITEM_NEXT, 1964 ZERO, 1965 }; 1966 1967 static const enum index item_higig2[] = { 1968 ITEM_HIGIG2_CLASSIFICATION, 1969 ITEM_HIGIG2_VID, 1970 ITEM_NEXT, 1971 ZERO, 1972 }; 1973 1974 static const enum index item_esp[] = { 1975 ITEM_ESP_SPI, 1976 ITEM_NEXT, 1977 ZERO, 1978 }; 1979 1980 static const enum index item_ah[] = { 1981 ITEM_AH_SPI, 1982 ITEM_NEXT, 1983 ZERO, 1984 }; 1985 1986 static const enum index item_pfcp[] = { 1987 ITEM_PFCP_S_FIELD, 1988 ITEM_PFCP_SEID, 1989 ITEM_NEXT, 1990 ZERO, 1991 }; 1992 1993 static const enum index next_set_raw[] = { 1994 SET_RAW_INDEX, 1995 ITEM_ETH, 1996 ZERO, 1997 }; 1998 1999 static const enum index item_tag[] = { 2000 ITEM_TAG_DATA, 2001 ITEM_TAG_INDEX, 2002 ITEM_NEXT, 2003 ZERO, 2004 }; 2005 2006 static const enum index item_l2tpv3oip[] = { 2007 ITEM_L2TPV3OIP_SESSION_ID, 2008 ITEM_NEXT, 2009 ZERO, 2010 }; 2011 2012 static const enum index item_ecpri[] = { 2013 ITEM_ECPRI_COMMON, 2014 ITEM_NEXT, 2015 ZERO, 2016 }; 2017 2018 static const enum index item_ecpri_common[] = { 2019 ITEM_ECPRI_COMMON_TYPE, 2020 ZERO, 2021 }; 2022 2023 static const enum index item_ecpri_common_type[] = { 2024 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 2025 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 2026 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 2027 ZERO, 2028 }; 2029 2030 static const enum index item_geneve_opt[] = { 2031 ITEM_GENEVE_OPT_CLASS, 2032 ITEM_GENEVE_OPT_TYPE, 2033 ITEM_GENEVE_OPT_LENGTH, 2034 ITEM_GENEVE_OPT_DATA, 2035 ITEM_NEXT, 2036 ZERO, 2037 }; 2038 2039 static const enum index item_integrity[] = { 2040 ITEM_INTEGRITY_LEVEL, 2041 ITEM_INTEGRITY_VALUE, 2042 ZERO, 2043 }; 2044 2045 static const enum index item_integrity_lv[] = { 2046 ITEM_INTEGRITY_LEVEL, 2047 ITEM_INTEGRITY_VALUE, 2048 ITEM_NEXT, 2049 ZERO, 2050 }; 2051 2052 static const enum index item_port_representor[] = { 2053 ITEM_PORT_REPRESENTOR_PORT_ID, 2054 ITEM_NEXT, 2055 ZERO, 2056 }; 2057 2058 static const enum index item_represented_port[] = { 2059 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 2060 ITEM_NEXT, 2061 ZERO, 2062 }; 2063 2064 static const enum index item_flex[] = { 2065 ITEM_FLEX_PATTERN_HANDLE, 2066 ITEM_FLEX_ITEM_HANDLE, 2067 ITEM_NEXT, 2068 ZERO, 2069 }; 2070 2071 static const enum index item_l2tpv2[] = { 2072 ITEM_L2TPV2_TYPE, 2073 ITEM_NEXT, 2074 ZERO, 2075 }; 2076 2077 static const enum index item_l2tpv2_type[] = { 2078 ITEM_L2TPV2_TYPE_DATA, 2079 ITEM_L2TPV2_TYPE_DATA_L, 2080 ITEM_L2TPV2_TYPE_DATA_S, 2081 ITEM_L2TPV2_TYPE_DATA_O, 2082 ITEM_L2TPV2_TYPE_DATA_L_S, 2083 ITEM_L2TPV2_TYPE_CTRL, 2084 ZERO, 2085 }; 2086 2087 static const enum index item_l2tpv2_type_data[] = { 2088 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 2089 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 2090 ITEM_NEXT, 2091 ZERO, 2092 }; 2093 2094 static const enum index item_l2tpv2_type_data_l[] = { 2095 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 2096 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 2097 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 2098 ITEM_NEXT, 2099 ZERO, 2100 }; 2101 2102 static const enum index item_l2tpv2_type_data_s[] = { 2103 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 2104 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 2105 ITEM_L2TPV2_MSG_DATA_S_NS, 2106 ITEM_L2TPV2_MSG_DATA_S_NR, 2107 ITEM_NEXT, 2108 ZERO, 2109 }; 2110 2111 static const enum index item_l2tpv2_type_data_o[] = { 2112 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 2113 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 2114 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 2115 ITEM_NEXT, 2116 ZERO, 2117 }; 2118 2119 static const enum index item_l2tpv2_type_data_l_s[] = { 2120 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 2121 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 2122 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 2123 ITEM_L2TPV2_MSG_DATA_L_S_NS, 2124 ITEM_L2TPV2_MSG_DATA_L_S_NR, 2125 ITEM_NEXT, 2126 ZERO, 2127 }; 2128 2129 static const enum index item_l2tpv2_type_ctrl[] = { 2130 ITEM_L2TPV2_MSG_CTRL_LENGTH, 2131 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 2132 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 2133 ITEM_L2TPV2_MSG_CTRL_NS, 2134 ITEM_L2TPV2_MSG_CTRL_NR, 2135 ITEM_NEXT, 2136 ZERO, 2137 }; 2138 2139 static const enum index item_ppp[] = { 2140 ITEM_PPP_ADDR, 2141 ITEM_PPP_CTRL, 2142 ITEM_PPP_PROTO_ID, 2143 ITEM_NEXT, 2144 ZERO, 2145 }; 2146 2147 static const enum index item_meter[] = { 2148 ITEM_METER_COLOR, 2149 ITEM_NEXT, 2150 ZERO, 2151 }; 2152 2153 static const enum index item_quota[] = { 2154 ITEM_QUOTA_STATE, 2155 ITEM_NEXT, 2156 ZERO, 2157 }; 2158 2159 static const enum index item_aggr_affinity[] = { 2160 ITEM_AGGR_AFFINITY_VALUE, 2161 ITEM_NEXT, 2162 ZERO, 2163 }; 2164 2165 static const enum index item_tx_queue[] = { 2166 ITEM_TX_QUEUE_VALUE, 2167 ITEM_NEXT, 2168 ZERO, 2169 }; 2170 2171 static const enum index item_ib_bth[] = { 2172 ITEM_IB_BTH_OPCODE, 2173 ITEM_IB_BTH_PKEY, 2174 ITEM_IB_BTH_DST_QPN, 2175 ITEM_IB_BTH_PSN, 2176 ITEM_NEXT, 2177 ZERO, 2178 }; 2179 2180 static const enum index item_ptype[] = { 2181 ITEM_PTYPE_VALUE, 2182 ITEM_NEXT, 2183 ZERO, 2184 }; 2185 2186 static const enum index item_nsh[] = { 2187 ITEM_NEXT, 2188 ZERO, 2189 }; 2190 2191 static const enum index item_compare_field[] = { 2192 ITEM_COMPARE_OP, 2193 ITEM_COMPARE_FIELD_A_TYPE, 2194 ITEM_COMPARE_FIELD_B_TYPE, 2195 ITEM_NEXT, 2196 ZERO, 2197 }; 2198 2199 static const enum index compare_field_a[] = { 2200 ITEM_COMPARE_FIELD_A_TYPE, 2201 ITEM_COMPARE_FIELD_A_LEVEL, 2202 ITEM_COMPARE_FIELD_A_TAG_INDEX, 2203 ITEM_COMPARE_FIELD_A_TYPE_ID, 2204 ITEM_COMPARE_FIELD_A_CLASS_ID, 2205 ITEM_COMPARE_FIELD_A_OFFSET, 2206 ITEM_COMPARE_FIELD_B_TYPE, 2207 ZERO, 2208 }; 2209 2210 static const enum index compare_field_b[] = { 2211 ITEM_COMPARE_FIELD_B_TYPE, 2212 ITEM_COMPARE_FIELD_B_LEVEL, 2213 ITEM_COMPARE_FIELD_B_TAG_INDEX, 2214 ITEM_COMPARE_FIELD_B_TYPE_ID, 2215 ITEM_COMPARE_FIELD_B_CLASS_ID, 2216 ITEM_COMPARE_FIELD_B_OFFSET, 2217 ITEM_COMPARE_FIELD_B_VALUE, 2218 ITEM_COMPARE_FIELD_B_POINTER, 2219 ITEM_COMPARE_FIELD_WIDTH, 2220 ZERO, 2221 }; 2222 2223 static const enum index next_action[] = { 2224 ACTION_END, 2225 ACTION_VOID, 2226 ACTION_PASSTHRU, 2227 ACTION_SKIP_CMAN, 2228 ACTION_JUMP, 2229 ACTION_MARK, 2230 ACTION_FLAG, 2231 ACTION_QUEUE, 2232 ACTION_DROP, 2233 ACTION_COUNT, 2234 ACTION_RSS, 2235 ACTION_PF, 2236 ACTION_VF, 2237 ACTION_PORT_ID, 2238 ACTION_METER, 2239 ACTION_METER_COLOR, 2240 ACTION_METER_MARK, 2241 ACTION_OF_DEC_NW_TTL, 2242 ACTION_OF_POP_VLAN, 2243 ACTION_OF_PUSH_VLAN, 2244 ACTION_OF_SET_VLAN_VID, 2245 ACTION_OF_SET_VLAN_PCP, 2246 ACTION_OF_POP_MPLS, 2247 ACTION_OF_PUSH_MPLS, 2248 ACTION_VXLAN_ENCAP, 2249 ACTION_VXLAN_DECAP, 2250 ACTION_NVGRE_ENCAP, 2251 ACTION_NVGRE_DECAP, 2252 ACTION_L2_ENCAP, 2253 ACTION_L2_DECAP, 2254 ACTION_MPLSOGRE_ENCAP, 2255 ACTION_MPLSOGRE_DECAP, 2256 ACTION_MPLSOUDP_ENCAP, 2257 ACTION_MPLSOUDP_DECAP, 2258 ACTION_SET_IPV4_SRC, 2259 ACTION_SET_IPV4_DST, 2260 ACTION_SET_IPV6_SRC, 2261 ACTION_SET_IPV6_DST, 2262 ACTION_SET_TP_SRC, 2263 ACTION_SET_TP_DST, 2264 ACTION_MAC_SWAP, 2265 ACTION_DEC_TTL, 2266 ACTION_SET_TTL, 2267 ACTION_SET_MAC_SRC, 2268 ACTION_SET_MAC_DST, 2269 ACTION_INC_TCP_SEQ, 2270 ACTION_DEC_TCP_SEQ, 2271 ACTION_INC_TCP_ACK, 2272 ACTION_DEC_TCP_ACK, 2273 ACTION_RAW_ENCAP, 2274 ACTION_RAW_DECAP, 2275 ACTION_SET_TAG, 2276 ACTION_SET_META, 2277 ACTION_SET_IPV4_DSCP, 2278 ACTION_SET_IPV6_DSCP, 2279 ACTION_AGE, 2280 ACTION_AGE_UPDATE, 2281 ACTION_SAMPLE, 2282 ACTION_INDIRECT, 2283 ACTION_INDIRECT_LIST, 2284 ACTION_SHARED_INDIRECT, 2285 ACTION_MODIFY_FIELD, 2286 ACTION_CONNTRACK, 2287 ACTION_CONNTRACK_UPDATE, 2288 ACTION_PORT_REPRESENTOR, 2289 ACTION_REPRESENTED_PORT, 2290 ACTION_SEND_TO_KERNEL, 2291 ACTION_QUOTA_CREATE, 2292 ACTION_QUOTA_QU, 2293 ACTION_IPV6_EXT_REMOVE, 2294 ACTION_IPV6_EXT_PUSH, 2295 ACTION_NAT64, 2296 ZERO, 2297 }; 2298 2299 static const enum index action_quota_create[] = { 2300 ACTION_QUOTA_CREATE_LIMIT, 2301 ACTION_QUOTA_CREATE_MODE, 2302 ACTION_NEXT, 2303 ZERO 2304 }; 2305 2306 static const enum index action_quota_update[] = { 2307 ACTION_QUOTA_QU_LIMIT, 2308 ACTION_QUOTA_QU_UPDATE_OP, 2309 ACTION_NEXT, 2310 ZERO 2311 }; 2312 2313 static const enum index action_mark[] = { 2314 ACTION_MARK_ID, 2315 ACTION_NEXT, 2316 ZERO, 2317 }; 2318 2319 static const enum index action_queue[] = { 2320 ACTION_QUEUE_INDEX, 2321 ACTION_NEXT, 2322 ZERO, 2323 }; 2324 2325 static const enum index action_count[] = { 2326 ACTION_COUNT_ID, 2327 ACTION_NEXT, 2328 ZERO, 2329 }; 2330 2331 static const enum index action_rss[] = { 2332 ACTION_RSS_FUNC, 2333 ACTION_RSS_LEVEL, 2334 ACTION_RSS_TYPES, 2335 ACTION_RSS_KEY, 2336 ACTION_RSS_KEY_LEN, 2337 ACTION_RSS_QUEUES, 2338 ACTION_NEXT, 2339 ZERO, 2340 }; 2341 2342 static const enum index action_vf[] = { 2343 ACTION_VF_ORIGINAL, 2344 ACTION_VF_ID, 2345 ACTION_NEXT, 2346 ZERO, 2347 }; 2348 2349 static const enum index action_port_id[] = { 2350 ACTION_PORT_ID_ORIGINAL, 2351 ACTION_PORT_ID_ID, 2352 ACTION_NEXT, 2353 ZERO, 2354 }; 2355 2356 static const enum index action_meter[] = { 2357 ACTION_METER_ID, 2358 ACTION_NEXT, 2359 ZERO, 2360 }; 2361 2362 static const enum index action_meter_color[] = { 2363 ACTION_METER_COLOR_TYPE, 2364 ACTION_NEXT, 2365 ZERO, 2366 }; 2367 2368 static const enum index action_meter_mark[] = { 2369 ACTION_METER_PROFILE, 2370 ACTION_METER_POLICY, 2371 ACTION_METER_COLOR_MODE, 2372 ACTION_METER_STATE, 2373 ACTION_NEXT, 2374 ZERO, 2375 }; 2376 2377 static const enum index action_of_push_vlan[] = { 2378 ACTION_OF_PUSH_VLAN_ETHERTYPE, 2379 ACTION_NEXT, 2380 ZERO, 2381 }; 2382 2383 static const enum index action_of_set_vlan_vid[] = { 2384 ACTION_OF_SET_VLAN_VID_VLAN_VID, 2385 ACTION_NEXT, 2386 ZERO, 2387 }; 2388 2389 static const enum index action_of_set_vlan_pcp[] = { 2390 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 2391 ACTION_NEXT, 2392 ZERO, 2393 }; 2394 2395 static const enum index action_of_pop_mpls[] = { 2396 ACTION_OF_POP_MPLS_ETHERTYPE, 2397 ACTION_NEXT, 2398 ZERO, 2399 }; 2400 2401 static const enum index action_of_push_mpls[] = { 2402 ACTION_OF_PUSH_MPLS_ETHERTYPE, 2403 ACTION_NEXT, 2404 ZERO, 2405 }; 2406 2407 static const enum index action_set_ipv4_src[] = { 2408 ACTION_SET_IPV4_SRC_IPV4_SRC, 2409 ACTION_NEXT, 2410 ZERO, 2411 }; 2412 2413 static const enum index action_set_mac_src[] = { 2414 ACTION_SET_MAC_SRC_MAC_SRC, 2415 ACTION_NEXT, 2416 ZERO, 2417 }; 2418 2419 static const enum index action_set_ipv4_dst[] = { 2420 ACTION_SET_IPV4_DST_IPV4_DST, 2421 ACTION_NEXT, 2422 ZERO, 2423 }; 2424 2425 static const enum index action_set_ipv6_src[] = { 2426 ACTION_SET_IPV6_SRC_IPV6_SRC, 2427 ACTION_NEXT, 2428 ZERO, 2429 }; 2430 2431 static const enum index action_set_ipv6_dst[] = { 2432 ACTION_SET_IPV6_DST_IPV6_DST, 2433 ACTION_NEXT, 2434 ZERO, 2435 }; 2436 2437 static const enum index action_set_tp_src[] = { 2438 ACTION_SET_TP_SRC_TP_SRC, 2439 ACTION_NEXT, 2440 ZERO, 2441 }; 2442 2443 static const enum index action_set_tp_dst[] = { 2444 ACTION_SET_TP_DST_TP_DST, 2445 ACTION_NEXT, 2446 ZERO, 2447 }; 2448 2449 static const enum index action_set_ttl[] = { 2450 ACTION_SET_TTL_TTL, 2451 ACTION_NEXT, 2452 ZERO, 2453 }; 2454 2455 static const enum index action_jump[] = { 2456 ACTION_JUMP_GROUP, 2457 ACTION_NEXT, 2458 ZERO, 2459 }; 2460 2461 static const enum index action_set_mac_dst[] = { 2462 ACTION_SET_MAC_DST_MAC_DST, 2463 ACTION_NEXT, 2464 ZERO, 2465 }; 2466 2467 static const enum index action_inc_tcp_seq[] = { 2468 ACTION_INC_TCP_SEQ_VALUE, 2469 ACTION_NEXT, 2470 ZERO, 2471 }; 2472 2473 static const enum index action_dec_tcp_seq[] = { 2474 ACTION_DEC_TCP_SEQ_VALUE, 2475 ACTION_NEXT, 2476 ZERO, 2477 }; 2478 2479 static const enum index action_inc_tcp_ack[] = { 2480 ACTION_INC_TCP_ACK_VALUE, 2481 ACTION_NEXT, 2482 ZERO, 2483 }; 2484 2485 static const enum index action_dec_tcp_ack[] = { 2486 ACTION_DEC_TCP_ACK_VALUE, 2487 ACTION_NEXT, 2488 ZERO, 2489 }; 2490 2491 static const enum index action_raw_encap[] = { 2492 ACTION_RAW_ENCAP_SIZE, 2493 ACTION_RAW_ENCAP_INDEX, 2494 ACTION_NEXT, 2495 ZERO, 2496 }; 2497 2498 static const enum index action_raw_decap[] = { 2499 ACTION_RAW_DECAP_INDEX, 2500 ACTION_NEXT, 2501 ZERO, 2502 }; 2503 2504 static const enum index action_ipv6_ext_remove[] = { 2505 ACTION_IPV6_EXT_REMOVE_INDEX, 2506 ACTION_NEXT, 2507 ZERO, 2508 }; 2509 2510 static const enum index action_ipv6_ext_push[] = { 2511 ACTION_IPV6_EXT_PUSH_INDEX, 2512 ACTION_NEXT, 2513 ZERO, 2514 }; 2515 2516 static const enum index action_set_tag[] = { 2517 ACTION_SET_TAG_DATA, 2518 ACTION_SET_TAG_INDEX, 2519 ACTION_SET_TAG_MASK, 2520 ACTION_NEXT, 2521 ZERO, 2522 }; 2523 2524 static const enum index action_set_meta[] = { 2525 ACTION_SET_META_DATA, 2526 ACTION_SET_META_MASK, 2527 ACTION_NEXT, 2528 ZERO, 2529 }; 2530 2531 static const enum index action_set_ipv4_dscp[] = { 2532 ACTION_SET_IPV4_DSCP_VALUE, 2533 ACTION_NEXT, 2534 ZERO, 2535 }; 2536 2537 static const enum index action_set_ipv6_dscp[] = { 2538 ACTION_SET_IPV6_DSCP_VALUE, 2539 ACTION_NEXT, 2540 ZERO, 2541 }; 2542 2543 static const enum index action_age[] = { 2544 ACTION_AGE, 2545 ACTION_AGE_TIMEOUT, 2546 ACTION_NEXT, 2547 ZERO, 2548 }; 2549 2550 static const enum index action_age_update[] = { 2551 ACTION_AGE_UPDATE, 2552 ACTION_AGE_UPDATE_TIMEOUT, 2553 ACTION_AGE_UPDATE_TOUCH, 2554 ACTION_NEXT, 2555 ZERO, 2556 }; 2557 2558 static const enum index action_sample[] = { 2559 ACTION_SAMPLE, 2560 ACTION_SAMPLE_RATIO, 2561 ACTION_SAMPLE_INDEX, 2562 ACTION_NEXT, 2563 ZERO, 2564 }; 2565 2566 static const enum index next_action_sample[] = { 2567 ACTION_QUEUE, 2568 ACTION_RSS, 2569 ACTION_MARK, 2570 ACTION_COUNT, 2571 ACTION_PORT_ID, 2572 ACTION_RAW_ENCAP, 2573 ACTION_VXLAN_ENCAP, 2574 ACTION_NVGRE_ENCAP, 2575 ACTION_REPRESENTED_PORT, 2576 ACTION_PORT_REPRESENTOR, 2577 ACTION_NEXT, 2578 ZERO, 2579 }; 2580 2581 static const enum index item_ipv6_push_ext[] = { 2582 ITEM_IPV6_PUSH_REMOVE_EXT, 2583 ZERO, 2584 }; 2585 2586 static const enum index item_ipv6_push_ext_type[] = { 2587 ITEM_IPV6_PUSH_REMOVE_EXT_TYPE, 2588 ZERO, 2589 }; 2590 2591 static const enum index item_ipv6_push_ext_header[] = { 2592 ITEM_IPV6_ROUTING_EXT, 2593 ITEM_NEXT, 2594 ZERO, 2595 }; 2596 2597 static const enum index action_modify_field_dst[] = { 2598 ACTION_MODIFY_FIELD_DST_LEVEL, 2599 ACTION_MODIFY_FIELD_DST_TAG_INDEX, 2600 ACTION_MODIFY_FIELD_DST_TYPE_ID, 2601 ACTION_MODIFY_FIELD_DST_CLASS_ID, 2602 ACTION_MODIFY_FIELD_DST_OFFSET, 2603 ACTION_MODIFY_FIELD_SRC_TYPE, 2604 ZERO, 2605 }; 2606 2607 static const enum index action_modify_field_src[] = { 2608 ACTION_MODIFY_FIELD_SRC_LEVEL, 2609 ACTION_MODIFY_FIELD_SRC_TAG_INDEX, 2610 ACTION_MODIFY_FIELD_SRC_TYPE_ID, 2611 ACTION_MODIFY_FIELD_SRC_CLASS_ID, 2612 ACTION_MODIFY_FIELD_SRC_OFFSET, 2613 ACTION_MODIFY_FIELD_SRC_VALUE, 2614 ACTION_MODIFY_FIELD_SRC_POINTER, 2615 ACTION_MODIFY_FIELD_WIDTH, 2616 ZERO, 2617 }; 2618 2619 static const enum index action_update_conntrack[] = { 2620 ACTION_CONNTRACK_UPDATE_DIR, 2621 ACTION_CONNTRACK_UPDATE_CTX, 2622 ACTION_NEXT, 2623 ZERO, 2624 }; 2625 2626 static const enum index action_port_representor[] = { 2627 ACTION_PORT_REPRESENTOR_PORT_ID, 2628 ACTION_NEXT, 2629 ZERO, 2630 }; 2631 2632 static const enum index action_represented_port[] = { 2633 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 2634 ACTION_NEXT, 2635 ZERO, 2636 }; 2637 2638 static const enum index action_nat64[] = { 2639 ACTION_NAT64_MODE, 2640 ACTION_NEXT, 2641 ZERO, 2642 }; 2643 2644 static const enum index next_hash_subcmd[] = { 2645 HASH_CALC_TABLE, 2646 HASH_CALC_ENCAP, 2647 ZERO, 2648 }; 2649 2650 static const enum index next_hash_encap_dest_subcmd[] = { 2651 ENCAP_HASH_FIELD_SRC_PORT, 2652 ENCAP_HASH_FIELD_GRE_FLOW_ID, 2653 ZERO, 2654 }; 2655 2656 static int parse_set_raw_encap_decap(struct context *, const struct token *, 2657 const char *, unsigned int, 2658 void *, unsigned int); 2659 static int parse_set_sample_action(struct context *, const struct token *, 2660 const char *, unsigned int, 2661 void *, unsigned int); 2662 static int parse_set_ipv6_ext_action(struct context *, const struct token *, 2663 const char *, unsigned int, 2664 void *, unsigned int); 2665 static int parse_set_init(struct context *, const struct token *, 2666 const char *, unsigned int, 2667 void *, unsigned int); 2668 static int 2669 parse_flex_handle(struct context *, const struct token *, 2670 const char *, unsigned int, void *, unsigned int); 2671 static int parse_init(struct context *, const struct token *, 2672 const char *, unsigned int, 2673 void *, unsigned int); 2674 static int parse_vc(struct context *, const struct token *, 2675 const char *, unsigned int, 2676 void *, unsigned int); 2677 static int parse_vc_spec(struct context *, const struct token *, 2678 const char *, unsigned int, void *, unsigned int); 2679 static int parse_vc_conf(struct context *, const struct token *, 2680 const char *, unsigned int, void *, unsigned int); 2681 static int parse_vc_conf_timeout(struct context *, const struct token *, 2682 const char *, unsigned int, void *, 2683 unsigned int); 2684 static int parse_vc_item_ecpri_type(struct context *, const struct token *, 2685 const char *, unsigned int, 2686 void *, unsigned int); 2687 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, 2688 const char *, unsigned int, 2689 void *, unsigned int); 2690 static int parse_vc_action_meter_color_type(struct context *, 2691 const struct token *, 2692 const char *, unsigned int, void *, 2693 unsigned int); 2694 static int parse_vc_action_rss(struct context *, const struct token *, 2695 const char *, unsigned int, void *, 2696 unsigned int); 2697 static int parse_vc_action_rss_func(struct context *, const struct token *, 2698 const char *, unsigned int, void *, 2699 unsigned int); 2700 static int parse_vc_action_rss_type(struct context *, const struct token *, 2701 const char *, unsigned int, void *, 2702 unsigned int); 2703 static int parse_vc_action_rss_queue(struct context *, const struct token *, 2704 const char *, unsigned int, void *, 2705 unsigned int); 2706 static int parse_vc_action_vxlan_encap(struct context *, const struct token *, 2707 const char *, unsigned int, void *, 2708 unsigned int); 2709 static int parse_vc_action_nvgre_encap(struct context *, const struct token *, 2710 const char *, unsigned int, void *, 2711 unsigned int); 2712 static int parse_vc_action_l2_encap(struct context *, const struct token *, 2713 const char *, unsigned int, void *, 2714 unsigned int); 2715 static int parse_vc_action_l2_decap(struct context *, const struct token *, 2716 const char *, unsigned int, void *, 2717 unsigned int); 2718 static int parse_vc_action_mplsogre_encap(struct context *, 2719 const struct token *, const char *, 2720 unsigned int, void *, unsigned int); 2721 static int parse_vc_action_mplsogre_decap(struct context *, 2722 const struct token *, const char *, 2723 unsigned int, void *, unsigned int); 2724 static int parse_vc_action_mplsoudp_encap(struct context *, 2725 const struct token *, const char *, 2726 unsigned int, void *, unsigned int); 2727 static int parse_vc_action_mplsoudp_decap(struct context *, 2728 const struct token *, const char *, 2729 unsigned int, void *, unsigned int); 2730 static int parse_vc_action_raw_encap(struct context *, 2731 const struct token *, const char *, 2732 unsigned int, void *, unsigned int); 2733 static int parse_vc_action_raw_decap(struct context *, 2734 const struct token *, const char *, 2735 unsigned int, void *, unsigned int); 2736 static int parse_vc_action_raw_encap_index(struct context *, 2737 const struct token *, const char *, 2738 unsigned int, void *, unsigned int); 2739 static int parse_vc_action_raw_decap_index(struct context *, 2740 const struct token *, const char *, 2741 unsigned int, void *, unsigned int); 2742 static int parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 2743 const char *str, unsigned int len, void *buf, 2744 unsigned int size); 2745 static int parse_vc_action_ipv6_ext_remove_index(struct context *ctx, 2746 const struct token *token, 2747 const char *str, unsigned int len, 2748 void *buf, 2749 unsigned int size); 2750 static int parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 2751 const char *str, unsigned int len, void *buf, 2752 unsigned int size); 2753 static int parse_vc_action_ipv6_ext_push_index(struct context *ctx, 2754 const struct token *token, 2755 const char *str, unsigned int len, 2756 void *buf, 2757 unsigned int size); 2758 static int parse_vc_action_set_meta(struct context *ctx, 2759 const struct token *token, const char *str, 2760 unsigned int len, void *buf, 2761 unsigned int size); 2762 static int parse_vc_action_sample(struct context *ctx, 2763 const struct token *token, const char *str, 2764 unsigned int len, void *buf, 2765 unsigned int size); 2766 static int 2767 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 2768 const char *str, unsigned int len, void *buf, 2769 unsigned int size); 2770 static int 2771 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 2772 const char *str, unsigned int len, void *buf, 2773 unsigned int size); 2774 static int 2775 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 2776 const char *str, unsigned int len, void *buf, 2777 unsigned int size); 2778 static int 2779 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 2780 const char *str, unsigned int len, void *buf, 2781 unsigned int size); 2782 static int 2783 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 2784 const char *str, unsigned int len, void *buf, 2785 unsigned int size); 2786 static int parse_destroy(struct context *, const struct token *, 2787 const char *, unsigned int, 2788 void *, unsigned int); 2789 static int parse_flush(struct context *, const struct token *, 2790 const char *, unsigned int, 2791 void *, unsigned int); 2792 static int parse_dump(struct context *, const struct token *, 2793 const char *, unsigned int, 2794 void *, unsigned int); 2795 static int parse_query(struct context *, const struct token *, 2796 const char *, unsigned int, 2797 void *, unsigned int); 2798 static int parse_action(struct context *, const struct token *, 2799 const char *, unsigned int, 2800 void *, unsigned int); 2801 static int parse_list(struct context *, const struct token *, 2802 const char *, unsigned int, 2803 void *, unsigned int); 2804 static int parse_aged(struct context *, const struct token *, 2805 const char *, unsigned int, 2806 void *, unsigned int); 2807 static int parse_isolate(struct context *, const struct token *, 2808 const char *, unsigned int, 2809 void *, unsigned int); 2810 static int parse_configure(struct context *, const struct token *, 2811 const char *, unsigned int, 2812 void *, unsigned int); 2813 static int parse_template(struct context *, const struct token *, 2814 const char *, unsigned int, 2815 void *, unsigned int); 2816 static int parse_template_destroy(struct context *, const struct token *, 2817 const char *, unsigned int, 2818 void *, unsigned int); 2819 static int parse_table(struct context *, const struct token *, 2820 const char *, unsigned int, void *, unsigned int); 2821 static int parse_table_destroy(struct context *, const struct token *, 2822 const char *, unsigned int, 2823 void *, unsigned int); 2824 static int parse_qo(struct context *, const struct token *, 2825 const char *, unsigned int, 2826 void *, unsigned int); 2827 static int parse_qo_destroy(struct context *, const struct token *, 2828 const char *, unsigned int, 2829 void *, unsigned int); 2830 static int parse_qia(struct context *, const struct token *, 2831 const char *, unsigned int, 2832 void *, unsigned int); 2833 static int parse_qia_destroy(struct context *, const struct token *, 2834 const char *, unsigned int, 2835 void *, unsigned int); 2836 static int parse_push(struct context *, const struct token *, 2837 const char *, unsigned int, 2838 void *, unsigned int); 2839 static int parse_pull(struct context *, const struct token *, 2840 const char *, unsigned int, 2841 void *, unsigned int); 2842 static int parse_group(struct context *, const struct token *, 2843 const char *, unsigned int, 2844 void *, unsigned int); 2845 static int parse_hash(struct context *, const struct token *, 2846 const char *, unsigned int, 2847 void *, unsigned int); 2848 static int parse_tunnel(struct context *, const struct token *, 2849 const char *, unsigned int, 2850 void *, unsigned int); 2851 static int parse_flex(struct context *, const struct token *, 2852 const char *, unsigned int, void *, unsigned int); 2853 static int parse_int(struct context *, const struct token *, 2854 const char *, unsigned int, 2855 void *, unsigned int); 2856 static int parse_prefix(struct context *, const struct token *, 2857 const char *, unsigned int, 2858 void *, unsigned int); 2859 static int parse_boolean(struct context *, const struct token *, 2860 const char *, unsigned int, 2861 void *, unsigned int); 2862 static int parse_string(struct context *, const struct token *, 2863 const char *, unsigned int, 2864 void *, unsigned int); 2865 static int parse_hex(struct context *ctx, const struct token *token, 2866 const char *str, unsigned int len, 2867 void *buf, unsigned int size); 2868 static int parse_string0(struct context *, const struct token *, 2869 const char *, unsigned int, 2870 void *, unsigned int); 2871 static int parse_mac_addr(struct context *, const struct token *, 2872 const char *, unsigned int, 2873 void *, unsigned int); 2874 static int parse_ipv4_addr(struct context *, const struct token *, 2875 const char *, unsigned int, 2876 void *, unsigned int); 2877 static int parse_ipv6_addr(struct context *, const struct token *, 2878 const char *, unsigned int, 2879 void *, unsigned int); 2880 static int parse_port(struct context *, const struct token *, 2881 const char *, unsigned int, 2882 void *, unsigned int); 2883 static int parse_ia(struct context *, const struct token *, 2884 const char *, unsigned int, 2885 void *, unsigned int); 2886 static int parse_ia_destroy(struct context *ctx, const struct token *token, 2887 const char *str, unsigned int len, 2888 void *buf, unsigned int size); 2889 static int parse_ia_id2ptr(struct context *ctx, const struct token *token, 2890 const char *str, unsigned int len, void *buf, 2891 unsigned int size); 2892 2893 static int parse_indlst_id2ptr(struct context *ctx, const struct token *token, 2894 const char *str, unsigned int len, void *buf, 2895 unsigned int size); 2896 static int parse_ia_port(struct context *ctx, const struct token *token, 2897 const char *str, unsigned int len, void *buf, 2898 unsigned int size); 2899 static int parse_mp(struct context *, const struct token *, 2900 const char *, unsigned int, 2901 void *, unsigned int); 2902 static int parse_meter_profile_id2ptr(struct context *ctx, 2903 const struct token *token, 2904 const char *str, unsigned int len, 2905 void *buf, unsigned int size); 2906 static int parse_meter_policy_id2ptr(struct context *ctx, 2907 const struct token *token, 2908 const char *str, unsigned int len, 2909 void *buf, unsigned int size); 2910 static int parse_meter_color(struct context *ctx, const struct token *token, 2911 const char *str, unsigned int len, void *buf, 2912 unsigned int size); 2913 static int parse_insertion_table_type(struct context *ctx, const struct token *token, 2914 const char *str, unsigned int len, void *buf, 2915 unsigned int size); 2916 static int parse_hash_table_type(struct context *ctx, const struct token *token, 2917 const char *str, unsigned int len, void *buf, 2918 unsigned int size); 2919 static int 2920 parse_quota_state_name(struct context *ctx, const struct token *token, 2921 const char *str, unsigned int len, void *buf, 2922 unsigned int size); 2923 static int 2924 parse_quota_mode_name(struct context *ctx, const struct token *token, 2925 const char *str, unsigned int len, void *buf, 2926 unsigned int size); 2927 static int 2928 parse_quota_update_name(struct context *ctx, const struct token *token, 2929 const char *str, unsigned int len, void *buf, 2930 unsigned int size); 2931 static int 2932 parse_qu_mode_name(struct context *ctx, const struct token *token, 2933 const char *str, unsigned int len, void *buf, 2934 unsigned int size); 2935 static int comp_none(struct context *, const struct token *, 2936 unsigned int, char *, unsigned int); 2937 static int comp_boolean(struct context *, const struct token *, 2938 unsigned int, char *, unsigned int); 2939 static int comp_action(struct context *, const struct token *, 2940 unsigned int, char *, unsigned int); 2941 static int comp_port(struct context *, const struct token *, 2942 unsigned int, char *, unsigned int); 2943 static int comp_rule_id(struct context *, const struct token *, 2944 unsigned int, char *, unsigned int); 2945 static int comp_vc_action_rss_type(struct context *, const struct token *, 2946 unsigned int, char *, unsigned int); 2947 static int comp_vc_action_rss_queue(struct context *, const struct token *, 2948 unsigned int, char *, unsigned int); 2949 static int comp_set_raw_index(struct context *, const struct token *, 2950 unsigned int, char *, unsigned int); 2951 static int comp_set_sample_index(struct context *, const struct token *, 2952 unsigned int, char *, unsigned int); 2953 static int comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 2954 unsigned int ent, char *buf, unsigned int size); 2955 static int comp_set_modify_field_op(struct context *, const struct token *, 2956 unsigned int, char *, unsigned int); 2957 static int comp_set_modify_field_id(struct context *, const struct token *, 2958 unsigned int, char *, unsigned int); 2959 static int comp_pattern_template_id(struct context *, const struct token *, 2960 unsigned int, char *, unsigned int); 2961 static int comp_actions_template_id(struct context *, const struct token *, 2962 unsigned int, char *, unsigned int); 2963 static int comp_table_id(struct context *, const struct token *, 2964 unsigned int, char *, unsigned int); 2965 static int comp_queue_id(struct context *, const struct token *, 2966 unsigned int, char *, unsigned int); 2967 static int comp_meter_color(struct context *, const struct token *, 2968 unsigned int, char *, unsigned int); 2969 static int comp_insertion_table_type(struct context *, const struct token *, 2970 unsigned int, char *, unsigned int); 2971 static int comp_hash_table_type(struct context *, const struct token *, 2972 unsigned int, char *, unsigned int); 2973 static int 2974 comp_quota_state_name(struct context *ctx, const struct token *token, 2975 unsigned int ent, char *buf, unsigned int size); 2976 static int 2977 comp_quota_mode_name(struct context *ctx, const struct token *token, 2978 unsigned int ent, char *buf, unsigned int size); 2979 static int 2980 comp_quota_update_name(struct context *ctx, const struct token *token, 2981 unsigned int ent, char *buf, unsigned int size); 2982 static int 2983 comp_qu_mode_name(struct context *ctx, const struct token *token, 2984 unsigned int ent, char *buf, unsigned int size); 2985 static int 2986 comp_set_compare_field_id(struct context *ctx, const struct token *token, 2987 unsigned int ent, char *buf, unsigned int size); 2988 static int 2989 comp_set_compare_op(struct context *ctx, const struct token *token, 2990 unsigned int ent, char *buf, unsigned int size); 2991 static int 2992 parse_vc_compare_op(struct context *ctx, const struct token *token, 2993 const char *str, unsigned int len, void *buf, 2994 unsigned int size); 2995 static int 2996 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 2997 const char *str, unsigned int len, void *buf, 2998 unsigned int size); 2999 static int 3000 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 3001 const char *str, unsigned int len, void *buf, 3002 unsigned int size); 3003 3004 struct indlst_conf { 3005 uint32_t id; 3006 uint32_t conf_num; 3007 struct rte_flow_action *actions; 3008 const void **conf; 3009 SLIST_ENTRY(indlst_conf) next; 3010 }; 3011 3012 static const struct indlst_conf *indirect_action_list_conf_get(uint32_t conf_id); 3013 3014 /** Token definitions. */ 3015 static const struct token token_list[] = { 3016 /* Special tokens. */ 3017 [ZERO] = { 3018 .name = "ZERO", 3019 .help = "null entry, abused as the entry point", 3020 .next = NEXT(NEXT_ENTRY(FLOW, ADD)), 3021 }, 3022 [END] = { 3023 .name = "", 3024 .type = "RETURN", 3025 .help = "command may end here", 3026 }, 3027 [START_SET] = { 3028 .name = "START_SET", 3029 .help = "null entry, abused as the entry point for set", 3030 .next = NEXT(NEXT_ENTRY(SET)), 3031 }, 3032 [END_SET] = { 3033 .name = "end_set", 3034 .type = "RETURN", 3035 .help = "set command may end here", 3036 }, 3037 /* Common tokens. */ 3038 [COMMON_INTEGER] = { 3039 .name = "{int}", 3040 .type = "INTEGER", 3041 .help = "integer value", 3042 .call = parse_int, 3043 .comp = comp_none, 3044 }, 3045 [COMMON_UNSIGNED] = { 3046 .name = "{unsigned}", 3047 .type = "UNSIGNED", 3048 .help = "unsigned integer value", 3049 .call = parse_int, 3050 .comp = comp_none, 3051 }, 3052 [COMMON_PREFIX] = { 3053 .name = "{prefix}", 3054 .type = "PREFIX", 3055 .help = "prefix length for bit-mask", 3056 .call = parse_prefix, 3057 .comp = comp_none, 3058 }, 3059 [COMMON_BOOLEAN] = { 3060 .name = "{boolean}", 3061 .type = "BOOLEAN", 3062 .help = "any boolean value", 3063 .call = parse_boolean, 3064 .comp = comp_boolean, 3065 }, 3066 [COMMON_STRING] = { 3067 .name = "{string}", 3068 .type = "STRING", 3069 .help = "fixed string", 3070 .call = parse_string, 3071 .comp = comp_none, 3072 }, 3073 [COMMON_HEX] = { 3074 .name = "{hex}", 3075 .type = "HEX", 3076 .help = "fixed string", 3077 .call = parse_hex, 3078 }, 3079 [COMMON_FILE_PATH] = { 3080 .name = "{file path}", 3081 .type = "STRING", 3082 .help = "file path", 3083 .call = parse_string0, 3084 .comp = comp_none, 3085 }, 3086 [COMMON_MAC_ADDR] = { 3087 .name = "{MAC address}", 3088 .type = "MAC-48", 3089 .help = "standard MAC address notation", 3090 .call = parse_mac_addr, 3091 .comp = comp_none, 3092 }, 3093 [COMMON_IPV4_ADDR] = { 3094 .name = "{IPv4 address}", 3095 .type = "IPV4 ADDRESS", 3096 .help = "standard IPv4 address notation", 3097 .call = parse_ipv4_addr, 3098 .comp = comp_none, 3099 }, 3100 [COMMON_IPV6_ADDR] = { 3101 .name = "{IPv6 address}", 3102 .type = "IPV6 ADDRESS", 3103 .help = "standard IPv6 address notation", 3104 .call = parse_ipv6_addr, 3105 .comp = comp_none, 3106 }, 3107 [COMMON_RULE_ID] = { 3108 .name = "{rule id}", 3109 .type = "RULE ID", 3110 .help = "rule identifier", 3111 .call = parse_int, 3112 .comp = comp_rule_id, 3113 }, 3114 [COMMON_PORT_ID] = { 3115 .name = "{port_id}", 3116 .type = "PORT ID", 3117 .help = "port identifier", 3118 .call = parse_port, 3119 .comp = comp_port, 3120 }, 3121 [COMMON_GROUP_ID] = { 3122 .name = "{group_id}", 3123 .type = "GROUP ID", 3124 .help = "group identifier", 3125 .call = parse_int, 3126 .comp = comp_none, 3127 }, 3128 [COMMON_PRIORITY_LEVEL] = { 3129 .name = "{level}", 3130 .type = "PRIORITY", 3131 .help = "priority level", 3132 .call = parse_int, 3133 .comp = comp_none, 3134 }, 3135 [COMMON_INDIRECT_ACTION_ID] = { 3136 .name = "{indirect_action_id}", 3137 .type = "INDIRECT_ACTION_ID", 3138 .help = "indirect action id", 3139 .call = parse_int, 3140 .comp = comp_none, 3141 }, 3142 [COMMON_PROFILE_ID] = { 3143 .name = "{profile_id}", 3144 .type = "PROFILE_ID", 3145 .help = "profile id", 3146 .call = parse_int, 3147 .comp = comp_none, 3148 }, 3149 [COMMON_POLICY_ID] = { 3150 .name = "{policy_id}", 3151 .type = "POLICY_ID", 3152 .help = "policy id", 3153 .call = parse_int, 3154 .comp = comp_none, 3155 }, 3156 [COMMON_FLEX_TOKEN] = { 3157 .name = "{flex token}", 3158 .type = "flex token", 3159 .help = "flex token", 3160 .call = parse_int, 3161 .comp = comp_none, 3162 }, 3163 [COMMON_FLEX_HANDLE] = { 3164 .name = "{flex handle}", 3165 .type = "FLEX HANDLE", 3166 .help = "fill flex item data", 3167 .call = parse_flex_handle, 3168 .comp = comp_none, 3169 }, 3170 [COMMON_PATTERN_TEMPLATE_ID] = { 3171 .name = "{pattern_template_id}", 3172 .type = "PATTERN_TEMPLATE_ID", 3173 .help = "pattern template id", 3174 .call = parse_int, 3175 .comp = comp_pattern_template_id, 3176 }, 3177 [COMMON_ACTIONS_TEMPLATE_ID] = { 3178 .name = "{actions_template_id}", 3179 .type = "ACTIONS_TEMPLATE_ID", 3180 .help = "actions template id", 3181 .call = parse_int, 3182 .comp = comp_actions_template_id, 3183 }, 3184 [COMMON_TABLE_ID] = { 3185 .name = "{table_id}", 3186 .type = "TABLE_ID", 3187 .help = "table id", 3188 .call = parse_int, 3189 .comp = comp_table_id, 3190 }, 3191 [COMMON_QUEUE_ID] = { 3192 .name = "{queue_id}", 3193 .type = "QUEUE_ID", 3194 .help = "queue id", 3195 .call = parse_int, 3196 .comp = comp_queue_id, 3197 }, 3198 /* Top-level command. */ 3199 [FLOW] = { 3200 .name = "flow", 3201 .type = "{command} {port_id} [{arg} [...]]", 3202 .help = "manage ingress/egress flow rules", 3203 .next = NEXT(NEXT_ENTRY 3204 (INFO, 3205 CONFIGURE, 3206 PATTERN_TEMPLATE, 3207 ACTIONS_TEMPLATE, 3208 TABLE, 3209 FLOW_GROUP, 3210 INDIRECT_ACTION, 3211 VALIDATE, 3212 CREATE, 3213 DESTROY, 3214 UPDATE, 3215 FLUSH, 3216 DUMP, 3217 LIST, 3218 AGED, 3219 QUERY, 3220 ISOLATE, 3221 TUNNEL, 3222 FLEX, 3223 QUEUE, 3224 PUSH, 3225 PULL, 3226 HASH)), 3227 .call = parse_init, 3228 }, 3229 /* Top-level command. */ 3230 [INFO] = { 3231 .name = "info", 3232 .help = "get information about flow engine", 3233 .next = NEXT(NEXT_ENTRY(END), 3234 NEXT_ENTRY(COMMON_PORT_ID)), 3235 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3236 .call = parse_configure, 3237 }, 3238 /* Top-level command. */ 3239 [CONFIGURE] = { 3240 .name = "configure", 3241 .help = "configure flow engine", 3242 .next = NEXT(next_config_attr, 3243 NEXT_ENTRY(COMMON_PORT_ID)), 3244 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3245 .call = parse_configure, 3246 }, 3247 /* Configure arguments. */ 3248 [CONFIG_QUEUES_NUMBER] = { 3249 .name = "queues_number", 3250 .help = "number of queues", 3251 .next = NEXT(next_config_attr, 3252 NEXT_ENTRY(COMMON_UNSIGNED)), 3253 .args = ARGS(ARGS_ENTRY(struct buffer, 3254 args.configure.nb_queue)), 3255 }, 3256 [CONFIG_QUEUES_SIZE] = { 3257 .name = "queues_size", 3258 .help = "number of elements in queues", 3259 .next = NEXT(next_config_attr, 3260 NEXT_ENTRY(COMMON_UNSIGNED)), 3261 .args = ARGS(ARGS_ENTRY(struct buffer, 3262 args.configure.queue_attr.size)), 3263 }, 3264 [CONFIG_COUNTERS_NUMBER] = { 3265 .name = "counters_number", 3266 .help = "number of counters", 3267 .next = NEXT(next_config_attr, 3268 NEXT_ENTRY(COMMON_UNSIGNED)), 3269 .args = ARGS(ARGS_ENTRY(struct buffer, 3270 args.configure.port_attr.nb_counters)), 3271 }, 3272 [CONFIG_AGING_OBJECTS_NUMBER] = { 3273 .name = "aging_counters_number", 3274 .help = "number of aging objects", 3275 .next = NEXT(next_config_attr, 3276 NEXT_ENTRY(COMMON_UNSIGNED)), 3277 .args = ARGS(ARGS_ENTRY(struct buffer, 3278 args.configure.port_attr.nb_aging_objects)), 3279 }, 3280 [CONFIG_QUOTAS_NUMBER] = { 3281 .name = "quotas_number", 3282 .help = "number of quotas", 3283 .next = NEXT(next_config_attr, 3284 NEXT_ENTRY(COMMON_UNSIGNED)), 3285 .args = ARGS(ARGS_ENTRY(struct buffer, 3286 args.configure.port_attr.nb_quotas)), 3287 }, 3288 [CONFIG_METERS_NUMBER] = { 3289 .name = "meters_number", 3290 .help = "number of meters", 3291 .next = NEXT(next_config_attr, 3292 NEXT_ENTRY(COMMON_UNSIGNED)), 3293 .args = ARGS(ARGS_ENTRY(struct buffer, 3294 args.configure.port_attr.nb_meters)), 3295 }, 3296 [CONFIG_CONN_TRACK_NUMBER] = { 3297 .name = "conn_tracks_number", 3298 .help = "number of connection trackings", 3299 .next = NEXT(next_config_attr, 3300 NEXT_ENTRY(COMMON_UNSIGNED)), 3301 .args = ARGS(ARGS_ENTRY(struct buffer, 3302 args.configure.port_attr.nb_conn_tracks)), 3303 }, 3304 [CONFIG_FLAGS] = { 3305 .name = "flags", 3306 .help = "configuration flags", 3307 .next = NEXT(next_config_attr, 3308 NEXT_ENTRY(COMMON_UNSIGNED)), 3309 .args = ARGS(ARGS_ENTRY(struct buffer, 3310 args.configure.port_attr.flags)), 3311 }, 3312 [CONFIG_HOST_PORT] = { 3313 .name = "host_port", 3314 .help = "host port for shared objects", 3315 .next = NEXT(next_config_attr, 3316 NEXT_ENTRY(COMMON_UNSIGNED)), 3317 .args = ARGS(ARGS_ENTRY(struct buffer, 3318 args.configure.port_attr.host_port_id)), 3319 }, 3320 /* Top-level command. */ 3321 [PATTERN_TEMPLATE] = { 3322 .name = "pattern_template", 3323 .type = "{command} {port_id} [{arg} [...]]", 3324 .help = "manage pattern templates", 3325 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3326 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3327 .call = parse_template, 3328 }, 3329 /* Sub-level commands. */ 3330 [PATTERN_TEMPLATE_CREATE] = { 3331 .name = "create", 3332 .help = "create pattern template", 3333 .next = NEXT(next_pt_attr), 3334 .call = parse_template, 3335 }, 3336 [PATTERN_TEMPLATE_DESTROY] = { 3337 .name = "destroy", 3338 .help = "destroy pattern template", 3339 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), 3340 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3341 .call = parse_template_destroy, 3342 }, 3343 /* Pattern template arguments. */ 3344 [PATTERN_TEMPLATE_CREATE_ID] = { 3345 .name = "pattern_template_id", 3346 .help = "specify a pattern template id to create", 3347 .next = NEXT(next_pt_attr, 3348 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3349 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), 3350 }, 3351 [PATTERN_TEMPLATE_DESTROY_ID] = { 3352 .name = "pattern_template", 3353 .help = "specify a pattern template id to destroy", 3354 .next = NEXT(next_pt_destroy_attr, 3355 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3356 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3357 args.templ_destroy.template_id)), 3358 .call = parse_template_destroy, 3359 }, 3360 [PATTERN_TEMPLATE_RELAXED_MATCHING] = { 3361 .name = "relaxed", 3362 .help = "is matching relaxed", 3363 .next = NEXT(next_pt_attr, 3364 NEXT_ENTRY(COMMON_BOOLEAN)), 3365 .args = ARGS(ARGS_ENTRY_BF(struct buffer, 3366 args.vc.attr.reserved, 1)), 3367 }, 3368 [PATTERN_TEMPLATE_INGRESS] = { 3369 .name = "ingress", 3370 .help = "attribute pattern to ingress", 3371 .next = NEXT(next_pt_attr), 3372 .call = parse_template, 3373 }, 3374 [PATTERN_TEMPLATE_EGRESS] = { 3375 .name = "egress", 3376 .help = "attribute pattern to egress", 3377 .next = NEXT(next_pt_attr), 3378 .call = parse_template, 3379 }, 3380 [PATTERN_TEMPLATE_TRANSFER] = { 3381 .name = "transfer", 3382 .help = "attribute pattern to transfer", 3383 .next = NEXT(next_pt_attr), 3384 .call = parse_template, 3385 }, 3386 [PATTERN_TEMPLATE_SPEC] = { 3387 .name = "template", 3388 .help = "specify item to create pattern template", 3389 .next = NEXT(next_item), 3390 }, 3391 /* Top-level command. */ 3392 [ACTIONS_TEMPLATE] = { 3393 .name = "actions_template", 3394 .type = "{command} {port_id} [{arg} [...]]", 3395 .help = "manage actions templates", 3396 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3397 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3398 .call = parse_template, 3399 }, 3400 /* Sub-level commands. */ 3401 [ACTIONS_TEMPLATE_CREATE] = { 3402 .name = "create", 3403 .help = "create actions template", 3404 .next = NEXT(next_at_attr), 3405 .call = parse_template, 3406 }, 3407 [ACTIONS_TEMPLATE_DESTROY] = { 3408 .name = "destroy", 3409 .help = "destroy actions template", 3410 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), 3411 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3412 .call = parse_template_destroy, 3413 }, 3414 /* Actions template arguments. */ 3415 [ACTIONS_TEMPLATE_CREATE_ID] = { 3416 .name = "actions_template_id", 3417 .help = "specify an actions template id to create", 3418 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), 3419 NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), 3420 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3421 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), 3422 }, 3423 [ACTIONS_TEMPLATE_DESTROY_ID] = { 3424 .name = "actions_template", 3425 .help = "specify an actions template id to destroy", 3426 .next = NEXT(next_at_destroy_attr, 3427 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3428 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3429 args.templ_destroy.template_id)), 3430 .call = parse_template_destroy, 3431 }, 3432 [ACTIONS_TEMPLATE_INGRESS] = { 3433 .name = "ingress", 3434 .help = "attribute actions to ingress", 3435 .next = NEXT(next_at_attr), 3436 .call = parse_template, 3437 }, 3438 [ACTIONS_TEMPLATE_EGRESS] = { 3439 .name = "egress", 3440 .help = "attribute actions to egress", 3441 .next = NEXT(next_at_attr), 3442 .call = parse_template, 3443 }, 3444 [ACTIONS_TEMPLATE_TRANSFER] = { 3445 .name = "transfer", 3446 .help = "attribute actions to transfer", 3447 .next = NEXT(next_at_attr), 3448 .call = parse_template, 3449 }, 3450 [ACTIONS_TEMPLATE_SPEC] = { 3451 .name = "template", 3452 .help = "specify action to create actions template", 3453 .next = NEXT(next_action), 3454 .call = parse_template, 3455 }, 3456 [ACTIONS_TEMPLATE_MASK] = { 3457 .name = "mask", 3458 .help = "specify action mask to create actions template", 3459 .next = NEXT(next_action), 3460 .call = parse_template, 3461 }, 3462 /* Top-level command. */ 3463 [TABLE] = { 3464 .name = "template_table", 3465 .type = "{command} {port_id} [{arg} [...]]", 3466 .help = "manage template tables", 3467 .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3468 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3469 .call = parse_table, 3470 }, 3471 /* Sub-level commands. */ 3472 [TABLE_CREATE] = { 3473 .name = "create", 3474 .help = "create template table", 3475 .next = NEXT(next_table_attr), 3476 .call = parse_table, 3477 }, 3478 [TABLE_DESTROY] = { 3479 .name = "destroy", 3480 .help = "destroy template table", 3481 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3482 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3483 .call = parse_table_destroy, 3484 }, 3485 [TABLE_RESIZE] = { 3486 .name = "resize", 3487 .help = "resize template table", 3488 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_ID)), 3489 .call = parse_table 3490 }, 3491 [TABLE_RESIZE_COMPLETE] = { 3492 .name = "resize_complete", 3493 .help = "complete table resize", 3494 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 3495 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3496 .call = parse_table_destroy, 3497 }, 3498 /* Table arguments. */ 3499 [TABLE_CREATE_ID] = { 3500 .name = "table_id", 3501 .help = "specify table id to create", 3502 .next = NEXT(next_table_attr, 3503 NEXT_ENTRY(COMMON_TABLE_ID)), 3504 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3505 }, 3506 [TABLE_DESTROY_ID] = { 3507 .name = "table", 3508 .help = "table id", 3509 .next = NEXT(next_table_destroy_attr, 3510 NEXT_ENTRY(COMMON_TABLE_ID)), 3511 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3512 args.table_destroy.table_id)), 3513 .call = parse_table_destroy, 3514 }, 3515 [TABLE_RESIZE_ID] = { 3516 .name = "table_resize_id", 3517 .help = "table resize id", 3518 .next = NEXT(NEXT_ENTRY(TABLE_RESIZE_RULES_NUMBER), 3519 NEXT_ENTRY(COMMON_TABLE_ID)), 3520 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 3521 .call = parse_table 3522 }, 3523 [TABLE_RESIZE_RULES_NUMBER] = { 3524 .name = "table_resize_rules_num", 3525 .help = "table resize rules number", 3526 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_UNSIGNED)), 3527 .args = ARGS(ARGS_ENTRY(struct buffer, 3528 args.table.attr.nb_flows)), 3529 .call = parse_table 3530 }, 3531 [TABLE_INSERTION_TYPE] = { 3532 .name = "insertion_type", 3533 .help = "specify insertion type", 3534 .next = NEXT(next_table_attr, 3535 NEXT_ENTRY(TABLE_INSERTION_TYPE_NAME)), 3536 .args = ARGS(ARGS_ENTRY(struct buffer, 3537 args.table.attr.insertion_type)), 3538 }, 3539 [TABLE_INSERTION_TYPE_NAME] = { 3540 .name = "insertion_type_name", 3541 .help = "insertion type name", 3542 .call = parse_insertion_table_type, 3543 .comp = comp_insertion_table_type, 3544 }, 3545 [TABLE_HASH_FUNC] = { 3546 .name = "hash_func", 3547 .help = "specify hash calculation function", 3548 .next = NEXT(next_table_attr, 3549 NEXT_ENTRY(TABLE_HASH_FUNC_NAME)), 3550 .args = ARGS(ARGS_ENTRY(struct buffer, 3551 args.table.attr.hash_func)), 3552 }, 3553 [TABLE_HASH_FUNC_NAME] = { 3554 .name = "hash_func_name", 3555 .help = "hash calculation function name", 3556 .call = parse_hash_table_type, 3557 .comp = comp_hash_table_type, 3558 }, 3559 [TABLE_GROUP] = { 3560 .name = "group", 3561 .help = "specify a group", 3562 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3563 .args = ARGS(ARGS_ENTRY(struct buffer, 3564 args.table.attr.flow_attr.group)), 3565 }, 3566 [TABLE_PRIORITY] = { 3567 .name = "priority", 3568 .help = "specify a priority level", 3569 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 3570 .args = ARGS(ARGS_ENTRY(struct buffer, 3571 args.table.attr.flow_attr.priority)), 3572 }, 3573 [TABLE_EGRESS] = { 3574 .name = "egress", 3575 .help = "affect rule to egress", 3576 .next = NEXT(next_table_attr), 3577 .call = parse_table, 3578 }, 3579 [TABLE_INGRESS] = { 3580 .name = "ingress", 3581 .help = "affect rule to ingress", 3582 .next = NEXT(next_table_attr), 3583 .call = parse_table, 3584 }, 3585 [TABLE_TRANSFER] = { 3586 .name = "transfer", 3587 .help = "affect rule to transfer", 3588 .next = NEXT(next_table_attr), 3589 .call = parse_table, 3590 }, 3591 [TABLE_TRANSFER_WIRE_ORIG] = { 3592 .name = "wire_orig", 3593 .help = "affect rule direction to transfer", 3594 .next = NEXT(next_table_attr), 3595 .call = parse_table, 3596 }, 3597 [TABLE_TRANSFER_VPORT_ORIG] = { 3598 .name = "vport_orig", 3599 .help = "affect rule direction to transfer", 3600 .next = NEXT(next_table_attr), 3601 .call = parse_table, 3602 }, 3603 [TABLE_RESIZABLE] = { 3604 .name = "resizable", 3605 .help = "set resizable attribute", 3606 .next = NEXT(next_table_attr), 3607 .call = parse_table, 3608 }, 3609 [TABLE_RULES_NUMBER] = { 3610 .name = "rules_number", 3611 .help = "number of rules in table", 3612 .next = NEXT(next_table_attr, 3613 NEXT_ENTRY(COMMON_UNSIGNED)), 3614 .args = ARGS(ARGS_ENTRY(struct buffer, 3615 args.table.attr.nb_flows)), 3616 .call = parse_table, 3617 }, 3618 [TABLE_PATTERN_TEMPLATE] = { 3619 .name = "pattern_template", 3620 .help = "specify pattern template id", 3621 .next = NEXT(next_table_attr, 3622 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 3623 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3624 args.table.pat_templ_id)), 3625 .call = parse_table, 3626 }, 3627 [TABLE_ACTIONS_TEMPLATE] = { 3628 .name = "actions_template", 3629 .help = "specify actions template id", 3630 .next = NEXT(next_table_attr, 3631 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 3632 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3633 args.table.act_templ_id)), 3634 .call = parse_table, 3635 }, 3636 /* Top-level command. */ 3637 [FLOW_GROUP] = { 3638 .name = "group", 3639 .help = "manage flow groups", 3640 .next = NEXT(NEXT_ENTRY(GROUP_ID), NEXT_ENTRY(COMMON_PORT_ID)), 3641 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3642 .call = parse_group, 3643 }, 3644 /* Sub-level commands. */ 3645 [GROUP_SET_MISS_ACTIONS] = { 3646 .name = "set_miss_actions", 3647 .help = "set group miss actions", 3648 .next = NEXT(next_action), 3649 .call = parse_group, 3650 }, 3651 /* Group arguments */ 3652 [GROUP_ID] = { 3653 .name = "group_id", 3654 .help = "group id", 3655 .next = NEXT(next_group_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3656 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3657 }, 3658 [GROUP_INGRESS] = { 3659 .name = "ingress", 3660 .help = "group ingress attr", 3661 .next = NEXT(next_group_attr), 3662 .call = parse_group, 3663 }, 3664 [GROUP_EGRESS] = { 3665 .name = "egress", 3666 .help = "group egress attr", 3667 .next = NEXT(next_group_attr), 3668 .call = parse_group, 3669 }, 3670 [GROUP_TRANSFER] = { 3671 .name = "transfer", 3672 .help = "group transfer attr", 3673 .next = NEXT(next_group_attr), 3674 .call = parse_group, 3675 }, 3676 /* Top-level command. */ 3677 [QUEUE] = { 3678 .name = "queue", 3679 .help = "queue a flow rule operation", 3680 .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3681 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3682 .call = parse_qo, 3683 }, 3684 /* Sub-level commands. */ 3685 [QUEUE_CREATE] = { 3686 .name = "create", 3687 .help = "create a flow rule", 3688 .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), 3689 NEXT_ENTRY(COMMON_QUEUE_ID)), 3690 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3691 .call = parse_qo, 3692 }, 3693 [QUEUE_DESTROY] = { 3694 .name = "destroy", 3695 .help = "destroy a flow rule", 3696 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3697 NEXT_ENTRY(COMMON_QUEUE_ID)), 3698 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3699 .call = parse_qo_destroy, 3700 }, 3701 [QUEUE_FLOW_UPDATE_RESIZED] = { 3702 .name = "update_resized", 3703 .help = "update a flow after table resize", 3704 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3705 NEXT_ENTRY(COMMON_QUEUE_ID)), 3706 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3707 .call = parse_qo_destroy, 3708 }, 3709 [QUEUE_UPDATE] = { 3710 .name = "update", 3711 .help = "update a flow rule", 3712 .next = NEXT(NEXT_ENTRY(QUEUE_UPDATE_ID), 3713 NEXT_ENTRY(COMMON_QUEUE_ID)), 3714 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3715 .call = parse_qo, 3716 }, 3717 [QUEUE_AGED] = { 3718 .name = "aged", 3719 .help = "list and destroy aged flows", 3720 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), 3721 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3722 .call = parse_aged, 3723 }, 3724 [QUEUE_INDIRECT_ACTION] = { 3725 .name = "indirect_action", 3726 .help = "queue indirect actions", 3727 .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), 3728 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3729 .call = parse_qia, 3730 }, 3731 /* Queue arguments. */ 3732 [QUEUE_TEMPLATE_TABLE] = { 3733 .name = "template_table", 3734 .help = "specify table id", 3735 .next = NEXT(next_async_insert_subcmd, 3736 NEXT_ENTRY(COMMON_TABLE_ID)), 3737 .args = ARGS(ARGS_ENTRY(struct buffer, 3738 args.vc.table_id)), 3739 .call = parse_qo, 3740 }, 3741 [QUEUE_PATTERN_TEMPLATE] = { 3742 .name = "pattern_template", 3743 .help = "specify pattern template index", 3744 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3745 NEXT_ENTRY(COMMON_UNSIGNED)), 3746 .args = ARGS(ARGS_ENTRY(struct buffer, 3747 args.vc.pat_templ_id)), 3748 .call = parse_qo, 3749 }, 3750 [QUEUE_ACTIONS_TEMPLATE] = { 3751 .name = "actions_template", 3752 .help = "specify actions template index", 3753 .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), 3754 NEXT_ENTRY(COMMON_UNSIGNED)), 3755 .args = ARGS(ARGS_ENTRY(struct buffer, 3756 args.vc.act_templ_id)), 3757 .call = parse_qo, 3758 }, 3759 [QUEUE_RULE_ID] = { 3760 .name = "rule_index", 3761 .help = "specify flow rule index", 3762 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3763 NEXT_ENTRY(COMMON_UNSIGNED)), 3764 .args = ARGS(ARGS_ENTRY(struct buffer, 3765 args.vc.rule_id)), 3766 .call = parse_qo, 3767 }, 3768 [QUEUE_CREATE_POSTPONE] = { 3769 .name = "postpone", 3770 .help = "postpone create operation", 3771 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3772 NEXT_ENTRY(COMMON_BOOLEAN)), 3773 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3774 .call = parse_qo, 3775 }, 3776 [QUEUE_DESTROY_POSTPONE] = { 3777 .name = "postpone", 3778 .help = "postpone destroy operation", 3779 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3780 NEXT_ENTRY(COMMON_BOOLEAN)), 3781 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3782 .call = parse_qo_destroy, 3783 }, 3784 [QUEUE_DESTROY_ID] = { 3785 .name = "rule", 3786 .help = "specify rule id to destroy", 3787 .next = NEXT(next_queue_destroy_attr, 3788 NEXT_ENTRY(COMMON_UNSIGNED)), 3789 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3790 args.destroy.rule)), 3791 .call = parse_qo_destroy, 3792 }, 3793 [QUEUE_UPDATE_ID] = { 3794 .name = "rule", 3795 .help = "specify rule id to update", 3796 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3797 NEXT_ENTRY(COMMON_UNSIGNED)), 3798 .args = ARGS(ARGS_ENTRY(struct buffer, 3799 args.vc.rule_id)), 3800 .call = parse_qo, 3801 }, 3802 /* Queue indirect action arguments */ 3803 [QUEUE_INDIRECT_ACTION_CREATE] = { 3804 .name = "create", 3805 .help = "create indirect action", 3806 .next = NEXT(next_qia_create_attr), 3807 .call = parse_qia, 3808 }, 3809 [QUEUE_INDIRECT_ACTION_UPDATE] = { 3810 .name = "update", 3811 .help = "update indirect action", 3812 .next = NEXT(next_qia_update_attr, 3813 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3814 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3815 .call = parse_qia, 3816 }, 3817 [QUEUE_INDIRECT_ACTION_DESTROY] = { 3818 .name = "destroy", 3819 .help = "destroy indirect action", 3820 .next = NEXT(next_qia_destroy_attr), 3821 .call = parse_qia_destroy, 3822 }, 3823 [QUEUE_INDIRECT_ACTION_QUERY] = { 3824 .name = "query", 3825 .help = "query indirect action", 3826 .next = NEXT(next_qia_query_attr, 3827 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3828 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3829 .call = parse_qia, 3830 }, 3831 /* Indirect action destroy arguments. */ 3832 [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { 3833 .name = "postpone", 3834 .help = "postpone destroy operation", 3835 .next = NEXT(next_qia_destroy_attr, 3836 NEXT_ENTRY(COMMON_BOOLEAN)), 3837 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3838 }, 3839 [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { 3840 .name = "action_id", 3841 .help = "specify a indirect action id to destroy", 3842 .next = NEXT(next_qia_destroy_attr, 3843 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3844 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3845 args.ia_destroy.action_id)), 3846 .call = parse_qia_destroy, 3847 }, 3848 [QUEUE_INDIRECT_ACTION_QUERY_UPDATE] = { 3849 .name = "query_update", 3850 .help = "indirect query [and|or] update action", 3851 .next = NEXT(next_qia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3852 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3853 .call = parse_qia 3854 }, 3855 [QUEUE_INDIRECT_ACTION_QU_MODE] = { 3856 .name = "mode", 3857 .help = "indirect query [and|or] update action", 3858 .next = NEXT(next_qia_qu_attr, 3859 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 3860 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 3861 .call = parse_qia 3862 }, 3863 /* Indirect action update arguments. */ 3864 [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { 3865 .name = "postpone", 3866 .help = "postpone update operation", 3867 .next = NEXT(next_qia_update_attr, 3868 NEXT_ENTRY(COMMON_BOOLEAN)), 3869 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3870 }, 3871 /* Indirect action update arguments. */ 3872 [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { 3873 .name = "postpone", 3874 .help = "postpone query operation", 3875 .next = NEXT(next_qia_query_attr, 3876 NEXT_ENTRY(COMMON_BOOLEAN)), 3877 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3878 }, 3879 /* Indirect action create arguments. */ 3880 [QUEUE_INDIRECT_ACTION_CREATE_ID] = { 3881 .name = "action_id", 3882 .help = "specify a indirect action id to create", 3883 .next = NEXT(next_qia_create_attr, 3884 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3885 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3886 }, 3887 [QUEUE_INDIRECT_ACTION_INGRESS] = { 3888 .name = "ingress", 3889 .help = "affect rule to ingress", 3890 .next = NEXT(next_qia_create_attr), 3891 .call = parse_qia, 3892 }, 3893 [QUEUE_INDIRECT_ACTION_EGRESS] = { 3894 .name = "egress", 3895 .help = "affect rule to egress", 3896 .next = NEXT(next_qia_create_attr), 3897 .call = parse_qia, 3898 }, 3899 [QUEUE_INDIRECT_ACTION_TRANSFER] = { 3900 .name = "transfer", 3901 .help = "affect rule to transfer", 3902 .next = NEXT(next_qia_create_attr), 3903 .call = parse_qia, 3904 }, 3905 [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { 3906 .name = "postpone", 3907 .help = "postpone create operation", 3908 .next = NEXT(next_qia_create_attr, 3909 NEXT_ENTRY(COMMON_BOOLEAN)), 3910 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3911 }, 3912 [QUEUE_INDIRECT_ACTION_SPEC] = { 3913 .name = "action", 3914 .help = "specify action to create indirect handle", 3915 .next = NEXT(next_action), 3916 }, 3917 [QUEUE_INDIRECT_ACTION_LIST] = { 3918 .name = "list", 3919 .help = "specify actions for indirect handle list", 3920 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 3921 .call = parse_qia, 3922 }, 3923 /* Top-level command. */ 3924 [PUSH] = { 3925 .name = "push", 3926 .help = "push enqueued operations", 3927 .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3928 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3929 .call = parse_push, 3930 }, 3931 /* Sub-level commands. */ 3932 [PUSH_QUEUE] = { 3933 .name = "queue", 3934 .help = "specify queue id", 3935 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3936 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3937 }, 3938 /* Top-level command. */ 3939 [PULL] = { 3940 .name = "pull", 3941 .help = "pull flow operations results", 3942 .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3943 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3944 .call = parse_pull, 3945 }, 3946 /* Sub-level commands. */ 3947 [PULL_QUEUE] = { 3948 .name = "queue", 3949 .help = "specify queue id", 3950 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3951 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3952 }, 3953 /* Top-level command. */ 3954 [HASH] = { 3955 .name = "hash", 3956 .help = "calculate hash for a given pattern in a given template table", 3957 .next = NEXT(next_hash_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3958 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3959 .call = parse_hash, 3960 }, 3961 /* Sub-level commands. */ 3962 [HASH_CALC_TABLE] = { 3963 .name = "template_table", 3964 .help = "specify table id", 3965 .next = NEXT(NEXT_ENTRY(HASH_CALC_PATTERN_INDEX), 3966 NEXT_ENTRY(COMMON_TABLE_ID)), 3967 .args = ARGS(ARGS_ENTRY(struct buffer, 3968 args.vc.table_id)), 3969 .call = parse_hash, 3970 }, 3971 [HASH_CALC_ENCAP] = { 3972 .name = "encap", 3973 .help = "calculates encap hash", 3974 .next = NEXT(next_hash_encap_dest_subcmd), 3975 .call = parse_hash, 3976 }, 3977 [HASH_CALC_PATTERN_INDEX] = { 3978 .name = "pattern_template", 3979 .help = "specify pattern template id", 3980 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3981 NEXT_ENTRY(COMMON_UNSIGNED)), 3982 .args = ARGS(ARGS_ENTRY(struct buffer, 3983 args.vc.pat_templ_id)), 3984 .call = parse_hash, 3985 }, 3986 [ENCAP_HASH_FIELD_SRC_PORT] = { 3987 .name = "hash_field_sport", 3988 .help = "the encap hash field is src port", 3989 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 3990 .call = parse_hash, 3991 }, 3992 [ENCAP_HASH_FIELD_GRE_FLOW_ID] = { 3993 .name = "hash_field_flow_id", 3994 .help = "the encap hash field is NVGRE flow id", 3995 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN)), 3996 .call = parse_hash, 3997 }, 3998 /* Top-level command. */ 3999 [INDIRECT_ACTION] = { 4000 .name = "indirect_action", 4001 .type = "{command} {port_id} [{arg} [...]]", 4002 .help = "manage indirect actions", 4003 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4004 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4005 .call = parse_ia, 4006 }, 4007 /* Sub-level commands. */ 4008 [INDIRECT_ACTION_CREATE] = { 4009 .name = "create", 4010 .help = "create indirect action", 4011 .next = NEXT(next_ia_create_attr), 4012 .call = parse_ia, 4013 }, 4014 [INDIRECT_ACTION_UPDATE] = { 4015 .name = "update", 4016 .help = "update indirect action", 4017 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), 4018 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4019 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 4020 .call = parse_ia, 4021 }, 4022 [INDIRECT_ACTION_DESTROY] = { 4023 .name = "destroy", 4024 .help = "destroy indirect action", 4025 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), 4026 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4027 .call = parse_ia_destroy, 4028 }, 4029 [INDIRECT_ACTION_QUERY] = { 4030 .name = "query", 4031 .help = "query indirect action", 4032 .next = NEXT(NEXT_ENTRY(END), 4033 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4034 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4035 .call = parse_ia, 4036 }, 4037 [INDIRECT_ACTION_QUERY_UPDATE] = { 4038 .name = "query_update", 4039 .help = "query [and|or] update", 4040 .next = NEXT(next_ia_qu_attr, NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 4041 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 4042 .call = parse_ia 4043 }, 4044 [INDIRECT_ACTION_QU_MODE] = { 4045 .name = "mode", 4046 .help = "query_update mode", 4047 .next = NEXT(next_ia_qu_attr, 4048 NEXT_ENTRY(INDIRECT_ACTION_QU_MODE_NAME)), 4049 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.qu_mode)), 4050 .call = parse_ia, 4051 }, 4052 [INDIRECT_ACTION_QU_MODE_NAME] = { 4053 .name = "mode_name", 4054 .help = "query-update mode name", 4055 .call = parse_qu_mode_name, 4056 .comp = comp_qu_mode_name, 4057 }, 4058 [VALIDATE] = { 4059 .name = "validate", 4060 .help = "check whether a flow rule can be created", 4061 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4062 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4063 .call = parse_vc, 4064 }, 4065 [CREATE] = { 4066 .name = "create", 4067 .help = "create a flow rule", 4068 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4069 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4070 .call = parse_vc, 4071 }, 4072 [DESTROY] = { 4073 .name = "destroy", 4074 .help = "destroy specific flow rules", 4075 .next = NEXT(next_destroy_attr, 4076 NEXT_ENTRY(COMMON_PORT_ID)), 4077 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4078 .call = parse_destroy, 4079 }, 4080 [UPDATE] = { 4081 .name = "update", 4082 .help = "update a flow rule with new actions", 4083 .next = NEXT(NEXT_ENTRY(VC_IS_USER_ID, END), 4084 NEXT_ENTRY(ACTIONS), 4085 NEXT_ENTRY(COMMON_RULE_ID), 4086 NEXT_ENTRY(COMMON_PORT_ID)), 4087 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.rule_id), 4088 ARGS_ENTRY(struct buffer, port)), 4089 .call = parse_vc, 4090 }, 4091 [FLUSH] = { 4092 .name = "flush", 4093 .help = "destroy all flow rules", 4094 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4095 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4096 .call = parse_flush, 4097 }, 4098 [DUMP] = { 4099 .name = "dump", 4100 .help = "dump single/all flow rules to file", 4101 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 4102 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4103 .call = parse_dump, 4104 }, 4105 [QUERY] = { 4106 .name = "query", 4107 .help = "query an existing flow rule", 4108 .next = NEXT(next_query_attr, NEXT_ENTRY(QUERY_ACTION), 4109 NEXT_ENTRY(COMMON_RULE_ID), 4110 NEXT_ENTRY(COMMON_PORT_ID)), 4111 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), 4112 ARGS_ENTRY(struct buffer, args.query.rule), 4113 ARGS_ENTRY(struct buffer, port)), 4114 .call = parse_query, 4115 }, 4116 [LIST] = { 4117 .name = "list", 4118 .help = "list existing flow rules", 4119 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4120 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4121 .call = parse_list, 4122 }, 4123 [AGED] = { 4124 .name = "aged", 4125 .help = "list and destroy aged flows", 4126 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)), 4127 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4128 .call = parse_aged, 4129 }, 4130 [ISOLATE] = { 4131 .name = "isolate", 4132 .help = "restrict ingress traffic to the defined flow rules", 4133 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), 4134 NEXT_ENTRY(COMMON_PORT_ID)), 4135 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), 4136 ARGS_ENTRY(struct buffer, port)), 4137 .call = parse_isolate, 4138 }, 4139 [FLEX] = { 4140 .name = "flex_item", 4141 .help = "flex item API", 4142 .next = NEXT(next_flex_item), 4143 .call = parse_flex, 4144 }, 4145 [FLEX_ITEM_INIT] = { 4146 .name = "init", 4147 .help = "flex item init", 4148 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4149 ARGS_ENTRY(struct buffer, port)), 4150 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4151 NEXT_ENTRY(COMMON_PORT_ID)), 4152 .call = parse_flex 4153 }, 4154 [FLEX_ITEM_CREATE] = { 4155 .name = "create", 4156 .help = "flex item create", 4157 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), 4158 ARGS_ENTRY(struct buffer, args.flex.token), 4159 ARGS_ENTRY(struct buffer, port)), 4160 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), 4161 NEXT_ENTRY(COMMON_FLEX_TOKEN), 4162 NEXT_ENTRY(COMMON_PORT_ID)), 4163 .call = parse_flex 4164 }, 4165 [FLEX_ITEM_DESTROY] = { 4166 .name = "destroy", 4167 .help = "flex item destroy", 4168 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 4169 ARGS_ENTRY(struct buffer, port)), 4170 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 4171 NEXT_ENTRY(COMMON_PORT_ID)), 4172 .call = parse_flex 4173 }, 4174 [TUNNEL] = { 4175 .name = "tunnel", 4176 .help = "new tunnel API", 4177 .next = NEXT(NEXT_ENTRY 4178 (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), 4179 .call = parse_tunnel, 4180 }, 4181 /* Tunnel arguments. */ 4182 [TUNNEL_CREATE] = { 4183 .name = "create", 4184 .help = "create new tunnel object", 4185 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), 4186 NEXT_ENTRY(COMMON_PORT_ID)), 4187 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4188 .call = parse_tunnel, 4189 }, 4190 [TUNNEL_CREATE_TYPE] = { 4191 .name = "type", 4192 .help = "create new tunnel", 4193 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), 4194 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), 4195 .call = parse_tunnel, 4196 }, 4197 [TUNNEL_DESTROY] = { 4198 .name = "destroy", 4199 .help = "destroy tunnel", 4200 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), 4201 NEXT_ENTRY(COMMON_PORT_ID)), 4202 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4203 .call = parse_tunnel, 4204 }, 4205 [TUNNEL_DESTROY_ID] = { 4206 .name = "id", 4207 .help = "tunnel identifier to destroy", 4208 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), 4209 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4210 .call = parse_tunnel, 4211 }, 4212 [TUNNEL_LIST] = { 4213 .name = "list", 4214 .help = "list existing tunnels", 4215 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 4216 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 4217 .call = parse_tunnel, 4218 }, 4219 /* Destroy arguments. */ 4220 [DESTROY_RULE] = { 4221 .name = "rule", 4222 .help = "specify a rule identifier", 4223 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4224 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), 4225 .call = parse_destroy, 4226 }, 4227 [DESTROY_IS_USER_ID] = { 4228 .name = "user_id", 4229 .help = "rule identifier is user-id", 4230 .next = NEXT(next_destroy_attr), 4231 .call = parse_destroy, 4232 }, 4233 /* Dump arguments. */ 4234 [DUMP_ALL] = { 4235 .name = "all", 4236 .help = "dump all", 4237 .next = NEXT(next_dump_attr), 4238 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), 4239 .call = parse_dump, 4240 }, 4241 [DUMP_ONE] = { 4242 .name = "rule", 4243 .help = "dump one rule", 4244 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), 4245 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), 4246 ARGS_ENTRY(struct buffer, args.dump.rule)), 4247 .call = parse_dump, 4248 }, 4249 [DUMP_IS_USER_ID] = { 4250 .name = "user_id", 4251 .help = "rule identifier is user-id", 4252 .next = NEXT(next_dump_subcmd), 4253 .call = parse_dump, 4254 }, 4255 /* Query arguments. */ 4256 [QUERY_ACTION] = { 4257 .name = "{action}", 4258 .type = "ACTION", 4259 .help = "action to query, must be part of the rule", 4260 .call = parse_action, 4261 .comp = comp_action, 4262 }, 4263 [QUERY_IS_USER_ID] = { 4264 .name = "user_id", 4265 .help = "rule identifier is user-id", 4266 .next = NEXT(next_query_attr), 4267 .call = parse_query, 4268 }, 4269 /* List arguments. */ 4270 [LIST_GROUP] = { 4271 .name = "group", 4272 .help = "specify a group", 4273 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4274 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), 4275 .call = parse_list, 4276 }, 4277 [AGED_DESTROY] = { 4278 .name = "destroy", 4279 .help = "specify aged flows need be destroyed", 4280 .call = parse_aged, 4281 .comp = comp_none, 4282 }, 4283 /* Validate/create attributes. */ 4284 [VC_GROUP] = { 4285 .name = "group", 4286 .help = "specify a group", 4287 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 4288 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), 4289 .call = parse_vc, 4290 }, 4291 [VC_PRIORITY] = { 4292 .name = "priority", 4293 .help = "specify a priority level", 4294 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 4295 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), 4296 .call = parse_vc, 4297 }, 4298 [VC_INGRESS] = { 4299 .name = "ingress", 4300 .help = "affect rule to ingress", 4301 .next = NEXT(next_vc_attr), 4302 .call = parse_vc, 4303 }, 4304 [VC_EGRESS] = { 4305 .name = "egress", 4306 .help = "affect rule to egress", 4307 .next = NEXT(next_vc_attr), 4308 .call = parse_vc, 4309 }, 4310 [VC_TRANSFER] = { 4311 .name = "transfer", 4312 .help = "apply rule directly to endpoints found in pattern", 4313 .next = NEXT(next_vc_attr), 4314 .call = parse_vc, 4315 }, 4316 [VC_TUNNEL_SET] = { 4317 .name = "tunnel_set", 4318 .help = "tunnel steer rule", 4319 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4320 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4321 .call = parse_vc, 4322 }, 4323 [VC_TUNNEL_MATCH] = { 4324 .name = "tunnel_match", 4325 .help = "tunnel match rule", 4326 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4327 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 4328 .call = parse_vc, 4329 }, 4330 [VC_USER_ID] = { 4331 .name = "user_id", 4332 .help = "specify a user id to create", 4333 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 4334 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.user_id)), 4335 .call = parse_vc, 4336 }, 4337 [VC_IS_USER_ID] = { 4338 .name = "user_id", 4339 .help = "rule identifier is user-id", 4340 .call = parse_vc, 4341 }, 4342 /* Validate/create pattern. */ 4343 [ITEM_PATTERN] = { 4344 .name = "pattern", 4345 .help = "submit a list of pattern items", 4346 .next = NEXT(next_item), 4347 .call = parse_vc, 4348 }, 4349 [ITEM_PARAM_IS] = { 4350 .name = "is", 4351 .help = "match value perfectly (with full bit-mask)", 4352 .call = parse_vc_spec, 4353 }, 4354 [ITEM_PARAM_SPEC] = { 4355 .name = "spec", 4356 .help = "match value according to configured bit-mask", 4357 .call = parse_vc_spec, 4358 }, 4359 [ITEM_PARAM_LAST] = { 4360 .name = "last", 4361 .help = "specify upper bound to establish a range", 4362 .call = parse_vc_spec, 4363 }, 4364 [ITEM_PARAM_MASK] = { 4365 .name = "mask", 4366 .help = "specify bit-mask with relevant bits set to one", 4367 .call = parse_vc_spec, 4368 }, 4369 [ITEM_PARAM_PREFIX] = { 4370 .name = "prefix", 4371 .help = "generate bit-mask from a prefix length", 4372 .call = parse_vc_spec, 4373 }, 4374 [ITEM_NEXT] = { 4375 .name = "/", 4376 .help = "specify next pattern item", 4377 .next = NEXT(next_item), 4378 }, 4379 [ITEM_END] = { 4380 .name = "end", 4381 .help = "end list of pattern items", 4382 .priv = PRIV_ITEM(END, 0), 4383 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 4384 .call = parse_vc, 4385 }, 4386 [ITEM_VOID] = { 4387 .name = "void", 4388 .help = "no-op pattern item", 4389 .priv = PRIV_ITEM(VOID, 0), 4390 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4391 .call = parse_vc, 4392 }, 4393 [ITEM_INVERT] = { 4394 .name = "invert", 4395 .help = "perform actions when pattern does not match", 4396 .priv = PRIV_ITEM(INVERT, 0), 4397 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 4398 .call = parse_vc, 4399 }, 4400 [ITEM_ANY] = { 4401 .name = "any", 4402 .help = "match any protocol for the current layer", 4403 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), 4404 .next = NEXT(item_any), 4405 .call = parse_vc, 4406 }, 4407 [ITEM_ANY_NUM] = { 4408 .name = "num", 4409 .help = "number of layers covered", 4410 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4411 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), 4412 }, 4413 [ITEM_PORT_ID] = { 4414 .name = "port_id", 4415 .help = "match traffic from/to a given DPDK port ID", 4416 .priv = PRIV_ITEM(PORT_ID, 4417 sizeof(struct rte_flow_item_port_id)), 4418 .next = NEXT(item_port_id), 4419 .call = parse_vc, 4420 }, 4421 [ITEM_PORT_ID_ID] = { 4422 .name = "id", 4423 .help = "DPDK port ID", 4424 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), 4425 item_param), 4426 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), 4427 }, 4428 [ITEM_MARK] = { 4429 .name = "mark", 4430 .help = "match traffic against value set in previously matched rule", 4431 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), 4432 .next = NEXT(item_mark), 4433 .call = parse_vc, 4434 }, 4435 [ITEM_MARK_ID] = { 4436 .name = "id", 4437 .help = "Integer value to match against", 4438 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), 4439 item_param), 4440 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), 4441 }, 4442 [ITEM_RAW] = { 4443 .name = "raw", 4444 .help = "match an arbitrary byte string", 4445 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), 4446 .next = NEXT(item_raw), 4447 .call = parse_vc, 4448 }, 4449 [ITEM_RAW_RELATIVE] = { 4450 .name = "relative", 4451 .help = "look for pattern after the previous item", 4452 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4453 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4454 relative, 1)), 4455 }, 4456 [ITEM_RAW_SEARCH] = { 4457 .name = "search", 4458 .help = "search pattern from offset (see also limit)", 4459 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4460 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 4461 search, 1)), 4462 }, 4463 [ITEM_RAW_OFFSET] = { 4464 .name = "offset", 4465 .help = "absolute or relative offset for pattern", 4466 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), 4467 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), 4468 }, 4469 [ITEM_RAW_LIMIT] = { 4470 .name = "limit", 4471 .help = "search area limit for start of pattern", 4472 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4473 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), 4474 }, 4475 [ITEM_RAW_PATTERN] = { 4476 .name = "pattern", 4477 .help = "byte string to look for", 4478 .next = NEXT(item_raw, 4479 NEXT_ENTRY(COMMON_STRING), 4480 NEXT_ENTRY(ITEM_PARAM_IS, 4481 ITEM_PARAM_SPEC, 4482 ITEM_PARAM_MASK)), 4483 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4484 ARGS_ENTRY(struct rte_flow_item_raw, length), 4485 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4486 ITEM_RAW_PATTERN_SIZE)), 4487 }, 4488 [ITEM_RAW_PATTERN_HEX] = { 4489 .name = "pattern_hex", 4490 .help = "hex string to look for", 4491 .next = NEXT(item_raw, 4492 NEXT_ENTRY(COMMON_HEX), 4493 NEXT_ENTRY(ITEM_PARAM_IS, 4494 ITEM_PARAM_SPEC, 4495 ITEM_PARAM_MASK)), 4496 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 4497 ARGS_ENTRY(struct rte_flow_item_raw, length), 4498 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 4499 ITEM_RAW_PATTERN_SIZE)), 4500 }, 4501 [ITEM_ETH] = { 4502 .name = "eth", 4503 .help = "match Ethernet header", 4504 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), 4505 .next = NEXT(item_eth), 4506 .call = parse_vc, 4507 }, 4508 [ITEM_ETH_DST] = { 4509 .name = "dst", 4510 .help = "destination MAC", 4511 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4512 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), 4513 }, 4514 [ITEM_ETH_SRC] = { 4515 .name = "src", 4516 .help = "source MAC", 4517 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4518 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), 4519 }, 4520 [ITEM_ETH_TYPE] = { 4521 .name = "type", 4522 .help = "EtherType", 4523 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4524 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), 4525 }, 4526 [ITEM_ETH_HAS_VLAN] = { 4527 .name = "has_vlan", 4528 .help = "packet header contains VLAN", 4529 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4530 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, 4531 has_vlan, 1)), 4532 }, 4533 [ITEM_VLAN] = { 4534 .name = "vlan", 4535 .help = "match 802.1Q/ad VLAN tag", 4536 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), 4537 .next = NEXT(item_vlan), 4538 .call = parse_vc, 4539 }, 4540 [ITEM_VLAN_TCI] = { 4541 .name = "tci", 4542 .help = "tag control information", 4543 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4544 item_param), 4545 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, hdr.vlan_tci)), 4546 }, 4547 [ITEM_VLAN_PCP] = { 4548 .name = "pcp", 4549 .help = "priority code point", 4550 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4551 item_param), 4552 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4553 hdr.vlan_tci, "\xe0\x00")), 4554 }, 4555 [ITEM_VLAN_DEI] = { 4556 .name = "dei", 4557 .help = "drop eligible indicator", 4558 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4559 item_param), 4560 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4561 hdr.vlan_tci, "\x10\x00")), 4562 }, 4563 [ITEM_VLAN_VID] = { 4564 .name = "vid", 4565 .help = "VLAN identifier", 4566 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4567 item_param), 4568 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 4569 hdr.vlan_tci, "\x0f\xff")), 4570 }, 4571 [ITEM_VLAN_INNER_TYPE] = { 4572 .name = "inner_type", 4573 .help = "inner EtherType", 4574 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4575 item_param), 4576 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, 4577 hdr.eth_proto)), 4578 }, 4579 [ITEM_VLAN_HAS_MORE_VLAN] = { 4580 .name = "has_more_vlan", 4581 .help = "packet header contains another VLAN", 4582 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 4583 item_param), 4584 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, 4585 has_more_vlan, 1)), 4586 }, 4587 [ITEM_IPV4] = { 4588 .name = "ipv4", 4589 .help = "match IPv4 header", 4590 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), 4591 .next = NEXT(item_ipv4), 4592 .call = parse_vc, 4593 }, 4594 [ITEM_IPV4_VER_IHL] = { 4595 .name = "version_ihl", 4596 .help = "match header length", 4597 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4598 item_param), 4599 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, 4600 hdr.version_ihl)), 4601 }, 4602 [ITEM_IPV4_TOS] = { 4603 .name = "tos", 4604 .help = "type of service", 4605 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4606 item_param), 4607 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4608 hdr.type_of_service)), 4609 }, 4610 [ITEM_IPV4_LENGTH] = { 4611 .name = "length", 4612 .help = "total length", 4613 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4614 item_param), 4615 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4616 hdr.total_length)), 4617 }, 4618 [ITEM_IPV4_ID] = { 4619 .name = "packet_id", 4620 .help = "fragment packet id", 4621 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4622 item_param), 4623 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4624 hdr.packet_id)), 4625 }, 4626 [ITEM_IPV4_FRAGMENT_OFFSET] = { 4627 .name = "fragment_offset", 4628 .help = "fragmentation flags and fragment offset", 4629 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4630 item_param), 4631 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4632 hdr.fragment_offset)), 4633 }, 4634 [ITEM_IPV4_TTL] = { 4635 .name = "ttl", 4636 .help = "time to live", 4637 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4638 item_param), 4639 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4640 hdr.time_to_live)), 4641 }, 4642 [ITEM_IPV4_PROTO] = { 4643 .name = "proto", 4644 .help = "next protocol ID", 4645 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 4646 item_param), 4647 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4648 hdr.next_proto_id)), 4649 }, 4650 [ITEM_IPV4_SRC] = { 4651 .name = "src", 4652 .help = "source address", 4653 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4654 item_param), 4655 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4656 hdr.src_addr)), 4657 }, 4658 [ITEM_IPV4_DST] = { 4659 .name = "dst", 4660 .help = "destination address", 4661 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4662 item_param), 4663 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 4664 hdr.dst_addr)), 4665 }, 4666 [ITEM_IPV6] = { 4667 .name = "ipv6", 4668 .help = "match IPv6 header", 4669 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), 4670 .next = NEXT(item_ipv6), 4671 .call = parse_vc, 4672 }, 4673 [ITEM_IPV6_TC] = { 4674 .name = "tc", 4675 .help = "traffic class", 4676 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4677 item_param), 4678 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4679 hdr.vtc_flow, 4680 "\x0f\xf0\x00\x00")), 4681 }, 4682 [ITEM_IPV6_FLOW] = { 4683 .name = "flow", 4684 .help = "flow label", 4685 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4686 item_param), 4687 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 4688 hdr.vtc_flow, 4689 "\x00\x0f\xff\xff")), 4690 }, 4691 [ITEM_IPV6_LEN] = { 4692 .name = "length", 4693 .help = "payload length", 4694 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4695 item_param), 4696 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4697 hdr.payload_len)), 4698 }, 4699 [ITEM_IPV6_PROTO] = { 4700 .name = "proto", 4701 .help = "protocol (next header)", 4702 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4703 item_param), 4704 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4705 hdr.proto)), 4706 }, 4707 [ITEM_IPV6_HOP] = { 4708 .name = "hop", 4709 .help = "hop limit", 4710 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4711 item_param), 4712 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4713 hdr.hop_limits)), 4714 }, 4715 [ITEM_IPV6_SRC] = { 4716 .name = "src", 4717 .help = "source address", 4718 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4719 item_param), 4720 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4721 hdr.src_addr)), 4722 }, 4723 [ITEM_IPV6_DST] = { 4724 .name = "dst", 4725 .help = "destination address", 4726 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 4727 item_param), 4728 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 4729 hdr.dst_addr)), 4730 }, 4731 [ITEM_IPV6_HAS_FRAG_EXT] = { 4732 .name = "has_frag_ext", 4733 .help = "fragment packet attribute", 4734 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 4735 item_param), 4736 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, 4737 has_frag_ext, 1)), 4738 }, 4739 [ITEM_IPV6_ROUTING_EXT] = { 4740 .name = "ipv6_routing_ext", 4741 .help = "match IPv6 routing extension header", 4742 .priv = PRIV_ITEM(IPV6_ROUTING_EXT, 4743 sizeof(struct rte_flow_item_ipv6_routing_ext)), 4744 .next = NEXT(item_ipv6_routing_ext), 4745 .call = parse_vc, 4746 }, 4747 [ITEM_IPV6_ROUTING_EXT_TYPE] = { 4748 .name = "ext_type", 4749 .help = "match IPv6 routing extension header type", 4750 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4751 item_param), 4752 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4753 hdr.type)), 4754 }, 4755 [ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = { 4756 .name = "ext_next_hdr", 4757 .help = "match IPv6 routing extension header next header type", 4758 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4759 item_param), 4760 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4761 hdr.next_hdr)), 4762 }, 4763 [ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = { 4764 .name = "ext_seg_left", 4765 .help = "match IPv6 routing extension header segment left", 4766 .next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4767 item_param), 4768 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext, 4769 hdr.segments_left)), 4770 }, 4771 [ITEM_ICMP] = { 4772 .name = "icmp", 4773 .help = "match ICMP header", 4774 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), 4775 .next = NEXT(item_icmp), 4776 .call = parse_vc, 4777 }, 4778 [ITEM_ICMP_TYPE] = { 4779 .name = "type", 4780 .help = "ICMP packet type", 4781 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4782 item_param), 4783 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4784 hdr.icmp_type)), 4785 }, 4786 [ITEM_ICMP_CODE] = { 4787 .name = "code", 4788 .help = "ICMP packet code", 4789 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4790 item_param), 4791 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4792 hdr.icmp_code)), 4793 }, 4794 [ITEM_ICMP_IDENT] = { 4795 .name = "ident", 4796 .help = "ICMP packet identifier", 4797 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4798 item_param), 4799 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4800 hdr.icmp_ident)), 4801 }, 4802 [ITEM_ICMP_SEQ] = { 4803 .name = "seq", 4804 .help = "ICMP packet sequence number", 4805 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 4806 item_param), 4807 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 4808 hdr.icmp_seq_nb)), 4809 }, 4810 [ITEM_UDP] = { 4811 .name = "udp", 4812 .help = "match UDP header", 4813 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), 4814 .next = NEXT(item_udp), 4815 .call = parse_vc, 4816 }, 4817 [ITEM_UDP_SRC] = { 4818 .name = "src", 4819 .help = "UDP source port", 4820 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), 4821 item_param), 4822 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4823 hdr.src_port)), 4824 }, 4825 [ITEM_UDP_DST] = { 4826 .name = "dst", 4827 .help = "UDP destination port", 4828 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4829 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 4830 hdr.dst_port)), 4831 }, 4832 [ITEM_TCP] = { 4833 .name = "tcp", 4834 .help = "match TCP header", 4835 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), 4836 .next = NEXT(item_tcp), 4837 .call = parse_vc, 4838 }, 4839 [ITEM_TCP_SRC] = { 4840 .name = "src", 4841 .help = "TCP source port", 4842 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4843 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4844 hdr.src_port)), 4845 }, 4846 [ITEM_TCP_DST] = { 4847 .name = "dst", 4848 .help = "TCP destination port", 4849 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4850 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4851 hdr.dst_port)), 4852 }, 4853 [ITEM_TCP_FLAGS] = { 4854 .name = "flags", 4855 .help = "TCP flags", 4856 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4857 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 4858 hdr.tcp_flags)), 4859 }, 4860 [ITEM_SCTP] = { 4861 .name = "sctp", 4862 .help = "match SCTP header", 4863 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), 4864 .next = NEXT(item_sctp), 4865 .call = parse_vc, 4866 }, 4867 [ITEM_SCTP_SRC] = { 4868 .name = "src", 4869 .help = "SCTP source port", 4870 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4871 item_param), 4872 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4873 hdr.src_port)), 4874 }, 4875 [ITEM_SCTP_DST] = { 4876 .name = "dst", 4877 .help = "SCTP destination port", 4878 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4879 item_param), 4880 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4881 hdr.dst_port)), 4882 }, 4883 [ITEM_SCTP_TAG] = { 4884 .name = "tag", 4885 .help = "validation tag", 4886 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4887 item_param), 4888 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4889 hdr.tag)), 4890 }, 4891 [ITEM_SCTP_CKSUM] = { 4892 .name = "cksum", 4893 .help = "checksum", 4894 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 4895 item_param), 4896 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 4897 hdr.cksum)), 4898 }, 4899 [ITEM_VXLAN] = { 4900 .name = "vxlan", 4901 .help = "match VXLAN header", 4902 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), 4903 .next = NEXT(item_vxlan), 4904 .call = parse_vc, 4905 }, 4906 [ITEM_VXLAN_VNI] = { 4907 .name = "vni", 4908 .help = "VXLAN identifier", 4909 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4910 item_param), 4911 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), 4912 }, 4913 [ITEM_VXLAN_LAST_RSVD] = { 4914 .name = "last_rsvd", 4915 .help = "VXLAN last reserved bits", 4916 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 4917 item_param), 4918 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 4919 hdr.rsvd1)), 4920 }, 4921 [ITEM_E_TAG] = { 4922 .name = "e_tag", 4923 .help = "match E-Tag header", 4924 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), 4925 .next = NEXT(item_e_tag), 4926 .call = parse_vc, 4927 }, 4928 [ITEM_E_TAG_GRP_ECID_B] = { 4929 .name = "grp_ecid_b", 4930 .help = "GRP and E-CID base", 4931 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), 4932 item_param), 4933 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, 4934 rsvd_grp_ecid_b, 4935 "\x3f\xff")), 4936 }, 4937 [ITEM_NVGRE] = { 4938 .name = "nvgre", 4939 .help = "match NVGRE header", 4940 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), 4941 .next = NEXT(item_nvgre), 4942 .call = parse_vc, 4943 }, 4944 [ITEM_NVGRE_TNI] = { 4945 .name = "tni", 4946 .help = "virtual subnet ID", 4947 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), 4948 item_param), 4949 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), 4950 }, 4951 [ITEM_MPLS] = { 4952 .name = "mpls", 4953 .help = "match MPLS header", 4954 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), 4955 .next = NEXT(item_mpls), 4956 .call = parse_vc, 4957 }, 4958 [ITEM_MPLS_LABEL] = { 4959 .name = "label", 4960 .help = "MPLS label", 4961 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4962 item_param), 4963 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4964 label_tc_s, 4965 "\xff\xff\xf0")), 4966 }, 4967 [ITEM_MPLS_TC] = { 4968 .name = "tc", 4969 .help = "MPLS Traffic Class", 4970 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4971 item_param), 4972 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4973 label_tc_s, 4974 "\x00\x00\x0e")), 4975 }, 4976 [ITEM_MPLS_S] = { 4977 .name = "s", 4978 .help = "MPLS Bottom-of-Stack", 4979 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4980 item_param), 4981 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4982 label_tc_s, 4983 "\x00\x00\x01")), 4984 }, 4985 [ITEM_MPLS_TTL] = { 4986 .name = "ttl", 4987 .help = "MPLS Time-to-Live", 4988 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4989 item_param), 4990 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_mpls, ttl)), 4991 }, 4992 [ITEM_GRE] = { 4993 .name = "gre", 4994 .help = "match GRE header", 4995 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), 4996 .next = NEXT(item_gre), 4997 .call = parse_vc, 4998 }, 4999 [ITEM_GRE_PROTO] = { 5000 .name = "protocol", 5001 .help = "GRE protocol type", 5002 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5003 item_param), 5004 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5005 protocol)), 5006 }, 5007 [ITEM_GRE_C_RSVD0_VER] = { 5008 .name = "c_rsvd0_ver", 5009 .help = 5010 "checksum (1b), undefined (1b), key bit (1b)," 5011 " sequence number (1b), reserved 0 (9b)," 5012 " version (3b)", 5013 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 5014 item_param), 5015 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 5016 c_rsvd0_ver)), 5017 }, 5018 [ITEM_GRE_C_BIT] = { 5019 .name = "c_bit", 5020 .help = "checksum bit (C)", 5021 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), 5022 item_param), 5023 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5024 c_rsvd0_ver, 5025 "\x80\x00\x00\x00")), 5026 }, 5027 [ITEM_GRE_S_BIT] = { 5028 .name = "s_bit", 5029 .help = "sequence number bit (S)", 5030 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5031 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5032 c_rsvd0_ver, 5033 "\x10\x00\x00\x00")), 5034 }, 5035 [ITEM_GRE_K_BIT] = { 5036 .name = "k_bit", 5037 .help = "key bit (K)", 5038 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 5039 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 5040 c_rsvd0_ver, 5041 "\x20\x00\x00\x00")), 5042 }, 5043 [ITEM_FUZZY] = { 5044 .name = "fuzzy", 5045 .help = "fuzzy pattern match, expect faster than default", 5046 .priv = PRIV_ITEM(FUZZY, 5047 sizeof(struct rte_flow_item_fuzzy)), 5048 .next = NEXT(item_fuzzy), 5049 .call = parse_vc, 5050 }, 5051 [ITEM_FUZZY_THRESH] = { 5052 .name = "thresh", 5053 .help = "match accuracy threshold", 5054 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), 5055 item_param), 5056 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, 5057 thresh)), 5058 }, 5059 [ITEM_GTP] = { 5060 .name = "gtp", 5061 .help = "match GTP header", 5062 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), 5063 .next = NEXT(item_gtp), 5064 .call = parse_vc, 5065 }, 5066 [ITEM_GTP_FLAGS] = { 5067 .name = "v_pt_rsv_flags", 5068 .help = "GTP flags", 5069 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5070 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, 5071 hdr.gtp_hdr_info)), 5072 }, 5073 [ITEM_GTP_MSG_TYPE] = { 5074 .name = "msg_type", 5075 .help = "GTP message type", 5076 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5077 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), 5078 }, 5079 [ITEM_GTP_TEID] = { 5080 .name = "teid", 5081 .help = "tunnel endpoint identifier", 5082 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5083 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), 5084 }, 5085 [ITEM_GTPC] = { 5086 .name = "gtpc", 5087 .help = "match GTP header", 5088 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), 5089 .next = NEXT(item_gtp), 5090 .call = parse_vc, 5091 }, 5092 [ITEM_GTPU] = { 5093 .name = "gtpu", 5094 .help = "match GTP header", 5095 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), 5096 .next = NEXT(item_gtp), 5097 .call = parse_vc, 5098 }, 5099 [ITEM_GENEVE] = { 5100 .name = "geneve", 5101 .help = "match GENEVE header", 5102 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), 5103 .next = NEXT(item_geneve), 5104 .call = parse_vc, 5105 }, 5106 [ITEM_GENEVE_VNI] = { 5107 .name = "vni", 5108 .help = "virtual network identifier", 5109 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5110 item_param), 5111 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), 5112 }, 5113 [ITEM_GENEVE_PROTO] = { 5114 .name = "protocol", 5115 .help = "GENEVE protocol type", 5116 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5117 item_param), 5118 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, 5119 protocol)), 5120 }, 5121 [ITEM_GENEVE_OPTLEN] = { 5122 .name = "optlen", 5123 .help = "GENEVE options length in dwords", 5124 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 5125 item_param), 5126 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, 5127 ver_opt_len_o_c_rsvd0, 5128 "\x3f\x00")), 5129 }, 5130 [ITEM_VXLAN_GPE] = { 5131 .name = "vxlan-gpe", 5132 .help = "match VXLAN-GPE header", 5133 .priv = PRIV_ITEM(VXLAN_GPE, 5134 sizeof(struct rte_flow_item_vxlan_gpe)), 5135 .next = NEXT(item_vxlan_gpe), 5136 .call = parse_vc, 5137 }, 5138 [ITEM_VXLAN_GPE_VNI] = { 5139 .name = "vni", 5140 .help = "VXLAN-GPE identifier", 5141 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5142 item_param), 5143 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5144 hdr.vni)), 5145 }, 5146 [ITEM_VXLAN_GPE_PROTO] = { 5147 .name = "protocol", 5148 .help = "VXLAN-GPE next protocol", 5149 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5150 item_param), 5151 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5152 protocol)), 5153 }, 5154 [ITEM_VXLAN_GPE_FLAGS] = { 5155 .name = "flags", 5156 .help = "VXLAN-GPE flags", 5157 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5158 item_param), 5159 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5160 flags)), 5161 }, 5162 [ITEM_VXLAN_GPE_RSVD0] = { 5163 .name = "rsvd0", 5164 .help = "VXLAN-GPE rsvd0", 5165 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5166 item_param), 5167 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5168 rsvd0)), 5169 }, 5170 [ITEM_VXLAN_GPE_RSVD1] = { 5171 .name = "rsvd1", 5172 .help = "VXLAN-GPE rsvd1", 5173 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 5174 item_param), 5175 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 5176 rsvd1)), 5177 }, 5178 [ITEM_ARP_ETH_IPV4] = { 5179 .name = "arp_eth_ipv4", 5180 .help = "match ARP header for Ethernet/IPv4", 5181 .priv = PRIV_ITEM(ARP_ETH_IPV4, 5182 sizeof(struct rte_flow_item_arp_eth_ipv4)), 5183 .next = NEXT(item_arp_eth_ipv4), 5184 .call = parse_vc, 5185 }, 5186 [ITEM_ARP_ETH_IPV4_SHA] = { 5187 .name = "sha", 5188 .help = "sender hardware address", 5189 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5190 item_param), 5191 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5192 hdr.arp_data.arp_sha)), 5193 }, 5194 [ITEM_ARP_ETH_IPV4_SPA] = { 5195 .name = "spa", 5196 .help = "sender IPv4 address", 5197 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5198 item_param), 5199 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5200 hdr.arp_data.arp_sip)), 5201 }, 5202 [ITEM_ARP_ETH_IPV4_THA] = { 5203 .name = "tha", 5204 .help = "target hardware address", 5205 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 5206 item_param), 5207 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5208 hdr.arp_data.arp_tha)), 5209 }, 5210 [ITEM_ARP_ETH_IPV4_TPA] = { 5211 .name = "tpa", 5212 .help = "target IPv4 address", 5213 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 5214 item_param), 5215 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 5216 hdr.arp_data.arp_tip)), 5217 }, 5218 [ITEM_IPV6_EXT] = { 5219 .name = "ipv6_ext", 5220 .help = "match presence of any IPv6 extension header", 5221 .priv = PRIV_ITEM(IPV6_EXT, 5222 sizeof(struct rte_flow_item_ipv6_ext)), 5223 .next = NEXT(item_ipv6_ext), 5224 .call = parse_vc, 5225 }, 5226 [ITEM_IPV6_EXT_NEXT_HDR] = { 5227 .name = "next_hdr", 5228 .help = "next header", 5229 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5230 item_param), 5231 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 5232 next_hdr)), 5233 }, 5234 [ITEM_IPV6_FRAG_EXT] = { 5235 .name = "ipv6_frag_ext", 5236 .help = "match presence of IPv6 fragment extension header", 5237 .priv = PRIV_ITEM(IPV6_FRAG_EXT, 5238 sizeof(struct rte_flow_item_ipv6_frag_ext)), 5239 .next = NEXT(item_ipv6_frag_ext), 5240 .call = parse_vc, 5241 }, 5242 [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { 5243 .name = "next_hdr", 5244 .help = "next header", 5245 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5246 item_param), 5247 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, 5248 hdr.next_header)), 5249 }, 5250 [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { 5251 .name = "frag_data", 5252 .help = "fragment flags and offset", 5253 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5254 item_param), 5255 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5256 hdr.frag_data)), 5257 }, 5258 [ITEM_IPV6_FRAG_EXT_ID] = { 5259 .name = "packet_id", 5260 .help = "fragment packet id", 5261 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 5262 item_param), 5263 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 5264 hdr.id)), 5265 }, 5266 [ITEM_ICMP6] = { 5267 .name = "icmp6", 5268 .help = "match any ICMPv6 header", 5269 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), 5270 .next = NEXT(item_icmp6), 5271 .call = parse_vc, 5272 }, 5273 [ITEM_ICMP6_TYPE] = { 5274 .name = "type", 5275 .help = "ICMPv6 type", 5276 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5277 item_param), 5278 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5279 type)), 5280 }, 5281 [ITEM_ICMP6_CODE] = { 5282 .name = "code", 5283 .help = "ICMPv6 code", 5284 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 5285 item_param), 5286 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 5287 code)), 5288 }, 5289 [ITEM_ICMP6_ECHO_REQUEST] = { 5290 .name = "icmp6_echo_request", 5291 .help = "match ICMPv6 echo request", 5292 .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, 5293 sizeof(struct rte_flow_item_icmp6_echo)), 5294 .next = NEXT(item_icmp6_echo_request), 5295 .call = parse_vc, 5296 }, 5297 [ITEM_ICMP6_ECHO_REQUEST_ID] = { 5298 .name = "ident", 5299 .help = "ICMPv6 echo request identifier", 5300 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5301 item_param), 5302 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5303 hdr.identifier)), 5304 }, 5305 [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { 5306 .name = "seq", 5307 .help = "ICMPv6 echo request sequence", 5308 .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), 5309 item_param), 5310 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5311 hdr.sequence)), 5312 }, 5313 [ITEM_ICMP6_ECHO_REPLY] = { 5314 .name = "icmp6_echo_reply", 5315 .help = "match ICMPv6 echo reply", 5316 .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, 5317 sizeof(struct rte_flow_item_icmp6_echo)), 5318 .next = NEXT(item_icmp6_echo_reply), 5319 .call = parse_vc, 5320 }, 5321 [ITEM_ICMP6_ECHO_REPLY_ID] = { 5322 .name = "ident", 5323 .help = "ICMPv6 echo reply identifier", 5324 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5325 item_param), 5326 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5327 hdr.identifier)), 5328 }, 5329 [ITEM_ICMP6_ECHO_REPLY_SEQ] = { 5330 .name = "seq", 5331 .help = "ICMPv6 echo reply sequence", 5332 .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), 5333 item_param), 5334 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, 5335 hdr.sequence)), 5336 }, 5337 [ITEM_ICMP6_ND_NS] = { 5338 .name = "icmp6_nd_ns", 5339 .help = "match ICMPv6 neighbor discovery solicitation", 5340 .priv = PRIV_ITEM(ICMP6_ND_NS, 5341 sizeof(struct rte_flow_item_icmp6_nd_ns)), 5342 .next = NEXT(item_icmp6_nd_ns), 5343 .call = parse_vc, 5344 }, 5345 [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { 5346 .name = "target_addr", 5347 .help = "target address", 5348 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), 5349 item_param), 5350 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, 5351 target_addr)), 5352 }, 5353 [ITEM_ICMP6_ND_NA] = { 5354 .name = "icmp6_nd_na", 5355 .help = "match ICMPv6 neighbor discovery advertisement", 5356 .priv = PRIV_ITEM(ICMP6_ND_NA, 5357 sizeof(struct rte_flow_item_icmp6_nd_na)), 5358 .next = NEXT(item_icmp6_nd_na), 5359 .call = parse_vc, 5360 }, 5361 [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { 5362 .name = "target_addr", 5363 .help = "target address", 5364 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), 5365 item_param), 5366 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, 5367 target_addr)), 5368 }, 5369 [ITEM_ICMP6_ND_OPT] = { 5370 .name = "icmp6_nd_opt", 5371 .help = "match presence of any ICMPv6 neighbor discovery" 5372 " option", 5373 .priv = PRIV_ITEM(ICMP6_ND_OPT, 5374 sizeof(struct rte_flow_item_icmp6_nd_opt)), 5375 .next = NEXT(item_icmp6_nd_opt), 5376 .call = parse_vc, 5377 }, 5378 [ITEM_ICMP6_ND_OPT_TYPE] = { 5379 .name = "type", 5380 .help = "ND option type", 5381 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5382 item_param), 5383 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, 5384 type)), 5385 }, 5386 [ITEM_ICMP6_ND_OPT_SLA_ETH] = { 5387 .name = "icmp6_nd_opt_sla_eth", 5388 .help = "match ICMPv6 neighbor discovery source Ethernet" 5389 " link-layer address option", 5390 .priv = PRIV_ITEM 5391 (ICMP6_ND_OPT_SLA_ETH, 5392 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), 5393 .next = NEXT(item_icmp6_nd_opt_sla_eth), 5394 .call = parse_vc, 5395 }, 5396 [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { 5397 .name = "sla", 5398 .help = "source Ethernet LLA", 5399 .next = NEXT(item_icmp6_nd_opt_sla_eth, 5400 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5401 .args = ARGS(ARGS_ENTRY_HTON 5402 (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), 5403 }, 5404 [ITEM_ICMP6_ND_OPT_TLA_ETH] = { 5405 .name = "icmp6_nd_opt_tla_eth", 5406 .help = "match ICMPv6 neighbor discovery target Ethernet" 5407 " link-layer address option", 5408 .priv = PRIV_ITEM 5409 (ICMP6_ND_OPT_TLA_ETH, 5410 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), 5411 .next = NEXT(item_icmp6_nd_opt_tla_eth), 5412 .call = parse_vc, 5413 }, 5414 [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { 5415 .name = "tla", 5416 .help = "target Ethernet LLA", 5417 .next = NEXT(item_icmp6_nd_opt_tla_eth, 5418 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 5419 .args = ARGS(ARGS_ENTRY_HTON 5420 (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), 5421 }, 5422 [ITEM_META] = { 5423 .name = "meta", 5424 .help = "match metadata header", 5425 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), 5426 .next = NEXT(item_meta), 5427 .call = parse_vc, 5428 }, 5429 [ITEM_META_DATA] = { 5430 .name = "data", 5431 .help = "metadata value", 5432 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), 5433 item_param), 5434 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, 5435 data, "\xff\xff\xff\xff")), 5436 }, 5437 [ITEM_RANDOM] = { 5438 .name = "random", 5439 .help = "match random value", 5440 .priv = PRIV_ITEM(RANDOM, sizeof(struct rte_flow_item_random)), 5441 .next = NEXT(item_random), 5442 .call = parse_vc, 5443 }, 5444 [ITEM_RANDOM_VALUE] = { 5445 .name = "value", 5446 .help = "random value", 5447 .next = NEXT(item_random, NEXT_ENTRY(COMMON_UNSIGNED), 5448 item_param), 5449 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_random, 5450 value, "\xff\xff")), 5451 }, 5452 [ITEM_GRE_KEY] = { 5453 .name = "gre_key", 5454 .help = "match GRE key", 5455 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), 5456 .next = NEXT(item_gre_key), 5457 .call = parse_vc, 5458 }, 5459 [ITEM_GRE_KEY_VALUE] = { 5460 .name = "value", 5461 .help = "key value", 5462 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), 5463 item_param), 5464 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5465 }, 5466 [ITEM_GRE_OPTION] = { 5467 .name = "gre_option", 5468 .help = "match GRE optional fields", 5469 .priv = PRIV_ITEM(GRE_OPTION, 5470 sizeof(struct rte_flow_item_gre_opt)), 5471 .next = NEXT(item_gre_option), 5472 .call = parse_vc, 5473 }, 5474 [ITEM_GRE_OPTION_CHECKSUM] = { 5475 .name = "checksum", 5476 .help = "match GRE checksum", 5477 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5478 item_param), 5479 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5480 checksum_rsvd.checksum)), 5481 }, 5482 [ITEM_GRE_OPTION_KEY] = { 5483 .name = "key", 5484 .help = "match GRE key", 5485 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5486 item_param), 5487 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5488 key.key)), 5489 }, 5490 [ITEM_GRE_OPTION_SEQUENCE] = { 5491 .name = "sequence", 5492 .help = "match GRE sequence", 5493 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 5494 item_param), 5495 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 5496 sequence.sequence)), 5497 }, 5498 [ITEM_GTP_PSC] = { 5499 .name = "gtp_psc", 5500 .help = "match GTP extension header with type 0x85", 5501 .priv = PRIV_ITEM(GTP_PSC, 5502 sizeof(struct rte_flow_item_gtp_psc)), 5503 .next = NEXT(item_gtp_psc), 5504 .call = parse_vc, 5505 }, 5506 [ITEM_GTP_PSC_QFI] = { 5507 .name = "qfi", 5508 .help = "QoS flow identifier", 5509 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5510 item_param), 5511 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5512 hdr.qfi, 6)), 5513 }, 5514 [ITEM_GTP_PSC_PDU_T] = { 5515 .name = "pdu_t", 5516 .help = "PDU type", 5517 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 5518 item_param), 5519 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 5520 hdr.type, 4)), 5521 }, 5522 [ITEM_PPPOES] = { 5523 .name = "pppoes", 5524 .help = "match PPPoE session header", 5525 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), 5526 .next = NEXT(item_pppoes), 5527 .call = parse_vc, 5528 }, 5529 [ITEM_PPPOED] = { 5530 .name = "pppoed", 5531 .help = "match PPPoE discovery header", 5532 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), 5533 .next = NEXT(item_pppoed), 5534 .call = parse_vc, 5535 }, 5536 [ITEM_PPPOE_SEID] = { 5537 .name = "seid", 5538 .help = "session identifier", 5539 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), 5540 item_param), 5541 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, 5542 session_id)), 5543 }, 5544 [ITEM_PPPOE_PROTO_ID] = { 5545 .name = "pppoe_proto_id", 5546 .help = "match PPPoE session protocol identifier", 5547 .priv = PRIV_ITEM(PPPOE_PROTO_ID, 5548 sizeof(struct rte_flow_item_pppoe_proto_id)), 5549 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED), 5550 item_param), 5551 .args = ARGS(ARGS_ENTRY_HTON 5552 (struct rte_flow_item_pppoe_proto_id, proto_id)), 5553 .call = parse_vc, 5554 }, 5555 [ITEM_HIGIG2] = { 5556 .name = "higig2", 5557 .help = "matches higig2 header", 5558 .priv = PRIV_ITEM(HIGIG2, 5559 sizeof(struct rte_flow_item_higig2_hdr)), 5560 .next = NEXT(item_higig2), 5561 .call = parse_vc, 5562 }, 5563 [ITEM_HIGIG2_CLASSIFICATION] = { 5564 .name = "classification", 5565 .help = "matches classification of higig2 header", 5566 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5567 item_param), 5568 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5569 hdr.ppt1.classification)), 5570 }, 5571 [ITEM_HIGIG2_VID] = { 5572 .name = "vid", 5573 .help = "matches vid of higig2 header", 5574 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 5575 item_param), 5576 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 5577 hdr.ppt1.vid)), 5578 }, 5579 [ITEM_TAG] = { 5580 .name = "tag", 5581 .help = "match tag value", 5582 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), 5583 .next = NEXT(item_tag), 5584 .call = parse_vc, 5585 }, 5586 [ITEM_TAG_DATA] = { 5587 .name = "data", 5588 .help = "tag value to match", 5589 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5590 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), 5591 }, 5592 [ITEM_TAG_INDEX] = { 5593 .name = "index", 5594 .help = "index of tag array to match", 5595 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), 5596 NEXT_ENTRY(ITEM_PARAM_IS)), 5597 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), 5598 }, 5599 [ITEM_L2TPV3OIP] = { 5600 .name = "l2tpv3oip", 5601 .help = "match L2TPv3 over IP header", 5602 .priv = PRIV_ITEM(L2TPV3OIP, 5603 sizeof(struct rte_flow_item_l2tpv3oip)), 5604 .next = NEXT(item_l2tpv3oip), 5605 .call = parse_vc, 5606 }, 5607 [ITEM_L2TPV3OIP_SESSION_ID] = { 5608 .name = "session_id", 5609 .help = "session identifier", 5610 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), 5611 item_param), 5612 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, 5613 session_id)), 5614 }, 5615 [ITEM_ESP] = { 5616 .name = "esp", 5617 .help = "match ESP header", 5618 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), 5619 .next = NEXT(item_esp), 5620 .call = parse_vc, 5621 }, 5622 [ITEM_ESP_SPI] = { 5623 .name = "spi", 5624 .help = "security policy index", 5625 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5626 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, 5627 hdr.spi)), 5628 }, 5629 [ITEM_AH] = { 5630 .name = "ah", 5631 .help = "match AH header", 5632 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), 5633 .next = NEXT(item_ah), 5634 .call = parse_vc, 5635 }, 5636 [ITEM_AH_SPI] = { 5637 .name = "spi", 5638 .help = "security parameters index", 5639 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5640 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), 5641 }, 5642 [ITEM_PFCP] = { 5643 .name = "pfcp", 5644 .help = "match pfcp header", 5645 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), 5646 .next = NEXT(item_pfcp), 5647 .call = parse_vc, 5648 }, 5649 [ITEM_PFCP_S_FIELD] = { 5650 .name = "s_field", 5651 .help = "S field", 5652 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5653 item_param), 5654 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, 5655 s_field)), 5656 }, 5657 [ITEM_PFCP_SEID] = { 5658 .name = "seid", 5659 .help = "session endpoint identifier", 5660 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 5661 item_param), 5662 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), 5663 }, 5664 [ITEM_ECPRI] = { 5665 .name = "ecpri", 5666 .help = "match eCPRI header", 5667 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), 5668 .next = NEXT(item_ecpri), 5669 .call = parse_vc, 5670 }, 5671 [ITEM_ECPRI_COMMON] = { 5672 .name = "common", 5673 .help = "eCPRI common header", 5674 .next = NEXT(item_ecpri_common), 5675 }, 5676 [ITEM_ECPRI_COMMON_TYPE] = { 5677 .name = "type", 5678 .help = "type of common header", 5679 .next = NEXT(item_ecpri_common_type), 5680 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), 5681 }, 5682 [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { 5683 .name = "iq_data", 5684 .help = "Type #0: IQ Data", 5685 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5686 ITEM_NEXT)), 5687 .call = parse_vc_item_ecpri_type, 5688 }, 5689 [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { 5690 .name = "pc_id", 5691 .help = "Physical Channel ID", 5692 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 5693 ITEM_ECPRI_COMMON, ITEM_NEXT), 5694 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5695 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5696 hdr.type0.pc_id)), 5697 }, 5698 [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { 5699 .name = "rtc_ctrl", 5700 .help = "Type #2: Real-Time Control Data", 5701 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5702 ITEM_NEXT)), 5703 .call = parse_vc_item_ecpri_type, 5704 }, 5705 [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { 5706 .name = "rtc_id", 5707 .help = "Real-Time Control Data ID", 5708 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 5709 ITEM_ECPRI_COMMON, ITEM_NEXT), 5710 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5711 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5712 hdr.type2.rtc_id)), 5713 }, 5714 [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { 5715 .name = "delay_measure", 5716 .help = "Type #5: One-Way Delay Measurement", 5717 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5718 ITEM_NEXT)), 5719 .call = parse_vc_item_ecpri_type, 5720 }, 5721 [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { 5722 .name = "msr_id", 5723 .help = "Measurement ID", 5724 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 5725 ITEM_ECPRI_COMMON, ITEM_NEXT), 5726 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 5727 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 5728 hdr.type5.msr_id)), 5729 }, 5730 [ITEM_GENEVE_OPT] = { 5731 .name = "geneve-opt", 5732 .help = "GENEVE header option", 5733 .priv = PRIV_ITEM(GENEVE_OPT, 5734 sizeof(struct rte_flow_item_geneve_opt) + 5735 ITEM_GENEVE_OPT_DATA_SIZE), 5736 .next = NEXT(item_geneve_opt), 5737 .call = parse_vc, 5738 }, 5739 [ITEM_GENEVE_OPT_CLASS] = { 5740 .name = "class", 5741 .help = "GENEVE option class", 5742 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5743 item_param), 5744 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, 5745 option_class)), 5746 }, 5747 [ITEM_GENEVE_OPT_TYPE] = { 5748 .name = "type", 5749 .help = "GENEVE option type", 5750 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5751 item_param), 5752 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, 5753 option_type)), 5754 }, 5755 [ITEM_GENEVE_OPT_LENGTH] = { 5756 .name = "length", 5757 .help = "GENEVE option data length (in 32b words)", 5758 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 5759 item_param), 5760 .args = ARGS(ARGS_ENTRY_BOUNDED( 5761 struct rte_flow_item_geneve_opt, option_len, 5762 0, 31)), 5763 }, 5764 [ITEM_GENEVE_OPT_DATA] = { 5765 .name = "data", 5766 .help = "GENEVE option data pattern", 5767 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), 5768 item_param), 5769 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), 5770 ARGS_ENTRY_ARB(0, 0), 5771 ARGS_ENTRY_ARB 5772 (sizeof(struct rte_flow_item_geneve_opt), 5773 ITEM_GENEVE_OPT_DATA_SIZE)), 5774 }, 5775 [ITEM_INTEGRITY] = { 5776 .name = "integrity", 5777 .help = "match packet integrity", 5778 .priv = PRIV_ITEM(INTEGRITY, 5779 sizeof(struct rte_flow_item_integrity)), 5780 .next = NEXT(item_integrity), 5781 .call = parse_vc, 5782 }, 5783 [ITEM_INTEGRITY_LEVEL] = { 5784 .name = "level", 5785 .help = "integrity level", 5786 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5787 item_param), 5788 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), 5789 }, 5790 [ITEM_INTEGRITY_VALUE] = { 5791 .name = "value", 5792 .help = "integrity value", 5793 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 5794 item_param), 5795 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), 5796 }, 5797 [ITEM_CONNTRACK] = { 5798 .name = "conntrack", 5799 .help = "conntrack state", 5800 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 5801 item_param), 5802 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 5803 }, 5804 [ITEM_PORT_REPRESENTOR] = { 5805 .name = "port_representor", 5806 .help = "match traffic entering the embedded switch from the given ethdev", 5807 .priv = PRIV_ITEM(PORT_REPRESENTOR, 5808 sizeof(struct rte_flow_item_ethdev)), 5809 .next = NEXT(item_port_representor), 5810 .call = parse_vc, 5811 }, 5812 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 5813 .name = "port_id", 5814 .help = "ethdev port ID", 5815 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 5816 item_param), 5817 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5818 }, 5819 [ITEM_REPRESENTED_PORT] = { 5820 .name = "represented_port", 5821 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 5822 .priv = PRIV_ITEM(REPRESENTED_PORT, 5823 sizeof(struct rte_flow_item_ethdev)), 5824 .next = NEXT(item_represented_port), 5825 .call = parse_vc, 5826 }, 5827 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 5828 .name = "ethdev_port_id", 5829 .help = "ethdev port ID", 5830 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 5831 item_param), 5832 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 5833 }, 5834 [ITEM_FLEX] = { 5835 .name = "flex", 5836 .help = "match flex header", 5837 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 5838 .next = NEXT(item_flex), 5839 .call = parse_vc, 5840 }, 5841 [ITEM_FLEX_ITEM_HANDLE] = { 5842 .name = "item", 5843 .help = "flex item handle", 5844 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5845 NEXT_ENTRY(ITEM_PARAM_IS)), 5846 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 5847 }, 5848 [ITEM_FLEX_PATTERN_HANDLE] = { 5849 .name = "pattern", 5850 .help = "flex pattern handle", 5851 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 5852 NEXT_ENTRY(ITEM_PARAM_IS)), 5853 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 5854 }, 5855 [ITEM_L2TPV2] = { 5856 .name = "l2tpv2", 5857 .help = "match L2TPv2 header", 5858 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 5859 .next = NEXT(item_l2tpv2), 5860 .call = parse_vc, 5861 }, 5862 [ITEM_L2TPV2_TYPE] = { 5863 .name = "type", 5864 .help = "type of l2tpv2", 5865 .next = NEXT(item_l2tpv2_type), 5866 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 5867 }, 5868 [ITEM_L2TPV2_TYPE_DATA] = { 5869 .name = "data", 5870 .help = "Type #7: data message without any options", 5871 .next = NEXT(item_l2tpv2_type_data), 5872 .call = parse_vc_item_l2tpv2_type, 5873 }, 5874 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 5875 .name = "tunnel_id", 5876 .help = "tunnel identifier", 5877 .next = NEXT(item_l2tpv2_type_data, 5878 NEXT_ENTRY(COMMON_UNSIGNED), 5879 item_param), 5880 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5881 hdr.type7.tunnel_id)), 5882 }, 5883 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 5884 .name = "session_id", 5885 .help = "session identifier", 5886 .next = NEXT(item_l2tpv2_type_data, 5887 NEXT_ENTRY(COMMON_UNSIGNED), 5888 item_param), 5889 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5890 hdr.type7.session_id)), 5891 }, 5892 [ITEM_L2TPV2_TYPE_DATA_L] = { 5893 .name = "data_l", 5894 .help = "Type #6: data message with length option", 5895 .next = NEXT(item_l2tpv2_type_data_l), 5896 .call = parse_vc_item_l2tpv2_type, 5897 }, 5898 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 5899 .name = "length", 5900 .help = "message length", 5901 .next = NEXT(item_l2tpv2_type_data_l, 5902 NEXT_ENTRY(COMMON_UNSIGNED), 5903 item_param), 5904 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5905 hdr.type6.length)), 5906 }, 5907 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 5908 .name = "tunnel_id", 5909 .help = "tunnel identifier", 5910 .next = NEXT(item_l2tpv2_type_data_l, 5911 NEXT_ENTRY(COMMON_UNSIGNED), 5912 item_param), 5913 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5914 hdr.type6.tunnel_id)), 5915 }, 5916 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 5917 .name = "session_id", 5918 .help = "session identifier", 5919 .next = NEXT(item_l2tpv2_type_data_l, 5920 NEXT_ENTRY(COMMON_UNSIGNED), 5921 item_param), 5922 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5923 hdr.type6.session_id)), 5924 }, 5925 [ITEM_L2TPV2_TYPE_DATA_S] = { 5926 .name = "data_s", 5927 .help = "Type #5: data message with ns, nr option", 5928 .next = NEXT(item_l2tpv2_type_data_s), 5929 .call = parse_vc_item_l2tpv2_type, 5930 }, 5931 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 5932 .name = "tunnel_id", 5933 .help = "tunnel identifier", 5934 .next = NEXT(item_l2tpv2_type_data_s, 5935 NEXT_ENTRY(COMMON_UNSIGNED), 5936 item_param), 5937 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5938 hdr.type5.tunnel_id)), 5939 }, 5940 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 5941 .name = "session_id", 5942 .help = "session identifier", 5943 .next = NEXT(item_l2tpv2_type_data_s, 5944 NEXT_ENTRY(COMMON_UNSIGNED), 5945 item_param), 5946 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5947 hdr.type5.session_id)), 5948 }, 5949 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 5950 .name = "ns", 5951 .help = "sequence number for message", 5952 .next = NEXT(item_l2tpv2_type_data_s, 5953 NEXT_ENTRY(COMMON_UNSIGNED), 5954 item_param), 5955 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5956 hdr.type5.ns)), 5957 }, 5958 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 5959 .name = "nr", 5960 .help = "sequence number for next receive message", 5961 .next = NEXT(item_l2tpv2_type_data_s, 5962 NEXT_ENTRY(COMMON_UNSIGNED), 5963 item_param), 5964 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5965 hdr.type5.nr)), 5966 }, 5967 [ITEM_L2TPV2_TYPE_DATA_O] = { 5968 .name = "data_o", 5969 .help = "Type #4: data message with offset option", 5970 .next = NEXT(item_l2tpv2_type_data_o), 5971 .call = parse_vc_item_l2tpv2_type, 5972 }, 5973 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 5974 .name = "tunnel_id", 5975 .help = "tunnel identifier", 5976 .next = NEXT(item_l2tpv2_type_data_o, 5977 NEXT_ENTRY(COMMON_UNSIGNED), 5978 item_param), 5979 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5980 hdr.type4.tunnel_id)), 5981 }, 5982 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 5983 .name = "session_id", 5984 .help = "session identifier", 5985 .next = NEXT(item_l2tpv2_type_data_o, 5986 NEXT_ENTRY(COMMON_UNSIGNED), 5987 item_param), 5988 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5989 hdr.type5.session_id)), 5990 }, 5991 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 5992 .name = "offset_size", 5993 .help = "the size of offset padding", 5994 .next = NEXT(item_l2tpv2_type_data_o, 5995 NEXT_ENTRY(COMMON_UNSIGNED), 5996 item_param), 5997 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5998 hdr.type4.offset_size)), 5999 }, 6000 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 6001 .name = "data_l_s", 6002 .help = "Type #3: data message contains length, ns, nr " 6003 "options", 6004 .next = NEXT(item_l2tpv2_type_data_l_s), 6005 .call = parse_vc_item_l2tpv2_type, 6006 }, 6007 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 6008 .name = "length", 6009 .help = "message length", 6010 .next = NEXT(item_l2tpv2_type_data_l_s, 6011 NEXT_ENTRY(COMMON_UNSIGNED), 6012 item_param), 6013 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6014 hdr.type3.length)), 6015 }, 6016 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 6017 .name = "tunnel_id", 6018 .help = "tunnel identifier", 6019 .next = NEXT(item_l2tpv2_type_data_l_s, 6020 NEXT_ENTRY(COMMON_UNSIGNED), 6021 item_param), 6022 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6023 hdr.type3.tunnel_id)), 6024 }, 6025 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 6026 .name = "session_id", 6027 .help = "session identifier", 6028 .next = NEXT(item_l2tpv2_type_data_l_s, 6029 NEXT_ENTRY(COMMON_UNSIGNED), 6030 item_param), 6031 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6032 hdr.type3.session_id)), 6033 }, 6034 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 6035 .name = "ns", 6036 .help = "sequence number for message", 6037 .next = NEXT(item_l2tpv2_type_data_l_s, 6038 NEXT_ENTRY(COMMON_UNSIGNED), 6039 item_param), 6040 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6041 hdr.type3.ns)), 6042 }, 6043 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 6044 .name = "nr", 6045 .help = "sequence number for next receive message", 6046 .next = NEXT(item_l2tpv2_type_data_l_s, 6047 NEXT_ENTRY(COMMON_UNSIGNED), 6048 item_param), 6049 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6050 hdr.type3.nr)), 6051 }, 6052 [ITEM_L2TPV2_TYPE_CTRL] = { 6053 .name = "control", 6054 .help = "Type #3: conrtol message contains length, ns, nr " 6055 "options", 6056 .next = NEXT(item_l2tpv2_type_ctrl), 6057 .call = parse_vc_item_l2tpv2_type, 6058 }, 6059 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 6060 .name = "length", 6061 .help = "message length", 6062 .next = NEXT(item_l2tpv2_type_ctrl, 6063 NEXT_ENTRY(COMMON_UNSIGNED), 6064 item_param), 6065 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6066 hdr.type3.length)), 6067 }, 6068 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 6069 .name = "tunnel_id", 6070 .help = "tunnel identifier", 6071 .next = NEXT(item_l2tpv2_type_ctrl, 6072 NEXT_ENTRY(COMMON_UNSIGNED), 6073 item_param), 6074 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6075 hdr.type3.tunnel_id)), 6076 }, 6077 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 6078 .name = "session_id", 6079 .help = "session identifier", 6080 .next = NEXT(item_l2tpv2_type_ctrl, 6081 NEXT_ENTRY(COMMON_UNSIGNED), 6082 item_param), 6083 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6084 hdr.type3.session_id)), 6085 }, 6086 [ITEM_L2TPV2_MSG_CTRL_NS] = { 6087 .name = "ns", 6088 .help = "sequence number for message", 6089 .next = NEXT(item_l2tpv2_type_ctrl, 6090 NEXT_ENTRY(COMMON_UNSIGNED), 6091 item_param), 6092 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6093 hdr.type3.ns)), 6094 }, 6095 [ITEM_L2TPV2_MSG_CTRL_NR] = { 6096 .name = "nr", 6097 .help = "sequence number for next receive message", 6098 .next = NEXT(item_l2tpv2_type_ctrl, 6099 NEXT_ENTRY(COMMON_UNSIGNED), 6100 item_param), 6101 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 6102 hdr.type3.nr)), 6103 }, 6104 [ITEM_PPP] = { 6105 .name = "ppp", 6106 .help = "match PPP header", 6107 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 6108 .next = NEXT(item_ppp), 6109 .call = parse_vc, 6110 }, 6111 [ITEM_PPP_ADDR] = { 6112 .name = "addr", 6113 .help = "PPP address", 6114 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6115 item_param), 6116 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 6117 }, 6118 [ITEM_PPP_CTRL] = { 6119 .name = "ctrl", 6120 .help = "PPP control", 6121 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6122 item_param), 6123 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 6124 }, 6125 [ITEM_PPP_PROTO_ID] = { 6126 .name = "proto_id", 6127 .help = "PPP protocol identifier", 6128 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 6129 item_param), 6130 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 6131 hdr.proto_id)), 6132 }, 6133 [ITEM_METER] = { 6134 .name = "meter", 6135 .help = "match meter color", 6136 .priv = PRIV_ITEM(METER_COLOR, 6137 sizeof(struct rte_flow_item_meter_color)), 6138 .next = NEXT(item_meter), 6139 .call = parse_vc, 6140 }, 6141 [ITEM_METER_COLOR] = { 6142 .name = "color", 6143 .help = "meter color", 6144 .next = NEXT(item_meter, 6145 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 6146 item_param), 6147 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 6148 color)), 6149 }, 6150 [ITEM_METER_COLOR_NAME] = { 6151 .name = "color_name", 6152 .help = "meter color name", 6153 .call = parse_meter_color, 6154 .comp = comp_meter_color, 6155 }, 6156 [ITEM_QUOTA] = { 6157 .name = "quota", 6158 .help = "match quota", 6159 .priv = PRIV_ITEM(QUOTA, sizeof(struct rte_flow_item_quota)), 6160 .next = NEXT(item_quota), 6161 .call = parse_vc 6162 }, 6163 [ITEM_QUOTA_STATE] = { 6164 .name = "quota_state", 6165 .help = "quota state", 6166 .next = NEXT(item_quota, NEXT_ENTRY(ITEM_QUOTA_STATE_NAME), 6167 NEXT_ENTRY(ITEM_PARAM_SPEC, ITEM_PARAM_MASK)), 6168 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_quota, state)) 6169 }, 6170 [ITEM_QUOTA_STATE_NAME] = { 6171 .name = "state_name", 6172 .help = "quota state name", 6173 .call = parse_quota_state_name, 6174 .comp = comp_quota_state_name 6175 }, 6176 [ITEM_IB_BTH] = { 6177 .name = "ib_bth", 6178 .help = "match ib bth fields", 6179 .priv = PRIV_ITEM(IB_BTH, 6180 sizeof(struct rte_flow_item_ib_bth)), 6181 .next = NEXT(item_ib_bth), 6182 .call = parse_vc, 6183 }, 6184 [ITEM_IB_BTH_OPCODE] = { 6185 .name = "opcode", 6186 .help = "match ib bth opcode", 6187 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6188 item_param), 6189 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6190 hdr.opcode)), 6191 }, 6192 [ITEM_IB_BTH_PKEY] = { 6193 .name = "pkey", 6194 .help = "partition key", 6195 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6196 item_param), 6197 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6198 hdr.pkey)), 6199 }, 6200 [ITEM_IB_BTH_DST_QPN] = { 6201 .name = "dst_qp", 6202 .help = "destination qp", 6203 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6204 item_param), 6205 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6206 hdr.dst_qp)), 6207 }, 6208 [ITEM_IB_BTH_PSN] = { 6209 .name = "psn", 6210 .help = "packet sequence number", 6211 .next = NEXT(item_ib_bth, NEXT_ENTRY(COMMON_UNSIGNED), 6212 item_param), 6213 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ib_bth, 6214 hdr.psn)), 6215 }, 6216 [ITEM_PTYPE] = { 6217 .name = "ptype", 6218 .help = "match L2/L3/L4 and tunnel information", 6219 .priv = PRIV_ITEM(PTYPE, 6220 sizeof(struct rte_flow_item_ptype)), 6221 .next = NEXT(item_ptype), 6222 .call = parse_vc, 6223 }, 6224 [ITEM_PTYPE_VALUE] = { 6225 .name = "packet_type", 6226 .help = "packet type as defined in rte_mbuf_ptype", 6227 .next = NEXT(item_ptype, NEXT_ENTRY(COMMON_UNSIGNED), 6228 item_param), 6229 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ptype, packet_type)), 6230 }, 6231 [ITEM_NSH] = { 6232 .name = "nsh", 6233 .help = "match NSH header", 6234 .priv = PRIV_ITEM(NSH, 6235 sizeof(struct rte_flow_item_nsh)), 6236 .next = NEXT(item_nsh), 6237 .call = parse_vc, 6238 }, 6239 [ITEM_COMPARE] = { 6240 .name = "compare", 6241 .help = "match with the comparison result", 6242 .priv = PRIV_ITEM(COMPARE, sizeof(struct rte_flow_item_compare)), 6243 .next = NEXT(NEXT_ENTRY(ITEM_COMPARE_OP)), 6244 .call = parse_vc, 6245 }, 6246 [ITEM_COMPARE_OP] = { 6247 .name = "op", 6248 .help = "operation type", 6249 .next = NEXT(item_compare_field, 6250 NEXT_ENTRY(ITEM_COMPARE_OP_VALUE), item_param), 6251 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, operation)), 6252 }, 6253 [ITEM_COMPARE_OP_VALUE] = { 6254 .name = "{operation}", 6255 .help = "operation type value", 6256 .call = parse_vc_compare_op, 6257 .comp = comp_set_compare_op, 6258 }, 6259 [ITEM_COMPARE_FIELD_A_TYPE] = { 6260 .name = "a_type", 6261 .help = "compared field type", 6262 .next = NEXT(compare_field_a, 6263 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_TYPE_VALUE), item_param), 6264 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.field)), 6265 }, 6266 [ITEM_COMPARE_FIELD_A_TYPE_VALUE] = { 6267 .name = "{a_type}", 6268 .help = "compared field type value", 6269 .call = parse_vc_compare_field_id, 6270 .comp = comp_set_compare_field_id, 6271 }, 6272 [ITEM_COMPARE_FIELD_A_LEVEL] = { 6273 .name = "a_level", 6274 .help = "compared field level", 6275 .next = NEXT(compare_field_a, 6276 NEXT_ENTRY(ITEM_COMPARE_FIELD_A_LEVEL_VALUE), item_param), 6277 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, a.level)), 6278 }, 6279 [ITEM_COMPARE_FIELD_A_LEVEL_VALUE] = { 6280 .name = "{a_level}", 6281 .help = "compared field level value", 6282 .call = parse_vc_compare_field_level, 6283 .comp = comp_none, 6284 }, 6285 [ITEM_COMPARE_FIELD_A_TAG_INDEX] = { 6286 .name = "a_tag_index", 6287 .help = "compared field tag array", 6288 .next = NEXT(compare_field_a, 6289 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6290 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6291 a.tag_index)), 6292 }, 6293 [ITEM_COMPARE_FIELD_A_TYPE_ID] = { 6294 .name = "a_type_id", 6295 .help = "compared field type ID", 6296 .next = NEXT(compare_field_a, 6297 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6298 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6299 a.type)), 6300 }, 6301 [ITEM_COMPARE_FIELD_A_CLASS_ID] = { 6302 .name = "a_class", 6303 .help = "compared field class ID", 6304 .next = NEXT(compare_field_a, 6305 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6306 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6307 a.class_id)), 6308 }, 6309 [ITEM_COMPARE_FIELD_A_OFFSET] = { 6310 .name = "a_offset", 6311 .help = "compared field bit offset", 6312 .next = NEXT(compare_field_a, 6313 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6314 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6315 a.offset)), 6316 }, 6317 [ITEM_COMPARE_FIELD_B_TYPE] = { 6318 .name = "b_type", 6319 .help = "comparator field type", 6320 .next = NEXT(compare_field_b, 6321 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_TYPE_VALUE), item_param), 6322 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6323 b.field)), 6324 }, 6325 [ITEM_COMPARE_FIELD_B_TYPE_VALUE] = { 6326 .name = "{b_type}", 6327 .help = "comparator field type value", 6328 .call = parse_vc_compare_field_id, 6329 .comp = comp_set_compare_field_id, 6330 }, 6331 [ITEM_COMPARE_FIELD_B_LEVEL] = { 6332 .name = "b_level", 6333 .help = "comparator field level", 6334 .next = NEXT(compare_field_b, 6335 NEXT_ENTRY(ITEM_COMPARE_FIELD_B_LEVEL_VALUE), item_param), 6336 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6337 b.level)), 6338 }, 6339 [ITEM_COMPARE_FIELD_B_LEVEL_VALUE] = { 6340 .name = "{b_level}", 6341 .help = "comparator field level value", 6342 .call = parse_vc_compare_field_level, 6343 .comp = comp_none, 6344 }, 6345 [ITEM_COMPARE_FIELD_B_TAG_INDEX] = { 6346 .name = "b_tag_index", 6347 .help = "comparator field tag array", 6348 .next = NEXT(compare_field_b, 6349 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6350 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6351 b.tag_index)), 6352 }, 6353 [ITEM_COMPARE_FIELD_B_TYPE_ID] = { 6354 .name = "b_type_id", 6355 .help = "comparator field type ID", 6356 .next = NEXT(compare_field_b, 6357 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6358 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6359 b.type)), 6360 }, 6361 [ITEM_COMPARE_FIELD_B_CLASS_ID] = { 6362 .name = "b_class", 6363 .help = "comparator field class ID", 6364 .next = NEXT(compare_field_b, 6365 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6366 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_compare, 6367 b.class_id)), 6368 }, 6369 [ITEM_COMPARE_FIELD_B_OFFSET] = { 6370 .name = "b_offset", 6371 .help = "comparator field bit offset", 6372 .next = NEXT(compare_field_b, 6373 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6374 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6375 b.offset)), 6376 }, 6377 [ITEM_COMPARE_FIELD_B_VALUE] = { 6378 .name = "b_value", 6379 .help = "comparator immediate value", 6380 .next = NEXT(compare_field_b, 6381 NEXT_ENTRY(COMMON_HEX), item_param), 6382 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6383 ARGS_ENTRY_ARB(0, 0), 6384 ARGS_ENTRY(struct rte_flow_item_compare, 6385 b.value)), 6386 }, 6387 [ITEM_COMPARE_FIELD_B_POINTER] = { 6388 .name = "b_ptr", 6389 .help = "pointer to comparator immediate value", 6390 .next = NEXT(compare_field_b, 6391 NEXT_ENTRY(COMMON_HEX), item_param), 6392 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6393 b.pvalue), 6394 ARGS_ENTRY_ARB(0, 0), 6395 ARGS_ENTRY_ARB 6396 (sizeof(struct rte_flow_item_compare), 6397 FLOW_FIELD_PATTERN_SIZE)), 6398 }, 6399 [ITEM_COMPARE_FIELD_WIDTH] = { 6400 .name = "width", 6401 .help = "number of bits to compare", 6402 .next = NEXT(item_compare_field, 6403 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 6404 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_compare, 6405 width)), 6406 }, 6407 6408 /* Validate/create actions. */ 6409 [ACTIONS] = { 6410 .name = "actions", 6411 .help = "submit a list of associated actions", 6412 .next = NEXT(next_action), 6413 .call = parse_vc, 6414 }, 6415 [ACTION_NEXT] = { 6416 .name = "/", 6417 .help = "specify next action", 6418 .next = NEXT(next_action), 6419 }, 6420 [ACTION_END] = { 6421 .name = "end", 6422 .help = "end list of actions", 6423 .priv = PRIV_ACTION(END, 0), 6424 .call = parse_vc, 6425 }, 6426 [ACTION_VOID] = { 6427 .name = "void", 6428 .help = "no-op action", 6429 .priv = PRIV_ACTION(VOID, 0), 6430 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6431 .call = parse_vc, 6432 }, 6433 [ACTION_PASSTHRU] = { 6434 .name = "passthru", 6435 .help = "let subsequent rule process matched packets", 6436 .priv = PRIV_ACTION(PASSTHRU, 0), 6437 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6438 .call = parse_vc, 6439 }, 6440 [ACTION_SKIP_CMAN] = { 6441 .name = "skip_cman", 6442 .help = "bypass cman on received packets", 6443 .priv = PRIV_ACTION(SKIP_CMAN, 0), 6444 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6445 .call = parse_vc, 6446 }, 6447 [ACTION_JUMP] = { 6448 .name = "jump", 6449 .help = "redirect traffic to a given group", 6450 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 6451 .next = NEXT(action_jump), 6452 .call = parse_vc, 6453 }, 6454 [ACTION_JUMP_GROUP] = { 6455 .name = "group", 6456 .help = "group to redirect traffic to", 6457 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 6458 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 6459 .call = parse_vc_conf, 6460 }, 6461 [ACTION_MARK] = { 6462 .name = "mark", 6463 .help = "attach 32 bit value to packets", 6464 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 6465 .next = NEXT(action_mark), 6466 .call = parse_vc, 6467 }, 6468 [ACTION_MARK_ID] = { 6469 .name = "id", 6470 .help = "32 bit value to return with packets", 6471 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6472 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 6473 .call = parse_vc_conf, 6474 }, 6475 [ACTION_FLAG] = { 6476 .name = "flag", 6477 .help = "flag packets", 6478 .priv = PRIV_ACTION(FLAG, 0), 6479 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6480 .call = parse_vc, 6481 }, 6482 [ACTION_QUEUE] = { 6483 .name = "queue", 6484 .help = "assign packets to a given queue index", 6485 .priv = PRIV_ACTION(QUEUE, 6486 sizeof(struct rte_flow_action_queue)), 6487 .next = NEXT(action_queue), 6488 .call = parse_vc, 6489 }, 6490 [ACTION_QUEUE_INDEX] = { 6491 .name = "index", 6492 .help = "queue index to use", 6493 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 6494 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 6495 .call = parse_vc_conf, 6496 }, 6497 [ACTION_DROP] = { 6498 .name = "drop", 6499 .help = "drop packets (note: passthru has priority)", 6500 .priv = PRIV_ACTION(DROP, 0), 6501 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6502 .call = parse_vc, 6503 }, 6504 [ACTION_COUNT] = { 6505 .name = "count", 6506 .help = "enable counters for this rule", 6507 .priv = PRIV_ACTION(COUNT, 6508 sizeof(struct rte_flow_action_count)), 6509 .next = NEXT(action_count), 6510 .call = parse_vc, 6511 }, 6512 [ACTION_COUNT_ID] = { 6513 .name = "identifier", 6514 .help = "counter identifier to use", 6515 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 6516 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 6517 .call = parse_vc_conf, 6518 }, 6519 [ACTION_RSS] = { 6520 .name = "rss", 6521 .help = "spread packets among several queues", 6522 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 6523 .next = NEXT(action_rss), 6524 .call = parse_vc_action_rss, 6525 }, 6526 [ACTION_RSS_FUNC] = { 6527 .name = "func", 6528 .help = "RSS hash function to apply", 6529 .next = NEXT(action_rss, 6530 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 6531 ACTION_RSS_FUNC_TOEPLITZ, 6532 ACTION_RSS_FUNC_SIMPLE_XOR, 6533 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 6534 }, 6535 [ACTION_RSS_FUNC_DEFAULT] = { 6536 .name = "default", 6537 .help = "default hash function", 6538 .call = parse_vc_action_rss_func, 6539 }, 6540 [ACTION_RSS_FUNC_TOEPLITZ] = { 6541 .name = "toeplitz", 6542 .help = "Toeplitz hash function", 6543 .call = parse_vc_action_rss_func, 6544 }, 6545 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 6546 .name = "simple_xor", 6547 .help = "simple XOR hash function", 6548 .call = parse_vc_action_rss_func, 6549 }, 6550 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 6551 .name = "symmetric_toeplitz", 6552 .help = "Symmetric Toeplitz hash function", 6553 .call = parse_vc_action_rss_func, 6554 }, 6555 [ACTION_RSS_LEVEL] = { 6556 .name = "level", 6557 .help = "encapsulation level for \"types\"", 6558 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6559 .args = ARGS(ARGS_ENTRY_ARB 6560 (offsetof(struct action_rss_data, conf) + 6561 offsetof(struct rte_flow_action_rss, level), 6562 sizeof(((struct rte_flow_action_rss *)0)-> 6563 level))), 6564 }, 6565 [ACTION_RSS_TYPES] = { 6566 .name = "types", 6567 .help = "specific RSS hash types", 6568 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 6569 }, 6570 [ACTION_RSS_TYPE] = { 6571 .name = "{type}", 6572 .help = "RSS hash type", 6573 .call = parse_vc_action_rss_type, 6574 .comp = comp_vc_action_rss_type, 6575 }, 6576 [ACTION_RSS_KEY] = { 6577 .name = "key", 6578 .help = "RSS hash key", 6579 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 6580 .args = ARGS(ARGS_ENTRY_ARB 6581 (offsetof(struct action_rss_data, conf) + 6582 offsetof(struct rte_flow_action_rss, key), 6583 sizeof(((struct rte_flow_action_rss *)0)->key)), 6584 ARGS_ENTRY_ARB 6585 (offsetof(struct action_rss_data, conf) + 6586 offsetof(struct rte_flow_action_rss, key_len), 6587 sizeof(((struct rte_flow_action_rss *)0)-> 6588 key_len)), 6589 ARGS_ENTRY(struct action_rss_data, key)), 6590 }, 6591 [ACTION_RSS_KEY_LEN] = { 6592 .name = "key_len", 6593 .help = "RSS hash key length in bytes", 6594 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 6595 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6596 (offsetof(struct action_rss_data, conf) + 6597 offsetof(struct rte_flow_action_rss, key_len), 6598 sizeof(((struct rte_flow_action_rss *)0)-> 6599 key_len), 6600 0, 6601 RSS_HASH_KEY_LENGTH)), 6602 }, 6603 [ACTION_RSS_QUEUES] = { 6604 .name = "queues", 6605 .help = "queue indices to use", 6606 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 6607 .call = parse_vc_conf, 6608 }, 6609 [ACTION_RSS_QUEUE] = { 6610 .name = "{queue}", 6611 .help = "queue index", 6612 .call = parse_vc_action_rss_queue, 6613 .comp = comp_vc_action_rss_queue, 6614 }, 6615 [ACTION_PF] = { 6616 .name = "pf", 6617 .help = "direct traffic to physical function", 6618 .priv = PRIV_ACTION(PF, 0), 6619 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6620 .call = parse_vc, 6621 }, 6622 [ACTION_VF] = { 6623 .name = "vf", 6624 .help = "direct traffic to a virtual function ID", 6625 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 6626 .next = NEXT(action_vf), 6627 .call = parse_vc, 6628 }, 6629 [ACTION_VF_ORIGINAL] = { 6630 .name = "original", 6631 .help = "use original VF ID if possible", 6632 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 6633 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 6634 original, 1)), 6635 .call = parse_vc_conf, 6636 }, 6637 [ACTION_VF_ID] = { 6638 .name = "id", 6639 .help = "VF ID", 6640 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 6641 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 6642 .call = parse_vc_conf, 6643 }, 6644 [ACTION_PORT_ID] = { 6645 .name = "port_id", 6646 .help = "direct matching traffic to a given DPDK port ID", 6647 .priv = PRIV_ACTION(PORT_ID, 6648 sizeof(struct rte_flow_action_port_id)), 6649 .next = NEXT(action_port_id), 6650 .call = parse_vc, 6651 }, 6652 [ACTION_PORT_ID_ORIGINAL] = { 6653 .name = "original", 6654 .help = "use original DPDK port ID if possible", 6655 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 6656 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 6657 original, 1)), 6658 .call = parse_vc_conf, 6659 }, 6660 [ACTION_PORT_ID_ID] = { 6661 .name = "id", 6662 .help = "DPDK port ID", 6663 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 6664 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 6665 .call = parse_vc_conf, 6666 }, 6667 [ACTION_METER] = { 6668 .name = "meter", 6669 .help = "meter the directed packets at given id", 6670 .priv = PRIV_ACTION(METER, 6671 sizeof(struct rte_flow_action_meter)), 6672 .next = NEXT(action_meter), 6673 .call = parse_vc, 6674 }, 6675 [ACTION_METER_COLOR] = { 6676 .name = "color", 6677 .help = "meter color for the packets", 6678 .priv = PRIV_ACTION(METER_COLOR, 6679 sizeof(struct rte_flow_action_meter_color)), 6680 .next = NEXT(action_meter_color), 6681 .call = parse_vc, 6682 }, 6683 [ACTION_METER_COLOR_TYPE] = { 6684 .name = "type", 6685 .help = "specific meter color", 6686 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6687 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 6688 ACTION_METER_COLOR_YELLOW, 6689 ACTION_METER_COLOR_RED)), 6690 }, 6691 [ACTION_METER_COLOR_GREEN] = { 6692 .name = "green", 6693 .help = "meter color green", 6694 .call = parse_vc_action_meter_color_type, 6695 }, 6696 [ACTION_METER_COLOR_YELLOW] = { 6697 .name = "yellow", 6698 .help = "meter color yellow", 6699 .call = parse_vc_action_meter_color_type, 6700 }, 6701 [ACTION_METER_COLOR_RED] = { 6702 .name = "red", 6703 .help = "meter color red", 6704 .call = parse_vc_action_meter_color_type, 6705 }, 6706 [ACTION_METER_ID] = { 6707 .name = "mtr_id", 6708 .help = "meter id to use", 6709 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 6710 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 6711 .call = parse_vc_conf, 6712 }, 6713 [ACTION_METER_MARK] = { 6714 .name = "meter_mark", 6715 .help = "meter the directed packets using profile and policy", 6716 .priv = PRIV_ACTION(METER_MARK, 6717 sizeof(struct rte_flow_action_meter_mark)), 6718 .next = NEXT(action_meter_mark), 6719 .call = parse_vc, 6720 }, 6721 [ACTION_METER_PROFILE] = { 6722 .name = "mtr_profile", 6723 .help = "meter profile id to use", 6724 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 6725 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6726 }, 6727 [ACTION_METER_PROFILE_ID2PTR] = { 6728 .name = "{mtr_profile_id}", 6729 .type = "PROFILE_ID", 6730 .help = "meter profile id", 6731 .next = NEXT(action_meter_mark), 6732 .call = parse_meter_profile_id2ptr, 6733 .comp = comp_none, 6734 }, 6735 [ACTION_METER_POLICY] = { 6736 .name = "mtr_policy", 6737 .help = "meter policy id to use", 6738 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 6739 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6740 }, 6741 [ACTION_METER_POLICY_ID2PTR] = { 6742 .name = "{mtr_policy_id}", 6743 .type = "POLICY_ID", 6744 .help = "meter policy id", 6745 .next = NEXT(action_meter_mark), 6746 .call = parse_meter_policy_id2ptr, 6747 .comp = comp_none, 6748 }, 6749 [ACTION_METER_COLOR_MODE] = { 6750 .name = "mtr_color_mode", 6751 .help = "meter color awareness mode", 6752 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6753 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 6754 .call = parse_vc_conf, 6755 }, 6756 [ACTION_METER_STATE] = { 6757 .name = "mtr_state", 6758 .help = "meter state", 6759 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 6760 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 6761 .call = parse_vc_conf, 6762 }, 6763 [ACTION_OF_DEC_NW_TTL] = { 6764 .name = "of_dec_nw_ttl", 6765 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 6766 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 6767 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6768 .call = parse_vc, 6769 }, 6770 [ACTION_OF_POP_VLAN] = { 6771 .name = "of_pop_vlan", 6772 .help = "OpenFlow's OFPAT_POP_VLAN", 6773 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 6774 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6775 .call = parse_vc, 6776 }, 6777 [ACTION_OF_PUSH_VLAN] = { 6778 .name = "of_push_vlan", 6779 .help = "OpenFlow's OFPAT_PUSH_VLAN", 6780 .priv = PRIV_ACTION 6781 (OF_PUSH_VLAN, 6782 sizeof(struct rte_flow_action_of_push_vlan)), 6783 .next = NEXT(action_of_push_vlan), 6784 .call = parse_vc, 6785 }, 6786 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 6787 .name = "ethertype", 6788 .help = "EtherType", 6789 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 6790 .args = ARGS(ARGS_ENTRY_HTON 6791 (struct rte_flow_action_of_push_vlan, 6792 ethertype)), 6793 .call = parse_vc_conf, 6794 }, 6795 [ACTION_OF_SET_VLAN_VID] = { 6796 .name = "of_set_vlan_vid", 6797 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 6798 .priv = PRIV_ACTION 6799 (OF_SET_VLAN_VID, 6800 sizeof(struct rte_flow_action_of_set_vlan_vid)), 6801 .next = NEXT(action_of_set_vlan_vid), 6802 .call = parse_vc, 6803 }, 6804 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 6805 .name = "vlan_vid", 6806 .help = "VLAN id", 6807 .next = NEXT(action_of_set_vlan_vid, 6808 NEXT_ENTRY(COMMON_UNSIGNED)), 6809 .args = ARGS(ARGS_ENTRY_HTON 6810 (struct rte_flow_action_of_set_vlan_vid, 6811 vlan_vid)), 6812 .call = parse_vc_conf, 6813 }, 6814 [ACTION_OF_SET_VLAN_PCP] = { 6815 .name = "of_set_vlan_pcp", 6816 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 6817 .priv = PRIV_ACTION 6818 (OF_SET_VLAN_PCP, 6819 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 6820 .next = NEXT(action_of_set_vlan_pcp), 6821 .call = parse_vc, 6822 }, 6823 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 6824 .name = "vlan_pcp", 6825 .help = "VLAN priority", 6826 .next = NEXT(action_of_set_vlan_pcp, 6827 NEXT_ENTRY(COMMON_UNSIGNED)), 6828 .args = ARGS(ARGS_ENTRY_HTON 6829 (struct rte_flow_action_of_set_vlan_pcp, 6830 vlan_pcp)), 6831 .call = parse_vc_conf, 6832 }, 6833 [ACTION_OF_POP_MPLS] = { 6834 .name = "of_pop_mpls", 6835 .help = "OpenFlow's OFPAT_POP_MPLS", 6836 .priv = PRIV_ACTION(OF_POP_MPLS, 6837 sizeof(struct rte_flow_action_of_pop_mpls)), 6838 .next = NEXT(action_of_pop_mpls), 6839 .call = parse_vc, 6840 }, 6841 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 6842 .name = "ethertype", 6843 .help = "EtherType", 6844 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6845 .args = ARGS(ARGS_ENTRY_HTON 6846 (struct rte_flow_action_of_pop_mpls, 6847 ethertype)), 6848 .call = parse_vc_conf, 6849 }, 6850 [ACTION_OF_PUSH_MPLS] = { 6851 .name = "of_push_mpls", 6852 .help = "OpenFlow's OFPAT_PUSH_MPLS", 6853 .priv = PRIV_ACTION 6854 (OF_PUSH_MPLS, 6855 sizeof(struct rte_flow_action_of_push_mpls)), 6856 .next = NEXT(action_of_push_mpls), 6857 .call = parse_vc, 6858 }, 6859 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 6860 .name = "ethertype", 6861 .help = "EtherType", 6862 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 6863 .args = ARGS(ARGS_ENTRY_HTON 6864 (struct rte_flow_action_of_push_mpls, 6865 ethertype)), 6866 .call = parse_vc_conf, 6867 }, 6868 [ACTION_VXLAN_ENCAP] = { 6869 .name = "vxlan_encap", 6870 .help = "VXLAN encapsulation, uses configuration set by \"set" 6871 " vxlan\"", 6872 .priv = PRIV_ACTION(VXLAN_ENCAP, 6873 sizeof(struct action_vxlan_encap_data)), 6874 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6875 .call = parse_vc_action_vxlan_encap, 6876 }, 6877 [ACTION_VXLAN_DECAP] = { 6878 .name = "vxlan_decap", 6879 .help = "Performs a decapsulation action by stripping all" 6880 " headers of the VXLAN tunnel network overlay from the" 6881 " matched flow.", 6882 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 6883 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6884 .call = parse_vc, 6885 }, 6886 [ACTION_NVGRE_ENCAP] = { 6887 .name = "nvgre_encap", 6888 .help = "NVGRE encapsulation, uses configuration set by \"set" 6889 " nvgre\"", 6890 .priv = PRIV_ACTION(NVGRE_ENCAP, 6891 sizeof(struct action_nvgre_encap_data)), 6892 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6893 .call = parse_vc_action_nvgre_encap, 6894 }, 6895 [ACTION_NVGRE_DECAP] = { 6896 .name = "nvgre_decap", 6897 .help = "Performs a decapsulation action by stripping all" 6898 " headers of the NVGRE tunnel network overlay from the" 6899 " matched flow.", 6900 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 6901 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6902 .call = parse_vc, 6903 }, 6904 [ACTION_L2_ENCAP] = { 6905 .name = "l2_encap", 6906 .help = "l2 encap, uses configuration set by" 6907 " \"set l2_encap\"", 6908 .priv = PRIV_ACTION(RAW_ENCAP, 6909 sizeof(struct action_raw_encap_data)), 6910 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6911 .call = parse_vc_action_l2_encap, 6912 }, 6913 [ACTION_L2_DECAP] = { 6914 .name = "l2_decap", 6915 .help = "l2 decap, uses configuration set by" 6916 " \"set l2_decap\"", 6917 .priv = PRIV_ACTION(RAW_DECAP, 6918 sizeof(struct action_raw_decap_data)), 6919 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6920 .call = parse_vc_action_l2_decap, 6921 }, 6922 [ACTION_MPLSOGRE_ENCAP] = { 6923 .name = "mplsogre_encap", 6924 .help = "mplsogre encapsulation, uses configuration set by" 6925 " \"set mplsogre_encap\"", 6926 .priv = PRIV_ACTION(RAW_ENCAP, 6927 sizeof(struct action_raw_encap_data)), 6928 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6929 .call = parse_vc_action_mplsogre_encap, 6930 }, 6931 [ACTION_MPLSOGRE_DECAP] = { 6932 .name = "mplsogre_decap", 6933 .help = "mplsogre decapsulation, uses configuration set by" 6934 " \"set mplsogre_decap\"", 6935 .priv = PRIV_ACTION(RAW_DECAP, 6936 sizeof(struct action_raw_decap_data)), 6937 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6938 .call = parse_vc_action_mplsogre_decap, 6939 }, 6940 [ACTION_MPLSOUDP_ENCAP] = { 6941 .name = "mplsoudp_encap", 6942 .help = "mplsoudp encapsulation, uses configuration set by" 6943 " \"set mplsoudp_encap\"", 6944 .priv = PRIV_ACTION(RAW_ENCAP, 6945 sizeof(struct action_raw_encap_data)), 6946 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6947 .call = parse_vc_action_mplsoudp_encap, 6948 }, 6949 [ACTION_MPLSOUDP_DECAP] = { 6950 .name = "mplsoudp_decap", 6951 .help = "mplsoudp decapsulation, uses configuration set by" 6952 " \"set mplsoudp_decap\"", 6953 .priv = PRIV_ACTION(RAW_DECAP, 6954 sizeof(struct action_raw_decap_data)), 6955 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6956 .call = parse_vc_action_mplsoudp_decap, 6957 }, 6958 [ACTION_SET_IPV4_SRC] = { 6959 .name = "set_ipv4_src", 6960 .help = "Set a new IPv4 source address in the outermost" 6961 " IPv4 header", 6962 .priv = PRIV_ACTION(SET_IPV4_SRC, 6963 sizeof(struct rte_flow_action_set_ipv4)), 6964 .next = NEXT(action_set_ipv4_src), 6965 .call = parse_vc, 6966 }, 6967 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 6968 .name = "ipv4_addr", 6969 .help = "new IPv4 source address to set", 6970 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 6971 .args = ARGS(ARGS_ENTRY_HTON 6972 (struct rte_flow_action_set_ipv4, ipv4_addr)), 6973 .call = parse_vc_conf, 6974 }, 6975 [ACTION_SET_IPV4_DST] = { 6976 .name = "set_ipv4_dst", 6977 .help = "Set a new IPv4 destination address in the outermost" 6978 " IPv4 header", 6979 .priv = PRIV_ACTION(SET_IPV4_DST, 6980 sizeof(struct rte_flow_action_set_ipv4)), 6981 .next = NEXT(action_set_ipv4_dst), 6982 .call = parse_vc, 6983 }, 6984 [ACTION_SET_IPV4_DST_IPV4_DST] = { 6985 .name = "ipv4_addr", 6986 .help = "new IPv4 destination address to set", 6987 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 6988 .args = ARGS(ARGS_ENTRY_HTON 6989 (struct rte_flow_action_set_ipv4, ipv4_addr)), 6990 .call = parse_vc_conf, 6991 }, 6992 [ACTION_SET_IPV6_SRC] = { 6993 .name = "set_ipv6_src", 6994 .help = "Set a new IPv6 source address in the outermost" 6995 " IPv6 header", 6996 .priv = PRIV_ACTION(SET_IPV6_SRC, 6997 sizeof(struct rte_flow_action_set_ipv6)), 6998 .next = NEXT(action_set_ipv6_src), 6999 .call = parse_vc, 7000 }, 7001 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 7002 .name = "ipv6_addr", 7003 .help = "new IPv6 source address to set", 7004 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7005 .args = ARGS(ARGS_ENTRY_HTON 7006 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7007 .call = parse_vc_conf, 7008 }, 7009 [ACTION_SET_IPV6_DST] = { 7010 .name = "set_ipv6_dst", 7011 .help = "Set a new IPv6 destination address in the outermost" 7012 " IPv6 header", 7013 .priv = PRIV_ACTION(SET_IPV6_DST, 7014 sizeof(struct rte_flow_action_set_ipv6)), 7015 .next = NEXT(action_set_ipv6_dst), 7016 .call = parse_vc, 7017 }, 7018 [ACTION_SET_IPV6_DST_IPV6_DST] = { 7019 .name = "ipv6_addr", 7020 .help = "new IPv6 destination address to set", 7021 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 7022 .args = ARGS(ARGS_ENTRY_HTON 7023 (struct rte_flow_action_set_ipv6, ipv6_addr)), 7024 .call = parse_vc_conf, 7025 }, 7026 [ACTION_SET_TP_SRC] = { 7027 .name = "set_tp_src", 7028 .help = "set a new source port number in the outermost" 7029 " TCP/UDP header", 7030 .priv = PRIV_ACTION(SET_TP_SRC, 7031 sizeof(struct rte_flow_action_set_tp)), 7032 .next = NEXT(action_set_tp_src), 7033 .call = parse_vc, 7034 }, 7035 [ACTION_SET_TP_SRC_TP_SRC] = { 7036 .name = "port", 7037 .help = "new source port number to set", 7038 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 7039 .args = ARGS(ARGS_ENTRY_HTON 7040 (struct rte_flow_action_set_tp, port)), 7041 .call = parse_vc_conf, 7042 }, 7043 [ACTION_SET_TP_DST] = { 7044 .name = "set_tp_dst", 7045 .help = "set a new destination port number in the outermost" 7046 " TCP/UDP header", 7047 .priv = PRIV_ACTION(SET_TP_DST, 7048 sizeof(struct rte_flow_action_set_tp)), 7049 .next = NEXT(action_set_tp_dst), 7050 .call = parse_vc, 7051 }, 7052 [ACTION_SET_TP_DST_TP_DST] = { 7053 .name = "port", 7054 .help = "new destination port number to set", 7055 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 7056 .args = ARGS(ARGS_ENTRY_HTON 7057 (struct rte_flow_action_set_tp, port)), 7058 .call = parse_vc_conf, 7059 }, 7060 [ACTION_MAC_SWAP] = { 7061 .name = "mac_swap", 7062 .help = "Swap the source and destination MAC addresses" 7063 " in the outermost Ethernet header", 7064 .priv = PRIV_ACTION(MAC_SWAP, 0), 7065 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7066 .call = parse_vc, 7067 }, 7068 [ACTION_DEC_TTL] = { 7069 .name = "dec_ttl", 7070 .help = "decrease network TTL if available", 7071 .priv = PRIV_ACTION(DEC_TTL, 0), 7072 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7073 .call = parse_vc, 7074 }, 7075 [ACTION_SET_TTL] = { 7076 .name = "set_ttl", 7077 .help = "set ttl value", 7078 .priv = PRIV_ACTION(SET_TTL, 7079 sizeof(struct rte_flow_action_set_ttl)), 7080 .next = NEXT(action_set_ttl), 7081 .call = parse_vc, 7082 }, 7083 [ACTION_SET_TTL_TTL] = { 7084 .name = "ttl_value", 7085 .help = "new ttl value to set", 7086 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 7087 .args = ARGS(ARGS_ENTRY_HTON 7088 (struct rte_flow_action_set_ttl, ttl_value)), 7089 .call = parse_vc_conf, 7090 }, 7091 [ACTION_SET_MAC_SRC] = { 7092 .name = "set_mac_src", 7093 .help = "set source mac address", 7094 .priv = PRIV_ACTION(SET_MAC_SRC, 7095 sizeof(struct rte_flow_action_set_mac)), 7096 .next = NEXT(action_set_mac_src), 7097 .call = parse_vc, 7098 }, 7099 [ACTION_SET_MAC_SRC_MAC_SRC] = { 7100 .name = "mac_addr", 7101 .help = "new source mac address", 7102 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 7103 .args = ARGS(ARGS_ENTRY_HTON 7104 (struct rte_flow_action_set_mac, mac_addr)), 7105 .call = parse_vc_conf, 7106 }, 7107 [ACTION_SET_MAC_DST] = { 7108 .name = "set_mac_dst", 7109 .help = "set destination mac address", 7110 .priv = PRIV_ACTION(SET_MAC_DST, 7111 sizeof(struct rte_flow_action_set_mac)), 7112 .next = NEXT(action_set_mac_dst), 7113 .call = parse_vc, 7114 }, 7115 [ACTION_SET_MAC_DST_MAC_DST] = { 7116 .name = "mac_addr", 7117 .help = "new destination mac address to set", 7118 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 7119 .args = ARGS(ARGS_ENTRY_HTON 7120 (struct rte_flow_action_set_mac, mac_addr)), 7121 .call = parse_vc_conf, 7122 }, 7123 [ACTION_INC_TCP_SEQ] = { 7124 .name = "inc_tcp_seq", 7125 .help = "increase TCP sequence number", 7126 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 7127 .next = NEXT(action_inc_tcp_seq), 7128 .call = parse_vc, 7129 }, 7130 [ACTION_INC_TCP_SEQ_VALUE] = { 7131 .name = "value", 7132 .help = "the value to increase TCP sequence number by", 7133 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7134 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7135 .call = parse_vc_conf, 7136 }, 7137 [ACTION_DEC_TCP_SEQ] = { 7138 .name = "dec_tcp_seq", 7139 .help = "decrease TCP sequence number", 7140 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 7141 .next = NEXT(action_dec_tcp_seq), 7142 .call = parse_vc, 7143 }, 7144 [ACTION_DEC_TCP_SEQ_VALUE] = { 7145 .name = "value", 7146 .help = "the value to decrease TCP sequence number by", 7147 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 7148 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7149 .call = parse_vc_conf, 7150 }, 7151 [ACTION_INC_TCP_ACK] = { 7152 .name = "inc_tcp_ack", 7153 .help = "increase TCP acknowledgment number", 7154 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 7155 .next = NEXT(action_inc_tcp_ack), 7156 .call = parse_vc, 7157 }, 7158 [ACTION_INC_TCP_ACK_VALUE] = { 7159 .name = "value", 7160 .help = "the value to increase TCP acknowledgment number by", 7161 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7162 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7163 .call = parse_vc_conf, 7164 }, 7165 [ACTION_DEC_TCP_ACK] = { 7166 .name = "dec_tcp_ack", 7167 .help = "decrease TCP acknowledgment number", 7168 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 7169 .next = NEXT(action_dec_tcp_ack), 7170 .call = parse_vc, 7171 }, 7172 [ACTION_DEC_TCP_ACK_VALUE] = { 7173 .name = "value", 7174 .help = "the value to decrease TCP acknowledgment number by", 7175 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 7176 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 7177 .call = parse_vc_conf, 7178 }, 7179 [ACTION_RAW_ENCAP] = { 7180 .name = "raw_encap", 7181 .help = "encapsulation data, defined by set raw_encap", 7182 .priv = PRIV_ACTION(RAW_ENCAP, 7183 sizeof(struct action_raw_encap_data)), 7184 .next = NEXT(action_raw_encap), 7185 .call = parse_vc_action_raw_encap, 7186 }, 7187 [ACTION_RAW_ENCAP_SIZE] = { 7188 .name = "size", 7189 .help = "raw encap size", 7190 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7191 NEXT_ENTRY(COMMON_UNSIGNED)), 7192 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_raw_encap, size)), 7193 .call = parse_vc_conf, 7194 }, 7195 [ACTION_RAW_ENCAP_INDEX] = { 7196 .name = "index", 7197 .help = "the index of raw_encap_confs", 7198 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 7199 }, 7200 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 7201 .name = "{index}", 7202 .type = "UNSIGNED", 7203 .help = "unsigned integer value", 7204 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7205 .call = parse_vc_action_raw_encap_index, 7206 .comp = comp_set_raw_index, 7207 }, 7208 [ACTION_RAW_DECAP] = { 7209 .name = "raw_decap", 7210 .help = "decapsulation data, defined by set raw_encap", 7211 .priv = PRIV_ACTION(RAW_DECAP, 7212 sizeof(struct action_raw_decap_data)), 7213 .next = NEXT(action_raw_decap), 7214 .call = parse_vc_action_raw_decap, 7215 }, 7216 [ACTION_RAW_DECAP_INDEX] = { 7217 .name = "index", 7218 .help = "the index of raw_encap_confs", 7219 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 7220 }, 7221 [ACTION_RAW_DECAP_INDEX_VALUE] = { 7222 .name = "{index}", 7223 .type = "UNSIGNED", 7224 .help = "unsigned integer value", 7225 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7226 .call = parse_vc_action_raw_decap_index, 7227 .comp = comp_set_raw_index, 7228 }, 7229 [ACTION_MODIFY_FIELD] = { 7230 .name = "modify_field", 7231 .help = "modify destination field with data from source field", 7232 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 7233 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 7234 .call = parse_vc, 7235 }, 7236 [ACTION_MODIFY_FIELD_OP] = { 7237 .name = "op", 7238 .help = "operation type", 7239 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 7240 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 7241 .call = parse_vc_conf, 7242 }, 7243 [ACTION_MODIFY_FIELD_OP_VALUE] = { 7244 .name = "{operation}", 7245 .help = "operation type value", 7246 .call = parse_vc_modify_field_op, 7247 .comp = comp_set_modify_field_op, 7248 }, 7249 [ACTION_MODIFY_FIELD_DST_TYPE] = { 7250 .name = "dst_type", 7251 .help = "destination field type", 7252 .next = NEXT(action_modify_field_dst, 7253 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 7254 .call = parse_vc_conf, 7255 }, 7256 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 7257 .name = "{dst_type}", 7258 .help = "destination field type value", 7259 .call = parse_vc_modify_field_id, 7260 .comp = comp_set_modify_field_id, 7261 }, 7262 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 7263 .name = "dst_level", 7264 .help = "destination field level", 7265 .next = NEXT(action_modify_field_dst, 7266 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_LEVEL_VALUE)), 7267 .call = parse_vc_conf, 7268 }, 7269 [ACTION_MODIFY_FIELD_DST_LEVEL_VALUE] = { 7270 .name = "{dst_level}", 7271 .help = "destination field level value", 7272 .call = parse_vc_modify_field_level, 7273 .comp = comp_none, 7274 }, 7275 [ACTION_MODIFY_FIELD_DST_TAG_INDEX] = { 7276 .name = "dst_tag_index", 7277 .help = "destination field tag array", 7278 .next = NEXT(action_modify_field_dst, 7279 NEXT_ENTRY(COMMON_UNSIGNED)), 7280 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7281 dst.tag_index)), 7282 .call = parse_vc_conf, 7283 }, 7284 [ACTION_MODIFY_FIELD_DST_TYPE_ID] = { 7285 .name = "dst_type_id", 7286 .help = "destination field type ID", 7287 .next = NEXT(action_modify_field_dst, 7288 NEXT_ENTRY(COMMON_UNSIGNED)), 7289 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7290 dst.type)), 7291 .call = parse_vc_conf, 7292 }, 7293 [ACTION_MODIFY_FIELD_DST_CLASS_ID] = { 7294 .name = "dst_class", 7295 .help = "destination field class ID", 7296 .next = NEXT(action_modify_field_dst, 7297 NEXT_ENTRY(COMMON_UNSIGNED)), 7298 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7299 dst.class_id)), 7300 .call = parse_vc_conf, 7301 }, 7302 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 7303 .name = "dst_offset", 7304 .help = "destination field bit offset", 7305 .next = NEXT(action_modify_field_dst, 7306 NEXT_ENTRY(COMMON_UNSIGNED)), 7307 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7308 dst.offset)), 7309 .call = parse_vc_conf, 7310 }, 7311 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 7312 .name = "src_type", 7313 .help = "source field type", 7314 .next = NEXT(action_modify_field_src, 7315 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 7316 .call = parse_vc_conf, 7317 }, 7318 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 7319 .name = "{src_type}", 7320 .help = "source field type value", 7321 .call = parse_vc_modify_field_id, 7322 .comp = comp_set_modify_field_id, 7323 }, 7324 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 7325 .name = "src_level", 7326 .help = "source field level", 7327 .next = NEXT(action_modify_field_src, 7328 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE)), 7329 .call = parse_vc_conf, 7330 }, 7331 [ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE] = { 7332 .name = "{src_level}", 7333 .help = "source field level value", 7334 .call = parse_vc_modify_field_level, 7335 .comp = comp_none, 7336 }, 7337 [ACTION_MODIFY_FIELD_SRC_TAG_INDEX] = { 7338 .name = "src_tag_index", 7339 .help = "source field tag array", 7340 .next = NEXT(action_modify_field_src, 7341 NEXT_ENTRY(COMMON_UNSIGNED)), 7342 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7343 src.tag_index)), 7344 .call = parse_vc_conf, 7345 }, 7346 [ACTION_MODIFY_FIELD_SRC_TYPE_ID] = { 7347 .name = "src_type_id", 7348 .help = "source field type ID", 7349 .next = NEXT(action_modify_field_src, 7350 NEXT_ENTRY(COMMON_UNSIGNED)), 7351 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7352 src.type)), 7353 .call = parse_vc_conf, 7354 }, 7355 [ACTION_MODIFY_FIELD_SRC_CLASS_ID] = { 7356 .name = "src_class", 7357 .help = "source field class ID", 7358 .next = NEXT(action_modify_field_src, 7359 NEXT_ENTRY(COMMON_UNSIGNED)), 7360 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_action_modify_field, 7361 src.class_id)), 7362 .call = parse_vc_conf, 7363 }, 7364 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 7365 .name = "src_offset", 7366 .help = "source field bit offset", 7367 .next = NEXT(action_modify_field_src, 7368 NEXT_ENTRY(COMMON_UNSIGNED)), 7369 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7370 src.offset)), 7371 .call = parse_vc_conf, 7372 }, 7373 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 7374 .name = "src_value", 7375 .help = "source immediate value", 7376 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7377 NEXT_ENTRY(COMMON_HEX)), 7378 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 7379 ARGS_ENTRY_ARB(0, 0), 7380 ARGS_ENTRY(struct rte_flow_action_modify_field, 7381 src.value)), 7382 .call = parse_vc_conf, 7383 }, 7384 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 7385 .name = "src_ptr", 7386 .help = "pointer to source immediate value", 7387 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 7388 NEXT_ENTRY(COMMON_HEX)), 7389 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7390 src.pvalue), 7391 ARGS_ENTRY_ARB(0, 0), 7392 ARGS_ENTRY_ARB 7393 (sizeof(struct rte_flow_action_modify_field), 7394 FLOW_FIELD_PATTERN_SIZE)), 7395 .call = parse_vc_conf, 7396 }, 7397 [ACTION_MODIFY_FIELD_WIDTH] = { 7398 .name = "width", 7399 .help = "number of bits to copy", 7400 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 7401 NEXT_ENTRY(COMMON_UNSIGNED)), 7402 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 7403 width)), 7404 .call = parse_vc_conf, 7405 }, 7406 [ACTION_SEND_TO_KERNEL] = { 7407 .name = "send_to_kernel", 7408 .help = "send packets to kernel", 7409 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 7410 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7411 .call = parse_vc, 7412 }, 7413 [ACTION_IPV6_EXT_REMOVE] = { 7414 .name = "ipv6_ext_remove", 7415 .help = "IPv6 extension type, defined by set ipv6_ext_remove", 7416 .priv = PRIV_ACTION(IPV6_EXT_REMOVE, 7417 sizeof(struct action_ipv6_ext_remove_data)), 7418 .next = NEXT(action_ipv6_ext_remove), 7419 .call = parse_vc_action_ipv6_ext_remove, 7420 }, 7421 [ACTION_IPV6_EXT_REMOVE_INDEX] = { 7422 .name = "index", 7423 .help = "the index of ipv6_ext_remove", 7424 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_REMOVE_INDEX_VALUE)), 7425 }, 7426 [ACTION_IPV6_EXT_REMOVE_INDEX_VALUE] = { 7427 .name = "{index}", 7428 .type = "UNSIGNED", 7429 .help = "unsigned integer value", 7430 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7431 .call = parse_vc_action_ipv6_ext_remove_index, 7432 .comp = comp_set_ipv6_ext_index, 7433 }, 7434 [ACTION_IPV6_EXT_PUSH] = { 7435 .name = "ipv6_ext_push", 7436 .help = "IPv6 extension data, defined by set ipv6_ext_push", 7437 .priv = PRIV_ACTION(IPV6_EXT_PUSH, 7438 sizeof(struct action_ipv6_ext_push_data)), 7439 .next = NEXT(action_ipv6_ext_push), 7440 .call = parse_vc_action_ipv6_ext_push, 7441 }, 7442 [ACTION_IPV6_EXT_PUSH_INDEX] = { 7443 .name = "index", 7444 .help = "the index of ipv6_ext_push", 7445 .next = NEXT(NEXT_ENTRY(ACTION_IPV6_EXT_PUSH_INDEX_VALUE)), 7446 }, 7447 [ACTION_IPV6_EXT_PUSH_INDEX_VALUE] = { 7448 .name = "{index}", 7449 .type = "UNSIGNED", 7450 .help = "unsigned integer value", 7451 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7452 .call = parse_vc_action_ipv6_ext_push_index, 7453 .comp = comp_set_ipv6_ext_index, 7454 }, 7455 [ACTION_NAT64] = { 7456 .name = "nat64", 7457 .help = "NAT64 IP headers translation", 7458 .priv = PRIV_ACTION(NAT64, sizeof(struct rte_flow_action_nat64)), 7459 .next = NEXT(action_nat64), 7460 .call = parse_vc, 7461 }, 7462 [ACTION_NAT64_MODE] = { 7463 .name = "type", 7464 .help = "NAT64 translation type", 7465 .next = NEXT(action_nat64, NEXT_ENTRY(COMMON_UNSIGNED)), 7466 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_nat64, type)), 7467 .call = parse_vc_conf, 7468 }, 7469 /* Top level command. */ 7470 [SET] = { 7471 .name = "set", 7472 .help = "set raw encap/decap/sample data", 7473 .type = "set raw_encap|raw_decap <index> <pattern>" 7474 " or set sample_actions <index> <action>", 7475 .next = NEXT(NEXT_ENTRY 7476 (SET_RAW_ENCAP, 7477 SET_RAW_DECAP, 7478 SET_SAMPLE_ACTIONS, 7479 SET_IPV6_EXT_REMOVE, 7480 SET_IPV6_EXT_PUSH)), 7481 .call = parse_set_init, 7482 }, 7483 /* Sub-level commands. */ 7484 [SET_RAW_ENCAP] = { 7485 .name = "raw_encap", 7486 .help = "set raw encap data", 7487 .next = NEXT(next_set_raw), 7488 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7489 (offsetof(struct buffer, port), 7490 sizeof(((struct buffer *)0)->port), 7491 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7492 .call = parse_set_raw_encap_decap, 7493 }, 7494 [SET_RAW_DECAP] = { 7495 .name = "raw_decap", 7496 .help = "set raw decap data", 7497 .next = NEXT(next_set_raw), 7498 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7499 (offsetof(struct buffer, port), 7500 sizeof(((struct buffer *)0)->port), 7501 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 7502 .call = parse_set_raw_encap_decap, 7503 }, 7504 [SET_RAW_INDEX] = { 7505 .name = "{index}", 7506 .type = "COMMON_UNSIGNED", 7507 .help = "index of raw_encap/raw_decap data", 7508 .next = NEXT(next_item), 7509 .call = parse_port, 7510 }, 7511 [SET_SAMPLE_INDEX] = { 7512 .name = "{index}", 7513 .type = "UNSIGNED", 7514 .help = "index of sample actions", 7515 .next = NEXT(next_action_sample), 7516 .call = parse_port, 7517 }, 7518 [SET_SAMPLE_ACTIONS] = { 7519 .name = "sample_actions", 7520 .help = "set sample actions list", 7521 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 7522 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7523 (offsetof(struct buffer, port), 7524 sizeof(((struct buffer *)0)->port), 7525 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 7526 .call = parse_set_sample_action, 7527 }, 7528 [SET_IPV6_EXT_PUSH] = { 7529 .name = "ipv6_ext_push", 7530 .help = "set IPv6 extension header", 7531 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7532 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7533 (offsetof(struct buffer, port), 7534 sizeof(((struct buffer *)0)->port), 7535 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7536 .call = parse_set_ipv6_ext_action, 7537 }, 7538 [SET_IPV6_EXT_REMOVE] = { 7539 .name = "ipv6_ext_remove", 7540 .help = "set IPv6 extension header", 7541 .next = NEXT(NEXT_ENTRY(SET_IPV6_EXT_INDEX)), 7542 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 7543 (offsetof(struct buffer, port), 7544 sizeof(((struct buffer *)0)->port), 7545 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1)), 7546 .call = parse_set_ipv6_ext_action, 7547 }, 7548 [SET_IPV6_EXT_INDEX] = { 7549 .name = "{index}", 7550 .type = "UNSIGNED", 7551 .help = "index of ipv6 extension push/remove actions", 7552 .next = NEXT(item_ipv6_push_ext), 7553 .call = parse_port, 7554 }, 7555 [ITEM_IPV6_PUSH_REMOVE_EXT] = { 7556 .name = "ipv6_ext", 7557 .help = "set IPv6 extension header", 7558 .priv = PRIV_ITEM(IPV6_EXT, 7559 sizeof(struct rte_flow_item_ipv6_ext)), 7560 .next = NEXT(item_ipv6_push_ext_type), 7561 .call = parse_vc, 7562 }, 7563 [ITEM_IPV6_PUSH_REMOVE_EXT_TYPE] = { 7564 .name = "type", 7565 .help = "set IPv6 extension type", 7566 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 7567 next_hdr)), 7568 .next = NEXT(item_ipv6_push_ext_header, NEXT_ENTRY(COMMON_UNSIGNED), 7569 item_param), 7570 }, 7571 [ACTION_SET_TAG] = { 7572 .name = "set_tag", 7573 .help = "set tag", 7574 .priv = PRIV_ACTION(SET_TAG, 7575 sizeof(struct rte_flow_action_set_tag)), 7576 .next = NEXT(action_set_tag), 7577 .call = parse_vc, 7578 }, 7579 [ACTION_SET_TAG_INDEX] = { 7580 .name = "index", 7581 .help = "index of tag array", 7582 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7583 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 7584 .call = parse_vc_conf, 7585 }, 7586 [ACTION_SET_TAG_DATA] = { 7587 .name = "data", 7588 .help = "tag value", 7589 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7590 .args = ARGS(ARGS_ENTRY 7591 (struct rte_flow_action_set_tag, data)), 7592 .call = parse_vc_conf, 7593 }, 7594 [ACTION_SET_TAG_MASK] = { 7595 .name = "mask", 7596 .help = "mask for tag value", 7597 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 7598 .args = ARGS(ARGS_ENTRY 7599 (struct rte_flow_action_set_tag, mask)), 7600 .call = parse_vc_conf, 7601 }, 7602 [ACTION_SET_META] = { 7603 .name = "set_meta", 7604 .help = "set metadata", 7605 .priv = PRIV_ACTION(SET_META, 7606 sizeof(struct rte_flow_action_set_meta)), 7607 .next = NEXT(action_set_meta), 7608 .call = parse_vc_action_set_meta, 7609 }, 7610 [ACTION_SET_META_DATA] = { 7611 .name = "data", 7612 .help = "metadata value", 7613 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7614 .args = ARGS(ARGS_ENTRY 7615 (struct rte_flow_action_set_meta, data)), 7616 .call = parse_vc_conf, 7617 }, 7618 [ACTION_SET_META_MASK] = { 7619 .name = "mask", 7620 .help = "mask for metadata value", 7621 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 7622 .args = ARGS(ARGS_ENTRY 7623 (struct rte_flow_action_set_meta, mask)), 7624 .call = parse_vc_conf, 7625 }, 7626 [ACTION_SET_IPV4_DSCP] = { 7627 .name = "set_ipv4_dscp", 7628 .help = "set DSCP value", 7629 .priv = PRIV_ACTION(SET_IPV4_DSCP, 7630 sizeof(struct rte_flow_action_set_dscp)), 7631 .next = NEXT(action_set_ipv4_dscp), 7632 .call = parse_vc, 7633 }, 7634 [ACTION_SET_IPV4_DSCP_VALUE] = { 7635 .name = "dscp_value", 7636 .help = "new IPv4 DSCP value to set", 7637 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7638 .args = ARGS(ARGS_ENTRY 7639 (struct rte_flow_action_set_dscp, dscp)), 7640 .call = parse_vc_conf, 7641 }, 7642 [ACTION_SET_IPV6_DSCP] = { 7643 .name = "set_ipv6_dscp", 7644 .help = "set DSCP value", 7645 .priv = PRIV_ACTION(SET_IPV6_DSCP, 7646 sizeof(struct rte_flow_action_set_dscp)), 7647 .next = NEXT(action_set_ipv6_dscp), 7648 .call = parse_vc, 7649 }, 7650 [ACTION_SET_IPV6_DSCP_VALUE] = { 7651 .name = "dscp_value", 7652 .help = "new IPv6 DSCP value to set", 7653 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 7654 .args = ARGS(ARGS_ENTRY 7655 (struct rte_flow_action_set_dscp, dscp)), 7656 .call = parse_vc_conf, 7657 }, 7658 [ACTION_AGE] = { 7659 .name = "age", 7660 .help = "set a specific metadata header", 7661 .next = NEXT(action_age), 7662 .priv = PRIV_ACTION(AGE, 7663 sizeof(struct rte_flow_action_age)), 7664 .call = parse_vc, 7665 }, 7666 [ACTION_AGE_TIMEOUT] = { 7667 .name = "timeout", 7668 .help = "flow age timeout value", 7669 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 7670 timeout, 24)), 7671 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 7672 .call = parse_vc_conf, 7673 }, 7674 [ACTION_AGE_UPDATE] = { 7675 .name = "age_update", 7676 .help = "update aging parameter", 7677 .next = NEXT(action_age_update), 7678 .priv = PRIV_ACTION(AGE, 7679 sizeof(struct rte_flow_update_age)), 7680 .call = parse_vc, 7681 }, 7682 [ACTION_AGE_UPDATE_TIMEOUT] = { 7683 .name = "timeout", 7684 .help = "age timeout update value", 7685 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7686 timeout, 24)), 7687 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7688 .call = parse_vc_conf_timeout, 7689 }, 7690 [ACTION_AGE_UPDATE_TOUCH] = { 7691 .name = "touch", 7692 .help = "this flow is touched", 7693 .next = NEXT(action_age_update, NEXT_ENTRY(COMMON_BOOLEAN)), 7694 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_update_age, 7695 touch, 1)), 7696 .call = parse_vc_conf, 7697 }, 7698 [ACTION_SAMPLE] = { 7699 .name = "sample", 7700 .help = "set a sample action", 7701 .next = NEXT(action_sample), 7702 .priv = PRIV_ACTION(SAMPLE, 7703 sizeof(struct action_sample_data)), 7704 .call = parse_vc_action_sample, 7705 }, 7706 [ACTION_SAMPLE_RATIO] = { 7707 .name = "ratio", 7708 .help = "flow sample ratio value", 7709 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 7710 .args = ARGS(ARGS_ENTRY_ARB 7711 (offsetof(struct action_sample_data, conf) + 7712 offsetof(struct rte_flow_action_sample, ratio), 7713 sizeof(((struct rte_flow_action_sample *)0)-> 7714 ratio))), 7715 }, 7716 [ACTION_SAMPLE_INDEX] = { 7717 .name = "index", 7718 .help = "the index of sample actions list", 7719 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 7720 }, 7721 [ACTION_SAMPLE_INDEX_VALUE] = { 7722 .name = "{index}", 7723 .type = "COMMON_UNSIGNED", 7724 .help = "unsigned integer value", 7725 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7726 .call = parse_vc_action_sample_index, 7727 .comp = comp_set_sample_index, 7728 }, 7729 [ACTION_CONNTRACK] = { 7730 .name = "conntrack", 7731 .help = "create a conntrack object", 7732 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7733 .priv = PRIV_ACTION(CONNTRACK, 7734 sizeof(struct rte_flow_action_conntrack)), 7735 .call = parse_vc, 7736 }, 7737 [ACTION_CONNTRACK_UPDATE] = { 7738 .name = "conntrack_update", 7739 .help = "update a conntrack object", 7740 .next = NEXT(action_update_conntrack), 7741 .priv = PRIV_ACTION(CONNTRACK, 7742 sizeof(struct rte_flow_modify_conntrack)), 7743 .call = parse_vc, 7744 }, 7745 [ACTION_CONNTRACK_UPDATE_DIR] = { 7746 .name = "dir", 7747 .help = "update a conntrack object direction", 7748 .next = NEXT(action_update_conntrack), 7749 .call = parse_vc_action_conntrack_update, 7750 }, 7751 [ACTION_CONNTRACK_UPDATE_CTX] = { 7752 .name = "ctx", 7753 .help = "update a conntrack object context", 7754 .next = NEXT(action_update_conntrack), 7755 .call = parse_vc_action_conntrack_update, 7756 }, 7757 [ACTION_PORT_REPRESENTOR] = { 7758 .name = "port_representor", 7759 .help = "at embedded switch level, send matching traffic to the given ethdev", 7760 .priv = PRIV_ACTION(PORT_REPRESENTOR, 7761 sizeof(struct rte_flow_action_ethdev)), 7762 .next = NEXT(action_port_representor), 7763 .call = parse_vc, 7764 }, 7765 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 7766 .name = "port_id", 7767 .help = "ethdev port ID", 7768 .next = NEXT(action_port_representor, 7769 NEXT_ENTRY(COMMON_UNSIGNED)), 7770 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7771 port_id)), 7772 .call = parse_vc_conf, 7773 }, 7774 [ACTION_REPRESENTED_PORT] = { 7775 .name = "represented_port", 7776 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 7777 .priv = PRIV_ACTION(REPRESENTED_PORT, 7778 sizeof(struct rte_flow_action_ethdev)), 7779 .next = NEXT(action_represented_port), 7780 .call = parse_vc, 7781 }, 7782 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 7783 .name = "ethdev_port_id", 7784 .help = "ethdev port ID", 7785 .next = NEXT(action_represented_port, 7786 NEXT_ENTRY(COMMON_UNSIGNED)), 7787 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 7788 port_id)), 7789 .call = parse_vc_conf, 7790 }, 7791 /* Indirect action destroy arguments. */ 7792 [INDIRECT_ACTION_DESTROY_ID] = { 7793 .name = "action_id", 7794 .help = "specify a indirect action id to destroy", 7795 .next = NEXT(next_ia_destroy_attr, 7796 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7797 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 7798 args.ia_destroy.action_id)), 7799 .call = parse_ia_destroy, 7800 }, 7801 /* Indirect action create arguments. */ 7802 [INDIRECT_ACTION_CREATE_ID] = { 7803 .name = "action_id", 7804 .help = "specify a indirect action id to create", 7805 .next = NEXT(next_ia_create_attr, 7806 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 7807 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 7808 }, 7809 [ACTION_INDIRECT] = { 7810 .name = "indirect", 7811 .help = "apply indirect action by id", 7812 .priv = PRIV_ACTION(INDIRECT, 0), 7813 .next = NEXT(next_ia), 7814 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7815 .call = parse_vc, 7816 }, 7817 [ACTION_INDIRECT_LIST] = { 7818 .name = "indirect_list", 7819 .help = "apply indirect list action by id", 7820 .priv = PRIV_ACTION(INDIRECT_LIST, 7821 sizeof(struct 7822 rte_flow_action_indirect_list)), 7823 .next = NEXT(next_ial), 7824 .call = parse_vc, 7825 }, 7826 [ACTION_INDIRECT_LIST_HANDLE] = { 7827 .name = "handle", 7828 .help = "indirect list handle", 7829 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_HANDLE)), 7830 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7831 }, 7832 [ACTION_INDIRECT_LIST_CONF] = { 7833 .name = "conf", 7834 .help = "indirect list configuration", 7835 .next = NEXT(next_ial, NEXT_ENTRY(INDIRECT_LIST_ACTION_ID2PTR_CONF)), 7836 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7837 }, 7838 [INDIRECT_LIST_ACTION_ID2PTR_HANDLE] = { 7839 .type = "UNSIGNED", 7840 .help = "unsigned integer value", 7841 .call = parse_indlst_id2ptr, 7842 .comp = comp_none, 7843 }, 7844 [INDIRECT_LIST_ACTION_ID2PTR_CONF] = { 7845 .type = "UNSIGNED", 7846 .help = "unsigned integer value", 7847 .call = parse_indlst_id2ptr, 7848 .comp = comp_none, 7849 }, 7850 [ACTION_SHARED_INDIRECT] = { 7851 .name = "shared_indirect", 7852 .help = "apply indirect action by id and port", 7853 .priv = PRIV_ACTION(INDIRECT, 0), 7854 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_PORT)), 7855 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t)), 7856 ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 7857 .call = parse_vc, 7858 }, 7859 [INDIRECT_ACTION_PORT] = { 7860 .name = "{indirect_action_port}", 7861 .type = "INDIRECT_ACTION_PORT", 7862 .help = "indirect action port", 7863 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 7864 .call = parse_ia_port, 7865 .comp = comp_none, 7866 }, 7867 [INDIRECT_ACTION_ID2PTR] = { 7868 .name = "{action_id}", 7869 .type = "INDIRECT_ACTION_ID", 7870 .help = "indirect action id", 7871 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 7872 .call = parse_ia_id2ptr, 7873 .comp = comp_none, 7874 }, 7875 [INDIRECT_ACTION_INGRESS] = { 7876 .name = "ingress", 7877 .help = "affect rule to ingress", 7878 .next = NEXT(next_ia_create_attr), 7879 .call = parse_ia, 7880 }, 7881 [INDIRECT_ACTION_EGRESS] = { 7882 .name = "egress", 7883 .help = "affect rule to egress", 7884 .next = NEXT(next_ia_create_attr), 7885 .call = parse_ia, 7886 }, 7887 [INDIRECT_ACTION_TRANSFER] = { 7888 .name = "transfer", 7889 .help = "affect rule to transfer", 7890 .next = NEXT(next_ia_create_attr), 7891 .call = parse_ia, 7892 }, 7893 [INDIRECT_ACTION_SPEC] = { 7894 .name = "action", 7895 .help = "specify action to create indirect handle", 7896 .next = NEXT(next_action), 7897 }, 7898 [INDIRECT_ACTION_LIST] = { 7899 .name = "list", 7900 .help = "specify actions for indirect handle list", 7901 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7902 .call = parse_ia, 7903 }, 7904 [INDIRECT_ACTION_FLOW_CONF] = { 7905 .name = "flow_conf", 7906 .help = "specify actions configuration for indirect handle list", 7907 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 7908 .call = parse_ia, 7909 }, 7910 [ACTION_POL_G] = { 7911 .name = "g_actions", 7912 .help = "submit a list of associated actions for green", 7913 .next = NEXT(next_action), 7914 .call = parse_mp, 7915 }, 7916 [ACTION_POL_Y] = { 7917 .name = "y_actions", 7918 .help = "submit a list of associated actions for yellow", 7919 .next = NEXT(next_action), 7920 }, 7921 [ACTION_POL_R] = { 7922 .name = "r_actions", 7923 .help = "submit a list of associated actions for red", 7924 .next = NEXT(next_action), 7925 }, 7926 [ACTION_QUOTA_CREATE] = { 7927 .name = "quota_create", 7928 .help = "create quota action", 7929 .priv = PRIV_ACTION(QUOTA, 7930 sizeof(struct rte_flow_action_quota)), 7931 .next = NEXT(action_quota_create), 7932 .call = parse_vc 7933 }, 7934 [ACTION_QUOTA_CREATE_LIMIT] = { 7935 .name = "limit", 7936 .help = "quota limit", 7937 .next = NEXT(action_quota_create, NEXT_ENTRY(COMMON_UNSIGNED)), 7938 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, quota)), 7939 .call = parse_vc_conf 7940 }, 7941 [ACTION_QUOTA_CREATE_MODE] = { 7942 .name = "mode", 7943 .help = "quota mode", 7944 .next = NEXT(action_quota_create, 7945 NEXT_ENTRY(ACTION_QUOTA_CREATE_MODE_NAME)), 7946 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_quota, mode)), 7947 .call = parse_vc_conf 7948 }, 7949 [ACTION_QUOTA_CREATE_MODE_NAME] = { 7950 .name = "mode_name", 7951 .help = "quota mode name", 7952 .call = parse_quota_mode_name, 7953 .comp = comp_quota_mode_name 7954 }, 7955 [ACTION_QUOTA_QU] = { 7956 .name = "quota_update", 7957 .help = "update quota action", 7958 .priv = PRIV_ACTION(QUOTA, 7959 sizeof(struct rte_flow_update_quota)), 7960 .next = NEXT(action_quota_update), 7961 .call = parse_vc 7962 }, 7963 [ACTION_QUOTA_QU_LIMIT] = { 7964 .name = "limit", 7965 .help = "quota limit", 7966 .next = NEXT(action_quota_update, NEXT_ENTRY(COMMON_UNSIGNED)), 7967 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, quota)), 7968 .call = parse_vc_conf 7969 }, 7970 [ACTION_QUOTA_QU_UPDATE_OP] = { 7971 .name = "update_op", 7972 .help = "query update op SET|ADD", 7973 .next = NEXT(action_quota_update, 7974 NEXT_ENTRY(ACTION_QUOTA_QU_UPDATE_OP_NAME)), 7975 .args = ARGS(ARGS_ENTRY(struct rte_flow_update_quota, op)), 7976 .call = parse_vc_conf 7977 }, 7978 [ACTION_QUOTA_QU_UPDATE_OP_NAME] = { 7979 .name = "update_op_name", 7980 .help = "quota update op name", 7981 .call = parse_quota_update_name, 7982 .comp = comp_quota_update_name 7983 }, 7984 7985 /* Top-level command. */ 7986 [ADD] = { 7987 .name = "add", 7988 .type = "port meter policy {port_id} {arg}", 7989 .help = "add port meter policy", 7990 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 7991 .call = parse_init, 7992 }, 7993 /* Sub-level commands. */ 7994 [ITEM_POL_PORT] = { 7995 .name = "port", 7996 .help = "add port meter policy", 7997 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 7998 }, 7999 [ITEM_POL_METER] = { 8000 .name = "meter", 8001 .help = "add port meter policy", 8002 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 8003 }, 8004 [ITEM_POL_POLICY] = { 8005 .name = "policy", 8006 .help = "add port meter policy", 8007 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 8008 NEXT_ENTRY(ACTION_POL_Y), 8009 NEXT_ENTRY(ACTION_POL_G), 8010 NEXT_ENTRY(COMMON_POLICY_ID), 8011 NEXT_ENTRY(COMMON_PORT_ID)), 8012 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 8013 ARGS_ENTRY(struct buffer, port)), 8014 .call = parse_mp, 8015 }, 8016 [ITEM_AGGR_AFFINITY] = { 8017 .name = "aggr_affinity", 8018 .help = "match on the aggregated port receiving the packets", 8019 .priv = PRIV_ITEM(AGGR_AFFINITY, 8020 sizeof(struct rte_flow_item_aggr_affinity)), 8021 .next = NEXT(item_aggr_affinity), 8022 .call = parse_vc, 8023 }, 8024 [ITEM_AGGR_AFFINITY_VALUE] = { 8025 .name = "affinity", 8026 .help = "aggregated affinity value", 8027 .next = NEXT(item_aggr_affinity, NEXT_ENTRY(COMMON_UNSIGNED), 8028 item_param), 8029 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_aggr_affinity, 8030 affinity)), 8031 }, 8032 [ITEM_TX_QUEUE] = { 8033 .name = "tx_queue", 8034 .help = "match on the tx queue of send packet", 8035 .priv = PRIV_ITEM(TX_QUEUE, 8036 sizeof(struct rte_flow_item_tx_queue)), 8037 .next = NEXT(item_tx_queue), 8038 .call = parse_vc, 8039 }, 8040 [ITEM_TX_QUEUE_VALUE] = { 8041 .name = "tx_queue_value", 8042 .help = "tx queue value", 8043 .next = NEXT(item_tx_queue, NEXT_ENTRY(COMMON_UNSIGNED), 8044 item_param), 8045 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tx_queue, 8046 tx_queue)), 8047 }, 8048 }; 8049 8050 /** Remove and return last entry from argument stack. */ 8051 static const struct arg * 8052 pop_args(struct context *ctx) 8053 { 8054 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 8055 } 8056 8057 /** Add entry on top of the argument stack. */ 8058 static int 8059 push_args(struct context *ctx, const struct arg *arg) 8060 { 8061 if (ctx->args_num == CTX_STACK_SIZE) 8062 return -1; 8063 ctx->args[ctx->args_num++] = arg; 8064 return 0; 8065 } 8066 8067 /** Spread value into buffer according to bit-mask. */ 8068 static size_t 8069 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 8070 { 8071 uint32_t i = arg->size; 8072 uint32_t end = 0; 8073 int sub = 1; 8074 int add = 0; 8075 size_t len = 0; 8076 8077 if (!arg->mask) 8078 return 0; 8079 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8080 if (!arg->hton) { 8081 i = 0; 8082 end = arg->size; 8083 sub = 0; 8084 add = 1; 8085 } 8086 #endif 8087 while (i != end) { 8088 unsigned int shift = 0; 8089 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 8090 8091 for (shift = 0; arg->mask[i] >> shift; ++shift) { 8092 if (!(arg->mask[i] & (1 << shift))) 8093 continue; 8094 ++len; 8095 if (!dst) 8096 continue; 8097 *buf &= ~(1 << shift); 8098 *buf |= (val & 1) << shift; 8099 val >>= 1; 8100 } 8101 i += add; 8102 } 8103 return len; 8104 } 8105 8106 /** Compare a string with a partial one of a given length. */ 8107 static int 8108 strcmp_partial(const char *full, const char *partial, size_t partial_len) 8109 { 8110 int r = strncmp(full, partial, partial_len); 8111 8112 if (r) 8113 return r; 8114 if (strlen(full) <= partial_len) 8115 return 0; 8116 return full[partial_len]; 8117 } 8118 8119 /** 8120 * Parse a prefix length and generate a bit-mask. 8121 * 8122 * Last argument (ctx->args) is retrieved to determine mask size, storage 8123 * location and whether the result must use network byte ordering. 8124 */ 8125 static int 8126 parse_prefix(struct context *ctx, const struct token *token, 8127 const char *str, unsigned int len, 8128 void *buf, unsigned int size) 8129 { 8130 const struct arg *arg = pop_args(ctx); 8131 static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff"; 8132 char *end; 8133 uintmax_t u; 8134 unsigned int bytes; 8135 unsigned int extra; 8136 8137 (void)token; 8138 /* Argument is expected. */ 8139 if (!arg) 8140 return -1; 8141 errno = 0; 8142 u = strtoumax(str, &end, 0); 8143 if (errno || (size_t)(end - str) != len) 8144 goto error; 8145 if (arg->mask) { 8146 uintmax_t v = 0; 8147 8148 extra = arg_entry_bf_fill(NULL, 0, arg); 8149 if (u > extra) 8150 goto error; 8151 if (!ctx->object) 8152 return len; 8153 extra -= u; 8154 while (u--) 8155 (v <<= 1, v |= 1); 8156 v <<= extra; 8157 if (!arg_entry_bf_fill(ctx->object, v, arg) || 8158 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 8159 goto error; 8160 return len; 8161 } 8162 bytes = u / 8; 8163 extra = u % 8; 8164 size = arg->size; 8165 if (bytes > size || bytes + !!extra > size) 8166 goto error; 8167 if (!ctx->object) 8168 return len; 8169 buf = (uint8_t *)ctx->object + arg->offset; 8170 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 8171 if (!arg->hton) { 8172 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 8173 memset(buf, 0x00, size - bytes); 8174 if (extra) 8175 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 8176 } else 8177 #endif 8178 { 8179 memset(buf, 0xff, bytes); 8180 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 8181 if (extra) 8182 ((uint8_t *)buf)[bytes] = conv[extra]; 8183 } 8184 if (ctx->objmask) 8185 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 8186 return len; 8187 error: 8188 push_args(ctx, arg); 8189 return -1; 8190 } 8191 8192 /** Default parsing function for token name matching. */ 8193 static int 8194 parse_default(struct context *ctx, const struct token *token, 8195 const char *str, unsigned int len, 8196 void *buf, unsigned int size) 8197 { 8198 (void)ctx; 8199 (void)buf; 8200 (void)size; 8201 if (strcmp_partial(token->name, str, len)) 8202 return -1; 8203 return len; 8204 } 8205 8206 /** Parse flow command, initialize output buffer for subsequent tokens. */ 8207 static int 8208 parse_init(struct context *ctx, const struct token *token, 8209 const char *str, unsigned int len, 8210 void *buf, unsigned int size) 8211 { 8212 struct buffer *out = buf; 8213 8214 /* Token name must match. */ 8215 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8216 return -1; 8217 /* Nothing else to do if there is no buffer. */ 8218 if (!out) 8219 return len; 8220 /* Make sure buffer is large enough. */ 8221 if (size < sizeof(*out)) 8222 return -1; 8223 /* Initialize buffer. */ 8224 memset(out, 0x00, sizeof(*out)); 8225 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 8226 ctx->objdata = 0; 8227 ctx->object = out; 8228 ctx->objmask = NULL; 8229 return len; 8230 } 8231 8232 /** Parse tokens for indirect action commands. */ 8233 static int 8234 parse_ia(struct context *ctx, const struct token *token, 8235 const char *str, unsigned int len, 8236 void *buf, unsigned int size) 8237 { 8238 struct buffer *out = buf; 8239 8240 /* Token name must match. */ 8241 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8242 return -1; 8243 /* Nothing else to do if there is no buffer. */ 8244 if (!out) 8245 return len; 8246 if (!out->command) { 8247 if (ctx->curr != INDIRECT_ACTION) 8248 return -1; 8249 if (sizeof(*out) > size) 8250 return -1; 8251 out->command = ctx->curr; 8252 ctx->objdata = 0; 8253 ctx->object = out; 8254 ctx->objmask = NULL; 8255 out->args.vc.data = (uint8_t *)out + size; 8256 return len; 8257 } 8258 switch (ctx->curr) { 8259 case INDIRECT_ACTION_CREATE: 8260 case INDIRECT_ACTION_UPDATE: 8261 case INDIRECT_ACTION_QUERY_UPDATE: 8262 out->args.vc.actions = 8263 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8264 sizeof(double)); 8265 out->args.vc.attr.group = UINT32_MAX; 8266 /* fallthrough */ 8267 case INDIRECT_ACTION_QUERY: 8268 out->command = ctx->curr; 8269 ctx->objdata = 0; 8270 ctx->object = out; 8271 ctx->objmask = NULL; 8272 return len; 8273 case INDIRECT_ACTION_EGRESS: 8274 out->args.vc.attr.egress = 1; 8275 return len; 8276 case INDIRECT_ACTION_INGRESS: 8277 out->args.vc.attr.ingress = 1; 8278 return len; 8279 case INDIRECT_ACTION_TRANSFER: 8280 out->args.vc.attr.transfer = 1; 8281 return len; 8282 case INDIRECT_ACTION_QU_MODE: 8283 return len; 8284 case INDIRECT_ACTION_LIST: 8285 out->command = INDIRECT_ACTION_LIST_CREATE; 8286 return len; 8287 case INDIRECT_ACTION_FLOW_CONF: 8288 out->command = INDIRECT_ACTION_FLOW_CONF_CREATE; 8289 return len; 8290 default: 8291 return -1; 8292 } 8293 } 8294 8295 8296 /** Parse tokens for indirect action destroy command. */ 8297 static int 8298 parse_ia_destroy(struct context *ctx, const struct token *token, 8299 const char *str, unsigned int len, 8300 void *buf, unsigned int size) 8301 { 8302 struct buffer *out = buf; 8303 uint32_t *action_id; 8304 8305 /* Token name must match. */ 8306 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8307 return -1; 8308 /* Nothing else to do if there is no buffer. */ 8309 if (!out) 8310 return len; 8311 if (!out->command || out->command == INDIRECT_ACTION) { 8312 if (ctx->curr != INDIRECT_ACTION_DESTROY) 8313 return -1; 8314 if (sizeof(*out) > size) 8315 return -1; 8316 out->command = ctx->curr; 8317 ctx->objdata = 0; 8318 ctx->object = out; 8319 ctx->objmask = NULL; 8320 out->args.ia_destroy.action_id = 8321 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8322 sizeof(double)); 8323 return len; 8324 } 8325 action_id = out->args.ia_destroy.action_id 8326 + out->args.ia_destroy.action_id_n++; 8327 if ((uint8_t *)action_id > (uint8_t *)out + size) 8328 return -1; 8329 ctx->objdata = 0; 8330 ctx->object = action_id; 8331 ctx->objmask = NULL; 8332 return len; 8333 } 8334 8335 /** Parse tokens for indirect action commands. */ 8336 static int 8337 parse_qia(struct context *ctx, const struct token *token, 8338 const char *str, unsigned int len, 8339 void *buf, unsigned int size) 8340 { 8341 struct buffer *out = buf; 8342 8343 /* Token name must match. */ 8344 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8345 return -1; 8346 /* Nothing else to do if there is no buffer. */ 8347 if (!out) 8348 return len; 8349 if (!out->command) { 8350 if (ctx->curr != QUEUE) 8351 return -1; 8352 if (sizeof(*out) > size) 8353 return -1; 8354 out->args.vc.data = (uint8_t *)out + size; 8355 return len; 8356 } 8357 switch (ctx->curr) { 8358 case QUEUE_INDIRECT_ACTION: 8359 return len; 8360 case QUEUE_INDIRECT_ACTION_CREATE: 8361 case QUEUE_INDIRECT_ACTION_UPDATE: 8362 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 8363 out->args.vc.actions = 8364 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8365 sizeof(double)); 8366 out->args.vc.attr.group = UINT32_MAX; 8367 /* fallthrough */ 8368 case QUEUE_INDIRECT_ACTION_QUERY: 8369 out->command = ctx->curr; 8370 ctx->objdata = 0; 8371 ctx->object = out; 8372 ctx->objmask = NULL; 8373 return len; 8374 case QUEUE_INDIRECT_ACTION_EGRESS: 8375 out->args.vc.attr.egress = 1; 8376 return len; 8377 case QUEUE_INDIRECT_ACTION_INGRESS: 8378 out->args.vc.attr.ingress = 1; 8379 return len; 8380 case QUEUE_INDIRECT_ACTION_TRANSFER: 8381 out->args.vc.attr.transfer = 1; 8382 return len; 8383 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 8384 return len; 8385 case QUEUE_INDIRECT_ACTION_QU_MODE: 8386 return len; 8387 case QUEUE_INDIRECT_ACTION_LIST: 8388 out->command = QUEUE_INDIRECT_ACTION_LIST_CREATE; 8389 return len; 8390 default: 8391 return -1; 8392 } 8393 } 8394 8395 /** Parse tokens for indirect action destroy command. */ 8396 static int 8397 parse_qia_destroy(struct context *ctx, const struct token *token, 8398 const char *str, unsigned int len, 8399 void *buf, unsigned int size) 8400 { 8401 struct buffer *out = buf; 8402 uint32_t *action_id; 8403 8404 /* Token name must match. */ 8405 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8406 return -1; 8407 /* Nothing else to do if there is no buffer. */ 8408 if (!out) 8409 return len; 8410 if (!out->command || out->command == QUEUE) { 8411 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 8412 return -1; 8413 if (sizeof(*out) > size) 8414 return -1; 8415 out->command = ctx->curr; 8416 ctx->objdata = 0; 8417 ctx->object = out; 8418 ctx->objmask = NULL; 8419 out->args.ia_destroy.action_id = 8420 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8421 sizeof(double)); 8422 return len; 8423 } 8424 switch (ctx->curr) { 8425 case QUEUE_INDIRECT_ACTION: 8426 out->command = ctx->curr; 8427 ctx->objdata = 0; 8428 ctx->object = out; 8429 ctx->objmask = NULL; 8430 return len; 8431 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 8432 action_id = out->args.ia_destroy.action_id 8433 + out->args.ia_destroy.action_id_n++; 8434 if ((uint8_t *)action_id > (uint8_t *)out + size) 8435 return -1; 8436 ctx->objdata = 0; 8437 ctx->object = action_id; 8438 ctx->objmask = NULL; 8439 return len; 8440 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 8441 return len; 8442 default: 8443 return -1; 8444 } 8445 } 8446 8447 /** Parse tokens for meter policy action commands. */ 8448 static int 8449 parse_mp(struct context *ctx, const struct token *token, 8450 const char *str, unsigned int len, 8451 void *buf, unsigned int size) 8452 { 8453 struct buffer *out = buf; 8454 8455 /* Token name must match. */ 8456 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8457 return -1; 8458 /* Nothing else to do if there is no buffer. */ 8459 if (!out) 8460 return len; 8461 if (!out->command) { 8462 if (ctx->curr != ITEM_POL_POLICY) 8463 return -1; 8464 if (sizeof(*out) > size) 8465 return -1; 8466 out->command = ctx->curr; 8467 ctx->objdata = 0; 8468 ctx->object = out; 8469 ctx->objmask = NULL; 8470 out->args.vc.data = (uint8_t *)out + size; 8471 return len; 8472 } 8473 switch (ctx->curr) { 8474 case ACTION_POL_G: 8475 out->args.vc.actions = 8476 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8477 sizeof(double)); 8478 out->command = ctx->curr; 8479 ctx->objdata = 0; 8480 ctx->object = out; 8481 ctx->objmask = NULL; 8482 return len; 8483 default: 8484 return -1; 8485 } 8486 } 8487 8488 /** Parse tokens for validate/create commands. */ 8489 static int 8490 parse_vc(struct context *ctx, const struct token *token, 8491 const char *str, unsigned int len, 8492 void *buf, unsigned int size) 8493 { 8494 struct buffer *out = buf; 8495 uint8_t *data; 8496 uint32_t data_size; 8497 8498 /* Token name must match. */ 8499 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8500 return -1; 8501 /* Nothing else to do if there is no buffer. */ 8502 if (!out) 8503 return len; 8504 if (!out->command) { 8505 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 8506 ctx->curr != PATTERN_TEMPLATE_CREATE && 8507 ctx->curr != ACTIONS_TEMPLATE_CREATE && 8508 ctx->curr != UPDATE) 8509 return -1; 8510 if (ctx->curr == UPDATE) 8511 out->args.vc.pattern = 8512 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8513 sizeof(double)); 8514 if (sizeof(*out) > size) 8515 return -1; 8516 out->command = ctx->curr; 8517 ctx->objdata = 0; 8518 ctx->object = out; 8519 ctx->objmask = NULL; 8520 out->args.vc.data = (uint8_t *)out + size; 8521 return len; 8522 } 8523 ctx->objdata = 0; 8524 switch (ctx->curr) { 8525 default: 8526 ctx->object = &out->args.vc.attr; 8527 break; 8528 case VC_TUNNEL_SET: 8529 case VC_TUNNEL_MATCH: 8530 ctx->object = &out->args.vc.tunnel_ops; 8531 break; 8532 case VC_USER_ID: 8533 ctx->object = out; 8534 break; 8535 } 8536 ctx->objmask = NULL; 8537 switch (ctx->curr) { 8538 case VC_GROUP: 8539 case VC_PRIORITY: 8540 case VC_USER_ID: 8541 return len; 8542 case VC_TUNNEL_SET: 8543 out->args.vc.tunnel_ops.enabled = 1; 8544 out->args.vc.tunnel_ops.actions = 1; 8545 return len; 8546 case VC_TUNNEL_MATCH: 8547 out->args.vc.tunnel_ops.enabled = 1; 8548 out->args.vc.tunnel_ops.items = 1; 8549 return len; 8550 case VC_INGRESS: 8551 out->args.vc.attr.ingress = 1; 8552 return len; 8553 case VC_EGRESS: 8554 out->args.vc.attr.egress = 1; 8555 return len; 8556 case VC_TRANSFER: 8557 out->args.vc.attr.transfer = 1; 8558 return len; 8559 case ITEM_PATTERN: 8560 out->args.vc.pattern = 8561 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8562 sizeof(double)); 8563 ctx->object = out->args.vc.pattern; 8564 ctx->objmask = NULL; 8565 return len; 8566 case ITEM_END: 8567 if ((out->command == VALIDATE || out->command == CREATE) && 8568 ctx->last) 8569 return -1; 8570 if (out->command == PATTERN_TEMPLATE_CREATE && 8571 !ctx->last) 8572 return -1; 8573 break; 8574 case ACTIONS: 8575 out->args.vc.actions = out->args.vc.pattern ? 8576 (void *)RTE_ALIGN_CEIL((uintptr_t) 8577 (out->args.vc.pattern + 8578 out->args.vc.pattern_n), 8579 sizeof(double)) : 8580 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8581 sizeof(double)); 8582 ctx->object = out->args.vc.actions; 8583 ctx->objmask = NULL; 8584 return len; 8585 case VC_IS_USER_ID: 8586 out->args.vc.user_id = true; 8587 return len; 8588 default: 8589 if (!token->priv) 8590 return -1; 8591 break; 8592 } 8593 if (!out->args.vc.actions) { 8594 const struct parse_item_priv *priv = token->priv; 8595 struct rte_flow_item *item = 8596 out->args.vc.pattern + out->args.vc.pattern_n; 8597 8598 data_size = priv->size * 3; /* spec, last, mask */ 8599 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8600 (out->args.vc.data - data_size), 8601 sizeof(double)); 8602 if ((uint8_t *)item + sizeof(*item) > data) 8603 return -1; 8604 *item = (struct rte_flow_item){ 8605 .type = priv->type, 8606 }; 8607 ++out->args.vc.pattern_n; 8608 ctx->object = item; 8609 ctx->objmask = NULL; 8610 } else { 8611 const struct parse_action_priv *priv = token->priv; 8612 struct rte_flow_action *action = 8613 out->args.vc.actions + out->args.vc.actions_n; 8614 8615 data_size = priv->size; /* configuration */ 8616 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 8617 (out->args.vc.data - data_size), 8618 sizeof(double)); 8619 if ((uint8_t *)action + sizeof(*action) > data) 8620 return -1; 8621 *action = (struct rte_flow_action){ 8622 .type = priv->type, 8623 .conf = data_size ? data : NULL, 8624 }; 8625 ++out->args.vc.actions_n; 8626 ctx->object = action; 8627 ctx->objmask = NULL; 8628 } 8629 memset(data, 0, data_size); 8630 out->args.vc.data = data; 8631 ctx->objdata = data_size; 8632 return len; 8633 } 8634 8635 /** Parse pattern item parameter type. */ 8636 static int 8637 parse_vc_spec(struct context *ctx, const struct token *token, 8638 const char *str, unsigned int len, 8639 void *buf, unsigned int size) 8640 { 8641 struct buffer *out = buf; 8642 struct rte_flow_item *item; 8643 uint32_t data_size; 8644 int index; 8645 int objmask = 0; 8646 8647 (void)size; 8648 /* Token name must match. */ 8649 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8650 return -1; 8651 /* Parse parameter types. */ 8652 switch (ctx->curr) { 8653 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 8654 8655 case ITEM_PARAM_IS: 8656 index = 0; 8657 objmask = 1; 8658 break; 8659 case ITEM_PARAM_SPEC: 8660 index = 0; 8661 break; 8662 case ITEM_PARAM_LAST: 8663 index = 1; 8664 break; 8665 case ITEM_PARAM_PREFIX: 8666 /* Modify next token to expect a prefix. */ 8667 if (ctx->next_num < 2) 8668 return -1; 8669 ctx->next[ctx->next_num - 2] = prefix; 8670 /* Fall through. */ 8671 case ITEM_PARAM_MASK: 8672 index = 2; 8673 break; 8674 default: 8675 return -1; 8676 } 8677 /* Nothing else to do if there is no buffer. */ 8678 if (!out) 8679 return len; 8680 if (!out->args.vc.pattern_n) 8681 return -1; 8682 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8683 data_size = ctx->objdata / 3; /* spec, last, mask */ 8684 /* Point to selected object. */ 8685 ctx->object = out->args.vc.data + (data_size * index); 8686 if (objmask) { 8687 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 8688 item->mask = ctx->objmask; 8689 } else 8690 ctx->objmask = NULL; 8691 /* Update relevant item pointer. */ 8692 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 8693 ctx->object; 8694 return len; 8695 } 8696 8697 /** Parse action configuration field. */ 8698 static int 8699 parse_vc_conf(struct context *ctx, const struct token *token, 8700 const char *str, unsigned int len, 8701 void *buf, unsigned int size) 8702 { 8703 struct buffer *out = buf; 8704 8705 (void)size; 8706 /* Token name must match. */ 8707 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8708 return -1; 8709 /* Nothing else to do if there is no buffer. */ 8710 if (!out) 8711 return len; 8712 /* Point to selected object. */ 8713 ctx->object = out->args.vc.data; 8714 ctx->objmask = NULL; 8715 return len; 8716 } 8717 8718 /** Parse action configuration field. */ 8719 static int 8720 parse_vc_conf_timeout(struct context *ctx, const struct token *token, 8721 const char *str, unsigned int len, 8722 void *buf, unsigned int size) 8723 { 8724 struct buffer *out = buf; 8725 struct rte_flow_update_age *update; 8726 8727 (void)size; 8728 if (ctx->curr != ACTION_AGE_UPDATE_TIMEOUT) 8729 return -1; 8730 /* Token name must match. */ 8731 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8732 return -1; 8733 /* Nothing else to do if there is no buffer. */ 8734 if (!out) 8735 return len; 8736 /* Point to selected object. */ 8737 ctx->object = out->args.vc.data; 8738 ctx->objmask = NULL; 8739 /* Update the timeout is valid. */ 8740 update = (struct rte_flow_update_age *)out->args.vc.data; 8741 update->timeout_valid = 1; 8742 return len; 8743 } 8744 8745 /** Parse eCPRI common header type field. */ 8746 static int 8747 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 8748 const char *str, unsigned int len, 8749 void *buf, unsigned int size) 8750 { 8751 struct rte_flow_item_ecpri *ecpri; 8752 struct rte_flow_item_ecpri *ecpri_mask; 8753 struct rte_flow_item *item; 8754 uint32_t data_size; 8755 uint8_t msg_type; 8756 struct buffer *out = buf; 8757 const struct arg *arg; 8758 8759 (void)size; 8760 /* Token name must match. */ 8761 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8762 return -1; 8763 switch (ctx->curr) { 8764 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 8765 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 8766 break; 8767 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 8768 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 8769 break; 8770 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 8771 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 8772 break; 8773 default: 8774 return -1; 8775 } 8776 if (!ctx->object) 8777 return len; 8778 arg = pop_args(ctx); 8779 if (!arg) 8780 return -1; 8781 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 8782 ecpri->hdr.common.type = msg_type; 8783 data_size = ctx->objdata / 3; /* spec, last, mask */ 8784 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 8785 (data_size * 2)); 8786 ecpri_mask->hdr.common.type = 0xFF; 8787 if (arg->hton) { 8788 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 8789 ecpri_mask->hdr.common.u32 = 8790 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 8791 } 8792 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8793 item->spec = ecpri; 8794 item->mask = ecpri_mask; 8795 return len; 8796 } 8797 8798 /** Parse L2TPv2 common header type field. */ 8799 static int 8800 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, 8801 const char *str, unsigned int len, 8802 void *buf, unsigned int size) 8803 { 8804 struct rte_flow_item_l2tpv2 *l2tpv2; 8805 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 8806 struct rte_flow_item *item; 8807 uint32_t data_size; 8808 uint16_t msg_type = 0; 8809 struct buffer *out = buf; 8810 const struct arg *arg; 8811 8812 (void)size; 8813 /* Token name must match. */ 8814 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8815 return -1; 8816 switch (ctx->curr) { 8817 case ITEM_L2TPV2_TYPE_DATA: 8818 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 8819 break; 8820 case ITEM_L2TPV2_TYPE_DATA_L: 8821 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 8822 break; 8823 case ITEM_L2TPV2_TYPE_DATA_S: 8824 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 8825 break; 8826 case ITEM_L2TPV2_TYPE_DATA_O: 8827 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 8828 break; 8829 case ITEM_L2TPV2_TYPE_DATA_L_S: 8830 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 8831 break; 8832 case ITEM_L2TPV2_TYPE_CTRL: 8833 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 8834 break; 8835 default: 8836 return -1; 8837 } 8838 if (!ctx->object) 8839 return len; 8840 arg = pop_args(ctx); 8841 if (!arg) 8842 return -1; 8843 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 8844 l2tpv2->hdr.common.flags_version |= msg_type; 8845 data_size = ctx->objdata / 3; /* spec, last, mask */ 8846 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 8847 (data_size * 2)); 8848 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 8849 if (arg->hton) { 8850 l2tpv2->hdr.common.flags_version = 8851 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 8852 l2tpv2_mask->hdr.common.flags_version = 8853 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 8854 } 8855 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 8856 item->spec = l2tpv2; 8857 item->mask = l2tpv2_mask; 8858 return len; 8859 } 8860 8861 /** Parse operation for compare match item. */ 8862 static int 8863 parse_vc_compare_op(struct context *ctx, const struct token *token, 8864 const char *str, unsigned int len, void *buf, 8865 unsigned int size) 8866 { 8867 struct rte_flow_item_compare *compare_item; 8868 unsigned int i; 8869 8870 (void)token; 8871 (void)buf; 8872 (void)size; 8873 if (ctx->curr != ITEM_COMPARE_OP_VALUE) 8874 return -1; 8875 for (i = 0; compare_ops[i]; ++i) 8876 if (!strcmp_partial(compare_ops[i], str, len)) 8877 break; 8878 if (!compare_ops[i]) 8879 return -1; 8880 if (!ctx->object) 8881 return len; 8882 compare_item = ctx->object; 8883 compare_item->operation = (enum rte_flow_item_compare_op)i; 8884 return len; 8885 } 8886 8887 /** Parse id for compare match item. */ 8888 static int 8889 parse_vc_compare_field_id(struct context *ctx, const struct token *token, 8890 const char *str, unsigned int len, void *buf, 8891 unsigned int size) 8892 { 8893 struct rte_flow_item_compare *compare_item; 8894 unsigned int i; 8895 8896 (void)token; 8897 (void)buf; 8898 (void)size; 8899 if (ctx->curr != ITEM_COMPARE_FIELD_A_TYPE_VALUE && 8900 ctx->curr != ITEM_COMPARE_FIELD_B_TYPE_VALUE) 8901 return -1; 8902 for (i = 0; flow_field_ids[i]; ++i) 8903 if (!strcmp_partial(flow_field_ids[i], str, len)) 8904 break; 8905 if (!flow_field_ids[i]) 8906 return -1; 8907 if (!ctx->object) 8908 return len; 8909 compare_item = ctx->object; 8910 if (ctx->curr == ITEM_COMPARE_FIELD_A_TYPE_VALUE) 8911 compare_item->a.field = (enum rte_flow_field_id)i; 8912 else 8913 compare_item->b.field = (enum rte_flow_field_id)i; 8914 return len; 8915 } 8916 8917 /** Parse level for compare match item. */ 8918 static int 8919 parse_vc_compare_field_level(struct context *ctx, const struct token *token, 8920 const char *str, unsigned int len, void *buf, 8921 unsigned int size) 8922 { 8923 struct rte_flow_item_compare *compare_item; 8924 struct flex_item *fp = NULL; 8925 uint32_t val; 8926 struct buffer *out = buf; 8927 char *end; 8928 8929 (void)token; 8930 (void)size; 8931 if (ctx->curr != ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 8932 ctx->curr != ITEM_COMPARE_FIELD_B_LEVEL_VALUE) 8933 return -1; 8934 if (!ctx->object) 8935 return len; 8936 compare_item = ctx->object; 8937 errno = 0; 8938 val = strtoumax(str, &end, 0); 8939 if (errno || (size_t)(end - str) != len) 8940 return -1; 8941 /* No need to validate action template mask value */ 8942 if (out->args.vc.masks) { 8943 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) 8944 compare_item->a.level = val; 8945 else 8946 compare_item->b.level = val; 8947 return len; 8948 } 8949 if ((ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE && 8950 compare_item->a.field == RTE_FLOW_FIELD_FLEX_ITEM) || 8951 (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE && 8952 compare_item->b.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 8953 if (val >= FLEX_MAX_PARSERS_NUM) { 8954 printf("Bad flex item handle\n"); 8955 return -1; 8956 } 8957 fp = flex_items[ctx->port][val]; 8958 if (!fp) { 8959 printf("Bad flex item handle\n"); 8960 return -1; 8961 } 8962 } 8963 if (ctx->curr == ITEM_COMPARE_FIELD_A_LEVEL_VALUE) { 8964 if (compare_item->a.field != RTE_FLOW_FIELD_FLEX_ITEM) 8965 compare_item->a.level = val; 8966 else 8967 compare_item->a.flex_handle = fp->flex_handle; 8968 } else if (ctx->curr == ITEM_COMPARE_FIELD_B_LEVEL_VALUE) { 8969 if (compare_item->b.field != RTE_FLOW_FIELD_FLEX_ITEM) 8970 compare_item->b.level = val; 8971 else 8972 compare_item->b.flex_handle = fp->flex_handle; 8973 } 8974 return len; 8975 } 8976 8977 /** Parse meter color action type. */ 8978 static int 8979 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 8980 const char *str, unsigned int len, 8981 void *buf, unsigned int size) 8982 { 8983 struct rte_flow_action *action_data; 8984 struct rte_flow_action_meter_color *conf; 8985 enum rte_color color; 8986 8987 (void)buf; 8988 (void)size; 8989 /* Token name must match. */ 8990 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8991 return -1; 8992 switch (ctx->curr) { 8993 case ACTION_METER_COLOR_GREEN: 8994 color = RTE_COLOR_GREEN; 8995 break; 8996 case ACTION_METER_COLOR_YELLOW: 8997 color = RTE_COLOR_YELLOW; 8998 break; 8999 case ACTION_METER_COLOR_RED: 9000 color = RTE_COLOR_RED; 9001 break; 9002 default: 9003 return -1; 9004 } 9005 9006 if (!ctx->object) 9007 return len; 9008 action_data = ctx->object; 9009 conf = (struct rte_flow_action_meter_color *) 9010 (uintptr_t)(action_data->conf); 9011 conf->color = color; 9012 return len; 9013 } 9014 9015 /** Parse RSS action. */ 9016 static int 9017 parse_vc_action_rss(struct context *ctx, const struct token *token, 9018 const char *str, unsigned int len, 9019 void *buf, unsigned int size) 9020 { 9021 struct buffer *out = buf; 9022 struct rte_flow_action *action; 9023 struct action_rss_data *action_rss_data; 9024 unsigned int i; 9025 int ret; 9026 9027 ret = parse_vc(ctx, token, str, len, buf, size); 9028 if (ret < 0) 9029 return ret; 9030 /* Nothing else to do if there is no buffer. */ 9031 if (!out) 9032 return ret; 9033 if (!out->args.vc.actions_n) 9034 return -1; 9035 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9036 /* Point to selected object. */ 9037 ctx->object = out->args.vc.data; 9038 ctx->objmask = NULL; 9039 /* Set up default configuration. */ 9040 action_rss_data = ctx->object; 9041 *action_rss_data = (struct action_rss_data){ 9042 .conf = (struct rte_flow_action_rss){ 9043 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 9044 .level = 0, 9045 .types = rss_hf, 9046 .key_len = 0, 9047 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 9048 .key = NULL, 9049 .queue = action_rss_data->queue, 9050 }, 9051 .queue = { 0 }, 9052 }; 9053 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 9054 action_rss_data->queue[i] = i; 9055 action->conf = &action_rss_data->conf; 9056 return ret; 9057 } 9058 9059 /** 9060 * Parse func field for RSS action. 9061 * 9062 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 9063 * ACTION_RSS_FUNC_* index that called this function. 9064 */ 9065 static int 9066 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 9067 const char *str, unsigned int len, 9068 void *buf, unsigned int size) 9069 { 9070 struct action_rss_data *action_rss_data; 9071 enum rte_eth_hash_function func; 9072 9073 (void)buf; 9074 (void)size; 9075 /* Token name must match. */ 9076 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9077 return -1; 9078 switch (ctx->curr) { 9079 case ACTION_RSS_FUNC_DEFAULT: 9080 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 9081 break; 9082 case ACTION_RSS_FUNC_TOEPLITZ: 9083 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 9084 break; 9085 case ACTION_RSS_FUNC_SIMPLE_XOR: 9086 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 9087 break; 9088 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 9089 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 9090 break; 9091 default: 9092 return -1; 9093 } 9094 if (!ctx->object) 9095 return len; 9096 action_rss_data = ctx->object; 9097 action_rss_data->conf.func = func; 9098 return len; 9099 } 9100 9101 /** 9102 * Parse type field for RSS action. 9103 * 9104 * Valid tokens are type field names and the "end" token. 9105 */ 9106 static int 9107 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 9108 const char *str, unsigned int len, 9109 void *buf, unsigned int size) 9110 { 9111 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 9112 struct action_rss_data *action_rss_data; 9113 unsigned int i; 9114 9115 (void)token; 9116 (void)buf; 9117 (void)size; 9118 if (ctx->curr != ACTION_RSS_TYPE) 9119 return -1; 9120 if (!(ctx->objdata >> 16) && ctx->object) { 9121 action_rss_data = ctx->object; 9122 action_rss_data->conf.types = 0; 9123 } 9124 if (!strcmp_partial("end", str, len)) { 9125 ctx->objdata &= 0xffff; 9126 return len; 9127 } 9128 for (i = 0; rss_type_table[i].str; ++i) 9129 if (!strcmp_partial(rss_type_table[i].str, str, len)) 9130 break; 9131 if (!rss_type_table[i].str) 9132 return -1; 9133 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 9134 /* Repeat token. */ 9135 if (ctx->next_num == RTE_DIM(ctx->next)) 9136 return -1; 9137 ctx->next[ctx->next_num++] = next; 9138 if (!ctx->object) 9139 return len; 9140 action_rss_data = ctx->object; 9141 action_rss_data->conf.types |= rss_type_table[i].rss_type; 9142 return len; 9143 } 9144 9145 /** 9146 * Parse queue field for RSS action. 9147 * 9148 * Valid tokens are queue indices and the "end" token. 9149 */ 9150 static int 9151 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 9152 const char *str, unsigned int len, 9153 void *buf, unsigned int size) 9154 { 9155 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 9156 struct action_rss_data *action_rss_data; 9157 const struct arg *arg; 9158 int ret; 9159 int i; 9160 9161 (void)token; 9162 (void)buf; 9163 (void)size; 9164 if (ctx->curr != ACTION_RSS_QUEUE) 9165 return -1; 9166 i = ctx->objdata >> 16; 9167 if (!strcmp_partial("end", str, len)) { 9168 ctx->objdata &= 0xffff; 9169 goto end; 9170 } 9171 if (i >= ACTION_RSS_QUEUE_NUM) 9172 return -1; 9173 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 9174 i * sizeof(action_rss_data->queue[i]), 9175 sizeof(action_rss_data->queue[i])); 9176 if (push_args(ctx, arg)) 9177 return -1; 9178 ret = parse_int(ctx, token, str, len, NULL, 0); 9179 if (ret < 0) { 9180 pop_args(ctx); 9181 return -1; 9182 } 9183 ++i; 9184 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 9185 /* Repeat token. */ 9186 if (ctx->next_num == RTE_DIM(ctx->next)) 9187 return -1; 9188 ctx->next[ctx->next_num++] = next; 9189 end: 9190 if (!ctx->object) 9191 return len; 9192 action_rss_data = ctx->object; 9193 action_rss_data->conf.queue_num = i; 9194 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 9195 return len; 9196 } 9197 9198 /** Setup VXLAN encap configuration. */ 9199 static int 9200 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 9201 { 9202 /* Set up default configuration. */ 9203 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 9204 .conf = (struct rte_flow_action_vxlan_encap){ 9205 .definition = action_vxlan_encap_data->items, 9206 }, 9207 .items = { 9208 { 9209 .type = RTE_FLOW_ITEM_TYPE_ETH, 9210 .spec = &action_vxlan_encap_data->item_eth, 9211 .mask = &rte_flow_item_eth_mask, 9212 }, 9213 { 9214 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9215 .spec = &action_vxlan_encap_data->item_vlan, 9216 .mask = &rte_flow_item_vlan_mask, 9217 }, 9218 { 9219 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9220 .spec = &action_vxlan_encap_data->item_ipv4, 9221 .mask = &rte_flow_item_ipv4_mask, 9222 }, 9223 { 9224 .type = RTE_FLOW_ITEM_TYPE_UDP, 9225 .spec = &action_vxlan_encap_data->item_udp, 9226 .mask = &rte_flow_item_udp_mask, 9227 }, 9228 { 9229 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 9230 .spec = &action_vxlan_encap_data->item_vxlan, 9231 .mask = &rte_flow_item_vxlan_mask, 9232 }, 9233 { 9234 .type = RTE_FLOW_ITEM_TYPE_END, 9235 }, 9236 }, 9237 .item_eth.hdr.ether_type = 0, 9238 .item_vlan = { 9239 .hdr.vlan_tci = vxlan_encap_conf.vlan_tci, 9240 .hdr.eth_proto = 0, 9241 }, 9242 .item_ipv4.hdr = { 9243 .src_addr = vxlan_encap_conf.ipv4_src, 9244 .dst_addr = vxlan_encap_conf.ipv4_dst, 9245 }, 9246 .item_udp.hdr = { 9247 .src_port = vxlan_encap_conf.udp_src, 9248 .dst_port = vxlan_encap_conf.udp_dst, 9249 }, 9250 .item_vxlan.hdr.flags = 0, 9251 }; 9252 memcpy(action_vxlan_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9253 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9254 memcpy(action_vxlan_encap_data->item_eth.hdr.src_addr.addr_bytes, 9255 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9256 if (!vxlan_encap_conf.select_ipv4) { 9257 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 9258 &vxlan_encap_conf.ipv6_src, 9259 sizeof(vxlan_encap_conf.ipv6_src)); 9260 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 9261 &vxlan_encap_conf.ipv6_dst, 9262 sizeof(vxlan_encap_conf.ipv6_dst)); 9263 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 9264 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9265 .spec = &action_vxlan_encap_data->item_ipv6, 9266 .mask = &rte_flow_item_ipv6_mask, 9267 }; 9268 } 9269 if (!vxlan_encap_conf.select_vlan) 9270 action_vxlan_encap_data->items[1].type = 9271 RTE_FLOW_ITEM_TYPE_VOID; 9272 if (vxlan_encap_conf.select_tos_ttl) { 9273 if (vxlan_encap_conf.select_ipv4) { 9274 static struct rte_flow_item_ipv4 ipv4_mask_tos; 9275 9276 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 9277 sizeof(ipv4_mask_tos)); 9278 ipv4_mask_tos.hdr.type_of_service = 0xff; 9279 ipv4_mask_tos.hdr.time_to_live = 0xff; 9280 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 9281 vxlan_encap_conf.ip_tos; 9282 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 9283 vxlan_encap_conf.ip_ttl; 9284 action_vxlan_encap_data->items[2].mask = 9285 &ipv4_mask_tos; 9286 } else { 9287 static struct rte_flow_item_ipv6 ipv6_mask_tos; 9288 9289 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 9290 sizeof(ipv6_mask_tos)); 9291 ipv6_mask_tos.hdr.vtc_flow |= 9292 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 9293 ipv6_mask_tos.hdr.hop_limits = 0xff; 9294 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 9295 rte_cpu_to_be_32 9296 ((uint32_t)vxlan_encap_conf.ip_tos << 9297 RTE_IPV6_HDR_TC_SHIFT); 9298 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 9299 vxlan_encap_conf.ip_ttl; 9300 action_vxlan_encap_data->items[2].mask = 9301 &ipv6_mask_tos; 9302 } 9303 } 9304 memcpy(action_vxlan_encap_data->item_vxlan.hdr.vni, vxlan_encap_conf.vni, 9305 RTE_DIM(vxlan_encap_conf.vni)); 9306 return 0; 9307 } 9308 9309 /** Parse VXLAN encap action. */ 9310 static int 9311 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 9312 const char *str, unsigned int len, 9313 void *buf, unsigned int size) 9314 { 9315 struct buffer *out = buf; 9316 struct rte_flow_action *action; 9317 struct action_vxlan_encap_data *action_vxlan_encap_data; 9318 int ret; 9319 9320 ret = parse_vc(ctx, token, str, len, buf, size); 9321 if (ret < 0) 9322 return ret; 9323 /* Nothing else to do if there is no buffer. */ 9324 if (!out) 9325 return ret; 9326 if (!out->args.vc.actions_n) 9327 return -1; 9328 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9329 /* Point to selected object. */ 9330 ctx->object = out->args.vc.data; 9331 ctx->objmask = NULL; 9332 action_vxlan_encap_data = ctx->object; 9333 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 9334 action->conf = &action_vxlan_encap_data->conf; 9335 return ret; 9336 } 9337 9338 /** Setup NVGRE encap configuration. */ 9339 static int 9340 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 9341 { 9342 /* Set up default configuration. */ 9343 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 9344 .conf = (struct rte_flow_action_nvgre_encap){ 9345 .definition = action_nvgre_encap_data->items, 9346 }, 9347 .items = { 9348 { 9349 .type = RTE_FLOW_ITEM_TYPE_ETH, 9350 .spec = &action_nvgre_encap_data->item_eth, 9351 .mask = &rte_flow_item_eth_mask, 9352 }, 9353 { 9354 .type = RTE_FLOW_ITEM_TYPE_VLAN, 9355 .spec = &action_nvgre_encap_data->item_vlan, 9356 .mask = &rte_flow_item_vlan_mask, 9357 }, 9358 { 9359 .type = RTE_FLOW_ITEM_TYPE_IPV4, 9360 .spec = &action_nvgre_encap_data->item_ipv4, 9361 .mask = &rte_flow_item_ipv4_mask, 9362 }, 9363 { 9364 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 9365 .spec = &action_nvgre_encap_data->item_nvgre, 9366 .mask = &rte_flow_item_nvgre_mask, 9367 }, 9368 { 9369 .type = RTE_FLOW_ITEM_TYPE_END, 9370 }, 9371 }, 9372 .item_eth.hdr.ether_type = 0, 9373 .item_vlan = { 9374 .hdr.vlan_tci = nvgre_encap_conf.vlan_tci, 9375 .hdr.eth_proto = 0, 9376 }, 9377 .item_ipv4.hdr = { 9378 .src_addr = nvgre_encap_conf.ipv4_src, 9379 .dst_addr = nvgre_encap_conf.ipv4_dst, 9380 }, 9381 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 9382 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 9383 .item_nvgre.flow_id = 0, 9384 }; 9385 memcpy(action_nvgre_encap_data->item_eth.hdr.dst_addr.addr_bytes, 9386 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9387 memcpy(action_nvgre_encap_data->item_eth.hdr.src_addr.addr_bytes, 9388 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9389 if (!nvgre_encap_conf.select_ipv4) { 9390 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 9391 &nvgre_encap_conf.ipv6_src, 9392 sizeof(nvgre_encap_conf.ipv6_src)); 9393 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 9394 &nvgre_encap_conf.ipv6_dst, 9395 sizeof(nvgre_encap_conf.ipv6_dst)); 9396 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 9397 .type = RTE_FLOW_ITEM_TYPE_IPV6, 9398 .spec = &action_nvgre_encap_data->item_ipv6, 9399 .mask = &rte_flow_item_ipv6_mask, 9400 }; 9401 } 9402 if (!nvgre_encap_conf.select_vlan) 9403 action_nvgre_encap_data->items[1].type = 9404 RTE_FLOW_ITEM_TYPE_VOID; 9405 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 9406 RTE_DIM(nvgre_encap_conf.tni)); 9407 return 0; 9408 } 9409 9410 /** Parse NVGRE encap action. */ 9411 static int 9412 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 9413 const char *str, unsigned int len, 9414 void *buf, unsigned int size) 9415 { 9416 struct buffer *out = buf; 9417 struct rte_flow_action *action; 9418 struct action_nvgre_encap_data *action_nvgre_encap_data; 9419 int ret; 9420 9421 ret = parse_vc(ctx, token, str, len, buf, size); 9422 if (ret < 0) 9423 return ret; 9424 /* Nothing else to do if there is no buffer. */ 9425 if (!out) 9426 return ret; 9427 if (!out->args.vc.actions_n) 9428 return -1; 9429 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9430 /* Point to selected object. */ 9431 ctx->object = out->args.vc.data; 9432 ctx->objmask = NULL; 9433 action_nvgre_encap_data = ctx->object; 9434 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 9435 action->conf = &action_nvgre_encap_data->conf; 9436 return ret; 9437 } 9438 9439 /** Parse l2 encap action. */ 9440 static int 9441 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 9442 const char *str, unsigned int len, 9443 void *buf, unsigned int size) 9444 { 9445 struct buffer *out = buf; 9446 struct rte_flow_action *action; 9447 struct action_raw_encap_data *action_encap_data; 9448 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9449 struct rte_flow_item_vlan vlan = { 9450 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9451 .hdr.eth_proto = 0, 9452 }; 9453 uint8_t *header; 9454 int ret; 9455 9456 ret = parse_vc(ctx, token, str, len, buf, size); 9457 if (ret < 0) 9458 return ret; 9459 /* Nothing else to do if there is no buffer. */ 9460 if (!out) 9461 return ret; 9462 if (!out->args.vc.actions_n) 9463 return -1; 9464 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9465 /* Point to selected object. */ 9466 ctx->object = out->args.vc.data; 9467 ctx->objmask = NULL; 9468 /* Copy the headers to the buffer. */ 9469 action_encap_data = ctx->object; 9470 *action_encap_data = (struct action_raw_encap_data) { 9471 .conf = (struct rte_flow_action_raw_encap){ 9472 .data = action_encap_data->data, 9473 }, 9474 .data = {}, 9475 }; 9476 header = action_encap_data->data; 9477 if (l2_encap_conf.select_vlan) 9478 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9479 else if (l2_encap_conf.select_ipv4) 9480 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9481 else 9482 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9483 memcpy(eth.hdr.dst_addr.addr_bytes, 9484 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9485 memcpy(eth.hdr.src_addr.addr_bytes, 9486 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9487 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9488 header += sizeof(struct rte_ether_hdr); 9489 if (l2_encap_conf.select_vlan) { 9490 if (l2_encap_conf.select_ipv4) 9491 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9492 else 9493 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9494 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9495 header += sizeof(struct rte_vlan_hdr); 9496 } 9497 action_encap_data->conf.size = header - 9498 action_encap_data->data; 9499 action->conf = &action_encap_data->conf; 9500 return ret; 9501 } 9502 9503 /** Parse l2 decap action. */ 9504 static int 9505 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 9506 const char *str, unsigned int len, 9507 void *buf, unsigned int size) 9508 { 9509 struct buffer *out = buf; 9510 struct rte_flow_action *action; 9511 struct action_raw_decap_data *action_decap_data; 9512 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9513 struct rte_flow_item_vlan vlan = { 9514 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9515 .hdr.eth_proto = 0, 9516 }; 9517 uint8_t *header; 9518 int ret; 9519 9520 ret = parse_vc(ctx, token, str, len, buf, size); 9521 if (ret < 0) 9522 return ret; 9523 /* Nothing else to do if there is no buffer. */ 9524 if (!out) 9525 return ret; 9526 if (!out->args.vc.actions_n) 9527 return -1; 9528 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9529 /* Point to selected object. */ 9530 ctx->object = out->args.vc.data; 9531 ctx->objmask = NULL; 9532 /* Copy the headers to the buffer. */ 9533 action_decap_data = ctx->object; 9534 *action_decap_data = (struct action_raw_decap_data) { 9535 .conf = (struct rte_flow_action_raw_decap){ 9536 .data = action_decap_data->data, 9537 }, 9538 .data = {}, 9539 }; 9540 header = action_decap_data->data; 9541 if (l2_decap_conf.select_vlan) 9542 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9543 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9544 header += sizeof(struct rte_ether_hdr); 9545 if (l2_decap_conf.select_vlan) { 9546 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9547 header += sizeof(struct rte_vlan_hdr); 9548 } 9549 action_decap_data->conf.size = header - 9550 action_decap_data->data; 9551 action->conf = &action_decap_data->conf; 9552 return ret; 9553 } 9554 9555 #define ETHER_TYPE_MPLS_UNICAST 0x8847 9556 9557 /** Parse MPLSOGRE encap action. */ 9558 static int 9559 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 9560 const char *str, unsigned int len, 9561 void *buf, unsigned int size) 9562 { 9563 struct buffer *out = buf; 9564 struct rte_flow_action *action; 9565 struct action_raw_encap_data *action_encap_data; 9566 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9567 struct rte_flow_item_vlan vlan = { 9568 .hdr.vlan_tci = mplsogre_encap_conf.vlan_tci, 9569 .hdr.eth_proto = 0, 9570 }; 9571 struct rte_flow_item_ipv4 ipv4 = { 9572 .hdr = { 9573 .src_addr = mplsogre_encap_conf.ipv4_src, 9574 .dst_addr = mplsogre_encap_conf.ipv4_dst, 9575 .next_proto_id = IPPROTO_GRE, 9576 .version_ihl = RTE_IPV4_VHL_DEF, 9577 .time_to_live = IPDEFTTL, 9578 }, 9579 }; 9580 struct rte_flow_item_ipv6 ipv6 = { 9581 .hdr = { 9582 .proto = IPPROTO_GRE, 9583 .hop_limits = IPDEFTTL, 9584 }, 9585 }; 9586 struct rte_flow_item_gre gre = { 9587 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9588 }; 9589 struct rte_flow_item_mpls mpls = { 9590 .ttl = 0, 9591 }; 9592 uint8_t *header; 9593 int ret; 9594 9595 ret = parse_vc(ctx, token, str, len, buf, size); 9596 if (ret < 0) 9597 return ret; 9598 /* Nothing else to do if there is no buffer. */ 9599 if (!out) 9600 return ret; 9601 if (!out->args.vc.actions_n) 9602 return -1; 9603 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9604 /* Point to selected object. */ 9605 ctx->object = out->args.vc.data; 9606 ctx->objmask = NULL; 9607 /* Copy the headers to the buffer. */ 9608 action_encap_data = ctx->object; 9609 *action_encap_data = (struct action_raw_encap_data) { 9610 .conf = (struct rte_flow_action_raw_encap){ 9611 .data = action_encap_data->data, 9612 }, 9613 .data = {}, 9614 .preserve = {}, 9615 }; 9616 header = action_encap_data->data; 9617 if (mplsogre_encap_conf.select_vlan) 9618 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9619 else if (mplsogre_encap_conf.select_ipv4) 9620 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9621 else 9622 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9623 memcpy(eth.hdr.dst_addr.addr_bytes, 9624 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9625 memcpy(eth.hdr.src_addr.addr_bytes, 9626 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9627 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9628 header += sizeof(struct rte_ether_hdr); 9629 if (mplsogre_encap_conf.select_vlan) { 9630 if (mplsogre_encap_conf.select_ipv4) 9631 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9632 else 9633 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9634 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9635 header += sizeof(struct rte_vlan_hdr); 9636 } 9637 if (mplsogre_encap_conf.select_ipv4) { 9638 memcpy(header, &ipv4, sizeof(ipv4)); 9639 header += sizeof(ipv4); 9640 } else { 9641 memcpy(&ipv6.hdr.src_addr, 9642 &mplsogre_encap_conf.ipv6_src, 9643 sizeof(mplsogre_encap_conf.ipv6_src)); 9644 memcpy(&ipv6.hdr.dst_addr, 9645 &mplsogre_encap_conf.ipv6_dst, 9646 sizeof(mplsogre_encap_conf.ipv6_dst)); 9647 memcpy(header, &ipv6, sizeof(ipv6)); 9648 header += sizeof(ipv6); 9649 } 9650 memcpy(header, &gre, sizeof(gre)); 9651 header += sizeof(gre); 9652 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 9653 RTE_DIM(mplsogre_encap_conf.label)); 9654 mpls.label_tc_s[2] |= 0x1; 9655 memcpy(header, &mpls, sizeof(mpls)); 9656 header += sizeof(mpls); 9657 action_encap_data->conf.size = header - 9658 action_encap_data->data; 9659 action->conf = &action_encap_data->conf; 9660 return ret; 9661 } 9662 9663 /** Parse MPLSOGRE decap action. */ 9664 static int 9665 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 9666 const char *str, unsigned int len, 9667 void *buf, unsigned int size) 9668 { 9669 struct buffer *out = buf; 9670 struct rte_flow_action *action; 9671 struct action_raw_decap_data *action_decap_data; 9672 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9673 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9674 struct rte_flow_item_ipv4 ipv4 = { 9675 .hdr = { 9676 .next_proto_id = IPPROTO_GRE, 9677 }, 9678 }; 9679 struct rte_flow_item_ipv6 ipv6 = { 9680 .hdr = { 9681 .proto = IPPROTO_GRE, 9682 }, 9683 }; 9684 struct rte_flow_item_gre gre = { 9685 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 9686 }; 9687 struct rte_flow_item_mpls mpls; 9688 uint8_t *header; 9689 int ret; 9690 9691 ret = parse_vc(ctx, token, str, len, buf, size); 9692 if (ret < 0) 9693 return ret; 9694 /* Nothing else to do if there is no buffer. */ 9695 if (!out) 9696 return ret; 9697 if (!out->args.vc.actions_n) 9698 return -1; 9699 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9700 /* Point to selected object. */ 9701 ctx->object = out->args.vc.data; 9702 ctx->objmask = NULL; 9703 /* Copy the headers to the buffer. */ 9704 action_decap_data = ctx->object; 9705 *action_decap_data = (struct action_raw_decap_data) { 9706 .conf = (struct rte_flow_action_raw_decap){ 9707 .data = action_decap_data->data, 9708 }, 9709 .data = {}, 9710 }; 9711 header = action_decap_data->data; 9712 if (mplsogre_decap_conf.select_vlan) 9713 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9714 else if (mplsogre_encap_conf.select_ipv4) 9715 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9716 else 9717 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9718 memcpy(eth.hdr.dst_addr.addr_bytes, 9719 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9720 memcpy(eth.hdr.src_addr.addr_bytes, 9721 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9722 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9723 header += sizeof(struct rte_ether_hdr); 9724 if (mplsogre_encap_conf.select_vlan) { 9725 if (mplsogre_encap_conf.select_ipv4) 9726 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9727 else 9728 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9729 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9730 header += sizeof(struct rte_vlan_hdr); 9731 } 9732 if (mplsogre_encap_conf.select_ipv4) { 9733 memcpy(header, &ipv4, sizeof(ipv4)); 9734 header += sizeof(ipv4); 9735 } else { 9736 memcpy(header, &ipv6, sizeof(ipv6)); 9737 header += sizeof(ipv6); 9738 } 9739 memcpy(header, &gre, sizeof(gre)); 9740 header += sizeof(gre); 9741 memset(&mpls, 0, sizeof(mpls)); 9742 memcpy(header, &mpls, sizeof(mpls)); 9743 header += sizeof(mpls); 9744 action_decap_data->conf.size = header - 9745 action_decap_data->data; 9746 action->conf = &action_decap_data->conf; 9747 return ret; 9748 } 9749 9750 /** Parse MPLSOUDP encap action. */ 9751 static int 9752 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 9753 const char *str, unsigned int len, 9754 void *buf, unsigned int size) 9755 { 9756 struct buffer *out = buf; 9757 struct rte_flow_action *action; 9758 struct action_raw_encap_data *action_encap_data; 9759 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9760 struct rte_flow_item_vlan vlan = { 9761 .hdr.vlan_tci = mplsoudp_encap_conf.vlan_tci, 9762 .hdr.eth_proto = 0, 9763 }; 9764 struct rte_flow_item_ipv4 ipv4 = { 9765 .hdr = { 9766 .src_addr = mplsoudp_encap_conf.ipv4_src, 9767 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 9768 .next_proto_id = IPPROTO_UDP, 9769 .version_ihl = RTE_IPV4_VHL_DEF, 9770 .time_to_live = IPDEFTTL, 9771 }, 9772 }; 9773 struct rte_flow_item_ipv6 ipv6 = { 9774 .hdr = { 9775 .proto = IPPROTO_UDP, 9776 .hop_limits = IPDEFTTL, 9777 }, 9778 }; 9779 struct rte_flow_item_udp udp = { 9780 .hdr = { 9781 .src_port = mplsoudp_encap_conf.udp_src, 9782 .dst_port = mplsoudp_encap_conf.udp_dst, 9783 }, 9784 }; 9785 struct rte_flow_item_mpls mpls; 9786 uint8_t *header; 9787 int ret; 9788 9789 ret = parse_vc(ctx, token, str, len, buf, size); 9790 if (ret < 0) 9791 return ret; 9792 /* Nothing else to do if there is no buffer. */ 9793 if (!out) 9794 return ret; 9795 if (!out->args.vc.actions_n) 9796 return -1; 9797 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9798 /* Point to selected object. */ 9799 ctx->object = out->args.vc.data; 9800 ctx->objmask = NULL; 9801 /* Copy the headers to the buffer. */ 9802 action_encap_data = ctx->object; 9803 *action_encap_data = (struct action_raw_encap_data) { 9804 .conf = (struct rte_flow_action_raw_encap){ 9805 .data = action_encap_data->data, 9806 }, 9807 .data = {}, 9808 .preserve = {}, 9809 }; 9810 header = action_encap_data->data; 9811 if (mplsoudp_encap_conf.select_vlan) 9812 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9813 else if (mplsoudp_encap_conf.select_ipv4) 9814 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9815 else 9816 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9817 memcpy(eth.hdr.dst_addr.addr_bytes, 9818 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9819 memcpy(eth.hdr.src_addr.addr_bytes, 9820 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9821 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9822 header += sizeof(struct rte_ether_hdr); 9823 if (mplsoudp_encap_conf.select_vlan) { 9824 if (mplsoudp_encap_conf.select_ipv4) 9825 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9826 else 9827 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9828 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9829 header += sizeof(struct rte_vlan_hdr); 9830 } 9831 if (mplsoudp_encap_conf.select_ipv4) { 9832 memcpy(header, &ipv4, sizeof(ipv4)); 9833 header += sizeof(ipv4); 9834 } else { 9835 memcpy(&ipv6.hdr.src_addr, 9836 &mplsoudp_encap_conf.ipv6_src, 9837 sizeof(mplsoudp_encap_conf.ipv6_src)); 9838 memcpy(&ipv6.hdr.dst_addr, 9839 &mplsoudp_encap_conf.ipv6_dst, 9840 sizeof(mplsoudp_encap_conf.ipv6_dst)); 9841 memcpy(header, &ipv6, sizeof(ipv6)); 9842 header += sizeof(ipv6); 9843 } 9844 memcpy(header, &udp, sizeof(udp)); 9845 header += sizeof(udp); 9846 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 9847 RTE_DIM(mplsoudp_encap_conf.label)); 9848 mpls.label_tc_s[2] |= 0x1; 9849 memcpy(header, &mpls, sizeof(mpls)); 9850 header += sizeof(mpls); 9851 action_encap_data->conf.size = header - 9852 action_encap_data->data; 9853 action->conf = &action_encap_data->conf; 9854 return ret; 9855 } 9856 9857 /** Parse MPLSOUDP decap action. */ 9858 static int 9859 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 9860 const char *str, unsigned int len, 9861 void *buf, unsigned int size) 9862 { 9863 struct buffer *out = buf; 9864 struct rte_flow_action *action; 9865 struct action_raw_decap_data *action_decap_data; 9866 struct rte_flow_item_eth eth = { .hdr.ether_type = 0, }; 9867 struct rte_flow_item_vlan vlan = {.hdr.vlan_tci = 0}; 9868 struct rte_flow_item_ipv4 ipv4 = { 9869 .hdr = { 9870 .next_proto_id = IPPROTO_UDP, 9871 }, 9872 }; 9873 struct rte_flow_item_ipv6 ipv6 = { 9874 .hdr = { 9875 .proto = IPPROTO_UDP, 9876 }, 9877 }; 9878 struct rte_flow_item_udp udp = { 9879 .hdr = { 9880 .dst_port = rte_cpu_to_be_16(6635), 9881 }, 9882 }; 9883 struct rte_flow_item_mpls mpls; 9884 uint8_t *header; 9885 int ret; 9886 9887 ret = parse_vc(ctx, token, str, len, buf, size); 9888 if (ret < 0) 9889 return ret; 9890 /* Nothing else to do if there is no buffer. */ 9891 if (!out) 9892 return ret; 9893 if (!out->args.vc.actions_n) 9894 return -1; 9895 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9896 /* Point to selected object. */ 9897 ctx->object = out->args.vc.data; 9898 ctx->objmask = NULL; 9899 /* Copy the headers to the buffer. */ 9900 action_decap_data = ctx->object; 9901 *action_decap_data = (struct action_raw_decap_data) { 9902 .conf = (struct rte_flow_action_raw_decap){ 9903 .data = action_decap_data->data, 9904 }, 9905 .data = {}, 9906 }; 9907 header = action_decap_data->data; 9908 if (mplsoudp_decap_conf.select_vlan) 9909 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 9910 else if (mplsoudp_encap_conf.select_ipv4) 9911 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9912 else 9913 eth.hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9914 memcpy(eth.hdr.dst_addr.addr_bytes, 9915 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 9916 memcpy(eth.hdr.src_addr.addr_bytes, 9917 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 9918 memcpy(header, ð.hdr, sizeof(struct rte_ether_hdr)); 9919 header += sizeof(struct rte_ether_hdr); 9920 if (mplsoudp_encap_conf.select_vlan) { 9921 if (mplsoudp_encap_conf.select_ipv4) 9922 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 9923 else 9924 vlan.hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 9925 memcpy(header, &vlan.hdr, sizeof(struct rte_vlan_hdr)); 9926 header += sizeof(struct rte_vlan_hdr); 9927 } 9928 if (mplsoudp_encap_conf.select_ipv4) { 9929 memcpy(header, &ipv4, sizeof(ipv4)); 9930 header += sizeof(ipv4); 9931 } else { 9932 memcpy(header, &ipv6, sizeof(ipv6)); 9933 header += sizeof(ipv6); 9934 } 9935 memcpy(header, &udp, sizeof(udp)); 9936 header += sizeof(udp); 9937 memset(&mpls, 0, sizeof(mpls)); 9938 memcpy(header, &mpls, sizeof(mpls)); 9939 header += sizeof(mpls); 9940 action_decap_data->conf.size = header - 9941 action_decap_data->data; 9942 action->conf = &action_decap_data->conf; 9943 return ret; 9944 } 9945 9946 static int 9947 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 9948 const char *str, unsigned int len, void *buf, 9949 unsigned int size) 9950 { 9951 struct action_raw_decap_data *action_raw_decap_data; 9952 struct rte_flow_action *action; 9953 const struct arg *arg; 9954 struct buffer *out = buf; 9955 int ret; 9956 uint16_t idx; 9957 9958 RTE_SET_USED(token); 9959 RTE_SET_USED(buf); 9960 RTE_SET_USED(size); 9961 arg = ARGS_ENTRY_ARB_BOUNDED 9962 (offsetof(struct action_raw_decap_data, idx), 9963 sizeof(((struct action_raw_decap_data *)0)->idx), 9964 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 9965 if (push_args(ctx, arg)) 9966 return -1; 9967 ret = parse_int(ctx, token, str, len, NULL, 0); 9968 if (ret < 0) { 9969 pop_args(ctx); 9970 return -1; 9971 } 9972 if (!ctx->object) 9973 return len; 9974 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 9975 action_raw_decap_data = ctx->object; 9976 idx = action_raw_decap_data->idx; 9977 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 9978 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 9979 action->conf = &action_raw_decap_data->conf; 9980 return len; 9981 } 9982 9983 9984 static int 9985 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 9986 const char *str, unsigned int len, void *buf, 9987 unsigned int size) 9988 { 9989 struct action_raw_encap_data *action_raw_encap_data; 9990 struct rte_flow_action *action; 9991 const struct arg *arg; 9992 struct buffer *out = buf; 9993 int ret; 9994 uint16_t idx; 9995 9996 RTE_SET_USED(token); 9997 RTE_SET_USED(buf); 9998 RTE_SET_USED(size); 9999 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 10000 return -1; 10001 arg = ARGS_ENTRY_ARB_BOUNDED 10002 (offsetof(struct action_raw_encap_data, idx), 10003 sizeof(((struct action_raw_encap_data *)0)->idx), 10004 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 10005 if (push_args(ctx, arg)) 10006 return -1; 10007 ret = parse_int(ctx, token, str, len, NULL, 0); 10008 if (ret < 0) { 10009 pop_args(ctx); 10010 return -1; 10011 } 10012 if (!ctx->object) 10013 return len; 10014 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10015 action_raw_encap_data = ctx->object; 10016 idx = action_raw_encap_data->idx; 10017 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 10018 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 10019 action_raw_encap_data->conf.preserve = NULL; 10020 action->conf = &action_raw_encap_data->conf; 10021 return len; 10022 } 10023 10024 static int 10025 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 10026 const char *str, unsigned int len, void *buf, 10027 unsigned int size) 10028 { 10029 struct buffer *out = buf; 10030 int ret; 10031 10032 ret = parse_vc(ctx, token, str, len, buf, size); 10033 if (ret < 0) 10034 return ret; 10035 /* Nothing else to do if there is no buffer. */ 10036 if (!out) 10037 return ret; 10038 if (!out->args.vc.actions_n) 10039 return -1; 10040 /* Point to selected object. */ 10041 ctx->object = out->args.vc.data; 10042 ctx->objmask = NULL; 10043 return ret; 10044 } 10045 10046 static int 10047 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 10048 const char *str, unsigned int len, void *buf, 10049 unsigned int size) 10050 { 10051 struct buffer *out = buf; 10052 struct rte_flow_action *action; 10053 struct action_raw_decap_data *action_raw_decap_data = NULL; 10054 int ret; 10055 10056 ret = parse_vc(ctx, token, str, len, buf, size); 10057 if (ret < 0) 10058 return ret; 10059 /* Nothing else to do if there is no buffer. */ 10060 if (!out) 10061 return ret; 10062 if (!out->args.vc.actions_n) 10063 return -1; 10064 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10065 /* Point to selected object. */ 10066 ctx->object = out->args.vc.data; 10067 ctx->objmask = NULL; 10068 /* Copy the headers to the buffer. */ 10069 action_raw_decap_data = ctx->object; 10070 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 10071 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 10072 action->conf = &action_raw_decap_data->conf; 10073 return ret; 10074 } 10075 10076 static int 10077 parse_vc_action_ipv6_ext_remove(struct context *ctx, const struct token *token, 10078 const char *str, unsigned int len, void *buf, 10079 unsigned int size) 10080 { 10081 struct buffer *out = buf; 10082 struct rte_flow_action *action; 10083 struct action_ipv6_ext_remove_data *ipv6_ext_remove_data = NULL; 10084 int ret; 10085 10086 ret = parse_vc(ctx, token, str, len, buf, size); 10087 if (ret < 0) 10088 return ret; 10089 /* Nothing else to do if there is no buffer. */ 10090 if (!out) 10091 return ret; 10092 if (!out->args.vc.actions_n) 10093 return -1; 10094 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10095 /* Point to selected object. */ 10096 ctx->object = out->args.vc.data; 10097 ctx->objmask = NULL; 10098 /* Copy the headers to the buffer. */ 10099 ipv6_ext_remove_data = ctx->object; 10100 ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[0].type; 10101 action->conf = &ipv6_ext_remove_data->conf; 10102 return ret; 10103 } 10104 10105 static int 10106 parse_vc_action_ipv6_ext_remove_index(struct context *ctx, const struct token *token, 10107 const char *str, unsigned int len, void *buf, 10108 unsigned int size) 10109 { 10110 struct action_ipv6_ext_remove_data *action_ipv6_ext_remove_data; 10111 struct rte_flow_action *action; 10112 const struct arg *arg; 10113 struct buffer *out = buf; 10114 int ret; 10115 uint16_t idx; 10116 10117 RTE_SET_USED(token); 10118 RTE_SET_USED(buf); 10119 RTE_SET_USED(size); 10120 arg = ARGS_ENTRY_ARB_BOUNDED 10121 (offsetof(struct action_ipv6_ext_remove_data, idx), 10122 sizeof(((struct action_ipv6_ext_remove_data *)0)->idx), 10123 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10124 if (push_args(ctx, arg)) 10125 return -1; 10126 ret = parse_int(ctx, token, str, len, NULL, 0); 10127 if (ret < 0) { 10128 pop_args(ctx); 10129 return -1; 10130 } 10131 if (!ctx->object) 10132 return len; 10133 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10134 action_ipv6_ext_remove_data = ctx->object; 10135 idx = action_ipv6_ext_remove_data->idx; 10136 action_ipv6_ext_remove_data->conf.type = ipv6_ext_remove_confs[idx].type; 10137 action->conf = &action_ipv6_ext_remove_data->conf; 10138 return len; 10139 } 10140 10141 static int 10142 parse_vc_action_ipv6_ext_push(struct context *ctx, const struct token *token, 10143 const char *str, unsigned int len, void *buf, 10144 unsigned int size) 10145 { 10146 struct buffer *out = buf; 10147 struct rte_flow_action *action; 10148 struct action_ipv6_ext_push_data *ipv6_ext_push_data = NULL; 10149 int ret; 10150 10151 ret = parse_vc(ctx, token, str, len, buf, size); 10152 if (ret < 0) 10153 return ret; 10154 /* Nothing else to do if there is no buffer. */ 10155 if (!out) 10156 return ret; 10157 if (!out->args.vc.actions_n) 10158 return -1; 10159 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10160 /* Point to selected object. */ 10161 ctx->object = out->args.vc.data; 10162 ctx->objmask = NULL; 10163 /* Copy the headers to the buffer. */ 10164 ipv6_ext_push_data = ctx->object; 10165 ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[0].type; 10166 ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[0].data; 10167 ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[0].size; 10168 action->conf = &ipv6_ext_push_data->conf; 10169 return ret; 10170 } 10171 10172 static int 10173 parse_vc_action_ipv6_ext_push_index(struct context *ctx, const struct token *token, 10174 const char *str, unsigned int len, void *buf, 10175 unsigned int size) 10176 { 10177 struct action_ipv6_ext_push_data *action_ipv6_ext_push_data; 10178 struct rte_flow_action *action; 10179 const struct arg *arg; 10180 struct buffer *out = buf; 10181 int ret; 10182 uint16_t idx; 10183 10184 RTE_SET_USED(token); 10185 RTE_SET_USED(buf); 10186 RTE_SET_USED(size); 10187 arg = ARGS_ENTRY_ARB_BOUNDED 10188 (offsetof(struct action_ipv6_ext_push_data, idx), 10189 sizeof(((struct action_ipv6_ext_push_data *)0)->idx), 10190 0, IPV6_EXT_PUSH_CONFS_MAX_NUM - 1); 10191 if (push_args(ctx, arg)) 10192 return -1; 10193 ret = parse_int(ctx, token, str, len, NULL, 0); 10194 if (ret < 0) { 10195 pop_args(ctx); 10196 return -1; 10197 } 10198 if (!ctx->object) 10199 return len; 10200 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10201 action_ipv6_ext_push_data = ctx->object; 10202 idx = action_ipv6_ext_push_data->idx; 10203 action_ipv6_ext_push_data->conf.type = ipv6_ext_push_confs[idx].type; 10204 action_ipv6_ext_push_data->conf.size = ipv6_ext_push_confs[idx].size; 10205 action_ipv6_ext_push_data->conf.data = ipv6_ext_push_confs[idx].data; 10206 action->conf = &action_ipv6_ext_push_data->conf; 10207 return len; 10208 } 10209 10210 static int 10211 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 10212 const char *str, unsigned int len, void *buf, 10213 unsigned int size) 10214 { 10215 int ret; 10216 10217 ret = parse_vc(ctx, token, str, len, buf, size); 10218 if (ret < 0) 10219 return ret; 10220 ret = rte_flow_dynf_metadata_register(); 10221 if (ret < 0) 10222 return -1; 10223 return len; 10224 } 10225 10226 static int 10227 parse_vc_action_sample(struct context *ctx, const struct token *token, 10228 const char *str, unsigned int len, void *buf, 10229 unsigned int size) 10230 { 10231 struct buffer *out = buf; 10232 struct rte_flow_action *action; 10233 struct action_sample_data *action_sample_data = NULL; 10234 static struct rte_flow_action end_action = { 10235 RTE_FLOW_ACTION_TYPE_END, 0 10236 }; 10237 int ret; 10238 10239 ret = parse_vc(ctx, token, str, len, buf, size); 10240 if (ret < 0) 10241 return ret; 10242 /* Nothing else to do if there is no buffer. */ 10243 if (!out) 10244 return ret; 10245 if (!out->args.vc.actions_n) 10246 return -1; 10247 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10248 /* Point to selected object. */ 10249 ctx->object = out->args.vc.data; 10250 ctx->objmask = NULL; 10251 /* Copy the headers to the buffer. */ 10252 action_sample_data = ctx->object; 10253 action_sample_data->conf.actions = &end_action; 10254 action->conf = &action_sample_data->conf; 10255 return ret; 10256 } 10257 10258 static int 10259 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 10260 const char *str, unsigned int len, void *buf, 10261 unsigned int size) 10262 { 10263 struct action_sample_data *action_sample_data; 10264 struct rte_flow_action *action; 10265 const struct arg *arg; 10266 struct buffer *out = buf; 10267 int ret; 10268 uint16_t idx; 10269 10270 RTE_SET_USED(token); 10271 RTE_SET_USED(buf); 10272 RTE_SET_USED(size); 10273 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 10274 return -1; 10275 arg = ARGS_ENTRY_ARB_BOUNDED 10276 (offsetof(struct action_sample_data, idx), 10277 sizeof(((struct action_sample_data *)0)->idx), 10278 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 10279 if (push_args(ctx, arg)) 10280 return -1; 10281 ret = parse_int(ctx, token, str, len, NULL, 0); 10282 if (ret < 0) { 10283 pop_args(ctx); 10284 return -1; 10285 } 10286 if (!ctx->object) 10287 return len; 10288 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 10289 action_sample_data = ctx->object; 10290 idx = action_sample_data->idx; 10291 action_sample_data->conf.actions = raw_sample_confs[idx].data; 10292 action->conf = &action_sample_data->conf; 10293 return len; 10294 } 10295 10296 /** Parse operation for modify_field command. */ 10297 static int 10298 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 10299 const char *str, unsigned int len, void *buf, 10300 unsigned int size) 10301 { 10302 struct rte_flow_action_modify_field *action_modify_field; 10303 unsigned int i; 10304 10305 (void)token; 10306 (void)buf; 10307 (void)size; 10308 if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) 10309 return -1; 10310 for (i = 0; modify_field_ops[i]; ++i) 10311 if (!strcmp_partial(modify_field_ops[i], str, len)) 10312 break; 10313 if (!modify_field_ops[i]) 10314 return -1; 10315 if (!ctx->object) 10316 return len; 10317 action_modify_field = ctx->object; 10318 action_modify_field->operation = (enum rte_flow_modify_op)i; 10319 return len; 10320 } 10321 10322 /** Parse id for modify_field command. */ 10323 static int 10324 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 10325 const char *str, unsigned int len, void *buf, 10326 unsigned int size) 10327 { 10328 struct rte_flow_action_modify_field *action_modify_field; 10329 unsigned int i; 10330 10331 (void)token; 10332 (void)buf; 10333 (void)size; 10334 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 10335 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 10336 return -1; 10337 for (i = 0; flow_field_ids[i]; ++i) 10338 if (!strcmp_partial(flow_field_ids[i], str, len)) 10339 break; 10340 if (!flow_field_ids[i]) 10341 return -1; 10342 if (!ctx->object) 10343 return len; 10344 action_modify_field = ctx->object; 10345 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 10346 action_modify_field->dst.field = (enum rte_flow_field_id)i; 10347 else 10348 action_modify_field->src.field = (enum rte_flow_field_id)i; 10349 return len; 10350 } 10351 10352 /** Parse level for modify_field command. */ 10353 static int 10354 parse_vc_modify_field_level(struct context *ctx, const struct token *token, 10355 const char *str, unsigned int len, void *buf, 10356 unsigned int size) 10357 { 10358 struct rte_flow_action_modify_field *action; 10359 struct flex_item *fp = NULL; 10360 uint32_t val; 10361 struct buffer *out = buf; 10362 char *end; 10363 10364 (void)token; 10365 (void)size; 10366 if (ctx->curr != ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10367 ctx->curr != ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) 10368 return -1; 10369 if (!ctx->object) 10370 return len; 10371 action = ctx->object; 10372 errno = 0; 10373 val = strtoumax(str, &end, 0); 10374 if (errno || (size_t)(end - str) != len) 10375 return -1; 10376 /* No need to validate action template mask value */ 10377 if (out->args.vc.masks) { 10378 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) 10379 action->dst.level = val; 10380 else 10381 action->src.level = val; 10382 return len; 10383 } 10384 if ((ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE && 10385 action->dst.field == RTE_FLOW_FIELD_FLEX_ITEM) || 10386 (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE && 10387 action->src.field == RTE_FLOW_FIELD_FLEX_ITEM)) { 10388 if (val >= FLEX_MAX_PARSERS_NUM) { 10389 printf("Bad flex item handle\n"); 10390 return -1; 10391 } 10392 fp = flex_items[ctx->port][val]; 10393 if (!fp) { 10394 printf("Bad flex item handle\n"); 10395 return -1; 10396 } 10397 } 10398 if (ctx->curr == ACTION_MODIFY_FIELD_DST_LEVEL_VALUE) { 10399 if (action->dst.field != RTE_FLOW_FIELD_FLEX_ITEM) 10400 action->dst.level = val; 10401 else 10402 action->dst.flex_handle = fp->flex_handle; 10403 } else if (ctx->curr == ACTION_MODIFY_FIELD_SRC_LEVEL_VALUE) { 10404 if (action->src.field != RTE_FLOW_FIELD_FLEX_ITEM) 10405 action->src.level = val; 10406 else 10407 action->src.flex_handle = fp->flex_handle; 10408 } 10409 return len; 10410 } 10411 10412 /** Parse the conntrack update, not a rte_flow_action. */ 10413 static int 10414 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 10415 const char *str, unsigned int len, void *buf, 10416 unsigned int size) 10417 { 10418 struct buffer *out = buf; 10419 struct rte_flow_modify_conntrack *ct_modify = NULL; 10420 10421 (void)size; 10422 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 10423 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 10424 return -1; 10425 /* Token name must match. */ 10426 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10427 return -1; 10428 /* Nothing else to do if there is no buffer. */ 10429 if (!out) 10430 return len; 10431 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 10432 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 10433 ct_modify->new_ct.is_original_dir = 10434 conntrack_context.is_original_dir; 10435 ct_modify->direction = 1; 10436 } else { 10437 uint32_t old_dir; 10438 10439 old_dir = ct_modify->new_ct.is_original_dir; 10440 memcpy(&ct_modify->new_ct, &conntrack_context, 10441 sizeof(conntrack_context)); 10442 ct_modify->new_ct.is_original_dir = old_dir; 10443 ct_modify->state = 1; 10444 } 10445 return len; 10446 } 10447 10448 /** Parse tokens for destroy command. */ 10449 static int 10450 parse_destroy(struct context *ctx, const struct token *token, 10451 const char *str, unsigned int len, 10452 void *buf, unsigned int size) 10453 { 10454 struct buffer *out = buf; 10455 10456 /* Token name must match. */ 10457 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10458 return -1; 10459 /* Nothing else to do if there is no buffer. */ 10460 if (!out) 10461 return len; 10462 if (!out->command) { 10463 if (ctx->curr != DESTROY) 10464 return -1; 10465 if (sizeof(*out) > size) 10466 return -1; 10467 out->command = ctx->curr; 10468 ctx->objdata = 0; 10469 ctx->object = out; 10470 ctx->objmask = NULL; 10471 out->args.destroy.rule = 10472 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10473 sizeof(double)); 10474 return len; 10475 } 10476 if (ctx->curr == DESTROY_IS_USER_ID) { 10477 out->args.destroy.is_user_id = true; 10478 return len; 10479 } 10480 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 10481 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 10482 return -1; 10483 ctx->objdata = 0; 10484 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 10485 ctx->objmask = NULL; 10486 return len; 10487 } 10488 10489 /** Parse tokens for flush command. */ 10490 static int 10491 parse_flush(struct context *ctx, const struct token *token, 10492 const char *str, unsigned int len, 10493 void *buf, unsigned int size) 10494 { 10495 struct buffer *out = buf; 10496 10497 /* Token name must match. */ 10498 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10499 return -1; 10500 /* Nothing else to do if there is no buffer. */ 10501 if (!out) 10502 return len; 10503 if (!out->command) { 10504 if (ctx->curr != FLUSH) 10505 return -1; 10506 if (sizeof(*out) > size) 10507 return -1; 10508 out->command = ctx->curr; 10509 ctx->objdata = 0; 10510 ctx->object = out; 10511 ctx->objmask = NULL; 10512 } 10513 return len; 10514 } 10515 10516 /** Parse tokens for dump command. */ 10517 static int 10518 parse_dump(struct context *ctx, const struct token *token, 10519 const char *str, unsigned int len, 10520 void *buf, unsigned int size) 10521 { 10522 struct buffer *out = buf; 10523 10524 /* Token name must match. */ 10525 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10526 return -1; 10527 /* Nothing else to do if there is no buffer. */ 10528 if (!out) 10529 return len; 10530 if (!out->command) { 10531 if (ctx->curr != DUMP) 10532 return -1; 10533 if (sizeof(*out) > size) 10534 return -1; 10535 out->command = ctx->curr; 10536 ctx->objdata = 0; 10537 ctx->object = out; 10538 ctx->objmask = NULL; 10539 return len; 10540 } 10541 switch (ctx->curr) { 10542 case DUMP_ALL: 10543 case DUMP_ONE: 10544 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 10545 out->command = ctx->curr; 10546 ctx->objdata = 0; 10547 ctx->object = out; 10548 ctx->objmask = NULL; 10549 return len; 10550 case DUMP_IS_USER_ID: 10551 out->args.dump.is_user_id = true; 10552 return len; 10553 default: 10554 return -1; 10555 } 10556 } 10557 10558 /** Parse tokens for query command. */ 10559 static int 10560 parse_query(struct context *ctx, const struct token *token, 10561 const char *str, unsigned int len, 10562 void *buf, unsigned int size) 10563 { 10564 struct buffer *out = buf; 10565 10566 /* Token name must match. */ 10567 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10568 return -1; 10569 /* Nothing else to do if there is no buffer. */ 10570 if (!out) 10571 return len; 10572 if (!out->command) { 10573 if (ctx->curr != QUERY) 10574 return -1; 10575 if (sizeof(*out) > size) 10576 return -1; 10577 out->command = ctx->curr; 10578 ctx->objdata = 0; 10579 ctx->object = out; 10580 ctx->objmask = NULL; 10581 } 10582 if (ctx->curr == QUERY_IS_USER_ID) { 10583 out->args.query.is_user_id = true; 10584 return len; 10585 } 10586 return len; 10587 } 10588 10589 /** Parse action names. */ 10590 static int 10591 parse_action(struct context *ctx, const struct token *token, 10592 const char *str, unsigned int len, 10593 void *buf, unsigned int size) 10594 { 10595 struct buffer *out = buf; 10596 const struct arg *arg = pop_args(ctx); 10597 unsigned int i; 10598 10599 (void)size; 10600 /* Argument is expected. */ 10601 if (!arg) 10602 return -1; 10603 /* Parse action name. */ 10604 for (i = 0; next_action[i]; ++i) { 10605 const struct parse_action_priv *priv; 10606 10607 token = &token_list[next_action[i]]; 10608 if (strcmp_partial(token->name, str, len)) 10609 continue; 10610 priv = token->priv; 10611 if (!priv) 10612 goto error; 10613 if (out) 10614 memcpy((uint8_t *)ctx->object + arg->offset, 10615 &priv->type, 10616 arg->size); 10617 return len; 10618 } 10619 error: 10620 push_args(ctx, arg); 10621 return -1; 10622 } 10623 10624 /** Parse tokens for list command. */ 10625 static int 10626 parse_list(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 != LIST) 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 out->args.list.group = 10648 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10649 sizeof(double)); 10650 return len; 10651 } 10652 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 10653 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 10654 return -1; 10655 ctx->objdata = 0; 10656 ctx->object = out->args.list.group + out->args.list.group_n++; 10657 ctx->objmask = NULL; 10658 return len; 10659 } 10660 10661 /** Parse tokens for list all aged flows command. */ 10662 static int 10663 parse_aged(struct context *ctx, const struct token *token, 10664 const char *str, unsigned int len, 10665 void *buf, unsigned int size) 10666 { 10667 struct buffer *out = buf; 10668 10669 /* Token name must match. */ 10670 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10671 return -1; 10672 /* Nothing else to do if there is no buffer. */ 10673 if (!out) 10674 return len; 10675 if (!out->command || out->command == QUEUE) { 10676 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 10677 return -1; 10678 if (sizeof(*out) > size) 10679 return -1; 10680 out->command = ctx->curr; 10681 ctx->objdata = 0; 10682 ctx->object = out; 10683 ctx->objmask = NULL; 10684 } 10685 if (ctx->curr == AGED_DESTROY) 10686 out->args.aged.destroy = 1; 10687 return len; 10688 } 10689 10690 /** Parse tokens for isolate command. */ 10691 static int 10692 parse_isolate(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 != ISOLATE) 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 } 10714 return len; 10715 } 10716 10717 /** Parse tokens for info/configure command. */ 10718 static int 10719 parse_configure(struct context *ctx, const struct token *token, 10720 const char *str, unsigned int len, 10721 void *buf, unsigned int size) 10722 { 10723 struct buffer *out = buf; 10724 10725 /* Token name must match. */ 10726 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10727 return -1; 10728 /* Nothing else to do if there is no buffer. */ 10729 if (!out) 10730 return len; 10731 if (!out->command) { 10732 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 10733 return -1; 10734 if (sizeof(*out) > size) 10735 return -1; 10736 out->command = ctx->curr; 10737 ctx->objdata = 0; 10738 ctx->object = out; 10739 ctx->objmask = NULL; 10740 } 10741 return len; 10742 } 10743 10744 /** Parse tokens for template create command. */ 10745 static int 10746 parse_template(struct context *ctx, const struct token *token, 10747 const char *str, unsigned int len, 10748 void *buf, unsigned int size) 10749 { 10750 struct buffer *out = buf; 10751 10752 /* Token name must match. */ 10753 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10754 return -1; 10755 /* Nothing else to do if there is no buffer. */ 10756 if (!out) 10757 return len; 10758 if (!out->command) { 10759 if (ctx->curr != PATTERN_TEMPLATE && 10760 ctx->curr != ACTIONS_TEMPLATE) 10761 return -1; 10762 if (sizeof(*out) > size) 10763 return -1; 10764 out->command = ctx->curr; 10765 ctx->objdata = 0; 10766 ctx->object = out; 10767 ctx->objmask = NULL; 10768 out->args.vc.data = (uint8_t *)out + size; 10769 return len; 10770 } 10771 switch (ctx->curr) { 10772 case PATTERN_TEMPLATE_CREATE: 10773 out->args.vc.pattern = 10774 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10775 sizeof(double)); 10776 out->args.vc.pat_templ_id = UINT32_MAX; 10777 out->command = ctx->curr; 10778 ctx->objdata = 0; 10779 ctx->object = out; 10780 ctx->objmask = NULL; 10781 return len; 10782 case PATTERN_TEMPLATE_EGRESS: 10783 out->args.vc.attr.egress = 1; 10784 return len; 10785 case PATTERN_TEMPLATE_INGRESS: 10786 out->args.vc.attr.ingress = 1; 10787 return len; 10788 case PATTERN_TEMPLATE_TRANSFER: 10789 out->args.vc.attr.transfer = 1; 10790 return len; 10791 case ACTIONS_TEMPLATE_CREATE: 10792 out->args.vc.act_templ_id = UINT32_MAX; 10793 out->command = ctx->curr; 10794 ctx->objdata = 0; 10795 ctx->object = out; 10796 ctx->objmask = NULL; 10797 return len; 10798 case ACTIONS_TEMPLATE_SPEC: 10799 out->args.vc.actions = 10800 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10801 sizeof(double)); 10802 ctx->object = out->args.vc.actions; 10803 ctx->objmask = NULL; 10804 return len; 10805 case ACTIONS_TEMPLATE_MASK: 10806 out->args.vc.masks = 10807 (void *)RTE_ALIGN_CEIL((uintptr_t) 10808 (out->args.vc.actions + 10809 out->args.vc.actions_n), 10810 sizeof(double)); 10811 ctx->object = out->args.vc.masks; 10812 ctx->objmask = NULL; 10813 return len; 10814 case ACTIONS_TEMPLATE_EGRESS: 10815 out->args.vc.attr.egress = 1; 10816 return len; 10817 case ACTIONS_TEMPLATE_INGRESS: 10818 out->args.vc.attr.ingress = 1; 10819 return len; 10820 case ACTIONS_TEMPLATE_TRANSFER: 10821 out->args.vc.attr.transfer = 1; 10822 return len; 10823 default: 10824 return -1; 10825 } 10826 } 10827 10828 /** Parse tokens for template destroy command. */ 10829 static int 10830 parse_template_destroy(struct context *ctx, const struct token *token, 10831 const char *str, unsigned int len, 10832 void *buf, unsigned int size) 10833 { 10834 struct buffer *out = buf; 10835 uint32_t *template_id; 10836 10837 /* Token name must match. */ 10838 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10839 return -1; 10840 /* Nothing else to do if there is no buffer. */ 10841 if (!out) 10842 return len; 10843 if (!out->command || 10844 out->command == PATTERN_TEMPLATE || 10845 out->command == ACTIONS_TEMPLATE) { 10846 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 10847 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 10848 return -1; 10849 if (sizeof(*out) > size) 10850 return -1; 10851 out->command = ctx->curr; 10852 ctx->objdata = 0; 10853 ctx->object = out; 10854 ctx->objmask = NULL; 10855 out->args.templ_destroy.template_id = 10856 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10857 sizeof(double)); 10858 return len; 10859 } 10860 template_id = out->args.templ_destroy.template_id 10861 + out->args.templ_destroy.template_id_n++; 10862 if ((uint8_t *)template_id > (uint8_t *)out + size) 10863 return -1; 10864 ctx->objdata = 0; 10865 ctx->object = template_id; 10866 ctx->objmask = NULL; 10867 return len; 10868 } 10869 10870 /** Parse tokens for table create command. */ 10871 static int 10872 parse_table(struct context *ctx, const struct token *token, 10873 const char *str, unsigned int len, 10874 void *buf, unsigned int size) 10875 { 10876 struct buffer *out = buf; 10877 uint32_t *template_id; 10878 10879 /* Token name must match. */ 10880 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10881 return -1; 10882 /* Nothing else to do if there is no buffer. */ 10883 if (!out) 10884 return len; 10885 if (!out->command) { 10886 if (ctx->curr != TABLE) 10887 return -1; 10888 if (sizeof(*out) > size) 10889 return -1; 10890 out->command = ctx->curr; 10891 ctx->objdata = 0; 10892 ctx->object = out; 10893 ctx->objmask = NULL; 10894 return len; 10895 } 10896 switch (ctx->curr) { 10897 case TABLE_CREATE: 10898 case TABLE_RESIZE: 10899 out->command = ctx->curr; 10900 ctx->objdata = 0; 10901 ctx->object = out; 10902 ctx->objmask = NULL; 10903 out->args.table.id = UINT32_MAX; 10904 return len; 10905 case TABLE_PATTERN_TEMPLATE: 10906 out->args.table.pat_templ_id = 10907 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10908 sizeof(double)); 10909 template_id = out->args.table.pat_templ_id 10910 + out->args.table.pat_templ_id_n++; 10911 if ((uint8_t *)template_id > (uint8_t *)out + size) 10912 return -1; 10913 ctx->objdata = 0; 10914 ctx->object = template_id; 10915 ctx->objmask = NULL; 10916 return len; 10917 case TABLE_ACTIONS_TEMPLATE: 10918 out->args.table.act_templ_id = 10919 (void *)RTE_ALIGN_CEIL((uintptr_t) 10920 (out->args.table.pat_templ_id + 10921 out->args.table.pat_templ_id_n), 10922 sizeof(double)); 10923 template_id = out->args.table.act_templ_id 10924 + out->args.table.act_templ_id_n++; 10925 if ((uint8_t *)template_id > (uint8_t *)out + size) 10926 return -1; 10927 ctx->objdata = 0; 10928 ctx->object = template_id; 10929 ctx->objmask = NULL; 10930 return len; 10931 case TABLE_INGRESS: 10932 out->args.table.attr.flow_attr.ingress = 1; 10933 return len; 10934 case TABLE_EGRESS: 10935 out->args.table.attr.flow_attr.egress = 1; 10936 return len; 10937 case TABLE_TRANSFER: 10938 out->args.table.attr.flow_attr.transfer = 1; 10939 return len; 10940 case TABLE_TRANSFER_WIRE_ORIG: 10941 if (!out->args.table.attr.flow_attr.transfer) 10942 return -1; 10943 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_WIRE_ORIG; 10944 return len; 10945 case TABLE_TRANSFER_VPORT_ORIG: 10946 if (!out->args.table.attr.flow_attr.transfer) 10947 return -1; 10948 out->args.table.attr.specialize |= RTE_FLOW_TABLE_SPECIALIZE_TRANSFER_VPORT_ORIG; 10949 return len; 10950 case TABLE_RESIZABLE: 10951 out->args.table.attr.specialize |= 10952 RTE_FLOW_TABLE_SPECIALIZE_RESIZABLE; 10953 return len; 10954 case TABLE_RULES_NUMBER: 10955 ctx->objdata = 0; 10956 ctx->object = out; 10957 ctx->objmask = NULL; 10958 return len; 10959 case TABLE_RESIZE_ID: 10960 case TABLE_RESIZE_RULES_NUMBER: 10961 return len; 10962 default: 10963 return -1; 10964 } 10965 } 10966 10967 /** Parse tokens for table destroy command. */ 10968 static int 10969 parse_table_destroy(struct context *ctx, const struct token *token, 10970 const char *str, unsigned int len, 10971 void *buf, unsigned int size) 10972 { 10973 struct buffer *out = buf; 10974 uint32_t *table_id; 10975 10976 /* Token name must match. */ 10977 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 10978 return -1; 10979 /* Nothing else to do if there is no buffer. */ 10980 if (!out) 10981 return len; 10982 if (!out->command || out->command == TABLE) { 10983 if (ctx->curr != TABLE_DESTROY && 10984 ctx->curr != TABLE_RESIZE_COMPLETE) 10985 return -1; 10986 if (sizeof(*out) > size) 10987 return -1; 10988 out->command = ctx->curr; 10989 ctx->objdata = 0; 10990 ctx->object = out; 10991 ctx->objmask = NULL; 10992 out->args.table_destroy.table_id = 10993 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 10994 sizeof(double)); 10995 return len; 10996 } 10997 table_id = out->args.table_destroy.table_id 10998 + out->args.table_destroy.table_id_n++; 10999 if ((uint8_t *)table_id > (uint8_t *)out + size) 11000 return -1; 11001 ctx->objdata = 0; 11002 ctx->object = table_id; 11003 ctx->objmask = NULL; 11004 return len; 11005 } 11006 11007 /** Parse tokens for queue create commands. */ 11008 static int 11009 parse_qo(struct context *ctx, const struct token *token, 11010 const char *str, unsigned int len, 11011 void *buf, unsigned int size) 11012 { 11013 struct buffer *out = buf; 11014 11015 /* Token name must match. */ 11016 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11017 return -1; 11018 /* Nothing else to do if there is no buffer. */ 11019 if (!out) 11020 return len; 11021 if (!out->command) { 11022 if (ctx->curr != QUEUE) 11023 return -1; 11024 if (sizeof(*out) > size) 11025 return -1; 11026 out->command = ctx->curr; 11027 ctx->objdata = 0; 11028 ctx->object = out; 11029 ctx->objmask = NULL; 11030 out->args.vc.data = (uint8_t *)out + size; 11031 return len; 11032 } 11033 switch (ctx->curr) { 11034 case QUEUE_CREATE: 11035 case QUEUE_UPDATE: 11036 out->command = ctx->curr; 11037 ctx->objdata = 0; 11038 ctx->object = out; 11039 ctx->objmask = NULL; 11040 out->args.vc.rule_id = UINT32_MAX; 11041 return len; 11042 case QUEUE_TEMPLATE_TABLE: 11043 case QUEUE_PATTERN_TEMPLATE: 11044 case QUEUE_ACTIONS_TEMPLATE: 11045 case QUEUE_CREATE_POSTPONE: 11046 case QUEUE_RULE_ID: 11047 case QUEUE_UPDATE_ID: 11048 return len; 11049 case ITEM_PATTERN: 11050 out->args.vc.pattern = 11051 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11052 sizeof(double)); 11053 ctx->object = out->args.vc.pattern; 11054 ctx->objmask = NULL; 11055 return len; 11056 case ACTIONS: 11057 out->args.vc.actions = 11058 (void *)RTE_ALIGN_CEIL((uintptr_t) 11059 (out->args.vc.pattern + 11060 out->args.vc.pattern_n), 11061 sizeof(double)); 11062 ctx->object = out->args.vc.actions; 11063 ctx->objmask = NULL; 11064 return len; 11065 default: 11066 return -1; 11067 } 11068 } 11069 11070 /** Parse tokens for queue destroy command. */ 11071 static int 11072 parse_qo_destroy(struct context *ctx, const struct token *token, 11073 const char *str, unsigned int len, 11074 void *buf, unsigned int size) 11075 { 11076 struct buffer *out = buf; 11077 uint64_t *flow_id; 11078 11079 /* Token name must match. */ 11080 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11081 return -1; 11082 /* Nothing else to do if there is no buffer. */ 11083 if (!out) 11084 return len; 11085 if (!out->command || out->command == QUEUE) { 11086 if (ctx->curr != QUEUE_DESTROY && 11087 ctx->curr != QUEUE_FLOW_UPDATE_RESIZED) 11088 return -1; 11089 if (sizeof(*out) > size) 11090 return -1; 11091 out->command = ctx->curr; 11092 ctx->objdata = 0; 11093 ctx->object = out; 11094 ctx->objmask = NULL; 11095 out->args.destroy.rule = 11096 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11097 sizeof(double)); 11098 return len; 11099 } 11100 switch (ctx->curr) { 11101 case QUEUE_DESTROY_ID: 11102 flow_id = out->args.destroy.rule 11103 + out->args.destroy.rule_n++; 11104 if ((uint8_t *)flow_id > (uint8_t *)out + size) 11105 return -1; 11106 ctx->objdata = 0; 11107 ctx->object = flow_id; 11108 ctx->objmask = NULL; 11109 return len; 11110 case QUEUE_DESTROY_POSTPONE: 11111 return len; 11112 default: 11113 return -1; 11114 } 11115 } 11116 11117 /** Parse tokens for push queue command. */ 11118 static int 11119 parse_push(struct context *ctx, const struct token *token, 11120 const char *str, unsigned int len, 11121 void *buf, unsigned int size) 11122 { 11123 struct buffer *out = buf; 11124 11125 /* Token name must match. */ 11126 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11127 return -1; 11128 /* Nothing else to do if there is no buffer. */ 11129 if (!out) 11130 return len; 11131 if (!out->command) { 11132 if (ctx->curr != PUSH) 11133 return -1; 11134 if (sizeof(*out) > size) 11135 return -1; 11136 out->command = ctx->curr; 11137 ctx->objdata = 0; 11138 ctx->object = out; 11139 ctx->objmask = NULL; 11140 out->args.vc.data = (uint8_t *)out + size; 11141 } 11142 return len; 11143 } 11144 11145 /** Parse tokens for pull command. */ 11146 static int 11147 parse_pull(struct context *ctx, const struct token *token, 11148 const char *str, unsigned int len, 11149 void *buf, unsigned int size) 11150 { 11151 struct buffer *out = buf; 11152 11153 /* Token name must match. */ 11154 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11155 return -1; 11156 /* Nothing else to do if there is no buffer. */ 11157 if (!out) 11158 return len; 11159 if (!out->command) { 11160 if (ctx->curr != PULL) 11161 return -1; 11162 if (sizeof(*out) > size) 11163 return -1; 11164 out->command = ctx->curr; 11165 ctx->objdata = 0; 11166 ctx->object = out; 11167 ctx->objmask = NULL; 11168 out->args.vc.data = (uint8_t *)out + size; 11169 } 11170 return len; 11171 } 11172 11173 /** Parse tokens for hash calculation commands. */ 11174 static int 11175 parse_hash(struct context *ctx, const struct token *token, 11176 const char *str, unsigned int len, 11177 void *buf, unsigned int size) 11178 { 11179 struct buffer *out = buf; 11180 11181 /* Token name must match. */ 11182 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11183 return -1; 11184 /* Nothing else to do if there is no buffer. */ 11185 if (!out) 11186 return len; 11187 if (!out->command) { 11188 if (ctx->curr != HASH) 11189 return -1; 11190 if (sizeof(*out) > size) 11191 return -1; 11192 out->command = ctx->curr; 11193 ctx->objdata = 0; 11194 ctx->object = out; 11195 ctx->objmask = NULL; 11196 out->args.vc.data = (uint8_t *)out + size; 11197 return len; 11198 } 11199 switch (ctx->curr) { 11200 case HASH_CALC_TABLE: 11201 case HASH_CALC_PATTERN_INDEX: 11202 return len; 11203 case ITEM_PATTERN: 11204 out->args.vc.pattern = 11205 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11206 sizeof(double)); 11207 ctx->object = out->args.vc.pattern; 11208 ctx->objmask = NULL; 11209 return len; 11210 case HASH_CALC_ENCAP: 11211 out->args.vc.encap_hash = 1; 11212 return len; 11213 case ENCAP_HASH_FIELD_SRC_PORT: 11214 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_SRC_PORT; 11215 return len; 11216 case ENCAP_HASH_FIELD_GRE_FLOW_ID: 11217 out->args.vc.field = RTE_FLOW_ENCAP_HASH_FIELD_NVGRE_FLOW_ID; 11218 return len; 11219 default: 11220 return -1; 11221 } 11222 } 11223 11224 static int 11225 parse_group(struct context *ctx, const struct token *token, 11226 const char *str, unsigned int len, 11227 void *buf, unsigned int size) 11228 { 11229 struct buffer *out = buf; 11230 11231 /* Token name must match. */ 11232 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11233 return -1; 11234 /* Nothing else to do if there is no buffer. */ 11235 if (!out) 11236 return len; 11237 if (!out->command) { 11238 if (ctx->curr != FLOW_GROUP) 11239 return -1; 11240 if (sizeof(*out) > size) 11241 return -1; 11242 out->command = ctx->curr; 11243 ctx->objdata = 0; 11244 ctx->object = out; 11245 ctx->objmask = NULL; 11246 out->args.vc.data = (uint8_t *)out + size; 11247 return len; 11248 } 11249 switch (ctx->curr) { 11250 case GROUP_INGRESS: 11251 out->args.vc.attr.ingress = 1; 11252 return len; 11253 case GROUP_EGRESS: 11254 out->args.vc.attr.egress = 1; 11255 return len; 11256 case GROUP_TRANSFER: 11257 out->args.vc.attr.transfer = 1; 11258 return len; 11259 case GROUP_SET_MISS_ACTIONS: 11260 out->command = ctx->curr; 11261 ctx->objdata = 0; 11262 ctx->object = out; 11263 ctx->objmask = NULL; 11264 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 11265 sizeof(double)); 11266 return len; 11267 default: 11268 return -1; 11269 } 11270 } 11271 11272 static int 11273 parse_flex(struct context *ctx, const struct token *token, 11274 const char *str, unsigned int len, 11275 void *buf, unsigned int size) 11276 { 11277 struct buffer *out = buf; 11278 11279 /* Token name must match. */ 11280 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11281 return -1; 11282 /* Nothing else to do if there is no buffer. */ 11283 if (!out) 11284 return len; 11285 if (out->command == ZERO) { 11286 if (ctx->curr != FLEX) 11287 return -1; 11288 if (sizeof(*out) > size) 11289 return -1; 11290 out->command = ctx->curr; 11291 ctx->objdata = 0; 11292 ctx->object = out; 11293 ctx->objmask = NULL; 11294 } else { 11295 switch (ctx->curr) { 11296 default: 11297 break; 11298 case FLEX_ITEM_INIT: 11299 case FLEX_ITEM_CREATE: 11300 case FLEX_ITEM_DESTROY: 11301 out->command = ctx->curr; 11302 break; 11303 } 11304 } 11305 11306 return len; 11307 } 11308 11309 static int 11310 parse_tunnel(struct context *ctx, const struct token *token, 11311 const char *str, unsigned int len, 11312 void *buf, unsigned int size) 11313 { 11314 struct buffer *out = buf; 11315 11316 /* Token name must match. */ 11317 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 11318 return -1; 11319 /* Nothing else to do if there is no buffer. */ 11320 if (!out) 11321 return len; 11322 if (!out->command) { 11323 if (ctx->curr != TUNNEL) 11324 return -1; 11325 if (sizeof(*out) > size) 11326 return -1; 11327 out->command = ctx->curr; 11328 ctx->objdata = 0; 11329 ctx->object = out; 11330 ctx->objmask = NULL; 11331 } else { 11332 switch (ctx->curr) { 11333 default: 11334 break; 11335 case TUNNEL_CREATE: 11336 case TUNNEL_DESTROY: 11337 case TUNNEL_LIST: 11338 out->command = ctx->curr; 11339 break; 11340 case TUNNEL_CREATE_TYPE: 11341 case TUNNEL_DESTROY_ID: 11342 ctx->object = &out->args.vc.tunnel_ops; 11343 break; 11344 } 11345 } 11346 11347 return len; 11348 } 11349 11350 /** 11351 * Parse signed/unsigned integers 8 to 64-bit long. 11352 * 11353 * Last argument (ctx->args) is retrieved to determine integer type and 11354 * storage location. 11355 */ 11356 static int 11357 parse_int(struct context *ctx, const struct token *token, 11358 const char *str, unsigned int len, 11359 void *buf, unsigned int size) 11360 { 11361 const struct arg *arg = pop_args(ctx); 11362 uintmax_t u; 11363 char *end; 11364 11365 (void)token; 11366 /* Argument is expected. */ 11367 if (!arg) 11368 return -1; 11369 errno = 0; 11370 u = arg->sign ? 11371 (uintmax_t)strtoimax(str, &end, 0) : 11372 strtoumax(str, &end, 0); 11373 if (errno || (size_t)(end - str) != len) 11374 goto error; 11375 if (arg->bounded && 11376 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 11377 (intmax_t)u > (intmax_t)arg->max)) || 11378 (!arg->sign && (u < arg->min || u > arg->max)))) 11379 goto error; 11380 if (!ctx->object) 11381 return len; 11382 if (arg->mask) { 11383 if (!arg_entry_bf_fill(ctx->object, u, arg) || 11384 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 11385 goto error; 11386 return len; 11387 } 11388 buf = (uint8_t *)ctx->object + arg->offset; 11389 size = arg->size; 11390 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 11391 return -1; 11392 objmask: 11393 switch (size) { 11394 case sizeof(uint8_t): 11395 *(uint8_t *)buf = u; 11396 break; 11397 case sizeof(uint16_t): 11398 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 11399 break; 11400 case sizeof(uint8_t [3]): 11401 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 11402 if (!arg->hton) { 11403 ((uint8_t *)buf)[0] = u; 11404 ((uint8_t *)buf)[1] = u >> 8; 11405 ((uint8_t *)buf)[2] = u >> 16; 11406 break; 11407 } 11408 #endif 11409 ((uint8_t *)buf)[0] = u >> 16; 11410 ((uint8_t *)buf)[1] = u >> 8; 11411 ((uint8_t *)buf)[2] = u; 11412 break; 11413 case sizeof(uint32_t): 11414 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 11415 break; 11416 case sizeof(uint64_t): 11417 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 11418 break; 11419 default: 11420 goto error; 11421 } 11422 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 11423 u = -1; 11424 buf = (uint8_t *)ctx->objmask + arg->offset; 11425 goto objmask; 11426 } 11427 return len; 11428 error: 11429 push_args(ctx, arg); 11430 return -1; 11431 } 11432 11433 /** 11434 * Parse a string. 11435 * 11436 * Three arguments (ctx->args) are retrieved from the stack to store data, 11437 * its actual length and address (in that order). 11438 */ 11439 static int 11440 parse_string(struct context *ctx, const struct token *token, 11441 const char *str, unsigned int len, 11442 void *buf, unsigned int size) 11443 { 11444 const struct arg *arg_data = pop_args(ctx); 11445 const struct arg *arg_len = pop_args(ctx); 11446 const struct arg *arg_addr = pop_args(ctx); 11447 char tmp[16]; /* Ought to be enough. */ 11448 int ret; 11449 11450 /* Arguments are expected. */ 11451 if (!arg_data) 11452 return -1; 11453 if (!arg_len) { 11454 push_args(ctx, arg_data); 11455 return -1; 11456 } 11457 if (!arg_addr) { 11458 push_args(ctx, arg_len); 11459 push_args(ctx, arg_data); 11460 return -1; 11461 } 11462 size = arg_data->size; 11463 /* Bit-mask fill is not supported. */ 11464 if (arg_data->mask || size < len) 11465 goto error; 11466 if (!ctx->object) 11467 return len; 11468 /* Let parse_int() fill length information first. */ 11469 ret = snprintf(tmp, sizeof(tmp), "%u", len); 11470 if (ret < 0) 11471 goto error; 11472 push_args(ctx, arg_len); 11473 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11474 if (ret < 0) { 11475 pop_args(ctx); 11476 goto error; 11477 } 11478 buf = (uint8_t *)ctx->object + arg_data->offset; 11479 /* Output buffer is not necessarily NUL-terminated. */ 11480 memcpy(buf, str, len); 11481 memset((uint8_t *)buf + len, 0x00, size - len); 11482 if (ctx->objmask) 11483 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11484 /* Save address if requested. */ 11485 if (arg_addr->size) { 11486 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11487 (void *[]){ 11488 (uint8_t *)ctx->object + arg_data->offset 11489 }, 11490 arg_addr->size); 11491 if (ctx->objmask) 11492 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11493 (void *[]){ 11494 (uint8_t *)ctx->objmask + arg_data->offset 11495 }, 11496 arg_addr->size); 11497 } 11498 return len; 11499 error: 11500 push_args(ctx, arg_addr); 11501 push_args(ctx, arg_len); 11502 push_args(ctx, arg_data); 11503 return -1; 11504 } 11505 11506 static int 11507 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 11508 { 11509 const uint8_t *head = dst; 11510 uint32_t left; 11511 11512 if (*size == 0) 11513 return -1; 11514 11515 left = *size; 11516 11517 /* Convert chars to bytes */ 11518 while (left) { 11519 char tmp[3], *end = tmp; 11520 uint32_t read_lim = left & 1 ? 1 : 2; 11521 11522 snprintf(tmp, read_lim + 1, "%s", src); 11523 *dst = strtoul(tmp, &end, 16); 11524 if (*end) { 11525 *dst = 0; 11526 *size = (uint32_t)(dst - head); 11527 return -1; 11528 } 11529 left -= read_lim; 11530 src += read_lim; 11531 dst++; 11532 } 11533 *dst = 0; 11534 *size = (uint32_t)(dst - head); 11535 return 0; 11536 } 11537 11538 static int 11539 parse_hex(struct context *ctx, const struct token *token, 11540 const char *str, unsigned int len, 11541 void *buf, unsigned int size) 11542 { 11543 const struct arg *arg_data = pop_args(ctx); 11544 const struct arg *arg_len = pop_args(ctx); 11545 const struct arg *arg_addr = pop_args(ctx); 11546 char tmp[16]; /* Ought to be enough. */ 11547 int ret; 11548 unsigned int hexlen = len; 11549 unsigned int length = 256; 11550 uint8_t hex_tmp[length]; 11551 11552 /* Arguments are expected. */ 11553 if (!arg_data) 11554 return -1; 11555 if (!arg_len) { 11556 push_args(ctx, arg_data); 11557 return -1; 11558 } 11559 if (!arg_addr) { 11560 push_args(ctx, arg_len); 11561 push_args(ctx, arg_data); 11562 return -1; 11563 } 11564 size = arg_data->size; 11565 /* Bit-mask fill is not supported. */ 11566 if (arg_data->mask) 11567 goto error; 11568 if (!ctx->object) 11569 return len; 11570 11571 /* translate bytes string to array. */ 11572 if (str[0] == '0' && ((str[1] == 'x') || 11573 (str[1] == 'X'))) { 11574 str += 2; 11575 hexlen -= 2; 11576 } 11577 if (hexlen > length) 11578 goto error; 11579 ret = parse_hex_string(str, hex_tmp, &hexlen); 11580 if (ret < 0) 11581 goto error; 11582 /* Check the converted binary fits into data buffer. */ 11583 if (hexlen > size) 11584 goto error; 11585 /* Let parse_int() fill length information first. */ 11586 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 11587 if (ret < 0) 11588 goto error; 11589 /* Save length if requested. */ 11590 if (arg_len->size) { 11591 push_args(ctx, arg_len); 11592 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 11593 if (ret < 0) { 11594 pop_args(ctx); 11595 goto error; 11596 } 11597 } 11598 buf = (uint8_t *)ctx->object + arg_data->offset; 11599 /* Output buffer is not necessarily NUL-terminated. */ 11600 memcpy(buf, hex_tmp, hexlen); 11601 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 11602 if (ctx->objmask) 11603 memset((uint8_t *)ctx->objmask + arg_data->offset, 11604 0xff, hexlen); 11605 /* Save address if requested. */ 11606 if (arg_addr->size) { 11607 memcpy((uint8_t *)ctx->object + arg_addr->offset, 11608 (void *[]){ 11609 (uint8_t *)ctx->object + arg_data->offset 11610 }, 11611 arg_addr->size); 11612 if (ctx->objmask) 11613 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 11614 (void *[]){ 11615 (uint8_t *)ctx->objmask + arg_data->offset 11616 }, 11617 arg_addr->size); 11618 } 11619 return len; 11620 error: 11621 push_args(ctx, arg_addr); 11622 push_args(ctx, arg_len); 11623 push_args(ctx, arg_data); 11624 return -1; 11625 11626 } 11627 11628 /** 11629 * Parse a zero-ended string. 11630 */ 11631 static int 11632 parse_string0(struct context *ctx, const struct token *token __rte_unused, 11633 const char *str, unsigned int len, 11634 void *buf, unsigned int size) 11635 { 11636 const struct arg *arg_data = pop_args(ctx); 11637 11638 /* Arguments are expected. */ 11639 if (!arg_data) 11640 return -1; 11641 size = arg_data->size; 11642 /* Bit-mask fill is not supported. */ 11643 if (arg_data->mask || size < len + 1) 11644 goto error; 11645 if (!ctx->object) 11646 return len; 11647 buf = (uint8_t *)ctx->object + arg_data->offset; 11648 strncpy(buf, str, len); 11649 if (ctx->objmask) 11650 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 11651 return len; 11652 error: 11653 push_args(ctx, arg_data); 11654 return -1; 11655 } 11656 11657 /** 11658 * Parse a MAC address. 11659 * 11660 * Last argument (ctx->args) is retrieved to determine storage size and 11661 * location. 11662 */ 11663 static int 11664 parse_mac_addr(struct context *ctx, const struct token *token, 11665 const char *str, unsigned int len, 11666 void *buf, unsigned int size) 11667 { 11668 const struct arg *arg = pop_args(ctx); 11669 struct rte_ether_addr tmp; 11670 int ret; 11671 11672 (void)token; 11673 /* Argument is expected. */ 11674 if (!arg) 11675 return -1; 11676 size = arg->size; 11677 /* Bit-mask fill is not supported. */ 11678 if (arg->mask || size != sizeof(tmp)) 11679 goto error; 11680 /* Only network endian is supported. */ 11681 if (!arg->hton) 11682 goto error; 11683 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 11684 if (ret < 0 || (unsigned int)ret != len) 11685 goto error; 11686 if (!ctx->object) 11687 return len; 11688 buf = (uint8_t *)ctx->object + arg->offset; 11689 memcpy(buf, &tmp, size); 11690 if (ctx->objmask) 11691 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11692 return len; 11693 error: 11694 push_args(ctx, arg); 11695 return -1; 11696 } 11697 11698 /** 11699 * Parse an IPv4 address. 11700 * 11701 * Last argument (ctx->args) is retrieved to determine storage size and 11702 * location. 11703 */ 11704 static int 11705 parse_ipv4_addr(struct context *ctx, const struct token *token, 11706 const char *str, unsigned int len, 11707 void *buf, unsigned int size) 11708 { 11709 const struct arg *arg = pop_args(ctx); 11710 char str2[len + 1]; 11711 struct in_addr tmp; 11712 int ret; 11713 11714 /* Argument is expected. */ 11715 if (!arg) 11716 return -1; 11717 size = arg->size; 11718 /* Bit-mask fill is not supported. */ 11719 if (arg->mask || size != sizeof(tmp)) 11720 goto error; 11721 /* Only network endian is supported. */ 11722 if (!arg->hton) 11723 goto error; 11724 memcpy(str2, str, len); 11725 str2[len] = '\0'; 11726 ret = inet_pton(AF_INET, str2, &tmp); 11727 if (ret != 1) { 11728 /* Attempt integer parsing. */ 11729 push_args(ctx, arg); 11730 return parse_int(ctx, token, str, len, buf, size); 11731 } 11732 if (!ctx->object) 11733 return len; 11734 buf = (uint8_t *)ctx->object + arg->offset; 11735 memcpy(buf, &tmp, size); 11736 if (ctx->objmask) 11737 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11738 return len; 11739 error: 11740 push_args(ctx, arg); 11741 return -1; 11742 } 11743 11744 /** 11745 * Parse an IPv6 address. 11746 * 11747 * Last argument (ctx->args) is retrieved to determine storage size and 11748 * location. 11749 */ 11750 static int 11751 parse_ipv6_addr(struct context *ctx, const struct token *token, 11752 const char *str, unsigned int len, 11753 void *buf, unsigned int size) 11754 { 11755 const struct arg *arg = pop_args(ctx); 11756 char str2[len + 1]; 11757 struct in6_addr tmp; 11758 int ret; 11759 11760 (void)token; 11761 /* Argument is expected. */ 11762 if (!arg) 11763 return -1; 11764 size = arg->size; 11765 /* Bit-mask fill is not supported. */ 11766 if (arg->mask || size != sizeof(tmp)) 11767 goto error; 11768 /* Only network endian is supported. */ 11769 if (!arg->hton) 11770 goto error; 11771 memcpy(str2, str, len); 11772 str2[len] = '\0'; 11773 ret = inet_pton(AF_INET6, str2, &tmp); 11774 if (ret != 1) 11775 goto error; 11776 if (!ctx->object) 11777 return len; 11778 buf = (uint8_t *)ctx->object + arg->offset; 11779 memcpy(buf, &tmp, size); 11780 if (ctx->objmask) 11781 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 11782 return len; 11783 error: 11784 push_args(ctx, arg); 11785 return -1; 11786 } 11787 11788 /** Boolean values (even indices stand for false). */ 11789 static const char *const boolean_name[] = { 11790 "0", "1", 11791 "false", "true", 11792 "no", "yes", 11793 "N", "Y", 11794 "off", "on", 11795 NULL, 11796 }; 11797 11798 /** 11799 * Parse a boolean value. 11800 * 11801 * Last argument (ctx->args) is retrieved to determine storage size and 11802 * location. 11803 */ 11804 static int 11805 parse_boolean(struct context *ctx, const struct token *token, 11806 const char *str, unsigned int len, 11807 void *buf, unsigned int size) 11808 { 11809 const struct arg *arg = pop_args(ctx); 11810 unsigned int i; 11811 int ret; 11812 11813 /* Argument is expected. */ 11814 if (!arg) 11815 return -1; 11816 for (i = 0; boolean_name[i]; ++i) 11817 if (!strcmp_partial(boolean_name[i], str, len)) 11818 break; 11819 /* Process token as integer. */ 11820 if (boolean_name[i]) 11821 str = i & 1 ? "1" : "0"; 11822 push_args(ctx, arg); 11823 ret = parse_int(ctx, token, str, strlen(str), buf, size); 11824 return ret > 0 ? (int)len : ret; 11825 } 11826 11827 /** Parse port and update context. */ 11828 static int 11829 parse_port(struct context *ctx, const struct token *token, 11830 const char *str, unsigned int len, 11831 void *buf, unsigned int size) 11832 { 11833 struct buffer *out = &(struct buffer){ .port = 0 }; 11834 int ret; 11835 11836 if (buf) 11837 out = buf; 11838 else { 11839 ctx->objdata = 0; 11840 ctx->object = out; 11841 ctx->objmask = NULL; 11842 size = sizeof(*out); 11843 } 11844 ret = parse_int(ctx, token, str, len, out, size); 11845 if (ret >= 0) 11846 ctx->port = out->port; 11847 if (!buf) 11848 ctx->object = NULL; 11849 return ret; 11850 } 11851 11852 /** Parse tokens for shared indirect actions. */ 11853 static int 11854 parse_ia_port(struct context *ctx, const struct token *token, 11855 const char *str, unsigned int len, 11856 void *buf, unsigned int size) 11857 { 11858 struct rte_flow_action *action = ctx->object; 11859 uint32_t id; 11860 int ret; 11861 11862 (void)buf; 11863 (void)size; 11864 ctx->objdata = 0; 11865 ctx->object = &id; 11866 ctx->objmask = NULL; 11867 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11868 ctx->object = action; 11869 if (ret != (int)len) 11870 return ret; 11871 /* set indirect action */ 11872 if (action) 11873 action->conf = (void *)(uintptr_t)id; 11874 return ret; 11875 } 11876 11877 static int 11878 parse_ia_id2ptr(struct context *ctx, const struct token *token, 11879 const char *str, unsigned int len, 11880 void *buf, unsigned int size) 11881 { 11882 struct rte_flow_action *action = ctx->object; 11883 uint32_t id; 11884 int ret; 11885 11886 (void)buf; 11887 (void)size; 11888 ctx->objdata = 0; 11889 ctx->object = &id; 11890 ctx->objmask = NULL; 11891 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11892 ctx->object = action; 11893 if (ret != (int)len) 11894 return ret; 11895 /* set indirect action */ 11896 if (action) { 11897 portid_t port_id = ctx->port; 11898 if (ctx->prev == INDIRECT_ACTION_PORT) 11899 port_id = (portid_t)(uintptr_t)action->conf; 11900 action->conf = port_action_handle_get_by_id(port_id, id); 11901 ret = (action->conf) ? ret : -1; 11902 } 11903 return ret; 11904 } 11905 11906 static int 11907 parse_indlst_id2ptr(struct context *ctx, const struct token *token, 11908 const char *str, unsigned int len, 11909 __rte_unused void *buf, __rte_unused unsigned int size) 11910 { 11911 struct rte_flow_action *action = ctx->object; 11912 struct rte_flow_action_indirect_list *action_conf; 11913 const struct indlst_conf *indlst_conf; 11914 uint32_t id; 11915 int ret; 11916 11917 ctx->objdata = 0; 11918 ctx->object = &id; 11919 ctx->objmask = NULL; 11920 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11921 ctx->object = action; 11922 if (ret != (int)len) 11923 return ret; 11924 11925 /* set handle and conf */ 11926 if (action) { 11927 action_conf = (void *)(uintptr_t)action->conf; 11928 action_conf->conf = NULL; 11929 switch (ctx->curr) { 11930 case INDIRECT_LIST_ACTION_ID2PTR_HANDLE: 11931 action_conf->handle = (typeof(action_conf->handle)) 11932 port_action_handle_get_by_id(ctx->port, id); 11933 if (!action_conf->handle) { 11934 printf("no indirect list handle for id %u\n", id); 11935 return -1; 11936 } 11937 break; 11938 case INDIRECT_LIST_ACTION_ID2PTR_CONF: 11939 indlst_conf = indirect_action_list_conf_get(id); 11940 if (!indlst_conf) 11941 return -1; 11942 action_conf->conf = (const void **)indlst_conf->conf; 11943 break; 11944 default: 11945 break; 11946 } 11947 } 11948 return ret; 11949 } 11950 11951 static int 11952 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 11953 const char *str, unsigned int len, 11954 void *buf, unsigned int size) 11955 { 11956 struct rte_flow_action *action = ctx->object; 11957 struct rte_flow_action_meter_mark *meter; 11958 struct rte_flow_meter_profile *profile = NULL; 11959 uint32_t id = 0; 11960 int ret; 11961 11962 (void)buf; 11963 (void)size; 11964 ctx->objdata = 0; 11965 ctx->object = &id; 11966 ctx->objmask = NULL; 11967 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11968 ctx->object = action; 11969 if (ret != (int)len) 11970 return ret; 11971 /* set meter profile */ 11972 if (action) { 11973 meter = (struct rte_flow_action_meter_mark *) 11974 (uintptr_t)(action->conf); 11975 profile = port_meter_profile_get_by_id(ctx->port, id); 11976 meter->profile = profile; 11977 ret = (profile) ? ret : -1; 11978 } 11979 return ret; 11980 } 11981 11982 static int 11983 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 11984 const char *str, unsigned int len, 11985 void *buf, unsigned int size) 11986 { 11987 struct rte_flow_action *action = ctx->object; 11988 struct rte_flow_action_meter_mark *meter; 11989 struct rte_flow_meter_policy *policy = NULL; 11990 uint32_t id = 0; 11991 int ret; 11992 11993 (void)buf; 11994 (void)size; 11995 ctx->objdata = 0; 11996 ctx->object = &id; 11997 ctx->objmask = NULL; 11998 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 11999 ctx->object = action; 12000 if (ret != (int)len) 12001 return ret; 12002 /* set meter policy */ 12003 if (action) { 12004 meter = (struct rte_flow_action_meter_mark *) 12005 (uintptr_t)(action->conf); 12006 policy = port_meter_policy_get_by_id(ctx->port, id); 12007 meter->policy = policy; 12008 ret = (policy) ? ret : -1; 12009 } 12010 return ret; 12011 } 12012 12013 /** Parse set command, initialize output buffer for subsequent tokens. */ 12014 static int 12015 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 12016 const char *str, unsigned int len, 12017 void *buf, unsigned int size) 12018 { 12019 struct buffer *out = buf; 12020 12021 /* Token name must match. */ 12022 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12023 return -1; 12024 /* Nothing else to do if there is no buffer. */ 12025 if (!out) 12026 return len; 12027 /* Make sure buffer is large enough. */ 12028 if (size < sizeof(*out)) 12029 return -1; 12030 ctx->objdata = 0; 12031 ctx->objmask = NULL; 12032 ctx->object = out; 12033 if (!out->command) 12034 return -1; 12035 out->command = ctx->curr; 12036 /* For encap/decap we need is pattern */ 12037 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12038 sizeof(double)); 12039 return len; 12040 } 12041 12042 /** Parse set command, initialize output buffer for subsequent tokens. */ 12043 static int 12044 parse_set_sample_action(struct context *ctx, const struct token *token, 12045 const char *str, unsigned int len, 12046 void *buf, unsigned int size) 12047 { 12048 struct buffer *out = buf; 12049 12050 /* Token name must match. */ 12051 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12052 return -1; 12053 /* Nothing else to do if there is no buffer. */ 12054 if (!out) 12055 return len; 12056 /* Make sure buffer is large enough. */ 12057 if (size < sizeof(*out)) 12058 return -1; 12059 ctx->objdata = 0; 12060 ctx->objmask = NULL; 12061 ctx->object = out; 12062 if (!out->command) 12063 return -1; 12064 out->command = ctx->curr; 12065 /* For sampler we need is actions */ 12066 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12067 sizeof(double)); 12068 return len; 12069 } 12070 12071 /** Parse set command, initialize output buffer for subsequent tokens. */ 12072 static int 12073 parse_set_ipv6_ext_action(struct context *ctx, const struct token *token, 12074 const char *str, unsigned int len, 12075 void *buf, unsigned int size) 12076 { 12077 struct buffer *out = buf; 12078 12079 /* Token name must match. */ 12080 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12081 return -1; 12082 /* Nothing else to do if there is no buffer. */ 12083 if (!out) 12084 return len; 12085 /* Make sure buffer is large enough. */ 12086 if (size < sizeof(*out)) 12087 return -1; 12088 ctx->objdata = 0; 12089 ctx->objmask = NULL; 12090 ctx->object = out; 12091 if (!out->command) 12092 return -1; 12093 out->command = ctx->curr; 12094 /* For ipv6_ext_push/remove we need is pattern */ 12095 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12096 sizeof(double)); 12097 return len; 12098 } 12099 12100 /** 12101 * Parse set raw_encap/raw_decap command, 12102 * initialize output buffer for subsequent tokens. 12103 */ 12104 static int 12105 parse_set_init(struct context *ctx, const struct token *token, 12106 const char *str, unsigned int len, 12107 void *buf, unsigned int size) 12108 { 12109 struct buffer *out = buf; 12110 12111 /* Token name must match. */ 12112 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 12113 return -1; 12114 /* Nothing else to do if there is no buffer. */ 12115 if (!out) 12116 return len; 12117 /* Make sure buffer is large enough. */ 12118 if (size < sizeof(*out)) 12119 return -1; 12120 /* Initialize buffer. */ 12121 memset(out, 0x00, sizeof(*out)); 12122 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 12123 ctx->objdata = 0; 12124 ctx->object = out; 12125 ctx->objmask = NULL; 12126 if (!out->command) { 12127 if (ctx->curr != SET) 12128 return -1; 12129 if (sizeof(*out) > size) 12130 return -1; 12131 out->command = ctx->curr; 12132 out->args.vc.data = (uint8_t *)out + size; 12133 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 12134 sizeof(double)); 12135 } 12136 return len; 12137 } 12138 12139 /* 12140 * Replace testpmd handles in a flex flow item with real values. 12141 */ 12142 static int 12143 parse_flex_handle(struct context *ctx, const struct token *token, 12144 const char *str, unsigned int len, 12145 void *buf, unsigned int size) 12146 { 12147 struct rte_flow_item_flex *spec, *mask; 12148 const struct rte_flow_item_flex *src_spec, *src_mask; 12149 const struct arg *arg = pop_args(ctx); 12150 uint32_t offset; 12151 uint16_t handle; 12152 int ret; 12153 12154 if (!arg) { 12155 printf("Bad environment\n"); 12156 return -1; 12157 } 12158 offset = arg->offset; 12159 push_args(ctx, arg); 12160 ret = parse_int(ctx, token, str, len, buf, size); 12161 if (ret <= 0 || !ctx->object) 12162 return ret; 12163 if (ctx->port >= RTE_MAX_ETHPORTS) { 12164 printf("Bad port\n"); 12165 return -1; 12166 } 12167 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 12168 const struct flex_item *fp; 12169 spec = ctx->object; 12170 handle = (uint16_t)(uintptr_t)spec->handle; 12171 if (handle >= FLEX_MAX_PARSERS_NUM) { 12172 printf("Bad flex item handle\n"); 12173 return -1; 12174 } 12175 fp = flex_items[ctx->port][handle]; 12176 if (!fp) { 12177 printf("Bad flex item handle\n"); 12178 return -1; 12179 } 12180 spec->handle = fp->flex_handle; 12181 mask = spec + 2; /* spec, last, mask */ 12182 mask->handle = fp->flex_handle; 12183 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 12184 handle = (uint16_t)(uintptr_t) 12185 ((struct rte_flow_item_flex *)ctx->object)->pattern; 12186 if (handle >= FLEX_MAX_PATTERNS_NUM) { 12187 printf("Bad pattern handle\n"); 12188 return -1; 12189 } 12190 src_spec = &flex_patterns[handle].spec; 12191 src_mask = &flex_patterns[handle].mask; 12192 spec = ctx->object; 12193 mask = spec + 2; /* spec, last, mask */ 12194 /* fill flow rule spec and mask parameters */ 12195 spec->length = src_spec->length; 12196 spec->pattern = src_spec->pattern; 12197 mask->length = src_mask->length; 12198 mask->pattern = src_mask->pattern; 12199 } else { 12200 printf("Bad arguments - unknown flex item offset\n"); 12201 return -1; 12202 } 12203 return ret; 12204 } 12205 12206 /** Parse Meter color name */ 12207 static int 12208 parse_meter_color(struct context *ctx, const struct token *token, 12209 const char *str, unsigned int len, void *buf, 12210 unsigned int size) 12211 { 12212 struct rte_flow_item_meter_color *meter_color; 12213 unsigned int i; 12214 12215 (void)token; 12216 (void)buf; 12217 (void)size; 12218 for (i = 0; meter_colors[i]; ++i) 12219 if (!strcmp_partial(meter_colors[i], str, len)) 12220 break; 12221 if (!meter_colors[i]) 12222 return -1; 12223 if (!ctx->object) 12224 return len; 12225 meter_color = ctx->object; 12226 meter_color->color = (enum rte_color)i; 12227 return len; 12228 } 12229 12230 /** Parse Insertion Table Type name */ 12231 static int 12232 parse_insertion_table_type(struct context *ctx, const struct token *token, 12233 const char *str, unsigned int len, void *buf, 12234 unsigned int size) 12235 { 12236 const struct arg *arg = pop_args(ctx); 12237 unsigned int i; 12238 char tmp[2]; 12239 int ret; 12240 12241 (void)size; 12242 /* Argument is expected. */ 12243 if (!arg) 12244 return -1; 12245 for (i = 0; table_insertion_types[i]; ++i) 12246 if (!strcmp_partial(table_insertion_types[i], str, len)) 12247 break; 12248 if (!table_insertion_types[i]) 12249 return -1; 12250 push_args(ctx, arg); 12251 snprintf(tmp, sizeof(tmp), "%u", i); 12252 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12253 return ret > 0 ? (int)len : ret; 12254 } 12255 12256 /** Parse Hash Calculation Table Type name */ 12257 static int 12258 parse_hash_table_type(struct context *ctx, const struct token *token, 12259 const char *str, unsigned int len, void *buf, 12260 unsigned int size) 12261 { 12262 const struct arg *arg = pop_args(ctx); 12263 unsigned int i; 12264 char tmp[2]; 12265 int ret; 12266 12267 (void)size; 12268 /* Argument is expected. */ 12269 if (!arg) 12270 return -1; 12271 for (i = 0; table_hash_funcs[i]; ++i) 12272 if (!strcmp_partial(table_hash_funcs[i], str, len)) 12273 break; 12274 if (!table_hash_funcs[i]) 12275 return -1; 12276 push_args(ctx, arg); 12277 snprintf(tmp, sizeof(tmp), "%u", i); 12278 ret = parse_int(ctx, token, tmp, strlen(tmp), buf, sizeof(i)); 12279 return ret > 0 ? (int)len : ret; 12280 } 12281 12282 static int 12283 parse_name_to_index(struct context *ctx, const struct token *token, 12284 const char *str, unsigned int len, void *buf, 12285 unsigned int size, 12286 const char *const names[], size_t names_size, uint32_t *dst) 12287 { 12288 int ret; 12289 uint32_t i; 12290 12291 RTE_SET_USED(token); 12292 RTE_SET_USED(buf); 12293 RTE_SET_USED(size); 12294 if (!ctx->object) 12295 return len; 12296 for (i = 0; i < names_size; i++) { 12297 if (!names[i]) 12298 continue; 12299 ret = strcmp_partial(names[i], str, 12300 RTE_MIN(len, strlen(names[i]))); 12301 if (!ret) { 12302 *dst = i; 12303 return len; 12304 } 12305 } 12306 return -1; 12307 } 12308 12309 static const char *const quota_mode_names[] = { 12310 NULL, 12311 [RTE_FLOW_QUOTA_MODE_PACKET] = "packet", 12312 [RTE_FLOW_QUOTA_MODE_L2] = "l2", 12313 [RTE_FLOW_QUOTA_MODE_L3] = "l3" 12314 }; 12315 12316 static const char *const quota_state_names[] = { 12317 [RTE_FLOW_QUOTA_STATE_PASS] = "pass", 12318 [RTE_FLOW_QUOTA_STATE_BLOCK] = "block" 12319 }; 12320 12321 static const char *const quota_update_names[] = { 12322 [RTE_FLOW_UPDATE_QUOTA_SET] = "set", 12323 [RTE_FLOW_UPDATE_QUOTA_ADD] = "add" 12324 }; 12325 12326 static const char *const query_update_mode_names[] = { 12327 [RTE_FLOW_QU_QUERY_FIRST] = "query_first", 12328 [RTE_FLOW_QU_UPDATE_FIRST] = "update_first" 12329 }; 12330 12331 static int 12332 parse_quota_state_name(struct context *ctx, const struct token *token, 12333 const char *str, unsigned int len, void *buf, 12334 unsigned int size) 12335 { 12336 struct rte_flow_item_quota *quota = ctx->object; 12337 12338 return parse_name_to_index(ctx, token, str, len, buf, size, 12339 quota_state_names, 12340 RTE_DIM(quota_state_names), 12341 (uint32_t *)"a->state); 12342 } 12343 12344 static int 12345 parse_quota_mode_name(struct context *ctx, const struct token *token, 12346 const char *str, unsigned int len, void *buf, 12347 unsigned int size) 12348 { 12349 struct rte_flow_action_quota *quota = ctx->object; 12350 12351 return parse_name_to_index(ctx, token, str, len, buf, size, 12352 quota_mode_names, 12353 RTE_DIM(quota_mode_names), 12354 (uint32_t *)"a->mode); 12355 } 12356 12357 static int 12358 parse_quota_update_name(struct context *ctx, const struct token *token, 12359 const char *str, unsigned int len, void *buf, 12360 unsigned int size) 12361 { 12362 struct rte_flow_update_quota *update = ctx->object; 12363 12364 return parse_name_to_index(ctx, token, str, len, buf, size, 12365 quota_update_names, 12366 RTE_DIM(quota_update_names), 12367 (uint32_t *)&update->op); 12368 } 12369 12370 static int 12371 parse_qu_mode_name(struct context *ctx, const struct token *token, 12372 const char *str, unsigned int len, void *buf, 12373 unsigned int size) 12374 { 12375 struct buffer *out = ctx->object; 12376 12377 return parse_name_to_index(ctx, token, str, len, buf, size, 12378 query_update_mode_names, 12379 RTE_DIM(query_update_mode_names), 12380 (uint32_t *)&out->args.ia.qu_mode); 12381 } 12382 12383 /** No completion. */ 12384 static int 12385 comp_none(struct context *ctx, const struct token *token, 12386 unsigned int ent, char *buf, unsigned int size) 12387 { 12388 (void)ctx; 12389 (void)token; 12390 (void)ent; 12391 (void)buf; 12392 (void)size; 12393 return 0; 12394 } 12395 12396 /** Complete boolean values. */ 12397 static int 12398 comp_boolean(struct context *ctx, const struct token *token, 12399 unsigned int ent, char *buf, unsigned int size) 12400 { 12401 unsigned int i; 12402 12403 (void)ctx; 12404 (void)token; 12405 for (i = 0; boolean_name[i]; ++i) 12406 if (buf && i == ent) 12407 return strlcpy(buf, boolean_name[i], size); 12408 if (buf) 12409 return -1; 12410 return i; 12411 } 12412 12413 /** Complete action names. */ 12414 static int 12415 comp_action(struct context *ctx, const struct token *token, 12416 unsigned int ent, char *buf, unsigned int size) 12417 { 12418 unsigned int i; 12419 12420 (void)ctx; 12421 (void)token; 12422 for (i = 0; next_action[i]; ++i) 12423 if (buf && i == ent) 12424 return strlcpy(buf, token_list[next_action[i]].name, 12425 size); 12426 if (buf) 12427 return -1; 12428 return i; 12429 } 12430 12431 /** Complete available ports. */ 12432 static int 12433 comp_port(struct context *ctx, const struct token *token, 12434 unsigned int ent, char *buf, unsigned int size) 12435 { 12436 unsigned int i = 0; 12437 portid_t p; 12438 12439 (void)ctx; 12440 (void)token; 12441 RTE_ETH_FOREACH_DEV(p) { 12442 if (buf && i == ent) 12443 return snprintf(buf, size, "%u", p); 12444 ++i; 12445 } 12446 if (buf) 12447 return -1; 12448 return i; 12449 } 12450 12451 /** Complete available rule IDs. */ 12452 static int 12453 comp_rule_id(struct context *ctx, const struct token *token, 12454 unsigned int ent, char *buf, unsigned int size) 12455 { 12456 unsigned int i = 0; 12457 struct rte_port *port; 12458 struct port_flow *pf; 12459 12460 (void)token; 12461 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12462 ctx->port == (portid_t)RTE_PORT_ALL) 12463 return -1; 12464 port = &ports[ctx->port]; 12465 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 12466 if (buf && i == ent) 12467 return snprintf(buf, size, "%"PRIu64, pf->id); 12468 ++i; 12469 } 12470 if (buf) 12471 return -1; 12472 return i; 12473 } 12474 12475 /** Complete operation for compare match item. */ 12476 static int 12477 comp_set_compare_op(struct context *ctx, const struct token *token, 12478 unsigned int ent, char *buf, unsigned int size) 12479 { 12480 RTE_SET_USED(ctx); 12481 RTE_SET_USED(token); 12482 if (!buf) 12483 return RTE_DIM(compare_ops); 12484 if (ent < RTE_DIM(compare_ops) - 1) 12485 return strlcpy(buf, compare_ops[ent], size); 12486 return -1; 12487 } 12488 12489 /** Complete field id for compare match item. */ 12490 static int 12491 comp_set_compare_field_id(struct context *ctx, const struct token *token, 12492 unsigned int ent, char *buf, unsigned int size) 12493 { 12494 const char *name; 12495 12496 RTE_SET_USED(token); 12497 if (!buf) 12498 return RTE_DIM(flow_field_ids); 12499 if (ent >= RTE_DIM(flow_field_ids) - 1) 12500 return -1; 12501 name = flow_field_ids[ent]; 12502 if (ctx->curr == ITEM_COMPARE_FIELD_B_TYPE || 12503 (strcmp(name, "pointer") && strcmp(name, "value"))) 12504 return strlcpy(buf, name, size); 12505 return -1; 12506 } 12507 12508 /** Complete type field for RSS action. */ 12509 static int 12510 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 12511 unsigned int ent, char *buf, unsigned int size) 12512 { 12513 unsigned int i; 12514 12515 (void)ctx; 12516 (void)token; 12517 for (i = 0; rss_type_table[i].str; ++i) 12518 ; 12519 if (!buf) 12520 return i + 1; 12521 if (ent < i) 12522 return strlcpy(buf, rss_type_table[ent].str, size); 12523 if (ent == i) 12524 return snprintf(buf, size, "end"); 12525 return -1; 12526 } 12527 12528 /** Complete queue field for RSS action. */ 12529 static int 12530 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 12531 unsigned int ent, char *buf, unsigned int size) 12532 { 12533 (void)ctx; 12534 (void)token; 12535 if (!buf) 12536 return nb_rxq + 1; 12537 if (ent < nb_rxq) 12538 return snprintf(buf, size, "%u", ent); 12539 if (ent == nb_rxq) 12540 return snprintf(buf, size, "end"); 12541 return -1; 12542 } 12543 12544 /** Complete index number for set raw_encap/raw_decap commands. */ 12545 static int 12546 comp_set_raw_index(struct context *ctx, const struct token *token, 12547 unsigned int ent, char *buf, unsigned int size) 12548 { 12549 uint16_t idx = 0; 12550 uint16_t nb = 0; 12551 12552 RTE_SET_USED(ctx); 12553 RTE_SET_USED(token); 12554 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 12555 if (buf && idx == ent) 12556 return snprintf(buf, size, "%u", idx); 12557 ++nb; 12558 } 12559 return nb; 12560 } 12561 12562 /** Complete index number for set raw_ipv6_ext_push/ipv6_ext_remove commands. */ 12563 static int 12564 comp_set_ipv6_ext_index(struct context *ctx, const struct token *token, 12565 unsigned int ent, char *buf, unsigned int size) 12566 { 12567 uint16_t idx = 0; 12568 uint16_t nb = 0; 12569 12570 RTE_SET_USED(ctx); 12571 RTE_SET_USED(token); 12572 for (idx = 0; idx < IPV6_EXT_PUSH_CONFS_MAX_NUM; ++idx) { 12573 if (buf && idx == ent) 12574 return snprintf(buf, size, "%u", idx); 12575 ++nb; 12576 } 12577 return nb; 12578 } 12579 12580 /** Complete index number for set raw_encap/raw_decap commands. */ 12581 static int 12582 comp_set_sample_index(struct context *ctx, const struct token *token, 12583 unsigned int ent, char *buf, unsigned int size) 12584 { 12585 uint16_t idx = 0; 12586 uint16_t nb = 0; 12587 12588 RTE_SET_USED(ctx); 12589 RTE_SET_USED(token); 12590 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 12591 if (buf && idx == ent) 12592 return snprintf(buf, size, "%u", idx); 12593 ++nb; 12594 } 12595 return nb; 12596 } 12597 12598 /** Complete operation for modify_field command. */ 12599 static int 12600 comp_set_modify_field_op(struct context *ctx, const struct token *token, 12601 unsigned int ent, char *buf, unsigned int size) 12602 { 12603 RTE_SET_USED(ctx); 12604 RTE_SET_USED(token); 12605 if (!buf) 12606 return RTE_DIM(modify_field_ops); 12607 if (ent < RTE_DIM(modify_field_ops) - 1) 12608 return strlcpy(buf, modify_field_ops[ent], size); 12609 return -1; 12610 } 12611 12612 /** Complete field id for modify_field command. */ 12613 static int 12614 comp_set_modify_field_id(struct context *ctx, const struct token *token, 12615 unsigned int ent, char *buf, unsigned int size) 12616 { 12617 const char *name; 12618 12619 RTE_SET_USED(token); 12620 if (!buf) 12621 return RTE_DIM(flow_field_ids); 12622 if (ent >= RTE_DIM(flow_field_ids) - 1) 12623 return -1; 12624 name = flow_field_ids[ent]; 12625 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 12626 (strcmp(name, "pointer") && strcmp(name, "value"))) 12627 return strlcpy(buf, name, size); 12628 return -1; 12629 } 12630 12631 /** Complete available pattern template IDs. */ 12632 static int 12633 comp_pattern_template_id(struct context *ctx, const struct token *token, 12634 unsigned int ent, char *buf, unsigned int size) 12635 { 12636 unsigned int i = 0; 12637 struct rte_port *port; 12638 struct port_template *pt; 12639 12640 (void)token; 12641 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12642 ctx->port == (portid_t)RTE_PORT_ALL) 12643 return -1; 12644 port = &ports[ctx->port]; 12645 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 12646 if (buf && i == ent) 12647 return snprintf(buf, size, "%u", pt->id); 12648 ++i; 12649 } 12650 if (buf) 12651 return -1; 12652 return i; 12653 } 12654 12655 /** Complete available actions template IDs. */ 12656 static int 12657 comp_actions_template_id(struct context *ctx, const struct token *token, 12658 unsigned int ent, char *buf, unsigned int size) 12659 { 12660 unsigned int i = 0; 12661 struct rte_port *port; 12662 struct port_template *pt; 12663 12664 (void)token; 12665 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12666 ctx->port == (portid_t)RTE_PORT_ALL) 12667 return -1; 12668 port = &ports[ctx->port]; 12669 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 12670 if (buf && i == ent) 12671 return snprintf(buf, size, "%u", pt->id); 12672 ++i; 12673 } 12674 if (buf) 12675 return -1; 12676 return i; 12677 } 12678 12679 /** Complete available table IDs. */ 12680 static int 12681 comp_table_id(struct context *ctx, const struct token *token, 12682 unsigned int ent, char *buf, unsigned int size) 12683 { 12684 unsigned int i = 0; 12685 struct rte_port *port; 12686 struct port_table *pt; 12687 12688 (void)token; 12689 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12690 ctx->port == (portid_t)RTE_PORT_ALL) 12691 return -1; 12692 port = &ports[ctx->port]; 12693 for (pt = port->table_list; pt != NULL; pt = pt->next) { 12694 if (buf && i == ent) 12695 return snprintf(buf, size, "%u", pt->id); 12696 ++i; 12697 } 12698 if (buf) 12699 return -1; 12700 return i; 12701 } 12702 12703 /** Complete available queue IDs. */ 12704 static int 12705 comp_queue_id(struct context *ctx, const struct token *token, 12706 unsigned int ent, char *buf, unsigned int size) 12707 { 12708 unsigned int i = 0; 12709 struct rte_port *port; 12710 12711 (void)token; 12712 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 12713 ctx->port == (portid_t)RTE_PORT_ALL) 12714 return -1; 12715 port = &ports[ctx->port]; 12716 for (i = 0; i < port->queue_nb; i++) { 12717 if (buf && i == ent) 12718 return snprintf(buf, size, "%u", i); 12719 } 12720 if (buf) 12721 return -1; 12722 return i; 12723 } 12724 12725 static int 12726 comp_names_to_index(struct context *ctx, const struct token *token, 12727 unsigned int ent, char *buf, unsigned int size, 12728 const char *const names[], size_t names_size) 12729 { 12730 RTE_SET_USED(ctx); 12731 RTE_SET_USED(token); 12732 if (!buf) 12733 return names_size; 12734 if (names[ent] && ent < names_size) 12735 return rte_strscpy(buf, names[ent], size); 12736 return -1; 12737 12738 } 12739 12740 /** Complete available Meter colors. */ 12741 static int 12742 comp_meter_color(struct context *ctx, const struct token *token, 12743 unsigned int ent, char *buf, unsigned int size) 12744 { 12745 RTE_SET_USED(ctx); 12746 RTE_SET_USED(token); 12747 if (!buf) 12748 return RTE_DIM(meter_colors); 12749 if (ent < RTE_DIM(meter_colors) - 1) 12750 return strlcpy(buf, meter_colors[ent], size); 12751 return -1; 12752 } 12753 12754 /** Complete available Insertion Table types. */ 12755 static int 12756 comp_insertion_table_type(struct context *ctx, const struct token *token, 12757 unsigned int ent, char *buf, unsigned int size) 12758 { 12759 RTE_SET_USED(ctx); 12760 RTE_SET_USED(token); 12761 if (!buf) 12762 return RTE_DIM(table_insertion_types); 12763 if (ent < RTE_DIM(table_insertion_types) - 1) 12764 return rte_strscpy(buf, table_insertion_types[ent], size); 12765 return -1; 12766 } 12767 12768 /** Complete available Hash Calculation Table types. */ 12769 static int 12770 comp_hash_table_type(struct context *ctx, const struct token *token, 12771 unsigned int ent, char *buf, unsigned int size) 12772 { 12773 RTE_SET_USED(ctx); 12774 RTE_SET_USED(token); 12775 if (!buf) 12776 return RTE_DIM(table_hash_funcs); 12777 if (ent < RTE_DIM(table_hash_funcs) - 1) 12778 return rte_strscpy(buf, table_hash_funcs[ent], size); 12779 return -1; 12780 } 12781 12782 static int 12783 comp_quota_state_name(struct context *ctx, const struct token *token, 12784 unsigned int ent, char *buf, unsigned int size) 12785 { 12786 return comp_names_to_index(ctx, token, ent, buf, size, 12787 quota_state_names, 12788 RTE_DIM(quota_state_names)); 12789 } 12790 12791 static int 12792 comp_quota_mode_name(struct context *ctx, const struct token *token, 12793 unsigned int ent, char *buf, unsigned int size) 12794 { 12795 return comp_names_to_index(ctx, token, ent, buf, size, 12796 quota_mode_names, 12797 RTE_DIM(quota_mode_names)); 12798 } 12799 12800 static int 12801 comp_quota_update_name(struct context *ctx, const struct token *token, 12802 unsigned int ent, char *buf, unsigned int size) 12803 { 12804 return comp_names_to_index(ctx, token, ent, buf, size, 12805 quota_update_names, 12806 RTE_DIM(quota_update_names)); 12807 } 12808 12809 static int 12810 comp_qu_mode_name(struct context *ctx, const struct token *token, 12811 unsigned int ent, char *buf, unsigned int size) 12812 { 12813 return comp_names_to_index(ctx, token, ent, buf, size, 12814 query_update_mode_names, 12815 RTE_DIM(query_update_mode_names)); 12816 } 12817 12818 /** Internal context. */ 12819 static struct context cmd_flow_context; 12820 12821 /** Global parser instance (cmdline API). */ 12822 cmdline_parse_inst_t cmd_flow; 12823 cmdline_parse_inst_t cmd_set_raw; 12824 12825 /** Initialize context. */ 12826 static void 12827 cmd_flow_context_init(struct context *ctx) 12828 { 12829 /* A full memset() is not necessary. */ 12830 ctx->curr = ZERO; 12831 ctx->prev = ZERO; 12832 ctx->next_num = 0; 12833 ctx->args_num = 0; 12834 ctx->eol = 0; 12835 ctx->last = 0; 12836 ctx->port = 0; 12837 ctx->objdata = 0; 12838 ctx->object = NULL; 12839 ctx->objmask = NULL; 12840 } 12841 12842 /** Parse a token (cmdline API). */ 12843 static int 12844 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 12845 unsigned int size) 12846 { 12847 struct context *ctx = &cmd_flow_context; 12848 const struct token *token; 12849 const enum index *list; 12850 int len; 12851 int i; 12852 12853 (void)hdr; 12854 token = &token_list[ctx->curr]; 12855 /* Check argument length. */ 12856 ctx->eol = 0; 12857 ctx->last = 1; 12858 for (len = 0; src[len]; ++len) 12859 if (src[len] == '#' || isspace(src[len])) 12860 break; 12861 if (!len) 12862 return -1; 12863 /* Last argument and EOL detection. */ 12864 for (i = len; src[i]; ++i) 12865 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 12866 break; 12867 else if (!isspace(src[i])) { 12868 ctx->last = 0; 12869 break; 12870 } 12871 for (; src[i]; ++i) 12872 if (src[i] == '\r' || src[i] == '\n') { 12873 ctx->eol = 1; 12874 break; 12875 } 12876 /* Initialize context if necessary. */ 12877 if (!ctx->next_num) { 12878 if (!token->next) 12879 return 0; 12880 ctx->next[ctx->next_num++] = token->next[0]; 12881 } 12882 /* Process argument through candidates. */ 12883 ctx->prev = ctx->curr; 12884 list = ctx->next[ctx->next_num - 1]; 12885 for (i = 0; list[i]; ++i) { 12886 const struct token *next = &token_list[list[i]]; 12887 int tmp; 12888 12889 ctx->curr = list[i]; 12890 if (next->call) 12891 tmp = next->call(ctx, next, src, len, result, size); 12892 else 12893 tmp = parse_default(ctx, next, src, len, result, size); 12894 if (tmp == -1 || tmp != len) 12895 continue; 12896 token = next; 12897 break; 12898 } 12899 if (!list[i]) 12900 return -1; 12901 --ctx->next_num; 12902 /* Push subsequent tokens if any. */ 12903 if (token->next) 12904 for (i = 0; token->next[i]; ++i) { 12905 if (ctx->next_num == RTE_DIM(ctx->next)) 12906 return -1; 12907 ctx->next[ctx->next_num++] = token->next[i]; 12908 } 12909 /* Push arguments if any. */ 12910 if (token->args) 12911 for (i = 0; token->args[i]; ++i) { 12912 if (ctx->args_num == RTE_DIM(ctx->args)) 12913 return -1; 12914 ctx->args[ctx->args_num++] = token->args[i]; 12915 } 12916 return len; 12917 } 12918 12919 int 12920 flow_parse(const char *src, void *result, unsigned int size, 12921 struct rte_flow_attr **attr, 12922 struct rte_flow_item **pattern, struct rte_flow_action **actions) 12923 { 12924 int ret; 12925 struct context saved_flow_ctx = cmd_flow_context; 12926 12927 cmd_flow_context_init(&cmd_flow_context); 12928 do { 12929 ret = cmd_flow_parse(NULL, src, result, size); 12930 if (ret > 0) { 12931 src += ret; 12932 while (isspace(*src)) 12933 src++; 12934 } 12935 } while (ret > 0 && strlen(src)); 12936 cmd_flow_context = saved_flow_ctx; 12937 *attr = &((struct buffer *)result)->args.vc.attr; 12938 *pattern = ((struct buffer *)result)->args.vc.pattern; 12939 *actions = ((struct buffer *)result)->args.vc.actions; 12940 return (ret >= 0 && !strlen(src)) ? 0 : -1; 12941 } 12942 12943 /** Return number of completion entries (cmdline API). */ 12944 static int 12945 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 12946 { 12947 struct context *ctx = &cmd_flow_context; 12948 const struct token *token = &token_list[ctx->curr]; 12949 const enum index *list; 12950 int i; 12951 12952 (void)hdr; 12953 /* Count number of tokens in current list. */ 12954 if (ctx->next_num) 12955 list = ctx->next[ctx->next_num - 1]; 12956 else 12957 list = token->next[0]; 12958 for (i = 0; list[i]; ++i) 12959 ; 12960 if (!i) 12961 return 0; 12962 /* 12963 * If there is a single token, use its completion callback, otherwise 12964 * return the number of entries. 12965 */ 12966 token = &token_list[list[0]]; 12967 if (i == 1 && token->comp) { 12968 /* Save index for cmd_flow_get_help(). */ 12969 ctx->prev = list[0]; 12970 return token->comp(ctx, token, 0, NULL, 0); 12971 } 12972 return i; 12973 } 12974 12975 /** Return a completion entry (cmdline API). */ 12976 static int 12977 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 12978 char *dst, unsigned int size) 12979 { 12980 struct context *ctx = &cmd_flow_context; 12981 const struct token *token = &token_list[ctx->curr]; 12982 const enum index *list; 12983 int i; 12984 12985 (void)hdr; 12986 /* Count number of tokens in current list. */ 12987 if (ctx->next_num) 12988 list = ctx->next[ctx->next_num - 1]; 12989 else 12990 list = token->next[0]; 12991 for (i = 0; list[i]; ++i) 12992 ; 12993 if (!i) 12994 return -1; 12995 /* If there is a single token, use its completion callback. */ 12996 token = &token_list[list[0]]; 12997 if (i == 1 && token->comp) { 12998 /* Save index for cmd_flow_get_help(). */ 12999 ctx->prev = list[0]; 13000 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 13001 } 13002 /* Otherwise make sure the index is valid and use defaults. */ 13003 if (index >= i) 13004 return -1; 13005 token = &token_list[list[index]]; 13006 strlcpy(dst, token->name, size); 13007 /* Save index for cmd_flow_get_help(). */ 13008 ctx->prev = list[index]; 13009 return 0; 13010 } 13011 13012 /** Populate help strings for current token (cmdline API). */ 13013 static int 13014 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 13015 { 13016 struct context *ctx = &cmd_flow_context; 13017 const struct token *token = &token_list[ctx->prev]; 13018 13019 (void)hdr; 13020 if (!size) 13021 return -1; 13022 /* Set token type and update global help with details. */ 13023 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 13024 if (token->help) 13025 cmd_flow.help_str = token->help; 13026 else 13027 cmd_flow.help_str = token->name; 13028 return 0; 13029 } 13030 13031 /** Token definition template (cmdline API). */ 13032 static struct cmdline_token_hdr cmd_flow_token_hdr = { 13033 .ops = &(struct cmdline_token_ops){ 13034 .parse = cmd_flow_parse, 13035 .complete_get_nb = cmd_flow_complete_get_nb, 13036 .complete_get_elt = cmd_flow_complete_get_elt, 13037 .get_help = cmd_flow_get_help, 13038 }, 13039 .offset = 0, 13040 }; 13041 13042 /** Populate the next dynamic token. */ 13043 static void 13044 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 13045 cmdline_parse_token_hdr_t **hdr_inst) 13046 { 13047 struct context *ctx = &cmd_flow_context; 13048 13049 /* Always reinitialize context before requesting the first token. */ 13050 if (!(hdr_inst - cmd_flow.tokens)) 13051 cmd_flow_context_init(ctx); 13052 /* Return NULL when no more tokens are expected. */ 13053 if (!ctx->next_num && ctx->curr) { 13054 *hdr = NULL; 13055 return; 13056 } 13057 /* Determine if command should end here. */ 13058 if (ctx->eol && ctx->last && ctx->next_num) { 13059 const enum index *list = ctx->next[ctx->next_num - 1]; 13060 int i; 13061 13062 for (i = 0; list[i]; ++i) { 13063 if (list[i] != END) 13064 continue; 13065 *hdr = NULL; 13066 return; 13067 } 13068 } 13069 *hdr = &cmd_flow_token_hdr; 13070 } 13071 13072 static SLIST_HEAD(, indlst_conf) indlst_conf_head = 13073 SLIST_HEAD_INITIALIZER(); 13074 13075 static void 13076 indirect_action_flow_conf_create(const struct buffer *in) 13077 { 13078 int len, ret; 13079 uint32_t i; 13080 struct indlst_conf *indlst_conf = NULL; 13081 size_t base = RTE_ALIGN(sizeof(*indlst_conf), 8); 13082 struct rte_flow_action *src = in->args.vc.actions; 13083 13084 if (!in->args.vc.actions_n) 13085 goto end; 13086 len = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, NULL, 0, src, NULL); 13087 if (len <= 0) 13088 goto end; 13089 len = RTE_ALIGN(len, 16); 13090 13091 indlst_conf = calloc(1, base + len + 13092 in->args.vc.actions_n * sizeof(uintptr_t)); 13093 if (!indlst_conf) 13094 goto end; 13095 indlst_conf->id = in->args.vc.attr.group; 13096 indlst_conf->conf_num = in->args.vc.actions_n - 1; 13097 indlst_conf->actions = RTE_PTR_ADD(indlst_conf, base); 13098 ret = rte_flow_conv(RTE_FLOW_CONV_OP_ACTIONS, indlst_conf->actions, 13099 len, src, NULL); 13100 if (ret <= 0) { 13101 free(indlst_conf); 13102 indlst_conf = NULL; 13103 goto end; 13104 } 13105 indlst_conf->conf = RTE_PTR_ADD(indlst_conf, base + len); 13106 for (i = 0; i < indlst_conf->conf_num; i++) 13107 indlst_conf->conf[i] = indlst_conf->actions[i].conf; 13108 SLIST_INSERT_HEAD(&indlst_conf_head, indlst_conf, next); 13109 end: 13110 if (indlst_conf) 13111 printf("created indirect action list configuration %u\n", 13112 in->args.vc.attr.group); 13113 else 13114 printf("cannot create indirect action list configuration %u\n", 13115 in->args.vc.attr.group); 13116 } 13117 13118 static const struct indlst_conf * 13119 indirect_action_list_conf_get(uint32_t conf_id) 13120 { 13121 const struct indlst_conf *conf; 13122 13123 SLIST_FOREACH(conf, &indlst_conf_head, next) { 13124 if (conf->id == conf_id) 13125 return conf; 13126 } 13127 return NULL; 13128 } 13129 13130 /** Dispatch parsed buffer to function calls. */ 13131 static void 13132 cmd_flow_parsed(const struct buffer *in) 13133 { 13134 switch (in->command) { 13135 case INFO: 13136 port_flow_get_info(in->port); 13137 break; 13138 case CONFIGURE: 13139 port_flow_configure(in->port, 13140 &in->args.configure.port_attr, 13141 in->args.configure.nb_queue, 13142 &in->args.configure.queue_attr); 13143 break; 13144 case PATTERN_TEMPLATE_CREATE: 13145 port_flow_pattern_template_create(in->port, 13146 in->args.vc.pat_templ_id, 13147 &((const struct rte_flow_pattern_template_attr) { 13148 .relaxed_matching = in->args.vc.attr.reserved, 13149 .ingress = in->args.vc.attr.ingress, 13150 .egress = in->args.vc.attr.egress, 13151 .transfer = in->args.vc.attr.transfer, 13152 }), 13153 in->args.vc.pattern); 13154 break; 13155 case PATTERN_TEMPLATE_DESTROY: 13156 port_flow_pattern_template_destroy(in->port, 13157 in->args.templ_destroy.template_id_n, 13158 in->args.templ_destroy.template_id); 13159 break; 13160 case ACTIONS_TEMPLATE_CREATE: 13161 port_flow_actions_template_create(in->port, 13162 in->args.vc.act_templ_id, 13163 &((const struct rte_flow_actions_template_attr) { 13164 .ingress = in->args.vc.attr.ingress, 13165 .egress = in->args.vc.attr.egress, 13166 .transfer = in->args.vc.attr.transfer, 13167 }), 13168 in->args.vc.actions, 13169 in->args.vc.masks); 13170 break; 13171 case ACTIONS_TEMPLATE_DESTROY: 13172 port_flow_actions_template_destroy(in->port, 13173 in->args.templ_destroy.template_id_n, 13174 in->args.templ_destroy.template_id); 13175 break; 13176 case TABLE_CREATE: 13177 port_flow_template_table_create(in->port, in->args.table.id, 13178 &in->args.table.attr, in->args.table.pat_templ_id_n, 13179 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 13180 in->args.table.act_templ_id); 13181 break; 13182 case TABLE_DESTROY: 13183 port_flow_template_table_destroy(in->port, 13184 in->args.table_destroy.table_id_n, 13185 in->args.table_destroy.table_id); 13186 break; 13187 case TABLE_RESIZE_COMPLETE: 13188 port_flow_template_table_resize_complete 13189 (in->port, in->args.table_destroy.table_id[0]); 13190 break; 13191 case GROUP_SET_MISS_ACTIONS: 13192 port_queue_group_set_miss_actions(in->port, &in->args.vc.attr, 13193 in->args.vc.actions); 13194 break; 13195 case TABLE_RESIZE: 13196 port_flow_template_table_resize(in->port, in->args.table.id, 13197 in->args.table.attr.nb_flows); 13198 break; 13199 case QUEUE_CREATE: 13200 port_queue_flow_create(in->port, in->queue, in->postpone, 13201 in->args.vc.table_id, in->args.vc.rule_id, 13202 in->args.vc.pat_templ_id, in->args.vc.act_templ_id, 13203 in->args.vc.pattern, in->args.vc.actions); 13204 break; 13205 case QUEUE_DESTROY: 13206 port_queue_flow_destroy(in->port, in->queue, in->postpone, 13207 in->args.destroy.rule_n, 13208 in->args.destroy.rule); 13209 break; 13210 case QUEUE_FLOW_UPDATE_RESIZED: 13211 port_queue_flow_update_resized(in->port, in->queue, 13212 in->postpone, 13213 in->args.destroy.rule[0]); 13214 break; 13215 case QUEUE_UPDATE: 13216 port_queue_flow_update(in->port, in->queue, in->postpone, 13217 in->args.vc.rule_id, in->args.vc.act_templ_id, 13218 in->args.vc.actions); 13219 break; 13220 case PUSH: 13221 port_queue_flow_push(in->port, in->queue); 13222 break; 13223 case PULL: 13224 port_queue_flow_pull(in->port, in->queue); 13225 break; 13226 case HASH: 13227 if (!in->args.vc.encap_hash) 13228 port_flow_hash_calc(in->port, in->args.vc.table_id, 13229 in->args.vc.pat_templ_id, 13230 in->args.vc.pattern); 13231 else 13232 port_flow_hash_calc_encap(in->port, in->args.vc.field, 13233 in->args.vc.pattern); 13234 break; 13235 case QUEUE_AGED: 13236 port_queue_flow_aged(in->port, in->queue, 13237 in->args.aged.destroy); 13238 break; 13239 case QUEUE_INDIRECT_ACTION_CREATE: 13240 case QUEUE_INDIRECT_ACTION_LIST_CREATE: 13241 port_queue_action_handle_create( 13242 in->port, in->queue, in->postpone, 13243 in->args.vc.attr.group, 13244 in->command == QUEUE_INDIRECT_ACTION_LIST_CREATE, 13245 &((const struct rte_flow_indir_action_conf) { 13246 .ingress = in->args.vc.attr.ingress, 13247 .egress = in->args.vc.attr.egress, 13248 .transfer = in->args.vc.attr.transfer, 13249 }), 13250 in->args.vc.actions); 13251 break; 13252 case QUEUE_INDIRECT_ACTION_DESTROY: 13253 port_queue_action_handle_destroy(in->port, 13254 in->queue, in->postpone, 13255 in->args.ia_destroy.action_id_n, 13256 in->args.ia_destroy.action_id); 13257 break; 13258 case QUEUE_INDIRECT_ACTION_UPDATE: 13259 port_queue_action_handle_update(in->port, 13260 in->queue, in->postpone, 13261 in->args.vc.attr.group, 13262 in->args.vc.actions); 13263 break; 13264 case QUEUE_INDIRECT_ACTION_QUERY: 13265 port_queue_action_handle_query(in->port, 13266 in->queue, in->postpone, 13267 in->args.ia.action_id); 13268 break; 13269 case QUEUE_INDIRECT_ACTION_QUERY_UPDATE: 13270 port_queue_action_handle_query_update(in->port, in->queue, 13271 in->postpone, 13272 in->args.ia.action_id, 13273 in->args.ia.qu_mode, 13274 in->args.vc.actions); 13275 break; 13276 case INDIRECT_ACTION_CREATE: 13277 case INDIRECT_ACTION_LIST_CREATE: 13278 port_action_handle_create( 13279 in->port, in->args.vc.attr.group, 13280 in->command == INDIRECT_ACTION_LIST_CREATE, 13281 &((const struct rte_flow_indir_action_conf) { 13282 .ingress = in->args.vc.attr.ingress, 13283 .egress = in->args.vc.attr.egress, 13284 .transfer = in->args.vc.attr.transfer, 13285 }), 13286 in->args.vc.actions); 13287 break; 13288 case INDIRECT_ACTION_FLOW_CONF_CREATE: 13289 indirect_action_flow_conf_create(in); 13290 break; 13291 case INDIRECT_ACTION_DESTROY: 13292 port_action_handle_destroy(in->port, 13293 in->args.ia_destroy.action_id_n, 13294 in->args.ia_destroy.action_id); 13295 break; 13296 case INDIRECT_ACTION_UPDATE: 13297 port_action_handle_update(in->port, in->args.vc.attr.group, 13298 in->args.vc.actions); 13299 break; 13300 case INDIRECT_ACTION_QUERY: 13301 port_action_handle_query(in->port, in->args.ia.action_id); 13302 break; 13303 case INDIRECT_ACTION_QUERY_UPDATE: 13304 port_action_handle_query_update(in->port, 13305 in->args.ia.action_id, 13306 in->args.ia.qu_mode, 13307 in->args.vc.actions); 13308 break; 13309 case VALIDATE: 13310 port_flow_validate(in->port, &in->args.vc.attr, 13311 in->args.vc.pattern, in->args.vc.actions, 13312 &in->args.vc.tunnel_ops); 13313 break; 13314 case CREATE: 13315 port_flow_create(in->port, &in->args.vc.attr, 13316 in->args.vc.pattern, in->args.vc.actions, 13317 &in->args.vc.tunnel_ops, in->args.vc.user_id); 13318 break; 13319 case DESTROY: 13320 port_flow_destroy(in->port, in->args.destroy.rule_n, 13321 in->args.destroy.rule, 13322 in->args.destroy.is_user_id); 13323 break; 13324 case UPDATE: 13325 port_flow_update(in->port, in->args.vc.rule_id, 13326 in->args.vc.actions, in->args.vc.user_id); 13327 break; 13328 case FLUSH: 13329 port_flow_flush(in->port); 13330 break; 13331 case DUMP_ONE: 13332 case DUMP_ALL: 13333 port_flow_dump(in->port, in->args.dump.mode, 13334 in->args.dump.rule, in->args.dump.file, 13335 in->args.dump.is_user_id); 13336 break; 13337 case QUERY: 13338 port_flow_query(in->port, in->args.query.rule, 13339 &in->args.query.action, 13340 in->args.query.is_user_id); 13341 break; 13342 case LIST: 13343 port_flow_list(in->port, in->args.list.group_n, 13344 in->args.list.group); 13345 break; 13346 case ISOLATE: 13347 port_flow_isolate(in->port, in->args.isolate.set); 13348 break; 13349 case AGED: 13350 port_flow_aged(in->port, in->args.aged.destroy); 13351 break; 13352 case TUNNEL_CREATE: 13353 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 13354 break; 13355 case TUNNEL_DESTROY: 13356 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 13357 break; 13358 case TUNNEL_LIST: 13359 port_flow_tunnel_list(in->port); 13360 break; 13361 case ACTION_POL_G: 13362 port_meter_policy_add(in->port, in->args.policy.policy_id, 13363 in->args.vc.actions); 13364 break; 13365 case FLEX_ITEM_CREATE: 13366 flex_item_create(in->port, in->args.flex.token, 13367 in->args.flex.filename); 13368 break; 13369 case FLEX_ITEM_DESTROY: 13370 flex_item_destroy(in->port, in->args.flex.token); 13371 break; 13372 default: 13373 break; 13374 } 13375 fflush(stdout); 13376 } 13377 13378 /** Token generator and output processing callback (cmdline API). */ 13379 static void 13380 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 13381 { 13382 if (cl == NULL) 13383 cmd_flow_tok(arg0, arg2); 13384 else 13385 cmd_flow_parsed(arg0); 13386 } 13387 13388 /** Global parser instance (cmdline API). */ 13389 cmdline_parse_inst_t cmd_flow = { 13390 .f = cmd_flow_cb, 13391 .data = NULL, /**< Unused. */ 13392 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 13393 .tokens = { 13394 NULL, 13395 }, /**< Tokens are returned by cmd_flow_tok(). */ 13396 }; 13397 13398 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 13399 13400 static void 13401 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 13402 { 13403 struct rte_ipv4_hdr *ipv4; 13404 struct rte_ether_hdr *eth; 13405 struct rte_ipv6_hdr *ipv6; 13406 struct rte_vxlan_hdr *vxlan; 13407 struct rte_vxlan_gpe_hdr *gpe; 13408 struct rte_flow_item_nvgre *nvgre; 13409 uint32_t ipv6_vtc_flow; 13410 13411 switch (item->type) { 13412 case RTE_FLOW_ITEM_TYPE_ETH: 13413 eth = (struct rte_ether_hdr *)buf; 13414 if (next_proto) 13415 eth->ether_type = rte_cpu_to_be_16(next_proto); 13416 break; 13417 case RTE_FLOW_ITEM_TYPE_IPV4: 13418 ipv4 = (struct rte_ipv4_hdr *)buf; 13419 if (!ipv4->version_ihl) 13420 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 13421 if (next_proto && ipv4->next_proto_id == 0) 13422 ipv4->next_proto_id = (uint8_t)next_proto; 13423 break; 13424 case RTE_FLOW_ITEM_TYPE_IPV6: 13425 ipv6 = (struct rte_ipv6_hdr *)buf; 13426 if (next_proto && ipv6->proto == 0) 13427 ipv6->proto = (uint8_t)next_proto; 13428 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 13429 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 13430 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 13431 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 13432 break; 13433 case RTE_FLOW_ITEM_TYPE_VXLAN: 13434 vxlan = (struct rte_vxlan_hdr *)buf; 13435 vxlan->vx_flags = 0x08; 13436 break; 13437 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13438 gpe = (struct rte_vxlan_gpe_hdr *)buf; 13439 gpe->vx_flags = 0x0C; 13440 break; 13441 case RTE_FLOW_ITEM_TYPE_NVGRE: 13442 nvgre = (struct rte_flow_item_nvgre *)buf; 13443 nvgre->protocol = rte_cpu_to_be_16(0x6558); 13444 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 13445 break; 13446 default: 13447 break; 13448 } 13449 } 13450 13451 /** Helper of get item's default mask. */ 13452 static const void * 13453 flow_item_default_mask(const struct rte_flow_item *item) 13454 { 13455 const void *mask = NULL; 13456 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 13457 static struct rte_flow_item_ipv6_routing_ext ipv6_routing_ext_default_mask = { 13458 .hdr = { 13459 .next_hdr = 0xff, 13460 .type = 0xff, 13461 .segments_left = 0xff, 13462 }, 13463 }; 13464 13465 switch (item->type) { 13466 case RTE_FLOW_ITEM_TYPE_ANY: 13467 mask = &rte_flow_item_any_mask; 13468 break; 13469 case RTE_FLOW_ITEM_TYPE_PORT_ID: 13470 mask = &rte_flow_item_port_id_mask; 13471 break; 13472 case RTE_FLOW_ITEM_TYPE_RAW: 13473 mask = &rte_flow_item_raw_mask; 13474 break; 13475 case RTE_FLOW_ITEM_TYPE_ETH: 13476 mask = &rte_flow_item_eth_mask; 13477 break; 13478 case RTE_FLOW_ITEM_TYPE_VLAN: 13479 mask = &rte_flow_item_vlan_mask; 13480 break; 13481 case RTE_FLOW_ITEM_TYPE_IPV4: 13482 mask = &rte_flow_item_ipv4_mask; 13483 break; 13484 case RTE_FLOW_ITEM_TYPE_IPV6: 13485 mask = &rte_flow_item_ipv6_mask; 13486 break; 13487 case RTE_FLOW_ITEM_TYPE_ICMP: 13488 mask = &rte_flow_item_icmp_mask; 13489 break; 13490 case RTE_FLOW_ITEM_TYPE_UDP: 13491 mask = &rte_flow_item_udp_mask; 13492 break; 13493 case RTE_FLOW_ITEM_TYPE_TCP: 13494 mask = &rte_flow_item_tcp_mask; 13495 break; 13496 case RTE_FLOW_ITEM_TYPE_SCTP: 13497 mask = &rte_flow_item_sctp_mask; 13498 break; 13499 case RTE_FLOW_ITEM_TYPE_VXLAN: 13500 mask = &rte_flow_item_vxlan_mask; 13501 break; 13502 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13503 mask = &rte_flow_item_vxlan_gpe_mask; 13504 break; 13505 case RTE_FLOW_ITEM_TYPE_E_TAG: 13506 mask = &rte_flow_item_e_tag_mask; 13507 break; 13508 case RTE_FLOW_ITEM_TYPE_NVGRE: 13509 mask = &rte_flow_item_nvgre_mask; 13510 break; 13511 case RTE_FLOW_ITEM_TYPE_MPLS: 13512 mask = &rte_flow_item_mpls_mask; 13513 break; 13514 case RTE_FLOW_ITEM_TYPE_GRE: 13515 mask = &rte_flow_item_gre_mask; 13516 break; 13517 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13518 mask = &gre_key_default_mask; 13519 break; 13520 case RTE_FLOW_ITEM_TYPE_META: 13521 mask = &rte_flow_item_meta_mask; 13522 break; 13523 case RTE_FLOW_ITEM_TYPE_RANDOM: 13524 mask = &rte_flow_item_random_mask; 13525 break; 13526 case RTE_FLOW_ITEM_TYPE_FUZZY: 13527 mask = &rte_flow_item_fuzzy_mask; 13528 break; 13529 case RTE_FLOW_ITEM_TYPE_GTP: 13530 mask = &rte_flow_item_gtp_mask; 13531 break; 13532 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13533 mask = &rte_flow_item_gtp_psc_mask; 13534 break; 13535 case RTE_FLOW_ITEM_TYPE_GENEVE: 13536 mask = &rte_flow_item_geneve_mask; 13537 break; 13538 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13539 mask = &rte_flow_item_geneve_opt_mask; 13540 break; 13541 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 13542 mask = &rte_flow_item_pppoe_proto_id_mask; 13543 break; 13544 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13545 mask = &rte_flow_item_l2tpv3oip_mask; 13546 break; 13547 case RTE_FLOW_ITEM_TYPE_ESP: 13548 mask = &rte_flow_item_esp_mask; 13549 break; 13550 case RTE_FLOW_ITEM_TYPE_AH: 13551 mask = &rte_flow_item_ah_mask; 13552 break; 13553 case RTE_FLOW_ITEM_TYPE_PFCP: 13554 mask = &rte_flow_item_pfcp_mask; 13555 break; 13556 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 13557 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 13558 mask = &rte_flow_item_ethdev_mask; 13559 break; 13560 case RTE_FLOW_ITEM_TYPE_L2TPV2: 13561 mask = &rte_flow_item_l2tpv2_mask; 13562 break; 13563 case RTE_FLOW_ITEM_TYPE_PPP: 13564 mask = &rte_flow_item_ppp_mask; 13565 break; 13566 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 13567 mask = &rte_flow_item_meter_color_mask; 13568 break; 13569 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13570 mask = &ipv6_routing_ext_default_mask; 13571 break; 13572 case RTE_FLOW_ITEM_TYPE_AGGR_AFFINITY: 13573 mask = &rte_flow_item_aggr_affinity_mask; 13574 break; 13575 case RTE_FLOW_ITEM_TYPE_TX_QUEUE: 13576 mask = &rte_flow_item_tx_queue_mask; 13577 break; 13578 case RTE_FLOW_ITEM_TYPE_IB_BTH: 13579 mask = &rte_flow_item_ib_bth_mask; 13580 break; 13581 case RTE_FLOW_ITEM_TYPE_PTYPE: 13582 mask = &rte_flow_item_ptype_mask; 13583 break; 13584 default: 13585 break; 13586 } 13587 return mask; 13588 } 13589 13590 /** Dispatch parsed buffer to function calls. */ 13591 static void 13592 cmd_set_ipv6_ext_parsed(const struct buffer *in) 13593 { 13594 uint32_t n = in->args.vc.pattern_n; 13595 int i = 0; 13596 struct rte_flow_item *item = NULL; 13597 size_t size = 0; 13598 uint8_t *data = NULL; 13599 uint8_t *type = NULL; 13600 size_t *total_size = NULL; 13601 uint16_t idx = in->port; /* We borrow port field as index */ 13602 struct rte_flow_item_ipv6_routing_ext *ext; 13603 const struct rte_flow_item_ipv6_ext *ipv6_ext; 13604 13605 RTE_ASSERT(in->command == SET_IPV6_EXT_PUSH || 13606 in->command == SET_IPV6_EXT_REMOVE); 13607 13608 if (in->command == SET_IPV6_EXT_REMOVE) { 13609 if (n != 1 || in->args.vc.pattern->type != 13610 RTE_FLOW_ITEM_TYPE_IPV6_EXT) { 13611 fprintf(stderr, "Error - Not supported item\n"); 13612 return; 13613 } 13614 type = (uint8_t *)&ipv6_ext_remove_confs[idx].type; 13615 item = in->args.vc.pattern; 13616 ipv6_ext = item->spec; 13617 *type = ipv6_ext->next_hdr; 13618 return; 13619 } 13620 13621 total_size = &ipv6_ext_push_confs[idx].size; 13622 data = (uint8_t *)&ipv6_ext_push_confs[idx].data; 13623 type = (uint8_t *)&ipv6_ext_push_confs[idx].type; 13624 13625 *total_size = 0; 13626 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13627 for (i = n - 1 ; i >= 0; --i) { 13628 item = in->args.vc.pattern + i; 13629 switch (item->type) { 13630 case RTE_FLOW_ITEM_TYPE_IPV6_EXT: 13631 ipv6_ext = item->spec; 13632 *type = ipv6_ext->next_hdr; 13633 break; 13634 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13635 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13636 if (!ext->hdr.hdr_len) { 13637 size = sizeof(struct rte_ipv6_routing_ext) + 13638 (ext->hdr.segments_left << 4); 13639 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13640 /* Indicate no TLV once SRH. */ 13641 if (ext->hdr.type == 4) 13642 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13643 } else { 13644 size = sizeof(struct rte_ipv6_routing_ext) + 13645 (ext->hdr.hdr_len << 3); 13646 } 13647 *total_size += size; 13648 memcpy(data, ext, size); 13649 break; 13650 default: 13651 fprintf(stderr, "Error - Not supported item\n"); 13652 goto error; 13653 } 13654 } 13655 RTE_ASSERT((*total_size) <= ACTION_IPV6_EXT_PUSH_MAX_DATA); 13656 return; 13657 error: 13658 *total_size = 0; 13659 memset(data, 0x00, ACTION_IPV6_EXT_PUSH_MAX_DATA); 13660 } 13661 13662 /** Dispatch parsed buffer to function calls. */ 13663 static void 13664 cmd_set_raw_parsed_sample(const struct buffer *in) 13665 { 13666 uint32_t n = in->args.vc.actions_n; 13667 uint32_t i = 0; 13668 struct rte_flow_action *action = NULL; 13669 struct rte_flow_action *data = NULL; 13670 const struct rte_flow_action_rss *rss = NULL; 13671 size_t size = 0; 13672 uint16_t idx = in->port; /* We borrow port field as index */ 13673 uint32_t max_size = sizeof(struct rte_flow_action) * 13674 ACTION_SAMPLE_ACTIONS_NUM; 13675 13676 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 13677 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 13678 memset(data, 0x00, max_size); 13679 for (; i <= n - 1; i++) { 13680 action = in->args.vc.actions + i; 13681 if (action->type == RTE_FLOW_ACTION_TYPE_END) 13682 break; 13683 switch (action->type) { 13684 case RTE_FLOW_ACTION_TYPE_MARK: 13685 size = sizeof(struct rte_flow_action_mark); 13686 rte_memcpy(&sample_mark[idx], 13687 (const void *)action->conf, size); 13688 action->conf = &sample_mark[idx]; 13689 break; 13690 case RTE_FLOW_ACTION_TYPE_COUNT: 13691 size = sizeof(struct rte_flow_action_count); 13692 rte_memcpy(&sample_count[idx], 13693 (const void *)action->conf, size); 13694 action->conf = &sample_count[idx]; 13695 break; 13696 case RTE_FLOW_ACTION_TYPE_QUEUE: 13697 size = sizeof(struct rte_flow_action_queue); 13698 rte_memcpy(&sample_queue[idx], 13699 (const void *)action->conf, size); 13700 action->conf = &sample_queue[idx]; 13701 break; 13702 case RTE_FLOW_ACTION_TYPE_RSS: 13703 size = sizeof(struct rte_flow_action_rss); 13704 rss = action->conf; 13705 rte_memcpy(&sample_rss_data[idx].conf, 13706 (const void *)rss, size); 13707 if (rss->key_len && rss->key) { 13708 sample_rss_data[idx].conf.key = 13709 sample_rss_data[idx].key; 13710 rte_memcpy((void *)((uintptr_t) 13711 sample_rss_data[idx].conf.key), 13712 (const void *)rss->key, 13713 sizeof(uint8_t) * rss->key_len); 13714 } 13715 if (rss->queue_num && rss->queue) { 13716 sample_rss_data[idx].conf.queue = 13717 sample_rss_data[idx].queue; 13718 rte_memcpy((void *)((uintptr_t) 13719 sample_rss_data[idx].conf.queue), 13720 (const void *)rss->queue, 13721 sizeof(uint16_t) * rss->queue_num); 13722 } 13723 action->conf = &sample_rss_data[idx].conf; 13724 break; 13725 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 13726 size = sizeof(struct rte_flow_action_raw_encap); 13727 rte_memcpy(&sample_encap[idx], 13728 (const void *)action->conf, size); 13729 action->conf = &sample_encap[idx]; 13730 break; 13731 case RTE_FLOW_ACTION_TYPE_PORT_ID: 13732 size = sizeof(struct rte_flow_action_port_id); 13733 rte_memcpy(&sample_port_id[idx], 13734 (const void *)action->conf, size); 13735 action->conf = &sample_port_id[idx]; 13736 break; 13737 case RTE_FLOW_ACTION_TYPE_PF: 13738 break; 13739 case RTE_FLOW_ACTION_TYPE_VF: 13740 size = sizeof(struct rte_flow_action_vf); 13741 rte_memcpy(&sample_vf[idx], 13742 (const void *)action->conf, size); 13743 action->conf = &sample_vf[idx]; 13744 break; 13745 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 13746 size = sizeof(struct rte_flow_action_vxlan_encap); 13747 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 13748 action->conf = &sample_vxlan_encap[idx].conf; 13749 break; 13750 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 13751 size = sizeof(struct rte_flow_action_nvgre_encap); 13752 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 13753 action->conf = &sample_nvgre_encap[idx]; 13754 break; 13755 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 13756 size = sizeof(struct rte_flow_action_ethdev); 13757 rte_memcpy(&sample_port_representor[idx], 13758 (const void *)action->conf, size); 13759 action->conf = &sample_port_representor[idx]; 13760 break; 13761 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 13762 size = sizeof(struct rte_flow_action_ethdev); 13763 rte_memcpy(&sample_represented_port[idx], 13764 (const void *)action->conf, size); 13765 action->conf = &sample_represented_port[idx]; 13766 break; 13767 default: 13768 fprintf(stderr, "Error - Not supported action\n"); 13769 return; 13770 } 13771 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 13772 data++; 13773 } 13774 } 13775 13776 /** Dispatch parsed buffer to function calls. */ 13777 static void 13778 cmd_set_raw_parsed(const struct buffer *in) 13779 { 13780 uint32_t n = in->args.vc.pattern_n; 13781 int i = 0; 13782 struct rte_flow_item *item = NULL; 13783 size_t size = 0; 13784 uint8_t *data = NULL; 13785 uint8_t *data_tail = NULL; 13786 size_t *total_size = NULL; 13787 uint16_t upper_layer = 0; 13788 uint16_t proto = 0; 13789 uint16_t idx = in->port; /* We borrow port field as index */ 13790 int gtp_psc = -1; /* GTP PSC option index. */ 13791 const void *src_spec; 13792 13793 if (in->command == SET_SAMPLE_ACTIONS) 13794 return cmd_set_raw_parsed_sample(in); 13795 else if (in->command == SET_IPV6_EXT_PUSH || 13796 in->command == SET_IPV6_EXT_REMOVE) 13797 return cmd_set_ipv6_ext_parsed(in); 13798 RTE_ASSERT(in->command == SET_RAW_ENCAP || 13799 in->command == SET_RAW_DECAP); 13800 if (in->command == SET_RAW_ENCAP) { 13801 total_size = &raw_encap_confs[idx].size; 13802 data = (uint8_t *)&raw_encap_confs[idx].data; 13803 } else { 13804 total_size = &raw_decap_confs[idx].size; 13805 data = (uint8_t *)&raw_decap_confs[idx].data; 13806 } 13807 *total_size = 0; 13808 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 13809 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 13810 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 13811 for (i = n - 1 ; i >= 0; --i) { 13812 const struct rte_flow_item_gtp *gtp; 13813 const struct rte_flow_item_geneve_opt *opt; 13814 struct rte_flow_item_ipv6_routing_ext *ext; 13815 13816 item = in->args.vc.pattern + i; 13817 if (item->spec == NULL) 13818 item->spec = flow_item_default_mask(item); 13819 src_spec = item->spec; 13820 switch (item->type) { 13821 case RTE_FLOW_ITEM_TYPE_ETH: 13822 size = sizeof(struct rte_ether_hdr); 13823 break; 13824 case RTE_FLOW_ITEM_TYPE_VLAN: 13825 size = sizeof(struct rte_vlan_hdr); 13826 proto = RTE_ETHER_TYPE_VLAN; 13827 break; 13828 case RTE_FLOW_ITEM_TYPE_IPV4: 13829 size = sizeof(struct rte_ipv4_hdr); 13830 proto = RTE_ETHER_TYPE_IPV4; 13831 break; 13832 case RTE_FLOW_ITEM_TYPE_IPV6: 13833 size = sizeof(struct rte_ipv6_hdr); 13834 proto = RTE_ETHER_TYPE_IPV6; 13835 break; 13836 case RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT: 13837 ext = (struct rte_flow_item_ipv6_routing_ext *)(uintptr_t)item->spec; 13838 if (!ext->hdr.hdr_len) { 13839 size = sizeof(struct rte_ipv6_routing_ext) + 13840 (ext->hdr.segments_left << 4); 13841 ext->hdr.hdr_len = ext->hdr.segments_left << 1; 13842 /* SRv6 without TLV. */ 13843 if (ext->hdr.type == RTE_IPV6_SRCRT_TYPE_4) 13844 ext->hdr.last_entry = ext->hdr.segments_left - 1; 13845 } else { 13846 size = sizeof(struct rte_ipv6_routing_ext) + 13847 (ext->hdr.hdr_len << 3); 13848 } 13849 proto = IPPROTO_ROUTING; 13850 break; 13851 case RTE_FLOW_ITEM_TYPE_UDP: 13852 size = sizeof(struct rte_udp_hdr); 13853 proto = 0x11; 13854 break; 13855 case RTE_FLOW_ITEM_TYPE_TCP: 13856 size = sizeof(struct rte_tcp_hdr); 13857 proto = 0x06; 13858 break; 13859 case RTE_FLOW_ITEM_TYPE_VXLAN: 13860 size = sizeof(struct rte_vxlan_hdr); 13861 break; 13862 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 13863 size = sizeof(struct rte_vxlan_gpe_hdr); 13864 break; 13865 case RTE_FLOW_ITEM_TYPE_GRE: 13866 size = sizeof(struct rte_gre_hdr); 13867 proto = 0x2F; 13868 break; 13869 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 13870 size = sizeof(rte_be32_t); 13871 proto = 0x0; 13872 break; 13873 case RTE_FLOW_ITEM_TYPE_MPLS: 13874 size = sizeof(struct rte_mpls_hdr); 13875 proto = 0x0; 13876 break; 13877 case RTE_FLOW_ITEM_TYPE_NVGRE: 13878 size = sizeof(struct rte_flow_item_nvgre); 13879 proto = 0x2F; 13880 break; 13881 case RTE_FLOW_ITEM_TYPE_GENEVE: 13882 size = sizeof(struct rte_geneve_hdr); 13883 break; 13884 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 13885 opt = (const struct rte_flow_item_geneve_opt *) 13886 item->spec; 13887 size = offsetof(struct rte_flow_item_geneve_opt, 13888 option_len) + sizeof(uint8_t); 13889 if (opt->option_len && opt->data) { 13890 *total_size += opt->option_len * 13891 sizeof(uint32_t); 13892 rte_memcpy(data_tail - (*total_size), 13893 opt->data, 13894 opt->option_len * sizeof(uint32_t)); 13895 } 13896 break; 13897 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 13898 size = sizeof(rte_be32_t); 13899 proto = 0x73; 13900 break; 13901 case RTE_FLOW_ITEM_TYPE_ESP: 13902 size = sizeof(struct rte_esp_hdr); 13903 proto = 0x32; 13904 break; 13905 case RTE_FLOW_ITEM_TYPE_AH: 13906 size = sizeof(struct rte_flow_item_ah); 13907 proto = 0x33; 13908 break; 13909 case RTE_FLOW_ITEM_TYPE_GTP: 13910 if (gtp_psc < 0) { 13911 size = sizeof(struct rte_gtp_hdr); 13912 break; 13913 } 13914 if (gtp_psc != i + 1) { 13915 fprintf(stderr, 13916 "Error - GTP PSC does not follow GTP\n"); 13917 goto error; 13918 } 13919 gtp = item->spec; 13920 if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { 13921 /* Only E flag should be set. */ 13922 fprintf(stderr, 13923 "Error - GTP unsupported flags\n"); 13924 goto error; 13925 } else { 13926 struct rte_gtp_hdr_ext_word ext_word = { 13927 .next_ext = 0x85 13928 }; 13929 13930 /* We have to add GTP header extra word. */ 13931 *total_size += sizeof(ext_word); 13932 rte_memcpy(data_tail - (*total_size), 13933 &ext_word, sizeof(ext_word)); 13934 } 13935 size = sizeof(struct rte_gtp_hdr); 13936 break; 13937 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 13938 if (gtp_psc >= 0) { 13939 fprintf(stderr, 13940 "Error - Multiple GTP PSC items\n"); 13941 goto error; 13942 } else { 13943 const struct rte_flow_item_gtp_psc 13944 *opt = item->spec; 13945 struct rte_gtp_psc_generic_hdr *hdr; 13946 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 13947 sizeof(int32_t)); 13948 13949 *total_size += hdr_size; 13950 hdr = (typeof(hdr))(data_tail - (*total_size)); 13951 memset(hdr, 0, hdr_size); 13952 *hdr = opt->hdr; 13953 hdr->ext_hdr_len = 1; 13954 gtp_psc = i; 13955 size = 0; 13956 } 13957 break; 13958 case RTE_FLOW_ITEM_TYPE_PFCP: 13959 size = sizeof(struct rte_flow_item_pfcp); 13960 break; 13961 case RTE_FLOW_ITEM_TYPE_FLEX: 13962 if (item->spec != NULL) { 13963 size = ((const struct rte_flow_item_flex *)item->spec)->length; 13964 src_spec = ((const struct rte_flow_item_flex *)item->spec)->pattern; 13965 } else { 13966 size = 0; 13967 src_spec = NULL; 13968 } 13969 break; 13970 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 13971 size = 0; 13972 if (item->spec) { 13973 const struct rte_flow_item_gre_opt 13974 *opt = item->spec; 13975 if (opt->checksum_rsvd.checksum) { 13976 *total_size += 13977 sizeof(opt->checksum_rsvd); 13978 rte_memcpy(data_tail - (*total_size), 13979 &opt->checksum_rsvd, 13980 sizeof(opt->checksum_rsvd)); 13981 } 13982 if (opt->key.key) { 13983 *total_size += sizeof(opt->key.key); 13984 rte_memcpy(data_tail - (*total_size), 13985 &opt->key.key, 13986 sizeof(opt->key.key)); 13987 } 13988 if (opt->sequence.sequence) { 13989 *total_size += sizeof(opt->sequence.sequence); 13990 rte_memcpy(data_tail - (*total_size), 13991 &opt->sequence.sequence, 13992 sizeof(opt->sequence.sequence)); 13993 } 13994 } 13995 proto = 0x2F; 13996 break; 13997 default: 13998 fprintf(stderr, "Error - Not supported item\n"); 13999 goto error; 14000 } 14001 if (size) { 14002 *total_size += size; 14003 rte_memcpy(data_tail - (*total_size), src_spec, size); 14004 /* update some fields which cannot be set by cmdline */ 14005 update_fields((data_tail - (*total_size)), item, 14006 upper_layer); 14007 upper_layer = proto; 14008 } 14009 } 14010 if (verbose_level & 0x1) 14011 printf("total data size is %zu\n", (*total_size)); 14012 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 14013 memmove(data, (data_tail - (*total_size)), *total_size); 14014 return; 14015 14016 error: 14017 *total_size = 0; 14018 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 14019 } 14020 14021 /** Populate help strings for current token (cmdline API). */ 14022 static int 14023 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 14024 unsigned int size) 14025 { 14026 struct context *ctx = &cmd_flow_context; 14027 const struct token *token = &token_list[ctx->prev]; 14028 14029 (void)hdr; 14030 if (!size) 14031 return -1; 14032 /* Set token type and update global help with details. */ 14033 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 14034 if (token->help) 14035 cmd_set_raw.help_str = token->help; 14036 else 14037 cmd_set_raw.help_str = token->name; 14038 return 0; 14039 } 14040 14041 /** Token definition template (cmdline API). */ 14042 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 14043 .ops = &(struct cmdline_token_ops){ 14044 .parse = cmd_flow_parse, 14045 .complete_get_nb = cmd_flow_complete_get_nb, 14046 .complete_get_elt = cmd_flow_complete_get_elt, 14047 .get_help = cmd_set_raw_get_help, 14048 }, 14049 .offset = 0, 14050 }; 14051 14052 /** Populate the next dynamic token. */ 14053 static void 14054 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 14055 cmdline_parse_token_hdr_t **hdr_inst) 14056 { 14057 struct context *ctx = &cmd_flow_context; 14058 14059 /* Always reinitialize context before requesting the first token. */ 14060 if (!(hdr_inst - cmd_set_raw.tokens)) { 14061 cmd_flow_context_init(ctx); 14062 ctx->curr = START_SET; 14063 } 14064 /* Return NULL when no more tokens are expected. */ 14065 if (!ctx->next_num && (ctx->curr != START_SET)) { 14066 *hdr = NULL; 14067 return; 14068 } 14069 /* Determine if command should end here. */ 14070 if (ctx->eol && ctx->last && ctx->next_num) { 14071 const enum index *list = ctx->next[ctx->next_num - 1]; 14072 int i; 14073 14074 for (i = 0; list[i]; ++i) { 14075 if (list[i] != END) 14076 continue; 14077 *hdr = NULL; 14078 return; 14079 } 14080 } 14081 *hdr = &cmd_set_raw_token_hdr; 14082 } 14083 14084 /** Token generator and output processing callback (cmdline API). */ 14085 static void 14086 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 14087 { 14088 if (cl == NULL) 14089 cmd_set_raw_tok(arg0, arg2); 14090 else 14091 cmd_set_raw_parsed(arg0); 14092 } 14093 14094 /** Global parser instance (cmdline API). */ 14095 cmdline_parse_inst_t cmd_set_raw = { 14096 .f = cmd_set_raw_cb, 14097 .data = NULL, /**< Unused. */ 14098 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 14099 .tokens = { 14100 NULL, 14101 }, /**< Tokens are returned by cmd_flow_tok(). */ 14102 }; 14103 14104 /* *** display raw_encap/raw_decap buf */ 14105 struct cmd_show_set_raw_result { 14106 cmdline_fixed_string_t cmd_show; 14107 cmdline_fixed_string_t cmd_what; 14108 cmdline_fixed_string_t cmd_all; 14109 uint16_t cmd_index; 14110 }; 14111 14112 static void 14113 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 14114 { 14115 struct cmd_show_set_raw_result *res = parsed_result; 14116 uint16_t index = res->cmd_index; 14117 uint8_t all = 0; 14118 uint8_t *raw_data = NULL; 14119 size_t raw_size = 0; 14120 char title[16] = {0}; 14121 14122 RTE_SET_USED(cl); 14123 RTE_SET_USED(data); 14124 if (!strcmp(res->cmd_all, "all")) { 14125 all = 1; 14126 index = 0; 14127 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 14128 fprintf(stderr, "index should be 0-%u\n", 14129 RAW_ENCAP_CONFS_MAX_NUM - 1); 14130 return; 14131 } 14132 do { 14133 if (!strcmp(res->cmd_what, "raw_encap")) { 14134 raw_data = (uint8_t *)&raw_encap_confs[index].data; 14135 raw_size = raw_encap_confs[index].size; 14136 snprintf(title, 16, "\nindex: %u", index); 14137 rte_hexdump(stdout, title, raw_data, raw_size); 14138 } else { 14139 raw_data = (uint8_t *)&raw_decap_confs[index].data; 14140 raw_size = raw_decap_confs[index].size; 14141 snprintf(title, 16, "\nindex: %u", index); 14142 rte_hexdump(stdout, title, raw_data, raw_size); 14143 } 14144 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 14145 } 14146 14147 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 14148 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14149 cmd_show, "show"); 14150 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 14151 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14152 cmd_what, "raw_encap#raw_decap"); 14153 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 14154 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 14155 cmd_index, RTE_UINT16); 14156 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 14157 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 14158 cmd_all, "all"); 14159 cmdline_parse_inst_t cmd_show_set_raw = { 14160 .f = cmd_show_set_raw_parsed, 14161 .data = NULL, 14162 .help_str = "show <raw_encap|raw_decap> <index>", 14163 .tokens = { 14164 (void *)&cmd_show_set_raw_cmd_show, 14165 (void *)&cmd_show_set_raw_cmd_what, 14166 (void *)&cmd_show_set_raw_cmd_index, 14167 NULL, 14168 }, 14169 }; 14170 cmdline_parse_inst_t cmd_show_set_raw_all = { 14171 .f = cmd_show_set_raw_parsed, 14172 .data = NULL, 14173 .help_str = "show <raw_encap|raw_decap> all", 14174 .tokens = { 14175 (void *)&cmd_show_set_raw_cmd_show, 14176 (void *)&cmd_show_set_raw_cmd_what, 14177 (void *)&cmd_show_set_raw_cmd_all, 14178 NULL, 14179 }, 14180 }; 14181