diff options
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r-- | net/tipc/msg.c | 42 |
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 | |||
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 | } | ||