summaryrefslogtreecommitdiffstats
path: root/zebra/zebra_mpls.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_mpls.c')
-rw-r--r--zebra/zebra_mpls.c4393
1 files changed, 2107 insertions, 2286 deletions
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 3c8503878..e44e5d2e6 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -45,12 +45,12 @@
#include "zebra/zebra_vrf.h"
#include "zebra/zebra_mpls.h"
-DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object")
-DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object")
-DEFINE_MTYPE_STATIC(ZEBRA, SLSP, "MPLS static LSP config")
-DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object")
-DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE, "MPLS static nexthop object")
-DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME, "MPLS static nexthop ifname")
+DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object")
+DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object")
+DEFINE_MTYPE_STATIC(ZEBRA, SLSP, "MPLS static LSP config")
+DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object")
+DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE, "MPLS static nexthop object")
+DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME, "MPLS static nexthop ifname")
int mpls_enabled;
@@ -59,106 +59,72 @@ extern struct zebra_t zebrad;
/* static function declarations */
-static void
-fec_evaluate (struct zebra_vrf *zvrf);
-static u_int32_t
-fec_derive_label_from_index (struct zebra_vrf *vrf, zebra_fec_t *fec);
-static int
-lsp_install (struct zebra_vrf *zvrf, mpls_label_t label,
- struct route_node *rn, struct route_entry *re);
-static int
-lsp_uninstall (struct zebra_vrf *zvrf, mpls_label_t label);
-static int
-fec_change_update_lsp (struct zebra_vrf *zvrf, zebra_fec_t *fec, mpls_label_t old_label);
-static int
-fec_send (zebra_fec_t *fec, struct zserv *client);
-static void
-fec_update_clients (zebra_fec_t *fec);
-static void
-fec_print (zebra_fec_t *fec, struct vty *vty);
-static zebra_fec_t *
-fec_find (struct route_table *table, struct prefix *p);
-static zebra_fec_t *
-fec_add (struct route_table *table, struct prefix *p, mpls_label_t label,
- u_int32_t flags, u_int32_t label_index);
-static int
-fec_del (zebra_fec_t *fec);
-
-static unsigned int
-label_hash (void *p);
-static int
-label_cmp (const void *p1, const void *p2);
-static int
-nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop);
-static int
-nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop);
-static int
-nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe);
-
-static void
-lsp_select_best_nhlfe (zebra_lsp_t *lsp);
-static void
-lsp_uninstall_from_kernel (struct hash_backet *backet, void *ctxt);
-static void
-lsp_schedule (struct hash_backet *backet, void *ctxt);
-static wq_item_status
-lsp_process (struct work_queue *wq, void *data);
-static void
-lsp_processq_del (struct work_queue *wq, void *data);
-static void
-lsp_processq_complete (struct work_queue *wq);
-static int
-lsp_processq_add (zebra_lsp_t *lsp);
-static void *
-lsp_alloc (void *p);
-
-static char *
-nhlfe2str (zebra_nhlfe_t *nhlfe, char *buf, int size);
-static int
-nhlfe_nhop_match (zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
- union g_addr *gate, ifindex_t ifindex);
-static zebra_nhlfe_t *
-nhlfe_find (zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
- enum nexthop_types_t gtype, union g_addr *gate,
- ifindex_t ifindex);
-static zebra_nhlfe_t *
-nhlfe_add (zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
- enum nexthop_types_t gtype, union g_addr *gate,
- ifindex_t ifindex, mpls_label_t out_label);
-static int
-nhlfe_del (zebra_nhlfe_t *snhlfe);
-static void
-nhlfe_out_label_update (zebra_nhlfe_t *nhlfe, struct nexthop_label *nh_label);
-static int
-mpls_lsp_uninstall_all (struct hash *lsp_table, zebra_lsp_t *lsp,
- enum lsp_types_t type);
-static int
-mpls_static_lsp_uninstall_all (struct zebra_vrf *zvrf, mpls_label_t in_label);
-static void
-nhlfe_print (zebra_nhlfe_t *nhlfe, struct vty *vty);
-static void
-lsp_print (zebra_lsp_t *lsp, void *ctxt);
-static void *
-slsp_alloc (void *p);
-static int
-snhlfe_match (zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
- union g_addr *gate, ifindex_t ifindex);
-static zebra_snhlfe_t *
-snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype,
- union g_addr *gate, ifindex_t ifindex);
-static zebra_snhlfe_t *
-snhlfe_add (zebra_slsp_t *slsp, enum nexthop_types_t gtype,
- union g_addr *gate, ifindex_t ifindex, mpls_label_t out_label);
-static int
-snhlfe_del (zebra_snhlfe_t *snhlfe);
-static int
-snhlfe_del_all (zebra_slsp_t *slsp);
-static char *
-snhlfe2str (zebra_snhlfe_t *snhlfe, char *buf, int size);
-static int
-mpls_processq_init (struct zebra_t *zebra);
-
-
+static void fec_evaluate(struct zebra_vrf *zvrf);
+static u_int32_t fec_derive_label_from_index(struct zebra_vrf *vrf,
+ zebra_fec_t *fec);
+static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
+ struct route_node *rn, struct route_entry *re);
+static int lsp_uninstall(struct zebra_vrf *zvrf, mpls_label_t label);
+static int fec_change_update_lsp(struct zebra_vrf *zvrf, zebra_fec_t *fec,
+ mpls_label_t old_label);
+static int fec_send(zebra_fec_t *fec, struct zserv *client);
+static void fec_update_clients(zebra_fec_t *fec);
+static void fec_print(zebra_fec_t *fec, struct vty *vty);
+static zebra_fec_t *fec_find(struct route_table *table, struct prefix *p);
+static zebra_fec_t *fec_add(struct route_table *table, struct prefix *p,
+ mpls_label_t label, u_int32_t flags,
+ u_int32_t label_index);
+static int fec_del(zebra_fec_t *fec);
+
+static unsigned int label_hash(void *p);
+static int label_cmp(const void *p1, const void *p2);
+static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe,
+ struct nexthop *nexthop);
+static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe,
+ struct nexthop *nexthop);
+static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe);
+
+static void lsp_select_best_nhlfe(zebra_lsp_t *lsp);
+static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt);
+static void lsp_schedule(struct hash_backet *backet, void *ctxt);
+static wq_item_status lsp_process(struct work_queue *wq, void *data);
+static void lsp_processq_del(struct work_queue *wq, void *data);
+static void lsp_processq_complete(struct work_queue *wq);
+static int lsp_processq_add(zebra_lsp_t *lsp);
+static void *lsp_alloc(void *p);
+
+static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size);
+static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex);
+static zebra_nhlfe_t *nhlfe_find(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
+ enum nexthop_types_t gtype, union g_addr *gate,
+ ifindex_t ifindex);
+static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
+ enum nexthop_types_t gtype, union g_addr *gate,
+ ifindex_t ifindex, mpls_label_t out_label);
+static int nhlfe_del(zebra_nhlfe_t *snhlfe);
+static void nhlfe_out_label_update(zebra_nhlfe_t *nhlfe,
+ struct nexthop_label *nh_label);
+static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
+ enum lsp_types_t type);
+static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf,
+ mpls_label_t in_label);
+static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty);
+static void lsp_print(zebra_lsp_t *lsp, void *ctxt);
+static void *slsp_alloc(void *p);
+static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex);
+static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp,
+ enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex);
+static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp,
+ enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex,
+ mpls_label_t out_label);
+static int snhlfe_del(zebra_snhlfe_t *snhlfe);
+static int snhlfe_del_all(zebra_slsp_t *slsp);
+static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size);
+static int mpls_processq_init(struct zebra_t *zebra);
/* Static functions */
@@ -166,189 +132,175 @@ mpls_processq_init (struct zebra_t *zebra);
/*
* Install label forwarding entry based on labeled-route entry.
*/
-static int
-lsp_install (struct zebra_vrf *zvrf, mpls_label_t label,
- struct route_node *rn, struct route_entry *re)
-{
- struct hash *lsp_table;
- zebra_ile_t tmp_ile;
- zebra_lsp_t *lsp;
- zebra_nhlfe_t *nhlfe;
- struct nexthop *nexthop;
- enum lsp_types_t lsp_type;
- char buf[BUFSIZ];
- int added, changed;
-
- /* Lookup table. */
- lsp_table = zvrf->lsp_table;
- if (!lsp_table)
- return -1;
-
- lsp_type = lsp_type_from_re_type (re->type);
- added = changed = 0;
-
- /* Locate or allocate LSP entry. */
- tmp_ile.in_label = label;
- lsp = hash_get (lsp_table, &tmp_ile, lsp_alloc);
- if (!lsp)
- return -1;
-
- /* For each active nexthop, create NHLFE. Note that we deliberately skip
- * recursive nexthops right now, because intermediate hops won't understand
- * the label advertised by the recursive nexthop (plus we don't have the
- * logic yet to push multiple labels).
- */
- for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
- {
- /* Skip inactive and recursive entries. */
- if (!CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
- continue;
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
- continue;
-
- nhlfe = nhlfe_find (lsp, lsp_type, nexthop->type, &nexthop->gate,
- nexthop->ifindex);
- if (nhlfe)
- {
- /* Clear deleted flag (in case it was set) */
- UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED);
- if (nexthop_labels_match (nhlfe->nexthop, nexthop))
- /* No change */
- continue;
-
-
- if (IS_ZEBRA_DEBUG_MPLS)
- {
- nhlfe2str (nhlfe, buf, BUFSIZ);
- zlog_debug ("LSP in-label %u type %d nexthop %s "
- "out-label changed",
- lsp->ile.in_label, lsp_type, buf);
- }
-
- /* Update out label, trigger processing. */
- nhlfe_out_label_update (nhlfe, nexthop->nh_label);
- SET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED);
- changed++;
- }
- else
- {
- /* Add LSP entry to this nexthop */
- nhlfe = nhlfe_add (lsp, lsp_type, nexthop->type,
- &nexthop->gate, nexthop->ifindex,
- nexthop->nh_label->label[0]);
- if (!nhlfe)
- return -1;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- {
- nhlfe2str (nhlfe, buf, BUFSIZ);
- zlog_debug ("Add LSP in-label %u type %d nexthop %s "
- "out-label %u",
- lsp->ile.in_label, lsp_type, buf,
- nexthop->nh_label->label[0]);
- }
-
- lsp->addr_family = NHLFE_FAMILY (nhlfe);
-
- /* Mark NHLFE as changed. */
- SET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED);
- added++;
- }
- }
-
- /* Queue LSP for processing if necessary. If no NHLFE got added (special
- * case), delete the LSP entry; this case results in somewhat ugly logging.
- */
- if (added || changed)
- {
- if (lsp_processq_add (lsp))
- return -1;
- }
- else if (!lsp->nhlfe_list &&
- !CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED))
- {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug ("Free LSP in-label %u flags 0x%x",
- lsp->ile.in_label, lsp->flags);
-
- lsp = hash_release(lsp_table, &lsp->ile);
- if (lsp)
- XFREE(MTYPE_LSP, lsp);
- }
-
- return 0;
+static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
+ struct route_node *rn, struct route_entry *re)
+{
+ struct hash *lsp_table;
+ zebra_ile_t tmp_ile;
+ zebra_lsp_t *lsp;
+ zebra_nhlfe_t *nhlfe;
+ struct nexthop *nexthop;
+ enum lsp_types_t lsp_type;
+ char buf[BUFSIZ];
+ int added, changed;
+
+ /* Lookup table. */
+ lsp_table = zvrf->lsp_table;
+ if (!lsp_table)
+ return -1;
+
+ lsp_type = lsp_type_from_re_type(re->type);
+ added = changed = 0;
+
+ /* Locate or allocate LSP entry. */
+ tmp_ile.in_label = label;
+ lsp = hash_get(lsp_table, &tmp_ile, lsp_alloc);
+ if (!lsp)
+ return -1;
+
+ /* For each active nexthop, create NHLFE. Note that we deliberately skip
+ * recursive nexthops right now, because intermediate hops won't
+ * understand
+ * the label advertised by the recursive nexthop (plus we don't have the
+ * logic yet to push multiple labels).
+ */
+ for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) {
+ /* Skip inactive and recursive entries. */
+ if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ continue;
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
+ continue;
+
+ nhlfe = nhlfe_find(lsp, lsp_type, nexthop->type, &nexthop->gate,
+ nexthop->ifindex);
+ if (nhlfe) {
+ /* Clear deleted flag (in case it was set) */
+ UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED);
+ if (nexthop_labels_match(nhlfe->nexthop, nexthop))
+ /* No change */
+ continue;
+
+
+ if (IS_ZEBRA_DEBUG_MPLS) {
+ nhlfe2str(nhlfe, buf, BUFSIZ);
+ zlog_debug(
+ "LSP in-label %u type %d nexthop %s "
+ "out-label changed",
+ lsp->ile.in_label, lsp_type, buf);
+ }
+
+ /* Update out label, trigger processing. */
+ nhlfe_out_label_update(nhlfe, nexthop->nh_label);
+ SET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED);
+ changed++;
+ } else {
+ /* Add LSP entry to this nexthop */
+ nhlfe = nhlfe_add(lsp, lsp_type, nexthop->type,
+ &nexthop->gate, nexthop->ifindex,
+ nexthop->nh_label->label[0]);
+ if (!nhlfe)
+ return -1;
+
+ if (IS_ZEBRA_DEBUG_MPLS) {
+ nhlfe2str(nhlfe, buf, BUFSIZ);
+ zlog_debug(
+ "Add LSP in-label %u type %d nexthop %s "
+ "out-label %u",
+ lsp->ile.in_label, lsp_type, buf,
+ nexthop->nh_label->label[0]);
+ }
+
+ lsp->addr_family = NHLFE_FAMILY(nhlfe);
+
+ /* Mark NHLFE as changed. */
+ SET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED);
+ added++;
+ }
+ }
+
+ /* Queue LSP for processing if necessary. If no NHLFE got added (special
+ * case), delete the LSP entry; this case results in somewhat ugly
+ * logging.
+ */
+ if (added || changed) {
+ if (lsp_processq_add(lsp))
+ return -1;
+ } else if (!lsp->nhlfe_list
+ && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("Free LSP in-label %u flags 0x%x",
+ lsp->ile.in_label, lsp->flags);
+
+ lsp = hash_release(lsp_table, &lsp->ile);
+ if (lsp)
+ XFREE(MTYPE_LSP, lsp);
+ }
+
+ return 0;
}
/*
* Uninstall all non-static NHLFEs of a label forwarding entry. If all
* NHLFEs are removed, the entire entry is deleted.
*/
-static int
-lsp_uninstall (struct zebra_vrf *zvrf, mpls_label_t label)
-{
- struct hash *lsp_table;
- zebra_ile_t tmp_ile;
- zebra_lsp_t *lsp;
- zebra_nhlfe_t *nhlfe, *nhlfe_next;
- char buf[BUFSIZ];
-
- /* Lookup table. */
- lsp_table = zvrf->lsp_table;
- if (!lsp_table)
- return -1;
-
- /* If entry is not present, exit. */
- tmp_ile.in_label = label;
- lsp = hash_lookup (lsp_table, &tmp_ile);
- if (!lsp || !lsp->nhlfe_list)
- return 0;
-
- /* Mark NHLFEs for delete or directly delete, as appropriate. */
- for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next)
- {
- nhlfe_next = nhlfe->next;
-
- /* Skip static NHLFEs */
- if (nhlfe->type == ZEBRA_LSP_STATIC)
- continue;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- {
- nhlfe2str (nhlfe, buf, BUFSIZ);
- zlog_debug ("Del LSP in-label %u type %d nexthop %s flags 0x%x",
- label, nhlfe->type, buf, nhlfe->flags);
- }
-
- if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED))
- {
- UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED);
- SET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED);
- }
- else
- {
- nhlfe_del (nhlfe);
- }
- }
-
- /* Queue LSP for processing, if needed, else delete. */
- if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
- {
- if (lsp_processq_add (lsp))
- return -1;
- }
- else if (!lsp->nhlfe_list &&
- !CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED))
- {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug ("Del LSP in-label %u flags 0x%x",
- lsp->ile.in_label, lsp->flags);
-
- lsp = hash_release(lsp_table, &lsp->ile);
- if (lsp)
- XFREE(MTYPE_LSP, lsp);
- }
-
- return 0;
+static int lsp_uninstall(struct zebra_vrf *zvrf, mpls_label_t label)
+{
+ struct hash *lsp_table;
+ zebra_ile_t tmp_ile;
+ zebra_lsp_t *lsp;
+ zebra_nhlfe_t *nhlfe, *nhlfe_next;
+ char buf[BUFSIZ];
+
+ /* Lookup table. */
+ lsp_table = zvrf->lsp_table;
+ if (!lsp_table)
+ return -1;
+
+ /* If entry is not present, exit. */
+ tmp_ile.in_label = label;
+ lsp = hash_lookup(lsp_table, &tmp_ile);
+ if (!lsp || !lsp->nhlfe_list)
+ return 0;
+
+ /* Mark NHLFEs for delete or directly delete, as appropriate. */
+ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) {
+ nhlfe_next = nhlfe->next;
+
+ /* Skip static NHLFEs */
+ if (nhlfe->type == ZEBRA_LSP_STATIC)
+ continue;
+
+ if (IS_ZEBRA_DEBUG_MPLS) {
+ nhlfe2str(nhlfe, buf, BUFSIZ);
+ zlog_debug(
+ "Del LSP in-label %u type %d nexthop %s flags 0x%x",
+ label, nhlfe->type, buf, nhlfe->flags);
+ }
+
+ if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED)) {
+ UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED);
+ SET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED);
+ } else {
+ nhlfe_del(nhlfe);
+ }
+ }
+
+ /* Queue LSP for processing, if needed, else delete. */
+ if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) {
+ if (lsp_processq_add(lsp))
+ return -1;
+ } else if (!lsp->nhlfe_list
+ && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("Del LSP in-label %u flags 0x%x",
+ lsp->ile.in_label, lsp->flags);
+
+ lsp = hash_release(lsp_table, &lsp->ile);
+ if (lsp)
+ XFREE(MTYPE_LSP, lsp);
+ }
+
+ return 0;
}
/*
@@ -356,54 +308,55 @@ lsp_uninstall (struct zebra_vrf *zvrf, mpls_label_t label)
* will walk all registered FECs with label-index and appropriately update
* their local labels and trigger client updates.
*/
-static void
-fec_evaluate (struct zebra_vrf *zvrf)
-{
- struct route_node *rn;
- zebra_fec_t *fec;
- u_int32_t old_label, new_label;
- int af;
- char buf[BUFSIZ];
-
- for (af = AFI_IP; af < AFI_MAX; af++)
- {
- if (zvrf->fec_table[af] == NULL)
- continue;
-
- for (rn = route_top(zvrf->fec_table[af]); rn; rn = route_next(rn))
- {
- if ((fec = rn->info) == NULL)
- continue;
-
- /* Skip configured FECs and those without a label index. */
- if (fec->flags & FEC_FLAG_CONFIGURED ||
- fec->label_index == MPLS_INVALID_LABEL_INDEX)
- continue;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- prefix2str(&rn->p, buf, BUFSIZ);
-
- /* Save old label, determine new label. */
- old_label = fec->label;
- new_label = zvrf->mpls_srgb.start_label + fec->label_index;
- if (new_label >= zvrf->mpls_srgb.end_label)
- new_label = MPLS_INVALID_LABEL;
-
- /* If label has changed, update FEC and clients. */
- if (new_label == old_label)
- continue;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug ("Update fec %s new label %u upon label block",
- buf, new_label);
-
- fec->label = new_label;
- fec_update_clients (fec);
-
- /* Update label forwarding entries appropriately */
- fec_change_update_lsp (zvrf, fec, old_label);
- }
- }
+static void fec_evaluate(struct zebra_vrf *zvrf)
+{
+ struct route_node *rn;
+ zebra_fec_t *fec;
+ u_int32_t old_label, new_label;
+ int af;
+ char buf[BUFSIZ];
+
+ for (af = AFI_IP; af < AFI_MAX; af++) {
+ if (zvrf->fec_table[af] == NULL)
+ continue;
+
+ for (rn = route_top(zvrf->fec_table[af]); rn;
+ rn = route_next(rn)) {
+ if ((fec = rn->info) == NULL)
+ continue;
+
+ /* Skip configured FECs and those without a label index.
+ */
+ if (fec->flags & FEC_FLAG_CONFIGURED
+ || fec->label_index == MPLS_INVALID_LABEL_INDEX)
+ continue;
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ prefix2str(&rn->p, buf, BUFSIZ);
+
+ /* Save old label, determine new label. */
+ old_label = fec->label;
+ new_label =
+ zvrf->mpls_srgb.start_label + fec->label_index;
+ if (new_label >= zvrf->mpls_srgb.end_label)
+ new_label = MPLS_INVALID_LABEL;
+
+ /* If label has changed, update FEC and clients. */
+ if (new_label == old_label)
+ continue;
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug(
+ "Update fec %s new label %u upon label block",
+ buf, new_label);
+
+ fec->label = new_label;
+ fec_update_clients(fec);
+
+ /* Update label forwarding entries appropriately */
+ fec_change_update_lsp(zvrf, fec, old_label);
+ }
+ }
}
/*
@@ -411,195 +364,188 @@ fec_evaluate (struct zebra_vrf *zvrf)
* its label index. The index is "acceptable" if it falls within the
* globally configured label block (SRGB).
*/
-static u_int32_t
-fec_derive_label_from_index (struct zebra_vrf *zvrf, zebra_fec_t *fec)
+static u_int32_t fec_derive_label_from_index(struct zebra_vrf *zvrf,
+ zebra_fec_t *fec)
{
- u_int32_t label;
+ u_int32_t label;
- if (fec->label_index != MPLS_INVALID_LABEL_INDEX &&
- zvrf->mpls_srgb.start_label &&
- ((label = zvrf->mpls_srgb.start_label + fec->label_index) <
- zvrf->mpls_srgb.end_label))
- fec->label = label;
- else
- fec->label = MPLS_INVALID_LABEL;
+ if (fec->label_index != MPLS_INVALID_LABEL_INDEX
+ && zvrf->mpls_srgb.start_label
+ && ((label = zvrf->mpls_srgb.start_label + fec->label_index)
+ < zvrf->mpls_srgb.end_label))
+ fec->label = label;
+ else
+ fec->label = MPLS_INVALID_LABEL;
- return fec->label;
+ return fec->label;
}
/*
* There is a change for this FEC. Install or uninstall label forwarding
* entries, as appropriate.
*/
-static int
-fec_change_update_lsp (struct zebra_vrf *zvrf, zebra_fec_t *fec, mpls_label_t old_label)
+static int fec_change_update_lsp(struct zebra_vrf *zvrf, zebra_fec_t *fec,
+ mpls_label_t old_label)
{
- struct route_table *table;
- struct route_node *rn;
- struct route_entry *re;
- afi_t afi;
+ struct route_table *table;
+ struct route_node *rn;
+ struct route_entry *re;
+ afi_t afi;
- /* Uninstall label forwarding entry, if previously installed. */
- if (old_label != MPLS_INVALID_LABEL &&
- old_label != MPLS_IMP_NULL_LABEL)
- lsp_uninstall (zvrf, old_label);
+ /* Uninstall label forwarding entry, if previously installed. */
+ if (old_label != MPLS_INVALID_LABEL && old_label != MPLS_IMP_NULL_LABEL)
+ lsp_uninstall(zvrf, old_label);
- /* Install label forwarding entry corr. to new label, if needed. */
- if (fec->label == MPLS_INVALID_LABEL ||
- fec->label == MPLS_IMP_NULL_LABEL)
- return 0;
+ /* Install label forwarding entry corr. to new label, if needed. */
+ if (fec->label == MPLS_INVALID_LABEL
+ || fec->label == MPLS_IMP_NULL_LABEL)
+ return 0;
- afi = family2afi(PREFIX_FAMILY(&fec->rn->p));
- table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf_id (zvrf));
- if (!table)
- return 0;
+ afi = family2afi(PREFIX_FAMILY(&fec->rn->p));
+ table = zebra_vrf_table(afi, SAFI_UNICAST, zvrf_id(zvrf));
+ if (!table)
+ return 0;
- /* See if labeled route exists. */
- rn = route_node_lookup (table, &fec->rn->p);
- if (!rn)
- return 0;
+ /* See if labeled route exists. */
+ rn = route_node_lookup(table, &fec->rn->p);
+ if (!rn)
+ return 0;
- RNODE_FOREACH_RE (rn, re)
- {
- if (CHECK_FLAG (re->flags, ZEBRA_FLAG_SELECTED))
- break;
- }
+ RNODE_FOREACH_RE(rn, re)
+ {
+ if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED))
+ break;
+ }
- if (!re || !zebra_rib_labeled_unicast (re))
- return 0;
+ if (!re || !zebra_rib_labeled_unicast(re))
+ return 0;
- if (lsp_install (zvrf, fec->label, rn, re))
- return -1;
+ if (lsp_install(zvrf, fec->label, rn, re))
+ return -1;
- return 0;
+ return 0;
}
/*
* Inform about FEC to a registered client.
*/
-static int
-fec_send (zebra_fec_t *fec, struct zserv *client)
+static int fec_send(zebra_fec_t *fec, struct zserv *client)
{
- struct stream *s;
- struct route_node *rn;
+ struct stream *s;
+ struct route_node *rn;
- rn = fec->rn;
+ rn = fec->rn;
- /* Get output stream. */
- s = client->obuf;
- stream_reset (s);
+ /* Get output stream. */
+ s = client->obuf;
+ stream_reset(s);
- zserv_create_header (s, ZEBRA_FEC_UPDATE, VRF_DEFAULT);
+ zserv_create_header(s, ZEBRA_FEC_UPDATE, VRF_DEFAULT);
- stream_putw(s, rn->p.family);
- stream_put_prefix (s, &rn->p);
- stream_putl(s, fec->label);
- stream_putw_at(s, 0, stream_get_endp(s));
- return zebra_server_send_message(client);
+ stream_putw(s, rn->p.family);
+ stream_put_prefix(s, &rn->p);
+ stream_putl(s, fec->label);
+ stream_putw_at(s, 0, stream_get_endp(s));
+ return zebra_server_send_message(client);
}
/*
* Update all registered clients about this FEC. Caller should've updated
* FEC and ensure no duplicate updates.
*/
-static void
-fec_update_clients (zebra_fec_t *fec)
+static void fec_update_clients(zebra_fec_t *fec)
{
- struct listnode *node;
- struct zserv *client;
+ struct listnode *node;
+ struct zserv *client;
- for (ALL_LIST_ELEMENTS_RO(fec->client_list, node, client))
- {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug ("Update client %s", zebra_route_string(client->proto));
- fec_send(fec, client);
- }
+ for (ALL_LIST_ELEMENTS_RO(fec->client_list, node, client)) {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("Update client %s",
+ zebra_route_string(client->proto));
+ fec_send(fec, client);
+ }
}
/*
* Print a FEC-label binding entry.
*/
-static void
-fec_print (zebra_fec_t *fec, struct vty *vty)
-{
- struct route_node *rn;
- struct listnode *node;
- struct zserv *client;
- char buf[BUFSIZ];
-
- rn = fec->rn;
- prefix2str(&rn->p, buf, BUFSIZ);
- vty_out (vty, "%s\n", buf);
- vty_out(vty, " Label: %s", label2str(fec->label, buf, BUFSIZ));
- if (fec->label_index != MPLS_INVALID_LABEL_INDEX)
- vty_out(vty, ", Label Index: %u", fec->label_index);
- vty_out (vty, "\n");
- if (!list_isempty(fec->client_list))
- {
- vty_out(vty, " Client list:");
- for (ALL_LIST_ELEMENTS_RO(fec->client_list, node, client))
- vty_out(vty, " %s(fd %d)",
- zebra_route_string(client->proto), client->sock);
- vty_out (vty, "\n");
- }
+static void fec_print(zebra_fec_t *fec, struct vty *vty)
+{
+ struct route_node *rn;
+ struct listnode *node;
+ struct zserv *client;
+ char buf[BUFSIZ];
+
+ rn = fec->rn;
+ prefix2str(&rn->p, buf, BUFSIZ);
+ vty_out(vty, "%s\n", buf);
+ vty_out(vty, " Label: %s", label2str(fec->label, buf, BUFSIZ));
+ if (fec->label_index != MPLS_INVALID_LABEL_INDEX)
+ vty_out(vty, ", Label Index: %u", fec->label_index);
+ vty_out(vty, "\n");
+ if (!list_isempty(fec->client_list)) {
+ vty_out(vty, " Client list:");
+ for (ALL_LIST_ELEMENTS_RO(fec->client_list, node, client))
+ vty_out(vty, " %s(fd %d)",
+ zebra_route_string(client->proto),
+ client->sock);
+ vty_out(vty, "\n");
+ }
}
/*
* Locate FEC-label binding that matches with passed info.
*/
-static zebra_fec_t *
-fec_find (struct route_table *table, struct prefix *p)
+static zebra_fec_t *fec_find(struct route_table *table, struct prefix *p)
{
- struct route_node *rn;
+ struct route_node *rn;
- apply_mask (p);
- rn = route_node_lookup(table, p);
- if (!rn)
- return NULL;
+ apply_mask(p);
+ rn = route_node_lookup(table, p);
+ if (!rn)
+ return NULL;
- route_unlock_node(rn);
- return (rn->info);
+ route_unlock_node(rn);
+ return (rn->info);
}
/*
* Add a FEC. This may be upon a client registering for a binding
* or when a binding is configured.
*/
-static zebra_fec_t *
-fec_add (struct route_table *table, struct prefix *p,
- mpls_label_t label, u_int32_t flags, u_int32_t label_index)
+static zebra_fec_t *fec_add(struct route_table *table, struct prefix *p,
+ mpls_label_t label, u_int32_t flags,
+ u_int32_t label_index)
{
- struct route_node *rn;
- zebra_fec_t *fec;
+ struct route_node *rn;
+ zebra_fec_t *fec;
- apply_mask (p);
+ apply_mask(p);
- /* Lookup (or add) route node.*/
- rn = route_node_get (table, p);
- if (!rn)
- return NULL;
+ /* Lookup (or add) route node.*/
+ rn = route_node_get(table, p);
+ if (!rn)
+ return NULL;
- fec = rn->info;
+ fec = rn->info;
- if (!fec)
- {
- fec = XCALLOC (MTYPE_FEC, sizeof(zebra_fec_t));
- if (!fec)
- return NULL;
+ if (!fec) {
+ fec = XCALLOC(MTYPE_FEC, sizeof(zebra_fec_t));
+ if (!fec)
+ return NULL;
- rn->info = fec;
- fec->rn = rn;
- fec->label = label;
- fec->client_list = list_new();
- }
- else
- route_unlock_node (rn); /* for the route_node_get */
+ rn->info = fec;
+ fec->rn = rn;
+ fec->label = label;
+ fec->client_list = list_new();
+ } else
+ route_unlock_node(rn); /* for the route_node_get */
- fec->label_index = label_index;
- fec->flags = flags;
+ fec->label_index = label_index;
+ fec->flags = flags;
- return fec;
+ return fec;
}
/*
@@ -607,37 +553,34 @@ fec_add (struct route_table *table, struct prefix *p,
* a FEC and no binding exists or when the binding is deleted and there
* are no registered clients.
*/
-static int
-fec_del (zebra_fec_t *fec)
+static int fec_del(zebra_fec_t *fec)
{
- list_free (fec->client_list);
- fec->rn->info = NULL;
- route_unlock_node (fec->rn);
- XFREE (MTYPE_FEC, fec);
- return 0;
+ list_free(fec->client_list);
+ fec->rn->info = NULL;
+ route_unlock_node(fec->rn);
+ XFREE(MTYPE_FEC, fec);
+ return 0;
}
/*
* Hash function for label.
*/
-static unsigned int
-label_hash (void *p)
+static unsigned int label_hash(void *p)
{
- const zebra_ile_t *ile = p;
+ const zebra_ile_t *ile = p;
- return (jhash_1word(ile->in_label, 0));
+ return (jhash_1word(ile->in_label, 0));
}
/*
* Compare 2 LSP hash entries based on in-label.
*/
-static int
-label_cmp (const void *p1, const void *p2)
+static int label_cmp(const void *p1, const void *p2)
{
- const zebra_ile_t *ile1 = p1;
- const zebra_ile_t *ile2 = p2;
+ const zebra_ile_t *ile1 = p1;
+ const zebra_ile_t *ile2 = p2;
- return (ile1->in_label == ile2->in_label);
+ return (ile1->in_label == ile2->in_label);
}
/*
@@ -645,50 +588,49 @@ label_cmp (const void *p1, const void *p2)
* the passed flag.
* NOTE: Looking only for connected routes right now.
*/
-static int
-nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
+static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe,
+ struct nexthop *nexthop)
{
- struct route_table *table;
- struct prefix_ipv4 p;
- struct route_node *rn;
- struct route_entry *match;
- struct nexthop *match_nh;
-
- table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
- if (!table)
- return 0;
+ struct route_table *table;
+ struct prefix_ipv4 p;
+ struct route_node *rn;
+ struct route_entry *match;
+ struct nexthop *match_nh;
- /* Lookup nexthop in IPv4 routing table. */
- memset (&p, 0, sizeof (struct prefix_ipv4));
- p.family = AF_INET;
- p.prefixlen = IPV4_MAX_PREFIXLEN;
- p.prefix = nexthop->gate.ipv4;
+ table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT);
+ if (!table)
+ return 0;
- rn = route_node_match (table, (struct prefix *) &p);
- if (!rn)
- return 0;
+ /* Lookup nexthop in IPv4 routing table. */
+ memset(&p, 0, sizeof(struct prefix_ipv4));
+ p.family = AF_INET;
+ p.prefixlen = IPV4_MAX_PREFIXLEN;
+ p.prefix = nexthop->gate.ipv4;
- route_unlock_node (rn);
+ rn = route_node_match(table, (struct prefix *)&p);
+ if (!rn)
+ return 0;
- /* Locate a valid connected route. */
- RNODE_FOREACH_RE (rn, match)
- {
- if (CHECK_FLAG (match->status, ROUTE_ENTRY_REMOVED) ||
- !CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
- continue;
+ route_unlock_node(rn);
- for (match_nh = match->nexthop; match_nh; match_nh = match_nh->next)
+ /* Locate a valid connected route. */
+ RNODE_FOREACH_RE(rn, match)
{
- if (match->type == ZEBRA_ROUTE_CONNECT ||
- nexthop->ifindex == match_nh->ifindex)
- {
- nexthop->ifindex = match_nh->ifindex;
- return 1;
- }
+ if (CHECK_FLAG(match->status, ROUTE_ENTRY_REMOVED)
+ || !CHECK_FLAG(match->flags, ZEBRA_FLAG_SELECTED))
+ continue;
+
+ for (match_nh = match->nexthop; match_nh;
+ match_nh = match_nh->next) {
+ if (match->type == ZEBRA_ROUTE_CONNECT
+ || nexthop->ifindex == match_nh->ifindex) {
+ nexthop->ifindex = match_nh->ifindex;
+ return 1;
+ }
+ }
}
- }
- return 0;
+ return 0;
}
@@ -697,44 +639,44 @@ nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
* the passed flag.
* NOTE: Looking only for connected routes right now.
*/
-static int
-nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
+static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe,
+ struct nexthop *nexthop)
{
- struct route_table *table;
- struct prefix_ipv6 p;
- struct route_node *rn;
- struct route_entry *match;
+ struct route_table *table;
+ struct prefix_ipv6 p;
+ struct route_node *rn;
+ struct route_entry *match;
- table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
- if (!table)
- return 0;
+ table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT);
+ if (!table)
+ return 0;
- /* Lookup nexthop in IPv6 routing table. */
- memset (&p, 0, sizeof (struct prefix_ipv6));
- p.family = AF_INET6;
- p.prefixlen = IPV6_MAX_PREFIXLEN;
- p.prefix = nexthop->gate.ipv6;
+ /* Lookup nexthop in IPv6 routing table. */
+ memset(&p, 0, sizeof(struct prefix_ipv6));
+ p.family = AF_INET6;
+ p.prefixlen = IPV6_MAX_PREFIXLEN;
+ p.prefix = nexthop->gate.ipv6;
- rn = route_node_match (table, (struct prefix *) &p);
- if (!rn)
- return 0;
+ rn = route_node_match(table, (struct prefix *)&p);
+ if (!rn)
+ return 0;
- route_unlock_node (rn);
+ route_unlock_node(rn);
- /* Locate a valid connected route. */
- RNODE_FOREACH_RE (rn, match)
- {
- if ((match->type == ZEBRA_ROUTE_CONNECT) &&
- !CHECK_FLAG (match->status, ROUTE_ENTRY_REMOVED) &&
- CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))
- break;
- }
+ /* Locate a valid connected route. */
+ RNODE_FOREACH_RE(rn, match)
+ {
+ if ((match->type == ZEBRA_ROUTE_CONNECT)
+ && !CHECK_FLAG(match->status, ROUTE_ENTRY_REMOVED)
+ && CHECK_FLAG(match->flags, ZEBRA_FLAG_SELECTED))
+ break;
+ }
- if (!match || !match->nexthop)
- return 0;
+ if (!match || !match->nexthop)
+ return 0;
- nexthop->ifindex = match->nexthop->ifindex;
- return 1;
+ nexthop->ifindex = match->nexthop->ifindex;
+ return 1;
}
@@ -743,57 +685,52 @@ nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)
* or not.
* NOTE: Each NHLFE points to only 1 nexthop.
*/
-static int
-nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe)
-{
- struct nexthop *nexthop;
- struct interface *ifp;
-
- nexthop = nhlfe->nexthop;
- if (!nexthop) // unexpected
- return 0;
-
- /* Check on nexthop based on type. */
- switch (nexthop->type)
- {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- if (nhlfe_nexthop_active_ipv4 (nhlfe, nexthop))
- SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
- else
- UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
- break;
-
- case NEXTHOP_TYPE_IPV6:
- if (nhlfe_nexthop_active_ipv6 (nhlfe, nexthop))
- SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
- else
- UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
- break;
-
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6))
- {
- ifp = if_lookup_by_index (nexthop->ifindex, VRF_DEFAULT);
- if (ifp && if_is_operative(ifp))
- SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
- else
- UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
- }
- else
- {
- if (nhlfe_nexthop_active_ipv6 (nhlfe, nexthop))
- SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
- else
- UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
- }
- break;
-
- default:
- break;
- }
-
- return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe)
+{
+ struct nexthop *nexthop;
+ struct interface *ifp;
+
+ nexthop = nhlfe->nexthop;
+ if (!nexthop) // unexpected
+ return 0;
+
+ /* Check on nexthop based on type. */
+ switch (nexthop->type) {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ if (nhlfe_nexthop_active_ipv4(nhlfe, nexthop))
+ SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ else
+ UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ break;
+
+ case NEXTHOP_TYPE_IPV6:
+ if (nhlfe_nexthop_active_ipv6(nhlfe, nexthop))
+ SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ else
+ UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ break;
+
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) {
+ ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT);
+ if (ifp && if_is_operative(ifp))
+ SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ else
+ UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ } else {
+ if (nhlfe_nexthop_active_ipv6(nhlfe, nexthop))
+ SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ else
+ UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
}
/*
@@ -802,783 +739,739 @@ nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe)
* marked. This is invoked when an LSP scheduled for processing (due
* to some change) is examined.
*/
-static void
-lsp_select_best_nhlfe (zebra_lsp_t *lsp)
-{
- zebra_nhlfe_t *nhlfe;
- zebra_nhlfe_t *best;
- struct nexthop *nexthop;
- int changed = 0;
-
- if (!lsp)
- return;
-
- best = NULL;
- lsp->num_ecmp = 0;
- UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED);
-
- /*
- * First compute the best path, after checking nexthop status. We are only
- * concerned with non-deleted NHLFEs.
- */
- for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
- {
- /* Clear selection flags. */
- UNSET_FLAG (nhlfe->flags,
- (NHLFE_FLAG_SELECTED | NHLFE_FLAG_MULTIPATH));
-
- if (!CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED) &&
- nhlfe_nexthop_active (nhlfe))
- {
- if (!best || (nhlfe->distance < best->distance))
- best = nhlfe;
- }
- }
-
- lsp->best_nhlfe = best;
- if (!lsp->best_nhlfe)
- return;
-
- /* Mark best NHLFE as selected. */
- SET_FLAG (lsp->best_nhlfe->flags, NHLFE_FLAG_SELECTED);
-
- /*
- * If best path exists, see if there is ECMP. While doing this, note if a
- * new (uninstalled) NHLFE has been selected, an installed entry that is
- * still selected has a change or an installed entry is to be removed.
- */
- for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
- {
- int nh_chg, nh_sel, nh_inst;
-
- nexthop = nhlfe->nexthop;
- if (!nexthop) // unexpected
- continue;
-
- if (!CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED) &&
- CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) &&
- (nhlfe->distance == lsp->best_nhlfe->distance))
- {
- SET_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED);
- SET_FLAG (nhlfe->flags, NHLFE_FLAG_MULTIPATH);
- lsp->num_ecmp++;
- }
-
- if (CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED) &&
- !changed)
- {
- nh_chg = CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED);
- nh_sel = CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED);
- nh_inst = CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED);
-
- if ((nh_sel && !nh_inst) ||
- (nh_sel && nh_inst && nh_chg) ||
- (nh_inst && !nh_sel))
- changed = 1;
- }
-
- /* We have finished examining, clear changed flag. */
- UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED);
- }
-
- if (changed)
- SET_FLAG (lsp->flags, LSP_FLAG_CHANGED);
+static void lsp_select_best_nhlfe(zebra_lsp_t *lsp)
+{
+ zebra_nhlfe_t *nhlfe;
+ zebra_nhlfe_t *best;
+ struct nexthop *nexthop;
+ int changed = 0;
+
+ if (!lsp)
+ return;
+
+ best = NULL;
+ lsp->num_ecmp = 0;
+ UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED);
+
+ /*
+ * First compute the best path, after checking nexthop status. We are
+ * only
+ * concerned with non-deleted NHLFEs.
+ */
+ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
+ /* Clear selection flags. */
+ UNSET_FLAG(nhlfe->flags,
+ (NHLFE_FLAG_SELECTED | NHLFE_FLAG_MULTIPATH));
+
+ if (!CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED)
+ && nhlfe_nexthop_active(nhlfe)) {
+ if (!best || (nhlfe->distance < best->distance))
+ best = nhlfe;
+ }
+ }
+
+ lsp->best_nhlfe = best;
+ if (!lsp->best_nhlfe)
+ return;
+
+ /* Mark best NHLFE as selected. */
+ SET_FLAG(lsp->best_nhlfe->flags, NHLFE_FLAG_SELECTED);
+
+ /*
+ * If best path exists, see if there is ECMP. While doing this, note if
+ * a
+ * new (uninstalled) NHLFE has been selected, an installed entry that is
+ * still selected has a change or an installed entry is to be removed.
+ */
+ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
+ int nh_chg, nh_sel, nh_inst;
+
+ nexthop = nhlfe->nexthop;
+ if (!nexthop) // unexpected
+ continue;
+
+ if (!CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED)
+ && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)
+ && (nhlfe->distance == lsp->best_nhlfe->distance)) {
+ SET_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED);
+ SET_FLAG(nhlfe->flags, NHLFE_FLAG_MULTIPATH);
+ lsp->num_ecmp++;
+ }
+
+ if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED) && !changed) {
+ nh_chg = CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED);
+ nh_sel = CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED);
+ nh_inst =
+ CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED);
+
+ if ((nh_sel && !nh_inst)
+ || (nh_sel && nh_inst && nh_chg)
+ || (nh_inst && !nh_sel))
+ changed = 1;
+ }
+
+ /* We have finished examining, clear changed flag. */
+ UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED);
+ }
+
+ if (changed)
+ SET_FLAG(lsp->flags, LSP_FLAG_CHANGED);
}
/*
* Delete LSP forwarding entry from kernel, if installed. Called upon
* process exit.
*/
-static void
-lsp_uninstall_from_kernel (struct hash_backet *backet, void *ctxt)
+static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt)
{
- zebra_lsp_t *lsp;
+ zebra_lsp_t *lsp;
- lsp = (zebra_lsp_t *) backet->data;
- if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
- kernel_del_lsp (lsp);
+ lsp = (zebra_lsp_t *)backet->data;
+ if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
+ kernel_del_lsp(lsp);
}
/*
* Schedule LSP forwarding entry for processing. Called upon changes
* that may impact LSPs such as nexthop / connected route changes.
*/
-static void
-lsp_schedule (struct hash_backet *backet, void *ctxt)
+static void lsp_schedule(struct hash_backet *backet, void *ctxt)
{
- zebra_lsp_t *lsp;
+ zebra_lsp_t *lsp;
- lsp = (zebra_lsp_t *) backet->data;
- lsp_processq_add (lsp);
+ lsp = (zebra_lsp_t *)backet->data;
+ lsp_processq_add(lsp);
}
/*
* Process a LSP entry that is in the queue. Recalculate best NHLFE and
* any multipaths and update or delete from the kernel, as needed.
*/
-static wq_item_status
-lsp_process (struct work_queue *wq, void *data)
-{
- zebra_lsp_t *lsp;
- zebra_nhlfe_t *oldbest, *newbest;
- char buf[BUFSIZ], buf2[BUFSIZ];
- struct zebra_vrf *zvrf = vrf_info_lookup (VRF_DEFAULT);
-
- lsp = (zebra_lsp_t *)data;
- if (!lsp) // unexpected
- return WQ_SUCCESS;
-
- oldbest = lsp->best_nhlfe;
-
- /* Select best NHLFE(s) */
- lsp_select_best_nhlfe (lsp);
-
- newbest = lsp->best_nhlfe;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- {
- if (oldbest)
- nhlfe2str (oldbest, buf, BUFSIZ);
- if (newbest)
- nhlfe2str (newbest, buf2, BUFSIZ);
- zlog_debug ("Process LSP in-label %u oldbest %s newbest %s "
- "flags 0x%x ecmp# %d",
- lsp->ile.in_label, oldbest ? buf : "NULL",
- newbest ? buf2 : "NULL", lsp->flags, lsp->num_ecmp);
- }
-
- if (!CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED))
- {
- /* Not already installed */
- if (newbest)
- {
- kernel_add_lsp (lsp);
- zvrf->lsp_installs++;
- }
- }
- else
- {
- /* Installed, may need an update and/or delete. */
- if (!newbest)
- {
- kernel_del_lsp (lsp);
- zvrf->lsp_removals++;
- }
- else if (CHECK_FLAG (lsp->flags, LSP_FLAG_CHANGED))
- {
- kernel_upd_lsp (lsp);
- zvrf->lsp_installs++;
- }
- }
-
- return WQ_SUCCESS;
+static wq_item_status lsp_process(struct work_queue *wq, void *data)
+{
+ zebra_lsp_t *lsp;
+ zebra_nhlfe_t *oldbest, *newbest;
+ char buf[BUFSIZ], buf2[BUFSIZ];
+ struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT);
+
+ lsp = (zebra_lsp_t *)data;
+ if (!lsp) // unexpected
+ return WQ_SUCCESS;
+
+ oldbest = lsp->best_nhlfe;
+
+ /* Select best NHLFE(s) */
+ lsp_select_best_nhlfe(lsp);
+
+ newbest = lsp->best_nhlfe;
+
+ if (IS_ZEBRA_DEBUG_MPLS) {
+ if (oldbest)
+ nhlfe2str(oldbest, buf, BUFSIZ);
+ if (newbest)
+ nhlfe2str(newbest, buf2, BUFSIZ);
+ zlog_debug(
+ "Process LSP in-label %u oldbest %s newbest %s "
+ "flags 0x%x ecmp# %d",
+ lsp->ile.in_label, oldbest ? buf : "NULL",
+ newbest ? buf2 : "NULL", lsp->flags, lsp->num_ecmp);
+ }
+
+ if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) {
+ /* Not already installed */
+ if (newbest) {
+ kernel_add_lsp(lsp);
+ zvrf->lsp_installs++;
+ }
+ } else {
+ /* Installed, may need an update and/or delete. */
+ if (!newbest) {
+ kernel_del_lsp(lsp);
+ zvrf->lsp_removals++;
+ } else if (CHECK_FLAG(lsp->flags, LSP_FLAG_CHANGED)) {
+ kernel_upd_lsp(lsp);
+ zvrf->lsp_installs++;
+ }
+ }
+
+ return WQ_SUCCESS;
}
/*
* Callback upon processing completion of a LSP forwarding entry.
*/
-static void
-lsp_processq_del (struct work_queue *wq, void *data)
+static void lsp_processq_del(struct work_queue *wq, void *data)
{
- struct zebra_vrf *zvrf;
- zebra_lsp_t *lsp;
- struct hash *lsp_table;
- zebra_nhlfe_t *nhlfe, *nhlfe_next;
+ struct zebra_vrf *zvrf;
+ zebra_lsp_t *lsp;
+ struct hash *lsp_table;
+ zebra_nhlfe_t *nhlfe, *nhlfe_next;
- zvrf = vrf_info_lookup(VRF_DEFAULT);
- assert (zvrf);
+ zvrf = vrf_info_lookup(VRF_DEFAULT);
+ assert(zvrf);
- lsp_table = zvrf->lsp_table;
- if (!lsp_table) // unexpected
- return;
+ lsp_table = zvrf->lsp_table;
+ if (!lsp_table) // unexpected
+ return;
- lsp = (zebra_lsp_t *)data;
- if (!lsp) // unexpected
- return;
+ lsp = (zebra_lsp_t *)data;
+ if (!lsp) // unexpected
+ return;
- /* Clear flag, remove any NHLFEs marked for deletion. If no NHLFEs exist,
- * delete LSP entry also.
- */
- UNSET_FLAG (lsp->flags, LSP_FLAG_SCHEDULED);
+ /* Clear flag, remove any NHLFEs marked for deletion. If no NHLFEs
+ * exist,
+ * delete LSP entry also.
+ */
+ UNSET_FLAG(lsp->flags, LSP_FLAG_SCHEDULED);
- for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next)
- {
- nhlfe_next = nhlfe->next;
- if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED))
- nhlfe_del (nhlfe);
- }
+ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) {
+ nhlfe_next = nhlfe->next;
+ if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED))
+ nhlfe_del(nhlfe);
+ }
- if (!lsp->nhlfe_list)
- {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug ("Free LSP in-label %u flags 0x%x",
- lsp->ile.in_label, lsp->flags);
+ if (!lsp->nhlfe_list) {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("Free LSP in-label %u flags 0x%x",
+ lsp->ile.in_label, lsp->flags);
- lsp = hash_release(lsp_table, &lsp->ile);
- if (lsp)
- XFREE(MTYPE_LSP, lsp);
- }
+ lsp = hash_release(lsp_table, &lsp->ile);
+ if (lsp)
+ XFREE(MTYPE_LSP, lsp);
+ }
}
/*
* Callback upon finishing the processing of all scheduled
* LSP forwarding entries.
*/
-static void
-lsp_processq_complete (struct work_queue *wq)
+static void lsp_processq_complete(struct work_queue *wq)
{
- /* Nothing to do for now. */
+ /* Nothing to do for now. */
}
/*
* Add LSP forwarding entry to queue for subsequent processing.
*/
-static int
-lsp_processq_add (zebra_lsp_t *lsp)
+static int lsp_processq_add(zebra_lsp_t *lsp)
{
- /* If already scheduled, exit. */
- if (CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED))
- return 0;
+ /* If already scheduled, exit. */
+ if (CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
+ return 0;
- if (zebrad.lsp_process_q == NULL)
- {
- zlog_err ("%s: work_queue does not exist!", __func__);
- return -1;
- }
+ if (zebrad.lsp_process_q == NULL) {
+ zlog_err("%s: work_queue does not exist!", __func__);
+ return -1;
+ }
- work_queue_add (zebrad.lsp_process_q, lsp);
- SET_FLAG (lsp->flags, LSP_FLAG_SCHEDULED);
- return 0;
+ work_queue_add(zebrad.lsp_process_q, lsp);
+ SET_FLAG(lsp->flags, LSP_FLAG_SCHEDULED);
+ return 0;
}
/*
* Callback to allocate LSP forwarding table entry.
*/
-static void *
-lsp_alloc (void *p)
+static void *lsp_alloc(void *p)
{
- const zebra_ile_t *ile = p;
- zebra_lsp_t *lsp;
+ const zebra_ile_t *ile = p;
+ zebra_lsp_t *lsp;
- lsp = XCALLOC (MTYPE_LSP, sizeof(zebra_lsp_t));
- lsp->ile = *ile;
+ lsp = XCALLOC(MTYPE_LSP, sizeof(zebra_lsp_t));
+ lsp->ile = *ile;
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug ("Alloc LSP in-label %u", lsp->ile.in_label);
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("Alloc LSP in-label %u", lsp->ile.in_label);
- return ((void *)lsp);
+ return ((void *)lsp);
}
/*
* Create printable string for NHLFE entry.
*/
-static char *
-nhlfe2str (zebra_nhlfe_t *nhlfe, char *buf, int size)
+static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size)
{
- struct nexthop *nexthop;
+ struct nexthop *nexthop;
- buf[0] = '\0';
- nexthop = nhlfe->nexthop;
- switch (nexthop->type)
- {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- inet_ntop (AF_INET, &nexthop->gate.ipv4, buf, size);
- break;
- case NEXTHOP_TYPE_IPV6:
- inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, size);
- break;
- default:
- break;
- }
+ buf[0] = '\0';
+ nexthop = nhlfe->nexthop;
+ switch (nexthop->type) {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ inet_ntop(AF_INET, &nexthop->gate.ipv4, buf, size);
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, size);
+ break;
+ default:
+ break;
+ }
- return buf;
+ return buf;
}
/*
* Check if NHLFE matches with search info passed.
*/
-static int
-nhlfe_nhop_match (zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
- union g_addr *gate, ifindex_t ifindex)
+static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex)
{
- struct nexthop *nhop;
- int cmp = 1;
+ struct nexthop *nhop;
+ int cmp = 1;
- nhop = nhlfe->nexthop;
- if (!nhop)
- return 1;
+ nhop = nhlfe->nexthop;
+ if (!nhop)
+ return 1;
- if (nhop->type != gtype)
- return 1;
+ if (nhop->type != gtype)
+ return 1;
- switch (nhop->type)
- {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- cmp = memcmp(&(nhop->gate.ipv4), &(gate->ipv4),
- sizeof(struct in_addr));
- if (!cmp && nhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
- cmp = !(nhop->ifindex == ifindex);
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- cmp = memcmp(&(nhop->gate.ipv6), &(gate->ipv6),
- sizeof(struct in6_addr));
- if (!cmp && nhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
- cmp = !(nhop->ifindex == ifindex);
- break;
- default:
- break;
- }
+ switch (nhop->type) {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ cmp = memcmp(&(nhop->gate.ipv4), &(gate->ipv4),
+ sizeof(struct in_addr));
+ if (!cmp && nhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
+ cmp = !(nhop->ifindex == ifindex);
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ cmp = memcmp(&(nhop->gate.ipv6), &(gate->ipv6),
+ sizeof(struct in6_addr));
+ if (!cmp && nhop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
+ cmp = !(nhop->ifindex == ifindex);
+ break;
+ default:
+ break;
+ }
- return cmp;
+ return cmp;
}
/*
* Locate NHLFE that matches with passed info.
*/
-static zebra_nhlfe_t *
-nhlfe_find (zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
- enum nexthop_types_t gtype, union g_addr *gate,
- ifindex_t ifindex)
+static zebra_nhlfe_t *nhlfe_find(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
+ enum nexthop_types_t gtype, union g_addr *gate,
+ ifindex_t ifindex)
{
- zebra_nhlfe_t *nhlfe;
+ zebra_nhlfe_t *nhlfe;
- if (!lsp)
- return NULL;
+ if (!lsp)
+ return NULL;
- for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
- {
- if (nhlfe->type != lsp_type)
- continue;
- if (!nhlfe_nhop_match (nhlfe, gtype, gate, ifindex))
- break;
- }
+ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
+ if (nhlfe->type != lsp_type)
+ continue;
+ if (!nhlfe_nhop_match(nhlfe, gtype, gate, ifindex))
+ break;
+ }
- return nhlfe;
+ return nhlfe;
}
/*
* Add NHLFE. Base entry must have been created and duplicate
* check done.
*/
-static zebra_nhlfe_t *
-nhlfe_add (zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
- enum nexthop_types_t gtype, union g_addr *gate,
- ifindex_t ifindex, mpls_label_t out_label)
-{
- zebra_nhlfe_t *nhlfe;
- struct nexthop *nexthop;
-
- if (!lsp)
- return NULL;
-
- nhlfe = XCALLOC(MTYPE_NHLFE, sizeof(zebra_nhlfe_t));
- if (!nhlfe)
- return NULL;
-
- nhlfe->lsp = lsp;
- nhlfe->type = lsp_type;
- nhlfe->distance = lsp_distance (lsp_type);
-
- nexthop = nexthop_new();
- if (!nexthop)
- {
- XFREE (MTYPE_NHLFE, nhlfe);
- return NULL;
- }
- nexthop_add_labels (nexthop, lsp_type, 1, &out_label);
-
- nexthop->type = gtype;
- switch (nexthop->type)
- {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- nexthop->gate.ipv4 = gate->ipv4;
- if (ifindex)
- nexthop->ifindex = ifindex;
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- nexthop->gate.ipv6 = gate->ipv6;
- if (ifindex)
- nexthop->ifindex = ifindex;
- break;
- default:
- nexthop_free(nexthop);
- XFREE (MTYPE_NHLFE, nhlfe);
- return NULL;
- break;
- }
-
- nhlfe->nexthop = nexthop;
- if (lsp->nhlfe_list)
- lsp->nhlfe_list->prev = nhlfe;
- nhlfe->next = lsp->nhlfe_list;
- lsp->nhlfe_list = nhlfe;
-
- return nhlfe;
+static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
+ enum nexthop_types_t gtype, union g_addr *gate,
+ ifindex_t ifindex, mpls_label_t out_label)
+{
+ zebra_nhlfe_t *nhlfe;
+ struct nexthop *nexthop;
+
+ if (!lsp)
+ return NULL;
+
+ nhlfe = XCALLOC(MTYPE_NHLFE, sizeof(zebra_nhlfe_t));
+ if (!nhlfe)
+ return NULL;
+
+ nhlfe->lsp = lsp;
+ nhlfe->type = lsp_type;
+ nhlfe->distance = lsp_distance(lsp_type);
+
+ nexthop = nexthop_new();
+ if (!nexthop) {
+ XFREE(MTYPE_NHLFE, nhlfe);
+ return NULL;
+ }
+ nexthop_add_labels(nexthop, lsp_type, 1, &out_label);
+
+ nexthop->type = gtype;
+ switch (nexthop->type) {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ nexthop->gate.ipv4 = gate->ipv4;
+ if (ifindex)
+ nexthop->ifindex = ifindex;
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ nexthop->gate.ipv6 = gate->ipv6;
+ if (ifindex)
+ nexthop->ifindex = ifindex;
+ break;
+ default:
+ nexthop_free(nexthop);
+ XFREE(MTYPE_NHLFE, nhlfe);
+ return NULL;
+ break;
+ }
+
+ nhlfe->nexthop = nexthop;
+ if (lsp->nhlfe_list)
+ lsp->nhlfe_list->prev = nhlfe;
+ nhlfe->next = lsp->nhlfe_list;
+ lsp->nhlfe_list = nhlfe;
+
+ return nhlfe;
}
/*
* Delete NHLFE. Entry must be present on list.
*/
-static int
-nhlfe_del (zebra_nhlfe_t *nhlfe)
+static int nhlfe_del(zebra_nhlfe_t *nhlfe)
{
- zebra_lsp_t *lsp;
+ zebra_lsp_t *lsp;
- if (!nhlfe)
- return -1;
+ if (!nhlfe)
+ return -1;
- lsp = nhlfe->lsp;
- if (!lsp)
- return -1;
+ lsp = nhlfe->lsp;
+ if (!lsp)
+ return -1;
- /* Free nexthop. */
- if (nhlfe->nexthop)
- nexthop_free(nhlfe->nexthop);
+ /* Free nexthop. */
+ if (nhlfe->nexthop)
+ nexthop_free(nhlfe->nexthop);
- /* Unlink from LSP */
- if (nhlfe->next)
- nhlfe->next->prev = nhlfe->prev;
- if (nhlfe->prev)
- nhlfe->prev->next = nhlfe->next;
- else
- lsp->nhlfe_list = nhlfe->next;
+ /* Unlink from LSP */
+ if (nhlfe->next)
+ nhlfe->next->prev = nhlfe->prev;
+ if (nhlfe->prev)
+ nhlfe->prev->next = nhlfe->next;
+ else
+ lsp->nhlfe_list = nhlfe->next;
- if (nhlfe == lsp->best_nhlfe)
- lsp->best_nhlfe = NULL;
+ if (nhlfe == lsp->best_nhlfe)
+ lsp->best_nhlfe = NULL;
- XFREE (MTYPE_NHLFE, nhlfe);
+ XFREE(MTYPE_NHLFE, nhlfe);
- return 0;
+ return 0;
}
/*
* Update label for NHLFE entry.
*/
-static void
-nhlfe_out_label_update (zebra_nhlfe_t *nhlfe, struct nexthop_label *nh_label)
-{
- nhlfe->nexthop->nh_label->label[0] = nh_label->label[0];
-}
-
-static int
-mpls_lsp_uninstall_all (struct hash *lsp_table, zebra_lsp_t *lsp,
- enum lsp_types_t type)
-{
- zebra_nhlfe_t *nhlfe, *nhlfe_next;
- int schedule_lsp = 0;
- char buf[BUFSIZ];
-
- /* Mark NHLFEs for delete or directly delete, as appropriate. */
- for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next)
- {
- nhlfe_next = nhlfe->next;
-
- /* Skip non-static NHLFEs */
- if (nhlfe->type != type)
- continue;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- {
- nhlfe2str (nhlfe, buf, BUFSIZ);
- zlog_debug ("Del LSP in-label %u type %d nexthop %s flags 0x%x",
- lsp->ile.in_label, type, buf, nhlfe->flags);
- }
-
- if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED))
- {
- UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED);
- SET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED);
- schedule_lsp = 1;
- }
- else
- {
- nhlfe_del (nhlfe);
- }
- }
-
- /* Queue LSP for processing, if needed, else delete. */
- if (schedule_lsp)
- {
- if (lsp_processq_add (lsp))
- return -1;
- }
- else if (!lsp->nhlfe_list &&
- !CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED))
- {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug ("Free LSP in-label %u flags 0x%x",
- lsp->ile.in_label, lsp->flags);
-
- lsp = hash_release(lsp_table, &lsp->ile);
- if (lsp)
- XFREE(MTYPE_LSP, lsp);
- }
-
- return 0;
+static void nhlfe_out_label_update(zebra_nhlfe_t *nhlfe,
+ struct nexthop_label *nh_label)
+{
+ nhlfe->nexthop->nh_label->label[0] = nh_label->label[0];
+}
+
+static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
+ enum lsp_types_t type)
+{
+ zebra_nhlfe_t *nhlfe, *nhlfe_next;
+ int schedule_lsp = 0;
+ char buf[BUFSIZ];
+
+ /* Mark NHLFEs for delete or directly delete, as appropriate. */
+ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) {
+ nhlfe_next = nhlfe->next;
+
+ /* Skip non-static NHLFEs */
+ if (nhlfe->type != type)
+ continue;
+
+ if (IS_ZEBRA_DEBUG_MPLS) {
+ nhlfe2str(nhlfe, buf, BUFSIZ);
+ zlog_debug(
+ "Del LSP in-label %u type %d nexthop %s flags 0x%x",
+ lsp->ile.in_label, type, buf, nhlfe->flags);
+ }
+
+ if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) {
+ UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED);
+ SET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED);
+ schedule_lsp = 1;
+ } else {
+ nhlfe_del(nhlfe);
+ }
+ }
+
+ /* Queue LSP for processing, if needed, else delete. */
+ if (schedule_lsp) {
+ if (lsp_processq_add(lsp))
+ return -1;
+ } else if (!lsp->nhlfe_list
+ && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("Free LSP in-label %u flags 0x%x",
+ lsp->ile.in_label, lsp->flags);
+
+ lsp = hash_release(lsp_table, &lsp->ile);
+ if (lsp)
+ XFREE(MTYPE_LSP, lsp);
+ }
+
+ return 0;
}
/*
* Uninstall all static NHLFEs for a particular LSP forwarding entry.
* If no other NHLFEs exist, the entry would be deleted.
*/
-static int
-mpls_static_lsp_uninstall_all (struct zebra_vrf *zvrf, mpls_label_t in_label)
+static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf,
+ mpls_label_t in_label)
{
- struct hash *lsp_table;
- zebra_ile_t tmp_ile;
- zebra_lsp_t *lsp;
+ struct hash *lsp_table;
+ zebra_ile_t tmp_ile;
+ zebra_lsp_t *lsp;
- /* Lookup table. */
- lsp_table = zvrf->lsp_table;
- if (!lsp_table)
- return -1;
+ /* Lookup table. */
+ lsp_table = zvrf->lsp_table;
+ if (!lsp_table)
+ return -1;
- /* If entry is not present, exit. */
- tmp_ile.in_label = in_label;
- lsp = hash_lookup (lsp_table, &tmp_ile);
- if (!lsp || !lsp->nhlfe_list)
- return 0;
+ /* If entry is not present, exit. */
+ tmp_ile.in_label = in_label;
+ lsp = hash_lookup(lsp_table, &tmp_ile);
+ if (!lsp || !lsp->nhlfe_list)
+ return 0;
- return mpls_lsp_uninstall_all (lsp_table, lsp, ZEBRA_LSP_STATIC);
+ return mpls_lsp_uninstall_all(lsp_table, lsp, ZEBRA_LSP_STATIC);
}
-static json_object *
-nhlfe_json (zebra_nhlfe_t *nhlfe)
+static json_object *nhlfe_json(zebra_nhlfe_t *nhlfe)
{
- char buf[BUFSIZ];
- json_object *json_nhlfe = NULL;
- struct nexthop *nexthop = nhlfe->nexthop;
+ char buf[BUFSIZ];
+ json_object *json_nhlfe = NULL;
+ struct nexthop *nexthop = nhlfe->nexthop;
- json_nhlfe = json_object_new_object();
- json_object_string_add(json_nhlfe, "type", nhlfe_type2str(nhlfe->type));
- json_object_int_add(json_nhlfe, "outLabel", nexthop->nh_label->label[0]);
- json_object_int_add(json_nhlfe, "distance", nhlfe->distance);
+ json_nhlfe = json_object_new_object();
+ json_object_string_add(json_nhlfe, "type", nhlfe_type2str(nhlfe->type));
+ json_object_int_add(json_nhlfe, "outLabel",
+ nexthop->nh_label->label[0]);
+ json_object_int_add(json_nhlfe, "distance", nhlfe->distance);
- if (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED))
- json_object_boolean_true_add(json_nhlfe, "installed");
+ if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED))
+ json_object_boolean_true_add(json_nhlfe, "installed");
- switch (nexthop->type)
- {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- json_object_string_add(json_nhlfe, "nexthop",
- inet_ntoa (nexthop->gate.ipv4));
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- json_object_string_add(json_nhlfe, "nexthop",
- inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
-
- if (nexthop->ifindex)
- json_object_string_add(json_nhlfe, "interface", ifindex2ifname (nexthop->ifindex, VRF_DEFAULT));
- break;
- default:
- break;
- }
- return json_nhlfe;
+ switch (nexthop->type) {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ json_object_string_add(json_nhlfe, "nexthop",
+ inet_ntoa(nexthop->gate.ipv4));
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ json_object_string_add(
+ json_nhlfe, "nexthop",
+ inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
+
+ if (nexthop->ifindex)
+ json_object_string_add(
+ json_nhlfe, "interface",
+ ifindex2ifname(nexthop->ifindex, VRF_DEFAULT));
+ break;
+ default:
+ break;
+ }
+ return json_nhlfe;
}
/*
* Print the NHLFE for a LSP forwarding entry.
*/
-static void
-nhlfe_print (zebra_nhlfe_t *nhlfe, struct vty *vty)
-{
- struct nexthop *nexthop;
- char buf[BUFSIZ];
-
- nexthop = nhlfe->nexthop;
- if (!nexthop || !nexthop->nh_label) // unexpected
- return;
-
- vty_out (vty, " type: %s remote label: %s distance: %d\n",
- nhlfe_type2str(nhlfe->type),
- label2str(nexthop->nh_label->label[0], buf, BUFSIZ),
- nhlfe->distance);
- switch (nexthop->type)
- {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4));
- if (nexthop->ifindex)
- vty_out (vty, " dev %s", ifindex2ifname (nexthop->ifindex, VRF_DEFAULT));
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- vty_out (vty, " via %s",
- inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
- if (nexthop->ifindex)
- vty_out (vty, " dev %s", ifindex2ifname (nexthop->ifindex, VRF_DEFAULT));
- break;
- default:
- break;
- }
- vty_out(vty, "%s", CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED) ?
- " (installed)" : "");
- vty_out (vty, "\n");
+static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty)
+{
+ struct nexthop *nexthop;
+ char buf[BUFSIZ];
+
+ nexthop = nhlfe->nexthop;
+ if (!nexthop || !nexthop->nh_label) // unexpected
+ return;
+
+ vty_out(vty, " type: %s remote label: %s distance: %d\n",
+ nhlfe_type2str(nhlfe->type),
+ label2str(nexthop->nh_label->label[0], buf, BUFSIZ),
+ nhlfe->distance);
+ switch (nexthop->type) {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4));
+ if (nexthop->ifindex)
+ vty_out(vty, " dev %s",
+ ifindex2ifname(nexthop->ifindex, VRF_DEFAULT));
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ vty_out(vty, " via %s",
+ inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
+ if (nexthop->ifindex)
+ vty_out(vty, " dev %s",
+ ifindex2ifname(nexthop->ifindex, VRF_DEFAULT));
+ break;
+ default:
+ break;
+ }
+ vty_out(vty, "%s",
+ CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED) ? " (installed)"
+ : "");
+ vty_out(vty, "\n");
}
/*
* Print an LSP forwarding entry.
*/
-static void
-lsp_print (zebra_lsp_t *lsp, void *ctxt)
+static void lsp_print(zebra_lsp_t *lsp, void *ctxt)
{
- zebra_nhlfe_t *nhlfe;
- struct vty *vty;
+ zebra_nhlfe_t *nhlfe;
+ struct vty *vty;
- vty = (struct vty *) ctxt;
+ vty = (struct vty *)ctxt;
- vty_out (vty, "Local label: %u%s\n",
- lsp->ile.in_label,
- CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED) ? " (installed)" : "");
+ vty_out(vty, "Local label: %u%s\n", lsp->ile.in_label,
+ CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED) ? " (installed)"
+ : "");
- for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
- nhlfe_print (nhlfe, vty);
+ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
+ nhlfe_print(nhlfe, vty);
}
/*
* JSON objects for an LSP forwarding entry.
*/
-static json_object *
-lsp_json (zebra_lsp_t *lsp)
+static json_object *lsp_json(zebra_lsp_t *lsp)
{
- zebra_nhlfe_t *nhlfe = NULL;
- json_object *json = json_object_new_object();
- json_object *json_nhlfe_list = json_object_new_array();
+ zebra_nhlfe_t *nhlfe = NULL;
+ json_object *json = json_object_new_object();
+ json_object *json_nhlfe_list = json_object_new_array();
- json_object_int_add(json, "inLabel", lsp->ile.in_label);
+ json_object_int_add(json, "inLabel", lsp->ile.in_label);
- if (CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED))
- json_object_boolean_true_add(json, "installed");
+ if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
+ json_object_boolean_true_add(json, "installed");
- for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
- json_object_array_add(json_nhlfe_list, nhlfe_json(nhlfe));
+ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
+ json_object_array_add(json_nhlfe_list, nhlfe_json(nhlfe));
- json_object_object_add(json, "nexthops", json_nhlfe_list);
- return json;
+ json_object_object_add(json, "nexthops", json_nhlfe_list);
+ return json;
}
/* Return a sorted linked list of the hash contents */
-static struct list *
-hash_get_sorted_list (struct hash *hash, void *cmp)
+static struct list *hash_get_sorted_list(struct hash *hash, void *cmp)
{
- unsigned int i;
- struct hash_backet *hb;
- struct list *sorted_list = list_new();
+ unsigned int i;
+ struct hash_backet *hb;
+ struct list *sorted_list = list_new();
- sorted_list->cmp = (int (*)(void *, void *)) cmp;
+ sorted_list->cmp = (int (*)(void *, void *))cmp;
- for (i = 0; i < hash->size; i++)
- for (hb = hash->index[i]; hb; hb = hb->next)
- listnode_add_sort(sorted_list, hb->data);
+ for (i = 0; i < hash->size; i++)
+ for (hb = hash->index[i]; hb; hb = hb->next)
+ listnode_add_sort(sorted_list, hb->data);
- return sorted_list;
+ return sorted_list;
}
/*
* Compare two LSPs based on their label values.
*/
-static int
-lsp_cmp (zebra_lsp_t *lsp1, zebra_lsp_t *lsp2)
+static int lsp_cmp(zebra_lsp_t *lsp1, zebra_lsp_t *lsp2)
{
- if (lsp1->ile.in_label < lsp2->ile.in_label)
- return -1;
+ if (lsp1->ile.in_label < lsp2->ile.in_label)
+ return -1;
- if (lsp1->ile.in_label > lsp2->ile.in_label)
- return 1;
+ if (lsp1->ile.in_label > lsp2->ile.in_label)
+ return 1;
- return 0;
+ return 0;
}
/*
* Callback to allocate static LSP.
*/
-static void *
-slsp_alloc (void *p)
+static void *slsp_alloc(void *p)
{
- const zebra_ile_t *ile = p;
- zebra_slsp_t *slsp;
+ const zebra_ile_t *ile = p;
+ zebra_slsp_t *slsp;
- slsp = XCALLOC (MTYPE_SLSP, sizeof(zebra_slsp_t));
- slsp->ile = *ile;
- return ((void *)slsp);
+ slsp = XCALLOC(MTYPE_SLSP, sizeof(zebra_slsp_t));
+ slsp->ile = *ile;
+ return ((void *)slsp);
}
/*
* Compare two static LSPs based on their label values.
*/
-static int
-slsp_cmp (zebra_slsp_t *slsp1, zebra_slsp_t *slsp2)
+static int slsp_cmp(zebra_slsp_t *slsp1, zebra_slsp_t *slsp2)
{
- if (slsp1->ile.in_label < slsp2->ile.in_label)
- return -1;
+ if (slsp1->ile.in_label < slsp2->ile.in_label)
+ return -1;
- if (slsp1->ile.in_label > slsp2->ile.in_label)
- return 1;
+ if (slsp1->ile.in_label > slsp2->ile.in_label)
+ return 1;
- return 0;
+ return 0;
}
/*
* Check if static NHLFE matches with search info passed.
*/
-static int
-snhlfe_match (zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
- union g_addr *gate, ifindex_t ifindex)
+static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex)
{
- int cmp = 1;
+ int cmp = 1;
- if (snhlfe->gtype != gtype)
- return 1;
+ if (snhlfe->gtype != gtype)
+ return 1;
- switch (snhlfe->gtype)
- {
- case NEXTHOP_TYPE_IPV4:
- cmp = memcmp(&(snhlfe->gate.ipv4), &(gate->ipv4),
- sizeof(struct in_addr));
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- cmp = memcmp(&(snhlfe->gate.ipv6), &(gate->ipv6),
- sizeof(struct in6_addr));
- if (!cmp && snhlfe->gtype == NEXTHOP_TYPE_IPV6_IFINDEX)
- cmp = !(snhlfe->ifindex == ifindex);
- break;
- default:
- break;
- }
+ switch (snhlfe->gtype) {
+ case NEXTHOP_TYPE_IPV4:
+ cmp = memcmp(&(snhlfe->gate.ipv4), &(gate->ipv4),
+ sizeof(struct in_addr));
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ cmp = memcmp(&(snhlfe->gate.ipv6), &(gate->ipv6),
+ sizeof(struct in6_addr));
+ if (!cmp && snhlfe->gtype == NEXTHOP_TYPE_IPV6_IFINDEX)
+ cmp = !(snhlfe->ifindex == ifindex);
+ break;
+ default:
+ break;
+ }
- return cmp;
+ return cmp;
}
/*
* Locate static NHLFE that matches with passed info.
*/
-static zebra_snhlfe_t *
-snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype,
- union g_addr *gate, ifindex_t ifindex)
+static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp,
+ enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex)
{
- zebra_snhlfe_t *snhlfe;
+ zebra_snhlfe_t *snhlfe;
- if (!slsp)
- return NULL;
+ if (!slsp)
+ return NULL;
- for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe->next)
- {
- if (!snhlfe_match (snhlfe, gtype, gate, ifindex))
- break;
- }
+ for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe->next) {
+ if (!snhlfe_match(snhlfe, gtype, gate, ifindex))
+ break;
+ }
- return snhlfe;
+ return snhlfe;
}
@@ -1586,144 +1479,136 @@ snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype,
* Add static NHLFE. Base LSP config entry must have been created
* and duplicate check done.
*/
-static zebra_snhlfe_t *
-snhlfe_add (zebra_slsp_t *slsp, enum nexthop_types_t gtype,
- union g_addr *gate, ifindex_t ifindex,
- mpls_label_t out_label)
-{
- zebra_snhlfe_t *snhlfe;
-
- if (!slsp)
- return NULL;
-
- snhlfe = XCALLOC(MTYPE_SNHLFE, sizeof(zebra_snhlfe_t));
- snhlfe->slsp = slsp;
- snhlfe->out_label = out_label;
- snhlfe->gtype = gtype;
- switch (gtype)
- {
- case NEXTHOP_TYPE_IPV4:
- snhlfe->gate.ipv4 = gate->ipv4;
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- snhlfe->gate.ipv6 = gate->ipv6;
- if (ifindex)
- snhlfe->ifindex = ifindex;
- break;
- default:
- XFREE (MTYPE_SNHLFE, snhlfe);
- return NULL;
- }
-
- if (slsp->snhlfe_list)
- slsp->snhlfe_list->prev = snhlfe;
- snhlfe->next = slsp->snhlfe_list;
- slsp->snhlfe_list = snhlfe;
-
- return snhlfe;
+static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp,
+ enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex,
+ mpls_label_t out_label)
+{
+ zebra_snhlfe_t *snhlfe;
+
+ if (!slsp)
+ return NULL;
+
+ snhlfe = XCALLOC(MTYPE_SNHLFE, sizeof(zebra_snhlfe_t));
+ snhlfe->slsp = slsp;
+ snhlfe->out_label = out_label;
+ snhlfe->gtype = gtype;
+ switch (gtype) {
+ case NEXTHOP_TYPE_IPV4:
+ snhlfe->gate.ipv4 = gate->ipv4;
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ snhlfe->gate.ipv6 = gate->ipv6;
+ if (ifindex)
+ snhlfe->ifindex = ifindex;
+ break;
+ default:
+ XFREE(MTYPE_SNHLFE, snhlfe);
+ return NULL;
+ }
+
+ if (slsp->snhlfe_list)
+ slsp->snhlfe_list->prev = snhlfe;
+ snhlfe->next = slsp->snhlfe_list;
+ slsp->snhlfe_list = snhlfe;
+
+ return snhlfe;
}
/*
* Delete static NHLFE. Entry must be present on list.
*/
-static int
-snhlfe_del (zebra_snhlfe_t *snhlfe)
+static int snhlfe_del(zebra_snhlfe_t *snhlfe)
{
- zebra_slsp_t *slsp;
+ zebra_slsp_t *slsp;
- if (!snhlfe)
- return -1;
+ if (!snhlfe)
+ return -1;
- slsp = snhlfe->slsp;
- if (!slsp)
- return -1;
+ slsp = snhlfe->slsp;
+ if (!slsp)
+ return -1;
- if (snhlfe->next)
- snhlfe->next->prev = snhlfe->prev;
- if (snhlfe->prev)
- snhlfe->prev->next = snhlfe->next;
- else
- slsp->snhlfe_list = snhlfe->next;
+ if (snhlfe->next)
+ snhlfe->next->prev = snhlfe->prev;
+ if (snhlfe->prev)
+ snhlfe->prev->next = snhlfe->next;
+ else
+ slsp->snhlfe_list = snhlfe->next;
- snhlfe->prev = snhlfe->next = NULL;
- if (snhlfe->ifname)
- XFREE (MTYPE_SNHLFE_IFNAME, snhlfe->ifname);
- XFREE (MTYPE_SNHLFE, snhlfe);
+ snhlfe->prev = snhlfe->next = NULL;
+ if (snhlfe->ifname)
+ XFREE(MTYPE_SNHLFE_IFNAME, snhlfe->ifname);
+ XFREE(MTYPE_SNHLFE, snhlfe);
- return 0;
+ return 0;
}
/*
* Delete all static NHLFE entries for this LSP (in label).
*/
-static int
-snhlfe_del_all (zebra_slsp_t *slsp)
+static int snhlfe_del_all(zebra_slsp_t *slsp)
{
- zebra_snhlfe_t *snhlfe, *snhlfe_next;
+ zebra_snhlfe_t *snhlfe, *snhlfe_next;
- if (!slsp)
- return -1;
+ if (!slsp)
+ return -1;
- for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe_next)
- {
- snhlfe_next = snhlfe->next;
- snhlfe_del (snhlfe);
- }
+ for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe_next) {
+ snhlfe_next = snhlfe->next;
+ snhlfe_del(snhlfe);
+ }
- return 0;
+ return 0;
}
/*
* Create printable string for NHLFE configuration.
*/
-static char *
-snhlfe2str (zebra_snhlfe_t *snhlfe, char *buf, int size)
+static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size)
{
- buf[0] = '\0';
- switch (snhlfe->gtype)
- {
- case NEXTHOP_TYPE_IPV4:
- inet_ntop (AF_INET, &snhlfe->gate.ipv4, buf, size);
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- inet_ntop (AF_INET6, &snhlfe->gate.ipv6, buf, size);
- if (snhlfe->ifindex)
- strcat (buf, ifindex2ifname (snhlfe->ifindex, VRF_DEFAULT));
- break;
- default:
- break;
- }
+ buf[0] = '\0';
+ switch (snhlfe->gtype) {
+ case NEXTHOP_TYPE_IPV4:
+ inet_ntop(AF_INET, &snhlfe->gate.ipv4, buf, size);
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ inet_ntop(AF_INET6, &snhlfe->gate.ipv6, buf, size);
+ if (snhlfe->ifindex)
+ strcat(buf,
+ ifindex2ifname(snhlfe->ifindex, VRF_DEFAULT));
+ break;
+ default:
+ break;
+ }
- return buf;
+ return buf;
}
/*
* Initialize work queue for processing changed LSPs.
*/
-static int
-mpls_processq_init (struct zebra_t *zebra)
+static int mpls_processq_init(struct zebra_t *zebra)
{
- zebra->lsp_process_q = work_queue_new (zebra->master, "LSP processing");
- if (!zebra->lsp_process_q)
- {
- zlog_err ("%s: could not initialise work queue!", __func__);
- return -1;
- }
+ zebra->lsp_process_q = work_queue_new(zebra->master, "LSP processing");
+ if (!zebra->lsp_process_q) {
+ zlog_err("%s: could not initialise work queue!", __func__);
+ return -1;
+ }
- zebra->lsp_process_q->spec.workfunc = &lsp_process;
- zebra->lsp_process_q->spec.del_item_data = &lsp_processq_del;
- zebra->lsp_process_q->spec.errorfunc = NULL;
- zebra->lsp_process_q->spec.completion_func = &lsp_processq_complete;
- zebra->lsp_process_q->spec.max_retries = 0;
- zebra->lsp_process_q->spec.hold = 10;
+ zebra->lsp_process_q->spec.workfunc = &lsp_process;
+ zebra->lsp_process_q->spec.del_item_data = &lsp_processq_del;
+ zebra->lsp_process_q->spec.errorfunc = NULL;
+ zebra->lsp_process_q->spec.completion_func = &lsp_processq_complete;
+ zebra->lsp_process_q->spec.max_retries = 0;
+ zebra->lsp_process_q->spec.hold = 10;
- return 0;
+ return 0;
}
-
/* Public functions */
/*
@@ -1738,132 +1623,128 @@ mpls_processq_init (struct zebra_t *zebra)
* -2 if a label was inside the reserved range (0-15)
* -3 if the number of labels given exceeds MPLS_MAX_LABELS
*/
-int
-mpls_str2label (const char *label_str, u_int8_t *num_labels,
- mpls_label_t *labels)
-{
- char *ostr; // copy of label string (start)
- char *lstr; // copy of label string
- char *nump; // pointer to next segment
- char *endp; // end pointer
- int i; // for iterating label_str
- int rc; // return code
- mpls_label_t pl[MPLS_MAX_LABELS]; // parsed labels
-
- /* labels to zero until we have a successful parse */
- ostr = lstr = XSTRDUP (MTYPE_TMP, label_str);
- *num_labels = 0;
- rc = 0;
-
- for (i = 0; i < MPLS_MAX_LABELS && lstr && !rc; i++)
- {
- nump = strsep (&lstr, "/");
- pl[i] = strtoul(nump, &endp, 10);
-
- /* format check */
- if (*endp != '\0')
- rc = -1;
- /* validity check */
- else if (!IS_MPLS_UNRESERVED_LABEL(pl[i]))
- rc = -2;
- }
+int mpls_str2label(const char *label_str, u_int8_t *num_labels,
+ mpls_label_t *labels)
+{
+ char *ostr; // copy of label string (start)
+ char *lstr; // copy of label string
+ char *nump; // pointer to next segment
+ char *endp; // end pointer
+ int i; // for iterating label_str
+ int rc; // return code
+ mpls_label_t pl[MPLS_MAX_LABELS]; // parsed labels
+
+ /* labels to zero until we have a successful parse */
+ ostr = lstr = XSTRDUP(MTYPE_TMP, label_str);
+ *num_labels = 0;
+ rc = 0;
+
+ for (i = 0; i < MPLS_MAX_LABELS && lstr && !rc; i++) {
+ nump = strsep(&lstr, "/");
+ pl[i] = strtoul(nump, &endp, 10);
+
+ /* format check */
+ if (*endp != '\0')
+ rc = -1;
+ /* validity check */
+ else if (!IS_MPLS_UNRESERVED_LABEL(pl[i]))
+ rc = -2;
+ }
- /* excess labels */
- if (!rc && i == MPLS_MAX_LABELS && lstr)
- rc = -3;
+ /* excess labels */
+ if (!rc && i == MPLS_MAX_LABELS && lstr)
+ rc = -3;
- if (!rc)
- {
- *num_labels = i;
- memcpy (labels, pl, *num_labels * sizeof (mpls_label_t));
- }
+ if (!rc) {
+ *num_labels = i;
+ memcpy(labels, pl, *num_labels * sizeof(mpls_label_t));
+ }
- XFREE (MTYPE_TMP, ostr);
+ XFREE(MTYPE_TMP, ostr);
- return rc;
+ return rc;
}
/*
* Label to string conversion, labels in string separated by '/'.
*/
-char *
-mpls_label2str (u_int8_t num_labels, mpls_label_t *labels,
- char *buf, int len, int pretty)
-{
- char *buf_ptr = buf;
- buf[0] = '\0';
-
- if (pretty) {
- if (num_labels == 1) {
- label2str(labels[0], buf, len);
- } else if (num_labels == 2) {
- label2str(labels[0], buf, len);
- buf_ptr += strlen(buf);
-
- snprintf (buf_ptr, len, "/");
- buf_ptr++;
-
- label2str(labels[1], buf_ptr, len);
- }
- } else {
- if (num_labels == 1)
- snprintf (buf, len, "%u", labels[0]);
- else if (num_labels == 2)
- snprintf (buf, len, "%u/%u", labels[0], labels[1]);
- }
- return buf;
+char *mpls_label2str(u_int8_t num_labels, mpls_label_t *labels, char *buf,
+ int len, int pretty)
+{
+ char *buf_ptr = buf;
+ buf[0] = '\0';
+
+ if (pretty) {
+ if (num_labels == 1) {
+ label2str(labels[0], buf, len);
+ } else if (num_labels == 2) {
+ label2str(labels[0], buf, len);
+ buf_ptr += strlen(buf);
+
+ snprintf(buf_ptr, len, "/");
+ buf_ptr++;
+
+ label2str(labels[1], buf_ptr, len);
+ }
+ } else {
+ if (num_labels == 1)
+ snprintf(buf, len, "%u", labels[0]);
+ else if (num_labels == 2)
+ snprintf(buf, len, "%u/%u", labels[0], labels[1]);
+ }
+ return buf;
}
/*
* Install dynamic LSP entry.
*/
-int
-zebra_mpls_lsp_install (struct zebra_vrf *zvrf, struct route_node *rn, struct route_entry *re)
+int zebra_mpls_lsp_install(struct zebra_vrf *zvrf, struct route_node *rn,
+ struct route_entry *re)
{
- struct route_table *table;
- zebra_fec_t *fec;
+ struct route_table *table;
+ zebra_fec_t *fec;
- table = zvrf->fec_table[family2afi(PREFIX_FAMILY(&rn->p))];
- if (!table)
- return -1;
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(&rn->p))];
+ if (!table)
+ return -1;
- /* See if there is a configured label binding for this FEC. */
- fec = fec_find (table, &rn->p);
- if (!fec || fec->label == MPLS_INVALID_LABEL)
- return 0;
+ /* See if there is a configured label binding for this FEC. */
+ fec = fec_find(table, &rn->p);
+ if (!fec || fec->label == MPLS_INVALID_LABEL)
+ return 0;
- /* We cannot install a label forwarding entry if local label is the
- * implicit-null label.
- */
- if (fec->label == MPLS_IMP_NULL_LABEL)
- return 0;
+ /* We cannot install a label forwarding entry if local label is the
+ * implicit-null label.
+ */
+ if (fec->label == MPLS_IMP_NULL_LABEL)
+ return 0;
- if (lsp_install (zvrf, fec->label, rn, re))
- return -1;
+ if (lsp_install(zvrf, fec->label, rn, re))
+ return -1;
- return 0;
+ return 0;
}
/*
* Uninstall dynamic LSP entry, if any.
*/
-int
-zebra_mpls_lsp_uninstall (struct zebra_vrf *zvrf, struct route_node *rn, struct route_entry *re)
+int zebra_mpls_lsp_uninstall(struct zebra_vrf *zvrf, struct route_node *rn,
+ struct route_entry *re)
{
- struct route_table *table;
- zebra_fec_t *fec;
+ struct route_table *table;
+ zebra_fec_t *fec;
- table = zvrf->fec_table[family2afi(PREFIX_FAMILY(&rn->p))];
- if (!table)
- return -1;
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(&rn->p))];
+ if (!table)
+ return -1;
- /* See if there is a configured label binding for this FEC. */
- fec = fec_find (table, &rn->p);
- if (!fec || fec->label == MPLS_INVALID_LABEL)
- return 0;
+ /* See if there is a configured label binding for this FEC. */
+ fec = fec_find(table, &rn->p);
+ if (!fec || fec->label == MPLS_INVALID_LABEL)
+ return 0;
- /* Uninstall always removes all dynamic NHLFEs. */
- return lsp_uninstall (zvrf, fec->label);
+ /* Uninstall always removes all dynamic NHLFEs. */
+ return lsp_uninstall(zvrf, fec->label);
}
/*
@@ -1874,91 +1755,85 @@ zebra_mpls_lsp_uninstall (struct zebra_vrf *zvrf, struct route_node *rn, struct
* label from a locally configured label block (SRGB), if one exists and index
* is acceptable.
*/
-int
-zebra_mpls_fec_register (struct zebra_vrf *zvrf, struct prefix *p,
- u_int32_t label_index, struct zserv *client)
-{
- struct route_table *table;
- zebra_fec_t *fec;
- char buf[BUFSIZ];
- int new_client;
- int label_change = 0;
- u_int32_t old_label;
-
- table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
- if (!table)
- return -1;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- prefix2str(p, buf, BUFSIZ);
-
- /* Locate FEC */
- fec = fec_find (table, p);
- if (!fec)
- {
- fec = fec_add (table, p, MPLS_INVALID_LABEL, 0, label_index);
- if (!fec)
- {
- prefix2str(p, buf, BUFSIZ);
- zlog_err("Failed to add FEC %s upon register, client %s",
- buf, zebra_route_string(client->proto));
- return -1;
- }
-
- old_label = MPLS_INVALID_LABEL;
- new_client = 1;
- }
- else
- {
- /* Client may register same FEC with different label index. */
- new_client = (listnode_lookup(fec->client_list, client) == NULL);
- if (!new_client && fec->label_index == label_index)
- /* Duplicate register */
- return 0;
-
- /* Save current label, update label index */
- old_label = fec->label;
- fec->label_index = label_index;
- }
-
- if (new_client)
- listnode_add (fec->client_list, client);
-
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug("FEC %s Label Index %u %s by client %s",
- buf, label_index, new_client ? "registered" : "updated",
- zebra_route_string(client->proto));
-
- /* If not a configured FEC, derive the local label (from label index)
- * or reset it.
- */
- if (!(fec->flags & FEC_FLAG_CONFIGURED))
- {
- fec_derive_label_from_index (zvrf, fec);
-
- /* If no label change, exit. */
- if (fec->label == old_label)
- return 0;
-
- label_change = 1;
- }
-
- /* If new client or label change, update client and install or uninstall
- * label forwarding entry as needed.
- */
- /* Inform client of label, if needed. */
- if ((new_client && fec->label != MPLS_INVALID_LABEL) ||
- label_change)
- {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug ("Update client label %u", fec->label);
- fec_send (fec, client);
- }
-
- if (new_client || label_change)
- return fec_change_update_lsp (zvrf, fec, old_label);
-
- return 0;
+int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
+ u_int32_t label_index, struct zserv *client)
+{
+ struct route_table *table;
+ zebra_fec_t *fec;
+ char buf[BUFSIZ];
+ int new_client;
+ int label_change = 0;
+ u_int32_t old_label;
+
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
+ if (!table)
+ return -1;
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ prefix2str(p, buf, BUFSIZ);
+
+ /* Locate FEC */
+ fec = fec_find(table, p);
+ if (!fec) {
+ fec = fec_add(table, p, MPLS_INVALID_LABEL, 0, label_index);
+ if (!fec) {
+ prefix2str(p, buf, BUFSIZ);
+ zlog_err(
+ "Failed to add FEC %s upon register, client %s",
+ buf, zebra_route_string(client->proto));
+ return -1;
+ }
+
+ old_label = MPLS_INVALID_LABEL;
+ new_client = 1;
+ } else {
+ /* Client may register same FEC with different label index. */
+ new_client =
+ (listnode_lookup(fec->client_list, client) == NULL);
+ if (!new_client && fec->label_index == label_index)
+ /* Duplicate register */
+ return 0;
+
+ /* Save current label, update label index */
+ old_label = fec->label;
+ fec->label_index = label_index;
+ }
+
+ if (new_client)
+ listnode_add(fec->client_list, client);
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("FEC %s Label Index %u %s by client %s", buf,
+ label_index, new_client ? "registered" : "updated",
+ zebra_route_string(client->proto));
+
+ /* If not a configured FEC, derive the local label (from label index)
+ * or reset it.
+ */
+ if (!(fec->flags & FEC_FLAG_CONFIGURED)) {
+ fec_derive_label_from_index(zvrf, fec);
+
+ /* If no label change, exit. */
+ if (fec->label == old_label)
+ return 0;
+
+ label_change = 1;
+ }
+
+ /* If new client or label change, update client and install or uninstall
+ * label forwarding entry as needed.
+ */
+ /* Inform client of label, if needed. */
+ if ((new_client && fec->label != MPLS_INVALID_LABEL) || label_change) {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("Update client label %u", fec->label);
+ fec_send(fec, client);
+ }
+
+ if (new_client || label_change)
+ return fec_change_update_lsp(zvrf, fec, old_label);
+
+ return 0;
}
/*
@@ -1966,89 +1841,85 @@ zebra_mpls_fec_register (struct zebra_vrf *zvrf, struct prefix *p,
* itself is deleted if no other registered clients exist and there is no
* label bound to the FEC.
*/
-int
-zebra_mpls_fec_unregister (struct zebra_vrf *zvrf, struct prefix *p,
- struct zserv *client)
+int zebra_mpls_fec_unregister(struct zebra_vrf *zvrf, struct prefix *p,
+ struct zserv *client)
{
- struct route_table *table;
- zebra_fec_t *fec;
- char buf[BUFSIZ];
-
- table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
- if (!table)
- return -1;
+ struct route_table *table;
+ zebra_fec_t *fec;
+ char buf[BUFSIZ];
- if (IS_ZEBRA_DEBUG_MPLS)
- prefix2str(p, buf, BUFSIZ);
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
+ if (!table)
+ return -1;
- fec = fec_find (table, p);
- if (!fec)
- {
- prefix2str(p, buf, BUFSIZ);
- zlog_err("Failed to find FEC %s upon unregister, client %s",
- buf, zebra_route_string(client->proto));
- return -1;
- }
+ if (IS_ZEBRA_DEBUG_MPLS)
+ prefix2str(p, buf, BUFSIZ);
- listnode_delete(fec->client_list, client);
-
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug("FEC %s unregistered by client %s",
- buf, zebra_route_string(client->proto));
+ fec = fec_find(table, p);
+ if (!fec) {
+ prefix2str(p, buf, BUFSIZ);
+ zlog_err("Failed to find FEC %s upon unregister, client %s",
+ buf, zebra_route_string(client->proto));
+ return -1;
+ }
- /* If not a configured entry, delete the FEC if no other clients. Before
- * deleting, see if any LSP needs to be uninstalled.
- */
- if (!(fec->flags & FEC_FLAG_CONFIGURED) &&
- list_isempty(fec->client_list))
- {
- mpls_label_t old_label = fec->label;
- fec->label = MPLS_INVALID_LABEL; /* reset */
- fec_change_update_lsp (zvrf, fec, old_label);
- fec_del (fec);
- }
+ listnode_delete(fec->client_list, client);
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("FEC %s unregistered by client %s", buf,
+ zebra_route_string(client->proto));
+
+ /* If not a configured entry, delete the FEC if no other clients. Before
+ * deleting, see if any LSP needs to be uninstalled.
+ */
+ if (!(fec->flags & FEC_FLAG_CONFIGURED)
+ && list_isempty(fec->client_list)) {
+ mpls_label_t old_label = fec->label;
+ fec->label = MPLS_INVALID_LABEL; /* reset */
+ fec_change_update_lsp(zvrf, fec, old_label);
+ fec_del(fec);
+ }
- return 0;
+ return 0;
}
/*
* Cleanup any FECs registered by this client.
*/
-int
-zebra_mpls_cleanup_fecs_for_client (struct zebra_vrf *zvrf, struct zserv *client)
-{
- struct route_node *rn;
- zebra_fec_t *fec;
- struct listnode *node;
- struct zserv *fec_client;
- int af;
-
- for (af = AFI_IP; af < AFI_MAX; af++)
- {
- if (zvrf->fec_table[af] == NULL)
- continue;
-
- for (rn = route_top(zvrf->fec_table[af]); rn; rn = route_next(rn))
- {
- fec = rn->info;
- if (!fec || list_isempty(fec->client_list))
- continue;
-
- for (ALL_LIST_ELEMENTS_RO(fec->client_list, node, fec_client))
- {
- if (fec_client == client)
- {
- listnode_delete(fec->client_list, fec_client);
- if (!(fec->flags & FEC_FLAG_CONFIGURED) &&
- list_isempty(fec->client_list))
- fec_del (fec);
- break;
- }
- }
- }
- }
+int zebra_mpls_cleanup_fecs_for_client(struct zebra_vrf *zvrf,
+ struct zserv *client)
+{
+ struct route_node *rn;
+ zebra_fec_t *fec;
+ struct listnode *node;
+ struct zserv *fec_client;
+ int af;
+
+ for (af = AFI_IP; af < AFI_MAX; af++) {
+ if (zvrf->fec_table[af] == NULL)
+ continue;
+
+ for (rn = route_top(zvrf->fec_table[af]); rn;
+ rn = route_next(rn)) {
+ fec = rn->info;
+ if (!fec || list_isempty(fec->client_list))
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(fec->client_list, node,
+ fec_client)) {
+ if (fec_client == client) {
+ listnode_delete(fec->client_list,
+ fec_client);
+ if (!(fec->flags & FEC_FLAG_CONFIGURED)
+ && list_isempty(fec->client_list))
+ fec_del(fec);
+ break;
+ }
+ }
+ }
+ }
- return 0;
+ return 0;
}
/*
@@ -2058,38 +1929,36 @@ zebra_mpls_cleanup_fecs_for_client (struct zebra_vrf *zvrf, struct zserv *client
* TODO: Currently walks entire table, can optimize later with another
* hash..
*/
-zebra_fec_t *
-zebra_mpls_fec_for_label (struct zebra_vrf *zvrf, mpls_label_t label)
-{
- struct route_node *rn;
- zebra_fec_t *fec;
- int af;
-
- for (af = AFI_IP; af < AFI_MAX; af++)
- {
- if (zvrf->fec_table[af] == NULL)
- continue;
-
- for (rn = route_top(zvrf->fec_table[af]); rn; rn = route_next(rn))
- {
- if (!rn->info)
- continue;
- fec = rn->info;
- if (fec->label == label)
- return fec;
- }
- }
+zebra_fec_t *zebra_mpls_fec_for_label(struct zebra_vrf *zvrf,
+ mpls_label_t label)
+{
+ struct route_node *rn;
+ zebra_fec_t *fec;
+ int af;
+
+ for (af = AFI_IP; af < AFI_MAX; af++) {
+ if (zvrf->fec_table[af] == NULL)
+ continue;
+
+ for (rn = route_top(zvrf->fec_table[af]); rn;
+ rn = route_next(rn)) {
+ if (!rn->info)
+ continue;
+ fec = rn->info;
+ if (fec->label == label)
+ return fec;
+ }
+ }
- return NULL;
+ return NULL;
}
/*
* Inform if specified label is currently bound to a FEC or not.
*/
-int
-zebra_mpls_label_already_bound (struct zebra_vrf *zvrf, mpls_label_t label)
+int zebra_mpls_label_already_bound(struct zebra_vrf *zvrf, mpls_label_t label)
{
- return (zebra_mpls_fec_for_label (zvrf, label) ? 1 : 0);
+ return (zebra_mpls_fec_for_label(zvrf, label) ? 1 : 0);
}
/*
@@ -2097,59 +1966,54 @@ zebra_mpls_label_already_bound (struct zebra_vrf *zvrf, mpls_label_t label)
* FEC, notify them. If there are labeled routes for this FEC, install the
* label forwarding entry.
*/
-int
-zebra_mpls_static_fec_add (struct zebra_vrf *zvrf, struct prefix *p,
- mpls_label_t in_label)
-{
- struct route_table *table;
- zebra_fec_t *fec;
- char buf[BUFSIZ];
- mpls_label_t old_label;
- int ret = 0;
-
- table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
- if (!table)
- return -1;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- prefix2str(p, buf, BUFSIZ);
-
- /* Update existing FEC or create a new one. */
- fec = fec_find (table, p);
- if (!fec)
- {
- fec = fec_add (table, p, in_label, FEC_FLAG_CONFIGURED,
- MPLS_INVALID_LABEL_INDEX);
- if (!fec)
- {
- prefix2str(p, buf, BUFSIZ);
- zlog_err ("Failed to add FEC %s upon config", buf);
- return -1;
- }
-
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug ("Add fec %s label %u", buf, in_label);
- }
- else
- {
- fec->flags |= FEC_FLAG_CONFIGURED;
- if (fec->label == in_label)
- /* Duplicate config */
- return 0;
-
- /* Label change, update clients. */
- old_label = fec->label;
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug ("Update fec %s new label %u", buf, in_label);
-
- fec->label = in_label;
- fec_update_clients (fec);
-
- /* Update label forwarding entries appropriately */
- ret = fec_change_update_lsp (zvrf, fec, old_label);
- }
-
- return ret;
+int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p,
+ mpls_label_t in_label)
+{
+ struct route_table *table;
+ zebra_fec_t *fec;
+ char buf[BUFSIZ];
+ mpls_label_t old_label;
+ int ret = 0;
+
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
+ if (!table)
+ return -1;
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ prefix2str(p, buf, BUFSIZ);
+
+ /* Update existing FEC or create a new one. */
+ fec = fec_find(table, p);
+ if (!fec) {
+ fec = fec_add(table, p, in_label, FEC_FLAG_CONFIGURED,
+ MPLS_INVALID_LABEL_INDEX);
+ if (!fec) {
+ prefix2str(p, buf, BUFSIZ);
+ zlog_err("Failed to add FEC %s upon config", buf);
+ return -1;
+ }
+
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("Add fec %s label %u", buf, in_label);
+ } else {
+ fec->flags |= FEC_FLAG_CONFIGURED;
+ if (fec->label == in_label)
+ /* Duplicate config */
+ return 0;
+
+ /* Label change, update clients. */
+ old_label = fec->label;
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("Update fec %s new label %u", buf, in_label);
+
+ fec->label = in_label;
+ fec_update_clients(fec);
+
+ /* Update label forwarding entries appropriately */
+ ret = fec_change_update_lsp(zvrf, fec, old_label);
+ }
+
+ return ret;
}
/*
@@ -2158,218 +2022,210 @@ zebra_mpls_static_fec_add (struct zebra_vrf *zvrf, struct prefix *p,
* Note: Upon delete of static binding, if label index exists for this FEC,
* client may need to be updated with derived label.
*/
-int
-zebra_mpls_static_fec_del (struct zebra_vrf *zvrf, struct prefix *p)
-{
- struct route_table *table;
- zebra_fec_t *fec;
- mpls_label_t old_label;
- char buf[BUFSIZ];
-
- table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
- if (!table)
- return -1;
-
- fec = fec_find (table, p);
- if (!fec)
- {
- prefix2str(p, buf, BUFSIZ);
- zlog_err("Failed to find FEC %s upon delete", buf);
- return -1;
- }
-
- if (IS_ZEBRA_DEBUG_MPLS)
- {
- prefix2str(p, buf, BUFSIZ);
- zlog_debug ("Delete fec %s label index %u",
- buf, fec->label_index);
- }
-
- old_label = fec->label;
- fec->flags &= ~FEC_FLAG_CONFIGURED;
- fec->label = MPLS_INVALID_LABEL;
-
- /* If no client exists, just delete the FEC. */
- if (list_isempty(fec->client_list))
- {
- fec_del (fec);
- return 0;
- }
-
- /* Derive the local label (from label index) or reset it. */
- fec_derive_label_from_index (zvrf, fec);
-
- /* If there is a label change, update clients. */
- if (fec->label == old_label)
- return 0;
- fec_update_clients (fec);
-
- /* Update label forwarding entries appropriately */
- return fec_change_update_lsp (zvrf, fec, old_label);
+int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p)
+{
+ struct route_table *table;
+ zebra_fec_t *fec;
+ mpls_label_t old_label;
+ char buf[BUFSIZ];
+
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
+ if (!table)
+ return -1;
+
+ fec = fec_find(table, p);
+ if (!fec) {
+ prefix2str(p, buf, BUFSIZ);
+ zlog_err("Failed to find FEC %s upon delete", buf);
+ return -1;
+ }
+
+ if (IS_ZEBRA_DEBUG_MPLS) {
+ prefix2str(p, buf, BUFSIZ);
+ zlog_debug("Delete fec %s label index %u", buf,
+ fec->label_index);
+ }
+
+ old_label = fec->label;
+ fec->flags &= ~FEC_FLAG_CONFIGURED;
+ fec->label = MPLS_INVALID_LABEL;
+
+ /* If no client exists, just delete the FEC. */
+ if (list_isempty(fec->client_list)) {
+ fec_del(fec);
+ return 0;
+ }
+
+ /* Derive the local label (from label index) or reset it. */
+ fec_derive_label_from_index(zvrf, fec);
+
+ /* If there is a label change, update clients. */
+ if (fec->label == old_label)
+ return 0;
+ fec_update_clients(fec);
+
+ /* Update label forwarding entries appropriately */
+ return fec_change_update_lsp(zvrf, fec, old_label);
}
/*
* Display MPLS FEC to label binding configuration (VTY command handler).
*/
-int
-zebra_mpls_write_fec_config (struct vty *vty, struct zebra_vrf *zvrf)
+int zebra_mpls_write_fec_config(struct vty *vty, struct zebra_vrf *zvrf)
{
- struct route_node *rn;
- int af;
- zebra_fec_t *fec;
- char buf[BUFSIZ];
- int write = 0;
+ struct route_node *rn;
+ int af;
+ zebra_fec_t *fec;
+ char buf[BUFSIZ];
+ int write = 0;
- for (af = AFI_IP; af < AFI_MAX; af++)
- {
- if (zvrf->fec_table[af] == NULL)
- continue;
+ for (af = AFI_IP; af < AFI_MAX; af++) {
+ if (zvrf->fec_table[af] == NULL)
+ continue;
- for (rn = route_top(zvrf->fec_table[af]); rn; rn = route_next(rn))
- {
- if (!rn->info)
- continue;
+ for (rn = route_top(zvrf->fec_table[af]); rn;
+ rn = route_next(rn)) {
+ if (!rn->info)
+ continue;
- char lstr[BUFSIZ];
- fec = rn->info;
+ char lstr[BUFSIZ];
+ fec = rn->info;
- if (!(fec->flags & FEC_FLAG_CONFIGURED))
- continue;
+ if (!(fec->flags & FEC_FLAG_CONFIGURED))
+ continue;
- write = 1;
- prefix2str(&rn->p, buf, BUFSIZ);
- vty_out (vty, "mpls label bind %s %s\n", buf,
- label2str(fec->label, lstr, BUFSIZ));
- }
- }
+ write = 1;
+ prefix2str(&rn->p, buf, BUFSIZ);
+ vty_out(vty, "mpls label bind %s %s\n", buf,
+ label2str(fec->label, lstr, BUFSIZ));
+ }
+ }
- return write;
+ return write;
}
/*
* Display MPLS FEC to label binding (VTY command handler).
*/
-void
-zebra_mpls_print_fec_table (struct vty *vty, struct zebra_vrf *zvrf)
+void zebra_mpls_print_fec_table(struct vty *vty, struct zebra_vrf *zvrf)
{
- struct route_node *rn;
- int af;
+ struct route_node *rn;
+ int af;
- for (af = AFI_IP; af < AFI_MAX; af++)
- {
- if (zvrf->fec_table[af] == NULL)
- continue;
+ for (af = AFI_IP; af < AFI_MAX; af++) {
+ if (zvrf->fec_table[af] == NULL)
+ continue;
- for (rn = route_top(zvrf->fec_table[af]); rn; rn = route_next(rn))
- {
- if (!rn->info)
- continue;
- fec_print (rn->info, vty);
- }
- }
+ for (rn = route_top(zvrf->fec_table[af]); rn;
+ rn = route_next(rn)) {
+ if (!rn->info)
+ continue;
+ fec_print(rn->info, vty);
+ }
+ }
}
/*
* Display MPLS FEC to label binding for a specific FEC (VTY command handler).
*/
-void
-zebra_mpls_print_fec (struct vty *vty, struct zebra_vrf *zvrf, struct prefix *p)
+void zebra_mpls_print_fec(struct vty *vty, struct zebra_vrf *zvrf,
+ struct prefix *p)
{
- struct route_table *table;
- struct route_node *rn;
+ struct route_table *table;
+ struct route_node *rn;
- table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
- if (!table)
- return;
+ table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
+ if (!table)
+ return;
- apply_mask (p);
- rn = route_node_lookup(table, p);
- if (!rn)
- return;
+ apply_mask(p);
+ rn = route_node_lookup(table, p);
+ if (!rn)
+ return;
- route_unlock_node(rn);
- if (!rn->info)
- return;
+ route_unlock_node(rn);
+ if (!rn->info)
+ return;
- fec_print (rn->info, vty);
+ fec_print(rn->info, vty);
}
/*
* Install/uninstall a FEC-To-NHLFE (FTN) binding.
*/
-int
-mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
- struct prefix *prefix, enum nexthop_types_t gtype,
- union g_addr *gate, ifindex_t ifindex, u_int8_t distance,
- mpls_label_t out_label)
-{
- struct route_table *table;
- struct route_node *rn;
- struct route_entry *re;
- struct nexthop *nexthop;
-
- /* Lookup table. */
- table = zebra_vrf_table (family2afi(prefix->family), SAFI_UNICAST, zvrf_id (zvrf));
- if (! table)
- return -1;
-
- /* Lookup existing route */
- rn = route_node_get (table, prefix);
- RNODE_FOREACH_RE (rn, re)
- {
- if (CHECK_FLAG (re->status, ROUTE_ENTRY_REMOVED))
- continue;
- if (re->distance == distance)
- break;
- }
-
- if (re == NULL)
- return -1;
-
- for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
- {
- switch (nexthop->type)
+int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
+ struct prefix *prefix, enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex, u_int8_t distance,
+ mpls_label_t out_label)
+{
+ struct route_table *table;
+ struct route_node *rn;
+ struct route_entry *re;
+ struct nexthop *nexthop;
+
+ /* Lookup table. */
+ table = zebra_vrf_table(family2afi(prefix->family), SAFI_UNICAST,
+ zvrf_id(zvrf));
+ if (!table)
+ return -1;
+
+ /* Lookup existing route */
+ rn = route_node_get(table, prefix);
+ RNODE_FOREACH_RE(rn, re)
{
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- if (gtype != NEXTHOP_TYPE_IPV4 && gtype != NEXTHOP_TYPE_IPV4_IFINDEX)
- continue;
- if (! IPV4_ADDR_SAME (&nexthop->gate.ipv4, &gate->ipv4))
- continue;
- if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX &&
- nexthop->ifindex != ifindex)
- continue;
- goto found;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- if (gtype != NEXTHOP_TYPE_IPV6 && gtype != NEXTHOP_TYPE_IPV6_IFINDEX)
- continue;
- if (! IPV6_ADDR_SAME (&nexthop->gate.ipv6, &gate->ipv6))
- continue;
- if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX &&
- nexthop->ifindex != ifindex)
- continue;
- goto found;
- default:
- break;
+ if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
+ continue;
+ if (re->distance == distance)
+ break;
}
- }
- /* nexthop not found */
- return -1;
- found:
- if (add && nexthop->nh_label_type == ZEBRA_LSP_NONE)
- nexthop_add_labels (nexthop, type, 1, &out_label);
- else if (!add && nexthop->nh_label_type == type)
- nexthop_del_labels (nexthop);
- else
- return 0;
+ if (re == NULL)
+ return -1;
+
+ for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next) {
+ switch (nexthop->type) {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ if (gtype != NEXTHOP_TYPE_IPV4
+ && gtype != NEXTHOP_TYPE_IPV4_IFINDEX)
+ continue;
+ if (!IPV4_ADDR_SAME(&nexthop->gate.ipv4, &gate->ipv4))
+ continue;
+ if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
+ && nexthop->ifindex != ifindex)
+ continue;
+ goto found;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ if (gtype != NEXTHOP_TYPE_IPV6
+ && gtype != NEXTHOP_TYPE_IPV6_IFINDEX)
+ continue;
+ if (!IPV6_ADDR_SAME(&nexthop->gate.ipv6, &gate->ipv6))
+ continue;
+ if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
+ && nexthop->ifindex != ifindex)
+ continue;
+ goto found;
+ default:
+ break;
+ }
+ }
+ /* nexthop not found */
+ return -1;
+
+found:
+ if (add && nexthop->nh_label_type == ZEBRA_LSP_NONE)
+ nexthop_add_labels(nexthop, type, 1, &out_label);
+ else if (!add && nexthop->nh_label_type == type)
+ nexthop_del_labels(nexthop);
+ else
+ return 0;
- SET_FLAG (re->status, ROUTE_ENTRY_CHANGED);
- SET_FLAG (re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
- rib_queue_add (rn);
+ SET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
+ SET_FLAG(re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
+ rib_queue_add(rn);
- return 0;
+ return 0;
}
/*
@@ -2377,197 +2233,185 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
* a new LSP entry or a new NHLFE for an existing in-label or an update of
* the out-label for an existing NHLFE (update case).
*/
-int
-mpls_lsp_install (struct zebra_vrf *zvrf, enum lsp_types_t type,
- mpls_label_t in_label, mpls_label_t out_label,
- enum nexthop_types_t gtype, union g_addr *gate,
- ifindex_t ifindex)
-{
- struct hash *lsp_table;
- zebra_ile_t tmp_ile;
- zebra_lsp_t *lsp;
- zebra_nhlfe_t *nhlfe;
- char buf[BUFSIZ];
-
- /* Lookup table. */
- lsp_table = zvrf->lsp_table;
- if (!lsp_table)
- return -1;
-
- /* If entry is present, exit. */
- tmp_ile.in_label = in_label;
- lsp = hash_get (lsp_table, &tmp_ile, lsp_alloc);
- if (!lsp)
- return -1;
- nhlfe = nhlfe_find (lsp, type, gtype, gate, ifindex);
- if (nhlfe)
- {
- struct nexthop *nh = nhlfe->nexthop;
-
- assert (nh);
- assert (nh->nh_label);
-
- /* Clear deleted flag (in case it was set) */
- UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED);
- if (nh->nh_label->label[0] == out_label)
- /* No change */
- return 0;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- {
- nhlfe2str (nhlfe, buf, BUFSIZ);
- zlog_debug ("LSP in-label %u type %d nexthop %s "
- "out-label changed to %u (old %u)",
- in_label, type, buf,
- out_label, nh->nh_label->label[0]);
- }
-
- /* Update out label, trigger processing. */
- nh->nh_label->label[0] = out_label;
- }
- else
- {
- /* Add LSP entry to this nexthop */
- nhlfe = nhlfe_add (lsp, type, gtype, gate, ifindex, out_label);
- if (!nhlfe)
- return -1;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- {
- nhlfe2str (nhlfe, buf, BUFSIZ);
- zlog_debug ("Add LSP in-label %u type %d nexthop %s "
- "out-label %u", in_label, type, buf, out_label);
- }
-
- lsp->addr_family = NHLFE_FAMILY (nhlfe);
- }
-
- /* Mark NHLFE, queue LSP for processing. */
- SET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED);
- if (lsp_processq_add (lsp))
- return -1;
-
- return 0;
+int mpls_lsp_install(struct zebra_vrf *zvrf, enum lsp_types_t type,
+ mpls_label_t in_label, mpls_label_t out_label,
+ enum nexthop_types_t gtype, union g_addr *gate,
+ ifindex_t ifindex)
+{
+ struct hash *lsp_table;
+ zebra_ile_t tmp_ile;
+ zebra_lsp_t *lsp;
+ zebra_nhlfe_t *nhlfe;
+ char buf[BUFSIZ];
+
+ /* Lookup table. */
+ lsp_table = zvrf->lsp_table;
+ if (!lsp_table)
+ return -1;
+
+ /* If entry is present, exit. */
+ tmp_ile.in_label = in_label;
+ lsp = hash_get(lsp_table, &tmp_ile, lsp_alloc);
+ if (!lsp)
+ return -1;
+ nhlfe = nhlfe_find(lsp, type, gtype, gate, ifindex);
+ if (nhlfe) {
+ struct nexthop *nh = nhlfe->nexthop;
+
+ assert(nh);
+ assert(nh->nh_label);
+
+ /* Clear deleted flag (in case it was set) */
+ UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED);
+ if (nh->nh_label->label[0] == out_label)
+ /* No change */
+ return 0;
+
+ if (IS_ZEBRA_DEBUG_MPLS) {
+ nhlfe2str(nhlfe, buf, BUFSIZ);
+ zlog_debug(
+ "LSP in-label %u type %d nexthop %s "
+ "out-label changed to %u (old %u)",
+ in_label, type, buf, out_label,
+ nh->nh_label->label[0]);
+ }
+
+ /* Update out label, trigger processing. */
+ nh->nh_label->label[0] = out_label;
+ } else {
+ /* Add LSP entry to this nexthop */
+ nhlfe = nhlfe_add(lsp, type, gtype, gate, ifindex, out_label);
+ if (!nhlfe)
+ return -1;
+
+ if (IS_ZEBRA_DEBUG_MPLS) {
+ nhlfe2str(nhlfe, buf, BUFSIZ);
+ zlog_debug(
+ "Add LSP in-label %u type %d nexthop %s "
+ "out-label %u",
+ in_label, type, buf, out_label);
+ }
+
+ lsp->addr_family = NHLFE_FAMILY(nhlfe);
+ }
+
+ /* Mark NHLFE, queue LSP for processing. */
+ SET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED);
+ if (lsp_processq_add(lsp))
+ return -1;
+
+ return 0;
}
/*
* Uninstall a particular NHLFE in the forwarding table. If this is
* the only NHLFE, the entire LSP forwarding entry has to be deleted.
*/
-int
-mpls_lsp_uninstall (struct zebra_vrf *zvrf, enum lsp_types_t type,
- mpls_label_t in_label, enum nexthop_types_t gtype,
- union g_addr *gate, ifindex_t ifindex)
-{
- struct hash *lsp_table;
- zebra_ile_t tmp_ile;
- zebra_lsp_t *lsp;
- zebra_nhlfe_t *nhlfe;
- char buf[BUFSIZ];
-
- /* Lookup table. */
- lsp_table = zvrf->lsp_table;
- if (!lsp_table)
- return -1;
-
- /* If entry is not present, exit. */
- tmp_ile.in_label = in_label;
- lsp = hash_lookup (lsp_table, &tmp_ile);
- if (!lsp)
- return 0;
- nhlfe = nhlfe_find (lsp, type, gtype, gate, ifindex);
- if (!nhlfe)
- return 0;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- {
- nhlfe2str (nhlfe, buf, BUFSIZ);
- zlog_debug ("Del LSP in-label %u type %d nexthop %s flags 0x%x",
- in_label, type, buf, nhlfe->flags);
- }
-
- /* Mark NHLFE for delete or directly delete, as appropriate. */
- if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED))
- {
- UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED);
- SET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED);
- if (lsp_processq_add (lsp))
- return -1;
- }
- else
- {
- nhlfe_del (nhlfe);
-
- /* Free LSP entry if no other NHLFEs and not scheduled. */
- if (!lsp->nhlfe_list &&
- !CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED))
- {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug ("Free LSP in-label %u flags 0x%x",
- lsp->ile.in_label, lsp->flags);
-
- lsp = hash_release(lsp_table, &lsp->ile);
- if (lsp)
- XFREE(MTYPE_LSP, lsp);
- }
- }
- return 0;
+int mpls_lsp_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
+ mpls_label_t in_label, enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex)
+{
+ struct hash *lsp_table;
+ zebra_ile_t tmp_ile;
+ zebra_lsp_t *lsp;
+ zebra_nhlfe_t *nhlfe;
+ char buf[BUFSIZ];
+
+ /* Lookup table. */
+ lsp_table = zvrf->lsp_table;
+ if (!lsp_table)
+ return -1;
+
+ /* If entry is not present, exit. */
+ tmp_ile.in_label = in_label;
+ lsp = hash_lookup(lsp_table, &tmp_ile);
+ if (!lsp)
+ return 0;
+ nhlfe = nhlfe_find(lsp, type, gtype, gate, ifindex);
+ if (!nhlfe)
+ return 0;
+
+ if (IS_ZEBRA_DEBUG_MPLS) {
+ nhlfe2str(nhlfe, buf, BUFSIZ);
+ zlog_debug("Del LSP in-label %u type %d nexthop %s flags 0x%x",
+ in_label, type, buf, nhlfe->flags);
+ }
+
+ /* Mark NHLFE for delete or directly delete, as appropriate. */
+ if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) {
+ UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED);
+ SET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED);
+ if (lsp_processq_add(lsp))
+ return -1;
+ } else {
+ nhlfe_del(nhlfe);
+
+ /* Free LSP entry if no other NHLFEs and not scheduled. */
+ if (!lsp->nhlfe_list
+ && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("Free LSP in-label %u flags 0x%x",
+ lsp->ile.in_label, lsp->flags);
+
+ lsp = hash_release(lsp_table, &lsp->ile);
+ if (lsp)
+ XFREE(MTYPE_LSP, lsp);
+ }
+ }
+ return 0;
}
/*
* Uninstall all LDP NHLFEs for a particular LSP forwarding entry.
* If no other NHLFEs exist, the entry would be deleted.
*/
-void
-mpls_ldp_lsp_uninstall_all (struct hash_backet *backet, void *ctxt)
+void mpls_ldp_lsp_uninstall_all(struct hash_backet *backet, void *ctxt)
{
- zebra_lsp_t *lsp;
- struct hash *lsp_table;
+ zebra_lsp_t *lsp;
+ struct hash *lsp_table;
- lsp = (zebra_lsp_t *) backet->data;
- if (!lsp || !lsp->nhlfe_list)
- return;
+ lsp = (zebra_lsp_t *)backet->data;
+ if (!lsp || !lsp->nhlfe_list)
+ return;
- lsp_table = ctxt;
- if (!lsp_table)
- return;
+ lsp_table = ctxt;
+ if (!lsp_table)
+ return;
- mpls_lsp_uninstall_all (lsp_table, lsp, ZEBRA_LSP_LDP);
+ mpls_lsp_uninstall_all(lsp_table, lsp, ZEBRA_LSP_LDP);
}
/*
* Uninstall all LDP FEC-To-NHLFE (FTN) bindings of the given address-family.
*/
-void
-mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi)
-{
- struct route_table *table;
- struct route_node *rn;
- struct route_entry *re;
- struct nexthop *nexthop;
- int update;
-
- /* Process routes of interested address-families. */
- table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf_id (zvrf));
- if (!table)
- return;
-
- for (rn = route_top (table); rn; rn = route_next (rn))
- {
- update = 0;
- RNODE_FOREACH_RE (rn, re)
- for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
- if (nexthop->nh_label_type == ZEBRA_LSP_LDP)
- {
- nexthop_del_labels (nexthop);
- SET_FLAG (re->status, ROUTE_ENTRY_CHANGED);
- SET_FLAG (re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
- update = 1;
- }
-
- if (update)
- rib_queue_add (rn);
- }
+void mpls_ldp_ftn_uninstall_all(struct zebra_vrf *zvrf, int afi)
+{
+ struct route_table *table;
+ struct route_node *rn;
+ struct route_entry *re;
+ struct nexthop *nexthop;
+ int update;
+
+ /* Process routes of interested address-families. */
+ table = zebra_vrf_table(afi, SAFI_UNICAST, zvrf_id(zvrf));
+ if (!table)
+ return;
+
+ for (rn = route_top(table); rn; rn = route_next(rn)) {
+ update = 0;
+ RNODE_FOREACH_RE(rn, re)
+ for (nexthop = re->nexthop; nexthop; nexthop = nexthop->next)
+ if (nexthop->nh_label_type == ZEBRA_LSP_LDP) {
+ nexthop_del_labels(nexthop);
+ SET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
+ SET_FLAG(re->status,
+ ROUTE_ENTRY_NEXTHOPS_CHANGED);
+ update = 1;
+ }
+
+ if (update)
+ rib_queue_add(rn);
+ }
}
#if defined(HAVE_CUMULUS)
@@ -2577,54 +2421,51 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi)
* be consistent - i.e., all paths either do a swap or do PHP. This is due
* to current HW restrictions.
*/
-int
-zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,
- mpls_label_t out_label, enum nexthop_types_t gtype,
- union g_addr *gate, ifindex_t ifindex)
-{
- struct hash *slsp_table;
- zebra_ile_t tmp_ile;
- zebra_slsp_t *slsp;
- zebra_snhlfe_t *snhlfe;
-
- /* Lookup table. */
- slsp_table = zvrf->slsp_table;
- if (!slsp_table)
- return 0;
-
- /* If entry is not present, exit. */
- tmp_ile.in_label = in_label;
- slsp = hash_lookup (slsp_table, &tmp_ile);
- if (!slsp)
- return 1;
-
- snhlfe = snhlfe_find (slsp, gtype, gate, ifindex);
- if (snhlfe)
- {
- if (snhlfe->out_label == out_label)
- return 1;
-
- /* If not only NHLFE, cannot allow label change. */
- if (snhlfe != slsp->snhlfe_list ||
- snhlfe->next)
- return 0;
- }
- else
- {
- /* If other NHLFEs exist, label operation must match. */
- if (slsp->snhlfe_list)
- {
- int cur_op, new_op;
-
- cur_op = (slsp->snhlfe_list->out_label == MPLS_IMP_NULL_LABEL);
- new_op = (out_label == MPLS_IMP_NULL_LABEL);
- if (cur_op != new_op)
- return 0;
- }
- }
-
- /* Label values are good. */
- return 1;
+int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf,
+ mpls_label_t in_label,
+ mpls_label_t out_label,
+ enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex)
+{
+ struct hash *slsp_table;
+ zebra_ile_t tmp_ile;
+ zebra_slsp_t *slsp;
+ zebra_snhlfe_t *snhlfe;
+
+ /* Lookup table. */
+ slsp_table = zvrf->slsp_table;
+ if (!slsp_table)
+ return 0;
+
+ /* If entry is not present, exit. */
+ tmp_ile.in_label = in_label;
+ slsp = hash_lookup(slsp_table, &tmp_ile);
+ if (!slsp)
+ return 1;
+
+ snhlfe = snhlfe_find(slsp, gtype, gate, ifindex);
+ if (snhlfe) {
+ if (snhlfe->out_label == out_label)
+ return 1;
+
+ /* If not only NHLFE, cannot allow label change. */
+ if (snhlfe != slsp->snhlfe_list || snhlfe->next)
+ return 0;
+ } else {
+ /* If other NHLFEs exist, label operation must match. */
+ if (slsp->snhlfe_list) {
+ int cur_op, new_op;
+
+ cur_op = (slsp->snhlfe_list->out_label
+ == MPLS_IMP_NULL_LABEL);
+ new_op = (out_label == MPLS_IMP_NULL_LABEL);
+ if (cur_op != new_op)
+ return 0;
+ }
+ }
+
+ /* Label values are good. */
+ return 1;
}
#endif /* HAVE_CUMULUS */
@@ -2635,64 +2476,61 @@ zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,
* Note: The label operation (swap or PHP) is common for the LSP entry (all
* NHLFEs).
*/
-int
-zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,
- mpls_label_t out_label, enum nexthop_types_t gtype,
- union g_addr *gate, ifindex_t ifindex)
-{
- struct hash *slsp_table;
- zebra_ile_t tmp_ile;
- zebra_slsp_t *slsp;
- zebra_snhlfe_t *snhlfe;
- char buf[BUFSIZ];
-
- /* Lookup table. */
- slsp_table = zvrf->slsp_table;
- if (!slsp_table)
- return -1;
-
- /* If entry is present, exit. */
- tmp_ile.in_label = in_label;
- slsp = hash_get (slsp_table, &tmp_ile, slsp_alloc);
- if (!slsp)
- return -1;
- snhlfe = snhlfe_find (slsp, gtype, gate, ifindex);
- if (snhlfe)
- {
- if (snhlfe->out_label == out_label)
- /* No change */
- return 0;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- {
- snhlfe2str (snhlfe, buf, BUFSIZ);
- zlog_debug ("Upd static LSP in-label %u nexthop %s "
- "out-label %u (old %u)",
- in_label, buf, out_label, snhlfe->out_label);
- }
- snhlfe->out_label = out_label;
- }
- else
- {
- /* Add static LSP entry to this nexthop */
- snhlfe = snhlfe_add (slsp, gtype, gate, ifindex, out_label);
- if (!snhlfe)
- return -1;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- {
- snhlfe2str (snhlfe, buf, BUFSIZ);
- zlog_debug ("Add static LSP in-label %u nexthop %s out-label %u",
- in_label, buf, out_label);
- }
- }
-
- /* (Re)Install LSP in the main table. */
- if (mpls_lsp_install (zvrf, ZEBRA_LSP_STATIC, in_label, out_label, gtype,
- gate, ifindex))
- return -1;
-
- return 0;
+int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label,
+ mpls_label_t out_label,
+ enum nexthop_types_t gtype, union g_addr *gate,
+ ifindex_t ifindex)
+{
+ struct hash *slsp_table;
+ zebra_ile_t tmp_ile;
+ zebra_slsp_t *slsp;
+ zebra_snhlfe_t *snhlfe;
+ char buf[BUFSIZ];
+
+ /* Lookup table. */
+ slsp_table = zvrf->slsp_table;
+ if (!slsp_table)
+ return -1;
+
+ /* If entry is present, exit. */
+ tmp_ile.in_label = in_label;
+ slsp = hash_get(slsp_table, &tmp_ile, slsp_alloc);
+ if (!slsp)
+ return -1;
+ snhlfe = snhlfe_find(slsp, gtype, gate, ifindex);
+ if (snhlfe) {
+ if (snhlfe->out_label == out_label)
+ /* No change */
+ return 0;
+
+ if (IS_ZEBRA_DEBUG_MPLS) {
+ snhlfe2str(snhlfe, buf, BUFSIZ);
+ zlog_debug(
+ "Upd static LSP in-label %u nexthop %s "
+ "out-label %u (old %u)",
+ in_label, buf, out_label, snhlfe->out_label);
+ }
+ snhlfe->out_label = out_label;
+ } else {
+ /* Add static LSP entry to this nexthop */
+ snhlfe = snhlfe_add(slsp, gtype, gate, ifindex, out_label);
+ if (!snhlfe)
+ return -1;
+
+ if (IS_ZEBRA_DEBUG_MPLS) {
+ snhlfe2str(snhlfe, buf, BUFSIZ);
+ zlog_debug(
+ "Add static LSP in-label %u nexthop %s out-label %u",
+ in_label, buf, out_label);
+ }
+ }
+
+ /* (Re)Install LSP in the main table. */
+ if (mpls_lsp_install(zvrf, ZEBRA_LSP_STATIC, in_label, out_label, gtype,
+ gate, ifindex))
+ return -1;
+
+ return 0;
}
/*
@@ -2702,71 +2540,66 @@ zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,
* NOTE: Delete of the only NHLFE will also end up deleting the entire
* LSP configuration.
*/
-int
-zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label,
- enum nexthop_types_t gtype, union g_addr *gate,
- ifindex_t ifindex)
-{
- struct hash *slsp_table;
- zebra_ile_t tmp_ile;
- zebra_slsp_t *slsp;
- zebra_snhlfe_t *snhlfe;
-
- /* Lookup table. */
- slsp_table = zvrf->slsp_table;
- if (!slsp_table)
- return -1;
-
- /* If entry is not present, exit. */
- tmp_ile.in_label = in_label;
- slsp = hash_lookup (slsp_table, &tmp_ile);
- if (!slsp)
- return 0;
-
- /* Is it delete of entire LSP or a specific NHLFE? */
- if (gtype == NEXTHOP_TYPE_BLACKHOLE)
- {
- if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug ("Del static LSP in-label %u", in_label);
-
- /* Uninstall entire LSP from the main table. */
- mpls_static_lsp_uninstall_all (zvrf, in_label);
-
- /* Delete all static NHLFEs */
- snhlfe_del_all (slsp);
- }
- else
- {
- /* Find specific NHLFE, exit if not found. */
- snhlfe = snhlfe_find (slsp, gtype, gate, ifindex);
- if (!snhlfe)
- return 0;
-
- if (IS_ZEBRA_DEBUG_MPLS)
- {
- char buf[BUFSIZ];
- snhlfe2str (snhlfe, buf, BUFSIZ);
- zlog_debug ("Del static LSP in-label %u nexthop %s",
- in_label, buf);
- }
-
- /* Uninstall LSP from the main table. */
- mpls_lsp_uninstall (zvrf, ZEBRA_LSP_STATIC, in_label, gtype, gate,
- ifindex);
-
- /* Delete static LSP NHLFE */
- snhlfe_del (snhlfe);
- }
-
- /* Remove entire static LSP entry if no NHLFE - valid in either case above. */
- if (!slsp->snhlfe_list)
- {
- slsp = hash_release(slsp_table, &tmp_ile);
- if (slsp)
- XFREE(MTYPE_SLSP, slsp);
- }
-
- return 0;
+int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
+ enum nexthop_types_t gtype, union g_addr *gate,
+ ifindex_t ifindex)
+{
+ struct hash *slsp_table;
+ zebra_ile_t tmp_ile;
+ zebra_slsp_t *slsp;
+ zebra_snhlfe_t *snhlfe;
+
+ /* Lookup table. */
+ slsp_table = zvrf->slsp_table;
+ if (!slsp_table)
+ return -1;
+
+ /* If entry is not present, exit. */
+ tmp_ile.in_label = in_label;
+ slsp = hash_lookup(slsp_table, &tmp_ile);
+ if (!slsp)
+ return 0;
+
+ /* Is it delete of entire LSP or a specific NHLFE? */
+ if (gtype == NEXTHOP_TYPE_BLACKHOLE) {
+ if (IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug("Del static LSP in-label %u", in_label);
+
+ /* Uninstall entire LSP from the main table. */
+ mpls_static_lsp_uninstall_all(zvrf, in_label);
+
+ /* Delete all static NHLFEs */
+ snhlfe_del_all(slsp);
+ } else {
+ /* Find specific NHLFE, exit if not found. */
+ snhlfe = snhlfe_find(slsp, gtype, gate, ifindex);
+ if (!snhlfe)
+ return 0;
+
+ if (IS_ZEBRA_DEBUG_MPLS) {
+ char buf[BUFSIZ];
+ snhlfe2str(snhlfe, buf, BUFSIZ);
+ zlog_debug("Del static LSP in-label %u nexthop %s",
+ in_label, buf);
+ }
+
+ /* Uninstall LSP from the main table. */
+ mpls_lsp_uninstall(zvrf, ZEBRA_LSP_STATIC, in_label, gtype,
+ gate, ifindex);
+
+ /* Delete static LSP NHLFE */
+ snhlfe_del(snhlfe);
+ }
+
+ /* Remove entire static LSP entry if no NHLFE - valid in either case
+ * above. */
+ if (!slsp->snhlfe_list) {
+ slsp = hash_release(slsp_table, &tmp_ile);
+ if (slsp)
+ XFREE(MTYPE_SLSP, slsp);
+ }
+
+ return 0;
}
/*
@@ -2774,200 +2607,192 @@ zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label,
* Called upon changes that may affect one or more of them such as
* interface or nexthop state changes.
*/
-void
-zebra_mpls_lsp_schedule (struct zebra_vrf *zvrf)
+void zebra_mpls_lsp_schedule(struct zebra_vrf *zvrf)
{
- if (!zvrf)
- return;
- hash_iterate(zvrf->lsp_table, lsp_schedule, NULL);
+ if (!zvrf)
+ return;
+ hash_iterate(zvrf->lsp_table, lsp_schedule, NULL);
}
/*
* Display MPLS label forwarding table for a specific LSP
* (VTY command handler).
*/
-void
-zebra_mpls_print_lsp (struct vty *vty, struct zebra_vrf *zvrf, mpls_label_t label,
- u_char use_json)
+void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf,
+ mpls_label_t label, u_char use_json)
{
- struct hash *lsp_table;
- zebra_lsp_t *lsp;
- zebra_ile_t tmp_ile;
- json_object *json = NULL;
+ struct hash *lsp_table;
+ zebra_lsp_t *lsp;
+ zebra_ile_t tmp_ile;
+ json_object *json = NULL;
- /* Lookup table. */
- lsp_table = zvrf->lsp_table;
- if (!lsp_table)
- return;
+ /* Lookup table. */
+ lsp_table = zvrf->lsp_table;
+ if (!lsp_table)
+ return;
- /* If entry is not present, exit. */
- tmp_ile.in_label = label;
- lsp = hash_lookup (lsp_table, &tmp_ile);
- if (!lsp)
- return;
+ /* If entry is not present, exit. */
+ tmp_ile.in_label = label;
+ lsp = hash_lookup(lsp_table, &tmp_ile);
+ if (!lsp)
+ return;
- if (use_json)
- {
- json = lsp_json(lsp);
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
- else
- lsp_print (lsp, (void *)vty);
+ if (use_json) {
+ json = lsp_json(lsp);
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else
+ lsp_print(lsp, (void *)vty);
}
/*
* Display MPLS label forwarding table (VTY command handler).
*/
-void
-zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf,
- u_char use_json)
-{
- char buf[BUFSIZ];
- json_object *json = NULL;
- zebra_lsp_t *lsp = NULL;
- zebra_nhlfe_t *nhlfe = NULL;
- struct nexthop *nexthop = NULL;
- struct listnode *node = NULL;
- struct list *lsp_list = hash_get_sorted_list(zvrf->lsp_table, lsp_cmp);
-
- if (use_json)
- {
- json = json_object_new_object();
-
- for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp))
- json_object_object_add(json, label2str(lsp->ile.in_label, buf, BUFSIZ),
- lsp_json(lsp));
-
- vty_out (vty, "%s\n",
- json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
- }
- else
- {
- vty_out (vty, " Inbound Outbound\n");
- vty_out (vty, " Label Type Nexthop Label\n");
- vty_out (vty, "-------- ------- --------------- --------\n");
-
- for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp))
- {
- for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next)
- {
- vty_out (vty, "%8d %7s ", lsp->ile.in_label, nhlfe_type2str(nhlfe->type));
- nexthop = nhlfe->nexthop;
-
- switch (nexthop->type)
- {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- vty_out (vty, "%15s", inet_ntoa (nexthop->gate.ipv4));
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- vty_out (vty, "%15s", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ));
- break;
- default:
- break;
- }
-
- vty_out (vty, " %8d\n", nexthop->nh_label->label[0]);
- }
- }
-
- vty_out (vty, "\n");
- }
-
- list_delete (lsp_list);
+void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
+ u_char use_json)
+{
+ char buf[BUFSIZ];
+ json_object *json = NULL;
+ zebra_lsp_t *lsp = NULL;
+ zebra_nhlfe_t *nhlfe = NULL;
+ struct nexthop *nexthop = NULL;
+ struct listnode *node = NULL;
+ struct list *lsp_list = hash_get_sorted_list(zvrf->lsp_table, lsp_cmp);
+
+ if (use_json) {
+ json = json_object_new_object();
+
+ for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp))
+ json_object_object_add(
+ json, label2str(lsp->ile.in_label, buf, BUFSIZ),
+ lsp_json(lsp));
+
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ } else {
+ vty_out(vty, " Inbound Outbound\n");
+ vty_out(vty, " Label Type Nexthop Label\n");
+ vty_out(vty, "-------- ------- --------------- --------\n");
+
+ for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) {
+ for (nhlfe = lsp->nhlfe_list; nhlfe;
+ nhlfe = nhlfe->next) {
+ vty_out(vty, "%8d %7s ", lsp->ile.in_label,
+ nhlfe_type2str(nhlfe->type));
+ nexthop = nhlfe->nexthop;
+
+ switch (nexthop->type) {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ vty_out(vty, "%15s",
+ inet_ntoa(nexthop->gate.ipv4));
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ vty_out(vty, "%15s",
+ inet_ntop(AF_INET6,
+ &nexthop->gate.ipv6,
+ buf, BUFSIZ));
+ break;
+ default:
+ break;
+ }
+
+ vty_out(vty, " %8d\n",
+ nexthop->nh_label->label[0]);
+ }
+ }
+
+ vty_out(vty, "\n");
+ }
+
+ list_delete(lsp_list);
}
/*
* Display MPLS LSP configuration of all static LSPs (VTY command handler).
*/
-int
-zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf)
-{
- zebra_slsp_t *slsp;
- zebra_snhlfe_t *snhlfe;
- struct listnode *node;
- struct list *slsp_list = hash_get_sorted_list(zvrf->slsp_table, slsp_cmp);
-
- for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp))
- {
- for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe->next)
- {
- char buf[INET6_ADDRSTRLEN];
- char lstr[30];
-
- snhlfe2str (snhlfe, buf, BUFSIZ);
- switch (snhlfe->out_label) {
- case MPLS_V4_EXP_NULL_LABEL:
- case MPLS_V6_EXP_NULL_LABEL:
- strlcpy(lstr, "explicit-null", sizeof(lstr));
- break;
- case MPLS_IMP_NULL_LABEL:
- strlcpy(lstr, "implicit-null", sizeof(lstr));
- break;
- default:
- sprintf(lstr, "%u", snhlfe->out_label);
- break;
- }
-
- vty_out (vty, "mpls lsp %u %s %s\n",
- slsp->ile.in_label, buf, lstr);
- }
- }
+int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)
+{
+ zebra_slsp_t *slsp;
+ zebra_snhlfe_t *snhlfe;
+ struct listnode *node;
+ struct list *slsp_list =
+ hash_get_sorted_list(zvrf->slsp_table, slsp_cmp);
+
+ for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp)) {
+ for (snhlfe = slsp->snhlfe_list; snhlfe;
+ snhlfe = snhlfe->next) {
+ char buf[INET6_ADDRSTRLEN];
+ char lstr[30];
+
+ snhlfe2str(snhlfe, buf, BUFSIZ);
+ switch (snhlfe->out_label) {
+ case MPLS_V4_EXP_NULL_LABEL:
+ case MPLS_V6_EXP_NULL_LABEL:
+ strlcpy(lstr, "explicit-null", sizeof(lstr));
+ break;
+ case MPLS_IMP_NULL_LABEL:
+ strlcpy(lstr, "implicit-null", sizeof(lstr));
+ break;
+ default:
+ sprintf(lstr, "%u", snhlfe->out_label);
+ break;
+ }
+
+ vty_out(vty, "mpls lsp %u %s %s\n", slsp->ile.in_label,
+ buf, lstr);
+ }
+ }
- list_delete (slsp_list);
- return (zvrf->slsp_table->count ? 1 : 0);
+ list_delete(slsp_list);
+ return (zvrf->slsp_table->count ? 1 : 0);
}
/*
* Add/update global label block.
*/
-int
-zebra_mpls_label_block_add (struct zebra_vrf *zvrf, u_int32_t start_label,
- u_int32_t end_label)
+int zebra_mpls_label_block_add(struct zebra_vrf *zvrf, u_int32_t start_label,
+ u_int32_t end_label)
{
- zvrf->mpls_srgb.start_label = start_label;
- zvrf->mpls_srgb.end_label = end_label;
+ zvrf->mpls_srgb.start_label = start_label;
+ zvrf->mpls_srgb.end_label = end_label;
- /* Evaluate registered FECs to see if any get a label or not. */
- fec_evaluate (zvrf);
- return 0;
+ /* Evaluate registered FECs to see if any get a label or not. */
+ fec_evaluate(zvrf);
+ return 0;
}
/*
* Delete global label block.
*/
-int
-zebra_mpls_label_block_del (struct zebra_vrf *zvrf)
+int zebra_mpls_label_block_del(struct zebra_vrf *zvrf)
{
- zvrf->mpls_srgb.start_label = MPLS_DEFAULT_MIN_SRGB_LABEL;
- zvrf->mpls_srgb.end_label = MPLS_DEFAULT_MAX_SRGB_LABEL;
+ zvrf->mpls_srgb.start_label = MPLS_DEFAULT_MIN_SRGB_LABEL;
+ zvrf->mpls_srgb.end_label = MPLS_DEFAULT_MAX_SRGB_LABEL;
- /* Process registered FECs to clear their local label, if needed. */
- fec_evaluate (zvrf);
- return 0;
+ /* Process registered FECs to clear their local label, if needed. */
+ fec_evaluate(zvrf);
+ return 0;
}
/*
* Display MPLS global label block configuration (VTY command handler).
*/
-int
-zebra_mpls_write_label_block_config (struct vty *vty, struct zebra_vrf *zvrf)
+int zebra_mpls_write_label_block_config(struct vty *vty, struct zebra_vrf *zvrf)
{
- if (zvrf->mpls_srgb.start_label == 0)
- return 0;
+ if (zvrf->mpls_srgb.start_label == 0)
+ return 0;
- if ((zvrf->mpls_srgb.start_label != MPLS_DEFAULT_MIN_SRGB_LABEL) ||
- (zvrf->mpls_srgb.end_label != MPLS_DEFAULT_MAX_SRGB_LABEL))
- {
- vty_out (vty, "mpls label global-block %u %u\n",
- zvrf->mpls_srgb.start_label,zvrf->mpls_srgb.end_label);
- }
+ if ((zvrf->mpls_srgb.start_label != MPLS_DEFAULT_MIN_SRGB_LABEL)
+ || (zvrf->mpls_srgb.end_label != MPLS_DEFAULT_MAX_SRGB_LABEL)) {
+ vty_out(vty, "mpls label global-block %u %u\n",
+ zvrf->mpls_srgb.start_label, zvrf->mpls_srgb.end_label);
+ }
- return 1;
+ return 1;
}
/*
@@ -2975,48 +2800,44 @@ zebra_mpls_write_label_block_config (struct vty *vty, struct zebra_vrf *zvrf)
* entries from the kernel.
* NOTE: Currently supported only for default VRF.
*/
-void
-zebra_mpls_close_tables (struct zebra_vrf *zvrf)
+void zebra_mpls_close_tables(struct zebra_vrf *zvrf)
{
- hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL);
- hash_clean(zvrf->lsp_table, NULL);
- hash_free(zvrf->lsp_table);
- hash_clean(zvrf->slsp_table, NULL);
- hash_free(zvrf->slsp_table);
+ hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL);
+ hash_clean(zvrf->lsp_table, NULL);
+ hash_free(zvrf->lsp_table);
+ hash_clean(zvrf->slsp_table, NULL);
+ hash_free(zvrf->slsp_table);
}
/*
* Allocate MPLS tables for this VRF and do other initialization.
* NOTE: Currently supported only for default VRF.
*/
-void
-zebra_mpls_init_tables (struct zebra_vrf *zvrf)
+void zebra_mpls_init_tables(struct zebra_vrf *zvrf)
{
- if (!zvrf)
- return;
- zvrf->slsp_table = hash_create(label_hash, label_cmp, NULL);
- zvrf->lsp_table = hash_create(label_hash, label_cmp, NULL);
- zvrf->fec_table[AFI_IP] = route_table_init();
- zvrf->fec_table[AFI_IP6] = route_table_init();
- zvrf->mpls_flags = 0;
- zvrf->mpls_srgb.start_label = MPLS_DEFAULT_MIN_SRGB_LABEL;
- zvrf->mpls_srgb.end_label = MPLS_DEFAULT_MAX_SRGB_LABEL;
+ if (!zvrf)
+ return;
+ zvrf->slsp_table = hash_create(label_hash, label_cmp, NULL);
+ zvrf->lsp_table = hash_create(label_hash, label_cmp, NULL);
+ zvrf->fec_table[AFI_IP] = route_table_init();
+ zvrf->fec_table[AFI_IP6] = route_table_init();
+ zvrf->mpls_flags = 0;
+ zvrf->mpls_srgb.start_label = MPLS_DEFAULT_MIN_SRGB_LABEL;
+ zvrf->mpls_srgb.end_label = MPLS_DEFAULT_MAX_SRGB_LABEL;
}
/*
* Global MPLS initialization.
*/
-void
-zebra_mpls_init (void)
+void zebra_mpls_init(void)
{
- mpls_enabled = 0;
+ mpls_enabled = 0;
- if (mpls_kernel_init () < 0)
- {
- zlog_warn ("Disabling MPLS support (no kernel support)");
- return;
- }
+ if (mpls_kernel_init() < 0) {
+ zlog_warn("Disabling MPLS support (no kernel support)");
+ return;
+ }
- if (! mpls_processq_init (&zebrad))
- mpls_enabled = 1;
+ if (!mpls_processq_init(&zebrad))
+ mpls_enabled = 1;
}