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