netfilter: xt_qtaguid: 1st pass at tracking tag based data resources
[linux-2.6.git] / net / netfilter / xt_qtaguid_internal.h
1 /*
2  * Kernel iptables module to track stats for packets based on user tags.
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 #ifndef __XT_QTAGUID_INTERNAL_H__
11 #define __XT_QTAGUID_INTERNAL_H__
12
13 #include <linux/types.h>
14 #include <linux/rbtree.h>
15 #include <linux/spinlock_types.h>
16 #include <linux/workqueue.h>
17
18 /* Define/comment out these *DEBUG to compile in/out the pr_debug calls. */
19 /* Iface handling */
20 #define IDEBUG
21 /* Iptable Matching. Per packet. */
22 #define MDEBUG
23 /* Red-black tree handling. Per packet. */
24 #define RDEBUG
25 /* procfs ctrl/stats handling */
26 #define CDEBUG
27 /* dev and resource tracking */
28 #define DDEBUG
29
30 /* E.g (IDEBUG_MASK | CDEBUG_MASK | DDEBUG_MASK) */
31 #define DEFAULT_DEBUG_MASK 0
32
33
34 #define IDEBUG_MASK (1<<0)
35 #define MDEBUG_MASK (1<<1)
36 #define RDEBUG_MASK (1<<2)
37 #define CDEBUG_MASK (1<<3)
38 #define DDEBUG_MASK (1<<4)
39
40 #define MSK_DEBUG(mask, ...) do {                       \
41                 if (unlikely(debug_mask & (mask)))      \
42                         pr_debug(__VA_ARGS__);          \
43         } while (0)
44 #ifdef IDEBUG
45 #define IF_DEBUG(...) MSK_DEBUG(IDEBUG_MASK, __VA_ARGS__)
46 #else
47 #define IF_DEBUG(...) no_printk(__VA_ARGS__)
48 #endif
49 #ifdef MDEBUG
50 #define MT_DEBUG(...) MSK_DEBUG(MDEBUG_MASK, __VA_ARGS__)
51 #else
52 #define MT_DEBUG(...) no_printk(__VA_ARGS__)
53 #endif
54 #ifdef RDEBUG
55 #define RB_DEBUG(...) MSK_DEBUG(RDEBUG_MASK, __VA_ARGS__)
56 #else
57 #define RB_DEBUG(...) no_printk(__VA_ARGS__)
58 #endif
59 #ifdef CDEBUG
60 #define CT_DEBUG(...) MSK_DEBUG(CDEBUG_MASK, __VA_ARGS__)
61 #else
62 #define CT_DEBUG(...) no_printk(__VA_ARGS__)
63 #endif
64 #ifdef DDEBUG
65 #define DR_DEBUG(...) MSK_DEBUG(DDEBUG_MASK, __VA_ARGS__)
66 #else
67 #define DR_DEBUG(...) no_printk(__VA_ARGS__)
68 #endif
69
70 extern uint debug_mask;
71
72 /*---------------------------------------------------------------------------*/
73 /*
74  * Tags:
75  *
76  * They represent what the data usage counters will be tracked against.
77  * By default a tag is just based on the UID.
78  * The UID is used as the base for policing, and can not be ignored.
79  * So a tag will always at least represent a UID (uid_tag).
80  *
81  * A tag can be augmented with an "accounting tag" which is associated
82  * with a UID.
83  * User space can set the acct_tag portion of the tag which is then used
84  * with sockets: all data belonging to that socket will be counted against the
85  * tag. The policing is then based on the tag's uid_tag portion,
86  * and stats are collected for the acct_tag portion separately.
87  *
88  * There could be
89  * a:  {acct_tag=1, uid_tag=10003}
90  * b:  {acct_tag=2, uid_tag=10003}
91  * c:  {acct_tag=3, uid_tag=10003}
92  * d:  {acct_tag=0, uid_tag=10003}
93  * a, b, and c represent tags associated with specific sockets.
94  * d is for the totals for that uid, including all untagged traffic.
95  * Typically d is used with policing/quota rules.
96  *
97  * We want tag_t big enough to distinguish uid_t and acct_tag.
98  * It might become a struct if needed.
99  * Nothing should be using it as an int.
100  */
101 typedef uint64_t tag_t;  /* Only used via accessors */
102
103 #define TAG_UID_MASK 0xFFFFFFFFULL
104 #define TAG_ACCT_MASK (~0xFFFFFFFFULL)
105
106 static inline int tag_compare(tag_t t1, tag_t t2)
107 {
108         return t1 < t2 ? -1 : t1 == t2 ? 0 : 1;
109 }
110
111 static inline tag_t combine_atag_with_uid(tag_t acct_tag, uid_t uid)
112 {
113         return acct_tag | uid;
114 }
115 static inline tag_t make_tag_from_uid(uid_t uid)
116 {
117         return uid;
118 }
119 static inline uid_t get_uid_from_tag(tag_t tag)
120 {
121         return tag & TAG_UID_MASK;
122 }
123 static inline tag_t get_utag_from_tag(tag_t tag)
124 {
125         return tag & TAG_UID_MASK;
126 }
127 static inline tag_t get_atag_from_tag(tag_t tag)
128 {
129         return tag & TAG_ACCT_MASK;
130 }
131
132 static inline bool valid_atag(tag_t tag)
133 {
134         return !(tag & TAG_UID_MASK);
135 }
136 static inline tag_t make_atag_from_value(uint32_t value)
137 {
138         return (uint64_t)value << 32;
139 }
140 /*---------------------------------------------------------------------------*/
141
142 /*
143  * Maximum number of socket tags that a UID is allowed to have active.
144  * Multiple processes belonging to the same UID contribute towards this limit.
145  * Special UIDs that can impersonate a UID also contribute (e.g. download
146  * manager, ...)
147  */
148 #define DEFAULT_MAX_SOCK_TAGS 1024
149
150 /*
151  * For now we only track 2 sets of counters.
152  * The default set is 0.
153  * Userspace can activate another set for a given uid being tracked.
154  */
155 #define IFS_MAX_COUNTER_SETS 2
156
157 enum ifs_tx_rx {
158         IFS_TX,
159         IFS_RX,
160         IFS_MAX_DIRECTIONS
161 };
162
163 /* For now, TCP, UDP, the rest */
164 enum ifs_proto {
165         IFS_TCP,
166         IFS_UDP,
167         IFS_PROTO_OTHER,
168         IFS_MAX_PROTOS
169 };
170
171 struct byte_packet_counters {
172         uint64_t bytes;
173         uint64_t packets;
174 };
175
176 struct data_counters {
177         struct byte_packet_counters bpc[IFS_MAX_COUNTER_SETS][IFS_MAX_DIRECTIONS][IFS_MAX_PROTOS];
178 };
179
180 /* Generic X based nodes used as a base for rb_tree ops */
181 struct tag_node {
182         struct rb_node node;
183         tag_t tag;
184 };
185
186 struct tag_stat {
187         struct tag_node tn;
188         struct data_counters counters;
189         /*
190          * If this tag is acct_tag based, we need to count against the
191          * matching parent uid_tag.
192          */
193         struct data_counters *parent_counters;
194 };
195
196 struct iface_stat {
197         struct list_head list;  /* in iface_stat_list */
198         char *ifname;
199         uint64_t rx_bytes;
200         uint64_t rx_packets;
201         uint64_t tx_bytes;
202         uint64_t tx_packets;
203         bool active;
204         struct proc_dir_entry *proc_ptr;
205
206         struct rb_root tag_stat_tree;
207         spinlock_t tag_stat_list_lock;
208 };
209
210 /* This is needed to create proc_dir_entries from atomic context. */
211 struct iface_stat_work {
212         struct work_struct iface_work;
213         struct iface_stat *iface_entry;
214 };
215
216 /*
217  * Track tag that this socket is transferring data for, and not necessarily
218  * the uid that owns the socket.
219  * This is the tag against which tag_stat.counters will be billed.
220  * These structs need to be looked up by sock and pid.
221  */
222 struct sock_tag {
223         struct rb_node sock_node;
224         struct sock *sk;  /* Only used as a number, never dereferenced */
225         /* The socket is needed for sockfd_put() */
226         struct socket *socket;
227         /* Used to associate with a given pid */
228         struct list_head list;   /* in proc_qtu_data.sock_tag_list */
229         pid_t pid;
230
231         tag_t tag;
232 };
233
234 struct qtaguid_event_counts {
235         /* Various successful events */
236         atomic64_t sockets_tagged;
237         atomic64_t sockets_untagged;
238         atomic64_t counter_set_changes;
239         atomic64_t delete_cmds;
240         atomic64_t iface_events;  /* Number of NETDEV_* events handled */
241         /*
242          * match_found_sk_*: numbers related to the netfilter matching
243          * function finding a sock for the sk_buff.
244          */
245         atomic64_t match_found_sk;   /* An sk was already in the sk_buff. */
246         /* The connection tracker had the sk. */
247         atomic64_t match_found_sk_in_ct;
248         /*
249          * No sk could be found. No apparent owner. Could happen with
250          * unsolicited traffic.
251          */
252         atomic64_t match_found_sk_none;
253 };
254
255 /* Track the set active_set for the given tag. */
256 struct tag_counter_set {
257         struct tag_node tn;
258         int active_set;
259 };
260
261 /*----------------------------------------------*/
262 /*
263  * The qtu uid data is used to track resources that are created directly or
264  * indirectly by processes (uid tracked).
265  * It is shared by the processes with the same uid.
266  * Some of the resource will be counted to prevent further rogue allocations,
267  * some will need freeing once the owner process (uid) exits.
268  */
269 struct uid_tag_data {
270         struct rb_node node;
271         uid_t uid;
272
273         /*
274          * For the uid, how many accounting tags have been set.
275          */
276         int num_active_tags;
277         struct rb_root tag_ref_tree;
278         /* No tag_node_tree_lock; use uid_tag_data_tree_lock */
279 };
280
281 struct tag_ref {
282         struct tag_node tn;
283
284         /*
285          * This tracks the number of active sockets that have a tag on them
286          * which matches this tag_ref.tn.tag.
287          * A tag ref can live on after the sockets are untagged.
288          * A tag ref can only be removed during a tag delete command.
289          */
290         int num_sock_tags;
291 };
292
293 struct proc_qtu_data {
294         struct rb_node node;
295         pid_t pid;
296
297         struct uid_tag_data *parent_tag_data;
298
299         /* Tracks the sock_tags that need freeing upon this proc's death */
300         struct list_head sock_tag_list;
301         /* No spinlock_t sock_tag_list_lock; use the global one. */
302 };
303
304 /*----------------------------------------------*/
305 #endif  /* ifndef __XT_QTAGUID_INTERNAL_H__ */