From 718e3744195351130f4ce7dbe0613f4b3e23df93 Mon Sep 17 00:00:00 2001 From: paul Date: Fri, 13 Dec 2002 20:15:29 +0000 Subject: Initial revision --- zebra/ioctl.c | 540 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 540 insertions(+) create mode 100644 zebra/ioctl.c (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c new file mode 100644 index 00000000..13afba29 --- /dev/null +++ b/zebra/ioctl.c @@ -0,0 +1,540 @@ +/* + * Common ioctl functions. + * Copyright (C) 1997, 98 Kunihiro Ishiguro + * + * 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 + +#include "linklist.h" +#include "if.h" +#include "prefix.h" +#include "ioctl.h" +#include "log.h" + +#include "zebra/rib.h" +#include "zebra/rt.h" + +/* clear and set interface name string */ +void +ifreq_set_name (struct ifreq *ifreq, struct interface *ifp) +{ + strncpy (ifreq->ifr_name, ifp->name, IFNAMSIZ); +} + +/* call ioctl system call */ +int +if_ioctl (u_long request, caddr_t buffer) +{ + int sock; + int ret = 0; + int err = 0; + + sock = socket (AF_INET, SOCK_DGRAM, 0); + if (sock < 0) + { + perror ("socket"); + exit (1); + } + + ret = ioctl (sock, request, buffer); + if (ret < 0) + { + err = errno; + } + close (sock); + + if (ret < 0) + { + errno = err; + return ret; + } + return 0; +} + +#ifdef HAVE_IPV6 +int +if_ioctl_ipv6 (u_long request, caddr_t buffer) +{ + int sock; + int ret = 0; + int err = 0; + + sock = socket (AF_INET6, SOCK_DGRAM, 0); + if (sock < 0) + { + perror ("socket"); + exit (1); + } + + ret = ioctl (sock, request, buffer); + if (ret < 0) + { + err = errno; + } + close (sock); + + if (ret < 0) + { + errno = err; + return ret; + } + return 0; +} +#endif /* HAVE_IPV6 */ + +/* + * get interface metric + * -- if value is not avaliable set -1 + */ +void +if_get_metric (struct interface *ifp) +{ +#ifdef SIOCGIFMETRIC + struct ifreq ifreq; + + ifreq_set_name (&ifreq, ifp); + + if (if_ioctl (SIOCGIFMETRIC, (caddr_t) &ifreq) < 0) + return; + ifp->metric = ifreq.ifr_metric; + if (ifp->metric == 0) + ifp->metric = 1; +#else /* SIOCGIFMETRIC */ + ifp->metric = -1; +#endif /* SIOCGIFMETRIC */ +} + +/* get interface MTU */ +void +if_get_mtu (struct interface *ifp) +{ + struct ifreq ifreq; + + ifreq_set_name (&ifreq, ifp); + +#if defined(SIOCGIFMTU) + if (if_ioctl (SIOCGIFMTU, (caddr_t) & ifreq) < 0) + { + zlog_info ("Can't lookup mtu by ioctl(SIOCGIFMTU)"); + ifp->mtu = -1; + return; + } + +#ifdef SUNOS_5 + ifp->mtu = ifreq.ifr_metric; +#else + ifp->mtu = ifreq.ifr_mtu; +#endif /* SUNOS_5 */ + +#else + zlog (NULL, LOG_INFO, "Can't lookup mtu on this system"); + ifp->mtu = -1; +#endif +} + +#ifdef HAVE_NETLINK +/* Interface address setting via netlink interface. */ +int +if_set_prefix (struct interface *ifp, struct connected *ifc) +{ + return kernel_address_add_ipv4 (ifp, ifc); +} + +/* Interface address is removed using netlink interface. */ +int +if_unset_prefix (struct interface *ifp, struct connected *ifc) +{ + return kernel_address_delete_ipv4 (ifp, ifc); +} +#else /* ! HAVE_NETLINK */ +#ifdef HAVE_IFALIASREQ +/* Set up interface's IP address, netmask (and broadcas? ). *BSD may + has ifaliasreq structure. */ +int +if_set_prefix (struct interface *ifp, struct connected *ifc) +{ + int ret; + struct ifaliasreq addreq; + struct sockaddr_in addr; + struct sockaddr_in mask; + struct prefix_ipv4 *p; + + p = (struct prefix_ipv4 *) ifc->address; + + memset (&addreq, 0, sizeof addreq); + strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); + + memset (&addr, 0, sizeof (struct sockaddr_in)); + addr.sin_addr = p->prefix; + addr.sin_family = p->family; +#ifdef HAVE_SIN_LEN + addr.sin_len = sizeof (struct sockaddr_in); +#endif + memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in)); + + memset (&mask, 0, sizeof (struct sockaddr_in)); + masklen2ip (p->prefixlen, &mask.sin_addr); + mask.sin_family = p->family; +#ifdef HAVE_SIN_LEN + mask.sin_len = sizeof (struct sockaddr_in); +#endif + memcpy (&addreq.ifra_mask, &mask, sizeof (struct sockaddr_in)); + + ret = if_ioctl (SIOCAIFADDR, (caddr_t) &addreq); + if (ret < 0) + return ret; + return 0; +} + +/* Set up interface's IP address, netmask (and broadcas? ). *BSD may + has ifaliasreq structure. */ +int +if_unset_prefix (struct interface *ifp, struct connected *ifc) +{ + int ret; + struct ifaliasreq addreq; + struct sockaddr_in addr; + struct sockaddr_in mask; + struct prefix_ipv4 *p; + + p = (struct prefix_ipv4 *)ifc->address; + + memset (&addreq, 0, sizeof addreq); + strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); + + memset (&addr, 0, sizeof (struct sockaddr_in)); + addr.sin_addr = p->prefix; + addr.sin_family = p->family; +#ifdef HAVE_SIN_LEN + addr.sin_len = sizeof (struct sockaddr_in); +#endif + memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in)); + + memset (&mask, 0, sizeof (struct sockaddr_in)); + masklen2ip (p->prefixlen, &mask.sin_addr); + mask.sin_family = p->family; +#ifdef HAVE_SIN_LEN + mask.sin_len = sizeof (struct sockaddr_in); +#endif + memcpy (&addreq.ifra_mask, &mask, sizeof (struct sockaddr_in)); + + ret = if_ioctl (SIOCDIFADDR, (caddr_t) &addreq); + if (ret < 0) + return ret; + return 0; +} +#else +/* Set up interface's address, netmask (and broadcas? ). Linux or + Solaris uses ifname:number semantics to set IP address aliases. */ +int +if_set_prefix (struct interface *ifp, struct connected *ifc) +{ + int ret; + struct ifreq ifreq; + struct sockaddr_in addr; + struct sockaddr_in broad; + struct sockaddr_in mask; + struct prefix_ipv4 ifaddr; + struct prefix_ipv4 *p; + + p = (struct prefix_ipv4 *) ifc->address; + + ifaddr = *p; + + ifreq_set_name (&ifreq, ifp); + + addr.sin_addr = p->prefix; + addr.sin_family = p->family; + memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in)); + ret = if_ioctl (SIOCSIFADDR, (caddr_t) &ifreq); + if (ret < 0) + return ret; + + /* We need mask for make broadcast addr. */ + masklen2ip (p->prefixlen, &mask.sin_addr); + + if (if_is_broadcast (ifp)) + { + apply_mask_ipv4 (&ifaddr); + addr.sin_addr = ifaddr.prefix; + + broad.sin_addr.s_addr = (addr.sin_addr.s_addr | ~mask.sin_addr.s_addr); + broad.sin_family = p->family; + + memcpy (&ifreq.ifr_broadaddr, &broad, sizeof (struct sockaddr_in)); + ret = if_ioctl (SIOCSIFBRDADDR, (caddr_t) &ifreq); + if (ret < 0) + return ret; + } + + mask.sin_family = p->family; +#ifdef SUNOS_5 + memcpy (&mask, &ifreq.ifr_addr, sizeof (mask)); +#else + memcpy (&ifreq.ifr_netmask, &mask, sizeof (struct sockaddr_in)); +#endif /* SUNOS5 */ + ret = if_ioctl (SIOCSIFNETMASK, (caddr_t) &ifreq); + if (ret < 0) + return ret; + + return 0; +} + +/* Set up interface's address, netmask (and broadcas? ). Linux or + Solaris uses ifname:number semantics to set IP address aliases. */ +int +if_unset_prefix (struct interface *ifp, struct connected *ifc) +{ + int ret; + struct ifreq ifreq; + struct sockaddr_in addr; + struct prefix_ipv4 *p; + + p = (struct prefix_ipv4 *) ifc->address; + + ifreq_set_name (&ifreq, ifp); + + memset (&addr, 0, sizeof (struct sockaddr_in)); + addr.sin_family = p->family; + memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in)); + ret = if_ioctl (SIOCSIFADDR, (caddr_t) &ifreq); + if (ret < 0) + return ret; + + return 0; +} +#endif /* HAVE_IFALIASREQ */ +#endif /* HAVE_NETLINK */ + +/* get interface flags */ +void +if_get_flags (struct interface *ifp) +{ + int ret; + struct ifreq ifreq; + + ifreq_set_name (&ifreq, ifp); + + ret = if_ioctl (SIOCGIFFLAGS, (caddr_t) &ifreq); + if (ret < 0) + { + perror ("ioctl"); + return; + } + + ifp->flags = ifreq.ifr_flags & 0x0000ffff; +} + +/* Set interface flags */ +int +if_set_flags (struct interface *ifp, unsigned long flags) +{ + int ret; + struct ifreq ifreq; + + ifreq_set_name (&ifreq, ifp); + + ifreq.ifr_flags = ifp->flags; + ifreq.ifr_flags |= flags; + + ret = if_ioctl (SIOCSIFFLAGS, (caddr_t) &ifreq); + + if (ret < 0) + { + zlog_info ("can't set interface flags"); + return ret; + } + return 0; +} + +/* Unset interface's flag. */ +int +if_unset_flags (struct interface *ifp, unsigned long flags) +{ + int ret; + struct ifreq ifreq; + + ifreq_set_name (&ifreq, ifp); + + ifreq.ifr_flags = ifp->flags; + ifreq.ifr_flags &= ~flags; + + ret = if_ioctl (SIOCSIFFLAGS, (caddr_t) &ifreq); + + if (ret < 0) + { + zlog_info ("can't unset interface flags"); + return ret; + } + return 0; +} + +#ifdef HAVE_IPV6 + +#ifdef LINUX_IPV6 +#ifndef _LINUX_IN6_H +/* linux/include/net/ipv6.h */ +struct in6_ifreq +{ + struct in6_addr ifr6_addr; + u_int32_t ifr6_prefixlen; + int ifr6_ifindex; +}; +#endif /* _LINUX_IN6_H */ + +/* Interface's address add/delete functions. */ +int +if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) +{ + int ret; + struct prefix_ipv6 *p; + struct in6_ifreq ifreq; + + p = (struct prefix_ipv6 *) ifc->address; + + memset (&ifreq, 0, sizeof (struct in6_ifreq)); + + memcpy (&ifreq.ifr6_addr, &p->prefix, sizeof (struct in6_addr)); + ifreq.ifr6_ifindex = ifp->ifindex; + ifreq.ifr6_prefixlen = p->prefixlen; + + ret = if_ioctl_ipv6 (SIOCSIFADDR, (caddr_t) &ifreq); + + return ret; +} + +int +if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) +{ + int ret; + struct prefix_ipv6 *p; + struct in6_ifreq ifreq; + + p = (struct prefix_ipv6 *) ifc->address; + + memset (&ifreq, 0, sizeof (struct in6_ifreq)); + + memcpy (&ifreq.ifr6_addr, &p->prefix, sizeof (struct in6_addr)); + ifreq.ifr6_ifindex = ifp->ifindex; + ifreq.ifr6_prefixlen = p->prefixlen; + + ret = if_ioctl_ipv6 (SIOCDIFADDR, (caddr_t) &ifreq); + + return ret; +} +#else /* LINUX_IPV6 */ +#ifdef HAVE_IN6_ALIASREQ +#ifndef ND6_INFINITE_LIFETIME +#define ND6_INFINITE_LIFETIME 0xffffffffL +#endif /* ND6_INFINITE_LIFETIME */ +int +if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) +{ + int ret; + struct in6_aliasreq addreq; + struct sockaddr_in6 addr; + struct sockaddr_in6 mask; + struct prefix_ipv6 *p; + + p = (struct prefix_ipv6 * ) ifc->address; + + memset (&addreq, 0, sizeof addreq); + strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); + + memset (&addr, 0, sizeof (struct sockaddr_in6)); + addr.sin6_addr = p->prefix; + addr.sin6_family = p->family; +#ifdef HAVE_SIN_LEN + addr.sin6_len = sizeof (struct sockaddr_in6); +#endif + memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in6)); + + memset (&mask, 0, sizeof (struct sockaddr_in6)); + masklen2ip6 (p->prefixlen, &mask.sin6_addr); + mask.sin6_family = p->family; +#ifdef HAVE_SIN_LEN + mask.sin6_len = sizeof (struct sockaddr_in6); +#endif + memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6)); + + addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; + addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; + + ret = if_ioctl_ipv6 (SIOCAIFADDR_IN6, (caddr_t) &addreq); + if (ret < 0) + return ret; + return 0; +} + +int +if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) +{ + int ret; + struct in6_aliasreq addreq; + struct sockaddr_in6 addr; + struct sockaddr_in6 mask; + struct prefix_ipv6 *p; + + p = (struct prefix_ipv6 *) ifc->address; + + memset (&addreq, 0, sizeof addreq); + strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); + + memset (&addr, 0, sizeof (struct sockaddr_in6)); + addr.sin6_addr = p->prefix; + addr.sin6_family = p->family; +#ifdef HAVE_SIN_LEN + addr.sin6_len = sizeof (struct sockaddr_in6); +#endif + memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in6)); + + memset (&mask, 0, sizeof (struct sockaddr_in6)); + masklen2ip6 (p->prefixlen, &mask.sin6_addr); + mask.sin6_family = p->family; +#ifdef HAVE_SIN_LEN + mask.sin6_len = sizeof (struct sockaddr_in6); +#endif + memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6)); + + addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; + addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; + + ret = if_ioctl_ipv6 (SIOCDIFADDR_IN6, (caddr_t) &addreq); + if (ret < 0) + return ret; + return 0; +} +#else +int +if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) +{ + return 0; +} + +int +if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) +{ + return 0; +} +#endif /* HAVE_IN6_ALIASREQ */ + +#endif /* LINUX_IPV6 */ + +#endif /* HAVE_IPV6 */ -- cgit v1.2.3 From 726f9b2bbdd5a607f7b0a10a64547739b807e361 Mon Sep 17 00:00:00 2001 From: hasso Date: Sun, 25 May 2003 21:04:54 +0000 Subject: Last fixes from 6Wind patch. --- zebra/ioctl.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 13afba29..3e5d1d2f 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -474,8 +474,10 @@ if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) #endif memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6)); +#ifdef HAVE_IFRA_LIFETIME addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; +#endif ret = if_ioctl_ipv6 (SIOCAIFADDR_IN6, (caddr_t) &addreq); if (ret < 0) @@ -513,8 +515,10 @@ if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) #endif memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6)); +#ifdef HAVE_IFRA_LIFETIME addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; +#endif ret = if_ioctl_ipv6 (SIOCDIFADDR_IN6, (caddr_t) &addreq); if (ret < 0) -- cgit v1.2.3 From edd7c245d3a77012abf801da00d5664ebaa5f749 Mon Sep 17 00:00:00 2001 From: paul Date: Wed, 4 Jun 2003 13:59:38 +0000 Subject: 2003-06-04 Paul Jakma * Merge of zebra privileges --- zebra/ioctl.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 3e5d1d2f..f8e7f22b 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -27,10 +27,13 @@ #include "prefix.h" #include "ioctl.h" #include "log.h" +#include "privs.h" #include "zebra/rib.h" #include "zebra/rt.h" +extern struct zebra_privs_t zserv_privs; + /* clear and set interface name string */ void ifreq_set_name (struct ifreq *ifreq, struct interface *ifp) @@ -46,14 +49,19 @@ if_ioctl (u_long request, caddr_t buffer) int ret = 0; int err = 0; + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); sock = socket (AF_INET, SOCK_DGRAM, 0); if (sock < 0) { + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); perror ("socket"); exit (1); } - ret = ioctl (sock, request, buffer); + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); if (ret < 0) { err = errno; @@ -76,14 +84,21 @@ if_ioctl_ipv6 (u_long request, caddr_t buffer) int ret = 0; int err = 0; + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); sock = socket (AF_INET6, SOCK_DGRAM, 0); if (sock < 0) { + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); perror ("socket"); exit (1); } ret = ioctl (sock, request, buffer); + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); + if (ret < 0) { err = errno; -- cgit v1.2.3 From 0e4f190ebf5a26e4b66fb49cd74ae0ff0c7e0863 Mon Sep 17 00:00:00 2001 From: paul Date: Thu, 12 Jun 2003 02:13:45 +0000 Subject: 2003-06-12 Paul Jakma * zebra/ioctl.c: Properly zero-out struct ifreq before passing it to the SIOCSIFFLAGS ioctl(2), so that it doesn't occasionally trigger promisc mode on interface. Reported/tested by: Vladimir B. Grebenschikov (patch snarfed taken from FreeBSD ports) --- zebra/ioctl.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index f8e7f22b..1a682e27 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -364,6 +364,7 @@ if_set_flags (struct interface *ifp, unsigned long flags) int ret; struct ifreq ifreq; + bzero(&ifreq, sizeof(struct ifreq)); ifreq_set_name (&ifreq, ifp); ifreq.ifr_flags = ifp->flags; @@ -386,6 +387,7 @@ if_unset_flags (struct interface *ifp, unsigned long flags) int ret; struct ifreq ifreq; + bzero(&ifreq, sizeof(struct ifreq)); ifreq_set_name (&ifreq, ifp); ifreq.ifr_flags = ifp->flags; @@ -488,6 +490,9 @@ if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) mask.sin6_len = sizeof (struct sockaddr_in6); #endif memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6)); + + addreq.ifra_lifetime.ia6t_vltime = 0xffffffff; + addreq.ifra_lifetime.ia6t_pltime = 0xffffffff; #ifdef HAVE_IFRA_LIFETIME addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; -- cgit v1.2.3 From d1724b6555510c22d2df55a9245fe4e6f1b08922 Mon Sep 17 00:00:00 2001 From: paul Date: Wed, 22 Oct 2003 02:41:52 +0000 Subject: 2003-10-22 Paul Jakma * lib/regex.c: bzero -> memset * zebra/ioctl.c: ditto. bzero is not portable. --- zebra/ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 1a682e27..ff253be1 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -364,7 +364,7 @@ if_set_flags (struct interface *ifp, unsigned long flags) int ret; struct ifreq ifreq; - bzero(&ifreq, sizeof(struct ifreq)); + memset (&ifreq, 0, sizeof(struct ifreq)); ifreq_set_name (&ifreq, ifp); ifreq.ifr_flags = ifp->flags; @@ -387,7 +387,7 @@ if_unset_flags (struct interface *ifp, unsigned long flags) int ret; struct ifreq ifreq; - bzero(&ifreq, sizeof(struct ifreq)); + memset (&ifreq, 0, sizeof(struct ifreq)); ifreq_set_name (&ifreq, ifp); ifreq.ifr_flags = ifp->flags; -- cgit v1.2.3 From 44145db3ae79d54da58c967d96cf059421dbf9eb Mon Sep 17 00:00:00 2001 From: paul Date: Sun, 9 May 2004 11:00:23 +0000 Subject: 2004-05-09 Paul Jakma * ioctl.c: (if_get_mtu) set mtu6 to mtu * mtu_kvm.c: (if_kvm_get_mtu) set mtu6 to mtu * rt_netlink.c: (netlink_interface) set mtu6 to mtu (netlink_link_change) ditto 2004-05-09 Sowmini Varadhan * interface.c: (if_delete_update) only used with HAVE_NETLINK and RTM_IFANNOUNCE. (if_flag_dump_vty) Solaris IFF_IPV4 and IFF_IPV6 if flags (if_dump_vty) print mtu6 if not same as mtu --- zebra/ioctl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index ff253be1..eca0e769 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -148,19 +148,19 @@ if_get_mtu (struct interface *ifp) if (if_ioctl (SIOCGIFMTU, (caddr_t) & ifreq) < 0) { zlog_info ("Can't lookup mtu by ioctl(SIOCGIFMTU)"); - ifp->mtu = -1; + ifp->mtu6 = ifp->mtu = -1; return; } #ifdef SUNOS_5 - ifp->mtu = ifreq.ifr_metric; + ifp->mtu6 = ifp->mtu = ifreq.ifr_metric; #else - ifp->mtu = ifreq.ifr_mtu; + ifp->mtu6 = ifp->mtu = ifreq.ifr_mtu; #endif /* SUNOS_5 */ #else zlog (NULL, LOG_INFO, "Can't lookup mtu on this system"); - ifp->mtu = -1; + ifp->mtu6 = ifp->mtu = -1; #endif } -- cgit v1.2.3 From 4460e7a4cf3dadcd9f06e4b519ba7be2cc936c0a Mon Sep 17 00:00:00 2001 From: ajs Date: Sat, 29 Jan 2005 17:07:40 +0000 Subject: 2005-01-29 Andrew J. Schorr * if_ioctl_solaris.c: (interface_list_ioctl) Save errno before calling zserv_privs.change. * ioctl{,_solaris}.c: (if_ioctl,if_ioctl_ipv6) Save errno before calling zserv_privs.change. * ipforward_solaris.c: (solaris_nd) Save errno before calling zserv_privs.change. * irdp_main.c: (irdp_sock_init) Save errno before calling zserv_privs.change. [backport candidate] --- zebra/ioctl.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index eca0e769..e28d359e 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -46,8 +46,8 @@ int if_ioctl (u_long request, caddr_t buffer) { int sock; - int ret = 0; - int err = 0; + int ret; + int err; if (zserv_privs.change(ZPRIVS_RAISE)) zlog (NULL, LOG_ERR, "Can't raise privileges"); @@ -59,13 +59,10 @@ if_ioctl (u_long request, caddr_t buffer) perror ("socket"); exit (1); } - ret = ioctl (sock, request, buffer); + if ((ret = ioctl (sock, request, buffer)) < 0) + err = errno; if (zserv_privs.change(ZPRIVS_LOWER)) zlog (NULL, LOG_ERR, "Can't lower privileges"); - if (ret < 0) - { - err = errno; - } close (sock); if (ret < 0) @@ -81,8 +78,8 @@ int if_ioctl_ipv6 (u_long request, caddr_t buffer) { int sock; - int ret = 0; - int err = 0; + int ret; + int err; if (zserv_privs.change(ZPRIVS_RAISE)) zlog (NULL, LOG_ERR, "Can't raise privileges"); @@ -95,14 +92,10 @@ if_ioctl_ipv6 (u_long request, caddr_t buffer) exit (1); } - ret = ioctl (sock, request, buffer); + if ((ret = ioctl (sock, request, buffer)) < 0) + err = errno; if (zserv_privs.change(ZPRIVS_LOWER)) zlog (NULL, LOG_ERR, "Can't lower privileges"); - - if (ret < 0) - { - err = errno; - } close (sock); if (ret < 0) -- cgit v1.2.3 From 6a52d0d155fc8b892e30cdb5e3fbe4c2779bd4cd Mon Sep 17 00:00:00 2001 From: ajs Date: Sun, 30 Jan 2005 18:49:28 +0000 Subject: 2005-01-30 Andrew J. Schorr * daemon.c: (daemon) Replace perror with zlog_err. * vty.c: (vty_serv_un) Replace perror with zlog_err. * ripd.c: (rip_create_socket) Replace perror with zlog_err. * ioctl.c: (if_ioctl,if_ioctl_ipv6,if_get_flags) Replace perror with zlog_err. * ioctl_solaris.c: (if_ioctl,if_ioctl_ipv6) Replace perror with zlog_err. --- zebra/ioctl.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index e28d359e..56de810c 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -54,9 +54,10 @@ if_ioctl (u_long request, caddr_t buffer) sock = socket (AF_INET, SOCK_DGRAM, 0); if (sock < 0) { + int save_errno = errno; if (zserv_privs.change(ZPRIVS_LOWER)) zlog (NULL, LOG_ERR, "Can't lower privileges"); - perror ("socket"); + zlog_err("Cannot create UDP socket: %s", safe_strerror(save_errno)); exit (1); } if ((ret = ioctl (sock, request, buffer)) < 0) @@ -86,9 +87,11 @@ if_ioctl_ipv6 (u_long request, caddr_t buffer) sock = socket (AF_INET6, SOCK_DGRAM, 0); if (sock < 0) { + int save_errno = errno; if (zserv_privs.change(ZPRIVS_LOWER)) zlog (NULL, LOG_ERR, "Can't lower privileges"); - perror ("socket"); + zlog_err("Cannot create IPv6 datagram socket: %s", + safe_strerror(save_errno)); exit (1); } @@ -343,7 +346,7 @@ if_get_flags (struct interface *ifp) ret = if_ioctl (SIOCGIFFLAGS, (caddr_t) &ifreq); if (ret < 0) { - perror ("ioctl"); + zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s", safe_strerror(errno)); return; } -- cgit v1.2.3 From a1ac18c4d5b4f8f4f279efb2ae12b46258f22282 Mon Sep 17 00:00:00 2001 From: paul Date: Tue, 28 Jun 2005 17:17:12 +0000 Subject: 2005-06-28 Paul Jakma * (global) Extern and static'ification, with related fixups of declarations, ensuring files include their own headers, etc. if_ioctl.c: (interface_info_ioctl) fix obvious arg mis-order in list loop --- zebra/ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 56de810c..4137acfa 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -75,7 +75,7 @@ if_ioctl (u_long request, caddr_t buffer) } #ifdef HAVE_IPV6 -int +static int if_ioctl_ipv6 (u_long request, caddr_t buffer) { int sock; -- cgit v1.2.3 From 5c78b3d006e6926f938796cffa08e8e14fb8e7af Mon Sep 17 00:00:00 2001 From: paul Date: Wed, 25 Jan 2006 04:31:40 +0000 Subject: [zebra/solaris] Interface state fixups for Solaris. 2006-01-25 Paul Jakma * (general) More solaris PF_ROUTE hacks. The IFF_UP mangling for solaris was incomplete on the PF_ROUTE side. fix it. This changeset generally uglifies things. For some future work I'd like to see the state changes seperated out from the details of the code. Differences between systems might then be slightly easier to implement without convoluted hacks. Changes should be specific to Solaris mostly, however also tested on FreeBSD 6. * if_ioctl_solaris.c: (interface_list_ioctl) ignore ~IFF_UP interfaces, we'll hear about them when/if interface goes up through NEWADDR. Update flags explicitely at end of it to kick mangling. * ioctl_solaris.c: (if_mangle_up) removed to interface.c, in kind. (lifreq_set_name) more convenient to take the string, than the ifp. (if_get_flags_direct) new convenience function, returns the actual flags. Used during bootstrap in if_ioctl_solaris.c to peek at flags of logical interfaces to see whether or not to ignore them. (if_get_flags) ENXIO means it's gone, poke out IFF_UP and kick flags update. (if_{un,}set_flags) flags argument should be 64bit. * ioctl.{c,h}: flags argument should be 64bit. * interface.h: Add a 'primary_state' flag to struct zebra_if on SUNOS_5. Export if_flags_update. * interface.c: (if_flags_mangle) moved over in kind from ioctl_solaris.c. Nasty kludge to try get IFF_UP right, as much as is possible. Also keep track of the actual IFF_UP value for the primary interface, so we can know when the ifp must be deleted. (if_flags_update) Take a new interface flags value, apply it to the interface, and take whatever actions are required due to flag transitions. (if_refresh) flag state change logic is moved out to previous. Just call if_get_flags, which will end up using previous to effect the update of flags. (if_flag_dump_vty) IFF_IPV{4,6} aren't interesting, VIRTUAL and NOXMIT are though. * kernel_socket.c: (ifm_read) Down->Down transitions shouldn't create ifp, for non-IFANNOUNCE systems. Use if_flags_update to update flags. flag transition logic is now handled automatically through if_flags_update. (ifam_read) Better to call if_refresh *after* adding connected addresses, as connected count affects IFF_UP on IFF_UP-mangled systems. On Solaris, Up->Down due to DELADDR means we need to delete the ifp - the IFINFO might already have been and gone. * rt.h: include other dependent headers. --- zebra/ioctl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 4137acfa..06be5bec 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -31,6 +31,7 @@ #include "zebra/rib.h" #include "zebra/rt.h" +#include "zebra/interface.h" extern struct zebra_privs_t zserv_privs; @@ -350,12 +351,12 @@ if_get_flags (struct interface *ifp) return; } - ifp->flags = ifreq.ifr_flags & 0x0000ffff; + if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff)); } /* Set interface flags */ int -if_set_flags (struct interface *ifp, unsigned long flags) +if_set_flags (struct interface *ifp, uint64_t flags) { int ret; struct ifreq ifreq; @@ -378,7 +379,7 @@ if_set_flags (struct interface *ifp, unsigned long flags) /* Unset interface's flag. */ int -if_unset_flags (struct interface *ifp, unsigned long flags) +if_unset_flags (struct interface *ifp, uint64_t flags) { int ret; struct ifreq ifreq; -- cgit v1.2.3 From 7c2602a1df9aaeec980d05683ca88890315d0bc5 Mon Sep 17 00:00:00 2001 From: paul Date: Tue, 10 Apr 2007 19:43:43 +0000 Subject: [zebra] MTU change should propogate to zserv client on BSD/Solaris 2007-04-10 Paul Jakma * ioctl{_solaris,}.c: (if_get_mtu) Ping clients via zebra_interface_up_update if MTU is changed. --- zebra/ioctl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 06be5bec..ccb927ac 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -155,6 +155,9 @@ if_get_mtu (struct interface *ifp) ifp->mtu6 = ifp->mtu = ifreq.ifr_mtu; #endif /* SUNOS_5 */ + /* propogate */ + zebra_interface_up_update(ifp); + #else zlog (NULL, LOG_INFO, "Can't lookup mtu on this system"); ifp->mtu6 = ifp->mtu = -1; -- cgit v1.2.3 From 66afda8a04f8fe0a64a4b4a5a94348b65f561885 Mon Sep 17 00:00:00 2001 From: paul Date: Thu, 10 May 2007 02:38:51 +0000 Subject: [autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings 2007-05-09 Paul Jakma * configure.ac: sys/conf.h depends on sys/param.h, at least on FBSD 6.2. (bug #363) Should check for in_pktinfo for IRDP 2006-05-27 Paul Jakma * configure.ac: General cleanup of header and type checks, introducing an internal define, QUAGGA_INCLUDES, to build up a list of stuff to include so as to avoid 'present but cant be compiled' warnings. Misc additional checks of things missing according to autoscan. Add LIBM, for bgpd's use of libm, so as to avoid burdening LIBS, and all the binaries, with libm linkage. Remove the bad practice of using m4 changequote(), just quote the []'s in the case statements properly. This should fix bugs 162, 303 and 178. * */*.{c,h}: Update all HAVE_* to the standard autoconf namespaced HAVE_* defines. I.e. HAVE_SA_LEN -> HAVE_STRUCT_SOCKADDR_SA_LEN, * bgpd/Makefile.am: Add LIBM to bgpd's LDADD, for pow(). --- zebra/ioctl.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index ccb927ac..c9ec8d57 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -179,7 +179,7 @@ if_unset_prefix (struct interface *ifp, struct connected *ifc) return kernel_address_delete_ipv4 (ifp, ifc); } #else /* ! HAVE_NETLINK */ -#ifdef HAVE_IFALIASREQ +#ifdef HAVE_STRUCT_IFALIASREQ /* Set up interface's IP address, netmask (and broadcas? ). *BSD may has ifaliasreq structure. */ int @@ -199,7 +199,7 @@ if_set_prefix (struct interface *ifp, struct connected *ifc) memset (&addr, 0, sizeof (struct sockaddr_in)); addr.sin_addr = p->prefix; addr.sin_family = p->family; -#ifdef HAVE_SIN_LEN +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN addr.sin_len = sizeof (struct sockaddr_in); #endif memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in)); @@ -207,7 +207,7 @@ if_set_prefix (struct interface *ifp, struct connected *ifc) memset (&mask, 0, sizeof (struct sockaddr_in)); masklen2ip (p->prefixlen, &mask.sin_addr); mask.sin_family = p->family; -#ifdef HAVE_SIN_LEN +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN mask.sin_len = sizeof (struct sockaddr_in); #endif memcpy (&addreq.ifra_mask, &mask, sizeof (struct sockaddr_in)); @@ -237,7 +237,7 @@ if_unset_prefix (struct interface *ifp, struct connected *ifc) memset (&addr, 0, sizeof (struct sockaddr_in)); addr.sin_addr = p->prefix; addr.sin_family = p->family; -#ifdef HAVE_SIN_LEN +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN addr.sin_len = sizeof (struct sockaddr_in); #endif memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in)); @@ -245,7 +245,7 @@ if_unset_prefix (struct interface *ifp, struct connected *ifc) memset (&mask, 0, sizeof (struct sockaddr_in)); masklen2ip (p->prefixlen, &mask.sin_addr); mask.sin_family = p->family; -#ifdef HAVE_SIN_LEN +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN mask.sin_len = sizeof (struct sockaddr_in); #endif memcpy (&addreq.ifra_mask, &mask, sizeof (struct sockaddr_in)); @@ -335,7 +335,7 @@ if_unset_prefix (struct interface *ifp, struct connected *ifc) return 0; } -#endif /* HAVE_IFALIASREQ */ +#endif /* HAVE_STRUCT_IFALIASREQ */ #endif /* HAVE_NETLINK */ /* get interface flags */ @@ -457,7 +457,7 @@ if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) return ret; } #else /* LINUX_IPV6 */ -#ifdef HAVE_IN6_ALIASREQ +#ifdef HAVE_STRUCT_IN6_ALIASREQ #ifndef ND6_INFINITE_LIFETIME #define ND6_INFINITE_LIFETIME 0xffffffffL #endif /* ND6_INFINITE_LIFETIME */ @@ -478,7 +478,7 @@ if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) memset (&addr, 0, sizeof (struct sockaddr_in6)); addr.sin6_addr = p->prefix; addr.sin6_family = p->family; -#ifdef HAVE_SIN_LEN +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN addr.sin6_len = sizeof (struct sockaddr_in6); #endif memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in6)); @@ -486,7 +486,7 @@ if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) memset (&mask, 0, sizeof (struct sockaddr_in6)); masklen2ip6 (p->prefixlen, &mask.sin6_addr); mask.sin6_family = p->family; -#ifdef HAVE_SIN_LEN +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN mask.sin6_len = sizeof (struct sockaddr_in6); #endif memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6)); @@ -494,7 +494,7 @@ if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) addreq.ifra_lifetime.ia6t_vltime = 0xffffffff; addreq.ifra_lifetime.ia6t_pltime = 0xffffffff; -#ifdef HAVE_IFRA_LIFETIME +#ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; #endif @@ -522,7 +522,7 @@ if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) memset (&addr, 0, sizeof (struct sockaddr_in6)); addr.sin6_addr = p->prefix; addr.sin6_family = p->family; -#ifdef HAVE_SIN_LEN +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN addr.sin6_len = sizeof (struct sockaddr_in6); #endif memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in6)); @@ -530,12 +530,12 @@ if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) memset (&mask, 0, sizeof (struct sockaddr_in6)); masklen2ip6 (p->prefixlen, &mask.sin6_addr); mask.sin6_family = p->family; -#ifdef HAVE_SIN_LEN +#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN mask.sin6_len = sizeof (struct sockaddr_in6); #endif memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6)); -#ifdef HAVE_IFRA_LIFETIME +#ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; #endif @@ -557,7 +557,7 @@ if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) { return 0; } -#endif /* HAVE_IN6_ALIASREQ */ +#endif /* HAVE_STRUCT_IN6_ALIASREQ */ #endif /* LINUX_IPV6 */ -- cgit v1.2.3 From 1e70bfb680354e1ea007618851a16166d9397393 Mon Sep 17 00:00:00 2001 From: ajs Date: Thu, 10 Jan 2008 15:24:32 +0000 Subject: [link-detect] Try to get BSD link-detect to work properly. 2008-01-10 Ingo Flaschberger * configure.ac: Define HAVE_BSD_LINK_DETECT if is present. * lib/zebra.h: If HAVE_BSD_LINK_DETECT is defined, include . * zebra/ioctl.c: (if_get_flags) If HAVE_BSD_LINK_DETECT, use the SIOCGIFMEDIA ioctl to ascertain link state. * zebra/kernel_socket.c: (bsd_linkdetect_translate) New function to map the ifm_data.ifi_link_state value into the IFF_RUNNING flag. (ifm_read) Call bsd_linkdetect_translate to fix the IFF_RUNNING flag before calling if_flags_update. --- zebra/ioctl.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index c9ec8d57..4f99a6cd 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -344,6 +344,9 @@ if_get_flags (struct interface *ifp) { int ret; struct ifreq ifreq; +#ifdef HAVE_BSD_LINK_DETECT + struct ifmediareq ifmr; +#endif /* HAVE_BSD_LINK_DETECT */ ifreq_set_name (&ifreq, ifp); @@ -353,6 +356,36 @@ if_get_flags (struct interface *ifp) zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s", safe_strerror(errno)); return; } +#ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */ + (void) memset(&ifmr, 0, sizeof(ifmr)); + strncpy (&ifmr.ifm_name, ifp->name, IFNAMSIZ); + if (if_ioctl(SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) + { + zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s", safe_strerror(errno)); + return; + } + if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */ + { + if (ifmr.ifm_status & IFM_ACTIVE) + { + SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + zlog_debug("%s: BSD link state to up at interface %s, ifindex %d", + __func__, ifp->name, ifp->ifindex); + } + else + { + UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + zlog_debug("%s: BSD link state to down at interface %s, ifindex %d", + __func__, ifp->name, ifp->ifindex); + } + } + else /* Force always up */ + { + SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + zlog_debug("%s: BSD link state invalid, forced up at interface %s, ifindex %d", + __func__, ifp->name, ifp->ifindex); + } +#endif /* HAVE_BSD_LINK_DETECT */ if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff)); } -- cgit v1.2.3 From 033305144d57b98416df160adf3f050cd7c20b35 Mon Sep 17 00:00:00 2001 From: ajs Date: Fri, 11 Jan 2008 15:57:13 +0000 Subject: [link-detect] Improve BSD support. 2008-01-11 Andrew J. Schorr * lib/zebra.h: Revert previous change, no need to include here. * zebra/ioctl.c: If HAVE_BSD_LINK_DETECT is defined, include (if_get_flags) Remove debug messages about BSD link state. * zebra/kernel_socket.c: (bsd_linkdetect_translate) If link state is unknown, we should set the IFF_RUNNING flag. --- zebra/ioctl.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 4f99a6cd..7bb4da1f 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -33,6 +33,10 @@ #include "zebra/rt.h" #include "zebra/interface.h" +#ifdef HAVE_BSD_LINK_DETECT +#include +#endif /* HAVE_BSD_LINK_DETECT*/ + extern struct zebra_privs_t zserv_privs; /* clear and set interface name string */ @@ -367,24 +371,12 @@ if_get_flags (struct interface *ifp) if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */ { if (ifmr.ifm_status & IFM_ACTIVE) - { - SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); - zlog_debug("%s: BSD link state to up at interface %s, ifindex %d", - __func__, ifp->name, ifp->ifindex); - } + SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); else - { - UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); - zlog_debug("%s: BSD link state to down at interface %s, ifindex %d", - __func__, ifp->name, ifp->ifindex); - } + UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); } else /* Force always up */ - { - SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); - zlog_debug("%s: BSD link state invalid, forced up at interface %s, ifindex %d", - __func__, ifp->name, ifp->ifindex); - } + SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); #endif /* HAVE_BSD_LINK_DETECT */ if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff)); -- cgit v1.2.3 From 3b98020d90eeb01eccf07b899585819ce7b6c8b1 Mon Sep 17 00:00:00 2001 From: pilot Date: Tue, 26 Feb 2008 14:02:24 +0000 Subject: + fix bug#326 by rib_lookup_and_pushup() --- zebra/ioctl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 7bb4da1f..d536771a 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -196,6 +196,7 @@ if_set_prefix (struct interface *ifp, struct connected *ifc) struct prefix_ipv4 *p; p = (struct prefix_ipv4 *) ifc->address; + rib_lookup_and_pushup (p); memset (&addreq, 0, sizeof addreq); strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); -- cgit v1.2.3 From d32541332b3f59c69c24277e0220cbd92c3c1c98 Mon Sep 17 00:00:00 2001 From: paul Date: Tue, 1 Jul 2008 18:24:58 +0000 Subject: [zebra] Make BSD link-state deal more gracefully with GIFMEDIA ioctl error 2008-07-01 Paul Jakma * ioctl.c: (if_get_flags) Deal more gracefully with failure of the BSD link-state SIOCGIFMEDIA ioctl, as some interfaces apparently don't implement it (e.g. tun). Also, make BSD link-state checking be conditional on the 'link-detect' interface configuration flag, as it should be. Fixes bug #465. --- zebra/ioctl.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'zebra/ioctl.c') diff --git a/zebra/ioctl.c b/zebra/ioctl.c index d536771a..5cf9e7b0 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -362,22 +362,29 @@ if_get_flags (struct interface *ifp) return; } #ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */ - (void) memset(&ifmr, 0, sizeof(ifmr)); - strncpy (&ifmr.ifm_name, ifp->name, IFNAMSIZ); - if (if_ioctl(SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) - { - zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s", safe_strerror(errno)); - return; - } - if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */ + + /* Per-default, IFF_RUNNING is held high, unless link-detect says + * otherwise - we abuse IFF_RUNNING inside zebra as a link-state flag, + * following practice on Linux and Solaris kernels + */ + SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + + if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) { - if (ifmr.ifm_status & IFM_ACTIVE) - SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); - else - UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); - } - else /* Force always up */ - SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + (void) memset(&ifmr, 0, sizeof(ifmr)); + strncpy (&ifmr.ifm_name, ifp->name, IFNAMSIZ); + + /* Seems not all interfaces implement this ioctl */ + if (if_ioctl(SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) + zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s", safe_strerror(errno)); + else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */ + { + if (ifmr.ifm_status & IFM_ACTIVE) + SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + else + UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + } + } #endif /* HAVE_BSD_LINK_DETECT */ if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff)); -- cgit v1.2.3