Source: keepalived
Version: 1:1.2.9-1
Tags: patch

The patch to support libnl 3 is incomplete.

In libnl 3 the return codes have changed. It currently results in weird
errors and unexpected behaviour.

For example, when I add an ip + port to a virtual_server_group and
reload keepalived I get this message in /var/log/syslog:
> Keepalived_healthcheckers[11685]: IPVS: Memory allocation problem

This message is based on return code 12 from "ipvs_update_dest(srule,
drule)" in keepalived/check/ipvswrapper.c, line 396. In libnl 3, return
code 12 is "NLE_OBJ_NOTFOUND" (previously "ENOENT"). ENOENT is expected
on line 397 in keepalived/check/ipvswrapper.c. The final result:
Keepalived fails to add the real_servers to this new IP.

This is just 1 example. Probably there is more unexpected behaviour. I
also saw a message like "Keepalived_vrrp[11687]: IPVS: Too many links"
(return code 31) related to the lvs_sync_daemon_interface setting. In
libnl 3, return code 31 is "NLE_NODEV" (previously "ENODEV"). This makes
way more sense. So the message should be: "Keepalived_vrrp[11687]: IPVS:
No such device".

An updated libnl3.patch is attached. This patch adds a function to
translate libnl 3 errors to sys errors. It also uses a FALLBACK_LIBNL1
variable instead of LIBNL2 (got this from ipvsadm). 

-- 
Regards,
Pim van den Berg
Description: Support libnl version 2.0 and higher
Author: Marc - A. Dahlhaus <m...@wol.de>
Forwarded: http://article.gmane.org/gmane.linux.keepalived.devel/3522
Last-Update: 2011-12-21

--- a/configure.in
+++ b/configure.in
@@ -58,11 +58,19 @@
 AC_CHECK_LIB(nl, nl_socket_modify_cb,
   [
     USE_NL="LIBIPVS_USE_NL"
+    CFLAGS="$CFLAGS -DFALLBACK_LIBNL1"
     LIBS="$LIBS -lnl"
   ],
-  [
-    USE_NL="LIBIPVS_DONTUSE_NL"
-    AC_MSG_WARN([keepalived will be built without libnl support.])
+  [AC_CHECK_LIB(nl-3, nl_socket_alloc,
+    [
+      USE_NL="LIBIPVS_USE_NL"
+      CFLAGS="$CFLAGS -I/usr/include/libnl3"
+      LIBS="$LIBS -lnl-3 -lnl-genl-3"
+    ],
+    [
+      USE_NL="LIBIPVS_DONTUSE_NL"
+      AC_MSG_WARN([keepalived will be built without libnl support.])
+    ])
   ])
 
 dnl ----[ Kernel version check ]----
--- a/keepalived/libipvs-2.6/libipvs.c
+++ b/keepalived/libipvs-2.6/libipvs.c
@@ -34,6 +34,11 @@
 struct ip_vs_getinfo ipvs_info;
 
 #ifdef LIBIPVS_USE_NL
+# ifndef FALLBACK_LIBNL1
+#  define nl_handle nl_sock
+#  define nl_handle_alloc nl_socket_alloc
+#  define nl_handle_destroy nl_socket_free
+# endif
 struct nl_handle *sock = NULL;
 int family, try_nl = 1;
 #endif
@@ -42,6 +47,31 @@
 	{ errno = EAFNOSUPPORT; return ret; }			\
 	s->__addr_v4 = s->addr.ip;				\
 
+#ifndef FALLBACK_LIBNL1
+static int nlerr2syserr(int err)
+{
+	switch (abs(err)) {
+	case NLE_BAD_SOCK:       return EBADF;
+	case NLE_EXIST:          return EEXIST;
+	case NLE_NOADDR:         return EADDRNOTAVAIL;
+	case NLE_OBJ_NOTFOUND:   return ENOENT;
+	case NLE_INTR:           return EINTR;
+	case NLE_AGAIN:          return EAGAIN;
+	case NLE_INVAL:          return EINVAL;
+	case NLE_NOACCESS:       return EACCES;
+	case NLE_NOMEM:          return ENOMEM;
+	case NLE_AF_NOSUPPORT:   return EAFNOSUPPORT;
+	case NLE_PROTO_MISMATCH: return EPROTONOSUPPORT;
+	case NLE_OPNOTSUPP:      return EOPNOTSUPP;
+	case NLE_PERM:           return EPERM;
+	case NLE_BUSY:           return EBUSY;
+	case NLE_RANGE:          return ERANGE;
+	case NLE_NODEV:          return ENODEV;
+	default:                 return err;
+	}
+}
+#endif
+
 #ifdef LIBIPVS_USE_NL
 struct nl_msg *ipvs_nl_message(int cmd, int flags) {
 	struct nl_msg *msg;
@@ -103,6 +133,9 @@
 	sock = NULL;
 	nlmsg_free(msg);
 	errno = err;
+#ifndef FALLBACK_LIBNL1
+	errno = nlerr2syserr(err);
+#endif
 	return -1;
 }
 #endif

Attachment: signature.asc
Description: Digital signature

Reply via email to