Merge branch 'linux-linaro-lsk-v4.4-android' of git://git.linaro.org/kernel/linux...
[firefly-linux-kernel-4.4.55.git] / net / netfilter / xt_qtaguid_print.c
1 /*
2  * Pretty printing Support for iptables xt_qtaguid module.
3  *
4  * (C) 2011 Google, Inc
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 /*
12  * Most of the functions in this file just waste time if DEBUG is not defined.
13  * The matching xt_qtaguid_print.h will static inline empty funcs if the needed
14  * debug flags ore not defined.
15  * Those funcs that fail to allocate memory will panic as there is no need to
16  * hobble allong just pretending to do the requested work.
17  */
18
19 #define DEBUG
20
21 #include <linux/fs.h>
22 #include <linux/gfp.h>
23 #include <linux/net.h>
24 #include <linux/rbtree.h>
25 #include <linux/slab.h>
26 #include <linux/spinlock_types.h>
27
28
29 #include "xt_qtaguid_internal.h"
30 #include "xt_qtaguid_print.h"
31
32 #ifdef DDEBUG
33
34 static void _bug_on_err_or_null(void *ptr)
35 {
36         if (IS_ERR_OR_NULL(ptr)) {
37                 pr_err("qtaguid: kmalloc failed\n");
38                 BUG();
39         }
40 }
41
42 char *pp_tag_t(tag_t *tag)
43 {
44         char *res;
45
46         if (!tag)
47                 res = kasprintf(GFP_ATOMIC, "tag_t@null{}");
48         else
49                 res = kasprintf(GFP_ATOMIC,
50                                 "tag_t@%p{tag=0x%llx, uid=%u}",
51                                 tag, *tag, get_uid_from_tag(*tag));
52         _bug_on_err_or_null(res);
53         return res;
54 }
55
56 char *pp_data_counters(struct data_counters *dc, bool showValues)
57 {
58         char *res;
59
60         if (!dc)
61                 res = kasprintf(GFP_ATOMIC, "data_counters@null{}");
62         else if (showValues)
63                 res = kasprintf(
64                         GFP_ATOMIC, "data_counters@%p{"
65                         "set0{"
66                         "rx{"
67                         "tcp{b=%llu, p=%llu}, "
68                         "udp{b=%llu, p=%llu},"
69                         "other{b=%llu, p=%llu}}, "
70                         "tx{"
71                         "tcp{b=%llu, p=%llu}, "
72                         "udp{b=%llu, p=%llu},"
73                         "other{b=%llu, p=%llu}}}, "
74                         "set1{"
75                         "rx{"
76                         "tcp{b=%llu, p=%llu}, "
77                         "udp{b=%llu, p=%llu},"
78                         "other{b=%llu, p=%llu}}, "
79                         "tx{"
80                         "tcp{b=%llu, p=%llu}, "
81                         "udp{b=%llu, p=%llu},"
82                         "other{b=%llu, p=%llu}}}}",
83                         dc,
84                         dc->bpc[0][IFS_RX][IFS_TCP].bytes,
85                         dc->bpc[0][IFS_RX][IFS_TCP].packets,
86                         dc->bpc[0][IFS_RX][IFS_UDP].bytes,
87                         dc->bpc[0][IFS_RX][IFS_UDP].packets,
88                         dc->bpc[0][IFS_RX][IFS_PROTO_OTHER].bytes,
89                         dc->bpc[0][IFS_RX][IFS_PROTO_OTHER].packets,
90                         dc->bpc[0][IFS_TX][IFS_TCP].bytes,
91                         dc->bpc[0][IFS_TX][IFS_TCP].packets,
92                         dc->bpc[0][IFS_TX][IFS_UDP].bytes,
93                         dc->bpc[0][IFS_TX][IFS_UDP].packets,
94                         dc->bpc[0][IFS_TX][IFS_PROTO_OTHER].bytes,
95                         dc->bpc[0][IFS_TX][IFS_PROTO_OTHER].packets,
96                         dc->bpc[1][IFS_RX][IFS_TCP].bytes,
97                         dc->bpc[1][IFS_RX][IFS_TCP].packets,
98                         dc->bpc[1][IFS_RX][IFS_UDP].bytes,
99                         dc->bpc[1][IFS_RX][IFS_UDP].packets,
100                         dc->bpc[1][IFS_RX][IFS_PROTO_OTHER].bytes,
101                         dc->bpc[1][IFS_RX][IFS_PROTO_OTHER].packets,
102                         dc->bpc[1][IFS_TX][IFS_TCP].bytes,
103                         dc->bpc[1][IFS_TX][IFS_TCP].packets,
104                         dc->bpc[1][IFS_TX][IFS_UDP].bytes,
105                         dc->bpc[1][IFS_TX][IFS_UDP].packets,
106                         dc->bpc[1][IFS_TX][IFS_PROTO_OTHER].bytes,
107                         dc->bpc[1][IFS_TX][IFS_PROTO_OTHER].packets);
108         else
109                 res = kasprintf(GFP_ATOMIC, "data_counters@%p{...}", dc);
110         _bug_on_err_or_null(res);
111         return res;
112 }
113
114 char *pp_tag_node(struct tag_node *tn)
115 {
116         char *tag_str;
117         char *res;
118
119         if (!tn) {
120                 res = kasprintf(GFP_ATOMIC, "tag_node@null{}");
121                 _bug_on_err_or_null(res);
122                 return res;
123         }
124         tag_str = pp_tag_t(&tn->tag);
125         res = kasprintf(GFP_ATOMIC,
126                         "tag_node@%p{tag=%s}",
127                         tn, tag_str);
128         _bug_on_err_or_null(res);
129         kfree(tag_str);
130         return res;
131 }
132
133 char *pp_tag_ref(struct tag_ref *tr)
134 {
135         char *tn_str;
136         char *res;
137
138         if (!tr) {
139                 res = kasprintf(GFP_ATOMIC, "tag_ref@null{}");
140                 _bug_on_err_or_null(res);
141                 return res;
142         }
143         tn_str = pp_tag_node(&tr->tn);
144         res = kasprintf(GFP_ATOMIC,
145                         "tag_ref@%p{%s, num_sock_tags=%d}",
146                         tr, tn_str, tr->num_sock_tags);
147         _bug_on_err_or_null(res);
148         kfree(tn_str);
149         return res;
150 }
151
152 char *pp_tag_stat(struct tag_stat *ts)
153 {
154         char *tn_str;
155         char *counters_str;
156         char *parent_counters_str;
157         char *res;
158
159         if (!ts) {
160                 res = kasprintf(GFP_ATOMIC, "tag_stat@null{}");
161                 _bug_on_err_or_null(res);
162                 return res;
163         }
164         tn_str = pp_tag_node(&ts->tn);
165         counters_str = pp_data_counters(&ts->counters, true);
166         parent_counters_str = pp_data_counters(ts->parent_counters, false);
167         res = kasprintf(GFP_ATOMIC,
168                         "tag_stat@%p{%s, counters=%s, parent_counters=%s}",
169                         ts, tn_str, counters_str, parent_counters_str);
170         _bug_on_err_or_null(res);
171         kfree(tn_str);
172         kfree(counters_str);
173         kfree(parent_counters_str);
174         return res;
175 }
176
177 char *pp_iface_stat(struct iface_stat *is)
178 {
179         char *res;
180         if (!is) {
181                 res = kasprintf(GFP_ATOMIC, "iface_stat@null{}");
182         } else {
183                 struct data_counters *cnts = &is->totals_via_skb;
184                 res = kasprintf(GFP_ATOMIC, "iface_stat@%p{"
185                                 "list=list_head{...}, "
186                                 "ifname=%s, "
187                                 "total_dev={rx={bytes=%llu, "
188                                 "packets=%llu}, "
189                                 "tx={bytes=%llu, "
190                                 "packets=%llu}}, "
191                                 "total_skb={rx={bytes=%llu, "
192                                 "packets=%llu}, "
193                                 "tx={bytes=%llu, "
194                                 "packets=%llu}}, "
195                                 "last_known_valid=%d, "
196                                 "last_known={rx={bytes=%llu, "
197                                 "packets=%llu}, "
198                                 "tx={bytes=%llu, "
199                                 "packets=%llu}}, "
200                                 "active=%d, "
201                                 "net_dev=%p, "
202                                 "proc_ptr=%p, "
203                                 "tag_stat_tree=rb_root{...}}",
204                                 is,
205                                 is->ifname,
206                                 is->totals_via_dev[IFS_RX].bytes,
207                                 is->totals_via_dev[IFS_RX].packets,
208                                 is->totals_via_dev[IFS_TX].bytes,
209                                 is->totals_via_dev[IFS_TX].packets,
210                                 dc_sum_bytes(cnts, 0, IFS_RX),
211                                 dc_sum_packets(cnts, 0, IFS_RX),
212                                 dc_sum_bytes(cnts, 0, IFS_TX),
213                                 dc_sum_packets(cnts, 0, IFS_TX),
214                                 is->last_known_valid,
215                                 is->last_known[IFS_RX].bytes,
216                                 is->last_known[IFS_RX].packets,
217                                 is->last_known[IFS_TX].bytes,
218                                 is->last_known[IFS_TX].packets,
219                                 is->active,
220                                 is->net_dev,
221                                 is->proc_ptr);
222         }
223         _bug_on_err_or_null(res);
224         return res;
225 }
226
227 char *pp_sock_tag(struct sock_tag *st)
228 {
229         char *tag_str;
230         char *res;
231
232         if (!st) {
233                 res = kasprintf(GFP_ATOMIC, "sock_tag@null{}");
234                 _bug_on_err_or_null(res);
235                 return res;
236         }
237         tag_str = pp_tag_t(&st->tag);
238         res = kasprintf(GFP_ATOMIC, "sock_tag@%p{"
239                         "sock_node=rb_node{...}, "
240                         "sk=%p socket=%p (f_count=%lu), list=list_head{...}, "
241                         "pid=%u, tag=%s}",
242                         st, st->sk, st->socket, atomic_long_read(
243                                 &st->socket->file->f_count),
244                         st->pid, tag_str);
245         _bug_on_err_or_null(res);
246         kfree(tag_str);
247         return res;
248 }
249
250 char *pp_uid_tag_data(struct uid_tag_data *utd)
251 {
252         char *res;
253
254         if (!utd)
255                 res = kasprintf(GFP_ATOMIC, "uid_tag_data@null{}");
256         else
257                 res = kasprintf(GFP_ATOMIC, "uid_tag_data@%p{"
258                                 "uid=%u, num_active_acct_tags=%d, "
259                                 "num_pqd=%d, "
260                                 "tag_node_tree=rb_root{...}, "
261                                 "proc_qtu_data_tree=rb_root{...}}",
262                                 utd, utd->uid,
263                                 utd->num_active_tags, utd->num_pqd);
264         _bug_on_err_or_null(res);
265         return res;
266 }
267
268 char *pp_proc_qtu_data(struct proc_qtu_data *pqd)
269 {
270         char *parent_tag_data_str;
271         char *res;
272
273         if (!pqd) {
274                 res = kasprintf(GFP_ATOMIC, "proc_qtu_data@null{}");
275                 _bug_on_err_or_null(res);
276                 return res;
277         }
278         parent_tag_data_str = pp_uid_tag_data(pqd->parent_tag_data);
279         res = kasprintf(GFP_ATOMIC, "proc_qtu_data@%p{"
280                         "node=rb_node{...}, pid=%u, "
281                         "parent_tag_data=%s, "
282                         "sock_tag_list=list_head{...}}",
283                         pqd, pqd->pid, parent_tag_data_str
284                 );
285         _bug_on_err_or_null(res);
286         kfree(parent_tag_data_str);
287         return res;
288 }
289
290 /*------------------------------------------*/
291 void prdebug_sock_tag_tree(int indent_level,
292                            struct rb_root *sock_tag_tree)
293 {
294         struct rb_node *node;
295         struct sock_tag *sock_tag_entry;
296         char *str;
297
298         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
299                 return;
300
301         if (RB_EMPTY_ROOT(sock_tag_tree)) {
302                 str = "sock_tag_tree=rb_root{}";
303                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
304                 return;
305         }
306
307         str = "sock_tag_tree=rb_root{";
308         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
309         indent_level++;
310         for (node = rb_first(sock_tag_tree);
311              node;
312              node = rb_next(node)) {
313                 sock_tag_entry = rb_entry(node, struct sock_tag, sock_node);
314                 str = pp_sock_tag(sock_tag_entry);
315                 pr_debug("%*d: %s,\n", indent_level*2, indent_level, str);
316                 kfree(str);
317         }
318         indent_level--;
319         str = "}";
320         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
321 }
322
323 void prdebug_sock_tag_list(int indent_level,
324                            struct list_head *sock_tag_list)
325 {
326         struct sock_tag *sock_tag_entry;
327         char *str;
328
329         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
330                 return;
331
332         if (list_empty(sock_tag_list)) {
333                 str = "sock_tag_list=list_head{}";
334                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
335                 return;
336         }
337
338         str = "sock_tag_list=list_head{";
339         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
340         indent_level++;
341         list_for_each_entry(sock_tag_entry, sock_tag_list, list) {
342                 str = pp_sock_tag(sock_tag_entry);
343                 pr_debug("%*d: %s,\n", indent_level*2, indent_level, str);
344                 kfree(str);
345         }
346         indent_level--;
347         str = "}";
348         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
349 }
350
351 void prdebug_proc_qtu_data_tree(int indent_level,
352                                 struct rb_root *proc_qtu_data_tree)
353 {
354         char *str;
355         struct rb_node *node;
356         struct proc_qtu_data *proc_qtu_data_entry;
357
358         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
359                 return;
360
361         if (RB_EMPTY_ROOT(proc_qtu_data_tree)) {
362                 str = "proc_qtu_data_tree=rb_root{}";
363                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
364                 return;
365         }
366
367         str = "proc_qtu_data_tree=rb_root{";
368         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
369         indent_level++;
370         for (node = rb_first(proc_qtu_data_tree);
371              node;
372              node = rb_next(node)) {
373                 proc_qtu_data_entry = rb_entry(node,
374                                                struct proc_qtu_data,
375                                                node);
376                 str = pp_proc_qtu_data(proc_qtu_data_entry);
377                 pr_debug("%*d: %s,\n", indent_level*2, indent_level,
378                          str);
379                 kfree(str);
380                 indent_level++;
381                 prdebug_sock_tag_list(indent_level,
382                                       &proc_qtu_data_entry->sock_tag_list);
383                 indent_level--;
384
385         }
386         indent_level--;
387         str = "}";
388         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
389 }
390
391 void prdebug_tag_ref_tree(int indent_level, struct rb_root *tag_ref_tree)
392 {
393         char *str;
394         struct rb_node *node;
395         struct tag_ref *tag_ref_entry;
396
397         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
398                 return;
399
400         if (RB_EMPTY_ROOT(tag_ref_tree)) {
401                 str = "tag_ref_tree{}";
402                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
403                 return;
404         }
405
406         str = "tag_ref_tree{";
407         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
408         indent_level++;
409         for (node = rb_first(tag_ref_tree);
410              node;
411              node = rb_next(node)) {
412                 tag_ref_entry = rb_entry(node,
413                                          struct tag_ref,
414                                          tn.node);
415                 str = pp_tag_ref(tag_ref_entry);
416                 pr_debug("%*d: %s,\n", indent_level*2, indent_level,
417                          str);
418                 kfree(str);
419         }
420         indent_level--;
421         str = "}";
422         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
423 }
424
425 void prdebug_uid_tag_data_tree(int indent_level,
426                                struct rb_root *uid_tag_data_tree)
427 {
428         char *str;
429         struct rb_node *node;
430         struct uid_tag_data *uid_tag_data_entry;
431
432         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
433                 return;
434
435         if (RB_EMPTY_ROOT(uid_tag_data_tree)) {
436                 str = "uid_tag_data_tree=rb_root{}";
437                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
438                 return;
439         }
440
441         str = "uid_tag_data_tree=rb_root{";
442         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
443         indent_level++;
444         for (node = rb_first(uid_tag_data_tree);
445              node;
446              node = rb_next(node)) {
447                 uid_tag_data_entry = rb_entry(node, struct uid_tag_data,
448                                               node);
449                 str = pp_uid_tag_data(uid_tag_data_entry);
450                 pr_debug("%*d: %s,\n", indent_level*2, indent_level, str);
451                 kfree(str);
452                 if (!RB_EMPTY_ROOT(&uid_tag_data_entry->tag_ref_tree)) {
453                         indent_level++;
454                         prdebug_tag_ref_tree(indent_level,
455                                              &uid_tag_data_entry->tag_ref_tree);
456                         indent_level--;
457                 }
458         }
459         indent_level--;
460         str = "}";
461         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
462 }
463
464 void prdebug_tag_stat_tree(int indent_level,
465                                   struct rb_root *tag_stat_tree)
466 {
467         char *str;
468         struct rb_node *node;
469         struct tag_stat *ts_entry;
470
471         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
472                 return;
473
474         if (RB_EMPTY_ROOT(tag_stat_tree)) {
475                 str = "tag_stat_tree{}";
476                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
477                 return;
478         }
479
480         str = "tag_stat_tree{";
481         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
482         indent_level++;
483         for (node = rb_first(tag_stat_tree);
484              node;
485              node = rb_next(node)) {
486                 ts_entry = rb_entry(node, struct tag_stat, tn.node);
487                 str = pp_tag_stat(ts_entry);
488                 pr_debug("%*d: %s\n", indent_level*2, indent_level,
489                          str);
490                 kfree(str);
491         }
492         indent_level--;
493         str = "}";
494         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
495 }
496
497 void prdebug_iface_stat_list(int indent_level,
498                              struct list_head *iface_stat_list)
499 {
500         char *str;
501         struct iface_stat *iface_entry;
502
503         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
504                 return;
505
506         if (list_empty(iface_stat_list)) {
507                 str = "iface_stat_list=list_head{}";
508                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
509                 return;
510         }
511
512         str = "iface_stat_list=list_head{";
513         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
514         indent_level++;
515         list_for_each_entry(iface_entry, iface_stat_list, list) {
516                 str = pp_iface_stat(iface_entry);
517                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
518                 kfree(str);
519
520                 spin_lock_bh(&iface_entry->tag_stat_list_lock);
521                 if (!RB_EMPTY_ROOT(&iface_entry->tag_stat_tree)) {
522                         indent_level++;
523                         prdebug_tag_stat_tree(indent_level,
524                                               &iface_entry->tag_stat_tree);
525                         indent_level--;
526                 }
527                 spin_unlock_bh(&iface_entry->tag_stat_list_lock);
528         }
529         indent_level--;
530         str = "}";
531         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
532 }
533
534 #endif  /* ifdef DDEBUG */
535 /*------------------------------------------*/
536 static const char * const netdev_event_strings[] = {
537         "netdev_unknown",
538         "NETDEV_UP",
539         "NETDEV_DOWN",
540         "NETDEV_REBOOT",
541         "NETDEV_CHANGE",
542         "NETDEV_REGISTER",
543         "NETDEV_UNREGISTER",
544         "NETDEV_CHANGEMTU",
545         "NETDEV_CHANGEADDR",
546         "NETDEV_GOING_DOWN",
547         "NETDEV_CHANGENAME",
548         "NETDEV_FEAT_CHANGE",
549         "NETDEV_BONDING_FAILOVER",
550         "NETDEV_PRE_UP",
551         "NETDEV_PRE_TYPE_CHANGE",
552         "NETDEV_POST_TYPE_CHANGE",
553         "NETDEV_POST_INIT",
554         "NETDEV_UNREGISTER_BATCH",
555         "NETDEV_RELEASE",
556         "NETDEV_NOTIFY_PEERS",
557         "NETDEV_JOIN",
558 };
559
560 const char *netdev_evt_str(int netdev_event)
561 {
562         if (netdev_event < 0
563             || netdev_event >= ARRAY_SIZE(netdev_event_strings))
564                 return "bad event num";
565         return netdev_event_strings[netdev_event];
566 }