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

📄 bgp_attr.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 4 页
字号:
/* BGP attributes management routines.   Copyright (C) 1996, 97, 98, 1999 Kunihiro Ishiguro   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 "linklist.h"#include "prefix.h"#include "memory.h"#include "vector.h"#include "vty.h"#include "stream.h"#include "log.h"#include "hash.h"#include "bgpd/bgpd.h"#include "bgpd/bgp_attr.h"#include "bgpd/bgp_route.h"#include "bgpd/bgp_aspath.h"#include "bgpd/bgp_community.h"#include "bgpd/bgp_debug.h"#include "bgpd/bgp_packet.h"#include "bgpd/bgp_ecommunity.h"/* Attribute strings for logging. */struct message attr_str [] =   {    { BGP_ATTR_ORIGIN,           "ORIGIN" },     { BGP_ATTR_AS_PATH,          "AS_PATH" },     { BGP_ATTR_NEXT_HOP,         "NEXT_HOP" },     { BGP_ATTR_MULTI_EXIT_DISC,  "MULTI_EXIT_DISC" },     { BGP_ATTR_LOCAL_PREF,       "LOCAL_PREF" },     { BGP_ATTR_ATOMIC_AGGREGATE, "ATOMIC_AGGREGATE" },     { BGP_ATTR_AGGREGATOR,       "AGGREGATOR" },     { BGP_ATTR_COMMUNITIES,      "COMMUNITY" },     { BGP_ATTR_ORIGINATOR_ID,    "ORIGINATOR_ID" },    { BGP_ATTR_CLUSTER_LIST,     "CLUSTERLIST" },     { BGP_ATTR_DPA,              "DPA" },    { BGP_ATTR_ADVERTISER,       "ADVERTISER"} ,    { BGP_ATTR_RCID_PATH,        "RCID_PATH" },    { BGP_ATTR_MP_REACH_NLRI,    "MP_REACH_NLRI" },    { BGP_ATTR_MP_UNREACH_NLRI,  "MP_UNREACH_NLRI" },    { 0, NULL }  };struct hash *cluster_hash;void *cluster_hash_alloc (struct cluster_list *val){  struct cluster_list *cluster;  cluster = XMALLOC (MTYPE_CLUSTER, sizeof (struct cluster_list));  cluster->length = val->length;  if (cluster->length)    {      cluster->list = XMALLOC (MTYPE_CLUSTER_VAL, val->length);      memcpy (cluster->list, val->list, val->length);    }  else    cluster->list = NULL;  cluster->refcnt = 0;  return cluster;}/* Cluster list related functions. */struct cluster_list *cluster_parse (caddr_t pnt, int length){  struct cluster_list tmp;  struct cluster_list *cluster;  tmp.length = length;  tmp.list = (struct in_addr *) pnt;  cluster = hash_get (cluster_hash, &tmp, cluster_hash_alloc);  cluster->refcnt++;  return cluster;}intcluster_loop_check (struct cluster_list *cluster, struct in_addr originator){  int i;      for (i = 0; i < cluster->length / 4; i++)    if (cluster->list[i].s_addr == originator.s_addr)      return 1;  return 0;}unsigned intcluster_hash_key_make (struct cluster_list *cluster){  unsigned int key = 0;  int length;  caddr_t pnt;  length = cluster->length;  pnt = (caddr_t) cluster->list;    while (length)    key += pnt[--length];  return key;}intcluster_hash_cmp (struct cluster_list *cluster1, struct cluster_list *cluster2){  if (cluster1->length == cluster2->length &&      memcmp (cluster1->list, cluster2->list, cluster1->length) == 0)    return 1;  return 0;}voidcluster_free (struct cluster_list *cluster){  if (cluster->list)    XFREE (MTYPE_CLUSTER_VAL, cluster->list);  XFREE (MTYPE_CLUSTER, cluster);}struct cluster_list *cluster_dup (struct cluster_list *cluster){  struct cluster_list *new;  new = XMALLOC (MTYPE_CLUSTER, sizeof (struct cluster_list));  memset (new, 0, sizeof (struct cluster_list));  new->length = cluster->length;  if (cluster->length)    {      new->list = XMALLOC (MTYPE_CLUSTER_VAL, cluster->length);      memcpy (new->list, cluster->list, cluster->length);    }  else    new->list = NULL;    return new;}struct cluster_list *cluster_intern (struct cluster_list *cluster){  struct cluster_list *find;  find = hash_get (cluster_hash, cluster, cluster_hash_alloc);  find->refcnt++;  return find;}voidcluster_unintern (struct cluster_list *cluster){  struct cluster_list *ret;  if (cluster->refcnt)    cluster->refcnt--;  if (cluster->refcnt == 0)    {      ret = hash_release (cluster_hash, cluster);      cluster_free (cluster);    }}voidcluster_init (){  cluster_hash = hash_create (cluster_hash_key_make, cluster_hash_cmp);}/* Unknown transit attribute. */struct hash *transit_hash;voidtransit_free (struct transit *transit){  if (transit->val)    XFREE (MTYPE_TRANSIT_VAL, transit->val);  XFREE (MTYPE_TRANSIT, transit);}void *transit_hash_alloc (struct transit *transit){  /* Transit structure is already allocated.  */  return transit;}struct transit *transit_intern (struct transit *transit){  struct transit *find;  find = hash_get (transit_hash, transit, transit_hash_alloc);  if (find != transit)    transit_free (transit);  find->refcnt++;  return find;}voidtransit_unintern (struct transit *transit){  struct transit *ret;  if (transit->refcnt)    transit->refcnt--;  if (transit->refcnt == 0)    {      ret = hash_release (transit_hash, transit);      transit_free (transit);    }}unsigned inttransit_hash_key_make (struct transit *transit){  unsigned int key = 0;  int length;  caddr_t pnt;  length = transit->length;  pnt = (caddr_t) transit->val;    while (length)    key += pnt[--length];  return key;}inttransit_hash_cmp (struct transit *transit1, struct transit *transit2){  if (transit1->length == transit2->length &&      memcmp (transit1->val, transit2->val, transit1->length) == 0)    return 1;  return 0;}voidtransit_init (){  transit_hash = hash_create (transit_hash_key_make, transit_hash_cmp);}/* Attribute hash routines. */struct hash *attrhash;unsigned intattrhash_key_make (struct attr *attr){  unsigned int key = 0;  key += attr->origin;  key += attr->nexthop.s_addr;  key += attr->med;  key += attr->local_pref;  key += attr->aggregator_as;  key += attr->aggregator_addr.s_addr;  key += attr->weight;  key += attr->mp_nexthop_global_in.s_addr;  if (attr->aspath)    key += aspath_key_make (attr->aspath);  if (attr->community)    key += community_hash_make (attr->community);  if (attr->ecommunity)    key += ecommunity_hash_make (attr->ecommunity);  if (attr->cluster)    key += cluster_hash_key_make (attr->cluster);  if (attr->transit)    key += transit_hash_key_make (attr->transit);#ifdef HAVE_IPV6  {    int i;       key += attr->mp_nexthop_len;    for (i = 0; i < 16; i++)      key += attr->mp_nexthop_global.s6_addr[i];    for (i = 0; i < 16; i++)      key += attr->mp_nexthop_local.s6_addr[i];  }#endif /* HAVE_IPV6 */  return key;}intattrhash_cmp (struct attr *attr1, struct attr *attr2){  if (attr1->flag == attr2->flag      && attr1->origin == attr2->origin      && attr1->nexthop.s_addr == attr2->nexthop.s_addr      && attr1->med == attr2->med      && attr1->local_pref == attr2->local_pref      && attr1->aggregator_as == attr2->aggregator_as      && attr1->aggregator_addr.s_addr == attr2->aggregator_addr.s_addr      && attr1->weight == attr2->weight#ifdef HAVE_IPV6      && attr1->mp_nexthop_len == attr2->mp_nexthop_len      && IPV6_ADDR_SAME (&attr1->mp_nexthop_global, &attr2->mp_nexthop_global)      && IPV6_ADDR_SAME (&attr1->mp_nexthop_local, &attr2->mp_nexthop_local)#endif /* HAVE_IPV6 */      && IPV4_ADDR_SAME (&attr1->mp_nexthop_global_in, &attr2->mp_nexthop_global_in)      && attr1->aspath == attr2->aspath      && attr1->community == attr2->community      && attr1->ecommunity == attr2->ecommunity      && attr1->cluster == attr2->cluster      && attr1->transit == attr2->transit)    return 1;  else    return 0;}voidattrhash_init (){  attrhash = hash_create (attrhash_key_make, attrhash_cmp);}voidattr_show_all_iterator (struct hash_backet *backet, struct vty *vty){  struct attr *attr = backet->data;  vty_out (vty, "attr[%ld] nexthop %s%s", attr->refcnt, 	   inet_ntoa (attr->nexthop), VTY_NEWLINE);}voidattr_show_all (struct vty *vty){  hash_iterate (attrhash, 		(void (*)(struct hash_backet *, void *))		attr_show_all_iterator,		vty);}void *bgp_attr_hash_alloc (struct attr *val){  struct attr *attr;  attr = XMALLOC (MTYPE_ATTR, sizeof (struct attr));  *attr = *val;  attr->refcnt = 0;  return attr;}/* Internet argument attribute. */struct attr *bgp_attr_intern (struct attr *attr){  struct attr *find;  /* Intern referenced strucutre. */  if (attr->aspath)    {      if (! attr->aspath->refcnt)	attr->aspath = aspath_intern (attr->aspath);      else	attr->aspath->refcnt++;    }  if (attr->community)    {      if (! attr->community->refcnt)	attr->community = community_intern (attr->community);      else	attr->community->refcnt++;    }  if (attr->ecommunity)    {      if (! attr->ecommunity->refcnt)	attr->ecommunity = ecommunity_intern (attr->ecommunity);      else	attr->ecommunity->refcnt++;    }  if (attr->cluster)    {      if (! attr->cluster->refcnt)	attr->cluster = cluster_intern (attr->cluster);      else	attr->cluster->refcnt++;    }  if (attr->transit)    {      if (! attr->transit->refcnt)	attr->transit = transit_intern (attr->transit);      else	attr->transit->refcnt++;    }  find = (struct attr *) hash_get (attrhash, attr, bgp_attr_hash_alloc);  find->refcnt++;  return find;}/* Make network statement's attribute. */struct attr *bgp_attr_default_set (struct attr *attr, u_char origin){  memset (attr, 0, sizeof (struct attr));  attr->origin = origin;  attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN);  attr->aspath = aspath_empty ();  attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);  attr->weight = 32768;  attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);#ifdef HAVE_IPV6  attr->mp_nexthop_len = 16;#endif  return attr;}/* Make network statement's attribute. */struct attr *bgp_attr_default_intern (u_char origin){  struct attr attr;  struct attr *new;  memset (&attr, 0, sizeof (struct attr));  attr.origin = origin;  attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGIN);  attr.aspath = aspath_empty ();  attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);  attr.weight = 32768;  attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP);

⌨️ 快捷键说明

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