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

📄 ospf_zebra.c

📁 router source code for the ospdf.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Zebra connect library for OSPFd * Copyright (C) 1997, 98, 99, 2000 Kunihiro Ishiguro, Toshiaki Takada * * 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 "thread.h"#include "command.h"#include "network.h"#include "prefix.h"#include "routemap.h"#include "table.h"#include "stream.h"#include "memory.h"#include "zclient.h"#include "filter.h"#include "log.h"#include "ospfd/ospfd.h"#include "ospfd/ospf_interface.h"#include "ospfd/ospf_ism.h"#include "ospfd/ospf_asbr.h"#include "ospfd/ospf_asbr.h"#include "ospfd/ospf_abr.h"#include "ospfd/ospf_lsa.h"#include "ospfd/ospf_dump.h"#include "ospfd/ospf_route.h"#include "ospfd/ospf_zebra.h"#ifdef HAVE_SNMP#include "ospfd/ospf_snmp.h"#endif /* HAVE_SNMP *//* Zebra structure to hold current status. */struct zclient *zclient = NULL;/* For registering threads. */extern struct thread_master *master;/* Inteface addition message from zebra. */intospf_interface_add (int command, struct zclient *zclient, zebra_size_t length){  struct interface *ifp;  struct ospf *ospf;  ifp = zebra_interface_add_read (zclient->ibuf);  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))    zlog_info ("Zebra: interface add %s index %d flags %ld metric %d mtu %d",	       ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);  if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))    {      SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);      IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_BROADCAST;            if (if_is_broadcast (ifp))	IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_BROADCAST;      else if (if_is_pointopoint (ifp))	IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_POINTOPOINT;      else if (if_is_loopback (ifp))	IF_DEF_PARAMS (ifp)->type = OSPF_IFTYPE_LOOPBACK;    }  ospf = ospf_lookup ();  if (ospf != NULL)    ospf_if_update (ospf);#ifdef HAVE_SNMP  ospf_snmp_if_update (ifp);#endif /* HAVE_SNMP */  return 0;}intospf_interface_delete (int command, struct zclient *zclient,		       zebra_size_t length){  struct interface *ifp;  struct stream *s;  struct route_node *rn;  s = zclient->ibuf;    /* zebra_interface_state_read() updates interface structure in iflist */  ifp = zebra_interface_state_read (s);  if (ifp == NULL)    return 0;  if (if_is_up (ifp))    zlog_warn ("Zebra: got delete of %s, but interface is still up",	       ifp->name);    if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))    zlog_info ("Zebra: interface delete %s index %d flags %ld metric %d mtu %d",	       ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);  #ifdef HAVE_SNMP  ospf_snmp_if_delete (ifp);#endif /* HAVE_SNMP */  for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))    if (rn->info)      ospf_if_free ((struct ospf_interface *) rn->info);  for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn))    if (rn->info)      ospf_del_if_params (rn->info);    if_delete (ifp);  return 0;}struct interface *zebra_interface_if_lookup (struct stream *s){  struct interface *ifp;  u_char ifname_tmp[INTERFACE_NAMSIZ];  /* Read interface name. */  stream_get (ifname_tmp, s, INTERFACE_NAMSIZ);  /* Lookup this by interface index. */  ifp = if_lookup_by_name (ifname_tmp);  /* If such interface does not exist, indicate an error */  if (!ifp)    return NULL;  return ifp;}voidzebra_interface_if_set_value (struct stream *s, struct interface *ifp){  /* Read interface's index. */  ifp->ifindex = stream_getl (s);  /* Read interface's value. */  ifp->flags = stream_getl (s);  ifp->metric = stream_getl (s);  ifp->mtu = stream_getl (s);  ifp->bandwidth = stream_getl (s);}intospf_interface_state_up (int command, struct zclient *zclient,			 zebra_size_t length){  struct interface *ifp;  struct interface if_tmp;  struct ospf_interface *oi;  struct route_node *rn;    ifp = zebra_interface_if_lookup (zclient->ibuf);  if (ifp == NULL)    return 0;  /* Interface is already up. */  if (if_is_up (ifp))    {      /* Temporarily keep ifp values. */      memcpy (&if_tmp, ifp, sizeof (struct interface));      zebra_interface_if_set_value (zclient->ibuf, ifp);      if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))	zlog_info ("Zebra: Interface[%s] state update.", ifp->name);      if (if_tmp.bandwidth != ifp->bandwidth)	{	  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))	    zlog_info ("Zebra: Interface[%s] bandwidth change %d -> %d.",		       ifp->name, if_tmp.bandwidth, ifp->bandwidth);	  ospf_if_recalculate_output_cost (ifp);	}      return 0;    }    zebra_interface_if_set_value (zclient->ibuf, ifp);    if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))    zlog_info ("Zebra: Interface[%s] state change to up.", ifp->name);    for (rn = route_top (IF_OIFS (ifp));rn; rn = route_next (rn))    {      if ( (oi = rn->info) == NULL)	continue;            ospf_if_up (oi);    }    return 0;}intospf_interface_state_down (int command, struct zclient *zclient,			   zebra_size_t length){  struct interface *ifp;  struct ospf_interface *oi;  struct route_node *node;  ifp = zebra_interface_state_read (zclient->ibuf);  if (ifp == NULL)    return 0;  if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))    zlog_info ("Zebra: Interface[%s] state change to down.", ifp->name);  for (node = route_top (IF_OIFS (ifp));node; node = route_next (node))    {      if ( (oi = node->info) == NULL)	continue;      ospf_if_down (oi);    }  return 0;}intospf_interface_address_add (int command, struct zclient *zclient,			    zebra_size_t length){  struct ospf *ospf;  struct connected *c;  c = zebra_interface_address_add_read (zclient->ibuf);  if (c == NULL)    return 0;  ospf = ospf_lookup ();  if (ospf != NULL)    ospf_if_update (ospf);#ifdef HAVE_SNMP  ospf_snmp_if_update (c->ifp);#endif /* HAVE_SNMP */  return 0;}intospf_interface_address_delete (int command, struct zclient *zclient,			       zebra_size_t length){  struct ospf *ospf;  struct connected *c;  struct interface *ifp;  struct ospf_interface *oi;  struct route_node *rn;  struct prefix p;  c = zebra_interface_address_delete_read (zclient->ibuf);  if (c == NULL)    return 0;  ifp = c->ifp;  p = *c->address;  p.prefixlen = IPV4_MAX_PREFIXLEN;  rn = route_node_lookup (IF_OIFS (ifp), &p);  if (! rn)    return 0;  assert (rn->info);  oi = rn->info;    /* Call interface hook functions to clean up */  ospf_if_free (oi);  #ifdef HAVE_SNMP  ospf_snmp_if_update (c->ifp);#endif /* HAVE_SNMP */  connected_free (c);  ospf = ospf_lookup ();  if (ospf != NULL)    ospf_if_update (ospf);  return 0;}voidospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or){  u_char message;  u_char distance;  u_char flags;  int psize;  struct stream *s;  struct ospf_path *path;  listnode node;  if (zclient->redist[ZEBRA_ROUTE_OSPF])    {      message = 0;      flags = 0;      /* OSPF pass nexthop and metric */      SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP);      SET_FLAG (message, ZAPI_MESSAGE_METRIC);      /* Distance value. */      distance = ospf_distance_apply (p, or);      if (distance)	SET_FLAG (message, ZAPI_MESSAGE_DISTANCE);      /* Make packet. */      s = zclient->obuf;      stream_reset (s);      /* Length place holder. */      stream_putw (s, 0);      /* Put command, type, flags, message. */      stream_putc (s, ZEBRA_IPV4_ROUTE_ADD);      stream_putc (s, ZEBRA_ROUTE_OSPF);      stream_putc (s, flags);      stream_putc (s, message);        /* Put prefix information. */      psize = PSIZE (p->prefixlen);      stream_putc (s, p->prefixlen);      stream_write (s, (u_char *)&p->prefix, psize);      /* Nexthop count. */      stream_putc (s, or->path->count);      /* Nexthop, ifindex, distance and metric information. */      for (node = listhead (or->path); node; nextnode (node))	{	  path = getdata (node);	  if (path->nexthop.s_addr != INADDR_ANY)	    {	      stream_putc (s, ZEBRA_NEXTHOP_IPV4);	      stream_put_in_addr (s, &path->nexthop);	    }	  else	    {	      stream_putc (s, ZEBRA_NEXTHOP_IFINDEX);	      if (path->oi)		stream_putl (s, path->oi->ifp->ifindex);	      else		stream_putl (s, 0);	    }	}      if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE))	stream_putc (s, distance);      if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC))	{	  if (or->path_type == OSPF_PATH_TYPE1_EXTERNAL)	    stream_putl (s, or->cost + or->u.ext.type2_cost);	  else if (or->path_type == OSPF_PATH_TYPE2_EXTERNAL)	    stream_putl (s, or->u.ext.type2_cost);	  else	    stream_putl (s, or->cost);	}      stream_putw_at (s, 0, stream_get_endp (s));      writen (zclient->sock, s->data, stream_get_endp (s));#if 0      if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))	{	  char *nexthop_str;	  nexthop_str = strdup (inet_ntoa (*nexthop));	  zlog_info ("Zebra: Route add %s/%d nexthop %s metric %d",		     inet_ntoa (p->prefix), p->prefixlen, nexthop_str,		     metric);	  free (nexthop_str);	}#endif /* 0 */    }}voidospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or){  struct zapi_ipv4 api;  if (zclient->redist[ZEBRA_ROUTE_OSPF])    {      api.type = ZEBRA_ROUTE_OSPF;      api.flags = 0;      api.message = 0;      zapi_ipv4_delete (zclient, p, &api);#if 0      if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))	{	  char *nexthop_str;	  nexthop_str = strdup (inet_ntoa (*nexthop));	  zlog_info ("Zebra: Route delete %s/%d nexthop %s",		     inet_ntoa (p->prefix), p->prefixlen, nexthop_str);	  free (nexthop_str);	}#endif /* 0 */    }}voidospf_zebra_add_discard (struct prefix_ipv4 *p){  struct zapi_ipv4 api;  if (zclient->redist[ZEBRA_ROUTE_OSPF])    {      api.type = ZEBRA_ROUTE_OSPF;      api.flags = ZEBRA_FLAG_BLACKHOLE;      api.message = 0;      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);      api.nexthop_num = 0;      api.ifindex_num = 0;      zapi_ipv4_add (zclient, p, &api);    }}voidospf_zebra_delete_discard (struct prefix_ipv4 *p){  struct zapi_ipv4 api;  if (zclient->redist[ZEBRA_ROUTE_OSPF])    {      api.type = ZEBRA_ROUTE_OSPF;      api.flags = ZEBRA_FLAG_BLACKHOLE;      api.message = 0;      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);      api.nexthop_num = 0;      api.ifindex_num = 0;      zapi_ipv4_delete (zclient, p, &api);    }}intospf_is_type_redistributed (int type){  return (DEFAULT_ROUTE_TYPE (type)) ?    zclient->default_information : zclient->redist[type];}intospf_redistribute_set (struct ospf *ospf, int type, int mtype, int mvalue){  int force = 0;    if (ospf_is_type_redistributed (type))    {      if (mtype != ospf->dmetric[type].type)	{	  ospf->dmetric[type].type = mtype;	  force = LSA_REFRESH_FORCE;	}      if (mvalue != ospf->dmetric[type].value)	{	  ospf->dmetric[type].value = mvalue;	  force = LSA_REFRESH_FORCE;	}	        ospf_external_lsa_refresh_type (ospf, type, force);            if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))	zlog_info ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",		   LOOKUP (ospf_redistributed_proto, type),		   metric_type (ospf, type), metric_value (ospf, type));            return CMD_SUCCESS;    }  ospf->dmetric[type].type = mtype;  ospf->dmetric[type].value = mvalue;  zclient_redistribute_set (zclient, type);  if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))    zlog_info ("Redistribute[%s]: Start  Type[%d], Metric[%d]",	       LOOKUP (ospf_redistributed_proto, type),	       metric_type (ospf, type), metric_value (ospf, type));    ospf_asbr_status_update (ospf, ++ospf->redistribute);  return CMD_SUCCESS;}intospf_redistribute_unset (struct ospf *ospf, int type){  if (type == zclient->redist_default)    return CMD_SUCCESS;  if (! ospf_is_type_redistributed (type))    return CMD_SUCCESS;  zclient_redistribute_unset (zclient, type);    if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))    zlog_info ("Redistribute[%s]: Stop",	       LOOKUP (ospf_redistributed_proto, type));  ospf->dmetric[type].type = -1;  ospf->dmetric[type].value = -1;  /* Remove the routes from OSPF table. */  ospf_redistribute_withdraw (type);  ospf_asbr_status_update (ospf, --ospf->redistribute);  return CMD_SUCCESS;}intospf_redistribute_default_set (struct ospf *ospf, int originate,			       int mtype, int mvalue){  int force = 0;  if (ospf_is_type_redistributed (DEFAULT_ROUTE))    {      if (mtype != ospf->dmetric[DEFAULT_ROUTE].type)	{	  ospf->dmetric[DEFAULT_ROUTE].type = mtype;	  force = 1;	}      if (mvalue != ospf->dmetric[DEFAULT_ROUTE].value)	{	  force = 1;	  ospf->dmetric[DEFAULT_ROUTE].value = mvalue;	}            ospf_external_lsa_refresh_default (ospf);            if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))	zlog_info ("Redistribute[%s]: Refresh  Type[%d], Metric[%d]",		   LOOKUP (ospf_redistributed_proto, DEFAULT_ROUTE),		   metric_type (ospf, DEFAULT_ROUTE),		   metric_value (ospf, DEFAULT_ROUTE));      return CMD_SUCCESS;    }  ospf->default_originate = originate;  ospf->dmetric[DEFAULT_ROUTE].type = mtype;  ospf->dmetric[DEFAULT_ROUTE].value = mvalue;  zclient_redistribute_default_set (zclient);    if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE))    zlog_info ("Redistribute[DEFAULT]: Start  Type[%d], Metric[%d]",	       metric_type (ospf, DEFAULT_ROUTE),

⌨️ 快捷键说明

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