xref: /openbmc/linux/drivers/net/wireguard/allowedips.h (revision 8be98d2f2a0a262f8bf8a0bc1fdf522b3c7aab17)
1e7096c13SJason A. Donenfeld /* SPDX-License-Identifier: GPL-2.0 */
2e7096c13SJason A. Donenfeld /*
3e7096c13SJason A. Donenfeld  * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4e7096c13SJason A. Donenfeld  */
5e7096c13SJason A. Donenfeld 
6e7096c13SJason A. Donenfeld #ifndef _WG_ALLOWEDIPS_H
7e7096c13SJason A. Donenfeld #define _WG_ALLOWEDIPS_H
8e7096c13SJason A. Donenfeld 
9e7096c13SJason A. Donenfeld #include <linux/mutex.h>
10e7096c13SJason A. Donenfeld #include <linux/ip.h>
11e7096c13SJason A. Donenfeld #include <linux/ipv6.h>
12e7096c13SJason A. Donenfeld 
13e7096c13SJason A. Donenfeld struct wg_peer;
14e7096c13SJason A. Donenfeld 
15e7096c13SJason A. Donenfeld struct allowedips_node {
16e7096c13SJason A. Donenfeld 	struct wg_peer __rcu *peer;
17e7096c13SJason A. Donenfeld 	struct allowedips_node __rcu *bit[2];
18e7096c13SJason A. Donenfeld 	u8 cidr, bit_at_a, bit_at_b, bitlen;
19f634f418SJason A. Donenfeld 	u8 bits[16] __aligned(__alignof(u64));
20e7096c13SJason A. Donenfeld 
21f634f418SJason A. Donenfeld 	/* Keep rarely used members at bottom to be beyond cache line. */
22*bf7b042dSJason A. Donenfeld 	unsigned long parent_bit_packed;
23e7096c13SJason A. Donenfeld 	union {
24e7096c13SJason A. Donenfeld 		struct list_head peer_list;
25e7096c13SJason A. Donenfeld 		struct rcu_head rcu;
26e7096c13SJason A. Donenfeld 	};
27e7096c13SJason A. Donenfeld };
28e7096c13SJason A. Donenfeld 
29e7096c13SJason A. Donenfeld struct allowedips {
30e7096c13SJason A. Donenfeld 	struct allowedips_node __rcu *root4;
31e7096c13SJason A. Donenfeld 	struct allowedips_node __rcu *root6;
32e7096c13SJason A. Donenfeld 	u64 seq;
33*bf7b042dSJason A. Donenfeld } __aligned(4); /* We pack the lower 2 bits of &root, but m68k only gives 16-bit alignment. */
34e7096c13SJason A. Donenfeld 
35e7096c13SJason A. Donenfeld void wg_allowedips_init(struct allowedips *table);
36e7096c13SJason A. Donenfeld void wg_allowedips_free(struct allowedips *table, struct mutex *mutex);
37e7096c13SJason A. Donenfeld int wg_allowedips_insert_v4(struct allowedips *table, const struct in_addr *ip,
38e7096c13SJason A. Donenfeld 			    u8 cidr, struct wg_peer *peer, struct mutex *lock);
39e7096c13SJason A. Donenfeld int wg_allowedips_insert_v6(struct allowedips *table, const struct in6_addr *ip,
40e7096c13SJason A. Donenfeld 			    u8 cidr, struct wg_peer *peer, struct mutex *lock);
41e7096c13SJason A. Donenfeld void wg_allowedips_remove_by_peer(struct allowedips *table,
42e7096c13SJason A. Donenfeld 				  struct wg_peer *peer, struct mutex *lock);
43e7096c13SJason A. Donenfeld /* The ip input pointer should be __aligned(__alignof(u64))) */
44e7096c13SJason A. Donenfeld int wg_allowedips_read_node(struct allowedips_node *node, u8 ip[16], u8 *cidr);
45e7096c13SJason A. Donenfeld 
46e7096c13SJason A. Donenfeld /* These return a strong reference to a peer: */
47e7096c13SJason A. Donenfeld struct wg_peer *wg_allowedips_lookup_dst(struct allowedips *table,
48e7096c13SJason A. Donenfeld 					 struct sk_buff *skb);
49e7096c13SJason A. Donenfeld struct wg_peer *wg_allowedips_lookup_src(struct allowedips *table,
50e7096c13SJason A. Donenfeld 					 struct sk_buff *skb);
51e7096c13SJason A. Donenfeld 
52e7096c13SJason A. Donenfeld #ifdef DEBUG
53e7096c13SJason A. Donenfeld bool wg_allowedips_selftest(void);
54e7096c13SJason A. Donenfeld #endif
55e7096c13SJason A. Donenfeld 
56dc680de2SJason A. Donenfeld int wg_allowedips_slab_init(void);
57dc680de2SJason A. Donenfeld void wg_allowedips_slab_uninit(void);
58dc680de2SJason A. Donenfeld 
59e7096c13SJason A. Donenfeld #endif /* _WG_ALLOWEDIPS_H */
60