aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/dst.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/dst.h')
-rw-r--r--include/net/dst.h213
1 files changed, 147 insertions, 66 deletions
diff --git a/include/net/dst.h b/include/net/dst.h
index 02386505033d..e12ddfb9eb16 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -16,13 +16,6 @@
16#include <net/neighbour.h> 16#include <net/neighbour.h>
17#include <asm/processor.h> 17#include <asm/processor.h>
18 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) 19#define DST_GC_MIN (HZ/10)
27#define DST_GC_INC (HZ/2) 20#define DST_GC_INC (HZ/2)
28#define DST_GC_MAX (120*HZ) 21#define DST_GC_MAX (120*HZ)
@@ -40,23 +33,10 @@ struct dst_entry {
40 struct rcu_head rcu_head; 33 struct rcu_head rcu_head;
41 struct dst_entry *child; 34 struct dst_entry *child;
42 struct net_device *dev; 35 struct net_device *dev;
43 short error; 36 struct dst_ops *ops;
44 short obsolete; 37 unsigned long _metrics;
45 int flags;
46#define DST_HOST 1
47#define DST_NOXFRM 2
48#define DST_NOPOLICY 4
49#define DST_NOHASH 8
50 unsigned long expires; 38 unsigned long expires;
51
52 unsigned short header_len; /* more space at head required */
53 unsigned short trailer_len; /* space to reserve at tail */
54
55 unsigned int rate_tokens;
56 unsigned long rate_last; /* rate limiting for ICMP */
57
58 struct dst_entry *path; 39 struct dst_entry *path;
59
60 struct neighbour *neighbour; 40 struct neighbour *neighbour;
61 struct hh_cache *hh; 41 struct hh_cache *hh;
62#ifdef CONFIG_XFRM 42#ifdef CONFIG_XFRM
@@ -67,17 +47,16 @@ struct dst_entry {
67 int (*input)(struct sk_buff*); 47 int (*input)(struct sk_buff*);
68 int (*output)(struct sk_buff*); 48 int (*output)(struct sk_buff*);
69 49
70 struct dst_ops *ops; 50 short error;
71 51 short obsolete;
72 u32 metrics[RTAX_MAX]; 52 unsigned short header_len; /* more space at head required */
73 53 unsigned short trailer_len; /* space to reserve at tail */
74#ifdef CONFIG_NET_CLS_ROUTE 54#ifdef CONFIG_IP_ROUTE_CLASSID
75 __u32 tclassid; 55 __u32 tclassid;
76#else 56#else
77 __u32 __pad2; 57 __u32 __pad2;
78#endif 58#endif
79 59
80
81 /* 60 /*
82 * Align __refcnt to a 64 bytes alignment 61 * Align __refcnt to a 64 bytes alignment
83 * (L1_CACHE_SIZE would be too much) 62 * (L1_CACHE_SIZE would be too much)
@@ -92,20 +71,115 @@ struct dst_entry {
92 atomic_t __refcnt; /* client references */ 71 atomic_t __refcnt; /* client references */
93 int __use; 72 int __use;
94 unsigned long lastuse; 73 unsigned long lastuse;
74 int flags;
75#define DST_HOST 0x0001
76#define DST_NOXFRM 0x0002
77#define DST_NOPOLICY 0x0004
78#define DST_NOHASH 0x0008
79#define DST_NOCACHE 0x0010
80#define DST_NOCOUNT 0x0020
95 union { 81 union {
96 struct dst_entry *next; 82 struct dst_entry *next;
97 struct rtable *rt_next; 83 struct rtable __rcu *rt_next;
98 struct rt6_info *rt6_next; 84 struct rt6_info *rt6_next;
99 struct dn_route *dn_next; 85 struct dn_route __rcu *dn_next;
100 }; 86 };
101}; 87};
102 88
103#ifdef __KERNEL__ 89extern u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old);
90extern const u32 dst_default_metrics[RTAX_MAX];
91
92#define DST_METRICS_READ_ONLY 0x1UL
93#define __DST_METRICS_PTR(Y) \
94 ((u32 *)((Y) & ~DST_METRICS_READ_ONLY))
95#define DST_METRICS_PTR(X) __DST_METRICS_PTR((X)->_metrics)
96
97static inline bool dst_metrics_read_only(const struct dst_entry *dst)
98{
99 return dst->_metrics & DST_METRICS_READ_ONLY;
100}
101
102extern void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old);
103
104static inline void dst_destroy_metrics_generic(struct dst_entry *dst)
105{
106 unsigned long val = dst->_metrics;
107 if (!(val & DST_METRICS_READ_ONLY))
108 __dst_destroy_metrics_generic(dst, val);
109}
110
111static inline u32 *dst_metrics_write_ptr(struct dst_entry *dst)
112{
113 unsigned long p = dst->_metrics;
114
115 BUG_ON(!p);
116
117 if (p & DST_METRICS_READ_ONLY)
118 return dst->ops->cow_metrics(dst, p);
119 return __DST_METRICS_PTR(p);
120}
121
122/* This may only be invoked before the entry has reached global
123 * visibility.
124 */
125static inline void dst_init_metrics(struct dst_entry *dst,
126 const u32 *src_metrics,
127 bool read_only)
128{
129 dst->_metrics = ((unsigned long) src_metrics) |
130 (read_only ? DST_METRICS_READ_ONLY : 0);
131}
132
133static inline void dst_copy_metrics(struct dst_entry *dest, const struct dst_entry *src)
134{
135 u32 *dst_metrics = dst_metrics_write_ptr(dest);
136
137 if (dst_metrics) {
138 u32 *src_metrics = DST_METRICS_PTR(src);
139
140 memcpy(dst_metrics, src_metrics, RTAX_MAX * sizeof(u32));
141 }
142}
143
144static inline u32 *dst_metrics_ptr(struct dst_entry *dst)
145{
146 return DST_METRICS_PTR(dst);
147}
148
149static inline u32
150dst_metric_raw(const struct dst_entry *dst, const int metric)
151{
152 u32 *p = DST_METRICS_PTR(dst);
153
154 return p[metric-1];
155}
156
157static inline u32
158dst_metric(const struct dst_entry *dst, const int metric)
159{
160 WARN_ON_ONCE(metric == RTAX_HOPLIMIT ||
161 metric == RTAX_ADVMSS ||
162 metric == RTAX_MTU);
163 return dst_metric_raw(dst, metric);
164}
104 165
105static inline u32 166static inline u32
106dst_metric(const struct dst_entry *dst, int metric) 167dst_metric_advmss(const struct dst_entry *dst)
107{ 168{
108 return dst->metrics[metric-1]; 169 u32 advmss = dst_metric_raw(dst, RTAX_ADVMSS);
170
171 if (!advmss)
172 advmss = dst->ops->default_advmss(dst);
173
174 return advmss;
175}
176
177static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val)
178{
179 u32 *p = dst_metrics_write_ptr(dst);
180
181 if (p)
182 p[metric-1] = val;
109} 183}
110 184
111static inline u32 185static inline u32
@@ -116,11 +190,11 @@ dst_feature(const struct dst_entry *dst, u32 feature)
116 190
117static inline u32 dst_mtu(const struct dst_entry *dst) 191static inline u32 dst_mtu(const struct dst_entry *dst)
118{ 192{
119 u32 mtu = dst_metric(dst, RTAX_MTU); 193 u32 mtu = dst_metric_raw(dst, RTAX_MTU);
120 /* 194
121 * Alexey put it here, so ask him about it :) 195 if (!mtu)
122 */ 196 mtu = dst->ops->default_mtu(dst);
123 barrier(); 197
124 return mtu; 198 return mtu;
125} 199}
126 200
@@ -133,20 +207,18 @@ static inline unsigned long dst_metric_rtt(const struct dst_entry *dst, int metr
133static inline void set_dst_metric_rtt(struct dst_entry *dst, int metric, 207static inline void set_dst_metric_rtt(struct dst_entry *dst, int metric,
134 unsigned long rtt) 208 unsigned long rtt)
135{ 209{
136 dst->metrics[metric-1] = jiffies_to_msecs(rtt); 210 dst_metric_set(dst, metric, jiffies_to_msecs(rtt));
137} 211}
138 212
139static inline u32 213static inline u32
140dst_allfrag(const struct dst_entry *dst) 214dst_allfrag(const struct dst_entry *dst)
141{ 215{
142 int ret = dst_feature(dst, RTAX_FEATURE_ALLFRAG); 216 int ret = dst_feature(dst, RTAX_FEATURE_ALLFRAG);
143 /* Yes, _exactly_. This is paranoia. */
144 barrier();
145 return ret; 217 return ret;
146} 218}
147 219
148static inline int 220static inline int
149dst_metric_locked(struct dst_entry *dst, int metric) 221dst_metric_locked(const struct dst_entry *dst, int metric)
150{ 222{
151 return dst_metric(dst, RTAX_LOCK) & (1<<metric); 223 return dst_metric(dst, RTAX_LOCK) & (1<<metric);
152} 224}
@@ -228,23 +300,37 @@ static inline void skb_dst_force(struct sk_buff *skb)
228 300
229 301
230/** 302/**
303 * __skb_tunnel_rx - prepare skb for rx reinsert
304 * @skb: buffer
305 * @dev: tunnel device
306 *
307 * After decapsulation, packet is going to re-enter (netif_rx()) our stack,
308 * so make some cleanups. (no accounting done)
309 */
310static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
311{
312 skb->dev = dev;
313 skb->rxhash = 0;
314 skb_set_queue_mapping(skb, 0);
315 skb_dst_drop(skb);
316 nf_reset(skb);
317}
318
319/**
231 * skb_tunnel_rx - prepare skb for rx reinsert 320 * skb_tunnel_rx - prepare skb for rx reinsert
232 * @skb: buffer 321 * @skb: buffer
233 * @dev: tunnel device 322 * @dev: tunnel device
234 * 323 *
235 * After decapsulation, packet is going to re-enter (netif_rx()) our stack, 324 * After decapsulation, packet is going to re-enter (netif_rx()) our stack,
236 * so make some cleanups, and perform accounting. 325 * so make some cleanups, and perform accounting.
326 * Note: this accounting is not SMP safe.
237 */ 327 */
238static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev) 328static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
239{ 329{
240 skb->dev = dev;
241 /* TODO : stats should be SMP safe */ 330 /* TODO : stats should be SMP safe */
242 dev->stats.rx_packets++; 331 dev->stats.rx_packets++;
243 dev->stats.rx_bytes += skb->len; 332 dev->stats.rx_bytes += skb->len;
244 skb->rxhash = 0; 333 __skb_tunnel_rx(skb, dev);
245 skb_set_queue_mapping(skb, 0);
246 skb_dst_drop(skb);
247 nf_reset(skb);
248} 334}
249 335
250/* Children define the path of the packet through the 336/* Children define the path of the packet through the
@@ -253,14 +339,15 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
253 339
254static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb) 340static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
255{ 341{
256 struct dst_entry *child = skb_dst(skb)->child; 342 struct dst_entry *child = dst_clone(skb_dst(skb)->child);
257 343
258 skb_dst_drop(skb); 344 skb_dst_drop(skb);
259 return child; 345 return child;
260} 346}
261 347
262extern int dst_discard(struct sk_buff *skb); 348extern int dst_discard(struct sk_buff *skb);
263extern void * dst_alloc(struct dst_ops * ops); 349extern void *dst_alloc(struct dst_ops * ops, struct net_device *dev,
350 int initial_ref, int initial_obsolete, int flags);
264extern void __dst_free(struct dst_entry * dst); 351extern void __dst_free(struct dst_entry * dst);
265extern struct dst_entry *dst_destroy(struct dst_entry * dst); 352extern struct dst_entry *dst_destroy(struct dst_entry * dst);
266 353
@@ -329,28 +416,22 @@ extern void dst_init(void);
329 416
330/* Flags for xfrm_lookup flags argument. */ 417/* Flags for xfrm_lookup flags argument. */
331enum { 418enum {
332 XFRM_LOOKUP_WAIT = 1 << 0, 419 XFRM_LOOKUP_ICMP = 1 << 0,
333 XFRM_LOOKUP_ICMP = 1 << 1,
334}; 420};
335 421
336struct flowi; 422struct flowi;
337#ifndef CONFIG_XFRM 423#ifndef CONFIG_XFRM
338static inline int xfrm_lookup(struct net *net, struct dst_entry **dst_p, 424static inline struct dst_entry *xfrm_lookup(struct net *net,
339 struct flowi *fl, struct sock *sk, int flags) 425 struct dst_entry *dst_orig,
426 const struct flowi *fl, struct sock *sk,
427 int flags)
340{ 428{
341 return 0; 429 return dst_orig;
342} 430}
343static inline int __xfrm_lookup(struct net *net, struct dst_entry **dst_p,
344 struct flowi *fl, struct sock *sk, int flags)
345{
346 return 0;
347}
348#else 431#else
349extern int xfrm_lookup(struct net *net, struct dst_entry **dst_p, 432extern struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
350 struct flowi *fl, struct sock *sk, int flags); 433 const struct flowi *fl, struct sock *sk,
351extern int __xfrm_lookup(struct net *net, struct dst_entry **dst_p, 434 int flags);
352 struct flowi *fl, struct sock *sk, int flags);
353#endif
354#endif 435#endif
355 436
356#endif /* _NET_DST_H */ 437#endif /* _NET_DST_H */