diff options
Diffstat (limited to 'bgpd')
| -rw-r--r-- | bgpd/bgp_addpath.c | 32 | ||||
| -rw-r--r-- | bgpd/bgp_addpath.h | 9 | ||||
| -rw-r--r-- | bgpd/bgp_fsm.c | 3 | ||||
| -rw-r--r-- | bgpd/bgp_packet.c | 186 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 10 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 71 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 51 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 72 | 
8 files changed, 106 insertions, 328 deletions
diff --git a/bgpd/bgp_addpath.c b/bgpd/bgp_addpath.c index aada6e555f..030db4b28e 100644 --- a/bgpd/bgp_addpath.c +++ b/bgpd/bgp_addpath.c @@ -10,8 +10,6 @@  #include "bgp_addpath.h"  #include "bgp_route.h" -#include "bgp_open.h" -#include "bgp_packet.h"  static const struct bgp_addpath_strategy_names strat_names[BGP_ADDPATH_MAX] = {  	{ @@ -361,30 +359,6 @@ void bgp_addpath_type_changed(struct bgp *bgp)  	}  } -int bgp_addpath_capability_action(enum bgp_addpath_strat addpath_type, uint16_t paths) -{ -	int action = CAPABILITY_ACTION_UNSET; - -	switch (addpath_type) { -	case BGP_ADDPATH_ALL: -	case BGP_ADDPATH_BEST_PER_AS: -		action = CAPABILITY_ACTION_SET; -		break; -	case BGP_ADDPATH_BEST_SELECTED: -		if (paths) -			action = CAPABILITY_ACTION_SET; -		else -			action = CAPABILITY_ACTION_UNSET; -		break; -	case BGP_ADDPATH_NONE: -	case BGP_ADDPATH_MAX: -		action = CAPABILITY_ACTION_UNSET; -		break; -	} - -	return action; -} -  /*   * Change the addpath type assigned to a peer, or peer group. In addition to   * adjusting the counts, peer sessions will be reset as needed to make the @@ -398,7 +372,6 @@ void bgp_addpath_set_peer_type(struct peer *peer, afi_t afi, safi_t safi,  	struct listnode *node, *nnode;  	struct peer *tmp_peer;  	struct peer_group *group; -	int action = bgp_addpath_capability_action(addpath_type, paths);  	if (safi == SAFI_LABELED_UNICAST)  		safi = SAFI_UNICAST; @@ -456,12 +429,9 @@ void bgp_addpath_set_peer_type(struct peer *peer, afi_t afi, safi_t safi,  			}  		}  	} else { -		if (!CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV) && -		    !CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV)) -			peer_change_action(peer, afi, safi, peer_change_reset); +		peer_change_action(peer, afi, safi, peer_change_reset);  	} -	bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_ADDPATH, action);  }  /* diff --git a/bgpd/bgp_addpath.h b/bgpd/bgp_addpath.h index f1ff98ea7a..c136671ea4 100644 --- a/bgpd/bgp_addpath.h +++ b/bgpd/bgp_addpath.h @@ -15,11 +15,7 @@  #include "bgpd/bgp_table.h"  #include "lib/json.h" -struct bgp_addpath_capability { -	uint16_t afi; -	uint8_t safi; -	uint8_t flags; -}; +#define BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE 1  struct bgp_paths_limit_capability {  	uint16_t afi; @@ -27,8 +23,6 @@ struct bgp_paths_limit_capability {  	uint16_t paths_limit;  } __attribute__((packed)); -#define BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE 1 -  void bgp_addpath_init_bgp_data(struct bgp_addpath_bgp_data *d);  bool bgp_addpath_is_addpath_used(struct bgp_addpath_bgp_data *d, afi_t afi, @@ -68,5 +62,4 @@ void bgp_addpath_update_ids(struct bgp *bgp, struct bgp_dest *dest, afi_t afi,  			    safi_t safi);  void bgp_addpath_type_changed(struct bgp *bgp); -extern int bgp_addpath_capability_action(enum bgp_addpath_strat addpath_type, uint16_t paths);  #endif 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_packet.c b/bgpd/bgp_packet.c index ca2e8de041..f8726ffff9 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1218,7 +1218,6 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  	uint16_t len;  	uint32_t gr_restart_time;  	uint8_t addpath_afi_safi_count = 0; -	bool adv_addpath_tx = false;  	unsigned long number_of_orfs_p;  	uint8_t number_of_orfs = 0;  	const char *capability = lookup_msg(capcode_str, capability_code, @@ -1226,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; @@ -1383,87 +1385,6 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  		COND_FLAG(peer->cap, PEER_CAP_LLGR_ADV,  			  action == CAPABILITY_ACTION_SET);  		break; -	case CAPABILITY_CODE_ADDPATH: -		FOREACH_AFI_SAFI (afi, safi) { -			if (peer->afc[afi][safi]) { -				addpath_afi_safi_count++; - -				/* Only advertise addpath TX if a feature that -				* will use it is -				* configured */ -				if (peer->addpath_type[afi][safi] != -				    BGP_ADDPATH_NONE) -					adv_addpath_tx = true; - -				/* If we have enabled labeled unicast, we MUST check -				* against unicast SAFI because addpath IDs are -				* allocated under unicast SAFI, the same as the RIB -				* is managed in unicast SAFI. -				*/ -				if (safi == SAFI_LABELED_UNICAST) -					if (peer->addpath_type[afi][SAFI_UNICAST] != -					    BGP_ADDPATH_NONE) -						adv_addpath_tx = true; -			} -		} - -		stream_putc(s, action); -		stream_putc(s, CAPABILITY_CODE_ADDPATH); -		stream_putc(s, CAPABILITY_CODE_ADDPATH_LEN * -				       addpath_afi_safi_count); - -		FOREACH_AFI_SAFI (afi, safi) { -			if (peer->afc[afi][safi]) { -				bool adv_addpath_rx = -					!CHECK_FLAG(peer->af_flags[afi][safi], -						    PEER_FLAG_DISABLE_ADDPATH_RX); -				uint8_t flags = 0; - -				/* Convert AFI, SAFI to values for packet. */ -				bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, -							  &pkt_safi); - -				stream_putw(s, pkt_afi); -				stream_putc(s, pkt_safi); - -				if (adv_addpath_rx) { -					SET_FLAG(flags, BGP_ADDPATH_RX); -					SET_FLAG(peer->af_cap[afi][safi], -						 PEER_CAP_ADDPATH_AF_RX_ADV); -				} else { -					UNSET_FLAG(peer->af_cap[afi][safi], -						   PEER_CAP_ADDPATH_AF_RX_ADV); -				} - -				if (adv_addpath_tx) { -					SET_FLAG(flags, BGP_ADDPATH_TX); -					SET_FLAG(peer->af_cap[afi][safi], -						 PEER_CAP_ADDPATH_AF_TX_ADV); -					if (safi == SAFI_LABELED_UNICAST) -						SET_FLAG(peer->af_cap[afi] -								     [SAFI_UNICAST], -							 PEER_CAP_ADDPATH_AF_TX_ADV); -				} else { -					UNSET_FLAG(peer->af_cap[afi][safi], -						   PEER_CAP_ADDPATH_AF_TX_ADV); -				} - -				stream_putc(s, flags); -			} -		} - -		if (bgp_debug_neighbor_events(peer)) -			zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s", -				   peer, -				   action == CAPABILITY_ACTION_SET -					   ? "Advertising" -					   : "Removing", -				   capability, iana_afi2str(pkt_afi), -				   iana_safi2str(pkt_safi)); - -		COND_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV, -			  action == CAPABILITY_ACTION_SET); -		break;  	case CAPABILITY_CODE_PATHS_LIMIT:  		FOREACH_AFI_SAFI (afi, safi) {  			if (!peer->afc[afi][safi]) @@ -1619,6 +1540,7 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,  	case CAPABILITY_CODE_REFRESH:  	case CAPABILITY_CODE_AS4:  	case CAPABILITY_CODE_DYNAMIC: +	case CAPABILITY_CODE_ADDPATH:  	case CAPABILITY_CODE_ENHANCED_RR:  	case CAPABILITY_CODE_EXT_MESSAGE:  		break; @@ -3174,102 +3096,6 @@ static int bgp_route_refresh_receive(struct peer_connection *connection,  	return BGP_PACKET_NOOP;  } -static void bgp_dynamic_capability_addpath(uint8_t *pnt, int action, -					   struct capability_header *hdr, -					   struct peer *peer) -{ -	uint8_t *data = pnt + 3; -	uint8_t *end = data + hdr->length; -	size_t len = end - data; -	afi_t afi; -	safi_t safi; - -	if (action == CAPABILITY_ACTION_SET) { -		if (len % CAPABILITY_CODE_ADDPATH_LEN) { -			flog_warn(EC_BGP_CAPABILITY_INVALID_LENGTH, -				  "Add Path: Received invalid length %zu, non-multiple of 4", -				  len); -			return; -		} - -		SET_FLAG(peer->cap, PEER_CAP_ADDPATH_RCV); - -		while (data + CAPABILITY_CODE_ADDPATH_LEN <= end) { -			afi_t afi; -			safi_t safi; -			iana_afi_t pkt_afi; -			iana_safi_t pkt_safi; -			struct bgp_addpath_capability bac; - -			memcpy(&bac, data, sizeof(bac)); -			pkt_afi = ntohs(bac.afi); -			pkt_safi = safi_int2iana(bac.safi); - -			/* If any other value (other than 1-3) is received, -			 * then the capability SHOULD be treated as not -			 * understood and ignored. -			 */ -			if (!bac.flags || bac.flags > 3) { -				flog_warn(EC_BGP_CAPABILITY_INVALID_LENGTH, -					  "Add Path: Received invalid send/receive value %u in Add Path capability", -					  bac.flags); -				goto ignore; -			} - -			if (bgp_debug_neighbor_events(peer)) -				zlog_debug("%s OPEN has %s capability for afi/safi: %s/%s%s%s", -					   peer->host, lookup_msg(capcode_str, hdr->code, NULL), -					   iana_afi2str(pkt_afi), iana_safi2str(pkt_safi), -					   CHECK_FLAG(bac.flags, BGP_ADDPATH_RX) ? ", receive" : "", -					   CHECK_FLAG(bac.flags, BGP_ADDPATH_TX) ? ", transmit" -										 : ""); - -			if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, -						      &safi)) { -				if (bgp_debug_neighbor_events(peer)) -					zlog_debug("%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI", -						   peer->host, -						   iana_afi2str(pkt_afi), -						   iana_safi2str(pkt_safi)); -				goto ignore; -			} else if (!peer->afc[afi][safi]) { -				if (bgp_debug_neighbor_events(peer)) -					zlog_debug("%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI", -						   peer->host, -						   iana_afi2str(pkt_afi), -						   iana_safi2str(pkt_safi)); -				goto ignore; -			} - -			if (CHECK_FLAG(bac.flags, BGP_ADDPATH_RX)) -				SET_FLAG(peer->af_cap[afi][safi], -					 PEER_CAP_ADDPATH_AF_RX_RCV); -			else -				UNSET_FLAG(peer->af_cap[afi][safi], -					   PEER_CAP_ADDPATH_AF_RX_RCV); - -			if (CHECK_FLAG(bac.flags, BGP_ADDPATH_TX)) -				SET_FLAG(peer->af_cap[afi][safi], -					 PEER_CAP_ADDPATH_AF_TX_RCV); -			else -				UNSET_FLAG(peer->af_cap[afi][safi], -					   PEER_CAP_ADDPATH_AF_TX_RCV); - -ignore: -			data += CAPABILITY_CODE_ADDPATH_LEN; -		} -	} else { -		FOREACH_AFI_SAFI (afi, safi) { -			UNSET_FLAG(peer->af_cap[afi][safi], -				   PEER_CAP_ADDPATH_AF_RX_RCV); -			UNSET_FLAG(peer->af_cap[afi][safi], -				   PEER_CAP_ADDPATH_AF_TX_RCV); -		} - -		UNSET_FLAG(peer->cap, PEER_CAP_ADDPATH_RCV); -	} -} -  static void bgp_dynamic_capability_paths_limit(uint8_t *pnt, int action,  					       struct capability_header *hdr,  					       struct peer *peer) @@ -4030,9 +3856,6 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,  		case CAPABILITY_CODE_LLGR:  			bgp_dynamic_capability_llgr(pnt, action, hdr, peer);  			break; -		case CAPABILITY_CODE_ADDPATH: -			bgp_dynamic_capability_addpath(pnt, action, hdr, peer); -			break;  		case CAPABILITY_CODE_PATHS_LIMIT:  			bgp_dynamic_capability_paths_limit(pnt, action, hdr,  							   peer); @@ -4046,6 +3869,7 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,  		case CAPABILITY_CODE_REFRESH:  		case CAPABILITY_CODE_AS4:  		case CAPABILITY_CODE_DYNAMIC: +		case CAPABILITY_CODE_ADDPATH:  		case CAPABILITY_CODE_ENHANCED_RR:  		case CAPABILITY_CODE_EXT_MESSAGE:  			break; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 672c43b37c..f2e61e1e7f 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -10951,6 +10951,12 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,  		else  			vty_out(vty, ", (stale)");  	} +	if (bgp_path_suppressed(path)) { +		if (json_paths) +			json_object_boolean_true_add(json_path, "suppressed"); +		else +			vty_out(vty, ", (suppressed)"); +	}  	if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {  		if (json_paths) { @@ -15239,7 +15245,7 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,  				if (type == bgp_show_adj_route_advertised ||  				    type == bgp_show_adj_route_received) {  					if (first) { -						vty_out(vty, "\"%s\":", rd_str); +						vty_out(vty, "{\"%s\":", rd_str);  						first = false;  					} else {  						vty_out(vty, ",\"%s\":", rd_str); @@ -15253,6 +15259,8 @@ static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,  			output_count += output_count_per_rd;  			filtered_count += filtered_count_per_rd;  		} +		if (first == false && json_routes) +			vty_out(vty, "}");  	} else {  		show_adj_route(vty, peer, table, afi, safi, type, rmap_name,  			       json, json_ar, show_flags, &header1, &header2, diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 2b3e11929b..046b18f224 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -9206,21 +9206,12 @@ DEFUN(neighbor_disable_addpath_rx,  	struct peer *peer;  	afi_t afi = bgp_node_afi(vty);  	safi_t safi = bgp_node_safi(vty); -	int ret; -	int action;  	peer = peer_and_group_lookup_vty(vty, peer_str);  	if (!peer)  		return CMD_WARNING_CONFIG_FAILED; -	action = bgp_addpath_capability_action(peer->addpath_type[afi][safi], 0); - -	ret = peer_af_flag_set_vty(vty, peer_str, afi, safi, -				   PEER_FLAG_DISABLE_ADDPATH_RX); - -	bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_ADDPATH, action); - -	return ret; +	return peer_af_flag_set_vty(vty, peer_str, afi, safi, PEER_FLAG_DISABLE_ADDPATH_RX);  }  DEFUN(no_neighbor_disable_addpath_rx, @@ -9235,21 +9226,12 @@ DEFUN(no_neighbor_disable_addpath_rx,  	struct peer *peer;  	afi_t afi = bgp_node_afi(vty);  	safi_t safi = bgp_node_safi(vty); -	int ret; -	int action;  	peer = peer_and_group_lookup_vty(vty, peer_str);  	if (!peer)  		return CMD_WARNING_CONFIG_FAILED; -	action = bgp_addpath_capability_action(peer->addpath_type[afi][safi], 0); - -	ret = peer_af_flag_unset_vty(vty, peer_str, afi, safi, -				     PEER_FLAG_DISABLE_ADDPATH_RX); - -	bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_ADDPATH, action); - -	return ret; +	return peer_af_flag_unset_vty(vty, peer_str, afi, safi, PEER_FLAG_DISABLE_ADDPATH_RX);  }  DEFUN (neighbor_addpath_tx_all_paths, @@ -9261,15 +9243,12 @@ DEFUN (neighbor_addpath_tx_all_paths,  {  	int idx_peer = 1;  	struct peer *peer; -	afi_t afi = bgp_node_afi(vty); -	safi_t safi = bgp_node_safi(vty);  	peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);  	if (!peer)  		return CMD_WARNING_CONFIG_FAILED; -	bgp_addpath_set_peer_type(peer, afi, safi, BGP_ADDPATH_ALL, 0); - +	bgp_addpath_set_peer_type(peer, bgp_node_afi(vty), bgp_node_safi(vty), BGP_ADDPATH_ALL, 0);  	return CMD_SUCCESS;  } @@ -9289,20 +9268,18 @@ DEFUN (no_neighbor_addpath_tx_all_paths,  {  	int idx_peer = 2;  	struct peer *peer; -	afi_t afi = bgp_node_afi(vty); -	safi_t safi = bgp_node_safi(vty);  	peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);  	if (!peer)  		return CMD_WARNING_CONFIG_FAILED; -	if (peer->addpath_type[afi][safi] != BGP_ADDPATH_ALL) { +	if (peer->addpath_type[bgp_node_afi(vty)][bgp_node_safi(vty)] != BGP_ADDPATH_ALL) {  		vty_out(vty,  			"%% Peer not currently configured to transmit all paths.");  		return CMD_WARNING_CONFIG_FAILED;  	} -	bgp_addpath_set_peer_type(peer, afi, safi, BGP_ADDPATH_NONE, 0); +	bgp_addpath_set_peer_type(peer, bgp_node_afi(vty), bgp_node_safi(vty), BGP_ADDPATH_NONE, 0);  	return CMD_SUCCESS;  } @@ -17598,12 +17575,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; @@ -17657,12 +17628,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; @@ -17720,12 +17685,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; @@ -17790,12 +17749,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; @@ -17865,13 +17818,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) { @@ -17934,12 +17881,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; diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 8e8616c155..179404a2ce 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -2042,11 +2042,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 +2197,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 d5463f3d0c..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); @@ -4820,39 +4823,40 @@ static const struct peer_flag_action peer_flag_action_list[] = {  	{0, 0, 0}};  static const struct peer_flag_action peer_af_flag_action_list[] = { -	{PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out}, -	{PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out}, -	{PEER_FLAG_SEND_LARGE_COMMUNITY, 1, peer_change_reset_out}, -	{PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out}, -	{PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset}, -	{PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset}, -	{PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in}, -	{PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out}, -	{PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out}, -	{PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out}, -	{PEER_FLAG_DEFAULT_ORIGINATE, 0, peer_change_none}, -	{PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out}, -	{PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in}, -	{PEER_FLAG_ALLOWAS_IN_ORIGIN, 0, peer_change_reset_in}, -	{PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset}, -	{PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset}, -	{PEER_FLAG_MAX_PREFIX, 0, peer_change_none}, -	{PEER_FLAG_MAX_PREFIX_WARNING, 0, peer_change_none}, -	{PEER_FLAG_MAX_PREFIX_FORCE, 0, peer_change_none}, -	{PEER_FLAG_MAX_PREFIX_OUT, 0, peer_change_none}, -	{PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out}, -	{PEER_FLAG_FORCE_NEXTHOP_SELF, 1, peer_change_reset_out}, -	{PEER_FLAG_REMOVE_PRIVATE_AS_ALL, 1, peer_change_reset_out}, -	{PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE, 1, peer_change_reset_out}, -	{PEER_FLAG_AS_OVERRIDE, 1, peer_change_reset_out}, -	{PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE, 1, peer_change_reset_out}, -	{PEER_FLAG_WEIGHT, 0, peer_change_reset_in}, -	{PEER_FLAG_DISABLE_ADDPATH_RX, 0, peer_change_none}, -	{PEER_FLAG_SOO, 0, peer_change_reset}, -	{PEER_FLAG_ACCEPT_OWN, 0, peer_change_reset}, -	{PEER_FLAG_SEND_EXT_COMMUNITY_RPKI, 1, peer_change_reset_out}, -	{PEER_FLAG_ADDPATH_RX_PATHS_LIMIT, 0, peer_change_none}, -	{0, 0, 0}}; +	{ PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out }, +	{ PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out }, +	{ PEER_FLAG_SEND_LARGE_COMMUNITY, 1, peer_change_reset_out }, +	{ PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out }, +	{ PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset }, +	{ PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset }, +	{ PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in }, +	{ PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out }, +	{ PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out }, +	{ PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out }, +	{ PEER_FLAG_DEFAULT_ORIGINATE, 0, peer_change_none }, +	{ PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out }, +	{ PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in }, +	{ PEER_FLAG_ALLOWAS_IN_ORIGIN, 0, peer_change_reset_in }, +	{ PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset }, +	{ PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset }, +	{ PEER_FLAG_MAX_PREFIX, 0, peer_change_none }, +	{ PEER_FLAG_MAX_PREFIX_WARNING, 0, peer_change_none }, +	{ PEER_FLAG_MAX_PREFIX_FORCE, 0, peer_change_none }, +	{ PEER_FLAG_MAX_PREFIX_OUT, 0, peer_change_none }, +	{ PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out }, +	{ PEER_FLAG_FORCE_NEXTHOP_SELF, 1, peer_change_reset_out }, +	{ PEER_FLAG_REMOVE_PRIVATE_AS_ALL, 1, peer_change_reset_out }, +	{ PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE, 1, peer_change_reset_out }, +	{ PEER_FLAG_AS_OVERRIDE, 1, peer_change_reset_out }, +	{ PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE, 1, peer_change_reset_out }, +	{ PEER_FLAG_WEIGHT, 0, peer_change_reset_in }, +	{ PEER_FLAG_DISABLE_ADDPATH_RX, 0, peer_change_reset }, +	{ PEER_FLAG_SOO, 0, peer_change_reset }, +	{ PEER_FLAG_ACCEPT_OWN, 0, peer_change_reset }, +	{ PEER_FLAG_SEND_EXT_COMMUNITY_RPKI, 1, peer_change_reset_out }, +	{ PEER_FLAG_ADDPATH_RX_PATHS_LIMIT, 0, peer_change_none }, +	{ 0, 0, 0 } +};  /* Proper action set. */  static int peer_flag_action_set(const struct peer_flag_action *action_list,  | 
