summaryrefslogtreecommitdiffstats
path: root/isisd/isis_sr.h
blob: a7d52aafe1f79c4bb45863915987993c1292482f (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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
/*
 * This is an implementation of Segment Routing for IS-IS
 * as per draft draft-ietf-isis-segment-routing-extensions-25
 *
 * Copyright (C) 2019 Orange Labs 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

PREDECL_RBTREE_UNIQ(srdb_node)
PREDECL_RBTREE_UNIQ(srdb_node_prefix)
PREDECL_RBTREE_UNIQ(srdb_area_prefix)
PREDECL_RBTREE_UNIQ(srdb_prefix_cfg)

/* SR Adj-SID type. */
enum sr_adj_type {
	ISIS_SR_ADJ_NORMAL = 0,
	ISIS_SR_LAN_BACKUP,
};

/* SR Adjacency. */
struct sr_adjacency {
	/* Adjacency type. */
	enum sr_adj_type type;

	/* Adj-SID nexthop information. */
	struct {
		int family;
		union g_addr address;
		mpls_label_t label;
	} nexthop;

	/* (LAN-)Adj-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;
};

/* SR Prefix-SID type. */
enum sr_prefix_type {
	ISIS_SR_PREFIX_LOCAL = 0,
	ISIS_SR_PREFIX_REMOTE,
};

/* SR Nexthop Information. */
struct sr_nexthop_info {
	mpls_label_t label;
	time_t uptime;
};

/* State of Object (SR-Node and SR-Prefix) stored in SRDB */
enum srdb_state {
	SRDB_STATE_VALIDATED = 0,
	SRDB_STATE_NEW,
	SRDB_STATE_MODIFIED,
	SRDB_STATE_UNCHANGED
};

/* SR Prefix-SID. */
struct sr_prefix {
	/* RB-tree entries. */
	struct srdb_node_prefix_item node_entry;
	struct srdb_area_prefix_item area_entry;

	/* IP prefix. */
	struct prefix prefix;

	/* SID value, algorithm and flags. */
	struct isis_prefix_sid sid;

	/* Local label value. */
	mpls_label_t local_label;

	/* Prefix-SID type. */
	enum sr_prefix_type type;
	union {
		struct {
			/* Information about this local Prefix-SID. */
			struct sr_nexthop_info info;
		} local;
		struct {
			/* Route associated to this remote Prefix-SID. */
			struct isis_route_info *rinfo;
		} remote;
	} u;

	/* Backpointer to SR node. */
	struct sr_node *srn;

	/* SR-Prefix State used while the LSPDB is being parsed. */
	enum srdb_state state;
};

/* SR node. */
struct sr_node {
	/* RB-tree entry. */
	struct srdb_node_item entry;

	/* IS-IS level: ISIS_LEVEL1 or ISIS_LEVEL2. */
	int level;

	/* IS-IS node identifier. */
	uint8_t sysid[ISIS_SYS_ID_LEN];

	/* IS-IS node capabilities (SRGB, SR Algorithms, etc). */
	struct isis_router_cap cap;

	/* List of Prefix-SIDs advertised by this node. */
	struct srdb_node_prefix_head prefix_sids;

	/* Backpointer to IS-IS area. */
	struct isis_area *area;

	/* SR-Node State used while the LSPDB is being parsed. */
	enum srdb_state state;
};

/* 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,
};

/* 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,
};

/* SR Prefix-SID configuration. */
struct sr_prefix_cfg {
	/* 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;

	/* 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 information. */
struct isis_sr_db {
	/* Operational status of Segment Routing. */
	bool enabled;

	/* Adj-SIDs. */
	struct list *adj_sids;

	/* SR information from all nodes. */
	struct srdb_node_head sr_nodes[ISIS_LEVELS];

	/* Prefix-SIDs. */
	struct srdb_area_prefix_head prefix_sids[ISIS_LEVELS];

	/* Area SR 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;

		/* Maximum SID Depth supported by the node. */
		uint8_t msd;

		/* Prefix-SID mappings. */
		struct srdb_prefix_cfg_head prefix_sids;
	} config;
};

/* Prototypes. */
extern int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound,
				   uint32_t upper_bound);
extern void isis_sr_cfg_msd_update(struct isis_area *area);
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 isis_sr_nexthop_update(struct sr_nexthop_info *srnh,
				   mpls_label_t label);
extern void isis_sr_nexthop_reset(struct sr_nexthop_info *srnh);
extern void isis_area_verify_sr(struct isis_area *area);
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 */