From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id C8C0A8E8D for ; Fri, 15 Jan 2016 17:18:14 +0100 (CET) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga101.fm.intel.com with ESMTP; 15 Jan 2016 08:18:13 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,300,1449561600"; d="scan'208";a="727759718" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga003.jf.intel.com with ESMTP; 15 Jan 2016 08:18:11 -0800 Received: from sivswdev02.ir.intel.com (sivswdev02.ir.intel.com [10.237.217.46]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id u0FGIA81024914; Fri, 15 Jan 2016 16:18:10 GMT Received: from sivswdev02.ir.intel.com (localhost [127.0.0.1]) by sivswdev02.ir.intel.com with ESMTP id u0FGIAAF012937; Fri, 15 Jan 2016 16:18:10 GMT Received: (from fyigit@localhost) by sivswdev02.ir.intel.com with id u0FGIAEu012933; Fri, 15 Jan 2016 16:18:10 GMT From: Ferruh Yigit To: dev@dpdk.org Date: Fri, 15 Jan 2016 16:18:02 +0000 Message-Id: <1452874684-12750-2-git-send-email-ferruh.yigit@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1452874684-12750-1-git-send-email-ferruh.yigit@intel.com> References: <1452874684-12750-1-git-send-email-ferruh.yigit@intel.com> Subject: [dpdk-dev] [RFC 1/3] rte_ctrl_if: add control interface library X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jan 2016 16:18:15 -0000 This library gets control messages form kernelspace and forwards them to librte_ether and returns response back to the kernelspace. Library does: 1) Trigger Linux virtual interface creation 2) Initialize the netlink socket communication 3) Provides process() API to the application that does processing the received messages This library requires corresponding kernel module to be inserted. Signed-off-by: Ferruh Yigit --- config/common_linuxapp | 7 +- lib/Makefile | 3 +- lib/librte_ctrl_if/Makefile | 58 +++++ lib/librte_ctrl_if/rte_ctrl_if.c | 166 ++++++++++++++ lib/librte_ctrl_if/rte_ctrl_if.h | 54 +++++ lib/librte_ctrl_if/rte_ctrl_if_version.map | 9 + lib/librte_ctrl_if/rte_ethtool.c | 354 +++++++++++++++++++++++++++++ lib/librte_ctrl_if/rte_ethtool.h | 64 ++++++ lib/librte_ctrl_if/rte_nl.c | 274 ++++++++++++++++++++++ lib/librte_ctrl_if/rte_nl.h | 60 +++++ lib/librte_eal/common/include/rte_log.h | 3 +- mk/rte.app.mk | 3 +- 12 files changed, 1051 insertions(+), 4 deletions(-) create mode 100644 lib/librte_ctrl_if/Makefile create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.c create mode 100644 lib/librte_ctrl_if/rte_ctrl_if.h create mode 100644 lib/librte_ctrl_if/rte_ctrl_if_version.map create mode 100644 lib/librte_ctrl_if/rte_ethtool.c create mode 100644 lib/librte_ctrl_if/rte_ethtool.h create mode 100644 lib/librte_ctrl_if/rte_nl.c create mode 100644 lib/librte_ctrl_if/rte_nl.h diff --git a/config/common_linuxapp b/config/common_linuxapp index 74bc515..de705d0 100644 --- a/config/common_linuxapp +++ b/config/common_linuxapp @@ -1,6 +1,6 @@ # BSD LICENSE # -# Copyright(c) 2010-2015 Intel Corporation. All rights reserved. +# Copyright(c) 2010-2016 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -503,6 +503,11 @@ CONFIG_RTE_KNI_VHOST_DEBUG_RX=n CONFIG_RTE_KNI_VHOST_DEBUG_TX=n # +# Compile librte_ctrl_if +# +CONFIG_RTE_LIBRTE_CTRL_IF=y + +# # Compile vhost library # fuse-devel is needed to run vhost-cuse. # fuse-devel enables user space char driver development diff --git a/lib/Makefile b/lib/Makefile index ef172ea..a50bc1e 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,6 +1,6 @@ # BSD LICENSE # -# Copyright(c) 2010-2015 Intel Corporation. All rights reserved. +# Copyright(c) 2010-2016 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -58,6 +58,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PORT) += librte_port DIRS-$(CONFIG_RTE_LIBRTE_TABLE) += librte_table DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += librte_pipeline DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += librte_reorder +DIRS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += librte_ctrl_if ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y) DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile new file mode 100644 index 0000000..9e1ed0d --- /dev/null +++ b/lib/librte_ctrl_if/Makefile @@ -0,0 +1,58 @@ +# BSD LICENSE +# +# Copyright(c) 2010-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. + +include $(RTE_SDK)/mk/rte.vars.mk + +# +# library name +# +LIB = librte_ctrl_if.a + +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) + +EXPORT_MAP := rte_ctrl_if_version.map + +LIBABIVER := 2 + +SRCS-y += rte_ctrl_if.c +SRCS-y += rte_nl.c +SRCS-y += rte_ethtool.c + +# +# Export include files +# +SYMLINK-y-include += rte_ctrl_if.h + +# this lib depends upon: +DEPDIRS-y += lib/librte_ether + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c new file mode 100644 index 0000000..acc578a --- /dev/null +++ b/lib/librte_ctrl_if/rte_ctrl_if.c @@ -0,0 +1,166 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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. + */ + +#include +#include + +#include + +#include +#include "rte_ctrl_if.h" +#include "rte_nl.h" + +static int kcp_fd = -1; +static int kcp_fd_ref; + +#define RTE_KCP_IOCTL_TEST _IOWR(0, 1, int) +#define RTE_KCP_IOCTL_CREATE _IOWR(0, 2, int) +#define RTE_KCP_IOCTL_RELEASE _IOWR(0, 3, int) + +static int +control_interface_init(void) +{ + int ret; + kcp_fd = open("/dev/kcp", O_RDWR); + + if (kcp_fd < 0) { + RTE_LOG(ERR, CTRL_IF, + "Failed to initialize control interface.\n"); + return -1; + } + + ret = control_interface_nl_init(); + if (ret < 0) + close(kcp_fd); + + return ret; +} + +static int +control_interface_ref_get(void) +{ + int ret = 0; + + if (kcp_fd_ref == 0) + ret = control_interface_init(); + + if (ret == 0) + kcp_fd_ref++; + + return kcp_fd_ref; +} + +static void +control_interface_release(void) +{ + close(kcp_fd); + control_interface_nl_release(); +} + +static int +control_interface_ref_put(void) +{ + if (kcp_fd_ref == 0) + return 0; + + kcp_fd_ref--; + + if (kcp_fd_ref == 0) + control_interface_release(); + + return kcp_fd_ref; +} + +static int +rte_eth_control_interface_create_one(uint8_t port_id) +{ + if (control_interface_ref_get() != 0) { + ioctl(kcp_fd, RTE_KCP_IOCTL_CREATE, port_id); + RTE_LOG(DEBUG, CTRL_IF, + "Control interface created for port:%u\n", + port_id); + } + + return 0; +} + +int +rte_eth_control_interface_create(void) +{ + int i; + int ret = 0; + + for (i = 0; i < RTE_MAX_ETHPORTS; i++) { + if (rte_eth_dev_is_valid_port(i)) { + ret = rte_eth_control_interface_create_one(i); + if (ret < 0) + return ret; + } + } + + return ret; +} + +static int +rte_eth_control_interface_destroy_one(uint8_t port_id) +{ + ioctl(kcp_fd, RTE_KCP_IOCTL_RELEASE, port_id); + control_interface_ref_put(); + RTE_LOG(DEBUG, CTRL_IF, "Control interface destroyed for port:%u\n", + port_id); + + return 0; +} + +int +rte_eth_control_interface_destroy(void) +{ + int i; + int ret = 0; + + for (i = 0; i < RTE_MAX_ETHPORTS; i++) { + if (rte_eth_dev_is_valid_port(i)) { + ret = rte_eth_control_interface_destroy_one(i); + if (ret < 0) + return ret; + } + } + + return ret; +} + +int +rte_eth_control_interface_process_msg(int flag, int timeout_sec) +{ + return control_interface_process_msg(flag, timeout_sec); +} diff --git a/lib/librte_ctrl_if/rte_ctrl_if.h b/lib/librte_ctrl_if/rte_ctrl_if.h new file mode 100644 index 0000000..77245ae --- /dev/null +++ b/lib/librte_ctrl_if/rte_ctrl_if.h @@ -0,0 +1,54 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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_IF_H_ +#define _RTE_CTRL_IF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum control_interface_process_flag { + RTE_ETHTOOL_CTRL_IF_PROCESS_MSG, + RTE_ETHTOOL_CTRL_IF_DISCARD_MSG, +}; + +int rte_eth_control_interface_create(void); +int rte_eth_control_interface_destroy(void); +int rte_eth_control_interface_process_msg(int flag, int timeout_sec); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_CTRL_IF_H_ */ diff --git a/lib/librte_ctrl_if/rte_ctrl_if_version.map b/lib/librte_ctrl_if/rte_ctrl_if_version.map new file mode 100644 index 0000000..8b27e26 --- /dev/null +++ b/lib/librte_ctrl_if/rte_ctrl_if_version.map @@ -0,0 +1,9 @@ +DPDK_2.3 { + global: + + rte_eth_control_interface_create; + rte_eth_control_interface_destroy; + rte_eth_control_interface_process_msg; + + local: *; +}; diff --git a/lib/librte_ctrl_if/rte_ethtool.c b/lib/librte_ctrl_if/rte_ethtool.c new file mode 100644 index 0000000..7d6ccec --- /dev/null +++ b/lib/librte_ctrl_if/rte_ethtool.c @@ -0,0 +1,354 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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. + */ + +#include + +#include + +#include +#include +#include "rte_ethtool.h" + +#define ETHTOOL_GEEPROM_LEN 99 +#define ETHTOOL_GREGS_LEN 98 +#define ETHTOOL_GSSET_COUNT 97 + +static int +get_drvinfo(int port_id, void *data, int *data_len) +{ + struct ethtool_drvinfo *info = data; + struct rte_eth_dev_info dev_info; + int n; + + memset(&dev_info, 0, sizeof(dev_info)); + rte_eth_dev_info_get(port_id, &dev_info); + + snprintf(info->driver, sizeof(info->driver), "%s", + dev_info.driver_name); + snprintf(info->version, sizeof(info->version), "%s", + rte_version()); + snprintf(info->bus_info, sizeof(info->bus_info), + "%04x:%02x:%02x.%x", + dev_info.pci_dev->addr.domain, dev_info.pci_dev->addr.bus, + dev_info.pci_dev->addr.devid, dev_info.pci_dev->addr.function); + + n = rte_eth_dev_get_reg_length(port_id); + info->regdump_len = n < 0 ? 0 : n; + + n = rte_eth_dev_get_eeprom_length(port_id); + info->eedump_len = n < 0 ? 0 : n; + + info->n_stats = sizeof(struct rte_eth_stats) / sizeof(uint64_t); + info->testinfo_len = 0; + + *data_len = sizeof(struct ethtool_drvinfo); + + return 0; +} + +static int +get_reg_len(int port_id, void *data, int *data_len) +{ + int reg_length = 0; + + reg_length = rte_eth_dev_get_reg_length(port_id); + if (reg_length < 0) + return reg_length; + + *(int *)data = reg_length * sizeof(uint32_t); + *data_len = sizeof(int); + + return 0; +} + +static int +get_reg(int port_id, void *in_data, void *out_data, int *out_data_len) +{ + unsigned int reg_length; + int reg_length_out_len; + struct ethtool_regs *ethtool_regs = in_data; + struct rte_dev_reg_info regs = { + .data = out_data, + .length = 0, + }; + int ret; + + ret = get_reg_len(port_id, ®_length, ®_length_out_len); + if (ret < 0 || reg_length > ethtool_regs->len) + return -1; + + ret = rte_eth_dev_get_reg_info(port_id, ®s); + if (ret < 0) + return ret; + + ethtool_regs->version = regs.version; + *out_data_len = reg_length; + + return 0; +} + +static int +get_link(int port_id, void *data, int *data_len) +{ + struct rte_eth_link link; + + rte_eth_link_get(port_id, &link); + + *(int *)data = link.link_status; + *data_len = sizeof(int); + + return 0; +} + +static int +get_eeprom_length(int port_id, void *data, int *data_len) +{ + int eeprom_length = 0; + + eeprom_length = rte_eth_dev_get_eeprom_length(port_id); + if (eeprom_length < 0) + return eeprom_length; + + *(int *)data = eeprom_length; + *data_len = sizeof(int); + + return 0; +} + +static int +get_eeprom(int port_id, void *in_data, void *out_data) +{ + struct ethtool_eeprom *eeprom = in_data; + struct rte_dev_eeprom_info eeprom_info = { + .data = out_data, + .offset = eeprom->offset, + .length = eeprom->len, + }; + int ret; + + ret = rte_eth_dev_get_eeprom(port_id, &eeprom_info); + if (ret < 0) + return ret; + + eeprom->magic = eeprom_info.magic; + + return 0; +} + +static int +set_eeprom(int port_id, void *in_data, void *out_data) +{ + struct ethtool_eeprom *eeprom = in_data; + struct rte_dev_eeprom_info eeprom_info = { + .data = out_data, + .offset = eeprom->offset, + .length = eeprom->len, + }; + int ret; + + ret = rte_eth_dev_set_eeprom(port_id, &eeprom_info); + if (ret < 0) + return ret; + + eeprom->magic = eeprom_info.magic; + + return 0; +} + +static int +get_pauseparam(int port_id, void *data, void *data_len) +{ + struct ethtool_pauseparam *pauseparam = data; + struct rte_eth_fc_conf fc_conf; + int ret; + + ret = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf); + if (ret) + return ret; + + pauseparam->tx_pause = 0; + pauseparam->rx_pause = 0; + + switch (fc_conf.mode) { + case RTE_FC_RX_PAUSE: + pauseparam->rx_pause = 1; + break; + case RTE_FC_TX_PAUSE: + pauseparam->tx_pause = 1; + break; + case RTE_FC_FULL: + pauseparam->rx_pause = 1; + pauseparam->tx_pause = 1; + default: + break; + } + pauseparam->autoneg = (uint32_t)fc_conf.autoneg; + + *(int *)data_len = sizeof(struct ethtool_pauseparam); + + return 0; +} + +int +rte_eth_dev_ethtool_process(int cmd_id, int port_id, void *in_data, + void *out_data, int *out_data_len) +{ + int ret = 0; + + if (!rte_eth_dev_is_valid_port(port_id)) + return -ENODEV; + + switch (cmd_id) { + case ETHTOOL_GDRVINFO: + return get_drvinfo(port_id, out_data, out_data_len); + case ETHTOOL_GREGS_LEN: + return get_reg_len(port_id, out_data, out_data_len); + case ETHTOOL_GREGS: + return get_reg(port_id, in_data, out_data, out_data_len); + case ETHTOOL_GLINK: + return get_link(port_id, out_data, out_data_len); + case ETHTOOL_GEEPROM_LEN: + return get_eeprom_length(port_id, out_data, out_data_len); + case ETHTOOL_GEEPROM: + return get_eeprom(port_id, in_data, out_data); + case ETHTOOL_SEEPROM: + return set_eeprom(port_id, in_data, out_data); + case ETHTOOL_GPAUSEPARAM: + return get_pauseparam(port_id, out_data, out_data_len); + default: + ret = -95 /* EOPNOTSUPP */; + break; + } + + return ret; +} + +static int +set_mtu(int port_id, void *in_data) +{ + int *mtu = in_data; + + return rte_eth_dev_set_mtu(port_id, *mtu); +} + +static int +get_stats(int port_id, void *data, int *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; + if_stats->multicast = stats.imcasts; + + *data_len = sizeof(struct rtnl_link_stats64); + + return 0; +} + +static int +get_mac(int port_id, void *data, int *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(int 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(int port_id) +{ + rte_eth_dev_stop(port_id); + return rte_eth_dev_start(port_id); +} + +static int +stop_port(int port_id) +{ + rte_eth_dev_stop(port_id); + return 0; +} + +int +rte_eth_dev_control_process(int cmd_id, int port_id, void *in_data, + void *out_data, int *out_data_len) +{ + int ret = 0; + + if (!rte_eth_dev_is_valid_port(port_id)) + return -ENODEV; + + switch (cmd_id) { + case RTE_KCP_REQ_CHANGE_MTU: + return set_mtu(port_id, in_data); + case RTE_KCP_REQ_GET_STATS: + return get_stats(port_id, out_data, out_data_len); + case RTE_KCP_REQ_GET_MAC: + return get_mac(port_id, out_data, out_data_len); + case RTE_KCP_REQ_SET_MAC: + return set_mac(port_id, in_data); + case RTE_KCP_REQ_START_PORT: + return start_port(port_id); + case RTE_KCP_REQ_STOP_PORT: + return stop_port(port_id); + default: + ret = -95 /* EOPNOTSUPP */; + break; + } + + return ret; +} diff --git a/lib/librte_ctrl_if/rte_ethtool.h b/lib/librte_ctrl_if/rte_ethtool.h new file mode 100644 index 0000000..af1abfe --- /dev/null +++ b/lib/librte_ctrl_if/rte_ethtool.h @@ -0,0 +1,64 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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_ETHTOOL_H_ +#define _RTE_ETHTOOL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +enum rte_kcp_req_id { + RTE_KCP_REQ_UNKNOWN = (1 << 16), + RTE_KCP_REQ_CHANGE_MTU, + RTE_KCP_REQ_CFG_NETWORK_IF, + RTE_KCP_REQ_GET_STATS, + RTE_KCP_REQ_GET_MAC, + RTE_KCP_REQ_SET_MAC, + RTE_KCP_REQ_START_PORT, + RTE_KCP_REQ_STOP_PORT, + RTE_KCP_REQ_MAX, +}; + +int rte_eth_dev_ethtool_process(int cmd_id, int port_id, void *in_data, + void *out_data, int *out_data_len); +int rte_eth_dev_control_process(int cmd_id, int port_id, void *in_data, + void *out_data, int *out_data_len); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_ETHTOOL_H_ */ diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c new file mode 100644 index 0000000..03b39cb --- /dev/null +++ b/lib/librte_ctrl_if/rte_nl.c @@ -0,0 +1,274 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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. + */ + +#include + +#include +#include + +#include +#include +#include "rte_ethtool.h" +#include "rte_nl.h" +#include "rte_ctrl_if.h" + +#define KCP_NL_GRP 31 +#define MAX_PAYLOAD 1024 + +static int sock_fd = -1; +pthread_t thread_id; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER; +static struct nlmsghdr *nlh_s; +static struct nlmsghdr *nlh_r; +static struct msghdr msg_s; +static struct msghdr msg_r; +static struct iovec iov_s; +static struct iovec iov_r; +static struct sockaddr_nl dest_addr; +static struct sockaddr_nl src_addr; +static int terminate; + +static int kcp_ethtool_msg_count; +static struct kcp_ethtool_msg head; + +static void +control_interface_nl_send(void *buf, size_t len) +{ + int ret; + + /* Fill in the netlink message payload */ + memcpy(NLMSG_DATA(nlh_s), buf, len); + + ret = sendmsg(sock_fd, &msg_s, 0); + + if (ret < 0) + RTE_LOG(ERR, CTRL_IF, "Failed nl msg send. ret:%d, err:%d\n", + ret, errno); +} + +static void +control_interface_nl_process_msg(struct kcp_ethtool_msg *msg) +{ + if (msg->cmd_id > RTE_KCP_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); + } else { + msg->err = rte_eth_dev_ethtool_process(msg->cmd_id, + msg->port_id, msg->input_buffer, + msg->output_buffer, &msg->output_buffer_len); + } + + control_interface_nl_send((void *)msg, + sizeof(struct kcp_ethtool_msg)); +} + +int +control_interface_process_msg(int flag, int timeout_sec) +{ + int ret = 0; + struct timespec ts; + + pthread_mutex_lock(&list_lock); + while (timeout_sec && !kcp_ethtool_msg_count && !ret) { + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += timeout_sec; + ret = pthread_cond_timedwait(&cond, &list_lock, &ts); + } + + switch (flag) { + case RTE_ETHTOOL_CTRL_IF_PROCESS_MSG: + if (kcp_ethtool_msg_count) { + control_interface_nl_process_msg(&head); + kcp_ethtool_msg_count = 0; + } + break; + + case RTE_ETHTOOL_CTRL_IF_DISCARD_MSG: + if (kcp_ethtool_msg_count) { + head.err = -1; + control_interface_nl_send((void *)&head, + sizeof(struct kcp_ethtool_msg)); + kcp_ethtool_msg_count = 0; + } + break; + + default: + ret = -1; + break; + } + pthread_mutex_unlock(&list_lock); + + return ret; +} + +static int +msg_list_add(struct nlmsghdr *nlh) +{ + pthread_mutex_lock(&list_lock); + + memcpy(&head, NLMSG_DATA(nlh), sizeof(struct kcp_ethtool_msg)); + kcp_ethtool_msg_count = 1; + + pthread_mutex_unlock(&list_lock); + + return 0; +} + +static void * +control_interface_nl_recv(void *arg) +{ + int ret; + + for (;;) { + if (terminate == 1) + break; + + ret = recvmsg(sock_fd, &msg_r, 0); + if (ret < 0) + continue; + + if ((unsigned)ret < sizeof(struct kcp_ethtool_msg)) { + RTE_LOG(WARNING, CTRL_IF, + "Received %u bytes, payload %lu\n", + ret, sizeof(struct kcp_ethtool_msg)); + continue; + } + + ret = msg_list_add(nlh_r); + + pthread_cond_signal(&cond); + } + + return arg; +} + +static void +nl_setup_header(struct msghdr *msg, struct nlmsghdr **nlh, struct iovec *iov, + struct sockaddr_nl *daddr) +{ + struct nlmsghdr *nlh_tmp; + + if (*nlh == NULL) + *nlh = malloc(NLMSG_SPACE(MAX_PAYLOAD)); + + nlh_tmp = *nlh; + memset(nlh_tmp, 0, NLMSG_SPACE(MAX_PAYLOAD)); + + /* Fill the netlink message header */ + nlh_tmp->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); + nlh_tmp->nlmsg_pid = getpid(); /* self pid */ + nlh_tmp->nlmsg_flags = 0; + + iov->iov_base = (void *)nlh_tmp; + iov->iov_len = nlh_tmp->nlmsg_len; + memset(msg, 0, sizeof(struct msghdr)); + msg->msg_name = (void *)daddr; + msg->msg_namelen = sizeof(struct sockaddr_nl); + msg->msg_iov = iov; + msg->msg_iovlen = 1; +} + +static int +control_interface_nl_socket_init(void) +{ + int fd; + int ret; + + fd = socket(PF_NETLINK, SOCK_RAW, KCP_NL_GRP); + if (fd < 0) + return -1; + + src_addr.nl_family = AF_NETLINK; + src_addr.nl_pid = getpid(); + ret = bind(fd, (struct sockaddr *)&src_addr, sizeof(src_addr)); + if (ret) { + close(fd); + return -1; + } + + dest_addr.nl_family = AF_NETLINK; + dest_addr.nl_pid = 0; /* For Linux Kernel */ + dest_addr.nl_groups = 0; + + nl_setup_header(&msg_s, &nlh_s, &iov_s, &dest_addr); + nl_setup_header(&msg_r, &nlh_r, &iov_r, &dest_addr); + + return fd; +} + +int +control_interface_nl_init(void) +{ + int ret; + char buf[] = "pid"; + sock_fd = control_interface_nl_socket_init(); + + if (sock_fd < 0) { + RTE_LOG(ERR, CTRL_IF, + "Failed to initialize control interface.\n"); + return -1; + } + + ret = pthread_create(&thread_id, NULL, control_interface_nl_recv, + NULL); + if (ret != 0) + return -1; + control_interface_nl_send((void *)buf, sizeof(buf)); + + return 0; +} + +static void +msg_list_destroy(void) +{ + pthread_mutex_lock(&list_lock); + kcp_ethtool_msg_count = 0; + pthread_cond_signal(&cond); + pthread_mutex_unlock(&list_lock); +} + +void +control_interface_nl_release(void) +{ + terminate = 1; + pthread_cancel(thread_id); + pthread_join(thread_id, NULL); + close(sock_fd); + msg_list_destroy(); + free(nlh_r); + free(nlh_s); + nlh_r = NULL; + nlh_s = NULL; +} diff --git a/lib/librte_ctrl_if/rte_nl.h b/lib/librte_ctrl_if/rte_nl.h new file mode 100644 index 0000000..bb600cc --- /dev/null +++ b/lib/librte_ctrl_if/rte_nl.h @@ -0,0 +1,60 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-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_NL_H_ +#define _RTE_NL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define KCP_ETHTOOL_MSG_LEN 500 +struct kcp_ethtool_msg { + int cmd_id; + int port_id; + char input_buffer[KCP_ETHTOOL_MSG_LEN]; + char output_buffer[KCP_ETHTOOL_MSG_LEN]; + int input_buffer_len; + int output_buffer_len; + int err; +}; + +int control_interface_nl_init(void); +void control_interface_nl_release(void); +int control_interface_process_msg(int flag, int timeout_sec); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_NL_H_ */ diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h index 2e47e7f..a0a2c9f 100644 --- a/lib/librte_eal/common/include/rte_log.h +++ b/lib/librte_eal/common/include/rte_log.h @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -79,6 +79,7 @@ extern struct rte_logs rte_logs; #define RTE_LOGTYPE_PIPELINE 0x00008000 /**< Log related to pipeline. */ #define RTE_LOGTYPE_MBUF 0x00010000 /**< Log related to mbuf. */ #define RTE_LOGTYPE_CRYPTODEV 0x00020000 /**< Log related to cryptodev. */ +#define RTE_LOGTYPE_CTRL_IF 0x00040000 /**< Log related to control interface. */ /* these log types can be used in an application */ #define RTE_LOGTYPE_USER1 0x01000000 /**< User-defined log type 1. */ diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 8ecab41..e1638f0 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -1,6 +1,6 @@ # BSD LICENSE # -# Copyright(c) 2010-2015 Intel Corporation. All rights reserved. +# Copyright(c) 2010-2016 Intel Corporation. All rights reserved. # Copyright(c) 2014-2015 6WIND S.A. # All rights reserved. # @@ -122,6 +122,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF) += -lrte_mbuf _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF_OFFLOAD) += -lrte_mbuf_offload _LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG) += -lrte_ip_frag _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER) += -lethdev +_LDLIBS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += -lrte_ctrl_if _LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += -lrte_cryptodev _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += -lrte_mempool _LDLIBS-$(CONFIG_RTE_LIBRTE_RING) += -lrte_ring -- 2.5.0