From d5b8c21628320ca1d55e9cb687f2a9d941133068 Mon Sep 17 00:00:00 2001 From: kssoman Date: Fri, 17 Aug 2018 08:47:48 -0700 Subject: [PATCH] zebra : Zebra does not properly track which route-maps are changed (#2493) * Check for the modified routemap in zebra_route_map_process_update_cb() * Added zebra_rib_table_rm_update() for RIB routemap processing * Added zebra_nht_rm_update() for NHT routemap processing Signed-off-by: kssoman --- zebra/redistribute.c | 7 ++-- zebra/redistribute.h | 3 +- zebra/rib.h | 2 + zebra/zebra_rib.c | 13 ++++-- zebra/zebra_routemap.c | 95 +++++++++++++++++++++++++++++++++++++++--- 5 files changed, 105 insertions(+), 15 deletions(-) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index e3101fbe72..640d58e17e 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -715,7 +715,7 @@ int zebra_import_table_config(struct vty *vty) return write; } -void zebra_import_table_rm_update() +void zebra_import_table_rm_update(const char *rmap) { afi_t afi; int i; @@ -730,9 +730,8 @@ void zebra_import_table_rm_update() continue; rmap_name = zebra_get_import_table_route_map(afi, i); - if (!rmap_name) - return; - + if ((!rmap_name) || (strcmp(rmap_name, rmap) != 0)) + continue; table = zebra_vrf_other_route_table(afi, i, VRF_DEFAULT); for (rn = route_top(table); rn; rn = route_next(rn)) { diff --git a/zebra/redistribute.h b/zebra/redistribute.h index a0fbd13cf9..f67480da9c 100644 --- a/zebra/redistribute.h +++ b/zebra/redistribute.h @@ -71,6 +71,5 @@ extern int is_zebra_import_table_enabled(afi_t, uint32_t table_id); extern int zebra_import_table_config(struct vty *); -extern void zebra_import_table_rm_update(void); - +extern void zebra_import_table_rm_update(const char *rmap); #endif /* _ZEBRA_REDISTRIBUTE_H */ diff --git a/zebra/rib.h b/zebra/rib.h index a37b2bf221..f821c6edb4 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -325,6 +325,8 @@ extern struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id); extern void rib_update(vrf_id_t vrf_id, rib_update_event_t event); +extern void rib_update_table(struct route_table *table, + rib_update_event_t event); extern void rib_sweep_route(void); extern void rib_sweep_table(struct route_table *table); extern void rib_close_table(struct route_table *table); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 69f6ff9de7..46042b793a 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2637,8 +2637,7 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, } /* Schedule routes of a particular table (address-family) based on event. */ -static void rib_update_table(struct route_table *table, - rib_update_event_t event) +void rib_update_table(struct route_table *table, rib_update_event_t event) { struct route_node *rn; struct route_entry *re, *next; @@ -2718,12 +2717,18 @@ void rib_update(vrf_id_t vrf_id, rib_update_event_t event) /* Process routes of interested address-families. */ table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); - if (table) + if (table) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("%s : AFI_IP event %d", __func__, event); rib_update_table(table, event); + } table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id); - if (table) + if (table) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("%s : AFI_IP6 event %d", __func__, event); rib_update_table(table, event); + } } /* Delete self installed routes after zebra is relaunched. */ diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index fc17ee3491..2ee4b40465 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -1281,11 +1281,101 @@ static struct route_map_rule_cmd route_set_src_cmd = { "src", route_set_src, route_set_src_compile, route_set_src_free, }; +/* The function checks if the changed routemap specified by parameter rmap + * matches the configured protocol routemaps in proto_rm table. If there is + * a match then rib_update_table() to process the routes. + */ +static void zebra_rib_table_rm_update(const char *rmap) +{ + int i = 0; + struct route_table *table; + char *rmap_name; + char afi_ip = 0; + char afi_ipv6 = 0; + + for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) { + /* Check for ip routemap table */ + rmap_name = proto_rm[AFI_IP][i]; + if (rmap_name && (strcmp(rmap_name, rmap) == 0)) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("%s : AFI_IP rmap %s, route type %s", + __func__, rmap, zebra_route_string(i)); + /* There is single rib table for all protocols */ + if (afi_ip == 0) { + table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, + VRF_DEFAULT); + if (table) { + afi_ip = 1; + rib_update_table(table, + RIB_UPDATE_RMAP_CHANGE); + } + } + } + + /* Check for ipv6 routemap table */ + rmap_name = proto_rm[AFI_IP6][i]; + if (rmap_name && (strcmp(rmap_name, rmap) == 0)) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("%s : AFI_IP6 rmap %s,route type %s", + __func__, rmap, zebra_route_string(i)); + if (afi_ipv6 == 0) { + table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, + VRF_DEFAULT); + if (table) { + afi_ipv6 = 1; + rib_update_table(table, + RIB_UPDATE_RMAP_CHANGE); + } + } + } + } +} + +/* The function checks if the changed routemap specified by parameter rmap + * matches the configured protocol routemaps in nht_rm table. If there is + * a match then zebra_evaluate_rnh() to process the nexthops. + */ +static void zebra_nht_rm_update(const char *rmap) +{ + int i = 0; + char *rmap_name; + char afi_ip = 0; + char afi_ipv6 = 0; + + for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) { + rmap_name = nht_rm[AFI_IP][i]; + if (rmap_name && (strcmp(rmap_name, rmap) == 0)) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("%s : AFI_IP rmap %s route type %s", + __func__, rmap, zebra_route_string(i)); + if (afi_ip == 0) { + afi_ip = 1; + zebra_evaluate_rnh(0, AF_INET, 1, + RNH_NEXTHOP_TYPE, NULL); + } + } + rmap_name = nht_rm[AFI_IP6][i]; + if (rmap_name && (strcmp(rmap_name, rmap) == 0)) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug("%s : AFI_IP6 rmap %s route type %s", + __func__, rmap, zebra_route_string(i)); + if (afi_ipv6 == 0) { + afi_ipv6 = 1; + zebra_evaluate_rnh(0, AF_INET6, 1, + RNH_NEXTHOP_TYPE, NULL); + } + } + } +} + static void zebra_route_map_process_update_cb(char *rmap_name) { if (IS_ZEBRA_DEBUG_EVENT) zlog_debug("Event handler for route-map: %s", rmap_name); + zebra_import_table_rm_update(rmap_name); + zebra_rib_table_rm_update(rmap_name); + zebra_nht_rm_update(rmap_name); } static int zebra_route_map_update_timer(struct thread *thread) @@ -1307,11 +1397,6 @@ static int zebra_route_map_update_timer(struct thread *thread) * 1) VRF Aware * 2) Route-map aware */ - zebra_import_table_rm_update(); - rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE); - zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); - zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); - return (0); } -- 2.39.5