Commit 29042e19f2c602fabe4705b5b719550b4627639c

Authored by Jon Paul Maloy
Committed by David S. Miller
1 parent a69e5a0dcf

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>

Showing 3 changed files with 48 additions and 34 deletions Side-by-side Diff

... ... @@ -463,43 +463,58 @@
463 463  
464 464 /**
465 465 * tipc_msg_reverse(): swap source and destination addresses and add error code
466   - * @buf: buffer containing message to be reversed
467   - * @dnode: return value: node where to send message after reversal
468   - * @err: error code to be set in message
469   - * Consumes buffer if failure
  466 + * @own_node: originating node id for reversed message
  467 + * @skb: buffer containing message to be reversed; may be replaced.
  468 + * @err: error code to be set in message, if any
  469 + * Consumes buffer at failure
470 470 * Returns true if success, otherwise false
471 471 */
472   -bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
473   - int err)
  472 +bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, u32 *dnode, 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 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 480 goto exit;
481   - msg = buf_msg(buf);
482   - if (msg_dest_droppable(msg))
  481 + hdr = buf_msg(_skb);
  482 + if (msg_dest_droppable(hdr))
483 483 goto exit;
484   - if (msg_errcode(msg))
  484 + if (msg_errcode(hdr))
485 485 goto exit;
486   - memcpy(&ohdr, msg, msg_hdr_sz(msg));
487   - msg_set_errcode(msg, err);
488   - msg_set_origport(msg, msg_destport(&ohdr));
489   - msg_set_destport(msg, msg_origport(&ohdr));
490   - msg_set_prevnode(msg, own_addr);
491   - if (!msg_short(msg)) {
492   - msg_set_orignode(msg, msg_destnode(&ohdr));
493   - msg_set_destnode(msg, msg_orignode(&ohdr));
  486 +
  487 + /* Take a copy of original header before altering message */
  488 + memcpy(&ohdr, hdr, msg_hdr_sz(hdr));
  489 +
  490 + /* Never return SHORT header; expand by replacing buffer if necessary */
  491 + if (msg_short(hdr)) {
  492 + *skb = tipc_buf_acquire(BASIC_H_SIZE + dlen);
  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);
496   - skb_trim(buf, msg_size(msg));
497   - skb_orphan(buf);
498   - *dnode = msg_orignode(&ohdr);
  502 +
  503 + /* Now reverse the concerned fields */
  504 + msg_set_errcode(hdr, err);
  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 514 return true;
500 515 exit:
501   - kfree_skb(buf);
502   - *dnode = 0;
  516 + kfree_skb(_skb);
  517 + *skb = NULL;
503 518 return false;
504 519 }
505 520  
... ... @@ -785,8 +785,7 @@
785 785  
786 786 struct sk_buff *tipc_buf_acquire(u32 size);
787 787 bool tipc_msg_validate(struct sk_buff *skb);
788   -bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
789   - int err);
  788 +bool tipc_msg_reverse(u32 own_addr, struct sk_buff **skb, u32 *dnode, int err);
790 789 void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,
791 790 u32 hsize, u32 destnode);
792 791 struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
... ... @@ -260,7 +260,7 @@
260 260 u32 own_node = tsk_own_node(tipc_sk(sk));
261 261  
262 262 while ((skb = __skb_dequeue(&sk->sk_receive_queue))) {
263   - if (tipc_msg_reverse(own_node, skb, &dnode, TIPC_ERR_NO_PORT))
  263 + if (tipc_msg_reverse(own_node, &skb, &dnode, TIPC_ERR_NO_PORT))
264 264 tipc_node_xmit_skb(sock_net(sk), skb, dnode, 0);
265 265 }
266 266 }
... ... @@ -441,7 +441,7 @@
441 441 tsk->connected = 0;
442 442 tipc_node_remove_conn(net, dnode, tsk->portid);
443 443 }
444   - if (tipc_msg_reverse(tsk_own_node(tsk), skb, &dnode,
  444 + if (tipc_msg_reverse(tsk_own_node(tsk), &skb, &dnode,
445 445 TIPC_ERR_NO_PORT))
446 446 tipc_node_xmit_skb(net, skb, dnode, 0);
447 447 }
... ... @@ -784,7 +784,7 @@
784 784 if (conn_cong)
785 785 tsk->sk.sk_write_space(&tsk->sk);
786 786 } else if (msg_type(msg) == CONN_PROBE) {
787   - if (tipc_msg_reverse(own_node, *skb, &dnode, TIPC_OK)) {
  787 + if (tipc_msg_reverse(own_node, skb, &dnode, TIPC_OK)) {
788 788 msg_set_type(msg, CONN_PROBE_REPLY);
789 789 return;
790 790 }
... ... @@ -1702,7 +1702,7 @@
1702 1702 atomic_add(truesize, dcnt);
1703 1703 return 0;
1704 1704 }
1705   - if (!err || tipc_msg_reverse(tsk_own_node(tsk), skb, &dnode, -err))
  1705 + if (!err || tipc_msg_reverse(tsk_own_node(tsk), &skb, &dnode, -err))
1706 1706 tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
1707 1707 return 0;
1708 1708 }
... ... @@ -1796,7 +1796,7 @@
1796 1796 goto xmit;
1797 1797 }
1798 1798 tn = net_generic(net, tipc_net_id);
1799   - if (!tipc_msg_reverse(tn->own_addr, skb, &dnode, -err))
  1799 + if (!tipc_msg_reverse(tn->own_addr, &skb, &dnode, -err))
1800 1800 continue;
1801 1801 xmit:
1802 1802 tipc_node_xmit_skb(net, skb, dnode, dport);
... ... @@ -2090,7 +2090,7 @@
2090 2090 kfree_skb(skb);
2091 2091 goto restart;
2092 2092 }
2093   - if (tipc_msg_reverse(tsk_own_node(tsk), skb, &dnode,
  2093 + if (tipc_msg_reverse(tsk_own_node(tsk), &skb, &dnode,
2094 2094 TIPC_CONN_SHUTDOWN))
2095 2095 tipc_node_xmit_skb(net, skb, dnode,
2096 2096 tsk->portid);