From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 3D3AF7CB4 for ; Tue, 4 Jul 2017 18:14:32 +0200 (CEST) Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Jul 2017 09:14:21 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.40,309,1496127600"; d="scan'208";a="122666486" Received: from silpixa00372839.ir.intel.com (HELO silpixa00372839.ger.corp.intel.com) ([10.237.222.154]) by fmsmga006.fm.intel.com with ESMTP; 04 Jul 2017 09:14:19 -0700 From: Ferruh Yigit To: dev@dpdk.org Cc: Ferruh Yigit , Stephen Hemminger , Bruce Richardson , Anatoly Burakov Date: Tue, 4 Jul 2017 17:13:33 +0100 Message-Id: <20170704161337.45926-17-ferruh.yigit@intel.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170704161337.45926-1-ferruh.yigit@intel.com> References: <20170630165140.59594-1-ferruh.yigit@intel.com> <20170704161337.45926-1-ferruh.yigit@intel.com> Subject: [dpdk-dev] [PATCH v10 16/20] ctrl_if: initialize generic netlink interface X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 Jul 2017 16:14:33 -0000 Initialize generic netlink sockets to exchange data between kernelspace. Signed-off-by: Ferruh Yigit --- lib/librte_ctrl_if/Makefile | 2 + lib/librte_ctrl_if/rte_ctrl_if.c | 10 ++ lib/librte_ctrl_if/rte_nl.c | 231 +++++++++++++++++++++++++++++++++++++++ lib/librte_ctrl_if/rte_nl.h | 48 ++++++++ 4 files changed, 291 insertions(+) create mode 100644 lib/librte_ctrl_if/rte_nl.c create mode 100644 lib/librte_ctrl_if/rte_nl.h diff --git a/lib/librte_ctrl_if/Makefile b/lib/librte_ctrl_if/Makefile index c682af4c4..0da04f7d0 100644 --- a/lib/librte_ctrl_if/Makefile +++ b/lib/librte_ctrl_if/Makefile @@ -38,12 +38,14 @@ LIB = librte_ctrl_if.a CFLAGS += -O3 CFLAGS += $(WERROR_FLAGS) +LDLIBS += -lpthread EXPORT_MAP := rte_ctrl_if_version.map LIBABIVER := 1 SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) := rte_ctrl_if.c +SRCS-$(CONFIG_RTE_LIBRTE_CTRL_IF) += rte_nl.c # # Export include files diff --git a/lib/librte_ctrl_if/rte_ctrl_if.c b/lib/librte_ctrl_if/rte_ctrl_if.c index 5dda9121a..84a9023d5 100644 --- a/lib/librte_ctrl_if/rte_ctrl_if.c +++ b/lib/librte_ctrl_if/rte_ctrl_if.c @@ -39,6 +39,7 @@ #include #include "rte_ctrl_if.h" +#include "rte_nl.h" #define NAMESZ 32 #define IFNAME "dpdk" @@ -90,6 +91,13 @@ control_interface_init(void) return -1; } + ret = control_interface_nl_init(); + if (ret < 0) { + RTE_LOG(ERR, CTRL_IF, "Failed to initialize netlink\n"); + close(unci_rtnl_fd); + unci_rtnl_fd = -1; + } + return ret; } @@ -115,6 +123,8 @@ control_interface_release(void) { close(unci_rtnl_fd); unci_rtnl_fd = -1; + + control_interface_nl_release(); } static int diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c new file mode 100644 index 000000000..8042d12fb --- /dev/null +++ b/lib/librte_ctrl_if/rte_nl.c @@ -0,0 +1,231 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include "rte_nl.h" +#include "rte_ctrl_if.h" + +#define GENLMSG_DATA(glh) (((char *)(NLMSG_DATA(glh)) + GENL_HDRLEN)) +#define NLA_DATA(na) ((void *)((char *)(na) + NLA_HDRLEN)) + +struct ctrl_if_nl { + union { + struct hdr { + struct nlmsghdr nlh; + struct genlmsghdr genlh; + } h; + uint8_t nlmsg[UNCI_GENL_MSG_LEN]; + }; + struct msghdr msg; + struct iovec iov; + struct sockaddr_nl dest_addr; +}; + +static int sock_fd = -1; +static pthread_t thread_id; + +static struct ctrl_if_nl nl_s; +static struct ctrl_if_nl nl_r; + +static int nl_family_id; + +static void * +nl_recv(void *arg) +{ + int ret; + + for (;;) { + ret = recvmsg(sock_fd, &nl_r.msg, 0); + if (ret < 0) + continue; + + if (nl_r.h.nlh.nlmsg_type == NLMSG_ERROR) + continue; + + if ((unsigned int)ret < sizeof(struct unci_nl_msg)) { + RTE_LOG(WARNING, CTRL_IF, + "Received %d bytes, payload %zu\n", + ret, sizeof(struct unci_nl_msg)); + continue; + } + } + + return arg; +} + +static void +nl_setup_header(struct ctrl_if_nl *nl) +{ + memset(nl, 0, sizeof(struct ctrl_if_nl)); + + nl->dest_addr.nl_family = AF_NETLINK; + + /* Fill the netlink message header */ + nl->h.nlh.nlmsg_len = UNCI_GENL_MSG_LEN; + nl->h.nlh.nlmsg_pid = getpid(); /* self pid */ + nl->h.nlh.nlmsg_flags = NLM_F_REQUEST; + nl->h.nlh.nlmsg_type = nl_family_id; + + nl->h.genlh.cmd = UNCI_CMD_MSG; + nl->h.genlh.version = UNCI_GENL_VERSION; + + nl->iov.iov_base = (void *)nl->nlmsg; + nl->iov.iov_len = nl->h.nlh.nlmsg_len; + + nl->msg.msg_name = (void *)&nl->dest_addr; + nl->msg.msg_namelen = sizeof(struct sockaddr_nl); + nl->msg.msg_iov = &nl->iov; + nl->msg.msg_iovlen = 1; +} + +static int +unci_genl_family_get(int fd) +{ + struct nlattr *nl_na; + int id = -1; + int ret; + + nl_setup_header(&nl_s); + nl_setup_header(&nl_r); + + nl_s.h.nlh.nlmsg_type = GENL_ID_CTRL; + nl_s.h.nlh.nlmsg_flags = NLM_F_REQUEST; + nl_s.h.nlh.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); + + nl_s.h.genlh.cmd = CTRL_CMD_GETFAMILY; + + nl_na = (struct nlattr *) GENLMSG_DATA(&nl_s); + nl_na->nla_type = CTRL_ATTR_FAMILY_NAME; + nl_na->nla_len = strlen(UNCI_DEVICE) + 1 + NLA_HDRLEN; + strcpy(NLA_DATA(nl_na), UNCI_DEVICE); + + nl_s.h.nlh.nlmsg_len += NLMSG_ALIGN(nl_na->nla_len); + + nl_s.iov.iov_len = nl_s.h.nlh.nlmsg_len; + + ret = sendmsg(fd, &nl_s.msg, 0); + + if ((uint32_t)ret != nl_s.h.nlh.nlmsg_len) + return -1; + + ret = recvmsg(fd, &nl_r.msg, 0); + if (ret < 0) + return -1; + + if (!NLMSG_OK((&nl_r.h.nlh), (uint32_t)ret)) + return -1; + + if (nl_r.h.nlh.nlmsg_type == NLMSG_ERROR) + return -1; + + nl_na = (struct nlattr *) GENLMSG_DATA(&nl_r); + nl_na = (struct nlattr *) ((char *) nl_na + NLA_ALIGN(nl_na->nla_len)); + if (nl_na->nla_type == CTRL_ATTR_FAMILY_ID) + id = *(__u16 *) NLA_DATA(nl_na); + + return id; +} + +static int +nl_socket_init(void) +{ + struct sockaddr_nl src_addr; + int fd; + int ret; + + fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); + if (fd < 0) + return -1; + + memset(&src_addr, 0, sizeof(struct sockaddr_nl)); + 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; + } + + nl_family_id = unci_genl_family_get(fd); + if (!nl_family_id) { + close(fd); + return -1; + } + + nl_setup_header(&nl_s); + nl_setup_header(&nl_r); + + return fd; +} + +int +control_interface_nl_init(void) +{ + int ret; + + sock_fd = nl_socket_init(); + if (sock_fd < 0) { + RTE_LOG(ERR, CTRL_IF, "Failed to initialize netlink socket\n"); + return -1; + } + + ret = pthread_create(&thread_id, NULL, nl_recv, NULL); + if (ret != 0) { + RTE_LOG(ERR, CTRL_IF, "Failed to create receive thread\n"); + return -1; + } + + ret = rte_thread_setname(thread_id, "netlink-recv"); + if (ret != 0) + RTE_LOG(ERR, CTRL_IF, "Failed to set thread name.\n"); + + return 0; +} + +void +control_interface_nl_release(void) +{ + pthread_cancel(thread_id); + pthread_join(thread_id, NULL); + close(sock_fd); +} diff --git a/lib/librte_ctrl_if/rte_nl.h b/lib/librte_ctrl_if/rte_nl.h new file mode 100644 index 000000000..05a61e193 --- /dev/null +++ b/lib/librte_ctrl_if/rte_nl.h @@ -0,0 +1,48 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTE_NL_H_ +#define _RTE_NL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int control_interface_nl_init(void); +void control_interface_nl_release(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _RTE_NL_H_ */ -- 2.13.0