aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/tipc/msg.c38
-rw-r--r--net/tipc/msg.h2
-rw-r--r--net/tipc/net.c33
-rw-r--r--net/tipc/socket.c16
4 files changed, 51 insertions, 38 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 6070dd0ec634..7bfc4422bf2c 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -36,6 +36,8 @@
36 36
37#include "core.h" 37#include "core.h"
38#include "msg.h" 38#include "msg.h"
39#include "addr.h"
40#include "name_table.h"
39 41
40#define MAX_FORWARD_SIZE 1024 42#define MAX_FORWARD_SIZE 1024
41 43
@@ -370,3 +372,39 @@ exit:
370 kfree_skb(buf); 372 kfree_skb(buf);
371 return false; 373 return false;
372} 374}
375
376/**
377 * tipc_msg_eval: determine fate of message that found no destination
378 * @buf: the buffer containing the message.
379 * @dnode: return value: next-hop node, if message to be forwarded
380 * @err: error code to use, if message to be rejected
381 *
382 * Does not consume buffer
383 * Returns 0 (TIPC_OK) if message ok and we can try again, -TIPC error
384 * code if message to be rejected
385 */
386int tipc_msg_eval(struct sk_buff *buf, u32 *dnode)
387{
388 struct tipc_msg *msg = buf_msg(buf);
389 u32 dport;
390
391 if (msg_type(msg) != TIPC_NAMED_MSG)
392 return -TIPC_ERR_NO_PORT;
393 if (skb_linearize(buf))
394 return -TIPC_ERR_NO_NAME;
395 if (msg_data_sz(msg) > MAX_FORWARD_SIZE)
396 return -TIPC_ERR_NO_NAME;
397 if (msg_reroute_cnt(msg) > 0)
398 return -TIPC_ERR_NO_NAME;
399
400 *dnode = addr_domain(msg_lookup_scope(msg));
401 dport = tipc_nametbl_translate(msg_nametype(msg),
402 msg_nameinst(msg),
403 dnode);
404 if (!dport)
405 return -TIPC_ERR_NO_NAME;
406 msg_incr_reroute_cnt(msg);
407 msg_set_destnode(msg, *dnode);
408 msg_set_destport(msg, dport);
409 return TIPC_OK;
410}
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 38050941a504..7d574346e75e 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -727,6 +727,8 @@ static inline u32 msg_tot_origport(struct tipc_msg *m)
727 727
728bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err); 728bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err);
729 729
730int tipc_msg_eval(struct sk_buff *buf, u32 *dnode);
731
730void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, 732void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize,
731 u32 destnode); 733 u32 destnode);
732 734
diff --git a/net/tipc/net.c b/net/tipc/net.c
index f64375e7f99f..5f7d6ffb5465 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/net.c: TIPC network routing code 2 * net/tipc/net.c: TIPC network routing code
3 * 3 *
4 * Copyright (c) 1995-2006, Ericsson AB 4 * Copyright (c) 1995-2006, 2014, Ericsson AB
5 * Copyright (c) 2005, 2010-2011, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -103,29 +103,6 @@
103 * This is always used within the scope of a tipc_nametbl_lock(read). 103 * This is always used within the scope of a tipc_nametbl_lock(read).
104 * - A local spin_lock protecting the queue of subscriber events. 104 * - A local spin_lock protecting the queue of subscriber events.
105*/ 105*/
106
107static void net_route_named_msg(struct sk_buff *buf)
108{
109 struct tipc_msg *msg = buf_msg(buf);
110 u32 dnode;
111 u32 dport;
112
113 if (!msg_named(msg)) {
114 kfree_skb(buf);
115 return;
116 }
117
118 dnode = addr_domain(msg_lookup_scope(msg));
119 dport = tipc_nametbl_translate(msg_nametype(msg), msg_nameinst(msg), &dnode);
120 if (dport) {
121 msg_set_destnode(msg, dnode);
122 msg_set_destport(msg, dport);
123 tipc_net_route_msg(buf);
124 return;
125 }
126 tipc_reject_msg(buf, TIPC_ERR_NO_NAME);
127}
128
129void tipc_net_route_msg(struct sk_buff *buf) 106void tipc_net_route_msg(struct sk_buff *buf)
130{ 107{
131 struct tipc_msg *msg; 108 struct tipc_msg *msg;
@@ -141,10 +118,12 @@ void tipc_net_route_msg(struct sk_buff *buf)
141 if (msg_isdata(msg)) { 118 if (msg_isdata(msg)) {
142 if (msg_mcast(msg)) 119 if (msg_mcast(msg))
143 tipc_port_mcast_rcv(buf, NULL); 120 tipc_port_mcast_rcv(buf, NULL);
144 else if (msg_destport(msg)) 121 else if (msg_destport(msg)) {
145 tipc_sk_rcv(buf); 122 tipc_sk_rcv(buf);
146 else 123 } else {
147 net_route_named_msg(buf); 124 pr_warn("Cannot route msg; no destination\n");
125 kfree_skb(buf);
126 }
148 return; 127 return;
149 } 128 }
150 switch (msg_user(msg)) { 129 switch (msg_user(msg)) {
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 5961a6335f49..e642ed5b3602 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1466,16 +1466,10 @@ int tipc_sk_rcv(struct sk_buff *buf)
1466 uint limit; 1466 uint limit;
1467 u32 dnode; 1467 u32 dnode;
1468 1468
1469 /* Forward unresolved named message */ 1469 /* Validate destination and message */
1470 if (unlikely(!dport)) {
1471 tipc_net_route_msg(buf);
1472 return 0;
1473 }
1474
1475 /* Validate destination */
1476 port = tipc_port_lock(dport); 1470 port = tipc_port_lock(dport);
1477 if (unlikely(!port)) { 1471 if (unlikely(!port)) {
1478 rc = -TIPC_ERR_NO_PORT; 1472 rc = tipc_msg_eval(buf, &dnode);
1479 goto exit; 1473 goto exit;
1480 } 1474 }
1481 1475
@@ -1494,17 +1488,17 @@ int tipc_sk_rcv(struct sk_buff *buf)
1494 if (sk_add_backlog(sk, buf, limit)) 1488 if (sk_add_backlog(sk, buf, limit))
1495 rc = -TIPC_ERR_OVERLOAD; 1489 rc = -TIPC_ERR_OVERLOAD;
1496 } 1490 }
1497
1498 bh_unlock_sock(sk); 1491 bh_unlock_sock(sk);
1499 tipc_port_unlock(port); 1492 tipc_port_unlock(port);
1500 1493
1501 if (likely(!rc)) 1494 if (likely(!rc))
1502 return 0; 1495 return 0;
1503exit: 1496exit:
1504 if (!tipc_msg_reverse(buf, &dnode, -rc)) 1497 if ((rc < 0) && !tipc_msg_reverse(buf, &dnode, -rc))
1505 return -EHOSTUNREACH; 1498 return -EHOSTUNREACH;
1499
1506 tipc_link_xmit2(buf, dnode, 0); 1500 tipc_link_xmit2(buf, dnode, 0);
1507 return -EHOSTUNREACH; 1501 return (rc < 0) ? -EHOSTUNREACH : 0;
1508} 1502}
1509 1503
1510static int tipc_wait_for_connect(struct socket *sock, long *timeo_p) 1504static int tipc_wait_for_connect(struct socket *sock, long *timeo_p)