ospf6d: "clear ipv6 ospf6 process" command

Adding the "clear ipv6 ospf6 command" . It resets
the ospfv3 datastructures and clears the database
as well as route tables. It resets the neighborship
by restarting the interface state machine.
If the user wants to change the router-id, this
command updates the router-id to the latest static
router-id and starts the neighbor formation with
the new router-id.

Signed-off-by: Yash Ranjan <ranjany@vmware.com>
This commit is contained in:
Yash Ranjan 2021-05-03 04:46:41 -07:00
parent 32694c41bb
commit f71ed6df3e
10 changed files with 134 additions and 7 deletions

View File

@ -77,6 +77,13 @@ OSPF6 router
of packets to process before returning. The default value of this parameter
is 20.
.. clicmd:: clear ipv6 ospf6 process [vrf NAME]
This command clears up the database and routing tables and resets the
neighborship by restarting the interface state machine. This will be
helpful when there is a change in router-id and if user wants the router-id
change to take effect, user can use this cli instead of restarting the
ospf6d daemon.
.. _ospf6-area:

View File

@ -194,6 +194,11 @@ struct route_map_index {
};
DECLARE_QOBJ_TYPE(route_map_index);
/* route map maximum length. Not strictly the maximum xpath length but cannot be
* greater
*/
#define RMAP_NAME_MAXLEN XPATH_MAXLEN
/* Route map list structure. */
struct route_map {
/* Name of route map. */

View File

@ -2478,7 +2478,7 @@ void ospf6_asbr_init(void)
install_element(OSPF6_NODE, &no_ospf6_redistribute_cmd);
}
void ospf6_asbr_redistribute_reset(struct ospf6 *ospf6)
void ospf6_asbr_redistribute_disable(struct ospf6 *ospf6)
{
int type;
struct ospf6_redist *red;
@ -2500,6 +2500,35 @@ void ospf6_asbr_redistribute_reset(struct ospf6 *ospf6)
}
}
void ospf6_asbr_redistribute_reset(struct ospf6 *ospf6)
{
int type;
struct ospf6_redist *red;
char buf[RMAP_NAME_MAXLEN];
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
buf[0] = '\0';
if (type == ZEBRA_ROUTE_OSPF6)
continue;
red = ospf6_redist_lookup(ospf6, type, 0);
if (!red)
continue;
if (type == DEFAULT_ROUTE) {
ospf6_redistribute_default_set(
ospf6, ospf6->default_originate);
continue;
}
if (ROUTEMAP_NAME(red))
strlcpy(buf, ROUTEMAP_NAME(red), sizeof(buf));
ospf6_asbr_redistribute_unset(ospf6, red, type);
if (buf[0])
ospf6_asbr_routemap_set(red, buf);
ospf6_asbr_redistribute_set(ospf6, type);
}
}
void ospf6_asbr_terminate(void)
{
/* Cleanup route maps */

View File

@ -93,6 +93,7 @@ extern int ospf6_redistribute_config_write(struct vty *vty,
struct ospf6 *ospf6);
extern void ospf6_asbr_init(void);
extern void ospf6_asbr_redistribute_disable(struct ospf6 *ospf6);
extern void ospf6_asbr_redistribute_reset(struct ospf6 *ospf6);
extern void ospf6_asbr_terminate(void);
extern void ospf6_asbr_send_externals_to_area(struct ospf6_area *);

View File

@ -2695,7 +2695,7 @@ void ospf6_interface_init(void)
}
/* Clear the specified interface structure */
static void ospf6_interface_clear(struct vty *vty, struct interface *ifp)
void ospf6_interface_clear(struct interface *ifp)
{
struct ospf6_interface *oi;
@ -2733,7 +2733,7 @@ DEFUN (clear_ipv6_ospf6_interface,
if (argc == 4) /* Clear all the ospfv3 interfaces. */
{
FOR_ALL_INTERFACES (vrf, ifp)
ospf6_interface_clear(vty, ifp);
ospf6_interface_clear(ifp);
} else /* Interface name is specified. */
{
if ((ifp = if_lookup_by_name(argv[idx_ifname]->arg,
@ -2743,7 +2743,7 @@ DEFUN (clear_ipv6_ospf6_interface,
argv[idx_ifname]->arg);
return CMD_WARNING;
}
ospf6_interface_clear(vty, ifp);
ospf6_interface_clear(ifp);
}
return CMD_SUCCESS;

View File

@ -213,6 +213,7 @@ extern int backup_seen(struct thread *);
extern int neighbor_change(struct thread *);
extern void ospf6_interface_init(void);
extern void ospf6_interface_clear(struct interface *ifp);
extern void install_element_ospf6_clear_interface(void);

View File

@ -63,6 +63,10 @@ FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES,
{ .val_bool = false },
);
#ifndef VTYSH_EXTRACT_PL
#include "ospf6d/ospf6_top_clippy.c"
#endif
/* global ospf6d variable */
static struct ospf6_master ospf6_master;
struct ospf6_master *om6;
@ -512,7 +516,7 @@ static void ospf6_disable(struct ospf6 *o)
/* XXX: This also changes persistent settings */
/* Unregister redistribution */
ospf6_asbr_redistribute_reset(o);
ospf6_asbr_redistribute_disable(o);
ospf6_lsdb_remove_all(o->lsdb);
ospf6_route_remove_all(o->route_table);
@ -649,6 +653,78 @@ DEFUN(no_router_ospf6, no_router_ospf6_cmd, "no router ospf6 [vrf NAME]",
return CMD_SUCCESS;
}
static void ospf6_db_clear(struct ospf6 *ospf6)
{
struct ospf6_interface *oi;
struct interface *ifp;
struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id);
struct listnode *node, *nnode;
struct ospf6_area *oa;
FOR_ALL_INTERFACES (vrf, ifp) {
if (if_is_operative(ifp) && ifp->info != NULL) {
oi = (struct ospf6_interface *)ifp->info;
ospf6_lsdb_remove_all(oi->lsdb);
ospf6_lsdb_remove_all(oi->lsdb_self);
ospf6_lsdb_remove_all(oi->lsupdate_list);
ospf6_lsdb_remove_all(oi->lsack_list);
}
}
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
ospf6_lsdb_remove_all(oa->lsdb);
ospf6_lsdb_remove_all(oa->lsdb_self);
ospf6_spf_table_finish(oa->spf_table);
ospf6_route_remove_all(oa->route_table);
}
ospf6_lsdb_remove_all(ospf6->lsdb);
ospf6_lsdb_remove_all(ospf6->lsdb_self);
ospf6_route_remove_all(ospf6->route_table);
ospf6_route_remove_all(ospf6->brouter_table);
}
static void ospf6_process_reset(struct ospf6 *ospf6)
{
struct interface *ifp;
struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id);
ospf6_flush_self_originated_lsas_now(ospf6);
ospf6->inst_shutdown = 0;
ospf6_db_clear(ospf6);
ospf6_router_id_update(ospf6);
ospf6_asbr_redistribute_reset(ospf6);
FOR_ALL_INTERFACES (vrf, ifp)
ospf6_interface_clear(ifp);
}
DEFPY (clear_router_ospf6,
clear_router_ospf6_cmd,
"clear ipv6 ospf6 process [vrf NAME$name]",
CLEAR_STR
IP6_STR
OSPF6_STR
"Reset OSPF Process\n"
VRF_CMD_HELP_STR)
{
struct ospf6 *ospf6;
const char *vrf_name = VRF_DEFAULT_NAME;
if (name != NULL)
vrf_name = name;
ospf6 = ospf6_lookup_by_vrf_name(vrf_name);
if (ospf6 == NULL)
vty_out(vty, "OSPFv3 is not configured\n");
else
ospf6_process_reset(ospf6);
return CMD_SUCCESS;
}
/* change Router_ID commands. */
DEFUN(ospf6_router_id,
ospf6_router_id_cmd,
@ -679,7 +755,7 @@ DEFUN(ospf6_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, save config and restart ospf6d\n");
"For this router-id change to take effect, run the \"clear ipv6 ospf6 process\" command\n");
return CMD_SUCCESS;
}
}
@ -705,7 +781,7 @@ DEFUN(no_ospf6_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, save config and restart ospf6d\n");
"For this router-id change to take effect, run the \"clear ipv6 ospf6 process\" command\n");
return CMD_SUCCESS;
}
}
@ -1708,6 +1784,11 @@ static struct cmd_node ospf6_node = {
.config_write = config_write_ospf6,
};
void install_element_ospf6_clear_process(void)
{
install_element(ENABLE_NODE, &clear_router_ospf6_cmd);
}
/* Install ospf related commands. */
void ospf6_top_init(void)
{

View File

@ -173,6 +173,7 @@ extern struct ospf6_master *om6;
/* prototypes */
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);

View File

@ -1425,6 +1425,7 @@ void ospf6_init(struct thread_master *master)
install_element_ospf6_debug_flood();
install_element_ospf6_debug_nssa();
install_element_ospf6_clear_process();
install_element_ospf6_clear_interface();
install_element(ENABLE_NODE, &show_debugging_ospf6_cmd);

View File

@ -88,6 +88,7 @@ ospf6d_ospf6d_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
ospf6d_ospf6d_snmp_la_LIBADD = lib/libfrrsnmp.la
clippy_scan += \
ospf6d/ospf6_top.c \
ospf6d/ospf6_asbr.c \
# end