DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID_FUNC, "SRv6 SID function");
DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_USID_WLIB,
"SRv6 uSID Wide LIB information");
+DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID, "SRv6 SID");
+DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID_CTX, "SRv6 SID context");
/* define hooks for the basic API, so that it can be specialized or served
* externally
return 0;
}
+/* --- Zebra SRv6 SID context management functions -------------------------- */
+
+struct zebra_srv6_sid_ctx *zebra_srv6_sid_ctx_alloc(void)
+{
+ struct zebra_srv6_sid_ctx *ctx = NULL;
+
+ ctx = XCALLOC(MTYPE_ZEBRA_SRV6_SID_CTX,
+ sizeof(struct zebra_srv6_sid_ctx));
+
+ return ctx;
+}
+
+void zebra_srv6_sid_ctx_free(struct zebra_srv6_sid_ctx *ctx)
+{
+ XFREE(MTYPE_ZEBRA_SRV6_SID_CTX, ctx);
+}
+
+/**
+ * Free an SRv6 SID context.
+ *
+ * @param val SRv6 SID context to be freed
+ */
+void delete_zebra_srv6_sid_ctx(void *val)
+{
+ zebra_srv6_sid_ctx_free((struct zebra_srv6_sid_ctx *)val);
+}
+
/* --- Zebra SRv6 SID format management functions --------------------------- */
void srv6_sid_format_register(struct srv6_sid_format *format)
return NULL;
}
+/* --- Zebra SRv6 SID management functions ---------------------------------- */
+
+/**
+ * Alloc and fill an SRv6 SID.
+ *
+ * @param ctx Context associated with the SID to be created
+ * @param sid_value IPv6 address associated with the SID to be created
+ * @param locator Parent locator of the SID to be created
+ * @param sid_block Block from which the SID value has been allocated
+ * @param sid_func Function part of the SID to be created
+ * @param alloc_mode Allocation mode of the Function (dynamic vs explicit)
+ * @return The requested SID
+ */
+struct zebra_srv6_sid *
+zebra_srv6_sid_alloc(struct zebra_srv6_sid_ctx *ctx, struct in6_addr *sid_value,
+ struct srv6_locator *locator,
+ struct zebra_srv6_sid_block *sid_block, uint32_t sid_func,
+ enum srv6_sid_alloc_mode alloc_mode)
+{
+ struct zebra_srv6_sid *sid;
+
+ if (!ctx || !sid_value)
+ return NULL;
+
+ sid = XCALLOC(MTYPE_ZEBRA_SRV6_SID, sizeof(struct zebra_srv6_sid));
+ sid->ctx = ctx;
+ sid->value = *sid_value;
+ sid->locator = locator;
+ sid->block = sid_block;
+ sid->func = sid_func;
+ sid->alloc_mode = alloc_mode;
+ sid->client_list = list_new();
+
+ return sid;
+}
+
+void zebra_srv6_sid_free(struct zebra_srv6_sid *sid)
+{
+ list_delete(&sid->client_list);
+ XFREE(MTYPE_ZEBRA_SRV6_SID, sid);
+}
+
+/**
+ * Free an SRv6 SID.
+ *
+ * @param val SRv6 SID to be freed
+ */
+void delete_zebra_srv6_sid(void *val)
+{
+ zebra_srv6_sid_free((struct zebra_srv6_sid *)val);
+}
+
void zebra_srv6_locator_add(struct srv6_locator *locator)
{
struct zebra_srv6 *srv6 = zebra_srv6_get_default();
format_uncompressed = create_srv6_sid_format_uncompressed();
srv6_sid_format_register(format_uncompressed);
+ /* Init list to store SRv6 SIDs */
+ srv6.sids = list_new();
+ srv6.sids->del = delete_zebra_srv6_sid_ctx;
+
/* Init list to store SRv6 SID blocks */
srv6.sid_blocks = list_new();
srv6.sid_blocks->del = delete_zebra_srv6_sid_block;
struct srv6_locator *locator;
struct srv6_sid_format *format;
struct zebra_srv6_sid_block *block;
+ struct zebra_srv6_sid_ctx *sid_ctx;
if (srv6.locators) {
while (listcount(srv6.locators)) {
list_delete(&srv6.locators);
}
+ /* Free SRv6 SIDs */
+ if (srv6.sids) {
+ while (listcount(srv6.sids)) {
+ sid_ctx = listnode_head(srv6.sids);
+
+ listnode_delete(srv6.sids, sid_ctx);
+ zebra_srv6_sid_ctx_free(sid_ctx);
+ }
+
+ list_delete(&srv6.sids);
+ }
+
/* Free SRv6 SID blocks */
if (srv6.sid_blocks) {
while (listcount(srv6.sid_blocks)) {
} u;
};
+/**
+ * The function part of an SRv6 SID can be allocated in one
+ * of the following ways:
+ * - dynamic: allocate any available function
+ * - explicit: allocate a specific function
+ */
+enum srv6_sid_alloc_mode {
+ SRV6_SID_ALLOC_MODE_UNSPEC = 0,
+ /* Dynamic SID allocation */
+ SRV6_SID_ALLOC_MODE_DYNAMIC = 1,
+ /* Explicit SID allocation */
+ SRV6_SID_ALLOC_MODE_EXPLICIT = 2,
+ SRV6_SID_ALLOC_MODE_MAX = 3,
+};
+
+/**
+ * Convert SID allocation mode to string.
+ *
+ * @param alloc_mode SID allocation mode
+ * @return String representing the allocation mode
+ */
+static inline const char *
+srv6_sid_alloc_mode2str(enum srv6_sid_alloc_mode alloc_mode)
+{
+ switch (alloc_mode) {
+ case SRV6_SID_ALLOC_MODE_EXPLICIT:
+ return "explicit";
+ case SRV6_SID_ALLOC_MODE_DYNAMIC:
+ return "dynamic";
+ case SRV6_SID_ALLOC_MODE_UNSPEC:
+ return "unspec";
+ case SRV6_SID_ALLOC_MODE_MAX:
+ default:
+ return "unknown";
+ }
+}
+
+/* SRv6 SID instance. */
+struct zebra_srv6_sid {
+ /*
+ * SID context associated with the SID.
+ * Defines behavior and attributes of the SID.
+ */
+ struct zebra_srv6_sid_ctx *ctx;
+
+ /* SID value (e.g. fc00:0:1:e000::) */
+ struct in6_addr value;
+
+ /* Pointer to the SRv6 locator from which the SID has been allocated */
+ struct srv6_locator *locator;
+
+ /* Pointer to the SRv6 block from which the SID has been allocated */
+ struct zebra_srv6_sid_block *block;
+
+ /*
+ * Function part of the SID
+ * Example:
+ * SID = fc00:0:1:e000:: => func = e000
+ */
+ uint32_t func;
+
+ /* SID wide function. */
+ uint32_t wide_func;
+
+ /* SID allocation mode: dynamic or explicit */
+ enum srv6_sid_alloc_mode alloc_mode;
+
+ /* List of clients that are using the SID */
+ struct list *client_list;
+};
+
+/*
+ * Zebra SRv6 SID context.
+ * A context defines a behavior and (optionally) some behavior-specific
+ * attributes. Client daemons (bgp, isis, ...) ask SRv6 Manager to allocate
+ * a SID for a particular context. SRv6 Manager is responsible for allocating
+ * a SID from a given SID block and associating with the context.
+ *
+ * Example:
+ * bgp asks to associate a SID to the context {behavior=End.DT46 vrf=Vrf10}.
+ * SRv6 Manager allocate SID fc00:0:1:e000:: for that context.
+ */
+struct zebra_srv6_sid_ctx {
+ /* SRv6 SID context information. */
+ struct srv6_sid_ctx ctx;
+
+ /* SID associated with the context. */
+ struct zebra_srv6_sid *sid;
+};
+
/* SRv6 instance structure. */
struct zebra_srv6 {
struct list *locators;
/* SRv6 SID formats */
struct list *sid_formats;
+ /* SRv6 SIDs */
+ struct list *sids;
+
/* SRv6 SID blocks */
struct list *sid_blocks;
};
extern struct zebra_srv6_sid_block *
zebra_srv6_sid_block_lookup(struct prefix_ipv6 *prefix);
+extern struct zebra_srv6_sid *
+zebra_srv6_sid_alloc(struct zebra_srv6_sid_ctx *ctx, struct in6_addr *sid_value,
+ struct srv6_locator *locator,
+ struct zebra_srv6_sid_block *sid_block, uint32_t sid_func,
+ enum srv6_sid_alloc_mode alloc_mode);
+extern void zebra_srv6_sid_free(struct zebra_srv6_sid *sid);
+extern void delete_zebra_srv6_sid(void *val);
+
+extern struct zebra_srv6_sid_ctx *zebra_srv6_sid_ctx_alloc(void);
+extern void zebra_srv6_sid_ctx_free(struct zebra_srv6_sid_ctx *ctx);
+extern void delete_zebra_srv6_sid_ctx(void *val);
+
#endif /* _ZEBRA_SRV6_H */