summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/connected.c24
-rw-r--r--zebra/connected.h4
-rw-r--r--zebra/debug.c4
-rw-r--r--zebra/if_netlink.c5
-rw-r--r--zebra/interface.c31
-rw-r--r--zebra/irdp_packet.c2
-rw-r--r--zebra/kernel_null.c6
-rw-r--r--zebra/kernel_socket.h4
-rw-r--r--zebra/main.c12
-rw-r--r--zebra/rib.h68
-rw-r--r--zebra/rt.h4
-rw-r--r--zebra/rt_ioctl.c4
-rw-r--r--zebra/rt_netlink.c379
-rw-r--r--zebra/rt_socket.c4
-rw-r--r--zebra/rtadv.c16
-rw-r--r--zebra/rtadv.h3
-rw-r--r--zebra/rtread_netlink.c6
-rw-r--r--zebra/zebra_rib.c534
-rw-r--r--zebra/zebra_vty.c4
-rw-r--r--zebra/zserv.c6
20 files changed, 525 insertions, 595 deletions
diff --git a/zebra/connected.c b/zebra/connected.c
index ad3e9607..b235d8c0 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -36,6 +36,7 @@
#include "zebra/interface.h"
#include "zebra/connected.h"
extern struct zebra_t zebrad;
+
/* withdraw a connected address */
static void
@@ -86,7 +87,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);
@@ -174,6 +175,7 @@ void
connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
{
struct prefix_ipv4 p;
+ struct in_addr src = ((struct prefix_ipv4 *) ifc->address)->prefix;
if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
return;
@@ -188,14 +190,14 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
if (prefix_ipv4_any (&p))
return;
- rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
- RT_TABLE_MAIN, ifp->metric, 0);
+ rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, &src,
+ ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0, RT_SCOPE_LINK);
rib_update ();
}
/* Add connected IPv4 route to the interface. */
-void
+struct connected *
connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
u_char prefixlen, struct in_addr *broad,
const char *label)
@@ -270,10 +272,10 @@ connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
/* nothing to do? */
- if ((ifc = connected_implicit_withdraw (ifp, ifc)) == NULL)
- return;
-
+ ifc = connected_implicit_withdraw (ifp, ifc);
connected_announce (ifp, ifc);
+
+ return ifc;
}
void
@@ -347,7 +349,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
}
/* Add connected IPv6 route to the interface. */
-void
+struct connected *
connected_add_ipv6 (struct interface *ifp, int flags, struct in6_addr *addr,
u_char prefixlen, struct in6_addr *broad,
const char *label)
@@ -394,10 +396,10 @@ connected_add_ipv6 (struct interface *ifp, int flags, struct in6_addr *addr,
if (label)
ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
- if ((ifc = connected_implicit_withdraw (ifp, ifc)) == NULL)
- return;
-
+ ifc = connected_implicit_withdraw (ifp, ifc);
connected_announce (ifp, ifc);
+
+ return ifc;
}
void
diff --git a/zebra/connected.h b/zebra/connected.h
index 9595ddb1..8bfe4118 100644
--- a/zebra/connected.h
+++ b/zebra/connected.h
@@ -26,7 +26,7 @@
extern struct connected *
connected_check (struct interface *ifp, struct prefix *p);
-extern void
+extern struct connected *
connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
u_char prefixlen, struct in_addr *broad,
const char *label);
@@ -39,7 +39,7 @@ extern void connected_up_ipv4 (struct interface *, struct connected *);
extern void connected_down_ipv4 (struct interface *, struct connected *);
#ifdef HAVE_IPV6
-extern void
+extern struct connected *
connected_add_ipv6 (struct interface *ifp, int flags, struct in6_addr *address,
u_char prefixlen, struct in6_addr *broad,
const char *label);
diff --git a/zebra/debug.c b/zebra/debug.c
index 7350e576..175029b8 100644
--- a/zebra/debug.c
+++ b/zebra/debug.c
@@ -236,11 +236,7 @@ DEFUN (no_debug_zebra_rib,
DEFUN (no_debug_zebra_rib_q,
no_debug_zebra_rib_q_cmd,
-<<<<<<< HEAD:zebra/debug.c
- "no debug zebra rib queueu",
-=======
"no debug zebra rib queue",
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/debug.c
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..74c977a9 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -48,8 +48,7 @@ if_zebra_new_hook (struct interface *ifp)
{
struct zebra_if *zebra_if;
- zebra_if = XMALLOC (MTYPE_TMP, sizeof (struct zebra_if));
- memset (zebra_if, 0, sizeof (struct zebra_if));
+ zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if));
zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC;
zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_UNSPEC;
@@ -274,7 +273,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 +310,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 +378,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 +537,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 +831,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 +844,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 +1216,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 +1409,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/kernel_null.c b/zebra/kernel_null.c
index 94b7b3c7..c72bbd09 100644
--- a/zebra/kernel_null.c
+++ b/zebra/kernel_null.c
@@ -12,9 +12,9 @@ int kernel_add_ipv4 (struct prefix *a, struct rib *b) { return 0; }
#pragma weak kernel_delete_ipv4 = kernel_add_ipv4
int kernel_add_ipv6 (struct prefix *a, struct rib *b) { return 0; }
#pragma weak kernel_delete_ipv6 = kernel_add_ipv6
-int kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
- unsigned int index, int flags, int table)
-{ return 0; }
+void kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
+ unsigned int index, int table)
+{ }
int kernel_add_route (struct prefix_ipv4 *a, struct in_addr *b, int c, int d)
{ return 0; }
diff --git a/zebra/kernel_socket.h b/zebra/kernel_socket.h
index ad6770ca..e9558ad6 100644
--- a/zebra/kernel_socket.h
+++ b/zebra/kernel_socket.h
@@ -28,10 +28,6 @@ extern int ifam_read (struct ifa_msghdr *);
extern int ifm_read (struct if_msghdr *);
extern int rtm_write (int, union sockunion *, union sockunion *,
union sockunion *, unsigned int, int, int);
-<<<<<<< HEAD:zebra/kernel_socket.h
-extern struct message rtm_type_str[];
-=======
extern const struct message rtm_type_str[];
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/kernel_socket.h
#endif /* __ZEBRA_KERNEL_SOCKET_H */
diff --git a/zebra/main.c b/zebra/main.c
index 61750f1d..ac0637b6 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -63,12 +63,16 @@ int keep_kernel_mode = 0;
u_int32_t nl_rcvbufsize = 0;
#endif /* HAVE_NETLINK */
+/* Manage system routes. */
+extern int rib_system_routes;
+
/* Command line options. */
struct option longopts[] =
{
{ "batch", no_argument, NULL, 'b'},
{ "daemon", no_argument, NULL, 'd'},
{ "keep_kernel", no_argument, NULL, 'k'},
+ { "rib_system", no_argument, NULL, 'S'},
{ "log_mode", no_argument, NULL, 'l'},
{ "config_file", required_argument, NULL, 'f'},
{ "pid_file", required_argument, NULL, 'i'},
@@ -131,6 +135,7 @@ usage (char *progname, int status)
"-i, --pid_file Set process identifier file name\n"\
"-k, --keep_kernel Don't delete old routes which installed by "\
"zebra.\n"\
+ "-S, --system Manage all routes on link transistions\n"
"-l, --log_mode Set verbose log mode flag\n"\
"-C, --dryrun Check configuration for validity and exit\n"\
"-A, --vty_addr Set vty's bind address\n"\
@@ -231,9 +236,9 @@ main (int argc, char **argv)
int opt;
#ifdef HAVE_NETLINK
- opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:g:vs:C", longopts, 0);
+ opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:g:vs:CS", longopts, 0);
#else
- opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:g:vC", longopts, 0);
+ opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:g:vCS", longopts, 0);
#endif /* HAVE_NETLINK */
if (opt == EOF)
@@ -251,6 +256,9 @@ main (int argc, char **argv)
case 'k':
keep_kernel_mode = 1;
break;
+ case 'S':
+ rib_system_routes = 1;
+ break;
case 'C':
dryrun = 1;
break;
diff --git a/zebra/rib.h b/zebra/rib.h
index 887ed3c2..c39afa73 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,27 @@ 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;
+
+ /* Scope for this route. */
+ u_int8_t scope;
+
+ /* Status Flags for the *route_node*, but kept in the head RIB.. */
+ u_char rn_status;
+#define RIB_ROUTE_QUEUED(x) (1 << (x))
/* Distance. */
u_char distance;
@@ -76,6 +79,7 @@ struct rib
/* RIB internal status */
u_char status;
#define RIB_ENTRY_REMOVED (1 << 0)
+#define RIB_ENTRY_PRESERVE (2 << 0)
/* Nexthop information. */
u_char nexthop_num;
@@ -104,6 +108,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 +124,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 +140,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 +152,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 +183,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. */
@@ -220,7 +225,8 @@ struct vrf
struct route_table *stable[AFI_MAX][SAFI_MAX];
};
-extern struct nexthop *nexthop_ifindex_add (struct rib *, unsigned int);
+extern struct nexthop *nexthop_ifindex_add (struct rib *, unsigned int,
+ struct in_addr *);
extern struct nexthop *nexthop_ifname_add (struct rib *, char *);
extern struct nexthop *nexthop_blackhole_add (struct rib *);
extern struct nexthop *nexthop_ipv4_add (struct rib *, struct in_addr *,
@@ -249,7 +255,7 @@ extern struct route_table *vrf_static_table (afi_t afi, safi_t safi, u_int32_t i
extern int rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
struct in_addr *gate, struct in_addr *src,
unsigned int ifindex, u_int32_t vrf_id,
- u_int32_t, u_char);
+ u_int32_t metric, u_int8_t distance, u_int8_t scope);
extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *);
diff --git a/zebra/rt.h b/zebra/rt.h
index 8bfe5a42..8b975558 100644
--- a/zebra/rt.h
+++ b/zebra/rt.h
@@ -36,8 +36,8 @@ extern int kernel_address_delete_ipv4 (struct interface *, struct connected *);
#ifdef HAVE_IPV6
extern int kernel_add_ipv6 (struct prefix *, struct rib *);
extern int kernel_delete_ipv6 (struct prefix *, struct rib *);
-extern int kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
- unsigned int index, int flags, int table);
+extern void kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
+ unsigned int index, int table);
#endif /* HAVE_IPV6 */
diff --git a/zebra/rt_ioctl.c b/zebra/rt_ioctl.c
index a5d588c7..d39ec4df 100644
--- a/zebra/rt_ioctl.c
+++ b/zebra/rt_ioctl.c
@@ -553,8 +553,8 @@ kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
/* Delete IPv6 route from the kernel. */
int
kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
- unsigned int index, int flags, int table)
+ unsigned int index, int table)
{
- return kernel_ioctl_ipv6 (SIOCDELRT, dest, gate, index, flags);
+ return kernel_ioctl_ipv6 (SIOCDELRT, dest, gate, index, 0;
}
#endif /* HAVE_IPV6 */
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 07e86647..8f8ad58a 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
@@ -65,7 +66,7 @@ static const struct message nlmsg_str[] = {
{0, NULL}
};
-static const char *nexthop_types_desc[] =
+static const char *nexthop_types_desc[] =
{
"none",
"Directly connected",
@@ -85,32 +86,11 @@ 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)
-{
- struct interface *oifp;
+extern int rib_system_routes;
- if (((oifp = if_lookup_by_index(ifi_index)) != NULL) && (oifp != ifp))
- {
- 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);
- }
- }
- ifp->ifindex = ifi_index;
-}
+static void
+netlink_delroute (int family, void *dest, int length, void *gate,
+ int index, int table, int proto);
static int
netlink_recvbuf (struct nlsock *nl, uint32_t newsize)
@@ -280,7 +260,8 @@ 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 };
@@ -293,6 +274,7 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
continue;
if (errno == EWOULDBLOCK || errno == EAGAIN)
break;
+
zlog (NULL, LOG_ERR, "%s recvmsg overrun: %s",
nl->name, safe_strerror(errno));
continue;
@@ -311,6 +293,13 @@ 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_debug ("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))
{
@@ -462,14 +451,28 @@ 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->mtu6 = ifp->mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
ifp->metric = 1;
/* Hardware type and address. */
@@ -523,7 +526,7 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
#ifdef HAVE_IPV6
&& ifa->ifa_family != AF_INET6
#endif /* HAVE_IPV6 */
- )
+ )
return 0;
if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
@@ -548,7 +551,7 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
{
char buf[BUFSIZ];
zlog_debug ("netlink_interface_addr %s %s:",
- lookup (nlmsg_str, h->nlmsg_type), ifp->name);
+ lookup (nlmsg_str, h->nlmsg_type), ifp->name);
if (tb[IFA_LOCAL])
zlog_debug (" IFA_LOCAL %s/%d",
inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]),
@@ -614,9 +617,25 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
if (ifa->ifa_family == AF_INET)
{
if (h->nlmsg_type == RTM_NEWADDR)
- connected_add_ipv4 (ifp, flags,
- (struct in_addr *) addr, ifa->ifa_prefixlen,
- (struct in_addr *) broad, label);
+ {
+ struct connected *ifc;
+ ifc = connected_add_ipv4 (ifp, flags,
+ (struct in_addr *) addr, ifa->ifa_prefixlen,
+ (struct in_addr *) broad, label);
+
+ /* If address added, but interface is down,
+ then remove the FIB entry from kernel.
+ */
+ if (rib_system_routes && ifc && !if_is_operative (ifp))
+ {
+ struct prefix_ipv4 p;
+ PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc));
+ apply_mask_ipv4 (&p);
+
+ netlink_delroute (p.family, &p.prefix, p.prefixlen, NULL,
+ ifp->ifindex, RT_TABLE_MAIN, RTPROT_KERNEL);
+ }
+ }
else
connected_delete_ipv4 (ifp, flags,
(struct in_addr *) addr, ifa->ifa_prefixlen,
@@ -626,9 +645,9 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
if (ifa->ifa_family == AF_INET6)
{
if (h->nlmsg_type == RTM_NEWADDR)
- connected_add_ipv6 (ifp, flags,
- (struct in6_addr *) addr, ifa->ifa_prefixlen,
- (struct in6_addr *) broad, label);
+ connected_add_ipv6 (ifp, flags,
+ (struct in6_addr *) addr, ifa->ifa_prefixlen,
+ (struct in6_addr *) broad, label);
else
connected_delete_ipv6 (ifp,
(struct in6_addr *) addr, ifa->ifa_prefixlen,
@@ -699,7 +718,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
src = NULL;
if (tb[RTA_OIF])
- index = *(int *) RTA_DATA (tb[RTA_OIF]);
+ index = *(uint32_t *) RTA_DATA (tb[RTA_OIF]);
if (tb[RTA_DST])
dest = RTA_DATA (tb[RTA_DST]);
@@ -714,7 +733,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
gate = RTA_DATA (tb[RTA_GATEWAY]);
if (tb[RTA_PRIORITY])
- metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]);
+ metric = *(uint32_t *) RTA_DATA(tb[RTA_PRIORITY]);
if (rtm->rtm_family == AF_INET)
{
@@ -723,7 +742,8 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
memcpy (&p.prefix, dest, 4);
p.prefixlen = rtm->rtm_dst_len;
- rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index, table, metric, 0);
+ rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index,
+ table, metric, 0, rtm->rtm_scope);
}
#ifdef HAVE_IPV6
if (rtm->rtm_family == AF_INET6)
@@ -830,7 +850,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
src = NULL;
if (tb[RTA_OIF])
- index = *(int *) RTA_DATA (tb[RTA_OIF]);
+ index = *(uint32_t *) RTA_DATA (tb[RTA_OIF]);
if (tb[RTA_DST])
dest = RTA_DATA (tb[RTA_DST]);
@@ -861,7 +881,8 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
}
if (h->nlmsg_type == RTM_NEWROUTE)
- rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table, 0, 0);
+ rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table, 0,
+ 0, rtm->rtm_scope);
else
rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table);
}
@@ -936,66 +957,103 @@ 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;
+ unsigned int mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
+ ifp = if_lookup_by_index (ifi->ifi_index);
+ /* New interface */
if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
{
if (ifp == NULL)
- ifp = if_get_by_name (name);
-
- set_ifindex(ifp, ifi->ifi_index);
- ifp->flags = ifi->ifi_flags & 0x0000fffff;
- ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
- ifp->metric = 1;
-
- /* If new link is added. */
- if_add_update (ifp);
+ {
+ ifp = if_create(name, strlen(name));
+ ifp->ifindex = ifi->ifi_index;
+ ifp->metric = 1;
+ }
+ else if (strcmp(ifp->name, name) != 0)
+ {
+ strncpy(ifp->name, name, INTERFACE_NAMSIZ);
+ }
+
+ 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 = mtu;
+
+ /* If new link is added. */
+ if_add_update (ifp);
}
- 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);
+ /* Interface status change. */
+ else if (new_flags != ifp->flags)
+ {
+ ifp->mtu6 = ifp->mtu = mtu;
+
+ 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
- {
- ifp->flags = ifi->ifi_flags & 0x0000fffff;
- if (if_is_operative (ifp))
- if_up (ifp);
- }
- }
+ zebra_interface_up_update (ifp);
+ }
+ else
+ {
+ ifp->flags = new_flags;
+ if (if_is_operative (ifp))
+ if_up (ifp);
+ }
+ }
+ /* Interface name change */
+ else if (strcmp(ifp->name, name) != 0)
+ {
+ ifp->mtu = ifp->mtu6 = mtu;
+ zlog_info("interface index %d was renamed from %s to %s",
+ ifi->ifi_index, ifp->name, name);
+
+ strncpy(ifp->name, name, INTERFACE_NAMSIZ);
+ rib_update();
+ }
+ /* Interface mtu change */
+ else if (mtu != ifp->mtu)
+ {
+ zlog_info("interface index %d mtu changed from %u to %u",
+ ifp->mtu, mtu);
+ ifp->mtu = ifp->mtu6 = mtu;
+ if (if_is_operative (ifp))
+ zebra_interface_up_update (ifp);
+ }
}
else
{
- /* RTM_DELLINK. */
- ifp = if_lookup_by_name (name);
-
+ // RTM_DELLINK.
+ ifp = if_lookup_by_index (ifi->ifi_index);
if (ifp == NULL)
{
- zlog (NULL, LOG_WARNING, "interface %s is deleted but can't find",
- name);
+ zlog (NULL, LOG_WARNING, "interface %s index %d is deleted but can't find",
+ name, ifi->ifi_index);
return 0;
}
+ else
+ zlog_info ("interface %s index %d deleted.",
+ name, ifi->ifi_index);
if_delete_update (ifp);
+ if_delete (ifp);
}
-
return 0;
}
@@ -1188,11 +1246,6 @@ netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
/* Request an acknowledgement by setting NLM_F_ACK */
n->nlmsg_flags |= NLM_F_ACK;
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl->name,
- lookup (nlmsg_str, n->nlmsg_type), n->nlmsg_type,
- n->nlmsg_seq);
-
/* Send message to netlink interface. */
if (zserv_privs.change (ZPRIVS_RAISE))
zlog (NULL, LOG_ERR, "Can't raise privileges");
@@ -1217,15 +1270,11 @@ netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
}
/* Routing table change via netlink interface. */
-static int
-netlink_route (int cmd, int family, void *dest, int length, void *gate,
- int index, int zebra_flags, int table)
+static void
+netlink_delroute (int family, void *dest, int length, void *gate,
+ int index, int table, int proto)
{
- int ret;
- int bytelen;
- struct sockaddr_nl snl;
- int discard;
-
+ int bytelen = (family == AF_INET ? 4 : 16);
struct
{
struct nlmsghdr n;
@@ -1235,59 +1284,25 @@ netlink_route (int cmd, int family, void *dest, int length, void *gate,
memset (&req, 0, sizeof req);
- bytelen = (family == AF_INET ? 4 : 16);
-
req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
- req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
- req.n.nlmsg_type = cmd;
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = RTM_DELROUTE;
req.r.rtm_family = family;
+ req.r.rtm_scope = RT_SCOPE_NOWHERE;
req.r.rtm_table = table;
req.r.rtm_dst_len = length;
- req.r.rtm_protocol = RTPROT_ZEBRA;
- req.r.rtm_scope = RT_SCOPE_UNIVERSE;
-
- if ((zebra_flags & ZEBRA_FLAG_BLACKHOLE)
- || (zebra_flags & ZEBRA_FLAG_REJECT))
- discard = 1;
- else
- discard = 0;
-
- if (cmd == RTM_NEWROUTE)
- {
- if (discard)
- {
- if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
- req.r.rtm_type = RTN_BLACKHOLE;
- else if (zebra_flags & ZEBRA_FLAG_REJECT)
- req.r.rtm_type = RTN_UNREACHABLE;
- else
- assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
- }
- else
- req.r.rtm_type = RTN_UNICAST;
- }
if (dest)
addattr_l (&req.n, sizeof req, RTA_DST, dest, bytelen);
- if (!discard)
- {
- if (gate)
- addattr_l (&req.n, sizeof req, RTA_GATEWAY, gate, bytelen);
- if (index > 0)
- addattr32 (&req.n, sizeof req, RTA_OIF, index);
- }
+ if (gate)
+ addattr_l (&req.n, sizeof req, RTA_GATEWAY, gate, bytelen);
- /* Destination netlink address. */
- memset (&snl, 0, sizeof snl);
- snl.nl_family = AF_NETLINK;
+ if (index > 0)
+ addattr32 (&req.n, sizeof req, RTA_OIF, index);
/* Talk to netlink socket. */
- ret = netlink_talk (&req.n, &netlink_cmd);
- if (ret < 0)
- return -1;
-
- return 0;
+ netlink_talk (&req.n, &netlink_cmd);
}
/* Routing table change via netlink interface. */
@@ -1326,6 +1341,20 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
else
discard = 0;
+ switch (rib->type) {
+ case ZEBRA_ROUTE_KERNEL:
+ /* FIXME: should remember original protocol from RTM_NEWLINK */
+ req.r.rtm_protocol = RTPROT_BOOT;
+ break;
+ case ZEBRA_ROUTE_CONNECT:
+ req.r.rtm_protocol = RTPROT_KERNEL;
+ break;
+ default:
+ req.r.rtm_protocol = RTPROT_ZEBRA;
+ }
+
+ req.r.rtm_scope = rib->scope;
+
if (cmd == RTM_NEWROUTE)
{
if (discard)
@@ -1343,8 +1372,8 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
- /* Metric. */
- addattr32 (&req.n, sizeof req, RTA_PRIORITY, rib->metric);
+ if (rib->type != ZEBRA_ROUTE_CONNECT)
+ addattr32 (&req.n, sizeof req, RTA_PRIORITY, rib->metric);
if (discard)
{
@@ -1743,12 +1772,12 @@ kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
}
/* Delete IPv6 route from the kernel. */
-int
+void
kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
- unsigned int index, int flags, int table)
+ unsigned int index, int table)
{
- return netlink_route (RTM_DELROUTE, AF_INET6, &dest->prefix,
- dest->prefixlen, gate, index, flags, table);
+ netlink_delroute (AF_INET6, &dest->prefix,
+ dest->prefixlen, gate, index, table, RTPROT_ZEBRA);
}
#endif /* HAVE_IPV6 */
@@ -1831,72 +1860,20 @@ kernel_read (struct thread *thread)
return 0;
}
-<<<<<<< HEAD:zebra/rt_netlink.c
-/* 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)
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/rt_netlink.c
{
-<<<<<<< HEAD:zebra/rt_netlink.c
- /*
- * 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;
- */
-=======
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/rt_netlink.c
struct sock_filter filter[] = {
-<<<<<<< HEAD:zebra/rt_netlink.c
- /* 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] */
+ /* 0: ldw [12] */
BPF_STMT(BPF_LD|BPF_ABS|BPF_W, offsetof(struct nlmsghdr, nlmsg_pid)),
- /* 4: jeq XX jt 5 jf 6 */
+ /* 1: jeq XX jt 2 jf 3 */
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htonl(pid), 0, 1),
- /* 5: ret 0 (skip) */
+ /* 2: ret 0 (skip) */
BPF_STMT(BPF_RET|BPF_K, 0),
- /* 6: ret 0xffff (keep) */
+ /* 3: ret 0xffff (keep) */
BPF_STMT(BPF_RET|BPF_K, 0xffff),
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/rt_netlink.c
};
struct sock_fprog prog = {
@@ -1925,9 +1902,6 @@ kernel_init (void)
/* Register kernel socket. */
if (netlink.sock > 0)
{
-<<<<<<< HEAD:zebra/rt_netlink.c
- 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,
@@ -1938,7 +1912,6 @@ kernel_init (void)
netlink_recvbuf (&netlink, nl_rcvbufsize);
netlink_install_filter (netlink.sock, netlink_cmd.snl.nl_pid);
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/rt_netlink.c
thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
}
}
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index 1b8ded7e..9bbecb95 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -509,13 +509,13 @@ kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
/* Delete IPv6 route from the kernel. */
int
kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
- unsigned int index, int flags, int table)
+ unsigned int index, int table)
{
int route;
if (zserv_privs.change(ZPRIVS_RAISE))
zlog (NULL, LOG_ERR, "Can't raise privileges");
- route = kernel_rtm_ipv6 (RTM_DELETE, dest, gate, index, flags);
+ route = kernel_rtm_ipv6 (RTM_DELETE, dest, gate, index);
if (zserv_privs.change(ZPRIVS_LOWER))
zlog (NULL, LOG_ERR, "Can't lower privileges");
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index 4bdb83d5..86956ed7 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -84,17 +84,16 @@ struct rtadv *rtadv = NULL;
static struct rtadv *
rtadv_new (void)
{
- struct rtadv *new;
- new = XMALLOC (MTYPE_TMP, sizeof (struct rtadv));
- memset (new, 0, sizeof (struct rtadv));
- return new;
+ return XCALLOC (MTYPE_TMP, sizeof (struct rtadv));
}
+#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 +450,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);
@@ -529,12 +528,7 @@ rtadv_make_socket (void)
static struct rtadv_prefix *
rtadv_prefix_new ()
{
- struct rtadv_prefix *new;
-
- new = XMALLOC (MTYPE_RTADV_PREFIX, sizeof (struct rtadv_prefix));
- memset (new, 0, sizeof (struct rtadv_prefix));
-
- return new;
+ return XCALLOC (MTYPE_RTADV_PREFIX, sizeof (struct rtadv_prefix));
}
static void
diff --git a/zebra/rtadv.h b/zebra/rtadv.h
index 658bc5ff..abd1c6fc 100644
--- a/zebra/rtadv.h
+++ b/zebra/rtadv.h
@@ -23,10 +23,7 @@
#ifndef _ZEBRA_RTADV_H
#define _ZEBRA_RTADV_H
-<<<<<<< HEAD:zebra/rtadv.h
-=======
#include "vty.h"
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/rtadv.h
#include "zebra/interface.h"
/* Router advertisement prefix. */
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 1cb9856a..69249779 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -44,6 +44,9 @@
/* Default rtm_table for all clients */
extern struct zebra_t zebrad;
+/* Should kernel routes be removed on link down? */
+int rib_system_routes = 0;
+
/* Hold time for RIB process, should be very minimal.
* it is useful to able to set it otherwise for testing, hence exported
* as global here for test-rig code.
@@ -93,6 +96,7 @@ vrf_alloc (const char *name)
return vrf;
}
+#if 0
/* Free VRF. */
static void
vrf_free (struct vrf *vrf)
@@ -101,6 +105,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 +114,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 +128,7 @@ vrf_lookup_by_name (char *name)
return vrf;
return NULL;
}
+#endif
/* Initialize VRF. */
static void
@@ -205,14 +212,16 @@ nexthop_free (struct nexthop *nexthop)
}
struct nexthop *
-nexthop_ifindex_add (struct rib *rib, unsigned int ifindex)
+nexthop_ifindex_add (struct rib *rib, unsigned int ifindex,
+ struct in_addr *src)
{
struct nexthop *nexthop;
- nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
- memset (nexthop, 0, sizeof (struct nexthop));
+ nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
nexthop->type = NEXTHOP_TYPE_IFINDEX;
nexthop->ifindex = ifindex;
+ if (src)
+ nexthop->src.ipv4 = *src;
nexthop_add (rib, nexthop);
@@ -224,8 +233,7 @@ nexthop_ifname_add (struct rib *rib, char *ifname)
{
struct nexthop *nexthop;
- nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
- memset (nexthop, 0, sizeof (struct nexthop));
+ nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
nexthop->type = NEXTHOP_TYPE_IFNAME;
nexthop->ifname = XSTRDUP (0, ifname);
@@ -239,8 +247,7 @@ nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src)
{
struct nexthop *nexthop;
- nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
- memset (nexthop, 0, sizeof (struct nexthop));
+ nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
nexthop->type = NEXTHOP_TYPE_IPV4;
nexthop->gate.ipv4 = *ipv4;
if (src)
@@ -257,8 +264,7 @@ nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4,
{
struct nexthop *nexthop;
- nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
- memset (nexthop, 0, sizeof (struct nexthop));
+ nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
nexthop->gate.ipv4 = *ipv4;
if (src)
@@ -276,8 +282,7 @@ nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6)
{
struct nexthop *nexthop;
- nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
- memset (nexthop, 0, sizeof (struct nexthop));
+ nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
nexthop->type = NEXTHOP_TYPE_IPV6;
nexthop->gate.ipv6 = *ipv6;
@@ -292,8 +297,7 @@ nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,
{
struct nexthop *nexthop;
- nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
- memset (nexthop, 0, sizeof (struct nexthop));
+ nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;
nexthop->gate.ipv6 = *ipv6;
nexthop->ifname = XSTRDUP (0, ifname);
@@ -309,8 +313,7 @@ nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,
{
struct nexthop *nexthop;
- nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
- memset (nexthop, 0, sizeof (struct nexthop));
+ nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
nexthop->gate.ipv6 = *ipv6;
nexthop->ifindex = ifindex;
@@ -326,8 +329,7 @@ nexthop_blackhole_add (struct rib *rib)
{
struct nexthop *nexthop;
- nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
- memset (nexthop, 0, sizeof (struct nexthop));
+ nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));
nexthop->type = NEXTHOP_TYPE_BLACKHOLE;
SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);
@@ -336,6 +338,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 +379,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));
@@ -400,16 +432,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)
{
@@ -422,7 +470,13 @@ 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;
@@ -501,17 +555,36 @@ 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))
+ 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)
{
@@ -526,7 +599,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.ipv6))
+ SET_FLAG (rib->flags, ZEBRA_FLAG_CHANGED);
+
return 1;
}
return 0;
@@ -683,21 +764,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)
-<<<<<<< HEAD:zebra/zebra_rib.c
- {
- 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;
}
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c
/* None such found :( */
if (!match)
@@ -709,24 +781,24 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate)
/* Ok, we have a cood candidate, let's check it's nexthop list... */
for (nexthop = match->nexthop; nexthop; nexthop = nexthop->next)
if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))
- {
- /* We are happy with either direct or recursive hexthop */
- if (nexthop->gate.ipv4.s_addr == qgate->sin.sin_addr.s_addr ||
- nexthop->rgate.ipv4.s_addr == qgate->sin.sin_addr.s_addr)
- return ZEBRA_RIB_FOUND_EXACT;
- else
{
- if (IS_ZEBRA_DEBUG_RIB)
- {
- char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
- inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
- inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
- inet_ntop (AF_INET, &qgate->sin.sin_addr.s_addr, qgate_buf, INET_ADDRSTRLEN);
- zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
- }
- return ZEBRA_RIB_FOUND_NOGATE;
+ /* We are happy with either direct or recursive hexthop */
+ if (nexthop->gate.ipv4.s_addr == qgate->sin.sin_addr.s_addr ||
+ nexthop->rgate.ipv4.s_addr == qgate->sin.sin_addr.s_addr)
+ return ZEBRA_RIB_FOUND_EXACT;
+ else
+ {
+ if (IS_ZEBRA_DEBUG_RIB)
+ {
+ char gate_buf[INET_ADDRSTRLEN], rgate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN];
+ inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN);
+ inet_ntop (AF_INET, &nexthop->rgate.ipv4.s_addr, rgate_buf, INET_ADDRSTRLEN);
+ inet_ntop (AF_INET, &qgate->sin.sin_addr.s_addr, qgate_buf, INET_ADDRSTRLEN);
+ zlog_debug ("%s: qgate == %s, gate == %s, rgate == %s", __func__, qgate_buf, gate_buf, rgate_buf);
+ }
+ return ZEBRA_RIB_FOUND_NOGATE;
+ }
}
- }
return ZEBRA_RIB_NOTFOUND;
}
@@ -795,8 +867,10 @@ rib_match_ipv6 (struct in6_addr *addr)
}
#endif /* HAVE_IPV6 */
-#define RIB_SYSTEM_ROUTE(R) \
+#define RIB_SYSTEM_ROUTE(R) \
((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
+#define RIB_SHOULD_UPDATE(R) \
+ (! CHECK_FLAG((R)->status, RIB_ENTRY_PRESERVE) )
/* This function verifies reachability of one given nexthop, which can be
* numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored
@@ -807,7 +881,6 @@ rib_match_ipv6 (struct in6_addr *addr)
*
* The return value is the final value of 'ACTIVE' flag.
*/
-
static int
nexthop_active_check (struct route_node *rn, struct rib *rib,
struct nexthop *nexthop, int set)
@@ -980,8 +1053,6 @@ rib_uninstall_kernel (struct route_node *rn, struct rib *rib)
break;
#ifdef HAVE_IPV6
case AF_INET6:
- if (IS_ZEBRA_DEBUG_RIB)
- zlog_debug ("%s: calling kernel_delete_ipv4 (%p, %p)", __func__, rn, rib);
ret = kernel_delete_ipv6 (&rn->p, rib);
break;
#endif /* HAVE_IPV6 */
@@ -1000,7 +1071,7 @@ rib_uninstall (struct route_node *rn, struct rib *rib)
if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
{
redistribute_delete (&rn->p, rib);
- if (! RIB_SYSTEM_ROUTE (rib))
+ if (RIB_SHOULD_UPDATE (rib))
rib_uninstall_kernel (rn, rib);
UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED);
}
@@ -1125,17 +1196,17 @@ rib_process (struct route_node *rn)
if (CHECK_FLAG (select->flags, ZEBRA_FLAG_CHANGED))
{
redistribute_delete (&rn->p, select);
- if (! RIB_SYSTEM_ROUTE (select))
+ if (RIB_SHOULD_UPDATE (select))
rib_uninstall_kernel (rn, select);
/* Set real nexthop. */
nexthop_active_update (rn, select, 1);
- if (! RIB_SYSTEM_ROUTE (select))
+ if (RIB_SHOULD_UPDATE (select))
rib_install_kernel (rn, select);
redistribute_add (&rn->p, select);
}
- else if (! RIB_SYSTEM_ROUTE (select))
+ else if (RIB_SHOULD_UPDATE (select))
{
/* Housekeeping code to deal with
race conditions in kernel with linux
@@ -1166,7 +1237,7 @@ rib_process (struct route_node *rn)
zlog_debug ("%s: %s/%d: Removing existing route, fib %p", __func__,
buf, rn->p.prefixlen, fib);
redistribute_delete (&rn->p, fib);
- if (! RIB_SYSTEM_ROUTE (fib))
+ if (RIB_SHOULD_UPDATE (fib))
rib_uninstall_kernel (rn, fib);
UNSET_FLAG (fib->flags, ZEBRA_FLAG_SELECTED);
@@ -1186,7 +1257,7 @@ rib_process (struct route_node *rn)
/* Set real nexthop. */
nexthop_active_update (rn, select, 1);
- if (! RIB_SYSTEM_ROUTE (select))
+ if (RIB_SHOULD_UPDATE (select))
rib_install_kernel (rn, select);
SET_FLAG (select->flags, ZEBRA_FLAG_SELECTED);
redistribute_add (&rn->p, select);
@@ -1200,129 +1271,31 @@ rib_process (struct route_node *rn)
rn->p.prefixlen, del, rn);
rib_unlink (rn, del);
}
-<<<<<<< HEAD:zebra/zebra_rib.c
end:
if (IS_ZEBRA_DEBUG_RIB_Q)
zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
}
-/* Take a list of route_node structs and return 1, if there was a record picked from
- * it and processed by rib_process(). Don't process more, than one RN record; operate
- * only in the specified sub-queue.
- */
-unsigned int
-process_subq (struct list * subq, u_char qindex)
-{
- struct listnode *lnode;
- struct route_node *rnode;
- if (!(lnode = listhead (subq)))
- return 0;
- rnode = listgetdata (lnode);
- rib_process (rnode);
- if (rnode->info) /* The first RIB record is holding the flags bitmask. */
- UNSET_FLAG (((struct rib *)rnode->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
- route_unlock_node (rnode);
- list_delete_node (subq, lnode);
- return 1;
-}
-
-/* Dispatch the meta queue by picking, processing and unlocking the next RN from
- * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data
- * is pointed to the meta queue structure.
- */
-static wq_item_status
-meta_queue_process (struct work_queue *dummy, void *data)
-{
- struct meta_queue * mq = data;
- u_char i;
- for (i = 0; i < MQ_SIZE; i++)
- if (process_subq (mq->subq[i], i))
- {
- mq->size--;
- break;
- }
- return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
-}
-=======
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c
-
-<<<<<<< HEAD:zebra/zebra_rib.c
-/* Look into the RN and queue it into one or more priority queues, increasing the size
- * for each data push done.
- */
-void rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
-{
- u_char qindex;
- struct rib *rib;
- char buf[INET6_ADDRSTRLEN];
-=======
-end:
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c
- if (IS_ZEBRA_DEBUG_RIB_Q)
-<<<<<<< HEAD:zebra/zebra_rib.c
- inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
- for (rib = rn->info; rib; rib = rib->next)
- {
- switch (rib->type)
- {
- case ZEBRA_ROUTE_KERNEL:
- case ZEBRA_ROUTE_CONNECT:
- qindex = 0;
- break;
- case ZEBRA_ROUTE_STATIC:
- qindex = 1;
- break;
- case ZEBRA_ROUTE_RIP:
- case ZEBRA_ROUTE_RIPNG:
- case ZEBRA_ROUTE_OSPF:
- case ZEBRA_ROUTE_OSPF6:
- case ZEBRA_ROUTE_ISIS:
- qindex = 2;
- break;
- case ZEBRA_ROUTE_BGP:
- qindex = 3;
- break;
- default:
- qindex = 4;
- break;
- }
- /* Invariant: at this point we always have rn->info set. */
- if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
- {
- if (IS_ZEBRA_DEBUG_RIB_Q)
- zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u", __func__, buf, rn->p.prefixlen, rn, qindex);
- continue;
- }
- SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
- listnode_add (mq->subq[qindex], rn);
- route_lock_node (rn);
- mq->size++;
- if (IS_ZEBRA_DEBUG_RIB_Q)
- zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u", __func__, buf, rn->p.prefixlen, rn, qindex);
- }
-=======
- zlog_debug ("%s: %s/%d: rn %p dequeued", __func__, buf, rn->p.prefixlen, rn);
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c
-}
-
-<<<<<<< HEAD:zebra/zebra_rib.c
-=======
-/* Take a list of route_node structs and return 1, if there was a record picked from
- * it and processed by rib_process(). Don't process more, than one RN record; operate
- * only in the specified sub-queue.
+/* Take a list of route_node structs and return 1, if there was a record
+ * picked from it and processed by rib_process(). Don't process more,
+ * than one RN record; operate only in the specified sub-queue.
*/
static unsigned int
process_subq (struct list * subq, u_char qindex)
{
- struct listnode *lnode;
+ struct listnode *lnode = listhead (subq);
struct route_node *rnode;
- if (!(lnode = listhead (subq)))
+
+ if (!lnode)
return 0;
+
rnode = listgetdata (lnode);
rib_process (rnode);
+
if (rnode->info) /* The first RIB record is holding the flags bitmask. */
UNSET_FLAG (((struct rib *)rnode->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
+
route_unlock_node (rnode);
list_delete_node (subq, lnode);
return 1;
@@ -1336,69 +1309,68 @@ static wq_item_status
meta_queue_process (struct work_queue *dummy, void *data)
{
struct meta_queue * mq = data;
- u_char i;
+ unsigned i;
+
for (i = 0; i < MQ_SIZE; i++)
if (process_subq (mq->subq[i], i))
- {
- mq->size--;
- break;
- }
+ {
+ mq->size--;
+ break;
+ }
return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
}
-/* Look into the RN and queue it into one or more priority queues, increasing the size
- * for each data push done.
+/* Map from rib types to queue type (priority) in meta queue */
+static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = {
+ [ZEBRA_ROUTE_SYSTEM] = 4,
+ [ZEBRA_ROUTE_KERNEL] = 0,
+ [ZEBRA_ROUTE_CONNECT] = 0,
+ [ZEBRA_ROUTE_STATIC] = 1,
+ [ZEBRA_ROUTE_RIP] = 2,
+ [ZEBRA_ROUTE_RIPNG] = 2,
+ [ZEBRA_ROUTE_OSPF] = 2,
+ [ZEBRA_ROUTE_OSPF6] = 2,
+ [ZEBRA_ROUTE_ISIS] = 2,
+ [ZEBRA_ROUTE_BGP] = 3,
+ [ZEBRA_ROUTE_HSLS] = 4,
+};
+
+/* Look into the RN and queue it into one or more priority queues,
+ * increasing the size for each data push done.
*/
static void
rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn)
{
- u_char qindex;
struct rib *rib;
char buf[INET6_ADDRSTRLEN];
+
if (IS_ZEBRA_DEBUG_RIB_Q)
inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
+
for (rib = rn->info; rib; rib = rib->next)
- {
- switch (rib->type)
- {
- case ZEBRA_ROUTE_KERNEL:
- case ZEBRA_ROUTE_CONNECT:
- qindex = 0;
- break;
- case ZEBRA_ROUTE_STATIC:
- qindex = 1;
- break;
- case ZEBRA_ROUTE_RIP:
- case ZEBRA_ROUTE_RIPNG:
- case ZEBRA_ROUTE_OSPF:
- case ZEBRA_ROUTE_OSPF6:
- case ZEBRA_ROUTE_ISIS:
- qindex = 2;
- break;
- case ZEBRA_ROUTE_BGP:
- qindex = 3;
- break;
- default:
- qindex = 4;
- break;
- }
- /* Invariant: at this point we always have rn->info set. */
- if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
{
+ u_char qindex = meta_queue_map[rib->type];
+
+ /* Invariant: at this point we always have rn->info set. */
+ if (CHECK_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex)))
+ {
+ if (IS_ZEBRA_DEBUG_RIB_Q)
+ zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u",
+ __func__, buf, rn->p.prefixlen, rn, qindex);
+ continue;
+ }
+
+ SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
+ listnode_add (mq->subq[qindex], rn);
+ route_lock_node (rn);
+ mq->size++;
+
if (IS_ZEBRA_DEBUG_RIB_Q)
- zlog_debug ("%s: %s/%d: rn %p is already queued in sub-queue %u", __func__, buf, rn->p.prefixlen, rn, qindex);
- continue;
- }
- SET_FLAG (((struct rib *)rn->info)->rn_status, RIB_ROUTE_QUEUED(qindex));
- listnode_add (mq->subq[qindex], rn);
- route_lock_node (rn);
- mq->size++;
- if (IS_ZEBRA_DEBUG_RIB_Q)
- zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u", __func__, buf, rn->p.prefixlen, rn, qindex);
- }
+ zlog_debug ("%s: %s/%d: queued rn %p into sub-queue %u",
+ __func__, buf, rn->p.prefixlen, rn, qindex);
+ }
}
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c
/* Add route_node to work queue and schedule processing */
static void
rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
@@ -1441,48 +1413,31 @@ rib_queue_add (struct zebra_t *zebra, struct route_node *rn)
work_queue_add (zebra->ribq, zebra->mq);
rib_meta_queue_add (zebra->mq, rn);
-<<<<<<< HEAD:zebra/zebra_rib.c
-=======
if (IS_ZEBRA_DEBUG_RIB_Q)
zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c
-<<<<<<< HEAD:zebra/zebra_rib.c
- if (IS_ZEBRA_DEBUG_RIB_Q)
- zlog_debug ("%s: %s/%d: rn %p queued", __func__, buf, rn->p.prefixlen, rn);
-
-=======
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c
return;
}
-/* Create new meta queue. A destructor function doesn't seem to be necessary here. */
-<<<<<<< HEAD:zebra/zebra_rib.c
-struct meta_queue *
-meta_queue_new ()
-=======
+/* Create new meta queue.
+ A destructor function doesn't seem to be necessary here.
+ */
static struct meta_queue *
meta_queue_new (void)
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c
{
struct meta_queue *new;
- unsigned i, failed = 0;
+ unsigned i;
+
+ new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue));
+ assert(new);
- if ((new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue))) == NULL)
- return NULL;
for (i = 0; i < MQ_SIZE; i++)
- if ((new->subq[i] = list_new ()) == NULL)
- failed = 1;
- if (failed)
- {
- for (i = 0; i < MQ_SIZE; i++)
- if (new->subq[i])
- list_delete (new->subq[i]);
- XFREE (MTYPE_WORK_QUEUE, new);
- return NULL;
- }
- new->size = 0;
+ {
+ new->subq[i] = list_new ();
+ assert(new->subq[i]);
+ }
+
return new;
}
@@ -1587,8 +1542,6 @@ rib_link (struct route_node *rn, struct rib *rib)
static void
rib_addnode (struct route_node *rn, struct rib *rib)
-<<<<<<< HEAD:zebra/zebra_rib.c
-=======
{
/* RIB node has been un-removed before route-node is processed.
* route_node must hence already be on the queue for processing..
@@ -1610,32 +1563,7 @@ rib_addnode (struct route_node *rn, struct rib *rib)
static void
rib_unlink (struct route_node *rn, struct rib *rib)
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c
{
-<<<<<<< HEAD:zebra/zebra_rib.c
- /* RIB node has been un-removed before route-node is processed.
- * route_node must hence already be on the queue for processing..
- */
- if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED))
- {
- if (IS_ZEBRA_DEBUG_RIB)
- {
- char buf[INET6_ADDRSTRLEN];
- inet_ntop (rn->p.family, &rn->p.u.prefix, buf, INET6_ADDRSTRLEN);
- zlog_debug ("%s: %s/%d: rn %p, un-removed rib %p",
- __func__, buf, rn->p.prefixlen, rn, rib);
- }
- UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED);
- return;
- }
- rib_link (rn, rib);
-}
-
-static void
-rib_unlink (struct route_node *rn, struct rib *rib)
-{
-=======
->>>>>>> 41dc3488cf127a1e23333459a0c316ded67f7ff3:zebra/zebra_rib.c
struct nexthop *nexthop, *next;
char buf[INET6_ADDRSTRLEN];
@@ -1695,7 +1623,7 @@ int
rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
struct in_addr *gate, struct in_addr *src,
unsigned int ifindex, u_int32_t vrf_id,
- u_int32_t metric, u_char distance)
+ u_int32_t metric, u_int8_t distance, u_int8_t scope)
{
struct rib *rib;
struct rib *same = NULL;
@@ -1703,6 +1631,7 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
struct route_node *rn;
struct nexthop *nexthop;
+
/* Lookup table. */
table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
if (! table)
@@ -1758,6 +1687,7 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
rib->table = vrf_id;
rib->nexthop_num = 0;
rib->uptime = time (NULL);
+ rib->scope = scope;
/* Nexthop settings. */
if (gate)
@@ -1768,12 +1698,18 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
nexthop_ipv4_add (rib, gate, src);
}
else
- nexthop_ifindex_add (rib, ifindex);
+ nexthop_ifindex_add (rib, ifindex, src);
/* If this route is kernel route, set FIB flag to the route. */
- if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
- for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
- SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
+ if (RIB_SYSTEM_ROUTE (rib))
+ {
+ /* Mark system routes with the don't touch me flag */
+ if (! rib_system_routes)
+ SET_FLAG(rib->status, RIB_ENTRY_PRESERVE);
+
+ for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
+ SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
+ }
/* Link new rib to node.*/
if (IS_ZEBRA_DEBUG_RIB)
@@ -1806,10 +1742,10 @@ 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,
+ (unsigned long) rib->uptime,
rib->type,
rib->table
);
@@ -1931,8 +1867,7 @@ void rib_lookup_and_pushup (struct prefix_ipv4 * p)
*/
for (rib = rn->info; rib; rib = rib->next)
{
- if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) &&
- ! RIB_SYSTEM_ROUTE (rib))
+ if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) && RIB_SHOULD_UPDATE (rib))
{
changed = 1;
if (IS_ZEBRA_DEBUG_RIB)
@@ -2350,8 +2285,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id);
/* Make new static route structure. */
- si = XMALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
- memset (si, 0, sizeof (struct static_ipv4));
+ si = XCALLOC (MTYPE_STATIC_IPV4, sizeof (struct static_ipv4));
si->type = type;
si->distance = distance;
@@ -2392,6 +2326,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;
}
@@ -2456,6 +2393,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;
}
@@ -2476,7 +2416,7 @@ rib_bogus_ipv6 (int type, struct prefix_ipv6 *p,
if (type == ZEBRA_ROUTE_KERNEL && IN6_IS_ADDR_UNSPECIFIED (&p->prefix)
&& p->prefixlen == 96 && gate && IN6_IS_ADDR_UNSPECIFIED (gate))
{
- kernel_delete_ipv6_old (p, gate, ifindex, 0, table);
+ kernel_delete_ipv6_old (p, gate, ifindex, table);
return 1;
}
return 0;
@@ -2558,12 +2498,18 @@ rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
nexthop_ipv6_add (rib, gate);
}
else
- nexthop_ifindex_add (rib, ifindex);
+ nexthop_ifindex_add (rib, ifindex, NULL);
/* If this route is kernel route, set FIB flag to the route. */
if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT)
- for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
- SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
+ {
+ /* Mark system routes with the don't touch me flag */
+ if (! rib_system_routes)
+ SET_FLAG(rib->status, RIB_ENTRY_PRESERVE);
+
+ for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
+ SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
+ }
/* Link new rib to node.*/
rib_addnode (rn, rib);
@@ -2894,8 +2840,7 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
}
/* Make new static route structure. */
- si = XMALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
- memset (si, 0, sizeof (struct static_ipv6));
+ si = XCALLOC (MTYPE_STATIC_IPV6, sizeof (struct static_ipv6));
si->type = type;
si->distance = distance;
@@ -2938,6 +2883,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;
}
@@ -2991,6 +2938,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 */
@@ -3015,6 +2963,7 @@ rib_update (void)
rib_queue_add (&zebrad, rn);
}
+#if 0
/* Interface goes up. */
static void
rib_if_up (struct interface *ifp)
@@ -3028,6 +2977,7 @@ rib_if_down (struct interface *ifp)
{
rib_update ();
}
+#endif
/* Remove all routes which comes from non main table. */
static void
@@ -3107,7 +3057,7 @@ rib_close_table (struct route_table *table)
for (rn = route_top (table); rn; rn = route_next (rn))
for (rib = rn->info; rib; rib = rib->next)
{
- if (! RIB_SYSTEM_ROUTE (rib)
+ if (RIB_SHOULD_UPDATE (rib)
&& CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED))
rib_uninstall_kernel (rn, rib);
}
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 0c313921..f50ab05e 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -2030,10 +2030,10 @@ static int config_write_protocol(struct vty *vty)
}
/* table node for protocol filtering */
-struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
+static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 };
/* IP node for static routes. */
-struct cmd_node ip_node = { IP_NODE, "", 1 };
+static struct cmd_node ip_node = { IP_NODE, "", 1 };
/* Route VTY. */
void
diff --git a/zebra/zserv.c b/zebra/zserv.c
index ef79eaad..76e74088 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -773,7 +773,7 @@ zread_ipv4_add (struct zserv *client, u_short length)
{
case ZEBRA_NEXTHOP_IFINDEX:
ifindex = stream_getl (s);
- nexthop_ifindex_add (rib, ifindex);
+ nexthop_ifindex_add (rib, ifindex, NULL);
break;
case ZEBRA_NEXTHOP_IFNAME:
ifname_len = stream_getc (s);
@@ -1569,7 +1569,7 @@ config_write_table (struct vty *vty)
}
/* table node for routing tables. */
-struct cmd_node table_node =
+static struct cmd_node table_node =
{
TABLE_NODE,
"", /* This node has no interface. */
@@ -1689,7 +1689,7 @@ config_write_forwarding (struct vty *vty)
}
/* table node for routing tables. */
-struct cmd_node forwarding_node =
+static struct cmd_node forwarding_node =
{
FORWARDING_NODE,
"", /* This node has no interface. */