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