Make datapath compile with Xen kernel.
authorBen Pfaff <blp@nicira.com>
Tue, 30 Dec 2008 18:01:06 +0000 (10:01 -0800)
committerBen Pfaff <blp@nicira.com>
Tue, 30 Dec 2008 18:01:19 +0000 (10:01 -0800)
The Xen kernel is based on 2.6.18 but backports many features from later
kernels.  It is not always possible, therefore, to detect whether we need
to use compatibility code based on LINUX_VERSION_CODE.  This commit fixes
the problem by using configure-time tests to check for the need for the
compatibility code.

Build-tested on Linux 2.6.15 through 2.6.28 with the default configuration
(except that some kernels needed preemption turned off) and with Xen
kernel 2.6.18-92.1.10.el5.xs5.0.0.394.644.

Fixes bug #548.

acinclude.m4
datapath/linux-2.6/Kbuild.in
datapath/linux-2.6/Makefile.main.in
datapath/linux-2.6/compat-2.6/include/asm-generic/bug.h
datapath/linux-2.6/compat-2.6/include/linux/icmp.h
datapath/linux-2.6/compat-2.6/include/linux/if_arp.h
datapath/linux-2.6/compat-2.6/include/linux/ip.h
datapath/linux-2.6/compat-2.6/include/linux/ipv6.h
datapath/linux-2.6/compat-2.6/include/linux/skbuff.h
datapath/linux-2.6/compat-2.6/include/linux/tcp.h
datapath/linux-2.6/compat-2.6/include/linux/udp.h

index 0036ac1b3eb528b0cfe356d0e7de0a14eabd86d8..1380940efb587bd85d925d32f3dca6eee7a0069c 100644 (file)
@@ -1,3 +1,5 @@
+# -*- autoconf -*-
+
 # Copyright (c) 2008 The Board of Trustees of The Leland Stanford
 # Junior University
 #
@@ -61,10 +63,60 @@ AC_DEFUN([OFP_CHECK_LINUX], [
        ! test -e "$path"/include/linux/autoconf.h; then
        AC_MSG_ERROR([Linux kernel source in $path is not configured])
     fi
+    m4_if($3, [2.6], [OFP_CHECK_LINUX26_COMPAT])
   fi
   AM_CONDITIONAL($5, test -n "$path")
 ])
 
+dnl OFP_GREP_IFELSE(FILE, REGEX, IF-MATCH, IF-NO-MATCH)
+dnl
+dnl Greps FILE for REGEX.  If it matches, runs IF-MATCH, otherwise IF-NO-MATCH.
+AC_DEFUN([OFP_GREP_IFELSE], [
+  AC_MSG_CHECKING([whether $2 matches in $1])
+  grep '$2' $1 >/dev/null 2>&1
+  status=$?
+  case $status in
+    0) 
+      AC_MSG_RESULT([yes])
+      $3
+      ;;
+    1) 
+      AC_MSG_RESULT([no])
+      $4
+      ;;
+    *) 
+      AC_MSG_ERROR([grep exited with status $status]) 
+      ;;
+  esac
+])
+
+dnl OFP_DEFINE(NAME)
+dnl
+dnl Defines NAME to 1 in kcompat.h.
+AC_DEFUN([OFP_DEFINE], [
+  echo '#define $1 1' >> datapath/linux-2.6/kcompat.h.new
+])
+
+dnl OFP_CHECK_LINUX26_COMPAT
+dnl
+dnl Runs various Autoconf checks on the Linux 2.6 kernel source in
+dnl the directory in $KSRC26.
+AC_DEFUN([OFP_CHECK_LINUX26_COMPAT], [
+  rm -f datapath/linux-2.6/kcompat.h.new
+  mkdir -p datapath/linux-2.6
+  : > datapath/linux-2.6/kcompat.h.new
+  OFP_GREP_IFELSE([$KSRC26/include/linux/skbuff.h], [skb_transport_header],
+                  [OFP_DEFINE([HAVE_SKBUFF_HEADER_HELPERS])])
+  OFP_GREP_IFELSE([$KSRC26/include/linux/skbuff.h], [raw],
+                  [OFP_DEFINE([HAVE_MAC_RAW])])
+  if cmp -s datapath/linux-2.6/kcompat.h.new \
+            datapath/linux-2.6/kcompat.h >/dev/null 2>&1; then
+    rm datapath/linux-2.6/kcompat.h.new
+  else
+    mv datapath/linux-2.6/kcompat.h.new datapath/linux-2.6/kcompat.h
+  fi
+])
+
 dnl Checks for --enable-hw-tables and substitutes HW_TABLES to any
 dnl requested hardware table modules.
 AC_DEFUN([OFP_CHECK_HWTABLES],
index 11990026ecc29ebb693715a81e251c73461945f3..1d405ccec43482f1aa69df66f64a90997dcd9b89 100644 (file)
@@ -20,6 +20,7 @@ else
 EXTRA_CFLAGS += -DBUILDNR=\"+build$(BUILDNR)\"
 endif
 EXTRA_CFLAGS += -g
+EXTRA_CFLAGS += -include $(builddir)/kcompat.h
 
 # These include directories have to go before -I$(KSRC)/include.
 # NOSTDINC_FLAGS just happens to be a variable that goes in the
index a93b86e08b865f31da86d0f88f3e55757209c140..7847c83589d4f6ca9286d71e51aa2268f94b87ed 100644 (file)
@@ -16,12 +16,13 @@ $(foreach m,$(all_modules), \
     $(eval $(notdir $(s)): ; ln -s $(srcdir)/../$(s) $@)))
 
 distclean: clean
+       rm -f kcompat.h
 distdir: clean
 install:
 all: default
 check: all
 clean:
-       rm -f *.o *.ko *_mod.* Module.symvers *.cmd
+       rm -f *.o *.ko *_mod.* Module.symvers *.cmd kcompat.h.new
        for d in $(all_links); do if test -h $$d; then rm $$d; fi; done
 
 ifneq ($(KSRC),)
index f3b54882300148f00b06c29a79f9ff69e7079829..1d9b31401e753db2fd0d5954c04ee8c14359a475 100644 (file)
@@ -3,10 +3,7 @@
 
 #include_next <asm-generic/bug.h>
 
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
-
+#ifndef WARN_ON_ONCE
 #define WARN_ON_ONCE(condition)        ({                              \
        static int __warned;                                    \
        int __ret_warn_once = !!(condition);                    \
@@ -17,7 +14,6 @@
        }                                                       \
        unlikely(__ret_warn_once);                              \
 })
-
-#endif /* linux kernel < 2.6.19 */
+#endif
 
 #endif
index b02678b8da40cd0d1f825046fff3e7672c49df27..89b354e4c700a36512add2adb4cb34e9a09e8975 100644 (file)
@@ -3,16 +3,11 @@
 
 #include_next <linux/icmp.h>
 
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
-
-#ifdef __KERNEL__
+#ifndef HAVE_SKBUFF_HEADER_HELPERS
 static inline struct icmphdr *icmp_hdr(const struct sk_buff *skb)
 {
         return (struct icmphdr *)skb_transport_header(skb);
 }
-#endif /* __KERNEL__ */
-
-#endif /* linux kernel < 2.6.22 */
+#endif
 
 #endif
index b21c98d546ca6837fa83f67d6074f67da6a69705..e48d6ba0d760bf29eeddb5999c56e1256d0feb2a 100644 (file)
@@ -3,18 +3,13 @@
 
 #include_next <linux/if_arp.h>
 
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
-
-#ifdef __KERNEL__
+#ifndef HAVE_SKBUFF_HEADER_HELPERS
 #include <linux/skbuff.h>
 
 static inline struct arphdr *arp_hdr(const struct sk_buff *skb)
 {
        return (struct arphdr *)skb_network_header(skb);
 }
-#endif /* __KERNEL__ */
-
-#endif /* linux kernel < 2.6.22 */
+#endif /* !HAVE_SKBUFF_HEADER_HELPERS */
 
 #endif
index 9c8d57464306be87bc5bc08c67a10014f8f30df6..36765396b2951da1ef94c443ca07dc6155bd421c 100644 (file)
@@ -3,12 +3,7 @@
 
 #include_next <linux/ip.h>
 
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
-
-#ifdef __KERNEL__
-#include <linux/skbuff.h>
-
+#ifndef HAVE_SKBUFF_HEADER_HELPERS
 static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
 {
        return (struct iphdr *)skb_network_header(skb);
@@ -18,8 +13,6 @@ static inline unsigned int ip_hdrlen(const struct sk_buff *skb)
 {
        return ip_hdr(skb)->ihl * 4;
 }
-#endif /* __KERNEL__ */
-
-#endif /* linux kernel < 2.6.22 */
+#endif /* !HAVE_SKBUFF_HEADER_HELPERS */
 
 #endif
index e735a7804205d7f83f5670e24ee7320d50af6e0c..25a5431af72756152b32ca0a0768c91579008958 100644 (file)
@@ -3,18 +3,11 @@
 
 #include_next <linux/ipv6.h>
 
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
-
-#ifdef __KERNEL__
-#include <linux/skbuff.h>
-
+#ifndef HAVE_SKBUFF_HEADER_HELPERS
 static inline struct ipv6hdr *ipv6_hdr(const struct sk_buff *skb)
 {
        return (struct ipv6hdr *)skb_network_header(skb);
 }
-#endif /* __KERNEL__ */
-
-#endif /* linux kernel < 2.6.22 */
+#endif
 
 #endif
index a0111fb2b141a367d1ca464a58a00ccad000bc72..1464e728c23164f17742554673bc150be908cd3f 100644 (file)
@@ -17,19 +17,21 @@ static inline void kfree_skb_maybe_null(struct sk_buff *skb)
 #endif
 
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+#ifndef CHECKSUM_PARTIAL
 /* Note that CHECKSUM_PARTIAL is not implemented, but this allows us to at
  * least test against it: see update_csum() in forward.c. */
 #define CHECKSUM_PARTIAL 3
+#endif
+#ifndef CHECKSUM_COMPLETE
 #define CHECKSUM_COMPLETE CHECKSUM_HW
-#endif /* linux kernel < 2.6.19 */
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
+#endif
 
+#ifdef HAVE_MAC_RAW
 #define mac_header mac.raw
 #define network_header nh.raw
+#endif
 
+#ifndef HAVE_SKBUFF_HEADER_HELPERS
 static inline unsigned char *skb_transport_header(const struct sk_buff *skb)
 {
        return skb->h.raw;
@@ -87,6 +89,6 @@ static inline void skb_copy_to_linear_data(struct sk_buff *skb,
 {
        memcpy(skb->data, from, len);
 }
-#endif /* linux kernel < 2.6.22 */
+#endif /* !HAVE_SKBUFF_HEADER_HELPERS */
 
 #endif
index e8b519771a14222bd6ffb3e5d12b7a3172cb7b49..6fad1933b22ada5ccaf3dc8e21fc01d0a400e6ad 100644 (file)
@@ -3,10 +3,7 @@
 
 #include_next <linux/tcp.h>
 
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
-
-#ifdef __KERNEL__
+#ifndef HAVE_SKBUFF_HEADER_HELPERS
 static inline struct tcphdr *tcp_hdr(const struct sk_buff *skb)
 {
        return (struct tcphdr *)skb_transport_header(skb);
@@ -16,8 +13,6 @@ static inline unsigned int tcp_hdrlen(const struct sk_buff *skb)
 {
         return tcp_hdr(skb)->doff * 4;
 }
-#endif /* __KERNEL__ */
-
-#endif /* linux kernel < 2.6.22 */
+#endif /* !HAVE_SKBUFF_HEADER_HELPERS */
 
 #endif
index ffab1873756d2298e35857528513225fb5a79c2e..6fe4721bfd6778953b4d0db294064a3782a83180 100644 (file)
@@ -3,17 +3,11 @@
 
 #include_next <linux/udp.h>
 
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
-
-#ifdef __KERNEL__
+#ifndef HAVE_SKBUFF_HEADER_HELPERS
 static inline struct udphdr *udp_hdr(const struct sk_buff *skb)
 {
        return (struct udphdr *)skb_transport_header(skb);
 }
-#endif /* __KERNEL__ */
-
-
-#endif /* linux kernel < 2.6.22 */
+#endif /* HAVE_SKBUFF_HEADER_HELPERS */
 
 #endif