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