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

📄 bgp_zebra.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 2 页
字号:
/* zebra client   Copyright (C) 1997, 98, 99 Kunihiro IshiguroThis file is part of GNU Zebra.GNU Zebra is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 2, or (at your option) anylater version.GNU Zebra is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Zebra; see the file COPYING.  If not, write to theFree Software Foundation, Inc., 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  */#include <zebra.h>#include "command.h"#include "stream.h"#include "network.h"#include "prefix.h"#include "log.h"#include "sockunion.h"#include "zclient.h"#include "routemap.h"#include "thread.h"#include "bgpd/bgpd.h"#include "bgpd/bgp_route.h"#include "bgpd/bgp_attr.h"#include "bgpd/bgp_nexthop.h"#include "bgpd/bgp_zebra.h"#include "bgpd/bgp_fsm.h"/* All information about zebra. */static struct zclient *zclient = NULL;/* Update default router id. */intbgp_if_update (struct interface *ifp){  struct bgp *bgp;  listnode cn;  struct listnode *nn;  struct listnode *nm;  struct peer *peer;  for (cn = listhead (ifp->connected); cn; nextnode (cn))    {      struct connected *co;      struct in_addr addr;      co = getdata (cn);      if (co->address->family == AF_INET)	{	  addr = co->address->u.prefix4;	  /* Ignore NET127. */	  if (IPV4_NET127 (ntohl (addr.s_addr)))	    continue;	  LIST_LOOP (bm->bgp, bgp, nn)	    {	      /* Respect configured router id */	      if (! (bgp->config & BGP_CONFIG_ROUTER_ID))		if (ntohl (bgp->router_id.s_addr) < ntohl (addr.s_addr))		  {		    bgp->router_id = addr;		    LIST_LOOP (bgp->peer, peer, nm)		      {			peer->local_id = addr;		      }		  }	    }	}    }  return 0;}intbgp_if_update_all (){  listnode node;  struct interface *ifp;  for (node = listhead (iflist); node; node = nextnode (node))    {      ifp = getdata (node);      bgp_if_update (ifp);    }  return 0;}/* Inteface addition message from zebra. */intbgp_interface_add (int command, struct zclient *zclient, zebra_size_t length){  struct interface *ifp;  ifp = zebra_interface_add_read (zclient->ibuf);  bgp_if_update (ifp);  return 0;}intbgp_interface_delete (int command, struct zclient *zclient,		      zebra_size_t length){  struct stream *s;  struct interface *ifp;  s = zclient->ibuf;  ifp = zebra_interface_state_read (s);  return 0;}intbgp_interface_up (int command, struct zclient *zclient, zebra_size_t length){  struct stream *s;  struct interface *ifp;  struct connected *c;  listnode node;  s = zclient->ibuf;  ifp = zebra_interface_state_read (s);  if (! ifp)    return 0;  for (node = listhead (ifp->connected); node; nextnode (node))    {      c = getdata (node);      bgp_connected_add (c);    }  return 0;}intbgp_interface_down (int command, struct zclient *zclient, zebra_size_t length){  struct stream *s;  struct interface *ifp;  struct connected *c;  listnode node;  s = zclient->ibuf;  ifp = zebra_interface_state_read (s);  if (! ifp)    return 0;  for (node = listhead (ifp->connected); node; nextnode (node))    {      c = getdata (node);      bgp_connected_delete (c);    }  /* Fast external-failover (Currently IPv4 only) */  {    struct listnode *nn, *nm;    struct bgp *bgp;    struct peer *peer;    struct interface *peer_if;    LIST_LOOP (bm->bgp, bgp, nn)      {	if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER))	  continue;	LIST_LOOP (bgp->peer, peer, nm)	  {	    if (peer->ttl != 1)	      continue;	    if (peer->su.sa.sa_family == AF_INET)	      peer_if = if_lookup_by_ipv4 (&peer->su.sin.sin_addr);	    else	      continue;	    if (ifp == peer_if)	      BGP_EVENT_ADD (peer, BGP_Stop);	  }      }  }  return 0;}intbgp_interface_address_add (int command, struct zclient *zclient,			   zebra_size_t length){  struct connected *ifc;  ifc = zebra_interface_address_add_read (zclient->ibuf);  if (ifc == NULL)    return 0;  bgp_if_update (ifc->ifp);  if (if_is_up (ifc->ifp))    bgp_connected_add (ifc);  return 0;}intbgp_interface_address_delete (int command, struct zclient *zclient,			      zebra_size_t length){  struct connected *ifc;  ifc = zebra_interface_address_delete_read (zclient->ibuf);  if (ifc == NULL)    return 0;  bgp_if_update (ifc->ifp);  if (if_is_up (ifc->ifp))    bgp_connected_delete (ifc);  connected_free (ifc);  return 0;}/* Zebra route add and delete treatment. */intzebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length){  struct stream *s;  struct zapi_ipv4 api;  unsigned long ifindex;  struct in_addr nexthop;  struct prefix_ipv4 p;  s = zclient->ibuf;  ifindex = 0;  nexthop.s_addr = 0;  /* Type, flags, message. */  api.type = stream_getc (s);  api.flags = stream_getc (s);  api.message = stream_getc (s);  /* IPv4 prefix. */  memset (&p, 0, sizeof (struct prefix_ipv4));  p.family = AF_INET;  p.prefixlen = stream_getc (s);  stream_get (&p.prefix, s, PSIZE (p.prefixlen));  /* Nexthop, ifindex, distance, metric. */  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))    {      api.nexthop_num = stream_getc (s);      nexthop.s_addr = stream_get_ipv4 (s);    }  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))    {      api.ifindex_num = stream_getc (s);      ifindex = stream_getl (s);    }  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))    api.distance = stream_getc (s);  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))    api.metric = stream_getl (s);  else    api.metric = 0;  if (command == ZEBRA_IPV4_ROUTE_ADD)    bgp_redistribute_add ((struct prefix *)&p, &nexthop, api.metric, api.type);  else    bgp_redistribute_delete ((struct prefix *)&p, api.type);  return 0;}#ifdef HAVE_IPV6/* Zebra route add and delete treatment. */intzebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length){  struct stream *s;  struct zapi_ipv6 api;  unsigned long ifindex;  struct in6_addr nexthop;  struct prefix_ipv6 p;  s = zclient->ibuf;  ifindex = 0;  memset (&nexthop, 0, sizeof (struct in6_addr));  /* Type, flags, message. */  api.type = stream_getc (s);  api.flags = stream_getc (s);  api.message = stream_getc (s);  /* IPv6 prefix. */  memset (&p, 0, sizeof (struct prefix_ipv6));  p.family = AF_INET6;  p.prefixlen = stream_getc (s);  stream_get (&p.prefix, s, PSIZE (p.prefixlen));  /* Nexthop, ifindex, distance, metric. */  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))    {      api.nexthop_num = stream_getc (s);      stream_get (&nexthop, s, 16);    }  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))    {      api.ifindex_num = stream_getc (s);      ifindex = stream_getl (s);    }  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))    api.distance = stream_getc (s);  else    api.distance = 0;  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))    api.metric = stream_getl (s);  else    api.metric = 0;  /* Simply ignore link-local address. */  if (IN6_IS_ADDR_LINKLOCAL (&p.prefix))    return 0;  if (command == ZEBRA_IPV6_ROUTE_ADD)    bgp_redistribute_add ((struct prefix *)&p, NULL, api.metric, api.type);  else    bgp_redistribute_delete ((struct prefix *) &p, api.type);    return 0;}#endif /* HAVE_IPV6 */struct interface *if_lookup_by_ipv4 (struct in_addr *addr){  listnode ifnode;  listnode cnode;  struct interface *ifp;  struct connected *connected;  struct prefix_ipv4 p;  struct prefix *cp;     p.family = AF_INET;  p.prefix = *addr;  p.prefixlen = IPV4_MAX_BITLEN;  for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))    {      ifp = getdata (ifnode);      for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))	{	  connected = getdata (cnode);	  cp = connected->address;	    	  if (cp->family == AF_INET)	    if (prefix_match (cp, (struct prefix *)&p))	      return ifp;	}    }  return NULL;}struct interface *if_lookup_by_ipv4_exact (struct in_addr *addr){  listnode ifnode;  listnode cnode;  struct interface *ifp;  struct connected *connected;  struct prefix *cp;     for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))    {      ifp = getdata (ifnode);      for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))	{	  connected = getdata (cnode);	  cp = connected->address;	    	  if (cp->family == AF_INET)	    if (IPV4_ADDR_SAME (&cp->u.prefix4, addr))	      return ifp;	}    }  return NULL;}#ifdef HAVE_IPV6struct interface *if_lookup_by_ipv6 (struct in6_addr *addr){  listnode ifnode;  listnode cnode;  struct interface *ifp;  struct connected *connected;  struct prefix_ipv6 p;  struct prefix *cp;     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))	{	  connected = getdata (cnode);	  cp = connected->address;	    	  if (cp->family == AF_INET6)	    if (prefix_match (cp, (struct prefix *)&p))	      return ifp;	}    }  return NULL;}struct interface *if_lookup_by_ipv6_exact (struct in6_addr *addr){  listnode ifnode;  listnode cnode;  struct interface *ifp;  struct connected *connected;  struct prefix *cp;   for (ifnode = listhead (iflist); ifnode; nextnode (ifnode))    {      ifp = getdata (ifnode);      for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))	{	  connected = getdata (cnode);	  cp = connected->address;	    	  if (cp->family == AF_INET6)	    if (IPV6_ADDR_SAME (&cp->u.prefix6, addr))	      return ifp;	}    }  return NULL;}intif_get_ipv6_global (struct interface *ifp, struct in6_addr *addr){  listnode cnode;  struct connected *connected;  struct prefix *cp;     for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))    {      connected = getdata (cnode);      cp = connected->address;	          if (cp->family == AF_INET6)	if (! IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))	  {	    memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);	    return 1;	  }    }  return 0;}intif_get_ipv6_local (struct interface *ifp, struct in6_addr *addr){  listnode cnode;  struct connected *connected;  struct prefix *cp;     for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))    {      connected = getdata (cnode);      cp = connected->address;	          if (cp->family == AF_INET6)	if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))	  {	    memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);	    return 1;

⌨️ 快捷键说明

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