summaryrefslogtreecommitdiffstats
path: root/isisd/isis_srv6.h
diff options
context:
space:
mode:
Diffstat (limited to 'isisd/isis_srv6.h')
-rw-r--r--isisd/isis_srv6.h181
1 files changed, 181 insertions, 0 deletions
diff --git a/isisd/isis_srv6.h b/isisd/isis_srv6.h
new file mode 100644
index 0000000..3386436
--- /dev/null
+++ b/isisd/isis_srv6.h
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * This is an implementation of Segment Routing over IPv6 (SRv6) for IS-IS
+ * as per RFC 9352
+ * https://datatracker.ietf.org/doc/html/rfc9352
+ *
+ * Copyright (C) 2023 Carmine Scarpitta - University of Rome Tor Vergata
+ */
+
+#ifndef _FRR_ISIS_SRV6_H
+#define _FRR_ISIS_SRV6_H
+
+#include "lib/srv6.h"
+#include "isisd/isis_tlvs.h"
+
+#define ISIS_DEFAULT_SRV6_MAX_SEG_LEFT_MSD 3
+#define ISIS_DEFAULT_SRV6_MAX_END_POP_MSD 3
+#define ISIS_DEFAULT_SRV6_MAX_H_ENCAPS_MSD 2
+#define ISIS_DEFAULT_SRV6_MAX_END_D_MSD 5
+#define ISIS_DEFAULT_SRV6_IFNAME "sr0"
+
+/* SRv6 SID structure */
+struct isis_srv6_sid_structure {
+ uint8_t loc_block_len;
+ uint8_t loc_node_len;
+ uint8_t func_len;
+ uint8_t arg_len;
+};
+
+/* SRv6 SID not bound to any adjacency */
+struct isis_srv6_sid {
+ struct isis_srv6_sid *next;
+
+ /* SID flags */
+ uint8_t flags;
+
+ /* SID value */
+ struct in6_addr sid;
+
+ /* Endpoint behavior bound to the SID */
+ enum srv6_endpoint_behavior_codepoint behavior;
+
+ /* SRv6 SID structure */
+ struct isis_srv6_sid_structure structure;
+
+ /* Parent SRv6 locator */
+ struct srv6_locator_chunk *locator;
+
+ /* Backpointer to IS-IS area */
+ struct isis_area *area;
+};
+
+/* SRv6 Locator */
+struct isis_srv6_locator {
+ struct isis_srv6_locator *next;
+
+ uint32_t metric;
+
+ uint8_t flags;
+#define ISIS_SRV6_LOCATOR_FLAG_D 1 << 7
+
+ uint8_t algorithm;
+ struct prefix_ipv6 prefix;
+
+ struct list *srv6_sid;
+};
+
+/* SRv6 Adjacency-SID type */
+enum srv6_adj_type {
+ ISIS_SRV6_ADJ_NORMAL = 0,
+ ISIS_SRV6_LAN_BACKUP,
+};
+
+/* SRv6 Adjacency. */
+struct srv6_adjacency {
+ /* Adjacency type */
+ enum srv6_adj_type type;
+
+ /* SID flags */
+ uint8_t flags;
+
+ /* SID value */
+ struct in6_addr sid;
+
+ /* Endpoint behavior bound to the SID */
+ enum srv6_endpoint_behavior_codepoint behavior;
+
+ /* SRv6 SID structure */
+ struct isis_srv6_sid_structure structure;
+
+ /* Parent SRv6 locator */
+ struct srv6_locator_chunk *locator;
+
+ /* Adjacency-SID nexthop information */
+ struct in6_addr nexthop;
+
+ /* End.X SID TI-LFA backup nexthops */
+ struct list *backup_nexthops;
+
+ /* SRv6 (LAN) End.X SID Sub-TLV */
+ union {
+ struct isis_srv6_endx_sid_subtlv *endx_sid;
+ struct isis_srv6_lan_endx_sid_subtlv *lendx_sid;
+ } u;
+
+ /* Back pointer to IS-IS adjacency. */
+ struct isis_adjacency *adj;
+};
+
+/* Per-area IS-IS SRv6 Data Base (SRv6 DB) */
+struct isis_srv6_db {
+
+ /* List of SRv6 Locator chunks */
+ struct list *srv6_locator_chunks;
+
+ /* List of SRv6 SIDs allocated by the IS-IS instance */
+ struct list *srv6_sids;
+
+ /* List of SRv6 End.X SIDs allocated by the IS-IS instance */
+ struct list *srv6_endx_sids;
+
+ /* Area SRv6 configuration. */
+ struct {
+ /* Administrative status of SRv6 */
+ bool enabled;
+
+ /* Name of the SRv6 Locator */
+ char srv6_locator_name[SRV6_LOCNAME_SIZE];
+
+ /* Maximum Segments Left Depth supported by the router */
+ uint8_t max_seg_left_msd;
+
+ /* Maximum Maximum End Pop Depth supported by the router */
+ uint8_t max_end_pop_msd;
+
+ /* Maximum H.Encaps supported by the router */
+ uint8_t max_h_encaps_msd;
+
+ /* Maximum End D MSD supported by the router */
+ uint8_t max_end_d_msd;
+
+ /* Interface used for installing SRv6 SIDs into the data plane */
+ char srv6_ifname[IF_NAMESIZE];
+ } config;
+};
+
+bool isis_srv6_locator_unset(struct isis_area *area);
+
+void isis_srv6_interface_set(struct isis_area *area, const char *ifname);
+
+struct isis_srv6_sid *
+isis_srv6_sid_alloc(struct isis_area *area, struct srv6_locator_chunk *chunk,
+ enum srv6_endpoint_behavior_codepoint behavior,
+ int sid_func);
+extern void isis_srv6_sid_free(struct isis_srv6_sid *sid);
+
+extern void isis_srv6_area_init(struct isis_area *area);
+extern void isis_srv6_area_term(struct isis_area *area);
+
+void isis_srv6_init(void);
+void isis_srv6_term(void);
+
+void isis_srv6_sid_structure2subsubtlv(
+ const struct isis_srv6_sid *sid,
+ struct isis_srv6_sid_structure_subsubtlv *structure_subsubtlv);
+void isis_srv6_end_sid2subtlv(const struct isis_srv6_sid *sid,
+ struct isis_srv6_end_sid_subtlv *sid_subtlv);
+void isis_srv6_locator2tlv(const struct isis_srv6_locator *loc,
+ struct isis_srv6_locator_tlv *loc_tlv);
+
+void srv6_endx_sid_add_single(struct isis_adjacency *adj, bool backup,
+ struct list *nexthops);
+void srv6_endx_sid_add(struct isis_adjacency *adj);
+void srv6_endx_sid_del(struct srv6_adjacency *sra);
+struct srv6_adjacency *isis_srv6_endx_sid_find(struct isis_adjacency *adj,
+ enum srv6_adj_type type);
+void isis_area_delete_backup_srv6_endx_sids(struct isis_area *area, int level);
+
+int isis_srv6_ifp_up_notify(struct interface *ifp);
+
+#endif /* _FRR_ISIS_SRV6_H */