mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 11:47:08 +00:00
ospfd: Update Prefix & Adjacency SIDs Management
SIDs are not uninstall in LFIB when ospf adjacenyi or loopback goes down as self LSA flusing is not handle by ospf_ext_link_lsa_update(). The patch introduces new functions ospf_sr_ext_itf_add() and ospf_sr_ext_itf_delete() in ospf_sr.c to directly manage LFIB for SIDs when change is detected in ospf_ext_link_ism_change() and ospf_ext_link_nsm_change(). Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
This commit is contained in:
parent
008bcff499
commit
21baf89aff
@ -443,6 +443,32 @@ static void set_rmt_itf_addr(struct ext_itf *exti, struct in_addr rmtif)
|
||||
exti->rmt_itf_addr.value = rmtif;
|
||||
}
|
||||
|
||||
/* Delete Extended LSA */
|
||||
static void ospf_extended_lsa_delete(struct ext_itf *exti)
|
||||
{
|
||||
|
||||
/* Process only Active Extended Prefix/Link LSA */
|
||||
if (!CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ACTIVE))
|
||||
return;
|
||||
|
||||
osr_debug("EXT (%s): Disable %s%s%s-SID on interface %s", __func__,
|
||||
exti->stype == PREF_SID ? "Prefix" : "",
|
||||
exti->stype == ADJ_SID ? "Adjacency" : "",
|
||||
exti->stype == LAN_ADJ_SID ? "LAN-Adjacency" : "",
|
||||
exti->ifp->name);
|
||||
|
||||
/* Flush LSA if already engaged */
|
||||
if (CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED)) {
|
||||
ospf_ext_lsa_schedule(exti, FLUSH_THIS_LSA);
|
||||
UNSET_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED);
|
||||
}
|
||||
|
||||
/* De-activate this Extended Prefix/Link and remove corresponding
|
||||
* Segment-Routing Prefix-SID or (LAN)-ADJ-SID */
|
||||
exti->flags = EXT_LPFLG_LSA_INACTIVE;
|
||||
ospf_sr_ext_itf_delete(exti);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update Extended prefix SID index for Loopback interface type
|
||||
*
|
||||
@ -516,6 +542,7 @@ void ospf_ext_update_sr(bool enable)
|
||||
|
||||
/* Refresh LSAs if already engaged or originate */
|
||||
for (ALL_LIST_ELEMENTS_RO(OspfEXT.iflist, node, exti)) {
|
||||
/* Skip inactive Extended Link */
|
||||
if (!CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ACTIVE))
|
||||
continue;
|
||||
|
||||
@ -526,17 +553,15 @@ void ospf_ext_update_sr(bool enable)
|
||||
REORIGINATE_THIS_LSA);
|
||||
}
|
||||
} else {
|
||||
/* Start by Flushing engaged LSAs */
|
||||
for (ALL_LIST_ELEMENTS_RO(OspfEXT.iflist, node, exti)) {
|
||||
if (CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED))
|
||||
ospf_ext_lsa_schedule(exti, FLUSH_THIS_LSA);
|
||||
exti->flags = EXT_LPFLG_LSA_INACTIVE;
|
||||
}
|
||||
/* Start by Removing Extended LSA */
|
||||
for (ALL_LIST_ELEMENTS_RO(OspfEXT.iflist, node, exti))
|
||||
ospf_extended_lsa_delete(exti);
|
||||
|
||||
/* And then disable Extended Link/Prefix */
|
||||
OspfEXT.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------
|
||||
* Followings are callback functions against generic Opaque-LSAs handling
|
||||
@ -574,10 +599,11 @@ static int ospf_ext_link_del_if(struct interface *ifp)
|
||||
|
||||
exti = lookup_ext_by_ifp(ifp);
|
||||
if (exti != NULL) {
|
||||
struct list *iflist = OspfEXT.iflist;
|
||||
/* Flush LSA and remove Adjacency SID */
|
||||
ospf_extended_lsa_delete(exti);
|
||||
|
||||
/* Dequeue listnode entry from the list. */
|
||||
listnode_delete(iflist, exti);
|
||||
listnode_delete(OspfEXT.iflist, exti);
|
||||
|
||||
XFREE(MTYPE_OSPF_EXT_PARAMS, exti);
|
||||
|
||||
@ -610,6 +636,7 @@ static void ospf_ext_ism_change(struct ospf_interface *oi, int old_status)
|
||||
|
||||
/* Reset Extended information if ospf interface goes Down */
|
||||
if (oi->state == ISM_Down) {
|
||||
ospf_extended_lsa_delete(exti);
|
||||
exti->area = NULL;
|
||||
exti->flags = EXT_LPFLG_LSA_INACTIVE;
|
||||
return;
|
||||
@ -660,8 +687,8 @@ static void ospf_ext_link_nsm_change(struct ospf_neighbor *nbr, int old_status)
|
||||
struct ext_itf *exti;
|
||||
uint32_t label;
|
||||
|
||||
/* Process Neighbor only when its state is NSM Full */
|
||||
if (nbr->state != NSM_Full)
|
||||
/* Process Link only when neighbor old or new state is NSM Full */
|
||||
if (nbr->state != NSM_Full && old_status != NSM_Full)
|
||||
return;
|
||||
|
||||
/* Get interface information for Segment Routing */
|
||||
@ -673,6 +700,23 @@ static void ospf_ext_link_nsm_change(struct ospf_neighbor *nbr, int old_status)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check that we have a valid area and ospf context */
|
||||
if (oi->area == NULL || oi->area->ospf == NULL) {
|
||||
flog_warn(EC_OSPF_EXT_LSA_UNEXPECTED,
|
||||
"EXT (%s): Cannot refer to OSPF from OI(%s)",
|
||||
__func__, IF_NAME(oi));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove Extended Link if Neighbor State goes Down or Deleted */
|
||||
if (nbr->state == NSM_Down || nbr->state == NSM_Deleted) {
|
||||
ospf_extended_lsa_delete(exti);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Keep Area information in combination with SR info. */
|
||||
exti->area = oi->area;
|
||||
|
||||
/* Process only Adjacency/LAN SID */
|
||||
if (exti->stype == PREF_SID)
|
||||
return;
|
||||
@ -748,6 +792,9 @@ static void ospf_ext_link_nsm_change(struct ospf_neighbor *nbr, int old_status)
|
||||
else
|
||||
ospf_ext_link_lsa_schedule(exti, REORIGINATE_THIS_LSA);
|
||||
}
|
||||
|
||||
/* Finally install (LAN)Adjacency-SID in the SRDB */
|
||||
ospf_sr_ext_itf_add(exti);
|
||||
}
|
||||
|
||||
/* Callbacks to handle Extended Link Segment Routing LSA information */
|
||||
@ -770,6 +817,10 @@ static int ospf_ext_link_lsa_update(struct ospf_lsa *lsa)
|
||||
!= OPAQUE_TYPE_EXTENDED_LINK_LSA)
|
||||
return 0;
|
||||
|
||||
/* Check if it is not my LSA */
|
||||
if (IS_LSA_SELF(lsa))
|
||||
return 0;
|
||||
|
||||
/* Check if Extended is enable */
|
||||
if (!OspfEXT.enabled)
|
||||
return 0;
|
||||
@ -1218,6 +1269,10 @@ static int ospf_ext_link_lsa_originate(void *arg)
|
||||
if (exti->stype == PREF_SID)
|
||||
continue;
|
||||
|
||||
/* Skip Inactive Extended Link */
|
||||
if (!CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ACTIVE))
|
||||
continue;
|
||||
|
||||
/* Process only Extended Link with valid Area ID */
|
||||
if ((exti->area == NULL)
|
||||
|| (!IPV4_ADDR_SAME(&exti->area->area_id, &area->area_id)))
|
||||
|
138
ospfd/ospf_sr.c
138
ospfd/ospf_sr.c
@ -286,6 +286,8 @@ static void ospf_sr_stop(void)
|
||||
* be remove though list_delete() call. See sr_node_del()
|
||||
*/
|
||||
hash_clean(OspfSR.neighbors, (void *)sr_node_del);
|
||||
OspfSR.self = NULL;
|
||||
OspfSR.enabled = false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -352,9 +354,6 @@ void ospf_sr_term(void)
|
||||
/* Clear Prefix Table */
|
||||
if (OspfSR.prefix)
|
||||
route_table_finish(OspfSR.prefix);
|
||||
|
||||
OspfSR.enabled = false;
|
||||
OspfSR.self = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -367,8 +366,6 @@ void ospf_sr_finish(void)
|
||||
{
|
||||
/* Stop Segment Routing */
|
||||
ospf_sr_stop();
|
||||
|
||||
OspfSR.enabled = false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1345,6 +1342,136 @@ void ospf_sr_ext_link_lsa_delete(struct ospf_lsa *lsa)
|
||||
}
|
||||
}
|
||||
|
||||
/* Add (LAN)Adjacency-SID from Extended Link Information */
|
||||
void ospf_sr_ext_itf_add(struct ext_itf *exti)
|
||||
{
|
||||
struct sr_node *srn = OspfSR.self;
|
||||
struct sr_link *srl;
|
||||
|
||||
osr_debug("SR (%s): Add Extended Link LSA 8.0.0.%u from self", __func__,
|
||||
exti->instance);
|
||||
|
||||
/* Sanity check */
|
||||
if (srn == NULL)
|
||||
return;
|
||||
|
||||
/* Initialize new Segment Routing Link */
|
||||
srl = XCALLOC(MTYPE_OSPF_SR_PARAMS, sizeof(struct sr_link));
|
||||
srl->srn = srn;
|
||||
srl->adv_router = srn->adv_router;
|
||||
srl->itf_addr = exti->link.link_data;
|
||||
srl->instance =
|
||||
SET_OPAQUE_LSID(OPAQUE_TYPE_EXTENDED_LINK_LSA, exti->instance);
|
||||
switch (exti->stype) {
|
||||
case ADJ_SID:
|
||||
srl->type = ADJ_SID;
|
||||
/* Primary information */
|
||||
srl->flags[0] = exti->adj_sid[0].flags;
|
||||
if (CHECK_FLAG(exti->adj_sid[0].flags,
|
||||
EXT_SUBTLV_LINK_ADJ_SID_VFLG))
|
||||
srl->sid[0] = GET_LABEL(ntohl(exti->adj_sid[0].value));
|
||||
else
|
||||
srl->sid[0] = ntohl(exti->adj_sid[0].value);
|
||||
if (exti->rmt_itf_addr.header.type == 0)
|
||||
srl->nhlfe[0].nexthop = exti->link.link_id;
|
||||
else
|
||||
srl->nhlfe[0].nexthop = exti->rmt_itf_addr.value;
|
||||
/* Backup Information if set */
|
||||
if (exti->adj_sid[1].header.type == 0)
|
||||
break;
|
||||
srl->flags[1] = exti->adj_sid[1].flags;
|
||||
if (CHECK_FLAG(exti->adj_sid[1].flags,
|
||||
EXT_SUBTLV_LINK_ADJ_SID_VFLG))
|
||||
srl->sid[1] = GET_LABEL(ntohl(exti->adj_sid[1].value));
|
||||
else
|
||||
srl->sid[1] = ntohl(exti->adj_sid[1].value);
|
||||
if (exti->rmt_itf_addr.header.type == 0)
|
||||
srl->nhlfe[1].nexthop = exti->link.link_id;
|
||||
else
|
||||
srl->nhlfe[1].nexthop = exti->rmt_itf_addr.value;
|
||||
break;
|
||||
case LAN_ADJ_SID:
|
||||
srl->type = LAN_ADJ_SID;
|
||||
/* Primary information */
|
||||
srl->flags[0] = exti->lan_sid[0].flags;
|
||||
if (CHECK_FLAG(exti->lan_sid[0].flags,
|
||||
EXT_SUBTLV_LINK_ADJ_SID_VFLG))
|
||||
srl->sid[0] = GET_LABEL(ntohl(exti->lan_sid[0].value));
|
||||
else
|
||||
srl->sid[0] = ntohl(exti->lan_sid[0].value);
|
||||
if (exti->rmt_itf_addr.header.type == 0)
|
||||
srl->nhlfe[0].nexthop = exti->lan_sid[0].neighbor_id;
|
||||
else
|
||||
srl->nhlfe[0].nexthop = exti->rmt_itf_addr.value;
|
||||
/* Backup Information if set */
|
||||
if (exti->lan_sid[1].header.type == 0)
|
||||
break;
|
||||
srl->flags[1] = exti->lan_sid[1].flags;
|
||||
if (CHECK_FLAG(exti->lan_sid[1].flags,
|
||||
EXT_SUBTLV_LINK_ADJ_SID_VFLG))
|
||||
srl->sid[1] = GET_LABEL(ntohl(exti->lan_sid[1].value));
|
||||
else
|
||||
srl->sid[1] = ntohl(exti->lan_sid[1].value);
|
||||
if (exti->rmt_itf_addr.header.type == 0)
|
||||
srl->nhlfe[1].nexthop = exti->lan_sid[1].neighbor_id;
|
||||
else
|
||||
srl->nhlfe[1].nexthop = exti->rmt_itf_addr.value;
|
||||
break;
|
||||
default:
|
||||
/* Wrong SID Type. Abort! */
|
||||
XFREE(MTYPE_OSPF_SR_PARAMS, srl);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Segment Routing Link is ready, update it */
|
||||
update_ext_link_sid(srn, srl, OSPF_LSA_SELF);
|
||||
}
|
||||
|
||||
/* Delete Prefix or (LAN)Adjacency-SID from Extended Link Information */
|
||||
void ospf_sr_ext_itf_delete(struct ext_itf *exti)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct sr_node *srn = OspfSR.self;
|
||||
struct sr_prefix *srp = NULL;
|
||||
struct sr_link *srl = NULL;
|
||||
uint32_t instance;
|
||||
|
||||
osr_debug("SR (%s): Remove Extended LSA %u.0.0.%u from self",
|
||||
__func__, exti->stype == PREF_SID ? 7 : 8, exti->instance);
|
||||
|
||||
/* Sanity check: SR-Node and Extended Prefix/Link list may have been
|
||||
* removed earlier when stopping OSPF or OSPF-SR */
|
||||
if (srn == NULL || srn->ext_prefix == NULL || srn->ext_link == NULL)
|
||||
return;
|
||||
|
||||
if (exti->stype == PREF_SID) {
|
||||
instance = SET_OPAQUE_LSID(OPAQUE_TYPE_EXTENDED_PREFIX_LSA,
|
||||
exti->instance);
|
||||
for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp))
|
||||
if (srp->instance == instance)
|
||||
break;
|
||||
|
||||
/* Uninstall Segment Prefix SID if found */
|
||||
if ((srp != NULL) && (srp->instance == instance))
|
||||
delete_prefix_sid(srp);
|
||||
} else {
|
||||
/* Search for corresponding Segment Link for self SR-Node */
|
||||
instance = SET_OPAQUE_LSID(OPAQUE_TYPE_EXTENDED_LINK_LSA,
|
||||
exti->instance);
|
||||
for (ALL_LIST_ELEMENTS_RO(srn->ext_link, node, srl))
|
||||
if (srl->instance == instance)
|
||||
break;
|
||||
|
||||
/* Remove Segment Link if found */
|
||||
if ((srl != NULL) && (srl->instance == instance)) {
|
||||
del_adj_sid(srl->nhlfe[0]);
|
||||
del_adj_sid(srl->nhlfe[1]);
|
||||
listnode_delete(srn->ext_link, srl);
|
||||
XFREE(MTYPE_OSPF_SR_PARAMS, srl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update Segment Routing from Extended Prefix LSA */
|
||||
void ospf_sr_ext_prefix_lsa_update(struct ospf_lsa *lsa)
|
||||
{
|
||||
@ -1700,7 +1827,6 @@ DEFUN (no_ospf_sr_enable,
|
||||
|
||||
/* Finally, stop Segment Routing */
|
||||
ospf_sr_stop();
|
||||
OspfSR.enabled = false;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
@ -312,6 +312,10 @@ extern void ospf_sr_ext_link_lsa_update(struct ospf_lsa *lsa);
|
||||
extern void ospf_sr_ext_link_lsa_delete(struct ospf_lsa *lsa);
|
||||
extern void ospf_sr_ext_prefix_lsa_update(struct ospf_lsa *lsa);
|
||||
extern void ospf_sr_ext_prefix_lsa_delete(struct ospf_lsa *lsa);
|
||||
/* Segment Routing Extending Link management */
|
||||
struct ext_itf;
|
||||
extern void ospf_sr_ext_itf_add(struct ext_itf *exti);
|
||||
extern void ospf_sr_ext_itf_delete(struct ext_itf *exti);
|
||||
/* Segment Routing configuration functions */
|
||||
extern uint32_t get_ext_link_label_value(void);
|
||||
extern void ospf_sr_config_write_router(struct vty *vty);
|
||||
|
Loading…
Reference in New Issue
Block a user