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

📄 bgp_nexthop.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 3 页
字号:
		valid = bgp_nexthop_check_ebgp (AFI_IP, bi->attr);	      else		valid = bgp_nexthop_lookup (AFI_IP, bi->peer, bi,					    &changed, &metricchanged);	      current = CHECK_FLAG (bi->flags, BGP_INFO_VALID) ? 1 : 0;	      if (changed)		SET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);	      else		UNSET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);	      if (valid != current)		{		  if (CHECK_FLAG (bi->flags, BGP_INFO_VALID))		    {		      bgp_aggregate_decrement (bgp, &rn->p, bi,					       AFI_IP, SAFI_UNICAST);		      UNSET_FLAG (bi->flags, BGP_INFO_VALID);		    }		  else		    {		      SET_FLAG (bi->flags, BGP_INFO_VALID);		      bgp_aggregate_increment (bgp, &rn->p, bi,					       AFI_IP, SAFI_UNICAST);		    }		}              if (CHECK_FLAG (bgp->af_flags[AFI_IP][SAFI_UNICAST],		  BGP_CONFIG_DAMPENING)                  &&  bi->damp_info )                if (bgp_damp_scan (bi, AFI_IP, SAFI_UNICAST))		  bgp_aggregate_increment (bgp, &rn->p, bi,					   AFI_IP, SAFI_UNICAST);	    }	}      bgp_process (bgp, rn, AFI_IP, SAFI_UNICAST);    }  /* Flash old cache. */  if (bgp_nexthop_cache_ipv4 == cache1)    bgp_nexthop_cache_reset (cache2);  else    bgp_nexthop_cache_reset (cache1);}#ifdef HAVE_IPV6voidbgp_scan_ipv6 (){  struct bgp_node *rn;  struct bgp *bgp;  struct bgp_info *bi;  struct bgp_info *next;  struct peer *peer;  struct listnode *nn;  int valid;  int current;  int changed;  int metricchanged;  /* Change cache. */  if (bgp_nexthop_cache_ipv6 == cache6_1)    bgp_nexthop_cache_ipv6 = cache6_2;  else    bgp_nexthop_cache_ipv6 = cache6_1;  /* Get default bgp. */  bgp = bgp_get_default ();  if (bgp == NULL)    return;  /* Maximum prefix check */  LIST_LOOP (bgp->peer, peer, nn)    {      if (peer->status != Established)	continue;      if (peer->afc[AFI_IP6][SAFI_UNICAST])	bgp_maximum_prefix_overflow (peer, AFI_IP6, SAFI_UNICAST, 1);      if (peer->afc[AFI_IP6][SAFI_MULTICAST])	bgp_maximum_prefix_overflow (peer, AFI_IP6, SAFI_MULTICAST, 1);    }  for (rn = bgp_table_top (bgp->rib[AFI_IP6][SAFI_UNICAST]); rn;       rn = bgp_route_next (rn))    {      for (bi = rn->info; bi; bi = next)	{	  next = bi->next;	  if (bi->type == ZEBRA_ROUTE_BGP && bi->sub_type == BGP_ROUTE_NORMAL)	    {	      changed = 0;	      metricchanged = 0;	      if (peer_sort (bi->peer) == BGP_PEER_EBGP && bi->peer->ttl == 1)		valid = 1;	      else		valid = bgp_nexthop_lookup_ipv6 (bi->peer, bi,						 &changed, &metricchanged);	      current = CHECK_FLAG (bi->flags, BGP_INFO_VALID) ? 1 : 0;	      if (changed)		SET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);	      else		UNSET_FLAG (bi->flags, BGP_INFO_IGP_CHANGED);	      if (valid != current)		{		  if (CHECK_FLAG (bi->flags, BGP_INFO_VALID))		    {		      bgp_aggregate_decrement (bgp, &rn->p, bi,					       AFI_IP6, SAFI_UNICAST);		      UNSET_FLAG (bi->flags, BGP_INFO_VALID);		    }		  else		    {		      SET_FLAG (bi->flags, BGP_INFO_VALID);		      bgp_aggregate_increment (bgp, &rn->p, bi,					       AFI_IP6, SAFI_UNICAST);		    }		}              if (CHECK_FLAG (bgp->af_flags[AFI_IP6][SAFI_UNICAST],		  BGP_CONFIG_DAMPENING)                  &&  bi->damp_info )                if (bgp_damp_scan (bi, AFI_IP6, SAFI_UNICAST))		  bgp_aggregate_increment (bgp, &rn->p, bi,					   AFI_IP6, SAFI_UNICAST);	    }	}      bgp_process (bgp, rn, AFI_IP6, SAFI_UNICAST);    }  /* Flash old cache. */  if (bgp_nexthop_cache_ipv6 == cache6_1)    bgp_nexthop_cache_reset (cache6_2);  else    bgp_nexthop_cache_reset (cache6_1);}#endif /* HAVE_IPV6 *//* BGP scan thread.  This thread check nexthop reachability. */intbgp_scan (struct thread *t){  bgp_scan_thread =    thread_add_timer (master, bgp_scan, NULL, bgp_scan_interval);  if (BGP_DEBUG (normal, NORMAL))    zlog_info ("Performing BGP general scanning");  bgp_scan_ipv4 ();#ifdef HAVE_IPV6  bgp_scan_ipv6 ();#endif /* HAVE_IPV6 */  return 0;}struct bgp_connected{  unsigned int refcnt;};voidbgp_connected_add (struct connected *ifc){  struct prefix p;  struct prefix *addr;  struct prefix *dest;  struct interface *ifp;  struct bgp_node *rn;  struct bgp_connected *bc;  ifp = ifc->ifp;  if (! ifp)    return;  if (if_is_loopback (ifp))    return;  addr = ifc->address;  dest = ifc->destination;  if (addr->family == AF_INET)    {      memset (&p, 0, sizeof (struct prefix));      p.family = AF_INET;      p.prefixlen = addr->prefixlen;      if (if_is_pointopoint (ifp))	p.u.prefix4 = dest->u.prefix4;      else	p.u.prefix4 = addr->u.prefix4;      apply_mask_ipv4 ((struct prefix_ipv4 *) &p);      if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))	return;      rn = bgp_node_get (bgp_connected_ipv4, (struct prefix *) &p);      if (rn->info)	{	  bc = rn->info;	  bc->refcnt++;	}      else	{	  bc = XMALLOC (0, sizeof (struct bgp_connected));	  memset (bc, 0, sizeof (struct bgp_connected));	  bc->refcnt = 1;	  rn->info = bc;	}    }#ifdef HAVE_IPV6  if (addr->family == AF_INET6)    {      memset (&p, 0, sizeof (struct prefix));      p.family = AF_INET6;      p.prefixlen = addr->prefixlen;      if (if_is_pointopoint (ifp))	p.u.prefix6 = dest->u.prefix6;      else	p.u.prefix6 = addr->u.prefix6;      apply_mask_ipv6 ((struct prefix_ipv6 *) &p);      if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))	return;      if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))	return;      rn = bgp_node_get (bgp_connected_ipv6, (struct prefix *) &p);      if (rn->info)	{	  bc = rn->info;	  bc->refcnt++;	}      else	{	  bc = XMALLOC (0, sizeof (struct bgp_connected));	  memset (bc, 0, sizeof (struct bgp_connected));	  bc->refcnt = 1;	  rn->info = bc;	}    }#endif /* HAVE_IPV6 */}voidbgp_connected_delete (struct connected *ifc){  struct prefix p;  struct prefix *addr;  struct prefix *dest;  struct interface *ifp;  struct bgp_node *rn;  struct bgp_connected *bc;  ifp = ifc->ifp;  if (if_is_loopback (ifp))    return;  addr = ifc->address;  dest = ifc->destination;  if (addr->family == AF_INET)    {      memset (&p, 0, sizeof (struct prefix));      p.family = AF_INET;      p.prefixlen = addr->prefixlen;      if (if_is_pointopoint (ifp))	p.u.prefix4 = dest->u.prefix4;      else	p.u.prefix4 = addr->u.prefix4;      apply_mask_ipv4 ((struct prefix_ipv4 *) &p);      if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))	return;      rn = bgp_node_lookup (bgp_connected_ipv4, &p);      if (! rn)	return;      bc = rn->info;      bc->refcnt--;      if (bc->refcnt == 0)	{	  XFREE (0, bc);	  rn->info = NULL;	}      bgp_unlock_node (rn);      bgp_unlock_node (rn);    }#ifdef HAVE_IPV6  else if (addr->family == AF_INET6)    {      memset (&p, 0, sizeof (struct prefix));      p.family = AF_INET6;      p.prefixlen = addr->prefixlen;      if (if_is_pointopoint (ifp))	p.u.prefix6 = dest->u.prefix6;      else	p.u.prefix6 = addr->u.prefix6;      apply_mask_ipv6 ((struct prefix_ipv6 *) &p);      if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))	return;      if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))	return;      rn = bgp_node_lookup (bgp_connected_ipv6, (struct prefix *) &p);      if (! rn)	return;      bc = rn->info;      bc->refcnt--;      if (bc->refcnt == 0)	{	  XFREE (0, bc);	  rn->info = NULL;	}      bgp_unlock_node (rn);      bgp_unlock_node (rn);    }#endif /* HAVE_IPV6 */}intbgp_nexthop_self (afi_t afi, struct attr *attr){  listnode node;  listnode node2;  struct interface *ifp;  struct connected *ifc;  struct prefix *p;  for (node = listhead (iflist); node; nextnode (node))    {      ifp = getdata (node);      for (node2 = listhead (ifp->connected); node2; nextnode (node2))	{	  ifc = getdata (node2);	  p = ifc->address;	  if (p && p->family == AF_INET 	      && IPV4_ADDR_SAME (&p->u.prefix4, &attr->nexthop))	    return 1;	}    }  return 0;}struct bgp_nexthop_cache *zlookup_read (){  struct stream *s;  u_int16_t length;  u_char command;  int nbytes;  struct in_addr raddr;  u_int32_t metric;  int i;  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);  raddr.s_addr = stream_get_ipv4 (s);  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_IPV4:	      nexthop->gate.ipv4.s_addr = stream_get_ipv4 (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 (struct in_addr addr){  int ret;  struct stream *s;  /* Check socket. */  if (zlookup->sock < 0)    return NULL;  s = zlookup->obuf;  stream_reset (s);  stream_putw (s, 7);  stream_putc (s, ZEBRA_IPV4_NEXTHOP_LOOKUP);  stream_put_in_addr (s, &addr);  ret = writen (zlookup->sock, s->data, 7);  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 ();}#ifdef HAVE_IPV6struct bgp_nexthop_cache *zlookup_read_ipv6 (){  struct stream *s;  u_int16_t length;  u_char command;  int nbytes;  struct in6_addr raddr;  u_int32_t metric;  int i;

⌨️ 快捷键说明

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