~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/include/net/dst.h

Version: ~ [ linux-5.6-rc3 ] ~ [ linux-5.5.6 ] ~ [ linux-5.4.22 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.106 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.171 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.214 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.214 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.82 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp