xref: /openbmc/linux/include/net/dst.h (revision 4800cd83)
1 /*
2  * net/dst.h	Protocol independent destination cache definitions.
3  *
4  * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
5  *
6  */
7 
8 #ifndef _NET_DST_H
9 #define _NET_DST_H
10 
11 #include <net/dst_ops.h>
12 #include <linux/netdevice.h>
13 #include <linux/rtnetlink.h>
14 #include <linux/rcupdate.h>
15 #include <linux/jiffies.h>
16 #include <net/neighbour.h>
17 #include <asm/processor.h>
18 
19 /*
20  * 0 - no debugging messages
21  * 1 - rare events and bugs (default)
22  * 2 - trace mode.
23  */
24 #define RT_CACHE_DEBUG		0
25 
26 #define DST_GC_MIN	(HZ/10)
27 #define DST_GC_INC	(HZ/2)
28 #define DST_GC_MAX	(120*HZ)
29 
30 /* Each dst_entry has reference count and sits in some parent list(s).
31  * When it is removed from parent list, it is "freed" (dst_free).
32  * After this it enters dead state (dst->obsolete > 0) and if its refcnt
33  * is zero, it can be destroyed immediately, otherwise it is added
34  * to gc list and garbage collector periodically checks the refcnt.
35  */
36 
37 struct sk_buff;
38 
39 struct dst_entry {
40 	struct rcu_head		rcu_head;
41 	struct dst_entry	*child;
42 	struct net_device       *dev;
43 	short			error;
44 	short			obsolete;
45 	int			flags;
46 #define DST_HOST		0x0001
47 #define DST_NOXFRM		0x0002
48 #define DST_NOPOLICY		0x0004
49 #define DST_NOHASH		0x0008
50 #define DST_NOCACHE		0x0010
51 	unsigned long		expires;
52 
53 	unsigned short		header_len;	/* more space at head required */
54 	unsigned short		trailer_len;	/* space to reserve at tail */
55 
56 	unsigned int		rate_tokens;
57 	unsigned long		rate_last;	/* rate limiting for ICMP */
58 
59 	struct dst_entry	*path;
60 
61 	struct neighbour	*neighbour;
62 	struct hh_cache		*hh;
63 #ifdef CONFIG_XFRM
64 	struct xfrm_state	*xfrm;
65 #else
66 	void			*__pad1;
67 #endif
68 	int			(*input)(struct sk_buff*);
69 	int			(*output)(struct sk_buff*);
70 
71 	struct  dst_ops	        *ops;
72 
73 	u32			_metrics[RTAX_MAX];
74 
75 #ifdef CONFIG_NET_CLS_ROUTE
76 	__u32			tclassid;
77 #else
78 	__u32			__pad2;
79 #endif
80 
81 
82 	/*
83 	 * Align __refcnt to a 64 bytes alignment
84 	 * (L1_CACHE_SIZE would be too much)
85 	 */
86 #ifdef CONFIG_64BIT
87 	long			__pad_to_align_refcnt[1];
88 #endif
89 	/*
90 	 * __refcnt wants to be on a different cache line from
91 	 * input/output/ops or performance tanks badly
92 	 */
93 	atomic_t		__refcnt;	/* client references	*/
94 	int			__use;
95 	unsigned long		lastuse;
96 	union {
97 		struct dst_entry	*next;
98 		struct rtable __rcu	*rt_next;
99 		struct rt6_info		*rt6_next;
100 		struct dn_route __rcu	*dn_next;
101 	};
102 };
103 
104 #ifdef __KERNEL__
105 
106 static inline u32
107 dst_metric_raw(const struct dst_entry *dst, const int metric)
108 {
109 	return dst->_metrics[metric-1];
110 }
111 
112 static inline u32
113 dst_metric(const struct dst_entry *dst, const int metric)
114 {
115 	WARN_ON_ONCE(metric == RTAX_HOPLIMIT ||
116 		     metric == RTAX_ADVMSS ||
117 		     metric == RTAX_MTU);
118 	return dst_metric_raw(dst, metric);
119 }
120 
121 static inline u32
122 dst_metric_advmss(const struct dst_entry *dst)
123 {
124 	u32 advmss = dst_metric_raw(dst, RTAX_ADVMSS);
125 
126 	if (!advmss)
127 		advmss = dst->ops->default_advmss(dst);
128 
129 	return advmss;
130 }
131 
132 static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val)
133 {
134 	dst->_metrics[metric-1] = val;
135 }
136 
137 static inline void dst_import_metrics(struct dst_entry *dst, const u32 *src_metrics)
138 {
139 	memcpy(dst->_metrics, src_metrics, RTAX_MAX * sizeof(u32));
140 }
141 
142 static inline void dst_copy_metrics(struct dst_entry *dest, const struct dst_entry *src)
143 {
144 	dst_import_metrics(dest, src->_metrics);
145 }
146 
147 static inline u32 *dst_metrics_ptr(struct dst_entry *dst)
148 {
149 	return dst->_metrics;
150 }
151 
152 static inline u32
153 dst_feature(const struct dst_entry *dst, u32 feature)
154 {
155 	return dst_metric(dst, RTAX_FEATURES) & feature;
156 }
157 
158 static inline u32 dst_mtu(const struct dst_entry *dst)
159 {
160 	u32 mtu = dst_metric_raw(dst, RTAX_MTU);
161 
162 	if (!mtu)
163 		mtu = dst->ops->default_mtu(dst);
164 
165 	return mtu;
166 }
167 
168 /* RTT metrics are stored in milliseconds for user ABI, but used as jiffies */
169 static inline unsigned long dst_metric_rtt(const struct dst_entry *dst, int metric)
170 {
171 	return msecs_to_jiffies(dst_metric(dst, metric));
172 }
173 
174 static inline void set_dst_metric_rtt(struct dst_entry *dst, int metric,
175 				      unsigned long rtt)
176 {
177 	dst_metric_set(dst, metric, jiffies_to_msecs(rtt));
178 }
179 
180 static inline u32
181 dst_allfrag(const struct dst_entry *dst)
182 {
183 	int ret = dst_feature(dst,  RTAX_FEATURE_ALLFRAG);
184 	/* Yes, _exactly_. This is paranoia. */
185 	barrier();
186 	return ret;
187 }
188 
189 static inline int
190 dst_metric_locked(const struct dst_entry *dst, int metric)
191 {
192 	return dst_metric(dst, RTAX_LOCK) & (1<<metric);
193 }
194 
195 static inline void dst_hold(struct dst_entry * dst)
196 {
197 	/*
198 	 * If your kernel compilation stops here, please check
199 	 * __pad_to_align_refcnt declaration in struct dst_entry
200 	 */
201 	BUILD_BUG_ON(offsetof(struct dst_entry, __refcnt) & 63);
202 	atomic_inc(&dst->__refcnt);
203 }
204 
205 static inline void dst_use(struct dst_entry *dst, unsigned long time)
206 {
207 	dst_hold(dst);
208 	dst->__use++;
209 	dst->lastuse = time;
210 }
211 
212 static inline void dst_use_noref(struct dst_entry *dst, unsigned long time)
213 {
214 	dst->__use++;
215 	dst->lastuse = time;
216 }
217 
218 static inline
219 struct dst_entry * dst_clone(struct dst_entry * dst)
220 {
221 	if (dst)
222 		atomic_inc(&dst->__refcnt);
223 	return dst;
224 }
225 
226 extern void dst_release(struct dst_entry *dst);
227 
228 static inline void refdst_drop(unsigned long refdst)
229 {
230 	if (!(refdst & SKB_DST_NOREF))
231 		dst_release((struct dst_entry *)(refdst & SKB_DST_PTRMASK));
232 }
233 
234 /**
235  * skb_dst_drop - drops skb dst
236  * @skb: buffer
237  *
238  * Drops dst reference count if a reference was taken.
239  */
240 static inline void skb_dst_drop(struct sk_buff *skb)
241 {
242 	if (skb->_skb_refdst) {
243 		refdst_drop(skb->_skb_refdst);
244 		skb->_skb_refdst = 0UL;
245 	}
246 }
247 
248 static inline void skb_dst_copy(struct sk_buff *nskb, const struct sk_buff *oskb)
249 {
250 	nskb->_skb_refdst = oskb->_skb_refdst;
251 	if (!(nskb->_skb_refdst & SKB_DST_NOREF))
252 		dst_clone(skb_dst(nskb));
253 }
254 
255 /**
256  * skb_dst_force - makes sure skb dst is refcounted
257  * @skb: buffer
258  *
259  * If dst is not yet refcounted, let's do it
260  */
261 static inline void skb_dst_force(struct sk_buff *skb)
262 {
263 	if (skb_dst_is_noref(skb)) {
264 		WARN_ON(!rcu_read_lock_held());
265 		skb->_skb_refdst &= ~SKB_DST_NOREF;
266 		dst_clone(skb_dst(skb));
267 	}
268 }
269 
270 
271 /**
272  *	__skb_tunnel_rx - prepare skb for rx reinsert
273  *	@skb: buffer
274  *	@dev: tunnel device
275  *
276  *	After decapsulation, packet is going to re-enter (netif_rx()) our stack,
277  *	so make some cleanups. (no accounting done)
278  */
279 static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
280 {
281 	skb->dev = dev;
282 	skb->rxhash = 0;
283 	skb_set_queue_mapping(skb, 0);
284 	skb_dst_drop(skb);
285 	nf_reset(skb);
286 }
287 
288 /**
289  *	skb_tunnel_rx - prepare skb for rx reinsert
290  *	@skb: buffer
291  *	@dev: tunnel device
292  *
293  *	After decapsulation, packet is going to re-enter (netif_rx()) our stack,
294  *	so make some cleanups, and perform accounting.
295  *	Note: this accounting is not SMP safe.
296  */
297 static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
298 {
299 	/* TODO : stats should be SMP safe */
300 	dev->stats.rx_packets++;
301 	dev->stats.rx_bytes += skb->len;
302 	__skb_tunnel_rx(skb, dev);
303 }
304 
305 /* Children define the path of the packet through the
306  * Linux networking.  Thus, destinations are stackable.
307  */
308 
309 static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
310 {
311 	struct dst_entry *child = skb_dst(skb)->child;
312 
313 	skb_dst_drop(skb);
314 	return child;
315 }
316 
317 extern int dst_discard(struct sk_buff *skb);
318 extern void * dst_alloc(struct dst_ops * ops);
319 extern void __dst_free(struct dst_entry * dst);
320 extern struct dst_entry *dst_destroy(struct dst_entry * dst);
321 
322 static inline void dst_free(struct dst_entry * dst)
323 {
324 	if (dst->obsolete > 1)
325 		return;
326 	if (!atomic_read(&dst->__refcnt)) {
327 		dst = dst_destroy(dst);
328 		if (!dst)
329 			return;
330 	}
331 	__dst_free(dst);
332 }
333 
334 static inline void dst_rcu_free(struct rcu_head *head)
335 {
336 	struct dst_entry *dst = container_of(head, struct dst_entry, rcu_head);
337 	dst_free(dst);
338 }
339 
340 static inline void dst_confirm(struct dst_entry *dst)
341 {
342 	if (dst)
343 		neigh_confirm(dst->neighbour);
344 }
345 
346 static inline void dst_link_failure(struct sk_buff *skb)
347 {
348 	struct dst_entry *dst = skb_dst(skb);
349 	if (dst && dst->ops && dst->ops->link_failure)
350 		dst->ops->link_failure(skb);
351 }
352 
353 static inline void dst_set_expires(struct dst_entry *dst, int timeout)
354 {
355 	unsigned long expires = jiffies + timeout;
356 
357 	if (expires == 0)
358 		expires = 1;
359 
360 	if (dst->expires == 0 || time_before(expires, dst->expires))
361 		dst->expires = expires;
362 }
363 
364 /* Output packet to network from transport.  */
365 static inline int dst_output(struct sk_buff *skb)
366 {
367 	return skb_dst(skb)->output(skb);
368 }
369 
370 /* Input packet from network to transport.  */
371 static inline int dst_input(struct sk_buff *skb)
372 {
373 	return skb_dst(skb)->input(skb);
374 }
375 
376 static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
377 {
378 	if (dst->obsolete)
379 		dst = dst->ops->check(dst, cookie);
380 	return dst;
381 }
382 
383 extern void		dst_init(void);
384 
385 /* Flags for xfrm_lookup flags argument. */
386 enum {
387 	XFRM_LOOKUP_WAIT = 1 << 0,
388 	XFRM_LOOKUP_ICMP = 1 << 1,
389 };
390 
391 struct flowi;
392 #ifndef CONFIG_XFRM
393 static inline int xfrm_lookup(struct net *net, struct dst_entry **dst_p,
394 			      struct flowi *fl, struct sock *sk, int flags)
395 {
396 	return 0;
397 }
398 static inline int __xfrm_lookup(struct net *net, struct dst_entry **dst_p,
399 				struct flowi *fl, struct sock *sk, int flags)
400 {
401 	return 0;
402 }
403 #else
404 extern int xfrm_lookup(struct net *net, struct dst_entry **dst_p,
405 		       struct flowi *fl, struct sock *sk, int flags);
406 extern int __xfrm_lookup(struct net *net, struct dst_entry **dst_p,
407 			 struct flowi *fl, struct sock *sk, int flags);
408 #endif
409 #endif
410 
411 #endif /* _NET_DST_H */
412