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

📄 ospf_ia.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * OSPF inter-area routing. * Copyright (C) 1999, 2000 Alex Zinin, Toshiaki Takada * * This file is part of GNU Zebra. * * GNU Zebra is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * GNU Zebra is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Zebra; see the file COPYING.  If not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */#include <zebra.h>#include "thread.h"#include "memory.h"#include "hash.h"#include "linklist.h"#include "prefix.h"#include "table.h"#include "log.h"#include "ospfd/ospfd.h"#include "ospfd/ospf_interface.h"#include "ospfd/ospf_ism.h"#include "ospfd/ospf_asbr.h"#include "ospfd/ospf_lsa.h"#include "ospfd/ospf_lsdb.h"#include "ospfd/ospf_neighbor.h"#include "ospfd/ospf_nsm.h"#include "ospfd/ospf_spf.h"#include "ospfd/ospf_route.h"#include "ospfd/ospf_ase.h"#include "ospfd/ospf_abr.h"#include "ospfd/ospf_ia.h"#include "ospfd/ospf_dump.h"#define DEBUGstruct ospf_route *ospf_find_abr_route (struct route_table *rtrs,                      struct prefix_ipv4 *abr,                     struct ospf_area *area){  struct route_node *rn;  struct ospf_route *or;  listnode node;  if ((rn = route_node_lookup (rtrs, (struct prefix *) abr)) == NULL)    return NULL;  route_unlock_node (rn);  for (node = listhead ((list) rn->info); node; nextnode (node))    if ((or = getdata (node)) != NULL)      if (IPV4_ADDR_SAME (&or->u.std.area_id, &area->area_id) && (or->u.std.flags & ROUTER_LSA_BORDER))	return or;  return NULL;}voidospf_ia_network_route (struct ospf *ospf, struct route_table *rt,		       struct prefix_ipv4 *p, struct ospf_route *new_or,		       struct ospf_route *abr_or){  struct route_node *rn1;  struct ospf_route *or;  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("ospf_ia_network_route(): processing summary route to %s/%d", 	       inet_ntoa (p->prefix), p->prefixlen);  /* Find a route to the same dest */  if ((rn1 = route_node_lookup (rt, (struct prefix *) p)))    {      int res;      route_unlock_node (rn1);      if ((or = rn1->info))	{	  if (IS_DEBUG_OSPF_EVENT)	    zlog_info ("ospf_ia_network_route(): "		       "Found a route to the same network");	  /* Check the existing route. */	  if ((res = ospf_route_cmp (ospf, new_or, or)) < 0)	    {	      /* New route is better, so replace old one. */	      ospf_route_subst (rn1, new_or, abr_or);	    }	  else if (res == 0)	    {	      /* New and old route are equal, so next hops can be added. */	      route_lock_node (rn1);	      ospf_route_copy_nexthops (or, abr_or->path);	      route_unlock_node (rn1);	      /* new route can be deleted, because existing route has been updated. */	      ospf_route_free (new_or);	    }	  else	    {	      /* New route is worse, so free it. */	      ospf_route_free (new_or);	      return;	    }	} /* if (or)*/    } /*if (rn1)*/  else    { /* no route */      if (IS_DEBUG_OSPF_EVENT)	zlog_info ("ospf_ia_network_route(): add new route to %s/%d",		   inet_ntoa (p->prefix), p->prefixlen);      ospf_route_add (rt, p, new_or, abr_or);    }}voidospf_ia_router_route (struct ospf *ospf, struct route_table *rtrs,		      struct prefix_ipv4 *p,                      struct ospf_route *new_or, struct ospf_route *abr_or){  struct ospf_route *or = NULL;  struct route_node *rn;  int ret;  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("ospf_ia_router_route(): considering %s/%d", 	       inet_ntoa (p->prefix), p->prefixlen);  /* Find a route to the same dest */  rn = route_node_get (rtrs, (struct prefix *) p);     if (rn->info == NULL)    /* This is a new route */    rn->info = list_new ();  else    {      struct ospf_area *or_area;      or_area = ospf_area_lookup_by_area_id (ospf, new_or->u.std.area_id);      assert (or_area);      /* This is an additional route */      route_unlock_node (rn);      or = ospf_find_asbr_route_through_area (rtrs, p, or_area);    }  if (or)    {      if (IS_DEBUG_OSPF_EVENT)	zlog_info ("ospf_ia_router_route(): "		   "a route to the same ABR through the same area exists");      /* New route is better */      if ((ret = ospf_route_cmp (ospf, new_or, or)) < 0)	{	  listnode_delete (rn->info, or);	  ospf_route_free (or);	  /* proceed down */	}      /* Routes are the same */      else if (ret == 0)	{	  if (IS_DEBUG_OSPF_EVENT)	    zlog_info ("ospf_ia_router_route(): merging the new route");	  ospf_route_copy_nexthops (or, abr_or->path);	  ospf_route_free (new_or);	  return;	}      /* New route is worse */      else	{	  if (IS_DEBUG_OSPF_EVENT)	    zlog_info ("ospf_ia_router_route(): skipping the new route");	  ospf_route_free (new_or);	  return;	}    }  ospf_route_copy_nexthops (new_or, abr_or->path);  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("ospf_ia_router_route(): adding the new route");   listnode_add (rn->info, new_or);}intprocess_summary_lsa (struct ospf_area *area, struct route_table *rt,		     struct route_table *rtrs, struct ospf_lsa *lsa){  struct ospf *ospf = area->ospf;  struct ospf_area_range *range;  struct ospf_route *abr_or, *new_or;  struct summary_lsa *sl;  struct prefix_ipv4 p, abr;  u_int32_t metric;  if (lsa == NULL)    return 0;  sl = (struct summary_lsa *) lsa->data;  if (IS_DEBUG_OSPF_EVENT)    zlog_info ("process_summary_lsa(): LS ID: %s", inet_ntoa (sl->header.id));  metric = GET_METRIC (sl->metric);     if (metric == OSPF_LS_INFINITY)    return 0;  if (IS_LSA_MAXAGE (lsa))    return 0;  if (ospf_lsa_is_self_originated (area->ospf, lsa))    return 0;  p.family = AF_INET;  p.prefix = sl->header.id;     if (sl->header.type == OSPF_SUMMARY_LSA)    p.prefixlen = ip_masklen (sl->mask);  else    p.prefixlen = IPV4_MAX_BITLEN;        apply_mask_ipv4 (&p);  if (sl->header.type == OSPF_SUMMARY_LSA &&      (range = ospf_area_range_match_any (ospf, &p)) &&      ospf_area_range_active (range))    return 0;  if (ospf->abr_type != OSPF_ABR_STAND &&      area->external_routing != OSPF_AREA_DEFAULT &&      p.prefix.s_addr == OSPF_DEFAULT_DESTINATION &&      p.prefixlen == 0)    return 0; /* Ignore summary default from a stub area */  abr.family = AF_INET;  abr.prefix = sl->header.adv_router;  abr.prefixlen = IPV4_MAX_BITLEN;  apply_mask_ipv4 (&abr);  abr_or = ospf_find_abr_route (rtrs, &abr, area);  if (abr_or == NULL)    return 0;  new_or = ospf_route_new ();  new_or->type = OSPF_DESTINATION_NETWORK;  new_or->id = sl->header.id;  new_or->mask = sl->mask;  new_or->u.std.options = sl->header.options;  new_or->u.std.origin = (struct lsa_header *) sl;  new_or->cost = abr_or->cost + metric;  new_or->u.std.area_id = area->area_id;#ifdef HAVE_NSSA  new_or->u.std.external_routing = area->external_routing;#endif /* HAVE_NSSA */  new_or->path_type = OSPF_PATH_INTER_AREA;  if (sl->header.type == OSPF_SUMMARY_LSA)    ospf_ia_network_route (ospf, rt, &p, new_or, abr_or);  else     {      new_or->type = OSPF_DESTINATION_ROUTER;      new_or->u.std.flags = ROUTER_LSA_EXTERNAL;      ospf_ia_router_route (ospf, rtrs, &p, new_or, abr_or);    }  return 0;}voidospf_examine_summaries (struct ospf_area *area,			struct route_table *lsdb_rt,                        struct route_table *rt,                        struct route_table *rtrs){  struct ospf_lsa *lsa;  struct route_node *rn;  LSDB_LOOP (lsdb_rt, rn, lsa)    process_summary_lsa (area, rt, rtrs, lsa);}intospf_area_is_transit (struct ospf_area *area){  return (area->transit == OSPF_TRANSIT_TRUE) ||    ospf_full_virtual_nbrs(area); /* Cisco forgets to set the V-bit :( */}voidospf_update_network_route (struct ospf *ospf,			   struct route_table *rt,                            struct route_table *rtrs,                           struct summary_lsa *lsa,                           struct prefix_ipv4 *p,                           struct ospf_area *area){  struct route_node *rn;  struct ospf_route *or, *abr_or, *new_or;  struct prefix_ipv4 abr;  u_int32_t cost;  abr.family = AF_INET;  abr.prefix =lsa->header.adv_router;  abr.prefixlen = IPV4_MAX_BITLEN;  apply_mask_ipv4 (&abr);  abr_or = ospf_find_abr_route (rtrs, &abr, area);  if (abr_or == NULL)    {      if (IS_DEBUG_OSPF_EVENT)	zlog_info ("ospf_update_network_route(): can't find a route to the ABR");      return;    }  cost = abr_or->cost + GET_METRIC (lsa->metric);  rn = route_node_lookup (rt, (struct prefix *) p);  if (! rn)    {      if (ospf->abr_type != OSPF_ABR_SHORTCUT)        return; /* Standard ABR can update only already installed                   backbone paths                                       */      if (IS_DEBUG_OSPF_EVENT)	zlog_info ("ospf_update_network_route(): "		   "Allowing Shortcut ABR to add new route");      new_or = ospf_route_new ();      new_or->type = OSPF_DESTINATION_NETWORK;      new_or->id = lsa->header.id;      new_or->mask = lsa->mask;      new_or->u.std.options = lsa->header.options;      new_or->u.std.origin = (struct lsa_header *) lsa;      new_or->cost = cost;      new_or->u.std.area_id = area->area_id;#ifdef HAVE_NSSA      new_or->u.std.external_routing = area->external_routing;#endif /* HAVE_NSSA */      new_or->path_type = OSPF_PATH_INTER_AREA;      ospf_route_add (rt, p, new_or, abr_or);      return;    }  else    {      route_unlock_node (rn);      if (rn->info == NULL)        return;

⌨️ 快捷键说明

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