[PATCH 02/12] Set (and restore) interface parameters

[email protected] (Quentin Armitage)
Newsgroups gmane.linux.keepalived.devel
Message-ID <[email protected]>
In order to receive and send multicasts on the correct interfaces
various parameters need to be set via the /proc/sys/net/ipv4/conf
interface. This patch sets them as needed, and restores any
changes on the underlying interface on exit.

Signed-off-by: Quentin Armitage <[email protected]>
---
 configure                          |   55 +++++++++++++
 configure.in                       |   18 ++++-
 keepalived/include/vrrp_if.h       |    1 +
 keepalived/include/vrrp_netlink3.h |   30 +++++++
 keepalived/vrrp/Makefile.in        |    6 +-
 keepalived/vrrp/vrrp_netlink.c     |    1 +
 keepalived/vrrp/vrrp_netlink3.c    |  156 ++++++++++++++++++++++++++++++++++++
 keepalived/vrrp/vrrp_vmac.c        |  132 ++++++++++++++++++++++++++++++
 8 files changed, 397 insertions(+), 2 deletions(-)
 create mode 100644 keepalived/include/vrrp_netlink3.h
 create mode 100644 keepalived/vrrp/vrrp_netlink3.c

diff --git a/configure b/configure
index a340883..efe72af 100755
--- a/configure
+++ b/configure
@@ -621,6 +621,7 @@ ac_includes_default="\
 
 ac_subst_vars='LTLIBOBJS
 LIBOBJS
+USE_NL3
 VRRP_SUPPORT
 USE_NL
 IPVS_SUPPORT
@@ -3905,6 +3906,7 @@ else
 fi
 
 
+USE_NL3="_WITHOUT_LIBNL_"
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_alloc in -lnl-3" >&5
 $as_echo_n "checking for nl_socket_alloc in -lnl-3... " >&6; }
 if ${ac_cv_lib_nl_3_nl_socket_alloc+:} false; then :
@@ -3991,6 +3993,50 @@ else
 
 fi
 
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_rtgen_request in -lnl-route-3" >&5
+$as_echo_n "checking for nl_rtgen_request in -lnl-route-3... " >&6; }
+if ${ac_cv_lib_nl_route_3_nl_rtgen_request+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnl-route-3  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char nl_rtgen_request ();
+int
+main ()
+{
+return nl_rtgen_request ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_nl_route_3_nl_rtgen_request=yes
+else
+  ac_cv_lib_nl_route_3_nl_rtgen_request=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_route_3_nl_rtgen_request" >&5
+$as_echo "$ac_cv_lib_nl_route_3_nl_rtgen_request" >&6; }
+if test "x$ac_cv_lib_nl_route_3_nl_rtgen_request" = xyes; then :
+
+	USE_NL3="_HAVE_LIBNL3_"
+        CFLAGS="$CFLAGS $(pkg-config --cflags libnl-route-3.0)"
+	LIBS="$LIBS $(pkg-config --libs libnl-route-3.0)"
+
+fi
+
 
 else
 
@@ -4033,6 +4079,7 @@ $as_echo "$ac_cv_lib_nl_nl_socket_modify_cb" >&6; }
 if test "x$ac_cv_lib_nl_nl_socket_modify_cb" = xyes; then :
 
         USE_NL="LIBIPVS_USE_NL"
+	USE_NL3="_HAVE_LIBNL1_"
         CFLAGS="$CFLAGS -DFALLBACK_LIBNL1"
         LIBS="$LIBS $(pkg-config --libs libnl-1)"
 
@@ -4507,6 +4554,7 @@ fi
 
 
 
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
 $as_echo_n "checking for an ANSI C-conforming const... " >&6; }
 if ${ac_cv_c_const+:} false; then :
@@ -6023,3 +6071,10 @@ if test "${DFLAGS}" = "-D_DEBUG_"; then
 else
   echo "Use Debug flags          : No"
 fi
+if test "${USE_NL3}" = "_HAVE_LIBNL3_"; then
+  echo "libnl version            : 3"
+elif test "${USE_NL3}" = "_HAVE_LIBNL1_"; then
+  echo "libnl version            : 1"
+else
+  echo "libnl version            : None"
+fi
diff --git a/configure.in b/configure.in
index 38a8acd..68bc336 100644
--- a/configure.in
+++ b/configure.in
@@ -58,6 +58,7 @@ 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]))
 
+USE_NL3="_WITHOUT_LIBNL_"
 AC_CHECK_LIB(nl-3, nl_socket_alloc,
   [
     AC_CHECK_LIB(nl-genl-3, genl_connect,
@@ -69,11 +70,18 @@ AC_CHECK_LIB(nl-3, nl_socket_alloc,
       [
         AC_MSG_ERROR([libnl-3 is installed but not libnl-gen-3. Please, install libnl-gen-3.])
       ])
+    AC_CHECK_LIB(nl-route-3, nl_rtgen_request,
+      [
+	USE_NL3="_HAVE_LIBNL3_"
+        CFLAGS="$CFLAGS $(pkg-config --cflags libnl-route-3.0)"
+	LIBS="$LIBS $(pkg-config --libs libnl-route-3.0)"
+      ])
   ],
   [
     AC_CHECK_LIB(nl, nl_socket_modify_cb,
       [
         USE_NL="LIBIPVS_USE_NL"
+	USE_NL3="_HAVE_LIBNL1_"
         CFLAGS="$CFLAGS -DFALLBACK_LIBNL1"
         LIBS="$LIBS $(pkg-config --libs libnl-1)"
       ],
@@ -101,7 +109,7 @@ AC_TRY_RUN([
     #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 */
+      fprintf (fp, "0.0.0\n"); /* Let''s fail gently */
     #endif
       fclose (fp); 
       return 0;
@@ -301,6 +309,7 @@ AC_SUBST(VERSION_DATE)
 AC_SUBST(IPVS_SUPPORT)
 AC_SUBST(USE_NL)
 AC_SUBST(VRRP_SUPPORT)
+AC_SUBST(USE_NL3)
 
 dnl ----[ Checks for typedefs, structures, and compiler characteristics ]----
 AC_C_CONST
@@ -392,4 +401,11 @@ if test "${DFLAGS}" = "-D_DEBUG_"; then
 else
   echo "Use Debug flags          : No"
 fi
+if test "${USE_NL3}" = "_HAVE_LIBNL3_"; then
+  echo "libnl version            : 3"
+elif test "${USE_NL3}" = "_HAVE_LIBNL1_"; then
+  echo "libnl version            : 1"
+else
+  echo "libnl version            : None"
+fi
 dnl ----[ end configure ]---
diff --git a/keepalived/include/vrrp_if.h b/keepalived/include/vrrp_if.h
index a8bfc1c..ec6064f 100644
--- a/keepalived/include/vrrp_if.h
+++ b/keepalived/include/vrrp_if.h
@@ -88,6 +88,7 @@ typedef struct _interface {
 	int			linkbeat;		/* LinkBeat from MII BMSR req */
 	int			vmac;			/* Set if interface is a VMAC interface */
 	unsigned int		base_ifindex;		/* Base interface index (if interface is a VMAC interface) */
+	int			reset_arp_ignore;	/* Set if we have set arp_ignore in interface */
 } interface_t;
 
 /* Tracked interface structure definition */
diff --git a/keepalived/include/vrrp_netlink3.h b/keepalived/include/vrrp_netlink3.h
new file mode 100644
index 0000000..3b5ae5e
--- /dev/null
+++ b/keepalived/include/vrrp_netlink3.h
@@ -0,0 +1,30 @@
+/*
+ * Soft:        Keepalived is a failover program for the LVS project
+ *              <www.linuxvirtualserver.org>. It monitor & manipulate
+ *              a loadbalanced server pool using multi-layer checks.
+ *
+ * Part:        vrrp_netlink3.c include file.
+ *
+ * Author:      Alexandre Cassen, <[email protected]>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *              
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ *
+ * Copyright (C) 2001-2014 Alexandre Cassen, <[email protected]>
+ */
+
+#ifndef _VRRP_NETLINK3_H
+#define _VRRP_NETLINK3_H 1
+
+/* prototypes */
+extern int netlink3_set_interface_parameters(int, int, int *);
+extern int netlink3_reset_interface_parameters(int);
+
+#endif
diff --git a/keepalived/vrrp/Makefile.in b/keepalived/vrrp/Makefile.in
index 8f4a59b..915b51f 100644
--- a/keepalived/vrrp/Makefile.in
+++ b/keepalived/vrrp/Makefile.in
@@ -19,6 +19,9 @@ OBJS = 	vrrp_daemon.o vrrp_print.o vrrp_data.o vrrp_parser.o \
 ifeq ($(SNMP_FLAG),_WITH_SNMP_)
   OBJS += vrrp_snmp.o
 endif
+ifeq ($(NL3_FLAG),_HAVE_LIBNL3_)
+  OBJS += vrrp_netlink3.o
+endif
 HEADERS = $(OBJS:.o=.h)
 
 .c.o:
@@ -83,8 +86,9 @@ vrrp_ndisc.o: vrrp_ndisc.c ../include/vrrp_ndisc.h ../include/vrrp_ipaddress.h \
   ../../lib/utils.h ../../lib/memory.h
 vrrp_vmac.o: vrrp_vmac.c ../include/vrrp_vmac.h ../include/vrrp_netlink.h \
   ../include/vrrp_data.h ../../lib/logger.h ../../lib/memory.h ../../lib/utils.h \
-  ../../lib/bitops.h
+  ../../lib/bitops.h ../include/vrrp_netlink3.h
 vrrp_snmp.o: vrrp_snmp.c ../include/vrrp_snmp.h ../include/vrrp_track.h \
   ../include/vrrp_data.h ../include/vrrp_ipaddress.h ../include/vrrp_iproute.h \
   ../include/vrrp_iprule.h ../include/vrrp.h ../../lib/vector.h ../../lib/list.h ../include/snmp.h \
   ../include/global_data.h ../../lib/logger.h
+vrrp_netlink3.o: vrrp_netlink3.c ../include/vrrp_netlink3.h ../../lib/logger.h
diff --git a/keepalived/vrrp/vrrp_netlink.c b/keepalived/vrrp/vrrp_netlink.c
index 7ac851b..bb52143 100644
--- a/keepalived/vrrp/vrrp_netlink.c
+++ b/keepalived/vrrp/vrrp_netlink.c
@@ -477,6 +477,7 @@ netlink_if_link_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
 	ifp->ifindex = ifi->ifi_index;
 	ifp->mtu = *(int *) RTA_DATA(tb[IFLA_MTU]);
 	ifp->hw_type = ifi->ifi_type;
+	ifp->reset_arp_ignore = 0;
 
 	if (!ifp->vmac) {
 		if_vmac_reflect_flags(ifi->ifi_index, ifi->ifi_flags);
diff --git a/keepalived/vrrp/vrrp_netlink3.c b/keepalived/vrrp/vrrp_netlink3.c
new file mode 100644
index 0000000..2b75758
--- /dev/null
+++ b/keepalived/vrrp/vrrp_netlink3.c
@@ -0,0 +1,156 @@
+/*
+ * Soft:        Keepalived is a failover program for the LVS project
+ *              <www.linuxvirtualserver.org>. It monitor & manipulate
+ *              a loadbalanced server pool using multi-layer checks.
+ *
+ * Part:        libnl3 interface
+ *
+ * Author:      Alexandre Cassen, <[email protected]>
+ *
+ *              This program is distributed in the hope that it will be useful,
+ *              but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *              See the GNU General Public License for more details.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ *
+ * Copyright (C) 2001-2014 Alexandre Cassen, <[email protected]>
+ */
+
+#include <netlink/netlink.h>
+#include <netlink/route/link.h>
+#include <netlink/route/link/inet.h>
+#include <linux/ip.h>
+#include <syslog.h>
+
+#include "logger.h"
+
+int
+netlink3_set_interface_parameters(int ifindex, int base_ifindex, int *reset_arp_ignore)
+{
+	struct nl_sock *sk;
+	struct nl_cache *cache;
+	struct rtnl_link *link = NULL;
+	struct rtnl_link *new_state = NULL;
+	uint32_t base_arp_ignore;
+	int res = 0;
+
+	if (!(sk = nl_socket_alloc())) {
+		log_message(LOG_INFO, "Unable to open netlink socket");
+		return -1;
+	}
+
+	if (nl_connect(sk, NETLINK_ROUTE) < 0)
+		goto err;
+	if (rtnl_link_alloc_cache(sk, AF_UNSPEC, &cache))
+		goto err;
+	if (!(link = rtnl_link_get(cache, ifindex)))
+		goto err;
+
+	// Allocate a new link
+	if (!(new_state = rtnl_link_alloc()))
+		goto err;
+
+	if (rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARP_IGNORE, 2) ||
+	    rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_RP_FILTER, 0) ||
+	    rtnl_link_change (sk, link, new_state, 0))
+		goto err;
+
+	rtnl_link_put(new_state);
+	new_state = NULL;
+
+	rtnl_link_put(link);
+	link = NULL;
+
+	/* Set arp_ignore on base interface if needed */
+	if (*reset_arp_ignore)
+		(*reset_arp_ignore)++;
+	else {
+		if (!(link = rtnl_link_get(cache, base_ifindex)))
+			goto err;
+		if (rtnl_link_inet_get_conf(link, IPV4_DEVCONF_ARP_IGNORE, &base_arp_ignore) < 0)
+			goto err;
+
+		if (base_arp_ignore == 0) {
+			/* The underlying interface mustn't reply for our address(es) */
+			if (!(new_state = rtnl_link_alloc()))
+				goto err;
+
+			if (rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARP_IGNORE, 1) ||
+			    rtnl_link_change(sk, link, new_state, 0))
+				goto err;
+
+			rtnl_link_put(new_state);
+			new_state = NULL;
+
+			rtnl_link_put(link);
+			link = NULL;
+
+			*reset_arp_ignore = 1;
+		}
+	}
+
+	goto exit;
+err:
+	res = -1;
+
+	if (link)
+		rtnl_link_put(link);
+	if (new_state)
+		rtnl_link_put(new_state);
+
+exit:
+	nl_close ( sk ) ;
+
+	return res;
+}
+
+int
+netlink3_reset_interface_parameters(int ifindex)
+{
+	struct nl_sock *sk;
+	struct nl_cache *cache;
+	struct rtnl_link *link = NULL;
+	struct rtnl_link *new_state = NULL;
+	int res = 0;
+
+	if (!(sk = nl_socket_alloc())) {
+		log_message(LOG_INFO, "Unable to open netlink socket");
+		return -1;
+	}
+
+	if (nl_connect(sk, NETLINK_ROUTE) < 0)
+		goto err;
+	if (rtnl_link_alloc_cache(sk, AF_UNSPEC, &cache))
+		goto err;
+	if (!(link = rtnl_link_get(cache, ifindex)))
+		goto err;
+	if (!(new_state = rtnl_link_alloc()))
+		goto err;
+	if (rtnl_link_inet_set_conf(new_state, IPV4_DEVCONF_ARP_IGNORE, 0) ||
+	    rtnl_link_change(sk, link, new_state, 0))
+		goto err;
+
+	rtnl_link_put(link);
+	link = NULL;
+
+	rtnl_link_put(new_state);
+	new_state = NULL;
+
+	goto exit;
+err:
+	res = -1;
+
+	if (link)
+		rtnl_link_put(link);
+	if (new_state)
+		rtnl_link_put(new_state);
+
+exit:
+	nl_close(sk);
+
+	return res;
+}
diff --git a/keepalived/vrrp/vrrp_vmac.c b/keepalived/vrrp/vrrp_vmac.c
index b4634f9..e80135e 100644
--- a/keepalived/vrrp/vrrp_vmac.c
+++ b/keepalived/vrrp/vrrp_vmac.c
@@ -20,6 +20,9 @@
  * Copyright (C) 2001-2012 Alexandre Cassen, <[email protected]>
  */
 
+/* global include */
+#include <limits.h>
+
 /* local include */
 #include "vrrp_vmac.h"
 #include "vrrp_netlink.h"
@@ -29,11 +32,126 @@
 #include "utils.h"
 #include "parser.h"
 #include "bitops.h"
+#ifdef _HAVE_LIBNL3_
+#include "vrrp_netlink3.h"
+#endif
 
 #ifdef _HAVE_VRRP_VMAC_
 /* private matter */
 static const char *ll_kind = "macvlan";
 
+/* The following parameters need to be set on the vmac interface and its parent:
+ *   vmac interface:
+ *     arp_ignore=2    // We mustn't reply to ARP requests on this interface for IP address on parent interface
+ *                     // and we only need to reply to addresses on the same subnet.
+ *     rp_filter=0     // Allows us to receive on VMAC interface when it has no IP address.
+ *   parent interface:
+ *     arp_ignore=1    // We mustn't reply to ARP requests on this interface for vrrp IP address
+ */
+#ifdef _HAVE_LIBNL3_
+static void
+set_interface_parameters(const interface_t *ifp, interface_t *base_ifp)
+{
+       if (netlink3_set_interface_parameters(ifp->ifindex, base_ifp->ifindex, &base_ifp->reset_arp_ignore))
+               log_message(LOG_INFO, "Unable to set parameters for %s", ifp->ifname);
+}
+
+static void
+reset_interface_parameters(interface_t *base_ifp)
+{
+       if (netlink3_reset_interface_parameters(base_ifp->ifindex))
+               log_message(LOG_INFO, "Unable to reset parameters for %s", base_ifp->ifname);
+}
+
+#else
+/* Sysctl get and set functions */
+static void
+make_sysctl_filename(char *dest, const char* prefix, const char* iface, const char* parameter)
+{
+	strcpy(dest, "/proc/sys/");
+	strcat(dest, prefix);
+	strcat(dest, "/");
+	strcat(dest, iface);
+	strcat(dest, "/");
+	strcat(dest, parameter);
+}
+
+static int
+get_sysctl(const char* prefix, const char* iface, const char* parameter)
+{
+	char *filename;
+	char buf[1];
+	int fd;
+	int len;
+
+	/* Make the filename */
+	filename = MALLOC(PATH_MAX);
+	make_sysctl_filename(filename, prefix, iface, parameter);
+
+	fd = open(filename, O_RDONLY);
+	FREE(filename);
+	if (fd<0)
+		return -1;
+
+	len = read(fd, &buf, 1);
+	close(fd);
+
+	/* We only read integers 0-9 */
+	if (len <= 0)
+		return -1;
+
+	/* Return the value of the string read */
+	return buf[0] - '0';
+}
+
+static int
+set_sysctl(const char* prefix, const char* iface, const char* parameter, int value)
+{
+	char* filename;
+	char buf[1];
+	int fd;
+	int len;
+
+	/* Make the filename */
+	filename = MALLOC(PATH_MAX);
+	make_sysctl_filename(filename, prefix, iface, parameter);
+
+	fd = open(filename, O_WRONLY);
+	FREE(filename);
+	if (fd <0)
+		return -1;
+
+	/* We only write integers 0-9 */
+	buf[0] = '0' + value;
+	len = write(fd, &buf, 1);
+	close(fd);
+
+	if (len != 1)
+		return -1;
+
+	/* Success */
+	return 0;
+}
+
+void
+set_interface_parameters(interface_t *ifp, interface_t *base_ifp)
+{
+       set_sysctl("net/ipv4/conf", ifp->ifname, "arp_ignore", 2);
+       if (base_ifp->reset_arp_ignore)
+               base_ifp->reset_arp_ignore++;
+       else if (get_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_ignore") == 0) {
+               set_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_ignore", 1);
+               base_ifp->reset_arp_ignore = 1;
+       }
+       set_sysctl("net/ipv4/conf", ifp->ifname, "rp_filter", 0);
+}
+
+void reset_interface_parameters(interface_t *base_ifp)
+{
+       set_sysctl("net/ipv4/conf", base_ifp->ifname, "arp_ignore", 0);
+}
+#endif
+
 static int
 netlink_link_up(vrrp_t *vrrp)
 {
@@ -69,6 +187,7 @@ netlink_link_add_vmac(vrrp_t *vrrp)
 	struct rtattr *data;
 	unsigned int base_ifindex;
 	interface_t *ifp;
+	interface_t *base_ifp;
 	char ifname[IFNAMSIZ];
 	u_char ll_addr[ETH_ALEN] = {0x00, 0x00, 0x5e, 0x00, 0x01, vrrp->vrid};
 	struct {
@@ -175,6 +294,7 @@ netlink_link_add_vmac(vrrp_t *vrrp)
 	ifp = if_get_by_ifname(ifname);
 	if (!ifp)
 		return -1;
+	base_ifp = vrrp->ifp;
 	base_ifindex = vrrp->ifp->ifindex;
 	ifp->flags = vrrp->ifp->flags; /* Copy base interface flags */
 	vrrp->ifp = ifp;
@@ -183,6 +303,11 @@ netlink_link_add_vmac(vrrp_t *vrrp)
 	vrrp->vmac_ifindex = IF_INDEX(vrrp->ifp); /* For use on delete */
 	__set_bit(VRRP_VMAC_UP_BIT, &vrrp->vmac_flags);
 	netlink_link_up(vrrp);
+
+	if (vrrp->family == AF_INET) {
+		/* Set the necessary kernel parameters to make macvlans work for us */
+		set_interface_parameters(ifp, base_ifp);
+	}
 #endif
 	return 1;
 }
@@ -193,6 +318,7 @@ netlink_link_del_vmac(vrrp_t *vrrp)
 	int status = 1;
 
 #ifdef _HAVE_VRRP_VMAC_
+	interface_t *base_ifp ;
 	struct {
 		struct nlmsghdr n;
 		struct ifinfomsg ifi;
@@ -202,6 +328,12 @@ netlink_link_del_vmac(vrrp_t *vrrp)
 	if (!vrrp->ifp)
 		return -1;
 
+	/* Reset arp_ignore on the base interface if necessary */
+	base_ifp = if_get_by_ifindex(vrrp->ifp->base_ifindex);
+	if (base_ifp->reset_arp_ignore && --base_ifp->reset_arp_ignore == 0) {
+		reset_interface_parameters(base_ifp);
+	}
+
 	memset(&req, 0, sizeof (req));
 
 	req.n.nlmsg_len = NLMSG_LENGTH(sizeof (struct ifinfomsg));
-- 
1.7.7.6


------------------------------------------------------------------------------
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.