]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ofed/libibverbs/fixes/rocee_examples.patch
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ofed / libibverbs / fixes / rocee_examples.patch
1 [PATCH 4/4] libibverbs: Update examples
2
3 Since RDMAoE requires usage of GRH, update ibv_*_pinpong examples to accept
4 GIDs. GIDs are given as an index to the local port's table and are exchanged
5 between the client and the server through the socket connection.
6
7 Signed-off-by: Eli Cohen <eli@mellanox.co.il>
8 ---
9  examples/devinfo.c      |   14 ++++++++
10  examples/pingpong.c     |   31 ++++++++++++++++++
11  examples/pingpong.h     |    4 ++
12  examples/rc_pingpong.c  |   79 +++++++++++++++++++++++++++++++++++-----------
13  examples/srq_pingpong.c |   72 ++++++++++++++++++++++++++++++++----------
14  examples/uc_pingpong.c  |   70 ++++++++++++++++++++++++++++++++---------
15  examples/ud_pingpong.c  |   69 ++++++++++++++++++++++++++++++-----------
16  7 files changed, 269 insertions(+), 70 deletions(-)
17
18 Index: libibverbs/examples/devinfo.c
19 ===================================================================
20 --- libibverbs.orig/examples/devinfo.c  2010-02-08 15:04:24.369329000 +0200
21 +++ libibverbs/examples/devinfo.c       2010-03-17 14:08:48.404754000 +0200
22 @@ -184,6 +184,19 @@ static int print_all_port_gids(struct ib
23         return rc;
24  }
25  
26 +static const char *link_layer_str(uint8_t link_layer)
27 +{
28 +       switch (link_layer) {
29 +       case IBV_LINK_LAYER_UNSPECIFIED:
30 +       case IBV_LINK_LAYER_INFINIBAND:
31 +               return "IB";
32 +       case IBV_LINK_LAYER_ETHERNET:
33 +               return "Ethernet";
34 +       default:
35 +               return "Unknown";
36 +       }
37 +}
38 +
39  static int print_hca_cap(struct ibv_device *ib_dev, uint8_t ib_port)
40  {
41         struct ibv_context *ctx;
42 @@ -284,6 +297,7 @@ static int print_hca_cap(struct ibv_devi
43                 printf("\t\t\tsm_lid:\t\t\t%d\n", port_attr.sm_lid);
44                 printf("\t\t\tport_lid:\t\t%d\n", port_attr.lid);
45                 printf("\t\t\tport_lmc:\t\t0x%02x\n", port_attr.lmc);
46 +               printf("\t\t\tlink_layer:\t\t%s\n", link_layer_str(port_attr.link_layer));
47  
48                 if (verbose) {
49                         printf("\t\t\tmax_msg_sz:\t\t0x%x\n", port_attr.max_msg_sz);
50 Index: libibverbs/examples/pingpong.c
51 ===================================================================
52 --- libibverbs.orig/examples/pingpong.c 2010-02-08 15:04:24.372330000 +0200
53 +++ libibverbs/examples/pingpong.c      2010-03-17 14:08:48.433754000 +0200
54 @@ -31,6 +31,10 @@
55   */
56  
57  #include "pingpong.h"
58 +#include <arpa/inet.h>
59 +#include <stdlib.h>
60 +#include <stdio.h>
61 +#include <string.h>
62  
63  enum ibv_mtu pp_mtu_to_enum(int mtu)
64  {
65 @@ -53,3 +57,30 @@ uint16_t pp_get_local_lid(struct ibv_con
66  
67         return attr.lid;
68  }
69 +
70 +int pp_get_port_info(struct ibv_context *context, int port,
71 +                    struct ibv_port_attr *attr)
72 +{
73 +       return ibv_query_port(context, port, attr);
74 +}
75 +
76 +void wire_gid_to_gid(const char *wgid, union ibv_gid *gid)
77 +{
78 +       char tmp[9];
79 +       uint32_t v32;
80 +       int i;
81 +
82 +       for (tmp[8] = 0, i = 0; i < 4; ++i) {
83 +               memcpy(tmp, wgid + i * 8, 8);
84 +               sscanf(tmp, "%x", &v32);
85 +               *(uint32_t *)(&gid->raw[i * 4]) = ntohl(v32);
86 +       }
87 +}
88 +
89 +void gid_to_wire_gid(const union ibv_gid *gid, char wgid[])
90 +{
91 +       int i;
92 +
93 +       for (i = 0; i < 4; ++i)
94 +               sprintf(&wgid[i * 8], "%08x", htonl(*(uint32_t *)(gid->raw + i * 4)));
95 +}
96 Index: libibverbs/examples/pingpong.h
97 ===================================================================
98 --- libibverbs.orig/examples/pingpong.h 2010-02-08 15:04:24.375328000 +0200
99 +++ libibverbs/examples/pingpong.h      2010-03-17 14:08:48.443756000 +0200
100 @@ -37,5 +37,9 @@
101  
102  enum ibv_mtu pp_mtu_to_enum(int mtu);
103  uint16_t pp_get_local_lid(struct ibv_context *context, int port);
104 +int pp_get_port_info(struct ibv_context *context, int port,
105 +                    struct ibv_port_attr *attr);
106 +void wire_gid_to_gid(const char *wgid, union ibv_gid *gid);
107 +void gid_to_wire_gid(const union ibv_gid *gid, char wgid[]);
108  
109  #endif /* IBV_PINGPONG_H */
110 Index: libibverbs/examples/rc_pingpong.c
111 ===================================================================
112 --- libibverbs.orig/examples/rc_pingpong.c      2010-02-08 15:04:24.378329000 +0200
113 +++ libibverbs/examples/rc_pingpong.c   2010-03-17 14:11:16.145313000 +0200
114 @@ -67,17 +67,19 @@ struct pingpong_context {
115         int                      size;
116         int                      rx_depth;
117         int                      pending;
118 +       struct ibv_port_attr     portinfo;
119  };
120  
121  struct pingpong_dest {
122         int lid;
123         int qpn;
124         int psn;
125 +       union ibv_gid gid;
126  };
127  
128  static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn,
129                           enum ibv_mtu mtu, int sl,
130 -                         struct pingpong_dest *dest)
131 +                         struct pingpong_dest *dest, int sgid_idx)
132  {
133         struct ibv_qp_attr attr = {
134                 .qp_state               = IBV_QPS_RTR,
135 @@ -94,6 +96,13 @@ static int pp_connect_ctx(struct pingpon
136                         .port_num       = port
137                 }
138         };
139 +
140 +       if (dest->gid.global.interface_id) {
141 +               attr.ah_attr.is_global = 1;
142 +               attr.ah_attr.grh.hop_limit = 1;
143 +               attr.ah_attr.grh.dgid = dest->gid;
144 +               attr.ah_attr.grh.sgid_index = sgid_idx;
145 +       }
146         if (ibv_modify_qp(ctx->qp, &attr,
147                           IBV_QP_STATE              |
148                           IBV_QP_AV                 |
149 @@ -135,10 +144,11 @@ static struct pingpong_dest *pp_client_e
150                 .ai_socktype = SOCK_STREAM
151         };
152         char *service;
153 -       char msg[sizeof "0000:000000:000000"];
154 +       char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
155         int n;
156         int sockfd = -1;
157         struct pingpong_dest *rem_dest = NULL;
158 +       char gid[33];
159  
160         if (asprintf(&service, "%d", port) < 0)
161                 return NULL;
162 @@ -169,7 +179,8 @@ static struct pingpong_dest *pp_client_e
163                 return NULL;
164         }
165  
166 -       sprintf(msg, "%04x:%06x:%06x", my_dest->lid, my_dest->qpn, my_dest->psn);
167 +       gid_to_wire_gid(&my_dest->gid, gid);
168 +       sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid);
169         if (write(sockfd, msg, sizeof msg) != sizeof msg) {
170                 fprintf(stderr, "Couldn't send local address\n");
171                 goto out;
172 @@ -187,7 +198,8 @@ static struct pingpong_dest *pp_client_e
173         if (!rem_dest)
174                 goto out;
175  
176 -       sscanf(msg, "%x:%x:%x", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn);
177 +       sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid);
178 +       wire_gid_to_gid(gid, &rem_dest->gid);
179  
180  out:
181         close(sockfd);
182 @@ -197,7 +209,8 @@ out:
183  static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx,
184                                                  int ib_port, enum ibv_mtu mtu,
185                                                  int port, int sl,
186 -                                                const struct pingpong_dest *my_dest)
187 +                                                const struct pingpong_dest *my_dest,
188 +                                                int sgid_idx)
189  {
190         struct addrinfo *res, *t;
191         struct addrinfo hints = {
192 @@ -206,10 +219,11 @@ static struct pingpong_dest *pp_server_e
193                 .ai_socktype = SOCK_STREAM
194         };
195         char *service;
196 -       char msg[sizeof "0000:000000:000000"];
197 +       char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
198         int n;
199         int sockfd = -1, connfd;
200         struct pingpong_dest *rem_dest = NULL;
201 +       char gid[33];
202  
203         if (asprintf(&service, "%d", port) < 0)
204                 return NULL;
205 @@ -263,16 +277,19 @@ static struct pingpong_dest *pp_server_e
206         if (!rem_dest)
207                 goto out;
208  
209 -       sscanf(msg, "%x:%x:%x", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn);
210 +       sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid);
211 +       wire_gid_to_gid(gid, &rem_dest->gid);
212  
213 -       if (pp_connect_ctx(ctx, ib_port, my_dest->psn, mtu, sl, rem_dest)) {
214 +       if (pp_connect_ctx(ctx, ib_port, my_dest->psn, mtu, sl, rem_dest, sgid_idx)) {
215                 fprintf(stderr, "Couldn't connect to remote QP\n");
216                 free(rem_dest);
217                 rem_dest = NULL;
218                 goto out;
219         }
220  
221 -       sprintf(msg, "%04x:%06x:%06x", my_dest->lid, my_dest->qpn, my_dest->psn);
222 +
223 +       gid_to_wire_gid(&my_dest->gid, gid);
224 +       sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid);
225         if (write(connfd, msg, sizeof msg) != sizeof msg) {
226                 fprintf(stderr, "Couldn't send local address\n");
227                 free(rem_dest);
228 @@ -289,11 +306,11 @@ out:
229  
230  static struct pingpong_context *pp_init_ctx(struct ibv_device *ib_dev, int size,
231                                             int rx_depth, int port,
232 -                                           int use_event)
233 +                                           int use_event, int is_server)
234  {
235         struct pingpong_context *ctx;
236  
237 -       ctx = malloc(sizeof *ctx);
238 +       ctx = calloc(1, sizeof *ctx);
239         if (!ctx)
240                 return NULL;
241  
242 @@ -306,7 +323,7 @@ static struct pingpong_context *pp_init_
243                 return NULL;
244         }
245  
246 -       memset(ctx->buf, 0, size);
247 +       memset(ctx->buf, 0x7b + is_server, size);
248  
249         ctx->context = ibv_open_device(ib_dev);
250         if (!ctx->context) {
251 @@ -481,6 +498,7 @@ static void usage(const char *argv0)
252         printf("  -n, --iters=<iters>    number of exchanges (default 1000)\n");
253         printf("  -l, --sl=<sl>          service level value\n");
254         printf("  -e, --events           sleep on CQ events (default poll)\n");
255 +       printf("  -g, --gid-idx=<gid index> local port gid index\n");
256  }
257  
258  int main(int argc, char *argv[])
259 @@ -504,6 +522,8 @@ int main(int argc, char *argv[])
260         int                      rcnt, scnt;
261         int                      num_cq_events = 0;
262         int                      sl = 0;
263 +       int                      gidx = -1;
264 +       char                     gid[33];
265  
266         srand48(getpid() * time(NULL));
267  
268 @@ -520,10 +540,11 @@ int main(int argc, char *argv[])
269                         { .name = "iters",    .has_arg = 1, .val = 'n' },
270                         { .name = "sl",       .has_arg = 1, .val = 'l' },
271                         { .name = "events",   .has_arg = 0, .val = 'e' },
272 +                       { .name = "gid-idx",  .has_arg = 1, .val = 'g' },
273                         { 0 }
274                 };
275  
276 -               c = getopt_long(argc, argv, "p:d:i:s:m:r:n:l:e", long_options, NULL);
277 +               c = getopt_long(argc, argv, "p:d:i:s:m:r:n:l:eg:", long_options, NULL);
278                 if (c == -1)
279                         break;
280  
281 @@ -576,6 +597,10 @@ int main(int argc, char *argv[])
282                         ++use_event;
283                         break;
284  
285 +               case 'g':
286 +                       gidx = strtol(optarg, NULL, 0);
287 +                       break;
288 +
289                 default:
290                         usage(argv[0]);
291                         return 1;
292 @@ -615,7 +640,7 @@ int main(int argc, char *argv[])
293                 }
294         }
295  
296 -       ctx = pp_init_ctx(ib_dev, size, rx_depth, ib_port, use_event);
297 +       ctx = pp_init_ctx(ib_dev, size, rx_depth, ib_port, use_event, !servername);
298         if (!ctx)
299                 return 1;
300  
301 @@ -631,30 +656,47 @@ int main(int argc, char *argv[])
302                         return 1;
303                 }
304  
305 -       my_dest.lid = pp_get_local_lid(ctx->context, ib_port);
306 -       my_dest.qpn = ctx->qp->qp_num;
307 -       my_dest.psn = lrand48() & 0xffffff;
308 -       if (!my_dest.lid) {
309 +
310 +       if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) {
311 +               fprintf(stderr, "Couldn't get port info\n");
312 +               return 1;
313 +       }
314 +
315 +       my_dest.lid = ctx->portinfo.lid;
316 +       if (ctx->portinfo.link_layer == IBV_LINK_LAYER_INFINIBAND && !my_dest.lid) {
317                 fprintf(stderr, "Couldn't get local LID\n");
318                 return 1;
319         }
320  
321 -       printf("  local address:  LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n",
322 -              my_dest.lid, my_dest.qpn, my_dest.psn);
323 +       if (gidx >= 0) {
324 +               if (ibv_query_gid(ctx->context, ib_port, gidx, &my_dest.gid)) {
325 +                       fprintf(stderr, "Could not get local gid for gid index %d\n", gidx);
326 +                       return 1;
327 +               }
328 +       } else
329 +               memset(&my_dest.gid, 0, sizeof my_dest.gid);
330 +
331 +       my_dest.qpn = ctx->qp->qp_num;
332 +       my_dest.psn = lrand48() & 0xffffff;
333 +       inet_ntop(AF_INET6, &my_dest.gid, gid, sizeof gid);
334 +       printf("  local address:  LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
335 +              my_dest.lid, my_dest.qpn, my_dest.psn, gid);
336 +
337  
338         if (servername)
339                 rem_dest = pp_client_exch_dest(servername, port, &my_dest);
340         else
341 -               rem_dest = pp_server_exch_dest(ctx, ib_port, mtu, port, sl, &my_dest);
342 +               rem_dest = pp_server_exch_dest(ctx, ib_port, mtu, port, sl, &my_dest, gidx);
343  
344         if (!rem_dest)
345                 return 1;
346  
347 -       printf("  remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n",
348 -              rem_dest->lid, rem_dest->qpn, rem_dest->psn);
349 +       inet_ntop(AF_INET6, &rem_dest->gid, gid, sizeof gid);
350 +       printf("  remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
351 +              rem_dest->lid, rem_dest->qpn, rem_dest->psn, gid);
352  
353         if (servername)
354 -               if (pp_connect_ctx(ctx, ib_port, my_dest.psn, mtu, sl, rem_dest))
355 +               if (pp_connect_ctx(ctx, ib_port, my_dest.psn, mtu, sl, rem_dest, gidx))
356                         return 1;
357  
358         ctx->pending = PINGPONG_RECV_WRID;
359 @@ -706,6 +748,7 @@ int main(int argc, char *argv[])
360                                         fprintf(stderr, "poll CQ failed %d\n", ne);
361                                         return 1;
362                                 }
363 +
364                         } while (!use_event && ne < 1);
365  
366                         for (i = 0; i < ne; ++i) {
367 Index: libibverbs/examples/srq_pingpong.c
368 ===================================================================
369 --- libibverbs.orig/examples/srq_pingpong.c     2010-02-08 15:04:24.382329000 +0200
370 +++ libibverbs/examples/srq_pingpong.c  2010-03-17 14:13:22.332220000 +0200
371 @@ -71,17 +71,19 @@ struct pingpong_context {
372         int                      num_qp;
373         int                      rx_depth;
374         int                      pending[MAX_QP];
375 +       struct ibv_port_attr     portinfo;
376  };
377  
378  struct pingpong_dest {
379         int lid;
380         int qpn;
381         int psn;
382 +       union ibv_gid gid;
383  };
384  
385  static int pp_connect_ctx(struct pingpong_context *ctx, int port, enum ibv_mtu mtu,
386                           int sl, const struct pingpong_dest *my_dest,
387 -                         const struct pingpong_dest *dest)
388 +                         const struct pingpong_dest *dest, int sgid_idx)
389  {
390         int i;
391  
392 @@ -101,6 +103,13 @@ static int pp_connect_ctx(struct pingpon
393                                 .port_num       = port
394                         }
395                 };
396 +
397 +               if (dest->gid.global.interface_id) {
398 +                       attr.ah_attr.is_global = 1;
399 +                       attr.ah_attr.grh.hop_limit = 1;
400 +                       attr.ah_attr.grh.dgid = dest->gid;
401 +                       attr.ah_attr.grh.sgid_index = sgid_idx;
402 +               }
403                 if (ibv_modify_qp(ctx->qp[i], &attr,
404                                   IBV_QP_STATE              |
405                                   IBV_QP_AV                 |
406 @@ -143,12 +152,13 @@ static struct pingpong_dest *pp_client_e
407                 .ai_socktype = SOCK_STREAM
408         };
409         char *service;
410 -       char msg[sizeof "0000:000000:000000"];
411 +       char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
412         int n;
413         int r;
414         int i;
415         int sockfd = -1;
416         struct pingpong_dest *rem_dest = NULL;
417 +       char gid[33];
418  
419         if (asprintf(&service, "%d", port) < 0)
420                 return NULL;
421 @@ -180,7 +190,8 @@ static struct pingpong_dest *pp_client_e
422         }
423  
424         for (i = 0; i < MAX_QP; ++i) {
425 -               sprintf(msg, "%04x:%06x:%06x", my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn);
426 +               gid_to_wire_gid(&my_dest[i].gid, gid);
427 +               sprintf(msg, "%04x:%06x:%06x:%s", my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn, gid);
428                 if (write(sockfd, msg, sizeof msg) != sizeof msg) {
429                         fprintf(stderr, "Couldn't send local address\n");
430                         goto out;
431 @@ -204,8 +215,9 @@ static struct pingpong_dest *pp_client_e
432                         n += r;
433                 }
434  
435 -               sscanf(msg, "%x:%x:%x",
436 -                      &rem_dest[i].lid, &rem_dest[i].qpn, &rem_dest[i].psn);
437 +               sscanf(msg, "%x:%x:%x:%s",
438 +                      &rem_dest[i].lid, &rem_dest[i].qpn, &rem_dest[i].psn, gid);
439 +               wire_gid_to_gid(gid, &rem_dest[i].gid);
440         }
441  
442         write(sockfd, "done", sizeof "done");
443 @@ -218,7 +230,8 @@ out:
444  static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx,
445                                                  int ib_port, enum ibv_mtu mtu,
446                                                  int port, int sl,
447 -                                                const struct pingpong_dest *my_dest)
448 +                                                const struct pingpong_dest *my_dest,
449 +                                                int sgid_idx)
450  {
451         struct addrinfo *res, *t;
452         struct addrinfo hints = {
453 @@ -227,12 +240,13 @@ static struct pingpong_dest *pp_server_e
454                 .ai_socktype = SOCK_STREAM
455         };
456         char *service;
457 -       char msg[sizeof "0000:000000:000000"];
458 +       char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
459         int n;
460         int r;
461         int i;
462         int sockfd = -1, connfd;
463         struct pingpong_dest *rem_dest = NULL;
464 +       char gid[33];
465  
466         if (asprintf(&service, "%d", port) < 0)
467                 return NULL;
468 @@ -292,11 +306,12 @@ static struct pingpong_dest *pp_server_e
469                         n += r;
470                 }
471  
472 -               sscanf(msg, "%x:%x:%x",
473 -                      &rem_dest[i].lid, &rem_dest[i].qpn, &rem_dest[i].psn);
474 +               sscanf(msg, "%x:%x:%x:%s",
475 +                      &rem_dest[i].lid, &rem_dest[i].qpn, &rem_dest[i].psn, gid);
476 +               wire_gid_to_gid(gid, &rem_dest[i].gid);
477         }
478  
479 -       if (pp_connect_ctx(ctx, ib_port, mtu, sl, my_dest, rem_dest)) {
480 +       if (pp_connect_ctx(ctx, ib_port, mtu, sl, my_dest, rem_dest, sgid_idx)) {
481                 fprintf(stderr, "Couldn't connect to remote QP\n");
482                 free(rem_dest);
483                 rem_dest = NULL;
484 @@ -304,7 +319,8 @@ static struct pingpong_dest *pp_server_e
485         }
486  
487         for (i = 0; i < MAX_QP; ++i) {
488 -               sprintf(msg, "%04x:%06x:%06x", my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn);
489 +               gid_to_wire_gid(&my_dest[i].gid, gid);
490 +               sprintf(msg, "%04x:%06x:%06x:%s", my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn, gid);
491                 if (write(connfd, msg, sizeof msg) != sizeof msg) {
492                         fprintf(stderr, "Couldn't send local address\n");
493                         free(rem_dest);
494 @@ -327,7 +343,7 @@ static struct pingpong_context *pp_init_
495         struct pingpong_context *ctx;
496         int i;
497  
498 -       ctx = malloc(sizeof *ctx);
499 +       ctx = calloc(1, sizeof *ctx);
500         if (!ctx)
501                 return NULL;
502  
503 @@ -551,6 +567,7 @@ static void usage(const char *argv0)
504         printf("  -n, --iters=<iters>    number of exchanges per QP(default 1000)\n");
505         printf("  -l, --sl=<sl>          service level value\n");
506         printf("  -e, --events           sleep on CQ events (default poll)\n");
507 +       printf("  -g, --gid-idx=<gid index> local port gid index\n");
508  }
509  
510  int main(int argc, char *argv[])
511 @@ -578,6 +595,8 @@ int main(int argc, char *argv[])
512         int                      i;
513         int                      num_cq_events = 0;
514         int                      sl = 0;
515 +       int                      gidx = -1;
516 +       char                     gid[33];
517  
518         srand48(getpid() * time(NULL));
519  
520 @@ -595,10 +614,11 @@ int main(int argc, char *argv[])
521                         { .name = "iters",    .has_arg = 1, .val = 'n' },
522                         { .name = "sl",       .has_arg = 1, .val = 'l' },
523                         { .name = "events",   .has_arg = 0, .val = 'e' },
524 +                       { .name = "gid-idx",  .has_arg = 1, .val = 'g' },
525                         { 0 }
526                 };
527  
528 -               c = getopt_long(argc, argv, "p:d:i:s:m:q:r:n:l:e", long_options, NULL);
529 +               c = getopt_long(argc, argv, "p:d:i:s:m:q:r:n:l:eg:", long_options, NULL);
530                 if (c == -1)
531                         break;
532  
533 @@ -655,6 +675,10 @@ int main(int argc, char *argv[])
534                         ++use_event;
535                         break;
536  
537 +               case 'g':
538 +                       gidx = strtol(optarg, NULL, 0);
539 +                       break;
540 +
541                 default:
542                         usage(argv[0]);
543                         return 1;
544 @@ -722,33 +746,50 @@ int main(int argc, char *argv[])
545  
546         memset(my_dest, 0, sizeof my_dest);
547  
548 +       if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) {
549 +               fprintf(stderr, "Couldn't get port info\n");
550 +               return 1;
551 +       }
552         for (i = 0; i < num_qp; ++i) {
553                 my_dest[i].qpn = ctx->qp[i]->qp_num;
554                 my_dest[i].psn = lrand48() & 0xffffff;
555 -               my_dest[i].lid = pp_get_local_lid(ctx->context, ib_port);
556 -               if (!my_dest[i].lid) {
557 +               my_dest[i].lid = ctx->portinfo.lid;
558 +               if (ctx->portinfo.link_layer == IBV_LINK_LAYER_INFINIBAND && !my_dest[i].lid) {
559                         fprintf(stderr, "Couldn't get local LID\n");
560                         return 1;
561                 }
562  
563 -               printf("  local address:  LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n",
564 -                      my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn);
565 +               if (gidx >= 0) {
566 +                       if (ibv_query_gid(ctx->context, ib_port, gidx, &my_dest[i].gid)) {
567 +                               fprintf(stderr, "Could not get local gid for gid index %d\n", gidx);
568 +                               return 1;
569 +                       }
570 +               } else
571 +                       memset(&my_dest[i].gid, 0, sizeof my_dest[i].gid);
572 +
573 +               inet_ntop(AF_INET6, &my_dest[i].gid, gid, sizeof gid);
574 +               printf("  local address:  LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
575 +                      my_dest[i].lid, my_dest[i].qpn, my_dest[i].psn, gid);
576         }
577  
578         if (servername)
579                 rem_dest = pp_client_exch_dest(servername, port, my_dest);
580         else
581 -               rem_dest = pp_server_exch_dest(ctx, ib_port, mtu, port, sl, my_dest);
582 +               rem_dest = pp_server_exch_dest(ctx, ib_port, mtu, port, sl, my_dest, gidx);
583  
584         if (!rem_dest)
585                 return 1;
586  
587 -       for (i = 0; i < num_qp; ++i)
588 -               printf("  remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n",
589 -                      rem_dest[i].lid, rem_dest[i].qpn, rem_dest[i].psn);
590 +       inet_ntop(AF_INET6, &rem_dest->gid, gid, sizeof gid);
591 +
592 +       for (i = 0; i < num_qp; ++i) {
593 +               inet_ntop(AF_INET6, &rem_dest[i].gid, gid, sizeof gid);
594 +               printf("  remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
595 +                      rem_dest[i].lid, rem_dest[i].qpn, rem_dest[i].psn, gid);
596 +       }
597  
598         if (servername)
599 -               if (pp_connect_ctx(ctx, ib_port, mtu, sl, my_dest, rem_dest))
600 +               if (pp_connect_ctx(ctx, ib_port, mtu, sl, my_dest, rem_dest, gidx))
601                         return 1;
602  
603         if (servername)
604 Index: libibverbs/examples/uc_pingpong.c
605 ===================================================================
606 --- libibverbs.orig/examples/uc_pingpong.c      2010-02-08 15:04:24.386328000 +0200
607 +++ libibverbs/examples/uc_pingpong.c   2010-03-17 14:14:23.573114000 +0200
608 @@ -67,17 +67,19 @@ struct pingpong_context {
609         int                      size;
610         int                      rx_depth;
611         int                      pending;
612 +       struct ibv_port_attr     portinfo;
613  };
614  
615  struct pingpong_dest {
616         int lid;
617         int qpn;
618         int psn;
619 +       union ibv_gid gid;
620  };
621  
622  static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn,
623                           enum ibv_mtu mtu, int sl,
624 -                         struct pingpong_dest *dest)
625 +                         struct pingpong_dest *dest, int sgid_idx)
626  {
627         struct ibv_qp_attr attr = {
628                 .qp_state               = IBV_QPS_RTR,
629 @@ -92,6 +94,14 @@ static int pp_connect_ctx(struct pingpon
630                         .port_num       = port
631                 }
632         };
633 +
634 +       if (dest->gid.global.interface_id) {
635 +               attr.ah_attr.is_global = 1;
636 +               attr.ah_attr.grh.hop_limit = 1;
637 +               attr.ah_attr.grh.dgid = dest->gid;
638 +               attr.ah_attr.grh.sgid_index = sgid_idx;
639 +       }
640 +
641         if (ibv_modify_qp(ctx->qp, &attr,
642                           IBV_QP_STATE              |
643                           IBV_QP_AV                 |
644 @@ -123,10 +133,11 @@ static struct pingpong_dest *pp_client_e
645                 .ai_socktype = SOCK_STREAM
646         };
647         char *service;
648 -       char msg[sizeof "0000:000000:000000"];
649 +       char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
650         int n;
651         int sockfd = -1;
652         struct pingpong_dest *rem_dest = NULL;
653 +       char gid[33];
654  
655         if (asprintf(&service, "%d", port) < 0)
656                 return NULL;
657 @@ -157,7 +168,8 @@ static struct pingpong_dest *pp_client_e
658                 return NULL;
659         }
660  
661 -       sprintf(msg, "%04x:%06x:%06x", my_dest->lid, my_dest->qpn, my_dest->psn);
662 +       gid_to_wire_gid(&my_dest->gid, gid);
663 +       sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid);
664         if (write(sockfd, msg, sizeof msg) != sizeof msg) {
665                 fprintf(stderr, "Couldn't send local address\n");
666                 goto out;
667 @@ -175,7 +187,8 @@ static struct pingpong_dest *pp_client_e
668         if (!rem_dest)
669                 goto out;
670  
671 -       sscanf(msg, "%x:%x:%x", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn);
672 +       sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid);
673 +       wire_gid_to_gid(gid, &rem_dest->gid);
674  
675  out:
676         close(sockfd);
677 @@ -185,7 +198,8 @@ out:
678  static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx,
679                                                  int ib_port, enum ibv_mtu mtu,
680                                                  int port, int sl,
681 -                                                const struct pingpong_dest *my_dest)
682 +                                                const struct pingpong_dest *my_dest,
683 +                                                int sgid_idx)
684  {
685         struct addrinfo *res, *t;
686         struct addrinfo hints = {
687 @@ -194,10 +208,11 @@ static struct pingpong_dest *pp_server_e
688                 .ai_socktype = SOCK_STREAM
689         };
690         char *service;
691 -       char msg[sizeof "0000:000000:000000"];
692 +       char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
693         int n;
694         int sockfd = -1, connfd;
695         struct pingpong_dest *rem_dest = NULL;
696 +       char gid[33];
697  
698         if (asprintf(&service, "%d", port) < 0)
699                 return NULL;
700 @@ -251,16 +266,18 @@ static struct pingpong_dest *pp_server_e
701         if (!rem_dest)
702                 goto out;
703  
704 -       sscanf(msg, "%x:%x:%x", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn);
705 +       sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid);
706 +       wire_gid_to_gid(gid, &rem_dest->gid);
707  
708 -       if (pp_connect_ctx(ctx, ib_port, my_dest->psn, mtu, sl, rem_dest)) {
709 +       if (pp_connect_ctx(ctx, ib_port, my_dest->psn, mtu, sl, rem_dest, sgid_idx)) {
710                 fprintf(stderr, "Couldn't connect to remote QP\n");
711                 free(rem_dest);
712                 rem_dest = NULL;
713                 goto out;
714         }
715  
716 -       sprintf(msg, "%04x:%06x:%06x", my_dest->lid, my_dest->qpn, my_dest->psn);
717 +       gid_to_wire_gid(&my_dest->gid, gid);
718 +       sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid);
719         if (write(connfd, msg, sizeof msg) != sizeof msg) {
720                 fprintf(stderr, "Couldn't send local address\n");
721                 free(rem_dest);
722 @@ -281,7 +298,7 @@ static struct pingpong_context *pp_init_
723  {
724         struct pingpong_context *ctx;
725  
726 -       ctx = malloc(sizeof *ctx);
727 +       ctx = calloc(1, sizeof *ctx);
728         if (!ctx)
729                 return NULL;
730  
731 @@ -469,6 +486,7 @@ static void usage(const char *argv0)
732         printf("  -n, --iters=<iters>    number of exchanges (default 1000)\n");
733         printf("  -l, --sl=<sl>          service level value\n");
734         printf("  -e, --events           sleep on CQ events (default poll)\n");
735 +       printf("  -g, --gid-idx=<gid index> local port gid index\n");
736  }
737  
738  int main(int argc, char *argv[])
739 @@ -492,6 +510,8 @@ int main(int argc, char *argv[])
740         int                      rcnt, scnt;
741         int                      num_cq_events = 0;
742         int                      sl = 0;
743 +       int                      gidx = -1;
744 +       char                     gid[33];
745  
746         srand48(getpid() * time(NULL));
747  
748 @@ -508,10 +528,11 @@ int main(int argc, char *argv[])
749                         { .name = "iters",    .has_arg = 1, .val = 'n' },
750                         { .name = "sl",       .has_arg = 1, .val = 'l' },
751                         { .name = "events",   .has_arg = 0, .val = 'e' },
752 +                       { .name = "gid-idx",  .has_arg = 1, .val = 'g' },
753                         { 0 }
754                 };
755  
756 -               c = getopt_long(argc, argv, "p:d:i:s:m:r:n:l:e", long_options, NULL);
757 +               c = getopt_long(argc, argv, "p:d:i:s:m:r:n:l:eg:", long_options, NULL);
758                 if (c == -1)
759                         break;
760  
761 @@ -564,6 +585,10 @@ int main(int argc, char *argv[])
762                         ++use_event;
763                         break;
764  
765 +               case 'g':
766 +                       gidx = strtol(optarg, NULL, 0);
767 +                       break;
768 +
769                 default:
770                         usage(argv[0]);
771                         return 1;
772 @@ -619,30 +644,45 @@ int main(int argc, char *argv[])
773                         return 1;
774                 }
775  
776 -       my_dest.lid = pp_get_local_lid(ctx->context, ib_port);
777 -       my_dest.qpn = ctx->qp->qp_num;
778 -       my_dest.psn = lrand48() & 0xffffff;
779 -       if (!my_dest.lid) {
780 +       if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) {
781 +               fprintf(stderr, "Couldn't get port info\n");
782 +               return 1;
783 +       }
784 +
785 +       my_dest.lid = ctx->portinfo.lid;
786 +       if (ctx->portinfo.link_layer == IBV_LINK_LAYER_INFINIBAND && !my_dest.lid) {
787                 fprintf(stderr, "Couldn't get local LID\n");
788                 return 1;
789         }
790  
791 -       printf("  local address:  LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n",
792 -              my_dest.lid, my_dest.qpn, my_dest.psn);
793 +       if (gidx >= 0) {
794 +               if (ibv_query_gid(ctx->context, ib_port, gidx, &my_dest.gid)) {
795 +                       fprintf(stderr, "Could not get local gid for gid index %d\n", gidx);
796 +                       return 1;
797 +               }
798 +       } else
799 +               memset(&my_dest.gid, 0, sizeof my_dest.gid);
800 +
801 +       my_dest.qpn = ctx->qp->qp_num;
802 +       my_dest.psn = lrand48() & 0xffffff;
803 +       inet_ntop(AF_INET6, &my_dest.gid, gid, sizeof gid);
804 +       printf("  local address:  LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
805 +              my_dest.lid, my_dest.qpn, my_dest.psn, gid);
806  
807         if (servername)
808                 rem_dest = pp_client_exch_dest(servername, port, &my_dest);
809         else
810 -               rem_dest = pp_server_exch_dest(ctx, ib_port, mtu, port, sl, &my_dest);
811 +               rem_dest = pp_server_exch_dest(ctx, ib_port, mtu, port, sl, &my_dest, gidx);
812  
813         if (!rem_dest)
814                 return 1;
815  
816 -       printf("  remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n",
817 -              rem_dest->lid, rem_dest->qpn, rem_dest->psn);
818 +       inet_ntop(AF_INET6, &rem_dest->gid, gid, sizeof gid);
819 +       printf("  remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
820 +              rem_dest->lid, rem_dest->qpn, rem_dest->psn, gid);
821  
822         if (servername)
823 -               if (pp_connect_ctx(ctx, ib_port, my_dest.psn, mtu, sl, rem_dest))
824 +               if (pp_connect_ctx(ctx, ib_port, my_dest.psn, mtu, sl, rem_dest, gidx))
825                         return 1;
826  
827         ctx->pending = PINGPONG_RECV_WRID;
828 Index: libibverbs/examples/ud_pingpong.c
829 ===================================================================
830 --- libibverbs.orig/examples/ud_pingpong.c      2010-02-08 15:04:24.389329000 +0200
831 +++ libibverbs/examples/ud_pingpong.c   2010-03-17 14:08:48.502754000 +0200
832 @@ -68,16 +68,18 @@ struct pingpong_context {
833         int                      size;
834         int                      rx_depth;
835         int                      pending;
836 +       struct ibv_port_attr     portinfo;
837  };
838  
839  struct pingpong_dest {
840         int lid;
841         int qpn;
842         int psn;
843 +       union ibv_gid gid;
844  };
845  
846  static int pp_connect_ctx(struct pingpong_context *ctx, int port, int my_psn,
847 -                         int sl, struct pingpong_dest *dest)
848 +                         int sl, struct pingpong_dest *dest, int sgid_idx)
849  {
850         struct ibv_ah_attr ah_attr = {
851                 .is_global     = 0,
852 @@ -105,6 +107,13 @@ static int pp_connect_ctx(struct pingpon
853                 return 1;
854         }
855  
856 +       if (dest->gid.global.interface_id) {
857 +               ah_attr.is_global = 1;
858 +               ah_attr.grh.hop_limit = 1;
859 +               ah_attr.grh.dgid = dest->gid;
860 +               ah_attr.grh.sgid_index = sgid_idx;
861 +       }
862 +
863         ctx->ah = ibv_create_ah(ctx->pd, &ah_attr);
864         if (!ctx->ah) {
865                 fprintf(stderr, "Failed to create AH\n");
866 @@ -123,10 +132,11 @@ static struct pingpong_dest *pp_client_e
867                 .ai_socktype = SOCK_STREAM
868         };
869         char *service;
870 -       char msg[sizeof "0000:000000:000000"];
871 +       char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
872         int n;
873         int sockfd = -1;
874         struct pingpong_dest *rem_dest = NULL;
875 +       char gid[33];
876  
877         if (asprintf(&service, "%d", port) < 0)
878                 return NULL;
879 @@ -157,7 +167,8 @@ static struct pingpong_dest *pp_client_e
880                 return NULL;
881         }
882  
883 -       sprintf(msg, "%04x:%06x:%06x", my_dest->lid, my_dest->qpn, my_dest->psn);
884 +       gid_to_wire_gid(&my_dest->gid, gid);
885 +       sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid);
886         if (write(sockfd, msg, sizeof msg) != sizeof msg) {
887                 fprintf(stderr, "Couldn't send local address\n");
888                 goto out;
889 @@ -175,7 +186,8 @@ static struct pingpong_dest *pp_client_e
890         if (!rem_dest)
891                 goto out;
892  
893 -       sscanf(msg, "%x:%x:%x", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn);
894 +       sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid);
895 +       wire_gid_to_gid(gid, &rem_dest->gid);
896  
897  out:
898         close(sockfd);
899 @@ -184,7 +196,8 @@ out:
900  
901  static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx,
902                                                  int ib_port, int port, int sl,
903 -                                                const struct pingpong_dest *my_dest)
904 +                                                const struct pingpong_dest *my_dest,
905 +                                                int sgid_idx)
906  {
907         struct addrinfo *res, *t;
908         struct addrinfo hints = {
909 @@ -193,10 +206,11 @@ static struct pingpong_dest *pp_server_e
910                 .ai_socktype = SOCK_STREAM
911         };
912         char *service;
913 -       char msg[sizeof "0000:000000:000000"];
914 +       char msg[sizeof "0000:000000:000000:00000000000000000000000000000000"];
915         int n;
916         int sockfd = -1, connfd;
917         struct pingpong_dest *rem_dest = NULL;
918 +       char gid[33];
919  
920         if (asprintf(&service, "%d", port) < 0)
921                 return NULL;
922 @@ -250,16 +264,18 @@ static struct pingpong_dest *pp_server_e
923         if (!rem_dest)
924                 goto out;
925  
926 -       sscanf(msg, "%x:%x:%x", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn);
927 +       sscanf(msg, "%x:%x:%x:%s", &rem_dest->lid, &rem_dest->qpn, &rem_dest->psn, gid);
928 +       wire_gid_to_gid(gid, &rem_dest->gid);
929  
930 -       if (pp_connect_ctx(ctx, ib_port, my_dest->psn, sl, rem_dest)) {
931 +       if (pp_connect_ctx(ctx, ib_port, my_dest->psn, sl, rem_dest, sgid_idx)) {
932                 fprintf(stderr, "Couldn't connect to remote QP\n");
933                 free(rem_dest);
934                 rem_dest = NULL;
935                 goto out;
936         }
937  
938 -       sprintf(msg, "%04x:%06x:%06x", my_dest->lid, my_dest->qpn, my_dest->psn);
939 +       gid_to_wire_gid(&my_dest->gid, gid);
940 +       sprintf(msg, "%04x:%06x:%06x:%s", my_dest->lid, my_dest->qpn, my_dest->psn, gid);
941         if (write(connfd, msg, sizeof msg) != sizeof msg) {
942                 fprintf(stderr, "Couldn't send local address\n");
943                 free(rem_dest);
944 @@ -474,10 +490,11 @@ static void usage(const char *argv0)
945         printf("  -p, --port=<port>      listen on/connect to port <port> (default 18515)\n");
946         printf("  -d, --ib-dev=<dev>     use IB device <dev> (default first device found)\n");
947         printf("  -i, --ib-port=<port>   use port <port> of IB device (default 1)\n");
948 -       printf("  -s, --size=<size>      size of message to exchange (default 2048)\n");
949 +       printf("  -s, --size=<size>      size of message to exchange (default 1024)\n");
950         printf("  -r, --rx-depth=<dep>   number of receives to post at a time (default 500)\n");
951         printf("  -n, --iters=<iters>    number of exchanges (default 1000)\n");
952         printf("  -e, --events           sleep on CQ events (default poll)\n");
953 +       printf("  -g, --gid-idx=<gid index> local port gid index\n");
954  }
955  
956  int main(int argc, char *argv[])
957 @@ -492,7 +509,7 @@ int main(int argc, char *argv[])
958         char                    *servername = NULL;
959         int                      port = 18515;
960         int                      ib_port = 1;
961 -       int                      size = 2048;
962 +       int                      size = 1024;
963         int                      rx_depth = 500;
964         int                      iters = 1000;
965         int                      use_event = 0;
966 @@ -500,6 +517,8 @@ int main(int argc, char *argv[])
967         int                      rcnt, scnt;
968         int                      num_cq_events = 0;
969         int                      sl = 0;
970 +       int                      gidx = -1;
971 +       char                     gid[33];
972  
973         srand48(getpid() * time(NULL));
974  
975 @@ -515,10 +534,11 @@ int main(int argc, char *argv[])
976                         { .name = "iters",    .has_arg = 1, .val = 'n' },
977                         { .name = "sl",       .has_arg = 1, .val = 'l' },
978                         { .name = "events",   .has_arg = 0, .val = 'e' },
979 +                       { .name = "gid-idx",  .has_arg = 1, .val = 'g' },
980                         { 0 }
981                 };
982  
983 -               c = getopt_long(argc, argv, "p:d:i:s:r:n:l:e", long_options, NULL);
984 +               c = getopt_long(argc, argv, "p:d:i:s:r:n:l:eg:", long_options, NULL);
985                 if (c == -1)
986                         break;
987  
988 @@ -563,6 +583,10 @@ int main(int argc, char *argv[])
989                         ++use_event;
990                         break;
991  
992 +               case 'g':
993 +                       gidx = strtol(optarg, NULL, 0);
994 +                       break;
995 +
996                 default:
997                         usage(argv[0]);
998                         return 1;
999 @@ -618,30 +642,41 @@ int main(int argc, char *argv[])
1000                         return 1;
1001                 }
1002  
1003 -       my_dest.lid = pp_get_local_lid(ctx->context, ib_port);
1004 -       my_dest.qpn = ctx->qp->qp_num;
1005 -       my_dest.psn = lrand48() & 0xffffff;
1006 -       if (!my_dest.lid) {
1007 -               fprintf(stderr, "Couldn't get local LID\n");
1008 +       if (pp_get_port_info(ctx->context, ib_port, &ctx->portinfo)) {
1009 +               fprintf(stderr, "Couldn't get port info\n");
1010                 return 1;
1011         }
1012 +       my_dest.lid = ctx->portinfo.lid;
1013 +
1014 +       my_dest.qpn = ctx->qp->qp_num;
1015 +       my_dest.psn = lrand48() & 0xffffff;
1016 +
1017 +       if (gidx >= 0) {
1018 +               if (ibv_query_gid(ctx->context, ib_port, gidx, &my_dest.gid)) {
1019 +                       fprintf(stderr, "Could not get local gid for gid index %d\n", gidx);
1020 +                       return 1;
1021 +               }
1022 +       } else
1023 +               memset(&my_dest.gid, 0, sizeof my_dest.gid);
1024  
1025 -       printf("  local address:  LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n",
1026 -              my_dest.lid, my_dest.qpn, my_dest.psn);
1027 +       inet_ntop(AF_INET6, &my_dest.gid, gid, sizeof gid);
1028 +       printf("  local address:  LID 0x%04x, QPN 0x%06x, PSN 0x%06x: GID %s\n",
1029 +              my_dest.lid, my_dest.qpn, my_dest.psn, gid);
1030  
1031         if (servername)
1032                 rem_dest = pp_client_exch_dest(servername, port, &my_dest);
1033         else
1034 -               rem_dest = pp_server_exch_dest(ctx, ib_port, port, sl, &my_dest);
1035 +               rem_dest = pp_server_exch_dest(ctx, ib_port, port, sl, &my_dest, gidx);
1036  
1037         if (!rem_dest)
1038                 return 1;
1039  
1040 -       printf("  remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x\n",
1041 -              rem_dest->lid, rem_dest->qpn, rem_dest->psn);
1042 +       inet_ntop(AF_INET6, &rem_dest->gid, gid, sizeof gid);
1043 +       printf("  remote address: LID 0x%04x, QPN 0x%06x, PSN 0x%06x, GID %s\n",
1044 +              rem_dest->lid, rem_dest->qpn, rem_dest->psn, gid);
1045  
1046         if (servername)
1047 -               if (pp_connect_ctx(ctx, ib_port, my_dest.psn, sl, rem_dest))
1048 +               if (pp_connect_ctx(ctx, ib_port, my_dest.psn, sl, rem_dest, gidx))
1049                         return 1;
1050  
1051         ctx->pending = PINGPONG_RECV_WRID;