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 <linux/config.h>
12#include <net/neighbour.h>
13
14/*
15 * 0 - no debugging messages
16 * 1 - rare events and bugs (default)
17 * 2 - trace mode.
18 */
19#define RT_CACHE_DEBUG		0
20
21#define DST_GC_MIN	(1*HZ)
22#define DST_GC_INC	(5*HZ)
23#define DST_GC_MAX	(120*HZ)
24
25struct sk_buff;
26
27struct dst_entry
28{
29	struct dst_entry        *next;
30	atomic_t		__refcnt;	/* client references	*/
31	int			__use;
32	struct net_device       *dev;
33	int			obsolete;
34	int			flags;
35#define DST_HOST		1
36	unsigned long		lastuse;
37	unsigned long		expires;
38
39	unsigned		mxlock;
40	unsigned		pmtu;
41	unsigned		window;
42	unsigned		rtt;
43	unsigned		rttvar;
44	unsigned		ssthresh;
45	unsigned		cwnd;
46	unsigned		advmss;
47	unsigned		reordering;
48
49	unsigned long		rate_last;	/* rate limiting for ICMP */
50	unsigned long		rate_tokens;
51
52	int			error;
53
54	struct neighbour	*neighbour;
55	struct hh_cache		*hh;
56
57	int			(*input)(struct sk_buff*);
58	int			(*output)(struct sk_buff*);
59
60#ifdef CONFIG_NET_CLS_ROUTE
61	__u32			tclassid;
62#endif
63
64	struct  dst_ops	        *ops;
65
66	char			info[0];
67};
68
69
70struct dst_ops
71{
72	unsigned short		family;
73	unsigned short		protocol;
74	unsigned		gc_thresh;
75
76	int			(*gc)(void);
77	struct dst_entry *	(*check)(struct dst_entry *, __u32 cookie);
78	struct dst_entry *	(*reroute)(struct dst_entry *,
79					   struct sk_buff *);
80	void			(*destroy)(struct dst_entry *);
81	struct dst_entry *	(*negative_advice)(struct dst_entry *);
82	void			(*link_failure)(struct sk_buff *);
83	int			entry_size;
84
85	atomic_t		entries;
86	kmem_cache_t 		*kmem_cachep;
87};
88
89#ifdef __KERNEL__
90
91static inline void dst_hold(struct dst_entry * dst)
92{
93	atomic_inc(&dst->__refcnt);
94}
95
96static inline
97struct dst_entry * dst_clone(struct dst_entry * dst)
98{
99	if (dst)
100		atomic_inc(&dst->__refcnt);
101	return dst;
102}
103
104static inline
105void dst_release(struct dst_entry * dst)
106{
107	if (dst)
108		atomic_dec(&dst->__refcnt);
109}
110
111extern void * dst_alloc(struct dst_ops * ops);
112extern void __dst_free(struct dst_entry * dst);
113extern void dst_destroy(struct dst_entry * dst);
114
115static inline
116void dst_free(struct dst_entry * dst)
117{
118	if (dst->obsolete > 1)
119		return;
120	if (!atomic_read(&dst->__refcnt)) {
121		dst_destroy(dst);
122		return;
123	}
124	__dst_free(dst);
125}
126
127static inline void dst_confirm(struct dst_entry *dst)
128{
129	if (dst)
130		neigh_confirm(dst->neighbour);
131}
132
133static inline void dst_negative_advice(struct dst_entry **dst_p)
134{
135	struct dst_entry * dst = *dst_p;
136	if (dst && dst->ops->negative_advice)
137		*dst_p = dst->ops->negative_advice(dst);
138}
139
140static inline void dst_link_failure(struct sk_buff *skb)
141{
142	struct dst_entry * dst = skb->dst;
143	if (dst && dst->ops && dst->ops->link_failure)
144		dst->ops->link_failure(skb);
145}
146
147static inline void dst_set_expires(struct dst_entry *dst, int timeout)
148{
149	unsigned long expires = jiffies + timeout;
150
151	if (expires == 0)
152		expires = 1;
153
154	if (dst->expires == 0 || (long)(dst->expires - expires) > 0)
155		dst->expires = expires;
156}
157
158extern void		dst_init(void);
159
160#endif
161
162#endif /* _NET_DST_H */
163