summaryrefslogtreecommitdiffstats
path: root/isisd/isisd.h
blob: f5042e4ad5c290adcded807e7af4d7c13b0b6c3c (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
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * IS-IS Rout(e)ing protocol - isisd.h
 *
 * Copyright (C) 2001,2002   Sampo Saaristo
 *                           Tampere University of Technology
 *                           Institute of Communications Engineering
 */

#ifndef ISISD_H
#define ISISD_H

#include "vty.h"
#include "memory.h"

#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_redist.h"
#include "isisd/isis_pdu_counter.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_sr.h"
#include "isisd/isis_srv6.h"
#include "isis_flags.h"
#include "isis_lsp.h"
#include "isis_lfa.h"
#include "qobj.h"
#include "ldp_sync.h"
#include "iso.h"

DECLARE_MGROUP(ISISD);

#ifdef FABRICD
static const bool fabricd = true;
#define PROTO_TYPE ZEBRA_ROUTE_OPENFABRIC
#define PROTO_NAME "openfabric"
#define PROTO_HELP "OpenFabric routing protocol\n"
#define PROTO_REDIST_STR FRR_REDIST_STR_FABRICD
#define PROTO_IP_REDIST_STR FRR_IP_REDIST_STR_FABRICD
#define PROTO_IP6_REDIST_STR FRR_IP6_REDIST_STR_FABRICD
#define PROTO_REDIST_HELP FRR_REDIST_HELP_STR_FABRICD
#define PROTO_IP_REDIST_HELP FRR_IP_REDIST_HELP_STR_FABRICD
#define PROTO_IP6_REDIST_HELP FRR_IP6_REDIST_HELP_STR_FABRICD
#define ROUTER_NODE OPENFABRIC_NODE
#else
static const bool fabricd = false;
#define PROTO_TYPE ZEBRA_ROUTE_ISIS
#define PROTO_NAME "isis"
#define PROTO_HELP "IS-IS routing protocol\n"
#define PROTO_REDIST_STR FRR_REDIST_STR_ISISD
#define PROTO_IP_REDIST_STR FRR_IP_REDIST_STR_ISISD
#define PROTO_IP6_REDIST_STR FRR_IP6_REDIST_STR_ISISD
#define PROTO_REDIST_HELP FRR_REDIST_HELP_STR_ISISD
#define PROTO_IP_REDIST_HELP FRR_IP_REDIST_HELP_STR_ISISD
#define PROTO_IP6_REDIST_HELP FRR_IP6_REDIST_HELP_STR_ISISD
#define ROUTER_NODE ISIS_NODE
extern void isis_cli_init(void);
#endif

#define ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf)             \
	if (argv_find(argv, argc, "vrf", &idx_vrf)) {                          \
		vrf_name = argv[idx_vrf + 1]->arg;                             \
		all_vrf = strmatch(vrf_name, "all");                           \
	}

extern struct zebra_privs_t isisd_privs;

/* uncomment if you are a developer in bug hunt */
/* #define EXTREME_DEBUG  */

struct fabricd;

struct isis_master {
	/* ISIS instance. */
	struct list *isis;
	/* ISIS thread master. */
	struct event_loop *master;
	uint8_t options;
};
#define F_ISIS_UNIT_TEST 0x01

#define ISIS_DEFAULT_MAX_AREA_ADDRESSES 3

struct isis {
	vrf_id_t vrf_id;
	char *name;
	unsigned long process_id;
	int sysid_set;
	uint8_t sysid[ISIS_SYS_ID_LEN]; /* SystemID for this IS */
	uint32_t router_id;		/* Router ID from zebra */
	struct list *area_list;	/* list of IS-IS areas */
	uint8_t max_area_addrs;		  /* maximumAreaAdresses */
	struct iso_address *man_area_addrs; /* manualAreaAddresses */
	time_t uptime;			  /* when did we start */
	struct event *t_dync_clean; /* dynamic hostname cache cleanup thread */
	uint32_t circuit_ids_used[8];     /* 256 bits to track circuit ids 1 through 255 */
	int snmp_notifications;
	struct list *dyn_cache;

	struct route_table *ext_info[REDIST_PROTOCOL_COUNT];
};

extern struct isis_master *im;

extern struct event *t_isis_cfg;

enum spf_tree_id {
	SPFTREE_IPV4 = 0,
	SPFTREE_IPV6,
	SPFTREE_DSTSRC,
	SPFTREE_COUNT
};

struct lsp_refresh_arg {
	struct isis_area *area;
	int level;
};

/* for yang configuration */
enum isis_metric_style {
	ISIS_NARROW_METRIC = 0,
	ISIS_WIDE_METRIC,
	ISIS_TRANSITION_METRIC,
};

struct isis_area {
	struct isis *isis;			       /* back pointer */
	struct lspdb_head lspdb[ISIS_LEVELS];	       /* link-state dbs */
	struct isis_spftree *spftree[SPFTREE_COUNT][ISIS_LEVELS];
#define DEFAULT_LSP_MTU 1497
	unsigned int lsp_mtu;      /* Size of LSPs to generate */
	struct list *circuit_list; /* IS-IS circuits */
	struct list *adjacency_list; /* IS-IS adjacencies */
	struct flags flags;
	struct event *t_tick; /* LSP walker */
	struct event *t_lsp_refresh[ISIS_LEVELS];
	struct event *t_overload_on_startup_timer;
	struct timeval last_lsp_refresh_event[ISIS_LEVELS];
	struct event *t_rlfa_rib_update;
	/* t_lsp_refresh is used in two ways:
	 * a) regular refresh of LSPs
	 * b) (possibly throttled) updates to LSPs
	 *
	 * The lsp_regenerate_pending flag tracks whether the timer is active
	 * for the a) or the b) case.
	 *
	 * It is of utmost importance to clear this flag when the timer is
	 * rescheduled for normal refresh, because otherwise, updates will
	 * be delayed until the next regular refresh.
	 */
	int lsp_regenerate_pending[ISIS_LEVELS];

	bool bfd_signalled_down;
	bool bfd_force_spf_refresh;

	struct fabricd *fabricd;

	/*
	 * Configurables
	 */
	struct isis_passwd area_passwd;
	struct isis_passwd domain_passwd;
	/* do we support dynamic hostnames?  */
	char dynhostname;
	/* do we support new style metrics?  */
	char newmetric;
	char oldmetric;
	/* Allow sending the default admin-group value of 0x00000000. */
	bool admin_group_send_zero;
	/* Set the legacy flag (aka. L-FLAG) in the ASLA Sub-TLV */
	bool asla_legacy_flag;
	/* identifies the routing instance   */
	char *area_tag;
	/* area addresses for this area      */
	struct list *area_addrs;
	uint16_t max_lsp_lifetime[ISIS_LEVELS];
	char is_type; /* level-1 level-1-2 or level-2-only */
	/* are we overloaded? */
	char overload_bit;
	bool overload_configured;
	uint32_t overload_counter;
	uint32_t overload_on_startup_time;
	/* advertise prefixes of passive interfaces only? */
	bool advertise_passive_only;
	/* Are we advertising high metrics? */
	bool advertise_high_metrics;
	/* L1/L2 router identifier for inter-area traffic */
	char attached_bit_send;
	char attached_bit_rcv_ignore;
	uint16_t lsp_refresh[ISIS_LEVELS];
	/* minimum time allowed before lsp retransmission */
	uint16_t lsp_gen_interval[ISIS_LEVELS];
	/* min interval between between consequtive SPFs */
	uint16_t min_spf_interval[ISIS_LEVELS];
	/* the percentage of LSP mtu size used, before generating a new frag */
	int lsp_frag_threshold;
	uint64_t lsp_gen_count[ISIS_LEVELS];
	uint64_t lsp_purge_count[ISIS_LEVELS];
	uint32_t lsp_exceeded_max_counter;
	uint32_t lsp_seqno_skipped_counter;
	uint64_t spf_run_count[ISIS_LEVELS];
	int ip_circuits;
	/* logging adjacency changes? */
	uint8_t log_adj_changes;
	/* logging pdu drops? */
	uint8_t log_pdu_drops;
	/* multi topology settings */
	struct list *mt_settings;
	/* MPLS-TE settings */
	struct mpls_te_area *mta;
	/* Segment Routing information */
	struct isis_sr_db srdb;
	/* Segment Routing over IPv6 (SRv6) information */
	struct isis_srv6_db srv6db;
	int ipv6_circuits;
	bool purge_originator;
	/* SPF prefix priorities. */
	struct spf_prefix_priority_acl
		spf_prefix_priorities[SPF_PREFIX_PRIO_MAX];
	/* Fast Re-Route information. */
	size_t lfa_protected_links[ISIS_LEVELS];
	size_t lfa_load_sharing[ISIS_LEVELS];
	enum spf_prefix_priority lfa_priority_limit[ISIS_LEVELS];
	struct lfa_tiebreaker_tree_head lfa_tiebreakers[ISIS_LEVELS];
	char *rlfa_plist_name[ISIS_LEVELS];
	struct prefix_list *rlfa_plist[ISIS_LEVELS];
	size_t rlfa_protected_links[ISIS_LEVELS];
	size_t tilfa_protected_links[ISIS_LEVELS];
	/* MPLS LDP-IGP Sync */
	struct ldp_sync_info_cmd ldp_sync_cmd;
#ifndef FABRICD
	/* Flex-Algo */
	struct flex_algos *flex_algos;
#endif /* ifndef FABRICD */
	/* Counters */
	uint32_t circuit_state_changes;
	struct list *redist_settings[REDIST_PROTOCOL_COUNT][ZEBRA_ROUTE_MAX + 1]
				    [ISIS_LEVELS];
	struct route_table *ext_reach[REDIST_PROTOCOL_COUNT][ISIS_LEVELS];

	struct spf_backoff *spf_delay_ietf[ISIS_LEVELS]; /*Structure with IETF
							    SPF algo
							    parameters*/
	struct event *spf_timer[ISIS_LEVELS];

	struct lsp_refresh_arg lsp_refresh_arg[ISIS_LEVELS];

	pdu_counter_t pdu_tx_counters;
	pdu_counter_t pdu_rx_counters;
	pdu_counter_t pdu_drop_counters;
	uint64_t lsp_rxmt_count;

	/* Area counters */
	uint64_t rej_adjacencies[2];
	uint64_t auth_type_failures[2];
	uint64_t auth_failures[2];
	uint64_t id_len_mismatches[2];
	uint64_t lsp_error_counter[2];

	QOBJ_FIELDS;
};
DECLARE_QOBJ_TYPE(isis_area);

DECLARE_MTYPE(ISIS_ACL_NAME);	/* isis_area->spf_prefix_prioritites */
DECLARE_MTYPE(ISIS_AREA_ADDR);	/* isis_area->area_addrs */
DECLARE_MTYPE(ISIS_PLIST_NAME);

DECLARE_HOOK(isis_area_overload_bit_update, (struct isis_area * area), (area));

void isis_terminate(void);
void isis_master_init(struct event_loop *master);
void isis_vrf_link(struct isis *isis, struct vrf *vrf);
void isis_vrf_unlink(struct isis *isis, struct vrf *vrf);
struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id);
struct isis *isis_lookup_by_vrfname(const char *vrfname);
struct isis *isis_lookup_by_sysid(const uint8_t *sysid);

void isis_init(void);
void isis_vrf_init(void);

struct isis *isis_new(const char *vrf_name);
void isis_finish(struct isis *isis);

void isis_area_add_circuit(struct isis_area *area,
			   struct isis_circuit *circuit);
void isis_area_del_circuit(struct isis_area *area,
			   struct isis_circuit *circuit);

struct isis_area *isis_area_create(const char *, const char *);
struct isis_area *isis_area_lookup(const char *, vrf_id_t vrf_id);
struct isis_area *isis_area_lookup_by_vrf(const char *area_tag,
					  const char *vrf_name);
int isis_area_get(struct vty *vty, const char *area_tag);
void isis_area_destroy(struct isis_area *area);
void isis_filter_update(struct access_list *access);
void isis_prefix_list_update(struct prefix_list *plist);
void print_debug(struct vty *, int, int);
struct isis_lsp *lsp_for_sysid(struct lspdb_head *head, const char *sysid_str,
			       struct isis *isis);

void isis_area_invalidate_routes(struct isis_area *area, int levels);
void isis_area_verify_routes(struct isis_area *area);
void isis_area_switchover_routes(struct isis_area *area, int family,
				 union g_addr *nexthop_ip, ifindex_t ifindex,
				 int level);

void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit);
void isis_area_overload_on_startup_set(struct isis_area *area,
				       uint32_t startup_time);
void isis_area_advertise_high_metrics_set(struct isis_area *area,
					  bool advertise_high_metrics);
void isis_area_attached_bit_send_set(struct isis_area *area, bool attached_bit);
void isis_area_attached_bit_receive_set(struct isis_area *area,
					bool attached_bit);
void isis_area_dynhostname_set(struct isis_area *area, bool dynhostname);
void isis_area_metricstyle_set(struct isis_area *area, bool old_metric,
			       bool new_metric);
void isis_area_lsp_mtu_set(struct isis_area *area, unsigned int lsp_mtu);
void isis_area_is_type_set(struct isis_area *area, int is_type);
void isis_area_max_lsp_lifetime_set(struct isis_area *area, int level,
				    uint16_t max_lsp_lifetime);
void isis_area_lsp_refresh_set(struct isis_area *area, int level,
			       uint16_t lsp_refresh);
/* IS_LEVEL_1 sets area_passwd, IS_LEVEL_2 domain_passwd */
int isis_area_passwd_unset(struct isis_area *area, int level);
int isis_area_passwd_cleartext_set(struct isis_area *area, int level,
				   const char *passwd, uint8_t snp_auth);
int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
				  const char *passwd, uint8_t snp_auth);
void show_isis_database_lspdb_json(struct json_object *json,
				   struct isis_area *area, int level,
				   struct lspdb_head *lspdb, const char *argv,
				   int ui_level);
void show_isis_database_lspdb_vty(struct vty *vty, struct isis_area *area,
				  int level, struct lspdb_head *lspdb,
				  const char *argv, int ui_level);
char *isis_restart_filepath(void);
void isis_restart_write_overload_time(struct isis_area *isis_area,
				      uint32_t overload_time);
uint32_t isis_restart_read_overload_time(struct isis_area *isis_area);
void config_end_lsp_generate(struct isis_area *area);

/* YANG paths */
#define ISIS_INSTANCE	"/frr-isisd:isis/instance"
#define ISIS_SR		"/frr-isisd:isis/instance/segment-routing"
#define ISIS_SRV6	"/frr-isisd:isis/instance/segment-routing-srv6"

/* Master of threads. */
extern struct event_loop *master;

extern unsigned long debug_adj_pkt;
extern unsigned long debug_snp_pkt;
extern unsigned long debug_update_pkt;
extern unsigned long debug_spf_events;
extern unsigned long debug_rte_events;
extern unsigned long debug_events;
extern unsigned long debug_pkt_dump;
extern unsigned long debug_lsp_gen;
extern unsigned long debug_lsp_sched;
extern unsigned long debug_flooding;
extern unsigned long debug_bfd;
extern unsigned long debug_tx_queue;
extern unsigned long debug_sr;
extern unsigned long debug_ldp_sync;
extern unsigned long debug_lfa;
extern unsigned long debug_te;

#define DEBUG_ADJ_PACKETS                (1<<0)
#define DEBUG_SNP_PACKETS                (1<<1)
#define DEBUG_UPDATE_PACKETS             (1<<2)
#define DEBUG_SPF_EVENTS                 (1<<3)
#define DEBUG_RTE_EVENTS                 (1<<4)
#define DEBUG_EVENTS                     (1<<5)
#define DEBUG_PACKET_DUMP                (1<<6)
#define DEBUG_LSP_GEN                    (1<<7)
#define DEBUG_LSP_SCHED                  (1<<8)
#define DEBUG_FLOODING                   (1<<9)
#define DEBUG_BFD                        (1<<10)
#define DEBUG_TX_QUEUE                   (1<<11)
#define DEBUG_SR                         (1<<12)
#define DEBUG_LDP_SYNC                   (1<<13)
#define DEBUG_LFA                        (1<<14)
#define DEBUG_TE                         (1<<15)

/* Debug related macro. */
#define IS_DEBUG_ADJ_PACKETS (debug_adj_pkt & DEBUG_ADJ_PACKETS)
#define IS_DEBUG_SNP_PACKETS (debug_snp_pkt & DEBUG_SNP_PACKETS)
#define IS_DEBUG_UPDATE_PACKETS (debug_update_pkt & DEBUG_UPDATE_PACKETS)
#define IS_DEBUG_SPF_EVENTS (debug_spf_events & DEBUG_SPF_EVENTS)
#define IS_DEBUG_RTE_EVENTS (debug_rte_events & DEBUG_RTE_EVENTS)
#define IS_DEBUG_EVENTS (debug_events & DEBUG_EVENTS)
#define IS_DEBUG_PACKET_DUMP (debug_pkt_dump & DEBUG_PACKET_DUMP)
#define IS_DEBUG_LSP_GEN (debug_lsp_gen & DEBUG_LSP_GEN)
#define IS_DEBUG_LSP_SCHED (debug_lsp_sched & DEBUG_LSP_SCHED)
#define IS_DEBUG_FLOODING (debug_flooding & DEBUG_FLOODING)
#define IS_DEBUG_BFD (debug_bfd & DEBUG_BFD)
#define IS_DEBUG_TX_QUEUE (debug_tx_queue & DEBUG_TX_QUEUE)
#define IS_DEBUG_SR (debug_sr & DEBUG_SR)
#define IS_DEBUG_LDP_SYNC (debug_ldp_sync & DEBUG_LDP_SYNC)
#define IS_DEBUG_LFA (debug_lfa & DEBUG_LFA)
#define IS_DEBUG_TE (debug_te & DEBUG_TE)

#define lsp_debug(...)                                                         \
	do {                                                                   \
		if (IS_DEBUG_LSP_GEN)                                          \
			zlog_debug(__VA_ARGS__);                               \
	} while (0)

#define sched_debug(...)                                                       \
	do {                                                                   \
		if (IS_DEBUG_LSP_SCHED)                                        \
			zlog_debug(__VA_ARGS__);                               \
	} while (0)

#define sr_debug(...)                                                          \
	do {                                                                   \
		if (IS_DEBUG_SR)                                               \
			zlog_debug(__VA_ARGS__);                               \
	} while (0)

#define te_debug(...)                                                          \
	do {                                                                   \
		if (IS_DEBUG_TE)                                               \
			zlog_debug(__VA_ARGS__);                               \
	} while (0)

#endif /* ISISD_H */