Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  *      INETPEER - A storage for permanent information about peers
0004  *
0005  *  Authors:    Andrey V. Savochkin <saw@msu.ru>
0006  */
0007 
0008 #ifndef _NET_INETPEER_H
0009 #define _NET_INETPEER_H
0010 
0011 #include <linux/types.h>
0012 #include <linux/init.h>
0013 #include <linux/jiffies.h>
0014 #include <linux/spinlock.h>
0015 #include <linux/rtnetlink.h>
0016 #include <net/ipv6.h>
0017 #include <linux/atomic.h>
0018 
0019 /* IPv4 address key for cache lookups */
0020 struct ipv4_addr_key {
0021     __be32  addr;
0022     int vif;
0023 };
0024 
0025 #define INETPEER_MAXKEYSZ   (sizeof(struct in6_addr) / sizeof(u32))
0026 
0027 struct inetpeer_addr {
0028     union {
0029         struct ipv4_addr_key    a4;
0030         struct in6_addr     a6;
0031         u32         key[INETPEER_MAXKEYSZ];
0032     };
0033     __u16               family;
0034 };
0035 
0036 struct inet_peer {
0037     struct rb_node      rb_node;
0038     struct inetpeer_addr    daddr;
0039 
0040     u32         metrics[RTAX_MAX];
0041     u32         rate_tokens;    /* rate limiting for ICMP */
0042     u32         n_redirects;
0043     unsigned long       rate_last;
0044     /*
0045      * Once inet_peer is queued for deletion (refcnt == 0), following field
0046      * is not available: rid
0047      * We can share memory with rcu_head to help keep inet_peer small.
0048      */
0049     union {
0050         struct {
0051             atomic_t            rid;        /* Frag reception counter */
0052         };
0053         struct rcu_head         rcu;
0054     };
0055 
0056     /* following fields might be frequently dirtied */
0057     __u32           dtime;  /* the time of last use of not referenced entries */
0058     refcount_t      refcnt;
0059 };
0060 
0061 struct inet_peer_base {
0062     struct rb_root      rb_root;
0063     seqlock_t       lock;
0064     int         total;
0065 };
0066 
0067 void inet_peer_base_init(struct inet_peer_base *);
0068 
0069 void inet_initpeers(void) __init;
0070 
0071 #define INETPEER_METRICS_NEW    (~(u32) 0)
0072 
0073 static inline void inetpeer_set_addr_v4(struct inetpeer_addr *iaddr, __be32 ip)
0074 {
0075     iaddr->a4.addr = ip;
0076     iaddr->a4.vif = 0;
0077     iaddr->family = AF_INET;
0078 }
0079 
0080 static inline __be32 inetpeer_get_addr_v4(struct inetpeer_addr *iaddr)
0081 {
0082     return iaddr->a4.addr;
0083 }
0084 
0085 static inline void inetpeer_set_addr_v6(struct inetpeer_addr *iaddr,
0086                     struct in6_addr *in6)
0087 {
0088     iaddr->a6 = *in6;
0089     iaddr->family = AF_INET6;
0090 }
0091 
0092 static inline struct in6_addr *inetpeer_get_addr_v6(struct inetpeer_addr *iaddr)
0093 {
0094     return &iaddr->a6;
0095 }
0096 
0097 /* can be called with or without local BH being disabled */
0098 struct inet_peer *inet_getpeer(struct inet_peer_base *base,
0099                    const struct inetpeer_addr *daddr,
0100                    int create);
0101 
0102 static inline struct inet_peer *inet_getpeer_v4(struct inet_peer_base *base,
0103                         __be32 v4daddr,
0104                         int vif, int create)
0105 {
0106     struct inetpeer_addr daddr;
0107 
0108     daddr.a4.addr = v4daddr;
0109     daddr.a4.vif = vif;
0110     daddr.family = AF_INET;
0111     return inet_getpeer(base, &daddr, create);
0112 }
0113 
0114 static inline struct inet_peer *inet_getpeer_v6(struct inet_peer_base *base,
0115                         const struct in6_addr *v6daddr,
0116                         int create)
0117 {
0118     struct inetpeer_addr daddr;
0119 
0120     daddr.a6 = *v6daddr;
0121     daddr.family = AF_INET6;
0122     return inet_getpeer(base, &daddr, create);
0123 }
0124 
0125 static inline int inetpeer_addr_cmp(const struct inetpeer_addr *a,
0126                     const struct inetpeer_addr *b)
0127 {
0128     int i, n;
0129 
0130     if (a->family == AF_INET)
0131         n = sizeof(a->a4) / sizeof(u32);
0132     else
0133         n = sizeof(a->a6) / sizeof(u32);
0134 
0135     for (i = 0; i < n; i++) {
0136         if (a->key[i] == b->key[i])
0137             continue;
0138         if (a->key[i] < b->key[i])
0139             return -1;
0140         return 1;
0141     }
0142 
0143     return 0;
0144 }
0145 
0146 /* can be called from BH context or outside */
0147 void inet_putpeer(struct inet_peer *p);
0148 bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout);
0149 
0150 void inetpeer_invalidate_tree(struct inet_peer_base *);
0151 
0152 #endif /* _NET_INETPEER_H */