Skip to content

Commit fdf81fa

Browse files
committed
bgpd: Store reason why bestpath was choosen
Store in bgp_node the reason why we choose a particular best path over another. At this point we do not do anything other than just store this data when we make the decision. Future commits will display it. Signed-off-by: Donald Sharp <[email protected]>
1 parent f08b5ca commit fdf81fa

File tree

4 files changed

+87
-10
lines changed

4 files changed

+87
-10
lines changed

bgpd/bgp_route.c

+54-8
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,8 @@ void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf)
434434
static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
435435
struct bgp_path_info *exist, int *paths_eq,
436436
struct bgp_maxpaths_cfg *mpath_cfg, int debug,
437-
char *pfx_buf, afi_t afi, safi_t safi)
437+
char *pfx_buf, afi_t afi, safi_t safi,
438+
enum bgp_path_selection_reason *reason)
438439
{
439440
struct attr *newattr, *existattr;
440441
bgp_peer_sort_t new_sort;
@@ -463,6 +464,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
463464

464465
/* 0. Null check. */
465466
if (new == NULL) {
467+
*reason = bgp_path_selection_none;
466468
if (debug)
467469
zlog_debug("%s: new is NULL", pfx_buf);
468470
return 0;
@@ -472,6 +474,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
472474
bgp_path_info_path_with_addpath_rx_str(new, new_buf);
473475

474476
if (exist == NULL) {
477+
*reason = bgp_path_selection_first;
475478
if (debug)
476479
zlog_debug("%s: %s is the initial bestpath", pfx_buf,
477480
new_buf);
@@ -514,6 +517,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
514517
}
515518

516519
if (newattr->sticky && !existattr->sticky) {
520+
*reason = bgp_path_selection_evpn_sticky_mac;
517521
if (debug)
518522
zlog_debug(
519523
"%s: %s wins over %s due to sticky MAC flag",
@@ -522,6 +526,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
522526
}
523527

524528
if (!newattr->sticky && existattr->sticky) {
529+
*reason = bgp_path_selection_evpn_sticky_mac;
525530
if (debug)
526531
zlog_debug(
527532
"%s: %s loses to %s due to sticky MAC flag",
@@ -534,6 +539,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
534539
exist_mm_seq = mac_mobility_seqnum(existattr);
535540

536541
if (new_mm_seq > exist_mm_seq) {
542+
*reason = bgp_path_selection_evpn_seq;
537543
if (debug)
538544
zlog_debug(
539545
"%s: %s wins over %s due to MM seq %u > %u",
@@ -543,6 +549,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
543549
}
544550

545551
if (new_mm_seq < exist_mm_seq) {
552+
*reason = bgp_path_selection_evpn_seq;
546553
if (debug)
547554
zlog_debug(
548555
"%s: %s loses to %s due to MM seq %u < %u",
@@ -557,6 +564,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
557564
*/
558565
nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
559566
if (nh_cmp < 0) {
567+
*reason = bgp_path_selection_evpn_lower_ip;
560568
if (debug)
561569
zlog_debug(
562570
"%s: %s wins over %s due to same MM seq %u and lower IP %s",
@@ -565,6 +573,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
565573
return 1;
566574
}
567575
if (nh_cmp > 0) {
576+
*reason = bgp_path_selection_evpn_lower_ip;
568577
if (debug)
569578
zlog_debug(
570579
"%s: %s loses to %s due to same MM seq %u and higher IP %s",
@@ -579,6 +588,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
579588
exist_weight = existattr->weight;
580589

581590
if (new_weight > exist_weight) {
591+
*reason = bgp_path_selection_weight;
582592
if (debug)
583593
zlog_debug("%s: %s wins over %s due to weight %d > %d",
584594
pfx_buf, new_buf, exist_buf, new_weight,
@@ -587,6 +597,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
587597
}
588598

589599
if (new_weight < exist_weight) {
600+
*reason = bgp_path_selection_weight;
590601
if (debug)
591602
zlog_debug("%s: %s loses to %s due to weight %d < %d",
592603
pfx_buf, new_buf, exist_buf, new_weight,
@@ -603,6 +614,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
603614
exist_pref = existattr->local_pref;
604615

605616
if (new_pref > exist_pref) {
617+
*reason = bgp_path_selection_local_pref;
606618
if (debug)
607619
zlog_debug(
608620
"%s: %s wins over %s due to localpref %d > %d",
@@ -612,6 +624,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
612624
}
613625

614626
if (new_pref < exist_pref) {
627+
*reason = bgp_path_selection_local_pref;
615628
if (debug)
616629
zlog_debug(
617630
"%s: %s loses to %s due to localpref %d < %d",
@@ -627,6 +640,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
627640
*/
628641
if (!(new->sub_type == BGP_ROUTE_NORMAL ||
629642
new->sub_type == BGP_ROUTE_IMPORTED)) {
643+
*reason = bgp_path_selection_local_route;
630644
if (debug)
631645
zlog_debug(
632646
"%s: %s wins over %s due to preferred BGP_ROUTE type",
@@ -636,6 +650,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
636650

637651
if (!(exist->sub_type == BGP_ROUTE_NORMAL ||
638652
exist->sub_type == BGP_ROUTE_IMPORTED)) {
653+
*reason = bgp_path_selection_local_route;
639654
if (debug)
640655
zlog_debug(
641656
"%s: %s loses to %s due to preferred BGP_ROUTE type",
@@ -655,6 +670,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
655670
aspath_hops += aspath_count_confeds(newattr->aspath);
656671

657672
if (aspath_hops < (exist_hops + exist_confeds)) {
673+
*reason = bgp_path_selection_confed_as_path;
658674
if (debug)
659675
zlog_debug(
660676
"%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
@@ -665,6 +681,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
665681
}
666682

667683
if (aspath_hops > (exist_hops + exist_confeds)) {
684+
*reason = bgp_path_selection_confed_as_path;
668685
if (debug)
669686
zlog_debug(
670687
"%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
@@ -677,6 +694,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
677694
int newhops = aspath_count_hops(newattr->aspath);
678695

679696
if (newhops < exist_hops) {
697+
*reason = bgp_path_selection_as_path;
680698
if (debug)
681699
zlog_debug(
682700
"%s: %s wins over %s due to aspath hopcount %d < %d",
@@ -686,6 +704,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
686704
}
687705

688706
if (newhops > exist_hops) {
707+
*reason = bgp_path_selection_as_path;
689708
if (debug)
690709
zlog_debug(
691710
"%s: %s loses to %s due to aspath hopcount %d > %d",
@@ -698,6 +717,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
698717

699718
/* 5. Origin check. */
700719
if (newattr->origin < existattr->origin) {
720+
*reason = bgp_path_selection_origin;
701721
if (debug)
702722
zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
703723
pfx_buf, new_buf, exist_buf,
@@ -707,6 +727,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
707727
}
708728

709729
if (newattr->origin > existattr->origin) {
730+
*reason = bgp_path_selection_origin;
710731
if (debug)
711732
zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
712733
pfx_buf, new_buf, exist_buf,
@@ -732,6 +753,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
732753
exist_med = bgp_med_value(exist->attr, bgp);
733754

734755
if (new_med < exist_med) {
756+
*reason = bgp_path_selection_med;
735757
if (debug)
736758
zlog_debug(
737759
"%s: %s wins over %s due to MED %d < %d",
@@ -741,6 +763,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
741763
}
742764

743765
if (new_med > exist_med) {
766+
*reason = bgp_path_selection_med;
744767
if (debug)
745768
zlog_debug(
746769
"%s: %s loses to %s due to MED %d > %d",
@@ -756,6 +779,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
756779

757780
if (new_sort == BGP_PEER_EBGP
758781
&& (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
782+
*reason = bgp_path_selection_peer;
759783
if (debug)
760784
zlog_debug(
761785
"%s: %s wins over %s due to eBGP peer > iBGP peer",
@@ -765,6 +789,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
765789

766790
if (exist_sort == BGP_PEER_EBGP
767791
&& (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
792+
*reason = bgp_path_selection_peer;
768793
if (debug)
769794
zlog_debug(
770795
"%s: %s loses to %s due to iBGP peer < eBGP peer",
@@ -834,6 +859,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
834859
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
835860
if (new_sort == BGP_PEER_CONFED
836861
&& exist_sort == BGP_PEER_IBGP) {
862+
*reason = bgp_path_selection_confed;
837863
if (debug)
838864
zlog_debug(
839865
"%s: %s wins over %s due to confed-external peer > confed-internal peer",
@@ -843,6 +869,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
843869

844870
if (exist_sort == BGP_PEER_CONFED
845871
&& new_sort == BGP_PEER_IBGP) {
872+
*reason = bgp_path_selection_confed;
846873
if (debug)
847874
zlog_debug(
848875
"%s: %s loses to %s due to confed-internal peer < confed-external peer",
@@ -918,6 +945,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
918945
"%s: %s loses to %s after IGP metric comparison",
919946
pfx_buf, new_buf, exist_buf);
920947
}
948+
*reason = bgp_path_selection_igp_metric;
921949
return ret;
922950
}
923951

@@ -928,6 +956,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
928956
if (!bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID)
929957
&& new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
930958
if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
959+
*reason = bgp_path_selection_older;
931960
if (debug)
932961
zlog_debug(
933962
"%s: %s wins over %s due to oldest external",
@@ -936,6 +965,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
936965
}
937966

938967
if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
968+
*reason = bgp_path_selection_older;
939969
if (debug)
940970
zlog_debug(
941971
"%s: %s loses to %s due to oldest external",
@@ -959,6 +989,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
959989
exist_id.s_addr = exist->peer->remote_id.s_addr;
960990

961991
if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
992+
*reason = bgp_path_selection_router_id;
962993
if (debug)
963994
zlog_debug(
964995
"%s: %s wins over %s due to Router-ID comparison",
@@ -967,6 +998,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
967998
}
968999

9691000
if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1001+
*reason = bgp_path_selection_router_id;
9701002
if (debug)
9711003
zlog_debug(
9721004
"%s: %s loses to %s due to Router-ID comparison",
@@ -979,6 +1011,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
9791011
exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
9801012

9811013
if (new_cluster < exist_cluster) {
1014+
*reason = bgp_path_selection_cluster_length;
9821015
if (debug)
9831016
zlog_debug(
9841017
"%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
@@ -988,6 +1021,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
9881021
}
9891022

9901023
if (new_cluster > exist_cluster) {
1024+
*reason = bgp_path_selection_cluster_length;
9911025
if (debug)
9921026
zlog_debug(
9931027
"%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
@@ -1001,6 +1035,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
10011035
* valid peer information (as the connection may or may not be up).
10021036
*/
10031037
if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1038+
*reason = bgp_path_selection_stale;
10041039
if (debug)
10051040
zlog_debug(
10061041
"%s: %s wins over %s due to latter path being STALE",
@@ -1009,6 +1044,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
10091044
}
10101045

10111046
if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1047+
*reason = bgp_path_selection_stale;
10121048
if (debug)
10131049
zlog_debug(
10141050
"%s: %s loses to %s due to former path being STALE",
@@ -1017,14 +1053,19 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
10171053
}
10181054

10191055
/* locally configured routes to advertise do not have su_remote */
1020-
if (new->peer->su_remote == NULL)
1056+
if (new->peer->su_remote == NULL) {
1057+
*reason = bgp_path_selection_local_configured;
10211058
return 0;
1022-
if (exist->peer->su_remote == NULL)
1059+
}
1060+
if (exist->peer->su_remote == NULL) {
1061+
*reason = bgp_path_selection_local_configured;
10231062
return 1;
1063+
}
10241064

10251065
ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
10261066

10271067
if (ret == 1) {
1068+
*reason = bgp_path_selection_neighbor_ip;
10281069
if (debug)
10291070
zlog_debug(
10301071
"%s: %s loses to %s due to Neighor IP comparison",
@@ -1033,13 +1074,15 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
10331074
}
10341075

10351076
if (ret == -1) {
1077+
*reason = bgp_path_selection_neighbor_ip;
10361078
if (debug)
10371079
zlog_debug(
10381080
"%s: %s wins over %s due to Neighor IP comparison",
10391081
pfx_buf, new_buf, exist_buf);
10401082
return 1;
10411083
}
10421084

1085+
*reason = bgp_path_selection_default;
10431086
if (debug)
10441087
zlog_debug("%s: %s wins over %s due to nothing left to compare",
10451088
pfx_buf, new_buf, exist_buf);
@@ -1053,12 +1096,13 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
10531096
* This version is compatible with */
10541097
int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
10551098
struct bgp_path_info *exist, char *pfx_buf,
1056-
afi_t afi, safi_t safi)
1099+
afi_t afi, safi_t safi,
1100+
enum bgp_path_selection_reason *reason)
10571101
{
10581102
int paths_eq;
10591103
int ret;
10601104
ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1061-
afi, safi);
1105+
afi, safi, reason);
10621106

10631107
if (paths_eq)
10641108
ret = 0;
@@ -1955,7 +1999,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
19551999
if (bgp_path_info_cmp(
19562000
bgp, pi2, new_select,
19572001
&paths_eq, mpath_cfg, debug,
1958-
pfx_buf, afi, safi)) {
2002+
pfx_buf, afi, safi,
2003+
&rn->reason)) {
19592004
bgp_path_info_unset_flag(
19602005
rn, new_select,
19612006
BGP_PATH_DMED_SELECTED);
@@ -2028,7 +2073,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
20282073
bgp_path_info_unset_flag(rn, pi, BGP_PATH_DMED_CHECK);
20292074

20302075
if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2031-
debug, pfx_buf, afi, safi)) {
2076+
debug, pfx_buf, afi, safi, &rn->reason)) {
20322077
new_select = pi;
20332078
}
20342079
}
@@ -2084,7 +2129,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
20842129
}
20852130

20862131
bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2087-
mpath_cfg, debug, pfx_buf, afi, safi);
2132+
mpath_cfg, debug, pfx_buf, afi, safi,
2133+
&rn->reason);
20882134

20892135
if (paths_eq) {
20902136
if (debug)

bgpd/bgp_route.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,8 @@ extern void bgp_path_info_restore(struct bgp_node *rn,
588588
extern int bgp_path_info_cmp_compatible(struct bgp *bgp,
589589
struct bgp_path_info *new,
590590
struct bgp_path_info *exist,
591-
char *pfx_buf, afi_t afi, safi_t safi);
591+
char *pfx_buf, afi_t afi, safi_t safi,
592+
enum bgp_path_selection_reason *reason);
592593
extern void bgp_attr_add_gshut_community(struct attr *attr);
593594

594595
extern void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,

0 commit comments

Comments
 (0)