aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r--net/tipc/msg.c42
1 files changed, 42 insertions, 0 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}