Skip to contentSkip to conversation

ibacm: Implement dynamic IP support

PATCH In review [email protected] 3 participants 21 messages Mar 28, 2014 5 messages not in the archive

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover ibacm: Implement dynamic IP support

From: Sean Hefty <[email protected]>

The following patch series implements dynamic system IP address updates for ibacm. System IP's are read at start up and Netlink is monitored to respond to system IP address changes.

IP's are no longer required or supported in ibacm_addr.cfg after this series. Support for ibacm_addr.cfg was maintained through the first 13 patches in case this feature breaks some user in some unforeseen way.

Ira

--
Sending this on Ira's behalf, who is experiencing technical difficulties.

- Sean

Ira Weiny (16):
ibacm: get_devaddr remove unused variable from signature
ibacm: pass interface name rather than 'struct ifreq' to get_devaddr,
get_sgid, and get_pkey
ibacm: use sysfs (in acm_if_is_ib) rather than ioctl(...
SIOCGIFHWADDR ...) to read interface type
ibacm: move sysfs helper functions to acm_util 'module'
ibacm: Move calling of helper functions out of get_devaddr
ibacm: move acm_if_iter_sys to acm_util.c
ibacm: convert logging in acm_util.c to acm_log
ibacm: add separate acm_ep_insert_addr function
ibacm: read system IP's into endpoints at startup
ibacm: add locking around end point address arrays
ibacm: Add thread to monitor IP address changes
ibacm: add/remove addr's in EP's when added/removed from the system.
ibacm: fix handling of aliased IPoIB devices
ibacm: ib_acme remove IP addresses from ibacm_addr.cfg file
generation
ibacm: remove acm_if_iter_sys function
ibacm: remove processing of IP's from ibacm_addr.cfg

 Makefile.am        |   10 +-
 linux/acme_linux.c |  217 ---------------------------
 man/ib_acme.1      |    3 +-
 src/acm.c          |  419 +++++++++++++++++++++++++++++++++++++++++++++++++---
 src/acm_util.c     |  124 ++++++++++++++++
 src/acm_util.h     |   51 +++++++
 src/acme.c         |   13 +-
 7 files changed, 581 insertions(+), 256 deletions(-)
 delete mode 100644 linux/acme_linux.c
 create mode 100644 src/acm_util.c
 create mode 100644 src/acm_util.h
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 1395985810-23822-1-git-send-email-sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#2 lore raw

PATCH 1/16 ibacm: get_devaddr remove unused variable from signature

From: Ira Weiny <[email protected]>

---
 linux/acme_linux.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
linux/acme_linux.c +2 -2
index ef5b107..6978db7 100644
@@ -102,7 +102,7 @@ get_sgid(struct ifreq *ifr, union ibv_gid *sgid)
 }
 
 static int
-get_devaddr(int s, struct ifreq *ifr,
+get_devaddr(struct ifreq *ifr,
 	int *dev_index, uint8_t *port, uint16_t *pkey)
 {
 	struct ibv_device_attr dev_attr;
@@ -199,7 +199,7 @@ int gen_addr_ip(FILE *f)
 		if (ifr[i].ifr_hwaddr.sa_family != ARPHRD_INFINIBAND)
 			continue;
 
-		ret = get_devaddr(s, &ifr[i], &dev_index, &port, &pkey);
+		ret = get_devaddr(&ifr[i], &dev_index, &port, &pkey);
 		if (ret)
 			continue;
 
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#3 lore raw

PATCH 2/16 ibacm: pass interface name rather than 'struct ifreq' to get_devaddr, get_sgid, and get_pkey

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

---
 linux/acme_linux.c |   17 ++++++++---------
 1 files changed, 8 insertions(+), 9 deletions(-)
linux/acme_linux.c +8 -9
index 6978db7..201ff19 100644
@@ -47,13 +47,13 @@ extern int verbose;
 
 
 static int
-get_pkey(struct ifreq *ifreq, uint16_t *pkey)
+get_pkey(char *ifname, uint16_t *pkey)
 {
 	char buf[128], *end;
 	FILE *f;
 	int ret;
 
-	snprintf(buf, sizeof buf, "//sys//class//net//%s//pkey", ifreq->ifr_name);
+	snprintf(buf, sizeof buf, "//sys//class//net//%s//pkey", ifname);
 	f = fopen(buf, "r");
 	if (!f) {
 		printf("failed to open %s\n", buf);
@@ -73,13 +73,13 @@ get_pkey(struct ifreq *ifreq, uint16_t *pkey)
 }
 
 static int
-get_sgid(struct ifreq *ifr, union ibv_gid *sgid)
+get_sgid(char *ifname, union ibv_gid *sgid)
 {
 	char buf[128], *end;
 	FILE *f;
 	int i, p, ret;
 
-	snprintf(buf, sizeof buf, "//sys//class//net//%s//address", ifr->ifr_name);
+	snprintf(buf, sizeof buf, "//sys//class//net//%s//address", ifname);
 	f = fopen(buf, "r");
 	if (!f) {
 		printf("failed to open %s\n", buf);
@@ -102,21 +102,20 @@ get_sgid(struct ifreq *ifr, union ibv_gid *sgid)
 }
 
 static int
-get_devaddr(struct ifreq *ifr,
-	int *dev_index, uint8_t *port, uint16_t *pkey)
+get_devaddr(char *ifname, int *dev_index, uint8_t *port, uint16_t *pkey)
 {
 	struct ibv_device_attr dev_attr;
 	struct ibv_port_attr port_attr;
 	union ibv_gid sgid, gid;
 	int ret, i;
 
-	ret = get_sgid(ifr, &sgid);
+	ret = get_sgid(ifname, &sgid);
 	if (ret) {
 		printf("unable to get sgid\n");
 		return ret;
 	}
 
-	ret = get_pkey(ifr, pkey);
+	ret = get_pkey(ifname, pkey);
 	if (ret) {
 		printf("unable to get pkey\n");
 		return ret;
@@ -199,7 +198,7 @@ int gen_addr_ip(FILE *f)
 		if (ifr[i].ifr_hwaddr.sa_family != ARPHRD_INFINIBAND)
 			continue;
 
-		ret = get_devaddr(&ifr[i], &dev_index, &port, &pkey);
+		ret = get_devaddr(ifr[i].ifr_name, &dev_index, &port, &pkey);
 		if (ret)
 			continue;
 
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#4 lore raw

PATCH 3/16 ibacm: use sysfs (in acm_if_is_ib) rather than ioctl(... SIOCGIFHWADDR ...) to read interface type

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

Getting an interface type from sysfs is easier than using an ioctl when an interface name is readily available (as is the case with netlink.)

In preparation for netlink support create a function which uses sysfs and use it instead of ioctls.

---
 linux/acme_linux.c |   34 +++++++++++++++++++++++++++-------
 1 files changed, 27 insertions(+), 7 deletions(-)
linux/acme_linux.c +27 -7
index 201ff19..0bd1f75 100644
@@ -38,6 +38,7 @@
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <sys/types.h>
+#include <errno.h>
 
 #include <infiniband/verbs.h>
 
@@ -101,6 +102,31 @@ get_sgid(char *ifname, union ibv_gid *sgid)
 	return ret;
 }
 
+static int acm_if_is_ib(char *ifname)
+{
+	unsigned type;
+	char buf[128];
+	FILE *f;
+	int ret;
+
+	snprintf(buf, sizeof buf, "//sys//class//net//%s//type", ifname);
+	f = fopen(buf, "r");
+	if (!f) {
+		printf("failed to open %s\n", buf);
+		return 0;
+	}
+
+	if (fgets(buf, sizeof buf, f)) {
+		type = strtol(buf, NULL, 0);
+		ret = (type == ARPHRD_INFINIBAND);
+	} else {
+		ret = 0;
+	}
+
+	fclose(f);
+	return ret;
+}
+
 static int
 get_devaddr(char *ifname, int *dev_index, uint8_t *port, uint16_t *pkey)
 {
@@ -189,13 +215,7 @@ int gen_addr_ip(FILE *f)
 			continue;
 		}
 
-		ret = ioctl(s, SIOCGIFHWADDR, &ifr[i]);
-		if (ret) {
-			printf("failed to get hw address %d\n", ret);
-			continue;
-		}
-
-		if (ifr[i].ifr_hwaddr.sa_family != ARPHRD_INFINIBAND)
+		if (!acm_if_is_ib(ifr[i].ifr_name))
 			continue;
 
 		ret = get_devaddr(ifr[i].ifr_name, &dev_index, &port, &pkey);
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#5 lore raw

PATCH 4/16 ibacm: move sysfs helper functions to acm_util 'module'

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

This is in preparation for these functions to be included ib both ibacm and ib_acme build.

Also rename to more global appropriate name acm_if_*

---
 Makefile.am        |    7 ++-
 linux/acme_linux.c |   87 +---------------------------------------
 src/acm_util.c     |  112 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/acm_util.h     |   39 ++++++++++++++++++
 src/acme.c         |    1 +
 5 files changed, 159 insertions(+), 87 deletions(-)
 create mode 100644 src/acm_util.c
 create mode 100644 src/acm_util.h
Makefile.am +4 -3
index 57021e0..539ef83 100644
@@ -1,11 +1,12 @@
-AM_CPPFLAGS = -I$(srcdir)/include -I$(srcdir)/linux
+AM_CPPFLAGS = -I$(srcdir)/include -I$(srcdir)/linux -I$(srcdir)/src
 
 AM_CFLAGS = -g -Wall -D_GNU_SOURCE -DSYSCONFDIR=\"$(sysconfdir)\" -DBINDIR=\"$(bindir)\" -DRDMADIR=\"@rdmadir@\"
 
 bin_PROGRAMS = util/ib_acme
 sbin_PROGRAMS = svc/ibacm
 svc_ibacm_SOURCES = src/acm.c
-util_ib_acme_SOURCES = src/acme.c linux/acme_linux.c src/libacm.c linux/libacm_linux.c src/parse.c
+util_ib_acme_SOURCES = src/acme.c linux/acme_linux.c src/libacm.c linux/libacm_linux.c \
+			src/parse.c src/acm_util.c
 svc_ibacm_CFLAGS = $(AM_CFLAGS)
 util_ib_acme_CFLAGS = $(AM_CFLAGS)
 
@@ -18,7 +19,7 @@ man_MANS = \
 	man/ibacm.1 \
 	man/ibacm.7
 
-EXTRA_DIST = src/acm_mad.h src/libacm.h ibacm.init.in \
+EXTRA_DIST = src/acm_util.h src/acm_mad.h src/libacm.h ibacm.init.in \
 	     linux/osd.h linux/dlist.h ibacm.spec.in $(man_MANS) ibacm_hosts.data
 
 install-exec-hook:
linux/acme_linux.c +3 -84

115 lines not on this page · raw message

src/acm_util.c new file +112 -0

112 lines not on this page · raw message

src/acm_util.h new file +39 -0
new file mode 100644
index 0000000..94aac9d
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 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_IF_H)
+#define ACM_IF_H
+
+#include <infiniband/verbs.h>
+
+int acm_if_is_ib(char *ifname);
+int acm_if_get_pkey(char *ifname, uint16_t *pkey);
+int acm_if_get_sgid(char *ifname, union ibv_gid *sgid);
+
+#endif /* ACM_IF_H */
src/acme.c +1 -0
index b122e58..fbe9dbc 100644
@@ -43,6 +43,7 @@
 #include <infiniband/verbs.h>
 #include <infiniband/acm.h>
 #include "libacm.h"
+#include "acm_util.h"
 
 static char *dest_dir = ACM_CONF_DIR;
 static char *addr_file = ACM_ADDR_FILE;
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#6 lore raw

PATCH 5/16 ibacm: Move calling of helper functions out of get_devaddr

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

Again this is in prep for sharing this code with ibacm and ib_acme

get_devaddr uses globals which are specific to ib_acme. Move toward this function being ib_acme specific while the code in get_addr_ip becomes generic.

---
 linux/acme_linux.c |   64 ++++++++++++++++++++++++++++++++++------------------
 src/acm_util.h     |    5 ++++
 2 files changed, 47 insertions(+), 22 deletions(-)
linux/acme_linux.c +42 -22
index b246a9c..187507d 100644
@@ -47,25 +47,13 @@ extern int dev_cnt;
 extern int verbose;
 
 static int
-get_devaddr(char *ifname, int *dev_index, uint8_t *port, uint16_t *pkey)
+get_devaddr(union ibv_gid *sgid, int *dev_index, uint8_t *port)
 {
 	struct ibv_device_attr dev_attr;
 	struct ibv_port_attr port_attr;
-	union ibv_gid sgid, gid;
+	union ibv_gid gid;
 	int ret, i;
 
-	ret = acm_if_get_sgid(ifname, &sgid);
-	if (ret) {
-		printf("unable to get sgid\n");
-		return ret;
-	}
-
-	ret = acm_if_get_pkey(ifname, pkey);
-	if (ret) {
-		printf("unable to get pkey\n");
-		return ret;
-	}
-
 	for (*dev_index = 0; *dev_index < dev_cnt; (*dev_index)++) {
 		ret = ibv_query_device(verbs[*dev_index], &dev_attr);
 		if (ret)
@@ -81,7 +69,7 @@ get_devaddr(char *ifname, int *dev_index, uint8_t *port, uint16_t *pkey)
 				if (ret || !gid.global.interface_id)
 					break;
 
-				if (!memcmp(sgid.raw, gid.raw, sizeof gid))
+				if (!memcmp(sgid->raw, gid.raw, sizeof gid))
 					return 0;
 			}
 		}
@@ -89,14 +77,39 @@ get_devaddr(char *ifname, int *dev_index, uint8_t *port, uint16_t *pkey)
 	return -1;
 }
 
+static void iter_cb(char *ifname, union ibv_gid *gid, uint16_t pkey,
+		uint8_t addr_type, uint8_t *addr, size_t addr_len,
+		char *addr_name, void *ctx)
+{
+	FILE *f = (FILE *)ctx;
+	int ret;
+	int dev_index;
+	uint8_t port;
+
+	ret = get_devaddr(gid, &dev_index, &port);
+	if (ret) {
+		printf("Failed to find verbs device for %s\n", ifname);
+		return;
+	}
+
+	if (verbose)
+		printf("%s %s %d 0x%x\n", addr_name, verbs[dev_index]->device->name, port, pkey);
+	fprintf(f, "%s %s %d 0x%x\n", addr_name, verbs[dev_index]->device->name, port, pkey);
+}
+
 int gen_addr_ip(FILE *f)
 {
+	return acm_if_iter_sys(iter_cb, (void *)f);
+}
+
+int acm_if_iter_sys(acm_if_iter_cb cb, void *ctx)
+{
 	struct ifconf *ifc;
 	struct ifreq *ifr;
 	char ip[INET6_ADDRSTRLEN];
-	int s, ret, dev_index, i, len;
+	int s, ret, i, len;
 	uint16_t pkey;
-	uint8_t port;
+	union ibv_gid sgid;
 
 	s = socket(AF_INET6, SOCK_DGRAM, 0);
 	if (!s)
@@ -137,13 +150,19 @@ int gen_addr_ip(FILE *f)
 		if (!acm_if_is_ib(ifr[i].ifr_name))
 			continue;
 
-		ret = get_devaddr(ifr[i].ifr_name, &dev_index, &port, &pkey);
-		if (ret)
+		ret = acm_if_get_sgid(ifr[i].ifr_name, &sgid);
+		if (ret) {
+			printf("unable to get sgid\n");
+			continue;
+		}
+
+		ret = acm_if_get_pkey(ifr[i].ifr_name, &pkey);
+		if (ret) {
+			printf("unable to get pkey\n");
 			continue;
+		}
 
-		if (verbose)
-			printf("%s %s %d 0x%x\n", ip, verbs[dev_index]->device->name, port, pkey);
-		fprintf(f, "%s %s %d 0x%x\n", ip, verbs[dev_index]->device->name, port, pkey);
+		cb(ifr[i].ifr_name, &sgid, pkey, 0, NULL, 0, ip, ctx);
 	}
 	ret = 0;
 
@@ -152,4 +171,5 @@ out2:
 out1:
 	close(s);
 	return ret;
+
 }
src/acm_util.h +5 -0
index 94aac9d..ea86133 100644
@@ -36,4 +36,9 @@ int acm_if_is_ib(char *ifname);
 int acm_if_get_pkey(char *ifname, uint16_t *pkey);
 int acm_if_get_sgid(char *ifname, union ibv_gid *sgid);
 
+typedef void (*acm_if_iter_cb)(char *ifname, union ibv_gid *gid, uint16_t pkey,
+				uint8_t addr_type, uint8_t *addr, size_t addr_len,
+				char *addr_name, void *ctx);
+int acm_if_iter_sys(acm_if_iter_cb cb, void *ctx);
+
 #endif /* ACM_IF_H */
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#7 lore raw

PATCH 6/16 ibacm: move acm_if_iter_sys to acm_util.c

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

---
 linux/acme_linux.c |   80 ---------------------------------------------------
 src/acm_util.c     |   81 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 80 deletions(-)
linux/acme_linux.c +0 -80
index 187507d..33fafd2 100644
@@ -30,14 +30,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <errno.h>
 
 #include <infiniband/verbs.h>
 #include "acm_util.h"
@@ -101,75 +93,3 @@ int gen_addr_ip(FILE *f)
 {
 	return acm_if_iter_sys(iter_cb, (void *)f);
 }
-
-int acm_if_iter_sys(acm_if_iter_cb cb, void *ctx)
-{
-	struct ifconf *ifc;
-	struct ifreq *ifr;
-	char ip[INET6_ADDRSTRLEN];
-	int s, ret, i, len;
-	uint16_t pkey;
-	union ibv_gid sgid;
-
-	s = socket(AF_INET6, SOCK_DGRAM, 0);
-	if (!s)
-		return -1;
-
-	len = sizeof(*ifc) + sizeof(*ifr) * 64;
-	ifc = malloc(len);
-	if (!ifc) {
-		ret = -1;
-		goto out1;
-	}
-
-	memset(ifc, 0, len);
-	ifc->ifc_len = len;
-	ifc->ifc_req = (struct ifreq *) (ifc + 1);
-
-	ret = ioctl(s, SIOCGIFCONF, ifc);
-	if (ret < 0) {
-		printf("ioctl ifconf error %d\n", ret);
-		goto out2;
-	}
-
-	ifr = ifc->ifc_req;
-	for (i = 0; i < ifc->ifc_len / sizeof(struct ifreq); i++) {
-		switch (ifr[i].ifr_addr.sa_family) {
-		case AF_INET:
-			inet_ntop(ifr[i].ifr_addr.sa_family,
-				&((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr, ip, sizeof ip);
-			break;
-		case AF_INET6:
-			inet_ntop(ifr[i].ifr_addr.sa_family,
-				&((struct sockaddr_in6 *) &ifr[i].ifr_addr)->sin6_addr, ip, sizeof ip);
-			break;
-		default:
-			continue;
-		}
-
-		if (!acm_if_is_ib(ifr[i].ifr_name))
-			continue;
-
-		ret = acm_if_get_sgid(ifr[i].ifr_name, &sgid);
-		if (ret) {
-			printf("unable to get sgid\n");
-			continue;
-		}
-
-		ret = acm_if_get_pkey(ifr[i].ifr_name, &pkey);
-		if (ret) {
-			printf("unable to get pkey\n");
-			continue;
-		}
-
-		cb(ifr[i].ifr_name, &sgid, pkey, 0, NULL, 0, ip, ctx);
-	}
-	ret = 0;
-
-out2:
-	free(ifc);
-out1:
-	close(s);
-	return ret;
-
-}
src/acm_util.c +81 -0

90 lines not on this page · raw message

Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#8 lore raw

PATCH 7/16 ibacm: convert logging in acm_util.c to acm_log

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

ib_acme build defines ACME_PRINTS which overrides acm_log to printf

---
 Makefile.am    |    2 +-
 src/acm.c      |    6 ++----
 src/acm_util.c |   21 +++++++++------------
 src/acm_util.h |   12 ++++++++++++
 4 files changed, 24 insertions(+), 17 deletions(-)
Makefile.am +1 -1
index 539ef83..703030d 100644
@@ -8,7 +8,7 @@ svc_ibacm_SOURCES = src/acm.c
 util_ib_acme_SOURCES = src/acme.c linux/acme_linux.c src/libacm.c linux/libacm_linux.c \
 			src/parse.c src/acm_util.c
 svc_ibacm_CFLAGS = $(AM_CFLAGS)
-util_ib_acme_CFLAGS = $(AM_CFLAGS)
+util_ib_acme_CFLAGS = $(AM_CFLAGS) -DACME_PRINTS
 
 ibacmincludedir = $(includedir)/infiniband
 
src/acm.c +2 -4
index 82f9431..5dc2684 100644
@@ -47,6 +47,7 @@
 #include <dlist.h>
 #include <search.h>
 #include "acm_mad.h"
+#include "acm_util.h"
 
 #define src_out     data[0]
 
@@ -245,10 +246,7 @@ static uint8_t min_rate = IBV_RATE_10_GBPS;
 static enum acm_route_preload route_preload;
 static enum acm_addr_preload addr_preload;
 
-#define acm_log(level, format, ...) \
-	acm_write(level, "%s: "format, __func__, ## __VA_ARGS__)
-
-static void acm_write(int level, const char *format, ...)
+void acm_write(int level, const char *format, ...)
 {
 	va_list args;
 	struct timeval tv;
src/acm_util.c +9 -12
index 922eceb..7a84ac7 100644
@@ -52,7 +52,7 @@ int acm_if_is_ib(char *ifname)
 	snprintf(buf, sizeof buf, "//sys//class//net//%s//type", ifname);
 	f = fopen(buf, "r");
 	if (!f) {
-		printf("failed to open %s\n", buf);
+		acm_log(0, "failed to open %s\n", buf);
 		return 0;
 	}
 
@@ -60,6 +60,7 @@ int acm_if_is_ib(char *ifname)
 		type = strtol(buf, NULL, 0);
 		ret = (type == ARPHRD_INFINIBAND);
 	} else {
+		acm_log(0, "failed to read interface type\n");
 		ret = 0;
 	}
 
@@ -76,7 +77,7 @@ int acm_if_get_pkey(char *ifname, uint16_t *pkey)
 	snprintf(buf, sizeof buf, "//sys//class//net//%s//pkey", ifname);
 	f = fopen(buf, "r");
 	if (!f) {
-		printf("failed to open %s\n", buf);
+		acm_log(0, "failed to open %s\n", buf);
 		return -1;
 	}
 
@@ -84,7 +85,7 @@ int acm_if_get_pkey(char *ifname, uint16_t *pkey)
 		*pkey = strtol(buf, &end, 16);
 		ret = 0;
 	} else {
-		printf("failed to read pkey\n");
+		acm_log(0, "failed to read pkey\n");
 		ret = -1;
 	}
 
@@ -101,7 +102,7 @@ int acm_if_get_sgid(char *ifname, union ibv_gid *sgid)
 	snprintf(buf, sizeof buf, "//sys//class//net//%s//address", ifname);
 	f = fopen(buf, "r");
 	if (!f) {
-		printf("failed to open %s\n", buf);
+		acm_log(0, "failed to open %s\n", buf);
 		return -1;
 	}
 
@@ -112,7 +113,7 @@ int acm_if_get_sgid(char *ifname, union ibv_gid *sgid)
 		}
 		ret = 0;
 	} else {
-		printf("failed to read sgid\n");
+		acm_log(0, "failed to read sgid\n");
 		ret = -1;
 	}
 
@@ -146,7 +147,7 @@ int acm_if_iter_sys(acm_if_iter_cb cb, void *ctx)
 
 	ret = ioctl(s, SIOCGIFCONF, ifc);
 	if (ret < 0) {
-		printf("ioctl ifconf error %d\n", ret);
+		acm_log(0, "ioctl ifconf error %d\n", ret);
 		goto out2;
 	}
 
@@ -169,16 +170,12 @@ int acm_if_iter_sys(acm_if_iter_cb cb, void *ctx)
 			continue;
 
 		ret = acm_if_get_sgid(ifr[i].ifr_name, &sgid);
-		if (ret) {
-			printf("unable to get sgid\n");
+		if (ret)
 			continue;
-		}
 
 		ret = acm_if_get_pkey(ifr[i].ifr_name, &pkey);
-		if (ret) {
-			printf("unable to get pkey\n");
+		if (ret)
 			continue;
-		}
 
 		cb(ifr[i].ifr_name, &sgid, pkey, 0, NULL, 0, ip, ctx);
 	}
src/acm_util.h +12 -0
index ea86133..4f111b6 100644
@@ -32,6 +32,18 @@
 
 #include <infiniband/verbs.h>
 
+#ifdef ACME_PRINTS
+
+#define acm_log(level, format, ...) \
+	printf(format, ## __VA_ARGS__)
+
+#else /* !ACME_PRINTS */
+#define acm_log(level, format, ...) \
+	acm_write(level, "%s: "format, __func__, ## __VA_ARGS__)
+
+void acm_write(int level, const char *format, ...);
+#endif /* ACME_PRINTS */
+
 int acm_if_is_ib(char *ifname);
 int acm_if_get_pkey(char *ifname, uint16_t *pkey);
 int acm_if_get_sgid(char *ifname, union ibv_gid *sgid);
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#9 lore raw

PATCH 8/16 ibacm: add separate acm_ep_insert_addr function

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

This is in preparation for netlink support which will do this dynamically.

---
 src/acm.c |   73 ++++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 58 insertions(+), 15 deletions(-)
src/acm.c +58 -15
index 5dc2684..6bbc1e5 100644
@@ -2875,6 +2875,53 @@ static void acm_parse_hosts_file(struct acm_ep *ep)
 	fclose(f);
 }
 
+static int
+acm_ep_insert_addr(struct acm_ep *ep, uint8_t *addr, size_t addr_len, uint8_t addr_type)
+{
+	int i;
+	int ret = ENOMEM;
+	uint8_t tmp[ACM_MAX_ADDRESS];
+	char name_str[INET6_ADDRSTRLEN];
+
+	if (addr_len > ACM_MAX_ADDRESS)
+		return EINVAL;
+
+	memset(tmp, 0, sizeof tmp);
+	memcpy(tmp, addr, addr_len);
+
+	lock_acquire(&ep->lock);
+	if (acm_addr_index(ep, tmp, addr_type) < 0) {
+		for (i = 0; i < MAX_EP_ADDR; i++) {
+			if (ep->addr_type[i] == ACM_ADDRESS_INVALID) {
+
+				ep->addr_type[i] = addr_type;
+				memcpy(ep->addr[i].addr, tmp, ACM_MAX_ADDRESS);
+
+				switch (addr_type) {
+				case ACM_ADDRESS_IP:
+					inet_ntop(AF_INET, addr, name_str, sizeof name_str);
+					strncpy(ep->name[i], name_str, ACM_MAX_ADDRESS);
+					break;
+				case ACM_ADDRESS_IP6:
+					inet_ntop(AF_INET6, addr, name_str, sizeof name_str);
+					strncpy(ep->name[i], name_str, ACM_MAX_ADDRESS);
+					break;
+				case ACM_ADDRESS_NAME:
+					strncpy(ep->name[i], (const char *)addr, ACM_MAX_ADDRESS);
+					break;
+				}
+
+				ret = 0;
+				break;
+			}
+		}
+	} else {
+		ret = 0;
+	}
+	lock_release(&ep->lock);
+	return ret;
+}
+
 static int acm_assign_ep_names(struct acm_ep *ep)
 {
 	FILE *faddr;
@@ -2883,8 +2930,9 @@ static int acm_assign_ep_names(struct acm_ep *ep)
 	char dev[32], addr[INET6_ADDRSTRLEN], pkey_str[8];
 	uint16_t pkey;
 	uint8_t type;
-	int port, index = 0;
+	int port, ret = 0;
 	struct in6_addr ip_addr;
+	size_t addr_len;
 
 	dev_name = ep->port->dev->verbs->device->name;
 	acm_log(1, "device %s, port %d, pkey 0x%x\n",
@@ -2903,12 +2951,16 @@ static int acm_assign_ep_names(struct acm_ep *ep)
 			continue;
 
 		acm_log(2, "%s", s);
-		if (inet_pton(AF_INET, addr, &ip_addr) > 0)
+		if (inet_pton(AF_INET, addr, &ip_addr) > 0) {
 			type = ACM_ADDRESS_IP;
-		else if (inet_pton(AF_INET6, addr, &ip_addr) > 0)
+			addr_len = 4;
+		} else if (inet_pton(AF_INET6, addr, &ip_addr) > 0) {
 			type = ACM_ADDRESS_IP6;
-		else
+			addr_len = ACM_MAX_ADDRESS;
+		} else {
 			type = ACM_ADDRESS_NAME;
+			addr_len = strlen(addr);
+		}
 
 		if (stricmp(pkey_str, "default")) {
 			if (sscanf(pkey_str, "%hx", &pkey) != 1) {
@@ -2922,17 +2974,8 @@ static int acm_assign_ep_names(struct acm_ep *ep)
 		if (!stricmp(dev_name, dev) && (ep->port->port_num == (uint8_t) port) &&
 			(ep->pkey == pkey)) {
 
-			ep->addr_type[index] = type;
 			acm_log(1, "assigning %s\n", addr);
-			strncpy(ep->name[index], addr, ACM_MAX_ADDRESS);
-			if (type == ACM_ADDRESS_IP)
-				memcpy(ep->addr[index].addr, &ip_addr, 4);
-			else if (type == ACM_ADDRESS_IP6)
-				memcpy(ep->addr[index].addr, &ip_addr, sizeof ip_addr);
-			else
-				strncpy((char *) ep->addr[index].addr, addr, ACM_MAX_ADDRESS);
-
-			if (++index == MAX_EP_ADDR) {
+			if ((ret = acm_ep_insert_addr(ep, (uint8_t *)&ip_addr, addr_len, type)) != 0) {
 				acm_log(1, "maximum number of names assigned to EP\n");
 				break;
 			}
@@ -2940,7 +2983,7 @@ static int acm_assign_ep_names(struct acm_ep *ep)
 	}
 	fclose(faddr);
 
-	return !index;
+	return ret;
 }
 
 /*
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#10 lore raw

PATCH 9/16 ibacm: read system IP's into endpoints at startup

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

ibacm_addr.cfg is read after system is read which can add endpoints which are not active at start up.

ibacm_addr.cfg can still specify names for end points

---
 Makefile.am    |    2 +-
 src/acm.c      |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/acm_util.c |   13 ++++++++++-
 3 files changed, 79 insertions(+), 2 deletions(-)
Makefile.am +1 -1
index 703030d..cab1ca1 100644
@@ -4,7 +4,7 @@ AM_CFLAGS = -g -Wall -D_GNU_SOURCE -DSYSCONFDIR=\"$(sysconfdir)\" -DBINDIR=\"$(b
 
 bin_PROGRAMS = util/ib_acme
 sbin_PROGRAMS = svc/ibacm
-svc_ibacm_SOURCES = src/acm.c
+svc_ibacm_SOURCES = src/acm.c src/acm_util.c
 util_ib_acme_SOURCES = src/acme.c linux/acme_linux.c src/libacm.c linux/libacm_linux.c \
 			src/parse.c src/acm_util.c
 svc_ibacm_CFLAGS = $(AM_CFLAGS)
src/acm.c +66 -0

84 lines not on this page · raw message

src/acm_util.c +12 -1
index 7a84ac7..c3c5b69 100644
@@ -40,6 +40,8 @@
 #include <sys/types.h>
 #include <errno.h>
 
+#include <infiniband/acm.h>
+#include "acm_mad.h"
 #include "acm_util.h"
 
 int acm_if_is_ib(char *ifname)
@@ -129,6 +131,9 @@ int acm_if_iter_sys(acm_if_iter_cb cb, void *ctx)
 	int s, ret, i, len;
 	uint16_t pkey;
 	union ibv_gid sgid;
+	uint8_t addr_type;
+	uint8_t addr[ACM_MAX_ADDRESS];
+	size_t addr_len;
 
 	s = socket(AF_INET6, SOCK_DGRAM, 0);
 	if (!s)
@@ -155,10 +160,16 @@ int acm_if_iter_sys(acm_if_iter_cb cb, void *ctx)
 	for (i = 0; i < ifc->ifc_len / sizeof(struct ifreq); i++) {
 		switch (ifr[i].ifr_addr.sa_family) {
 		case AF_INET:
+			addr_type = ACM_ADDRESS_IP;
+			memcpy(&addr, &((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr, sizeof addr);
+			addr_len = 4;
 			inet_ntop(ifr[i].ifr_addr.sa_family,
 				&((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr, ip, sizeof ip);
 			break;
 		case AF_INET6:
+			addr_type = ACM_ADDRESS_IP6;
+			memcpy(&addr, &((struct sockaddr_in6 *) &ifr[i].ifr_addr)->sin6_addr, sizeof addr);
+			addr_len = ACM_MAX_ADDRESS;
 			inet_ntop(ifr[i].ifr_addr.sa_family,
 				&((struct sockaddr_in6 *) &ifr[i].ifr_addr)->sin6_addr, ip, sizeof ip);
 			break;
@@ -177,7 +188,7 @@ int acm_if_iter_sys(acm_if_iter_cb cb, void *ctx)
 		if (ret)
 			continue;
 
-		cb(ifr[i].ifr_name, &sgid, pkey, 0, NULL, 0, ip, ctx);
+		cb(ifr[i].ifr_name, &sgid, pkey, addr_type, addr, addr_len, ip, ctx);
 	}
 	ret = 0;
 
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#11 lore raw

PATCH 10/16 ibacm: add locking around end point address arrays

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

---
 src/acm.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)
src/acm.c +6 -2
index c5da791..ebb48f4 100644
@@ -92,7 +92,7 @@ enum acm_addr_preload {
 };
 
 /*
- * Nested locking order: dest -> ep, dest -> port
+ * Nested locking order: dest -> ep, dest -> port, port -> ep
  */
 struct acm_dest {
 	uint8_t                address[ACM_MAX_ADDRESS]; /* keep first */
@@ -1830,8 +1830,12 @@ acm_get_port_ep(struct acm_port *port, struct acm_ep_addr_data *data)
 		    (!data->info.path.pkey || (ntohs(data->info.path.pkey) == ep->pkey)))
 			return ep;
 
-		if (acm_addr_index(ep, data->info.addr, (uint8_t) data->type) >= 0)
+		lock_acquire(&ep->lock);
+		if (acm_addr_index(ep, data->info.addr, (uint8_t) data->type) >= 0) {
+			lock_release(&ep->lock);
 			return ep;
+		}
+		lock_release(&ep->lock);
 	}
 
 	return NULL;
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#12 lore raw

PATCH 11/16 ibacm: Add thread to monitor IP address changes

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

Currently only reports events to the log

---
 src/acm.c |   86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 86 insertions(+), 0 deletions(-)
src/acm.c +86 -0
index ebb48f4..a23e953 100644
@@ -49,6 +49,9 @@
 #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_mad.h"
 #include "acm_util.h"
 
@@ -3368,6 +3371,86 @@ static void acm_port_down(struct acm_port *port)
 	acm_log(1, "%s %d is down\n", port->dev->verbs->device->name, port->port_num);
 }
 
+
+#define NL_MSG_BUF_SIZE 4096
+static void CDECL_FUNC acm_ipnl_handler(void *context)
+{
+	struct sockaddr_nl addr;
+	int sock, len;
+	char buffer[NL_MSG_BUF_SIZE];
+	struct nlmsghdr *nlh;
+	char name[IFNAMSIZ];
+	char ip_str[INET6_ADDRSTRLEN];
+
+	if ((sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) {
+		acm_log(0, "Failed to open NETLINK_ROUTE socket");
+		return;
+	}
+
+	memset(&addr, 0, sizeof(addr));
+	addr.nl_family = AF_NETLINK;
+	addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
+
+	if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+		acm_log(0, "Failed to bind NETLINK_ROUTE socket");
+		return;
+	}
+
+	while ((len = recv(sock, buffer, NL_MSG_BUF_SIZE, 0)) > 0) {
+		nlh = (struct nlmsghdr *)buffer;
+		while ((NLMSG_OK(nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE)) {
+			struct ifaddrmsg *ifa = (struct ifaddrmsg *) NLMSG_DATA(nlh);
+			struct ifinfomsg *ifi = (struct ifinfomsg *) NLMSG_DATA(nlh);
+			struct rtattr *rth = IFA_RTA(ifa);
+			int rtl = IFA_PAYLOAD(nlh);
+
+			switch (nlh->nlmsg_type) {
+			case RTM_NEWADDR:
+			{
+				if_indextoname(ifa->ifa_index, name);
+				while (rtl && RTA_OK(rth, rtl)) {
+					if (rth->rta_type == IFA_LOCAL) {
+						acm_log(0, "Address added %s : %s\n",
+						        name, inet_ntop(ifa->ifa_family, RTA_DATA(rth),
+							ip_str, sizeof(ip_str)));
+					}
+					rth = RTA_NEXT(rth, rtl);
+				}
+				break;
+			}
+			case RTM_DELADDR:
+			{
+				if_indextoname(ifa->ifa_index, name);
+				while (rtl && RTA_OK(rth, rtl)) {
+					if (rth->rta_type == IFA_LOCAL) {
+						acm_log(0, "Address deleted %s : %s\n",
+						        name, inet_ntop(ifa->ifa_family, RTA_DATA(rth),
+							ip_str, sizeof(ip_str)));
+					}
+					rth = RTA_NEXT(rth, rtl);
+				}
+				break;
+			}
+			case RTM_NEWLINK:
+			{
+				acm_log(2, "Link added : %s\n", if_indextoname(ifi->ifi_index, name));
+				break;
+			}
+			case RTM_DELLINK:
+			{
+				acm_log(2, "Link removed : %s\n", if_indextoname(ifi->ifi_index, name));
+				break;
+			}
+			default:
+				acm_log(2, "unknown netlink message\n");
+				break;
+			}
+			nlh = NLMSG_NEXT(nlh, len);
+		}
+	}
+	return;
+}
+
 /*
  * There is one event handler thread per device.  This is the only thread that
  * modifies the port state or a port endpoint list.  Other threads which access
@@ -3750,6 +3833,9 @@ int CDECL_FUNC main(int argc, char **argv)
 		return -1;
 	}
 
+	acm_log(1, "starting IP Netlink thread\n");
+	beginthread(acm_ipnl_handler, NULL);
+
 	acm_activate_devices();
 	acm_log(1, "starting timeout/retry thread\n");
 	beginthread(acm_retry_handler, NULL);
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 1395985810-23822-12-git-send-email-sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#14 lore raw

Re: [PATCH 11/16] ibacm: Add thread to monitor IP address changes

src/acm.c static void acm_port_down(struct acm_port *port) · line 3450

Quoted 13 lines · On 03/28/14 06:50, [email protected] wrote:
src/acm.c +13 -0
+	while ((len = recv(sock, buffer, NL_MSG_BUF_SIZE, 0)) > 0) {
+		nlh = (struct nlmsghdr *)buffer;
+		while ((NLMSG_OK(nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE)) {
+			struct ifaddrmsg *ifa = (struct ifaddrmsg *) NLMSG_DATA(nlh);
+			struct ifinfomsg *ifi = (struct ifinfomsg *) NLMSG_DATA(nlh);
+			struct rtattr *rth = IFA_RTA(ifa);
+			int rtl = IFA_PAYLOAD(nlh);
+
+			switch (nlh->nlmsg_type) {
+			[ ... ]
+			nlh = NLMSG_NEXT(nlh, len);
+		}
+	}

Is there any reason why this code doesn't handle netlink buffer overflows (ENOBUFS) ? From the netlink(7) man page:

Netlink is not a reliable protocol. [ ... ] The kernel can't send a netlink message if the socket buffer is full: the message will be dropped and the kernel and the user-space process will no longer have the same view of kernel state. It is up to the application to detect when this happens (via the ENOBUFS error returned by recvmsg(2)) and resynchronize.

Bart.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#16 lore raw

RE: [PATCH 11/16] ibacm: Add thread to monitor IP address changes

Quoted 9 lines · On 03/28/14 06:50, [email protected] wrote:

src/acm.c static void acm_port_down(struct acm_port *port)

Quoted 3 lines
src/acm.c +3 -0
+	while ((len = recv(sock, buffer, NL_MSG_BUF_SIZE, 0)) > 0) {
+		nlh = (struct nlmsghdr *)buffer;
+		while ((NLMSG_OK(nlh, len)) && (nlh->nlmsg_type !=

NLMSG_DONE)) {

Review

Quoted 1 line
(quoted diff) +1 -0
+			struct ifaddrmsg *ifa = (struct ifaddrmsg *)

NLMSG_DATA(nlh);

Review

Quoted 1 line
(quoted diff) +1 -0
+			struct ifinfomsg *ifi = (struct ifinfomsg *)

NLMSG_DATA(nlh);

Quoted 11 lines

src/acm.c static void acm_port_down(struct acm_port *port) · line 3450

Quoted 8 lines
src/acm.c +8 -0
+			struct rtattr *rth = IFA_RTA(ifa);
+			int rtl = IFA_PAYLOAD(nlh);
+
+			switch (nlh->nlmsg_type) {
+			[ ... ]
+			nlh = NLMSG_NEXT(nlh, len);
+		}
+	}

Is there any reason why this code doesn't handle netlink buffer overflows (ENOBUFS) ? From the netlink(7) man page:

No reason other than my inexperience with netlink.

Quoted 6 lines

Netlink is not a reliable protocol. [ ... ] The kernel can't send a netlink message if the socket buffer is full: the message will be dropped and the kernel and the user-space process will no longer have the same view of kernel state. It is up to the application to detect when this happens (via the ENOBUFS error returned by recvmsg(2)) and resynchronize.

Thanks, I'll rework the patch to account for this.

Maybe by that time I will have Intel's email figured out...

Thanks,
Ira

Quoted 2 lines

Bart.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 2807E5FD2F6FDA4886F6618EAC48510E04B34C7A-8k97q/[email protected]

#18 lore raw

Re: [PATCH 11/16] ibacm: Add thread to monitor IP address changes

Quoted 21 lines · Ira
Quoted 9 lines · On 03/28/14 06:50, [email protected] wrote:

src/acm.c static void acm_port_down(struct acm_port *port)

Quoted 3 lines
src/acm.c +3 -0
+	while ((len = recv(sock, buffer, NL_MSG_BUF_SIZE, 0)) > 0) {
+		nlh = (struct nlmsghdr *)buffer;
+		while ((NLMSG_OK(nlh, len)) && (nlh->nlmsg_type !=

NLMSG_DONE)) {

Review

Quoted 1 line
(quoted diff) +1 -0
+			struct ifaddrmsg *ifa = (struct ifaddrmsg *)

NLMSG_DATA(nlh);

Review

Quoted 1 line
(quoted diff) +1 -0
+			struct ifinfomsg *ifi = (struct ifinfomsg *)

NLMSG_DATA(nlh);

Quoted 11 lines

src/acm.c static void acm_port_down(struct acm_port *port) · line 3450

Quoted 8 lines
src/acm.c +8 -0
+			struct rtattr *rth = IFA_RTA(ifa);
+			int rtl = IFA_PAYLOAD(nlh);
+
+			switch (nlh->nlmsg_type) {
+			[ ... ]
+			nlh = NLMSG_NEXT(nlh, len);
+		}
+	}

Is there any reason why this code doesn't handle netlink buffer overflows (ENOBUFS) ? From the netlink(7) man page:

Quoted 1 line

No reason other than my inexperience with netlink.

In that case it's probably helpful to have a look at the libnl documentation. I'm not saying that library should be used here but it's accompanied by excellent documentation about the netlink protocol. See also http://www.carisma.slowglass.com/~tgr/libnl/ and
http://www.carisma.slowglass.com/~tgr/libnl/doc/core.html.

Bart.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#19 lore raw

PATCH 12/16 ibacm: add/remove addr's in EP's when added/removed from the system.

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

This builds on the previous patch by reacting to the IP address changes monitored there.

---
 src/acm.c |  112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 110 insertions(+), 2 deletions(-)
src/acm.c +110 -2
index a23e953..a83dc22 100644
@@ -795,6 +795,27 @@ out:
 	lock_release(&ep->lock);
 }
 
+static void acm_mark_addr_invalid(struct acm_ep *ep,
+				  struct acm_ep_addr_data *data)
+{
+	int i;
+
+	lock_acquire(&ep->lock);
+	for (i = 0; i < MAX_EP_ADDR; i++) {
+		if (ep->addr_type[i] != data->type)
+			continue;
+
+		if ((data->type == ACM_ADDRESS_NAME &&
+		    !strnicmp((char *) ep->addr[i].name,
+			      (char *) data->info.addr, ACM_MAX_ADDRESS)) ||
+		     !memcmp(ep->addr[i].addr, data->info.addr, ACM_MAX_ADDRESS)) {
+			ep->addr_type[i] = ACM_ADDRESS_INVALID;
+			break;
+		}
+	}
+	lock_release(&ep->lock);
+}
+
 static int acm_addr_index(struct acm_ep *ep, uint8_t *addr, uint8_t addr_type)
 {
 	int i;
@@ -3371,6 +3392,82 @@ static void acm_port_down(struct acm_port *port)
 	acm_log(1, "%s %d is down\n", port->dev->verbs->device->name, port->port_num);
 }
 
+static int acm_nl_to_addr_data(struct acm_ep_addr_data *ad,
+				  int af_family, uint8_t *addr, size_t addr_len)
+{
+	if (addr_len > ACM_MAX_ADDRESS)
+		return EINVAL;
+
+	/* find the ep associated with this address "if any" */
+	switch (af_family) {
+	case AF_INET:
+		ad->type = ACM_ADDRESS_IP;
+		break;
+	case AF_INET6:
+		ad->type = ACM_ADDRESS_IP6;
+		break;
+	default:
+		return EINVAL;
+	}
+	memcpy(&ad->info.addr, addr, addr_len);
+	return 0;
+}
+
+static void acm_add_ep_ip(struct acm_ep_addr_data *data, char *ifname)
+{
+	struct acm_ep *ep;
+	struct acm_device *dev;
+	uint8_t port_num;
+	uint16_t pkey;
+	union ibv_gid sgid;
+
+	ep = acm_get_ep(data);
+	if (ep) {
+		acm_format_name(1, log_data, sizeof log_data,
+				data->type, data->info.addr, sizeof data->info.addr);
+		acm_log(1, "Address '%s' already available\n", log_data);
+		return;
+	}
+
+	if (acm_if_get_sgid(ifname, &sgid))
+		return;
+
+	dev = acm_get_device_from_gid(&sgid, &port_num);
+	if (!dev)
+		return;
+
+	if (acm_if_get_pkey(ifname, &pkey))
+		return;
+
+	acm_format_name(0, log_data, sizeof log_data,
+			data->type, data->info.addr, sizeof data->info.addr);
+	acm_log(0, " %s\n", log_data);
+
+	ep = acm_find_ep(&dev->port[port_num-1], pkey);
+	if (ep) {
+		if (acm_ep_insert_addr(ep, data->info.addr, sizeof data->info.addr, data->type)) {
+			acm_format_name(0, log_data, sizeof log_data,
+					data->type, data->info.addr, sizeof data->info.addr);
+			acm_log(0, "Failed to add '%s' to EP\n", log_data);
+		}
+	} else {
+		acm_log(0, "Failed to add '%s' no EP for pkey\n", log_data);
+	}
+}
+
+static void acm_rm_ep_ip(struct acm_ep_addr_data *data)
+{
+	struct acm_ep *ep;
+
+	ep = acm_get_ep(data);
+	if (ep) {
+		acm_format_name(0, log_data, sizeof log_data,
+				data->type, data->info.addr, sizeof data->info.addr);
+		acm_log(0, " %s\n", log_data);
+		acm_mark_addr_invalid(ep, data);
+	}
+}
+
 
 #define NL_MSG_BUF_SIZE 4096
 static void CDECL_FUNC acm_ipnl_handler(void *context)
@@ -3403,6 +3500,7 @@ static void CDECL_FUNC acm_ipnl_handler(void *context)
 			struct ifinfomsg *ifi = (struct ifinfomsg *) NLMSG_DATA(nlh);
 			struct rtattr *rth = IFA_RTA(ifa);
 			int rtl = IFA_PAYLOAD(nlh);
+			struct acm_ep_addr_data ad;
 
 			switch (nlh->nlmsg_type) {
 			case RTM_NEWADDR:
@@ -3410,9 +3508,14 @@ static void CDECL_FUNC acm_ipnl_handler(void *context)
 				if_indextoname(ifa->ifa_index, name);
 				while (rtl && RTA_OK(rth, rtl)) {
 					if (rth->rta_type == IFA_LOCAL) {
-						acm_log(0, "Address added %s : %s\n",
+						acm_log(1, "New system address available %s : %s\n",
 						        name, inet_ntop(ifa->ifa_family, RTA_DATA(rth),
 							ip_str, sizeof(ip_str)));
+						if (!acm_nl_to_addr_data(&ad, ifa->ifa_family,
+								      RTA_DATA(rth),
+								      RTA_PAYLOAD(rth))) {
+							acm_add_ep_ip(&ad, name);
+						}
 					}
 					rth = RTA_NEXT(rth, rtl);
 				}
@@ -3423,9 +3526,14 @@ static void CDECL_FUNC acm_ipnl_handler(void *context)
 				if_indextoname(ifa->ifa_index, name);
 				while (rtl && RTA_OK(rth, rtl)) {
 					if (rth->rta_type == IFA_LOCAL) {
-						acm_log(0, "Address deleted %s : %s\n",
+						acm_log(1, "System address removed %s : %s\n",
 						        name, inet_ntop(ifa->ifa_family, RTA_DATA(rth),
 							ip_str, sizeof(ip_str)));
+						if (!acm_nl_to_addr_data(&ad, ifa->ifa_family,
+								      RTA_DATA(rth),
+								      RTA_PAYLOAD(rth))) {
+							acm_rm_ep_ip(&ad);
+						}
 					}
 					rth = RTA_NEXT(rth, rtl);
 				}
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#20 lore raw

PATCH 13/16 ibacm: fix handling of aliased IPoIB devices

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

ibX:Y devices don't have sysfs files directly. They use the "base" interface of ibX. The ioctl calls however include the full aliased name.

Netlink does not have this problem as the interface name is reported as it appears in sysfs.

---
 src/acm_util.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
src/acm_util.c +7 -0
index c3c5b69..da6d058 100644
@@ -134,6 +134,7 @@ int acm_if_iter_sys(acm_if_iter_cb cb, void *ctx)
 	uint8_t addr_type;
 	uint8_t addr[ACM_MAX_ADDRESS];
 	size_t addr_len;
+	char *alias_sep;
 
 	s = socket(AF_INET6, SOCK_DGRAM, 0);
 	if (!s)
@@ -177,6 +178,12 @@ int acm_if_iter_sys(acm_if_iter_cb cb, void *ctx)
 			continue;
 		}
 
+		acm_log(2, "%s\n", ifr[i].ifr_name);
+
+		alias_sep = strchr(ifr[i].ifr_name, ':');
+		if (alias_sep)
+			*alias_sep = '\0';
+
 		if (!acm_if_is_ib(ifr[i].ifr_name))
 			continue;
 
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#21 lore raw

PATCH 14/16 ibacm: ib_acme remove IP addresses from ibacm_addr.cfg file generation

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

---
 Makefile.am        |    3 +-
 linux/acme_linux.c |   95 ----------------------------------------------------
 man/ib_acme.1      |    3 +-
 src/acme.c         |   12 ++-----
 4 files changed, 5 insertions(+), 108 deletions(-)
 delete mode 100644 linux/acme_linux.c
Makefile.am +1 -2
index cab1ca1..9070a5a 100644
@@ -5,8 +5,7 @@ AM_CFLAGS = -g -Wall -D_GNU_SOURCE -DSYSCONFDIR=\"$(sysconfdir)\" -DBINDIR=\"$(b
 bin_PROGRAMS = util/ib_acme
 sbin_PROGRAMS = svc/ibacm
 svc_ibacm_SOURCES = src/acm.c src/acm_util.c
-util_ib_acme_SOURCES = src/acme.c linux/acme_linux.c src/libacm.c linux/libacm_linux.c \
-			src/parse.c src/acm_util.c
+util_ib_acme_SOURCES = src/acme.c src/libacm.c linux/libacm_linux.c src/parse.c
 svc_ibacm_CFLAGS = $(AM_CFLAGS)
 util_ib_acme_CFLAGS = $(AM_CFLAGS) -DACME_PRINTS
 
linux/acme_linux.c deleted +0 -95

95 lines not on this page · raw message

man/ib_acme.1 +1 -2
index b00b315..baa1dd6 100644
@@ -55,8 +55,7 @@ performance of ACM cache lookups.  Defaults to 1.
 \-A [addr_file]
 With this option, the ib_acme utility automatically generates the address
 configuration file ibacm_addr.cfg.  The generated file is
-constructed using the system host name and any IP addresses that are
-assigned to IPoIB device instances.
+constructed using the system host name.
 .TP
 \-O [opt_file]
 With this option, the ib_acme utility automatically generates the option
src/acme.c +3 -9
index fbe9dbc..61797af 100644
@@ -317,9 +317,11 @@ static void gen_addr_temp(FILE *f)
 	fprintf(f, "# Entry format is:\n");
 	fprintf(f, "# address device port pkey\n");
 	fprintf(f, "#\n");
+	fprintf(f, "# NOTE: IP addresses are now automatically read and monitored on the system.\n");
+	fprintf(f, "#       They are therefore no longer required nor supported in this file\n");
+	fprintf(f, "#\n");
 	fprintf(f, "# The address may be one of the following:\n");
 	fprintf(f, "# host_name - ascii character string, up to 31 characters\n");
-	fprintf(f, "# address - IPv4 or IPv6 formatted address\n");
 	fprintf(f, "#\n");
 	fprintf(f, "# device name - struct ibv_device name\n");
 	fprintf(f, "# port number - valid port number on device (numbering starts at 1)\n");
@@ -331,8 +333,6 @@ static void gen_addr_temp(FILE *f)
 	fprintf(f, "# node31      ibv_device0 1 default\n");
 	fprintf(f, "# node31-1    ibv_device0 1 0x00FF\n");
 	fprintf(f, "# node31-2    ibv_device0 2 0x00FF\n");
-	fprintf(f, "# 192.168.0.1 ibv_device0 1 0xFFFF\n");
-	fprintf(f, "# 192.168.0.2 ibv_device0 2 default\n");
 }
 
 static int open_verbs(void)
@@ -449,12 +449,6 @@ static int gen_addr(void)
 		goto out2;
 	}
 
-	ret = gen_addr_ip(f);
-	if (ret) {
-		printf("Failed to auto generate IP addresses in config file\n");
-		goto out2;
-	}
-
 out2:
 	close_verbs();
 out1:
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#22 lore raw

PATCH 15/16 ibacm: remove acm_if_iter_sys function

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

The use of this function and the callback mechanism it used is now unnecessary since ib_acme does not scan for IP's

---
 src/acm.c      |  102 +++++++++++++++++++++++++++++++++++++++++++++++---------
 src/acm_util.c |   84 ----------------------------------------------
 src/acm_util.h |    5 ---
 3 files changed, 86 insertions(+), 105 deletions(-)
src/acm.c +86 -16
index a83dc22..651ccdd 100644
@@ -2990,28 +2990,98 @@ acm_get_device_from_gid(union ibv_gid *sgid, uint8_t *port)
 	return NULL;
 }
 
-static void acm_ip_iter_cb(char *ifname, union ibv_gid *gid, uint16_t pkey,
-		uint8_t addr_type, uint8_t *addr, size_t addr_len,
-		char *addr_name, void *ctx)
+static int acm_get_system_ips(struct acm_ep *ep)
 {
+	struct ifconf *ifc;
+	struct ifreq *ifr;
+	char ip[INET6_ADDRSTRLEN];
+	int s, ret, i, len;
+	uint16_t pkey;
+	union ibv_gid sgid;
+	uint8_t addr_type;
+	uint8_t addr[ACM_MAX_ADDRESS];
+	size_t addr_len;
+	char *alias_sep;
 	uint8_t port_num;
 	struct acm_device *dev;
-	struct acm_ep *ep = (struct acm_ep *)ctx;
-
-	dev = acm_get_device_from_gid(gid, &port_num);
-	if (dev && ep->port->dev == dev
-	    && ep->port->port_num == port_num && ep->pkey == pkey) {
-		if (!acm_ep_insert_addr(ep, addr, addr_len, addr_type)) {
-			acm_log(0, "Added %s %s %d 0x%x from %s\n", addr_name,
-				dev->verbs->device->name, port_num, pkey,
-				ifname);
+
+	s = socket(AF_INET6, SOCK_DGRAM, 0);
+	if (!s)
+		return -1;
+
+	len = sizeof(*ifc) + sizeof(*ifr) * 64;
+	ifc = malloc(len);
+	if (!ifc) {
+		ret = -1;
+		goto out1;
+	}
+
+	memset(ifc, 0, len);
+	ifc->ifc_len = len;
+	ifc->ifc_req = (struct ifreq *) (ifc + 1);
+
+	ret = ioctl(s, SIOCGIFCONF, ifc);
+	if (ret < 0) {
+		acm_log(0, "ioctl ifconf error %d\n", ret);
+		goto out2;
+	}
+
+	ifr = ifc->ifc_req;
+	for (i = 0; i < ifc->ifc_len / sizeof(struct ifreq); i++) {
+		switch (ifr[i].ifr_addr.sa_family) {
+		case AF_INET:
+			addr_type = ACM_ADDRESS_IP;
+			memcpy(&addr, &((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr, sizeof addr);
+			addr_len = 4;
+			inet_ntop(ifr[i].ifr_addr.sa_family,
+				&((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr, ip, sizeof ip);
+			break;
+		case AF_INET6:
+			addr_type = ACM_ADDRESS_IP6;
+			memcpy(&addr, &((struct sockaddr_in6 *) &ifr[i].ifr_addr)->sin6_addr, sizeof addr);
+			addr_len = ACM_MAX_ADDRESS;
+			inet_ntop(ifr[i].ifr_addr.sa_family,
+				&((struct sockaddr_in6 *) &ifr[i].ifr_addr)->sin6_addr, ip, sizeof ip);
+			break;
+		default:
+			continue;
+		}
+
+		acm_log(2, "%s\n", ifr[i].ifr_name);
+
+		alias_sep = strchr(ifr[i].ifr_name, ':');
+		if (alias_sep)
+			*alias_sep = '\0';
+
+		if (!acm_if_is_ib(ifr[i].ifr_name))
+			continue;
+
+		ret = acm_if_get_sgid(ifr[i].ifr_name, &sgid);
+		if (ret)
+			continue;
+
+		ret = acm_if_get_pkey(ifr[i].ifr_name, &pkey);
+		if (ret)
+			continue;
+
+		dev = acm_get_device_from_gid(&sgid, &port_num);
+		if (dev && ep->port->dev == dev
+		    && ep->port->port_num == port_num && ep->pkey == pkey) {
+			if (!acm_ep_insert_addr(ep, addr, addr_len, addr_type)) {
+				acm_log(0, "Added %s %s %d 0x%x from %s\n", ip,
+					dev->verbs->device->name, port_num, pkey,
+					ifr[i].ifr_name);
+			}
 		}
 	}
-}
+	ret = 0;
+
+out2:
+	free(ifc);
+out1:
+	close(s);
+	return ret;
 
-static int acm_get_system_ips(struct acm_ep *ep)
-{
-	return acm_if_iter_sys(acm_ip_iter_cb, (void *)ep);
 }
 
 static int acm_assign_ep_names(struct acm_ep *ep)
src/acm_util.c +0 -84

87 lines not on this page · raw message

src/acm_util.h +0 -5
index 4f111b6..871b93a 100644
@@ -48,9 +48,4 @@ int acm_if_is_ib(char *ifname);
 int acm_if_get_pkey(char *ifname, uint16_t *pkey);
 int acm_if_get_sgid(char *ifname, union ibv_gid *sgid);
 
-typedef void (*acm_if_iter_cb)(char *ifname, union ibv_gid *gid, uint16_t pkey,
-				uint8_t addr_type, uint8_t *addr, size_t addr_len,
-				char *addr_name, void *ctx);
-int acm_if_iter_sys(acm_if_iter_cb cb, void *ctx);
-
 #endif /* ACM_IF_H */
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#23 lore raw

PATCH 16/16 ibacm: remove processing of IP's from ibacm_addr.cfg

In reply to a message not in the archive

From: Ira Weiny <[email protected]>

Flag an error and do not process IP's which may appear in this file.

---
 src/acm.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)
src/acm.c +4 -6
index 651ccdd..c8a90ad 100644
@@ -3115,12 +3115,10 @@ static int acm_assign_ep_names(struct acm_ep *ep)
 			continue;
 
 		acm_log(2, "%s", s);
-		if (inet_pton(AF_INET, addr, &ip_addr) > 0) {
-			type = ACM_ADDRESS_IP;
-			addr_len = 4;
-		} else if (inet_pton(AF_INET6, addr, &ip_addr) > 0) {
-			type = ACM_ADDRESS_IP6;
-			addr_len = ACM_MAX_ADDRESS;
+		if (inet_pton(AF_INET, addr, &ip_addr) > 0
+		    || inet_pton(AF_INET6, addr, &ip_addr) > 0) {
+			acm_log(0, "ERROR - IP's are no longer supported in this config file : %s", s);
+			continue;
 		} else {
 			type = ACM_ADDRESS_NAME;
 			addr_len = strlen(addr);
Signature · 6 lines
1.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 1395985810-23822-17-git-send-email-sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org

#25 lore raw

RE: [PATCH 16/16] ibacm: remove processing of IP's from ibacm_addr.cfg

Quoted 5 lines

Subject: [PATCH 16/16] ibacm: remove processing of IP's from ibacm_addr.cfg

From: Ira Weiny <[email protected]>

Flag an error and do not process IP's which may appear in this file.

It probably makes sense to make this configurable, with the default to no longer process IP addresses in the file. The option to enable could be read from the configuration file. This provides an easy way for a user to re-enable this feature, in the off chance that it is in use.

- Sean
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html