Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / net / netfilter / ipset / ip_set_hash_net.c
1 /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation.
6  */
7
8 /* Kernel module implementing an IP set type: the hash:net type */
9
10 #include <linux/jhash.h>
11 #include <linux/module.h>
12 #include <linux/ip.h>
13 #include <linux/skbuff.h>
14 #include <linux/errno.h>
15 #include <linux/random.h>
16 #include <net/ip.h>
17 #include <net/ipv6.h>
18 #include <net/netlink.h>
19
20 #include <linux/netfilter.h>
21 #include <linux/netfilter/ipset/pfxlen.h>
22 #include <linux/netfilter/ipset/ip_set.h>
23 #include <linux/netfilter/ipset/ip_set_hash.h>
24
25 #define IPSET_TYPE_REV_MIN      0
26 /*                              1    Range as input support for IPv4 added */
27 /*                              2    nomatch flag support added */
28 /*                              3    Counters support added */
29 /*                              4    Comments support added */
30 /*                              5    Forceadd support added */
31 #define IPSET_TYPE_REV_MAX      6 /* skbinfo mapping support added */
32
33 MODULE_LICENSE("GPL");
34 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
35 IP_SET_MODULE_DESC("hash:net", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
36 MODULE_ALIAS("ip_set_hash:net");
37
38 /* Type specific function prefix */
39 #define HTYPE           hash_net
40 #define IP_SET_HASH_WITH_NETS
41
42 /* IPv4 variant */
43
44 /* Member elements  */
45 struct hash_net4_elem {
46         __be32 ip;
47         u16 padding0;
48         u8 nomatch;
49         u8 cidr;
50 };
51
52 /* Common functions */
53
54 static inline bool
55 hash_net4_data_equal(const struct hash_net4_elem *ip1,
56                      const struct hash_net4_elem *ip2,
57                      u32 *multi)
58 {
59         return ip1->ip == ip2->ip &&
60                ip1->cidr == ip2->cidr;
61 }
62
63 static inline int
64 hash_net4_do_data_match(const struct hash_net4_elem *elem)
65 {
66         return elem->nomatch ? -ENOTEMPTY : 1;
67 }
68
69 static inline void
70 hash_net4_data_set_flags(struct hash_net4_elem *elem, u32 flags)
71 {
72         elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH;
73 }
74
75 static inline void
76 hash_net4_data_reset_flags(struct hash_net4_elem *elem, u8 *flags)
77 {
78         swap(*flags, elem->nomatch);
79 }
80
81 static inline void
82 hash_net4_data_netmask(struct hash_net4_elem *elem, u8 cidr)
83 {
84         elem->ip &= ip_set_netmask(cidr);
85         elem->cidr = cidr;
86 }
87
88 static bool
89 hash_net4_data_list(struct sk_buff *skb, const struct hash_net4_elem *data)
90 {
91         u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
92
93         if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
94             nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
95             (flags &&
96              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
97                 goto nla_put_failure;
98         return 0;
99
100 nla_put_failure:
101         return 1;
102 }
103
104 static inline void
105 hash_net4_data_next(struct hash_net4_elem *next,
106                     const struct hash_net4_elem *d)
107 {
108         next->ip = d->ip;
109 }
110
111 #define MTYPE           hash_net4
112 #define PF              4
113 #define HOST_MASK       32
114 #include "ip_set_hash_gen.h"
115
116 static int
117 hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb,
118                const struct xt_action_param *par,
119                enum ipset_adt adt, struct ip_set_adt_opt *opt)
120 {
121         const struct hash_net *h = set->data;
122         ipset_adtfn adtfn = set->variant->adt[adt];
123         struct hash_net4_elem e = {
124                 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
125         };
126         struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
127
128         if (e.cidr == 0)
129                 return -EINVAL;
130         if (adt == IPSET_TEST)
131                 e.cidr = HOST_MASK;
132
133         ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
134         e.ip &= ip_set_netmask(e.cidr);
135
136         return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
137 }
138
139 static int
140 hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
141                enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
142 {
143         const struct hash_net *h = set->data;
144         ipset_adtfn adtfn = set->variant->adt[adt];
145         struct hash_net4_elem e = { .cidr = HOST_MASK };
146         struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
147         u32 ip = 0, ip_to = 0, last;
148         int ret;
149
150         if (unlikely(!tb[IPSET_ATTR_IP] ||
151                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
152                      !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
153                      !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
154                      !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
155                      !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBMARK) ||
156                      !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBPRIO) ||
157                      !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBQUEUE)))
158                 return -IPSET_ERR_PROTOCOL;
159
160         if (tb[IPSET_ATTR_LINENO])
161                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
162
163         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) ||
164               ip_set_get_extensions(set, tb, &ext);
165         if (ret)
166                 return ret;
167
168         if (tb[IPSET_ATTR_CIDR]) {
169                 e.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
170                 if (!e.cidr || e.cidr > HOST_MASK)
171                         return -IPSET_ERR_INVALID_CIDR;
172         }
173
174         if (tb[IPSET_ATTR_CADT_FLAGS]) {
175                 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
176                 if (cadt_flags & IPSET_FLAG_NOMATCH)
177                         flags |= (IPSET_FLAG_NOMATCH << 16);
178         }
179
180         if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) {
181                 e.ip = htonl(ip & ip_set_hostmask(e.cidr));
182                 ret = adtfn(set, &e, &ext, &ext, flags);
183                 return ip_set_enomatch(ret, flags, adt, set) ? -ret:
184                        ip_set_eexist(ret, flags) ? 0 : ret;
185         }
186
187         ip_to = ip;
188         if (tb[IPSET_ATTR_IP_TO]) {
189                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
190                 if (ret)
191                         return ret;
192                 if (ip_to < ip)
193                         swap(ip, ip_to);
194                 if (ip + UINT_MAX == ip_to)
195                         return -IPSET_ERR_HASH_RANGE;
196         }
197         if (retried)
198                 ip = ntohl(h->next.ip);
199         while (!after(ip, ip_to)) {
200                 e.ip = htonl(ip);
201                 last = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
202                 ret = adtfn(set, &e, &ext, &ext, flags);
203                 if (ret && !ip_set_eexist(ret, flags))
204                         return ret;
205                 else
206                         ret = 0;
207                 ip = last + 1;
208         }
209         return ret;
210 }
211
212 /* IPv6 variant */
213
214 struct hash_net6_elem {
215         union nf_inet_addr ip;
216         u16 padding0;
217         u8 nomatch;
218         u8 cidr;
219 };
220
221 /* Common functions */
222
223 static inline bool
224 hash_net6_data_equal(const struct hash_net6_elem *ip1,
225                      const struct hash_net6_elem *ip2,
226                      u32 *multi)
227 {
228         return ipv6_addr_equal(&ip1->ip.in6, &ip2->ip.in6) &&
229                ip1->cidr == ip2->cidr;
230 }
231
232 static inline int
233 hash_net6_do_data_match(const struct hash_net6_elem *elem)
234 {
235         return elem->nomatch ? -ENOTEMPTY : 1;
236 }
237
238 static inline void
239 hash_net6_data_set_flags(struct hash_net6_elem *elem, u32 flags)
240 {
241         elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH;
242 }
243
244 static inline void
245 hash_net6_data_reset_flags(struct hash_net6_elem *elem, u8 *flags)
246 {
247         swap(*flags, elem->nomatch);
248 }
249
250 static inline void
251 hash_net6_data_netmask(struct hash_net6_elem *elem, u8 cidr)
252 {
253         ip6_netmask(&elem->ip, cidr);
254         elem->cidr = cidr;
255 }
256
257 static bool
258 hash_net6_data_list(struct sk_buff *skb, const struct hash_net6_elem *data)
259 {
260         u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
261
262         if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
263             nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
264             (flags &&
265              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
266                 goto nla_put_failure;
267         return 0;
268
269 nla_put_failure:
270         return 1;
271 }
272
273 static inline void
274 hash_net6_data_next(struct hash_net4_elem *next,
275                     const struct hash_net6_elem *d)
276 {
277 }
278
279 #undef MTYPE
280 #undef PF
281 #undef HOST_MASK
282
283 #define MTYPE           hash_net6
284 #define PF              6
285 #define HOST_MASK       128
286 #define IP_SET_EMIT_CREATE
287 #include "ip_set_hash_gen.h"
288
289 static int
290 hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb,
291                const struct xt_action_param *par,
292                enum ipset_adt adt, struct ip_set_adt_opt *opt)
293 {
294         const struct hash_net *h = set->data;
295         ipset_adtfn adtfn = set->variant->adt[adt];
296         struct hash_net6_elem e = {
297                 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
298         };
299         struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
300
301         if (e.cidr == 0)
302                 return -EINVAL;
303         if (adt == IPSET_TEST)
304                 e.cidr = HOST_MASK;
305
306         ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
307         ip6_netmask(&e.ip, e.cidr);
308
309         return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
310 }
311
312 static int
313 hash_net6_uadt(struct ip_set *set, struct nlattr *tb[],
314                enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
315 {
316         ipset_adtfn adtfn = set->variant->adt[adt];
317         struct hash_net6_elem e = { .cidr = HOST_MASK };
318         struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
319         int ret;
320
321         if (unlikely(!tb[IPSET_ATTR_IP] ||
322                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
323                      !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
324                      !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
325                      !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
326                      !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBMARK) ||
327                      !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBPRIO) ||
328                      !ip_set_optattr_netorder(tb, IPSET_ATTR_SKBQUEUE)))
329                 return -IPSET_ERR_PROTOCOL;
330         if (unlikely(tb[IPSET_ATTR_IP_TO]))
331                 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED;
332
333         if (tb[IPSET_ATTR_LINENO])
334                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
335
336         ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
337               ip_set_get_extensions(set, tb, &ext);
338         if (ret)
339                 return ret;
340
341         if (tb[IPSET_ATTR_CIDR])
342                 e.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
343
344         if (!e.cidr || e.cidr > HOST_MASK)
345                 return -IPSET_ERR_INVALID_CIDR;
346
347         ip6_netmask(&e.ip, e.cidr);
348
349         if (tb[IPSET_ATTR_CADT_FLAGS]) {
350                 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
351                 if (cadt_flags & IPSET_FLAG_NOMATCH)
352                         flags |= (IPSET_FLAG_NOMATCH << 16);
353         }
354
355         ret = adtfn(set, &e, &ext, &ext, flags);
356
357         return ip_set_enomatch(ret, flags, adt, set) ? -ret :
358                ip_set_eexist(ret, flags) ? 0 : ret;
359 }
360
361 static struct ip_set_type hash_net_type __read_mostly = {
362         .name           = "hash:net",
363         .protocol       = IPSET_PROTOCOL,
364         .features       = IPSET_TYPE_IP | IPSET_TYPE_NOMATCH,
365         .dimension      = IPSET_DIM_ONE,
366         .family         = NFPROTO_UNSPEC,
367         .revision_min   = IPSET_TYPE_REV_MIN,
368         .revision_max   = IPSET_TYPE_REV_MAX,
369         .create         = hash_net_create,
370         .create_policy  = {
371                 [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
372                 [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
373                 [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
374                 [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
375                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
376                 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
377         },
378         .adt_policy     = {
379                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
380                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
381                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
382                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
383                 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
384                 [IPSET_ATTR_BYTES]      = { .type = NLA_U64 },
385                 [IPSET_ATTR_PACKETS]    = { .type = NLA_U64 },
386                 [IPSET_ATTR_COMMENT]    = { .type = NLA_NUL_STRING },
387                 [IPSET_ATTR_SKBMARK]    = { .type = NLA_U64 },
388                 [IPSET_ATTR_SKBPRIO]    = { .type = NLA_U32 },
389                 [IPSET_ATTR_SKBQUEUE]   = { .type = NLA_U16 },
390         },
391         .me             = THIS_MODULE,
392 };
393
394 static int __init
395 hash_net_init(void)
396 {
397         return ip_set_type_register(&hash_net_type);
398 }
399
400 static void __exit
401 hash_net_fini(void)
402 {
403         ip_set_type_unregister(&hash_net_type);
404 }
405
406 module_init(hash_net_init);
407 module_exit(hash_net_fini);