#include "zebra/zserv.h"
#include "zebra/zebra_vrf.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
/* Definitions and macros. */
? AF_INET6 \
: AF_INET)
-#define MPLS_LABEL_HELPSTR \
- "Specify label(s) for this route\nOne or more " \
- "labels in the range (16-1048575) separated by '/'\n"
-
/* Typedefs */
typedef struct zebra_ile_t_ zebra_ile_t;
zebra_lsp_t *lsp;
/* Runtime info - flags, pointers etc. */
- u_int32_t flags;
+ uint32_t flags;
#define NHLFE_FLAG_CHANGED (1 << 0)
#define NHLFE_FLAG_SELECTED (1 << 1)
#define NHLFE_FLAG_MULTIPATH (1 << 2)
zebra_nhlfe_t *next;
zebra_nhlfe_t *prev;
- u_char distance;
+ uint8_t distance;
};
/*
/* List of NHLFE, pointer to best and num equal-cost. */
zebra_nhlfe_t *nhlfe_list;
zebra_nhlfe_t *best_nhlfe;
- u_int32_t num_ecmp;
+ uint32_t num_ecmp;
/* Flags */
- u_int32_t flags;
+ uint32_t flags;
#define LSP_FLAG_SCHEDULED (1 << 0)
#define LSP_FLAG_INSTALLED (1 << 1)
#define LSP_FLAG_CHANGED (1 << 2)
/* Address-family of NHLFE - saved here for delete. All NHLFEs */
/* have to be of the same AF */
- u_char addr_family;
+ uint8_t addr_family;
};
/*
mpls_label_t label;
/* Label index (into global label block), if valid */
- u_int32_t label_index;
+ uint32_t label_index;
/* Flags. */
- u_int32_t flags;
+ uint32_t flags;
#define FEC_FLAG_CONFIGURED (1 << 0)
/* Clients interested in this FEC. */
/* Function declarations. */
-/*
- * String to label conversion, labels separated by '/'.
- */
-int mpls_str2label(const char *label_str, u_int8_t *num_labels,
- mpls_label_t *labels);
-
-/*
- * 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);
-
/*
* 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, uint32_t start_label,
+ uint32_t end_label);
/*
* Delete global label block.
int zebra_mpls_lsp_uninstall(struct zebra_vrf *zvrf, struct route_node *rn,
struct route_entry *re);
-/*
- * Registration from a client for the label binding for a FEC. If a binding
- * already exists, it is informed to the client.
- * NOTE: If there is a manually configured label binding, that is used.
- * Otherwise, if aa label index is specified, it means we have to allocate the
- * label from a locally configured label block (SRGB), if one exists and index
- * is acceptable.
- */
+/* Add an NHLFE to an LSP, return the newly-added object */
+zebra_nhlfe_t *zebra_mpls_lsp_add_nhlfe(zebra_lsp_t *lsp,
+ enum lsp_types_t lsp_type,
+ enum nexthop_types_t gtype,
+ union g_addr *gate,
+ ifindex_t ifindex,
+ uint8_t num_labels,
+ mpls_label_t out_labels[]);
+
+/* Free an allocated NHLFE */
+void zebra_mpls_nhlfe_del(zebra_nhlfe_t *nhlfe);
+
int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
- u_int32_t label_index, struct zserv *client);
+ uint32_t label, uint32_t label_index,
+ struct zserv *client);
/*
* Deregistration from a client for the label binding for a FEC. The FEC
int zebra_mpls_fec_unregister(struct zebra_vrf *zvrf, struct prefix *p,
struct zserv *client);
-/*
- * Cleanup any FECs registered by this client.
- */
-int zebra_mpls_cleanup_fecs_for_client(struct zebra_vrf *zvrf,
- struct zserv *client);
-
/*
* Return FEC (if any) to which this label is bound.
* Note: Only works for per-prefix binding and when the label is not
*/
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);
+ union g_addr *gate, ifindex_t ifindex, uint8_t route_type,
+ unsigned short route_instance, mpls_label_t out_label);
+
+/*
+ * Uninstall all NHLFEs bound to a single FEC.
+ */
+int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
+ struct prefix *prefix, uint8_t route_type,
+ unsigned short route_instance);
/*
* Install/update a NHLFE for an LSP in the forwarding table. This may be
* 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).
+ * the out-label(s) 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);
+ mpls_label_t in_label, uint8_t num_out_labels,
+ mpls_label_t out_labels[], enum nexthop_types_t gtype,
+ union g_addr *gate, ifindex_t ifindex);
/*
* Uninstall a particular NHLFE in the forwarding table. If this is
union g_addr *gate, ifindex_t ifindex);
/*
- * 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);
-
-/*
- * Uninstall all LDP FEC-To-NHLFE (FTN) bindings of the given address-family.
+ * Uninstall all NHLFEs for a particular LSP forwarding entry.
*/
-void mpls_ldp_ftn_uninstall_all(struct zebra_vrf *zvrf, int afi);
+int mpls_lsp_uninstall_all_vrf(struct zebra_vrf *zvrf, enum lsp_types_t type,
+ mpls_label_t in_label);
/*
* Uninstall all Segment Routing NHLFEs for a particular LSP forwarding entry.
* If no other NHLFEs exist, the entry would be deleted.
*/
-void mpls_sr_lsp_uninstall_all(struct hash_backet *backet, void *ctxt);
+void mpls_sr_lsp_uninstall_all(struct hash_bucket *bucket, void *ctxt);
#if defined(HAVE_CUMULUS)
/*
enum nexthop_types_t gtype, union g_addr *gate,
ifindex_t ifindex);
+/*
+ * Process LSP update results from zebra dataplane.
+ */
+/* Forward ref of dplane update context type */
+struct zebra_dplane_ctx;
+
+void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *ctx);
+
+/* Process async dplane notifications. */
+void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx);
+
/*
* Schedule all MPLS label forwarding entries for processing.
* Called upon changes that may affect one or more of them such as
* (VTY command handler).
*/
void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf,
- mpls_label_t label, u_char use_json);
+ mpls_label_t label, bool use_json);
/*
* 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);
+ bool use_json);
/*
* Display MPLS LSP configuration of all static LSPs (VTY command handler).
*/
int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf);
+/*
+ * Called when VRF becomes inactive, cleans up information but keeps
+ * the table itself.
+ * NOTE: Currently supported only for default VRF.
+ */
+void zebra_mpls_cleanup_tables(struct zebra_vrf *zvrf);
+
/*
* Called upon process exiting, need to delete LSP forwarding
* entries from the kernel.
/*
* Distance (priority) definition for LSP NHLFE.
*/
-static inline u_char lsp_distance(enum lsp_types_t type)
+static inline uint8_t lsp_distance(enum lsp_types_t type)
{
switch (type) {
case ZEBRA_LSP_STATIC:
return (route_distance(ZEBRA_ROUTE_LDP));
case ZEBRA_LSP_BGP:
return (route_distance(ZEBRA_ROUTE_BGP));
- default:
+ case ZEBRA_LSP_NONE:
+ case ZEBRA_LSP_SHARP:
+ case ZEBRA_LSP_OSPF_SR:
return 150;
}
+
+ /*
+ * For some reason certain compilers do not believe
+ * that all the cases have been handled. And
+ * WTF does this work differently than when I removed
+ * the default case????
+ */
+ return 150;
}
/*
switch (re_type) {
case ZEBRA_ROUTE_STATIC:
return ZEBRA_LSP_STATIC;
+ case ZEBRA_ROUTE_LDP:
+ return ZEBRA_LSP_LDP;
case ZEBRA_ROUTE_BGP:
return ZEBRA_LSP_BGP;
+ case ZEBRA_ROUTE_OSPF:
+ return ZEBRA_LSP_OSPF_SR;
+ case ZEBRA_ROUTE_SHARP:
+ return ZEBRA_LSP_SHARP;
default:
return ZEBRA_LSP_NONE;
}
return ZEBRA_ROUTE_LDP;
case ZEBRA_LSP_BGP:
return ZEBRA_ROUTE_BGP;
- case ZEBRA_LSP_SR:
+ case ZEBRA_LSP_OSPF_SR:
return ZEBRA_ROUTE_OSPF;
case ZEBRA_LSP_NONE:
- default:
return ZEBRA_ROUTE_KERNEL;
+ case ZEBRA_LSP_SHARP:
+ return ZEBRA_ROUTE_SHARP;
}
+
+ /*
+ * For some reason certain compilers do not believe
+ * that all the cases have been handled. And
+ * WTF does this work differently than when I removed
+ * the default case????
+ */
+ return ZEBRA_ROUTE_KERNEL;
}
/* NHLFE type as printable string. */
return "LDP";
case ZEBRA_LSP_BGP:
return "BGP";
- case ZEBRA_LSP_SR:
- return "SR";
- default:
+ case ZEBRA_LSP_OSPF_SR:
+ return "SR (OSPF)";
+ case ZEBRA_LSP_SHARP:
+ return "SHARP";
+ case ZEBRA_LSP_NONE:
return "Unknown";
}
+
+ /*
+ * For some reason certain compilers do not believe
+ * that all the cases have been handled. And
+ * WTF does this work differently than when I removed
+ * the default case????
+ */
+ return "Unknown";
}
-static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf)
+static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf,
+ struct prefix *p)
{
+ struct route_table *table;
+ struct route_node *rn;
+ rib_dest_t *dest;
+
if (!zvrf)
return;
- zvrf->mpls_flags |= MPLS_FLAG_SCHEDULE_LSPS;
+ table = zvrf->table[family2afi(p->family)][SAFI_UNICAST];
+ if (!table)
+ return;
+
+ rn = route_node_match(table, p);
+ if (!rn)
+ return;
+
+
+ dest = rib_dest_from_rnode(rn);
+ SET_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS);
}
-static inline void mpls_unmark_lsps_for_processing(struct zebra_vrf *zvrf)
+static inline void mpls_unmark_lsps_for_processing(struct route_node *rn)
{
- if (!zvrf)
- return;
+ rib_dest_t *dest = rib_dest_from_rnode(rn);
- zvrf->mpls_flags &= ~MPLS_FLAG_SCHEDULE_LSPS;
+ UNSET_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS);
}
-static inline int mpls_should_lsps_be_processed(struct zebra_vrf *zvrf)
+static inline int mpls_should_lsps_be_processed(struct route_node *rn)
{
- if (!zvrf)
- return 0;
+ rib_dest_t *dest = rib_dest_from_rnode(rn);
- return ((zvrf->mpls_flags & MPLS_FLAG_SCHEDULE_LSPS) ? 1 : 0);
+ return !!CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_LSPS);
}
/* Global variables. */
extern int mpls_enabled;
+#ifdef __cplusplus
+}
+#endif
+
#endif /*_ZEBRA_MPLS_H */