svn commit: r325601 - stable/11/sys/contrib/rdma/krping
Hans Petter Selasky
hselasky at FreeBSD.org
Thu Nov 9 17:49:46 UTC 2017
Author: hselasky
Date: Thu Nov 9 17:49:45 2017
New Revision: 325601
URL: https://svnweb.freebsd.org/changeset/base/325601
Log:
MFC r324490:
Add support for parsing and using IPv6 addresses in krping.
Sponsored by: Mellanox Technologies
Modified:
stable/11/sys/contrib/rdma/krping/krping.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/contrib/rdma/krping/krping.c
==============================================================================
--- stable/11/sys/contrib/rdma/krping/krping.c Thu Nov 9 17:47:33 2017 (r325600)
+++ stable/11/sys/contrib/rdma/krping/krping.c Thu Nov 9 17:49:45 2017 (r325601)
@@ -85,6 +85,7 @@ static const struct krping_option krping_opts[] = {
{"count", OPT_INT, 'C'},
{"size", OPT_INT, 'S'},
{"addr", OPT_STRING, 'a'},
+ {"addr6", OPT_STRING, 'A'},
{"port", OPT_INT, 'p'},
{"verbose", OPT_NOPARAM, 'v'},
{"validate", OPT_NOPARAM, 'V'},
@@ -219,7 +220,11 @@ struct krping_cb {
struct krping_stats stats;
uint16_t port; /* dst port in NBO */
- struct in_addr addr; /* dst addr in NBO */
+ union {
+ struct in_addr v4;
+ struct in6_addr v6;
+ } addr; /* dst addr in NBO */
+ int addr_type; /* AF_INET or AF_INET6 */
char *addr_str; /* dst addr string */
int verbose; /* verbose logging */
int count; /* ping count */
@@ -1599,15 +1604,31 @@ static int fastreg_supported(struct krping_cb *cb, int
static int krping_bind_server(struct krping_cb *cb)
{
- struct sockaddr_in sin;
+ union {
+ struct sockaddr_in v4;
+ struct sockaddr_in6 v6;
+ } sin;
int ret;
memset(&sin, 0, sizeof(sin));
- sin.sin_len = sizeof sin;
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = cb->addr.s_addr;
- sin.sin_port = cb->port;
+ switch (cb->addr_type) {
+ case AF_INET:
+ sin.v4.sin_len = sizeof sin.v4;
+ sin.v4.sin_family = AF_INET;
+ sin.v4.sin_addr = cb->addr.v4;
+ sin.v4.sin_port = cb->port;
+ break;
+ case AF_INET6:
+ sin.v6.sin6_len = sizeof sin.v6;
+ sin.v6.sin6_family = AF_INET6;
+ sin.v6.sin6_addr = cb->addr.v6;
+ sin.v6.sin6_port = cb->port;
+ break;
+ default:
+ return (-EINVAL);
+ }
+
ret = rdma_bind_addr(cb->cm_id, (struct sockaddr *) &sin);
if (ret) {
PRINTF(cb, "rdma_bind_addr error %d\n", ret);
@@ -3058,15 +3079,31 @@ static int krping_connect_client(struct krping_cb *cb)
static int krping_bind_client(struct krping_cb *cb)
{
- struct sockaddr_in sin;
+ union {
+ struct sockaddr_in v4;
+ struct sockaddr_in6 v6;
+ } sin;
int ret;
memset(&sin, 0, sizeof(sin));
- sin.sin_len = sizeof sin;
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = cb->addr.s_addr;
- sin.sin_port = cb->port;
+ switch (cb->addr_type) {
+ case AF_INET:
+ sin.v4.sin_len = sizeof sin.v4;
+ sin.v4.sin_family = AF_INET;
+ sin.v4.sin_addr = cb->addr.v4;
+ sin.v4.sin_port = cb->port;
+ break;
+ case AF_INET6:
+ sin.v6.sin6_len = sizeof sin.v6;
+ sin.v6.sin6_family = AF_INET6;
+ sin.v6.sin6_addr = cb->addr.v6;
+ sin.v6.sin6_port = cb->port;
+ break;
+ default:
+ return (-EINVAL);
+ }
+
ret = rdma_resolve_addr(cb->cm_id, NULL, (struct sockaddr *) &sin,
2000);
if (ret) {
@@ -3139,12 +3176,29 @@ err1:
krping_free_qp(cb);
}
+static uint16_t
+krping_get_ipv6_scope_id(char *name)
+{
+ struct ifnet *ifp;
+ uint16_t retval;
+
+ if (name == NULL)
+ return (0);
+ ifp = ifunit_ref(name);
+ if (ifp == NULL)
+ return (0);
+ retval = ifp->if_index;
+ if_rele(ifp);
+ return (retval);
+}
+
int krping_doit(char *cmd, void *cookie)
{
struct krping_cb *cb;
int op;
int ret = 0;
char *optarg;
+ char *scope;
unsigned long optint;
cb = kzalloc(sizeof(*cb), GFP_KERNEL);
@@ -3161,6 +3215,7 @@ int krping_doit(char *cmd, void *cookie)
cb->size = 64;
cb->txdepth = RPING_SQ_DEPTH;
cb->mem = DMA;
+ cb->addr_type = AF_INET;
init_waitqueue_head(&cb->sem);
while ((op = krping_getopt("krping", &cmd, krping_opts, NULL, &optarg,
@@ -3168,11 +3223,33 @@ int krping_doit(char *cmd, void *cookie)
switch (op) {
case 'a':
cb->addr_str = optarg;
- DEBUG_LOG(cb, "ipaddr (%s)\n", optarg);
- if (!inet_aton(optarg, &cb->addr)) {
+ cb->addr_type = AF_INET;
+ DEBUG_LOG(cb, "ipv4addr (%s)\n", optarg);
+ if (inet_pton(AF_INET, optarg, &cb->addr) != 1) {
PRINTF(cb, "bad addr string %s\n",
optarg);
ret = EINVAL;
+ }
+ break;
+ case 'A':
+ cb->addr_str = optarg;
+ cb->addr_type = AF_INET6;
+ DEBUG_LOG(cb, "ipv6addr (%s)\n", optarg);
+ scope = strstr(optarg, "%");
+ /* extract scope ID, if any */
+ if (scope != NULL)
+ *scope++ = 0;
+ /* extract IPv6 network address */
+ if (inet_pton(AF_INET6, optarg, &cb->addr) != 1) {
+ PRINTF(cb, "bad addr string %s\n",
+ optarg);
+ ret = EINVAL;
+ } else if (IN6_IS_SCOPE_LINKLOCAL(&cb->addr.v6) ||
+ IN6_IS_ADDR_MC_INTFACELOCAL(&cb->addr.v6)) {
+ uint16_t scope_id = krping_get_ipv6_scope_id(scope);
+ DEBUG_LOG(cb, "ipv6 scope ID = %d\n", scope_id);
+ cb->addr.v6.s6_addr[2] = scope_id >> 8;
+ cb->addr.v6.s6_addr[3] = scope_id & 0xFF;
}
break;
case 'p':
More information about the svn-src-stable-11
mailing list