]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
rds: tcp: various endian-ness fixes
authorSowmini Varadhan <sowmini.varadhan@oracle.com>
Fri, 16 Jun 2017 20:30:20 +0000 (13:30 -0700)
committerChuck Anderson <chuck.anderson@oracle.com>
Sun, 18 Jun 2017 19:49:49 +0000 (12:49 -0700)
Found when testing between sparc and x86 machines on different
subnets, so the address comparison patterns hit the corner cases and
brought out some bugs fixed by this patch.

Orabug: 26289770

(Cherry-pick of upstream commit 00354de5779db4aa9c019db787ef89bd1a6b149b)

Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Tested-by: Imanti Mendez <imanti.mendez@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/rds/rds.h
net/rds/recv.c
net/rds/send.c
net/rds/tcp_connect.c
net/rds/tcp_listen.c
net/rds/threads.c

index acb0efaae371148c822e3178618e2bd760cbce0d..5cb7109da4bd99dde363a8c67dcd00b896eb55bd 100644 (file)
@@ -223,6 +223,8 @@ enum rds_conn_drop_src {
        DR_TCP_SEND_FAIL,
 };
 
+#define IS_CANONICAL(laddr, faddr) (htonl(laddr) < htonl(faddr))
+
 /* Per mpath connection state */
 struct rds_conn_path {
        struct rds_connection   *cp_conn;
index e4ba384a157571420688de0b241f66ece068685c..bf8c8b55a7a0bfb5a31e8ff2aa1cf2bec393df93 100644 (file)
@@ -266,10 +266,10 @@ static void rds_recv_hs_exthdrs(struct rds_header *hdr,
                switch (type) {
                case RDS_EXTHDR_NPATHS:
                        conn->c_npaths = min_t(int, RDS_MPATH_WORKERS,
-                                              buffer.rds_npaths);
+                                              be16_to_cpu(buffer.rds_npaths));
                        break;
                case RDS_EXTHDR_GEN_NUM:
-                       new_peer_gen_num = buffer.rds_gen_num;
+                       new_peer_gen_num = be32_to_cpu(buffer.rds_gen_num);
                        break;
                default:
                        pr_warn_ratelimited("ignoring unknown exthdr type "
@@ -305,7 +305,8 @@ static void rds_start_mprds(struct rds_connection *conn)
        int i;
        struct rds_conn_path *cp;
 
-       if (conn->c_npaths > 1 && conn->c_laddr < conn->c_faddr) {
+       if (conn->c_npaths > 1 &&
+           IS_CANONICAL(conn->c_laddr, conn->c_faddr)) {
                for (i = 1; i < conn->c_npaths; i++) {
                        cp = &conn->c_path[i];
                        rds_conn_path_connect_if_down(cp);
@@ -668,15 +669,15 @@ rds_recv_local(struct rds_conn_path *cp, __be32 saddr, __be32 daddr,
                        /* if this is a handshake ping,
                         * start multipath if necessary
                         */
-                       if (RDS_HS_PROBE(inc->i_hdr.h_sport,
-                                        inc->i_hdr.h_dport)) {
+                       if (RDS_HS_PROBE(be16_to_cpu(inc->i_hdr.h_sport),
+                                        be16_to_cpu(inc->i_hdr.h_dport))) {
                                rds_recv_hs_exthdrs(&inc->i_hdr, cp->cp_conn);
                                rds_start_mprds(cp->cp_conn);
                        }
                }
                goto out;
        }
-       if (inc->i_hdr.h_dport ==  RDS_FLAG_PROBE_PORT &&
+       if (be16_to_cpu(inc->i_hdr.h_dport) ==  RDS_FLAG_PROBE_PORT &&
            inc->i_hdr.h_sport == 0) {
                rds_recv_hs_exthdrs(&inc->i_hdr, cp->cp_conn);
                /* if this is a handshake pong, start multipath if necessary */
index 3491d7ef24a108e74372bfb13499da6ad015a5f7..1a700869054e7ac3088ff5672864aadb4d10ee15 100644 (file)
@@ -1644,15 +1644,17 @@ rds_send_probe(struct rds_conn_path *cp, __be16 sport,
        rm->m_inc.i_hdr.h_flags |= h_flags;
        cp->cp_next_tx_seq++;
 
-       if (RDS_HS_PROBE(sport, dport) && cp->cp_conn->c_trans->t_mp_capable) {
-               u16 npaths = RDS_MPATH_WORKERS;
+       if (RDS_HS_PROBE(be16_to_cpu(sport), be16_to_cpu(dport)) &&
+           cp->cp_conn->c_trans->t_mp_capable) {
+               u16 npaths = cpu_to_be16(RDS_MPATH_WORKERS);
+               u32 my_gen_num = cpu_to_be32(cp->cp_conn->c_my_gen_num);
 
                rds_message_add_extension(&rm->m_inc.i_hdr,
                                          RDS_EXTHDR_NPATHS, &npaths,
                                          sizeof(npaths));
                rds_message_add_extension(&rm->m_inc.i_hdr,
                                          RDS_EXTHDR_GEN_NUM,
-                                         &cp->cp_conn->c_my_gen_num,
+                                         &my_gen_num,
                                          sizeof(u32));
        }
        spin_unlock_irqrestore(&cp->cp_lock, flags);
@@ -1735,5 +1737,6 @@ rds_send_ping(struct rds_connection *conn)
        }
        conn->c_ping_triggered = 1;
        spin_unlock_irqrestore(&cp->cp_lock, flags);
-       rds_send_probe(&conn->c_path[0], RDS_FLAG_PROBE_PORT, 0, 0);
+       rds_send_probe(&conn->c_path[0], cpu_to_be16(RDS_FLAG_PROBE_PORT),
+                      0, 0);
 }
index ead79debd205e4f1b13ab286ac57e574ad00d80a..17d8936b9d92257f8e15d8389686d4b2ad6e7bda 100644 (file)
@@ -60,7 +60,8 @@ void rds_tcp_state_change(struct sock *sk)
        case TCP_SYN_RECV:
                break;
        case TCP_ESTABLISHED:
-                if (cp->cp_conn->c_laddr > cp->cp_conn->c_faddr &&
+                if (!IS_CANONICAL(cp->cp_conn->c_laddr,
+                                  cp->cp_conn->c_faddr) &&
                     rds_conn_path_transition(cp, RDS_CONN_CONNECTING,
                                              RDS_CONN_ERROR)) {
                        rds_conn_path_drop(cp, DR_TCP_STATE_CLOSE);
index f78a83af6509a15600ca14c7f18f7ae86a2314fd..66090ded403391886ed9edba78fcb3e755cd3fae 100644 (file)
@@ -81,7 +81,7 @@ bail:
 struct rds_tcp_connection *rds_tcp_accept_one_path(struct rds_connection *conn)
 {
        int i;
-       bool peer_is_smaller = (conn->c_faddr < conn->c_laddr);
+       bool peer_is_smaller = IS_CANONICAL(conn->c_faddr, conn->c_laddr);
        int npaths = max_t(int, 1, conn->c_npaths);
 
        if (!peer_is_smaller) {
index 1e0ea785e4dbfea44a7ba61e368a24af3cd85c66..dda33cda1331212c3c27e8e418bd68ccac0bc30d 100644 (file)
@@ -144,7 +144,7 @@ void rds_queue_reconnect(struct rds_conn_path *cp)
                cp->cp_reconnect_jiffies);
 
        /* let peer with smaller addr initiate reconnect, to avoid duels */
-       if (is_tcp && conn->c_laddr > conn->c_faddr)
+       if (is_tcp && !IS_CANONICAL(conn->c_laddr, conn->c_faddr))
                return;
 
        set_bit(RDS_RECONNECT_PENDING, &cp->cp_flags);
@@ -178,7 +178,7 @@ void rds_connect_worker(struct work_struct *work)
        bool is_tcp = conn->c_trans->t_type == RDS_TRANS_TCP;
 
        if (is_tcp && cp->cp_index > 0 &&
-           cp->cp_conn->c_laddr > cp->cp_conn->c_faddr)
+           !IS_CANONICAL(cp->cp_conn->c_laddr, cp->cp_conn->c_faddr))
                return;
        clear_bit(RDS_RECONNECT_PENDING, &cp->cp_flags);
        ret = rds_conn_path_transition(cp, RDS_CONN_DOWN, RDS_CONN_CONNECTING);