aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/Makefile4
-rw-r--r--net/tipc/bearer.c7
-rw-r--r--net/tipc/bearer.h2
-rw-r--r--net/tipc/link.c120
-rw-r--r--net/tipc/link.h1
-rw-r--r--net/tipc/node.c63
-rw-r--r--net/tipc/node.h1
-rw-r--r--net/tipc/socket.c90
-rw-r--r--net/tipc/socket.h2
-rw-r--r--net/tipc/trace.c200
-rw-r--r--net/tipc/trace.h231
11 files changed, 716 insertions, 5 deletions
diff --git a/net/tipc/Makefile b/net/tipc/Makefile
index aca168f2abb1..c86aba0282af 100644
--- a/net/tipc/Makefile
+++ b/net/tipc/Makefile
@@ -9,7 +9,9 @@ tipc-y += addr.o bcast.o bearer.o \
9 core.o link.o discover.o msg.o \ 9 core.o link.o discover.o msg.o \
10 name_distr.o subscr.o monitor.o name_table.o net.o \ 10 name_distr.o subscr.o monitor.o name_table.o net.o \
11 netlink.o netlink_compat.o node.o socket.o eth_media.o \ 11 netlink.o netlink_compat.o node.o socket.o eth_media.o \
12 topsrv.o socket.o group.o 12 topsrv.o socket.o group.o trace.o
13
14CFLAGS_trace.o += -I$(src)
13 15
14tipc-$(CONFIG_TIPC_MEDIA_UDP) += udp_media.o 16tipc-$(CONFIG_TIPC_MEDIA_UDP) += udp_media.o
15tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o 17tipc-$(CONFIG_TIPC_MEDIA_IB) += ib_media.o
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index e65c3a8551e4..e32294f37c29 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -99,7 +99,7 @@ static struct tipc_media *media_find_id(u8 type)
99/** 99/**
100 * tipc_media_addr_printf - record media address in print buffer 100 * tipc_media_addr_printf - record media address in print buffer
101 */ 101 */
102void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a) 102int tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a)
103{ 103{
104 char addr_str[MAX_ADDR_STR]; 104 char addr_str[MAX_ADDR_STR];
105 struct tipc_media *m; 105 struct tipc_media *m;
@@ -114,9 +114,10 @@ void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a)
114 114
115 ret = scnprintf(buf, len, "UNKNOWN(%u)", a->media_id); 115 ret = scnprintf(buf, len, "UNKNOWN(%u)", a->media_id);
116 for (i = 0; i < sizeof(a->value); i++) 116 for (i = 0; i < sizeof(a->value); i++)
117 ret += scnprintf(buf - ret, len + ret, 117 ret += scnprintf(buf + ret, len - ret,
118 "-%02x", a->value[i]); 118 "-%x", a->value[i]);
119 } 119 }
120 return ret;
120} 121}
121 122
122/** 123/**
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 394290cbbb1d..7f4c569594a5 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -207,7 +207,7 @@ int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info);
207 207
208int tipc_media_set_priority(const char *name, u32 new_value); 208int tipc_media_set_priority(const char *name, u32 new_value);
209int tipc_media_set_window(const char *name, u32 new_value); 209int tipc_media_set_window(const char *name, u32 new_value);
210void tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); 210int tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a);
211int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b, 211int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
212 struct nlattr *attrs[]); 212 struct nlattr *attrs[]);
213void tipc_disable_l2_media(struct tipc_bearer *b); 213void tipc_disable_l2_media(struct tipc_bearer *b);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 9e265eb89726..668dab529021 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -43,6 +43,7 @@
43#include "discover.h" 43#include "discover.h"
44#include "netlink.h" 44#include "netlink.h"
45#include "monitor.h" 45#include "monitor.h"
46#include "trace.h"
46 47
47#include <linux/pkt_sched.h> 48#include <linux/pkt_sched.h>
48 49
@@ -2222,3 +2223,122 @@ void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit)
2222{ 2223{
2223 l->abort_limit = limit; 2224 l->abort_limit = limit;
2224} 2225}
2226
2227char *tipc_link_name_ext(struct tipc_link *l, char *buf)
2228{
2229 if (!l)
2230 scnprintf(buf, TIPC_MAX_LINK_NAME, "null");
2231 else if (link_is_bc_sndlink(l))
2232 scnprintf(buf, TIPC_MAX_LINK_NAME, "broadcast-sender");
2233 else if (link_is_bc_rcvlink(l))
2234 scnprintf(buf, TIPC_MAX_LINK_NAME,
2235 "broadcast-receiver, peer %x", l->addr);
2236 else
2237 memcpy(buf, l->name, TIPC_MAX_LINK_NAME);
2238
2239 return buf;
2240}
2241
2242/**
2243 * tipc_link_dump - dump TIPC link data
2244 * @l: tipc link to be dumped
2245 * @dqueues: bitmask to decide if any link queue to be dumped?
2246 * - TIPC_DUMP_NONE: don't dump link queues
2247 * - TIPC_DUMP_TRANSMQ: dump link transmq queue
2248 * - TIPC_DUMP_BACKLOGQ: dump link backlog queue
2249 * - TIPC_DUMP_DEFERDQ: dump link deferd queue
2250 * - TIPC_DUMP_INPUTQ: dump link input queue
2251 * - TIPC_DUMP_WAKEUP: dump link wakeup queue
2252 * - TIPC_DUMP_ALL: dump all the link queues above
2253 * @buf: returned buffer of dump data in format
2254 */
2255int tipc_link_dump(struct tipc_link *l, u16 dqueues, char *buf)
2256{
2257 int i = 0;
2258 size_t sz = (dqueues) ? LINK_LMAX : LINK_LMIN;
2259 struct sk_buff_head *list;
2260 struct sk_buff *hskb, *tskb;
2261 u32 len;
2262
2263 if (!l) {
2264 i += scnprintf(buf, sz, "link data: (null)\n");
2265 return i;
2266 }
2267
2268 i += scnprintf(buf, sz, "link data: %x", l->addr);
2269 i += scnprintf(buf + i, sz - i, " %x", l->state);
2270 i += scnprintf(buf + i, sz - i, " %u", l->in_session);
2271 i += scnprintf(buf + i, sz - i, " %u", l->session);
2272 i += scnprintf(buf + i, sz - i, " %u", l->peer_session);
2273 i += scnprintf(buf + i, sz - i, " %u", l->snd_nxt);
2274 i += scnprintf(buf + i, sz - i, " %u", l->rcv_nxt);
2275 i += scnprintf(buf + i, sz - i, " %u", l->snd_nxt_state);
2276 i += scnprintf(buf + i, sz - i, " %u", l->rcv_nxt_state);
2277 i += scnprintf(buf + i, sz - i, " %x", l->peer_caps);
2278 i += scnprintf(buf + i, sz - i, " %u", l->silent_intv_cnt);
2279 i += scnprintf(buf + i, sz - i, " %u", l->rst_cnt);
2280 i += scnprintf(buf + i, sz - i, " %u", l->prev_from);
2281 i += scnprintf(buf + i, sz - i, " %u", l->stale_cnt);
2282 i += scnprintf(buf + i, sz - i, " %u", l->acked);
2283
2284 list = &l->transmq;
2285 len = skb_queue_len(list);
2286 hskb = skb_peek(list);
2287 tskb = skb_peek_tail(list);
2288 i += scnprintf(buf + i, sz - i, " | %u %u %u", len,
2289 (hskb) ? msg_seqno(buf_msg(hskb)) : 0,
2290 (tskb) ? msg_seqno(buf_msg(tskb)) : 0);
2291
2292 list = &l->deferdq;
2293 len = skb_queue_len(list);
2294 hskb = skb_peek(list);
2295 tskb = skb_peek_tail(list);
2296 i += scnprintf(buf + i, sz - i, " | %u %u %u", len,
2297 (hskb) ? msg_seqno(buf_msg(hskb)) : 0,
2298 (tskb) ? msg_seqno(buf_msg(tskb)) : 0);
2299
2300 list = &l->backlogq;
2301 len = skb_queue_len(list);
2302 hskb = skb_peek(list);
2303 tskb = skb_peek_tail(list);
2304 i += scnprintf(buf + i, sz - i, " | %u %u %u", len,
2305 (hskb) ? msg_seqno(buf_msg(hskb)) : 0,
2306 (tskb) ? msg_seqno(buf_msg(tskb)) : 0);
2307
2308 list = l->inputq;
2309 len = skb_queue_len(list);
2310 hskb = skb_peek(list);
2311 tskb = skb_peek_tail(list);
2312 i += scnprintf(buf + i, sz - i, " | %u %u %u\n", len,
2313 (hskb) ? msg_seqno(buf_msg(hskb)) : 0,
2314 (tskb) ? msg_seqno(buf_msg(tskb)) : 0);
2315
2316 if (dqueues & TIPC_DUMP_TRANSMQ) {
2317 i += scnprintf(buf + i, sz - i, "transmq: ");
2318 i += tipc_list_dump(&l->transmq, false, buf + i);
2319 }
2320 if (dqueues & TIPC_DUMP_BACKLOGQ) {
2321 i += scnprintf(buf + i, sz - i,
2322 "backlogq: <%u %u %u %u %u>, ",
2323 l->backlog[TIPC_LOW_IMPORTANCE].len,
2324 l->backlog[TIPC_MEDIUM_IMPORTANCE].len,
2325 l->backlog[TIPC_HIGH_IMPORTANCE].len,
2326 l->backlog[TIPC_CRITICAL_IMPORTANCE].len,
2327 l->backlog[TIPC_SYSTEM_IMPORTANCE].len);
2328 i += tipc_list_dump(&l->backlogq, false, buf + i);
2329 }
2330 if (dqueues & TIPC_DUMP_DEFERDQ) {
2331 i += scnprintf(buf + i, sz - i, "deferdq: ");
2332 i += tipc_list_dump(&l->deferdq, false, buf + i);
2333 }
2334 if (dqueues & TIPC_DUMP_INPUTQ) {
2335 i += scnprintf(buf + i, sz - i, "inputq: ");
2336 i += tipc_list_dump(l->inputq, false, buf + i);
2337 }
2338 if (dqueues & TIPC_DUMP_WAKEUP) {
2339 i += scnprintf(buf + i, sz - i, "wakeup: ");
2340 i += tipc_list_dump(&l->wakeupq, false, buf + i);
2341 }
2342
2343 return i;
2344}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 90488c538a4e..e8f692598e4d 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -109,6 +109,7 @@ u16 tipc_link_rcv_nxt(struct tipc_link *l);
109u16 tipc_link_acked(struct tipc_link *l); 109u16 tipc_link_acked(struct tipc_link *l);
110u32 tipc_link_id(struct tipc_link *l); 110u32 tipc_link_id(struct tipc_link *l);
111char *tipc_link_name(struct tipc_link *l); 111char *tipc_link_name(struct tipc_link *l);
112char *tipc_link_name_ext(struct tipc_link *l, char *buf);
112u32 tipc_link_state(struct tipc_link *l); 113u32 tipc_link_state(struct tipc_link *l);
113char tipc_link_plane(struct tipc_link *l); 114char tipc_link_plane(struct tipc_link *l);
114int tipc_link_prio(struct tipc_link *l); 115int tipc_link_prio(struct tipc_link *l);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 5980abb7839b..4fd6e2887818 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -43,6 +43,7 @@
43#include "monitor.h" 43#include "monitor.h"
44#include "discover.h" 44#include "discover.h"
45#include "netlink.h" 45#include "netlink.h"
46#include "trace.h"
46 47
47#define INVALID_NODE_SIG 0x10000 48#define INVALID_NODE_SIG 0x10000
48#define NODE_CLEANUP_AFTER 300000 49#define NODE_CLEANUP_AFTER 300000
@@ -2435,3 +2436,65 @@ int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb,
2435 2436
2436 return skb->len; 2437 return skb->len;
2437} 2438}
2439
2440u32 tipc_node_get_addr(struct tipc_node *node)
2441{
2442 return (node) ? node->addr : 0;
2443}
2444
2445/**
2446 * tipc_node_dump - dump TIPC node data
2447 * @n: tipc node to be dumped
2448 * @more: dump more?
2449 * - false: dump only tipc node data
2450 * - true: dump node link data as well
2451 * @buf: returned buffer of dump data in format
2452 */
2453int tipc_node_dump(struct tipc_node *n, bool more, char *buf)
2454{
2455 int i = 0;
2456 size_t sz = (more) ? NODE_LMAX : NODE_LMIN;
2457
2458 if (!n) {
2459 i += scnprintf(buf, sz, "node data: (null)\n");
2460 return i;
2461 }
2462
2463 i += scnprintf(buf, sz, "node data: %x", n->addr);
2464 i += scnprintf(buf + i, sz - i, " %x", n->state);
2465 i += scnprintf(buf + i, sz - i, " %d", n->active_links[0]);
2466 i += scnprintf(buf + i, sz - i, " %d", n->active_links[1]);
2467 i += scnprintf(buf + i, sz - i, " %x", n->action_flags);
2468 i += scnprintf(buf + i, sz - i, " %u", n->failover_sent);
2469 i += scnprintf(buf + i, sz - i, " %u", n->sync_point);
2470 i += scnprintf(buf + i, sz - i, " %d", n->link_cnt);
2471 i += scnprintf(buf + i, sz - i, " %u", n->working_links);
2472 i += scnprintf(buf + i, sz - i, " %x", n->capabilities);
2473 i += scnprintf(buf + i, sz - i, " %lu\n", n->keepalive_intv);
2474
2475 if (!more)
2476 return i;
2477
2478 i += scnprintf(buf + i, sz - i, "link_entry[0]:\n");
2479 i += scnprintf(buf + i, sz - i, " mtu: %u\n", n->links[0].mtu);
2480 i += scnprintf(buf + i, sz - i, " media: ");
2481 i += tipc_media_addr_printf(buf + i, sz - i, &n->links[0].maddr);
2482 i += scnprintf(buf + i, sz - i, "\n");
2483 i += tipc_link_dump(n->links[0].link, TIPC_DUMP_NONE, buf + i);
2484 i += scnprintf(buf + i, sz - i, " inputq: ");
2485 i += tipc_list_dump(&n->links[0].inputq, false, buf + i);
2486
2487 i += scnprintf(buf + i, sz - i, "link_entry[1]:\n");
2488 i += scnprintf(buf + i, sz - i, " mtu: %u\n", n->links[1].mtu);
2489 i += scnprintf(buf + i, sz - i, " media: ");
2490 i += tipc_media_addr_printf(buf + i, sz - i, &n->links[1].maddr);
2491 i += scnprintf(buf + i, sz - i, "\n");
2492 i += tipc_link_dump(n->links[1].link, TIPC_DUMP_NONE, buf + i);
2493 i += scnprintf(buf + i, sz - i, " inputq: ");
2494 i += tipc_list_dump(&n->links[1].inputq, false, buf + i);
2495
2496 i += scnprintf(buf + i, sz - i, "bclink:\n ");
2497 i += tipc_link_dump(n->bc_entry.link, TIPC_DUMP_NONE, buf + i);
2498
2499 return i;
2500}
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 03f5efb62cfb..4f59a30e989a 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -65,6 +65,7 @@ enum {
65 65
66void tipc_node_stop(struct net *net); 66void tipc_node_stop(struct net *net);
67bool tipc_node_get_id(struct net *net, u32 addr, u8 *id); 67bool tipc_node_get_id(struct net *net, u32 addr, u8 *id);
68u32 tipc_node_get_addr(struct tipc_node *node);
68u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr); 69u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr);
69void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128, 70void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128,
70 struct tipc_bearer *bearer, 71 struct tipc_bearer *bearer,
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index b57b1be7252b..b6b2a94eb54e 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 */
@@ -3564,3 +3565,92 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb)
3564 3565
3565 return skb->len; 3566 return skb->len;
3566} 3567}
3568
3569u32 tipc_sock_get_portid(struct sock *sk)
3570{
3571 return (sk) ? (tipc_sk(sk))->portid : 0;
3572}
3573
3574/**
3575 * tipc_sk_dump - dump TIPC socket
3576 * @sk: tipc sk to be dumped
3577 * @dqueues: bitmask to decide if any socket queue to be dumped?
3578 * - TIPC_DUMP_NONE: don't dump socket queues
3579 * - TIPC_DUMP_SK_SNDQ: dump socket send queue
3580 * - TIPC_DUMP_SK_RCVQ: dump socket rcv queue
3581 * - TIPC_DUMP_SK_BKLGQ: dump socket backlog queue
3582 * - TIPC_DUMP_ALL: dump all the socket queues above
3583 * @buf: returned buffer of dump data in format
3584 */
3585int tipc_sk_dump(struct sock *sk, u16 dqueues, char *buf)
3586{
3587 int i = 0;
3588 size_t sz = (dqueues) ? SK_LMAX : SK_LMIN;
3589 struct tipc_sock *tsk;
3590 struct publication *p;
3591 bool tsk_connected;
3592
3593 if (!sk) {
3594 i += scnprintf(buf, sz, "sk data: (null)\n");
3595 return i;
3596 }
3597
3598 tsk = tipc_sk(sk);
3599 tsk_connected = !tipc_sk_type_connectionless(sk);
3600
3601 i += scnprintf(buf, sz, "sk data: %u", sk->sk_type);
3602 i += scnprintf(buf + i, sz - i, " %d", sk->sk_state);
3603 i += scnprintf(buf + i, sz - i, " %x", tsk_own_node(tsk));
3604 i += scnprintf(buf + i, sz - i, " %u", tsk->portid);
3605 i += scnprintf(buf + i, sz - i, " | %u", tsk_connected);
3606 if (tsk_connected) {
3607 i += scnprintf(buf + i, sz - i, " %x", tsk_peer_node(tsk));
3608 i += scnprintf(buf + i, sz - i, " %u", tsk_peer_port(tsk));
3609 i += scnprintf(buf + i, sz - i, " %u", tsk->conn_type);
3610 i += scnprintf(buf + i, sz - i, " %u", tsk->conn_instance);
3611 }
3612 i += scnprintf(buf + i, sz - i, " | %u", tsk->published);
3613 if (tsk->published) {
3614 p = list_first_entry_or_null(&tsk->publications,
3615 struct publication, binding_sock);
3616 i += scnprintf(buf + i, sz - i, " %u", (p) ? p->type : 0);
3617 i += scnprintf(buf + i, sz - i, " %u", (p) ? p->lower : 0);
3618 i += scnprintf(buf + i, sz - i, " %u", (p) ? p->upper : 0);
3619 }
3620 i += scnprintf(buf + i, sz - i, " | %u", tsk->snd_win);
3621 i += scnprintf(buf + i, sz - i, " %u", tsk->rcv_win);
3622 i += scnprintf(buf + i, sz - i, " %u", tsk->max_pkt);
3623 i += scnprintf(buf + i, sz - i, " %x", tsk->peer_caps);
3624 i += scnprintf(buf + i, sz - i, " %u", tsk->cong_link_cnt);
3625 i += scnprintf(buf + i, sz - i, " %u", tsk->snt_unacked);
3626 i += scnprintf(buf + i, sz - i, " %u", tsk->rcv_unacked);
3627 i += scnprintf(buf + i, sz - i, " %u", atomic_read(&tsk->dupl_rcvcnt));
3628 i += scnprintf(buf + i, sz - i, " %u", sk->sk_shutdown);
3629 i += scnprintf(buf + i, sz - i, " | %d", sk_wmem_alloc_get(sk));
3630 i += scnprintf(buf + i, sz - i, " %d", sk->sk_sndbuf);
3631 i += scnprintf(buf + i, sz - i, " | %d", sk_rmem_alloc_get(sk));
3632 i += scnprintf(buf + i, sz - i, " %d", sk->sk_rcvbuf);
3633 i += scnprintf(buf + i, sz - i, " | %d\n", sk->sk_backlog.len);
3634
3635 if (dqueues & TIPC_DUMP_SK_SNDQ) {
3636 i += scnprintf(buf + i, sz - i, "sk_write_queue: ");
3637 i += tipc_list_dump(&sk->sk_write_queue, false, buf + i);
3638 }
3639
3640 if (dqueues & TIPC_DUMP_SK_RCVQ) {
3641 i += scnprintf(buf + i, sz - i, "sk_receive_queue: ");
3642 i += tipc_list_dump(&sk->sk_receive_queue, false, buf + i);
3643 }
3644
3645 if (dqueues & TIPC_DUMP_SK_BKLGQ) {
3646 i += scnprintf(buf + i, sz - i, "sk_backlog:\n head ");
3647 i += tipc_skb_dump(sk->sk_backlog.head, false, buf + i);
3648 if (sk->sk_backlog.tail != sk->sk_backlog.head) {
3649 i += scnprintf(buf + i, sz - i, " tail ");
3650 i += tipc_skb_dump(sk->sk_backlog.tail, false,
3651 buf + i);
3652 }
3653 }
3654
3655 return i;
3656}
diff --git a/net/tipc/socket.h b/net/tipc/socket.h
index 5e575f205afe..07e36545b696 100644
--- a/net/tipc/socket.h
+++ b/net/tipc/socket.h
@@ -71,4 +71,6 @@ int tipc_nl_sk_walk(struct sk_buff *skb, struct netlink_callback *cb,
71int tipc_dump_start(struct netlink_callback *cb); 71int tipc_dump_start(struct netlink_callback *cb);
72int __tipc_dump_start(struct netlink_callback *cb, struct net *net); 72int __tipc_dump_start(struct netlink_callback *cb, struct net *net);
73int tipc_dump_done(struct netlink_callback *cb); 73int tipc_dump_done(struct netlink_callback *cb);
74u32 tipc_sock_get_portid(struct sock *sk);
75
74#endif 76#endif
diff --git a/net/tipc/trace.c b/net/tipc/trace.c
new file mode 100644
index 000000000000..846196f0e810
--- /dev/null
+++ b/net/tipc/trace.c
@@ -0,0 +1,200 @@
1/*
2 * net/tipc/trace.c: TIPC tracepoints code
3 *
4 * Copyright (c) 2018, Ericsson AB
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the names of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU General Public License ("GPL") version 2 as published by the Free
21 * Software Foundation.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "ASIS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#define CREATE_TRACE_POINTS
37#include "trace.h"
38
39/**
40 * tipc_skb_dump - dump TIPC skb data
41 * @skb: skb to be dumped
42 * @more: dump more?
43 * - false: dump only tipc msg data
44 * - true: dump kernel-related skb data and tipc cb[] array as well
45 * @buf: returned buffer of dump data in format
46 */
47int tipc_skb_dump(struct sk_buff *skb, bool more, char *buf)
48{
49 int i = 0;
50 size_t sz = (more) ? SKB_LMAX : SKB_LMIN;
51 struct tipc_msg *hdr;
52 struct tipc_skb_cb *skbcb;
53
54 if (!skb) {
55 i += scnprintf(buf, sz, "msg: (null)\n");
56 return i;
57 }
58
59 hdr = buf_msg(skb);
60 skbcb = TIPC_SKB_CB(skb);
61
62 /* tipc msg data section */
63 i += scnprintf(buf, sz, "msg: %u", msg_user(hdr));
64 i += scnprintf(buf + i, sz - i, " %u", msg_type(hdr));
65 i += scnprintf(buf + i, sz - i, " %u", msg_hdr_sz(hdr));
66 i += scnprintf(buf + i, sz - i, " %u", msg_data_sz(hdr));
67 i += scnprintf(buf + i, sz - i, " %x", msg_orignode(hdr));
68 i += scnprintf(buf + i, sz - i, " %x", msg_destnode(hdr));
69 i += scnprintf(buf + i, sz - i, " %u", msg_seqno(hdr));
70 i += scnprintf(buf + i, sz - i, " %u", msg_ack(hdr));
71 i += scnprintf(buf + i, sz - i, " %u", msg_bcast_ack(hdr));
72 switch (msg_user(hdr)) {
73 case LINK_PROTOCOL:
74 i += scnprintf(buf + i, sz - i, " %c", msg_net_plane(hdr));
75 i += scnprintf(buf + i, sz - i, " %u", msg_probe(hdr));
76 i += scnprintf(buf + i, sz - i, " %u", msg_peer_stopping(hdr));
77 i += scnprintf(buf + i, sz - i, " %u", msg_session(hdr));
78 i += scnprintf(buf + i, sz - i, " %u", msg_next_sent(hdr));
79 i += scnprintf(buf + i, sz - i, " %u", msg_seq_gap(hdr));
80 i += scnprintf(buf + i, sz - i, " %u", msg_bc_snd_nxt(hdr));
81 i += scnprintf(buf + i, sz - i, " %u", msg_bc_gap(hdr));
82 break;
83 case TIPC_LOW_IMPORTANCE:
84 case TIPC_MEDIUM_IMPORTANCE:
85 case TIPC_HIGH_IMPORTANCE:
86 case TIPC_CRITICAL_IMPORTANCE:
87 case CONN_MANAGER:
88 case SOCK_WAKEUP:
89 i += scnprintf(buf + i, sz - i, " | %u", msg_origport(hdr));
90 i += scnprintf(buf + i, sz - i, " %u", msg_destport(hdr));
91 switch (msg_type(hdr)) {
92 case TIPC_NAMED_MSG:
93 i += scnprintf(buf + i, sz - i, " %u",
94 msg_nametype(hdr));
95 i += scnprintf(buf + i, sz - i, " %u",
96 msg_nameinst(hdr));
97 break;
98 case TIPC_MCAST_MSG:
99 i += scnprintf(buf + i, sz - i, " %u",
100 msg_nametype(hdr));
101 i += scnprintf(buf + i, sz - i, " %u",
102 msg_namelower(hdr));
103 i += scnprintf(buf + i, sz - i, " %u",
104 msg_nameupper(hdr));
105 break;
106 default:
107 break;
108 };
109 i += scnprintf(buf + i, sz - i, " | %u",
110 msg_src_droppable(hdr));
111 i += scnprintf(buf + i, sz - i, " %u",
112 msg_dest_droppable(hdr));
113 i += scnprintf(buf + i, sz - i, " %u", msg_errcode(hdr));
114 i += scnprintf(buf + i, sz - i, " %u", msg_reroute_cnt(hdr));
115 break;
116 default:
117 /* need more? */
118 break;
119 };
120
121 i += scnprintf(buf + i, sz - i, "\n");
122 if (!more)
123 return i;
124
125 /* kernel-related skb data section */
126 i += scnprintf(buf + i, sz - i, "skb: %s",
127 (skb->dev) ? skb->dev->name : "n/a");
128 i += scnprintf(buf + i, sz - i, " %u", skb->len);
129 i += scnprintf(buf + i, sz - i, " %u", skb->data_len);
130 i += scnprintf(buf + i, sz - i, " %u", skb->hdr_len);
131 i += scnprintf(buf + i, sz - i, " %u", skb->truesize);
132 i += scnprintf(buf + i, sz - i, " %u", skb_cloned(skb));
133 i += scnprintf(buf + i, sz - i, " %p", skb->sk);
134 i += scnprintf(buf + i, sz - i, " %u", skb_shinfo(skb)->nr_frags);
135 i += scnprintf(buf + i, sz - i, " %llx",
136 ktime_to_ms(skb_get_ktime(skb)));
137 i += scnprintf(buf + i, sz - i, " %llx\n",
138 ktime_to_ms(skb_hwtstamps(skb)->hwtstamp));
139
140 /* tipc skb cb[] data section */
141 i += scnprintf(buf + i, sz - i, "cb[]: %u", skbcb->bytes_read);
142 i += scnprintf(buf + i, sz - i, " %u", skbcb->orig_member);
143 i += scnprintf(buf + i, sz - i, " %u",
144 jiffies_to_msecs(skbcb->nxt_retr));
145 i += scnprintf(buf + i, sz - i, " %u", skbcb->validated);
146 i += scnprintf(buf + i, sz - i, " %u", skbcb->chain_imp);
147 i += scnprintf(buf + i, sz - i, " %u\n", skbcb->ackers);
148
149 return i;
150}
151
152/**
153 * tipc_list_dump - dump TIPC skb list/queue
154 * @list: list of skbs to be dumped
155 * @more: dump more?
156 * - false: dump only the head & tail skbs
157 * - true: dump the first & last 5 skbs
158 * @buf: returned buffer of dump data in format
159 */
160int tipc_list_dump(struct sk_buff_head *list, bool more, char *buf)
161{
162 int i = 0;
163 size_t sz = (more) ? LIST_LMAX : LIST_LMIN;
164 u32 count, len;
165 struct sk_buff *hskb, *tskb, *skb, *tmp;
166
167 if (!list) {
168 i += scnprintf(buf, sz, "(null)\n");
169 return i;
170 }
171
172 len = skb_queue_len(list);
173 i += scnprintf(buf, sz, "len = %d\n", len);
174
175 if (!len)
176 return i;
177
178 if (!more) {
179 hskb = skb_peek(list);
180 i += scnprintf(buf + i, sz - i, " head ");
181 i += tipc_skb_dump(hskb, false, buf + i);
182 if (len > 1) {
183 tskb = skb_peek_tail(list);
184 i += scnprintf(buf + i, sz - i, " tail ");
185 i += tipc_skb_dump(tskb, false, buf + i);
186 }
187 } else {
188 count = 0;
189 skb_queue_walk_safe(list, skb, tmp) {
190 count++;
191 if (count == 6)
192 i += scnprintf(buf + i, sz - i, " .\n .\n");
193 if (count > 5 && count <= len - 5)
194 continue;
195 i += scnprintf(buf + i, sz - i, " #%d ", count);
196 i += tipc_skb_dump(skb, false, buf + i);
197 }
198 }
199 return i;
200}
diff --git a/net/tipc/trace.h b/net/tipc/trace.h
new file mode 100644
index 000000000000..4c74927df685
--- /dev/null
+++ b/net/tipc/trace.h
@@ -0,0 +1,231 @@
1/*
2 * net/tipc/trace.h: TIPC tracepoints
3 *
4 * Copyright (c) 2018, Ericsson AB
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the names of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU General Public License ("GPL") version 2 as published by the Free
21 * Software Foundation.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "ASIS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#undef TRACE_SYSTEM
37#define TRACE_SYSTEM tipc
38
39#if !defined(_TIPC_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
40#define _TIPC_TRACE_H
41
42#include <linux/tracepoint.h>
43#include "core.h"
44#include "link.h"
45#include "socket.h"
46#include "node.h"
47
48#define SKB_LMIN (100)
49#define SKB_LMAX (SKB_LMIN * 2)
50#define LIST_LMIN (SKB_LMIN * 3)
51#define LIST_LMAX (SKB_LMIN * 11)
52#define SK_LMIN (SKB_LMIN * 2)
53#define SK_LMAX (SKB_LMIN * 11)
54#define LINK_LMIN (SKB_LMIN)
55#define LINK_LMAX (SKB_LMIN * 16)
56#define NODE_LMIN (SKB_LMIN)
57#define NODE_LMAX (SKB_LMIN * 11)
58
59#ifndef __TIPC_TRACE_ENUM
60#define __TIPC_TRACE_ENUM
61enum {
62 TIPC_DUMP_NONE = 0,
63
64 TIPC_DUMP_TRANSMQ = 1,
65 TIPC_DUMP_BACKLOGQ = (1 << 1),
66 TIPC_DUMP_DEFERDQ = (1 << 2),
67 TIPC_DUMP_INPUTQ = (1 << 3),
68 TIPC_DUMP_WAKEUP = (1 << 4),
69
70 TIPC_DUMP_SK_SNDQ = (1 << 8),
71 TIPC_DUMP_SK_RCVQ = (1 << 9),
72 TIPC_DUMP_SK_BKLGQ = (1 << 10),
73 TIPC_DUMP_ALL = 0xffffu
74};
75#endif
76
77int tipc_skb_dump(struct sk_buff *skb, bool more, char *buf);
78int tipc_list_dump(struct sk_buff_head *list, bool more, char *buf);
79int tipc_sk_dump(struct sock *sk, u16 dqueues, char *buf);
80int tipc_link_dump(struct tipc_link *l, u16 dqueues, char *buf);
81int tipc_node_dump(struct tipc_node *n, bool more, char *buf);
82
83DECLARE_EVENT_CLASS(tipc_skb_class,
84
85 TP_PROTO(struct sk_buff *skb, bool more, const char *header),
86
87 TP_ARGS(skb, more, header),
88
89 TP_STRUCT__entry(
90 __string(header, header)
91 __dynamic_array(char, buf, (more) ? SKB_LMAX : SKB_LMIN)
92 ),
93
94 TP_fast_assign(
95 __assign_str(header, header);
96 tipc_skb_dump(skb, more, __get_str(buf));
97 ),
98
99 TP_printk("%s\n%s", __get_str(header), __get_str(buf))
100)
101
102#define DEFINE_SKB_EVENT(name) \
103DEFINE_EVENT(tipc_skb_class, name, \
104 TP_PROTO(struct sk_buff *skb, bool more, const char *header), \
105 TP_ARGS(skb, more, header))
106DEFINE_SKB_EVENT(tipc_skb_dump);
107
108DECLARE_EVENT_CLASS(tipc_list_class,
109
110 TP_PROTO(struct sk_buff_head *list, bool more, const char *header),
111
112 TP_ARGS(list, more, header),
113
114 TP_STRUCT__entry(
115 __string(header, header)
116 __dynamic_array(char, buf, (more) ? LIST_LMAX : LIST_LMIN)
117 ),
118
119 TP_fast_assign(
120 __assign_str(header, header);
121 tipc_list_dump(list, more, __get_str(buf));
122 ),
123
124 TP_printk("%s\n%s", __get_str(header), __get_str(buf))
125);
126
127#define DEFINE_LIST_EVENT(name) \
128DEFINE_EVENT(tipc_list_class, name, \
129 TP_PROTO(struct sk_buff_head *list, bool more, const char *header), \
130 TP_ARGS(list, more, header))
131DEFINE_LIST_EVENT(tipc_list_dump);
132
133DECLARE_EVENT_CLASS(tipc_sk_class,
134
135 TP_PROTO(struct sock *sk, struct sk_buff *skb, u16 dqueues,
136 const char *header),
137
138 TP_ARGS(sk, skb, dqueues, header),
139
140 TP_STRUCT__entry(
141 __string(header, header)
142 __field(u32, portid)
143 __dynamic_array(char, buf, (dqueues) ? SK_LMAX : SK_LMIN)
144 __dynamic_array(char, skb_buf, (skb) ? SKB_LMIN : 1)
145 ),
146
147 TP_fast_assign(
148 __assign_str(header, header);
149 __entry->portid = tipc_sock_get_portid(sk);
150 tipc_sk_dump(sk, dqueues, __get_str(buf));
151 if (skb)
152 tipc_skb_dump(skb, false, __get_str(skb_buf));
153 else
154 *(__get_str(skb_buf)) = '\0';
155 ),
156
157 TP_printk("<%u> %s\n%s%s", __entry->portid, __get_str(header),
158 __get_str(skb_buf), __get_str(buf))
159);
160
161#define DEFINE_SK_EVENT(name) \
162DEFINE_EVENT(tipc_sk_class, name, \
163 TP_PROTO(struct sock *sk, struct sk_buff *skb, u16 dqueues, \
164 const char *header), \
165 TP_ARGS(sk, skb, dqueues, header))
166DEFINE_SK_EVENT(tipc_sk_dump);
167
168DECLARE_EVENT_CLASS(tipc_link_class,
169
170 TP_PROTO(struct tipc_link *l, u16 dqueues, const char *header),
171
172 TP_ARGS(l, dqueues, header),
173
174 TP_STRUCT__entry(
175 __string(header, header)
176 __array(char, name, TIPC_MAX_LINK_NAME)
177 __dynamic_array(char, buf, (dqueues) ? LINK_LMAX : LINK_LMIN)
178 ),
179
180 TP_fast_assign(
181 __assign_str(header, header);
182 tipc_link_name_ext(l, __entry->name);
183 tipc_link_dump(l, dqueues, __get_str(buf));
184 ),
185
186 TP_printk("<%s> %s\n%s", __entry->name, __get_str(header),
187 __get_str(buf))
188);
189
190#define DEFINE_LINK_EVENT(name) \
191DEFINE_EVENT(tipc_link_class, name, \
192 TP_PROTO(struct tipc_link *l, u16 dqueues, const char *header), \
193 TP_ARGS(l, dqueues, header))
194DEFINE_LINK_EVENT(tipc_link_dump);
195
196DECLARE_EVENT_CLASS(tipc_node_class,
197
198 TP_PROTO(struct tipc_node *n, bool more, const char *header),
199
200 TP_ARGS(n, more, header),
201
202 TP_STRUCT__entry(
203 __string(header, header)
204 __field(u32, addr)
205 __dynamic_array(char, buf, (more) ? NODE_LMAX : NODE_LMIN)
206 ),
207
208 TP_fast_assign(
209 __assign_str(header, header);
210 __entry->addr = tipc_node_get_addr(n);
211 tipc_node_dump(n, more, __get_str(buf));
212 ),
213
214 TP_printk("<%x> %s\n%s", __entry->addr, __get_str(header),
215 __get_str(buf))
216);
217
218#define DEFINE_NODE_EVENT(name) \
219DEFINE_EVENT(tipc_node_class, name, \
220 TP_PROTO(struct tipc_node *n, bool more, const char *header), \
221 TP_ARGS(n, more, header))
222DEFINE_NODE_EVENT(tipc_node_dump);
223
224#endif /* _TIPC_TRACE_H */
225
226/* This part must be outside protection */
227#undef TRACE_INCLUDE_PATH
228#define TRACE_INCLUDE_PATH .
229#undef TRACE_INCLUDE_FILE
230#define TRACE_INCLUDE_FILE trace
231#include <trace/define_trace.h>