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

📄 ospf6_abr.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2001 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 "ospf6d.h"#include "ospf6_dump.h"#include "ospf6_abr.h"static int abr_index;#define IS_OSPF6_DUMP_ABR (ospf6_dump_is_on (abr_index))#define ADD    0#define CHANGE 1#define REMOVE 2/* Inter-Area-Prefix-LSA Calculation */static struct ospf6_route_req *ospf6_abr_entry_lookup (struct ospf6_route_req *abr_entry,                        u_int32_t router_id, struct ospf6_area *area){  struct prefix_ls abr_id;  char router_string[32];  inet_ntop (AF_INET, &router_id, router_string, sizeof (router_string));  //zlog_info ("ABR:   Finding router %s in area %s", router_string, area->str);  memset (&abr_id, 0, sizeof (abr_id));  abr_id.family = AF_UNSPEC;  abr_id.prefixlen = 64; /* xxx */  abr_id.id.s_addr = htonl (0);  abr_id.adv_router.s_addr = router_id;  ospf6_route_lookup (abr_entry, (struct prefix *) &abr_id,                      area->table_topology);  if (ospf6_route_end (abr_entry))    {      if (IS_OSPF6_DUMP_ABR)        zlog_info ("ABR:   Router %s not found in area %s",                   router_string, area->str);      return NULL;    }  if (abr_entry->path.area_id != area->area_id)    {      if (IS_OSPF6_DUMP_ABR)        zlog_info ("ABR: ABR area id mismatch");      return NULL;    }  if (! CHECK_FLAG (abr_entry->path.router_bits, OSPF6_ROUTER_LSA_BIT_B))    {      if (IS_OSPF6_DUMP_ABR)        zlog_info ("ABR: ABR entry's B bit off");      return NULL;    }  return abr_entry;}static intospf6_abr_prefix_lsa_to_route (struct ospf6_lsa *lsa,                               struct ospf6_route_req *request){  struct ospf6_inter_area_prefix_lsa *iep;  struct ospf6_route_req abr_entry;  if (lsa->header->type != htons (OSPF6_LSA_TYPE_INTER_PREFIX))    {      if (IS_OSPF6_DUMP_ABR)        zlog_info ("ABR: LSA type mismatch");      return -1;    }  if (IS_LSA_MAXAGE (lsa))    {      if (IS_OSPF6_DUMP_ABR)        zlog_info ("ABR: LSA MaxAge");      return -1;    }  if (! ospf6_abr_entry_lookup (&abr_entry, lsa->header->adv_router,                                (struct ospf6_area *) lsa->scope))    {      if (IS_OSPF6_DUMP_ABR)        zlog_info ("ABR: ABR check failed");      return -1;    }  iep = OSPF6_LSA_HEADER_END (lsa->header);  memset (request, 0, sizeof (struct ospf6_route_req));  request->route.type = OSPF6_DEST_TYPE_NETWORK;  request->route.prefix.family = AF_INET6;  request->route.prefix.prefixlen = iep->prefix.prefix_length;  ospf6_prefix_in6_addr (&iep->prefix, &request->route.prefix.u.prefix6);  request->path.cost = abr_entry.path.cost +                      (ntohl (iep->metric) & ntohl (0x000fffff));  request->path.type = OSPF6_PATH_TYPE_INTER;  request->path.origin.type = lsa->header->type;  request->path.origin.id = lsa->header->id;  request->path.origin.adv_router = lsa->header->adv_router;  memcpy (&request->nexthop.address, &abr_entry.nexthop.address,          sizeof (request->nexthop.address));  request->nexthop.ifindex = abr_entry.nexthop.ifindex;  return 0;}voidospf6_abr_prefix_lsa_add (struct ospf6_lsa *lsa){  struct ospf6_route_req request;  int ret;  if (IS_OSPF6_DUMP_ABR)    zlog_info ("ABR: Calculate %s", lsa->str);  ret = ospf6_abr_prefix_lsa_to_route (lsa, &request);  if (ret < 0)    return;  if (IS_OSPF6_DUMP_ABR)    zlog_info ("ABR: Inter Area Route add for %s", lsa->str);  ospf6_route_add (&request, ospf6->route_table);}voidospf6_abr_prefix_lsa_remove (struct ospf6_lsa *lsa){  struct ospf6_inter_area_prefix_lsa *iep;  struct prefix_ipv6 prefix6;  struct ospf6_route_req request;  iep = OSPF6_LSA_HEADER_END (lsa->header);  prefix6.family = AF_INET6;  prefix6.prefixlen = iep->prefix.prefix_length;  ospf6_prefix_in6_addr (&iep->prefix, &prefix6.prefix);  if (IS_OSPF6_DUMP_ABR)    zlog_info ("ABR: Inter Area Route remove for %s", lsa->str);  for (ospf6_route_lookup (&request, (struct prefix *) &prefix6,                           ospf6->route_table);       ! ospf6_route_end (&request);       ospf6_route_next (&request))   {     if (memcmp (&prefix6, &request.route.prefix, sizeof (prefix6)))       break;     if (request.path.origin.type != htons (OSPF6_LSA_TYPE_INTER_PREFIX) ||         request.path.origin.adv_router != lsa->header->adv_router ||         request.path.origin.id != lsa->header->id)       continue;     ospf6_route_remove (&request, ospf6->route_table);   }}static intospf6_abr_router_lsa_to_route (struct ospf6_lsa *lsa,                               struct ospf6_route_req *request){  struct ospf6_inter_area_router_lsa *ier;  struct ospf6_route_req abr_entry;  if (lsa->header->type != htons (OSPF6_LSA_TYPE_INTER_ROUTER))    {      if (IS_OSPF6_DUMP_ABR)        zlog_info ("ABR: LSA type mismatch");      return -1;    }  if (IS_LSA_MAXAGE (lsa))    {      if (IS_OSPF6_DUMP_ABR)        zlog_info ("ABR: LSA MaxAge");      return -1;    }  if (! ospf6_abr_entry_lookup (&abr_entry, lsa->header->adv_router,                                (struct ospf6_area *) lsa->scope))    {      if (IS_OSPF6_DUMP_ABR)        zlog_info ("ABR: Advertising router check failed");      return -1;    }  ier = OSPF6_LSA_HEADER_END (lsa->header);  memset (request, 0, sizeof (struct ospf6_route_req));  request->route.type = OSPF6_DEST_TYPE_ROUTER;  request->route.prefix.family = AF_UNSPEC;  request->route.prefix.prefixlen = 64; /* XXX */  ((struct prefix_ls *) &request->route.prefix)->adv_router.s_addr    = ier->router_id;  request->path.cost = abr_entry.path.cost +                      (ntohl (ier->metric & htonl (0x000fffff)));  request->path.type = OSPF6_PATH_TYPE_INTER;  request->path.origin.type = lsa->header->type;  request->path.origin.id = lsa->header->id;  request->path.origin.adv_router = lsa->header->adv_router;  SET_FLAG (request->path.router_bits, OSPF6_ROUTER_LSA_BIT_E);  request->path.capability[0] = ier->options[0];  request->path.capability[1] = ier->options[1];  request->path.capability[2] = ier->options[2];  memcpy (&request->nexthop.address, &abr_entry.nexthop.address,          sizeof (request->nexthop.address));  request->nexthop.ifindex = abr_entry.nexthop.ifindex;  return 0;}voidospf6_abr_router_lsa_add (struct ospf6_lsa *lsa){  struct ospf6_route_req request;  int ret;  if (IS_OSPF6_DUMP_ABR)    zlog_info ("ABR: Calculate %s", lsa->str);  ret = ospf6_abr_router_lsa_to_route (lsa, &request);  if (ret < 0)    return;  if (IS_OSPF6_DUMP_ABR)    zlog_info ("ABR: Inter Area Router add for %s", lsa->str);  ospf6_route_add (&request, ospf6->topology_table);}voidospf6_abr_router_lsa_remove (struct ospf6_lsa *lsa){  struct ospf6_inter_area_router_lsa *ier;  struct prefix_ls prefix_ls;  struct ospf6_route_req request;  ier = OSPF6_LSA_HEADER_END (lsa->header);  memset (&prefix_ls, 0, sizeof (prefix_ls));  prefix_ls.family = AF_INET6;  prefix_ls.prefixlen = 64; /* XXX */  prefix_ls.adv_router.s_addr = ier->router_id;  if (IS_OSPF6_DUMP_ABR)    zlog_info ("ABR: Inter Area Route remove for %s", lsa->str);  for (ospf6_route_lookup (&request, (struct prefix *) &prefix_ls,                           ospf6->route_table);       ! ospf6_route_end (&request);       ospf6_route_next (&request))   {     if (memcmp (&prefix_ls, &request.route.prefix, sizeof (prefix_ls)))       break;     if (request.path.origin.type != htons (OSPF6_LSA_TYPE_INTER_ROUTER) ||         request.path.origin.adv_router != lsa->header->adv_router ||         request.path.origin.id != lsa->header->id)       continue;     ospf6_route_remove (&request, ospf6->route_table);   }}voidospf6_abr_abr_entry_add (struct ospf6_route_req *abr_entry){  struct ospf6_lsdb_node node;  struct prefix_ls *abr_id;  struct ospf6_route_req request;  struct ospf6_area *area;  if (IS_OSPF6_DUMP_ABR)    zlog_info ("ABR: New Area Border Router found");  area = ospf6_area_lookup (abr_entry->path.area_id, ospf6);  if (! area)    {      if (IS_OSPF6_DUMP_ABR)        zlog_info ("ABR: Can't find associated area");      return;    }  abr_id = (struct prefix_ls *) &abr_entry->route.prefix;  if (! ospf6_abr_entry_lookup (&request, abr_id->adv_router.s_addr, area))    {      if (IS_OSPF6_DUMP_ABR)        zlog_info ("ABR: back check failed");      return;    }  /* for each inter-prefix LSA this ABR originated */  for (ospf6_lsdb_type_router (&node, htons (OSPF6_LSA_TYPE_INTER_PREFIX),                               abr_id->adv_router.s_addr, area->lsdb);       ! ospf6_lsdb_is_end (&node);       ospf6_lsdb_next (&node))    ospf6_abr_prefix_lsa_add (node.lsa);  /* for each inter-router LSA this ABR originated */  for (ospf6_lsdb_type_router (&node, htons (OSPF6_LSA_TYPE_INTER_ROUTER),                               abr_id->adv_router.s_addr, area->lsdb);       ! ospf6_lsdb_is_end (&node);

⌨️ 快捷键说明

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