From: Joe Stringer <joestrin...@nicira.com>

Signed-off-by: Joe Stringer <joestrin...@nicira.com>
---
 acinclude.m4                            |  2 +
 datapath/linux/compat/include/net/dst.h | 78 +++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)

diff --git a/acinclude.m4 b/acinclude.m4
index a3dd3eb99bbd..da1d39704c7b 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -450,6 +450,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
   OVS_GREP_IFELSE([$KSRC/include/net/checksum.h], [csum_replace4])
   OVS_GREP_IFELSE([$KSRC/include/net/checksum.h], [csum_unfold])
 
+  OVS_GREP_IFELSE([$KSRC/include/net/dst.h], [dst_discard_sk])
+
   OVS_GREP_IFELSE([$KSRC/include/net/genetlink.h], [genl_has_listeners])
   OVS_GREP_IFELSE([$KSRC/include/net/genetlink.h], [mcgrp_offset])
   OVS_GREP_IFELSE([$KSRC/include/net/genetlink.h], [parallel_ops])
diff --git a/datapath/linux/compat/include/net/dst.h 
b/datapath/linux/compat/include/net/dst.h
index 9d9e6160351d..de74c9383b8b 100644
--- a/datapath/linux/compat/include/net/dst.h
+++ b/datapath/linux/compat/include/net/dst.h
@@ -22,4 +22,82 @@ static inline void skb_dst_drop(struct sk_buff *skb)
 
 #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  LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0)
+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
-- 
2.1.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to