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

📄 bgp_route.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 5 页
字号:
  struct bgp_adj_out *aout;  struct bgp_info *ri;  if (! table)    table = peer->bgp->rib[afi][safi];  for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))    {      for (ri = rn->info; ri; ri = ri->next)	if (ri->peer == peer)	  {	    bgp_rib_remove (rn, ri, peer, afi, safi);	    break;	  }      for (ain = rn->adj_in; ain; ain = ain->next)	if (ain->peer == peer)	  {	    bgp_adj_in_remove (rn, ain);	    bgp_unlock_node (rn);	    break;	  }      for (aout = rn->adj_out; aout; aout = aout->next)	if (aout->peer == peer)	  {	    bgp_adj_out_remove (rn, aout, peer, afi, safi);	    bgp_unlock_node (rn);	    break;	  }    }}voidbgp_clear_route (struct peer *peer, afi_t afi, safi_t safi){  struct bgp_node *rn;  struct bgp_table *table;  if (! peer->afc[afi][safi])    return;  if (safi != SAFI_MPLS_VPN)    bgp_clear_route_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_clear_route_table (peer, afi, safi, table);}  voidbgp_clear_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_clear_route (peer, afi, safi);}voidbgp_clear_adj_in (struct peer *peer, afi_t afi, safi_t safi){  struct bgp_table *table;  struct bgp_node *rn;  struct bgp_adj_in *ain;  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)	{          bgp_adj_in_remove (rn, ain);          bgp_unlock_node (rn);          break;	}}/* Delete all kernel routes. */voidbgp_terminate (){  struct bgp *bgp;  struct listnode *nn;  struct bgp_node *rn;  struct bgp_table *table;  struct bgp_info *ri;  LIST_LOOP (bm->bgp, bgp, nn)    {      table = bgp->rib[AFI_IP][SAFI_UNICAST];      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->type == ZEBRA_ROUTE_BGP 	      && ri->sub_type == BGP_ROUTE_NORMAL)	    bgp_zebra_withdraw (&rn->p, ri);      table = bgp->rib[AFI_IP6][SAFI_UNICAST];      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->type == ZEBRA_ROUTE_BGP 	      && ri->sub_type == BGP_ROUTE_NORMAL)	    bgp_zebra_withdraw (&rn->p, ri);    }}voidbgp_reset (){  vty_reset ();  bgp_zclient_reset ();  access_list_reset ();  prefix_list_reset ();}/* Parse NLRI stream.  Withdraw NLRI is recognized by NULL attr   value. */intbgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet){  u_char *pnt;  u_char *lim;  struct prefix p;  int psize;  int ret;  /* Check peer status. */  if (peer->status != Established)    return 0;    pnt = packet->nlri;  lim = pnt + packet->length;  for (; pnt < lim; pnt += psize)    {      /* Clear prefix structure. */      memset (&p, 0, sizeof (struct prefix));      /* Fetch prefix length. */      p.prefixlen = *pnt++;      p.family = afi2family (packet->afi);            /* Already checked in nlri_sanity_check().  We do double check         here. */      if ((packet->afi == AFI_IP && p.prefixlen > 32)	  || (packet->afi == AFI_IP6 && p.prefixlen > 128))	return -1;      /* Packet size overflow check. */      psize = PSIZE (p.prefixlen);      /* When packet overflow occur return immediately. */      if (pnt + psize > lim)	return -1;      /* Fetch prefix from NLRI packet. */      memcpy (&p.u.prefix, pnt, psize);      /* Check address. */      if (packet->afi == AFI_IP && packet->safi == SAFI_UNICAST)	{	  if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))	    {	      zlog (peer->log, LOG_ERR, 		    "IPv4 unicast NLRI is multicast address %s",		    inet_ntoa (p.u.prefix4));	      bgp_notify_send (peer, 			       BGP_NOTIFY_UPDATE_ERR, 			       BGP_NOTIFY_UPDATE_INVAL_NETWORK);	      return -1;	    }	}#ifdef HAVE_IPV6      /* Check address. */      if (packet->afi == AFI_IP6 && packet->safi == SAFI_UNICAST)	{	  if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))	    {	      char buf[BUFSIZ];	      zlog (peer->log, LOG_WARNING, 		    "IPv6 link-local NLRI received %s ignore this NLRI",		    inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));	      continue;	    }	}#endif /* HAVE_IPV6 */      /* Normal process. */      if (attr)	ret = bgp_update (peer, &p, attr, packet->afi, packet->safi, 			  ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0);      else	ret = bgp_withdraw (peer, &p, attr, packet->afi, packet->safi, 			    ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);      /* Address family configuration mismatch or maximum-prefix count         overflow. */      if (ret < 0)	return -1;    }  /* Packet length consistency check. */  if (pnt != lim)    return -1;  return 0;}/* NLRI encode syntax check routine. */intbgp_nlri_sanity_check (struct peer *peer, int afi, u_char *pnt,		       bgp_size_t length){  u_char *end;  u_char prefixlen;  int psize;  end = pnt + length;  /* RFC1771 6.3 The NLRI field in the UPDATE message is checked for     syntactic validity.  If the field is syntactically incorrect,     then the Error Subcode is set to Invalid Network Field. */  while (pnt < end)    {      prefixlen = *pnt++;            /* Prefix length check. */      if ((afi == AFI_IP && prefixlen > 32)	  || (afi == AFI_IP6 && prefixlen > 128))	{	  plog_err (peer->log, 		    "%s [Error] Update packet error (wrong prefix length %d)",		    peer->host, prefixlen);	  bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 			   BGP_NOTIFY_UPDATE_INVAL_NETWORK);	  return -1;	}      /* Packet size overflow check. */      psize = PSIZE (prefixlen);      if (pnt + psize > end)	{	  plog_err (peer->log, 		    "%s [Error] Update packet error"		    " (prefix data overflow prefix size is %d)",		    peer->host, psize);	  bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 			   BGP_NOTIFY_UPDATE_INVAL_NETWORK);	  return -1;	}      pnt += psize;    }  /* Packet length consistency check. */  if (pnt != end)    {      plog_err (peer->log,		"%s [Error] Update packet error"		" (prefix length mismatch with total length)",		peer->host);      bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 		       BGP_NOTIFY_UPDATE_INVAL_NETWORK);      return -1;    }  return 0;}struct bgp_static *bgp_static_new (){  struct bgp_static *new;  new = XMALLOC (MTYPE_BGP_STATIC, sizeof (struct bgp_static));  memset (new, 0, sizeof (struct bgp_static));  return new;}voidbgp_static_free (struct bgp_static *bgp_static){  if (bgp_static->rmap.name)    free (bgp_static->rmap.name);  XFREE (MTYPE_BGP_STATIC, bgp_static);}voidbgp_static_update (struct bgp *bgp, struct prefix *p,		   struct bgp_static *bgp_static, afi_t afi, safi_t safi){  struct bgp_node *rn;  struct bgp_info *ri;  struct bgp_info *new;  struct bgp_info info;  struct attr attr;  struct attr attr_tmp;  struct attr *attr_new;  int ret;  rn = bgp_afi_node_get (bgp, afi, safi, p, NULL);  bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);  if (bgp_static)    {      attr.nexthop = bgp_static->igpnexthop;      attr.med = bgp_static->igpmetric;      attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);    }  /* Apply route-map. */  if (bgp_static->rmap.name)    {      attr_tmp = attr;      info.peer = bgp->peer_self;      info.attr = &attr_tmp;      ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);      if (ret == RMAP_DENYMATCH)	{    	  /* Free uninterned attribute. */	  bgp_attr_flush (&attr_tmp);	  /* Unintern original. */	  aspath_unintern (attr.aspath);	  bgp_static_withdraw (bgp, p, afi, safi);	  return;	}      attr_new = bgp_attr_intern (&attr_tmp);    }  else    attr_new = bgp_attr_intern (&attr);  for (ri = rn->info; ri; ri = ri->next)    if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP	&& ri->sub_type == BGP_ROUTE_STATIC)      break;  if (ri)    {      if (attrhash_cmp (ri->attr, attr_new))	{	  bgp_unlock_node (rn);	  bgp_attr_unintern (attr_new);	  aspath_unintern (attr.aspath);	  return;	}      else	{	  /* The attribute is changed. */	  SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);	  /* Rewrite BGP route information. */	  bgp_aggregate_decrement (bgp, p, ri, afi, safi);	  bgp_attr_unintern (ri->attr);	  ri->attr = attr_new;	  ri->uptime = time (NULL);	  /* Process change. */	  bgp_aggregate_increment (bgp, p, ri, afi, safi);	  bgp_process (bgp, rn, afi, safi);	  bgp_unlock_node (rn);	  aspath_unintern (attr.aspath);	  return;	}    }  /* Make new BGP info. */  new = bgp_info_new ();  new->type = ZEBRA_ROUTE_BGP;  new->sub_type = BGP_ROUTE_STATIC;  new->peer = bgp->peer_self;  SET_FLAG (new->flags, BGP_INFO_VALID);  new->attr = attr_new;  new->uptime = time (NULL);  /* Aggregate address increment. */  bgp_aggregate_increment (bgp, p, new, afi, safi);    /* Register new BGP information. */  bgp_info_add (rn, new);  /* Process change. */  bgp_process (bgp, rn, afi, safi);  /* Unintern original. */  aspath_unintern (attr.aspath);}voidbgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi,			 u_char safi, struct prefix_rd *prd, u_char *tag){  struct bgp_node *rn;  struct bgp_info *new;  rn = bgp_afi_node_get (bgp, afi, safi, p, prd);  /* Make new BGP info. */  new = bgp_info_new ();  new->type = ZEBRA_ROUTE_BGP;  new->sub_type = BGP_ROUTE_STATIC;  new->peer = bgp->peer_self;  new->attr = bgp_attr_default_intern (BGP_ORIGIN_IGP);  SET_FLAG (new->flags, BGP_INFO_VALID);  new->uptime = time (NULL);  memcpy (new->tag, tag, 3);  /* Aggregate address increment. */  bgp_aggregate_increment (bgp, p, (struct bgp_info *) new, afi, safi);    /* Register new BGP information. */  bgp_info_add (rn, (struct bgp_info *) new);  /* Process change. */  bgp_process (bgp, rn, afi, safi);}voidbgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,		     safi_t safi){  struct bgp_node *rn;  struct bgp_info *ri;  rn = bgp_afi_node_get (bgp, afi, safi, p, NULL);  /* Check selected route and self inserted route. */  for (ri = rn->info; ri; ri = ri->next)    if (ri->peer == bgp->peer_self 	&& ri->type == ZEBRA_ROUTE_BGP	&& ri->sub_type == BGP_ROUTE_STATIC)      break;  /* Withdraw static BGP route from routing table. */  if (ri)    {      bgp_aggregate_decrement (bgp, p, ri, afi, safi);      UNSET_FLAG (ri->flags, BGP_INFO_VALID);      bgp_process (bgp, rn, afi, safi);      bgp_info_delete (rn, ri);      bgp_info_free (ri);      bgp_unlock_node (rn);    }  /* Unlock bgp_node_lookup. */  bgp_unlock_node (rn);}voidbgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi,			   u_char safi, struct prefix_rd *prd, u_char *tag){  struct bgp_node *rn;  struct bgp_info *ri;  rn = bgp_afi_node_get (bgp, afi, safi, p, prd);  /* Check selected route and self inserted route. */  for (ri = rn->info; ri; ri = ri->next)    if (ri->peer == bgp->peer_self 	&& ri->type == ZEBRA_ROUTE_BGP	&& ri->sub_type == BGP_ROUTE_STATIC)      break;  /* Withdraw static BGP route from routing table. */  if (ri)    {      bgp_aggregate_decrement (bgp, p, ri, afi, safi);      UNSET_FLAG (ri->flags, BGP_INFO_VALID);      bgp_process (bgp, rn, afi, safi);      bgp_info_delete (rn, ri);      bgp_info_free (ri);      bgp_unlock_node (rn);    }  /* Unlock bgp_node_lookup. */  bgp_unlock_node (rn);}/* Configure static BGP network.  When user don't run zebra, static   route should be installed as valid.  */intbgp_static_set (struct vty *vty, struct bgp *bgp, char *ip_str, u_int16_t afi,		u_char safi, char *rmap, int backdoor){  int ret;  struct prefix p;  struct bgp_static *bgp_static;  struct bgp_node *rn;  int need_update = 0;  /* Convert IP prefix string to struct prefix. */  ret = str2prefix (ip_str, &p);  if (! ret)

⌨️ 快捷键说明

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