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

📄 bgp_nexthop.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 3 页
字号:
  u_char nexthop_num;  struct nexthop *nexthop;  struct bgp_nexthop_cache *bnc;  s = zlookup->ibuf;  stream_reset (s);  nbytes = stream_read (s, zlookup->sock, 2);  length = stream_getw (s);  nbytes = stream_read (s, zlookup->sock, length - 2);  command = stream_getc (s);  stream_get (&raddr, s, 16);  metric = stream_getl (s);  nexthop_num = stream_getc (s);  if (nexthop_num)    {      bnc = bnc_new ();      bnc->valid = 1;      bnc->metric = metric;      bnc->nexthop_num = nexthop_num;      for (i = 0; i < nexthop_num; i++)	{	  nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));	  memset (nexthop, 0, sizeof (struct nexthop));	  nexthop->type = stream_getc (s);	  switch (nexthop->type)	    {	    case ZEBRA_NEXTHOP_IPV6:	      stream_get (&nexthop->gate.ipv6, s, 16);	      break;	    case ZEBRA_NEXTHOP_IPV6_IFINDEX:	    case ZEBRA_NEXTHOP_IPV6_IFNAME:	      stream_get (&nexthop->gate.ipv6, s, 16);	      nexthop->ifindex = stream_getl (s);	      break;	    case ZEBRA_NEXTHOP_IFINDEX:	    case ZEBRA_NEXTHOP_IFNAME:	      nexthop->ifindex = stream_getl (s);	      break;	    }	  bnc_nexthop_add (bnc, nexthop);	}    }  else    return NULL;  return bnc;}struct bgp_nexthop_cache *zlookup_query_ipv6 (struct in6_addr *addr){  int ret;  struct stream *s;  /* Check socket. */  if (zlookup->sock < 0)    return NULL;  s = zlookup->obuf;  stream_reset (s);  stream_putw (s, 19);  stream_putc (s, ZEBRA_IPV6_NEXTHOP_LOOKUP);  stream_put (s, addr, 16);  ret = writen (zlookup->sock, s->data, 19);  if (ret < 0)    {      zlog_err ("can't write to zlookup->sock");      close (zlookup->sock);      zlookup->sock = -1;      return NULL;    }  if (ret == 0)    {      zlog_err ("zlookup->sock connection closed");      close (zlookup->sock);      zlookup->sock = -1;      return NULL;    }  return zlookup_read_ipv6 ();}#endif /* HAVE_IPV6 */intbgp_import_check (struct prefix *p, u_int32_t *igpmetric, struct in_addr *igpnexthop){  struct stream *s;  int ret;  u_int16_t length;  u_char command;  int nbytes;  struct in_addr addr;  struct in_addr nexthop;  u_int32_t metric = 0;  u_char nexthop_num;  u_char nexthop_type;  /* If lookup connection is not available return valid. */  if (zlookup->sock < 0)    {      if (igpmetric)	*igpmetric = 0;      return 1;    }  /* Send query to the lookup connection */  s = zlookup->obuf;  stream_reset (s);  stream_putw (s, 8);  stream_putc (s, ZEBRA_IPV4_IMPORT_LOOKUP);  stream_putc (s, p->prefixlen);  stream_put_in_addr (s, &p->u.prefix4);  /* Write the packet. */  ret = writen (zlookup->sock, s->data, 8);  if (ret < 0)    {      zlog_err ("can't write to zlookup->sock");      close (zlookup->sock);      zlookup->sock = -1;      return 1;    }  if (ret == 0)    {      zlog_err ("zlookup->sock connection closed");      close (zlookup->sock);      zlookup->sock = -1;      return 1;    }  /* Get result. */  stream_reset (s);  /* Fetch length. */  nbytes = stream_read (s, zlookup->sock, 2);  length = stream_getw (s);  /* Fetch whole data. */  nbytes = stream_read (s, zlookup->sock, length - 2);  command = stream_getc (s);  addr.s_addr = stream_get_ipv4 (s);  metric = stream_getl (s);  nexthop_num = stream_getc (s);  /* Set IGP metric value. */  if (igpmetric)    *igpmetric = metric;  /* If there is nexthop then this is active route. */  if (nexthop_num)    {      nexthop.s_addr = 0;      nexthop_type = stream_getc (s);      if (nexthop_type == ZEBRA_NEXTHOP_IPV4)	{	  nexthop.s_addr = stream_get_ipv4 (s);	  if (igpnexthop)	    *igpnexthop = nexthop;	}      else	*igpnexthop = nexthop;      return 1;    }  else    return 0;}/* Scan all configured BGP route then check the route exists in IGP or   not. */intbgp_import (struct thread *t){  struct bgp_master *bm;  struct bgp *bgp;  struct bgp_node *rn;  struct bgp_static *bgp_static;  struct listnode *nn;  int valid;  u_int32_t metric;  struct in_addr nexthop;  afi_t afi;  safi_t safi;  bgp_import_thread =     thread_add_timer (master, bgp_import, NULL, bgp_import_interval);  bm = bgp_get_master ();  if (! bm)    return 0;  LIST_LOOP (bm->bgp, bgp, nn)    {      for (afi = AFI_IP; afi < AFI_MAX; afi++)	for (safi = SAFI_UNICAST; safi < SAFI_MPLS_VPN; safi++)	  for (rn = bgp_table_top (bgp->route[afi][safi]); rn;	       rn = bgp_route_next (rn))	    if ((bgp_static = rn->info) != NULL)	      {		if (bgp_static->backdoor)		  continue;		valid = bgp_static->valid;		metric = bgp_static->igpmetric;		nexthop = bgp_static->igpnexthop;		if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK)		    && afi == AFI_IP && safi == SAFI_UNICAST)		  bgp_static->valid = bgp_import_check (&rn->p, &bgp_static->igpmetric,						        &bgp_static->igpnexthop);		else		  {		    bgp_static->valid = 1;		    bgp_static->igpmetric = 0;		    bgp_static->igpnexthop.s_addr = 0;		  }		if (bgp_static->valid != valid)		  {		    if (bgp_static->valid)		      bgp_static_update (bgp, &rn->p, bgp_static, afi, safi);		    else		      bgp_static_withdraw (bgp, &rn->p, afi, safi);		  }		else if (bgp_static->valid)		  {		    if (bgp_static->igpmetric != metric			|| bgp_static->igpnexthop.s_addr != nexthop.s_addr			|| bgp_static->rmap.name)		      bgp_static_update (bgp, &rn->p, bgp_static, afi, safi);		  }	      }    }  return 0;}/* Connect to zebra for nexthop lookup. */intzlookup_connect (struct thread *t){  struct zclient *zlookup;  zlookup = THREAD_ARG (t);  zlookup->t_connect = NULL;  if (zlookup->sock != -1)    return 0;#ifdef HAVE_TCP_ZEBRA  zlookup->sock = zclient_socket ();#else  zlookup->sock = zclient_socket_un (ZEBRA_SERV_PATH);#endif /* HAVE_TCP_ZEBRA */  if (zlookup->sock < 0)    return -1;  return 0;}/* Check specified multiaccess next-hop. */intbgp_multiaccess_check_v4 (struct in_addr nexthop, char *peer){  struct bgp_node *rn1;  struct bgp_node *rn2;  struct prefix p1;  struct prefix p2;  struct in_addr addr;  int ret;  ret = inet_aton (peer, &addr);  if (! ret)    return 0;  memset (&p1, 0, sizeof (struct prefix));  p1.family = AF_INET;  p1.prefixlen = IPV4_MAX_BITLEN;  p1.u.prefix4 = nexthop;  memset (&p2, 0, sizeof (struct prefix));  p2.family = AF_INET;  p2.prefixlen = IPV4_MAX_BITLEN;  p2.u.prefix4 = addr;  /* If bgp scan is not enabled, return invalid. */  if (zlookup->sock < 0)    return 0;  rn1 = bgp_node_match (bgp_connected_ipv4, &p1);  if (! rn1)    return 0;    rn2 = bgp_node_match (bgp_connected_ipv4, &p2);  if (! rn2)    return 0;  if (rn1 == rn2)    return 1;  return 0;}DEFUN (bgp_scan_time,       bgp_scan_time_cmd,       "bgp scan-time <5-60>",       "BGP specific commands\n"       "Configure background scanner interval\n"       "Scanner interval (seconds)\n"){  bgp_scan_interval = atoi (argv[0]);  if (bgp_scan_thread)    {      thread_cancel (bgp_scan_thread);      bgp_scan_thread = 	thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);    }  return CMD_SUCCESS;}DEFUN (no_bgp_scan_time,       no_bgp_scan_time_cmd,       "no bgp scan-time",       NO_STR       "BGP specific commands\n"       "Configure background scanner interval\n"){  bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT;  if (bgp_scan_thread)    {      thread_cancel (bgp_scan_thread);      bgp_scan_thread = 	thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);    }  return CMD_SUCCESS;}ALIAS (no_bgp_scan_time,       no_bgp_scan_time_val_cmd,       "no bgp scan-time <5-60>",       NO_STR       "BGP specific commands\n"       "Configure background scanner interval\n"       "Scanner interval (seconds)\n");DEFUN (show_ip_bgp_scan,       show_ip_bgp_scan_cmd,       "show ip bgp scan",       SHOW_STR       IP_STR       BGP_STR       "BGP scan status\n"){  struct bgp_node *rn;  struct bgp_nexthop_cache *bnc;  if (bgp_scan_thread)    vty_out (vty, "BGP scan is running%s", VTY_NEWLINE);  else    vty_out (vty, "BGP scan is not running%s", VTY_NEWLINE);  vty_out (vty, "BGP scan interval is %d%s", bgp_scan_interval, VTY_NEWLINE);  vty_out (vty, "Current BGP nexthop cache:%s", VTY_NEWLINE);  for (rn = bgp_table_top (bgp_nexthop_cache_ipv4); rn; rn = bgp_route_next (rn))    if ((bnc = rn->info) != NULL)      {	if (bnc->valid)	  vty_out (vty, " %s valid [IGP metric %d]%s",		   inet_ntoa (rn->p.u.prefix4), bnc->metric, VTY_NEWLINE);	else	  vty_out (vty, " %s invalid%s",		   inet_ntoa (rn->p.u.prefix4), VTY_NEWLINE);      }#ifdef HAVE_IPV6  {    char buf[BUFSIZ];    for (rn = bgp_table_top (bgp_nexthop_cache_ipv6); rn; rn = bgp_route_next (rn))      if ((bnc = rn->info) != NULL)	{	  if (bnc->valid)	    vty_out (vty, " %s valid [IGP metric %d]%s",		     inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),		     bnc->metric, VTY_NEWLINE);	  else	    vty_out (vty, " %s invalid%s",		     inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),		     VTY_NEWLINE);	}  }#endif /* HAVE_IPV6 */  vty_out (vty, "BGP connected route:%s", VTY_NEWLINE);  for (rn = bgp_table_top (bgp_connected_ipv4); rn; rn = bgp_route_next (rn))    if (rn->info != NULL)      vty_out (vty, " %s/%d%s", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,	       VTY_NEWLINE);#ifdef HAVE_IPV6  {    char buf[BUFSIZ];    for (rn = bgp_table_top (bgp_connected_ipv6); rn; rn = bgp_route_next (rn))      if (rn->info != NULL)	vty_out (vty, " %s/%d%s",		 inet_ntop (AF_INET6, &rn->p.u.prefix6, buf, BUFSIZ),		 rn->p.prefixlen,		 VTY_NEWLINE);  }#endif /* HAVE_IPV6 */  return CMD_SUCCESS;}intbgp_config_write_scan_time (struct vty *vty){  if (bgp_scan_interval != BGP_SCAN_INTERVAL_DEFAULT)    vty_out (vty, " bgp scan-time %d%s", bgp_scan_interval, VTY_NEWLINE);  return CMD_SUCCESS;}voidbgp_scan_init (){  zlookup = zclient_new ();  zlookup->sock = -1;  zlookup->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ);  zlookup->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ);  zlookup->t_connect = thread_add_event (master, zlookup_connect, zlookup, 0);  bgp_scan_interval = BGP_SCAN_INTERVAL_DEFAULT;  bgp_import_interval = BGP_IMPORT_INTERVAL_DEFAULT;  cache1 = bgp_table_init ();  cache2 = bgp_table_init ();  bgp_nexthop_cache_ipv4 = cache1;  bgp_connected_ipv4 = bgp_table_init ();#ifdef HAVE_IPV6  cache6_1 = bgp_table_init ();  cache6_2 = bgp_table_init ();  bgp_nexthop_cache_ipv6 = cache6_1;  bgp_connected_ipv6 = bgp_table_init ();#endif /* HAVE_IPV6 */  /* Make BGP scan thread. */  bgp_scan_thread = thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);  /* Make BGP import there. */  bgp_import_thread = thread_add_timer (master, bgp_import, NULL, 0);  install_element (BGP_NODE, &bgp_scan_time_cmd);  install_element (BGP_NODE, &no_bgp_scan_time_cmd);  install_element (BGP_NODE, &no_bgp_scan_time_val_cmd);  install_element (VIEW_NODE, &show_ip_bgp_scan_cmd);  install_element (ENABLE_NODE, &show_ip_bgp_scan_cmd);}

⌨️ 快捷键说明

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