summaryrefslogtreecommitdiffstats
path: root/isisd/isis_sr.h
blob: 76f776825da5e4aa9f6ce2785f0d32bbaadd940d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * 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
 */

#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;

	uint8_t algorithm;

	struct list *nexthops;
	struct list *nexthops_backup;
};

/* 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_ADJ_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;

	/* SR Algorithm number */
	uint8_t algorithm;
};

/* 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 event *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,
						    uint8_t algorithm);
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,
			uint8_t algorithm);
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 int sr_if_addr_update(struct interface *ifp);
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 */