From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3D635A0525 for ; Tue, 18 Feb 2020 07:37:32 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 327BB288C; Tue, 18 Feb 2020 07:37:32 +0100 (CET) Received: from dish-sg.nttdocomo.co.jp (dish-sg.nttdocomo.co.jp [202.19.227.74]) by dpdk.org (Postfix) with ESMTP id 466011DA23 for ; Tue, 18 Feb 2020 07:37:30 +0100 (CET) X-dD-Source: Outbound Received: from zssg-mailmd102.ddreams.local (zssg-mailmd900.ddreams.local [10.160.172.63]) by zssg-mailou103.ddreams.local (Postfix) with ESMTP id 8503D12012C; Tue, 18 Feb 2020 15:37:29 +0900 (JST) Received: from zssg-mailmf104.ddreams.local (zssg-mailmf900.ddreams.local [10.160.172.84]) by zssg-mailmd102.ddreams.local (dDREAMS) with ESMTP id <0Q5V014Y7X2HK5A0@dDREAMS>; Tue, 18 Feb 2020 15:37:29 +0900 (JST) Received: from zssg-mailmf104.ddreams.local (unknown [127.0.0.1]) by zssg-mailmf104.ddreams.local (Postfix) with ESMTP id 5C2597E6038; Tue, 18 Feb 2020 15:37:29 +0900 (JST) Received: from zssg-mailmf104.ddreams.local (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5A68E8E605A; Tue, 18 Feb 2020 15:37:29 +0900 (JST) Received: from localhost (unknown [127.0.0.1]) by IMSVA (Postfix) with SMTP id 4F57B8E605D; Tue, 18 Feb 2020 15:37:29 +0900 (JST) X-IMSS-HAND-OFF-DIRECTIVE: localhost:10026 Received: from zssg-mailmf104.ddreams.local (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C82128E605D; Tue, 18 Feb 2020 15:37:28 +0900 (JST) Received: from davinci.ntt-tx.co.jp (unknown [10.160.183.139]) by zssg-mailmf104.ddreams.local (Postfix) with ESMTP; Tue, 18 Feb 2020 15:37:28 +0900 (JST) From: x-fn-spp-ml@ntt-tx.co.jp To: ferruh.yigit@intel.com, yasufum.o@gmail.com Cc: spp@dpdk.org Date: Tue, 18 Feb 2020 15:37:10 +0900 Message-id: <20200218063720.6597-8-x-fn-spp-ml@ntt-tx.co.jp> X-Mailer: git-send-email 2.18.0 In-reply-to: <20200218063720.6597-1-x-fn-spp-ml@ntt-tx.co.jp> References: <20200218063720.6597-1-x-fn-spp-ml@ntt-tx.co.jp> X-TM-AS-GCONF: 00 Subject: [spp] [PATCH 07/17] spp_primary: add common function of rte_flow X-BeenThere: spp@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Soft Patch Panel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: spp-bounces@dpdk.org Sender: "spp" From: Hideyuki Yamashita To support rte_flow in SPP, this patch provides parse functions those are commonly used by primary application. Signed-off-by: Hideyuki Yamashita Signed-off-by: Yasufumi Ogawa --- src/primary/flow/common.c | 646 ++++++++++++++++++++++++++++++++++++++ src/primary/flow/common.h | 53 ++++ src/primary/main.c | 48 +-- 3 files changed, 725 insertions(+), 22 deletions(-) create mode 100644 src/primary/flow/common.c create mode 100644 src/primary/flow/common.h diff --git a/src/primary/flow/common.c b/src/primary/flow/common.c new file mode 100644 index 0000000..da34619 --- /dev/null +++ b/src/primary/flow/common.c @@ -0,0 +1,646 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation + */ + +#include + +#include "shared/secondary/spp_worker_th/data_types.h" +#include "shared/secondary/utils.h" +#include "flow.h" +#include "common.h" + +/* + * Check if port_id is used + * Return 0: Port_id used + * Return 1: Unused port_id + */ +int +is_portid_used(int port_id) +{ + uint16_t pid; + + RTE_ETH_FOREACH_DEV(pid) { + if (port_id == pid) + return 0; + } + + return 1; +} + +/* + * Retrieve port ID from source UID of phy port. Return error code if port + * type is other than phy. + */ +int +parse_phy_port_id(char *res_uid, int *port_id) +{ + int ret; + char *port_type; + uint16_t queue_id; + + if (res_uid == NULL) { + RTE_LOG(ERR, SPP_FLOW, + "RES UID is NULL(%s:%d)\n", __func__, __LINE__); + return -1; + } + + ret = parse_resource_uid(res_uid, &port_type, port_id, &queue_id); + if (ret < 0) { + RTE_LOG(ERR, SPP_FLOW, + "Failed to parse RES UID(%s:%d)\n", + __func__, __LINE__); + return -1; + } + + if (strcmp(port_type, SPPWK_PHY_STR) != 0) { + RTE_LOG(ERR, SPP_FLOW, + "It's not phy type(%s:%d)\n", __func__, __LINE__); + return -1; + } + return 0; +} + +/* + * Convert string to rte_ether_addr. + * This function is intended to be called as a function pointer to + * 'parse_detail' in 'struct flow_detail_ops'. + */ +int +str_to_rte_ether_addr(char *mac_str, void *output) +{ + int i = 0; + uint8_t byte; + char *end, *token; + char tmp_mac_str[32] = { 0 }; + struct rte_ether_addr *mac_addr = output; + + strncpy(tmp_mac_str, mac_str, 32); + token = strtok(tmp_mac_str, ":"); + + while (token != NULL) { + if (i >= RTE_ETHER_ADDR_LEN) + return -1; + + byte = (uint8_t)strtoul(token, &end, 16); + if (end == NULL || *end != '\0') + return -1; + + mac_addr->addr_bytes[i] = byte; + i++; + token = strtok(NULL, ":"); + } + + return 0; +} + +/* + * Convert string to tci. + * This function is intended to be called as a function pointer to + * 'parse_detail' in 'struct flow_detail_ops'. + */ +int +str_to_tci(char *tci_str, void *output) +{ + char *end; + rte_be16_t *tci = output; + + *tci = (rte_be16_t)strtoul(tci_str, &end, 0); + if (end == NULL || *end != '\0') + return -1; + + return 0; +} + +/* + * Convert string to pcp. + * This function is intended to be called as a function pointer to + * 'parse_detail' in 'struct flow_detail_ops'. + */ +int +str_to_pcp(char *pcp_str, void *output) +{ + char *end; + uint8_t *pcp = output; + + *pcp = (uint8_t)strtoul(pcp_str, &end, 0); + if (end == NULL || *end != '\0') + return -1; + + /* 3bit check */ + if (*pcp > 0x7) + return -1; + + return 0; +} + +/* + * Set PCP in TCI. TCI is a 16bits value and consists of 3bits PCP, + * 1bit DEI and the rest 12bits VID. + * This function is intended to be called as a function pointer to + * 'parse_detail' in 'struct flow_detail_ops'. + */ +int +set_pcp_in_tci(char *pcp_str, void *output) +{ + int ret; + uint8_t pcp = 0; + rte_be16_t *tci = output; + + ret = str_to_pcp(pcp_str, &pcp); + if (ret != 0) + return -1; + + /* Assign to the first 3 bits */ + pcp = pcp << 1; + ((char *)tci)[0] = ((char *)tci)[0] | pcp; + + return 0; +} + +/* + * Set DEI in TCI. TCI is a 16bits value and consists of 3bits PCP, + * 1bit DEI and the rest 12bits VID. + * This function is intended to be called as a function pointer to + * 'parse_detail' in 'struct flow_detail_ops'. + */ +int +set_dei_in_tci(char *dei_str, void *output) +{ + char *end; + uint8_t dei = 0; + rte_be16_t *tci = output; + + dei = (uint8_t)strtoul(dei_str, &end, 0); + if (end == NULL || *end != '\0') + return -1; + + /* 1bit check */ + if (dei > 0x1) + return -1; + + /* Assign to 4th bit */ + ((char *)tci)[0] = ((char *)tci)[0] | dei; + + return 0; +} + +/* + * Set VID in TCI. TCI is a 16bits value and consists of 3bits PCP, + * 1bit DEI and the rest 12bits VID. + * This function is intended to be called as a function pointer to + * 'parse_detail' in 'struct flow_detail_ops'. + */ +int +set_vid_in_tci(char *vid_str, void *output) +{ + char *end; + rte_be16_t vid = 0; + rte_be16_t *tci = output; + + vid = (rte_be16_t)strtoul(vid_str, &end, 0); + if (end == NULL || *end != '\0') + return -1; + + /* 12bit check */ + if (vid > 0x0fff) + return -1; + + /* Convert vid to big endian if system is little endian. */ + int i = 1; + if (*(char *)&i) { /* check if little endian */ + uint8_t b1 = ((char *)&vid)[0]; + uint8_t b2 = ((char *)&vid)[1]; + ((char *)&vid)[0] = b2; + ((char *)&vid)[1] = b1; + } + + /* Assign to 5-16 bit */ + *tci = *tci | vid; + + return 0; +} + +/* + * Convert string to rte_be16_t. + * This function is intended to be called as a function pointer to + * 'parse_detail' in 'struct flow_detail_ops'. + */ +int +str_to_rte_be16_t(char *target_str, void *output) +{ + char *end; + rte_be16_t *value = output; + + *value = (rte_be16_t)strtoul(target_str, &end, 0); + if (end == NULL || *end != '\0') + return -1; + /* Convert vid to big endian if system is little endian. */ + int i = 1; + if (*(char *)&i) { /* check if little endian */ + uint8_t b1 = ((char *)value)[0]; + uint8_t b2 = ((char *)value)[1]; + ((char *)value)[0] = b2; + ((char *)value)[1] = b1; + } + + return 0; +} + +/* + * Convert string to uint16_t. + * This function is intended to be called as a function pointer to + * 'parse_detail' in 'struct flow_detail_ops'. + */ +int +str_to_uint16_t(char *target_str, void *output) +{ + char *end; + uint16_t *value = output; + + *value = (uint16_t)strtoul(target_str, &end, 0); + if (end == NULL || *end != '\0') + return -1; + + return 0; +} + +/* + * Convert string to uint32_t. + * This function is intended to be called as a function pointer to + * 'parse_detail' in 'struct flow_detail_ops'. + */ +int +str_to_uint32_t(char *target_str, void *output) +{ + char *end; + uint32_t *value = output; + + *value = (uint32_t)strtoul(target_str, &end, 0); + if (end == NULL || *end != '\0') + return -1; + + return 0; +} + +int +parse_rte_flow_item_field(char *token_list[], int *index, + struct flow_detail_ops *detail_list, size_t size, + void **spec, void **last, void **mask + ) +{ + int ret = 0; + uint32_t prefix, i, j, bitmask; + char *end, *target; + + if (!strcmp(token_list[*index], "is")) { + /* Match value perfectly (with full bit-mask). */ + (*index)++; + + if (*spec == NULL) { + ret = malloc_object(spec, size); + if (ret != 0) { + RTE_LOG(ERR, SPP_FLOW, + "Failed to alloc memory (%s:%d)\n", + __func__, __LINE__); + return -1; + } + } + + ret = detail_list->parse_detail(token_list[*index], + (char *)(*spec) + detail_list->offset); + if (ret != 0) { + RTE_LOG(ERR, SPP_FLOW, + "parse_detail error (%s:%d)\n", + __func__, __LINE__); + return -1; + } + + /* Set full bit-mask */ + if (*mask == NULL) { + ret = malloc_object(mask, size); + if (ret != 0) { + RTE_LOG(ERR, SPP_FLOW, + "Failed to alloc memory (%s:%d)\n", + __func__, __LINE__); + return -1; + } + } + + memset((char *)(*mask) + detail_list->offset, 0xff, + detail_list->size); + + } else if (!strcmp(token_list[*index], "spec")) { + /* Match value according to configured bit-mask. */ + (*index)++; + + if (*spec == NULL) { + ret = malloc_object(spec, size); + if (ret != 0) { + RTE_LOG(ERR, SPP_FLOW, + "Failed to alloc memory (%s:%d)\n", + __func__, __LINE__); + return -1; + } + } + + ret = detail_list->parse_detail(token_list[*index], + (char *)(*spec) + detail_list->offset); + if (ret != 0) { + RTE_LOG(ERR, SPP_FLOW, + "parse_detail error (%s:%d)\n", + __func__, __LINE__); + return -1; + } + + } else if (!strcmp(token_list[*index], "last")) { + /* Specify upper bound to establish a range. */ + (*index)++; + + if (*last == NULL) { + ret = malloc_object(last, size); + if (ret != 0) { + RTE_LOG(ERR, SPP_FLOW, + "Failed to alloc memory (%s:%d)\n", + __func__, __LINE__); + return -1; + } + } + + ret = detail_list->parse_detail(token_list[*index], + (char *)(*last) + detail_list->offset); + if (ret != 0) { + RTE_LOG(ERR, SPP_FLOW, + "parse_detail error (%s:%d)\n", + __func__, __LINE__); + return -1; + } + + } else if (!strcmp(token_list[*index], "mask")) { + /* Specify bit-mask with relevant bits set to one. */ + (*index)++; + + if (*mask == NULL) { + ret = malloc_object(mask, size); + if (ret != 0) { + RTE_LOG(ERR, SPP_FLOW, + "Failed to alloc memory (%s:%d)\n", + __func__, __LINE__); + return -1; + } + } + + ret = detail_list->parse_detail(token_list[*index], + (char *)(*mask) + detail_list->offset); + if (ret != 0) { + RTE_LOG(ERR, SPP_FLOW, + "parse_detail error (%s:%d)\n", + __func__, __LINE__); + return -1; + } + + } else if (!strcmp(token_list[*index], "prefix")) { + /* + * generate bit-mask with + * most-significant bits set to one. + */ + (*index)++; + + if (*mask == NULL) { + ret = malloc_object(mask, size); + if (ret != 0) { + RTE_LOG(ERR, SPP_FLOW, + "Failed to alloc memory (%s:%d)\n", + __func__, __LINE__); + return -1; + } + } + + prefix = strtoul(token_list[*index], &end, 10); + if (end == NULL || *end != '\0') { + RTE_LOG(ERR, SPP_FLOW, + "Prefix is not a number(%s:%d)\n", + __func__, __LINE__); + return -1; + } + + /* Compare prefix (bit) and size (byte). */ + if (prefix > detail_list->size * 8) { + RTE_LOG(ERR, SPP_FLOW, + "Prefix value is too large(%s:%d)\n", + __func__, __LINE__); + return -1; + } + + target = (char *)(*mask) + detail_list->offset; + memset(target, 0, detail_list->size); + for (i = 0; i < detail_list->size; i++) { + if (prefix <= 0) + break; + + bitmask = 0x80; + + for (j = 0; j < 8; j++) { + if (prefix <= 0) + break; + + target[i] = target[i] | bitmask; + bitmask = bitmask >> 1; + prefix--; + } + } + + } else { + RTE_LOG(ERR, SPP_FLOW, + "Invalid parameter is %s(%s:%d)\n", + token_list[*index], __func__, __LINE__); + return -1; + } + + return 0; +} + +int +parse_item_common(char *token_list[], int *index, + struct rte_flow_item *item, + struct flow_item_ops *ops) +{ + int ret = 0; + int i = 0; + //void *spec, *last, *mask; + void *spec = NULL, *last = NULL, *mask = NULL; + struct flow_detail_ops *detail_list = ops->detail_list; + + /* Next to pattern word */ + (*index)++; + + while (token_list[*index] != NULL) { + + /* Exit if "/" */ + if (!strcmp(token_list[*index], "/")) + break; + + /* First is value type */ + i = 0; + while (detail_list[i].token != NULL) { + if (!strcmp(token_list[*index], + detail_list[i].token)) { + break; + } + + i++; + } + if (detail_list[i].token == NULL) { + RTE_LOG(ERR, SPP_FLOW, + "Invalid \"%s\" pattern arguments(%s:%d)\n", + ops->str_type, __func__, __LINE__); + ret = -1; + break; + } + + /* Parse token value */ + if (detail_list[i].flg_value == 1) { + (*index)++; + + ret = parse_rte_flow_item_field(token_list, index, + &detail_list[i], ops->size, + &spec, &last, &mask); + if (ret != 0) { + RTE_LOG(ERR, SPP_FLOW, + "Invalid \"%s\" pattern arguments" + "(%s:%d)\n", + ops->str_type, __func__, __LINE__); + ret = -1; + break; + } + } + + (*index)++; + } + + /* Free memory allocated in case of failure. */ + if (ret != 0) { + if (spec != NULL) + free(spec); + + if (last != NULL) + free(last); + + if (mask != NULL) + free(mask); + } + + /* Parse result to item. */ + item->spec = spec; + item->last = last; + item->mask = mask; + + return ret; +} + +int +parse_action_common(char *token_list[], int *index, + struct rte_flow_action *action, + struct flow_action_ops *ops) +{ + int ret = 0; + int i = 0; + struct rte_flow_action_queue *conf; + struct flow_detail_ops *detail_list = ops->detail_list; + + conf = malloc(ops->size); + if (conf == NULL) { + RTE_LOG(ERR, SPP_FLOW, + "Memory allocation failure(%s:%d)\n", + __func__, __LINE__); + return -1; + } + memset(conf, 0, ops->size); + + /* Next to word */ + (*index)++; + + while (token_list[*index] != NULL) { + + /* Exit if "/" */ + if (!strcmp(token_list[*index], "/")) + break; + + /* First is value type */ + i = 0; + while (detail_list[i].token != NULL) { + if (!strcmp(token_list[*index], + detail_list[i].token)) { + break; + } + + i++; + } + if (detail_list[i].token == NULL) { + RTE_LOG(ERR, SPP_FLOW, + "Invalid \"%s\" pattern arguments(%s:%d)\n", + ops->str_type, __func__, __LINE__); + ret = -1; + break; + } + + /* Parse token value */ + if (detail_list[i].flg_value == 1) { + (*index)++; + + ret = detail_list[i].parse_detail( + token_list[*index], + (char *)conf + detail_list[i].offset); + if (ret != 0) { + RTE_LOG(ERR, SPP_FLOW, + "Invalid \"%s\" pattern arguments" + "(%s:%d)\n", + detail_list[i].token, + __func__, __LINE__); + ret = -1; + break; + } + } + + (*index)++; + } + + /* Free memory allocated in case of failure. */ + if ((ret != 0) && (conf != NULL)) + free(conf); + + /* Parse result to action. */ + action->conf = conf; + + return ret; +} + +/* Append action json, conf field is null */ +int +append_action_null_json(const void *conf __attribute__ ((unused)), + int buf_size, char *action_str) +{ + char null_str[] = "null"; + + if ((int)strlen(action_str) + (int)strlen(null_str) + > buf_size) + return -1; + + strncat(action_str, null_str, strlen(null_str)); + + return 0; +} + +int +malloc_object(void **ptr, size_t size) +{ + *ptr = malloc(size); + if (*ptr == NULL) { + RTE_LOG(ERR, SPP_FLOW, + "Memory allocation failure(%s:%d)\n", + __func__, __LINE__); + return -1; + } + + memset(*ptr, 0, size); + return 0; +} diff --git a/src/primary/flow/common.h b/src/primary/flow/common.h new file mode 100644 index 0000000..998fd12 --- /dev/null +++ b/src/primary/flow/common.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019 Nippon Telegraph and Telephone Corporation + */ + +#ifndef _PRIMARY_FLOW_COMMON_H_ +#define _PRIMARY_FLOW_COMMON_H_ + +int is_portid_used(int port_id); + +/* Function for flow command parse */ +int parse_phy_port_id(char *res_uid, int *port_id); + +/* Functions for converting string to data */ +int str_to_rte_ether_addr(char *mac_str, void *output); +int str_to_tci(char *tci_str, void *output); +int str_to_pcp(char *pcp_str, void *output); +int str_to_rte_be16_t(char *target_str, void *output); +int str_to_uint16_t(char *target_str, void *output); +int str_to_uint32_t(char *target_str, void *output); + +/* Functions for setting string to data */ +int set_pcp_in_tci(char *pcp_str, void *output); +int set_dei_in_tci(char *dei_str, void *output); +int set_vid_in_tci(char *vid_str, void *output); + +/* Parse rte_flow_item for each field */ +int parse_rte_flow_item_field(char *token_list[], int *index, + struct flow_detail_ops *detail_list, size_t size, + void **spec, void **last, void **mask); + +/* + * Common parse for item type. Perform detailed parse with + * flow_detail_ops according to type. + */ +int parse_item_common(char *token_list[], int *index, + struct rte_flow_item *item, + struct flow_item_ops *ops); + +/* + * Common parse for action type. Perform detailed parse with + * flow_detail_ops according to type. + */ +int parse_action_common(char *token_list[], int *index, + struct rte_flow_action *action, + struct flow_action_ops *ops); + +/* Append action json, conf field is null */ +int append_action_null_json(const void *conf, int buf_size, char *action_str); + +/* Allocate memory for the size */ +int malloc_object(void **ptr, size_t size); + +#endif diff --git a/src/primary/main.c b/src/primary/main.c index ca81636..4ef9cb1 100644 --- a/src/primary/main.c +++ b/src/primary/main.c @@ -395,9 +395,7 @@ append_lcore_info_json(char *str, /* TODO(yasufum): change to use shared */ static int -append_port_info_json(char *str, - struct port *ports_fwd_array, - struct port_map *port_map) +append_port_info_json(char *str) { unsigned int i; unsigned int has_port = 0; // for checking having port at last @@ -405,7 +403,7 @@ append_port_info_json(char *str, sprintf(str + strlen(str), "\"ports\":["); for (i = 0; i < RTE_MAX_ETHPORTS; i++) { - if (ports_fwd_array[i].in_port_id == PORT_RESET) + if (ports_fwd_array[i][0].in_port_id == PORT_RESET) continue; has_port = 1; @@ -457,9 +455,7 @@ append_port_info_json(char *str, /* TODO(yasufum): change to use shared */ static int -append_patch_info_json(char *str, - struct port *ports_fwd_array, - struct port_map *port_map) +append_patch_info_json(char *str) { unsigned int i; unsigned int has_patch = 0; // for checking having patch at last @@ -468,12 +464,12 @@ append_patch_info_json(char *str, sprintf(str + strlen(str), "\"patches\":["); for (i = 0; i < RTE_MAX_ETHPORTS; i++) { - if (ports_fwd_array[i].in_port_id == PORT_RESET) + if (ports_fwd_array[i][0].in_port_id == PORT_RESET) continue; RTE_LOG(INFO, PRIMARY, "Port ID %d\n", i); RTE_LOG(INFO, PRIMARY, "Status %d\n", - ports_fwd_array[i].in_port_id); + ports_fwd_array[i][0].in_port_id); memset(patch_str, '\0', sizeof(patch_str)); @@ -533,14 +529,14 @@ append_patch_info_json(char *str, sprintf(patch_str + strlen(patch_str), "\"dst\":"); RTE_LOG(INFO, PRIMARY, "Out Port ID %d\n", - ports_fwd_array[i].out_port_id); + ports_fwd_array[i][0].out_port_id); - if (ports_fwd_array[i].out_port_id == PORT_RESET) { + if (ports_fwd_array[i][0].out_port_id == PORT_RESET) { //sprintf(patch_str + strlen(patch_str), "%s", "\"\""); continue; } else { has_patch = 1; - unsigned int j = ports_fwd_array[i].out_port_id; + unsigned int j = ports_fwd_array[i][0].out_port_id; switch (port_map[j].port_type) { case PHY: RTE_LOG(INFO, PRIMARY, "Type: PHY\n"); @@ -629,8 +625,8 @@ forwarder_status_json(char *str) else sprintf(buf_running + strlen(buf_running), "\"%s\"", "idling"); - append_port_info_json(buf_ports, ports_fwd_array, port_map); - append_patch_info_json(buf_patches, ports_fwd_array, port_map); + append_port_info_json(buf_ports); + append_patch_info_json(buf_patches); sprintf(str, "\"forwarder\":{%s,%s,%s}", buf_running, buf_ports, buf_patches); @@ -871,7 +867,7 @@ add_port(char *p_type, int p_id) */ /* Update ports_fwd_array with port id */ - ports_fwd_array[port_id].in_port_id = port_id; + ports_fwd_array[port_id][0].in_port_id = port_id; return 0; } @@ -942,7 +938,7 @@ del_port(char *p_type, int p_id) port_id_list[dev_id].port_id = PORT_RESET; port_id_list[dev_id].type = UNDEF; - forward_array_remove(dev_id); + forward_array_remove(dev_id, 0); port_map_init_one(dev_id); return 0; @@ -964,6 +960,7 @@ parse_command(char *str) char *p_type; int p_id; char tmp_response[MSG_SIZE]; + uint16_t queue_id; memset(sec_name, '\0', 16); memset(tmp_response, '\0', MSG_SIZE); @@ -1033,7 +1030,8 @@ parse_command(char *str) RTE_LOG(DEBUG, PRIMARY, "'%s' command received.\n", token_list[0]); - ret = parse_resource_uid(token_list[1], &p_type, &p_id); + ret = parse_resource_uid(token_list[1], &p_type, &p_id, + &queue_id); if (ret < 0) { RTE_LOG(ERR, PRIMARY, "Failed to parse RES UID.\n"); return ret; @@ -1055,7 +1053,8 @@ parse_command(char *str) } else if (!strcmp(token_list[0], "del")) { RTE_LOG(DEBUG, PRIMARY, "Received del command\n"); - ret = parse_resource_uid(token_list[1], &p_type, &p_id); + ret = parse_resource_uid(token_list[1], &p_type, &p_id, + &queue_id); if (ret < 0) { RTE_LOG(ERR, PRIMARY, "Failed to parse RES UID.\n"); return ret; @@ -1094,13 +1093,15 @@ parse_command(char *str) char *out_p_type; int in_p_id; int out_p_id; + uint16_t in_queue_id, out_queue_id; - parse_resource_uid(token_list[1], &in_p_type, &in_p_id); + parse_resource_uid(token_list[1], &in_p_type, &in_p_id, + &in_queue_id); in_port = find_port_id(in_p_id, get_port_type(in_p_type)); parse_resource_uid(token_list[2], - &out_p_type, &out_p_id); + &out_p_type, &out_p_id, &out_queue_id); out_port = find_port_id(out_p_id, get_port_type(out_p_type)); @@ -1128,7 +1129,8 @@ parse_command(char *str) RTE_LOG(ERR, PRIMARY, "%s\n", err_msg); } - if (add_patch(in_port, out_port) == 0) { + if (add_patch(in_port, in_queue_id, out_port, + out_queue_id) == 0) { RTE_LOG(INFO, PRIMARY, "Patched '%s:%d' and '%s:%d'\n", in_p_type, in_p_id, @@ -1323,10 +1325,12 @@ main(int argc, char *argv[]) } /* Update ports_fwd_array with phy port. */ - ports_fwd_array[i].in_port_id = i; + ports_fwd_array[i][0].in_port_id = i; + ports_fwd_array[i][0].in_queue_id = 0; port_map[i].port_type = port_type; port_map[i].id = port_id; port_map[i].stats = &ports->port_stats[i]; + port_map[i].queue_info = NULL; /* TODO(yasufum) convert type of port_type to char */ RTE_LOG(DEBUG, PRIMARY, "Add port, type: %d, id: %d\n", -- 2.17.1