compat: Backport 'dst' functions.
authorJoe Stringer <joestringer@nicira.com>
Thu, 3 Dec 2015 07:53:40 +0000 (23:53 -0800)
committerJoe Stringer <joe@ovn.org>
Fri, 4 Dec 2015 01:08:16 +0000 (17:08 -0800)
Signed-off-by: Joe Stringer <joestringer@nicira.com>
Acked-by: Pravin B Shelar <pshelar@nicira.com>
acinclude.m4
datapath/linux/compat/include/net/dst.h

index a3dd3eb..da1d397 100644 (file)
@@ -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])
index 9d9e616..de74c93 100644 (file)
@@ -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