summaryrefslogtreecommitdiffstats
path: root/net/rds
diff options
context:
space:
mode:
authorSowmini Varadhan <sowmini.varadhan@oracle.com>2017-06-15 14:28:54 -0400
committerDavid S. Miller <davem@davemloft.net>2017-06-16 12:45:15 -0400
commit00354de5779db4aa9c019db787ef89bd1a6b149b (patch)
tree94bdcc84fb39332c5fb175cbe50c4cfb32acadc4 /net/rds
parent41500c3e2a19ffcf40a7158fce1774de08e26ba2 (diff)
rds: tcp: various endian-ness fixes
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. 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>
Diffstat (limited to 'net/rds')
-rw-r--r--net/rds/rds.h2
-rw-r--r--net/rds/recv.c12
-rw-r--r--net/rds/send.c11
-rw-r--r--net/rds/tcp_connect.c2
-rw-r--r--net/rds/tcp_listen.c2
-rw-r--r--net/rds/threads.c5
6 files changed, 21 insertions, 13 deletions
diff --git a/net/rds/rds.h b/net/rds/rds.h
index aa183d6adbcc..d6a04a05eb79 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -92,6 +92,8 @@ enum {
92#define RDS_MPATH_HASH(rs, n) (jhash_1word((rs)->rs_bound_port, \ 92#define RDS_MPATH_HASH(rs, n) (jhash_1word((rs)->rs_bound_port, \
93 (rs)->rs_hash_initval) & ((n) - 1)) 93 (rs)->rs_hash_initval) & ((n) - 1))
94 94
95#define IS_CANONICAL(laddr, faddr) (htonl(laddr) < htonl(faddr))
96
95/* Per mpath connection state */ 97/* Per mpath connection state */
96struct rds_conn_path { 98struct rds_conn_path {
97 struct rds_connection *cp_conn; 99 struct rds_connection *cp_conn;
diff --git a/net/rds/recv.c b/net/rds/recv.c
index c70c32cb05f5..49493dbc43a1 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -215,10 +215,10 @@ static void rds_recv_hs_exthdrs(struct rds_header *hdr,
215 switch (type) { 215 switch (type) {
216 case RDS_EXTHDR_NPATHS: 216 case RDS_EXTHDR_NPATHS:
217 conn->c_npaths = min_t(int, RDS_MPATH_WORKERS, 217 conn->c_npaths = min_t(int, RDS_MPATH_WORKERS,
218 buffer.rds_npaths); 218 be16_to_cpu(buffer.rds_npaths));
219 break; 219 break;
220 case RDS_EXTHDR_GEN_NUM: 220 case RDS_EXTHDR_GEN_NUM:
221 new_peer_gen_num = buffer.rds_gen_num; 221 new_peer_gen_num = be32_to_cpu(buffer.rds_gen_num);
222 break; 222 break;
223 default: 223 default:
224 pr_warn_ratelimited("ignoring unknown exthdr type " 224 pr_warn_ratelimited("ignoring unknown exthdr type "
@@ -254,7 +254,8 @@ static void rds_start_mprds(struct rds_connection *conn)
254 int i; 254 int i;
255 struct rds_conn_path *cp; 255 struct rds_conn_path *cp;
256 256
257 if (conn->c_npaths > 1 && conn->c_laddr < conn->c_faddr) { 257 if (conn->c_npaths > 1 &&
258 IS_CANONICAL(conn->c_laddr, conn->c_faddr)) {
258 for (i = 1; i < conn->c_npaths; i++) { 259 for (i = 1; i < conn->c_npaths; i++) {
259 cp = &conn->c_path[i]; 260 cp = &conn->c_path[i];
260 rds_conn_path_connect_if_down(cp); 261 rds_conn_path_connect_if_down(cp);
@@ -339,14 +340,15 @@ void rds_recv_incoming(struct rds_connection *conn, __be32 saddr, __be32 daddr,
339 rds_stats_inc(s_recv_ping); 340 rds_stats_inc(s_recv_ping);
340 rds_send_pong(cp, inc->i_hdr.h_sport); 341 rds_send_pong(cp, inc->i_hdr.h_sport);
341 /* if this is a handshake ping, start multipath if necessary */ 342 /* if this is a handshake ping, start multipath if necessary */
342 if (RDS_HS_PROBE(inc->i_hdr.h_sport, inc->i_hdr.h_dport)) { 343 if (RDS_HS_PROBE(be16_to_cpu(inc->i_hdr.h_sport),
344 be16_to_cpu(inc->i_hdr.h_dport))) {
343 rds_recv_hs_exthdrs(&inc->i_hdr, cp->cp_conn); 345 rds_recv_hs_exthdrs(&inc->i_hdr, cp->cp_conn);
344 rds_start_mprds(cp->cp_conn); 346 rds_start_mprds(cp->cp_conn);
345 } 347 }
346 goto out; 348 goto out;
347 } 349 }
348 350
349 if (inc->i_hdr.h_dport == RDS_FLAG_PROBE_PORT && 351 if (be16_to_cpu(inc->i_hdr.h_dport) == RDS_FLAG_PROBE_PORT &&
350 inc->i_hdr.h_sport == 0) { 352 inc->i_hdr.h_sport == 0) {
351 rds_recv_hs_exthdrs(&inc->i_hdr, cp->cp_conn); 353 rds_recv_hs_exthdrs(&inc->i_hdr, cp->cp_conn);
352 /* if this is a handshake pong, start multipath if necessary */ 354 /* if this is a handshake pong, start multipath if necessary */
diff --git a/net/rds/send.c b/net/rds/send.c
index 5cc64039caf7..3652a50397c7 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -1246,15 +1246,17 @@ rds_send_probe(struct rds_conn_path *cp, __be16 sport,
1246 rm->m_inc.i_hdr.h_flags |= h_flags; 1246 rm->m_inc.i_hdr.h_flags |= h_flags;
1247 cp->cp_next_tx_seq++; 1247 cp->cp_next_tx_seq++;
1248 1248
1249 if (RDS_HS_PROBE(sport, dport) && cp->cp_conn->c_trans->t_mp_capable) { 1249 if (RDS_HS_PROBE(be16_to_cpu(sport), be16_to_cpu(dport)) &&
1250 u16 npaths = RDS_MPATH_WORKERS; 1250 cp->cp_conn->c_trans->t_mp_capable) {
1251 u16 npaths = cpu_to_be16(RDS_MPATH_WORKERS);
1252 u32 my_gen_num = cpu_to_be32(cp->cp_conn->c_my_gen_num);
1251 1253
1252 rds_message_add_extension(&rm->m_inc.i_hdr, 1254 rds_message_add_extension(&rm->m_inc.i_hdr,
1253 RDS_EXTHDR_NPATHS, &npaths, 1255 RDS_EXTHDR_NPATHS, &npaths,
1254 sizeof(npaths)); 1256 sizeof(npaths));
1255 rds_message_add_extension(&rm->m_inc.i_hdr, 1257 rds_message_add_extension(&rm->m_inc.i_hdr,
1256 RDS_EXTHDR_GEN_NUM, 1258 RDS_EXTHDR_GEN_NUM,
1257 &cp->cp_conn->c_my_gen_num, 1259 &my_gen_num,
1258 sizeof(u32)); 1260 sizeof(u32));
1259 } 1261 }
1260 spin_unlock_irqrestore(&cp->cp_lock, flags); 1262 spin_unlock_irqrestore(&cp->cp_lock, flags);
@@ -1293,5 +1295,6 @@ rds_send_ping(struct rds_connection *conn)
1293 } 1295 }
1294 conn->c_ping_triggered = 1; 1296 conn->c_ping_triggered = 1;
1295 spin_unlock_irqrestore(&cp->cp_lock, flags); 1297 spin_unlock_irqrestore(&cp->cp_lock, flags);
1296 rds_send_probe(&conn->c_path[0], RDS_FLAG_PROBE_PORT, 0, 0); 1298 rds_send_probe(&conn->c_path[0], cpu_to_be16(RDS_FLAG_PROBE_PORT),
1299 0, 0);
1297} 1300}
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c
index 97db86101ac5..5a62a083bb5a 100644
--- a/net/rds/tcp_connect.c
+++ b/net/rds/tcp_connect.c
@@ -66,7 +66,7 @@ void rds_tcp_state_change(struct sock *sk)
66 * RDS connection as RDS_CONN_UP until the reconnect, 66 * RDS connection as RDS_CONN_UP until the reconnect,
67 * to avoid RDS datagram loss. 67 * to avoid RDS datagram loss.
68 */ 68 */
69 if (cp->cp_conn->c_laddr > cp->cp_conn->c_faddr && 69 if (!IS_CANONICAL(cp->cp_conn->c_laddr, cp->cp_conn->c_faddr) &&
70 rds_conn_path_transition(cp, RDS_CONN_CONNECTING, 70 rds_conn_path_transition(cp, RDS_CONN_CONNECTING,
71 RDS_CONN_ERROR)) { 71 RDS_CONN_ERROR)) {
72 rds_conn_path_drop(cp); 72 rds_conn_path_drop(cp);
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index 238ff5c9a75b..f9c6312be841 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -83,7 +83,7 @@ static
83struct rds_tcp_connection *rds_tcp_accept_one_path(struct rds_connection *conn) 83struct rds_tcp_connection *rds_tcp_accept_one_path(struct rds_connection *conn)
84{ 84{
85 int i; 85 int i;
86 bool peer_is_smaller = (conn->c_faddr < conn->c_laddr); 86 bool peer_is_smaller = IS_CANONICAL(conn->c_faddr, conn->c_laddr);
87 int npaths = max_t(int, 1, conn->c_npaths); 87 int npaths = max_t(int, 1, conn->c_npaths);
88 88
89 /* for mprds, all paths MUST be initiated by the peer 89 /* for mprds, all paths MUST be initiated by the peer
diff --git a/net/rds/threads.c b/net/rds/threads.c
index 3e447d056d09..2852bc1d37d4 100644
--- a/net/rds/threads.c
+++ b/net/rds/threads.c
@@ -127,7 +127,7 @@ void rds_queue_reconnect(struct rds_conn_path *cp)
127 127
128 /* let peer with smaller addr initiate reconnect, to avoid duels */ 128 /* let peer with smaller addr initiate reconnect, to avoid duels */
129 if (conn->c_trans->t_type == RDS_TRANS_TCP && 129 if (conn->c_trans->t_type == RDS_TRANS_TCP &&
130 conn->c_laddr > conn->c_faddr) 130 !IS_CANONICAL(conn->c_laddr, conn->c_faddr))
131 return; 131 return;
132 132
133 set_bit(RDS_RECONNECT_PENDING, &cp->cp_flags); 133 set_bit(RDS_RECONNECT_PENDING, &cp->cp_flags);
@@ -156,7 +156,8 @@ void rds_connect_worker(struct work_struct *work)
156 struct rds_connection *conn = cp->cp_conn; 156 struct rds_connection *conn = cp->cp_conn;
157 int ret; 157 int ret;
158 158
159 if (cp->cp_index > 0 && cp->cp_conn->c_laddr > cp->cp_conn->c_faddr) 159 if (cp->cp_index > 0 &&
160 !IS_CANONICAL(cp->cp_conn->c_laddr, cp->cp_conn->c_faddr))
160 return; 161 return;
161 clear_bit(RDS_RECONNECT_PENDING, &cp->cp_flags); 162 clear_bit(RDS_RECONNECT_PENDING, &cp->cp_flags);
162 ret = rds_conn_path_transition(cp, RDS_CONN_DOWN, RDS_CONN_CONNECTING); 163 ret = rds_conn_path_transition(cp, RDS_CONN_DOWN, RDS_CONN_CONNECTING);