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

📄 bgp_attr.c

📁 linux 路由软件 可支持RIP OSPF BGP等
💻 C
📖 第 1 页 / 共 4 页
字号:
  /* AS path attribute extended length bit check. */  if (aspath->length > 255)    {      stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);      stream_putc (s, BGP_ATTR_AS_PATH);      stream_putw (s, aspath->length);    }  else    {      stream_putc (s, BGP_ATTR_FLAG_TRANS);      stream_putc(s, BGP_ATTR_AS_PATH);      stream_putc (s, aspath->length);    }  stream_put (s, aspath->data, aspath->length);  if (aspath != attr->aspath)    aspath_free (aspath);  /* Nexthop attribute. */  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP) && afi == AFI_IP)    {      stream_putc (s, BGP_ATTR_FLAG_TRANS);      stream_putc (s, BGP_ATTR_NEXT_HOP);      stream_putc (s, 4);      if (safi == SAFI_MPLS_VPN)	{	  if (attr->nexthop.s_addr == 0)	    stream_put_ipv4 (s, peer->nexthop.v4.s_addr);	  else	    stream_put_ipv4 (s, attr->nexthop.s_addr);	}      else	stream_put_ipv4 (s, attr->nexthop.s_addr);    }  /* MED attribute. */  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))    {      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);      stream_putc (s, BGP_ATTR_MULTI_EXIT_DISC);      stream_putc (s, 4);      stream_putl (s, attr->med);    }  /* Local preference. */  if (peer_sort (peer) == BGP_PEER_IBGP ||      peer_sort (peer) == BGP_PEER_CONFED)    {      stream_putc (s, BGP_ATTR_FLAG_TRANS);      stream_putc (s, BGP_ATTR_LOCAL_PREF);      stream_putc (s, 4);      stream_putl (s, attr->local_pref);    }  /* Atomic aggregate. */  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))    {      stream_putc (s, BGP_ATTR_FLAG_TRANS);      stream_putc (s, BGP_ATTR_ATOMIC_AGGREGATE);      stream_putc (s, 0);    }  /* Aggregator. */  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR))    {      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);      stream_putc (s, BGP_ATTR_AGGREGATOR);      stream_putc (s, 6);      stream_putw (s, attr->aggregator_as);      stream_put_ipv4 (s, attr->aggregator_addr.s_addr);    }  /* Community attribute. */  if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY)       && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES)))    {      if (attr->community->size * 4 > 255)	{	  stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);	  stream_putc (s, BGP_ATTR_COMMUNITIES);	  stream_putw (s, attr->community->size * 4);	}      else	{	  stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);	  stream_putc (s, BGP_ATTR_COMMUNITIES);	  stream_putc (s, attr->community->size * 4);	}      stream_put (s, attr->community->val, attr->community->size * 4);    }  /* Route Reflector. */  if (peer_sort (peer) == BGP_PEER_IBGP      && from      && peer_sort (from) == BGP_PEER_IBGP)    {      /* Originator ID. */      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);      stream_putc (s, BGP_ATTR_ORIGINATOR_ID);      stream_putc (s, 4);      if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))	stream_put_in_addr (s, &attr->originator_id);      else	{	  if (from)	    stream_put_in_addr (s, &from->remote_id);	  else	    stream_put_in_addr (s, &attr->originator_id);	}      /* Cluster list. */      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);      stream_putc (s, BGP_ATTR_CLUSTER_LIST);            if (attr->cluster)	{	  stream_putc (s, attr->cluster->length + 4);	  /* If this peer configuration's parent BGP has cluster_id. */	  if (bgp->config & BGP_CONFIG_CLUSTER_ID)	    stream_put_in_addr (s, &bgp->cluster_id);	  else	    stream_put_in_addr (s, &bgp->router_id);	  stream_put (s, attr->cluster->list, attr->cluster->length);	}      else	{	  stream_putc (s, 4);	  /* If this peer configuration's parent BGP has cluster_id. */	  if (bgp->config & BGP_CONFIG_CLUSTER_ID)	    stream_put_in_addr (s, &bgp->cluster_id);	  else	    stream_put_in_addr (s, &bgp->router_id);	}    }#ifdef HAVE_IPV6  /* If p is IPv6 address put it into attribute. */  if (p->family == AF_INET6)    {      unsigned long sizep;      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);      stream_putc (s, BGP_ATTR_MP_REACH_NLRI);      sizep = stream_get_putp (s);      stream_putc (s, 0);	/* Length of this attribute. */      stream_putw (s, AFI_IP6);	/* AFI */      stream_putc (s, safi);	/* SAFI */      stream_putc (s, attr->mp_nexthop_len);      if (attr->mp_nexthop_len == 16)	stream_put (s, &attr->mp_nexthop_global, 16);      else if (attr->mp_nexthop_len == 32)	{	  stream_put (s, &attr->mp_nexthop_global, 16);	  stream_put (s, &attr->mp_nexthop_local, 16);	}            /* SNPA */      stream_putc (s, 0);      /* Prefix write. */      stream_put_prefix (s, p);      /* Set MP attribute length. */      stream_putc_at (s, sizep, (stream_get_putp (s) - sizep) - 1);    }#endif /* HAVE_IPV6 */  if (p->family == AF_INET && safi == SAFI_MULTICAST)    {      unsigned long sizep;      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);      stream_putc (s, BGP_ATTR_MP_REACH_NLRI);      sizep = stream_get_putp (s);      stream_putc (s, 0);	/* Length of this attribute. */      stream_putw (s, AFI_IP);	/* AFI */      stream_putc (s, SAFI_MULTICAST);	/* SAFI */      stream_putc (s, 4);      stream_put_ipv4 (s, attr->nexthop.s_addr);      /* SNPA */      stream_putc (s, 0);      /* Prefix write. */      stream_put_prefix (s, p);      /* Set MP attribute length. */      stream_putc_at (s, sizep, (stream_get_putp (s) - sizep) - 1);    }  if (p->family == AF_INET && safi == SAFI_MPLS_VPN)    {      unsigned long sizep;      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);      stream_putc (s, BGP_ATTR_MP_REACH_NLRI);      sizep = stream_get_putp (s);      stream_putc (s, 0);	/* Length of this attribute. */      stream_putw (s, AFI_IP);	/* AFI */      stream_putc (s, BGP_SAFI_VPNV4);	/* SAFI */      stream_putc (s, 12);      stream_putl (s, 0);      stream_putl (s, 0);      stream_put (s, &attr->mp_nexthop_global_in, 4);      /* SNPA */      stream_putc (s, 0);      /* Tag, RD, Prefix write. */      stream_putc (s, p->prefixlen + 88);      stream_put (s, tag, 3);      stream_put (s, prd->val, 8);      stream_put (s, &p->u.prefix, PSIZE (p->prefixlen));      /* Set MP attribute length. */      stream_putc_at (s, sizep, (stream_get_putp (s) - sizep) - 1);    }  /* Extended Communities attribute. */  if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)       && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES)))    {      if (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED)	{	  if (attr->ecommunity->size * 8 > 255)	    {	      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);	      stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);	      stream_putw (s, attr->ecommunity->size * 8);	    }	  else	    {	      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);	      stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);	      stream_putc (s, attr->ecommunity->size * 8);	    }	  stream_put (s, attr->ecommunity->val, attr->ecommunity->size * 8);	}      else	{	  u_char *pnt;	  int tbit;	  int ecom_tr_size = 0;	  int i;	  for (i = 0; i < attr->ecommunity->size; i++)	    {	      pnt = attr->ecommunity->val + (i * 8);	      tbit = *pnt;	      if (CHECK_FLAG (tbit, ECOMMUNITY_FLAG_NON_TRANSITIVE))		continue;	      ecom_tr_size++;	    }	  if (ecom_tr_size)	    {	      if (ecom_tr_size * 8 > 255)		{		  stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);		  stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);		  stream_putw (s, ecom_tr_size * 8);		}	      else		{		  stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);		  stream_putc (s, BGP_ATTR_EXT_COMMUNITIES);		  stream_putc (s, ecom_tr_size * 8);		}	      for (i = 0; i < attr->ecommunity->size; i++)		{		  pnt = attr->ecommunity->val + (i * 8);		  tbit = *pnt;		  if (CHECK_FLAG (tbit, ECOMMUNITY_FLAG_NON_TRANSITIVE))		    continue;		  stream_put (s, pnt, 8);		}	    }	}    }  /* Unknown transit attribute. */  if (attr->transit)    stream_put (s, attr->transit->val, attr->transit->length);  /* Return total size of attribute. */  return stream_get_putp (s) - cp;}bgp_size_tbgp_packet_withdraw (struct peer *peer, struct stream *s, struct prefix *p,		     afi_t afi, safi_t safi, struct prefix_rd *prd,		     u_char *tag){  unsigned long cp;  unsigned long attrlen_pnt;  bgp_size_t size;  cp = stream_get_putp (s);  stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);  stream_putc (s, BGP_ATTR_MP_UNREACH_NLRI);  attrlen_pnt = stream_get_putp (s);  stream_putc (s, 0);		/* Length of this attribute. */  stream_putw (s, family2afi (p->family));  if (safi == SAFI_MPLS_VPN)    {      /* SAFI */      stream_putc (s, BGP_SAFI_VPNV4);      /* prefix. */      stream_putc (s, p->prefixlen + 88);      stream_put (s, tag, 3);      stream_put (s, prd->val, 8);      stream_put (s, &p->u.prefix, PSIZE (p->prefixlen));    }  else    {      /* SAFI */      stream_putc (s, safi);      /* prefix */      stream_put_prefix (s, p);    }  /* Set MP attribute length. */  size = stream_get_putp (s) - attrlen_pnt - 1;  stream_putc_at (s, attrlen_pnt, size);  return stream_get_putp (s) - cp;}/* Initialization of attribute. */voidbgp_attr_init (){  void attrhash_init ();  aspath_init ();  attrhash_init ();  community_init ();  ecommunity_init ();  cluster_init ();  transit_init ();}/* Make attribute packet. */voidbgp_dump_routes_attr (struct stream *s, struct attr *attr){  unsigned long cp;  unsigned long len;  struct aspath *aspath;  /* Remember current pointer. */  cp = stream_get_putp (s);  /* Place holder of length. */  stream_putw (s, 0);  /* Origin attribute. */  stream_putc (s, BGP_ATTR_FLAG_TRANS);  stream_putc (s, BGP_ATTR_ORIGIN);  stream_putc (s, 1);  stream_putc (s, attr->origin);  aspath = attr->aspath;  if (aspath->length > 255)    {      stream_putc (s, BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);      stream_putc (s, BGP_ATTR_AS_PATH);      stream_putw (s, aspath->length);    }  else    {      stream_putc (s, BGP_ATTR_FLAG_TRANS);      stream_putc (s, BGP_ATTR_AS_PATH);      stream_putc (s, aspath->length);    }  stream_put (s, aspath->data, aspath->length);  /* Nexthop attribute. */  stream_putc (s, BGP_ATTR_FLAG_TRANS);  stream_putc (s, BGP_ATTR_NEXT_HOP);  stream_putc (s, 4);  stream_put_ipv4 (s, attr->nexthop.s_addr);  /* MED attribute. */  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))    {      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL);      stream_putc (s, BGP_ATTR_MULTI_EXIT_DISC);      stream_putc (s, 4);      stream_putl (s, attr->med);    }  /* Local preference. */  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))    {      stream_putc (s, BGP_ATTR_FLAG_TRANS);      stream_putc (s, BGP_ATTR_LOCAL_PREF);      stream_putc (s, 4);      stream_putl (s, attr->local_pref);    }  /* Atomic aggregate. */  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))    {      stream_putc (s, BGP_ATTR_FLAG_TRANS);      stream_putc (s, BGP_ATTR_ATOMIC_AGGREGATE);      stream_putc (s, 0);    }  /* Aggregator. */  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR))    {      stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);      stream_putc (s, BGP_ATTR_AGGREGATOR);      stream_putc (s, 6);      stream_putw (s, attr->aggregator_as);      stream_put_ipv4 (s, attr->aggregator_addr.s_addr);    }  /* Community attribute. */  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES))    {      if (attr->community->size * 4 > 255)	{	  stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_EXTLEN);	  stream_putc (s, BGP_ATTR_COMMUNITIES);	  stream_putw (s, attr->community->size * 4);	}      else	{	  stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS);	  stream_putc (s, BGP_ATTR_COMMUNITIES);	  stream_putc (s, attr->community->size * 4);	}      stream_put (s, attr->community->val, attr->community->size * 4);    }  /* Return total size of attribute. */  len = stream_get_putp (s) - cp - 2;  stream_putw_at (s, cp, len);}

⌨️ 快捷键说明

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