mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 18:56:40 +00:00
ospfd: Add Label Manager for Segment Routing
Segment Routing Global Block is now using the Label Manager to reserved label range. Label Manager connection uses the synchronous mode and dedicated thread timer is used to establish the connection in safe manner without blocking OSPFd is the Label Manager is not available. Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
This commit is contained in:
parent
b9fb1c87c9
commit
d81b8e0e1a
266
ospfd/ospf_sr.c
266
ospfd/ospf_sr.c
@ -82,6 +82,7 @@
|
|||||||
static struct ospf_sr_db OspfSR;
|
static struct ospf_sr_db OspfSR;
|
||||||
static void ospf_sr_register_vty(void);
|
static void ospf_sr_register_vty(void);
|
||||||
static inline void del_adj_sid(struct sr_nhlfe nhlfe);
|
static inline void del_adj_sid(struct sr_nhlfe nhlfe);
|
||||||
|
static int ospf_sr_start(struct ospf *ospf);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Segment Routing Data Base functions
|
* Segment Routing Data Base functions
|
||||||
@ -221,6 +222,26 @@ static struct sr_node *get_sr_node_by_nexthop(struct ospf *ospf,
|
|||||||
* Segment Routing Initialization functions
|
* Segment Routing Initialization functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread function to re-attempt connection to the Label Manager and thus be
|
||||||
|
* able to start Segment Routing.
|
||||||
|
*
|
||||||
|
* @param start Thread structure that contains area as argument
|
||||||
|
*
|
||||||
|
* @return 1 on success
|
||||||
|
*/
|
||||||
|
static int sr_start_label_manager(struct thread *start)
|
||||||
|
{
|
||||||
|
struct ospf *ospf;
|
||||||
|
|
||||||
|
ospf = THREAD_ARG(start);
|
||||||
|
|
||||||
|
/* re-attempt to start SR & Label Manager connection */
|
||||||
|
ospf_sr_start(ospf);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Segment Routing starter function */
|
/* Segment Routing starter function */
|
||||||
static int ospf_sr_start(struct ospf *ospf)
|
static int ospf_sr_start(struct ospf *ospf)
|
||||||
{
|
{
|
||||||
@ -231,16 +252,56 @@ static int ospf_sr_start(struct ospf *ospf)
|
|||||||
|
|
||||||
osr_debug("SR (%s): Start Segment Routing", __func__);
|
osr_debug("SR (%s): Start Segment Routing", __func__);
|
||||||
|
|
||||||
/* Initialize self SR Node */
|
/* Initialize self SR Node if not already done */
|
||||||
srn = hash_get(OspfSR.neighbors, (void *)&(ospf->router_id),
|
if (OspfSR.self == NULL) {
|
||||||
(void *)sr_node_new);
|
srn = hash_get(OspfSR.neighbors, (void *)&(ospf->router_id),
|
||||||
|
(void *)sr_node_new);
|
||||||
|
|
||||||
/* Complete & Store self SR Node */
|
/* Complete & Store self SR Node */
|
||||||
srn->srgb.range_size = OspfSR.srgb.range_size;
|
srn->srgb.range_size = OspfSR.srgb.range_size;
|
||||||
srn->srgb.lower_bound = OspfSR.srgb.lower_bound;
|
srn->srgb.lower_bound = OspfSR.srgb.lower_bound;
|
||||||
srn->algo[0] = OspfSR.algo[0];
|
srn->algo[0] = OspfSR.algo[0];
|
||||||
srn->msd = OspfSR.msd;
|
srn->msd = OspfSR.msd;
|
||||||
OspfSR.self = srn;
|
OspfSR.self = srn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then, start Label Manager if not ready */
|
||||||
|
if (!ospf_zebra_label_manager_ready())
|
||||||
|
if (ospf_zebra_label_manager_connect() < 0) {
|
||||||
|
/* Re-attempt to connect to Label Manager in 1 sec. */
|
||||||
|
thread_add_timer(master, sr_start_label_manager, ospf,
|
||||||
|
1, &OspfSR.t_start_lm);
|
||||||
|
osr_debug(" |- Failed to start the Label Manager");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Request SGRB to the label manager if not already active. If the
|
||||||
|
* allocation fails, return an error to disable SR until a new SRGB
|
||||||
|
* is successfully allocated.
|
||||||
|
*/
|
||||||
|
if (!OspfSR.srgb_reserved) {
|
||||||
|
if (ospf_zebra_request_label_range(OspfSR.srgb.lower_bound,
|
||||||
|
OspfSR.srgb.range_size)
|
||||||
|
< 0) {
|
||||||
|
OspfSR.srgb_reserved = false;
|
||||||
|
return -1;
|
||||||
|
} else
|
||||||
|
OspfSR.srgb_reserved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SR is UP and ready to flood LSA */
|
||||||
|
OspfSR.status = SR_UP;
|
||||||
|
|
||||||
|
/* Set Router Information SR parameters */
|
||||||
|
osr_debug("SR: Activate SR for Router Information LSA");
|
||||||
|
|
||||||
|
ospf_router_info_update_sr(true, OspfSR.srgb, OspfSR.msd);
|
||||||
|
|
||||||
|
/* Update Ext LSA */
|
||||||
|
osr_debug("SR: Activate SR for Extended Link/Prefix LSA");
|
||||||
|
|
||||||
|
ospf_ext_update_sr(true);
|
||||||
|
|
||||||
osr_debug("SR (%s): Update SR-DB from LSDB", __func__);
|
osr_debug("SR (%s): Update SR-DB from LSDB", __func__);
|
||||||
|
|
||||||
@ -277,13 +338,24 @@ static void ospf_sr_stop(void)
|
|||||||
|
|
||||||
osr_debug("SR (%s): Stop Segment Routing", __func__);
|
osr_debug("SR (%s): Stop Segment Routing", __func__);
|
||||||
|
|
||||||
|
/* Disable any re-attempt to connect to Label Manager */
|
||||||
|
THREAD_TIMER_OFF(OspfSR.t_start_lm);
|
||||||
|
|
||||||
|
/* Release SRGB if active. */
|
||||||
|
if (OspfSR.srgb_reserved) {
|
||||||
|
ospf_zebra_release_label_range(
|
||||||
|
OspfSR.srgb.lower_bound,
|
||||||
|
OspfSR.srgb.lower_bound + OspfSR.srgb.range_size - 1);
|
||||||
|
OspfSR.srgb_reserved = false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove all SR Nodes from the Hash table. Prefix and Link SID will
|
* Remove all SR Nodes from the Hash table. Prefix and Link SID will
|
||||||
* be remove though list_delete() call. See sr_node_del()
|
* be remove though list_delete() call. See sr_node_del()
|
||||||
*/
|
*/
|
||||||
hash_clean(OspfSR.neighbors, (void *)sr_node_del);
|
hash_clean(OspfSR.neighbors, (void *)sr_node_del);
|
||||||
OspfSR.self = NULL;
|
OspfSR.self = NULL;
|
||||||
OspfSR.enabled = false;
|
OspfSR.status = SR_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -300,7 +372,7 @@ int ospf_sr_init(void)
|
|||||||
osr_debug("SR (%s): Initialize SR Data Base", __func__);
|
osr_debug("SR (%s): Initialize SR Data Base", __func__);
|
||||||
|
|
||||||
memset(&OspfSR, 0, sizeof(struct ospf_sr_db));
|
memset(&OspfSR, 0, sizeof(struct ospf_sr_db));
|
||||||
OspfSR.enabled = false;
|
OspfSR.status = SR_OFF;
|
||||||
/* Only AREA flooding is supported in this release */
|
/* Only AREA flooding is supported in this release */
|
||||||
OspfSR.scope = OSPF_OPAQUE_AREA_LSA;
|
OspfSR.scope = OSPF_OPAQUE_AREA_LSA;
|
||||||
|
|
||||||
@ -312,6 +384,7 @@ int ospf_sr_init(void)
|
|||||||
|
|
||||||
OspfSR.srgb.range_size = MPLS_DEFAULT_MAX_SRGB_SIZE;
|
OspfSR.srgb.range_size = MPLS_DEFAULT_MAX_SRGB_SIZE;
|
||||||
OspfSR.srgb.lower_bound = MPLS_DEFAULT_MIN_SRGB_LABEL;
|
OspfSR.srgb.lower_bound = MPLS_DEFAULT_MIN_SRGB_LABEL;
|
||||||
|
OspfSR.srgb_reserved = false;
|
||||||
OspfSR.msd = 0;
|
OspfSR.msd = 0;
|
||||||
|
|
||||||
/* Initialize Hash table for neighbor SR nodes */
|
/* Initialize Hash table for neighbor SR nodes */
|
||||||
@ -1612,7 +1685,7 @@ void ospf_sr_config_write_router(struct vty *vty)
|
|||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct sr_prefix *srp;
|
struct sr_prefix *srp;
|
||||||
|
|
||||||
if (OspfSR.enabled) {
|
if (OspfSR.status != SR_OFF) {
|
||||||
vty_out(vty, " segment-routing on\n");
|
vty_out(vty, " segment-routing on\n");
|
||||||
|
|
||||||
if ((OspfSR.srgb.lower_bound != MPLS_DEFAULT_MIN_SRGB_LABEL)
|
if ((OspfSR.srgb.lower_bound != MPLS_DEFAULT_MIN_SRGB_LABEL)
|
||||||
@ -1651,7 +1724,7 @@ DEFUN(ospf_sr_enable,
|
|||||||
|
|
||||||
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
||||||
|
|
||||||
if (OspfSR.enabled)
|
if (OspfSR.status != SR_OFF)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
if (ospf->vrf_id != VRF_DEFAULT) {
|
if (ospf->vrf_id != VRF_DEFAULT) {
|
||||||
@ -1663,19 +1736,9 @@ DEFUN(ospf_sr_enable,
|
|||||||
osr_debug("SR: Segment Routing: OFF -> ON");
|
osr_debug("SR: Segment Routing: OFF -> ON");
|
||||||
|
|
||||||
/* Start Segment Routing */
|
/* Start Segment Routing */
|
||||||
OspfSR.enabled = true;
|
OspfSR.status = SR_ON;
|
||||||
ospf_sr_start(ospf);
|
ospf_sr_start(ospf);
|
||||||
|
|
||||||
/* Set Router Information SR parameters */
|
|
||||||
osr_debug("SR: Activate SR for Router Information LSA");
|
|
||||||
|
|
||||||
ospf_router_info_update_sr(true, OspfSR.srgb, OspfSR.msd);
|
|
||||||
|
|
||||||
/* Update Ext LSA */
|
|
||||||
osr_debug("SR: Activate SR for Extended Link/Prefix LSA");
|
|
||||||
|
|
||||||
ospf_ext_update_sr(true);
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1687,7 +1750,7 @@ DEFUN (no_ospf_sr_enable,
|
|||||||
"Disable Segment Routing\n")
|
"Disable Segment Routing\n")
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!OspfSR.enabled)
|
if (OspfSR.status == SR_OFF)
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
osr_debug("SR: Segment Routing: ON -> OFF");
|
osr_debug("SR: Segment Routing: ON -> OFF");
|
||||||
@ -1706,7 +1769,7 @@ DEFUN (no_ospf_sr_enable,
|
|||||||
|
|
||||||
static int ospf_sr_enabled(struct vty *vty)
|
static int ospf_sr_enabled(struct vty *vty)
|
||||||
{
|
{
|
||||||
if (OspfSR.enabled)
|
if (OspfSR.status != SR_OFF)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (vty)
|
if (vty)
|
||||||
@ -1715,13 +1778,71 @@ static int ospf_sr_enabled(struct vty *vty)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update SRGB following new CLI value.
|
||||||
|
*
|
||||||
|
* @param lower Lower bound of the SRGB
|
||||||
|
* @param size Size of the SRGB
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 otherwise
|
||||||
|
*/
|
||||||
|
static int update_srgb(uint32_t lower, uint32_t size)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Check if values have changed */
|
||||||
|
if ((OspfSR.srgb.range_size == size)
|
||||||
|
&& (OspfSR.srgb.lower_bound == lower))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Release old SRGB if active. */
|
||||||
|
if (OspfSR.srgb_reserved) {
|
||||||
|
ospf_zebra_release_label_range(
|
||||||
|
OspfSR.srgb.lower_bound,
|
||||||
|
OspfSR.srgb.lower_bound + OspfSR.srgb.range_size - 1);
|
||||||
|
OspfSR.srgb_reserved = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set new SRGB values */
|
||||||
|
OspfSR.srgb.range_size = size;
|
||||||
|
OspfSR.srgb.lower_bound = lower;
|
||||||
|
if (OspfSR.self != NULL) {
|
||||||
|
OspfSR.self->srgb.range_size = size;
|
||||||
|
OspfSR.self->srgb.lower_bound = lower;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if SR is correctly started i.e. Label Manager connected */
|
||||||
|
if (OspfSR.status != SR_UP)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to reserve the new block from the Label Manger. If the allocation
|
||||||
|
* fails, disable SR until a new SRGB is successfully allocated.
|
||||||
|
*/
|
||||||
|
if (ospf_zebra_request_label_range(OspfSR.srgb.lower_bound,
|
||||||
|
OspfSR.srgb.range_size) < 0) {
|
||||||
|
OspfSR.srgb_reserved = false;
|
||||||
|
ospf_sr_stop();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SRGB is reserved, set Router Information parameters */
|
||||||
|
ospf_router_info_update_sr(true, OspfSR.srgb, OspfSR.msd);
|
||||||
|
|
||||||
|
/* and update NHLFE entries */
|
||||||
|
hash_iterate(OspfSR.neighbors,
|
||||||
|
(void (*)(struct hash_bucket *, void *))update_in_nhlfe,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (sr_sid_label_range,
|
DEFUN (sr_sid_label_range,
|
||||||
sr_sid_label_range_cmd,
|
sr_sid_label_range_cmd,
|
||||||
"segment-routing global-block (0-1048575) (0-1048575)",
|
"segment-routing global-block (16-1048575) (16-1048575)",
|
||||||
SR_STR
|
SR_STR
|
||||||
"Segment Routing Global Block label range\n"
|
"Segment Routing Global Block label range\n"
|
||||||
"Lower-bound range in decimal (0-1048575)\n"
|
"Lower-bound range in decimal (16-1048575)\n"
|
||||||
"Upper-bound range in decimal (0-1048575)\n")
|
"Upper-bound range in decimal (16-1048575)\n")
|
||||||
{
|
{
|
||||||
uint32_t upper;
|
uint32_t upper;
|
||||||
uint32_t lower;
|
uint32_t lower;
|
||||||
@ -1737,47 +1858,10 @@ DEFUN (sr_sid_label_range,
|
|||||||
upper = strtoul(argv[idx_up]->arg, NULL, 10);
|
upper = strtoul(argv[idx_up]->arg, NULL, 10);
|
||||||
size = upper - lower + 1;
|
size = upper - lower + 1;
|
||||||
|
|
||||||
if (size > MPLS_DEFAULT_MAX_SRGB_SIZE || size <= 0) {
|
if (update_srgb(lower, size) < 0)
|
||||||
vty_out(vty,
|
|
||||||
"Range size cannot be less than 0 or more than %u\n",
|
|
||||||
MPLS_DEFAULT_MAX_SRGB_SIZE);
|
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
}
|
else
|
||||||
|
|
||||||
if (upper > MPLS_DEFAULT_MAX_SRGB_LABEL) {
|
|
||||||
vty_out(vty, "Upper-bound cannot exceed %u\n",
|
|
||||||
MPLS_DEFAULT_MAX_SRGB_LABEL);
|
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (upper < MPLS_DEFAULT_MIN_SRGB_LABEL) {
|
|
||||||
vty_out(vty, "Upper-bound cannot be lower than %u\n",
|
|
||||||
MPLS_DEFAULT_MIN_SRGB_LABEL);
|
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if values have changed */
|
|
||||||
if ((OspfSR.srgb.range_size == size)
|
|
||||||
&& (OspfSR.srgb.lower_bound == lower))
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
/* Set SID/Label range SRGB */
|
|
||||||
OspfSR.srgb.range_size = size;
|
|
||||||
OspfSR.srgb.lower_bound = lower;
|
|
||||||
if (OspfSR.self != NULL) {
|
|
||||||
OspfSR.self->srgb.range_size = size;
|
|
||||||
OspfSR.self->srgb.lower_bound = lower;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set Router Information SR parameters */
|
|
||||||
ospf_router_info_update_sr(true, OspfSR.srgb, OspfSR.msd);
|
|
||||||
|
|
||||||
/* Update NHLFE entries */
|
|
||||||
hash_iterate(OspfSR.neighbors,
|
|
||||||
(void (*)(struct hash_bucket *, void *))update_in_nhlfe,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (no_sr_sid_label_range,
|
DEFUN (no_sr_sid_label_range,
|
||||||
@ -1793,23 +1877,11 @@ DEFUN (no_sr_sid_label_range,
|
|||||||
if (!ospf_sr_enabled(vty))
|
if (!ospf_sr_enabled(vty))
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
|
||||||
/* Revert to default SRGB value */
|
if (update_srgb(MPLS_DEFAULT_MIN_SRGB_SIZE,
|
||||||
OspfSR.srgb.range_size = MPLS_DEFAULT_MIN_SRGB_SIZE;
|
MPLS_DEFAULT_MIN_SRGB_LABEL) < 0)
|
||||||
OspfSR.srgb.lower_bound = MPLS_DEFAULT_MIN_SRGB_LABEL;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
if (OspfSR.self != NULL) {
|
else
|
||||||
OspfSR.self->srgb.range_size = OspfSR.srgb.range_size;
|
return CMD_SUCCESS;
|
||||||
OspfSR.self->srgb.lower_bound = OspfSR.srgb.lower_bound;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set Router Information SR parameters */
|
|
||||||
ospf_router_info_update_sr(true, OspfSR.srgb, OspfSR.msd);
|
|
||||||
|
|
||||||
/* Update NHLFE entries */
|
|
||||||
hash_iterate(OspfSR.neighbors,
|
|
||||||
(void (*)(struct hash_bucket *, void *))update_in_nhlfe,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (sr_node_msd,
|
DEFUN (sr_node_msd,
|
||||||
@ -1843,8 +1915,9 @@ DEFUN (sr_node_msd,
|
|||||||
if (OspfSR.self != NULL)
|
if (OspfSR.self != NULL)
|
||||||
OspfSR.self->msd = msd;
|
OspfSR.self->msd = msd;
|
||||||
|
|
||||||
/* Set Router Information SR parameters */
|
/* Set Router Information parameters if SR is UP */
|
||||||
ospf_router_info_update_sr(true, OspfSR.srgb, OspfSR.msd);
|
if (OspfSR.status == SR_UP)
|
||||||
|
ospf_router_info_update_sr(true, OspfSR.srgb, OspfSR.msd);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1866,8 +1939,9 @@ DEFUN (no_sr_node_msd,
|
|||||||
if (OspfSR.self != NULL)
|
if (OspfSR.self != NULL)
|
||||||
OspfSR.self->msd = 0;
|
OspfSR.self->msd = 0;
|
||||||
|
|
||||||
/* Set Router Information SR parameters */
|
/* Set Router Information parameters if SR is UP */
|
||||||
ospf_router_info_update_sr(true, OspfSR.srgb, 0);
|
if (OspfSR.status == SR_UP)
|
||||||
|
ospf_router_info_update_sr(true, OspfSR.srgb, 0);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1972,9 +2046,14 @@ DEFUN (sr_prefix_sid,
|
|||||||
} else {
|
} else {
|
||||||
listnode_add(OspfSR.self->ext_prefix, new);
|
listnode_add(OspfSR.self->ext_prefix, new);
|
||||||
}
|
}
|
||||||
ospf_zebra_update_prefix_sid(new);
|
|
||||||
|
|
||||||
/* Finally, update Extended Prefix LSA */
|
/* Install Prefix SID if SR is UP */
|
||||||
|
if (OspfSR.status == SR_UP)
|
||||||
|
ospf_zebra_update_prefix_sid(new);
|
||||||
|
else
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
|
/* Finally, update Extended Prefix LSA id SR is UP */
|
||||||
new->instance = ospf_ext_schedule_prefix_index(
|
new->instance = ospf_ext_schedule_prefix_index(
|
||||||
ifp, new->sid, &new->prefv4, new->flags);
|
ifp, new->sid, &new->prefv4, new->flags);
|
||||||
if (new->instance == 0) {
|
if (new->instance == 0) {
|
||||||
@ -2008,6 +2087,9 @@ DEFUN (no_sr_prefix_sid,
|
|||||||
if (!ospf_sr_enabled(vty))
|
if (!ospf_sr_enabled(vty))
|
||||||
return CMD_WARNING_CONFIG_FAILED;
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
|
||||||
|
if (OspfSR.status != SR_UP)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
/* Get network prefix */
|
/* Get network prefix */
|
||||||
argv_find(argv, argc, "A.B.C.D/M", &idx);
|
argv_find(argv, argc, "A.B.C.D/M", &idx);
|
||||||
rc = str2prefix(argv[idx]->arg, &p);
|
rc = str2prefix(argv[idx]->arg, &p);
|
||||||
@ -2352,7 +2434,7 @@ DEFUN (show_ip_opsf_srdb,
|
|||||||
bool uj = use_json(argc, argv);
|
bool uj = use_json(argc, argv);
|
||||||
json_object *json = NULL, *json_node_array = NULL;
|
json_object *json = NULL, *json_node_array = NULL;
|
||||||
|
|
||||||
if (!OspfSR.enabled) {
|
if (OspfSR.status == SR_OFF) {
|
||||||
vty_out(vty, "Segment Routing is disabled on this router\n");
|
vty_out(vty, "Segment Routing is disabled on this router\n");
|
||||||
return CMD_WARNING;
|
return CMD_WARNING;
|
||||||
}
|
}
|
||||||
|
@ -193,10 +193,13 @@ struct sr_srgb {
|
|||||||
/* SID type to make difference between loopback interfaces and others */
|
/* SID type to make difference between loopback interfaces and others */
|
||||||
enum sid_type { PREF_SID, LOCAL_SID, ADJ_SID, LAN_ADJ_SID };
|
enum sid_type { PREF_SID, LOCAL_SID, ADJ_SID, LAN_ADJ_SID };
|
||||||
|
|
||||||
|
/* Status of Segment Routing: Off (Disable), On (Enable), (Up) Started */
|
||||||
|
enum sr_status { SR_OFF, SR_ON, SR_UP, SR_DOWN };
|
||||||
|
|
||||||
/* Structure aggregating all OSPF Segment Routing information for the node */
|
/* Structure aggregating all OSPF Segment Routing information for the node */
|
||||||
struct ospf_sr_db {
|
struct ospf_sr_db {
|
||||||
/* Status of Segment Routing: enable or disable */
|
/* Status of Segment Routing */
|
||||||
bool enabled;
|
enum sr_status status;
|
||||||
|
|
||||||
/* Flooding Scope: Area = 10 or AS = 11 */
|
/* Flooding Scope: Area = 10 or AS = 11 */
|
||||||
uint8_t scope;
|
uint8_t scope;
|
||||||
@ -219,6 +222,13 @@ struct ospf_sr_db {
|
|||||||
* Only one range supported in this code
|
* Only one range supported in this code
|
||||||
*/
|
*/
|
||||||
struct sr_srgb srgb;
|
struct sr_srgb srgb;
|
||||||
|
|
||||||
|
/* Thread timer to start Label Manager */
|
||||||
|
struct thread *t_start_lm;
|
||||||
|
|
||||||
|
/* Status of SRGB: reserved within Label Manager or not */
|
||||||
|
bool srgb_reserved;
|
||||||
|
|
||||||
/* Maximum SID Depth supported by the node */
|
/* Maximum SID Depth supported by the node */
|
||||||
uint8_t msd;
|
uint8_t msd;
|
||||||
};
|
};
|
||||||
|
@ -59,6 +59,8 @@ DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments")
|
|||||||
|
|
||||||
/* Zebra structure to hold current status. */
|
/* Zebra structure to hold current status. */
|
||||||
struct zclient *zclient = NULL;
|
struct zclient *zclient = NULL;
|
||||||
|
/* and for the Synchronous connection to the Label Manager */
|
||||||
|
static struct zclient *zclient_sync;
|
||||||
|
|
||||||
/* For registering threads. */
|
/* For registering threads. */
|
||||||
extern struct thread_master *master;
|
extern struct thread_master *master;
|
||||||
@ -1713,6 +1715,109 @@ void ospf_zebra_vrf_deregister(struct ospf *ospf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Label Manager Functions */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if Label Manager is Ready or not.
|
||||||
|
*
|
||||||
|
* @return True if Label Manager is ready, False otherwise
|
||||||
|
*/
|
||||||
|
bool ospf_zebra_label_manager_ready(void)
|
||||||
|
{
|
||||||
|
return (zclient_sync->sock > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request Label Range to the Label Manager.
|
||||||
|
*
|
||||||
|
* @param base base label of the label range to request
|
||||||
|
* @param chunk_size size of the label range to request
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 on failure
|
||||||
|
*/
|
||||||
|
int ospf_zebra_request_label_range(uint32_t base, uint32_t chunk_size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uint32_t start, end;
|
||||||
|
|
||||||
|
if (zclient_sync->sock < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = lm_get_label_chunk(zclient_sync, 0, base, chunk_size, &start,
|
||||||
|
&end);
|
||||||
|
if (ret < 0) {
|
||||||
|
zlog_warn("%s: error getting label range!", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release Label Range to the Label Manager.
|
||||||
|
*
|
||||||
|
* @param start start of label range to release
|
||||||
|
* @param end end of label range to release
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 otherwise
|
||||||
|
*/
|
||||||
|
int ospf_zebra_release_label_range(uint32_t start, uint32_t end)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (zclient_sync->sock < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = lm_release_label_chunk(zclient_sync, start, end);
|
||||||
|
if (ret < 0) {
|
||||||
|
zlog_warn("%s: error releasing label range!", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to the Label Manager.
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 otherwise
|
||||||
|
*/
|
||||||
|
int ospf_zebra_label_manager_connect(void)
|
||||||
|
{
|
||||||
|
/* Connect to label manager. */
|
||||||
|
if (zclient_socket_connect(zclient_sync) < 0) {
|
||||||
|
zlog_warn("%s: failed connecting synchronous zclient!",
|
||||||
|
__func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* make socket non-blocking */
|
||||||
|
set_nonblocking(zclient_sync->sock);
|
||||||
|
|
||||||
|
/* Send hello to notify zebra this is a synchronous client */
|
||||||
|
if (zclient_send_hello(zclient_sync) < 0) {
|
||||||
|
zlog_warn("%s: failed sending hello for synchronous zclient!",
|
||||||
|
__func__);
|
||||||
|
close(zclient_sync->sock);
|
||||||
|
zclient_sync->sock = -1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect to label manager */
|
||||||
|
if (lm_label_manager_connect(zclient_sync, 0) != 0) {
|
||||||
|
zlog_warn("%s: failed connecting to label manager!", __func__);
|
||||||
|
if (zclient_sync->sock > 0) {
|
||||||
|
close(zclient_sync->sock);
|
||||||
|
zclient_sync->sock = -1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
osr_debug("SR (%s): Successfully connected to the Label Manager",
|
||||||
|
__func__);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void ospf_zebra_connected(struct zclient *zclient)
|
static void ospf_zebra_connected(struct zclient *zclient)
|
||||||
{
|
{
|
||||||
/* Send the client registration */
|
/* Send the client registration */
|
||||||
@ -1736,6 +1841,20 @@ void ospf_zebra_init(struct thread_master *master, unsigned short instance)
|
|||||||
zclient->redistribute_route_add = ospf_zebra_read_route;
|
zclient->redistribute_route_add = ospf_zebra_read_route;
|
||||||
zclient->redistribute_route_del = ospf_zebra_read_route;
|
zclient->redistribute_route_del = ospf_zebra_read_route;
|
||||||
|
|
||||||
|
/* Initialize special zclient for synchronous message exchanges. */
|
||||||
|
struct zclient_options options = zclient_options_default;
|
||||||
|
options.synchronous = true;
|
||||||
|
zclient_sync = zclient_new(master, &options);
|
||||||
|
zclient_sync->sock = -1;
|
||||||
|
zclient_sync->redist_default = ZEBRA_ROUTE_OSPF;
|
||||||
|
zclient_sync->instance = instance;
|
||||||
|
/*
|
||||||
|
* session_id must be different from default value (0) to distinguish
|
||||||
|
* the asynchronous socket from the synchronous one
|
||||||
|
*/
|
||||||
|
zclient_sync->session_id = 1;
|
||||||
|
zclient_sync->privs = &ospfd_privs;
|
||||||
|
|
||||||
access_list_add_hook(ospf_filter_update);
|
access_list_add_hook(ospf_filter_update);
|
||||||
access_list_delete_hook(ospf_filter_update);
|
access_list_delete_hook(ospf_filter_update);
|
||||||
prefix_list_add_hook(ospf_prefix_list_update);
|
prefix_list_add_hook(ospf_prefix_list_update);
|
||||||
|
@ -102,4 +102,8 @@ int ospf_external_info_apply_default_routemap(struct ospf *ospf,
|
|||||||
|
|
||||||
extern void ospf_zebra_send_arp(const struct interface *ifp,
|
extern void ospf_zebra_send_arp(const struct interface *ifp,
|
||||||
const struct prefix *p);
|
const struct prefix *p);
|
||||||
|
bool ospf_zebra_label_manager_ready(void);
|
||||||
|
int ospf_zebra_label_manager_connect(void);
|
||||||
|
int ospf_zebra_request_label_range(uint32_t base, uint32_t chunk_size);
|
||||||
|
int ospf_zebra_release_label_range(uint32_t start, uint32_t end);
|
||||||
#endif /* _ZEBRA_OSPF_ZEBRA_H */
|
#endif /* _ZEBRA_OSPF_ZEBRA_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user