diff options
| -rw-r--r-- | ripd/ChangeLog | 12 | ||||
| -rw-r--r-- | ripd/rip_interface.c | 30 | ||||
| -rw-r--r-- | ripd/ripd.c | 216 | 
3 files changed, 125 insertions, 133 deletions
| diff --git a/ripd/ChangeLog b/ripd/ChangeLog index ae67e72d..8618cb6f 100644 --- a/ripd/ChangeLog +++ b/ripd/ChangeLog @@ -1,3 +1,15 @@ +2004-10-22 Paul Jakma <paul@dishone.st> + +	* ripd.c: Collapse redundant passing of various address structs, +          struct interface and struct connected as arguments to functions +          down to two key arguments, namely struct connected and, possibly, +          address of source/destination. Testing for RIPv1 would be useful. +          (rip_read) lookup struct connected for the received packet, pass +          it on. +        * rip_interface.c: With previous changes, we no longer have to tread +          carefully with struct connected, as it will always be there and +          valid. +  2004-10-19 Andrew J. Schorr <aschorr@telemetry-investments.com>  	* ripd.c: (rip_update_interface) if connected->destination is NULL, diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 19f6f114..c1c0a45a 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -145,19 +145,15 @@ rip_interface_multicast_set (int sock, struct connected *connected)    struct sockaddr_in from;    struct in_addr addr;    struct prefix_ipv4 *p; - -  if (connected != NULL)  -    { -      if (if_is_pointopoint(connected->ifp) && CONNECTED_DEST_HOST(connected)) -	p = (struct prefix_ipv4 *) connected->destination; -      else -	p = (struct prefix_ipv4 *) connected->address; -      addr = p->prefix; -    } -  else  -    { -      addr.s_addr = INADDR_ANY; -    } +   +  assert (connected != NULL); +   +  if (if_is_pointopoint(connected->ifp) && CONNECTED_DEST_HOST(connected)) +    p = (struct prefix_ipv4 *) connected->destination; +  else +    p = (struct prefix_ipv4 *) connected->address; +   +  addr = p->prefix;    if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,                                    connected->ifp->ifindex) < 0)  @@ -165,7 +161,7 @@ rip_interface_multicast_set (int sock, struct connected *connected)        zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "  		 "source address %s for interface %s",  		 sock, inet_ntoa(addr), -		 (connected ? connected->ifp->name : "(unknown)")); +		 connected->ifp->name);        return;      } @@ -181,9 +177,7 @@ rip_interface_multicast_set (int sock, struct connected *connected)    /* Address should be any address. */    from.sin_family = AF_INET; -  if (connected) -    addr = ((struct prefix_ipv4 *) connected->address)->prefix; -  from.sin_addr = addr; +  from.sin_addr = connected->address->u.prefix4;  #ifdef HAVE_SIN_LEN    from.sin_len = sizeof (struct sockaddr_in);  #endif /* HAVE_SIN_LEN */ @@ -198,7 +192,7 @@ rip_interface_multicast_set (int sock, struct connected *connected)  		 "interface %s: %s",  	      	 sock,inet_ntoa(from.sin_addr),  		 (int)ntohs(from.sin_port), -		 (connected ? connected->ifp->name : "(unknown)"), +		 connected->ifp->name,  		  strerror (errno));      } diff --git a/ripd/ripd.c b/ripd/ripd.c index 94324f03..0f854cf3 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -64,9 +64,7 @@ long rip_global_queries = 0;  /* Prototypes. */  void rip_event (enum rip_event, int); -void rip_output_process (struct interface *, struct prefix *, -			 struct sockaddr_in *, int, u_char,  -                         struct connected *, struct prefix_ipv4 *); +void rip_output_process (struct connected *, struct sockaddr_in *, int, u_char);  /* RIP output routes type. */  enum @@ -1042,13 +1040,12 @@ rip_auth_md5_set (struct stream *s, struct interface *ifp)  /* RIP routing information. */  void  rip_response_process (struct rip_packet *packet, int size,  -		      struct sockaddr_in *from, struct interface *ifp) +		      struct sockaddr_in *from, struct connected *ifc)  {    caddr_t lim;    struct rte *rte;    struct prefix_ipv4 ifaddr;    struct prefix_ipv4 ifaddrclass; -  struct connected *c;    int subnetted;    /* We don't know yet. */ @@ -1207,18 +1204,14 @@ rip_response_process (struct rip_packet *packet, int size,  	  u_int32_t destination;  	  if (subnetted == -1) -	    { -	      c = connected_lookup_address (ifp, from->sin_addr); -	      if (c != NULL) -		{ -		  memcpy (&ifaddr, c->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; -		} -	    } +            { +              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); @@ -1277,18 +1270,23 @@ rip_response_process (struct rip_packet *packet, int size,  	}        /* Routing table updates. */ -      rip_rte_process (rte, from, ifp); +      rip_rte_process (rte, from, ifc->ifp);      }  } -/* RIP packet send to destination address. */ +/* 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 + */  int -rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,  -		 struct interface *ifp, struct connected *connected) +rip_send_packet (u_char * buf, int size, struct sockaddr_in *to, +                 struct connected *ifc)  {    int ret, send_sock;    struct sockaddr_in sin; - +   +  assert (ifc != NULL); +      if (IS_RIP_DEBUG_PACKET)      {        char dst[20]; @@ -1302,10 +1300,10 @@ rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,            strcpy(dst, inet_ntoa(sin.sin_addr));          }        zlog_info("rip_send_packet %s > %s (%s)", -                (connected ? inet_ntoa(connected->address->u.prefix4) : ""), -                dst, ifp->name); +                inet_ntoa(ifc->address->u.prefix4), +                dst, ifc->ifp->name);      } -  if (connected && connected->flags & ZEBRA_IFA_SECONDARY) +  if ( CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY) )      {        /*         * ZEBRA_IFA_SECONDARY is set on linux when an interface is configured @@ -1361,7 +1359,7 @@ rip_send_packet (u_char * buf, int size, struct sockaddr_in *to,  #ifdef RIP_RECVMSG        setsockopt_pktinfo (send_sock);  #endif /* RIP_RECVMSG */ -      rip_interface_multicast_set (send_sock, connected); +      rip_interface_multicast_set (send_sock, ifc);      }    ret = sendto (send_sock, buf, size, 0, (struct sockaddr *)&sin, @@ -1507,7 +1505,7 @@ rip_redistribute_delete (int type, int sub_type, struct prefix_ipv4 *p,  /* Response to request called from rip_read ().*/  void  rip_request_process (struct rip_packet *packet, int size,  -		     struct sockaddr_in *from, struct interface *ifp) +		     struct sockaddr_in *from, struct connected *ifc)  {    caddr_t lim;    struct rte *rte; @@ -1517,18 +1515,18 @@ rip_request_process (struct rip_packet *packet, int size,    struct rip_interface *ri;    /* Does not reponse to the requests on the loopback interfaces */ -  if (if_is_loopback (ifp)) +  if (if_is_loopback (ifc->ifp))      return;    /* Check RIP process is enabled on this interface. */ -  ri = ifp->info; +  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); @@ -1559,8 +1557,7 @@ rip_request_process (struct rip_packet *packet, int size,        saddr.prefix = from->sin_addr;        /* All route with split horizon */ -      rip_output_process (ifp, NULL, from, rip_all_route, packet->version,  -                          NULL, &saddr); +      rip_output_process (ifc, from, rip_all_route, packet->version);      }    else      { @@ -1592,7 +1589,7 @@ rip_request_process (struct rip_packet *packet, int size,  	}        packet->command = RIP_RESPONSE; -      rip_send_packet ((u_char *)packet, size, from, ifp, NULL); +      rip_send_packet ((u_char *)packet, size, from, ifc);      }    rip_global_queries++;  } @@ -1686,6 +1683,7 @@ rip_read (struct thread *t)    int len;    socklen_t fromlen;    struct interface *ifp; +  struct connected *ifc;    struct rip_interface *ri;    /* Fetch socket then register myself. */ @@ -1717,7 +1715,7 @@ rip_read (struct thread *t)    /* Which interface is this packet comes from. */    ifp = if_lookup_address (from.sin_addr); - +      /* RIP packet received */    if (IS_RIP_DEBUG_EVENT)      zlog_info ("RECV packet from %s port %d on %s", @@ -1727,7 +1725,15 @@ rip_read (struct thread *t)    /* If this packet come from unknown interface, ignore it. */    if (ifp == NULL)      { -      zlog_info ("packet comes from unknown interface"); +      zlog_info ("rip_read: packet comes from unknown interface"); +      return -1; +    } +   +  ifc = connected_lookup_address (ifp, from.sin_addr); +   +  if (ifc == NULL) +    { +      zlog_info ("rip_read: packet comes from unknown network");        return -1;      } @@ -1924,11 +1930,11 @@ rip_read (struct thread *t)    switch (packet->command)      {      case RIP_RESPONSE: -      rip_response_process (packet, len, &from, ifp); +      rip_response_process (packet, len, &from, ifc);        break;      case RIP_REQUEST:      case RIP_POLL: -      rip_request_process (packet, len, &from, ifp); +      rip_request_process (packet, len, &from, ifc);        break;      case RIP_TRACEON:      case RIP_TRACEOFF: @@ -2094,9 +2100,8 @@ rip_write_rte (int num, struct stream *s, struct prefix_ipv4 *p,  /* Send update to the ifp or spcified neighbor. */  void -rip_output_process (struct interface *ifp, struct prefix *ifaddr, -		    struct sockaddr_in *to, int route_type, u_char version, -                    struct connected *connected, struct prefix_ipv4 *saddr) +rip_output_process (struct connected *ifc, struct sockaddr_in *to,  +                    int route_type, u_char version)  {    int ret;    struct stream *s; @@ -2106,7 +2111,6 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,    struct prefix_ipv4 *p;    struct prefix_ipv4 classfull;    struct prefix_ipv4 ifaddrclass; -  struct connected *c;    int num;    int rtemax;    int subnetted = 0; @@ -2118,7 +2122,7 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,  	zlog_info ("update routes to neighbor %s", inet_ntoa (to->sin_addr));        else  	zlog_info ("update routes on interface %s ifindex %d", -		   ifp->name, ifp->ifindex); +		   ifc->ifp->name, ifc->ifp->ifindex);      }    /* Set output stream. */ @@ -2130,7 +2134,7 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,    rtemax = (RIP_PACKET_MAXSIZ - 4) / 20;    /* Get RIP interface. */ -  ri = ifp->info; +  ri = ifc->ifp->info;    /* If output interface is in simple password authentication mode, we       need space for authentication data.  */ @@ -2162,22 +2166,10 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,    if (version == RIPv1)      { -      if (ifaddr == NULL) -	{ -	  c = connected_lookup_address (ifp, to->sin_addr); -	  if (c != NULL) -	    ifaddr = c->address; -	} -      if (ifaddr == NULL) -	{ -	  zlog_warn ("cannot find source address for packets to neighbor %s", -		     inet_ntoa (to->sin_addr)); -	  return; -	} -      memcpy (&ifaddrclass, ifaddr, sizeof (struct prefix_ipv4)); +      memcpy (&ifaddrclass, ifc->address, sizeof (struct prefix_ipv4));        apply_classful_mask_ipv4 (&ifaddrclass);        subnetted = 0; -      if (ifaddr->prefixlen > ifaddrclass.prefixlen) +      if (ifc->address->prefixlen > ifaddrclass.prefixlen)          subnetted = 1;      } @@ -2199,7 +2191,7 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,  	    if (subnetted &&  		prefix_match ((struct prefix *) &ifaddrclass, &rp->p))  	      { -		if ((ifaddr->prefixlen != rp->p.prefixlen) && +		if ((ifc->address->prefixlen != rp->p.prefixlen) &&  		    (rp->p.prefixlen != 32))  		  continue;  	      } @@ -2243,10 +2235,10 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,               * configured on the same interface).               */  	    if (rinfo->type == ZEBRA_ROUTE_RIP  && -                 rinfo->ifindex == ifp->ifindex)  +                 rinfo->ifindex == ifc->ifp->ifindex)   	      continue;  	    if (rinfo->type == ZEBRA_ROUTE_CONNECT && -                 prefix_match((struct prefix *)p, (struct prefix *)saddr)) +                 prefix_match((struct prefix *)p, ifc->address))  	      continue;  	  } @@ -2255,7 +2247,7 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,  	rinfo->nexthop_out.s_addr = 0;  	rinfo->metric_out = rinfo->metric;  	rinfo->tag_out = rinfo->tag; -	rinfo->ifindex_out = ifp->ifindex; +	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, @@ -2264,7 +2256,7 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,  	 * to avoid an IGP multi-level recursive look-up.  	 * see (4.4)  	 */ -	if (rinfo->ifindex == ifp->ifindex) +	if (rinfo->ifindex == ifc->ifp->ifindex)  	  rinfo->nexthop_out = rinfo->nexthop;  	/* Interface route-map */ @@ -2321,7 +2313,7 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,  	/* Apply offset-list */  	if (rinfo->metric != RIP_METRIC_INFINITY) -	  rip_offset_list_apply_out (p, ifp, &rinfo->metric_out); +	  rip_offset_list_apply_out (p, ifc->ifp, &rinfo->metric_out);  	if (rinfo->metric_out > RIP_METRIC_INFINITY)  	  rinfo->metric_out = RIP_METRIC_INFINITY; @@ -2341,22 +2333,22 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,               * configured on the same interface).               */  	  if (rinfo->type == ZEBRA_ROUTE_RIP  && -	       rinfo->ifindex == ifp->ifindex) +	       rinfo->ifindex == ifc->ifp->ifindex)  	       rinfo->metric_out = RIP_METRIC_INFINITY;  	  if (rinfo->type == ZEBRA_ROUTE_CONNECT && -              prefix_match((struct prefix *)p, (struct prefix *)saddr)) +              prefix_match((struct prefix *)p, ifc->address))  	       rinfo->metric_out = RIP_METRIC_INFINITY;  	}  	/* Write RTE to the stream. */ -	num = rip_write_rte (num, s, p, version, rinfo, to ? NULL : ifp); +	num = rip_write_rte (num, s, p, version, rinfo, to ? NULL : ifc->ifp);  	if (num == rtemax)  	  {  	    if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5) -	      rip_auth_md5_set (s, ifp); +	      rip_auth_md5_set (s, ifc->ifp);  	    ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), -				   to, ifp, connected); +				   to, ifc);  	    if (ret >= 0 && IS_RIP_DEBUG_SEND)  	      rip_packet_dump ((struct rip_packet *)STREAM_DATA (s), @@ -2370,10 +2362,9 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,    if (num != 0)      {        if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5) -	rip_auth_md5_set (s, ifp); +	rip_auth_md5_set (s, ifc->ifp); -      ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), to, ifp,  -			     connected); +      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), @@ -2388,55 +2379,44 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,  /* Send RIP packet to the interface. */  void -rip_update_interface (struct interface *ifp, u_char version, int route_type, -                      struct connected *sconn) +rip_update_interface (struct connected *ifc, u_char version, int route_type)  { -  struct connected *connected; -  struct listnode *node;    struct sockaddr_in to; -  struct prefix_ipv4 *saddr = (struct prefix_ipv4 *) sconn->address;    /* When RIP version is 2 and multicast enable interface. */ -  if (version == RIPv2 && if_is_multicast (ifp))  +  if (version == RIPv2 && if_is_multicast (ifc->ifp))       {        if (IS_RIP_DEBUG_EVENT) -	zlog_info ("multicast announce on %s ", ifp->name); +	zlog_info ("multicast announce on %s ", ifc->ifp->name); -      rip_output_process (ifp, NULL, NULL, route_type, version,  -                          sconn, saddr); +      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 (if_is_broadcast (ifc->ifp) || if_is_pointopoint (ifc->ifp))      { -      for (node = listhead (ifp->connected); node; nextnode (node)) -	{	     -	  connected = getdata (node); - -	  if (connected->address->family == AF_INET) -	    { -	      /* Destination address and port setting. */ -	      memset (&to, 0, sizeof (struct sockaddr_in)); -	      if (connected->destination) -		/* use specified broadcast or point-to-point destination addr */ -	        to.sin_addr = connected->destination->u.prefix4; -	      else -		/* calculate the appropriate broadcast address */ -	        to.sin_addr.s_addr = -		  ipv4_broadcast_addr(connected->address->u.prefix4.s_addr, -				      connected->address->prefixlen); -	      to.sin_port = htons (RIP_PORT_DEFAULT); +      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 point-to-point destination addr */ +            to.sin_addr = ifc->destination->u.prefix4; +          else +            /* calculate the appropriate broadcast address */ +            to.sin_addr.s_addr = +              ipv4_broadcast_addr(ifc->address->u.prefix4.s_addr, +                                  ifc->address->prefixlen); +          to.sin_port = htons (RIP_PORT_DEFAULT); -	      if (IS_RIP_DEBUG_EVENT) -		zlog_info ("%s announce to %s on %s", -			   if_is_pointopoint (ifp) ? "unicast" : "broadcast", -			   inet_ntoa (to.sin_addr), ifp->name); +          if (IS_RIP_DEBUG_EVENT) +            zlog_info ("%s announce to %s on %s", +                       if_is_pointopoint (ifc->ifp) ? "unicast" : "broadcast", +                       inet_ntoa (to.sin_addr), ifc->ifp->name); -	      rip_output_process (ifp, connected->address, &to, route_type, -				 version, connected, saddr); -	    } -	} +          rip_output_process (ifc, &to, route_type, version); +        }      }  } @@ -2502,9 +2482,9 @@ rip_update_process (int route_type)  		continue;                if ((vsend & RIPv1) && !done) -	        rip_update_interface (ifp, RIPv1, route_type, connected); +	        rip_update_interface (connected, RIPv1, route_type);                if ((vsend & RIPv2) && if_is_multicast(ifp)) -	        rip_update_interface (ifp, RIPv2, route_type, connected); +	        rip_update_interface (connected, RIPv2, route_type);                done = 1;                if (!(vsend & RIPv2) || !if_is_multicast(ifp))                  break; @@ -2522,19 +2502,25 @@ rip_update_process (int route_type)  	ifp = if_lookup_address (p->prefix);  	if (! ifp)  	  { -	    zlog_warn ("Neighbor %s doesn't exist direct connected network", +	    zlog_warn ("Neighbor %s doesnt have connected interface!",  		       inet_ntoa (p->prefix));  	    continue;  	  } - +         +        if ( (connected = connected_lookup_address (ifp, p->prefix)) == NULL) +          { +            zlog_warn ("Neighbor %s doesnt have connected network", +                       inet_ntoa (p->prefix)); +            continue; +          } +          	/* Set destination address and port */  	memset (&to, 0, sizeof (struct sockaddr_in));  	to.sin_addr = p->prefix;  	to.sin_port = htons (RIP_PORT_DEFAULT);  	/* RIP version is rip's configuration. */ -	rip_output_process (ifp, NULL, &to, route_type, rip->version_send,  -                            NULL, p); +	rip_output_process (connected, &to, route_type, rip->version_send);        }  } @@ -2731,7 +2717,7 @@ rip_request_send (struct sockaddr_in *to, struct interface *ifp,         * over each connected address for this case.         */        if (rip_send_packet ((u_char *) &rip_packet, sizeof (rip_packet),  -                            to, ifp, connected) != sizeof (rip_packet)) +                            to, connected) != sizeof (rip_packet))          return -1;        else          return sizeof (rip_packet); @@ -2748,7 +2734,7 @@ rip_request_send (struct sockaddr_in *to, struct interface *ifp,          continue;        if (rip_send_packet ((u_char *) &rip_packet, sizeof (rip_packet),  -                            to, ifp, connected) != sizeof (rip_packet)) +                            to, connected) != sizeof (rip_packet))          return -1;      }    return sizeof (rip_packet); | 
