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

📄 bgp_attr.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 4 页
字号:
	    aspath = aspath_add_seq (aspath, peer->change_local_as);	}    }  else if (peer_sort (peer) == BGP_PEER_CONFED)    {      /* A confed member, so we need to do the AS_CONFED_SEQUENCE thing */      aspath = aspath_dup (attr->aspath);      aspath = aspath_add_confed_seq (aspath, peer->local_as);    }  else    aspath = attr->aspath;  /* 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;      unsigned long draftp = 0;      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);      /* In case of old draft BGP-4+. */      if (peer->version == BGP_VERSION_MP_4_DRAFT_00)	{	  draftp = stream_get_putp (s);	  stream_putw (s, 0);	}            /* Prefix write. */      stream_put_prefix (s, p);      /* Set MP attribute length. */      stream_putc_at (s, sizep, (stream_get_putp (s) - sizep) - 1);      /* In case of old draft BGP-4+. */      if (peer->version == BGP_VERSION_MP_4_DRAFT_00)	stream_putw_at (s, draftp, (stream_get_putp (s) - draftp) - 2);    }#endif /* HAVE_IPV6 */  if (p->family == AF_INET && safi == SAFI_MULTICAST)    {      unsigned long sizep;      unsigned long draftp = 0;      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);      /* In case of old draft BGP-4+. */      if (peer->version == BGP_VERSION_MP_4_DRAFT_00)	{	  draftp = stream_get_putp (s);	  stream_putw (s, 0);	}            /* Prefix write. */      stream_put_prefix (s, p);      /* Set MP attribute length. */      stream_putc_at (s, sizep, (stream_get_putp (s) - sizep) - 1);      /* In case of old draft BGP-4+. */      if (peer->version == BGP_VERSION_MP_4_DRAFT_00)	stream_putw_at (s, draftp, (stream_get_putp (s) - draftp) - 2);    }  if (p->family == AF_INET && safi == SAFI_MPLS_VPN)    {      unsigned long sizep;      unsigned long draftp = 0;      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);      /* In case of old draft BGP-4+. */      if (peer->version == BGP_VERSION_MP_4_DRAFT_00)	{	  draftp = stream_get_putp (s);	  stream_putw (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);      /* In case of old draft BGP-4+. */      if (peer->version == BGP_VERSION_MP_4_DRAFT_00)	stream_putw_at (s, draftp, (stream_get_putp (s) - draftp) - 2);    }  /* 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 (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);    }  /* 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 + -