diff options
Diffstat (limited to 'bgpd')
| -rw-r--r-- | bgpd/bgp_fsm.c | 3 | ||||
| -rw-r--r-- | bgpd/bgp_nht.c | 19 | ||||
| -rw-r--r-- | bgpd/bgp_packet.c | 3 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 6 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 53 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 73 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 5 | 
7 files changed, 107 insertions, 55 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 0e3ed9f0d1..1a30cb37f4 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -2163,6 +2163,9 @@ bgp_establish(struct peer_connection *connection)  	peer->established++;  	bgp_fsm_change_status(connection, Established); +	if (peer->last_reset == PEER_DOWN_WAITING_OPEN) +		peer->last_reset = 0; +  	/* bgp log-neighbor-changes of neighbor Up */  	if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {  		struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id); diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 164e2300c0..2ef7ec97e3 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -1278,6 +1278,25 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc)  	}  	LIST_FOREACH (path, &(bnc->paths), nh_thread) { +		/* +		 * Currently when a peer goes down, bgp immediately +		 * sees this via the interface events( if it is directly +		 * connected).  And in this case it takes and puts on +		 * a special peer queue all path info's associated with +		 * but these items are not yet processed typically when +		 * the nexthop is being handled here.  Thus we end +		 * up in a situation where the process Queue for BGP +		 * is being asked to look at the same path info multiple +		 * times.  Let's just cut to the chase here and if +		 * the bnc has a peer associated with it and the path info +		 * being looked at uses that peer and the peer is no +		 * longer established we know the path_info is being +		 * handled elsewhere and we do not need to process +		 * it here at all since the pathinfo is going away +		 */ +		if (peer && path->peer == peer && !peer_established(peer->connection)) +			continue; +  		if (path->type == ZEBRA_ROUTE_BGP &&  		    (path->sub_type == BGP_ROUTE_NORMAL ||  		     path->sub_type == BGP_ROUTE_STATIC || diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 0780b4f72d..f8726ffff9 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1225,6 +1225,9 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  	const char *hostname = cmd_hostname_get();  	const char *domainname = cmd_domainname_get(); +	if (!peer) +		return; +  	if (!peer_established(peer->connection))  		return; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index f2e61e1e7f..e932738cd4 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3885,6 +3885,12 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,  					 BGP_PATH_ATTR_CHANGED);  		UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);  		UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG); +	} else { +		/* +		 * Ensure that on uninstall that the INSTALL_PENDING +		 * is no longer set +		 */ +		UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);  	}  	/* call bmp hook for loc-rib route update / withdraw after flags were diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 04b9ce5ea6..e18f6443b5 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -122,6 +122,9 @@ FRR_CFG_DEFAULT_BOOL(BGP_ENFORCE_FIRST_AS,  	{ .val_bool = false, .match_version = "< 9.1", },  	{ .val_bool = true },  ); +FRR_CFG_DEFAULT_BOOL(BGP_RR_ALLOW_OUTBOUND_POLICY, +	{ .val_bool = false }, +);  DEFINE_HOOK(bgp_inst_config_write,  		(struct bgp *bgp, struct vty *vty), @@ -622,6 +625,8 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,  				 BGP_FLAG_DYNAMIC_CAPABILITY);  		if (DFLT_BGP_ENFORCE_FIRST_AS)  			SET_FLAG((*bgp)->flags, BGP_FLAG_ENFORCE_FIRST_AS); +		if (DFLT_BGP_RR_ALLOW_OUTBOUND_POLICY) +			SET_FLAG((*bgp)->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);  		ret = BGP_SUCCESS;  	} @@ -17575,12 +17580,6 @@ DEFUN (bgp_redistribute_ipv4_ospf,  	if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)  		protocol = ZEBRA_ROUTE_OSPF;  	else { -		if (bgp->vrf_id != VRF_DEFAULT) { -			vty_out(vty, -				"%% Only default BGP instance can use '%s'\n", -				argv[idx_ospf_table]->arg); -			return CMD_WARNING_CONFIG_FAILED; -		}  		if (strncmp(argv[idx_ospf_table]->arg, "table-direct",  			    strlen("table-direct")) == 0) {  			protocol = ZEBRA_ROUTE_TABLE_DIRECT; @@ -17634,12 +17633,6 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap,  	if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)  		protocol = ZEBRA_ROUTE_OSPF;  	else { -		if (bgp->vrf_id != VRF_DEFAULT) { -			vty_out(vty, -				"%% Only default BGP instance can use '%s'\n", -				argv[idx_ospf_table]->arg); -			return CMD_WARNING_CONFIG_FAILED; -		}  		if (strncmp(argv[idx_ospf_table]->arg, "table-direct",  			    strlen("table-direct")) == 0) {  			protocol = ZEBRA_ROUTE_TABLE_DIRECT; @@ -17697,12 +17690,6 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric,  	if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)  		protocol = ZEBRA_ROUTE_OSPF;  	else { -		if (bgp->vrf_id != VRF_DEFAULT) { -			vty_out(vty, -				"%% Only default BGP instance can use '%s'\n", -				argv[idx_ospf_table]->arg); -			return CMD_WARNING_CONFIG_FAILED; -		}  		if (strncmp(argv[idx_ospf_table]->arg, "table-direct",  			    strlen("table-direct")) == 0) {  			protocol = ZEBRA_ROUTE_TABLE_DIRECT; @@ -17767,12 +17754,6 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric,  	if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)  		protocol = ZEBRA_ROUTE_OSPF;  	else { -		if (bgp->vrf_id != VRF_DEFAULT) { -			vty_out(vty, -				"%% Only default BGP instance can use '%s'\n", -				argv[idx_ospf_table]->arg); -			return CMD_WARNING_CONFIG_FAILED; -		}  		if (strncmp(argv[idx_ospf_table]->arg, "table-direct",  			    strlen("table-direct")) == 0) {  			protocol = ZEBRA_ROUTE_TABLE_DIRECT; @@ -17842,13 +17823,7 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap,  	if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)  		protocol = ZEBRA_ROUTE_OSPF;  	else { -		if (bgp->vrf_id != VRF_DEFAULT) { -			vty_out(vty, -				"%% Only default BGP instance can use '%s'\n", -				argv[idx_ospf_table]->arg); -			return CMD_WARNING_CONFIG_FAILED; -		} else if (strncmp(argv[idx_ospf_table]->arg, "table-direct", -				   strlen("table-direct")) == 0) { +		if (strncmp(argv[idx_ospf_table]->arg, "table-direct", strlen("table-direct")) == 0) {  			protocol = ZEBRA_ROUTE_TABLE_DIRECT;  			if (instance == RT_TABLE_MAIN ||  			    instance == RT_TABLE_LOCAL) { @@ -17911,12 +17886,6 @@ DEFUN (no_bgp_redistribute_ipv4_ospf,  	if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)  		protocol = ZEBRA_ROUTE_OSPF;  	else { -		if (bgp->vrf_id != VRF_DEFAULT) { -			vty_out(vty, -				"%% Only default BGP instance can use '%s'\n", -				argv[idx_ospf_table]->arg); -			return CMD_WARNING_CONFIG_FAILED; -		}  		if (strncmp(argv[idx_ospf_table]->arg, "table-direct",  			    strlen("table-direct")) == 0) {  			protocol = ZEBRA_ROUTE_TABLE_DIRECT; @@ -19816,10 +19785,12 @@ int bgp_config_write(struct vty *vty)  			}  		} -		if (CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) { -			vty_out(vty, -				" bgp route-reflector allow-outbound-policy\n"); -		} +		if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY) != +		    SAVE_BGP_RR_ALLOW_OUTBOUND_POLICY) +			vty_out(vty, " %sbgp route-reflector allow-outbound-policy\n", +				CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY) ? "" +											  : "no "); +  		if (CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID))  			vty_out(vty, " bgp bestpath compare-routerid\n");  		if (CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP)) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 8e8616c155..1669aabc60 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1674,11 +1674,23 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)  	for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))  		for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)  			if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) && -			    (pi->type == ZEBRA_ROUTE_BGP -			     && (pi->sub_type == BGP_ROUTE_NORMAL -				 || pi->sub_type == BGP_ROUTE_IMPORTED))) -				bgp_zebra_route_install(dest, pi, bgp, true, -							NULL, false); +			    (pi->type == ZEBRA_ROUTE_BGP && (pi->sub_type == BGP_ROUTE_NORMAL || +							     pi->sub_type == BGP_ROUTE_IMPORTED))) { +				bool is_add = true; + +				if (bgp->table_map[afi][safi].name) { +					struct attr local_attr = *pi->attr; +					struct bgp_path_info local_info = *pi; + +					local_info.attr = &local_attr; + +					is_add = bgp_table_map_apply(bgp->table_map[afi][safi].map, +								     bgp_dest_get_prefix(dest), +								     &local_info); +				} + +				bgp_zebra_route_install(dest, pi, bgp, is_add, NULL, false); +			}  }  /* Announce routes of any bgp subtype of a table to zebra */ @@ -2042,11 +2054,34 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,  	/* Return if already redistribute flag is set. */  	if (instance) { -		if (redist_check_instance(&zclient->mi_redist[afi][type], -					  instance)) -			return CMD_WARNING; +		if (type == ZEBRA_ROUTE_TABLE_DIRECT) { +			/* +			 * When redistribution type is `table-direct` the +			 * instance means `table identification`. +			 * +			 * `table_id` support 32bit integers, however since +			 * `instance` is being overloaded to `table_id` it +			 * will only be possible to use the first 65535 +			 * entries. +			 * +			 * Also the ZAPI must also support `int` +			 * (see `zebra_redistribute_add`). +			 */ +			struct redist_table_direct table = { +				.table_id = instance, +				.vrf_id = bgp->vrf_id, +			}; +			if (redist_lookup_table_direct(&zclient->mi_redist[afi][type], &table) != +			    NULL) +				return CMD_WARNING; + +			redist_add_table_direct(&zclient->mi_redist[afi][type], &table); +		} else { +			if (redist_check_instance(&zclient->mi_redist[afi][type], instance)) +				return CMD_WARNING; -		redist_add_instance(&zclient->mi_redist[afi][type], instance); +			redist_add_instance(&zclient->mi_redist[afi][type], instance); +		}  	} else {  		if (vrf_bitmap_check(&zclient->redist[afi][type], bgp->vrf_id))  			return CMD_WARNING; @@ -2174,10 +2209,22 @@ int bgp_redistribute_unreg(struct bgp *bgp, afi_t afi, int type,  	/* Return if zebra connection is disabled. */  	if (instance) { -		if (!redist_check_instance(&zclient->mi_redist[afi][type], -					   instance)) -			return CMD_WARNING; -		redist_del_instance(&zclient->mi_redist[afi][type], instance); +		if (type == ZEBRA_ROUTE_TABLE_DIRECT) { +			struct redist_table_direct table = { +				.table_id = instance, +				.vrf_id = bgp->vrf_id, +			}; +			if (redist_lookup_table_direct(&zclient->mi_redist[afi][type], &table) == +			    NULL) +				return CMD_WARNING; + +			redist_del_table_direct(&zclient->mi_redist[afi][type], &table); +		} else { +			if (!redist_check_instance(&zclient->mi_redist[afi][type], instance)) +				return CMD_WARNING; + +			redist_del_instance(&zclient->mi_redist[afi][type], instance); +		}  	} else {  		if (!vrf_bitmap_check(&zclient->redist[afi][type], bgp->vrf_id))  			return CMD_WARNING; diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 6de403b30c..edf90d3dd8 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2026,8 +2026,11 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,  	if (bgp->autoshutdown)  		peer_flag_set(peer, PEER_FLAG_SHUTDOWN);  	/* Set up peer's events and timers. */ -	else if (!active && peer_active(peer->connection)) +	else if (!active && peer_active(peer->connection)) { +		if (peer->last_reset == PEER_DOWN_NOAFI_ACTIVATED) +			peer->last_reset = 0;  		bgp_timer_set(peer->connection); +	}  	bgp_peer_gr_flags_update(peer);  	BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp, bgp->peer);  | 
