-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathtilfa.h
343 lines (271 loc) · 10 KB
/
tilfa.h
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
/*
* =====================================================================================
*
* Filename: tilfa.h
*
* Description: This file contains the definition and declaration of Data structures for TILFA
*
* Version: 1.0
* Created: 12/08/2019 07:04:30 AM
* Revision: none
* Compiler: gcc
*
* Author: Er. Abhishek Sagar, Juniper Networks (https://csepracticals.wixsite.com/csepracticals), [email protected]
* Company: Juniper Networks
*
* This file is part of the SPFComputation distribution (https://github.com/sachinites)
* Copyright (c) 2019 Abhishek Sagar.
* 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, version 3.
*
* 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.
*
* visit website : https://csepracticals.wixsite.com/csepracticals for more courses and projects
*
* =====================================================================================
*/
#ifndef __TILFA__
#define __TILFA__
#include <stdint.h>
#include "instance.h"
#include "data_plane.h"
#include "complete_spf_path.h"
#include "spring_adjsid.h"
#include "LinuxMemoryManager/uapi_mm.h"
typedef struct edge_end_ interface_t;
typedef enum{
TILFA_PREFIX_SID_REFERENCE,
TILFA_ADJ_SID,
RSVP_LSP_LABEL
} tilfa_seg_type;
typedef struct gen_segment_list_{
interface_t *oif;
char gw_ip[PREFIX_LEN + 1];
node_t *nxthop;
boolean is_fhs_rsvp_lsp;
struct s_t{
tilfa_seg_type seg_type;
union gen_segment_list_u_{
node_t *node;
struct {
mpls_label_t adj_sid;
node_t *from_node;
node_t *to_node;
}adj_sid;
}u;
};
struct s_t inet3_mpls_label_out[MPLS_STACK_OP_LIMIT_MAX];
MPLS_STACK_OP inet3_stack_op[MPLS_STACK_OP_LIMIT_MAX];
struct s_t mpls0_mpls_label_out[MPLS_STACK_OP_LIMIT_MAX];
MPLS_STACK_OP mpls0_stack_op[MPLS_STACK_OP_LIMIT_MAX];
} gen_segment_list_t;
static int
gen_segment_list_mpls_label_stack_depth(
gen_segment_list_t *gen_segment_list,
boolean inet3,
boolean mpls0){
assert((inet3 && !mpls0) ||
(!inet3 && mpls0));
int i = 0 ;
if(inet3){
while(gen_segment_list->inet3_stack_op[i] != STACK_OPS_UNKNOWN){
i++;
}
}
else if(mpls0){
while(gen_segment_list->mpls0_stack_op[i] != STACK_OPS_UNKNOWN){
i++;
}
}
return i;
}
void
tilfa_insert_adj_sid_in_label_stack(gen_segment_list_t *gen_segment_list,
int stack_index,
boolean inet3,
boolean mpls0,
node_t *from_node,
node_t *to_node,
LEVEL level,
mpls_label_t adj_sid,
tilfa_seg_type seg_type);
void
tilfa_genseglst_fill_first_hop_segment(
node_t *spf_root,
LEVEL level,
gen_segment_list_t *gen_segment_list,
internal_nh_t *nxthop_ptr,
int *stack_top,
node_t *dest);
#define TILFA_SEGLIST_IS_INET3_ADJ_SID_SET(gen_segment_list_ptr, stack_index) \
(gen_segment_list_ptr->inet3_mpls_label_out[stack_index].u.adj_sid.adj_sid != NO_TAG)
#define TILFA_SEGLIST_IS_MPLS0_ADJ_SID_SET(gen_segment_list_ptr, stack_index) \
(gen_segment_list_ptr->mpls0_mpls_label_out[stack_index].u.adj_sid.adj_sid != NO_TAG)
#define TILFA_GET_INET3_ADJ_SID(gen_segment_list_ptr, stack_index) \
(gen_segment_list_ptr->inet3_mpls_label_out[stack_index].u.adj_sid.adj_sid)
#define TILFA_GET_MPLS0_ADJ_SID(gen_segment_list_ptr, stack_index) \
(gen_segment_list_ptr->mpls0_mpls_label_out[stack_index].u.adj_sid.adj_sid)
static node_t *
tilfa_get_adj_sid_to_node(
gen_segment_list_t *gen_segment_list,
int stack_index,
boolean inet3, boolean mpls0){
if(inet3){
if(gen_segment_list->inet3_mpls_label_out[stack_index].seg_type == TILFA_ADJ_SID ||
gen_segment_list->inet3_mpls_label_out[stack_index].seg_type == RSVP_LSP_LABEL)
return gen_segment_list->inet3_mpls_label_out[stack_index].u.adj_sid.to_node;
}
else if(mpls0){
if(gen_segment_list->mpls0_mpls_label_out[stack_index].seg_type == TILFA_ADJ_SID ||
gen_segment_list->mpls0_mpls_label_out[stack_index].seg_type == RSVP_LSP_LABEL)
return gen_segment_list->mpls0_mpls_label_out[stack_index].u.adj_sid.to_node;
}
assert(0);
return NULL;
}
char *
tilfa_print_one_liner_segment_list(
gen_segment_list_t *gen_segment_list,
boolean inet3, boolean mpls0);
static inline boolean
tilfa_is_gensegment_lst_empty_inet3(
gen_segment_list_t *gen_segment_list){
if(gen_segment_list->inet3_stack_op[0] == STACK_OPS_UNKNOWN)
return TRUE;
return FALSE;
}
static inline boolean
tilfa_is_gensegment_lst_empty_mpls0(
gen_segment_list_t *gen_segment_list){
if(gen_segment_list->mpls0_stack_op[0] == STACK_OPS_UNKNOWN)
return TRUE;
return FALSE;
}
typedef struct segment_list_{
interface_t *oif;
char gw_ip[PREFIX_LEN + 1];
mpls_label_t mpls_label_out[MPLS_STACK_OP_LIMIT_MAX];
MPLS_STACK_OP stack_op[MPLS_STACK_OP_LIMIT_MAX];
} segment_list_t;
typedef struct protected_resource_{
node_t *plr_node;
interface_t *protected_link;
boolean link_protection;
boolean node_protection;
int ref_count;
} protected_resource_t;
static inline void tilfa_unlock_protected_resource(
protected_resource_t *pr_res){
pr_res->ref_count--;
assert(pr_res->ref_count >= 0);
if(!pr_res->ref_count)
XFREE(pr_res);
}
static inline void tilfa_lock_protected_resource(
protected_resource_t *pr_res){
pr_res->ref_count++;
}
static inline boolean
tlfa_protected_resource_equal(protected_resource_t *pr_res1,
protected_resource_t *pr_res2){
if(pr_res1 == pr_res2) return TRUE;
if(pr_res1->plr_node == pr_res2->plr_node &&
pr_res1->protected_link == pr_res2->protected_link &&
pr_res1->link_protection == pr_res2->link_protection &&
pr_res1->node_protection == pr_res2->node_protection){
return TRUE;
}
return FALSE;
}
typedef struct tilfa_segment_list_{
node_t *dest;
protected_resource_t *pr_res;
uint8_t n_segment_list;
gen_segment_list_t gen_segment_list[MAX_NXT_HOPS];
glthread_t gen_segment_list_glue;
} tilfa_segment_list_t;
GLTHREAD_TO_STRUCT(tilfa_segment_list_to_gensegment_list,
tilfa_segment_list_t, gen_segment_list_glue);
typedef struct tilfa_lcl_config_{
char protected_link[IF_NAME_SIZE]; /*key*/
boolean link_protection;
boolean node_protection;
glthread_t config_glue;
} tilfa_lcl_config_t;
GLTHREAD_TO_STRUCT(tilfa_lcl_config_to_config_glue,
tilfa_lcl_config_t, config_glue);
typedef struct tilfa_cfg_globals_{
boolean is_enabled;
uint8_t max_segments_allowed;
} tilfa_cfg_globals_t;
typedef struct tilfa_remote_spf_result_{
node_t *node; /*root of rev spf result*/
ll_t *rem_spf_result_lst;
} tilfa_remote_spf_result_t;
typedef struct tilfa_info_ {
tilfa_cfg_globals_t tilfa_gl_var;
glthread_t tilfa_lcl_config_head;
protected_resource_t *current_resource_pruned;
ll_t *tilfa_pre_convergence_spf_results[MAX_LEVEL];
/* SPF results after pruning of reources*/
ll_t *tilfa_post_convergence_spf_results[MAX_LEVEL];
/*SPF Results of FORWARD run without Pruning of Resources*/
glthread_t post_convergence_spf_path[MAX_LEVEL];
/* SPF Results triggered on a remote node.
* Required for PQ node evaluation*/
ll_t *pre_convergence_remote_forward_spf_results[MAX_LEVEL];
ll_t *pre_convergence_remote_reverse_spf_results[MAX_LEVEL];
glthread_t tilfa_segment_list_head[MAX_LEVEL];
boolean is_tilfa_pruned;
} tilfa_info_t;
gen_segment_list_t *
tilfa_get_segment_list(node_t *node,
protected_resource_t *pr_res,
node_t *dst_node,
LEVEL level,
uint8_t *n_segment_list/*O/P*/);
void
init_tilfa(node_t *node);
boolean
tilfa_update_config(node_t *plr_node,
char *protected_link,
boolean link_protection,
boolean node_protection);
boolean
tilfa_topology_prune_protected_resource(node_t *node,
protected_resource_t *pr_res);
void
tilfa_topology_unprune_protected_resource(node_t *node,
protected_resource_t *pr_res);
void
tilfa_run_post_convergence_spf(node_t *spf_root, LEVEL level,
protected_resource_t *pr_res);
spf_path_result_t *
tilfa_lookup_spf_path_result(node_t *node, node_t *candidate_node,
LEVEL level);
void
compute_tilfa(node_t *spf_root, LEVEL level);
void
tilfa_clear_preconvergence_remote_spf_results(tilfa_info_t *tilfa_info,
node_t *node, LEVEL level,
boolean reverse_spf);
spf_path_result_t *
TILFA_GET_SPF_PATH_RESULT(node_t *spf_root, node_t *node, LEVEL level);
int
tilfa_copy_gensegment_list_stacks(gen_segment_list_t *src,
gen_segment_list_t *dst,
boolean inet3,
boolean mpls0,
int src_stack_index,
int dst_stack_index);
boolean
tilfa_fill_nxthop_from_segment_lst(routes_t *route,
internal_nh_t *nxthop,
gen_segment_list_t *gensegment_lst,
protected_resource_t *pr_res,
boolean inet3,
boolean mpls0);
#endif /* __TILFA__ */