summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_advertise.c4
-rw-r--r--bgpd/bgp_advertise.h32
-rw-r--r--lib/command.c185
-rw-r--r--lib/command.h2
-rw-r--r--lib/if.c2
-rw-r--r--lib/vty.c28
-rw-r--r--lib/zebra.h39
-rw-r--r--ospfd/ospf_abr.c45
-rw-r--r--ospfd/ospf_route.c55
-rw-r--r--ospfd/ospf_spf.c2
-rw-r--r--ospfd/ospf_vty.c3
-rw-r--r--ospfd/ospf_zebra.c7
-rw-r--r--ospfd/ospf_zebra.h2
-rw-r--r--ospfd/ospfd.c2
-rw-r--r--zebra/rib.h1
-rw-r--r--zebra/zebra_rib.c43
-rw-r--r--zebra/zserv.c8
-rw-r--r--zebra/zserv.h3
18 files changed, 204 insertions, 259 deletions
diff --git a/bgpd/bgp_advertise.c b/bgpd/bgp_advertise.c
index 87eb7ac7..4163ab96 100644
--- a/bgpd/bgp_advertise.c
+++ b/bgpd/bgp_advertise.c
@@ -263,7 +263,7 @@ bgp_adj_out_set (struct bgp_node *rn, struct peer *peer, struct prefix *p,
/* Add new advertisement to advertisement attribute list. */
bgp_advertise_add (adv->baa, adv);
- FIFO_ADD (&peer->sync[afi][safi]->update, &adv->fifo);
+ FIFO_ADD (&peer->sync[afi][safi]->update, adv);
}
void
@@ -297,7 +297,7 @@ bgp_adj_out_unset (struct bgp_node *rn, struct peer *peer, struct prefix *p,
adv->adj = adj;
/* Add to synchronization entry for withdraw announcement. */
- FIFO_ADD (&peer->sync[afi][safi]->withdraw, &adv->fifo);
+ FIFO_ADD (&peer->sync[afi][safi]->withdraw, adv);
/* Schedule packet write. */
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
diff --git a/bgpd/bgp_advertise.h b/bgpd/bgp_advertise.h
index 4ebde907..53427eb3 100644
--- a/bgpd/bgp_advertise.h
+++ b/bgpd/bgp_advertise.h
@@ -102,6 +102,38 @@ struct bgp_synchronize
struct bgp_advertise_fifo withdraw_low;
};
+static inline void FIFO_INIT(struct bgp_advertise_fifo *fifo)
+{
+ fifo->next = fifo->prev = (struct bgp_advertise *) fifo;
+}
+
+static inline void FIFO_ADD(struct bgp_advertise_fifo *fifo,
+ struct bgp_advertise *node)
+{
+ node->fifo.next = (struct bgp_advertise *) fifo;
+ node->fifo.prev = fifo->prev;
+ fifo->prev = fifo->prev->next = node;
+}
+
+static inline void FIFO_DEL(struct bgp_advertise *node)
+{
+ struct bgp_advertise_fifo *fifo = &node->fifo;
+
+ fifo->prev->next = fifo->next;
+ fifo->next->prev = fifo->prev;
+}
+
+static inline int FIFO_EMPTY(const struct bgp_advertise_fifo *fifo)
+{
+ return (fifo->next == (const struct bgp_advertise *) fifo);
+}
+
+static inline struct bgp_advertise *FIFO_HEAD(struct bgp_advertise_fifo *fifo)
+{
+ return FIFO_EMPTY(fifo) ? NULL : fifo->next;
+}
+
+
/* BGP adjacency linked list. */
#define BGP_INFO_ADD(N,A,TYPE) \
do { \
diff --git a/lib/command.c b/lib/command.c
index 290f1be0..bf624cc0 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -687,8 +687,8 @@ cmd_filter_by_symbol (char *command, char *symbol)
/* Completion match types. */
enum match_type
{
-no_match = 0,
-any_match,
+ no_match = 0,
+ any_match,
extend_match,
ipv4_prefix_match,
ipv4_match,
@@ -697,7 +697,7 @@ any_match,
range_match,
vararg_match,
partly_match,
-exact_match,
+ exact_match,
};
static enum match_type
@@ -1138,92 +1138,92 @@ cmd_range_match (const char *range, const char *str)
static char *
cmd_deopt (const char *str)
{
-/* we've got "[blah]". We want to strip off the []s and redo the
-* match check for "blah"
-*/
-size_t len = strlen (str);
-char *tmp;
+ /* we've got "[blah]". We want to strip off the []s and redo the
+ * match check for "blah"
+ */
+ size_t len = strlen (str);
+ char *tmp;
-if (len < 3)
-return NULL;
+ if (len < 3)
+ return NULL;
-/* tmp will hold a string of len-2 chars, so 'len' size is fine */
-tmp = XMALLOC(MTYPE_TMP, len);
+ /* tmp will hold a string of len-2 chars, so 'len' size is fine */
+ tmp = XMALLOC(MTYPE_TMP, len);
-memcpy (tmp, (str + 1), len - 2);
-tmp[len - 2] = '\0';
+ memcpy (tmp, (str + 1), len - 2);
+ tmp[len - 2] = '\0';
-return tmp;
+ return tmp;
}
static enum match_type
cmd_match (const char *str, const char *command,
-enum match_type min, bool recur)
+ enum match_type min, bool recur)
{
-if (recur && CMD_OPTION(str))
-{
-enum match_type ret;
-char *tmp = cmd_deopt (str);
+ if (recur && CMD_OPTION(str))
+ {
+ enum match_type ret;
+ char *tmp = cmd_deopt (str);
-/* this would be a bug in a command, however handle it gracefully
-* as it we only discover it if a user tries to run it
-*/
-if (tmp == NULL)
-return no_match;
+ /* this would be a bug in a command, however handle it gracefully
+ * as it we only discover it if a user tries to run it
+ */
+ if (tmp == NULL)
+ return no_match;
-ret = cmd_match (tmp, command, min, false);
+ ret = cmd_match (tmp, command, min, false);
-XFREE (MTYPE_TMP, tmp);
+ XFREE (MTYPE_TMP, tmp);
-return ret;
-}
-else if (CMD_VARARG (str))
-return vararg_match;
-else if (CMD_RANGE (str))
-{
-if (cmd_range_match (str, command))
-return range_match;
-}
+ return ret;
+ }
+ else if (CMD_VARARG (str))
+ return vararg_match;
+ else if (CMD_RANGE (str))
+ {
+ if (cmd_range_match (str, command))
+ return range_match;
+ }
#ifdef HAVE_IPV6
-else if (CMD_IPV6 (str))
-{
-if (cmd_ipv6_match (command) >= min)
-return ipv6_match;
-}
-else if (CMD_IPV6_PREFIX (str))
-{
-if (cmd_ipv6_prefix_match (command) >= min)
-return ipv6_prefix_match;
-}
+ else if (CMD_IPV6 (str))
+ {
+ if (cmd_ipv6_match (command) >= min)
+ return ipv6_match;
+ }
+ else if (CMD_IPV6_PREFIX (str))
+ {
+ if (cmd_ipv6_prefix_match (command) >= min)
+ return ipv6_prefix_match;
+ }
#endif /* HAVE_IPV6 */
-else if (CMD_IPV4 (str))
-{
-if (cmd_ipv4_match (command) >= min)
-return ipv4_match;
-}
-else if (CMD_IPV4_PREFIX (str))
-{
-if (cmd_ipv4_prefix_match (command) >= min)
-return ipv4_prefix_match;
-}
-else if (CMD_VARIABLE (str))
-return extend_match;
-else if (strncmp (command, str, strlen (command)) == 0)
-{
-if (strcmp (command, str) == 0)
-return exact_match;
-else if (partly_match >= min)
-return partly_match;
-}
+ else if (CMD_IPV4 (str))
+ {
+ if (cmd_ipv4_match (command) >= min)
+ return ipv4_match;
+ }
+ else if (CMD_IPV4_PREFIX (str))
+ {
+ if (cmd_ipv4_prefix_match (command) >= min)
+ return ipv4_prefix_match;
+ }
+ else if (CMD_VARIABLE (str))
+ return extend_match;
+ else if (strncmp (command, str, strlen (command)) == 0)
+ {
+ if (strcmp (command, str) == 0)
+ return exact_match;
+ else if (partly_match >= min)
+ return partly_match;
+ }
-return no_match;
+ return no_match;
}
/* Filter vector at the specified index and by the given command string, to
-* the desired matching level (thus allowing part matches), and return match
-* type flag.
-*/
+ * the desired matching level (thus allowing part matches), and return match
+ * type flag.
+ */
static enum match_type
cmd_filter (char *command, vector v, unsigned int index, enum match_type level)
{
@@ -1266,23 +1266,23 @@ cmd_filter (char *command, vector v, unsigned int index, enum match_type level)
}
}
-if (match_type == no_match)
-return no_match;
-
-/* 2nd pass: We now know the 'strongest' match type for the index, so we
-* go again and filter out commands whose argument (at this index) is
-* 'weaker'. E.g., if we have 2 commands:
-*
-* foo bar <1-255>
-* foo bar BLAH
-*
-* and the command string is 'foo bar 10', then we will get here with with
-* 'range_match' being the strongest match. However, if 'BLAH' came
-* earlier, it won't have been filtered out (as a CMD_VARIABLE allows "10").
-*
-* If we don't do a 2nd pass and filter it out, the higher-layers will
-* consider this to be ambiguous.
-*/
+ if (match_type == no_match)
+ return no_match;
+
+ /* 2nd pass: We now know the 'strongest' match type for the index, so we
+ * go again and filter out commands whose argument (at this index) is
+ * 'weaker'. E.g., if we have 2 commands:
+ *
+ * foo bar <1-255>
+ * foo bar BLAH
+ *
+ * and the command string is 'foo bar 10', then we will get here with with
+ * 'range_match' being the strongest match. However, if 'BLAH' came
+ * earlier, it won't have been filtered out (as a CMD_VARIABLE allows "10").
+ *
+ * If we don't do a 2nd pass and filter it out, the higher-layers will
+ * consider this to be ambiguous.
+ */
for (i = 0; i < vector_active (v); i++)
if ((cmd_element = vector_slot (v, i)) != NULL)
{
@@ -1406,8 +1406,8 @@ is_cmd_ambiguous (char *command, vector v, int index, enum match_type type)
break;
}
-if (CMD_OPTION(desc->cmd))
-XFREE (MTYPE_TMP, str);
+ if (CMD_OPTION(desc->cmd))
+ XFREE (MTYPE_TMP, str);
}
if (!match)
vector_slot (v, i) = NULL;
@@ -1626,7 +1626,7 @@ cmd_describe_command_real (vector vline, struct vty *vty, int *status)
/* Make sure that cmd_vector is filtered based on current word */
command = vector_slot (vline, index);
if (command)
-match = cmd_filter (command, cmd_vector, index, any_match);
+ match = cmd_filter (command, cmd_vector, index, any_match);
/* Make description vector. */
for (i = 0; i < vector_active (cmd_vector); i++)
@@ -2264,13 +2264,15 @@ cmd_execute_command_strict (vector vline, struct vty *vty,
/* Configration make from file. */
int
-config_from_file (struct vty *vty, FILE *fp)
+config_from_file (struct vty *vty, FILE *fp, unsigned int *line_num)
{
int ret;
+ *line_num = 0;
vector vline;
while (fgets (vty->buf, VTY_BUFSIZ, fp))
{
+ ++(*line_num);
vline = cmd_make_strvec (vty->buf);
/* In case of comment line */
@@ -3021,7 +3023,8 @@ DEFUN (config_logmsg,
if ((level = level_match(argv[0])) == ZLOG_DISABLED)
return CMD_ERR_NO_MATCH;
- zlog(NULL, level, ((message = argv_concat(argv, argc, 1)) ? message : ""));
+ message = argv_concat(argv, argc, 1);
+ zlog(NULL, level, "%s", message ? message : "");
if (message)
XFREE(MTYPE_TMP, message);
return CMD_SUCCESS;
diff --git a/lib/command.h b/lib/command.h
index fe9c7cd1..a2f5eab8 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -343,7 +343,7 @@ extern void cmd_free_strvec (vector);
extern vector cmd_describe_command (vector, struct vty *, int *status);
extern char **cmd_complete_command (vector, struct vty *, int *status);
extern const char *cmd_prompt (enum node_type);
-extern int config_from_file (struct vty *, FILE *);
+extern int config_from_file (struct vty *, FILE *, unsigned int *line_num);
extern enum node_type node_parent (enum node_type);
extern int cmd_execute_command (vector, struct vty *, struct cmd_element **, int);
extern int cmd_execute_command_strict (vector, struct vty *, struct cmd_element **);
diff --git a/lib/if.c b/lib/if.c
index e3107116..d14cfb93 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -664,7 +664,7 @@ connected_log (struct connected *connected, char *str)
strncat (logbuf, inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
BUFSIZ - strlen(logbuf));
}
- zlog (NULL, LOG_INFO, logbuf);
+ zlog (NULL, LOG_INFO, "%s", logbuf);
}
/* If two connected address has same prefix return 1. */
diff --git a/lib/vty.c b/lib/vty.c
index cae22ae7..a76fe2d1 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -250,7 +250,7 @@ vty_hello (struct vty *vty)
vty_out (vty, "MOTD file not found%s", VTY_NEWLINE);
}
else if (host.motd)
- vty_out (vty, host.motd);
+ vty_out (vty, "%s", host.motd);
}
/* Put out prompt and wait input from user. */
@@ -1842,7 +1842,7 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port)
freeaddrinfo (ainfo_save);
}
-#endif /* HAVE_IPV6 && ! NRL */
+#else /* HAVE_IPV6 && ! NRL */
/* Make vty server socket. */
static void
@@ -1908,6 +1908,7 @@ vty_serv_sock_family (const char* addr, unsigned short port, int family)
/* Add vty server event. */
vty_event (VTY_SERV, accept_sock, NULL);
}
+#endif /* HAVE_IPV6 && ! NRL */
#ifdef VTYSH
/* For sockaddr_un. */
@@ -2232,28 +2233,37 @@ vty_read_file (FILE *confp)
{
int ret;
struct vty *vty;
+ unsigned int line_num = 15;
vty = vty_new ();
- vty->fd = 0; /* stdout */
- vty->type = VTY_TERM;
+ vty->fd = dup(STDERR_FILENO); /* vty_close() will close this */
+ if (vty->fd < 0)
+ {
+ /* Fine, we couldn't make a new fd. vty_close doesn't close stdout. */
+ vty->fd = STDOUT_FILENO;
+ }
+ vty->type = VTY_FILE;
vty->node = CONFIG_NODE;
/* Execute configuration file */
- ret = config_from_file (vty, confp);
+ ret = config_from_file (vty, confp, &line_num);
+
+ /* Flush any previous errors before printing messages below */
+ buffer_flush_all (vty->obuf, vty->fd);
if ( !((ret == CMD_SUCCESS) || (ret == CMD_ERR_NOTHING_TODO)) )
{
switch (ret)
{
case CMD_ERR_AMBIGUOUS:
- fprintf (stderr, "Ambiguous command.\n");
+ fprintf (stderr, "*** Error reading config: Ambiguous command.\n");
break;
case CMD_ERR_NO_MATCH:
- fprintf (stderr, "There is no such command.\n");
+ fprintf (stderr, "*** Error reading config: There is no such command.\n");
break;
}
- fprintf (stderr, "Error occured during reading below line.\n%s\n",
- vty->buf);
+ fprintf (stderr, "*** Error occured processing line %u, below:\n%s\n",
+ line_num, vty->buf);
vty_close (vty);
exit (1);
}
diff --git a/lib/zebra.h b/lib/zebra.h
index 83f04294..757a3757 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -533,43 +533,4 @@ typedef u_int8_t safi_t;
typedef u_int16_t zebra_size_t;
typedef u_int16_t zebra_command_t;
-/* FIFO -- first in first out structure and macros. */
-struct fifo
-{
- struct fifo *next;
- struct fifo *prev;
-};
-
-#define FIFO_INIT(F) \
- do { \
- struct fifo *Xfifo = (struct fifo *)(F); \
- Xfifo->next = Xfifo->prev = Xfifo; \
- } while (0)
-
-#define FIFO_ADD(F,N) \
- do { \
- struct fifo *Xfifo = (struct fifo *)(F); \
- struct fifo *Xnode = (struct fifo *)(N); \
- Xnode->next = Xfifo; \
- Xnode->prev = Xfifo->prev; \
- Xfifo->prev = Xfifo->prev->next = Xnode; \
- } while (0)
-
-#define FIFO_DEL(N) \
- do { \
- struct fifo *Xnode = (struct fifo *)(N); \
- Xnode->prev->next = Xnode->next; \
- Xnode->next->prev = Xnode->prev; \
- } while (0)
-
-#define FIFO_HEAD(F) \
- ((((struct fifo *)(F))->next == (struct fifo *)(F)) \
- ? NULL : (F)->next)
-
-#define FIFO_EMPTY(F) \
- (((struct fifo *)(F))->next == (struct fifo *)(F))
-
-#define FIFO_TOP(F) \
- (FIFO_EMPTY(F) ? NULL : ((struct fifo *)(F))->next)
-
#endif /* _ZEBRA_H */
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c
index 7e32195b..def55f10 100644
--- a/ospfd/ospf_abr.c
+++ b/ospfd/ospf_abr.c
@@ -614,15 +614,6 @@ set_metric (struct ospf_lsa *lsa, u_int32_t metric)
memcpy(header->metric, mp, 3);
}
-static int
-ospf_abr_check_nssa_range (struct prefix_ipv4 *p, u_int32_t cost,
- struct ospf_area *area)
-{
- /* The Type-7 is tested against the aggregated prefix and forwarded
- for lsa installation and flooding */
- return 0;
-}
-
/* ospf_abr_translate_nssa */
static int
ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa)
@@ -1578,42 +1569,6 @@ ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */
}
static void
-ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */
-{
- struct listnode *node;
- struct ospf_area *area;
-
- if (! IS_OSPF_ABR (ospf))
- return;
-
- if (IS_DEBUG_OSPF_NSSA)
- zlog_debug ("ospf_abr_announce_stub_defaults(): Start");
-
- for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
- {
- if (IS_DEBUG_OSPF_NSSA)
- zlog_debug ("ospf_abr_announce_nssa_defaults(): looking at area %s",
- inet_ntoa (area->area_id));
-
- if (area->external_routing != OSPF_AREA_NSSA)
- continue;
-
- if (OSPF_IS_AREA_BACKBONE (area))
- continue; /* Sanity Check */
-
- /* if (!TranslatorRole continue V 1.0 look for "always" conf */
- if (area->NSSATranslatorState)
- {
- if (IS_DEBUG_OSPF_NSSA)
- zlog_debug ("ospf_abr_announce_nssa_defaults(): "
- "announcing 0.0.0.0/0 to this nssa");
- /* ospf_abr_announce_nssa_asbr_to_as (&p, area->default_cost, area); */
- /*ospf_abr_announce_network_to_area (&p, area->default_cost, area);*/
- }
- }
-}
-
-static void
ospf_abr_announce_stub_defaults (struct ospf *ospf)
{
struct listnode *node;
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c
index 2a81e97a..10608f50 100644
--- a/ospfd/ospf_route.c
+++ b/ospfd/ospf_route.c
@@ -272,61 +272,6 @@ ospf_route_install (struct ospf *ospf, struct route_table *rt)
}
}
-static void
-ospf_intra_route_add (struct route_table *rt, struct vertex *v,
- struct ospf_area *area)
-{
- struct route_node *rn;
- struct ospf_route *or;
- struct prefix_ipv4 p;
- struct ospf_path *path;
- struct vertex_parent *parent;
- struct listnode *node, *nnode;
-
- p.family = AF_INET;
- p.prefix = v->id;
- if (v->type == OSPF_VERTEX_ROUTER)
- p.prefixlen = IPV4_MAX_BITLEN;
- else
- {
- struct network_lsa *lsa = (struct network_lsa *) v->lsa;
- p.prefixlen = ip_masklen (lsa->mask);
- }
- apply_mask_ipv4 (&p);
-
- rn = route_node_get (rt, (struct prefix *) &p);
- if (rn->info)
- {
- zlog_warn ("Same routing information exists for %s", inet_ntoa (v->id));
- route_unlock_node (rn);
- return;
- }
-
- or = ospf_route_new ();
-
- if (v->type == OSPF_VERTEX_NETWORK)
- {
- or->type = OSPF_DESTINATION_NETWORK;
-
- for (ALL_LIST_ELEMENTS (v->parents, node, nnode, parent))
- {
- path = ospf_path_new ();
- path->nexthop = parent->nexthop->router;
- listnode_add (or->paths, path);
- }
- }
- else
- or->type = OSPF_DESTINATION_ROUTER;
-
- or->id = v->id;
- or->u.std.area_id = area->area_id;
- or->u.std.external_routing= area->external_routing;
- or->path_type = OSPF_PATH_INTRA_AREA;
- or->cost = v->distance;
-
- rn->info = or;
-}
-
/* RFC2328 16.1. (4). For "router". */
void
ospf_intra_add_router (struct route_table *rt, struct vertex *v,
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index fb863681..89289f60 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -1035,6 +1035,7 @@ ospf_rtrs_free (struct route_table *rtrs)
route_table_finish (rtrs);
}
+#if 0
static void
ospf_rtrs_print (struct route_table *rtrs)
{
@@ -1094,6 +1095,7 @@ ospf_rtrs_print (struct route_table *rtrs)
zlog_debug ("ospf_rtrs_print() end");
}
+#endif
/* Calculating the shortest-path tree for an area. */
static void
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 236c10b1..01e85c71 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -3731,7 +3731,7 @@ show_as_external_lsa_detail (struct vty *vty, struct ospf_lsa *lsa)
return 0;
}
-/* N.B. This function currently seems to be unused. */
+#if 0
static int
show_as_external_lsa_stdvty (struct ospf_lsa *lsa)
{
@@ -3755,6 +3755,7 @@ show_as_external_lsa_stdvty (struct ospf_lsa *lsa)
return 0;
}
+#endif
/* Show AS-NSSA-LSA detail information. */
static int
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index ed35cc80..bcc8905f 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -133,8 +133,9 @@ ospf_interface_delete (int command, struct zclient *zclient,
if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
zlog_debug
- ("Zebra: interface delete %s index %d flags %lld metric %d mtu %d",
- ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
+ ("Zebra: interface delete %s index %d flags %#llx metric %d mtu %d",
+ ifp->name, ifp->ifindex, (unsigned long long) ifp->flags,
+ ifp->metric, ifp->mtu);
#ifdef HAVE_SNMP
ospf_snmp_if_delete (ifp);
@@ -975,7 +976,7 @@ ospf_distribute_list_update_timer (struct thread *thread)
/* Update distribute-list and set timer to apply access-list. */
void
-ospf_distribute_list_update (struct ospf *ospf, int type)
+ospf_distribute_list_update (struct ospf *ospf, unsigned long type)
{
struct route_table *rt;
diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h
index 3efd8958..b6419c8b 100644
--- a/ospfd/ospf_zebra.h
+++ b/ospfd/ospf_zebra.h
@@ -56,7 +56,7 @@ extern int ospf_redistribute_check (struct ospf *, struct external_info *,
int *);
extern int ospf_distribute_check_connected (struct ospf *,
struct external_info *);
-extern void ospf_distribute_list_update (struct ospf *, int);
+extern void ospf_distribute_list_update (struct ospf *, unsigned long);
extern int ospf_is_type_redistributed (int);
extern void ospf_distance_reset (struct ospf *);
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index 93611da9..35c6b02b 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -1358,6 +1358,7 @@ ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
return 1;
}
+#if 0
/* XXX: unused? Leave for symmetry? */
static int
ospf_area_nssa_translator_role_unset (struct ospf *ospf,
@@ -1375,6 +1376,7 @@ ospf_area_nssa_translator_role_unset (struct ospf *ospf,
return 1;
}
+#endif
int
ospf_area_export_list_set (struct ospf *ospf,
diff --git a/zebra/rib.h b/zebra/rib.h
index 887ed3c2..499d48b2 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -262,6 +262,7 @@ extern struct rib *rib_match_ipv4 (struct in_addr);
extern struct rib *rib_lookup_ipv4 (struct prefix_ipv4 *);
extern void rib_update (void);
+extern void rib_update_background (void);
extern void rib_weed_tables (void);
extern void rib_sweep_route (void);
extern void rib_close (void);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 29a8e40b..6ac43d8c 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1424,7 +1424,6 @@ rib_queue_init (struct zebra_t *zebra)
zebra->ribq->spec.errorfunc = NULL;
/* XXX: TODO: These should be runtime configurable via vty */
zebra->ribq->spec.max_retries = 3;
- zebra->ribq->spec.hold = rib_process_hold_time;
if (!(zebra->mq = meta_queue_new ()))
zlog_err ("%s: could not initialise meta queue!", __func__);
@@ -2886,23 +2885,45 @@ static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
#endif /* HAVE_IPV6 */
/* RIB update function. */
-void
-rib_update (void)
+static void
+rib_update_table (struct table *table)
{
struct route_node *rn;
- struct route_table *table;
-
- table = vrf_table (AFI_IP, SAFI_UNICAST, 0);
if (table)
for (rn = route_top (table); rn; rn = route_next (rn))
if (rn->info)
rib_queue_add (&zebrad, rn);
+}
- table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);
- if (table)
- for (rn = route_top (table); rn; rn = route_next (rn))
- if (rn->info)
- rib_queue_add (&zebrad, rn);
+void
+rib_update (void)
+{
+ if (zebrad.update)
+ {
+ thread_cancel (zebrad.update);
+ zebrad.update = NULL;
+ }
+
+ rib_update_table (vrf_table (AFI_IP, SAFI_UNICAST, 0));
+
+#ifdef HAVE_IPV6
+ rib_update_table (vrf_table (AFI_IP6, SAFI_UNICAST, 0));
+#endif
+}
+
+static int
+rib_update_thread (struct thread *self)
+{
+ rib_update ();
+ return 0;
+}
+
+void
+rib_update_background (void)
+{
+ if (!zebrad.update)
+ zebrad.update = thread_add_background (zebrad.master, rib_update_thread,
+ NULL, rib_process_hold_time);
}
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 21f24627..ced8fa5a 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -877,6 +877,8 @@ zread_ipv4_add (struct zserv *client, u_short length)
/* Table */
rib->table=zebrad.rtm_table_default;
rib_add_ipv4_multipath (&p, rib);
+
+ rib_update_background ();
return 0;
}
@@ -951,6 +953,8 @@ zread_ipv4_delete (struct zserv *client, u_short length)
rib_delete_ipv4 (api.type, api.flags, &p, &nexthop, ifindex,
client->rtm_table);
+
+ rib_update_background ();
return 0;
}
@@ -1052,6 +1056,8 @@ zread_ipv6_add (struct zserv *client, u_short length)
else
rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, zebrad.rtm_table_default, api.metric,
api.distance);
+
+ rib_update_background ();
return 0;
}
@@ -1116,6 +1122,8 @@ zread_ipv6_delete (struct zserv *client, u_short length)
rib_delete_ipv6 (api.type, api.flags, &p, NULL, ifindex, client->rtm_table);
else
rib_delete_ipv6 (api.type, api.flags, &p, &nexthop, ifindex, client->rtm_table);
+
+ rib_update_background ();
return 0;
}
diff --git a/zebra/zserv.h b/zebra/zserv.h
index cccd9be0..340e7f5d 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -83,6 +83,9 @@ struct zebra_t
/* rib work queue */
struct work_queue *ribq;
struct meta_queue *mq;
+
+ /* rib update thread */
+ struct thread *update;
};
/* Count prefix size from mask length */