@@ -72,9 +72,9 @@ static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc)
72
72
if (LIST_EMPTY (& (bnc -> paths )) && !bnc -> nht_info ) {
73
73
if (BGP_DEBUG (nht , NHT )) {
74
74
char buf [PREFIX2STR_BUFFER ];
75
- zlog_debug ("bgp_unlink_nexthop: freeing bnc %s(%s)" ,
75
+ zlog_debug ("bgp_unlink_nexthop: freeing bnc %s(%u)(% s)" ,
76
76
bnc_str (bnc , buf , PREFIX2STR_BUFFER ),
77
- bnc -> bgp -> name_pretty );
77
+ bnc -> srte_color , bnc -> bgp -> name_pretty );
78
78
}
79
79
unregister_zebra_rnh (bnc ,
80
80
CHECK_FLAG (bnc -> flags , BGP_STATIC_ROUTE ));
@@ -103,7 +103,7 @@ void bgp_unlink_nexthop_by_peer(struct peer *peer)
103
103
if (!sockunion2hostprefix (& peer -> su , & p ))
104
104
return ;
105
105
106
- bnc = bnc_find (& peer -> bgp -> nexthop_cache_table [afi ], & p );
106
+ bnc = bnc_find (& peer -> bgp -> nexthop_cache_table [afi ], & p , 0 );
107
107
if (!bnc )
108
108
return ;
109
109
@@ -124,6 +124,7 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
124
124
struct bgp_nexthop_cache_head * tree = NULL ;
125
125
struct bgp_nexthop_cache * bnc ;
126
126
struct prefix p ;
127
+ uint32_t srte_color = 0 ;
127
128
int is_bgp_static_route = 0 ;
128
129
129
130
if (pi ) {
@@ -148,6 +149,8 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
148
149
* addr */
149
150
if (make_prefix (afi , pi , & p ) < 0 )
150
151
return 1 ;
152
+
153
+ srte_color = pi -> attr -> srte_color ;
151
154
} else if (peer ) {
152
155
if (!sockunion2hostprefix (& peer -> su , & p )) {
153
156
if (BGP_DEBUG (nht , NHT )) {
@@ -165,16 +168,17 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
165
168
else
166
169
tree = & bgp_nexthop -> nexthop_cache_table [afi ];
167
170
168
- bnc = bnc_find (tree , & p );
171
+ bnc = bnc_find (tree , & p , srte_color );
169
172
if (!bnc ) {
170
- bnc = bnc_new (tree , & p );
173
+ bnc = bnc_new (tree , & p , srte_color );
171
174
bnc -> bgp = bgp_nexthop ;
172
175
if (BGP_DEBUG (nht , NHT )) {
173
176
char buf [PREFIX2STR_BUFFER ];
174
177
175
- zlog_debug ("Allocated bnc %s(%s) peer %p" ,
178
+ zlog_debug ("Allocated bnc %s(%u)(% s) peer %p" ,
176
179
bnc_str (bnc , buf , PREFIX2STR_BUFFER ),
177
- bnc -> bgp -> name_pretty , peer );
180
+ bnc -> srte_color , bnc -> bgp -> name_pretty ,
181
+ peer );
178
182
}
179
183
}
180
184
@@ -266,7 +270,7 @@ void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer)
266
270
return ;
267
271
268
272
bnc = bnc_find (& peer -> bgp -> nexthop_cache_table [family2afi (p .family )],
269
- & p );
273
+ & p , 0 );
270
274
if (!bnc ) {
271
275
if (BGP_DEBUG (nht , NHT ))
272
276
zlog_debug (
@@ -296,89 +300,52 @@ void bgp_delete_connected_nexthop(afi_t afi, struct peer *peer)
296
300
}
297
301
}
298
302
299
- void bgp_parse_nexthop_update (int command , vrf_id_t vrf_id )
303
+ static void bgp_process_nexthop_update (struct bgp_nexthop_cache * bnc ,
304
+ struct zapi_route * nhr )
300
305
{
301
- struct bgp_nexthop_cache_head * tree = NULL ;
302
- struct bgp_nexthop_cache * bnc ;
303
306
struct nexthop * nexthop ;
304
307
struct nexthop * oldnh ;
305
308
struct nexthop * nhlist_head = NULL ;
306
309
struct nexthop * nhlist_tail = NULL ;
307
310
int i ;
308
- struct bgp * bgp ;
309
- struct zapi_route nhr ;
310
-
311
- bgp = bgp_lookup_by_vrf_id (vrf_id );
312
- if (!bgp ) {
313
- flog_err (
314
- EC_BGP_NH_UPD ,
315
- "parse nexthop update: instance not found for vrf_id %u" ,
316
- vrf_id );
317
- return ;
318
- }
319
-
320
- if (!zapi_nexthop_update_decode (zclient -> ibuf , & nhr )) {
321
- if (BGP_DEBUG (nht , NHT ))
322
- zlog_debug ("%s[%s]: Failure to decode nexthop update" ,
323
- __func__ , bgp -> name_pretty );
324
- return ;
325
- }
326
-
327
- if (command == ZEBRA_NEXTHOP_UPDATE )
328
- tree = & bgp -> nexthop_cache_table [family2afi (nhr .prefix .family )];
329
- else if (command == ZEBRA_IMPORT_CHECK_UPDATE )
330
- tree = & bgp -> import_check_table [family2afi (nhr .prefix .family )];
331
-
332
- bnc = bnc_find (tree , & nhr .prefix );
333
- if (!bnc ) {
334
- if (BGP_DEBUG (nht , NHT )) {
335
- char buf [PREFIX2STR_BUFFER ];
336
-
337
- prefix2str (& nhr .prefix , buf , sizeof (buf ));
338
- zlog_debug (
339
- "parse nexthop update(%s(%s)): bnc info not found" ,
340
- buf , bgp -> name_pretty );
341
- }
342
- return ;
343
- }
344
311
345
312
bnc -> last_update = bgp_clock ();
346
313
bnc -> change_flags = 0 ;
347
314
348
315
/* debug print the input */
349
316
if (BGP_DEBUG (nht , NHT )) {
350
317
char buf [PREFIX2STR_BUFFER ];
351
- prefix2str (& nhr . prefix , buf , sizeof (buf ));
318
+ prefix2str (& nhr -> prefix , buf , sizeof (buf ));
352
319
zlog_debug (
353
- "%s(%u): Rcvd NH update %s - metric %d/%d #nhops %d/%d flags 0x%x" ,
354
- bnc -> bgp -> name_pretty , vrf_id , buf , nhr . metric ,
355
- bnc -> metric , nhr . nexthop_num , bnc -> nexthop_num ,
356
- bnc -> flags );
320
+ "%s(%u): Rcvd NH update %s(%u) - metric %d/%d #nhops %d/%d flags 0x%x" ,
321
+ bnc -> bgp -> name_pretty , bnc -> bgp -> vrf_id , buf ,
322
+ bnc -> srte_color , nhr -> metric , bnc -> metric ,
323
+ nhr -> nexthop_num , bnc -> nexthop_num , bnc -> flags );
357
324
}
358
325
359
- if (nhr . metric != bnc -> metric )
326
+ if (nhr -> metric != bnc -> metric )
360
327
bnc -> change_flags |= BGP_NEXTHOP_METRIC_CHANGED ;
361
328
362
- if (nhr . nexthop_num != bnc -> nexthop_num )
329
+ if (nhr -> nexthop_num != bnc -> nexthop_num )
363
330
bnc -> change_flags |= BGP_NEXTHOP_CHANGED ;
364
331
365
- if (nhr . nexthop_num ) {
332
+ if (nhr -> nexthop_num ) {
366
333
struct peer * peer = bnc -> nht_info ;
367
334
368
335
/* notify bgp fsm if nbr ip goes from invalid->valid */
369
336
if (!bnc -> nexthop_num )
370
337
UNSET_FLAG (bnc -> flags , BGP_NEXTHOP_PEER_NOTIFIED );
371
338
372
339
bnc -> flags |= BGP_NEXTHOP_VALID ;
373
- bnc -> metric = nhr . metric ;
374
- bnc -> nexthop_num = nhr . nexthop_num ;
340
+ bnc -> metric = nhr -> metric ;
341
+ bnc -> nexthop_num = nhr -> nexthop_num ;
375
342
376
343
bnc -> flags &= ~BGP_NEXTHOP_LABELED_VALID ; /* check below */
377
344
378
- for (i = 0 ; i < nhr . nexthop_num ; i ++ ) {
345
+ for (i = 0 ; i < nhr -> nexthop_num ; i ++ ) {
379
346
int num_labels = 0 ;
380
347
381
- nexthop = nexthop_from_zapi_nexthop (& nhr . nexthops [i ]);
348
+ nexthop = nexthop_from_zapi_nexthop (& nhr -> nexthops [i ]);
382
349
383
350
/*
384
351
* Turn on RA for the v6 nexthops
@@ -388,7 +355,7 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
388
355
if (peer && !peer -> ifp
389
356
&& CHECK_FLAG (peer -> flags ,
390
357
PEER_FLAG_CAPABILITY_ENHE )
391
- && nhr . prefix .family == AF_INET6
358
+ && nhr -> prefix .family == AF_INET6
392
359
&& nexthop -> type != NEXTHOP_TYPE_BLACKHOLE ) {
393
360
struct interface * ifp ;
394
361
@@ -442,7 +409,7 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
442
409
bnc -> nexthop = nhlist_head ;
443
410
} else {
444
411
bnc -> flags &= ~BGP_NEXTHOP_VALID ;
445
- bnc -> nexthop_num = nhr . nexthop_num ;
412
+ bnc -> nexthop_num = nhr -> nexthop_num ;
446
413
447
414
/* notify bgp fsm if nbr ip goes from valid->invalid */
448
415
UNSET_FLAG (bnc -> flags , BGP_NEXTHOP_PEER_NOTIFIED );
@@ -454,6 +421,77 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
454
421
evaluate_paths (bnc );
455
422
}
456
423
424
+ void bgp_parse_nexthop_update (int command , vrf_id_t vrf_id )
425
+ {
426
+ struct bgp_nexthop_cache_head * tree = NULL ;
427
+ struct bgp_nexthop_cache * bnc ;
428
+ struct bgp * bgp ;
429
+ struct zapi_route nhr ;
430
+ afi_t afi ;
431
+
432
+ bgp = bgp_lookup_by_vrf_id (vrf_id );
433
+ if (!bgp ) {
434
+ flog_err (
435
+ EC_BGP_NH_UPD ,
436
+ "parse nexthop update: instance not found for vrf_id %u" ,
437
+ vrf_id );
438
+ return ;
439
+ }
440
+
441
+ if (!zapi_nexthop_update_decode (zclient -> ibuf , & nhr )) {
442
+ if (BGP_DEBUG (nht , NHT ))
443
+ zlog_debug ("%s[%s]: Failure to decode nexthop update" ,
444
+ __PRETTY_FUNCTION__ , bgp -> name_pretty );
445
+ return ;
446
+ }
447
+
448
+ afi = family2afi (nhr .prefix .family );
449
+ if (command == ZEBRA_NEXTHOP_UPDATE )
450
+ tree = & bgp -> nexthop_cache_table [afi ];
451
+ else if (command == ZEBRA_IMPORT_CHECK_UPDATE )
452
+ tree = & bgp -> import_check_table [afi ];
453
+
454
+ bnc = bnc_find (tree , & nhr .prefix , nhr .srte_color );
455
+ if (!bnc ) {
456
+ if (BGP_DEBUG (nht , NHT )) {
457
+ char buf [PREFIX2STR_BUFFER ];
458
+
459
+ prefix2str (& nhr .prefix , buf , sizeof (buf ));
460
+ zlog_debug (
461
+ "parse nexthop update(%s(%u)(%s)): bnc info not found" ,
462
+ buf , nhr .srte_color , bgp -> name_pretty );
463
+ }
464
+ return ;
465
+ }
466
+
467
+ bgp_process_nexthop_update (bnc , & nhr );
468
+
469
+ /*
470
+ * HACK: if any BGP route is dependant on an SR-policy that doesn't
471
+ * exist, zebra will never send NH updates relative to that policy. In
472
+ * that case, whenever we receive an update about a colorless NH, update
473
+ * the corresponding colorful NHs that share the same endpoint but that
474
+ * are inactive. This ugly hack should work around the problem at the
475
+ * cost of a performance pernalty. Long term, what should be done is to
476
+ * make zebra's RNH subsystem aware of SR-TE colors (like bgpd is),
477
+ * which should provide a better infrastructure to solve this issue in
478
+ * a more efficient and elegant way.
479
+ */
480
+ if (nhr .srte_color == 0 ) {
481
+ struct bgp_nexthop_cache * bnc_iter ;
482
+
483
+ frr_each (bgp_nexthop_cache , & bgp -> nexthop_cache_table [afi ],
484
+ bnc_iter ) {
485
+ if (!prefix_same (& bnc -> prefix , & bnc_iter -> prefix )
486
+ || bnc_iter -> srte_color == 0
487
+ || CHECK_FLAG (bnc_iter -> flags , BGP_NEXTHOP_VALID ))
488
+ continue ;
489
+
490
+ bgp_process_nexthop_update (bnc_iter , & nhr );
491
+ }
492
+ }
493
+ }
494
+
457
495
/*
458
496
* Cleanup nexthop registration and status information for BGP nexthops
459
497
* pertaining to this VRF. This is invoked upon VRF deletion.
@@ -667,8 +705,8 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
667
705
char buf [PREFIX2STR_BUFFER ];
668
706
bnc_str (bnc , buf , PREFIX2STR_BUFFER );
669
707
zlog_debug (
670
- "NH update for %s %s flags 0x%x chgflags 0x%x - evaluate paths" ,
671
- buf , bnc -> bgp -> name_pretty , bnc -> flags ,
708
+ "NH update for %s(%u)(%s) - flags 0x%x chgflags 0x%x - evaluate paths" ,
709
+ buf , bnc -> srte_color , bnc -> bgp -> name_pretty , bnc -> flags ,
672
710
bnc -> change_flags );
673
711
}
674
712
@@ -756,7 +794,8 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
756
794
path -> extra -> igpmetric = 0 ;
757
795
758
796
if (CHECK_FLAG (bnc -> change_flags , BGP_NEXTHOP_METRIC_CHANGED )
759
- || CHECK_FLAG (bnc -> change_flags , BGP_NEXTHOP_CHANGED ))
797
+ || CHECK_FLAG (bnc -> change_flags , BGP_NEXTHOP_CHANGED )
798
+ || path -> attr -> srte_color != 0 )
760
799
SET_FLAG (path -> flags , BGP_PATH_IGP_CHANGED );
761
800
762
801
path_valid = !!CHECK_FLAG (path -> flags , BGP_PATH_VALID );
@@ -874,7 +913,7 @@ void bgp_nht_reg_enhe_cap_intfs(struct peer *peer)
874
913
if (p .family != AF_INET6 )
875
914
return ;
876
915
877
- bnc = bnc_find (& bgp -> nexthop_cache_table [AFI_IP6 ], & p );
916
+ bnc = bnc_find (& bgp -> nexthop_cache_table [AFI_IP6 ], & p , 0 );
878
917
if (!bnc )
879
918
return ;
880
919
@@ -916,7 +955,7 @@ void bgp_nht_dereg_enhe_cap_intfs(struct peer *peer)
916
955
if (p .family != AF_INET6 )
917
956
return ;
918
957
919
- bnc = bnc_find (& bgp -> nexthop_cache_table [AFI_IP6 ], & p );
958
+ bnc = bnc_find (& bgp -> nexthop_cache_table [AFI_IP6 ], & p , 0 );
920
959
if (!bnc )
921
960
return ;
922
961
0 commit comments