]> git.proxmox.com Git - mirror_frr.git/commitdiff
ospf6d: Fix redist w/ route-map during restart
authorChirag Shah <chirag@cumulusnetworks.com>
Thu, 25 Jan 2018 03:02:19 +0000 (19:02 -0800)
committerChirag Shah <chirag@cumulusnetworks.com>
Fri, 26 Jan 2018 17:53:37 +0000 (09:53 -0800)
Add hook for route-map update event.
Add a delay one shot timer to accomodate route-map
update and reset redist with zebra to process
all redistribute routes with route-map info.

Cleanup route-map, prefix cached date during ospf6 exit.

Ticket:CM-13800
Testing Done:
configure redistribute connected with route-map to define
type-2 routes. Restart frr.service and validated
route-map add,update event, thread is scheduled,
once timer is done redist reset with zebra.
Upon redist add notification, all route map info is cached
in ospf6 and processed as type-2 route and send ASE E2 LSA.

Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
ospf6d/ospf6_asbr.c
ospf6d/ospf6_asbr.h
ospf6d/ospf6_main.c
ospf6d/ospf6_memory.c
ospf6d/ospf6_memory.h
ospf6d/ospf6_top.c
ospf6d/ospf6_top.h

index 745b87b890ed13f527557a19b37dd31a99e09f7d..02f8eb0b09ca6f2cd1b7e7accab7fb4d4fe1b497 100644 (file)
@@ -618,6 +618,56 @@ static void ospf6_asbr_routemap_unset(int type)
        ospf6->rmap[type].map = NULL;
 }
 
+static int ospf6_asbr_routemap_update_timer(struct thread *thread)
+{
+       void **arg;
+       int arg_type;
+
+       arg = THREAD_ARG(thread);
+       arg_type = (int)(intptr_t)arg[1];
+
+       ospf6->t_distribute_update = NULL;
+
+       if (ospf6->rmap[arg_type].name)
+               ospf6->rmap[arg_type].map = route_map_lookup_by_name(
+                                       ospf6->rmap[arg_type].name);
+       if (ospf6->rmap[arg_type].map) {
+               if (IS_OSPF6_DEBUG_ASBR)
+                       zlog_debug("%s: route-map %s update, reset redist %s",
+                                  __PRETTY_FUNCTION__,
+                                  ospf6->rmap[arg_type].name,
+                                  ZROUTE_NAME(arg_type));
+
+               ospf6_zebra_no_redistribute(arg_type);
+               ospf6_zebra_redistribute(arg_type);
+       }
+
+       XFREE(MTYPE_OSPF6_DIST_ARGS, arg);
+       return 0;
+}
+
+void ospf6_asbr_distribute_list_update(int type)
+{
+       void **args = NULL;
+
+       if (ospf6->t_distribute_update)
+               return;
+
+       args = XCALLOC(MTYPE_OSPF6_DIST_ARGS, sizeof(void *)*2);
+
+       args[0] = ospf6;
+       args[1] = (void *)((ptrdiff_t)type);
+
+       if (IS_OSPF6_DEBUG_ASBR)
+               zlog_debug("%s: trigger redistribute %s reset thread",
+                          __PRETTY_FUNCTION__, ZROUTE_NAME(type));
+
+       ospf6->t_distribute_update = NULL;
+       thread_add_timer_msec(master, ospf6_asbr_routemap_update_timer,
+                             (void **)args, OSPF_MIN_LS_INTERVAL,
+                             &ospf6->t_distribute_update);
+}
+
 static void ospf6_asbr_routemap_update(const char *mapname)
 {
        int type;
@@ -636,15 +686,27 @@ static void ospf6_asbr_routemap_update(const char *mapname)
                                        zlog_debug("%s: route-map %s update, reset redist %s",
                                                   __PRETTY_FUNCTION__, mapname,
                                                   ZROUTE_NAME(type));
-
-                               ospf6_zebra_no_redistribute(type);
-                               ospf6_zebra_redistribute(type);
+                               ospf6_asbr_distribute_list_update(type);
                        }
                } else
                        ospf6->rmap[type].map = NULL;
        }
 }
 
+static void ospf6_asbr_routemap_event(route_map_event_t event, const char *name)
+{
+       int type;
+
+       if (ospf6 == NULL)
+               return;
+       for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
+               if ((ospf6->rmap[type].name) &&
+                   (strcmp(ospf6->rmap[type].name, name) == 0)) {
+                       ospf6_asbr_distribute_list_update(type);
+               }
+       }
+}
+
 int ospf6_asbr_is_asbr(struct ospf6 *o)
 {
        return o->external_table->count;
@@ -745,7 +807,6 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
        match = ospf6_route_lookup(prefix, ospf6->external_table);
        if (match) {
                info = match->route_option;
-
                /* copy result of route-map */
                if (ospf6->rmap[type].map) {
                        if (troute.path.metric_type)
@@ -779,7 +840,9 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
                if (IS_OSPF6_DEBUG_ASBR) {
                        inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf,
                                  sizeof(ibuf));
-                       zlog_debug("Advertise as AS-External Id:%s", ibuf);
+                       prefix2str(prefix, pbuf, sizeof(pbuf));
+                       zlog_debug("Advertise as AS-External Id:%s prefix %s metric %u",
+                                  ibuf, pbuf, match->path.metric_type);
                }
 
                match->path.origin.id = htonl(info->id);
@@ -830,7 +893,9 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
 
        if (IS_OSPF6_DEBUG_ASBR) {
                inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, sizeof(ibuf));
-               zlog_debug("Advertise as AS-External Id:%s", ibuf);
+               prefix2str(prefix, pbuf, sizeof(pbuf));
+               zlog_debug("Advertise as AS-External Id:%s prefix %s metric %u",
+                          ibuf, pbuf, route->path.metric_type);
        }
 
        route->path.origin.id = htonl(info->id);
@@ -1339,6 +1404,7 @@ static void ospf6_routemap_init(void)
 
        route_map_add_hook(ospf6_asbr_routemap_update);
        route_map_delete_hook(ospf6_asbr_routemap_update);
+       route_map_event_hook(ospf6_asbr_routemap_event);
 
        route_map_set_metric_hook(generic_set_add);
        route_map_no_set_metric_hook(generic_set_delete);
@@ -1538,6 +1604,10 @@ void ospf6_asbr_redistribute_reset(void)
 
 void ospf6_asbr_terminate(void)
 {
+       /* Cleanup route maps */
+       route_map_add_hook(NULL);
+       route_map_delete_hook(NULL);
+       route_map_event_hook(NULL);
        route_map_finish();
 }
 
index 7f4665ac2b501645831f610dbbdd2bbb1efba7d2..cc4f0272aabbfc4d33c6710cb1253df341760af3 100644 (file)
@@ -95,5 +95,6 @@ extern int config_write_ospf6_debug_asbr(struct vty *vty);
 extern void install_element_ospf6_debug_asbr(void);
 extern void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
                                              struct ospf6_route *route);
+extern void ospf6_asbr_distribute_list_update(int type);
 
 #endif /* OSPF6_ASBR_H */
index 9a6729ee2a6aee8f820c43b95f92fa428234511a..88f03d8f646ec1d0d49b0bdc07e8cd3815e1f280 100644 (file)
@@ -97,6 +97,14 @@ static void __attribute__((noreturn)) ospf6_exit(int status)
        ospf6_asbr_terminate();
        ospf6_lsa_terminate();
 
+       /* reverse access_list_init */
+       access_list_reset();
+
+       /* reverse prefix_list_init */
+       prefix_list_add_hook(NULL);
+       prefix_list_delete_hook(NULL);
+       prefix_list_reset();
+
        vrf_terminate();
 
        if (zclient) {
index 1c3523b43d327fa76a4a21d0cded83a6b13967bd..c008b54ce7b765a3502f6b0da358f6fdfaa93df9 100644 (file)
@@ -42,4 +42,5 @@ DEFINE_MTYPE(OSPF6D, OSPF6_SPFTREE, "OSPF6 SPF tree")
 DEFINE_MTYPE(OSPF6D, OSPF6_NEXTHOP, "OSPF6 nexthop")
 DEFINE_MTYPE(OSPF6D, OSPF6_EXTERNAL_INFO, "OSPF6 ext. info")
 DEFINE_MTYPE(OSPF6D, OSPF6_PATH, "OSPF6 Path")
+DEFINE_MTYPE(OSPF6D, OSPF6_DIST_ARGS, "OSPF6 Distribute arguments")
 DEFINE_MTYPE(OSPF6D, OSPF6_OTHER, "OSPF6 other")
index 548af5e321e7767ae7c60187b0ff977454cf9a8e..a97d677543f3a189492e6e4b79d94ce89805410a 100644 (file)
@@ -41,6 +41,7 @@ DECLARE_MTYPE(OSPF6_SPFTREE)
 DECLARE_MTYPE(OSPF6_NEXTHOP)
 DECLARE_MTYPE(OSPF6_EXTERNAL_INFO)
 DECLARE_MTYPE(OSPF6_PATH)
+DECLARE_MTYPE(OSPF6_DIST_ARGS)
 DECLARE_MTYPE(OSPF6_OTHER)
 
 #endif /* _QUAGGA_OSPF6_MEMORY_H */
index 5d1144335be4c27b55d1f6a4bdf96f0017e59167..749873bcf8c753dae2232b3d2125e0b97df36b3c 100644 (file)
@@ -224,6 +224,7 @@ static void ospf6_disable(struct ospf6 *o)
                THREAD_OFF(o->maxage_remover);
                THREAD_OFF(o->t_spf_calc);
                THREAD_OFF(o->t_ase_calc);
+               THREAD_OFF(o->t_distribute_update);
        }
 }
 
index d8d34d0f3c7ff993a528511818e9e3f987fd8f7c..b39c25ba84c46472f9d4ba5dbd1e446a3f6bb830 100644 (file)
@@ -82,6 +82,7 @@ struct ospf6 {
        struct thread *t_spf_calc; /* SPF calculation timer. */
        struct thread *t_ase_calc; /* ASE calculation timer. */
        struct thread *maxage_remover;
+       struct thread *t_distribute_update; /* Distirbute update timer. */
 
        u_int32_t ref_bandwidth;