diff options
author | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2008-05-22 16:06:06 -0700 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2008-05-22 16:06:06 -0700 |
commit | 98c5476432c7a5d9b6eb79ef60262f79efa4588f (patch) | |
tree | bae10ae44fae81ecae1eea8e570c2894d60075c4 | |
parent | a352c7a182f86d926191c31ed9d7e180e9a6287e (diff) | |
download | quagga-98c5476432c7a5d9b6eb79ef60262f79efa4588f.tar.bz2 quagga-98c5476432c7a5d9b6eb79ef60262f79efa4588f.tar.xz |
Turn on kernel link-detect
If interface has link-detect enabled, try and turn on link-detect
in the kernel.
-rwxr-xr-x | configure.ac | 6 | ||||
-rw-r--r-- | zebra/Makefile.am | 7 | ||||
-rw-r--r-- | zebra/if_linkdetect.c | 81 | ||||
-rw-r--r-- | zebra/interface.c | 7 | ||||
-rw-r--r-- | zebra/interface.h | 10 | ||||
-rw-r--r-- | zebra/linkdetect_null.c | 16 |
6 files changed, 124 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac index 9f18bd39..e679632f 100755 --- a/configure.ac +++ b/configure.ac @@ -931,6 +931,12 @@ if test -r /proc/net/if_inet6; then fi AC_SUBST(IF_PROC) +if test -r /proc/sys/net/ipv4/conf; then + AC_DEFINE(HAVE_PROC_NET_IPV4_CONF,,/proc/sys/net/ipv4/conf) + LINK_DETECT=if_linkdetect.o +fi +AC_SUBST(LINK_DETECT) + dnl ----------------------------- dnl check ipforward detect method dnl ----------------------------- diff --git a/zebra/Makefile.am b/zebra/Makefile.am index 5d8db411..8977c893 100644 --- a/zebra/Makefile.am +++ b/zebra/Makefile.am @@ -10,13 +10,14 @@ LIBCAP = @LIBCAP@ ipforward = @IPFORWARD@ if_method = @IF_METHOD@ if_proc = @IF_PROC@ +link_detect = @LINK_DETECT@ rt_method = @RT_METHOD@ rtread_method = @RTREAD_METHOD@ kernel_method = @KERNEL_METHOD@ other_method = @OTHER_METHOD@ ioctl_method = @IOCTL_METHOD@ -otherobj = $(ioctl_method) $(ipforward) $(if_method) $(if_proc) \ +otherobj = $(ioctl_method) $(ipforward) $(if_method) $(if_proc) $(link_detect) \ $(rt_method) $(rtread_method) $(kernel_method) $(other_method) sbin_PROGRAMS = zebra @@ -29,7 +30,7 @@ zebra_SOURCES = \ irdp_main.c irdp_interface.c irdp_packet.c router-id.c testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \ - zebra_vty.c \ + zebra_vty.c linkdetect_null.c \ kernel_null.c redistribute_null.c ioctl_null.c misc_null.c noinst_HEADERS = \ @@ -42,7 +43,7 @@ testzebra_LDADD = $(LIBCAP) $(LIB_IPV6) ../lib/libzebra.la zebra_DEPENDENCIES = $(otherobj) -EXTRA_DIST = if_ioctl.c if_ioctl_solaris.c if_netlink.c if_proc.c \ +EXTRA_DIST = if_ioctl.c if_ioctl_solaris.c if_linkdetect.c if_netlink.c if_proc.c \ if_sysctl.c ipforward_aix.c ipforward_ews.c ipforward_proc.c \ ipforward_solaris.c ipforward_sysctl.c rt_ioctl.c rt_netlink.c \ rt_socket.c rtread_netlink.c rtread_proc.c rtread_sysctl.c \ diff --git a/zebra/if_linkdetect.c b/zebra/if_linkdetect.c new file mode 100644 index 00000000..9ae7c6a6 --- /dev/null +++ b/zebra/if_linkdetect.c @@ -0,0 +1,81 @@ +/* Interface link state tracking + * Copyright (C) 2008 Stephen Hemminger + * + * This file is part of GNU Zebra. + * + * GNU Zebra 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, or (at your option) any + * later version. + * + * GNU Zebra 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. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include <zebra.h> +#include "log.h" +#include "privs.h" + +#include "log.h" +#include "privs.h" +#include "prefix.h" + +#include "zebra/interface.h" + +extern struct zebra_privs_t zserv_privs; + +static int +linkdetect (const char *name, int onoff) +{ + FILE *fp; + int save_errno; + char proc_name[128]; + + snprintf(proc_name, sizeof(proc_name)-1, + "/proc/sys/net/ipv4/conf/%s/link_detect", name); + + if ( zserv_privs.change(ZPRIVS_RAISE) ) + zlog_err ("Can't raise privileges, %s", safe_strerror (errno) ); + + fp = fopen (proc_name, "w"); + save_errno = errno; + if (!fp) + { + if ( zserv_privs.change(ZPRIVS_LOWER) ) + zlog_err ("Can't lower privileges, %s", safe_strerror (errno)); + + zlog_info("Can't %s link-detect, %s:%s", + onoff ? "enable" : "disable", + proc_name, safe_strerror(save_errno)); + return -1; + } + else + { + fprintf (fp, "%d\n", onoff); + fclose (fp); + + if ( zserv_privs.change(ZPRIVS_LOWER) ) + zlog_err ("Can't lower privileges, %s", safe_strerror (errno)); + + return onoff; + } +} + +int +if_linkdetect_on (const char *name) +{ + return linkdetect (name, 1); +} + +int +if_linkdetect_off (const char *name) +{ + return linkdetect (name, 1); +} diff --git a/zebra/interface.c b/zebra/interface.c index cfcd5120..f6d2ff9b 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -32,6 +32,7 @@ #include "connected.h" #include "log.h" #include "zclient.h" +#include "ipforward.h" #include "zebra/interface.h" #include "zebra/rtadv.h" @@ -1029,6 +1030,9 @@ DEFUN (linkdetect, if_was_operative = if_is_operative(ifp); SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); + /* Enable FIB to remove kernel routes as well */ + if_linkdetect_on(ifp->name); + /* When linkdetection is enabled, if might come down */ if (!if_is_operative(ifp) && if_was_operative) if_down(ifp); @@ -1052,6 +1056,9 @@ DEFUN (no_linkdetect, if_was_operative = if_is_operative(ifp); UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); + /* Disable FIB update on link-detect */ + if_linkdetect_off(ifp->name); + /* Interface may come up after disabling link detection */ if (if_is_operative(ifp) && !if_was_operative) if_up(ifp); diff --git a/zebra/interface.h b/zebra/interface.h index 0a6b0365..6f356686 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -234,6 +234,16 @@ extern int interface_list_proc (void); extern int ifaddr_proc_ipv6 (void); #endif /* HAVE_PROC_NET_IF_INET6 */ +#ifdef HAVE_PROC_NET_IPV4_CONF +extern int if_linkdetect_on (const char *); +extern int if_linkdetect_off (const char *); +#else +#error config +#define if_linkdetect_on(name) +#define if_linkdetect_off(name) +#endif + + #ifdef BSDI extern int if_kvm_get_mtu (struct interface *); #endif /* BSDI */ diff --git a/zebra/linkdetect_null.c b/zebra/linkdetect_null.c new file mode 100644 index 00000000..c33363e1 --- /dev/null +++ b/zebra/linkdetect_null.c @@ -0,0 +1,16 @@ +/* NULL method for testing. */ + +#include <zebra.h> + + +int +if_linkdetect_on (const char *name) +{ + return 0; +} + +int +if_linkdetect_off (const char *name) +{ + return 0; +} |