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

📄 bgp_route.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 5 页
字号:
      break;  /* AS path local-as loop check. */  if (peer->change_local_as)    {      if (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND))	aspath_loop_count = 1;      if (aspath_loop_check (attr->aspath, peer->change_local_as) > aspath_loop_count) 	{	  reason = "as-path contains our own AS;";	  goto filtered;	}    }  /* AS path loop check. */  if (aspath_loop_check (attr->aspath, bgp->as) > peer->allowas_in[afi][safi]      || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)	  && aspath_loop_check(attr->aspath, bgp->confed_id)	  > peer->allowas_in[afi][safi]))    {      reason = "as-path contains our own AS;";      goto filtered;    }  /* Route reflector originator ID check.  */  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID)      && IPV4_ADDR_SAME (&bgp->router_id, &attr->originator_id))    {      reason = "originator is us;";      goto filtered;    }  /* Route reflector cluster ID check.  */  if (bgp_cluster_filter (peer, attr))    {      reason = "reflected from the same cluster;";      goto  filtered;    }  /* Apply incoming filter.  */  if (bgp_input_filter (peer, p, attr, afi, safi) == FILTER_DENY)    {      reason = "filter;";      goto filtered;    }  /* Apply incoming route-map. */  new_attr = *attr;  if (bgp_input_modifier (peer, p, &new_attr, afi, safi) == RMAP_DENY)    {      reason = "route-map;";      goto filtered;    }  /* IPv4 unicast next hop check.  */  if (afi == AFI_IP && safi == SAFI_UNICAST)    {      /* If the peer is EBGP and nexthop is not on connected route,	 discard it.  */      if (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl == 1	  && ! bgp_nexthop_check_ebgp (afi, &new_attr)	  && ! CHECK_FLAG (peer->flags, PEER_FLAG_ENFORCE_MULTIHOP))	{	  reason = "non-connected next-hop;";	  goto filtered;	}      /* Next hop must not be 0.0.0.0 nor Class E address.  Next hop	 must not be my own address.  */      if (bgp_nexthop_self (afi, &new_attr)	  || new_attr.nexthop.s_addr == 0	  || ntohl (new_attr.nexthop.s_addr) >= 0xe0000000)	{	  reason = "martian next-hop;";	  goto filtered;	}    }  attr_new = bgp_attr_intern (&new_attr);  /* If the update is implicit withdraw. */  if (ri)    {      ri->uptime = time (NULL);      /* Same attribute comes in. */      if (attrhash_cmp (ri->attr, attr_new))	{	  UNSET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);	  if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)	      && peer_sort (peer) == BGP_PEER_EBGP	      && CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))	    {	      if (BGP_DEBUG (update, UPDATE_IN))  		  zlog (peer->log, LOG_INFO, "%s rcvd %s/%d",		  peer->host,		  inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),		  p->prefixlen);	      peer->pcount[afi][safi]++;	      ret = bgp_damp_update (ri, rn, afi, safi);	      if (ret != BGP_DAMP_SUPPRESSED)		{		  bgp_aggregate_increment (bgp, p, ri, afi, safi);		  bgp_process (bgp, rn, afi, safi);		}	    }	  else	    {	      if (BGP_DEBUG (update, UPDATE_IN))  		zlog (peer->log, LOG_INFO,		"%s rcvd %s/%d...duplicate ignored",		peer->host,		inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),		p->prefixlen);	    }	  bgp_unlock_node (rn);	  bgp_attr_unintern (attr_new);	  return 0;	}      /* Received Logging. */      if (BGP_DEBUG (update, UPDATE_IN))  	zlog (peer->log, LOG_INFO, "%s rcvd %s/%d",	      peer->host,	      inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),	      p->prefixlen);      /* The attribute is changed. */      SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);      /* Update bgp route dampening information.  */      if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)	  && peer_sort (peer) == BGP_PEER_EBGP)	{	  /* This is implicit withdraw so we should update dampening	     information.  */	  if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))	    bgp_damp_withdraw (ri, rn, afi, safi, 1);  	  else	    peer->pcount[afi][safi]++;	}	      bgp_aggregate_decrement (bgp, p, ri, afi, safi);      /* Update to new attribute.  */      bgp_attr_unintern (ri->attr);      ri->attr = attr_new;      /* Update MPLS tag.  */      if (safi == SAFI_MPLS_VPN)	memcpy (ri->tag, tag, 3);      /* Update bgp route dampening information.  */      if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)	  && peer_sort (peer) == BGP_PEER_EBGP)	{	  /* Now we do normal update dampening.  */	  ret = bgp_damp_update (ri, rn, afi, safi);	  if (ret == BGP_DAMP_SUPPRESSED)	    {	      bgp_unlock_node (rn);	      return 0;	    }	}      /* Nexthop reachability check. */      if ((afi == AFI_IP || afi == AFI_IP6)	  && safi == SAFI_UNICAST 	  && (peer_sort (peer) == BGP_PEER_IBGP	      || (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)	      || CHECK_FLAG (peer->flags, PEER_FLAG_ENFORCE_MULTIHOP)))	{	  if (bgp_nexthop_lookup (afi, peer, ri, NULL, NULL))	    SET_FLAG (ri->flags, BGP_INFO_VALID);	  else	    UNSET_FLAG (ri->flags, BGP_INFO_VALID);	}      else	SET_FLAG (ri->flags, BGP_INFO_VALID);      /* Process change. */      bgp_aggregate_increment (bgp, p, ri, afi, safi);      bgp_process (bgp, rn, afi, safi);      bgp_unlock_node (rn);      return 0;    }  /* Received Logging. */  if (BGP_DEBUG (update, UPDATE_IN))      {      zlog (peer->log, LOG_INFO, "%s rcvd %s/%d",	    peer->host,	    inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),	    p->prefixlen);    }  /* Increment prefix counter */  peer->pcount[afi][safi]++;  /* Make new BGP info. */  new = bgp_info_new ();  new->type = type;  new->sub_type = sub_type;  new->peer = peer;  new->attr = attr_new;  new->uptime = time (NULL);  /* Update MPLS tag. */  if (safi == SAFI_MPLS_VPN)    memcpy (new->tag, tag, 3);  /* Nexthop reachability check. */  if ((afi == AFI_IP || afi == AFI_IP6)      && safi == SAFI_UNICAST      && (peer_sort (peer) == BGP_PEER_IBGP	  || (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)	  || CHECK_FLAG (peer->flags, PEER_FLAG_ENFORCE_MULTIHOP)))    {      if (bgp_nexthop_lookup (afi, peer, new, NULL, NULL))	SET_FLAG (new->flags, BGP_INFO_VALID);      else	UNSET_FLAG (new->flags, BGP_INFO_VALID);    }  else    SET_FLAG (new->flags, BGP_INFO_VALID);  /* Aggregate address increment. */  bgp_aggregate_increment (bgp, p, new, afi, safi);    /* Register new BGP information. */  bgp_info_add (rn, new);  /* If maximum prefix count is configured and current prefix     count exeed it. */  if (bgp_maximum_prefix_overflow (peer, afi, safi, 0))    return -1;  /* Process change. */  bgp_process (bgp, rn, afi, safi);  return 0;  /* This BGP update is filtered.  Log the reason then update BGP     entry.  */ filtered:  if (BGP_DEBUG (update, UPDATE_IN))    zlog (peer->log, LOG_INFO,	  "%s rcvd UPDATE about %s/%d -- DENIED due to: %s",	  peer->host,	  inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),	  p->prefixlen, reason);  if (ri)    bgp_rib_withdraw (rn, ri, peer, afi, safi, 1);  bgp_unlock_node (rn);  return 0;}intbgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr, 	     int afi, int safi, int type, int sub_type, struct prefix_rd *prd,	      u_char *tag){  struct bgp *bgp;  char buf[SU_ADDRSTRLEN];  struct bgp_node *rn;  struct bgp_info *ri;  bgp = peer->bgp;  /* Logging. */  if (BGP_DEBUG (update, UPDATE_IN))      zlog (peer->log, LOG_INFO, "%s rcvd UPDATE about %s/%d -- withdrawn",	  peer->host,	  inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),	  p->prefixlen);  /* Lookup node. */  rn = bgp_afi_node_get (bgp, afi, safi, p, prd);  /* If peer is soft reconfiguration enabled.  Record input packet for     further calculation. */  if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)      && peer != bgp->peer_self)    bgp_adj_in_unset (rn, peer);  /* Lookup withdrawn route. */  for (ri = rn->info; ri; ri = ri->next)    if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)      break;  /* Withdraw specified route from routing table. */  if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))    bgp_rib_withdraw (rn, ri, peer, afi, safi, 0);  else if (BGP_DEBUG (update, UPDATE_IN))    zlog (peer->log, LOG_INFO, 	  "%s Can't find the route %s/%d", peer->host,	  inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),	  p->prefixlen);  /* Unlock bgp_node_get() lock. */  bgp_unlock_node (rn);  return 0;}voidbgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw){  struct bgp *bgp;  struct attr attr;  struct aspath *aspath;  struct prefix p;  struct bgp_info binfo;  struct peer *from;  int ret = RMAP_DENYMATCH;  bgp = peer->bgp;  from = bgp->peer_self;  bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);  aspath = attr.aspath;  attr.local_pref = bgp->default_local_pref;  memcpy (&attr.nexthop, &peer->nexthop.v4, IPV4_MAX_BYTELEN);  if (afi == AFI_IP)    str2prefix ("0.0.0.0/0", &p);#ifdef HAVE_IPV6  else if (afi == AFI_IP6)    {      str2prefix ("::/0", &p);      /* IPv6 global nexthop must be included. */      memcpy (&attr.mp_nexthop_global, &peer->nexthop.v6_global, 	      IPV6_MAX_BYTELEN);	      attr.mp_nexthop_len = 16;       /* If the peer is on shared nextwork and we have link-local	 nexthop set it. */      if (peer->shared_network 	  && !IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_local))	{	  memcpy (&attr.mp_nexthop_local, &peer->nexthop.v6_local, 		  IPV6_MAX_BYTELEN);	  attr.mp_nexthop_len = 32;	}    }#endif /* HAVE_IPV6 */  else    return;  if (peer->default_rmap[afi][safi].name)    {      binfo.peer = bgp->peer_self;      binfo.attr = &attr;      ret = route_map_apply (peer->default_rmap[afi][safi].map, &p,			     RMAP_BGP, &binfo);      if (ret == RMAP_DENYMATCH)	{	  bgp_attr_flush (&attr);	  withdraw = 1;	}    }  if (withdraw)    {      if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE))	bgp_default_withdraw_send (peer, afi, safi);      UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);    }  else    {      SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);      bgp_default_update_send (peer, &attr, afi, safi, from);    }  aspath_unintern (aspath);}static voidbgp_announce_table (struct peer *peer, afi_t afi, safi_t safi,		    struct bgp_table *table){  struct bgp_node *rn;  struct bgp_info *ri;  struct attr attr;  if (! table)    table = peer->bgp->rib[afi][safi];  if (safi != SAFI_MPLS_VPN      && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))    bgp_default_originate (peer, afi, safi, 0);  for (rn = bgp_table_top (table); rn; rn = bgp_route_next(rn))    for (ri = rn->info; ri; ri = ri->next)      if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED) && ri->peer != peer)	{	  if (bgp_announce_check (ri, peer, &rn->p, &attr, afi, safi))	    bgp_adj_out_set (rn, peer, &rn->p, &attr, afi, safi, ri);	  else	    bgp_adj_out_unset (rn, peer, &rn->p, afi, safi);	}}voidbgp_announce_route (struct peer *peer, afi_t afi, safi_t safi){  struct bgp_node *rn;  struct bgp_table *table;  if (peer->status != Established)    return;  if (! peer->afc_nego[afi][safi])    return;  /* First update is deferred until ORF or ROUTE-REFRESH is received */  if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH))    return;  if (safi != SAFI_MPLS_VPN)    bgp_announce_table (peer, afi, safi, NULL);  else    for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;	 rn = bgp_route_next(rn))      if ((table = (rn->info)) != NULL)	bgp_announce_table (peer, afi, safi, table);}voidbgp_announce_route_all (struct peer *peer){  afi_t afi;  safi_t safi;    for (afi = AFI_IP; afi < AFI_MAX; afi++)    for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)      bgp_announce_route (peer, afi, safi);}static voidbgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi,			 struct bgp_table *table){  int ret;  struct bgp_node *rn;  struct bgp_adj_in *ain;  if (! table)    table = peer->bgp->rib[afi][safi];  for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))    for (ain = rn->adj_in; ain; ain = ain->next)      {	if (ain->peer == peer)	  {	    ret = bgp_update (peer, &rn->p, ain->attr, afi, safi,			      ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,			      NULL, NULL, 1);	    if (ret < 0)	      {		bgp_unlock_node (rn);		return;	      }	    continue;	  }      }}voidbgp_soft_reconfig_in (struct peer *peer, afi_t afi, safi_t safi){  struct bgp_node *rn;  struct bgp_table *table;  if (peer->status != Established)    return;  if (safi != SAFI_MPLS_VPN)    bgp_soft_reconfig_table (peer, afi, safi, NULL);  else    for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;	 rn = bgp_route_next (rn))      if ((table = rn->info) != NULL)	bgp_soft_reconfig_table (peer, afi, safi, table);}static voidbgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,		       struct bgp_table *table){  struct bgp_node *rn;  struct bgp_adj_in *ain;

⌨️ 快捷键说明

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