]> git.puffer.fish Git - mirror/frr.git/commitdiff
2004-05-05 Paul Jakma <paul@dishone.st>
authorpaul <paul>
Wed, 5 May 2004 15:27:15 +0000 (15:27 +0000)
committerpaul <paul>
Wed, 5 May 2004 15:27:15 +0000 (15:27 +0000)
        * ospf_packet.c:  (ospf_associate_packet_vl) cleanup, move
          some of the checks up to ospf_read, return either a
          virtual link oi, or NULL.
          (ospf_read) Cleanup, make it responsible for checks. Remove
          the nbr lookup - moved to ospf_neighbor. Adjust all nbr
          lookups to use new wrappers exported by ospf_neighbor.
        * ospf_neighbor.h: Add ospf_neigbour_get and ospf_nbr_lookup.
        * ospf_neighbor.c: (ospf_neigbour_get) Index ospf_interface
          neighbour table by router-id for virtual-link ospf_interfaces,
          not by peer_addr (which breaks for asymmetric vlinks)
          (ospf_nbr_lookup) add a wrapper for nbr lookups to deal with
          above.

ospfd/ChangeLog
ospfd/ospf_neighbor.c
ospfd/ospf_neighbor.h
ospfd/ospf_packet.c

index 39a18879dfe625b8a569418b8d2941f6d31dbd3f..6b15fe64dd0b511cf98e95c670534b855cee8bf4 100644 (file)
@@ -1,3 +1,18 @@
+2004-05-05 Paul Jakma <paul@dishone.st>
+
+       * ospf_packet.c:  (ospf_associate_packet_vl) cleanup, move 
+         some of the checks up to ospf_read, return either a 
+         virtual link oi, or NULL. 
+         (ospf_read) Cleanup, make it responsible for checks. Remove
+         the nbr lookup - moved to ospf_neighbor. Adjust all nbr
+         lookups to use new wrappers exported by ospf_neighbor.
+       * ospf_neighbor.h: Add ospf_neigbour_get and ospf_nbr_lookup.
+       * ospf_neighbor.c: (ospf_neigbour_get) Index ospf_interface 
+         neighbour table by router-id for virtual-link ospf_interfaces, 
+         not by peer_addr (which breaks for asymmetric vlinks)
+         (ospf_nbr_lookup) add a wrapper for nbr lookups to deal with
+         above.
+
 2004-04-22 Hasso Tepper <hasso@estpak.ee>
 
        * ospf_zebra.c: Don't ignore reject/bh routes, it's the only way
index ccef055924a37a34dadf967658f38b4686711513..6f2d4a0502aa4cdbba6f225470bb0baac8dfa1fb 100644 (file)
@@ -138,6 +138,11 @@ ospf_nbr_delete (struct ospf_neighbor *nbr)
   /* Unlink ospf neighbor from the interface. */
   p.family = AF_INET;
   p.prefixlen = IPV4_MAX_BITLEN;
+
+  /* vlinks are indexed by router-id */
+  if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+    p.u.prefix4 = nbr->router_id;
+  else
   p.u.prefix4 = nbr->src;
 
   rn = route_node_lookup (oi->nbrs, &p);
@@ -236,6 +241,10 @@ ospf_nbr_count_opaque_capable (struct ospf_interface *oi)
 }
 #endif /* HAVE_OPAQUE_LSA */
 
+/* lookup nbr by address - use this only if you know you must
+ * otherwise use the ospf_nbr_lookup() wrapper, which deals 
+ * with virtual link neighbours
+ */
 struct ospf_neighbor *
 ospf_nbr_lookup_by_addr (struct route_table *nbrs,
                         struct in_addr *addr)
@@ -317,3 +326,99 @@ ospf_renegotiate_optional_capabilities (struct ospf *top)
 
   return;
 }
+
+
+struct ospf_neighbor *
+ospf_nbr_lookup (struct ospf_interface *oi, struct ip *iph,
+                 struct ospf_header *ospfh)
+{
+  if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+    return (ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id));
+  else
+    return (ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src));
+}
+
+struct ospf_neighbor *
+ospf_nbr_add (struct ospf_interface *oi, struct ospf_header *ospfh,
+              struct prefix *p)
+{
+  struct ospf_neighbor *nbr;
+  
+  nbr = ospf_nbr_new (oi);
+  nbr->state = NSM_Down;
+  nbr->src = p->u.prefix4;
+  memcpy (&nbr->address, p, sizeof (struct prefix));
+
+  nbr->nbr_nbma = NULL;
+  if (oi->type == OSPF_IFTYPE_NBMA)
+    {
+      struct ospf_nbr_nbma *nbr_nbma;
+      listnode node;
+
+      for (node = listhead (oi->nbr_nbma); node; nextnode (node))
+        {
+          nbr_nbma = getdata (node);
+          assert (nbr_nbma);
+
+          if (IPV4_ADDR_SAME(&nbr_nbma->addr, &nbr->src))
+            {
+              nbr_nbma->nbr = nbr;
+              nbr->nbr_nbma = nbr_nbma;
+
+              if (nbr_nbma->t_poll)
+                OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
+
+              nbr->state_change = nbr_nbma->state_change + 1;
+            }
+        }
+    }
+      
+  /* New nbr, save the crypto sequence number if necessary */
+  if (ntohs (ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC)
+    nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
+  
+  if (IS_DEBUG_OSPF_EVENT)
+    zlog_info ("NSM[%s:%s]: start", IF_NAME (nbr->oi),
+               inet_ntoa (nbr->router_id));
+  
+  return nbr;
+}
+
+struct ospf_neighbor *
+ospf_nbr_get (struct ospf_interface *oi, struct ospf_header *ospfh,
+              struct ip *iph, struct prefix *p)
+{
+  struct route_node *rn;
+  struct prefix key;
+  struct ospf_neighbor *nbr;
+  
+  key.family = AF_INET;
+  key.prefixlen = IPV4_MAX_BITLEN;
+
+  if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
+    key.u.prefix4 = ospfh->router_id;   /* index vlink nbrs by router-id */
+  else
+    key.u.prefix4 = iph->ip_src;
+
+  rn = route_node_get (oi->nbrs, &key);
+  if (rn->info)
+    {
+      route_unlock_node (rn);
+      nbr = rn->info;
+      
+      if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt)
+        {
+          nbr->src = iph->ip_src;
+          memcpy (&nbr->address, p, sizeof (struct prefix));
+        }
+    }
+  else
+    {
+      rn->info = nbr = ospf_nbr_add (oi, ospfh, p);
+    }
+  
+  nbr->router_id = ospfh->router_id;
+
+  return nbr;
+}
+  
index f7b18742fb60e996d8cf9b5190b8b2775c630816..f91ef3f9582a49eb47ba54f2cf590ace5e3f34bf 100644 (file)
@@ -23,6 +23,8 @@
 #ifndef _ZEBRA_OSPF_NEIGHBOR_H
 #define _ZEBRA_OSPF_NEIGHBOR_H
 
+#include <ospfd/ospf_packet.h>
+
 /* Neighbor Data Structure */
 struct ospf_neighbor
 {
@@ -93,10 +95,16 @@ void ospf_nbr_free (struct ospf_neighbor *);
 void ospf_nbr_delete (struct ospf_neighbor *);
 int ospf_nbr_bidirectional (struct in_addr *, struct in_addr *, int);
 void ospf_nbr_add_self (struct ospf_interface *);
-int ospf_nbr_count (struct route_table *, int);
+int ospf_nbr_count (struct ospf_interface *, int);
 #ifdef HAVE_OPAQUE_LSA
-int ospf_opaque_capable_nbr_count (struct route_table *nbrs, int status);
+int ospf_nbr_count_opaque_capable (struct ospf_interface *);
 #endif /* HAVE_OPAQUE_LSA */
+struct ospf_neighbor *ospf_nbr_get (struct ospf_interface *,
+                                    struct ospf_header *,
+                                    struct ip *,
+                                    struct prefix *);
+struct ospf_neighbor *ospf_nbr_lookup (struct ospf_interface *, struct ip *,
+                                       struct ospf_header *);
 struct ospf_neighbor *ospf_nbr_lookup_by_addr (struct route_table *,
                                               struct in_addr *);
 struct ospf_neighbor *ospf_nbr_lookup_by_routerid (struct route_table *,
index 1f8ecd462b0e4fd081eb84ac54a6d021b4352112..e6b2ea7cae97c142cad9a320bf9b7c318961a7ec 100644 (file)
@@ -607,9 +607,8 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,
 {
   struct ospf_hello *hello;
   struct ospf_neighbor *nbr;
-  struct route_node *rn;
-  struct prefix p, key;
   int old_state;
+  struct prefix p;
 
   /* increment statistics. */
   oi->hello_in++;
@@ -736,70 +735,12 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,
                   OPTIONS (oi), hello->options);
        return;
       }
-
-
-  /* Get neighbor information from table. */
-  key.family = AF_INET;
-  key.prefixlen = IPV4_MAX_BITLEN;
-  key.u.prefix4 = iph->ip_src;
-
-  rn = route_node_get (oi->nbrs, &key);
-  if (rn->info)
-    {
-      route_unlock_node (rn);
-      nbr = rn->info;
-
-      if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt)
-       {
-         nbr->src = iph->ip_src;
-         nbr->address = p;
-       }
-    }
-  else
-    {
-      /* Create new OSPF Neighbor structure. */
-      nbr = ospf_nbr_new (oi);
-      nbr->state = NSM_Down;
-      nbr->src = iph->ip_src;
-      nbr->address = p;
-
-      rn->info = nbr;
-
-      nbr->nbr_nbma = NULL;
-
-      if (oi->type == OSPF_IFTYPE_NBMA)
-       {
-         struct ospf_nbr_nbma *nbr_nbma;
-         listnode node;
-
-         for (node = listhead (oi->nbr_nbma); node; nextnode (node))
-           {
-             nbr_nbma = getdata (node);
-             assert (nbr_nbma);
-      
-             if (IPV4_ADDR_SAME(&nbr_nbma->addr, &iph->ip_src))
-               {
-                 nbr_nbma->nbr = nbr;
-                 nbr->nbr_nbma = nbr_nbma;
-
-                 if (nbr_nbma->t_poll)
-                   OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
-                 
-                 nbr->state_change = nbr_nbma->state_change + 1;
-               }
-           }
-       }
-      
-      /* New nbr, save the crypto sequence number if necessary */
-      if (ntohs (ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC)
-       nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
-
-      if (IS_DEBUG_OSPF_EVENT)
-       zlog_info ("NSM[%s:%s]: start", IF_NAME (nbr->oi),
-                  inet_ntoa (nbr->router_id));
-    }
   
-  nbr->router_id = ospfh->router_id;
+  /* get neighbour struct */
+  nbr = ospf_nbr_get (oi, ospfh, iph, &p);
+
+  /* neighbour must be valid, ospf_nbr_get creates if none existed */
+  assert (nbr);
 
   old_state = nbr->state;
 
@@ -1029,7 +970,7 @@ ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
 
   dd = (struct ospf_db_desc *) STREAM_PNT (s);
 
-  nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
+  nbr = ospf_nbr_lookup (oi, iph, ospfh);
   if (nbr == NULL)
     {
       zlog_warn ("Packet[DD]: Unknown Neighbor %s",
@@ -1286,7 +1227,7 @@ ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
   /* Increment statistics. */
   oi->ls_req_in++;
 
-  nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
+  nbr = ospf_nbr_lookup (oi, iph, ospfh);
   if (nbr == NULL)
     {
       zlog_warn ("Link State Request: Unknown Neighbor %s.",
@@ -1520,7 +1461,7 @@ ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
   oi->ls_upd_in++;
 
   /* Check neighbor. */
-  nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
+  nbr = ospf_nbr_lookup (oi, iph, ospfh);
   if (nbr == NULL)
     {
       zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
@@ -1881,7 +1822,7 @@ ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
   /* increment statistics. */
   oi->ls_ack_in++;
 
-  nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
+  nbr = ospf_nbr_lookup (oi, iph, ospfh);
   if (nbr == NULL)
     {
       zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
@@ -2043,8 +1984,7 @@ ospf_recv_packet (int fd, struct interface **ifp)
 }
 
 struct ospf_interface *
-ospf_associate_packet_vl (struct ospf *ospf,
-                         struct interface *ifp, struct ospf_interface *oi,
+ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp, 
                          struct ip *iph, struct ospf_header *ospfh)
 {
   struct ospf_interface *rcv_oi;
@@ -2054,14 +1994,16 @@ ospf_associate_packet_vl (struct ospf *ospf,
 
   if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
       !OSPF_IS_AREA_BACKBONE (ospfh))
-    return oi;
+    return NULL;
 
-  if ((rcv_oi = oi) == NULL)
-    {
-     if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL, 
-                                                 iph->ip_dst)) == NULL)
-       return NULL;
-    }
+  /* look for local OSPF interface matching the destination
+   * to determine Area ID. We presume therefore the destination address
+   * is unique, or at least (for "unnumbered" links), not used in other 
+   * areas
+   */
+  if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL, 
+                                              iph->ip_dst)) == NULL)
+    return NULL;
 
   for (node = listhead (ospf->vlinks); node; nextnode (node))
     {
@@ -2092,7 +2034,7 @@ ospf_associate_packet_vl (struct ospf *ospf,
   if (IS_DEBUG_OSPF_EVENT)
     zlog_info ("couldn't find any VL to associate the packet with");
   
-  return oi;
+  return NULL;
 }
 
 int
@@ -2287,6 +2229,12 @@ ospf_read (struct thread *thread)
   if (ibuf == NULL)
     return -1;
   
+  if (ifp == NULL)
+    {
+      stream_free (ibuf);
+      return 0;
+    }
+    
   iph = (struct ip *) STREAM_DATA (ibuf);
 
   /* prepare for next packet. */
@@ -2316,23 +2264,33 @@ ospf_read (struct thread *thread)
 
   /* associate packet with ospf interface */
   oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
-  if (ifp && oi && oi->ifp != ifp)
-    {
-      zlog_warn ("Packet from [%s] received on wrong link %s",
-                 inet_ntoa (iph->ip_src), ifp->name); 
-      stream_free (ibuf);
-      return 0;
-    }
-  
-  if ((oi = ospf_associate_packet_vl (ospf, ifp, oi, iph, ospfh)) == NULL)
+
+  /* if no local ospf_interface, 
+   * or header area is backbone but ospf_interface is not
+   * check for VLINK interface
+   */
+  if ( (oi == NULL) ||
+      (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
+      && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
+     )
     {
-      if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
+      if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
         {
-          zlog_info ("ospf_read[%s/%s]: Could not associate packet with VL, "
-                     "dropping.",
-                     ospf_packet_type_str[ospfh->type],
-                     inet_ntoa (iph->ip_src));
+          zlog_warn ("Packet from [%s] received on link %s"
+                     " but no ospf_interface",
+                     inet_ntoa (iph->ip_src), ifp->name);
+          stream_free (ibuf);
+          return 0;
         }
+    }
+    
+  /* else it must be a local ospf interface, check it was received on 
+   * correct link 
+   */
+  else if (oi->ifp != ifp)
+    {
+      zlog_warn ("Packet from [%s] received on wrong link %s",
+                 inet_ntoa (iph->ip_src), ifp->name); 
       stream_free (ibuf);
       return 0;
     }