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

📄 ospf6_asbr.c

📁 linux 路由软件 可支持RIP OSPF BGP等
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2003 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 "memory.h"#include "prefix.h"#include "command.h"#include "vty.h"#include "routemap.h"#include "table.h"#include "plist.h"#include "thread.h"#include "linklist.h"#include "ospf6_proto.h"#include "ospf6_lsa.h"#include "ospf6_lsdb.h"#include "ospf6_route.h"#include "ospf6_zebra.h"#include "ospf6_message.h"#include "ospf6_top.h"#include "ospf6_area.h"#include "ospf6_interface.h"#include "ospf6_neighbor.h"#include "ospf6_asbr.h"#include "ospf6_intra.h"#include "ospf6_flood.h"#include "ospf6d.h"unsigned char conf_debug_ospf6_asbr = 0;char *zroute_name[] ={ "system", "kernel", "connected", "static",  "rip", "ripng", "ospf", "ospf6", "bgp", "unknown" };char *zroute_abname[] ={ "X", "K", "C", "S", "R", "R", "O", "O", "B", "?" };#define ZROUTE_NAME(x)                                     \  (0 < (x) && (x) < ZEBRA_ROUTE_MAX ? zroute_name[(x)] :   \   zroute_name[ZEBRA_ROUTE_MAX])#define ZROUTE_ABNAME(x)                                   \  (0 < (x) && (x) < ZEBRA_ROUTE_MAX ? zroute_abname[(x)] : \   zroute_abname[ZEBRA_ROUTE_MAX])/* AS External LSA origination */voidospf6_as_external_lsa_originate (struct ospf6_route *route){  char buffer[OSPF6_MAX_LSASIZE];  struct ospf6_lsa_header *lsa_header;  struct ospf6_lsa *old, *lsa;  struct ospf6_as_external_lsa *as_external_lsa;  char buf[64];  caddr_t p;  /* find previous LSA */  old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),                           route->path.origin.id, ospf6->router_id,                           ospf6->lsdb);  if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL))    {      prefix2str (&route->prefix, buf, sizeof (buf));      zlog_info ("Originate AS-External-LSA for %s", buf);    }  /* prepare buffer */  memset (buffer, 0, sizeof (buffer));  lsa_header = (struct ospf6_lsa_header *) buffer;  as_external_lsa = (struct ospf6_as_external_lsa *)    ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));  p = (caddr_t)    ((caddr_t) as_external_lsa + sizeof (struct ospf6_as_external_lsa));  /* Fill AS-External-LSA */  /* Metric type */  if (route->path.metric_type == 2)    SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);  else    UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);  /* forwarding address */  if (! IN6_IS_ADDR_UNSPECIFIED (&route->nexthop[0].address))    SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);  else    UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);  /* external route tag */  UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);  /* Set metric */  OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);  /* prefixlen */  as_external_lsa->prefix.prefix_length = route->prefix.prefixlen;  /* PrefixOptions */  as_external_lsa->prefix.prefix_options = route->path.prefix_options;  /* don't use refer LS-type */  as_external_lsa->prefix.prefix_refer_lstype = htons (0);  /* set Prefix */  memcpy (p, &route->prefix.u.prefix6,          OSPF6_PREFIX_SPACE (route->prefix.prefixlen));  ospf6_prefix_apply_mask (&as_external_lsa->prefix);  p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);  /* Forwarding address */  if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))    {      memcpy (p, &route->nexthop[0].address, sizeof (struct in6_addr));      p += sizeof (struct in6_addr);    }  /* External Route Tag */  if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))    {      /* xxx */    }  /* Fill LSA Header */  lsa_header->age = 0;  lsa_header->type = htons (OSPF6_LSTYPE_AS_EXTERNAL);  lsa_header->id = route->path.origin.id;  lsa_header->adv_router = ospf6->router_id;  lsa_header->seqnum =    ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,                         lsa_header->adv_router, ospf6->lsdb);  lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);  /* LSA checksum */  ospf6_lsa_checksum (lsa_header);  /* create LSA */  lsa = ospf6_lsa_create (lsa_header);  /* Originate */  ospf6_lsa_originate_process (lsa, ospf6);}voidospf6_asbr_lsa_add (struct ospf6_lsa *lsa){  struct ospf6_as_external_lsa *external;  struct prefix asbr_id;  struct ospf6_route *asbr_entry, *route;  char buf[64];  int i;  external = (struct ospf6_as_external_lsa *)    OSPF6_LSA_HEADER_END (lsa->header);  if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))    zlog_info ("Calculate AS-External route for %s", lsa->name);  if (lsa->header->adv_router == ospf6->router_id)    {      if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))        zlog_info ("Ignore self-originated AS-External-LSA");      return;    }  if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)    {      if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))        zlog_info ("Ignore LSA with LSInfinity Metric");      return;    }  ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &asbr_id);  asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table);  if (asbr_entry == NULL ||      ! CHECK_FLAG (asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E))    {      if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))        {          prefix2str (&asbr_id, buf, sizeof (buf));          zlog_info ("ASBR entry not found: %s", buf);        }      return;    }  route = ospf6_route_create ();  route->type = OSPF6_DEST_TYPE_NETWORK;  route->prefix.family = AF_INET6;  route->prefix.prefixlen = external->prefix.prefix_length;  ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix);  route->path.area_id = asbr_entry->path.area_id;  route->path.origin.type = lsa->header->type;  route->path.origin.id = lsa->header->id;  route->path.origin.adv_router = lsa->header->adv_router;  route->path.prefix_options = external->prefix.prefix_options;  if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))    {      route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;      route->path.metric_type = 2;      route->path.cost = asbr_entry->path.cost;      route->path.cost_e2 = OSPF6_ASBR_METRIC (external);    }  else    {      route->path.type = OSPF6_PATH_TYPE_EXTERNAL1;      route->path.metric_type = 1;      route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external);      route->path.cost_e2 = 0;    }  for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)    ospf6_nexthop_copy (&route->nexthop[i], &asbr_entry->nexthop[i]);  if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))    {      prefix2str (&route->prefix, buf, sizeof (buf));      zlog_info ("AS-External route add: %s", buf);    }  ospf6_route_add (route, ospf6->route_table);}voidospf6_asbr_lsa_remove (struct ospf6_lsa *lsa){  struct ospf6_as_external_lsa *external;  struct prefix prefix;  struct ospf6_route *route;  char buf[64];  external = (struct ospf6_as_external_lsa *)    OSPF6_LSA_HEADER_END (lsa->header);  if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))    zlog_info ("Withdraw AS-External route for %s", lsa->name);  if (lsa->header->adv_router == ospf6->router_id)    {      if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))        zlog_info ("Ignore self-originated AS-External-LSA");      return;    }  memset (&prefix, 0, sizeof (struct prefix));  prefix.family = AF_INET6;  prefix.prefixlen = external->prefix.prefix_length;  ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix);  route = ospf6_route_lookup (&prefix, ospf6->route_table);  if (route == NULL)    {      if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))        {          prefix2str (&prefix, buf, sizeof (buf));          zlog_info ("AS-External route %s not found", buf);        }      return;    }  for (ospf6_route_lock (route);       route && ospf6_route_is_prefix (&prefix, route);       route = ospf6_route_next (route))    {      if (route->type != OSPF6_DEST_TYPE_NETWORK)        continue;      if (route->path.origin.type != lsa->header->type)        continue;      if (route->path.origin.id != lsa->header->id)        continue;      if (route->path.origin.adv_router != lsa->header->adv_router)        continue;      if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))        {          prefix2str (&route->prefix, buf, sizeof (buf));          zlog_info ("AS-External route remove: %s", buf);        }      ospf6_route_remove (route, ospf6->route_table);    }}voidospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry){  char buf[64];  struct ospf6_lsa *lsa;  u_int16_t type;  u_int32_t router;  if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))    {      ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));      zlog_info ("New ASBR %s found", buf);    }  type = htons (OSPF6_LSTYPE_AS_EXTERNAL);  router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);  for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);       lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))    {      if (! OSPF6_LSA_IS_MAXAGE (lsa))        ospf6_asbr_lsa_add (lsa);    }  if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))    {      ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));      zlog_info ("Calculation for new ASBR %s done", buf);    }}voidospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry){  char buf[64];  struct ospf6_lsa *lsa;  u_int16_t type;  u_int32_t router;  if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))    {      ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));      zlog_info ("ASBR %s disappeared", buf);    }  type = htons (OSPF6_LSTYPE_AS_EXTERNAL);  router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);  for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);       lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))    ospf6_asbr_lsa_remove (lsa);  if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))    {      ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));      zlog_info ("Calculation for old ASBR %s done", buf);    }}/* redistribute function */voidospf6_asbr_routemap_set (int type, char *mapname){  if (ospf6->rmap[type].name)    free (ospf6->rmap[type].name);  ospf6->rmap[type].name = strdup (mapname);  ospf6->rmap[type].map = route_map_lookup_by_name (mapname);}voidospf6_asbr_routemap_unset (int type){  if (ospf6->rmap[type].name)    free (ospf6->rmap[type].name);  ospf6->rmap[type].name = NULL;  ospf6->rmap[type].map = NULL;}voidospf6_asbr_routemap_update (char *mapname){  int type;  if (ospf6 == NULL)    return;  for (type = 0; type < ZEBRA_ROUTE_MAX; type++)    {      if (ospf6->rmap[type].name)        ospf6->rmap[type].map =          route_map_lookup_by_name (ospf6->rmap[type].name);      else        ospf6->rmap[type].map = NULL;    }}intospf6_asbr_is_asbr (struct ospf6 *o){  return o->external_table->count;}voidospf6_asbr_redistribute_set (int type){  ospf6_zebra_redistribute (type);}voidospf6_asbr_redistribute_unset (int type){  struct ospf6_route *route;  struct ospf6_external_info *info;  ospf6_zebra_no_redistribute (type);  for (route = ospf6_route_head (ospf6->external_table); route;       route = ospf6_route_next (route))    {      info = route->route_option;      if (info->type != type)        continue;      ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,                                      &route->prefix);    }}

⌨️ 快捷键说明

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