diff options
| -rw-r--r-- | bgpd/bgp_orr.c | 72 | ||||
| -rw-r--r-- | lib/orr_msg.h | 3 | ||||
| -rw-r--r-- | ospfd/ospf_orr.c | 88 | ||||
| -rw-r--r-- | ospfd/ospf_orr.h | 9 | ||||
| -rw-r--r-- | ospfd/ospf_route.c | 4 | ||||
| -rw-r--r-- | ospfd/ospf_route.h | 3 | ||||
| -rw-r--r-- | ospfd/ospf_spf.c | 9 | 
7 files changed, 146 insertions, 42 deletions
diff --git a/bgpd/bgp_orr.c b/bgpd/bgp_orr.c index 894eae687f..81e6da2449 100644 --- a/bgpd/bgp_orr.c +++ b/bgpd/bgp_orr.c @@ -159,7 +159,6 @@ static void bgp_orr_group_free(struct bgp_orr_group *orr_group)  	/* Unset ORR Group parameters */  	XFREE(MTYPE_BGP_ORR_GROUP_NAME, orr_group->name); -	memset(orr_group, 0, sizeof(struct bgp_orr_group));  	listnode_delete(bgp->orr_group[afi][safi], orr_group);  	XFREE(MTYPE_BGP_ORR_GROUP, orr_group); @@ -933,6 +932,7 @@ static int bgp_orr_igp_metric_update(struct orr_igp_metric_info *table)  {  	afi_t afi;  	safi_t safi; +	bool add = false;  	bool root_found = false;  	uint32_t instId = 0;  	uint32_t numEntries = 0; @@ -943,7 +943,7 @@ static int bgp_orr_igp_metric_update(struct orr_igp_metric_info *table)  	struct list *orr_group_list = NULL;  	struct bgp_orr_group *group = NULL; -	struct listnode *node; +	struct listnode *node, *nnode;  	struct bgp_orr_igp_metric *igp_metric = NULL;  	struct list *bgp_orr_igp_metric = NULL; @@ -955,6 +955,7 @@ static int bgp_orr_igp_metric_update(struct orr_igp_metric_info *table)  	afi = family2afi(table->root.family);  	safi = table->safi;  	instId = table->instId; +	add = table->add;  	numEntries = table->num_entries;  	prefix_copy(&root, &table->root); @@ -985,8 +986,8 @@ static int bgp_orr_igp_metric_update(struct orr_igp_metric_info *table)  		zlog_debug("[BGP-ORR] %s: Address family %s", __func__,  			   get_afi_safi_str(afi, safi, false));  		zlog_debug("[BGP-ORR] %s: Root %pFX", __func__, &root); -		zlog_debug("[BGP-ORR] %s: Number of entries %d", __func__, -			   numEntries); +		zlog_debug("[BGP-ORR] %s: Number of entries to be %s %d", +			   __func__, add ? "added" : "deleted", numEntries);  		zlog_debug("[BGP-ORR] %s: Prefix (Cost) :", __func__);  		for (entry = 0; entry < numEntries; entry++)  			zlog_debug("[BGP-ORR] %s: %pFX (%d)", __func__, @@ -1007,27 +1008,52 @@ static int bgp_orr_igp_metric_update(struct orr_igp_metric_info *table)  		 * group  		 */  		if (prefix_cmp(&pfx, &root) == 0) { -			if (!group->igp_metric_info) -				group->igp_metric_info = list_new(); - -			bgp_orr_igp_metric = group->igp_metric_info; -			if (!bgp_orr_igp_metric) -				bgp_orr_igp_metric_register(group, false); -			assert(bgp_orr_igp_metric); - -			for (entry = 0; entry < numEntries; entry++) { -				igp_metric = XCALLOC( -					MTYPE_ORR_IGP_INFO, -					sizeof(struct bgp_orr_igp_metric)); -				if (!igp_metric) +			if (add) { +				/* Add new routes */ +				if (!group->igp_metric_info) +					group->igp_metric_info = list_new(); + +				bgp_orr_igp_metric = group->igp_metric_info; +				if (!bgp_orr_igp_metric)  					bgp_orr_igp_metric_register(group,  								    false); - -				prefix_copy(&igp_metric->prefix, -					    &table->nexthop[entry].prefix); -				igp_metric->igp_metric = -					table->nexthop[entry].metric; -				listnode_add(bgp_orr_igp_metric, igp_metric); +				assert(bgp_orr_igp_metric); + +				for (entry = 0; entry < numEntries; entry++) { +					igp_metric = XCALLOC( +						MTYPE_ORR_IGP_INFO, +						sizeof(struct +						       bgp_orr_igp_metric)); +					if (!igp_metric) +						bgp_orr_igp_metric_register( +							group, false); + +					prefix_copy( +						&igp_metric->prefix, +						&table->nexthop[entry].prefix); +					igp_metric->igp_metric = +						table->nexthop[entry].metric; +					listnode_add(bgp_orr_igp_metric, +						     igp_metric); +				} +			} else { +				/* Delete old routes */ +				for (entry = 0; entry < numEntries; entry++) { +					for (ALL_LIST_ELEMENTS( +						     group->igp_metric_info, +						     node, nnode, igp_metric)) { +						if (prefix_cmp( +							    &igp_metric->prefix, +							    &table->nexthop[entry] +								     .prefix)) +							continue; +						listnode_delete( +							group->igp_metric_info, +							igp_metric); +						XFREE(MTYPE_ORR_IGP_INFO, +						      igp_metric); +					} +				}  			}  			root_found = true;  			break; diff --git a/lib/orr_msg.h b/lib/orr_msg.h index ec13df61bb..b0c4c48df8 100644 --- a/lib/orr_msg.h +++ b/lib/orr_msg.h @@ -51,6 +51,9 @@ struct orr_igp_metric_info {  	safi_t safi; +	/* Add or delete routes */ +	bool add; +  	/* IGP metric from Active Root. */  	struct prefix root;  	uint32_t num_entries; diff --git a/ospfd/ospf_orr.c b/ospfd/ospf_orr.c index 41e2c8e2df..09dd5970ee 100644 --- a/ospfd/ospf_orr.c +++ b/ospfd/ospf_orr.c @@ -258,8 +258,8 @@ int ospf_orr_igp_metric_register(struct orr_igp_metric_reg msg)  	return 0;  } -void ospf_orr_igp_metric_send_update(struct orr_root *root, -				     unsigned short instance) +void ospf_orr_igp_metric_send_update_add(struct orr_root *root, +					 unsigned short instance)  {  	int ret;  	uint8_t count = 0; @@ -271,8 +271,8 @@ void ospf_orr_igp_metric_send_update(struct orr_root *root,  	msg.proto = ZEBRA_ROUTE_OSPF;  	msg.safi = root->safi;  	msg.instId = instance; +	msg.add = true;  	prefix_copy(&msg.root, &root->prefix); -	msg.num_entries = root->new_table->count;  	/* Update prefix table from ORR Route table */  	for (rn = route_top(root->new_table); rn; rn = route_next(rn)) { @@ -280,7 +280,8 @@ void ospf_orr_igp_metric_send_update(struct orr_root *root,  		if (!or)  			continue; -		if (or->type != OSPF_DESTINATION_NETWORK) +		if (or->type != OSPF_DESTINATION_NETWORK && +		    or->type != OSPF_DESTINATION_DISCARD)  			continue;  		if (ospf_route_match_same(root->old_table, @@ -318,6 +319,74 @@ void ospf_orr_igp_metric_send_update(struct orr_root *root,  	}  } +void ospf_orr_igp_metric_send_update_delete(struct orr_root *root, +					    unsigned short instance) +{ +	int ret; +	uint8_t count = 0; +	struct route_node *rn; +	struct ospf_route *or ; +	struct orr_igp_metric_info msg; + +	if (!root->old_table) +		return; + +	memset(&msg, 0, sizeof(msg)); +	msg.proto = ZEBRA_ROUTE_OSPF; +	msg.instId = instance; +	msg.safi = root->safi; +	msg.add = false; +	prefix_copy(&msg.root, &root->prefix); + +	/* Update prefix table from ORR Route table */ +	for (rn = route_top(root->old_table); rn; rn = route_next(rn)) { +		or = rn->info; +		if (!or) +			continue; + +		if (or->path_type != OSPF_PATH_INTRA_AREA && +		    or->path_type != OSPF_PATH_INTER_AREA) +			continue; + +		if (or->type != OSPF_DESTINATION_NETWORK && +		    or->type != OSPF_DESTINATION_DISCARD) +			continue; + +		if (ospf_route_exist_new_table(root->new_table, +					       (struct prefix_ipv4 *)&rn->p)) +			continue; + +		if (count < ORR_MAX_PREFIX) { +			prefix_copy(&msg.nexthop[count].prefix, +				    (struct prefix_ipv4 *)&rn->p); +			msg.nexthop[count].metric = or->cost; +			count++; +		} else { +			msg.num_entries = count; +			ret = zclient_send_opaque(zclient, +						  ORR_IGP_METRIC_UPDATE, +						  (uint8_t *)&msg, sizeof(msg)); +			if (ret != ZCLIENT_SEND_SUCCESS) +				ospf_orr_debug( +					"%s: Failed to send message to BGP.", +					__func__); +			count = 0; +			prefix_copy(&msg.nexthop[count].prefix, +				    (struct prefix_ipv4 *)&rn->p); +			msg.nexthop[count].metric = or->cost; +			count++; +		} +	} +	if (count > 0 && count <= ORR_MAX_PREFIX) { +		msg.num_entries = count; +		ret = zclient_send_opaque(zclient, ORR_IGP_METRIC_UPDATE, +					  (uint8_t *)&msg, sizeof(msg)); +		if (ret != ZCLIENT_SEND_SUCCESS) +			ospf_orr_debug("%s: Failed to send message to BGP.", +				       __func__); +	} +} +  static void ospf_show_orr_root(struct orr_root *root)  {  	if (!root) @@ -438,7 +507,8 @@ void ospf_orr_root_update_rcvd_lsa(struct ospf_lsa *lsa)  }  /* Do not Install routes to root table. Just update table ponters */ -void ospf_orr_route_install(struct orr_root *root, struct route_table *rt) +void ospf_orr_route_install(struct orr_root *root, struct route_table *rt, +			    unsigned short instance)  {  	/*  	 * rt contains new routing table, new_table contains an old one. @@ -449,6 +519,14 @@ void ospf_orr_route_install(struct orr_root *root, struct route_table *rt)  	root->old_table = root->new_table;  	root->new_table = rt; + +	/* Send update to BGP to delete old routes. */ +	ospf_orr_igp_metric_send_update_delete(root, instance); + +	/* REVISIT: Skipping external route table for now */ + +	/* Send update to BGP to add new routes. */ +	ospf_orr_igp_metric_send_update_add(root, instance);  }  void ospf_orr_spf_calculate_schedule(struct ospf *ospf) diff --git a/ospfd/ospf_orr.h b/ospfd/ospf_orr.h index 24b610c61c..d0a6f6e790 100644 --- a/ospfd/ospf_orr.h +++ b/ospfd/ospf_orr.h @@ -34,12 +34,15 @@  extern struct zclient *zclient;  extern int ospf_orr_igp_metric_register(struct orr_igp_metric_reg orr_reg); -extern void ospf_orr_igp_metric_send_update(struct orr_root *root, -					    unsigned short instance); +extern void ospf_orr_igp_metric_send_update_add(struct orr_root *root, +						unsigned short instance); +extern void ospf_orr_igp_metric_send_update_delete(struct orr_root *root, +						   unsigned short instance);  extern void ospf_orr_root_table_update(struct ospf_lsa *lsa, bool add);  extern void ospf_orr_root_update_rcvd_lsa(struct ospf_lsa *lsa);  extern void ospf_orr_route_install(struct orr_root *root, -				   struct route_table *rt); +				   struct route_table *rt, +				   unsigned short instance);  extern void ospf_orr_spf_calculate_schedule(struct ospf *ospf);  extern void ospf_orr_spf_calculate_area(struct ospf *ospf,  					struct ospf_area *area, diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index 6360d8ec60..26f593f089 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -151,8 +151,8 @@ void ospf_route_table_free(struct route_table *rt)     otherwise return 0. Since the ZEBRA-RIB does an implicit     withdraw, it is not necessary to send a delete, an add later     will act like an implicit delete. */ -static int ospf_route_exist_new_table(struct route_table *rt, -				      struct prefix_ipv4 *prefix) +int ospf_route_exist_new_table(struct route_table *rt, +			       struct prefix_ipv4 *prefix)  {  	struct route_node *rn; diff --git a/ospfd/ospf_route.h b/ospfd/ospf_route.h index fa9478fced..e7e2b651c5 100644 --- a/ospfd/ospf_route.h +++ b/ospfd/ospf_route.h @@ -172,5 +172,6 @@ extern void ospf_delete_discard_route(struct ospf *, struct route_table *,  				      struct prefix_ipv4 *);  extern int ospf_route_match_same(struct route_table *, struct prefix_ipv4 *,  				 struct ospf_route *); - +extern int ospf_route_exist_new_table(struct route_table *rt, +				      struct prefix_ipv4 *prefix);  #endif /* _ZEBRA_OSPF_ROUTE_H */ diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 467ec76090..74213d7de2 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -2060,7 +2060,7 @@ void ospf_orr_spf_calculate_schedule_worker(struct thread *thread)  			/* Update routing table. */  			monotime(&start_time); -			ospf_orr_route_install(root, new_table); +			ospf_orr_route_install(root, new_table, ospf->instance);  			rt_time = monotime_since(&start_time, NULL);  			/* @@ -2111,13 +2111,6 @@ void ospf_orr_spf_calculate_schedule_worker(struct thread *thread)  						abr_time, ospf->areas->count);  				zlog_info("Reason(s) for SPF: %s", rbuf);  			} - -			root->new_table = new_table; -			root->new_rtrs = new_rtrs; - -			/* Send IGP Metric update to BGP */ -			ospf_orr_igp_metric_send_update(root, ospf->instance); -  		} /* ALL_LIST_ELEMENTS_RO() */  	} /* FOREACH_AFI_SAFI() */  }  | 
