xref: /linux-6.15/include/net/dst_cache.h (revision 70d0bb45)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2911362c7SPaolo Abeni #ifndef _NET_DST_CACHE_H
3911362c7SPaolo Abeni #define _NET_DST_CACHE_H
4911362c7SPaolo Abeni 
5911362c7SPaolo Abeni #include <linux/jiffies.h>
6911362c7SPaolo Abeni #include <net/dst.h>
7911362c7SPaolo Abeni #if IS_ENABLED(CONFIG_IPV6)
8911362c7SPaolo Abeni #include <net/ip6_fib.h>
9911362c7SPaolo Abeni #endif
10911362c7SPaolo Abeni 
11911362c7SPaolo Abeni struct dst_cache {
12911362c7SPaolo Abeni 	struct dst_cache_pcpu __percpu *cache;
13911362c7SPaolo Abeni 	unsigned long reset_ts;
14911362c7SPaolo Abeni };
15911362c7SPaolo Abeni 
16911362c7SPaolo Abeni /**
17911362c7SPaolo Abeni  *	dst_cache_get - perform cache lookup
18911362c7SPaolo Abeni  *	@dst_cache: the cache
19911362c7SPaolo Abeni  *
20911362c7SPaolo Abeni  *	The caller should use dst_cache_get_ip4() if it need to retrieve the
21911362c7SPaolo Abeni  *	source address to be used when xmitting to the cached dst.
22911362c7SPaolo Abeni  *	local BH must be disabled.
23911362c7SPaolo Abeni  */
24911362c7SPaolo Abeni struct dst_entry *dst_cache_get(struct dst_cache *dst_cache);
25911362c7SPaolo Abeni 
26911362c7SPaolo Abeni /**
27911362c7SPaolo Abeni  *	dst_cache_get_ip4 - perform cache lookup and fetch ipv4 source address
28911362c7SPaolo Abeni  *	@dst_cache: the cache
29911362c7SPaolo Abeni  *	@saddr: return value for the retrieved source address
30911362c7SPaolo Abeni  *
31911362c7SPaolo Abeni  *	local BH must be disabled.
32911362c7SPaolo Abeni  */
33911362c7SPaolo Abeni struct rtable *dst_cache_get_ip4(struct dst_cache *dst_cache, __be32 *saddr);
34911362c7SPaolo Abeni 
35911362c7SPaolo Abeni /**
36911362c7SPaolo Abeni  *	dst_cache_set_ip4 - store the ipv4 dst into the cache
37911362c7SPaolo Abeni  *	@dst_cache: the cache
38911362c7SPaolo Abeni  *	@dst: the entry to be cached
39911362c7SPaolo Abeni  *	@saddr: the source address to be stored inside the cache
40911362c7SPaolo Abeni  *
41911362c7SPaolo Abeni  *	local BH must be disabled.
42911362c7SPaolo Abeni  */
43911362c7SPaolo Abeni void dst_cache_set_ip4(struct dst_cache *dst_cache, struct dst_entry *dst,
44911362c7SPaolo Abeni 		       __be32 saddr);
45911362c7SPaolo Abeni 
46911362c7SPaolo Abeni #if IS_ENABLED(CONFIG_IPV6)
47911362c7SPaolo Abeni 
48911362c7SPaolo Abeni /**
49911362c7SPaolo Abeni  *	dst_cache_set_ip6 - store the ipv6 dst into the cache
50911362c7SPaolo Abeni  *	@dst_cache: the cache
51911362c7SPaolo Abeni  *	@dst: the entry to be cached
52911362c7SPaolo Abeni  *	@saddr: the source address to be stored inside the cache
53911362c7SPaolo Abeni  *
54911362c7SPaolo Abeni  *	local BH must be disabled.
55911362c7SPaolo Abeni  */
56911362c7SPaolo Abeni void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst,
574c1342d9SJonathan Neuschäfer 		       const struct in6_addr *saddr);
58911362c7SPaolo Abeni 
59911362c7SPaolo Abeni /**
60911362c7SPaolo Abeni  *	dst_cache_get_ip6 - perform cache lookup and fetch ipv6 source address
61911362c7SPaolo Abeni  *	@dst_cache: the cache
62911362c7SPaolo Abeni  *	@saddr: return value for the retrieved source address
63911362c7SPaolo Abeni  *
64911362c7SPaolo Abeni  *	local BH must be disabled.
65911362c7SPaolo Abeni  */
66911362c7SPaolo Abeni struct dst_entry *dst_cache_get_ip6(struct dst_cache *dst_cache,
67911362c7SPaolo Abeni 				    struct in6_addr *saddr);
68911362c7SPaolo Abeni #endif
69911362c7SPaolo Abeni 
70911362c7SPaolo Abeni /**
71911362c7SPaolo Abeni  *	dst_cache_reset - invalidate the cache contents
72911362c7SPaolo Abeni  *	@dst_cache: the cache
73911362c7SPaolo Abeni  *
7476b12974SJonathan Neuschäfer  *	This does not free the cached dst to avoid races and contentions.
75911362c7SPaolo Abeni  *	the dst will be freed on later cache lookup.
76911362c7SPaolo Abeni  */
dst_cache_reset(struct dst_cache * dst_cache)77911362c7SPaolo Abeni static inline void dst_cache_reset(struct dst_cache *dst_cache)
78911362c7SPaolo Abeni {
793b09b2bdSEric Dumazet 	WRITE_ONCE(dst_cache->reset_ts, jiffies);
80911362c7SPaolo Abeni }
81911362c7SPaolo Abeni 
82911362c7SPaolo Abeni /**
8320ae1d6aSJason A. Donenfeld  *	dst_cache_reset_now - invalidate the cache contents immediately
8420ae1d6aSJason A. Donenfeld  *	@dst_cache: the cache
8520ae1d6aSJason A. Donenfeld  *
8620ae1d6aSJason A. Donenfeld  *	The caller must be sure there are no concurrent users, as this frees
8720ae1d6aSJason A. Donenfeld  *	all dst_cache users immediately, rather than waiting for the next
8820ae1d6aSJason A. Donenfeld  *	per-cpu usage like dst_cache_reset does. Most callers should use the
8920ae1d6aSJason A. Donenfeld  *	higher speed lazily-freed dst_cache_reset function instead.
9020ae1d6aSJason A. Donenfeld  */
9120ae1d6aSJason A. Donenfeld void dst_cache_reset_now(struct dst_cache *dst_cache);
9220ae1d6aSJason A. Donenfeld 
9320ae1d6aSJason A. Donenfeld /**
94911362c7SPaolo Abeni  *	dst_cache_init - initialize the cache, allocating the required storage
95911362c7SPaolo Abeni  *	@dst_cache: the cache
96911362c7SPaolo Abeni  *	@gfp: allocation flags
97911362c7SPaolo Abeni  */
98911362c7SPaolo Abeni int dst_cache_init(struct dst_cache *dst_cache, gfp_t gfp);
99911362c7SPaolo Abeni 
100911362c7SPaolo Abeni /**
101911362c7SPaolo Abeni  *	dst_cache_destroy - empty the cache and free the allocated storage
102911362c7SPaolo Abeni  *	@dst_cache: the cache
103911362c7SPaolo Abeni  *
104911362c7SPaolo Abeni  *	No synchronization is enforced: it must be called only when the cache
105*70d0bb45SSimon Horman  *	is unused.
106911362c7SPaolo Abeni  */
107911362c7SPaolo Abeni void dst_cache_destroy(struct dst_cache *dst_cache);
108911362c7SPaolo Abeni 
109911362c7SPaolo Abeni #endif
110