⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ospf_ase.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 2 页
字号:
	 to type 1 external and the cost is equal to X+Y.  If the	 external metric type is 2, the path-type is set to type 2	 external, the link state component of the route's cost is X,	 and the type 2 cost is Y. */  new = ospf_ase_calculate_new_route (lsa, asbr_route, metric);  /* (6) Compare the AS external path described by the LSA with the         existing paths in N's routing table entry, as follows. If	 the new path is preferred, it replaces the present paths in	 N's routing table entry.  If the new path is of equal	 preference, it is added to N's routing table entry's list of	 paths. */  /* Set prefix. */  p.family = AF_INET;  p.prefix = al->header.id;  p.prefixlen = ip_masklen (al->mask);  /* if there is a Intra/Inter area route to the N     do not install external route */  if ((rn = route_node_lookup (ospf->new_table,			       (struct prefix *) &p)) != NULL      && (rn->info != NULL))    {      if (new)	ospf_route_free (new);      return 0;    }    /* Find a route to the same dest */  /* If there is no route, create new one. */  if ((rn = route_node_lookup (ospf->new_external_route,			       (struct prefix *) &p)) == NULL       || (or = rn->info) == NULL)    {      zlog_info ("Route[External]: Adding a new route %s/%d",		 inet_ntoa (p.prefix), p.prefixlen);      ospf_route_add (ospf->new_external_route, &p, new, asbr_route);      if (al->e[0].fwd_addr.s_addr)	ospf_ase_complete_direct_routes (new, al->e[0].fwd_addr);      return 0;    }  else    {      /* (a) Intra-area and inter-area paths are always preferred             over AS external paths.         (b) Type 1 external paths are always preferred over type 2             external paths. When all paths are type 2 external	     paths, the paths with the smallest advertised type 2	     metric are always preferred. */      ret = ospf_route_cmp (ospf, new, or);    /*     (c) If the new AS external path is still indistinguishable             from the current paths in the N's routing table entry,	     and RFC1583Compatibility is set to "disabled", select	     the preferred paths based on the intra-AS paths to the	     ASBR/forwarding addresses, as specified in Section	     16.4.1.         (d) If the new AS external path is still indistinguishable             from the current paths in the N's routing table entry,	     select the preferred path based on a least cost	     comparison.  Type 1 external paths are compared by	     looking at the sum of the distance to the forwarding	     address and the advertised type 1 metric (X+Y).  Type 2	     external paths advertising equal type 2 metrics are	     compared by looking at the distance to the forwarding	     addresses.  */      /* New route is better */      if (ret < 0)	{	  zlog_info ("Route[External]: New route is better");	  ospf_route_subst (rn, new, asbr_route);	  if (al->e[0].fwd_addr.s_addr)	    ospf_ase_complete_direct_routes (new, al->e[0].fwd_addr);	  or = new;	  new = NULL;	}      /* Old route is better */      else if (ret > 0)	{	  zlog_info ("Route[External]: Old route is better");	  /* do nothing */	}      /* Routes are equal */      else	{	  zlog_info ("Route[External]: Routes are equal");	  ospf_route_copy_nexthops (or, asbr_route->path);	  if (al->e[0].fwd_addr.s_addr)	    ospf_ase_complete_direct_routes (or, al->e[0].fwd_addr);	}    }  /* Make sure setting newly calculated ASBR route.*/  or->u.ext.asbr = asbr_route;  if (new)    ospf_route_free (new);  lsa->route = or;  return 0;}intospf_ase_route_match_same (struct route_table *rt, struct prefix *prefix,			   struct ospf_route *newor){  struct route_node *rn;  struct ospf_route *or;  struct ospf_path *op;  struct ospf_path *newop;  listnode n1;  listnode n2;  if (! rt || ! prefix)    return 0;   rn = route_node_lookup (rt, prefix);   if (! rn)     return 0;    route_unlock_node (rn);   or = rn->info;   if (or->path_type != newor->path_type)     return 0;   switch (or->path_type)     {     case OSPF_PATH_TYPE1_EXTERNAL:       if (or->cost != newor->cost)	 return 0;       break;     case OSPF_PATH_TYPE2_EXTERNAL:       if ((or->cost != newor->cost) ||	   (or->u.ext.type2_cost != newor->u.ext.type2_cost))	 return 0;       break;     default:       assert (0);       return 0;     }      if (or->path->count != newor->path->count)     return 0;          /* Check each path. */   for (n1 = listhead (or->path), n2 = listhead (newor->path);	n1 && n2; nextnode (n1), nextnode (n2))     {        op = getdata (n1);       newop = getdata (n2);              if (! IPV4_ADDR_SAME (&op->nexthop, &newop->nexthop))	 return 0;     }   return 1;}intospf_ase_compare_tables (struct route_table *new_external_route,			 struct route_table *old_external_route){  struct route_node *rn, *new_rn;  struct ospf_route *or;    /* Remove deleted routes */  for (rn = route_top (old_external_route); rn; rn = route_next (rn))    if ((or = rn->info))      {	if (! (new_rn = route_node_lookup (new_external_route, &rn->p)))	  ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p, or);	else	  route_unlock_node (new_rn);      }  	  /* Install new routes */  for (rn = route_top (new_external_route); rn; rn = route_next (rn))    if ((or = rn->info) != NULL)      if (! ospf_ase_route_match_same (old_external_route, &rn->p, or))	ospf_zebra_add ((struct prefix_ipv4 *) &rn->p, or);				         return 0;}intospf_ase_calculate_timer (struct thread *t){  struct ospf *ospf;  struct ospf_lsa *lsa;  struct route_node *rn;#ifdef HAVE_NSSA  listnode node;  struct ospf_area *area;#endif /* HAVE_NSSA */  ospf = THREAD_ARG (t);  ospf->t_ase_calc = NULL;  if (ospf->ase_calc)    {      ospf->ase_calc = 0;      /* Calculate external route for each AS-external-LSA */      LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)	ospf_ase_calculate_route (ospf, lsa);#ifdef HAVE_NSSA      /*  This version simple adds to the table all NSSA areas  */      if (ospf->anyNSSA)	for (node = listhead (ospf->areas); node; nextnode (node))	  {	    area = getdata (node);	    if (IS_DEBUG_OSPF_NSSA)	      zlog_info ("ospf_ase_calculate_timer(): looking at area %s",			 inet_ntoa (area->area_id));	    if (area->external_routing == OSPF_AREA_NSSA)	      LSDB_LOOP (NSSA_LSDB (area), rn, lsa)		ospf_ase_calculate_route (ospf, lsa);	  }#endif /* HAVE_NSSA */      /* Compare old and new external routing table and install the	 difference info zebra/kernel */      ospf_ase_compare_tables (ospf->new_external_route,			       ospf->old_external_route);      /* Delete old external routing table */      ospf_route_table_free (ospf->old_external_route);      ospf->old_external_route = ospf->new_external_route;      ospf->new_external_route = route_table_init ();    }  return 0;}voidospf_ase_calculate_schedule (struct ospf *ospf){  if (ospf == NULL)    return;  ospf->ase_calc = 1;}voidospf_ase_calculate_timer_add (struct ospf *ospf){  if (ospf == NULL)    return;  if (! ospf->t_ase_calc)    ospf->t_ase_calc = thread_add_timer (master, ospf_ase_calculate_timer,					 ospf, OSPF_ASE_CALC_INTERVAL);}voidospf_ase_register_external_lsa (struct ospf_lsa *lsa, struct ospf *top){  struct route_node *rn;  struct prefix_ipv4 p;  list lst;  struct as_external_lsa *al;  al = (struct as_external_lsa *) lsa->data;  p.family = AF_INET;  p.prefix = lsa->data->id;  p.prefixlen = ip_masklen (al->mask);  apply_mask_ipv4 (&p);  rn = route_node_get (top->external_lsas, (struct prefix *) &p);  if ((lst = rn->info) == NULL)    rn->info = lst = list_new();  /* We assume that if LSA is deleted from DB     is is also deleted from this RT */  listnode_add (lst, ospf_lsa_lock (lsa));}voidospf_ase_unregister_external_lsa (struct ospf_lsa *lsa, struct ospf *top){  struct route_node *rn;  struct prefix_ipv4 p;  list lst;  struct as_external_lsa *al;  al = (struct as_external_lsa *) lsa->data;  p.family = AF_INET;  p.prefix = lsa->data->id;  p.prefixlen = ip_masklen (al->mask);  apply_mask_ipv4 (&p);  rn = route_node_get (top->external_lsas, (struct prefix *) &p);  lst = rn->info;#ifdef ORIGINAL_CODING  assert (lst);  listnode_delete (lst, lsa);  ospf_lsa_unlock (lsa);#else /* ORIGINAL_CODING */  /* XXX lst can be NULL */  if (lst) {    listnode_delete (lst, lsa);    ospf_lsa_unlock (lsa);  }#endif /* ORIGINAL_CODING */}voidospf_ase_external_lsas_finish (struct route_table *rt){  struct route_node *rn;  struct ospf_lsa *lsa;  list lst;  listnode node;    for (rn = route_top (rt); rn; rn = route_next (rn))    if ((lst = rn->info) != NULL)      {	for (node = listhead (lst); node; node = nextnode (node))	  if ((lsa = getdata (node)) != NULL)	    ospf_lsa_unlock (lsa);	list_delete (lst);      }    route_table_finish (rt);}voidospf_ase_incremental_update (struct ospf *ospf, struct ospf_lsa *lsa){  list lsas;  listnode node;  struct route_node *rn, *rn2;  struct prefix_ipv4 p;  struct route_table *tmp_old;  struct as_external_lsa *al;  al = (struct as_external_lsa *) lsa->data;  p.family = AF_INET;  p.prefix = lsa->data->id;  p.prefixlen = ip_masklen (al->mask);  apply_mask_ipv4 (&p);  /* if new_table is NULL, there was no spf calculation, thus     incremental update is unneeded */  if (!ospf->new_table)    return;    /* If there is already an intra-area or inter-area route     to the destination, no recalculation is necessary     (internal routes take precedence). */    rn = route_node_lookup (ospf->new_table, (struct prefix *) &p);  if (rn && rn->info)    {      route_unlock_node (rn);      return;    }  rn = route_node_lookup (ospf->external_lsas, (struct prefix *) &p);  assert (rn && rn->info);  lsas = rn->info;    for (node = listhead (lsas); node; nextnode (node))    if ((lsa = getdata (node)) != NULL)      ospf_ase_calculate_route (ospf, lsa);  /* prepare temporary old routing table for compare */  tmp_old = route_table_init ();  rn = route_node_lookup (ospf->old_external_route, (struct prefix *) &p);  if (rn && rn->info)    {      rn2 = route_node_get (tmp_old, (struct prefix *) &p);      rn2->info = rn->info;    }  /* install changes to zebra */  ospf_ase_compare_tables (ospf->new_external_route, tmp_old);  /* update ospf->old_external_route table */  if (rn && rn->info)    ospf_route_free ((struct ospf_route *) rn->info);  rn2 = route_node_lookup (ospf->new_external_route, (struct prefix *) &p);  /* if new route exists, install it to ospf->old_external_route */  if (rn2 && rn2->info)    {      if (!rn)	rn = route_node_get (ospf->old_external_route, (struct prefix *) &p);      rn->info = rn2->info;    }  else    {      /* remove route node from ospf->old_external_route */      if (rn)	{	  rn->info = NULL;	  route_unlock_node (rn);	  route_unlock_node (rn);	}    }  if (rn2)    {      /* rn2->info is stored in route node of ospf->old_external_route */      rn2->info = NULL;      route_unlock_node (rn2);      route_unlock_node (rn2);    }  route_table_finish (tmp_old);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -