diff options
author | Jon Paul Maloy <jon.maloy@ericsson.com> | 2015-07-22 10:11:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-07-26 19:31:50 -0400 |
commit | bcd3ffd4f6d7c994c93be2ab8598fdfb2952a1f1 (patch) | |
tree | acc0313d0b76c136e0b32944c45dadd69a8f0bcb /net/tipc/socket.c | |
parent | 29042e19f2c602fabe4705b5b719550b4627639c (diff) |
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>
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 81 |
1 files changed, 45 insertions, 36 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e2d5b9831485..71d88adadb18 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -248,6 +248,22 @@ static void tsk_advance_rx_queue(struct sock *sk) | |||
248 | kfree_skb(__skb_dequeue(&sk->sk_receive_queue)); | 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 | * tsk_rej_rx_queue - reject all buffers in socket receive queue | 268 | * tsk_rej_rx_queue - reject all buffers in socket receive queue |
253 | * | 269 | * |
@@ -256,13 +272,9 @@ static void tsk_advance_rx_queue(struct sock *sk) | |||
256 | static void tsk_rej_rx_queue(struct sock *sk) | 272 | static void tsk_rej_rx_queue(struct sock *sk) |
257 | { | 273 | { |
258 | struct sk_buff *skb; | 274 | struct sk_buff *skb; |
259 | u32 dnode; | ||
260 | u32 own_node = tsk_own_node(tipc_sk(sk)); | ||
261 | 275 | ||
262 | while ((skb = __skb_dequeue(&sk->sk_receive_queue))) { | 276 | while ((skb = __skb_dequeue(&sk->sk_receive_queue))) |
263 | if (tipc_msg_reverse(own_node, &skb, &dnode, TIPC_ERR_NO_PORT)) | 277 | tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT); |
264 | tipc_node_xmit_skb(sock_net(sk), skb, dnode, 0); | ||
265 | } | ||
266 | } | 278 | } |
267 | 279 | ||
268 | /* tsk_peer_msg - verify if message was sent by connected port's peer | 280 | /* tsk_peer_msg - verify if message was sent by connected port's peer |
@@ -441,9 +453,7 @@ static int tipc_release(struct socket *sock) | |||
441 | tsk->connected = 0; | 453 | tsk->connected = 0; |
442 | tipc_node_remove_conn(net, dnode, tsk->portid); | 454 | tipc_node_remove_conn(net, dnode, tsk->portid); |
443 | } | 455 | } |
444 | if (tipc_msg_reverse(tsk_own_node(tsk), &skb, &dnode, | 456 | tipc_sk_respond(sk, skb, TIPC_ERR_NO_PORT); |
445 | TIPC_ERR_NO_PORT)) | ||
446 | tipc_node_xmit_skb(net, skb, dnode, 0); | ||
447 | } | 457 | } |
448 | } | 458 | } |
449 | 459 | ||
@@ -764,35 +774,35 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, | |||
764 | /** | 774 | /** |
765 | * tipc_sk_proto_rcv - receive a connection mng protocol message | 775 | * tipc_sk_proto_rcv - receive a connection mng protocol message |
766 | * @tsk: receiving socket | 776 | * @tsk: receiving socket |
767 | * @skb: pointer to message buffer. Set to NULL if buffer is consumed. | 777 | * @skb: pointer to message buffer. |
768 | */ | 778 | */ |
769 | static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff **skb) | 779 | static void tipc_sk_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb) |
770 | { | 780 | { |
771 | struct tipc_msg *msg = buf_msg(*skb); | 781 | struct sock *sk = &tsk->sk; |
782 | struct tipc_msg *hdr = buf_msg(skb); | ||
783 | int mtyp = msg_type(hdr); | ||
772 | int conn_cong; | 784 | int conn_cong; |
773 | u32 dnode; | 785 | |
774 | u32 own_node = tsk_own_node(tsk); | ||
775 | /* Ignore if connection cannot be validated: */ | 786 | /* Ignore if connection cannot be validated: */ |
776 | if (!tsk_peer_msg(tsk, msg)) | 787 | if (!tsk_peer_msg(tsk, hdr)) |
777 | goto exit; | 788 | goto exit; |
778 | 789 | ||
779 | tsk->probing_state = TIPC_CONN_OK; | 790 | tsk->probing_state = TIPC_CONN_OK; |
780 | 791 | ||
781 | if (msg_type(msg) == CONN_ACK) { | 792 | if (mtyp == CONN_PROBE) { |
793 | msg_set_type(hdr, CONN_PROBE_REPLY); | ||
794 | tipc_sk_respond(sk, skb, TIPC_OK); | ||
795 | return; | ||
796 | } else if (mtyp == CONN_ACK) { | ||
782 | conn_cong = tsk_conn_cong(tsk); | 797 | conn_cong = tsk_conn_cong(tsk); |
783 | tsk->sent_unacked -= msg_msgcnt(msg); | 798 | tsk->sent_unacked -= msg_msgcnt(hdr); |
784 | if (conn_cong) | 799 | if (conn_cong) |
785 | tsk->sk.sk_write_space(&tsk->sk); | 800 | sk->sk_write_space(sk); |
786 | } else if (msg_type(msg) == CONN_PROBE) { | 801 | } else if (mtyp != CONN_PROBE_REPLY) { |
787 | if (tipc_msg_reverse(own_node, skb, &dnode, TIPC_OK)) { | 802 | pr_warn("Received unknown CONN_PROTO msg\n"); |
788 | msg_set_type(msg, CONN_PROBE_REPLY); | ||
789 | return; | ||
790 | } | ||
791 | } | 803 | } |
792 | /* Do nothing if msg_type() == CONN_PROBE_REPLY */ | ||
793 | exit: | 804 | exit: |
794 | kfree_skb(*skb); | 805 | kfree_skb(skb); |
795 | *skb = NULL; | ||
796 | } | 806 | } |
797 | 807 | ||
798 | static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) | 808 | static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p) |
@@ -1638,7 +1648,7 @@ static int filter_rcv(struct sock *sk, struct sk_buff **skb) | |||
1638 | int rc = TIPC_OK; | 1648 | int rc = TIPC_OK; |
1639 | 1649 | ||
1640 | if (unlikely(msg_user(msg) == CONN_MANAGER)) { | 1650 | if (unlikely(msg_user(msg) == CONN_MANAGER)) { |
1641 | tipc_sk_proto_rcv(tsk, skb); | 1651 | tipc_sk_proto_rcv(tsk, *skb); |
1642 | return TIPC_OK; | 1652 | return TIPC_OK; |
1643 | } | 1653 | } |
1644 | 1654 | ||
@@ -1690,7 +1700,7 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb) | |||
1690 | { | 1700 | { |
1691 | int err; | 1701 | int err; |
1692 | atomic_t *dcnt; | 1702 | atomic_t *dcnt; |
1693 | u32 dnode; | 1703 | u32 dnode = msg_prevnode(buf_msg(skb)); |
1694 | struct tipc_sock *tsk = tipc_sk(sk); | 1704 | struct tipc_sock *tsk = tipc_sk(sk); |
1695 | struct net *net = sock_net(sk); | 1705 | struct net *net = sock_net(sk); |
1696 | uint truesize = skb->truesize; | 1706 | uint truesize = skb->truesize; |
@@ -1702,7 +1712,7 @@ static int tipc_backlog_rcv(struct sock *sk, struct sk_buff *skb) | |||
1702 | atomic_add(truesize, dcnt); | 1712 | atomic_add(truesize, dcnt); |
1703 | return 0; | 1713 | return 0; |
1704 | } | 1714 | } |
1705 | if (!err || tipc_msg_reverse(tsk_own_node(tsk), &skb, &dnode, -err)) | 1715 | if (!err || tipc_msg_reverse(tsk_own_node(tsk), &skb, -err)) |
1706 | tipc_node_xmit_skb(net, skb, dnode, tsk->portid); | 1716 | tipc_node_xmit_skb(net, skb, dnode, tsk->portid); |
1707 | return 0; | 1717 | return 0; |
1708 | } | 1718 | } |
@@ -1794,9 +1804,11 @@ int tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq) | |||
1794 | if (!err) { | 1804 | if (!err) { |
1795 | dnode = msg_destnode(buf_msg(skb)); | 1805 | dnode = msg_destnode(buf_msg(skb)); |
1796 | goto xmit; | 1806 | goto xmit; |
1807 | } else { | ||
1808 | dnode = msg_prevnode(buf_msg(skb)); | ||
1797 | } | 1809 | } |
1798 | tn = net_generic(net, tipc_net_id); | 1810 | tn = net_generic(net, tipc_net_id); |
1799 | if (!tipc_msg_reverse(tn->own_addr, &skb, &dnode, -err)) | 1811 | if (!tipc_msg_reverse(tn->own_addr, &skb, -err)) |
1800 | continue; | 1812 | continue; |
1801 | xmit: | 1813 | xmit: |
1802 | tipc_node_xmit_skb(net, skb, dnode, dport); | 1814 | tipc_node_xmit_skb(net, skb, dnode, dport); |
@@ -2083,6 +2095,8 @@ static int tipc_shutdown(struct socket *sock, int how) | |||
2083 | case SS_CONNECTED: | 2095 | case SS_CONNECTED: |
2084 | 2096 | ||
2085 | restart: | 2097 | restart: |
2098 | dnode = tsk_peer_node(tsk); | ||
2099 | |||
2086 | /* Disconnect and send a 'FIN+' or 'FIN-' message to peer */ | 2100 | /* Disconnect and send a 'FIN+' or 'FIN-' message to peer */ |
2087 | skb = __skb_dequeue(&sk->sk_receive_queue); | 2101 | skb = __skb_dequeue(&sk->sk_receive_queue); |
2088 | if (skb) { | 2102 | if (skb) { |
@@ -2090,13 +2104,8 @@ restart: | |||
2090 | kfree_skb(skb); | 2104 | kfree_skb(skb); |
2091 | goto restart; | 2105 | goto restart; |
2092 | } | 2106 | } |
2093 | if (tipc_msg_reverse(tsk_own_node(tsk), &skb, &dnode, | 2107 | tipc_sk_respond(sk, skb, TIPC_CONN_SHUTDOWN); |
2094 | TIPC_CONN_SHUTDOWN)) | ||
2095 | tipc_node_xmit_skb(net, skb, dnode, | ||
2096 | tsk->portid); | ||
2097 | } else { | 2108 | } else { |
2098 | dnode = tsk_peer_node(tsk); | ||
2099 | |||
2100 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, | 2109 | skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, |
2101 | TIPC_CONN_MSG, SHORT_H_SIZE, | 2110 | TIPC_CONN_MSG, SHORT_H_SIZE, |
2102 | 0, dnode, tsk_own_node(tsk), | 2111 | 0, dnode, tsk_own_node(tsk), |