aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/inetpeer.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/inetpeer.h')
-rw-r--r--include/net/inetpeer.h82
1 files changed, 76 insertions, 6 deletions
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index 2040bff945d4..c27c8f10ebdc 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -65,6 +65,69 @@ struct inet_peer {
65 atomic_t refcnt; 65 atomic_t refcnt;
66}; 66};
67 67
68struct inet_peer_base {
69 struct inet_peer __rcu *root;
70 seqlock_t lock;
71 u32 flush_seq;
72 int total;
73};
74
75#define INETPEER_BASE_BIT 0x1UL
76
77static inline struct inet_peer *inetpeer_ptr(unsigned long val)
78{
79 BUG_ON(val & INETPEER_BASE_BIT);
80 return (struct inet_peer *) val;
81}
82
83static inline struct inet_peer_base *inetpeer_base_ptr(unsigned long val)
84{
85 if (!(val & INETPEER_BASE_BIT))
86 return NULL;
87 val &= ~INETPEER_BASE_BIT;
88 return (struct inet_peer_base *) val;
89}
90
91static inline bool inetpeer_ptr_is_peer(unsigned long val)
92{
93 return !(val & INETPEER_BASE_BIT);
94}
95
96static inline void __inetpeer_ptr_set_peer(unsigned long *val, struct inet_peer *peer)
97{
98 /* This implicitly clears INETPEER_BASE_BIT */
99 *val = (unsigned long) peer;
100}
101
102static inline bool inetpeer_ptr_set_peer(unsigned long *ptr, struct inet_peer *peer)
103{
104 unsigned long val = (unsigned long) peer;
105 unsigned long orig = *ptr;
106
107 if (!(orig & INETPEER_BASE_BIT) ||
108 cmpxchg(ptr, orig, val) != orig)
109 return false;
110 return true;
111}
112
113static inline void inetpeer_init_ptr(unsigned long *ptr, struct inet_peer_base *base)
114{
115 *ptr = (unsigned long) base | INETPEER_BASE_BIT;
116}
117
118static inline void inetpeer_transfer_peer(unsigned long *to, unsigned long *from)
119{
120 unsigned long val = *from;
121
122 *to = val;
123 if (inetpeer_ptr_is_peer(val)) {
124 struct inet_peer *peer = inetpeer_ptr(val);
125 atomic_inc(&peer->refcnt);
126 }
127}
128
129extern void inet_peer_base_init(struct inet_peer_base *);
130
68void inet_initpeers(void) __init; 131void inet_initpeers(void) __init;
69 132
70#define INETPEER_METRICS_NEW (~(u32) 0) 133#define INETPEER_METRICS_NEW (~(u32) 0)
@@ -75,31 +138,38 @@ static inline bool inet_metrics_new(const struct inet_peer *p)
75} 138}
76 139
77/* can be called with or without local BH being disabled */ 140/* can be called with or without local BH being disabled */
78struct inet_peer *inet_getpeer(const struct inetpeer_addr *daddr, int create); 141struct inet_peer *inet_getpeer(struct inet_peer_base *base,
142 const struct inetpeer_addr *daddr,
143 int create);
79 144
80static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create) 145static inline struct inet_peer *inet_getpeer_v4(struct inet_peer_base *base,
146 __be32 v4daddr,
147 int create)
81{ 148{
82 struct inetpeer_addr daddr; 149 struct inetpeer_addr daddr;
83 150
84 daddr.addr.a4 = v4daddr; 151 daddr.addr.a4 = v4daddr;
85 daddr.family = AF_INET; 152 daddr.family = AF_INET;
86 return inet_getpeer(&daddr, create); 153 return inet_getpeer(base, &daddr, create);
87} 154}
88 155
89static inline struct inet_peer *inet_getpeer_v6(const struct in6_addr *v6daddr, int create) 156static inline struct inet_peer *inet_getpeer_v6(struct inet_peer_base *base,
157 const struct in6_addr *v6daddr,
158 int create)
90{ 159{
91 struct inetpeer_addr daddr; 160 struct inetpeer_addr daddr;
92 161
93 *(struct in6_addr *)daddr.addr.a6 = *v6daddr; 162 *(struct in6_addr *)daddr.addr.a6 = *v6daddr;
94 daddr.family = AF_INET6; 163 daddr.family = AF_INET6;
95 return inet_getpeer(&daddr, create); 164 return inet_getpeer(base, &daddr, create);
96} 165}
97 166
98/* can be called from BH context or outside */ 167/* can be called from BH context or outside */
99extern void inet_putpeer(struct inet_peer *p); 168extern void inet_putpeer(struct inet_peer *p);
100extern bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout); 169extern bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout);
101 170
102extern void inetpeer_invalidate_tree(int family); 171extern void inetpeer_invalidate_tree(struct inet_peer_base *);
172extern void inetpeer_invalidate_family(int family);
103 173
104/* 174/*
105 * temporary check to make sure we dont access rid, ip_id_count, tcp_ts, 175 * temporary check to make sure we dont access rid, ip_id_count, tcp_ts,