@@ -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
@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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 <fcntl.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+
+#include <rte_ethdev.h>
+#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);
+}
new file mode 100644
@@ -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_ */
new file mode 100644
@@ -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: *;
+};
new file mode 100644
@@ -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 <stdio.h>
+
+#include <linux/if_link.h>
+
+#include <rte_version.h>
+#include <rte_ethdev.h>
+#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;
+}
new file mode 100644
@@ -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 <linux/ethtool.h>
+
+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_ */
new file mode 100644
@@ -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 <unistd.h>
+
+#include <sys/socket.h>
+#include <linux/netlink.h>
+
+#include <rte_spinlock.h>
+#include <rte_ethdev.h>
+#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;
+}
new file mode 100644
@@ -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_ */
@@ -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. */
@@ -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