From 2ec1e66ff18df311ec5ed3a94a84b2e709f5441c Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Mon, 7 Dec 2015 11:56:02 -0800 Subject: [PATCH 1/4] BGP bestpath debugs need to display the addpath RX ID Signed-off-by: Daniel Walton Reviewed-by: Donald Sharp Ticket: CM-8459 Output with fix 2015/12/07 09:47:41.342932 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) and path 10.0.0.7 (addpath rxid 2) are equal via matching aspaths 2015/12/07 09:47:41.342966 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) wins over path 10.0.0.7 (addpath rxid 2) due to Router-ID comparison 2015/12/07 09:47:41.342978 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.342988 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.342999 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343008 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343019 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343029 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343039 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343048 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343058 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) is the bestpath from AS 0 2015/12/07 09:47:41.343068 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) is the initial bestpath 2015/12/07 09:47:41.343077 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) is the bestpath, now find multipaths 2015/12/07 09:47:41.343088 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 2) has the same nexthop as the bestpath, skip it 2015/12/07 09:47:41.343097 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) is the bestpath, add to the multipath list 2015/12/07 09:47:41.343109 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343119 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343127 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) is equivalent to the bestpath, add to the multipath list 2015/12/07 09:47:41.343139 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343164 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343173 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) is equivalent to the bestpath, add to the multipath list 2015/12/07 09:47:41.343186 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343196 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343205 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) is equivalent to the bestpath, add to the multipath list 2015/12/07 09:47:41.343217 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343227 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343236 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) is equivalent to the bestpath, add to the multipath list 2015/12/07 09:47:41.343254 BGP: 1.1.1.1/32 add mpath nexthop 34.34.34.34 path 10.0.0.7 (addpath rxid 4) 2015/12/07 09:47:41.343268 BGP: 1.1.1.1/32 add mpath nexthop 56.56.56.56 path 10.0.0.7 (addpath rxid 6) --- bgpd/bgp_mpath.c | 37 ++++---- bgpd/bgp_route.c | 228 +++++++++++++++++++++++++---------------------- bgpd/bgp_route.h | 4 + 3 files changed, 147 insertions(+), 122 deletions(-) diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c index cf92bb1514..f7b13f5278 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 = BGP_DEFAULT_MAXPATHS; @@ -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 *); From b6120505946e08951fdd9adf8539940777cdb635 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Mon, 7 Dec 2015 13:05:34 -0800 Subject: [PATCH 2/4] Enable IPv6 ND RA for interfaces that have an IPv6 address Signed-off-by: Daniel Walton Reviewed-by: Donald Sharp Ticket: CM-7932 --- zebra/Makefile.am | 2 +- zebra/connected.c | 8 +++++ zebra/interface.c | 20 +++++++++++ zebra/interface.h | 1 + zebra/rtadv.c | 87 +++++++++++++++++++++++++++------------------- zebra/rtadv.h | 6 ++++ zebra/rtadv_null.c | 27 ++++++++++++++ 7 files changed, 115 insertions(+), 36 deletions(-) create mode 100644 zebra/rtadv_null.c diff --git a/zebra/Makefile.am b/zebra/Makefile.am index 1526a9772a..8246e0b88c 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; } From cc81cf68da6ab43769112b50cb7faf3d6b333674 Mon Sep 17 00:00:00 2001 From: Daniel Walton Date: Tue, 8 Dec 2015 18:30:55 +0000 Subject: [PATCH 3/4] BGP: update-group needs to consider addpath capability flags Signed-off-by: Daniel Walton Reviewed-by: Donald Sharp Ticket: CM-8475 --- bgpd/bgp_updgrp.h | 2 ++ 1 file changed, 2 insertions(+) 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 From 2bf26d4184cd6b6fdea42629725cd2005f8bef47 Mon Sep 17 00:00:00 2001 From: vivek Date: Tue, 8 Dec 2015 15:04:48 -0800 Subject: [PATCH 4/4] Zebra: Eliminate unnecessary del-add upon static route addition When static routes are added, they get processed and potentially installed in the RIB once. Subsequently, NHT is invoked and ends up scheduling the route for processing again because this is the first time the nexthop is resolved for NHT. This used to result in a del-add earlier (as noted in the defect), but is a replace now. This change eliminates the unnecessary replace by ensuring NHT is invoked first if the static route has a nexthop that will be tracked by NHT. Signed-off-by: Vivek Venkatraman Reviewed-by: Donald Sharp Reviewed-by: Dinesh Dutt Ticket: CM-4573 Reviewed By: CCR-3903 Testing Done: Manual and bgpsmoke Note: Updates/improves static route NHT patch(es). --- zebra/zebra_rib.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 25166dea21..87425cb4b9 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1914,7 +1914,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; @@ -1949,7 +1949,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 : @@ -1960,7 +1963,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.. @@ -1970,7 +1973,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); } /* @@ -2153,7 +2156,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) @@ -2396,7 +2399,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.*/ @@ -2630,7 +2633,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 { @@ -2679,7 +2687,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]; @@ -2690,7 +2697,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); } } @@ -3095,7 +3112,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) @@ -3216,7 +3233,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.*/