diff options
Diffstat (limited to 'isisd/isis_sr.h')
-rw-r--r-- | isisd/isis_sr.h | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/isisd/isis_sr.h b/isisd/isis_sr.h new file mode 100644 index 0000000..a933f36 --- /dev/null +++ b/isisd/isis_sr.h @@ -0,0 +1,237 @@ +/* + * This is an implementation of Segment Routing for IS-IS as per RFC 8667 + * + * Copyright (C) 2019 Orange http://www.orange.com + * + * Author: Olivier Dugeon <olivier.dugeon@orange.com> + * Contributor: Renato Westphal <renato@opensourcerouting.org> for NetDEF + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _FRR_ISIS_SR_H +#define _FRR_ISIS_SR_H + +#include "lib/linklist.h" +#include "lib/mpls.h" +#include "lib/nexthop.h" +#include "lib/typesafe.h" + +#include "isisd/isis_tlvs.h" + +/* + * Segment Routing information is transported through the following Sub-TLVs: + * + * Sub-TLV Name Value TLVs + * --------------------------------------------------------------------- + * SID Label 1 + * + * Prefix Segment Identifier 3 135, 235, 236 and 237 + * + * Adjacency Segment Identifier 31 22, 23, 141, 222 and 223 + * LAN Adjacency Segment Identifier 32 22, 23, 141, 222 and 223 + * + * Segment Routing Capability 2 242 + * Segment Routing Algorithm 19 242 + * Node Maximum Stack Depth (MSD) 23 242 + * + * Sub-TLV definitions, serialization and de-serialization are defined + * in isis_tlvs.[c,h]. + */ + +#define SRGB_LOWER_BOUND 16000 +#define SRGB_UPPER_BOUND 23999 +#define SRLB_LOWER_BOUND 15000 +#define SRLB_UPPER_BOUND 15999 + +/* Segment Routing Data Base (SRDB) RB-Tree structure */ +PREDECL_RBTREE_UNIQ(srdb_prefix_cfg); + +/* + * Segment Routing Prefix-SID information. + * + * This structure is intended to be embedded inside other structures that + * might or might not contain Prefix-SID information. + */ +struct isis_sr_psid_info { + /* Prefix-SID Sub-TLV information. */ + struct isis_prefix_sid sid; + + /* Resolved input/output label. */ + mpls_label_t label; + + /* Indicates whether the Prefix-SID is present or not. */ + bool present; +}; + +/* Segment Routing Local Block allocation */ +struct sr_local_block { + bool active; + uint32_t start; + uint32_t end; + uint32_t current; + uint32_t max_block; + uint64_t *used_mark; +}; +#define SRLB_BLOCK_SIZE 64 + +/* Segment Routing Adjacency-SID type. */ +enum sr_adj_type { + ISIS_SR_ADJ_NORMAL = 0, + ISIS_SR_LAN_BACKUP, +}; + +/* Segment Routing Adjacency. */ +struct sr_adjacency { + /* Adjacency type. */ + enum sr_adj_type type; + + /* Adjacency-SID input label. */ + mpls_label_t input_label; + + /* Adjacency-SID nexthop information. */ + struct { + int family; + union g_addr address; + } nexthop; + + /* Adjacency-SID TI-LFA backup nexthops. */ + struct list *backup_nexthops; + + /* (LAN-)Adjacency-SID Sub-TLV. */ + union { + struct isis_adj_sid *adj_sid; + struct isis_lan_adj_sid *ladj_sid; + } u; + + /* Back pointer to IS-IS adjacency. */ + struct isis_adjacency *adj; +}; + +/* SID type. NOTE: these values must be in sync with the YANG module. */ +enum sr_sid_value_type { + SR_SID_VALUE_TYPE_INDEX = 0, + SR_SID_VALUE_TYPE_ABSOLUTE = 1, +}; + +#define IS_SID_VALUE(flag) CHECK_FLAG(flag, ISIS_PREFIX_SID_VALUE) + +/* Last Hop Behavior. NOTE: these values must be in sync with the YANG module */ +enum sr_last_hop_behavior { + SR_LAST_HOP_BEHAVIOR_EXP_NULL = 0, + SR_LAST_HOP_BEHAVIOR_NO_PHP = 1, + SR_LAST_HOP_BEHAVIOR_PHP = 2, +}; + +/* Segment Routing Prefix-SID configuration. */ +struct sr_prefix_cfg { + /* SRDB RB-tree entry. */ + struct srdb_prefix_cfg_item entry; + + /* IP prefix. */ + struct prefix prefix; + + /* SID value. */ + uint32_t sid; + + /* SID value type. */ + enum sr_sid_value_type sid_type; + + /* SID last hop behavior. */ + enum sr_last_hop_behavior last_hop_behavior; + + /* Indicates whether the node flag must be explicitly unset. */ + bool n_flag_clear; + + /* Does this Prefix-SID refer to a loopback address (Node-SID)? */ + bool node_sid; + + /* Backpointer to IS-IS area. */ + struct isis_area *area; +}; + +/* Per-area IS-IS Segment Routing Data Base (SRDB). */ +struct isis_sr_db { + /* Global Operational status of Segment Routing. */ + bool enabled; + + /* Thread timer to start Label Manager */ + struct thread *t_start_lm; + + /* List of local Adjacency-SIDs. */ + struct list *adj_sids; + + /* Management of SRLB & SRGB allocation */ + struct sr_local_block srlb; + bool srgb_active; + + /* Area Segment Routing configuration. */ + struct { + /* Administrative status of Segment Routing. */ + bool enabled; + + /* Segment Routing Global Block lower & upper bound. */ + uint32_t srgb_lower_bound; + uint32_t srgb_upper_bound; + + /* Segment Routing Local Block lower & upper bound. */ + uint32_t srlb_lower_bound; + uint32_t srlb_upper_bound; + + /* Maximum SID Depth supported by the node. */ + uint8_t msd; + + /* Prefix-SID mappings. */ + struct srdb_prefix_cfg_head prefix_sids; + } config; +}; + +/* Prototypes. */ +extern struct isis_sr_block *isis_sr_find_srgb(struct lspdb_head *lspdb, + const uint8_t *sysid); +extern mpls_label_t sr_prefix_in_label(struct isis_area *area, + struct isis_prefix_sid *psid, + bool local); +extern mpls_label_t sr_prefix_out_label(struct lspdb_head *lspdb, int family, + struct isis_prefix_sid *psid, + const uint8_t *nh_sysid, bool last_hop); +extern int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound, + uint32_t upper_bound); +extern int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_bound, + uint32_t upper_bound); +extern struct sr_prefix_cfg * +isis_sr_cfg_prefix_add(struct isis_area *area, const struct prefix *prefix); +extern void isis_sr_cfg_prefix_del(struct sr_prefix_cfg *pcfg); +extern struct sr_prefix_cfg * +isis_sr_cfg_prefix_find(struct isis_area *area, union prefixconstptr prefix); +extern void isis_sr_prefix_cfg2subtlv(const struct sr_prefix_cfg *pcfg, + bool external, + struct isis_prefix_sid *psid); +extern void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, + bool backup, struct list *nexthops); +extern struct sr_adjacency *isis_sr_adj_sid_find(struct isis_adjacency *adj, + int family, + enum sr_adj_type type); +extern void isis_area_delete_backup_adj_sids(struct isis_area *area, int level); +extern char *sr_op2str(char *buf, size_t size, mpls_label_t label_in, + mpls_label_t label_out); +extern int isis_sr_start(struct isis_area *area); +extern void isis_sr_stop(struct isis_area *area); +extern void isis_sr_area_init(struct isis_area *area); +extern void isis_sr_area_term(struct isis_area *area); +extern void isis_sr_init(void); +extern void isis_sr_term(void); + +#endif /* _FRR_ISIS_SR_H */ |