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

📄 bgp_damp.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
/* BGP flap dampening   Copyright (C) 2001 IP Infusion Inc.This file is part of GNU Zebra.GNU Zebra is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 2, or (at your option) anylater version.GNU Zebra is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Zebra; see the file COPYING.  If not, write to the FreeSoftware Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA02111-1307, USA.  */#include <zebra.h>#include <math.h>#include "prefix.h"#include "memory.h"#include "command.h"#include "log.h"#include "thread.h"#include "bgpd/bgpd.h"#include "bgpd/bgp_damp.h"#include "bgpd/bgp_table.h"#include "bgpd/bgp_route.h"#include "bgpd/bgp_attr.h" #include "bgpd/bgp_advertise.h"/* Global variable to access damping configuration */struct bgp_damp_config bgp_damp_cfg;struct bgp_damp_config *damp = &bgp_damp_cfg;/* Utility macro to add and delete BGP dampening information to no   used list.  */#define BGP_DAMP_LIST_ADD(N,A)  BGP_INFO_ADD(N,A,no_reuse_list)#define BGP_DAMP_LIST_DEL(N,A)  BGP_INFO_DEL(N,A,no_reuse_list)/* Calculate reuse list index by penalty value.  */static intbgp_reuse_index (int penalty){  int i;  int index;  i = (int)(((double) penalty / damp->reuse_limit - 1.0) * damp->scale_factor);    if ( i >= damp->reuse_index_size )    i = damp->reuse_index_size - 1;  index = damp->reuse_index[i] - damp->reuse_index[0];  return (damp->reuse_offset + index) % damp->reuse_list_size;  }/* Add BGP dampening information to reuse list.  */static void bgp_reuse_list_add (struct bgp_damp_info *bdi){  int index;  index = bdi->index = bgp_reuse_index (bdi->penalty);  bdi->prev = NULL;  bdi->next = damp->reuse_list[index];  if (damp->reuse_list[index])    damp->reuse_list[index]->prev = bdi;  damp->reuse_list[index] = bdi;}/* Delete BGP dampening information from reuse list.  */static voidbgp_reuse_list_delete (struct bgp_damp_info *bdi){  if (bdi->next)    bdi->next->prev = bdi->prev;  if (bdi->prev)    bdi->prev->next = bdi->next;  else    damp->reuse_list[bdi->index] = bdi->next;}   /* Return decayed penalty value.  */int bgp_damp_decay (time_t tdiff, int penalty){  int i;  i = (int) ((double) tdiff / DELTA_T);  if (i == 0)    return penalty;     if (i >= damp->decay_array_size)    return 0;  return (int) (penalty * damp->decay_array[i]);}/* Handler of reuse timer event.  Each route in the current reuse-list   is evaluated.  RFC2439 Section 4.8.7.  */intbgp_reuse_timer (struct thread *t){  struct bgp_damp_info *bdi;  struct bgp_damp_info *next;  time_t t_now, t_diff;  struct bgp *bgp;  int bgp_process (struct bgp *, struct bgp_node *, afi_t, safi_t);  damp->t_reuse = NULL;  damp->t_reuse =    thread_add_timer (master, bgp_reuse_timer, NULL, DELTA_REUSE);  bgp = bgp_get_default ();  if (! bgp)    return 0;  t_now = time (NULL);  /* 1.  save a pointer to the current zeroth queue head and zero the     list head entry.  */  bdi = damp->reuse_list[damp->reuse_offset];  damp->reuse_list[damp->reuse_offset] = NULL;  /* 2.  set offset = modulo reuse-list-size ( offset + 1 ), thereby     rotating the circular queue of list-heads.  */  damp->reuse_offset = (damp->reuse_offset + 1) % damp->reuse_list_size;  /* 3. if ( the saved list head pointer is non-empty ) */  for (; bdi; bdi = next)    {      next = bdi->next;      /* Set t-diff = t-now - t-updated.  */      t_diff = t_now - bdi->t_updated;      /* Set figure-of-merit = figure-of-merit * decay-array-ok [t-diff] */      bdi->penalty = bgp_damp_decay (t_diff, bdi->penalty);         /* Set t-updated = t-now.  */      bdi->t_updated = t_now;      /* if (figure-of-merit < reuse).  */      if (bdi->penalty < damp->reuse_limit)	{	  /* Reuse the route.  */	  UNSET_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED);	  bdi->suppress_time = 0;	  if (bdi->lastrecord == BGP_RECORD_UPDATE)	    {	      UNSET_FLAG (bdi->binfo->flags, BGP_INFO_HISTORY);	      bgp_aggregate_increment (bgp, &bdi->rn->p, bdi->binfo,				       bdi->afi, bdi->safi);   	      bgp_process (bgp, bdi->rn, bdi->afi, bdi->safi);	    }	  if (bdi->penalty <= damp->reuse_limit / 2.0)	    bgp_damp_info_free (bdi, 1);	  else	    BGP_DAMP_LIST_ADD (damp, bdi);	}      else	/* Re-insert into another list (See RFC2439 Section 4.8.6).  */	bgp_reuse_list_add (bdi);    }  return 0;}/* A route becomes unreachable (RFC2439 Section 4.8.2).  */intbgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn,		   afi_t afi, safi_t safi, int attr_change){  time_t t_now;  struct bgp_damp_info *bdi;  double last_penalty = 0;    t_now = time (NULL);  /* Processing Unreachable Messages.  */  bdi = binfo->damp_info;  if (bdi == NULL)    {      /* If there is no previous stability history. */      /* RFC2439 said:	 1. allocate a damping structure.         2. set figure-of-merit = 1.         3. withdraw the route.  */      bdi =  XCALLOC (MTYPE_BGP_DAMP_INFO, sizeof (struct bgp_damp_info));      bdi->binfo = binfo;      bdi->rn = rn;      bdi->penalty = (attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY);      bdi->flap = 1;      bdi->start_time = t_now;      bdi->suppress_time = 0;      bdi->index = -1;      bdi->afi = afi;      bdi->safi = safi;      binfo->damp_info = bdi;      BGP_DAMP_LIST_ADD (damp, bdi);    }  else    {      last_penalty = bdi->penalty;      /* 1. Set t-diff = t-now - t-updated.  */      bdi->penalty = 	(bgp_damp_decay (t_now - bdi->t_updated, bdi->penalty) 	 + (attr_change ? DEFAULT_PENALTY / 2 : DEFAULT_PENALTY));      if (bdi->penalty > damp->ceiling)	bdi->penalty = damp->ceiling;      bdi->flap++;    }    bdi->lastrecord = BGP_RECORD_WITHDRAW;  bdi->t_updated = t_now;  /* Make this route as historical status.  */  SET_FLAG (binfo->flags, BGP_INFO_HISTORY);  /* Remove the route from a reuse list if it is on one.  */  if (CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED))    {      /* If decay rate isn't equal to 0, reinsert brn. */        if (bdi->penalty != last_penalty)	{	  bgp_reuse_list_delete (bdi);	  bgp_reuse_list_add (bdi);  	}      return BGP_DAMP_SUPPRESSED;     }  /* If not suppressed before, do annonunce this withdraw and     insert into reuse_list.  */  if (bdi->penalty >= damp->suppress_value)    {      SET_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED);      bdi->suppress_time = t_now;      BGP_DAMP_LIST_DEL (damp, bdi);      bgp_reuse_list_add (bdi);    }  return BGP_DAMP_USED;}intbgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn, 		 afi_t afi, safi_t safi){  time_t t_now;  struct bgp_damp_info *bdi;  int status;  bdi = binfo->damp_info;  if (! bdi)    return BGP_DAMP_USED;  t_now = time (NULL);  UNSET_FLAG (binfo->flags, BGP_INFO_HISTORY);   bdi->lastrecord = BGP_RECORD_UPDATE;  bdi->penalty = bgp_damp_decay (t_now - bdi->t_updated, bdi->penalty);  if (! CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED)      && (bdi->penalty < damp->suppress_value))    status = BGP_DAMP_USED;  else if (CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED)	   && (bdi->penalty < damp->reuse_limit) )    {      UNSET_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED);      bgp_reuse_list_delete (bdi);      BGP_DAMP_LIST_ADD (damp, bdi);      bdi->suppress_time = 0;      status = BGP_DAMP_USED;    }  else    status = BGP_DAMP_SUPPRESSED;    if (bdi->penalty > damp->reuse_limit / 2.0)    bdi->t_updated = t_now;  else    bgp_damp_info_free (bdi, 0);	  return status;}/* Remove dampening information and history route.  */int bgp_damp_scan (struct bgp_info *binfo, afi_t afi, safi_t safi){  time_t t_now, t_diff;  struct bgp_damp_info *bdi;  t_now = time (NULL);  bdi = binfo->damp_info;   if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))    {      t_diff = t_now - bdi->suppress_time;      if (t_diff >= damp->max_suppress_time)        {          UNSET_FLAG (binfo->flags, BGP_INFO_DAMPED);          bgp_reuse_list_delete (bdi);	  BGP_DAMP_LIST_ADD (damp, bdi);          bdi->penalty = damp->reuse_limit;          bdi->suppress_time = 0;          bdi->t_updated = t_now;                    /* Need to announce UPDATE once this binfo is usable again. */

⌨️ 快捷键说明

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