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

📄 bgp_packet.c

📁 linux 路由软件 可支持RIP OSPF BGP等
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (peer->status != Established)     {      zlog_err ("%s [FSM] Update packet received under status %s",		peer->host, LOOKUP (bgp_status_msg, peer->status));      bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);      return -1;    }  /* Set initial values. */  memset (&attr, 0, sizeof (struct attr));  memset (&update, 0, sizeof (struct bgp_nlri));  memset (&withdraw, 0, sizeof (struct bgp_nlri));  memset (&mp_update, 0, sizeof (struct bgp_nlri));  memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));  s = peer->ibuf;  end = stream_pnt (s) + size;  /* RFC1771 6.3 If the Unfeasible Routes Length or Total Attribute     Length is too large (i.e., if Unfeasible Routes Length + Total     Attribute Length + 23 exceeds the message Length), then the Error     Subcode is set to Malformed Attribute List.  */  if (stream_pnt (s) + 2 > end)    {      zlog_err ("%s [Error] Update packet error"		" (packet length is short for unfeasible length)",		peer->host);      bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 		       BGP_NOTIFY_UPDATE_MAL_ATTR);      return -1;    }  /* Unfeasible Route Length. */  withdraw_len = stream_getw (s);  /* Unfeasible Route Length check. */  if (stream_pnt (s) + withdraw_len > end)    {      zlog_err ("%s [Error] Update packet error"		" (packet unfeasible length overflow %d)",		peer->host, withdraw_len);      bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 		       BGP_NOTIFY_UPDATE_MAL_ATTR);      return -1;    }  /* Unfeasible Route packet format check. */  if (withdraw_len > 0)    {      ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), withdraw_len);      if (ret < 0)	return -1;      if (BGP_DEBUG (packet, PACKET_RECV))	  zlog_info ("%s [Update:RECV] Unfeasible NLRI received", peer->host);      withdraw.afi = AFI_IP;      withdraw.safi = SAFI_UNICAST;      withdraw.nlri = stream_pnt (s);      withdraw.length = withdraw_len;      stream_forward (s, withdraw_len);    }    /* Attribute total length check. */  if (stream_pnt (s) + 2 > end)    {      zlog_warn ("%s [Error] Packet Error"		 " (update packet is short for attribute length)",		 peer->host);      bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 		       BGP_NOTIFY_UPDATE_MAL_ATTR);      return -1;    }  /* Fetch attribute total length. */  attribute_len = stream_getw (s);  /* Attribute length check. */  if (stream_pnt (s) + attribute_len > end)    {      zlog_warn ("%s [Error] Packet Error"		 " (update packet attribute length overflow %d)",		 peer->host, attribute_len);      bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, 		       BGP_NOTIFY_UPDATE_MAL_ATTR);      return -1;    }  /* Parse attribute when it exists. */  if (attribute_len)    {      ret = bgp_attr_parse (peer, &attr, attribute_len, 			    &mp_update, &mp_withdraw);      if (ret < 0)	return -1;    }  /* Logging the attribute. */  if (BGP_DEBUG (update, UPDATE_IN))    {      ret= bgp_dump_attr (peer, &attr, attrstr, BUFSIZ);      if (ret)	zlog (peer->log, LOG_INFO, "%s rcvd UPDATE w/ attr: %s",	      peer->host, attrstr);    }  /* Network Layer Reachability Information. */  update_len = end - stream_pnt (s);  if (update_len)    {      /* Check NLRI packet format and prefix length. */      ret = bgp_nlri_sanity_check (peer, AFI_IP, stream_pnt (s), update_len);      if (ret < 0)	return -1;      /* Set NLRI portion to structure. */      update.afi = AFI_IP;      update.safi = SAFI_UNICAST;      update.nlri = stream_pnt (s);      update.length = update_len;      stream_forward (s, update_len);    }  /* NLRI is processed only when the peer is configured specific     Address Family and Subsequent Address Family. */  if (peer->afc[AFI_IP][SAFI_UNICAST])    {      if (withdraw.length)	bgp_nlri_parse (peer, NULL, &withdraw);      if (update.length)	{	  /* We check well-known attribute only for IPv4 unicast	     update. */	  ret = bgp_attr_check (peer, &attr);	  if (ret < 0)	    return -1;	  bgp_nlri_parse (peer, &attr, &update);	}      if (mp_update.length	  && mp_update.afi == AFI_IP 	  && mp_update.safi == SAFI_UNICAST)	bgp_nlri_parse (peer, &attr, &mp_update);      if (mp_withdraw.length	  && mp_withdraw.afi == AFI_IP 	  && mp_withdraw.safi == SAFI_UNICAST)	bgp_nlri_parse (peer, NULL, &mp_withdraw);      if (! attribute_len && ! withdraw_len)	{	  /* End-of-RIB received */	  SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);	  if (BGP_DEBUG (normal, NORMAL))	    zlog (peer->log, LOG_INFO, "rcvd End-of-RIB for IPv4 Unicast from %s",		  peer->host);	  /* NSF delete stale route */	  if (peer->nsf[AFI_IP][SAFI_UNICAST])	    bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);	}    }  if (peer->afc[AFI_IP][SAFI_MULTICAST])    {      if (mp_update.length	  && mp_update.afi == AFI_IP 	  && mp_update.safi == SAFI_MULTICAST)	bgp_nlri_parse (peer, &attr, &mp_update);      if (mp_withdraw.length	  && mp_withdraw.afi == AFI_IP 	  && mp_withdraw.safi == SAFI_MULTICAST)	bgp_nlri_parse (peer, NULL, &mp_withdraw);      if (! withdraw_len	  && mp_withdraw.afi == AFI_IP	  && mp_withdraw.safi == SAFI_MULTICAST	  && mp_withdraw.length == 0)	{	  /* End-of-RIB received */	  SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST], PEER_STATUS_EOR_RECEIVED);	  if (BGP_DEBUG (normal, NORMAL))	    zlog (peer->log, LOG_INFO, "rcvd End-of-RIB for IPv4 Multicast from %s",		  peer->host);	  /* NSF delete stale route */	  if (peer->nsf[AFI_IP][SAFI_MULTICAST])	    bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);	}    }  if (peer->afc[AFI_IP6][SAFI_UNICAST])    {      if (mp_update.length 	  && mp_update.afi == AFI_IP6 	  && mp_update.safi == SAFI_UNICAST)	bgp_nlri_parse (peer, &attr, &mp_update);      if (mp_withdraw.length 	  && mp_withdraw.afi == AFI_IP6 	  && mp_withdraw.safi == SAFI_UNICAST)	bgp_nlri_parse (peer, NULL, &mp_withdraw);      if (! withdraw_len	  && mp_withdraw.afi == AFI_IP6	  && mp_withdraw.safi == SAFI_UNICAST	  && mp_withdraw.length == 0)	{	  /* End-of-RIB received */	  SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);	  if (BGP_DEBUG (normal, NORMAL))	    zlog (peer->log, LOG_INFO, "rcvd End-of-RIB for IPv6 Unicast from %s",		  peer->host);	  /* NSF delete stale route */	  if (peer->nsf[AFI_IP6][SAFI_UNICAST])	    bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);	}    }  if (peer->afc[AFI_IP6][SAFI_MULTICAST])    {      if (mp_update.length 	  && mp_update.afi == AFI_IP6 	  && mp_update.safi == SAFI_MULTICAST)	bgp_nlri_parse (peer, &attr, &mp_update);      if (mp_withdraw.length 	  && mp_withdraw.afi == AFI_IP6 	  && mp_withdraw.safi == SAFI_MULTICAST)	bgp_nlri_parse (peer, NULL, &mp_withdraw);      if (! withdraw_len	  && mp_withdraw.afi == AFI_IP6	  && mp_withdraw.safi == SAFI_MULTICAST	  && mp_withdraw.length == 0)	{	  /* End-of-RIB received */	  SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_MULTICAST], PEER_STATUS_EOR_RECEIVED);	  if (BGP_DEBUG (update, UPDATE_IN))	    zlog (peer->log, LOG_INFO, "rcvd End-of-RIB for IPv6 Multicast from %s",		  peer->host);	  /* NSF delete stale route */	  if (peer->nsf[AFI_IP6][SAFI_MULTICAST])	    bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);	}    }  if (peer->afc[AFI_IP][SAFI_MPLS_VPN])    {      if (mp_update.length 	  && mp_update.afi == AFI_IP 	  && mp_update.safi == BGP_SAFI_VPNV4)	bgp_nlri_parse_vpnv4 (peer, &attr, &mp_update);      if (mp_withdraw.length 	  && mp_withdraw.afi == AFI_IP 	  && mp_withdraw.safi == BGP_SAFI_VPNV4)	bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);      if (! withdraw_len	  && mp_withdraw.afi == AFI_IP	  && mp_withdraw.safi == BGP_SAFI_VPNV4	  && mp_withdraw.length == 0)	{	  /* End-of-RIB received */	  if (BGP_DEBUG (update, UPDATE_IN))	    zlog (peer->log, LOG_INFO, "rcvd End-of-RIB for VPNv4 Unicast from %s",		  peer->host);	}    }  /* Everything is done.  We unintern temporary structures which     interned in bgp_attr_parse(). */  if (attr.aspath)    aspath_unintern (attr.aspath);  if (attr.community)    community_unintern (attr.community);  if (attr.ecommunity)    ecommunity_unintern (attr.ecommunity);  if (attr.cluster)    cluster_unintern (attr.cluster);  if (attr.transit)    transit_unintern (attr.transit);  /* If peering is stopped due to some reason, do not generate BGP     event.  */  if (peer->status != Established)    return 0;  /* Increment packet counter. */  peer->update_in++;  peer->update_time = time (NULL);  /* Generate BGP event. */  BGP_EVENT_ADD (peer, Receive_UPDATE_message);  return 0;}/* Notify message treatment function. */voidbgp_notify_receive (struct peer *peer, bgp_size_t size){  struct bgp_notify bgp_notify;  if (peer->notify.data)    {      XFREE (MTYPE_TMP, peer->notify.data);      peer->notify.data = NULL;      peer->notify.length = 0;    }  bgp_notify.code = stream_getc (peer->ibuf);  bgp_notify.subcode = stream_getc (peer->ibuf);  bgp_notify.length = size - 2;  bgp_notify.data = NULL;  /* Preserv notify code and sub code. */  peer->notify.code = bgp_notify.code;  peer->notify.subcode = bgp_notify.subcode;  /* For further diagnostic record returned Data. */  if (bgp_notify.length)    {      peer->notify.length = size - 2;      peer->notify.data = XMALLOC (MTYPE_TMP, size - 2);      memcpy (peer->notify.data, stream_pnt (peer->ibuf), size - 2);    }  /* For debug */  {    int i;    int first = 0;    char c[4];    if (bgp_notify.length)      {	bgp_notify.data = XMALLOC (MTYPE_TMP, bgp_notify.length * 3);	for (i = 0; i < bgp_notify.length; i++)	  if (first)	    {	      sprintf (c, " %02x", stream_getc (peer->ibuf));	      strcat (bgp_notify.data, c);	    }	  else	    {	      first = 1;	      sprintf (c, "%02x", stream_getc (peer->ibuf));	      strcpy (bgp_notify.data, c);	    }      }    bgp_notify_print(peer, &bgp_notify, "received");    if (bgp_notify.data)      XFREE (MTYPE_TMP, bgp_notify.data);  }  /* peer count update */  peer->notify_in++;  if (peer->status == Established)    peer->last_reset = PEER_DOWN_NOTIFY_RECEIVED;  /* We have to check for Notify with Unsupported Optional Parameter.     in that case we fallback to open without the capability option.     But this done in bgp_stop. We just mark it here to avoid changing     the fsm tables.  */  if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&      bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM )    UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);  /* Also apply to Unsupported Capability until remote router support     capability. */  if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR &&      bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL)    UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN);  BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message);}/* Keepalive treatment function -- get keepalive send keepalive */voidbgp_keepalive_receive (struct peer *peer, bgp_size_t size){  if (BGP_DEBUG (keepalive, KEEPALIVE))      zlog_info ("%s KEEPALIVE rcvd", peer->host);     BGP_EVENT_ADD (peer, Receive_KEEPALIVE_message);}/* Route refresh message is received. */voidbgp_route_refresh_receive (struct peer *peer, bgp_size_t size){  afi_t afi;  safi_t safi;  u_char reserved;  struct stream *s;  /* If peer does not have the capability, send notification. */  if (! CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_ADV))    {      plog_err (peer->log, "%s [Error] BGP route refresh is not enabled",		peer->host);      bgp_notify_send (peer,		       BGP_NOTIFY_HEADER_ERR,		       BGP_NOTIFY_HEADER_BAD_MESTYPE);      return;    }  /* Status must be Established. */  if (peer->status != Established)     {      plog_err (peer->log,		"%s [Error] Route refresh packet received under status %s",		peer->host, LOOKUP (bgp_status_msg, peer->status));      bgp_notify_send (peer, BGP_NOTIFY_FSM_ERR, 0);      return;    }  s = peer->ibuf;    /* Parse packet. */  afi = stream_getw (s);  reserved = stream_getc (s);  safi = stream_getc (s);  if (BGP_DEBUG (normal, NORMAL))    zlog_info ("%s rcvd REFRESH_REQ for afi/safi: %d/%d",	       peer->host, afi, safi);  /* Check AFI and SAFI. */  if ((afi != AFI_IP && afi != AFI_IP6)      || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST	  && safi != BGP_SAFI_VPNV4))    {      if (BGP_DEBUG (normal, NORMAL))	{	  zlog_info ("%s REFRESH_REQ for unrecognized afi/safi: %d/%d - ignored",		     peer->host, afi, safi);	}      return;    }  /* Adjust safi code. */  if (safi == BGP_SAFI_VPNV4)    safi = SAFI_MPLS_VPN;  if (size != BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE)    {      u_char *end;      u_char when_to_refresh;      u_char orf_type;      u_int16_t orf_len;      if (size - (BGP_MSG_ROUTE_REFRESH_MIN_SIZE - BGP_HEADER_SIZE) < 5)        {          zlog_info ("%s ORF route refresh length error", peer->host);          bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);          return;        }      when_to_refresh = stream_getc (s);      end = stream_pnt (s) + (size - 5);      while (stream_pnt (s) < end)	{	  orf_type = stream_getc (s); 	  orf_len = stream_getw (s);	  if (orf_type == ORF_TYPE_PREFIX	      || orf_type == ORF_TYPE_PREFIX_OLD)	    {

⌨️ 快捷键说明

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