[ofa-general] [RFC PATCH] IPv6 support for examples/rping.c

Aleksey Senin alekseys at voltaire.com
Wed Jul 30 07:44:38 PDT 2008


Here is patch that should be applied to rping.c in order to check 
RDMA CM support in the kernel.

>From 40acd529ae583f0e7ec88a070ad55cc9a3c430d4 Mon Sep 17 00:00:00 2001
From: Aleksey Senin <alekseys at voltaire.com>
Date: Wed, 30 Jul 2008 17:30:49 +0300
Subject: [PATCH] Initial support for IPv6
 Signed-off-by: Aleksey Senin <alekseys at voltaire.com>

---
 examples/rping.c |   81 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 67 insertions(+), 14 deletions(-)

diff --git a/examples/rping.c b/examples/rping.c
index 983ce1c..cbfcc1c 100644
--- a/examples/rping.c
+++ b/examples/rping.c
@@ -145,7 +145,9 @@ struct rping_cb {
 
 	uint16_t port;			/* dst port in NBO */
 	uint32_t addr;			/* dst addr in NBO */
+	uint32_t addr_pad[3];
 	char *addr_str;			/* dst addr string */
+	char *laddr_str;
 	int verbose;			/* verbose logging */
 	int count;			/* ping count */
 	int size;			/* ping data size */
@@ -727,17 +729,36 @@ static int rping_test_server(struct rping_cb *cb)
 	return ret;
 }
 
+struct rping_addr{
+	struct sockaddr addr;
+	unsigned char pad[sizeof(struct sockaddr_in6) - sizeof(struct sockaddr)];
+};
+
+
 static int rping_bind_server(struct rping_cb *cb)
 {
-	struct sockaddr_in sin;
+	struct rping_addr sin;
 	int ret;
-
 	memset(&sin, 0, sizeof(sin));
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = cb->addr;
-	sin.sin_port = cb->port;
 
-	ret = rdma_bind_addr(cb->cm_id, (struct sockaddr *) &sin);
+	if ( cb->addr_str && strchr(cb->addr_str, ':') ){
+		DEBUG_LOG("Got IPv6 address: %s\n", cb->addr_str);
+		struct sockaddr_in6 *addr = ( struct sockaddr_in6*)&sin.addr;
+		sin.addr.sa_family = AF_INET6;
+		addr->sin6_port = cb->port;
+		inet_pton(AF_INET6, cb->addr_str, addr->sin6_addr.s6_addr);
+		/* &sin.r6_addr.sin6_addr.s6_addr); */
+	} else {
+		struct sockaddr_in *addr = (struct sockaddr_in*)&sin.addr;
+		DEBUG_LOG("Got IPv4 address: %s\n", cb->addr_str);
+		sin.addr.sa_family = AF_INET;
+		addr->sin_port = cb->port;
+		addr->sin_addr.s_addr = cb->addr;
+		/*sin.r_addr.sin_port = cb->port;
+		sin.r_addr.sin_addr.s_addr = cb->addr; */
+	}
+
+	ret = rdma_bind_addr(cb->cm_id, &sin.addr);
 	if (ret) {
 		fprintf(stderr, "rdma_bind_addr error %d\n", ret);
 		return ret;
@@ -997,16 +1018,43 @@ static int rping_connect_client(struct rping_cb *cb)
 
 static int rping_bind_client(struct rping_cb *cb)
 {
-	struct sockaddr_in sin;
+	struct  rping_addr sin;
+	struct  rping_addr saddr;
+	struct sockaddr *paddr;
 	int ret;
 
 	memset(&sin, 0, sizeof(sin));
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = cb->addr;
-	sin.sin_port = cb->port;
 
-	ret = rdma_resolve_addr(cb->cm_id, NULL, (struct sockaddr *) &sin,
-				2000);
+	if(cb->addr_str && strchr(cb->addr_str, ':') ) {
+		struct sockaddr_in6 *addr = (struct sockaddr_in6*)&sin.addr;
+		sin.addr.sa_family = AF_INET6;
+		addr->sin6_port = cb->port;
+		inet_pton(AF_INET6, cb->addr_str, addr->sin6_addr.s6_addr);
+	} else {
+		struct sockaddr_in *addr = (struct sockaddr_in*)&sin.addr;
+		sin.addr.sa_family = AF_INET;
+		addr->sin_addr.s_addr = cb->addr;
+		addr->sin_port = cb->port;
+	}
+        if ( sin.addr.sa_family == AF_INET6 ) {
+	    struct sockaddr_in6 *addr = (struct sockaddr_in6*)&saddr.addr;
+	    saddr.addr.sa_family = AF_INET6;
+            addr->sin6_port = 7174;
+	    if(cb->laddr_str) {
+		DEBUG_LOG("Using specified address: %s\n", cb->laddr_str);
+		inet_pton(AF_INET6, cb->laddr_str, addr->sin6_addr.s6_addr);
+		paddr = &saddr.addr;
+	    }
+	    else {
+			DEBUG_LOG("You have to specify local IPv6 address in order to use this programm with IPv6 support");
+			return -1;
+	    }
+	}else {
+	    paddr = NULL;
+	}
+
+	ret = rdma_resolve_addr(cb->cm_id, paddr, &sin.addr, 2000);
+
 	if (ret) {
 		fprintf(stderr, "rdma_resolve_addr error %d\n", ret);
 		return ret;
@@ -1084,6 +1132,7 @@ static void usage(char *name)
 	printf("\t-a addr\t\taddress\n");
 	printf("\t-p port\t\tport\n");
 	printf("\t-P\t\tpersistent server mode allowing multiple connections\n");
+	printf("\t-I\t\tlocal IPv6 source address\n");
 }
 
 int main(int argc, char *argv[])
@@ -1105,11 +1154,12 @@ int main(int argc, char *argv[])
 	sem_init(&cb->sem, 0, 0);
 
 	opterr = 0;
-	while ((op=getopt(argc, argv, "a:Pp:C:S:t:scvVd")) != -1) {
+	while ((op=getopt(argc, argv, "a:Pp:C:S:t:scvVdI:")) != -1) {
 		switch (op) {
 		case 'a':
 			cb->addr_str = optarg;
-			cb->addr = inet_addr(optarg);
+			strchr(optarg, ':')?inet_pton(AF_INET6, optarg, &cb->addr):\
+				inet_pton(AF_INET, optarg, &cb->addr);
 			DEBUG_LOG("ipaddr (%s)\n", optarg);
 			break;
 		case 'P':
@@ -1158,6 +1208,9 @@ int main(int argc, char *argv[])
 		case 'd':
 			debug++;
 			break;
+		case 'I':
+			cb->laddr_str = optarg;
+			break;
 		default:
 			usage("rping");
 			ret = EINVAL;
-- 
1.5.6.dirty





More information about the general mailing list