#
# Keepalived OpenSource project.
#
# Configuration template file for keepalived.
# autoconf will generate & check deps for proper compilation
#
# Copyright (C) 2001-2009 Alexandre Cassen, <acassen@linux-vs.org>

dnl ----[ Process this file with autoconf to produce a configure script ]----
AC_INIT(keepalived/core/main.c)
VERSION=`cat VERSION`
VERSION_DATE=`date +%m/%d,20%y`
OUTPUT_TARGET="Makefile genhash/Makefile keepalived/core/Makefile lib/config.h keepalived.spec"

dnl ----[ Checks for programs ]----
AC_PROG_CC
AC_PROG_INSTALL
AC_CHECK_TOOL(STRIP,strip)

dnl ----[ Keepalived specific configure options ]----
AC_ARG_ENABLE(lvs-syncd,
  [  --disable-lvs-syncd     do not use LVS synchronization daemon])
AC_ARG_ENABLE(lvs,
  [  --disable-lvs           do not use the LVS framework])
AC_ARG_ENABLE(vrrp,
  [  --disable-vrrp          do not use the VRRP framework])
AC_ARG_WITH(kernel-dir,
  [  --with-kernel-dir=DIR   path to linux kernel source directory],
  [kernelinc="$withval/include" kernelpath="$withval"],
  [kernelinc="/usr/src/linux/include" kernelpath="/usr/src/linux"])
AC_ARG_WITH(kernel-version,
  [  --with-kernel-version=VER forced value for linux kernel version (VER=2.4|2.6)],
  [kernelversion="$withval"], [kernelversion=""])
AC_ARG_ENABLE(fwmark,
  [  --disable-fwmark        compile without SO_MARK support])
AC_ARG_ENABLE(snmp,
  [  --enable-snmp           compile with SNMP support])
AC_ARG_ENABLE(sha1,
  [  --enable-sha1           compile with SHA1 support])
AC_ARG_ENABLE(debug,
  [  --enable-debug          compile with debugging flags])
AC_ARG_ENABLE(profile,
  [  --enable-profile        compile with profiling flags])

dnl ----[ Checks for header files ]----
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(fcntl.h syslog.h unistd.h sys/ioctl.h sys/time.h)
dnl [do we really need this ?] AC_CHECK_HEADERS(linux/netlink.h linux/rtnetlink.h)
AC_CHECK_HEADERS(openssl/ssl.h openssl/md5.h openssl/err.h,,AC_MSG_ERROR([
  !!! OpenSSL is not properly installed on your system. !!!
  !!! Can not include OpenSSL headers files.            !!!]))
AC_CHECK_DECL([ETHERTYPE_IPV6],[],[CFLAGS="$CFLAGS -DETHERTYPE_IPV6=0x86dd"],
  [[@%:@include <net/ethernet.h>]])

dnl ----[ Checks for libraries ]----
AC_CHECK_LIB(crypt, crypt,,AC_MSG_ERROR([crypt() function is required]))
AC_CHECK_LIB(crypto, MD5_Init,,AC_MSG_ERROR([OpenSSL libraries are required]))
AC_CHECK_LIB(ssl, SSL_CTX_new,,AC_MSG_ERROR([OpenSSL libraries are required]))

AC_CHECK_LIB(nl-3, nl_socket_alloc,
  [
    AC_CHECK_LIB(nl-genl-3, genl_connect,
      [
        USE_NL="LIBIPVS_USE_NL"
        CFLAGS="$CFLAGS $(pkg-config --cflags libnl-genl-3.0)"
	LIBS="$LIBS $(pkg-config --libs libnl-genl-3.0)"
      ],
      [
        AC_MSG_ERROR([libnl-3 is installed but not libnl-gen-3. Please, install libnl-gen-3.])
      ])
  ],
  [
    AC_CHECK_LIB(nl, nl_socket_modify_cb,
      [
        USE_NL="LIBIPVS_USE_NL"
        CFLAGS="$CFLAGS -DFALLBACK_LIBNL1"
        LIBS="$LIBS $(pkg-config --libs libnl-1)"
      ],
      [                                                                                           
        USE_NL="LIBIPVS_DONTUSE_NL"
        AC_MSG_WARN([keepalived will be built without libnl support.])
      ])
  ])

dnl ----[ Kernel version check ]----
CPPFLAGS="$CPPFLAGS -I$kernelinc"
AC_MSG_CHECKING([for kernel version])
AC_TRY_RUN([
    #include <stdlib.h>
    #include <stdio.h>
    #include <linux/version.h>
    #if !defined(UTS_RELEASE) && !defined(LINUX_VERSION_CODE)
    #include <linux/utsrelease.h>
    #endif
    int main (void) {
      FILE *fp = fopen ("linuxinfo", "w");
      if (!fp) return 1;
    #if defined(UTS_RELEASE)
      fprintf (fp, "%s\n", UTS_RELEASE);
    #elif defined(LINUX_VERSION_CODE)
      fprintf (fp, "%d.%d.%d\n", LINUX_VERSION_CODE >> 16, (LINUX_VERSION_CODE >> 8) & 0xFF, LINUX_VERSION_CODE & 0xFF);
    #else
      fprintf (fp, "0.0.0\n"); /* Let's fail gently */
    #endif
      fclose (fp); 
      return 0;
    } 
  ], [
    LINUX_MAJOR=`cat linuxinfo | cut -d'.' -f1`
    LINUX_MINOR=`cat linuxinfo | cut -d'.' -f2`
    LINUX_PATCH=`cat linuxinfo | cut -d'.' -f3`
  ], [
    LINUX_MAJOR="0"
    LINUX_MINOR="0"
    LINUX_PATCH="0"
  ], [
    LINUX_MAJOR="0"
    LINUX_MINOR="0"
    LINUX_PATCH="0"
  ])
  rm -f linuxinfo

  if test "$kernelversion" = "2.4"; then
    KERN="_KRNL_2_4_"
    AC_MSG_RESULT([2.4])
  elif test "$kernelversion" = "2.6"; then
    KERN="_KRNL_2_6_"
    AC_MSG_RESULT([2.6])
  else
    AC_MSG_RESULT([$LINUX_MAJOR.$LINUX_MINOR.$LINUX_PATCH])
    if test "$LINUX_MAJOR" = "2" && test "$LINUX_MINOR" = "6"; then
      KERN="_KRNL_2_6_"
    elif test "$LINUX_MAJOR" = "2" && test "$LINUX_MINOR" = "4"; then
      KERN="_KRNL_2_4_"
    else
      KERN="_KRNL_2_6_"
    fi
    if test "$LINUX_MAJOR" = "0" -a "$LINUX_MINOR" = "0" -a "$LINUX_PATCH" = "0"; then
      AC_MSG_WARN([Cannot determine Linux Kernel version.])
    fi
  fi

AC_SUBST(KERN)

dnl ----[ Checks for LVS and VRRP support ]----
IPVS_SUPPORT="_WITHOUT_LVS_"
if test "$enable_lvs" != "no"; then
  if test "$KERN" = "_KRNL_2_6_"; then
    IPVS_SUPPORT="_WITH_LVS_"
  else
    AC_CHECK_HEADER([net/ip_vs.h],
      [IPVS_SUPPORT="_WITH_LVS_"],
      [
        IPVS_SUPPORT="_WITHOUT_LVS_"
        AC_MSG_WARN([keepalived will be built without LVS support.])
      ])
  fi
fi  

if test "$IPVS_SUPPORT" = "_WITHOUT_LVS_" -a "$enable_vrrp" = "no"; then
  AC_MSG_ERROR([keepalived MUST be compiled at least with LVS or VRRP framework])
fi

dnl ----[ IPVS syncd support probe ]---
IPVS_SYNCD="_WITHOUT_IPVS_SYNCD_"
if test "$IPVS_SUPPORT" = "_WITH_LVS_"; then
  AC_MSG_CHECKING([for IPVS syncd support])
  if test "$KERN" = "_KRNL_2_6_"; then
    IPVS_SYNCD="_HAVE_IPVS_SYNCD_"
  elif test "_KRNL_2_4_"; then
    IPVS_SYNCD="_HAVE_IPVS_SYNCD_"
  else
    IPVS_SYNCD="_WITHOUT_IPVS_SYNCD_"
  fi

  if test "${IPVS_SUPPORT}" = "_WITHOUT_LVS_" -o "$enable_lvs_syncd" = "no"; then
    IPVS_SYNCD="_WITHOUT_IPVS_SYNCD_"
  fi

  if test "$IPVS_SYNCD" = "_HAVE_IPVS_SYNCD_"; then
    AC_MSG_RESULT([yes])
  else
    AC_MSG_RESULT([no])
  fi
fi

AC_SUBST(IPVS_SYNCD)

dnl ----[ Checks for kernel netlink support ]----
VRRP_SUPPORT="_WITHOUT_VRRP_"
if test "$enable_vrrp" != "no"; then
  VRRP_SUPPORT="_WITH_VRRP_"
fi

dnl ----[ Checks for kernel VMAC support ]----
CPPFLAGS="$CPPFLAGS -I$kernelinc"
AC_MSG_CHECKING([for kernel macvlan support])
AC_TRY_COMPILE([
    #include <bits/sockaddr.h>
    #include <linux/if_link.h>
    int macvlan;
  ], [
    macvlan = IFLA_MACVLAN_MODE;
    macvlan = MACVLAN_MODE_PRIVATE;
  ], [
    MACVLAN_SUPPORT=yes
  ], []);

  if test "$MACVLAN_SUPPORT" = "yes"; then
    VRRP_VMAC="_HAVE_VRRP_VMAC_"
    AC_MSG_RESULT([yes])
  else
    VRRP_VMAC="_WITHOUT_VRRP_VMAC_"
    AC_MSG_RESULT([no])
  fi

AC_SUBST(VRRP_VMAC)

dnl ----[ Checks for SNMP support ]----
SNMP_SUPPORT="_WITHOUT_SNMP_"
if test "$enable_snmp" = "yes"; then

  AC_PATH_TOOL([NETSNMP_CONFIG], [net-snmp-config], [no])
  if test x"$NETSNMP_CONFIG" = x"no"; then
    AC_MSG_ERROR([*** unable to find net-snmp-config])
  fi
  NETSNMP_LIBS=`${NETSNMP_CONFIG} --agent-libs`
  NETSNMP_CFLAGS="`${NETSNMP_CONFIG} --base-cflags` -DNETSNMP_NO_INLINE"

  CFLAGS="$CFLAGS ${NETSNMP_CFLAGS}"
  LIBS="$LIBS ${NETSNMP_LIBS}"
  AC_MSG_CHECKING([whether C compiler supports flag "${NETSNMP_CFLAGS} ${NETSNMP_LIBS}" from Net-SNMP])
  AC_LINK_IFELSE([AC_LANG_PROGRAM([
int main(void);
],
[
{
  return 0;
}
])],[AC_MSG_RESULT(yes)],[
     AC_MSG_RESULT(no)
     AC_MSG_ERROR([*** incorrect CFLAGS from net-snmp-config])])

  # Do we have subagent support?
  AC_CHECK_FUNCS([netsnmp_enable_subagent], [:],
      [AC_MSG_ERROR([*** no subagent support in net-snmp])])

  # Do we have a usable <net-snmp/agent/util_funcs.h> header?
  # Some ancien distributions may miss this header.
  AC_CHECK_HEADERS([net-snmp/agent/util_funcs.h],,,[
@%:@include <net-snmp/net-snmp-config.h>
@%:@include <net-snmp/net-snmp-includes.h>
@%:@include <net-snmp/library/snmp_transport.h>
@%:@include <net-snmp/agent/net-snmp-agent-includes.h>
@%:@include <net-snmp/agent/snmp_vars.h>
  ])

  SNMP_SUPPORT="_WITH_SNMP_"
fi

AC_SUBST(SNMP_SUPPORT)

dnl ----[ SHA1 or not ? ]----
SHA1_SUPPORT="_WITHOUT_SHA1_"
if test "${enable_sha1}" = "yes"; then
  CFLAGS="$CFLAGS -DFEAT_SHA1"
  AC_CHECK_HEADERS(openssl/sha.h,,AC_MSG_ERROR([unable to find openssl/sha.h]))
  AC_CHECK_LIB(crypto, SHA1_Init,,AC_MSG_ERROR([SHA1 in OpenSSL required]))
  SHA1_SUPPORT="_WITH_SHA1_"
fi

AC_SUBST(SHA1_SUPPORT)

dnl ----[ check for SO_MARK support ]----
if test "${enable_fwmark}" = "no"; then
  SO_MARK_SUPPORT="_WITHOUT_SO_MARK_"
else
  AC_CHECK_DECL(SO_MARK,,AC_MSG_ERROR([No SO_MARK declaration in headers]),
    #include <sys/socket.h>
  )
  SO_MARK_SUPPORT="_WITH_SO_MARK_"
fi

AC_SUBST(SO_MARK_SUPPORT)


dnl ----[ Debug or not ? ]----
if test "${enable_debug}" = "yes"; then
  DFLAGS="-D_DEBUG_"
  AC_SUBST(DFLAGS)
fi

dnl ----[ Profiling or not ? ]----
if test "${enable_profile}" = "yes"; then
  CFLAGS="$CFLAGS -pg"
fi

AC_SUBST(VERSION)
AC_SUBST(VERSION_DATE)
AC_SUBST(IPVS_SUPPORT)
AC_SUBST(USE_NL)
AC_SUBST(VRRP_SUPPORT)

dnl ----[ Checks for typedefs, structures, and compiler characteristics ]----
AC_C_CONST
AC_TYPE_PID_T
AC_HEADER_TIME

dnl ----[ Checks for library functions ]----
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MEMCMP
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(gettimeofday select socket strerror strtol uname)

dnl ----[ Process output target ]----
OUTPUT_TARGET="$OUTPUT_TARGET keepalived/Makefile lib/Makefile"
if test "${VRRP_SUPPORT}" = "_WITH_VRRP_"; then
  OUTPUT_TARGET="$OUTPUT_TARGET keepalived/vrrp/Makefile"
fi
if test "$IPVS_SUPPORT" = "_WITH_LVS_"; then
  OUTPUT_TARGET="$OUTPUT_TARGET keepalived/check/Makefile"
  if test "$KERN" = "_KRNL_2_6_"; then
    OUTPUT_TARGET="$OUTPUT_TARGET keepalived/libipvs-2.6/Makefile"
  elif test "$KERN" = "_KRNL_2_4_"; then
    OUTPUT_TARGET="$OUTPUT_TARGET keepalived/libipvs-2.4/Makefile"
  fi
fi
AC_OUTPUT($OUTPUT_TARGET)


dnl ----[ Display current configuration ]----
cat <<EOF;

Keepalived configuration
------------------------
Keepalived version       : ${VERSION}
Compiler                 : ${CC}
Compiler flags           : ${CFLAGS}
EOF

dnl ----[ display optional vars  ]----
if test -n "$LIBS"; then
  echo "Extra Lib                : $LIBS"
fi

if test "${IPVS_SUPPORT}" = "_WITH_LVS_"; then
  echo "Use IPVS Framework       : Yes"
  if test "${IPVS_SYNCD}" = "_HAVE_IPVS_SYNCD_"; then
    echo "IPVS sync daemon support : Yes"
  elif test "${IPVS_SYNCD}" = "_WITHOUT_IPVS_SYNCD_"; then
    echo "IPVS sync daemon support : No"
  fi
  if test "${USE_NL}" = "LIBIPVS_USE_NL"; then
    echo "IPVS use libnl           : Yes"
  else
    echo "IPVS use libnl           : No"
  fi
else
  echo "Use IPVS Framework       : No"
  echo "IPVS sync daemon support : No"
fi

if test "${SO_MARK_SUPPORT}" = "_WITH_SO_MARK_"; then
  echo "fwmark socket support    : Yes"
else
  echo "fwmark socket support    : No"
fi

if test "${VRRP_SUPPORT}" = "_WITH_VRRP_"; then
  echo "Use VRRP Framework       : Yes"
  if test "${VRRP_VMAC}" = "_HAVE_VRRP_VMAC_"; then
    echo "Use VRRP VMAC            : Yes"
  else
    echo "Use VRRP VMAC            : No"
  fi
else
  echo "Use VRRP Framework       : No"
fi
if test "${SNMP_SUPPORT}" = "_WITH_SNMP_"; then
  echo "SNMP support             : Yes"
else
  echo "SNMP support             : No"
fi
if test "${SHA1_SUPPORT}" = "_WITH_SHA1_"; then
  echo "SHA1 support             : Yes"
else
  echo "SHA1 support             : No"
fi
if test "${DFLAGS}" = "-D_DEBUG_"; then
  echo "Use Debug flags          : Yes"
else
  echo "Use Debug flags          : No"
fi
dnl ----[ end configure ]---
