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 78 /* Top-level command. */ 79 FLOW, 80 /* Sub-level commands. */ 81 INFO, 82 CONFIGURE, 83 PATTERN_TEMPLATE, 84 ACTIONS_TEMPLATE, 85 TABLE, 86 INDIRECT_ACTION, 87 VALIDATE, 88 CREATE, 89 DESTROY, 90 FLUSH, 91 DUMP, 92 QUERY, 93 LIST, 94 AGED, 95 ISOLATE, 96 TUNNEL, 97 FLEX, 98 QUEUE, 99 PUSH, 100 PULL, 101 102 /* Flex arguments */ 103 FLEX_ITEM_INIT, 104 FLEX_ITEM_CREATE, 105 FLEX_ITEM_DESTROY, 106 107 /* Pattern template arguments. */ 108 PATTERN_TEMPLATE_CREATE, 109 PATTERN_TEMPLATE_DESTROY, 110 PATTERN_TEMPLATE_CREATE_ID, 111 PATTERN_TEMPLATE_DESTROY_ID, 112 PATTERN_TEMPLATE_RELAXED_MATCHING, 113 PATTERN_TEMPLATE_INGRESS, 114 PATTERN_TEMPLATE_EGRESS, 115 PATTERN_TEMPLATE_TRANSFER, 116 PATTERN_TEMPLATE_SPEC, 117 118 /* Actions template arguments. */ 119 ACTIONS_TEMPLATE_CREATE, 120 ACTIONS_TEMPLATE_DESTROY, 121 ACTIONS_TEMPLATE_CREATE_ID, 122 ACTIONS_TEMPLATE_DESTROY_ID, 123 ACTIONS_TEMPLATE_INGRESS, 124 ACTIONS_TEMPLATE_EGRESS, 125 ACTIONS_TEMPLATE_TRANSFER, 126 ACTIONS_TEMPLATE_SPEC, 127 ACTIONS_TEMPLATE_MASK, 128 129 /* Queue arguments. */ 130 QUEUE_CREATE, 131 QUEUE_DESTROY, 132 QUEUE_AGED, 133 QUEUE_INDIRECT_ACTION, 134 135 /* Queue create arguments. */ 136 QUEUE_CREATE_ID, 137 QUEUE_CREATE_POSTPONE, 138 QUEUE_TEMPLATE_TABLE, 139 QUEUE_PATTERN_TEMPLATE, 140 QUEUE_ACTIONS_TEMPLATE, 141 QUEUE_SPEC, 142 143 /* Queue destroy arguments. */ 144 QUEUE_DESTROY_ID, 145 QUEUE_DESTROY_POSTPONE, 146 147 /* Queue indirect action arguments */ 148 QUEUE_INDIRECT_ACTION_CREATE, 149 QUEUE_INDIRECT_ACTION_UPDATE, 150 QUEUE_INDIRECT_ACTION_DESTROY, 151 QUEUE_INDIRECT_ACTION_QUERY, 152 153 /* Queue indirect action create arguments */ 154 QUEUE_INDIRECT_ACTION_CREATE_ID, 155 QUEUE_INDIRECT_ACTION_INGRESS, 156 QUEUE_INDIRECT_ACTION_EGRESS, 157 QUEUE_INDIRECT_ACTION_TRANSFER, 158 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 159 QUEUE_INDIRECT_ACTION_SPEC, 160 161 /* Queue indirect action update arguments */ 162 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 163 164 /* Queue indirect action destroy arguments */ 165 QUEUE_INDIRECT_ACTION_DESTROY_ID, 166 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 167 168 /* Queue indirect action query arguments */ 169 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 170 171 /* Push arguments. */ 172 PUSH_QUEUE, 173 174 /* Pull arguments. */ 175 PULL_QUEUE, 176 177 /* Table arguments. */ 178 TABLE_CREATE, 179 TABLE_DESTROY, 180 TABLE_CREATE_ID, 181 TABLE_DESTROY_ID, 182 TABLE_GROUP, 183 TABLE_PRIORITY, 184 TABLE_INGRESS, 185 TABLE_EGRESS, 186 TABLE_TRANSFER, 187 TABLE_RULES_NUMBER, 188 TABLE_PATTERN_TEMPLATE, 189 TABLE_ACTIONS_TEMPLATE, 190 191 /* Tunnel arguments. */ 192 TUNNEL_CREATE, 193 TUNNEL_CREATE_TYPE, 194 TUNNEL_LIST, 195 TUNNEL_DESTROY, 196 TUNNEL_DESTROY_ID, 197 198 /* Destroy arguments. */ 199 DESTROY_RULE, 200 201 /* Query arguments. */ 202 QUERY_ACTION, 203 204 /* List arguments. */ 205 LIST_GROUP, 206 207 /* Destroy aged flow arguments. */ 208 AGED_DESTROY, 209 210 /* Validate/create arguments. */ 211 VC_GROUP, 212 VC_PRIORITY, 213 VC_INGRESS, 214 VC_EGRESS, 215 VC_TRANSFER, 216 VC_TUNNEL_SET, 217 VC_TUNNEL_MATCH, 218 219 /* Dump arguments */ 220 DUMP_ALL, 221 DUMP_ONE, 222 223 /* Configure arguments */ 224 CONFIG_QUEUES_NUMBER, 225 CONFIG_QUEUES_SIZE, 226 CONFIG_COUNTERS_NUMBER, 227 CONFIG_AGING_OBJECTS_NUMBER, 228 CONFIG_METERS_NUMBER, 229 CONFIG_CONN_TRACK_NUMBER, 230 CONFIG_FLAGS, 231 232 /* Indirect action arguments */ 233 INDIRECT_ACTION_CREATE, 234 INDIRECT_ACTION_UPDATE, 235 INDIRECT_ACTION_DESTROY, 236 INDIRECT_ACTION_QUERY, 237 238 /* Indirect action create arguments */ 239 INDIRECT_ACTION_CREATE_ID, 240 INDIRECT_ACTION_INGRESS, 241 INDIRECT_ACTION_EGRESS, 242 INDIRECT_ACTION_TRANSFER, 243 INDIRECT_ACTION_SPEC, 244 245 /* Indirect action destroy arguments */ 246 INDIRECT_ACTION_DESTROY_ID, 247 248 /* Validate/create pattern. */ 249 ITEM_PATTERN, 250 ITEM_PARAM_IS, 251 ITEM_PARAM_SPEC, 252 ITEM_PARAM_LAST, 253 ITEM_PARAM_MASK, 254 ITEM_PARAM_PREFIX, 255 ITEM_NEXT, 256 ITEM_END, 257 ITEM_VOID, 258 ITEM_INVERT, 259 ITEM_ANY, 260 ITEM_ANY_NUM, 261 ITEM_PORT_ID, 262 ITEM_PORT_ID_ID, 263 ITEM_MARK, 264 ITEM_MARK_ID, 265 ITEM_RAW, 266 ITEM_RAW_RELATIVE, 267 ITEM_RAW_SEARCH, 268 ITEM_RAW_OFFSET, 269 ITEM_RAW_LIMIT, 270 ITEM_RAW_PATTERN, 271 ITEM_RAW_PATTERN_HEX, 272 ITEM_ETH, 273 ITEM_ETH_DST, 274 ITEM_ETH_SRC, 275 ITEM_ETH_TYPE, 276 ITEM_ETH_HAS_VLAN, 277 ITEM_VLAN, 278 ITEM_VLAN_TCI, 279 ITEM_VLAN_PCP, 280 ITEM_VLAN_DEI, 281 ITEM_VLAN_VID, 282 ITEM_VLAN_INNER_TYPE, 283 ITEM_VLAN_HAS_MORE_VLAN, 284 ITEM_IPV4, 285 ITEM_IPV4_VER_IHL, 286 ITEM_IPV4_TOS, 287 ITEM_IPV4_ID, 288 ITEM_IPV4_FRAGMENT_OFFSET, 289 ITEM_IPV4_TTL, 290 ITEM_IPV4_PROTO, 291 ITEM_IPV4_SRC, 292 ITEM_IPV4_DST, 293 ITEM_IPV6, 294 ITEM_IPV6_TC, 295 ITEM_IPV6_FLOW, 296 ITEM_IPV6_PROTO, 297 ITEM_IPV6_HOP, 298 ITEM_IPV6_SRC, 299 ITEM_IPV6_DST, 300 ITEM_IPV6_HAS_FRAG_EXT, 301 ITEM_ICMP, 302 ITEM_ICMP_TYPE, 303 ITEM_ICMP_CODE, 304 ITEM_ICMP_IDENT, 305 ITEM_ICMP_SEQ, 306 ITEM_UDP, 307 ITEM_UDP_SRC, 308 ITEM_UDP_DST, 309 ITEM_TCP, 310 ITEM_TCP_SRC, 311 ITEM_TCP_DST, 312 ITEM_TCP_FLAGS, 313 ITEM_SCTP, 314 ITEM_SCTP_SRC, 315 ITEM_SCTP_DST, 316 ITEM_SCTP_TAG, 317 ITEM_SCTP_CKSUM, 318 ITEM_VXLAN, 319 ITEM_VXLAN_VNI, 320 ITEM_VXLAN_LAST_RSVD, 321 ITEM_E_TAG, 322 ITEM_E_TAG_GRP_ECID_B, 323 ITEM_NVGRE, 324 ITEM_NVGRE_TNI, 325 ITEM_MPLS, 326 ITEM_MPLS_LABEL, 327 ITEM_MPLS_TC, 328 ITEM_MPLS_S, 329 ITEM_GRE, 330 ITEM_GRE_PROTO, 331 ITEM_GRE_C_RSVD0_VER, 332 ITEM_GRE_C_BIT, 333 ITEM_GRE_K_BIT, 334 ITEM_GRE_S_BIT, 335 ITEM_FUZZY, 336 ITEM_FUZZY_THRESH, 337 ITEM_GTP, 338 ITEM_GTP_FLAGS, 339 ITEM_GTP_MSG_TYPE, 340 ITEM_GTP_TEID, 341 ITEM_GTPC, 342 ITEM_GTPU, 343 ITEM_GENEVE, 344 ITEM_GENEVE_VNI, 345 ITEM_GENEVE_PROTO, 346 ITEM_GENEVE_OPTLEN, 347 ITEM_VXLAN_GPE, 348 ITEM_VXLAN_GPE_VNI, 349 ITEM_ARP_ETH_IPV4, 350 ITEM_ARP_ETH_IPV4_SHA, 351 ITEM_ARP_ETH_IPV4_SPA, 352 ITEM_ARP_ETH_IPV4_THA, 353 ITEM_ARP_ETH_IPV4_TPA, 354 ITEM_IPV6_EXT, 355 ITEM_IPV6_EXT_NEXT_HDR, 356 ITEM_IPV6_FRAG_EXT, 357 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 358 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 359 ITEM_IPV6_FRAG_EXT_ID, 360 ITEM_ICMP6, 361 ITEM_ICMP6_TYPE, 362 ITEM_ICMP6_CODE, 363 ITEM_ICMP6_ND_NS, 364 ITEM_ICMP6_ND_NS_TARGET_ADDR, 365 ITEM_ICMP6_ND_NA, 366 ITEM_ICMP6_ND_NA_TARGET_ADDR, 367 ITEM_ICMP6_ND_OPT, 368 ITEM_ICMP6_ND_OPT_TYPE, 369 ITEM_ICMP6_ND_OPT_SLA_ETH, 370 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 371 ITEM_ICMP6_ND_OPT_TLA_ETH, 372 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 373 ITEM_META, 374 ITEM_META_DATA, 375 ITEM_GRE_KEY, 376 ITEM_GRE_KEY_VALUE, 377 ITEM_GRE_OPTION, 378 ITEM_GRE_OPTION_CHECKSUM, 379 ITEM_GRE_OPTION_KEY, 380 ITEM_GRE_OPTION_SEQUENCE, 381 ITEM_GTP_PSC, 382 ITEM_GTP_PSC_QFI, 383 ITEM_GTP_PSC_PDU_T, 384 ITEM_PPPOES, 385 ITEM_PPPOED, 386 ITEM_PPPOE_SEID, 387 ITEM_PPPOE_PROTO_ID, 388 ITEM_HIGIG2, 389 ITEM_HIGIG2_CLASSIFICATION, 390 ITEM_HIGIG2_VID, 391 ITEM_TAG, 392 ITEM_TAG_DATA, 393 ITEM_TAG_INDEX, 394 ITEM_L2TPV3OIP, 395 ITEM_L2TPV3OIP_SESSION_ID, 396 ITEM_ESP, 397 ITEM_ESP_SPI, 398 ITEM_AH, 399 ITEM_AH_SPI, 400 ITEM_PFCP, 401 ITEM_PFCP_S_FIELD, 402 ITEM_PFCP_SEID, 403 ITEM_ECPRI, 404 ITEM_ECPRI_COMMON, 405 ITEM_ECPRI_COMMON_TYPE, 406 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 407 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 408 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 409 ITEM_ECPRI_MSG_IQ_DATA_PCID, 410 ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 411 ITEM_ECPRI_MSG_DLY_MSR_MSRID, 412 ITEM_GENEVE_OPT, 413 ITEM_GENEVE_OPT_CLASS, 414 ITEM_GENEVE_OPT_TYPE, 415 ITEM_GENEVE_OPT_LENGTH, 416 ITEM_GENEVE_OPT_DATA, 417 ITEM_INTEGRITY, 418 ITEM_INTEGRITY_LEVEL, 419 ITEM_INTEGRITY_VALUE, 420 ITEM_CONNTRACK, 421 ITEM_POL_PORT, 422 ITEM_POL_METER, 423 ITEM_POL_POLICY, 424 ITEM_PORT_REPRESENTOR, 425 ITEM_PORT_REPRESENTOR_PORT_ID, 426 ITEM_REPRESENTED_PORT, 427 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 428 ITEM_FLEX, 429 ITEM_FLEX_ITEM_HANDLE, 430 ITEM_FLEX_PATTERN_HANDLE, 431 ITEM_L2TPV2, 432 ITEM_L2TPV2_TYPE, 433 ITEM_L2TPV2_TYPE_DATA, 434 ITEM_L2TPV2_TYPE_DATA_L, 435 ITEM_L2TPV2_TYPE_DATA_S, 436 ITEM_L2TPV2_TYPE_DATA_O, 437 ITEM_L2TPV2_TYPE_DATA_L_S, 438 ITEM_L2TPV2_TYPE_CTRL, 439 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 440 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 441 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 442 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 443 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 444 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 445 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 446 ITEM_L2TPV2_MSG_DATA_S_NS, 447 ITEM_L2TPV2_MSG_DATA_S_NR, 448 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 449 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 450 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 451 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 452 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 453 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 454 ITEM_L2TPV2_MSG_DATA_L_S_NS, 455 ITEM_L2TPV2_MSG_DATA_L_S_NR, 456 ITEM_L2TPV2_MSG_CTRL_LENGTH, 457 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 458 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 459 ITEM_L2TPV2_MSG_CTRL_NS, 460 ITEM_L2TPV2_MSG_CTRL_NR, 461 ITEM_PPP, 462 ITEM_PPP_ADDR, 463 ITEM_PPP_CTRL, 464 ITEM_PPP_PROTO_ID, 465 ITEM_METER, 466 ITEM_METER_COLOR, 467 ITEM_METER_COLOR_NAME, 468 469 /* Validate/create actions. */ 470 ACTIONS, 471 ACTION_NEXT, 472 ACTION_END, 473 ACTION_VOID, 474 ACTION_PASSTHRU, 475 ACTION_JUMP, 476 ACTION_JUMP_GROUP, 477 ACTION_MARK, 478 ACTION_MARK_ID, 479 ACTION_FLAG, 480 ACTION_QUEUE, 481 ACTION_QUEUE_INDEX, 482 ACTION_DROP, 483 ACTION_COUNT, 484 ACTION_COUNT_ID, 485 ACTION_RSS, 486 ACTION_RSS_FUNC, 487 ACTION_RSS_LEVEL, 488 ACTION_RSS_FUNC_DEFAULT, 489 ACTION_RSS_FUNC_TOEPLITZ, 490 ACTION_RSS_FUNC_SIMPLE_XOR, 491 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ, 492 ACTION_RSS_TYPES, 493 ACTION_RSS_TYPE, 494 ACTION_RSS_KEY, 495 ACTION_RSS_KEY_LEN, 496 ACTION_RSS_QUEUES, 497 ACTION_RSS_QUEUE, 498 ACTION_PF, 499 ACTION_VF, 500 ACTION_VF_ORIGINAL, 501 ACTION_VF_ID, 502 ACTION_PORT_ID, 503 ACTION_PORT_ID_ORIGINAL, 504 ACTION_PORT_ID_ID, 505 ACTION_METER, 506 ACTION_METER_COLOR, 507 ACTION_METER_COLOR_TYPE, 508 ACTION_METER_COLOR_GREEN, 509 ACTION_METER_COLOR_YELLOW, 510 ACTION_METER_COLOR_RED, 511 ACTION_METER_ID, 512 ACTION_METER_MARK, 513 ACTION_METER_PROFILE, 514 ACTION_METER_PROFILE_ID2PTR, 515 ACTION_METER_POLICY, 516 ACTION_METER_POLICY_ID2PTR, 517 ACTION_METER_COLOR_MODE, 518 ACTION_METER_INIT_COLOR, 519 ACTION_METER_STATE, 520 ACTION_OF_DEC_NW_TTL, 521 ACTION_OF_POP_VLAN, 522 ACTION_OF_PUSH_VLAN, 523 ACTION_OF_PUSH_VLAN_ETHERTYPE, 524 ACTION_OF_SET_VLAN_VID, 525 ACTION_OF_SET_VLAN_VID_VLAN_VID, 526 ACTION_OF_SET_VLAN_PCP, 527 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 528 ACTION_OF_POP_MPLS, 529 ACTION_OF_POP_MPLS_ETHERTYPE, 530 ACTION_OF_PUSH_MPLS, 531 ACTION_OF_PUSH_MPLS_ETHERTYPE, 532 ACTION_VXLAN_ENCAP, 533 ACTION_VXLAN_DECAP, 534 ACTION_NVGRE_ENCAP, 535 ACTION_NVGRE_DECAP, 536 ACTION_L2_ENCAP, 537 ACTION_L2_DECAP, 538 ACTION_MPLSOGRE_ENCAP, 539 ACTION_MPLSOGRE_DECAP, 540 ACTION_MPLSOUDP_ENCAP, 541 ACTION_MPLSOUDP_DECAP, 542 ACTION_SET_IPV4_SRC, 543 ACTION_SET_IPV4_SRC_IPV4_SRC, 544 ACTION_SET_IPV4_DST, 545 ACTION_SET_IPV4_DST_IPV4_DST, 546 ACTION_SET_IPV6_SRC, 547 ACTION_SET_IPV6_SRC_IPV6_SRC, 548 ACTION_SET_IPV6_DST, 549 ACTION_SET_IPV6_DST_IPV6_DST, 550 ACTION_SET_TP_SRC, 551 ACTION_SET_TP_SRC_TP_SRC, 552 ACTION_SET_TP_DST, 553 ACTION_SET_TP_DST_TP_DST, 554 ACTION_MAC_SWAP, 555 ACTION_DEC_TTL, 556 ACTION_SET_TTL, 557 ACTION_SET_TTL_TTL, 558 ACTION_SET_MAC_SRC, 559 ACTION_SET_MAC_SRC_MAC_SRC, 560 ACTION_SET_MAC_DST, 561 ACTION_SET_MAC_DST_MAC_DST, 562 ACTION_INC_TCP_SEQ, 563 ACTION_INC_TCP_SEQ_VALUE, 564 ACTION_DEC_TCP_SEQ, 565 ACTION_DEC_TCP_SEQ_VALUE, 566 ACTION_INC_TCP_ACK, 567 ACTION_INC_TCP_ACK_VALUE, 568 ACTION_DEC_TCP_ACK, 569 ACTION_DEC_TCP_ACK_VALUE, 570 ACTION_RAW_ENCAP, 571 ACTION_RAW_DECAP, 572 ACTION_RAW_ENCAP_INDEX, 573 ACTION_RAW_ENCAP_INDEX_VALUE, 574 ACTION_RAW_DECAP_INDEX, 575 ACTION_RAW_DECAP_INDEX_VALUE, 576 ACTION_SET_TAG, 577 ACTION_SET_TAG_DATA, 578 ACTION_SET_TAG_INDEX, 579 ACTION_SET_TAG_MASK, 580 ACTION_SET_META, 581 ACTION_SET_META_DATA, 582 ACTION_SET_META_MASK, 583 ACTION_SET_IPV4_DSCP, 584 ACTION_SET_IPV4_DSCP_VALUE, 585 ACTION_SET_IPV6_DSCP, 586 ACTION_SET_IPV6_DSCP_VALUE, 587 ACTION_AGE, 588 ACTION_AGE_TIMEOUT, 589 ACTION_SAMPLE, 590 ACTION_SAMPLE_RATIO, 591 ACTION_SAMPLE_INDEX, 592 ACTION_SAMPLE_INDEX_VALUE, 593 ACTION_INDIRECT, 594 INDIRECT_ACTION_ID2PTR, 595 ACTION_MODIFY_FIELD, 596 ACTION_MODIFY_FIELD_OP, 597 ACTION_MODIFY_FIELD_OP_VALUE, 598 ACTION_MODIFY_FIELD_DST_TYPE, 599 ACTION_MODIFY_FIELD_DST_TYPE_VALUE, 600 ACTION_MODIFY_FIELD_DST_LEVEL, 601 ACTION_MODIFY_FIELD_DST_OFFSET, 602 ACTION_MODIFY_FIELD_SRC_TYPE, 603 ACTION_MODIFY_FIELD_SRC_TYPE_VALUE, 604 ACTION_MODIFY_FIELD_SRC_LEVEL, 605 ACTION_MODIFY_FIELD_SRC_OFFSET, 606 ACTION_MODIFY_FIELD_SRC_VALUE, 607 ACTION_MODIFY_FIELD_SRC_POINTER, 608 ACTION_MODIFY_FIELD_WIDTH, 609 ACTION_CONNTRACK, 610 ACTION_CONNTRACK_UPDATE, 611 ACTION_CONNTRACK_UPDATE_DIR, 612 ACTION_CONNTRACK_UPDATE_CTX, 613 ACTION_POL_G, 614 ACTION_POL_Y, 615 ACTION_POL_R, 616 ACTION_PORT_REPRESENTOR, 617 ACTION_PORT_REPRESENTOR_PORT_ID, 618 ACTION_REPRESENTED_PORT, 619 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 620 ACTION_SEND_TO_KERNEL, 621 }; 622 623 /** Maximum size for pattern in struct rte_flow_item_raw. */ 624 #define ITEM_RAW_PATTERN_SIZE 512 625 626 /** Maximum size for GENEVE option data pattern in bytes. */ 627 #define ITEM_GENEVE_OPT_DATA_SIZE 124 628 629 /** Storage size for struct rte_flow_item_raw including pattern. */ 630 #define ITEM_RAW_SIZE \ 631 (sizeof(struct rte_flow_item_raw) + ITEM_RAW_PATTERN_SIZE) 632 633 /** Maximum size for external pattern in struct rte_flow_action_modify_data. */ 634 #define ACTION_MODIFY_PATTERN_SIZE 32 635 636 /** Storage size for struct rte_flow_action_modify_field including pattern. */ 637 #define ACTION_MODIFY_SIZE \ 638 (sizeof(struct rte_flow_action_modify_field) + \ 639 ACTION_MODIFY_PATTERN_SIZE) 640 641 /** Maximum number of queue indices in struct rte_flow_action_rss. */ 642 #define ACTION_RSS_QUEUE_NUM 128 643 644 /** Storage for struct rte_flow_action_rss including external data. */ 645 struct action_rss_data { 646 struct rte_flow_action_rss conf; 647 uint8_t key[RSS_HASH_KEY_LENGTH]; 648 uint16_t queue[ACTION_RSS_QUEUE_NUM]; 649 }; 650 651 /** Maximum data size in struct rte_flow_action_raw_encap. */ 652 #define ACTION_RAW_ENCAP_MAX_DATA 512 653 #define RAW_ENCAP_CONFS_MAX_NUM 8 654 655 /** Storage for struct rte_flow_action_raw_encap. */ 656 struct raw_encap_conf { 657 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 658 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 659 size_t size; 660 }; 661 662 struct raw_encap_conf raw_encap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 663 664 /** Storage for struct rte_flow_action_raw_encap including external data. */ 665 struct action_raw_encap_data { 666 struct rte_flow_action_raw_encap conf; 667 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 668 uint8_t preserve[ACTION_RAW_ENCAP_MAX_DATA]; 669 uint16_t idx; 670 }; 671 672 /** Storage for struct rte_flow_action_raw_decap. */ 673 struct raw_decap_conf { 674 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 675 size_t size; 676 }; 677 678 struct raw_decap_conf raw_decap_confs[RAW_ENCAP_CONFS_MAX_NUM]; 679 680 /** Storage for struct rte_flow_action_raw_decap including external data. */ 681 struct action_raw_decap_data { 682 struct rte_flow_action_raw_decap conf; 683 uint8_t data[ACTION_RAW_ENCAP_MAX_DATA]; 684 uint16_t idx; 685 }; 686 687 struct vxlan_encap_conf vxlan_encap_conf = { 688 .select_ipv4 = 1, 689 .select_vlan = 0, 690 .select_tos_ttl = 0, 691 .vni = "\x00\x00\x00", 692 .udp_src = 0, 693 .udp_dst = RTE_BE16(RTE_VXLAN_DEFAULT_PORT), 694 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 695 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 696 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 697 "\x00\x00\x00\x00\x00\x00\x00\x01", 698 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 699 "\x00\x00\x00\x00\x00\x00\x11\x11", 700 .vlan_tci = 0, 701 .ip_tos = 0, 702 .ip_ttl = 255, 703 .eth_src = "\x00\x00\x00\x00\x00\x00", 704 .eth_dst = "\xff\xff\xff\xff\xff\xff", 705 }; 706 707 /** Maximum number of items in struct rte_flow_action_vxlan_encap. */ 708 #define ACTION_VXLAN_ENCAP_ITEMS_NUM 6 709 710 /** Storage for struct rte_flow_action_vxlan_encap including external data. */ 711 struct action_vxlan_encap_data { 712 struct rte_flow_action_vxlan_encap conf; 713 struct rte_flow_item items[ACTION_VXLAN_ENCAP_ITEMS_NUM]; 714 struct rte_flow_item_eth item_eth; 715 struct rte_flow_item_vlan item_vlan; 716 union { 717 struct rte_flow_item_ipv4 item_ipv4; 718 struct rte_flow_item_ipv6 item_ipv6; 719 }; 720 struct rte_flow_item_udp item_udp; 721 struct rte_flow_item_vxlan item_vxlan; 722 }; 723 724 struct nvgre_encap_conf nvgre_encap_conf = { 725 .select_ipv4 = 1, 726 .select_vlan = 0, 727 .tni = "\x00\x00\x00", 728 .ipv4_src = RTE_IPV4(127, 0, 0, 1), 729 .ipv4_dst = RTE_IPV4(255, 255, 255, 255), 730 .ipv6_src = "\x00\x00\x00\x00\x00\x00\x00\x00" 731 "\x00\x00\x00\x00\x00\x00\x00\x01", 732 .ipv6_dst = "\x00\x00\x00\x00\x00\x00\x00\x00" 733 "\x00\x00\x00\x00\x00\x00\x11\x11", 734 .vlan_tci = 0, 735 .eth_src = "\x00\x00\x00\x00\x00\x00", 736 .eth_dst = "\xff\xff\xff\xff\xff\xff", 737 }; 738 739 /** Maximum number of items in struct rte_flow_action_nvgre_encap. */ 740 #define ACTION_NVGRE_ENCAP_ITEMS_NUM 5 741 742 /** Storage for struct rte_flow_action_nvgre_encap including external data. */ 743 struct action_nvgre_encap_data { 744 struct rte_flow_action_nvgre_encap conf; 745 struct rte_flow_item items[ACTION_NVGRE_ENCAP_ITEMS_NUM]; 746 struct rte_flow_item_eth item_eth; 747 struct rte_flow_item_vlan item_vlan; 748 union { 749 struct rte_flow_item_ipv4 item_ipv4; 750 struct rte_flow_item_ipv6 item_ipv6; 751 }; 752 struct rte_flow_item_nvgre item_nvgre; 753 }; 754 755 struct l2_encap_conf l2_encap_conf; 756 757 struct l2_decap_conf l2_decap_conf; 758 759 struct mplsogre_encap_conf mplsogre_encap_conf; 760 761 struct mplsogre_decap_conf mplsogre_decap_conf; 762 763 struct mplsoudp_encap_conf mplsoudp_encap_conf; 764 765 struct mplsoudp_decap_conf mplsoudp_decap_conf; 766 767 struct rte_flow_action_conntrack conntrack_context; 768 769 #define ACTION_SAMPLE_ACTIONS_NUM 10 770 #define RAW_SAMPLE_CONFS_MAX_NUM 8 771 /** Storage for struct rte_flow_action_sample including external data. */ 772 struct action_sample_data { 773 struct rte_flow_action_sample conf; 774 uint32_t idx; 775 }; 776 /** Storage for struct rte_flow_action_sample. */ 777 struct raw_sample_conf { 778 struct rte_flow_action data[ACTION_SAMPLE_ACTIONS_NUM]; 779 }; 780 struct raw_sample_conf raw_sample_confs[RAW_SAMPLE_CONFS_MAX_NUM]; 781 struct rte_flow_action_mark sample_mark[RAW_SAMPLE_CONFS_MAX_NUM]; 782 struct rte_flow_action_queue sample_queue[RAW_SAMPLE_CONFS_MAX_NUM]; 783 struct rte_flow_action_count sample_count[RAW_SAMPLE_CONFS_MAX_NUM]; 784 struct rte_flow_action_port_id sample_port_id[RAW_SAMPLE_CONFS_MAX_NUM]; 785 struct rte_flow_action_raw_encap sample_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 786 struct action_vxlan_encap_data sample_vxlan_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 787 struct action_nvgre_encap_data sample_nvgre_encap[RAW_SAMPLE_CONFS_MAX_NUM]; 788 struct action_rss_data sample_rss_data[RAW_SAMPLE_CONFS_MAX_NUM]; 789 struct rte_flow_action_vf sample_vf[RAW_SAMPLE_CONFS_MAX_NUM]; 790 struct rte_flow_action_ethdev sample_port_representor[RAW_SAMPLE_CONFS_MAX_NUM]; 791 struct rte_flow_action_ethdev sample_represented_port[RAW_SAMPLE_CONFS_MAX_NUM]; 792 793 static const char *const modify_field_ops[] = { 794 "set", "add", "sub", NULL 795 }; 796 797 static const char *const modify_field_ids[] = { 798 "start", "mac_dst", "mac_src", 799 "vlan_type", "vlan_id", "mac_type", 800 "ipv4_dscp", "ipv4_ttl", "ipv4_src", "ipv4_dst", 801 "ipv6_dscp", "ipv6_hoplimit", "ipv6_src", "ipv6_dst", 802 "tcp_port_src", "tcp_port_dst", 803 "tcp_seq_num", "tcp_ack_num", "tcp_flags", 804 "udp_port_src", "udp_port_dst", 805 "vxlan_vni", "geneve_vni", "gtp_teid", 806 "tag", "mark", "meta", "pointer", "value", 807 "ipv4_ecn", "ipv6_ecn", "gtp_psc_qfi", "meter_color", NULL 808 }; 809 810 static const char *const meter_colors[] = { 811 "green", "yellow", "red", "all", NULL 812 }; 813 814 /** Maximum number of subsequent tokens and arguments on the stack. */ 815 #define CTX_STACK_SIZE 16 816 817 /** Parser context. */ 818 struct context { 819 /** Stack of subsequent token lists to process. */ 820 const enum index *next[CTX_STACK_SIZE]; 821 /** Arguments for stacked tokens. */ 822 const void *args[CTX_STACK_SIZE]; 823 enum index curr; /**< Current token index. */ 824 enum index prev; /**< Index of the last token seen. */ 825 int next_num; /**< Number of entries in next[]. */ 826 int args_num; /**< Number of entries in args[]. */ 827 uint32_t eol:1; /**< EOL has been detected. */ 828 uint32_t last:1; /**< No more arguments. */ 829 portid_t port; /**< Current port ID (for completions). */ 830 uint32_t objdata; /**< Object-specific data. */ 831 void *object; /**< Address of current object for relative offsets. */ 832 void *objmask; /**< Object a full mask must be written to. */ 833 }; 834 835 /** Token argument. */ 836 struct arg { 837 uint32_t hton:1; /**< Use network byte ordering. */ 838 uint32_t sign:1; /**< Value is signed. */ 839 uint32_t bounded:1; /**< Value is bounded. */ 840 uintmax_t min; /**< Minimum value if bounded. */ 841 uintmax_t max; /**< Maximum value if bounded. */ 842 uint32_t offset; /**< Relative offset from ctx->object. */ 843 uint32_t size; /**< Field size. */ 844 const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */ 845 }; 846 847 /** Parser token definition. */ 848 struct token { 849 /** Type displayed during completion (defaults to "TOKEN"). */ 850 const char *type; 851 /** Help displayed during completion (defaults to token name). */ 852 const char *help; 853 /** Private data used by parser functions. */ 854 const void *priv; 855 /** 856 * Lists of subsequent tokens to push on the stack. Each call to the 857 * parser consumes the last entry of that stack. 858 */ 859 const enum index *const *next; 860 /** Arguments stack for subsequent tokens that need them. */ 861 const struct arg *const *args; 862 /** 863 * Token-processing callback, returns -1 in case of error, the 864 * length of the matched string otherwise. If NULL, attempts to 865 * match the token name. 866 * 867 * If buf is not NULL, the result should be stored in it according 868 * to context. An error is returned if not large enough. 869 */ 870 int (*call)(struct context *ctx, const struct token *token, 871 const char *str, unsigned int len, 872 void *buf, unsigned int size); 873 /** 874 * Callback that provides possible values for this token, used for 875 * completion. Returns -1 in case of error, the number of possible 876 * values otherwise. If NULL, the token name is used. 877 * 878 * If buf is not NULL, entry index ent is written to buf and the 879 * full length of the entry is returned (same behavior as 880 * snprintf()). 881 */ 882 int (*comp)(struct context *ctx, const struct token *token, 883 unsigned int ent, char *buf, unsigned int size); 884 /** Mandatory token name, no default value. */ 885 const char *name; 886 }; 887 888 /** Static initializer for the next field. */ 889 #define NEXT(...) (const enum index *const []){ __VA_ARGS__, NULL, } 890 891 /** Static initializer for a NEXT() entry. */ 892 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, ZERO, } 893 894 /** Static initializer for the args field. */ 895 #define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, } 896 897 /** Static initializer for ARGS() to target a field. */ 898 #define ARGS_ENTRY(s, f) \ 899 (&(const struct arg){ \ 900 .offset = offsetof(s, f), \ 901 .size = sizeof(((s *)0)->f), \ 902 }) 903 904 /** Static initializer for ARGS() to target a bit-field. */ 905 #define ARGS_ENTRY_BF(s, f, b) \ 906 (&(const struct arg){ \ 907 .size = sizeof(s), \ 908 .mask = (const void *)&(const s){ .f = (1 << (b)) - 1 }, \ 909 }) 910 911 /** Static initializer for ARGS() to target a field with limits. */ 912 #define ARGS_ENTRY_BOUNDED(s, f, i, a) \ 913 (&(const struct arg){ \ 914 .bounded = 1, \ 915 .min = (i), \ 916 .max = (a), \ 917 .offset = offsetof(s, f), \ 918 .size = sizeof(((s *)0)->f), \ 919 }) 920 921 /** Static initializer for ARGS() to target an arbitrary bit-mask. */ 922 #define ARGS_ENTRY_MASK(s, f, m) \ 923 (&(const struct arg){ \ 924 .offset = offsetof(s, f), \ 925 .size = sizeof(((s *)0)->f), \ 926 .mask = (const void *)(m), \ 927 }) 928 929 /** Same as ARGS_ENTRY_MASK() using network byte ordering for the value. */ 930 #define ARGS_ENTRY_MASK_HTON(s, f, m) \ 931 (&(const struct arg){ \ 932 .hton = 1, \ 933 .offset = offsetof(s, f), \ 934 .size = sizeof(((s *)0)->f), \ 935 .mask = (const void *)(m), \ 936 }) 937 938 /** Static initializer for ARGS() to target a pointer. */ 939 #define ARGS_ENTRY_PTR(s, f) \ 940 (&(const struct arg){ \ 941 .size = sizeof(*((s *)0)->f), \ 942 }) 943 944 /** Static initializer for ARGS() with arbitrary offset and size. */ 945 #define ARGS_ENTRY_ARB(o, s) \ 946 (&(const struct arg){ \ 947 .offset = (o), \ 948 .size = (s), \ 949 }) 950 951 /** Same as ARGS_ENTRY_ARB() with bounded values. */ 952 #define ARGS_ENTRY_ARB_BOUNDED(o, s, i, a) \ 953 (&(const struct arg){ \ 954 .bounded = 1, \ 955 .min = (i), \ 956 .max = (a), \ 957 .offset = (o), \ 958 .size = (s), \ 959 }) 960 961 /** Same as ARGS_ENTRY() using network byte ordering. */ 962 #define ARGS_ENTRY_HTON(s, f) \ 963 (&(const struct arg){ \ 964 .hton = 1, \ 965 .offset = offsetof(s, f), \ 966 .size = sizeof(((s *)0)->f), \ 967 }) 968 969 /** Same as ARGS_ENTRY_HTON() for a single argument, without structure. */ 970 #define ARG_ENTRY_HTON(s) \ 971 (&(const struct arg){ \ 972 .hton = 1, \ 973 .offset = 0, \ 974 .size = sizeof(s), \ 975 }) 976 977 /** Parser output buffer layout expected by cmd_flow_parsed(). */ 978 struct buffer { 979 enum index command; /**< Flow command. */ 980 portid_t port; /**< Affected port ID. */ 981 queueid_t queue; /** Async queue ID. */ 982 bool postpone; /** Postpone async operation */ 983 union { 984 struct { 985 struct rte_flow_port_attr port_attr; 986 uint32_t nb_queue; 987 struct rte_flow_queue_attr queue_attr; 988 } configure; /**< Configuration arguments. */ 989 struct { 990 uint32_t *template_id; 991 uint32_t template_id_n; 992 } templ_destroy; /**< Template destroy arguments. */ 993 struct { 994 uint32_t id; 995 struct rte_flow_template_table_attr attr; 996 uint32_t *pat_templ_id; 997 uint32_t pat_templ_id_n; 998 uint32_t *act_templ_id; 999 uint32_t act_templ_id_n; 1000 } table; /**< Table arguments. */ 1001 struct { 1002 uint32_t *table_id; 1003 uint32_t table_id_n; 1004 } table_destroy; /**< Template destroy arguments. */ 1005 struct { 1006 uint32_t *action_id; 1007 uint32_t action_id_n; 1008 } ia_destroy; /**< Indirect action destroy arguments. */ 1009 struct { 1010 uint32_t action_id; 1011 } ia; /* Indirect action query arguments */ 1012 struct { 1013 uint32_t table_id; 1014 uint32_t pat_templ_id; 1015 uint32_t act_templ_id; 1016 struct rte_flow_attr attr; 1017 struct tunnel_ops tunnel_ops; 1018 struct rte_flow_item *pattern; 1019 struct rte_flow_action *actions; 1020 struct rte_flow_action *masks; 1021 uint32_t pattern_n; 1022 uint32_t actions_n; 1023 uint8_t *data; 1024 } vc; /**< Validate/create arguments. */ 1025 struct { 1026 uint32_t *rule; 1027 uint32_t rule_n; 1028 } destroy; /**< Destroy arguments. */ 1029 struct { 1030 char file[128]; 1031 bool mode; 1032 uint32_t rule; 1033 } dump; /**< Dump arguments. */ 1034 struct { 1035 uint32_t rule; 1036 struct rte_flow_action action; 1037 } query; /**< Query arguments. */ 1038 struct { 1039 uint32_t *group; 1040 uint32_t group_n; 1041 } list; /**< List arguments. */ 1042 struct { 1043 int set; 1044 } isolate; /**< Isolated mode arguments. */ 1045 struct { 1046 int destroy; 1047 } aged; /**< Aged arguments. */ 1048 struct { 1049 uint32_t policy_id; 1050 } policy;/**< Policy arguments. */ 1051 struct { 1052 uint16_t token; 1053 uintptr_t uintptr; 1054 char filename[128]; 1055 } flex; /**< Flex arguments*/ 1056 } args; /**< Command arguments. */ 1057 }; 1058 1059 /** Private data for pattern items. */ 1060 struct parse_item_priv { 1061 enum rte_flow_item_type type; /**< Item type. */ 1062 uint32_t size; /**< Size of item specification structure. */ 1063 }; 1064 1065 #define PRIV_ITEM(t, s) \ 1066 (&(const struct parse_item_priv){ \ 1067 .type = RTE_FLOW_ITEM_TYPE_ ## t, \ 1068 .size = s, \ 1069 }) 1070 1071 /** Private data for actions. */ 1072 struct parse_action_priv { 1073 enum rte_flow_action_type type; /**< Action type. */ 1074 uint32_t size; /**< Size of action configuration structure. */ 1075 }; 1076 1077 #define PRIV_ACTION(t, s) \ 1078 (&(const struct parse_action_priv){ \ 1079 .type = RTE_FLOW_ACTION_TYPE_ ## t, \ 1080 .size = s, \ 1081 }) 1082 1083 static const enum index next_flex_item[] = { 1084 FLEX_ITEM_INIT, 1085 FLEX_ITEM_CREATE, 1086 FLEX_ITEM_DESTROY, 1087 ZERO, 1088 }; 1089 1090 static const enum index next_config_attr[] = { 1091 CONFIG_QUEUES_NUMBER, 1092 CONFIG_QUEUES_SIZE, 1093 CONFIG_COUNTERS_NUMBER, 1094 CONFIG_AGING_OBJECTS_NUMBER, 1095 CONFIG_METERS_NUMBER, 1096 CONFIG_CONN_TRACK_NUMBER, 1097 CONFIG_FLAGS, 1098 END, 1099 ZERO, 1100 }; 1101 1102 static const enum index next_pt_subcmd[] = { 1103 PATTERN_TEMPLATE_CREATE, 1104 PATTERN_TEMPLATE_DESTROY, 1105 ZERO, 1106 }; 1107 1108 static const enum index next_pt_attr[] = { 1109 PATTERN_TEMPLATE_CREATE_ID, 1110 PATTERN_TEMPLATE_RELAXED_MATCHING, 1111 PATTERN_TEMPLATE_INGRESS, 1112 PATTERN_TEMPLATE_EGRESS, 1113 PATTERN_TEMPLATE_TRANSFER, 1114 PATTERN_TEMPLATE_SPEC, 1115 ZERO, 1116 }; 1117 1118 static const enum index next_pt_destroy_attr[] = { 1119 PATTERN_TEMPLATE_DESTROY_ID, 1120 END, 1121 ZERO, 1122 }; 1123 1124 static const enum index next_at_subcmd[] = { 1125 ACTIONS_TEMPLATE_CREATE, 1126 ACTIONS_TEMPLATE_DESTROY, 1127 ZERO, 1128 }; 1129 1130 static const enum index next_at_attr[] = { 1131 ACTIONS_TEMPLATE_CREATE_ID, 1132 ACTIONS_TEMPLATE_INGRESS, 1133 ACTIONS_TEMPLATE_EGRESS, 1134 ACTIONS_TEMPLATE_TRANSFER, 1135 ACTIONS_TEMPLATE_SPEC, 1136 ZERO, 1137 }; 1138 1139 static const enum index next_at_destroy_attr[] = { 1140 ACTIONS_TEMPLATE_DESTROY_ID, 1141 END, 1142 ZERO, 1143 }; 1144 1145 static const enum index next_table_subcmd[] = { 1146 TABLE_CREATE, 1147 TABLE_DESTROY, 1148 ZERO, 1149 }; 1150 1151 static const enum index next_table_attr[] = { 1152 TABLE_CREATE_ID, 1153 TABLE_GROUP, 1154 TABLE_PRIORITY, 1155 TABLE_INGRESS, 1156 TABLE_EGRESS, 1157 TABLE_TRANSFER, 1158 TABLE_RULES_NUMBER, 1159 TABLE_PATTERN_TEMPLATE, 1160 TABLE_ACTIONS_TEMPLATE, 1161 END, 1162 ZERO, 1163 }; 1164 1165 static const enum index next_table_destroy_attr[] = { 1166 TABLE_DESTROY_ID, 1167 END, 1168 ZERO, 1169 }; 1170 1171 static const enum index next_queue_subcmd[] = { 1172 QUEUE_CREATE, 1173 QUEUE_DESTROY, 1174 QUEUE_AGED, 1175 QUEUE_INDIRECT_ACTION, 1176 ZERO, 1177 }; 1178 1179 static const enum index next_queue_destroy_attr[] = { 1180 QUEUE_DESTROY_ID, 1181 END, 1182 ZERO, 1183 }; 1184 1185 static const enum index next_qia_subcmd[] = { 1186 QUEUE_INDIRECT_ACTION_CREATE, 1187 QUEUE_INDIRECT_ACTION_UPDATE, 1188 QUEUE_INDIRECT_ACTION_DESTROY, 1189 QUEUE_INDIRECT_ACTION_QUERY, 1190 ZERO, 1191 }; 1192 1193 static const enum index next_qia_create_attr[] = { 1194 QUEUE_INDIRECT_ACTION_CREATE_ID, 1195 QUEUE_INDIRECT_ACTION_INGRESS, 1196 QUEUE_INDIRECT_ACTION_EGRESS, 1197 QUEUE_INDIRECT_ACTION_TRANSFER, 1198 QUEUE_INDIRECT_ACTION_CREATE_POSTPONE, 1199 QUEUE_INDIRECT_ACTION_SPEC, 1200 ZERO, 1201 }; 1202 1203 static const enum index next_qia_update_attr[] = { 1204 QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE, 1205 QUEUE_INDIRECT_ACTION_SPEC, 1206 ZERO, 1207 }; 1208 1209 static const enum index next_qia_destroy_attr[] = { 1210 QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE, 1211 QUEUE_INDIRECT_ACTION_DESTROY_ID, 1212 END, 1213 ZERO, 1214 }; 1215 1216 static const enum index next_qia_query_attr[] = { 1217 QUEUE_INDIRECT_ACTION_QUERY_POSTPONE, 1218 END, 1219 ZERO, 1220 }; 1221 1222 static const enum index next_ia_create_attr[] = { 1223 INDIRECT_ACTION_CREATE_ID, 1224 INDIRECT_ACTION_INGRESS, 1225 INDIRECT_ACTION_EGRESS, 1226 INDIRECT_ACTION_TRANSFER, 1227 INDIRECT_ACTION_SPEC, 1228 ZERO, 1229 }; 1230 1231 static const enum index next_dump_subcmd[] = { 1232 DUMP_ALL, 1233 DUMP_ONE, 1234 ZERO, 1235 }; 1236 1237 static const enum index next_ia_subcmd[] = { 1238 INDIRECT_ACTION_CREATE, 1239 INDIRECT_ACTION_UPDATE, 1240 INDIRECT_ACTION_DESTROY, 1241 INDIRECT_ACTION_QUERY, 1242 ZERO, 1243 }; 1244 1245 static const enum index next_vc_attr[] = { 1246 VC_GROUP, 1247 VC_PRIORITY, 1248 VC_INGRESS, 1249 VC_EGRESS, 1250 VC_TRANSFER, 1251 VC_TUNNEL_SET, 1252 VC_TUNNEL_MATCH, 1253 ITEM_PATTERN, 1254 ZERO, 1255 }; 1256 1257 static const enum index next_destroy_attr[] = { 1258 DESTROY_RULE, 1259 END, 1260 ZERO, 1261 }; 1262 1263 static const enum index next_dump_attr[] = { 1264 COMMON_FILE_PATH, 1265 END, 1266 ZERO, 1267 }; 1268 1269 static const enum index next_list_attr[] = { 1270 LIST_GROUP, 1271 END, 1272 ZERO, 1273 }; 1274 1275 static const enum index next_aged_attr[] = { 1276 AGED_DESTROY, 1277 END, 1278 ZERO, 1279 }; 1280 1281 static const enum index next_ia_destroy_attr[] = { 1282 INDIRECT_ACTION_DESTROY_ID, 1283 END, 1284 ZERO, 1285 }; 1286 1287 static const enum index item_param[] = { 1288 ITEM_PARAM_IS, 1289 ITEM_PARAM_SPEC, 1290 ITEM_PARAM_LAST, 1291 ITEM_PARAM_MASK, 1292 ITEM_PARAM_PREFIX, 1293 ZERO, 1294 }; 1295 1296 static const enum index next_item[] = { 1297 ITEM_END, 1298 ITEM_VOID, 1299 ITEM_INVERT, 1300 ITEM_ANY, 1301 ITEM_PORT_ID, 1302 ITEM_MARK, 1303 ITEM_RAW, 1304 ITEM_ETH, 1305 ITEM_VLAN, 1306 ITEM_IPV4, 1307 ITEM_IPV6, 1308 ITEM_ICMP, 1309 ITEM_UDP, 1310 ITEM_TCP, 1311 ITEM_SCTP, 1312 ITEM_VXLAN, 1313 ITEM_E_TAG, 1314 ITEM_NVGRE, 1315 ITEM_MPLS, 1316 ITEM_GRE, 1317 ITEM_FUZZY, 1318 ITEM_GTP, 1319 ITEM_GTPC, 1320 ITEM_GTPU, 1321 ITEM_GENEVE, 1322 ITEM_VXLAN_GPE, 1323 ITEM_ARP_ETH_IPV4, 1324 ITEM_IPV6_EXT, 1325 ITEM_IPV6_FRAG_EXT, 1326 ITEM_ICMP6, 1327 ITEM_ICMP6_ND_NS, 1328 ITEM_ICMP6_ND_NA, 1329 ITEM_ICMP6_ND_OPT, 1330 ITEM_ICMP6_ND_OPT_SLA_ETH, 1331 ITEM_ICMP6_ND_OPT_TLA_ETH, 1332 ITEM_META, 1333 ITEM_GRE_KEY, 1334 ITEM_GRE_OPTION, 1335 ITEM_GTP_PSC, 1336 ITEM_PPPOES, 1337 ITEM_PPPOED, 1338 ITEM_PPPOE_PROTO_ID, 1339 ITEM_HIGIG2, 1340 ITEM_TAG, 1341 ITEM_L2TPV3OIP, 1342 ITEM_ESP, 1343 ITEM_AH, 1344 ITEM_PFCP, 1345 ITEM_ECPRI, 1346 ITEM_GENEVE_OPT, 1347 ITEM_INTEGRITY, 1348 ITEM_CONNTRACK, 1349 ITEM_PORT_REPRESENTOR, 1350 ITEM_REPRESENTED_PORT, 1351 ITEM_FLEX, 1352 ITEM_L2TPV2, 1353 ITEM_PPP, 1354 ITEM_METER, 1355 END_SET, 1356 ZERO, 1357 }; 1358 1359 static const enum index item_fuzzy[] = { 1360 ITEM_FUZZY_THRESH, 1361 ITEM_NEXT, 1362 ZERO, 1363 }; 1364 1365 static const enum index item_any[] = { 1366 ITEM_ANY_NUM, 1367 ITEM_NEXT, 1368 ZERO, 1369 }; 1370 1371 static const enum index item_port_id[] = { 1372 ITEM_PORT_ID_ID, 1373 ITEM_NEXT, 1374 ZERO, 1375 }; 1376 1377 static const enum index item_mark[] = { 1378 ITEM_MARK_ID, 1379 ITEM_NEXT, 1380 ZERO, 1381 }; 1382 1383 static const enum index item_raw[] = { 1384 ITEM_RAW_RELATIVE, 1385 ITEM_RAW_SEARCH, 1386 ITEM_RAW_OFFSET, 1387 ITEM_RAW_LIMIT, 1388 ITEM_RAW_PATTERN, 1389 ITEM_RAW_PATTERN_HEX, 1390 ITEM_NEXT, 1391 ZERO, 1392 }; 1393 1394 static const enum index item_eth[] = { 1395 ITEM_ETH_DST, 1396 ITEM_ETH_SRC, 1397 ITEM_ETH_TYPE, 1398 ITEM_ETH_HAS_VLAN, 1399 ITEM_NEXT, 1400 ZERO, 1401 }; 1402 1403 static const enum index item_vlan[] = { 1404 ITEM_VLAN_TCI, 1405 ITEM_VLAN_PCP, 1406 ITEM_VLAN_DEI, 1407 ITEM_VLAN_VID, 1408 ITEM_VLAN_INNER_TYPE, 1409 ITEM_VLAN_HAS_MORE_VLAN, 1410 ITEM_NEXT, 1411 ZERO, 1412 }; 1413 1414 static const enum index item_ipv4[] = { 1415 ITEM_IPV4_VER_IHL, 1416 ITEM_IPV4_TOS, 1417 ITEM_IPV4_ID, 1418 ITEM_IPV4_FRAGMENT_OFFSET, 1419 ITEM_IPV4_TTL, 1420 ITEM_IPV4_PROTO, 1421 ITEM_IPV4_SRC, 1422 ITEM_IPV4_DST, 1423 ITEM_NEXT, 1424 ZERO, 1425 }; 1426 1427 static const enum index item_ipv6[] = { 1428 ITEM_IPV6_TC, 1429 ITEM_IPV6_FLOW, 1430 ITEM_IPV6_PROTO, 1431 ITEM_IPV6_HOP, 1432 ITEM_IPV6_SRC, 1433 ITEM_IPV6_DST, 1434 ITEM_IPV6_HAS_FRAG_EXT, 1435 ITEM_NEXT, 1436 ZERO, 1437 }; 1438 1439 static const enum index item_icmp[] = { 1440 ITEM_ICMP_TYPE, 1441 ITEM_ICMP_CODE, 1442 ITEM_ICMP_IDENT, 1443 ITEM_ICMP_SEQ, 1444 ITEM_NEXT, 1445 ZERO, 1446 }; 1447 1448 static const enum index item_udp[] = { 1449 ITEM_UDP_SRC, 1450 ITEM_UDP_DST, 1451 ITEM_NEXT, 1452 ZERO, 1453 }; 1454 1455 static const enum index item_tcp[] = { 1456 ITEM_TCP_SRC, 1457 ITEM_TCP_DST, 1458 ITEM_TCP_FLAGS, 1459 ITEM_NEXT, 1460 ZERO, 1461 }; 1462 1463 static const enum index item_sctp[] = { 1464 ITEM_SCTP_SRC, 1465 ITEM_SCTP_DST, 1466 ITEM_SCTP_TAG, 1467 ITEM_SCTP_CKSUM, 1468 ITEM_NEXT, 1469 ZERO, 1470 }; 1471 1472 static const enum index item_vxlan[] = { 1473 ITEM_VXLAN_VNI, 1474 ITEM_VXLAN_LAST_RSVD, 1475 ITEM_NEXT, 1476 ZERO, 1477 }; 1478 1479 static const enum index item_e_tag[] = { 1480 ITEM_E_TAG_GRP_ECID_B, 1481 ITEM_NEXT, 1482 ZERO, 1483 }; 1484 1485 static const enum index item_nvgre[] = { 1486 ITEM_NVGRE_TNI, 1487 ITEM_NEXT, 1488 ZERO, 1489 }; 1490 1491 static const enum index item_mpls[] = { 1492 ITEM_MPLS_LABEL, 1493 ITEM_MPLS_TC, 1494 ITEM_MPLS_S, 1495 ITEM_NEXT, 1496 ZERO, 1497 }; 1498 1499 static const enum index item_gre[] = { 1500 ITEM_GRE_PROTO, 1501 ITEM_GRE_C_RSVD0_VER, 1502 ITEM_GRE_C_BIT, 1503 ITEM_GRE_K_BIT, 1504 ITEM_GRE_S_BIT, 1505 ITEM_NEXT, 1506 ZERO, 1507 }; 1508 1509 static const enum index item_gre_key[] = { 1510 ITEM_GRE_KEY_VALUE, 1511 ITEM_NEXT, 1512 ZERO, 1513 }; 1514 1515 static const enum index item_gre_option[] = { 1516 ITEM_GRE_OPTION_CHECKSUM, 1517 ITEM_GRE_OPTION_KEY, 1518 ITEM_GRE_OPTION_SEQUENCE, 1519 ITEM_NEXT, 1520 ZERO, 1521 }; 1522 1523 static const enum index item_gtp[] = { 1524 ITEM_GTP_FLAGS, 1525 ITEM_GTP_MSG_TYPE, 1526 ITEM_GTP_TEID, 1527 ITEM_NEXT, 1528 ZERO, 1529 }; 1530 1531 static const enum index item_geneve[] = { 1532 ITEM_GENEVE_VNI, 1533 ITEM_GENEVE_PROTO, 1534 ITEM_GENEVE_OPTLEN, 1535 ITEM_NEXT, 1536 ZERO, 1537 }; 1538 1539 static const enum index item_vxlan_gpe[] = { 1540 ITEM_VXLAN_GPE_VNI, 1541 ITEM_NEXT, 1542 ZERO, 1543 }; 1544 1545 static const enum index item_arp_eth_ipv4[] = { 1546 ITEM_ARP_ETH_IPV4_SHA, 1547 ITEM_ARP_ETH_IPV4_SPA, 1548 ITEM_ARP_ETH_IPV4_THA, 1549 ITEM_ARP_ETH_IPV4_TPA, 1550 ITEM_NEXT, 1551 ZERO, 1552 }; 1553 1554 static const enum index item_ipv6_ext[] = { 1555 ITEM_IPV6_EXT_NEXT_HDR, 1556 ITEM_NEXT, 1557 ZERO, 1558 }; 1559 1560 static const enum index item_ipv6_frag_ext[] = { 1561 ITEM_IPV6_FRAG_EXT_NEXT_HDR, 1562 ITEM_IPV6_FRAG_EXT_FRAG_DATA, 1563 ITEM_IPV6_FRAG_EXT_ID, 1564 ITEM_NEXT, 1565 ZERO, 1566 }; 1567 1568 static const enum index item_icmp6[] = { 1569 ITEM_ICMP6_TYPE, 1570 ITEM_ICMP6_CODE, 1571 ITEM_NEXT, 1572 ZERO, 1573 }; 1574 1575 static const enum index item_icmp6_nd_ns[] = { 1576 ITEM_ICMP6_ND_NS_TARGET_ADDR, 1577 ITEM_NEXT, 1578 ZERO, 1579 }; 1580 1581 static const enum index item_icmp6_nd_na[] = { 1582 ITEM_ICMP6_ND_NA_TARGET_ADDR, 1583 ITEM_NEXT, 1584 ZERO, 1585 }; 1586 1587 static const enum index item_icmp6_nd_opt[] = { 1588 ITEM_ICMP6_ND_OPT_TYPE, 1589 ITEM_NEXT, 1590 ZERO, 1591 }; 1592 1593 static const enum index item_icmp6_nd_opt_sla_eth[] = { 1594 ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, 1595 ITEM_NEXT, 1596 ZERO, 1597 }; 1598 1599 static const enum index item_icmp6_nd_opt_tla_eth[] = { 1600 ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, 1601 ITEM_NEXT, 1602 ZERO, 1603 }; 1604 1605 static const enum index item_meta[] = { 1606 ITEM_META_DATA, 1607 ITEM_NEXT, 1608 ZERO, 1609 }; 1610 1611 static const enum index item_gtp_psc[] = { 1612 ITEM_GTP_PSC_QFI, 1613 ITEM_GTP_PSC_PDU_T, 1614 ITEM_NEXT, 1615 ZERO, 1616 }; 1617 1618 static const enum index item_pppoed[] = { 1619 ITEM_PPPOE_SEID, 1620 ITEM_NEXT, 1621 ZERO, 1622 }; 1623 1624 static const enum index item_pppoes[] = { 1625 ITEM_PPPOE_SEID, 1626 ITEM_NEXT, 1627 ZERO, 1628 }; 1629 1630 static const enum index item_pppoe_proto_id[] = { 1631 ITEM_NEXT, 1632 ZERO, 1633 }; 1634 1635 static const enum index item_higig2[] = { 1636 ITEM_HIGIG2_CLASSIFICATION, 1637 ITEM_HIGIG2_VID, 1638 ITEM_NEXT, 1639 ZERO, 1640 }; 1641 1642 static const enum index item_esp[] = { 1643 ITEM_ESP_SPI, 1644 ITEM_NEXT, 1645 ZERO, 1646 }; 1647 1648 static const enum index item_ah[] = { 1649 ITEM_AH_SPI, 1650 ITEM_NEXT, 1651 ZERO, 1652 }; 1653 1654 static const enum index item_pfcp[] = { 1655 ITEM_PFCP_S_FIELD, 1656 ITEM_PFCP_SEID, 1657 ITEM_NEXT, 1658 ZERO, 1659 }; 1660 1661 static const enum index next_set_raw[] = { 1662 SET_RAW_INDEX, 1663 ITEM_ETH, 1664 ZERO, 1665 }; 1666 1667 static const enum index item_tag[] = { 1668 ITEM_TAG_DATA, 1669 ITEM_TAG_INDEX, 1670 ITEM_NEXT, 1671 ZERO, 1672 }; 1673 1674 static const enum index item_l2tpv3oip[] = { 1675 ITEM_L2TPV3OIP_SESSION_ID, 1676 ITEM_NEXT, 1677 ZERO, 1678 }; 1679 1680 static const enum index item_ecpri[] = { 1681 ITEM_ECPRI_COMMON, 1682 ITEM_NEXT, 1683 ZERO, 1684 }; 1685 1686 static const enum index item_ecpri_common[] = { 1687 ITEM_ECPRI_COMMON_TYPE, 1688 ZERO, 1689 }; 1690 1691 static const enum index item_ecpri_common_type[] = { 1692 ITEM_ECPRI_COMMON_TYPE_IQ_DATA, 1693 ITEM_ECPRI_COMMON_TYPE_RTC_CTRL, 1694 ITEM_ECPRI_COMMON_TYPE_DLY_MSR, 1695 ZERO, 1696 }; 1697 1698 static const enum index item_geneve_opt[] = { 1699 ITEM_GENEVE_OPT_CLASS, 1700 ITEM_GENEVE_OPT_TYPE, 1701 ITEM_GENEVE_OPT_LENGTH, 1702 ITEM_GENEVE_OPT_DATA, 1703 ITEM_NEXT, 1704 ZERO, 1705 }; 1706 1707 static const enum index item_integrity[] = { 1708 ITEM_INTEGRITY_LEVEL, 1709 ITEM_INTEGRITY_VALUE, 1710 ZERO, 1711 }; 1712 1713 static const enum index item_integrity_lv[] = { 1714 ITEM_INTEGRITY_LEVEL, 1715 ITEM_INTEGRITY_VALUE, 1716 ITEM_NEXT, 1717 ZERO, 1718 }; 1719 1720 static const enum index item_port_representor[] = { 1721 ITEM_PORT_REPRESENTOR_PORT_ID, 1722 ITEM_NEXT, 1723 ZERO, 1724 }; 1725 1726 static const enum index item_represented_port[] = { 1727 ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID, 1728 ITEM_NEXT, 1729 ZERO, 1730 }; 1731 1732 static const enum index item_flex[] = { 1733 ITEM_FLEX_PATTERN_HANDLE, 1734 ITEM_FLEX_ITEM_HANDLE, 1735 ITEM_NEXT, 1736 ZERO, 1737 }; 1738 1739 static const enum index item_l2tpv2[] = { 1740 ITEM_L2TPV2_TYPE, 1741 ITEM_NEXT, 1742 ZERO, 1743 }; 1744 1745 static const enum index item_l2tpv2_type[] = { 1746 ITEM_L2TPV2_TYPE_DATA, 1747 ITEM_L2TPV2_TYPE_DATA_L, 1748 ITEM_L2TPV2_TYPE_DATA_S, 1749 ITEM_L2TPV2_TYPE_DATA_O, 1750 ITEM_L2TPV2_TYPE_DATA_L_S, 1751 ITEM_L2TPV2_TYPE_CTRL, 1752 ZERO, 1753 }; 1754 1755 static const enum index item_l2tpv2_type_data[] = { 1756 ITEM_L2TPV2_MSG_DATA_TUNNEL_ID, 1757 ITEM_L2TPV2_MSG_DATA_SESSION_ID, 1758 ITEM_NEXT, 1759 ZERO, 1760 }; 1761 1762 static const enum index item_l2tpv2_type_data_l[] = { 1763 ITEM_L2TPV2_MSG_DATA_L_LENGTH, 1764 ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID, 1765 ITEM_L2TPV2_MSG_DATA_L_SESSION_ID, 1766 ITEM_NEXT, 1767 ZERO, 1768 }; 1769 1770 static const enum index item_l2tpv2_type_data_s[] = { 1771 ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID, 1772 ITEM_L2TPV2_MSG_DATA_S_SESSION_ID, 1773 ITEM_L2TPV2_MSG_DATA_S_NS, 1774 ITEM_L2TPV2_MSG_DATA_S_NR, 1775 ITEM_NEXT, 1776 ZERO, 1777 }; 1778 1779 static const enum index item_l2tpv2_type_data_o[] = { 1780 ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID, 1781 ITEM_L2TPV2_MSG_DATA_O_SESSION_ID, 1782 ITEM_L2TPV2_MSG_DATA_O_OFFSET, 1783 ITEM_NEXT, 1784 ZERO, 1785 }; 1786 1787 static const enum index item_l2tpv2_type_data_l_s[] = { 1788 ITEM_L2TPV2_MSG_DATA_L_S_LENGTH, 1789 ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID, 1790 ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID, 1791 ITEM_L2TPV2_MSG_DATA_L_S_NS, 1792 ITEM_L2TPV2_MSG_DATA_L_S_NR, 1793 ITEM_NEXT, 1794 ZERO, 1795 }; 1796 1797 static const enum index item_l2tpv2_type_ctrl[] = { 1798 ITEM_L2TPV2_MSG_CTRL_LENGTH, 1799 ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID, 1800 ITEM_L2TPV2_MSG_CTRL_SESSION_ID, 1801 ITEM_L2TPV2_MSG_CTRL_NS, 1802 ITEM_L2TPV2_MSG_CTRL_NR, 1803 ITEM_NEXT, 1804 ZERO, 1805 }; 1806 1807 static const enum index item_ppp[] = { 1808 ITEM_PPP_ADDR, 1809 ITEM_PPP_CTRL, 1810 ITEM_PPP_PROTO_ID, 1811 ITEM_NEXT, 1812 ZERO, 1813 }; 1814 1815 static const enum index item_meter[] = { 1816 ITEM_METER_COLOR, 1817 ITEM_NEXT, 1818 ZERO, 1819 }; 1820 1821 static const enum index next_action[] = { 1822 ACTION_END, 1823 ACTION_VOID, 1824 ACTION_PASSTHRU, 1825 ACTION_JUMP, 1826 ACTION_MARK, 1827 ACTION_FLAG, 1828 ACTION_QUEUE, 1829 ACTION_DROP, 1830 ACTION_COUNT, 1831 ACTION_RSS, 1832 ACTION_PF, 1833 ACTION_VF, 1834 ACTION_PORT_ID, 1835 ACTION_METER, 1836 ACTION_METER_COLOR, 1837 ACTION_METER_MARK, 1838 ACTION_OF_DEC_NW_TTL, 1839 ACTION_OF_POP_VLAN, 1840 ACTION_OF_PUSH_VLAN, 1841 ACTION_OF_SET_VLAN_VID, 1842 ACTION_OF_SET_VLAN_PCP, 1843 ACTION_OF_POP_MPLS, 1844 ACTION_OF_PUSH_MPLS, 1845 ACTION_VXLAN_ENCAP, 1846 ACTION_VXLAN_DECAP, 1847 ACTION_NVGRE_ENCAP, 1848 ACTION_NVGRE_DECAP, 1849 ACTION_L2_ENCAP, 1850 ACTION_L2_DECAP, 1851 ACTION_MPLSOGRE_ENCAP, 1852 ACTION_MPLSOGRE_DECAP, 1853 ACTION_MPLSOUDP_ENCAP, 1854 ACTION_MPLSOUDP_DECAP, 1855 ACTION_SET_IPV4_SRC, 1856 ACTION_SET_IPV4_DST, 1857 ACTION_SET_IPV6_SRC, 1858 ACTION_SET_IPV6_DST, 1859 ACTION_SET_TP_SRC, 1860 ACTION_SET_TP_DST, 1861 ACTION_MAC_SWAP, 1862 ACTION_DEC_TTL, 1863 ACTION_SET_TTL, 1864 ACTION_SET_MAC_SRC, 1865 ACTION_SET_MAC_DST, 1866 ACTION_INC_TCP_SEQ, 1867 ACTION_DEC_TCP_SEQ, 1868 ACTION_INC_TCP_ACK, 1869 ACTION_DEC_TCP_ACK, 1870 ACTION_RAW_ENCAP, 1871 ACTION_RAW_DECAP, 1872 ACTION_SET_TAG, 1873 ACTION_SET_META, 1874 ACTION_SET_IPV4_DSCP, 1875 ACTION_SET_IPV6_DSCP, 1876 ACTION_AGE, 1877 ACTION_SAMPLE, 1878 ACTION_INDIRECT, 1879 ACTION_MODIFY_FIELD, 1880 ACTION_CONNTRACK, 1881 ACTION_CONNTRACK_UPDATE, 1882 ACTION_PORT_REPRESENTOR, 1883 ACTION_REPRESENTED_PORT, 1884 ACTION_SEND_TO_KERNEL, 1885 ZERO, 1886 }; 1887 1888 static const enum index action_mark[] = { 1889 ACTION_MARK_ID, 1890 ACTION_NEXT, 1891 ZERO, 1892 }; 1893 1894 static const enum index action_queue[] = { 1895 ACTION_QUEUE_INDEX, 1896 ACTION_NEXT, 1897 ZERO, 1898 }; 1899 1900 static const enum index action_count[] = { 1901 ACTION_COUNT_ID, 1902 ACTION_NEXT, 1903 ZERO, 1904 }; 1905 1906 static const enum index action_rss[] = { 1907 ACTION_RSS_FUNC, 1908 ACTION_RSS_LEVEL, 1909 ACTION_RSS_TYPES, 1910 ACTION_RSS_KEY, 1911 ACTION_RSS_KEY_LEN, 1912 ACTION_RSS_QUEUES, 1913 ACTION_NEXT, 1914 ZERO, 1915 }; 1916 1917 static const enum index action_vf[] = { 1918 ACTION_VF_ORIGINAL, 1919 ACTION_VF_ID, 1920 ACTION_NEXT, 1921 ZERO, 1922 }; 1923 1924 static const enum index action_port_id[] = { 1925 ACTION_PORT_ID_ORIGINAL, 1926 ACTION_PORT_ID_ID, 1927 ACTION_NEXT, 1928 ZERO, 1929 }; 1930 1931 static const enum index action_meter[] = { 1932 ACTION_METER_ID, 1933 ACTION_NEXT, 1934 ZERO, 1935 }; 1936 1937 static const enum index action_meter_color[] = { 1938 ACTION_METER_COLOR_TYPE, 1939 ACTION_NEXT, 1940 ZERO, 1941 }; 1942 1943 static const enum index action_meter_mark[] = { 1944 ACTION_METER_PROFILE, 1945 ACTION_METER_POLICY, 1946 ACTION_METER_COLOR_MODE, 1947 ACTION_METER_INIT_COLOR, 1948 ACTION_METER_STATE, 1949 ACTION_NEXT, 1950 ZERO, 1951 }; 1952 1953 static const enum index action_of_push_vlan[] = { 1954 ACTION_OF_PUSH_VLAN_ETHERTYPE, 1955 ACTION_NEXT, 1956 ZERO, 1957 }; 1958 1959 static const enum index action_of_set_vlan_vid[] = { 1960 ACTION_OF_SET_VLAN_VID_VLAN_VID, 1961 ACTION_NEXT, 1962 ZERO, 1963 }; 1964 1965 static const enum index action_of_set_vlan_pcp[] = { 1966 ACTION_OF_SET_VLAN_PCP_VLAN_PCP, 1967 ACTION_NEXT, 1968 ZERO, 1969 }; 1970 1971 static const enum index action_of_pop_mpls[] = { 1972 ACTION_OF_POP_MPLS_ETHERTYPE, 1973 ACTION_NEXT, 1974 ZERO, 1975 }; 1976 1977 static const enum index action_of_push_mpls[] = { 1978 ACTION_OF_PUSH_MPLS_ETHERTYPE, 1979 ACTION_NEXT, 1980 ZERO, 1981 }; 1982 1983 static const enum index action_set_ipv4_src[] = { 1984 ACTION_SET_IPV4_SRC_IPV4_SRC, 1985 ACTION_NEXT, 1986 ZERO, 1987 }; 1988 1989 static const enum index action_set_mac_src[] = { 1990 ACTION_SET_MAC_SRC_MAC_SRC, 1991 ACTION_NEXT, 1992 ZERO, 1993 }; 1994 1995 static const enum index action_set_ipv4_dst[] = { 1996 ACTION_SET_IPV4_DST_IPV4_DST, 1997 ACTION_NEXT, 1998 ZERO, 1999 }; 2000 2001 static const enum index action_set_ipv6_src[] = { 2002 ACTION_SET_IPV6_SRC_IPV6_SRC, 2003 ACTION_NEXT, 2004 ZERO, 2005 }; 2006 2007 static const enum index action_set_ipv6_dst[] = { 2008 ACTION_SET_IPV6_DST_IPV6_DST, 2009 ACTION_NEXT, 2010 ZERO, 2011 }; 2012 2013 static const enum index action_set_tp_src[] = { 2014 ACTION_SET_TP_SRC_TP_SRC, 2015 ACTION_NEXT, 2016 ZERO, 2017 }; 2018 2019 static const enum index action_set_tp_dst[] = { 2020 ACTION_SET_TP_DST_TP_DST, 2021 ACTION_NEXT, 2022 ZERO, 2023 }; 2024 2025 static const enum index action_set_ttl[] = { 2026 ACTION_SET_TTL_TTL, 2027 ACTION_NEXT, 2028 ZERO, 2029 }; 2030 2031 static const enum index action_jump[] = { 2032 ACTION_JUMP_GROUP, 2033 ACTION_NEXT, 2034 ZERO, 2035 }; 2036 2037 static const enum index action_set_mac_dst[] = { 2038 ACTION_SET_MAC_DST_MAC_DST, 2039 ACTION_NEXT, 2040 ZERO, 2041 }; 2042 2043 static const enum index action_inc_tcp_seq[] = { 2044 ACTION_INC_TCP_SEQ_VALUE, 2045 ACTION_NEXT, 2046 ZERO, 2047 }; 2048 2049 static const enum index action_dec_tcp_seq[] = { 2050 ACTION_DEC_TCP_SEQ_VALUE, 2051 ACTION_NEXT, 2052 ZERO, 2053 }; 2054 2055 static const enum index action_inc_tcp_ack[] = { 2056 ACTION_INC_TCP_ACK_VALUE, 2057 ACTION_NEXT, 2058 ZERO, 2059 }; 2060 2061 static const enum index action_dec_tcp_ack[] = { 2062 ACTION_DEC_TCP_ACK_VALUE, 2063 ACTION_NEXT, 2064 ZERO, 2065 }; 2066 2067 static const enum index action_raw_encap[] = { 2068 ACTION_RAW_ENCAP_INDEX, 2069 ACTION_NEXT, 2070 ZERO, 2071 }; 2072 2073 static const enum index action_raw_decap[] = { 2074 ACTION_RAW_DECAP_INDEX, 2075 ACTION_NEXT, 2076 ZERO, 2077 }; 2078 2079 static const enum index action_set_tag[] = { 2080 ACTION_SET_TAG_DATA, 2081 ACTION_SET_TAG_INDEX, 2082 ACTION_SET_TAG_MASK, 2083 ACTION_NEXT, 2084 ZERO, 2085 }; 2086 2087 static const enum index action_set_meta[] = { 2088 ACTION_SET_META_DATA, 2089 ACTION_SET_META_MASK, 2090 ACTION_NEXT, 2091 ZERO, 2092 }; 2093 2094 static const enum index action_set_ipv4_dscp[] = { 2095 ACTION_SET_IPV4_DSCP_VALUE, 2096 ACTION_NEXT, 2097 ZERO, 2098 }; 2099 2100 static const enum index action_set_ipv6_dscp[] = { 2101 ACTION_SET_IPV6_DSCP_VALUE, 2102 ACTION_NEXT, 2103 ZERO, 2104 }; 2105 2106 static const enum index action_age[] = { 2107 ACTION_AGE, 2108 ACTION_AGE_TIMEOUT, 2109 ACTION_NEXT, 2110 ZERO, 2111 }; 2112 2113 static const enum index action_sample[] = { 2114 ACTION_SAMPLE, 2115 ACTION_SAMPLE_RATIO, 2116 ACTION_SAMPLE_INDEX, 2117 ACTION_NEXT, 2118 ZERO, 2119 }; 2120 2121 static const enum index next_action_sample[] = { 2122 ACTION_QUEUE, 2123 ACTION_RSS, 2124 ACTION_MARK, 2125 ACTION_COUNT, 2126 ACTION_PORT_ID, 2127 ACTION_RAW_ENCAP, 2128 ACTION_VXLAN_ENCAP, 2129 ACTION_NVGRE_ENCAP, 2130 ACTION_NEXT, 2131 ZERO, 2132 }; 2133 2134 static const enum index action_modify_field_dst[] = { 2135 ACTION_MODIFY_FIELD_DST_LEVEL, 2136 ACTION_MODIFY_FIELD_DST_OFFSET, 2137 ACTION_MODIFY_FIELD_SRC_TYPE, 2138 ZERO, 2139 }; 2140 2141 static const enum index action_modify_field_src[] = { 2142 ACTION_MODIFY_FIELD_SRC_LEVEL, 2143 ACTION_MODIFY_FIELD_SRC_OFFSET, 2144 ACTION_MODIFY_FIELD_SRC_VALUE, 2145 ACTION_MODIFY_FIELD_SRC_POINTER, 2146 ACTION_MODIFY_FIELD_WIDTH, 2147 ZERO, 2148 }; 2149 2150 static const enum index action_update_conntrack[] = { 2151 ACTION_CONNTRACK_UPDATE_DIR, 2152 ACTION_CONNTRACK_UPDATE_CTX, 2153 ACTION_NEXT, 2154 ZERO, 2155 }; 2156 2157 static const enum index action_port_representor[] = { 2158 ACTION_PORT_REPRESENTOR_PORT_ID, 2159 ACTION_NEXT, 2160 ZERO, 2161 }; 2162 2163 static const enum index action_represented_port[] = { 2164 ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID, 2165 ACTION_NEXT, 2166 ZERO, 2167 }; 2168 2169 static int parse_set_raw_encap_decap(struct context *, const struct token *, 2170 const char *, unsigned int, 2171 void *, unsigned int); 2172 static int parse_set_sample_action(struct context *, const struct token *, 2173 const char *, unsigned int, 2174 void *, unsigned int); 2175 static int parse_set_init(struct context *, const struct token *, 2176 const char *, unsigned int, 2177 void *, unsigned int); 2178 static int 2179 parse_flex_handle(struct context *, const struct token *, 2180 const char *, unsigned int, void *, unsigned int); 2181 static int parse_init(struct context *, const struct token *, 2182 const char *, unsigned int, 2183 void *, unsigned int); 2184 static int parse_vc(struct context *, const struct token *, 2185 const char *, unsigned int, 2186 void *, unsigned int); 2187 static int parse_vc_spec(struct context *, const struct token *, 2188 const char *, unsigned int, void *, unsigned int); 2189 static int parse_vc_conf(struct context *, const struct token *, 2190 const char *, unsigned int, void *, unsigned int); 2191 static int parse_vc_item_ecpri_type(struct context *, const struct token *, 2192 const char *, unsigned int, 2193 void *, unsigned int); 2194 static int parse_vc_item_l2tpv2_type(struct context *, const struct token *, 2195 const char *, unsigned int, 2196 void *, unsigned int); 2197 static int parse_vc_action_meter_color_type(struct context *, 2198 const struct token *, 2199 const char *, unsigned int, void *, 2200 unsigned int); 2201 static int parse_vc_action_rss(struct context *, const struct token *, 2202 const char *, unsigned int, void *, 2203 unsigned int); 2204 static int parse_vc_action_rss_func(struct context *, const struct token *, 2205 const char *, unsigned int, void *, 2206 unsigned int); 2207 static int parse_vc_action_rss_type(struct context *, const struct token *, 2208 const char *, unsigned int, void *, 2209 unsigned int); 2210 static int parse_vc_action_rss_queue(struct context *, const struct token *, 2211 const char *, unsigned int, void *, 2212 unsigned int); 2213 static int parse_vc_action_vxlan_encap(struct context *, const struct token *, 2214 const char *, unsigned int, void *, 2215 unsigned int); 2216 static int parse_vc_action_nvgre_encap(struct context *, const struct token *, 2217 const char *, unsigned int, void *, 2218 unsigned int); 2219 static int parse_vc_action_l2_encap(struct context *, const struct token *, 2220 const char *, unsigned int, void *, 2221 unsigned int); 2222 static int parse_vc_action_l2_decap(struct context *, const struct token *, 2223 const char *, unsigned int, void *, 2224 unsigned int); 2225 static int parse_vc_action_mplsogre_encap(struct context *, 2226 const struct token *, const char *, 2227 unsigned int, void *, unsigned int); 2228 static int parse_vc_action_mplsogre_decap(struct context *, 2229 const struct token *, const char *, 2230 unsigned int, void *, unsigned int); 2231 static int parse_vc_action_mplsoudp_encap(struct context *, 2232 const struct token *, const char *, 2233 unsigned int, void *, unsigned int); 2234 static int parse_vc_action_mplsoudp_decap(struct context *, 2235 const struct token *, const char *, 2236 unsigned int, void *, unsigned int); 2237 static int parse_vc_action_raw_encap(struct context *, 2238 const struct token *, const char *, 2239 unsigned int, void *, unsigned int); 2240 static int parse_vc_action_raw_decap(struct context *, 2241 const struct token *, const char *, 2242 unsigned int, void *, unsigned int); 2243 static int parse_vc_action_raw_encap_index(struct context *, 2244 const struct token *, const char *, 2245 unsigned int, void *, unsigned int); 2246 static int parse_vc_action_raw_decap_index(struct context *, 2247 const struct token *, const char *, 2248 unsigned int, void *, unsigned int); 2249 static int parse_vc_action_set_meta(struct context *ctx, 2250 const struct token *token, const char *str, 2251 unsigned int len, void *buf, 2252 unsigned int size); 2253 static int parse_vc_action_sample(struct context *ctx, 2254 const struct token *token, const char *str, 2255 unsigned int len, void *buf, 2256 unsigned int size); 2257 static int 2258 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 2259 const char *str, unsigned int len, void *buf, 2260 unsigned int size); 2261 static int 2262 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 2263 const char *str, unsigned int len, void *buf, 2264 unsigned int size); 2265 static int 2266 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 2267 const char *str, unsigned int len, void *buf, 2268 unsigned int size); 2269 static int 2270 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 2271 const char *str, unsigned int len, void *buf, 2272 unsigned int size); 2273 static int parse_destroy(struct context *, const struct token *, 2274 const char *, unsigned int, 2275 void *, unsigned int); 2276 static int parse_flush(struct context *, const struct token *, 2277 const char *, unsigned int, 2278 void *, unsigned int); 2279 static int parse_dump(struct context *, const struct token *, 2280 const char *, unsigned int, 2281 void *, unsigned int); 2282 static int parse_query(struct context *, const struct token *, 2283 const char *, unsigned int, 2284 void *, unsigned int); 2285 static int parse_action(struct context *, const struct token *, 2286 const char *, unsigned int, 2287 void *, unsigned int); 2288 static int parse_list(struct context *, const struct token *, 2289 const char *, unsigned int, 2290 void *, unsigned int); 2291 static int parse_aged(struct context *, const struct token *, 2292 const char *, unsigned int, 2293 void *, unsigned int); 2294 static int parse_isolate(struct context *, const struct token *, 2295 const char *, unsigned int, 2296 void *, unsigned int); 2297 static int parse_configure(struct context *, const struct token *, 2298 const char *, unsigned int, 2299 void *, unsigned int); 2300 static int parse_template(struct context *, const struct token *, 2301 const char *, unsigned int, 2302 void *, unsigned int); 2303 static int parse_template_destroy(struct context *, const struct token *, 2304 const char *, unsigned int, 2305 void *, unsigned int); 2306 static int parse_table(struct context *, const struct token *, 2307 const char *, unsigned int, void *, unsigned int); 2308 static int parse_table_destroy(struct context *, const struct token *, 2309 const char *, unsigned int, 2310 void *, unsigned int); 2311 static int parse_qo(struct context *, const struct token *, 2312 const char *, unsigned int, 2313 void *, unsigned int); 2314 static int parse_qo_destroy(struct context *, const struct token *, 2315 const char *, unsigned int, 2316 void *, unsigned int); 2317 static int parse_qia(struct context *, const struct token *, 2318 const char *, unsigned int, 2319 void *, unsigned int); 2320 static int parse_qia_destroy(struct context *, const struct token *, 2321 const char *, unsigned int, 2322 void *, unsigned int); 2323 static int parse_push(struct context *, const struct token *, 2324 const char *, unsigned int, 2325 void *, unsigned int); 2326 static int parse_pull(struct context *, const struct token *, 2327 const char *, unsigned int, 2328 void *, unsigned int); 2329 static int parse_tunnel(struct context *, const struct token *, 2330 const char *, unsigned int, 2331 void *, unsigned int); 2332 static int parse_flex(struct context *, const struct token *, 2333 const char *, unsigned int, void *, unsigned int); 2334 static int parse_int(struct context *, const struct token *, 2335 const char *, unsigned int, 2336 void *, unsigned int); 2337 static int parse_prefix(struct context *, const struct token *, 2338 const char *, unsigned int, 2339 void *, unsigned int); 2340 static int parse_boolean(struct context *, const struct token *, 2341 const char *, unsigned int, 2342 void *, unsigned int); 2343 static int parse_string(struct context *, const struct token *, 2344 const char *, unsigned int, 2345 void *, unsigned int); 2346 static int parse_hex(struct context *ctx, const struct token *token, 2347 const char *str, unsigned int len, 2348 void *buf, unsigned int size); 2349 static int parse_string0(struct context *, const struct token *, 2350 const char *, unsigned int, 2351 void *, unsigned int); 2352 static int parse_mac_addr(struct context *, const struct token *, 2353 const char *, unsigned int, 2354 void *, unsigned int); 2355 static int parse_ipv4_addr(struct context *, const struct token *, 2356 const char *, unsigned int, 2357 void *, unsigned int); 2358 static int parse_ipv6_addr(struct context *, const struct token *, 2359 const char *, unsigned int, 2360 void *, unsigned int); 2361 static int parse_port(struct context *, const struct token *, 2362 const char *, unsigned int, 2363 void *, unsigned int); 2364 static int parse_ia(struct context *, const struct token *, 2365 const char *, unsigned int, 2366 void *, unsigned int); 2367 static int parse_ia_destroy(struct context *ctx, const struct token *token, 2368 const char *str, unsigned int len, 2369 void *buf, unsigned int size); 2370 static int parse_ia_id2ptr(struct context *ctx, const struct token *token, 2371 const char *str, unsigned int len, void *buf, 2372 unsigned int size); 2373 static int parse_mp(struct context *, const struct token *, 2374 const char *, unsigned int, 2375 void *, unsigned int); 2376 static int parse_meter_profile_id2ptr(struct context *ctx, 2377 const struct token *token, 2378 const char *str, unsigned int len, 2379 void *buf, unsigned int size); 2380 static int parse_meter_policy_id2ptr(struct context *ctx, 2381 const struct token *token, 2382 const char *str, unsigned int len, 2383 void *buf, unsigned int size); 2384 static int parse_meter_color(struct context *ctx, const struct token *token, 2385 const char *str, unsigned int len, void *buf, 2386 unsigned int size); 2387 static int comp_none(struct context *, const struct token *, 2388 unsigned int, char *, unsigned int); 2389 static int comp_boolean(struct context *, const struct token *, 2390 unsigned int, char *, unsigned int); 2391 static int comp_action(struct context *, const struct token *, 2392 unsigned int, char *, unsigned int); 2393 static int comp_port(struct context *, const struct token *, 2394 unsigned int, char *, unsigned int); 2395 static int comp_rule_id(struct context *, const struct token *, 2396 unsigned int, char *, unsigned int); 2397 static int comp_vc_action_rss_type(struct context *, const struct token *, 2398 unsigned int, char *, unsigned int); 2399 static int comp_vc_action_rss_queue(struct context *, const struct token *, 2400 unsigned int, char *, unsigned int); 2401 static int comp_set_raw_index(struct context *, const struct token *, 2402 unsigned int, char *, unsigned int); 2403 static int comp_set_sample_index(struct context *, const struct token *, 2404 unsigned int, char *, unsigned int); 2405 static int comp_set_modify_field_op(struct context *, const struct token *, 2406 unsigned int, char *, unsigned int); 2407 static int comp_set_modify_field_id(struct context *, const struct token *, 2408 unsigned int, char *, unsigned int); 2409 static int comp_pattern_template_id(struct context *, const struct token *, 2410 unsigned int, char *, unsigned int); 2411 static int comp_actions_template_id(struct context *, const struct token *, 2412 unsigned int, char *, unsigned int); 2413 static int comp_table_id(struct context *, const struct token *, 2414 unsigned int, char *, unsigned int); 2415 static int comp_queue_id(struct context *, const struct token *, 2416 unsigned int, char *, unsigned int); 2417 static int comp_meter_color(struct context *, const struct token *, 2418 unsigned int, char *, unsigned int); 2419 2420 /** Token definitions. */ 2421 static const struct token token_list[] = { 2422 /* Special tokens. */ 2423 [ZERO] = { 2424 .name = "ZERO", 2425 .help = "null entry, abused as the entry point", 2426 .next = NEXT(NEXT_ENTRY(FLOW, ADD)), 2427 }, 2428 [END] = { 2429 .name = "", 2430 .type = "RETURN", 2431 .help = "command may end here", 2432 }, 2433 [START_SET] = { 2434 .name = "START_SET", 2435 .help = "null entry, abused as the entry point for set", 2436 .next = NEXT(NEXT_ENTRY(SET)), 2437 }, 2438 [END_SET] = { 2439 .name = "end_set", 2440 .type = "RETURN", 2441 .help = "set command may end here", 2442 }, 2443 /* Common tokens. */ 2444 [COMMON_INTEGER] = { 2445 .name = "{int}", 2446 .type = "INTEGER", 2447 .help = "integer value", 2448 .call = parse_int, 2449 .comp = comp_none, 2450 }, 2451 [COMMON_UNSIGNED] = { 2452 .name = "{unsigned}", 2453 .type = "UNSIGNED", 2454 .help = "unsigned integer value", 2455 .call = parse_int, 2456 .comp = comp_none, 2457 }, 2458 [COMMON_PREFIX] = { 2459 .name = "{prefix}", 2460 .type = "PREFIX", 2461 .help = "prefix length for bit-mask", 2462 .call = parse_prefix, 2463 .comp = comp_none, 2464 }, 2465 [COMMON_BOOLEAN] = { 2466 .name = "{boolean}", 2467 .type = "BOOLEAN", 2468 .help = "any boolean value", 2469 .call = parse_boolean, 2470 .comp = comp_boolean, 2471 }, 2472 [COMMON_STRING] = { 2473 .name = "{string}", 2474 .type = "STRING", 2475 .help = "fixed string", 2476 .call = parse_string, 2477 .comp = comp_none, 2478 }, 2479 [COMMON_HEX] = { 2480 .name = "{hex}", 2481 .type = "HEX", 2482 .help = "fixed string", 2483 .call = parse_hex, 2484 }, 2485 [COMMON_FILE_PATH] = { 2486 .name = "{file path}", 2487 .type = "STRING", 2488 .help = "file path", 2489 .call = parse_string0, 2490 .comp = comp_none, 2491 }, 2492 [COMMON_MAC_ADDR] = { 2493 .name = "{MAC address}", 2494 .type = "MAC-48", 2495 .help = "standard MAC address notation", 2496 .call = parse_mac_addr, 2497 .comp = comp_none, 2498 }, 2499 [COMMON_IPV4_ADDR] = { 2500 .name = "{IPv4 address}", 2501 .type = "IPV4 ADDRESS", 2502 .help = "standard IPv4 address notation", 2503 .call = parse_ipv4_addr, 2504 .comp = comp_none, 2505 }, 2506 [COMMON_IPV6_ADDR] = { 2507 .name = "{IPv6 address}", 2508 .type = "IPV6 ADDRESS", 2509 .help = "standard IPv6 address notation", 2510 .call = parse_ipv6_addr, 2511 .comp = comp_none, 2512 }, 2513 [COMMON_RULE_ID] = { 2514 .name = "{rule id}", 2515 .type = "RULE ID", 2516 .help = "rule identifier", 2517 .call = parse_int, 2518 .comp = comp_rule_id, 2519 }, 2520 [COMMON_PORT_ID] = { 2521 .name = "{port_id}", 2522 .type = "PORT ID", 2523 .help = "port identifier", 2524 .call = parse_port, 2525 .comp = comp_port, 2526 }, 2527 [COMMON_GROUP_ID] = { 2528 .name = "{group_id}", 2529 .type = "GROUP ID", 2530 .help = "group identifier", 2531 .call = parse_int, 2532 .comp = comp_none, 2533 }, 2534 [COMMON_PRIORITY_LEVEL] = { 2535 .name = "{level}", 2536 .type = "PRIORITY", 2537 .help = "priority level", 2538 .call = parse_int, 2539 .comp = comp_none, 2540 }, 2541 [COMMON_INDIRECT_ACTION_ID] = { 2542 .name = "{indirect_action_id}", 2543 .type = "INDIRECT_ACTION_ID", 2544 .help = "indirect action id", 2545 .call = parse_int, 2546 .comp = comp_none, 2547 }, 2548 [COMMON_PROFILE_ID] = { 2549 .name = "{profile_id}", 2550 .type = "PROFILE_ID", 2551 .help = "profile id", 2552 .call = parse_int, 2553 .comp = comp_none, 2554 }, 2555 [COMMON_POLICY_ID] = { 2556 .name = "{policy_id}", 2557 .type = "POLICY_ID", 2558 .help = "policy id", 2559 .call = parse_int, 2560 .comp = comp_none, 2561 }, 2562 [COMMON_FLEX_TOKEN] = { 2563 .name = "{flex token}", 2564 .type = "flex token", 2565 .help = "flex token", 2566 .call = parse_int, 2567 .comp = comp_none, 2568 }, 2569 [COMMON_FLEX_HANDLE] = { 2570 .name = "{flex handle}", 2571 .type = "FLEX HANDLE", 2572 .help = "fill flex item data", 2573 .call = parse_flex_handle, 2574 .comp = comp_none, 2575 }, 2576 [COMMON_PATTERN_TEMPLATE_ID] = { 2577 .name = "{pattern_template_id}", 2578 .type = "PATTERN_TEMPLATE_ID", 2579 .help = "pattern template id", 2580 .call = parse_int, 2581 .comp = comp_pattern_template_id, 2582 }, 2583 [COMMON_ACTIONS_TEMPLATE_ID] = { 2584 .name = "{actions_template_id}", 2585 .type = "ACTIONS_TEMPLATE_ID", 2586 .help = "actions template id", 2587 .call = parse_int, 2588 .comp = comp_actions_template_id, 2589 }, 2590 [COMMON_TABLE_ID] = { 2591 .name = "{table_id}", 2592 .type = "TABLE_ID", 2593 .help = "table id", 2594 .call = parse_int, 2595 .comp = comp_table_id, 2596 }, 2597 [COMMON_QUEUE_ID] = { 2598 .name = "{queue_id}", 2599 .type = "QUEUE_ID", 2600 .help = "queue id", 2601 .call = parse_int, 2602 .comp = comp_queue_id, 2603 }, 2604 /* Top-level command. */ 2605 [FLOW] = { 2606 .name = "flow", 2607 .type = "{command} {port_id} [{arg} [...]]", 2608 .help = "manage ingress/egress flow rules", 2609 .next = NEXT(NEXT_ENTRY 2610 (INFO, 2611 CONFIGURE, 2612 PATTERN_TEMPLATE, 2613 ACTIONS_TEMPLATE, 2614 TABLE, 2615 INDIRECT_ACTION, 2616 VALIDATE, 2617 CREATE, 2618 DESTROY, 2619 FLUSH, 2620 DUMP, 2621 LIST, 2622 AGED, 2623 QUERY, 2624 ISOLATE, 2625 TUNNEL, 2626 FLEX, 2627 QUEUE, 2628 PUSH, 2629 PULL)), 2630 .call = parse_init, 2631 }, 2632 /* Top-level command. */ 2633 [INFO] = { 2634 .name = "info", 2635 .help = "get information about flow engine", 2636 .next = NEXT(NEXT_ENTRY(END), 2637 NEXT_ENTRY(COMMON_PORT_ID)), 2638 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 2639 .call = parse_configure, 2640 }, 2641 /* Top-level command. */ 2642 [CONFIGURE] = { 2643 .name = "configure", 2644 .help = "configure flow engine", 2645 .next = NEXT(next_config_attr, 2646 NEXT_ENTRY(COMMON_PORT_ID)), 2647 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 2648 .call = parse_configure, 2649 }, 2650 /* Configure arguments. */ 2651 [CONFIG_QUEUES_NUMBER] = { 2652 .name = "queues_number", 2653 .help = "number of queues", 2654 .next = NEXT(next_config_attr, 2655 NEXT_ENTRY(COMMON_UNSIGNED)), 2656 .args = ARGS(ARGS_ENTRY(struct buffer, 2657 args.configure.nb_queue)), 2658 }, 2659 [CONFIG_QUEUES_SIZE] = { 2660 .name = "queues_size", 2661 .help = "number of elements in queues", 2662 .next = NEXT(next_config_attr, 2663 NEXT_ENTRY(COMMON_UNSIGNED)), 2664 .args = ARGS(ARGS_ENTRY(struct buffer, 2665 args.configure.queue_attr.size)), 2666 }, 2667 [CONFIG_COUNTERS_NUMBER] = { 2668 .name = "counters_number", 2669 .help = "number of counters", 2670 .next = NEXT(next_config_attr, 2671 NEXT_ENTRY(COMMON_UNSIGNED)), 2672 .args = ARGS(ARGS_ENTRY(struct buffer, 2673 args.configure.port_attr.nb_counters)), 2674 }, 2675 [CONFIG_AGING_OBJECTS_NUMBER] = { 2676 .name = "aging_counters_number", 2677 .help = "number of aging objects", 2678 .next = NEXT(next_config_attr, 2679 NEXT_ENTRY(COMMON_UNSIGNED)), 2680 .args = ARGS(ARGS_ENTRY(struct buffer, 2681 args.configure.port_attr.nb_aging_objects)), 2682 }, 2683 [CONFIG_METERS_NUMBER] = { 2684 .name = "meters_number", 2685 .help = "number of meters", 2686 .next = NEXT(next_config_attr, 2687 NEXT_ENTRY(COMMON_UNSIGNED)), 2688 .args = ARGS(ARGS_ENTRY(struct buffer, 2689 args.configure.port_attr.nb_meters)), 2690 }, 2691 [CONFIG_CONN_TRACK_NUMBER] = { 2692 .name = "conn_tracks_number", 2693 .help = "number of connection trackings", 2694 .next = NEXT(next_config_attr, 2695 NEXT_ENTRY(COMMON_UNSIGNED)), 2696 .args = ARGS(ARGS_ENTRY(struct buffer, 2697 args.configure.port_attr.nb_conn_tracks)), 2698 }, 2699 [CONFIG_FLAGS] = { 2700 .name = "flags", 2701 .help = "configuration flags", 2702 .next = NEXT(next_config_attr, 2703 NEXT_ENTRY(COMMON_UNSIGNED)), 2704 .args = ARGS(ARGS_ENTRY(struct buffer, 2705 args.configure.port_attr.flags)), 2706 }, 2707 /* Top-level command. */ 2708 [PATTERN_TEMPLATE] = { 2709 .name = "pattern_template", 2710 .type = "{command} {port_id} [{arg} [...]]", 2711 .help = "manage pattern templates", 2712 .next = NEXT(next_pt_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 2713 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 2714 .call = parse_template, 2715 }, 2716 /* Sub-level commands. */ 2717 [PATTERN_TEMPLATE_CREATE] = { 2718 .name = "create", 2719 .help = "create pattern template", 2720 .next = NEXT(next_pt_attr), 2721 .call = parse_template, 2722 }, 2723 [PATTERN_TEMPLATE_DESTROY] = { 2724 .name = "destroy", 2725 .help = "destroy pattern template", 2726 .next = NEXT(NEXT_ENTRY(PATTERN_TEMPLATE_DESTROY_ID)), 2727 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 2728 .call = parse_template_destroy, 2729 }, 2730 /* Pattern template arguments. */ 2731 [PATTERN_TEMPLATE_CREATE_ID] = { 2732 .name = "pattern_template_id", 2733 .help = "specify a pattern template id to create", 2734 .next = NEXT(next_pt_attr, 2735 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 2736 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.pat_templ_id)), 2737 }, 2738 [PATTERN_TEMPLATE_DESTROY_ID] = { 2739 .name = "pattern_template", 2740 .help = "specify a pattern template id to destroy", 2741 .next = NEXT(next_pt_destroy_attr, 2742 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 2743 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 2744 args.templ_destroy.template_id)), 2745 .call = parse_template_destroy, 2746 }, 2747 [PATTERN_TEMPLATE_RELAXED_MATCHING] = { 2748 .name = "relaxed", 2749 .help = "is matching relaxed", 2750 .next = NEXT(next_pt_attr, 2751 NEXT_ENTRY(COMMON_BOOLEAN)), 2752 .args = ARGS(ARGS_ENTRY_BF(struct buffer, 2753 args.vc.attr.reserved, 1)), 2754 }, 2755 [PATTERN_TEMPLATE_INGRESS] = { 2756 .name = "ingress", 2757 .help = "attribute pattern to ingress", 2758 .next = NEXT(next_pt_attr), 2759 .call = parse_template, 2760 }, 2761 [PATTERN_TEMPLATE_EGRESS] = { 2762 .name = "egress", 2763 .help = "attribute pattern to egress", 2764 .next = NEXT(next_pt_attr), 2765 .call = parse_template, 2766 }, 2767 [PATTERN_TEMPLATE_TRANSFER] = { 2768 .name = "transfer", 2769 .help = "attribute pattern to transfer", 2770 .next = NEXT(next_pt_attr), 2771 .call = parse_template, 2772 }, 2773 [PATTERN_TEMPLATE_SPEC] = { 2774 .name = "template", 2775 .help = "specify item to create pattern template", 2776 .next = NEXT(next_item), 2777 }, 2778 /* Top-level command. */ 2779 [ACTIONS_TEMPLATE] = { 2780 .name = "actions_template", 2781 .type = "{command} {port_id} [{arg} [...]]", 2782 .help = "manage actions templates", 2783 .next = NEXT(next_at_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 2784 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 2785 .call = parse_template, 2786 }, 2787 /* Sub-level commands. */ 2788 [ACTIONS_TEMPLATE_CREATE] = { 2789 .name = "create", 2790 .help = "create actions template", 2791 .next = NEXT(next_at_attr), 2792 .call = parse_template, 2793 }, 2794 [ACTIONS_TEMPLATE_DESTROY] = { 2795 .name = "destroy", 2796 .help = "destroy actions template", 2797 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_DESTROY_ID)), 2798 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 2799 .call = parse_template_destroy, 2800 }, 2801 /* Actions template arguments. */ 2802 [ACTIONS_TEMPLATE_CREATE_ID] = { 2803 .name = "actions_template_id", 2804 .help = "specify an actions template id to create", 2805 .next = NEXT(NEXT_ENTRY(ACTIONS_TEMPLATE_MASK), 2806 NEXT_ENTRY(ACTIONS_TEMPLATE_SPEC), 2807 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 2808 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.act_templ_id)), 2809 }, 2810 [ACTIONS_TEMPLATE_DESTROY_ID] = { 2811 .name = "actions_template", 2812 .help = "specify an actions template id to destroy", 2813 .next = NEXT(next_at_destroy_attr, 2814 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 2815 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 2816 args.templ_destroy.template_id)), 2817 .call = parse_template_destroy, 2818 }, 2819 [ACTIONS_TEMPLATE_INGRESS] = { 2820 .name = "ingress", 2821 .help = "attribute actions to ingress", 2822 .next = NEXT(next_at_attr), 2823 .call = parse_template, 2824 }, 2825 [ACTIONS_TEMPLATE_EGRESS] = { 2826 .name = "egress", 2827 .help = "attribute actions to egress", 2828 .next = NEXT(next_at_attr), 2829 .call = parse_template, 2830 }, 2831 [ACTIONS_TEMPLATE_TRANSFER] = { 2832 .name = "transfer", 2833 .help = "attribute actions to transfer", 2834 .next = NEXT(next_at_attr), 2835 .call = parse_template, 2836 }, 2837 [ACTIONS_TEMPLATE_SPEC] = { 2838 .name = "template", 2839 .help = "specify action to create actions template", 2840 .next = NEXT(next_action), 2841 .call = parse_template, 2842 }, 2843 [ACTIONS_TEMPLATE_MASK] = { 2844 .name = "mask", 2845 .help = "specify action mask to create actions template", 2846 .next = NEXT(next_action), 2847 .call = parse_template, 2848 }, 2849 /* Top-level command. */ 2850 [TABLE] = { 2851 .name = "template_table", 2852 .type = "{command} {port_id} [{arg} [...]]", 2853 .help = "manage template tables", 2854 .next = NEXT(next_table_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 2855 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 2856 .call = parse_table, 2857 }, 2858 /* Sub-level commands. */ 2859 [TABLE_CREATE] = { 2860 .name = "create", 2861 .help = "create template table", 2862 .next = NEXT(next_table_attr), 2863 .call = parse_table, 2864 }, 2865 [TABLE_DESTROY] = { 2866 .name = "destroy", 2867 .help = "destroy template table", 2868 .next = NEXT(NEXT_ENTRY(TABLE_DESTROY_ID)), 2869 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 2870 .call = parse_table_destroy, 2871 }, 2872 /* Table arguments. */ 2873 [TABLE_CREATE_ID] = { 2874 .name = "table_id", 2875 .help = "specify table id to create", 2876 .next = NEXT(next_table_attr, 2877 NEXT_ENTRY(COMMON_TABLE_ID)), 2878 .args = ARGS(ARGS_ENTRY(struct buffer, args.table.id)), 2879 }, 2880 [TABLE_DESTROY_ID] = { 2881 .name = "table", 2882 .help = "specify table id to destroy", 2883 .next = NEXT(next_table_destroy_attr, 2884 NEXT_ENTRY(COMMON_TABLE_ID)), 2885 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 2886 args.table_destroy.table_id)), 2887 .call = parse_table_destroy, 2888 }, 2889 [TABLE_GROUP] = { 2890 .name = "group", 2891 .help = "specify a group", 2892 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 2893 .args = ARGS(ARGS_ENTRY(struct buffer, 2894 args.table.attr.flow_attr.group)), 2895 }, 2896 [TABLE_PRIORITY] = { 2897 .name = "priority", 2898 .help = "specify a priority level", 2899 .next = NEXT(next_table_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 2900 .args = ARGS(ARGS_ENTRY(struct buffer, 2901 args.table.attr.flow_attr.priority)), 2902 }, 2903 [TABLE_EGRESS] = { 2904 .name = "egress", 2905 .help = "affect rule to egress", 2906 .next = NEXT(next_table_attr), 2907 .call = parse_table, 2908 }, 2909 [TABLE_INGRESS] = { 2910 .name = "ingress", 2911 .help = "affect rule to ingress", 2912 .next = NEXT(next_table_attr), 2913 .call = parse_table, 2914 }, 2915 [TABLE_TRANSFER] = { 2916 .name = "transfer", 2917 .help = "affect rule to transfer", 2918 .next = NEXT(next_table_attr), 2919 .call = parse_table, 2920 }, 2921 [TABLE_RULES_NUMBER] = { 2922 .name = "rules_number", 2923 .help = "number of rules in table", 2924 .next = NEXT(next_table_attr, 2925 NEXT_ENTRY(COMMON_UNSIGNED)), 2926 .args = ARGS(ARGS_ENTRY(struct buffer, 2927 args.table.attr.nb_flows)), 2928 }, 2929 [TABLE_PATTERN_TEMPLATE] = { 2930 .name = "pattern_template", 2931 .help = "specify pattern template id", 2932 .next = NEXT(next_table_attr, 2933 NEXT_ENTRY(COMMON_PATTERN_TEMPLATE_ID)), 2934 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 2935 args.table.pat_templ_id)), 2936 .call = parse_table, 2937 }, 2938 [TABLE_ACTIONS_TEMPLATE] = { 2939 .name = "actions_template", 2940 .help = "specify actions template id", 2941 .next = NEXT(next_table_attr, 2942 NEXT_ENTRY(COMMON_ACTIONS_TEMPLATE_ID)), 2943 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 2944 args.table.act_templ_id)), 2945 .call = parse_table, 2946 }, 2947 /* Top-level command. */ 2948 [QUEUE] = { 2949 .name = "queue", 2950 .help = "queue a flow rule operation", 2951 .next = NEXT(next_queue_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 2952 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 2953 .call = parse_qo, 2954 }, 2955 /* Sub-level commands. */ 2956 [QUEUE_CREATE] = { 2957 .name = "create", 2958 .help = "create a flow rule", 2959 .next = NEXT(NEXT_ENTRY(QUEUE_TEMPLATE_TABLE), 2960 NEXT_ENTRY(COMMON_QUEUE_ID)), 2961 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 2962 .call = parse_qo, 2963 }, 2964 [QUEUE_DESTROY] = { 2965 .name = "destroy", 2966 .help = "destroy a flow rule", 2967 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 2968 NEXT_ENTRY(COMMON_QUEUE_ID)), 2969 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 2970 .call = parse_qo_destroy, 2971 }, 2972 [QUEUE_AGED] = { 2973 .name = "aged", 2974 .help = "list and destroy aged flows", 2975 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_QUEUE_ID)), 2976 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 2977 .call = parse_aged, 2978 }, 2979 [QUEUE_INDIRECT_ACTION] = { 2980 .name = "indirect_action", 2981 .help = "queue indirect actions", 2982 .next = NEXT(next_qia_subcmd, NEXT_ENTRY(COMMON_QUEUE_ID)), 2983 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 2984 .call = parse_qia, 2985 }, 2986 /* Queue arguments. */ 2987 [QUEUE_TEMPLATE_TABLE] = { 2988 .name = "template_table", 2989 .help = "specify table id", 2990 .next = NEXT(NEXT_ENTRY(QUEUE_PATTERN_TEMPLATE), 2991 NEXT_ENTRY(COMMON_TABLE_ID)), 2992 .args = ARGS(ARGS_ENTRY(struct buffer, 2993 args.vc.table_id)), 2994 .call = parse_qo, 2995 }, 2996 [QUEUE_PATTERN_TEMPLATE] = { 2997 .name = "pattern_template", 2998 .help = "specify pattern template index", 2999 .next = NEXT(NEXT_ENTRY(QUEUE_ACTIONS_TEMPLATE), 3000 NEXT_ENTRY(COMMON_UNSIGNED)), 3001 .args = ARGS(ARGS_ENTRY(struct buffer, 3002 args.vc.pat_templ_id)), 3003 .call = parse_qo, 3004 }, 3005 [QUEUE_ACTIONS_TEMPLATE] = { 3006 .name = "actions_template", 3007 .help = "specify actions template index", 3008 .next = NEXT(NEXT_ENTRY(QUEUE_CREATE_POSTPONE), 3009 NEXT_ENTRY(COMMON_UNSIGNED)), 3010 .args = ARGS(ARGS_ENTRY(struct buffer, 3011 args.vc.act_templ_id)), 3012 .call = parse_qo, 3013 }, 3014 [QUEUE_CREATE_POSTPONE] = { 3015 .name = "postpone", 3016 .help = "postpone create operation", 3017 .next = NEXT(NEXT_ENTRY(ITEM_PATTERN), 3018 NEXT_ENTRY(COMMON_BOOLEAN)), 3019 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3020 .call = parse_qo, 3021 }, 3022 [QUEUE_DESTROY_POSTPONE] = { 3023 .name = "postpone", 3024 .help = "postpone destroy operation", 3025 .next = NEXT(NEXT_ENTRY(QUEUE_DESTROY_ID), 3026 NEXT_ENTRY(COMMON_BOOLEAN)), 3027 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3028 .call = parse_qo_destroy, 3029 }, 3030 [QUEUE_DESTROY_ID] = { 3031 .name = "rule", 3032 .help = "specify rule id to destroy", 3033 .next = NEXT(next_queue_destroy_attr, 3034 NEXT_ENTRY(COMMON_UNSIGNED)), 3035 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3036 args.destroy.rule)), 3037 .call = parse_qo_destroy, 3038 }, 3039 /* Queue indirect action arguments */ 3040 [QUEUE_INDIRECT_ACTION_CREATE] = { 3041 .name = "create", 3042 .help = "create indirect action", 3043 .next = NEXT(next_qia_create_attr), 3044 .call = parse_qia, 3045 }, 3046 [QUEUE_INDIRECT_ACTION_UPDATE] = { 3047 .name = "update", 3048 .help = "update indirect action", 3049 .next = NEXT(next_qia_update_attr, 3050 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3051 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3052 .call = parse_qia, 3053 }, 3054 [QUEUE_INDIRECT_ACTION_DESTROY] = { 3055 .name = "destroy", 3056 .help = "destroy indirect action", 3057 .next = NEXT(next_qia_destroy_attr), 3058 .call = parse_qia_destroy, 3059 }, 3060 [QUEUE_INDIRECT_ACTION_QUERY] = { 3061 .name = "query", 3062 .help = "query indirect action", 3063 .next = NEXT(next_qia_query_attr, 3064 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3065 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3066 .call = parse_qia, 3067 }, 3068 /* Indirect action destroy arguments. */ 3069 [QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE] = { 3070 .name = "postpone", 3071 .help = "postpone destroy operation", 3072 .next = NEXT(next_qia_destroy_attr, 3073 NEXT_ENTRY(COMMON_BOOLEAN)), 3074 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3075 }, 3076 [QUEUE_INDIRECT_ACTION_DESTROY_ID] = { 3077 .name = "action_id", 3078 .help = "specify a indirect action id to destroy", 3079 .next = NEXT(next_qia_destroy_attr, 3080 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3081 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 3082 args.ia_destroy.action_id)), 3083 .call = parse_qia_destroy, 3084 }, 3085 /* Indirect action update arguments. */ 3086 [QUEUE_INDIRECT_ACTION_UPDATE_POSTPONE] = { 3087 .name = "postpone", 3088 .help = "postpone update operation", 3089 .next = NEXT(next_qia_update_attr, 3090 NEXT_ENTRY(COMMON_BOOLEAN)), 3091 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3092 }, 3093 /* Indirect action update arguments. */ 3094 [QUEUE_INDIRECT_ACTION_QUERY_POSTPONE] = { 3095 .name = "postpone", 3096 .help = "postpone query operation", 3097 .next = NEXT(next_qia_query_attr, 3098 NEXT_ENTRY(COMMON_BOOLEAN)), 3099 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3100 }, 3101 /* Indirect action create arguments. */ 3102 [QUEUE_INDIRECT_ACTION_CREATE_ID] = { 3103 .name = "action_id", 3104 .help = "specify a indirect action id to create", 3105 .next = NEXT(next_qia_create_attr, 3106 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3107 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3108 }, 3109 [QUEUE_INDIRECT_ACTION_INGRESS] = { 3110 .name = "ingress", 3111 .help = "affect rule to ingress", 3112 .next = NEXT(next_qia_create_attr), 3113 .call = parse_qia, 3114 }, 3115 [QUEUE_INDIRECT_ACTION_EGRESS] = { 3116 .name = "egress", 3117 .help = "affect rule to egress", 3118 .next = NEXT(next_qia_create_attr), 3119 .call = parse_qia, 3120 }, 3121 [QUEUE_INDIRECT_ACTION_TRANSFER] = { 3122 .name = "transfer", 3123 .help = "affect rule to transfer", 3124 .next = NEXT(next_qia_create_attr), 3125 .call = parse_qia, 3126 }, 3127 [QUEUE_INDIRECT_ACTION_CREATE_POSTPONE] = { 3128 .name = "postpone", 3129 .help = "postpone create operation", 3130 .next = NEXT(next_qia_create_attr, 3131 NEXT_ENTRY(COMMON_BOOLEAN)), 3132 .args = ARGS(ARGS_ENTRY(struct buffer, postpone)), 3133 }, 3134 [QUEUE_INDIRECT_ACTION_SPEC] = { 3135 .name = "action", 3136 .help = "specify action to create indirect handle", 3137 .next = NEXT(next_action), 3138 }, 3139 /* Top-level command. */ 3140 [PUSH] = { 3141 .name = "push", 3142 .help = "push enqueued operations", 3143 .next = NEXT(NEXT_ENTRY(PUSH_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3144 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3145 .call = parse_push, 3146 }, 3147 /* Sub-level commands. */ 3148 [PUSH_QUEUE] = { 3149 .name = "queue", 3150 .help = "specify queue id", 3151 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3152 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3153 }, 3154 /* Top-level command. */ 3155 [PULL] = { 3156 .name = "pull", 3157 .help = "pull flow operations results", 3158 .next = NEXT(NEXT_ENTRY(PULL_QUEUE), NEXT_ENTRY(COMMON_PORT_ID)), 3159 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3160 .call = parse_pull, 3161 }, 3162 /* Sub-level commands. */ 3163 [PULL_QUEUE] = { 3164 .name = "queue", 3165 .help = "specify queue id", 3166 .next = NEXT(NEXT_ENTRY(END), NEXT_ENTRY(COMMON_QUEUE_ID)), 3167 .args = ARGS(ARGS_ENTRY(struct buffer, queue)), 3168 }, 3169 /* Top-level command. */ 3170 [INDIRECT_ACTION] = { 3171 .name = "indirect_action", 3172 .type = "{command} {port_id} [{arg} [...]]", 3173 .help = "manage indirect actions", 3174 .next = NEXT(next_ia_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3175 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3176 .call = parse_ia, 3177 }, 3178 /* Sub-level commands. */ 3179 [INDIRECT_ACTION_CREATE] = { 3180 .name = "create", 3181 .help = "create indirect action", 3182 .next = NEXT(next_ia_create_attr), 3183 .call = parse_ia, 3184 }, 3185 [INDIRECT_ACTION_UPDATE] = { 3186 .name = "update", 3187 .help = "update indirect action", 3188 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_SPEC), 3189 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3190 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 3191 .call = parse_ia, 3192 }, 3193 [INDIRECT_ACTION_DESTROY] = { 3194 .name = "destroy", 3195 .help = "destroy indirect action", 3196 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_DESTROY_ID)), 3197 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3198 .call = parse_ia_destroy, 3199 }, 3200 [INDIRECT_ACTION_QUERY] = { 3201 .name = "query", 3202 .help = "query indirect action", 3203 .next = NEXT(NEXT_ENTRY(END), 3204 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 3205 .args = ARGS(ARGS_ENTRY(struct buffer, args.ia.action_id)), 3206 .call = parse_ia, 3207 }, 3208 [VALIDATE] = { 3209 .name = "validate", 3210 .help = "check whether a flow rule can be created", 3211 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 3212 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3213 .call = parse_vc, 3214 }, 3215 [CREATE] = { 3216 .name = "create", 3217 .help = "create a flow rule", 3218 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PORT_ID)), 3219 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3220 .call = parse_vc, 3221 }, 3222 [DESTROY] = { 3223 .name = "destroy", 3224 .help = "destroy specific flow rules", 3225 .next = NEXT(NEXT_ENTRY(DESTROY_RULE), 3226 NEXT_ENTRY(COMMON_PORT_ID)), 3227 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3228 .call = parse_destroy, 3229 }, 3230 [FLUSH] = { 3231 .name = "flush", 3232 .help = "destroy all flow rules", 3233 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 3234 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3235 .call = parse_flush, 3236 }, 3237 [DUMP] = { 3238 .name = "dump", 3239 .help = "dump single/all flow rules to file", 3240 .next = NEXT(next_dump_subcmd, NEXT_ENTRY(COMMON_PORT_ID)), 3241 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3242 .call = parse_dump, 3243 }, 3244 [QUERY] = { 3245 .name = "query", 3246 .help = "query an existing flow rule", 3247 .next = NEXT(NEXT_ENTRY(QUERY_ACTION), 3248 NEXT_ENTRY(COMMON_RULE_ID), 3249 NEXT_ENTRY(COMMON_PORT_ID)), 3250 .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action.type), 3251 ARGS_ENTRY(struct buffer, args.query.rule), 3252 ARGS_ENTRY(struct buffer, port)), 3253 .call = parse_query, 3254 }, 3255 [LIST] = { 3256 .name = "list", 3257 .help = "list existing flow rules", 3258 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_PORT_ID)), 3259 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3260 .call = parse_list, 3261 }, 3262 [AGED] = { 3263 .name = "aged", 3264 .help = "list and destroy aged flows", 3265 .next = NEXT(next_aged_attr, NEXT_ENTRY(COMMON_PORT_ID)), 3266 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3267 .call = parse_aged, 3268 }, 3269 [ISOLATE] = { 3270 .name = "isolate", 3271 .help = "restrict ingress traffic to the defined flow rules", 3272 .next = NEXT(NEXT_ENTRY(COMMON_BOOLEAN), 3273 NEXT_ENTRY(COMMON_PORT_ID)), 3274 .args = ARGS(ARGS_ENTRY(struct buffer, args.isolate.set), 3275 ARGS_ENTRY(struct buffer, port)), 3276 .call = parse_isolate, 3277 }, 3278 [FLEX] = { 3279 .name = "flex_item", 3280 .help = "flex item API", 3281 .next = NEXT(next_flex_item), 3282 .call = parse_flex, 3283 }, 3284 [FLEX_ITEM_INIT] = { 3285 .name = "init", 3286 .help = "flex item init", 3287 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 3288 ARGS_ENTRY(struct buffer, port)), 3289 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 3290 NEXT_ENTRY(COMMON_PORT_ID)), 3291 .call = parse_flex 3292 }, 3293 [FLEX_ITEM_CREATE] = { 3294 .name = "create", 3295 .help = "flex item create", 3296 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.filename), 3297 ARGS_ENTRY(struct buffer, args.flex.token), 3298 ARGS_ENTRY(struct buffer, port)), 3299 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH), 3300 NEXT_ENTRY(COMMON_FLEX_TOKEN), 3301 NEXT_ENTRY(COMMON_PORT_ID)), 3302 .call = parse_flex 3303 }, 3304 [FLEX_ITEM_DESTROY] = { 3305 .name = "destroy", 3306 .help = "flex item destroy", 3307 .args = ARGS(ARGS_ENTRY(struct buffer, args.flex.token), 3308 ARGS_ENTRY(struct buffer, port)), 3309 .next = NEXT(NEXT_ENTRY(COMMON_FLEX_TOKEN), 3310 NEXT_ENTRY(COMMON_PORT_ID)), 3311 .call = parse_flex 3312 }, 3313 [TUNNEL] = { 3314 .name = "tunnel", 3315 .help = "new tunnel API", 3316 .next = NEXT(NEXT_ENTRY 3317 (TUNNEL_CREATE, TUNNEL_LIST, TUNNEL_DESTROY)), 3318 .call = parse_tunnel, 3319 }, 3320 /* Tunnel arguments. */ 3321 [TUNNEL_CREATE] = { 3322 .name = "create", 3323 .help = "create new tunnel object", 3324 .next = NEXT(NEXT_ENTRY(TUNNEL_CREATE_TYPE), 3325 NEXT_ENTRY(COMMON_PORT_ID)), 3326 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3327 .call = parse_tunnel, 3328 }, 3329 [TUNNEL_CREATE_TYPE] = { 3330 .name = "type", 3331 .help = "create new tunnel", 3332 .next = NEXT(NEXT_ENTRY(COMMON_FILE_PATH)), 3333 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, type)), 3334 .call = parse_tunnel, 3335 }, 3336 [TUNNEL_DESTROY] = { 3337 .name = "destroy", 3338 .help = "destroy tunnel", 3339 .next = NEXT(NEXT_ENTRY(TUNNEL_DESTROY_ID), 3340 NEXT_ENTRY(COMMON_PORT_ID)), 3341 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3342 .call = parse_tunnel, 3343 }, 3344 [TUNNEL_DESTROY_ID] = { 3345 .name = "id", 3346 .help = "tunnel identifier to destroy", 3347 .next = NEXT(NEXT_ENTRY(COMMON_UNSIGNED)), 3348 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 3349 .call = parse_tunnel, 3350 }, 3351 [TUNNEL_LIST] = { 3352 .name = "list", 3353 .help = "list existing tunnels", 3354 .next = NEXT(NEXT_ENTRY(COMMON_PORT_ID)), 3355 .args = ARGS(ARGS_ENTRY(struct buffer, port)), 3356 .call = parse_tunnel, 3357 }, 3358 /* Destroy arguments. */ 3359 [DESTROY_RULE] = { 3360 .name = "rule", 3361 .help = "specify a rule identifier", 3362 .next = NEXT(next_destroy_attr, NEXT_ENTRY(COMMON_RULE_ID)), 3363 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)), 3364 .call = parse_destroy, 3365 }, 3366 /* Dump arguments. */ 3367 [DUMP_ALL] = { 3368 .name = "all", 3369 .help = "dump all", 3370 .next = NEXT(next_dump_attr), 3371 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file)), 3372 .call = parse_dump, 3373 }, 3374 [DUMP_ONE] = { 3375 .name = "rule", 3376 .help = "dump one rule", 3377 .next = NEXT(next_dump_attr, NEXT_ENTRY(COMMON_RULE_ID)), 3378 .args = ARGS(ARGS_ENTRY(struct buffer, args.dump.file), 3379 ARGS_ENTRY(struct buffer, args.dump.rule)), 3380 .call = parse_dump, 3381 }, 3382 /* Query arguments. */ 3383 [QUERY_ACTION] = { 3384 .name = "{action}", 3385 .type = "ACTION", 3386 .help = "action to query, must be part of the rule", 3387 .call = parse_action, 3388 .comp = comp_action, 3389 }, 3390 /* List arguments. */ 3391 [LIST_GROUP] = { 3392 .name = "group", 3393 .help = "specify a group", 3394 .next = NEXT(next_list_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3395 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)), 3396 .call = parse_list, 3397 }, 3398 [AGED_DESTROY] = { 3399 .name = "destroy", 3400 .help = "specify aged flows need be destroyed", 3401 .call = parse_aged, 3402 .comp = comp_none, 3403 }, 3404 /* Validate/create attributes. */ 3405 [VC_GROUP] = { 3406 .name = "group", 3407 .help = "specify a group", 3408 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_GROUP_ID)), 3409 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, group)), 3410 .call = parse_vc, 3411 }, 3412 [VC_PRIORITY] = { 3413 .name = "priority", 3414 .help = "specify a priority level", 3415 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_PRIORITY_LEVEL)), 3416 .args = ARGS(ARGS_ENTRY(struct rte_flow_attr, priority)), 3417 .call = parse_vc, 3418 }, 3419 [VC_INGRESS] = { 3420 .name = "ingress", 3421 .help = "affect rule to ingress", 3422 .next = NEXT(next_vc_attr), 3423 .call = parse_vc, 3424 }, 3425 [VC_EGRESS] = { 3426 .name = "egress", 3427 .help = "affect rule to egress", 3428 .next = NEXT(next_vc_attr), 3429 .call = parse_vc, 3430 }, 3431 [VC_TRANSFER] = { 3432 .name = "transfer", 3433 .help = "apply rule directly to endpoints found in pattern", 3434 .next = NEXT(next_vc_attr), 3435 .call = parse_vc, 3436 }, 3437 [VC_TUNNEL_SET] = { 3438 .name = "tunnel_set", 3439 .help = "tunnel steer rule", 3440 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 3441 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 3442 .call = parse_vc, 3443 }, 3444 [VC_TUNNEL_MATCH] = { 3445 .name = "tunnel_match", 3446 .help = "tunnel match rule", 3447 .next = NEXT(next_vc_attr, NEXT_ENTRY(COMMON_UNSIGNED)), 3448 .args = ARGS(ARGS_ENTRY(struct tunnel_ops, id)), 3449 .call = parse_vc, 3450 }, 3451 /* Validate/create pattern. */ 3452 [ITEM_PATTERN] = { 3453 .name = "pattern", 3454 .help = "submit a list of pattern items", 3455 .next = NEXT(next_item), 3456 .call = parse_vc, 3457 }, 3458 [ITEM_PARAM_IS] = { 3459 .name = "is", 3460 .help = "match value perfectly (with full bit-mask)", 3461 .call = parse_vc_spec, 3462 }, 3463 [ITEM_PARAM_SPEC] = { 3464 .name = "spec", 3465 .help = "match value according to configured bit-mask", 3466 .call = parse_vc_spec, 3467 }, 3468 [ITEM_PARAM_LAST] = { 3469 .name = "last", 3470 .help = "specify upper bound to establish a range", 3471 .call = parse_vc_spec, 3472 }, 3473 [ITEM_PARAM_MASK] = { 3474 .name = "mask", 3475 .help = "specify bit-mask with relevant bits set to one", 3476 .call = parse_vc_spec, 3477 }, 3478 [ITEM_PARAM_PREFIX] = { 3479 .name = "prefix", 3480 .help = "generate bit-mask from a prefix length", 3481 .call = parse_vc_spec, 3482 }, 3483 [ITEM_NEXT] = { 3484 .name = "/", 3485 .help = "specify next pattern item", 3486 .next = NEXT(next_item), 3487 }, 3488 [ITEM_END] = { 3489 .name = "end", 3490 .help = "end list of pattern items", 3491 .priv = PRIV_ITEM(END, 0), 3492 .next = NEXT(NEXT_ENTRY(ACTIONS, END)), 3493 .call = parse_vc, 3494 }, 3495 [ITEM_VOID] = { 3496 .name = "void", 3497 .help = "no-op pattern item", 3498 .priv = PRIV_ITEM(VOID, 0), 3499 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 3500 .call = parse_vc, 3501 }, 3502 [ITEM_INVERT] = { 3503 .name = "invert", 3504 .help = "perform actions when pattern does not match", 3505 .priv = PRIV_ITEM(INVERT, 0), 3506 .next = NEXT(NEXT_ENTRY(ITEM_NEXT)), 3507 .call = parse_vc, 3508 }, 3509 [ITEM_ANY] = { 3510 .name = "any", 3511 .help = "match any protocol for the current layer", 3512 .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)), 3513 .next = NEXT(item_any), 3514 .call = parse_vc, 3515 }, 3516 [ITEM_ANY_NUM] = { 3517 .name = "num", 3518 .help = "number of layers covered", 3519 .next = NEXT(item_any, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 3520 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, num)), 3521 }, 3522 [ITEM_PORT_ID] = { 3523 .name = "port_id", 3524 .help = "match traffic from/to a given DPDK port ID", 3525 .priv = PRIV_ITEM(PORT_ID, 3526 sizeof(struct rte_flow_item_port_id)), 3527 .next = NEXT(item_port_id), 3528 .call = parse_vc, 3529 }, 3530 [ITEM_PORT_ID_ID] = { 3531 .name = "id", 3532 .help = "DPDK port ID", 3533 .next = NEXT(item_port_id, NEXT_ENTRY(COMMON_UNSIGNED), 3534 item_param), 3535 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port_id, id)), 3536 }, 3537 [ITEM_MARK] = { 3538 .name = "mark", 3539 .help = "match traffic against value set in previously matched rule", 3540 .priv = PRIV_ITEM(MARK, sizeof(struct rte_flow_item_mark)), 3541 .next = NEXT(item_mark), 3542 .call = parse_vc, 3543 }, 3544 [ITEM_MARK_ID] = { 3545 .name = "id", 3546 .help = "Integer value to match against", 3547 .next = NEXT(item_mark, NEXT_ENTRY(COMMON_UNSIGNED), 3548 item_param), 3549 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_mark, id)), 3550 }, 3551 [ITEM_RAW] = { 3552 .name = "raw", 3553 .help = "match an arbitrary byte string", 3554 .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE), 3555 .next = NEXT(item_raw), 3556 .call = parse_vc, 3557 }, 3558 [ITEM_RAW_RELATIVE] = { 3559 .name = "relative", 3560 .help = "look for pattern after the previous item", 3561 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 3562 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 3563 relative, 1)), 3564 }, 3565 [ITEM_RAW_SEARCH] = { 3566 .name = "search", 3567 .help = "search pattern from offset (see also limit)", 3568 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 3569 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_raw, 3570 search, 1)), 3571 }, 3572 [ITEM_RAW_OFFSET] = { 3573 .name = "offset", 3574 .help = "absolute or relative offset for pattern", 3575 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_INTEGER), item_param), 3576 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, offset)), 3577 }, 3578 [ITEM_RAW_LIMIT] = { 3579 .name = "limit", 3580 .help = "search area limit for start of pattern", 3581 .next = NEXT(item_raw, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 3582 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, limit)), 3583 }, 3584 [ITEM_RAW_PATTERN] = { 3585 .name = "pattern", 3586 .help = "byte string to look for", 3587 .next = NEXT(item_raw, 3588 NEXT_ENTRY(COMMON_STRING), 3589 NEXT_ENTRY(ITEM_PARAM_IS, 3590 ITEM_PARAM_SPEC, 3591 ITEM_PARAM_MASK)), 3592 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 3593 ARGS_ENTRY(struct rte_flow_item_raw, length), 3594 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 3595 ITEM_RAW_PATTERN_SIZE)), 3596 }, 3597 [ITEM_RAW_PATTERN_HEX] = { 3598 .name = "pattern_hex", 3599 .help = "hex string to look for", 3600 .next = NEXT(item_raw, 3601 NEXT_ENTRY(COMMON_HEX), 3602 NEXT_ENTRY(ITEM_PARAM_IS, 3603 ITEM_PARAM_SPEC, 3604 ITEM_PARAM_MASK)), 3605 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_raw, pattern), 3606 ARGS_ENTRY(struct rte_flow_item_raw, length), 3607 ARGS_ENTRY_ARB(sizeof(struct rte_flow_item_raw), 3608 ITEM_RAW_PATTERN_SIZE)), 3609 }, 3610 [ITEM_ETH] = { 3611 .name = "eth", 3612 .help = "match Ethernet header", 3613 .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)), 3614 .next = NEXT(item_eth), 3615 .call = parse_vc, 3616 }, 3617 [ITEM_ETH_DST] = { 3618 .name = "dst", 3619 .help = "destination MAC", 3620 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 3621 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, dst)), 3622 }, 3623 [ITEM_ETH_SRC] = { 3624 .name = "src", 3625 .help = "source MAC", 3626 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 3627 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, src)), 3628 }, 3629 [ITEM_ETH_TYPE] = { 3630 .name = "type", 3631 .help = "EtherType", 3632 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 3633 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, type)), 3634 }, 3635 [ITEM_ETH_HAS_VLAN] = { 3636 .name = "has_vlan", 3637 .help = "packet header contains VLAN", 3638 .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 3639 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_eth, 3640 has_vlan, 1)), 3641 }, 3642 [ITEM_VLAN] = { 3643 .name = "vlan", 3644 .help = "match 802.1Q/ad VLAN tag", 3645 .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)), 3646 .next = NEXT(item_vlan), 3647 .call = parse_vc, 3648 }, 3649 [ITEM_VLAN_TCI] = { 3650 .name = "tci", 3651 .help = "tag control information", 3652 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 3653 item_param), 3654 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)), 3655 }, 3656 [ITEM_VLAN_PCP] = { 3657 .name = "pcp", 3658 .help = "priority code point", 3659 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 3660 item_param), 3661 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 3662 tci, "\xe0\x00")), 3663 }, 3664 [ITEM_VLAN_DEI] = { 3665 .name = "dei", 3666 .help = "drop eligible indicator", 3667 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 3668 item_param), 3669 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 3670 tci, "\x10\x00")), 3671 }, 3672 [ITEM_VLAN_VID] = { 3673 .name = "vid", 3674 .help = "VLAN identifier", 3675 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 3676 item_param), 3677 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_vlan, 3678 tci, "\x0f\xff")), 3679 }, 3680 [ITEM_VLAN_INNER_TYPE] = { 3681 .name = "inner_type", 3682 .help = "inner EtherType", 3683 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 3684 item_param), 3685 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, 3686 inner_type)), 3687 }, 3688 [ITEM_VLAN_HAS_MORE_VLAN] = { 3689 .name = "has_more_vlan", 3690 .help = "packet header contains another VLAN", 3691 .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), 3692 item_param), 3693 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_vlan, 3694 has_more_vlan, 1)), 3695 }, 3696 [ITEM_IPV4] = { 3697 .name = "ipv4", 3698 .help = "match IPv4 header", 3699 .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)), 3700 .next = NEXT(item_ipv4), 3701 .call = parse_vc, 3702 }, 3703 [ITEM_IPV4_VER_IHL] = { 3704 .name = "version_ihl", 3705 .help = "match header length", 3706 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 3707 item_param), 3708 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv4, 3709 hdr.version_ihl)), 3710 }, 3711 [ITEM_IPV4_TOS] = { 3712 .name = "tos", 3713 .help = "type of service", 3714 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 3715 item_param), 3716 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 3717 hdr.type_of_service)), 3718 }, 3719 [ITEM_IPV4_ID] = { 3720 .name = "packet_id", 3721 .help = "fragment packet id", 3722 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 3723 item_param), 3724 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 3725 hdr.packet_id)), 3726 }, 3727 [ITEM_IPV4_FRAGMENT_OFFSET] = { 3728 .name = "fragment_offset", 3729 .help = "fragmentation flags and fragment offset", 3730 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 3731 item_param), 3732 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 3733 hdr.fragment_offset)), 3734 }, 3735 [ITEM_IPV4_TTL] = { 3736 .name = "ttl", 3737 .help = "time to live", 3738 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 3739 item_param), 3740 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 3741 hdr.time_to_live)), 3742 }, 3743 [ITEM_IPV4_PROTO] = { 3744 .name = "proto", 3745 .help = "next protocol ID", 3746 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_UNSIGNED), 3747 item_param), 3748 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 3749 hdr.next_proto_id)), 3750 }, 3751 [ITEM_IPV4_SRC] = { 3752 .name = "src", 3753 .help = "source address", 3754 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 3755 item_param), 3756 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 3757 hdr.src_addr)), 3758 }, 3759 [ITEM_IPV4_DST] = { 3760 .name = "dst", 3761 .help = "destination address", 3762 .next = NEXT(item_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 3763 item_param), 3764 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4, 3765 hdr.dst_addr)), 3766 }, 3767 [ITEM_IPV6] = { 3768 .name = "ipv6", 3769 .help = "match IPv6 header", 3770 .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)), 3771 .next = NEXT(item_ipv6), 3772 .call = parse_vc, 3773 }, 3774 [ITEM_IPV6_TC] = { 3775 .name = "tc", 3776 .help = "traffic class", 3777 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 3778 item_param), 3779 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 3780 hdr.vtc_flow, 3781 "\x0f\xf0\x00\x00")), 3782 }, 3783 [ITEM_IPV6_FLOW] = { 3784 .name = "flow", 3785 .help = "flow label", 3786 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 3787 item_param), 3788 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_ipv6, 3789 hdr.vtc_flow, 3790 "\x00\x0f\xff\xff")), 3791 }, 3792 [ITEM_IPV6_PROTO] = { 3793 .name = "proto", 3794 .help = "protocol (next header)", 3795 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 3796 item_param), 3797 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 3798 hdr.proto)), 3799 }, 3800 [ITEM_IPV6_HOP] = { 3801 .name = "hop", 3802 .help = "hop limit", 3803 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 3804 item_param), 3805 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 3806 hdr.hop_limits)), 3807 }, 3808 [ITEM_IPV6_SRC] = { 3809 .name = "src", 3810 .help = "source address", 3811 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 3812 item_param), 3813 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 3814 hdr.src_addr)), 3815 }, 3816 [ITEM_IPV6_DST] = { 3817 .name = "dst", 3818 .help = "destination address", 3819 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_IPV6_ADDR), 3820 item_param), 3821 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6, 3822 hdr.dst_addr)), 3823 }, 3824 [ITEM_IPV6_HAS_FRAG_EXT] = { 3825 .name = "has_frag_ext", 3826 .help = "fragment packet attribute", 3827 .next = NEXT(item_ipv6, NEXT_ENTRY(COMMON_UNSIGNED), 3828 item_param), 3829 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6, 3830 has_frag_ext, 1)), 3831 }, 3832 [ITEM_ICMP] = { 3833 .name = "icmp", 3834 .help = "match ICMP header", 3835 .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)), 3836 .next = NEXT(item_icmp), 3837 .call = parse_vc, 3838 }, 3839 [ITEM_ICMP_TYPE] = { 3840 .name = "type", 3841 .help = "ICMP packet type", 3842 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 3843 item_param), 3844 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 3845 hdr.icmp_type)), 3846 }, 3847 [ITEM_ICMP_CODE] = { 3848 .name = "code", 3849 .help = "ICMP packet code", 3850 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 3851 item_param), 3852 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 3853 hdr.icmp_code)), 3854 }, 3855 [ITEM_ICMP_IDENT] = { 3856 .name = "ident", 3857 .help = "ICMP packet identifier", 3858 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 3859 item_param), 3860 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 3861 hdr.icmp_ident)), 3862 }, 3863 [ITEM_ICMP_SEQ] = { 3864 .name = "seq", 3865 .help = "ICMP packet sequence number", 3866 .next = NEXT(item_icmp, NEXT_ENTRY(COMMON_UNSIGNED), 3867 item_param), 3868 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp, 3869 hdr.icmp_seq_nb)), 3870 }, 3871 [ITEM_UDP] = { 3872 .name = "udp", 3873 .help = "match UDP header", 3874 .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)), 3875 .next = NEXT(item_udp), 3876 .call = parse_vc, 3877 }, 3878 [ITEM_UDP_SRC] = { 3879 .name = "src", 3880 .help = "UDP source port", 3881 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), 3882 item_param), 3883 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 3884 hdr.src_port)), 3885 }, 3886 [ITEM_UDP_DST] = { 3887 .name = "dst", 3888 .help = "UDP destination port", 3889 .next = NEXT(item_udp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 3890 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp, 3891 hdr.dst_port)), 3892 }, 3893 [ITEM_TCP] = { 3894 .name = "tcp", 3895 .help = "match TCP header", 3896 .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)), 3897 .next = NEXT(item_tcp), 3898 .call = parse_vc, 3899 }, 3900 [ITEM_TCP_SRC] = { 3901 .name = "src", 3902 .help = "TCP source port", 3903 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 3904 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 3905 hdr.src_port)), 3906 }, 3907 [ITEM_TCP_DST] = { 3908 .name = "dst", 3909 .help = "TCP destination port", 3910 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 3911 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 3912 hdr.dst_port)), 3913 }, 3914 [ITEM_TCP_FLAGS] = { 3915 .name = "flags", 3916 .help = "TCP flags", 3917 .next = NEXT(item_tcp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 3918 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp, 3919 hdr.tcp_flags)), 3920 }, 3921 [ITEM_SCTP] = { 3922 .name = "sctp", 3923 .help = "match SCTP header", 3924 .priv = PRIV_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)), 3925 .next = NEXT(item_sctp), 3926 .call = parse_vc, 3927 }, 3928 [ITEM_SCTP_SRC] = { 3929 .name = "src", 3930 .help = "SCTP source port", 3931 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 3932 item_param), 3933 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 3934 hdr.src_port)), 3935 }, 3936 [ITEM_SCTP_DST] = { 3937 .name = "dst", 3938 .help = "SCTP destination port", 3939 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 3940 item_param), 3941 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 3942 hdr.dst_port)), 3943 }, 3944 [ITEM_SCTP_TAG] = { 3945 .name = "tag", 3946 .help = "validation tag", 3947 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 3948 item_param), 3949 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 3950 hdr.tag)), 3951 }, 3952 [ITEM_SCTP_CKSUM] = { 3953 .name = "cksum", 3954 .help = "checksum", 3955 .next = NEXT(item_sctp, NEXT_ENTRY(COMMON_UNSIGNED), 3956 item_param), 3957 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_sctp, 3958 hdr.cksum)), 3959 }, 3960 [ITEM_VXLAN] = { 3961 .name = "vxlan", 3962 .help = "match VXLAN header", 3963 .priv = PRIV_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)), 3964 .next = NEXT(item_vxlan), 3965 .call = parse_vc, 3966 }, 3967 [ITEM_VXLAN_VNI] = { 3968 .name = "vni", 3969 .help = "VXLAN identifier", 3970 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 3971 item_param), 3972 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)), 3973 }, 3974 [ITEM_VXLAN_LAST_RSVD] = { 3975 .name = "last_rsvd", 3976 .help = "VXLAN last reserved bits", 3977 .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), 3978 item_param), 3979 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, 3980 rsvd1)), 3981 }, 3982 [ITEM_E_TAG] = { 3983 .name = "e_tag", 3984 .help = "match E-Tag header", 3985 .priv = PRIV_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)), 3986 .next = NEXT(item_e_tag), 3987 .call = parse_vc, 3988 }, 3989 [ITEM_E_TAG_GRP_ECID_B] = { 3990 .name = "grp_ecid_b", 3991 .help = "GRP and E-CID base", 3992 .next = NEXT(item_e_tag, NEXT_ENTRY(COMMON_UNSIGNED), 3993 item_param), 3994 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_e_tag, 3995 rsvd_grp_ecid_b, 3996 "\x3f\xff")), 3997 }, 3998 [ITEM_NVGRE] = { 3999 .name = "nvgre", 4000 .help = "match NVGRE header", 4001 .priv = PRIV_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)), 4002 .next = NEXT(item_nvgre), 4003 .call = parse_vc, 4004 }, 4005 [ITEM_NVGRE_TNI] = { 4006 .name = "tni", 4007 .help = "virtual subnet ID", 4008 .next = NEXT(item_nvgre, NEXT_ENTRY(COMMON_UNSIGNED), 4009 item_param), 4010 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_nvgre, tni)), 4011 }, 4012 [ITEM_MPLS] = { 4013 .name = "mpls", 4014 .help = "match MPLS header", 4015 .priv = PRIV_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)), 4016 .next = NEXT(item_mpls), 4017 .call = parse_vc, 4018 }, 4019 [ITEM_MPLS_LABEL] = { 4020 .name = "label", 4021 .help = "MPLS label", 4022 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4023 item_param), 4024 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4025 label_tc_s, 4026 "\xff\xff\xf0")), 4027 }, 4028 [ITEM_MPLS_TC] = { 4029 .name = "tc", 4030 .help = "MPLS Traffic Class", 4031 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4032 item_param), 4033 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4034 label_tc_s, 4035 "\x00\x00\x0e")), 4036 }, 4037 [ITEM_MPLS_S] = { 4038 .name = "s", 4039 .help = "MPLS Bottom-of-Stack", 4040 .next = NEXT(item_mpls, NEXT_ENTRY(COMMON_UNSIGNED), 4041 item_param), 4042 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_mpls, 4043 label_tc_s, 4044 "\x00\x00\x01")), 4045 }, 4046 [ITEM_GRE] = { 4047 .name = "gre", 4048 .help = "match GRE header", 4049 .priv = PRIV_ITEM(GRE, sizeof(struct rte_flow_item_gre)), 4050 .next = NEXT(item_gre), 4051 .call = parse_vc, 4052 }, 4053 [ITEM_GRE_PROTO] = { 4054 .name = "protocol", 4055 .help = "GRE protocol type", 4056 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 4057 item_param), 4058 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 4059 protocol)), 4060 }, 4061 [ITEM_GRE_C_RSVD0_VER] = { 4062 .name = "c_rsvd0_ver", 4063 .help = 4064 "checksum (1b), undefined (1b), key bit (1b)," 4065 " sequence number (1b), reserved 0 (9b)," 4066 " version (3b)", 4067 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), 4068 item_param), 4069 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, 4070 c_rsvd0_ver)), 4071 }, 4072 [ITEM_GRE_C_BIT] = { 4073 .name = "c_bit", 4074 .help = "checksum bit (C)", 4075 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), 4076 item_param), 4077 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 4078 c_rsvd0_ver, 4079 "\x80\x00\x00\x00")), 4080 }, 4081 [ITEM_GRE_S_BIT] = { 4082 .name = "s_bit", 4083 .help = "sequence number bit (S)", 4084 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4085 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 4086 c_rsvd0_ver, 4087 "\x10\x00\x00\x00")), 4088 }, 4089 [ITEM_GRE_K_BIT] = { 4090 .name = "k_bit", 4091 .help = "key bit (K)", 4092 .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), 4093 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, 4094 c_rsvd0_ver, 4095 "\x20\x00\x00\x00")), 4096 }, 4097 [ITEM_FUZZY] = { 4098 .name = "fuzzy", 4099 .help = "fuzzy pattern match, expect faster than default", 4100 .priv = PRIV_ITEM(FUZZY, 4101 sizeof(struct rte_flow_item_fuzzy)), 4102 .next = NEXT(item_fuzzy), 4103 .call = parse_vc, 4104 }, 4105 [ITEM_FUZZY_THRESH] = { 4106 .name = "thresh", 4107 .help = "match accuracy threshold", 4108 .next = NEXT(item_fuzzy, NEXT_ENTRY(COMMON_UNSIGNED), 4109 item_param), 4110 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_fuzzy, 4111 thresh)), 4112 }, 4113 [ITEM_GTP] = { 4114 .name = "gtp", 4115 .help = "match GTP header", 4116 .priv = PRIV_ITEM(GTP, sizeof(struct rte_flow_item_gtp)), 4117 .next = NEXT(item_gtp), 4118 .call = parse_vc, 4119 }, 4120 [ITEM_GTP_FLAGS] = { 4121 .name = "v_pt_rsv_flags", 4122 .help = "GTP flags", 4123 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4124 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, 4125 v_pt_rsv_flags)), 4126 }, 4127 [ITEM_GTP_MSG_TYPE] = { 4128 .name = "msg_type", 4129 .help = "GTP message type", 4130 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4131 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, msg_type)), 4132 }, 4133 [ITEM_GTP_TEID] = { 4134 .name = "teid", 4135 .help = "tunnel endpoint identifier", 4136 .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4137 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, teid)), 4138 }, 4139 [ITEM_GTPC] = { 4140 .name = "gtpc", 4141 .help = "match GTP header", 4142 .priv = PRIV_ITEM(GTPC, sizeof(struct rte_flow_item_gtp)), 4143 .next = NEXT(item_gtp), 4144 .call = parse_vc, 4145 }, 4146 [ITEM_GTPU] = { 4147 .name = "gtpu", 4148 .help = "match GTP header", 4149 .priv = PRIV_ITEM(GTPU, sizeof(struct rte_flow_item_gtp)), 4150 .next = NEXT(item_gtp), 4151 .call = parse_vc, 4152 }, 4153 [ITEM_GENEVE] = { 4154 .name = "geneve", 4155 .help = "match GENEVE header", 4156 .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)), 4157 .next = NEXT(item_geneve), 4158 .call = parse_vc, 4159 }, 4160 [ITEM_GENEVE_VNI] = { 4161 .name = "vni", 4162 .help = "virtual network identifier", 4163 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 4164 item_param), 4165 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)), 4166 }, 4167 [ITEM_GENEVE_PROTO] = { 4168 .name = "protocol", 4169 .help = "GENEVE protocol type", 4170 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 4171 item_param), 4172 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, 4173 protocol)), 4174 }, 4175 [ITEM_GENEVE_OPTLEN] = { 4176 .name = "optlen", 4177 .help = "GENEVE options length in dwords", 4178 .next = NEXT(item_geneve, NEXT_ENTRY(COMMON_UNSIGNED), 4179 item_param), 4180 .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_geneve, 4181 ver_opt_len_o_c_rsvd0, 4182 "\x3f\x00")), 4183 }, 4184 [ITEM_VXLAN_GPE] = { 4185 .name = "vxlan-gpe", 4186 .help = "match VXLAN-GPE header", 4187 .priv = PRIV_ITEM(VXLAN_GPE, 4188 sizeof(struct rte_flow_item_vxlan_gpe)), 4189 .next = NEXT(item_vxlan_gpe), 4190 .call = parse_vc, 4191 }, 4192 [ITEM_VXLAN_GPE_VNI] = { 4193 .name = "vni", 4194 .help = "VXLAN-GPE identifier", 4195 .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), 4196 item_param), 4197 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, 4198 vni)), 4199 }, 4200 [ITEM_ARP_ETH_IPV4] = { 4201 .name = "arp_eth_ipv4", 4202 .help = "match ARP header for Ethernet/IPv4", 4203 .priv = PRIV_ITEM(ARP_ETH_IPV4, 4204 sizeof(struct rte_flow_item_arp_eth_ipv4)), 4205 .next = NEXT(item_arp_eth_ipv4), 4206 .call = parse_vc, 4207 }, 4208 [ITEM_ARP_ETH_IPV4_SHA] = { 4209 .name = "sha", 4210 .help = "sender hardware address", 4211 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 4212 item_param), 4213 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 4214 sha)), 4215 }, 4216 [ITEM_ARP_ETH_IPV4_SPA] = { 4217 .name = "spa", 4218 .help = "sender IPv4 address", 4219 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4220 item_param), 4221 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 4222 spa)), 4223 }, 4224 [ITEM_ARP_ETH_IPV4_THA] = { 4225 .name = "tha", 4226 .help = "target hardware address", 4227 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), 4228 item_param), 4229 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 4230 tha)), 4231 }, 4232 [ITEM_ARP_ETH_IPV4_TPA] = { 4233 .name = "tpa", 4234 .help = "target IPv4 address", 4235 .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), 4236 item_param), 4237 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, 4238 tpa)), 4239 }, 4240 [ITEM_IPV6_EXT] = { 4241 .name = "ipv6_ext", 4242 .help = "match presence of any IPv6 extension header", 4243 .priv = PRIV_ITEM(IPV6_EXT, 4244 sizeof(struct rte_flow_item_ipv6_ext)), 4245 .next = NEXT(item_ipv6_ext), 4246 .call = parse_vc, 4247 }, 4248 [ITEM_IPV6_EXT_NEXT_HDR] = { 4249 .name = "next_hdr", 4250 .help = "next header", 4251 .next = NEXT(item_ipv6_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4252 item_param), 4253 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_ext, 4254 next_hdr)), 4255 }, 4256 [ITEM_IPV6_FRAG_EXT] = { 4257 .name = "ipv6_frag_ext", 4258 .help = "match presence of IPv6 fragment extension header", 4259 .priv = PRIV_ITEM(IPV6_FRAG_EXT, 4260 sizeof(struct rte_flow_item_ipv6_frag_ext)), 4261 .next = NEXT(item_ipv6_frag_ext), 4262 .call = parse_vc, 4263 }, 4264 [ITEM_IPV6_FRAG_EXT_NEXT_HDR] = { 4265 .name = "next_hdr", 4266 .help = "next header", 4267 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4268 item_param), 4269 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ipv6_frag_ext, 4270 hdr.next_header)), 4271 }, 4272 [ITEM_IPV6_FRAG_EXT_FRAG_DATA] = { 4273 .name = "frag_data", 4274 .help = "fragment flags and offset", 4275 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4276 item_param), 4277 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 4278 hdr.frag_data)), 4279 }, 4280 [ITEM_IPV6_FRAG_EXT_ID] = { 4281 .name = "packet_id", 4282 .help = "fragment packet id", 4283 .next = NEXT(item_ipv6_frag_ext, NEXT_ENTRY(COMMON_UNSIGNED), 4284 item_param), 4285 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_frag_ext, 4286 hdr.id)), 4287 }, 4288 [ITEM_ICMP6] = { 4289 .name = "icmp6", 4290 .help = "match any ICMPv6 header", 4291 .priv = PRIV_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)), 4292 .next = NEXT(item_icmp6), 4293 .call = parse_vc, 4294 }, 4295 [ITEM_ICMP6_TYPE] = { 4296 .name = "type", 4297 .help = "ICMPv6 type", 4298 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 4299 item_param), 4300 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 4301 type)), 4302 }, 4303 [ITEM_ICMP6_CODE] = { 4304 .name = "code", 4305 .help = "ICMPv6 code", 4306 .next = NEXT(item_icmp6, NEXT_ENTRY(COMMON_UNSIGNED), 4307 item_param), 4308 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, 4309 code)), 4310 }, 4311 [ITEM_ICMP6_ND_NS] = { 4312 .name = "icmp6_nd_ns", 4313 .help = "match ICMPv6 neighbor discovery solicitation", 4314 .priv = PRIV_ITEM(ICMP6_ND_NS, 4315 sizeof(struct rte_flow_item_icmp6_nd_ns)), 4316 .next = NEXT(item_icmp6_nd_ns), 4317 .call = parse_vc, 4318 }, 4319 [ITEM_ICMP6_ND_NS_TARGET_ADDR] = { 4320 .name = "target_addr", 4321 .help = "target address", 4322 .next = NEXT(item_icmp6_nd_ns, NEXT_ENTRY(COMMON_IPV6_ADDR), 4323 item_param), 4324 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_ns, 4325 target_addr)), 4326 }, 4327 [ITEM_ICMP6_ND_NA] = { 4328 .name = "icmp6_nd_na", 4329 .help = "match ICMPv6 neighbor discovery advertisement", 4330 .priv = PRIV_ITEM(ICMP6_ND_NA, 4331 sizeof(struct rte_flow_item_icmp6_nd_na)), 4332 .next = NEXT(item_icmp6_nd_na), 4333 .call = parse_vc, 4334 }, 4335 [ITEM_ICMP6_ND_NA_TARGET_ADDR] = { 4336 .name = "target_addr", 4337 .help = "target address", 4338 .next = NEXT(item_icmp6_nd_na, NEXT_ENTRY(COMMON_IPV6_ADDR), 4339 item_param), 4340 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_na, 4341 target_addr)), 4342 }, 4343 [ITEM_ICMP6_ND_OPT] = { 4344 .name = "icmp6_nd_opt", 4345 .help = "match presence of any ICMPv6 neighbor discovery" 4346 " option", 4347 .priv = PRIV_ITEM(ICMP6_ND_OPT, 4348 sizeof(struct rte_flow_item_icmp6_nd_opt)), 4349 .next = NEXT(item_icmp6_nd_opt), 4350 .call = parse_vc, 4351 }, 4352 [ITEM_ICMP6_ND_OPT_TYPE] = { 4353 .name = "type", 4354 .help = "ND option type", 4355 .next = NEXT(item_icmp6_nd_opt, NEXT_ENTRY(COMMON_UNSIGNED), 4356 item_param), 4357 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_nd_opt, 4358 type)), 4359 }, 4360 [ITEM_ICMP6_ND_OPT_SLA_ETH] = { 4361 .name = "icmp6_nd_opt_sla_eth", 4362 .help = "match ICMPv6 neighbor discovery source Ethernet" 4363 " link-layer address option", 4364 .priv = PRIV_ITEM 4365 (ICMP6_ND_OPT_SLA_ETH, 4366 sizeof(struct rte_flow_item_icmp6_nd_opt_sla_eth)), 4367 .next = NEXT(item_icmp6_nd_opt_sla_eth), 4368 .call = parse_vc, 4369 }, 4370 [ITEM_ICMP6_ND_OPT_SLA_ETH_SLA] = { 4371 .name = "sla", 4372 .help = "source Ethernet LLA", 4373 .next = NEXT(item_icmp6_nd_opt_sla_eth, 4374 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4375 .args = ARGS(ARGS_ENTRY_HTON 4376 (struct rte_flow_item_icmp6_nd_opt_sla_eth, sla)), 4377 }, 4378 [ITEM_ICMP6_ND_OPT_TLA_ETH] = { 4379 .name = "icmp6_nd_opt_tla_eth", 4380 .help = "match ICMPv6 neighbor discovery target Ethernet" 4381 " link-layer address option", 4382 .priv = PRIV_ITEM 4383 (ICMP6_ND_OPT_TLA_ETH, 4384 sizeof(struct rte_flow_item_icmp6_nd_opt_tla_eth)), 4385 .next = NEXT(item_icmp6_nd_opt_tla_eth), 4386 .call = parse_vc, 4387 }, 4388 [ITEM_ICMP6_ND_OPT_TLA_ETH_TLA] = { 4389 .name = "tla", 4390 .help = "target Ethernet LLA", 4391 .next = NEXT(item_icmp6_nd_opt_tla_eth, 4392 NEXT_ENTRY(COMMON_MAC_ADDR), item_param), 4393 .args = ARGS(ARGS_ENTRY_HTON 4394 (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), 4395 }, 4396 [ITEM_META] = { 4397 .name = "meta", 4398 .help = "match metadata header", 4399 .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), 4400 .next = NEXT(item_meta), 4401 .call = parse_vc, 4402 }, 4403 [ITEM_META_DATA] = { 4404 .name = "data", 4405 .help = "metadata value", 4406 .next = NEXT(item_meta, NEXT_ENTRY(COMMON_UNSIGNED), 4407 item_param), 4408 .args = ARGS(ARGS_ENTRY_MASK(struct rte_flow_item_meta, 4409 data, "\xff\xff\xff\xff")), 4410 }, 4411 [ITEM_GRE_KEY] = { 4412 .name = "gre_key", 4413 .help = "match GRE key", 4414 .priv = PRIV_ITEM(GRE_KEY, sizeof(rte_be32_t)), 4415 .next = NEXT(item_gre_key), 4416 .call = parse_vc, 4417 }, 4418 [ITEM_GRE_KEY_VALUE] = { 4419 .name = "value", 4420 .help = "key value", 4421 .next = NEXT(item_gre_key, NEXT_ENTRY(COMMON_UNSIGNED), 4422 item_param), 4423 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 4424 }, 4425 [ITEM_GRE_OPTION] = { 4426 .name = "gre_option", 4427 .help = "match GRE optional fields", 4428 .priv = PRIV_ITEM(GRE_OPTION, 4429 sizeof(struct rte_flow_item_gre_opt)), 4430 .next = NEXT(item_gre_option), 4431 .call = parse_vc, 4432 }, 4433 [ITEM_GRE_OPTION_CHECKSUM] = { 4434 .name = "checksum", 4435 .help = "match GRE checksum", 4436 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 4437 item_param), 4438 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 4439 checksum_rsvd.checksum)), 4440 }, 4441 [ITEM_GRE_OPTION_KEY] = { 4442 .name = "key", 4443 .help = "match GRE key", 4444 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 4445 item_param), 4446 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 4447 key.key)), 4448 }, 4449 [ITEM_GRE_OPTION_SEQUENCE] = { 4450 .name = "sequence", 4451 .help = "match GRE sequence", 4452 .next = NEXT(item_gre_option, NEXT_ENTRY(COMMON_UNSIGNED), 4453 item_param), 4454 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre_opt, 4455 sequence.sequence)), 4456 }, 4457 [ITEM_GTP_PSC] = { 4458 .name = "gtp_psc", 4459 .help = "match GTP extension header with type 0x85", 4460 .priv = PRIV_ITEM(GTP_PSC, 4461 sizeof(struct rte_flow_item_gtp_psc)), 4462 .next = NEXT(item_gtp_psc), 4463 .call = parse_vc, 4464 }, 4465 [ITEM_GTP_PSC_QFI] = { 4466 .name = "qfi", 4467 .help = "QoS flow identifier", 4468 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 4469 item_param), 4470 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 4471 hdr.qfi, 6)), 4472 }, 4473 [ITEM_GTP_PSC_PDU_T] = { 4474 .name = "pdu_t", 4475 .help = "PDU type", 4476 .next = NEXT(item_gtp_psc, NEXT_ENTRY(COMMON_UNSIGNED), 4477 item_param), 4478 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_gtp_psc, 4479 hdr.type, 4)), 4480 }, 4481 [ITEM_PPPOES] = { 4482 .name = "pppoes", 4483 .help = "match PPPoE session header", 4484 .priv = PRIV_ITEM(PPPOES, sizeof(struct rte_flow_item_pppoe)), 4485 .next = NEXT(item_pppoes), 4486 .call = parse_vc, 4487 }, 4488 [ITEM_PPPOED] = { 4489 .name = "pppoed", 4490 .help = "match PPPoE discovery header", 4491 .priv = PRIV_ITEM(PPPOED, sizeof(struct rte_flow_item_pppoe)), 4492 .next = NEXT(item_pppoed), 4493 .call = parse_vc, 4494 }, 4495 [ITEM_PPPOE_SEID] = { 4496 .name = "seid", 4497 .help = "session identifier", 4498 .next = NEXT(item_pppoes, NEXT_ENTRY(COMMON_UNSIGNED), 4499 item_param), 4500 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pppoe, 4501 session_id)), 4502 }, 4503 [ITEM_PPPOE_PROTO_ID] = { 4504 .name = "pppoe_proto_id", 4505 .help = "match PPPoE session protocol identifier", 4506 .priv = PRIV_ITEM(PPPOE_PROTO_ID, 4507 sizeof(struct rte_flow_item_pppoe_proto_id)), 4508 .next = NEXT(item_pppoe_proto_id, NEXT_ENTRY(COMMON_UNSIGNED), 4509 item_param), 4510 .args = ARGS(ARGS_ENTRY_HTON 4511 (struct rte_flow_item_pppoe_proto_id, proto_id)), 4512 .call = parse_vc, 4513 }, 4514 [ITEM_HIGIG2] = { 4515 .name = "higig2", 4516 .help = "matches higig2 header", 4517 .priv = PRIV_ITEM(HIGIG2, 4518 sizeof(struct rte_flow_item_higig2_hdr)), 4519 .next = NEXT(item_higig2), 4520 .call = parse_vc, 4521 }, 4522 [ITEM_HIGIG2_CLASSIFICATION] = { 4523 .name = "classification", 4524 .help = "matches classification of higig2 header", 4525 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 4526 item_param), 4527 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 4528 hdr.ppt1.classification)), 4529 }, 4530 [ITEM_HIGIG2_VID] = { 4531 .name = "vid", 4532 .help = "matches vid of higig2 header", 4533 .next = NEXT(item_higig2, NEXT_ENTRY(COMMON_UNSIGNED), 4534 item_param), 4535 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_higig2_hdr, 4536 hdr.ppt1.vid)), 4537 }, 4538 [ITEM_TAG] = { 4539 .name = "tag", 4540 .help = "match tag value", 4541 .priv = PRIV_ITEM(TAG, sizeof(struct rte_flow_item_tag)), 4542 .next = NEXT(item_tag), 4543 .call = parse_vc, 4544 }, 4545 [ITEM_TAG_DATA] = { 4546 .name = "data", 4547 .help = "tag value to match", 4548 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4549 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, data)), 4550 }, 4551 [ITEM_TAG_INDEX] = { 4552 .name = "index", 4553 .help = "index of tag array to match", 4554 .next = NEXT(item_tag, NEXT_ENTRY(COMMON_UNSIGNED), 4555 NEXT_ENTRY(ITEM_PARAM_IS)), 4556 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), 4557 }, 4558 [ITEM_L2TPV3OIP] = { 4559 .name = "l2tpv3oip", 4560 .help = "match L2TPv3 over IP header", 4561 .priv = PRIV_ITEM(L2TPV3OIP, 4562 sizeof(struct rte_flow_item_l2tpv3oip)), 4563 .next = NEXT(item_l2tpv3oip), 4564 .call = parse_vc, 4565 }, 4566 [ITEM_L2TPV3OIP_SESSION_ID] = { 4567 .name = "session_id", 4568 .help = "session identifier", 4569 .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(COMMON_UNSIGNED), 4570 item_param), 4571 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, 4572 session_id)), 4573 }, 4574 [ITEM_ESP] = { 4575 .name = "esp", 4576 .help = "match ESP header", 4577 .priv = PRIV_ITEM(ESP, sizeof(struct rte_flow_item_esp)), 4578 .next = NEXT(item_esp), 4579 .call = parse_vc, 4580 }, 4581 [ITEM_ESP_SPI] = { 4582 .name = "spi", 4583 .help = "security policy index", 4584 .next = NEXT(item_esp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4585 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_esp, 4586 hdr.spi)), 4587 }, 4588 [ITEM_AH] = { 4589 .name = "ah", 4590 .help = "match AH header", 4591 .priv = PRIV_ITEM(AH, sizeof(struct rte_flow_item_ah)), 4592 .next = NEXT(item_ah), 4593 .call = parse_vc, 4594 }, 4595 [ITEM_AH_SPI] = { 4596 .name = "spi", 4597 .help = "security parameters index", 4598 .next = NEXT(item_ah, NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4599 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ah, spi)), 4600 }, 4601 [ITEM_PFCP] = { 4602 .name = "pfcp", 4603 .help = "match pfcp header", 4604 .priv = PRIV_ITEM(PFCP, sizeof(struct rte_flow_item_pfcp)), 4605 .next = NEXT(item_pfcp), 4606 .call = parse_vc, 4607 }, 4608 [ITEM_PFCP_S_FIELD] = { 4609 .name = "s_field", 4610 .help = "S field", 4611 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 4612 item_param), 4613 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, 4614 s_field)), 4615 }, 4616 [ITEM_PFCP_SEID] = { 4617 .name = "seid", 4618 .help = "session endpoint identifier", 4619 .next = NEXT(item_pfcp, NEXT_ENTRY(COMMON_UNSIGNED), 4620 item_param), 4621 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_pfcp, seid)), 4622 }, 4623 [ITEM_ECPRI] = { 4624 .name = "ecpri", 4625 .help = "match eCPRI header", 4626 .priv = PRIV_ITEM(ECPRI, sizeof(struct rte_flow_item_ecpri)), 4627 .next = NEXT(item_ecpri), 4628 .call = parse_vc, 4629 }, 4630 [ITEM_ECPRI_COMMON] = { 4631 .name = "common", 4632 .help = "eCPRI common header", 4633 .next = NEXT(item_ecpri_common), 4634 }, 4635 [ITEM_ECPRI_COMMON_TYPE] = { 4636 .name = "type", 4637 .help = "type of common header", 4638 .next = NEXT(item_ecpri_common_type), 4639 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_ecpri)), 4640 }, 4641 [ITEM_ECPRI_COMMON_TYPE_IQ_DATA] = { 4642 .name = "iq_data", 4643 .help = "Type #0: IQ Data", 4644 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 4645 ITEM_NEXT)), 4646 .call = parse_vc_item_ecpri_type, 4647 }, 4648 [ITEM_ECPRI_MSG_IQ_DATA_PCID] = { 4649 .name = "pc_id", 4650 .help = "Physical Channel ID", 4651 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_IQ_DATA_PCID, 4652 ITEM_ECPRI_COMMON, ITEM_NEXT), 4653 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4654 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 4655 hdr.type0.pc_id)), 4656 }, 4657 [ITEM_ECPRI_COMMON_TYPE_RTC_CTRL] = { 4658 .name = "rtc_ctrl", 4659 .help = "Type #2: Real-Time Control Data", 4660 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 4661 ITEM_NEXT)), 4662 .call = parse_vc_item_ecpri_type, 4663 }, 4664 [ITEM_ECPRI_MSG_RTC_CTRL_RTCID] = { 4665 .name = "rtc_id", 4666 .help = "Real-Time Control Data ID", 4667 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_RTC_CTRL_RTCID, 4668 ITEM_ECPRI_COMMON, ITEM_NEXT), 4669 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4670 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 4671 hdr.type2.rtc_id)), 4672 }, 4673 [ITEM_ECPRI_COMMON_TYPE_DLY_MSR] = { 4674 .name = "delay_measure", 4675 .help = "Type #5: One-Way Delay Measurement", 4676 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 4677 ITEM_NEXT)), 4678 .call = parse_vc_item_ecpri_type, 4679 }, 4680 [ITEM_ECPRI_MSG_DLY_MSR_MSRID] = { 4681 .name = "msr_id", 4682 .help = "Measurement ID", 4683 .next = NEXT(NEXT_ENTRY(ITEM_ECPRI_MSG_DLY_MSR_MSRID, 4684 ITEM_ECPRI_COMMON, ITEM_NEXT), 4685 NEXT_ENTRY(COMMON_UNSIGNED), item_param), 4686 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ecpri, 4687 hdr.type5.msr_id)), 4688 }, 4689 [ITEM_GENEVE_OPT] = { 4690 .name = "geneve-opt", 4691 .help = "GENEVE header option", 4692 .priv = PRIV_ITEM(GENEVE_OPT, 4693 sizeof(struct rte_flow_item_geneve_opt) + 4694 ITEM_GENEVE_OPT_DATA_SIZE), 4695 .next = NEXT(item_geneve_opt), 4696 .call = parse_vc, 4697 }, 4698 [ITEM_GENEVE_OPT_CLASS] = { 4699 .name = "class", 4700 .help = "GENEVE option class", 4701 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 4702 item_param), 4703 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve_opt, 4704 option_class)), 4705 }, 4706 [ITEM_GENEVE_OPT_TYPE] = { 4707 .name = "type", 4708 .help = "GENEVE option type", 4709 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 4710 item_param), 4711 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, 4712 option_type)), 4713 }, 4714 [ITEM_GENEVE_OPT_LENGTH] = { 4715 .name = "length", 4716 .help = "GENEVE option data length (in 32b words)", 4717 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_UNSIGNED), 4718 item_param), 4719 .args = ARGS(ARGS_ENTRY_BOUNDED( 4720 struct rte_flow_item_geneve_opt, option_len, 4721 0, 31)), 4722 }, 4723 [ITEM_GENEVE_OPT_DATA] = { 4724 .name = "data", 4725 .help = "GENEVE option data pattern", 4726 .next = NEXT(item_geneve_opt, NEXT_ENTRY(COMMON_HEX), 4727 item_param), 4728 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_geneve_opt, data), 4729 ARGS_ENTRY_ARB(0, 0), 4730 ARGS_ENTRY_ARB 4731 (sizeof(struct rte_flow_item_geneve_opt), 4732 ITEM_GENEVE_OPT_DATA_SIZE)), 4733 }, 4734 [ITEM_INTEGRITY] = { 4735 .name = "integrity", 4736 .help = "match packet integrity", 4737 .priv = PRIV_ITEM(INTEGRITY, 4738 sizeof(struct rte_flow_item_integrity)), 4739 .next = NEXT(item_integrity), 4740 .call = parse_vc, 4741 }, 4742 [ITEM_INTEGRITY_LEVEL] = { 4743 .name = "level", 4744 .help = "integrity level", 4745 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 4746 item_param), 4747 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, level)), 4748 }, 4749 [ITEM_INTEGRITY_VALUE] = { 4750 .name = "value", 4751 .help = "integrity value", 4752 .next = NEXT(item_integrity_lv, NEXT_ENTRY(COMMON_UNSIGNED), 4753 item_param), 4754 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_integrity, value)), 4755 }, 4756 [ITEM_CONNTRACK] = { 4757 .name = "conntrack", 4758 .help = "conntrack state", 4759 .next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(COMMON_UNSIGNED), 4760 item_param), 4761 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)), 4762 }, 4763 [ITEM_PORT_REPRESENTOR] = { 4764 .name = "port_representor", 4765 .help = "match traffic entering the embedded switch from the given ethdev", 4766 .priv = PRIV_ITEM(PORT_REPRESENTOR, 4767 sizeof(struct rte_flow_item_ethdev)), 4768 .next = NEXT(item_port_representor), 4769 .call = parse_vc, 4770 }, 4771 [ITEM_PORT_REPRESENTOR_PORT_ID] = { 4772 .name = "port_id", 4773 .help = "ethdev port ID", 4774 .next = NEXT(item_port_representor, NEXT_ENTRY(COMMON_UNSIGNED), 4775 item_param), 4776 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 4777 }, 4778 [ITEM_REPRESENTED_PORT] = { 4779 .name = "represented_port", 4780 .help = "match traffic entering the embedded switch from the entity represented by the given ethdev", 4781 .priv = PRIV_ITEM(REPRESENTED_PORT, 4782 sizeof(struct rte_flow_item_ethdev)), 4783 .next = NEXT(item_represented_port), 4784 .call = parse_vc, 4785 }, 4786 [ITEM_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 4787 .name = "ethdev_port_id", 4788 .help = "ethdev port ID", 4789 .next = NEXT(item_represented_port, NEXT_ENTRY(COMMON_UNSIGNED), 4790 item_param), 4791 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ethdev, port_id)), 4792 }, 4793 [ITEM_FLEX] = { 4794 .name = "flex", 4795 .help = "match flex header", 4796 .priv = PRIV_ITEM(FLEX, sizeof(struct rte_flow_item_flex)), 4797 .next = NEXT(item_flex), 4798 .call = parse_vc, 4799 }, 4800 [ITEM_FLEX_ITEM_HANDLE] = { 4801 .name = "item", 4802 .help = "flex item handle", 4803 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 4804 NEXT_ENTRY(ITEM_PARAM_IS)), 4805 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, handle)), 4806 }, 4807 [ITEM_FLEX_PATTERN_HANDLE] = { 4808 .name = "pattern", 4809 .help = "flex pattern handle", 4810 .next = NEXT(item_flex, NEXT_ENTRY(COMMON_FLEX_HANDLE), 4811 NEXT_ENTRY(ITEM_PARAM_IS)), 4812 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)), 4813 }, 4814 [ITEM_L2TPV2] = { 4815 .name = "l2tpv2", 4816 .help = "match L2TPv2 header", 4817 .priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)), 4818 .next = NEXT(item_l2tpv2), 4819 .call = parse_vc, 4820 }, 4821 [ITEM_L2TPV2_TYPE] = { 4822 .name = "type", 4823 .help = "type of l2tpv2", 4824 .next = NEXT(item_l2tpv2_type), 4825 .args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)), 4826 }, 4827 [ITEM_L2TPV2_TYPE_DATA] = { 4828 .name = "data", 4829 .help = "Type #7: data message without any options", 4830 .next = NEXT(item_l2tpv2_type_data), 4831 .call = parse_vc_item_l2tpv2_type, 4832 }, 4833 [ITEM_L2TPV2_MSG_DATA_TUNNEL_ID] = { 4834 .name = "tunnel_id", 4835 .help = "tunnel identifier", 4836 .next = NEXT(item_l2tpv2_type_data, 4837 NEXT_ENTRY(COMMON_UNSIGNED), 4838 item_param), 4839 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4840 hdr.type7.tunnel_id)), 4841 }, 4842 [ITEM_L2TPV2_MSG_DATA_SESSION_ID] = { 4843 .name = "session_id", 4844 .help = "session identifier", 4845 .next = NEXT(item_l2tpv2_type_data, 4846 NEXT_ENTRY(COMMON_UNSIGNED), 4847 item_param), 4848 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4849 hdr.type7.session_id)), 4850 }, 4851 [ITEM_L2TPV2_TYPE_DATA_L] = { 4852 .name = "data_l", 4853 .help = "Type #6: data message with length option", 4854 .next = NEXT(item_l2tpv2_type_data_l), 4855 .call = parse_vc_item_l2tpv2_type, 4856 }, 4857 [ITEM_L2TPV2_MSG_DATA_L_LENGTH] = { 4858 .name = "length", 4859 .help = "message length", 4860 .next = NEXT(item_l2tpv2_type_data_l, 4861 NEXT_ENTRY(COMMON_UNSIGNED), 4862 item_param), 4863 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4864 hdr.type6.length)), 4865 }, 4866 [ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = { 4867 .name = "tunnel_id", 4868 .help = "tunnel identifier", 4869 .next = NEXT(item_l2tpv2_type_data_l, 4870 NEXT_ENTRY(COMMON_UNSIGNED), 4871 item_param), 4872 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4873 hdr.type6.tunnel_id)), 4874 }, 4875 [ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = { 4876 .name = "session_id", 4877 .help = "session identifier", 4878 .next = NEXT(item_l2tpv2_type_data_l, 4879 NEXT_ENTRY(COMMON_UNSIGNED), 4880 item_param), 4881 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4882 hdr.type6.session_id)), 4883 }, 4884 [ITEM_L2TPV2_TYPE_DATA_S] = { 4885 .name = "data_s", 4886 .help = "Type #5: data message with ns, nr option", 4887 .next = NEXT(item_l2tpv2_type_data_s), 4888 .call = parse_vc_item_l2tpv2_type, 4889 }, 4890 [ITEM_L2TPV2_MSG_DATA_S_TUNNEL_ID] = { 4891 .name = "tunnel_id", 4892 .help = "tunnel identifier", 4893 .next = NEXT(item_l2tpv2_type_data_s, 4894 NEXT_ENTRY(COMMON_UNSIGNED), 4895 item_param), 4896 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4897 hdr.type5.tunnel_id)), 4898 }, 4899 [ITEM_L2TPV2_MSG_DATA_S_SESSION_ID] = { 4900 .name = "session_id", 4901 .help = "session identifier", 4902 .next = NEXT(item_l2tpv2_type_data_s, 4903 NEXT_ENTRY(COMMON_UNSIGNED), 4904 item_param), 4905 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4906 hdr.type5.session_id)), 4907 }, 4908 [ITEM_L2TPV2_MSG_DATA_S_NS] = { 4909 .name = "ns", 4910 .help = "sequence number for message", 4911 .next = NEXT(item_l2tpv2_type_data_s, 4912 NEXT_ENTRY(COMMON_UNSIGNED), 4913 item_param), 4914 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4915 hdr.type5.ns)), 4916 }, 4917 [ITEM_L2TPV2_MSG_DATA_S_NR] = { 4918 .name = "nr", 4919 .help = "sequence number for next receive message", 4920 .next = NEXT(item_l2tpv2_type_data_s, 4921 NEXT_ENTRY(COMMON_UNSIGNED), 4922 item_param), 4923 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4924 hdr.type5.nr)), 4925 }, 4926 [ITEM_L2TPV2_TYPE_DATA_O] = { 4927 .name = "data_o", 4928 .help = "Type #4: data message with offset option", 4929 .next = NEXT(item_l2tpv2_type_data_o), 4930 .call = parse_vc_item_l2tpv2_type, 4931 }, 4932 [ITEM_L2TPV2_MSG_DATA_O_TUNNEL_ID] = { 4933 .name = "tunnel_id", 4934 .help = "tunnel identifier", 4935 .next = NEXT(item_l2tpv2_type_data_o, 4936 NEXT_ENTRY(COMMON_UNSIGNED), 4937 item_param), 4938 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4939 hdr.type4.tunnel_id)), 4940 }, 4941 [ITEM_L2TPV2_MSG_DATA_O_SESSION_ID] = { 4942 .name = "session_id", 4943 .help = "session identifier", 4944 .next = NEXT(item_l2tpv2_type_data_o, 4945 NEXT_ENTRY(COMMON_UNSIGNED), 4946 item_param), 4947 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4948 hdr.type5.session_id)), 4949 }, 4950 [ITEM_L2TPV2_MSG_DATA_O_OFFSET] = { 4951 .name = "offset_size", 4952 .help = "the size of offset padding", 4953 .next = NEXT(item_l2tpv2_type_data_o, 4954 NEXT_ENTRY(COMMON_UNSIGNED), 4955 item_param), 4956 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4957 hdr.type4.offset_size)), 4958 }, 4959 [ITEM_L2TPV2_TYPE_DATA_L_S] = { 4960 .name = "data_l_s", 4961 .help = "Type #3: data message contains length, ns, nr " 4962 "options", 4963 .next = NEXT(item_l2tpv2_type_data_l_s), 4964 .call = parse_vc_item_l2tpv2_type, 4965 }, 4966 [ITEM_L2TPV2_MSG_DATA_L_S_LENGTH] = { 4967 .name = "length", 4968 .help = "message length", 4969 .next = NEXT(item_l2tpv2_type_data_l_s, 4970 NEXT_ENTRY(COMMON_UNSIGNED), 4971 item_param), 4972 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4973 hdr.type3.length)), 4974 }, 4975 [ITEM_L2TPV2_MSG_DATA_L_S_TUNNEL_ID] = { 4976 .name = "tunnel_id", 4977 .help = "tunnel identifier", 4978 .next = NEXT(item_l2tpv2_type_data_l_s, 4979 NEXT_ENTRY(COMMON_UNSIGNED), 4980 item_param), 4981 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4982 hdr.type3.tunnel_id)), 4983 }, 4984 [ITEM_L2TPV2_MSG_DATA_L_S_SESSION_ID] = { 4985 .name = "session_id", 4986 .help = "session identifier", 4987 .next = NEXT(item_l2tpv2_type_data_l_s, 4988 NEXT_ENTRY(COMMON_UNSIGNED), 4989 item_param), 4990 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 4991 hdr.type3.session_id)), 4992 }, 4993 [ITEM_L2TPV2_MSG_DATA_L_S_NS] = { 4994 .name = "ns", 4995 .help = "sequence number for message", 4996 .next = NEXT(item_l2tpv2_type_data_l_s, 4997 NEXT_ENTRY(COMMON_UNSIGNED), 4998 item_param), 4999 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5000 hdr.type3.ns)), 5001 }, 5002 [ITEM_L2TPV2_MSG_DATA_L_S_NR] = { 5003 .name = "nr", 5004 .help = "sequence number for next receive message", 5005 .next = NEXT(item_l2tpv2_type_data_l_s, 5006 NEXT_ENTRY(COMMON_UNSIGNED), 5007 item_param), 5008 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5009 hdr.type3.nr)), 5010 }, 5011 [ITEM_L2TPV2_TYPE_CTRL] = { 5012 .name = "control", 5013 .help = "Type #3: conrtol message contains length, ns, nr " 5014 "options", 5015 .next = NEXT(item_l2tpv2_type_ctrl), 5016 .call = parse_vc_item_l2tpv2_type, 5017 }, 5018 [ITEM_L2TPV2_MSG_CTRL_LENGTH] = { 5019 .name = "length", 5020 .help = "message length", 5021 .next = NEXT(item_l2tpv2_type_ctrl, 5022 NEXT_ENTRY(COMMON_UNSIGNED), 5023 item_param), 5024 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5025 hdr.type3.length)), 5026 }, 5027 [ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = { 5028 .name = "tunnel_id", 5029 .help = "tunnel identifier", 5030 .next = NEXT(item_l2tpv2_type_ctrl, 5031 NEXT_ENTRY(COMMON_UNSIGNED), 5032 item_param), 5033 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5034 hdr.type3.tunnel_id)), 5035 }, 5036 [ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = { 5037 .name = "session_id", 5038 .help = "session identifier", 5039 .next = NEXT(item_l2tpv2_type_ctrl, 5040 NEXT_ENTRY(COMMON_UNSIGNED), 5041 item_param), 5042 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5043 hdr.type3.session_id)), 5044 }, 5045 [ITEM_L2TPV2_MSG_CTRL_NS] = { 5046 .name = "ns", 5047 .help = "sequence number for message", 5048 .next = NEXT(item_l2tpv2_type_ctrl, 5049 NEXT_ENTRY(COMMON_UNSIGNED), 5050 item_param), 5051 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5052 hdr.type3.ns)), 5053 }, 5054 [ITEM_L2TPV2_MSG_CTRL_NR] = { 5055 .name = "nr", 5056 .help = "sequence number for next receive message", 5057 .next = NEXT(item_l2tpv2_type_ctrl, 5058 NEXT_ENTRY(COMMON_UNSIGNED), 5059 item_param), 5060 .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2, 5061 hdr.type3.nr)), 5062 }, 5063 [ITEM_PPP] = { 5064 .name = "ppp", 5065 .help = "match PPP header", 5066 .priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)), 5067 .next = NEXT(item_ppp), 5068 .call = parse_vc, 5069 }, 5070 [ITEM_PPP_ADDR] = { 5071 .name = "addr", 5072 .help = "PPP address", 5073 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 5074 item_param), 5075 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)), 5076 }, 5077 [ITEM_PPP_CTRL] = { 5078 .name = "ctrl", 5079 .help = "PPP control", 5080 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 5081 item_param), 5082 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)), 5083 }, 5084 [ITEM_PPP_PROTO_ID] = { 5085 .name = "proto_id", 5086 .help = "PPP protocol identifier", 5087 .next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED), 5088 item_param), 5089 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, 5090 hdr.proto_id)), 5091 }, 5092 [ITEM_METER] = { 5093 .name = "meter", 5094 .help = "match meter color", 5095 .priv = PRIV_ITEM(METER_COLOR, 5096 sizeof(struct rte_flow_item_meter_color)), 5097 .next = NEXT(item_meter), 5098 .call = parse_vc, 5099 }, 5100 [ITEM_METER_COLOR] = { 5101 .name = "color", 5102 .help = "meter color", 5103 .next = NEXT(item_meter, 5104 NEXT_ENTRY(ITEM_METER_COLOR_NAME), 5105 item_param), 5106 .args = ARGS(ARGS_ENTRY(struct rte_flow_item_meter_color, 5107 color)), 5108 }, 5109 [ITEM_METER_COLOR_NAME] = { 5110 .name = "color_name", 5111 .help = "meter color name", 5112 .call = parse_meter_color, 5113 .comp = comp_meter_color, 5114 }, 5115 /* Validate/create actions. */ 5116 [ACTIONS] = { 5117 .name = "actions", 5118 .help = "submit a list of associated actions", 5119 .next = NEXT(next_action), 5120 .call = parse_vc, 5121 }, 5122 [ACTION_NEXT] = { 5123 .name = "/", 5124 .help = "specify next action", 5125 .next = NEXT(next_action), 5126 }, 5127 [ACTION_END] = { 5128 .name = "end", 5129 .help = "end list of actions", 5130 .priv = PRIV_ACTION(END, 0), 5131 .call = parse_vc, 5132 }, 5133 [ACTION_VOID] = { 5134 .name = "void", 5135 .help = "no-op action", 5136 .priv = PRIV_ACTION(VOID, 0), 5137 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5138 .call = parse_vc, 5139 }, 5140 [ACTION_PASSTHRU] = { 5141 .name = "passthru", 5142 .help = "let subsequent rule process matched packets", 5143 .priv = PRIV_ACTION(PASSTHRU, 0), 5144 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5145 .call = parse_vc, 5146 }, 5147 [ACTION_JUMP] = { 5148 .name = "jump", 5149 .help = "redirect traffic to a given group", 5150 .priv = PRIV_ACTION(JUMP, sizeof(struct rte_flow_action_jump)), 5151 .next = NEXT(action_jump), 5152 .call = parse_vc, 5153 }, 5154 [ACTION_JUMP_GROUP] = { 5155 .name = "group", 5156 .help = "group to redirect traffic to", 5157 .next = NEXT(action_jump, NEXT_ENTRY(COMMON_UNSIGNED)), 5158 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_jump, group)), 5159 .call = parse_vc_conf, 5160 }, 5161 [ACTION_MARK] = { 5162 .name = "mark", 5163 .help = "attach 32 bit value to packets", 5164 .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)), 5165 .next = NEXT(action_mark), 5166 .call = parse_vc, 5167 }, 5168 [ACTION_MARK_ID] = { 5169 .name = "id", 5170 .help = "32 bit value to return with packets", 5171 .next = NEXT(action_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 5172 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)), 5173 .call = parse_vc_conf, 5174 }, 5175 [ACTION_FLAG] = { 5176 .name = "flag", 5177 .help = "flag packets", 5178 .priv = PRIV_ACTION(FLAG, 0), 5179 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5180 .call = parse_vc, 5181 }, 5182 [ACTION_QUEUE] = { 5183 .name = "queue", 5184 .help = "assign packets to a given queue index", 5185 .priv = PRIV_ACTION(QUEUE, 5186 sizeof(struct rte_flow_action_queue)), 5187 .next = NEXT(action_queue), 5188 .call = parse_vc, 5189 }, 5190 [ACTION_QUEUE_INDEX] = { 5191 .name = "index", 5192 .help = "queue index to use", 5193 .next = NEXT(action_queue, NEXT_ENTRY(COMMON_UNSIGNED)), 5194 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)), 5195 .call = parse_vc_conf, 5196 }, 5197 [ACTION_DROP] = { 5198 .name = "drop", 5199 .help = "drop packets (note: passthru has priority)", 5200 .priv = PRIV_ACTION(DROP, 0), 5201 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5202 .call = parse_vc, 5203 }, 5204 [ACTION_COUNT] = { 5205 .name = "count", 5206 .help = "enable counters for this rule", 5207 .priv = PRIV_ACTION(COUNT, 5208 sizeof(struct rte_flow_action_count)), 5209 .next = NEXT(action_count), 5210 .call = parse_vc, 5211 }, 5212 [ACTION_COUNT_ID] = { 5213 .name = "identifier", 5214 .help = "counter identifier to use", 5215 .next = NEXT(action_count, NEXT_ENTRY(COMMON_UNSIGNED)), 5216 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_count, id)), 5217 .call = parse_vc_conf, 5218 }, 5219 [ACTION_RSS] = { 5220 .name = "rss", 5221 .help = "spread packets among several queues", 5222 .priv = PRIV_ACTION(RSS, sizeof(struct action_rss_data)), 5223 .next = NEXT(action_rss), 5224 .call = parse_vc_action_rss, 5225 }, 5226 [ACTION_RSS_FUNC] = { 5227 .name = "func", 5228 .help = "RSS hash function to apply", 5229 .next = NEXT(action_rss, 5230 NEXT_ENTRY(ACTION_RSS_FUNC_DEFAULT, 5231 ACTION_RSS_FUNC_TOEPLITZ, 5232 ACTION_RSS_FUNC_SIMPLE_XOR, 5233 ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ)), 5234 }, 5235 [ACTION_RSS_FUNC_DEFAULT] = { 5236 .name = "default", 5237 .help = "default hash function", 5238 .call = parse_vc_action_rss_func, 5239 }, 5240 [ACTION_RSS_FUNC_TOEPLITZ] = { 5241 .name = "toeplitz", 5242 .help = "Toeplitz hash function", 5243 .call = parse_vc_action_rss_func, 5244 }, 5245 [ACTION_RSS_FUNC_SIMPLE_XOR] = { 5246 .name = "simple_xor", 5247 .help = "simple XOR hash function", 5248 .call = parse_vc_action_rss_func, 5249 }, 5250 [ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ] = { 5251 .name = "symmetric_toeplitz", 5252 .help = "Symmetric Toeplitz hash function", 5253 .call = parse_vc_action_rss_func, 5254 }, 5255 [ACTION_RSS_LEVEL] = { 5256 .name = "level", 5257 .help = "encapsulation level for \"types\"", 5258 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 5259 .args = ARGS(ARGS_ENTRY_ARB 5260 (offsetof(struct action_rss_data, conf) + 5261 offsetof(struct rte_flow_action_rss, level), 5262 sizeof(((struct rte_flow_action_rss *)0)-> 5263 level))), 5264 }, 5265 [ACTION_RSS_TYPES] = { 5266 .name = "types", 5267 .help = "specific RSS hash types", 5268 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_TYPE)), 5269 }, 5270 [ACTION_RSS_TYPE] = { 5271 .name = "{type}", 5272 .help = "RSS hash type", 5273 .call = parse_vc_action_rss_type, 5274 .comp = comp_vc_action_rss_type, 5275 }, 5276 [ACTION_RSS_KEY] = { 5277 .name = "key", 5278 .help = "RSS hash key", 5279 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_HEX)), 5280 .args = ARGS(ARGS_ENTRY_ARB 5281 (offsetof(struct action_rss_data, conf) + 5282 offsetof(struct rte_flow_action_rss, key), 5283 sizeof(((struct rte_flow_action_rss *)0)->key)), 5284 ARGS_ENTRY_ARB 5285 (offsetof(struct action_rss_data, conf) + 5286 offsetof(struct rte_flow_action_rss, key_len), 5287 sizeof(((struct rte_flow_action_rss *)0)-> 5288 key_len)), 5289 ARGS_ENTRY(struct action_rss_data, key)), 5290 }, 5291 [ACTION_RSS_KEY_LEN] = { 5292 .name = "key_len", 5293 .help = "RSS hash key length in bytes", 5294 .next = NEXT(action_rss, NEXT_ENTRY(COMMON_UNSIGNED)), 5295 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 5296 (offsetof(struct action_rss_data, conf) + 5297 offsetof(struct rte_flow_action_rss, key_len), 5298 sizeof(((struct rte_flow_action_rss *)0)-> 5299 key_len), 5300 0, 5301 RSS_HASH_KEY_LENGTH)), 5302 }, 5303 [ACTION_RSS_QUEUES] = { 5304 .name = "queues", 5305 .help = "queue indices to use", 5306 .next = NEXT(action_rss, NEXT_ENTRY(ACTION_RSS_QUEUE)), 5307 .call = parse_vc_conf, 5308 }, 5309 [ACTION_RSS_QUEUE] = { 5310 .name = "{queue}", 5311 .help = "queue index", 5312 .call = parse_vc_action_rss_queue, 5313 .comp = comp_vc_action_rss_queue, 5314 }, 5315 [ACTION_PF] = { 5316 .name = "pf", 5317 .help = "direct traffic to physical function", 5318 .priv = PRIV_ACTION(PF, 0), 5319 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5320 .call = parse_vc, 5321 }, 5322 [ACTION_VF] = { 5323 .name = "vf", 5324 .help = "direct traffic to a virtual function ID", 5325 .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)), 5326 .next = NEXT(action_vf), 5327 .call = parse_vc, 5328 }, 5329 [ACTION_VF_ORIGINAL] = { 5330 .name = "original", 5331 .help = "use original VF ID if possible", 5332 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_BOOLEAN)), 5333 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf, 5334 original, 1)), 5335 .call = parse_vc_conf, 5336 }, 5337 [ACTION_VF_ID] = { 5338 .name = "id", 5339 .help = "VF ID", 5340 .next = NEXT(action_vf, NEXT_ENTRY(COMMON_UNSIGNED)), 5341 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)), 5342 .call = parse_vc_conf, 5343 }, 5344 [ACTION_PORT_ID] = { 5345 .name = "port_id", 5346 .help = "direct matching traffic to a given DPDK port ID", 5347 .priv = PRIV_ACTION(PORT_ID, 5348 sizeof(struct rte_flow_action_port_id)), 5349 .next = NEXT(action_port_id), 5350 .call = parse_vc, 5351 }, 5352 [ACTION_PORT_ID_ORIGINAL] = { 5353 .name = "original", 5354 .help = "use original DPDK port ID if possible", 5355 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_BOOLEAN)), 5356 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_port_id, 5357 original, 1)), 5358 .call = parse_vc_conf, 5359 }, 5360 [ACTION_PORT_ID_ID] = { 5361 .name = "id", 5362 .help = "DPDK port ID", 5363 .next = NEXT(action_port_id, NEXT_ENTRY(COMMON_UNSIGNED)), 5364 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_port_id, id)), 5365 .call = parse_vc_conf, 5366 }, 5367 [ACTION_METER] = { 5368 .name = "meter", 5369 .help = "meter the directed packets at given id", 5370 .priv = PRIV_ACTION(METER, 5371 sizeof(struct rte_flow_action_meter)), 5372 .next = NEXT(action_meter), 5373 .call = parse_vc, 5374 }, 5375 [ACTION_METER_COLOR] = { 5376 .name = "color", 5377 .help = "meter color for the packets", 5378 .priv = PRIV_ACTION(METER_COLOR, 5379 sizeof(struct rte_flow_action_meter_color)), 5380 .next = NEXT(action_meter_color), 5381 .call = parse_vc, 5382 }, 5383 [ACTION_METER_COLOR_TYPE] = { 5384 .name = "type", 5385 .help = "specific meter color", 5386 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 5387 NEXT_ENTRY(ACTION_METER_COLOR_GREEN, 5388 ACTION_METER_COLOR_YELLOW, 5389 ACTION_METER_COLOR_RED)), 5390 }, 5391 [ACTION_METER_COLOR_GREEN] = { 5392 .name = "green", 5393 .help = "meter color green", 5394 .call = parse_vc_action_meter_color_type, 5395 }, 5396 [ACTION_METER_COLOR_YELLOW] = { 5397 .name = "yellow", 5398 .help = "meter color yellow", 5399 .call = parse_vc_action_meter_color_type, 5400 }, 5401 [ACTION_METER_COLOR_RED] = { 5402 .name = "red", 5403 .help = "meter color red", 5404 .call = parse_vc_action_meter_color_type, 5405 }, 5406 [ACTION_METER_ID] = { 5407 .name = "mtr_id", 5408 .help = "meter id to use", 5409 .next = NEXT(action_meter, NEXT_ENTRY(COMMON_UNSIGNED)), 5410 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter, mtr_id)), 5411 .call = parse_vc_conf, 5412 }, 5413 [ACTION_METER_MARK] = { 5414 .name = "meter_mark", 5415 .help = "meter the directed packets using profile and policy", 5416 .priv = PRIV_ACTION(METER_MARK, 5417 sizeof(struct rte_flow_action_meter_mark)), 5418 .next = NEXT(action_meter_mark), 5419 .call = parse_vc, 5420 }, 5421 [ACTION_METER_PROFILE] = { 5422 .name = "mtr_profile", 5423 .help = "meter profile id to use", 5424 .next = NEXT(NEXT_ENTRY(ACTION_METER_PROFILE_ID2PTR)), 5425 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 5426 }, 5427 [ACTION_METER_PROFILE_ID2PTR] = { 5428 .name = "{mtr_profile_id}", 5429 .type = "PROFILE_ID", 5430 .help = "meter profile id", 5431 .next = NEXT(action_meter_mark), 5432 .call = parse_meter_profile_id2ptr, 5433 .comp = comp_none, 5434 }, 5435 [ACTION_METER_POLICY] = { 5436 .name = "mtr_policy", 5437 .help = "meter policy id to use", 5438 .next = NEXT(NEXT_ENTRY(ACTION_METER_POLICY_ID2PTR)), 5439 ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 5440 }, 5441 [ACTION_METER_POLICY_ID2PTR] = { 5442 .name = "{mtr_policy_id}", 5443 .type = "POLICY_ID", 5444 .help = "meter policy id", 5445 .next = NEXT(action_meter_mark), 5446 .call = parse_meter_policy_id2ptr, 5447 .comp = comp_none, 5448 }, 5449 [ACTION_METER_COLOR_MODE] = { 5450 .name = "mtr_color_mode", 5451 .help = "meter color awareness mode", 5452 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 5453 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, color_mode)), 5454 .call = parse_vc_conf, 5455 }, 5456 [ACTION_METER_INIT_COLOR] = { 5457 .name = "mtr_init_color", 5458 .help = "meter initial color", 5459 .next = NEXT(action_meter_mark, NEXT_ENTRY(ITEM_METER_COLOR_NAME)), 5460 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, init_color)), 5461 }, 5462 [ACTION_METER_STATE] = { 5463 .name = "mtr_state", 5464 .help = "meter state", 5465 .next = NEXT(action_meter_mark, NEXT_ENTRY(COMMON_UNSIGNED)), 5466 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_meter_mark, state)), 5467 .call = parse_vc_conf, 5468 }, 5469 [ACTION_OF_DEC_NW_TTL] = { 5470 .name = "of_dec_nw_ttl", 5471 .help = "OpenFlow's OFPAT_DEC_NW_TTL", 5472 .priv = PRIV_ACTION(OF_DEC_NW_TTL, 0), 5473 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5474 .call = parse_vc, 5475 }, 5476 [ACTION_OF_POP_VLAN] = { 5477 .name = "of_pop_vlan", 5478 .help = "OpenFlow's OFPAT_POP_VLAN", 5479 .priv = PRIV_ACTION(OF_POP_VLAN, 0), 5480 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5481 .call = parse_vc, 5482 }, 5483 [ACTION_OF_PUSH_VLAN] = { 5484 .name = "of_push_vlan", 5485 .help = "OpenFlow's OFPAT_PUSH_VLAN", 5486 .priv = PRIV_ACTION 5487 (OF_PUSH_VLAN, 5488 sizeof(struct rte_flow_action_of_push_vlan)), 5489 .next = NEXT(action_of_push_vlan), 5490 .call = parse_vc, 5491 }, 5492 [ACTION_OF_PUSH_VLAN_ETHERTYPE] = { 5493 .name = "ethertype", 5494 .help = "EtherType", 5495 .next = NEXT(action_of_push_vlan, NEXT_ENTRY(COMMON_UNSIGNED)), 5496 .args = ARGS(ARGS_ENTRY_HTON 5497 (struct rte_flow_action_of_push_vlan, 5498 ethertype)), 5499 .call = parse_vc_conf, 5500 }, 5501 [ACTION_OF_SET_VLAN_VID] = { 5502 .name = "of_set_vlan_vid", 5503 .help = "OpenFlow's OFPAT_SET_VLAN_VID", 5504 .priv = PRIV_ACTION 5505 (OF_SET_VLAN_VID, 5506 sizeof(struct rte_flow_action_of_set_vlan_vid)), 5507 .next = NEXT(action_of_set_vlan_vid), 5508 .call = parse_vc, 5509 }, 5510 [ACTION_OF_SET_VLAN_VID_VLAN_VID] = { 5511 .name = "vlan_vid", 5512 .help = "VLAN id", 5513 .next = NEXT(action_of_set_vlan_vid, 5514 NEXT_ENTRY(COMMON_UNSIGNED)), 5515 .args = ARGS(ARGS_ENTRY_HTON 5516 (struct rte_flow_action_of_set_vlan_vid, 5517 vlan_vid)), 5518 .call = parse_vc_conf, 5519 }, 5520 [ACTION_OF_SET_VLAN_PCP] = { 5521 .name = "of_set_vlan_pcp", 5522 .help = "OpenFlow's OFPAT_SET_VLAN_PCP", 5523 .priv = PRIV_ACTION 5524 (OF_SET_VLAN_PCP, 5525 sizeof(struct rte_flow_action_of_set_vlan_pcp)), 5526 .next = NEXT(action_of_set_vlan_pcp), 5527 .call = parse_vc, 5528 }, 5529 [ACTION_OF_SET_VLAN_PCP_VLAN_PCP] = { 5530 .name = "vlan_pcp", 5531 .help = "VLAN priority", 5532 .next = NEXT(action_of_set_vlan_pcp, 5533 NEXT_ENTRY(COMMON_UNSIGNED)), 5534 .args = ARGS(ARGS_ENTRY_HTON 5535 (struct rte_flow_action_of_set_vlan_pcp, 5536 vlan_pcp)), 5537 .call = parse_vc_conf, 5538 }, 5539 [ACTION_OF_POP_MPLS] = { 5540 .name = "of_pop_mpls", 5541 .help = "OpenFlow's OFPAT_POP_MPLS", 5542 .priv = PRIV_ACTION(OF_POP_MPLS, 5543 sizeof(struct rte_flow_action_of_pop_mpls)), 5544 .next = NEXT(action_of_pop_mpls), 5545 .call = parse_vc, 5546 }, 5547 [ACTION_OF_POP_MPLS_ETHERTYPE] = { 5548 .name = "ethertype", 5549 .help = "EtherType", 5550 .next = NEXT(action_of_pop_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 5551 .args = ARGS(ARGS_ENTRY_HTON 5552 (struct rte_flow_action_of_pop_mpls, 5553 ethertype)), 5554 .call = parse_vc_conf, 5555 }, 5556 [ACTION_OF_PUSH_MPLS] = { 5557 .name = "of_push_mpls", 5558 .help = "OpenFlow's OFPAT_PUSH_MPLS", 5559 .priv = PRIV_ACTION 5560 (OF_PUSH_MPLS, 5561 sizeof(struct rte_flow_action_of_push_mpls)), 5562 .next = NEXT(action_of_push_mpls), 5563 .call = parse_vc, 5564 }, 5565 [ACTION_OF_PUSH_MPLS_ETHERTYPE] = { 5566 .name = "ethertype", 5567 .help = "EtherType", 5568 .next = NEXT(action_of_push_mpls, NEXT_ENTRY(COMMON_UNSIGNED)), 5569 .args = ARGS(ARGS_ENTRY_HTON 5570 (struct rte_flow_action_of_push_mpls, 5571 ethertype)), 5572 .call = parse_vc_conf, 5573 }, 5574 [ACTION_VXLAN_ENCAP] = { 5575 .name = "vxlan_encap", 5576 .help = "VXLAN encapsulation, uses configuration set by \"set" 5577 " vxlan\"", 5578 .priv = PRIV_ACTION(VXLAN_ENCAP, 5579 sizeof(struct action_vxlan_encap_data)), 5580 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5581 .call = parse_vc_action_vxlan_encap, 5582 }, 5583 [ACTION_VXLAN_DECAP] = { 5584 .name = "vxlan_decap", 5585 .help = "Performs a decapsulation action by stripping all" 5586 " headers of the VXLAN tunnel network overlay from the" 5587 " matched flow.", 5588 .priv = PRIV_ACTION(VXLAN_DECAP, 0), 5589 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5590 .call = parse_vc, 5591 }, 5592 [ACTION_NVGRE_ENCAP] = { 5593 .name = "nvgre_encap", 5594 .help = "NVGRE encapsulation, uses configuration set by \"set" 5595 " nvgre\"", 5596 .priv = PRIV_ACTION(NVGRE_ENCAP, 5597 sizeof(struct action_nvgre_encap_data)), 5598 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5599 .call = parse_vc_action_nvgre_encap, 5600 }, 5601 [ACTION_NVGRE_DECAP] = { 5602 .name = "nvgre_decap", 5603 .help = "Performs a decapsulation action by stripping all" 5604 " headers of the NVGRE tunnel network overlay from the" 5605 " matched flow.", 5606 .priv = PRIV_ACTION(NVGRE_DECAP, 0), 5607 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5608 .call = parse_vc, 5609 }, 5610 [ACTION_L2_ENCAP] = { 5611 .name = "l2_encap", 5612 .help = "l2 encap, uses configuration set by" 5613 " \"set l2_encap\"", 5614 .priv = PRIV_ACTION(RAW_ENCAP, 5615 sizeof(struct action_raw_encap_data)), 5616 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5617 .call = parse_vc_action_l2_encap, 5618 }, 5619 [ACTION_L2_DECAP] = { 5620 .name = "l2_decap", 5621 .help = "l2 decap, uses configuration set by" 5622 " \"set l2_decap\"", 5623 .priv = PRIV_ACTION(RAW_DECAP, 5624 sizeof(struct action_raw_decap_data)), 5625 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5626 .call = parse_vc_action_l2_decap, 5627 }, 5628 [ACTION_MPLSOGRE_ENCAP] = { 5629 .name = "mplsogre_encap", 5630 .help = "mplsogre encapsulation, uses configuration set by" 5631 " \"set mplsogre_encap\"", 5632 .priv = PRIV_ACTION(RAW_ENCAP, 5633 sizeof(struct action_raw_encap_data)), 5634 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5635 .call = parse_vc_action_mplsogre_encap, 5636 }, 5637 [ACTION_MPLSOGRE_DECAP] = { 5638 .name = "mplsogre_decap", 5639 .help = "mplsogre decapsulation, uses configuration set by" 5640 " \"set mplsogre_decap\"", 5641 .priv = PRIV_ACTION(RAW_DECAP, 5642 sizeof(struct action_raw_decap_data)), 5643 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5644 .call = parse_vc_action_mplsogre_decap, 5645 }, 5646 [ACTION_MPLSOUDP_ENCAP] = { 5647 .name = "mplsoudp_encap", 5648 .help = "mplsoudp encapsulation, uses configuration set by" 5649 " \"set mplsoudp_encap\"", 5650 .priv = PRIV_ACTION(RAW_ENCAP, 5651 sizeof(struct action_raw_encap_data)), 5652 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5653 .call = parse_vc_action_mplsoudp_encap, 5654 }, 5655 [ACTION_MPLSOUDP_DECAP] = { 5656 .name = "mplsoudp_decap", 5657 .help = "mplsoudp decapsulation, uses configuration set by" 5658 " \"set mplsoudp_decap\"", 5659 .priv = PRIV_ACTION(RAW_DECAP, 5660 sizeof(struct action_raw_decap_data)), 5661 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5662 .call = parse_vc_action_mplsoudp_decap, 5663 }, 5664 [ACTION_SET_IPV4_SRC] = { 5665 .name = "set_ipv4_src", 5666 .help = "Set a new IPv4 source address in the outermost" 5667 " IPv4 header", 5668 .priv = PRIV_ACTION(SET_IPV4_SRC, 5669 sizeof(struct rte_flow_action_set_ipv4)), 5670 .next = NEXT(action_set_ipv4_src), 5671 .call = parse_vc, 5672 }, 5673 [ACTION_SET_IPV4_SRC_IPV4_SRC] = { 5674 .name = "ipv4_addr", 5675 .help = "new IPv4 source address to set", 5676 .next = NEXT(action_set_ipv4_src, NEXT_ENTRY(COMMON_IPV4_ADDR)), 5677 .args = ARGS(ARGS_ENTRY_HTON 5678 (struct rte_flow_action_set_ipv4, ipv4_addr)), 5679 .call = parse_vc_conf, 5680 }, 5681 [ACTION_SET_IPV4_DST] = { 5682 .name = "set_ipv4_dst", 5683 .help = "Set a new IPv4 destination address in the outermost" 5684 " IPv4 header", 5685 .priv = PRIV_ACTION(SET_IPV4_DST, 5686 sizeof(struct rte_flow_action_set_ipv4)), 5687 .next = NEXT(action_set_ipv4_dst), 5688 .call = parse_vc, 5689 }, 5690 [ACTION_SET_IPV4_DST_IPV4_DST] = { 5691 .name = "ipv4_addr", 5692 .help = "new IPv4 destination address to set", 5693 .next = NEXT(action_set_ipv4_dst, NEXT_ENTRY(COMMON_IPV4_ADDR)), 5694 .args = ARGS(ARGS_ENTRY_HTON 5695 (struct rte_flow_action_set_ipv4, ipv4_addr)), 5696 .call = parse_vc_conf, 5697 }, 5698 [ACTION_SET_IPV6_SRC] = { 5699 .name = "set_ipv6_src", 5700 .help = "Set a new IPv6 source address in the outermost" 5701 " IPv6 header", 5702 .priv = PRIV_ACTION(SET_IPV6_SRC, 5703 sizeof(struct rte_flow_action_set_ipv6)), 5704 .next = NEXT(action_set_ipv6_src), 5705 .call = parse_vc, 5706 }, 5707 [ACTION_SET_IPV6_SRC_IPV6_SRC] = { 5708 .name = "ipv6_addr", 5709 .help = "new IPv6 source address to set", 5710 .next = NEXT(action_set_ipv6_src, NEXT_ENTRY(COMMON_IPV6_ADDR)), 5711 .args = ARGS(ARGS_ENTRY_HTON 5712 (struct rte_flow_action_set_ipv6, ipv6_addr)), 5713 .call = parse_vc_conf, 5714 }, 5715 [ACTION_SET_IPV6_DST] = { 5716 .name = "set_ipv6_dst", 5717 .help = "Set a new IPv6 destination address in the outermost" 5718 " IPv6 header", 5719 .priv = PRIV_ACTION(SET_IPV6_DST, 5720 sizeof(struct rte_flow_action_set_ipv6)), 5721 .next = NEXT(action_set_ipv6_dst), 5722 .call = parse_vc, 5723 }, 5724 [ACTION_SET_IPV6_DST_IPV6_DST] = { 5725 .name = "ipv6_addr", 5726 .help = "new IPv6 destination address to set", 5727 .next = NEXT(action_set_ipv6_dst, NEXT_ENTRY(COMMON_IPV6_ADDR)), 5728 .args = ARGS(ARGS_ENTRY_HTON 5729 (struct rte_flow_action_set_ipv6, ipv6_addr)), 5730 .call = parse_vc_conf, 5731 }, 5732 [ACTION_SET_TP_SRC] = { 5733 .name = "set_tp_src", 5734 .help = "set a new source port number in the outermost" 5735 " TCP/UDP header", 5736 .priv = PRIV_ACTION(SET_TP_SRC, 5737 sizeof(struct rte_flow_action_set_tp)), 5738 .next = NEXT(action_set_tp_src), 5739 .call = parse_vc, 5740 }, 5741 [ACTION_SET_TP_SRC_TP_SRC] = { 5742 .name = "port", 5743 .help = "new source port number to set", 5744 .next = NEXT(action_set_tp_src, NEXT_ENTRY(COMMON_UNSIGNED)), 5745 .args = ARGS(ARGS_ENTRY_HTON 5746 (struct rte_flow_action_set_tp, port)), 5747 .call = parse_vc_conf, 5748 }, 5749 [ACTION_SET_TP_DST] = { 5750 .name = "set_tp_dst", 5751 .help = "set a new destination port number in the outermost" 5752 " TCP/UDP header", 5753 .priv = PRIV_ACTION(SET_TP_DST, 5754 sizeof(struct rte_flow_action_set_tp)), 5755 .next = NEXT(action_set_tp_dst), 5756 .call = parse_vc, 5757 }, 5758 [ACTION_SET_TP_DST_TP_DST] = { 5759 .name = "port", 5760 .help = "new destination port number to set", 5761 .next = NEXT(action_set_tp_dst, NEXT_ENTRY(COMMON_UNSIGNED)), 5762 .args = ARGS(ARGS_ENTRY_HTON 5763 (struct rte_flow_action_set_tp, port)), 5764 .call = parse_vc_conf, 5765 }, 5766 [ACTION_MAC_SWAP] = { 5767 .name = "mac_swap", 5768 .help = "Swap the source and destination MAC addresses" 5769 " in the outermost Ethernet header", 5770 .priv = PRIV_ACTION(MAC_SWAP, 0), 5771 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5772 .call = parse_vc, 5773 }, 5774 [ACTION_DEC_TTL] = { 5775 .name = "dec_ttl", 5776 .help = "decrease network TTL if available", 5777 .priv = PRIV_ACTION(DEC_TTL, 0), 5778 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5779 .call = parse_vc, 5780 }, 5781 [ACTION_SET_TTL] = { 5782 .name = "set_ttl", 5783 .help = "set ttl value", 5784 .priv = PRIV_ACTION(SET_TTL, 5785 sizeof(struct rte_flow_action_set_ttl)), 5786 .next = NEXT(action_set_ttl), 5787 .call = parse_vc, 5788 }, 5789 [ACTION_SET_TTL_TTL] = { 5790 .name = "ttl_value", 5791 .help = "new ttl value to set", 5792 .next = NEXT(action_set_ttl, NEXT_ENTRY(COMMON_UNSIGNED)), 5793 .args = ARGS(ARGS_ENTRY_HTON 5794 (struct rte_flow_action_set_ttl, ttl_value)), 5795 .call = parse_vc_conf, 5796 }, 5797 [ACTION_SET_MAC_SRC] = { 5798 .name = "set_mac_src", 5799 .help = "set source mac address", 5800 .priv = PRIV_ACTION(SET_MAC_SRC, 5801 sizeof(struct rte_flow_action_set_mac)), 5802 .next = NEXT(action_set_mac_src), 5803 .call = parse_vc, 5804 }, 5805 [ACTION_SET_MAC_SRC_MAC_SRC] = { 5806 .name = "mac_addr", 5807 .help = "new source mac address", 5808 .next = NEXT(action_set_mac_src, NEXT_ENTRY(COMMON_MAC_ADDR)), 5809 .args = ARGS(ARGS_ENTRY_HTON 5810 (struct rte_flow_action_set_mac, mac_addr)), 5811 .call = parse_vc_conf, 5812 }, 5813 [ACTION_SET_MAC_DST] = { 5814 .name = "set_mac_dst", 5815 .help = "set destination mac address", 5816 .priv = PRIV_ACTION(SET_MAC_DST, 5817 sizeof(struct rte_flow_action_set_mac)), 5818 .next = NEXT(action_set_mac_dst), 5819 .call = parse_vc, 5820 }, 5821 [ACTION_SET_MAC_DST_MAC_DST] = { 5822 .name = "mac_addr", 5823 .help = "new destination mac address to set", 5824 .next = NEXT(action_set_mac_dst, NEXT_ENTRY(COMMON_MAC_ADDR)), 5825 .args = ARGS(ARGS_ENTRY_HTON 5826 (struct rte_flow_action_set_mac, mac_addr)), 5827 .call = parse_vc_conf, 5828 }, 5829 [ACTION_INC_TCP_SEQ] = { 5830 .name = "inc_tcp_seq", 5831 .help = "increase TCP sequence number", 5832 .priv = PRIV_ACTION(INC_TCP_SEQ, sizeof(rte_be32_t)), 5833 .next = NEXT(action_inc_tcp_seq), 5834 .call = parse_vc, 5835 }, 5836 [ACTION_INC_TCP_SEQ_VALUE] = { 5837 .name = "value", 5838 .help = "the value to increase TCP sequence number by", 5839 .next = NEXT(action_inc_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 5840 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5841 .call = parse_vc_conf, 5842 }, 5843 [ACTION_DEC_TCP_SEQ] = { 5844 .name = "dec_tcp_seq", 5845 .help = "decrease TCP sequence number", 5846 .priv = PRIV_ACTION(DEC_TCP_SEQ, sizeof(rte_be32_t)), 5847 .next = NEXT(action_dec_tcp_seq), 5848 .call = parse_vc, 5849 }, 5850 [ACTION_DEC_TCP_SEQ_VALUE] = { 5851 .name = "value", 5852 .help = "the value to decrease TCP sequence number by", 5853 .next = NEXT(action_dec_tcp_seq, NEXT_ENTRY(COMMON_UNSIGNED)), 5854 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5855 .call = parse_vc_conf, 5856 }, 5857 [ACTION_INC_TCP_ACK] = { 5858 .name = "inc_tcp_ack", 5859 .help = "increase TCP acknowledgment number", 5860 .priv = PRIV_ACTION(INC_TCP_ACK, sizeof(rte_be32_t)), 5861 .next = NEXT(action_inc_tcp_ack), 5862 .call = parse_vc, 5863 }, 5864 [ACTION_INC_TCP_ACK_VALUE] = { 5865 .name = "value", 5866 .help = "the value to increase TCP acknowledgment number by", 5867 .next = NEXT(action_inc_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 5868 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5869 .call = parse_vc_conf, 5870 }, 5871 [ACTION_DEC_TCP_ACK] = { 5872 .name = "dec_tcp_ack", 5873 .help = "decrease TCP acknowledgment number", 5874 .priv = PRIV_ACTION(DEC_TCP_ACK, sizeof(rte_be32_t)), 5875 .next = NEXT(action_dec_tcp_ack), 5876 .call = parse_vc, 5877 }, 5878 [ACTION_DEC_TCP_ACK_VALUE] = { 5879 .name = "value", 5880 .help = "the value to decrease TCP acknowledgment number by", 5881 .next = NEXT(action_dec_tcp_ack, NEXT_ENTRY(COMMON_UNSIGNED)), 5882 .args = ARGS(ARG_ENTRY_HTON(rte_be32_t)), 5883 .call = parse_vc_conf, 5884 }, 5885 [ACTION_RAW_ENCAP] = { 5886 .name = "raw_encap", 5887 .help = "encapsulation data, defined by set raw_encap", 5888 .priv = PRIV_ACTION(RAW_ENCAP, 5889 sizeof(struct action_raw_encap_data)), 5890 .next = NEXT(action_raw_encap), 5891 .call = parse_vc_action_raw_encap, 5892 }, 5893 [ACTION_RAW_ENCAP_INDEX] = { 5894 .name = "index", 5895 .help = "the index of raw_encap_confs", 5896 .next = NEXT(NEXT_ENTRY(ACTION_RAW_ENCAP_INDEX_VALUE)), 5897 }, 5898 [ACTION_RAW_ENCAP_INDEX_VALUE] = { 5899 .name = "{index}", 5900 .type = "UNSIGNED", 5901 .help = "unsigned integer value", 5902 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5903 .call = parse_vc_action_raw_encap_index, 5904 .comp = comp_set_raw_index, 5905 }, 5906 [ACTION_RAW_DECAP] = { 5907 .name = "raw_decap", 5908 .help = "decapsulation data, defined by set raw_encap", 5909 .priv = PRIV_ACTION(RAW_DECAP, 5910 sizeof(struct action_raw_decap_data)), 5911 .next = NEXT(action_raw_decap), 5912 .call = parse_vc_action_raw_decap, 5913 }, 5914 [ACTION_RAW_DECAP_INDEX] = { 5915 .name = "index", 5916 .help = "the index of raw_encap_confs", 5917 .next = NEXT(NEXT_ENTRY(ACTION_RAW_DECAP_INDEX_VALUE)), 5918 }, 5919 [ACTION_RAW_DECAP_INDEX_VALUE] = { 5920 .name = "{index}", 5921 .type = "UNSIGNED", 5922 .help = "unsigned integer value", 5923 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 5924 .call = parse_vc_action_raw_decap_index, 5925 .comp = comp_set_raw_index, 5926 }, 5927 [ACTION_MODIFY_FIELD] = { 5928 .name = "modify_field", 5929 .help = "modify destination field with data from source field", 5930 .priv = PRIV_ACTION(MODIFY_FIELD, ACTION_MODIFY_SIZE), 5931 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_OP)), 5932 .call = parse_vc, 5933 }, 5934 [ACTION_MODIFY_FIELD_OP] = { 5935 .name = "op", 5936 .help = "operation type", 5937 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE), 5938 NEXT_ENTRY(ACTION_MODIFY_FIELD_OP_VALUE)), 5939 .call = parse_vc_conf, 5940 }, 5941 [ACTION_MODIFY_FIELD_OP_VALUE] = { 5942 .name = "{operation}", 5943 .help = "operation type value", 5944 .call = parse_vc_modify_field_op, 5945 .comp = comp_set_modify_field_op, 5946 }, 5947 [ACTION_MODIFY_FIELD_DST_TYPE] = { 5948 .name = "dst_type", 5949 .help = "destination field type", 5950 .next = NEXT(action_modify_field_dst, 5951 NEXT_ENTRY(ACTION_MODIFY_FIELD_DST_TYPE_VALUE)), 5952 .call = parse_vc_conf, 5953 }, 5954 [ACTION_MODIFY_FIELD_DST_TYPE_VALUE] = { 5955 .name = "{dst_type}", 5956 .help = "destination field type value", 5957 .call = parse_vc_modify_field_id, 5958 .comp = comp_set_modify_field_id, 5959 }, 5960 [ACTION_MODIFY_FIELD_DST_LEVEL] = { 5961 .name = "dst_level", 5962 .help = "destination field level", 5963 .next = NEXT(action_modify_field_dst, 5964 NEXT_ENTRY(COMMON_UNSIGNED)), 5965 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 5966 dst.level)), 5967 .call = parse_vc_conf, 5968 }, 5969 [ACTION_MODIFY_FIELD_DST_OFFSET] = { 5970 .name = "dst_offset", 5971 .help = "destination field bit offset", 5972 .next = NEXT(action_modify_field_dst, 5973 NEXT_ENTRY(COMMON_UNSIGNED)), 5974 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 5975 dst.offset)), 5976 .call = parse_vc_conf, 5977 }, 5978 [ACTION_MODIFY_FIELD_SRC_TYPE] = { 5979 .name = "src_type", 5980 .help = "source field type", 5981 .next = NEXT(action_modify_field_src, 5982 NEXT_ENTRY(ACTION_MODIFY_FIELD_SRC_TYPE_VALUE)), 5983 .call = parse_vc_conf, 5984 }, 5985 [ACTION_MODIFY_FIELD_SRC_TYPE_VALUE] = { 5986 .name = "{src_type}", 5987 .help = "source field type value", 5988 .call = parse_vc_modify_field_id, 5989 .comp = comp_set_modify_field_id, 5990 }, 5991 [ACTION_MODIFY_FIELD_SRC_LEVEL] = { 5992 .name = "src_level", 5993 .help = "source field level", 5994 .next = NEXT(action_modify_field_src, 5995 NEXT_ENTRY(COMMON_UNSIGNED)), 5996 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 5997 src.level)), 5998 .call = parse_vc_conf, 5999 }, 6000 [ACTION_MODIFY_FIELD_SRC_OFFSET] = { 6001 .name = "src_offset", 6002 .help = "source field bit offset", 6003 .next = NEXT(action_modify_field_src, 6004 NEXT_ENTRY(COMMON_UNSIGNED)), 6005 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 6006 src.offset)), 6007 .call = parse_vc_conf, 6008 }, 6009 [ACTION_MODIFY_FIELD_SRC_VALUE] = { 6010 .name = "src_value", 6011 .help = "source immediate value", 6012 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 6013 NEXT_ENTRY(COMMON_HEX)), 6014 .args = ARGS(ARGS_ENTRY_ARB(0, 0), 6015 ARGS_ENTRY_ARB(0, 0), 6016 ARGS_ENTRY(struct rte_flow_action_modify_field, 6017 src.value)), 6018 .call = parse_vc_conf, 6019 }, 6020 [ACTION_MODIFY_FIELD_SRC_POINTER] = { 6021 .name = "src_ptr", 6022 .help = "pointer to source immediate value", 6023 .next = NEXT(NEXT_ENTRY(ACTION_MODIFY_FIELD_WIDTH), 6024 NEXT_ENTRY(COMMON_HEX)), 6025 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 6026 src.pvalue), 6027 ARGS_ENTRY_ARB(0, 0), 6028 ARGS_ENTRY_ARB 6029 (sizeof(struct rte_flow_action_modify_field), 6030 ACTION_MODIFY_PATTERN_SIZE)), 6031 .call = parse_vc_conf, 6032 }, 6033 [ACTION_MODIFY_FIELD_WIDTH] = { 6034 .name = "width", 6035 .help = "number of bits to copy", 6036 .next = NEXT(NEXT_ENTRY(ACTION_NEXT), 6037 NEXT_ENTRY(COMMON_UNSIGNED)), 6038 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_modify_field, 6039 width)), 6040 .call = parse_vc_conf, 6041 }, 6042 [ACTION_SEND_TO_KERNEL] = { 6043 .name = "send_to_kernel", 6044 .help = "send packets to kernel", 6045 .priv = PRIV_ACTION(SEND_TO_KERNEL, 0), 6046 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6047 .call = parse_vc, 6048 }, 6049 /* Top level command. */ 6050 [SET] = { 6051 .name = "set", 6052 .help = "set raw encap/decap/sample data", 6053 .type = "set raw_encap|raw_decap <index> <pattern>" 6054 " or set sample_actions <index> <action>", 6055 .next = NEXT(NEXT_ENTRY 6056 (SET_RAW_ENCAP, 6057 SET_RAW_DECAP, 6058 SET_SAMPLE_ACTIONS)), 6059 .call = parse_set_init, 6060 }, 6061 /* Sub-level commands. */ 6062 [SET_RAW_ENCAP] = { 6063 .name = "raw_encap", 6064 .help = "set raw encap data", 6065 .next = NEXT(next_set_raw), 6066 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6067 (offsetof(struct buffer, port), 6068 sizeof(((struct buffer *)0)->port), 6069 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 6070 .call = parse_set_raw_encap_decap, 6071 }, 6072 [SET_RAW_DECAP] = { 6073 .name = "raw_decap", 6074 .help = "set raw decap data", 6075 .next = NEXT(next_set_raw), 6076 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6077 (offsetof(struct buffer, port), 6078 sizeof(((struct buffer *)0)->port), 6079 0, RAW_ENCAP_CONFS_MAX_NUM - 1)), 6080 .call = parse_set_raw_encap_decap, 6081 }, 6082 [SET_RAW_INDEX] = { 6083 .name = "{index}", 6084 .type = "COMMON_UNSIGNED", 6085 .help = "index of raw_encap/raw_decap data", 6086 .next = NEXT(next_item), 6087 .call = parse_port, 6088 }, 6089 [SET_SAMPLE_INDEX] = { 6090 .name = "{index}", 6091 .type = "UNSIGNED", 6092 .help = "index of sample actions", 6093 .next = NEXT(next_action_sample), 6094 .call = parse_port, 6095 }, 6096 [SET_SAMPLE_ACTIONS] = { 6097 .name = "sample_actions", 6098 .help = "set sample actions list", 6099 .next = NEXT(NEXT_ENTRY(SET_SAMPLE_INDEX)), 6100 .args = ARGS(ARGS_ENTRY_ARB_BOUNDED 6101 (offsetof(struct buffer, port), 6102 sizeof(((struct buffer *)0)->port), 6103 0, RAW_SAMPLE_CONFS_MAX_NUM - 1)), 6104 .call = parse_set_sample_action, 6105 }, 6106 [ACTION_SET_TAG] = { 6107 .name = "set_tag", 6108 .help = "set tag", 6109 .priv = PRIV_ACTION(SET_TAG, 6110 sizeof(struct rte_flow_action_set_tag)), 6111 .next = NEXT(action_set_tag), 6112 .call = parse_vc, 6113 }, 6114 [ACTION_SET_TAG_INDEX] = { 6115 .name = "index", 6116 .help = "index of tag array", 6117 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 6118 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_set_tag, index)), 6119 .call = parse_vc_conf, 6120 }, 6121 [ACTION_SET_TAG_DATA] = { 6122 .name = "data", 6123 .help = "tag value", 6124 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 6125 .args = ARGS(ARGS_ENTRY 6126 (struct rte_flow_action_set_tag, data)), 6127 .call = parse_vc_conf, 6128 }, 6129 [ACTION_SET_TAG_MASK] = { 6130 .name = "mask", 6131 .help = "mask for tag value", 6132 .next = NEXT(action_set_tag, NEXT_ENTRY(COMMON_UNSIGNED)), 6133 .args = ARGS(ARGS_ENTRY 6134 (struct rte_flow_action_set_tag, mask)), 6135 .call = parse_vc_conf, 6136 }, 6137 [ACTION_SET_META] = { 6138 .name = "set_meta", 6139 .help = "set metadata", 6140 .priv = PRIV_ACTION(SET_META, 6141 sizeof(struct rte_flow_action_set_meta)), 6142 .next = NEXT(action_set_meta), 6143 .call = parse_vc_action_set_meta, 6144 }, 6145 [ACTION_SET_META_DATA] = { 6146 .name = "data", 6147 .help = "metadata value", 6148 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 6149 .args = ARGS(ARGS_ENTRY 6150 (struct rte_flow_action_set_meta, data)), 6151 .call = parse_vc_conf, 6152 }, 6153 [ACTION_SET_META_MASK] = { 6154 .name = "mask", 6155 .help = "mask for metadata value", 6156 .next = NEXT(action_set_meta, NEXT_ENTRY(COMMON_UNSIGNED)), 6157 .args = ARGS(ARGS_ENTRY 6158 (struct rte_flow_action_set_meta, mask)), 6159 .call = parse_vc_conf, 6160 }, 6161 [ACTION_SET_IPV4_DSCP] = { 6162 .name = "set_ipv4_dscp", 6163 .help = "set DSCP value", 6164 .priv = PRIV_ACTION(SET_IPV4_DSCP, 6165 sizeof(struct rte_flow_action_set_dscp)), 6166 .next = NEXT(action_set_ipv4_dscp), 6167 .call = parse_vc, 6168 }, 6169 [ACTION_SET_IPV4_DSCP_VALUE] = { 6170 .name = "dscp_value", 6171 .help = "new IPv4 DSCP value to set", 6172 .next = NEXT(action_set_ipv4_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 6173 .args = ARGS(ARGS_ENTRY 6174 (struct rte_flow_action_set_dscp, dscp)), 6175 .call = parse_vc_conf, 6176 }, 6177 [ACTION_SET_IPV6_DSCP] = { 6178 .name = "set_ipv6_dscp", 6179 .help = "set DSCP value", 6180 .priv = PRIV_ACTION(SET_IPV6_DSCP, 6181 sizeof(struct rte_flow_action_set_dscp)), 6182 .next = NEXT(action_set_ipv6_dscp), 6183 .call = parse_vc, 6184 }, 6185 [ACTION_SET_IPV6_DSCP_VALUE] = { 6186 .name = "dscp_value", 6187 .help = "new IPv6 DSCP value to set", 6188 .next = NEXT(action_set_ipv6_dscp, NEXT_ENTRY(COMMON_UNSIGNED)), 6189 .args = ARGS(ARGS_ENTRY 6190 (struct rte_flow_action_set_dscp, dscp)), 6191 .call = parse_vc_conf, 6192 }, 6193 [ACTION_AGE] = { 6194 .name = "age", 6195 .help = "set a specific metadata header", 6196 .next = NEXT(action_age), 6197 .priv = PRIV_ACTION(AGE, 6198 sizeof(struct rte_flow_action_age)), 6199 .call = parse_vc, 6200 }, 6201 [ACTION_AGE_TIMEOUT] = { 6202 .name = "timeout", 6203 .help = "flow age timeout value", 6204 .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, 6205 timeout, 24)), 6206 .next = NEXT(action_age, NEXT_ENTRY(COMMON_UNSIGNED)), 6207 .call = parse_vc_conf, 6208 }, 6209 [ACTION_SAMPLE] = { 6210 .name = "sample", 6211 .help = "set a sample action", 6212 .next = NEXT(action_sample), 6213 .priv = PRIV_ACTION(SAMPLE, 6214 sizeof(struct action_sample_data)), 6215 .call = parse_vc_action_sample, 6216 }, 6217 [ACTION_SAMPLE_RATIO] = { 6218 .name = "ratio", 6219 .help = "flow sample ratio value", 6220 .next = NEXT(action_sample, NEXT_ENTRY(COMMON_UNSIGNED)), 6221 .args = ARGS(ARGS_ENTRY_ARB 6222 (offsetof(struct action_sample_data, conf) + 6223 offsetof(struct rte_flow_action_sample, ratio), 6224 sizeof(((struct rte_flow_action_sample *)0)-> 6225 ratio))), 6226 }, 6227 [ACTION_SAMPLE_INDEX] = { 6228 .name = "index", 6229 .help = "the index of sample actions list", 6230 .next = NEXT(NEXT_ENTRY(ACTION_SAMPLE_INDEX_VALUE)), 6231 }, 6232 [ACTION_SAMPLE_INDEX_VALUE] = { 6233 .name = "{index}", 6234 .type = "COMMON_UNSIGNED", 6235 .help = "unsigned integer value", 6236 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6237 .call = parse_vc_action_sample_index, 6238 .comp = comp_set_sample_index, 6239 }, 6240 [ACTION_CONNTRACK] = { 6241 .name = "conntrack", 6242 .help = "create a conntrack object", 6243 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6244 .priv = PRIV_ACTION(CONNTRACK, 6245 sizeof(struct rte_flow_action_conntrack)), 6246 .call = parse_vc, 6247 }, 6248 [ACTION_CONNTRACK_UPDATE] = { 6249 .name = "conntrack_update", 6250 .help = "update a conntrack object", 6251 .next = NEXT(action_update_conntrack), 6252 .priv = PRIV_ACTION(CONNTRACK, 6253 sizeof(struct rte_flow_modify_conntrack)), 6254 .call = parse_vc, 6255 }, 6256 [ACTION_CONNTRACK_UPDATE_DIR] = { 6257 .name = "dir", 6258 .help = "update a conntrack object direction", 6259 .next = NEXT(action_update_conntrack), 6260 .call = parse_vc_action_conntrack_update, 6261 }, 6262 [ACTION_CONNTRACK_UPDATE_CTX] = { 6263 .name = "ctx", 6264 .help = "update a conntrack object context", 6265 .next = NEXT(action_update_conntrack), 6266 .call = parse_vc_action_conntrack_update, 6267 }, 6268 [ACTION_PORT_REPRESENTOR] = { 6269 .name = "port_representor", 6270 .help = "at embedded switch level, send matching traffic to the given ethdev", 6271 .priv = PRIV_ACTION(PORT_REPRESENTOR, 6272 sizeof(struct rte_flow_action_ethdev)), 6273 .next = NEXT(action_port_representor), 6274 .call = parse_vc, 6275 }, 6276 [ACTION_PORT_REPRESENTOR_PORT_ID] = { 6277 .name = "port_id", 6278 .help = "ethdev port ID", 6279 .next = NEXT(action_port_representor, 6280 NEXT_ENTRY(COMMON_UNSIGNED)), 6281 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 6282 port_id)), 6283 .call = parse_vc_conf, 6284 }, 6285 [ACTION_REPRESENTED_PORT] = { 6286 .name = "represented_port", 6287 .help = "at embedded switch level, send matching traffic to the entity represented by the given ethdev", 6288 .priv = PRIV_ACTION(REPRESENTED_PORT, 6289 sizeof(struct rte_flow_action_ethdev)), 6290 .next = NEXT(action_represented_port), 6291 .call = parse_vc, 6292 }, 6293 [ACTION_REPRESENTED_PORT_ETHDEV_PORT_ID] = { 6294 .name = "ethdev_port_id", 6295 .help = "ethdev port ID", 6296 .next = NEXT(action_represented_port, 6297 NEXT_ENTRY(COMMON_UNSIGNED)), 6298 .args = ARGS(ARGS_ENTRY(struct rte_flow_action_ethdev, 6299 port_id)), 6300 .call = parse_vc_conf, 6301 }, 6302 /* Indirect action destroy arguments. */ 6303 [INDIRECT_ACTION_DESTROY_ID] = { 6304 .name = "action_id", 6305 .help = "specify a indirect action id to destroy", 6306 .next = NEXT(next_ia_destroy_attr, 6307 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 6308 .args = ARGS(ARGS_ENTRY_PTR(struct buffer, 6309 args.ia_destroy.action_id)), 6310 .call = parse_ia_destroy, 6311 }, 6312 /* Indirect action create arguments. */ 6313 [INDIRECT_ACTION_CREATE_ID] = { 6314 .name = "action_id", 6315 .help = "specify a indirect action id to create", 6316 .next = NEXT(next_ia_create_attr, 6317 NEXT_ENTRY(COMMON_INDIRECT_ACTION_ID)), 6318 .args = ARGS(ARGS_ENTRY(struct buffer, args.vc.attr.group)), 6319 }, 6320 [ACTION_INDIRECT] = { 6321 .name = "indirect", 6322 .help = "apply indirect action by id", 6323 .priv = PRIV_ACTION(INDIRECT, 0), 6324 .next = NEXT(NEXT_ENTRY(INDIRECT_ACTION_ID2PTR)), 6325 .args = ARGS(ARGS_ENTRY_ARB(0, sizeof(uint32_t))), 6326 .call = parse_vc, 6327 }, 6328 [INDIRECT_ACTION_ID2PTR] = { 6329 .name = "{action_id}", 6330 .type = "INDIRECT_ACTION_ID", 6331 .help = "indirect action id", 6332 .next = NEXT(NEXT_ENTRY(ACTION_NEXT)), 6333 .call = parse_ia_id2ptr, 6334 .comp = comp_none, 6335 }, 6336 [INDIRECT_ACTION_INGRESS] = { 6337 .name = "ingress", 6338 .help = "affect rule to ingress", 6339 .next = NEXT(next_ia_create_attr), 6340 .call = parse_ia, 6341 }, 6342 [INDIRECT_ACTION_EGRESS] = { 6343 .name = "egress", 6344 .help = "affect rule to egress", 6345 .next = NEXT(next_ia_create_attr), 6346 .call = parse_ia, 6347 }, 6348 [INDIRECT_ACTION_TRANSFER] = { 6349 .name = "transfer", 6350 .help = "affect rule to transfer", 6351 .next = NEXT(next_ia_create_attr), 6352 .call = parse_ia, 6353 }, 6354 [INDIRECT_ACTION_SPEC] = { 6355 .name = "action", 6356 .help = "specify action to create indirect handle", 6357 .next = NEXT(next_action), 6358 }, 6359 [ACTION_POL_G] = { 6360 .name = "g_actions", 6361 .help = "submit a list of associated actions for green", 6362 .next = NEXT(next_action), 6363 .call = parse_mp, 6364 }, 6365 [ACTION_POL_Y] = { 6366 .name = "y_actions", 6367 .help = "submit a list of associated actions for yellow", 6368 .next = NEXT(next_action), 6369 }, 6370 [ACTION_POL_R] = { 6371 .name = "r_actions", 6372 .help = "submit a list of associated actions for red", 6373 .next = NEXT(next_action), 6374 }, 6375 6376 /* Top-level command. */ 6377 [ADD] = { 6378 .name = "add", 6379 .type = "port meter policy {port_id} {arg}", 6380 .help = "add port meter policy", 6381 .next = NEXT(NEXT_ENTRY(ITEM_POL_PORT)), 6382 .call = parse_init, 6383 }, 6384 /* Sub-level commands. */ 6385 [ITEM_POL_PORT] = { 6386 .name = "port", 6387 .help = "add port meter policy", 6388 .next = NEXT(NEXT_ENTRY(ITEM_POL_METER)), 6389 }, 6390 [ITEM_POL_METER] = { 6391 .name = "meter", 6392 .help = "add port meter policy", 6393 .next = NEXT(NEXT_ENTRY(ITEM_POL_POLICY)), 6394 }, 6395 [ITEM_POL_POLICY] = { 6396 .name = "policy", 6397 .help = "add port meter policy", 6398 .next = NEXT(NEXT_ENTRY(ACTION_POL_R), 6399 NEXT_ENTRY(ACTION_POL_Y), 6400 NEXT_ENTRY(ACTION_POL_G), 6401 NEXT_ENTRY(COMMON_POLICY_ID), 6402 NEXT_ENTRY(COMMON_PORT_ID)), 6403 .args = ARGS(ARGS_ENTRY(struct buffer, args.policy.policy_id), 6404 ARGS_ENTRY(struct buffer, port)), 6405 .call = parse_mp, 6406 }, 6407 }; 6408 6409 /** Remove and return last entry from argument stack. */ 6410 static const struct arg * 6411 pop_args(struct context *ctx) 6412 { 6413 return ctx->args_num ? ctx->args[--ctx->args_num] : NULL; 6414 } 6415 6416 /** Add entry on top of the argument stack. */ 6417 static int 6418 push_args(struct context *ctx, const struct arg *arg) 6419 { 6420 if (ctx->args_num == CTX_STACK_SIZE) 6421 return -1; 6422 ctx->args[ctx->args_num++] = arg; 6423 return 0; 6424 } 6425 6426 /** Spread value into buffer according to bit-mask. */ 6427 static size_t 6428 arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg) 6429 { 6430 uint32_t i = arg->size; 6431 uint32_t end = 0; 6432 int sub = 1; 6433 int add = 0; 6434 size_t len = 0; 6435 6436 if (!arg->mask) 6437 return 0; 6438 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 6439 if (!arg->hton) { 6440 i = 0; 6441 end = arg->size; 6442 sub = 0; 6443 add = 1; 6444 } 6445 #endif 6446 while (i != end) { 6447 unsigned int shift = 0; 6448 uint8_t *buf = (uint8_t *)dst + arg->offset + (i -= sub); 6449 6450 for (shift = 0; arg->mask[i] >> shift; ++shift) { 6451 if (!(arg->mask[i] & (1 << shift))) 6452 continue; 6453 ++len; 6454 if (!dst) 6455 continue; 6456 *buf &= ~(1 << shift); 6457 *buf |= (val & 1) << shift; 6458 val >>= 1; 6459 } 6460 i += add; 6461 } 6462 return len; 6463 } 6464 6465 /** Compare a string with a partial one of a given length. */ 6466 static int 6467 strcmp_partial(const char *full, const char *partial, size_t partial_len) 6468 { 6469 int r = strncmp(full, partial, partial_len); 6470 6471 if (r) 6472 return r; 6473 if (strlen(full) <= partial_len) 6474 return 0; 6475 return full[partial_len]; 6476 } 6477 6478 /** 6479 * Parse a prefix length and generate a bit-mask. 6480 * 6481 * Last argument (ctx->args) is retrieved to determine mask size, storage 6482 * location and whether the result must use network byte ordering. 6483 */ 6484 static int 6485 parse_prefix(struct context *ctx, const struct token *token, 6486 const char *str, unsigned int len, 6487 void *buf, unsigned int size) 6488 { 6489 const struct arg *arg = pop_args(ctx); 6490 static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff"; 6491 char *end; 6492 uintmax_t u; 6493 unsigned int bytes; 6494 unsigned int extra; 6495 6496 (void)token; 6497 /* Argument is expected. */ 6498 if (!arg) 6499 return -1; 6500 errno = 0; 6501 u = strtoumax(str, &end, 0); 6502 if (errno || (size_t)(end - str) != len) 6503 goto error; 6504 if (arg->mask) { 6505 uintmax_t v = 0; 6506 6507 extra = arg_entry_bf_fill(NULL, 0, arg); 6508 if (u > extra) 6509 goto error; 6510 if (!ctx->object) 6511 return len; 6512 extra -= u; 6513 while (u--) 6514 (v <<= 1, v |= 1); 6515 v <<= extra; 6516 if (!arg_entry_bf_fill(ctx->object, v, arg) || 6517 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 6518 goto error; 6519 return len; 6520 } 6521 bytes = u / 8; 6522 extra = u % 8; 6523 size = arg->size; 6524 if (bytes > size || bytes + !!extra > size) 6525 goto error; 6526 if (!ctx->object) 6527 return len; 6528 buf = (uint8_t *)ctx->object + arg->offset; 6529 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 6530 if (!arg->hton) { 6531 memset((uint8_t *)buf + size - bytes, 0xff, bytes); 6532 memset(buf, 0x00, size - bytes); 6533 if (extra) 6534 ((uint8_t *)buf)[size - bytes - 1] = conv[extra]; 6535 } else 6536 #endif 6537 { 6538 memset(buf, 0xff, bytes); 6539 memset((uint8_t *)buf + bytes, 0x00, size - bytes); 6540 if (extra) 6541 ((uint8_t *)buf)[bytes] = conv[extra]; 6542 } 6543 if (ctx->objmask) 6544 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 6545 return len; 6546 error: 6547 push_args(ctx, arg); 6548 return -1; 6549 } 6550 6551 /** Default parsing function for token name matching. */ 6552 static int 6553 parse_default(struct context *ctx, const struct token *token, 6554 const char *str, unsigned int len, 6555 void *buf, unsigned int size) 6556 { 6557 (void)ctx; 6558 (void)buf; 6559 (void)size; 6560 if (strcmp_partial(token->name, str, len)) 6561 return -1; 6562 return len; 6563 } 6564 6565 /** Parse flow command, initialize output buffer for subsequent tokens. */ 6566 static int 6567 parse_init(struct context *ctx, const struct token *token, 6568 const char *str, unsigned int len, 6569 void *buf, unsigned int size) 6570 { 6571 struct buffer *out = buf; 6572 6573 /* Token name must match. */ 6574 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 6575 return -1; 6576 /* Nothing else to do if there is no buffer. */ 6577 if (!out) 6578 return len; 6579 /* Make sure buffer is large enough. */ 6580 if (size < sizeof(*out)) 6581 return -1; 6582 /* Initialize buffer. */ 6583 memset(out, 0x00, sizeof(*out)); 6584 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 6585 ctx->objdata = 0; 6586 ctx->object = out; 6587 ctx->objmask = NULL; 6588 return len; 6589 } 6590 6591 /** Parse tokens for indirect action commands. */ 6592 static int 6593 parse_ia(struct context *ctx, const struct token *token, 6594 const char *str, unsigned int len, 6595 void *buf, unsigned int size) 6596 { 6597 struct buffer *out = buf; 6598 6599 /* Token name must match. */ 6600 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 6601 return -1; 6602 /* Nothing else to do if there is no buffer. */ 6603 if (!out) 6604 return len; 6605 if (!out->command) { 6606 if (ctx->curr != INDIRECT_ACTION) 6607 return -1; 6608 if (sizeof(*out) > size) 6609 return -1; 6610 out->command = ctx->curr; 6611 ctx->objdata = 0; 6612 ctx->object = out; 6613 ctx->objmask = NULL; 6614 out->args.vc.data = (uint8_t *)out + size; 6615 return len; 6616 } 6617 switch (ctx->curr) { 6618 case INDIRECT_ACTION_CREATE: 6619 case INDIRECT_ACTION_UPDATE: 6620 out->args.vc.actions = 6621 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 6622 sizeof(double)); 6623 out->args.vc.attr.group = UINT32_MAX; 6624 /* fallthrough */ 6625 case INDIRECT_ACTION_QUERY: 6626 out->command = ctx->curr; 6627 ctx->objdata = 0; 6628 ctx->object = out; 6629 ctx->objmask = NULL; 6630 return len; 6631 case INDIRECT_ACTION_EGRESS: 6632 out->args.vc.attr.egress = 1; 6633 return len; 6634 case INDIRECT_ACTION_INGRESS: 6635 out->args.vc.attr.ingress = 1; 6636 return len; 6637 case INDIRECT_ACTION_TRANSFER: 6638 out->args.vc.attr.transfer = 1; 6639 return len; 6640 default: 6641 return -1; 6642 } 6643 } 6644 6645 6646 /** Parse tokens for indirect action destroy command. */ 6647 static int 6648 parse_ia_destroy(struct context *ctx, const struct token *token, 6649 const char *str, unsigned int len, 6650 void *buf, unsigned int size) 6651 { 6652 struct buffer *out = buf; 6653 uint32_t *action_id; 6654 6655 /* Token name must match. */ 6656 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 6657 return -1; 6658 /* Nothing else to do if there is no buffer. */ 6659 if (!out) 6660 return len; 6661 if (!out->command || out->command == INDIRECT_ACTION) { 6662 if (ctx->curr != INDIRECT_ACTION_DESTROY) 6663 return -1; 6664 if (sizeof(*out) > size) 6665 return -1; 6666 out->command = ctx->curr; 6667 ctx->objdata = 0; 6668 ctx->object = out; 6669 ctx->objmask = NULL; 6670 out->args.ia_destroy.action_id = 6671 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 6672 sizeof(double)); 6673 return len; 6674 } 6675 action_id = out->args.ia_destroy.action_id 6676 + out->args.ia_destroy.action_id_n++; 6677 if ((uint8_t *)action_id > (uint8_t *)out + size) 6678 return -1; 6679 ctx->objdata = 0; 6680 ctx->object = action_id; 6681 ctx->objmask = NULL; 6682 return len; 6683 } 6684 6685 /** Parse tokens for indirect action commands. */ 6686 static int 6687 parse_qia(struct context *ctx, const struct token *token, 6688 const char *str, unsigned int len, 6689 void *buf, unsigned int size) 6690 { 6691 struct buffer *out = buf; 6692 6693 /* Token name must match. */ 6694 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 6695 return -1; 6696 /* Nothing else to do if there is no buffer. */ 6697 if (!out) 6698 return len; 6699 if (!out->command) { 6700 if (ctx->curr != QUEUE) 6701 return -1; 6702 if (sizeof(*out) > size) 6703 return -1; 6704 out->args.vc.data = (uint8_t *)out + size; 6705 return len; 6706 } 6707 switch (ctx->curr) { 6708 case QUEUE_INDIRECT_ACTION: 6709 return len; 6710 case QUEUE_INDIRECT_ACTION_CREATE: 6711 case QUEUE_INDIRECT_ACTION_UPDATE: 6712 out->args.vc.actions = 6713 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 6714 sizeof(double)); 6715 out->args.vc.attr.group = UINT32_MAX; 6716 /* fallthrough */ 6717 case QUEUE_INDIRECT_ACTION_QUERY: 6718 out->command = ctx->curr; 6719 ctx->objdata = 0; 6720 ctx->object = out; 6721 ctx->objmask = NULL; 6722 return len; 6723 case QUEUE_INDIRECT_ACTION_EGRESS: 6724 out->args.vc.attr.egress = 1; 6725 return len; 6726 case QUEUE_INDIRECT_ACTION_INGRESS: 6727 out->args.vc.attr.ingress = 1; 6728 return len; 6729 case QUEUE_INDIRECT_ACTION_TRANSFER: 6730 out->args.vc.attr.transfer = 1; 6731 return len; 6732 case QUEUE_INDIRECT_ACTION_CREATE_POSTPONE: 6733 return len; 6734 default: 6735 return -1; 6736 } 6737 } 6738 6739 /** Parse tokens for indirect action destroy command. */ 6740 static int 6741 parse_qia_destroy(struct context *ctx, const struct token *token, 6742 const char *str, unsigned int len, 6743 void *buf, unsigned int size) 6744 { 6745 struct buffer *out = buf; 6746 uint32_t *action_id; 6747 6748 /* Token name must match. */ 6749 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 6750 return -1; 6751 /* Nothing else to do if there is no buffer. */ 6752 if (!out) 6753 return len; 6754 if (!out->command || out->command == QUEUE) { 6755 if (ctx->curr != QUEUE_INDIRECT_ACTION_DESTROY) 6756 return -1; 6757 if (sizeof(*out) > size) 6758 return -1; 6759 out->command = ctx->curr; 6760 ctx->objdata = 0; 6761 ctx->object = out; 6762 ctx->objmask = NULL; 6763 out->args.ia_destroy.action_id = 6764 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 6765 sizeof(double)); 6766 return len; 6767 } 6768 switch (ctx->curr) { 6769 case QUEUE_INDIRECT_ACTION: 6770 out->command = ctx->curr; 6771 ctx->objdata = 0; 6772 ctx->object = out; 6773 ctx->objmask = NULL; 6774 return len; 6775 case QUEUE_INDIRECT_ACTION_DESTROY_ID: 6776 action_id = out->args.ia_destroy.action_id 6777 + out->args.ia_destroy.action_id_n++; 6778 if ((uint8_t *)action_id > (uint8_t *)out + size) 6779 return -1; 6780 ctx->objdata = 0; 6781 ctx->object = action_id; 6782 ctx->objmask = NULL; 6783 return len; 6784 case QUEUE_INDIRECT_ACTION_DESTROY_POSTPONE: 6785 return len; 6786 default: 6787 return -1; 6788 } 6789 } 6790 6791 /** Parse tokens for meter policy action commands. */ 6792 static int 6793 parse_mp(struct context *ctx, const struct token *token, 6794 const char *str, unsigned int len, 6795 void *buf, unsigned int size) 6796 { 6797 struct buffer *out = buf; 6798 6799 /* Token name must match. */ 6800 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 6801 return -1; 6802 /* Nothing else to do if there is no buffer. */ 6803 if (!out) 6804 return len; 6805 if (!out->command) { 6806 if (ctx->curr != ITEM_POL_POLICY) 6807 return -1; 6808 if (sizeof(*out) > size) 6809 return -1; 6810 out->command = ctx->curr; 6811 ctx->objdata = 0; 6812 ctx->object = out; 6813 ctx->objmask = NULL; 6814 out->args.vc.data = (uint8_t *)out + size; 6815 return len; 6816 } 6817 switch (ctx->curr) { 6818 case ACTION_POL_G: 6819 out->args.vc.actions = 6820 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 6821 sizeof(double)); 6822 out->command = ctx->curr; 6823 ctx->objdata = 0; 6824 ctx->object = out; 6825 ctx->objmask = NULL; 6826 return len; 6827 default: 6828 return -1; 6829 } 6830 } 6831 6832 /** Parse tokens for validate/create commands. */ 6833 static int 6834 parse_vc(struct context *ctx, const struct token *token, 6835 const char *str, unsigned int len, 6836 void *buf, unsigned int size) 6837 { 6838 struct buffer *out = buf; 6839 uint8_t *data; 6840 uint32_t data_size; 6841 6842 /* Token name must match. */ 6843 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 6844 return -1; 6845 /* Nothing else to do if there is no buffer. */ 6846 if (!out) 6847 return len; 6848 if (!out->command) { 6849 if (ctx->curr != VALIDATE && ctx->curr != CREATE && 6850 ctx->curr != PATTERN_TEMPLATE_CREATE && 6851 ctx->curr != ACTIONS_TEMPLATE_CREATE) 6852 return -1; 6853 if (sizeof(*out) > size) 6854 return -1; 6855 out->command = ctx->curr; 6856 ctx->objdata = 0; 6857 ctx->object = out; 6858 ctx->objmask = NULL; 6859 out->args.vc.data = (uint8_t *)out + size; 6860 return len; 6861 } 6862 ctx->objdata = 0; 6863 switch (ctx->curr) { 6864 default: 6865 ctx->object = &out->args.vc.attr; 6866 break; 6867 case VC_TUNNEL_SET: 6868 case VC_TUNNEL_MATCH: 6869 ctx->object = &out->args.vc.tunnel_ops; 6870 break; 6871 } 6872 ctx->objmask = NULL; 6873 switch (ctx->curr) { 6874 case VC_GROUP: 6875 case VC_PRIORITY: 6876 return len; 6877 case VC_TUNNEL_SET: 6878 out->args.vc.tunnel_ops.enabled = 1; 6879 out->args.vc.tunnel_ops.actions = 1; 6880 return len; 6881 case VC_TUNNEL_MATCH: 6882 out->args.vc.tunnel_ops.enabled = 1; 6883 out->args.vc.tunnel_ops.items = 1; 6884 return len; 6885 case VC_INGRESS: 6886 out->args.vc.attr.ingress = 1; 6887 return len; 6888 case VC_EGRESS: 6889 out->args.vc.attr.egress = 1; 6890 return len; 6891 case VC_TRANSFER: 6892 out->args.vc.attr.transfer = 1; 6893 return len; 6894 case ITEM_PATTERN: 6895 out->args.vc.pattern = 6896 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 6897 sizeof(double)); 6898 ctx->object = out->args.vc.pattern; 6899 ctx->objmask = NULL; 6900 return len; 6901 case ITEM_END: 6902 if ((out->command == VALIDATE || out->command == CREATE) && 6903 ctx->last) 6904 return -1; 6905 if (out->command == PATTERN_TEMPLATE_CREATE && 6906 !ctx->last) 6907 return -1; 6908 break; 6909 case ACTIONS: 6910 out->args.vc.actions = 6911 (void *)RTE_ALIGN_CEIL((uintptr_t) 6912 (out->args.vc.pattern + 6913 out->args.vc.pattern_n), 6914 sizeof(double)); 6915 ctx->object = out->args.vc.actions; 6916 ctx->objmask = NULL; 6917 return len; 6918 default: 6919 if (!token->priv) 6920 return -1; 6921 break; 6922 } 6923 if (!out->args.vc.actions) { 6924 const struct parse_item_priv *priv = token->priv; 6925 struct rte_flow_item *item = 6926 out->args.vc.pattern + out->args.vc.pattern_n; 6927 6928 data_size = priv->size * 3; /* spec, last, mask */ 6929 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 6930 (out->args.vc.data - data_size), 6931 sizeof(double)); 6932 if ((uint8_t *)item + sizeof(*item) > data) 6933 return -1; 6934 *item = (struct rte_flow_item){ 6935 .type = priv->type, 6936 }; 6937 ++out->args.vc.pattern_n; 6938 ctx->object = item; 6939 ctx->objmask = NULL; 6940 } else { 6941 const struct parse_action_priv *priv = token->priv; 6942 struct rte_flow_action *action = 6943 out->args.vc.actions + out->args.vc.actions_n; 6944 6945 data_size = priv->size; /* configuration */ 6946 data = (void *)RTE_ALIGN_FLOOR((uintptr_t) 6947 (out->args.vc.data - data_size), 6948 sizeof(double)); 6949 if ((uint8_t *)action + sizeof(*action) > data) 6950 return -1; 6951 *action = (struct rte_flow_action){ 6952 .type = priv->type, 6953 .conf = data_size ? data : NULL, 6954 }; 6955 ++out->args.vc.actions_n; 6956 ctx->object = action; 6957 ctx->objmask = NULL; 6958 } 6959 memset(data, 0, data_size); 6960 out->args.vc.data = data; 6961 ctx->objdata = data_size; 6962 return len; 6963 } 6964 6965 /** Parse pattern item parameter type. */ 6966 static int 6967 parse_vc_spec(struct context *ctx, const struct token *token, 6968 const char *str, unsigned int len, 6969 void *buf, unsigned int size) 6970 { 6971 struct buffer *out = buf; 6972 struct rte_flow_item *item; 6973 uint32_t data_size; 6974 int index; 6975 int objmask = 0; 6976 6977 (void)size; 6978 /* Token name must match. */ 6979 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 6980 return -1; 6981 /* Parse parameter types. */ 6982 switch (ctx->curr) { 6983 static const enum index prefix[] = NEXT_ENTRY(COMMON_PREFIX); 6984 6985 case ITEM_PARAM_IS: 6986 index = 0; 6987 objmask = 1; 6988 break; 6989 case ITEM_PARAM_SPEC: 6990 index = 0; 6991 break; 6992 case ITEM_PARAM_LAST: 6993 index = 1; 6994 break; 6995 case ITEM_PARAM_PREFIX: 6996 /* Modify next token to expect a prefix. */ 6997 if (ctx->next_num < 2) 6998 return -1; 6999 ctx->next[ctx->next_num - 2] = prefix; 7000 /* Fall through. */ 7001 case ITEM_PARAM_MASK: 7002 index = 2; 7003 break; 7004 default: 7005 return -1; 7006 } 7007 /* Nothing else to do if there is no buffer. */ 7008 if (!out) 7009 return len; 7010 if (!out->args.vc.pattern_n) 7011 return -1; 7012 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 7013 data_size = ctx->objdata / 3; /* spec, last, mask */ 7014 /* Point to selected object. */ 7015 ctx->object = out->args.vc.data + (data_size * index); 7016 if (objmask) { 7017 ctx->objmask = out->args.vc.data + (data_size * 2); /* mask */ 7018 item->mask = ctx->objmask; 7019 } else 7020 ctx->objmask = NULL; 7021 /* Update relevant item pointer. */ 7022 *((const void **[]){ &item->spec, &item->last, &item->mask })[index] = 7023 ctx->object; 7024 return len; 7025 } 7026 7027 /** Parse action configuration field. */ 7028 static int 7029 parse_vc_conf(struct context *ctx, const struct token *token, 7030 const char *str, unsigned int len, 7031 void *buf, unsigned int size) 7032 { 7033 struct buffer *out = buf; 7034 7035 (void)size; 7036 /* Token name must match. */ 7037 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 7038 return -1; 7039 /* Nothing else to do if there is no buffer. */ 7040 if (!out) 7041 return len; 7042 /* Point to selected object. */ 7043 ctx->object = out->args.vc.data; 7044 ctx->objmask = NULL; 7045 return len; 7046 } 7047 7048 /** Parse eCPRI common header type field. */ 7049 static int 7050 parse_vc_item_ecpri_type(struct context *ctx, const struct token *token, 7051 const char *str, unsigned int len, 7052 void *buf, unsigned int size) 7053 { 7054 struct rte_flow_item_ecpri *ecpri; 7055 struct rte_flow_item_ecpri *ecpri_mask; 7056 struct rte_flow_item *item; 7057 uint32_t data_size; 7058 uint8_t msg_type; 7059 struct buffer *out = buf; 7060 const struct arg *arg; 7061 7062 (void)size; 7063 /* Token name must match. */ 7064 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 7065 return -1; 7066 switch (ctx->curr) { 7067 case ITEM_ECPRI_COMMON_TYPE_IQ_DATA: 7068 msg_type = RTE_ECPRI_MSG_TYPE_IQ_DATA; 7069 break; 7070 case ITEM_ECPRI_COMMON_TYPE_RTC_CTRL: 7071 msg_type = RTE_ECPRI_MSG_TYPE_RTC_CTRL; 7072 break; 7073 case ITEM_ECPRI_COMMON_TYPE_DLY_MSR: 7074 msg_type = RTE_ECPRI_MSG_TYPE_DLY_MSR; 7075 break; 7076 default: 7077 return -1; 7078 } 7079 if (!ctx->object) 7080 return len; 7081 arg = pop_args(ctx); 7082 if (!arg) 7083 return -1; 7084 ecpri = (struct rte_flow_item_ecpri *)out->args.vc.data; 7085 ecpri->hdr.common.type = msg_type; 7086 data_size = ctx->objdata / 3; /* spec, last, mask */ 7087 ecpri_mask = (struct rte_flow_item_ecpri *)(out->args.vc.data + 7088 (data_size * 2)); 7089 ecpri_mask->hdr.common.type = 0xFF; 7090 if (arg->hton) { 7091 ecpri->hdr.common.u32 = rte_cpu_to_be_32(ecpri->hdr.common.u32); 7092 ecpri_mask->hdr.common.u32 = 7093 rte_cpu_to_be_32(ecpri_mask->hdr.common.u32); 7094 } 7095 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 7096 item->spec = ecpri; 7097 item->mask = ecpri_mask; 7098 return len; 7099 } 7100 7101 /** Parse L2TPv2 common header type field. */ 7102 static int 7103 parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token, 7104 const char *str, unsigned int len, 7105 void *buf, unsigned int size) 7106 { 7107 struct rte_flow_item_l2tpv2 *l2tpv2; 7108 struct rte_flow_item_l2tpv2 *l2tpv2_mask; 7109 struct rte_flow_item *item; 7110 uint32_t data_size; 7111 uint16_t msg_type = 0; 7112 struct buffer *out = buf; 7113 const struct arg *arg; 7114 7115 (void)size; 7116 /* Token name must match. */ 7117 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 7118 return -1; 7119 switch (ctx->curr) { 7120 case ITEM_L2TPV2_TYPE_DATA: 7121 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA; 7122 break; 7123 case ITEM_L2TPV2_TYPE_DATA_L: 7124 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L; 7125 break; 7126 case ITEM_L2TPV2_TYPE_DATA_S: 7127 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_S; 7128 break; 7129 case ITEM_L2TPV2_TYPE_DATA_O: 7130 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_O; 7131 break; 7132 case ITEM_L2TPV2_TYPE_DATA_L_S: 7133 msg_type |= RTE_L2TPV2_MSG_TYPE_DATA_L_S; 7134 break; 7135 case ITEM_L2TPV2_TYPE_CTRL: 7136 msg_type |= RTE_L2TPV2_MSG_TYPE_CONTROL; 7137 break; 7138 default: 7139 return -1; 7140 } 7141 if (!ctx->object) 7142 return len; 7143 arg = pop_args(ctx); 7144 if (!arg) 7145 return -1; 7146 l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data; 7147 l2tpv2->hdr.common.flags_version |= msg_type; 7148 data_size = ctx->objdata / 3; /* spec, last, mask */ 7149 l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data + 7150 (data_size * 2)); 7151 l2tpv2_mask->hdr.common.flags_version = 0xFFFF; 7152 if (arg->hton) { 7153 l2tpv2->hdr.common.flags_version = 7154 rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version); 7155 l2tpv2_mask->hdr.common.flags_version = 7156 rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version); 7157 } 7158 item = &out->args.vc.pattern[out->args.vc.pattern_n - 1]; 7159 item->spec = l2tpv2; 7160 item->mask = l2tpv2_mask; 7161 return len; 7162 } 7163 7164 /** Parse meter color action type. */ 7165 static int 7166 parse_vc_action_meter_color_type(struct context *ctx, const struct token *token, 7167 const char *str, unsigned int len, 7168 void *buf, unsigned int size) 7169 { 7170 struct rte_flow_action *action_data; 7171 struct rte_flow_action_meter_color *conf; 7172 enum rte_color color; 7173 7174 (void)buf; 7175 (void)size; 7176 /* Token name must match. */ 7177 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 7178 return -1; 7179 switch (ctx->curr) { 7180 case ACTION_METER_COLOR_GREEN: 7181 color = RTE_COLOR_GREEN; 7182 break; 7183 case ACTION_METER_COLOR_YELLOW: 7184 color = RTE_COLOR_YELLOW; 7185 break; 7186 case ACTION_METER_COLOR_RED: 7187 color = RTE_COLOR_RED; 7188 break; 7189 default: 7190 return -1; 7191 } 7192 7193 if (!ctx->object) 7194 return len; 7195 action_data = ctx->object; 7196 conf = (struct rte_flow_action_meter_color *) 7197 (uintptr_t)(action_data->conf); 7198 conf->color = color; 7199 return len; 7200 } 7201 7202 /** Parse RSS action. */ 7203 static int 7204 parse_vc_action_rss(struct context *ctx, const struct token *token, 7205 const char *str, unsigned int len, 7206 void *buf, unsigned int size) 7207 { 7208 struct buffer *out = buf; 7209 struct rte_flow_action *action; 7210 struct action_rss_data *action_rss_data; 7211 unsigned int i; 7212 int ret; 7213 7214 ret = parse_vc(ctx, token, str, len, buf, size); 7215 if (ret < 0) 7216 return ret; 7217 /* Nothing else to do if there is no buffer. */ 7218 if (!out) 7219 return ret; 7220 if (!out->args.vc.actions_n) 7221 return -1; 7222 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 7223 /* Point to selected object. */ 7224 ctx->object = out->args.vc.data; 7225 ctx->objmask = NULL; 7226 /* Set up default configuration. */ 7227 action_rss_data = ctx->object; 7228 *action_rss_data = (struct action_rss_data){ 7229 .conf = (struct rte_flow_action_rss){ 7230 .func = RTE_ETH_HASH_FUNCTION_DEFAULT, 7231 .level = 0, 7232 .types = rss_hf, 7233 .key_len = 0, 7234 .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), 7235 .key = NULL, 7236 .queue = action_rss_data->queue, 7237 }, 7238 .queue = { 0 }, 7239 }; 7240 for (i = 0; i < action_rss_data->conf.queue_num; ++i) 7241 action_rss_data->queue[i] = i; 7242 action->conf = &action_rss_data->conf; 7243 return ret; 7244 } 7245 7246 /** 7247 * Parse func field for RSS action. 7248 * 7249 * The RTE_ETH_HASH_FUNCTION_* value to assign is derived from the 7250 * ACTION_RSS_FUNC_* index that called this function. 7251 */ 7252 static int 7253 parse_vc_action_rss_func(struct context *ctx, const struct token *token, 7254 const char *str, unsigned int len, 7255 void *buf, unsigned int size) 7256 { 7257 struct action_rss_data *action_rss_data; 7258 enum rte_eth_hash_function func; 7259 7260 (void)buf; 7261 (void)size; 7262 /* Token name must match. */ 7263 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 7264 return -1; 7265 switch (ctx->curr) { 7266 case ACTION_RSS_FUNC_DEFAULT: 7267 func = RTE_ETH_HASH_FUNCTION_DEFAULT; 7268 break; 7269 case ACTION_RSS_FUNC_TOEPLITZ: 7270 func = RTE_ETH_HASH_FUNCTION_TOEPLITZ; 7271 break; 7272 case ACTION_RSS_FUNC_SIMPLE_XOR: 7273 func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR; 7274 break; 7275 case ACTION_RSS_FUNC_SYMMETRIC_TOEPLITZ: 7276 func = RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ; 7277 break; 7278 default: 7279 return -1; 7280 } 7281 if (!ctx->object) 7282 return len; 7283 action_rss_data = ctx->object; 7284 action_rss_data->conf.func = func; 7285 return len; 7286 } 7287 7288 /** 7289 * Parse type field for RSS action. 7290 * 7291 * Valid tokens are type field names and the "end" token. 7292 */ 7293 static int 7294 parse_vc_action_rss_type(struct context *ctx, const struct token *token, 7295 const char *str, unsigned int len, 7296 void *buf, unsigned int size) 7297 { 7298 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_TYPE); 7299 struct action_rss_data *action_rss_data; 7300 unsigned int i; 7301 7302 (void)token; 7303 (void)buf; 7304 (void)size; 7305 if (ctx->curr != ACTION_RSS_TYPE) 7306 return -1; 7307 if (!(ctx->objdata >> 16) && ctx->object) { 7308 action_rss_data = ctx->object; 7309 action_rss_data->conf.types = 0; 7310 } 7311 if (!strcmp_partial("end", str, len)) { 7312 ctx->objdata &= 0xffff; 7313 return len; 7314 } 7315 for (i = 0; rss_type_table[i].str; ++i) 7316 if (!strcmp_partial(rss_type_table[i].str, str, len)) 7317 break; 7318 if (!rss_type_table[i].str) 7319 return -1; 7320 ctx->objdata = 1 << 16 | (ctx->objdata & 0xffff); 7321 /* Repeat token. */ 7322 if (ctx->next_num == RTE_DIM(ctx->next)) 7323 return -1; 7324 ctx->next[ctx->next_num++] = next; 7325 if (!ctx->object) 7326 return len; 7327 action_rss_data = ctx->object; 7328 action_rss_data->conf.types |= rss_type_table[i].rss_type; 7329 return len; 7330 } 7331 7332 /** 7333 * Parse queue field for RSS action. 7334 * 7335 * Valid tokens are queue indices and the "end" token. 7336 */ 7337 static int 7338 parse_vc_action_rss_queue(struct context *ctx, const struct token *token, 7339 const char *str, unsigned int len, 7340 void *buf, unsigned int size) 7341 { 7342 static const enum index next[] = NEXT_ENTRY(ACTION_RSS_QUEUE); 7343 struct action_rss_data *action_rss_data; 7344 const struct arg *arg; 7345 int ret; 7346 int i; 7347 7348 (void)token; 7349 (void)buf; 7350 (void)size; 7351 if (ctx->curr != ACTION_RSS_QUEUE) 7352 return -1; 7353 i = ctx->objdata >> 16; 7354 if (!strcmp_partial("end", str, len)) { 7355 ctx->objdata &= 0xffff; 7356 goto end; 7357 } 7358 if (i >= ACTION_RSS_QUEUE_NUM) 7359 return -1; 7360 arg = ARGS_ENTRY_ARB(offsetof(struct action_rss_data, queue) + 7361 i * sizeof(action_rss_data->queue[i]), 7362 sizeof(action_rss_data->queue[i])); 7363 if (push_args(ctx, arg)) 7364 return -1; 7365 ret = parse_int(ctx, token, str, len, NULL, 0); 7366 if (ret < 0) { 7367 pop_args(ctx); 7368 return -1; 7369 } 7370 ++i; 7371 ctx->objdata = i << 16 | (ctx->objdata & 0xffff); 7372 /* Repeat token. */ 7373 if (ctx->next_num == RTE_DIM(ctx->next)) 7374 return -1; 7375 ctx->next[ctx->next_num++] = next; 7376 end: 7377 if (!ctx->object) 7378 return len; 7379 action_rss_data = ctx->object; 7380 action_rss_data->conf.queue_num = i; 7381 action_rss_data->conf.queue = i ? action_rss_data->queue : NULL; 7382 return len; 7383 } 7384 7385 /** Setup VXLAN encap configuration. */ 7386 static int 7387 parse_setup_vxlan_encap_data(struct action_vxlan_encap_data *action_vxlan_encap_data) 7388 { 7389 /* Set up default configuration. */ 7390 *action_vxlan_encap_data = (struct action_vxlan_encap_data){ 7391 .conf = (struct rte_flow_action_vxlan_encap){ 7392 .definition = action_vxlan_encap_data->items, 7393 }, 7394 .items = { 7395 { 7396 .type = RTE_FLOW_ITEM_TYPE_ETH, 7397 .spec = &action_vxlan_encap_data->item_eth, 7398 .mask = &rte_flow_item_eth_mask, 7399 }, 7400 { 7401 .type = RTE_FLOW_ITEM_TYPE_VLAN, 7402 .spec = &action_vxlan_encap_data->item_vlan, 7403 .mask = &rte_flow_item_vlan_mask, 7404 }, 7405 { 7406 .type = RTE_FLOW_ITEM_TYPE_IPV4, 7407 .spec = &action_vxlan_encap_data->item_ipv4, 7408 .mask = &rte_flow_item_ipv4_mask, 7409 }, 7410 { 7411 .type = RTE_FLOW_ITEM_TYPE_UDP, 7412 .spec = &action_vxlan_encap_data->item_udp, 7413 .mask = &rte_flow_item_udp_mask, 7414 }, 7415 { 7416 .type = RTE_FLOW_ITEM_TYPE_VXLAN, 7417 .spec = &action_vxlan_encap_data->item_vxlan, 7418 .mask = &rte_flow_item_vxlan_mask, 7419 }, 7420 { 7421 .type = RTE_FLOW_ITEM_TYPE_END, 7422 }, 7423 }, 7424 .item_eth.type = 0, 7425 .item_vlan = { 7426 .tci = vxlan_encap_conf.vlan_tci, 7427 .inner_type = 0, 7428 }, 7429 .item_ipv4.hdr = { 7430 .src_addr = vxlan_encap_conf.ipv4_src, 7431 .dst_addr = vxlan_encap_conf.ipv4_dst, 7432 }, 7433 .item_udp.hdr = { 7434 .src_port = vxlan_encap_conf.udp_src, 7435 .dst_port = vxlan_encap_conf.udp_dst, 7436 }, 7437 .item_vxlan.flags = 0, 7438 }; 7439 memcpy(action_vxlan_encap_data->item_eth.dst.addr_bytes, 7440 vxlan_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 7441 memcpy(action_vxlan_encap_data->item_eth.src.addr_bytes, 7442 vxlan_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 7443 if (!vxlan_encap_conf.select_ipv4) { 7444 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.src_addr, 7445 &vxlan_encap_conf.ipv6_src, 7446 sizeof(vxlan_encap_conf.ipv6_src)); 7447 memcpy(&action_vxlan_encap_data->item_ipv6.hdr.dst_addr, 7448 &vxlan_encap_conf.ipv6_dst, 7449 sizeof(vxlan_encap_conf.ipv6_dst)); 7450 action_vxlan_encap_data->items[2] = (struct rte_flow_item){ 7451 .type = RTE_FLOW_ITEM_TYPE_IPV6, 7452 .spec = &action_vxlan_encap_data->item_ipv6, 7453 .mask = &rte_flow_item_ipv6_mask, 7454 }; 7455 } 7456 if (!vxlan_encap_conf.select_vlan) 7457 action_vxlan_encap_data->items[1].type = 7458 RTE_FLOW_ITEM_TYPE_VOID; 7459 if (vxlan_encap_conf.select_tos_ttl) { 7460 if (vxlan_encap_conf.select_ipv4) { 7461 static struct rte_flow_item_ipv4 ipv4_mask_tos; 7462 7463 memcpy(&ipv4_mask_tos, &rte_flow_item_ipv4_mask, 7464 sizeof(ipv4_mask_tos)); 7465 ipv4_mask_tos.hdr.type_of_service = 0xff; 7466 ipv4_mask_tos.hdr.time_to_live = 0xff; 7467 action_vxlan_encap_data->item_ipv4.hdr.type_of_service = 7468 vxlan_encap_conf.ip_tos; 7469 action_vxlan_encap_data->item_ipv4.hdr.time_to_live = 7470 vxlan_encap_conf.ip_ttl; 7471 action_vxlan_encap_data->items[2].mask = 7472 &ipv4_mask_tos; 7473 } else { 7474 static struct rte_flow_item_ipv6 ipv6_mask_tos; 7475 7476 memcpy(&ipv6_mask_tos, &rte_flow_item_ipv6_mask, 7477 sizeof(ipv6_mask_tos)); 7478 ipv6_mask_tos.hdr.vtc_flow |= 7479 RTE_BE32(0xfful << RTE_IPV6_HDR_TC_SHIFT); 7480 ipv6_mask_tos.hdr.hop_limits = 0xff; 7481 action_vxlan_encap_data->item_ipv6.hdr.vtc_flow |= 7482 rte_cpu_to_be_32 7483 ((uint32_t)vxlan_encap_conf.ip_tos << 7484 RTE_IPV6_HDR_TC_SHIFT); 7485 action_vxlan_encap_data->item_ipv6.hdr.hop_limits = 7486 vxlan_encap_conf.ip_ttl; 7487 action_vxlan_encap_data->items[2].mask = 7488 &ipv6_mask_tos; 7489 } 7490 } 7491 memcpy(action_vxlan_encap_data->item_vxlan.vni, vxlan_encap_conf.vni, 7492 RTE_DIM(vxlan_encap_conf.vni)); 7493 return 0; 7494 } 7495 7496 /** Parse VXLAN encap action. */ 7497 static int 7498 parse_vc_action_vxlan_encap(struct context *ctx, const struct token *token, 7499 const char *str, unsigned int len, 7500 void *buf, unsigned int size) 7501 { 7502 struct buffer *out = buf; 7503 struct rte_flow_action *action; 7504 struct action_vxlan_encap_data *action_vxlan_encap_data; 7505 int ret; 7506 7507 ret = parse_vc(ctx, token, str, len, buf, size); 7508 if (ret < 0) 7509 return ret; 7510 /* Nothing else to do if there is no buffer. */ 7511 if (!out) 7512 return ret; 7513 if (!out->args.vc.actions_n) 7514 return -1; 7515 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 7516 /* Point to selected object. */ 7517 ctx->object = out->args.vc.data; 7518 ctx->objmask = NULL; 7519 action_vxlan_encap_data = ctx->object; 7520 parse_setup_vxlan_encap_data(action_vxlan_encap_data); 7521 action->conf = &action_vxlan_encap_data->conf; 7522 return ret; 7523 } 7524 7525 /** Setup NVGRE encap configuration. */ 7526 static int 7527 parse_setup_nvgre_encap_data(struct action_nvgre_encap_data *action_nvgre_encap_data) 7528 { 7529 /* Set up default configuration. */ 7530 *action_nvgre_encap_data = (struct action_nvgre_encap_data){ 7531 .conf = (struct rte_flow_action_nvgre_encap){ 7532 .definition = action_nvgre_encap_data->items, 7533 }, 7534 .items = { 7535 { 7536 .type = RTE_FLOW_ITEM_TYPE_ETH, 7537 .spec = &action_nvgre_encap_data->item_eth, 7538 .mask = &rte_flow_item_eth_mask, 7539 }, 7540 { 7541 .type = RTE_FLOW_ITEM_TYPE_VLAN, 7542 .spec = &action_nvgre_encap_data->item_vlan, 7543 .mask = &rte_flow_item_vlan_mask, 7544 }, 7545 { 7546 .type = RTE_FLOW_ITEM_TYPE_IPV4, 7547 .spec = &action_nvgre_encap_data->item_ipv4, 7548 .mask = &rte_flow_item_ipv4_mask, 7549 }, 7550 { 7551 .type = RTE_FLOW_ITEM_TYPE_NVGRE, 7552 .spec = &action_nvgre_encap_data->item_nvgre, 7553 .mask = &rte_flow_item_nvgre_mask, 7554 }, 7555 { 7556 .type = RTE_FLOW_ITEM_TYPE_END, 7557 }, 7558 }, 7559 .item_eth.type = 0, 7560 .item_vlan = { 7561 .tci = nvgre_encap_conf.vlan_tci, 7562 .inner_type = 0, 7563 }, 7564 .item_ipv4.hdr = { 7565 .src_addr = nvgre_encap_conf.ipv4_src, 7566 .dst_addr = nvgre_encap_conf.ipv4_dst, 7567 }, 7568 .item_nvgre.c_k_s_rsvd0_ver = RTE_BE16(0x2000), 7569 .item_nvgre.protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), 7570 .item_nvgre.flow_id = 0, 7571 }; 7572 memcpy(action_nvgre_encap_data->item_eth.dst.addr_bytes, 7573 nvgre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 7574 memcpy(action_nvgre_encap_data->item_eth.src.addr_bytes, 7575 nvgre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 7576 if (!nvgre_encap_conf.select_ipv4) { 7577 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.src_addr, 7578 &nvgre_encap_conf.ipv6_src, 7579 sizeof(nvgre_encap_conf.ipv6_src)); 7580 memcpy(&action_nvgre_encap_data->item_ipv6.hdr.dst_addr, 7581 &nvgre_encap_conf.ipv6_dst, 7582 sizeof(nvgre_encap_conf.ipv6_dst)); 7583 action_nvgre_encap_data->items[2] = (struct rte_flow_item){ 7584 .type = RTE_FLOW_ITEM_TYPE_IPV6, 7585 .spec = &action_nvgre_encap_data->item_ipv6, 7586 .mask = &rte_flow_item_ipv6_mask, 7587 }; 7588 } 7589 if (!nvgre_encap_conf.select_vlan) 7590 action_nvgre_encap_data->items[1].type = 7591 RTE_FLOW_ITEM_TYPE_VOID; 7592 memcpy(action_nvgre_encap_data->item_nvgre.tni, nvgre_encap_conf.tni, 7593 RTE_DIM(nvgre_encap_conf.tni)); 7594 return 0; 7595 } 7596 7597 /** Parse NVGRE encap action. */ 7598 static int 7599 parse_vc_action_nvgre_encap(struct context *ctx, const struct token *token, 7600 const char *str, unsigned int len, 7601 void *buf, unsigned int size) 7602 { 7603 struct buffer *out = buf; 7604 struct rte_flow_action *action; 7605 struct action_nvgre_encap_data *action_nvgre_encap_data; 7606 int ret; 7607 7608 ret = parse_vc(ctx, token, str, len, buf, size); 7609 if (ret < 0) 7610 return ret; 7611 /* Nothing else to do if there is no buffer. */ 7612 if (!out) 7613 return ret; 7614 if (!out->args.vc.actions_n) 7615 return -1; 7616 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 7617 /* Point to selected object. */ 7618 ctx->object = out->args.vc.data; 7619 ctx->objmask = NULL; 7620 action_nvgre_encap_data = ctx->object; 7621 parse_setup_nvgre_encap_data(action_nvgre_encap_data); 7622 action->conf = &action_nvgre_encap_data->conf; 7623 return ret; 7624 } 7625 7626 /** Parse l2 encap action. */ 7627 static int 7628 parse_vc_action_l2_encap(struct context *ctx, const struct token *token, 7629 const char *str, unsigned int len, 7630 void *buf, unsigned int size) 7631 { 7632 struct buffer *out = buf; 7633 struct rte_flow_action *action; 7634 struct action_raw_encap_data *action_encap_data; 7635 struct rte_flow_item_eth eth = { .type = 0, }; 7636 struct rte_flow_item_vlan vlan = { 7637 .tci = mplsoudp_encap_conf.vlan_tci, 7638 .inner_type = 0, 7639 }; 7640 uint8_t *header; 7641 int ret; 7642 7643 ret = parse_vc(ctx, token, str, len, buf, size); 7644 if (ret < 0) 7645 return ret; 7646 /* Nothing else to do if there is no buffer. */ 7647 if (!out) 7648 return ret; 7649 if (!out->args.vc.actions_n) 7650 return -1; 7651 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 7652 /* Point to selected object. */ 7653 ctx->object = out->args.vc.data; 7654 ctx->objmask = NULL; 7655 /* Copy the headers to the buffer. */ 7656 action_encap_data = ctx->object; 7657 *action_encap_data = (struct action_raw_encap_data) { 7658 .conf = (struct rte_flow_action_raw_encap){ 7659 .data = action_encap_data->data, 7660 }, 7661 .data = {}, 7662 }; 7663 header = action_encap_data->data; 7664 if (l2_encap_conf.select_vlan) 7665 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 7666 else if (l2_encap_conf.select_ipv4) 7667 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 7668 else 7669 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 7670 memcpy(eth.dst.addr_bytes, 7671 l2_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 7672 memcpy(eth.src.addr_bytes, 7673 l2_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 7674 memcpy(header, ð, sizeof(eth)); 7675 header += sizeof(eth); 7676 if (l2_encap_conf.select_vlan) { 7677 if (l2_encap_conf.select_ipv4) 7678 vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 7679 else 7680 vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 7681 memcpy(header, &vlan, sizeof(vlan)); 7682 header += sizeof(vlan); 7683 } 7684 action_encap_data->conf.size = header - 7685 action_encap_data->data; 7686 action->conf = &action_encap_data->conf; 7687 return ret; 7688 } 7689 7690 /** Parse l2 decap action. */ 7691 static int 7692 parse_vc_action_l2_decap(struct context *ctx, const struct token *token, 7693 const char *str, unsigned int len, 7694 void *buf, unsigned int size) 7695 { 7696 struct buffer *out = buf; 7697 struct rte_flow_action *action; 7698 struct action_raw_decap_data *action_decap_data; 7699 struct rte_flow_item_eth eth = { .type = 0, }; 7700 struct rte_flow_item_vlan vlan = { 7701 .tci = mplsoudp_encap_conf.vlan_tci, 7702 .inner_type = 0, 7703 }; 7704 uint8_t *header; 7705 int ret; 7706 7707 ret = parse_vc(ctx, token, str, len, buf, size); 7708 if (ret < 0) 7709 return ret; 7710 /* Nothing else to do if there is no buffer. */ 7711 if (!out) 7712 return ret; 7713 if (!out->args.vc.actions_n) 7714 return -1; 7715 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 7716 /* Point to selected object. */ 7717 ctx->object = out->args.vc.data; 7718 ctx->objmask = NULL; 7719 /* Copy the headers to the buffer. */ 7720 action_decap_data = ctx->object; 7721 *action_decap_data = (struct action_raw_decap_data) { 7722 .conf = (struct rte_flow_action_raw_decap){ 7723 .data = action_decap_data->data, 7724 }, 7725 .data = {}, 7726 }; 7727 header = action_decap_data->data; 7728 if (l2_decap_conf.select_vlan) 7729 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 7730 memcpy(header, ð, sizeof(eth)); 7731 header += sizeof(eth); 7732 if (l2_decap_conf.select_vlan) { 7733 memcpy(header, &vlan, sizeof(vlan)); 7734 header += sizeof(vlan); 7735 } 7736 action_decap_data->conf.size = header - 7737 action_decap_data->data; 7738 action->conf = &action_decap_data->conf; 7739 return ret; 7740 } 7741 7742 #define ETHER_TYPE_MPLS_UNICAST 0x8847 7743 7744 /** Parse MPLSOGRE encap action. */ 7745 static int 7746 parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, 7747 const char *str, unsigned int len, 7748 void *buf, unsigned int size) 7749 { 7750 struct buffer *out = buf; 7751 struct rte_flow_action *action; 7752 struct action_raw_encap_data *action_encap_data; 7753 struct rte_flow_item_eth eth = { .type = 0, }; 7754 struct rte_flow_item_vlan vlan = { 7755 .tci = mplsogre_encap_conf.vlan_tci, 7756 .inner_type = 0, 7757 }; 7758 struct rte_flow_item_ipv4 ipv4 = { 7759 .hdr = { 7760 .src_addr = mplsogre_encap_conf.ipv4_src, 7761 .dst_addr = mplsogre_encap_conf.ipv4_dst, 7762 .next_proto_id = IPPROTO_GRE, 7763 .version_ihl = RTE_IPV4_VHL_DEF, 7764 .time_to_live = IPDEFTTL, 7765 }, 7766 }; 7767 struct rte_flow_item_ipv6 ipv6 = { 7768 .hdr = { 7769 .proto = IPPROTO_GRE, 7770 .hop_limits = IPDEFTTL, 7771 }, 7772 }; 7773 struct rte_flow_item_gre gre = { 7774 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 7775 }; 7776 struct rte_flow_item_mpls mpls = { 7777 .ttl = 0, 7778 }; 7779 uint8_t *header; 7780 int ret; 7781 7782 ret = parse_vc(ctx, token, str, len, buf, size); 7783 if (ret < 0) 7784 return ret; 7785 /* Nothing else to do if there is no buffer. */ 7786 if (!out) 7787 return ret; 7788 if (!out->args.vc.actions_n) 7789 return -1; 7790 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 7791 /* Point to selected object. */ 7792 ctx->object = out->args.vc.data; 7793 ctx->objmask = NULL; 7794 /* Copy the headers to the buffer. */ 7795 action_encap_data = ctx->object; 7796 *action_encap_data = (struct action_raw_encap_data) { 7797 .conf = (struct rte_flow_action_raw_encap){ 7798 .data = action_encap_data->data, 7799 }, 7800 .data = {}, 7801 .preserve = {}, 7802 }; 7803 header = action_encap_data->data; 7804 if (mplsogre_encap_conf.select_vlan) 7805 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 7806 else if (mplsogre_encap_conf.select_ipv4) 7807 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 7808 else 7809 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 7810 memcpy(eth.dst.addr_bytes, 7811 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 7812 memcpy(eth.src.addr_bytes, 7813 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 7814 memcpy(header, ð, sizeof(eth)); 7815 header += sizeof(eth); 7816 if (mplsogre_encap_conf.select_vlan) { 7817 if (mplsogre_encap_conf.select_ipv4) 7818 vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 7819 else 7820 vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 7821 memcpy(header, &vlan, sizeof(vlan)); 7822 header += sizeof(vlan); 7823 } 7824 if (mplsogre_encap_conf.select_ipv4) { 7825 memcpy(header, &ipv4, sizeof(ipv4)); 7826 header += sizeof(ipv4); 7827 } else { 7828 memcpy(&ipv6.hdr.src_addr, 7829 &mplsogre_encap_conf.ipv6_src, 7830 sizeof(mplsogre_encap_conf.ipv6_src)); 7831 memcpy(&ipv6.hdr.dst_addr, 7832 &mplsogre_encap_conf.ipv6_dst, 7833 sizeof(mplsogre_encap_conf.ipv6_dst)); 7834 memcpy(header, &ipv6, sizeof(ipv6)); 7835 header += sizeof(ipv6); 7836 } 7837 memcpy(header, &gre, sizeof(gre)); 7838 header += sizeof(gre); 7839 memcpy(mpls.label_tc_s, mplsogre_encap_conf.label, 7840 RTE_DIM(mplsogre_encap_conf.label)); 7841 mpls.label_tc_s[2] |= 0x1; 7842 memcpy(header, &mpls, sizeof(mpls)); 7843 header += sizeof(mpls); 7844 action_encap_data->conf.size = header - 7845 action_encap_data->data; 7846 action->conf = &action_encap_data->conf; 7847 return ret; 7848 } 7849 7850 /** Parse MPLSOGRE decap action. */ 7851 static int 7852 parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, 7853 const char *str, unsigned int len, 7854 void *buf, unsigned int size) 7855 { 7856 struct buffer *out = buf; 7857 struct rte_flow_action *action; 7858 struct action_raw_decap_data *action_decap_data; 7859 struct rte_flow_item_eth eth = { .type = 0, }; 7860 struct rte_flow_item_vlan vlan = {.tci = 0}; 7861 struct rte_flow_item_ipv4 ipv4 = { 7862 .hdr = { 7863 .next_proto_id = IPPROTO_GRE, 7864 }, 7865 }; 7866 struct rte_flow_item_ipv6 ipv6 = { 7867 .hdr = { 7868 .proto = IPPROTO_GRE, 7869 }, 7870 }; 7871 struct rte_flow_item_gre gre = { 7872 .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), 7873 }; 7874 struct rte_flow_item_mpls mpls; 7875 uint8_t *header; 7876 int ret; 7877 7878 ret = parse_vc(ctx, token, str, len, buf, size); 7879 if (ret < 0) 7880 return ret; 7881 /* Nothing else to do if there is no buffer. */ 7882 if (!out) 7883 return ret; 7884 if (!out->args.vc.actions_n) 7885 return -1; 7886 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 7887 /* Point to selected object. */ 7888 ctx->object = out->args.vc.data; 7889 ctx->objmask = NULL; 7890 /* Copy the headers to the buffer. */ 7891 action_decap_data = ctx->object; 7892 *action_decap_data = (struct action_raw_decap_data) { 7893 .conf = (struct rte_flow_action_raw_decap){ 7894 .data = action_decap_data->data, 7895 }, 7896 .data = {}, 7897 }; 7898 header = action_decap_data->data; 7899 if (mplsogre_decap_conf.select_vlan) 7900 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 7901 else if (mplsogre_encap_conf.select_ipv4) 7902 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 7903 else 7904 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 7905 memcpy(eth.dst.addr_bytes, 7906 mplsogre_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 7907 memcpy(eth.src.addr_bytes, 7908 mplsogre_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 7909 memcpy(header, ð, sizeof(eth)); 7910 header += sizeof(eth); 7911 if (mplsogre_encap_conf.select_vlan) { 7912 if (mplsogre_encap_conf.select_ipv4) 7913 vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 7914 else 7915 vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 7916 memcpy(header, &vlan, sizeof(vlan)); 7917 header += sizeof(vlan); 7918 } 7919 if (mplsogre_encap_conf.select_ipv4) { 7920 memcpy(header, &ipv4, sizeof(ipv4)); 7921 header += sizeof(ipv4); 7922 } else { 7923 memcpy(header, &ipv6, sizeof(ipv6)); 7924 header += sizeof(ipv6); 7925 } 7926 memcpy(header, &gre, sizeof(gre)); 7927 header += sizeof(gre); 7928 memset(&mpls, 0, sizeof(mpls)); 7929 memcpy(header, &mpls, sizeof(mpls)); 7930 header += sizeof(mpls); 7931 action_decap_data->conf.size = header - 7932 action_decap_data->data; 7933 action->conf = &action_decap_data->conf; 7934 return ret; 7935 } 7936 7937 /** Parse MPLSOUDP encap action. */ 7938 static int 7939 parse_vc_action_mplsoudp_encap(struct context *ctx, const struct token *token, 7940 const char *str, unsigned int len, 7941 void *buf, unsigned int size) 7942 { 7943 struct buffer *out = buf; 7944 struct rte_flow_action *action; 7945 struct action_raw_encap_data *action_encap_data; 7946 struct rte_flow_item_eth eth = { .type = 0, }; 7947 struct rte_flow_item_vlan vlan = { 7948 .tci = mplsoudp_encap_conf.vlan_tci, 7949 .inner_type = 0, 7950 }; 7951 struct rte_flow_item_ipv4 ipv4 = { 7952 .hdr = { 7953 .src_addr = mplsoudp_encap_conf.ipv4_src, 7954 .dst_addr = mplsoudp_encap_conf.ipv4_dst, 7955 .next_proto_id = IPPROTO_UDP, 7956 .version_ihl = RTE_IPV4_VHL_DEF, 7957 .time_to_live = IPDEFTTL, 7958 }, 7959 }; 7960 struct rte_flow_item_ipv6 ipv6 = { 7961 .hdr = { 7962 .proto = IPPROTO_UDP, 7963 .hop_limits = IPDEFTTL, 7964 }, 7965 }; 7966 struct rte_flow_item_udp udp = { 7967 .hdr = { 7968 .src_port = mplsoudp_encap_conf.udp_src, 7969 .dst_port = mplsoudp_encap_conf.udp_dst, 7970 }, 7971 }; 7972 struct rte_flow_item_mpls mpls; 7973 uint8_t *header; 7974 int ret; 7975 7976 ret = parse_vc(ctx, token, str, len, buf, size); 7977 if (ret < 0) 7978 return ret; 7979 /* Nothing else to do if there is no buffer. */ 7980 if (!out) 7981 return ret; 7982 if (!out->args.vc.actions_n) 7983 return -1; 7984 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 7985 /* Point to selected object. */ 7986 ctx->object = out->args.vc.data; 7987 ctx->objmask = NULL; 7988 /* Copy the headers to the buffer. */ 7989 action_encap_data = ctx->object; 7990 *action_encap_data = (struct action_raw_encap_data) { 7991 .conf = (struct rte_flow_action_raw_encap){ 7992 .data = action_encap_data->data, 7993 }, 7994 .data = {}, 7995 .preserve = {}, 7996 }; 7997 header = action_encap_data->data; 7998 if (mplsoudp_encap_conf.select_vlan) 7999 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 8000 else if (mplsoudp_encap_conf.select_ipv4) 8001 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 8002 else 8003 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 8004 memcpy(eth.dst.addr_bytes, 8005 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 8006 memcpy(eth.src.addr_bytes, 8007 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 8008 memcpy(header, ð, sizeof(eth)); 8009 header += sizeof(eth); 8010 if (mplsoudp_encap_conf.select_vlan) { 8011 if (mplsoudp_encap_conf.select_ipv4) 8012 vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 8013 else 8014 vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 8015 memcpy(header, &vlan, sizeof(vlan)); 8016 header += sizeof(vlan); 8017 } 8018 if (mplsoudp_encap_conf.select_ipv4) { 8019 memcpy(header, &ipv4, sizeof(ipv4)); 8020 header += sizeof(ipv4); 8021 } else { 8022 memcpy(&ipv6.hdr.src_addr, 8023 &mplsoudp_encap_conf.ipv6_src, 8024 sizeof(mplsoudp_encap_conf.ipv6_src)); 8025 memcpy(&ipv6.hdr.dst_addr, 8026 &mplsoudp_encap_conf.ipv6_dst, 8027 sizeof(mplsoudp_encap_conf.ipv6_dst)); 8028 memcpy(header, &ipv6, sizeof(ipv6)); 8029 header += sizeof(ipv6); 8030 } 8031 memcpy(header, &udp, sizeof(udp)); 8032 header += sizeof(udp); 8033 memcpy(mpls.label_tc_s, mplsoudp_encap_conf.label, 8034 RTE_DIM(mplsoudp_encap_conf.label)); 8035 mpls.label_tc_s[2] |= 0x1; 8036 memcpy(header, &mpls, sizeof(mpls)); 8037 header += sizeof(mpls); 8038 action_encap_data->conf.size = header - 8039 action_encap_data->data; 8040 action->conf = &action_encap_data->conf; 8041 return ret; 8042 } 8043 8044 /** Parse MPLSOUDP decap action. */ 8045 static int 8046 parse_vc_action_mplsoudp_decap(struct context *ctx, const struct token *token, 8047 const char *str, unsigned int len, 8048 void *buf, unsigned int size) 8049 { 8050 struct buffer *out = buf; 8051 struct rte_flow_action *action; 8052 struct action_raw_decap_data *action_decap_data; 8053 struct rte_flow_item_eth eth = { .type = 0, }; 8054 struct rte_flow_item_vlan vlan = {.tci = 0}; 8055 struct rte_flow_item_ipv4 ipv4 = { 8056 .hdr = { 8057 .next_proto_id = IPPROTO_UDP, 8058 }, 8059 }; 8060 struct rte_flow_item_ipv6 ipv6 = { 8061 .hdr = { 8062 .proto = IPPROTO_UDP, 8063 }, 8064 }; 8065 struct rte_flow_item_udp udp = { 8066 .hdr = { 8067 .dst_port = rte_cpu_to_be_16(6635), 8068 }, 8069 }; 8070 struct rte_flow_item_mpls mpls; 8071 uint8_t *header; 8072 int ret; 8073 8074 ret = parse_vc(ctx, token, str, len, buf, size); 8075 if (ret < 0) 8076 return ret; 8077 /* Nothing else to do if there is no buffer. */ 8078 if (!out) 8079 return ret; 8080 if (!out->args.vc.actions_n) 8081 return -1; 8082 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8083 /* Point to selected object. */ 8084 ctx->object = out->args.vc.data; 8085 ctx->objmask = NULL; 8086 /* Copy the headers to the buffer. */ 8087 action_decap_data = ctx->object; 8088 *action_decap_data = (struct action_raw_decap_data) { 8089 .conf = (struct rte_flow_action_raw_decap){ 8090 .data = action_decap_data->data, 8091 }, 8092 .data = {}, 8093 }; 8094 header = action_decap_data->data; 8095 if (mplsoudp_decap_conf.select_vlan) 8096 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 8097 else if (mplsoudp_encap_conf.select_ipv4) 8098 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 8099 else 8100 eth.type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 8101 memcpy(eth.dst.addr_bytes, 8102 mplsoudp_encap_conf.eth_dst, RTE_ETHER_ADDR_LEN); 8103 memcpy(eth.src.addr_bytes, 8104 mplsoudp_encap_conf.eth_src, RTE_ETHER_ADDR_LEN); 8105 memcpy(header, ð, sizeof(eth)); 8106 header += sizeof(eth); 8107 if (mplsoudp_encap_conf.select_vlan) { 8108 if (mplsoudp_encap_conf.select_ipv4) 8109 vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 8110 else 8111 vlan.inner_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); 8112 memcpy(header, &vlan, sizeof(vlan)); 8113 header += sizeof(vlan); 8114 } 8115 if (mplsoudp_encap_conf.select_ipv4) { 8116 memcpy(header, &ipv4, sizeof(ipv4)); 8117 header += sizeof(ipv4); 8118 } else { 8119 memcpy(header, &ipv6, sizeof(ipv6)); 8120 header += sizeof(ipv6); 8121 } 8122 memcpy(header, &udp, sizeof(udp)); 8123 header += sizeof(udp); 8124 memset(&mpls, 0, sizeof(mpls)); 8125 memcpy(header, &mpls, sizeof(mpls)); 8126 header += sizeof(mpls); 8127 action_decap_data->conf.size = header - 8128 action_decap_data->data; 8129 action->conf = &action_decap_data->conf; 8130 return ret; 8131 } 8132 8133 static int 8134 parse_vc_action_raw_decap_index(struct context *ctx, const struct token *token, 8135 const char *str, unsigned int len, void *buf, 8136 unsigned int size) 8137 { 8138 struct action_raw_decap_data *action_raw_decap_data; 8139 struct rte_flow_action *action; 8140 const struct arg *arg; 8141 struct buffer *out = buf; 8142 int ret; 8143 uint16_t idx; 8144 8145 RTE_SET_USED(token); 8146 RTE_SET_USED(buf); 8147 RTE_SET_USED(size); 8148 arg = ARGS_ENTRY_ARB_BOUNDED 8149 (offsetof(struct action_raw_decap_data, idx), 8150 sizeof(((struct action_raw_decap_data *)0)->idx), 8151 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 8152 if (push_args(ctx, arg)) 8153 return -1; 8154 ret = parse_int(ctx, token, str, len, NULL, 0); 8155 if (ret < 0) { 8156 pop_args(ctx); 8157 return -1; 8158 } 8159 if (!ctx->object) 8160 return len; 8161 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8162 action_raw_decap_data = ctx->object; 8163 idx = action_raw_decap_data->idx; 8164 action_raw_decap_data->conf.data = raw_decap_confs[idx].data; 8165 action_raw_decap_data->conf.size = raw_decap_confs[idx].size; 8166 action->conf = &action_raw_decap_data->conf; 8167 return len; 8168 } 8169 8170 8171 static int 8172 parse_vc_action_raw_encap_index(struct context *ctx, const struct token *token, 8173 const char *str, unsigned int len, void *buf, 8174 unsigned int size) 8175 { 8176 struct action_raw_encap_data *action_raw_encap_data; 8177 struct rte_flow_action *action; 8178 const struct arg *arg; 8179 struct buffer *out = buf; 8180 int ret; 8181 uint16_t idx; 8182 8183 RTE_SET_USED(token); 8184 RTE_SET_USED(buf); 8185 RTE_SET_USED(size); 8186 if (ctx->curr != ACTION_RAW_ENCAP_INDEX_VALUE) 8187 return -1; 8188 arg = ARGS_ENTRY_ARB_BOUNDED 8189 (offsetof(struct action_raw_encap_data, idx), 8190 sizeof(((struct action_raw_encap_data *)0)->idx), 8191 0, RAW_ENCAP_CONFS_MAX_NUM - 1); 8192 if (push_args(ctx, arg)) 8193 return -1; 8194 ret = parse_int(ctx, token, str, len, NULL, 0); 8195 if (ret < 0) { 8196 pop_args(ctx); 8197 return -1; 8198 } 8199 if (!ctx->object) 8200 return len; 8201 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8202 action_raw_encap_data = ctx->object; 8203 idx = action_raw_encap_data->idx; 8204 action_raw_encap_data->conf.data = raw_encap_confs[idx].data; 8205 action_raw_encap_data->conf.size = raw_encap_confs[idx].size; 8206 action_raw_encap_data->conf.preserve = NULL; 8207 action->conf = &action_raw_encap_data->conf; 8208 return len; 8209 } 8210 8211 static int 8212 parse_vc_action_raw_encap(struct context *ctx, const struct token *token, 8213 const char *str, unsigned int len, void *buf, 8214 unsigned int size) 8215 { 8216 struct buffer *out = buf; 8217 struct rte_flow_action *action; 8218 struct action_raw_encap_data *action_raw_encap_data = NULL; 8219 int ret; 8220 8221 ret = parse_vc(ctx, token, str, len, buf, size); 8222 if (ret < 0) 8223 return ret; 8224 /* Nothing else to do if there is no buffer. */ 8225 if (!out) 8226 return ret; 8227 if (!out->args.vc.actions_n) 8228 return -1; 8229 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8230 /* Point to selected object. */ 8231 ctx->object = out->args.vc.data; 8232 ctx->objmask = NULL; 8233 /* Copy the headers to the buffer. */ 8234 action_raw_encap_data = ctx->object; 8235 action_raw_encap_data->conf.data = raw_encap_confs[0].data; 8236 action_raw_encap_data->conf.preserve = NULL; 8237 action_raw_encap_data->conf.size = raw_encap_confs[0].size; 8238 action->conf = &action_raw_encap_data->conf; 8239 return ret; 8240 } 8241 8242 static int 8243 parse_vc_action_raw_decap(struct context *ctx, const struct token *token, 8244 const char *str, unsigned int len, void *buf, 8245 unsigned int size) 8246 { 8247 struct buffer *out = buf; 8248 struct rte_flow_action *action; 8249 struct action_raw_decap_data *action_raw_decap_data = NULL; 8250 int ret; 8251 8252 ret = parse_vc(ctx, token, str, len, buf, size); 8253 if (ret < 0) 8254 return ret; 8255 /* Nothing else to do if there is no buffer. */ 8256 if (!out) 8257 return ret; 8258 if (!out->args.vc.actions_n) 8259 return -1; 8260 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8261 /* Point to selected object. */ 8262 ctx->object = out->args.vc.data; 8263 ctx->objmask = NULL; 8264 /* Copy the headers to the buffer. */ 8265 action_raw_decap_data = ctx->object; 8266 action_raw_decap_data->conf.data = raw_decap_confs[0].data; 8267 action_raw_decap_data->conf.size = raw_decap_confs[0].size; 8268 action->conf = &action_raw_decap_data->conf; 8269 return ret; 8270 } 8271 8272 static int 8273 parse_vc_action_set_meta(struct context *ctx, const struct token *token, 8274 const char *str, unsigned int len, void *buf, 8275 unsigned int size) 8276 { 8277 int ret; 8278 8279 ret = parse_vc(ctx, token, str, len, buf, size); 8280 if (ret < 0) 8281 return ret; 8282 ret = rte_flow_dynf_metadata_register(); 8283 if (ret < 0) 8284 return -1; 8285 return len; 8286 } 8287 8288 static int 8289 parse_vc_action_sample(struct context *ctx, const struct token *token, 8290 const char *str, unsigned int len, void *buf, 8291 unsigned int size) 8292 { 8293 struct buffer *out = buf; 8294 struct rte_flow_action *action; 8295 struct action_sample_data *action_sample_data = NULL; 8296 static struct rte_flow_action end_action = { 8297 RTE_FLOW_ACTION_TYPE_END, 0 8298 }; 8299 int ret; 8300 8301 ret = parse_vc(ctx, token, str, len, buf, size); 8302 if (ret < 0) 8303 return ret; 8304 /* Nothing else to do if there is no buffer. */ 8305 if (!out) 8306 return ret; 8307 if (!out->args.vc.actions_n) 8308 return -1; 8309 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8310 /* Point to selected object. */ 8311 ctx->object = out->args.vc.data; 8312 ctx->objmask = NULL; 8313 /* Copy the headers to the buffer. */ 8314 action_sample_data = ctx->object; 8315 action_sample_data->conf.actions = &end_action; 8316 action->conf = &action_sample_data->conf; 8317 return ret; 8318 } 8319 8320 static int 8321 parse_vc_action_sample_index(struct context *ctx, const struct token *token, 8322 const char *str, unsigned int len, void *buf, 8323 unsigned int size) 8324 { 8325 struct action_sample_data *action_sample_data; 8326 struct rte_flow_action *action; 8327 const struct arg *arg; 8328 struct buffer *out = buf; 8329 int ret; 8330 uint16_t idx; 8331 8332 RTE_SET_USED(token); 8333 RTE_SET_USED(buf); 8334 RTE_SET_USED(size); 8335 if (ctx->curr != ACTION_SAMPLE_INDEX_VALUE) 8336 return -1; 8337 arg = ARGS_ENTRY_ARB_BOUNDED 8338 (offsetof(struct action_sample_data, idx), 8339 sizeof(((struct action_sample_data *)0)->idx), 8340 0, RAW_SAMPLE_CONFS_MAX_NUM - 1); 8341 if (push_args(ctx, arg)) 8342 return -1; 8343 ret = parse_int(ctx, token, str, len, NULL, 0); 8344 if (ret < 0) { 8345 pop_args(ctx); 8346 return -1; 8347 } 8348 if (!ctx->object) 8349 return len; 8350 action = &out->args.vc.actions[out->args.vc.actions_n - 1]; 8351 action_sample_data = ctx->object; 8352 idx = action_sample_data->idx; 8353 action_sample_data->conf.actions = raw_sample_confs[idx].data; 8354 action->conf = &action_sample_data->conf; 8355 return len; 8356 } 8357 8358 /** Parse operation for modify_field command. */ 8359 static int 8360 parse_vc_modify_field_op(struct context *ctx, const struct token *token, 8361 const char *str, unsigned int len, void *buf, 8362 unsigned int size) 8363 { 8364 struct rte_flow_action_modify_field *action_modify_field; 8365 unsigned int i; 8366 8367 (void)token; 8368 (void)buf; 8369 (void)size; 8370 if (ctx->curr != ACTION_MODIFY_FIELD_OP_VALUE) 8371 return -1; 8372 for (i = 0; modify_field_ops[i]; ++i) 8373 if (!strcmp_partial(modify_field_ops[i], str, len)) 8374 break; 8375 if (!modify_field_ops[i]) 8376 return -1; 8377 if (!ctx->object) 8378 return len; 8379 action_modify_field = ctx->object; 8380 action_modify_field->operation = (enum rte_flow_modify_op)i; 8381 return len; 8382 } 8383 8384 /** Parse id for modify_field command. */ 8385 static int 8386 parse_vc_modify_field_id(struct context *ctx, const struct token *token, 8387 const char *str, unsigned int len, void *buf, 8388 unsigned int size) 8389 { 8390 struct rte_flow_action_modify_field *action_modify_field; 8391 unsigned int i; 8392 8393 (void)token; 8394 (void)buf; 8395 (void)size; 8396 if (ctx->curr != ACTION_MODIFY_FIELD_DST_TYPE_VALUE && 8397 ctx->curr != ACTION_MODIFY_FIELD_SRC_TYPE_VALUE) 8398 return -1; 8399 for (i = 0; modify_field_ids[i]; ++i) 8400 if (!strcmp_partial(modify_field_ids[i], str, len)) 8401 break; 8402 if (!modify_field_ids[i]) 8403 return -1; 8404 if (!ctx->object) 8405 return len; 8406 action_modify_field = ctx->object; 8407 if (ctx->curr == ACTION_MODIFY_FIELD_DST_TYPE_VALUE) 8408 action_modify_field->dst.field = (enum rte_flow_field_id)i; 8409 else 8410 action_modify_field->src.field = (enum rte_flow_field_id)i; 8411 return len; 8412 } 8413 8414 /** Parse the conntrack update, not a rte_flow_action. */ 8415 static int 8416 parse_vc_action_conntrack_update(struct context *ctx, const struct token *token, 8417 const char *str, unsigned int len, void *buf, 8418 unsigned int size) 8419 { 8420 struct buffer *out = buf; 8421 struct rte_flow_modify_conntrack *ct_modify = NULL; 8422 8423 (void)size; 8424 if (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX && 8425 ctx->curr != ACTION_CONNTRACK_UPDATE_DIR) 8426 return -1; 8427 /* Token name must match. */ 8428 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8429 return -1; 8430 /* Nothing else to do if there is no buffer. */ 8431 if (!out) 8432 return len; 8433 ct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data; 8434 if (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) { 8435 ct_modify->new_ct.is_original_dir = 8436 conntrack_context.is_original_dir; 8437 ct_modify->direction = 1; 8438 } else { 8439 uint32_t old_dir; 8440 8441 old_dir = ct_modify->new_ct.is_original_dir; 8442 memcpy(&ct_modify->new_ct, &conntrack_context, 8443 sizeof(conntrack_context)); 8444 ct_modify->new_ct.is_original_dir = old_dir; 8445 ct_modify->state = 1; 8446 } 8447 return len; 8448 } 8449 8450 /** Parse tokens for destroy command. */ 8451 static int 8452 parse_destroy(struct context *ctx, const struct token *token, 8453 const char *str, unsigned int len, 8454 void *buf, unsigned int size) 8455 { 8456 struct buffer *out = buf; 8457 8458 /* Token name must match. */ 8459 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8460 return -1; 8461 /* Nothing else to do if there is no buffer. */ 8462 if (!out) 8463 return len; 8464 if (!out->command) { 8465 if (ctx->curr != DESTROY) 8466 return -1; 8467 if (sizeof(*out) > size) 8468 return -1; 8469 out->command = ctx->curr; 8470 ctx->objdata = 0; 8471 ctx->object = out; 8472 ctx->objmask = NULL; 8473 out->args.destroy.rule = 8474 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8475 sizeof(double)); 8476 return len; 8477 } 8478 if (((uint8_t *)(out->args.destroy.rule + out->args.destroy.rule_n) + 8479 sizeof(*out->args.destroy.rule)) > (uint8_t *)out + size) 8480 return -1; 8481 ctx->objdata = 0; 8482 ctx->object = out->args.destroy.rule + out->args.destroy.rule_n++; 8483 ctx->objmask = NULL; 8484 return len; 8485 } 8486 8487 /** Parse tokens for flush command. */ 8488 static int 8489 parse_flush(struct context *ctx, const struct token *token, 8490 const char *str, unsigned int len, 8491 void *buf, unsigned int size) 8492 { 8493 struct buffer *out = buf; 8494 8495 /* Token name must match. */ 8496 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8497 return -1; 8498 /* Nothing else to do if there is no buffer. */ 8499 if (!out) 8500 return len; 8501 if (!out->command) { 8502 if (ctx->curr != FLUSH) 8503 return -1; 8504 if (sizeof(*out) > size) 8505 return -1; 8506 out->command = ctx->curr; 8507 ctx->objdata = 0; 8508 ctx->object = out; 8509 ctx->objmask = NULL; 8510 } 8511 return len; 8512 } 8513 8514 /** Parse tokens for dump command. */ 8515 static int 8516 parse_dump(struct context *ctx, const struct token *token, 8517 const char *str, unsigned int len, 8518 void *buf, unsigned int size) 8519 { 8520 struct buffer *out = buf; 8521 8522 /* Token name must match. */ 8523 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8524 return -1; 8525 /* Nothing else to do if there is no buffer. */ 8526 if (!out) 8527 return len; 8528 if (!out->command) { 8529 if (ctx->curr != DUMP) 8530 return -1; 8531 if (sizeof(*out) > size) 8532 return -1; 8533 out->command = ctx->curr; 8534 ctx->objdata = 0; 8535 ctx->object = out; 8536 ctx->objmask = NULL; 8537 return len; 8538 } 8539 switch (ctx->curr) { 8540 case DUMP_ALL: 8541 case DUMP_ONE: 8542 out->args.dump.mode = (ctx->curr == DUMP_ALL) ? true : false; 8543 out->command = ctx->curr; 8544 ctx->objdata = 0; 8545 ctx->object = out; 8546 ctx->objmask = NULL; 8547 return len; 8548 default: 8549 return -1; 8550 } 8551 } 8552 8553 /** Parse tokens for query command. */ 8554 static int 8555 parse_query(struct context *ctx, const struct token *token, 8556 const char *str, unsigned int len, 8557 void *buf, unsigned int size) 8558 { 8559 struct buffer *out = buf; 8560 8561 /* Token name must match. */ 8562 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8563 return -1; 8564 /* Nothing else to do if there is no buffer. */ 8565 if (!out) 8566 return len; 8567 if (!out->command) { 8568 if (ctx->curr != QUERY) 8569 return -1; 8570 if (sizeof(*out) > size) 8571 return -1; 8572 out->command = ctx->curr; 8573 ctx->objdata = 0; 8574 ctx->object = out; 8575 ctx->objmask = NULL; 8576 } 8577 return len; 8578 } 8579 8580 /** Parse action names. */ 8581 static int 8582 parse_action(struct context *ctx, const struct token *token, 8583 const char *str, unsigned int len, 8584 void *buf, unsigned int size) 8585 { 8586 struct buffer *out = buf; 8587 const struct arg *arg = pop_args(ctx); 8588 unsigned int i; 8589 8590 (void)size; 8591 /* Argument is expected. */ 8592 if (!arg) 8593 return -1; 8594 /* Parse action name. */ 8595 for (i = 0; next_action[i]; ++i) { 8596 const struct parse_action_priv *priv; 8597 8598 token = &token_list[next_action[i]]; 8599 if (strcmp_partial(token->name, str, len)) 8600 continue; 8601 priv = token->priv; 8602 if (!priv) 8603 goto error; 8604 if (out) 8605 memcpy((uint8_t *)ctx->object + arg->offset, 8606 &priv->type, 8607 arg->size); 8608 return len; 8609 } 8610 error: 8611 push_args(ctx, arg); 8612 return -1; 8613 } 8614 8615 /** Parse tokens for list command. */ 8616 static int 8617 parse_list(struct context *ctx, const struct token *token, 8618 const char *str, unsigned int len, 8619 void *buf, unsigned int size) 8620 { 8621 struct buffer *out = buf; 8622 8623 /* Token name must match. */ 8624 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8625 return -1; 8626 /* Nothing else to do if there is no buffer. */ 8627 if (!out) 8628 return len; 8629 if (!out->command) { 8630 if (ctx->curr != LIST) 8631 return -1; 8632 if (sizeof(*out) > size) 8633 return -1; 8634 out->command = ctx->curr; 8635 ctx->objdata = 0; 8636 ctx->object = out; 8637 ctx->objmask = NULL; 8638 out->args.list.group = 8639 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8640 sizeof(double)); 8641 return len; 8642 } 8643 if (((uint8_t *)(out->args.list.group + out->args.list.group_n) + 8644 sizeof(*out->args.list.group)) > (uint8_t *)out + size) 8645 return -1; 8646 ctx->objdata = 0; 8647 ctx->object = out->args.list.group + out->args.list.group_n++; 8648 ctx->objmask = NULL; 8649 return len; 8650 } 8651 8652 /** Parse tokens for list all aged flows command. */ 8653 static int 8654 parse_aged(struct context *ctx, const struct token *token, 8655 const char *str, unsigned int len, 8656 void *buf, unsigned int size) 8657 { 8658 struct buffer *out = buf; 8659 8660 /* Token name must match. */ 8661 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8662 return -1; 8663 /* Nothing else to do if there is no buffer. */ 8664 if (!out) 8665 return len; 8666 if (!out->command || out->command == QUEUE) { 8667 if (ctx->curr != AGED && ctx->curr != QUEUE_AGED) 8668 return -1; 8669 if (sizeof(*out) > size) 8670 return -1; 8671 out->command = ctx->curr; 8672 ctx->objdata = 0; 8673 ctx->object = out; 8674 ctx->objmask = NULL; 8675 } 8676 if (ctx->curr == AGED_DESTROY) 8677 out->args.aged.destroy = 1; 8678 return len; 8679 } 8680 8681 /** Parse tokens for isolate command. */ 8682 static int 8683 parse_isolate(struct context *ctx, const struct token *token, 8684 const char *str, unsigned int len, 8685 void *buf, unsigned int size) 8686 { 8687 struct buffer *out = buf; 8688 8689 /* Token name must match. */ 8690 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8691 return -1; 8692 /* Nothing else to do if there is no buffer. */ 8693 if (!out) 8694 return len; 8695 if (!out->command) { 8696 if (ctx->curr != ISOLATE) 8697 return -1; 8698 if (sizeof(*out) > size) 8699 return -1; 8700 out->command = ctx->curr; 8701 ctx->objdata = 0; 8702 ctx->object = out; 8703 ctx->objmask = NULL; 8704 } 8705 return len; 8706 } 8707 8708 /** Parse tokens for info/configure command. */ 8709 static int 8710 parse_configure(struct context *ctx, const struct token *token, 8711 const char *str, unsigned int len, 8712 void *buf, unsigned int size) 8713 { 8714 struct buffer *out = buf; 8715 8716 /* Token name must match. */ 8717 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8718 return -1; 8719 /* Nothing else to do if there is no buffer. */ 8720 if (!out) 8721 return len; 8722 if (!out->command) { 8723 if (ctx->curr != INFO && ctx->curr != CONFIGURE) 8724 return -1; 8725 if (sizeof(*out) > size) 8726 return -1; 8727 out->command = ctx->curr; 8728 ctx->objdata = 0; 8729 ctx->object = out; 8730 ctx->objmask = NULL; 8731 } 8732 return len; 8733 } 8734 8735 /** Parse tokens for template create command. */ 8736 static int 8737 parse_template(struct context *ctx, const struct token *token, 8738 const char *str, unsigned int len, 8739 void *buf, unsigned int size) 8740 { 8741 struct buffer *out = buf; 8742 8743 /* Token name must match. */ 8744 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8745 return -1; 8746 /* Nothing else to do if there is no buffer. */ 8747 if (!out) 8748 return len; 8749 if (!out->command) { 8750 if (ctx->curr != PATTERN_TEMPLATE && 8751 ctx->curr != ACTIONS_TEMPLATE) 8752 return -1; 8753 if (sizeof(*out) > size) 8754 return -1; 8755 out->command = ctx->curr; 8756 ctx->objdata = 0; 8757 ctx->object = out; 8758 ctx->objmask = NULL; 8759 out->args.vc.data = (uint8_t *)out + size; 8760 return len; 8761 } 8762 switch (ctx->curr) { 8763 case PATTERN_TEMPLATE_CREATE: 8764 out->args.vc.pattern = 8765 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8766 sizeof(double)); 8767 out->args.vc.pat_templ_id = UINT32_MAX; 8768 out->command = ctx->curr; 8769 ctx->objdata = 0; 8770 ctx->object = out; 8771 ctx->objmask = NULL; 8772 return len; 8773 case PATTERN_TEMPLATE_EGRESS: 8774 out->args.vc.attr.egress = 1; 8775 return len; 8776 case PATTERN_TEMPLATE_INGRESS: 8777 out->args.vc.attr.ingress = 1; 8778 return len; 8779 case PATTERN_TEMPLATE_TRANSFER: 8780 out->args.vc.attr.transfer = 1; 8781 return len; 8782 case ACTIONS_TEMPLATE_CREATE: 8783 out->args.vc.act_templ_id = UINT32_MAX; 8784 out->command = ctx->curr; 8785 ctx->objdata = 0; 8786 ctx->object = out; 8787 ctx->objmask = NULL; 8788 return len; 8789 case ACTIONS_TEMPLATE_SPEC: 8790 out->args.vc.actions = 8791 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8792 sizeof(double)); 8793 ctx->object = out->args.vc.actions; 8794 ctx->objmask = NULL; 8795 return len; 8796 case ACTIONS_TEMPLATE_MASK: 8797 out->args.vc.masks = 8798 (void *)RTE_ALIGN_CEIL((uintptr_t) 8799 (out->args.vc.actions + 8800 out->args.vc.actions_n), 8801 sizeof(double)); 8802 ctx->object = out->args.vc.masks; 8803 ctx->objmask = NULL; 8804 return len; 8805 case ACTIONS_TEMPLATE_EGRESS: 8806 out->args.vc.attr.egress = 1; 8807 return len; 8808 case ACTIONS_TEMPLATE_INGRESS: 8809 out->args.vc.attr.ingress = 1; 8810 return len; 8811 case ACTIONS_TEMPLATE_TRANSFER: 8812 out->args.vc.attr.transfer = 1; 8813 return len; 8814 default: 8815 return -1; 8816 } 8817 } 8818 8819 /** Parse tokens for template destroy command. */ 8820 static int 8821 parse_template_destroy(struct context *ctx, const struct token *token, 8822 const char *str, unsigned int len, 8823 void *buf, unsigned int size) 8824 { 8825 struct buffer *out = buf; 8826 uint32_t *template_id; 8827 8828 /* Token name must match. */ 8829 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8830 return -1; 8831 /* Nothing else to do if there is no buffer. */ 8832 if (!out) 8833 return len; 8834 if (!out->command || 8835 out->command == PATTERN_TEMPLATE || 8836 out->command == ACTIONS_TEMPLATE) { 8837 if (ctx->curr != PATTERN_TEMPLATE_DESTROY && 8838 ctx->curr != ACTIONS_TEMPLATE_DESTROY) 8839 return -1; 8840 if (sizeof(*out) > size) 8841 return -1; 8842 out->command = ctx->curr; 8843 ctx->objdata = 0; 8844 ctx->object = out; 8845 ctx->objmask = NULL; 8846 out->args.templ_destroy.template_id = 8847 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8848 sizeof(double)); 8849 return len; 8850 } 8851 template_id = out->args.templ_destroy.template_id 8852 + out->args.templ_destroy.template_id_n++; 8853 if ((uint8_t *)template_id > (uint8_t *)out + size) 8854 return -1; 8855 ctx->objdata = 0; 8856 ctx->object = template_id; 8857 ctx->objmask = NULL; 8858 return len; 8859 } 8860 8861 /** Parse tokens for table create command. */ 8862 static int 8863 parse_table(struct context *ctx, const struct token *token, 8864 const char *str, unsigned int len, 8865 void *buf, unsigned int size) 8866 { 8867 struct buffer *out = buf; 8868 uint32_t *template_id; 8869 8870 /* Token name must match. */ 8871 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8872 return -1; 8873 /* Nothing else to do if there is no buffer. */ 8874 if (!out) 8875 return len; 8876 if (!out->command) { 8877 if (ctx->curr != TABLE) 8878 return -1; 8879 if (sizeof(*out) > size) 8880 return -1; 8881 out->command = ctx->curr; 8882 ctx->objdata = 0; 8883 ctx->object = out; 8884 ctx->objmask = NULL; 8885 return len; 8886 } 8887 switch (ctx->curr) { 8888 case TABLE_CREATE: 8889 out->command = ctx->curr; 8890 ctx->objdata = 0; 8891 ctx->object = out; 8892 ctx->objmask = NULL; 8893 out->args.table.id = UINT32_MAX; 8894 return len; 8895 case TABLE_PATTERN_TEMPLATE: 8896 out->args.table.pat_templ_id = 8897 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8898 sizeof(double)); 8899 template_id = out->args.table.pat_templ_id 8900 + out->args.table.pat_templ_id_n++; 8901 if ((uint8_t *)template_id > (uint8_t *)out + size) 8902 return -1; 8903 ctx->objdata = 0; 8904 ctx->object = template_id; 8905 ctx->objmask = NULL; 8906 return len; 8907 case TABLE_ACTIONS_TEMPLATE: 8908 out->args.table.act_templ_id = 8909 (void *)RTE_ALIGN_CEIL((uintptr_t) 8910 (out->args.table.pat_templ_id + 8911 out->args.table.pat_templ_id_n), 8912 sizeof(double)); 8913 template_id = out->args.table.act_templ_id 8914 + out->args.table.act_templ_id_n++; 8915 if ((uint8_t *)template_id > (uint8_t *)out + size) 8916 return -1; 8917 ctx->objdata = 0; 8918 ctx->object = template_id; 8919 ctx->objmask = NULL; 8920 return len; 8921 case TABLE_INGRESS: 8922 out->args.table.attr.flow_attr.ingress = 1; 8923 return len; 8924 case TABLE_EGRESS: 8925 out->args.table.attr.flow_attr.egress = 1; 8926 return len; 8927 case TABLE_TRANSFER: 8928 out->args.table.attr.flow_attr.transfer = 1; 8929 return len; 8930 default: 8931 return -1; 8932 } 8933 } 8934 8935 /** Parse tokens for table destroy command. */ 8936 static int 8937 parse_table_destroy(struct context *ctx, const struct token *token, 8938 const char *str, unsigned int len, 8939 void *buf, unsigned int size) 8940 { 8941 struct buffer *out = buf; 8942 uint32_t *table_id; 8943 8944 /* Token name must match. */ 8945 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8946 return -1; 8947 /* Nothing else to do if there is no buffer. */ 8948 if (!out) 8949 return len; 8950 if (!out->command || out->command == TABLE) { 8951 if (ctx->curr != TABLE_DESTROY) 8952 return -1; 8953 if (sizeof(*out) > size) 8954 return -1; 8955 out->command = ctx->curr; 8956 ctx->objdata = 0; 8957 ctx->object = out; 8958 ctx->objmask = NULL; 8959 out->args.table_destroy.table_id = 8960 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 8961 sizeof(double)); 8962 return len; 8963 } 8964 table_id = out->args.table_destroy.table_id 8965 + out->args.table_destroy.table_id_n++; 8966 if ((uint8_t *)table_id > (uint8_t *)out + size) 8967 return -1; 8968 ctx->objdata = 0; 8969 ctx->object = table_id; 8970 ctx->objmask = NULL; 8971 return len; 8972 } 8973 8974 /** Parse tokens for queue create commands. */ 8975 static int 8976 parse_qo(struct context *ctx, const struct token *token, 8977 const char *str, unsigned int len, 8978 void *buf, unsigned int size) 8979 { 8980 struct buffer *out = buf; 8981 8982 /* Token name must match. */ 8983 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 8984 return -1; 8985 /* Nothing else to do if there is no buffer. */ 8986 if (!out) 8987 return len; 8988 if (!out->command) { 8989 if (ctx->curr != QUEUE) 8990 return -1; 8991 if (sizeof(*out) > size) 8992 return -1; 8993 out->command = ctx->curr; 8994 ctx->objdata = 0; 8995 ctx->object = out; 8996 ctx->objmask = NULL; 8997 out->args.vc.data = (uint8_t *)out + size; 8998 return len; 8999 } 9000 switch (ctx->curr) { 9001 case QUEUE_CREATE: 9002 out->command = ctx->curr; 9003 ctx->objdata = 0; 9004 ctx->object = out; 9005 ctx->objmask = NULL; 9006 return len; 9007 case QUEUE_TEMPLATE_TABLE: 9008 case QUEUE_PATTERN_TEMPLATE: 9009 case QUEUE_ACTIONS_TEMPLATE: 9010 case QUEUE_CREATE_POSTPONE: 9011 return len; 9012 case ITEM_PATTERN: 9013 out->args.vc.pattern = 9014 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 9015 sizeof(double)); 9016 ctx->object = out->args.vc.pattern; 9017 ctx->objmask = NULL; 9018 return len; 9019 case ACTIONS: 9020 out->args.vc.actions = 9021 (void *)RTE_ALIGN_CEIL((uintptr_t) 9022 (out->args.vc.pattern + 9023 out->args.vc.pattern_n), 9024 sizeof(double)); 9025 ctx->object = out->args.vc.actions; 9026 ctx->objmask = NULL; 9027 return len; 9028 default: 9029 return -1; 9030 } 9031 } 9032 9033 /** Parse tokens for queue destroy command. */ 9034 static int 9035 parse_qo_destroy(struct context *ctx, const struct token *token, 9036 const char *str, unsigned int len, 9037 void *buf, unsigned int size) 9038 { 9039 struct buffer *out = buf; 9040 uint32_t *flow_id; 9041 9042 /* Token name must match. */ 9043 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9044 return -1; 9045 /* Nothing else to do if there is no buffer. */ 9046 if (!out) 9047 return len; 9048 if (!out->command || out->command == QUEUE) { 9049 if (ctx->curr != QUEUE_DESTROY) 9050 return -1; 9051 if (sizeof(*out) > size) 9052 return -1; 9053 out->command = ctx->curr; 9054 ctx->objdata = 0; 9055 ctx->object = out; 9056 ctx->objmask = NULL; 9057 out->args.destroy.rule = 9058 (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 9059 sizeof(double)); 9060 return len; 9061 } 9062 switch (ctx->curr) { 9063 case QUEUE_DESTROY_ID: 9064 flow_id = out->args.destroy.rule 9065 + out->args.destroy.rule_n++; 9066 if ((uint8_t *)flow_id > (uint8_t *)out + size) 9067 return -1; 9068 ctx->objdata = 0; 9069 ctx->object = flow_id; 9070 ctx->objmask = NULL; 9071 return len; 9072 case QUEUE_DESTROY_POSTPONE: 9073 return len; 9074 default: 9075 return -1; 9076 } 9077 } 9078 9079 /** Parse tokens for push queue command. */ 9080 static int 9081 parse_push(struct context *ctx, const struct token *token, 9082 const char *str, unsigned int len, 9083 void *buf, unsigned int size) 9084 { 9085 struct buffer *out = buf; 9086 9087 /* Token name must match. */ 9088 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9089 return -1; 9090 /* Nothing else to do if there is no buffer. */ 9091 if (!out) 9092 return len; 9093 if (!out->command) { 9094 if (ctx->curr != PUSH) 9095 return -1; 9096 if (sizeof(*out) > size) 9097 return -1; 9098 out->command = ctx->curr; 9099 ctx->objdata = 0; 9100 ctx->object = out; 9101 ctx->objmask = NULL; 9102 out->args.vc.data = (uint8_t *)out + size; 9103 } 9104 return len; 9105 } 9106 9107 /** Parse tokens for pull command. */ 9108 static int 9109 parse_pull(struct context *ctx, const struct token *token, 9110 const char *str, unsigned int len, 9111 void *buf, unsigned int size) 9112 { 9113 struct buffer *out = buf; 9114 9115 /* Token name must match. */ 9116 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9117 return -1; 9118 /* Nothing else to do if there is no buffer. */ 9119 if (!out) 9120 return len; 9121 if (!out->command) { 9122 if (ctx->curr != PULL) 9123 return -1; 9124 if (sizeof(*out) > size) 9125 return -1; 9126 out->command = ctx->curr; 9127 ctx->objdata = 0; 9128 ctx->object = out; 9129 ctx->objmask = NULL; 9130 out->args.vc.data = (uint8_t *)out + size; 9131 } 9132 return len; 9133 } 9134 9135 static int 9136 parse_flex(struct context *ctx, const struct token *token, 9137 const char *str, unsigned int len, 9138 void *buf, unsigned int size) 9139 { 9140 struct buffer *out = buf; 9141 9142 /* Token name must match. */ 9143 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9144 return -1; 9145 /* Nothing else to do if there is no buffer. */ 9146 if (!out) 9147 return len; 9148 if (out->command == ZERO) { 9149 if (ctx->curr != FLEX) 9150 return -1; 9151 if (sizeof(*out) > size) 9152 return -1; 9153 out->command = ctx->curr; 9154 ctx->objdata = 0; 9155 ctx->object = out; 9156 ctx->objmask = NULL; 9157 } else { 9158 switch (ctx->curr) { 9159 default: 9160 break; 9161 case FLEX_ITEM_INIT: 9162 case FLEX_ITEM_CREATE: 9163 case FLEX_ITEM_DESTROY: 9164 out->command = ctx->curr; 9165 break; 9166 } 9167 } 9168 9169 return len; 9170 } 9171 9172 static int 9173 parse_tunnel(struct context *ctx, const struct token *token, 9174 const char *str, unsigned int len, 9175 void *buf, unsigned int size) 9176 { 9177 struct buffer *out = buf; 9178 9179 /* Token name must match. */ 9180 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9181 return -1; 9182 /* Nothing else to do if there is no buffer. */ 9183 if (!out) 9184 return len; 9185 if (!out->command) { 9186 if (ctx->curr != TUNNEL) 9187 return -1; 9188 if (sizeof(*out) > size) 9189 return -1; 9190 out->command = ctx->curr; 9191 ctx->objdata = 0; 9192 ctx->object = out; 9193 ctx->objmask = NULL; 9194 } else { 9195 switch (ctx->curr) { 9196 default: 9197 break; 9198 case TUNNEL_CREATE: 9199 case TUNNEL_DESTROY: 9200 case TUNNEL_LIST: 9201 out->command = ctx->curr; 9202 break; 9203 case TUNNEL_CREATE_TYPE: 9204 case TUNNEL_DESTROY_ID: 9205 ctx->object = &out->args.vc.tunnel_ops; 9206 break; 9207 } 9208 } 9209 9210 return len; 9211 } 9212 9213 /** 9214 * Parse signed/unsigned integers 8 to 64-bit long. 9215 * 9216 * Last argument (ctx->args) is retrieved to determine integer type and 9217 * storage location. 9218 */ 9219 static int 9220 parse_int(struct context *ctx, const struct token *token, 9221 const char *str, unsigned int len, 9222 void *buf, unsigned int size) 9223 { 9224 const struct arg *arg = pop_args(ctx); 9225 uintmax_t u; 9226 char *end; 9227 9228 (void)token; 9229 /* Argument is expected. */ 9230 if (!arg) 9231 return -1; 9232 errno = 0; 9233 u = arg->sign ? 9234 (uintmax_t)strtoimax(str, &end, 0) : 9235 strtoumax(str, &end, 0); 9236 if (errno || (size_t)(end - str) != len) 9237 goto error; 9238 if (arg->bounded && 9239 ((arg->sign && ((intmax_t)u < (intmax_t)arg->min || 9240 (intmax_t)u > (intmax_t)arg->max)) || 9241 (!arg->sign && (u < arg->min || u > arg->max)))) 9242 goto error; 9243 if (!ctx->object) 9244 return len; 9245 if (arg->mask) { 9246 if (!arg_entry_bf_fill(ctx->object, u, arg) || 9247 !arg_entry_bf_fill(ctx->objmask, -1, arg)) 9248 goto error; 9249 return len; 9250 } 9251 buf = (uint8_t *)ctx->object + arg->offset; 9252 size = arg->size; 9253 if (u > RTE_LEN2MASK(size * CHAR_BIT, uint64_t)) 9254 return -1; 9255 objmask: 9256 switch (size) { 9257 case sizeof(uint8_t): 9258 *(uint8_t *)buf = u; 9259 break; 9260 case sizeof(uint16_t): 9261 *(uint16_t *)buf = arg->hton ? rte_cpu_to_be_16(u) : u; 9262 break; 9263 case sizeof(uint8_t [3]): 9264 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 9265 if (!arg->hton) { 9266 ((uint8_t *)buf)[0] = u; 9267 ((uint8_t *)buf)[1] = u >> 8; 9268 ((uint8_t *)buf)[2] = u >> 16; 9269 break; 9270 } 9271 #endif 9272 ((uint8_t *)buf)[0] = u >> 16; 9273 ((uint8_t *)buf)[1] = u >> 8; 9274 ((uint8_t *)buf)[2] = u; 9275 break; 9276 case sizeof(uint32_t): 9277 *(uint32_t *)buf = arg->hton ? rte_cpu_to_be_32(u) : u; 9278 break; 9279 case sizeof(uint64_t): 9280 *(uint64_t *)buf = arg->hton ? rte_cpu_to_be_64(u) : u; 9281 break; 9282 default: 9283 goto error; 9284 } 9285 if (ctx->objmask && buf != (uint8_t *)ctx->objmask + arg->offset) { 9286 u = -1; 9287 buf = (uint8_t *)ctx->objmask + arg->offset; 9288 goto objmask; 9289 } 9290 return len; 9291 error: 9292 push_args(ctx, arg); 9293 return -1; 9294 } 9295 9296 /** 9297 * Parse a string. 9298 * 9299 * Three arguments (ctx->args) are retrieved from the stack to store data, 9300 * its actual length and address (in that order). 9301 */ 9302 static int 9303 parse_string(struct context *ctx, const struct token *token, 9304 const char *str, unsigned int len, 9305 void *buf, unsigned int size) 9306 { 9307 const struct arg *arg_data = pop_args(ctx); 9308 const struct arg *arg_len = pop_args(ctx); 9309 const struct arg *arg_addr = pop_args(ctx); 9310 char tmp[16]; /* Ought to be enough. */ 9311 int ret; 9312 9313 /* Arguments are expected. */ 9314 if (!arg_data) 9315 return -1; 9316 if (!arg_len) { 9317 push_args(ctx, arg_data); 9318 return -1; 9319 } 9320 if (!arg_addr) { 9321 push_args(ctx, arg_len); 9322 push_args(ctx, arg_data); 9323 return -1; 9324 } 9325 size = arg_data->size; 9326 /* Bit-mask fill is not supported. */ 9327 if (arg_data->mask || size < len) 9328 goto error; 9329 if (!ctx->object) 9330 return len; 9331 /* Let parse_int() fill length information first. */ 9332 ret = snprintf(tmp, sizeof(tmp), "%u", len); 9333 if (ret < 0) 9334 goto error; 9335 push_args(ctx, arg_len); 9336 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 9337 if (ret < 0) { 9338 pop_args(ctx); 9339 goto error; 9340 } 9341 buf = (uint8_t *)ctx->object + arg_data->offset; 9342 /* Output buffer is not necessarily NUL-terminated. */ 9343 memcpy(buf, str, len); 9344 memset((uint8_t *)buf + len, 0x00, size - len); 9345 if (ctx->objmask) 9346 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 9347 /* Save address if requested. */ 9348 if (arg_addr->size) { 9349 memcpy((uint8_t *)ctx->object + arg_addr->offset, 9350 (void *[]){ 9351 (uint8_t *)ctx->object + arg_data->offset 9352 }, 9353 arg_addr->size); 9354 if (ctx->objmask) 9355 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 9356 (void *[]){ 9357 (uint8_t *)ctx->objmask + arg_data->offset 9358 }, 9359 arg_addr->size); 9360 } 9361 return len; 9362 error: 9363 push_args(ctx, arg_addr); 9364 push_args(ctx, arg_len); 9365 push_args(ctx, arg_data); 9366 return -1; 9367 } 9368 9369 static int 9370 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size) 9371 { 9372 const uint8_t *head = dst; 9373 uint32_t left; 9374 9375 if (*size == 0) 9376 return -1; 9377 9378 left = *size; 9379 9380 /* Convert chars to bytes */ 9381 while (left) { 9382 char tmp[3], *end = tmp; 9383 uint32_t read_lim = left & 1 ? 1 : 2; 9384 9385 snprintf(tmp, read_lim + 1, "%s", src); 9386 *dst = strtoul(tmp, &end, 16); 9387 if (*end) { 9388 *dst = 0; 9389 *size = (uint32_t)(dst - head); 9390 return -1; 9391 } 9392 left -= read_lim; 9393 src += read_lim; 9394 dst++; 9395 } 9396 *dst = 0; 9397 *size = (uint32_t)(dst - head); 9398 return 0; 9399 } 9400 9401 static int 9402 parse_hex(struct context *ctx, const struct token *token, 9403 const char *str, unsigned int len, 9404 void *buf, unsigned int size) 9405 { 9406 const struct arg *arg_data = pop_args(ctx); 9407 const struct arg *arg_len = pop_args(ctx); 9408 const struct arg *arg_addr = pop_args(ctx); 9409 char tmp[16]; /* Ought to be enough. */ 9410 int ret; 9411 unsigned int hexlen = len; 9412 unsigned int length = 256; 9413 uint8_t hex_tmp[length]; 9414 9415 /* Arguments are expected. */ 9416 if (!arg_data) 9417 return -1; 9418 if (!arg_len) { 9419 push_args(ctx, arg_data); 9420 return -1; 9421 } 9422 if (!arg_addr) { 9423 push_args(ctx, arg_len); 9424 push_args(ctx, arg_data); 9425 return -1; 9426 } 9427 size = arg_data->size; 9428 /* Bit-mask fill is not supported. */ 9429 if (arg_data->mask) 9430 goto error; 9431 if (!ctx->object) 9432 return len; 9433 9434 /* translate bytes string to array. */ 9435 if (str[0] == '0' && ((str[1] == 'x') || 9436 (str[1] == 'X'))) { 9437 str += 2; 9438 hexlen -= 2; 9439 } 9440 if (hexlen > length) 9441 goto error; 9442 ret = parse_hex_string(str, hex_tmp, &hexlen); 9443 if (ret < 0) 9444 goto error; 9445 /* Check the converted binary fits into data buffer. */ 9446 if (hexlen > size) 9447 goto error; 9448 /* Let parse_int() fill length information first. */ 9449 ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); 9450 if (ret < 0) 9451 goto error; 9452 /* Save length if requested. */ 9453 if (arg_len->size) { 9454 push_args(ctx, arg_len); 9455 ret = parse_int(ctx, token, tmp, ret, NULL, 0); 9456 if (ret < 0) { 9457 pop_args(ctx); 9458 goto error; 9459 } 9460 } 9461 buf = (uint8_t *)ctx->object + arg_data->offset; 9462 /* Output buffer is not necessarily NUL-terminated. */ 9463 memcpy(buf, hex_tmp, hexlen); 9464 memset((uint8_t *)buf + hexlen, 0x00, size - hexlen); 9465 if (ctx->objmask) 9466 memset((uint8_t *)ctx->objmask + arg_data->offset, 9467 0xff, hexlen); 9468 /* Save address if requested. */ 9469 if (arg_addr->size) { 9470 memcpy((uint8_t *)ctx->object + arg_addr->offset, 9471 (void *[]){ 9472 (uint8_t *)ctx->object + arg_data->offset 9473 }, 9474 arg_addr->size); 9475 if (ctx->objmask) 9476 memcpy((uint8_t *)ctx->objmask + arg_addr->offset, 9477 (void *[]){ 9478 (uint8_t *)ctx->objmask + arg_data->offset 9479 }, 9480 arg_addr->size); 9481 } 9482 return len; 9483 error: 9484 push_args(ctx, arg_addr); 9485 push_args(ctx, arg_len); 9486 push_args(ctx, arg_data); 9487 return -1; 9488 9489 } 9490 9491 /** 9492 * Parse a zero-ended string. 9493 */ 9494 static int 9495 parse_string0(struct context *ctx, const struct token *token __rte_unused, 9496 const char *str, unsigned int len, 9497 void *buf, unsigned int size) 9498 { 9499 const struct arg *arg_data = pop_args(ctx); 9500 9501 /* Arguments are expected. */ 9502 if (!arg_data) 9503 return -1; 9504 size = arg_data->size; 9505 /* Bit-mask fill is not supported. */ 9506 if (arg_data->mask || size < len + 1) 9507 goto error; 9508 if (!ctx->object) 9509 return len; 9510 buf = (uint8_t *)ctx->object + arg_data->offset; 9511 strncpy(buf, str, len); 9512 if (ctx->objmask) 9513 memset((uint8_t *)ctx->objmask + arg_data->offset, 0xff, len); 9514 return len; 9515 error: 9516 push_args(ctx, arg_data); 9517 return -1; 9518 } 9519 9520 /** 9521 * Parse a MAC address. 9522 * 9523 * Last argument (ctx->args) is retrieved to determine storage size and 9524 * location. 9525 */ 9526 static int 9527 parse_mac_addr(struct context *ctx, const struct token *token, 9528 const char *str, unsigned int len, 9529 void *buf, unsigned int size) 9530 { 9531 const struct arg *arg = pop_args(ctx); 9532 struct rte_ether_addr tmp; 9533 int ret; 9534 9535 (void)token; 9536 /* Argument is expected. */ 9537 if (!arg) 9538 return -1; 9539 size = arg->size; 9540 /* Bit-mask fill is not supported. */ 9541 if (arg->mask || size != sizeof(tmp)) 9542 goto error; 9543 /* Only network endian is supported. */ 9544 if (!arg->hton) 9545 goto error; 9546 ret = cmdline_parse_etheraddr(NULL, str, &tmp, size); 9547 if (ret < 0 || (unsigned int)ret != len) 9548 goto error; 9549 if (!ctx->object) 9550 return len; 9551 buf = (uint8_t *)ctx->object + arg->offset; 9552 memcpy(buf, &tmp, size); 9553 if (ctx->objmask) 9554 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 9555 return len; 9556 error: 9557 push_args(ctx, arg); 9558 return -1; 9559 } 9560 9561 /** 9562 * Parse an IPv4 address. 9563 * 9564 * Last argument (ctx->args) is retrieved to determine storage size and 9565 * location. 9566 */ 9567 static int 9568 parse_ipv4_addr(struct context *ctx, const struct token *token, 9569 const char *str, unsigned int len, 9570 void *buf, unsigned int size) 9571 { 9572 const struct arg *arg = pop_args(ctx); 9573 char str2[len + 1]; 9574 struct in_addr tmp; 9575 int ret; 9576 9577 /* Argument is expected. */ 9578 if (!arg) 9579 return -1; 9580 size = arg->size; 9581 /* Bit-mask fill is not supported. */ 9582 if (arg->mask || size != sizeof(tmp)) 9583 goto error; 9584 /* Only network endian is supported. */ 9585 if (!arg->hton) 9586 goto error; 9587 memcpy(str2, str, len); 9588 str2[len] = '\0'; 9589 ret = inet_pton(AF_INET, str2, &tmp); 9590 if (ret != 1) { 9591 /* Attempt integer parsing. */ 9592 push_args(ctx, arg); 9593 return parse_int(ctx, token, str, len, buf, size); 9594 } 9595 if (!ctx->object) 9596 return len; 9597 buf = (uint8_t *)ctx->object + arg->offset; 9598 memcpy(buf, &tmp, size); 9599 if (ctx->objmask) 9600 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 9601 return len; 9602 error: 9603 push_args(ctx, arg); 9604 return -1; 9605 } 9606 9607 /** 9608 * Parse an IPv6 address. 9609 * 9610 * Last argument (ctx->args) is retrieved to determine storage size and 9611 * location. 9612 */ 9613 static int 9614 parse_ipv6_addr(struct context *ctx, const struct token *token, 9615 const char *str, unsigned int len, 9616 void *buf, unsigned int size) 9617 { 9618 const struct arg *arg = pop_args(ctx); 9619 char str2[len + 1]; 9620 struct in6_addr tmp; 9621 int ret; 9622 9623 (void)token; 9624 /* Argument is expected. */ 9625 if (!arg) 9626 return -1; 9627 size = arg->size; 9628 /* Bit-mask fill is not supported. */ 9629 if (arg->mask || size != sizeof(tmp)) 9630 goto error; 9631 /* Only network endian is supported. */ 9632 if (!arg->hton) 9633 goto error; 9634 memcpy(str2, str, len); 9635 str2[len] = '\0'; 9636 ret = inet_pton(AF_INET6, str2, &tmp); 9637 if (ret != 1) 9638 goto error; 9639 if (!ctx->object) 9640 return len; 9641 buf = (uint8_t *)ctx->object + arg->offset; 9642 memcpy(buf, &tmp, size); 9643 if (ctx->objmask) 9644 memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size); 9645 return len; 9646 error: 9647 push_args(ctx, arg); 9648 return -1; 9649 } 9650 9651 /** Boolean values (even indices stand for false). */ 9652 static const char *const boolean_name[] = { 9653 "0", "1", 9654 "false", "true", 9655 "no", "yes", 9656 "N", "Y", 9657 "off", "on", 9658 NULL, 9659 }; 9660 9661 /** 9662 * Parse a boolean value. 9663 * 9664 * Last argument (ctx->args) is retrieved to determine storage size and 9665 * location. 9666 */ 9667 static int 9668 parse_boolean(struct context *ctx, const struct token *token, 9669 const char *str, unsigned int len, 9670 void *buf, unsigned int size) 9671 { 9672 const struct arg *arg = pop_args(ctx); 9673 unsigned int i; 9674 int ret; 9675 9676 /* Argument is expected. */ 9677 if (!arg) 9678 return -1; 9679 for (i = 0; boolean_name[i]; ++i) 9680 if (!strcmp_partial(boolean_name[i], str, len)) 9681 break; 9682 /* Process token as integer. */ 9683 if (boolean_name[i]) 9684 str = i & 1 ? "1" : "0"; 9685 push_args(ctx, arg); 9686 ret = parse_int(ctx, token, str, strlen(str), buf, size); 9687 return ret > 0 ? (int)len : ret; 9688 } 9689 9690 /** Parse port and update context. */ 9691 static int 9692 parse_port(struct context *ctx, const struct token *token, 9693 const char *str, unsigned int len, 9694 void *buf, unsigned int size) 9695 { 9696 struct buffer *out = &(struct buffer){ .port = 0 }; 9697 int ret; 9698 9699 if (buf) 9700 out = buf; 9701 else { 9702 ctx->objdata = 0; 9703 ctx->object = out; 9704 ctx->objmask = NULL; 9705 size = sizeof(*out); 9706 } 9707 ret = parse_int(ctx, token, str, len, out, size); 9708 if (ret >= 0) 9709 ctx->port = out->port; 9710 if (!buf) 9711 ctx->object = NULL; 9712 return ret; 9713 } 9714 9715 static int 9716 parse_ia_id2ptr(struct context *ctx, const struct token *token, 9717 const char *str, unsigned int len, 9718 void *buf, unsigned int size) 9719 { 9720 struct rte_flow_action *action = ctx->object; 9721 uint32_t id; 9722 int ret; 9723 9724 (void)buf; 9725 (void)size; 9726 ctx->objdata = 0; 9727 ctx->object = &id; 9728 ctx->objmask = NULL; 9729 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 9730 ctx->object = action; 9731 if (ret != (int)len) 9732 return ret; 9733 /* set indirect action */ 9734 if (action) { 9735 action->conf = port_action_handle_get_by_id(ctx->port, id); 9736 ret = (action->conf) ? ret : -1; 9737 } 9738 return ret; 9739 } 9740 9741 static int 9742 parse_meter_profile_id2ptr(struct context *ctx, const struct token *token, 9743 const char *str, unsigned int len, 9744 void *buf, unsigned int size) 9745 { 9746 struct rte_flow_action *action = ctx->object; 9747 struct rte_flow_action_meter_mark *meter; 9748 struct rte_flow_meter_profile *profile = NULL; 9749 uint32_t id = 0; 9750 int ret; 9751 9752 (void)buf; 9753 (void)size; 9754 ctx->objdata = 0; 9755 ctx->object = &id; 9756 ctx->objmask = NULL; 9757 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 9758 ctx->object = action; 9759 if (ret != (int)len) 9760 return ret; 9761 /* set meter profile */ 9762 if (action) { 9763 meter = (struct rte_flow_action_meter_mark *) 9764 (uintptr_t)(action->conf); 9765 profile = port_meter_profile_get_by_id(ctx->port, id); 9766 meter->profile = profile; 9767 ret = (profile) ? ret : -1; 9768 } 9769 return ret; 9770 } 9771 9772 static int 9773 parse_meter_policy_id2ptr(struct context *ctx, const struct token *token, 9774 const char *str, unsigned int len, 9775 void *buf, unsigned int size) 9776 { 9777 struct rte_flow_action *action = ctx->object; 9778 struct rte_flow_action_meter_mark *meter; 9779 struct rte_flow_meter_policy *policy = NULL; 9780 uint32_t id = 0; 9781 int ret; 9782 9783 (void)buf; 9784 (void)size; 9785 ctx->objdata = 0; 9786 ctx->object = &id; 9787 ctx->objmask = NULL; 9788 ret = parse_int(ctx, token, str, len, ctx->object, sizeof(id)); 9789 ctx->object = action; 9790 if (ret != (int)len) 9791 return ret; 9792 /* set meter policy */ 9793 if (action) { 9794 meter = (struct rte_flow_action_meter_mark *) 9795 (uintptr_t)(action->conf); 9796 policy = port_meter_policy_get_by_id(ctx->port, id); 9797 meter->policy = policy; 9798 ret = (policy) ? ret : -1; 9799 } 9800 return ret; 9801 } 9802 9803 /** Parse set command, initialize output buffer for subsequent tokens. */ 9804 static int 9805 parse_set_raw_encap_decap(struct context *ctx, const struct token *token, 9806 const char *str, unsigned int len, 9807 void *buf, unsigned int size) 9808 { 9809 struct buffer *out = buf; 9810 9811 /* Token name must match. */ 9812 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9813 return -1; 9814 /* Nothing else to do if there is no buffer. */ 9815 if (!out) 9816 return len; 9817 /* Make sure buffer is large enough. */ 9818 if (size < sizeof(*out)) 9819 return -1; 9820 ctx->objdata = 0; 9821 ctx->objmask = NULL; 9822 ctx->object = out; 9823 if (!out->command) 9824 return -1; 9825 out->command = ctx->curr; 9826 /* For encap/decap we need is pattern */ 9827 out->args.vc.pattern = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 9828 sizeof(double)); 9829 return len; 9830 } 9831 9832 /** Parse set command, initialize output buffer for subsequent tokens. */ 9833 static int 9834 parse_set_sample_action(struct context *ctx, const struct token *token, 9835 const char *str, unsigned int len, 9836 void *buf, unsigned int size) 9837 { 9838 struct buffer *out = buf; 9839 9840 /* Token name must match. */ 9841 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9842 return -1; 9843 /* Nothing else to do if there is no buffer. */ 9844 if (!out) 9845 return len; 9846 /* Make sure buffer is large enough. */ 9847 if (size < sizeof(*out)) 9848 return -1; 9849 ctx->objdata = 0; 9850 ctx->objmask = NULL; 9851 ctx->object = out; 9852 if (!out->command) 9853 return -1; 9854 out->command = ctx->curr; 9855 /* For sampler we need is actions */ 9856 out->args.vc.actions = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 9857 sizeof(double)); 9858 return len; 9859 } 9860 9861 /** 9862 * Parse set raw_encap/raw_decap command, 9863 * initialize output buffer for subsequent tokens. 9864 */ 9865 static int 9866 parse_set_init(struct context *ctx, const struct token *token, 9867 const char *str, unsigned int len, 9868 void *buf, unsigned int size) 9869 { 9870 struct buffer *out = buf; 9871 9872 /* Token name must match. */ 9873 if (parse_default(ctx, token, str, len, NULL, 0) < 0) 9874 return -1; 9875 /* Nothing else to do if there is no buffer. */ 9876 if (!out) 9877 return len; 9878 /* Make sure buffer is large enough. */ 9879 if (size < sizeof(*out)) 9880 return -1; 9881 /* Initialize buffer. */ 9882 memset(out, 0x00, sizeof(*out)); 9883 memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out)); 9884 ctx->objdata = 0; 9885 ctx->object = out; 9886 ctx->objmask = NULL; 9887 if (!out->command) { 9888 if (ctx->curr != SET) 9889 return -1; 9890 if (sizeof(*out) > size) 9891 return -1; 9892 out->command = ctx->curr; 9893 out->args.vc.data = (uint8_t *)out + size; 9894 ctx->object = (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1), 9895 sizeof(double)); 9896 } 9897 return len; 9898 } 9899 9900 /* 9901 * Replace testpmd handles in a flex flow item with real values. 9902 */ 9903 static int 9904 parse_flex_handle(struct context *ctx, const struct token *token, 9905 const char *str, unsigned int len, 9906 void *buf, unsigned int size) 9907 { 9908 struct rte_flow_item_flex *spec, *mask; 9909 const struct rte_flow_item_flex *src_spec, *src_mask; 9910 const struct arg *arg = pop_args(ctx); 9911 uint32_t offset; 9912 uint16_t handle; 9913 int ret; 9914 9915 if (!arg) { 9916 printf("Bad environment\n"); 9917 return -1; 9918 } 9919 offset = arg->offset; 9920 push_args(ctx, arg); 9921 ret = parse_int(ctx, token, str, len, buf, size); 9922 if (ret <= 0 || !ctx->object) 9923 return ret; 9924 if (ctx->port >= RTE_MAX_ETHPORTS) { 9925 printf("Bad port\n"); 9926 return -1; 9927 } 9928 if (offset == offsetof(struct rte_flow_item_flex, handle)) { 9929 const struct flex_item *fp; 9930 struct rte_flow_item_flex *item_flex = ctx->object; 9931 handle = (uint16_t)(uintptr_t)item_flex->handle; 9932 if (handle >= FLEX_MAX_PARSERS_NUM) { 9933 printf("Bad flex item handle\n"); 9934 return -1; 9935 } 9936 fp = flex_items[ctx->port][handle]; 9937 if (!fp) { 9938 printf("Bad flex item handle\n"); 9939 return -1; 9940 } 9941 item_flex->handle = fp->flex_handle; 9942 } else if (offset == offsetof(struct rte_flow_item_flex, pattern)) { 9943 handle = (uint16_t)(uintptr_t) 9944 ((struct rte_flow_item_flex *)ctx->object)->pattern; 9945 if (handle >= FLEX_MAX_PATTERNS_NUM) { 9946 printf("Bad pattern handle\n"); 9947 return -1; 9948 } 9949 src_spec = &flex_patterns[handle].spec; 9950 src_mask = &flex_patterns[handle].mask; 9951 spec = ctx->object; 9952 mask = spec + 2; /* spec, last, mask */ 9953 /* fill flow rule spec and mask parameters */ 9954 spec->length = src_spec->length; 9955 spec->pattern = src_spec->pattern; 9956 mask->length = src_mask->length; 9957 mask->pattern = src_mask->pattern; 9958 } else { 9959 printf("Bad arguments - unknown flex item offset\n"); 9960 return -1; 9961 } 9962 return ret; 9963 } 9964 9965 /** Parse Meter color name */ 9966 static int 9967 parse_meter_color(struct context *ctx, const struct token *token, 9968 const char *str, unsigned int len, void *buf, 9969 unsigned int size) 9970 { 9971 struct rte_flow_item_meter_color *meter_color; 9972 unsigned int i; 9973 9974 (void)token; 9975 (void)buf; 9976 (void)size; 9977 for (i = 0; meter_colors[i]; ++i) 9978 if (!strcmp_partial(meter_colors[i], str, len)) 9979 break; 9980 if (!meter_colors[i]) 9981 return -1; 9982 if (!ctx->object) 9983 return len; 9984 meter_color = ctx->object; 9985 meter_color->color = (enum rte_color)i; 9986 return len; 9987 } 9988 9989 /** No completion. */ 9990 static int 9991 comp_none(struct context *ctx, const struct token *token, 9992 unsigned int ent, char *buf, unsigned int size) 9993 { 9994 (void)ctx; 9995 (void)token; 9996 (void)ent; 9997 (void)buf; 9998 (void)size; 9999 return 0; 10000 } 10001 10002 /** Complete boolean values. */ 10003 static int 10004 comp_boolean(struct context *ctx, const struct token *token, 10005 unsigned int ent, char *buf, unsigned int size) 10006 { 10007 unsigned int i; 10008 10009 (void)ctx; 10010 (void)token; 10011 for (i = 0; boolean_name[i]; ++i) 10012 if (buf && i == ent) 10013 return strlcpy(buf, boolean_name[i], size); 10014 if (buf) 10015 return -1; 10016 return i; 10017 } 10018 10019 /** Complete action names. */ 10020 static int 10021 comp_action(struct context *ctx, const struct token *token, 10022 unsigned int ent, char *buf, unsigned int size) 10023 { 10024 unsigned int i; 10025 10026 (void)ctx; 10027 (void)token; 10028 for (i = 0; next_action[i]; ++i) 10029 if (buf && i == ent) 10030 return strlcpy(buf, token_list[next_action[i]].name, 10031 size); 10032 if (buf) 10033 return -1; 10034 return i; 10035 } 10036 10037 /** Complete available ports. */ 10038 static int 10039 comp_port(struct context *ctx, const struct token *token, 10040 unsigned int ent, char *buf, unsigned int size) 10041 { 10042 unsigned int i = 0; 10043 portid_t p; 10044 10045 (void)ctx; 10046 (void)token; 10047 RTE_ETH_FOREACH_DEV(p) { 10048 if (buf && i == ent) 10049 return snprintf(buf, size, "%u", p); 10050 ++i; 10051 } 10052 if (buf) 10053 return -1; 10054 return i; 10055 } 10056 10057 /** Complete available rule IDs. */ 10058 static int 10059 comp_rule_id(struct context *ctx, const struct token *token, 10060 unsigned int ent, char *buf, unsigned int size) 10061 { 10062 unsigned int i = 0; 10063 struct rte_port *port; 10064 struct port_flow *pf; 10065 10066 (void)token; 10067 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 10068 ctx->port == (portid_t)RTE_PORT_ALL) 10069 return -1; 10070 port = &ports[ctx->port]; 10071 for (pf = port->flow_list; pf != NULL; pf = pf->next) { 10072 if (buf && i == ent) 10073 return snprintf(buf, size, "%u", pf->id); 10074 ++i; 10075 } 10076 if (buf) 10077 return -1; 10078 return i; 10079 } 10080 10081 /** Complete type field for RSS action. */ 10082 static int 10083 comp_vc_action_rss_type(struct context *ctx, const struct token *token, 10084 unsigned int ent, char *buf, unsigned int size) 10085 { 10086 unsigned int i; 10087 10088 (void)ctx; 10089 (void)token; 10090 for (i = 0; rss_type_table[i].str; ++i) 10091 ; 10092 if (!buf) 10093 return i + 1; 10094 if (ent < i) 10095 return strlcpy(buf, rss_type_table[ent].str, size); 10096 if (ent == i) 10097 return snprintf(buf, size, "end"); 10098 return -1; 10099 } 10100 10101 /** Complete queue field for RSS action. */ 10102 static int 10103 comp_vc_action_rss_queue(struct context *ctx, const struct token *token, 10104 unsigned int ent, char *buf, unsigned int size) 10105 { 10106 (void)ctx; 10107 (void)token; 10108 if (!buf) 10109 return nb_rxq + 1; 10110 if (ent < nb_rxq) 10111 return snprintf(buf, size, "%u", ent); 10112 if (ent == nb_rxq) 10113 return snprintf(buf, size, "end"); 10114 return -1; 10115 } 10116 10117 /** Complete index number for set raw_encap/raw_decap commands. */ 10118 static int 10119 comp_set_raw_index(struct context *ctx, const struct token *token, 10120 unsigned int ent, char *buf, unsigned int size) 10121 { 10122 uint16_t idx = 0; 10123 uint16_t nb = 0; 10124 10125 RTE_SET_USED(ctx); 10126 RTE_SET_USED(token); 10127 for (idx = 0; idx < RAW_ENCAP_CONFS_MAX_NUM; ++idx) { 10128 if (buf && idx == ent) 10129 return snprintf(buf, size, "%u", idx); 10130 ++nb; 10131 } 10132 return nb; 10133 } 10134 10135 /** Complete index number for set raw_encap/raw_decap commands. */ 10136 static int 10137 comp_set_sample_index(struct context *ctx, const struct token *token, 10138 unsigned int ent, char *buf, unsigned int size) 10139 { 10140 uint16_t idx = 0; 10141 uint16_t nb = 0; 10142 10143 RTE_SET_USED(ctx); 10144 RTE_SET_USED(token); 10145 for (idx = 0; idx < RAW_SAMPLE_CONFS_MAX_NUM; ++idx) { 10146 if (buf && idx == ent) 10147 return snprintf(buf, size, "%u", idx); 10148 ++nb; 10149 } 10150 return nb; 10151 } 10152 10153 /** Complete operation for modify_field command. */ 10154 static int 10155 comp_set_modify_field_op(struct context *ctx, const struct token *token, 10156 unsigned int ent, char *buf, unsigned int size) 10157 { 10158 RTE_SET_USED(ctx); 10159 RTE_SET_USED(token); 10160 if (!buf) 10161 return RTE_DIM(modify_field_ops); 10162 if (ent < RTE_DIM(modify_field_ops) - 1) 10163 return strlcpy(buf, modify_field_ops[ent], size); 10164 return -1; 10165 } 10166 10167 /** Complete field id for modify_field command. */ 10168 static int 10169 comp_set_modify_field_id(struct context *ctx, const struct token *token, 10170 unsigned int ent, char *buf, unsigned int size) 10171 { 10172 const char *name; 10173 10174 RTE_SET_USED(token); 10175 if (!buf) 10176 return RTE_DIM(modify_field_ids); 10177 if (ent >= RTE_DIM(modify_field_ids) - 1) 10178 return -1; 10179 name = modify_field_ids[ent]; 10180 if (ctx->curr == ACTION_MODIFY_FIELD_SRC_TYPE || 10181 (strcmp(name, "pointer") && strcmp(name, "value"))) 10182 return strlcpy(buf, name, size); 10183 return -1; 10184 } 10185 10186 /** Complete available pattern template IDs. */ 10187 static int 10188 comp_pattern_template_id(struct context *ctx, const struct token *token, 10189 unsigned int ent, char *buf, unsigned int size) 10190 { 10191 unsigned int i = 0; 10192 struct rte_port *port; 10193 struct port_template *pt; 10194 10195 (void)token; 10196 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 10197 ctx->port == (portid_t)RTE_PORT_ALL) 10198 return -1; 10199 port = &ports[ctx->port]; 10200 for (pt = port->pattern_templ_list; pt != NULL; pt = pt->next) { 10201 if (buf && i == ent) 10202 return snprintf(buf, size, "%u", pt->id); 10203 ++i; 10204 } 10205 if (buf) 10206 return -1; 10207 return i; 10208 } 10209 10210 /** Complete available actions template IDs. */ 10211 static int 10212 comp_actions_template_id(struct context *ctx, const struct token *token, 10213 unsigned int ent, char *buf, unsigned int size) 10214 { 10215 unsigned int i = 0; 10216 struct rte_port *port; 10217 struct port_template *pt; 10218 10219 (void)token; 10220 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 10221 ctx->port == (portid_t)RTE_PORT_ALL) 10222 return -1; 10223 port = &ports[ctx->port]; 10224 for (pt = port->actions_templ_list; pt != NULL; pt = pt->next) { 10225 if (buf && i == ent) 10226 return snprintf(buf, size, "%u", pt->id); 10227 ++i; 10228 } 10229 if (buf) 10230 return -1; 10231 return i; 10232 } 10233 10234 /** Complete available table IDs. */ 10235 static int 10236 comp_table_id(struct context *ctx, const struct token *token, 10237 unsigned int ent, char *buf, unsigned int size) 10238 { 10239 unsigned int i = 0; 10240 struct rte_port *port; 10241 struct port_table *pt; 10242 10243 (void)token; 10244 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 10245 ctx->port == (portid_t)RTE_PORT_ALL) 10246 return -1; 10247 port = &ports[ctx->port]; 10248 for (pt = port->table_list; pt != NULL; pt = pt->next) { 10249 if (buf && i == ent) 10250 return snprintf(buf, size, "%u", pt->id); 10251 ++i; 10252 } 10253 if (buf) 10254 return -1; 10255 return i; 10256 } 10257 10258 /** Complete available queue IDs. */ 10259 static int 10260 comp_queue_id(struct context *ctx, const struct token *token, 10261 unsigned int ent, char *buf, unsigned int size) 10262 { 10263 unsigned int i = 0; 10264 struct rte_port *port; 10265 10266 (void)token; 10267 if (port_id_is_invalid(ctx->port, DISABLED_WARN) || 10268 ctx->port == (portid_t)RTE_PORT_ALL) 10269 return -1; 10270 port = &ports[ctx->port]; 10271 for (i = 0; i < port->queue_nb; i++) { 10272 if (buf && i == ent) 10273 return snprintf(buf, size, "%u", i); 10274 } 10275 if (buf) 10276 return -1; 10277 return i; 10278 } 10279 10280 /** Complete available Meter colors. */ 10281 static int 10282 comp_meter_color(struct context *ctx, const struct token *token, 10283 unsigned int ent, char *buf, unsigned int size) 10284 { 10285 RTE_SET_USED(ctx); 10286 RTE_SET_USED(token); 10287 if (!buf) 10288 return RTE_DIM(meter_colors); 10289 if (ent < RTE_DIM(meter_colors) - 1) 10290 return strlcpy(buf, meter_colors[ent], size); 10291 return -1; 10292 } 10293 10294 /** Internal context. */ 10295 static struct context cmd_flow_context; 10296 10297 /** Global parser instance (cmdline API). */ 10298 cmdline_parse_inst_t cmd_flow; 10299 cmdline_parse_inst_t cmd_set_raw; 10300 10301 /** Initialize context. */ 10302 static void 10303 cmd_flow_context_init(struct context *ctx) 10304 { 10305 /* A full memset() is not necessary. */ 10306 ctx->curr = ZERO; 10307 ctx->prev = ZERO; 10308 ctx->next_num = 0; 10309 ctx->args_num = 0; 10310 ctx->eol = 0; 10311 ctx->last = 0; 10312 ctx->port = 0; 10313 ctx->objdata = 0; 10314 ctx->object = NULL; 10315 ctx->objmask = NULL; 10316 } 10317 10318 /** Parse a token (cmdline API). */ 10319 static int 10320 cmd_flow_parse(cmdline_parse_token_hdr_t *hdr, const char *src, void *result, 10321 unsigned int size) 10322 { 10323 struct context *ctx = &cmd_flow_context; 10324 const struct token *token; 10325 const enum index *list; 10326 int len; 10327 int i; 10328 10329 (void)hdr; 10330 token = &token_list[ctx->curr]; 10331 /* Check argument length. */ 10332 ctx->eol = 0; 10333 ctx->last = 1; 10334 for (len = 0; src[len]; ++len) 10335 if (src[len] == '#' || isspace(src[len])) 10336 break; 10337 if (!len) 10338 return -1; 10339 /* Last argument and EOL detection. */ 10340 for (i = len; src[i]; ++i) 10341 if (src[i] == '#' || src[i] == '\r' || src[i] == '\n') 10342 break; 10343 else if (!isspace(src[i])) { 10344 ctx->last = 0; 10345 break; 10346 } 10347 for (; src[i]; ++i) 10348 if (src[i] == '\r' || src[i] == '\n') { 10349 ctx->eol = 1; 10350 break; 10351 } 10352 /* Initialize context if necessary. */ 10353 if (!ctx->next_num) { 10354 if (!token->next) 10355 return 0; 10356 ctx->next[ctx->next_num++] = token->next[0]; 10357 } 10358 /* Process argument through candidates. */ 10359 ctx->prev = ctx->curr; 10360 list = ctx->next[ctx->next_num - 1]; 10361 for (i = 0; list[i]; ++i) { 10362 const struct token *next = &token_list[list[i]]; 10363 int tmp; 10364 10365 ctx->curr = list[i]; 10366 if (next->call) 10367 tmp = next->call(ctx, next, src, len, result, size); 10368 else 10369 tmp = parse_default(ctx, next, src, len, result, size); 10370 if (tmp == -1 || tmp != len) 10371 continue; 10372 token = next; 10373 break; 10374 } 10375 if (!list[i]) 10376 return -1; 10377 --ctx->next_num; 10378 /* Push subsequent tokens if any. */ 10379 if (token->next) 10380 for (i = 0; token->next[i]; ++i) { 10381 if (ctx->next_num == RTE_DIM(ctx->next)) 10382 return -1; 10383 ctx->next[ctx->next_num++] = token->next[i]; 10384 } 10385 /* Push arguments if any. */ 10386 if (token->args) 10387 for (i = 0; token->args[i]; ++i) { 10388 if (ctx->args_num == RTE_DIM(ctx->args)) 10389 return -1; 10390 ctx->args[ctx->args_num++] = token->args[i]; 10391 } 10392 return len; 10393 } 10394 10395 int 10396 flow_parse(const char *src, void *result, unsigned int size, 10397 struct rte_flow_attr **attr, 10398 struct rte_flow_item **pattern, struct rte_flow_action **actions) 10399 { 10400 int ret; 10401 struct context saved_flow_ctx = cmd_flow_context; 10402 10403 cmd_flow_context_init(&cmd_flow_context); 10404 do { 10405 ret = cmd_flow_parse(NULL, src, result, size); 10406 if (ret > 0) { 10407 src += ret; 10408 while (isspace(*src)) 10409 src++; 10410 } 10411 } while (ret > 0 && strlen(src)); 10412 cmd_flow_context = saved_flow_ctx; 10413 *attr = &((struct buffer *)result)->args.vc.attr; 10414 *pattern = ((struct buffer *)result)->args.vc.pattern; 10415 *actions = ((struct buffer *)result)->args.vc.actions; 10416 return (ret >= 0 && !strlen(src)) ? 0 : -1; 10417 } 10418 10419 /** Return number of completion entries (cmdline API). */ 10420 static int 10421 cmd_flow_complete_get_nb(cmdline_parse_token_hdr_t *hdr) 10422 { 10423 struct context *ctx = &cmd_flow_context; 10424 const struct token *token = &token_list[ctx->curr]; 10425 const enum index *list; 10426 int i; 10427 10428 (void)hdr; 10429 /* Count number of tokens in current list. */ 10430 if (ctx->next_num) 10431 list = ctx->next[ctx->next_num - 1]; 10432 else 10433 list = token->next[0]; 10434 for (i = 0; list[i]; ++i) 10435 ; 10436 if (!i) 10437 return 0; 10438 /* 10439 * If there is a single token, use its completion callback, otherwise 10440 * return the number of entries. 10441 */ 10442 token = &token_list[list[0]]; 10443 if (i == 1 && token->comp) { 10444 /* Save index for cmd_flow_get_help(). */ 10445 ctx->prev = list[0]; 10446 return token->comp(ctx, token, 0, NULL, 0); 10447 } 10448 return i; 10449 } 10450 10451 /** Return a completion entry (cmdline API). */ 10452 static int 10453 cmd_flow_complete_get_elt(cmdline_parse_token_hdr_t *hdr, int index, 10454 char *dst, unsigned int size) 10455 { 10456 struct context *ctx = &cmd_flow_context; 10457 const struct token *token = &token_list[ctx->curr]; 10458 const enum index *list; 10459 int i; 10460 10461 (void)hdr; 10462 /* Count number of tokens in current list. */ 10463 if (ctx->next_num) 10464 list = ctx->next[ctx->next_num - 1]; 10465 else 10466 list = token->next[0]; 10467 for (i = 0; list[i]; ++i) 10468 ; 10469 if (!i) 10470 return -1; 10471 /* If there is a single token, use its completion callback. */ 10472 token = &token_list[list[0]]; 10473 if (i == 1 && token->comp) { 10474 /* Save index for cmd_flow_get_help(). */ 10475 ctx->prev = list[0]; 10476 return token->comp(ctx, token, index, dst, size) < 0 ? -1 : 0; 10477 } 10478 /* Otherwise make sure the index is valid and use defaults. */ 10479 if (index >= i) 10480 return -1; 10481 token = &token_list[list[index]]; 10482 strlcpy(dst, token->name, size); 10483 /* Save index for cmd_flow_get_help(). */ 10484 ctx->prev = list[index]; 10485 return 0; 10486 } 10487 10488 /** Populate help strings for current token (cmdline API). */ 10489 static int 10490 cmd_flow_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, unsigned int size) 10491 { 10492 struct context *ctx = &cmd_flow_context; 10493 const struct token *token = &token_list[ctx->prev]; 10494 10495 (void)hdr; 10496 if (!size) 10497 return -1; 10498 /* Set token type and update global help with details. */ 10499 strlcpy(dst, (token->type ? token->type : "TOKEN"), size); 10500 if (token->help) 10501 cmd_flow.help_str = token->help; 10502 else 10503 cmd_flow.help_str = token->name; 10504 return 0; 10505 } 10506 10507 /** Token definition template (cmdline API). */ 10508 static struct cmdline_token_hdr cmd_flow_token_hdr = { 10509 .ops = &(struct cmdline_token_ops){ 10510 .parse = cmd_flow_parse, 10511 .complete_get_nb = cmd_flow_complete_get_nb, 10512 .complete_get_elt = cmd_flow_complete_get_elt, 10513 .get_help = cmd_flow_get_help, 10514 }, 10515 .offset = 0, 10516 }; 10517 10518 /** Populate the next dynamic token. */ 10519 static void 10520 cmd_flow_tok(cmdline_parse_token_hdr_t **hdr, 10521 cmdline_parse_token_hdr_t **hdr_inst) 10522 { 10523 struct context *ctx = &cmd_flow_context; 10524 10525 /* Always reinitialize context before requesting the first token. */ 10526 if (!(hdr_inst - cmd_flow.tokens)) 10527 cmd_flow_context_init(ctx); 10528 /* Return NULL when no more tokens are expected. */ 10529 if (!ctx->next_num && ctx->curr) { 10530 *hdr = NULL; 10531 return; 10532 } 10533 /* Determine if command should end here. */ 10534 if (ctx->eol && ctx->last && ctx->next_num) { 10535 const enum index *list = ctx->next[ctx->next_num - 1]; 10536 int i; 10537 10538 for (i = 0; list[i]; ++i) { 10539 if (list[i] != END) 10540 continue; 10541 *hdr = NULL; 10542 return; 10543 } 10544 } 10545 *hdr = &cmd_flow_token_hdr; 10546 } 10547 10548 /** Dispatch parsed buffer to function calls. */ 10549 static void 10550 cmd_flow_parsed(const struct buffer *in) 10551 { 10552 switch (in->command) { 10553 case INFO: 10554 port_flow_get_info(in->port); 10555 break; 10556 case CONFIGURE: 10557 port_flow_configure(in->port, 10558 &in->args.configure.port_attr, 10559 in->args.configure.nb_queue, 10560 &in->args.configure.queue_attr); 10561 break; 10562 case PATTERN_TEMPLATE_CREATE: 10563 port_flow_pattern_template_create(in->port, 10564 in->args.vc.pat_templ_id, 10565 &((const struct rte_flow_pattern_template_attr) { 10566 .relaxed_matching = in->args.vc.attr.reserved, 10567 .ingress = in->args.vc.attr.ingress, 10568 .egress = in->args.vc.attr.egress, 10569 .transfer = in->args.vc.attr.transfer, 10570 }), 10571 in->args.vc.pattern); 10572 break; 10573 case PATTERN_TEMPLATE_DESTROY: 10574 port_flow_pattern_template_destroy(in->port, 10575 in->args.templ_destroy.template_id_n, 10576 in->args.templ_destroy.template_id); 10577 break; 10578 case ACTIONS_TEMPLATE_CREATE: 10579 port_flow_actions_template_create(in->port, 10580 in->args.vc.act_templ_id, 10581 &((const struct rte_flow_actions_template_attr) { 10582 .ingress = in->args.vc.attr.ingress, 10583 .egress = in->args.vc.attr.egress, 10584 .transfer = in->args.vc.attr.transfer, 10585 }), 10586 in->args.vc.actions, 10587 in->args.vc.masks); 10588 break; 10589 case ACTIONS_TEMPLATE_DESTROY: 10590 port_flow_actions_template_destroy(in->port, 10591 in->args.templ_destroy.template_id_n, 10592 in->args.templ_destroy.template_id); 10593 break; 10594 case TABLE_CREATE: 10595 port_flow_template_table_create(in->port, in->args.table.id, 10596 &in->args.table.attr, in->args.table.pat_templ_id_n, 10597 in->args.table.pat_templ_id, in->args.table.act_templ_id_n, 10598 in->args.table.act_templ_id); 10599 break; 10600 case TABLE_DESTROY: 10601 port_flow_template_table_destroy(in->port, 10602 in->args.table_destroy.table_id_n, 10603 in->args.table_destroy.table_id); 10604 break; 10605 case QUEUE_CREATE: 10606 port_queue_flow_create(in->port, in->queue, in->postpone, 10607 in->args.vc.table_id, in->args.vc.pat_templ_id, 10608 in->args.vc.act_templ_id, in->args.vc.pattern, 10609 in->args.vc.actions); 10610 break; 10611 case QUEUE_DESTROY: 10612 port_queue_flow_destroy(in->port, in->queue, in->postpone, 10613 in->args.destroy.rule_n, 10614 in->args.destroy.rule); 10615 break; 10616 case PUSH: 10617 port_queue_flow_push(in->port, in->queue); 10618 break; 10619 case PULL: 10620 port_queue_flow_pull(in->port, in->queue); 10621 break; 10622 case QUEUE_AGED: 10623 port_queue_flow_aged(in->port, in->queue, 10624 in->args.aged.destroy); 10625 break; 10626 case QUEUE_INDIRECT_ACTION_CREATE: 10627 port_queue_action_handle_create( 10628 in->port, in->queue, in->postpone, 10629 in->args.vc.attr.group, 10630 &((const struct rte_flow_indir_action_conf) { 10631 .ingress = in->args.vc.attr.ingress, 10632 .egress = in->args.vc.attr.egress, 10633 .transfer = in->args.vc.attr.transfer, 10634 }), 10635 in->args.vc.actions); 10636 break; 10637 case QUEUE_INDIRECT_ACTION_DESTROY: 10638 port_queue_action_handle_destroy(in->port, 10639 in->queue, in->postpone, 10640 in->args.ia_destroy.action_id_n, 10641 in->args.ia_destroy.action_id); 10642 break; 10643 case QUEUE_INDIRECT_ACTION_UPDATE: 10644 port_queue_action_handle_update(in->port, 10645 in->queue, in->postpone, 10646 in->args.vc.attr.group, 10647 in->args.vc.actions); 10648 break; 10649 case QUEUE_INDIRECT_ACTION_QUERY: 10650 port_queue_action_handle_query(in->port, 10651 in->queue, in->postpone, 10652 in->args.vc.attr.group); 10653 break; 10654 case INDIRECT_ACTION_CREATE: 10655 port_action_handle_create( 10656 in->port, in->args.vc.attr.group, 10657 &((const struct rte_flow_indir_action_conf) { 10658 .ingress = in->args.vc.attr.ingress, 10659 .egress = in->args.vc.attr.egress, 10660 .transfer = in->args.vc.attr.transfer, 10661 }), 10662 in->args.vc.actions); 10663 break; 10664 case INDIRECT_ACTION_DESTROY: 10665 port_action_handle_destroy(in->port, 10666 in->args.ia_destroy.action_id_n, 10667 in->args.ia_destroy.action_id); 10668 break; 10669 case INDIRECT_ACTION_UPDATE: 10670 port_action_handle_update(in->port, in->args.vc.attr.group, 10671 in->args.vc.actions); 10672 break; 10673 case INDIRECT_ACTION_QUERY: 10674 port_action_handle_query(in->port, in->args.ia.action_id); 10675 break; 10676 case VALIDATE: 10677 port_flow_validate(in->port, &in->args.vc.attr, 10678 in->args.vc.pattern, in->args.vc.actions, 10679 &in->args.vc.tunnel_ops); 10680 break; 10681 case CREATE: 10682 port_flow_create(in->port, &in->args.vc.attr, 10683 in->args.vc.pattern, in->args.vc.actions, 10684 &in->args.vc.tunnel_ops); 10685 break; 10686 case DESTROY: 10687 port_flow_destroy(in->port, in->args.destroy.rule_n, 10688 in->args.destroy.rule); 10689 break; 10690 case FLUSH: 10691 port_flow_flush(in->port); 10692 break; 10693 case DUMP_ONE: 10694 case DUMP_ALL: 10695 port_flow_dump(in->port, in->args.dump.mode, 10696 in->args.dump.rule, in->args.dump.file); 10697 break; 10698 case QUERY: 10699 port_flow_query(in->port, in->args.query.rule, 10700 &in->args.query.action); 10701 break; 10702 case LIST: 10703 port_flow_list(in->port, in->args.list.group_n, 10704 in->args.list.group); 10705 break; 10706 case ISOLATE: 10707 port_flow_isolate(in->port, in->args.isolate.set); 10708 break; 10709 case AGED: 10710 port_flow_aged(in->port, in->args.aged.destroy); 10711 break; 10712 case TUNNEL_CREATE: 10713 port_flow_tunnel_create(in->port, &in->args.vc.tunnel_ops); 10714 break; 10715 case TUNNEL_DESTROY: 10716 port_flow_tunnel_destroy(in->port, in->args.vc.tunnel_ops.id); 10717 break; 10718 case TUNNEL_LIST: 10719 port_flow_tunnel_list(in->port); 10720 break; 10721 case ACTION_POL_G: 10722 port_meter_policy_add(in->port, in->args.policy.policy_id, 10723 in->args.vc.actions); 10724 break; 10725 case FLEX_ITEM_CREATE: 10726 flex_item_create(in->port, in->args.flex.token, 10727 in->args.flex.filename); 10728 break; 10729 case FLEX_ITEM_DESTROY: 10730 flex_item_destroy(in->port, in->args.flex.token); 10731 break; 10732 default: 10733 break; 10734 } 10735 } 10736 10737 /** Token generator and output processing callback (cmdline API). */ 10738 static void 10739 cmd_flow_cb(void *arg0, struct cmdline *cl, void *arg2) 10740 { 10741 if (cl == NULL) 10742 cmd_flow_tok(arg0, arg2); 10743 else 10744 cmd_flow_parsed(arg0); 10745 } 10746 10747 /** Global parser instance (cmdline API). */ 10748 cmdline_parse_inst_t cmd_flow = { 10749 .f = cmd_flow_cb, 10750 .data = NULL, /**< Unused. */ 10751 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 10752 .tokens = { 10753 NULL, 10754 }, /**< Tokens are returned by cmd_flow_tok(). */ 10755 }; 10756 10757 /** set cmd facility. Reuse cmd flow's infrastructure as much as possible. */ 10758 10759 static void 10760 update_fields(uint8_t *buf, struct rte_flow_item *item, uint16_t next_proto) 10761 { 10762 struct rte_ipv4_hdr *ipv4; 10763 struct rte_ether_hdr *eth; 10764 struct rte_ipv6_hdr *ipv6; 10765 struct rte_vxlan_hdr *vxlan; 10766 struct rte_vxlan_gpe_hdr *gpe; 10767 struct rte_flow_item_nvgre *nvgre; 10768 uint32_t ipv6_vtc_flow; 10769 10770 switch (item->type) { 10771 case RTE_FLOW_ITEM_TYPE_ETH: 10772 eth = (struct rte_ether_hdr *)buf; 10773 if (next_proto) 10774 eth->ether_type = rte_cpu_to_be_16(next_proto); 10775 break; 10776 case RTE_FLOW_ITEM_TYPE_IPV4: 10777 ipv4 = (struct rte_ipv4_hdr *)buf; 10778 if (!ipv4->version_ihl) 10779 ipv4->version_ihl = RTE_IPV4_VHL_DEF; 10780 if (next_proto && ipv4->next_proto_id == 0) 10781 ipv4->next_proto_id = (uint8_t)next_proto; 10782 break; 10783 case RTE_FLOW_ITEM_TYPE_IPV6: 10784 ipv6 = (struct rte_ipv6_hdr *)buf; 10785 if (next_proto && ipv6->proto == 0) 10786 ipv6->proto = (uint8_t)next_proto; 10787 ipv6_vtc_flow = rte_be_to_cpu_32(ipv6->vtc_flow); 10788 ipv6_vtc_flow &= 0x0FFFFFFF; /*< reset version bits. */ 10789 ipv6_vtc_flow |= 0x60000000; /*< set ipv6 version. */ 10790 ipv6->vtc_flow = rte_cpu_to_be_32(ipv6_vtc_flow); 10791 break; 10792 case RTE_FLOW_ITEM_TYPE_VXLAN: 10793 vxlan = (struct rte_vxlan_hdr *)buf; 10794 vxlan->vx_flags = 0x08; 10795 break; 10796 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 10797 gpe = (struct rte_vxlan_gpe_hdr *)buf; 10798 gpe->vx_flags = 0x0C; 10799 break; 10800 case RTE_FLOW_ITEM_TYPE_NVGRE: 10801 nvgre = (struct rte_flow_item_nvgre *)buf; 10802 nvgre->protocol = rte_cpu_to_be_16(0x6558); 10803 nvgre->c_k_s_rsvd0_ver = rte_cpu_to_be_16(0x2000); 10804 break; 10805 default: 10806 break; 10807 } 10808 } 10809 10810 /** Helper of get item's default mask. */ 10811 static const void * 10812 flow_item_default_mask(const struct rte_flow_item *item) 10813 { 10814 const void *mask = NULL; 10815 static rte_be32_t gre_key_default_mask = RTE_BE32(UINT32_MAX); 10816 10817 switch (item->type) { 10818 case RTE_FLOW_ITEM_TYPE_ANY: 10819 mask = &rte_flow_item_any_mask; 10820 break; 10821 case RTE_FLOW_ITEM_TYPE_PORT_ID: 10822 mask = &rte_flow_item_port_id_mask; 10823 break; 10824 case RTE_FLOW_ITEM_TYPE_RAW: 10825 mask = &rte_flow_item_raw_mask; 10826 break; 10827 case RTE_FLOW_ITEM_TYPE_ETH: 10828 mask = &rte_flow_item_eth_mask; 10829 break; 10830 case RTE_FLOW_ITEM_TYPE_VLAN: 10831 mask = &rte_flow_item_vlan_mask; 10832 break; 10833 case RTE_FLOW_ITEM_TYPE_IPV4: 10834 mask = &rte_flow_item_ipv4_mask; 10835 break; 10836 case RTE_FLOW_ITEM_TYPE_IPV6: 10837 mask = &rte_flow_item_ipv6_mask; 10838 break; 10839 case RTE_FLOW_ITEM_TYPE_ICMP: 10840 mask = &rte_flow_item_icmp_mask; 10841 break; 10842 case RTE_FLOW_ITEM_TYPE_UDP: 10843 mask = &rte_flow_item_udp_mask; 10844 break; 10845 case RTE_FLOW_ITEM_TYPE_TCP: 10846 mask = &rte_flow_item_tcp_mask; 10847 break; 10848 case RTE_FLOW_ITEM_TYPE_SCTP: 10849 mask = &rte_flow_item_sctp_mask; 10850 break; 10851 case RTE_FLOW_ITEM_TYPE_VXLAN: 10852 mask = &rte_flow_item_vxlan_mask; 10853 break; 10854 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 10855 mask = &rte_flow_item_vxlan_gpe_mask; 10856 break; 10857 case RTE_FLOW_ITEM_TYPE_E_TAG: 10858 mask = &rte_flow_item_e_tag_mask; 10859 break; 10860 case RTE_FLOW_ITEM_TYPE_NVGRE: 10861 mask = &rte_flow_item_nvgre_mask; 10862 break; 10863 case RTE_FLOW_ITEM_TYPE_MPLS: 10864 mask = &rte_flow_item_mpls_mask; 10865 break; 10866 case RTE_FLOW_ITEM_TYPE_GRE: 10867 mask = &rte_flow_item_gre_mask; 10868 break; 10869 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 10870 mask = &gre_key_default_mask; 10871 break; 10872 case RTE_FLOW_ITEM_TYPE_META: 10873 mask = &rte_flow_item_meta_mask; 10874 break; 10875 case RTE_FLOW_ITEM_TYPE_FUZZY: 10876 mask = &rte_flow_item_fuzzy_mask; 10877 break; 10878 case RTE_FLOW_ITEM_TYPE_GTP: 10879 mask = &rte_flow_item_gtp_mask; 10880 break; 10881 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 10882 mask = &rte_flow_item_gtp_psc_mask; 10883 break; 10884 case RTE_FLOW_ITEM_TYPE_GENEVE: 10885 mask = &rte_flow_item_geneve_mask; 10886 break; 10887 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 10888 mask = &rte_flow_item_geneve_opt_mask; 10889 break; 10890 case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: 10891 mask = &rte_flow_item_pppoe_proto_id_mask; 10892 break; 10893 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 10894 mask = &rte_flow_item_l2tpv3oip_mask; 10895 break; 10896 case RTE_FLOW_ITEM_TYPE_ESP: 10897 mask = &rte_flow_item_esp_mask; 10898 break; 10899 case RTE_FLOW_ITEM_TYPE_AH: 10900 mask = &rte_flow_item_ah_mask; 10901 break; 10902 case RTE_FLOW_ITEM_TYPE_PFCP: 10903 mask = &rte_flow_item_pfcp_mask; 10904 break; 10905 case RTE_FLOW_ITEM_TYPE_PORT_REPRESENTOR: 10906 case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT: 10907 mask = &rte_flow_item_ethdev_mask; 10908 break; 10909 case RTE_FLOW_ITEM_TYPE_L2TPV2: 10910 mask = &rte_flow_item_l2tpv2_mask; 10911 break; 10912 case RTE_FLOW_ITEM_TYPE_PPP: 10913 mask = &rte_flow_item_ppp_mask; 10914 break; 10915 case RTE_FLOW_ITEM_TYPE_METER_COLOR: 10916 mask = &rte_flow_item_meter_color_mask; 10917 break; 10918 default: 10919 break; 10920 } 10921 return mask; 10922 } 10923 10924 /** Dispatch parsed buffer to function calls. */ 10925 static void 10926 cmd_set_raw_parsed_sample(const struct buffer *in) 10927 { 10928 uint32_t n = in->args.vc.actions_n; 10929 uint32_t i = 0; 10930 struct rte_flow_action *action = NULL; 10931 struct rte_flow_action *data = NULL; 10932 const struct rte_flow_action_rss *rss = NULL; 10933 size_t size = 0; 10934 uint16_t idx = in->port; /* We borrow port field as index */ 10935 uint32_t max_size = sizeof(struct rte_flow_action) * 10936 ACTION_SAMPLE_ACTIONS_NUM; 10937 10938 RTE_ASSERT(in->command == SET_SAMPLE_ACTIONS); 10939 data = (struct rte_flow_action *)&raw_sample_confs[idx].data; 10940 memset(data, 0x00, max_size); 10941 for (; i <= n - 1; i++) { 10942 action = in->args.vc.actions + i; 10943 if (action->type == RTE_FLOW_ACTION_TYPE_END) 10944 break; 10945 switch (action->type) { 10946 case RTE_FLOW_ACTION_TYPE_MARK: 10947 size = sizeof(struct rte_flow_action_mark); 10948 rte_memcpy(&sample_mark[idx], 10949 (const void *)action->conf, size); 10950 action->conf = &sample_mark[idx]; 10951 break; 10952 case RTE_FLOW_ACTION_TYPE_COUNT: 10953 size = sizeof(struct rte_flow_action_count); 10954 rte_memcpy(&sample_count[idx], 10955 (const void *)action->conf, size); 10956 action->conf = &sample_count[idx]; 10957 break; 10958 case RTE_FLOW_ACTION_TYPE_QUEUE: 10959 size = sizeof(struct rte_flow_action_queue); 10960 rte_memcpy(&sample_queue[idx], 10961 (const void *)action->conf, size); 10962 action->conf = &sample_queue[idx]; 10963 break; 10964 case RTE_FLOW_ACTION_TYPE_RSS: 10965 size = sizeof(struct rte_flow_action_rss); 10966 rss = action->conf; 10967 rte_memcpy(&sample_rss_data[idx].conf, 10968 (const void *)rss, size); 10969 if (rss->key_len && rss->key) { 10970 sample_rss_data[idx].conf.key = 10971 sample_rss_data[idx].key; 10972 rte_memcpy((void *)((uintptr_t) 10973 sample_rss_data[idx].conf.key), 10974 (const void *)rss->key, 10975 sizeof(uint8_t) * rss->key_len); 10976 } 10977 if (rss->queue_num && rss->queue) { 10978 sample_rss_data[idx].conf.queue = 10979 sample_rss_data[idx].queue; 10980 rte_memcpy((void *)((uintptr_t) 10981 sample_rss_data[idx].conf.queue), 10982 (const void *)rss->queue, 10983 sizeof(uint16_t) * rss->queue_num); 10984 } 10985 action->conf = &sample_rss_data[idx].conf; 10986 break; 10987 case RTE_FLOW_ACTION_TYPE_RAW_ENCAP: 10988 size = sizeof(struct rte_flow_action_raw_encap); 10989 rte_memcpy(&sample_encap[idx], 10990 (const void *)action->conf, size); 10991 action->conf = &sample_encap[idx]; 10992 break; 10993 case RTE_FLOW_ACTION_TYPE_PORT_ID: 10994 size = sizeof(struct rte_flow_action_port_id); 10995 rte_memcpy(&sample_port_id[idx], 10996 (const void *)action->conf, size); 10997 action->conf = &sample_port_id[idx]; 10998 break; 10999 case RTE_FLOW_ACTION_TYPE_PF: 11000 break; 11001 case RTE_FLOW_ACTION_TYPE_VF: 11002 size = sizeof(struct rte_flow_action_vf); 11003 rte_memcpy(&sample_vf[idx], 11004 (const void *)action->conf, size); 11005 action->conf = &sample_vf[idx]; 11006 break; 11007 case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: 11008 size = sizeof(struct rte_flow_action_vxlan_encap); 11009 parse_setup_vxlan_encap_data(&sample_vxlan_encap[idx]); 11010 action->conf = &sample_vxlan_encap[idx].conf; 11011 break; 11012 case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: 11013 size = sizeof(struct rte_flow_action_nvgre_encap); 11014 parse_setup_nvgre_encap_data(&sample_nvgre_encap[idx]); 11015 action->conf = &sample_nvgre_encap[idx]; 11016 break; 11017 case RTE_FLOW_ACTION_TYPE_PORT_REPRESENTOR: 11018 size = sizeof(struct rte_flow_action_ethdev); 11019 rte_memcpy(&sample_port_representor[idx], 11020 (const void *)action->conf, size); 11021 action->conf = &sample_port_representor[idx]; 11022 break; 11023 case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT: 11024 size = sizeof(struct rte_flow_action_ethdev); 11025 rte_memcpy(&sample_represented_port[idx], 11026 (const void *)action->conf, size); 11027 action->conf = &sample_represented_port[idx]; 11028 break; 11029 default: 11030 fprintf(stderr, "Error - Not supported action\n"); 11031 return; 11032 } 11033 rte_memcpy(data, action, sizeof(struct rte_flow_action)); 11034 data++; 11035 } 11036 } 11037 11038 /** Dispatch parsed buffer to function calls. */ 11039 static void 11040 cmd_set_raw_parsed(const struct buffer *in) 11041 { 11042 uint32_t n = in->args.vc.pattern_n; 11043 int i = 0; 11044 struct rte_flow_item *item = NULL; 11045 size_t size = 0; 11046 uint8_t *data = NULL; 11047 uint8_t *data_tail = NULL; 11048 size_t *total_size = NULL; 11049 uint16_t upper_layer = 0; 11050 uint16_t proto = 0; 11051 uint16_t idx = in->port; /* We borrow port field as index */ 11052 int gtp_psc = -1; /* GTP PSC option index. */ 11053 11054 if (in->command == SET_SAMPLE_ACTIONS) 11055 return cmd_set_raw_parsed_sample(in); 11056 RTE_ASSERT(in->command == SET_RAW_ENCAP || 11057 in->command == SET_RAW_DECAP); 11058 if (in->command == SET_RAW_ENCAP) { 11059 total_size = &raw_encap_confs[idx].size; 11060 data = (uint8_t *)&raw_encap_confs[idx].data; 11061 } else { 11062 total_size = &raw_decap_confs[idx].size; 11063 data = (uint8_t *)&raw_decap_confs[idx].data; 11064 } 11065 *total_size = 0; 11066 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 11067 /* process hdr from upper layer to low layer (L3/L4 -> L2). */ 11068 data_tail = data + ACTION_RAW_ENCAP_MAX_DATA; 11069 for (i = n - 1 ; i >= 0; --i) { 11070 const struct rte_flow_item_gtp *gtp; 11071 const struct rte_flow_item_geneve_opt *opt; 11072 11073 item = in->args.vc.pattern + i; 11074 if (item->spec == NULL) 11075 item->spec = flow_item_default_mask(item); 11076 switch (item->type) { 11077 case RTE_FLOW_ITEM_TYPE_ETH: 11078 size = sizeof(struct rte_ether_hdr); 11079 break; 11080 case RTE_FLOW_ITEM_TYPE_VLAN: 11081 size = sizeof(struct rte_vlan_hdr); 11082 proto = RTE_ETHER_TYPE_VLAN; 11083 break; 11084 case RTE_FLOW_ITEM_TYPE_IPV4: 11085 size = sizeof(struct rte_ipv4_hdr); 11086 proto = RTE_ETHER_TYPE_IPV4; 11087 break; 11088 case RTE_FLOW_ITEM_TYPE_IPV6: 11089 size = sizeof(struct rte_ipv6_hdr); 11090 proto = RTE_ETHER_TYPE_IPV6; 11091 break; 11092 case RTE_FLOW_ITEM_TYPE_UDP: 11093 size = sizeof(struct rte_udp_hdr); 11094 proto = 0x11; 11095 break; 11096 case RTE_FLOW_ITEM_TYPE_TCP: 11097 size = sizeof(struct rte_tcp_hdr); 11098 proto = 0x06; 11099 break; 11100 case RTE_FLOW_ITEM_TYPE_VXLAN: 11101 size = sizeof(struct rte_vxlan_hdr); 11102 break; 11103 case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: 11104 size = sizeof(struct rte_vxlan_gpe_hdr); 11105 break; 11106 case RTE_FLOW_ITEM_TYPE_GRE: 11107 size = sizeof(struct rte_gre_hdr); 11108 proto = 0x2F; 11109 break; 11110 case RTE_FLOW_ITEM_TYPE_GRE_KEY: 11111 size = sizeof(rte_be32_t); 11112 proto = 0x0; 11113 break; 11114 case RTE_FLOW_ITEM_TYPE_MPLS: 11115 size = sizeof(struct rte_mpls_hdr); 11116 proto = 0x0; 11117 break; 11118 case RTE_FLOW_ITEM_TYPE_NVGRE: 11119 size = sizeof(struct rte_flow_item_nvgre); 11120 proto = 0x2F; 11121 break; 11122 case RTE_FLOW_ITEM_TYPE_GENEVE: 11123 size = sizeof(struct rte_geneve_hdr); 11124 break; 11125 case RTE_FLOW_ITEM_TYPE_GENEVE_OPT: 11126 opt = (const struct rte_flow_item_geneve_opt *) 11127 item->spec; 11128 size = offsetof(struct rte_flow_item_geneve_opt, 11129 option_len) + sizeof(uint8_t); 11130 if (opt->option_len && opt->data) { 11131 *total_size += opt->option_len * 11132 sizeof(uint32_t); 11133 rte_memcpy(data_tail - (*total_size), 11134 opt->data, 11135 opt->option_len * sizeof(uint32_t)); 11136 } 11137 break; 11138 case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: 11139 size = sizeof(rte_be32_t); 11140 proto = 0x73; 11141 break; 11142 case RTE_FLOW_ITEM_TYPE_ESP: 11143 size = sizeof(struct rte_esp_hdr); 11144 proto = 0x32; 11145 break; 11146 case RTE_FLOW_ITEM_TYPE_AH: 11147 size = sizeof(struct rte_flow_item_ah); 11148 proto = 0x33; 11149 break; 11150 case RTE_FLOW_ITEM_TYPE_GTP: 11151 if (gtp_psc < 0) { 11152 size = sizeof(struct rte_gtp_hdr); 11153 break; 11154 } 11155 if (gtp_psc != i + 1) { 11156 fprintf(stderr, 11157 "Error - GTP PSC does not follow GTP\n"); 11158 goto error; 11159 } 11160 gtp = item->spec; 11161 if ((gtp->v_pt_rsv_flags & 0x07) != 0x04) { 11162 /* Only E flag should be set. */ 11163 fprintf(stderr, 11164 "Error - GTP unsupported flags\n"); 11165 goto error; 11166 } else { 11167 struct rte_gtp_hdr_ext_word ext_word = { 11168 .next_ext = 0x85 11169 }; 11170 11171 /* We have to add GTP header extra word. */ 11172 *total_size += sizeof(ext_word); 11173 rte_memcpy(data_tail - (*total_size), 11174 &ext_word, sizeof(ext_word)); 11175 } 11176 size = sizeof(struct rte_gtp_hdr); 11177 break; 11178 case RTE_FLOW_ITEM_TYPE_GTP_PSC: 11179 if (gtp_psc >= 0) { 11180 fprintf(stderr, 11181 "Error - Multiple GTP PSC items\n"); 11182 goto error; 11183 } else { 11184 const struct rte_flow_item_gtp_psc 11185 *opt = item->spec; 11186 struct rte_gtp_psc_generic_hdr *hdr; 11187 size_t hdr_size = RTE_ALIGN(sizeof(*hdr), 11188 sizeof(int32_t)); 11189 11190 *total_size += hdr_size; 11191 hdr = (typeof(hdr))(data_tail - (*total_size)); 11192 memset(hdr, 0, hdr_size); 11193 *hdr = opt->hdr; 11194 hdr->ext_hdr_len = 1; 11195 gtp_psc = i; 11196 size = 0; 11197 } 11198 break; 11199 case RTE_FLOW_ITEM_TYPE_PFCP: 11200 size = sizeof(struct rte_flow_item_pfcp); 11201 break; 11202 case RTE_FLOW_ITEM_TYPE_FLEX: 11203 size = item->spec ? 11204 ((const struct rte_flow_item_flex *) 11205 item->spec)->length : 0; 11206 break; 11207 case RTE_FLOW_ITEM_TYPE_GRE_OPTION: 11208 size = 0; 11209 if (item->spec) { 11210 const struct rte_flow_item_gre_opt 11211 *opt = item->spec; 11212 if (opt->checksum_rsvd.checksum) { 11213 *total_size += 11214 sizeof(opt->checksum_rsvd); 11215 rte_memcpy(data_tail - (*total_size), 11216 &opt->checksum_rsvd, 11217 sizeof(opt->checksum_rsvd)); 11218 } 11219 if (opt->key.key) { 11220 *total_size += sizeof(opt->key.key); 11221 rte_memcpy(data_tail - (*total_size), 11222 &opt->key.key, 11223 sizeof(opt->key.key)); 11224 } 11225 if (opt->sequence.sequence) { 11226 *total_size += sizeof(opt->sequence.sequence); 11227 rte_memcpy(data_tail - (*total_size), 11228 &opt->sequence.sequence, 11229 sizeof(opt->sequence.sequence)); 11230 } 11231 } 11232 proto = 0x2F; 11233 break; 11234 default: 11235 fprintf(stderr, "Error - Not supported item\n"); 11236 goto error; 11237 } 11238 *total_size += size; 11239 rte_memcpy(data_tail - (*total_size), item->spec, size); 11240 /* update some fields which cannot be set by cmdline */ 11241 update_fields((data_tail - (*total_size)), item, 11242 upper_layer); 11243 upper_layer = proto; 11244 } 11245 if (verbose_level & 0x1) 11246 printf("total data size is %zu\n", (*total_size)); 11247 RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA); 11248 memmove(data, (data_tail - (*total_size)), *total_size); 11249 return; 11250 11251 error: 11252 *total_size = 0; 11253 memset(data, 0x00, ACTION_RAW_ENCAP_MAX_DATA); 11254 } 11255 11256 /** Populate help strings for current token (cmdline API). */ 11257 static int 11258 cmd_set_raw_get_help(cmdline_parse_token_hdr_t *hdr, char *dst, 11259 unsigned int size) 11260 { 11261 struct context *ctx = &cmd_flow_context; 11262 const struct token *token = &token_list[ctx->prev]; 11263 11264 (void)hdr; 11265 if (!size) 11266 return -1; 11267 /* Set token type and update global help with details. */ 11268 snprintf(dst, size, "%s", (token->type ? token->type : "TOKEN")); 11269 if (token->help) 11270 cmd_set_raw.help_str = token->help; 11271 else 11272 cmd_set_raw.help_str = token->name; 11273 return 0; 11274 } 11275 11276 /** Token definition template (cmdline API). */ 11277 static struct cmdline_token_hdr cmd_set_raw_token_hdr = { 11278 .ops = &(struct cmdline_token_ops){ 11279 .parse = cmd_flow_parse, 11280 .complete_get_nb = cmd_flow_complete_get_nb, 11281 .complete_get_elt = cmd_flow_complete_get_elt, 11282 .get_help = cmd_set_raw_get_help, 11283 }, 11284 .offset = 0, 11285 }; 11286 11287 /** Populate the next dynamic token. */ 11288 static void 11289 cmd_set_raw_tok(cmdline_parse_token_hdr_t **hdr, 11290 cmdline_parse_token_hdr_t **hdr_inst) 11291 { 11292 struct context *ctx = &cmd_flow_context; 11293 11294 /* Always reinitialize context before requesting the first token. */ 11295 if (!(hdr_inst - cmd_set_raw.tokens)) { 11296 cmd_flow_context_init(ctx); 11297 ctx->curr = START_SET; 11298 } 11299 /* Return NULL when no more tokens are expected. */ 11300 if (!ctx->next_num && (ctx->curr != START_SET)) { 11301 *hdr = NULL; 11302 return; 11303 } 11304 /* Determine if command should end here. */ 11305 if (ctx->eol && ctx->last && ctx->next_num) { 11306 const enum index *list = ctx->next[ctx->next_num - 1]; 11307 int i; 11308 11309 for (i = 0; list[i]; ++i) { 11310 if (list[i] != END) 11311 continue; 11312 *hdr = NULL; 11313 return; 11314 } 11315 } 11316 *hdr = &cmd_set_raw_token_hdr; 11317 } 11318 11319 /** Token generator and output processing callback (cmdline API). */ 11320 static void 11321 cmd_set_raw_cb(void *arg0, struct cmdline *cl, void *arg2) 11322 { 11323 if (cl == NULL) 11324 cmd_set_raw_tok(arg0, arg2); 11325 else 11326 cmd_set_raw_parsed(arg0); 11327 } 11328 11329 /** Global parser instance (cmdline API). */ 11330 cmdline_parse_inst_t cmd_set_raw = { 11331 .f = cmd_set_raw_cb, 11332 .data = NULL, /**< Unused. */ 11333 .help_str = NULL, /**< Updated by cmd_flow_get_help(). */ 11334 .tokens = { 11335 NULL, 11336 }, /**< Tokens are returned by cmd_flow_tok(). */ 11337 }; 11338 11339 /* *** display raw_encap/raw_decap buf */ 11340 struct cmd_show_set_raw_result { 11341 cmdline_fixed_string_t cmd_show; 11342 cmdline_fixed_string_t cmd_what; 11343 cmdline_fixed_string_t cmd_all; 11344 uint16_t cmd_index; 11345 }; 11346 11347 static void 11348 cmd_show_set_raw_parsed(void *parsed_result, struct cmdline *cl, void *data) 11349 { 11350 struct cmd_show_set_raw_result *res = parsed_result; 11351 uint16_t index = res->cmd_index; 11352 uint8_t all = 0; 11353 uint8_t *raw_data = NULL; 11354 size_t raw_size = 0; 11355 char title[16] = {0}; 11356 11357 RTE_SET_USED(cl); 11358 RTE_SET_USED(data); 11359 if (!strcmp(res->cmd_all, "all")) { 11360 all = 1; 11361 index = 0; 11362 } else if (index >= RAW_ENCAP_CONFS_MAX_NUM) { 11363 fprintf(stderr, "index should be 0-%u\n", 11364 RAW_ENCAP_CONFS_MAX_NUM - 1); 11365 return; 11366 } 11367 do { 11368 if (!strcmp(res->cmd_what, "raw_encap")) { 11369 raw_data = (uint8_t *)&raw_encap_confs[index].data; 11370 raw_size = raw_encap_confs[index].size; 11371 snprintf(title, 16, "\nindex: %u", index); 11372 rte_hexdump(stdout, title, raw_data, raw_size); 11373 } else { 11374 raw_data = (uint8_t *)&raw_decap_confs[index].data; 11375 raw_size = raw_decap_confs[index].size; 11376 snprintf(title, 16, "\nindex: %u", index); 11377 rte_hexdump(stdout, title, raw_data, raw_size); 11378 } 11379 } while (all && ++index < RAW_ENCAP_CONFS_MAX_NUM); 11380 } 11381 11382 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_show = 11383 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 11384 cmd_show, "show"); 11385 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_what = 11386 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 11387 cmd_what, "raw_encap#raw_decap"); 11388 static cmdline_parse_token_num_t cmd_show_set_raw_cmd_index = 11389 TOKEN_NUM_INITIALIZER(struct cmd_show_set_raw_result, 11390 cmd_index, RTE_UINT16); 11391 static cmdline_parse_token_string_t cmd_show_set_raw_cmd_all = 11392 TOKEN_STRING_INITIALIZER(struct cmd_show_set_raw_result, 11393 cmd_all, "all"); 11394 cmdline_parse_inst_t cmd_show_set_raw = { 11395 .f = cmd_show_set_raw_parsed, 11396 .data = NULL, 11397 .help_str = "show <raw_encap|raw_decap> <index>", 11398 .tokens = { 11399 (void *)&cmd_show_set_raw_cmd_show, 11400 (void *)&cmd_show_set_raw_cmd_what, 11401 (void *)&cmd_show_set_raw_cmd_index, 11402 NULL, 11403 }, 11404 }; 11405 cmdline_parse_inst_t cmd_show_set_raw_all = { 11406 .f = cmd_show_set_raw_parsed, 11407 .data = NULL, 11408 .help_str = "show <raw_encap|raw_decap> all", 11409 .tokens = { 11410 (void *)&cmd_show_set_raw_cmd_show, 11411 (void *)&cmd_show_set_raw_cmd_what, 11412 (void *)&cmd_show_set_raw_cmd_all, 11413 NULL, 11414 }, 11415 }; 11416