From ace9429bb58fd418f0c81d4c2835699bddf6bde6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:27:49 +0200 Subject: Adding upstream version 6.6.15. Signed-off-by: Daniel Baumann --- include/net/inetpeer.h | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 include/net/inetpeer.h (limited to 'include/net/inetpeer.h') diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h new file mode 100644 index 000000000..74ff68856 --- /dev/null +++ b/include/net/inetpeer.h @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * INETPEER - A storage for permanent information about peers + * + * Authors: Andrey V. Savochkin + */ + +#ifndef _NET_INETPEER_H +#define _NET_INETPEER_H + +#include +#include +#include +#include +#include +#include +#include + +/* IPv4 address key for cache lookups */ +struct ipv4_addr_key { + __be32 addr; + int vif; +}; + +#define INETPEER_MAXKEYSZ (sizeof(struct in6_addr) / sizeof(u32)) + +struct inetpeer_addr { + union { + struct ipv4_addr_key a4; + struct in6_addr a6; + u32 key[INETPEER_MAXKEYSZ]; + }; + __u16 family; +}; + +struct inet_peer { + struct rb_node rb_node; + struct inetpeer_addr daddr; + + u32 metrics[RTAX_MAX]; + u32 rate_tokens; /* rate limiting for ICMP */ + u32 n_redirects; + unsigned long rate_last; + /* + * Once inet_peer is queued for deletion (refcnt == 0), following field + * is not available: rid + * We can share memory with rcu_head to help keep inet_peer small. + */ + union { + struct { + atomic_t rid; /* Frag reception counter */ + }; + struct rcu_head rcu; + }; + + /* following fields might be frequently dirtied */ + __u32 dtime; /* the time of last use of not referenced entries */ + refcount_t refcnt; +}; + +struct inet_peer_base { + struct rb_root rb_root; + seqlock_t lock; + int total; +}; + +void inet_peer_base_init(struct inet_peer_base *); + +void inet_initpeers(void) __init; + +#define INETPEER_METRICS_NEW (~(u32) 0) + +static inline void inetpeer_set_addr_v4(struct inetpeer_addr *iaddr, __be32 ip) +{ + iaddr->a4.addr = ip; + iaddr->a4.vif = 0; + iaddr->family = AF_INET; +} + +static inline __be32 inetpeer_get_addr_v4(struct inetpeer_addr *iaddr) +{ + return iaddr->a4.addr; +} + +static inline void inetpeer_set_addr_v6(struct inetpeer_addr *iaddr, + struct in6_addr *in6) +{ + iaddr->a6 = *in6; + iaddr->family = AF_INET6; +} + +static inline struct in6_addr *inetpeer_get_addr_v6(struct inetpeer_addr *iaddr) +{ + return &iaddr->a6; +} + +/* can be called with or without local BH being disabled */ +struct inet_peer *inet_getpeer(struct inet_peer_base *base, + const struct inetpeer_addr *daddr, + int create); + +static inline struct inet_peer *inet_getpeer_v4(struct inet_peer_base *base, + __be32 v4daddr, + int vif, int create) +{ + struct inetpeer_addr daddr; + + daddr.a4.addr = v4daddr; + daddr.a4.vif = vif; + daddr.family = AF_INET; + return inet_getpeer(base, &daddr, create); +} + +static inline struct inet_peer *inet_getpeer_v6(struct inet_peer_base *base, + const struct in6_addr *v6daddr, + int create) +{ + struct inetpeer_addr daddr; + + daddr.a6 = *v6daddr; + daddr.family = AF_INET6; + return inet_getpeer(base, &daddr, create); +} + +static inline int inetpeer_addr_cmp(const struct inetpeer_addr *a, + const struct inetpeer_addr *b) +{ + int i, n; + + if (a->family == AF_INET) + n = sizeof(a->a4) / sizeof(u32); + else + n = sizeof(a->a6) / sizeof(u32); + + for (i = 0; i < n; i++) { + if (a->key[i] == b->key[i]) + continue; + if (a->key[i] < b->key[i]) + return -1; + return 1; + } + + return 0; +} + +/* can be called from BH context or outside */ +void inet_putpeer(struct inet_peer *p); +bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout); + +void inetpeer_invalidate_tree(struct inet_peer_base *); + +#endif /* _NET_INETPEER_H */ -- cgit v1.2.3