linux/include/net/dst.h
<<
>>
Prefs
   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/netdevice.h>
  12#include <linux/rtnetlink.h>
  13#include <linux/rcupdate.h>
  14#include <linux/jiffies.h>
  15#include <net/neighbour.h>
  16#include <asm/processor.h>
  17
  18/*
  19 * 0 - no debugging messages
  20 * 1 - rare events and bugs (default)
  21 * 2 - trace mode.
  22 */
  23#define RT_CACHE_DEBUG          0
  24
  25#define DST_GC_MIN      (HZ/10)
  26#define DST_GC_INC      (HZ/2)
  27#define DST_GC_MAX      (120*HZ)
  28
  29/* Each dst_entry has reference count and sits in some parent list(s).
  30 * When it is removed from parent list, it is "freed" (dst_free).
  31 * After this it enters dead state (dst->obsolete > 0) and if its refcnt
  32 * is zero, it can be destroyed immediately, otherwise it is added
  33 * to gc list and garbage collector periodically checks the refcnt.
  34 */
  35
  36struct sk_buff;
  37
  38struct dst_entry
  39{
  40        struct rcu_head         rcu_head;
  41        struct dst_entry        *child;
  42        struct net_device       *dev;
  43        short                   error;
  44        short                   obsolete;
  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;
  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;
  59
  60        struct neighbour        *neighbour;
  61        struct hh_cache         *hh;
  62        struct xfrm_state       *xfrm;
  63
  64        int                     (*input)(struct sk_buff*);
  65        int                     (*output)(struct sk_buff*);
  66
  67        struct  dst_ops         *ops;
  68
  69        u32                     metrics[RTAX_MAX];
  70
  71#ifdef CONFIG_NET_CLS_ROUTE
  72        __u32                   tclassid;
  73#endif
  74
  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    *rt_next;
  85                struct rt6_info   *rt6_next;
  86                struct dn_route  *dn_next;
  87        };
  88};
  89
  90
  91struct dst_ops
  92{
  93        unsigned short          family;
  94        __be16                  protocol;
  95        unsigned                gc_thresh;
  96
  97        int                     (*gc)(struct dst_ops *ops);
  98        struct dst_entry *      (*check)(struct dst_entry *, __u32 cookie);
  99        void                    (*destroy)(struct dst_entry *);
 100        void                    (*ifdown)(struct dst_entry *,
 101                                          struct net_device *dev, int how);
 102        struct dst_entry *      (*negative_advice)(struct dst_entry *);
 103        void                    (*link_failure)(struct sk_buff *);
 104        void                    (*update_pmtu)(struct dst_entry *dst, u32 mtu);
 105        int                     (*local_out)(struct sk_buff *skb);
 106        int                     entry_size;
 107
 108        atomic_t                entries;
 109        struct kmem_cache               *kmem_cachep;
 110        struct net              *dst_net;
 111};
 112
 113#ifdef __KERNEL__
 114
 115static inline u32
 116dst_metric(const struct dst_entry *dst, int metric)
 117{
 118        return dst->metrics[metric-1];
 119}
 120
 121static inline u32 dst_mtu(const struct dst_entry *dst)
 122{
 123        u32 mtu = dst_metric(dst, RTAX_MTU);
 124        /*
 125         * Alexey put it here, so ask him about it :)
 126         */
 127        barrier();
 128        return mtu;
 129}
 130
 131/* RTT metrics are stored in milliseconds for user ABI, but used as jiffies */
 132static inline unsigned long dst_metric_rtt(const struct dst_entry *dst, int metric)
 133{
 134        return msecs_to_jiffies(dst_metric(dst, metric));
 135}
 136
 137static inline void set_dst_metric_rtt(struct dst_entry *dst, int metric,
 138                                      unsigned long rtt)
 139{
 140        dst->metrics[metric-1] = jiffies_to_msecs(rtt);
 141}
 142
 143static inline u32
 144dst_allfrag(const struct dst_entry *dst)
 145{
 146        int ret = dst_metric(dst, RTAX_FEATURES) & RTAX_FEATURE_ALLFRAG;
 147        /* Yes, _exactly_. This is paranoia. */
 148        barrier();
 149        return ret;
 150}
 151
 152static inline int
 153dst_metric_locked(struct dst_entry *dst, int metric)
 154{
 155        return dst_metric(dst, RTAX_LOCK) & (1<<metric);
 156}
 157
 158static inline void dst_hold(struct dst_entry * dst)
 159{
 160        atomic_inc(&dst->__refcnt);
 161}
 162
 163static inline void dst_use(struct dst_entry *dst, unsigned long time)
 164{
 165        dst_hold(dst);
 166        dst->__use++;
 167        dst->lastuse = time;
 168}
 169
 170static inline
 171struct dst_entry * dst_clone(struct dst_entry * dst)
 172{
 173        if (dst)
 174                atomic_inc(&dst->__refcnt);
 175        return dst;
 176}
 177
 178extern void dst_release(struct dst_entry *dst);
 179
 180/* Children define the path of the packet through the
 181 * Linux networking.  Thus, destinations are stackable.
 182 */
 183
 184static inline struct dst_entry *dst_pop(struct dst_entry *dst)
 185{
 186        struct dst_entry *child = dst_clone(dst->child);
 187
 188        dst_release(dst);
 189        return child;
 190}
 191
 192extern int dst_discard(struct sk_buff *skb);
 193extern void * dst_alloc(struct dst_ops * ops);
 194extern void __dst_free(struct dst_entry * dst);
 195extern struct dst_entry *dst_destroy(struct dst_entry * dst);
 196
 197static inline void dst_free(struct dst_entry * dst)
 198{
 199        if (dst->obsolete > 1)
 200                return;
 201        if (!atomic_read(&dst->__refcnt)) {
 202                dst = dst_destroy(dst);
 203                if (!dst)
 204                        return;
 205        }
 206        __dst_free(dst);
 207}
 208
 209static inline void dst_rcu_free(struct rcu_head *head)
 210{
 211        struct dst_entry *dst = container_of(head, struct dst_entry, rcu_head);
 212        dst_free(dst);
 213}
 214
 215static inline void dst_confirm(struct dst_entry *dst)
 216{
 217        if (dst)
 218                neigh_confirm(dst->neighbour);
 219}
 220
 221static inline void dst_negative_advice(struct dst_entry **dst_p)
 222{
 223        struct dst_entry * dst = *dst_p;
 224        if (dst && dst->ops->negative_advice)
 225                *dst_p = dst->ops->negative_advice(dst);
 226}
 227
 228static inline void dst_link_failure(struct sk_buff *skb)
 229{
 230        struct dst_entry * dst = skb->dst;
 231        if (dst && dst->ops && dst->ops->link_failure)
 232                dst->ops->link_failure(skb);
 233}
 234
 235static inline void dst_set_expires(struct dst_entry *dst, int timeout)
 236{
 237        unsigned long expires = jiffies + timeout;
 238
 239        if (expires == 0)
 240                expires = 1;
 241
 242        if (dst->expires == 0 || time_before(expires, dst->expires))
 243                dst->expires = expires;
 244}
 245
 246/* Output packet to network from transport.  */
 247static inline int dst_output(struct sk_buff *skb)
 248{
 249        return skb->dst->output(skb);
 250}
 251
 252/* Input packet from network to transport.  */
 253static inline int dst_input(struct sk_buff *skb)
 254{
 255        return skb->dst->input(skb);
 256}
 257
 258static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
 259{
 260        if (dst->obsolete)
 261                dst = dst->ops->check(dst, cookie);
 262        return dst;
 263}
 264
 265extern void             dst_init(void);
 266
 267/* Flags for xfrm_lookup flags argument. */
 268enum {
 269        XFRM_LOOKUP_WAIT = 1 << 0,
 270        XFRM_LOOKUP_ICMP = 1 << 1,
 271};
 272
 273struct flowi;
 274#ifndef CONFIG_XFRM
 275static inline int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
 276                       struct sock *sk, int flags)
 277{
 278        return 0;
 279} 
 280static inline int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
 281                                struct sock *sk, int flags)
 282{
 283        return 0;
 284}
 285#else
 286extern int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
 287                       struct sock *sk, int flags);
 288extern int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
 289                         struct sock *sk, int flags);
 290#endif
 291#endif
 292
 293#endif /* _NET_DST_H */
 294
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.