summaryrefslogtreecommitdiff
path: root/zebra
diff options
context:
space:
mode:
authorkssoman <somanks@vmware.com>2018-08-17 08:47:48 -0700
committerkssoman <somanks@vmware.com>2018-08-17 08:47:48 -0700
commitd5b8c21628320ca1d55e9cb687f2a9d941133068 (patch)
treea9c8f5c915e51e3ad36cb46a867d4520a8a02b10 /zebra
parent067d5028c1b82cab172f2d951d7f8c7598ad0f1c (diff)
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 <somanks@vmware.com>
Diffstat (limited to 'zebra')
-rw-r--r--zebra/redistribute.c7
-rw-r--r--zebra/redistribute.h3
-rw-r--r--zebra/rib.h2
-rw-r--r--zebra/zebra_rib.c13
-rw-r--r--zebra/zebra_routemap.c95
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 <sigh>
* 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);
}