ospf6d: Init/De-init gr helper functionality

Description:
	Graceful restart helper functionality initialisation and deinit apis.

Signed-off-by: Rajesh Girada <rgirada@vmware.com>
This commit is contained in:
rgirada 2021-06-28 00:04:54 -07:00
parent 91c169f7d7
commit 59790f521a
5 changed files with 305 additions and 1 deletions

155
ospf6d/ospf6_gr_helper.c Normal file
View File

@ -0,0 +1,155 @@
/*
* OSPF6 Graceful Retsart helper functions.
*
* Copyright (C) 2021-22 Vmware, Inc.
* Rajesh Kumar Girada
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "log.h"
#include "vty.h"
#include "command.h"
#include "prefix.h"
#include "stream.h"
#include "zclient.h"
#include "memory.h"
#include "table.h"
#include "lib/bfd.h"
#include "lib_errors.h"
#include "jhash.h"
#include "ospf6_proto.h"
#include "ospf6_lsa.h"
#include "ospf6_lsdb.h"
#include "ospf6_route.h"
#include "ospf6_message.h"
#include "ospf6_top.h"
#include "ospf6_area.h"
#include "ospf6_interface.h"
#include "ospf6_neighbor.h"
#include "ospf6_intra.h"
#include "ospf6d.h"
#include "ospf6_gr_helper.h"
#include "lib/json.h"
#ifndef VTYSH_EXTRACT_PL
#include "ospf6d/ospf6_gr_helper_clippy.c"
#endif
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_GR_HELPER, "OSPF6 Graceful restart helper");
const char *ospf6_exit_reason_desc[] = {
"Unknown reason", "Helper inprogress", "Topology Change",
"Grace timer expiry", "Successful graceful restart",
};
const char *ospf6_restart_reason_desc[] = {
"Unknown restart",
"Software restart",
"Software reload/upgrade",
"Switch to redundant control processor",
};
const char *ospf6_rejected_reason_desc[] = {
"Unknown reason",
"Helper support disabled",
"Neighbour is not in FULL state",
"Supports only planned restart but received for unplanned",
"Topo change due to change in lsa rxmt list",
"LSA age is more than Grace interval",
};
static unsigned int ospf6_enable_rtr_hash_key(const void *data)
{
const struct advRtr *rtr = data;
return jhash_1word(rtr->advRtrAddr, 0);
}
static bool ospf6_enable_rtr_hash_cmp(const void *d1, const void *d2)
{
const struct advRtr *rtr1 = d1;
const struct advRtr *rtr2 = d2;
return (rtr1->advRtrAddr == rtr2->advRtrAddr);
}
static void *ospf6_enable_rtr_hash_alloc(void *p)
{
struct advRtr *rid;
rid = XCALLOC(MTYPE_OSPF6_GR_HELPER, sizeof(struct advRtr));
rid->advRtrAddr = ((struct advRtr *)p)->advRtrAddr;
return rid;
}
static void ospf6_disable_rtr_hash_free(void *rtr)
{
XFREE(MTYPE_OSPF6_GR_HELPER, rtr);
}
static void ospf6_enable_rtr_hash_destroy(struct ospf6 *ospf6)
{
if (ospf6->ospf6_helper_cfg.enable_rtr_list == NULL)
return;
hash_clean(ospf6->ospf6_helper_cfg.enable_rtr_list,
ospf6_disable_rtr_hash_free);
hash_free(ospf6->ospf6_helper_cfg.enable_rtr_list);
ospf6->ospf6_helper_cfg.enable_rtr_list = NULL;
}
/*
* Initilise GR helper config datastructer.
*
* ospf6
* ospf6 pointer
*
* Returns:
* Nothing
*/
void ospf6_gr_helper_init(struct ospf6 *ospf6)
{
ospf6->ospf6_helper_cfg.is_helper_supported = OSPF6_FALSE;
ospf6->ospf6_helper_cfg.strict_lsa_check = OSPF6_TRUE;
ospf6->ospf6_helper_cfg.only_planned_restart = OSPF6_FALSE;
ospf6->ospf6_helper_cfg.supported_grace_time = OSPF6_MAX_GRACE_INTERVAL;
ospf6->ospf6_helper_cfg.last_exit_reason = OSPF6_GR_HELPER_EXIT_NONE;
ospf6->ospf6_helper_cfg.active_restarter_cnt = 0;
ospf6->ospf6_helper_cfg.enable_rtr_list = hash_create(
ospf6_enable_rtr_hash_key, ospf6_enable_rtr_hash_cmp,
"Ospf6 enable router hash");
}
/*
* De-Initilise GR helper config datastructer.
*
* ospf6
* ospf6 pointer
*
* Returns:
* Nothing
*/
void ospf6_gr_helper_deinit(struct ospf6 *ospf6)
{
ospf6_enable_rtr_hash_destroy(ospf6);
}

137
ospf6d/ospf6_gr_helper.h Normal file
View File

@ -0,0 +1,137 @@
/*
* OSPF6 Graceful Retsart helper functions.
*
* Copyright (C) 2021-22 Vmware, Inc.
* Rajesh Kumar Girada
*
* This file is part of GNU Zebra.
*
* GNU Zebra is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* GNU Zebra is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OSPF6_GR_HELPER_H
#define OSPF6_GR_HELPER_H
#define OSPF6_GR_NOT_HELPER 0
#define OSPF6_GR_ACTIVE_HELPER 1
#define OSPF6_GR_HELPER_NO_LSACHECK 0
#define OSPF6_GR_HELPER_LSACHECK 1
#define OSPF6_MAX_GRACE_INTERVAL 1800
#define OSPF6_MIN_GRACE_INTERVAL 1
enum ospf6_helper_exit_reason {
OSPF6_GR_HELPER_EXIT_NONE = 0,
OSPF6_GR_HELPER_INPROGRESS,
OSPF6_GR_HELPER_TOPO_CHG,
OSPF6_GR_HELPER_GRACE_TIMEOUT,
OSPF6_GR_HELPER_COMPLETED
};
enum ospf6_gr_restart_reason {
OSPF6_GR_UNKNOWN_RESTART = 0,
OSPF6_GR_SW_RESTART = 1,
OSPF6_GR_SW_UPGRADE = 2,
OSPF6_GR_SWITCH_REDUNDANT_CARD = 3,
OSPF6_GR_INVALID_REASON_CODE = 4
};
enum ospf6_gr_helper_rejected_reason {
OSPF6_HELPER_REJECTED_NONE,
OSPF6_HELPER_SUPPORT_DISABLED,
OSPF6_HELPER_NOT_A_VALID_NEIGHBOUR,
OSPF6_HELPER_PLANNED_ONLY_RESTART,
OSPF6_HELPER_TOPO_CHANGE_RTXMT_LIST,
OSPF6_HELPER_LSA_AGE_MORE
};
#ifdef roundup
#define ROUNDUP(val, gran) roundup(val, gran)
#else /* roundup */
#define ROUNDUP(val, gran) (((val)-1 | (gran)-1) + 1)
#endif /* roundup */
/*
* Generic TLV (type, length, value) macros
*/
struct tlv_header {
uint16_t type; /* Type of Value */
uint16_t length; /* Length of Value portion only, in bytes */
};
#define TLV_HDR_SIZE (sizeof(struct tlv_header))
#define TLV_BODY_SIZE(tlvh) (ROUNDUP(ntohs((tlvh)->length), sizeof(uint32_t)))
#define TLV_SIZE(tlvh) (TLV_HDR_SIZE + TLV_BODY_SIZE(tlvh))
#define TLV_HDR_TOP(lsah) \
(struct tlv_header *)((char *)(lsah) + OSPF6_LSA_HEADER_SIZE)
#define TLV_HDR_NEXT(tlvh) \
(struct tlv_header *)((char *)(tlvh) + TLV_SIZE(tlvh))
/* Ref RFC5187 appendex-A */
/* Grace period TLV */
#define GRACE_PERIOD_TYPE 1
#define GRACE_PERIOD_LENGTH 4
struct grace_tlv_graceperiod {
struct tlv_header header;
uint32_t interval;
};
#define GRACE_PERIOD_TLV_SIZE sizeof(struct grace_tlv_graceperiod)
/* Restart reason TLV */
#define RESTART_REASON_TYPE 2
#define RESTART_REASON_LENGTH 1
struct grace_tlv_restart_reason {
struct tlv_header header;
uint8_t reason;
uint8_t reserved[3];
};
#define GRACE_RESTART_REASON_TLV_SIZE sizeof(struct grace_tlv_restart_reason)
#define OSPF6_GRACE_LSA_MIN_SIZE \
GRACE_PERIOD_TLV_SIZE + GRACE_RESTART_REASON_TLV_SIZE
struct advRtr {
in_addr_t advRtrAddr;
};
#define OSPF6_HELPER_ENABLE_RTR_COUNT(ospf) \
(ospf6->ospf6_helper_cfg.enableRtrList->count)
/* Check , it is a planned restart */
#define OSPF6_GR_IS_PLANNED_RESTART(reason) \
((reason == OSPF6_GR_SW_RESTART) || (reason == OSPF6_GR_SW_UPGRADE))
/* Check the router is HELPER for current neighbour */
#define OSPF6_GR_IS_ACTIVE_HELPER(N) \
((N)->grHelperInfo.grHelper_status == OSPF6_GR_ACTIVE_HELPER)
/* Check the LSA is GRACE LSA */
#define IS_GRACE_LSA(lsa) (ntohs(lsa->header->type) == OSPF6_LSTYPE_GRACE_LSA)
/* Check neighbour is in FULL state */
#define IS_NBR_STATE_FULL(nbr) (nbr->state == OSPF6_NEIGHBOR_FULL)
extern const char *ospf6_exit_reason_desc[];
extern const char *ospf6_restart_reason_desc[];
extern const char *ospf6_rejected_reason_desc[];
extern void ospf6_gr_helper_init(struct ospf6 *ospf6);
extern void ospf6_gr_helper_deinit(struct ospf6 *ospf6);
#endif /* OSPF6_GR_HELPER_H */

View File

@ -51,6 +51,7 @@
#include "ospf6_intra.h"
#include "ospf6_spf.h"
#include "ospf6d.h"
#include "ospf6_gr_helper.h"
#include "lib/json.h"
#include "ospf6_nssa.h"
@ -440,6 +441,7 @@ static struct ospf6 *ospf6_create(const char *name)
o->oi_write_q = list_new();
ospf6_gr_helper_init(o);
QOBJ_REG(o, ospf6);
/* Make ospf protocol socket. */
@ -485,6 +487,7 @@ void ospf6_delete(struct ospf6 *o)
QOBJ_UNREG(o);
ospf6_gr_helper_deinit(o);
ospf6_flush_self_originated_lsas_now(o);
ospf6_disable(o);
ospf6_del(o);
@ -2233,7 +2236,6 @@ static int config_write_ospf6(struct vty *vty)
ospf6_distance_config_write(vty, ospf6);
ospf6_distribute_config_write(vty, ospf6);
ospf6_asbr_summary_config_write(vty, ospf6);
vty_out(vty, "!\n");
}
return 0;

View File

@ -108,6 +108,12 @@ extern struct thread_master *master;
vrf_name = VRF_DEFAULT_NAME; \
}
#define OSPF6_FALSE false
#define OSPF6_TRUE true
#define OSPF6_SUCCESS 1
#define OSPF6_FAILURE 0
#define OSPF6_INVALID -1
extern struct zebra_privs_t ospf6d_privs;
/* Function Prototypes */

View File

@ -12,6 +12,7 @@ vtysh_scan += \
ospf6d/ospf6_area.c \
ospf6d/ospf6_bfd.c \
ospf6d/ospf6_flood.c \
ospf6d/ospf6_gr_helper.c \
ospf6d/ospf6_interface.c \
ospf6d/ospf6_intra.c \
ospf6d/ospf6_lsa.c \
@ -39,6 +40,7 @@ ospf6d_libospf6_a_SOURCES = \
ospf6d/ospf6_routemap_nb_config.c \
ospf6d/ospf6_bfd.c \
ospf6d/ospf6_flood.c \
ospf6d/ospf6_gr_helper.c \
ospf6d/ospf6_interface.c \
ospf6d/ospf6_intra.c \
ospf6d/ospf6_lsa.c \
@ -61,6 +63,7 @@ noinst_HEADERS += \
ospf6d/ospf6_asbr.h \
ospf6d/ospf6_bfd.h \
ospf6d/ospf6_flood.h \
ospf6d/ospf6_gr_helper.h \
ospf6d/ospf6_interface.h \
ospf6d/ospf6_intra.h \
ospf6d/ospf6_lsa.h \
@ -91,6 +94,7 @@ clippy_scan += \
ospf6d/ospf6_top.c \
ospf6d/ospf6_asbr.c \
ospf6d/ospf6_lsa.c \
ospf6d/ospf6_gr_helper.c \
# end
nodist_ospf6d_ospf6d_SOURCES = \