diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c index 496ccdf11b..50813df034 100644 --- a/bgpd/bgp_mpath.c +++ b/bgpd/bgp_mpath.c @@ -427,6 +427,7 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best, struct bgp_info *cur_mpath, *new_mpath, *next_mpath, *prev_mpath; int mpath_changed, debug; char pfx_buf[PREFIX2STR_BUFFER], nh_buf[2][INET6_ADDRSTRLEN]; + char path_buf[PATH_ADDPATH_STR_BUFFER]; mpath_changed = 0; maxpaths = MULTIPATH_NUM; @@ -500,11 +501,13 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best, { mpath_changed = 1; if (debug) - zlog_debug ("%s remove mpath nexthop %s peer %s", pfx_buf, - inet_ntop (AF_INET, &cur_mpath->attr->nexthop, - nh_buf[0], sizeof (nh_buf[0])), - sockunion2str (cur_mpath->peer->su_remote, - nh_buf[1], sizeof (nh_buf[1]))); + { + bgp_info_path_with_addpath_rx_str(cur_mpath, path_buf); + zlog_debug ("%s remove mpath nexthop %s %s", pfx_buf, + inet_ntop (AF_INET, &cur_mpath->attr->nexthop, + nh_buf[0], sizeof (nh_buf[0])), + path_buf); + } } mp_node = mp_next_node; cur_mpath = next_mpath; @@ -524,11 +527,13 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best, bgp_info_mpath_dequeue (cur_mpath); mpath_changed = 1; if (debug) - zlog_debug ("%s remove mpath nexthop %s peer %s", pfx_buf, - inet_ntop (AF_INET, &cur_mpath->attr->nexthop, - nh_buf[0], sizeof (nh_buf[0])), - sockunion2str (cur_mpath->peer->su_remote, - nh_buf[1], sizeof (nh_buf[1]))); + { + bgp_info_path_with_addpath_rx_str(cur_mpath, path_buf); + zlog_debug ("%s remove mpath nexthop %s %s", pfx_buf, + inet_ntop (AF_INET, &cur_mpath->attr->nexthop, + nh_buf[0], sizeof (nh_buf[0])), + path_buf); + } cur_mpath = next_mpath; } else @@ -558,11 +563,13 @@ bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best, mpath_changed = 1; mpath_count++; if (debug) - zlog_debug ("%s add mpath nexthop %s peer %s", pfx_buf, - inet_ntop (AF_INET, &new_mpath->attr->nexthop, - nh_buf[0], sizeof (nh_buf[0])), - sockunion2str (new_mpath->peer->su_remote, - nh_buf[1], sizeof (nh_buf[1]))); + { + bgp_info_path_with_addpath_rx_str(new_mpath, path_buf); + zlog_debug ("%s add mpath nexthop %s %s", pfx_buf, + inet_ntop (AF_INET, &new_mpath->attr->nexthop, + nh_buf[0], sizeof (nh_buf[0])), + path_buf); + } } mp_node = mp_next_node; } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index d30aaa7215..b4ba8afe97 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -318,6 +318,15 @@ bgp_med_value (struct attr *attr, struct bgp *bgp) } } +void +bgp_info_path_with_addpath_rx_str (struct bgp_info *ri, char *buf) +{ + if (ri->addpath_rx_id) + sprintf(buf, "path %s (addpath rxid %d)", ri->peer->host, ri->addpath_rx_id); + else + sprintf(buf, "path %s", ri->peer->host); +} + /* 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, @@ -342,6 +351,8 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, int internal_as_route; int confed_as_route; int ret; + char new_buf[PATH_ADDPATH_STR_BUFFER]; + char exist_buf[PATH_ADDPATH_STR_BUFFER]; *paths_eq = 0; @@ -353,14 +364,19 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, return 0; } + if (debug) + bgp_info_path_with_addpath_rx_str (new, new_buf); + if (exist == NULL) { if (debug) - zlog_debug("%s: path %s is the initial bestpath", - pfx_buf, new->peer->host); + zlog_debug("%s: %s is the initial bestpath", pfx_buf, new_buf); return 1; } + if (debug) + bgp_info_path_with_addpath_rx_str (exist, exist_buf); + newattr = new->attr; existattr = exist->attr; newattre = newattr->extra; @@ -377,18 +393,16 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (new_weight > exist_weight) { 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); + zlog_debug("%s: %s wins over %s due to weight %d > %d", + pfx_buf, new_buf, exist_buf, new_weight, exist_weight); return 1; } if (new_weight < exist_weight) { 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); + zlog_debug("%s: %s loses to %s due to weight %d < %d", + pfx_buf, new_buf, exist_buf, new_weight, exist_weight); return 0; } @@ -403,18 +417,16 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (new_pref > exist_pref) { 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); + zlog_debug("%s: %s wins over %s due to localpref %d > %d", + pfx_buf, new_buf, exist_buf, new_pref, exist_pref); return 1; } if (new_pref < exist_pref) { 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); + zlog_debug("%s: %s loses to %s due to localpref %d < %d", + pfx_buf, new_buf, exist_buf, new_pref, exist_pref); return 0; } @@ -426,16 +438,16 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (! (new->sub_type == BGP_ROUTE_NORMAL)) { 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); + zlog_debug("%s: %s wins over %s due to preferred BGP_ROUTE type", + pfx_buf, new_buf, exist_buf); return 1; } if (! (exist->sub_type == BGP_ROUTE_NORMAL)) { 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); + zlog_debug("%s: %s loses to %s due to preferred BGP_ROUTE type", + pfx_buf, new_buf, exist_buf); return 0; } @@ -455,8 +467,8 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if ( aspath_hops < (exist_hops + exist_confeds)) { 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, + zlog_debug("%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d", + pfx_buf, new_buf, exist_buf, aspath_hops, (exist_hops + exist_confeds)); return 1; } @@ -464,8 +476,8 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if ( aspath_hops > (exist_hops + exist_confeds)) { 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, + zlog_debug("%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d", + pfx_buf, new_buf, exist_buf, aspath_hops, (exist_hops + exist_confeds)); return 0; } @@ -477,18 +489,16 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (newhops < exist_hops) { 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); + zlog_debug("%s: %s wins over %s due to aspath hopcount %d < %d", + pfx_buf, new_buf, exist_buf, newhops, exist_hops); return 1; } if (newhops > exist_hops) { 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); + zlog_debug("%s: %s loses to %s due to aspath hopcount %d > %d", + pfx_buf, new_buf, exist_buf, newhops, exist_hops); return 0; } } @@ -498,8 +508,8 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (newattr->origin < existattr->origin) { if (debug) - zlog_debug("%s: path %s wins over path %s due to ORIGIN %s < %s", - pfx_buf, new->peer->host, exist->peer->host, + zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s", + pfx_buf, new_buf, exist_buf, bgp_origin_long_str[newattr->origin], bgp_origin_long_str[existattr->origin]); return 1; @@ -508,8 +518,8 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (newattr->origin > existattr->origin) { if (debug) - zlog_debug("%s: path %s loses to path %s due to ORIGIN %s > %s", - pfx_buf, new->peer->host, exist->peer->host, + zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s", + pfx_buf, new_buf, exist_buf, bgp_origin_long_str[newattr->origin], bgp_origin_long_str[existattr->origin]); return 0; @@ -536,18 +546,16 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (new_med < exist_med) { 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); + zlog_debug("%s: %s wins over %s due to MED %d < %d", + pfx_buf, new_buf, exist_buf, new_med, exist_med); return 1; } if (new_med > exist_med) { 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); + zlog_debug("%s: %s loses to %s due to MED %d > %d", + pfx_buf, new_buf, exist_buf, new_med, exist_med); return 0; } } @@ -560,8 +568,8 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) { if (debug) - zlog_debug("%s: path %s wins over path %s due to eBGP peer > iBGP peer", - pfx_buf, new->peer->host, exist->peer->host); + zlog_debug("%s: %s wins over %s due to eBGP peer > iBGP peer", + pfx_buf, new_buf, exist_buf); return 1; } @@ -569,8 +577,8 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) { if (debug) - zlog_debug("%s: path %s loses to path %s due to iBGP peer < eBGP peer", - pfx_buf, new->peer->host, exist->peer->host); + zlog_debug("%s: %s loses to %s due to iBGP peer < eBGP peer", + pfx_buf, new_buf, exist_buf); return 0; } @@ -585,16 +593,16 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (newm < existm) { 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); + zlog_debug("%s: %s wins over %s due to IGP metric %d < %d", + pfx_buf, new_buf, exist_buf, newm, existm); ret = 1; } if (newm > existm) { 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); + zlog_debug("%s: %s loses to %s due to IGP metric %d > %d", + pfx_buf, new_buf, exist_buf, newm, existm); ret = 0; } @@ -615,18 +623,16 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (newm < existm) { 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); + zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d", + pfx_buf, new_buf, exist_buf, newm, existm); ret = 1; } if (newm > existm) { 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); + zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d", + pfx_buf, new_buf, exist_buf, newm, existm); ret = 0; } } @@ -638,16 +644,16 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (new_sort == BGP_PEER_CONFED && exist_sort == BGP_PEER_IBGP) { if (debug) - zlog_debug("%s: path %s wins over path %s due to confed-external peer > confed-internal peer", - pfx_buf, new->peer->host, exist->peer->host); + zlog_debug("%s: %s wins over %s due to confed-external peer > confed-internal peer", + pfx_buf, new_buf, exist_buf); return 1; } if (exist_sort == BGP_PEER_CONFED && new_sort == BGP_PEER_IBGP) { if (debug) - zlog_debug("%s: path %s loses to path %s due to confed-internal peer < confed-external peer", - pfx_buf, new->peer->host, exist->peer->host); + zlog_debug("%s: %s loses to %s due to confed-internal peer < confed-external peer", + pfx_buf, new_buf, exist_buf); return 0; } } @@ -669,8 +675,8 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, *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); + zlog_debug("%s: %s and %s are equal via multipath-relax", + pfx_buf, new_buf, exist_buf); } else if (new->peer->sort == BGP_PEER_IBGP) { @@ -679,8 +685,8 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, *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); + zlog_debug("%s: %s and %s are equal via matching aspaths", + pfx_buf, new_buf, exist_buf); } } else if (new->peer->as == exist->peer->as) @@ -688,8 +694,8 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, *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); + zlog_debug("%s: %s and %s are equal via same remote-as", + pfx_buf, new_buf, exist_buf); } } else @@ -712,16 +718,16 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (CHECK_FLAG (new->flags, BGP_INFO_SELECTED)) { if (debug) - zlog_debug("%s: path %s wins over path %s due to oldest external", - pfx_buf, new->peer->host, exist->peer->host); + zlog_debug("%s: %s wins over %s due to oldest external", + pfx_buf, new_buf, exist_buf); return 1; } if (CHECK_FLAG (exist->flags, BGP_INFO_SELECTED)) { if (debug) - zlog_debug("%s: path %s loses to path %s due to oldest external", - pfx_buf, new->peer->host, exist->peer->host); + zlog_debug("%s: %s loses to %s due to oldest external", + pfx_buf, new_buf, exist_buf); return 0; } } @@ -743,16 +749,16 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (ntohl (new_id.s_addr) < ntohl (exist_id.s_addr)) { if (debug) - zlog_debug("%s: path %s wins over path %s due to Router-ID comparison", - pfx_buf, new->peer->host, exist->peer->host); + zlog_debug("%s: %s wins over %s due to Router-ID comparison", + pfx_buf, new_buf, exist_buf); return 1; } if (ntohl (new_id.s_addr) > ntohl (exist_id.s_addr)) { if (debug) - zlog_debug("%s: path %s loses to path %s due to Router-ID comparison", - pfx_buf, new->peer->host, exist->peer->host); + zlog_debug("%s: %s loses to %s due to Router-ID comparison", + pfx_buf, new_buf, exist_buf); return 0; } @@ -763,18 +769,16 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (new_cluster < exist_cluster) { 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); + zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d", + pfx_buf, new_buf, exist_buf, new_cluster, exist_cluster); return 1; } if (new_cluster > exist_cluster) { 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); + zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d", + pfx_buf, new_buf, exist_buf, new_cluster, exist_cluster); return 0; } @@ -785,16 +789,16 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (CHECK_FLAG (exist->flags, BGP_INFO_STALE)) { 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); + zlog_debug("%s: %s wins over %s due to latter path being STALE", + pfx_buf, new_buf, exist_buf); return 1; } if (CHECK_FLAG (new->flags, BGP_INFO_STALE)) { 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); + zlog_debug("%s: %s loses to %s due to former path being STALE", + pfx_buf, new_buf, exist_buf); return 0; } @@ -803,22 +807,22 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist, if (ret == 1) { if (debug) - zlog_debug("%s: path %s loses to path %s due to Neighor IP comparison", - pfx_buf, new->peer->host, exist->peer->host); + zlog_debug("%s: %s loses to %s due to Neighor IP comparison", + pfx_buf, new_buf, exist_buf); return 0; } if (ret == -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); + zlog_debug("%s: %s wins over %s due to Neighor IP comparison", + pfx_buf, new_buf, exist_buf); 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); + zlog_debug("%s: %s wins over %s due to nothing left to compare", + pfx_buf, new_buf, exist_buf); return 1; } @@ -1507,6 +1511,7 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, int paths_eq, do_mpath, debug; struct list mp_list; char pfx_buf[PREFIX2STR_BUFFER]; + char path_buf[PATH_ADDPATH_STR_BUFFER]; bgp_mp_list_init (&mp_list); do_mpath = (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1); @@ -1572,9 +1577,11 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, bgp_info_set_flag (rn, new_select, BGP_INFO_DMED_SELECTED); if (debug) - zlog_debug("%s: path %s is the bestpath from AS %d", - pfx_buf, new_select->peer->host, - aspath_get_firstas(new_select->attr->aspath)); + { + bgp_info_path_with_addpath_rx_str (new_select, path_buf); + zlog_debug("%s: %s is the bestpath from AS %d", + pfx_buf, path_buf, aspath_get_firstas(new_select->attr->aspath)); + } } } @@ -1625,16 +1632,22 @@ 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); + { + bgp_info_path_with_addpath_rx_str (new_select, path_buf); + zlog_debug("%s: %s is the bestpath, now find multipaths", pfx_buf, path_buf); + } for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1); ri = nextri) { + + if (debug) + bgp_info_path_with_addpath_rx_str (ri, path_buf); + if (ri == new_select) { if (debug) - zlog_debug("%s: path %s is the bestpath, add to the multipath list", - pfx_buf, ri->peer->host); + zlog_debug("%s: %s is the bestpath, add to the multipath list", + pfx_buf, path_buf); bgp_mp_list_add (&mp_list, ri); continue; } @@ -1651,8 +1664,8 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, if (!bgp_info_nexthop_cmp (ri, new_select)) { if (debug) - zlog_debug("%s: path %s has the same nexthop as the bestpath, skip it", - pfx_buf, ri->peer->host); + zlog_debug("%s: %s has the same nexthop as the bestpath, skip it", + pfx_buf, path_buf); continue; } @@ -1661,8 +1674,8 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, if (paths_eq) { if (debug) - zlog_debug("%s: path %s is equivalent to the bestpath, add to the multipath list", - pfx_buf, ri->peer->host); + zlog_debug("%s: %s is equivalent to the bestpath, add to the multipath list", + pfx_buf, path_buf); bgp_mp_list_add (&mp_list, ri); } } @@ -2080,12 +2093,13 @@ info_make (int type, int sub_type, u_short instance, struct peer *peer, struct a } static void -bgp_info_addpath_rx_str(struct bgp_info *ri, char *buf) +bgp_info_addpath_rx_str(u_int32_t addpath_id, char *buf) { - if (ri && ri->addpath_rx_id) - sprintf(buf, " with addpath ID %d", ri->addpath_rx_id); + if (addpath_id) + sprintf(buf, " with addpath ID %d", addpath_id); } + /* Check if received nexthop is valid or not. */ static int bgp_update_martian_nexthop (afi_t afi, safi_t safi, struct attr *attr) @@ -2258,7 +2272,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, u_int32_t addpath_id, { if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_info_addpath_rx_str(ri, buf2); + bgp_info_addpath_rx_str(addpath_id, buf2); zlog_debug ("%s rcvd %s/%d%s", peer->host, inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), @@ -2281,7 +2295,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, u_int32_t addpath_id, peer->rcvd_attr_printed = 1; } - bgp_info_addpath_rx_str(ri, buf2); + bgp_info_addpath_rx_str(addpath_id, buf2); zlog_debug ("%s rcvd %s/%d%s...duplicate ignored", peer->host, inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), @@ -2307,7 +2321,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, u_int32_t addpath_id, { if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_info_addpath_rx_str(ri, buf2); + bgp_info_addpath_rx_str(addpath_id, buf2); zlog_debug ("%s rcvd %s/%d%s, flapped quicker than processing", peer->host, inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), @@ -2319,7 +2333,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Received Logging. */ if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_info_addpath_rx_str(ri, buf2); + bgp_info_addpath_rx_str(addpath_id, buf2); zlog_debug ("%s rcvd %s/%d%s", peer->host, inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), @@ -2413,7 +2427,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, u_int32_t addpath_id, peer->rcvd_attr_printed = 1; } - bgp_info_addpath_rx_str(ri, buf2); + bgp_info_addpath_rx_str(addpath_id, buf2); zlog_debug ("%s rcvd %s/%d%s", peer->host, inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), @@ -2486,7 +2500,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, u_int32_t addpath_id, peer->rcvd_attr_printed = 1; } - bgp_info_addpath_rx_str(ri, buf2); + bgp_info_addpath_rx_str(addpath_id, buf2); zlog_debug ("%s rcvd UPDATE about %s/%d%s -- DENIED due to: %s", peer->host, inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), @@ -2541,7 +2555,7 @@ bgp_withdraw (struct peer *peer, struct prefix *p, u_int32_t addpath_id, /* Logging. */ if (bgp_debug_update(peer, p, NULL, 1)) { - bgp_info_addpath_rx_str(ri, buf2); + bgp_info_addpath_rx_str(addpath_id, buf2); zlog_debug ("%s rcvd UPDATE about %s/%d%s -- withdrawn", peer->host, inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 60152e9470..faeb5d6a3c 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -191,6 +191,9 @@ struct bgp_static #define UNSUPPRESS_MAP_NAME(F) ((F)->usmap.name) #define UNSUPPRESS_MAP(F) ((F)->usmap.map) +/* path PREFIX (addpath rxid NUMBER) */ +#define PATH_ADDPATH_STR_BUFFER PREFIX2STR_BUFFER + 32 + enum bgp_path_type { BGP_PATH_ALL, @@ -229,6 +232,7 @@ extern void bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri); extern struct bgp_info_extra *bgp_info_extra_get (struct bgp_info *); extern void bgp_info_set_flag (struct bgp_node *, struct bgp_info *, u_int32_t); extern void bgp_info_unset_flag (struct bgp_node *, struct bgp_info *, u_int32_t); +extern void bgp_info_path_with_addpath_rx_str (struct bgp_info *ri, char *buf); extern int bgp_nlri_sanity_check (struct peer *, int, safi_t, u_char *, bgp_size_t, int *); extern int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *); diff --git a/bgpd/bgp_updgrp.h b/bgpd/bgp_updgrp.h index cbaf65ed4c..b94519ef00 100644 --- a/bgpd/bgp_updgrp.h +++ b/bgpd/bgp_updgrp.h @@ -58,6 +58,8 @@ #define PEER_UPDGRP_AF_CAP_FLAGS (PEER_CAP_ORF_PREFIX_SM_RCV | \ PEER_CAP_ORF_PREFIX_SM_OLD_RCV |\ + PEER_CAP_ADDPATH_AF_TX_ADV |\ + PEER_CAP_ADDPATH_AF_RX_RCV |\ PEER_CAP_ENHE_AF_NEGO) typedef enum diff --git a/zebra/Makefile.am b/zebra/Makefile.am index 8253664e7a..2a4ab188c6 100644 --- a/zebra/Makefile.am +++ b/zebra/Makefile.am @@ -39,7 +39,7 @@ zebra_SOURCES = \ testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \ zebra_vty.c zebra_ptm.c zebra_routemap.c \ kernel_null.c redistribute_null.c ioctl_null.c misc_null.c zebra_rnh_null.c \ - zebra_ptm_null.c + zebra_ptm_null.c rtadv_null.c noinst_HEADERS = \ connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \ diff --git a/zebra/connected.c b/zebra/connected.c index 41b68d1564..f67b44ba80 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -36,6 +36,7 @@ #include "zebra/redistribute.h" #include "zebra/interface.h" #include "zebra/connected.h" +#include "zebra/rtadv.h" extern struct zebra_t zebrad; /* communicate the withdrawal of a connected address */ @@ -71,6 +72,10 @@ connected_withdraw (struct connected *ifc) listnode_delete (ifc->ifp->connected, ifc); connected_free (ifc); } + + /* Enable RA suppression if there are no IPv6 addresses on this interface */ + if (! ipv6_address_configured(ifc->ifp)) + ipv6_nd_suppress_ra_set (ifc->ifp, RA_SUPPRESS); } static void @@ -93,6 +98,9 @@ connected_announce (struct interface *ifp, struct connected *ifc) if (ifc->address->family == AF_INET) if_subnet_add (ifp, ifc); + else if (ifc->address->family == AF_INET6) + ipv6_nd_suppress_ra_set (ifp, RA_ENABLE); + zebra_interface_address_add_update (ifp, ifc); if (if_is_operative(ifp)) diff --git a/zebra/interface.c b/zebra/interface.c index bd1e404d23..2768e69a6d 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1730,6 +1730,8 @@ ipv6_address_install (struct vty *vty, struct interface *ifp, /* Add to linked list. */ listnode_add (ifp->connected, ifc); + + ipv6_nd_suppress_ra_set (ifp, RA_ENABLE); } /* This address is configured from zebra. */ @@ -1765,6 +1767,20 @@ ipv6_address_install (struct vty *vty, struct interface *ifp, return CMD_SUCCESS; } +/* Return true if an ipv6 address is configured on ifp */ +int +ipv6_address_configured (struct interface *ifp) +{ + struct connected *connected; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected)) + if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) && (connected->address->family == AF_INET6)) + return 1; + + return 0; +} + static int ipv6_address_uninstall (struct vty *vty, struct interface *ifp, const char *addr_str, const char *peer_str, @@ -1814,6 +1830,10 @@ ipv6_address_uninstall (struct vty *vty, struct interface *ifp, return CMD_WARNING; } + /* Enable RA suppression if there are no IPv6 addresses on this interface */ + if (! ipv6_address_configured(ifp)) + ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS); + UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED); /* This information will be propagated to the zclients when the * kernel notification is received. */ diff --git a/zebra/interface.h b/zebra/interface.h index 650b62a458..6f253a467e 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -217,6 +217,7 @@ extern void if_refresh (struct interface *); extern void if_flags_update (struct interface *, uint64_t); extern int if_subnet_add (struct interface *, struct connected *); extern int if_subnet_delete (struct interface *, struct connected *); +extern int ipv6_address_configured (struct interface *ifp); #ifdef HAVE_PROC_NET_DEV extern void ifstat_update_proc (void); diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 30b4d749bd..69bd566408 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -707,6 +707,46 @@ rtadv_prefix_reset (struct zebra_if *zif, struct rtadv_prefix *rp) return 0; } +void +ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status) +{ + struct zebra_if *zif; + struct zebra_vrf *zvrf; + + zif = ifp->info; + zvrf = vrf_info_lookup (ifp->vrf_id); + + if (status == RA_SUPPRESS) + { + /* RA is currently enabled */ + if (zif->rtadv.AdvSendAdvertisements) + { + zif->rtadv.AdvSendAdvertisements = 0; + zif->rtadv.AdvIntervalTimer = 0; + zvrf->rtadv.adv_if_count--; + + if_leave_all_router (zvrf->rtadv.sock, ifp); + + if (zvrf->rtadv.adv_if_count == 0) + rtadv_event (zvrf, RTADV_STOP, 0); + } + } + else + { + if (! zif->rtadv.AdvSendAdvertisements) + { + zif->rtadv.AdvSendAdvertisements = 1; + zif->rtadv.AdvIntervalTimer = 0; + zvrf->rtadv.adv_if_count++; + + if_join_all_router (zvrf->rtadv.sock, ifp); + + if (zvrf->rtadv.adv_if_count == 1) + rtadv_event (zvrf, RTADV_START, zvrf->rtadv.sock); + } + } +} + DEFUN (ipv6_nd_suppress_ra, ipv6_nd_suppress_ra_cmd, "ipv6 nd suppress-ra", @@ -715,12 +755,8 @@ DEFUN (ipv6_nd_suppress_ra, "Suppress Router Advertisement\n") { struct interface *ifp; - struct zebra_if *zif; - struct zebra_vrf *zvrf; ifp = vty->index; - zif = ifp->info; - zvrf = vrf_info_lookup (ifp->vrf_id); if (if_is_loopback (ifp)) { @@ -728,18 +764,7 @@ DEFUN (ipv6_nd_suppress_ra, return CMD_WARNING; } - if (zif->rtadv.AdvSendAdvertisements) - { - zif->rtadv.AdvSendAdvertisements = 0; - zif->rtadv.AdvIntervalTimer = 0; - zvrf->rtadv.adv_if_count--; - - if_leave_all_router (zvrf->rtadv.sock, ifp); - - if (zvrf->rtadv.adv_if_count == 0) - rtadv_event (zvrf, RTADV_STOP, 0); - } - + ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS); return CMD_SUCCESS; } @@ -752,12 +777,8 @@ DEFUN (no_ipv6_nd_suppress_ra, "Suppress Router Advertisement\n") { struct interface *ifp; - struct zebra_if *zif; - struct zebra_vrf *zvrf; ifp = vty->index; - zif = ifp->info; - zvrf = vrf_info_lookup (ifp->vrf_id); if (if_is_loopback (ifp)) { @@ -765,18 +786,7 @@ DEFUN (no_ipv6_nd_suppress_ra, return CMD_WARNING; } - if (! zif->rtadv.AdvSendAdvertisements) - { - zif->rtadv.AdvSendAdvertisements = 1; - zif->rtadv.AdvIntervalTimer = 0; - zvrf->rtadv.adv_if_count++; - - if_join_all_router (zvrf->rtadv.sock, ifp); - - if (zvrf->rtadv.adv_if_count == 1) - rtadv_event (zvrf, RTADV_START, zvrf->rtadv.sock); - } - + ipv6_nd_suppress_ra_set (ifp, RA_ENABLE); return CMD_SUCCESS; } @@ -1760,10 +1770,17 @@ rtadv_config_write (struct vty *vty, struct interface *ifp) if (! if_is_loopback (ifp)) { - if (zif->rtadv.AdvSendAdvertisements) - vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE); + if (ipv6_address_configured(ifp)) + { + if (! zif->rtadv.AdvSendAdvertisements) + vty_out (vty, " ipv6 nd suppress-ra%s", VTY_NEWLINE); + } + else + { + if (zif->rtadv.AdvSendAdvertisements) + vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE); + } } - interval = zif->rtadv.MaxRtrAdvInterval; if (interval % 1000) diff --git a/zebra/rtadv.h b/zebra/rtadv.h index 160814b209..46b282aed6 100644 --- a/zebra/rtadv.h +++ b/zebra/rtadv.h @@ -100,8 +100,14 @@ extern const char *rtadv_pref_strs[]; #endif /* HAVE_RTADV */ +typedef enum { + RA_ENABLE = 0, + RA_SUPPRESS, +} ipv6_nd_suppress_ra_status; + extern void rtadv_init (struct zebra_vrf *); extern void rtadv_terminate (struct zebra_vrf *); extern void rtadv_cmd_init (void); +extern void ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status); #endif /* _ZEBRA_RTADV_H */ diff --git a/zebra/rtadv_null.c b/zebra/rtadv_null.c new file mode 100644 index 0000000000..d4678d5751 --- /dev/null +++ b/zebra/rtadv_null.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2015 Cumulus Networks, Inc. + * + * This file is part of Quagga. + * + * Quagga 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; either version 2, or (at your option) any + * later version. + * + * Quagga 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. + * + * You should have received a copy of the GNU General Public License + * along with Quagga; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include +#include +#include + +void ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status) +{ return; } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 27e0314b01..e41d5d4fad 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1858,7 +1858,7 @@ rib_queue_init (struct zebra_t *zebra) /* Add RIB to head of the route node. */ static void -rib_link (struct route_node *rn, struct rib *rib) +rib_link (struct route_node *rn, struct rib *rib, int process) { struct rib *head; rib_dest_t *dest; @@ -1893,7 +1893,10 @@ rib_link (struct route_node *rn, struct rib *rib) /* Further processing only if entry is in main table */ if ((rib->table == RT_TABLE_MAIN) || (rib->table == zebrad.rtm_table_default)) - rib_queue_add (&zebrad, rn); + { + if (process) + rib_queue_add (&zebrad, rn); + } else { afi = (rn->p.family == AF_INET) ? AFI_IP : @@ -1904,7 +1907,7 @@ rib_link (struct route_node *rn, struct rib *rib) } static void -rib_addnode (struct route_node *rn, struct rib *rib) +rib_addnode (struct route_node *rn, struct rib *rib, int process) { /* RIB node has been un-removed before route-node is processed. * route_node must hence already be on the queue for processing.. @@ -1914,7 +1917,7 @@ rib_addnode (struct route_node *rn, struct rib *rib) UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED); return; } - rib_link (rn, rib); + rib_link (rn, rib, process); } /* @@ -2097,7 +2100,7 @@ rib_add_ipv4 (int type, u_short instance, int flags, struct prefix_ipv4 *p, if (IS_ZEBRA_DEBUG_RIB_DETAILED) rib_dump ((struct prefix *)p, rib); } - rib_addnode (rn, rib); + rib_addnode (rn, rib, 1); /* Free implicit route.*/ if (same) @@ -2340,7 +2343,7 @@ rib_add_ipv4_multipath (struct prefix_ipv4 *p, struct rib *rib, safi_t safi) if (IS_ZEBRA_DEBUG_RIB_DETAILED) rib_dump ((struct prefix *)p, rib); } - rib_addnode (rn, rib); + rib_addnode (rn, rib, 1); ret = 1; /* Free implicit route.*/ @@ -2571,7 +2574,12 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro si->vrf_id, buf, p->prefixlen, rn, rib, rib->type); } } - rib_queue_add (&zebrad, rn); + /* Schedule route for processing or invoke NHT, as appropriate. */ + if (si->type == STATIC_IPV4_GATEWAY || + si->type == STATIC_IPV6_GATEWAY) + zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p); + else + rib_queue_add (&zebrad, rn); } else { @@ -2617,7 +2625,6 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro /* Save the flags of this static routes (reject, blackhole) */ rib->flags = si->flags; - /* Link this rib to the tree. */ if (IS_ZEBRA_DEBUG_RIB) { char buf[INET6_ADDRSTRLEN]; @@ -2628,7 +2635,17 @@ static_install_route (afi_t afi, safi_t safi, struct prefix *p, struct static_ro si->vrf_id, buf, p->prefixlen, rn, rib, rib->type); } } - rib_addnode (rn, rib); + /* Link this rib to the tree. Schedule for processing or invoke NHT, + * as appropriate. + */ + if (si->type == STATIC_IPV4_GATEWAY || + si->type == STATIC_IPV6_GATEWAY) + { + rib_addnode (rn, rib, 0); + zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p); + } + else + rib_addnode (rn, rib, 1); } } @@ -3026,7 +3043,7 @@ rib_add_ipv6 (int type, u_short instance, int flags, struct prefix_ipv6 *p, if (IS_ZEBRA_DEBUG_RIB_DETAILED) rib_dump ((struct prefix *)p, rib); } - rib_addnode (rn, rib); + rib_addnode (rn, rib, 1); /* Free implicit route.*/ if (same) @@ -3147,7 +3164,7 @@ rib_add_ipv6_multipath (struct prefix *p, struct rib *rib, safi_t safi, if (IS_ZEBRA_DEBUG_RIB_DETAILED) rib_dump ((struct prefix *)p, rib); } - rib_addnode (rn, rib); + rib_addnode (rn, rib, 1); ret = 1; /* Free implicit route.*/