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

📄 ospf6_asbr.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2001-2002 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 "ospf6_prefix.h"  /* xxx for ospf6_asbr.h */#include "ospf6_lsa.h"     /* xxx for ospf6_asbr.h */#include "ospf6_route.h"   /* xxx for ospf6_asbr.h, ospf6_zebra.h */#include "ospf6_zebra.h"#include "ospf6_asbr.h"#include "ospf6_damp.h"#include "ospf6_top.h"#include "ospf6_lsdb.h"#include "ospf6_proto.h"extern struct thread_master *master;struct route_table *external_table;struct{  char *name;  struct route_map *map;} rmap [ZEBRA_ROUTE_MAX];static u_int32_t link_state_id = 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])/* redistribute function */voidospf6_asbr_routemap_set (int type, char *mapname){  if (rmap[type].name)    free (rmap[type].name);  rmap[type].name = strdup (mapname);  rmap[type].map = route_map_lookup_by_name (mapname);}voidospf6_asbr_routemap_unset (int type){  if (rmap[type].name)    free (rmap[type].name);  rmap[type].name = NULL;  rmap[type].map = NULL;}voidospf6_asbr_routemap_update (){  int i;  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)    {      if (rmap[i].name)        rmap[i].map = route_map_lookup_by_name (rmap[i].name);      else        rmap[i].map = NULL;    }}DEFUN (ospf6_redistribute,       ospf6_redistribute_cmd,       "redistribute (static|kernel|connected|ripng|bgp)",       "Redistribute\n"       "Static route\n"       "Kernel route\n"       "Connected route\n"       "RIPng route\n"       "BGP route\n"      ){  int type = 0;  if (strncmp (argv[0], "sta", 3) == 0)    type = ZEBRA_ROUTE_STATIC;  else if (strncmp (argv[0], "ker", 3) == 0)    type = ZEBRA_ROUTE_KERNEL;  else if (strncmp (argv[0], "con", 3) == 0)    type = ZEBRA_ROUTE_CONNECT;  else if (strncmp (argv[0], "rip", 3) == 0)    type = ZEBRA_ROUTE_RIPNG;  else if (strncmp (argv[0], "bgp", 3) == 0)    type = ZEBRA_ROUTE_BGP;  ospf6_zebra_no_redistribute (type);  ospf6_asbr_routemap_unset (type);  ospf6_zebra_redistribute (type);  return CMD_SUCCESS;}DEFUN (ospf6_redistribute_routemap,       ospf6_redistribute_routemap_cmd,       "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",       "Redistribute\n"       "Static routes\n"       "Kernel route\n"       "Connected route\n"       "RIPng route\n"       "BGP route\n"       "Route map reference\n"       "Route map name\n"      ){  int type = 0;  if (strncmp (argv[0], "sta", 3) == 0)    type = ZEBRA_ROUTE_STATIC;  else if (strncmp (argv[0], "ker", 3) == 0)    type = ZEBRA_ROUTE_KERNEL;  else if (strncmp (argv[0], "con", 3) == 0)    type = ZEBRA_ROUTE_CONNECT;  else if (strncmp (argv[0], "rip", 3) == 0)    type = ZEBRA_ROUTE_RIPNG;  else if (strncmp (argv[0], "bgp", 3) == 0)    type = ZEBRA_ROUTE_BGP;  ospf6_zebra_no_redistribute (type);  ospf6_asbr_routemap_set (type, argv[1]);  ospf6_zebra_redistribute (type);  return CMD_SUCCESS;}DEFUN (no_ospf6_redistribute,       no_ospf6_redistribute_cmd,       "no redistribute (static|kernel|connected|ripng|bgp)",       NO_STR       "Redistribute\n"       "Static route\n"       "Kernel route\n"       "Connected route\n"       "RIPng route\n"       "BGP route\n"      ){  int type = 0;  struct route_node *node;  struct ospf6_external_route *route;  struct ospf6_external_info *info, *info_next = NULL;  if (strncmp (argv[0], "sta", 3) == 0)    type = ZEBRA_ROUTE_STATIC;  else if (strncmp (argv[0], "ker", 3) == 0)    type = ZEBRA_ROUTE_KERNEL;  else if (strncmp (argv[0], "con", 3) == 0)    type = ZEBRA_ROUTE_CONNECT;  else if (strncmp (argv[0], "rip", 3) == 0)    type = ZEBRA_ROUTE_RIPNG;  else if (strncmp (argv[0], "bgp", 3) == 0)    type = ZEBRA_ROUTE_BGP;  ospf6_zebra_no_redistribute (type);  ospf6_asbr_routemap_unset (type);  /* remove redistributed route */  for (node = route_top (external_table); node; node = route_next (node))    {      route = node->info;      if (! route)        continue;      for (info = route->info_head; info; info = info_next)        {          info_next = info->next;          if (info->type != type)            continue;          ospf6_asbr_route_remove (info->type, info->ifindex,                                   &route->prefix);        }    }  return CMD_SUCCESS;}intospf6_redistribute_config_write (struct vty *vty){  int i;  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)    {      if (i == ZEBRA_ROUTE_OSPF6)        continue;      if (! ospf6_zebra_is_redistribute (i))        continue;      if (rmap[i].map)        vty_out (vty, " redistribute %s route-map %s%s",                 ZROUTE_NAME(i), rmap[i].name, VTY_NEWLINE);      else        vty_out (vty, " redistribute %s%s",                 ZROUTE_NAME(i), VTY_NEWLINE);    }  return 0;}voidospf6_redistribute_show_config (struct vty *vty){  int i;  if (! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_SYSTEM) &&      ! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_KERNEL) &&      ! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_STATIC) &&      ! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_RIPNG) &&      ! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_BGP))    return;  vty_out (vty, " Redistributing External Routes from,%s", VTY_NEWLINE);  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)    {      if (i == ZEBRA_ROUTE_OSPF6)        continue;      if (! ospf6_zebra_is_redistribute (i))        continue;      if (rmap[i].map)        vty_out (vty, "    %s with route-map %s%s",                 ZROUTE_NAME(i), rmap[i].name, VTY_NEWLINE);      else        vty_out (vty, "    %s%s", ZROUTE_NAME(i), VTY_NEWLINE);    }}/* AS External LSA origination */intospf6_asbr_external_lsa_originate (struct thread *thread){  struct ospf6_external_info *info;  char buffer [MAXLSASIZE];  struct ospf6_lsa_as_external *e;  char *p;  info = THREAD_ARG (thread);  /* clear thread */  info->thread_originate = NULL;  if (info->is_removed)    {      if (IS_OSPF6_DUMP_ASBR)        {          char pbuf[64];          prefix2str (&info->route->prefix, pbuf, sizeof (pbuf));          zlog_info ("ASBR: quit redistribution %s: state is down",                     pbuf);        }      return 0;    }  /* prepare buffer */  memset (buffer, 0, sizeof (buffer));  e = (struct ospf6_lsa_as_external *) buffer;  p = (char *) (e + 1);  if (info->metric_type == 2)    SET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_E);   /* type2 */  else    UNSET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_E); /* type1, default */  /* forwarding address */  if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))    SET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_F);  else    UNSET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_F);  /* external route tag */  UNSET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_T);  /* set metric. note: related to E bit */  OSPF6_ASBR_METRIC_SET (e, info->metric);  /* prefixlen */  e->prefix.prefix_length = info->route->prefix.prefixlen;  /* PrefixOptions */  e->prefix.prefix_options = info->prefix_options;  /* don't use refer LS-type */  e->prefix.prefix_refer_lstype = htons (0);  /* set Prefix */  memcpy (p, &info->route->prefix.u.prefix6,          OSPF6_PREFIX_SPACE (info->route->prefix.prefixlen));  ospf6_prefix_apply_mask (&e->prefix);  p += OSPF6_PREFIX_SPACE (info->route->prefix.prefixlen);  /* Forwarding address */  if (CHECK_FLAG (e->bits_metric, OSPF6_ASBR_BIT_F))    {      memcpy (p, &info->forwarding, sizeof (struct in6_addr));      p += sizeof (struct in6_addr);    }  /* External Route Tag */  if (CHECK_FLAG (e->bits_metric, OSPF6_ASBR_BIT_T))    {      /* xxx */    }  ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_AS_EXTERNAL),                       htonl (info->id), ospf6->router_id,                       (char *) buffer, p - buffer, ospf6);  return 0;}intospf6_asbr_schedule_external (void *data){  struct ospf6_external_info *info = data;  u_long elasped_time, time = 0;  if (info->thread_originate)    {      if (IS_OSPF6_DUMP_ASBR)        {          char pbuf[64];          prefix2str (&info->route->prefix, pbuf, sizeof (pbuf));          zlog_info ("ASBR: schedule redistribution %s: another thread",                     pbuf);        }      return 0;    }  elasped_time =    ospf6_lsa_has_elasped (htons (OSPF6_LSA_TYPE_AS_EXTERNAL),                           htonl (info->id), ospf6->router_id, ospf6);  if (elasped_time < OSPF6_MIN_LS_INTERVAL)    time = OSPF6_MIN_LS_INTERVAL - elasped_time;  else    time = 0;  //if (IS_OSPF6_DUMP_ASBR)    {      char pbuf[64];      prefix2str (&info->route->prefix, pbuf, sizeof (pbuf));      zlog_info ("ASBR: schedule redistribution %s as LS-ID %ld after %lu sec",                 pbuf, (u_long) info->id, time);    }  if (time)    info->thread_originate =      thread_add_timer (master, ospf6_asbr_external_lsa_originate, info, time);  else    info->thread_originate =      thread_add_timer (master, ospf6_asbr_external_lsa_originate, info, 0);  return 0;}intospf6_asbr_external_lsa_flush (void *data){  struct ospf6_lsa *lsa = data;  if (lsa)    ospf6_lsa_premature_aging (lsa);  return 0;}intospf6_asbr_external_lsa_refresh (void *data){  struct ospf6_lsa *lsa = data;  struct ospf6_lsa_as_external *e;  struct prefix prefix;  struct route_node *node;  struct ospf6_external_route *route = NULL;  struct ospf6_external_info *info = NULL;  struct ospf6_external_info *match = NULL;  if (IS_OSPF6_DUMP_ASBR)    zlog_info ("ASBR: refresh %s", lsa->str);  e = (struct ospf6_lsa_as_external *) (lsa->header + 1);  ospf6_prefix_in6_addr (&e->prefix, &prefix.u.prefix6);  prefix.prefixlen = e->prefix.prefix_length;  prefix.family = AF_INET6;  apply_mask_ipv6 ((struct prefix_ipv6 *) &prefix);  for (node = route_top (external_table); node; node = route_next (node))    {      route = node->info;      if (route == NULL)        continue;      for (info = route->info_head; info; info = info->next)        {          if (lsa->header->id == htonl (info->id))            match = info;        }    }  if (match == NULL)    {      ospf6_lsa_premature_aging (lsa);      return 0;    }  ospf6_asbr_schedule_external (match);  return 0;#if 0  node = route_node_lookup (external_table, &prefix);  if (! node || ! node->info)    {      char pname[64];      prefix2str (&prefix, pname, sizeof (pname));      if (IS_OSPF6_DUMP_ASBR)        zlog_info ("ASBR: could not find %s: premature age", pname);      ospf6_lsa_premature_aging (lsa);      return 0;    }  /* find external_info */  route = node->info;  for (info = route->info_head; info; info = info->next)    {      if (lsa->header->id == htonl (info->id))        break;    }  if (info)    ospf6_asbr_schedule_external (info);  else    ospf6_lsa_premature_aging (lsa);  return 0;#endif}voidospf6_asbr_route_add (int type, int ifindex, struct prefix *prefix,                      u_int nexthop_num, struct in6_addr *nexthop){  int ret;  struct route_node *node;  struct ospf6_external_route *route;  struct ospf6_external_info *info, tinfo;  if (! ospf6_zebra_is_redistribute (type))    return;  /* apply route-map */  memset (&tinfo, 0, sizeof (struct ospf6_external_info));  if (rmap[type].map)    {      ret = route_map_apply (rmap[type].map, prefix, RMAP_OSPF6, &tinfo);      if (ret == RMAP_DENYMATCH)        {          if (IS_OSPF6_DUMP_ASBR)            zlog_info ("ASBR: denied by route-map %s", rmap[type].name);          return;        }    }  node = route_node_get (external_table, prefix);  route = node->info;  if (! route)    {      route = XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO,                       sizeof (struct ospf6_external_route));      memset (route, 0, sizeof (struct ospf6_external_route));      memcpy (&route->prefix, prefix, sizeof (struct prefix));      node->info = route;      route->node = node;    }  for (info = route->info_head; info; info = info->next)    {      if (info->type == type && info->ifindex == ifindex)        break;    }  if (! info)    {      info = XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO,                      sizeof (struct ospf6_external_info));      memset (info, 0, sizeof (struct ospf6_external_info));      info->route = route;      /* add tail */

⌨️ 快捷键说明

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