summaryrefslogtreecommitdiffstats
path: root/pathd/pathd.h
blob: 81d7aa91054adfb9769ed651f4bd84bed400c1de (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
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
/*
 * Copyright (C) 2020  NetDEF, Inc.
 *
 * 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_PATHD_H_
#define _FRR_PATHD_H_

#include "lib/memory.h"
#include "lib/mpls.h"
#include "lib/ipaddr.h"
#include "lib/srte.h"
#include "lib/hook.h"
#include "lib/prefix.h"

#define PATH_SID_ERROR 1
#define PATH_SID_NO_ERROR 0
#define CHECK_SID(or, ts, es)                                                  \
	((or == SRTE_ORIGIN_PCEP && (ts == MPLS_LABEL_NONE || es != ts))       \
	 || (or == SRTE_ORIGIN_LOCAL && ts == MPLS_LABEL_NONE))

DECLARE_MGROUP(PATHD);

DECLARE_HOOK(pathd_srte_config_write, (struct vty *vty), (vty));

enum srte_protocol_origin {
	SRTE_ORIGIN_UNDEFINED = 0,
	SRTE_ORIGIN_PCEP = 1,
	SRTE_ORIGIN_BGP = 2,
	SRTE_ORIGIN_LOCAL = 3,
};

enum srte_policy_status {
	SRTE_POLICY_STATUS_UNKNOWN = 0,
	SRTE_POLICY_STATUS_DOWN = 1,
	SRTE_POLICY_STATUS_UP = 2,
	SRTE_POLICY_STATUS_GOING_DOWN = 3,
	SRTE_POLICY_STATUS_GOING_UP = 4
};

enum srte_candidate_type {
	SRTE_CANDIDATE_TYPE_UNDEFINED = 0,
	SRTE_CANDIDATE_TYPE_EXPLICIT = 1,
	SRTE_CANDIDATE_TYPE_DYNAMIC = 2,
};

enum srte_candidate_metric_type {
	/* IGP metric */
	SRTE_CANDIDATE_METRIC_TYPE_IGP = 1,
	/* TE metric */
	SRTE_CANDIDATE_METRIC_TYPE_TE = 2,
	/* Hop Counts */
	SRTE_CANDIDATE_METRIC_TYPE_HC = 3,
	/* Aggregate bandwidth consumption */
	SRTE_CANDIDATE_METRIC_TYPE_ABC = 4,
	/* Load of the most loaded link */
	SRTE_CANDIDATE_METRIC_TYPE_LMLL = 5,
	/* Cumulative IGP cost */
	SRTE_CANDIDATE_METRIC_TYPE_CIGP = 6,
	/* Cumulative TE cost */
	SRTE_CANDIDATE_METRIC_TYPE_CTE = 7,
	/* P2MP IGP metric */
	SRTE_CANDIDATE_METRIC_TYPE_PIGP = 8,
	/* P2MP TE metric */
	SRTE_CANDIDATE_METRIC_TYPE_PTE = 9,
	/* P2MP hop count metric */
	SRTE_CANDIDATE_METRIC_TYPE_PHC = 10,
	/* Segment-ID (SID) Depth */
	SRTE_CANDIDATE_METRIC_TYPE_MSD = 11,
	/* Path Delay metric */
	SRTE_CANDIDATE_METRIC_TYPE_PD = 12,
	/* Path Delay Variation metric */
	SRTE_CANDIDATE_METRIC_TYPE_PDV = 13,
	/* Path Loss metric */
	SRTE_CANDIDATE_METRIC_TYPE_PL = 14,
	/* P2MP Path Delay metric */
	SRTE_CANDIDATE_METRIC_TYPE_PPD = 15,
	/* P2MP Path Delay variation metric */
	SRTE_CANDIDATE_METRIC_TYPE_PPDV = 16,
	/* P2MP Path Loss metric */
	SRTE_CANDIDATE_METRIC_TYPE_PPL = 17,
	/* Number of adaptations on a path */
	SRTE_CANDIDATE_METRIC_TYPE_NAP = 18,
	/* Number of layers on a path */
	SRTE_CANDIDATE_METRIC_TYPE_NLP = 19,
	/* Domain Count metric */
	SRTE_CANDIDATE_METRIC_TYPE_DC = 20,
	/* Border Node Count metric */
	SRTE_CANDIDATE_METRIC_TYPE_BNC = 21,
};
#define MAX_METRIC_TYPE 21

enum srte_segment_nai_type {
	SRTE_SEGMENT_NAI_TYPE_NONE = 0,
	SRTE_SEGMENT_NAI_TYPE_IPV4_NODE = 1,
	SRTE_SEGMENT_NAI_TYPE_IPV6_NODE = 2,
	SRTE_SEGMENT_NAI_TYPE_IPV4_ADJACENCY = 3,
	SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY = 4,
	SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY = 5,
	SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY_LINK_LOCAL_ADDRESSES = 6,
	SRTE_SEGMENT_NAI_TYPE_IPV4_LOCAL_IFACE = 7,
	SRTE_SEGMENT_NAI_TYPE_IPV6_LOCAL_IFACE = 8,
	SRTE_SEGMENT_NAI_TYPE_IPV4_ALGORITHM = 9,
	SRTE_SEGMENT_NAI_TYPE_IPV6_ALGORITHM = 10
};

enum objfun_type {
	OBJFUN_UNDEFINED = 0,
	/* Minimum Cost Path [RFC5541] */
	OBJFUN_MCP = 1,
	/* Minimum Load Path [RFC5541] */
	OBJFUN_MLP = 2,
	/* Maximum residual Bandwidth Path [RFC5541] */
	OBJFUN_MBP = 3,
	/* Minimize aggregate Bandwidth Consumption [RFC5541] */
	OBJFUN_MBC = 4,
	/* Minimize the Load of the most loaded Link [RFC5541] */
	OBJFUN_MLL = 5,
	/* Minimize the Cumulative Cost of a set of paths [RFC5541] */
	OBJFUN_MCC = 6,
	/* Shortest Path Tree [RFC8306] */
	OBJFUN_SPT = 7,
	/* Minimum Cost Tree [RFC8306] */
	OBJFUN_MCT = 8,
	/* Minimum Packet Loss Path [RFC8233] */
	OBJFUN_MPLP = 9,
	/* Maximum Under-Utilized Path [RFC8233] */
	OBJFUN_MUP = 10,
	/* Maximum Reserved Under-Utilized Path [RFC8233] */
	OBJFUN_MRUP = 11,
	/* Minimize the number of Transit Domains [RFC8685] */
	OBJFUN_MTD = 12,
	/* Minimize the number of Border Nodes [RFC8685] */
	OBJFUN_MBN = 13,
	/* Minimize the number of Common Transit Domains [RFC8685] */
	OBJFUN_MCTD = 14,
	/* Minimize the number of Shared Links [RFC8800] */
	OBJFUN_MSL = 15,
	/* Minimize the number of Shared SRLGs [RFC8800] */
	OBJFUN_MSS = 16,
	/* Minimize the number of Shared Nodes [RFC8800] */
	OBJFUN_MSN = 17,
};
#define MAX_OBJFUN_TYPE 17

enum affinity_filter_type {
	AFFINITY_FILTER_UNDEFINED = 0,
	AFFINITY_FILTER_EXCLUDE_ANY = 1,
	AFFINITY_FILTER_INCLUDE_ANY = 2,
	AFFINITY_FILTER_INCLUDE_ALL = 3,
};
#define MAX_AFFINITY_FILTER_TYPE 3

struct srte_segment_list;

struct srte_segment_entry {
	RB_ENTRY(srte_segment_entry) entry;

	/* The segment list the entry belong to */
	struct srte_segment_list *segment_list;

	/* Index of the Label. */
	uint32_t index;

	/* Label Value. */
	mpls_label_t sid_value;

	/* NAI Type */
	enum srte_segment_nai_type nai_type;
	/* NAI local address when nai type is not NONE */
	struct ipaddr nai_local_addr;
	/* NAI local interface when nai type is not IPv4 unnumbered adjacency */
	uint32_t nai_local_iface;
	/* NAI local interface when nai type is IPv4 or IPv6 adjacency */
	struct ipaddr nai_remote_addr;
	/* NAI remote interface when nai type is not IPv4 unnumbered adjacency
	 */
	uint32_t nai_remote_iface;
	/* Support draft-ietf-spring-segment-routing-policy sl types queries*/
	uint8_t nai_local_prefix_len;
	uint8_t nai_algorithm;
};
RB_HEAD(srte_segment_entry_head, srte_segment_entry);
RB_PROTOTYPE(srte_segment_entry_head, srte_segment_entry, entry,
	     srte_segment_entry_compare)

struct srte_segment_list {
	RB_ENTRY(srte_segment_list) entry;

	/* Name of the Segment List. */
	char name[64];

	/* The Protocol-Origin. */
	enum srte_protocol_origin protocol_origin;

	/* The Originator */
	char originator[64];

	/* Nexthops. */
	struct srte_segment_entry_head segments;

	/* Status flags. */
	uint16_t flags;
#define F_SEGMENT_LIST_NEW 0x0002
#define F_SEGMENT_LIST_MODIFIED 0x0004
#define F_SEGMENT_LIST_DELETED 0x0008
#define F_SEGMENT_LIST_SID_CONFLICT 0x0010
};
RB_HEAD(srte_segment_list_head, srte_segment_list);
RB_PROTOTYPE(srte_segment_list_head, srte_segment_list, entry,
	     srte_segment_list_compare)

struct srte_metric {
	uint16_t flags;
#define F_METRIC_IS_DEFINED 0x0001
#define F_METRIC_IS_REQUIRED 0x0002
#define F_METRIC_IS_BOUND 0x0004
#define F_METRIC_IS_COMPUTED 0x0008
	float value;
};

/* Runtime information about the candidate path */
struct srte_lsp {
	/* Backpointer to the Candidate Path. */
	struct srte_candidate *candidate;

	/* The associated Segment List. */
	struct srte_segment_list *segment_list;

	/* The Protocol-Origin. */
	enum srte_protocol_origin protocol_origin;

	/* The Originator */
	char originator[64];

	/* The Discriminator */
	uint32_t discriminator;

	/* Flags. */
	uint32_t flags;

	/* Metrics LSP Values */
	struct srte_metric metrics[MAX_METRIC_TYPE];

	/* Bandwidth Configured Value */
	float bandwidth;

	/* The objective function in used */
	enum objfun_type objfun;
};

/* Configured candidate path */
struct srte_candidate {
	RB_ENTRY(srte_candidate) entry;

	/* Backpointer to SR Policy */
	struct srte_policy *policy;

	/* The LSP associated with this candidate path. */
	struct srte_lsp *lsp;

	/* Administrative preference. */
	uint32_t preference;

	/* Symbolic Name. */
	char name[64];

	/* The associated Segment List. */
	struct srte_segment_list *segment_list;

	/* The Protocol-Origin. */
	enum srte_protocol_origin protocol_origin;

	/* The Originator */
	char originator[64];

	/* The Discriminator */
	uint32_t discriminator;

	/* The Type (explicit or dynamic) */
	enum srte_candidate_type type;

	/* Flags. */
	uint32_t flags;
#define F_CANDIDATE_BEST 0x0001
#define F_CANDIDATE_NEW 0x0002
#define F_CANDIDATE_MODIFIED 0x0004
#define F_CANDIDATE_DELETED 0x0008
#define F_CANDIDATE_HAS_BANDWIDTH 0x0100
#define F_CANDIDATE_REQUIRED_BANDWIDTH 0x0200
#define F_CANDIDATE_HAS_OBJFUN 0x0400
#define F_CANDIDATE_REQUIRED_OBJFUN 0x0800
#define F_CANDIDATE_HAS_EXCLUDE_ANY 0x1000
#define F_CANDIDATE_HAS_INCLUDE_ANY 0x2000
#define F_CANDIDATE_HAS_INCLUDE_ALL 0x4000

	/* Metrics Configured Values */
	struct srte_metric metrics[MAX_METRIC_TYPE];

	/* Bandwidth Configured Value */
	float bandwidth;

	/* Configured objective functions */
	enum objfun_type objfun;

	/* Path constraints attribute filters */
	uint32_t affinity_filters[MAX_AFFINITY_FILTER_TYPE];

	/* Hooks delaying timer */
	struct thread *hook_timer;
};

RB_HEAD(srte_candidate_head, srte_candidate);
RB_PROTOTYPE(srte_candidate_head, srte_candidate, entry, srte_candidate_compare)

struct srte_policy {
	RB_ENTRY(srte_policy) entry;

	/* Color */
	uint32_t color;

	/* Endpoint */
	struct ipaddr endpoint;

	/* Name */
	char name[64];

	/* Binding SID */
	mpls_label_t binding_sid;

	/* The Protocol-Origin. */
	enum srte_protocol_origin protocol_origin;

	/* The Originator */
	char originator[64];

	/* Operational Status of the policy */
	enum srte_policy_status status;

	/* Best candidate path. */
	struct srte_candidate *best_candidate;

	/* Candidate Paths */
	struct srte_candidate_head candidate_paths;
	/* Status flags. */
	uint16_t flags;
#define F_POLICY_NEW 0x0002
#define F_POLICY_MODIFIED 0x0004
#define F_POLICY_DELETED 0x0008
	/* SRP id for PcInitiated support */
	int srp_id;
};
RB_HEAD(srte_policy_head, srte_policy);
RB_PROTOTYPE(srte_policy_head, srte_policy, entry, srte_policy_compare)

DECLARE_HOOK(pathd_candidate_created, (struct srte_candidate * candidate),
	     (candidate));
DECLARE_HOOK(pathd_candidate_updated, (struct srte_candidate * candidate),
	     (candidate));
DECLARE_HOOK(pathd_candidate_removed, (struct srte_candidate * candidate),
	     (candidate));

extern struct srte_segment_list_head srte_segment_lists;
extern struct srte_policy_head srte_policies;
extern struct zebra_privs_t pathd_privs;

/* master thread, defined in path_main.c */
extern struct thread_master *master;

/* pathd.c */
struct srte_segment_list *srte_segment_list_add(const char *name);
void srte_segment_list_del(struct srte_segment_list *segment_list);
struct srte_segment_list *srte_segment_list_find(const char *name);
struct srte_segment_entry *
srte_segment_entry_add(struct srte_segment_list *segment_list, uint32_t index);
void srte_segment_entry_del(struct srte_segment_entry *segment);
int srte_segment_entry_set_nai(struct srte_segment_entry *segment,
			       enum srte_segment_nai_type type,
			       struct ipaddr *local_ip, uint32_t local_iface,
			       struct ipaddr *remote_ip, uint32_t remote_iface,
			       uint8_t algo, uint8_t pref_len);
void srte_segment_set_local_modification(struct srte_segment_list *s_list,
					 struct srte_segment_entry *s_entry,
					 uint32_t ted_sid);
struct srte_policy *srte_policy_add(uint32_t color, struct ipaddr *endpoint,
				    enum srte_protocol_origin origin,
				    const char *originator);
void srte_policy_del(struct srte_policy *policy);
struct srte_policy *srte_policy_find(uint32_t color, struct ipaddr *endpoint);
int srte_policy_update_ted_sid(void);
void srte_policy_update_binding_sid(struct srte_policy *policy,
				    uint32_t binding_sid);
void srte_apply_changes(void);
void srte_clean_zebra(void);
void srte_policy_apply_changes(struct srte_policy *policy);
struct srte_candidate *srte_candidate_add(struct srte_policy *policy,
					  uint32_t preference,
					  enum srte_protocol_origin origin,
					  const char *originator);
void srte_candidate_del(struct srte_candidate *candidate);
void srte_candidate_set_bandwidth(struct srte_candidate *candidate,
				  float bandwidth, bool required);
void srte_candidate_unset_bandwidth(struct srte_candidate *candidate);
void srte_candidate_set_metric(struct srte_candidate *candidate,
			       enum srte_candidate_metric_type type,
			       float value, bool required, bool is_cound,
			       bool is_computed);
void srte_candidate_unset_metric(struct srte_candidate *candidate,
				 enum srte_candidate_metric_type type);
void srte_candidate_set_objfun(struct srte_candidate *candidate, bool required,
			       enum objfun_type type);
void srte_candidate_unset_objfun(struct srte_candidate *candidate);
void srte_candidate_set_affinity_filter(struct srte_candidate *candidate,
					enum affinity_filter_type type,
					uint32_t filter);
void srte_candidate_unset_affinity_filter(struct srte_candidate *candidate,
					  enum affinity_filter_type type);
void srte_lsp_set_bandwidth(struct srte_lsp *lsp, float bandwidth,
			    bool required);
void srte_lsp_unset_bandwidth(struct srte_lsp *lsp);
void srte_lsp_set_metric(struct srte_lsp *lsp,
			 enum srte_candidate_metric_type type, float value,
			 bool required, bool is_cound, bool is_computed);
void srte_lsp_unset_metric(struct srte_lsp *lsp,
			   enum srte_candidate_metric_type type);
struct srte_candidate *srte_candidate_find(struct srte_policy *policy,
					   uint32_t preference);
struct srte_segment_entry *
srte_segment_entry_find(struct srte_segment_list *segment_list, uint32_t index);
void srte_candidate_status_update(struct srte_candidate *candidate, int status);
void srte_candidate_unset_segment_list(const char *originator, bool force);
const char *srte_origin2str(enum srte_protocol_origin origin);
void pathd_shutdown(void);

/* path_cli.c */
void path_cli_init(void);


/**
 * Search for sid based in prefix and algorithm
 *
 * @param Prefix	The prefix to use
 * @param algo		Algorithm we want to query for
 * @param ted_sid	Sid to query
 *
 * @return		void
 */
int32_t srte_ted_do_query_type_c(struct srte_segment_entry *entry,
				 struct prefix *prefix_cli, uint32_t algo);

/**
 * Search for sid based in prefix and interface id
 *
 * @param Prefix	The prefix to use
 * @param local_iface	The id of interface
 * @param ted_sid	Sid to query
 *
 * @return		void
 */
int32_t srte_ted_do_query_type_e(struct srte_segment_entry *entry,
				 struct prefix *prefix_cli,
				 uint32_t local_iface);
/**
 * Search for sid based in local and remote ip
 *
 * @param entry		entry to update
 * @param local		Local addr for query
 * @param remote	Local addr for query
 *
 * @return		void
 */
int32_t srte_ted_do_query_type_f(struct srte_segment_entry *entry,
				 struct ipaddr *local, struct ipaddr *remote);
#endif /* _FRR_PATHD_H_ */