X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lnet%2Fklnds%2Fo2iblnd%2Fo2iblnd_cb.c;h=8127bd281eddf8ceca048a051210055c3ae1bef1;hb=daee9d5d61fb14cf998a3444ed33152cfc27fab5;hp=431aa909670013d0d101856eb1e3a14a90a12095;hpb=1f7e6dd796f7e8e6ca9f55b9c6dc54efb69a5e34;p=fs%2Flustre-release.git diff --git a/lnet/klnds/o2iblnd/o2iblnd_cb.c b/lnet/klnds/o2iblnd/o2iblnd_cb.c index 431aa90..8127bd2 100644 --- a/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -1207,6 +1207,48 @@ kiblnd_queue_tx (kib_tx_t *tx, kib_conn_t *conn) kiblnd_check_sends(conn); } +static int kiblnd_resolve_addr(struct rdma_cm_id *cmid, + struct sockaddr_in *srcaddr, + struct sockaddr_in *dstaddr, + int timeout_ms) +{ + unsigned short port; + int rc; + +#ifdef HAVE_OFED_RDMA_SET_REUSEADDR + /* allow the port to be reused */ + rc = rdma_set_reuseaddr(cmid, 1); + if (rc != 0) { + CERROR("Unable to set reuse on cmid: %d\n", rc); + return rc; + } +#endif + + /* look for a free privileged port */ + for (port = PROT_SOCK-1; port > 0; port--) { + srcaddr->sin_port = htons(port); + rc = rdma_resolve_addr(cmid, + (struct sockaddr *)srcaddr, + (struct sockaddr *)dstaddr, + timeout_ms); + if (rc == 0) { + CDEBUG(D_NET, "bound to port %hu\n", port); + return 0; + } else if (rc == -EADDRINUSE || rc == -EADDRNOTAVAIL) { + CDEBUG(D_NET, "bind to port %hu failed: %d\n", + port, rc); + } else { + return rc; + } + } + + CERROR("Failed to bind to a free privileged port\n"); +#ifndef HAVE_OFED_RDMA_SET_REUSEADDR + CERROR("You may need IB verbs that supports rdma_set_reuseaddr()\n"); +#endif + return rc; +} + void kiblnd_connect_peer (kib_peer_t *peer) { @@ -1240,22 +1282,30 @@ kiblnd_connect_peer (kib_peer_t *peer) kiblnd_peer_addref(peer); /* cmid's ref */ - rc = rdma_resolve_addr(cmid, - (struct sockaddr *)&srcaddr, - (struct sockaddr *)&dstaddr, - *kiblnd_tunables.kib_timeout * 1000); - if (rc == 0) { - LASSERT (cmid->device != NULL); - CDEBUG(D_NET, "%s: connection bound to %s:%u.%u.%u.%u:%s\n", - libcfs_nid2str(peer->ibp_nid), dev->ibd_ifname, - HIPQUAD(dev->ibd_ifip), cmid->device->name); - return; + if (*kiblnd_tunables.kib_use_priv_port) { + rc = kiblnd_resolve_addr(cmid, &srcaddr, &dstaddr, + *kiblnd_tunables.kib_timeout * 1000); + } else { + rc = rdma_resolve_addr(cmid, + (struct sockaddr *)&srcaddr, + (struct sockaddr *)&dstaddr, + *kiblnd_tunables.kib_timeout * 1000); + } + if (rc != 0) { + /* Can't initiate address resolution: */ + CERROR("Can't resolve addr for %s: %d\n", + libcfs_nid2str(peer->ibp_nid), rc); + goto failed2; } - /* Can't initiate address resolution: */ - CERROR("Can't resolve addr for %s: %d\n", - libcfs_nid2str(peer->ibp_nid), rc); + LASSERT (cmid->device != NULL); + CDEBUG(D_NET, "%s: connection bound to %s:%u.%u.%u.%u:%s\n", + libcfs_nid2str(peer->ibp_nid), dev->ibd_ifname, + HIPQUAD(dev->ibd_ifip), cmid->device->name); + return; + + failed2: kiblnd_peer_decref(peer); /* cmid's ref */ rdma_destroy_id(cmid); failed: @@ -2126,7 +2176,7 @@ kiblnd_passive_connect (struct rdma_cm_id *cmid, void *priv, int priv_nob) int version = IBLND_MSG_VERSION; unsigned long flags; int rc; - + struct sockaddr_in *peer_addr; LASSERT (!cfs_in_interrupt()); /* cmid inherits 'context' from the corresponding listener id */ @@ -2138,6 +2188,15 @@ kiblnd_passive_connect (struct rdma_cm_id *cmid, void *priv, int priv_nob) rej.ibr_why = IBLND_REJECT_FATAL; rej.ibr_cp.ibcp_max_msg_size = IBLND_MSG_SIZE; + peer_addr = (struct sockaddr_in *)&(cmid->route.addr.dst_addr); + if (*kiblnd_tunables.kib_require_priv_port && + ntohs(peer_addr->sin_port) >= PROT_SOCK) { + __u32 ip = ntohl(peer_addr->sin_addr.s_addr); + CERROR("Peer's port (%u.%u.%u.%u:%hu) is not privileged\n", + HIPQUAD(ip), ntohs(peer_addr->sin_port)); + goto failed; + } + if (priv_nob < offsetof(kib_msg_t, ibm_type)) { CERROR("Short connection request\n"); goto failed;