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

📄 ospf6_lsdb.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 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 "memory.h"#include "log.h"#include "command.h"#include "if.h"#include "ospf6_dump.h"#include "ospf6_lsdb.h"#include "ospf6_interface.h"#include "ospf6_area.h"#include "ospf6_top.h"#define OSPF6_LSDB_MATCH_TYPE        0x01#define OSPF6_LSDB_MATCH_ID          0x02#define OSPF6_LSDB_MATCH_ADV_ROUTER  0x04#define OSPF6_LSDB_SHOW_DUMP         0x08#define OSPF6_LSDB_SHOW_DETAIL       0x10struct ospf6_lsdb_hook_t hooks[0x2000];struct ospf6_lsdb_hook_t *ospf6_lsdb_hook = hooks;struct ospf6_lsdb *ospf6_lsdb_create (){  struct ospf6_lsdb *lsdb;  lsdb = XCALLOC (MTYPE_OSPF6_LSDB, sizeof (struct ospf6_lsdb));  if (lsdb == NULL)    {      zlog_warn ("Can't malloc lsdb");      return NULL;    }  memset (lsdb, 0, sizeof (struct ospf6_lsdb));  lsdb->table = route_table_init ();  return lsdb;}voidospf6_lsdb_delete (struct ospf6_lsdb *lsdb){  ospf6_lsdb_remove_all (lsdb);  route_table_finish (lsdb->table);  XFREE (MTYPE_OSPF6_LSDB, lsdb);}static voidospf6_lsdb_set_key (struct prefix_ipv6 *key, int flag,                    u_int16_t type, u_int32_t id, u_int32_t adv_router){  int len = 0;  memset (key, 0, sizeof (struct prefix_ipv6));  if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_TYPE))    {      len += 2;      if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_ADV_ROUTER))        {          len += 4;          if (CHECK_FLAG (flag, OSPF6_LSDB_MATCH_ID))            len += 4;        }    }  if (len > 0)    memcpy ((char *)&key->prefix, &type, 2);  if (len > 2)    memcpy ((char *)&key->prefix + 2, &adv_router, 4);  if (len > 6)    memcpy ((char *)&key->prefix + 6, &id, 4);  key->family = AF_INET6;  key->prefixlen = len * 8;}voidospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb){  int flag;  struct prefix_ipv6 key;  struct route_node *rn;  struct ospf6_lsa *old = NULL;  flag = OSPF6_LSDB_MATCH_TYPE | OSPF6_LSDB_MATCH_ID |         OSPF6_LSDB_MATCH_ADV_ROUTER;  ospf6_lsdb_set_key (&key, flag, lsa->header->type, lsa->header->id,                      lsa->header->adv_router);  rn = route_node_get (lsdb->table, (struct prefix *) &key);  if (rn->info)    old = rn->info;  rn->info = lsa;  ospf6_lsa_lock (lsa);  if (old)    ospf6_lsa_unlock (old);  else    lsdb->count++;}voidospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb){  int flag;  struct prefix_ipv6 key;  struct route_node *rn;  struct ospf6_lsa *old;  flag = OSPF6_LSDB_MATCH_TYPE | OSPF6_LSDB_MATCH_ID |         OSPF6_LSDB_MATCH_ADV_ROUTER;  ospf6_lsdb_set_key (&key, flag, lsa->header->type, lsa->header->id,                      lsa->header->adv_router);  rn = route_node_lookup (lsdb->table, (struct prefix *) &key);  if (! rn || ! rn->info)    {      zlog_warn ("LSDB: Can't remove: no such LSA: %s", lsa->str);      return;    }  old = rn->info;  if (old != lsa)    {      zlog_warn ("LSDB: Can't remove: different instance: %s (%p <-> %p) %s",                 lsa->str, lsa, old, old->str);      return;    }  rn->info = NULL;  ospf6_lsa_unlock (old);  lsdb->count--;}static voidospf6_lsdb_lookup_node (struct ospf6_lsdb_node *node,                        u_int16_t type, u_int32_t id, u_int32_t adv_router,                        struct ospf6_lsdb *lsdb){  int flag;  struct route_node *rn;  memset (node, 0, sizeof (struct ospf6_lsdb_node));  flag = OSPF6_LSDB_MATCH_TYPE | OSPF6_LSDB_MATCH_ID |         OSPF6_LSDB_MATCH_ADV_ROUTER;  ospf6_lsdb_set_key (&node->key, flag, type, id, adv_router);  rn = route_node_lookup (lsdb->table, (struct prefix *) &node->key);  if (! rn || ! rn->info)    return;  node->node = rn;  node->next = route_next (rn);  node->lsa = rn->info;  if (node->next != NULL)    route_unlock_node (node->next);}struct ospf6_lsa *ospf6_lsdb_lookup_lsdb (u_int16_t type, u_int32_t id, u_int32_t adv_router,                        struct ospf6_lsdb *lsdb){  struct ospf6_lsdb_node node;  ospf6_lsdb_lookup_node (&node, type, id, adv_router, lsdb);  return node.lsa;}/* Iteration function */voidospf6_lsdb_head (struct ospf6_lsdb_node *node, struct ospf6_lsdb *lsdb){  struct route_node *rn;  memset (node, 0, sizeof (struct ospf6_lsdb_node));  rn = route_top (lsdb->table);  if (rn == NULL)    return;  while (rn && rn->info == NULL)    rn = route_next (rn);  if (rn && rn->info)    {      node->node = rn;      node->next = route_next (rn);      node->lsa = rn->info;      if (node->next != NULL)        route_unlock_node (node->next);    }}voidospf6_lsdb_type (struct ospf6_lsdb_node *node, u_int16_t type,                 struct ospf6_lsdb *lsdb){  int flag;  struct route_node *rn;  memset (node, 0, sizeof (struct ospf6_lsdb_node));  flag = OSPF6_LSDB_MATCH_TYPE;  ospf6_lsdb_set_key (&node->key, flag, type, 0, 0);  /* get the closest radix node */  rn = route_node_get (lsdb->table, (struct prefix *) &node->key);  /* skip to the real existing lsdb entry */  while (rn && rn->info == NULL && rn->p.prefixlen >= node->key.prefixlen &&         prefix_match ((struct prefix *) &node->key, &rn->p))    rn = route_next (rn);  if (rn && rn->info)    {      node->node = rn;      node->next = route_next (rn);      node->lsa = rn->info;      if (node->next != NULL)        route_unlock_node (node->next);    }}voidospf6_lsdb_type_router (struct ospf6_lsdb_node *node,                        u_int16_t type, u_int32_t adv_router,                        struct ospf6_lsdb *lsdb){  int flag;  struct route_node *rn;  memset (node, 0, sizeof (struct ospf6_lsdb_node));  flag = OSPF6_LSDB_MATCH_TYPE | OSPF6_LSDB_MATCH_ADV_ROUTER;  ospf6_lsdb_set_key (&node->key, flag, type, 0, adv_router);  /* get the closest radix node */  rn = route_node_get (lsdb->table, (struct prefix *) &node->key);  /* skip to the real existing lsdb entry */  while (rn && rn->info == NULL && rn->p.prefixlen >= node->key.prefixlen &&         prefix_match ((struct prefix *) &node->key, &rn->p))    rn = route_next (rn);  if (rn && rn->info)    {      node->node = rn;      node->next = route_next (rn);      node->lsa = rn->info;      if (node->next != NULL)        route_unlock_node (node->next);    }}voidospf6_lsdb_next (struct ospf6_lsdb_node *node){  struct route_node *rn;  route_lock_node (node->node);  rn = route_next (node->node);  /* skip to the real existing lsdb entry */  while (rn && rn->info == NULL && rn->p.prefixlen >= node->key.prefixlen &&         prefix_match ((struct prefix *) &node->key, &rn->p))    rn = route_next (rn);  if (rn && rn->info && rn->p.prefixlen >= node->key.prefixlen &&      prefix_match ((struct prefix *) &node->key, &rn->p))    {      node->node = rn;      node->next = route_next (rn);      node->lsa = rn->info;      if (node->next != NULL)        route_unlock_node (node->next);    }  else    {      node->node = NULL;      node->next = NULL;      node->lsa = NULL;    }}struct ospf6_lsa *ospf6_lsdb_lookup (u_int16_t type, u_int32_t id, u_int32_t adv_router,                   void *scope){  struct ospf6_interface *o6i;  struct ospf6_area *o6a;  listnode i, j;  if (scope == (void *) ospf6)    return ospf6_lsdb_lookup_lsdb (type, id, adv_router, ospf6->lsdb);  for (i = listhead (ospf6->area_list); i; nextnode (i))    {      o6a = getdata (i);      if (scope == (void *) o6a)        return ospf6_lsdb_lookup_lsdb (type, id, adv_router, o6a->lsdb);      for (j = listhead (o6a->if_list); j; nextnode (j))        {          o6i = getdata (j);          if (scope == (void *) o6i)            return ospf6_lsdb_lookup_lsdb (type, id, adv_router, o6i->lsdb);        }    }  zlog_warn ("LSDB: Can't lookup: unknown scope, type %#hx", ntohs (type));  return NULL;}voidospf6_lsdb_install (struct ospf6_lsa *new){  struct ospf6_lsdb *lsdb;  struct ospf6_lsa *old;  int need_hook = 0;  void (*hook) (struct ospf6_lsa *, struct ospf6_lsa *);  struct ospf6 *as = NULL;  struct ospf6_area *area = NULL;  struct ospf6_interface *linklocal = NULL;  hook = NULL;  switch (ntohs (new->header->type) & OSPF6_LSTYPE_SCOPE_MASK)    {      case OSPF6_LSA_SCOPE_LINKLOCAL:        linklocal = (struct ospf6_interface *) new->scope;        lsdb = linklocal->lsdb;        break;      case OSPF6_LSA_SCOPE_AREA:        area = (struct ospf6_area *) new->scope;        lsdb = area->lsdb;        break;      case OSPF6_LSA_SCOPE_AS:        as = (struct ospf6 *) new->scope;

⌨️ 快捷键说明

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