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

📄 bgpd.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 5 页
字号:
    {      peer->last_reset = PEER_DOWN_RMAP_UNBIND;      bgp_notify_send (peer, BGP_NOTIFY_CEASE,		       BGP_NOTIFY_CEASE_CONFIG_CHANGE);    }  else    BGP_EVENT_ADD (peer, BGP_Stop);  return 0;}/* BGP instance creation by `router bgp' commands. */struct bgp *bgp_create (as_t *as, char *name){  struct bgp *bgp;  afi_t afi;  safi_t safi;  bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp));  bgp->peer_self = peer_new ();  bgp->peer_self->host = "Static announcement";  bgp->peer = list_new ();  bgp->peer->cmp = (int (*)(void *, void *)) peer_cmp;  bgp->group = list_new ();  bgp->group->cmp = (int (*)(void *, void *)) peer_group_cmp;  for (afi = AFI_IP; afi < AFI_MAX; afi++)    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)      {	bgp->route[afi][safi] = bgp_table_init ();	bgp->aggregate[afi][safi] = bgp_table_init ();	bgp->rib[afi][safi] = bgp_table_init ();      }  bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;  bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;  bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;  bgp->as = *as;  if (name)    bgp->name = strdup (name);  return bgp;}/* Return master of BGP. */struct bgp_master *bgp_get_master (){  if (bm)    return bm;  return NULL;}/* Return first entry of BGP. */struct bgp *bgp_get_default (){  if (bm->bgp->head)    return bm->bgp->head->data;  return NULL;}/* Lookup BGP entry. */struct bgp *bgp_lookup (as_t as, char *name){  struct bgp *bgp;  struct listnode *nn;  LIST_LOOP (bm->bgp, bgp, nn)    if (bgp->as == as	&& ((bgp->name == NULL && name == NULL) 	    || (bgp->name && name && strcmp (bgp->name, name) == 0)))      return bgp;  return NULL;}/* Lookup BGP structure by view name. */struct bgp *bgp_lookup_by_name (char *name){  struct bgp *bgp;  struct listnode *nn;  LIST_LOOP (bm->bgp, bgp, nn)    if ((bgp->name == NULL && name == NULL)	|| (bgp->name && name && strcmp (bgp->name, name) == 0))      return bgp;  return NULL;}/* Called from VTY commands. */intbgp_get (struct bgp **bgp_val, as_t *as, char *name){  struct bgp *bgp;  /* Multiple instance check. */  if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))    {      if (name)	bgp = bgp_lookup_by_name (name);      else	bgp = bgp_get_default ();      /* Already exists. */      if (bgp)	{          if (bgp->as != *as)	    {	      *as = bgp->as;	      return BGP_ERR_INSTANCE_MISMATCH;	    }	  *bgp_val = bgp;	  return 0;	}    }  else    {      /* BGP instance name can not be specified for single instance.  */      if (name)	return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET;      /* Get default BGP structure if exists. */      bgp = bgp_get_default ();      if (bgp)	{	  if (bgp->as != *as)	    {	      *as = bgp->as;	      return BGP_ERR_AS_MISMATCH;	    }	  *bgp_val = bgp;	  return 0;	}    }  bgp = bgp_create (as, name);  listnode_add (bm->bgp, bgp);  bgp_if_update_all ();  *bgp_val = bgp;  return 0;}/* Delete BGP instance. */intbgp_delete (struct bgp *bgp){  struct peer *peer;  struct listnode *nn;  struct listnode *next;  afi_t afi;  safi_t safi;  int i;  /* Delete static route. */  bgp_static_delete (bgp);  /* Unset redistribution. */  for (afi = AFI_IP; afi < AFI_MAX; afi++)    for (i = 0; i < ZEBRA_ROUTE_MAX; i++)       if (i != ZEBRA_ROUTE_BGP)	bgp_redistribute_unset (bgp, afi, i);  bgp->group->del = (void (*)(void *)) peer_group_delete;  list_delete (bgp->group);  for (nn = bgp->peer->head; nn; nn = next)    {      peer = nn->data;      next = nn->next;      peer_delete (peer);    }  listnode_delete (bm->bgp, bgp);  if (bgp->name)    free (bgp->name);    for (afi = AFI_IP; afi < AFI_MAX; afi++)    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)      {	if (bgp->route[afi][safi])	  XFREE (MTYPE_ROUTE_TABLE, bgp->route[afi][safi]);	if (bgp->aggregate[afi][safi])	  XFREE (MTYPE_ROUTE_TABLE,bgp->aggregate[afi][safi]) ;	if (bgp->rib[afi][safi])	  XFREE (MTYPE_ROUTE_TABLE,bgp->rib[afi][safi]);      }  XFREE (MTYPE_BGP, bgp);  return 0;}struct peer *peer_lookup (struct bgp *bgp, union sockunion *su){  struct peer *peer;  struct listnode *nn;  if (! bgp)    bgp = bgp_get_default ();  if (! bgp)    return NULL;    LIST_LOOP (bgp->peer, peer, nn)    {      if (sockunion_same (&peer->su, su)	  && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))	return peer;    }  return NULL;}struct peer *peer_lookup_with_open (union sockunion *su, as_t remote_as,		       struct in_addr *remote_id, int *as){  struct peer *peer;  struct listnode *nn;  struct bgp *bgp;  bgp = bgp_get_default ();  if (! bgp)    return NULL;  LIST_LOOP (bgp->peer, peer, nn)    {      if (sockunion_same (&peer->su, su)	  && ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))	{	  if (peer->as == remote_as	      && peer->remote_id.s_addr == remote_id->s_addr)	    return peer;	  if (peer->as == remote_as)	    *as = 1;	}    }  LIST_LOOP (bgp->peer, peer, nn)    {      if (sockunion_same (&peer->su, su)	  &&  ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))	{	  if (peer->as == remote_as	      && peer->remote_id.s_addr == 0)	    return peer;	  if (peer->as == remote_as)	    *as = 1;	}    }  return NULL;}/* If peer is configured at least one address family return 1. */intpeer_active (struct peer *peer){  if (peer->afc[AFI_IP][SAFI_UNICAST]      || peer->afc[AFI_IP][SAFI_MULTICAST]      || peer->afc[AFI_IP][SAFI_MPLS_VPN]      || peer->afc[AFI_IP6][SAFI_UNICAST]      || peer->afc[AFI_IP6][SAFI_MULTICAST])    return 1;  return 0;}/* If peer is negotiated at least one address family return 1. */intpeer_active_nego (struct peer *peer){  if (peer->afc_nego[AFI_IP][SAFI_UNICAST]      || peer->afc_nego[AFI_IP][SAFI_MULTICAST]      || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]      || peer->afc_nego[AFI_IP6][SAFI_UNICAST]      || peer->afc_nego[AFI_IP6][SAFI_MULTICAST])    return 1;  return 0;}/* peer_flag_change_type. */enum peer_change_type{  peer_change_none,  peer_change_reset,  peer_change_reset_in,  peer_change_reset_out,};voidpeer_change_action (struct peer *peer, afi_t afi, safi_t safi,		    enum peer_change_type type){  if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    return;  if (type == peer_change_reset)    bgp_notify_send (peer, BGP_NOTIFY_CEASE,		     BGP_NOTIFY_CEASE_CONFIG_CHANGE);  else if (type == peer_change_reset_in)    {      if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)	  || CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))	bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);      else	bgp_notify_send (peer, BGP_NOTIFY_CEASE,			 BGP_NOTIFY_CEASE_CONFIG_CHANGE);    }  else if (type == peer_change_reset_out)    bgp_announce_route (peer, afi, safi);}struct peer_flag_action{  /* Peer's flag.  */  u_int32_t flag;  /* This flag can be set for peer-group member.  */  u_char not_for_member;  /* Action when the flag is changed.  */  enum peer_change_type type;  /* Peer down cause */  u_char peer_down;};struct peer_flag_action peer_flag_action_list[] =   {    { PEER_FLAG_PASSIVE,                  0, peer_change_reset },    { PEER_FLAG_SHUTDOWN,                 0, peer_change_reset },    { PEER_FLAG_DONT_CAPABILITY,          0, peer_change_none },    { PEER_FLAG_OVERRIDE_CAPABILITY,      0, peer_change_none },    { PEER_FLAG_STRICT_CAP_MATCH,         0, peer_change_none },    { PEER_FLAG_NO_ROUTE_REFRESH_CAP,     0, peer_change_reset },    { PEER_FLAG_DYNAMIC_CAPABILITY,       0, peer_change_reset },    { PEER_FLAG_ENFORCE_MULTIHOP,         0, peer_change_reset },    { 0, 0, 0 }  };struct peer_flag_action peer_af_flag_action_list[] =   {    { PEER_FLAG_NEXTHOP_SELF,             1, peer_change_reset_out },    { PEER_FLAG_SEND_COMMUNITY,           1, peer_change_reset_out },    { PEER_FLAG_SEND_EXT_COMMUNITY,       1, peer_change_reset_out },    { PEER_FLAG_SOFT_RECONFIG,            0, peer_change_reset_in },    { PEER_FLAG_REFLECTOR_CLIENT,         1, peer_change_reset },    { PEER_FLAG_RSERVER_CLIENT,           1, peer_change_reset },    { PEER_FLAG_AS_PATH_UNCHANGED,        1, peer_change_reset_out },    { PEER_FLAG_NEXTHOP_UNCHANGED,        1, peer_change_reset_out },    { PEER_FLAG_MED_UNCHANGED,            1, peer_change_reset_out },    { PEER_FLAG_REMOVE_PRIVATE_AS,        1, peer_change_reset_out },    { PEER_FLAG_ALLOWAS_IN,               0, peer_change_reset_in },    { PEER_FLAG_ORF_PREFIX_SM,            1, peer_change_reset },    { PEER_FLAG_ORF_PREFIX_RM,            1, peer_change_reset },    { 0, 0, 0 }  };/* Proper action set. */intpeer_flag_action_set (struct peer_flag_action *action_list, int size,		      struct peer_flag_action *action, u_int32_t flag){  int i;  int found = 0;  int reset_in = 0;  int reset_out = 0;  struct peer_flag_action *match = NULL;  /* Check peer's frag action.  */  for (i = 0; i < size; i++)    {      match = &action_list[i];      if (match->flag == 0)	break;      if (match->flag & flag)	{	  found = 1;	  if (match->type == peer_change_reset_in)	    reset_in = 1;	  if (match->type == peer_change_reset_out)	    reset_out = 1;	  if (match->type == peer_change_reset)	    {	      reset_in = 1;	      reset_out = 1;	    }	  if (match->not_for_member)	    action->not_for_member = 1;	}    }  /* Set peer clear type.  */  if (reset_in && reset_out)    action->type = peer_change_reset;  else if (reset_in)    action->type = peer_change_reset_in;  else if (reset_out)    action->type = peer_change_reset_out;  else    action->type = peer_change_none;  return found;}voidpeer_flag_modify_action (struct peer *peer, u_int32_t flag){  if (flag == PEER_FLAG_SHUTDOWN)    {      if (CHECK_FLAG (peer->flags, flag))	{	  if (peer->status == Established)	    bgp_notify_send (peer, BGP_NOTIFY_CEASE,			     BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);	  else	    BGP_EVENT_ADD (peer, BGP_Stop);	}      else	{	  peer->v_start = BGP_INIT_START_TIMER;	  BGP_EVENT_ADD (peer, BGP_Stop);	}    }  else if (peer->status == Established)    {      if (flag == PEER_FLAG_NO_ROUTE_REFRESH_CAP	  && CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV))	{	  if (CHECK_FLAG (peer->flags, flag))	    UNSET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);	  else	    SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);	  bgp_capability_send (peer, AFI_IP, SAFI_UNICAST,			       CAPABILITY_CODE_REFRESH,			       CHECK_FLAG (peer->flags, flag) ?			       CAPABILITY_ACTION_UNSET : CAPABILITY_ACTION_SET);	}      else	{	  if (flag == PEER_FLAG_NO_ROUTE_REFRESH_CAP)	    peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;	  else if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)	    peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;	  else if (flag == PEER_FLAG_PASSIVE)	    peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;	  else if (flag == PEER_FLAG_ENFORCE_MULTIHOP)	    peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;	  bgp_notify_send (peer, BGP_NOTIFY_CEASE,			   BGP_NOTIFY_CEASE_CONFIG_CHANGE);	}    }  else    BGP_EVENT_ADD (peer, BGP_Stop);}/* Change specified peer flag. */intpeer_flag_modify (struct peer *peer, u_int32_t flag, int set){  int found;  int size;  struct peer_group *group;  struct listnode *nn;  struct peer_flag_action action;  memset (&action, 0, sizeof (struct peer_flag_action));  size = sizeof peer_flag_action_list / sizeof (struct peer_flag_action);  found = peer_flag_action_set (peer_flag_action_list, size, &action, flag);  /* No flag action is found.  */  if (! found)    return BGP_ERR_INVALID_FLAG;      /* Not for peer-group member.  */  if (action.not_for_member && peer_group_active (peer))    return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;  /* When unset the peer-group member's flag we have to check     peer-group configuration.  */  if (! set && peer_group_active (peer))    if (CHECK_FLAG (peer->group->conf->flags, flag))      {	if (flag == PEER_FLAG_SHUTDOWN)	  return BGP_ERR_PEER_GROUP_SHUTDOWN;	else	  return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;      }  /* Flag conflict check.  */  if (set      && CHECK_FLAG (peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH)      && CHECK_FLAG (peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY))    return BGP_ERR_PEER_FLAG_CONFLICT;  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    {      if (set && CHECK_FLAG (peer->flags, flag) == flag)	return 0;      if (! set && ! CHECK_FLAG (peer->flags, flag))	return 0;    }  if (set)    SET_FLAG (peer->flags, flag);  else    UNSET_FLAG (peer->flags, flag);   if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))    {      if (action.type == peer_change_reset)	peer_flag_modify_action (peer, flag);      return 0;    }  /* peer-group member updates. */  group = peer->group;  LIST_LOOP (group->peer, peer, nn)    {      if (set && CHECK_FLAG (peer->flags, flag) == flag)	continue;      if (! set && ! CHECK_FLAG (peer->flags, flag))	continue;      if (set)	SET_FLAG (peer->flags, flag);      else	UNSET_FLAG (peer->flags, flag);      if (action.type == peer_change_reset)	peer_flag_modify_action (peer, flag);

⌨️ 快捷键说明

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