diff options
-rw-r--r-- | net/tipc/msg.c | 38 | ||||
-rw-r--r-- | net/tipc/msg.h | 2 | ||||
-rw-r--r-- | net/tipc/net.c | 33 | ||||
-rw-r--r-- | net/tipc/socket.c | 16 |
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 | */ | ||
386 | int 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 | ||
728 | bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err); | 728 | bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err); |
729 | 729 | ||
730 | int tipc_msg_eval(struct sk_buff *buf, u32 *dnode); | ||
731 | |||
730 | void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, | 732 | void 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 | |||
107 | static 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 | |||
129 | void tipc_net_route_msg(struct sk_buff *buf) | 106 | void 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; |
1503 | exit: | 1496 | exit: |
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 | ||
1510 | static int tipc_wait_for_connect(struct socket *sock, long *timeo_p) | 1504 | static int tipc_wait_for_connect(struct socket *sock, long *timeo_p) |