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