From: Donald Sharp Date: Wed, 20 May 2015 01:04:02 +0000 (-0700) Subject: Add 'debug bgp bestpath' X-Git-Tag: frr-2.0-rc1~1429 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=9fbdd10028783510d49488ed24d233660dece846;p=matthieu%2Ffrr.git Add 'debug bgp bestpath' --- diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index b1fc7726f1..f86c3f7b27 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -46,6 +46,7 @@ unsigned long conf_bgp_debug_packet; unsigned long conf_bgp_debug_filter; unsigned long conf_bgp_debug_keepalive; unsigned long conf_bgp_debug_update; +unsigned long conf_bgp_debug_bestpath; unsigned long conf_bgp_debug_zebra; unsigned long conf_bgp_debug_nht; unsigned long conf_bgp_debug_update_groups; @@ -57,6 +58,7 @@ unsigned long term_bgp_debug_packet; unsigned long term_bgp_debug_filter; unsigned long term_bgp_debug_keepalive; unsigned long term_bgp_debug_update; +unsigned long term_bgp_debug_bestpath; unsigned long term_bgp_debug_zebra; unsigned long term_bgp_debug_nht; unsigned long term_bgp_debug_update_groups; @@ -66,6 +68,7 @@ struct list *bgp_debug_keepalive_peers = NULL; struct list *bgp_debug_update_out_peers = NULL; struct list *bgp_debug_update_in_peers = NULL; struct list *bgp_debug_update_prefixes = NULL; +struct list *bgp_debug_bestpath_prefixes = NULL; struct list *bgp_debug_zebra_prefixes = NULL; /* messages for BGP-4 status */ @@ -814,6 +817,126 @@ DEFUN (no_debug_bgp_keepalive_peer, return CMD_SUCCESS; } +/* debug bgp bestpath */ +DEFUN (debug_bgp_bestpath_prefix, + debug_bgp_bestpath_prefix_cmd, + "debug bgp bestpath (A.B.C.D/M|X:X::X:X/M)", + DEBUG_STR + BGP_STR + "BGP bestpath\n" + "IP prefix /, e.g., 35.0.0.0/8\n" + "IPv6 prefix /\n") + +{ + struct prefix *argv_p; + int ret; + + argv_p = prefix_new(); + ret = str2prefix (argv[0], argv_p); + if (!ret) + { + prefix_free(argv_p); + vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE); + return CMD_WARNING; + } + + + if (!bgp_debug_bestpath_prefixes) + bgp_debug_bestpath_prefixes = list_new (); + + if (bgp_debug_list_has_entry(bgp_debug_bestpath_prefixes, NULL, argv_p)) + { + vty_out (vty, "BGP bestptah debugging is already enabled for %s%s", argv[0], VTY_NEWLINE); + return CMD_SUCCESS; + } + + bgp_debug_list_add_entry(bgp_debug_bestpath_prefixes, NULL, argv_p); + + if (vty->node == CONFIG_NODE) + { + DEBUG_ON (bestpath, BESTPATH); + } + else + { + TERM_DEBUG_ON (bestpath, BESTPATH); + vty_out (vty, "BGP bestpath debugging is on for %s%s", argv[0], VTY_NEWLINE); + } + + return CMD_SUCCESS; +} + +DEFUN (no_debug_bgp_bestpath_prefix, + no_debug_bgp_bestpath_prefix_cmd, + "no debug bgp bestpath (A.B.C.D/M|X:X::X:X/M)", + NO_STR + DEBUG_STR + BGP_STR + "BGP bestpath\n" + "IP prefix /, e.g., 35.0.0.0/8\n" + "IPv6 prefix /\n") + +{ + struct prefix *argv_p; + int found_prefix = 0; + int ret; + + argv_p = prefix_new(); + ret = str2prefix (argv[0], argv_p); + if (!ret) + { + prefix_free(argv_p); + vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE); + return CMD_WARNING; + } + + if (bgp_debug_bestpath_prefixes && !list_isempty(bgp_debug_bestpath_prefixes)) + { + found_prefix = bgp_debug_list_remove_entry(bgp_debug_bestpath_prefixes, NULL, argv_p); + + if (list_isempty(bgp_debug_bestpath_prefixes)) + { + if (vty->node == CONFIG_NODE) + { + DEBUG_OFF (bestpath, BESTPATH); + } + else + { + TERM_DEBUG_OFF (bestpath, BESTPATH); + vty_out (vty, "BGP bestpath debugging (per prefix) is off%s", VTY_NEWLINE); + } + } + } + + if (found_prefix) + vty_out (vty, "BGP bestpath debugging is off for %s%s", argv[0], VTY_NEWLINE); + else + vty_out (vty, "BGP bestpath debugging was not enabled for %s%s", argv[0], VTY_NEWLINE); + + return CMD_SUCCESS; +} + +DEFUN (no_debug_bgp_bestpath, + no_debug_bgp_bestpath_cmd, + "no debug bgp bestpath", + NO_STR + DEBUG_STR + BGP_STR + "BGP bestpath\n") +{ + bgp_debug_list_free(bgp_debug_bestpath_prefixes); + + if (vty->node == CONFIG_NODE) + DEBUG_OFF (bestpath, BESTPATH); + else + { + TERM_DEBUG_OFF (bestpath, BESTPATH); + vty_out (vty, "BGP bestpath debugging is off%s", VTY_NEWLINE); + } + return CMD_SUCCESS; +} + + + /* debug bgp updates */ DEFUN (debug_bgp_update, debug_bgp_update_cmd, @@ -1376,6 +1499,7 @@ DEFUN (no_debug_bgp, bgp_debug_list_free(bgp_debug_update_in_peers); bgp_debug_list_free(bgp_debug_update_out_peers); bgp_debug_list_free(bgp_debug_update_prefixes); + bgp_debug_list_free(bgp_debug_bestpath_prefixes); bgp_debug_list_free(bgp_debug_zebra_prefixes); bgp_debug_clear_updgrp_update_dbg(vty->index); @@ -1384,6 +1508,7 @@ DEFUN (no_debug_bgp, TERM_DEBUG_OFF (update, UPDATE_IN); TERM_DEBUG_OFF (update, UPDATE_OUT); TERM_DEBUG_OFF (update, UPDATE_PREFIX); + TERM_DEBUG_OFF (bestpath, BESTPATH); TERM_DEBUG_OFF (as4, AS4); TERM_DEBUG_OFF (as4, AS4_SEGMENT); TERM_DEBUG_OFF (neighbor_events, NEIGHBOR_EVENTS); @@ -1431,6 +1556,10 @@ DEFUN (show_debugging_bgp, bgp_debug_list_print (vty, " BGP updates debugging is on (outbound)", bgp_debug_update_out_peers); + if (BGP_DEBUG (bestpath, BESTPATH)) + bgp_debug_list_print (vty, " BGP bestpath debugging is on for", + bgp_debug_bestpath_prefixes); + if (BGP_DEBUG (zebra, ZEBRA)) bgp_debug_list_print (vty, " BGP zebra debugging is on", bgp_debug_zebra_prefixes); @@ -1481,6 +1610,12 @@ bgp_config_write_debug (struct vty *vty) write++; } + if (CONF_BGP_DEBUG (bestpath, BESTPATH)) + { + vty_out (vty, "debug bgp bestpath%s", VTY_NEWLINE); + write++; + } + if (CONF_BGP_DEBUG (neighbor_events, NEIGHBOR_EVENTS)) { vty_out (vty, "debug bgp neighbor-events%s", VTY_NEWLINE); @@ -1541,6 +1676,8 @@ bgp_debug_init (void) install_element (CONFIG_NODE, &debug_bgp_zebra_cmd); install_element (ENABLE_NODE, &debug_bgp_update_groups_cmd); install_element (CONFIG_NODE, &debug_bgp_update_groups_cmd); + install_element (ENABLE_NODE, &debug_bgp_bestpath_prefix_cmd); + install_element (CONFIG_NODE, &debug_bgp_bestpath_prefix_cmd); /* deb bgp updates [in|out] A.B.C.D */ install_element (ENABLE_NODE, &debug_bgp_update_direct_peer_cmd); @@ -1590,6 +1727,10 @@ bgp_debug_init (void) install_element (ENABLE_NODE, &no_debug_bgp_update_groups_cmd); install_element (CONFIG_NODE, &no_debug_bgp_update_groups_cmd); install_element (ENABLE_NODE, &no_debug_bgp_cmd); + install_element (ENABLE_NODE, &no_debug_bgp_bestpath_cmd); + install_element (CONFIG_NODE, &no_debug_bgp_bestpath_cmd); + install_element (ENABLE_NODE, &no_debug_bgp_bestpath_prefix_cmd); + install_element (CONFIG_NODE, &no_debug_bgp_bestpath_prefix_cmd); } /* Return true if this prefix is on the per_prefix_list of prefixes to debug @@ -1710,6 +1851,20 @@ bgp_debug_update (struct peer *peer, struct prefix *p, return 0; } +int +bgp_debug_bestpath (struct prefix *p) +{ + if (BGP_DEBUG (bestpath, BESTPATH)) + { + if (bgp_debug_per_prefix (p, term_bgp_debug_bestpath, + BGP_DEBUG_BESTPATH, + bgp_debug_bestpath_prefixes)) + return 1; + } + + return 0; +} + int bgp_debug_zebra (struct prefix *p) { diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h index a80d00440e..54c0ac685a 100644 --- a/bgpd/bgp_debug.h +++ b/bgpd/bgp_debug.h @@ -64,6 +64,7 @@ extern unsigned long conf_bgp_debug_neighbor_events; extern unsigned long conf_bgp_debug_packet; extern unsigned long conf_bgp_debug_keepalive; extern unsigned long conf_bgp_debug_update; +extern unsigned long conf_bgp_debug_bestpath; extern unsigned long conf_bgp_debug_zebra; extern unsigned long conf_bgp_debug_nht; extern unsigned long conf_bgp_debug_update_groups; @@ -73,6 +74,7 @@ extern unsigned long term_bgp_debug_neighbor_events; extern unsigned long term_bgp_debug_packet; extern unsigned long term_bgp_debug_keepalive; extern unsigned long term_bgp_debug_update; +extern unsigned long term_bgp_debug_bestpath; extern unsigned long term_bgp_debug_zebra; extern unsigned long term_bgp_debug_nht; extern unsigned long term_bgp_debug_update_groups; @@ -82,6 +84,7 @@ extern struct list *bgp_debug_keepalive_peers; extern struct list *bgp_debug_update_in_peers; extern struct list *bgp_debug_update_out_peers; extern struct list *bgp_debug_update_prefixes; +extern struct list *bgp_debug_bestpath_prefixes; extern struct list *bgp_debug_zebra_prefixes; struct bgp_debug_filter @@ -93,6 +96,7 @@ struct bgp_debug_filter #define BGP_DEBUG_AS4 0x01 #define BGP_DEBUG_AS4_SEGMENT 0x02 +#define BGP_DEBUG_BESTPATH 0x01 #define BGP_DEBUG_NEIGHBOR_EVENTS 0x01 #define BGP_DEBUG_PACKET 0x01 #define BGP_DEBUG_KEEPALIVE 0x01 @@ -138,6 +142,7 @@ extern int bgp_debug_neighbor_events(struct peer *peer); extern int bgp_debug_keepalive(struct peer *peer); extern int bgp_debug_update(struct peer *peer, struct prefix *p, struct update_group *updgrp, unsigned int inbound); +extern int bgp_debug_bestpath(struct prefix *p); extern int bgp_debug_zebra(struct prefix *p); #endif /* _QUAGGA_BGP_DEBUG_H */ diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c index 8ed928baf3..14fb49c38b 100644 --- a/bgpd/bgp_mpath.c +++ b/bgpd/bgp_mpath.c @@ -435,8 +435,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best, old_mpath_count = 0; prev_mpath = new_best; mp_node = listhead (mp_list); - debug = bgp_debug_update(NULL, &rn->p, NULL, 1) || - bgp_debug_update(NULL, &rn->p, NULL, 0); + debug = bgp_debug_bestpath(&rn->p); if (debug) prefix2str (&rn->p, pfx_buf, sizeof (pfx_buf)); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index ef26656aff..5097f0bce6 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -319,10 +319,11 @@ bgp_med_value (struct attr *attr, struct bgp *bgp) } } -/* Compare two bgp route entity. br is preferable then return 1. */ +/* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */ static int bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, - int *paths_eq, struct bgp_maxpaths_cfg *mpath_cfg) + int *paths_eq, struct bgp_maxpaths_cfg *mpath_cfg, int debug, + char *pfx_buf) { struct attr *newattr, *existattr; struct attr_extra *newattre, *existattre; @@ -347,9 +348,19 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, /* 0. Null check. */ if (new == NULL) - return 0; + { + if (debug) + zlog_debug("%s: new is NULL", pfx_buf); + return 0; + } + if (exist == NULL) - return 1; + { + if (debug) + zlog_debug("%s: path %s is the initial bestpath", + pfx_buf, new->peer->host); + return 1; + } newattr = new->attr; existattr = exist->attr; @@ -365,9 +376,22 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, exist_weight = existattre->weight; if (new_weight > exist_weight) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to weight %d > %d", + pfx_buf, new->peer->host, exist->peer->host, new_weight, + exist_weight); + return 1; + } + if (new_weight < exist_weight) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to weight %d < %d", + pfx_buf, new->peer->host, exist->peer->host, new_weight, + exist_weight); + return 0; + } /* 2. Local preference check. */ new_pref = exist_pref = bgp->default_local_pref; @@ -378,9 +402,22 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, exist_pref = existattr->local_pref; if (new_pref > exist_pref) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to localpref %d > %d", + pfx_buf, new->peer->host, exist->peer->host, new_pref, + exist_pref); + return 1; + } + if (new_pref < exist_pref) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to localpref %d < %d", + pfx_buf, new->peer->host, exist->peer->host, new_pref, + exist_pref); + return 0; + } /* 3. Local route check. We prefer: * - BGP_ROUTE_STATIC @@ -388,9 +425,20 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, * - BGP_ROUTE_REDISTRIBUTE */ if (! (new->sub_type == BGP_ROUTE_NORMAL)) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to preferred BGP_ROUTE type", + pfx_buf, new->peer->host, exist->peer->host); + return 1; + } + if (! (exist->sub_type == BGP_ROUTE_NORMAL)) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to preferred BGP_ROUTE type", + pfx_buf, new->peer->host, exist->peer->host); + return 0; + } /* 4. AS path length check. */ if (! bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE)) @@ -406,26 +454,67 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, aspath_hops += aspath_count_confeds (newattr->aspath); if ( aspath_hops < (exist_hops + exist_confeds)) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to aspath (with confeds) hopcount %d < %d", + pfx_buf, new->peer->host, exist->peer->host, + aspath_hops, (exist_hops + exist_confeds)); + return 1; + } + if ( aspath_hops > (exist_hops + exist_confeds)) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to aspath (with confeds) hopcount %d > %d", + pfx_buf, new->peer->host, exist->peer->host, + aspath_hops, (exist_hops + exist_confeds)); + return 0; + } } else { int newhops = aspath_count_hops (newattr->aspath); if (newhops < exist_hops) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to aspath hopcount %d < %d", + pfx_buf, new->peer->host, exist->peer->host, + newhops, exist_hops); + return 1; + } + if (newhops > exist_hops) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to aspath hopcount %d > %d", + pfx_buf, new->peer->host, exist->peer->host, + newhops, exist_hops); + return 0; + } } } /* 5. Origin check. */ if (newattr->origin < existattr->origin) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to ORIGIN %s < %s", + pfx_buf, new->peer->host, exist->peer->host, + bgp_origin_long_str[newattr->origin], + bgp_origin_long_str[existattr->origin]); + return 1; + } + if (newattr->origin > existattr->origin) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to ORIGIN %s > %s", + pfx_buf, new->peer->host, exist->peer->host, + bgp_origin_long_str[newattr->origin], + bgp_origin_long_str[existattr->origin]); + return 0; + } /* 6. MED check. */ internal_as_route = (aspath_count_hops (newattr->aspath) == 0 @@ -446,9 +535,22 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, exist_med = bgp_med_value (exist->attr, bgp); if (new_med < exist_med) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to MED %d < %d", + pfx_buf, new->peer->host, exist->peer->host, new_med, + exist_med); + return 1; + } + if (new_med > exist_med) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to MED %d > %d", + pfx_buf, new->peer->host, exist->peer->host, new_med, + exist_med); + return 0; + } } /* 7. Peer type check. */ @@ -457,10 +559,21 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (new_sort == BGP_PEER_EBGP && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to eBGP peer > iBGP peeer", + pfx_buf, new->peer->host, exist->peer->host); + return 1; + } + if (exist_sort == BGP_PEER_EBGP && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to iBGP peer < eBGP peeer", + pfx_buf, new->peer->host, exist->peer->host); + return 0; + } /* 8. IGP metric check. */ newm = existm = 0; @@ -471,9 +584,20 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, existm = exist->extra->igpmetric; if (newm < existm) - ret = 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to IGP metric %d < %d", + pfx_buf, new->peer->host, exist->peer->host, newm, existm); + ret = 1; + } + if (newm > existm) - ret = 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to IGP metric %d > %d", + pfx_buf, new->peer->host, exist->peer->host, newm, existm); + ret = 0; + } /* 8.1. Same IGP metric. Compare the cluster list length as representative of IGP hops metric. Rewrite the metric value @@ -488,10 +612,24 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, { newm = BGP_CLUSTER_LIST_LENGTH(new->attr); existm = BGP_CLUSTER_LIST_LENGTH(exist->attr); + if (newm < existm) - ret = 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to CLUSTER_LIST length %d < %d", + pfx_buf, new->peer->host, exist->peer->host, newm, + existm); + ret = 1; + } + if (newm > existm) - ret = 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to CLUSTER_LIST length %d > %d", + pfx_buf, new->peer->host, exist->peer->host, newm, + existm); + ret = 0; + } } } @@ -510,14 +648,30 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, * array. */ *paths_eq = 1; + + if (debug) + zlog_debug("%s: path %s and path %s are equal via multipath-relax", + pfx_buf, new->peer->host, exist->peer->host); } else if (new->peer->sort == BGP_PEER_IBGP) { if (aspath_cmp (new->attr->aspath, exist->attr->aspath)) - *paths_eq = 1; + { + *paths_eq = 1; + + if (debug) + zlog_debug("%s: path %s and path %s are equal via matching aspaths", + pfx_buf, new->peer->host, exist->peer->host); + } } else if (new->peer->as == exist->peer->as) - *paths_eq = 1; + { + *paths_eq = 1; + + if (debug) + zlog_debug("%s: path %s and path %s are equal via same remote-as", + pfx_buf, new->peer->host, exist->peer->host); + } } else { @@ -537,9 +691,20 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, && exist_sort == BGP_PEER_EBGP) { if (CHECK_FLAG (new->flags, BGP_INFO_SELECTED)) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to oldest external", + pfx_buf, new->peer->host, exist->peer->host); + return 1; + } + if (CHECK_FLAG (exist->flags, BGP_INFO_SELECTED)) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to oldest external", + pfx_buf, new->peer->host, exist->peer->host); + return 0; + } } /* 11. Router-ID comparision. */ @@ -557,34 +722,84 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, exist_id.s_addr = exist->peer->remote_id.s_addr; if (ntohl (new_id.s_addr) < ntohl (exist_id.s_addr)) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to Router-ID comparison", + pfx_buf, new->peer->host, exist->peer->host); + return 1; + } + if (ntohl (new_id.s_addr) > ntohl (exist_id.s_addr)) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to Router-ID comparison", + pfx_buf, new->peer->host, exist->peer->host); + return 0; + } /* 12. Cluster length comparision. */ new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr); exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr); if (new_cluster < exist_cluster) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to CLUSTER_LIST length %d < %d", + pfx_buf, new->peer->host, exist->peer->host, new_cluster, + exist_cluster); + return 1; + } + if (new_cluster > exist_cluster) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to CLUSTER_LIST length %d > %d", + pfx_buf, new->peer->host, exist->peer->host, new_cluster, + exist_cluster); + return 0; + } /* 13. Neighbor address comparision. */ /* Do this only if neither path is "stale" as stale paths do not have * valid peer information (as the connection may or may not be up). */ if (CHECK_FLAG (exist->flags, BGP_INFO_STALE)) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to latter path being STALE", + pfx_buf, new->peer->host, exist->peer->host); + return 1; + } + if (CHECK_FLAG (new->flags, BGP_INFO_STALE)) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to former path being STALE", + pfx_buf, new->peer->host, exist->peer->host); + return 0; + } ret = sockunion_cmp (new->peer->su_remote, exist->peer->su_remote); if (ret == 1) - return 0; + { + if (debug) + zlog_debug("%s: path %s loses to path %s due to Neighor IP comparison", + pfx_buf, new->peer->host, exist->peer->host); + return 0; + } + if (ret == -1) - return 1; + { + if (debug) + zlog_debug("%s: path %s wins over path %s due to Neighor IP comparison", + pfx_buf, new->peer->host, exist->peer->host); + return 1; + } + + if (debug) + zlog_debug("%s: path %s wins over path %s due to nothing left to compare", + pfx_buf, new->peer->host, exist->peer->host); return 1; } @@ -1974,14 +2189,20 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, struct bgp_info *ri1; struct bgp_info *ri2; struct bgp_info *nextri = NULL; - int paths_eq, do_mpath; + int paths_eq, do_mpath, debug; struct list mp_list; char buf[INET6_BUFSIZ]; + char pfx_buf[INET6_ADDRSTRLEN]; bgp_mp_list_init (&mp_list); do_mpath = (mpath_cfg->maxpaths_ebgp != BGP_DEFAULT_MAXPATHS || mpath_cfg->maxpaths_ibgp != BGP_DEFAULT_MAXPATHS); + debug = bgp_debug_bestpath(&rn->p); + + if (debug) + prefix2str (&rn->p, pfx_buf, sizeof (pfx_buf)); + /* bgp deterministic-med */ new_select = NULL; if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED)) @@ -2017,7 +2238,7 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, if (CHECK_FLAG (ri2->flags, BGP_INFO_SELECTED)) old_select = ri2; if (bgp_info_cmp (bgp, ri2, new_select, &paths_eq, - mpath_cfg)) + mpath_cfg, debug, pfx_buf)) { bgp_info_unset_flag (rn, new_select, BGP_INFO_DMED_SELECTED); new_select = ri2; @@ -2065,7 +2286,7 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_CHECK); bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_SELECTED); - if (bgp_info_cmp (bgp, ri, new_select, &paths_eq, mpath_cfg)) + if (bgp_info_cmp (bgp, ri, new_select, &paths_eq, mpath_cfg, debug, pfx_buf)) { new_select = ri; } @@ -2076,10 +2297,17 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, */ if (do_mpath && new_select) { + if (debug) + zlog_debug("%s: path %s is the bestpath, now find multipaths", + pfx_buf, new_select->peer->host); + for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1); ri = nextri) { if (ri == new_select) { + if (debug) + zlog_debug("%s: path %s is the bestpath, add to the multipath list", + pfx_buf, ri->peer->host); bgp_mp_list_add (&mp_list, ri); continue; } @@ -2097,10 +2325,13 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, && (! CHECK_FLAG (ri->flags, BGP_INFO_DMED_SELECTED))) continue; - bgp_info_cmp (bgp, ri, new_select, &paths_eq, mpath_cfg); + bgp_info_cmp (bgp, ri, new_select, &paths_eq, mpath_cfg, debug, pfx_buf); if (paths_eq) { + if (debug) + zlog_debug("%s: %s path is equivalent to the bestpath, add to the multipath list", + pfx_buf, ri->peer->host); bgp_mp_list_add (&mp_list, ri); } }