From patchwork Fri Jun 30 16:51:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ferruh Yigit X-Patchwork-Id: 26129 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 305DC7CEC; Fri, 30 Jun 2017 18:52:46 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 42B1C235 for ; Fri, 30 Jun 2017 18:52:10 +0200 (CEST) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 30 Jun 2017 09:52:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.40,287,1496127600"; d="scan'208";a="103233362" Received: from silpixa00372839.ir.intel.com (HELO silpixa00372839.ger.corp.intel.com) ([10.237.222.154]) by orsmga004.jf.intel.com with ESMTP; 30 Jun 2017 09:52:08 -0700 From: Ferruh Yigit To: dev@dpdk.org Cc: Ferruh Yigit , Stephen Hemminger , Bruce Richardson , Anatoly Burakov Date: Fri, 30 Jun 2017 17:51:37 +0100 Message-Id: <20170630165140.59594-18-ferruh.yigit@intel.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170630165140.59594-1-ferruh.yigit@intel.com> References: <20170621110651.75299-1-ferruh.yigit@intel.com> <20170630165140.59594-1-ferruh.yigit@intel.com> Subject: [dpdk-dev] [PATCH v9 17/20] ctrl_if: process control messages X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Receive the requests from virtual interface and process control messages. Signed-off-by: Ferruh Yigit --- lib/librte_ctrl_if/Makefile | 1 + lib/librte_ctrl_if/rte_ctrl_process.c | 167 ++++++++++++++++++++++++++++++++++ lib/librte_ctrl_if/rte_ctrl_process.h | 50 ++++++++++ lib/librte_ctrl_if/rte_nl.c | 130 ++++++++++++++++++++++++++ 4 files changed, 348 insertions(+) create mode 100644 lib/librte_ctrl_if/rte_ctrl_process.c create mode 100644 lib/librte_ctrl_if/rte_ctrl_process.h diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile index 0da04f7d0..67b9967b4 100644 --- a/lib/librte_ctrl_if/Makefile +++ b/lib/librte_ctrl_if/Makefile @@ -46,6 +46,7 @@ LIBABIVER := 1 SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) := rte_ctrl_if.c SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += rte_nl.c +SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += rte_ctrl_process.c # # Export include files diff --git a/lib/librte_ctrl_if/rte_ctrl_process.c b/lib/librte_ctrl_if/rte_ctrl_process.c new file mode 100644 index 000000000..cfb243f64 --- /dev/null +++ b/lib/librte_ctrl_if/rte_ctrl_process.c @@ -0,0 +1,167 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include + +#include +#include +#include "rte_ctrl_process.h" + +static int +set_mtu(uint8_t port_id, void *in_data) +{ + int *mtu = in_data; + + return rte_eth_dev_set_mtu(port_id, *mtu); +} + +static int +get_stats(uint8_t port_id, void *data, size_t *data_len) +{ + struct rte_eth_stats stats; + struct rtnl_link_stats64 *if_stats = data; + int ret; + + ret = rte_eth_stats_get(port_id, &stats); + if (ret < 0) + return -EOPNOTSUPP; + + if_stats->rx_packets = stats.ipackets; + if_stats->tx_packets = stats.opackets; + if_stats->rx_bytes = stats.ibytes; + if_stats->tx_bytes = stats.obytes; + if_stats->rx_errors = stats.ierrors; + if_stats->tx_errors = stats.oerrors; + if_stats->rx_dropped = stats.imissed; + + *data_len = sizeof(struct rtnl_link_stats64); + + return 0; +} + +static int +get_mac(uint8_t port_id, void *data, size_t *data_len) +{ + struct ether_addr addr; + + rte_eth_macaddr_get(port_id, &addr); + memcpy(data, &addr, sizeof(struct ether_addr)); + + *data_len = sizeof(struct ether_addr); + + return 0; +} + +static int +set_mac(uint8_t port_id, void *in_data) +{ + struct ether_addr addr; + + memcpy(&addr, in_data, ETHER_ADDR_LEN); + + return rte_eth_dev_default_mac_addr_set(port_id, &addr); +} + +static int +start_port(uint8_t port_id) +{ + rte_eth_dev_stop(port_id); + return rte_eth_dev_start(port_id); +} + +static int +stop_port(uint8_t port_id) +{ + rte_eth_dev_stop(port_id); + return 0; +} + +static int +set_promisc(uint8_t port_id, void *in_data) +{ + int *promisc = in_data; + + if (*promisc) + rte_eth_promiscuous_enable(port_id); + else + rte_eth_promiscuous_disable(port_id); + + return 0; +} + +static int +set_allmulti(uint8_t port_id, void *in_data) +{ + int *allmulti = in_data; + + if (*allmulti) + rte_eth_allmulticast_enable(port_id); + else + rte_eth_allmulticast_disable(port_id); + + return 0; +} + +int +rte_eth_dev_control_process(uint32_t cmd_id, uint8_t port_id, void *in_data, + void *out_data, size_t *out_data_len) +{ + if (!rte_eth_dev_is_valid_port(port_id)) + return -ENODEV; + + switch (cmd_id) { + case UNCI_REQ_CHANGE_MTU: + return set_mtu(port_id, in_data); + case UNCI_REQ_GET_STATS: + return get_stats(port_id, out_data, out_data_len); + case UNCI_REQ_GET_MAC: + return get_mac(port_id, out_data, out_data_len); + case UNCI_REQ_SET_MAC: + return set_mac(port_id, in_data); + case UNCI_REQ_START_PORT: + return start_port(port_id); + case UNCI_REQ_STOP_PORT: + return stop_port(port_id); + case UNCI_REQ_SET_PROMISC: + return set_promisc(port_id, in_data); + case UNCI_REQ_SET_ALLMULTI: + return set_allmulti(port_id, in_data); + default: + return -EOPNOTSUPP; + } + + return 0; +} diff --git a/lib/librte_ctrl_if/rte_ctrl_process.h b/lib/librte_ctrl_if/rte_ctrl_process.h new file mode 100644 index 000000000..f67c60107 --- /dev/null +++ b/lib/librte_ctrl_if/rte_ctrl_process.h @@ -0,0 +1,50 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTE_CTRL_ETHTOOL_H_ +#define _RTE_CTRL_ETHTOOL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +int rte_eth_dev_control_process(uint32_t cmd_id, uint8_t port_id, void *in_data, + void *out_data, size_t *out_data_len); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_CTRL_ETHTOOL_H_ */ diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c index e88b3fc91..920d123a9 100644 --- a/lib/librte_ctrl_if/rte_nl.c +++ b/lib/librte_ctrl_if/rte_nl.c @@ -39,6 +39,7 @@ #include #include +#include "rte_ctrl_process.h" #include "rte_nl.h" #include "rte_ctrl_if.h" @@ -54,12 +55,139 @@ struct ctrl_if_nl { struct sockaddr_nl dest_addr; }; +struct ctrl_if_msg_sync { + struct unci_nl_msg msg_storage; + pthread_mutex_t msg_lock; + uint32_t pending_process; +}; + + +/** + * Flags values for rte_eth_control_interface_process_msg() API + */ +enum control_interface_process_flag { + /**< Process if msg available. */ + RTE_ETHTOOL_CTRL_IF_PROCESS_MSG, + + /**< Discard msg if available, respond with a error value. */ + RTE_ETHTOOL_CTRL_IF_DISCARD_MSG, +}; + static int sock_fd = -1; static pthread_t thread_id; static struct ctrl_if_nl nl_s; static struct ctrl_if_nl nl_r; +static struct ctrl_if_msg_sync ctrl_if_sync = { + .msg_lock = PTHREAD_MUTEX_INITIALIZER, +}; + +static int +nl_send(void *buf, size_t len) +{ + int ret; + + if (nl_s.nlh.nlmsg_len < len) { + RTE_LOG(ERR, CTRL_IF, "Message is too big, len:%zu\n", len); + return -1; + } + + if (!NLMSG_OK(&nl_s.nlh, NLMSG_SPACE(MAX_PAYLOAD))) { + RTE_LOG(ERR, CTRL_IF, "Message is not OK\n"); + return -1; + } + + /* Fill in the netlink message payload */ + memcpy(NLMSG_DATA(nl_s.nlmsg), buf, len); + + ret = sendmsg(sock_fd, &nl_s.msg, 0); + + if (ret < 0) + RTE_LOG(ERR, CTRL_IF, "Failed nl msg send. ret:%d, err:%d\n", + ret, errno); + return ret; +} + +/* each request sent expects a reply */ +static int +nl_reply(struct unci_nl_msg *msg) +{ + return nl_send((void *)msg, sizeof(struct unci_nl_msg)); +} + +static void +process_msg(struct unci_nl_msg *msg) +{ + if (msg->cmd_id > UNCI_REQ_UNKNOWN) { + msg->err = rte_eth_dev_control_process(msg->cmd_id, + msg->port_id, msg->input_buffer, + msg->output_buffer, &msg->output_buffer_len); + } + + if (msg->err) + memset(msg->output_buffer, 0, msg->output_buffer_len); + + nl_reply(msg); +} + +static int +control_interface_msg_process(uint32_t flag) +{ + struct unci_nl_msg msg_storage; + int ret = 0; + + pthread_mutex_lock(&ctrl_if_sync.msg_lock); + if (ctrl_if_sync.pending_process == 0) { + pthread_mutex_unlock(&ctrl_if_sync.msg_lock); + return 0; + } + + memcpy(&msg_storage, &ctrl_if_sync.msg_storage, + sizeof(struct unci_nl_msg)); + ctrl_if_sync.pending_process = 0; + pthread_mutex_unlock(&ctrl_if_sync.msg_lock); + + switch (flag) { + case RTE_ETHTOOL_CTRL_IF_PROCESS_MSG: + process_msg(&msg_storage); + break; + + case RTE_ETHTOOL_CTRL_IF_DISCARD_MSG: + msg_storage.err = -1; + nl_reply(&msg_storage); + break; + + default: + ret = -1; + break; + } + + return ret; +} + +static int +msg_add_and_process(struct nlmsghdr *nlh) +{ + pthread_mutex_lock(&ctrl_if_sync.msg_lock); + + if (ctrl_if_sync.pending_process) { + pthread_mutex_unlock(&ctrl_if_sync.msg_lock); + return -1; + } + + memcpy(&ctrl_if_sync.msg_storage, NLMSG_DATA(nlh), + sizeof(struct unci_nl_msg)); + ctrl_if_sync.msg_storage.flag = UNCI_MSG_FLAG_RESPONSE; + ctrl_if_sync.pending_process = 1; + + pthread_mutex_unlock(&ctrl_if_sync.msg_lock); + + control_interface_msg_process(RTE_ETHTOOL_CTRL_IF_PROCESS_MSG); + + return 0; +} + static void * nl_recv(void *arg) { @@ -76,6 +204,8 @@ nl_recv(void *arg) ret, sizeof(struct unci_nl_msg)); continue; } + + msg_add_and_process(&nl_r.nlh); } return arg;