From: Ferruh Yigit <ferruh.yigit@intel.com>
To: dev@dpdk.org
Cc: Ferruh Yigit <ferruh.yigit@intel.com>,
Stephen Hemminger <stephen@networkplumber.org>,
Bruce Richardson <bruce.richardson@intel.com>,
Anatoly Burakov <anatoly.burakov@intel.com>
Subject: [dpdk-dev] [PATCH v9 15/20] ctrl_if: add create destroy interface APIs
Date: Fri, 30 Jun 2017 17:51:35 +0100 [thread overview]
Message-ID: <20170630165140.59594-16-ferruh.yigit@intel.com> (raw)
In-Reply-To: <20170630165140.59594-1-ferruh.yigit@intel.com>
Library provides two APIs to create and destroy interfaces.
rtnl used to create or destroy interfaces.
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
lib/librte_ctrl_if/rte_ctrl_if.c | 304 +++++++++++++++++++++++++++++
lib/librte_ctrl_if/rte_ctrl_if.h | 34 ++++
lib/librte_ctrl_if/rte_ctrl_if_version.map | 4 +
3 files changed, 342 insertions(+)
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c
index 45a3a07cf..8b0718969 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if.c
+++ b/lib/librte_ctrl_if/rte_ctrl_if.c
@@ -31,4 +31,308 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <fcntl.h>
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <rte_log.h>
#include "rte_ctrl_if.h"
+
+#define NAMESZ 32
+#define IFNAME "dpdk"
+#define BUFSZ 1024
+
+static int unci_rtnl_fd = -1;
+static uint32_t unci_fd_ref;
+
+struct unci_request {
+ struct nlmsghdr nlmsg;
+ uint8_t buf[BUFSZ];
+};
+
+static int
+control_interface_rtnl_init(void)
+{
+ struct sockaddr_nl src;
+ int ret;
+
+ unci_rtnl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (unci_rtnl_fd < 0) {
+ RTE_LOG(ERR, CTRL_IF, "Socket for create failed\n");
+ return -1;
+ }
+
+ memset(&src, 0, sizeof(struct sockaddr_nl));
+
+ src.nl_family = AF_NETLINK;
+ src.nl_pid = getpid();
+
+ ret = bind(unci_rtnl_fd, (struct sockaddr *)&src,
+ sizeof(struct sockaddr_nl));
+ if (ret < 0) {
+ RTE_LOG(ERR, CTRL_IF, "Bind for create failed\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+control_interface_init(void)
+{
+ int ret;
+
+ ret = control_interface_rtnl_init();
+ if (ret < 0) {
+ RTE_LOG(ERR, CTRL_IF, "Failed to initialize rtnetlink\n");
+ return -1;
+ }
+
+ return ret;
+}
+
+static int
+control_interface_ref_get(void)
+{
+ int ret = 0;
+
+ if (unci_fd_ref == 0)
+ ret = control_interface_init();
+
+ if (ret == 0)
+ unci_fd_ref++;
+ else
+ RTE_LOG(ERR, CTRL_IF,
+ "Failed to initialize control interface\n");
+
+ return unci_fd_ref;
+}
+
+static void
+control_interface_release(void)
+{
+ close(unci_rtnl_fd);
+}
+
+static int
+control_interface_ref_put(void)
+{
+ if (unci_fd_ref == 0)
+ return 0;
+
+ unci_fd_ref--;
+
+ if (unci_fd_ref == 0)
+ control_interface_release();
+
+ return unci_fd_ref;
+}
+
+static int
+add_attr(struct unci_request *req, uint16_t type, void *buf, size_t len)
+{
+ struct rtattr *rta;
+ int nlmsg_len;
+
+ nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
+ rta = (struct rtattr *)((char *)&req->nlmsg + nlmsg_len);
+ if (nlmsg_len + RTA_LENGTH(len) > sizeof(struct unci_request))
+ return -1;
+ rta->rta_type = type;
+ rta->rta_len = RTA_LENGTH(len);
+ memcpy(RTA_DATA(rta), buf, len);
+ req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(len);
+
+ return 0;
+}
+
+static struct
+rtattr *add_attr_nested(struct unci_request *req, unsigned short type)
+{
+ struct rtattr *rta;
+ uint32_t nlmsg_len;
+
+ nlmsg_len = NLMSG_ALIGN(req->nlmsg.nlmsg_len);
+ rta = (struct rtattr *)((uint8_t *)&req->nlmsg + nlmsg_len);
+ if (nlmsg_len + RTA_LENGTH(0) > sizeof(struct unci_request))
+ return NULL;
+ rta->rta_type = type;
+ rta->rta_len = nlmsg_len;
+ req->nlmsg.nlmsg_len = nlmsg_len + RTA_LENGTH(0);
+
+ return rta;
+}
+
+static void
+end_attr_nested(struct unci_request *req, struct rtattr *rta)
+{
+ rta->rta_len = req->nlmsg.nlmsg_len - rta->rta_len;
+}
+
+static int
+rte_eth_rtnl_create(uint8_t port_id)
+{
+ struct unci_request req;
+ struct ifinfomsg *info;
+ struct rtattr *rta1;
+ struct rtattr *rta2;
+ uint32_t pid = getpid();
+ char name[NAMESZ];
+ char type[NAMESZ];
+ struct iovec iov;
+ struct msghdr msg;
+ struct sockaddr_nl nladdr;
+ int ret;
+ uint8_t buf[BUFSZ];
+
+ memset(&req, 0, sizeof(struct unci_request));
+
+ req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ req.nlmsg.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
+ req.nlmsg.nlmsg_flags |= NLM_F_ACK;
+ req.nlmsg.nlmsg_type = RTM_NEWLINK;
+
+ info = NLMSG_DATA(&req.nlmsg);
+
+ info->ifi_family = AF_UNSPEC;
+ info->ifi_index = 0;
+
+ snprintf(name, NAMESZ, IFNAME"%u", port_id);
+ ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
+ if (ret < 0)
+ return -1;
+
+ rta1 = add_attr_nested(&req, IFLA_LINKINFO);
+ if (rta1 == NULL)
+ return -1;
+
+ snprintf(type, NAMESZ, UNCI_DEVICE);
+ ret = add_attr(&req, IFLA_INFO_KIND, type, strlen(type) + 1);
+ if (ret < 0)
+ return -1;
+
+ rta2 = add_attr_nested(&req, IFLA_INFO_DATA);
+ if (rta2 == NULL)
+ return -1;
+
+ ret = add_attr(&req, IFLA_UNCI_PORTID, &port_id, sizeof(uint8_t));
+ if (ret < 0)
+ return -1;
+
+ ret = add_attr(&req, IFLA_UNCI_PID, &pid, sizeof(uint32_t));
+ if (ret < 0)
+ return -1;
+
+ end_attr_nested(&req, rta2);
+ end_attr_nested(&req, rta1);
+
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ iov.iov_base = (void *)&req.nlmsg;
+ iov.iov_len = req.nlmsg.nlmsg_len;
+
+ memset(&msg, 0, sizeof(struct msghdr));
+ msg.msg_name = &nladdr;
+ msg.msg_namelen = sizeof(nladdr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ ret = sendmsg(unci_rtnl_fd, &msg, 0);
+ if (ret < 0) {
+ RTE_LOG(ERR, CTRL_IF, "Send for create failed %d.\n", errno);
+ return -1;
+ }
+
+ memset(buf, 0, sizeof(buf));
+ iov.iov_base = buf;
+ iov.iov_len = sizeof(buf);
+
+ ret = recvmsg(unci_rtnl_fd, &msg, 0);
+ if (ret < 0) {
+ RTE_LOG(ERR, CTRL_IF, "Recv for create failed\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+rte_eth_control_interface_create_one(uint8_t port_id)
+{
+ int ret;
+
+ if (control_interface_ref_get() != 0) {
+ ret = rte_eth_rtnl_create(port_id);
+ RTE_LOG(DEBUG, CTRL_IF,
+ "Control interface %s for port:%u\n",
+ ret < 0 ? "failed" : "created", port_id);
+ }
+
+ return 0;
+}
+
+static int
+rte_eth_rtnl_destroy(uint8_t port_id)
+{
+ struct unci_request req;
+ struct ifinfomsg *info;
+ char name[NAMESZ];
+ struct iovec iov;
+ struct msghdr msg;
+ struct sockaddr_nl nladdr;
+ int ret;
+
+ memset(&req, 0, sizeof(struct unci_request));
+
+ req.nlmsg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ req.nlmsg.nlmsg_flags = NLM_F_REQUEST;
+ req.nlmsg.nlmsg_type = RTM_DELLINK;
+
+ info = NLMSG_DATA(&req.nlmsg);
+
+ info->ifi_family = AF_UNSPEC;
+ info->ifi_index = 0;
+
+ snprintf(name, NAMESZ, IFNAME"%u", port_id);
+ ret = add_attr(&req, IFLA_IFNAME, name, strlen(name) + 1);
+ if (ret < 0)
+ return -1;
+
+ memset(&nladdr, 0, sizeof(nladdr));
+ nladdr.nl_family = AF_NETLINK;
+
+ iov.iov_base = (void *)&req.nlmsg;
+ iov.iov_len = req.nlmsg.nlmsg_len;
+
+ memset(&msg, 0, sizeof(struct msghdr));
+ msg.msg_name = &nladdr;
+ msg.msg_namelen = sizeof(nladdr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ ret = sendmsg(unci_rtnl_fd, &msg, 0);
+ if (ret < 0) {
+ RTE_LOG(ERR, CTRL_IF, "Send for destroy failed\n");
+ return -1;
+ }
+ return 0;
+}
+
+int
+rte_eth_control_interface_destroy_one(uint8_t port_id)
+{
+ rte_eth_rtnl_destroy(port_id);
+ control_interface_ref_put();
+ RTE_LOG(DEBUG, CTRL_IF, "Control interface destroyed for port:%u\n",
+ port_id);
+
+ return 0;
+}
diff --git a/lib/librte_ctrl_if/rte_ctrl_if.h b/lib/librte_ctrl_if/rte_ctrl_if.h
index 04a6983bb..13ede38a8 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if.h
+++ b/lib/librte_ctrl_if/rte_ctrl_if.h
@@ -49,6 +49,40 @@ extern "C" {
#include <exec-env/rte_unci_common.h>
+/**
+ * Creates control interfaces (Linux virtual network interface)for
+ * given ethdev port.
+ *
+ * This API opens device created by supportive kernel module and initializes
+ * kernel communication interface.
+ *
+ * With first interface created, a pthread created to receive the control
+ * messages.
+ *
+ * If supportive kernel module is not inserted this API will return
+ * an error.
+ *
+ * @param port_id
+ * port id to create virtual interface
+ * @return
+ * 0 on success.
+ * Negative value on error.
+ */
+int rte_eth_control_interface_create_one(uint8_t port_id);
+
+/**
+ * Destroys control interfaces.
+ *
+ * This API close device created by supportive kernel module and release
+ * underlying communication interface.
+ *
+ * @return
+ * @param port_id
+ * port id to destroy virtual interface
+ * 0 on success.
+ * Negative value on error.
+ */
+int rte_eth_control_interface_destroy_one(uint8_t port_id);
#ifdef __cplusplus
}
diff --git a/lib/librte_ctrl_if/rte_ctrl_if_version.map b/lib/librte_ctrl_if/rte_ctrl_if_version.map
index b6d2840be..b658a0ee0 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if_version.map
+++ b/lib/librte_ctrl_if/rte_ctrl_if_version.map
@@ -1,4 +1,8 @@
DPDK_17.08 {
+ global:
+
+ rte_eth_control_interface_create_one;
+ rte_eth_control_interface_destroy_one;
local: *;
};
--
2.13.0
next prev parent reply other threads:[~2017-06-30 16:52 UTC|newest]
Thread overview: 91+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-26 16:52 [dpdk-dev] [RFC] Kernel Control Path (KCP) Ferruh Yigit
2017-05-28 16:55 ` Wiles, Keith
2017-05-29 9:26 ` Bruce Richardson
2017-05-29 17:29 ` Wiles, Keith
2017-06-16 15:54 ` Ferruh Yigit
2017-06-20 12:33 ` Ferruh Yigit
2017-05-30 10:55 ` Thomas Monjalon
2017-06-13 17:21 ` Ferruh Yigit
2017-06-13 18:00 ` Jay Rolette
2017-06-13 18:04 ` Dumitrescu, Cristian
2017-06-13 18:18 ` Wiles, Keith
2017-06-15 12:07 ` Alex Rosenbaum
2017-06-16 15:27 ` Ferruh Yigit
2017-06-16 16:48 ` Stephen Hemminger
2017-06-13 18:17 ` Wiles, Keith
2017-06-21 11:06 ` [dpdk-dev] [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Ferruh Yigit
2017-06-21 11:06 ` [dpdk-dev] [PATCH v8 1/4] ethtool: move from sample folder to lib folder Ferruh Yigit
2017-06-26 11:02 ` Bruce Richardson
2017-06-21 11:06 ` [dpdk-dev] [PATCH v8 2/4] unci: add kernel control path kernel module Ferruh Yigit
2017-06-21 15:23 ` Stephen Hemminger
2017-06-30 17:02 ` Ferruh Yigit
2017-06-21 11:06 ` [dpdk-dev] [PATCH v8 3/4] rte_ctrl_if: add control interface library Ferruh Yigit
2017-06-26 11:09 ` Bruce Richardson
2017-06-26 11:30 ` Bruce Richardson
2017-06-21 11:06 ` [dpdk-dev] [PATCH v8 4/4] ethdev: add control interface support Ferruh Yigit
2017-06-21 15:24 ` Stephen Hemminger
2017-06-30 17:06 ` Ferruh Yigit
2017-06-26 11:39 ` [dpdk-dev] [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Bruce Richardson
2017-06-29 16:13 ` Ferruh Yigit
2017-06-30 16:56 ` Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 00/20] " Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 01/20] ethtool: add library skeleton Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 02/20] ethtool: move from sample folder into lib folder Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 03/20] ethtool: remove PMD specific API call Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 04/20] ethtool: update header doxygen syntax Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 05/20] ethtool: enable library Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 06/20] doc: add ethtool library documentation Ferruh Yigit
2017-07-02 20:18 ` Mcnamara, John
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 07/20] doc: update ethtool sample app doc Ferruh Yigit
2017-07-02 20:17 ` Mcnamara, John
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 08/20] unci: add module skeleton Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 09/20] unci: add rtnl newlink Ferruh Yigit
2017-06-30 17:27 ` Stephen Hemminger
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 10/20] unci: init netlink Ferruh Yigit
2017-06-30 17:28 ` Stephen Hemminger
2017-06-30 17:29 ` Stephen Hemminger
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 11/20] unci: add netlink exec Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 12/20] unci: add netdevice ops Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 13/20] unci: add ethtool support Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 14/20] ctrl_if: add library skeleton Ferruh Yigit
2017-06-30 16:51 ` Ferruh Yigit [this message]
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 16/20] ctrl_if: initialize netlink interface Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 17/20] ctrl_if: process control messages Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 18/20] ctrl_if: process ethtool messages Ferruh Yigit
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 19/20] doc: add control interface library documentation Ferruh Yigit
2017-07-02 20:16 ` Mcnamara, John
2017-06-30 16:51 ` [dpdk-dev] [PATCH v9 20/20] ethdev: add control interface support Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 01/20] ethtool: add library skeleton Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 02/20] ethtool: move from sample folder into lib folder Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 03/20] ethtool: remove PMD specific API call Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 04/20] ethtool: update header doxygen syntax Ferruh Yigit
2017-07-06 9:18 ` Burakov, Anatoly
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 05/20] ethtool: enable library Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 06/20] doc: add ethtool library documentation Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 07/20] doc: update ethtool sample app doc Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 08/20] unci: add module skeleton Ferruh Yigit
2017-07-06 9:25 ` Burakov, Anatoly
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 09/20] unci: add rtnl newlink Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 10/20] unci: init netlink Ferruh Yigit
2017-07-06 9:32 ` Burakov, Anatoly
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 11/20] unci: add netlink exec Ferruh Yigit
2017-07-05 19:07 ` Stephen Hemminger
2017-07-06 10:45 ` Ferruh Yigit
2017-07-07 0:25 ` Stephen Hemminger
2017-07-05 19:15 ` Stephen Hemminger
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 12/20] unci: add netdevice ops Ferruh Yigit
2017-07-05 19:12 ` Stephen Hemminger
2017-07-05 19:12 ` Stephen Hemminger
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 13/20] unci: add ethtool support Ferruh Yigit
2017-07-05 19:07 ` Stephen Hemminger
2017-07-05 19:08 ` Stephen Hemminger
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 14/20] ctrl_if: add library skeleton Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 15/20] ctrl_if: add create destroy interface APIs Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 16/20] ctrl_if: initialize generic netlink interface Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 17/20] ctrl_if: process control messages Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 18/20] ctrl_if: process ethtool messages Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 19/20] doc: add control interface library documentation Ferruh Yigit
2017-07-04 16:13 ` [dpdk-dev] [PATCH v10 20/20] ethdev: add control interface support Ferruh Yigit
2017-07-08 6:28 ` Yuanhan Liu
2017-07-20 14:55 ` Ferruh Yigit
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170630165140.59594-16-ferruh.yigit@intel.com \
--to=ferruh.yigit@intel.com \
--cc=anatoly.burakov@intel.com \
--cc=bruce.richardson@intel.com \
--cc=dev@dpdk.org \
--cc=stephen@networkplumber.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).