]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_sr.h
Merge pull request #7011 from opensourcerouting/isis-ti-lfa
[mirror_frr.git] / isisd / isis_sr.h
1 /*
2 * This is an implementation of Segment Routing for IS-IS as per RFC 8667
3 *
4 * Copyright (C) 2019 Orange http://www.orange.com
5 *
6 * Author: Olivier Dugeon <olivier.dugeon@orange.com>
7 * Contributor: Renato Westphal <renato@opensourcerouting.org> for NetDEF
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; see the file COPYING; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #ifndef _FRR_ISIS_SR_H
25 #define _FRR_ISIS_SR_H
26
27 #include "lib/linklist.h"
28 #include "lib/mpls.h"
29 #include "lib/nexthop.h"
30 #include "lib/typesafe.h"
31
32 #include "isisd/isis_tlvs.h"
33
34 /*
35 * Segment Routing information is transported through the following Sub-TLVs:
36 *
37 * Sub-TLV Name Value TLVs
38 * ---------------------------------------------------------------------
39 * SID Label 1
40 *
41 * Prefix Segment Identifier 3 135, 235, 236 and 237
42 *
43 * Adjacency Segment Identifier 31 22, 23, 141, 222 and 223
44 * LAN Adjacency Segment Identifier 32 22, 23, 141, 222 and 223
45 *
46 * Segment Routing Capability 2 242
47 * Segment Routing Algorithm 19 242
48 * Node Maximum Stack Depth (MSD) 23 242
49 *
50 * Sub-TLV definitions, serialization and de-serialization are defined
51 * in isis_tlvs.[c,h].
52 */
53
54 #define SRGB_LOWER_BOUND 16000
55 #define SRGB_UPPER_BOUND 23999
56 #define SRLB_LOWER_BOUND 15000
57 #define SRLB_UPPER_BOUND 15999
58
59 /* Segment Routing Data Base (SRDB) RB-Tree structure */
60 PREDECL_RBTREE_UNIQ(srdb_node)
61 PREDECL_RBTREE_UNIQ(srdb_node_prefix)
62 PREDECL_RBTREE_UNIQ(srdb_area_prefix)
63 PREDECL_RBTREE_UNIQ(srdb_prefix_cfg)
64
65 /* Segment Routing Local Block allocation */
66 struct sr_local_block {
67 bool active;
68 uint32_t start;
69 uint32_t end;
70 uint32_t current;
71 uint32_t max_block;
72 uint64_t *used_mark;
73 };
74 #define SRLB_BLOCK_SIZE 64
75
76 /* Segment Routing Adjacency-SID type. */
77 enum sr_adj_type {
78 ISIS_SR_ADJ_NORMAL = 0,
79 ISIS_SR_LAN_BACKUP,
80 };
81
82 /* Segment Routing Adjacency. */
83 struct sr_adjacency {
84 /* Adjacency type. */
85 enum sr_adj_type type;
86
87 /* Adjacency-SID input label. */
88 mpls_label_t input_label;
89
90 /* Adjacency-SID nexthop information. */
91 struct {
92 int family;
93 union g_addr address;
94 } nexthop;
95
96 /* Adjacency-SID TI-LFA backup nexthops. */
97 struct list *backup_nexthops;
98
99 /* (LAN-)Adjacency-SID Sub-TLV. */
100 union {
101 struct isis_adj_sid *adj_sid;
102 struct isis_lan_adj_sid *ladj_sid;
103 } u;
104
105 /* Back pointer to IS-IS adjacency. */
106 struct isis_adjacency *adj;
107 };
108
109 /* Segment Routing Prefix-SID type. */
110 enum sr_prefix_type {
111 ISIS_SR_PREFIX_LOCAL = 0,
112 ISIS_SR_PREFIX_REMOTE,
113 };
114
115 /* Segment Routing Nexthop Information. */
116 struct sr_nexthop_info {
117 mpls_label_t label;
118 time_t uptime;
119 };
120
121 /* State of Object (SR-Node and SR-Prefix) stored in SRDB */
122 enum srdb_state {
123 SRDB_STATE_VALIDATED = 0,
124 SRDB_STATE_NEW,
125 SRDB_STATE_MODIFIED,
126 SRDB_STATE_UNCHANGED
127 };
128
129 /* Segment Routing Prefix-SID. */
130 struct sr_prefix {
131 /* SRDB RB-tree entries. */
132 struct srdb_node_prefix_item node_entry;
133 struct srdb_area_prefix_item area_entry;
134
135 /* IP prefix. */
136 struct prefix prefix;
137
138 /* SID value, algorithm and flags subTLVs. */
139 struct isis_prefix_sid sid;
140
141 /* Input label value. */
142 mpls_label_t input_label;
143
144 /* Prefix-SID type. */
145 enum sr_prefix_type type;
146 union {
147 struct {
148 /* Information about this local Prefix-SID. */
149 struct sr_nexthop_info info;
150 } local;
151 struct {
152 /* Route associated to this remote Prefix-SID. */
153 struct isis_route_info *rinfo;
154 } remote;
155 } u;
156
157 /* Backpointer to Segment Routing node. */
158 struct sr_node *srn;
159
160 /* SR-Prefix State used while the LSPDB is being parsed. */
161 enum srdb_state state;
162 };
163
164 /* Segment Routing node. */
165 struct sr_node {
166 /* SRDB RB-tree entry. */
167 struct srdb_node_item entry;
168
169 /* IS-IS level: ISIS_LEVEL1 or ISIS_LEVEL2. */
170 int level;
171
172 /* IS-IS node identifier. */
173 uint8_t sysid[ISIS_SYS_ID_LEN];
174
175 /* Segment Routing node capabilities (SRGB, SR Algorithms) subTLVs. */
176 struct isis_router_cap cap;
177
178 /* List of Prefix-SIDs advertised by this node. */
179 struct srdb_node_prefix_head prefix_sids;
180
181 /* Backpointer to IS-IS area. */
182 struct isis_area *area;
183
184 /* SR-Node State used while the LSPDB is being parsed. */
185 enum srdb_state state;
186 };
187
188 /* SID type. NOTE: these values must be in sync with the YANG module. */
189 enum sr_sid_value_type {
190 SR_SID_VALUE_TYPE_INDEX = 0,
191 SR_SID_VALUE_TYPE_ABSOLUTE = 1,
192 };
193
194 #define IS_SID_VALUE(flag) CHECK_FLAG(flag, ISIS_PREFIX_SID_VALUE)
195
196 /* Last Hop Behavior. NOTE: these values must be in sync with the YANG module */
197 enum sr_last_hop_behavior {
198 SR_LAST_HOP_BEHAVIOR_EXP_NULL = 0,
199 SR_LAST_HOP_BEHAVIOR_NO_PHP = 1,
200 SR_LAST_HOP_BEHAVIOR_PHP = 2,
201 };
202
203 /* Segment Routing Prefix-SID configuration. */
204 struct sr_prefix_cfg {
205 /* SRDB RB-tree entry. */
206 struct srdb_prefix_cfg_item entry;
207
208 /* IP prefix. */
209 struct prefix prefix;
210
211 /* SID value. */
212 uint32_t sid;
213
214 /* SID value type. */
215 enum sr_sid_value_type sid_type;
216
217 /* SID last hop behavior. */
218 enum sr_last_hop_behavior last_hop_behavior;
219
220 /* Does this Prefix-SID refer to a loopback address (Node-SID)? */
221 bool node_sid;
222
223 /* Backpointer to IS-IS area. */
224 struct isis_area *area;
225 };
226
227 /* Per-area IS-IS Segment Routing Data Base (SRDB). */
228 struct isis_sr_db {
229 /* Global Operational status of Segment Routing. */
230 bool enabled;
231
232 /* Thread timer to start Label Manager */
233 struct thread *t_start_lm;
234
235 /* List of local Adjacency-SIDs. */
236 struct list *adj_sids;
237
238 /* Segment Routing Node information per IS-IS level. */
239 struct srdb_node_head sr_nodes[ISIS_LEVELS];
240
241 /* Segment Routing Prefix-SIDs per IS-IS level. */
242 struct srdb_area_prefix_head prefix_sids[ISIS_LEVELS];
243
244 /* Management of SRLB & SRGB allocation */
245 struct sr_local_block srlb;
246 bool srgb_active;
247
248 /* Area Segment Routing configuration. */
249 struct {
250 /* Administrative status of Segment Routing. */
251 bool enabled;
252
253 /* Segment Routing Global Block lower & upper bound. */
254 uint32_t srgb_lower_bound;
255 uint32_t srgb_upper_bound;
256
257 /* Segment Routing Local Block lower & upper bound. */
258 uint32_t srlb_lower_bound;
259 uint32_t srlb_upper_bound;
260
261 /* Maximum SID Depth supported by the node. */
262 uint8_t msd;
263
264 /* Prefix-SID mappings. */
265 struct srdb_prefix_cfg_head prefix_sids;
266 } config;
267 };
268
269 /* Prototypes. */
270 extern int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound,
271 uint32_t upper_bound);
272 extern int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_bound,
273 uint32_t upper_bound);
274 extern struct sr_prefix_cfg *
275 isis_sr_cfg_prefix_add(struct isis_area *area, const struct prefix *prefix);
276 extern void isis_sr_cfg_prefix_del(struct sr_prefix_cfg *pcfg);
277 extern struct sr_prefix_cfg *
278 isis_sr_cfg_prefix_find(struct isis_area *area, union prefixconstptr prefix);
279 extern void isis_sr_prefix_cfg2subtlv(const struct sr_prefix_cfg *pcfg,
280 bool external,
281 struct isis_prefix_sid *psid);
282 extern void isis_sr_nexthop_update(struct sr_nexthop_info *srnh,
283 mpls_label_t label);
284 extern void isis_sr_nexthop_reset(struct sr_nexthop_info *srnh);
285 extern void sr_adj_sid_add_single(struct isis_adjacency *adj, int family,
286 bool backup, struct list *nexthops);
287 extern struct sr_adjacency *isis_sr_adj_sid_find(struct isis_adjacency *adj,
288 int family,
289 enum sr_adj_type type);
290 extern void isis_area_delete_backup_adj_sids(struct isis_area *area, int level);
291 extern void isis_area_verify_sr(struct isis_area *area);
292 extern int isis_sr_start(struct isis_area *area);
293 extern void isis_sr_stop(struct isis_area *area);
294 extern void isis_sr_area_init(struct isis_area *area);
295 extern void isis_sr_area_term(struct isis_area *area);
296 extern void isis_sr_init(void);
297 extern void isis_sr_term(void);
298
299 #endif /* _FRR_ISIS_SR_H */