]> git.proxmox.com Git - mirror_frr.git/commitdiff
Kevin C Miller <kevinm@andrew.cmu.edu>
authorpaul <paul>
Fri, 13 Dec 2002 21:44:27 +0000 (21:44 +0000)
committerpaul <paul>
Fri, 13 Dec 2002 21:44:27 +0000 (21:44 +0000)
[zebra 16681] OSPF NSSA Patches

lib/linklist.c
ospfd/ospf_ase.c
ospfd/ospf_flood.c
ospfd/ospf_interface.c
ospfd/ospf_lsa.c
ospfd/ospf_lsa.h
ospfd/ospf_packet.c
ospfd/ospf_zebra.c
zebra/connected.c

index 5a2b696930458672fe72f6ceca0d37bc089717c9..3cb10caf1703ab7fa65676c6120df47c07a5e227 100644 (file)
@@ -162,6 +162,7 @@ listnode_delete (struct list *list, void *val)
 {
   struct listnode *node;
 
+  assert(list);
   for (node = list->head; node; node = node->next)
     {
       if (node->data == val)
@@ -189,6 +190,7 @@ listnode_head (struct list *list)
 {
   struct listnode *node;
 
+  assert(list);
   node = list->head;
 
   if (node)
@@ -203,6 +205,7 @@ list_delete_all_node (struct list *list)
   struct listnode *node;
   struct listnode *next;
 
+  assert(list);
   for (node = list->head; node; node = next)
     {
       next = node->next;
@@ -221,6 +224,7 @@ list_delete (struct list *list)
   struct listnode *node;
   struct listnode *next;
 
+  assert(list);
   for (node = list->head; node; node = next)
     {
       next = node->next;
@@ -237,6 +241,7 @@ listnode_lookup (struct list *list, void *data)
 {
   listnode node;
 
+  assert(list);
   for (node = list->head; node; nextnode (node))
     if (data == getdata (node))
       return node;
index b60aa071db2684d3d1729618f0d6d02f47e87d80..8eb7025c0122af9ea772d369c440126f341c6399 100644 (file)
@@ -642,6 +642,10 @@ ospf_ase_calculate_timer (struct thread *t)
              foreach_lsa (NSSA_LSDB (area), NULL, 0,
                           ospf_ase_calculate_route);
          }
+      /* kevinm: And add the NSSA routes in ospf_top */
+      foreach_lsa(NSSA_LSDB (ospf_top), NULL, 0,
+                 ospf_ase_calculate_route);
+
 #endif /* HAVE_NSSA */
 
       /* Compare old and new external routing table and install the
index bd33c345138692e50b1eca4dbcdef66f5a770394..00a4c644d3d02a3eb3f0d014604628054e299051 100644 (file)
@@ -622,6 +622,7 @@ ospf_flood_through_as (struct ospf_neighbor *inbr, struct ospf_lsa *lsa)
 {
   listnode node;
   int lsa_ack_flag;
+  struct as_external_lsa *extlsa;
 
   lsa_ack_flag = 0;
 
@@ -646,6 +647,7 @@ ospf_flood_through_as (struct ospf_neighbor *inbr, struct ospf_lsa *lsa)
     {
       int continue_flag = 0;
       struct ospf_area *area = getdata (node);
+      struct in_addr fwd;
       listnode if_node;
 
       switch (area->external_routing)
@@ -657,11 +659,13 @@ ospf_flood_through_as (struct ospf_neighbor *inbr, struct ospf_lsa *lsa)
        case OSPF_AREA_NSSA:    /* Sending Type 5 or 7 into NSSA area */
 #ifdef HAVE_NSSA
          /* Type-7, flood NSSA area */
-          if (lsa->data->type == OSPF_AS_NSSA_LSA) 
+          if (lsa->data->type == OSPF_AS_NSSA_LSA &&
+               area == lsa->area) { 
            /* We will send it. */
            continue_flag = 0;
-          else
+          } else {
            continue_flag = 1;  /* Skip this NSSA area for Type-5's et al */
+         }
           break;
 #endif /* HAVE_NSSA */
 
index ddae98001b0458f02e0e4f543187da38cadf2407..f0300273274f44dc79a15e1e6c237ed045198531 100644 (file)
@@ -257,7 +257,22 @@ ospf_if_cleanup (struct ospf_interface *oi)
   oi->nbr_self = ospf_nbr_new (oi);
   oi->nbr_self->state = NSM_TwoWay;
   oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
-  oi->nbr_self->options = OSPF_OPTION_E;
+
+  switch (oi->area->external_routing)
+    {
+    case OSPF_AREA_DEFAULT:
+      SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
+      break;
+    case OSPF_AREA_STUB:
+      UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
+      break;
+#ifdef HAVE_NSSA
+    case OSPF_AREA_NSSA:
+      UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
+      SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
+      break;
+#endif /* HAVE_NSSA */
+    }
 
   ospf_lsa_unlock (oi->network_lsa_self);
   oi->network_lsa_self = NULL;
index a4495e97185fe994b1cfe14cfafa9efac81260b8..c2fade2d9192ca4bb38c8dd9b363f7629b9de8ee 100644 (file)
@@ -253,6 +253,15 @@ ospf_lsa_dup (struct ospf_lsa *lsa)
   new->retransmit_counter = 0;
   new->data = ospf_lsa_data_dup (lsa->data);
 
+  /* kevinm: Clear the refresh_list, otherwise there are going
+     to be problems when we try to remove the LSA from the
+     queue (which it's not a member of.)
+     XXX: Should we add the LSA to the refresh_list queue? */
+  new->refresh_list = -1;
+
+  if (IS_DEBUG_OSPF (lsa, LSA))
+    zlog_info ("LSA: duplicated %p (new: %p)", lsa, new);
+
   return new;
 }
 
@@ -1420,12 +1429,14 @@ ospf_get_ip_from_ifp (struct ospf_interface *oi)
 
 /* Get 1st IP connection for Forward Addr */
 struct in_addr
-ospf_get_nssa_ip (void)
+ospf_get_nssa_ip (struct ospf_area *area)
 {
   struct in_addr fwd;
+  struct in_addr best_default;
   listnode n1;
 
   fwd.s_addr = 0;
+  best_default.s_addr = 0;
 
 
   for (n1 = listhead (ospf_top->oiflist); n1; nextnode (n1))
@@ -1434,9 +1445,16 @@ ospf_get_nssa_ip (void)
 
       if (if_is_operative (oi->ifp))
        if (oi->area->external_routing == OSPF_AREA_NSSA)
-         if (oi->address && oi->address->family == AF_INET)
-           return (oi->address->u.prefix4 );
+         if (oi->address && oi->address->family == AF_INET) {
+           if (best_default.s_addr == 0) {
+             best_default = oi->address->u.prefix4;
+           }
+           if (oi->area == area)
+             return (oi->address->u.prefix4);
+         }
     }
+  if (best_default.s_addr != 0)
+    return best_default;
 
   return fwd;
 }
@@ -1628,7 +1646,8 @@ void
 ospf_install_flood_nssa (struct ospf_lsa *lsa, struct external_info *ei)
 {
   struct ospf_lsa *new2;
-  struct as_external_lsa *extlsa;
+  struct as_external_lsa *extlsa, *newextlsa;
+  listnode node;
 
   /* NSSA Originate or Refresh (If anyNSSA)
 
@@ -1645,54 +1664,61 @@ ospf_install_flood_nssa (struct ospf_lsa *lsa, struct external_info *ei)
   Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
   Type-5's to non-NSSA Areas.  (it will also attempt a re-install) */
 
-  /* make lsa duplicate, lock=1 */
-  new2 = ospf_lsa_dup(lsa);
-
-  /* make type-7 */
-  new2->data->type  = OSPF_AS_NSSA_LSA;
-
-  /* set P-bit if not ABR */
-  if (! OSPF_IS_ABR)
-    {
-      SET_FLAG(new2->data->options, OSPF_OPTION_NP);
-
-      /* set non-zero FWD ADDR 
-
-      draft-ietf-ospf-nssa-update-09.txt
-
-      if the network between the NSSA AS boundary router and the
-      adjacent AS is advertised into OSPF as an internal OSPF route, 
-      the forwarding address should be the next op address as is cu
-      currently done with type-5 LSAs.  If the intervening network is 
-      not adversited into OSPF as an internal OSPF route and the 
-      type-7 LSA's P-bit is set a forwarding address should be 
-      selected from one of the router's active OSPF inteface addresses
-      which belong to the NSSA.  If no such addresses exist, then
-      no type-7 LSA's with the P-bit set should originate from this
-      router.   */
+  for (node = listhead (ospf_top->areas); node; nextnode (node)) {
+  
+         struct ospf_area *area = getdata (node);
 
-      extlsa = (struct as_external_lsa *)(lsa->data);
+         /* make lsa duplicate, lock=1 */
+         new2 = ospf_lsa_dup(lsa);
 
-      if (extlsa->e[0].fwd_addr.s_addr == 0) 
-       extlsa->e[0].fwd_addr = ospf_get_nssa_ip(); /* this NSSA area in ifp */
+         /* make type-7 */
+         new2->data->type  = OSPF_AS_NSSA_LSA;
 
-      if (IS_DEBUG_OSPF_NSSA)
-       if (extlsa->e[0].fwd_addr.s_addr == 0) 
-         {
-           zlog_info ("LSA[Type-7]: Could not build FWD-ADDR");
-           ospf_lsa_discard(new2);
-           return;
-         }
-    }
+         /* set P-bit if not ABR */
+         if (! OSPF_IS_ABR)
+           {
+             SET_FLAG(new2->data->options, OSPF_OPTION_NP);
+
+             /* set non-zero FWD ADDR 
+
+             draft-ietf-ospf-nssa-update-09.txt
+
+             if the network between the NSSA AS boundary router and the
+             adjacent AS is advertised into OSPF as an internal OSPF route, 
+             the forwarding address should be the next op address as is cu
+             currently done with type-5 LSAs.  If the intervening network is 
+             not adversited into OSPF as an internal OSPF route and the 
+             type-7 LSA's P-bit is set a forwarding address should be 
+             selected from one of the router's active OSPF inteface addresses
+             which belong to the NSSA.  If no such addresses exist, then
+             no type-7 LSA's with the P-bit set should originate from this
+             router.   */
+
+               /* not updating lsa anymore, just new2 */ 
+               extlsa = (struct as_external_lsa *)(new2->data);
+
+             if (extlsa->e[0].fwd_addr.s_addr == 0) 
+               /* this NSSA area in ifp */
+               extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); 
+
+             if (IS_DEBUG_OSPF_NSSA)
+               if (extlsa->e[0].fwd_addr.s_addr == 0) 
+                 {
+                   zlog_info ("LSA[Type-7]: Could not build FWD-ADDR");
+                   ospf_lsa_discard(new2);
+                   return;
+                 }
+           }
 
-  /* Re-calculate checksum. */
-  ospf_lsa_checksum (new2->data);
+         /* Re-calculate checksum. */
+         ospf_lsa_checksum (new2->data);
 
-  /* install also as Type-7 */
-  ospf_lsa_install (NULL, new2);   /* Remove Old, Lock New = 2 */
+         /* install also as Type-7 */
+         ospf_lsa_install (NULL, new2);   /* Remove Old, Lock New = 2 */
 
-  /* will send each copy, lock=2+n */
-  ospf_flood_through_as (NULL, new2); /* all attached NSSA's, no AS/STUBs */
+         /* will send each copy, lock=2+n */
+         ospf_flood_through_as (NULL, new2); /* all attached NSSA's, no AS/STUBs */
+       }
 
   /* last send, lock=2 LSA is now permanent in Type-7 LSDB */
   /* It has the same ID as it's Type-5 Counter-Part */
@@ -2257,6 +2283,13 @@ ospf_lsa_install (struct ospf_interface *oi, struct ospf_lsa *lsa)
   /* Set LSDB. */
   switch (lsa->data->type)
     {
+      /* kevinm */
+    case OSPF_AS_NSSA_LSA:
+      if (lsa->area)
+       lsdb = lsa->area->lsdb;
+      else
+       lsdb = ospf_top->lsdb;
+      break;
     case OSPF_AS_EXTERNAL_LSA:
 #ifdef HAVE_OPAQUE_LSA
     case OSPF_OPAQUE_AS_LSA:
@@ -2370,6 +2403,9 @@ ospf_lsa_install (struct ospf_interface *oi, struct ospf_lsa *lsa)
 #ifdef HAVE_OPAQUE_LSA
         case OSPF_OPAQUE_AS_LSA:
 #endif /* HAVE_OPAQUE_LSA */
+#ifdef HAVE_NSSA
+       case OSPF_AS_NSSA_LSA:
+#endif
           zlog_info ("LSA[%s]: Install %s",
                  dump_lsa_key (new),
                  LOOKUP (ospf_lsa_type_msg, new->data->type));
@@ -2579,6 +2615,9 @@ ospf_lsa_maxage_walker_remover (struct ospf_lsa *lsa, void *p_arg, int int_arg)
 #ifdef HAVE_OPAQUE_LSA
           case OSPF_OPAQUE_AS_LSA:
 #endif /* HAVE_OPAQUE_LSA */
+#ifdef HAVE_NSSA
+         case OSPF_AS_NSSA_LSA:
+#endif
            ospf_ase_incremental_update (lsa, ospf_top);
             break;
           default:
@@ -3260,6 +3299,8 @@ ospf_refresher_register_lsa (struct ospf *top, struct ospf_lsa *lsa)
        top->lsa_refresh_queue.qs[index] = list_new ();
       listnode_add (top->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
       lsa->refresh_list = index;
+      if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
+       zlog_info ("LSA[Refresh]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", lsa, index);
     }
 }
 
@@ -3324,7 +3365,7 @@ ospf_lsa_refresh_walker (struct thread *t)
              next = node->next;
              
              if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
-               zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p", lsa);
+               zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)", lsa, i);
              
              list_delete_node (refresh_list, node);
              ospf_lsa_unlock (lsa);
index 02fbe7046cda73e6977405554d0d1535098310e4..4303bcd6b66c929fa41d66905fd49f737a90bf17 100644 (file)
@@ -323,4 +323,8 @@ int is_prefix_default (struct prefix_ipv4 *);
 int metric_type (u_char);
 int metric_value (u_char);
 
+#ifdef HAVE_NSSA
+struct in_addr ospf_get_nssa_ip (struct ospf_area *);
+#endif
+
 #endif /* _ZEBRA_OSPF_LSA_H */
index d2338fffda98df76f78f237c2ee01379e6920f9c..ceb6d84549fc198d10cedb7b6172b99bd2d97869 100644 (file)
@@ -616,16 +616,22 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,
 
   /* increment statistics. */
   oi->hello_in++;
+  zlog_info ("Packet %s [Hello:RECV]: oi hello cnt %d",
+            inet_ntoa (ospfh->router_id), oi->hello_in);
 
   hello = (struct ospf_hello *) STREAM_PNT (s);
 
   /* If Hello is myself, silently discard. */
-  if (IPV4_ADDR_SAME (&ospfh->router_id, &ospf_top->router_id))
+  if (IPV4_ADDR_SAME (&ospfh->router_id, &ospf_top->router_id)) {
+    zlog_info ("Packet %s [Hello:RECV]: router_id matches our router id");
     return;
+  }
 
   /* If incoming interface is passive one, ignore Hello. */
-  if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
+  if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
+    zlog_info ("Packet %s [HELLO:RECV]: oi is passive");
     return;
+  }
 
   /* get neighbor prefix. */
   p.family = AF_INET;
@@ -2217,8 +2223,8 @@ ospf_read (struct thread *thread)
 
   /* IP Header dump. */
   /*
-  if (ospf_debug_packet & OSPF_DEBUG_RECV)
-    ospf_ip_header_dump (ibuf);
+    if (ospf_debug_packet & OSPF_DEBUG_RECV)*/
+    ospf_ip_header_dump (ibuf); /*
   */
   /* Self-originated packet should be discarded silently. */
   if (ospf_if_lookup_by_local_addr (NULL, iph->ip_src))
@@ -2265,8 +2271,8 @@ ospf_read (struct thread *thread)
     }
 
   /* Show debug receiving packet. */
-  if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
-    {
+  /*  if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
+      {*/
       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
        {
          zlog_info ("-----------------------------------------------------");
@@ -2281,7 +2287,7 @@ ospf_read (struct thread *thread)
 
       if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
        zlog_info ("-----------------------------------------------------");
-    }
+      /*    }*/
 
   /* Some header verification. */
   ret = ospf_verify_header (ibuf, oi, iph, ospfh);
@@ -2453,7 +2459,11 @@ ospf_make_hello (struct ospf_interface *oi, struct stream *s)
 
   /* Add neighbor seen. */
   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
-    if ((nbr = rn->info) != NULL)
+    if ((nbr = rn->info) != NULL) {
+      zlog_info("make_hello: nbr %s, state %d",
+               inet_ntoa(nbr->router_id),
+               nbr->state);
+
       /* ignore 0.0.0.0 node. */
       if (nbr->router_id.s_addr != 0)
        if (nbr->state != NSM_Attempt)
@@ -2466,11 +2476,12 @@ ospf_make_hello (struct ospf_interface *oi, struct stream *s)
              if (nbr->d_router.s_addr != 0 &&
                  IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4) &&
                  IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
-               flag = 1;
+               flag = 0;
 
              stream_put_ipv4 (s, nbr->router_id.s_addr);
              length += 4;
            }
+    }
 
   /* Let neighbor generate BackupSeen. */
   if (flag == 1)
index 72ffe76f4255808daf013d3f4db1b5953d9d8d86..a8e1630e46120c2b34d4f297c75ec0e80beef3cc 100644 (file)
@@ -66,6 +66,8 @@ ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
     zlog_info ("Zebra: interface add %s index %d flags %ld metric %d mtu %d",
               ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);
 
+  assert(ifp->info);
+
   if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type))
     {
       SET_IF_PARAM (IF_DEF_PARAMS (ifp), type);
index 22c9a1f62df2c8b30ce113f28c939b15601ef891..dcb0b875e54c2d22ed413b89192fdc572d37603e 100644 (file)
@@ -69,7 +69,7 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
   p.prefixlen = addr->prefixlen;
 
   /* Point-to-point check. */
-  if (ifc_pointopoint (ifc))
+  if (ifc_pointopoint (ifc) && dest)
     p.prefix = dest->prefix;
   else
     p.prefix = addr->prefix;