1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
#ifndef __NET_DST_WRAPPER_H
#define __NET_DST_WRAPPER_H 1
#include <linux/version.h>
#include_next <net/dst.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) && \
LINUX_VERSION_CODE > KERNEL_VERSION(3,0,20)
#define dst_get_neighbour_noref dst_get_neighbour
#endif
#ifndef HAVE_SKB_DST_ACCESSOR_FUNCS
static inline void skb_dst_drop(struct sk_buff *skb)
{
if (skb->dst)
dst_release(skb_dst(skb));
skb->dst = NULL;
}
#endif
#ifndef DST_OBSOLETE_NONE
#define DST_OBSOLETE_NONE 0
#endif
#ifndef DST_NOCOUNT
#define DST_NOCOUNT 0
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
static inline void __skb_dst_copy(struct sk_buff *nskb, unsigned long refdst)
{
nskb->_skb_dst = refdst;
dst_clone(skb_dst(nskb));
}
static inline void refdst_drop(unsigned long refdst) { }
static inline void skb_dst_set_noref(struct sk_buff *skb,
struct dst_entry *dst) { }
static inline void dst_init_metrics(struct dst_entry *dst, const u32 *metrics,
bool read_only) { }
#elif !defined(HAVE___SKB_DST_COPY)
static inline void __skb_dst_copy(struct sk_buff *nskb, unsigned long refdst)
{
nskb->_skb_refdst = refdst;
if (!(nskb->_skb_refdst & SKB_DST_NOREF))
dst_clone(skb_dst(nskb));
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
static inline void dst_entries_add(struct dst_ops *ops, int count)
{
atomic_add(count, &ops->entries);
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0)
static const u32 rpl_dst_default_metrics[RTAX_MAX + 1] = {
/* This initializer is needed to force linker to place this variable
* into const section. Otherwise it might end into bss section.
* We really want to avoid false sharing on this variable, and catch
* any writes on it.
*/
[RTAX_MAX] = 0xdeadbeef,
};
#define dst_default_metrics rpl_dst_default_metrics
static inline void rpl_dst_init(struct dst_entry *dst, struct dst_ops *ops,
struct net_device *dev, int initial_ref,
int initial_obsolete, unsigned short flags)
{
/* XXX: It's easier to handle compatibility by zeroing, as we can
* refer to fewer fields. Do that here.
*/
memset(dst, 0, sizeof *dst);
dst->dev = dev;
if (dev)
dev_hold(dev);
dst->ops = ops;
dst_init_metrics(dst, dst_default_metrics, true);
dst->path = dst;
dst->input = dst_discard;
#ifndef HAVE_DST_DISCARD_SK
dst->output = dst_discard;
#else
dst->output = dst_discard_sk;
#endif
dst->obsolete = initial_obsolete;
atomic_set(&dst->__refcnt, initial_ref);
dst->lastuse = jiffies;
dst->flags = flags;
if (!(flags & DST_NOCOUNT))
dst_entries_add(ops, 1);
}
#define dst_init rpl_dst_init
#endif
#endif
|