Merge tag 'v3.5-rc7' into late/soc
[firefly-linux-kernel-4.4.55.git] / net / netfilter / ipset / ip_set_hash_netiface.c
1 /* Copyright (C) 2011 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,iface 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 <linux/rbtree.h>
17 #include <net/ip.h>
18 #include <net/ipv6.h>
19 #include <net/netlink.h>
20
21 #include <linux/netfilter.h>
22 #include <linux/netfilter/ipset/pfxlen.h>
23 #include <linux/netfilter/ipset/ip_set.h>
24 #include <linux/netfilter/ipset/ip_set_timeout.h>
25 #include <linux/netfilter/ipset/ip_set_hash.h>
26
27 MODULE_LICENSE("GPL");
28 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
29 MODULE_DESCRIPTION("hash:net,iface type of IP sets");
30 MODULE_ALIAS("ip_set_hash:net,iface");
31
32 /* Interface name rbtree */
33
34 struct iface_node {
35         struct rb_node node;
36         char iface[IFNAMSIZ];
37 };
38
39 #define iface_data(n)   (rb_entry(n, struct iface_node, node)->iface)
40
41 static void
42 rbtree_destroy(struct rb_root *root)
43 {
44         struct rb_node *p, *n = root->rb_node;
45         struct iface_node *node;
46
47         /* Non-recursive destroy, like in ext3 */
48         while (n) {
49                 if (n->rb_left) {
50                         n = n->rb_left;
51                         continue;
52                 }
53                 if (n->rb_right) {
54                         n = n->rb_right;
55                         continue;
56                 }
57                 p = rb_parent(n);
58                 node = rb_entry(n, struct iface_node, node);
59                 if (!p)
60                         *root = RB_ROOT;
61                 else if (p->rb_left == n)
62                         p->rb_left = NULL;
63                 else if (p->rb_right == n)
64                         p->rb_right = NULL;
65
66                 kfree(node);
67                 n = p;
68         }
69 }
70
71 static int
72 iface_test(struct rb_root *root, const char **iface)
73 {
74         struct rb_node *n = root->rb_node;
75
76         while (n) {
77                 const char *d = iface_data(n);
78                 int res = strcmp(*iface, d);
79
80                 if (res < 0)
81                         n = n->rb_left;
82                 else if (res > 0)
83                         n = n->rb_right;
84                 else {
85                         *iface = d;
86                         return 1;
87                 }
88         }
89         return 0;
90 }
91
92 static int
93 iface_add(struct rb_root *root, const char **iface)
94 {
95         struct rb_node **n = &(root->rb_node), *p = NULL;
96         struct iface_node *d;
97
98         while (*n) {
99                 char *ifname = iface_data(*n);
100                 int res = strcmp(*iface, ifname);
101
102                 p = *n;
103                 if (res < 0)
104                         n = &((*n)->rb_left);
105                 else if (res > 0)
106                         n = &((*n)->rb_right);
107                 else {
108                         *iface = ifname;
109                         return 0;
110                 }
111         }
112
113         d = kzalloc(sizeof(*d), GFP_ATOMIC);
114         if (!d)
115                 return -ENOMEM;
116         strcpy(d->iface, *iface);
117
118         rb_link_node(&d->node, p, n);
119         rb_insert_color(&d->node, root);
120
121         *iface = d->iface;
122         return 0;
123 }
124
125 /* Type specific function prefix */
126 #define TYPE            hash_netiface
127
128 static bool
129 hash_netiface_same_set(const struct ip_set *a, const struct ip_set *b);
130
131 #define hash_netiface4_same_set hash_netiface_same_set
132 #define hash_netiface6_same_set hash_netiface_same_set
133
134 #define STREQ(a, b)     (strcmp(a, b) == 0)
135
136 /* The type variant functions: IPv4 */
137
138 struct hash_netiface4_elem_hashed {
139         __be32 ip;
140         u8 physdev;
141         u8 cidr;
142         u8 nomatch;
143         u8 padding;
144 };
145
146 #define HKEY_DATALEN    sizeof(struct hash_netiface4_elem_hashed)
147
148 /* Member elements without timeout */
149 struct hash_netiface4_elem {
150         __be32 ip;
151         u8 physdev;
152         u8 cidr;
153         u8 nomatch;
154         u8 padding;
155         const char *iface;
156 };
157
158 /* Member elements with timeout support */
159 struct hash_netiface4_telem {
160         __be32 ip;
161         u8 physdev;
162         u8 cidr;
163         u8 nomatch;
164         u8 padding;
165         const char *iface;
166         unsigned long timeout;
167 };
168
169 static inline bool
170 hash_netiface4_data_equal(const struct hash_netiface4_elem *ip1,
171                           const struct hash_netiface4_elem *ip2,
172                           u32 *multi)
173 {
174         return ip1->ip == ip2->ip &&
175                ip1->cidr == ip2->cidr &&
176                (++*multi) &&
177                ip1->physdev == ip2->physdev &&
178                ip1->iface == ip2->iface;
179 }
180
181 static inline bool
182 hash_netiface4_data_isnull(const struct hash_netiface4_elem *elem)
183 {
184         return elem->cidr == 0;
185 }
186
187 static inline void
188 hash_netiface4_data_copy(struct hash_netiface4_elem *dst,
189                          const struct hash_netiface4_elem *src)
190 {
191         dst->ip = src->ip;
192         dst->cidr = src->cidr;
193         dst->physdev = src->physdev;
194         dst->iface = src->iface;
195         dst->nomatch = src->nomatch;
196 }
197
198 static inline void
199 hash_netiface4_data_flags(struct hash_netiface4_elem *dst, u32 flags)
200 {
201         dst->nomatch = flags & IPSET_FLAG_NOMATCH;
202 }
203
204 static inline bool
205 hash_netiface4_data_match(const struct hash_netiface4_elem *elem)
206 {
207         return !elem->nomatch;
208 }
209
210 static inline void
211 hash_netiface4_data_netmask(struct hash_netiface4_elem *elem, u8 cidr)
212 {
213         elem->ip &= ip_set_netmask(cidr);
214         elem->cidr = cidr;
215 }
216
217 static inline void
218 hash_netiface4_data_zero_out(struct hash_netiface4_elem *elem)
219 {
220         elem->cidr = 0;
221 }
222
223 static bool
224 hash_netiface4_data_list(struct sk_buff *skb,
225                          const struct hash_netiface4_elem *data)
226 {
227         u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0;
228
229         if (data->nomatch)
230                 flags |= IPSET_FLAG_NOMATCH;
231         if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
232             nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
233             nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) ||
234             (flags &&
235              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
236                 goto nla_put_failure;
237         return 0;
238
239 nla_put_failure:
240         return 1;
241 }
242
243 static bool
244 hash_netiface4_data_tlist(struct sk_buff *skb,
245                           const struct hash_netiface4_elem *data)
246 {
247         const struct hash_netiface4_telem *tdata =
248                 (const struct hash_netiface4_telem *)data;
249         u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0;
250
251         if (data->nomatch)
252                 flags |= IPSET_FLAG_NOMATCH;
253         if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
254             nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
255             nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) ||
256             (flags &&
257              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))) ||
258             nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
259                           htonl(ip_set_timeout_get(tdata->timeout))))
260                 goto nla_put_failure;
261
262         return 0;
263
264 nla_put_failure:
265         return 1;
266 }
267
268 #define IP_SET_HASH_WITH_NETS
269 #define IP_SET_HASH_WITH_RBTREE
270 #define IP_SET_HASH_WITH_MULTI
271
272 #define PF              4
273 #define HOST_MASK       32
274 #include <linux/netfilter/ipset/ip_set_ahash.h>
275
276 static inline void
277 hash_netiface4_data_next(struct ip_set_hash *h,
278                          const struct hash_netiface4_elem *d)
279 {
280         h->next.ip = ntohl(d->ip);
281 }
282
283 static int
284 hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
285                     const struct xt_action_param *par,
286                     enum ipset_adt adt, const struct ip_set_adt_opt *opt)
287 {
288         struct ip_set_hash *h = set->data;
289         ipset_adtfn adtfn = set->variant->adt[adt];
290         struct hash_netiface4_elem data = {
291                 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
292         };
293         int ret;
294
295         if (data.cidr == 0)
296                 return -EINVAL;
297         if (adt == IPSET_TEST)
298                 data.cidr = HOST_MASK;
299
300         ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip);
301         data.ip &= ip_set_netmask(data.cidr);
302
303 #define IFACE(dir)      (par->dir ? par->dir->name : NULL)
304 #define PHYSDEV(dir)    (nf_bridge->dir ? nf_bridge->dir->name : NULL)
305 #define SRCDIR          (opt->flags & IPSET_DIM_TWO_SRC)
306
307         if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
308 #ifdef CONFIG_BRIDGE_NETFILTER
309                 const struct nf_bridge_info *nf_bridge = skb->nf_bridge;
310
311                 if (!nf_bridge)
312                         return -EINVAL;
313                 data.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev);
314                 data.physdev = 1;
315 #else
316                 data.iface = NULL;
317 #endif
318         } else
319                 data.iface = SRCDIR ? IFACE(in) : IFACE(out);
320
321         if (!data.iface)
322                 return -EINVAL;
323         ret = iface_test(&h->rbtree, &data.iface);
324         if (adt == IPSET_ADD) {
325                 if (!ret) {
326                         ret = iface_add(&h->rbtree, &data.iface);
327                         if (ret)
328                                 return ret;
329                 }
330         } else if (!ret)
331                 return ret;
332
333         return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
334 }
335
336 static int
337 hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
338                     enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
339 {
340         struct ip_set_hash *h = set->data;
341         ipset_adtfn adtfn = set->variant->adt[adt];
342         struct hash_netiface4_elem data = { .cidr = HOST_MASK };
343         u32 ip = 0, ip_to, last;
344         u32 timeout = h->timeout;
345         char iface[IFNAMSIZ];
346         int ret;
347
348         if (unlikely(!tb[IPSET_ATTR_IP] ||
349                      !tb[IPSET_ATTR_IFACE] ||
350                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
351                      !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
352                 return -IPSET_ERR_PROTOCOL;
353
354         if (tb[IPSET_ATTR_LINENO])
355                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
356
357         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
358         if (ret)
359                 return ret;
360
361         if (tb[IPSET_ATTR_CIDR]) {
362                 data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
363                 if (!data.cidr || data.cidr > HOST_MASK)
364                         return -IPSET_ERR_INVALID_CIDR;
365         }
366
367         if (tb[IPSET_ATTR_TIMEOUT]) {
368                 if (!with_timeout(h->timeout))
369                         return -IPSET_ERR_TIMEOUT;
370                 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
371         }
372
373         strcpy(iface, nla_data(tb[IPSET_ATTR_IFACE]));
374         data.iface = iface;
375         ret = iface_test(&h->rbtree, &data.iface);
376         if (adt == IPSET_ADD) {
377                 if (!ret) {
378                         ret = iface_add(&h->rbtree, &data.iface);
379                         if (ret)
380                                 return ret;
381                 }
382         } else if (!ret)
383                 return ret;
384
385         if (tb[IPSET_ATTR_CADT_FLAGS]) {
386                 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
387                 if (cadt_flags & IPSET_FLAG_PHYSDEV)
388                         data.physdev = 1;
389                 if (adt == IPSET_ADD && (cadt_flags & IPSET_FLAG_NOMATCH))
390                         flags |= (cadt_flags << 16);
391         }
392
393         if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) {
394                 data.ip = htonl(ip & ip_set_hostmask(data.cidr));
395                 ret = adtfn(set, &data, timeout, flags);
396                 return ip_set_eexist(ret, flags) ? 0 : ret;
397         }
398
399         if (tb[IPSET_ATTR_IP_TO]) {
400                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
401                 if (ret)
402                         return ret;
403                 if (ip_to < ip)
404                         swap(ip, ip_to);
405                 if (ip + UINT_MAX == ip_to)
406                         return -IPSET_ERR_HASH_RANGE;
407         } else {
408                 ip_set_mask_from_to(ip, ip_to, data.cidr);
409         }
410
411         if (retried)
412                 ip = h->next.ip;
413         while (!after(ip, ip_to)) {
414                 data.ip = htonl(ip);
415                 last = ip_set_range_to_cidr(ip, ip_to, &data.cidr);
416                 ret = adtfn(set, &data, timeout, flags);
417
418                 if (ret && !ip_set_eexist(ret, flags))
419                         return ret;
420                 else
421                         ret = 0;
422                 ip = last + 1;
423         }
424         return ret;
425 }
426
427 static bool
428 hash_netiface_same_set(const struct ip_set *a, const struct ip_set *b)
429 {
430         const struct ip_set_hash *x = a->data;
431         const struct ip_set_hash *y = b->data;
432
433         /* Resizing changes htable_bits, so we ignore it */
434         return x->maxelem == y->maxelem &&
435                x->timeout == y->timeout;
436 }
437
438 /* The type variant functions: IPv6 */
439
440 struct hash_netiface6_elem_hashed {
441         union nf_inet_addr ip;
442         u8 physdev;
443         u8 cidr;
444         u8 nomatch;
445         u8 padding;
446 };
447
448 #define HKEY_DATALEN    sizeof(struct hash_netiface6_elem_hashed)
449
450 struct hash_netiface6_elem {
451         union nf_inet_addr ip;
452         u8 physdev;
453         u8 cidr;
454         u8 nomatch;
455         u8 padding;
456         const char *iface;
457 };
458
459 struct hash_netiface6_telem {
460         union nf_inet_addr ip;
461         u8 physdev;
462         u8 cidr;
463         u8 nomatch;
464         u8 padding;
465         const char *iface;
466         unsigned long timeout;
467 };
468
469 static inline bool
470 hash_netiface6_data_equal(const struct hash_netiface6_elem *ip1,
471                           const struct hash_netiface6_elem *ip2,
472                           u32 *multi)
473 {
474         return ipv6_addr_cmp(&ip1->ip.in6, &ip2->ip.in6) == 0 &&
475                ip1->cidr == ip2->cidr &&
476                (++*multi) &&
477                ip1->physdev == ip2->physdev &&
478                ip1->iface == ip2->iface;
479 }
480
481 static inline bool
482 hash_netiface6_data_isnull(const struct hash_netiface6_elem *elem)
483 {
484         return elem->cidr == 0;
485 }
486
487 static inline void
488 hash_netiface6_data_copy(struct hash_netiface6_elem *dst,
489                          const struct hash_netiface6_elem *src)
490 {
491         memcpy(dst, src, sizeof(*dst));
492 }
493
494 static inline void
495 hash_netiface6_data_flags(struct hash_netiface6_elem *dst, u32 flags)
496 {
497         dst->nomatch = flags & IPSET_FLAG_NOMATCH;
498 }
499
500 static inline bool
501 hash_netiface6_data_match(const struct hash_netiface6_elem *elem)
502 {
503         return !elem->nomatch;
504 }
505
506 static inline void
507 hash_netiface6_data_zero_out(struct hash_netiface6_elem *elem)
508 {
509         elem->cidr = 0;
510 }
511
512 static inline void
513 ip6_netmask(union nf_inet_addr *ip, u8 prefix)
514 {
515         ip->ip6[0] &= ip_set_netmask6(prefix)[0];
516         ip->ip6[1] &= ip_set_netmask6(prefix)[1];
517         ip->ip6[2] &= ip_set_netmask6(prefix)[2];
518         ip->ip6[3] &= ip_set_netmask6(prefix)[3];
519 }
520
521 static inline void
522 hash_netiface6_data_netmask(struct hash_netiface6_elem *elem, u8 cidr)
523 {
524         ip6_netmask(&elem->ip, cidr);
525         elem->cidr = cidr;
526 }
527
528 static bool
529 hash_netiface6_data_list(struct sk_buff *skb,
530                          const struct hash_netiface6_elem *data)
531 {
532         u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0;
533
534         if (data->nomatch)
535                 flags |= IPSET_FLAG_NOMATCH;
536         if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
537             nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
538             nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) ||
539             (flags &&
540              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
541                 goto nla_put_failure;
542         return 0;
543
544 nla_put_failure:
545         return 1;
546 }
547
548 static bool
549 hash_netiface6_data_tlist(struct sk_buff *skb,
550                           const struct hash_netiface6_elem *data)
551 {
552         const struct hash_netiface6_telem *e =
553                 (const struct hash_netiface6_telem *)data;
554         u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0;
555
556         if (data->nomatch)
557                 flags |= IPSET_FLAG_NOMATCH;
558         if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
559             nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
560             nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) ||
561             (flags &&
562              nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))) ||
563             nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
564                           htonl(ip_set_timeout_get(e->timeout))))
565                 goto nla_put_failure;
566         return 0;
567
568 nla_put_failure:
569         return 1;
570 }
571
572 #undef PF
573 #undef HOST_MASK
574
575 #define PF              6
576 #define HOST_MASK       128
577 #include <linux/netfilter/ipset/ip_set_ahash.h>
578
579 static inline void
580 hash_netiface6_data_next(struct ip_set_hash *h,
581                          const struct hash_netiface6_elem *d)
582 {
583 }
584
585 static int
586 hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,
587                     const struct xt_action_param *par,
588                     enum ipset_adt adt, const struct ip_set_adt_opt *opt)
589 {
590         struct ip_set_hash *h = set->data;
591         ipset_adtfn adtfn = set->variant->adt[adt];
592         struct hash_netiface6_elem data = {
593                 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
594         };
595         int ret;
596
597         if (data.cidr == 0)
598                 return -EINVAL;
599         if (adt == IPSET_TEST)
600                 data.cidr = HOST_MASK;
601
602         ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6);
603         ip6_netmask(&data.ip, data.cidr);
604
605         if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
606 #ifdef CONFIG_BRIDGE_NETFILTER
607                 const struct nf_bridge_info *nf_bridge = skb->nf_bridge;
608
609                 if (!nf_bridge)
610                         return -EINVAL;
611                 data.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev);
612                 data.physdev = 1;
613 #else
614                 data.iface = NULL;
615 #endif
616         } else
617                 data.iface = SRCDIR ? IFACE(in) : IFACE(out);
618
619         if (!data.iface)
620                 return -EINVAL;
621         ret = iface_test(&h->rbtree, &data.iface);
622         if (adt == IPSET_ADD) {
623                 if (!ret) {
624                         ret = iface_add(&h->rbtree, &data.iface);
625                         if (ret)
626                                 return ret;
627                 }
628         } else if (!ret)
629                 return ret;
630
631         return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
632 }
633
634 static int
635 hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
636                    enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
637 {
638         struct ip_set_hash *h = set->data;
639         ipset_adtfn adtfn = set->variant->adt[adt];
640         struct hash_netiface6_elem data = { .cidr = HOST_MASK };
641         u32 timeout = h->timeout;
642         char iface[IFNAMSIZ];
643         int ret;
644
645         if (unlikely(!tb[IPSET_ATTR_IP] ||
646                      !tb[IPSET_ATTR_IFACE] ||
647                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
648                      !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
649                 return -IPSET_ERR_PROTOCOL;
650         if (unlikely(tb[IPSET_ATTR_IP_TO]))
651                 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED;
652
653         if (tb[IPSET_ATTR_LINENO])
654                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
655
656         ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip);
657         if (ret)
658                 return ret;
659
660         if (tb[IPSET_ATTR_CIDR])
661                 data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
662         if (!data.cidr || data.cidr > HOST_MASK)
663                 return -IPSET_ERR_INVALID_CIDR;
664         ip6_netmask(&data.ip, data.cidr);
665
666         if (tb[IPSET_ATTR_TIMEOUT]) {
667                 if (!with_timeout(h->timeout))
668                         return -IPSET_ERR_TIMEOUT;
669                 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
670         }
671
672         strcpy(iface, nla_data(tb[IPSET_ATTR_IFACE]));
673         data.iface = iface;
674         ret = iface_test(&h->rbtree, &data.iface);
675         if (adt == IPSET_ADD) {
676                 if (!ret) {
677                         ret = iface_add(&h->rbtree, &data.iface);
678                         if (ret)
679                                 return ret;
680                 }
681         } else if (!ret)
682                 return ret;
683
684         if (tb[IPSET_ATTR_CADT_FLAGS]) {
685                 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
686                 if (cadt_flags & IPSET_FLAG_PHYSDEV)
687                         data.physdev = 1;
688                 if (adt == IPSET_ADD && (cadt_flags & IPSET_FLAG_NOMATCH))
689                         flags |= (cadt_flags << 16);
690         }
691
692         ret = adtfn(set, &data, timeout, flags);
693
694         return ip_set_eexist(ret, flags) ? 0 : ret;
695 }
696
697 /* Create hash:ip type of sets */
698
699 static int
700 hash_netiface_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
701 {
702         struct ip_set_hash *h;
703         u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
704         u8 hbits;
705         size_t hsize;
706
707         if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
708                 return -IPSET_ERR_INVALID_FAMILY;
709
710         if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
711                      !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
712                      !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
713                 return -IPSET_ERR_PROTOCOL;
714
715         if (tb[IPSET_ATTR_HASHSIZE]) {
716                 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
717                 if (hashsize < IPSET_MIMINAL_HASHSIZE)
718                         hashsize = IPSET_MIMINAL_HASHSIZE;
719         }
720
721         if (tb[IPSET_ATTR_MAXELEM])
722                 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
723
724         h = kzalloc(sizeof(*h)
725                     + sizeof(struct ip_set_hash_nets)
726                       * (set->family == NFPROTO_IPV4 ? 32 : 128), GFP_KERNEL);
727         if (!h)
728                 return -ENOMEM;
729
730         h->maxelem = maxelem;
731         get_random_bytes(&h->initval, sizeof(h->initval));
732         h->timeout = IPSET_NO_TIMEOUT;
733         h->ahash_max = AHASH_MAX_SIZE;
734
735         hbits = htable_bits(hashsize);
736         hsize = htable_size(hbits);
737         if (hsize == 0) {
738                 kfree(h);
739                 return -ENOMEM;
740         }
741         h->table = ip_set_alloc(hsize);
742         if (!h->table) {
743                 kfree(h);
744                 return -ENOMEM;
745         }
746         h->table->htable_bits = hbits;
747         h->rbtree = RB_ROOT;
748
749         set->data = h;
750
751         if (tb[IPSET_ATTR_TIMEOUT]) {
752                 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
753
754                 set->variant = set->family == NFPROTO_IPV4
755                         ? &hash_netiface4_tvariant : &hash_netiface6_tvariant;
756
757                 if (set->family == NFPROTO_IPV4)
758                         hash_netiface4_gc_init(set);
759                 else
760                         hash_netiface6_gc_init(set);
761         } else {
762                 set->variant = set->family == NFPROTO_IPV4
763                         ? &hash_netiface4_variant : &hash_netiface6_variant;
764         }
765
766         pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
767                  set->name, jhash_size(h->table->htable_bits),
768                  h->table->htable_bits, h->maxelem, set->data, h->table);
769
770         return 0;
771 }
772
773 static struct ip_set_type hash_netiface_type __read_mostly = {
774         .name           = "hash:net,iface",
775         .protocol       = IPSET_PROTOCOL,
776         .features       = IPSET_TYPE_IP | IPSET_TYPE_IFACE,
777         .dimension      = IPSET_DIM_TWO,
778         .family         = NFPROTO_UNSPEC,
779         .revision_min   = 0,
780         .revision_max   = 1,    /* nomatch flag support added */
781         .create         = hash_netiface_create,
782         .create_policy  = {
783                 [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
784                 [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
785                 [IPSET_ATTR_PROBES]     = { .type = NLA_U8 },
786                 [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
787                 [IPSET_ATTR_PROTO]      = { .type = NLA_U8 },
788                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
789         },
790         .adt_policy     = {
791                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
792                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
793                 [IPSET_ATTR_IFACE]      = { .type = NLA_NUL_STRING,
794                                             .len = IPSET_MAXNAMELEN - 1 },
795                 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
796                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
797                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
798                 [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
799         },
800         .me             = THIS_MODULE,
801 };
802
803 static int __init
804 hash_netiface_init(void)
805 {
806         return ip_set_type_register(&hash_netiface_type);
807 }
808
809 static void __exit
810 hash_netiface_fini(void)
811 {
812         ip_set_type_unregister(&hash_netiface_type);
813 }
814
815 module_init(hash_netiface_init);
816 module_exit(hash_netiface_fini);