From 08965422d08f51ce9fe3a4490da5732c98b54a6a Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 4 Jun 2021 14:22:06 +0200 Subject: [PATCH 1/4] ospf6d: don't update router-id if at least one adjacency is Full When a router-id change is notified by zebra to ospf6d, we only take into account the change if no adjacencies are in Full state. Signed-off-by: Louis Scalbert --- ospf6d/ospf6_top.c | 31 +++++++++++++++++++++++++------ ospf6d/ospf6_top.h | 2 +- ospf6d/ospf6_zebra.c | 2 +- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 6f40989efd..e098490285 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -225,7 +225,7 @@ static int ospf6_vrf_enable(struct vrf *vrf) thread_add_read(master, ospf6_receive, ospf6, ospf6->fd, &ospf6->t_ospf6_receive); - ospf6_router_id_update(ospf6); + ospf6_router_id_update(ospf6, true); } } @@ -440,7 +440,7 @@ struct ospf6 *ospf6_instance_create(const char *name) if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES) SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); if (ospf6->router_id == 0) - ospf6_router_id_update(ospf6); + ospf6_router_id_update(ospf6, true); ospf6_add(ospf6); if (ospf6->vrf_id != VRF_UNKNOWN) { vrf = vrf_lookup_by_id(ospf6->vrf_id); @@ -594,15 +594,34 @@ void ospf6_maxage_remove(struct ospf6 *o) &o->maxage_remover); } -void ospf6_router_id_update(struct ospf6 *ospf6) +void ospf6_router_id_update(struct ospf6 *ospf6, bool init) { + in_addr_t new_router_id; + struct listnode *node; + struct ospf6_area *oa; + if (!ospf6) return; if (ospf6->router_id_static != 0) - ospf6->router_id = ospf6->router_id_static; + new_router_id = ospf6->router_id_static; else - ospf6->router_id = ospf6->router_id_zebra; + new_router_id = ospf6->zebra_router_id; + + if (ospf6->router_id == new_router_id) + return; + + if (!init) + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { + if (oa->full_nbrs) { + zlog_err( + "%s: cannot update router-id. Save config and restart ospf6d\n", + __func__); + return; + } + } + + ospf6->router_id = new_router_id; } /* start ospf6 */ @@ -694,7 +713,7 @@ static void ospf6_process_reset(struct ospf6 *ospf6) ospf6->inst_shutdown = 0; ospf6_db_clear(ospf6); - ospf6_router_id_update(ospf6); + ospf6_router_id_update(ospf6, true); ospf6_asbr_redistribute_reset(ospf6); FOR_ALL_INTERFACES (vrf, ifp) diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index f0251bcb62..aba5d64536 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -175,7 +175,7 @@ extern void ospf6_master_init(struct thread_master *master); extern void install_element_ospf6_clear_process(void); extern void ospf6_top_init(void); extern void ospf6_delete(struct ospf6 *o); -extern void ospf6_router_id_update(struct ospf6 *ospf6); +extern void ospf6_router_id_update(struct ospf6 *ospf6, bool init); extern void ospf6_maxage_remove(struct ospf6 *o); extern struct ospf6 *ospf6_instance_create(const char *name); diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index a7e15c68ae..1c9541710e 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -101,7 +101,7 @@ static int ospf6_router_id_update_zebra(ZAPI_CALLBACK_ARGS) o->router_id_zebra = router_id.u.prefix4.s_addr; - ospf6_router_id_update(o); + ospf6_router_id_update(o, false); return 0; } From 6794884231cc9a83b936323009370c3e1deff643 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Wed, 30 Jun 2021 15:18:50 +0200 Subject: [PATCH 2/4] ospf6d: factorize router-id update ospf6_router_id_update function is used by ospf6_router_id_update_zebra to update the running the ospf6 router-id. This patches makes the functions to (un)configure ospf6 router-id use the same function as ospf6_router_id_update_zebra. Signed-off-by: Louis Scalbert --- --- ospf6d/ospf6_top.c | 47 +++++++++++++++----------------------------- ospf6d/ospf6_top.h | 3 ++- ospf6d/ospf6_zebra.c | 2 +- 3 files changed, 19 insertions(+), 33 deletions(-) diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index e098490285..f18eea2129 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -225,7 +225,7 @@ static int ospf6_vrf_enable(struct vrf *vrf) thread_add_read(master, ospf6_receive, ospf6, ospf6->fd, &ospf6->t_ospf6_receive); - ospf6_router_id_update(ospf6, true); + ospf6_router_id_update(ospf6, true, NULL); } } @@ -440,7 +440,7 @@ struct ospf6 *ospf6_instance_create(const char *name) if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES) SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); if (ospf6->router_id == 0) - ospf6_router_id_update(ospf6, true); + ospf6_router_id_update(ospf6, true, NULL); ospf6_add(ospf6); if (ospf6->vrf_id != VRF_UNKNOWN) { vrf = vrf_lookup_by_id(ospf6->vrf_id); @@ -594,7 +594,7 @@ void ospf6_maxage_remove(struct ospf6 *o) &o->maxage_remover); } -void ospf6_router_id_update(struct ospf6 *ospf6, bool init) +void ospf6_router_id_update(struct ospf6 *ospf6, bool init, struct vty *vty) { in_addr_t new_router_id; struct listnode *node; @@ -606,7 +606,7 @@ void ospf6_router_id_update(struct ospf6 *ospf6, bool init) if (ospf6->router_id_static != 0) new_router_id = ospf6->router_id_static; else - new_router_id = ospf6->zebra_router_id; + new_router_id = ospf6->router_id_zebra; if (ospf6->router_id == new_router_id) return; @@ -614,9 +614,15 @@ void ospf6_router_id_update(struct ospf6 *ospf6, bool init) if (!init) for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { if (oa->full_nbrs) { - zlog_err( - "%s: cannot update router-id. Save config and restart ospf6d\n", - __func__); + if (vty) + vty_out(vty, + "For this router-id change to take effect," + " run the \"clear ipv6 ospf6 process\" command\n"); + else + zlog_err( + "%s: cannot update router-id." + " Run the \"clear ipv6 ospf6 process\" command\n", + __func__); return; } } @@ -713,7 +719,7 @@ static void ospf6_process_reset(struct ospf6 *ospf6) ospf6->inst_shutdown = 0; ospf6_db_clear(ospf6); - ospf6_router_id_update(ospf6, true); + ospf6_router_id_update(ospf6, true, NULL); ospf6_asbr_redistribute_reset(ospf6); FOR_ALL_INTERFACES (vrf, ifp) @@ -757,8 +763,6 @@ DEFUN(ospf6_router_id, int ret; const char *router_id_str; uint32_t router_id; - struct ospf6_area *oa; - struct listnode *node; argv_find(argv, argc, "A.B.C.D", &idx); router_id_str = argv[idx]->arg; @@ -771,15 +775,7 @@ DEFUN(ospf6_router_id, o->router_id_static = router_id; - for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) { - if (oa->full_nbrs) { - vty_out(vty, - "For this router-id change to take effect, run the \"clear ipv6 ospf6 process\" command\n"); - return CMD_SUCCESS; - } - } - - o->router_id = router_id; + ospf6_router_id_update(o, false, vty); return CMD_SUCCESS; } @@ -792,21 +788,10 @@ DEFUN(no_ospf6_router_id, V4NOTATION_STR) { VTY_DECLVAR_CONTEXT(ospf6, o); - struct ospf6_area *oa; - struct listnode *node; o->router_id_static = 0; - for (ALL_LIST_ELEMENTS_RO(o->area_list, node, oa)) { - if (oa->full_nbrs) { - vty_out(vty, - "For this router-id change to take effect, run the \"clear ipv6 ospf6 process\" command\n"); - return CMD_SUCCESS; - } - } - o->router_id = 0; - if (o->router_id_zebra) - o->router_id = o->router_id_zebra; + ospf6_router_id_update(o, false, vty); return CMD_SUCCESS; } diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index aba5d64536..f58af459ba 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -175,7 +175,8 @@ extern void ospf6_master_init(struct thread_master *master); extern void install_element_ospf6_clear_process(void); extern void ospf6_top_init(void); extern void ospf6_delete(struct ospf6 *o); -extern void ospf6_router_id_update(struct ospf6 *ospf6, bool init); +extern void ospf6_router_id_update(struct ospf6 *ospf6, bool init, + struct vty *vty); extern void ospf6_maxage_remove(struct ospf6 *o); extern struct ospf6 *ospf6_instance_create(const char *name); diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 1c9541710e..727e6f7fef 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -101,7 +101,7 @@ static int ospf6_router_id_update_zebra(ZAPI_CALLBACK_ARGS) o->router_id_zebra = router_id.u.prefix4.s_addr; - ospf6_router_id_update(o, false); + ospf6_router_id_update(o, false, NULL); return 0; } From c54fb080a054524dbcb0a03a73c2905c8558ddc9 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 10 Jun 2021 11:30:05 +0200 Subject: [PATCH 3/4] ospf6d: reset areas and redistribution at router-id modification The ospf6 router-id is provided by order of preference by: ospf6d itself if the "ospf6 router-id X.X.X.X" command is set. - zebra. If the "ip router-id X.X.X.X" zebra command is set, the configured IP is provided as the ID or alternatively the highest loopback IPv4 address or else the highest interface IPv4 address. The running ospf6 router-id is stored in ospf6->router-id. ospf6->router-id can change in the following conditions: - A configuration change provides a new router-id value according to the above rules. ospf6->router-id is updated to the new value if there is no adjacency in FULL state. Otherwise, the ospf6d process must be restarted to take the new router-id into account. - On startup of both zebra and ospf6d, if ospf6d has not yet received a valid router-id, ospf6d->router-id is set to 0 (i.e. 0.0.0.0). Then, zebra notifies ospf6d that the router-id is available. At ospf6->router-id, the current behavior of ospf6d is the following: - The self generated LSAs that refer to the previous router-id as the advertising router are kept. - Self generated LSAs are created with router-id value. - LSAs from the redistribution that refer to the previous router-id are kept and no new redistribution LSAs are created. As a consequence, the routers in the ospf6 areas will get incorrect LSAs and might not be able to install prefixes of those LSAs into their RIB. This fix solves this issue by resetting the areas and the redistribution when ospf6->router-id updated. Signed-off-by: Louis Scalbert --- ospf6d/ospf6_top.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index f18eea2129..d4557e0ef6 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -73,6 +73,8 @@ struct ospf6_master *om6; static void ospf6_disable(struct ospf6 *o); +static void ospf6_process_reset(struct ospf6 *ospf6); + static void ospf6_add(struct ospf6 *ospf6) { listnode_add(om6->ospf6, ospf6); @@ -628,6 +630,9 @@ void ospf6_router_id_update(struct ospf6 *ospf6, bool init, struct vty *vty) } ospf6->router_id = new_router_id; + + if (!init) + ospf6_process_reset(ospf6); } /* start ospf6 */ From c295917b4aadfde98692e314fc6b0c9f6af021dd Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Tue, 22 Jun 2021 10:45:53 +0200 Subject: [PATCH 4/4] ospf6d: harmonize ospf6_asbr_redistribute_disable and _reset Harmonize the code of functions ospf6_asbr_redistribute_disable and ospf6_asbr_redistribute_reset. Signed-off-by: Louis Scalbert --- ospf6d/ospf6_asbr.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index d7307fe375..c537816d3b 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -2483,21 +2483,23 @@ void ospf6_asbr_redistribute_disable(struct ospf6 *ospf6) int type; struct ospf6_redist *red; - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + if (type == ZEBRA_ROUTE_OSPF6) + continue; red = ospf6_redist_lookup(ospf6, type, 0); if (!red) continue; - if (type == ZEBRA_ROUTE_OSPF6) + + if (type == DEFAULT_ROUTE) { + ospf6_asbr_routemap_unset(red); + ospf6_redist_del(ospf6, red, type); + ospf6_redistribute_default_set(ospf6, + DEFAULT_ORIGINATE_NONE); continue; + } ospf6_asbr_redistribute_unset(ospf6, red, type); ospf6_redist_del(ospf6, red, type); } - red = ospf6_redist_lookup(ospf6, DEFAULT_ROUTE, 0); - if (red) { - ospf6_asbr_routemap_unset(red); - ospf6_redist_del(ospf6, red, type); - ospf6_redistribute_default_set(ospf6, DEFAULT_ORIGINATE_NONE); - } } void ospf6_asbr_redistribute_reset(struct ospf6 *ospf6)