forked from Mirror/frr
ospfd: Clear ip ospf process and clear ip ospf neighbor
Implement the below 2 CLIs to clear the current data in the process and neighbor data structure. 1. clear ip ospf process 2. clear ip ospf neighbor Signed-off-by: Mobashshera Rasool <mrasool@vmware.com>
This commit is contained in:
parent
f10f8f0e98
commit
f91ce319d3
|
@ -322,6 +322,23 @@ To start OSPF process you have to specify the OSPF router.
|
||||||
|
|
||||||
This feature is enabled by default.
|
This feature is enabled by default.
|
||||||
|
|
||||||
|
.. index:: clear ip ospf [(1-65535)] process
|
||||||
|
.. clicmd:: clear ip ospf [(1-65535)] process
|
||||||
|
|
||||||
|
This command can be used to clear the ospf process data structures. This
|
||||||
|
will clear the ospf neighborship as well and it will get re-established.
|
||||||
|
This will clear the LSDB too. 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 ospfd daemon.
|
||||||
|
|
||||||
|
.. index:: clear ip ospf [(1-65535)] neighbor
|
||||||
|
.. clicmd:: clear ip ospf [(1-65535)] neighbor
|
||||||
|
|
||||||
|
This command can be used to clear the ospf neighbor data structures. This
|
||||||
|
will clear the ospf neighborship and it will get re-established. This
|
||||||
|
command can be used when the neighbor state get stuck at some state and
|
||||||
|
this can be used to recover it from that state.
|
||||||
|
|
||||||
.. _ospf-area:
|
.. _ospf-area:
|
||||||
|
|
||||||
Areas
|
Areas
|
||||||
|
|
|
@ -750,6 +750,7 @@ void ospf_ase_unregister_external_lsa(struct ospf_lsa *lsa, struct ospf *top)
|
||||||
lst = rn->info;
|
lst = rn->info;
|
||||||
listnode_delete(lst, lsa);
|
listnode_delete(lst, lsa);
|
||||||
ospf_lsa_unlock(&lsa); /* external_lsas list */
|
ospf_lsa_unlock(&lsa); /* external_lsas list */
|
||||||
|
|
||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2789,7 +2789,7 @@ int ospf_check_nbr_status(struct ospf *ospf)
|
||||||
static int ospf_maxage_lsa_remover(struct thread *thread)
|
static int ospf_maxage_lsa_remover(struct thread *thread)
|
||||||
{
|
{
|
||||||
struct ospf *ospf = THREAD_ARG(thread);
|
struct ospf *ospf = THREAD_ARG(thread);
|
||||||
struct ospf_lsa *lsa;
|
struct ospf_lsa *lsa, *old;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
int reschedule = 0;
|
int reschedule = 0;
|
||||||
|
|
||||||
|
@ -2851,6 +2851,17 @@ static int ospf_maxage_lsa_remover(struct thread *thread)
|
||||||
|
|
||||||
/* Remove from lsdb. */
|
/* Remove from lsdb. */
|
||||||
if (lsa->lsdb) {
|
if (lsa->lsdb) {
|
||||||
|
old = ospf_lsdb_lookup(lsa->lsdb, lsa);
|
||||||
|
/* The max age LSA here must be the same
|
||||||
|
* as the LSA in LSDB
|
||||||
|
*/
|
||||||
|
if (old != lsa) {
|
||||||
|
flog_err(EC_OSPF_LSA_MISSING,
|
||||||
|
"%s: LSA[Type%d:%s]: LSA not in LSDB",
|
||||||
|
__func__, lsa->data->type,
|
||||||
|
inet_ntoa(lsa->data->id));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
ospf_discard_from_db(ospf, lsa->lsdb, lsa);
|
ospf_discard_from_db(ospf, lsa->lsdb, lsa);
|
||||||
ospf_lsdb_delete(lsa->lsdb, lsa);
|
ospf_lsdb_delete(lsa->lsdb, lsa);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -280,7 +280,7 @@ DEFPY (ospf_router_id,
|
||||||
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
|
||||||
if (area->full_nbrs) {
|
if (area->full_nbrs) {
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"For this router-id change to take effect, save config and restart ospfd\n");
|
"For this router-id change to take effect, use “clear ip ospf process” command\n");
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ DEFUN_HIDDEN (ospf_router_id_old,
|
||||||
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
|
||||||
if (area->full_nbrs) {
|
if (area->full_nbrs) {
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"For this router-id change to take effect, save config and restart ospfd\n");
|
"For this router-id change to take effect, use “clear ip ospf process” command\n");
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +346,7 @@ DEFPY (no_ospf_router_id,
|
||||||
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
|
||||||
if (area->full_nbrs) {
|
if (area->full_nbrs) {
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"For this router-id change to take effect, save config and restart ospfd\n");
|
"For this router-id change to take effect, use “clear ip ospf process” command\n");
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11176,6 +11176,70 @@ DEFUN (show_ip_ospf_vrfs,
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
DEFPY (clear_ip_ospf_neighbor,
|
||||||
|
clear_ip_ospf_neighbor_cmd,
|
||||||
|
"clear ip ospf [(1-65535)]$instance neighbor [A.B.C.D$nbr_id]",
|
||||||
|
CLEAR_STR
|
||||||
|
IP_STR
|
||||||
|
"OSPF information\n"
|
||||||
|
"Instance ID\n"
|
||||||
|
"Reset OSPF Neighbor\n"
|
||||||
|
"Neighbor ID\n")
|
||||||
|
{
|
||||||
|
struct listnode *node;
|
||||||
|
struct ospf *ospf = NULL;
|
||||||
|
|
||||||
|
/* If user does not specify the arguments,
|
||||||
|
* instance = 0 and nbr_id = 0.0.0.0
|
||||||
|
*/
|
||||||
|
if (instance != 0) {
|
||||||
|
/* This means clear only the particular ospf process */
|
||||||
|
ospf = ospf_lookup_instance(instance);
|
||||||
|
if (ospf == NULL)
|
||||||
|
return CMD_NOT_MY_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear all the ospf processes */
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
||||||
|
if (!ospf->oi_running)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ospf_neighbor_reset(ospf, nbr_id, nbr_id_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFPY (clear_ip_ospf_process,
|
||||||
|
clear_ip_ospf_process_cmd,
|
||||||
|
"clear ip ospf [(1-65535)]$instance process",
|
||||||
|
CLEAR_STR
|
||||||
|
IP_STR
|
||||||
|
"OSPF information\n"
|
||||||
|
"Instance ID\n"
|
||||||
|
"Reset OSPF Process\n")
|
||||||
|
{
|
||||||
|
struct listnode *node;
|
||||||
|
struct ospf *ospf = NULL;
|
||||||
|
|
||||||
|
/* Check if instance is not passed as an argument */
|
||||||
|
if (instance != 0) {
|
||||||
|
/* This means clear only the particular ospf process */
|
||||||
|
ospf = ospf_lookup_instance(instance);
|
||||||
|
if (ospf == NULL)
|
||||||
|
return CMD_NOT_MY_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear all the ospf processes */
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
|
||||||
|
if (!ospf->oi_running)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ospf_process_reset(ospf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *const ospf_abr_type_str[] = {
|
static const char *const ospf_abr_type_str[] = {
|
||||||
"unknown", "standard", "ibm", "cisco", "shortcut"
|
"unknown", "standard", "ibm", "cisco", "shortcut"
|
||||||
|
@ -12572,6 +12636,8 @@ DEFUN (clear_ip_ospf_interface,
|
||||||
void ospf_vty_clear_init(void)
|
void ospf_vty_clear_init(void)
|
||||||
{
|
{
|
||||||
install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd);
|
install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd);
|
||||||
|
install_element(ENABLE_NODE, &clear_ip_ospf_process_cmd);
|
||||||
|
install_element(ENABLE_NODE, &clear_ip_ospf_neighbor_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -87,13 +87,15 @@ static void ospf_finish_final(struct ospf *);
|
||||||
|
|
||||||
#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
|
#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
|
||||||
|
|
||||||
void ospf_router_id_update(struct ospf *ospf)
|
void ospf_process_refresh_data(struct ospf *ospf, bool reset)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
|
struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
|
||||||
struct in_addr router_id, router_id_old;
|
struct in_addr router_id, router_id_old;
|
||||||
struct ospf_interface *oi;
|
struct ospf_interface *oi;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct listnode *node;
|
struct listnode *node, *nnode;
|
||||||
|
struct ospf_area *area;
|
||||||
|
bool rid_change = false;
|
||||||
|
|
||||||
if (!ospf->oi_running) {
|
if (!ospf->oi_running) {
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
|
@ -126,8 +128,8 @@ void ospf_router_id_update(struct ospf *ospf)
|
||||||
zlog_debug("Router-ID[OLD:%pI4]: Update to %pI4",
|
zlog_debug("Router-ID[OLD:%pI4]: Update to %pI4",
|
||||||
&ospf->router_id, &router_id);
|
&ospf->router_id, &router_id);
|
||||||
|
|
||||||
if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) {
|
rid_change = !(IPV4_ADDR_SAME(&router_id_old, &router_id));
|
||||||
|
if (rid_change || (reset)) {
|
||||||
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
|
||||||
/* Some nbrs are identified by router_id, these needs
|
/* Some nbrs are identified by router_id, these needs
|
||||||
* to be rebuilt. Possible optimization would be to do
|
* to be rebuilt. Possible optimization would be to do
|
||||||
|
@ -149,16 +151,8 @@ void ospf_router_id_update(struct ospf *ospf)
|
||||||
ospf_if_up(oi);
|
ospf_if_up(oi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flush (inline) all external LSAs based on the OSPF_LSA_SELF
|
/* Flush (inline) all the self originated LSAs */
|
||||||
* flag */
|
ospf_flush_self_originated_lsas_now(ospf);
|
||||||
if (ospf->lsdb) {
|
|
||||||
struct route_node *rn;
|
|
||||||
struct ospf_lsa *lsa;
|
|
||||||
|
|
||||||
LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
|
|
||||||
if (IS_LSA_SELF(lsa))
|
|
||||||
ospf_lsa_flush_schedule(ospf, lsa);
|
|
||||||
}
|
|
||||||
|
|
||||||
ospf->router_id = router_id;
|
ospf->router_id = router_id;
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
|
@ -183,24 +177,81 @@ void ospf_router_id_update(struct ospf *ospf)
|
||||||
LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) {
|
LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) {
|
||||||
/* AdvRouter and Router ID is the same. */
|
/* AdvRouter and Router ID is the same. */
|
||||||
if (IPV4_ADDR_SAME(&lsa->data->adv_router,
|
if (IPV4_ADDR_SAME(&lsa->data->adv_router,
|
||||||
&ospf->router_id)) {
|
&ospf->router_id) && rid_change) {
|
||||||
SET_FLAG(lsa->flags,
|
SET_FLAG(lsa->flags,
|
||||||
OSPF_LSA_SELF_CHECKED);
|
OSPF_LSA_SELF_CHECKED);
|
||||||
SET_FLAG(lsa->flags, OSPF_LSA_SELF);
|
SET_FLAG(lsa->flags, OSPF_LSA_SELF);
|
||||||
ospf_lsa_flush_schedule(ospf, lsa);
|
ospf_lsa_flush_schedule(ospf, lsa);
|
||||||
}
|
}
|
||||||
|
/* The above flush will send immediately
|
||||||
|
* So discard the LSA to originate new
|
||||||
|
*/
|
||||||
|
ospf_discard_from_db(ospf, ospf->lsdb, lsa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
|
||||||
|
ospf_discard_from_db(ospf, ospf->lsdb, lsa);
|
||||||
|
|
||||||
|
ospf_lsdb_delete_all(ospf->lsdb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Delete the LSDB */
|
||||||
|
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
|
||||||
|
ospf_area_lsdb_discard_delete(area);
|
||||||
|
|
||||||
/* update router-lsa's for each area */
|
/* update router-lsa's for each area */
|
||||||
ospf_router_lsa_update(ospf);
|
ospf_router_lsa_update(ospf);
|
||||||
|
|
||||||
/* update ospf_interface's */
|
/* update ospf_interface's */
|
||||||
FOR_ALL_INTERFACES (vrf, ifp)
|
FOR_ALL_INTERFACES (vrf, ifp) {
|
||||||
|
if (reset)
|
||||||
|
ospf_if_reset(ifp);
|
||||||
|
else
|
||||||
ospf_if_update(ospf, ifp);
|
ospf_if_update(ospf, ifp);
|
||||||
|
}
|
||||||
|
|
||||||
ospf_external_lsa_rid_change(ospf);
|
ospf_external_lsa_rid_change(ospf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ospf->inst_shutdown = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ospf_router_id_update(struct ospf *ospf)
|
||||||
|
{
|
||||||
|
ospf_process_refresh_data(ospf, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ospf_process_reset(struct ospf *ospf)
|
||||||
|
{
|
||||||
|
ospf_process_refresh_data(ospf, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ospf_neighbor_reset(struct ospf *ospf, struct in_addr nbr_id,
|
||||||
|
const char *nbr_str)
|
||||||
|
{
|
||||||
|
struct route_node *rn;
|
||||||
|
struct ospf_neighbor *nbr;
|
||||||
|
struct ospf_interface *oi;
|
||||||
|
struct listnode *node;
|
||||||
|
|
||||||
|
/* Clear only a particular nbr with nbr router id as nbr_id */
|
||||||
|
if (nbr_str != NULL) {
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
|
||||||
|
nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, &nbr_id);
|
||||||
|
if (nbr)
|
||||||
|
OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send Neighbor event KillNbr to all associated neighbors. */
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
|
||||||
|
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
|
||||||
|
nbr = rn->info;
|
||||||
|
if (nbr && (nbr != oi->nbr_self))
|
||||||
|
OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For OSPF area sort by area id. */
|
/* For OSPF area sort by area id. */
|
||||||
|
@ -870,14 +921,11 @@ static struct ospf_area *ospf_area_new(struct ospf *ospf,
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ospf_area_free(struct ospf_area *area)
|
void ospf_area_lsdb_discard_delete(struct ospf_area *area)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct ospf_lsa *lsa;
|
struct ospf_lsa *lsa;
|
||||||
|
|
||||||
ospf_opaque_type10_lsa_term(area);
|
|
||||||
|
|
||||||
/* Free LSDBs. */
|
|
||||||
LSDB_LOOP (ROUTER_LSDB(area), rn, lsa)
|
LSDB_LOOP (ROUTER_LSDB(area), rn, lsa)
|
||||||
ospf_discard_from_db(area->ospf, area->lsdb, lsa);
|
ospf_discard_from_db(area->ospf, area->lsdb, lsa);
|
||||||
LSDB_LOOP (NETWORK_LSDB(area), rn, lsa)
|
LSDB_LOOP (NETWORK_LSDB(area), rn, lsa)
|
||||||
|
@ -895,6 +943,15 @@ static void ospf_area_free(struct ospf_area *area)
|
||||||
ospf_discard_from_db(area->ospf, area->lsdb, lsa);
|
ospf_discard_from_db(area->ospf, area->lsdb, lsa);
|
||||||
|
|
||||||
ospf_lsdb_delete_all(area->lsdb);
|
ospf_lsdb_delete_all(area->lsdb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ospf_area_free(struct ospf_area *area)
|
||||||
|
{
|
||||||
|
ospf_opaque_type10_lsa_term(area);
|
||||||
|
|
||||||
|
/* Free LSDBs. */
|
||||||
|
ospf_area_lsdb_discard_delete(area);
|
||||||
|
|
||||||
ospf_lsdb_free(area->lsdb);
|
ospf_lsdb_free(area->lsdb);
|
||||||
|
|
||||||
ospf_lsa_unlock(&area->router_lsa_self);
|
ospf_lsa_unlock(&area->router_lsa_self);
|
||||||
|
|
|
@ -571,7 +571,11 @@ extern struct ospf *ospf_lookup_by_inst_name(unsigned short instance,
|
||||||
const char *name);
|
const char *name);
|
||||||
extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id);
|
extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id);
|
||||||
extern void ospf_finish(struct ospf *);
|
extern void ospf_finish(struct ospf *);
|
||||||
|
extern void ospf_process_refresh_data(struct ospf *ospf, bool reset);
|
||||||
extern void ospf_router_id_update(struct ospf *ospf);
|
extern void ospf_router_id_update(struct ospf *ospf);
|
||||||
|
extern void ospf_process_reset(struct ospf *ospf);
|
||||||
|
extern void ospf_neighbor_reset(struct ospf *ospf, struct in_addr nbr_id,
|
||||||
|
const char *nbr_str);
|
||||||
extern int ospf_network_set(struct ospf *, struct prefix_ipv4 *, struct in_addr,
|
extern int ospf_network_set(struct ospf *, struct prefix_ipv4 *, struct in_addr,
|
||||||
int);
|
int);
|
||||||
extern int ospf_network_unset(struct ospf *, struct prefix_ipv4 *,
|
extern int ospf_network_unset(struct ospf *, struct prefix_ipv4 *,
|
||||||
|
@ -596,6 +600,7 @@ extern int ospf_area_shortcut_set(struct ospf *, struct ospf_area *, int);
|
||||||
extern int ospf_area_shortcut_unset(struct ospf *, struct ospf_area *);
|
extern int ospf_area_shortcut_unset(struct ospf *, struct ospf_area *);
|
||||||
extern int ospf_timers_refresh_set(struct ospf *, int);
|
extern int ospf_timers_refresh_set(struct ospf *, int);
|
||||||
extern int ospf_timers_refresh_unset(struct ospf *);
|
extern int ospf_timers_refresh_unset(struct ospf *);
|
||||||
|
void ospf_area_lsdb_discard_delete(struct ospf_area *area);
|
||||||
extern int ospf_nbr_nbma_set(struct ospf *, struct in_addr);
|
extern int ospf_nbr_nbma_set(struct ospf *, struct in_addr);
|
||||||
extern int ospf_nbr_nbma_unset(struct ospf *, struct in_addr);
|
extern int ospf_nbr_nbma_unset(struct ospf *, struct in_addr);
|
||||||
extern int ospf_nbr_nbma_priority_set(struct ospf *, struct in_addr, uint8_t);
|
extern int ospf_nbr_nbma_priority_set(struct ospf *, struct in_addr, uint8_t);
|
||||||
|
|
Loading…
Reference in a new issue