diff options
Diffstat (limited to 'ospfd/ospf_sr.c')
| -rw-r--r-- | ospfd/ospf_sr.c | 112 |
1 files changed, 89 insertions, 23 deletions
diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index e2218957d2..7b2d794214 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -159,6 +159,16 @@ static struct sr_node *sr_node_new(struct in_addr *rid) return new; } +/* Supposed to be used for testing */ +struct sr_node *ospf_sr_node_create(struct in_addr *rid) +{ + struct sr_node *srn; + + srn = hash_get(OspfSR.neighbors, (void *)rid, (void *)sr_node_new); + + return srn; +} + /* Delete Segment Routing node */ static void sr_node_del(struct sr_node *srn) { @@ -588,11 +598,6 @@ int ospf_sr_init(void) if (OspfSR.neighbors == NULL) return rc; - /* Initialize Route Table for prefix */ - OspfSR.prefix = route_table_init(); - if (OspfSR.prefix == NULL) - return rc; - /* Register Segment Routing VTY command */ ospf_sr_register_vty(); @@ -616,9 +621,6 @@ void ospf_sr_term(void) if (OspfSR.neighbors) hash_free(OspfSR.neighbors); - /* Clear Prefix Table */ - if (OspfSR.prefix) - route_table_finish(OspfSR.prefix); } /* @@ -653,6 +655,56 @@ static mpls_label_t index2label(uint32_t index, struct sr_block srgb) return label; } +/* Get the prefix sid for a specific router id */ +mpls_label_t ospf_sr_get_prefix_sid_by_id(struct in_addr *id) +{ + struct sr_node *srn; + struct sr_prefix *srp; + mpls_label_t label; + + srn = (struct sr_node *)hash_lookup(OspfSR.neighbors, id); + + if (srn) { + /* + * TODO: Here we assume that the SRGBs are the same, + * and that the node's prefix SID is at the head of + * the list, probably needs tweaking. + */ + srp = listnode_head(srn->ext_prefix); + label = index2label(srp->sid, srn->srgb); + } else { + label = MPLS_INVALID_LABEL; + } + + return label; +} + +/* Get the adjacency sid for a specific 'root' id and 'neighbor' id */ +mpls_label_t ospf_sr_get_adj_sid_by_id(struct in_addr *root_id, + struct in_addr *neighbor_id) +{ + struct sr_node *srn; + struct sr_link *srl; + mpls_label_t label; + struct listnode *node; + + srn = (struct sr_node *)hash_lookup(OspfSR.neighbors, root_id); + + label = MPLS_INVALID_LABEL; + + if (srn) { + for (ALL_LIST_ELEMENTS_RO(srn->ext_link, node, srl)) { + if (srl->type == ADJ_SID + && srl->remote_id.s_addr == neighbor_id->s_addr) { + label = srl->sid[0]; + break; + } + } + } + + return label; +} + /* Get neighbor full structure from address */ static struct ospf_neighbor *get_neighbor_by_addr(struct ospf *top, struct in_addr addr) @@ -853,8 +905,13 @@ static int compute_prefix_nhlfe(struct sr_prefix *srp) * be received before corresponding Router Information LSA */ if (srnext == NULL || srnext->srgb.lower_bound == 0 - || srnext->srgb.range_size == 0) + || srnext->srgb.range_size == 0) { + osr_debug( + " |- SR-Node %pI4 not ready. Stop process", + &srnext->adv_router); + path->srni.label_out = MPLS_INVALID_LABEL; continue; + } osr_debug(" |- Found SRGB %u/%u for next hop SR-Node %pI4", srnext->srgb.range_size, srnext->srgb.lower_bound, @@ -1213,7 +1270,7 @@ static void update_in_nhlfe(struct hash_bucket *bucket, void *args) /* * When SRGB has changed, update NHLFE Output Label for all Extended Prefix - * with SID index which use the given SR-Node as nexthop though hash_iterate() + * with SID index which use the given SR-Node as nexthop through hash_iterate() */ static void update_out_nhlfe(struct hash_bucket *bucket, void *args) { @@ -1223,21 +1280,29 @@ static void update_out_nhlfe(struct hash_bucket *bucket, void *args) struct sr_prefix *srp; struct ospf_path *path; + /* Skip Self SR-Node */ + if (srn == OspfSR.self) + return; + + osr_debug("SR (%s): Update Out NHLFE for neighbor SR-Node %pI4", + __func__, &srn->adv_router); + for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp)) { - /* Process only SID Index with valid route */ + /* Skip Prefix that has not yet a valid route */ if (srp->route == NULL) continue; for (ALL_LIST_ELEMENTS_RO(srp->route->paths, pnode, path)) { - /* Process only SID Index for next hop without PHP */ - if ((path->srni.nexthop == srp->srn) - && (!CHECK_FLAG(srp->flags, - EXT_SUBTLV_PREFIX_SID_NPFLG))) + /* Skip path that has not next SR-Node as nexthop */ + if (path->srni.nexthop != srnext) continue; - path->srni.label_out = - index2label(srp->sid, srnext->srgb); - ospf_zebra_update_prefix_sid(srp); + + /* Compute new Output Label */ + path->srni.label_out = sr_prefix_out_label(srp, srnext); } + + /* Finally update MPLS table */ + ospf_zebra_update_prefix_sid(srp); } } @@ -1378,11 +1443,6 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa) srn->srlb.lower_bound = GET_LABEL(ntohl(ri_srlb->lower.value)); } - osr_debug(" |- Update SR-Node[%pI4], SRGB[%u/%u], SRLB[%u/%u], Algo[%u], MSD[%u]", - &srn->adv_router, srn->srgb.lower_bound, srn->srgb.range_size, - srn->srlb.lower_bound, srn->srlb.range_size, srn->algo[0], - srn->msd); - /* Check if SRGB has changed */ if ((srn->srgb.range_size == srgb.range_size) && (srn->srgb.lower_bound == srgb.lower_bound)) @@ -1392,6 +1452,11 @@ void ospf_sr_ri_lsa_update(struct ospf_lsa *lsa) srn->srgb.range_size = srgb.range_size; srn->srgb.lower_bound = srgb.lower_bound; + osr_debug(" |- Update SR-Node[%pI4], SRGB[%u/%u], SRLB[%u/%u], Algo[%u], MSD[%u]", + &srn->adv_router, srn->srgb.lower_bound, srn->srgb.range_size, + srn->srlb.lower_bound, srn->srlb.range_size, srn->algo[0], + srn->msd); + /* ... and NHLFE if it is a neighbor SR node */ if (srn->neighbor == OspfSR.self) hash_iterate(OspfSR.neighbors, update_out_nhlfe, srn); @@ -1562,6 +1627,7 @@ void ospf_sr_ext_itf_add(struct ext_itf *exti) srl->itf_addr = exti->link.link_data; srl->instance = SET_OPAQUE_LSID(OPAQUE_TYPE_EXTENDED_LINK_LSA, exti->instance); + srl->remote_id = exti->link.link_id; switch (exti->stype) { case ADJ_SID: srl->type = ADJ_SID; |
