diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/msg.c | 42 | ||||
-rw-r--r-- | net/tipc/msg.h | 2 | ||||
-rw-r--r-- | net/tipc/socket.c | 28 |
3 files changed, 64 insertions, 8 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 4093b4c94d26..6070dd0ec634 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include "core.h" | 37 | #include "core.h" |
38 | #include "msg.h" | 38 | #include "msg.h" |
39 | 39 | ||
40 | #define MAX_FORWARD_SIZE 1024 | ||
41 | |||
40 | static unsigned int align(unsigned int i) | 42 | static unsigned int align(unsigned int i) |
41 | { | 43 | { |
42 | return (i + 3) & ~3u; | 44 | return (i + 3) & ~3u; |
@@ -328,3 +330,43 @@ bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode) | |||
328 | *buf = bbuf; | 330 | *buf = bbuf; |
329 | return true; | 331 | return true; |
330 | } | 332 | } |
333 | |||
334 | /** | ||
335 | * tipc_msg_reverse(): swap source and destination addresses and add error code | ||
336 | * @buf: buffer containing message to be reversed | ||
337 | * @dnode: return value: node where to send message after reversal | ||
338 | * @err: error code to be set in message | ||
339 | * Consumes buffer if failure | ||
340 | * Returns true if success, otherwise false | ||
341 | */ | ||
342 | bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err) | ||
343 | { | ||
344 | struct tipc_msg *msg = buf_msg(buf); | ||
345 | uint imp = msg_importance(msg); | ||
346 | struct tipc_msg ohdr; | ||
347 | uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE); | ||
348 | |||
349 | if (skb_linearize(buf) || !msg_isdata(msg)) | ||
350 | goto exit; | ||
351 | if (msg_dest_droppable(msg) || msg_errcode(msg)) | ||
352 | goto exit; | ||
353 | |||
354 | memcpy(&ohdr, msg, msg_hdr_sz(msg)); | ||
355 | msg_set_importance(msg, min_t(uint, ++imp, TIPC_CRITICAL_IMPORTANCE)); | ||
356 | msg_set_errcode(msg, err); | ||
357 | msg_set_origport(msg, msg_destport(&ohdr)); | ||
358 | msg_set_destport(msg, msg_origport(&ohdr)); | ||
359 | msg_set_prevnode(msg, tipc_own_addr); | ||
360 | if (!msg_short(msg)) { | ||
361 | msg_set_orignode(msg, msg_destnode(&ohdr)); | ||
362 | msg_set_destnode(msg, msg_orignode(&ohdr)); | ||
363 | } | ||
364 | msg_set_size(msg, msg_hdr_sz(msg) + rdsz); | ||
365 | skb_trim(buf, msg_size(msg)); | ||
366 | skb_orphan(buf); | ||
367 | *dnode = msg_orignode(&ohdr); | ||
368 | return true; | ||
369 | exit: | ||
370 | kfree_skb(buf); | ||
371 | return false; | ||
372 | } | ||
diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 5e1339d60c69..38050941a504 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h | |||
@@ -725,6 +725,8 @@ static inline u32 msg_tot_origport(struct tipc_msg *m) | |||
725 | return msg_origport(m); | 725 | return msg_origport(m); |
726 | } | 726 | } |
727 | 727 | ||
728 | bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err); | ||
729 | |||
728 | void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, | 730 | void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, |
729 | u32 destnode); | 731 | u32 destnode); |
730 | 732 | ||
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 9a95dab13b7e..5961a6335f49 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "node.h" | 39 | #include "node.h" |
40 | 40 | ||
41 | #include <linux/export.h> | 41 | #include <linux/export.h> |
42 | #include "link.h" | ||
42 | 43 | ||
43 | #define SS_LISTENING -1 /* socket is listening */ | 44 | #define SS_LISTENING -1 /* socket is listening */ |
44 | #define SS_READY -2 /* socket is connectionless */ | 45 | #define SS_READY -2 /* socket is connectionless */ |
@@ -123,9 +124,12 @@ static void advance_rx_queue(struct sock *sk) | |||
123 | static void reject_rx_queue(struct sock *sk) | 124 | static void reject_rx_queue(struct sock *sk) |
124 | { | 125 | { |
125 | struct sk_buff *buf; | 126 | struct sk_buff *buf; |
127 | u32 dnode; | ||
126 | 128 | ||
127 | while ((buf = __skb_dequeue(&sk->sk_receive_queue))) | 129 | while ((buf = __skb_dequeue(&sk->sk_receive_queue))) { |
128 | tipc_reject_msg(buf, TIPC_ERR_NO_PORT); | 130 | if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) |
131 | tipc_link_xmit2(buf, dnode, 0); | ||
132 | } | ||
129 | } | 133 | } |
130 | 134 | ||
131 | /** | 135 | /** |
@@ -303,6 +307,7 @@ static int tipc_release(struct socket *sock) | |||
303 | struct tipc_sock *tsk; | 307 | struct tipc_sock *tsk; |
304 | struct tipc_port *port; | 308 | struct tipc_port *port; |
305 | struct sk_buff *buf; | 309 | struct sk_buff *buf; |
310 | u32 dnode; | ||
306 | 311 | ||
307 | /* | 312 | /* |
308 | * Exit if socket isn't fully initialized (occurs when a failed accept() | 313 | * Exit if socket isn't fully initialized (occurs when a failed accept() |
@@ -331,7 +336,8 @@ static int tipc_release(struct socket *sock) | |||
331 | sock->state = SS_DISCONNECTING; | 336 | sock->state = SS_DISCONNECTING; |
332 | tipc_port_disconnect(port->ref); | 337 | tipc_port_disconnect(port->ref); |
333 | } | 338 | } |
334 | tipc_reject_msg(buf, TIPC_ERR_NO_PORT); | 339 | if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) |
340 | tipc_link_xmit2(buf, dnode, 0); | ||
335 | } | 341 | } |
336 | } | 342 | } |
337 | 343 | ||
@@ -1430,14 +1436,15 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1430 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf) | 1436 | static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf) |
1431 | { | 1437 | { |
1432 | int rc; | 1438 | int rc; |
1439 | u32 onode; | ||
1433 | struct tipc_sock *tsk = tipc_sk(sk); | 1440 | struct tipc_sock *tsk = tipc_sk(sk); |
1434 | uint truesize = buf->truesize; | 1441 | uint truesize = buf->truesize; |
1435 | 1442 | ||
1436 | rc = filter_rcv(sk, buf); | 1443 | rc = filter_rcv(sk, buf); |
1437 | if (unlikely(rc)) | ||
1438 | tipc_reject_msg(buf, -rc); | ||
1439 | 1444 | ||
1440 | if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT) | 1445 | if (unlikely(rc && tipc_msg_reverse(buf, &onode, -rc))) |
1446 | tipc_link_xmit2(buf, onode, 0); | ||
1447 | else if (atomic_read(&tsk->dupl_rcvcnt) < TIPC_CONN_OVERLOAD_LIMIT) | ||
1441 | atomic_add(truesize, &tsk->dupl_rcvcnt); | 1448 | atomic_add(truesize, &tsk->dupl_rcvcnt); |
1442 | 1449 | ||
1443 | return 0; | 1450 | return 0; |
@@ -1457,6 +1464,7 @@ int tipc_sk_rcv(struct sk_buff *buf) | |||
1457 | u32 dport = msg_destport(buf_msg(buf)); | 1464 | u32 dport = msg_destport(buf_msg(buf)); |
1458 | int rc = TIPC_OK; | 1465 | int rc = TIPC_OK; |
1459 | uint limit; | 1466 | uint limit; |
1467 | u32 dnode; | ||
1460 | 1468 | ||
1461 | /* Forward unresolved named message */ | 1469 | /* Forward unresolved named message */ |
1462 | if (unlikely(!dport)) { | 1470 | if (unlikely(!dport)) { |
@@ -1493,7 +1501,9 @@ int tipc_sk_rcv(struct sk_buff *buf) | |||
1493 | if (likely(!rc)) | 1501 | if (likely(!rc)) |
1494 | return 0; | 1502 | return 0; |
1495 | exit: | 1503 | exit: |
1496 | tipc_reject_msg(buf, -rc); | 1504 | if (!tipc_msg_reverse(buf, &dnode, -rc)) |
1505 | return -EHOSTUNREACH; | ||
1506 | tipc_link_xmit2(buf, dnode, 0); | ||
1497 | return -EHOSTUNREACH; | 1507 | return -EHOSTUNREACH; |
1498 | } | 1508 | } |
1499 | 1509 | ||
@@ -1758,6 +1768,7 @@ static int tipc_shutdown(struct socket *sock, int how) | |||
1758 | struct tipc_sock *tsk = tipc_sk(sk); | 1768 | struct tipc_sock *tsk = tipc_sk(sk); |
1759 | struct tipc_port *port = &tsk->port; | 1769 | struct tipc_port *port = &tsk->port; |
1760 | struct sk_buff *buf; | 1770 | struct sk_buff *buf; |
1771 | u32 peer; | ||
1761 | int res; | 1772 | int res; |
1762 | 1773 | ||
1763 | if (how != SHUT_RDWR) | 1774 | if (how != SHUT_RDWR) |
@@ -1778,7 +1789,8 @@ restart: | |||
1778 | goto restart; | 1789 | goto restart; |
1779 | } | 1790 | } |
1780 | tipc_port_disconnect(port->ref); | 1791 | tipc_port_disconnect(port->ref); |
1781 | tipc_reject_msg(buf, TIPC_CONN_SHUTDOWN); | 1792 | if (tipc_msg_reverse(buf, &peer, TIPC_CONN_SHUTDOWN)) |
1793 | tipc_link_xmit2(buf, peer, 0); | ||
1782 | } else { | 1794 | } else { |
1783 | tipc_port_shutdown(port->ref); | 1795 | tipc_port_shutdown(port->ref); |
1784 | } | 1796 | } |