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

📄 ospf6_abr.c

📁 linux 路由软件 可支持RIP OSPF BGP等
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Area Border Router function. * Copyright (C) 2004 Yasuhiro Ohara * * 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 "log.h"#include "prefix.h"#include "table.h"#include "vty.h"#include "linklist.h"#include "command.h"#include "thread.h"#include "ospf6_proto.h"#include "ospf6_route.h"#include "ospf6_lsa.h"#include "ospf6_route.h"#include "ospf6_lsdb.h"#include "ospf6_message.h"#include "ospf6_top.h"#include "ospf6_area.h"#include "ospf6_interface.h"#include "ospf6_neighbor.h"#include "ospf6_flood.h"#include "ospf6_intra.h"#include "ospf6_abr.h"#include "ospf6d.h"unsigned char conf_debug_ospf6_abr;intospf6_is_router_abr (struct ospf6 *o){  listnode node;  struct ospf6_area *oa;  int area_count = 0;  for (node = listhead (o->area_list); node; nextnode (node))    {      oa = OSPF6_AREA (getdata (node));      if (IS_AREA_ENABLED (oa))        area_count++;    }  if (area_count > 1)    return 1;  return 0;}voidospf6_abr_enable_area (struct ospf6_area *area){  struct ospf6_area *oa;  struct ospf6_route *ro;  listnode node;  for (node = listhead (area->ospf6->area_list); node; nextnode (node))    {      oa = OSPF6_AREA (getdata (node));      /* update B bit for each area */      OSPF6_ROUTER_LSA_SCHEDULE (oa);      /* install other area's configured address range */      if (oa != area)        {          for (ro = ospf6_route_head (oa->range_table); ro;               ro = ospf6_route_next (ro))            {              if (CHECK_FLAG (ro->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))                ospf6_abr_originate_summary_to_area (ro, area);            }        }    }  /* install calculated routes to border routers */  for (ro = ospf6_route_head (area->ospf6->brouter_table); ro;       ro = ospf6_route_next (ro))    ospf6_abr_originate_summary_to_area (ro, area);  /* install calculated routes to network (may be rejected by ranges) */  for (ro = ospf6_route_head (area->ospf6->route_table); ro;       ro = ospf6_route_next (ro))    ospf6_abr_originate_summary_to_area (ro, area);}voidospf6_abr_disable_area (struct ospf6_area *area){  struct ospf6_area *oa;  struct ospf6_route *ro;  struct ospf6_lsa *old;  listnode node;  /* Withdraw all summary prefixes previously originated */  for (ro = ospf6_route_head (area->summary_prefix); ro;       ro = ospf6_route_next (ro))    {      old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id,                               area->ospf6->router_id, area->lsdb);      if (old)        ospf6_lsa_purge (old);      ospf6_route_remove (ro, area->summary_prefix);    }  /* Withdraw all summary router-routes previously originated */  for (ro = ospf6_route_head (area->summary_router); ro;       ro = ospf6_route_next (ro))    {      old = ospf6_lsdb_lookup (ro->path.origin.type, ro->path.origin.id,                               area->ospf6->router_id, area->lsdb);      if (old)        ospf6_lsa_purge (old);      ospf6_route_remove (ro, area->summary_router);    }  /* Schedule Router-LSA for each area (ABR status may change) */  for (node = listhead (area->ospf6->area_list); node; nextnode (node))    {      oa = OSPF6_AREA (getdata (node));      /* update B bit for each area */      OSPF6_ROUTER_LSA_SCHEDULE (oa);    }}/* RFC 2328 12.4.3. Summary-LSAs */voidospf6_abr_originate_summary_to_area (struct ospf6_route *route,                                     struct ospf6_area *area){  struct ospf6_lsa *lsa, *old = NULL;  struct ospf6_interface *oi;  struct ospf6_route *summary, *range = NULL;  struct ospf6_area *route_area;  char buffer[OSPF6_MAX_LSASIZE];  struct ospf6_lsa_header *lsa_header;  caddr_t p;  struct ospf6_inter_prefix_lsa *prefix_lsa;  struct ospf6_inter_router_lsa *router_lsa;  struct ospf6_route_table *summary_table = NULL;  u_int16_t type;  char buf[64];  int is_debug = 0;  if (route->type == OSPF6_DEST_TYPE_ROUTER)    {      if (IS_OSPF6_DEBUG_ABR || IS_OSPF6_DEBUG_ORIGINATE (INTER_ROUTER))        {          is_debug++;          inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)),                     buf, sizeof (buf));          zlog_info ("Originating summary in area %s for ASBR %s",                     area->name, buf);        }      summary_table = area->summary_router;    }  else    {      if (IS_OSPF6_DEBUG_ABR || IS_OSPF6_DEBUG_ORIGINATE (INTER_PREFIX))        {          is_debug++;          prefix2str (&route->prefix, buf, sizeof (buf));          zlog_info ("Originating summary in area %s for %s",                     area->name, buf);        }      summary_table = area->summary_prefix;    }  summary = ospf6_route_lookup (&route->prefix, summary_table);  if (summary)    old = ospf6_lsdb_lookup (summary->path.origin.type,                             summary->path.origin.id,                             area->ospf6->router_id, area->lsdb);  /* if this route has just removed, remove corresponding LSA */  if (CHECK_FLAG (route->flag, OSPF6_ROUTE_REMOVE))    {      if (is_debug)        zlog_info ("The route has just removed, purge previous LSA");      if (summary)        ospf6_route_remove (summary, summary_table);      if (old)        ospf6_lsa_purge (old);      return;    }  /* Only destination type network, range or ASBR are considered */  if (route->type != OSPF6_DEST_TYPE_NETWORK &&      route->type != OSPF6_DEST_TYPE_RANGE &&      (route->type != OSPF6_DEST_TYPE_ROUTER ||       ! CHECK_FLAG (route->path.router_bits, OSPF6_ROUTER_BIT_E)))    {      if (is_debug)        zlog_info ("Route type is none of network, range nor ASBR, withdraw");      if (summary)        ospf6_route_remove (summary, summary_table);      if (old)        ospf6_lsa_purge (old);      return;    }  /* AS External routes are never considered */  if (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1 ||      route->path.type == OSPF6_PATH_TYPE_EXTERNAL2)    {      if (is_debug)        zlog_info ("Path type is external, withdraw");      if (summary)        ospf6_route_remove (summary, summary_table);      if (old)        ospf6_lsa_purge (old);      return;    }  /* do not generate if the path's area is the same as target area */  if (route->path.area_id == area->area_id)    {      if (is_debug)        zlog_info ("The route is in the area itself, ignore");      if (summary)        ospf6_route_remove (summary, summary_table);      if (old)        ospf6_lsa_purge (old);      return;    }  /* do not generate if the nexthops belongs to the target area */  oi = ospf6_interface_lookup_by_ifindex (route->nexthop[0].ifindex);  if (oi && oi->area && oi->area == area)    {      if (is_debug)        zlog_info ("The route's nexthop is in the same area, ignore");      if (summary)        ospf6_route_remove (summary, summary_table);      if (old)        ospf6_lsa_purge (old);      return;    }  /* do not generate if the route cost is greater or equal to LSInfinity */  if (route->path.cost >= LS_INFINITY)    {      if (is_debug)        zlog_info ("The cost exceeds LSInfinity, withdraw");      if (summary)        ospf6_route_remove (summary, summary_table);      if (old)        ospf6_lsa_purge (old);      return;    }  /* if this is a route to ASBR */  if (route->type == OSPF6_DEST_TYPE_ROUTER)    {      /* Only the prefered best path is considered */      if (! CHECK_FLAG (route->flag, OSPF6_ROUTE_BEST))        {          if (is_debug)            zlog_info ("This is the secondary path to the ASBR, ignore");          if (summary)            ospf6_route_remove (summary, summary_table);          if (old)            ospf6_lsa_purge (old);          return;        }      /* Do not generate if the area is stub */      /* XXX */    }  /* if this is an intra-area route, this may be suppressed by aggregation */  if (route->type == OSPF6_DEST_TYPE_NETWORK &&      route->path.type == OSPF6_PATH_TYPE_INTRA)    {      /* search for configured address range for the route's area */      route_area = ospf6_area_lookup (route->path.area_id, area->ospf6);      assert (route_area);      range = ospf6_route_lookup_bestmatch (&route->prefix,                                            route_area->range_table);      /* ranges are ignored when originate backbone routes to transit area.         Otherwise, if ranges are configured, the route is suppressed. */      if (range && ! CHECK_FLAG (range->flag, OSPF6_ROUTE_REMOVE) &&          (route->path.area_id != BACKBONE_AREA_ID ||           ! IS_AREA_TRANSIT (area)))        {          if (is_debug)            {              prefix2str (&range->prefix, buf, sizeof (buf));              zlog_info ("Suppressed by range %s of area %s",                         buf, route_area->name);            }          if (summary)            ospf6_route_remove (summary, summary_table);          if (old)            ospf6_lsa_purge (old);          return;        }    }  /* If this is a configured address range */  if (route->type == OSPF6_DEST_TYPE_RANGE)    {      /* If DoNotAdvertise is set */      if (CHECK_FLAG (route->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE))        {          if (is_debug)            zlog_info ("This is the range with DoNotAdvertise set. ignore");          if (summary)            ospf6_route_remove (summary, summary_table);          if (old)            ospf6_lsa_purge (old);          return;        }      /* Whether the route have active longer prefix */      if (! CHECK_FLAG (route->flag, OSPF6_ROUTE_ACTIVE_SUMMARY))        {          if (is_debug)            zlog_info ("The range is not active. withdraw");          if (summary)            ospf6_route_remove (summary, summary_table);          if (old)            ospf6_lsa_purge (old);          return;        }    }  /* the route is going to be originated. store it in area's summary_table */  if (summary == NULL)    {      summary = ospf6_route_copy (route);      if (route->type == OSPF6_DEST_TYPE_NETWORK ||          route->type == OSPF6_DEST_TYPE_RANGE)        summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_PREFIX);      else        summary->path.origin.type = htons (OSPF6_LSTYPE_INTER_ROUTER);      summary->path.origin.adv_router = area->ospf6->router_id;      summary->path.origin.id =        ospf6_new_ls_id (summary->path.origin.type,                         summary->path.origin.adv_router, area->lsdb);      summary = ospf6_route_add (summary, summary_table);    }  else    {      summary->type = route->type;      gettimeofday (&summary->changed, NULL);    }  summary->path.router_bits = route->path.router_bits;  summary->path.options[0] = route->path.options[0];  summary->path.options[1] = route->path.options[1];  summary->path.options[2] = route->path.options[2];  summary->path.prefix_options = route->path.prefix_options;  summary->path.area_id = area->area_id;  summary->path.type = OSPF6_PATH_TYPE_INTER;  summary->path.cost = route->path.cost;  summary->nexthop[0] = route->nexthop[0];  /* prepare buffer */  memset (buffer, 0, sizeof (buffer));  lsa_header = (struct ospf6_lsa_header *) buffer;  if (route->type == OSPF6_DEST_TYPE_ROUTER)    {      router_lsa = (struct ospf6_inter_router_lsa *)        ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));      p = (caddr_t) router_lsa + sizeof (struct ospf6_inter_router_lsa);      /* Fill Inter-Area-Router-LSA */      router_lsa->options[0] = route->path.options[0];      router_lsa->options[1] = route->path.options[1];      router_lsa->options[2] = route->path.options[2];

⌨️ 快捷键说明

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