Hello community, here is the log from the commit of package ibacm for openSUSE:Factory checked in at 2016-04-28 16:56:45 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ibacm (Old) and /work/SRC/openSUSE:Factory/.ibacm.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ibacm" Changes: -------- --- /work/SRC/openSUSE:Factory/ibacm/ibacm.changes 2015-11-08 14:36:16.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.ibacm.new/ibacm.changes 2016-04-28 17:01:38.000000000 +0200 @@ -1,0 +2,6 @@ +Wed Apr 13 07:30:09 UTC 2016 - p.drou...@gmail.com + +- Update to version 1.2.0 + * Empty changelog + +------------------------------------------------------------------- Old: ---- ibacm-1.1.0.tar.gz New: ---- ibacm-1.2.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ibacm.spec ++++++ --- /var/tmp/diff_new_pack.jo3Nnp/_old 2016-04-28 17:01:40.000000000 +0200 +++ /var/tmp/diff_new_pack.jo3Nnp/_new 2016-04-28 17:01:40.000000000 +0200 @@ -1,7 +1,7 @@ # # spec file for package ibacm # -# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %define so_ver 1 Name: ibacm -Version: 1.1.0 +Version: 1.2.0 Release: 0 Summary: InfiniBand Communication Manager Assistant License: GPL-2.0 or BSD-2-Clause @@ -82,11 +82,12 @@ %files -n lib%{name}p%{so_ver} %defattr(-,root,root,-) %dir %{_libdir}/%{name} -%{_libdir}/%{name}/lib%{name}p.* +%{_libdir}/%{name}/lib%{name}p.so.* %files devel %defattr(-,root,root,-) %{_includedir}/infiniband/acm.h %{_includedir}/infiniband/acm_prov.h +%{_libdir}/%{name}/lib%{name}p.so %changelog ++++++ ibacm-1.1.0.tar.gz -> ibacm-1.2.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ibacm-1.1.0/Makefile.am new/ibacm-1.2.0/Makefile.am --- old/ibacm-1.1.0/Makefile.am 2015-07-30 22:54:10.000000000 +0200 +++ new/ibacm-1.2.0/Makefile.am 2016-03-18 21:25:29.000000000 +0100 @@ -40,7 +40,7 @@ EXTRA_DIST = src/acm_util.h prov/acmp/src/libibacmp.map \ include/acm_mad.h src/libacm.h ibacm.init.in \ linux/osd.h linux/dlist.h ibacm.spec.in \ - $(man_MANS) ibacm_hosts.data + $(man_MANS) ibacm_hosts.data src/acm_netlink.h install-exec-hook: install -D -m 755 ibacm.init $(DESTDIR)$(sysconfdir)/init.d/ibacm; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ibacm-1.1.0/Makefile.in new/ibacm-1.2.0/Makefile.in --- old/ibacm-1.1.0/Makefile.in 2015-07-30 22:55:40.000000000 +0200 +++ new/ibacm-1.2.0/Makefile.in 2016-03-18 21:26:44.000000000 +0100 @@ -306,7 +306,7 @@ EXTRA_DIST = src/acm_util.h prov/acmp/src/libibacmp.map \ include/acm_mad.h src/libacm.h ibacm.init.in \ linux/osd.h linux/dlist.h ibacm.spec.in \ - $(man_MANS) ibacm_hosts.data + $(man_MANS) ibacm_hosts.data src/acm_netlink.h all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ibacm-1.1.0/config.h.in new/ibacm-1.2.0/config.h.in --- old/ibacm-1.1.0/config.h.in 2015-07-30 22:56:49.000000000 +0200 +++ new/ibacm-1.2.0/config.h.in 2016-03-18 21:38:57.000000000 +0100 @@ -18,6 +18,9 @@ /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H +/* Have netlink header files */ +#undef HAVE_NETLINK + /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ibacm-1.1.0/configure new/ibacm-1.2.0/configure --- old/ibacm-1.1.0/configure 2015-07-30 22:55:37.000000000 +0200 +++ new/ibacm-1.2.0/configure 2016-03-18 21:26:41.000000000 +0100 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for ibacm 1.1.0. +# Generated by GNU Autoconf 2.67 for ibacm 1.2.0. # # Report bugs to <linux-r...@vger.kernel.org>. # @@ -701,8 +701,8 @@ # Identity of this package. PACKAGE_NAME='ibacm' PACKAGE_TARNAME='ibacm' -PACKAGE_VERSION='1.1.0' -PACKAGE_STRING='ibacm 1.1.0' +PACKAGE_VERSION='1.2.0' +PACKAGE_STRING='ibacm 1.2.0' PACKAGE_BUGREPORT='linux-r...@vger.kernel.org' PACKAGE_URL='' @@ -1427,7 +1427,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures ibacm 1.1.0 to adapt to many kinds of systems. +\`configure' configures ibacm 1.2.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1497,7 +1497,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of ibacm 1.1.0:";; + short | recursive ) echo "Configuration of ibacm 1.2.0:";; esac cat <<\_ACEOF @@ -1601,7 +1601,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -ibacm configure 1.1.0 +ibacm configure 1.2.0 generated by GNU Autoconf 2.67 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2148,7 +2148,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by ibacm $as_me 1.1.0, which was +It was created by ibacm $as_me 1.2.0, which was generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -2966,7 +2966,7 @@ # Define the identity of the package. PACKAGE='ibacm' - VERSION='1.1.0' + VERSION='1.2.0' cat >>confdefs.h <<_ACEOF @@ -11656,6 +11656,26 @@ fi +ac_fn_c_check_header_mongrel "$LINENO" "rdma/rdma_netlink.h" "ac_cv_header_rdma_rdma_netlink_h" "$ac_includes_default" +if test "x$ac_cv_header_rdma_rdma_netlink_h" = x""yes; then : + ac_fn_c_check_header_mongrel "$LINENO" "rdma/ib_user_sa.h" "ac_cv_header_rdma_ib_user_sa_h" "$ac_includes_default" +if test "x$ac_cv_header_rdma_ib_user_sa_h" = x""yes; then : + +$as_echo "#define HAVE_NETLINK 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Missing rdma/ib_user_sa.h" >&5 +$as_echo "$as_me: WARNING: Missing rdma/ib_user_sa.h" >&2;} +fi + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Missing rdma/rdma_netlink.h" >&5 +$as_echo "$as_me: WARNING: Missing rdma/rdma_netlink.h" >&2;} +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler support for atomics" >&5 $as_echo_n "checking compiler support for atomics... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -12257,7 +12277,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by ibacm $as_me 1.1.0, which was +This file was extended by ibacm $as_me 1.2.0, which was generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12323,7 +12343,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -ibacm config.status 1.1.0 +ibacm config.status 1.2.0 configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ibacm-1.1.0/configure.ac new/ibacm-1.2.0/configure.ac --- old/ibacm-1.1.0/configure.ac 2015-07-30 22:54:03.000000000 +0200 +++ new/ibacm-1.2.0/configure.ac 2016-03-18 21:25:13.000000000 +0100 @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ([2.63]) -AC_INIT([ibacm], [1.1.0], [linux-r...@vger.kernel.org]) +AC_INIT([ibacm], [1.2.0], [linux-r...@vger.kernel.org]) AC_CONFIG_SRCDIR([src/acm.c]) AC_CONFIG_AUX_DIR(config) AC_CONFIG_HEADERS([config.h]) @@ -61,6 +61,13 @@ AC_MSG_ERROR([<infiniband/umad.h> not found. Is libibumad installed?])) fi +dnl Check netlink header files +AC_CHECK_HEADER(rdma/rdma_netlink.h, + AC_CHECK_HEADER(rdma/ib_user_sa.h, + AC_DEFINE(HAVE_NETLINK, 1, [Have netlink header files]), + AC_MSG_WARN([Missing rdma/ib_user_sa.h])), + AC_MSG_WARN([Missing rdma/rdma_netlink.h])) + dnl Check for gcc atomic intrinsics AC_MSG_CHECKING(compiler support for atomics) AC_TRY_LINK([int i = 0;], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ibacm-1.1.0/ibacm.spec new/ibacm-1.2.0/ibacm.spec --- old/ibacm-1.1.0/ibacm.spec 2015-07-30 22:58:24.000000000 +0200 +++ new/ibacm-1.2.0/ibacm.spec 2016-03-18 21:51:09.000000000 +0100 @@ -1,5 +1,5 @@ Name: ibacm -Version: 1.1.0 +Version: 1.2.0 Release: 1%{?dist} Summary: InfiniBand Communication Manager Assistant diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ibacm-1.1.0/ibacm.spec.in new/ibacm-1.2.0/ibacm.spec.in --- old/ibacm-1.1.0/ibacm.spec.in 2015-07-30 22:54:10.000000000 +0200 +++ new/ibacm-1.2.0/ibacm.spec.in 2016-03-18 21:25:29.000000000 +0100 @@ -1,5 +1,5 @@ Name: ibacm -Version: 1.1.0 +Version: 1.2.0 Release: 1%{?dist} Summary: InfiniBand Communication Manager Assistant diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ibacm-1.1.0/prov/acmp/src/acmp.c new/ibacm-1.2.0/prov/acmp/src/acmp.c --- old/ibacm-1.1.0/prov/acmp/src/acmp.c 2015-07-30 22:54:10.000000000 +0200 +++ new/ibacm-1.2.0/prov/acmp/src/acmp.c 2016-03-18 21:25:29.000000000 +0100 @@ -46,15 +46,18 @@ #include <infiniband/acm_prov.h> #include <infiniband/umad.h> #include <infiniband/verbs.h> +#include <ifaddrs.h> #include <dlist.h> #include <dlfcn.h> #include <search.h> +#include <netdb.h> #include <net/if.h> #include <sys/ioctl.h> #include <net/if_arp.h> #include <netinet/in.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> +#include "acm_util.h" #include "acm_mad.h" #define src_out data[0] @@ -1739,6 +1742,74 @@ } static int +acmp_check_addr_match(struct ifaddrs *iap, struct acm_ep_addr_data *saddr, + unsigned int d_family) +{ + char sip[INET6_ADDRSTRLEN] = {0}; + char dip[INET6_ADDRSTRLEN] = {0}; + const char *tmp; + size_t sock_size; + unsigned int s_family; + int ret; + + s_family = iap->ifa_addr->sa_family; + + if (!iap->ifa_addr || + !(iap->ifa_flags & IFF_UP) || + (s_family != d_family)) + return -1; + + sock_size = (s_family == AF_INET) ? sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6); + + ret = getnameinfo(iap->ifa_addr, sock_size, + sip, sizeof(sip), + NULL, 0, NI_NUMERICHOST); + + if (ret) + return ret; + + tmp = inet_ntop(d_family, (void *)saddr->info.addr, dip, + sizeof(dip)); + if (!tmp) + return -1; + ret = memcmp(sip, dip, strlen(dip)); + return ret; +} + +static void +acmp_acquire_sgid(struct acm_ep_addr_data *saddr, + struct acmp_dest *dest) +{ + struct ifaddrs *addrs, *iap; + unsigned int d_family; + int ret; + + if (!ib_any_gid(&dest->path.sgid)) + return; + + if (dest->addr_type != ACM_ADDRESS_IP6 && + dest->addr_type != ACM_ADDRESS_IP) + return; + + if (getifaddrs(&addrs)) + return; + + d_family = (dest->addr_type == ACM_ADDRESS_IP) ? AF_INET : AF_INET6; + + for (iap = addrs; iap != NULL; iap = iap->ifa_next) { + ret = acmp_check_addr_match(iap, saddr, d_family); + if (!ret) { + ret = acm_if_get_sgid(iap->ifa_name, + &dest->path.sgid); + if (!ret) + break; + } + } + freeifaddrs(addrs); +} + +static int acmp_resolve_dest(struct acmp_ep *ep, struct acm_msg *msg, uint64_t id) { struct acmp_dest *dest; @@ -1774,6 +1845,7 @@ acm_log(2, "have address, resolving route\n"); acm_increment_counter(ACM_CNTR_ADDR_CACHE); atomic_inc(&ep->counters[ACM_CNTR_ADDR_CACHE]); + acmp_acquire_sgid(saddr, dest); status = acmp_resolve_path_sa(ep, dest, acmp_dest_sa_resp); if (status) { break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ibacm-1.1.0/src/acm.c new/ibacm-1.2.0/src/acm.c --- old/ibacm-1.1.0/src/acm.c 2015-07-30 22:54:10.000000000 +0200 +++ new/ibacm-1.2.0/src/acm.c 2016-03-18 21:25:29.000000000 +0100 @@ -46,6 +46,10 @@ #include <infiniband/acm_prov.h> #include <infiniband/umad.h> #include <infiniband/verbs.h> +#ifdef HAVE_NETLINK +#include <infiniband/umad_types.h> +#include <infiniband/umad_sa.h> +#endif #include <dlist.h> #include <dlfcn.h> #include <search.h> @@ -55,9 +59,18 @@ #include <netinet/in.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> +#ifdef HAVE_NETLINK +#include <rdma/rdma_netlink.h> +#include <rdma/ib_user_sa.h> +#endif #include <poll.h> #include "acm_mad.h" #include "acm_util.h" +#ifdef HAVE_NETLINK +#if !defined(RDMA_NL_LS_F_ERR) + #include "acm_netlink.h" +#endif +#endif #define src_out data[0] #define src_index data[1] @@ -66,6 +79,9 @@ #define MAX_EP_ADDR 4 #define NL_MSG_BUF_SIZE 4096 #define ACM_PROV_NAME_SIZE 64 +#ifdef HAVE_NETLINK +#define NL_CLIENT_INDEX 0 +#endif struct acmc_subnet { DLIST_ENTRY entry; @@ -106,7 +122,8 @@ union ibv_gid *gid_tbl; uint16_t lid; uint16_t lid_mask; - int default_pkey_index; + int sa_pkey_index; + uint16_t def_acm_pkey; }; struct acmc_device { @@ -151,6 +168,23 @@ struct acm_sa_mad mad; }; +#ifdef HAVE_NETLINK +struct acm_nl_path { + struct nlattr attr_hdr; + struct ib_path_rec_data rec; +}; + +struct acm_nl_msg { + struct nlmsghdr nlmsg_header; + union { + uint8_t data[ACM_MSG_DATA_LENGTH]; + struct rdma_ls_resolve_header resolve_header; + struct nlattr attr[0]; + struct acm_nl_path path[0]; + }; +}; +#endif + static char def_prov_name[ACM_PROV_NAME_SIZE] = "ibacmp"; static DLIST_ENTRY provider_list; static struct acmc_prov *def_provider = NULL; @@ -172,6 +206,9 @@ static int acm_ep_insert_addr(struct acmc_ep *ep, const char *name, uint8_t *addr, size_t addr_len, uint8_t addr_type); static void acm_event_handler(struct acmc_device *dev); +#ifdef HAVE_NETLINK +static int acm_nl_send(SOCKET sock, struct acm_msg *msg); +#endif static struct sa_data { int timeout; @@ -466,7 +503,13 @@ goto release; } - ret = send(client->sock, (char *) msg, msg->hdr.length, 0); +#ifdef HAVE_NETLINK + if (id == NL_CLIENT_INDEX) + ret = acm_nl_send(client->sock, msg); + else +#endif + ret = send(client->sock, (char *) msg, msg->hdr.length, 0); + if (ret != msg->hdr.length) acm_log(0, "ERROR - failed to send response\n"); else @@ -597,6 +640,10 @@ } for (i = 0; i < FD_SETSIZE - 1; i++) { + #ifdef HAVE_NETLINK + if (i == NL_CLIENT_INDEX) + continue; + #endif if (!atomic_get(&client_array[i].refcnt)) break; } @@ -1346,6 +1393,330 @@ } } +#ifdef HAVE_NETLINK +static int acm_nl_send(SOCKET sock, struct acm_msg *msg) +{ + struct sockaddr_nl dst_addr; + struct acm_nl_msg acmnlmsg; + struct acm_nl_msg *orig; + int ret; + int datalen; + + orig = (struct acm_nl_msg *) msg->hdr.tid; + + memset(&dst_addr, 0, sizeof(dst_addr)); + dst_addr.nl_family = AF_NETLINK; + dst_addr.nl_groups = (1 << (RDMA_NL_GROUP_LS - 1)); + + memset(&acmnlmsg, 0, sizeof(acmnlmsg)); + acmnlmsg.nlmsg_header.nlmsg_len = NLMSG_HDRLEN; + acmnlmsg.nlmsg_header.nlmsg_pid = getpid(); + acmnlmsg.nlmsg_header.nlmsg_type = orig->nlmsg_header.nlmsg_type; + acmnlmsg.nlmsg_header.nlmsg_seq = orig->nlmsg_header.nlmsg_seq; + + if (msg->hdr.status != ACM_STATUS_SUCCESS) { + acm_log(2, "acm status no success = %d\n", msg->hdr.status); + acmnlmsg.nlmsg_header.nlmsg_flags |= RDMA_NL_LS_F_ERR; + } else { + acm_log(2, "acm status success\n"); + acmnlmsg.nlmsg_header.nlmsg_len += + NLA_ALIGN(sizeof(struct acm_nl_path)); + acmnlmsg.path[0].attr_hdr.nla_type = LS_NLA_TYPE_PATH_RECORD; + acmnlmsg.path[0].attr_hdr.nla_len = sizeof(struct acm_nl_path); + if (orig->resolve_header.path_use == + LS_RESOLVE_PATH_USE_UNIDIRECTIONAL) + acmnlmsg.path[0].rec.flags = IB_PATH_PRIMARY | + IB_PATH_OUTBOUND; + else + acmnlmsg.path[0].rec.flags = IB_PATH_PRIMARY | + IB_PATH_GMP | IB_PATH_BIDIRECTIONAL; + memcpy(acmnlmsg.path[0].rec.path_rec, + &msg->resolve_data[0].info.path, + sizeof(struct ibv_path_record)); + } + + datalen = NLMSG_ALIGN(acmnlmsg.nlmsg_header.nlmsg_len); + ret = sendto(sock, &acmnlmsg, datalen, 0, + (const struct sockaddr *)&dst_addr, + (socklen_t)sizeof(dst_addr)); + if (ret != datalen) { + acm_log(0, "ERROR - sendto = %d errno = %d\n", ret, errno); + ret = -1; + } else { + ret = msg->hdr.length; + } + + free(orig); + + return ret; +} + +#define NLA_LEN(nla) ((nla)->nla_len - NLA_HDRLEN) +#define NLA_DATA(nla) ((char *)(nla) + NLA_HDRLEN) + +static int acm_nl_parse_path_attr(struct nlattr *attr, + struct acm_ep_addr_data *data) +{ + struct ibv_path_record *path; + uint64_t *sid; + struct rdma_nla_ls_gid *gid; + uint8_t *tcl; + uint16_t *pkey; + uint16_t *qos; + uint16_t val; + int ret = 0; + +#define IBV_PATH_RECORD_QOS_MASK 0xfff0 + + path = &data->info.path; + switch (attr->nla_type & RDMA_NLA_TYPE_MASK) { + case LS_NLA_TYPE_SERVICE_ID: + sid = (uint64_t *) NLA_DATA(attr); + if (NLA_LEN(attr) == sizeof(*sid)) { + acm_log(2, "service_id 0x%llx\n", *sid); + path->service_id = htonll(*sid); + } else { + ret = -1; + } + break; + + case LS_NLA_TYPE_DGID: + gid = (struct rdma_nla_ls_gid *) NLA_DATA(attr); + if (NLA_LEN(attr) == sizeof(gid->gid)) { + acm_format_name(2, log_data, sizeof(log_data), + ACM_ADDRESS_GID, gid->gid, + sizeof(union ibv_gid)); + acm_log(2, "path dgid %s\n", log_data); + memcpy(path->dgid.raw, gid->gid, sizeof(path->dgid)); + data->flags |= ACM_EP_FLAG_DEST; + } else { + ret = -1; + } + break; + + case LS_NLA_TYPE_SGID: + gid = (struct rdma_nla_ls_gid *) NLA_DATA(attr); + if (NLA_LEN(attr) == sizeof(gid->gid)) { + acm_format_name(2, log_data, sizeof(log_data), + ACM_ADDRESS_GID, gid->gid, + sizeof(union ibv_gid)); + acm_log(2, "path sgid %s\n", log_data); + memcpy(path->sgid.raw, gid->gid, sizeof(path->sgid)); + data->flags |= ACM_EP_FLAG_SOURCE; + } else { + ret = -1; + } + break; + + case LS_NLA_TYPE_TCLASS: + tcl = (uint8_t *) NLA_DATA(attr); + if (NLA_LEN(attr) == sizeof(*tcl)) { + acm_log(2, "tclass 0x%x\n", *tcl); + path->tclass = *tcl; + } else { + ret = -1; + } + break; + + case LS_NLA_TYPE_PKEY: + pkey = (uint16_t *) NLA_DATA(attr); + if (NLA_LEN(attr) == sizeof(*pkey)) { + acm_log(2, "pkey 0x%x\n", *pkey); + path->pkey = htons(*pkey); + } else { + ret = -1; + } + break; + + case LS_NLA_TYPE_QOS_CLASS: + qos = (uint16_t *) NLA_DATA(attr); + if (NLA_LEN(attr) == sizeof(*qos)) { + acm_log(2, "qos_class 0x%x\n", *qos); + val = ntohs(path->qosclass_sl); + val &= ~IBV_PATH_RECORD_QOS_MASK; + val |= (*qos & IBV_PATH_RECORD_QOS_MASK); + path->qosclass_sl = htons(val); + } else { + ret = -1; + } + break; + + default: + acm_log(1, "WARN: unknown attr %x\n", attr->nla_type); + /* We can not ignore a mandatory attribute */ + if (attr->nla_type & RDMA_NLA_F_MANDATORY) + ret = -1; + break; + } + + return ret; +} + +static void acm_nl_process_invalid_request(struct acmc_client *client, + struct acm_nl_msg *acmnlmsg) +{ + struct acm_msg msg; + + memset(&msg, 0, sizeof(msg)); + msg.hdr.opcode = ACM_OP_RESOLVE; + msg.hdr.version = ACM_VERSION; + msg.hdr.length = ACM_MSG_HDR_LENGTH; + msg.hdr.status = ACM_STATUS_EINVAL; + msg.hdr.tid = (uint64_t) acmnlmsg; + + acm_nl_send(client->sock, &msg); +} + +static void acm_nl_process_resolve(struct acmc_client *client, + struct acm_nl_msg *acmnlmsg) +{ + struct acm_msg msg; + struct nlattr *attr; + int payload_len; + int resolve_hdr_len; + int rem; + int total_attr_len; + int status; + unsigned char *data; + + memset(&msg, 0, sizeof(msg)); + msg.hdr.opcode = ACM_OP_RESOLVE; + msg.hdr.version = ACM_VERSION; + msg.hdr.length = ACM_MSG_HDR_LENGTH + ACM_MSG_EP_LENGTH; + msg.hdr.status = ACM_STATUS_SUCCESS; + msg.hdr.tid = (uint64_t) acmnlmsg; + msg.resolve_data[0].type = ACM_EP_INFO_PATH; + + /* We support only one pathrecord */ + acm_log(2, "path use 0x%x\n", acmnlmsg->resolve_header.path_use); + if (acmnlmsg->resolve_header.path_use == + LS_RESOLVE_PATH_USE_UNIDIRECTIONAL) + msg.resolve_data[0].info.path.reversible_numpath = 1; + else + msg.resolve_data[0].info.path.reversible_numpath = + IBV_PATH_RECORD_REVERSIBLE | 1; + + data = (unsigned char *) &acmnlmsg->nlmsg_header + NLMSG_HDRLEN; + resolve_hdr_len = NLMSG_ALIGN(sizeof(struct rdma_ls_resolve_header)); + attr = (struct nlattr *) (data + resolve_hdr_len); + payload_len = acmnlmsg->nlmsg_header.nlmsg_len - NLMSG_HDRLEN - + resolve_hdr_len; + rem = payload_len; + while (1) { + if (rem < (int) sizeof(*attr) || + attr->nla_len < sizeof(*attr) || + attr->nla_len > rem) + break; + + status = acm_nl_parse_path_attr(attr, &msg.resolve_data[0]); + if (status) { + acm_nl_process_invalid_request(client, acmnlmsg); + return; + } + + /* Next attribute */ + total_attr_len = NLA_ALIGN(attr->nla_len); + rem -= total_attr_len; + attr = (struct nlattr *) ((char *) attr + total_attr_len); + } + + atomic_inc(&counter[ACM_CNTR_RESOLVE]); + acm_svr_resolve(client, &msg); +} + +static int acm_nl_is_valid_resolve_request(struct acm_nl_msg *acmnlmsg) +{ + int payload_len; + + payload_len = acmnlmsg->nlmsg_header.nlmsg_len - NLMSG_HDRLEN; + if (payload_len < (sizeof(struct rdma_ls_resolve_header) + + sizeof(struct nlattr))) + return 0; + + return 1; +} + +static void acm_nl_receive(struct acmc_client *client) +{ + struct acm_nl_msg *acmnlmsg; + int datalen = sizeof(*acmnlmsg); + int ret; + uint16_t client_inx, op; + + acmnlmsg = calloc(1, sizeof(*acmnlmsg)); + if (!acmnlmsg) { + acm_log(0, "Out of memory for recving nl msg.\n"); + return; + } + ret = recv(client->sock, acmnlmsg, datalen, 0); + if (!NLMSG_OK(&acmnlmsg->nlmsg_header, ret)) { + acm_log(0, "Netlink receive error: %d.\n", ret); + goto rcv_cleanup; + } + + acm_log(2, "nlmsg: len %d type 0x%x flags 0x%x seq %d pid %d\n", + acmnlmsg->nlmsg_header.nlmsg_len, + acmnlmsg->nlmsg_header.nlmsg_type, + acmnlmsg->nlmsg_header.nlmsg_flags, + acmnlmsg->nlmsg_header.nlmsg_seq, + acmnlmsg->nlmsg_header.nlmsg_pid); + + /* Currently we handle only request from the local service client */ + client_inx = RDMA_NL_GET_CLIENT(acmnlmsg->nlmsg_header.nlmsg_type); + op = RDMA_NL_GET_OP(acmnlmsg->nlmsg_header.nlmsg_type); + if (client_inx != RDMA_NL_LS) + goto rcv_cleanup; + + switch (op) { + case RDMA_NL_LS_OP_RESOLVE: + if (acm_nl_is_valid_resolve_request(acmnlmsg)) + acm_nl_process_resolve(client, acmnlmsg); + else + acm_nl_process_invalid_request(client, acmnlmsg); + break; + default: + /* Not supported*/ + acm_log(1, "WARN - invalid opcode %x\n", op); + acm_nl_process_invalid_request(client, acmnlmsg); + break; + } + + return; +rcv_cleanup: + free(acmnlmsg); +} + +static int acm_init_nl(void) +{ + struct sockaddr_nl src_addr; + int ret; + SOCKET nl_rcv_socket; + + nl_rcv_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_RDMA); + if (nl_rcv_socket == INVALID_SOCKET) { + acm_log(0, "ERROR - unable to allocate netlink recv socket\n"); + return socket_errno(); + } + + memset(&src_addr, 0, sizeof(src_addr)); + src_addr.nl_family = AF_NETLINK; + src_addr.nl_pid = getpid(); + src_addr.nl_groups = (1 << (RDMA_NL_GROUP_LS - 1)); + + ret = bind(nl_rcv_socket, (struct sockaddr *)&src_addr, + sizeof(src_addr)); + if (ret == SOCKET_ERROR) { + acm_log(0, "ERROR - unable to bind netlink socket\n"); + close(nl_rcv_socket); + return socket_errno(); + } + + /* init nl client structure */ + client_array[NL_CLIENT_INDEX].sock = nl_rcv_socket; + return 0; +} +#endif + static void acm_server(void) { fd_set readfds; @@ -1360,12 +1731,16 @@ acm_log(0, "ERROR - server listen failed\n"); return; } +#ifdef HAVE_NETLINK + ret = acm_init_nl(); + if (ret) + acm_log(1, "Warn - Netlink init failed\n"); +#endif while (1) { n = (int) listen_socket; FD_ZERO(&readfds); FD_SET(listen_socket, &readfds); - n = max(n, (int) ip_mon_socket); FD_SET(ip_mon_socket, &readfds); @@ -1399,7 +1774,12 @@ if (client_array[i].sock != INVALID_SOCKET && FD_ISSET(client_array[i].sock, &readfds)) { acm_log(2, "receiving from client %d\n", i); - acm_svr_receive(&client_array[i]); + #ifdef HAVE_NETLINK + if (i == NL_CLIENT_INDEX) + acm_nl_receive(&client_array[i]); + else + #endif + acm_svr_receive(&client_array[i]); } } @@ -1652,7 +2032,7 @@ continue; } } else { - pkey = 0xFFFF; + pkey = ep->port->def_acm_pkey; } if (!stricmp(dev_name, dev) && @@ -1846,6 +2226,7 @@ int i, ret; struct acmc_prov_context *dev_ctx; int index = -1; + uint16_t first_pkey = 0; acm_log(1, "%s %d\n", port->dev->device.verbs->device->name, port->port.port_num); @@ -1891,15 +2272,18 @@ goto err1; } - /* Determine the default pkey first. - Order of preference: 0xffff, 0x7fff, first pkey - */ + /* Determine the default pkey for SA access first. + * Order of preference: 0xffff, 0x7fff + * Use the first pkey as the default pkey for parsing address file. + */ for (i = 0; i < attr.pkey_tbl_len; i++) { ret = ibv_query_pkey(port->dev->device.verbs, port->port.port_num, i, &pkey); if (ret) continue; pkey = ntohs(pkey); + if (i == 0) + first_pkey = pkey; if (pkey == 0xffff) { index = i; break; @@ -1908,7 +2292,8 @@ index = i; } } - port->default_pkey_index = index < 0 ? 0: index; + port->sa_pkey_index = index < 0 ? 0 : index; + port->def_acm_pkey = first_pkey; for (i = 0; i < attr.pkey_tbl_len; i++) { ret = ibv_query_pkey(port->dev->device.verbs, @@ -2418,7 +2803,7 @@ mad->umad.addr.qkey = port->sa_addr.qkey; mad->umad.addr.lid = htons(port->sa_addr.lid); mad->umad.addr.sl = port->sa_addr.sl; - mad->umad.addr.pkey_index = req->ep->port->default_pkey_index; + mad->umad.addr.pkey_index = req->ep->port->sa_pkey_index; lock_acquire(&port->lock); if (port->sa_credits && DListEmpty(&port->sa_wait)) { @@ -2756,6 +3141,10 @@ acm_server(); acm_log(0, "shutting down\n"); +#ifdef HAVE_NETLINK + if (client_array[NL_CLIENT_INDEX].sock != INVALID_SOCKET) + close(client_array[NL_CLIENT_INDEX].sock); +#endif acm_close_providers(); acm_stop_sa_handler(); umad_done(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ibacm-1.1.0/src/acm_netlink.h new/ibacm-1.2.0/src/acm_netlink.h --- old/ibacm-1.1.0/src/acm_netlink.h 1970-01-01 01:00:00.000000000 +0100 +++ new/ibacm-1.2.0/src/acm_netlink.h 2016-03-18 21:25:29.000000000 +0100 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2015 Intel Corporation. All rights reserved. + * + * This software is available to you under the OpenFabrics.org BSD license + * below: + * + * 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. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if !defined(ACM_NETLINK_H) +#define ACM_NETLINK_H + +/* + * This header file basically copies the local service related defines and + * structures from the latest kernel include/uapi/rdma/rdma_netlink.h file + * so that ibacm can be built without the latest kernel patches. + */ + +enum { + RDMA_NL_LS = 4, /* RDMA Local Services */ +}; + +enum { + RDMA_NL_GROUP_LS = 3, +}; + +/* + * Local service operations: + * RESOLVE - The client requests the local service to resolve a path. + * SET_TIMEOUT - The local service requests the client to set the timeout. + */ +enum { + RDMA_NL_LS_OP_RESOLVE = 0, + RDMA_NL_LS_OP_SET_TIMEOUT, + RDMA_NL_LS_NUM_OPS +}; + +/* Local service netlink message flags */ +#define RDMA_NL_LS_F_ERR 0x0100 /* Failed response */ + +/* + * Local service resolve operation family header. + * The layout for the resolve operation: + * nlmsg header + * family header + * attributes + */ + +/* + * Local service path use: + * Specify how the path(s) will be used. + * ALL - For connected CM operation (6 pathrecords) + * UNIDIRECTIONAL - For unidirectional UD (1 pathrecord) + * GMP - For miscellaneous GMP like operation (at least 1 reversible + * pathrecord) + */ +enum { + LS_RESOLVE_PATH_USE_ALL = 0, + LS_RESOLVE_PATH_USE_UNIDIRECTIONAL, + LS_RESOLVE_PATH_USE_GMP, + LS_RESOLVE_PATH_USE_MAX +}; + +#define LS_DEVICE_NAME_MAX 64 + +struct rdma_ls_resolve_header { + __u8 device_name[LS_DEVICE_NAME_MAX]; + __u8 port_num; + __u8 path_use; +}; + +/* Local service attribute type */ +#define RDMA_NLA_F_MANDATORY (1 << 13) +#define RDMA_NLA_TYPE_MASK (~(NLA_F_NESTED | NLA_F_NET_BYTEORDER | \ + RDMA_NLA_F_MANDATORY)) + +/* + * Local service attributes: + * Attr Name Size Byte order + * ----------------------------------------------------- + * PATH_RECORD struct ib_path_rec_data + * TIMEOUT u32 cpu + * SERVICE_ID u64 cpu + * DGID u8[16] BE + * SGID u8[16] BE + * TCLASS u8 + * PKEY u16 cpu + * QOS_CLASS u16 cpu + */ +enum { + LS_NLA_TYPE_UNSPEC = 0, + LS_NLA_TYPE_PATH_RECORD, + LS_NLA_TYPE_TIMEOUT, + LS_NLA_TYPE_SERVICE_ID, + LS_NLA_TYPE_DGID, + LS_NLA_TYPE_SGID, + LS_NLA_TYPE_TCLASS, + LS_NLA_TYPE_PKEY, + LS_NLA_TYPE_QOS_CLASS, + LS_NLA_TYPE_MAX +}; + +/* Local service DGID/SGID attribute: big endian */ +struct rdma_nla_ls_gid { + __u8 gid[16]; +}; + +#endif /* ACM_NETLINK_H */