From: Mr NeilBrown Date: Tue, 7 Jul 2020 04:03:23 +0000 (+1000) Subject: LU-10391 socklnd: Change ksock_hello_msg to struct lnet_nid X-Git-Tag: 2.15.0-RC1~74 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=d1fb459cca931f84f087aae5519bd86eca92009f;p=fs%2Flustre-release.git LU-10391 socklnd: Change ksock_hello_msg to struct lnet_nid 'struct ksock_hello_msg' now stores 'struct lnet_nid', but it is converted to 'struct ksock_hello_msg_nid4' - the old format - for transmit, which is converted back on receive. This opens the way for a new version of the hello protocol which will use 16byte addresses. Test-Parameters: trivial Test-Parameters: serverversion=2.12 serverdistro=el7.9 testlist=runtests Test-Parameters: clientversion=2.12 testlist=runtests Signed-off-by: Mr NeilBrown Change-Id: I22e86f9088f6001f203f24f93ef292fcf2a8e69f Reviewed-on: https://review.whamcloud.com/43610 Reviewed-by: James Simmons Reviewed-by: Serguei Smirnov Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/lnet/include/lnet/socklnd.h b/lnet/include/lnet/socklnd.h index be2f502..22e60ed 100644 --- a/lnet/include/lnet/socklnd.h +++ b/lnet/include/lnet/socklnd.h @@ -35,17 +35,31 @@ #include struct ksock_hello_msg { - __u32 kshm_magic; /* magic number of socklnd message */ - __u32 kshm_version; /* version of socklnd message */ + __u32 kshm_magic; /* LNET_PROTO_MAGIC */ + __u32 kshm_version; /* KSOCK_PROTO_V* */ + struct lnet_nid kshm_src_nid; /* sender's nid */ + struct lnet_nid kshm_dst_nid; /* destination nid */ + lnet_pid_t kshm_src_pid; /* sender's pid */ + lnet_pid_t kshm_dst_pid; /* destination pid */ + __u64 kshm_src_incarnation; /* sender's incarnation */ + __u64 kshm_dst_incarnation; /* destination's incarnation */ + __u32 kshm_ctype; /* SOCKLND_CONN_* */ + __u32 kshm_nips; /* always sent as zero */ + __u32 kshm_ips[0]; /* deprecated */ +} __packed; + +struct ksock_hello_msg_nid4 { + __u32 kshm_magic; /* LNET_PROTO_MAGIC */ + __u32 kshm_version; /* KSOCK_PROTO_V* */ lnet_nid_t kshm_src_nid; /* sender's nid */ lnet_nid_t kshm_dst_nid; /* destination nid */ lnet_pid_t kshm_src_pid; /* sender's pid */ lnet_pid_t kshm_dst_pid; /* destination pid */ __u64 kshm_src_incarnation; /* sender's incarnation */ __u64 kshm_dst_incarnation; /* destination's incarnation */ - __u32 kshm_ctype; /* connection type */ - __u32 kshm_nips; /* # IP addrs */ - __u32 kshm_ips[0]; /* IP addrs */ + __u32 kshm_ctype; /* SOCKLND_CONN_* */ + __u32 kshm_nips; /* sent as zero */ + __u32 kshm_ips[0]; /* deprecated */ } __packed; struct ksock_msg_hdr { diff --git a/lnet/klnds/socklnd/socklnd.c b/lnet/klnds/socklnd/socklnd.c index 011c1bb..70add94 100644 --- a/lnet/klnds/socklnd/socklnd.c +++ b/lnet/klnds/socklnd/socklnd.c @@ -853,7 +853,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_conn_cb *conn_cb, { rwlock_t *global_lock = &ksocknal_data.ksnd_global_lock; LIST_HEAD(zombies); - struct lnet_process_id peerid4; + struct lnet_processid peerid; u64 incarnation; struct ksock_conn *conn; struct ksock_conn *conn2; @@ -923,7 +923,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_conn_cb *conn_cb, /* Active connection sends HELLO eagerly */ hello->kshm_nips = 0; - peerid4 = lnet_pid_to_pid4(&peer_ni->ksnp_id); + peerid = peer_ni->ksnp_id; write_lock_bh(global_lock); conn->ksnc_proto = peer_ni->ksnp_proto; @@ -939,34 +939,31 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_conn_cb *conn_cb, #endif } - rc = ksocknal_send_hello(ni, conn, peerid4.nid, hello); + rc = ksocknal_send_hello(ni, conn, &peerid.nid, hello); if (rc != 0) goto failed_1; } else { - peerid4.nid = LNET_NID_ANY; - peerid4.pid = LNET_PID_ANY; + peerid.nid = LNET_ANY_NID; + peerid.pid = LNET_PID_ANY; /* Passive, get protocol from peer_ni */ conn->ksnc_proto = NULL; } - rc = ksocknal_recv_hello(ni, conn, hello, &peerid4, &incarnation); + rc = ksocknal_recv_hello(ni, conn, hello, &peerid, &incarnation); if (rc < 0) goto failed_1; LASSERT(rc == 0 || active); LASSERT(conn->ksnc_proto != NULL); - LASSERT(peerid4.nid != LNET_NID_ANY); + LASSERT(!LNET_NID_IS_ANY(&peerid.nid)); - cpt = lnet_cpt_of_nid(peerid4.nid, ni); + cpt = lnet_nid2cpt(&peerid.nid, ni); if (active) { ksocknal_peer_addref(peer_ni); write_lock_bh(global_lock); } else { - struct lnet_processid peerid; - - lnet_pid4_to_pid(peerid4, &peerid); peer_ni = ksocknal_create_peer(ni, &peerid); if (IS_ERR(peer_ni)) { rc = PTR_ERR(peer_ni); @@ -996,7 +993,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_conn_cb *conn_cb, /* Am I already connecting to this guy? Resolve in * favour of higher NID... */ - if (peerid4.nid < lnet_nid_to_nid4(&ni->ni_nid) && + if (memcmp(&peerid.nid, &ni->ni_nid, sizeof(peerid.nid)) < 0 && ksocknal_connecting(peer_ni->ksnp_conn_cb, ((struct sockaddr *) &conn->ksnc_peeraddr))) { rc = EALREADY; @@ -1152,7 +1149,6 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_conn_cb *conn_cb, } write_unlock_bh(global_lock); - /* We've now got a new connection. Any errors from here on are just * like "normal" comms errors and we close the connection normally. * NB (a) we still have to send the reply HELLO for passive @@ -1163,13 +1159,13 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_conn_cb *conn_cb, CDEBUG(D_NET, "New conn %s p %d.x %pIS -> %pISp" " incarnation:%lld sched[%d]\n", - libcfs_id2str(peerid4), conn->ksnc_proto->pro_version, + libcfs_idstr(&peerid), conn->ksnc_proto->pro_version, &conn->ksnc_myaddr, &conn->ksnc_peeraddr, incarnation, cpt); if (!active) { hello->kshm_nips = 0; - rc = ksocknal_send_hello(ni, conn, peerid4.nid, hello); + rc = ksocknal_send_hello(ni, conn, &peerid.nid, hello); } LIBCFS_FREE(hello, offsetof(struct ksock_hello_msg, @@ -1226,10 +1222,10 @@ failed_2: if (warn != NULL) { if (rc < 0) CERROR("Not creating conn %s type %d: %s\n", - libcfs_id2str(peerid4), conn->ksnc_type, warn); + libcfs_idstr(&peerid), conn->ksnc_type, warn); else CDEBUG(D_NET, "Not creating conn %s type %d: %s\n", - libcfs_id2str(peerid4), conn->ksnc_type, warn); + libcfs_idstr(&peerid), conn->ksnc_type, warn); } if (!active) { @@ -1239,7 +1235,7 @@ failed_2: */ conn->ksnc_type = SOCKLND_CONN_NONE; hello->kshm_nips = 0; - ksocknal_send_hello(ni, conn, peerid4.nid, hello); + ksocknal_send_hello(ni, conn, &peerid.nid, hello); } write_lock_bh(global_lock); diff --git a/lnet/klnds/socklnd/socklnd.h b/lnet/klnds/socklnd/socklnd.h index 48427a3..7ce64a4 100644 --- a/lnet/klnds/socklnd/socklnd.h +++ b/lnet/klnds/socklnd/socklnd.h @@ -642,10 +642,11 @@ extern int ksocknal_scheduler(void *arg); extern int ksocknal_connd(void *arg); extern int ksocknal_reaper(void *arg); int ksocknal_send_hello(struct lnet_ni *ni, struct ksock_conn *conn, - lnet_nid_t peer_nid, struct ksock_hello_msg *hello); + struct lnet_nid *peer_nid, + struct ksock_hello_msg *hello); int ksocknal_recv_hello(struct lnet_ni *ni, struct ksock_conn *conn, struct ksock_hello_msg *hello, - struct lnet_process_id *id, + struct lnet_processid *id, __u64 *incarnation); extern void ksocknal_read_callback(struct ksock_conn *conn); extern void ksocknal_write_callback(struct ksock_conn *conn); diff --git a/lnet/klnds/socklnd/socklnd_cb.c b/lnet/klnds/socklnd/socklnd_cb.c index e3d5e73..fe3e6cb 100644 --- a/lnet/klnds/socklnd/socklnd_cb.c +++ b/lnet/klnds/socklnd/socklnd_cb.c @@ -1659,50 +1659,50 @@ void ksocknal_write_callback(struct ksock_conn *conn) static const struct ksock_proto * ksocknal_parse_proto_version(struct ksock_hello_msg *hello) { - __u32 version = 0; + __u32 version = 0; - if (hello->kshm_magic == LNET_PROTO_MAGIC) - version = hello->kshm_version; - else if (hello->kshm_magic == __swab32(LNET_PROTO_MAGIC)) - version = __swab32(hello->kshm_version); + if (hello->kshm_magic == LNET_PROTO_MAGIC) + version = hello->kshm_version; + else if (hello->kshm_magic == __swab32(LNET_PROTO_MAGIC)) + version = __swab32(hello->kshm_version); - if (version != 0) { + if (version) { #if SOCKNAL_VERSION_DEBUG - if (*ksocknal_tunables.ksnd_protocol == 1) - return NULL; + if (*ksocknal_tunables.ksnd_protocol == 1) + return NULL; - if (*ksocknal_tunables.ksnd_protocol == 2 && - version == KSOCK_PROTO_V3) - return NULL; + if (*ksocknal_tunables.ksnd_protocol == 2 && + version == KSOCK_PROTO_V3) + return NULL; #endif - if (version == KSOCK_PROTO_V2) - return &ksocknal_protocol_v2x; + if (version == KSOCK_PROTO_V2) + return &ksocknal_protocol_v2x; - if (version == KSOCK_PROTO_V3) - return &ksocknal_protocol_v3x; + if (version == KSOCK_PROTO_V3) + return &ksocknal_protocol_v3x; - return NULL; - } + return NULL; + } - if (hello->kshm_magic == le32_to_cpu(LNET_PROTO_TCP_MAGIC)) { + if (hello->kshm_magic == le32_to_cpu(LNET_PROTO_TCP_MAGIC)) { struct lnet_magicversion *hmv; BUILD_BUG_ON(sizeof(struct lnet_magicversion) != - offsetof(struct ksock_hello_msg, kshm_src_nid)); + offsetof(struct ksock_hello_msg, kshm_src_nid)); hmv = (struct lnet_magicversion *)hello; - if (hmv->version_major == cpu_to_le16 (KSOCK_PROTO_V1_MAJOR) && - hmv->version_minor == cpu_to_le16 (KSOCK_PROTO_V1_MINOR)) - return &ksocknal_protocol_v1x; - } + if (hmv->version_major == cpu_to_le16 (KSOCK_PROTO_V1_MAJOR) && + hmv->version_minor == cpu_to_le16 (KSOCK_PROTO_V1_MINOR)) + return &ksocknal_protocol_v1x; + } - return NULL; + return NULL; } int ksocknal_send_hello(struct lnet_ni *ni, struct ksock_conn *conn, - lnet_nid_t peer_nid, struct ksock_hello_msg *hello) + struct lnet_nid *peer_nid, struct ksock_hello_msg *hello) { /* CAVEAT EMPTOR: this byte flips 'ipaddrs' */ struct ksock_net *net = (struct ksock_net *)ni->ni_data; @@ -1712,12 +1712,12 @@ ksocknal_send_hello(struct lnet_ni *ni, struct ksock_conn *conn, /* rely on caller to hold a ref on socket so it wouldn't disappear */ LASSERT(conn->ksnc_proto != NULL); - hello->kshm_src_nid = lnet_nid_to_nid4(&ni->ni_nid); - hello->kshm_dst_nid = peer_nid; - hello->kshm_src_pid = the_lnet.ln_pid; + hello->kshm_src_nid = ni->ni_nid; + hello->kshm_dst_nid = *peer_nid; + hello->kshm_src_pid = the_lnet.ln_pid; hello->kshm_src_incarnation = net->ksnn_incarnation; - hello->kshm_ctype = conn->ksnc_type; + hello->kshm_ctype = conn->ksnc_type; return conn->ksnc_proto->pro_send_hello(conn, hello); } @@ -1725,24 +1725,23 @@ ksocknal_send_hello(struct lnet_ni *ni, struct ksock_conn *conn, static int ksocknal_invert_type(int type) { - switch (type) - { - case SOCKLND_CONN_ANY: - case SOCKLND_CONN_CONTROL: - return (type); - case SOCKLND_CONN_BULK_IN: - return SOCKLND_CONN_BULK_OUT; - case SOCKLND_CONN_BULK_OUT: - return SOCKLND_CONN_BULK_IN; - default: - return (SOCKLND_CONN_NONE); - } + switch (type) { + case SOCKLND_CONN_ANY: + case SOCKLND_CONN_CONTROL: + return (type); + case SOCKLND_CONN_BULK_IN: + return SOCKLND_CONN_BULK_OUT; + case SOCKLND_CONN_BULK_OUT: + return SOCKLND_CONN_BULK_IN; + default: + return (SOCKLND_CONN_NONE); + } } int ksocknal_recv_hello(struct lnet_ni *ni, struct ksock_conn *conn, struct ksock_hello_msg *hello, - struct lnet_process_id *peerid, + struct lnet_processid *peerid, __u64 *incarnation) { /* Return < 0 fatal error @@ -1750,13 +1749,13 @@ ksocknal_recv_hello(struct lnet_ni *ni, struct ksock_conn *conn, * EALREADY lost connection race * EPROTO protocol version mismatch */ - struct socket *sock = conn->ksnc_sock; - int active = (conn->ksnc_proto != NULL); - int timeout; - int proto_match; - int rc; + struct socket *sock = conn->ksnc_sock; + int active = (conn->ksnc_proto != NULL); + int timeout; + int proto_match; + int rc; const struct ksock_proto *proto; - struct lnet_process_id recv_id; + struct lnet_processid recv_id; /* socket type set on active connections - not set on passive */ LASSERT(!active == !(conn->ksnc_type != SOCKLND_CONN_NONE)); @@ -1806,8 +1805,7 @@ ksocknal_recv_hello(struct lnet_ni *ni, struct ksock_conn *conn, conn->ksnc_proto = &ksocknal_protocol_v1x; #endif hello->kshm_nips = 0; - ksocknal_send_hello(ni, conn, - lnet_nid_to_nid4(&ni->ni_nid), + ksocknal_send_hello(ni, conn, &ni->ni_nid, hello); } @@ -1831,7 +1829,7 @@ ksocknal_recv_hello(struct lnet_ni *ni, struct ksock_conn *conn, *incarnation = hello->kshm_src_incarnation; - if (hello->kshm_src_nid == LNET_NID_ANY) { + if (LNET_NID_IS_ANY(&hello->kshm_src_nid)) { CERROR("Expecting a HELLO hdr with a NID, but got LNET_NID_ANY from %pIS\n", &conn->ksnc_peeraddr); return -EPROTO; @@ -1845,10 +1843,12 @@ ksocknal_recv_hello(struct lnet_ni *ni, struct ksock_conn *conn, &conn->ksnc_peeraddr) | LNET_PID_USERFLAG; LASSERT(conn->ksnc_peeraddr.ss_family == AF_INET); - recv_id.nid = LNET_MKNID( - LNET_NID_NET(&ni->ni_nid), - ntohl(((struct sockaddr_in *) - &conn->ksnc_peeraddr)->sin_addr.s_addr)); + memset(&recv_id.nid, 0, sizeof(recv_id.nid)); + recv_id.nid.nid_type = ni->ni_nid.nid_type; + recv_id.nid.nid_num = ni->ni_nid.nid_num; + recv_id.nid.nid_addr[0] = + ((struct sockaddr_in *) + &conn->ksnc_peeraddr)->sin_addr.s_addr; } else { recv_id.nid = hello->kshm_src_nid; recv_id.pid = hello->kshm_src_pid; @@ -1861,7 +1861,7 @@ ksocknal_recv_hello(struct lnet_ni *ni, struct ksock_conn *conn, conn->ksnc_type = ksocknal_invert_type(hello->kshm_ctype); if (conn->ksnc_type == SOCKLND_CONN_NONE) { CERROR("Unexpected type %d from %s ip %pIS\n", - hello->kshm_ctype, libcfs_id2str(*peerid), + hello->kshm_ctype, libcfs_idstr(peerid), &conn->ksnc_peeraddr); return -EPROTO; } @@ -1869,12 +1869,12 @@ ksocknal_recv_hello(struct lnet_ni *ni, struct ksock_conn *conn, } if (peerid->pid != recv_id.pid || - peerid->nid != recv_id.nid) { + !nid_same(&peerid->nid, &recv_id.nid)) { LCONSOLE_ERROR_MSG(0x130, "Connected successfully to %s on host %pIS, but they claimed they were %s; please check your Lustre configuration.\n", - libcfs_id2str(*peerid), + libcfs_idstr(peerid), &conn->ksnc_peeraddr, - libcfs_id2str(recv_id)); + libcfs_idstr(&recv_id)); return -EPROTO; } @@ -1885,7 +1885,7 @@ ksocknal_recv_hello(struct lnet_ni *ni, struct ksock_conn *conn, if (ksocknal_invert_type(hello->kshm_ctype) != conn->ksnc_type) { CERROR("Mismatched types: me %d, %s ip %pIS %d\n", - conn->ksnc_type, libcfs_id2str(*peerid), + conn->ksnc_type, libcfs_idstr(peerid), &conn->ksnc_peeraddr, hello->kshm_ctype); return -EPROTO; diff --git a/lnet/klnds/socklnd/socklnd_proto.c b/lnet/klnds/socklnd/socklnd_proto.c index 055b9f9..789c4d5 100644 --- a/lnet/klnds/socklnd/socklnd_proto.c +++ b/lnet/klnds/socklnd/socklnd_proto.c @@ -488,12 +488,12 @@ ksocknal_send_hello_v1(struct ksock_conn *conn, struct ksock_hello_msg *hello) hmv->magic = LNET_PROTO_MAGIC; } - hdr->src_nid = cpu_to_le64 (hello->kshm_src_nid); - hdr->src_pid = cpu_to_le32 (hello->kshm_src_pid); - hdr->type = cpu_to_le32 (LNET_MSG_HELLO); - hdr->payload_length = cpu_to_le32 (hello->kshm_nips * sizeof(__u32)); - hdr->msg.hello.type = cpu_to_le32 (hello->kshm_ctype); - hdr->msg.hello.incarnation = cpu_to_le64 (hello->kshm_src_incarnation); + hdr->src_nid = cpu_to_le64(lnet_nid_to_nid4(&hello->kshm_src_nid)); + hdr->src_pid = cpu_to_le32 (hello->kshm_src_pid); + hdr->type = cpu_to_le32 (LNET_MSG_HELLO); + hdr->payload_length = cpu_to_le32 (hello->kshm_nips * sizeof(__u32)); + hdr->msg.hello.type = cpu_to_le32 (hello->kshm_ctype); + hdr->msg.hello.incarnation = cpu_to_le64 (hello->kshm_src_incarnation); rc = lnet_sock_write(sock, hdr, sizeof(*hdr), lnet_acceptor_timeout()); if (rc != 0) { @@ -502,12 +502,11 @@ ksocknal_send_hello_v1(struct ksock_conn *conn, struct ksock_hello_msg *hello) goto out; } - if (hello->kshm_nips == 0) - goto out; + if (hello->kshm_nips == 0) + goto out; - for (i = 0; i < (int) hello->kshm_nips; i++) { - hello->kshm_ips[i] = __cpu_to_le32 (hello->kshm_ips[i]); - } + for (i = 0; i < (int) hello->kshm_nips; i++) + hello->kshm_ips[i] = __cpu_to_le32 (hello->kshm_ips[i]); rc = lnet_sock_write(sock, hello->kshm_ips, hello->kshm_nips * sizeof(__u32), @@ -516,11 +515,11 @@ ksocknal_send_hello_v1(struct ksock_conn *conn, struct ksock_hello_msg *hello) CNETERR("Error %d sending HELLO payload (%d) to %pISp\n", rc, hello->kshm_nips, &conn->ksnc_peeraddr); - } + } out: - LIBCFS_FREE(hdr, sizeof(*hdr)); + LIBCFS_FREE(hdr, sizeof(*hdr)); - return rc; + return rc; } static int @@ -528,27 +527,55 @@ ksocknal_send_hello_v2(struct ksock_conn *conn, struct ksock_hello_msg *hello) { struct socket *sock = conn->ksnc_sock; int rc; + struct ksock_hello_msg_nid4 *hello4; + + CFS_ALLOC_PTR(hello4); + if (!hello4) { + CERROR("Can't allocate struct ksock_hello_msg_nid4\n"); + return -ENOMEM; + } + + hello->kshm_magic = LNET_PROTO_MAGIC; + hello->kshm_version = conn->ksnc_proto->pro_version; - hello->kshm_magic = LNET_PROTO_MAGIC; - hello->kshm_version = conn->ksnc_proto->pro_version; + hello4->kshm_magic = LNET_PROTO_MAGIC; + hello4->kshm_version = conn->ksnc_proto->pro_version; + hello4->kshm_src_nid = lnet_nid_to_nid4(&hello->kshm_src_nid); + hello4->kshm_dst_nid = lnet_nid_to_nid4(&hello->kshm_dst_nid); + hello4->kshm_src_pid = hello->kshm_src_pid; + hello4->kshm_dst_pid = hello->kshm_dst_pid; + hello4->kshm_src_incarnation = hello->kshm_src_incarnation; + hello4->kshm_dst_incarnation = hello->kshm_dst_incarnation; + hello4->kshm_ctype = hello->kshm_ctype; + hello4->kshm_nips = hello->kshm_nips; if (the_lnet.ln_testprotocompat) { /* single-shot proto check */ if (test_and_clear_bit(0, &the_lnet.ln_testprotocompat)) hello->kshm_version++; /* just different! */ } - - rc = lnet_sock_write(sock, hello, offsetof(struct ksock_hello_msg, kshm_ips), - lnet_acceptor_timeout()); - - if (rc != 0) { + hello4->kshm_magic = LNET_PROTO_MAGIC; + hello4->kshm_version = hello->kshm_version; + hello4->kshm_src_nid = lnet_nid_to_nid4(&hello->kshm_src_nid); + hello4->kshm_dst_nid = lnet_nid_to_nid4(&hello->kshm_dst_nid); + hello4->kshm_src_pid = hello->kshm_src_pid; + hello4->kshm_dst_pid = hello->kshm_dst_pid; + hello4->kshm_src_incarnation = hello->kshm_src_incarnation; + hello4->kshm_dst_incarnation = hello->kshm_dst_incarnation; + hello4->kshm_ctype = hello->kshm_ctype; + hello4->kshm_nips = hello->kshm_nips; + + rc = lnet_sock_write(sock, hello4, sizeof(*hello4), + lnet_acceptor_timeout()); + CFS_FREE_PTR(hello4); + if (rc) { CNETERR("Error %d sending HELLO hdr to %pISp\n", rc, &conn->ksnc_peeraddr); return rc; } - if (hello->kshm_nips == 0) - return 0; + if (hello->kshm_nips == 0) + return 0; rc = lnet_sock_write(sock, hello->kshm_ips, hello->kshm_nips * sizeof(__u32), @@ -571,16 +598,16 @@ ksocknal_recv_hello_v1(struct ksock_conn *conn, struct ksock_hello_msg *hello, int rc; int i; - LIBCFS_ALLOC(hdr, sizeof(*hdr)); - if (hdr == NULL) { + CFS_ALLOC_PTR(hdr); + if (!hdr) { CERROR("Can't allocate struct lnet_hdr_nid4\n"); return -ENOMEM; } rc = lnet_sock_read(sock, &hdr->src_nid, - sizeof(*hdr) - offsetof(struct _lnet_hdr_nid4, - src_nid), - timeout); + sizeof(*hdr) - offsetof(struct _lnet_hdr_nid4, + src_nid), + timeout); if (rc != 0) { CERROR("Error %d reading rest of HELLO hdr from %pIS\n", rc, &conn->ksnc_peeraddr); @@ -597,12 +624,11 @@ ksocknal_recv_hello_v1(struct ksock_conn *conn, struct ksock_hello_msg *hello, goto out; } - hello->kshm_src_nid = le64_to_cpu (hdr->src_nid); - hello->kshm_src_pid = le32_to_cpu (hdr->src_pid); - hello->kshm_src_incarnation = le64_to_cpu (hdr->msg.hello.incarnation); - hello->kshm_ctype = le32_to_cpu (hdr->msg.hello.type); - hello->kshm_nips = le32_to_cpu (hdr->payload_length) / - sizeof (__u32); + lnet_nid4_to_nid(le64_to_cpu(hdr->src_nid), &hello->kshm_src_nid); + hello->kshm_src_pid = le32_to_cpu(hdr->src_pid); + hello->kshm_src_incarnation = le64_to_cpu(hdr->msg.hello.incarnation); + hello->kshm_ctype = le32_to_cpu(hdr->msg.hello.type); + hello->kshm_nips = le32_to_cpu(hdr->payload_length) / sizeof(__u32); if (hello->kshm_nips > LNET_INTERFACES_NUM) { CERROR("Bad nips %d from ip %pIS\n", @@ -611,68 +637,80 @@ ksocknal_recv_hello_v1(struct ksock_conn *conn, struct ksock_hello_msg *hello, goto out; } - if (hello->kshm_nips == 0) - goto out; + if (hello->kshm_nips == 0) + goto out; rc = lnet_sock_read(sock, hello->kshm_ips, - hello->kshm_nips * sizeof(__u32), timeout); - if (rc != 0) { + hello->kshm_nips * sizeof(__u32), timeout); + if (rc != 0) { CERROR("Error %d reading IPs from ip %pIS\n", rc, &conn->ksnc_peeraddr); LASSERT(rc < 0 && rc != -EALREADY); - goto out; - } + goto out; + } - for (i = 0; i < (int) hello->kshm_nips; i++) { - hello->kshm_ips[i] = __le32_to_cpu(hello->kshm_ips[i]); + for (i = 0; i < (int) hello->kshm_nips; i++) { + hello->kshm_ips[i] = __le32_to_cpu(hello->kshm_ips[i]); - if (hello->kshm_ips[i] == 0) { + if (hello->kshm_ips[i] == 0) { CERROR("Zero IP[%d] from ip %pIS\n", i, &conn->ksnc_peeraddr); - rc = -EPROTO; - break; - } - } + rc = -EPROTO; + break; + } + } out: - LIBCFS_FREE(hdr, sizeof(*hdr)); + CFS_FREE_PTR(hdr); - return rc; + return rc; } static int ksocknal_recv_hello_v2(struct ksock_conn *conn, struct ksock_hello_msg *hello, int timeout) { - struct socket *sock = conn->ksnc_sock; - int rc; - int i; - - if (hello->kshm_magic == LNET_PROTO_MAGIC) - conn->ksnc_flip = 0; - else - conn->ksnc_flip = 1; - - rc = lnet_sock_read(sock, &hello->kshm_src_nid, - offsetof(struct ksock_hello_msg, kshm_ips) - - offsetof(struct ksock_hello_msg, kshm_src_nid), - timeout); - if (rc != 0) { + struct socket *sock = conn->ksnc_sock; + struct ksock_hello_msg_nid4 *hello4 = (void *)hello; + int rc; + int i; + + if (hello->kshm_magic == LNET_PROTO_MAGIC) + conn->ksnc_flip = 0; + else + conn->ksnc_flip = 1; + + rc = lnet_sock_read(sock, &hello4->kshm_src_nid, + offsetof(struct ksock_hello_msg_nid4, kshm_ips) - + offsetof(struct ksock_hello_msg_nid4, kshm_src_nid), + timeout); + if (rc != 0) { CERROR("Error %d reading HELLO from %pIS\n", rc, &conn->ksnc_peeraddr); LASSERT(rc < 0 && rc != -EALREADY); - return rc; - } + return rc; + } - if (conn->ksnc_flip) { - __swab32s(&hello->kshm_src_pid); - __swab64s(&hello->kshm_src_nid); - __swab32s(&hello->kshm_dst_pid); - __swab64s(&hello->kshm_dst_nid); - __swab64s(&hello->kshm_src_incarnation); - __swab64s(&hello->kshm_dst_incarnation); - __swab32s(&hello->kshm_ctype); - __swab32s(&hello->kshm_nips); - } + if (conn->ksnc_flip) { + /* These must be copied in reverse order to avoid corruption. */ + hello->kshm_nips = __swab32(hello4->kshm_nips); + hello->kshm_ctype = __swab32(hello4->kshm_ctype); + hello->kshm_dst_incarnation = __swab64(hello4->kshm_dst_incarnation); + hello->kshm_src_incarnation = __swab64(hello4->kshm_src_incarnation); + hello->kshm_dst_pid = __swab32(hello4->kshm_dst_pid); + hello->kshm_src_pid = __swab32(hello4->kshm_src_pid); + lnet_nid4_to_nid(hello4->kshm_dst_nid, &hello->kshm_dst_nid); + lnet_nid4_to_nid(hello4->kshm_src_nid, &hello->kshm_src_nid); + } else { + /* These must be copied in reverse order to avoid corruption. */ + hello->kshm_nips = hello4->kshm_nips; + hello->kshm_ctype = hello4->kshm_ctype; + hello->kshm_dst_incarnation = hello4->kshm_dst_incarnation; + hello->kshm_src_incarnation = hello4->kshm_src_incarnation; + hello->kshm_dst_pid = hello4->kshm_dst_pid; + hello->kshm_src_pid = hello4->kshm_src_pid; + lnet_nid4_to_nid(hello4->kshm_dst_nid, &hello->kshm_dst_nid); + lnet_nid4_to_nid(hello4->kshm_src_nid, &hello->kshm_src_nid); + } if (hello->kshm_nips > LNET_INTERFACES_NUM) { CERROR("Bad nips %d from ip %pIS\n", @@ -680,8 +718,8 @@ ksocknal_recv_hello_v2(struct ksock_conn *conn, struct ksock_hello_msg *hello, return -EPROTO; } - if (hello->kshm_nips == 0) - return 0; + if (hello->kshm_nips == 0) + return 0; rc = lnet_sock_read(sock, hello->kshm_ips, hello->kshm_nips * sizeof(__u32), timeout); @@ -692,18 +730,18 @@ ksocknal_recv_hello_v2(struct ksock_conn *conn, struct ksock_hello_msg *hello, return rc; } - for (i = 0; i < (int) hello->kshm_nips; i++) { - if (conn->ksnc_flip) - __swab32s(&hello->kshm_ips[i]); + for (i = 0; i < (int) hello->kshm_nips; i++) { + if (conn->ksnc_flip) + __swab32s(&hello->kshm_ips[i]); if (hello->kshm_ips[i] == 0) { CERROR("Zero IP[%d] from ip %pIS\n", i, &conn->ksnc_peeraddr); return -EPROTO; } - } + } - return 0; + return 0; } static void