libceph: make sure our addr->port is zero and addr->nonce is non-zero

Our messenger instance addr->port is normally zero -- anything else is
nonsensical because as a client we connect to multiple servers and don't
listen on any port.  However, a user can supply an arbitrary addr:port
via ip option and the port is currently preserved.  Zero it.

Conversely, make sure our addr->nonce is non-zero.  A zero nonce is
special: in combination with a zero port, it is used to blocklist the
entire ip.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index a912f2d..0b432ce 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -2042,6 +2042,8 @@ int ceph_parse_ips(const char *c, const char *end,
 
 static int process_banner(struct ceph_connection *con)
 {
+	struct ceph_entity_addr *my_addr = &con->msgr->inst.addr;
+
 	dout("process_banner on %p\n", con);
 
 	if (verify_hello(con) < 0)
@@ -2068,16 +2070,14 @@ static int process_banner(struct ceph_connection *con)
 	/*
 	 * did we learn our address?
 	 */
-	if (addr_is_blank(&con->msgr->inst.addr)) {
-		int port = addr_port(&con->msgr->inst.addr);
-
-		memcpy(&con->msgr->inst.addr.in_addr,
+	if (addr_is_blank(my_addr)) {
+		memcpy(&my_addr->in_addr,
 		       &con->peer_addr_for_me.in_addr,
 		       sizeof(con->peer_addr_for_me.in_addr));
-		addr_set_port(&con->msgr->inst.addr, port);
+		addr_set_port(my_addr, 0);
 		encode_my_addr(con->msgr);
 		dout("process_banner learned my addr is %s\n",
-		     ceph_pr_addr(&con->msgr->inst.addr));
+		     ceph_pr_addr(my_addr));
 	}
 
 	return 0;
@@ -3058,12 +3058,19 @@ void ceph_messenger_init(struct ceph_messenger *msgr,
 {
 	spin_lock_init(&msgr->global_seq_lock);
 
-	if (myaddr)
-		msgr->inst.addr = *myaddr;
+	if (myaddr) {
+		memcpy(&msgr->inst.addr.in_addr, &myaddr->in_addr,
+		       sizeof(msgr->inst.addr.in_addr));
+		addr_set_port(&msgr->inst.addr, 0);
+	}
 
-	/* select a random nonce */
 	msgr->inst.addr.type = 0;
-	get_random_bytes(&msgr->inst.addr.nonce, sizeof(msgr->inst.addr.nonce));
+
+	/* generate a random non-zero nonce */
+	do {
+		get_random_bytes(&msgr->inst.addr.nonce,
+				 sizeof(msgr->inst.addr.nonce));
+	} while (!msgr->inst.addr.nonce);
 	encode_my_addr(msgr);
 
 	atomic_set(&msgr->stopping, 0);