diff options
| -rw-r--r-- | ripd/rip_northbound.c | 48 | ||||
| -rw-r--r-- | ripd/rip_zebra.c | 28 | ||||
| -rw-r--r-- | ripd/ripd.c | 26 | ||||
| -rw-r--r-- | ripd/ripd.h | 14 | ||||
| -rw-r--r-- | ripngd/ripng_northbound.c | 48 | ||||
| -rw-r--r-- | ripngd/ripng_zebra.c | 29 | ||||
| -rw-r--r-- | ripngd/ripngd.c | 31 | ||||
| -rw-r--r-- | ripngd/ripngd.h | 14 | 
8 files changed, 154 insertions, 84 deletions
diff --git a/ripd/rip_northbound.c b/ripd/rip_northbound.c index d2360c470c..13520d11de 100644 --- a/ripd/rip_northbound.c +++ b/ripd/rip_northbound.c @@ -637,6 +637,17 @@ static int ripd_instance_redistribute_create(enum nb_event event,  					     const struct lyd_node *dnode,  					     union nb_resource *resource)  { +	struct rip *rip; +	int type; + +	if (event != NB_EV_APPLY) +		return NB_OK; + +	rip = yang_dnode_get_entry(dnode, true); +	type = yang_dnode_get_enum(dnode, "./protocol"); + +	rip->redist[type].enabled = true; +  	return NB_OK;  } @@ -652,7 +663,17 @@ static int ripd_instance_redistribute_delete(enum nb_event event,  	rip = yang_dnode_get_entry(dnode, true);  	type = yang_dnode_get_enum(dnode, "./protocol"); -	rip_redistribute_conf_delete(rip, type); +	rip->redist[type].enabled = false; +	if (rip->redist[type].route_map.name) { +		free(rip->redist[type].route_map.name); +		rip->redist[type].route_map.name = NULL; +		rip->redist[type].route_map.map = NULL; +	} +	rip->redist[type].metric_config = false; +	rip->redist[type].metric = 0; + +	if (rip->enabled) +		rip_redistribute_conf_delete(rip, type);  	return NB_OK;  } @@ -666,7 +687,8 @@ ripd_instance_redistribute_apply_finish(const struct lyd_node *dnode)  	rip = yang_dnode_get_entry(dnode, true);  	type = yang_dnode_get_enum(dnode, "./protocol"); -	rip_redistribute_conf_update(rip, type); +	if (rip->enabled) +		rip_redistribute_conf_update(rip, type);  }  /* @@ -688,10 +710,10 @@ ripd_instance_redistribute_route_map_modify(enum nb_event event,  	type = yang_dnode_get_enum(dnode, "../protocol");  	rmap_name = yang_dnode_get_string(dnode, NULL); -	if (rip->route_map[type].name) -		free(rip->route_map[type].name); -	rip->route_map[type].name = strdup(rmap_name); -	rip->route_map[type].map = route_map_lookup_by_name(rmap_name); +	if (rip->redist[type].route_map.name) +		free(rip->redist[type].route_map.name); +	rip->redist[type].route_map.name = strdup(rmap_name); +	rip->redist[type].route_map.map = route_map_lookup_by_name(rmap_name);  	return NB_OK;  } @@ -709,9 +731,9 @@ ripd_instance_redistribute_route_map_delete(enum nb_event event,  	rip = yang_dnode_get_entry(dnode, true);  	type = yang_dnode_get_enum(dnode, "../protocol"); -	free(rip->route_map[type].name); -	rip->route_map[type].name = NULL; -	rip->route_map[type].map = NULL; +	free(rip->redist[type].route_map.name); +	rip->redist[type].route_map.name = NULL; +	rip->redist[type].route_map.map = NULL;  	return NB_OK;  } @@ -735,8 +757,8 @@ ripd_instance_redistribute_metric_modify(enum nb_event event,  	type = yang_dnode_get_enum(dnode, "../protocol");  	metric = yang_dnode_get_uint8(dnode, NULL); -	rip->route_map[type].metric_config = true; -	rip->route_map[type].metric = metric; +	rip->redist[type].metric_config = true; +	rip->redist[type].metric = metric;  	return NB_OK;  } @@ -754,8 +776,8 @@ ripd_instance_redistribute_metric_delete(enum nb_event event,  	rip = yang_dnode_get_entry(dnode, true);  	type = yang_dnode_get_enum(dnode, "../protocol"); -	rip->route_map[type].metric_config = false; -	rip->route_map[type].metric = 0; +	rip->redist[type].metric_config = false; +	rip->redist[type].metric = 0;  	return NB_OK;  } diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index d8b35cf976..4f0df12232 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -168,23 +168,28 @@ void rip_redistribute_conf_delete(struct rip *rip, int type)  int rip_redistribute_check(struct rip *rip, int type)  { -	return vrf_bitmap_check(zclient->redist[AFI_IP][type], -				rip->vrf->vrf_id); +	return rip->redist[type].enabled;  } -void rip_redistribute_clean(struct rip *rip) +void rip_redistribute_enable(struct rip *rip)  {  	for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) { -		if (!vrf_bitmap_check(zclient->redist[AFI_IP][i], -				      rip->vrf->vrf_id)) +		if (!rip_redistribute_check(rip, i))  			continue; -		if (zclient->sock > 0) -			zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, -						zclient, AFI_IP, i, 0, -						rip->vrf->vrf_id); +		zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, +					i, 0, rip->vrf->vrf_id); +	} +} -		vrf_bitmap_unset(zclient->redist[AFI_IP][i], rip->vrf->vrf_id); +void rip_redistribute_disable(struct rip *rip) +{ +	for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) { +		if (!rip_redistribute_check(rip, i)) +			continue; + +		zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, +					AFI_IP, i, 0, rip->vrf->vrf_id);  	}  } @@ -192,8 +197,7 @@ void rip_show_redistribute_config(struct vty *vty, struct rip *rip)  {  	for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {  		if (i == zclient->redist_default -		    || !vrf_bitmap_check(zclient->redist[AFI_IP][i], -					 rip->vrf->vrf_id)) +		    || !rip_redistribute_check(rip, i))  			continue;  		vty_out(vty, " %s", zebra_route_string(i)); diff --git a/ripd/ripd.c b/ripd/ripd.c index a6a2a29deb..7fe8fc8c8b 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -2239,10 +2239,10 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to,  			}  			/* Apply redistribute route map - continue, if deny */ -			if (rip->route_map[rinfo->type].name +			if (rip->redist[rinfo->type].route_map.name  			    && rinfo->sub_type != RIP_ROUTE_INTERFACE) {  				ret = route_map_apply( -					rip->route_map[rinfo->type].map, +					rip->redist[rinfo->type].route_map.map,  					(struct prefix *)p, RMAP_RIP, rinfo);  				if (ret == RMAP_DENYMATCH) { @@ -2258,11 +2258,10 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to,  			/* When route-map does not set metric. */  			if (!rinfo->metric_set) {  				/* If redistribute metric is set. */ -				if (rip->route_map[rinfo->type].metric_config +				if (rip->redist[rinfo->type].metric_config  				    && rinfo->metric != RIP_METRIC_INFINITY) {  					rinfo->metric_out = -						rip->route_map[rinfo->type] -							.metric; +						rip->redist[rinfo->type].metric;  				} else {  					/* If the route is not connected or  					   localy generated @@ -3382,8 +3381,8 @@ void rip_clean(struct rip *rip)  	stream_free(rip->obuf);  	for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) -		if (rip->route_map[i].name) -			free(rip->route_map[i].name); +		if (rip->redist[i].route_map.name) +			free(rip->redist[i].route_map.name);  	route_table_finish(rip->table);  	route_table_finish(rip->neighbor); @@ -3398,7 +3397,6 @@ void rip_clean(struct rip *rip)  	list_delete(&rip->offset_list_master);  	rip_interfaces_clean(rip);  	route_table_finish(rip->distance_table); -	rip_redistribute_clean(rip);  	RB_REMOVE(rip_instance_head, &rip_instances, rip);  	XFREE(MTYPE_RIP_VRF_NAME, rip->vrf_name); @@ -3447,9 +3445,9 @@ void rip_if_rmap_update_interface(struct interface *ifp)  static void rip_routemap_update_redistribute(struct rip *rip)  {  	for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) { -		if (rip->route_map[i].name) -			rip->route_map[i].map = route_map_lookup_by_name( -				rip->route_map[i].name); +		if (rip->redist[i].route_map.name) +			rip->redist[i].route_map.map = route_map_lookup_by_name( +				rip->redist[i].route_map.name);  	}  } @@ -3501,6 +3499,9 @@ static void rip_instance_enable(struct rip *rip, struct vrf *vrf, int sock)  	rip_vrf_link(rip, vrf);  	rip->enabled = true; +	/* Resend all redistribute requests. */ +	rip_redistribute_enable(rip); +  	/* Create read and timer thread. */  	rip_event(rip, RIP_READ, rip->sock);  	rip_event(rip, RIP_UPDATE_EVENT, 1); @@ -3536,6 +3537,9 @@ static void rip_instance_disable(struct rip *rip)  		route_unlock_node(rp);  	} +	/* Flush all redistribute requests. */ +	rip_redistribute_disable(rip); +  	/* Cancel RIP related timers. */  	RIP_TIMER_OFF(rip->t_update);  	RIP_TIMER_OFF(rip->t_triggered_update); diff --git a/ripd/ripd.h b/ripd/ripd.h index d88c5c1e61..f78dae7a8b 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -170,13 +170,16 @@ struct rip {  	/* RIP offset-lists. */  	struct list *offset_list_master; -	/* For redistribute route map. */ +	/* RIP redistribute configuration. */  	struct { -		char *name; -		struct route_map *map; +		bool enabled; +		struct { +			char *name; +			struct route_map *map; +		} route_map;  		bool metric_config;  		uint8_t metric; -	} route_map[ZEBRA_ROUTE_MAX]; +	} redist[ZEBRA_ROUTE_MAX];  	/* For distribute-list container */  	struct distribute_ctx *distribute_ctx; @@ -487,7 +490,8 @@ extern struct rip *rip_info_get_instance(const struct rip_info *rinfo);  extern struct rip_distance *rip_distance_new(void);  extern void rip_distance_free(struct rip_distance *rdistance);  extern uint8_t rip_distance_apply(struct rip *rip, struct rip_info *rinfo); -extern void rip_redistribute_clean(struct rip *rip); +extern void rip_redistribute_enable(struct rip *rip); +extern void rip_redistribute_disable(struct rip *rip);  extern int rip_route_rte(struct rip_info *rinfo);  extern struct rip_info *rip_ecmp_add(struct rip *rip, diff --git a/ripngd/ripng_northbound.c b/ripngd/ripng_northbound.c index 4b15a3aef7..dda57a31fe 100644 --- a/ripngd/ripng_northbound.c +++ b/ripngd/ripng_northbound.c @@ -411,6 +411,17 @@ static int ripngd_instance_redistribute_create(enum nb_event event,  					       const struct lyd_node *dnode,  					       union nb_resource *resource)  { +	struct ripng *ripng; +	int type; + +	if (event != NB_EV_APPLY) +		return NB_OK; + +	ripng = yang_dnode_get_entry(dnode, true); +	type = yang_dnode_get_enum(dnode, "./protocol"); + +	ripng->redist[type].enabled = true; +  	return NB_OK;  } @@ -426,7 +437,17 @@ static int ripngd_instance_redistribute_delete(enum nb_event event,  	ripng = yang_dnode_get_entry(dnode, true);  	type = yang_dnode_get_enum(dnode, "./protocol"); -	ripng_redistribute_conf_delete(ripng, type); +	ripng->redist[type].enabled = false; +	if (ripng->redist[type].route_map.name) { +		free(ripng->redist[type].route_map.name); +		ripng->redist[type].route_map.name = NULL; +		ripng->redist[type].route_map.map = NULL; +	} +	ripng->redist[type].metric_config = false; +	ripng->redist[type].metric = 0; + +	if (ripng->enabled) +		ripng_redistribute_conf_delete(ripng, type);  	return NB_OK;  } @@ -440,7 +461,8 @@ ripngd_instance_redistribute_apply_finish(const struct lyd_node *dnode)  	ripng = yang_dnode_get_entry(dnode, true);  	type = yang_dnode_get_enum(dnode, "./protocol"); -	ripng_redistribute_conf_update(ripng, type); +	if (ripng->enabled) +		ripng_redistribute_conf_update(ripng, type);  }  /* @@ -462,10 +484,10 @@ ripngd_instance_redistribute_route_map_modify(enum nb_event event,  	type = yang_dnode_get_enum(dnode, "../protocol");  	rmap_name = yang_dnode_get_string(dnode, NULL); -	if (ripng->route_map[type].name) -		free(ripng->route_map[type].name); -	ripng->route_map[type].name = strdup(rmap_name); -	ripng->route_map[type].map = route_map_lookup_by_name(rmap_name); +	if (ripng->redist[type].route_map.name) +		free(ripng->redist[type].route_map.name); +	ripng->redist[type].route_map.name = strdup(rmap_name); +	ripng->redist[type].route_map.map = route_map_lookup_by_name(rmap_name);  	return NB_OK;  } @@ -483,9 +505,9 @@ ripngd_instance_redistribute_route_map_delete(enum nb_event event,  	ripng = yang_dnode_get_entry(dnode, true);  	type = yang_dnode_get_enum(dnode, "../protocol"); -	free(ripng->route_map[type].name); -	ripng->route_map[type].name = NULL; -	ripng->route_map[type].map = NULL; +	free(ripng->redist[type].route_map.name); +	ripng->redist[type].route_map.name = NULL; +	ripng->redist[type].route_map.map = NULL;  	return NB_OK;  } @@ -509,8 +531,8 @@ ripngd_instance_redistribute_metric_modify(enum nb_event event,  	type = yang_dnode_get_enum(dnode, "../protocol");  	metric = yang_dnode_get_uint8(dnode, NULL); -	ripng->route_map[type].metric_config = true; -	ripng->route_map[type].metric = metric; +	ripng->redist[type].metric_config = true; +	ripng->redist[type].metric = metric;  	return NB_OK;  } @@ -528,8 +550,8 @@ ripngd_instance_redistribute_metric_delete(enum nb_event event,  	ripng = yang_dnode_get_entry(dnode, true);  	type = yang_dnode_get_enum(dnode, "../protocol"); -	ripng->route_map[type].metric_config = false; -	ripng->route_map[type].metric = 0; +	ripng->redist[type].metric_config = false; +	ripng->redist[type].metric = 0;  	return NB_OK;  } diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index 913ac5191c..e2dcc02384 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -165,24 +165,28 @@ void ripng_redistribute_conf_delete(struct ripng *ripng, int type)  int ripng_redistribute_check(struct ripng *ripng, int type)  { -	return vrf_bitmap_check(zclient->redist[AFI_IP6][type], -				ripng->vrf->vrf_id); +	return ripng->redist[type].enabled;  } -void ripng_redistribute_clean(struct ripng *ripng) +void ripng_redistribute_enable(struct ripng *ripng)  {  	for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) { -		if (!vrf_bitmap_check(zclient->redist[AFI_IP6][i], -				      ripng->vrf->vrf_id)) +		if (!ripng_redistribute_check(ripng, i))  			continue; -		if (zclient->sock > 0) -			zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, -						zclient, AFI_IP6, i, 0, -						ripng->vrf->vrf_id); +		zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, +					AFI_IP6, i, 0, ripng->vrf->vrf_id); +	} +} -		vrf_bitmap_unset(zclient->redist[AFI_IP6][i], -				 ripng->vrf->vrf_id); +void ripng_redistribute_disable(struct ripng *ripng) +{ +	for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) { +		if (!ripng_redistribute_check(ripng, i)) +			continue; + +		zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, +					AFI_IP6, i, 0, ripng->vrf->vrf_id);  	}  } @@ -192,8 +196,7 @@ void ripng_redistribute_write(struct vty *vty, struct ripng *ripng)  	for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {  		if (i == zclient->redist_default -		    || !vrf_bitmap_check(zclient->redist[AFI_IP6][i], -					 ripng->vrf->vrf_id)) +		    || !ripng_redistribute_check(ripng, i))  			continue;  		vty_out(vty, "    %s", zebra_route_string(i)); diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 951c73bc45..c3aa9d8dbf 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -1682,10 +1682,11 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to,  			}  			/* Redistribute route-map. */ -			if (ripng->route_map[rinfo->type].name) { -				ret = route_map_apply( -					ripng->route_map[rinfo->type].map, -					(struct prefix *)p, RMAP_RIPNG, rinfo); +			if (ripng->redist[rinfo->type].route_map.name) { +				ret = route_map_apply(ripng->redist[rinfo->type] +							      .route_map.map, +						      (struct prefix *)p, +						      RMAP_RIPNG, rinfo);  				if (ret == RMAP_DENYMATCH) {  					if (IS_RIPNG_DEBUG_PACKET) @@ -1700,10 +1701,10 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to,  			/* When the route-map does not set metric. */  			if (!rinfo->metric_set) {  				/* If the redistribute metric is set. */ -				if (ripng->route_map[rinfo->type].metric_config +				if (ripng->redist[rinfo->type].metric_config  				    && rinfo->metric != RIPNG_METRIC_INFINITY) {  					rinfo->metric_out = -						ripng->route_map[rinfo->type] +						ripng->redist[rinfo->type]  							.metric;  				} else {  					/* If the route is not connected or @@ -2531,8 +2532,8 @@ void ripng_clean(struct ripng *ripng)  		ripng_instance_disable(ripng);  	for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) -		if (ripng->route_map[i].name) -			free(ripng->route_map[i].name); +		if (ripng->redist[i].route_map.name) +			free(ripng->redist[i].route_map.name);  	agg_table_finish(ripng->table);  	list_delete(&ripng->peer_list); @@ -2548,7 +2549,6 @@ void ripng_clean(struct ripng *ripng)  	vector_free(ripng->passive_interface);  	list_delete(&ripng->offset_list_master);  	ripng_interface_clean(ripng); -	ripng_redistribute_clean(ripng);  	RB_REMOVE(ripng_instance_head, &ripng_instances, ripng);  	XFREE(MTYPE_RIPNG_VRF_NAME, ripng->vrf_name); @@ -2598,9 +2598,10 @@ void ripng_if_rmap_update_interface(struct interface *ifp)  static void ripng_routemap_update_redistribute(struct ripng *ripng)  {  	for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) { -		if (ripng->route_map[i].name) -			ripng->route_map[i].map = route_map_lookup_by_name( -				ripng->route_map[i].name); +		if (ripng->redist[i].route_map.name) +			ripng->redist[i].route_map.map = +				route_map_lookup_by_name( +					ripng->redist[i].route_map.name);  	}  } @@ -2652,6 +2653,9 @@ static void ripng_instance_enable(struct ripng *ripng, struct vrf *vrf,  	ripng_vrf_link(ripng, vrf);  	ripng->enabled = true; +	/* Resend all redistribute requests. */ +	ripng_redistribute_enable(ripng); +  	/* Create read and timer thread. */  	ripng_event(ripng, RIPNG_READ, ripng->sock);  	ripng_event(ripng, RIPNG_UPDATE_EVENT, 1); @@ -2694,6 +2698,9 @@ static void ripng_instance_disable(struct ripng *ripng)  		}  	} +	/* Flush all redistribute requests. */ +	ripng_redistribute_disable(ripng); +  	/* Cancel the RIPng timers */  	RIPNG_TIMER_OFF(ripng->t_update);  	RIPNG_TIMER_OFF(ripng->t_triggered_update); diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h index d6c4394c6d..b38e6b3a95 100644 --- a/ripngd/ripngd.h +++ b/ripngd/ripngd.h @@ -149,13 +149,16 @@ struct ripng {  	/* RIPng ECMP flag */  	bool ecmp; -	/* For redistribute route map. */ +	/* RIPng redistribute configuration. */  	struct { -		char *name; -		struct route_map *map; +		bool enabled; +		struct { +			char *name; +			struct route_map *map; +		} route_map;  		bool metric_config;  		uint8_t metric; -	} route_map[ZEBRA_ROUTE_MAX]; +	} redist[ZEBRA_ROUTE_MAX];  	/* For distribute-list container */  	struct distribute_ctx *distribute_ctx; @@ -447,7 +450,8 @@ extern void ripng_if_rmap_update_interface(struct interface *);  extern void ripng_zebra_ipv6_add(struct ripng *ripng, struct agg_node *node);  extern void ripng_zebra_ipv6_delete(struct ripng *ripng, struct agg_node *node); -extern void ripng_redistribute_clean(struct ripng *ripng); +extern void ripng_redistribute_enable(struct ripng *ripng); +extern void ripng_redistribute_disable(struct ripng *ripng);  extern int ripng_redistribute_check(struct ripng *ripng, int type);  extern void ripng_redistribute_write(struct vty *vty, struct ripng *ripng);  | 
