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

📄 bgp_open.c

📁 linux 路由软件 可支持RIP OSPF BGP等
💻 C
📖 第 1 页 / 共 2 页
字号:
	    }	  restart_pnt = pnt + 4;	  restart_end = pnt + cap.length + 2;	  while (restart_pnt < restart_end)	    {	      memcpy (&graf, restart_pnt, sizeof (struct graceful_restart_af));	      afi = ntohs(graf.afi);	      safi = graf.safi;	      if (CHECK_FLAG (graf.flag, RESTART_F_BIT))		SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);	      if (strcmp (afi_safi_print (afi, safi), "Unknown") == 0)		{		   if (BGP_DEBUG (normal, NORMAL))		     zlog_info ("%s Addr-family %d/%d(afi/safi) not supported. Ignore the Graceful Restart capability",				peer->host, afi, safi);		}	      else if (! peer->afc[afi][safi])		{		   if (BGP_DEBUG (normal, NORMAL))		      zlog_info ("%s Addr-family %d/%d(afi/safi) not enabled. Ignore the Graceful Restart capability",				 peer->host, afi, safi);		}	      else		{		  if (BGP_DEBUG (normal, NORMAL))		    zlog_info ("%s Address family %s is%spreserved", peer->host,			       afi_safi_print (afi, safi),			       CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV)				 ? " " : " not ");		    SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);		}	      restart_pnt += 4;	    }	}      else if (cap.code == CAPABILITY_CODE_DYNAMIC)	{	  /* Check length. */	  if (cap.length != CAPABILITY_CODE_DYNAMIC_LEN)	    {	      zlog_info ("%s Dynamic Capability length error %d",			 peer->host, cap.length);	      bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);	      return -1;	    }	  if (BGP_DEBUG (normal, NORMAL))	    zlog_info ("%s OPEN has DYNAMIC capability", peer->host);	  SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);	}      else if (cap.code > 128)	{	  /* We don't send Notification for unknown vendor specific	     capabilities.  It seems reasonable for now...  */	  zlog_warn ("%s Vendor specific capability %d",		     peer->host, cap.code);	}      else	{	  zlog_warn ("%s unrecognized capability code: %d - ignored",		     peer->host, cap.code);	  memcpy (*error, &cap, cap.length + 2);	  *error += cap.length + 2;	}      pnt += cap.length + 2;    }  return 0;}intbgp_auth_parse (struct peer *peer, u_char *pnt, size_t length){  bgp_notify_send (peer, 		   BGP_NOTIFY_OPEN_ERR, 		   BGP_NOTIFY_OPEN_AUTH_FAILURE);   return -1;}intstrict_capability_same (struct peer *peer){  int i, j;  for (i = AFI_IP; i < AFI_MAX; i++)    for (j = SAFI_UNICAST; j < SAFI_MAX; j++)      if (peer->afc[i][j] != peer->afc_nego[i][j])	return 0;  return 1;}/* Parse open option */intbgp_open_option_parse (struct peer *peer, u_char length, int *capability){  int ret;  u_char *end;  u_char opt_type;  u_char opt_length;  u_char *pnt;  u_char *error;  u_char error_data[BGP_MAX_PACKET_SIZE];  /* Fetch pointer. */  pnt = stream_pnt (peer->ibuf);  ret = 0;  opt_type = 0;  opt_length = 0;  end = pnt + length;  error = error_data;  if (BGP_DEBUG (normal, NORMAL))    zlog_info ("%s rcv OPEN w/ OPTION parameter len: %u",	       peer->host, length);    while (pnt < end)     {      /* Check the length. */      if (pnt + 2 > end)	{	  zlog_info ("%s Option length error", peer->host);	  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);	  return -1;	}      /* Fetch option type and length. */      opt_type = *pnt++;      opt_length = *pnt++;            /* Option length check. */      if (pnt + opt_length > end)	{	  zlog_info ("%s Option length error", peer->host);	  bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);	  return -1;	}      if (BGP_DEBUG (normal, NORMAL))	zlog_info ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",		   peer->host, opt_type,		   opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :		   opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",		   opt_length);        switch (opt_type)	{	case BGP_OPEN_OPT_AUTH:	  ret = bgp_auth_parse (peer, pnt, opt_length);	  break;	case BGP_OPEN_OPT_CAP:	  ret = bgp_capability_parse (peer, pnt, opt_length, &error);	  *capability = 1;	  break;	default:	  bgp_notify_send (peer, 			   BGP_NOTIFY_OPEN_ERR, 			   BGP_NOTIFY_OPEN_UNSUP_PARAM); 	  ret = -1;	  break;	}      /* Parse error.  To accumulate all unsupported capability codes,         bgp_capability_parse does not return -1 when encounter         unsupported capability code.  To detect that, please check         error and erro_data pointer, like below.  */      if (ret < 0)	return -1;      /* Forward pointer. */      pnt += opt_length;    }  /* All OPEN option is parsed.  Check capability when strict compare     flag is enabled.*/  if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))    {      /* If Unsupported Capability exists. */      if (error != error_data)	{	  bgp_notify_send_with_data (peer, 				     BGP_NOTIFY_OPEN_ERR, 				     BGP_NOTIFY_OPEN_UNSUP_CAPBL, 				     error_data, error - error_data);	  return -1;	}      /* Check local capability does not negotiated with remote         peer. */      if (! strict_capability_same (peer))	{	  bgp_notify_send (peer, 			   BGP_NOTIFY_OPEN_ERR, 			   BGP_NOTIFY_OPEN_UNSUP_CAPBL);	  return -1;	}    }  /* Check there is no common capability send Unsupported Capability     error. */  if (*capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))    {      if (! peer->afc_nego[AFI_IP][SAFI_UNICAST] 	  && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]	  && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]	  && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]	  && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])	{	  plog_err (peer->log, "%s [Error] No common capability", peer->host);	  if (error != error_data)	    bgp_notify_send_with_data (peer, 				       BGP_NOTIFY_OPEN_ERR, 				       BGP_NOTIFY_OPEN_UNSUP_CAPBL, 				       error_data, error - error_data);	  else	    bgp_notify_send (peer, 			     BGP_NOTIFY_OPEN_ERR, 			     BGP_NOTIFY_OPEN_UNSUP_CAPBL);	  return -1;	}    }  return 0;}voidbgp_open_capability_orf (struct stream *s, struct peer *peer,                         afi_t afi, safi_t safi, u_char code){  u_char cap_len;  u_char orf_len;  unsigned long capp;  unsigned long orfp;  unsigned long numberp;  int number_of_orfs = 0;  if (safi == SAFI_MPLS_VPN)    safi = BGP_SAFI_VPNV4;  stream_putc (s, BGP_OPEN_OPT_CAP);  capp = stream_get_putp (s);           /* Set Capability Len Pointer */  stream_putc (s, 0);                   /* Capability Length */  stream_putc (s, code);                /* Capability Code */  orfp = stream_get_putp (s);           /* Set ORF Len Pointer */  stream_putc (s, 0);                   /* ORF Length */  stream_putw (s, afi);  stream_putc (s, 0);  stream_putc (s, safi);  numberp = stream_get_putp (s);        /* Set Number Pointer */  stream_putc (s, 0);                   /* Number of ORFs */  /* Address Prefix ORF */  if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)      || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))    {      stream_putc (s, (code == CAPABILITY_CODE_ORF ?		   ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));      if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)	  && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))	{	  SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);	  SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);	  stream_putc (s, ORF_MODE_BOTH);	}      else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))	{	  SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);	  stream_putc (s, ORF_MODE_SEND);	}      else	{	  SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);	  stream_putc (s, ORF_MODE_RECEIVE);	}      number_of_orfs++;    }  /* Total Number of ORFs. */  stream_putc_at (s, numberp, number_of_orfs);  /* Total ORF Len. */  orf_len = stream_get_putp (s) - orfp - 1;  stream_putc_at (s, orfp, orf_len);  /* Total Capability Len. */  cap_len = stream_get_putp (s) - capp - 1;  stream_putc_at (s, capp, cap_len);}/* Fill in capability open option to the packet. */voidbgp_open_capability (struct stream *s, struct peer *peer){  u_char len;  unsigned long cp;  afi_t afi;  safi_t safi;  /* Remember current pointer for Opt Parm Len. */  cp = stream_get_putp (s);  /* Opt Parm Len. */  stream_putc (s, 0);  /* Do not send capability. */  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)       || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))    return;  /* IPv4 unicast. */  if (peer->afc[AFI_IP][SAFI_UNICAST])    {      peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;      stream_putc (s, BGP_OPEN_OPT_CAP);      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);      stream_putc (s, CAPABILITY_CODE_MP);      stream_putc (s, CAPABILITY_CODE_MP_LEN);      stream_putw (s, AFI_IP);      stream_putc (s, 0);      stream_putc (s, SAFI_UNICAST);    }  /* IPv4 multicast. */  if (peer->afc[AFI_IP][SAFI_MULTICAST])    {      peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;      stream_putc (s, BGP_OPEN_OPT_CAP);      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);      stream_putc (s, CAPABILITY_CODE_MP);      stream_putc (s, CAPABILITY_CODE_MP_LEN);      stream_putw (s, AFI_IP);      stream_putc (s, 0);      stream_putc (s, SAFI_MULTICAST);    }  /* IPv4 VPN */  if (peer->afc[AFI_IP][SAFI_MPLS_VPN])    {      peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;      stream_putc (s, BGP_OPEN_OPT_CAP);      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);      stream_putc (s, CAPABILITY_CODE_MP);      stream_putc (s, CAPABILITY_CODE_MP_LEN);      stream_putw (s, AFI_IP);      stream_putc (s, 0);      stream_putc (s, BGP_SAFI_VPNV4);    }#ifdef HAVE_IPV6  /* IPv6 unicast. */  if (peer->afc[AFI_IP6][SAFI_UNICAST])    {      peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;      stream_putc (s, BGP_OPEN_OPT_CAP);      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);      stream_putc (s, CAPABILITY_CODE_MP);      stream_putc (s, CAPABILITY_CODE_MP_LEN);      stream_putw (s, AFI_IP6);      stream_putc (s, 0);      stream_putc (s, SAFI_UNICAST);    }  /* IPv6 multicast. */  if (peer->afc[AFI_IP6][SAFI_MULTICAST])    {      peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;      stream_putc (s, BGP_OPEN_OPT_CAP);      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);      stream_putc (s, CAPABILITY_CODE_MP);      stream_putc (s, CAPABILITY_CODE_MP_LEN);      stream_putw (s, AFI_IP6);      stream_putc (s, 0);      stream_putc (s, SAFI_MULTICAST);    }#endif /* HAVE_IPV6 */  /* Route refresh. */  SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);  stream_putc (s, BGP_OPEN_OPT_CAP);  stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);  stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);  stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);  stream_putc (s, BGP_OPEN_OPT_CAP);  stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);  stream_putc (s, CAPABILITY_CODE_REFRESH);  stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);  /* ORF capability. */  for (afi = AFI_IP ; afi < AFI_MAX ; afi++)    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)      if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)	  || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))	{	  bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);	  bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);	}  /* Dynamic capability. */  if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))    {      SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);      stream_putc (s, BGP_OPEN_OPT_CAP);      stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);      stream_putc (s, CAPABILITY_CODE_DYNAMIC);      stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);    }  /* Graceful restart capability */  if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))    {      SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);      stream_putc (s, BGP_OPEN_OPT_CAP);      stream_putc (s, CAPABILITY_CODE_RESTART_LEN + 2);      stream_putc (s, CAPABILITY_CODE_RESTART);      stream_putc (s, CAPABILITY_CODE_RESTART_LEN);      stream_putw (s, peer->bgp->restart_time);    }  /* Total Opt Parm Len. */  len = stream_get_putp (s) - cp - 1;  stream_putc_at (s, cp, len);}

⌨️ 快捷键说明

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