diff options
Diffstat (limited to 'ripd')
| -rw-r--r-- | ripd/rip_debug.c | 237 | ||||
| -rw-r--r-- | ripd/rip_debug.h | 4 | ||||
| -rw-r--r-- | ripd/rip_interface.c | 2409 | ||||
| -rw-r--r-- | ripd/rip_interface.h | 20 | ||||
| -rw-r--r-- | ripd/rip_main.c | 197 | ||||
| -rw-r--r-- | ripd/rip_memory.c | 10 | ||||
| -rw-r--r-- | ripd/rip_offset.c | 545 | ||||
| -rw-r--r-- | ripd/rip_peer.c | 230 | ||||
| -rw-r--r-- | ripd/rip_routemap.c | 784 | ||||
| -rw-r--r-- | ripd/rip_snmp.c | 865 | ||||
| -rw-r--r-- | ripd/rip_zebra.c | 943 | ||||
| -rw-r--r-- | ripd/ripd.c | 6755 | ||||
| -rw-r--r-- | ripd/ripd.h | 481 | 
13 files changed, 6581 insertions, 6899 deletions
diff --git a/ripd/rip_debug.c b/ripd/rip_debug.c index 04252a85fb..b2c80817dd 100644 --- a/ripd/rip_debug.c +++ b/ripd/rip_debug.c @@ -34,30 +34,28 @@ DEFUN (show_debugging_rip,         DEBUG_STR         RIP_STR)  { -  vty_out (vty, "RIP debugging status:\n"); - -  if (IS_RIP_DEBUG_EVENT) -    vty_out (vty, "  RIP event debugging is on\n"); - -  if (IS_RIP_DEBUG_PACKET) -    { -      if (IS_RIP_DEBUG_SEND && IS_RIP_DEBUG_RECV) -	{ -	  vty_out (vty,"  RIP packet debugging is on\n"); -	} -      else -	{ -	  if (IS_RIP_DEBUG_SEND) -	    vty_out (vty,"  RIP packet send debugging is on\n"); -	  else -	    vty_out (vty,"  RIP packet receive debugging is on\n"); +	vty_out(vty, "RIP debugging status:\n"); + +	if (IS_RIP_DEBUG_EVENT) +		vty_out(vty, "  RIP event debugging is on\n"); + +	if (IS_RIP_DEBUG_PACKET) { +		if (IS_RIP_DEBUG_SEND && IS_RIP_DEBUG_RECV) { +			vty_out(vty, "  RIP packet debugging is on\n"); +		} else { +			if (IS_RIP_DEBUG_SEND) +				vty_out(vty, +					"  RIP packet send debugging is on\n"); +			else +				vty_out(vty, +					"  RIP packet receive debugging is on\n"); +		}  	} -    } -  if (IS_RIP_DEBUG_ZEBRA) -    vty_out (vty, "  RIP zebra debugging is on\n"); +	if (IS_RIP_DEBUG_ZEBRA) +		vty_out(vty, "  RIP zebra debugging is on\n"); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (debug_rip_events, @@ -67,8 +65,8 @@ DEFUN (debug_rip_events,         RIP_STR         "RIP events\n")  { -  rip_debug_event = RIP_DEBUG_EVENT; -  return CMD_WARNING_CONFIG_FAILED; +	rip_debug_event = RIP_DEBUG_EVENT; +	return CMD_WARNING_CONFIG_FAILED;  }  DEFUN (debug_rip_packet, @@ -78,10 +76,10 @@ DEFUN (debug_rip_packet,         RIP_STR         "RIP packet\n")  { -  rip_debug_packet = RIP_DEBUG_PACKET; -  rip_debug_packet |= RIP_DEBUG_SEND; -  rip_debug_packet |= RIP_DEBUG_RECV; -  return CMD_SUCCESS; +	rip_debug_packet = RIP_DEBUG_PACKET; +	rip_debug_packet |= RIP_DEBUG_SEND; +	rip_debug_packet |= RIP_DEBUG_RECV; +	return CMD_SUCCESS;  }  DEFUN (debug_rip_packet_direct, @@ -93,13 +91,17 @@ DEFUN (debug_rip_packet_direct,         "RIP receive packet\n"         "RIP send packet\n")  { -  int idx_recv_send = 3; -  rip_debug_packet |= RIP_DEBUG_PACKET; -  if (strncmp ("send", argv[idx_recv_send]->arg, strlen (argv[idx_recv_send]->arg)) == 0) -    rip_debug_packet |= RIP_DEBUG_SEND; -  if (strncmp ("recv", argv[idx_recv_send]->arg, strlen (argv[idx_recv_send]->arg)) == 0) -    rip_debug_packet |= RIP_DEBUG_RECV; -  return CMD_SUCCESS; +	int idx_recv_send = 3; +	rip_debug_packet |= RIP_DEBUG_PACKET; +	if (strncmp("send", argv[idx_recv_send]->arg, +		    strlen(argv[idx_recv_send]->arg)) +	    == 0) +		rip_debug_packet |= RIP_DEBUG_SEND; +	if (strncmp("recv", argv[idx_recv_send]->arg, +		    strlen(argv[idx_recv_send]->arg)) +	    == 0) +		rip_debug_packet |= RIP_DEBUG_RECV; +	return CMD_SUCCESS;  }  DEFUN (debug_rip_zebra, @@ -109,8 +111,8 @@ DEFUN (debug_rip_zebra,         RIP_STR         "RIP and ZEBRA communication\n")  { -  rip_debug_zebra = RIP_DEBUG_ZEBRA; -  return CMD_WARNING_CONFIG_FAILED; +	rip_debug_zebra = RIP_DEBUG_ZEBRA; +	return CMD_WARNING_CONFIG_FAILED;  }  DEFUN (no_debug_rip_events, @@ -121,8 +123,8 @@ DEFUN (no_debug_rip_events,         RIP_STR         "RIP events\n")  { -  rip_debug_event = 0; -  return CMD_SUCCESS; +	rip_debug_event = 0; +	return CMD_SUCCESS;  }  DEFUN (no_debug_rip_packet, @@ -133,8 +135,8 @@ DEFUN (no_debug_rip_packet,         RIP_STR         "RIP packet\n")  { -  rip_debug_packet = 0; -  return CMD_SUCCESS; +	rip_debug_packet = 0; +	return CMD_SUCCESS;  }  DEFUN (no_debug_rip_packet_direct, @@ -147,22 +149,23 @@ DEFUN (no_debug_rip_packet_direct,         "RIP option set for receive packet\n"         "RIP option set for send packet\n")  { -  int idx_recv_send = 4; -  if (strncmp ("send", argv[idx_recv_send]->arg, strlen (argv[idx_recv_send]->arg)) == 0) -    { -      if (IS_RIP_DEBUG_RECV) -       rip_debug_packet &= ~RIP_DEBUG_SEND; -      else -       rip_debug_packet = 0; -    } -  else if (strncmp ("recv", argv[idx_recv_send]->arg, strlen (argv[idx_recv_send]->arg)) == 0) -    { -      if (IS_RIP_DEBUG_SEND) -       rip_debug_packet &= ~RIP_DEBUG_RECV; -      else -       rip_debug_packet = 0; -    } -  return CMD_SUCCESS; +	int idx_recv_send = 4; +	if (strncmp("send", argv[idx_recv_send]->arg, +		    strlen(argv[idx_recv_send]->arg)) +	    == 0) { +		if (IS_RIP_DEBUG_RECV) +			rip_debug_packet &= ~RIP_DEBUG_SEND; +		else +			rip_debug_packet = 0; +	} else if (strncmp("recv", argv[idx_recv_send]->arg, +			   strlen(argv[idx_recv_send]->arg)) +		   == 0) { +		if (IS_RIP_DEBUG_SEND) +			rip_debug_packet &= ~RIP_DEBUG_RECV; +		else +			rip_debug_packet = 0; +	} +	return CMD_SUCCESS;  }  DEFUN (no_debug_rip_zebra, @@ -173,85 +176,73 @@ DEFUN (no_debug_rip_zebra,         RIP_STR         "RIP and ZEBRA communication\n")  { -  rip_debug_zebra = 0; -  return CMD_WARNING_CONFIG_FAILED; +	rip_debug_zebra = 0; +	return CMD_WARNING_CONFIG_FAILED;  }  /* Debug node. */ -static struct cmd_node debug_node = -{ -  DEBUG_NODE, -  "",				/* Debug node has no interface. */ -  1 -}; +static struct cmd_node debug_node = {DEBUG_NODE, +				     "", /* Debug node has no interface. */ +				     1}; -static int -config_write_debug (struct vty *vty) +static int config_write_debug(struct vty *vty)  { -  int write = 0; +	int write = 0; -  if (IS_RIP_DEBUG_EVENT) -    { -      vty_out (vty, "debug rip events\n"); -      write++; -    } -  if (IS_RIP_DEBUG_PACKET) -    { -      if (IS_RIP_DEBUG_SEND && IS_RIP_DEBUG_RECV) -	{ -	  vty_out (vty,"debug rip packet\n"); -	  write++; +	if (IS_RIP_DEBUG_EVENT) { +		vty_out(vty, "debug rip events\n"); +		write++;  	} -      else -	{ -	  if (IS_RIP_DEBUG_SEND) -	    vty_out (vty,"debug rip packet send\n"); -	  else -	    vty_out (vty,"debug rip packet recv\n"); -	  write++; +	if (IS_RIP_DEBUG_PACKET) { +		if (IS_RIP_DEBUG_SEND && IS_RIP_DEBUG_RECV) { +			vty_out(vty, "debug rip packet\n"); +			write++; +		} else { +			if (IS_RIP_DEBUG_SEND) +				vty_out(vty, "debug rip packet send\n"); +			else +				vty_out(vty, "debug rip packet recv\n"); +			write++; +		}  	} -    } -  if (IS_RIP_DEBUG_ZEBRA) -    { -      vty_out (vty, "debug rip zebra\n"); -      write++; -    } -  return write; +	if (IS_RIP_DEBUG_ZEBRA) { +		vty_out(vty, "debug rip zebra\n"); +		write++; +	} +	return write;  } -void -rip_debug_reset (void) +void rip_debug_reset(void)  { -  rip_debug_event = 0; -  rip_debug_packet = 0; -  rip_debug_zebra = 0; +	rip_debug_event = 0; +	rip_debug_packet = 0; +	rip_debug_zebra = 0;  } -void -rip_debug_init (void) +void rip_debug_init(void)  { -  rip_debug_event = 0; -  rip_debug_packet = 0; -  rip_debug_zebra = 0; - -  install_node (&debug_node, config_write_debug); - -  install_element (ENABLE_NODE, &show_debugging_rip_cmd); -  install_element (ENABLE_NODE, &debug_rip_events_cmd); -  install_element (ENABLE_NODE, &debug_rip_packet_cmd); -  install_element (ENABLE_NODE, &debug_rip_packet_direct_cmd); -  install_element (ENABLE_NODE, &debug_rip_zebra_cmd); -  install_element (ENABLE_NODE, &no_debug_rip_events_cmd); -  install_element (ENABLE_NODE, &no_debug_rip_packet_cmd); -  install_element (ENABLE_NODE, &no_debug_rip_packet_direct_cmd); -  install_element (ENABLE_NODE, &no_debug_rip_zebra_cmd); - -  install_element (CONFIG_NODE, &debug_rip_events_cmd); -  install_element (CONFIG_NODE, &debug_rip_packet_cmd); -  install_element (CONFIG_NODE, &debug_rip_packet_direct_cmd); -  install_element (CONFIG_NODE, &debug_rip_zebra_cmd); -  install_element (CONFIG_NODE, &no_debug_rip_events_cmd); -  install_element (CONFIG_NODE, &no_debug_rip_packet_cmd); -  install_element (CONFIG_NODE, &no_debug_rip_packet_direct_cmd); -  install_element (CONFIG_NODE, &no_debug_rip_zebra_cmd); +	rip_debug_event = 0; +	rip_debug_packet = 0; +	rip_debug_zebra = 0; + +	install_node(&debug_node, config_write_debug); + +	install_element(ENABLE_NODE, &show_debugging_rip_cmd); +	install_element(ENABLE_NODE, &debug_rip_events_cmd); +	install_element(ENABLE_NODE, &debug_rip_packet_cmd); +	install_element(ENABLE_NODE, &debug_rip_packet_direct_cmd); +	install_element(ENABLE_NODE, &debug_rip_zebra_cmd); +	install_element(ENABLE_NODE, &no_debug_rip_events_cmd); +	install_element(ENABLE_NODE, &no_debug_rip_packet_cmd); +	install_element(ENABLE_NODE, &no_debug_rip_packet_direct_cmd); +	install_element(ENABLE_NODE, &no_debug_rip_zebra_cmd); + +	install_element(CONFIG_NODE, &debug_rip_events_cmd); +	install_element(CONFIG_NODE, &debug_rip_packet_cmd); +	install_element(CONFIG_NODE, &debug_rip_packet_direct_cmd); +	install_element(CONFIG_NODE, &debug_rip_zebra_cmd); +	install_element(CONFIG_NODE, &no_debug_rip_events_cmd); +	install_element(CONFIG_NODE, &no_debug_rip_packet_cmd); +	install_element(CONFIG_NODE, &no_debug_rip_packet_direct_cmd); +	install_element(CONFIG_NODE, &no_debug_rip_zebra_cmd);  } diff --git a/ripd/rip_debug.h b/ripd/rip_debug.h index e1dcd2fa7a..c3b15d2e15 100644 --- a/ripd/rip_debug.h +++ b/ripd/rip_debug.h @@ -46,7 +46,7 @@ extern unsigned long rip_debug_event;  extern unsigned long rip_debug_packet;  extern unsigned long rip_debug_zebra; -extern void rip_debug_init (void); -extern void rip_debug_reset (void); +extern void rip_debug_init(void); +extern void rip_debug_reset(void);  #endif /* _ZEBRA_RIP_DEBUG_H */ diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 357856e1e8..a170471123 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -41,25 +41,22 @@  #include "ripd/rip_debug.h"  #include "ripd/rip_interface.h" -DEFINE_HOOK(rip_ifaddr_add, (struct connected *ifc), (ifc)) -DEFINE_HOOK(rip_ifaddr_del, (struct connected *ifc), (ifc)) +DEFINE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc)) +DEFINE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc))  /* static prototypes */ -static void rip_enable_apply (struct interface *); -static void rip_passive_interface_apply (struct interface *); +static void rip_enable_apply(struct interface *); +static void rip_passive_interface_apply(struct interface *);  static int rip_if_down(struct interface *ifp); -static int rip_enable_if_lookup (const char *ifname); -static int rip_enable_network_lookup2 (struct connected *connected); -static void rip_enable_apply_all (void); +static int rip_enable_if_lookup(const char *ifname); +static int rip_enable_network_lookup2(struct connected *connected); +static void rip_enable_apply_all(void); -const struct message ri_version_msg[] = -{ -  {RI_RIP_VERSION_1,       "1"}, -  {RI_RIP_VERSION_2,       "2"}, -  {RI_RIP_VERSION_1_AND_2, "1 2"}, -  {RI_RIP_VERSION_NONE,    "none"}, -  { 0 } -}; +const struct message ri_version_msg[] = {{RI_RIP_VERSION_1, "1"}, +					 {RI_RIP_VERSION_2, "2"}, +					 {RI_RIP_VERSION_1_AND_2, "1 2"}, +					 {RI_RIP_VERSION_NONE, "none"}, +					 {0}};  extern struct zebra_privs_t ripd_privs; @@ -70,167 +67,158 @@ vector rip_enable_interface;  struct route_table *rip_enable_network;  /* Vector to store passive-interface name. */ -static int passive_default;	/* are we in passive-interface default mode? */ +static int passive_default; /* are we in passive-interface default mode? */  vector Vrip_passive_nondefault;  /* Join to the RIP version 2 multicast group. */ -static int -ipv4_multicast_join (int sock,  -		     struct in_addr group,  -		     struct in_addr ifa, -		     ifindex_t ifindex) +static int ipv4_multicast_join(int sock, struct in_addr group, +			       struct in_addr ifa, ifindex_t ifindex)  { -  int ret; +	int ret; -  ret = setsockopt_ipv4_multicast (sock, -				   IP_ADD_MEMBERSHIP,  -				   ifa, -				   group.s_addr,  -				   ifindex);  +	ret = setsockopt_ipv4_multicast(sock, IP_ADD_MEMBERSHIP, ifa, +					group.s_addr, ifindex); -  if (ret < 0)  -    zlog_info("can't setsockopt IP_ADD_MEMBERSHIP %s", safe_strerror(errno)); +	if (ret < 0) +		zlog_info("can't setsockopt IP_ADD_MEMBERSHIP %s", +			  safe_strerror(errno)); -  return ret; +	return ret;  }  /* Leave from the RIP version 2 multicast group. */ -static int -ipv4_multicast_leave (int sock,  -		      struct in_addr group,  -		      struct in_addr ifa, -		      ifindex_t ifindex) +static int ipv4_multicast_leave(int sock, struct in_addr group, +				struct in_addr ifa, ifindex_t ifindex)  { -  int ret; +	int ret; -  ret = setsockopt_ipv4_multicast (sock, -				   IP_DROP_MEMBERSHIP,  -				   ifa, -				   group.s_addr,  -				   ifindex); +	ret = setsockopt_ipv4_multicast(sock, IP_DROP_MEMBERSHIP, ifa, +					group.s_addr, ifindex); -  if (ret < 0)  -    zlog_info("can't setsockopt IP_DROP_MEMBERSHIP"); +	if (ret < 0) +		zlog_info("can't setsockopt IP_DROP_MEMBERSHIP"); -  return ret; +	return ret;  } -static void rip_interface_reset (struct rip_interface *); +static void rip_interface_reset(struct rip_interface *);  /* Allocate new RIP's interface configuration. */ -static struct rip_interface * -rip_interface_new (void) +static struct rip_interface *rip_interface_new(void)  { -  struct rip_interface *ri; +	struct rip_interface *ri; -  ri = XCALLOC (MTYPE_RIP_INTERFACE, sizeof (struct rip_interface)); +	ri = XCALLOC(MTYPE_RIP_INTERFACE, sizeof(struct rip_interface)); -  rip_interface_reset (ri); +	rip_interface_reset(ri); -  return ri; +	return ri;  } -void -rip_interface_multicast_set (int sock, struct connected *connected) +void rip_interface_multicast_set(int sock, struct connected *connected)  { -  struct in_addr addr; +	struct in_addr addr; -  assert (connected != NULL); +	assert(connected != NULL); -  addr = CONNECTED_ID(connected)->u.prefix4; +	addr = CONNECTED_ID(connected)->u.prefix4; + +	if (setsockopt_ipv4_multicast_if(sock, addr, connected->ifp->ifindex) +	    < 0) { +		zlog_warn( +			"Can't setsockopt IP_MULTICAST_IF on fd %d to " +			"ifindex %d for interface %s", +			sock, connected->ifp->ifindex, connected->ifp->name); +	} -  if (setsockopt_ipv4_multicast_if (sock, addr, connected->ifp->ifindex) < 0) -    { -      zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to " -		 "ifindex %d for interface %s", -		 sock, connected->ifp->ifindex, -		 connected->ifp->name); -    } -   -  return; +	return;  }  /* Send RIP request packet to specified interface. */ -static void -rip_request_interface_send (struct interface *ifp, u_char version) +static void rip_request_interface_send(struct interface *ifp, u_char version)  { -  struct sockaddr_in to; +	struct sockaddr_in to; -  /* RIPv2 support multicast. */ -  if (version == RIPv2 && if_is_multicast (ifp)) -    { -       -      if (IS_RIP_DEBUG_EVENT) -	zlog_debug ("multicast request on %s", ifp->name); +	/* RIPv2 support multicast. */ +	if (version == RIPv2 && if_is_multicast(ifp)) { -      rip_request_send (NULL, ifp, version, NULL); -      return; -    } +		if (IS_RIP_DEBUG_EVENT) +			zlog_debug("multicast request on %s", ifp->name); -  /* RIPv1 and non multicast interface. */ -  if (if_is_pointopoint (ifp) || if_is_broadcast (ifp)) -    { -      struct listnode *cnode, *cnnode; -      struct connected *connected; - -      if (IS_RIP_DEBUG_EVENT) -	zlog_debug ("broadcast request to %s", ifp->name); +		rip_request_send(NULL, ifp, version, NULL); +		return; +	} -      for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, connected)) -	{ -	  if (connected->address->family == AF_INET) -	    { -	      memset (&to, 0, sizeof (struct sockaddr_in)); -	      to.sin_port = htons (RIP_PORT_DEFAULT); -              if (connected->destination) -                /* use specified broadcast or peer destination addr */ -                to.sin_addr = connected->destination->u.prefix4; -              else if (connected->address->prefixlen < IPV4_MAX_PREFIXLEN) -	        /* calculate the appropriate broadcast address */ -                to.sin_addr.s_addr = -		  ipv4_broadcast_addr(connected->address->u.prefix4.s_addr, -				      connected->address->prefixlen); -	      else -		/* do not know where to send the packet */ -	        continue; - -	      if (IS_RIP_DEBUG_EVENT) -		zlog_debug ("SEND request to %s", inet_ntoa (to.sin_addr)); -	       -	      rip_request_send (&to, ifp, version, connected); -	    } +	/* RIPv1 and non multicast interface. */ +	if (if_is_pointopoint(ifp) || if_is_broadcast(ifp)) { +		struct listnode *cnode, *cnnode; +		struct connected *connected; + +		if (IS_RIP_DEBUG_EVENT) +			zlog_debug("broadcast request to %s", ifp->name); + +		for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, +				       connected)) { +			if (connected->address->family == AF_INET) { +				memset(&to, 0, sizeof(struct sockaddr_in)); +				to.sin_port = htons(RIP_PORT_DEFAULT); +				if (connected->destination) +					/* use specified broadcast or peer +					 * destination addr */ +					to.sin_addr = connected->destination->u +							      .prefix4; +				else if (connected->address->prefixlen +					 < IPV4_MAX_PREFIXLEN) +					/* calculate the appropriate broadcast +					 * address */ +					to.sin_addr +						.s_addr = ipv4_broadcast_addr( +						connected->address->u.prefix4 +							.s_addr, +						connected->address->prefixlen); +				else +					/* do not know where to send the packet +					 */ +					continue; + +				if (IS_RIP_DEBUG_EVENT) +					zlog_debug("SEND request to %s", +						   inet_ntoa(to.sin_addr)); + +				rip_request_send(&to, ifp, version, connected); +			} +		}  	} -    }  }  /* This will be executed when interface goes up. */ -static void -rip_request_interface (struct interface *ifp) +static void rip_request_interface(struct interface *ifp)  { -  struct rip_interface *ri; +	struct rip_interface *ri; -  /* In default ripd doesn't send RIP_REQUEST to the loopback interface. */ -  if (if_is_loopback (ifp)) -    return; +	/* In default ripd doesn't send RIP_REQUEST to the loopback interface. +	 */ +	if (if_is_loopback(ifp)) +		return; -  /* If interface is down, don't send RIP packet. */ -  if (! if_is_operative (ifp)) -    return; +	/* If interface is down, don't send RIP packet. */ +	if (!if_is_operative(ifp)) +		return; -  /* Fetch RIP interface information. */ -  ri = ifp->info; +	/* Fetch RIP interface information. */ +	ri = ifp->info; -  /* If there is no version configuration in the interface, -     use rip's version setting. */ -  { -    int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? -		 rip->version_send : ri->ri_send); -    if (vsend & RIPv1) -      rip_request_interface_send (ifp, RIPv1); -    if (vsend & RIPv2) -      rip_request_interface_send (ifp, RIPv2); -  } +	/* If there is no version configuration in the interface, +	   use rip's version setting. */ +	{ +		int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? rip->version_send +							    : ri->ri_send); +		if (vsend & RIPv1) +			rip_request_interface_send(ifp, RIPv1); +		if (vsend & RIPv2) +			rip_request_interface_send(ifp, RIPv2); +	}  }  #if 0 @@ -267,949 +255,892 @@ rip_request_neighbor_all (void)  #endif  /* Multicast packet receive socket. */ -static int -rip_multicast_join (struct interface *ifp, int sock) +static int rip_multicast_join(struct interface *ifp, int sock)  { -  struct listnode *cnode; -  struct connected *ifc; +	struct listnode *cnode; +	struct connected *ifc; -  if (if_is_operative (ifp) && if_is_multicast (ifp)) -    { -      if (IS_RIP_DEBUG_EVENT) -	zlog_debug ("multicast join at %s", ifp->name); +	if (if_is_operative(ifp) && if_is_multicast(ifp)) { +		if (IS_RIP_DEBUG_EVENT) +			zlog_debug("multicast join at %s", ifp->name); -      for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc)) -	{ -	  struct prefix_ipv4 *p; -	  struct in_addr group; -	       -	  p = (struct prefix_ipv4 *) ifc->address; -       -	  if (p->family != AF_INET) -	    continue; -       -	  group.s_addr = htonl (INADDR_RIP_GROUP); -	  if (ipv4_multicast_join (sock, group, p->prefix, ifp->ifindex) < 0) -	    return -1; -	  else -	    return 0; +		for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) { +			struct prefix_ipv4 *p; +			struct in_addr group; + +			p = (struct prefix_ipv4 *)ifc->address; + +			if (p->family != AF_INET) +				continue; + +			group.s_addr = htonl(INADDR_RIP_GROUP); +			if (ipv4_multicast_join(sock, group, p->prefix, +						ifp->ifindex) +			    < 0) +				return -1; +			else +				return 0; +		}  	} -    } -  return 0; +	return 0;  }  /* Leave from multicast group. */ -static void -rip_multicast_leave (struct interface *ifp, int sock) +static void rip_multicast_leave(struct interface *ifp, int sock)  { -  struct listnode *cnode; -  struct connected *connected; +	struct listnode *cnode; +	struct connected *connected; -  if (if_is_up (ifp) && if_is_multicast (ifp)) -    { -      if (IS_RIP_DEBUG_EVENT) -	zlog_debug ("multicast leave from %s", ifp->name); +	if (if_is_up(ifp) && if_is_multicast(ifp)) { +		if (IS_RIP_DEBUG_EVENT) +			zlog_debug("multicast leave from %s", ifp->name); -      for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected)) -	{ -	  struct prefix_ipv4 *p; -	  struct in_addr group; -           -	  p = (struct prefix_ipv4 *) connected->address; -	   -	  if (p->family != AF_INET) -	    continue; -       -	  group.s_addr = htonl (INADDR_RIP_GROUP); -          if (ipv4_multicast_leave (sock, group, p->prefix, ifp->ifindex) == 0) -	    return; -        } -    } +		for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) { +			struct prefix_ipv4 *p; +			struct in_addr group; + +			p = (struct prefix_ipv4 *)connected->address; + +			if (p->family != AF_INET) +				continue; + +			group.s_addr = htonl(INADDR_RIP_GROUP); +			if (ipv4_multicast_leave(sock, group, p->prefix, +						 ifp->ifindex) +			    == 0) +				return; +		} +	}  }  /* Is there and address on interface that I could use ? */ -static int -rip_if_ipv4_address_check (struct interface *ifp) +static int rip_if_ipv4_address_check(struct interface *ifp)  { -  struct listnode *nn; -  struct connected *connected; -  int count = 0; +	struct listnode *nn; +	struct connected *connected; +	int count = 0; -  for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, connected)) -    { -      struct prefix *p; +	for (ALL_LIST_ELEMENTS_RO(ifp->connected, nn, connected)) { +		struct prefix *p; -      p = connected->address; +		p = connected->address; + +		if (p->family == AF_INET) +			count++; +	} -      if (p->family == AF_INET) -        count++; -    } -						 -  return count; +	return count;  } -						 -						 -						 +  /* Does this address belongs to me ? */ -int -if_check_address (struct in_addr addr) -{ -  struct listnode *node; -  struct interface *ifp; -   -  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) -    { -      struct listnode *cnode; -      struct connected *connected; - -      for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected)) -	{ -	  struct prefix_ipv4 *p; +int if_check_address(struct in_addr addr) +{ +	struct listnode *node; +	struct interface *ifp; -	  p = (struct prefix_ipv4 *) connected->address; +	for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { +		struct listnode *cnode; +		struct connected *connected; -	  if (p->family != AF_INET) -	    continue; +		for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) { +			struct prefix_ipv4 *p; -	  if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0) -	    return 1; +			p = (struct prefix_ipv4 *)connected->address; + +			if (p->family != AF_INET) +				continue; + +			if (IPV4_ADDR_CMP(&p->prefix, &addr) == 0) +				return 1; +		}  	} -    } -  return 0; +	return 0;  }  /* Inteface link down message processing. */ -int -rip_interface_down (int command, struct zclient *zclient, zebra_size_t length, -    vrf_id_t vrf_id) +int rip_interface_down(int command, struct zclient *zclient, +		       zebra_size_t length, vrf_id_t vrf_id)  { -  struct interface *ifp; -  struct stream *s; +	struct interface *ifp; +	struct stream *s; -  s = zclient->ibuf;   +	s = zclient->ibuf; -  /* zebra_interface_state_read() updates interface structure in -     iflist. */ -  ifp = zebra_interface_state_read (s, vrf_id); +	/* zebra_interface_state_read() updates interface structure in +	   iflist. */ +	ifp = zebra_interface_state_read(s, vrf_id); -  if (ifp == NULL) -    return 0; +	if (ifp == NULL) +		return 0; -  rip_if_down(ifp); -  -  if (IS_RIP_DEBUG_ZEBRA) -    zlog_debug ("interface %s index %d flags %llx metric %d mtu %d is down", -	       ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, -	       ifp->metric, ifp->mtu); +	rip_if_down(ifp); -  return 0; +	if (IS_RIP_DEBUG_ZEBRA) +		zlog_debug( +			"interface %s index %d flags %llx metric %d mtu %d is down", +			ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, +			ifp->metric, ifp->mtu); + +	return 0;  }  /* Inteface link up message processing */ -int -rip_interface_up (int command, struct zclient *zclient, zebra_size_t length, -    vrf_id_t vrf_id) +int rip_interface_up(int command, struct zclient *zclient, zebra_size_t length, +		     vrf_id_t vrf_id)  { -  struct interface *ifp; +	struct interface *ifp; + +	/* zebra_interface_state_read () updates interface structure in +	   iflist. */ +	ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); -  /* zebra_interface_state_read () updates interface structure in -     iflist. */ -  ifp = zebra_interface_state_read (zclient->ibuf, vrf_id); +	if (ifp == NULL) +		return 0; -  if (ifp == NULL) -    return 0; +	if (IS_RIP_DEBUG_ZEBRA) +		zlog_debug( +			"interface %s index %d flags %#llx metric %d mtu %d is up", +			ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, +			ifp->metric, ifp->mtu); -  if (IS_RIP_DEBUG_ZEBRA) -    zlog_debug ("interface %s index %d flags %#llx metric %d mtu %d is up", -	       ifp->name, ifp->ifindex, (unsigned long long) ifp->flags, -	       ifp->metric, ifp->mtu); +	/* Check if this interface is RIP enabled or not.*/ +	rip_enable_apply(ifp); -  /* Check if this interface is RIP enabled or not.*/ -  rip_enable_apply (ifp); -  -  /* Check for a passive interface */ -  rip_passive_interface_apply (ifp); +	/* Check for a passive interface */ +	rip_passive_interface_apply(ifp); -  /* Apply distribute list to the all interface. */ -  rip_distribute_update_interface (ifp); +	/* Apply distribute list to the all interface. */ +	rip_distribute_update_interface(ifp); -  return 0; +	return 0;  }  /* Inteface addition message from zebra. */ -int -rip_interface_add (int command, struct zclient *zclient, zebra_size_t length, -    vrf_id_t vrf_id) +int rip_interface_add(int command, struct zclient *zclient, zebra_size_t length, +		      vrf_id_t vrf_id)  { -  struct interface *ifp; +	struct interface *ifp; -  ifp = zebra_interface_add_read (zclient->ibuf, vrf_id); +	ifp = zebra_interface_add_read(zclient->ibuf, vrf_id); -  if (IS_RIP_DEBUG_ZEBRA) -    zlog_debug ("interface add %s index %d flags %#llx metric %d mtu %d", -		ifp->name, ifp->ifindex, (unsigned long long) ifp->flags, -		ifp->metric, ifp->mtu); +	if (IS_RIP_DEBUG_ZEBRA) +		zlog_debug( +			"interface add %s index %d flags %#llx metric %d mtu %d", +			ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, +			ifp->metric, ifp->mtu); -  /* Check if this interface is RIP enabled or not.*/ -  rip_enable_apply (ifp); -  -  /* Check for a passive interface */ -  rip_passive_interface_apply (ifp); +	/* Check if this interface is RIP enabled or not.*/ +	rip_enable_apply(ifp); -  /* Apply distribute list to the all interface. */ -  rip_distribute_update_interface (ifp); +	/* Check for a passive interface */ +	rip_passive_interface_apply(ifp); -  /* rip_request_neighbor_all (); */ +	/* Apply distribute list to the all interface. */ +	rip_distribute_update_interface(ifp); -  /* Check interface routemap. */ -  rip_if_rmap_update_interface (ifp); +	/* rip_request_neighbor_all (); */ -  return 0; +	/* Check interface routemap. */ +	rip_if_rmap_update_interface(ifp); + +	return 0;  } -int -rip_interface_delete (int command, struct zclient *zclient, -		      zebra_size_t length, vrf_id_t vrf_id) +int rip_interface_delete(int command, struct zclient *zclient, +			 zebra_size_t length, vrf_id_t vrf_id)  { -  struct interface *ifp; -  struct stream *s; +	struct interface *ifp; +	struct stream *s; + +	s = zclient->ibuf; +	/* zebra_interface_state_read() updates interface structure in iflist */ +	ifp = zebra_interface_state_read(s, vrf_id); -  s = zclient->ibuf;   -  /* zebra_interface_state_read() updates interface structure in iflist */ -  ifp = zebra_interface_state_read (s, vrf_id); +	if (ifp == NULL) +		return 0; + +	if (if_is_up(ifp)) { +		rip_if_down(ifp); +	} -  if (ifp == NULL) -    return 0; +	zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d", +		  ifp->name, ifp->ifindex, (unsigned long long)ifp->flags, +		  ifp->metric, ifp->mtu); -  if (if_is_up (ifp)) { -    rip_if_down(ifp); -  }  -   -  zlog_info("interface delete %s index %d flags %#llx metric %d mtu %d", -	    ifp->name, ifp->ifindex, (unsigned long long) ifp->flags, -	    ifp->metric, ifp->mtu); -   -  /* To support pseudo interface do not free interface structure.  */ -  /* if_delete(ifp); */ -  ifp->ifindex = IFINDEX_DELETED; +	/* To support pseudo interface do not free interface structure.  */ +	/* if_delete(ifp); */ +	ifp->ifindex = IFINDEX_DELETED; -  return 0; +	return 0;  } -static void -rip_interface_clean (struct rip_interface *ri) +static void rip_interface_clean(struct rip_interface *ri)  { -  ri->enable_network = 0; -  ri->enable_interface = 0; -  ri->running = 0; +	ri->enable_network = 0; +	ri->enable_interface = 0; +	ri->running = 0; -  if (ri->t_wakeup) -    { -      thread_cancel (ri->t_wakeup); -      ri->t_wakeup = NULL; -    } +	if (ri->t_wakeup) { +		thread_cancel(ri->t_wakeup); +		ri->t_wakeup = NULL; +	}  } -void -rip_interfaces_clean (void) +void rip_interfaces_clean(void)  { -  struct listnode *node; -  struct interface *ifp; +	struct listnode *node; +	struct interface *ifp; -  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) -    rip_interface_clean (ifp->info); +	for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) +		rip_interface_clean(ifp->info);  } -static void -rip_interface_reset (struct rip_interface *ri) +static void rip_interface_reset(struct rip_interface *ri)  { -  /* Default authentication type is simple password for Cisco -     compatibility. */ -  ri->auth_type = RIP_NO_AUTH; -  ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE; +	/* Default authentication type is simple password for Cisco +	   compatibility. */ +	ri->auth_type = RIP_NO_AUTH; +	ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE; -  /* Set default split-horizon behavior.  If the interface is Frame -     Relay or SMDS is enabled, the default value for split-horizon is -     off.  But currently Zebra does detect Frame Relay or SMDS -     interface.  So all interface is set to split horizon.  */ -  ri->split_horizon_default = RIP_SPLIT_HORIZON; -  ri->split_horizon = ri->split_horizon_default; +	/* Set default split-horizon behavior.  If the interface is Frame +	   Relay or SMDS is enabled, the default value for split-horizon is +	   off.  But currently Zebra does detect Frame Relay or SMDS +	   interface.  So all interface is set to split horizon.  */ +	ri->split_horizon_default = RIP_SPLIT_HORIZON; +	ri->split_horizon = ri->split_horizon_default; -  ri->ri_send = RI_RIP_UNSPEC; -  ri->ri_receive = RI_RIP_UNSPEC; +	ri->ri_send = RI_RIP_UNSPEC; +	ri->ri_receive = RI_RIP_UNSPEC; -  ri->v2_broadcast = 0; +	ri->v2_broadcast = 0; -  if (ri->auth_str) -    { -      free (ri->auth_str); -      ri->auth_str = NULL; -    } -  if (ri->key_chain) -    { -      free (ri->key_chain); -      ri->key_chain = NULL; -    } +	if (ri->auth_str) { +		free(ri->auth_str); +		ri->auth_str = NULL; +	} +	if (ri->key_chain) { +		free(ri->key_chain); +		ri->key_chain = NULL; +	} + +	ri->list[RIP_FILTER_IN] = NULL; +	ri->list[RIP_FILTER_OUT] = NULL; -  ri->list[RIP_FILTER_IN] = NULL; -  ri->list[RIP_FILTER_OUT] = NULL; +	ri->prefix[RIP_FILTER_IN] = NULL; +	ri->prefix[RIP_FILTER_OUT] = NULL; -  ri->prefix[RIP_FILTER_IN] = NULL; -  ri->prefix[RIP_FILTER_OUT] = NULL; +	ri->recv_badpackets = 0; +	ri->recv_badroutes = 0; +	ri->sent_updates = 0; -  ri->recv_badpackets = 0; -  ri->recv_badroutes = 0; -  ri->sent_updates = 0; +	ri->passive = 0; -  ri->passive = 0; -   -  rip_interface_clean (ri); +	rip_interface_clean(ri);  } -void -rip_interfaces_reset (void) +void rip_interfaces_reset(void)  { -  struct listnode *node; -  struct interface *ifp; +	struct listnode *node; +	struct interface *ifp; -  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) -    rip_interface_reset (ifp->info); +	for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) +		rip_interface_reset(ifp->info);  } -int -rip_if_down(struct interface *ifp) +int rip_if_down(struct interface *ifp)  { -  struct route_node *rp; -  struct rip_info *rinfo; -  struct rip_interface *ri = NULL; -  struct list *list = NULL; -  struct listnode *listnode = NULL, *nextnode = NULL; -  if (rip) -    { -      for (rp = route_top (rip->table); rp; rp = route_next (rp)) -        if ((list = rp->info) != NULL) -          for (ALL_LIST_ELEMENTS (list, listnode, nextnode, rinfo)) -            if (rinfo->ifindex == ifp->ifindex) -              rip_ecmp_delete (rinfo); - -      ri = ifp->info; -   -      if (ri->running) -        { -          if (IS_RIP_DEBUG_EVENT) -            zlog_debug ("turn off %s", ifp->name); - -          /* Leave from multicast group. */ -          rip_multicast_leave (ifp, rip->sock); - -          ri->running = 0; -        } -    } - -  return 0; +	struct route_node *rp; +	struct rip_info *rinfo; +	struct rip_interface *ri = NULL; +	struct list *list = NULL; +	struct listnode *listnode = NULL, *nextnode = NULL; +	if (rip) { +		for (rp = route_top(rip->table); rp; rp = route_next(rp)) +			if ((list = rp->info) != NULL) +				for (ALL_LIST_ELEMENTS(list, listnode, nextnode, +						       rinfo)) +					if (rinfo->ifindex == ifp->ifindex) +						rip_ecmp_delete(rinfo); + +		ri = ifp->info; + +		if (ri->running) { +			if (IS_RIP_DEBUG_EVENT) +				zlog_debug("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. */ -void -rip_if_down_all () +void rip_if_down_all()  { -  struct interface *ifp; -  struct listnode *node, *nnode; +	struct interface *ifp; +	struct listnode *node, *nnode; -  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), node, nnode, ifp)) -    rip_if_down (ifp); +	for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) +		rip_if_down(ifp);  } -static void -rip_apply_address_add (struct connected *ifc) +static void rip_apply_address_add(struct connected *ifc)  { -  struct prefix_ipv4 address; -  struct prefix *p; +	struct prefix_ipv4 address; +	struct prefix *p; -  if (!rip) -    return; - -  if (! if_is_up(ifc->ifp)) -    return; +	if (!rip) +		return; -  p = ifc->address; +	if (!if_is_up(ifc->ifp)) +		return; -  memset (&address, 0, sizeof (address)); -  address.family = p->family; -  address.prefix = p->u.prefix4; -  address.prefixlen = p->prefixlen; -  apply_mask_ipv4(&address); +	p = ifc->address; -  /* Check if this interface is RIP enabled or not -     or  Check if this address's prefix is RIP enabled */ -  if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) || -      (rip_enable_network_lookup2(ifc) >= 0)) -    rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE, -                         &address, ifc->ifp->ifindex, NULL, 0, 0, 0); +	memset(&address, 0, sizeof(address)); +	address.family = p->family; +	address.prefix = p->u.prefix4; +	address.prefixlen = p->prefixlen; +	apply_mask_ipv4(&address); +	/* Check if this interface is RIP enabled or not +	   or  Check if this address's prefix is RIP enabled */ +	if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) +	    || (rip_enable_network_lookup2(ifc) >= 0)) +		rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE, +				     &address, ifc->ifp->ifindex, NULL, 0, 0, +				     0);  } -int -rip_interface_address_add (int command, struct zclient *zclient, -			   zebra_size_t length, vrf_id_t vrf_id) +int rip_interface_address_add(int command, struct zclient *zclient, +			      zebra_size_t length, vrf_id_t vrf_id)  { -  struct connected *ifc; -  struct prefix *p; +	struct connected *ifc; +	struct prefix *p; -  ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_ADD,  -                                      zclient->ibuf, vrf_id); +	ifc = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, +					   zclient->ibuf, vrf_id); -  if (ifc == NULL) -    return 0; +	if (ifc == NULL) +		return 0; -  p = ifc->address; +	p = ifc->address; -  if (p->family == AF_INET) -    { -      if (IS_RIP_DEBUG_ZEBRA) -	zlog_debug ("connected address %s/%d is added",  -		   inet_ntoa (p->u.prefix4), p->prefixlen); +	if (p->family == AF_INET) { +		if (IS_RIP_DEBUG_ZEBRA) +			zlog_debug("connected address %s/%d is added", +				   inet_ntoa(p->u.prefix4), p->prefixlen); -      rip_enable_apply(ifc->ifp); -      /* Check if this prefix needs to be redistributed */ -      rip_apply_address_add(ifc); +		rip_enable_apply(ifc->ifp); +		/* Check if this prefix needs to be redistributed */ +		rip_apply_address_add(ifc); -      hook_call(rip_ifaddr_add, ifc); -    } +		hook_call(rip_ifaddr_add, ifc); +	} -  return 0; +	return 0;  } -static void -rip_apply_address_del (struct connected *ifc) { -  struct prefix_ipv4 address; -  struct prefix *p; +static void rip_apply_address_del(struct connected *ifc) +{ +	struct prefix_ipv4 address; +	struct prefix *p; -  if (!rip) -    return; +	if (!rip) +		return; -  if (! if_is_up(ifc->ifp)) -    return; +	if (!if_is_up(ifc->ifp)) +		return; -  p = ifc->address; +	p = ifc->address; -  memset (&address, 0, sizeof (address)); -  address.family = p->family; -  address.prefix = p->u.prefix4; -  address.prefixlen = p->prefixlen; -  apply_mask_ipv4(&address); +	memset(&address, 0, sizeof(address)); +	address.family = p->family; +	address.prefix = p->u.prefix4; +	address.prefixlen = p->prefixlen; +	apply_mask_ipv4(&address); -  rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE, -                          &address, ifc->ifp->ifindex); +	rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE, +				&address, ifc->ifp->ifindex);  } -int -rip_interface_address_delete (int command, struct zclient *zclient, -			      zebra_size_t length, vrf_id_t vrf_id) +int rip_interface_address_delete(int command, struct zclient *zclient, +				 zebra_size_t length, vrf_id_t vrf_id)  { -  struct connected *ifc; -  struct prefix *p; - -  ifc = zebra_interface_address_read (ZEBRA_INTERFACE_ADDRESS_DELETE, -                                      zclient->ibuf, vrf_id); -   -  if (ifc) -    { -      p = ifc->address; -      if (p->family == AF_INET) -	{ -	  if (IS_RIP_DEBUG_ZEBRA) -	    zlog_debug ("connected address %s/%d is deleted", -		       inet_ntoa (p->u.prefix4), p->prefixlen); +	struct connected *ifc; +	struct prefix *p; -          hook_call(rip_ifaddr_del, ifc); +	ifc = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, +					   zclient->ibuf, vrf_id); -	  /* Chech wether this prefix needs to be removed */ -          rip_apply_address_del(ifc); +	if (ifc) { +		p = ifc->address; +		if (p->family == AF_INET) { +			if (IS_RIP_DEBUG_ZEBRA) +				zlog_debug("connected address %s/%d is deleted", +					   inet_ntoa(p->u.prefix4), +					   p->prefixlen); -	} +			hook_call(rip_ifaddr_del, ifc); -      connected_free (ifc); +			/* Chech wether this prefix needs to be removed */ +			rip_apply_address_del(ifc); +		} -    } +		connected_free(ifc); +	} -  return 0; +	return 0;  }  /* Check interface is enabled by network statement. */  /* Check wether the interface has at least a connected prefix that   * is within the ripng_enable_network table. */ -static int -rip_enable_network_lookup_if (struct interface *ifp) -{ -  struct listnode *node, *nnode; -  struct connected *connected; -  struct prefix_ipv4 address; - -  for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected)) -    { -      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; +static int rip_enable_network_lookup_if(struct interface *ifp) +{ +	struct listnode *node, *nnode; +	struct connected *connected; +	struct prefix_ipv4 address; + +	for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) { +		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;  }  /* Check wether connected is within the ripng_enable_network table. */ -int -rip_enable_network_lookup2 (struct connected *connected) +int rip_enable_network_lookup2(struct connected *connected)  { -  struct prefix_ipv4 address; -  struct prefix *p; +	struct prefix_ipv4 address; +	struct prefix *p; -  p = connected->address; +	p = connected->address; -  if (p->family == AF_INET) { -    struct route_node *node; +	if (p->family == AF_INET) { +		struct route_node *node; -    address.family = p->family; -    address.prefix = p->u.prefix4; -    address.prefixlen = IPV4_MAX_BITLEN; +		address.family = p->family; +		address.prefix = p->u.prefix4; +		address.prefixlen = IPV4_MAX_BITLEN; -    /* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within rip_enable_network */ -    node = route_node_match (rip_enable_network, -                             (struct prefix *)&address); +		/* LPM on p->family, p->u.prefix4/IPV4_MAX_BITLEN within +		 * rip_enable_network */ +		node = route_node_match(rip_enable_network, +					(struct prefix *)&address); -    if (node) { -      route_unlock_node (node); -      return 1; -    } -  } +		if (node) { +			route_unlock_node(node); +			return 1; +		} +	} -  return -1; +	return -1;  }  /* Add RIP enable network. */ -static int -rip_enable_network_add (struct prefix *p) +static int rip_enable_network_add(struct prefix *p)  { -  struct route_node *node; +	struct route_node *node; -  node = route_node_get (rip_enable_network, p); +	node = route_node_get(rip_enable_network, p); -  if (node->info) -    { -      route_unlock_node (node); -      return -1; -    } -  else -    node->info = (void *)1; +	if (node->info) { +		route_unlock_node(node); +		return -1; +	} else +		node->info = (void *)1; -  /* XXX: One should find a better solution than a generic one */ -  rip_enable_apply_all(); +	/* XXX: One should find a better solution than a generic one */ +	rip_enable_apply_all(); -  return 1; +	return 1;  }  /* Delete RIP enable network. */ -static int -rip_enable_network_delete (struct prefix *p) +static int rip_enable_network_delete(struct prefix *p)  { -  struct route_node *node; +	struct route_node *node; -  node = route_node_lookup (rip_enable_network, p); -  if (node) -    { -      node->info = NULL; +	node = route_node_lookup(rip_enable_network, p); +	if (node) { +		node->info = NULL; -      /* Unlock info lock. */ -      route_unlock_node (node); +		/* Unlock info lock. */ +		route_unlock_node(node); -      /* Unlock lookup lock. */ -      route_unlock_node (node); +		/* Unlock lookup lock. */ +		route_unlock_node(node); -      /* XXX: One should find a better solution than a generic one */ -      rip_enable_apply_all (); +		/* XXX: One should find a better solution than a generic one */ +		rip_enable_apply_all(); -      return 1; -    } -  return -1; +		return 1; +	} +	return -1;  }  /* Check interface is enabled by ifname statement. */ -static int -rip_enable_if_lookup (const char *ifname) +static int rip_enable_if_lookup(const char *ifname)  { -  unsigned int i; -  char *str; +	unsigned int i; +	char *str; -  for (i = 0; i < vector_active (rip_enable_interface); i++) -    if ((str = vector_slot (rip_enable_interface, i)) != NULL) -      if (strcmp (str, ifname) == 0) -	return i; -  return -1; +	for (i = 0; i < vector_active(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. */ -static int -rip_enable_if_add (const char *ifname) +static int rip_enable_if_add(const char *ifname)  { -  int ret; +	int ret; -  ret = rip_enable_if_lookup (ifname); -  if (ret >= 0) -    return -1; +	ret = rip_enable_if_lookup(ifname); +	if (ret >= 0) +		return -1; -  vector_set (rip_enable_interface, strdup (ifname)); +	vector_set(rip_enable_interface, strdup(ifname)); -  rip_enable_apply_all(); /* TODOVJ */ +	rip_enable_apply_all(); /* TODOVJ */ -  return 1; +	return 1;  }  /* Delete interface from rip_enable_if. */ -static int -rip_enable_if_delete (const char *ifname) +static int rip_enable_if_delete(const char *ifname)  { -  int index; -  char *str; +	int index; +	char *str; -  index = rip_enable_if_lookup (ifname); -  if (index < 0) -    return -1; +	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); +	str = vector_slot(rip_enable_interface, index); +	free(str); +	vector_unset(rip_enable_interface, index); -  rip_enable_apply_all(); /* TODOVJ */ +	rip_enable_apply_all(); /* TODOVJ */ -  return 1; +	return 1;  }  /* Join to multicast group and send request to the interface. */ -static int -rip_interface_wakeup (struct thread *t) +static int rip_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; +	struct interface *ifp; +	struct rip_interface *ri; -  /* 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; -    } +	/* Get interface. */ +	ifp = THREAD_ARG(t); -  /* Set running flag. */ -  ri->running = 1; +	ri = ifp->info; +	ri->t_wakeup = NULL; -  /* Send RIP request to the interface. */ -  rip_request_interface (ifp); - -  return 0; -} +	/* 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; +	} -static void -rip_connect_set (struct interface *ifp, int set) -{ -  struct listnode *node, *nnode; -  struct connected *connected; -  struct prefix_ipv4 address; - -  for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected)) -    { -      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) { -        /* Check once more wether this prefix is within a "network IF_OR_PREF" one */ -        if ((rip_enable_if_lookup(connected->ifp->name) >= 0) || -            (rip_enable_network_lookup2(connected) >= 0)) -          rip_redistribute_add (ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE, -                                &address, connected->ifp->ifindex,  -                                NULL, 0, 0, 0); -      } 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, 0, 0, 0); -        } -    } +	/* Set running flag. */ +	ri->running = 1; + +	/* Send RIP request to the interface. */ +	rip_request_interface(ifp); + +	return 0; +} + +static void rip_connect_set(struct interface *ifp, int set) +{ +	struct listnode *node, *nnode; +	struct connected *connected; +	struct prefix_ipv4 address; + +	for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) { +		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) { +			/* Check once more wether this prefix is within a +			 * "network IF_OR_PREF" one */ +			if ((rip_enable_if_lookup(connected->ifp->name) >= 0) +			    || (rip_enable_network_lookup2(connected) >= 0)) +				rip_redistribute_add( +					ZEBRA_ROUTE_CONNECT, +					RIP_ROUTE_INTERFACE, &address, +					connected->ifp->ifindex, NULL, 0, 0, 0); +		} 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, 0, 0, 0); +		} +	}  }  /* Update interface status. */ -void -rip_enable_apply (struct interface *ifp) +void rip_enable_apply(struct interface *ifp)  { -  int ret; -  struct rip_interface *ri = NULL; +	int ret; +	struct rip_interface *ri = NULL; -  /* Check interface. */ -  if (! if_is_operative (ifp)) -    return; +	/* Check interface. */ +	if (!if_is_operative(ifp)) +		return; -  ri = ifp->info; - -  /* Check network configuration. */ -  ret = rip_enable_network_lookup_if (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 (IS_RIP_DEBUG_EVENT) -	    zlog_debug ("turn on %s", ifp->name); +	ri = ifp->info; + +	/* Check network configuration. */ +	ret = rip_enable_network_lookup_if(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; -	  /* Add interface wake up thread. */ -	  thread_add_timer(master, rip_interface_wakeup, ifp, 1, -                           &ri->t_wakeup); -          rip_connect_set (ifp, 1); +	/* any interface MUST have an IPv4 address */ +	if (!rip_if_ipv4_address_check(ifp)) { +		ri->enable_network = 0; +		ri->enable_interface = 0;  	} -    } -  else -    { -      if (ri->running) -	{ -	  /* Might as well clean up the route table as well -	   * rip_if_down sets to 0 ri->running, and displays "turn off %s" -	   **/  -	  rip_if_down(ifp); -          rip_connect_set (ifp, 0); +	/* Update running status of the interface. */ +	if (ri->enable_network || ri->enable_interface) { +		{ +			if (IS_RIP_DEBUG_EVENT) +				zlog_debug("turn on %s", ifp->name); + +			/* Add interface wake up thread. */ +			thread_add_timer(master, rip_interface_wakeup, ifp, 1, +					 &ri->t_wakeup); +			rip_connect_set(ifp, 1); +		} +	} else { +		if (ri->running) { +			/* Might as well clean up the route table as well +			 * rip_if_down sets to 0 ri->running, and displays "turn +			 *off %s" +			 **/ +			rip_if_down(ifp); + +			rip_connect_set(ifp, 0); +		}  	} -    }  }  /* Apply network configuration to all interface. */ -void -rip_enable_apply_all () +void rip_enable_apply_all()  { -  struct interface *ifp; -  struct listnode *node, *nnode; +	struct interface *ifp; +	struct listnode *node, *nnode; -  /* Check each interface. */ -  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), node, nnode, ifp)) -    rip_enable_apply (ifp); +	/* Check each interface. */ +	for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) +		rip_enable_apply(ifp);  } -int -rip_neighbor_lookup (struct sockaddr_in *from) +int rip_neighbor_lookup(struct sockaddr_in *from)  { -  struct prefix_ipv4 p; -  struct route_node *node; +	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; +	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; +	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. */ -static int -rip_neighbor_add (struct prefix_ipv4 *p) +static int rip_neighbor_add(struct prefix_ipv4 *p)  { -  struct route_node *node; +	struct route_node *node; -  node = route_node_get (rip->neighbor, (struct prefix *) p); +	node = route_node_get(rip->neighbor, (struct prefix *)p); -  if (node->info) -    return -1; +	if (node->info) +		return -1; -  node->info = rip->neighbor; +	node->info = rip->neighbor; -  return 0; +	return 0;  }  /* Delete RIP neighbor from the neighbor tree. */ -static int -rip_neighbor_delete (struct prefix_ipv4 *p) +static int rip_neighbor_delete(struct prefix_ipv4 *p)  { -  struct route_node *node; +	struct route_node *node; -  /* Lock for look up. */ -  node = route_node_lookup (rip->neighbor, (struct prefix *) p); -  if (! node) -    return -1; -   -  node->info = NULL; +	/* Lock for look up. */ +	node = route_node_lookup(rip->neighbor, (struct prefix *)p); +	if (!node) +		return -1; -  /* Unlock lookup lock. */ -  route_unlock_node (node); +	node->info = NULL; -  /* Unlock real neighbor information lock. */ -  route_unlock_node (node); +	/* Unlock lookup lock. */ +	route_unlock_node(node); -  return 0; +	/* Unlock real neighbor information lock. */ +	route_unlock_node(node); + +	return 0;  }  /* Clear all network and neighbor configuration. */ -void -rip_clean_network () -{ -  unsigned 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_active (rip_enable_interface); i++) -    if ((str = vector_slot (rip_enable_interface, i)) != NULL) -      { -	free (str); -	vector_slot (rip_enable_interface, i) = NULL; -      } +void rip_clean_network() +{ +	unsigned 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_active(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. */ -static int -rip_passive_nondefault_lookup (const char *ifname) +static int rip_passive_nondefault_lookup(const char *ifname)  { -  unsigned int i; -  char *str; +	unsigned int i; +	char *str; -  for (i = 0; i < vector_active (Vrip_passive_nondefault); i++) -    if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL) -      if (strcmp (str, ifname) == 0) -	return i; -  return -1; +	for (i = 0; i < vector_active(Vrip_passive_nondefault); i++) +		if ((str = vector_slot(Vrip_passive_nondefault, i)) != NULL) +			if (strcmp(str, ifname) == 0) +				return i; +	return -1;  } -void -rip_passive_interface_apply (struct interface *ifp) +void rip_passive_interface_apply(struct interface *ifp)  { -  struct rip_interface *ri; +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  ri->passive = ((rip_passive_nondefault_lookup (ifp->name) < 0) ? -		 passive_default : !passive_default); +	ri->passive = ((rip_passive_nondefault_lookup(ifp->name) < 0) +			       ? passive_default +			       : !passive_default); -  if (IS_RIP_DEBUG_ZEBRA) -    zlog_debug ("interface %s: passive = %d",ifp->name,ri->passive); +	if (IS_RIP_DEBUG_ZEBRA) +		zlog_debug("interface %s: passive = %d", ifp->name, +			   ri->passive);  } -static void -rip_passive_interface_apply_all (void) +static void rip_passive_interface_apply_all(void)  { -  struct interface *ifp; -  struct listnode *node, *nnode; +	struct interface *ifp; +	struct listnode *node, *nnode; -  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), node, nnode, ifp)) -    rip_passive_interface_apply (ifp); +	for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) +		rip_passive_interface_apply(ifp);  }  /* Passive interface. */ -static int -rip_passive_nondefault_set (struct vty *vty, const char *ifname) +static int rip_passive_nondefault_set(struct vty *vty, const char *ifname)  { -  if (rip_passive_nondefault_lookup (ifname) >= 0) -    return CMD_WARNING_CONFIG_FAILED; +	if (rip_passive_nondefault_lookup(ifname) >= 0) +		return CMD_WARNING_CONFIG_FAILED; -  vector_set (Vrip_passive_nondefault, strdup (ifname)); +	vector_set(Vrip_passive_nondefault, strdup(ifname)); -  rip_passive_interface_apply_all (); +	rip_passive_interface_apply_all(); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } -static int -rip_passive_nondefault_unset (struct vty *vty, const char *ifname) +static int rip_passive_nondefault_unset(struct vty *vty, const char *ifname)  { -  int i; -  char *str; +	int i; +	char *str; -  i = rip_passive_nondefault_lookup (ifname); -  if (i < 0) -    return CMD_WARNING_CONFIG_FAILED; +	i = rip_passive_nondefault_lookup(ifname); +	if (i < 0) +		return CMD_WARNING_CONFIG_FAILED; -  str = vector_slot (Vrip_passive_nondefault, i); -  free (str); -  vector_unset (Vrip_passive_nondefault, i); +	str = vector_slot(Vrip_passive_nondefault, i); +	free(str); +	vector_unset(Vrip_passive_nondefault, i); -  rip_passive_interface_apply_all (); +	rip_passive_interface_apply_all(); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* Free all configured RIP passive-interface settings. */ -void -rip_passive_nondefault_clean (void) +void rip_passive_nondefault_clean(void)  { -  unsigned int i; -  char *str; +	unsigned int i; +	char *str; -  for (i = 0; i < vector_active (Vrip_passive_nondefault); i++) -    if ((str = vector_slot (Vrip_passive_nondefault, i)) != NULL) -      { -	free (str); -	vector_slot (Vrip_passive_nondefault, i) = NULL; -      } -  rip_passive_interface_apply_all (); +	for (i = 0; i < vector_active(Vrip_passive_nondefault); i++) +		if ((str = vector_slot(Vrip_passive_nondefault, i)) != NULL) { +			free(str); +			vector_slot(Vrip_passive_nondefault, i) = NULL; +		} +	rip_passive_interface_apply_all();  }  /* RIP enable network or interface configuration. */ @@ -1220,25 +1151,24 @@ DEFUN (rip_network,         "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"         "Interface name\n")  { -  int idx_ipv4_word = 1; -  int ret; -  struct prefix_ipv4 p; +	int idx_ipv4_word = 1; +	int ret; +	struct prefix_ipv4 p; -  ret = str2prefix_ipv4 (argv[idx_ipv4_word]->arg, &p); +	ret = str2prefix_ipv4(argv[idx_ipv4_word]->arg, &p); -  if (ret) -    ret = rip_enable_network_add ((struct prefix *) &p); -  else -    ret = rip_enable_if_add (argv[idx_ipv4_word]->arg); +	if (ret) +		ret = rip_enable_network_add((struct prefix *)&p); +	else +		ret = rip_enable_if_add(argv[idx_ipv4_word]->arg); -  if (ret < 0) -    { -      vty_out (vty, "There is a same network configuration %s\n", -                 argv[idx_ipv4_word]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (ret < 0) { +		vty_out(vty, "There is a same network configuration %s\n", +			argv[idx_ipv4_word]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* RIP enable network or interface configuration. */ @@ -1250,25 +1180,24 @@ DEFUN (no_rip_network,         "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"         "Interface name\n")  { -  int idx_ipv4_word = 2; -  int ret; -  struct prefix_ipv4 p; +	int idx_ipv4_word = 2; +	int ret; +	struct prefix_ipv4 p; -  ret = str2prefix_ipv4 (argv[idx_ipv4_word]->arg, &p); +	ret = str2prefix_ipv4(argv[idx_ipv4_word]->arg, &p); -  if (ret) -    ret = rip_enable_network_delete ((struct prefix *) &p); -  else -    ret = rip_enable_if_delete (argv[idx_ipv4_word]->arg); +	if (ret) +		ret = rip_enable_network_delete((struct prefix *)&p); +	else +		ret = rip_enable_if_delete(argv[idx_ipv4_word]->arg); -  if (ret < 0) -    { -      vty_out (vty, "Can't find network configuration %s\n", -                 argv[idx_ipv4_word]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (ret < 0) { +		vty_out(vty, "Can't find network configuration %s\n", +			argv[idx_ipv4_word]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* RIP neighbor configuration set. */ @@ -1278,21 +1207,20 @@ DEFUN (rip_neighbor,         "Specify a neighbor router\n"         "Neighbor address\n")  { -  int idx_ipv4 = 1; -  int ret; -  struct prefix_ipv4 p; +	int idx_ipv4 = 1; +	int ret; +	struct prefix_ipv4 p; -  ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p); +	ret = str2prefix_ipv4(argv[idx_ipv4]->arg, &p); + +	if (ret <= 0) { +		vty_out(vty, "Please specify address by A.B.C.D\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  if (ret <= 0) -    { -      vty_out (vty, "Please specify address by A.B.C.D\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	rip_neighbor_add(&p); -  rip_neighbor_add (&p); -   -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* RIP neighbor configuration unset. */ @@ -1303,21 +1231,20 @@ DEFUN (no_rip_neighbor,         "Specify a neighbor router\n"         "Neighbor address\n")  { -  int idx_ipv4 = 2; -  int ret; -  struct prefix_ipv4 p; +	int idx_ipv4 = 2; +	int ret; +	struct prefix_ipv4 p; -  ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p); +	ret = str2prefix_ipv4(argv[idx_ipv4]->arg, &p); -  if (ret <= 0) -    { -      vty_out (vty, "Please specify address by A.B.C.D\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (ret <= 0) { +		vty_out(vty, "Please specify address by A.B.C.D\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	rip_neighbor_delete(&p); -  rip_neighbor_delete (&p); -   -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ip_rip_receive_version, @@ -1330,28 +1257,27 @@ DEFUN (ip_rip_receive_version,         "RIP version\n"         "None\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  int idx_type = 4; -  struct rip_interface *ri; - -  ri = ifp->info; - -  switch (argv[idx_type]->arg[0]) -    { -    case '1': -      ri->ri_receive = RI_RIP_VERSION_1; -      return CMD_SUCCESS; -    case '2': -      ri->ri_receive = RI_RIP_VERSION_2; -      return CMD_SUCCESS; -    case 'n': -      ri->ri_receive = RI_RIP_VERSION_NONE; -      return CMD_SUCCESS; -    default: -      break; -    } +	VTY_DECLVAR_CONTEXT(interface, ifp); +	int idx_type = 4; +	struct rip_interface *ri; + +	ri = ifp->info; + +	switch (argv[idx_type]->arg[0]) { +	case '1': +		ri->ri_receive = RI_RIP_VERSION_1; +		return CMD_SUCCESS; +	case '2': +		ri->ri_receive = RI_RIP_VERSION_2; +		return CMD_SUCCESS; +	case 'n': +		ri->ri_receive = RI_RIP_VERSION_NONE; +		return CMD_SUCCESS; +	default: +		break; +	} -  return CMD_WARNING_CONFIG_FAILED; +	return CMD_WARNING_CONFIG_FAILED;  }  DEFUN (ip_rip_receive_version_1, @@ -1366,14 +1292,14 @@ DEFUN (ip_rip_receive_version_1,         "RIP version 2\n"         "RIP version 1\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  /* Version 1 and 2. */ -  ri->ri_receive = RI_RIP_VERSION_1_AND_2; -  return CMD_SUCCESS; +	/* Version 1 and 2. */ +	ri->ri_receive = RI_RIP_VERSION_1_AND_2; +	return CMD_SUCCESS;  }  DEFUN (no_ip_rip_receive_version, @@ -1386,13 +1312,13 @@ DEFUN (no_ip_rip_receive_version,         "Version control\n"         "RIP version\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  ri->ri_receive = RI_RIP_UNSPEC; -  return CMD_SUCCESS; +	ri->ri_receive = RI_RIP_UNSPEC; +	return CMD_SUCCESS;  } @@ -1405,24 +1331,22 @@ DEFUN (ip_rip_send_version,         "Version control\n"         "RIP version\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  int idx_type = 4; -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	int idx_type = 4; +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  /* Version 1. */ -  if (atoi (argv[idx_type]->arg) == 1) -    { -      ri->ri_send = RI_RIP_VERSION_1; -      return CMD_SUCCESS; -    } -  if (atoi (argv[idx_type]->arg) == 2) -    { -      ri->ri_send = RI_RIP_VERSION_2; -      return CMD_SUCCESS; -    } -  return CMD_WARNING_CONFIG_FAILED; +	/* Version 1. */ +	if (atoi(argv[idx_type]->arg) == 1) { +		ri->ri_send = RI_RIP_VERSION_1; +		return CMD_SUCCESS; +	} +	if (atoi(argv[idx_type]->arg) == 2) { +		ri->ri_send = RI_RIP_VERSION_2; +		return CMD_SUCCESS; +	} +	return CMD_WARNING_CONFIG_FAILED;  }  DEFUN (ip_rip_send_version_1, @@ -1437,14 +1361,14 @@ DEFUN (ip_rip_send_version_1,         "RIP version 2\n"         "RIP version 1\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  /* Version 1 and 2. */ -  ri->ri_send = RI_RIP_VERSION_1_AND_2; -  return CMD_SUCCESS; +	/* Version 1 and 2. */ +	ri->ri_send = RI_RIP_VERSION_1_AND_2; +	return CMD_SUCCESS;  }  DEFUN (no_ip_rip_send_version, @@ -1457,13 +1381,13 @@ DEFUN (no_ip_rip_send_version,         "Version control\n"         "RIP version\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  ri->ri_send = RI_RIP_UNSPEC; -  return CMD_SUCCESS; +	ri->ri_send = RI_RIP_UNSPEC; +	return CMD_SUCCESS;  } @@ -1474,13 +1398,13 @@ DEFUN (ip_rip_v2_broadcast,         "Routing Information Protocol\n"         "Send ip broadcast v2 update\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  ri->v2_broadcast = 1; -  return CMD_SUCCESS; +	ri->v2_broadcast = 1; +	return CMD_SUCCESS;  }  DEFUN (no_ip_rip_v2_broadcast, @@ -1491,13 +1415,13 @@ DEFUN (no_ip_rip_v2_broadcast,         "Routing Information Protocol\n"         "Send ip broadcast v2 update\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  ri->v2_broadcast = 0; -  return CMD_SUCCESS; +	ri->v2_broadcast = 0; +	return CMD_SUCCESS;  }  DEFUN (ip_rip_authentication_mode, @@ -1513,40 +1437,38 @@ DEFUN (ip_rip_authentication_mode,         "RFC compatible\n"         "Old ripd compatible\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  char *cryptmode = argv[4]->text; -  char *authlen = (argc > 5) ? argv[6]->text : NULL; -  struct rip_interface *ri; -  int auth_type; - -  ri = ifp->info; - -  if (strmatch ("md5", cryptmode)) -    auth_type = RIP_AUTH_MD5; -  else { -    assert (strmatch ("text", cryptmode)); -    auth_type = RIP_AUTH_SIMPLE_PASSWORD; -  } - -  ri->auth_type = auth_type; - -  if (argc > 5) -  { -    if (auth_type != RIP_AUTH_MD5) -    { -      vty_out (vty, "auth length argument only valid for md5\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } -    if (strmatch ("rfc", authlen)) -      ri->md5_auth_len = RIP_AUTH_MD5_SIZE; -    else -    { -      assert (strmatch ("old-ripd", authlen)); -      ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE; -    } -  } - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	char *cryptmode = argv[4]->text; +	char *authlen = (argc > 5) ? argv[6]->text : NULL; +	struct rip_interface *ri; +	int auth_type; + +	ri = ifp->info; + +	if (strmatch("md5", cryptmode)) +		auth_type = RIP_AUTH_MD5; +	else { +		assert(strmatch("text", cryptmode)); +		auth_type = RIP_AUTH_SIMPLE_PASSWORD; +	} + +	ri->auth_type = auth_type; + +	if (argc > 5) { +		if (auth_type != RIP_AUTH_MD5) { +			vty_out(vty, +				"auth length argument only valid for md5\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} +		if (strmatch("rfc", authlen)) +			ri->md5_auth_len = RIP_AUTH_MD5_SIZE; +		else { +			assert(strmatch("old-ripd", authlen)); +			ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE; +		} +	} + +	return CMD_SUCCESS;  }  DEFUN (no_ip_rip_authentication_mode, @@ -1563,15 +1485,15 @@ DEFUN (no_ip_rip_authentication_mode,         "RFC compatible\n"         "Old ripd compatible\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  ri->auth_type = RIP_NO_AUTH; -  ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE; +	ri->auth_type = RIP_NO_AUTH; +	ri->md5_auth_len = RIP_AUTH_MD5_COMPAT_SIZE; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ip_rip_authentication_string, @@ -1583,31 +1505,29 @@ DEFUN (ip_rip_authentication_string,         "Authentication string\n"         "Authentication string\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  int idx_line = 4; -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	int idx_line = 4; +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  if (strlen (argv[idx_line]->arg) > 16) -    { -      vty_out (vty, -                 "%% RIPv2 authentication string must be shorter than 16\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (strlen(argv[idx_line]->arg) > 16) { +		vty_out(vty, +			"%% RIPv2 authentication string must be shorter than 16\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  if (ri->key_chain) -    { -      vty_out (vty, "%% key-chain configuration exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (ri->key_chain) { +		vty_out(vty, "%% key-chain configuration exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  if (ri->auth_str) -    free (ri->auth_str); +	if (ri->auth_str) +		free(ri->auth_str); -  ri->auth_str = strdup (argv[idx_line]->arg); +	ri->auth_str = strdup(argv[idx_line]->arg); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_ip_rip_authentication_string, @@ -1620,17 +1540,17 @@ DEFUN (no_ip_rip_authentication_string,         "Authentication string\n"         "Authentication string\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  if (ri->auth_str) -    free (ri->auth_str); +	if (ri->auth_str) +		free(ri->auth_str); -  ri->auth_str = NULL; +	ri->auth_str = NULL; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -1643,24 +1563,23 @@ DEFUN (ip_rip_authentication_key_chain,         "Authentication key-chain\n"         "name of key-chain\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  int idx_line = 4; -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	int idx_line = 4; +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  if (ri->auth_str) -    { -      vty_out (vty,"%% authentication string configuration exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (ri->auth_str) { +		vty_out(vty, "%% authentication string configuration exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  if (ri->key_chain) -    free (ri->key_chain); +	if (ri->key_chain) +		free(ri->key_chain); -  ri->key_chain = strdup (argv[idx_line]->arg); +	ri->key_chain = strdup(argv[idx_line]->arg); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_ip_rip_authentication_key_chain, @@ -1673,17 +1592,17 @@ DEFUN (no_ip_rip_authentication_key_chain,         "Authentication key-chain\n"         "name of key-chain\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  if (ri->key_chain) -    free (ri->key_chain); +	if (ri->key_chain) +		free(ri->key_chain); -  ri->key_chain = NULL; +	ri->key_chain = NULL; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -1698,13 +1617,13 @@ DEFUN (ip_rip_split_horizon,         "Routing Information Protocol\n"         "Perform split horizon\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  ri->split_horizon = RIP_SPLIT_HORIZON; -  return CMD_SUCCESS; +	ri->split_horizon = RIP_SPLIT_HORIZON; +	return CMD_SUCCESS;  }  DEFUN (ip_rip_split_horizon_poisoned_reverse, @@ -1715,13 +1634,13 @@ DEFUN (ip_rip_split_horizon_poisoned_reverse,         "Perform split horizon\n"         "With poisoned-reverse\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE; -  return CMD_SUCCESS; +	ri->split_horizon = RIP_SPLIT_HORIZON_POISONED_REVERSE; +	return CMD_SUCCESS;  }  /* CHANGED: no ip rip split-horizon @@ -1736,13 +1655,13 @@ DEFUN (no_ip_rip_split_horizon,         "Routing Information Protocol\n"         "Perform split horizon\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  ri->split_horizon = RIP_NO_SPLIT_HORIZON; -  return CMD_SUCCESS; +	ri->split_horizon = RIP_NO_SPLIT_HORIZON; +	return CMD_SUCCESS;  }  DEFUN (no_ip_rip_split_horizon_poisoned_reverse, @@ -1754,20 +1673,19 @@ DEFUN (no_ip_rip_split_horizon_poisoned_reverse,         "Perform split horizon\n"         "With poisoned-reverse\n")  { -  VTY_DECLVAR_CONTEXT(interface, ifp); -  struct rip_interface *ri; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct rip_interface *ri; -  ri = ifp->info; +	ri = ifp->info; -  switch( ri->split_horizon ) -  { -     case RIP_SPLIT_HORIZON_POISONED_REVERSE: -       ri->split_horizon = RIP_SPLIT_HORIZON; -     default: -       break; -  } +	switch (ri->split_horizon) { +	case RIP_SPLIT_HORIZON_POISONED_REVERSE: +		ri->split_horizon = RIP_SPLIT_HORIZON; +	default: +		break; +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (rip_passive_interface, @@ -1777,15 +1695,15 @@ DEFUN (rip_passive_interface,         "Interface name\n"         "default for all interfaces\n")  { -  if (argv[1]->type == WORD_TKN) { // user passed 'default' -    passive_default = 1; -    rip_passive_nondefault_clean(); -    return CMD_SUCCESS; -  } -  if (passive_default) -    return rip_passive_nondefault_unset (vty, argv[1]->arg); -  else -    return rip_passive_nondefault_set (vty, argv[1]->arg); +	if (argv[1]->type == WORD_TKN) { // user passed 'default' +		passive_default = 1; +		rip_passive_nondefault_clean(); +		return CMD_SUCCESS; +	} +	if (passive_default) +		return rip_passive_nondefault_unset(vty, argv[1]->arg); +	else +		return rip_passive_nondefault_set(vty, argv[1]->arg);  }  DEFUN (no_rip_passive_interface, @@ -1796,224 +1714,217 @@ DEFUN (no_rip_passive_interface,         "Interface name\n"         "default for all interfaces\n")  { -  if (argv[2]->type == WORD_TKN) { -    passive_default = 0; -    rip_passive_nondefault_clean(); -    return CMD_SUCCESS; -  } -  if (passive_default) -    return rip_passive_nondefault_set (vty, argv[2]->arg); -  else -    return rip_passive_nondefault_unset (vty, argv[2]->arg); +	if (argv[2]->type == WORD_TKN) { +		passive_default = 0; +		rip_passive_nondefault_clean(); +		return CMD_SUCCESS; +	} +	if (passive_default) +		return rip_passive_nondefault_set(vty, argv[2]->arg); +	else +		return rip_passive_nondefault_unset(vty, argv[2]->arg);  }  /* Write rip configuration of each interface. */ -static int -rip_interface_config_write (struct vty *vty) -{ -  struct listnode *node; -  struct interface *ifp; - -  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) -    { -      struct rip_interface *ri; - -      if (ifp->ifindex == IFINDEX_DELETED) -        continue; - -      ri = ifp->info; - -      /* Do not display the interface if there is no -       * configuration about it. -       **/ -      if ((!ifp->desc)                                     && -          (ri->split_horizon == ri->split_horizon_default) && -          (ri->ri_send == RI_RIP_UNSPEC)                   && -          (ri->ri_receive == RI_RIP_UNSPEC)                && -          (ri->auth_type != RIP_AUTH_MD5)                  && -          (!ri->v2_broadcast)                              && -          (ri->md5_auth_len != RIP_AUTH_MD5_SIZE)          && -          (!ri->auth_str)                                  && -          (!ri->key_chain)                                 ) -        continue; - -      vty_out (vty, "interface %s\n",ifp->name); - -      if (ifp->desc) -	vty_out (vty, " description %s\n",ifp->desc); - -      /* Split horizon. */ -      if (ri->split_horizon != ri->split_horizon_default) -	{ -          switch (ri->split_horizon) { -          case RIP_SPLIT_HORIZON: -            vty_out (vty, " ip rip split-horizon\n"); -            break; -          case RIP_SPLIT_HORIZON_POISONED_REVERSE: -            vty_out (vty," ip rip split-horizon poisoned-reverse\n"); -            break; -          case RIP_NO_SPLIT_HORIZON: -          default: -            vty_out (vty, " no ip rip split-horizon\n"); -            break; -          } +static int rip_interface_config_write(struct vty *vty) +{ +	struct listnode *node; +	struct interface *ifp; + +	for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { +		struct rip_interface *ri; + +		if (ifp->ifindex == IFINDEX_DELETED) +			continue; + +		ri = ifp->info; + +		/* Do not display the interface if there is no +		 * configuration about it. +		 **/ +		if ((!ifp->desc) +		    && (ri->split_horizon == ri->split_horizon_default) +		    && (ri->ri_send == RI_RIP_UNSPEC) +		    && (ri->ri_receive == RI_RIP_UNSPEC) +		    && (ri->auth_type != RIP_AUTH_MD5) && (!ri->v2_broadcast) +		    && (ri->md5_auth_len != RIP_AUTH_MD5_SIZE) +		    && (!ri->auth_str) && (!ri->key_chain)) +			continue; + +		vty_out(vty, "interface %s\n", ifp->name); + +		if (ifp->desc) +			vty_out(vty, " description %s\n", ifp->desc); + +		/* Split horizon. */ +		if (ri->split_horizon != ri->split_horizon_default) { +			switch (ri->split_horizon) { +			case RIP_SPLIT_HORIZON: +				vty_out(vty, " ip rip split-horizon\n"); +				break; +			case RIP_SPLIT_HORIZON_POISONED_REVERSE: +				vty_out(vty, +					" ip rip split-horizon poisoned-reverse\n"); +				break; +			case RIP_NO_SPLIT_HORIZON: +			default: +				vty_out(vty, " no ip rip split-horizon\n"); +				break; +			} +		} + +		/* RIP version setting. */ +		if (ri->ri_send != RI_RIP_UNSPEC) +			vty_out(vty, " ip rip send version %s\n", +				lookup_msg(ri_version_msg, ri->ri_send, NULL)); + +		if (ri->ri_receive != RI_RIP_UNSPEC) +			vty_out(vty, " ip rip receive version %s \n", +				lookup_msg(ri_version_msg, ri->ri_receive, +					   NULL)); + +		if (ri->v2_broadcast) +			vty_out(vty, " ip rip v2-broadcast\n"); + +		/* RIP authentication. */ +		if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD) +			vty_out(vty, " ip rip authentication mode text\n"); + +		if (ri->auth_type == RIP_AUTH_MD5) { +			vty_out(vty, " ip rip authentication mode md5"); +			if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE) +				vty_out(vty, " auth-length old-ripd"); +			else +				vty_out(vty, " auth-length rfc"); +			vty_out(vty, "\n"); +		} + +		if (ri->auth_str) +			vty_out(vty, " ip rip authentication string %s\n", +				ri->auth_str); + +		if (ri->key_chain) +			vty_out(vty, " ip rip authentication key-chain %s\n", +				ri->key_chain); + +		vty_out(vty, "!\n"); +	} +	return 0; +} + +int config_write_rip_network(struct vty *vty, int config_mode) +{ +	unsigned int i; +	char *ifname; +	struct route_node *node; + +	/* Network type RIP enable interface statement. */ +	for (node = route_top(rip_enable_network); node; +	     node = route_next(node)) +		if (node->info) +			vty_out(vty, "%s%s/%d\n", +				config_mode ? " network " : "    ", +				inet_ntoa(node->p.u.prefix4), +				node->p.prefixlen); + +	/* Interface name RIP enable statement. */ +	for (i = 0; i < vector_active(rip_enable_interface); i++) +		if ((ifname = vector_slot(rip_enable_interface, i)) != NULL) +			vty_out(vty, "%s%s\n", +				config_mode ? " network " : "    ", ifname); + +	/* RIP neighbors listing. */ +	for (node = route_top(rip->neighbor); node; node = route_next(node)) +		if (node->info) +			vty_out(vty, "%s%s\n", +				config_mode ? " neighbor " : "    ", +				inet_ntoa(node->p.u.prefix4)); + +	/* RIP passive interface listing. */ +	if (config_mode) { +		if (passive_default) +			vty_out(vty, " passive-interface default\n"); +		for (i = 0; i < vector_active(Vrip_passive_nondefault); i++) +			if ((ifname = vector_slot(Vrip_passive_nondefault, i)) +			    != NULL) +				vty_out(vty, " %spassive-interface %s\n", +					(passive_default ? "no " : ""), ifname);  	} -      /* RIP version setting. */ -      if (ri->ri_send != RI_RIP_UNSPEC) -	vty_out (vty, " ip rip send version %s\n", -		   lookup_msg(ri_version_msg, ri->ri_send, NULL)); - -      if (ri->ri_receive != RI_RIP_UNSPEC) -	vty_out (vty, " ip rip receive version %s \n", -		   lookup_msg(ri_version_msg, ri->ri_receive, NULL)); - -      if (ri->v2_broadcast) -	vty_out (vty, " ip rip v2-broadcast\n"); - -      /* RIP authentication. */ -      if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD) -	vty_out (vty, " ip rip authentication mode text\n"); - -      if (ri->auth_type == RIP_AUTH_MD5) -        { -          vty_out (vty, " ip rip authentication mode md5"); -          if (ri->md5_auth_len == RIP_AUTH_MD5_COMPAT_SIZE) -            vty_out (vty, " auth-length old-ripd"); -          else  -            vty_out (vty, " auth-length rfc"); -          vty_out (vty, "\n"); -        } - -      if (ri->auth_str) -	vty_out (vty, " ip rip authentication string %s\n", -		 ri->auth_str); - -      if (ri->key_chain) -	vty_out (vty, " ip rip authentication key-chain %s\n", -		 ri->key_chain); - -      vty_out (vty, "!\n"); -    } -  return 0; -} - -int -config_write_rip_network (struct vty *vty, int config_mode) -{ -  unsigned int i; -  char *ifname; -  struct route_node *node; - -  /* Network type RIP enable interface statement. */ -  for (node = route_top (rip_enable_network); node; node = route_next (node)) -    if (node->info) -      vty_out (vty, "%s%s/%d\n",  -	       config_mode ? " network " : "    ", -	       inet_ntoa (node->p.u.prefix4), -	       node->p.prefixlen); - -  /* Interface name RIP enable statement. */ -  for (i = 0; i < vector_active (rip_enable_interface); i++) -    if ((ifname = vector_slot (rip_enable_interface, i)) != NULL) -      vty_out (vty, "%s%s\n", -	       config_mode ? " network " : "    ", -	       ifname); - -  /* RIP neighbors listing. */ -  for (node = route_top (rip->neighbor); node; node = route_next (node)) -    if (node->info) -      vty_out (vty, "%s%s\n",  -	       config_mode ? " neighbor " : "    ", -	       inet_ntoa(node->p.u.prefix4)); - -  /* RIP passive interface listing. */ -  if (config_mode) { -    if (passive_default) -      vty_out (vty, " passive-interface default\n"); -    for (i = 0; i < vector_active (Vrip_passive_nondefault); i++) -      if ((ifname = vector_slot (Vrip_passive_nondefault, i)) != NULL) -	vty_out (vty, " %spassive-interface %s\n", -		 (passive_default ? "no " : ""), ifname); -  } - -  return 0; -} - -static struct cmd_node interface_node = -{ -  INTERFACE_NODE, -  "%s(config-if)# ", -  1, +	return 0; +} + +static struct cmd_node interface_node = { +	INTERFACE_NODE, "%s(config-if)# ", 1,  };  /* Called when interface structure allocated. */ -static int -rip_interface_new_hook (struct interface *ifp) +static int rip_interface_new_hook(struct interface *ifp)  { -  ifp->info = rip_interface_new (); -  return 0; +	ifp->info = rip_interface_new(); +	return 0;  }  /* Called when interface structure deleted. */ -static int -rip_interface_delete_hook (struct interface *ifp) +static int rip_interface_delete_hook(struct interface *ifp)  { -  XFREE (MTYPE_RIP_INTERFACE, ifp->info); -  ifp->info = NULL; -  return 0; +	XFREE(MTYPE_RIP_INTERFACE, ifp->info); +	ifp->info = NULL; +	return 0;  }  /* Allocate and initialize interface vector. */ -void -rip_if_init (void) +void rip_if_init(void)  { -  /* Default initial size of interface vector. */ -  if_add_hook (IF_NEW_HOOK, rip_interface_new_hook); -  if_add_hook (IF_DELETE_HOOK, rip_interface_delete_hook); -   -  /* RIP network init. */ -  rip_enable_interface = vector_init (1); -  rip_enable_network = route_table_init (); +	/* Default initial size of interface vector. */ +	if_add_hook(IF_NEW_HOOK, rip_interface_new_hook); +	if_add_hook(IF_DELETE_HOOK, rip_interface_delete_hook); + +	/* RIP network init. */ +	rip_enable_interface = vector_init(1); +	rip_enable_network = route_table_init(); -  /* RIP passive interface. */ -  Vrip_passive_nondefault = vector_init (1); +	/* RIP passive interface. */ +	Vrip_passive_nondefault = vector_init(1); -  /* Install interface node. */ -  install_node (&interface_node, rip_interface_config_write); -  if_cmd_init (); +	/* Install interface node. */ +	install_node(&interface_node, rip_interface_config_write); +	if_cmd_init(); -  /* Install commands. */ -  install_element (RIP_NODE, &rip_network_cmd); -  install_element (RIP_NODE, &no_rip_network_cmd); -  install_element (RIP_NODE, &rip_neighbor_cmd); -  install_element (RIP_NODE, &no_rip_neighbor_cmd); +	/* Install commands. */ +	install_element(RIP_NODE, &rip_network_cmd); +	install_element(RIP_NODE, &no_rip_network_cmd); +	install_element(RIP_NODE, &rip_neighbor_cmd); +	install_element(RIP_NODE, &no_rip_neighbor_cmd); -  install_element (RIP_NODE, &rip_passive_interface_cmd); -  install_element (RIP_NODE, &no_rip_passive_interface_cmd); +	install_element(RIP_NODE, &rip_passive_interface_cmd); +	install_element(RIP_NODE, &no_rip_passive_interface_cmd); -  install_element (INTERFACE_NODE, &ip_rip_send_version_cmd); -  install_element (INTERFACE_NODE, &ip_rip_send_version_1_cmd); -  install_element (INTERFACE_NODE, &no_ip_rip_send_version_cmd); +	install_element(INTERFACE_NODE, &ip_rip_send_version_cmd); +	install_element(INTERFACE_NODE, &ip_rip_send_version_1_cmd); +	install_element(INTERFACE_NODE, &no_ip_rip_send_version_cmd); -  install_element (INTERFACE_NODE, &ip_rip_receive_version_cmd); -  install_element (INTERFACE_NODE, &ip_rip_receive_version_1_cmd); -  install_element (INTERFACE_NODE, &no_ip_rip_receive_version_cmd); +	install_element(INTERFACE_NODE, &ip_rip_receive_version_cmd); +	install_element(INTERFACE_NODE, &ip_rip_receive_version_1_cmd); +	install_element(INTERFACE_NODE, &no_ip_rip_receive_version_cmd); -  install_element (INTERFACE_NODE, &ip_rip_v2_broadcast_cmd); -  install_element (INTERFACE_NODE, &no_ip_rip_v2_broadcast_cmd); +	install_element(INTERFACE_NODE, &ip_rip_v2_broadcast_cmd); +	install_element(INTERFACE_NODE, &no_ip_rip_v2_broadcast_cmd); -  install_element (INTERFACE_NODE, &ip_rip_authentication_mode_cmd); -  install_element (INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd); +	install_element(INTERFACE_NODE, &ip_rip_authentication_mode_cmd); +	install_element(INTERFACE_NODE, &no_ip_rip_authentication_mode_cmd); -  install_element (INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd); -  install_element (INTERFACE_NODE, &no_ip_rip_authentication_key_chain_cmd); +	install_element(INTERFACE_NODE, &ip_rip_authentication_key_chain_cmd); +	install_element(INTERFACE_NODE, +			&no_ip_rip_authentication_key_chain_cmd); -  install_element (INTERFACE_NODE, &ip_rip_authentication_string_cmd); -  install_element (INTERFACE_NODE, &no_ip_rip_authentication_string_cmd); +	install_element(INTERFACE_NODE, &ip_rip_authentication_string_cmd); +	install_element(INTERFACE_NODE, &no_ip_rip_authentication_string_cmd); -  install_element (INTERFACE_NODE, &ip_rip_split_horizon_cmd); -  install_element (INTERFACE_NODE, &ip_rip_split_horizon_poisoned_reverse_cmd); -  install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_cmd); -  install_element (INTERFACE_NODE, &no_ip_rip_split_horizon_poisoned_reverse_cmd); +	install_element(INTERFACE_NODE, &ip_rip_split_horizon_cmd); +	install_element(INTERFACE_NODE, +			&ip_rip_split_horizon_poisoned_reverse_cmd); +	install_element(INTERFACE_NODE, &no_ip_rip_split_horizon_cmd); +	install_element(INTERFACE_NODE, +			&no_ip_rip_split_horizon_poisoned_reverse_cmd);  } diff --git a/ripd/rip_interface.h b/ripd/rip_interface.h index 9513bafc22..8723388e75 100644 --- a/ripd/rip_interface.h +++ b/ripd/rip_interface.h @@ -20,17 +20,13 @@  #ifndef _QUAGGA_RIP_INTERFACE_H  #define _QUAGGA_RIP_INTERFACE_H -extern int rip_interface_down (int , struct zclient *, zebra_size_t, -    vrf_id_t); -extern int rip_interface_up (int , struct zclient *, zebra_size_t, -    vrf_id_t); -extern int rip_interface_add (int , struct zclient *, zebra_size_t, -    vrf_id_t); -extern int rip_interface_delete (int , struct zclient *, zebra_size_t, -    vrf_id_t); -extern int rip_interface_address_add (int , struct zclient *, zebra_size_t, -    vrf_id_t); -extern int rip_interface_address_delete (int , struct zclient *, zebra_size_t, -    vrf_id_t); +extern int rip_interface_down(int, struct zclient *, zebra_size_t, vrf_id_t); +extern int rip_interface_up(int, struct zclient *, zebra_size_t, vrf_id_t); +extern int rip_interface_add(int, struct zclient *, zebra_size_t, vrf_id_t); +extern int rip_interface_delete(int, struct zclient *, zebra_size_t, vrf_id_t); +extern int rip_interface_address_add(int, struct zclient *, zebra_size_t, +				     vrf_id_t); +extern int rip_interface_address_delete(int, struct zclient *, zebra_size_t, +					vrf_id_t);  #endif /* _QUAGGA_RIP_INTERFACE_H */ diff --git a/ripd/rip_main.c b/ripd/rip_main.c index 1a7d03bca1..91b623beb4 100644 --- a/ripd/rip_main.c +++ b/ripd/rip_main.c @@ -39,34 +39,24 @@  #include "ripd/ripd.h"  /* ripd options. */ -static struct option longopts[] =  -{ -  { "retain",      no_argument,       NULL, 'r'}, -  { 0 } -}; +static struct option longopts[] = {{"retain", no_argument, NULL, 'r'}, {0}};  /* ripd privileges */ -zebra_capabilities_t _caps_p [] =  -{ -  ZCAP_NET_RAW, -  ZCAP_BIND -}; +zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND}; -struct zebra_privs_t ripd_privs = -{ +struct zebra_privs_t ripd_privs = {  #if defined(FRR_USER) -  .user = FRR_USER, +	.user = FRR_USER,  #endif  #if defined FRR_GROUP -  .group = FRR_GROUP, +	.group = FRR_GROUP,  #endif  #ifdef VTY_GROUP -  .vty_group = VTY_GROUP, +	.vty_group = VTY_GROUP,  #endif -  .caps_p = _caps_p, -  .cap_num_p = 2, -  .cap_num_i = 0 -}; +	.caps_p = _caps_p, +	.cap_num_p = 2, +	.cap_num_i = 0};  /* Route retain mode flag. */  int retain_mode = 0; @@ -77,119 +67,110 @@ struct thread_master *master;  static struct frr_daemon_info ripd_di;  /* SIGHUP handler. */ -static void  -sighup (void) +static void sighup(void)  { -  zlog_info ("SIGHUP received"); -  rip_clean (); -  rip_reset (); -  zlog_info ("ripd restarting!"); +	zlog_info("SIGHUP received"); +	rip_clean(); +	rip_reset(); +	zlog_info("ripd restarting!"); -  /* Reload config file. */ -  vty_read_config (ripd_di.config_file, config_default); +	/* Reload config file. */ +	vty_read_config(ripd_di.config_file, config_default); -  /* Try to return to normal operation. */ +	/* Try to return to normal operation. */  }  /* SIGINT handler. */ -static void -sigint (void) +static void sigint(void)  { -  zlog_notice ("Terminating on signal"); +	zlog_notice("Terminating on signal"); -  if (! retain_mode) -    rip_clean (); +	if (!retain_mode) +		rip_clean(); -  rip_zclient_stop (); +	rip_zclient_stop(); -  exit (0); +	exit(0);  }  /* SIGUSR1 handler. */ -static void -sigusr1 (void) +static void sigusr1(void)  { -  zlog_rotate(); +	zlog_rotate();  } -static struct quagga_signal_t ripd_signals[] = -{ -  {  -    .signal = SIGHUP, -    .handler = &sighup, -  }, -  {  -    .signal = SIGUSR1, -    .handler = &sigusr1, -  }, -  { -    .signal = SIGINT, -    .handler = &sigint, -  }, -  { -    .signal = SIGTERM, -    .handler = &sigint, -  }, -};   - -FRR_DAEMON_INFO(ripd, RIP, -	.vty_port = RIP_VTY_PORT, - -	.proghelp = "Implementation of the RIP routing protocol.", - -	.signals = ripd_signals, -	.n_signals = array_size(ripd_signals), - -	.privs = &ripd_privs, -) +static struct quagga_signal_t ripd_signals[] = { +	{ +		.signal = SIGHUP, +		.handler = &sighup, +	}, +	{ +		.signal = SIGUSR1, +		.handler = &sigusr1, +	}, +	{ +		.signal = SIGINT, +		.handler = &sigint, +	}, +	{ +		.signal = SIGTERM, +		.handler = &sigint, +	}, +}; -/* Main routine of ripd. */ -int -main (int argc, char **argv) -{ -  frr_preinit (&ripd_di, argc, argv); -  frr_opt_add ("r", longopts, -	"  -r, --retain       When program terminates, retain added route by ripd.\n"); +FRR_DAEMON_INFO(ripd, RIP, .vty_port = RIP_VTY_PORT, -  /* Command line option parse. */ -  while (1)  -    { -      int opt; +		.proghelp = "Implementation of the RIP routing protocol.", -      opt = frr_getopt (argc, argv, NULL); -     -      if (opt == EOF) -	break; +		.signals = ripd_signals, .n_signals = array_size(ripd_signals), -      switch (opt)  -	{ -	case 0: -	  break; -	case 'r': -	  retain_mode = 1; -	  break; -	default: -	  frr_help_exit (1); -	  break; +		.privs = &ripd_privs, ) + +/* Main routine of ripd. */ +int main(int argc, char **argv) +{ +	frr_preinit(&ripd_di, argc, argv); +	frr_opt_add( +		"r", longopts, +		"  -r, --retain       When program terminates, retain added route by ripd.\n"); + +	/* Command line option parse. */ +	while (1) { +		int opt; + +		opt = frr_getopt(argc, argv, NULL); + +		if (opt == EOF) +			break; + +		switch (opt) { +		case 0: +			break; +		case 'r': +			retain_mode = 1; +			break; +		default: +			frr_help_exit(1); +			break; +		}  	} -    } -  /* Prepare master thread. */ -  master = frr_init (); +	/* Prepare master thread. */ +	master = frr_init(); -  /* Library initialization. */ -  keychain_init (); -  vrf_init (NULL, NULL, NULL, NULL); +	/* Library initialization. */ +	keychain_init(); +	vrf_init(NULL, NULL, NULL, NULL); -  /* RIP related initialization. */ -  rip_init (); -  rip_if_init (); -  rip_zclient_init(master); -  rip_peer_init (); +	/* RIP related initialization. */ +	rip_init(); +	rip_if_init(); +	rip_zclient_init(master); +	rip_peer_init(); -  frr_config_fork (); -  frr_run (master); +	frr_config_fork(); +	frr_run(master); -  /* Not reached. */ -  return (0); +	/* Not reached. */ +	return (0);  } diff --git a/ripd/rip_memory.c b/ripd/rip_memory.c index 662a6ccedd..4cdd3df048 100644 --- a/ripd/rip_memory.c +++ b/ripd/rip_memory.c @@ -26,9 +26,9 @@  #include "rip_memory.h"  DEFINE_MGROUP(RIPD, "ripd") -DEFINE_MTYPE(RIPD, RIP,             "RIP structure") -DEFINE_MTYPE(RIPD, RIP_INFO,        "RIP route info") -DEFINE_MTYPE(RIPD, RIP_INTERFACE,   "RIP interface") -DEFINE_MTYPE(RIPD, RIP_PEER,        "RIP peer") +DEFINE_MTYPE(RIPD, RIP, "RIP structure") +DEFINE_MTYPE(RIPD, RIP_INFO, "RIP route info") +DEFINE_MTYPE(RIPD, RIP_INTERFACE, "RIP interface") +DEFINE_MTYPE(RIPD, RIP_PEER, "RIP peer")  DEFINE_MTYPE(RIPD, RIP_OFFSET_LIST, "RIP offset list") -DEFINE_MTYPE(RIPD, RIP_DISTANCE,    "RIP distance") +DEFINE_MTYPE(RIPD, RIP_DISTANCE, "RIP distance") diff --git a/ripd/rip_offset.c b/ripd/rip_offset.c index 63f93d1391..6b539046f5 100644 --- a/ripd/rip_offset.c +++ b/ripd/rip_offset.c @@ -33,165 +33,148 @@  #define RIP_OFFSET_LIST_OUT 1  #define RIP_OFFSET_LIST_MAX 2 -struct rip_offset_list -{ -  char *ifname; - -  struct  -  { -    char *alist_name; -    /* struct access_list *alist; */ -    int metric; -  } direct[RIP_OFFSET_LIST_MAX]; +struct rip_offset_list { +	char *ifname; + +	struct { +		char *alist_name; +		/* struct access_list *alist; */ +		int metric; +	} direct[RIP_OFFSET_LIST_MAX];  };  static struct list *rip_offset_list_master; -static int -strcmp_safe (const char *s1, const char *s2) +static int strcmp_safe(const char *s1, const char *s2)  { -  if (s1 == NULL && s2 == NULL) -    return 0; -  if (s1 == NULL) -    return -1; -  if (s2 == NULL) -    return 1; -  return strcmp (s1, s2); +	if (s1 == NULL && s2 == NULL) +		return 0; +	if (s1 == NULL) +		return -1; +	if (s2 == NULL) +		return 1; +	return strcmp(s1, s2);  } -static struct rip_offset_list * -rip_offset_list_new (void) +static struct rip_offset_list *rip_offset_list_new(void)  { -  return XCALLOC (MTYPE_RIP_OFFSET_LIST, sizeof (struct rip_offset_list)); +	return XCALLOC(MTYPE_RIP_OFFSET_LIST, sizeof(struct rip_offset_list));  } -static void -rip_offset_list_free (struct rip_offset_list *offset) +static void rip_offset_list_free(struct rip_offset_list *offset)  { -  XFREE (MTYPE_RIP_OFFSET_LIST, offset); +	XFREE(MTYPE_RIP_OFFSET_LIST, offset);  } -static struct rip_offset_list * -rip_offset_list_lookup (const char *ifname) +static struct rip_offset_list *rip_offset_list_lookup(const char *ifname)  { -  struct rip_offset_list *offset; -  struct listnode *node, *nnode; +	struct rip_offset_list *offset; +	struct listnode *node, *nnode; -  for (ALL_LIST_ELEMENTS (rip_offset_list_master, node, nnode, offset)) -    { -      if (strcmp_safe (offset->ifname, ifname) == 0) -	return offset; -    } -  return NULL; +	for (ALL_LIST_ELEMENTS(rip_offset_list_master, node, nnode, offset)) { +		if (strcmp_safe(offset->ifname, ifname) == 0) +			return offset; +	} +	return NULL;  } -static struct rip_offset_list * -rip_offset_list_get (const char *ifname) +static struct rip_offset_list *rip_offset_list_get(const char *ifname)  { -  struct rip_offset_list *offset; -   -  offset = rip_offset_list_lookup (ifname); -  if (offset) -    return offset; - -  offset = rip_offset_list_new (); -  if (ifname) -    offset->ifname = strdup (ifname); -  listnode_add_sort (rip_offset_list_master, offset); - -  return offset; +	struct rip_offset_list *offset; + +	offset = rip_offset_list_lookup(ifname); +	if (offset) +		return offset; + +	offset = rip_offset_list_new(); +	if (ifname) +		offset->ifname = strdup(ifname); +	listnode_add_sort(rip_offset_list_master, offset); + +	return offset;  } -static int -rip_offset_list_set (struct vty *vty, const char *alist, const char *direct_str, -		     const char *metric_str, const char *ifname) +static int rip_offset_list_set(struct vty *vty, const char *alist, +			       const char *direct_str, const char *metric_str, +			       const char *ifname)  { -  int direct; -  int metric; -  struct rip_offset_list *offset; - -  /* Check direction. */ -  if (strncmp (direct_str, "i", 1) == 0) -    direct = RIP_OFFSET_LIST_IN; -  else if (strncmp (direct_str, "o", 1) == 0) -    direct = RIP_OFFSET_LIST_OUT; -  else -    { -      vty_out (vty, "Invalid direction: %s\n", direct_str); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* Check metric. */ -  metric = atoi (metric_str); -  if (metric < 0 || metric > 16) -    { -      vty_out (vty, "Invalid metric: %s\n", metric_str); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* Get offset-list structure with interface name. */ -  offset = rip_offset_list_get (ifname); - -  if (offset->direct[direct].alist_name) -    free (offset->direct[direct].alist_name); -  offset->direct[direct].alist_name = strdup (alist); -  offset->direct[direct].metric = metric; - -  return CMD_SUCCESS; +	int direct; +	int metric; +	struct rip_offset_list *offset; + +	/* Check direction. */ +	if (strncmp(direct_str, "i", 1) == 0) +		direct = RIP_OFFSET_LIST_IN; +	else if (strncmp(direct_str, "o", 1) == 0) +		direct = RIP_OFFSET_LIST_OUT; +	else { +		vty_out(vty, "Invalid direction: %s\n", direct_str); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* Check metric. */ +	metric = atoi(metric_str); +	if (metric < 0 || metric > 16) { +		vty_out(vty, "Invalid metric: %s\n", metric_str); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* Get offset-list structure with interface name. */ +	offset = rip_offset_list_get(ifname); + +	if (offset->direct[direct].alist_name) +		free(offset->direct[direct].alist_name); +	offset->direct[direct].alist_name = strdup(alist); +	offset->direct[direct].metric = metric; + +	return CMD_SUCCESS;  } -static int -rip_offset_list_unset (struct vty *vty, const char *alist, -		       const char *direct_str, const char *metric_str, -		       const char *ifname) +static int rip_offset_list_unset(struct vty *vty, const char *alist, +				 const char *direct_str, const char *metric_str, +				 const char *ifname)  { -  int direct; -  int metric; -  struct rip_offset_list *offset; - -  /* Check direction. */ -  if (strncmp (direct_str, "i", 1) == 0) -    direct = RIP_OFFSET_LIST_IN; -  else if (strncmp (direct_str, "o", 1) == 0) -    direct = RIP_OFFSET_LIST_OUT; -  else -    { -      vty_out (vty, "Invalid direction: %s\n", direct_str); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* Check metric. */ -  metric = atoi (metric_str); -  if (metric < 0 || metric > 16) -    { -      vty_out (vty, "Invalid metric: %s\n", metric_str); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* Get offset-list structure with interface name. */ -  offset = rip_offset_list_lookup (ifname); - -  if (offset) -    { -      if (offset->direct[direct].alist_name) -	free (offset->direct[direct].alist_name); -      offset->direct[direct].alist_name = NULL; - -      if (offset->direct[RIP_OFFSET_LIST_IN].alist_name == NULL && -	  offset->direct[RIP_OFFSET_LIST_OUT].alist_name == NULL) -	{ -	  listnode_delete (rip_offset_list_master, offset); -	  if (offset->ifname) -	    free (offset->ifname); -	  rip_offset_list_free (offset); +	int direct; +	int metric; +	struct rip_offset_list *offset; + +	/* Check direction. */ +	if (strncmp(direct_str, "i", 1) == 0) +		direct = RIP_OFFSET_LIST_IN; +	else if (strncmp(direct_str, "o", 1) == 0) +		direct = RIP_OFFSET_LIST_OUT; +	else { +		vty_out(vty, "Invalid direction: %s\n", direct_str); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* Check metric. */ +	metric = atoi(metric_str); +	if (metric < 0 || metric > 16) { +		vty_out(vty, "Invalid metric: %s\n", metric_str); +		return CMD_WARNING_CONFIG_FAILED;  	} -    } -  else -    { -      vty_out (vty, "Can't find offset-list\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } -  return CMD_SUCCESS; + +	/* Get offset-list structure with interface name. */ +	offset = rip_offset_list_lookup(ifname); + +	if (offset) { +		if (offset->direct[direct].alist_name) +			free(offset->direct[direct].alist_name); +		offset->direct[direct].alist_name = NULL; + +		if (offset->direct[RIP_OFFSET_LIST_IN].alist_name == NULL +		    && offset->direct[RIP_OFFSET_LIST_OUT].alist_name == NULL) { +			listnode_delete(rip_offset_list_master, offset); +			if (offset->ifname) +				free(offset->ifname); +			rip_offset_list_free(offset); +		} +	} else { +		vty_out(vty, "Can't find offset-list\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} +	return CMD_SUCCESS;  }  #define OFFSET_LIST_IN_NAME(O)  ((O)->direct[RIP_OFFSET_LIST_IN].alist_name) @@ -201,82 +184,78 @@ rip_offset_list_unset (struct vty *vty, const char *alist,  #define OFFSET_LIST_OUT_METRIC(O)  ((O)->direct[RIP_OFFSET_LIST_OUT].metric)  /* If metric is modifed return 1. */ -int -rip_offset_list_apply_in (struct prefix_ipv4 *p, struct interface *ifp, -			  u_int32_t *metric) +int rip_offset_list_apply_in(struct prefix_ipv4 *p, struct interface *ifp, +			     u_int32_t *metric)  { -  struct rip_offset_list *offset; -  struct access_list *alist; - -  /* Look up offset-list with interface name. */ -  offset = rip_offset_list_lookup (ifp->name); -  if (offset && OFFSET_LIST_IN_NAME (offset)) -    { -      alist = access_list_lookup (AFI_IP, OFFSET_LIST_IN_NAME (offset)); - -      if (alist  -	  && access_list_apply (alist, (struct prefix *)p) == FILTER_PERMIT) -	{ -	  *metric += OFFSET_LIST_IN_METRIC (offset); -	  return 1; +	struct rip_offset_list *offset; +	struct access_list *alist; + +	/* Look up offset-list with interface name. */ +	offset = rip_offset_list_lookup(ifp->name); +	if (offset && OFFSET_LIST_IN_NAME(offset)) { +		alist = access_list_lookup(AFI_IP, OFFSET_LIST_IN_NAME(offset)); + +		if (alist +		    && access_list_apply(alist, (struct prefix *)p) +			       == FILTER_PERMIT) { +			*metric += OFFSET_LIST_IN_METRIC(offset); +			return 1; +		} +		return 0;  	} -      return 0; -    } -  /* Look up offset-list without interface name. */ -  offset = rip_offset_list_lookup (NULL); -  if (offset && OFFSET_LIST_IN_NAME (offset)) -    { -      alist = access_list_lookup (AFI_IP, OFFSET_LIST_IN_NAME (offset)); - -      if (alist  -	  && access_list_apply (alist, (struct prefix *)p) == FILTER_PERMIT) -	{ -	  *metric += OFFSET_LIST_IN_METRIC (offset); -	  return 1; +	/* Look up offset-list without interface name. */ +	offset = rip_offset_list_lookup(NULL); +	if (offset && OFFSET_LIST_IN_NAME(offset)) { +		alist = access_list_lookup(AFI_IP, OFFSET_LIST_IN_NAME(offset)); + +		if (alist +		    && access_list_apply(alist, (struct prefix *)p) +			       == FILTER_PERMIT) { +			*metric += OFFSET_LIST_IN_METRIC(offset); +			return 1; +		} +		return 0;  	} -      return 0; -    } -  return 0; +	return 0;  }  /* If metric is modifed return 1. */ -int -rip_offset_list_apply_out (struct prefix_ipv4 *p, struct interface *ifp, -			  u_int32_t *metric) +int rip_offset_list_apply_out(struct prefix_ipv4 *p, struct interface *ifp, +			      u_int32_t *metric)  { -  struct rip_offset_list *offset; -  struct access_list *alist; - -  /* Look up offset-list with interface name. */ -  offset = rip_offset_list_lookup (ifp->name); -  if (offset && OFFSET_LIST_OUT_NAME (offset)) -    { -      alist = access_list_lookup (AFI_IP, OFFSET_LIST_OUT_NAME (offset)); - -      if (alist  -	  && access_list_apply (alist, (struct prefix *)p) == FILTER_PERMIT) -	{ -	  *metric += OFFSET_LIST_OUT_METRIC (offset); -	  return 1; +	struct rip_offset_list *offset; +	struct access_list *alist; + +	/* Look up offset-list with interface name. */ +	offset = rip_offset_list_lookup(ifp->name); +	if (offset && OFFSET_LIST_OUT_NAME(offset)) { +		alist = access_list_lookup(AFI_IP, +					   OFFSET_LIST_OUT_NAME(offset)); + +		if (alist +		    && access_list_apply(alist, (struct prefix *)p) +			       == FILTER_PERMIT) { +			*metric += OFFSET_LIST_OUT_METRIC(offset); +			return 1; +		} +		return 0;  	} -      return 0; -    } - -  /* Look up offset-list without interface name. */ -  offset = rip_offset_list_lookup (NULL); -  if (offset && OFFSET_LIST_OUT_NAME (offset)) -    { -      alist = access_list_lookup (AFI_IP, OFFSET_LIST_OUT_NAME (offset)); - -      if (alist  -	  && access_list_apply (alist, (struct prefix *)p) == FILTER_PERMIT) -	{ -	  *metric += OFFSET_LIST_OUT_METRIC (offset); -	  return 1; + +	/* Look up offset-list without interface name. */ +	offset = rip_offset_list_lookup(NULL); +	if (offset && OFFSET_LIST_OUT_NAME(offset)) { +		alist = access_list_lookup(AFI_IP, +					   OFFSET_LIST_OUT_NAME(offset)); + +		if (alist +		    && access_list_apply(alist, (struct prefix *)p) +			       == FILTER_PERMIT) { +			*metric += OFFSET_LIST_OUT_METRIC(offset); +			return 1; +		} +		return 0;  	} -      return 0; -    } -  return 0; +	return 0;  }  DEFUN (rip_offset_list, @@ -288,10 +267,12 @@ DEFUN (rip_offset_list,         "For outgoing updates\n"         "Metric value\n")  { -  int idx_word = 1; -  int idx_in_out = 2; -  int idx_number = 3; -  return rip_offset_list_set (vty, argv[idx_word]->arg, argv[idx_in_out]->arg, argv[idx_number]->arg, NULL); +	int idx_word = 1; +	int idx_in_out = 2; +	int idx_number = 3; +	return rip_offset_list_set(vty, argv[idx_word]->arg, +				   argv[idx_in_out]->arg, argv[idx_number]->arg, +				   NULL);  }  DEFUN (rip_offset_list_ifname, @@ -304,11 +285,13 @@ DEFUN (rip_offset_list_ifname,         "Metric value\n"         "Interface to match\n")  { -  int idx_word = 1; -  int idx_in_out = 2; -  int idx_number = 3; -  int idx_ifname = 4; -  return rip_offset_list_set (vty, argv[idx_word]->arg, argv[idx_in_out]->arg, argv[idx_number]->arg, argv[idx_ifname]->arg); +	int idx_word = 1; +	int idx_in_out = 2; +	int idx_number = 3; +	int idx_ifname = 4; +	return rip_offset_list_set(vty, argv[idx_word]->arg, +				   argv[idx_in_out]->arg, argv[idx_number]->arg, +				   argv[idx_ifname]->arg);  }  DEFUN (no_rip_offset_list, @@ -321,10 +304,12 @@ DEFUN (no_rip_offset_list,         "For outgoing updates\n"         "Metric value\n")  { -  int idx_word = 2; -  int idx_in_out = 3; -  int idx_number = 4; -  return rip_offset_list_unset (vty, argv[idx_word]->arg, argv[idx_in_out]->arg, argv[idx_number]->arg, NULL); +	int idx_word = 2; +	int idx_in_out = 3; +	int idx_number = 4; +	return rip_offset_list_unset(vty, argv[idx_word]->arg, +				     argv[idx_in_out]->arg, +				     argv[idx_number]->arg, NULL);  }  DEFUN (no_rip_offset_list_ifname, @@ -338,87 +323,89 @@ DEFUN (no_rip_offset_list_ifname,         "Metric value\n"         "Interface to match\n")  { -  int idx_word = 2; -  int idx_in_out = 3; -  int idx_number = 4; -  int idx_ifname = 5; -  return rip_offset_list_unset (vty, argv[idx_word]->arg, argv[idx_in_out]->arg, argv[idx_number]->arg, argv[idx_ifname]->arg); +	int idx_word = 2; +	int idx_in_out = 3; +	int idx_number = 4; +	int idx_ifname = 5; +	return rip_offset_list_unset( +		vty, argv[idx_word]->arg, argv[idx_in_out]->arg, +		argv[idx_number]->arg, argv[idx_ifname]->arg);  } -static int -offset_list_cmp (struct rip_offset_list *o1, struct rip_offset_list *o2) +static int offset_list_cmp(struct rip_offset_list *o1, +			   struct rip_offset_list *o2)  { -  return strcmp_safe (o1->ifname, o2->ifname); +	return strcmp_safe(o1->ifname, o2->ifname);  } -static void -offset_list_del (struct rip_offset_list *offset) +static void offset_list_del(struct rip_offset_list *offset)  { -  if (OFFSET_LIST_IN_NAME (offset)) -    free (OFFSET_LIST_IN_NAME (offset)); -  if (OFFSET_LIST_OUT_NAME (offset)) -    free (OFFSET_LIST_OUT_NAME (offset)); -  if (offset->ifname) -    free (offset->ifname); -  rip_offset_list_free (offset); +	if (OFFSET_LIST_IN_NAME(offset)) +		free(OFFSET_LIST_IN_NAME(offset)); +	if (OFFSET_LIST_OUT_NAME(offset)) +		free(OFFSET_LIST_OUT_NAME(offset)); +	if (offset->ifname) +		free(offset->ifname); +	rip_offset_list_free(offset);  } -void -rip_offset_init () +void rip_offset_init()  { -  rip_offset_list_master = list_new (); -  rip_offset_list_master->cmp = (int (*)(void *, void *)) offset_list_cmp; -  rip_offset_list_master->del = (void (*)(void *)) offset_list_del; - -  install_element (RIP_NODE, &rip_offset_list_cmd); -  install_element (RIP_NODE, &rip_offset_list_ifname_cmd); -  install_element (RIP_NODE, &no_rip_offset_list_cmd); -  install_element (RIP_NODE, &no_rip_offset_list_ifname_cmd); +	rip_offset_list_master = list_new(); +	rip_offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp; +	rip_offset_list_master->del = (void (*)(void *))offset_list_del; + +	install_element(RIP_NODE, &rip_offset_list_cmd); +	install_element(RIP_NODE, &rip_offset_list_ifname_cmd); +	install_element(RIP_NODE, &no_rip_offset_list_cmd); +	install_element(RIP_NODE, &no_rip_offset_list_ifname_cmd);  } -void -rip_offset_clean () +void rip_offset_clean()  { -  list_delete (rip_offset_list_master); +	list_delete(rip_offset_list_master); -  rip_offset_list_master = list_new (); -  rip_offset_list_master->cmp = (int (*)(void *, void *)) offset_list_cmp; -  rip_offset_list_master->del = (void (*)(void *)) offset_list_del; +	rip_offset_list_master = list_new(); +	rip_offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp; +	rip_offset_list_master->del = (void (*)(void *))offset_list_del;  } -int -config_write_rip_offset_list (struct vty *vty) +int config_write_rip_offset_list(struct vty *vty)  { -  struct listnode *node, *nnode; -  struct rip_offset_list *offset; - -  for (ALL_LIST_ELEMENTS (rip_offset_list_master, node, nnode, offset)) -    { -      if (! offset->ifname) -	{ -	  if (offset->direct[RIP_OFFSET_LIST_IN].alist_name) -	    vty_out (vty, " offset-list %s in %d\n", -		     offset->direct[RIP_OFFSET_LIST_IN].alist_name, -		     offset->direct[RIP_OFFSET_LIST_IN].metric); -	  if (offset->direct[RIP_OFFSET_LIST_OUT].alist_name) -	    vty_out (vty, " offset-list %s out %d\n", -		     offset->direct[RIP_OFFSET_LIST_OUT].alist_name, -		     offset->direct[RIP_OFFSET_LIST_OUT].metric); -	} -      else -	{ -	  if (offset->direct[RIP_OFFSET_LIST_IN].alist_name) -	    vty_out (vty, " offset-list %s in %d %s\n", -		     offset->direct[RIP_OFFSET_LIST_IN].alist_name, -		     offset->direct[RIP_OFFSET_LIST_IN].metric, -		     offset->ifname); -	  if (offset->direct[RIP_OFFSET_LIST_OUT].alist_name) -	    vty_out (vty, " offset-list %s out %d %s\n", -		     offset->direct[RIP_OFFSET_LIST_OUT].alist_name, -		     offset->direct[RIP_OFFSET_LIST_OUT].metric, -		     offset->ifname); +	struct listnode *node, *nnode; +	struct rip_offset_list *offset; + +	for (ALL_LIST_ELEMENTS(rip_offset_list_master, node, nnode, offset)) { +		if (!offset->ifname) { +			if (offset->direct[RIP_OFFSET_LIST_IN].alist_name) +				vty_out(vty, " offset-list %s in %d\n", +					offset->direct[RIP_OFFSET_LIST_IN] +						.alist_name, +					offset->direct[RIP_OFFSET_LIST_IN] +						.metric); +			if (offset->direct[RIP_OFFSET_LIST_OUT].alist_name) +				vty_out(vty, " offset-list %s out %d\n", +					offset->direct[RIP_OFFSET_LIST_OUT] +						.alist_name, +					offset->direct[RIP_OFFSET_LIST_OUT] +						.metric); +		} else { +			if (offset->direct[RIP_OFFSET_LIST_IN].alist_name) +				vty_out(vty, " offset-list %s in %d %s\n", +					offset->direct[RIP_OFFSET_LIST_IN] +						.alist_name, +					offset->direct[RIP_OFFSET_LIST_IN] +						.metric, +					offset->ifname); +			if (offset->direct[RIP_OFFSET_LIST_OUT].alist_name) +				vty_out(vty, " offset-list %s out %d %s\n", +					offset->direct[RIP_OFFSET_LIST_OUT] +						.alist_name, +					offset->direct[RIP_OFFSET_LIST_OUT] +						.metric, +					offset->ifname); +		}  	} -    } -  return 0; +	return 0;  } diff --git a/ripd/rip_peer.c b/ripd/rip_peer.c index 7f494a0981..763bfc142c 100644 --- a/ripd/rip_peer.c +++ b/ripd/rip_peer.c @@ -32,175 +32,155 @@  /* Linked list of RIP peer. */  struct list *peer_list; -static struct rip_peer * -rip_peer_new (void) +static struct rip_peer *rip_peer_new(void)  { -  return XCALLOC (MTYPE_RIP_PEER, sizeof (struct rip_peer)); +	return XCALLOC(MTYPE_RIP_PEER, sizeof(struct rip_peer));  } -static void -rip_peer_free (struct rip_peer *peer) +static void rip_peer_free(struct rip_peer *peer)  { -  XFREE (MTYPE_RIP_PEER, peer); +	XFREE(MTYPE_RIP_PEER, peer);  } -struct rip_peer * -rip_peer_lookup (struct in_addr *addr) +struct rip_peer *rip_peer_lookup(struct in_addr *addr)  { -  struct rip_peer *peer; -  struct listnode *node, *nnode; - -  for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer)) -    { -      if (IPV4_ADDR_SAME (&peer->addr, addr)) -	return peer; -    } -  return NULL; +	struct rip_peer *peer; +	struct listnode *node, *nnode; + +	for (ALL_LIST_ELEMENTS(peer_list, node, nnode, peer)) { +		if (IPV4_ADDR_SAME(&peer->addr, addr)) +			return peer; +	} +	return NULL;  } -struct rip_peer * -rip_peer_lookup_next (struct in_addr *addr) +struct rip_peer *rip_peer_lookup_next(struct in_addr *addr)  { -  struct rip_peer *peer; -  struct listnode *node, *nnode; - -  for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer)) -    { -      if (htonl (peer->addr.s_addr) > htonl (addr->s_addr)) -	return peer; -    } -  return NULL; +	struct rip_peer *peer; +	struct listnode *node, *nnode; + +	for (ALL_LIST_ELEMENTS(peer_list, node, nnode, peer)) { +		if (htonl(peer->addr.s_addr) > htonl(addr->s_addr)) +			return peer; +	} +	return NULL;  }  /* RIP peer is timeout. */ -static int -rip_peer_timeout (struct thread *t) +static int rip_peer_timeout(struct thread *t)  { -  struct rip_peer *peer; +	struct rip_peer *peer; -  peer = THREAD_ARG (t); -  listnode_delete (peer_list, peer); -  rip_peer_free (peer); +	peer = THREAD_ARG(t); +	listnode_delete(peer_list, peer); +	rip_peer_free(peer); -  return 0; +	return 0;  }  /* Get RIP peer.  At the same time update timeout thread. */ -static struct rip_peer * -rip_peer_get (struct in_addr *addr) +static struct rip_peer *rip_peer_get(struct in_addr *addr)  { -  struct rip_peer *peer; - -  peer = rip_peer_lookup (addr); - -  if (peer) -    { -      if (peer->t_timeout) -	thread_cancel (peer->t_timeout); -    } -  else -    { -      peer = rip_peer_new (); -      peer->addr = *addr; -      listnode_add_sort (peer_list, peer); -    } - -  /* Update timeout thread. */ -  peer->t_timeout = NULL; -  thread_add_timer(master, rip_peer_timeout, peer, RIP_PEER_TIMER_DEFAULT, -                   &peer->t_timeout); - -  /* Last update time set. */ -  time (&peer->uptime); -   -  return peer; +	struct rip_peer *peer; + +	peer = rip_peer_lookup(addr); + +	if (peer) { +		if (peer->t_timeout) +			thread_cancel(peer->t_timeout); +	} else { +		peer = rip_peer_new(); +		peer->addr = *addr; +		listnode_add_sort(peer_list, peer); +	} + +	/* Update timeout thread. */ +	peer->t_timeout = NULL; +	thread_add_timer(master, rip_peer_timeout, peer, RIP_PEER_TIMER_DEFAULT, +			 &peer->t_timeout); + +	/* Last update time set. */ +	time(&peer->uptime); + +	return peer;  } -void -rip_peer_update (struct sockaddr_in *from, u_char version) +void rip_peer_update(struct sockaddr_in *from, u_char version)  { -  struct rip_peer *peer; -  peer = rip_peer_get (&from->sin_addr); -  peer->version = version; +	struct rip_peer *peer; +	peer = rip_peer_get(&from->sin_addr); +	peer->version = version;  } -void -rip_peer_bad_route (struct sockaddr_in *from) +void rip_peer_bad_route(struct sockaddr_in *from)  { -  struct rip_peer *peer; -  peer = rip_peer_get (&from->sin_addr); -  peer->recv_badroutes++; +	struct rip_peer *peer; +	peer = rip_peer_get(&from->sin_addr); +	peer->recv_badroutes++;  } -void -rip_peer_bad_packet (struct sockaddr_in *from) +void rip_peer_bad_packet(struct sockaddr_in *from)  { -  struct rip_peer *peer; -  peer = rip_peer_get (&from->sin_addr); -  peer->recv_badpackets++; +	struct rip_peer *peer; +	peer = rip_peer_get(&from->sin_addr); +	peer->recv_badpackets++;  }  /* Display peer uptime. */ -static char * -rip_peer_uptime (struct rip_peer *peer, char *buf, size_t len) +static char *rip_peer_uptime(struct rip_peer *peer, char *buf, size_t len)  { -  time_t uptime; -  struct tm *tm; - -  /* If there is no connection has been done before print `never'. */ -  if (peer->uptime == 0) -    { -      snprintf (buf, len, "never   "); -      return buf; -    } - -  /* Get current time. */ -  uptime = time (NULL); -  uptime -= peer->uptime; -  tm = gmtime (&uptime); - -  /* Making formatted timer strings. */ +	time_t uptime; +	struct tm *tm; + +	/* If there is no connection has been done before print `never'. */ +	if (peer->uptime == 0) { +		snprintf(buf, len, "never   "); +		return buf; +	} + +	/* Get current time. */ +	uptime = time(NULL); +	uptime -= peer->uptime; +	tm = gmtime(&uptime); + +/* Making formatted timer strings. */  #define ONE_DAY_SECOND 60*60*24  #define ONE_WEEK_SECOND 60*60*24*7 -  if (uptime < ONE_DAY_SECOND) -    snprintf (buf, len, "%02d:%02d:%02d",  -	      tm->tm_hour, tm->tm_min, tm->tm_sec); -  else if (uptime < ONE_WEEK_SECOND) -    snprintf (buf, len, "%dd%02dh%02dm",  -	      tm->tm_yday, tm->tm_hour, tm->tm_min); -  else -    snprintf (buf, len, "%02dw%dd%02dh",  -	      tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); -  return buf; +	if (uptime < ONE_DAY_SECOND) +		snprintf(buf, len, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, +			 tm->tm_sec); +	else if (uptime < ONE_WEEK_SECOND) +		snprintf(buf, len, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, +			 tm->tm_min); +	else +		snprintf(buf, len, "%02dw%dd%02dh", tm->tm_yday / 7, +			 tm->tm_yday - ((tm->tm_yday / 7) * 7), tm->tm_hour); +	return buf;  } -void -rip_peer_display (struct vty *vty) +void rip_peer_display(struct vty *vty)  { -  struct rip_peer *peer; -  struct listnode *node, *nnode; +	struct rip_peer *peer; +	struct listnode *node, *nnode;  #define RIP_UPTIME_LEN 25 -  char timebuf[RIP_UPTIME_LEN]; - -  for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer)) -    { -      vty_out (vty, "    %-16s %9d %9d %9d   %s\n", inet_ntoa (peer->addr), -	       peer->recv_badpackets, peer->recv_badroutes, -	       ZEBRA_RIP_DISTANCE_DEFAULT, -	       rip_peer_uptime(peer, timebuf, RIP_UPTIME_LEN)); -    } +	char timebuf[RIP_UPTIME_LEN]; + +	for (ALL_LIST_ELEMENTS(peer_list, node, nnode, peer)) { +		vty_out(vty, "    %-16s %9d %9d %9d   %s\n", +			inet_ntoa(peer->addr), peer->recv_badpackets, +			peer->recv_badroutes, ZEBRA_RIP_DISTANCE_DEFAULT, +			rip_peer_uptime(peer, timebuf, RIP_UPTIME_LEN)); +	}  } -static int -rip_peer_list_cmp (struct rip_peer *p1, struct rip_peer *p2) +static int rip_peer_list_cmp(struct rip_peer *p1, struct rip_peer *p2)  { -  return htonl (p1->addr.s_addr) > htonl (p2->addr.s_addr); +	return htonl(p1->addr.s_addr) > htonl(p2->addr.s_addr);  } -void -rip_peer_init (void) +void rip_peer_init(void)  { -  peer_list = list_new (); -  peer_list->cmp = (int (*)(void *, void *)) rip_peer_list_cmp; +	peer_list = list_new(); +	peer_list->cmp = (int (*)(void *, void *))rip_peer_list_cmp;  } diff --git a/ripd/rip_routemap.c b/ripd/rip_routemap.c index 3f1495c0f0..7255df5e67 100644 --- a/ripd/rip_routemap.c +++ b/ripd/rip_routemap.c @@ -28,620 +28,552 @@  #include "command.h"  #include "filter.h"  #include "log.h" -#include "sockunion.h"		/* for inet_aton () */ +#include "sockunion.h" /* for inet_aton () */  #include "plist.h"  #include "vrf.h"  #include "ripd/ripd.h" -struct rip_metric_modifier -{ -  enum  -  { -    metric_increment, -    metric_decrement, -    metric_absolute -  } type; - -  u_char metric; +struct rip_metric_modifier { +	enum { metric_increment, metric_decrement, metric_absolute } type; + +	u_char metric;  };  /* Hook function for updating route_map assignment. */  /* ARGSUSED */ -static void -rip_route_map_update (const char *notused) +static void rip_route_map_update(const char *notused)  { -  int i; - -  if (rip)  -    { -      for (i = 0; i < ZEBRA_ROUTE_MAX; i++)  -	{ -	  if (rip->route_map[i].name) -	    rip->route_map[i].map =  -	      route_map_lookup_by_name (rip->route_map[i].name); +	int i; + +	if (rip) { +		for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { +			if (rip->route_map[i].name) +				rip->route_map[i].map = +					route_map_lookup_by_name( +						rip->route_map[i].name); +		}  	} -    }  }  /* `match metric METRIC' */  /* Match function return 1 if match is success else return zero. */ -static route_map_result_t -route_match_metric (void *rule, struct prefix *prefix,  -		    route_map_object_t type, void *object) -{ -  u_int32_t *metric; -  u_int32_t  check; -  struct rip_info *rinfo; - -  if (type == RMAP_RIP) -    { -      metric = rule; -      rinfo = object; -     -      /* If external metric is available, the route-map should -         work on this one (for redistribute purpose)  */ -      check = (rinfo->external_metric) ? rinfo->external_metric : -                                         rinfo->metric; -      if (check == *metric) -	return RMAP_MATCH; -      else +static route_map_result_t route_match_metric(void *rule, struct prefix *prefix, +					     route_map_object_t type, +					     void *object) +{ +	u_int32_t *metric; +	u_int32_t check; +	struct rip_info *rinfo; + +	if (type == RMAP_RIP) { +		metric = rule; +		rinfo = object; + +		/* If external metric is available, the route-map should +		   work on this one (for redistribute purpose)  */ +		check = (rinfo->external_metric) ? rinfo->external_metric +						 : rinfo->metric; +		if (check == *metric) +			return RMAP_MATCH; +		else +			return RMAP_NOMATCH; +	}  	return RMAP_NOMATCH; -    } -  return RMAP_NOMATCH;  }  /* Route map `match metric' match statement. `arg' is METRIC value */ -static void * -route_match_metric_compile (const char *arg) +static void *route_match_metric_compile(const char *arg)  { -  u_int32_t *metric; +	u_int32_t *metric; -  metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); -  *metric = atoi (arg); +	metric = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t)); +	*metric = atoi(arg); -  if(*metric > 0) -    return metric; +	if (*metric > 0) +		return metric; -  XFREE (MTYPE_ROUTE_MAP_COMPILED, metric); -  return NULL; +	XFREE(MTYPE_ROUTE_MAP_COMPILED, metric); +	return NULL;  }  /* Free route map's compiled `match metric' value. */ -static void -route_match_metric_free (void *rule) +static void route_match_metric_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  }  /* Route map commands for metric matching. */ -struct route_map_rule_cmd route_match_metric_cmd = -{ -  "metric", -  route_match_metric, -  route_match_metric_compile, -  route_match_metric_free -}; +struct route_map_rule_cmd route_match_metric_cmd = { +	"metric", route_match_metric, route_match_metric_compile, +	route_match_metric_free};  /* `match interface IFNAME' */  /* Match function return 1 if match is success else return zero. */ -static route_map_result_t -route_match_interface (void *rule, struct prefix *prefix, -		       route_map_object_t type, void *object) +static route_map_result_t route_match_interface(void *rule, +						struct prefix *prefix, +						route_map_object_t type, +						void *object)  { -  struct rip_info *rinfo; -  struct interface *ifp; -  char *ifname; +	struct rip_info *rinfo; +	struct interface *ifp; +	char *ifname; -  if (type == RMAP_RIP) -    { -      ifname = rule; -      ifp = if_lookup_by_name(ifname, VRF_DEFAULT); +	if (type == RMAP_RIP) { +		ifname = rule; +		ifp = if_lookup_by_name(ifname, VRF_DEFAULT); -      if (!ifp) -	return RMAP_NOMATCH; +		if (!ifp) +			return RMAP_NOMATCH; -      rinfo = object; +		rinfo = object; -      if (rinfo->ifindex_out == ifp->ifindex || rinfo->ifindex == ifp->ifindex) -	return RMAP_MATCH; -      else +		if (rinfo->ifindex_out == ifp->ifindex +		    || rinfo->ifindex == ifp->ifindex) +			return RMAP_MATCH; +		else +			return RMAP_NOMATCH; +	}  	return RMAP_NOMATCH; -    } -  return RMAP_NOMATCH;  }  /* Route map `match interface' match statement. `arg' is IFNAME value */  /* XXX I don`t know if I need to check does interface exist? */ -static void * -route_match_interface_compile (const char *arg) +static void *route_match_interface_compile(const char *arg)  { -  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); +	return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);  }  /* Free route map's compiled `match interface' value. */ -static void -route_match_interface_free (void *rule) +static void route_match_interface_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  }  /* Route map commands for interface matching. */ -struct route_map_rule_cmd route_match_interface_cmd = -{ -  "interface", -  route_match_interface, -  route_match_interface_compile, -  route_match_interface_free -}; +struct route_map_rule_cmd route_match_interface_cmd = { +	"interface", route_match_interface, route_match_interface_compile, +	route_match_interface_free};  /* `match ip next-hop IP_ACCESS_LIST' */  /* Match function return 1 if match is success else return zero. */ -static route_map_result_t -route_match_ip_next_hop (void *rule, struct prefix *prefix, -			route_map_object_t type, void *object) -{ -  struct access_list *alist; -  struct rip_info *rinfo; -  struct prefix_ipv4 p; - -  if (type == RMAP_RIP) -    { -      rinfo = object; -      p.family = AF_INET; -      p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from; -      p.prefixlen = IPV4_MAX_BITLEN; - -      alist = access_list_lookup (AFI_IP, (char *) rule); -      if (alist == NULL) +static route_map_result_t route_match_ip_next_hop(void *rule, +						  struct prefix *prefix, +						  route_map_object_t type, +						  void *object) +{ +	struct access_list *alist; +	struct rip_info *rinfo; +	struct prefix_ipv4 p; + +	if (type == RMAP_RIP) { +		rinfo = object; +		p.family = AF_INET; +		p.prefix = +			(rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from; +		p.prefixlen = IPV4_MAX_BITLEN; + +		alist = access_list_lookup(AFI_IP, (char *)rule); +		if (alist == NULL) +			return RMAP_NOMATCH; + +		return (access_list_apply(alist, &p) == FILTER_DENY +				? RMAP_NOMATCH +				: RMAP_MATCH); +	}  	return RMAP_NOMATCH; - -      return (access_list_apply (alist, &p) == FILTER_DENY ? -	      RMAP_NOMATCH : RMAP_MATCH); -    } -  return RMAP_NOMATCH;  }  /* Route map `ip next-hop' match statement.  `arg' should be     access-list name. */ -static void * -route_match_ip_next_hop_compile (const char *arg) +static void *route_match_ip_next_hop_compile(const char *arg)  { -  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); +	return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);  }  /* Free route map's compiled `. */ -static void -route_match_ip_next_hop_free (void *rule) +static void route_match_ip_next_hop_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  }  /* Route map commands for ip next-hop matching. */ -static struct route_map_rule_cmd route_match_ip_next_hop_cmd = -{ -  "ip next-hop", -  route_match_ip_next_hop, -  route_match_ip_next_hop_compile, -  route_match_ip_next_hop_free -}; +static struct route_map_rule_cmd route_match_ip_next_hop_cmd = { +	"ip next-hop", route_match_ip_next_hop, route_match_ip_next_hop_compile, +	route_match_ip_next_hop_free};  /* `match ip next-hop prefix-list PREFIX_LIST' */  static route_map_result_t -route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix, -                                    route_map_object_t type, void *object) +route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix, +				    route_map_object_t type, void *object)  { -  struct prefix_list *plist; -  struct rip_info *rinfo; -  struct prefix_ipv4 p; - -  if (type == RMAP_RIP) -    { -      rinfo = object; -      p.family = AF_INET; -      p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from; -      p.prefixlen = IPV4_MAX_BITLEN; - -      plist = prefix_list_lookup (AFI_IP, (char *) rule); -      if (plist == NULL) -        return RMAP_NOMATCH; - -      return (prefix_list_apply (plist, &p) == PREFIX_DENY ? -              RMAP_NOMATCH : RMAP_MATCH); -    } -  return RMAP_NOMATCH; +	struct prefix_list *plist; +	struct rip_info *rinfo; +	struct prefix_ipv4 p; + +	if (type == RMAP_RIP) { +		rinfo = object; +		p.family = AF_INET; +		p.prefix = +			(rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from; +		p.prefixlen = IPV4_MAX_BITLEN; + +		plist = prefix_list_lookup(AFI_IP, (char *)rule); +		if (plist == NULL) +			return RMAP_NOMATCH; + +		return (prefix_list_apply(plist, &p) == PREFIX_DENY +				? RMAP_NOMATCH +				: RMAP_MATCH); +	} +	return RMAP_NOMATCH;  } -static void * -route_match_ip_next_hop_prefix_list_compile (const char *arg) +static void *route_match_ip_next_hop_prefix_list_compile(const char *arg)  { -  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); +	return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);  } -static void -route_match_ip_next_hop_prefix_list_free (void *rule) +static void route_match_ip_next_hop_prefix_list_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  } -static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = -{ -  "ip next-hop prefix-list", -  route_match_ip_next_hop_prefix_list, -  route_match_ip_next_hop_prefix_list_compile, -  route_match_ip_next_hop_prefix_list_free -}; +static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = { +	"ip next-hop prefix-list", route_match_ip_next_hop_prefix_list, +	route_match_ip_next_hop_prefix_list_compile, +	route_match_ip_next_hop_prefix_list_free};  /* `match ip address IP_ACCESS_LIST' */  /* Match function should return 1 if match is success else return     zero. */ -static route_map_result_t -route_match_ip_address (void *rule, struct prefix *prefix,  -			route_map_object_t type, void *object) +static route_map_result_t route_match_ip_address(void *rule, +						 struct prefix *prefix, +						 route_map_object_t type, +						 void *object)  { -  struct access_list *alist; +	struct access_list *alist; -  if (type == RMAP_RIP) -    { -      alist = access_list_lookup (AFI_IP, (char *) rule); -      if (alist == NULL) +	if (type == RMAP_RIP) { +		alist = access_list_lookup(AFI_IP, (char *)rule); +		if (alist == NULL) +			return RMAP_NOMATCH; + +		return (access_list_apply(alist, prefix) == FILTER_DENY +				? RMAP_NOMATCH +				: RMAP_MATCH); +	}  	return RMAP_NOMATCH; -     -      return (access_list_apply (alist, prefix) == FILTER_DENY ? -	      RMAP_NOMATCH : RMAP_MATCH); -    } -  return RMAP_NOMATCH;  }  /* Route map `ip address' match statement.  `arg' should be     access-list name. */ -static void * -route_match_ip_address_compile (const char *arg) +static void *route_match_ip_address_compile(const char *arg)  { -  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); +	return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);  }  /* Free route map's compiled `ip address' value. */ -static void -route_match_ip_address_free (void *rule) +static void route_match_ip_address_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  }  /* Route map commands for ip address matching. */ -static struct route_map_rule_cmd route_match_ip_address_cmd = -{ -  "ip address", -  route_match_ip_address, -  route_match_ip_address_compile, -  route_match_ip_address_free -}; +static struct route_map_rule_cmd route_match_ip_address_cmd = { +	"ip address", route_match_ip_address, route_match_ip_address_compile, +	route_match_ip_address_free};  /* `match ip address prefix-list PREFIX_LIST' */  static route_map_result_t -route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,  -				    route_map_object_t type, void *object) +route_match_ip_address_prefix_list(void *rule, struct prefix *prefix, +				   route_map_object_t type, void *object)  { -  struct prefix_list *plist; +	struct prefix_list *plist; -  if (type == RMAP_RIP) -    { -      plist = prefix_list_lookup (AFI_IP, (char *) rule); -      if (plist == NULL) +	if (type == RMAP_RIP) { +		plist = prefix_list_lookup(AFI_IP, (char *)rule); +		if (plist == NULL) +			return RMAP_NOMATCH; + +		return (prefix_list_apply(plist, prefix) == PREFIX_DENY +				? RMAP_NOMATCH +				: RMAP_MATCH); +	}  	return RMAP_NOMATCH; -     -      return (prefix_list_apply (plist, prefix) == PREFIX_DENY ? -	      RMAP_NOMATCH : RMAP_MATCH); -    } -  return RMAP_NOMATCH;  } -static void * -route_match_ip_address_prefix_list_compile (const char *arg) +static void *route_match_ip_address_prefix_list_compile(const char *arg)  { -  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); +	return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);  } -static void -route_match_ip_address_prefix_list_free (void *rule) +static void route_match_ip_address_prefix_list_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  } -static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = -{ -  "ip address prefix-list", -  route_match_ip_address_prefix_list, -  route_match_ip_address_prefix_list_compile, -  route_match_ip_address_prefix_list_free -}; +static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = { +	"ip address prefix-list", route_match_ip_address_prefix_list, +	route_match_ip_address_prefix_list_compile, +	route_match_ip_address_prefix_list_free};  /* `match tag TAG' */  /* Match function return 1 if match is success else return zero. */ -static route_map_result_t -route_match_tag (void *rule, struct prefix *prefix,  -		    route_map_object_t type, void *object) -{ -  route_tag_t *tag; -  struct rip_info *rinfo; -  route_tag_t rinfo_tag; - -  if (type == RMAP_RIP) -    { -      tag = rule; -      rinfo = object; - -      /* The information stored by rinfo is host ordered. */ -      rinfo_tag = rinfo->tag; -      if (rinfo_tag == *tag) -	return RMAP_MATCH; -      else +static route_map_result_t route_match_tag(void *rule, struct prefix *prefix, +					  route_map_object_t type, void *object) +{ +	route_tag_t *tag; +	struct rip_info *rinfo; +	route_tag_t rinfo_tag; + +	if (type == RMAP_RIP) { +		tag = rule; +		rinfo = object; + +		/* The information stored by rinfo is host ordered. */ +		rinfo_tag = rinfo->tag; +		if (rinfo_tag == *tag) +			return RMAP_MATCH; +		else +			return RMAP_NOMATCH; +	}  	return RMAP_NOMATCH; -    } -  return RMAP_NOMATCH;  }  /* Route map commands for tag matching. */ -static struct route_map_rule_cmd route_match_tag_cmd = -{ -  "tag", -  route_match_tag, -  route_map_rule_tag_compile, -  route_map_rule_tag_free, +static struct route_map_rule_cmd route_match_tag_cmd = { +	"tag", route_match_tag, route_map_rule_tag_compile, +	route_map_rule_tag_free,  };  /* `set metric METRIC' */  /* Set metric to attribute. */ -static route_map_result_t -route_set_metric (void *rule, struct prefix *prefix,  -		  route_map_object_t type, void *object) -{ -  if (type == RMAP_RIP) -    { -      struct rip_metric_modifier *mod; -      struct rip_info *rinfo; - -      mod = rule; -      rinfo = object; - -      if (mod->type == metric_increment) -	rinfo->metric_out += mod->metric; -      else if (mod->type == metric_decrement) -	rinfo->metric_out -= mod->metric; -      else if (mod->type == metric_absolute) -	rinfo->metric_out = mod->metric; - -      if ((signed int)rinfo->metric_out < 1) -	rinfo->metric_out = 1; -      if (rinfo->metric_out > RIP_METRIC_INFINITY) -	rinfo->metric_out = RIP_METRIC_INFINITY; - -      rinfo->metric_set = 1; -    } -  return RMAP_OKAY; +static route_map_result_t route_set_metric(void *rule, struct prefix *prefix, +					   route_map_object_t type, +					   void *object) +{ +	if (type == RMAP_RIP) { +		struct rip_metric_modifier *mod; +		struct rip_info *rinfo; + +		mod = rule; +		rinfo = object; + +		if (mod->type == metric_increment) +			rinfo->metric_out += mod->metric; +		else if (mod->type == metric_decrement) +			rinfo->metric_out -= mod->metric; +		else if (mod->type == metric_absolute) +			rinfo->metric_out = mod->metric; + +		if ((signed int)rinfo->metric_out < 1) +			rinfo->metric_out = 1; +		if (rinfo->metric_out > RIP_METRIC_INFINITY) +			rinfo->metric_out = RIP_METRIC_INFINITY; + +		rinfo->metric_set = 1; +	} +	return RMAP_OKAY;  }  /* set metric compilation. */ -static void * -route_set_metric_compile (const char *arg) -{ -  int len; -  const char *pnt; -  int type; -  long metric; -  char *endptr = NULL; -  struct rip_metric_modifier *mod; - -  len = strlen (arg); -  pnt = arg; - -  if (len == 0) -    return NULL; - -  /* Examine first character. */ -  if (arg[0] == '+') -    { -      type = metric_increment; -      pnt++; -    } -  else if (arg[0] == '-') -    { -      type = metric_decrement; -      pnt++; -    } -  else -    type = metric_absolute; - -  /* Check beginning with digit string. */ -  if (*pnt < '0' || *pnt > '9') -    return NULL; - -  /* Convert string to integer. */ -  metric = strtol (pnt, &endptr, 10); - -  if (metric == LONG_MAX || *endptr != '\0') -    return NULL; -  if (metric < 0 || metric > RIP_METRIC_INFINITY) -    return NULL; - -  mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,  -		 sizeof (struct rip_metric_modifier)); -  mod->type = type; -  mod->metric = metric; - -  return mod; +static void *route_set_metric_compile(const char *arg) +{ +	int len; +	const char *pnt; +	int type; +	long metric; +	char *endptr = NULL; +	struct rip_metric_modifier *mod; + +	len = strlen(arg); +	pnt = arg; + +	if (len == 0) +		return NULL; + +	/* Examine first character. */ +	if (arg[0] == '+') { +		type = metric_increment; +		pnt++; +	} else if (arg[0] == '-') { +		type = metric_decrement; +		pnt++; +	} else +		type = metric_absolute; + +	/* Check beginning with digit string. */ +	if (*pnt < '0' || *pnt > '9') +		return NULL; + +	/* Convert string to integer. */ +	metric = strtol(pnt, &endptr, 10); + +	if (metric == LONG_MAX || *endptr != '\0') +		return NULL; +	if (metric < 0 || metric > RIP_METRIC_INFINITY) +		return NULL; + +	mod = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, +		      sizeof(struct rip_metric_modifier)); +	mod->type = type; +	mod->metric = metric; + +	return mod;  }  /* Free route map's compiled `set metric' value. */ -static void -route_set_metric_free (void *rule) +static void route_set_metric_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  }  /* Set metric rule structure. */ -static struct route_map_rule_cmd route_set_metric_cmd =  -{ -  "metric", -  route_set_metric, -  route_set_metric_compile, -  route_set_metric_free, +static struct route_map_rule_cmd route_set_metric_cmd = { +	"metric", route_set_metric, route_set_metric_compile, +	route_set_metric_free,  };  /* `set ip next-hop IP_ADDRESS' */  /* Set nexthop to object.  ojbect must be pointer to struct attr. */ -static route_map_result_t -route_set_ip_nexthop (void *rule, struct prefix *prefix,  -		      route_map_object_t type, void *object) +static route_map_result_t route_set_ip_nexthop(void *rule, +					       struct prefix *prefix, +					       route_map_object_t type, +					       void *object)  { -  struct in_addr *address; -  struct rip_info *rinfo; - -  if(type == RMAP_RIP) -    { -      /* Fetch routemap's rule information. */ -      address = rule; -      rinfo = object; -     -      /* Set next hop value. */  -      rinfo->nexthop_out = *address; -    } - -  return RMAP_OKAY; +	struct in_addr *address; +	struct rip_info *rinfo; + +	if (type == RMAP_RIP) { +		/* Fetch routemap's rule information. */ +		address = rule; +		rinfo = object; + +		/* Set next hop value. */ +		rinfo->nexthop_out = *address; +	} + +	return RMAP_OKAY;  }  /* Route map `ip nexthop' compile function.  Given string is converted     to struct in_addr structure. */ -static void * -route_set_ip_nexthop_compile (const char *arg) +static void *route_set_ip_nexthop_compile(const char *arg)  { -  int ret; -  struct in_addr *address; +	int ret; +	struct in_addr *address; -  address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr)); +	address = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(struct in_addr)); -  ret = inet_aton (arg, address); +	ret = inet_aton(arg, address); -  if (ret == 0) -    { -      XFREE (MTYPE_ROUTE_MAP_COMPILED, address); -      return NULL; -    } +	if (ret == 0) { +		XFREE(MTYPE_ROUTE_MAP_COMPILED, address); +		return NULL; +	} -  return address; +	return address;  }  /* Free route map's compiled `ip nexthop' value. */ -static void -route_set_ip_nexthop_free (void *rule) +static void route_set_ip_nexthop_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  }  /* Route map commands for ip nexthop set. */ -static struct route_map_rule_cmd route_set_ip_nexthop_cmd = -{ -  "ip next-hop", -  route_set_ip_nexthop, -  route_set_ip_nexthop_compile, -  route_set_ip_nexthop_free -}; +static struct route_map_rule_cmd route_set_ip_nexthop_cmd = { +	"ip next-hop", route_set_ip_nexthop, route_set_ip_nexthop_compile, +	route_set_ip_nexthop_free};  /* `set tag TAG' */  /* Set tag to object.  ojbect must be pointer to struct attr. */ -static route_map_result_t -route_set_tag (void *rule, struct prefix *prefix,  -		      route_map_object_t type, void *object) +static route_map_result_t route_set_tag(void *rule, struct prefix *prefix, +					route_map_object_t type, void *object)  { -  route_tag_t *tag; -  struct rip_info *rinfo; - -  if(type == RMAP_RIP) -    { -      /* Fetch routemap's rule information. */ -      tag = rule; -      rinfo = object; -     -      /* Set next hop value. */  -      rinfo->tag_out = *tag; -    } - -  return RMAP_OKAY; +	route_tag_t *tag; +	struct rip_info *rinfo; + +	if (type == RMAP_RIP) { +		/* Fetch routemap's rule information. */ +		tag = rule; +		rinfo = object; + +		/* Set next hop value. */ +		rinfo->tag_out = *tag; +	} + +	return RMAP_OKAY;  }  /* Route map commands for tag set. */ -static struct route_map_rule_cmd route_set_tag_cmd = -{ -  "tag", -  route_set_tag, -  route_map_rule_tag_compile, -  route_map_rule_tag_free -}; +static struct route_map_rule_cmd route_set_tag_cmd = { +	"tag", route_set_tag, route_map_rule_tag_compile, +	route_map_rule_tag_free};  #define MATCH_STR "Match values from routing table\n"  #define SET_STR "Set values in destination routing protocol\n" -void -rip_route_map_reset () +void rip_route_map_reset()  { -  ; +	;  }  /* Route-map init */ -void -rip_route_map_init () +void rip_route_map_init()  { -  route_map_init (); +	route_map_init(); -  route_map_add_hook (rip_route_map_update); -  route_map_delete_hook (rip_route_map_update); +	route_map_add_hook(rip_route_map_update); +	route_map_delete_hook(rip_route_map_update); -  route_map_match_interface_hook (generic_match_add); -  route_map_no_match_interface_hook (generic_match_delete); +	route_map_match_interface_hook(generic_match_add); +	route_map_no_match_interface_hook(generic_match_delete); -  route_map_match_ip_address_hook (generic_match_add); -  route_map_no_match_ip_address_hook (generic_match_delete); +	route_map_match_ip_address_hook(generic_match_add); +	route_map_no_match_ip_address_hook(generic_match_delete); -  route_map_match_ip_address_prefix_list_hook (generic_match_add); -  route_map_no_match_ip_address_prefix_list_hook (generic_match_delete); +	route_map_match_ip_address_prefix_list_hook(generic_match_add); +	route_map_no_match_ip_address_prefix_list_hook(generic_match_delete); -  route_map_match_ip_next_hop_hook (generic_match_add); -  route_map_no_match_ip_next_hop_hook (generic_match_delete); +	route_map_match_ip_next_hop_hook(generic_match_add); +	route_map_no_match_ip_next_hop_hook(generic_match_delete); -  route_map_match_ip_next_hop_prefix_list_hook (generic_match_add); -  route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete); +	route_map_match_ip_next_hop_prefix_list_hook(generic_match_add); +	route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete); -  route_map_match_metric_hook (generic_match_add); -  route_map_no_match_metric_hook (generic_match_delete); +	route_map_match_metric_hook(generic_match_add); +	route_map_no_match_metric_hook(generic_match_delete); -  route_map_match_tag_hook (generic_match_add); -  route_map_no_match_tag_hook (generic_match_delete); +	route_map_match_tag_hook(generic_match_add); +	route_map_no_match_tag_hook(generic_match_delete); -  route_map_set_ip_nexthop_hook (generic_set_add); -  route_map_no_set_ip_nexthop_hook (generic_set_delete); +	route_map_set_ip_nexthop_hook(generic_set_add); +	route_map_no_set_ip_nexthop_hook(generic_set_delete); -  route_map_set_metric_hook (generic_set_add); -  route_map_no_set_metric_hook (generic_set_delete); +	route_map_set_metric_hook(generic_set_add); +	route_map_no_set_metric_hook(generic_set_delete); -  route_map_set_tag_hook (generic_set_add); -  route_map_no_set_tag_hook (generic_set_delete); +	route_map_set_tag_hook(generic_set_add); +	route_map_no_set_tag_hook(generic_set_delete); -  route_map_install_match (&route_match_metric_cmd); -  route_map_install_match (&route_match_interface_cmd); -  route_map_install_match (&route_match_ip_next_hop_cmd); -  route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd); -  route_map_install_match (&route_match_ip_address_cmd); -  route_map_install_match (&route_match_ip_address_prefix_list_cmd); -  route_map_install_match (&route_match_tag_cmd); +	route_map_install_match(&route_match_metric_cmd); +	route_map_install_match(&route_match_interface_cmd); +	route_map_install_match(&route_match_ip_next_hop_cmd); +	route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd); +	route_map_install_match(&route_match_ip_address_cmd); +	route_map_install_match(&route_match_ip_address_prefix_list_cmd); +	route_map_install_match(&route_match_tag_cmd); -  route_map_install_set (&route_set_metric_cmd); -  route_map_install_set (&route_set_ip_nexthop_cmd); -  route_map_install_set (&route_set_tag_cmd); +	route_map_install_set(&route_set_metric_cmd); +	route_map_install_set(&route_set_ip_nexthop_cmd); +	route_map_install_set(&route_set_tag_cmd);  } diff --git a/ripd/rip_snmp.c b/ripd/rip_snmp.c index 6a4ae11ae1..45bb2e377a 100644 --- a/ripd/rip_snmp.c +++ b/ripd/rip_snmp.c @@ -82,319 +82,311 @@  SNMP_LOCAL_VARIABLES  /* RIP-MIB instances. */ -static oid rip_oid [] = { RIPV2MIB }; +static oid rip_oid[] = {RIPV2MIB};  /* Interface cache table sorted by interface's address. */  static struct route_table *rip_ifaddr_table;  /* Hook functions. */ -static u_char *rip2Globals (struct variable *, oid [], size_t *, -			    int, size_t *, WriteMethod **); -static u_char *rip2IfStatEntry (struct variable *, oid [], size_t *, -				int, size_t *, WriteMethod **); -static u_char *rip2IfConfAddress (struct variable *, oid [], size_t *, -				  int, size_t *, WriteMethod **); -static u_char *rip2PeerTable (struct variable *, oid [], size_t *, -			      int, size_t *, WriteMethod **); - -static struct variable rip_variables[] = -{ -  /* RIP Global Counters. */ -  {RIP2GLOBALROUTECHANGES,    COUNTER, RONLY, rip2Globals, -   2, {1, 1}}, -  {RIP2GLOBALQUERIES,         COUNTER, RONLY, rip2Globals, -   2, {1, 2}}, -  /* RIP Interface Tables. */ -  {RIP2IFSTATADDRESS,         IPADDRESS, RONLY, rip2IfStatEntry, -   3, {2, 1, 1}}, -  {RIP2IFSTATRCVBADPACKETS,   COUNTER, RONLY, rip2IfStatEntry, -   3, {2, 1, 2}}, -  {RIP2IFSTATRCVBADROUTES,    COUNTER, RONLY, rip2IfStatEntry, -   3, {2, 1, 3}}, -  {RIP2IFSTATSENTUPDATES,     COUNTER, RONLY, rip2IfStatEntry, -   3, {2, 1, 4}}, -  {RIP2IFSTATSTATUS,          COUNTER, RWRITE, rip2IfStatEntry, -   3, {2, 1, 5}}, -  {RIP2IFCONFADDRESS,         IPADDRESS, RONLY, rip2IfConfAddress, -   /* RIP Interface Configuration Table. */ -   3, {3, 1, 1}}, -  {RIP2IFCONFDOMAIN,          STRING, RONLY, rip2IfConfAddress, -   3, {3, 1, 2}}, -  {RIP2IFCONFAUTHTYPE,        COUNTER, RONLY, rip2IfConfAddress, -   3, {3, 1, 3}}, -  {RIP2IFCONFAUTHKEY,         STRING, RONLY, rip2IfConfAddress, -   3, {3, 1, 4}}, -  {RIP2IFCONFSEND,            COUNTER, RONLY, rip2IfConfAddress, -   3, {3, 1, 5}}, -  {RIP2IFCONFRECEIVE,         COUNTER, RONLY, rip2IfConfAddress, -   3, {3, 1, 6}}, -  {RIP2IFCONFDEFAULTMETRIC,   COUNTER, RONLY, rip2IfConfAddress, -   3, {3, 1, 7}}, -  {RIP2IFCONFSTATUS,          COUNTER, RONLY, rip2IfConfAddress, -   3, {3, 1, 8}}, -  {RIP2IFCONFSRCADDRESS,      IPADDRESS, RONLY, rip2IfConfAddress, -   3, {3, 1, 9}}, -  {RIP2PEERADDRESS,           IPADDRESS, RONLY, rip2PeerTable, -   /* RIP Peer Table. */ -   3, {4, 1, 1}}, -  {RIP2PEERDOMAIN,            STRING, RONLY, rip2PeerTable, -   3, {4, 1, 2}}, -  {RIP2PEERLASTUPDATE,        TIMETICKS, RONLY, rip2PeerTable, -   3, {4, 1, 3}}, -  {RIP2PEERVERSION,           INTEGER, RONLY, rip2PeerTable, -   3, {4, 1, 4}}, -  {RIP2PEERRCVBADPACKETS,     COUNTER, RONLY, rip2PeerTable, -   3, {4, 1, 5}}, -  {RIP2PEERRCVBADROUTES,      COUNTER, RONLY, rip2PeerTable, -   3, {4, 1, 6}} -}; +static u_char *rip2Globals(struct variable *, oid[], size_t *, int, size_t *, +			   WriteMethod **); +static u_char *rip2IfStatEntry(struct variable *, oid[], size_t *, int, +			       size_t *, WriteMethod **); +static u_char *rip2IfConfAddress(struct variable *, oid[], size_t *, int, +				 size_t *, WriteMethod **); +static u_char *rip2PeerTable(struct variable *, oid[], size_t *, int, size_t *, +			     WriteMethod **); + +static struct variable rip_variables[] = { +	/* RIP Global Counters. */ +	{RIP2GLOBALROUTECHANGES, COUNTER, RONLY, rip2Globals, 2, {1, 1}}, +	{RIP2GLOBALQUERIES, COUNTER, RONLY, rip2Globals, 2, {1, 2}}, +	/* RIP Interface Tables. */ +	{RIP2IFSTATADDRESS, IPADDRESS, RONLY, rip2IfStatEntry, 3, {2, 1, 1}}, +	{RIP2IFSTATRCVBADPACKETS, +	 COUNTER, +	 RONLY, +	 rip2IfStatEntry, +	 3, +	 {2, 1, 2}}, +	{RIP2IFSTATRCVBADROUTES, COUNTER, RONLY, rip2IfStatEntry, 3, {2, 1, 3}}, +	{RIP2IFSTATSENTUPDATES, COUNTER, RONLY, rip2IfStatEntry, 3, {2, 1, 4}}, +	{RIP2IFSTATSTATUS, COUNTER, RWRITE, rip2IfStatEntry, 3, {2, 1, 5}}, +	{RIP2IFCONFADDRESS, +	 IPADDRESS, +	 RONLY, +	 rip2IfConfAddress, +	 /* RIP Interface Configuration Table. */ +	 3, +	 {3, 1, 1}}, +	{RIP2IFCONFDOMAIN, STRING, RONLY, rip2IfConfAddress, 3, {3, 1, 2}}, +	{RIP2IFCONFAUTHTYPE, COUNTER, RONLY, rip2IfConfAddress, 3, {3, 1, 3}}, +	{RIP2IFCONFAUTHKEY, STRING, RONLY, rip2IfConfAddress, 3, {3, 1, 4}}, +	{RIP2IFCONFSEND, COUNTER, RONLY, rip2IfConfAddress, 3, {3, 1, 5}}, +	{RIP2IFCONFRECEIVE, COUNTER, RONLY, rip2IfConfAddress, 3, {3, 1, 6}}, +	{RIP2IFCONFDEFAULTMETRIC, +	 COUNTER, +	 RONLY, +	 rip2IfConfAddress, +	 3, +	 {3, 1, 7}}, +	{RIP2IFCONFSTATUS, COUNTER, RONLY, rip2IfConfAddress, 3, {3, 1, 8}}, +	{RIP2IFCONFSRCADDRESS, +	 IPADDRESS, +	 RONLY, +	 rip2IfConfAddress, +	 3, +	 {3, 1, 9}}, +	{RIP2PEERADDRESS, +	 IPADDRESS, +	 RONLY, +	 rip2PeerTable, +	 /* RIP Peer Table. */ +	 3, +	 {4, 1, 1}}, +	{RIP2PEERDOMAIN, STRING, RONLY, rip2PeerTable, 3, {4, 1, 2}}, +	{RIP2PEERLASTUPDATE, TIMETICKS, RONLY, rip2PeerTable, 3, {4, 1, 3}}, +	{RIP2PEERVERSION, INTEGER, RONLY, rip2PeerTable, 3, {4, 1, 4}}, +	{RIP2PEERRCVBADPACKETS, COUNTER, RONLY, rip2PeerTable, 3, {4, 1, 5}}, +	{RIP2PEERRCVBADROUTES, COUNTER, RONLY, rip2PeerTable, 3, {4, 1, 6}}};  extern struct thread_master *master; -static u_char * -rip2Globals (struct variable *v, oid name[], size_t *length, -	     int exact, size_t *var_len, WriteMethod **write_method) +static u_char *rip2Globals(struct variable *v, oid name[], size_t *length, +			   int exact, size_t *var_len, +			   WriteMethod **write_method)  { -  if (smux_header_generic(v, name, length, exact, var_len, write_method) -      == MATCH_FAILED) -    return NULL; - -  /* Retrun global counter. */ -  switch (v->magic) -    { -    case RIP2GLOBALROUTECHANGES: -      return SNMP_INTEGER (rip_global_route_changes); -      break; -    case RIP2GLOBALQUERIES: -      return SNMP_INTEGER (rip_global_queries); -      break; -    default: -      return NULL; -      break; -    } -  return NULL; +	if (smux_header_generic(v, name, length, exact, var_len, write_method) +	    == MATCH_FAILED) +		return NULL; + +	/* Retrun global counter. */ +	switch (v->magic) { +	case RIP2GLOBALROUTECHANGES: +		return SNMP_INTEGER(rip_global_route_changes); +		break; +	case RIP2GLOBALQUERIES: +		return SNMP_INTEGER(rip_global_queries); +		break; +	default: +		return NULL; +		break; +	} +	return NULL;  } -static int -rip_snmp_ifaddr_add (struct connected *ifc) +static int rip_snmp_ifaddr_add(struct connected *ifc)  { -  struct interface *ifp = ifc->ifp; -  struct prefix *p; -  struct route_node *rn; +	struct interface *ifp = ifc->ifp; +	struct prefix *p; +	struct route_node *rn; -  p = ifc->address; +	p = ifc->address; -  if (p->family != AF_INET) -    return 0; +	if (p->family != AF_INET) +		return 0; -  rn = route_node_get (rip_ifaddr_table, p); -  rn->info = ifp; -  return 0; +	rn = route_node_get(rip_ifaddr_table, p); +	rn->info = ifp; +	return 0;  } -static int -rip_snmp_ifaddr_del (struct connected *ifc) +static int rip_snmp_ifaddr_del(struct connected *ifc)  { -  struct interface *ifp = ifc->ifp; -  struct prefix *p; -  struct route_node *rn; -  struct interface *i; - -  p = ifc->address; - -  if (p->family != AF_INET) -    return 0; - -  rn = route_node_lookup (rip_ifaddr_table, p); -  if (! rn) -    return 0; -  i = rn->info; -  if (rn && !strncmp(i->name,ifp->name,INTERFACE_NAMSIZ)) -    { -      rn->info = NULL; -      route_unlock_node (rn); -      route_unlock_node (rn); -    } -  return 0; +	struct interface *ifp = ifc->ifp; +	struct prefix *p; +	struct route_node *rn; +	struct interface *i; + +	p = ifc->address; + +	if (p->family != AF_INET) +		return 0; + +	rn = route_node_lookup(rip_ifaddr_table, p); +	if (!rn) +		return 0; +	i = rn->info; +	if (rn && !strncmp(i->name, ifp->name, INTERFACE_NAMSIZ)) { +		rn->info = NULL; +		route_unlock_node(rn); +		route_unlock_node(rn); +	} +	return 0;  } -static struct interface * -rip_ifaddr_lookup_next (struct in_addr *addr) +static struct interface *rip_ifaddr_lookup_next(struct in_addr *addr)  { -  struct prefix_ipv4 p; -  struct route_node *rn; -  struct interface *ifp; - -  p.family = AF_INET; -  p.prefixlen = IPV4_MAX_BITLEN; -  p.prefix = *addr; - -  rn = route_node_get (rip_ifaddr_table, (struct prefix *) &p); - -  for (rn = route_next (rn); rn; rn = route_next (rn)) -    if (rn->info) -      break; - -  if (rn && rn->info) -    { -      ifp = rn->info; -      *addr = rn->p.u.prefix4; -      route_unlock_node (rn); -      return ifp; -    } -  return NULL; +	struct prefix_ipv4 p; +	struct route_node *rn; +	struct interface *ifp; + +	p.family = AF_INET; +	p.prefixlen = IPV4_MAX_BITLEN; +	p.prefix = *addr; + +	rn = route_node_get(rip_ifaddr_table, (struct prefix *)&p); + +	for (rn = route_next(rn); rn; rn = route_next(rn)) +		if (rn->info) +			break; + +	if (rn && rn->info) { +		ifp = rn->info; +		*addr = rn->p.u.prefix4; +		route_unlock_node(rn); +		return ifp; +	} +	return NULL;  } -static struct interface * -rip2IfLookup (struct variable *v, oid name[], size_t *length,  -	      struct in_addr *addr, int exact) +static struct interface *rip2IfLookup(struct variable *v, oid name[], +				      size_t *length, struct in_addr *addr, +				      int exact)  { -  int len; -  struct interface *ifp; -   -  if (exact) -    { -      /* Check the length. */ -      if (*length - v->namelen != sizeof (struct in_addr)) -	return NULL; +	int len; +	struct interface *ifp; -      oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr); +	if (exact) { +		/* Check the length. */ +		if (*length - v->namelen != sizeof(struct in_addr)) +			return NULL; -      return if_lookup_exact_address ((void *)addr, AF_INET, VRF_DEFAULT); -    } -  else -    { -      len = *length - v->namelen; -      if (len > 4) len = 4; +		oid2in_addr(name + v->namelen, sizeof(struct in_addr), addr); -      oid2in_addr (name + v->namelen, len, addr); +		return if_lookup_exact_address((void *)addr, AF_INET, +					       VRF_DEFAULT); +	} else { +		len = *length - v->namelen; +		if (len > 4) +			len = 4; -      ifp = rip_ifaddr_lookup_next (addr); +		oid2in_addr(name + v->namelen, len, addr); -      if (ifp == NULL) -	return NULL; +		ifp = rip_ifaddr_lookup_next(addr); -      oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr)); +		if (ifp == NULL) +			return NULL; -      *length = v->namelen + sizeof (struct in_addr); +		oid_copy_addr(name + v->namelen, addr, sizeof(struct in_addr)); -      return ifp; -    } -  return NULL; -} +		*length = v->namelen + sizeof(struct in_addr); -static struct rip_peer * -rip2PeerLookup (struct variable *v, oid name[], size_t *length,  -		struct in_addr *addr, int exact) -{ -  int len; -  struct rip_peer *peer; -   -  if (exact) -    { -      /* Check the length. */ -      if (*length - v->namelen != sizeof (struct in_addr) + 1) +		return ifp; +	}  	return NULL; +} -      oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr); - -      peer = rip_peer_lookup (addr); - -      if (peer->domain == (int)name[v->namelen + sizeof (struct in_addr)]) -	return peer; - -      return NULL; -    } -  else -    { -      len = *length - v->namelen; -      if (len > 4) len = 4; - -      oid2in_addr (name + v->namelen, len, addr); - -      len = *length - v->namelen; -      peer = rip_peer_lookup (addr); -      if (peer) -	{ -	  if ((len < (int)sizeof (struct in_addr) + 1) || -	      (peer->domain > (int)name[v->namelen + sizeof (struct in_addr)])) -	    { -	      oid_copy_addr (name + v->namelen, &peer->addr, -			     sizeof (struct in_addr)); -	      name[v->namelen + sizeof (struct in_addr)] = peer->domain; -	      *length = sizeof (struct in_addr) + v->namelen + 1; -	      return peer; -	    } -        }  -      peer = rip_peer_lookup_next (addr); - -      if (! peer) +static struct rip_peer *rip2PeerLookup(struct variable *v, oid name[], +				       size_t *length, struct in_addr *addr, +				       int exact) +{ +	int len; +	struct rip_peer *peer; + +	if (exact) { +		/* Check the length. */ +		if (*length - v->namelen != sizeof(struct in_addr) + 1) +			return NULL; + +		oid2in_addr(name + v->namelen, sizeof(struct in_addr), addr); + +		peer = rip_peer_lookup(addr); + +		if (peer->domain +		    == (int)name[v->namelen + sizeof(struct in_addr)]) +			return peer; + +		return NULL; +	} else { +		len = *length - v->namelen; +		if (len > 4) +			len = 4; + +		oid2in_addr(name + v->namelen, len, addr); + +		len = *length - v->namelen; +		peer = rip_peer_lookup(addr); +		if (peer) { +			if ((len < (int)sizeof(struct in_addr) + 1) +			    || (peer->domain +				> (int)name[v->namelen +					    + sizeof(struct in_addr)])) { +				oid_copy_addr(name + v->namelen, &peer->addr, +					      sizeof(struct in_addr)); +				name[v->namelen + sizeof(struct in_addr)] = +					peer->domain; +				*length = +					sizeof(struct in_addr) + v->namelen + 1; +				return peer; +			} +		} +		peer = rip_peer_lookup_next(addr); + +		if (!peer) +			return NULL; + +		oid_copy_addr(name + v->namelen, &peer->addr, +			      sizeof(struct in_addr)); +		name[v->namelen + sizeof(struct in_addr)] = peer->domain; +		*length = sizeof(struct in_addr) + v->namelen + 1; + +		return peer; +	}  	return NULL; - -      oid_copy_addr (name + v->namelen, &peer->addr, -		     sizeof (struct in_addr)); -      name[v->namelen + sizeof (struct in_addr)] = peer->domain; -      *length = sizeof (struct in_addr) + v->namelen + 1; - -      return peer; -    } -  return NULL;  } -static u_char * -rip2IfStatEntry (struct variable *v, oid name[], size_t *length, -	         int exact, size_t *var_len, WriteMethod **write_method) +static u_char *rip2IfStatEntry(struct variable *v, oid name[], size_t *length, +			       int exact, size_t *var_len, +			       WriteMethod **write_method)  { -  struct interface *ifp; -  struct rip_interface *ri; -  static struct in_addr addr; -  static long valid = SNMP_VALID; - -  if (smux_header_table(v, name, length, exact, var_len, write_method) -      == MATCH_FAILED) -    return NULL; - -  memset (&addr, 0, sizeof (struct in_addr)); -   -  /* Lookup interface. */ -  ifp = rip2IfLookup (v, name, length, &addr, exact); -  if (! ifp) -    return NULL; - -  /* Fetch rip_interface information. */ -  ri = ifp->info; - -  switch (v->magic) -    { -    case RIP2IFSTATADDRESS: -      return SNMP_IPADDRESS (addr); -      break; -    case RIP2IFSTATRCVBADPACKETS: -      *var_len = sizeof (long); -      return (u_char *) &ri->recv_badpackets; - -    case RIP2IFSTATRCVBADROUTES: -      *var_len = sizeof (long); -      return (u_char *) &ri->recv_badroutes; - -    case RIP2IFSTATSENTUPDATES: -      *var_len = sizeof (long); -      return (u_char *) &ri->sent_updates; - -    case RIP2IFSTATSTATUS: -      *var_len = sizeof (long); -      v->type = ASN_INTEGER; -      return (u_char *) &valid; - -    default: -      return NULL; - -    } -  return NULL; +	struct interface *ifp; +	struct rip_interface *ri; +	static struct in_addr addr; +	static long valid = SNMP_VALID; + +	if (smux_header_table(v, name, length, exact, var_len, write_method) +	    == MATCH_FAILED) +		return NULL; + +	memset(&addr, 0, sizeof(struct in_addr)); + +	/* Lookup interface. */ +	ifp = rip2IfLookup(v, name, length, &addr, exact); +	if (!ifp) +		return NULL; + +	/* Fetch rip_interface information. */ +	ri = ifp->info; + +	switch (v->magic) { +	case RIP2IFSTATADDRESS: +		return SNMP_IPADDRESS(addr); +		break; +	case RIP2IFSTATRCVBADPACKETS: +		*var_len = sizeof(long); +		return (u_char *)&ri->recv_badpackets; + +	case RIP2IFSTATRCVBADROUTES: +		*var_len = sizeof(long); +		return (u_char *)&ri->recv_badroutes; + +	case RIP2IFSTATSENTUPDATES: +		*var_len = sizeof(long); +		return (u_char *)&ri->sent_updates; + +	case RIP2IFSTATSTATUS: +		*var_len = sizeof(long); +		v->type = ASN_INTEGER; +		return (u_char *)&valid; + +	default: +		return NULL; +	} +	return NULL;  } -static long -rip2IfConfSend (struct rip_interface *ri) +static long rip2IfConfSend(struct rip_interface *ri)  {  #define doNotSend       1  #define ripVersion1     2 @@ -403,156 +395,151 @@ rip2IfConfSend (struct rip_interface *ri)  #define ripV1Demand     5  #define ripV2Demand     6 -  if (! ri->running) -    return doNotSend; -     -  if (ri->ri_send & RIPv2) -    return ripVersion2; -  else if (ri->ri_send & RIPv1) -    return ripVersion1; -  else if (rip) -    { -      if (rip->version_send == RIPv2) -	return ripVersion2; -      else if (rip->version_send == RIPv1) -	return ripVersion1; -    } -  return doNotSend; +	if (!ri->running) +		return doNotSend; + +	if (ri->ri_send & RIPv2) +		return ripVersion2; +	else if (ri->ri_send & RIPv1) +		return ripVersion1; +	else if (rip) { +		if (rip->version_send == RIPv2) +			return ripVersion2; +		else if (rip->version_send == RIPv1) +			return ripVersion1; +	} +	return doNotSend;  } -static long -rip2IfConfReceive (struct rip_interface *ri) +static long rip2IfConfReceive(struct rip_interface *ri)  {  #define rip1            1  #define rip2            2  #define rip1OrRip2      3  #define doNotReceive    4 -  int recvv; - -  if (! ri->running) -    return doNotReceive; - -  recvv = (ri->ri_receive == RI_RIP_UNSPEC) ?  rip->version_recv : -                                               ri->ri_receive; -  if (recvv == RI_RIP_VERSION_1_AND_2) -    return rip1OrRip2; -  else if (recvv & RIPv2) -    return rip2; -  else if (recvv & RIPv1) -    return rip1; -  else -    return doNotReceive; +	int recvv; + +	if (!ri->running) +		return doNotReceive; + +	recvv = (ri->ri_receive == RI_RIP_UNSPEC) ? rip->version_recv +						  : ri->ri_receive; +	if (recvv == RI_RIP_VERSION_1_AND_2) +		return rip1OrRip2; +	else if (recvv & RIPv2) +		return rip2; +	else if (recvv & RIPv1) +		return rip1; +	else +		return doNotReceive;  } -static u_char * -rip2IfConfAddress (struct variable *v, oid name[], size_t *length, -	           int exact, size_t *val_len, WriteMethod **write_method) +static u_char *rip2IfConfAddress(struct variable *v, oid name[], size_t *length, +				 int exact, size_t *val_len, +				 WriteMethod **write_method)  { -  static struct in_addr addr; -  static long valid = SNMP_INVALID; -  static long domain = 0; -  static long config = 0; -  static u_int auth = 0; -  struct interface *ifp; -  struct rip_interface *ri; - -  if (smux_header_table(v, name, length, exact, val_len, write_method) -      == MATCH_FAILED) -    return NULL; - -  memset (&addr, 0, sizeof (struct in_addr)); -   -  /* Lookup interface. */ -  ifp = rip2IfLookup (v, name, length, &addr, exact); -  if (! ifp) -    return NULL; - -  /* Fetch rip_interface information. */ -  ri = ifp->info; - -  switch (v->magic) -    { -    case RIP2IFCONFADDRESS: -      *val_len = sizeof (struct in_addr); -      return (u_char *) &addr; - -    case RIP2IFCONFDOMAIN: -      *val_len = 2; -      return (u_char *) &domain; - -    case RIP2IFCONFAUTHTYPE: -      auth = ri->auth_type; -      *val_len = sizeof (long); -      v->type = ASN_INTEGER; -      return (u_char *)&auth; - -    case RIP2IFCONFAUTHKEY: -      *val_len = 0; -      return (u_char *) &domain; -    case RIP2IFCONFSEND: -      config = rip2IfConfSend (ri); -      *val_len = sizeof (long); -      v->type = ASN_INTEGER; -      return (u_char *) &config; -    case RIP2IFCONFRECEIVE: -      config = rip2IfConfReceive (ri); -      *val_len = sizeof (long); -      v->type = ASN_INTEGER; -      return (u_char *) &config; - -    case RIP2IFCONFDEFAULTMETRIC: -      *val_len = sizeof (long); -      v->type = ASN_INTEGER; -      return (u_char *) &ifp->metric; -    case RIP2IFCONFSTATUS: -      *val_len = sizeof (long); -      v->type = ASN_INTEGER; -      return (u_char *) &valid; -    case RIP2IFCONFSRCADDRESS: -      *val_len = sizeof (struct in_addr); -      return (u_char *) &addr; - -    default: -      return NULL; - -    } -  return NULL; +	static struct in_addr addr; +	static long valid = SNMP_INVALID; +	static long domain = 0; +	static long config = 0; +	static u_int auth = 0; +	struct interface *ifp; +	struct rip_interface *ri; + +	if (smux_header_table(v, name, length, exact, val_len, write_method) +	    == MATCH_FAILED) +		return NULL; + +	memset(&addr, 0, sizeof(struct in_addr)); + +	/* Lookup interface. */ +	ifp = rip2IfLookup(v, name, length, &addr, exact); +	if (!ifp) +		return NULL; + +	/* Fetch rip_interface information. */ +	ri = ifp->info; + +	switch (v->magic) { +	case RIP2IFCONFADDRESS: +		*val_len = sizeof(struct in_addr); +		return (u_char *)&addr; + +	case RIP2IFCONFDOMAIN: +		*val_len = 2; +		return (u_char *)&domain; + +	case RIP2IFCONFAUTHTYPE: +		auth = ri->auth_type; +		*val_len = sizeof(long); +		v->type = ASN_INTEGER; +		return (u_char *)&auth; + +	case RIP2IFCONFAUTHKEY: +		*val_len = 0; +		return (u_char *)&domain; +	case RIP2IFCONFSEND: +		config = rip2IfConfSend(ri); +		*val_len = sizeof(long); +		v->type = ASN_INTEGER; +		return (u_char *)&config; +	case RIP2IFCONFRECEIVE: +		config = rip2IfConfReceive(ri); +		*val_len = sizeof(long); +		v->type = ASN_INTEGER; +		return (u_char *)&config; + +	case RIP2IFCONFDEFAULTMETRIC: +		*val_len = sizeof(long); +		v->type = ASN_INTEGER; +		return (u_char *)&ifp->metric; +	case RIP2IFCONFSTATUS: +		*val_len = sizeof(long); +		v->type = ASN_INTEGER; +		return (u_char *)&valid; +	case RIP2IFCONFSRCADDRESS: +		*val_len = sizeof(struct in_addr); +		return (u_char *)&addr; + +	default: +		return NULL; +	} +	return NULL;  } -static u_char * -rip2PeerTable (struct variable *v, oid name[], size_t *length, -	       int exact, size_t *val_len, WriteMethod **write_method) +static u_char *rip2PeerTable(struct variable *v, oid name[], size_t *length, +			     int exact, size_t *val_len, +			     WriteMethod **write_method)  { -  static struct in_addr addr; -  static int domain = 0; -  static int version; -  /* static time_t uptime; */ - -  struct rip_peer *peer; - -  if (smux_header_table(v, name, length, exact, val_len, write_method) -      == MATCH_FAILED) -    return NULL; - -  memset (&addr, 0, sizeof (struct in_addr)); -   -  /* Lookup interface. */ -  peer = rip2PeerLookup (v, name, length, &addr, exact); -  if (! peer) -    return NULL; - -  switch (v->magic) -    { -    case RIP2PEERADDRESS: -      *val_len = sizeof (struct in_addr); -      return (u_char *) &peer->addr; - -    case RIP2PEERDOMAIN: -      *val_len = 2; -      return (u_char *) &domain; - -    case RIP2PEERLASTUPDATE: +	static struct in_addr addr; +	static int domain = 0; +	static int version; +	/* static time_t uptime; */ + +	struct rip_peer *peer; + +	if (smux_header_table(v, name, length, exact, val_len, write_method) +	    == MATCH_FAILED) +		return NULL; + +	memset(&addr, 0, sizeof(struct in_addr)); + +	/* Lookup interface. */ +	peer = rip2PeerLookup(v, name, length, &addr, exact); +	if (!peer) +		return NULL; + +	switch (v->magic) { +	case RIP2PEERADDRESS: +		*val_len = sizeof(struct in_addr); +		return (u_char *)&peer->addr; + +	case RIP2PEERDOMAIN: +		*val_len = 2; +		return (u_char *)&domain; + +	case RIP2PEERLASTUPDATE:  #if 0         /* We don't know the SNMP agent startup time. We have two choices here:         * - assume ripd startup time equals SNMP agent startup time @@ -563,53 +550,47 @@ rip2PeerTable (struct variable *v, oid name[], size_t *length,        uptime = peer->uptime; /* now - snmp_agent_startup - peer->uptime */        return (u_char *) &uptime;  #else -      return (u_char *) NULL; +		return (u_char *)NULL;  #endif -    case RIP2PEERVERSION: -      *val_len = sizeof (int); -      version = peer->version; -      return (u_char *) &version; +	case RIP2PEERVERSION: +		*val_len = sizeof(int); +		version = peer->version; +		return (u_char *)&version; -    case RIP2PEERRCVBADPACKETS: -      *val_len = sizeof (int); -      return (u_char *) &peer->recv_badpackets; +	case RIP2PEERRCVBADPACKETS: +		*val_len = sizeof(int); +		return (u_char *)&peer->recv_badpackets; -    case RIP2PEERRCVBADROUTES: -      *val_len = sizeof (int); -      return (u_char *) &peer->recv_badroutes; +	case RIP2PEERRCVBADROUTES: +		*val_len = sizeof(int); +		return (u_char *)&peer->recv_badroutes; -    default: -      return NULL; - -    } -  return NULL; +	default: +		return NULL; +	} +	return NULL;  }  /* Register RIPv2-MIB. */ -static int -rip_snmp_init (struct thread_master *master) +static int rip_snmp_init(struct thread_master *master)  { -  rip_ifaddr_table = route_table_init (); +	rip_ifaddr_table = route_table_init(); -  smux_init (master); -  REGISTER_MIB("mibII/rip", rip_variables, variable, rip_oid); -  return 0; +	smux_init(master); +	REGISTER_MIB("mibII/rip", rip_variables, variable, rip_oid); +	return 0;  } -static int -rip_snmp_module_init (void) +static int rip_snmp_module_init(void)  { -  hook_register(rip_ifaddr_add, rip_snmp_ifaddr_add); -  hook_register(rip_ifaddr_del, rip_snmp_ifaddr_del); +	hook_register(rip_ifaddr_add, rip_snmp_ifaddr_add); +	hook_register(rip_ifaddr_del, rip_snmp_ifaddr_del); -  hook_register(frr_late_init, rip_snmp_init); -  return 0; +	hook_register(frr_late_init, rip_snmp_init); +	return 0;  } -FRR_MODULE_SETUP( -	.name = "ripd_snmp", -	.version = FRR_VERSION, -	.description = "ripd AgentX SNMP module", -	.init = rip_snmp_module_init, -) +FRR_MODULE_SETUP(.name = "ripd_snmp", .version = FRR_VERSION, +		 .description = "ripd AgentX SNMP module", +		 .init = rip_snmp_module_init, ) diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index dffa9db7cf..961a846db2 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -37,274 +37,265 @@  struct zclient *zclient = NULL;  /* Send ECMP routes to zebra. */ -static void -rip_zebra_ipv4_send (struct route_node *rp, u_char cmd) +static void rip_zebra_ipv4_send(struct route_node *rp, u_char cmd)  { -  static struct in_addr **nexthops = NULL; -  static unsigned int nexthops_len = 0; - -  struct list *list = (struct list *)rp->info; -  struct zapi_ipv4 api; -  struct listnode *listnode = NULL; -  struct rip_info *rinfo = NULL; -  int count = 0; - -  if (vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], VRF_DEFAULT)) -    { -      api.vrf_id = VRF_DEFAULT; -      api.type = ZEBRA_ROUTE_RIP; -      api.instance = 0; -      api.flags = 0; -      api.message = 0; -      api.safi = SAFI_UNICAST; - -      if (nexthops_len < listcount (list)) -        { -          nexthops_len = listcount (list); -          nexthops = XREALLOC (MTYPE_TMP, nexthops, -                               nexthops_len * sizeof (struct in_addr *)); -        } - -      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); -      for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo)) -        { -          nexthops[count++] = &rinfo->nexthop; -          if (cmd == ZEBRA_IPV4_ROUTE_ADD) -            SET_FLAG (rinfo->flags, RIP_RTF_FIB); -          else -            UNSET_FLAG (rinfo->flags, RIP_RTF_FIB); -        } - -      api.nexthop = nexthops; -      api.nexthop_num = count; -      api.ifindex_num = 0; - -      rinfo = listgetdata (listhead (list)); - -      SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); -      api.metric = rinfo->metric; - -      if (rinfo->distance && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT) -        { -          SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); -          api.distance = rinfo->distance; -        } - -      if (rinfo->tag) -        { -          SET_FLAG (api.message, ZAPI_MESSAGE_TAG); -          api.tag = rinfo->tag; -        } - -      zapi_ipv4_route (cmd, zclient, -                       (struct prefix_ipv4 *)&rp->p, &api); - -      if (IS_RIP_DEBUG_ZEBRA) -        { -          if (rip->ecmp) -            zlog_debug ("%s: %s/%d nexthops %d", -                        (cmd == ZEBRA_IPV4_ROUTE_ADD) ? \ -                            "Install into zebra" : "Delete from zebra", -                        inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen, count); -          else -            zlog_debug ("%s: %s/%d", -                        (cmd == ZEBRA_IPV4_ROUTE_ADD) ? \ -                            "Install into zebra" : "Delete from zebra", -                        inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen); -        } - -      rip_global_route_changes++; -    } +	static struct in_addr **nexthops = NULL; +	static unsigned int nexthops_len = 0; + +	struct list *list = (struct list *)rp->info; +	struct zapi_ipv4 api; +	struct listnode *listnode = NULL; +	struct rip_info *rinfo = NULL; +	int count = 0; + +	if (vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], +			     VRF_DEFAULT)) { +		api.vrf_id = VRF_DEFAULT; +		api.type = ZEBRA_ROUTE_RIP; +		api.instance = 0; +		api.flags = 0; +		api.message = 0; +		api.safi = SAFI_UNICAST; + +		if (nexthops_len < listcount(list)) { +			nexthops_len = listcount(list); +			nexthops = XREALLOC(MTYPE_TMP, nexthops, +					    nexthops_len +						    * sizeof(struct in_addr *)); +		} + +		SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); +		for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { +			nexthops[count++] = &rinfo->nexthop; +			if (cmd == ZEBRA_IPV4_ROUTE_ADD) +				SET_FLAG(rinfo->flags, RIP_RTF_FIB); +			else +				UNSET_FLAG(rinfo->flags, RIP_RTF_FIB); +		} + +		api.nexthop = nexthops; +		api.nexthop_num = count; +		api.ifindex_num = 0; + +		rinfo = listgetdata(listhead(list)); + +		SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); +		api.metric = rinfo->metric; + +		if (rinfo->distance +		    && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT) { +			SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); +			api.distance = rinfo->distance; +		} + +		if (rinfo->tag) { +			SET_FLAG(api.message, ZAPI_MESSAGE_TAG); +			api.tag = rinfo->tag; +		} + +		zapi_ipv4_route(cmd, zclient, (struct prefix_ipv4 *)&rp->p, +				&api); + +		if (IS_RIP_DEBUG_ZEBRA) { +			if (rip->ecmp) +				zlog_debug("%s: %s/%d nexthops %d", +					   (cmd == ZEBRA_IPV4_ROUTE_ADD) +						   ? "Install into zebra" +						   : "Delete from zebra", +					   inet_ntoa(rp->p.u.prefix4), +					   rp->p.prefixlen, count); +			else +				zlog_debug("%s: %s/%d", +					   (cmd == ZEBRA_IPV4_ROUTE_ADD) +						   ? "Install into zebra" +						   : "Delete from zebra", +					   inet_ntoa(rp->p.u.prefix4), +					   rp->p.prefixlen); +		} + +		rip_global_route_changes++; +	}  }  /* Add/update ECMP routes to zebra. */ -void -rip_zebra_ipv4_add (struct route_node *rp) +void rip_zebra_ipv4_add(struct route_node *rp)  { -  rip_zebra_ipv4_send (rp, ZEBRA_IPV4_ROUTE_ADD); +	rip_zebra_ipv4_send(rp, ZEBRA_IPV4_ROUTE_ADD);  }  /* Delete ECMP routes from zebra. */ -void -rip_zebra_ipv4_delete (struct route_node *rp) +void rip_zebra_ipv4_delete(struct route_node *rp)  { -  rip_zebra_ipv4_send (rp, ZEBRA_IPV4_ROUTE_DELETE); +	rip_zebra_ipv4_send(rp, ZEBRA_IPV4_ROUTE_DELETE);  }  /* Zebra route add and delete treatment. */ -static int -rip_zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length, -    vrf_id_t vrf_id) +static int rip_zebra_read_ipv4(int command, struct zclient *zclient, +			       zebra_size_t length, vrf_id_t vrf_id)  { -  struct stream *s; -  struct zapi_ipv4 api; -  unsigned long ifindex; -  struct in_addr nexthop; -  struct prefix_ipv4 p; - -  if (!rip) -    return 0; - -  s = zclient->ibuf; -  ifindex = 0; -  nexthop.s_addr = 0; - -  /* Type, flags, message. */ -  api.type = stream_getc (s); -  api.instance = stream_getw (s); -  api.flags = stream_getl (s); -  api.message = stream_getc (s); - -  /* IPv4 prefix. */ -  memset (&p, 0, sizeof (struct prefix_ipv4)); -  p.family = AF_INET; -  p.prefixlen = MIN(IPV4_MAX_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); -  else -    api.distance = 255; -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) -    api.metric = stream_getl (s); -  else -    api.metric = 0; - -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG)) -    api.tag = stream_getl (s); -  else -    api.tag = 0; - -  /* Then fetch IPv4 prefixes. */ -  if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) -    rip_redistribute_add (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex,  -                          &nexthop, api.metric, api.distance, api.tag); -  else if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL) -    rip_redistribute_delete (api.type, RIP_ROUTE_REDISTRIBUTE, &p, ifindex); - -  return 0; +	struct stream *s; +	struct zapi_ipv4 api; +	unsigned long ifindex; +	struct in_addr nexthop; +	struct prefix_ipv4 p; + +	if (!rip) +		return 0; + +	s = zclient->ibuf; +	ifindex = 0; +	nexthop.s_addr = 0; + +	/* Type, flags, message. */ +	api.type = stream_getc(s); +	api.instance = stream_getw(s); +	api.flags = stream_getl(s); +	api.message = stream_getc(s); + +	/* IPv4 prefix. */ +	memset(&p, 0, sizeof(struct prefix_ipv4)); +	p.family = AF_INET; +	p.prefixlen = MIN(IPV4_MAX_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); +	else +		api.distance = 255; +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) +		api.metric = stream_getl(s); +	else +		api.metric = 0; + +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) +		api.tag = stream_getl(s); +	else +		api.tag = 0; + +	/* Then fetch IPv4 prefixes. */ +	if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD) +		rip_redistribute_add(api.type, RIP_ROUTE_REDISTRIBUTE, &p, +				     ifindex, &nexthop, api.metric, +				     api.distance, api.tag); +	else if (command == ZEBRA_REDISTRIBUTE_IPV4_DEL) +		rip_redistribute_delete(api.type, RIP_ROUTE_REDISTRIBUTE, &p, +					ifindex); + +	return 0;  } -void -rip_zclient_reset (void) +void rip_zclient_reset(void)  { -  zclient_reset (zclient); +	zclient_reset(zclient);  }  /* RIP route-map set for redistribution */ -static void -rip_routemap_set (int type, const char *name) +static void rip_routemap_set(int type, const char *name)  { -  if (rip->route_map[type].name) -    free(rip->route_map[type].name); +	if (rip->route_map[type].name) +		free(rip->route_map[type].name); -  rip->route_map[type].name = strdup (name); -  rip->route_map[type].map = route_map_lookup_by_name (name); +	rip->route_map[type].name = strdup(name); +	rip->route_map[type].map = route_map_lookup_by_name(name);  } -static void -rip_redistribute_metric_set (int type, unsigned int metric) +static void rip_redistribute_metric_set(int type, unsigned int metric)  { -  rip->route_map[type].metric_config = 1; -  rip->route_map[type].metric = metric; +	rip->route_map[type].metric_config = 1; +	rip->route_map[type].metric = metric;  } -static int -rip_metric_unset (int type, unsigned int metric) +static int rip_metric_unset(int type, unsigned int metric)  {  #define DONT_CARE_METRIC_RIP 17   -  if (metric != DONT_CARE_METRIC_RIP && -      rip->route_map[type].metric != metric) -    return 1; -  rip->route_map[type].metric_config = 0; -  rip->route_map[type].metric = 0; -  return 0; +	if (metric != DONT_CARE_METRIC_RIP +	    && rip->route_map[type].metric != metric) +		return 1; +	rip->route_map[type].metric_config = 0; +	rip->route_map[type].metric = 0; +	return 0;  }  /* RIP route-map unset for redistribution */ -static int -rip_routemap_unset (int type, const char *name) +static int rip_routemap_unset(int type, const char *name)  { -  if (! rip->route_map[type].name || -      (name != NULL && strcmp(rip->route_map[type].name,name))) -    return 1; +	if (!rip->route_map[type].name +	    || (name != NULL && strcmp(rip->route_map[type].name, name))) +		return 1; -  free (rip->route_map[type].name); -  rip->route_map[type].name = NULL; -  rip->route_map[type].map = NULL; +	free(rip->route_map[type].name); +	rip->route_map[type].name = NULL; +	rip->route_map[type].map = NULL; -  return 0; +	return 0;  }  /* Redistribution types */  static struct { -  int type; -  int str_min_len; -  const char *str; -} redist_type[] = { -  {ZEBRA_ROUTE_KERNEL,  1, "kernel"}, -  {ZEBRA_ROUTE_CONNECT, 1, "connected"}, -  {ZEBRA_ROUTE_STATIC,  1, "static"}, -  {ZEBRA_ROUTE_OSPF,    1, "ospf"}, -  {ZEBRA_ROUTE_BGP,     2, "bgp"}, -  {ZEBRA_ROUTE_VNC,     1, "vnc"}, -  {0, 0, NULL} -}; - -static int -rip_redistribute_unset (int type) +	int type; +	int str_min_len; +	const char *str; +} redist_type[] = {{ZEBRA_ROUTE_KERNEL, 1, "kernel"}, +		   {ZEBRA_ROUTE_CONNECT, 1, "connected"}, +		   {ZEBRA_ROUTE_STATIC, 1, "static"}, +		   {ZEBRA_ROUTE_OSPF, 1, "ospf"}, +		   {ZEBRA_ROUTE_BGP, 2, "bgp"}, +		   {ZEBRA_ROUTE_VNC, 1, "vnc"}, +		   {0, 0, NULL}}; + +static int rip_redistribute_unset(int type)  { -  if (! vrf_bitmap_check (zclient->redist[AFI_IP][type], VRF_DEFAULT)) -    return CMD_SUCCESS; +	if (!vrf_bitmap_check(zclient->redist[AFI_IP][type], VRF_DEFAULT)) +		return CMD_SUCCESS; -  vrf_bitmap_unset (zclient->redist[AFI_IP][type], VRF_DEFAULT); +	vrf_bitmap_unset(zclient->redist[AFI_IP][type], VRF_DEFAULT); -  if (zclient->sock > 0) -    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, 0, VRF_DEFAULT); +	if (zclient->sock > 0) +		zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, +					AFI_IP, type, 0, VRF_DEFAULT); -  /* Remove the routes from RIP table. */ -  rip_redistribute_withdraw (type); +	/* Remove the routes from RIP table. */ +	rip_redistribute_withdraw(type); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } -int -rip_redistribute_check (int type) +int rip_redistribute_check(int type)  { -  return vrf_bitmap_check (zclient->redist[AFI_IP][type], VRF_DEFAULT); +	return vrf_bitmap_check(zclient->redist[AFI_IP][type], VRF_DEFAULT);  } -void -rip_redistribute_clean (void) +void rip_redistribute_clean(void)  { -  int i; - -  for (i = 0; redist_type[i].str; i++) -    { -      if (vrf_bitmap_check (zclient->redist[AFI_IP][redist_type[i].type], VRF_DEFAULT)) -	{ -	  if (zclient->sock > 0) -	    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, -				     zclient, AFI_IP, redist_type[i].type, 0, -				     VRF_DEFAULT); - -	  vrf_bitmap_unset (zclient->redist[AFI_IP][redist_type[i].type], VRF_DEFAULT); - -	  /* Remove the routes from RIP table. */ -	  rip_redistribute_withdraw (redist_type[i].type); +	int i; + +	for (i = 0; redist_type[i].str; i++) { +		if (vrf_bitmap_check( +			    zclient->redist[AFI_IP][redist_type[i].type], +			    VRF_DEFAULT)) { +			if (zclient->sock > 0) +				zebra_redistribute_send( +					ZEBRA_REDISTRIBUTE_DELETE, zclient, +					AFI_IP, redist_type[i].type, 0, +					VRF_DEFAULT); + +			vrf_bitmap_unset( +				zclient->redist[AFI_IP][redist_type[i].type], +				VRF_DEFAULT); + +			/* Remove the routes from RIP table. */ +			rip_redistribute_withdraw(redist_type[i].type); +		}  	} -    }  }  DEFUN (rip_redistribute_rip, @@ -313,8 +304,8 @@ DEFUN (rip_redistribute_rip,         "Redistribute information from another routing protocol\n"         "Routing Information Protocol (RIP)\n")  { -  vrf_bitmap_set (zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], VRF_DEFAULT); -  return CMD_SUCCESS; +	vrf_bitmap_set(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], VRF_DEFAULT); +	return CMD_SUCCESS;  }  DEFUN (no_rip_redistribute_rip, @@ -324,8 +315,8 @@ DEFUN (no_rip_redistribute_rip,         "Redistribute information from another routing protocol\n"         "Routing Information Protocol (RIP)\n")  { -  vrf_bitmap_unset (zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], VRF_DEFAULT); -  return CMD_SUCCESS; +	vrf_bitmap_unset(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], VRF_DEFAULT); +	return CMD_SUCCESS;  }  DEFUN (rip_redistribute_type, @@ -334,22 +325,22 @@ DEFUN (rip_redistribute_type,         REDIST_STR         FRR_REDIST_HELP_STR_RIPD)  { -  int i; - -  for(i = 0; redist_type[i].str; i++)  -    { -      if (strncmp (redist_type[i].str, argv[1]->arg,  -		   redist_type[i].str_min_len) == 0)  -	{ -	  zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient,  -	                        AFI_IP, redist_type[i].type, 0, VRF_DEFAULT); -	  return CMD_SUCCESS; +	int i; + +	for (i = 0; redist_type[i].str; i++) { +		if (strncmp(redist_type[i].str, argv[1]->arg, +			    redist_type[i].str_min_len) +		    == 0) { +			zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, +					     AFI_IP, redist_type[i].type, 0, +					     VRF_DEFAULT); +			return CMD_SUCCESS; +		}  	} -    } -  vty_out (vty, "Invalid type %s\n",argv[1]->arg); +	vty_out(vty, "Invalid type %s\n", argv[1]->arg); -  return CMD_WARNING_CONFIG_FAILED; +	return CMD_WARNING_CONFIG_FAILED;  }  DEFUN (no_rip_redistribute_type, @@ -359,23 +350,23 @@ DEFUN (no_rip_redistribute_type,         REDIST_STR         FRR_REDIST_HELP_STR_RIPD)  { -  int i; - -  for (i = 0; redist_type[i].str; i++)  -    { -      if (strncmp(redist_type[i].str, argv[2]->arg,  -		  redist_type[i].str_min_len) == 0)  -	{ -	  rip_metric_unset (redist_type[i].type, DONT_CARE_METRIC_RIP); -	  rip_routemap_unset (redist_type[i].type,NULL); -	  rip_redistribute_unset (redist_type[i].type); -	  return CMD_SUCCESS; -        } -    } - -  vty_out (vty, "Invalid type %s\n",argv[2]->arg); - -  return CMD_WARNING_CONFIG_FAILED; +	int i; + +	for (i = 0; redist_type[i].str; i++) { +		if (strncmp(redist_type[i].str, argv[2]->arg, +			    redist_type[i].str_min_len) +		    == 0) { +			rip_metric_unset(redist_type[i].type, +					 DONT_CARE_METRIC_RIP); +			rip_routemap_unset(redist_type[i].type, NULL); +			rip_redistribute_unset(redist_type[i].type); +			return CMD_SUCCESS; +		} +	} + +	vty_out(vty, "Invalid type %s\n", argv[2]->arg); + +	return CMD_WARNING_CONFIG_FAILED;  }  DEFUN (rip_redistribute_type_routemap, @@ -386,23 +377,24 @@ DEFUN (rip_redistribute_type_routemap,         "Route map reference\n"         "Pointer to route-map entries\n")  { -  int idx_protocol = 1; -  int idx_word = 3; -  int i; - -  for (i = 0; redist_type[i].str; i++) { -    if (strmatch (redist_type[i].str, argv[idx_protocol]->text)) -      { -	rip_routemap_set (redist_type[i].type, argv[idx_word]->arg); -	zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, -                              redist_type[i].type, 0, VRF_DEFAULT); -	return CMD_SUCCESS; -      } -  } +	int idx_protocol = 1; +	int idx_word = 3; +	int i; + +	for (i = 0; redist_type[i].str; i++) { +		if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) { +			rip_routemap_set(redist_type[i].type, +					 argv[idx_word]->arg); +			zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, +					     AFI_IP, redist_type[i].type, 0, +					     VRF_DEFAULT); +			return CMD_SUCCESS; +		} +	} -  vty_out (vty, "Invalid type %s\n", argv[idx_protocol]->text); +	vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); -  return CMD_WARNING_CONFIG_FAILED; +	return CMD_WARNING_CONFIG_FAILED;  }  DEFUN (no_rip_redistribute_type_routemap, @@ -414,23 +406,23 @@ DEFUN (no_rip_redistribute_type_routemap,         "Route map reference\n"         "Pointer to route-map entries\n")  { -  int idx_protocol = 2; -  int idx_word = 4; -  int i; - -  for (i = 0; redist_type[i].str; i++) { -    if (strmatch (redist_type[i].str, argv[idx_protocol]->text)) -      { -        if (rip_routemap_unset (redist_type[i].type,argv[idx_word]->arg)) -          return CMD_WARNING_CONFIG_FAILED; -        rip_redistribute_unset (redist_type[i].type); -        return CMD_SUCCESS; -      } -  } - -  vty_out (vty, "Invalid type %s\n", argv[idx_protocol]->text); - -  return CMD_WARNING_CONFIG_FAILED; +	int idx_protocol = 2; +	int idx_word = 4; +	int i; + +	for (i = 0; redist_type[i].str; i++) { +		if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) { +			if (rip_routemap_unset(redist_type[i].type, +					       argv[idx_word]->arg)) +				return CMD_WARNING_CONFIG_FAILED; +			rip_redistribute_unset(redist_type[i].type); +			return CMD_SUCCESS; +		} +	} + +	vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); + +	return CMD_WARNING_CONFIG_FAILED;  }  DEFUN (rip_redistribute_type_metric, @@ -441,26 +433,27 @@ DEFUN (rip_redistribute_type_metric,         "Metric\n"         "Metric value\n")  { -  int idx_protocol = 1; -  int idx_number = 3; -  int i; -  int metric; - -  metric = atoi (argv[idx_number]->arg); - -  for (i = 0; redist_type[i].str; i++) { -    if (strmatch (redist_type[i].str, argv[idx_protocol]->text)) -      { -	rip_redistribute_metric_set (redist_type[i].type, metric); -	zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, -                              redist_type[i].type, 0, VRF_DEFAULT); -	return CMD_SUCCESS; -      } -  } +	int idx_protocol = 1; +	int idx_number = 3; +	int i; +	int metric; + +	metric = atoi(argv[idx_number]->arg); + +	for (i = 0; redist_type[i].str; i++) { +		if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) { +			rip_redistribute_metric_set(redist_type[i].type, +						    metric); +			zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, +					     AFI_IP, redist_type[i].type, 0, +					     VRF_DEFAULT); +			return CMD_SUCCESS; +		} +	} -  vty_out (vty, "Invalid type %s\n", argv[idx_protocol]->text); +	vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); -  return CMD_WARNING_CONFIG_FAILED; +	return CMD_WARNING_CONFIG_FAILED;  }  DEFUN (no_rip_redistribute_type_metric, @@ -472,23 +465,23 @@ DEFUN (no_rip_redistribute_type_metric,         "Metric\n"         "Metric value\n")  { -  int idx_protocol = 2; -  int idx_number = 4; -  int i; - -  for (i = 0; redist_type[i].str; i++) { -    if (strmatch (redist_type[i].str, argv[idx_protocol]->text)) -      { -        if (rip_metric_unset (redist_type[i].type, atoi(argv[idx_number]->arg))) -          return CMD_WARNING_CONFIG_FAILED; -        rip_redistribute_unset (redist_type[i].type); -        return CMD_SUCCESS; -      } -  } - -  vty_out (vty, "Invalid type %s\n", argv[idx_protocol]->text); - -  return CMD_WARNING_CONFIG_FAILED; +	int idx_protocol = 2; +	int idx_number = 4; +	int i; + +	for (i = 0; redist_type[i].str; i++) { +		if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) { +			if (rip_metric_unset(redist_type[i].type, +					     atoi(argv[idx_number]->arg))) +				return CMD_WARNING_CONFIG_FAILED; +			rip_redistribute_unset(redist_type[i].type); +			return CMD_SUCCESS; +		} +	} + +	vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); + +	return CMD_WARNING_CONFIG_FAILED;  }  DEFUN (rip_redistribute_type_metric_routemap, @@ -501,28 +494,30 @@ DEFUN (rip_redistribute_type_metric_routemap,         "Route map reference\n"         "Pointer to route-map entries\n")  { -  int idx_protocol = 1; -  int idx_number = 3; -  int idx_word = 5; -  int i; -  int metric; - -  metric = atoi (argv[idx_number]->arg); - -  for (i = 0; redist_type[i].str; i++) { -    if (strmatch (redist_type[i].str, argv[idx_protocol]->text)) -      { -	rip_redistribute_metric_set (redist_type[i].type, metric); -	rip_routemap_set (redist_type[i].type, argv[idx_word]->arg); -	zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, -                              redist_type[i].type, 0, VRF_DEFAULT); -	return CMD_SUCCESS; -      } -  } +	int idx_protocol = 1; +	int idx_number = 3; +	int idx_word = 5; +	int i; +	int metric; + +	metric = atoi(argv[idx_number]->arg); + +	for (i = 0; redist_type[i].str; i++) { +		if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) { +			rip_redistribute_metric_set(redist_type[i].type, +						    metric); +			rip_routemap_set(redist_type[i].type, +					 argv[idx_word]->arg); +			zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, +					     AFI_IP, redist_type[i].type, 0, +					     VRF_DEFAULT); +			return CMD_SUCCESS; +		} +	} -  vty_out (vty, "Invalid type %s\n", argv[idx_protocol]->text); +	vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); -  return CMD_WARNING_CONFIG_FAILED; +	return CMD_WARNING_CONFIG_FAILED;  } @@ -537,29 +532,31 @@ DEFUN (no_rip_redistribute_type_metric_routemap,         "Route map reference\n"         "Pointer to route-map entries\n")  { -  int idx_protocol = 2; -  int idx_number = 4; -  int idx_word = 6; -  int i; - -  for (i = 0; redist_type[i].str; i++) { -    if (strmatch (redist_type[i].str, argv[idx_protocol]->text)) -      { -        if (rip_metric_unset (redist_type[i].type, atoi(argv[idx_number]->arg))) -          return CMD_WARNING_CONFIG_FAILED; -        if (rip_routemap_unset (redist_type[i].type, argv[idx_word]->arg)) -          { -            rip_redistribute_metric_set(redist_type[i].type, atoi(argv[idx_number]->arg)); -            return CMD_WARNING_CONFIG_FAILED; -          } -        rip_redistribute_unset (redist_type[i].type); -        return CMD_SUCCESS; -      } -    } - -  vty_out (vty, "Invalid type %s\n", argv[idx_protocol]->text); - -  return CMD_WARNING_CONFIG_FAILED; +	int idx_protocol = 2; +	int idx_number = 4; +	int idx_word = 6; +	int i; + +	for (i = 0; redist_type[i].str; i++) { +		if (strmatch(redist_type[i].str, argv[idx_protocol]->text)) { +			if (rip_metric_unset(redist_type[i].type, +					     atoi(argv[idx_number]->arg))) +				return CMD_WARNING_CONFIG_FAILED; +			if (rip_routemap_unset(redist_type[i].type, +					       argv[idx_word]->arg)) { +				rip_redistribute_metric_set( +					redist_type[i].type, +					atoi(argv[idx_number]->arg)); +				return CMD_WARNING_CONFIG_FAILED; +			} +			rip_redistribute_unset(redist_type[i].type); +			return CMD_SUCCESS; +		} +	} + +	vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); + +	return CMD_WARNING_CONFIG_FAILED;  }  /* Default information originate. */ @@ -570,20 +567,19 @@ DEFUN (rip_default_information_originate,         "Control distribution of default route\n"         "Distribute a default route\n")  { -  struct prefix_ipv4 p; +	struct prefix_ipv4 p; + +	if (!rip->default_information) { +		memset(&p, 0, sizeof(struct prefix_ipv4)); +		p.family = AF_INET; -  if (! rip->default_information) -    { -      memset (&p, 0, sizeof (struct prefix_ipv4)); -      p.family = AF_INET; +		rip->default_information = 1; -      rip->default_information = 1; -   -      rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0,  -                            NULL, 0, 0, 0); -    } +		rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0, +				     NULL, 0, 0, 0); +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_rip_default_information_originate, @@ -593,128 +589,125 @@ DEFUN (no_rip_default_information_originate,         "Control distribution of default route\n"         "Distribute a default route\n")  { -  struct prefix_ipv4 p; +	struct prefix_ipv4 p; + +	if (rip->default_information) { +		memset(&p, 0, sizeof(struct prefix_ipv4)); +		p.family = AF_INET; -  if (rip->default_information) -    { -      memset (&p, 0, sizeof (struct prefix_ipv4)); -      p.family = AF_INET; +		rip->default_information = 0; -      rip->default_information = 0; -   -      rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, 0); -    } +		rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, +					0); +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* RIP configuration write function. */ -static int -config_write_zebra (struct vty *vty) +static int config_write_zebra(struct vty *vty)  { -  if (! zclient->enable) -    { -      vty_out (vty, "no router zebra\n"); -      return 1; -    } -  else if (! vrf_bitmap_check (zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], VRF_DEFAULT)) -    { -      vty_out (vty, "router zebra\n"); -      vty_out (vty, " no redistribute rip\n"); -      return 1; -    } -  return 0; +	if (!zclient->enable) { +		vty_out(vty, "no router zebra\n"); +		return 1; +	} else if (!vrf_bitmap_check(zclient->redist[AFI_IP][ZEBRA_ROUTE_RIP], +				     VRF_DEFAULT)) { +		vty_out(vty, "router zebra\n"); +		vty_out(vty, " no redistribute rip\n"); +		return 1; +	} +	return 0;  } -int -config_write_rip_redistribute (struct vty *vty, int config_mode) +int config_write_rip_redistribute(struct vty *vty, int config_mode)  { -  int i; - -  for (i = 0; i < ZEBRA_ROUTE_MAX; i++) -    if (i != zclient->redist_default && -        vrf_bitmap_check (zclient->redist[AFI_IP][i], VRF_DEFAULT)) -      { -	if (config_mode) -	  { -	    if (rip->route_map[i].metric_config) -	      { -		if (rip->route_map[i].name) -		  vty_out (vty, " redistribute %s metric %d route-map %s\n", -			   zebra_route_string(i), rip->route_map[i].metric, -			   rip->route_map[i].name); -		else -		  vty_out (vty, " redistribute %s metric %d\n", -			   zebra_route_string(i),rip->route_map[i].metric); -	      } -	    else -	      { -		if (rip->route_map[i].name) -		  vty_out (vty, " redistribute %s route-map %s\n", -			   zebra_route_string(i),rip->route_map[i].name); -		else -		  vty_out (vty, " redistribute %s\n",zebra_route_string(i)); -	      } -	  } -	else -	  vty_out (vty, " %s", zebra_route_string(i)); -      } -  return 0; +	int i; + +	for (i = 0; i < ZEBRA_ROUTE_MAX; i++) +		if (i != zclient->redist_default +		    && vrf_bitmap_check(zclient->redist[AFI_IP][i], +					VRF_DEFAULT)) { +			if (config_mode) { +				if (rip->route_map[i].metric_config) { +					if (rip->route_map[i].name) +						vty_out(vty, +							" redistribute %s metric %d route-map %s\n", +							zebra_route_string(i), +							rip->route_map[i] +								.metric, +							rip->route_map[i].name); +					else +						vty_out(vty, +							" redistribute %s metric %d\n", +							zebra_route_string(i), +							rip->route_map[i] +								.metric); +				} else { +					if (rip->route_map[i].name) +						vty_out(vty, +							" redistribute %s route-map %s\n", +							zebra_route_string(i), +							rip->route_map[i].name); +					else +						vty_out(vty, +							" redistribute %s\n", +							zebra_route_string(i)); +				} +			} else +				vty_out(vty, " %s", zebra_route_string(i)); +		} +	return 0;  }  /* Zebra node structure. */ -static struct cmd_node zebra_node = -{ -  ZEBRA_NODE, -  "%s(config-router)# ", +static struct cmd_node zebra_node = { +	ZEBRA_NODE, "%s(config-router)# ",  }; -static void -rip_zebra_connected (struct zclient *zclient) +static void rip_zebra_connected(struct zclient *zclient)  { -  zclient_send_reg_requests (zclient, VRF_DEFAULT); +	zclient_send_reg_requests(zclient, VRF_DEFAULT);  } -void -rip_zclient_init (struct thread_master *master) +void rip_zclient_init(struct thread_master *master)  { -  /* Set default value to the zebra client structure. */ -  zclient = zclient_new(master); -  zclient_init (zclient, ZEBRA_ROUTE_RIP, 0); -  zclient->zebra_connected = rip_zebra_connected; -  zclient->interface_add = rip_interface_add; -  zclient->interface_delete = rip_interface_delete; -  zclient->interface_address_add = rip_interface_address_add; -  zclient->interface_address_delete = rip_interface_address_delete; -  zclient->interface_up = rip_interface_up; -  zclient->interface_down = rip_interface_down; -  zclient->redistribute_route_ipv4_add = rip_zebra_read_ipv4; -  zclient->redistribute_route_ipv4_del = rip_zebra_read_ipv4; -   -  /* Install zebra node. */ -  install_node (&zebra_node, config_write_zebra); - -  /* Install command elements to zebra node. */  -  install_default (ZEBRA_NODE); -  install_element (ZEBRA_NODE, &rip_redistribute_rip_cmd); -  install_element (ZEBRA_NODE, &no_rip_redistribute_rip_cmd); - -  /* Install command elements to rip node. */ -  install_element (RIP_NODE, &rip_redistribute_type_cmd); -  install_element (RIP_NODE, &rip_redistribute_type_routemap_cmd); -  install_element (RIP_NODE, &rip_redistribute_type_metric_cmd); -  install_element (RIP_NODE, &rip_redistribute_type_metric_routemap_cmd); -  install_element (RIP_NODE, &no_rip_redistribute_type_cmd); -  install_element (RIP_NODE, &no_rip_redistribute_type_routemap_cmd); -  install_element (RIP_NODE, &no_rip_redistribute_type_metric_cmd); -  install_element (RIP_NODE, &no_rip_redistribute_type_metric_routemap_cmd); -  install_element (RIP_NODE, &rip_default_information_originate_cmd); -  install_element (RIP_NODE, &no_rip_default_information_originate_cmd); +	/* Set default value to the zebra client structure. */ +	zclient = zclient_new(master); +	zclient_init(zclient, ZEBRA_ROUTE_RIP, 0); +	zclient->zebra_connected = rip_zebra_connected; +	zclient->interface_add = rip_interface_add; +	zclient->interface_delete = rip_interface_delete; +	zclient->interface_address_add = rip_interface_address_add; +	zclient->interface_address_delete = rip_interface_address_delete; +	zclient->interface_up = rip_interface_up; +	zclient->interface_down = rip_interface_down; +	zclient->redistribute_route_ipv4_add = rip_zebra_read_ipv4; +	zclient->redistribute_route_ipv4_del = rip_zebra_read_ipv4; + +	/* Install zebra node. */ +	install_node(&zebra_node, config_write_zebra); + +	/* Install command elements to zebra node. */ +	install_default(ZEBRA_NODE); +	install_element(ZEBRA_NODE, &rip_redistribute_rip_cmd); +	install_element(ZEBRA_NODE, &no_rip_redistribute_rip_cmd); + +	/* Install command elements to rip node. */ +	install_element(RIP_NODE, &rip_redistribute_type_cmd); +	install_element(RIP_NODE, &rip_redistribute_type_routemap_cmd); +	install_element(RIP_NODE, &rip_redistribute_type_metric_cmd); +	install_element(RIP_NODE, &rip_redistribute_type_metric_routemap_cmd); +	install_element(RIP_NODE, &no_rip_redistribute_type_cmd); +	install_element(RIP_NODE, &no_rip_redistribute_type_routemap_cmd); +	install_element(RIP_NODE, &no_rip_redistribute_type_metric_cmd); +	install_element(RIP_NODE, +			&no_rip_redistribute_type_metric_routemap_cmd); +	install_element(RIP_NODE, &rip_default_information_originate_cmd); +	install_element(RIP_NODE, &no_rip_default_information_originate_cmd);  } -void -rip_zclient_stop (void) +void rip_zclient_stop(void)  { -  zclient_stop (zclient); -  zclient_free (zclient); +	zclient_stop(zclient); +	zclient_free(zclient);  } diff --git a/ripd/ripd.c b/ripd/ripd.c index 8578dc3d21..d9b38bba89 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -65,187 +65,171 @@ long rip_global_route_changes = 0;  long rip_global_queries = 0;  /* Prototypes. */ -static void rip_event (enum rip_event, int); -static void rip_output_process (struct connected *, struct sockaddr_in *, int, u_char); -static int rip_triggered_update (struct thread *); -static int rip_update_jitter (unsigned long); +static void rip_event(enum rip_event, int); +static void rip_output_process(struct connected *, struct sockaddr_in *, int, +			       u_char); +static int rip_triggered_update(struct thread *); +static int rip_update_jitter(unsigned long);  /* RIP output routes type. */ -enum -{ -  rip_all_route, -  rip_changed_route -}; +enum { rip_all_route, rip_changed_route };  /* RIP command strings. */ -static const struct message rip_msg[] = -{ -  {RIP_REQUEST,    "REQUEST"}, -  {RIP_RESPONSE,   "RESPONSE"}, -  {RIP_TRACEON,    "TRACEON"}, -  {RIP_TRACEOFF,   "TRACEOFF"}, -  {RIP_POLL,       "POLL"}, -  {RIP_POLL_ENTRY, "POLL ENTRY"}, -  { 0 } -}; +static const struct message rip_msg[] = {{RIP_REQUEST, "REQUEST"}, +					 {RIP_RESPONSE, "RESPONSE"}, +					 {RIP_TRACEON, "TRACEON"}, +					 {RIP_TRACEOFF, "TRACEOFF"}, +					 {RIP_POLL, "POLL"}, +					 {RIP_POLL_ENTRY, "POLL ENTRY"}, +					 {0}};  /* Utility function to set boradcast option to the socket. */ -static int -sockopt_broadcast (int sock) +static int sockopt_broadcast(int sock)  { -  int ret; -  int on = 1; +	int ret; +	int on = 1; -  ret = setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof on); -  if (ret < 0) -    { -      zlog_warn ("can't set sockopt SO_BROADCAST to socket %d", sock); -      return -1; -    } -  return 0; +	ret = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on, +			 sizeof on); +	if (ret < 0) { +		zlog_warn("can't set sockopt SO_BROADCAST to socket %d", sock); +		return -1; +	} +	return 0;  } -static int -rip_route_rte (struct rip_info *rinfo) +static int rip_route_rte(struct rip_info *rinfo)  { -  return (rinfo->type == ZEBRA_ROUTE_RIP && rinfo->sub_type == RIP_ROUTE_RTE); +	return (rinfo->type == ZEBRA_ROUTE_RIP +		&& rinfo->sub_type == RIP_ROUTE_RTE);  } -static struct rip_info * -rip_info_new (void) +static struct rip_info *rip_info_new(void)  { -  return XCALLOC (MTYPE_RIP_INFO, sizeof (struct rip_info)); +	return XCALLOC(MTYPE_RIP_INFO, sizeof(struct rip_info));  } -void -rip_info_free (struct rip_info *rinfo) +void rip_info_free(struct rip_info *rinfo)  { -  XFREE (MTYPE_RIP_INFO, rinfo); +	XFREE(MTYPE_RIP_INFO, rinfo);  }  /* RIP route garbage collect timer. */ -static int -rip_garbage_collect (struct thread *t) +static int rip_garbage_collect(struct thread *t)  { -  struct rip_info *rinfo; -  struct route_node *rp; +	struct rip_info *rinfo; +	struct route_node *rp; + +	rinfo = THREAD_ARG(t); +	rinfo->t_garbage_collect = NULL; -  rinfo = THREAD_ARG (t); -  rinfo->t_garbage_collect = NULL; +	/* Off timeout timer. */ +	RIP_TIMER_OFF(rinfo->t_timeout); -  /* Off timeout timer. */ -  RIP_TIMER_OFF (rinfo->t_timeout); -   -  /* Get route_node pointer. */ -  rp = rinfo->rp; +	/* Get route_node pointer. */ +	rp = rinfo->rp; -  /* Unlock route_node. */ -  listnode_delete (rp->info, rinfo); -  if (list_isempty ((struct list *)rp->info)) -    { -      list_free (rp->info); -      rp->info = NULL; -      route_unlock_node (rp); -    } +	/* Unlock route_node. */ +	listnode_delete(rp->info, rinfo); +	if (list_isempty((struct list *)rp->info)) { +		list_free(rp->info); +		rp->info = NULL; +		route_unlock_node(rp); +	} -  /* Free RIP routing information. */ -  rip_info_free (rinfo); +	/* Free RIP routing information. */ +	rip_info_free(rinfo); -  return 0; +	return 0;  } -static void rip_timeout_update (struct rip_info *rinfo); +static void rip_timeout_update(struct rip_info *rinfo);  /* Add new route to the ECMP list.   * RETURN: the new entry added in the list, or NULL if it is not the first   *         entry and ECMP is not allowed.   */ -struct rip_info * -rip_ecmp_add (struct rip_info *rinfo_new) +struct rip_info *rip_ecmp_add(struct rip_info *rinfo_new)  { -  struct route_node *rp = rinfo_new->rp; -  struct rip_info *rinfo = NULL; -  struct list *list = NULL; +	struct route_node *rp = rinfo_new->rp; +	struct rip_info *rinfo = NULL; +	struct list *list = NULL; -  if (rp->info == NULL) -    rp->info = list_new (); -  list = (struct list *)rp->info; +	if (rp->info == NULL) +		rp->info = list_new(); +	list = (struct list *)rp->info; -  /* If ECMP is not allowed and some entry already exists in the list, -   * do nothing. */ -  if (listcount (list) && !rip->ecmp) -    return NULL; +	/* If ECMP is not allowed and some entry already exists in the list, +	 * do nothing. */ +	if (listcount(list) && !rip->ecmp) +		return NULL; -  rinfo = rip_info_new (); -  memcpy (rinfo, rinfo_new, sizeof (struct rip_info)); -  listnode_add (list, rinfo); +	rinfo = rip_info_new(); +	memcpy(rinfo, rinfo_new, sizeof(struct rip_info)); +	listnode_add(list, rinfo); -  if (rip_route_rte (rinfo)) -    { -      rip_timeout_update (rinfo); -      rip_zebra_ipv4_add (rp); -    } +	if (rip_route_rte(rinfo)) { +		rip_timeout_update(rinfo); +		rip_zebra_ipv4_add(rp); +	} -  /* Set the route change flag on the first entry. */ -  rinfo = listgetdata (listhead (list)); -  SET_FLAG (rinfo->flags, RIP_RTF_CHANGED); +	/* Set the route change flag on the first entry. */ +	rinfo = listgetdata(listhead(list)); +	SET_FLAG(rinfo->flags, RIP_RTF_CHANGED); -  /* Signal the output process to trigger an update (see section 2.5). */ -  rip_event (RIP_TRIGGERED_UPDATE, 0); +	/* Signal the output process to trigger an update (see section 2.5). */ +	rip_event(RIP_TRIGGERED_UPDATE, 0); -  return rinfo; +	return rinfo;  }  /* Replace the ECMP list with the new route.   * RETURN: the new entry added in the list   */ -struct rip_info * -rip_ecmp_replace (struct rip_info *rinfo_new) -{ -  struct route_node *rp = rinfo_new->rp; -  struct list *list = (struct list *)rp->info; -  struct rip_info *rinfo = NULL, *tmp_rinfo = NULL; -  struct listnode *node = NULL, *nextnode = NULL; - -  if (list == NULL || listcount (list) == 0) -    return rip_ecmp_add (rinfo_new); - -  /* Get the first entry */ -  rinfo = listgetdata (listhead (list)); - -  /* Learnt route replaced by a local one. Delete it from zebra. */ -  if (rip_route_rte (rinfo) && !rip_route_rte (rinfo_new)) -    if (CHECK_FLAG (rinfo->flags, RIP_RTF_FIB)) -      rip_zebra_ipv4_delete (rp); - -  /* Re-use the first entry, and delete the others. */ -  for (ALL_LIST_ELEMENTS (list, node, nextnode, tmp_rinfo)) -    if (tmp_rinfo != rinfo) -      { -        RIP_TIMER_OFF (tmp_rinfo->t_timeout); -        RIP_TIMER_OFF (tmp_rinfo->t_garbage_collect); -        list_delete_node (list, node); -        rip_info_free (tmp_rinfo); -      } +struct rip_info *rip_ecmp_replace(struct rip_info *rinfo_new) +{ +	struct route_node *rp = rinfo_new->rp; +	struct list *list = (struct list *)rp->info; +	struct rip_info *rinfo = NULL, *tmp_rinfo = NULL; +	struct listnode *node = NULL, *nextnode = NULL; + +	if (list == NULL || listcount(list) == 0) +		return rip_ecmp_add(rinfo_new); + +	/* Get the first entry */ +	rinfo = listgetdata(listhead(list)); + +	/* Learnt route replaced by a local one. Delete it from zebra. */ +	if (rip_route_rte(rinfo) && !rip_route_rte(rinfo_new)) +		if (CHECK_FLAG(rinfo->flags, RIP_RTF_FIB)) +			rip_zebra_ipv4_delete(rp); + +	/* Re-use the first entry, and delete the others. */ +	for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo)) +		if (tmp_rinfo != rinfo) { +			RIP_TIMER_OFF(tmp_rinfo->t_timeout); +			RIP_TIMER_OFF(tmp_rinfo->t_garbage_collect); +			list_delete_node(list, node); +			rip_info_free(tmp_rinfo); +		} -  RIP_TIMER_OFF (rinfo->t_timeout); -  RIP_TIMER_OFF (rinfo->t_garbage_collect); -  memcpy (rinfo, rinfo_new, sizeof (struct rip_info)); +	RIP_TIMER_OFF(rinfo->t_timeout); +	RIP_TIMER_OFF(rinfo->t_garbage_collect); +	memcpy(rinfo, rinfo_new, sizeof(struct rip_info)); -  if (rip_route_rte (rinfo)) -    { -      rip_timeout_update (rinfo); -      /* The ADD message implies an update. */ -      rip_zebra_ipv4_add (rp); -    } +	if (rip_route_rte(rinfo)) { +		rip_timeout_update(rinfo); +		/* The ADD message implies an update. */ +		rip_zebra_ipv4_add(rp); +	} -  /* Set the route change flag. */ -  SET_FLAG (rinfo->flags, RIP_RTF_CHANGED); +	/* Set the route change flag. */ +	SET_FLAG(rinfo->flags, RIP_RTF_CHANGED); -  /* Signal the output process to trigger an update (see section 2.5). */ -  rip_event (RIP_TRIGGERED_UPDATE, 0); +	/* Signal the output process to trigger an update (see section 2.5). */ +	rip_event(RIP_TRIGGERED_UPDATE, 0); -  return rinfo; +	return rinfo;  }  /* Delete one route from the ECMP list. @@ -254,692 +238,694 @@ rip_ecmp_replace (struct rip_info *rinfo_new)   *  the entry - the entry is the last one in the list; its metric is set   *              to INFINITY, and the garbage collector is started for it   */ -struct rip_info * -rip_ecmp_delete (struct rip_info *rinfo) -{ -  struct route_node *rp = rinfo->rp; -  struct list *list = (struct list *)rp->info; - -  RIP_TIMER_OFF (rinfo->t_timeout); - -  if (listcount (list) > 1) -    { -      /* Some other ECMP entries still exist. Just delete this entry. */ -      RIP_TIMER_OFF (rinfo->t_garbage_collect); -      listnode_delete (list, rinfo); -      if (rip_route_rte (rinfo) && CHECK_FLAG (rinfo->flags, RIP_RTF_FIB)) -        /* The ADD message implies the update. */ -        rip_zebra_ipv4_add (rp); -      rip_info_free (rinfo); -      rinfo = NULL; -    } -  else -    { -      assert (rinfo == listgetdata (listhead (list))); - -      /* This is the only entry left in the list. We must keep it in -       * the list for garbage collection time, with INFINITY metric. */ - -      rinfo->metric = RIP_METRIC_INFINITY; -      RIP_TIMER_ON (rinfo->t_garbage_collect, -                    rip_garbage_collect, rip->garbage_time); - -      if (rip_route_rte (rinfo) && CHECK_FLAG (rinfo->flags, RIP_RTF_FIB)) -        rip_zebra_ipv4_delete (rp); -    } +struct rip_info *rip_ecmp_delete(struct rip_info *rinfo) +{ +	struct route_node *rp = rinfo->rp; +	struct list *list = (struct list *)rp->info; + +	RIP_TIMER_OFF(rinfo->t_timeout); + +	if (listcount(list) > 1) { +		/* Some other ECMP entries still exist. Just delete this entry. +		 */ +		RIP_TIMER_OFF(rinfo->t_garbage_collect); +		listnode_delete(list, rinfo); +		if (rip_route_rte(rinfo) +		    && CHECK_FLAG(rinfo->flags, RIP_RTF_FIB)) +			/* The ADD message implies the update. */ +			rip_zebra_ipv4_add(rp); +		rip_info_free(rinfo); +		rinfo = NULL; +	} else { +		assert(rinfo == listgetdata(listhead(list))); + +		/* This is the only entry left in the list. We must keep it in +		 * the list for garbage collection time, with INFINITY metric. +		 */ + +		rinfo->metric = RIP_METRIC_INFINITY; +		RIP_TIMER_ON(rinfo->t_garbage_collect, rip_garbage_collect, +			     rip->garbage_time); + +		if (rip_route_rte(rinfo) +		    && CHECK_FLAG(rinfo->flags, RIP_RTF_FIB)) +			rip_zebra_ipv4_delete(rp); +	} -  /* Set the route change flag on the first entry. */ -  rinfo = listgetdata (listhead (list)); -  SET_FLAG (rinfo->flags, RIP_RTF_CHANGED); +	/* Set the route change flag on the first entry. */ +	rinfo = listgetdata(listhead(list)); +	SET_FLAG(rinfo->flags, RIP_RTF_CHANGED); -  /* Signal the output process to trigger an update (see section 2.5). */ -  rip_event (RIP_TRIGGERED_UPDATE, 0); +	/* Signal the output process to trigger an update (see section 2.5). */ +	rip_event(RIP_TRIGGERED_UPDATE, 0); -  return rinfo; +	return rinfo;  }  /* Timeout RIP routes. */ -static int -rip_timeout (struct thread *t) +static int rip_timeout(struct thread *t)  { -  rip_ecmp_delete ((struct rip_info *)THREAD_ARG (t)); -  return 0; +	rip_ecmp_delete((struct rip_info *)THREAD_ARG(t)); +	return 0;  } -static void -rip_timeout_update (struct rip_info *rinfo) -{ -  if (rinfo->metric != RIP_METRIC_INFINITY) -    { -      RIP_TIMER_OFF (rinfo->t_timeout); -      RIP_TIMER_ON (rinfo->t_timeout, rip_timeout, rip->timeout_time); -    } -} - -static int -rip_filter (int rip_distribute, struct prefix_ipv4 *p, struct rip_interface *ri) -{ -  struct distribute *dist; -  struct access_list *alist; -  struct prefix_list *plist; -  int distribute = rip_distribute == RIP_FILTER_OUT ? -      DISTRIBUTE_V4_OUT : DISTRIBUTE_V4_IN; -  const char *inout = rip_distribute == RIP_FILTER_OUT ? "out" : "in"; - -  /* Input distribute-list filtering. */ -  if (ri->list[rip_distribute]) -    { -      if (access_list_apply (ri->list[rip_distribute], -			     (struct prefix *) p) == FILTER_DENY) -	{ -	  if (IS_RIP_DEBUG_PACKET) -	    zlog_debug ("%s/%d filtered by distribute %s", -                        inet_ntoa (p->prefix), p->prefixlen, inout); -		  return -1; -		} -	    } -  if (ri->prefix[rip_distribute]) +static void rip_timeout_update(struct rip_info *rinfo)  { -      if (prefix_list_apply (ri->prefix[rip_distribute], -			     (struct prefix *) p) == PREFIX_DENY) -	{ -	  if (IS_RIP_DEBUG_PACKET) -	    zlog_debug ("%s/%d filtered by prefix-list %s", -                        inet_ntoa (p->prefix), p->prefixlen, inout); -	  return -1; -	} -    } - -  /* All interface filter check. */ -  dist = distribute_lookup (NULL); -  if (dist) -    { -      if (dist->list[distribute]) -	{ -	  alist = access_list_lookup (AFI_IP, dist->list[distribute]); -	     -	  if (alist) -	    { -	      if (access_list_apply (alist, (struct prefix *) p) == FILTER_DENY) -		{ -		  if (IS_RIP_DEBUG_PACKET) -		    zlog_debug ("%s/%d filtered by distribute %s", -                                inet_ntoa (p->prefix), p->prefixlen, inout); -		  return -1; +	if (rinfo->metric != RIP_METRIC_INFINITY) { +		RIP_TIMER_OFF(rinfo->t_timeout); +		RIP_TIMER_ON(rinfo->t_timeout, rip_timeout, rip->timeout_time); +	} +} + +static int rip_filter(int rip_distribute, struct prefix_ipv4 *p, +		      struct rip_interface *ri) +{ +	struct distribute *dist; +	struct access_list *alist; +	struct prefix_list *plist; +	int distribute = rip_distribute == RIP_FILTER_OUT ? DISTRIBUTE_V4_OUT +							  : DISTRIBUTE_V4_IN; +	const char *inout = rip_distribute == RIP_FILTER_OUT ? "out" : "in"; + +	/* Input distribute-list filtering. */ +	if (ri->list[rip_distribute]) { +		if (access_list_apply(ri->list[rip_distribute], +				      (struct prefix *)p) +		    == FILTER_DENY) { +			if (IS_RIP_DEBUG_PACKET) +				zlog_debug("%s/%d filtered by distribute %s", +					   inet_ntoa(p->prefix), p->prefixlen, +					   inout); +			return -1;  		} -	    }  	} -      if (dist->prefix[distribute]) -	{ -	  plist = prefix_list_lookup (AFI_IP, dist->prefix[distribute]); -	   -	  if (plist) -	    { -	      if (prefix_list_apply (plist, -				     (struct prefix *) p) == PREFIX_DENY) -		{ -		  if (IS_RIP_DEBUG_PACKET) -		    zlog_debug ("%s/%d filtered by prefix-list %s", -                                inet_ntoa (p->prefix), p->prefixlen, inout); -		  return -1; +	if (ri->prefix[rip_distribute]) { +		if (prefix_list_apply(ri->prefix[rip_distribute], +				      (struct prefix *)p) +		    == PREFIX_DENY) { +			if (IS_RIP_DEBUG_PACKET) +				zlog_debug("%s/%d filtered by prefix-list %s", +					   inet_ntoa(p->prefix), p->prefixlen, +					   inout); +			return -1;  		} -	    }  	} -    } -  return 0; + +	/* All interface filter check. */ +	dist = distribute_lookup(NULL); +	if (dist) { +		if (dist->list[distribute]) { +			alist = access_list_lookup(AFI_IP, +						   dist->list[distribute]); + +			if (alist) { +				if (access_list_apply(alist, (struct prefix *)p) +				    == FILTER_DENY) { +					if (IS_RIP_DEBUG_PACKET) +						zlog_debug( +							"%s/%d filtered by distribute %s", +							inet_ntoa(p->prefix), +							p->prefixlen, inout); +					return -1; +				} +			} +		} +		if (dist->prefix[distribute]) { +			plist = prefix_list_lookup(AFI_IP, +						   dist->prefix[distribute]); + +			if (plist) { +				if (prefix_list_apply(plist, (struct prefix *)p) +				    == PREFIX_DENY) { +					if (IS_RIP_DEBUG_PACKET) +						zlog_debug( +							"%s/%d filtered by prefix-list %s", +							inet_ntoa(p->prefix), +							p->prefixlen, inout); +					return -1; +				} +			} +		} +	} +	return 0;  }  /* Check nexthop address validity. */ -static int -rip_nexthop_check (struct in_addr *addr) +static int rip_nexthop_check(struct in_addr *addr)  { -  struct listnode *node; -  struct listnode *cnode; -  struct interface *ifp; -  struct connected *ifc; -  struct prefix *p; +	struct listnode *node; +	struct listnode *cnode; +	struct interface *ifp; +	struct connected *ifc; +	struct prefix *p; -  /* If nexthop address matches local configured address then it is -     invalid nexthop. */ +	/* If nexthop address matches local configured address then it is +	   invalid nexthop. */ -  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) -    { -      for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, ifc)) -	{	     -	  p = ifc->address; +	for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { +		for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) { +			p = ifc->address; -	  if (p->family == AF_INET -	      && IPV4_ADDR_SAME (&p->u.prefix4, addr)) -	    return -1; +			if (p->family == AF_INET +			    && IPV4_ADDR_SAME(&p->u.prefix4, addr)) +				return -1; +		}  	} -    } -  return 0; +	return 0;  }  /* RIP add route to routing table. */ -static void -rip_rte_process (struct rte *rte, struct sockaddr_in *from, -                 struct interface *ifp) -{ -  int ret; -  struct prefix_ipv4 p; -  struct route_node *rp; -  struct rip_info *rinfo = NULL, newinfo; -  struct rip_interface *ri; -  struct in_addr *nexthop; -  int same = 0; -  unsigned char old_dist, new_dist; -  struct list *list = NULL; -  struct listnode *node = NULL; - -  /* Make prefix structure. */ -  memset (&p, 0, sizeof (struct prefix_ipv4)); -  p.family = AF_INET; -  p.prefix = rte->prefix; -  p.prefixlen = ip_masklen (rte->mask); - -  /* Make sure mask is applied. */ -  apply_mask_ipv4 (&p); - -  /* Apply input filters. */ -  ri = ifp->info; - -  ret = rip_filter (RIP_FILTER_IN, &p, ri); -  if (ret < 0) -    return; - -  memset (&newinfo, 0, sizeof (newinfo)); -  newinfo.type = ZEBRA_ROUTE_RIP; -  newinfo.sub_type = RIP_ROUTE_RTE; -  newinfo.nexthop = rte->nexthop; -  newinfo.from = from->sin_addr; -  newinfo.ifindex = ifp->ifindex; -  newinfo.metric = rte->metric; -  newinfo.metric_out = rte->metric; /* XXX */ -  newinfo.tag = ntohs (rte->tag);   /* XXX */ - -  /* Modify entry according to the interface routemap. */ -  if (ri->routemap[RIP_FILTER_IN]) -    { -      int ret; - -      /* The object should be of the type of rip_info */ -      ret = route_map_apply (ri->routemap[RIP_FILTER_IN], -                             (struct prefix *) &p, RMAP_RIP, &newinfo); - -      if (ret == RMAP_DENYMATCH) -        { -          if (IS_RIP_DEBUG_PACKET) -            zlog_debug ("RIP %s/%d is filtered by route-map in", -                       inet_ntoa (p.prefix), p.prefixlen); -          return; -        } - -      /* Get back the object */ -      rte->nexthop = newinfo.nexthop_out; -      rte->tag = htons (newinfo.tag_out);       /* XXX */ -      rte->metric = newinfo.metric_out; /* XXX: the routemap uses the metric_out field */ -    } - -  /* Once the entry has been validated, update the metric by -     adding the cost of the network on wich the message -     arrived. If the result is greater than infinity, use infinity -     (RFC2453 Sec. 3.9.2) */ -  /* Zebra ripd can handle offset-list in. */ -  ret = rip_offset_list_apply_in (&p, ifp, &rte->metric); - -  /* If offset-list does not modify the metric use interface's -     metric. */ -  if (!ret) -    rte->metric += ifp->metric ? ifp->metric : 1; - -  if (rte->metric > RIP_METRIC_INFINITY) -    rte->metric = RIP_METRIC_INFINITY; - -  /* Set nexthop pointer. */ -  if (rte->nexthop.s_addr == 0) -    nexthop = &from->sin_addr; -  else -    nexthop = &rte->nexthop; - -  /* Check if nexthop address is myself, then do nothing. */ -  if (rip_nexthop_check (nexthop) < 0) -    { -      if (IS_RIP_DEBUG_PACKET) -        zlog_debug ("Nexthop address %s is myself", inet_ntoa (*nexthop)); -      return; -    } - -  /* Get index for the prefix. */ -  rp = route_node_get (rip->table, (struct prefix *) &p); - -  newinfo.rp = rp; -  newinfo.nexthop = *nexthop; -  newinfo.metric = rte->metric; -  newinfo.tag = ntohs (rte->tag); -  newinfo.distance = rip_distance_apply (&newinfo); - -  new_dist = newinfo.distance ? newinfo.distance : ZEBRA_RIP_DISTANCE_DEFAULT; - -  /* Check to see whether there is already RIP route on the table. */ -  if ((list = rp->info) != NULL) -    for (ALL_LIST_ELEMENTS_RO (list, node, rinfo)) -      { -        /* Need to compare with redistributed entry or local entry */ -        if (!rip_route_rte (rinfo)) -          break; - -        if (IPV4_ADDR_SAME (&rinfo->from, &from->sin_addr) && -            IPV4_ADDR_SAME (&rinfo->nexthop, nexthop)) -          break; - -        if (!listnextnode (node)) -          { -            /* Not found in the list */ - -            if (rte->metric > rinfo->metric) -              { -                /* New route has a greater metric. Discard it. */ -                route_unlock_node (rp); -                return; -              } - -            if (rte->metric < rinfo->metric) -              /* New route has a smaller metric. Replace the ECMP list -               * with the new one in below. */ -              break; - -            /* Metrics are same. We compare the distances. */ -            old_dist = rinfo->distance ? \ -                       rinfo->distance : ZEBRA_RIP_DISTANCE_DEFAULT; - -            if (new_dist > old_dist) -              { -                /* New route has a greater distance. Discard it. */ -                route_unlock_node (rp); -                return; -              } - -            if (new_dist < old_dist) -              /* New route has a smaller distance. Replace the ECMP list -               * with the new one in below. */ -              break; - -            /* Metrics and distances are both same. Keep "rinfo" null and -             * the new route is added in the ECMP list in below. */ -          } -      } - -  if (rinfo) -    { -      /* Local static route. */ -      if (rinfo->type == ZEBRA_ROUTE_RIP -          && ((rinfo->sub_type == RIP_ROUTE_STATIC) || -              (rinfo->sub_type == RIP_ROUTE_DEFAULT)) -          && rinfo->metric != RIP_METRIC_INFINITY) -        { -          route_unlock_node (rp); -          return; -        } - -      /* Redistributed route check. */ -      if (rinfo->type != ZEBRA_ROUTE_RIP -          && rinfo->metric != RIP_METRIC_INFINITY) -        { -          old_dist = rinfo->distance; -          /* Only routes directly connected to an interface (nexthop == 0) -	   * may have a valid NULL distance */ -          if (rinfo->nexthop.s_addr != 0) -            old_dist = old_dist ? old_dist : ZEBRA_RIP_DISTANCE_DEFAULT; -          /* If imported route does not have STRICT precedence,  -             mark it as a ghost */ -          if (new_dist <= old_dist && rte->metric != RIP_METRIC_INFINITY) -            rip_ecmp_replace (&newinfo); - -          route_unlock_node (rp); -          return; -        } -    } - -  if (!rinfo) -    { -      if (rp->info) -        route_unlock_node (rp); - -      /* Now, check to see whether there is already an explicit route -         for the destination prefix.  If there is no such route, add -         this route to the routing table, unless the metric is -         infinity (there is no point in adding a route which -         unusable). */ -      if (rte->metric != RIP_METRIC_INFINITY) -        rip_ecmp_add (&newinfo); -    } -  else -    { -      /* Route is there but we are not sure the route is RIP or not. */ - -      /* If there is an existing route, compare the next hop address -         to the address of the router from which the datagram came. -         If this datagram is from the same router as the existing -         route, reinitialize the timeout.  */ -      same = (IPV4_ADDR_SAME (&rinfo->from, &from->sin_addr) -              && (rinfo->ifindex == ifp->ifindex)); - -      old_dist = rinfo->distance ? \ -                 rinfo->distance : ZEBRA_RIP_DISTANCE_DEFAULT; - -      /* Next, compare the metrics.  If the datagram is from the same -         router as the existing route, and the new metric is different -         than the old one; or, if the new metric is lower than the old -         one, or if the tag has been changed; or if there is a route -         with a lower administrave distance; or an update of the -         distance on the actual route; do the following actions: */ -      if ((same && rinfo->metric != rte->metric) -          || (rte->metric < rinfo->metric) -          || ((same) -              && (rinfo->metric == rte->metric) -              && (newinfo.tag != rinfo->tag)) -          || (old_dist > new_dist) -          || ((old_dist != new_dist) && same)) -        { -          if (listcount (list) == 1) -            { -              if (newinfo.metric != RIP_METRIC_INFINITY) -                rip_ecmp_replace (&newinfo); -              else -                rip_ecmp_delete (rinfo); -            } -          else -            { -              if (newinfo.metric < rinfo->metric) -                rip_ecmp_replace (&newinfo); -              else if (newinfo.metric > rinfo->metric) -                rip_ecmp_delete (rinfo); -              else if (new_dist < old_dist) -                rip_ecmp_replace (&newinfo); -              else if (new_dist > old_dist) -                rip_ecmp_delete (rinfo); -              else -                { -                  int update = CHECK_FLAG (rinfo->flags, RIP_RTF_FIB) ? 1 : 0; - -                  assert (newinfo.metric != RIP_METRIC_INFINITY); - -                  RIP_TIMER_OFF (rinfo->t_timeout); -                  RIP_TIMER_OFF (rinfo->t_garbage_collect); -                  memcpy (rinfo, &newinfo, sizeof (struct rip_info)); -                  rip_timeout_update (rinfo); - -                  if (update) -                    rip_zebra_ipv4_add (rp); - -                  /* - Set the route change flag on the first entry. */ -                  rinfo = listgetdata (listhead (list)); -                  SET_FLAG (rinfo->flags, RIP_RTF_CHANGED); -                  rip_event (RIP_TRIGGERED_UPDATE, 0); -                } -            } -        } -      else /* same & no change */ -        rip_timeout_update (rinfo); - -      /* Unlock tempolary lock of the route. */ -      route_unlock_node (rp); -    } -} +static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, +			    struct interface *ifp) +{ +	int ret; +	struct prefix_ipv4 p; +	struct route_node *rp; +	struct rip_info *rinfo = NULL, newinfo; +	struct rip_interface *ri; +	struct in_addr *nexthop; +	int same = 0; +	unsigned char old_dist, new_dist; +	struct list *list = NULL; +	struct listnode *node = NULL; + +	/* Make prefix structure. */ +	memset(&p, 0, sizeof(struct prefix_ipv4)); +	p.family = AF_INET; +	p.prefix = rte->prefix; +	p.prefixlen = ip_masklen(rte->mask); + +	/* Make sure mask is applied. */ +	apply_mask_ipv4(&p); + +	/* Apply input filters. */ +	ri = ifp->info; -/* Dump RIP packet */ -static void -rip_packet_dump (struct rip_packet *packet, int size, const char *sndrcv) -{ -  caddr_t lim; -  struct rte *rte; -  const char *command_str; -  char pbuf[BUFSIZ], nbuf[BUFSIZ]; -  u_char netmask = 0; -  u_char *p; - -  /* Set command string. */ -  if (packet->command > 0 && packet->command < RIP_COMMAND_MAX) -    command_str = lookup_msg (rip_msg, packet->command, NULL); -  else -    command_str = "unknown"; - -  /* Dump packet header. */ -  zlog_debug ("%s %s version %d packet size %d", -	     sndrcv, command_str, packet->version, size); - -  /* Dump each routing table entry. */ -  rte = packet->rte; -   -  for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++) -    { -      if (packet->version == RIPv2) -	{ -	  netmask = ip_masklen (rte->mask); +	ret = rip_filter(RIP_FILTER_IN, &p, ri); +	if (ret < 0) +		return; + +	memset(&newinfo, 0, sizeof(newinfo)); +	newinfo.type = ZEBRA_ROUTE_RIP; +	newinfo.sub_type = RIP_ROUTE_RTE; +	newinfo.nexthop = rte->nexthop; +	newinfo.from = from->sin_addr; +	newinfo.ifindex = ifp->ifindex; +	newinfo.metric = rte->metric; +	newinfo.metric_out = rte->metric; /* XXX */ +	newinfo.tag = ntohs(rte->tag);    /* XXX */ + +	/* Modify entry according to the interface routemap. */ +	if (ri->routemap[RIP_FILTER_IN]) { +		int ret; + +		/* The object should be of the type of rip_info */ +		ret = route_map_apply(ri->routemap[RIP_FILTER_IN], +				      (struct prefix *)&p, RMAP_RIP, &newinfo); + +		if (ret == RMAP_DENYMATCH) { +			if (IS_RIP_DEBUG_PACKET) +				zlog_debug( +					"RIP %s/%d is filtered by route-map in", +					inet_ntoa(p.prefix), p.prefixlen); +			return; +		} + +		/* Get back the object */ +		rte->nexthop = newinfo.nexthop_out; +		rte->tag = htons(newinfo.tag_out); /* XXX */ +		rte->metric = +			newinfo.metric_out; /* XXX: the routemap uses the +					       metric_out field */ +	} + +	/* Once the entry has been validated, update the metric by +	   adding the cost of the network on wich the message +	   arrived. If the result is greater than infinity, use infinity +	   (RFC2453 Sec. 3.9.2) */ +	/* Zebra ripd can handle offset-list in. */ +	ret = rip_offset_list_apply_in(&p, ifp, &rte->metric); -          if (rte->family == htons (RIP_FAMILY_AUTH)) -            { -              if (rte->tag == htons (RIP_AUTH_SIMPLE_PASSWORD)) -		{ -		  p = (u_char *)&rte->prefix; +	/* If offset-list does not modify the metric use interface's +	   metric. */ +	if (!ret) +		rte->metric += ifp->metric ? ifp->metric : 1; -		  zlog_debug ("  family 0x%X type %d auth string: %s", -			     ntohs (rte->family), ntohs (rte->tag), p); +	if (rte->metric > RIP_METRIC_INFINITY) +		rte->metric = RIP_METRIC_INFINITY; + +	/* Set nexthop pointer. */ +	if (rte->nexthop.s_addr == 0) +		nexthop = &from->sin_addr; +	else +		nexthop = &rte->nexthop; + +	/* Check if nexthop address is myself, then do nothing. */ +	if (rip_nexthop_check(nexthop) < 0) { +		if (IS_RIP_DEBUG_PACKET) +			zlog_debug("Nexthop address %s is myself", +				   inet_ntoa(*nexthop)); +		return; +	} + +	/* Get index for the prefix. */ +	rp = route_node_get(rip->table, (struct prefix *)&p); + +	newinfo.rp = rp; +	newinfo.nexthop = *nexthop; +	newinfo.metric = rte->metric; +	newinfo.tag = ntohs(rte->tag); +	newinfo.distance = rip_distance_apply(&newinfo); + +	new_dist = newinfo.distance ? newinfo.distance +				    : ZEBRA_RIP_DISTANCE_DEFAULT; + +	/* Check to see whether there is already RIP route on the table. */ +	if ((list = rp->info) != NULL) +		for (ALL_LIST_ELEMENTS_RO(list, node, rinfo)) { +			/* Need to compare with redistributed entry or local +			 * entry */ +			if (!rip_route_rte(rinfo)) +				break; + +			if (IPV4_ADDR_SAME(&rinfo->from, &from->sin_addr) +			    && IPV4_ADDR_SAME(&rinfo->nexthop, nexthop)) +				break; + +			if (!listnextnode(node)) { +				/* Not found in the list */ + +				if (rte->metric > rinfo->metric) { +					/* New route has a greater metric. +					 * Discard it. */ +					route_unlock_node(rp); +					return; +				} + +				if (rte->metric < rinfo->metric) +					/* New route has a smaller metric. +					 * Replace the ECMP list +					 * with the new one in below. */ +					break; + +				/* Metrics are same. We compare the distances. +				 */ +				old_dist = rinfo->distance +						   ? rinfo->distance +						   : ZEBRA_RIP_DISTANCE_DEFAULT; + +				if (new_dist > old_dist) { +					/* New route has a greater distance. +					 * Discard it. */ +					route_unlock_node(rp); +					return; +				} + +				if (new_dist < old_dist) +					/* New route has a smaller distance. +					 * Replace the ECMP list +					 * with the new one in below. */ +					break; + +				/* Metrics and distances are both same. Keep +				 * "rinfo" null and +				 * the new route is added in the ECMP list in +				 * below. */ +			}  		} -              else if (rte->tag == htons (RIP_AUTH_MD5)) -		{ -		  struct rip_md5_info *md5; - -		  md5 = (struct rip_md5_info *) &packet->rte; - -		  zlog_debug ("  family 0x%X type %d (MD5 authentication)", -			     ntohs (md5->family), ntohs (md5->type)); -		  zlog_debug ("    RIP-2 packet len %d Key ID %d" -                             " Auth Data len %d", -                             ntohs (md5->packet_len), md5->keyid, -                             md5->auth_len); -                  zlog_debug ("    Sequence Number %ld", -                             (u_long) ntohl (md5->sequence)); + +	if (rinfo) { +		/* Local static route. */ +		if (rinfo->type == ZEBRA_ROUTE_RIP +		    && ((rinfo->sub_type == RIP_ROUTE_STATIC) +			|| (rinfo->sub_type == RIP_ROUTE_DEFAULT)) +		    && rinfo->metric != RIP_METRIC_INFINITY) { +			route_unlock_node(rp); +			return;  		} -              else if (rte->tag == htons (RIP_AUTH_DATA)) -		{ -		  p = (u_char *)&rte->prefix; - -		  zlog_debug ("  family 0x%X type %d (MD5 data)", -			     ntohs (rte->family), ntohs (rte->tag)); -		  zlog_debug ("    MD5: %02X%02X%02X%02X%02X%02X%02X%02X" -			     "%02X%02X%02X%02X%02X%02X%02X%02X", -                             p[0], p[1], p[2], p[3], p[4], p[5], p[6], -                             p[7], p[8], p[9], p[10], p[11], p[12], p[13], -                             p[14], p[15]); + +		/* Redistributed route check. */ +		if (rinfo->type != ZEBRA_ROUTE_RIP +		    && rinfo->metric != RIP_METRIC_INFINITY) { +			old_dist = rinfo->distance; +			/* Only routes directly connected to an interface +			 * (nexthop == 0) +			 * may have a valid NULL distance */ +			if (rinfo->nexthop.s_addr != 0) +				old_dist = old_dist +						   ? old_dist +						   : ZEBRA_RIP_DISTANCE_DEFAULT; +			/* If imported route does not have STRICT precedence, +			   mark it as a ghost */ +			if (new_dist <= old_dist +			    && rte->metric != RIP_METRIC_INFINITY) +				rip_ecmp_replace(&newinfo); + +			route_unlock_node(rp); +			return;  		} -	      else -		{ -		  zlog_debug ("  family 0x%X type %d (Unknown auth type)", -			     ntohs (rte->family), ntohs (rte->tag)); +	} + +	if (!rinfo) { +		if (rp->info) +			route_unlock_node(rp); + +		/* Now, check to see whether there is already an explicit route +		   for the destination prefix.  If there is no such route, add +		   this route to the routing table, unless the metric is +		   infinity (there is no point in adding a route which +		   unusable). */ +		if (rte->metric != RIP_METRIC_INFINITY) +			rip_ecmp_add(&newinfo); +	} else { +		/* Route is there but we are not sure the route is RIP or not. +		 */ + +		/* If there is an existing route, compare the next hop address +		   to the address of the router from which the datagram came. +		   If this datagram is from the same router as the existing +		   route, reinitialize the timeout.  */ +		same = (IPV4_ADDR_SAME(&rinfo->from, &from->sin_addr) +			&& (rinfo->ifindex == ifp->ifindex)); + +		old_dist = rinfo->distance ? rinfo->distance +					   : ZEBRA_RIP_DISTANCE_DEFAULT; + +		/* Next, compare the metrics.  If the datagram is from the same +		   router as the existing route, and the new metric is different +		   than the old one; or, if the new metric is lower than the old +		   one, or if the tag has been changed; or if there is a route +		   with a lower administrave distance; or an update of the +		   distance on the actual route; do the following actions: */ +		if ((same && rinfo->metric != rte->metric) +		    || (rte->metric < rinfo->metric) +		    || ((same) && (rinfo->metric == rte->metric) +			&& (newinfo.tag != rinfo->tag)) +		    || (old_dist > new_dist) +		    || ((old_dist != new_dist) && same)) { +			if (listcount(list) == 1) { +				if (newinfo.metric != RIP_METRIC_INFINITY) +					rip_ecmp_replace(&newinfo); +				else +					rip_ecmp_delete(rinfo); +			} else { +				if (newinfo.metric < rinfo->metric) +					rip_ecmp_replace(&newinfo); +				else if (newinfo.metric > rinfo->metric) +					rip_ecmp_delete(rinfo); +				else if (new_dist < old_dist) +					rip_ecmp_replace(&newinfo); +				else if (new_dist > old_dist) +					rip_ecmp_delete(rinfo); +				else { +					int update = CHECK_FLAG(rinfo->flags, +								RIP_RTF_FIB) +							     ? 1 +							     : 0; + +					assert(newinfo.metric +					       != RIP_METRIC_INFINITY); + +					RIP_TIMER_OFF(rinfo->t_timeout); +					RIP_TIMER_OFF(rinfo->t_garbage_collect); +					memcpy(rinfo, &newinfo, +					       sizeof(struct rip_info)); +					rip_timeout_update(rinfo); + +					if (update) +						rip_zebra_ipv4_add(rp); + +					/* - Set the route change flag on the +					 * first entry. */ +					rinfo = listgetdata(listhead(list)); +					SET_FLAG(rinfo->flags, RIP_RTF_CHANGED); +					rip_event(RIP_TRIGGERED_UPDATE, 0); +				} +			} +		} else /* same & no change */ +			rip_timeout_update(rinfo); + +		/* Unlock tempolary lock of the route. */ +		route_unlock_node(rp); +	} +} + +/* Dump RIP packet */ +static void rip_packet_dump(struct rip_packet *packet, int size, +			    const char *sndrcv) +{ +	caddr_t lim; +	struct rte *rte; +	const char *command_str; +	char pbuf[BUFSIZ], nbuf[BUFSIZ]; +	u_char netmask = 0; +	u_char *p; + +	/* Set command string. */ +	if (packet->command > 0 && packet->command < RIP_COMMAND_MAX) +		command_str = lookup_msg(rip_msg, packet->command, NULL); +	else +		command_str = "unknown"; + +	/* Dump packet header. */ +	zlog_debug("%s %s version %d packet size %d", sndrcv, command_str, +		   packet->version, size); + +	/* Dump each routing table entry. */ +	rte = packet->rte; + +	for (lim = (caddr_t)packet + size; (caddr_t)rte < lim; rte++) { +		if (packet->version == RIPv2) { +			netmask = ip_masklen(rte->mask); + +			if (rte->family == htons(RIP_FAMILY_AUTH)) { +				if (rte->tag +				    == htons(RIP_AUTH_SIMPLE_PASSWORD)) { +					p = (u_char *)&rte->prefix; + +					zlog_debug( +						"  family 0x%X type %d auth string: %s", +						ntohs(rte->family), +						ntohs(rte->tag), p); +				} else if (rte->tag == htons(RIP_AUTH_MD5)) { +					struct rip_md5_info *md5; + +					md5 = (struct rip_md5_info *)&packet +						      ->rte; + +					zlog_debug( +						"  family 0x%X type %d (MD5 authentication)", +						ntohs(md5->family), +						ntohs(md5->type)); +					zlog_debug( +						"    RIP-2 packet len %d Key ID %d" +						" Auth Data len %d", +						ntohs(md5->packet_len), +						md5->keyid, md5->auth_len); +					zlog_debug( +						"    Sequence Number %ld", +						(u_long)ntohl(md5->sequence)); +				} else if (rte->tag == htons(RIP_AUTH_DATA)) { +					p = (u_char *)&rte->prefix; + +					zlog_debug( +						"  family 0x%X type %d (MD5 data)", +						ntohs(rte->family), +						ntohs(rte->tag)); +					zlog_debug( +						"    MD5: %02X%02X%02X%02X%02X%02X%02X%02X" +						"%02X%02X%02X%02X%02X%02X%02X%02X", +						p[0], p[1], p[2], p[3], p[4], +						p[5], p[6], p[7], p[8], p[9], +						p[10], p[11], p[12], p[13], +						p[14], p[15]); +				} else { +					zlog_debug( +						"  family 0x%X type %d (Unknown auth type)", +						ntohs(rte->family), +						ntohs(rte->tag)); +				} +			} else +				zlog_debug( +					"  %s/%d -> %s family %d tag %" ROUTE_TAG_PRI +					" metric %ld", +					inet_ntop(AF_INET, &rte->prefix, pbuf, +						  BUFSIZ), +					netmask, +					inet_ntop(AF_INET, &rte->nexthop, nbuf, +						  BUFSIZ), +					ntohs(rte->family), +					(route_tag_t)ntohs(rte->tag), +					(u_long)ntohl(rte->metric)); +		} else { +			zlog_debug( +				"  %s family %d tag %" ROUTE_TAG_PRI +				" metric %ld", +				inet_ntop(AF_INET, &rte->prefix, pbuf, BUFSIZ), +				ntohs(rte->family), +				(route_tag_t)ntohs(rte->tag), +				(u_long)ntohl(rte->metric));  		} -            } -	  else -	    zlog_debug ("  %s/%d -> %s family %d tag %"ROUTE_TAG_PRI" metric %ld", -                       inet_ntop (AF_INET, &rte->prefix, pbuf, BUFSIZ), -                       netmask, inet_ntop (AF_INET, &rte->nexthop, nbuf, -                                           BUFSIZ), ntohs (rte->family), -                       (route_tag_t)ntohs (rte->tag), -                       (u_long) ntohl (rte->metric)); -	} -      else -	{ -	  zlog_debug ("  %s family %d tag %"ROUTE_TAG_PRI" metric %ld",  -		     inet_ntop (AF_INET, &rte->prefix, pbuf, BUFSIZ), -		     ntohs (rte->family), (route_tag_t)ntohs (rte->tag), -		     (u_long)ntohl (rte->metric));  	} -    }  }  /* Check if the destination address is valid (unicast; not net 0     or 127) (RFC2453 Section 3.9.2 - Page 26).  But we don't     check net 0 because we accept default route. */ -static int -rip_destination_check (struct in_addr addr) +static int rip_destination_check(struct in_addr addr)  { -  u_int32_t destination; +	u_int32_t destination; -  /* Convert to host byte order. */ -  destination = ntohl (addr.s_addr); +	/* Convert to host byte order. */ +	destination = ntohl(addr.s_addr); -  if (IPV4_NET127 (destination)) -    return 0; +	if (IPV4_NET127(destination)) +		return 0; -  /* Net 0 may match to the default route. */ -  if (IPV4_NET0 (destination) && destination != 0) -    return 0; +	/* Net 0 may match to the default route. */ +	if (IPV4_NET0(destination) && destination != 0) +		return 0; -  /* Unicast address must belong to class A, B, C. */ -  if (IN_CLASSA (destination)) -    return 1; -  if (IN_CLASSB (destination)) -    return 1; -  if (IN_CLASSC (destination)) -    return 1; +	/* Unicast address must belong to class A, B, C. */ +	if (IN_CLASSA(destination)) +		return 1; +	if (IN_CLASSB(destination)) +		return 1; +	if (IN_CLASSC(destination)) +		return 1; -  return 0; +	return 0;  }  /* RIP version 2 authentication. */ -static int -rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from, -			  struct interface *ifp) -{ -  struct rip_interface *ri; -  char *auth_str = (char *) &rte->prefix; -  int i; - -  /* reject passwords with zeros in the middle of the string */ -  for (i = strlen (auth_str); i < 16; i++) -    { -      if (auth_str[i] != '\0') -	return 0; -    } - -  if (IS_RIP_DEBUG_EVENT) -    zlog_debug ("RIPv2 simple password authentication from %s", -	       inet_ntoa (from->sin_addr)); - -  ri = ifp->info; - -  if (ri->auth_type != RIP_AUTH_SIMPLE_PASSWORD -      || rte->tag != htons(RIP_AUTH_SIMPLE_PASSWORD)) -    return 0; - -  /* Simple password authentication. */ -  if (ri->auth_str) -    { -      if (strncmp (auth_str, ri->auth_str, 16) == 0) -	return 1; -    } -  if (ri->key_chain) -    { -      struct keychain *keychain; -      struct key *key; - -      keychain = keychain_lookup (ri->key_chain); -      if (keychain == NULL) -	return 0; +static int rip_auth_simple_password(struct rte *rte, struct sockaddr_in *from, +				    struct interface *ifp) +{ +	struct rip_interface *ri; +	char *auth_str = (char *)&rte->prefix; +	int i; + +	/* reject passwords with zeros in the middle of the string */ +	for (i = strlen(auth_str); i < 16; i++) { +		if (auth_str[i] != '\0') +			return 0; +	} + +	if (IS_RIP_DEBUG_EVENT) +		zlog_debug("RIPv2 simple password authentication from %s", +			   inet_ntoa(from->sin_addr)); + +	ri = ifp->info; + +	if (ri->auth_type != RIP_AUTH_SIMPLE_PASSWORD +	    || rte->tag != htons(RIP_AUTH_SIMPLE_PASSWORD)) +		return 0; -      key = key_match_for_accept (keychain, auth_str); -      if (key) -	return 1; -    } -  return 0; +	/* Simple password authentication. */ +	if (ri->auth_str) { +		if (strncmp(auth_str, ri->auth_str, 16) == 0) +			return 1; +	} +	if (ri->key_chain) { +		struct keychain *keychain; +		struct key *key; + +		keychain = keychain_lookup(ri->key_chain); +		if (keychain == NULL) +			return 0; + +		key = key_match_for_accept(keychain, auth_str); +		if (key) +			return 1; +	} +	return 0;  }  /* RIP version 2 authentication with MD5. */ -static int -rip_auth_md5 (struct rip_packet *packet, struct sockaddr_in *from, -              int length, struct interface *ifp) -{ -  struct rip_interface *ri; -  struct rip_md5_info *md5; -  struct rip_md5_data *md5data; -  struct keychain *keychain; -  struct key *key; -  MD5_CTX ctx; -  u_char digest[RIP_AUTH_MD5_SIZE]; -  u_int16_t packet_len; -  char auth_str[RIP_AUTH_MD5_SIZE]; -   -  if (IS_RIP_DEBUG_EVENT) -    zlog_debug ("RIPv2 MD5 authentication from %s", -               inet_ntoa (from->sin_addr)); - -  ri = ifp->info; -  md5 = (struct rip_md5_info *) &packet->rte; - -  /* Check auth type. */ -  if (ri->auth_type != RIP_AUTH_MD5 || md5->type != htons(RIP_AUTH_MD5)) -    return 0; - -  /* If the authentication length is less than 16, then it must be wrong for -   * any interpretation of rfc2082. Some implementations also interpret -   * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka RIP_AUTH_MD5_COMPAT_SIZE. -   */ -  if ( !((md5->auth_len == RIP_AUTH_MD5_SIZE) -         || (md5->auth_len == RIP_AUTH_MD5_COMPAT_SIZE))) -    { -      if (IS_RIP_DEBUG_EVENT) -        zlog_debug ("RIPv2 MD5 authentication, strange authentication " -                   "length field %d", md5->auth_len); -    return 0; -    } - -  /* grab and verify check packet length */ -  packet_len = ntohs (md5->packet_len); - -  if (packet_len > (length - RIP_HEADER_SIZE - RIP_AUTH_MD5_SIZE)) -    { -      if (IS_RIP_DEBUG_EVENT) -        zlog_debug ("RIPv2 MD5 authentication, packet length field %d " -                   "greater than received length %d!", -                   md5->packet_len, length); -      return 0; -    } - -  /* retrieve authentication data */ -  md5data = (struct rip_md5_data *) (((u_char *) packet) + packet_len); -   -  memset (auth_str, 0, RIP_AUTH_MD5_SIZE); - -  if (ri->key_chain) -    { -      keychain = keychain_lookup (ri->key_chain); -      if (keychain == NULL) -	return 0; +static int rip_auth_md5(struct rip_packet *packet, struct sockaddr_in *from, +			int length, struct interface *ifp) +{ +	struct rip_interface *ri; +	struct rip_md5_info *md5; +	struct rip_md5_data *md5data; +	struct keychain *keychain; +	struct key *key; +	MD5_CTX ctx; +	u_char digest[RIP_AUTH_MD5_SIZE]; +	u_int16_t packet_len; +	char auth_str[RIP_AUTH_MD5_SIZE]; + +	if (IS_RIP_DEBUG_EVENT) +		zlog_debug("RIPv2 MD5 authentication from %s", +			   inet_ntoa(from->sin_addr)); -      key = key_lookup_for_accept (keychain, md5->keyid); -      if (key == NULL) -	return 0; +	ri = ifp->info; +	md5 = (struct rip_md5_info *)&packet->rte; + +	/* Check auth type. */ +	if (ri->auth_type != RIP_AUTH_MD5 || md5->type != htons(RIP_AUTH_MD5)) +		return 0; + +	/* If the authentication length is less than 16, then it must be wrong +	 * for +	 * any interpretation of rfc2082. Some implementations also interpret +	 * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka +	 * RIP_AUTH_MD5_COMPAT_SIZE. +	 */ +	if (!((md5->auth_len == RIP_AUTH_MD5_SIZE) +	      || (md5->auth_len == RIP_AUTH_MD5_COMPAT_SIZE))) { +		if (IS_RIP_DEBUG_EVENT) +			zlog_debug( +				"RIPv2 MD5 authentication, strange authentication " +				"length field %d", +				md5->auth_len); +		return 0; +	} + +	/* grab and verify check packet length */ +	packet_len = ntohs(md5->packet_len); -      strncpy (auth_str, key->string, RIP_AUTH_MD5_SIZE); -    } -  else if (ri->auth_str) -    strncpy (auth_str, ri->auth_str, RIP_AUTH_MD5_SIZE); - -  if (auth_str[0] == 0) -    return 0; -   -  /* MD5 digest authentication. */ -  memset (&ctx, 0, sizeof(ctx)); -  MD5Init(&ctx); -  MD5Update(&ctx, packet, packet_len + RIP_HEADER_SIZE); -  MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE); -  MD5Final(digest, &ctx); -   -  if (memcmp (md5data->digest, digest, RIP_AUTH_MD5_SIZE) == 0) -    return packet_len; -  else -    return 0; +	if (packet_len > (length - RIP_HEADER_SIZE - RIP_AUTH_MD5_SIZE)) { +		if (IS_RIP_DEBUG_EVENT) +			zlog_debug( +				"RIPv2 MD5 authentication, packet length field %d " +				"greater than received length %d!", +				md5->packet_len, length); +		return 0; +	} + +	/* retrieve authentication data */ +	md5data = (struct rip_md5_data *)(((u_char *)packet) + packet_len); + +	memset(auth_str, 0, RIP_AUTH_MD5_SIZE); + +	if (ri->key_chain) { +		keychain = keychain_lookup(ri->key_chain); +		if (keychain == NULL) +			return 0; + +		key = key_lookup_for_accept(keychain, md5->keyid); +		if (key == NULL) +			return 0; + +		strncpy(auth_str, key->string, RIP_AUTH_MD5_SIZE); +	} else if (ri->auth_str) +		strncpy(auth_str, ri->auth_str, RIP_AUTH_MD5_SIZE); + +	if (auth_str[0] == 0) +		return 0; + +	/* MD5 digest authentication. */ +	memset(&ctx, 0, sizeof(ctx)); +	MD5Init(&ctx); +	MD5Update(&ctx, packet, packet_len + RIP_HEADER_SIZE); +	MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE); +	MD5Final(digest, &ctx); + +	if (memcmp(md5data->digest, digest, RIP_AUTH_MD5_SIZE) == 0) +		return packet_len; +	else +		return 0;  }  /* Pick correct auth string for sends, prepare auth_str buffer for use. @@ -950,39 +936,37 @@ rip_auth_md5 (struct rip_packet *packet, struct sockaddr_in *from,   * zero padded.   *   */ -static void -rip_auth_prepare_str_send (struct rip_interface *ri, struct key *key,  -                           char *auth_str, int len) +static void rip_auth_prepare_str_send(struct rip_interface *ri, struct key *key, +				      char *auth_str, int len)  { -  assert (ri || key); +	assert(ri || key); -  memset (auth_str, 0, len); -  if (key && key->string) -    strncpy (auth_str, key->string, len); -  else if (ri->auth_str) -    strncpy (auth_str, ri->auth_str, len); +	memset(auth_str, 0, len); +	if (key && key->string) +		strncpy(auth_str, key->string, len); +	else if (ri->auth_str) +		strncpy(auth_str, ri->auth_str, len); -  return; +	return;  }  /* Write RIPv2 simple password authentication information   * - * auth_str is presumed to be 2 bytes and correctly prepared  + * auth_str is presumed to be 2 bytes and correctly prepared   * (left justified and zero padded).   */ -static void -rip_auth_simple_write (struct stream *s, char *auth_str, int len) +static void rip_auth_simple_write(struct stream *s, char *auth_str, int len)  { -  assert (s && len == RIP_AUTH_SIMPLE_SIZE); -   -  stream_putw (s, RIP_FAMILY_AUTH); -  stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD); -  stream_put (s, auth_str, RIP_AUTH_SIMPLE_SIZE); -   -  return; +	assert(s && len == RIP_AUTH_SIMPLE_SIZE); + +	stream_putw(s, RIP_FAMILY_AUTH); +	stream_putw(s, RIP_AUTH_SIMPLE_PASSWORD); +	stream_put(s, auth_str, RIP_AUTH_SIMPLE_SIZE); + +	return;  } -/* write RIPv2 MD5 "authentication header"  +/* write RIPv2 MD5 "authentication header"   * (uses the auth key data field)   *   * Digest offset field is set to 0. @@ -990,1814 +974,1818 @@ rip_auth_simple_write (struct stream *s, char *auth_str, int len)   * returns: offset of the digest offset field, which must be set when   * length to the auth-data MD5 digest is known.   */ -static size_t -rip_auth_md5_ah_write (struct stream *s, struct rip_interface *ri,  -                       struct key *key) -{ -  size_t doff = 0; - -  assert (s && ri && ri->auth_type == RIP_AUTH_MD5); - -  /* MD5 authentication. */ -  stream_putw (s, RIP_FAMILY_AUTH); -  stream_putw (s, RIP_AUTH_MD5); - -  /* MD5 AH digest offset field. -   * -   * Set to placeholder value here, to true value when RIP-2 Packet length -   * is known.  Actual value is set in .....(). -   */ -  doff = stream_get_endp(s); -  stream_putw (s, 0); - -  /* Key ID. */ -  if (key) -    stream_putc (s, key->index % 256); -  else -    stream_putc (s, 1); - -  /* Auth Data Len.  Set 16 for MD5 authentication data. Older ripds  -   * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for this -   * to be configurable.  -   */ -  stream_putc (s, ri->md5_auth_len); - -  /* Sequence Number (non-decreasing). */ -  /* RFC2080: The value used in the sequence number is -     arbitrary, but two suggestions are the time of the -     message's creation or a simple message counter. */ -  stream_putl (s, time (NULL)); -	       -  /* Reserved field must be zero. */ -  stream_putl (s, 0); -  stream_putl (s, 0); - -  return doff; +static size_t rip_auth_md5_ah_write(struct stream *s, struct rip_interface *ri, +				    struct key *key) +{ +	size_t doff = 0; + +	assert(s && ri && ri->auth_type == RIP_AUTH_MD5); + +	/* MD5 authentication. */ +	stream_putw(s, RIP_FAMILY_AUTH); +	stream_putw(s, RIP_AUTH_MD5); + +	/* MD5 AH digest offset field. +	 * +	 * Set to placeholder value here, to true value when RIP-2 Packet length +	 * is known.  Actual value is set in .....(). +	 */ +	doff = stream_get_endp(s); +	stream_putw(s, 0); + +	/* Key ID. */ +	if (key) +		stream_putc(s, key->index % 256); +	else +		stream_putc(s, 1); + +	/* Auth Data Len.  Set 16 for MD5 authentication data. Older ripds +	 * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for +	 * this +	 * to be configurable. +	 */ +	stream_putc(s, ri->md5_auth_len); + +	/* Sequence Number (non-decreasing). */ +	/* RFC2080: The value used in the sequence number is +	   arbitrary, but two suggestions are the time of the +	   message's creation or a simple message counter. */ +	stream_putl(s, time(NULL)); + +	/* Reserved field must be zero. */ +	stream_putl(s, 0); +	stream_putl(s, 0); + +	return doff;  }  /* If authentication is in used, write the appropriate header   * returns stream offset to which length must later be written   * or 0 if this is not required   */ -static size_t -rip_auth_header_write (struct stream *s, struct rip_interface *ri,  -                       struct key *key, char *auth_str, int len) -{ -  assert (ri->auth_type != RIP_NO_AUTH); -   -  switch (ri->auth_type) -    { -      case RIP_AUTH_SIMPLE_PASSWORD: -        rip_auth_prepare_str_send (ri, key, auth_str, len); -        rip_auth_simple_write (s, auth_str, len); -        return 0; -      case RIP_AUTH_MD5: -        return rip_auth_md5_ah_write (s, ri, key); -    } -  assert (1); -  return 0; +static size_t rip_auth_header_write(struct stream *s, struct rip_interface *ri, +				    struct key *key, char *auth_str, int len) +{ +	assert(ri->auth_type != RIP_NO_AUTH); + +	switch (ri->auth_type) { +	case RIP_AUTH_SIMPLE_PASSWORD: +		rip_auth_prepare_str_send(ri, key, auth_str, len); +		rip_auth_simple_write(s, auth_str, len); +		return 0; +	case RIP_AUTH_MD5: +		return rip_auth_md5_ah_write(s, ri, key); +	} +	assert(1); +	return 0;  }  /* Write RIPv2 MD5 authentication data trailer */ -static void -rip_auth_md5_set (struct stream *s, struct rip_interface *ri, size_t doff, -                  char *auth_str, int authlen) -{ -  unsigned long len; -  MD5_CTX ctx; -  unsigned char digest[RIP_AUTH_MD5_SIZE]; - -  /* Make it sure this interface is configured as MD5 -     authentication. */ -  assert ((ri->auth_type == RIP_AUTH_MD5) && (authlen == RIP_AUTH_MD5_SIZE)); -  assert (doff > 0); -   -  /* Get packet length. */ -  len = stream_get_endp(s); - -  /* Check packet length. */ -  if (len < (RIP_HEADER_SIZE + RIP_RTE_SIZE)) -    { -      zlog_err ("rip_auth_md5_set(): packet length %ld is less than minimum length.", len); -      return; -    } - -  /* Set the digest offset length in the header */ -  stream_putw_at (s, doff, len); -   -  /* Set authentication data. */ -  stream_putw (s, RIP_FAMILY_AUTH); -  stream_putw (s, RIP_AUTH_DATA); - -  /* Generate a digest for the RIP packet. */ -  memset(&ctx, 0, sizeof(ctx)); -  MD5Init(&ctx); -  MD5Update(&ctx, STREAM_DATA (s), stream_get_endp (s)); -  MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE); -  MD5Final(digest, &ctx); - -  /* Copy the digest to the packet. */ -  stream_write (s, digest, RIP_AUTH_MD5_SIZE); +static void rip_auth_md5_set(struct stream *s, struct rip_interface *ri, +			     size_t doff, char *auth_str, int authlen) +{ +	unsigned long len; +	MD5_CTX ctx; +	unsigned char digest[RIP_AUTH_MD5_SIZE]; + +	/* Make it sure this interface is configured as MD5 +	   authentication. */ +	assert((ri->auth_type == RIP_AUTH_MD5) +	       && (authlen == RIP_AUTH_MD5_SIZE)); +	assert(doff > 0); + +	/* Get packet length. */ +	len = stream_get_endp(s); + +	/* Check packet length. */ +	if (len < (RIP_HEADER_SIZE + RIP_RTE_SIZE)) { +		zlog_err( +			"rip_auth_md5_set(): packet length %ld is less than minimum length.", +			len); +		return; +	} + +	/* Set the digest offset length in the header */ +	stream_putw_at(s, doff, len); + +	/* Set authentication data. */ +	stream_putw(s, RIP_FAMILY_AUTH); +	stream_putw(s, RIP_AUTH_DATA); + +	/* Generate a digest for the RIP packet. */ +	memset(&ctx, 0, sizeof(ctx)); +	MD5Init(&ctx); +	MD5Update(&ctx, STREAM_DATA(s), stream_get_endp(s)); +	MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE); +	MD5Final(digest, &ctx); + +	/* Copy the digest to the packet. */ +	stream_write(s, digest, RIP_AUTH_MD5_SIZE);  }  /* RIP routing information. */ -static void -rip_response_process (struct rip_packet *packet, int size,  -		      struct sockaddr_in *from, struct connected *ifc) -{ -  caddr_t lim; -  struct rte *rte; -  struct prefix_ipv4 ifaddr; -  struct prefix_ipv4 ifaddrclass; -  int subnetted; - -  memset(&ifaddr, 0, sizeof(ifaddr)); -  /* We don't know yet. */ -  subnetted = -1; - -  /* The Response must be ignored if it is not from the RIP -     port. (RFC2453 - Sec. 3.9.2)*/ -  if (from->sin_port != htons(RIP_PORT_DEFAULT)) -    { -      zlog_info ("response doesn't come from RIP port: %d", -		 from->sin_port); -      rip_peer_bad_packet (from); -      return; -    } - -  /* The datagram's IPv4 source address should be checked to see -     whether the datagram is from a valid neighbor; the source of the -     datagram must be on a directly connected network (RFC2453 - Sec. 3.9.2) */ -  if (if_lookup_address((void *)&from->sin_addr, AF_INET, VRF_DEFAULT) == NULL) -    { -      zlog_info ("This datagram doesn't came from a valid neighbor: %s", -		 inet_ntoa (from->sin_addr)); -      rip_peer_bad_packet (from); -      return; -    } - -  /* It is also worth checking to see whether the response is from one -     of the router's own addresses. */ - -  ; /* Alredy done in rip_read () */ - -  /* Update RIP peer. */ -  rip_peer_update (from, packet->version); - -  /* Set RTE pointer. */ -  rte = packet->rte; - -  for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++) -    { -      /* RIPv2 authentication check. */ -      /* If the Address Family Identifier of the first (and only the -	 first) entry in the message is 0xFFFF, then the remainder of -	 the entry contains the authentication. */ -      /* If the packet gets here it means authentication enabled */ -      /* Check is done in rip_read(). So, just skipping it */ -      if (packet->version == RIPv2 && -	  rte == packet->rte && -	  rte->family == htons(RIP_FAMILY_AUTH)) -	continue; - -      if (rte->family != htons(AF_INET)) -	{ -	  /* Address family check.  RIP only supports AF_INET. */ -	  zlog_info ("Unsupported family %d from %s.", -		     ntohs (rte->family), inet_ntoa (from->sin_addr)); -	  continue; -	} - -      /* - is the destination address valid (e.g., unicast; not net 0 -         or 127) */ -      if (! rip_destination_check (rte->prefix)) -        { -	  zlog_info ("Network is net 0 or net 127 or it is not unicast network"); -	  rip_peer_bad_route (from); -	  continue; -	}  - -      /* Convert metric value to host byte order. */ -      rte->metric = ntohl (rte->metric); - -      /* - is the metric valid (i.e., between 1 and 16, inclusive) */ -      if (! (rte->metric >= 1 && rte->metric <= 16)) -	{ -	  zlog_info ("Route's metric is not in the 1-16 range."); -	  rip_peer_bad_route (from); -	  continue; +static void rip_response_process(struct rip_packet *packet, int size, +				 struct sockaddr_in *from, +				 struct connected *ifc) +{ +	caddr_t lim; +	struct rte *rte; +	struct prefix_ipv4 ifaddr; +	struct prefix_ipv4 ifaddrclass; +	int subnetted; + +	memset(&ifaddr, 0, sizeof(ifaddr)); +	/* We don't know yet. */ +	subnetted = -1; + +	/* The Response must be ignored if it is not from the RIP +	   port. (RFC2453 - Sec. 3.9.2)*/ +	if (from->sin_port != htons(RIP_PORT_DEFAULT)) { +		zlog_info("response doesn't come from RIP port: %d", +			  from->sin_port); +		rip_peer_bad_packet(from); +		return;  	} -      /* RIPv1 does not have nexthop value. */ -      if (packet->version == RIPv1 && rte->nexthop.s_addr != 0) -	{ -	  zlog_info ("RIPv1 packet with nexthop value %s", -		     inet_ntoa (rte->nexthop)); -	  rip_peer_bad_route (from); -	  continue; +	/* The datagram's IPv4 source address should be checked to see +	   whether the datagram is from a valid neighbor; the source of the +	   datagram must be on a directly connected network (RFC2453 - Sec. +	   3.9.2) */ +	if (if_lookup_address((void *)&from->sin_addr, AF_INET, VRF_DEFAULT) +	    == NULL) { +		zlog_info( +			"This datagram doesn't came from a valid neighbor: %s", +			inet_ntoa(from->sin_addr)); +		rip_peer_bad_packet(from); +		return;  	} -      /* That is, if the provided information is ignored, a possibly -	 sub-optimal, but absolutely valid, route may be taken.  If -	 the received Next Hop is not directly reachable, it should be -	 treated as 0.0.0.0. */ -      if (packet->version == RIPv2 && rte->nexthop.s_addr != 0) -	{ -	  u_int32_t addrval; - -	  /* Multicast address check. */ -	  addrval = ntohl (rte->nexthop.s_addr); -	  if (IN_CLASSD (addrval)) -	    { -	      zlog_info ("Nexthop %s is multicast address, skip this rte", -			 inet_ntoa (rte->nexthop)); -	      continue; -	    } - -	  if (! if_lookup_address ((void *)&rte->nexthop, AF_INET, VRF_DEFAULT)) -	    { -	      struct route_node *rn; -	      struct rip_info *rinfo; - -	      rn = route_node_match_ipv4 (rip->table, &rte->nexthop); - -	      if (rn) -		{ -		  rinfo = rn->info; - -		  if (rinfo->type == ZEBRA_ROUTE_RIP -		      && rinfo->sub_type == RIP_ROUTE_RTE) -		    { -		      if (IS_RIP_DEBUG_EVENT) -			zlog_debug ("Next hop %s is on RIP network.  Set nexthop to the packet's originator", inet_ntoa (rte->nexthop)); -		      rte->nexthop = rinfo->from; -		    } -		  else -		    { -		      if (IS_RIP_DEBUG_EVENT) -			zlog_debug ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop)); -		      rte->nexthop.s_addr = 0; -		    } - -		  route_unlock_node (rn); +	/* It is also worth checking to see whether the response is from one +	   of the router's own addresses. */ + +	; /* Alredy done in rip_read () */ + +	/* Update RIP peer. */ +	rip_peer_update(from, packet->version); + +	/* Set RTE pointer. */ +	rte = packet->rte; + +	for (lim = (caddr_t)packet + size; (caddr_t)rte < lim; rte++) { +		/* RIPv2 authentication check. */ +		/* If the Address Family Identifier of the first (and only the +		   first) entry in the message is 0xFFFF, then the remainder of +		   the entry contains the authentication. */ +		/* If the packet gets here it means authentication enabled */ +		/* Check is done in rip_read(). So, just skipping it */ +		if (packet->version == RIPv2 && rte == packet->rte +		    && rte->family == htons(RIP_FAMILY_AUTH)) +			continue; + +		if (rte->family != htons(AF_INET)) { +			/* Address family check.  RIP only supports AF_INET. */ +			zlog_info("Unsupported family %d from %s.", +				  ntohs(rte->family), +				  inet_ntoa(from->sin_addr)); +			continue;  		} -	      else -		{ -		  if (IS_RIP_DEBUG_EVENT) -		    zlog_debug ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop)); -		  rte->nexthop.s_addr = 0; + +		/* - is the destination address valid (e.g., unicast; not net 0 +		   or 127) */ +		if (!rip_destination_check(rte->prefix)) { +			zlog_info( +				"Network is net 0 or net 127 or it is not unicast network"); +			rip_peer_bad_route(from); +			continue;  		} -	    } -	} +		/* Convert metric value to host byte order. */ +		rte->metric = ntohl(rte->metric); -     /* For RIPv1, there won't be a valid netmask.   +		/* - is the metric valid (i.e., between 1 and 16, inclusive) */ +		if (!(rte->metric >= 1 && rte->metric <= 16)) { +			zlog_info("Route's metric is not in the 1-16 range."); +			rip_peer_bad_route(from); +			continue; +		} -	This is a best guess at the masks.  If everyone was using old -	Ciscos before the 'ip subnet zero' option, it would be almost -	right too :-) -       -	Cisco summarize ripv1 advertisments to the classful boundary -	(/16 for class B's) except when the RIP packet does to inside -	the classful network in question.  */ +		/* RIPv1 does not have nexthop value. */ +		if (packet->version == RIPv1 && rte->nexthop.s_addr != 0) { +			zlog_info("RIPv1 packet with nexthop value %s", +				  inet_ntoa(rte->nexthop)); +			rip_peer_bad_route(from); +			continue; +		} -      if ((packet->version == RIPv1 && rte->prefix.s_addr != 0)  -	  || (packet->version == RIPv2  -	      && (rte->prefix.s_addr != 0 && rte->mask.s_addr == 0))) -	{ -	  u_int32_t destination; - -	  if (subnetted == -1) -            { -              memcpy (&ifaddr, ifc->address, sizeof (struct prefix_ipv4)); -              memcpy (&ifaddrclass, &ifaddr, sizeof (struct prefix_ipv4)); -              apply_classful_mask_ipv4 (&ifaddrclass); -              subnetted = 0; -              if (ifaddr.prefixlen > ifaddrclass.prefixlen) -                subnetted = 1; -            } - -	  destination = ntohl (rte->prefix.s_addr); - -	  if (IN_CLASSA (destination)) -	      masklen2ip (8, &rte->mask); -	  else if (IN_CLASSB (destination)) -	      masklen2ip (16, &rte->mask); -	  else if (IN_CLASSC (destination)) -	      masklen2ip (24, &rte->mask); - -	  if (subnetted == 1) -	    masklen2ip (ifaddrclass.prefixlen, -			(struct in_addr *) &destination); -	  if ((subnetted == 1) && ((rte->prefix.s_addr & destination) == -	      ifaddrclass.prefix.s_addr)) -	    { -	      masklen2ip (ifaddr.prefixlen, &rte->mask); -	      if ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr) -		masklen2ip (32, &rte->mask); -	      if (IS_RIP_DEBUG_EVENT) -		zlog_debug ("Subnetted route %s", inet_ntoa (rte->prefix)); -	    } -	  else -	    { -	      if ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr) -		continue; -	    } - -	  if (IS_RIP_DEBUG_EVENT) -	    { -	      zlog_debug ("Resultant route %s", inet_ntoa (rte->prefix)); -	      zlog_debug ("Resultant mask %s", inet_ntoa (rte->mask)); -	    } -	} - -      /* In case of RIPv2, if prefix in RTE is not netmask applied one -         ignore the entry.  */ -      if ((packet->version == RIPv2)  -	  && (rte->mask.s_addr != 0)  -	  && ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr)) -	{ -	  zlog_warn ("RIPv2 address %s is not mask /%d applied one", -		     inet_ntoa (rte->prefix), ip_masklen (rte->mask)); -	  rip_peer_bad_route (from); -	  continue; -	} +		/* That is, if the provided information is ignored, a possibly +		   sub-optimal, but absolutely valid, route may be taken.  If +		   the received Next Hop is not directly reachable, it should be +		   treated as 0.0.0.0. */ +		if (packet->version == RIPv2 && rte->nexthop.s_addr != 0) { +			u_int32_t addrval; + +			/* Multicast address check. */ +			addrval = ntohl(rte->nexthop.s_addr); +			if (IN_CLASSD(addrval)) { +				zlog_info( +					"Nexthop %s is multicast address, skip this rte", +					inet_ntoa(rte->nexthop)); +				continue; +			} + +			if (!if_lookup_address((void *)&rte->nexthop, AF_INET, +					       VRF_DEFAULT)) { +				struct route_node *rn; +				struct rip_info *rinfo; + +				rn = route_node_match_ipv4(rip->table, +							   &rte->nexthop); + +				if (rn) { +					rinfo = rn->info; + +					if (rinfo->type == ZEBRA_ROUTE_RIP +					    && rinfo->sub_type +						       == RIP_ROUTE_RTE) { +						if (IS_RIP_DEBUG_EVENT) +							zlog_debug( +								"Next hop %s is on RIP network.  Set nexthop to the packet's originator", +								inet_ntoa( +									rte->nexthop)); +						rte->nexthop = rinfo->from; +					} else { +						if (IS_RIP_DEBUG_EVENT) +							zlog_debug( +								"Next hop %s is not directly reachable. Treat it as 0.0.0.0", +								inet_ntoa( +									rte->nexthop)); +						rte->nexthop.s_addr = 0; +					} + +					route_unlock_node(rn); +				} else { +					if (IS_RIP_DEBUG_EVENT) +						zlog_debug( +							"Next hop %s is not directly reachable. Treat it as 0.0.0.0", +							inet_ntoa( +								rte->nexthop)); +					rte->nexthop.s_addr = 0; +				} +			} +		} -      /* Default route's netmask is ignored. */ -      if (packet->version == RIPv2 -	  && (rte->prefix.s_addr == 0) -	  && (rte->mask.s_addr != 0)) -	{ -	  if (IS_RIP_DEBUG_EVENT) -	    zlog_debug ("Default route with non-zero netmask.  Set zero to netmask"); -	  rte->mask.s_addr = 0; +		/* For RIPv1, there won't be a valid netmask. + +		   This is a best guess at the masks.  If everyone was using old +		   Ciscos before the 'ip subnet zero' option, it would be almost +		   right too :-) + +		   Cisco summarize ripv1 advertisments to the classful boundary +		   (/16 for class B's) except when the RIP packet does to inside +		   the classful network in question.  */ + +		if ((packet->version == RIPv1 && rte->prefix.s_addr != 0) +		    || (packet->version == RIPv2 +			&& (rte->prefix.s_addr != 0 +			    && rte->mask.s_addr == 0))) { +			u_int32_t destination; + +			if (subnetted == -1) { +				memcpy(&ifaddr, ifc->address, +				       sizeof(struct prefix_ipv4)); +				memcpy(&ifaddrclass, &ifaddr, +				       sizeof(struct prefix_ipv4)); +				apply_classful_mask_ipv4(&ifaddrclass); +				subnetted = 0; +				if (ifaddr.prefixlen > ifaddrclass.prefixlen) +					subnetted = 1; +			} + +			destination = ntohl(rte->prefix.s_addr); + +			if (IN_CLASSA(destination)) +				masklen2ip(8, &rte->mask); +			else if (IN_CLASSB(destination)) +				masklen2ip(16, &rte->mask); +			else if (IN_CLASSC(destination)) +				masklen2ip(24, &rte->mask); + +			if (subnetted == 1) +				masklen2ip(ifaddrclass.prefixlen, +					   (struct in_addr *)&destination); +			if ((subnetted == 1) +			    && ((rte->prefix.s_addr & destination) +				== ifaddrclass.prefix.s_addr)) { +				masklen2ip(ifaddr.prefixlen, &rte->mask); +				if ((rte->prefix.s_addr & rte->mask.s_addr) +				    != rte->prefix.s_addr) +					masklen2ip(32, &rte->mask); +				if (IS_RIP_DEBUG_EVENT) +					zlog_debug("Subnetted route %s", +						   inet_ntoa(rte->prefix)); +			} else { +				if ((rte->prefix.s_addr & rte->mask.s_addr) +				    != rte->prefix.s_addr) +					continue; +			} + +			if (IS_RIP_DEBUG_EVENT) { +				zlog_debug("Resultant route %s", +					   inet_ntoa(rte->prefix)); +				zlog_debug("Resultant mask %s", +					   inet_ntoa(rte->mask)); +			} +		} + +		/* In case of RIPv2, if prefix in RTE is not netmask applied one +		   ignore the entry.  */ +		if ((packet->version == RIPv2) && (rte->mask.s_addr != 0) +		    && ((rte->prefix.s_addr & rte->mask.s_addr) +			!= rte->prefix.s_addr)) { +			zlog_warn( +				"RIPv2 address %s is not mask /%d applied one", +				inet_ntoa(rte->prefix), ip_masklen(rte->mask)); +			rip_peer_bad_route(from); +			continue; +		} + +		/* Default route's netmask is ignored. */ +		if (packet->version == RIPv2 && (rte->prefix.s_addr == 0) +		    && (rte->mask.s_addr != 0)) { +			if (IS_RIP_DEBUG_EVENT) +				zlog_debug( +					"Default route with non-zero netmask.  Set zero to netmask"); +			rte->mask.s_addr = 0; +		} + +		/* Routing table updates. */ +		rip_rte_process(rte, from, ifc->ifp);  	} -	   -      /* Routing table updates. */ -      rip_rte_process (rte, from, ifc->ifp); -    }  }  /* Make socket for RIP protocol. */ -static int  -rip_create_socket (void) -{ -  int ret; -  int sock; -  struct sockaddr_in addr; -   -  memset (&addr, 0, sizeof (struct sockaddr_in)); -  addr.sin_family = AF_INET; -  addr.sin_addr.s_addr = INADDR_ANY; +static int rip_create_socket(void) +{ +	int ret; +	int sock; +	struct sockaddr_in addr; + +	memset(&addr, 0, sizeof(struct sockaddr_in)); +	addr.sin_family = AF_INET; +	addr.sin_addr.s_addr = INADDR_ANY;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  addr.sin_len = sizeof (struct sockaddr_in); +	addr.sin_len = sizeof(struct sockaddr_in);  #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ -  /* sending port must always be the RIP port */ -  addr.sin_port = htons (RIP_PORT_DEFAULT); -   -  /* Make datagram socket. */ -  sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); -  if (sock < 0)  -    { -      zlog_err("Cannot create UDP socket: %s", safe_strerror(errno)); -      exit (1); -    } - -  sockopt_broadcast (sock); -  sockopt_reuseaddr (sock); -  sockopt_reuseport (sock); -  setsockopt_ipv4_multicast_loop (sock, 0); +	/* sending port must always be the RIP port */ +	addr.sin_port = htons(RIP_PORT_DEFAULT); + +	/* Make datagram socket. */ +	sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); +	if (sock < 0) { +		zlog_err("Cannot create UDP socket: %s", safe_strerror(errno)); +		exit(1); +	} + +	sockopt_broadcast(sock); +	sockopt_reuseaddr(sock); +	sockopt_reuseport(sock); +	setsockopt_ipv4_multicast_loop(sock, 0);  #ifdef RIP_RECVMSG -  setsockopt_pktinfo (sock); +	setsockopt_pktinfo(sock);  #endif /* RIP_RECVMSG */  #ifdef IPTOS_PREC_INTERNETCONTROL -  setsockopt_ipv4_tos (sock, IPTOS_PREC_INTERNETCONTROL); +	setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL);  #endif -  if (ripd_privs.change (ZPRIVS_RAISE)) -      zlog_err ("rip_create_socket: could not raise privs"); -  setsockopt_so_recvbuf (sock, RIP_UDP_RCV_BUF); -  if ( (ret = bind (sock, (struct sockaddr *) & addr, sizeof (addr))) < 0) -   -    { -      int save_errno = errno; -      if (ripd_privs.change (ZPRIVS_LOWER)) -        zlog_err ("rip_create_socket: could not lower privs"); -       -      zlog_err("%s: Can't bind socket %d to %s port %d: %s", __func__, -	       sock, inet_ntoa(addr.sin_addr),  -	       (int) ntohs(addr.sin_port),  -	       safe_strerror(save_errno)); -       -      close (sock); -      return ret; -    } -   -  if (ripd_privs.change (ZPRIVS_LOWER)) -      zlog_err ("rip_create_socket: could not lower privs"); -       -  return sock; +	if (ripd_privs.change(ZPRIVS_RAISE)) +		zlog_err("rip_create_socket: could not raise privs"); +	setsockopt_so_recvbuf(sock, RIP_UDP_RCV_BUF); +	if ((ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr))) < 0) + +	{ +		int save_errno = errno; +		if (ripd_privs.change(ZPRIVS_LOWER)) +			zlog_err("rip_create_socket: could not lower privs"); + +		zlog_err("%s: Can't bind socket %d to %s port %d: %s", __func__, +			 sock, inet_ntoa(addr.sin_addr), +			 (int)ntohs(addr.sin_port), safe_strerror(save_errno)); + +		close(sock); +		return ret; +	} + +	if (ripd_privs.change(ZPRIVS_LOWER)) +		zlog_err("rip_create_socket: could not lower privs"); + +	return sock;  }  /* RIP packet send to destination address, on interface denoted by   * by connected argument. NULL to argument denotes destination should be   * should be RIP multicast group   */ -static int -rip_send_packet (u_char * buf, int size, struct sockaddr_in *to, -                 struct connected *ifc) -{ -  int ret; -  struct sockaddr_in sin; -   -  assert (ifc != NULL); -   -  if (IS_RIP_DEBUG_PACKET) -    { +static int rip_send_packet(u_char *buf, int size, struct sockaddr_in *to, +			   struct connected *ifc) +{ +	int ret; +	struct sockaddr_in sin; + +	assert(ifc != NULL); + +	if (IS_RIP_DEBUG_PACKET) {  #define ADDRESS_SIZE 20 -      char dst[ADDRESS_SIZE]; -      dst[ADDRESS_SIZE - 1] = '\0'; -       -      if (to) -        { -          strncpy (dst, inet_ntoa(to->sin_addr), ADDRESS_SIZE - 1); -        } -      else -        { -          sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP); -          strncpy (dst, inet_ntoa(sin.sin_addr), ADDRESS_SIZE - 1); -        } +		char dst[ADDRESS_SIZE]; +		dst[ADDRESS_SIZE - 1] = '\0'; + +		if (to) { +			strncpy(dst, inet_ntoa(to->sin_addr), ADDRESS_SIZE - 1); +		} else { +			sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP); +			strncpy(dst, inet_ntoa(sin.sin_addr), ADDRESS_SIZE - 1); +		}  #undef ADDRESS_SIZE -      zlog_debug("rip_send_packet %s > %s (%s)", -                inet_ntoa(ifc->address->u.prefix4), -                dst, ifc->ifp->name); -    } -   -  if ( CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY) ) -    { -      /* -       * ZEBRA_IFA_SECONDARY is set on linux when an interface is configured -       * with multiple addresses on the same subnet: the first address -       * on the subnet is configured "primary", and all subsequent addresses -       * on that subnet are treated as "secondary" addresses.  -       * In order to avoid routing-table bloat on other rip listeners,  -       * we do not send out RIP packets with ZEBRA_IFA_SECONDARY source addrs. -       * XXX Since Linux is the only system for which the ZEBRA_IFA_SECONDARY -       * flag is set, we would end up sending a packet for a "secondary" -       * source address on non-linux systems.   -       */ -      if (IS_RIP_DEBUG_PACKET) -        zlog_debug("duplicate dropped"); -      return 0; -    } - -  /* Make destination address. */ -  memset (&sin, 0, sizeof (struct sockaddr_in)); -  sin.sin_family = AF_INET; +		zlog_debug("rip_send_packet %s > %s (%s)", +			   inet_ntoa(ifc->address->u.prefix4), dst, +			   ifc->ifp->name); +	} + +	if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)) { +		/* +		 * ZEBRA_IFA_SECONDARY is set on linux when an interface is +		 * configured +		 * with multiple addresses on the same subnet: the first address +		 * on the subnet is configured "primary", and all subsequent +		 * addresses +		 * on that subnet are treated as "secondary" addresses. +		 * In order to avoid routing-table bloat on other rip listeners, +		 * we do not send out RIP packets with ZEBRA_IFA_SECONDARY +		 * source addrs. +		 * XXX Since Linux is the only system for which the +		 * ZEBRA_IFA_SECONDARY +		 * flag is set, we would end up sending a packet for a +		 * "secondary" +		 * source address on non-linux systems. +		 */ +		if (IS_RIP_DEBUG_PACKET) +			zlog_debug("duplicate dropped"); +		return 0; +	} + +	/* Make destination address. */ +	memset(&sin, 0, sizeof(struct sockaddr_in)); +	sin.sin_family = AF_INET;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  sin.sin_len = sizeof (struct sockaddr_in); +	sin.sin_len = sizeof(struct sockaddr_in);  #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ -  /* When destination is specified, use it's port and address. */ -  if (to) -    { -      sin.sin_port = to->sin_port; -      sin.sin_addr = to->sin_addr; -    } -  else -    { -      sin.sin_port = htons (RIP_PORT_DEFAULT); -      sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP); +	/* When destination is specified, use it's port and address. */ +	if (to) { +		sin.sin_port = to->sin_port; +		sin.sin_addr = to->sin_addr; +	} else { +		sin.sin_port = htons(RIP_PORT_DEFAULT); +		sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP); -      rip_interface_multicast_set (rip->sock, ifc); -    } +		rip_interface_multicast_set(rip->sock, ifc); +	} -  ret = sendto (rip->sock, buf, size, 0, (struct sockaddr *)&sin, -		sizeof (struct sockaddr_in)); +	ret = sendto(rip->sock, buf, size, 0, (struct sockaddr *)&sin, +		     sizeof(struct sockaddr_in)); -  if (IS_RIP_DEBUG_EVENT) -      zlog_debug ("SEND to  %s.%d", inet_ntoa(sin.sin_addr),  -                  ntohs (sin.sin_port)); +	if (IS_RIP_DEBUG_EVENT) +		zlog_debug("SEND to  %s.%d", inet_ntoa(sin.sin_addr), +			   ntohs(sin.sin_port)); -  if (ret < 0) -    zlog_warn ("can't send packet : %s", safe_strerror (errno)); +	if (ret < 0) +		zlog_warn("can't send packet : %s", safe_strerror(errno)); -  return ret; +	return ret;  }  /* Add redistributed route to RIP table. */ -void -rip_redistribute_add (int type, int sub_type, struct prefix_ipv4 *p,  -		      ifindex_t ifindex, struct in_addr *nexthop, -                      unsigned int metric, unsigned char distance, -                      route_tag_t tag) -{ -  int ret; -  struct route_node *rp = NULL; -  struct rip_info *rinfo = NULL, newinfo; -  struct list *list = NULL; +void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p, +			  ifindex_t ifindex, struct in_addr *nexthop, +			  unsigned int metric, unsigned char distance, +			  route_tag_t tag) +{ +	int ret; +	struct route_node *rp = NULL; +	struct rip_info *rinfo = NULL, newinfo; +	struct list *list = NULL; + +	/* Redistribute route  */ +	ret = rip_destination_check(p->prefix); +	if (!ret) +		return; + +	rp = route_node_get(rip->table, (struct prefix *)p); + +	memset(&newinfo, 0, sizeof(struct rip_info)); +	newinfo.type = type; +	newinfo.sub_type = sub_type; +	newinfo.ifindex = ifindex; +	newinfo.metric = 1; +	newinfo.external_metric = metric; +	newinfo.distance = distance; +	if (tag <= UINT16_MAX) /* RIP only supports 16 bit tags */ +		newinfo.tag = tag; +	newinfo.rp = rp; +	if (nexthop) +		newinfo.nexthop = *nexthop; + +	if ((list = rp->info) != NULL && listcount(list) != 0) { +		rinfo = listgetdata(listhead(list)); + +		if (rinfo->type == ZEBRA_ROUTE_CONNECT +		    && rinfo->sub_type == RIP_ROUTE_INTERFACE +		    && rinfo->metric != RIP_METRIC_INFINITY) { +			route_unlock_node(rp); +			return; +		} -  /* Redistribute route  */ -  ret = rip_destination_check (p->prefix); -  if (! ret) -    return; - -  rp = route_node_get (rip->table, (struct prefix *) p); - -  memset (&newinfo, 0, sizeof (struct rip_info)); -  newinfo.type = type; -  newinfo.sub_type = sub_type; -  newinfo.ifindex = ifindex; -  newinfo.metric = 1; -  newinfo.external_metric = metric; -  newinfo.distance = distance; -  if (tag <= UINT16_MAX) /* RIP only supports 16 bit tags */ -    newinfo.tag = tag; -  newinfo.rp = rp; -  if (nexthop) -    newinfo.nexthop = *nexthop; - -  if ((list = rp->info) != NULL && listcount (list) != 0) -    { -      rinfo = listgetdata (listhead (list)); - -      if (rinfo->type == ZEBRA_ROUTE_CONNECT  -	  && rinfo->sub_type == RIP_ROUTE_INTERFACE -	  && rinfo->metric != RIP_METRIC_INFINITY) -	{ -	  route_unlock_node (rp); -	  return; +		/* Manually configured RIP route check. */ +		if (rinfo->type == ZEBRA_ROUTE_RIP +		    && ((rinfo->sub_type == RIP_ROUTE_STATIC) +			|| (rinfo->sub_type == RIP_ROUTE_DEFAULT))) { +			if (type != ZEBRA_ROUTE_RIP +			    || ((sub_type != RIP_ROUTE_STATIC) +				&& (sub_type != RIP_ROUTE_DEFAULT))) { +				route_unlock_node(rp); +				return; +			} +		} + +		rinfo = rip_ecmp_replace(&newinfo); +		route_unlock_node(rp); +	} else +		rinfo = rip_ecmp_add(&newinfo); + +	if (IS_RIP_DEBUG_EVENT) { +		if (!nexthop) +			zlog_debug( +				"Redistribute new prefix %s/%d on the interface %s", +				inet_ntoa(p->prefix), p->prefixlen, +				ifindex2ifname(ifindex, VRF_DEFAULT)); +		else +			zlog_debug( +				"Redistribute new prefix %s/%d with nexthop %s on the interface %s", +				inet_ntoa(p->prefix), p->prefixlen, +				inet_ntoa(rinfo->nexthop), +				ifindex2ifname(ifindex, VRF_DEFAULT));  	} -      /* Manually configured RIP route check. */ -      if (rinfo->type == ZEBRA_ROUTE_RIP  -	  && ((rinfo->sub_type == RIP_ROUTE_STATIC) || -	      (rinfo->sub_type == RIP_ROUTE_DEFAULT)) ) -	{ -	  if (type != ZEBRA_ROUTE_RIP || ((sub_type != RIP_ROUTE_STATIC) && -	                                  (sub_type != RIP_ROUTE_DEFAULT))) -	    { -	      route_unlock_node (rp); -	      return; -	    } -	} - -      rinfo = rip_ecmp_replace (&newinfo); -      route_unlock_node (rp); -    } -  else -    rinfo = rip_ecmp_add (&newinfo); - -  if (IS_RIP_DEBUG_EVENT) { -    if (!nexthop) -      zlog_debug ("Redistribute new prefix %s/%d on the interface %s", -                  inet_ntoa(p->prefix), p->prefixlen, -                  ifindex2ifname(ifindex, VRF_DEFAULT)); -    else -      zlog_debug ("Redistribute new prefix %s/%d with nexthop %s on the interface %s", -                  inet_ntoa(p->prefix), p->prefixlen, inet_ntoa(rinfo->nexthop), -                  ifindex2ifname(ifindex, VRF_DEFAULT)); -  } - -  rip_event (RIP_TRIGGERED_UPDATE, 0); +	rip_event(RIP_TRIGGERED_UPDATE, 0);  }  /* Delete redistributed route from RIP table. */ -void -rip_redistribute_delete (int type, int sub_type, struct prefix_ipv4 *p,  -			 ifindex_t ifindex) -{ -  int ret; -  struct route_node *rp; -  struct rip_info *rinfo; - -  ret = rip_destination_check (p->prefix); -  if (! ret) -    return; - -  rp = route_node_lookup (rip->table, (struct prefix *) p); -  if (rp) -    { -      struct list *list = rp->info; - -      if (list != NULL && listcount (list) != 0) -        { -          rinfo = listgetdata (listhead (list)); -          if (rinfo != NULL -              && rinfo->type == type -              && rinfo->sub_type == sub_type -              && rinfo->ifindex == ifindex) -            { -              /* Perform poisoned reverse. */ -              rinfo->metric = RIP_METRIC_INFINITY; -              RIP_TIMER_ON (rinfo->t_garbage_collect, -                            rip_garbage_collect, rip->garbage_time); -              RIP_TIMER_OFF (rinfo->t_timeout); -              rinfo->flags |= RIP_RTF_CHANGED; - -              if (IS_RIP_DEBUG_EVENT) -                zlog_debug ("Poisone %s/%d on the interface %s with an " -                            "infinity metric [delete]", -                            inet_ntoa(p->prefix), p->prefixlen, -                            ifindex2ifname(ifindex, VRF_DEFAULT)); - -              rip_event (RIP_TRIGGERED_UPDATE, 0); -            } -        } -      route_unlock_node (rp); -    } +void rip_redistribute_delete(int type, int sub_type, struct prefix_ipv4 *p, +			     ifindex_t ifindex) +{ +	int ret; +	struct route_node *rp; +	struct rip_info *rinfo; + +	ret = rip_destination_check(p->prefix); +	if (!ret) +		return; + +	rp = route_node_lookup(rip->table, (struct prefix *)p); +	if (rp) { +		struct list *list = rp->info; + +		if (list != NULL && listcount(list) != 0) { +			rinfo = listgetdata(listhead(list)); +			if (rinfo != NULL && rinfo->type == type +			    && rinfo->sub_type == sub_type +			    && rinfo->ifindex == ifindex) { +				/* Perform poisoned reverse. */ +				rinfo->metric = RIP_METRIC_INFINITY; +				RIP_TIMER_ON(rinfo->t_garbage_collect, +					     rip_garbage_collect, +					     rip->garbage_time); +				RIP_TIMER_OFF(rinfo->t_timeout); +				rinfo->flags |= RIP_RTF_CHANGED; + +				if (IS_RIP_DEBUG_EVENT) +					zlog_debug( +						"Poisone %s/%d on the interface %s with an " +						"infinity metric [delete]", +						inet_ntoa(p->prefix), +						p->prefixlen, +						ifindex2ifname(ifindex, +							       VRF_DEFAULT)); + +				rip_event(RIP_TRIGGERED_UPDATE, 0); +			} +		} +		route_unlock_node(rp); +	}  }  /* Response to request called from rip_read ().*/ -static void -rip_request_process (struct rip_packet *packet, int size,  -		     struct sockaddr_in *from, struct connected *ifc) -{ -  caddr_t lim; -  struct rte *rte; -  struct prefix_ipv4 p; -  struct route_node *rp; -  struct rip_info *rinfo; -  struct rip_interface *ri; - -  /* Does not reponse to the requests on the loopback interfaces */ -  if (if_is_loopback (ifc->ifp)) -    return; - -  /* Check RIP process is enabled on this interface. */ -  ri = ifc->ifp->info; -  if (! ri->running) -    return; - -  /* When passive interface is specified, suppress responses */ -  if (ri->passive) -    return; -   -  /* RIP peer update. */ -  rip_peer_update (from, packet->version); - -  lim = ((caddr_t) packet) + size; -  rte = packet->rte; - -  /* The Request is processed entry by entry.  If there are no -     entries, no response is given. */ -  if (lim == (caddr_t) rte) -    return; - -  /* There is one special case.  If there is exactly one entry in the -     request, and it has an address family identifier of zero and a -     metric of infinity (i.e., 16), then this is a request to send the -     entire routing table. */ -  if (lim == ((caddr_t) (rte + 1)) && -      ntohs (rte->family) == 0 && -      ntohl (rte->metric) == RIP_METRIC_INFINITY) -    {	 -      /* All route with split horizon */ -      rip_output_process (ifc, from, rip_all_route, packet->version); -    } -  else -    { -      if (ntohs (rte->family) != AF_INET) -	return; +static void rip_request_process(struct rip_packet *packet, int size, +				struct sockaddr_in *from, struct connected *ifc) +{ +	caddr_t lim; +	struct rte *rte; +	struct prefix_ipv4 p; +	struct route_node *rp; +	struct rip_info *rinfo; +	struct rip_interface *ri; + +	/* Does not reponse to the requests on the loopback interfaces */ +	if (if_is_loopback(ifc->ifp)) +		return; + +	/* Check RIP process is enabled on this interface. */ +	ri = ifc->ifp->info; +	if (!ri->running) +		return; + +	/* When passive interface is specified, suppress responses */ +	if (ri->passive) +		return; + +	/* RIP peer update. */ +	rip_peer_update(from, packet->version); + +	lim = ((caddr_t)packet) + size; +	rte = packet->rte; + +	/* The Request is processed entry by entry.  If there are no +	   entries, no response is given. */ +	if (lim == (caddr_t)rte) +		return; + +	/* There is one special case.  If there is exactly one entry in the +	   request, and it has an address family identifier of zero and a +	   metric of infinity (i.e., 16), then this is a request to send the +	   entire routing table. */ +	if (lim == ((caddr_t)(rte + 1)) && ntohs(rte->family) == 0 +	    && ntohl(rte->metric) == RIP_METRIC_INFINITY) { +		/* All route with split horizon */ +		rip_output_process(ifc, from, rip_all_route, packet->version); +	} else { +		if (ntohs(rte->family) != AF_INET) +			return; + +		/* Examine the list of RTEs in the Request one by one.  For each +		   entry, look up the destination in the router's routing +		   database and, if there is a route, put that route's metric in +		   the metric field of the RTE.  If there is no explicit route +		   to the specified destination, put infinity in the metric +		   field.  Once all the entries have been filled in, change the +		   command from Request to Response and send the datagram back +		   to the requestor. */ +		p.family = AF_INET; + +		for (; ((caddr_t)rte) < lim; rte++) { +			p.prefix = rte->prefix; +			p.prefixlen = ip_masklen(rte->mask); +			apply_mask_ipv4(&p); + +			rp = route_node_lookup(rip->table, (struct prefix *)&p); +			if (rp) { +				rinfo = listgetdata( +					listhead((struct list *)rp->info)); +				rte->metric = htonl(rinfo->metric); +				route_unlock_node(rp); +			} else +				rte->metric = htonl(RIP_METRIC_INFINITY); +		} +		packet->command = RIP_RESPONSE; -      /* Examine the list of RTEs in the Request one by one.  For each -	 entry, look up the destination in the router's routing -	 database and, if there is a route, put that route's metric in -	 the metric field of the RTE.  If there is no explicit route -	 to the specified destination, put infinity in the metric -	 field.  Once all the entries have been filled in, change the -	 command from Request to Response and send the datagram back -	 to the requestor. */ -      p.family = AF_INET; - -      for (; ((caddr_t) rte) < lim; rte++) -	{ -	  p.prefix = rte->prefix; -	  p.prefixlen = ip_masklen (rte->mask); -	  apply_mask_ipv4 (&p); -	   -	  rp = route_node_lookup (rip->table, (struct prefix *) &p); -	  if (rp) -	    { -	      rinfo = listgetdata (listhead ((struct list *)rp->info)); -	      rte->metric = htonl (rinfo->metric); -	      route_unlock_node (rp); -	    } -	  else -	    rte->metric = htonl (RIP_METRIC_INFINITY); -	} -      packet->command = RIP_RESPONSE; - -      rip_send_packet ((u_char *)packet, size, from, ifc); -    } -  rip_global_queries++; +		rip_send_packet((u_char *)packet, size, from, ifc); +	} +	rip_global_queries++;  }  #if RIP_RECVMSG  /* Set IPv6 packet info to the socket. */ -static int -setsockopt_pktinfo (int sock) +static int setsockopt_pktinfo(int sock)  { -  int ret; -  int val = 1; -     -  ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val)); -  if (ret < 0) -    zlog_warn ("Can't setsockopt IP_PKTINFO : %s", safe_strerror (errno)); -  return ret; +	int ret; +	int val = 1; + +	ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val)); +	if (ret < 0) +		zlog_warn("Can't setsockopt IP_PKTINFO : %s", +			  safe_strerror(errno)); +	return ret;  }  /* Read RIP packet by recvmsg function. */ -int -rip_recvmsg (int sock, u_char *buf, int size, struct sockaddr_in *from, -	     ifindex_t *ifindex) -{ -  int ret; -  struct msghdr msg; -  struct iovec iov; -  struct cmsghdr *ptr; -  char adata[1024]; - -  msg.msg_name = (void *) from; -  msg.msg_namelen = sizeof (struct sockaddr_in); -  msg.msg_iov = &iov; -  msg.msg_iovlen = 1; -  msg.msg_control = (void *) adata; -  msg.msg_controllen = sizeof adata; -  iov.iov_base = buf; -  iov.iov_len = size; - -  ret = recvmsg (sock, &msg, 0); -  if (ret < 0) -    return ret; - -  for (ptr = ZCMSG_FIRSTHDR(&msg); ptr != NULL; ptr = CMSG_NXTHDR(&msg, ptr)) -    if (ptr->cmsg_level == IPPROTO_IP && ptr->cmsg_type == IP_PKTINFO)  -      { -	struct in_pktinfo *pktinfo; -	int i; +int rip_recvmsg(int sock, u_char *buf, int size, struct sockaddr_in *from, +		ifindex_t *ifindex) +{ +	int ret; +	struct msghdr msg; +	struct iovec iov; +	struct cmsghdr *ptr; +	char adata[1024]; + +	msg.msg_name = (void *)from; +	msg.msg_namelen = sizeof(struct sockaddr_in); +	msg.msg_iov = &iov; +	msg.msg_iovlen = 1; +	msg.msg_control = (void *)adata; +	msg.msg_controllen = sizeof adata; +	iov.iov_base = buf; +	iov.iov_len = size; + +	ret = recvmsg(sock, &msg, 0); +	if (ret < 0) +		return ret; -	pktinfo = (struct in_pktinfo *) CMSG_DATA (ptr); -	i = pktinfo->ipi_ifindex; -      } -  return ret; +	for (ptr = ZCMSG_FIRSTHDR(&msg); ptr != NULL; +	     ptr = CMSG_NXTHDR(&msg, ptr)) +		if (ptr->cmsg_level == IPPROTO_IP +		    && ptr->cmsg_type == IP_PKTINFO) { +			struct in_pktinfo *pktinfo; +			int i; + +			pktinfo = (struct in_pktinfo *)CMSG_DATA(ptr); +			i = pktinfo->ipi_ifindex; +		} +	return ret;  }  /* RIP packet read function. */ -int -rip_read_new (struct thread *t) -{ -  int ret; -  int sock; -  char buf[RIP_PACKET_MAXSIZ]; -  struct sockaddr_in from; -  ifindex_t ifindex; -   -  /* Fetch socket then register myself. */ -  sock = THREAD_FD (t); -  rip_event (RIP_READ, sock); - -  /* Read RIP packet. */ -  ret = rip_recvmsg (sock, buf, RIP_PACKET_MAXSIZ, &from, (int *)&ifindex); -  if (ret < 0) -    { -      zlog_warn ("Can't read RIP packet: %s", safe_strerror (errno)); -      return ret; -    } - -  return ret; +int rip_read_new(struct thread *t) +{ +	int ret; +	int sock; +	char buf[RIP_PACKET_MAXSIZ]; +	struct sockaddr_in from; +	ifindex_t ifindex; + +	/* Fetch socket then register myself. */ +	sock = THREAD_FD(t); +	rip_event(RIP_READ, sock); + +	/* Read RIP packet. */ +	ret = rip_recvmsg(sock, buf, RIP_PACKET_MAXSIZ, &from, (int *)&ifindex); +	if (ret < 0) { +		zlog_warn("Can't read RIP packet: %s", safe_strerror(errno)); +		return ret; +	} + +	return ret;  }  #endif /* RIP_RECVMSG */  /* First entry point of RIP packet. */ -static int -rip_read (struct thread *t) -{ -  int sock; -  int ret; -  int rtenum; -  union rip_buf rip_buf; -  struct rip_packet *packet; -  struct sockaddr_in from; -  int len; -  int vrecv; -  socklen_t fromlen; -  struct interface *ifp = NULL; -  struct connected *ifc; -  struct rip_interface *ri; -  struct prefix p; - -  /* Fetch socket then register myself. */ -  sock = THREAD_FD (t); -  rip->t_read = NULL; - -  /* Add myself to tne next event */ -  rip_event (RIP_READ, sock); - -  /* RIPd manages only IPv4. */ -  memset (&from, 0, sizeof (struct sockaddr_in)); -  fromlen = sizeof (struct sockaddr_in); - -  len = recvfrom (sock, (char *)&rip_buf.buf, sizeof (rip_buf.buf), 0,  -		  (struct sockaddr *) &from, &fromlen); -  if (len < 0)  -    { -      zlog_info ("recvfrom failed: %s", safe_strerror (errno)); -      return len; -    } - -  /* Check is this packet comming from myself? */ -  if (if_check_address (from.sin_addr))  -    { -      if (IS_RIP_DEBUG_PACKET) -	zlog_debug ("ignore packet comes from myself"); -      return -1; -    } - -  /* Which interface is this packet comes from. */ -  ifc = if_lookup_address ((void *)&from.sin_addr, AF_INET, VRF_DEFAULT); -  if (ifc) -    ifp = ifc->ifp; - -  /* RIP packet received */ -  if (IS_RIP_DEBUG_EVENT) -    zlog_debug ("RECV packet from %s port %d on %s", -	       inet_ntoa (from.sin_addr), ntohs (from.sin_port), -	       ifp ? ifp->name : "unknown"); - -  /* If this packet come from unknown interface, ignore it. */ -  if (ifp == NULL) -    { -      zlog_info ("rip_read: cannot find interface for packet from %s port %d", -		 inet_ntoa(from.sin_addr), ntohs (from.sin_port)); -      return -1; -    } - -  p.family = AF_INET; -  p.u.prefix4 = from.sin_addr; -  p.prefixlen = IPV4_MAX_BITLEN; - -  ifc = connected_lookup_prefix (ifp, &p); -   -  if (ifc == NULL) -    { -      zlog_info ("rip_read: cannot find connected address for packet from %s " -		 "port %d on interface %s", -		 inet_ntoa(from.sin_addr), ntohs (from.sin_port), ifp->name); -      return -1; -    } - -  /* Packet length check. */ -  if (len < RIP_PACKET_MINSIZ) -    { -      zlog_warn ("packet size %d is smaller than minimum size %d", -		 len, RIP_PACKET_MINSIZ); -      rip_peer_bad_packet (&from); -      return len; -    } -  if (len > RIP_PACKET_MAXSIZ) -    { -      zlog_warn ("packet size %d is larger than max size %d", -		 len, RIP_PACKET_MAXSIZ); -      rip_peer_bad_packet (&from); -      return len; -    } - -  /* Packet alignment check. */ -  if ((len - RIP_PACKET_MINSIZ) % 20) -    { -      zlog_warn ("packet size %d is wrong for RIP packet alignment", len); -      rip_peer_bad_packet (&from); -      return len; -    } - -  /* Set RTE number. */ -  rtenum = ((len - RIP_PACKET_MINSIZ) / 20); - -  /* For easy to handle. */ -  packet = &rip_buf.rip_packet; - -  /* RIP version check. */ -  if (packet->version == 0) -    { -      zlog_info ("version 0 with command %d received.", packet->command); -      rip_peer_bad_packet (&from); -      return -1; -    } - -  /* Dump RIP packet. */ -  if (IS_RIP_DEBUG_RECV) -    rip_packet_dump (packet, len, "RECV"); - -  /* RIP version adjust.  This code should rethink now.  RFC1058 says -     that "Version 1 implementations are to ignore this extra data and -     process only the fields specified in this document.". So RIPv3 -     packet should be treated as RIPv1 ignoring must be zero field. */ -  if (packet->version > RIPv2) -    packet->version = RIPv2; - -  /* Is RIP running or is this RIP neighbor ?*/ -  ri = ifp->info; -  if (! ri->running && ! rip_neighbor_lookup (&from)) -    { -      if (IS_RIP_DEBUG_EVENT) -	zlog_debug ("RIP is not enabled on interface %s.", ifp->name); -      rip_peer_bad_packet (&from); -      return -1; -    } - -  /* RIP Version check. RFC2453, 4.6 and 5.1 */ -  vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ? -           rip->version_recv : ri->ri_receive); -  if (vrecv == RI_RIP_VERSION_NONE || -      ((packet->version == RIPv1) && !(vrecv & RIPv1)) || -      ((packet->version == RIPv2) && !(vrecv & RIPv2))) -    { -      if (IS_RIP_DEBUG_PACKET) -        zlog_debug ("  packet's v%d doesn't fit to if version spec",  -                   packet->version); -      rip_peer_bad_packet (&from); -      return -1; -    } -   -  /* RFC2453 5.2 If the router is not configured to authenticate RIP-2 -     messages, then RIP-1 and unauthenticated RIP-2 messages will be -     accepted; authenticated RIP-2 messages shall be discarded.  */ -  if ((ri->auth_type == RIP_NO_AUTH)  -      && rtenum  -      && (packet->version == RIPv2)  -      && (packet->rte->family == htons(RIP_FAMILY_AUTH))) -    { -      if (IS_RIP_DEBUG_EVENT) -	zlog_debug ("packet RIPv%d is dropped because authentication disabled",  -		   packet->version); -      rip_peer_bad_packet (&from); -      return -1; -    } -   -  /* RFC: -     If the router is configured to authenticate RIP-2 messages, then -     RIP-1 messages and RIP-2 messages which pass authentication -     testing shall be accepted; unauthenticated and failed -     authentication RIP-2 messages shall be discarded.  For maximum -     security, RIP-1 messages should be ignored when authentication is -     in use (see section 4.1); otherwise, the routing information from -     authenticated messages will be propagated by RIP-1 routers in an -     unauthenticated manner.  -  */ -  /* We make an exception for RIPv1 REQUEST packets, to which we'll -   * always reply regardless of authentication settings, because: -   * -   * - if there other authorised routers on-link, the REQUESTor can -   *   passively obtain the routing updates anyway -   * - if there are no other authorised routers on-link, RIP can -   *   easily be disabled for the link to prevent giving out information -   *   on state of this routers RIP routing table.. -   * -   * I.e. if RIPv1 has any place anymore these days, it's as a very -   * simple way to distribute routing information (e.g. to embedded -   * hosts / appliances) and the ability to give out RIPv1 -   * routing-information freely, while still requiring RIPv2 -   * authentication for any RESPONSEs might be vaguely useful. -   */ -  if (ri->auth_type != RIP_NO_AUTH  -      && packet->version == RIPv1) -    { -      /* Discard RIPv1 messages other than REQUESTs */ -      if (packet->command != RIP_REQUEST) -        { -          if (IS_RIP_DEBUG_PACKET) -            zlog_debug ("RIPv1" " dropped because authentication enabled"); -          rip_peer_bad_packet (&from); -          return -1; -        } -    } -  else if (ri->auth_type != RIP_NO_AUTH) -    { -      const char *auth_desc; -       -      if (rtenum == 0) -        { -          /* There definitely is no authentication in the packet. */ -          if (IS_RIP_DEBUG_PACKET) -            zlog_debug ("RIPv2 authentication failed: no auth RTE in packet"); -          rip_peer_bad_packet (&from); -          return -1; -        } -       -      /* First RTE must be an Authentication Family RTE */ -      if (packet->rte->family != htons(RIP_FAMILY_AUTH)) -        { -          if (IS_RIP_DEBUG_PACKET) -            zlog_debug ("RIPv2" " dropped because authentication enabled"); -	  rip_peer_bad_packet (&from); -	  return -1; -        } -       -      /* Check RIPv2 authentication. */ -      switch (ntohs(packet->rte->tag)) -        { -          case RIP_AUTH_SIMPLE_PASSWORD: -            auth_desc = "simple"; -            ret = rip_auth_simple_password (packet->rte, &from, ifp); -            break; -           -          case RIP_AUTH_MD5: -            auth_desc = "MD5"; -            ret = rip_auth_md5 (packet, &from, len, ifp); -            /* Reset RIP packet length to trim MD5 data. */ -            len = ret; -            break; -           -          default: -            ret = 0; -            auth_desc = "unknown type"; -            if (IS_RIP_DEBUG_PACKET) -              zlog_debug ("RIPv2 Unknown authentication type %d", -                          ntohs (packet->rte->tag)); -        } -       -      if (ret) -        { -          if (IS_RIP_DEBUG_PACKET) -            zlog_debug ("RIPv2 %s authentication success", auth_desc); -        } -      else -        { -          if (IS_RIP_DEBUG_PACKET) -            zlog_debug ("RIPv2 %s authentication failure", auth_desc); -          rip_peer_bad_packet (&from); -          return -1; -        } -    } -   -  /* Process each command. */ -  switch (packet->command) -    { -    case RIP_RESPONSE: -      rip_response_process (packet, len, &from, ifc); -      break; -    case RIP_REQUEST: -    case RIP_POLL: -      rip_request_process (packet, len, &from, ifc); -      break; -    case RIP_TRACEON: -    case RIP_TRACEOFF: -      zlog_info ("Obsolete command %s received, please sent it to routed",  -		 lookup_msg (rip_msg, packet->command, NULL)); -      rip_peer_bad_packet (&from); -      break; -    case RIP_POLL_ENTRY: -      zlog_info ("Obsolete command %s received",  -		 lookup_msg (rip_msg, packet->command, NULL)); -      rip_peer_bad_packet (&from); -      break; -    default: -      zlog_info ("Unknown RIP command %d received", packet->command); -      rip_peer_bad_packet (&from); -      break; -    } - -  return len; +static int rip_read(struct thread *t) +{ +	int sock; +	int ret; +	int rtenum; +	union rip_buf rip_buf; +	struct rip_packet *packet; +	struct sockaddr_in from; +	int len; +	int vrecv; +	socklen_t fromlen; +	struct interface *ifp = NULL; +	struct connected *ifc; +	struct rip_interface *ri; +	struct prefix p; + +	/* Fetch socket then register myself. */ +	sock = THREAD_FD(t); +	rip->t_read = NULL; + +	/* Add myself to tne next event */ +	rip_event(RIP_READ, sock); + +	/* RIPd manages only IPv4. */ +	memset(&from, 0, sizeof(struct sockaddr_in)); +	fromlen = sizeof(struct sockaddr_in); + +	len = recvfrom(sock, (char *)&rip_buf.buf, sizeof(rip_buf.buf), 0, +		       (struct sockaddr *)&from, &fromlen); +	if (len < 0) { +		zlog_info("recvfrom failed: %s", safe_strerror(errno)); +		return len; +	} + +	/* Check is this packet comming from myself? */ +	if (if_check_address(from.sin_addr)) { +		if (IS_RIP_DEBUG_PACKET) +			zlog_debug("ignore packet comes from myself"); +		return -1; +	} + +	/* Which interface is this packet comes from. */ +	ifc = if_lookup_address((void *)&from.sin_addr, AF_INET, VRF_DEFAULT); +	if (ifc) +		ifp = ifc->ifp; + +	/* RIP packet received */ +	if (IS_RIP_DEBUG_EVENT) +		zlog_debug("RECV packet from %s port %d on %s", +			   inet_ntoa(from.sin_addr), ntohs(from.sin_port), +			   ifp ? ifp->name : "unknown"); + +	/* If this packet come from unknown interface, ignore it. */ +	if (ifp == NULL) { +		zlog_info( +			"rip_read: cannot find interface for packet from %s port %d", +			inet_ntoa(from.sin_addr), ntohs(from.sin_port)); +		return -1; +	} + +	p.family = AF_INET; +	p.u.prefix4 = from.sin_addr; +	p.prefixlen = IPV4_MAX_BITLEN; + +	ifc = connected_lookup_prefix(ifp, &p); + +	if (ifc == NULL) { +		zlog_info( +			"rip_read: cannot find connected address for packet from %s " +			"port %d on interface %s", +			inet_ntoa(from.sin_addr), ntohs(from.sin_port), +			ifp->name); +		return -1; +	} + +	/* Packet length check. */ +	if (len < RIP_PACKET_MINSIZ) { +		zlog_warn("packet size %d is smaller than minimum size %d", len, +			  RIP_PACKET_MINSIZ); +		rip_peer_bad_packet(&from); +		return len; +	} +	if (len > RIP_PACKET_MAXSIZ) { +		zlog_warn("packet size %d is larger than max size %d", len, +			  RIP_PACKET_MAXSIZ); +		rip_peer_bad_packet(&from); +		return len; +	} + +	/* Packet alignment check. */ +	if ((len - RIP_PACKET_MINSIZ) % 20) { +		zlog_warn("packet size %d is wrong for RIP packet alignment", +			  len); +		rip_peer_bad_packet(&from); +		return len; +	} + +	/* Set RTE number. */ +	rtenum = ((len - RIP_PACKET_MINSIZ) / 20); + +	/* For easy to handle. */ +	packet = &rip_buf.rip_packet; + +	/* RIP version check. */ +	if (packet->version == 0) { +		zlog_info("version 0 with command %d received.", +			  packet->command); +		rip_peer_bad_packet(&from); +		return -1; +	} + +	/* Dump RIP packet. */ +	if (IS_RIP_DEBUG_RECV) +		rip_packet_dump(packet, len, "RECV"); + +	/* RIP version adjust.  This code should rethink now.  RFC1058 says +	   that "Version 1 implementations are to ignore this extra data and +	   process only the fields specified in this document.". So RIPv3 +	   packet should be treated as RIPv1 ignoring must be zero field. */ +	if (packet->version > RIPv2) +		packet->version = RIPv2; + +	/* Is RIP running or is this RIP neighbor ?*/ +	ri = ifp->info; +	if (!ri->running && !rip_neighbor_lookup(&from)) { +		if (IS_RIP_DEBUG_EVENT) +			zlog_debug("RIP is not enabled on interface %s.", +				   ifp->name); +		rip_peer_bad_packet(&from); +		return -1; +	} + +	/* RIP Version check. RFC2453, 4.6 and 5.1 */ +	vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ? rip->version_recv +						   : ri->ri_receive); +	if (vrecv == RI_RIP_VERSION_NONE +	    || ((packet->version == RIPv1) && !(vrecv & RIPv1)) +	    || ((packet->version == RIPv2) && !(vrecv & RIPv2))) { +		if (IS_RIP_DEBUG_PACKET) +			zlog_debug( +				"  packet's v%d doesn't fit to if version spec", +				packet->version); +		rip_peer_bad_packet(&from); +		return -1; +	} + +	/* RFC2453 5.2 If the router is not configured to authenticate RIP-2 +	   messages, then RIP-1 and unauthenticated RIP-2 messages will be +	   accepted; authenticated RIP-2 messages shall be discarded.  */ +	if ((ri->auth_type == RIP_NO_AUTH) && rtenum +	    && (packet->version == RIPv2) +	    && (packet->rte->family == htons(RIP_FAMILY_AUTH))) { +		if (IS_RIP_DEBUG_EVENT) +			zlog_debug( +				"packet RIPv%d is dropped because authentication disabled", +				packet->version); +		rip_peer_bad_packet(&from); +		return -1; +	} + +	/* RFC: +	   If the router is configured to authenticate RIP-2 messages, then +	   RIP-1 messages and RIP-2 messages which pass authentication +	   testing shall be accepted; unauthenticated and failed +	   authentication RIP-2 messages shall be discarded.  For maximum +	   security, RIP-1 messages should be ignored when authentication is +	   in use (see section 4.1); otherwise, the routing information from +	   authenticated messages will be propagated by RIP-1 routers in an +	   unauthenticated manner. +	*/ +	/* We make an exception for RIPv1 REQUEST packets, to which we'll +	 * always reply regardless of authentication settings, because: +	 * +	 * - if there other authorised routers on-link, the REQUESTor can +	 *   passively obtain the routing updates anyway +	 * - if there are no other authorised routers on-link, RIP can +	 *   easily be disabled for the link to prevent giving out information +	 *   on state of this routers RIP routing table.. +	 * +	 * I.e. if RIPv1 has any place anymore these days, it's as a very +	 * simple way to distribute routing information (e.g. to embedded +	 * hosts / appliances) and the ability to give out RIPv1 +	 * routing-information freely, while still requiring RIPv2 +	 * authentication for any RESPONSEs might be vaguely useful. +	 */ +	if (ri->auth_type != RIP_NO_AUTH && packet->version == RIPv1) { +		/* Discard RIPv1 messages other than REQUESTs */ +		if (packet->command != RIP_REQUEST) { +			if (IS_RIP_DEBUG_PACKET) +				zlog_debug( +					"RIPv1" +					" dropped because authentication enabled"); +			rip_peer_bad_packet(&from); +			return -1; +		} +	} else if (ri->auth_type != RIP_NO_AUTH) { +		const char *auth_desc; + +		if (rtenum == 0) { +			/* There definitely is no authentication in the packet. +			 */ +			if (IS_RIP_DEBUG_PACKET) +				zlog_debug( +					"RIPv2 authentication failed: no auth RTE in packet"); +			rip_peer_bad_packet(&from); +			return -1; +		} + +		/* First RTE must be an Authentication Family RTE */ +		if (packet->rte->family != htons(RIP_FAMILY_AUTH)) { +			if (IS_RIP_DEBUG_PACKET) +				zlog_debug( +					"RIPv2" +					" dropped because authentication enabled"); +			rip_peer_bad_packet(&from); +			return -1; +		} + +		/* Check RIPv2 authentication. */ +		switch (ntohs(packet->rte->tag)) { +		case RIP_AUTH_SIMPLE_PASSWORD: +			auth_desc = "simple"; +			ret = rip_auth_simple_password(packet->rte, &from, ifp); +			break; + +		case RIP_AUTH_MD5: +			auth_desc = "MD5"; +			ret = rip_auth_md5(packet, &from, len, ifp); +			/* Reset RIP packet length to trim MD5 data. */ +			len = ret; +			break; + +		default: +			ret = 0; +			auth_desc = "unknown type"; +			if (IS_RIP_DEBUG_PACKET) +				zlog_debug( +					"RIPv2 Unknown authentication type %d", +					ntohs(packet->rte->tag)); +		} + +		if (ret) { +			if (IS_RIP_DEBUG_PACKET) +				zlog_debug("RIPv2 %s authentication success", +					   auth_desc); +		} else { +			if (IS_RIP_DEBUG_PACKET) +				zlog_debug("RIPv2 %s authentication failure", +					   auth_desc); +			rip_peer_bad_packet(&from); +			return -1; +		} +	} + +	/* Process each command. */ +	switch (packet->command) { +	case RIP_RESPONSE: +		rip_response_process(packet, len, &from, ifc); +		break; +	case RIP_REQUEST: +	case RIP_POLL: +		rip_request_process(packet, len, &from, ifc); +		break; +	case RIP_TRACEON: +	case RIP_TRACEOFF: +		zlog_info( +			"Obsolete command %s received, please sent it to routed", +			lookup_msg(rip_msg, packet->command, NULL)); +		rip_peer_bad_packet(&from); +		break; +	case RIP_POLL_ENTRY: +		zlog_info("Obsolete command %s received", +			  lookup_msg(rip_msg, packet->command, NULL)); +		rip_peer_bad_packet(&from); +		break; +	default: +		zlog_info("Unknown RIP command %d received", packet->command); +		rip_peer_bad_packet(&from); +		break; +	} + +	return len;  }  /* Write routing table entry to the stream and return next index of     the routing table entry in the stream. */ -static int -rip_write_rte (int num, struct stream *s, struct prefix_ipv4 *p, -               u_char version, struct rip_info *rinfo) -{ -  struct in_addr mask; - -  /* Write routing table entry. */ -  if (version == RIPv1) -    { -      stream_putw (s, AF_INET); -      stream_putw (s, 0); -      stream_put_ipv4 (s, p->prefix.s_addr); -      stream_put_ipv4 (s, 0); -      stream_put_ipv4 (s, 0); -      stream_putl (s, rinfo->metric_out); -    } -  else -    { -      masklen2ip (p->prefixlen, &mask); - -      stream_putw (s, AF_INET); -      stream_putw (s, rinfo->tag_out); -      stream_put_ipv4 (s, p->prefix.s_addr); -      stream_put_ipv4 (s, mask.s_addr); -      stream_put_ipv4 (s, rinfo->nexthop_out.s_addr); -      stream_putl (s, rinfo->metric_out); -    } - -  return ++num; +static int rip_write_rte(int num, struct stream *s, struct prefix_ipv4 *p, +			 u_char version, struct rip_info *rinfo) +{ +	struct in_addr mask; + +	/* Write routing table entry. */ +	if (version == RIPv1) { +		stream_putw(s, AF_INET); +		stream_putw(s, 0); +		stream_put_ipv4(s, p->prefix.s_addr); +		stream_put_ipv4(s, 0); +		stream_put_ipv4(s, 0); +		stream_putl(s, rinfo->metric_out); +	} else { +		masklen2ip(p->prefixlen, &mask); + +		stream_putw(s, AF_INET); +		stream_putw(s, rinfo->tag_out); +		stream_put_ipv4(s, p->prefix.s_addr); +		stream_put_ipv4(s, mask.s_addr); +		stream_put_ipv4(s, rinfo->nexthop_out.s_addr); +		stream_putl(s, rinfo->metric_out); +	} + +	return ++num;  }  /* Send update to the ifp or spcified neighbor. */ -void -rip_output_process (struct connected *ifc, struct sockaddr_in *to,  -                    int route_type, u_char version) -{ -  int ret; -  struct stream *s; -  struct route_node *rp; -  struct rip_info *rinfo; -  struct rip_interface *ri; -  struct prefix_ipv4 *p; -  struct prefix_ipv4 classfull; -  struct prefix_ipv4 ifaddrclass; -  struct key *key = NULL; -  /* this might need to made dynamic if RIP ever supported auth methods -     with larger key string sizes */ -  char auth_str[RIP_AUTH_SIMPLE_SIZE]; -  size_t doff = 0; /* offset of digest offset field */ -  int num = 0; -  int rtemax; -  int subnetted = 0; -  struct list *list = NULL; -  struct listnode *listnode = NULL; +void rip_output_process(struct connected *ifc, struct sockaddr_in *to, +			int route_type, u_char version) +{ +	int ret; +	struct stream *s; +	struct route_node *rp; +	struct rip_info *rinfo; +	struct rip_interface *ri; +	struct prefix_ipv4 *p; +	struct prefix_ipv4 classfull; +	struct prefix_ipv4 ifaddrclass; +	struct key *key = NULL; +	/* this might need to made dynamic if RIP ever supported auth methods +	   with larger key string sizes */ +	char auth_str[RIP_AUTH_SIMPLE_SIZE]; +	size_t doff = 0; /* offset of digest offset field */ +	int num = 0; +	int rtemax; +	int subnetted = 0; +	struct list *list = NULL; +	struct listnode *listnode = NULL; + +	/* Logging output event. */ +	if (IS_RIP_DEBUG_EVENT) { +		if (to) +			zlog_debug("update routes to neighbor %s", +				   inet_ntoa(to->sin_addr)); +		else +			zlog_debug("update routes on interface %s ifindex %d", +				   ifc->ifp->name, ifc->ifp->ifindex); +	} -  /* Logging output event. */ -  if (IS_RIP_DEBUG_EVENT) -    { -      if (to) -	zlog_debug ("update routes to neighbor %s", inet_ntoa (to->sin_addr)); -      else -	zlog_debug ("update routes on interface %s ifindex %d", -		   ifc->ifp->name, ifc->ifp->ifindex); -    } - -  /* Set output stream. */ -  s = rip->obuf; - -  /* Reset stream and RTE counter. */ -  stream_reset (s); -  rtemax = RIP_MAX_RTE; - -  /* Get RIP interface. */ -  ri = ifc->ifp->info; -     -  /* If output interface is in simple password authentication mode, we -     need space for authentication data.  */ -  if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD) -    rtemax -= 1; - -  /* If output interface is in MD5 authentication mode, we need space -     for authentication header and data. */ -  if (ri->auth_type == RIP_AUTH_MD5) -    rtemax -= 2; - -  /* If output interface is in simple password authentication mode -     and string or keychain is specified we need space for auth. data */ -  if (ri->auth_type != RIP_NO_AUTH) -    { -      if (ri->key_chain) -       { -         struct keychain *keychain; - -         keychain = keychain_lookup (ri->key_chain); -         if (keychain) -           key = key_lookup_for_send (keychain); -       } -      /* to be passed to auth functions later */ -      rip_auth_prepare_str_send (ri, key, auth_str, RIP_AUTH_SIMPLE_SIZE); -    } - -  if (version == RIPv1) -    { -      memcpy (&ifaddrclass, ifc->address, sizeof (struct prefix_ipv4)); -      apply_classful_mask_ipv4 (&ifaddrclass); -      subnetted = 0; -      if (ifc->address->prefixlen > ifaddrclass.prefixlen) -        subnetted = 1; -    } - -  for (rp = route_top (rip->table); rp; rp = route_next (rp)) -    if ((list = rp->info) != NULL && listcount (list) != 0) -      { -        rinfo = listgetdata (listhead (list)); -	/* For RIPv1, if we are subnetted, output subnets in our network    */ -	/* that have the same mask as the output "interface". For other     */ -	/* networks, only the classfull version is output.                  */ -	 -	if (version == RIPv1) -	  { -	    p = (struct prefix_ipv4 *) &rp->p; - -	    if (IS_RIP_DEBUG_PACKET) -	      zlog_debug("RIPv1 mask check, %s/%d considered for output", -			inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen); - -	    if (subnetted && -		prefix_match ((struct prefix *) &ifaddrclass, &rp->p)) -	      { -		if ((ifc->address->prefixlen != rp->p.prefixlen) && -		    (rp->p.prefixlen != 32)) -		  continue; -	      } -	    else -	      { -		memcpy (&classfull, &rp->p, sizeof(struct prefix_ipv4)); -		apply_classful_mask_ipv4(&classfull); -		if (rp->p.u.prefix4.s_addr != 0 && -		    classfull.prefixlen != rp->p.prefixlen) -		  continue; -	      } -	    if (IS_RIP_DEBUG_PACKET) -	      zlog_debug("RIPv1 mask check, %s/%d made it through", -			inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen); -	  } -	else  -	  p = (struct prefix_ipv4 *) &rp->p; - -	/* Apply output filters. */ -	ret = rip_filter (RIP_FILTER_OUT, p, ri); -	if (ret < 0) -	  continue; - -	/* Changed route only output. */ -	if (route_type == rip_changed_route && -	    (! (rinfo->flags & RIP_RTF_CHANGED))) -	  continue; - -	/* Split horizon. */ -	/* if (split_horizon == rip_split_horizon) */ -	if (ri->split_horizon == RIP_SPLIT_HORIZON) -	  { -	    /*  -	     * We perform split horizon for RIP and connected route.  -	     * For rip routes, we want to suppress the route if we would -             * end up sending the route back on the interface that we -             * learned it from, with a higher metric. For connected routes, -             * we suppress the route if the prefix is a subset of the -             * source address that we are going to use for the packet  -             * (in order to handle the case when multiple subnets are -             * configured on the same interface). -             */ -	    int suppress = 0; -	    struct rip_info *tmp_rinfo = NULL; - -	    for (ALL_LIST_ELEMENTS_RO (list, listnode, tmp_rinfo)) -	      if (tmp_rinfo->type == ZEBRA_ROUTE_RIP && -	          tmp_rinfo->ifindex == ifc->ifp->ifindex) -	        { -	          suppress = 1; -	          break; -	        } - -	    if (!suppress && rinfo->type == ZEBRA_ROUTE_CONNECT && -                 prefix_match((struct prefix *)p, ifc->address)) -	      suppress = 1; - -	    if (suppress) -	      continue; -	  } - -	/* Preparation for route-map. */ -	rinfo->metric_set = 0; -	rinfo->nexthop_out.s_addr = 0; -	rinfo->metric_out = rinfo->metric; -	rinfo->tag_out = rinfo->tag; -	rinfo->ifindex_out = ifc->ifp->ifindex; - -	/* In order to avoid some local loops, -	 * if the RIP route has a nexthop via this interface, keep the nexthop, -	 * otherwise set it to 0. The nexthop should not be propagated -	 * beyond the local broadcast/multicast area in order -	 * to avoid an IGP multi-level recursive look-up. -	 * see (4.4) -	 */ -	if (rinfo->ifindex == ifc->ifp->ifindex) -	  rinfo->nexthop_out = rinfo->nexthop; - -	/* Interface route-map */ -	if (ri->routemap[RIP_FILTER_OUT]) -	  { -	    ret = route_map_apply (ri->routemap[RIP_FILTER_OUT],  -				     (struct prefix *) p, RMAP_RIP,  -				     rinfo); - -	    if (ret == RMAP_DENYMATCH) -	      { -	        if (IS_RIP_DEBUG_PACKET) -	          zlog_debug ("RIP %s/%d is filtered by route-map out", -                              inet_ntoa (p->prefix), p->prefixlen); -                continue; -	      } -	  } -            -	/* Apply redistribute route map - continue, if deny */ -	if (rip->route_map[rinfo->type].name -	    && rinfo->sub_type != RIP_ROUTE_INTERFACE) -	  { -	    ret = route_map_apply (rip->route_map[rinfo->type].map, -				   (struct prefix *)p, RMAP_RIP, rinfo); - -	    if (ret == RMAP_DENYMATCH)  -	      { -		if (IS_RIP_DEBUG_PACKET) -		  zlog_debug ("%s/%d is filtered by route-map", -			     inet_ntoa (p->prefix), p->prefixlen); -		continue; -	      } -	  } - -	/* When route-map does not set metric. */ -	if (! rinfo->metric_set) -	  { -	    /* If redistribute metric is set. */ -	    if (rip->route_map[rinfo->type].metric_config -		&& rinfo->metric != RIP_METRIC_INFINITY) -	      { -		rinfo->metric_out = rip->route_map[rinfo->type].metric; -	      } -	    else -	      { -		/* If the route is not connected or localy generated -		   one, use default-metric value*/ -		if (rinfo->type != ZEBRA_ROUTE_RIP  -		    && rinfo->type != ZEBRA_ROUTE_CONNECT -		    && rinfo->metric != RIP_METRIC_INFINITY) -		  rinfo->metric_out = rip->default_metric; -	      } -	  } - -	/* Apply offset-list */ -	if (rinfo->metric != RIP_METRIC_INFINITY) -	  rip_offset_list_apply_out (p, ifc->ifp, &rinfo->metric_out); - -	if (rinfo->metric_out > RIP_METRIC_INFINITY) -	  rinfo->metric_out = RIP_METRIC_INFINITY; - -	/* Perform split-horizon with poisoned reverse  -	 * for RIP and connected routes. -	 **/ -	if (ri->split_horizon == RIP_SPLIT_HORIZON_POISONED_REVERSE) { -	    /*  -	     * We perform split horizon for RIP and connected route.  -	     * For rip routes, we want to suppress the route if we would -             * end up sending the route back on the interface that we -             * learned it from, with a higher metric. For connected routes, -             * we suppress the route if the prefix is a subset of the -             * source address that we are going to use for the packet  -             * (in order to handle the case when multiple subnets are -             * configured on the same interface). -             */ -	  struct rip_info *tmp_rinfo = NULL; - -	  for (ALL_LIST_ELEMENTS_RO (list, listnode, tmp_rinfo)) -	    if (tmp_rinfo->type == ZEBRA_ROUTE_RIP  && -	        tmp_rinfo->ifindex == ifc->ifp->ifindex) -	      rinfo->metric_out = RIP_METRIC_INFINITY; -	  if (tmp_rinfo->type == ZEBRA_ROUTE_CONNECT && -              prefix_match((struct prefix *)p, ifc->address)) -	    rinfo->metric_out = RIP_METRIC_INFINITY; -	} -	 -	/* Prepare preamble, auth headers, if needs be */ -	if (num == 0) -	  { -	    stream_putc (s, RIP_RESPONSE); -	    stream_putc (s, version); -	    stream_putw (s, 0); -	     -	    /* auth header for !v1 && !no_auth */ -            if ( (ri->auth_type != RIP_NO_AUTH) && (version != RIPv1) ) -              doff = rip_auth_header_write (s, ri, key, auth_str,  -                                              RIP_AUTH_SIMPLE_SIZE); -          } -         -	/* Write RTE to the stream. */ -	num = rip_write_rte (num, s, p, version, rinfo); -	if (num == rtemax) -	  { -	    if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5) -              rip_auth_md5_set (s, ri, doff, auth_str, RIP_AUTH_SIMPLE_SIZE); - -	    ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), -				   to, ifc); - -	    if (ret >= 0 && IS_RIP_DEBUG_SEND) -	      rip_packet_dump ((struct rip_packet *)STREAM_DATA (s), -			       stream_get_endp(s), "SEND"); -	    num = 0; -	    stream_reset (s); -	  } -      } - -  /* Flush unwritten RTE. */ -  if (num != 0) -    { -      if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5) -        rip_auth_md5_set (s, ri, doff, auth_str, RIP_AUTH_SIMPLE_SIZE); - -      ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), to, ifc); - -      if (ret >= 0 && IS_RIP_DEBUG_SEND) -	rip_packet_dump ((struct rip_packet *)STREAM_DATA (s), -			 stream_get_endp (s), "SEND"); -      stream_reset (s); -    } - -  /* Statistics updates. */ -  ri->sent_updates++; +	/* Set output stream. */ +	s = rip->obuf; + +	/* Reset stream and RTE counter. */ +	stream_reset(s); +	rtemax = RIP_MAX_RTE; + +	/* Get RIP interface. */ +	ri = ifc->ifp->info; + +	/* If output interface is in simple password authentication mode, we +	   need space for authentication data.  */ +	if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD) +		rtemax -= 1; + +	/* If output interface is in MD5 authentication mode, we need space +	   for authentication header and data. */ +	if (ri->auth_type == RIP_AUTH_MD5) +		rtemax -= 2; + +	/* If output interface is in simple password authentication mode +	   and string or keychain is specified we need space for auth. data */ +	if (ri->auth_type != RIP_NO_AUTH) { +		if (ri->key_chain) { +			struct keychain *keychain; + +			keychain = keychain_lookup(ri->key_chain); +			if (keychain) +				key = key_lookup_for_send(keychain); +		} +		/* to be passed to auth functions later */ +		rip_auth_prepare_str_send(ri, key, auth_str, +					  RIP_AUTH_SIMPLE_SIZE); +	} + +	if (version == RIPv1) { +		memcpy(&ifaddrclass, ifc->address, sizeof(struct prefix_ipv4)); +		apply_classful_mask_ipv4(&ifaddrclass); +		subnetted = 0; +		if (ifc->address->prefixlen > ifaddrclass.prefixlen) +			subnetted = 1; +	} + +	for (rp = route_top(rip->table); rp; rp = route_next(rp)) +		if ((list = rp->info) != NULL && listcount(list) != 0) { +			rinfo = listgetdata(listhead(list)); +			/* For RIPv1, if we are subnetted, output subnets in our +			 * network    */ +			/* that have the same mask as the output "interface". +			 * For other     */ +			/* networks, only the classfull version is output. */ + +			if (version == RIPv1) { +				p = (struct prefix_ipv4 *)&rp->p; + +				if (IS_RIP_DEBUG_PACKET) +					zlog_debug( +						"RIPv1 mask check, %s/%d considered for output", +						inet_ntoa(rp->p.u.prefix4), +						rp->p.prefixlen); + +				if (subnetted +				    && prefix_match( +					       (struct prefix *)&ifaddrclass, +					       &rp->p)) { +					if ((ifc->address->prefixlen +					     != rp->p.prefixlen) +					    && (rp->p.prefixlen != 32)) +						continue; +				} else { +					memcpy(&classfull, &rp->p, +					       sizeof(struct prefix_ipv4)); +					apply_classful_mask_ipv4(&classfull); +					if (rp->p.u.prefix4.s_addr != 0 +					    && classfull.prefixlen +						       != rp->p.prefixlen) +						continue; +				} +				if (IS_RIP_DEBUG_PACKET) +					zlog_debug( +						"RIPv1 mask check, %s/%d made it through", +						inet_ntoa(rp->p.u.prefix4), +						rp->p.prefixlen); +			} else +				p = (struct prefix_ipv4 *)&rp->p; + +			/* Apply output filters. */ +			ret = rip_filter(RIP_FILTER_OUT, p, ri); +			if (ret < 0) +				continue; + +			/* Changed route only output. */ +			if (route_type == rip_changed_route +			    && (!(rinfo->flags & RIP_RTF_CHANGED))) +				continue; + +			/* Split horizon. */ +			/* if (split_horizon == rip_split_horizon) */ +			if (ri->split_horizon == RIP_SPLIT_HORIZON) { +				/* +				 * We perform split horizon for RIP and +				 * connected route. +				 * For rip routes, we want to suppress the route +				 * if we would +				 * end up sending the route back on the +				 * interface that we +				 * learned it from, with a higher metric. For +				 * connected routes, +				 * we suppress the route if the prefix is a +				 * subset of the +				 * source address that we are going to use for +				 * the packet +				 * (in order to handle the case when multiple +				 * subnets are +				 * configured on the same interface). +				 */ +				int suppress = 0; +				struct rip_info *tmp_rinfo = NULL; + +				for (ALL_LIST_ELEMENTS_RO(list, listnode, +							  tmp_rinfo)) +					if (tmp_rinfo->type == ZEBRA_ROUTE_RIP +					    && tmp_rinfo->ifindex +						       == ifc->ifp->ifindex) { +						suppress = 1; +						break; +					} + +				if (!suppress +				    && rinfo->type == ZEBRA_ROUTE_CONNECT +				    && prefix_match((struct prefix *)p, +						    ifc->address)) +					suppress = 1; + +				if (suppress) +					continue; +			} + +			/* Preparation for route-map. */ +			rinfo->metric_set = 0; +			rinfo->nexthop_out.s_addr = 0; +			rinfo->metric_out = rinfo->metric; +			rinfo->tag_out = rinfo->tag; +			rinfo->ifindex_out = ifc->ifp->ifindex; + +			/* In order to avoid some local loops, +			 * if the RIP route has a nexthop via this interface, +			 * keep the nexthop, +			 * otherwise set it to 0. The nexthop should not be +			 * propagated +			 * beyond the local broadcast/multicast area in order +			 * to avoid an IGP multi-level recursive look-up. +			 * see (4.4) +			 */ +			if (rinfo->ifindex == ifc->ifp->ifindex) +				rinfo->nexthop_out = rinfo->nexthop; + +			/* Interface route-map */ +			if (ri->routemap[RIP_FILTER_OUT]) { +				ret = route_map_apply( +					ri->routemap[RIP_FILTER_OUT], +					(struct prefix *)p, RMAP_RIP, rinfo); + +				if (ret == RMAP_DENYMATCH) { +					if (IS_RIP_DEBUG_PACKET) +						zlog_debug( +							"RIP %s/%d is filtered by route-map out", +							inet_ntoa(p->prefix), +							p->prefixlen); +					continue; +				} +			} + +			/* Apply redistribute route map - continue, if deny */ +			if (rip->route_map[rinfo->type].name +			    && rinfo->sub_type != RIP_ROUTE_INTERFACE) { +				ret = route_map_apply( +					rip->route_map[rinfo->type].map, +					(struct prefix *)p, RMAP_RIP, rinfo); + +				if (ret == RMAP_DENYMATCH) { +					if (IS_RIP_DEBUG_PACKET) +						zlog_debug( +							"%s/%d is filtered by route-map", +							inet_ntoa(p->prefix), +							p->prefixlen); +					continue; +				} +			} + +			/* When route-map does not set metric. */ +			if (!rinfo->metric_set) { +				/* If redistribute metric is set. */ +				if (rip->route_map[rinfo->type].metric_config +				    && rinfo->metric != RIP_METRIC_INFINITY) { +					rinfo->metric_out = +						rip->route_map[rinfo->type] +							.metric; +				} else { +					/* If the route is not connected or +					   localy generated +					   one, use default-metric value*/ +					if (rinfo->type != ZEBRA_ROUTE_RIP +					    && rinfo->type +						       != ZEBRA_ROUTE_CONNECT +					    && rinfo->metric +						       != RIP_METRIC_INFINITY) +						rinfo->metric_out = +							rip->default_metric; +				} +			} + +			/* Apply offset-list */ +			if (rinfo->metric != RIP_METRIC_INFINITY) +				rip_offset_list_apply_out(p, ifc->ifp, +							  &rinfo->metric_out); + +			if (rinfo->metric_out > RIP_METRIC_INFINITY) +				rinfo->metric_out = RIP_METRIC_INFINITY; + +			/* Perform split-horizon with poisoned reverse +			 * for RIP and connected routes. +			 **/ +			if (ri->split_horizon +			    == RIP_SPLIT_HORIZON_POISONED_REVERSE) { +				/* +				 * We perform split horizon for RIP and +				 * connected route. +				 * For rip routes, we want to suppress the route +				 * if we would +				 * end up sending the route back on the +				 * interface that we +				 * learned it from, with a higher metric. For +				 * connected routes, +				 * we suppress the route if the prefix is a +				 * subset of the +				 * source address that we are going to use for +				 * the packet +				 * (in order to handle the case when multiple +				 * subnets are +				 * configured on the same interface). +				 */ +				struct rip_info *tmp_rinfo = NULL; + +				for (ALL_LIST_ELEMENTS_RO(list, listnode, +							  tmp_rinfo)) +					if (tmp_rinfo->type == ZEBRA_ROUTE_RIP +					    && tmp_rinfo->ifindex +						       == ifc->ifp->ifindex) +						rinfo->metric_out = +							RIP_METRIC_INFINITY; +				if (tmp_rinfo->type == ZEBRA_ROUTE_CONNECT +				    && prefix_match((struct prefix *)p, +						    ifc->address)) +					rinfo->metric_out = RIP_METRIC_INFINITY; +			} + +			/* Prepare preamble, auth headers, if needs be */ +			if (num == 0) { +				stream_putc(s, RIP_RESPONSE); +				stream_putc(s, version); +				stream_putw(s, 0); + +				/* auth header for !v1 && !no_auth */ +				if ((ri->auth_type != RIP_NO_AUTH) +				    && (version != RIPv1)) +					doff = rip_auth_header_write( +						s, ri, key, auth_str, +						RIP_AUTH_SIMPLE_SIZE); +			} + +			/* Write RTE to the stream. */ +			num = rip_write_rte(num, s, p, version, rinfo); +			if (num == rtemax) { +				if (version == RIPv2 +				    && ri->auth_type == RIP_AUTH_MD5) +					rip_auth_md5_set(s, ri, doff, auth_str, +							 RIP_AUTH_SIMPLE_SIZE); + +				ret = rip_send_packet(STREAM_DATA(s), +						      stream_get_endp(s), to, +						      ifc); + +				if (ret >= 0 && IS_RIP_DEBUG_SEND) +					rip_packet_dump((struct rip_packet *) +								STREAM_DATA(s), +							stream_get_endp(s), +							"SEND"); +				num = 0; +				stream_reset(s); +			} +		} + +	/* Flush unwritten RTE. */ +	if (num != 0) { +		if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5) +			rip_auth_md5_set(s, ri, doff, auth_str, +					 RIP_AUTH_SIMPLE_SIZE); + +		ret = rip_send_packet(STREAM_DATA(s), stream_get_endp(s), to, +				      ifc); + +		if (ret >= 0 && IS_RIP_DEBUG_SEND) +			rip_packet_dump((struct rip_packet *)STREAM_DATA(s), +					stream_get_endp(s), "SEND"); +		stream_reset(s); +	} + +	/* Statistics updates. */ +	ri->sent_updates++;  }  /* Send RIP packet to the interface. */ -static void -rip_update_interface (struct connected *ifc, u_char version, int route_type) -{ -  struct interface *ifp = ifc->ifp; -  struct rip_interface *ri = ifp->info; -  struct sockaddr_in to; - -  /* When RIP version is 2 and multicast enable interface. */ -  if (version == RIPv2 && !ri->v2_broadcast && if_is_multicast (ifp)) -    { -      if (IS_RIP_DEBUG_EVENT) -	zlog_debug ("multicast announce on %s ", ifp->name); - -      rip_output_process (ifc, NULL, route_type, version); -      return; -    } -   -  /* If we can't send multicast packet, send it with unicast. */ -  if (if_is_broadcast (ifp) || if_is_pointopoint (ifp)) -    { -      if (ifc->address->family == AF_INET) -        { -          /* Destination address and port setting. */ -          memset (&to, 0, sizeof (struct sockaddr_in)); -          if (ifc->destination) -            /* use specified broadcast or peer destination addr */ -            to.sin_addr = ifc->destination->u.prefix4; -          else if (ifc->address->prefixlen < IPV4_MAX_PREFIXLEN) -            /* calculate the appropriate broadcast address */ -            to.sin_addr.s_addr = -              ipv4_broadcast_addr(ifc->address->u.prefix4.s_addr, -                                  ifc->address->prefixlen); -	  else -	    /* do not know where to send the packet */ -	    return; -          to.sin_port = htons (RIP_PORT_DEFAULT); - -          if (IS_RIP_DEBUG_EVENT) -            zlog_debug("%s announce to %s on %s", -		       CONNECTED_PEER(ifc) ? "unicast" : "broadcast", -		       inet_ntoa (to.sin_addr), ifp->name); - -          rip_output_process (ifc, &to, route_type, version); -        } -    } +static void rip_update_interface(struct connected *ifc, u_char version, +				 int route_type) +{ +	struct interface *ifp = ifc->ifp; +	struct rip_interface *ri = ifp->info; +	struct sockaddr_in to; + +	/* When RIP version is 2 and multicast enable interface. */ +	if (version == RIPv2 && !ri->v2_broadcast && if_is_multicast(ifp)) { +		if (IS_RIP_DEBUG_EVENT) +			zlog_debug("multicast announce on %s ", ifp->name); + +		rip_output_process(ifc, NULL, route_type, version); +		return; +	} + +	/* If we can't send multicast packet, send it with unicast. */ +	if (if_is_broadcast(ifp) || if_is_pointopoint(ifp)) { +		if (ifc->address->family == AF_INET) { +			/* Destination address and port setting. */ +			memset(&to, 0, sizeof(struct sockaddr_in)); +			if (ifc->destination) +				/* use specified broadcast or peer destination +				 * addr */ +				to.sin_addr = ifc->destination->u.prefix4; +			else if (ifc->address->prefixlen < IPV4_MAX_PREFIXLEN) +				/* calculate the appropriate broadcast address +				 */ +				to.sin_addr.s_addr = ipv4_broadcast_addr( +					ifc->address->u.prefix4.s_addr, +					ifc->address->prefixlen); +			else +				/* do not know where to send the packet */ +				return; +			to.sin_port = htons(RIP_PORT_DEFAULT); + +			if (IS_RIP_DEBUG_EVENT) +				zlog_debug("%s announce to %s on %s", +					   CONNECTED_PEER(ifc) ? "unicast" +							       : "broadcast", +					   inet_ntoa(to.sin_addr), ifp->name); + +			rip_output_process(ifc, &to, route_type, version); +		} +	}  }  /* Update send to all interface and neighbor. */ -static void -rip_update_process (int route_type) -{ -  struct listnode *node; -  struct listnode *ifnode, *ifnnode; -  struct connected *connected; -  struct interface *ifp; -  struct rip_interface *ri; -  struct route_node *rp; -  struct sockaddr_in to; -  struct prefix *p; - -  /* Send RIP update to each interface. */ -  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) -    { -      if (if_is_loopback (ifp)) -	continue; - -      if (! if_is_operative (ifp)) -	continue; - -      /* Fetch RIP interface information. */ -      ri = ifp->info; - -      /* When passive interface is specified, suppress announce to the -         interface. */ -      if (ri->passive) -	continue; - -      if (ri->running) -	{ -	  /*  -	   * If there is no version configuration in the interface, -	   * use rip's version setting.  -	   */ -	  int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? -		       rip->version_send : ri->ri_send); - -	  if (IS_RIP_DEBUG_EVENT)  -	    zlog_debug("SEND UPDATE to %s ifindex %d", -		       ifp->name, ifp->ifindex); - -          /* send update on each connected network */ -	  for (ALL_LIST_ELEMENTS (ifp->connected, ifnode, ifnnode, connected)) -	    { -	      if (connected->address->family == AF_INET) -	        { -		  if (vsend & RIPv1) -		    rip_update_interface (connected, RIPv1, route_type); -		  if ((vsend & RIPv2) && if_is_multicast(ifp)) -		    rip_update_interface (connected, RIPv2, route_type); +static void rip_update_process(int route_type) +{ +	struct listnode *node; +	struct listnode *ifnode, *ifnnode; +	struct connected *connected; +	struct interface *ifp; +	struct rip_interface *ri; +	struct route_node *rp; +	struct sockaddr_in to; +	struct prefix *p; + +	/* Send RIP update to each interface. */ +	for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { +		if (if_is_loopback(ifp)) +			continue; + +		if (!if_is_operative(ifp)) +			continue; + +		/* Fetch RIP interface information. */ +		ri = ifp->info; + +		/* When passive interface is specified, suppress announce to the +		   interface. */ +		if (ri->passive) +			continue; + +		if (ri->running) { +			/* +			 * If there is no version configuration in the +			 * interface, +			 * use rip's version setting. +			 */ +			int vsend = ((ri->ri_send == RI_RIP_UNSPEC) +					     ? rip->version_send +					     : ri->ri_send); + +			if (IS_RIP_DEBUG_EVENT) +				zlog_debug("SEND UPDATE to %s ifindex %d", +					   ifp->name, ifp->ifindex); + +			/* send update on each connected network */ +			for (ALL_LIST_ELEMENTS(ifp->connected, ifnode, ifnnode, +					       connected)) { +				if (connected->address->family == AF_INET) { +					if (vsend & RIPv1) +						rip_update_interface( +							connected, RIPv1, +							route_type); +					if ((vsend & RIPv2) +					    && if_is_multicast(ifp)) +						rip_update_interface( +							connected, RIPv2, +							route_type); +				} +			} +		} +	} + +	/* RIP send updates to each neighbor. */ +	for (rp = route_top(rip->neighbor); rp; rp = route_next(rp)) +		if (rp->info != NULL) { +			p = &rp->p; + +			connected = if_lookup_address(&p->u.prefix4, AF_INET, +						      VRF_DEFAULT); +			if (!connected) { +				zlog_warn( +					"Neighbor %s doesnt have connected interface!", +					inet_ntoa(p->u.prefix4)); +				continue; +			} + +			/* Set destination address and port */ +			memset(&to, 0, sizeof(struct sockaddr_in)); +			to.sin_addr = p->u.prefix4; +			to.sin_port = htons(RIP_PORT_DEFAULT); + +			/* RIP version is rip's configuration. */ +			rip_output_process(connected, &to, route_type, +					   rip->version_send);  		} -	    } -	} -    } - -  /* RIP send updates to each neighbor. */ -  for (rp = route_top (rip->neighbor); rp; rp = route_next (rp)) -    if (rp->info != NULL) -      { -	p = &rp->p; - -	connected = if_lookup_address (&p->u.prefix4, AF_INET, VRF_DEFAULT); -	if (! connected) -	  { -	    zlog_warn ("Neighbor %s doesnt have connected interface!", -		       inet_ntoa (p->u.prefix4)); -	    continue; -	  } -         -	/* Set destination address and port */ -	memset (&to, 0, sizeof (struct sockaddr_in)); -	to.sin_addr = p->u.prefix4; -	to.sin_port = htons (RIP_PORT_DEFAULT); - -	/* RIP version is rip's configuration. */ -	rip_output_process (connected, &to, route_type, rip->version_send); -      }  }  /* RIP's periodical timer. */ -static int -rip_update (struct thread *t) +static int rip_update(struct thread *t)  { -  /* Clear timer pointer. */ -  rip->t_update = NULL; +	/* Clear timer pointer. */ +	rip->t_update = NULL; -  if (IS_RIP_DEBUG_EVENT) -    zlog_debug ("update timer fire!"); +	if (IS_RIP_DEBUG_EVENT) +		zlog_debug("update timer fire!"); -  /* Process update output. */ -  rip_update_process (rip_all_route); +	/* Process update output. */ +	rip_update_process(rip_all_route); -  /* Triggered updates may be suppressed if a regular update is due by -     the time the triggered update would be sent. */ -  RIP_TIMER_OFF (rip->t_triggered_interval); -  rip->trigger = 0; +	/* Triggered updates may be suppressed if a regular update is due by +	   the time the triggered update would be sent. */ +	RIP_TIMER_OFF(rip->t_triggered_interval); +	rip->trigger = 0; -  /* Register myself. */ -  rip_event (RIP_UPDATE_EVENT, 0); +	/* Register myself. */ +	rip_event(RIP_UPDATE_EVENT, 0); -  return 0; +	return 0;  }  /* Walk down the RIP routing table then clear changed flag. */ -static void -rip_clear_changed_flag (void) +static void rip_clear_changed_flag(void)  { -  struct route_node *rp; -  struct rip_info *rinfo = NULL; -  struct list *list = NULL; -  struct listnode *listnode = NULL; +	struct route_node *rp; +	struct rip_info *rinfo = NULL; +	struct list *list = NULL; +	struct listnode *listnode = NULL; -  for (rp = route_top (rip->table); rp; rp = route_next (rp)) -    if ((list = rp->info) != NULL) -      for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo)) -        { -          UNSET_FLAG (rinfo->flags, RIP_RTF_CHANGED); -          /* This flag can be set only on the first entry. */ -          break; -        } +	for (rp = route_top(rip->table); rp; rp = route_next(rp)) +		if ((list = rp->info) != NULL) +			for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { +				UNSET_FLAG(rinfo->flags, RIP_RTF_CHANGED); +				/* This flag can be set only on the first entry. +				 */ +				break; +			}  }  /* Triggered update interval timer. */ -static int -rip_triggered_interval (struct thread *t) +static int rip_triggered_interval(struct thread *t)  { -  int rip_triggered_update (struct thread *); +	int rip_triggered_update(struct thread *); -  rip->t_triggered_interval = NULL; +	rip->t_triggered_interval = NULL; -  if (rip->trigger) -    { -      rip->trigger = 0; -      rip_triggered_update (t); -    } -  return 0; -}      +	if (rip->trigger) { +		rip->trigger = 0; +		rip_triggered_update(t); +	} +	return 0; +}  /* Execute triggered update. */ -static int -rip_triggered_update (struct thread *t) +static int rip_triggered_update(struct thread *t)  { -  int interval; +	int interval; -  /* Clear thred pointer. */ -  rip->t_triggered_update = NULL; +	/* Clear thred pointer. */ +	rip->t_triggered_update = NULL; -  /* Cancel interval timer. */ -  RIP_TIMER_OFF (rip->t_triggered_interval); -  rip->trigger = 0; +	/* Cancel interval timer. */ +	RIP_TIMER_OFF(rip->t_triggered_interval); +	rip->trigger = 0; -  /* Logging triggered update. */ -  if (IS_RIP_DEBUG_EVENT) -    zlog_debug ("triggered update!"); +	/* Logging triggered update. */ +	if (IS_RIP_DEBUG_EVENT) +		zlog_debug("triggered update!"); -  /* Split Horizon processing is done when generating triggered -     updates as well as normal updates (see section 2.6). */ -  rip_update_process (rip_changed_route); +	/* Split Horizon processing is done when generating triggered +	   updates as well as normal updates (see section 2.6). */ +	rip_update_process(rip_changed_route); -  /* Once all of the triggered updates have been generated, the route -     change flags should be cleared. */ -  rip_clear_changed_flag (); +	/* Once all of the triggered updates have been generated, the route +	   change flags should be cleared. */ +	rip_clear_changed_flag(); -  /* After a triggered update is sent, a timer should be set for a -   random interval between 1 and 5 seconds.  If other changes that -   would trigger updates occur before the timer expires, a single -   update is triggered when the timer expires. */ -  interval = (random () % 5) + 1; +	/* After a triggered update is sent, a timer should be set for a +	 random interval between 1 and 5 seconds.  If other changes that +	 would trigger updates occur before the timer expires, a single +	 update is triggered when the timer expires. */ +	interval = (random() % 5) + 1; -  rip->t_triggered_interval = NULL; -  thread_add_timer(master, rip_triggered_interval, NULL, interval, -                   &rip->t_triggered_interval); +	rip->t_triggered_interval = NULL; +	thread_add_timer(master, rip_triggered_interval, NULL, interval, +			 &rip->t_triggered_interval); -  return 0; +	return 0;  }  /* Withdraw redistributed route. */ -void -rip_redistribute_withdraw (int type) +void rip_redistribute_withdraw(int type) +{ +	struct route_node *rp; +	struct rip_info *rinfo = NULL; +	struct list *list = NULL; + +	if (!rip) +		return; + +	for (rp = route_top(rip->table); rp; rp = route_next(rp)) +		if ((list = rp->info) != NULL) { +			rinfo = listgetdata(listhead(list)); +			if (rinfo->type == type +			    && rinfo->sub_type != RIP_ROUTE_INTERFACE) { +				/* Perform poisoned reverse. */ +				rinfo->metric = RIP_METRIC_INFINITY; +				RIP_TIMER_ON(rinfo->t_garbage_collect, +					     rip_garbage_collect, +					     rip->garbage_time); +				RIP_TIMER_OFF(rinfo->t_timeout); +				rinfo->flags |= RIP_RTF_CHANGED; + +				if (IS_RIP_DEBUG_EVENT) { +					struct prefix_ipv4 *p = +						(struct prefix_ipv4 *)&rp->p; + +					zlog_debug( +						"Poisone %s/%d on the interface %s with an infinity metric [withdraw]", +						inet_ntoa(p->prefix), +						p->prefixlen, +						ifindex2ifname(rinfo->ifindex, +							       VRF_DEFAULT)); +				} + +				rip_event(RIP_TRIGGERED_UPDATE, 0); +			} +		} +} + +/* Create new RIP instance and set it to global variable. */ +static int rip_create(void)  { -  struct route_node *rp; -  struct rip_info *rinfo = NULL; -  struct list *list = NULL; +	rip = XCALLOC(MTYPE_RIP, sizeof(struct rip)); -  if (!rip) -    return; +	/* Set initial value. */ +	rip->version_send = RI_RIP_VERSION_2; +	rip->version_recv = RI_RIP_VERSION_1_AND_2; +	rip->update_time = RIP_UPDATE_TIMER_DEFAULT; +	rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT; +	rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT; +	rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT; -  for (rp = route_top (rip->table); rp; rp = route_next (rp)) -    if ((list = rp->info) != NULL) -      { -	rinfo = listgetdata (listhead (list)); -	if (rinfo->type == type -	    && rinfo->sub_type != RIP_ROUTE_INTERFACE) -	  { -	    /* Perform poisoned reverse. */ -	    rinfo->metric = RIP_METRIC_INFINITY; -	    RIP_TIMER_ON (rinfo->t_garbage_collect,  -			  rip_garbage_collect, rip->garbage_time); -	    RIP_TIMER_OFF (rinfo->t_timeout); -	    rinfo->flags |= RIP_RTF_CHANGED; +	/* Initialize RIP routig table. */ +	rip->table = route_table_init(); +	rip->route = route_table_init(); +	rip->neighbor = route_table_init(); -	    if (IS_RIP_DEBUG_EVENT) { -              struct prefix_ipv4 *p = (struct prefix_ipv4 *) &rp->p; +	/* Make output stream. */ +	rip->obuf = stream_new(1500); -              zlog_debug ("Poisone %s/%d on the interface %s with an infinity metric [withdraw]", -                          inet_ntoa(p->prefix), p->prefixlen, -                          ifindex2ifname(rinfo->ifindex, VRF_DEFAULT)); -	    } +	/* Make socket. */ +	rip->sock = rip_create_socket(); +	if (rip->sock < 0) +		return rip->sock; -	    rip_event (RIP_TRIGGERED_UPDATE, 0); -	  } -      } -} +	/* Create read and timer thread. */ +	rip_event(RIP_READ, rip->sock); +	rip_event(RIP_UPDATE_EVENT, 1); -/* Create new RIP instance and set it to global variable. */ -static int -rip_create (void) -{ -  rip = XCALLOC (MTYPE_RIP, sizeof (struct rip)); +	QOBJ_REG(rip, rip); -  /* Set initial value. */ -  rip->version_send = RI_RIP_VERSION_2; -  rip->version_recv = RI_RIP_VERSION_1_AND_2; -  rip->update_time = RIP_UPDATE_TIMER_DEFAULT; -  rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT; -  rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT; -  rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT; - -  /* Initialize RIP routig table. */ -  rip->table = route_table_init (); -  rip->route = route_table_init (); -  rip->neighbor = route_table_init (); +	return 0; +} -  /* Make output stream. */ -  rip->obuf = stream_new (1500); +/* Sned RIP request to the destination. */ +int rip_request_send(struct sockaddr_in *to, struct interface *ifp, +		     u_char version, struct connected *connected) +{ +	struct rte *rte; +	struct rip_packet rip_packet; +	struct listnode *node, *nnode; + +	memset(&rip_packet, 0, sizeof(rip_packet)); + +	rip_packet.command = RIP_REQUEST; +	rip_packet.version = version; +	rte = rip_packet.rte; +	rte->metric = htonl(RIP_METRIC_INFINITY); + +	if (connected) { +		/* +		 * connected is only sent for ripv1 case, or when +		 * interface does not support multicast.  Caller loops +		 * over each connected address for this case. +		 */ +		if (rip_send_packet((u_char *)&rip_packet, sizeof(rip_packet), +				    to, connected) +		    != sizeof(rip_packet)) +			return -1; +		else +			return sizeof(rip_packet); +	} -  /* Make socket. */ -  rip->sock = rip_create_socket (); -  if (rip->sock < 0) -    return rip->sock; +	/* send request on each connected network */ +	for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, connected)) { +		struct prefix_ipv4 *p; -  /* Create read and timer thread. */ -  rip_event (RIP_READ, rip->sock); -  rip_event (RIP_UPDATE_EVENT, 1); +		p = (struct prefix_ipv4 *)connected->address; -  QOBJ_REG (rip, rip); +		if (p->family != AF_INET) +			continue; -  return 0; +		if (rip_send_packet((u_char *)&rip_packet, sizeof(rip_packet), +				    to, connected) +		    != sizeof(rip_packet)) +			return -1; +	} +	return sizeof(rip_packet);  } -/* Sned RIP request to the destination. */ -int -rip_request_send (struct sockaddr_in *to, struct interface *ifp, -		  u_char version, struct connected *connected) -{ -  struct rte *rte; -  struct rip_packet rip_packet; -  struct listnode *node, *nnode; - -  memset (&rip_packet, 0, sizeof (rip_packet)); - -  rip_packet.command = RIP_REQUEST; -  rip_packet.version = version; -  rte = rip_packet.rte; -  rte->metric = htonl (RIP_METRIC_INFINITY); - -  if (connected)  -    { -      /*  -       * connected is only sent for ripv1 case, or when -       * interface does not support multicast.  Caller loops -       * over each connected address for this case. -       */ -      if (rip_send_packet ((u_char *) &rip_packet, sizeof (rip_packet),  -                            to, connected) != sizeof (rip_packet)) -        return -1; -      else -        return sizeof (rip_packet); -    } -	 -  /* send request on each connected network */ -  for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, connected)) -    { -      struct prefix_ipv4 *p; - -      p = (struct prefix_ipv4 *) connected->address; - -      if (p->family != AF_INET) -        continue; - -      if (rip_send_packet ((u_char *) &rip_packet, sizeof (rip_packet),  -                            to, connected) != sizeof (rip_packet)) -        return -1; -    } -  return sizeof (rip_packet); -} - -static int -rip_update_jitter (unsigned long time) +static int rip_update_jitter(unsigned long time)  {  #define JITTER_BOUND 4 -  /* We want to get the jitter to +/- 1/JITTER_BOUND the interval. -     Given that, we cannot let time be less than JITTER_BOUND seconds. -     The RIPv2 RFC says jitter should be small compared to -     update_time.  We consider 1/JITTER_BOUND to be small. -  */ -   -  int jitter_input = time; -  int jitter; -   -  if (jitter_input < JITTER_BOUND) -    jitter_input = JITTER_BOUND; -   -  jitter = (((random () % ((jitter_input * 2) + 1)) - jitter_input)); - -  return jitter/JITTER_BOUND; -} - -void -rip_event (enum rip_event event, int sock) -{ -  int jitter = 0; - -  switch (event) -    { -    case RIP_READ: -      rip->t_read = NULL; -      thread_add_read(master, rip_read, NULL, sock, &rip->t_read); -      break; -    case RIP_UPDATE_EVENT: -      RIP_TIMER_OFF (rip->t_update); -      jitter = rip_update_jitter (rip->update_time); -      thread_add_timer(master, rip_update, NULL, sock ? 2 : rip->update_time + jitter, -                       &rip->t_update); -      break; -    case RIP_TRIGGERED_UPDATE: -      if (rip->t_triggered_interval) -        rip->trigger = 1; -      else thread_add_event(master, rip_triggered_update, NULL, 0, -                            &rip->t_triggered_update); -      break; -    default: -      break; -    } +	/* We want to get the jitter to +/- 1/JITTER_BOUND the interval. +	   Given that, we cannot let time be less than JITTER_BOUND seconds. +	   The RIPv2 RFC says jitter should be small compared to +	   update_time.  We consider 1/JITTER_BOUND to be small. +	*/ + +	int jitter_input = time; +	int jitter; + +	if (jitter_input < JITTER_BOUND) +		jitter_input = JITTER_BOUND; + +	jitter = (((random() % ((jitter_input * 2) + 1)) - jitter_input)); + +	return jitter / JITTER_BOUND; +} + +void rip_event(enum rip_event event, int sock) +{ +	int jitter = 0; + +	switch (event) { +	case RIP_READ: +		rip->t_read = NULL; +		thread_add_read(master, rip_read, NULL, sock, &rip->t_read); +		break; +	case RIP_UPDATE_EVENT: +		RIP_TIMER_OFF(rip->t_update); +		jitter = rip_update_jitter(rip->update_time); +		thread_add_timer(master, rip_update, NULL, +				 sock ? 2 : rip->update_time + jitter, +				 &rip->t_update); +		break; +	case RIP_TRIGGERED_UPDATE: +		if (rip->t_triggered_interval) +			rip->trigger = 1; +		else +			thread_add_event(master, rip_triggered_update, NULL, 0, +					 &rip->t_triggered_update); +		break; +	default: +		break; +	}  }  DEFUN_NOSH (router_rip, @@ -2806,21 +2794,19 @@ DEFUN_NOSH (router_rip,         "Enable a routing process\n"         "Routing Information Protocol (RIP)\n")  { -  int ret; +	int ret; -  /* If rip is not enabled before. */ -  if (! rip) -    { -      ret = rip_create (); -      if (ret < 0) -	{ -	  zlog_info ("Can't create RIP"); -          return CMD_WARNING_CONFIG_FAILED; +	/* If rip is not enabled before. */ +	if (!rip) { +		ret = rip_create(); +		if (ret < 0) { +			zlog_info("Can't create RIP"); +			return CMD_WARNING_CONFIG_FAILED; +		}  	} -    } -  VTY_PUSH_CONTEXT(RIP_NODE, rip); +	VTY_PUSH_CONTEXT(RIP_NODE, rip); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_router_rip, @@ -2830,9 +2816,9 @@ DEFUN (no_router_rip,         "Enable a routing process\n"         "Routing Information Protocol (RIP)\n")  { -  if (rip) -    rip_clean (); -  return CMD_SUCCESS; +	if (rip) +		rip_clean(); +	return CMD_SUCCESS;  }  DEFUN (rip_version, @@ -2841,19 +2827,18 @@ DEFUN (rip_version,         "Set routing protocol version\n"         "version\n")  { -  int idx_number = 1; -  int version; +	int idx_number = 1; +	int version; -  version = atoi (argv[idx_number]->arg); -  if (version != RIPv1 && version != RIPv2) -    { -      vty_out (vty, "invalid rip version %d\n",version); -      return CMD_WARNING_CONFIG_FAILED; -    } -  rip->version_send = version; -  rip->version_recv = version; +	version = atoi(argv[idx_number]->arg); +	if (version != RIPv1 && version != RIPv2) { +		vty_out(vty, "invalid rip version %d\n", version); +		return CMD_WARNING_CONFIG_FAILED; +	} +	rip->version_send = version; +	rip->version_recv = version; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_rip_version, @@ -2863,11 +2848,11 @@ DEFUN (no_rip_version,         "Set routing protocol version\n"         "Version\n")  { -  /* Set RIP version to the default. */ -  rip->version_send = RI_RIP_VERSION_2; -  rip->version_recv = RI_RIP_VERSION_1_AND_2; +	/* Set RIP version to the default. */ +	rip->version_send = RI_RIP_VERSION_2; +	rip->version_recv = RI_RIP_VERSION_1_AND_2; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -2877,34 +2862,33 @@ DEFUN (rip_route,         "RIP static route configuration\n"         "IP prefix <network>/<length>\n")  { -  int idx_ipv4_prefixlen = 1; -  int ret; -  struct prefix_ipv4 p; -  struct route_node *node; +	int idx_ipv4_prefixlen = 1; +	int ret; +	struct prefix_ipv4 p; +	struct route_node *node; -  ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p); -  if (ret < 0) -    { -      vty_out (vty, "Malformed address\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } -  apply_mask_ipv4 (&p); +	ret = str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); +	if (ret < 0) { +		vty_out(vty, "Malformed address\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} +	apply_mask_ipv4(&p); -  /* For router rip configuration. */ -  node = route_node_get (rip->route, (struct prefix *) &p); +	/* For router rip configuration. */ +	node = route_node_get(rip->route, (struct prefix *)&p); -  if (node->info) -    { -      vty_out (vty, "There is already same static route.\n"); -      route_unlock_node (node); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (node->info) { +		vty_out(vty, "There is already same static route.\n"); +		route_unlock_node(node); +		return CMD_WARNING_CONFIG_FAILED; +	} -  node->info = (void *)1; +	node->info = (void *)1; -  rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0, NULL, 0, 0, 0); +	rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0, NULL, 0, +			     0, 0); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_rip_route, @@ -2914,34 +2898,33 @@ DEFUN (no_rip_route,         "RIP static route configuration\n"         "IP prefix <network>/<length>\n")  { -  int idx_ipv4_prefixlen = 2; -  int ret; -  struct prefix_ipv4 p; -  struct route_node *node; +	int idx_ipv4_prefixlen = 2; +	int ret; +	struct prefix_ipv4 p; +	struct route_node *node; -  ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p); -  if (ret < 0) -    { -      vty_out (vty, "Malformed address\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } -  apply_mask_ipv4 (&p); - -  /* For router rip configuration. */ -  node = route_node_lookup (rip->route, (struct prefix *) &p); -  if (! node) -    { -      vty_out (vty, "Can't find route %s.\n",argv[idx_ipv4_prefixlen]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } +	ret = str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); +	if (ret < 0) { +		vty_out(vty, "Malformed address\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} +	apply_mask_ipv4(&p); + +	/* For router rip configuration. */ +	node = route_node_lookup(rip->route, (struct prefix *)&p); +	if (!node) { +		vty_out(vty, "Can't find route %s.\n", +			argv[idx_ipv4_prefixlen]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} -  rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0); -  route_unlock_node (node); +	rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0); +	route_unlock_node(node); -  node->info = NULL; -  route_unlock_node (node); +	node->info = NULL; +	route_unlock_node(node); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  #if 0 @@ -2967,13 +2950,12 @@ DEFUN (rip_default_metric,         "Set a metric of redistribute routes\n"         "Default metric\n")  { -  int idx_number = 1; -  if (rip) -    { -      rip->default_metric = atoi (argv[idx_number]->arg); -      /* rip_update_default_metric (); */ -    } -  return CMD_SUCCESS; +	int idx_number = 1; +	if (rip) { +		rip->default_metric = atoi(argv[idx_number]->arg); +		/* rip_update_default_metric (); */ +	} +	return CMD_SUCCESS;  }  DEFUN (no_rip_default_metric, @@ -2983,12 +2965,11 @@ DEFUN (no_rip_default_metric,         "Set a metric of redistribute routes\n"         "Default metric\n")  { -  if (rip) -    { -      rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT; -      /* rip_update_default_metric (); */ -    } -  return CMD_SUCCESS; +	if (rip) { +		rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT; +		/* rip_update_default_metric (); */ +	} +	return CMD_SUCCESS;  } @@ -3001,46 +2982,46 @@ DEFUN (rip_timers,         "Routing information timeout timer. Default is 180.\n"         "Garbage collection timer. Default is 120.\n")  { -  int idx_number = 2; -  int idx_number_2 = 3; -  int idx_number_3 = 4; -  unsigned long update; -  unsigned long timeout; -  unsigned long garbage; -  char *endptr = NULL; -  unsigned long RIP_TIMER_MAX = 2147483647; -  unsigned long RIP_TIMER_MIN = 5; - -  update = strtoul (argv[idx_number]->arg, &endptr, 10); -  if (update > RIP_TIMER_MAX || update < RIP_TIMER_MIN || *endptr != '\0')   -    { -      vty_out (vty, "update timer value error\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } -   -  timeout = strtoul (argv[idx_number_2]->arg, &endptr, 10); -  if (timeout > RIP_TIMER_MAX || timeout < RIP_TIMER_MIN || *endptr != '\0')  -    { -      vty_out (vty, "timeout timer value error\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } -   -  garbage = strtoul (argv[idx_number_3]->arg, &endptr, 10); -  if (garbage > RIP_TIMER_MAX || garbage < RIP_TIMER_MIN || *endptr != '\0')  -    { -      vty_out (vty, "garbage timer value error\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* Set each timer value. */ -  rip->update_time = update; -  rip->timeout_time = timeout; -  rip->garbage_time = garbage; - -  /* Reset update timer thread. */ -  rip_event (RIP_UPDATE_EVENT, 0); - -  return CMD_SUCCESS; +	int idx_number = 2; +	int idx_number_2 = 3; +	int idx_number_3 = 4; +	unsigned long update; +	unsigned long timeout; +	unsigned long garbage; +	char *endptr = NULL; +	unsigned long RIP_TIMER_MAX = 2147483647; +	unsigned long RIP_TIMER_MIN = 5; + +	update = strtoul(argv[idx_number]->arg, &endptr, 10); +	if (update > RIP_TIMER_MAX || update < RIP_TIMER_MIN +	    || *endptr != '\0') { +		vty_out(vty, "update timer value error\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	timeout = strtoul(argv[idx_number_2]->arg, &endptr, 10); +	if (timeout > RIP_TIMER_MAX || timeout < RIP_TIMER_MIN +	    || *endptr != '\0') { +		vty_out(vty, "timeout timer value error\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	garbage = strtoul(argv[idx_number_3]->arg, &endptr, 10); +	if (garbage > RIP_TIMER_MAX || garbage < RIP_TIMER_MIN +	    || *endptr != '\0') { +		vty_out(vty, "garbage timer value error\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* Set each timer value. */ +	rip->update_time = update; +	rip->timeout_time = timeout; +	rip->garbage_time = garbage; + +	/* Reset update timer thread. */ +	rip_event(RIP_UPDATE_EVENT, 0); + +	return CMD_SUCCESS;  }  DEFUN (no_rip_timers, @@ -3053,210 +3034,193 @@ DEFUN (no_rip_timers,         "Routing information timeout timer. Default is 180.\n"         "Garbage collection timer. Default is 120.\n")  { -  /* Set each timer value to the default. */ -  rip->update_time = RIP_UPDATE_TIMER_DEFAULT; -  rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT; -  rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT; +	/* Set each timer value to the default. */ +	rip->update_time = RIP_UPDATE_TIMER_DEFAULT; +	rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT; +	rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT; -  /* Reset update timer thread. */ -  rip_event (RIP_UPDATE_EVENT, 0); +	/* Reset update timer thread. */ +	rip_event(RIP_UPDATE_EVENT, 0); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } -  struct route_table *rip_distance_table; -struct rip_distance -{ -  /* Distance value for the IP source prefix. */ -  u_char distance; +struct rip_distance { +	/* Distance value for the IP source prefix. */ +	u_char distance; -  /* Name of the access-list to be matched. */ -  char *access_list; +	/* Name of the access-list to be matched. */ +	char *access_list;  }; -static struct rip_distance * -rip_distance_new (void) +static struct rip_distance *rip_distance_new(void)  { -  return XCALLOC (MTYPE_RIP_DISTANCE, sizeof (struct rip_distance)); +	return XCALLOC(MTYPE_RIP_DISTANCE, sizeof(struct rip_distance));  } -static void -rip_distance_free (struct rip_distance *rdistance) -{ -  XFREE (MTYPE_RIP_DISTANCE, rdistance); -} - -static int -rip_distance_set (struct vty *vty, const char *distance_str, const char *ip_str, -		  const char *access_list_str) -{ -  int ret; -  struct prefix_ipv4 p; -  u_char distance; -  struct route_node *rn; -  struct rip_distance *rdistance; - -  ret = str2prefix_ipv4 (ip_str, &p); -  if (ret == 0) -    { -      vty_out (vty, "Malformed prefix\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  distance = atoi (distance_str); - -  /* Get RIP distance node. */ -  rn = route_node_get (rip_distance_table, (struct prefix *) &p); -  if (rn->info) -    { -      rdistance = rn->info; -      route_unlock_node (rn); -    } -  else -    { -      rdistance = rip_distance_new (); -      rn->info = rdistance; -    } - -  /* Set distance value. */ -  rdistance->distance = distance; - -  /* Reset access-list configuration. */ -  if (rdistance->access_list) -    { -      free (rdistance->access_list); -      rdistance->access_list = NULL; -    } -  if (access_list_str) -    rdistance->access_list = strdup (access_list_str); - -  return CMD_SUCCESS; -} - -static int -rip_distance_unset (struct vty *vty, const char *distance_str, -		    const char *ip_str, const char *access_list_str) -{ -  int ret; -  struct prefix_ipv4 p; -  struct route_node *rn; -  struct rip_distance *rdistance; - -  ret = str2prefix_ipv4 (ip_str, &p); -  if (ret == 0) -    { -      vty_out (vty, "Malformed prefix\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  rn = route_node_lookup (rip_distance_table, (struct prefix *)&p); -  if (! rn) -    { -      vty_out (vty, "Can't find specified prefix\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  rdistance = rn->info; - -  if (rdistance->access_list) -    free (rdistance->access_list); -  rip_distance_free (rdistance); - -  rn->info = NULL; -  route_unlock_node (rn); -  route_unlock_node (rn); - -  return CMD_SUCCESS; +static void rip_distance_free(struct rip_distance *rdistance) +{ +	XFREE(MTYPE_RIP_DISTANCE, rdistance);  } -static void -rip_distance_reset (void) +static int rip_distance_set(struct vty *vty, const char *distance_str, +			    const char *ip_str, const char *access_list_str)  { -  struct route_node *rn; -  struct rip_distance *rdistance; +	int ret; +	struct prefix_ipv4 p; +	u_char distance; +	struct route_node *rn; +	struct rip_distance *rdistance; + +	ret = str2prefix_ipv4(ip_str, &p); +	if (ret == 0) { +		vty_out(vty, "Malformed prefix\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	distance = atoi(distance_str); + +	/* Get RIP distance node. */ +	rn = route_node_get(rip_distance_table, (struct prefix *)&p); +	if (rn->info) { +		rdistance = rn->info; +		route_unlock_node(rn); +	} else { +		rdistance = rip_distance_new(); +		rn->info = rdistance; +	} + +	/* Set distance value. */ +	rdistance->distance = distance; + +	/* Reset access-list configuration. */ +	if (rdistance->access_list) { +		free(rdistance->access_list); +		rdistance->access_list = NULL; +	} +	if (access_list_str) +		rdistance->access_list = strdup(access_list_str); + +	return CMD_SUCCESS; +} + +static int rip_distance_unset(struct vty *vty, const char *distance_str, +			      const char *ip_str, const char *access_list_str) +{ +	int ret; +	struct prefix_ipv4 p; +	struct route_node *rn; +	struct rip_distance *rdistance; + +	ret = str2prefix_ipv4(ip_str, &p); +	if (ret == 0) { +		vty_out(vty, "Malformed prefix\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	rn = route_node_lookup(rip_distance_table, (struct prefix *)&p); +	if (!rn) { +		vty_out(vty, "Can't find specified prefix\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	rdistance = rn->info; -  for (rn = route_top (rip_distance_table); rn; rn = route_next (rn)) -    if ((rdistance = rn->info) != NULL) -      {  	if (rdistance->access_list) -	  free (rdistance->access_list); -	rip_distance_free (rdistance); +		free(rdistance->access_list); +	rip_distance_free(rdistance); +  	rn->info = NULL; -	route_unlock_node (rn); -      } +	route_unlock_node(rn); +	route_unlock_node(rn); + +	return CMD_SUCCESS;  } -/* Apply RIP information to distance method. */ -u_char -rip_distance_apply (struct rip_info *rinfo) -{ -  struct route_node *rn; -  struct prefix_ipv4 p; -  struct rip_distance *rdistance; -  struct access_list *alist; - -  if (! rip) -    return 0; - -  memset (&p, 0, sizeof (struct prefix_ipv4)); -  p.family = AF_INET; -  p.prefix = rinfo->from; -  p.prefixlen = IPV4_MAX_BITLEN; - -  /* Check source address. */ -  rn = route_node_match (rip_distance_table, (struct prefix *) &p); -  if (rn) -    { -      rdistance = rn->info; -      route_unlock_node (rn); - -      if (rdistance->access_list) -	{ -	  alist = access_list_lookup (AFI_IP, rdistance->access_list); -	  if (alist == NULL) -	    return 0; -	  if (access_list_apply (alist, &rinfo->rp->p) == FILTER_DENY) -	    return 0; +static void rip_distance_reset(void) +{ +	struct route_node *rn; +	struct rip_distance *rdistance; -	  return rdistance->distance; +	for (rn = route_top(rip_distance_table); rn; rn = route_next(rn)) +		if ((rdistance = rn->info) != NULL) { +			if (rdistance->access_list) +				free(rdistance->access_list); +			rip_distance_free(rdistance); +			rn->info = NULL; +			route_unlock_node(rn); +		} +} + +/* Apply RIP information to distance method. */ +u_char rip_distance_apply(struct rip_info *rinfo) +{ +	struct route_node *rn; +	struct prefix_ipv4 p; +	struct rip_distance *rdistance; +	struct access_list *alist; + +	if (!rip) +		return 0; + +	memset(&p, 0, sizeof(struct prefix_ipv4)); +	p.family = AF_INET; +	p.prefix = rinfo->from; +	p.prefixlen = IPV4_MAX_BITLEN; + +	/* Check source address. */ +	rn = route_node_match(rip_distance_table, (struct prefix *)&p); +	if (rn) { +		rdistance = rn->info; +		route_unlock_node(rn); + +		if (rdistance->access_list) { +			alist = access_list_lookup(AFI_IP, +						   rdistance->access_list); +			if (alist == NULL) +				return 0; +			if (access_list_apply(alist, &rinfo->rp->p) +			    == FILTER_DENY) +				return 0; + +			return rdistance->distance; +		} else +			return rdistance->distance;  	} -      else -	return rdistance->distance; -    } -  if (rip->distance) -    return rip->distance; +	if (rip->distance) +		return rip->distance; -  return 0; +	return 0;  } -static void -rip_distance_show (struct vty *vty) -{ -  struct route_node *rn; -  struct rip_distance *rdistance; -  int header = 1; -  char buf[BUFSIZ]; -   -  vty_out (vty, "  Distance: (default is %d)\n", -	   rip->distance ? rip->distance : ZEBRA_RIP_DISTANCE_DEFAULT); - -  for (rn = route_top (rip_distance_table); rn; rn = route_next (rn)) -    if ((rdistance = rn->info) != NULL) -      { -	if (header) -	  { -	    vty_out (vty,"    Address           Distance  List\n"); -	    header = 0; -	  } -	sprintf (buf, "%s/%d", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen); -	vty_out (vty, "    %-20s  %4d  %s\n", -		 buf, rdistance->distance, -		 rdistance->access_list ? rdistance->access_list : ""); -      } +static void rip_distance_show(struct vty *vty) +{ +	struct route_node *rn; +	struct rip_distance *rdistance; +	int header = 1; +	char buf[BUFSIZ]; + +	vty_out(vty, "  Distance: (default is %d)\n", +		rip->distance ? rip->distance : ZEBRA_RIP_DISTANCE_DEFAULT); + +	for (rn = route_top(rip_distance_table); rn; rn = route_next(rn)) +		if ((rdistance = rn->info) != NULL) { +			if (header) { +				vty_out(vty, +					"    Address           Distance  List\n"); +				header = 0; +			} +			sprintf(buf, "%s/%d", inet_ntoa(rn->p.u.prefix4), +				rn->p.prefixlen); +			vty_out(vty, "    %-20s  %4d  %s\n", buf, +				rdistance->distance, +				rdistance->access_list ? rdistance->access_list +						       : ""); +		}  }  DEFUN (rip_distance, @@ -3265,9 +3229,9 @@ DEFUN (rip_distance,         "Administrative distance\n"         "Distance value\n")  { -  int idx_number = 1; -  rip->distance = atoi (argv[idx_number]->arg); -  return CMD_SUCCESS; +	int idx_number = 1; +	rip->distance = atoi(argv[idx_number]->arg); +	return CMD_SUCCESS;  }  DEFUN (no_rip_distance, @@ -3277,8 +3241,8 @@ DEFUN (no_rip_distance,         "Administrative distance\n"         "Distance value\n")  { -  rip->distance = 0; -  return CMD_SUCCESS; +	rip->distance = 0; +	return CMD_SUCCESS;  }  DEFUN (rip_distance_source, @@ -3288,10 +3252,11 @@ DEFUN (rip_distance_source,         "Distance value\n"         "IP source prefix\n")  { -  int idx_number = 1; -  int idx_ipv4_prefixlen = 2; -  rip_distance_set (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL); -  return CMD_SUCCESS; +	int idx_number = 1; +	int idx_ipv4_prefixlen = 2; +	rip_distance_set(vty, argv[idx_number]->arg, +			 argv[idx_ipv4_prefixlen]->arg, NULL); +	return CMD_SUCCESS;  }  DEFUN (no_rip_distance_source, @@ -3302,10 +3267,11 @@ DEFUN (no_rip_distance_source,         "Distance value\n"         "IP source prefix\n")  { -  int idx_number = 2; -  int idx_ipv4_prefixlen = 3; -  rip_distance_unset (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL); -  return CMD_SUCCESS; +	int idx_number = 2; +	int idx_ipv4_prefixlen = 3; +	rip_distance_unset(vty, argv[idx_number]->arg, +			   argv[idx_ipv4_prefixlen]->arg, NULL); +	return CMD_SUCCESS;  }  DEFUN (rip_distance_source_access_list, @@ -3316,11 +3282,12 @@ DEFUN (rip_distance_source_access_list,         "IP source prefix\n"         "Access list name\n")  { -  int idx_number = 1; -  int idx_ipv4_prefixlen = 2; -  int idx_word = 3; -  rip_distance_set (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg); -  return CMD_SUCCESS; +	int idx_number = 1; +	int idx_ipv4_prefixlen = 2; +	int idx_word = 3; +	rip_distance_set(vty, argv[idx_number]->arg, +			 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg); +	return CMD_SUCCESS;  }  DEFUN (no_rip_distance_source_access_list, @@ -3332,51 +3299,50 @@ DEFUN (no_rip_distance_source_access_list,         "IP source prefix\n"         "Access list name\n")  { -  int idx_number = 2; -  int idx_ipv4_prefixlen = 3; -  int idx_word = 4; -  rip_distance_unset (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg); -  return CMD_SUCCESS; +	int idx_number = 2; +	int idx_ipv4_prefixlen = 3; +	int idx_word = 4; +	rip_distance_unset(vty, argv[idx_number]->arg, +			   argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg); +	return CMD_SUCCESS;  }  /* Update ECMP routes to zebra when ECMP is disabled. */ -static void -rip_ecmp_disable (void) -{ -  struct route_node *rp; -  struct rip_info *rinfo, *tmp_rinfo; -  struct list *list; -  struct listnode *node, *nextnode; - -  if (!rip) -    return; - -  for (rp = route_top (rip->table); rp; rp = route_next (rp)) -    if ((list = rp->info) != NULL && listcount (list) > 1) -      { -        rinfo = listgetdata (listhead (list)); -        if (!rip_route_rte (rinfo)) -          continue; - -        /* Drop all other entries, except the first one. */ -        for (ALL_LIST_ELEMENTS (list, node, nextnode, tmp_rinfo)) -          if (tmp_rinfo != rinfo) -            { -              RIP_TIMER_OFF (tmp_rinfo->t_timeout); -              RIP_TIMER_OFF (tmp_rinfo->t_garbage_collect); -              list_delete_node (list, node); -              rip_info_free (tmp_rinfo); -            } - -        /* Update zebra. */ -        rip_zebra_ipv4_add (rp); - -        /* Set the route change flag. */ -        SET_FLAG (rinfo->flags, RIP_RTF_CHANGED); - -        /* Signal the output process to trigger an update. */ -        rip_event (RIP_TRIGGERED_UPDATE, 0); -      } +static void rip_ecmp_disable(void) +{ +	struct route_node *rp; +	struct rip_info *rinfo, *tmp_rinfo; +	struct list *list; +	struct listnode *node, *nextnode; + +	if (!rip) +		return; + +	for (rp = route_top(rip->table); rp; rp = route_next(rp)) +		if ((list = rp->info) != NULL && listcount(list) > 1) { +			rinfo = listgetdata(listhead(list)); +			if (!rip_route_rte(rinfo)) +				continue; + +			/* Drop all other entries, except the first one. */ +			for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo)) +				if (tmp_rinfo != rinfo) { +					RIP_TIMER_OFF(tmp_rinfo->t_timeout); +					RIP_TIMER_OFF( +						tmp_rinfo->t_garbage_collect); +					list_delete_node(list, node); +					rip_info_free(tmp_rinfo); +				} + +			/* Update zebra. */ +			rip_zebra_ipv4_add(rp); + +			/* Set the route change flag. */ +			SET_FLAG(rinfo->flags, RIP_RTF_CHANGED); + +			/* Signal the output process to trigger an update. */ +			rip_event(RIP_TRIGGERED_UPDATE, 0); +		}  }  DEFUN (rip_allow_ecmp, @@ -3384,15 +3350,14 @@ DEFUN (rip_allow_ecmp,         "allow-ecmp",         "Allow Equal Cost MultiPath\n")  { -  if (rip->ecmp) -    { -      vty_out (vty, "ECMP is already enabled.\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (rip->ecmp) { +		vty_out(vty, "ECMP is already enabled.\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  rip->ecmp = 1; -  zlog_info ("ECMP is enabled."); -  return CMD_SUCCESS; +	rip->ecmp = 1; +	zlog_info("ECMP is enabled."); +	return CMD_SUCCESS;  }  DEFUN (no_rip_allow_ecmp, @@ -3401,62 +3366,55 @@ DEFUN (no_rip_allow_ecmp,         NO_STR         "Allow Equal Cost MultiPath\n")  { -  if (!rip->ecmp) -    { -      vty_out (vty, "ECMP is already disabled.\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (!rip->ecmp) { +		vty_out(vty, "ECMP is already disabled.\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  rip->ecmp = 0; -  zlog_info ("ECMP is disabled."); -  rip_ecmp_disable (); -  return CMD_SUCCESS; +	rip->ecmp = 0; +	zlog_info("ECMP is disabled."); +	rip_ecmp_disable(); +	return CMD_SUCCESS;  }  /* Print out routes update time. */ -static void -rip_vty_out_uptime (struct vty *vty, struct rip_info *rinfo) +static void rip_vty_out_uptime(struct vty *vty, struct rip_info *rinfo)  { -  time_t clock; -  struct tm *tm; +	time_t clock; +	struct tm *tm;  #define TIME_BUF 25 -  char timebuf [TIME_BUF]; -  struct thread *thread; - -  if ((thread = rinfo->t_timeout) != NULL) -    { -      clock = thread_timer_remain_second (thread); -      tm = gmtime (&clock); -      strftime (timebuf, TIME_BUF, "%M:%S", tm); -      vty_out (vty, "%5s", timebuf); -    } -  else if ((thread = rinfo->t_garbage_collect) != NULL) -    { -      clock = thread_timer_remain_second (thread); -      tm = gmtime (&clock); -      strftime (timebuf, TIME_BUF, "%M:%S", tm); -      vty_out (vty, "%5s", timebuf); -    } -} - -static const char * -rip_route_type_print (int sub_type) -{ -  switch (sub_type) -    { -      case RIP_ROUTE_RTE: -	return "n"; -      case RIP_ROUTE_STATIC: -	return "s"; -      case RIP_ROUTE_DEFAULT: -	return "d"; -      case RIP_ROUTE_REDISTRIBUTE: -	return "r"; -      case RIP_ROUTE_INTERFACE: -	return "i"; -      default: -	return "?"; -    } +	char timebuf[TIME_BUF]; +	struct thread *thread; + +	if ((thread = rinfo->t_timeout) != NULL) { +		clock = thread_timer_remain_second(thread); +		tm = gmtime(&clock); +		strftime(timebuf, TIME_BUF, "%M:%S", tm); +		vty_out(vty, "%5s", timebuf); +	} else if ((thread = rinfo->t_garbage_collect) != NULL) { +		clock = thread_timer_remain_second(thread); +		tm = gmtime(&clock); +		strftime(timebuf, TIME_BUF, "%M:%S", tm); +		vty_out(vty, "%5s", timebuf); +	} +} + +static const char *rip_route_type_print(int sub_type) +{ +	switch (sub_type) { +	case RIP_ROUTE_RTE: +		return "n"; +	case RIP_ROUTE_STATIC: +		return "s"; +	case RIP_ROUTE_DEFAULT: +		return "d"; +	case RIP_ROUTE_REDISTRIBUTE: +		return "r"; +	case RIP_ROUTE_INTERFACE: +		return "i"; +	default: +		return "?"; +	}  }  DEFUN (show_ip_rip, @@ -3466,76 +3424,83 @@ DEFUN (show_ip_rip,         IP_STR         "Show RIP routes\n")  { -  struct route_node *np; -  struct rip_info *rinfo = NULL; -  struct list *list = NULL; -  struct listnode *listnode = NULL; - -  if (! rip) -    return CMD_SUCCESS; - -  vty_out (vty, "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n" -	   "Sub-codes:\n" -           "      (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n" -	   "      (i) - interface\n\n" -	   "     Network            Next Hop         Metric From            Tag Time\n"); -   -  for (np = route_top (rip->table); np; np = route_next (np)) -    if ((list = np->info) != NULL) -      for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo)) -      { -	int len; - -	len = vty_out (vty, "%c(%s) %s/%d", -		       /* np->lock, For debugging. */ -		       zebra_route_char(rinfo->type), -		       rip_route_type_print (rinfo->sub_type), -		       inet_ntoa (np->p.u.prefix4), np->p.prefixlen); -	 -	len = 24 - len; - -	if (len > 0) -	  vty_out (vty, "%*s", len, " "); - -        if (rinfo->nexthop.s_addr)  -	  vty_out (vty, "%-20s %2d ", inet_ntoa (rinfo->nexthop), -		   rinfo->metric); -        else -	  vty_out (vty, "0.0.0.0              %2d ", rinfo->metric); - -	/* Route which exist in kernel routing table. */ -	if ((rinfo->type == ZEBRA_ROUTE_RIP) &&  -	    (rinfo->sub_type == RIP_ROUTE_RTE)) -	  { -	    vty_out (vty, "%-15s ", inet_ntoa (rinfo->from)); -	    vty_out (vty, "%3"ROUTE_TAG_PRI" ", (route_tag_t)rinfo->tag); -	    rip_vty_out_uptime (vty, rinfo); -	  } -	else if (rinfo->metric == RIP_METRIC_INFINITY) -	  { -	    vty_out (vty, "self            "); -	    vty_out (vty, "%3"ROUTE_TAG_PRI" ", (route_tag_t)rinfo->tag); -	    rip_vty_out_uptime (vty, rinfo); -	  } -	else -	  { -	    if (rinfo->external_metric) -	      { -	        len = vty_out (vty, "self (%s:%d)",  -			       zebra_route_string(rinfo->type), -	                       rinfo->external_metric); -	        len = 16 - len; -	        if (len > 0) -	          vty_out (vty, "%*s", len, " "); -	      } -	    else -	      vty_out (vty, "self            "); -	    vty_out (vty, "%3"ROUTE_TAG_PRI, (route_tag_t)rinfo->tag); -	  } - -	vty_out (vty, "\n"); -      } -  return CMD_SUCCESS; +	struct route_node *np; +	struct rip_info *rinfo = NULL; +	struct list *list = NULL; +	struct listnode *listnode = NULL; + +	if (!rip) +		return CMD_SUCCESS; + +	vty_out(vty, +		"Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n" +		"Sub-codes:\n" +		"      (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n" +		"      (i) - interface\n\n" +		"     Network            Next Hop         Metric From            Tag Time\n"); + +	for (np = route_top(rip->table); np; np = route_next(np)) +		if ((list = np->info) != NULL) +			for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { +				int len; + +				len = vty_out( +					vty, "%c(%s) %s/%d", +					/* np->lock, For debugging. */ +					zebra_route_char(rinfo->type), +					rip_route_type_print(rinfo->sub_type), +					inet_ntoa(np->p.u.prefix4), +					np->p.prefixlen); + +				len = 24 - len; + +				if (len > 0) +					vty_out(vty, "%*s", len, " "); + +				if (rinfo->nexthop.s_addr) +					vty_out(vty, "%-20s %2d ", +						inet_ntoa(rinfo->nexthop), +						rinfo->metric); +				else +					vty_out(vty, +						"0.0.0.0              %2d ", +						rinfo->metric); + +				/* Route which exist in kernel routing table. */ +				if ((rinfo->type == ZEBRA_ROUTE_RIP) +				    && (rinfo->sub_type == RIP_ROUTE_RTE)) { +					vty_out(vty, "%-15s ", +						inet_ntoa(rinfo->from)); +					vty_out(vty, "%3" ROUTE_TAG_PRI " ", +						(route_tag_t)rinfo->tag); +					rip_vty_out_uptime(vty, rinfo); +				} else if (rinfo->metric +					   == RIP_METRIC_INFINITY) { +					vty_out(vty, "self            "); +					vty_out(vty, "%3" ROUTE_TAG_PRI " ", +						(route_tag_t)rinfo->tag); +					rip_vty_out_uptime(vty, rinfo); +				} else { +					if (rinfo->external_metric) { +						len = vty_out( +							vty, "self (%s:%d)", +							zebra_route_string( +								rinfo->type), +							rinfo->external_metric); +						len = 16 - len; +						if (len > 0) +							vty_out(vty, "%*s", len, +								" "); +					} else +						vty_out(vty, +							"self            "); +					vty_out(vty, "%3" ROUTE_TAG_PRI, +						(route_tag_t)rinfo->tag); +				} + +				vty_out(vty, "\n"); +			} +	return CMD_SUCCESS;  }  /* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */ @@ -3547,534 +3512,508 @@ DEFUN (show_ip_rip_status,         "Show RIP routes\n"         "IP routing protocol process parameters and statistics\n")  { -  struct listnode *node; -  struct interface *ifp; -  struct rip_interface *ri; -  extern const struct message ri_version_msg[]; -  const char *send_version; -  const char *receive_version; - -  if (! rip) -    return CMD_SUCCESS; - -  vty_out (vty, "Routing Protocol is \"rip\"\n"); -  vty_out (vty, "  Sending updates every %ld seconds with +/-50%%,", -	   rip->update_time); -  vty_out (vty, " next due in %lu seconds\n",  -	   thread_timer_remain_second(rip->t_update)); -  vty_out (vty, "  Timeout after %ld seconds,", rip->timeout_time); -  vty_out (vty, " garbage collect after %ld seconds\n",rip->garbage_time); - -  /* Filtering status show. */ -  config_show_distribute (vty); -		  -  /* Default metric information. */ -  vty_out (vty, "  Default redistribution metric is %d\n", -	   rip->default_metric); - -  /* Redistribute information. */ -  vty_out (vty, "  Redistributing:"); -  config_write_rip_redistribute (vty, 0); -  vty_out (vty, "\n"); - -  vty_out (vty, "  Default version control: send version %s,", -	   lookup_msg(ri_version_msg,rip->version_send, NULL)); -  if (rip->version_recv == RI_RIP_VERSION_1_AND_2) -    vty_out (vty, " receive any version \n"); -  else -    vty_out (vty, " receive version %s \n", -	       lookup_msg(ri_version_msg,rip->version_recv, NULL)); - -  vty_out (vty, "    Interface        Send  Recv   Key-chain\n"); - -  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) -    { -      ri = ifp->info; - -      if (!ri->running) -	continue; - -      if (ri->enable_network || ri->enable_interface) -	{ -	  if (ri->ri_send == RI_RIP_UNSPEC) -	    send_version = lookup_msg(ri_version_msg, rip->version_send, NULL); -	  else -	    send_version = lookup_msg(ri_version_msg, ri->ri_send, NULL); - -	  if (ri->ri_receive == RI_RIP_UNSPEC) -	    receive_version = lookup_msg(ri_version_msg, rip->version_recv, NULL); -	  else -	    receive_version = lookup_msg(ri_version_msg, ri->ri_receive, NULL); -	 -	  vty_out (vty, "    %-17s%-3s   %-3s    %s\n", ifp->name, -		   send_version, -		   receive_version, -		   ri->key_chain ? ri->key_chain : ""); -	} -    } - -  vty_out (vty, "  Routing for Networks:\n"); -  config_write_rip_network (vty, 0);   - -  { -    int found_passive = 0; -    for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) -      { -	ri = ifp->info; - -	if ((ri->enable_network || ri->enable_interface) && ri->passive) -	  { -	    if (!found_passive) -	      { -		vty_out (vty, "  Passive Interface(s):\n"); -		found_passive = 1; -	      } -	    vty_out (vty, "    %s\n", ifp->name); -	  } -      } -  } - -  vty_out (vty, "  Routing Information Sources:\n"); -  vty_out (vty, -             "    Gateway          BadPackets BadRoutes  Distance Last Update\n"); -  rip_peer_display (vty); - -  rip_distance_show (vty); +	struct listnode *node; +	struct interface *ifp; +	struct rip_interface *ri; +	extern const struct message ri_version_msg[]; +	const char *send_version; +	const char *receive_version; + +	if (!rip) +		return CMD_SUCCESS; + +	vty_out(vty, "Routing Protocol is \"rip\"\n"); +	vty_out(vty, "  Sending updates every %ld seconds with +/-50%%,", +		rip->update_time); +	vty_out(vty, " next due in %lu seconds\n", +		thread_timer_remain_second(rip->t_update)); +	vty_out(vty, "  Timeout after %ld seconds,", rip->timeout_time); +	vty_out(vty, " garbage collect after %ld seconds\n", rip->garbage_time); + +	/* Filtering status show. */ +	config_show_distribute(vty); + +	/* Default metric information. */ +	vty_out(vty, "  Default redistribution metric is %d\n", +		rip->default_metric); + +	/* Redistribute information. */ +	vty_out(vty, "  Redistributing:"); +	config_write_rip_redistribute(vty, 0); +	vty_out(vty, "\n"); + +	vty_out(vty, "  Default version control: send version %s,", +		lookup_msg(ri_version_msg, rip->version_send, NULL)); +	if (rip->version_recv == RI_RIP_VERSION_1_AND_2) +		vty_out(vty, " receive any version \n"); +	else +		vty_out(vty, " receive version %s \n", +			lookup_msg(ri_version_msg, rip->version_recv, NULL)); + +	vty_out(vty, "    Interface        Send  Recv   Key-chain\n"); + +	for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { +		ri = ifp->info; + +		if (!ri->running) +			continue; + +		if (ri->enable_network || ri->enable_interface) { +			if (ri->ri_send == RI_RIP_UNSPEC) +				send_version = +					lookup_msg(ri_version_msg, +						   rip->version_send, NULL); +			else +				send_version = lookup_msg(ri_version_msg, +							  ri->ri_send, NULL); + +			if (ri->ri_receive == RI_RIP_UNSPEC) +				receive_version = +					lookup_msg(ri_version_msg, +						   rip->version_recv, NULL); +			else +				receive_version = lookup_msg( +					ri_version_msg, ri->ri_receive, NULL); + +			vty_out(vty, "    %-17s%-3s   %-3s    %s\n", ifp->name, +				send_version, receive_version, +				ri->key_chain ? ri->key_chain : ""); +		} +	} -  return CMD_SUCCESS; -} +	vty_out(vty, "  Routing for Networks:\n"); +	config_write_rip_network(vty, 0); -/* RIP configuration write function. */ -static int -config_write_rip (struct vty *vty) -{ -  int write = 0; -  struct route_node *rn; -  struct rip_distance *rdistance; - -  if (rip) -    { -      /* Router RIP statement. */ -      vty_out (vty, "router rip\n"); -      write++; -   -      /* RIP version statement.  Default is RIP version 2. */ -      if (rip->version_send != RI_RIP_VERSION_2 -	  || rip->version_recv != RI_RIP_VERSION_1_AND_2) -	vty_out (vty, " version %d\n",rip->version_send); -  -      /* RIP timer configuration. */ -      if (rip->update_time != RIP_UPDATE_TIMER_DEFAULT  -	  || rip->timeout_time != RIP_TIMEOUT_TIMER_DEFAULT  -	  || rip->garbage_time != RIP_GARBAGE_TIMER_DEFAULT) -	vty_out (vty, " timers basic %lu %lu %lu\n", -		 rip->update_time, -		 rip->timeout_time, -		 rip->garbage_time); - -      /* Default information configuration. */ -      if (rip->default_information)  	{ -	  if (rip->default_information_route_map) -	    vty_out (vty, " default-information originate route-map %s\n", -		     rip->default_information_route_map); -	  else -	    vty_out (vty," default-information originate\n"); +		int found_passive = 0; +		for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) { +			ri = ifp->info; + +			if ((ri->enable_network || ri->enable_interface) +			    && ri->passive) { +				if (!found_passive) { +					vty_out(vty, +						"  Passive Interface(s):\n"); +					found_passive = 1; +				} +				vty_out(vty, "    %s\n", ifp->name); +			} +		}  	} -      /* Redistribute configuration. */ -      config_write_rip_redistribute (vty, 1); - -      /* RIP offset-list configuration. */ -      config_write_rip_offset_list (vty); +	vty_out(vty, "  Routing Information Sources:\n"); +	vty_out(vty, +		"    Gateway          BadPackets BadRoutes  Distance Last Update\n"); +	rip_peer_display(vty); -      /* RIP enabled network and interface configuration. */ -      config_write_rip_network (vty, 1); -			 -      /* RIP default metric configuration */ -      if (rip->default_metric != RIP_DEFAULT_METRIC_DEFAULT) -        vty_out (vty, " default-metric %d\n", -		 rip->default_metric); +	rip_distance_show(vty); -      /* Distribute configuration. */ -      write += config_write_distribute (vty); +	return CMD_SUCCESS; +} -      /* Interface routemap configuration */ -      write += config_write_if_rmap (vty); +/* RIP configuration write function. */ +static int config_write_rip(struct vty *vty) +{ +	int write = 0; +	struct route_node *rn; +	struct rip_distance *rdistance; + +	if (rip) { +		/* Router RIP statement. */ +		vty_out(vty, "router rip\n"); +		write++; + +		/* RIP version statement.  Default is RIP version 2. */ +		if (rip->version_send != RI_RIP_VERSION_2 +		    || rip->version_recv != RI_RIP_VERSION_1_AND_2) +			vty_out(vty, " version %d\n", rip->version_send); + +		/* RIP timer configuration. */ +		if (rip->update_time != RIP_UPDATE_TIMER_DEFAULT +		    || rip->timeout_time != RIP_TIMEOUT_TIMER_DEFAULT +		    || rip->garbage_time != RIP_GARBAGE_TIMER_DEFAULT) +			vty_out(vty, " timers basic %lu %lu %lu\n", +				rip->update_time, rip->timeout_time, +				rip->garbage_time); + +		/* Default information configuration. */ +		if (rip->default_information) { +			if (rip->default_information_route_map) +				vty_out(vty, +					" default-information originate route-map %s\n", +					rip->default_information_route_map); +			else +				vty_out(vty, +					" default-information originate\n"); +		} -      /* Distance configuration. */ -      if (rip->distance) -	vty_out (vty, " distance %d\n", rip->distance); +		/* Redistribute configuration. */ +		config_write_rip_redistribute(vty, 1); + +		/* RIP offset-list configuration. */ +		config_write_rip_offset_list(vty); + +		/* RIP enabled network and interface configuration. */ +		config_write_rip_network(vty, 1); + +		/* RIP default metric configuration */ +		if (rip->default_metric != RIP_DEFAULT_METRIC_DEFAULT) +			vty_out(vty, " default-metric %d\n", +				rip->default_metric); + +		/* Distribute configuration. */ +		write += config_write_distribute(vty); + +		/* Interface routemap configuration */ +		write += config_write_if_rmap(vty); + +		/* Distance configuration. */ +		if (rip->distance) +			vty_out(vty, " distance %d\n", rip->distance); + +		/* RIP source IP prefix distance configuration. */ +		for (rn = route_top(rip_distance_table); rn; +		     rn = route_next(rn)) +			if ((rdistance = rn->info) != NULL) +				vty_out(vty, " distance %d %s/%d %s\n", +					rdistance->distance, +					inet_ntoa(rn->p.u.prefix4), +					rn->p.prefixlen, +					rdistance->access_list +						? rdistance->access_list +						: ""); + +		/* ECMP configuration. */ +		if (rip->ecmp) +			vty_out(vty, " allow-ecmp\n"); + +		/* RIP static route configuration. */ +		for (rn = route_top(rip->route); rn; rn = route_next(rn)) +			if (rn->info) +				vty_out(vty, " route %s/%d\n", +					inet_ntoa(rn->p.u.prefix4), +					rn->p.prefixlen); +	} +	return write; +} -      /* RIP source IP prefix distance configuration. */ -      for (rn = route_top (rip_distance_table); rn; rn = route_next (rn)) -	if ((rdistance = rn->info) != NULL) -	  vty_out (vty, " distance %d %s/%d %s\n", rdistance->distance, -		   inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen, -		   rdistance->access_list ? rdistance->access_list : ""); +/* RIP node structure. */ +static struct cmd_node rip_node = {RIP_NODE, "%s(config-router)# ", 1}; -      /* ECMP configuration. */ -      if (rip->ecmp) -        vty_out (vty, " allow-ecmp\n"); +/* Distribute-list update functions. */ +static void rip_distribute_update(struct distribute *dist) +{ +	struct interface *ifp; +	struct rip_interface *ri; +	struct access_list *alist; +	struct prefix_list *plist; -      /* RIP static route configuration. */ -      for (rn = route_top (rip->route); rn; rn = route_next (rn)) -	if (rn->info) -	  vty_out (vty, " route %s/%d\n",  -		   inet_ntoa (rn->p.u.prefix4), -		   rn->p.prefixlen); +	if (!dist->ifname) +		return; -    } -  return write; -} +	ifp = if_lookup_by_name(dist->ifname, VRF_DEFAULT); +	if (ifp == NULL) +		return; -/* RIP node structure. */ -static struct cmd_node rip_node = -{ -  RIP_NODE, -  "%s(config-router)# ", -  1 -}; +	ri = ifp->info; -/* Distribute-list update functions. */ -static void -rip_distribute_update (struct distribute *dist) -{ -  struct interface *ifp; -  struct rip_interface *ri; -  struct access_list *alist; -  struct prefix_list *plist; - -  if (! dist->ifname) -    return; - -  ifp = if_lookup_by_name (dist->ifname, VRF_DEFAULT); -  if (ifp == NULL) -    return; - -  ri = ifp->info; - -  if (dist->list[DISTRIBUTE_V4_IN]) -    { -      alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_IN]); -      if (alist) -	ri->list[RIP_FILTER_IN] = alist; -      else -	ri->list[RIP_FILTER_IN] = NULL; -    } -  else -    ri->list[RIP_FILTER_IN] = NULL; - -  if (dist->list[DISTRIBUTE_V4_OUT]) -    { -      alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_V4_OUT]); -      if (alist) -	ri->list[RIP_FILTER_OUT] = alist; -      else -	ri->list[RIP_FILTER_OUT] = NULL; -    } -  else -    ri->list[RIP_FILTER_OUT] = NULL; - -  if (dist->prefix[DISTRIBUTE_V4_IN]) -    { -      plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_IN]); -      if (plist) -	ri->prefix[RIP_FILTER_IN] = plist; -      else -	ri->prefix[RIP_FILTER_IN] = NULL; -    } -  else -    ri->prefix[RIP_FILTER_IN] = NULL; - -  if (dist->prefix[DISTRIBUTE_V4_OUT]) -    { -      plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_V4_OUT]); -      if (plist) -	ri->prefix[RIP_FILTER_OUT] = plist; -      else -	ri->prefix[RIP_FILTER_OUT] = NULL; -    } -  else -    ri->prefix[RIP_FILTER_OUT] = NULL; -} - -void -rip_distribute_update_interface (struct interface *ifp) -{ -  struct distribute *dist; - -  dist = distribute_lookup (ifp->name); -  if (dist) -    rip_distribute_update (dist); +	if (dist->list[DISTRIBUTE_V4_IN]) { +		alist = access_list_lookup(AFI_IP, +					   dist->list[DISTRIBUTE_V4_IN]); +		if (alist) +			ri->list[RIP_FILTER_IN] = alist; +		else +			ri->list[RIP_FILTER_IN] = NULL; +	} else +		ri->list[RIP_FILTER_IN] = NULL; + +	if (dist->list[DISTRIBUTE_V4_OUT]) { +		alist = access_list_lookup(AFI_IP, +					   dist->list[DISTRIBUTE_V4_OUT]); +		if (alist) +			ri->list[RIP_FILTER_OUT] = alist; +		else +			ri->list[RIP_FILTER_OUT] = NULL; +	} else +		ri->list[RIP_FILTER_OUT] = NULL; + +	if (dist->prefix[DISTRIBUTE_V4_IN]) { +		plist = prefix_list_lookup(AFI_IP, +					   dist->prefix[DISTRIBUTE_V4_IN]); +		if (plist) +			ri->prefix[RIP_FILTER_IN] = plist; +		else +			ri->prefix[RIP_FILTER_IN] = NULL; +	} else +		ri->prefix[RIP_FILTER_IN] = NULL; + +	if (dist->prefix[DISTRIBUTE_V4_OUT]) { +		plist = prefix_list_lookup(AFI_IP, +					   dist->prefix[DISTRIBUTE_V4_OUT]); +		if (plist) +			ri->prefix[RIP_FILTER_OUT] = plist; +		else +			ri->prefix[RIP_FILTER_OUT] = NULL; +	} else +		ri->prefix[RIP_FILTER_OUT] = NULL; +} + +void rip_distribute_update_interface(struct interface *ifp) +{ +	struct distribute *dist; + +	dist = distribute_lookup(ifp->name); +	if (dist) +		rip_distribute_update(dist);  }  /* Update all interface's distribute list. */  /* ARGSUSED */ -static void -rip_distribute_update_all (struct prefix_list *notused) +static void rip_distribute_update_all(struct prefix_list *notused)  { -  struct interface *ifp; -  struct listnode *node, *nnode; +	struct interface *ifp; +	struct listnode *node, *nnode; -  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), node, nnode, ifp)) -    rip_distribute_update_interface (ifp); +	for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) +		rip_distribute_update_interface(ifp);  }  /* ARGSUSED */ -static void -rip_distribute_update_all_wrapper(struct access_list *notused) +static void rip_distribute_update_all_wrapper(struct access_list *notused)  { -        rip_distribute_update_all(NULL); +	rip_distribute_update_all(NULL);  }  /* Delete all added rip route. */ -void -rip_clean (void) +void rip_clean(void)  { -  int i; -  struct route_node *rp; -  struct rip_info *rinfo = NULL; -  struct list *list = NULL; -  struct listnode *listnode = NULL; +	int i; +	struct route_node *rp; +	struct rip_info *rinfo = NULL; +	struct list *list = NULL; +	struct listnode *listnode = NULL; + +	if (rip) { +		QOBJ_UNREG(rip); + +		/* Clear RIP routes */ +		for (rp = route_top(rip->table); rp; rp = route_next(rp)) +			if ((list = rp->info) != NULL) { +				rinfo = listgetdata(listhead(list)); +				if (rip_route_rte(rinfo)) +					rip_zebra_ipv4_delete(rp); + +				for (ALL_LIST_ELEMENTS_RO(list, listnode, +							  rinfo)) { +					RIP_TIMER_OFF(rinfo->t_timeout); +					RIP_TIMER_OFF(rinfo->t_garbage_collect); +					rip_info_free(rinfo); +				} +				list_delete(list); +				rp->info = NULL; +				route_unlock_node(rp); +			} + +		/* Cancel RIP related timers. */ +		RIP_TIMER_OFF(rip->t_update); +		RIP_TIMER_OFF(rip->t_triggered_update); +		RIP_TIMER_OFF(rip->t_triggered_interval); + +		/* Cancel read thread. */ +		THREAD_READ_OFF(rip->t_read); + +		/* Close RIP socket. */ +		if (rip->sock >= 0) { +			close(rip->sock); +			rip->sock = -1; +		} -  if (rip) -    { -      QOBJ_UNREG (rip); - -      /* Clear RIP routes */ -      for (rp = route_top (rip->table); rp; rp = route_next (rp)) -        if ((list = rp->info) != NULL) -          { -            rinfo = listgetdata (listhead (list)); -            if (rip_route_rte (rinfo)) -              rip_zebra_ipv4_delete (rp); - -            for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo)) -              { -                RIP_TIMER_OFF (rinfo->t_timeout); -                RIP_TIMER_OFF (rinfo->t_garbage_collect); -                rip_info_free (rinfo); -              } -            list_delete (list); -            rp->info = NULL; -            route_unlock_node (rp); -          } - -      /* Cancel RIP related timers. */ -      RIP_TIMER_OFF (rip->t_update); -      RIP_TIMER_OFF (rip->t_triggered_update); -      RIP_TIMER_OFF (rip->t_triggered_interval); - -      /* Cancel read thread. */ -      THREAD_READ_OFF (rip->t_read); - -      /* Close RIP socket. */ -      if (rip->sock >= 0) -	{ -	  close (rip->sock); -	  rip->sock = -1; -	} - -      /* Static RIP route configuration. */ -      for (rp = route_top (rip->route); rp; rp = route_next (rp)) -	if (rp->info) -	  { -	    rp->info = NULL; -	    route_unlock_node (rp); -	  } - -      /* RIP neighbor configuration. */ -      for (rp = route_top (rip->neighbor); rp; rp = route_next (rp)) -	if (rp->info) -	  { -	    rp->info = NULL; -	    route_unlock_node (rp); -	  } - -      /* Redistribute related clear. */ -      if (rip->default_information_route_map) -	free (rip->default_information_route_map); - -      for (i = 0; i < ZEBRA_ROUTE_MAX; i++) -	if (rip->route_map[i].name) -	  free (rip->route_map[i].name); - -      XFREE (MTYPE_ROUTE_TABLE, rip->table); -      XFREE (MTYPE_ROUTE_TABLE, rip->route); -      XFREE (MTYPE_ROUTE_TABLE, rip->neighbor); -       -      XFREE (MTYPE_RIP, rip); -      rip = NULL; -    } - -  rip_clean_network (); -  rip_passive_nondefault_clean (); -  rip_offset_clean (); -  rip_interfaces_clean (); -  rip_distance_reset (); -  rip_redistribute_clean (); +		/* Static RIP route configuration. */ +		for (rp = route_top(rip->route); rp; rp = route_next(rp)) +			if (rp->info) { +				rp->info = NULL; +				route_unlock_node(rp); +			} + +		/* RIP neighbor configuration. */ +		for (rp = route_top(rip->neighbor); rp; rp = route_next(rp)) +			if (rp->info) { +				rp->info = NULL; +				route_unlock_node(rp); +			} + +		/* Redistribute related clear. */ +		if (rip->default_information_route_map) +			free(rip->default_information_route_map); + +		for (i = 0; i < ZEBRA_ROUTE_MAX; i++) +			if (rip->route_map[i].name) +				free(rip->route_map[i].name); + +		XFREE(MTYPE_ROUTE_TABLE, rip->table); +		XFREE(MTYPE_ROUTE_TABLE, rip->route); +		XFREE(MTYPE_ROUTE_TABLE, rip->neighbor); + +		XFREE(MTYPE_RIP, rip); +		rip = NULL; +	} + +	rip_clean_network(); +	rip_passive_nondefault_clean(); +	rip_offset_clean(); +	rip_interfaces_clean(); +	rip_distance_reset(); +	rip_redistribute_clean();  }  /* Reset all values to the default settings. */ -void -rip_reset (void) +void rip_reset(void)  { -  /* Reset global counters. */ -  rip_global_route_changes = 0; -  rip_global_queries = 0; +	/* Reset global counters. */ +	rip_global_route_changes = 0; +	rip_global_queries = 0; -  /* Call ripd related reset functions. */ -  rip_debug_reset (); -  rip_route_map_reset (); +	/* Call ripd related reset functions. */ +	rip_debug_reset(); +	rip_route_map_reset(); -  /* Call library reset functions. */ -  vty_reset (); -  access_list_reset (); -  prefix_list_reset (); +	/* Call library reset functions. */ +	vty_reset(); +	access_list_reset(); +	prefix_list_reset(); -  distribute_list_reset (); +	distribute_list_reset(); -  rip_interfaces_reset (); -  rip_distance_reset (); +	rip_interfaces_reset(); +	rip_distance_reset(); -  rip_zclient_reset (); +	rip_zclient_reset();  } -static void -rip_if_rmap_update (struct if_rmap *if_rmap) +static void rip_if_rmap_update(struct if_rmap *if_rmap)  { -  struct interface *ifp; -  struct rip_interface *ri; -  struct route_map *rmap; +	struct interface *ifp; +	struct rip_interface *ri; +	struct route_map *rmap; -  ifp = if_lookup_by_name (if_rmap->ifname, VRF_DEFAULT); -  if (ifp == NULL) -    return; +	ifp = if_lookup_by_name(if_rmap->ifname, VRF_DEFAULT); +	if (ifp == NULL) +		return; -  ri = ifp->info; +	ri = ifp->info; -  if (if_rmap->routemap[IF_RMAP_IN]) -    { -      rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_IN]); -      if (rmap) -	ri->routemap[IF_RMAP_IN] = rmap; -      else -	ri->routemap[IF_RMAP_IN] = NULL; -    } -  else -    ri->routemap[RIP_FILTER_IN] = NULL; +	if (if_rmap->routemap[IF_RMAP_IN]) { +		rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_IN]); +		if (rmap) +			ri->routemap[IF_RMAP_IN] = rmap; +		else +			ri->routemap[IF_RMAP_IN] = NULL; +	} else +		ri->routemap[RIP_FILTER_IN] = NULL; -  if (if_rmap->routemap[IF_RMAP_OUT]) -    { -      rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_OUT]); -      if (rmap) -	ri->routemap[IF_RMAP_OUT] = rmap; -      else -	ri->routemap[IF_RMAP_OUT] = NULL; -    } -  else -    ri->routemap[RIP_FILTER_OUT] = NULL; +	if (if_rmap->routemap[IF_RMAP_OUT]) { +		rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_OUT]); +		if (rmap) +			ri->routemap[IF_RMAP_OUT] = rmap; +		else +			ri->routemap[IF_RMAP_OUT] = NULL; +	} else +		ri->routemap[RIP_FILTER_OUT] = NULL;  } -void -rip_if_rmap_update_interface (struct interface *ifp) +void rip_if_rmap_update_interface(struct interface *ifp)  { -  struct if_rmap *if_rmap; +	struct if_rmap *if_rmap; -  if_rmap = if_rmap_lookup (ifp->name); -  if (if_rmap) -    rip_if_rmap_update (if_rmap); +	if_rmap = if_rmap_lookup(ifp->name); +	if (if_rmap) +		rip_if_rmap_update(if_rmap);  } -static void -rip_routemap_update_redistribute (void) +static void rip_routemap_update_redistribute(void)  { -  int i; +	int i; -  if (rip) -    { -      for (i = 0; i < ZEBRA_ROUTE_MAX; i++)  -	{ -	  if (rip->route_map[i].name) -	    rip->route_map[i].map =  -	      route_map_lookup_by_name (rip->route_map[i].name); +	if (rip) { +		for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { +			if (rip->route_map[i].name) +				rip->route_map[i].map = +					route_map_lookup_by_name( +						rip->route_map[i].name); +		}  	} -    }  }  /* ARGSUSED */ -static void -rip_routemap_update (const char *notused) +static void rip_routemap_update(const char *notused)  { -  struct interface *ifp; -  struct listnode *node, *nnode; +	struct interface *ifp; +	struct listnode *node, *nnode; -  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), node, nnode, ifp)) -    rip_if_rmap_update_interface (ifp); +	for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) +		rip_if_rmap_update_interface(ifp); -  rip_routemap_update_redistribute (); +	rip_routemap_update_redistribute();  }  /* Allocate new rip structure and set default value. */ -void -rip_init (void) -{ -  /* Install top nodes. */ -  install_node (&rip_node, config_write_rip); - -  /* Install rip commands. */ -  install_element (VIEW_NODE, &show_ip_rip_cmd); -  install_element (VIEW_NODE, &show_ip_rip_status_cmd); -  install_element (CONFIG_NODE, &router_rip_cmd); -  install_element (CONFIG_NODE, &no_router_rip_cmd); - -  install_default (RIP_NODE); -  install_element (RIP_NODE, &rip_version_cmd); -  install_element (RIP_NODE, &no_rip_version_cmd); -  install_element (RIP_NODE, &rip_default_metric_cmd); -  install_element (RIP_NODE, &no_rip_default_metric_cmd); -  install_element (RIP_NODE, &rip_timers_cmd); -  install_element (RIP_NODE, &no_rip_timers_cmd); -  install_element (RIP_NODE, &rip_route_cmd); -  install_element (RIP_NODE, &no_rip_route_cmd); -  install_element (RIP_NODE, &rip_distance_cmd); -  install_element (RIP_NODE, &no_rip_distance_cmd); -  install_element (RIP_NODE, &rip_distance_source_cmd); -  install_element (RIP_NODE, &no_rip_distance_source_cmd); -  install_element (RIP_NODE, &rip_distance_source_access_list_cmd); -  install_element (RIP_NODE, &no_rip_distance_source_access_list_cmd); -  install_element (RIP_NODE, &rip_allow_ecmp_cmd); -  install_element (RIP_NODE, &no_rip_allow_ecmp_cmd); - -  /* Debug related init. */ -  rip_debug_init (); - -  /* Access list install. */ -  access_list_init (); -  access_list_add_hook (rip_distribute_update_all_wrapper); -  access_list_delete_hook (rip_distribute_update_all_wrapper); - -  /* Prefix list initialize.*/ -  prefix_list_init (); -  prefix_list_add_hook (rip_distribute_update_all); -  prefix_list_delete_hook (rip_distribute_update_all); - -  /* Distribute list install. */ -  distribute_list_init (RIP_NODE); -  distribute_list_add_hook (rip_distribute_update); -  distribute_list_delete_hook (rip_distribute_update); - -  /* Route-map */ -  rip_route_map_init (); -  rip_offset_init (); - -  route_map_add_hook (rip_routemap_update); -  route_map_delete_hook (rip_routemap_update); - -  if_rmap_init (RIP_NODE); -  if_rmap_hook_add (rip_if_rmap_update); -  if_rmap_hook_delete (rip_if_rmap_update); - -  /* Distance control. */ -  rip_distance_table = route_table_init (); +void rip_init(void) +{ +	/* Install top nodes. */ +	install_node(&rip_node, config_write_rip); + +	/* Install rip commands. */ +	install_element(VIEW_NODE, &show_ip_rip_cmd); +	install_element(VIEW_NODE, &show_ip_rip_status_cmd); +	install_element(CONFIG_NODE, &router_rip_cmd); +	install_element(CONFIG_NODE, &no_router_rip_cmd); + +	install_default(RIP_NODE); +	install_element(RIP_NODE, &rip_version_cmd); +	install_element(RIP_NODE, &no_rip_version_cmd); +	install_element(RIP_NODE, &rip_default_metric_cmd); +	install_element(RIP_NODE, &no_rip_default_metric_cmd); +	install_element(RIP_NODE, &rip_timers_cmd); +	install_element(RIP_NODE, &no_rip_timers_cmd); +	install_element(RIP_NODE, &rip_route_cmd); +	install_element(RIP_NODE, &no_rip_route_cmd); +	install_element(RIP_NODE, &rip_distance_cmd); +	install_element(RIP_NODE, &no_rip_distance_cmd); +	install_element(RIP_NODE, &rip_distance_source_cmd); +	install_element(RIP_NODE, &no_rip_distance_source_cmd); +	install_element(RIP_NODE, &rip_distance_source_access_list_cmd); +	install_element(RIP_NODE, &no_rip_distance_source_access_list_cmd); +	install_element(RIP_NODE, &rip_allow_ecmp_cmd); +	install_element(RIP_NODE, &no_rip_allow_ecmp_cmd); + +	/* Debug related init. */ +	rip_debug_init(); + +	/* Access list install. */ +	access_list_init(); +	access_list_add_hook(rip_distribute_update_all_wrapper); +	access_list_delete_hook(rip_distribute_update_all_wrapper); + +	/* Prefix list initialize.*/ +	prefix_list_init(); +	prefix_list_add_hook(rip_distribute_update_all); +	prefix_list_delete_hook(rip_distribute_update_all); + +	/* Distribute list install. */ +	distribute_list_init(RIP_NODE); +	distribute_list_add_hook(rip_distribute_update); +	distribute_list_delete_hook(rip_distribute_update); + +	/* Route-map */ +	rip_route_map_init(); +	rip_offset_init(); + +	route_map_add_hook(rip_routemap_update); +	route_map_delete_hook(rip_routemap_update); + +	if_rmap_init(RIP_NODE); +	if_rmap_hook_add(rip_if_rmap_update); +	if_rmap_hook_delete(rip_if_rmap_update); + +	/* Distance control. */ +	rip_distance_table = route_table_init();  } diff --git a/ripd/ripd.h b/ripd/ripd.h index a8e65d1236..895a48c3db 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -98,255 +98,245 @@  #define RIP_AUTH_MD5_COMPAT_SIZE        RIP_RTE_SIZE  /* RIP structure. */ -struct rip  -{ -  /* RIP socket. */ -  int sock; - -  /* Default version of rip instance. */ -  int version_send;	/* version 1 or 2 (but not both) */ -  int version_recv;	/* version 1 or 2 or both */ - -  /* Output buffer of RIP. */ -  struct stream *obuf; - -  /* RIP routing information base. */ -  struct route_table *table; - -  /* RIP only static routing information. */ -  struct route_table *route; -   -  /* RIP neighbor. */ -  struct route_table *neighbor; -   -  /* RIP threads. */ -  struct thread *t_read; - -  /* Update and garbage timer. */ -  struct thread *t_update; - -  /* Triggered update hack. */ -  int trigger; -  struct thread *t_triggered_update; -  struct thread *t_triggered_interval; - -  /* RIP timer values. */ -  unsigned long update_time; -  unsigned long timeout_time; -  unsigned long garbage_time; - -  /* RIP default metric. */ -  int default_metric; - -  /* RIP default-information originate. */ -  u_char default_information; -  char *default_information_route_map; - -  /* RIP default distance. */ -  u_char distance; -  struct route_table *distance_table; - -  /* RIP ECMP flag */ -  unsigned int ecmp; - -  /* For redistribute route map. */ -  struct -  { -    char *name; -    struct route_map *map; -    int metric_config; -    u_int32_t metric; -  } route_map[ZEBRA_ROUTE_MAX]; - -  QOBJ_FIELDS +struct rip { +	/* RIP socket. */ +	int sock; + +	/* Default version of rip instance. */ +	int version_send; /* version 1 or 2 (but not both) */ +	int version_recv; /* version 1 or 2 or both */ + +	/* Output buffer of RIP. */ +	struct stream *obuf; + +	/* RIP routing information base. */ +	struct route_table *table; + +	/* RIP only static routing information. */ +	struct route_table *route; + +	/* RIP neighbor. */ +	struct route_table *neighbor; + +	/* RIP threads. */ +	struct thread *t_read; + +	/* Update and garbage timer. */ +	struct thread *t_update; + +	/* Triggered update hack. */ +	int trigger; +	struct thread *t_triggered_update; +	struct thread *t_triggered_interval; + +	/* RIP timer values. */ +	unsigned long update_time; +	unsigned long timeout_time; +	unsigned long garbage_time; + +	/* RIP default metric. */ +	int default_metric; + +	/* RIP default-information originate. */ +	u_char default_information; +	char *default_information_route_map; + +	/* RIP default distance. */ +	u_char distance; +	struct route_table *distance_table; + +	/* RIP ECMP flag */ +	unsigned int ecmp; + +	/* For redistribute route map. */ +	struct { +		char *name; +		struct route_map *map; +		int metric_config; +		u_int32_t metric; +	} route_map[ZEBRA_ROUTE_MAX]; + +	QOBJ_FIELDS  };  DECLARE_QOBJ_TYPE(rip)  /* RIP routing table entry which belong to rip_packet. */ -struct rte -{ -  u_int16_t family;		/* Address family of this route. */ -  u_int16_t tag;		/* Route Tag which included in RIP2 packet. */ -  struct in_addr prefix;	/* Prefix of rip route. */ -  struct in_addr mask;		/* Netmask of rip route. */ -  struct in_addr nexthop;	/* Next hop of rip route. */ -  u_int32_t metric;		/* Metric value of rip route. */ +struct rte { +	u_int16_t family;       /* Address family of this route. */ +	u_int16_t tag;		/* Route Tag which included in RIP2 packet. */ +	struct in_addr prefix;  /* Prefix of rip route. */ +	struct in_addr mask;    /* Netmask of rip route. */ +	struct in_addr nexthop; /* Next hop of rip route. */ +	u_int32_t metric;       /* Metric value of rip route. */  };  /* RIP packet structure. */ -struct rip_packet -{ -  unsigned char command;	/* Command type of RIP packet. */ -  unsigned char version;	/* RIP version which coming from peer. */ -  unsigned char pad1;		/* Padding of RIP packet header. */ -  unsigned char pad2;		/* Same as above. */ -  struct rte rte[1];		/* Address structure. */ +struct rip_packet { +	unsigned char command; /* Command type of RIP packet. */ +	unsigned char version; /* RIP version which coming from peer. */ +	unsigned char pad1;    /* Padding of RIP packet header. */ +	unsigned char pad2;    /* Same as above. */ +	struct rte rte[1];     /* Address structure. */  };  /* Buffer to read RIP packet. */ -union rip_buf -{ -  struct rip_packet rip_packet; -  char buf[RIP_PACKET_MAXSIZ]; +union rip_buf { +	struct rip_packet rip_packet; +	char buf[RIP_PACKET_MAXSIZ];  };  /* RIP route information. */ -struct rip_info -{ -  /* This route's type. */ -  int type; +struct rip_info { +	/* This route's type. */ +	int type; -  /* Sub type. */ -  int sub_type; +	/* Sub type. */ +	int sub_type; -  /* RIP nexthop. */ -  struct in_addr nexthop; -  struct in_addr from; +	/* RIP nexthop. */ +	struct in_addr nexthop; +	struct in_addr from; -  /* Which interface does this route come from. */ -  ifindex_t ifindex; +	/* Which interface does this route come from. */ +	ifindex_t ifindex; -  /* Metric of this route. */ -  u_int32_t metric; +	/* Metric of this route. */ +	u_int32_t metric; -  /* External metric of this route.  -     if learnt from an externalm proto */ -  u_int32_t external_metric; +	/* External metric of this route. +	   if learnt from an externalm proto */ +	u_int32_t external_metric; -  /* Tag information of this route. */ -  u_int16_t tag; +	/* Tag information of this route. */ +	u_int16_t tag; -  /* Flags of RIP route. */ +/* Flags of RIP route. */  #define RIP_RTF_FIB      1  #define RIP_RTF_CHANGED  2 -  u_char flags; +	u_char flags; -  /* Garbage collect timer. */ -  struct thread *t_timeout; -  struct thread *t_garbage_collect; +	/* Garbage collect timer. */ +	struct thread *t_timeout; +	struct thread *t_garbage_collect; -  /* Route-map futures - this variables can be changed. */ -  struct in_addr nexthop_out; -  u_char metric_set; -  u_int32_t metric_out; -  u_int16_t tag_out; -  ifindex_t ifindex_out; +	/* Route-map futures - this variables can be changed. */ +	struct in_addr nexthop_out; +	u_char metric_set; +	u_int32_t metric_out; +	u_int16_t tag_out; +	ifindex_t ifindex_out; -  struct route_node *rp; +	struct route_node *rp; -  u_char distance; +	u_char distance;  #ifdef NEW_RIP_TABLE -  struct rip_info *next; -  struct rip_info *prev; +	struct rip_info *next; +	struct rip_info *prev;  #endif /* NEW_RIP_TABLE */  };  typedef enum { -  RIP_NO_SPLIT_HORIZON = 0, -  RIP_SPLIT_HORIZON, -  RIP_SPLIT_HORIZON_POISONED_REVERSE +	RIP_NO_SPLIT_HORIZON = 0, +	RIP_SPLIT_HORIZON, +	RIP_SPLIT_HORIZON_POISONED_REVERSE  } split_horizon_policy_t;  /* RIP specific interface configuration. */ -struct rip_interface -{ -  /* RIP is enabled on this interface. */ -  int enable_network; -  int enable_interface; +struct rip_interface { +	/* RIP is enabled on this interface. */ +	int enable_network; +	int enable_interface; -  /* RIP is running on this interface. */ -  int running; +	/* RIP is running on this interface. */ +	int running; -  /* RIP version control. */ -  int ri_send; -  int ri_receive; +	/* RIP version control. */ +	int ri_send; +	int ri_receive; -  /* RIPv2 broadcast mode */ -  int v2_broadcast; +	/* RIPv2 broadcast mode */ +	int v2_broadcast; -  /* RIPv2 authentication type. */ -  int auth_type; +	/* RIPv2 authentication type. */ +	int auth_type; -  /* RIPv2 authentication string. */ -  char *auth_str; +	/* RIPv2 authentication string. */ +	char *auth_str; -  /* RIPv2 authentication key chain. */ -  char *key_chain; +	/* RIPv2 authentication key chain. */ +	char *key_chain; -  /* value to use for md5->auth_len */ -  u_int8_t md5_auth_len; +	/* value to use for md5->auth_len */ +	u_int8_t md5_auth_len; -  /* Split horizon flag. */ -  split_horizon_policy_t split_horizon; -  split_horizon_policy_t split_horizon_default; +	/* Split horizon flag. */ +	split_horizon_policy_t split_horizon; +	split_horizon_policy_t split_horizon_default; -  /* For filter type slot. */ +/* For filter type slot. */  #define RIP_FILTER_IN  0  #define RIP_FILTER_OUT 1  #define RIP_FILTER_MAX 2 -  /* Access-list. */ -  struct access_list *list[RIP_FILTER_MAX]; +	/* Access-list. */ +	struct access_list *list[RIP_FILTER_MAX]; -  /* Prefix-list. */ -  struct prefix_list *prefix[RIP_FILTER_MAX]; +	/* Prefix-list. */ +	struct prefix_list *prefix[RIP_FILTER_MAX]; -  /* Route-map. */ -  struct route_map *routemap[RIP_FILTER_MAX]; +	/* Route-map. */ +	struct route_map *routemap[RIP_FILTER_MAX]; -  /* Wake up thread. */ -  struct thread *t_wakeup; +	/* Wake up thread. */ +	struct thread *t_wakeup; -  /* Interface statistics. */ -  int recv_badpackets; -  int recv_badroutes; -  int sent_updates; +	/* Interface statistics. */ +	int recv_badpackets; +	int recv_badroutes; +	int sent_updates; -  /* Passive interface. */ -  int passive; +	/* Passive interface. */ +	int passive;  };  /* RIP peer information. */ -struct rip_peer -{ -  /* Peer address. */ -  struct in_addr addr; +struct rip_peer { +	/* Peer address. */ +	struct in_addr addr; -  /* Peer RIP tag value. */ -  int domain; +	/* Peer RIP tag value. */ +	int domain; -  /* Last update time. */ -  time_t uptime; +	/* Last update time. */ +	time_t uptime; -  /* Peer RIP version. */ -  u_char version; +	/* Peer RIP version. */ +	u_char version; -  /* Statistics. */ -  int recv_badpackets; -  int recv_badroutes; +	/* Statistics. */ +	int recv_badpackets; +	int recv_badroutes; -  /* Timeout thread. */ -  struct thread *t_timeout; +	/* Timeout thread. */ +	struct thread *t_timeout;  }; -struct rip_md5_info -{ -  u_int16_t family; -  u_int16_t type; -  u_int16_t packet_len; -  u_char keyid; -  u_char auth_len; -  u_int32_t sequence; -  u_int32_t reserv1; -  u_int32_t reserv2; +struct rip_md5_info { +	u_int16_t family; +	u_int16_t type; +	u_int16_t packet_len; +	u_char keyid; +	u_char auth_len; +	u_int32_t sequence; +	u_int32_t reserv1; +	u_int32_t reserv2;  }; -struct rip_md5_data -{ -  u_int16_t family; -  u_int16_t type; -  u_char digest[16]; +struct rip_md5_data { +	u_int16_t family; +	u_int16_t type; +	u_char digest[16];  };  /* RIP accepet/announce methods. */ @@ -362,11 +352,10 @@ struct rip_md5_data  #define RIP_DEFAULT_METRIC_DEFAULT         1  /* RIP event. */ -enum rip_event  -{ -  RIP_READ, -  RIP_UPDATE_EVENT, -  RIP_TRIGGERED_UPDATE, +enum rip_event { +	RIP_READ, +	RIP_UPDATE_EVENT, +	RIP_TRIGGERED_UPDATE,  };  /* Macro for timer turn on. */ @@ -376,62 +365,64 @@ enum rip_event  #define RIP_TIMER_OFF(X) THREAD_TIMER_OFF(X)  /* Prototypes. */ -extern void rip_init (void); -extern void rip_reset (void); -extern void rip_clean (void); -extern void rip_clean_network (void); -extern void rip_interfaces_clean (void); -extern void rip_interfaces_reset (void); -extern void rip_passive_nondefault_clean (void); -extern void rip_if_init (void); -extern void rip_if_down_all (void); -extern void rip_route_map_init (void); -extern void rip_route_map_reset (void); +extern void rip_init(void); +extern void rip_reset(void); +extern void rip_clean(void); +extern void rip_clean_network(void); +extern void rip_interfaces_clean(void); +extern void rip_interfaces_reset(void); +extern void rip_passive_nondefault_clean(void); +extern void rip_if_init(void); +extern void rip_if_down_all(void); +extern void rip_route_map_init(void); +extern void rip_route_map_reset(void);  extern void rip_zclient_init(struct thread_master *);  extern void rip_zclient_stop(void); -extern void rip_zclient_reset (void); -extern void rip_offset_init (void); -extern int if_check_address (struct in_addr addr); - -extern int rip_request_send (struct sockaddr_in *, struct interface *, u_char, -                      struct connected *); -extern int rip_neighbor_lookup (struct sockaddr_in *); - -extern int rip_redistribute_check (int); -extern void rip_redistribute_add (int, int, struct prefix_ipv4 *, ifindex_t, -			   struct in_addr *, unsigned int, unsigned char, -			   route_tag_t); -extern void rip_redistribute_delete (int, int, struct prefix_ipv4 *, ifindex_t); -extern void rip_redistribute_withdraw (int); -extern void rip_zebra_ipv4_add (struct route_node *); -extern void rip_zebra_ipv4_delete (struct route_node *); -extern void rip_interface_multicast_set (int, struct connected *); -extern void rip_distribute_update_interface (struct interface *); -extern void rip_if_rmap_update_interface (struct interface *); - -extern int config_write_rip_network (struct vty *, int); -extern int config_write_rip_offset_list (struct vty *); -extern int config_write_rip_redistribute (struct vty *, int); - -extern void rip_peer_init (void); -extern void rip_peer_update (struct sockaddr_in *, u_char); -extern void rip_peer_bad_route (struct sockaddr_in *); -extern void rip_peer_bad_packet (struct sockaddr_in *); -extern void rip_peer_display (struct vty *); -extern struct rip_peer *rip_peer_lookup (struct in_addr *); -extern struct rip_peer *rip_peer_lookup_next (struct in_addr *); - -extern int rip_offset_list_apply_in (struct prefix_ipv4 *, struct interface *, u_int32_t *); -extern int rip_offset_list_apply_out (struct prefix_ipv4 *, struct interface *, u_int32_t *); -extern void rip_offset_clean (void); - -extern void rip_info_free (struct rip_info *); -extern u_char rip_distance_apply (struct rip_info *); -extern void rip_redistribute_clean (void); - -extern struct rip_info *rip_ecmp_add (struct rip_info *); -extern struct rip_info *rip_ecmp_replace (struct rip_info *); -extern struct rip_info *rip_ecmp_delete (struct rip_info *); +extern void rip_zclient_reset(void); +extern void rip_offset_init(void); +extern int if_check_address(struct in_addr addr); + +extern int rip_request_send(struct sockaddr_in *, struct interface *, u_char, +			    struct connected *); +extern int rip_neighbor_lookup(struct sockaddr_in *); + +extern int rip_redistribute_check(int); +extern void rip_redistribute_add(int, int, struct prefix_ipv4 *, ifindex_t, +				 struct in_addr *, unsigned int, unsigned char, +				 route_tag_t); +extern void rip_redistribute_delete(int, int, struct prefix_ipv4 *, ifindex_t); +extern void rip_redistribute_withdraw(int); +extern void rip_zebra_ipv4_add(struct route_node *); +extern void rip_zebra_ipv4_delete(struct route_node *); +extern void rip_interface_multicast_set(int, struct connected *); +extern void rip_distribute_update_interface(struct interface *); +extern void rip_if_rmap_update_interface(struct interface *); + +extern int config_write_rip_network(struct vty *, int); +extern int config_write_rip_offset_list(struct vty *); +extern int config_write_rip_redistribute(struct vty *, int); + +extern void rip_peer_init(void); +extern void rip_peer_update(struct sockaddr_in *, u_char); +extern void rip_peer_bad_route(struct sockaddr_in *); +extern void rip_peer_bad_packet(struct sockaddr_in *); +extern void rip_peer_display(struct vty *); +extern struct rip_peer *rip_peer_lookup(struct in_addr *); +extern struct rip_peer *rip_peer_lookup_next(struct in_addr *); + +extern int rip_offset_list_apply_in(struct prefix_ipv4 *, struct interface *, +				    u_int32_t *); +extern int rip_offset_list_apply_out(struct prefix_ipv4 *, struct interface *, +				     u_int32_t *); +extern void rip_offset_clean(void); + +extern void rip_info_free(struct rip_info *); +extern u_char rip_distance_apply(struct rip_info *); +extern void rip_redistribute_clean(void); + +extern struct rip_info *rip_ecmp_add(struct rip_info *); +extern struct rip_info *rip_ecmp_replace(struct rip_info *); +extern struct rip_info *rip_ecmp_delete(struct rip_info *);  /* There is only one rip strucutre. */  extern struct rip *rip; @@ -443,7 +434,7 @@ extern struct thread_master *master;  extern long rip_global_route_changes;  extern long rip_global_queries; -DECLARE_HOOK(rip_ifaddr_add, (struct connected *ifc), (ifc)) -DECLARE_HOOK(rip_ifaddr_del, (struct connected *ifc), (ifc)) +DECLARE_HOOK(rip_ifaddr_add, (struct connected * ifc), (ifc)) +DECLARE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc))  #endif /* _ZEBRA_RIP_H */  | 
