Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tipc: introduce new tipc_sk_respond() function

Currently, we use the code sequence

if (msg_reverse())
tipc_link_xmit_skb()

at numerous locations in socket.c. The preparation of arguments
for these calls, as well as the sequence itself, makes the code
unecessarily complex.

In this commit, we introduce a new function, tipc_sk_respond(),
that performs this call combination. We also replace some, but not
yet all, of these explicit call sequences with calls to the new
function. Notably, we let the function tipc_sk_proto_rcv() use
the new function to directly send out PROBE_REPLY messages,
instead of deferring this to the calling tipc_sk_rcv() function,
as we do now.

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>

authored by

Jon Paul Maloy and committed by
David S. Miller
bcd3ffd4 29042e19

+47 -39
+1 -2
net/tipc/msg.c
··· 469 469 * Consumes buffer at failure 470 470 * Returns true if success, otherwise false 471 471 */ 472 - bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, u32 *dnode, int err) 472 + bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err) 473 473 { 474 474 struct sk_buff *_skb = *skb; 475 475 struct tipc_msg *hdr = buf_msg(_skb); ··· 508 508 msg_set_prevnode(hdr, own_node); 509 509 msg_set_orignode(hdr, own_node); 510 510 msg_set_size(hdr, msg_hdr_sz(hdr) + dlen); 511 - *dnode = msg_destnode(hdr); 512 511 skb_trim(_skb, msg_size(hdr)); 513 512 skb_orphan(_skb); 514 513 return true;
+1 -1
net/tipc/msg.h
··· 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 **skb, u32 *dnode, int err); 788 + bool tipc_msg_reverse(u32 own_addr, struct sk_buff **skb, int err); 789 789 void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type, 790 790 u32 hsize, u32 destnode); 791 791 struct sk_buff *tipc_msg_create(uint user, uint type, uint hdr_sz,
+45 -36
net/tipc/socket.c
··· 248 248 kfree_skb(__skb_dequeue(&sk->sk_receive_queue)); 249 249 } 250 250 251 + /* tipc_sk_respond() : send response message back to sender 252 + */ 253 + static void tipc_sk_respond(struct sock *sk, struct sk_buff *skb, int err) 254 + { 255 + u32 selector; 256 + u32 dnode; 257 + u32 onode = tipc_own_addr(sock_net(sk)); 258 + 259 + if (!tipc_msg_reverse(onode, &skb, err)) 260 + return; 261 + 262 + dnode = msg_destnode(buf_msg(skb)); 263 + selector = msg_origport(buf_msg(skb)); 264 + tipc_node_xmit_skb(sock_net(sk), skb, dnode, selector); 265 + } 266 + 251 267 /** 252 268 * tsk_rej_rx_queue - reject all buffers in socket receive queue 253 269 * ··· 272 256 static void tsk_rej_rx_queue(struct sock *sk) 273 257 { 274 258 struct sk_buff *skb; 275 - u32 dnode; 276 - u32 own_node = tsk_own_node(tipc_sk(sk)); 277 259 278 - while ((skb = __skb_dequeue(&sk->sk_receive_queue))) { 279 - if (tipc_msg_reverse(own_node, &skb, &dnode, TIPC_ERR_NO_PORT)) 280 - tipc_node_xmit_skb(sock_net(sk), skb, dnode, 0); 281 - } 260 + while ((skb = __skb_dequeue(&sk->sk_receive_queue))) 261 + tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT); 282 262 } 283 263 284 264 /* tsk_peer_msg - verify if message was sent by connected port's peer ··· 453 441 tsk->connected = 0; 454 442 tipc_node_remove_conn(net, dnode, tsk->portid); 455 443 } 456 - if (tipc_msg_reverse(tsk_own_node(tsk), &skb, &dnode, 457 - TIPC_ERR_NO_PORT)) 458 - tipc_node_xmit_skb(net, skb, dnode, 0); 444 + tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT); 459 445 } 460 446 } 461 447 ··· 774 764 /** 775 765 * tipc_sk_proto_rcv - receive a connection mng protocol message 776 766 * @tsk: receiving socket 777 - * @skb: pointer to message buffer. Set to NULL if buffer is consumed. 767 + * @skb: pointer to message buffer. 778 768 */ 779 - static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff **skb) 769 + static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb) 780 770 { 781 - struct tipc_msg *msg = buf_msg(*skb); 771 + struct sock *sk = &tsk->sk; 772 + struct tipc_msg *hdr = buf_msg(skb); 773 + int mtyp = msg_type(hdr); 782 774 int conn_cong; 783 - u32 dnode; 784 - u32 own_node = tsk_own_node(tsk); 775 + 785 776 /* Ignore if connection cannot be validated: */ 786 - if (!tsk_peer_msg(tsk, msg)) 777 + if (!tsk_peer_msg(tsk, hdr)) 787 778 goto exit; 788 779 789 780 tsk->probing_state = TIPC_CONN_OK; 790 781 791 - if (msg_type(msg) == CONN_ACK) { 782 + if (mtyp == CONN_PROBE) { 783 + msg_set_type(hdr, CONN_PROBE_REPLY); 784 + tipc_sk_respond(sk, skb, TIPC_OK); 785 + return; 786 + } else if (mtyp == CONN_ACK) { 792 787 conn_cong = tsk_conn_cong(tsk); 793 - tsk->sent_unacked -= msg_msgcnt(msg); 788 + tsk->sent_unacked -= msg_msgcnt(hdr); 794 789 if (conn_cong) 795 - tsk->sk.sk_write_space(&tsk->sk); 796 - } else if (msg_type(msg) == CONN_PROBE) { 797 - if (tipc_msg_reverse(own_node, skb, &dnode, TIPC_OK)) { 798 - msg_set_type(msg, CONN_PROBE_REPLY); 799 - return; 800 - } 790 + sk->sk_write_space(sk); 791 + } else if (mtyp != CONN_PROBE_REPLY) { 792 + pr_warn("Received unknown CONN_PROTO msg\n"); 801 793 } 802 - /* Do nothing if msg_type() == CONN_PROBE_REPLY */ 803 794 exit: 804 - kfree_skb(*skb); 805 - *skb = NULL; 795 + kfree_skb(skb); 806 796 } 807 797 808 798 static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) ··· 1648 1638 int rc = TIPC_OK; 1649 1639 1650 1640 if (unlikely(msg_user(msg) == CONN_MANAGER)) { 1651 - tipc_sk_proto_rcv(tsk, skb); 1641 + tipc_sk_proto_rcv(tsk, *skb); 1652 1642 return TIPC_OK; 1653 1643 } 1654 1644 ··· 1700 1690 { 1701 1691 int err; 1702 1692 atomic_t *dcnt; 1703 - u32 dnode; 1693 + u32 dnode = msg_prevnode(buf_msg(skb)); 1704 1694 struct tipc_sock *tsk = tipc_sk(sk); 1705 1695 struct net *net = sock_net(sk); 1706 1696 uint truesize = skb->truesize; ··· 1712 1702 atomic_add(truesize, dcnt); 1713 1703 return 0; 1714 1704 } 1715 - if (!err || tipc_msg_reverse(tsk_own_node(tsk), &skb, &dnode, -err)) 1705 + if (!err || tipc_msg_reverse(tsk_own_node(tsk), &skb, -err)) 1716 1706 tipc_node_xmit_skb(net, skb, dnode, tsk->portid); 1717 1707 return 0; 1718 1708 } ··· 1804 1794 if (!err) { 1805 1795 dnode = msg_destnode(buf_msg(skb)); 1806 1796 goto xmit; 1797 + } else { 1798 + dnode = msg_prevnode(buf_msg(skb)); 1807 1799 } 1808 1800 tn = net_generic(net, tipc_net_id); 1809 - if (!tipc_msg_reverse(tn->own_addr, &skb, &dnode, -err)) 1801 + if (!tipc_msg_reverse(tn->own_addr, &skb, -err)) 1810 1802 continue; 1811 1803 xmit: 1812 1804 tipc_node_xmit_skb(net, skb, dnode, dport); ··· 2095 2083 case SS_CONNECTED: 2096 2084 2097 2085 restart: 2086 + dnode = tsk_peer_node(tsk); 2087 + 2098 2088 /* Disconnect and send a 'FIN+' or 'FIN-' message to peer */ 2099 2089 skb = __skb_dequeue(&sk->sk_receive_queue); 2100 2090 if (skb) { ··· 2104 2090 kfree_skb(skb); 2105 2091 goto restart; 2106 2092 } 2107 - if (tipc_msg_reverse(tsk_own_node(tsk), &skb, &dnode, 2108 - TIPC_CONN_SHUTDOWN)) 2109 - tipc_node_xmit_skb(net, skb, dnode, 2110 - tsk->portid); 2093 + tipc_sk_respond(sk, skb, TIPC_CONN_SHUTDOWN); 2111 2094 } else { 2112 - dnode = tsk_peer_node(tsk); 2113 - 2114 2095 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, 2115 2096 TIPC_CONN_MSG, SHORT_H_SIZE, 2116 2097 0, dnode, tsk_own_node(tsk),