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 | ||
