diff options
Diffstat (limited to 'ospfd/ospf_asbr.c')
| -rw-r--r-- | ospfd/ospf_asbr.c | 434 | 
1 files changed, 211 insertions, 223 deletions
diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index 284c564688..76f5b62cd1 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -46,280 +46,268 @@  /* Remove external route. */ -void -ospf_external_route_remove (struct ospf *ospf, struct prefix_ipv4 *p) +void ospf_external_route_remove(struct ospf *ospf, struct prefix_ipv4 *p)  { -  struct route_node *rn; -  struct ospf_route *or; - -  rn = route_node_lookup (ospf->old_external_route, (struct prefix *) p); -  if (rn) -    if ((or = rn->info)) -      { -	zlog_info ("Route[%s/%d]: external path deleted", -		   inet_ntoa (p->prefix), p->prefixlen); - -	/* Remove route from zebra. */ -        if (or->type == OSPF_DESTINATION_NETWORK) -	  ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p, or); - -	ospf_route_free (or); -	rn->info = NULL; - -	route_unlock_node (rn); -	route_unlock_node (rn); -	return; -      } - -  zlog_info ("Route[%s/%d]: no such external path", -	     inet_ntoa (p->prefix), p->prefixlen); +	struct route_node *rn; +	struct ospf_route * or ; + +	rn = route_node_lookup(ospf->old_external_route, (struct prefix *)p); +	if (rn) +		if ((or = rn->info)) { +			zlog_info("Route[%s/%d]: external path deleted", +				  inet_ntoa(p->prefix), p->prefixlen); + +			/* Remove route from zebra. */ +			if (or->type == OSPF_DESTINATION_NETWORK) +				ospf_zebra_delete((struct prefix_ipv4 *)&rn->p, +						  or); + +			ospf_route_free(or); +			rn->info = NULL; + +			route_unlock_node(rn); +			route_unlock_node(rn); +			return; +		} + +	zlog_info("Route[%s/%d]: no such external path", inet_ntoa(p->prefix), +		  p->prefixlen);  }  /* Lookup external route. */ -struct ospf_route * -ospf_external_route_lookup (struct ospf *ospf, -			    struct prefix_ipv4 *p) +struct ospf_route *ospf_external_route_lookup(struct ospf *ospf, +					      struct prefix_ipv4 *p)  { -  struct route_node *rn; +	struct route_node *rn; -  rn = route_node_lookup (ospf->old_external_route, (struct prefix *) p); -  if (rn) -    { -      route_unlock_node (rn); -      if (rn->info) -	return rn->info; -    } +	rn = route_node_lookup(ospf->old_external_route, (struct prefix *)p); +	if (rn) { +		route_unlock_node(rn); +		if (rn->info) +			return rn->info; +	} -  zlog_warn ("Route[%s/%d]: lookup, no such prefix", -	     inet_ntoa (p->prefix), p->prefixlen); +	zlog_warn("Route[%s/%d]: lookup, no such prefix", inet_ntoa(p->prefix), +		  p->prefixlen); -  return NULL; +	return NULL;  }  /* Add an External info for AS-external-LSA. */ -struct external_info * -ospf_external_info_new (u_char type, u_short instance) +struct external_info *ospf_external_info_new(u_char type, u_short instance)  { -  struct external_info *new; +	struct external_info *new; -  new = (struct external_info *) -    XCALLOC (MTYPE_OSPF_EXTERNAL_INFO, sizeof (struct external_info)); -  new->type = type; -  new->instance = instance; +	new = (struct external_info *)XCALLOC(MTYPE_OSPF_EXTERNAL_INFO, +					      sizeof(struct external_info)); +	new->type = type; +	new->instance = instance; -  ospf_reset_route_map_set_values (&new->route_map_set); -  return new; +	ospf_reset_route_map_set_values(&new->route_map_set); +	return new;  } -static void -ospf_external_info_free (struct external_info *ei) +static void ospf_external_info_free(struct external_info *ei)  { -  XFREE (MTYPE_OSPF_EXTERNAL_INFO, ei); +	XFREE(MTYPE_OSPF_EXTERNAL_INFO, ei);  } -void -ospf_reset_route_map_set_values (struct route_map_set_values *values) +void ospf_reset_route_map_set_values(struct route_map_set_values *values)  { -  values->metric = -1; -  values->metric_type = -1; +	values->metric = -1; +	values->metric_type = -1;  } -int -ospf_route_map_set_compare (struct route_map_set_values *values1, -			    struct route_map_set_values *values2) +int ospf_route_map_set_compare(struct route_map_set_values *values1, +			       struct route_map_set_values *values2)  { -  return values1->metric == values2->metric && -    values1->metric_type == values2->metric_type; +	return values1->metric == values2->metric +	       && values1->metric_type == values2->metric_type;  }  /* Add an External info for AS-external-LSA. */ -struct external_info * -ospf_external_info_add (u_char type, u_short instance, struct prefix_ipv4 p, -			ifindex_t ifindex, struct in_addr nexthop, -                        route_tag_t tag) +struct external_info *ospf_external_info_add(u_char type, u_short instance, +					     struct prefix_ipv4 p, +					     ifindex_t ifindex, +					     struct in_addr nexthop, +					     route_tag_t tag)  { -  struct external_info *new; -  struct route_node *rn; -  struct ospf_external *ext; -  char inetbuf[INET6_BUFSIZ]; - -  ext = ospf_external_lookup(type, instance); -  if (!ext) -    ext = ospf_external_add(type, instance); - -  rn = route_node_get (EXTERNAL_INFO (ext), (struct prefix *) &p); -  /* If old info exists, -- discard new one or overwrite with new one? */ -  if (rn) -    if (rn->info) -      { -	new = rn->info; -	if ((new->ifindex == ifindex) && -	    (new->nexthop.s_addr == nexthop.s_addr) && (new->tag == tag)) -	  { -	    route_unlock_node(rn); -	    return NULL;	/* NULL => no LSA to refresh */ -	  } - -	inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, INET6_BUFSIZ); -	zlog_warn ("Redistribute[%s][%d]: %s/%d discarding old info with NH %s.", -		   ospf_redist_string(type), instance, -		   inet_ntoa (p.prefix), p.prefixlen, inetbuf); -	XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info); -	rn->info = NULL; -      } - -  /* Create new External info instance. */ -  new = ospf_external_info_new (type, instance); -  new->p = p; -  new->ifindex = ifindex; -  new->nexthop = nexthop; -  new->tag = tag; - -  /* we don't unlock rn from the get() because we're attaching the info */ -  if (rn) -    rn->info = new; - -  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) -    { -      inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, INET6_BUFSIZ); -      zlog_debug ("Redistribute[%s]: %s/%d external info created, with NH %s", -		  ospf_redist_string(type), -		  inet_ntoa (p.prefix), p.prefixlen, inetbuf); -    } -  return new; +	struct external_info *new; +	struct route_node *rn; +	struct ospf_external *ext; +	char inetbuf[INET6_BUFSIZ]; + +	ext = ospf_external_lookup(type, instance); +	if (!ext) +		ext = ospf_external_add(type, instance); + +	rn = route_node_get(EXTERNAL_INFO(ext), (struct prefix *)&p); +	/* If old info exists, -- discard new one or overwrite with new one? */ +	if (rn) +		if (rn->info) { +			new = rn->info; +			if ((new->ifindex == ifindex) +			    && (new->nexthop.s_addr == nexthop.s_addr) +			    && (new->tag == tag)) { +				route_unlock_node(rn); +				return NULL; /* NULL => no LSA to refresh */ +			} + +			inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, +				  INET6_BUFSIZ); +			zlog_warn( +				"Redistribute[%s][%d]: %s/%d discarding old info with NH %s.", +				ospf_redist_string(type), instance, +				inet_ntoa(p.prefix), p.prefixlen, inetbuf); +			XFREE(MTYPE_OSPF_EXTERNAL_INFO, rn->info); +			rn->info = NULL; +		} + +	/* Create new External info instance. */ +	new = ospf_external_info_new(type, instance); +	new->p = p; +	new->ifindex = ifindex; +	new->nexthop = nexthop; +	new->tag = tag; + +	/* we don't unlock rn from the get() because we're attaching the info */ +	if (rn) +		rn->info = new; + +	if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) { +		inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf, +			  INET6_BUFSIZ); +		zlog_debug( +			"Redistribute[%s]: %s/%d external info created, with NH %s", +			ospf_redist_string(type), inet_ntoa(p.prefix), +			p.prefixlen, inetbuf); +	} +	return new;  } -void -ospf_external_info_delete (u_char type, u_short instance, struct prefix_ipv4 p) +void ospf_external_info_delete(u_char type, u_short instance, +			       struct prefix_ipv4 p)  { -  struct route_node *rn; -  struct ospf_external *ext; - -  ext = ospf_external_lookup(type, instance); -  if (!ext) -    return; - -  rn = route_node_lookup (EXTERNAL_INFO (ext), (struct prefix *) &p); -  if (rn) -    { -      ospf_external_info_free (rn->info); -      rn->info = NULL; -      route_unlock_node (rn); -      route_unlock_node (rn); -    } +	struct route_node *rn; +	struct ospf_external *ext; + +	ext = ospf_external_lookup(type, instance); +	if (!ext) +		return; + +	rn = route_node_lookup(EXTERNAL_INFO(ext), (struct prefix *)&p); +	if (rn) { +		ospf_external_info_free(rn->info); +		rn->info = NULL; +		route_unlock_node(rn); +		route_unlock_node(rn); +	}  } -struct external_info * -ospf_external_info_lookup (u_char type, u_short instance, struct prefix_ipv4 *p) +struct external_info *ospf_external_info_lookup(u_char type, u_short instance, +						struct prefix_ipv4 *p)  { -  struct route_node *rn; -  struct ospf_external *ext; - -  ext = ospf_external_lookup(type, instance); -  if (!ext) -    return NULL; - -  rn = route_node_lookup (EXTERNAL_INFO (ext), (struct prefix *) p); -  if (rn) -    { -      route_unlock_node (rn); -      if (rn->info) -	return rn->info; -    } - -  return NULL; +	struct route_node *rn; +	struct ospf_external *ext; + +	ext = ospf_external_lookup(type, instance); +	if (!ext) +		return NULL; + +	rn = route_node_lookup(EXTERNAL_INFO(ext), (struct prefix *)p); +	if (rn) { +		route_unlock_node(rn); +		if (rn->info) +			return rn->info; +	} + +	return NULL;  } -struct ospf_lsa * -ospf_external_info_find_lsa (struct ospf *ospf, -			     struct prefix_ipv4 *p) +struct ospf_lsa *ospf_external_info_find_lsa(struct ospf *ospf, +					     struct prefix_ipv4 *p)  { -  struct ospf_lsa *lsa; -  struct as_external_lsa *al; -  struct in_addr mask, id; +	struct ospf_lsa *lsa; +	struct as_external_lsa *al; +	struct in_addr mask, id; -  lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, OSPF_AS_EXTERNAL_LSA, -				p->prefix, ospf->router_id); +	lsa = ospf_lsdb_lookup_by_id(ospf->lsdb, OSPF_AS_EXTERNAL_LSA, +				     p->prefix, ospf->router_id); -  if (!lsa) -    return NULL; +	if (!lsa) +		return NULL; -  al = (struct as_external_lsa *) lsa->data; +	al = (struct as_external_lsa *)lsa->data; -  masklen2ip (p->prefixlen, &mask); +	masklen2ip(p->prefixlen, &mask); -  if (mask.s_addr != al->mask.s_addr) -    { -      id.s_addr = p->prefix.s_addr | (~mask.s_addr); -      lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, OSPF_AS_EXTERNAL_LSA, -				   id, ospf->router_id); -      if (!lsa) -	return NULL; -    } +	if (mask.s_addr != al->mask.s_addr) { +		id.s_addr = p->prefix.s_addr | (~mask.s_addr); +		lsa = ospf_lsdb_lookup_by_id(ospf->lsdb, OSPF_AS_EXTERNAL_LSA, +					     id, ospf->router_id); +		if (!lsa) +			return NULL; +	} -  return lsa; +	return lsa;  }  /* Update ASBR status. */ -void -ospf_asbr_status_update (struct ospf *ospf, u_char status) +void ospf_asbr_status_update(struct ospf *ospf, u_char status)  { -  zlog_info ("ASBR[Status:%d]: Update", status); - -  /* ASBR on. */ -  if (status) -    { -      /* Already ASBR. */ -      if (IS_OSPF_ASBR (ospf)) -	{ -	  zlog_info ("ASBR[Status:%d]: Already ASBR", status); -	  return; -	} -      SET_FLAG (ospf->flags, OSPF_FLAG_ASBR); -    } -  else -    { -      /* Already non ASBR. */ -      if (! IS_OSPF_ASBR (ospf)) -	{ -	  zlog_info ("ASBR[Status:%d]: Already non ASBR", status); -	  return; +	zlog_info("ASBR[Status:%d]: Update", status); + +	/* ASBR on. */ +	if (status) { +		/* Already ASBR. */ +		if (IS_OSPF_ASBR(ospf)) { +			zlog_info("ASBR[Status:%d]: Already ASBR", status); +			return; +		} +		SET_FLAG(ospf->flags, OSPF_FLAG_ASBR); +	} else { +		/* Already non ASBR. */ +		if (!IS_OSPF_ASBR(ospf)) { +			zlog_info("ASBR[Status:%d]: Already non ASBR", status); +			return; +		} +		UNSET_FLAG(ospf->flags, OSPF_FLAG_ASBR);  	} -      UNSET_FLAG (ospf->flags, OSPF_FLAG_ASBR); -    } -  /* Transition from/to status ASBR, schedule timer. */ -  ospf_spf_calculate_schedule (ospf, SPF_FLAG_ASBR_STATUS_CHANGE); -  ospf_router_lsa_update (ospf); +	/* Transition from/to status ASBR, schedule timer. */ +	ospf_spf_calculate_schedule(ospf, SPF_FLAG_ASBR_STATUS_CHANGE); +	ospf_router_lsa_update(ospf);  } -void -ospf_redistribute_withdraw (struct ospf *ospf, u_char type, u_short instance) +void ospf_redistribute_withdraw(struct ospf *ospf, u_char type, +				u_short instance)  { -  struct route_node *rn; -  struct external_info *ei; -  struct ospf_external *ext; - -  ext = ospf_external_lookup(type, instance); -  if (!ext) -    return; - -  /* Delete external info for specified type. */ -  if (EXTERNAL_INFO (ext)) -    for (rn = route_top (EXTERNAL_INFO (ext)); rn; rn = route_next (rn)) -      if ((ei = rn->info)) -	if (ospf_external_info_find_lsa (ospf, &ei->p)) -	  { -	    if (is_prefix_default (&ei->p) && -		ospf->default_originate != DEFAULT_ORIGINATE_NONE) -	      continue; -	    ospf_external_lsa_flush (ospf, type, &ei->p, -				     ei->ifindex /*, ei->nexthop */); - -	    ospf_external_info_free (ei); -	    route_unlock_node (rn); -	    rn->info = NULL; -	  } +	struct route_node *rn; +	struct external_info *ei; +	struct ospf_external *ext; + +	ext = ospf_external_lookup(type, instance); +	if (!ext) +		return; + +	/* Delete external info for specified type. */ +	if (EXTERNAL_INFO(ext)) +		for (rn = route_top(EXTERNAL_INFO(ext)); rn; +		     rn = route_next(rn)) +			if ((ei = rn->info)) +				if (ospf_external_info_find_lsa(ospf, &ei->p)) { +					if (is_prefix_default(&ei->p) +					    && ospf->default_originate +						       != DEFAULT_ORIGINATE_NONE) +						continue; +					ospf_external_lsa_flush( +						ospf, type, &ei->p, +						ei->ifindex /*, ei->nexthop */); + +					ospf_external_info_free(ei); +					route_unlock_node(rn); +					rn->info = NULL; +				}  }  | 
