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