[quagga-dev 5458] [PATCH 2/6] Make ospf_if_lookup_recv_if() find the right unnumbered i/f

Joakim Tjernlund Joakim.Tjernlund at transmode.se
Tue Jun 3 18:41:37 BST 2008


This function will return the interface for the first matching
remote address for PtP i/f's. That won't work for multiple
unnumbered i/f's as these may all have the same address.

Add a check for correct dst address as specified in
RFC 2838, chap 8.2:
"The packet's IP destination address must be the IP address
 of the receiving interface, or one of the IP multicast
 addresses AllSPFRouters or AllDRouters."

Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund at transmode.se>
---
 ospfd/ospf_interface.c |   33 ++++++++++++---------------------
 ospfd/ospf_interface.h |    3 ++-
 ospfd/ospf_packet.c    |    4 ++--
 3 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 6368142..1f8e09d 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -439,39 +439,30 @@ ospf_if_lookup_by_prefix (struct ospf *ospf, struct prefix_ipv4 *p)
   return NULL;
 }
 
-/* determine receiving interface by source of packet */
+/* determine receiving interface by ifp */
 struct ospf_interface *
-ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src)
+ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr ip_dst,
+			struct interface *ifp)
 {
   struct listnode *node;
-  struct prefix_ipv4 addr;
-  struct ospf_interface *oi, *match;
-
-  addr.family = AF_INET;
-  addr.prefix = src;
-  addr.prefixlen = IPV4_MAX_BITLEN;
-
-  match = NULL;
+  struct ospf_interface *oi;
 
   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
     {
-      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+      if (oi->ifp != ifp)
 	continue;
-      
       if (if_is_loopback (oi->ifp))
         continue;
+      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+	continue; /* Never true ? */
 
-      if (prefix_match (CONNECTED_PREFIX(oi->connected),
-      			(struct prefix *) &addr))
-	{
-	  if ( (match == NULL) || 
-	       (match->address->prefixlen < oi->address->prefixlen)
-	     )
-	    match = oi;
-	}
+      if ((ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS)) ||
+	  (ip_dst.s_addr == htonl(OSPF_ALLDROUTERS)) ||
+	  IPV4_ADDR_SAME (&ip_dst.s_addr, &oi->address->u.prefix4))
+	   return oi;
     }
 
-  return match;
+  return NULL;
 }
 
 void
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index 79b178d..f40488e 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -250,7 +250,8 @@ extern struct ospf_interface *ospf_if_lookup_by_prefix (struct ospf *,
 							struct prefix_ipv4 *);
 extern struct ospf_interface *ospf_if_addr_local (struct in_addr);
 extern struct ospf_interface *ospf_if_lookup_recv_if (struct ospf *,
-						      struct in_addr);
+						      struct in_addr,
+						      struct interface *);
 extern struct ospf_interface *ospf_if_is_configured (struct ospf *,
 						     struct in_addr *);
 
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index ed342e7..b7bfe2b 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -2391,7 +2391,7 @@ ospf_read (struct thread *thread)
   ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
 
   /* associate packet with ospf interface */
-  oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
+  oi = ospf_if_lookup_recv_if (ospf, iph->ip_dst, ifp);
 
   /* if no local ospf_interface, 
    * or header area is backbone but ospf_interface is not
@@ -2411,7 +2411,7 @@ ospf_read (struct thread *thread)
           return 0;
         }
     }
-    
+
   /* else it must be a local ospf interface, check it was received on 
    * correct link 
    */
-- 
1.5.5.1




More information about the Quagga-dev mailing list