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

📄 bgp_zebra.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
	  }    }  return 0;}#endif /* HAVE_IPV6 */intbgp_nexthop_set (union sockunion *local, union sockunion *remote, 		 struct bgp_nexthop *nexthop, struct peer *peer){  int ret = 0;  struct interface *ifp = NULL;  memset (nexthop, 0, sizeof (struct bgp_nexthop));  if (!local)    return -1;  if (!remote)    return -1;  if (local->sa.sa_family == AF_INET)    {      nexthop->v4 = local->sin.sin_addr;      ifp = if_lookup_by_ipv4 (&local->sin.sin_addr);    }#ifdef HAVE_IPV6  if (local->sa.sa_family == AF_INET6)    {      if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))	{	  if (peer->ifname)	    ifp = if_lookup_by_index (if_nametoindex (peer->ifname));	}      else	ifp = if_lookup_by_ipv6 (&local->sin6.sin6_addr);    }#endif /* HAVE_IPV6 */  if (!ifp)    return -1;  nexthop->ifp = ifp;  /* IPv4 connection. */  if (local->sa.sa_family == AF_INET)    {#ifdef HAVE_IPV6      /* IPv6 nexthop*/      ret = if_get_ipv6_global (ifp, &nexthop->v6_global);      /* There is no global nexthop. */      if (!ret)	if_get_ipv6_local (ifp, &nexthop->v6_global);      else	if_get_ipv6_local (ifp, &nexthop->v6_local);#endif /* HAVE_IPV6 */    }#ifdef HAVE_IPV6  /* IPv6 connection. */  if (local->sa.sa_family == AF_INET6)    {      struct interface *direct = NULL;      /* IPv4 nexthop.  I don't care about it. */      if (peer->local_id.s_addr)	nexthop->v4 = peer->local_id;      /* Global address*/      if (! IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr))	{	  memcpy (&nexthop->v6_global, &local->sin6.sin6_addr, 		  IPV6_MAX_BYTELEN);	  /* If directory connected set link-local address. */	  direct = if_lookup_by_ipv6 (&remote->sin6.sin6_addr);	  if (direct)	    if_get_ipv6_local (ifp, &nexthop->v6_local);	}      else	/* Link-local address. */	{	  ret = if_get_ipv6_global (ifp, &nexthop->v6_global);	  /* If there is no global address.  Set link-local address as             global.  I know this break RFC specification... */	  if (!ret)	    memcpy (&nexthop->v6_global, &local->sin6.sin6_addr, 		    IPV6_MAX_BYTELEN);	  else	    memcpy (&nexthop->v6_local, &local->sin6.sin6_addr, 		    IPV6_MAX_BYTELEN);	}    }  if (IN6_IS_ADDR_LINKLOCAL (&local->sin6.sin6_addr) ||      if_lookup_by_ipv6 (&remote->sin6.sin6_addr))    peer->shared_network = 1;  else    peer->shared_network = 0;  /* KAME stack specific treatment.  */#ifdef KAME  if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_global)      && IN6_LINKLOCAL_IFINDEX (nexthop->v6_global))    {      SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_global, 0);    }  if (IN6_IS_ADDR_LINKLOCAL (&nexthop->v6_local)      && IN6_LINKLOCAL_IFINDEX (nexthop->v6_local))    {      SET_IN6_LINKLOCAL_IFINDEX (nexthop->v6_local, 0);    }#endif /* KAME */#endif /* HAVE_IPV6 */  return ret;}#ifdef HAVE_IPV6unsigned intbgp_ifindex_by_nexthop (struct in6_addr *addr){  listnode ifnode;  listnode cnode;  struct interface *ifp;  struct connected *connected;  struct prefix_ipv6 p;    p.family = AF_INET6;  p.prefix = *addr;  p.prefixlen = IPV6_MAX_BITLEN;  for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))    {      ifp = getdata (ifnode);      for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))	{	  struct prefix *cp; 	  connected = getdata (cnode);	  cp = connected->address;	    	  if (cp->family == AF_INET6)	    {	      if (prefix_match (cp, (struct prefix *)&p))		return ifp->ifindex;	    }	}    }  return 0;}#endif /* HAVE_IPV6 */voidbgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp){  int flags;  u_char distance;  struct peer *peer;  if (zclient->sock < 0)    return;  if (! zclient->redist[ZEBRA_ROUTE_BGP])    return;  flags = 0;  peer = info->peer;  if (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED)    {      SET_FLAG (flags, ZEBRA_FLAG_IBGP);      SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);    }  if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)      || CHECK_FLAG (peer->flags, PEER_FLAG_ENFORCE_MULTIHOP))    SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);  if (p->family == AF_INET)    {      struct zapi_ipv4 api;      struct in_addr *nexthop;      api.flags = flags;      nexthop = &info->attr->nexthop;      api.type = ZEBRA_ROUTE_BGP;      api.message = 0;      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);      api.nexthop_num = 1;      api.nexthop = &nexthop;      api.ifindex_num = 0;      SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);      api.metric = info->attr->med;      distance = bgp_distance_apply (p, info, bgp);      if (distance)	{	  SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);	  api.distance = distance;	}      zapi_ipv4_add (zclient, (struct prefix_ipv4 *) p, &api);    }#ifdef HAVE_IPV6  /* We have to think about a IPv6 link-local address curse. */  if (p->family == AF_INET6)    {      unsigned int ifindex;      struct in6_addr *nexthop;      struct zapi_ipv6 api;      ifindex = 0;      nexthop = NULL;      /* Only global address nexthop exists. */      if (info->attr->mp_nexthop_len == 16)	nexthop = &info->attr->mp_nexthop_global;            /* If both global and link-local address present. */      if (info->attr->mp_nexthop_len == 32)	{	  /* Workaround for Cisco's nexthop bug.  */	  if (IN6_IS_ADDR_UNSPECIFIED (&info->attr->mp_nexthop_global)	      && peer->su_remote->sa.sa_family == AF_INET6)	    nexthop = &peer->su_remote->sin6.sin6_addr;	  else	    nexthop = &info->attr->mp_nexthop_local;	  if (info->peer->nexthop.ifp)	    ifindex = info->peer->nexthop.ifp->ifindex;	}      if (nexthop == NULL)	return;      if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)	{	  if (info->peer->ifname)	    ifindex = if_nametoindex (info->peer->ifname);	  else if (info->peer->nexthop.ifp)	    ifindex = info->peer->nexthop.ifp->ifindex;	}      /* Make Zebra API structure. */      api.flags = flags;      api.type = ZEBRA_ROUTE_BGP;      api.message = 0;      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);      api.nexthop_num = 1;      api.nexthop = &nexthop;      SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);      api.ifindex_num = 1;      api.ifindex = &ifindex;      SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);      api.metric = info->attr->med;      zapi_ipv6_add (zclient, (struct prefix_ipv6 *) p, &api);    }#endif /* HAVE_IPV6 */}voidbgp_zebra_withdraw (struct prefix *p, struct bgp_info *info){  int flags;  struct peer *peer;  if (zclient->sock < 0)    return;  if (! zclient->redist[ZEBRA_ROUTE_BGP])    return;  peer = info->peer;  flags = 0;  if (peer_sort (peer) == BGP_PEER_IBGP)    {      SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);      SET_FLAG (flags, ZEBRA_FLAG_IBGP);    }  if ((peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)      || CHECK_FLAG (peer->flags, PEER_FLAG_ENFORCE_MULTIHOP))    SET_FLAG (flags, ZEBRA_FLAG_INTERNAL);  if (p->family == AF_INET)    {      struct zapi_ipv4 api;      struct in_addr *nexthop;      api.flags = flags;      nexthop = &info->attr->nexthop;      api.type = ZEBRA_ROUTE_BGP;      api.message = 0;      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);      api.nexthop_num = 1;      api.nexthop = &nexthop;      api.ifindex_num = 0;      SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);      api.metric = info->attr->med;      zapi_ipv4_delete (zclient, (struct prefix_ipv4 *) p, &api);    }#ifdef HAVE_IPV6  /* We have to think about a IPv6 link-local address curse. */  if (p->family == AF_INET6)    {      struct zapi_ipv6 api;      unsigned int ifindex;      struct in6_addr *nexthop;      ifindex = 0;      nexthop = NULL;      /* Only global address nexthop exists. */      if (info->attr->mp_nexthop_len == 16)	nexthop = &info->attr->mp_nexthop_global;      /* If both global and link-local address present. */      if (info->attr->mp_nexthop_len == 32)	{	  nexthop = &info->attr->mp_nexthop_local;	  if (info->peer->nexthop.ifp)	    ifindex = info->peer->nexthop.ifp->ifindex;	}      if (nexthop == NULL)	return;      if (IN6_IS_ADDR_LINKLOCAL (nexthop) && ! ifindex)	if (info->peer->ifname)	  ifindex = if_nametoindex (info->peer->ifname);      api.flags = flags;      api.type = ZEBRA_ROUTE_BGP;      api.message = 0;      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);      api.nexthop_num = 1;      api.nexthop = &nexthop;      SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);      api.ifindex_num = 1;      api.ifindex = &ifindex;      SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);      api.metric = info->attr->med;      zapi_ipv6_delete (zclient, (struct prefix_ipv6 *) p, &api);    }#endif /* HAVE_IPV6 */}/* Other routes redistribution into BGP. */intbgp_redistribute_set (struct bgp *bgp, afi_t afi, int type){  /* Set flag to BGP instance. */  bgp->redist[afi][type] = 1;  /* Return if already redistribute flag is set. */  if (zclient->redist[type])    return CMD_WARNING;  zclient->redist[type] = 1;  /* Return if zebra connection is not established. */  if (zclient->sock < 0)    return CMD_WARNING;      /* Send distribute add message to zebra. */  zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);  return CMD_SUCCESS;}/* Redistribute with route-map specification.  */intbgp_redistribute_rmap_set (struct bgp *bgp, afi_t afi, int type, char *name){  if (bgp->rmap[afi][type].name      && (strcmp (bgp->rmap[afi][type].name, name) == 0))    return 0;  if (bgp->rmap[afi][type].name)    free (bgp->rmap[afi][type].name);  bgp->rmap[afi][type].name = strdup (name);  bgp->rmap[afi][type].map = route_map_lookup_by_name (name);  return 1;}/* Redistribute with metric specification.  */intbgp_redistribute_metric_set (struct bgp *bgp, afi_t afi, int type,			     u_int32_t metric){  if (bgp->redist_metric_flag[afi][type]      && bgp->redist_metric[afi][type] == metric)    return 0;  bgp->redist_metric_flag[afi][type] = 1;  bgp->redist_metric[afi][type] = metric;  return 1;}/* Unset redistribution.  */intbgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type){  /* Unset flag from BGP instance. */  bgp->redist[afi][type] = 0;  /* Unset route-map. */  if (bgp->rmap[afi][type].name)    free (bgp->rmap[afi][type].name);  bgp->rmap[afi][type].name = NULL;  bgp->rmap[afi][type].map = NULL;  /* Unset metric. */  bgp->redist_metric_flag[afi][type] = 0;  bgp->redist_metric[afi][type] = 0;  /* Return if zebra connection is disabled. */  if (! zclient->redist[type])    return CMD_WARNING;  zclient->redist[type] = 0;  if (bgp->redist[AFI_IP][type] == 0       && bgp->redist[AFI_IP6][type] == 0       && zclient->sock >= 0)    /* Send distribute delete message to zebra. */    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);    /* Withdraw redistributed routes from current BGP's routing table. */  bgp_redistribute_withdraw (bgp, afi, type);  return CMD_SUCCESS;}/* Unset redistribution route-map configuration.  */intbgp_redistribute_routemap_unset (struct bgp *bgp, afi_t afi, int type){  if (! bgp->rmap[afi][type].name)    return 0;  /* Unset route-map. */  free (bgp->rmap[afi][type].name);  bgp->rmap[afi][type].name = NULL;  bgp->rmap[afi][type].map = NULL;  return 1;}/* Unset redistribution metric configuration.  */intbgp_redistribute_metric_unset (struct bgp *bgp, afi_t afi, int type){  if (! bgp->redist_metric_flag[afi][type])    return 0;  /* Unset metric. */  bgp->redist_metric_flag[afi][type] = 0;  bgp->redist_metric[afi][type] = 0;  return 1;}voidbgp_zclient_reset (){  zclient_reset (zclient);}voidbgp_zebra_init (int enable){  /* Set default values. */  zclient = zclient_new ();  zclient_init (zclient, ZEBRA_ROUTE_BGP);  zclient->interface_add = bgp_interface_add;  zclient->interface_delete = bgp_interface_delete;  zclient->interface_address_add = bgp_interface_address_add;  zclient->interface_address_delete = bgp_interface_address_delete;  zclient->ipv4_route_add = zebra_read_ipv4;  zclient->ipv4_route_delete = zebra_read_ipv4;  zclient->interface_up = bgp_interface_up;  zclient->interface_down = bgp_interface_down;#ifdef HAVE_IPV6  zclient->ipv6_route_add = zebra_read_ipv6;  zclient->ipv6_route_delete = zebra_read_ipv6;#endif /* HAVE_IPV6 */  /* Interface related init. */  if_init ();}

⌨️ 快捷键说明

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