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