Merge remote-tracking branch 'origin/develop-3.0' into develop-3.0-jb
[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                 res = kasprintf(GFP_ATOMIC, "iface_stat@%p{"
184                                 "list=list_head{...}, "
185                                 "ifname=%s, "
186                                 "total_dev={rx={bytes=%llu, "
187                                 "packets=%llu}, "
188                                 "tx={bytes=%llu, "
189                                 "packets=%llu}}, "
190                                 "total_skb={rx={bytes=%llu, "
191                                 "packets=%llu}, "
192                                 "tx={bytes=%llu, "
193                                 "packets=%llu}}, "
194                                 "last_known_valid=%d, "
195                                 "last_known={rx={bytes=%llu, "
196                                 "packets=%llu}, "
197                                 "tx={bytes=%llu, "
198                                 "packets=%llu}}, "
199                                 "active=%d, "
200                                 "net_dev=%p, "
201                                 "proc_ptr=%p, "
202                                 "tag_stat_tree=rb_root{...}}",
203                                 is,
204                                 is->ifname,
205                                 is->totals_via_dev[IFS_RX].bytes,
206                                 is->totals_via_dev[IFS_RX].packets,
207                                 is->totals_via_dev[IFS_TX].bytes,
208                                 is->totals_via_dev[IFS_TX].packets,
209                                 is->totals_via_skb[IFS_RX].bytes,
210                                 is->totals_via_skb[IFS_RX].packets,
211                                 is->totals_via_skb[IFS_TX].bytes,
212                                 is->totals_via_skb[IFS_TX].packets,
213                                 is->last_known_valid,
214                                 is->last_known[IFS_RX].bytes,
215                                 is->last_known[IFS_RX].packets,
216                                 is->last_known[IFS_TX].bytes,
217                                 is->last_known[IFS_TX].packets,
218                                 is->active,
219                                 is->net_dev,
220                                 is->proc_ptr);
221         _bug_on_err_or_null(res);
222         return res;
223 }
224
225 char *pp_sock_tag(struct sock_tag *st)
226 {
227         char *tag_str;
228         char *res;
229
230         if (!st) {
231                 res = kasprintf(GFP_ATOMIC, "sock_tag@null{}");
232                 _bug_on_err_or_null(res);
233                 return res;
234         }
235         tag_str = pp_tag_t(&st->tag);
236         res = kasprintf(GFP_ATOMIC, "sock_tag@%p{"
237                         "sock_node=rb_node{...}, "
238                         "sk=%p socket=%p (f_count=%lu), list=list_head{...}, "
239                         "pid=%u, tag=%s}",
240                         st, st->sk, st->socket, atomic_long_read(
241                                 &st->socket->file->f_count),
242                         st->pid, tag_str);
243         _bug_on_err_or_null(res);
244         kfree(tag_str);
245         return res;
246 }
247
248 char *pp_uid_tag_data(struct uid_tag_data *utd)
249 {
250         char *res;
251
252         if (!utd)
253                 res = kasprintf(GFP_ATOMIC, "uid_tag_data@null{}");
254         else
255                 res = kasprintf(GFP_ATOMIC, "uid_tag_data@%p{"
256                                 "uid=%u, num_active_acct_tags=%d, "
257                                 "num_pqd=%d, "
258                                 "tag_node_tree=rb_root{...}, "
259                                 "proc_qtu_data_tree=rb_root{...}}",
260                                 utd, utd->uid,
261                                 utd->num_active_tags, utd->num_pqd);
262         _bug_on_err_or_null(res);
263         return res;
264 }
265
266 char *pp_proc_qtu_data(struct proc_qtu_data *pqd)
267 {
268         char *parent_tag_data_str;
269         char *res;
270
271         if (!pqd) {
272                 res = kasprintf(GFP_ATOMIC, "proc_qtu_data@null{}");
273                 _bug_on_err_or_null(res);
274                 return res;
275         }
276         parent_tag_data_str = pp_uid_tag_data(pqd->parent_tag_data);
277         res = kasprintf(GFP_ATOMIC, "proc_qtu_data@%p{"
278                         "node=rb_node{...}, pid=%u, "
279                         "parent_tag_data=%s, "
280                         "sock_tag_list=list_head{...}}",
281                         pqd, pqd->pid, parent_tag_data_str
282                 );
283         _bug_on_err_or_null(res);
284         kfree(parent_tag_data_str);
285         return res;
286 }
287
288 /*------------------------------------------*/
289 void prdebug_sock_tag_tree(int indent_level,
290                            struct rb_root *sock_tag_tree)
291 {
292         struct rb_node *node;
293         struct sock_tag *sock_tag_entry;
294         char *str;
295
296         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
297                 return;
298
299         if (RB_EMPTY_ROOT(sock_tag_tree)) {
300                 str = "sock_tag_tree=rb_root{}";
301                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
302                 return;
303         }
304
305         str = "sock_tag_tree=rb_root{";
306         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
307         indent_level++;
308         for (node = rb_first(sock_tag_tree);
309              node;
310              node = rb_next(node)) {
311                 sock_tag_entry = rb_entry(node, struct sock_tag, sock_node);
312                 str = pp_sock_tag(sock_tag_entry);
313                 pr_debug("%*d: %s,\n", indent_level*2, indent_level, str);
314                 kfree(str);
315         }
316         indent_level--;
317         str = "}";
318         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
319 }
320
321 void prdebug_sock_tag_list(int indent_level,
322                            struct list_head *sock_tag_list)
323 {
324         struct sock_tag *sock_tag_entry;
325         char *str;
326
327         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
328                 return;
329
330         if (list_empty(sock_tag_list)) {
331                 str = "sock_tag_list=list_head{}";
332                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
333                 return;
334         }
335
336         str = "sock_tag_list=list_head{";
337         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
338         indent_level++;
339         list_for_each_entry(sock_tag_entry, sock_tag_list, list) {
340                 str = pp_sock_tag(sock_tag_entry);
341                 pr_debug("%*d: %s,\n", indent_level*2, indent_level, str);
342                 kfree(str);
343         }
344         indent_level--;
345         str = "}";
346         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
347 }
348
349 void prdebug_proc_qtu_data_tree(int indent_level,
350                                 struct rb_root *proc_qtu_data_tree)
351 {
352         char *str;
353         struct rb_node *node;
354         struct proc_qtu_data *proc_qtu_data_entry;
355
356         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
357                 return;
358
359         if (RB_EMPTY_ROOT(proc_qtu_data_tree)) {
360                 str = "proc_qtu_data_tree=rb_root{}";
361                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
362                 return;
363         }
364
365         str = "proc_qtu_data_tree=rb_root{";
366         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
367         indent_level++;
368         for (node = rb_first(proc_qtu_data_tree);
369              node;
370              node = rb_next(node)) {
371                 proc_qtu_data_entry = rb_entry(node,
372                                                struct proc_qtu_data,
373                                                node);
374                 str = pp_proc_qtu_data(proc_qtu_data_entry);
375                 pr_debug("%*d: %s,\n", indent_level*2, indent_level,
376                          str);
377                 kfree(str);
378                 indent_level++;
379                 prdebug_sock_tag_list(indent_level,
380                                       &proc_qtu_data_entry->sock_tag_list);
381                 indent_level--;
382
383         }
384         indent_level--;
385         str = "}";
386         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
387 }
388
389 void prdebug_tag_ref_tree(int indent_level, struct rb_root *tag_ref_tree)
390 {
391         char *str;
392         struct rb_node *node;
393         struct tag_ref *tag_ref_entry;
394
395         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
396                 return;
397
398         if (RB_EMPTY_ROOT(tag_ref_tree)) {
399                 str = "tag_ref_tree{}";
400                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
401                 return;
402         }
403
404         str = "tag_ref_tree{";
405         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
406         indent_level++;
407         for (node = rb_first(tag_ref_tree);
408              node;
409              node = rb_next(node)) {
410                 tag_ref_entry = rb_entry(node,
411                                          struct tag_ref,
412                                          tn.node);
413                 str = pp_tag_ref(tag_ref_entry);
414                 pr_debug("%*d: %s,\n", indent_level*2, indent_level,
415                          str);
416                 kfree(str);
417         }
418         indent_level--;
419         str = "}";
420         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
421 }
422
423 void prdebug_uid_tag_data_tree(int indent_level,
424                                struct rb_root *uid_tag_data_tree)
425 {
426         char *str;
427         struct rb_node *node;
428         struct uid_tag_data *uid_tag_data_entry;
429
430         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
431                 return;
432
433         if (RB_EMPTY_ROOT(uid_tag_data_tree)) {
434                 str = "uid_tag_data_tree=rb_root{}";
435                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
436                 return;
437         }
438
439         str = "uid_tag_data_tree=rb_root{";
440         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
441         indent_level++;
442         for (node = rb_first(uid_tag_data_tree);
443              node;
444              node = rb_next(node)) {
445                 uid_tag_data_entry = rb_entry(node, struct uid_tag_data,
446                                               node);
447                 str = pp_uid_tag_data(uid_tag_data_entry);
448                 pr_debug("%*d: %s,\n", indent_level*2, indent_level, str);
449                 kfree(str);
450                 if (!RB_EMPTY_ROOT(&uid_tag_data_entry->tag_ref_tree)) {
451                         indent_level++;
452                         prdebug_tag_ref_tree(indent_level,
453                                              &uid_tag_data_entry->tag_ref_tree);
454                         indent_level--;
455                 }
456         }
457         indent_level--;
458         str = "}";
459         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
460 }
461
462 void prdebug_tag_stat_tree(int indent_level,
463                                   struct rb_root *tag_stat_tree)
464 {
465         char *str;
466         struct rb_node *node;
467         struct tag_stat *ts_entry;
468
469         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
470                 return;
471
472         if (RB_EMPTY_ROOT(tag_stat_tree)) {
473                 str = "tag_stat_tree{}";
474                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
475                 return;
476         }
477
478         str = "tag_stat_tree{";
479         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
480         indent_level++;
481         for (node = rb_first(tag_stat_tree);
482              node;
483              node = rb_next(node)) {
484                 ts_entry = rb_entry(node, struct tag_stat, tn.node);
485                 str = pp_tag_stat(ts_entry);
486                 pr_debug("%*d: %s\n", indent_level*2, indent_level,
487                          str);
488                 kfree(str);
489         }
490         indent_level--;
491         str = "}";
492         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
493 }
494
495 void prdebug_iface_stat_list(int indent_level,
496                              struct list_head *iface_stat_list)
497 {
498         char *str;
499         struct iface_stat *iface_entry;
500
501         if (!unlikely(qtaguid_debug_mask & DDEBUG_MASK))
502                 return;
503
504         if (list_empty(iface_stat_list)) {
505                 str = "iface_stat_list=list_head{}";
506                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
507                 return;
508         }
509
510         str = "iface_stat_list=list_head{";
511         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
512         indent_level++;
513         list_for_each_entry(iface_entry, iface_stat_list, list) {
514                 str = pp_iface_stat(iface_entry);
515                 pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
516                 kfree(str);
517
518                 spin_lock_bh(&iface_entry->tag_stat_list_lock);
519                 if (!RB_EMPTY_ROOT(&iface_entry->tag_stat_tree)) {
520                         indent_level++;
521                         prdebug_tag_stat_tree(indent_level,
522                                               &iface_entry->tag_stat_tree);
523                         indent_level--;
524                 }
525                 spin_unlock_bh(&iface_entry->tag_stat_list_lock);
526         }
527         indent_level--;
528         str = "}";
529         pr_debug("%*d: %s\n", indent_level*2, indent_level, str);
530 }
531
532 #endif  /* ifdef DDEBUG */
533 /*------------------------------------------*/
534 static const char * const netdev_event_strings[] = {
535         "netdev_unknown",
536         "NETDEV_UP",
537         "NETDEV_DOWN",
538         "NETDEV_REBOOT",
539         "NETDEV_CHANGE",
540         "NETDEV_REGISTER",
541         "NETDEV_UNREGISTER",
542         "NETDEV_CHANGEMTU",
543         "NETDEV_CHANGEADDR",
544         "NETDEV_GOING_DOWN",
545         "NETDEV_CHANGENAME",
546         "NETDEV_FEAT_CHANGE",
547         "NETDEV_BONDING_FAILOVER",
548         "NETDEV_PRE_UP",
549         "NETDEV_PRE_TYPE_CHANGE",
550         "NETDEV_POST_TYPE_CHANGE",
551         "NETDEV_POST_INIT",
552         "NETDEV_UNREGISTER_BATCH",
553         "NETDEV_RELEASE",
554         "NETDEV_NOTIFY_PEERS",
555         "NETDEV_JOIN",
556 };
557
558 const char *netdev_evt_str(int netdev_event)
559 {
560         if (netdev_event < 0
561             || netdev_event >= ARRAY_SIZE(netdev_event_strings))
562                 return "bad event num";
563         return netdev_event_strings[netdev_event];
564 }