aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2014-06-25 21:41:36 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-27 15:50:55 -0400
commit5a379074a7dd6d288ec9e6472769ba0e0c54dd85 (patch)
tree53ef118e4b5276de35a522202bcb739138ba4e83 /net
parent8db1bae30b7cd3c3abc05f467d0f7c69b33b80e9 (diff)
tipc: introduce message evaluation function
When a message arrives in a node and finds no destination socket, we may need to drop it, reject it, or forward it after a secondary destination lookup. The latter two cases currently results in a code path that is perceived as complex, because it follows a deep call chain via obscure functions such as net_route_named_msg() and net_route_msg(). We now introduce a function, tipc_msg_eval(), that takes the decision about whether such a message should be rejected or forwarded, but leaves it to the caller to actually perform the indicated action. If the decision is 'reject', it is still the task of the recently introduced function tipc_msg_reverse() to take the final decision about whether the message is rejectable or not. In the latter case it drops the message. As a result of this change, we can finally eliminate the function net_route_named_msg(), and hence become independent of net_route_msg(). Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-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)