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

📄 redistribute.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
字号:
/* Redistribution Handler * Copyright (C) 1998 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 "vector.h"#include "vty.h"#include "command.h"#include "prefix.h"#include "table.h"#include "stream.h"#include "zclient.h"#include "linklist.h"#include "log.h"#include "zebra/rib.h"#include "zebra/zserv.h"#include "zebra/redistribute.h"#include "zebra/debug.h"intzebra_check_addr (struct prefix *p){  if (p->family == AF_INET)    {      u_int32_t addr;      addr = p->u.prefix4.s_addr;      addr = ntohl (addr);      if (IPV4_NET127 (addr) || IN_CLASSD (addr))	return 0;    }#ifdef HAVE_IPV6  if (p->family == AF_INET6)    {      if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6))	return 0;      if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6))	return 0;    }#endif /* HAVE_IPV6 */  return 1;}intis_default (struct prefix *p){  if (p->family == AF_INET)    if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0)      return 1;#ifdef HAVE_IPV6#if 0  /* IPv6 default separation is now pending until protocol daemon          can handle that. */  if (p->family == AF_INET6)    if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)      return 1;#endif /* 0 */#endif /* HAVE_IPV6 */  return 0;}voidzebra_redistribute_default (struct zserv *client){  struct prefix_ipv4 p;  struct route_table *table;  struct route_node *rn;  struct rib *newrib;#ifdef HAVE_IPV6  struct prefix_ipv6 p6;#endif /* HAVE_IPV6 */  /* Lookup default route. */  memset (&p, 0, sizeof (struct prefix_ipv4));  p.family = AF_INET;  /* Lookup table.  */  table = vrf_table (AFI_IP, SAFI_UNICAST, 0);  if (table)    {      rn = route_node_lookup (table, (struct prefix *)&p);      if (rn)	{	  for (newrib = rn->info; newrib; newrib = newrib->next)	    if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)		&& newrib->distance != DISTANCE_INFINITY)	      zsend_ipv4_add_multipath (client, &rn->p, newrib);	  route_unlock_node (rn);	}    }#ifdef HAVE_IPV6  /* Lookup default route. */  memset (&p6, 0, sizeof (struct prefix_ipv6));  p6.family = AF_INET6;  /* Lookup table.  */  table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);  if (table)    {      rn = route_node_lookup (table, (struct prefix *)&p6);      if (rn)	{	  for (newrib = rn->info; newrib; newrib = newrib->next)	    if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)		&& newrib->distance != DISTANCE_INFINITY)	      zsend_ipv6_add_multipath (client, &rn->p, newrib);	  route_unlock_node (rn);	}    }#endif /* HAVE_IPV6 */}/* Redistribute routes. */voidzebra_redistribute (struct zserv *client, int type){  struct rib *newrib;  struct route_table *table;  struct route_node *rn;  table = vrf_table (AFI_IP, SAFI_UNICAST, 0);  if (table)    for (rn = route_top (table); rn; rn = route_next (rn))      for (newrib = rn->info; newrib; newrib = newrib->next)	if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED) 	    && newrib->type == type 	    && newrib->distance != DISTANCE_INFINITY	    && zebra_check_addr (&rn->p))	  zsend_ipv4_add_multipath (client, &rn->p, newrib);  #ifdef HAVE_IPV6  table = vrf_table (AFI_IP6, SAFI_UNICAST, 0);  if (table)    for (rn = route_top (table); rn; rn = route_next (rn))      for (newrib = rn->info; newrib; newrib = newrib->next)	if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)	    && newrib->type == type 	    && newrib->distance != DISTANCE_INFINITY	    && zebra_check_addr (&rn->p))	  zsend_ipv6_add_multipath (client, &rn->p, newrib);#endif /* HAVE_IPV6 */}extern list client_list;voidredistribute_add (struct prefix *p, struct rib *rib){  listnode node;  struct zserv *client;  for (node = listhead (client_list); node; nextnode (node))    if ((client = getdata (node)) != NULL)      {	if (is_default (p))	  {	    if (client->redist_default || client->redist[rib->type])	      {		if (p->family == AF_INET)		  zsend_ipv4_add_multipath (client, p, rib);#ifdef HAVE_IPV6		if (p->family == AF_INET6)		  zsend_ipv6_add_multipath (client, p, rib);#endif /* HAVE_IPV6 */	  	      }	  }	else if (client->redist[rib->type])	  {	    if (p->family == AF_INET)	      zsend_ipv4_add_multipath (client, p, rib);#ifdef HAVE_IPV6	    if (p->family == AF_INET6)	      zsend_ipv6_add_multipath (client, p, rib);#endif /* HAVE_IPV6 */	  	  }      }}voidredistribute_delete (struct prefix *p, struct rib *rib){  listnode node;  struct zserv *client;  /* Add DISTANCE_INFINITY check. */  if (rib->distance == DISTANCE_INFINITY)    return;  for (node = listhead (client_list); node; nextnode (node))    if ((client = getdata (node)) != NULL)      {	if (is_default (p))	  {	    if (client->redist_default || client->redist[rib->type])	      {		if (p->family == AF_INET)		  zsend_ipv4_delete_multipath (client, p, rib);#ifdef HAVE_IPV6		if (p->family == AF_INET6)		  zsend_ipv6_delete_multipath (client, p, rib);#endif /* HAVE_IPV6 */	  	      }	  }	else if (client->redist[rib->type])	  {	    if (p->family == AF_INET)	      zsend_ipv4_delete_multipath (client, p, rib);#ifdef HAVE_IPV6	    if (p->family == AF_INET6)	      zsend_ipv6_delete_multipath (client, p, rib);#endif /* HAVE_IPV6 */	  	  }      }}voidzebra_redistribute_add (int command, struct zserv *client, int length){  int type;  type = stream_getc (client->ibuf);  switch (type)    {    case ZEBRA_ROUTE_KERNEL:    case ZEBRA_ROUTE_CONNECT:    case ZEBRA_ROUTE_STATIC:    case ZEBRA_ROUTE_RIP:    case ZEBRA_ROUTE_RIPNG:    case ZEBRA_ROUTE_OSPF:    case ZEBRA_ROUTE_OSPF6:    case ZEBRA_ROUTE_BGP:      if (! client->redist[type])	{	  client->redist[type] = 1;	  zebra_redistribute (client, type);	}      break;    default:      break;    }}     voidzebra_redistribute_delete (int command, struct zserv *client, int length){  int type;  type = stream_getc (client->ibuf);  switch (type)    {    case ZEBRA_ROUTE_KERNEL:    case ZEBRA_ROUTE_CONNECT:    case ZEBRA_ROUTE_STATIC:    case ZEBRA_ROUTE_RIP:    case ZEBRA_ROUTE_RIPNG:    case ZEBRA_ROUTE_OSPF:    case ZEBRA_ROUTE_OSPF6:    case ZEBRA_ROUTE_BGP:      client->redist[type] = 0;      break;    default:      break;    }}     voidzebra_redistribute_default_add (int command, struct zserv *client, int length){  client->redist_default = 1;  zebra_redistribute_default (client);}     voidzebra_redistribute_default_delete (int command, struct zserv *client,				   int length){  client->redist_default = 0;;}     /* Interface up information. */voidzebra_interface_up_update (struct interface *ifp){  listnode node;  struct zserv *client;  if (IS_ZEBRA_DEBUG_EVENT)    zlog_info ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name);  for (node = listhead (client_list); node; nextnode (node))    if ((client = getdata (node)) != NULL)      zsend_interface_up (client, ifp);}/* Interface down information. */voidzebra_interface_down_update (struct interface *ifp){  listnode node;  struct zserv *client;  if (IS_ZEBRA_DEBUG_EVENT)    zlog_info ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name);  for (node = listhead (client_list); node; nextnode (node))    if ((client = getdata (node)) != NULL)      zsend_interface_down (client, ifp);}/* Interface information update. */voidzebra_interface_add_update (struct interface *ifp){  listnode node;  struct zserv *client;  if (IS_ZEBRA_DEBUG_EVENT)    zlog_info ("MESSAGE: ZEBRA_INTERFACE_ADD %s", ifp->name);      for (node = listhead (client_list); node; nextnode (node))    if ((client = getdata (node)) != NULL)      if (client->ifinfo)	zsend_interface_add (client, ifp);}voidzebra_interface_delete_update (struct interface *ifp){  listnode node;  struct zserv *client;  if (IS_ZEBRA_DEBUG_EVENT)    zlog_info ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name);  for (node = listhead (client_list); node; nextnode (node))    if ((client = getdata (node)) != NULL)      if (client->ifinfo)	zsend_interface_delete (client, ifp);}/* Interface address addition. */voidzebra_interface_address_add_update (struct interface *ifp,				    struct connected *ifc){  listnode node;  struct zserv *client;  struct prefix *p;  char buf[BUFSIZ];  if (IS_ZEBRA_DEBUG_EVENT)    {      p = ifc->address;      zlog_info ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s/%d on %s",		 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),		 p->prefixlen, ifc->ifp->name);    }  for (node = listhead (client_list); node; nextnode (node))    if ((client = getdata (node)) != NULL)      if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))	zsend_interface_address_add (client, ifp, ifc);}/* Interface address deletion. */voidzebra_interface_address_delete_update (struct interface *ifp,				       struct connected *ifc){  listnode node;  struct zserv *client;  struct prefix *p;  char buf[BUFSIZ];  if (IS_ZEBRA_DEBUG_EVENT)    {      p = ifc->address;      zlog_info ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s/%d on %s",		 inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),		 p->prefixlen, ifc->ifp->name);    }  for (node = listhead (client_list); node; nextnode (node))    if ((client = getdata (node)) != NULL)      if (client->ifinfo && CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))	zsend_interface_address_delete (client, ifp, ifc);}

⌨️ 快捷键说明

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