diff options
-rw-r--r-- | bgpd/bgp_advertise.c | 4 | ||||
-rw-r--r-- | bgpd/bgp_advertise.h | 32 | ||||
-rw-r--r-- | lib/command.c | 185 | ||||
-rw-r--r-- | lib/command.h | 2 | ||||
-rw-r--r-- | lib/if.c | 2 | ||||
-rw-r--r-- | lib/vty.c | 28 | ||||
-rw-r--r-- | lib/zebra.h | 39 | ||||
-rw-r--r-- | ospfd/ospf_abr.c | 45 | ||||
-rw-r--r-- | ospfd/ospf_route.c | 55 | ||||
-rw-r--r-- | ospfd/ospf_spf.c | 2 | ||||
-rw-r--r-- | ospfd/ospf_vty.c | 3 | ||||
-rw-r--r-- | ospfd/ospf_zebra.c | 7 | ||||
-rw-r--r-- | ospfd/ospf_zebra.h | 2 | ||||
-rw-r--r-- | ospfd/ospfd.c | 2 | ||||
-rw-r--r-- | zebra/rib.h | 1 | ||||
-rw-r--r-- | zebra/zebra_rib.c | 43 | ||||
-rw-r--r-- | zebra/zserv.c | 8 | ||||
-rw-r--r-- | zebra/zserv.h | 3 |
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 **); @@ -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. */ @@ -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 */ |