aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/msg.c42
-rw-r--r--net/tipc/msg.h2
-rw-r--r--net/tipc/socket.c28
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
40static unsigned int align(unsigned int i) 42static 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 */
342bool 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;
369exit:
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
728bool tipc_msg_reverse(struct sk_buff *buf, u32 *dnode, int err);
729
728void tipc_msg_init(struct tipc_msg *m, u32 user, u32 type, u32 hsize, 730void 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)
123static void reject_rx_queue(struct sock *sk) 124static 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)
1430static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *buf) 1436static 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;
1495exit: 1503exit:
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 }