^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * INETPEER - A storage for permanent information about peers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Authors: Andrey V. Savochkin <saw@msu.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #ifndef _NET_INETPEER_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define _NET_INETPEER_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* IPv4 address key for cache lookups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct ipv4_addr_key {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) __be32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int vif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define INETPEER_MAXKEYSZ (sizeof(struct in6_addr) / sizeof(u32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct inetpeer_addr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct ipv4_addr_key a4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct in6_addr a6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) u32 key[INETPEER_MAXKEYSZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) __u16 family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct inet_peer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct rb_node rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct inetpeer_addr daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u32 metrics[RTAX_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) u32 rate_tokens; /* rate limiting for ICMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u32 n_redirects;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) unsigned long rate_last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * Once inet_peer is queued for deletion (refcnt == 0), following field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * is not available: rid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * We can share memory with rcu_head to help keep inet_peer small.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) atomic_t rid; /* Frag reception counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct rcu_head rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* following fields might be frequently dirtied */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) __u32 dtime; /* the time of last use of not referenced entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) refcount_t refcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct inet_peer_base {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct rb_root rb_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) seqlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) void inet_peer_base_init(struct inet_peer_base *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) void inet_initpeers(void) __init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define INETPEER_METRICS_NEW (~(u32) 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static inline void inetpeer_set_addr_v4(struct inetpeer_addr *iaddr, __be32 ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) iaddr->a4.addr = ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) iaddr->a4.vif = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) iaddr->family = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static inline __be32 inetpeer_get_addr_v4(struct inetpeer_addr *iaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return iaddr->a4.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static inline void inetpeer_set_addr_v6(struct inetpeer_addr *iaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct in6_addr *in6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) iaddr->a6 = *in6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) iaddr->family = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static inline struct in6_addr *inetpeer_get_addr_v6(struct inetpeer_addr *iaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return &iaddr->a6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* can be called with or without local BH being disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct inet_peer *inet_getpeer(struct inet_peer_base *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) const struct inetpeer_addr *daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static inline struct inet_peer *inet_getpeer_v4(struct inet_peer_base *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) __be32 v4daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int vif, int create)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct inetpeer_addr daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) daddr.a4.addr = v4daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) daddr.a4.vif = vif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) daddr.family = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return inet_getpeer(base, &daddr, create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static inline struct inet_peer *inet_getpeer_v6(struct inet_peer_base *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) const struct in6_addr *v6daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int create)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct inetpeer_addr daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) daddr.a6 = *v6daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) daddr.family = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return inet_getpeer(base, &daddr, create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static inline int inetpeer_addr_cmp(const struct inetpeer_addr *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) const struct inetpeer_addr *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int i, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (a->family == AF_INET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) n = sizeof(a->a4) / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) n = sizeof(a->a6) / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) for (i = 0; i < n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (a->key[i] == b->key[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (a->key[i] < b->key[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* can be called from BH context or outside */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) void inet_putpeer(struct inet_peer *p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) void inetpeer_invalidate_tree(struct inet_peer_base *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #endif /* _NET_INETPEER_H */