diff options
Diffstat (limited to 'include/net/dst.h')
-rw-r--r-- | include/net/dst.h | 142 |
1 files changed, 87 insertions, 55 deletions
diff --git a/include/net/dst.h b/include/net/dst.h index 93b0310317be..2a46cbaef92d 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
@@ -40,24 +40,10 @@ struct dst_entry { | |||
40 | struct rcu_head rcu_head; | 40 | struct rcu_head rcu_head; |
41 | struct dst_entry *child; | 41 | struct dst_entry *child; |
42 | struct net_device *dev; | 42 | struct net_device *dev; |
43 | short error; | 43 | struct dst_ops *ops; |
44 | short obsolete; | 44 | unsigned long _metrics; |
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; | 45 | 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; | 46 | struct dst_entry *path; |
60 | |||
61 | struct neighbour *neighbour; | 47 | struct neighbour *neighbour; |
62 | struct hh_cache *hh; | 48 | struct hh_cache *hh; |
63 | #ifdef CONFIG_XFRM | 49 | #ifdef CONFIG_XFRM |
@@ -68,17 +54,16 @@ struct dst_entry { | |||
68 | int (*input)(struct sk_buff*); | 54 | int (*input)(struct sk_buff*); |
69 | int (*output)(struct sk_buff*); | 55 | int (*output)(struct sk_buff*); |
70 | 56 | ||
71 | struct dst_ops *ops; | 57 | short error; |
72 | 58 | short obsolete; | |
73 | u32 _metrics[RTAX_MAX]; | 59 | unsigned short header_len; /* more space at head required */ |
74 | 60 | unsigned short trailer_len; /* space to reserve at tail */ | |
75 | #ifdef CONFIG_NET_CLS_ROUTE | 61 | #ifdef CONFIG_IP_ROUTE_CLASSID |
76 | __u32 tclassid; | 62 | __u32 tclassid; |
77 | #else | 63 | #else |
78 | __u32 __pad2; | 64 | __u32 __pad2; |
79 | #endif | 65 | #endif |
80 | 66 | ||
81 | |||
82 | /* | 67 | /* |
83 | * Align __refcnt to a 64 bytes alignment | 68 | * Align __refcnt to a 64 bytes alignment |
84 | * (L1_CACHE_SIZE would be too much) | 69 | * (L1_CACHE_SIZE would be too much) |
@@ -93,6 +78,12 @@ struct dst_entry { | |||
93 | atomic_t __refcnt; /* client references */ | 78 | atomic_t __refcnt; /* client references */ |
94 | int __use; | 79 | int __use; |
95 | unsigned long lastuse; | 80 | unsigned long lastuse; |
81 | int flags; | ||
82 | #define DST_HOST 0x0001 | ||
83 | #define DST_NOXFRM 0x0002 | ||
84 | #define DST_NOPOLICY 0x0004 | ||
85 | #define DST_NOHASH 0x0008 | ||
86 | #define DST_NOCACHE 0x0010 | ||
96 | union { | 87 | union { |
97 | struct dst_entry *next; | 88 | struct dst_entry *next; |
98 | struct rtable __rcu *rt_next; | 89 | struct rtable __rcu *rt_next; |
@@ -103,10 +94,70 @@ struct dst_entry { | |||
103 | 94 | ||
104 | #ifdef __KERNEL__ | 95 | #ifdef __KERNEL__ |
105 | 96 | ||
97 | extern u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old); | ||
98 | extern const u32 dst_default_metrics[RTAX_MAX]; | ||
99 | |||
100 | #define DST_METRICS_READ_ONLY 0x1UL | ||
101 | #define __DST_METRICS_PTR(Y) \ | ||
102 | ((u32 *)((Y) & ~DST_METRICS_READ_ONLY)) | ||
103 | #define DST_METRICS_PTR(X) __DST_METRICS_PTR((X)->_metrics) | ||
104 | |||
105 | static inline bool dst_metrics_read_only(const struct dst_entry *dst) | ||
106 | { | ||
107 | return dst->_metrics & DST_METRICS_READ_ONLY; | ||
108 | } | ||
109 | |||
110 | extern void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old); | ||
111 | |||
112 | static inline void dst_destroy_metrics_generic(struct dst_entry *dst) | ||
113 | { | ||
114 | unsigned long val = dst->_metrics; | ||
115 | if (!(val & DST_METRICS_READ_ONLY)) | ||
116 | __dst_destroy_metrics_generic(dst, val); | ||
117 | } | ||
118 | |||
119 | static inline u32 *dst_metrics_write_ptr(struct dst_entry *dst) | ||
120 | { | ||
121 | unsigned long p = dst->_metrics; | ||
122 | |||
123 | if (p & DST_METRICS_READ_ONLY) | ||
124 | return dst->ops->cow_metrics(dst, p); | ||
125 | return __DST_METRICS_PTR(p); | ||
126 | } | ||
127 | |||
128 | /* This may only be invoked before the entry has reached global | ||
129 | * visibility. | ||
130 | */ | ||
131 | static inline void dst_init_metrics(struct dst_entry *dst, | ||
132 | const u32 *src_metrics, | ||
133 | bool read_only) | ||
134 | { | ||
135 | dst->_metrics = ((unsigned long) src_metrics) | | ||
136 | (read_only ? DST_METRICS_READ_ONLY : 0); | ||
137 | } | ||
138 | |||
139 | static inline void dst_copy_metrics(struct dst_entry *dest, const struct dst_entry *src) | ||
140 | { | ||
141 | u32 *dst_metrics = dst_metrics_write_ptr(dest); | ||
142 | |||
143 | if (dst_metrics) { | ||
144 | u32 *src_metrics = DST_METRICS_PTR(src); | ||
145 | |||
146 | memcpy(dst_metrics, src_metrics, RTAX_MAX * sizeof(u32)); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | static inline u32 *dst_metrics_ptr(struct dst_entry *dst) | ||
151 | { | ||
152 | return DST_METRICS_PTR(dst); | ||
153 | } | ||
154 | |||
106 | static inline u32 | 155 | static inline u32 |
107 | dst_metric_raw(const struct dst_entry *dst, const int metric) | 156 | dst_metric_raw(const struct dst_entry *dst, const int metric) |
108 | { | 157 | { |
109 | return dst->_metrics[metric-1]; | 158 | u32 *p = DST_METRICS_PTR(dst); |
159 | |||
160 | return p[metric-1]; | ||
110 | } | 161 | } |
111 | 162 | ||
112 | static inline u32 | 163 | static inline u32 |
@@ -131,22 +182,10 @@ dst_metric_advmss(const struct dst_entry *dst) | |||
131 | 182 | ||
132 | static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val) | 183 | static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val) |
133 | { | 184 | { |
134 | dst->_metrics[metric-1] = val; | 185 | u32 *p = dst_metrics_write_ptr(dst); |
135 | } | ||
136 | 186 | ||
137 | static inline void dst_import_metrics(struct dst_entry *dst, const u32 *src_metrics) | 187 | if (p) |
138 | { | 188 | p[metric-1] = val; |
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 | } | 189 | } |
151 | 190 | ||
152 | static inline u32 | 191 | static inline u32 |
@@ -181,8 +220,6 @@ static inline u32 | |||
181 | dst_allfrag(const struct dst_entry *dst) | 220 | dst_allfrag(const struct dst_entry *dst) |
182 | { | 221 | { |
183 | int ret = dst_feature(dst, RTAX_FEATURE_ALLFRAG); | 222 | int ret = dst_feature(dst, RTAX_FEATURE_ALLFRAG); |
184 | /* Yes, _exactly_. This is paranoia. */ | ||
185 | barrier(); | ||
186 | return ret; | 223 | return ret; |
187 | } | 224 | } |
188 | 225 | ||
@@ -315,7 +352,7 @@ static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb) | |||
315 | } | 352 | } |
316 | 353 | ||
317 | extern int dst_discard(struct sk_buff *skb); | 354 | extern int dst_discard(struct sk_buff *skb); |
318 | extern void * dst_alloc(struct dst_ops * ops); | 355 | extern void *dst_alloc(struct dst_ops * ops, int initial_ref); |
319 | extern void __dst_free(struct dst_entry * dst); | 356 | extern void __dst_free(struct dst_entry * dst); |
320 | extern struct dst_entry *dst_destroy(struct dst_entry * dst); | 357 | extern struct dst_entry *dst_destroy(struct dst_entry * dst); |
321 | 358 | ||
@@ -384,27 +421,22 @@ extern void dst_init(void); | |||
384 | 421 | ||
385 | /* Flags for xfrm_lookup flags argument. */ | 422 | /* Flags for xfrm_lookup flags argument. */ |
386 | enum { | 423 | enum { |
387 | XFRM_LOOKUP_WAIT = 1 << 0, | 424 | XFRM_LOOKUP_ICMP = 1 << 0, |
388 | XFRM_LOOKUP_ICMP = 1 << 1, | ||
389 | }; | 425 | }; |
390 | 426 | ||
391 | struct flowi; | 427 | struct flowi; |
392 | #ifndef CONFIG_XFRM | 428 | #ifndef CONFIG_XFRM |
393 | static inline int xfrm_lookup(struct net *net, struct dst_entry **dst_p, | 429 | static inline struct dst_entry *xfrm_lookup(struct net *net, |
394 | struct flowi *fl, struct sock *sk, int flags) | 430 | struct dst_entry *dst_orig, |
431 | const struct flowi *fl, struct sock *sk, | ||
432 | int flags) | ||
395 | { | 433 | { |
396 | return 0; | 434 | return dst_orig; |
397 | } | 435 | } |
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 | 436 | #else |
404 | extern int xfrm_lookup(struct net *net, struct dst_entry **dst_p, | 437 | extern struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, |
405 | struct flowi *fl, struct sock *sk, int flags); | 438 | const struct flowi *fl, struct sock *sk, |
406 | extern int __xfrm_lookup(struct net *net, struct dst_entry **dst_p, | 439 | int flags); |
407 | struct flowi *fl, struct sock *sk, int flags); | ||
408 | #endif | 440 | #endif |
409 | #endif | 441 | #endif |
410 | 442 | ||