diff options
Diffstat (limited to 'net/tipc/socket.c')
-rw-r--r-- | net/tipc/socket.c | 227 |
1 files changed, 222 insertions, 5 deletions
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 8f34db2a9785..1217c90a363b 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include "bcast.h" | 46 | #include "bcast.h" |
47 | #include "netlink.h" | 47 | #include "netlink.h" |
48 | #include "group.h" | 48 | #include "group.h" |
49 | #include "trace.h" | ||
49 | 50 | ||
50 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ | 51 | #define CONN_TIMEOUT_DEFAULT 8000 /* default connect timeout = 8s */ |
51 | #define CONN_PROBING_INTV msecs_to_jiffies(3600000) /* [ms] => 1 h */ | 52 | #define CONN_PROBING_INTV msecs_to_jiffies(3600000) /* [ms] => 1 h */ |
@@ -233,6 +234,7 @@ static u16 tsk_inc(struct tipc_sock *tsk, int msglen) | |||
233 | */ | 234 | */ |
234 | static void tsk_advance_rx_queue(struct sock *sk) | 235 | static void tsk_advance_rx_queue(struct sock *sk) |
235 | { | 236 | { |
237 | trace_tipc_sk_advance_rx(sk, NULL, TIPC_DUMP_SK_RCVQ, " "); | ||
236 | kfree_skb(__skb_dequeue(&sk->sk_receive_queue)); | 238 | kfree_skb(__skb_dequeue(&sk->sk_receive_queue)); |
237 | } | 239 | } |
238 | 240 | ||
@@ -247,6 +249,7 @@ static void tipc_sk_respond(struct sock *sk, struct sk_buff *skb, int err) | |||
247 | if (!tipc_msg_reverse(onode, &skb, err)) | 249 | if (!tipc_msg_reverse(onode, &skb, err)) |
248 | return; | 250 | return; |
249 | 251 | ||
252 | trace_tipc_sk_rej_msg(sk, skb, TIPC_DUMP_NONE, "@sk_respond!"); | ||
250 | dnode = msg_destnode(buf_msg(skb)); | 253 | dnode = msg_destnode(buf_msg(skb)); |
251 | selector = msg_origport(buf_msg(skb)); | 254 | selector = msg_origport(buf_msg(skb)); |
252 | tipc_node_xmit_skb(sock_net(sk), skb, dnode, selector); | 255 | tipc_node_xmit_skb(sock_net(sk), skb, dnode, selector); |
@@ -482,6 +485,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock, | |||
482 | tsk_set_unreliable(tsk, true); | 485 | tsk_set_unreliable(tsk, true); |
483 | } | 486 | } |
484 | 487 | ||
488 | trace_tipc_sk_create(sk, NULL, TIPC_DUMP_NONE, " "); | ||
485 | return 0; | 489 | return 0; |
486 | } | 490 | } |
487 | 491 | ||
@@ -571,6 +575,7 @@ static int tipc_release(struct socket *sock) | |||
571 | tsk = tipc_sk(sk); | 575 | tsk = tipc_sk(sk); |
572 | lock_sock(sk); | 576 | lock_sock(sk); |
573 | 577 | ||
578 | trace_tipc_sk_release(sk, NULL, TIPC_DUMP_ALL, " "); | ||
574 | __tipc_shutdown(sock, TIPC_ERR_NO_PORT); | 579 | __tipc_shutdown(sock, TIPC_ERR_NO_PORT); |
575 | sk->sk_shutdown = SHUTDOWN_MASK; | 580 | sk->sk_shutdown = SHUTDOWN_MASK; |
576 | tipc_sk_leave(tsk); | 581 | tipc_sk_leave(tsk); |
@@ -718,6 +723,7 @@ static __poll_t tipc_poll(struct file *file, struct socket *sock, | |||
718 | __poll_t revents = 0; | 723 | __poll_t revents = 0; |
719 | 724 | ||
720 | sock_poll_wait(file, sock, wait); | 725 | sock_poll_wait(file, sock, wait); |
726 | trace_tipc_sk_poll(sk, NULL, TIPC_DUMP_ALL, " "); | ||
721 | 727 | ||
722 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 728 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
723 | revents |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM; | 729 | revents |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM; |
@@ -804,9 +810,12 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq, | |||
804 | rc = tipc_msg_build(hdr, msg, 0, dlen, mtu, &pkts); | 810 | rc = tipc_msg_build(hdr, msg, 0, dlen, mtu, &pkts); |
805 | 811 | ||
806 | /* Send message if build was successful */ | 812 | /* Send message if build was successful */ |
807 | if (unlikely(rc == dlen)) | 813 | if (unlikely(rc == dlen)) { |
814 | trace_tipc_sk_sendmcast(sk, skb_peek(&pkts), | ||
815 | TIPC_DUMP_SK_SNDQ, " "); | ||
808 | rc = tipc_mcast_xmit(net, &pkts, method, &dsts, | 816 | rc = tipc_mcast_xmit(net, &pkts, method, &dsts, |
809 | &tsk->cong_link_cnt); | 817 | &tsk->cong_link_cnt); |
818 | } | ||
810 | 819 | ||
811 | tipc_nlist_purge(&dsts); | 820 | tipc_nlist_purge(&dsts); |
812 | 821 | ||
@@ -1212,8 +1221,10 @@ static void tipc_sk_conn_proto_rcv(struct tipc_sock *tsk, struct sk_buff *skb, | |||
1212 | bool conn_cong; | 1221 | bool conn_cong; |
1213 | 1222 | ||
1214 | /* Ignore if connection cannot be validated: */ | 1223 | /* Ignore if connection cannot be validated: */ |
1215 | if (!tsk_peer_msg(tsk, hdr)) | 1224 | if (!tsk_peer_msg(tsk, hdr)) { |
1225 | trace_tipc_sk_drop_msg(sk, skb, TIPC_DUMP_NONE, "@proto_rcv!"); | ||
1216 | goto exit; | 1226 | goto exit; |
1227 | } | ||
1217 | 1228 | ||
1218 | if (unlikely(msg_errcode(hdr))) { | 1229 | if (unlikely(msg_errcode(hdr))) { |
1219 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); | 1230 | tipc_set_sk_state(sk, TIPC_DISCONNECTING); |
@@ -1381,6 +1392,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen) | |||
1381 | if (unlikely(syn && !tipc_msg_skb_clone(&pkts, &sk->sk_write_queue))) | 1392 | if (unlikely(syn && !tipc_msg_skb_clone(&pkts, &sk->sk_write_queue))) |
1382 | return -ENOMEM; | 1393 | return -ENOMEM; |
1383 | 1394 | ||
1395 | trace_tipc_sk_sendmsg(sk, skb_peek(&pkts), TIPC_DUMP_SK_SNDQ, " "); | ||
1384 | rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid); | 1396 | rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid); |
1385 | if (unlikely(rc == -ELINKCONG)) { | 1397 | if (unlikely(rc == -ELINKCONG)) { |
1386 | tipc_dest_push(clinks, dnode, 0); | 1398 | tipc_dest_push(clinks, dnode, 0); |
@@ -1458,6 +1470,8 @@ static int __tipc_sendstream(struct socket *sock, struct msghdr *m, size_t dlen) | |||
1458 | if (unlikely(rc != send)) | 1470 | if (unlikely(rc != send)) |
1459 | break; | 1471 | break; |
1460 | 1472 | ||
1473 | trace_tipc_sk_sendstream(sk, skb_peek(&pkts), | ||
1474 | TIPC_DUMP_SK_SNDQ, " "); | ||
1461 | rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid); | 1475 | rc = tipc_node_xmit(net, &pkts, dnode, tsk->portid); |
1462 | if (unlikely(rc == -ELINKCONG)) { | 1476 | if (unlikely(rc == -ELINKCONG)) { |
1463 | tsk->cong_link_cnt = 1; | 1477 | tsk->cong_link_cnt = 1; |
@@ -2132,6 +2146,7 @@ static void tipc_sk_filter_rcv(struct sock *sk, struct sk_buff *skb, | |||
2132 | struct sk_buff_head inputq; | 2146 | struct sk_buff_head inputq; |
2133 | int limit, err = TIPC_OK; | 2147 | int limit, err = TIPC_OK; |
2134 | 2148 | ||
2149 | trace_tipc_sk_filter_rcv(sk, skb, TIPC_DUMP_ALL, " "); | ||
2135 | TIPC_SKB_CB(skb)->bytes_read = 0; | 2150 | TIPC_SKB_CB(skb)->bytes_read = 0; |
2136 | __skb_queue_head_init(&inputq); | 2151 | __skb_queue_head_init(&inputq); |
2137 | __skb_queue_tail(&inputq, skb); | 2152 | __skb_queue_tail(&inputq, skb); |
@@ -2151,17 +2166,25 @@ static void tipc_sk_filter_rcv(struct sock *sk, struct sk_buff *skb, | |||
2151 | (!grp && msg_in_group(hdr))) | 2166 | (!grp && msg_in_group(hdr))) |
2152 | err = TIPC_ERR_NO_PORT; | 2167 | err = TIPC_ERR_NO_PORT; |
2153 | else if (sk_rmem_alloc_get(sk) + skb->truesize >= limit) { | 2168 | else if (sk_rmem_alloc_get(sk) + skb->truesize >= limit) { |
2169 | trace_tipc_sk_dump(sk, skb, TIPC_DUMP_ALL, | ||
2170 | "err_overload2!"); | ||
2154 | atomic_inc(&sk->sk_drops); | 2171 | atomic_inc(&sk->sk_drops); |
2155 | err = TIPC_ERR_OVERLOAD; | 2172 | err = TIPC_ERR_OVERLOAD; |
2156 | } | 2173 | } |
2157 | 2174 | ||
2158 | if (unlikely(err)) { | 2175 | if (unlikely(err)) { |
2159 | tipc_skb_reject(net, err, skb, xmitq); | 2176 | if (tipc_msg_reverse(tipc_own_addr(net), &skb, err)) { |
2177 | trace_tipc_sk_rej_msg(sk, skb, TIPC_DUMP_NONE, | ||
2178 | "@filter_rcv!"); | ||
2179 | __skb_queue_tail(xmitq, skb); | ||
2180 | } | ||
2160 | err = TIPC_OK; | 2181 | err = TIPC_OK; |
2161 | continue; | 2182 | continue; |
2162 | } | 2183 | } |
2163 | __skb_queue_tail(&sk->sk_receive_queue, skb); | 2184 | __skb_queue_tail(&sk->sk_receive_queue, skb); |
2164 | skb_set_owner_r(skb, sk); | 2185 | skb_set_owner_r(skb, sk); |
2186 | trace_tipc_sk_overlimit2(sk, skb, TIPC_DUMP_ALL, | ||
2187 | "rcvq >90% allocated!"); | ||
2165 | sk->sk_data_ready(sk); | 2188 | sk->sk_data_ready(sk); |
2166 | } | 2189 | } |
2167 | } | 2190 | } |
@@ -2227,14 +2250,21 @@ static void tipc_sk_enqueue(struct sk_buff_head *inputq, struct sock *sk, | |||
2227 | if (!sk->sk_backlog.len) | 2250 | if (!sk->sk_backlog.len) |
2228 | atomic_set(dcnt, 0); | 2251 | atomic_set(dcnt, 0); |
2229 | lim = rcvbuf_limit(sk, skb) + atomic_read(dcnt); | 2252 | lim = rcvbuf_limit(sk, skb) + atomic_read(dcnt); |
2230 | if (likely(!sk_add_backlog(sk, skb, lim))) | 2253 | if (likely(!sk_add_backlog(sk, skb, lim))) { |
2254 | trace_tipc_sk_overlimit1(sk, skb, TIPC_DUMP_ALL, | ||
2255 | "bklg & rcvq >90% allocated!"); | ||
2231 | continue; | 2256 | continue; |
2257 | } | ||
2232 | 2258 | ||
2259 | trace_tipc_sk_dump(sk, skb, TIPC_DUMP_ALL, "err_overload!"); | ||
2233 | /* Overload => reject message back to sender */ | 2260 | /* Overload => reject message back to sender */ |
2234 | onode = tipc_own_addr(sock_net(sk)); | 2261 | onode = tipc_own_addr(sock_net(sk)); |
2235 | atomic_inc(&sk->sk_drops); | 2262 | atomic_inc(&sk->sk_drops); |
2236 | if (tipc_msg_reverse(onode, &skb, TIPC_ERR_OVERLOAD)) | 2263 | if (tipc_msg_reverse(onode, &skb, TIPC_ERR_OVERLOAD)) { |
2264 | trace_tipc_sk_rej_msg(sk, skb, TIPC_DUMP_ALL, | ||
2265 | "@sk_enqueue!"); | ||
2237 | __skb_queue_tail(xmitq, skb); | 2266 | __skb_queue_tail(xmitq, skb); |
2267 | } | ||
2238 | break; | 2268 | break; |
2239 | } | 2269 | } |
2240 | } | 2270 | } |
@@ -2283,6 +2313,8 @@ void tipc_sk_rcv(struct net *net, struct sk_buff_head *inputq) | |||
2283 | /* Prepare for message rejection */ | 2313 | /* Prepare for message rejection */ |
2284 | if (!tipc_msg_reverse(tipc_own_addr(net), &skb, err)) | 2314 | if (!tipc_msg_reverse(tipc_own_addr(net), &skb, err)) |
2285 | continue; | 2315 | continue; |
2316 | |||
2317 | trace_tipc_sk_rej_msg(NULL, skb, TIPC_DUMP_NONE, "@sk_rcv!"); | ||
2286 | xmit: | 2318 | xmit: |
2287 | dnode = msg_destnode(buf_msg(skb)); | 2319 | dnode = msg_destnode(buf_msg(skb)); |
2288 | tipc_node_xmit_skb(net, skb, dnode, dport); | 2320 | tipc_node_xmit_skb(net, skb, dnode, dport); |
@@ -2556,6 +2588,7 @@ static int tipc_shutdown(struct socket *sock, int how) | |||
2556 | 2588 | ||
2557 | lock_sock(sk); | 2589 | lock_sock(sk); |
2558 | 2590 | ||
2591 | trace_tipc_sk_shutdown(sk, NULL, TIPC_DUMP_ALL, " "); | ||
2559 | __tipc_shutdown(sock, TIPC_CONN_SHUTDOWN); | 2592 | __tipc_shutdown(sock, TIPC_CONN_SHUTDOWN); |
2560 | sk->sk_shutdown = SEND_SHUTDOWN; | 2593 | sk->sk_shutdown = SEND_SHUTDOWN; |
2561 | 2594 | ||
@@ -3572,3 +3605,187 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
3572 | 3605 | ||
3573 | return skb->len; | 3606 | return skb->len; |
3574 | } | 3607 | } |
3608 | |||
3609 | /** | ||
3610 | * tipc_sk_filtering - check if a socket should be traced | ||
3611 | * @sk: the socket to be examined | ||
3612 | * @sysctl_tipc_sk_filter[]: the socket tuple for filtering, | ||
3613 | * (portid, sock type, name type, name lower, name upper) | ||
3614 | * | ||
3615 | * Returns true if the socket meets the socket tuple data | ||
3616 | * (value 0 = 'any') or when there is no tuple set (all = 0), | ||
3617 | * otherwise false | ||
3618 | */ | ||
3619 | bool tipc_sk_filtering(struct sock *sk) | ||
3620 | { | ||
3621 | struct tipc_sock *tsk; | ||
3622 | struct publication *p; | ||
3623 | u32 _port, _sktype, _type, _lower, _upper; | ||
3624 | u32 type = 0, lower = 0, upper = 0; | ||
3625 | |||
3626 | if (!sk) | ||
3627 | return true; | ||
3628 | |||
3629 | tsk = tipc_sk(sk); | ||
3630 | |||
3631 | _port = sysctl_tipc_sk_filter[0]; | ||
3632 | _sktype = sysctl_tipc_sk_filter[1]; | ||
3633 | _type = sysctl_tipc_sk_filter[2]; | ||
3634 | _lower = sysctl_tipc_sk_filter[3]; | ||
3635 | _upper = sysctl_tipc_sk_filter[4]; | ||
3636 | |||
3637 | if (!_port && !_sktype && !_type && !_lower && !_upper) | ||
3638 | return true; | ||
3639 | |||
3640 | if (_port) | ||
3641 | return (_port == tsk->portid); | ||
3642 | |||
3643 | if (_sktype && _sktype != sk->sk_type) | ||
3644 | return false; | ||
3645 | |||
3646 | if (tsk->published) { | ||
3647 | p = list_first_entry_or_null(&tsk->publications, | ||
3648 | struct publication, binding_sock); | ||
3649 | if (p) { | ||
3650 | type = p->type; | ||
3651 | lower = p->lower; | ||
3652 | upper = p->upper; | ||
3653 | } | ||
3654 | } | ||
3655 | |||
3656 | if (!tipc_sk_type_connectionless(sk)) { | ||
3657 | type = tsk->conn_type; | ||
3658 | lower = tsk->conn_instance; | ||
3659 | upper = tsk->conn_instance; | ||
3660 | } | ||
3661 | |||
3662 | if ((_type && _type != type) || (_lower && _lower != lower) || | ||
3663 | (_upper && _upper != upper)) | ||
3664 | return false; | ||
3665 | |||
3666 | return true; | ||
3667 | } | ||
3668 | |||
3669 | u32 tipc_sock_get_portid(struct sock *sk) | ||
3670 | { | ||
3671 | return (sk) ? (tipc_sk(sk))->portid : 0; | ||
3672 | } | ||
3673 | |||
3674 | /** | ||
3675 | * tipc_sk_overlimit1 - check if socket rx queue is about to be overloaded, | ||
3676 | * both the rcv and backlog queues are considered | ||
3677 | * @sk: tipc sk to be checked | ||
3678 | * @skb: tipc msg to be checked | ||
3679 | * | ||
3680 | * Returns true if the socket rx queue allocation is > 90%, otherwise false | ||
3681 | */ | ||
3682 | |||
3683 | bool tipc_sk_overlimit1(struct sock *sk, struct sk_buff *skb) | ||
3684 | { | ||
3685 | atomic_t *dcnt = &tipc_sk(sk)->dupl_rcvcnt; | ||
3686 | unsigned int lim = rcvbuf_limit(sk, skb) + atomic_read(dcnt); | ||
3687 | unsigned int qsize = sk->sk_backlog.len + sk_rmem_alloc_get(sk); | ||
3688 | |||
3689 | return (qsize > lim * 90 / 100); | ||
3690 | } | ||
3691 | |||
3692 | /** | ||
3693 | * tipc_sk_overlimit2 - check if socket rx queue is about to be overloaded, | ||
3694 | * only the rcv queue is considered | ||
3695 | * @sk: tipc sk to be checked | ||
3696 | * @skb: tipc msg to be checked | ||
3697 | * | ||
3698 | * Returns true if the socket rx queue allocation is > 90%, otherwise false | ||
3699 | */ | ||
3700 | |||
3701 | bool tipc_sk_overlimit2(struct sock *sk, struct sk_buff *skb) | ||
3702 | { | ||
3703 | unsigned int lim = rcvbuf_limit(sk, skb); | ||
3704 | unsigned int qsize = sk_rmem_alloc_get(sk); | ||
3705 | |||
3706 | return (qsize > lim * 90 / 100); | ||
3707 | } | ||
3708 | |||
3709 | /** | ||
3710 | * tipc_sk_dump - dump TIPC socket | ||
3711 | * @sk: tipc sk to be dumped | ||
3712 | * @dqueues: bitmask to decide if any socket queue to be dumped? | ||
3713 | * - TIPC_DUMP_NONE: don't dump socket queues | ||
3714 | * - TIPC_DUMP_SK_SNDQ: dump socket send queue | ||
3715 | * - TIPC_DUMP_SK_RCVQ: dump socket rcv queue | ||
3716 | * - TIPC_DUMP_SK_BKLGQ: dump socket backlog queue | ||
3717 | * - TIPC_DUMP_ALL: dump all the socket queues above | ||
3718 | * @buf: returned buffer of dump data in format | ||
3719 | */ | ||
3720 | int tipc_sk_dump(struct sock *sk, u16 dqueues, char *buf) | ||
3721 | { | ||
3722 | int i = 0; | ||
3723 | size_t sz = (dqueues) ? SK_LMAX : SK_LMIN; | ||
3724 | struct tipc_sock *tsk; | ||
3725 | struct publication *p; | ||
3726 | bool tsk_connected; | ||
3727 | |||
3728 | if (!sk) { | ||
3729 | i += scnprintf(buf, sz, "sk data: (null)\n"); | ||
3730 | return i; | ||
3731 | } | ||
3732 | |||
3733 | tsk = tipc_sk(sk); | ||
3734 | tsk_connected = !tipc_sk_type_connectionless(sk); | ||
3735 | |||
3736 | i += scnprintf(buf, sz, "sk data: %u", sk->sk_type); | ||
3737 | i += scnprintf(buf + i, sz - i, " %d", sk->sk_state); | ||
3738 | i += scnprintf(buf + i, sz - i, " %x", tsk_own_node(tsk)); | ||
3739 | i += scnprintf(buf + i, sz - i, " %u", tsk->portid); | ||
3740 | i += scnprintf(buf + i, sz - i, " | %u", tsk_connected); | ||
3741 | if (tsk_connected) { | ||
3742 | i += scnprintf(buf + i, sz - i, " %x", tsk_peer_node(tsk)); | ||
3743 | i += scnprintf(buf + i, sz - i, " %u", tsk_peer_port(tsk)); | ||
3744 | i += scnprintf(buf + i, sz - i, " %u", tsk->conn_type); | ||
3745 | i += scnprintf(buf + i, sz - i, " %u", tsk->conn_instance); | ||
3746 | } | ||
3747 | i += scnprintf(buf + i, sz - i, " | %u", tsk->published); | ||
3748 | if (tsk->published) { | ||
3749 | p = list_first_entry_or_null(&tsk->publications, | ||
3750 | struct publication, binding_sock); | ||
3751 | i += scnprintf(buf + i, sz - i, " %u", (p) ? p->type : 0); | ||
3752 | i += scnprintf(buf + i, sz - i, " %u", (p) ? p->lower : 0); | ||
3753 | i += scnprintf(buf + i, sz - i, " %u", (p) ? p->upper : 0); | ||
3754 | } | ||
3755 | i += scnprintf(buf + i, sz - i, " | %u", tsk->snd_win); | ||
3756 | i += scnprintf(buf + i, sz - i, " %u", tsk->rcv_win); | ||
3757 | i += scnprintf(buf + i, sz - i, " %u", tsk->max_pkt); | ||
3758 | i += scnprintf(buf + i, sz - i, " %x", tsk->peer_caps); | ||
3759 | i += scnprintf(buf + i, sz - i, " %u", tsk->cong_link_cnt); | ||
3760 | i += scnprintf(buf + i, sz - i, " %u", tsk->snt_unacked); | ||
3761 | i += scnprintf(buf + i, sz - i, " %u", tsk->rcv_unacked); | ||
3762 | i += scnprintf(buf + i, sz - i, " %u", atomic_read(&tsk->dupl_rcvcnt)); | ||
3763 | i += scnprintf(buf + i, sz - i, " %u", sk->sk_shutdown); | ||
3764 | i += scnprintf(buf + i, sz - i, " | %d", sk_wmem_alloc_get(sk)); | ||
3765 | i += scnprintf(buf + i, sz - i, " %d", sk->sk_sndbuf); | ||
3766 | i += scnprintf(buf + i, sz - i, " | %d", sk_rmem_alloc_get(sk)); | ||
3767 | i += scnprintf(buf + i, sz - i, " %d", sk->sk_rcvbuf); | ||
3768 | i += scnprintf(buf + i, sz - i, " | %d\n", sk->sk_backlog.len); | ||
3769 | |||
3770 | if (dqueues & TIPC_DUMP_SK_SNDQ) { | ||
3771 | i += scnprintf(buf + i, sz - i, "sk_write_queue: "); | ||
3772 | i += tipc_list_dump(&sk->sk_write_queue, false, buf + i); | ||
3773 | } | ||
3774 | |||
3775 | if (dqueues & TIPC_DUMP_SK_RCVQ) { | ||
3776 | i += scnprintf(buf + i, sz - i, "sk_receive_queue: "); | ||
3777 | i += tipc_list_dump(&sk->sk_receive_queue, false, buf + i); | ||
3778 | } | ||
3779 | |||
3780 | if (dqueues & TIPC_DUMP_SK_BKLGQ) { | ||
3781 | i += scnprintf(buf + i, sz - i, "sk_backlog:\n head "); | ||
3782 | i += tipc_skb_dump(sk->sk_backlog.head, false, buf + i); | ||
3783 | if (sk->sk_backlog.tail != sk->sk_backlog.head) { | ||
3784 | i += scnprintf(buf + i, sz - i, " tail "); | ||
3785 | i += tipc_skb_dump(sk->sk_backlog.tail, false, | ||
3786 | buf + i); | ||
3787 | } | ||
3788 | } | ||
3789 | |||
3790 | return i; | ||
3791 | } | ||