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

📄 zebra_rib.c

📁 zebra测试源代码用于 SOCKET 通信
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Routing Information Base. * Copyright (C) 1997, 98, 99, 2001 Kunihiro Ishiguro * * This file is part of GNU Zebra. * * GNU Zebra is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * GNU Zebra is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Zebra; see the file COPYING.  If not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA.   */#include <zebra.h>#include "prefix.h"#include "table.h"#include "memory.h"#include "str.h"#include "command.h"#include "if.h"#include "log.h"#include "sockunion.h"#include "zebra/rib.h"#include "zebra/rt.h"#include "zebra/zserv.h"#include "zebra/redistribute.h"#include "zebra/debug.h"/* Default rtm_table for all clients */extern int rtm_table_default;/* Each route type's string and default distance value. */struct{    int key;  int distance;} route_info[] ={  {ZEBRA_ROUTE_SYSTEM,    0},  {ZEBRA_ROUTE_KERNEL,    0},  {ZEBRA_ROUTE_CONNECT,   0},  {ZEBRA_ROUTE_STATIC,    1},  {ZEBRA_ROUTE_RIP,     120},  {ZEBRA_ROUTE_RIPNG,   120},  {ZEBRA_ROUTE_OSPF,    110},  {ZEBRA_ROUTE_OSPF6,   110},  {ZEBRA_ROUTE_BGP,      20  /* IBGP is 200. */}};/* Vector for routing table.  */vector vrf_vector;/* Allocate new VRF.  */struct vrf *vrf_alloc (char *name){  struct vrf *vrf;  vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));  /* Put name.  */  if (name)    vrf->name = XSTRDUP (MTYPE_VRF_NAME, name);  /* Allocate routing table and static table.  */  vrf->table[AFI_IP][SAFI_UNICAST] = route_table_init ();  vrf->table[AFI_IP6][SAFI_UNICAST] = route_table_init ();  vrf->stable[AFI_IP][SAFI_UNICAST] = route_table_init ();  vrf->stable[AFI_IP6][SAFI_UNICAST] = route_table_init ();  return vrf;}/* Free VRF.  */voidvrf_free (struct vrf *vrf){  if (vrf->name)    XFREE (MTYPE_VRF_NAME, vrf->name);  XFREE (MTYPE_VRF, vrf);}/* Lookup VRF by identifier.  */struct vrf *vrf_lookup (u_int32_t id){  return vector_lookup (vrf_vector, id);}/* Lookup VRF by name.  */struct vrf *vrf_lookup_by_name (char *name){  int i;  struct vrf *vrf;  for (i = 0; i < vector_max (vrf_vector); i++)    if ((vrf = vector_slot (vrf_vector, i)) != NULL)      if (vrf->name && name && strcmp (vrf->name, name) == 0)	return vrf;  return NULL;}/* Initialize VRF.  */voidvrf_init (){  struct vrf *default_table;  /* Allocate VRF vector.  */  vrf_vector = vector_init (1);  /* Allocate default main table.  */  default_table = vrf_alloc ("Default-IP-Routing-Table");  /* Default table index must be 0.  */  vector_set_index (vrf_vector, 0, default_table);}/* Lookup route table.  */struct route_table *vrf_table (afi_t afi, safi_t safi, u_int32_t id){  struct vrf *vrf;  vrf = vrf_lookup (id);  if (! vrf)    return NULL;  return vrf->table[afi][safi];}/* Lookup static route table.  */struct route_table *vrf_static_table (afi_t afi, safi_t safi, u_int32_t id){  struct vrf *vrf;  vrf = vrf_lookup (id);  if (! vrf)    return NULL;  return vrf->stable[afi][safi];}/* Add nexthop to the end of the list.  */voidnexthop_add (struct rib *rib, struct nexthop *nexthop){  struct nexthop *last;  for (last = rib->nexthop; last && last->next; last = last->next)    ;  if (last)    last->next = nexthop;  else    rib->nexthop = nexthop;  nexthop->prev = last;  rib->nexthop_num++;}/* Delete specified nexthop from the list. */voidnexthop_delete (struct rib *rib, struct nexthop *nexthop){  if (nexthop->next)    nexthop->next->prev = nexthop->prev;  if (nexthop->prev)    nexthop->prev->next = nexthop->next;  else    rib->nexthop = nexthop->next;  rib->nexthop_num--;}/* Free nexthop. */voidnexthop_free (struct nexthop *nexthop){  if (nexthop->type == NEXTHOP_TYPE_IFNAME && nexthop->ifname)    free (nexthop->ifname);  XFREE (MTYPE_NEXTHOP, nexthop);}struct nexthop *nexthop_ifindex_add (struct rib *rib, unsigned int ifindex){  struct nexthop *nexthop;  nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));  memset (nexthop, 0, sizeof (struct nexthop));  nexthop->type = NEXTHOP_TYPE_IFINDEX;  nexthop->ifindex = ifindex;  nexthop_add (rib, nexthop);  return nexthop;}struct nexthop *nexthop_ifname_add (struct rib *rib, char *ifname){  struct nexthop *nexthop;  nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));  memset (nexthop, 0, sizeof (struct nexthop));  nexthop->type = NEXTHOP_TYPE_IFNAME;  nexthop->ifname = strdup (ifname);  nexthop_add (rib, nexthop);  return nexthop;}struct nexthop *nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4){  struct nexthop *nexthop;  nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));  memset (nexthop, 0, sizeof (struct nexthop));  nexthop->type = NEXTHOP_TYPE_IPV4;  nexthop->gate.ipv4 = *ipv4;  nexthop_add (rib, nexthop);  return nexthop;}struct nexthop *nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4, 			  unsigned int ifindex){  struct nexthop *nexthop;  nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));  memset (nexthop, 0, sizeof (struct nexthop));  nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;  nexthop->gate.ipv4 = *ipv4;  nexthop->ifindex = ifindex;  nexthop_add (rib, nexthop);  return nexthop;}#ifdef HAVE_IPV6struct nexthop *nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6){  struct nexthop *nexthop;  nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));  memset (nexthop, 0, sizeof (struct nexthop));  nexthop->type = NEXTHOP_TYPE_IPV6;  nexthop->gate.ipv6 = *ipv6;  nexthop_add (rib, nexthop);  return nexthop;}struct nexthop *nexthop_ipv6_ifname_add (struct rib *rib, struct in6_addr *ipv6,			 char *ifname){  struct nexthop *nexthop;  nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));  memset (nexthop, 0, sizeof (struct nexthop));  nexthop->type = NEXTHOP_TYPE_IPV6_IFNAME;  nexthop->gate.ipv6 = *ipv6;  nexthop->ifname = XSTRDUP (0, ifname);  nexthop_add (rib, nexthop);  return nexthop;}struct nexthop *nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6,			  unsigned int ifindex){  struct nexthop *nexthop;  nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));  memset (nexthop, 0, sizeof (struct nexthop));  nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;  nexthop->gate.ipv6 = *ipv6;  nexthop->ifindex = ifindex;  nexthop_add (rib, nexthop);  return nexthop;}#endif /* HAVE_IPV6 */struct nexthop *nexthop_blackhole_add (struct rib *rib){  struct nexthop *nexthop;  nexthop = XMALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop));  memset (nexthop, 0, sizeof (struct nexthop));  nexthop->type = NEXTHOP_TYPE_BLACKHOLE;  SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE);  nexthop_add (rib, nexthop);  return nexthop;}/* If force flag is not set, do not modify falgs at all for uninstall   the route from FIB. */intnexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set,		     struct route_node *top){  struct prefix_ipv4 p;  struct route_table *table;  struct route_node *rn;  struct rib *match;  struct nexthop *newhop;  if (nexthop->type == NEXTHOP_TYPE_IPV4)    nexthop->ifindex = 0;  if (set)    UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);  /* Make lookup prefix. */  memset (&p, 0, sizeof (struct prefix_ipv4));  p.family = AF_INET;  p.prefixlen = IPV4_MAX_PREFIXLEN;  p.prefix = nexthop->gate.ipv4;  /* Lookup table.  */  table = vrf_table (AFI_IP, SAFI_UNICAST, 0);  if (! table)    return 0;  rn = route_node_match (table, (struct prefix *) &p);  while (rn)    {      route_unlock_node (rn);            /* If lookup self prefix return immidiately. */      if (rn == top)	return 0;      /* Pick up selected route. */      for (match = rn->info; match; match = match->next)	if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))	  break;      /* If there is no selected route or matched route is EGP, go up         tree. */      if (! match 	  || match->type == ZEBRA_ROUTE_BGP)	{	  do {	    rn = rn->parent;	  } while (rn && rn->info == NULL);	  if (rn)	    route_lock_node (rn);	}      else	{	  if (match->type == ZEBRA_ROUTE_CONNECT)	    {	      /* Directly point connected route. */	      newhop = match->nexthop;	      if (newhop && nexthop->type == NEXTHOP_TYPE_IPV4)		nexthop->ifindex = newhop->ifindex;	      	      return 1;	    }	  else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))	    {	      for (newhop = match->nexthop; newhop; newhop = newhop->next)		if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)		    && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))		  {		    if (set)		      {			SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);			nexthop->rtype = newhop->type;			if (newhop->type == NEXTHOP_TYPE_IPV4 ||			    newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)			  nexthop->rgate.ipv4 = newhop->gate.ipv4;			if (newhop->type == NEXTHOP_TYPE_IFINDEX			    || newhop->type == NEXTHOP_TYPE_IFNAME			    || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX)			  nexthop->rifindex = newhop->ifindex;		      }		    return 1;		  }	      return 0;	    }	  else	    {	      return 0;	    }	}    }  return 0;}#ifdef HAVE_IPV6/* If force flag is not set, do not modify falgs at all for uninstall   the route from FIB. */intnexthop_active_ipv6 (struct rib *rib, struct nexthop *nexthop, int set,		     struct route_node *top){  struct prefix_ipv6 p;  struct route_table *table;  struct route_node *rn;  struct rib *match;  struct nexthop *newhop;  if (nexthop->type == NEXTHOP_TYPE_IPV6)    nexthop->ifindex = 0;  if (set)    UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);  /* Make lookup prefix. */  memset (&p, 0, sizeof (struct prefix_ipv6));  p.family = AF_INET6;  p.prefixlen = IPV6_MAX_PREFIXLEN;  p.prefix = nexthop->gate.ipv6;  /* Lookup table.  */  table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);  if (! table)    return 0;  rn = route_node_match (table, (struct prefix *) &p);  while (rn)    {      route_unlock_node (rn);            /* If lookup self prefix return immidiately. */      if (rn == top)	return 0;      /* Pick up selected route. */      for (match = rn->info; match; match = match->next)	if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))	  break;      /* If there is no selected route or matched route is EGP, go up         tree. */      if (! match	  || match->type == ZEBRA_ROUTE_BGP)	{	  do {	    rn = rn->parent;	  } while (rn && rn->info == NULL);	  if (rn)	    route_lock_node (rn);	}      else	{	  if (match->type == ZEBRA_ROUTE_CONNECT)	    {	      /* Directly point connected route. */	      newhop = match->nexthop;	      if (newhop && nexthop->type == NEXTHOP_TYPE_IPV6)		nexthop->ifindex = newhop->ifindex;	      	      return 1;	    }	  else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))	    {	      for (newhop = match->nexthop; newhop; newhop = newhop->next)		if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)		    && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE))		  {		    if (set)		      {			SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE);			nexthop->rtype = newhop->type;			if (newhop->type == NEXTHOP_TYPE_IPV6			    || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX			    || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)			  nexthop->rgate.ipv6 = newhop->gate.ipv6;			if (newhop->type == NEXTHOP_TYPE_IFINDEX			    || newhop->type == NEXTHOP_TYPE_IFNAME			    || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX			    || newhop->type == NEXTHOP_TYPE_IPV6_IFNAME)			  nexthop->rifindex = newhop->ifindex;		      }		    return 1;		  }	      return 0;	    }	  else	    {	      return 0;	    }	}    }  return 0;}#endif /* HAVE_IPV6 */struct rib *rib_match_ipv4 (struct in_addr addr){  struct prefix_ipv4 p;  struct route_table *table;  struct route_node *rn;  struct rib *match;  struct nexthop *newhop;  /* Lookup table.  */  table = vrf_table (AFI_IP, SAFI_UNICAST, 0);  if (! table)    return 0;  memset (&p, 0, sizeof (struct prefix_ipv4));  p.family = AF_INET;  p.prefixlen = IPV4_MAX_PREFIXLEN;  p.prefix = addr;  rn = route_node_match (table, (struct prefix *) &p);  while (rn)    {      route_unlock_node (rn);            /* Pick up selected route. */      for (match = rn->info; match; match = match->next)	if (CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED))	  break;

⌨️ 快捷键说明

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