Skip to content

Commit

Permalink
Prevented the conflicting of Firsthop segments on TILFA paths.
Browse files Browse the repository at this point in the history
Topo used : tilfa_topo_p_q_distance_1
config :
conf node R0 no int eth0/0 en
conf node /
R0 rsvp
R4 rsvp
R3 rsvp
cd
run ins sync
conf node R0 rsvp tunnel 122.1.1.4 R0-R3
conf node R3 rsvp tunnel 122.1.1.1 R0-R3
conf node R0 lsp R0-R3 me 20 to 122.1.1.4 le 1
conf node R3 lsp R0-R3 me 20 to 122.1.1.1 le 1
conf node R0 int eth0/0 en
conf node R0 int eth0/0 li
show s r l 1
deb show in node R0 tilfa

expected output :
tilfa IP nexthop segments backup over interface eth0/1 shall be dropped
over RSVP FAs over physical interface eth0/1
  • Loading branch information
sachinites committed Jan 7, 2020
1 parent 7a3fdcd commit c67918f
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 21 deletions.
4 changes: 2 additions & 2 deletions testapp.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,15 @@ main(int argc, char **argv){
//instance = build_cisco_example_topo();
//instance = broadcast_link_protecting_lfa();
//instance = build_multi_link_topo();
instance = lsp_as_backup_topo();
//instance = lsp_as_backup_topo();
//instance = build_rlfa_topo();
//instance = build_lfa_topo();
//instance = overload_router_topo();
//instance = multi_primary_nxt_hops();
//instance = one_hop_backup();
//instance = tilfa_topo_parallel_links();
//instance = tilfa_topo_one_hop_test();
//instance = tilfa_topo_p_q_distance_1();
instance = tilfa_topo_p_q_distance_1();
//instance = tilfa_topo_page_408_node_protection();
//instance = tilfa_topo_2_adj_segment_example();
start_shell();
Expand Down
188 changes: 171 additions & 17 deletions tilfa.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,7 @@ tilfa_is_node_pruned(node_t *node){
return node->tilfa_info->is_tilfa_pruned;
}

/*Code Duplicacy detected !!*/
static boolean
tilfa_does_nexthop_overlap(internal_nh_t *one_nh,
internal_nh_t *nh_lst){
Expand Down Expand Up @@ -775,6 +776,52 @@ tilfa_does_nexthop_overlap(internal_nh_t *one_nh,
return FALSE;
}

static boolean
tilfa_does_nexthop_overlap2(internal_nh_t *one_nh,
internal_nh_t **nh_lst){

int i = 0;

for(; i < MAX_NXT_HOPS; i++){

if(!nh_lst[i]) return FALSE;

switch(nh_lst[i]->nh_type){
case UNICAST:
switch(one_nh->nh_type){
case UNICAST:
if(one_nh->oif == nh_lst[i]->oif)
return TRUE;
break;
case LSP:
if(one_nh->oif == nh_lst[i]->oif)
return TRUE;
break;
default:
;
}
break;
case LSP:
switch(one_nh->nh_type){
case UNICAST:
if(one_nh->oif == nh_lst[i]->oif)
return TRUE;
break;
case LSP:
if(one_nh->oif == nh_lst[i]->oif)
return TRUE;
break;
default:
;
}
break;
default:
;
}
}
return FALSE;
}

static int
tilfa_compute_first_hop_segments(node_t *spf_root,
node_t *first_hop_node,
Expand All @@ -788,13 +835,15 @@ tilfa_compute_first_hop_segments(node_t *spf_root,
internal_nh_t *first_hop_segment_array = NULL;

tilfa_info_t *tilfa_info = spf_root->tilfa_info;
nh_type_t nh;
nh_type_t nh = LSPNH;

memset(first_hop_segments, 0,
sizeof(internal_nh_t *) * MAX_NXT_HOPS);

ITERATE_NH_TYPE_BEGIN(nh){

/* First collect RSVP LSP NHs, followed
* by IPNH. This is done to reject IPNHs over
* RSVP LSP NHs in case of conflicts*/
do{
first_hop_segment_array =
tilfa_lookup_post_convergence_primary_nexthops(tilfa_info,
first_hop_node, level, nh);
Expand All @@ -812,10 +861,19 @@ tilfa_compute_first_hop_segments(node_t *spf_root,
if(tilfa_does_nexthop_overlap(first_hop_segment,
dst_pre_convergence_nhps))
continue;
/* Weed out conflicting nexthops. For example,
* Two RSVP LSPs can go out of same physical interface
* Or RSVP LSP oif can coincide with IPNH*/
if(tilfa_does_nexthop_overlap2(first_hop_segment,
first_hop_segments)) /*This needs to be addressed, incompatible arg passed*/
continue;
first_hop_segments[n++] = first_hop_segment;
if(n == MAX_NXT_HOPS) return n;
}
} ITERATE_NH_TYPE_END;
if(nh == LSPNH)
nh = IPNH;
else break;
}while(1);
return n;
}

Expand Down Expand Up @@ -1065,6 +1123,7 @@ TILFA_GENSEGLST_FILL_OIF_GATEWAY_FROM_NXTHOP(
else
gen_segment_list->mpls0_stack_op[*stack_top] = PUSH;
(*stack_top)++;
gen_segment_list->is_fhs_rsvp_lsp = TRUE;
}
return TRUE;
}
Expand Down Expand Up @@ -1136,8 +1195,8 @@ tilfa_compute_segment_list_connecting_p_q_nodes


int stack_top = 0;
boolean is_pq_prefix_sid_connected = FALSE;
uint32_t adj_sid = 0;
boolean is_pq_prefix_sid_connected = FALSE;

glthread_t *p_node_thread_temp = p_node_thread;
glthread_t *q_node_thread_temp = q_node_thread;
Expand Down Expand Up @@ -1286,13 +1345,10 @@ tilfa_compute_segment_list_from_tilfa_raw_results
gensegment_list[i].inet3_mpls_label_out[stack_top].seg_type = TILFA_PREFIX_SID_REFERENCE;
gensegment_list[i].inet3_mpls_label_out[stack_top].u.node = dest;
gensegment_list[i].inet3_stack_op[stack_top] = PUSH;
#if 0
/*mpls.0*/
/*Swap the dest node only*/
gensegment_list[i].mpls0_mpls_label_out[stack_top].seg_type = TILFA_PREFIX_SID_REFERENCE;
gensegment_list[i].mpls0_mpls_label_out[stack_top].u.node = dest;
gensegment_list[i].mpls0_stack_op[stack_top] = SWAP;
#endif
/*No need to push anything else in mpls0 stack*/
gensegment_list[i].mpls0_stack_op[stack_top] = STACK_OPS_UNKNOWN;
i++;
}
}
Expand Down Expand Up @@ -1495,14 +1551,116 @@ tilfa_compute_segment_list_from_tilfa_raw_results
return i;
}

static boolean
tilfa_is_fhs_overlap(
tilfa_segment_list_t *tilfa_segment_list,
int count,
gen_segment_list_t *gen_segment_list){

int i;

for(i = 0; i < count; i++){

if(gen_segment_list->oif ==
tilfa_segment_list->gen_segment_list[i].oif)
return TRUE;
}
return FALSE;;
}

static void
tilfa_merge_tilfa_segment_lists_by_destination(
tilfa_segment_list_t *src,
tilfa_segment_list_t *dst){

tilfa_segment_list_t temp;
memset(&temp, 0, sizeof(tilfa_segment_list_t));

int i = 0,
j = 0;

tilfa_segment_list_t *array[] = {src, dst};

int k = 0;
/*copy all RSVP LSP FHS to temp*/
for( ; k < 2; k++){
for( i = 0; i < array[k]->n_segment_list; i++){

if(!array[k]->gen_segment_list[i].is_fhs_rsvp_lsp)
continue;

if( k == 1){
if(tilfa_is_fhs_overlap(&temp, j,
&array[k]->gen_segment_list[i]))
continue;
}
memcpy(&temp.gen_segment_list[j], &array[k]->gen_segment_list[i],
sizeof(gen_segment_list_t));
j++;

if(j == MAX_NXT_HOPS){
memcpy(array[k]->gen_segment_list, temp.gen_segment_list,
sizeof(temp.gen_segment_list));
array[k]->n_segment_list = MAX_NXT_HOPS;
return;
}
}
}

/*Now copy IPNH from src and dst*/
for( k = 0; k < 2; k++){
for( i = 0; i < array[k]->n_segment_list; i++){

if(array[k]->gen_segment_list[i].is_fhs_rsvp_lsp)
continue;

if(tilfa_is_fhs_overlap(&temp, j,
&array[k]->gen_segment_list[i]))
continue;

memcpy(&temp.gen_segment_list[j], &array[k]->gen_segment_list[i],
sizeof(gen_segment_list_t));
j++;

if(j == MAX_NXT_HOPS){
memcpy(array[k]->gen_segment_list, temp.gen_segment_list,
sizeof(temp.gen_segment_list));
array[k]->n_segment_list = MAX_NXT_HOPS;
return;
}
}
}
memcpy(src->gen_segment_list, temp.gen_segment_list,
sizeof(temp.gen_segment_list));
src->n_segment_list = j;
}

static void
tilfa_record_segment_list(node_t *spf_root,
LEVEL level,
node_t *dst_node,
tilfa_segment_list_t *tilfa_segment_list){

glthread_t *curr;
tilfa_segment_list->dest = dst_node;
tilfa_segment_list_t *tilfa_segment_list_ptr = NULL;

init_glthread(&tilfa_segment_list->gen_segment_list_glue);

ITERATE_GLTHREAD_BEGIN(&spf_root->tilfa_info->tilfa_segment_list_head[level], curr){

tilfa_segment_list_ptr = tilfa_segment_list_to_gensegment_list(curr);

if(tilfa_segment_list_ptr->dest != dst_node) continue;

tilfa_merge_tilfa_segment_lists_by_destination(
tilfa_segment_list_ptr,
tilfa_segment_list);
free(tilfa_segment_list);

return;
} ITERATE_GLTHREAD_END(&spf_root->tilfa_info->tilfa_segment_list_head[level], curr);

glthread_add_next(&spf_root->tilfa_info->tilfa_segment_list_head[level],
&tilfa_segment_list->gen_segment_list_glue);
}
Expand Down Expand Up @@ -2136,17 +2294,13 @@ route_fetch_tilfa_backups(node_t *spf_root,

for( i = 0; i < tilfa_segment_list->n_segment_list; i++){

tilfa_bck_up = calloc(1, sizeof(internal_nh_t));

if(tilfa_fill_nxthop_from_segment_lst(route, tilfa_bck_up,
&tilfa_segment_list->gen_segment_list[i],
tilfa_segment_list->pr_res, inet3, mpls0)){


tilfa_bck_up = calloc(1, sizeof(internal_nh_t));
ROUTE_ADD_NH(route->backup_nh_list[LSPNH], tilfa_bck_up);
}
else{
free(tilfa_bck_up);
}
}
} ITERATE_GLTHREAD_END(tilfa_segment_list, curr);
}ITERATE_LIST_END;
Expand Down
2 changes: 1 addition & 1 deletion tilfa.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ typedef struct gen_segment_list_{

struct s_t mpls0_mpls_label_out[MPLS_STACK_OP_LIMIT_MAX];
MPLS_STACK_OP mpls0_stack_op[MPLS_STACK_OP_LIMIT_MAX];

boolean is_fhs_rsvp_lsp;
} gen_segment_list_t;

char *
Expand Down
1 change: 0 additions & 1 deletion topo.c
Original file line number Diff line number Diff line change
Expand Up @@ -1287,7 +1287,6 @@ tilfa_topo_p_q_distance_1(){
| |eth0/2 60.1.1.1/24 eth0/3 .2/24| |
| +------------------------------------+ |
+---------------+ +----------+
*/

instance_t *instance = get_new_instance();
Expand Down

0 comments on commit c67918f

Please sign in to comment.