Skip to content

Commit 29042e1

Browse files
Jon Paul Maloydavem330
authored andcommitted
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 <[email protected]> Signed-off-by: Jon Maloy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a69e5a0 commit 29042e1

File tree

3 files changed

+48
-34
lines changed

3 files changed

+48
-34
lines changed

net/tipc/msg.c

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -463,43 +463,58 @@ bool tipc_msg_make_bundle(struct sk_buff **skb, struct tipc_msg *msg,
463463

464464
/**
465465
* 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
470470
* Returns true if success, otherwise false
471471
*/
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)
474473
{
475-
struct tipc_msg *msg = buf_msg(buf);
474+
struct sk_buff *_skb = *skb;
475+
struct tipc_msg *hdr = buf_msg(_skb);
476476
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);
478478

479-
if (skb_linearize(buf))
479+
if (skb_linearize(_skb))
480480
goto exit;
481-
msg = buf_msg(buf);
482-
if (msg_dest_droppable(msg))
481+
hdr = buf_msg(_skb);
482+
if (msg_dest_droppable(hdr))
483483
goto exit;
484-
if (msg_errcode(msg))
484+
if (msg_errcode(hdr))
485485
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);
494501
}
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);
499514
return true;
500515
exit:
501-
kfree_skb(buf);
502-
*dnode = 0;
516+
kfree_skb(_skb);
517+
*skb = NULL;
503518
return false;
504519
}
505520

net/tipc/msg.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -785,8 +785,7 @@ static inline bool msg_peer_is_up(struct tipc_msg *m)
785785

786786
struct sk_buff *tipc_buf_acquire(u32 size);
787787
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);
790789
void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,
791790
u32 hsize, u32 destnode);
792791
struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,

net/tipc/socket.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ static void tsk_rej_rx_queue(struct sock *sk)
260260
u32 own_node = tsk_own_node(tipc_sk(sk));
261261

262262
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))
264264
tipc_node_xmit_skb(sock_net(sk), skb, dnode, 0);
265265
}
266266
}
@@ -441,7 +441,7 @@ static int tipc_release(struct socket *sock)
441441
tsk->connected = 0;
442442
tipc_node_remove_conn(net, dnode, tsk->portid);
443443
}
444-
if (tipc_msg_reverse(tsk_own_node(tsk), skb, &dnode,
444+
if (tipc_msg_reverse(tsk_own_node(tsk), &skb, &dnode,
445445
TIPC_ERR_NO_PORT))
446446
tipc_node_xmit_skb(net, skb, dnode, 0);
447447
}
@@ -784,7 +784,7 @@ static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff **skb)
784784
if (conn_cong)
785785
tsk->sk.sk_write_space(&tsk->sk);
786786
} 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)) {
788788
msg_set_type(msg, CONN_PROBE_REPLY);
789789
return;
790790
}
@@ -1702,7 +1702,7 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
17021702
atomic_add(truesize, dcnt);
17031703
return 0;
17041704
}
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))
17061706
tipc_node_xmit_skb(net, skb, dnode, tsk->portid);
17071707
return 0;
17081708
}
@@ -1796,7 +1796,7 @@ int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq)
17961796
goto xmit;
17971797
}
17981798
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))
18001800
continue;
18011801
xmit:
18021802
tipc_node_xmit_skb(net, skb, dnode, dport);
@@ -2090,7 +2090,7 @@ static int tipc_shutdown(struct socket *sock, int how)
20902090
kfree_skb(skb);
20912091
goto restart;
20922092
}
2093-
if (tipc_msg_reverse(tsk_own_node(tsk), skb, &dnode,
2093+
if (tipc_msg_reverse(tsk_own_node(tsk), &skb, &dnode,
20942094
TIPC_CONN_SHUTDOWN))
20952095
tipc_node_xmit_skb(net, skb, dnode,
20962096
tsk->portid);

0 commit comments

Comments
 (0)