Merge branches 'doc.2021.01.06a', 'fixes.2021.01.04b', 'kfree_rcu.2021.01.04a', ...
[linux-2.6-microblaze.git] / net / netfilter / ipset / ip_set_hash_ip.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */
3
4 /* Kernel module implementing an IP set type: the hash:ip type */
5
6 #include <linux/jhash.h>
7 #include <linux/module.h>
8 #include <linux/ip.h>
9 #include <linux/skbuff.h>
10 #include <linux/errno.h>
11 #include <linux/random.h>
12 #include <net/ip.h>
13 #include <net/ipv6.h>
14 #include <net/netlink.h>
15 #include <net/tcp.h>
16
17 #include <linux/netfilter.h>
18 #include <linux/netfilter/ipset/pfxlen.h>
19 #include <linux/netfilter/ipset/ip_set.h>
20 #include <linux/netfilter/ipset/ip_set_hash.h>
21
22 #define IPSET_TYPE_REV_MIN      0
23 /*                              1          Counters support */
24 /*                              2          Comments support */
25 /*                              3          Forceadd support */
26 /*                              4          skbinfo support */
27 #define IPSET_TYPE_REV_MAX      5       /* bucketsize, initval support  */
28
29 MODULE_LICENSE("GPL");
30 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>");
31 IP_SET_MODULE_DESC("hash:ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
32 MODULE_ALIAS("ip_set_hash:ip");
33
34 /* Type specific function prefix */
35 #define HTYPE           hash_ip
36 #define IP_SET_HASH_WITH_NETMASK
37
38 /* IPv4 variant */
39
40 /* Member elements */
41 struct hash_ip4_elem {
42         /* Zero valued IP addresses cannot be stored */
43         __be32 ip;
44 };
45
46 /* Common functions */
47
48 static bool
49 hash_ip4_data_equal(const struct hash_ip4_elem *e1,
50                     const struct hash_ip4_elem *e2,
51                     u32 *multi)
52 {
53         return e1->ip == e2->ip;
54 }
55
56 static bool
57 hash_ip4_data_list(struct sk_buff *skb, const struct hash_ip4_elem *e)
58 {
59         if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, e->ip))
60                 goto nla_put_failure;
61         return false;
62
63 nla_put_failure:
64         return true;
65 }
66
67 static void
68 hash_ip4_data_next(struct hash_ip4_elem *next, const struct hash_ip4_elem *e)
69 {
70         next->ip = e->ip;
71 }
72
73 #define MTYPE           hash_ip4
74 #define HOST_MASK       32
75 #include "ip_set_hash_gen.h"
76
77 static int
78 hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb,
79               const struct xt_action_param *par,
80               enum ipset_adt adt, struct ip_set_adt_opt *opt)
81 {
82         const struct hash_ip4 *h = set->data;
83         ipset_adtfn adtfn = set->variant->adt[adt];
84         struct hash_ip4_elem e = { 0 };
85         struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
86         __be32 ip;
87
88         ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip);
89         ip &= ip_set_netmask(h->netmask);
90         if (ip == 0)
91                 return -EINVAL;
92
93         e.ip = ip;
94         return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
95 }
96
97 static int
98 hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
99               enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
100 {
101         const struct hash_ip4 *h = set->data;
102         ipset_adtfn adtfn = set->variant->adt[adt];
103         struct hash_ip4_elem e = { 0 };
104         struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
105         u32 ip = 0, ip_to = 0, hosts;
106         int ret = 0;
107
108         if (tb[IPSET_ATTR_LINENO])
109                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
110
111         if (unlikely(!tb[IPSET_ATTR_IP]))
112                 return -IPSET_ERR_PROTOCOL;
113
114         ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
115         if (ret)
116                 return ret;
117
118         ret = ip_set_get_extensions(set, tb, &ext);
119         if (ret)
120                 return ret;
121
122         ip &= ip_set_hostmask(h->netmask);
123         e.ip = htonl(ip);
124         if (e.ip == 0)
125                 return -IPSET_ERR_HASH_ELEM;
126
127         if (adt == IPSET_TEST)
128                 return adtfn(set, &e, &ext, &ext, flags);
129
130         ip_to = ip;
131         if (tb[IPSET_ATTR_IP_TO]) {
132                 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
133                 if (ret)
134                         return ret;
135                 if (ip > ip_to)
136                         swap(ip, ip_to);
137         } else if (tb[IPSET_ATTR_CIDR]) {
138                 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
139
140                 if (!cidr || cidr > HOST_MASK)
141                         return -IPSET_ERR_INVALID_CIDR;
142                 ip_set_mask_from_to(ip, ip_to, cidr);
143         }
144
145         hosts = h->netmask == 32 ? 1 : 2 << (32 - h->netmask - 1);
146
147         if (retried) {
148                 ip = ntohl(h->next.ip);
149                 e.ip = htonl(ip);
150         }
151         for (; ip <= ip_to;) {
152                 ret = adtfn(set, &e, &ext, &ext, flags);
153                 if (ret && !ip_set_eexist(ret, flags))
154                         return ret;
155
156                 ip += hosts;
157                 e.ip = htonl(ip);
158                 if (e.ip == 0)
159                         return 0;
160
161                 ret = 0;
162         }
163         return ret;
164 }
165
166 /* IPv6 variant */
167
168 /* Member elements */
169 struct hash_ip6_elem {
170         union nf_inet_addr ip;
171 };
172
173 /* Common functions */
174
175 static bool
176 hash_ip6_data_equal(const struct hash_ip6_elem *ip1,
177                     const struct hash_ip6_elem *ip2,
178                     u32 *multi)
179 {
180         return ipv6_addr_equal(&ip1->ip.in6, &ip2->ip.in6);
181 }
182
183 static void
184 hash_ip6_netmask(union nf_inet_addr *ip, u8 prefix)
185 {
186         ip6_netmask(ip, prefix);
187 }
188
189 static bool
190 hash_ip6_data_list(struct sk_buff *skb, const struct hash_ip6_elem *e)
191 {
192         if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6))
193                 goto nla_put_failure;
194         return false;
195
196 nla_put_failure:
197         return true;
198 }
199
200 static void
201 hash_ip6_data_next(struct hash_ip6_elem *next, const struct hash_ip6_elem *e)
202 {
203 }
204
205 #undef MTYPE
206 #undef HOST_MASK
207
208 #define MTYPE           hash_ip6
209 #define HOST_MASK       128
210
211 #define IP_SET_EMIT_CREATE
212 #include "ip_set_hash_gen.h"
213
214 static int
215 hash_ip6_kadt(struct ip_set *set, const struct sk_buff *skb,
216               const struct xt_action_param *par,
217               enum ipset_adt adt, struct ip_set_adt_opt *opt)
218 {
219         const struct hash_ip6 *h = set->data;
220         ipset_adtfn adtfn = set->variant->adt[adt];
221         struct hash_ip6_elem e = { { .all = { 0 } } };
222         struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
223
224         ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
225         hash_ip6_netmask(&e.ip, h->netmask);
226         if (ipv6_addr_any(&e.ip.in6))
227                 return -EINVAL;
228
229         return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
230 }
231
232 static int
233 hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[],
234               enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
235 {
236         const struct hash_ip6 *h = set->data;
237         ipset_adtfn adtfn = set->variant->adt[adt];
238         struct hash_ip6_elem e = { { .all = { 0 } } };
239         struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
240         int ret;
241
242         if (tb[IPSET_ATTR_LINENO])
243                 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
244
245         if (unlikely(!tb[IPSET_ATTR_IP]))
246                 return -IPSET_ERR_PROTOCOL;
247         if (unlikely(tb[IPSET_ATTR_IP_TO]))
248                 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED;
249         if (unlikely(tb[IPSET_ATTR_CIDR])) {
250                 u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
251
252                 if (cidr != HOST_MASK)
253                         return -IPSET_ERR_INVALID_CIDR;
254         }
255
256         ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip);
257         if (ret)
258                 return ret;
259
260         ret = ip_set_get_extensions(set, tb, &ext);
261         if (ret)
262                 return ret;
263
264         hash_ip6_netmask(&e.ip, h->netmask);
265         if (ipv6_addr_any(&e.ip.in6))
266                 return -IPSET_ERR_HASH_ELEM;
267
268         ret = adtfn(set, &e, &ext, &ext, flags);
269
270         return ip_set_eexist(ret, flags) ? 0 : ret;
271 }
272
273 static struct ip_set_type hash_ip_type __read_mostly = {
274         .name           = "hash:ip",
275         .protocol       = IPSET_PROTOCOL,
276         .features       = IPSET_TYPE_IP,
277         .dimension      = IPSET_DIM_ONE,
278         .family         = NFPROTO_UNSPEC,
279         .revision_min   = IPSET_TYPE_REV_MIN,
280         .revision_max   = IPSET_TYPE_REV_MAX,
281         .create_flags[IPSET_TYPE_REV_MAX] = IPSET_CREATE_FLAG_BUCKETSIZE,
282         .create         = hash_ip_create,
283         .create_policy  = {
284                 [IPSET_ATTR_HASHSIZE]   = { .type = NLA_U32 },
285                 [IPSET_ATTR_MAXELEM]    = { .type = NLA_U32 },
286                 [IPSET_ATTR_INITVAL]    = { .type = NLA_U32 },
287                 [IPSET_ATTR_BUCKETSIZE] = { .type = NLA_U8 },
288                 [IPSET_ATTR_RESIZE]     = { .type = NLA_U8  },
289                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
290                 [IPSET_ATTR_NETMASK]    = { .type = NLA_U8  },
291                 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
292         },
293         .adt_policy     = {
294                 [IPSET_ATTR_IP]         = { .type = NLA_NESTED },
295                 [IPSET_ATTR_IP_TO]      = { .type = NLA_NESTED },
296                 [IPSET_ATTR_CIDR]       = { .type = NLA_U8 },
297                 [IPSET_ATTR_TIMEOUT]    = { .type = NLA_U32 },
298                 [IPSET_ATTR_LINENO]     = { .type = NLA_U32 },
299                 [IPSET_ATTR_BYTES]      = { .type = NLA_U64 },
300                 [IPSET_ATTR_PACKETS]    = { .type = NLA_U64 },
301                 [IPSET_ATTR_COMMENT]    = { .type = NLA_NUL_STRING,
302                                             .len  = IPSET_MAX_COMMENT_SIZE },
303                 [IPSET_ATTR_SKBMARK]    = { .type = NLA_U64 },
304                 [IPSET_ATTR_SKBPRIO]    = { .type = NLA_U32 },
305                 [IPSET_ATTR_SKBQUEUE]   = { .type = NLA_U16 },
306         },
307         .me             = THIS_MODULE,
308 };
309
310 static int __init
311 hash_ip_init(void)
312 {
313         return ip_set_type_register(&hash_ip_type);
314 }
315
316 static void __exit
317 hash_ip_fini(void)
318 {
319         rcu_barrier();
320         ip_set_type_unregister(&hash_ip_type);
321 }
322
323 module_init(hash_ip_init);
324 module_exit(hash_ip_fini);