summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/connected.c2
-rw-r--r--zebra/debug.c2
-rw-r--r--zebra/if_netlink.c5
-rw-r--r--zebra/interface.c28
-rw-r--r--zebra/irdp_packet.c2
-rw-r--r--zebra/rib.h59
-rw-r--r--zebra/rt_netlink.c451
-rw-r--r--zebra/rtadv.c4
-rw-r--r--zebra/rtread_netlink.c6
-rw-r--r--zebra/zebra_rib.c189
10 files changed, 388 insertions, 360 deletions
diff --git a/zebra/connected.c b/zebra/connected.c
index ad3e9607..f3e5396c 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -86,7 +86,7 @@ connected_announce (struct interface *ifp, struct connected *ifc)
zebra_interface_address_add_update (ifp, ifc);
- if (if_is_up(ifp))
+ if (if_is_operative(ifp))
{
if (ifc->address->family == AF_INET)
connected_up_ipv4 (ifp, ifc);
diff --git a/zebra/debug.c b/zebra/debug.c
index 23c4de3a..175029b8 100644
--- a/zebra/debug.c
+++ b/zebra/debug.c
@@ -236,7 +236,7 @@ DEFUN (no_debug_zebra_rib,
DEFUN (no_debug_zebra_rib_q,
no_debug_zebra_rib_q_cmd,
- "no debug zebra rib queueu",
+ "no debug zebra rib queue",
NO_STR
DEBUG_STR
"Zebra configuration\n"
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index c9c14760..701c81b6 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -22,12 +22,11 @@
#include <zebra.h>
-/* Extern from rt_netlink.c */
-void interface_lookup_netlink ();
+extern int interface_lookup_netlink (void);
/* Interface information read by netlink. */
void
-interface_list ()
+interface_list (void)
{
interface_lookup_netlink ();
}
diff --git a/zebra/interface.c b/zebra/interface.c
index 184b42a0..ce506056 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -274,7 +274,7 @@ if_addr_wakeup (struct interface *ifp)
/* Address check. */
if (p->family == AF_INET)
{
- if (! if_is_up (ifp))
+ if (! if_is_operative (ifp))
{
/* XXX: WTF is it trying to set flags here?
* caller has just gotten a new interface, has been
@@ -311,7 +311,7 @@ if_addr_wakeup (struct interface *ifp)
#ifdef HAVE_IPV6
if (p->family == AF_INET6)
{
- if (! if_is_up (ifp))
+ if (! if_is_operative (ifp))
{
/* XXX: See long comment above */
if_set_flags (ifp, IFF_UP | IFF_RUNNING);
@@ -379,7 +379,7 @@ if_delete_update (struct interface *ifp)
zebra_if = ifp->info;
- if (if_is_up(ifp))
+ if (if_is_operative(ifp))
{
zlog_err ("interface %s index %d is still up while being deleted.",
ifp->name, ifp->ifindex);
@@ -538,15 +538,25 @@ if_down (struct interface *ifp)
if (p->family == AF_INET)
connected_down_ipv4 (ifp, ifc);
+ }
+ }
+
+ /* Examine all static routes which direct to the interface. */
+ rib_update ();
+
#ifdef HAVE_IPV6
- else if (p->family == AF_INET6)
+ if (ifp->connected)
+ {
+ for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc))
+ {
+ p = ifc->address;
+ if (p->family == AF_INET6)
connected_down_ipv6 (ifp, ifc);
-#endif /* HAVE_IPV6 */
}
}
- /* Examine all static routes which direct to the interface. */
rib_update ();
+#endif /* HAVE_IPV6 */
}
void
@@ -822,6 +832,7 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
#endif /* HAVE_NET_RT_IFLIST */
}
+#if 0
/* Check supported address family. */
static int
if_supported_family (int family)
@@ -834,6 +845,7 @@ if_supported_family (int family)
#endif /* HAVE_IPV6 */
return 0;
}
+#endif
/* Wrapper hook point for zebra daemon so that ifindex can be set
* DEFUN macro not used as extract.pl HAS to ignore this
@@ -1205,7 +1217,7 @@ ip_address_install (struct vty *vty, struct interface *ifp,
&& CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
{
/* Some system need to up the interface to set IP address. */
- if (! if_is_up (ifp))
+ if (! if_is_operative (ifp))
{
if_set_flags (ifp, IFF_UP | IFF_RUNNING);
if_refresh (ifp);
@@ -1398,7 +1410,7 @@ ipv6_address_install (struct vty *vty, struct interface *ifp,
&& CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
{
/* Some system need to up the interface to set IP address. */
- if (! if_is_up (ifp))
+ if (! if_is_operative (ifp))
{
if_set_flags (ifp, IFF_UP | IFF_RUNNING);
if_refresh (ifp);
diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c
index 3c5f1559..ae121ea1 100644
--- a/zebra/irdp_packet.c
+++ b/zebra/irdp_packet.c
@@ -231,7 +231,7 @@ int irdp_read_raw(struct thread *r)
struct zebra_if *zi;
struct irdp_interface *irdp;
char buf[IRDP_RX_BUF];
- int ret, ifindex;
+ int ret, ifindex = 0;
int irdp_sock = THREAD_FD (r);
t_irdp_raw = thread_add_read (zebrad.master, irdp_read_raw, NULL, irdp_sock);
diff --git a/zebra/rib.h b/zebra/rib.h
index 887ed3c2..0d6ab815 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -38,10 +38,6 @@ union g_addr {
struct rib
{
- /* Status Flags for the *route_node*, but kept in the head RIB.. */
- u_char rn_status;
-#define RIB_ROUTE_QUEUED(x) (1 << (x))
-
/* Link list. */
struct rib *next;
struct rib *prev;
@@ -49,20 +45,24 @@ struct rib
/* Nexthop structure */
struct nexthop *nexthop;
- /* Refrence count. */
+ /* Reference count. */
unsigned long refcnt;
/* Uptime. */
time_t uptime;
- /* Type fo this route. */
- int type;
+ /* Metric */
+ u_int32_t metric;
/* Which routing table */
- int table;
+ u_int32_t table;
- /* Metric */
- u_int32_t metric;
+ /* Type for this route. < ZEBRA_ROUTE_MAX */
+ u_int8_t type;
+
+ /* Status Flags for the *route_node*, but kept in the head RIB.. */
+ u_char rn_status;
+#define RIB_ROUTE_QUEUED (1 << 0)
/* Distance. */
u_char distance;
@@ -104,6 +104,13 @@ struct static_ipv4
struct static_ipv4 *prev;
struct static_ipv4 *next;
+ /* Nexthop value. */
+ union
+ {
+ struct in_addr ipv4;
+ char *ifname;
+ } gate;
+
/* Administrative distance. */
u_char distance;
@@ -113,13 +120,6 @@ struct static_ipv4
#define STATIC_IPV4_IFNAME 2
#define STATIC_IPV4_BLACKHOLE 3
- /* Nexthop value. */
- union
- {
- struct in_addr ipv4;
- char *ifname;
- } gate;
-
/* bit flags */
u_char flags;
/*
@@ -136,6 +136,10 @@ struct static_ipv6
struct static_ipv6 *prev;
struct static_ipv6 *next;
+ /* Nexthop value. */
+ struct in6_addr ipv6;
+ char *ifname;
+
/* Administrative distance. */
u_char distance;
@@ -144,11 +148,6 @@ struct static_ipv6
#define STATIC_IPV6_GATEWAY 1
#define STATIC_IPV6_GATEWAY_IFNAME 2
#define STATIC_IPV6_IFNAME 3
-
- /* Nexthop value. */
- struct in6_addr ipv6;
- char *ifname;
-
/* bit flags */
u_char flags;
/*
@@ -180,22 +179,24 @@ struct nexthop
/* Interface index. */
char *ifname;
unsigned int ifindex;
+
+ /* Nexthop address or interface name. */
+ union g_addr gate;
+
+ unsigned int rifindex;
+ union g_addr rgate;
+ union g_addr src;
- enum nexthop_types_t type;
+/* Really enum nexthop_types_t but safe space */
+ u_char type;
u_char flags;
#define NEXTHOP_FLAG_ACTIVE (1 << 0) /* This nexthop is alive. */
#define NEXTHOP_FLAG_FIB (1 << 1) /* FIB nexthop. */
#define NEXTHOP_FLAG_RECURSIVE (1 << 2) /* Recursive nexthop. */
- /* Nexthop address or interface name. */
- union g_addr gate;
-
/* Recursive lookup nexthop. */
u_char rtype;
- unsigned int rifindex;
- union g_addr rgate;
- union g_addr src;
};
/* Routing table instance. */
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 0bf2d9eb..3e8048ba 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -41,6 +41,7 @@
#include "zebra/redistribute.h"
#include "zebra/interface.h"
#include "zebra/debug.h"
+#include <stddef.h>
/* Socket interface to kernel */
struct nlsock
@@ -52,7 +53,7 @@ struct nlsock
} netlink = { -1, 0, {0}, "netlink-listen"}, /* kernel messages */
netlink_cmd = { -1, 0, {0}, "netlink-cmd"}; /* command channel */
-struct message nlmsg_str[] = {
+static struct message nlmsg_str[] = {
{RTM_NEWROUTE, "RTM_NEWROUTE"},
{RTM_DELROUTE, "RTM_DELROUTE"},
{RTM_GETROUTE, "RTM_GETROUTE"},
@@ -65,7 +66,7 @@ struct message nlmsg_str[] = {
{0, NULL}
};
-const char *nexthop_types_desc[] =
+static const char *nexthop_types_desc[] =
{
"none",
"Directly connected",
@@ -86,31 +87,43 @@ extern struct zebra_privs_t zserv_privs;
extern u_int32_t nl_rcvbufsize;
-/* Note: on netlink systems, there should be a 1-to-1 mapping between interface
- names and ifindex values. */
-static void
-set_ifindex(struct interface *ifp, unsigned int ifi_index)
+static int
+netlink_recvbuf (struct nlsock *nl, uint32_t newsize)
{
- struct interface *oifp;
+ u_int32_t oldsize;
+ socklen_t newlen = sizeof(newsize);
+ socklen_t oldlen = sizeof(oldsize);
+ int ret;
- if (((oifp = if_lookup_by_index(ifi_index)) != NULL) && (oifp != ifp))
+ ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen);
+ if (ret < 0)
{
- if (ifi_index == IFINDEX_INTERNAL)
- zlog_err("Netlink is setting interface %s ifindex to reserved "
- "internal value %u", ifp->name, ifi_index);
- else
- {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("interface index %d was renamed from %s to %s",
- ifi_index, oifp->name, ifp->name);
- if (if_is_up(oifp))
- zlog_err("interface rename detected on up interface: index %d "
- "was renamed from %s to %s, results are uncertain!",
- ifi_index, oifp->name, ifp->name);
- if_delete_update(oifp);
- }
+ zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
+ safe_strerror (errno));
+ return -1;
}
- ifp->ifindex = ifi_index;
+
+ ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize,
+ sizeof(nl_rcvbufsize));
+ if (ret < 0)
+ {
+ zlog (NULL, LOG_ERR, "Can't set %s receive buffer size: %s", nl->name,
+ safe_strerror (errno));
+ return -1;
+ }
+
+ ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
+ if (ret < 0)
+ {
+ zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
+ safe_strerror (errno));
+ return -1;
+ }
+
+ zlog (NULL, LOG_INFO,
+ "Setting netlink socket receive buffer size: %u -> %u",
+ oldsize, newsize);
+ return 0;
}
/* Make socket for Linux netlink interface. */
@@ -131,56 +144,6 @@ netlink_socket (struct nlsock *nl, unsigned long groups)
return -1;
}
- ret = fcntl (sock, F_SETFL, O_NONBLOCK);
- if (ret < 0)
- {
- zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", nl->name,
- safe_strerror (errno));
- close (sock);
- return -1;
- }
-
- /* Set receive buffer size if it's set from command line */
- if (nl_rcvbufsize)
- {
- u_int32_t oldsize, oldlen;
- u_int32_t newsize, newlen;
-
- oldlen = sizeof(oldsize);
- newlen = sizeof(newsize);
-
- ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen);
- if (ret < 0)
- {
- zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
- safe_strerror (errno));
- close (sock);
- return -1;
- }
-
- ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize,
- sizeof(nl_rcvbufsize));
- if (ret < 0)
- {
- zlog (NULL, LOG_ERR, "Can't set %s receive buffer size: %s", nl->name,
- safe_strerror (errno));
- close (sock);
- return -1;
- }
-
- ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
- if (ret < 0)
- {
- zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
- safe_strerror (errno));
- close (sock);
- return -1;
- }
-
- zlog (NULL, LOG_INFO,
- "Setting netlink socket receive buffer size: %u -> %u",
- oldsize, newsize);
- }
memset (&snl, 0, sizeof snl);
snl.nl_family = AF_NETLINK;
@@ -222,41 +185,6 @@ netlink_socket (struct nlsock *nl, unsigned long groups)
return ret;
}
-int
-set_netlink_blocking (struct nlsock *nl, int *flags)
-{
-
- /* Change socket flags for blocking I/O. */
- if ((*flags = fcntl (nl->sock, F_GETFL, 0)) < 0)
- {
- zlog (NULL, LOG_ERR, "%s:%i F_GETFL error: %s",
- __FUNCTION__, __LINE__, safe_strerror (errno));
- return -1;
- }
- *flags &= ~O_NONBLOCK;
- if (fcntl (nl->sock, F_SETFL, *flags) < 0)
- {
- zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s",
- __FUNCTION__, __LINE__, safe_strerror (errno));
- return -1;
- }
- return 0;
-}
-
-int
-set_netlink_nonblocking (struct nlsock *nl, int *flags)
-{
- /* Restore socket flags for nonblocking I/O */
- *flags |= O_NONBLOCK;
- if (fcntl (nl->sock, F_SETFL, *flags) < 0)
- {
- zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s",
- __FUNCTION__, __LINE__, safe_strerror (errno));
- return -1;
- }
- return 0;
-}
-
/* Get type specified information from netlink. */
static int
netlink_request (int family, int type, struct nlsock *nl)
@@ -286,7 +214,7 @@ netlink_request (int family, int type, struct nlsock *nl)
req.nlh.nlmsg_len = sizeof req;
req.nlh.nlmsg_type = type;
req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
- req.nlh.nlmsg_pid = 0;
+ req.nlh.nlmsg_pid = nl->snl.nl_pid;
req.nlh.nlmsg_seq = ++nl->seq;
req.g.rtgen_family = family;
@@ -328,30 +256,23 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
while (1)
{
- char buf[4096];
+ //increased from 4096 to 32768 as recvmsg overrun error
+ char buf[32768];
struct iovec iov = { buf, sizeof buf };
struct sockaddr_nl snl;
struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
struct nlmsghdr *h;
- int save_errno;
-
- if (zserv_privs.change (ZPRIVS_RAISE))
- zlog (NULL, LOG_ERR, "Can't raise privileges");
status = recvmsg (nl->sock, &msg, 0);
- save_errno = errno;
-
- if (zserv_privs.change (ZPRIVS_LOWER))
- zlog (NULL, LOG_ERR, "Can't lower privileges");
-
if (status < 0)
{
- if (save_errno == EINTR)
+ if (errno == EINTR)
continue;
- if (save_errno == EWOULDBLOCK || save_errno == EAGAIN)
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
break;
+
zlog (NULL, LOG_ERR, "%s recvmsg overrun: %s",
- nl->name, safe_strerror(save_errno));
+ nl->name, safe_strerror(errno));
continue;
}
@@ -368,13 +289,6 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
return -1;
}
- /* JF: Ignore messages that aren't from the kernel */
- if ( snl.nl_pid != 0 )
- {
- zlog ( NULL, LOG_ERR, "Ignoring message from pid %u", snl.nl_pid );
- continue;
- }
-
for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status);
h = NLMSG_NEXT (h, status))
{
@@ -386,6 +300,8 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
if (h->nlmsg_type == NLMSG_ERROR)
{
struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h);
+ int errnum = err->error;
+ int msg_type = err->msg.nlmsg_type;
/* If the error field is zero, then this is an ACK */
if (err->error == 0)
@@ -414,27 +330,24 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
return -1;
}
- /* Deal with Error Noise - MAG */
- {
- int loglvl = LOG_ERR;
- int errnum = err->error;
- int msg_type = err->msg.nlmsg_type;
-
- if (nl == &netlink_cmd
- && (-errnum == ENODEV || -errnum == ESRCH)
- && (msg_type == RTM_NEWROUTE || msg_type == RTM_DELROUTE))
- loglvl = LOG_DEBUG;
-
- zlog (NULL, loglvl, "%s error: %s, type=%s(%u), "
- "seq=%u, pid=%u",
- nl->name, safe_strerror (-errnum),
- lookup (nlmsg_str, msg_type),
- msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
- }
- /*
- ret = -1;
- continue;
- */
+ /* Deal with errors that occur because of races in link handling */
+ if (nl == &netlink_cmd
+ && ((msg_type == RTM_DELROUTE &&
+ (-errnum == ENODEV || -errnum == ESRCH))
+ || (msg_type == RTM_NEWROUTE && -errnum == EEXIST)))
+ {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug ("%s: error: %s type=%s(%u), seq=%u, pid=%u",
+ nl->name, safe_strerror (-errnum),
+ lookup (nlmsg_str, msg_type),
+ msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
+ return 0;
+ }
+
+ zlog_err ("%s error: %s, type=%s(%u), seq=%u, pid=%u",
+ nl->name, safe_strerror (-errnum),
+ lookup (nlmsg_str, msg_type),
+ msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
return -1;
}
@@ -493,7 +406,7 @@ netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta,
/* Called from interface_lookup_netlink(). This function is only used
during bootstrap. */
-int
+static int
netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
{
int len;
@@ -527,12 +440,26 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
#endif /* IFLA_WIRELESS */
if (tb[IFLA_IFNAME] == NULL)
- return -1;
+ {
+ zlog_err("%s: missing interface name in message", __func__);
+ return -1;
+ }
name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
+ if (ifi->ifi_index == IFINDEX_INTERNAL)
+ {
+ zlog_err("%s: reserved ifindex", __func__);
+ return -1;
+ }
+
/* Add interface. */
- ifp = if_get_by_name (name);
- set_ifindex(ifp, ifi->ifi_index);
+ ifp = if_lookup_by_index(ifi->ifi_index);
+ if (!ifp)
+ {
+ ifp = if_create(name, strlen(name));
+ ifp->ifindex = ifi->ifi_index;
+ }
+ strncpy(ifp->name, name, INTERFACE_NAMSIZ);
ifp->flags = ifi->ifi_flags & 0x0000fffff;
ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
ifp->metric = 1;
@@ -570,7 +497,7 @@ netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
}
/* Lookup interface IPv4/IPv6 address. */
-int
+static int
netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
{
int len;
@@ -705,7 +632,7 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
}
/* Looking up routing table by netlink interface. */
-int
+static int
netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
{
int len;
@@ -822,7 +749,7 @@ struct message rtproto_str[] = {
};
/* Routing information change from the kernel. */
-int
+static int
netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
{
int len;
@@ -963,7 +890,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
return 0;
}
-int
+static int
netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
{
int len;
@@ -1001,21 +928,38 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
#endif /* IFLA_WIRELESS */
if (tb[IFLA_IFNAME] == NULL)
- return -1;
+ {
+ zlog_err("%s: missing interface name", __func__);
+ return -1;
+ }
name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
/* Add interface. */
if (h->nlmsg_type == RTM_NEWLINK)
{
- ifp = if_lookup_by_name (name);
+ unsigned long new_flags = ifi->ifi_flags & 0x0000fffff;
+ ifp = if_lookup_by_index (ifi->ifi_index);
+
+ if (ifp && strcmp(ifp->name, name) != 0)
+ {
+ zlog_info("interface index %d was renamed from %s to %s",
+ ifi->ifi_index, ifp->name, name);
+
+ strncpy(ifp->name, name, INTERFACE_NAMSIZ);
+ }
if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
{
if (ifp == NULL)
- ifp = if_get_by_name (name);
+ {
+ ifp = if_create(name, strlen(name));
+ ifp->ifindex = ifi->ifi_index;
+ }
- set_ifindex(ifp, ifi->ifi_index);
- ifp->flags = ifi->ifi_flags & 0x0000fffff;
+ zlog_info ("interface %s index %d %s added.",
+ name, ifi->ifi_index, if_flag_dump(new_flags));
+
+ ifp->flags = new_flags;
ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
ifp->metric = 1;
@@ -1025,30 +969,35 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
else
{
/* Interface status change. */
- set_ifindex(ifp, ifi->ifi_index);
ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
ifp->metric = 1;
- if (if_is_operative (ifp))
- {
- ifp->flags = ifi->ifi_flags & 0x0000fffff;
- if (!if_is_operative (ifp))
- if_down (ifp);
+ if (new_flags != ifp->flags)
+ {
+ zlog_info ("interface %s index %d changed %s.",
+ name, ifi->ifi_index, if_flag_dump(new_flags));
+
+ if (if_is_operative (ifp))
+ {
+ ifp->flags = new_flags;
+ if (!if_is_operative (ifp))
+ if_down (ifp);
+ else
+ /* Must notify client daemons of new interface status. */
+ zebra_interface_up_update (ifp);
+ }
else
- /* Must notify client daemons of new interface status. */
- zebra_interface_up_update (ifp);
- }
- else
- {
- ifp->flags = ifi->ifi_flags & 0x0000fffff;
- if (if_is_operative (ifp))
- if_up (ifp);
- }
+ {
+ ifp->flags = new_flags;
+ if (if_is_operative (ifp))
+ if_up (ifp);
+ }
+ }
}
}
else
{
- /* RTM_DELLINK. */
+ // RTM_DELLINK.
ifp = if_lookup_by_name (name);
if (ifp == NULL)
@@ -1057,16 +1006,25 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
name);
return 0;
}
+ else
+ zlog_info ("interface %s index %d deleted.",
+ name, ifi->ifi_index);
if_delete_update (ifp);
}
-
return 0;
}
-int
+static int
netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
{
+ /* JF: Ignore messages that aren't from the kernel */
+ if ( snl->nl_pid != 0 )
+ {
+ zlog ( NULL, LOG_ERR, "Ignoring message from pid %u", snl->nl_pid );
+ return 0;
+ }
+
switch (h->nlmsg_type)
{
case RTM_NEWROUTE:
@@ -1099,18 +1057,6 @@ int
interface_lookup_netlink (void)
{
int ret;
- int flags;
- int snb_ret;
-
- /*
- * Change netlink socket flags to blocking to ensure we get
- * a reply via nelink_parse_info
- */
- snb_ret = set_netlink_blocking (&netlink_cmd, &flags);
- if (snb_ret < 0)
- zlog (NULL, LOG_WARNING,
- "%s:%i Warning: Could not set netlink socket to blocking.",
- __FUNCTION__, __LINE__);
/* Get interface information. */
ret = netlink_request (AF_PACKET, RTM_GETLINK, &netlink_cmd);
@@ -1138,9 +1084,6 @@ interface_lookup_netlink (void)
return ret;
#endif /* HAVE_IPV6 */
- /* restore socket flags */
- if (snb_ret == 0)
- set_netlink_nonblocking (&netlink_cmd, &flags);
return 0;
}
@@ -1150,18 +1093,6 @@ int
netlink_route_read (void)
{
int ret;
- int flags;
- int snb_ret;
-
- /*
- * Change netlink socket flags to blocking to ensure we get
- * a reply via nelink_parse_info
- */
- snb_ret = set_netlink_blocking (&netlink_cmd, &flags);
- if (snb_ret < 0)
- zlog (NULL, LOG_WARNING,
- "%s:%i Warning: Could not set netlink socket to blocking.",
- __FUNCTION__, __LINE__);
/* Get IPv4 routing table. */
ret = netlink_request (AF_INET, RTM_GETROUTE, &netlink_cmd);
@@ -1181,15 +1112,12 @@ netlink_route_read (void)
return ret;
#endif /* HAVE_IPV6 */
- /* restore flags */
- if (snb_ret == 0)
- set_netlink_nonblocking (&netlink_cmd, &flags);
return 0;
}
/* Utility function comes from iproute2.
Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
-int
+static int
addattr_l (struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
{
int len;
@@ -1209,7 +1137,7 @@ addattr_l (struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
return 0;
}
-int
+static int
rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen)
{
int len;
@@ -1231,7 +1159,7 @@ rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen)
/* Utility function comes from iproute2.
Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
-int
+static int
addattr32 (struct nlmsghdr *n, int maxlen, int type, int data)
{
int len;
@@ -1259,15 +1187,13 @@ netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h)
}
/* sendmsg() to netlink socket then recvmsg(). */
-int
+static int
netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
{
int status;
struct sockaddr_nl snl;
struct iovec iov = { (void *) n, n->nlmsg_len };
struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
- int flags = 0;
- int snb_ret;
int save_errno;
memset (&snl, 0, sizeof snl);
@@ -1298,31 +1224,16 @@ netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
return -1;
}
- /*
- * Change socket flags for blocking I/O.
- * This ensures we wait for a reply in netlink_parse_info().
- */
- snb_ret = set_netlink_blocking (nl, &flags);
- if (snb_ret < 0)
- zlog (NULL, LOG_WARNING,
- "%s:%i Warning: Could not set netlink socket to blocking.",
- __FUNCTION__, __LINE__);
/*
* Get reply from netlink socket.
* The reply should either be an acknowlegement or an error.
*/
- status = netlink_parse_info (netlink_talk_filter, nl);
-
- /* Restore socket flags for nonblocking I/O */
- if (snb_ret == 0)
- set_netlink_nonblocking (nl, &flags);
-
- return status;
+ return netlink_parse_info (netlink_talk_filter, nl);
}
/* Routing table change via netlink interface. */
-int
+static int
netlink_route (int cmd, int family, void *dest, int length, void *gate,
int index, int zebra_flags, int table)
{
@@ -1397,7 +1308,7 @@ netlink_route (int cmd, int family, void *dest, int length, void *gate,
}
/* Routing table change via netlink interface. */
-int
+static int
netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
int family)
{
@@ -1860,7 +1771,7 @@ kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
#endif /* HAVE_IPV6 */
/* Interface address modification. */
-int
+static int
netlink_address (int cmd, int family, struct interface *ifp,
struct connected *ifc)
{
@@ -1925,7 +1836,7 @@ kernel_address_delete_ipv4 (struct interface *ifp, struct connected *ifc)
extern struct thread_master *master;
/* Kernel route reflection. */
-int
+static int
kernel_read (struct thread *thread)
{
int ret;
@@ -1938,45 +1849,26 @@ kernel_read (struct thread *thread)
return 0;
}
-/* Filter out messages from self that occur on listener socket */
-static void netlink_install_filter (int sock)
+/* Filter out messages from self that occur on listener socket,
+ caused by our actions on the command socket
+ */
+static void netlink_install_filter (int sock, __u32 pid)
{
- /*
- * Filter is equivalent to netlink_route_change
- *
- * if (h->nlmsg_type == RTM_DELROUTE || h->nlmsg_type == RTM_NEWROUTE) {
- * if (rtm->rtm_type != RTM_UNICAST)
- * return 0;
- * if (rtm->rtm_flags & RTM_F_CLONED)
- * return 0;
- * if (rtm->rtm_protocol == RTPROT_REDIRECT)
- * return 0;
- * if (rtm->rtm_protocol == RTPROT_KERNEL)
- * return 0;
- * if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE)
- * return 0;
- * }
- * return 0xffff;
- */
struct sock_filter filter[] = {
- /* 0*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)),
- /* 1*/ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_DELROUTE), 1, 0),
- /* 2*/ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 0, 11),
- /* 3*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_B,
- sizeof(struct nlmsghdr) + offsetof(struct rtmsg, rtm_type)),
- /* 4*/ BPF_JUMP(BPF_JMP|BPF_B, RTN_UNICAST, 0, 8),
- /* 5*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_B,
- sizeof(struct nlmsghdr) + offsetof(struct rtmsg, rtm_flags)),
- /* 6*/ BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, RTM_F_CLONED, 6, 0),
- /* 7*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_B,
- sizeof(struct nlmsghdr) + offsetof(struct rtmsg, rtm_protocol)),
- /* 8*/ BPF_JUMP(BPF_JMP+ BPF_B, RTPROT_REDIRECT, 4, 0),
- /* 9*/ BPF_JUMP(BPF_JMP+ BPF_B, RTPROT_KERNEL, 0, 1),
- /*10*/ BPF_JUMP(BPF_JMP+ BPF_B, RTPROT_ZEBRA, 0, 3),
- /*11*/ BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)),
- /*12*/ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 0, 1),
- /*13*/ BPF_STMT(BPF_RET|BPF_K, 0), /* drop */
- /*14*/ BPF_STMT(BPF_RET|BPF_K, 0xffff), /* keep */
+ /* 0: ldh [4] */
+ BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)),
+ /* 1: jeq 0x18 jt 3 jf 6 */
+ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 1, 0),
+ /* 2: jeq 0x19 jt 3 jf 6 */
+ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_DELROUTE), 0, 3),
+ /* 3: ldw [12] */
+ BPF_STMT(BPF_LD|BPF_ABS|BPF_W, offsetof(struct nlmsghdr, nlmsg_pid)),
+ /* 4: jeq XX jt 5 jf 6 */
+ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htonl(pid), 0, 1),
+ /* 5: ret 0 (skip) */
+ BPF_STMT(BPF_RET|BPF_K, 0),
+ /* 6: ret 0xffff (keep) */
+ BPF_STMT(BPF_RET|BPF_K, 0xffff),
};
struct sock_fprog prog = {
@@ -2005,7 +1897,16 @@ kernel_init (void)
/* Register kernel socket. */
if (netlink.sock > 0)
{
- netlink_install_filter (netlink.sock);
+ /* Only want non-blocking on the netlink event socket */
+ if (fcntl (netlink.sock, F_SETFL, O_NONBLOCK) < 0)
+ zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", netlink.name,
+ safe_strerror (errno));
+
+ /* Set receive buffer size if it's set from command line */
+ if (nl_rcvbufsize)
+ netlink_recvbuf (&netlink, nl_rcvbufsize);
+
+ netlink_install_filter (netlink.sock, netlink_cmd.snl.nl_pid);
thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
}
}
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 4bdb83d5..0097e28f 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -90,11 +90,13 @@ rtadv_new (void)
return new;
}
+#if 0
static void
rtadv_free (struct rtadv *rtadv)
{
XFREE (MTYPE_TMP, rtadv);
}
+#endif
static int
rtadv_recv_packet (int sock, u_char *buf, int buflen,
@@ -451,7 +453,7 @@ rtadv_read (struct thread *thread)
int len;
u_char buf[RTADV_MSG_SIZE];
struct sockaddr_in6 from;
- unsigned int ifindex;
+ unsigned int ifindex = 0;
int hoplimit = -1;
sock = THREAD_FD (thread);
diff --git a/zebra/rtread_netlink.c b/zebra/rtread_netlink.c
index 0b255a53..44715d94 100644
--- a/zebra/rtread_netlink.c
+++ b/zebra/rtread_netlink.c
@@ -21,11 +21,9 @@
*/
#include <zebra.h>
+extern void netlink_route_read (void);
-/* Extern from rt_netlink.c */
-void netlink_route_read ();
-
-void route_read ()
+void route_read (void)
{
netlink_route_read ();
}
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 4cb72ba8..545481d1 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -51,7 +51,7 @@ extern struct zebra_t zebrad;
int rib_process_hold_time = 10;
/* Each route type's string and default distance value. */
-struct
+static const struct
{
int key;
int distance;
@@ -70,7 +70,7 @@ struct
};
/* Vector for routing table. */
-vector vrf_vector;
+static vector vrf_vector;
/* Allocate new VRF. */
static struct vrf *
@@ -93,6 +93,7 @@ vrf_alloc (const char *name)
return vrf;
}
+#if 0
/* Free VRF. */
static void
vrf_free (struct vrf *vrf)
@@ -101,6 +102,7 @@ vrf_free (struct vrf *vrf)
XFREE (MTYPE_VRF_NAME, vrf->name);
XFREE (MTYPE_VRF, vrf);
}
+#endif
/* Lookup VRF by identifier. */
struct vrf *
@@ -109,6 +111,7 @@ vrf_lookup (u_int32_t id)
return vector_lookup (vrf_vector, id);
}
+#if 0
/* Lookup VRF by name. */
static struct vrf *
vrf_lookup_by_name (char *name)
@@ -122,6 +125,7 @@ vrf_lookup_by_name (char *name)
return vrf;
return NULL;
}
+#endif
/* Initialize VRF. */
static void
@@ -336,6 +340,35 @@ nexthop_blackhole_add (struct rib *rib)
return nexthop;
}
+static int
+nexthop_isactive(const struct nexthop *nexthop)
+{
+ struct interface *ifp;
+
+ switch(nexthop->type)
+ {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV6:
+ if (nexthop->ifindex == 0)
+ return 0;
+ /* fall through */
+ case NEXTHOP_TYPE_IFINDEX:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ ifp = if_lookup_by_index (nexthop->ifindex);
+ return (ifp && if_is_operative (ifp));
+
+ case NEXTHOP_TYPE_IFNAME:
+ case NEXTHOP_TYPE_IPV4_IFNAME:
+ case NEXTHOP_TYPE_IPV6_IFNAME:
+ ifp = if_lookup_by_name(nexthop->ifname);
+ return (ifp && if_is_operative (ifp));
+
+ default:
+ return 1;
+ }
+}
+
/* If force flag is not set, do not modify falgs at all for uninstall
the route from FIB. */
static int
@@ -348,11 +381,12 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
struct rib *match;
struct nexthop *newhop;
- if (nexthop->type == NEXTHOP_TYPE_IPV4)
- nexthop->ifindex = 0;
-
if (set)
- UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
+ {
+ UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
+ if (nexthop->type == NEXTHOP_TYPE_IPV4)
+ nexthop->ifindex = 0;
+ }
/* Make lookup prefix. */
memset (&p, 0, sizeof (struct prefix_ipv4));
@@ -376,8 +410,12 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
/* Pick up selected route. */
for (match = rn->info; match; match = match->next)
- if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
- break;
+ {
+ if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
+ continue;
+ if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
+ break;
+ }
/* If there is no selected route or matched route is EGP, go up
tree. */
@@ -396,16 +434,32 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
{
/* Directly point connected route. */
newhop = match->nexthop;
- if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)
- nexthop->ifindex = newhop->ifindex;
-
- return 1;
+ if (!newhop)
+ return 0; /* dead route */
+
+ if (nexthop_isactive (newhop))
+ {
+ if (set)
+ {
+ if (nexthop->type == NEXTHOP_TYPE_IPV4)
+ nexthop->ifindex = newhop->ifindex;
+ }
+ else
+ {
+ if (nexthop->ifindex != newhop->ifindex ||
+ CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+ SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
+ }
+ return 1;
+ }
}
- else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
+ else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL) ||
+ match->type == ZEBRA_ROUTE_STATIC)
{
for (newhop = match->nexthop; newhop; newhop = newhop->next)
if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
- && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
+ && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE)
+ && nexthop_isactive (newhop))
{
if (set)
{
@@ -418,7 +472,15 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,
|| newhop->type == NEXTHOP_TYPE_IFNAME
|| newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
nexthop->rifindex = newhop->ifindex;
+ if (nexthop->type == NEXTHOP_TYPE_IPV4)
+ nexthop->ifindex = newhop->ifindex;
}
+ else if (! CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)
+ || newhop->ifindex != nexthop->ifindex
+ || nexthop->gate.ipv4.s_addr != newhop->gate.ipv4.s_addr)
+ SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
+
+
return 1;
}
return 0;
@@ -473,8 +535,12 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
/* Pick up selected route. */
for (match = rn->info; match; match = match->next)
- if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
- break;
+ {
+ if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
+ continue;
+ if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
+ break;
+ }
/* If there is no selected route or matched route is EGP, go up
tree. */
@@ -493,17 +559,35 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
{
/* Directly point connected route. */
newhop = match->nexthop;
+ if (!newhop)
+ return 0; /* dead route */
- if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)
+ /* recursive route, remember index */
+ if (nexthop->type == NEXTHOP_TYPE_IPV6)
nexthop->ifindex = newhop->ifindex;
- return 1;
+ if (nexthop_isactive (newhop))
+ {
+ if (set)
+ {
+ if (nexthop->type == NEXTHOP_TYPE_IPV6)
+ nexthop->ifindex = newhop->ifindex;
+ }
+ else
+ {
+ if (nexthop->ifindex != newhop->ifindex ||
+ CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+ SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
+ }
+ return 1;
+ }
}
else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
{
for (newhop = match->nexthop; newhop; newhop = newhop->next)
if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)
- && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))
+ && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE)
+ && nexthop_isactive (newhop))
{
if (set)
{
@@ -518,7 +602,15 @@ nexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,
|| newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX
|| newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)
nexthop->rifindex = newhop->ifindex;
+ if (nexthop->type == NEXTHOP_TYPE_IPV6)
+ nexthop->ifindex = newhop->ifindex;
}
+ else if (! CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)
+ || newhop->ifindex != nexthop->ifindex
+ || !IPV6_ADDR_SAME(&nexthop->gate.ipv6,
+ &newhop->gate.ipv4))
+ SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
+
return 1;
}
return 0;
@@ -560,8 +652,13 @@ rib_match_ipv4 (struct in_addr addr)
/* Pick up selected route. */
for (match = rn->info; match; match = match->next)
- if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
- break;
+ {
+ if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
+ continue;
+ if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
+ break;
+ }
+
/* If there is no selected route or matched route is EGP, go up
tree. */
@@ -615,8 +712,12 @@ rib_lookup_ipv4 (struct prefix_ipv4 *p)
/* Pick up selected route. */
for (match = rn->info; match; match = match->next)
- if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
- break;
+ {
+ if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
+ continue;
+ if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
+ break;
+ }
if (! match || match->type == ZEBRA_ROUTE_BGP)
return NULL;
@@ -668,12 +769,12 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
/* Find out if a "selected" RR for the discovered RIB entry exists ever. */
for (match = rn->info; match; match = match->next)
- {
- if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
- continue;
- if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
- break;
- }
+ {
+ if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
+ continue;
+ if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
+ break;
+ }
/* None such found :( */
if (!match)
@@ -735,8 +836,12 @@ rib_match_ipv6 (struct in6_addr *addr)
/* Pick up selected route. */
for (match = rn->info; match; match = match->next)
- if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
- break;
+ {
+ if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED))
+ continue;
+ if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
+ break;
+ }
/* If there is no selected route or matched route is EGP, go up
tree. */
@@ -795,7 +900,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
{
case NEXTHOP_TYPE_IFINDEX:
ifp = if_lookup_by_index (nexthop->ifindex);
- if (ifp && if_is_operative(ifp))
+ if (ifp && if_is_operative (ifp))
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
@@ -804,7 +909,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
family = AFI_IP6;
case NEXTHOP_TYPE_IFNAME:
ifp = if_lookup_by_name (nexthop->ifname);
- if (ifp && if_is_operative(ifp))
+ if (ifp && if_is_operative (ifp))
{
if (set)
nexthop->ifindex = ifp->ifindex;
@@ -838,7 +943,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
{
ifp = if_lookup_by_index (nexthop->ifindex);
- if (ifp && if_is_operative(ifp))
+ if (ifp && if_is_operative (ifp))
SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
else
UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
@@ -867,8 +972,7 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
rmap = 0;
- if (rib->type >= 0 && rib->type < ZEBRA_ROUTE_MAX &&
- proto_rm[family][rib->type])
+ if (rib->type < ZEBRA_ROUTE_MAX && proto_rm[family][rib->type])
rmap = route_map_lookup_by_name (proto_rm[family][rib->type]);
if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX])
rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]);
@@ -1633,7 +1737,7 @@ void rib_dump (const char * func, const struct prefix_ipv4 * p, const struct rib
zlog_debug ("%s: dumping RIB entry %p for %s/%d", func, rib, straddr1, p->prefixlen);
zlog_debug
(
- "%s: refcnt == %lu, uptime == %u, type == %u, table == %d",
+ "%s: refcnt == %lu, uptime == %lu, type == %u, table == %d",
func,
rib->refcnt,
rib->uptime,
@@ -2219,6 +2323,9 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
/* Install into rib. */
static_install_ipv4 (p, si);
+ /* Scan for possible recursive route changes */
+ rib_update();
+
return 1;
}
@@ -2283,6 +2390,9 @@ static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
route_unlock_node (rn);
+ /* Scan for possible recursive route changes */
+ rib_update();
+
return 1;
}
@@ -2765,6 +2875,8 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
/* Install into rib. */
static_install_ipv6 (p, si);
+ /* Scan for possible recursive route changes */
+ rib_update();
return 1;
}
@@ -2818,6 +2930,7 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
XFREE (0, si->ifname);
XFREE (MTYPE_STATIC_IPV6, si);
+ rib_update();
return 1;
}
#endif /* HAVE_IPV6 */
@@ -2842,6 +2955,7 @@ rib_update (void)
rib_queue_add (&zebrad, rn);
}
+#if 0
/* Interface goes up. */
static void
rib_if_up (struct interface *ifp)
@@ -2855,6 +2969,7 @@ rib_if_down (struct interface *ifp)
{
rib_update ();
}
+#endif
/* Remove all routes which comes from non main table. */
static void