1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2011-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */
3 
4 /* Kernel module implementing an IP set type: the hash:net,iface 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 
16 #include <linux/netfilter.h>
17 #include <linux/netfilter_bridge.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    nomatch flag support added */
24 /*				2    /0 support added */
25 /*				3    Counters support added */
26 /*				4    Comments support added */
27 /*				5    Forceadd support added */
28 #define IPSET_TYPE_REV_MAX	6 /* skbinfo support added */
29 
30 MODULE_LICENSE("GPL");
31 MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>");
32 IP_SET_MODULE_DESC("hash:net,iface", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
33 MODULE_ALIAS("ip_set_hash:net,iface");
34 
35 /* Type specific function prefix */
36 #define HTYPE		hash_netiface
37 #define IP_SET_HASH_WITH_NETS
38 #define IP_SET_HASH_WITH_MULTI
39 #define IP_SET_HASH_WITH_NET0
40 
41 #define STRLCPY(a, b)	strlcpy(a, b, IFNAMSIZ)
42 
43 /* IPv4 variant */
44 
45 struct hash_netiface4_elem_hashed {
46 	__be32 ip;
47 	u8 physdev;
48 	u8 cidr;
49 	u8 nomatch;
50 	u8 elem;
51 };
52 
53 /* Member elements */
54 struct hash_netiface4_elem {
55 	__be32 ip;
56 	u8 physdev;
57 	u8 cidr;
58 	u8 nomatch;
59 	u8 elem;
60 	char iface[IFNAMSIZ];
61 };
62 
63 /* Common functions */
64 
65 static inline bool
66 hash_netiface4_data_equal(const struct hash_netiface4_elem *ip1,
67 			  const struct hash_netiface4_elem *ip2,
68 			  u32 *multi)
69 {
70 	return ip1->ip == ip2->ip &&
71 	       ip1->cidr == ip2->cidr &&
72 	       (++*multi) &&
73 	       ip1->physdev == ip2->physdev &&
74 	       strcmp(ip1->iface, ip2->iface) == 0;
75 }
76 
77 static inline int
78 hash_netiface4_do_data_match(const struct hash_netiface4_elem *elem)
79 {
80 	return elem->nomatch ? -ENOTEMPTY : 1;
81 }
82 
83 static inline void
84 hash_netiface4_data_set_flags(struct hash_netiface4_elem *elem, u32 flags)
85 {
86 	elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH;
87 }
88 
89 static inline void
90 hash_netiface4_data_reset_flags(struct hash_netiface4_elem *elem, u8 *flags)
91 {
92 	swap(*flags, elem->nomatch);
93 }
94 
95 static inline void
96 hash_netiface4_data_netmask(struct hash_netiface4_elem *elem, u8 cidr)
97 {
98 	elem->ip &= ip_set_netmask(cidr);
99 	elem->cidr = cidr;
100 }
101 
102 static bool
103 hash_netiface4_data_list(struct sk_buff *skb,
104 			 const struct hash_netiface4_elem *data)
105 {
106 	u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0;
107 
108 	if (data->nomatch)
109 		flags |= IPSET_FLAG_NOMATCH;
110 	if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
111 	    nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
112 	    nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) ||
113 	    (flags &&
114 	     nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
115 		goto nla_put_failure;
116 	return false;
117 
118 nla_put_failure:
119 	return true;
120 }
121 
122 static inline void
123 hash_netiface4_data_next(struct hash_netiface4_elem *next,
124 			 const struct hash_netiface4_elem *d)
125 {
126 	next->ip = d->ip;
127 }
128 
129 #define MTYPE		hash_netiface4
130 #define HOST_MASK	32
131 #define HKEY_DATALEN	sizeof(struct hash_netiface4_elem_hashed)
132 #include "ip_set_hash_gen.h"
133 
134 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
135 static const char *get_physindev_name(const struct sk_buff *skb)
136 {
137 	struct net_device *dev = nf_bridge_get_physindev(skb);
138 
139 	return dev ? dev->name : NULL;
140 }
141 
142 static const char *get_physoutdev_name(const struct sk_buff *skb)
143 {
144 	struct net_device *dev = nf_bridge_get_physoutdev(skb);
145 
146 	return dev ? dev->name : NULL;
147 }
148 #endif
149 
150 static int
151 hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
152 		    const struct xt_action_param *par,
153 		    enum ipset_adt adt, struct ip_set_adt_opt *opt)
154 {
155 	struct hash_netiface4 *h = set->data;
156 	ipset_adtfn adtfn = set->variant->adt[adt];
157 	struct hash_netiface4_elem e = {
158 		.cidr = INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
159 		.elem = 1,
160 	};
161 	struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
162 
163 	if (adt == IPSET_TEST)
164 		e.cidr = HOST_MASK;
165 
166 	ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
167 	e.ip &= ip_set_netmask(e.cidr);
168 
169 #define IFACE(dir)	(par->state->dir ? par->state->dir->name : "")
170 #define SRCDIR		(opt->flags & IPSET_DIM_TWO_SRC)
171 
172 	if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
173 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
174 		const char *eiface = SRCDIR ? get_physindev_name(skb) :
175 					      get_physoutdev_name(skb);
176 
177 		if (!eiface)
178 			return -EINVAL;
179 		STRLCPY(e.iface, eiface);
180 		e.physdev = 1;
181 #endif
182 	} else {
183 		STRLCPY(e.iface, SRCDIR ? IFACE(in) : IFACE(out));
184 	}
185 
186 	if (strlen(e.iface) == 0)
187 		return -EINVAL;
188 	return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
189 }
190 
191 static int
192 hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
193 		    enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
194 {
195 	struct hash_netiface4 *h = set->data;
196 	ipset_adtfn adtfn = set->variant->adt[adt];
197 	struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 };
198 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
199 	u32 ip = 0, ip_to = 0;
200 	int ret;
201 
202 	if (tb[IPSET_ATTR_LINENO])
203 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
204 
205 	if (unlikely(!tb[IPSET_ATTR_IP] ||
206 		     !tb[IPSET_ATTR_IFACE] ||
207 		     !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
208 		return -IPSET_ERR_PROTOCOL;
209 
210 	ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip);
211 	if (ret)
212 		return ret;
213 
214 	ret = ip_set_get_extensions(set, tb, &ext);
215 	if (ret)
216 		return ret;
217 
218 	if (tb[IPSET_ATTR_CIDR]) {
219 		e.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
220 		if (e.cidr > HOST_MASK)
221 			return -IPSET_ERR_INVALID_CIDR;
222 	}
223 	nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
224 
225 	if (tb[IPSET_ATTR_CADT_FLAGS]) {
226 		u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
227 
228 		if (cadt_flags & IPSET_FLAG_PHYSDEV)
229 			e.physdev = 1;
230 		if (cadt_flags & IPSET_FLAG_NOMATCH)
231 			flags |= (IPSET_FLAG_NOMATCH << 16);
232 	}
233 	if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) {
234 		e.ip = htonl(ip & ip_set_hostmask(e.cidr));
235 		ret = adtfn(set, &e, &ext, &ext, flags);
236 		return ip_set_enomatch(ret, flags, adt, set) ? -ret :
237 		       ip_set_eexist(ret, flags) ? 0 : ret;
238 	}
239 
240 	if (tb[IPSET_ATTR_IP_TO]) {
241 		ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
242 		if (ret)
243 			return ret;
244 		if (ip_to < ip)
245 			swap(ip, ip_to);
246 		if (ip + UINT_MAX == ip_to)
247 			return -IPSET_ERR_HASH_RANGE;
248 	} else {
249 		ip_set_mask_from_to(ip, ip_to, e.cidr);
250 	}
251 
252 	if (retried)
253 		ip = ntohl(h->next.ip);
254 	do {
255 		e.ip = htonl(ip);
256 		ip = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
257 		ret = adtfn(set, &e, &ext, &ext, flags);
258 
259 		if (ret && !ip_set_eexist(ret, flags))
260 			return ret;
261 
262 		ret = 0;
263 	} while (ip++ < ip_to);
264 	return ret;
265 }
266 
267 /* IPv6 variant */
268 
269 struct hash_netiface6_elem_hashed {
270 	union nf_inet_addr ip;
271 	u8 physdev;
272 	u8 cidr;
273 	u8 nomatch;
274 	u8 elem;
275 };
276 
277 struct hash_netiface6_elem {
278 	union nf_inet_addr ip;
279 	u8 physdev;
280 	u8 cidr;
281 	u8 nomatch;
282 	u8 elem;
283 	char iface[IFNAMSIZ];
284 };
285 
286 /* Common functions */
287 
288 static inline bool
289 hash_netiface6_data_equal(const struct hash_netiface6_elem *ip1,
290 			  const struct hash_netiface6_elem *ip2,
291 			  u32 *multi)
292 {
293 	return ipv6_addr_equal(&ip1->ip.in6, &ip2->ip.in6) &&
294 	       ip1->cidr == ip2->cidr &&
295 	       (++*multi) &&
296 	       ip1->physdev == ip2->physdev &&
297 	       strcmp(ip1->iface, ip2->iface) == 0;
298 }
299 
300 static inline int
301 hash_netiface6_do_data_match(const struct hash_netiface6_elem *elem)
302 {
303 	return elem->nomatch ? -ENOTEMPTY : 1;
304 }
305 
306 static inline void
307 hash_netiface6_data_set_flags(struct hash_netiface6_elem *elem, u32 flags)
308 {
309 	elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH;
310 }
311 
312 static inline void
313 hash_netiface6_data_reset_flags(struct hash_netiface6_elem *elem, u8 *flags)
314 {
315 	swap(*flags, elem->nomatch);
316 }
317 
318 static inline void
319 hash_netiface6_data_netmask(struct hash_netiface6_elem *elem, u8 cidr)
320 {
321 	ip6_netmask(&elem->ip, cidr);
322 	elem->cidr = cidr;
323 }
324 
325 static bool
326 hash_netiface6_data_list(struct sk_buff *skb,
327 			 const struct hash_netiface6_elem *data)
328 {
329 	u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0;
330 
331 	if (data->nomatch)
332 		flags |= IPSET_FLAG_NOMATCH;
333 	if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
334 	    nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
335 	    nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) ||
336 	    (flags &&
337 	     nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
338 		goto nla_put_failure;
339 	return false;
340 
341 nla_put_failure:
342 	return true;
343 }
344 
345 static inline void
346 hash_netiface6_data_next(struct hash_netiface6_elem *next,
347 			 const struct hash_netiface6_elem *d)
348 {
349 }
350 
351 #undef MTYPE
352 #undef HOST_MASK
353 
354 #define MTYPE		hash_netiface6
355 #define HOST_MASK	128
356 #define HKEY_DATALEN	sizeof(struct hash_netiface6_elem_hashed)
357 #define IP_SET_EMIT_CREATE
358 #include "ip_set_hash_gen.h"
359 
360 static int
361 hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,
362 		    const struct xt_action_param *par,
363 		    enum ipset_adt adt, struct ip_set_adt_opt *opt)
364 {
365 	struct hash_netiface6 *h = set->data;
366 	ipset_adtfn adtfn = set->variant->adt[adt];
367 	struct hash_netiface6_elem e = {
368 		.cidr = INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
369 		.elem = 1,
370 	};
371 	struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
372 
373 	if (adt == IPSET_TEST)
374 		e.cidr = HOST_MASK;
375 
376 	ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
377 	ip6_netmask(&e.ip, e.cidr);
378 
379 	if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
380 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
381 		const char *eiface = SRCDIR ? get_physindev_name(skb) :
382 					      get_physoutdev_name(skb);
383 
384 		if (!eiface)
385 			return -EINVAL;
386 		STRLCPY(e.iface, eiface);
387 		e.physdev = 1;
388 #endif
389 	} else {
390 		STRLCPY(e.iface, SRCDIR ? IFACE(in) : IFACE(out));
391 	}
392 
393 	if (strlen(e.iface) == 0)
394 		return -EINVAL;
395 
396 	return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
397 }
398 
399 static int
400 hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
401 		    enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
402 {
403 	ipset_adtfn adtfn = set->variant->adt[adt];
404 	struct hash_netiface6_elem e = { .cidr = HOST_MASK, .elem = 1 };
405 	struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
406 	int ret;
407 
408 	if (tb[IPSET_ATTR_LINENO])
409 		*lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
410 
411 	if (unlikely(!tb[IPSET_ATTR_IP] ||
412 		     !tb[IPSET_ATTR_IFACE] ||
413 		     !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
414 		return -IPSET_ERR_PROTOCOL;
415 	if (unlikely(tb[IPSET_ATTR_IP_TO]))
416 		return -IPSET_ERR_HASH_RANGE_UNSUPPORTED;
417 
418 	ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip);
419 	if (ret)
420 		return ret;
421 
422 	ret = ip_set_get_extensions(set, tb, &ext);
423 	if (ret)
424 		return ret;
425 
426 	if (tb[IPSET_ATTR_CIDR]) {
427 		e.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
428 		if (e.cidr > HOST_MASK)
429 			return -IPSET_ERR_INVALID_CIDR;
430 	}
431 
432 	ip6_netmask(&e.ip, e.cidr);
433 
434 	nla_strlcpy(e.iface, tb[IPSET_ATTR_IFACE], IFNAMSIZ);
435 
436 	if (tb[IPSET_ATTR_CADT_FLAGS]) {
437 		u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
438 
439 		if (cadt_flags & IPSET_FLAG_PHYSDEV)
440 			e.physdev = 1;
441 		if (cadt_flags & IPSET_FLAG_NOMATCH)
442 			flags |= (IPSET_FLAG_NOMATCH << 16);
443 	}
444 
445 	ret = adtfn(set, &e, &ext, &ext, flags);
446 
447 	return ip_set_enomatch(ret, flags, adt, set) ? -ret :
448 	       ip_set_eexist(ret, flags) ? 0 : ret;
449 }
450 
451 static struct ip_set_type hash_netiface_type __read_mostly = {
452 	.name		= "hash:net,iface",
453 	.protocol	= IPSET_PROTOCOL,
454 	.features	= IPSET_TYPE_IP | IPSET_TYPE_IFACE |
455 			  IPSET_TYPE_NOMATCH,
456 	.dimension	= IPSET_DIM_TWO,
457 	.family		= NFPROTO_UNSPEC,
458 	.revision_min	= IPSET_TYPE_REV_MIN,
459 	.revision_max	= IPSET_TYPE_REV_MAX,
460 	.create		= hash_netiface_create,
461 	.create_policy	= {
462 		[IPSET_ATTR_HASHSIZE]	= { .type = NLA_U32 },
463 		[IPSET_ATTR_MAXELEM]	= { .type = NLA_U32 },
464 		[IPSET_ATTR_PROBES]	= { .type = NLA_U8 },
465 		[IPSET_ATTR_RESIZE]	= { .type = NLA_U8  },
466 		[IPSET_ATTR_PROTO]	= { .type = NLA_U8 },
467 		[IPSET_ATTR_TIMEOUT]	= { .type = NLA_U32 },
468 		[IPSET_ATTR_CADT_FLAGS]	= { .type = NLA_U32 },
469 	},
470 	.adt_policy	= {
471 		[IPSET_ATTR_IP]		= { .type = NLA_NESTED },
472 		[IPSET_ATTR_IP_TO]	= { .type = NLA_NESTED },
473 		[IPSET_ATTR_IFACE]	= { .type = NLA_NUL_STRING,
474 					    .len  = IFNAMSIZ - 1 },
475 		[IPSET_ATTR_CADT_FLAGS]	= { .type = NLA_U32 },
476 		[IPSET_ATTR_CIDR]	= { .type = NLA_U8 },
477 		[IPSET_ATTR_TIMEOUT]	= { .type = NLA_U32 },
478 		[IPSET_ATTR_LINENO]	= { .type = NLA_U32 },
479 		[IPSET_ATTR_BYTES]	= { .type = NLA_U64 },
480 		[IPSET_ATTR_PACKETS]	= { .type = NLA_U64 },
481 		[IPSET_ATTR_COMMENT]	= { .type = NLA_NUL_STRING,
482 					    .len  = IPSET_MAX_COMMENT_SIZE },
483 		[IPSET_ATTR_SKBMARK]	= { .type = NLA_U64 },
484 		[IPSET_ATTR_SKBPRIO]	= { .type = NLA_U32 },
485 		[IPSET_ATTR_SKBQUEUE]	= { .type = NLA_U16 },
486 	},
487 	.me		= THIS_MODULE,
488 };
489 
490 static int __init
491 hash_netiface_init(void)
492 {
493 	return ip_set_type_register(&hash_netiface_type);
494 }
495 
496 static void __exit
497 hash_netiface_fini(void)
498 {
499 	rcu_barrier();
500 	ip_set_type_unregister(&hash_netiface_type);
501 }
502 
503 module_init(hash_netiface_init);
504 module_exit(hash_netiface_fini);
505