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