summaryrefslogtreecommitdiffstats
path: root/net/tipc/msg.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-07-22 10:11:18 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-26 19:31:50 -0400
commit29042e19f2c602fabe4705b5b719550b4627639c (patch)
treec56867f0670a1c8d4d20735857dbae24123778f4 /net/tipc/msg.c
parenta69e5a0dcfa4ea3e92b3cc0f17a39f1d88045c11 (diff)
tipc: let function tipc_msg_reverse() expand header when needed
The shortest TIPC message header, for cluster local CONNECTED messages, is 24 bytes long. With this format, the fields "dest_node" and "orig_node" are optimized away, since they in reality are redundant in this particular case. However, the absence of these fields leads to code inconsistencies that are difficult to handle in some cases, especially when we need to reverse or reject messages at the socket layer. In this commit, we concentrate the handling of the absent fields to one place, by letting the function tipc_msg_reverse() reallocate the buffer and expand the header to 32 bytes when necessary. This means that the socket code now can assume that the two previously absent fields are present in the header when a message needs to be rejected. This opens up for some further simplifications of the socket code. Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r--net/tipc/msg.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index 08b4cc7d496d..4339aab93034 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -463,43 +463,58 @@ bool tipc_msg_make_bundle(struct sk_buff **skb, struct tipc_msg *msg,
463 463
464/** 464/**
465 * tipc_msg_reverse(): swap source and destination addresses and add error code 465 * tipc_msg_reverse(): swap source and destination addresses and add error code
466 * @buf: buffer containing message to be reversed 466 * @own_node: originating node id for reversed message
467 * @dnode: return value: node where to send message after reversal 467 * @skb: buffer containing message to be reversed; may be replaced.
468 * @err: error code to be set in message 468 * @err: error code to be set in message, if any
469 * Consumes buffer if failure 469 * Consumes buffer at failure
470 * Returns true if success, otherwise false 470 * Returns true if success, otherwise false
471 */ 471 */
472bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode, 472bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, u32 *dnode, int err)
473 int err)
474{ 473{
475 struct tipc_msg *msg = buf_msg(buf); 474 struct sk_buff *_skb = *skb;
475 struct tipc_msg *hdr = buf_msg(_skb);
476 struct tipc_msg ohdr; 476 struct tipc_msg ohdr;
477 uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE); 477 int dlen = min_t(uint, msg_data_sz(hdr), MAX_FORWARD_SIZE);
478 478
479 if (skb_linearize(buf)) 479 if (skb_linearize(_skb))
480 goto exit; 480 goto exit;
481 msg = buf_msg(buf); 481 hdr = buf_msg(_skb);
482 if (msg_dest_droppable(msg)) 482 if (msg_dest_droppable(hdr))
483 goto exit; 483 goto exit;
484 if (msg_errcode(msg)) 484 if (msg_errcode(hdr))
485 goto exit; 485 goto exit;
486 memcpy(&ohdr, msg, msg_hdr_sz(msg)); 486
487 msg_set_errcode(msg, err); 487 /* Take a copy of original header before altering message */
488 msg_set_origport(msg, msg_destport(&ohdr)); 488 memcpy(&ohdr, hdr, msg_hdr_sz(hdr));
489 msg_set_destport(msg, msg_origport(&ohdr)); 489
490 msg_set_prevnode(msg, own_addr); 490 /* Never return SHORT header; expand by replacing buffer if necessary */
491 if (!msg_short(msg)) { 491 if (msg_short(hdr)) {
492 msg_set_orignode(msg, msg_destnode(&ohdr)); 492 *skb = tipc_buf_acquire(BASIC_H_SIZE + dlen);
493 msg_set_destnode(msg, msg_orignode(&ohdr)); 493 if (!*skb)
494 goto exit;
495 memcpy((*skb)->data + BASIC_H_SIZE, msg_data(hdr), dlen);
496 kfree_skb(_skb);
497 _skb = *skb;
498 hdr = buf_msg(_skb);
499 memcpy(hdr, &ohdr, BASIC_H_SIZE);
500 msg_set_hdr_sz(hdr, BASIC_H_SIZE);
494 } 501 }
495 msg_set_size(msg, msg_hdr_sz(msg) + rdsz); 502
496 skb_trim(buf, msg_size(msg)); 503 /* Now reverse the concerned fields */
497 skb_orphan(buf); 504 msg_set_errcode(hdr, err);
498 *dnode = msg_orignode(&ohdr); 505 msg_set_origport(hdr, msg_destport(&ohdr));
506 msg_set_destport(hdr, msg_origport(&ohdr));
507 msg_set_destnode(hdr, msg_prevnode(&ohdr));
508 msg_set_prevnode(hdr, own_node);
509 msg_set_orignode(hdr, own_node);
510 msg_set_size(hdr, msg_hdr_sz(hdr) + dlen);
511 *dnode = msg_destnode(hdr);
512 skb_trim(_skb, msg_size(hdr));
513 skb_orphan(_skb);
499 return true; 514 return true;
500exit: 515exit:
501 kfree_skb(buf); 516 kfree_skb(_skb);
502 *dnode = 0; 517 *skb = NULL;
503 return false; 518 return false;
504} 519}
505 520