All of lore.kernel.org
 help / color / mirror / Atom feed
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: [PATCH v10 15/20] ctrl_if: add create destroy interface APIs
Date: Tue,  4 Jul 2017 17:13:32 +0100	[thread overview]
Message-ID: <20170704161337.45926-16-ferruh.yigit@intel.com> (raw)
In-Reply-To: <20170704161337.45926-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           | 302 +++++++++++++++++++++++++++++
 lib/librte_ctrl_if/rte_ctrl_if.h           |  34 ++++
 lib/librte_ctrl_if/rte_ctrl_if_version.map |   4 +
 3 files changed, 340 insertions(+)

diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c
index 45a3a07cf..5dda9121a 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if.c
+++ b/lib/librte_ctrl_if/rte_ctrl_if.c
@@ -31,4 +31,306 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/socket.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_ref_cnt;
+
+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 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 to socket 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_ref_cnt == 0)
+		ret = control_interface_init();
+
+	if (ret == 0)
+		unci_ref_cnt++;
+	else
+		RTE_LOG(ERR, CTRL_IF,
+				"Failed to initialize control interface\n");
+
+	return unci_ref_cnt;
+}
+
+static void
+control_interface_release(void)
+{
+	close(unci_rtnl_fd);
+	unci_rtnl_fd = -1;
+}
+
+static int
+control_interface_ref_put(void)
+{
+	if (unci_ref_cnt == 0)
+		return 0;
+
+	unci_ref_cnt--;
+
+	if (unci_ref_cnt == 0)
+		control_interface_release();
+
+	return unci_ref_cnt;
+}
+
+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;
+	uint8_t buf[BUFSZ];
+	uint32_t port_id_local = port_id;
+	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 | 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_local,
+			sizeof(uint32_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(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(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 0bd4b88c9..d37b2eacb 100644
--- a/lib/librte_ctrl_if/rte_ctrl_if.h
+++ b/lib/librte_ctrl_if/rte_ctrl_if.h
@@ -51,6 +51,40 @@ extern "C" {
 
 #include <exec-env/unci.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(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(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..3cbe0d38f 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;
+	rte_eth_control_interface_destroy;
 
 	local: *;
 };
-- 
2.13.0

  parent reply	other threads:[~2017-07-04 16:14 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-26 16:52 [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 ` [PATCH v8 0/4] Userspace Network Control Interface (UNCI) Ferruh Yigit
2017-06-21 11:06   ` [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   ` [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   ` [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   ` [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   ` [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   ` [PATCH v9 00/20] " Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 01/20] ethtool: add library skeleton Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 02/20] ethtool: move from sample folder into lib folder Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 03/20] ethtool: remove PMD specific API call Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 04/20] ethtool: update header doxygen syntax Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 05/20] ethtool: enable library Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 06/20] doc: add ethtool library documentation Ferruh Yigit
2017-07-02 20:18       ` Mcnamara, John
2017-06-30 16:51     ` [PATCH v9 07/20] doc: update ethtool sample app doc Ferruh Yigit
2017-07-02 20:17       ` Mcnamara, John
2017-06-30 16:51     ` [PATCH v9 08/20] unci: add module skeleton Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 09/20] unci: add rtnl newlink Ferruh Yigit
2017-06-30 17:27       ` Stephen Hemminger
2017-06-30 16:51     ` [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     ` [PATCH v9 11/20] unci: add netlink exec Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 12/20] unci: add netdevice ops Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 13/20] unci: add ethtool support Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 14/20] ctrl_if: add library skeleton Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 15/20] ctrl_if: add create destroy interface APIs Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 16/20] ctrl_if: initialize netlink interface Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 17/20] ctrl_if: process control messages Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 18/20] ctrl_if: process ethtool messages Ferruh Yigit
2017-06-30 16:51     ` [PATCH v9 19/20] doc: add control interface library documentation Ferruh Yigit
2017-07-02 20:16       ` Mcnamara, John
2017-06-30 16:51     ` [PATCH v9 20/20] ethdev: add control interface support Ferruh Yigit
2017-07-04 16:13     ` [PATCH v10 00/20] Userspace Network Control Interface (UNCI) Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 01/20] ethtool: add library skeleton Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 02/20] ethtool: move from sample folder into lib folder Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 03/20] ethtool: remove PMD specific API call Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 04/20] ethtool: update header doxygen syntax Ferruh Yigit
2017-07-06  9:18         ` Burakov, Anatoly
2017-07-04 16:13       ` [PATCH v10 05/20] ethtool: enable library Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 06/20] doc: add ethtool library documentation Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 07/20] doc: update ethtool sample app doc Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 08/20] unci: add module skeleton Ferruh Yigit
2017-07-06  9:25         ` Burakov, Anatoly
2017-07-04 16:13       ` [PATCH v10 09/20] unci: add rtnl newlink Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 10/20] unci: init netlink Ferruh Yigit
2017-07-06  9:32         ` Burakov, Anatoly
2017-07-04 16:13       ` [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       ` [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       ` [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       ` [PATCH v10 14/20] ctrl_if: add library skeleton Ferruh Yigit
2017-07-04 16:13       ` Ferruh Yigit [this message]
2017-07-04 16:13       ` [PATCH v10 16/20] ctrl_if: initialize generic netlink interface Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 17/20] ctrl_if: process control messages Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 18/20] ctrl_if: process ethtool messages Ferruh Yigit
2017-07-04 16:13       ` [PATCH v10 19/20] doc: add control interface library documentation Ferruh Yigit
2017-07-04 16:13       ` [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=20170704161337.45926-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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.