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

📄 rip_interface.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 3 页
字号:
	  ri->t_wakeup = NULL;	}      ri->recv_badpackets = 0;      ri->recv_badroutes = 0;      ri->sent_updates = 0;      ri->passive = 0;    }}intrip_if_down(struct interface *ifp){  struct route_node *rp;  struct rip_info *rinfo;  struct rip_interface *ri = NULL;  if (rip)    {      for (rp = route_top (rip->table); rp; rp = route_next (rp))	if ((rinfo = rp->info) != NULL)	  {	    /* Routes got through this interface. */	    if (rinfo->ifindex == ifp->ifindex &&		rinfo->type == ZEBRA_ROUTE_RIP &&		rinfo->sub_type == RIP_ROUTE_RTE)	      {		rip_zebra_ipv4_delete ((struct prefix_ipv4 *) &rp->p,				       &rinfo->nexthop,				       rinfo->ifindex);		rip_redistribute_delete (rinfo->type,rinfo->sub_type,					 (struct prefix_ipv4 *)&rp->p,					 rinfo->ifindex);	      }	    else	      {		/* All redistributed routes but static and system */		if ((rinfo->ifindex == ifp->ifindex) &&		    (rinfo->type != ZEBRA_ROUTE_STATIC) &&		    (rinfo->type != ZEBRA_ROUTE_SYSTEM))		  rip_redistribute_delete (rinfo->type,rinfo->sub_type,					   (struct prefix_ipv4 *)&rp->p,					   rinfo->ifindex);	      }	  }    }	      ri = ifp->info;    if (ri->running)   {     if (IS_RIP_DEBUG_EVENT)       zlog_info ("turn off %s", ifp->name);     /* Leave from multicast group. */     rip_multicast_leave (ifp, rip->sock);     ri->running = 0;   }  return 0;}/* Needed for stop RIP process. */voidrip_if_down_all (){  struct interface *ifp;  listnode node;  for (node = listhead (iflist); node; nextnode (node))    {      ifp = getdata (node);      rip_if_down (ifp);    }}intrip_interface_address_add (int command, struct zclient *zclient,			   zebra_size_t length){  struct connected *ifc;  struct prefix *p;  ifc = zebra_interface_address_add_read (zclient->ibuf);  if (ifc == NULL)    return 0;  p = ifc->address;  if (p->family == AF_INET)    {      if (IS_RIP_DEBUG_ZEBRA)	zlog_info ("connected address %s/%d is added", 		   inet_ntoa (p->u.prefix4), p->prefixlen);            /* Check is this interface is RIP enabled or not.*/      rip_enable_apply (ifc->ifp);#ifdef HAVE_SNMP      rip_ifaddr_add (ifc->ifp, ifc);#endif /* HAVE_SNMP */    }  return 0;}intrip_interface_address_delete (int command, struct zclient *zclient,			      zebra_size_t length){  struct connected *ifc;  struct prefix *p;  ifc = zebra_interface_address_delete_read (zclient->ibuf);    if (ifc)    {      p = ifc->address;      if (p->family == AF_INET)	{	  if (IS_RIP_DEBUG_ZEBRA)	    zlog_info ("connected address %s/%d is deleted",		       inet_ntoa (p->u.prefix4), p->prefixlen);#ifdef HAVE_SNMP	  rip_ifaddr_delete (ifc->ifp, ifc);#endif /* HAVE_SNMP */	  /* Check if this interface is RIP enabled or not.*/	  rip_enable_apply (ifc->ifp);	}      connected_free (ifc);    }  return 0;}/* Check interface is enabled by network statement. */intrip_enable_network_lookup (struct interface *ifp){  struct listnode *nn;  struct connected *connected;  struct prefix_ipv4 address;  for (nn = listhead (ifp->connected); nn; nextnode (nn))    if ((connected = getdata (nn)) != NULL)      {	struct prefix *p; 	struct route_node *node;	p = connected->address;	if (p->family == AF_INET)	  {	    address.family = AF_INET;	    address.prefix = p->u.prefix4;	    address.prefixlen = IPV4_MAX_BITLEN;	    	    node = route_node_match (rip_enable_network,				     (struct prefix *)&address);	    if (node)	      {		route_unlock_node (node);		return 1;	      }	  }      }  return -1;}/* Add RIP enable network. */intrip_enable_network_add (struct prefix *p){  struct route_node *node;  node = route_node_get (rip_enable_network, p);  if (node->info)    {      route_unlock_node (node);      return -1;    }  else    node->info = "enabled";  return 1;}/* Delete RIP enable network. */intrip_enable_network_delete (struct prefix *p){  struct route_node *node;  node = route_node_lookup (rip_enable_network, p);  if (node)    {      node->info = NULL;      /* Unlock info lock. */      route_unlock_node (node);      /* Unlock lookup lock. */      route_unlock_node (node);      return 1;    }  return -1;}/* Check interface is enabled by ifname statement. */intrip_enable_if_lookup (char *ifname){  int i;  char *str;  for (i = 0; i < vector_max (rip_enable_interface); i++)    if ((str = vector_slot (rip_enable_interface, i)) != NULL)      if (strcmp (str, ifname) == 0)	return i;  return -1;}/* Add interface to rip_enable_if. */intrip_enable_if_add (char *ifname){  int ret;  ret = rip_enable_if_lookup (ifname);  if (ret >= 0)    return -1;  vector_set (rip_enable_interface, strdup (ifname));  return 1;}/* Delete interface from rip_enable_if. */intrip_enable_if_delete (char *ifname){  int index;  char *str;  index = rip_enable_if_lookup (ifname);  if (index < 0)    return -1;  str = vector_slot (rip_enable_interface, index);  free (str);  vector_unset (rip_enable_interface, index);  return 1;}/* Join to multicast group and send request to the interface. */intrip_interface_wakeup (struct thread *t){  struct interface *ifp;  struct rip_interface *ri;  /* Get interface. */  ifp = THREAD_ARG (t);  ri = ifp->info;  ri->t_wakeup = NULL;  /* Join to multicast group. */  if (rip_multicast_join (ifp, rip->sock) < 0)    {      zlog_err ("multicast join failed, interface %s not running", ifp->name);      return 0;    }  /* Set running flag. */  ri->running = 1;  /* Send RIP request to the interface. */  rip_request_interface (ifp);  return 0;}int rip_redistribute_check (int);voidrip_connect_set (struct interface *ifp, int set){  struct listnode *nn;  struct connected *connected;  struct prefix_ipv4 address;  for (nn = listhead (ifp->connected); nn; nextnode (nn))    if ((connected = getdata (nn)) != NULL)      {	struct prefix *p; 	p = connected->address;	if (p->family != AF_INET)	  continue;	address.family = AF_INET;	address.prefix = p->u.prefix4;	address.prefixlen = p->prefixlen;	apply_mask_ipv4 (&address);	if (set)	  rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,				&address, connected->ifp->ifindex, NULL);	else	  {	    rip_redistribute_delete (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE,				     &address, connected->ifp->ifindex);	    if (rip_redistribute_check (ZEBRA_ROUTE_CONNECT))	      rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE,				    &address, connected->ifp->ifindex, NULL);	  }      }}/* Update interface status. */voidrip_enable_apply (struct interface *ifp){  int ret;  struct rip_interface *ri = NULL;  /* Check interface. */  if (if_is_loopback (ifp))    return;  if (! if_is_up (ifp))    return;  ri = ifp->info;  /* Check network configuration. */  ret = rip_enable_network_lookup (ifp);  /* If the interface is matched. */  if (ret > 0)    ri->enable_network = 1;  else    ri->enable_network = 0;  /* Check interface name configuration. */  ret = rip_enable_if_lookup (ifp->name);  if (ret >= 0)    ri->enable_interface = 1;  else    ri->enable_interface = 0;  /* any interface MUST have an IPv4 address */  if ( ! rip_if_ipv4_address_check (ifp) )    {      ri->enable_network = 0;      ri->enable_interface = 0;    }  /* Update running status of the interface. */  if (ri->enable_network || ri->enable_interface)    {      if (! ri->running)	{	  if (IS_RIP_DEBUG_EVENT)	    zlog_info ("turn on %s", ifp->name);	  /* Add interface wake up thread. */	  if (! ri->t_wakeup)	    ri->t_wakeup = thread_add_timer (master, rip_interface_wakeup,					     ifp, 1);          rip_connect_set (ifp, 1);	}    }  else    {      if (ri->running)	{	  if (IS_RIP_DEBUG_EVENT)	    zlog_info ("turn off %s", ifp->name);	  /* Might as well clean up the route table as well */ 	  rip_if_down(ifp);	  ri->running = 0;          rip_connect_set (ifp, 0);	}    }}/* Apply network configuration to all interface. */voidrip_enable_apply_all (){  struct interface *ifp;  listnode node;  /* Check each interface. */  for (node = listhead (iflist); node; nextnode (node))    {      ifp = getdata (node);      rip_enable_apply (ifp);    }}intrip_neighbor_lookup (struct sockaddr_in *from){  struct prefix_ipv4 p;  struct route_node *node;  memset (&p, 0, sizeof (struct prefix_ipv4));  p.family = AF_INET;  p.prefix = from->sin_addr;  p.prefixlen = IPV4_MAX_BITLEN;  node = route_node_lookup (rip->neighbor, (struct prefix *) &p);  if (node)    {      route_unlock_node (node);      return 1;    }  return 0;}/* Add new RIP neighbor to the neighbor tree. */intrip_neighbor_add (struct prefix_ipv4 *p){  struct route_node *node;  node = route_node_get (rip->neighbor, (struct prefix *) p);  if (node->info)    return -1;  node->info = rip->neighbor;  return 0;}/* Delete RIP neighbor from the neighbor tree. */intrip_neighbor_delete (struct prefix_ipv4 *p){  struct route_node *node;  /* Lock for look up. */  node = route_node_lookup (rip->neighbor, (struct prefix *) p);  if (! node)    return -1;    node->info = NULL;  /* Unlock lookup lock. */  route_unlock_node (node);  /* Unlock real neighbor information lock. */  route_unlock_node (node);  return 0;}/* Clear all network and neighbor configuration. */voidrip_clean_network (){  int i;  char *str;  struct route_node *rn;  /* rip_enable_network. */  for (rn = route_top (rip_enable_network); rn; rn = route_next (rn))    if (rn->info)      {	rn->info = NULL;	route_unlock_node (rn);      }  /* rip_enable_interface. */  for (i = 0; i < vector_max (rip_enable_interface); i++)    if ((str = vector_slot (rip_enable_interface, i)) != NULL)      {	free (str);	vector_slot (rip_enable_interface, i) = NULL;      }}/* Utility function for looking up passive interface settings. */intrip_passive_interface_lookup (char *ifname){  int i;  char *str;  for (i = 0; i < vector_max (Vrip_passive_interface); i++)    if ((str = vector_slot (Vrip_passive_interface, i)) != NULL)      if (strcmp (str, ifname) == 0)	return i;  return -1;}voidrip_passive_interface_apply (struct interface *ifp){  int ret;  struct rip_interface *ri;  ri = ifp->info;  ret = rip_passive_interface_lookup (ifp->name);  if (ret < 0)    ri->passive = 0;  else    ri->passive = 1;}voidrip_passive_interface_apply_all (){  struct interface *ifp;  listnode node;  for (node = listhead (iflist); node; nextnode (node))    {      ifp = getdata (node);      rip_passive_interface_apply (ifp);    }}/* Passive interface. */intrip_passive_interface_set (struct vty *vty, char *ifname){  if (rip_passive_interface_lookup (ifname) >= 0)    return CMD_WARNING;  vector_set (Vrip_passive_interface, strdup (ifname));  rip_passive_interface_apply_all ();  return CMD_SUCCESS;}intrip_passive_interface_unset (struct vty *vty, char *ifname){  int i;  char *str;  i = rip_passive_interface_lookup (ifname);  if (i < 0)    return CMD_WARNING;  str = vector_slot (Vrip_passive_interface, i);  free (str);  vector_unset (Vrip_passive_interface, i);  rip_passive_interface_apply_all ();  return CMD_SUCCESS;}/* Free all configured RIP passive-interface settings. */voidrip_passive_interface_clean (){  int i;  char *str;  for (i = 0; i < vector_max (Vrip_passive_interface); i++)    if ((str = vector_slot (Vrip_passive_interface, i)) != NULL)      {	free (str);	vector_slot (Vrip_passive_interface, i) = NULL;      }  rip_passive_interface_apply_all ();}/* RIP enable network or interface configuration. */DEFUN (rip_network,       rip_network_cmd,       "network (A.B.C.D/M|WORD)",       "Enable routing on an IP network\n"       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"       "Interface name\n"){  int ret;  struct prefix_ipv4 p;  ret = str2prefix_ipv4 (argv[0], &p);  if (ret)    ret = rip_enable_network_add ((struct prefix *) &p);  else    ret = rip_enable_if_add (argv[0]);  if (ret < 0)    {      vty_out (vty, "There is a same network configuration %s%s", argv[0],	       VTY_NEWLINE);      return CMD_WARNING;    }  rip_enable_apply_all ();  return CMD_SUCCESS;}/* RIP enable network or interface configuration. */DEFUN (no_rip_network,       no_rip_network_cmd,       "no network (A.B.C.D/M|WORD)",       NO_STR       "Enable routing on an IP network\n"       "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"       "Interface name\n"){  int ret;  struct prefix_ipv4 p;  ret = str2prefix_ipv4 (argv[0], &p);  if (ret)    ret = rip_enable_network_delete ((struct prefix *) &p);  else    ret = rip_enable_if_delete (argv[0]);  if (ret < 0)    {      vty_out (vty, "Can't find network configuration %s%s", argv[0],	       VTY_NEWLINE);      return CMD_WARNING;    }  rip_enable_apply_all ();  return CMD_SUCCESS;}/* RIP neighbor configuration set. */DEFUN (rip_neighbor,       rip_neighbor_cmd,       "neighbor A.B.C.D",       "Specify a neighbor router\n"       "Neighbor address\n"){  int ret;  struct prefix_ipv4 p;  ret = str2prefix_ipv4 (argv[0], &p);  if (ret <= 0)    {      vty_out (vty, "Please specify address by A.B.C.D%s", VTY_NEWLINE);      return CMD_WARNING;    }

⌨️ 快捷键说明

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