]> git.puffer.fish Git - mirror/frr.git/commitdiff
* isis_spf.[ch]: Added TE TLVs to the SPF process. It seems to work
authorhasso <hasso>
Mon, 26 Sep 2005 18:15:36 +0000 (18:15 +0000)
committerhasso <hasso>
Mon, 26 Sep 2005 18:15:36 +0000 (18:15 +0000)
  mostly, but needs certainly much more testing, especially transition
  situation.

isisd/ChangeLog
isisd/isis_spf.c
isisd/isis_spf.h

index e3fe62570168b04ef895d27b822cfe4f76189136..7f3cd9daf02bcb6bd2481c705848a380a408a1bc 100644 (file)
@@ -1,3 +1,9 @@
+2005-09-26 Hasso Tepper <hasso at quagga.net>
+
+       * isis_spf.[ch]: Added TE TLVs to the SPF process. It seems to work
+         mostly, but needs certainly much more testing, especially transition
+         situation.
+
 2005-09-26 Hasso Tepper <hasso at quagga.net>
 
        * isis_lsp.c: Put correct metric info into TE TLV's. Wide metric is
index 1a5a2db0038a6d4a22aaf11a3e7e1c2174f066ca..ac4c71f3f503cd4645c9a7695c7f61f2dcd92924 100644 (file)
@@ -124,9 +124,15 @@ vtype2string (enum vertextype vtype)
     case VTYPE_PSEUDO_IS:
       return "pseudo_IS";
       break;
+    case VTYPE_PSEUDO_TE_IS:
+      return "pseudo_TE-IS";
+      break;
     case VTYPE_NONPSEUDO_IS:
       return "IS";
       break;
+    case VTYPE_NONPSEUDO_TE_IS:
+      return "TE-IS";
+      break;
     case VTYPE_ES:
       return "ES";
       break;
@@ -136,6 +142,9 @@ vtype2string (enum vertextype vtype)
     case VTYPE_IPREACH_EXTERNAL:
       return "IP external";
       break;
+    case VTYPE_IPREACH_TE:
+      return "IP TE";
+      break;
 #ifdef HAVE_IPV6
     case VTYPE_IP6REACH_INTERNAL:
       return "IP6 internal";
@@ -156,14 +165,17 @@ vid2string (struct isis_vertex *vertex, u_char * buff)
   switch (vertex->type)
     {
     case VTYPE_PSEUDO_IS:
+    case VTYPE_PSEUDO_TE_IS:
       return rawlspid_print (vertex->N.id);
       break;
     case VTYPE_NONPSEUDO_IS:
+    case VTYPE_NONPSEUDO_TE_IS:
     case VTYPE_ES:
       return sysid_print (vertex->N.id);
       break;
     case VTYPE_IPREACH_INTERNAL:
     case VTYPE_IPREACH_EXTERNAL:
+    case VTYPE_IPREACH_TE:
 #ifdef HAVE_IPV6
     case VTYPE_IP6REACH_INTERNAL:
     case VTYPE_IP6REACH_EXTERNAL:
@@ -267,13 +279,16 @@ isis_vertex_new (void *id, enum vertextype vtype)
     {
     case VTYPE_ES:
     case VTYPE_NONPSEUDO_IS:
+    case VTYPE_NONPSEUDO_TE_IS:
       memcpy (vertex->N.id, (u_char *) id, ISIS_SYS_ID_LEN);
       break;
     case VTYPE_PSEUDO_IS:
+    case VTYPE_PSEUDO_TE_IS:
       memcpy (vertex->N.id, (u_char *) id, ISIS_SYS_ID_LEN + 1);
       break;
     case VTYPE_IPREACH_INTERNAL:
     case VTYPE_IPREACH_EXTERNAL:
+    case VTYPE_IPREACH_TE:
 #ifdef HAVE_IPV6
     case VTYPE_IP6REACH_INTERNAL:
     case VTYPE_IP6REACH_EXTERNAL:
@@ -312,7 +327,11 @@ isis_spf_add_self (struct isis_spftree *spftree, struct isis_area *area,
   if (lsp == NULL)
     zlog_warn ("ISIS-Spf: could not find own l%d LSP!", level);
 
-  vertex = isis_vertex_new (isis->sysid, VTYPE_NONPSEUDO_IS);
+  if (!area->oldmetric)
+    vertex = isis_vertex_new (isis->sysid, VTYPE_NONPSEUDO_TE_IS);
+  else
+    vertex = isis_vertex_new (isis->sysid, VTYPE_NONPSEUDO_IS);
+
   vertex->lsp = lsp;
 
   listnode_add (spftree->paths, vertex);
@@ -341,15 +360,18 @@ isis_find_vertex (struct list *list, void *id, enum vertextype vtype)
        {
        case VTYPE_ES:
        case VTYPE_NONPSEUDO_IS:
+       case VTYPE_NONPSEUDO_TE_IS:
          if (memcmp ((u_char *) id, vertex->N.id, ISIS_SYS_ID_LEN) == 0)
            return vertex;
          break;
        case VTYPE_PSEUDO_IS:
+       case VTYPE_PSEUDO_TE_IS:
          if (memcmp ((u_char *) id, vertex->N.id, ISIS_SYS_ID_LEN + 1) == 0)
            return vertex;
          break;
        case VTYPE_IPREACH_INTERNAL:
        case VTYPE_IPREACH_EXTERNAL:
+       case VTYPE_IPREACH_TE:
 #ifdef HAVE_IPV6
        case VTYPE_IP6REACH_INTERNAL:
        case VTYPE_IP6REACH_EXTERNAL:
@@ -536,7 +558,9 @@ isis_spf_process_lsp (struct isis_spftree *spftree, struct isis_lsp *lsp,
   struct listnode *node, *fragnode = NULL;
   u_int16_t dist;
   struct is_neigh *is_neigh;
+  struct te_is_neigh *te_is_neigh;
   struct ipv4_reachability *ipreach;
+  struct te_ipv4_reachability *te_ipv4_reach;
   enum vertextype vtype;
   struct prefix prefix;
 #ifdef HAVE_IPV6
@@ -574,6 +598,22 @@ lspfragloop:
                         depth + 1, lsp->adj, family);
            }
        }
+      if (lsp->tlv_data.te_is_neighs)
+       {
+         for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.te_is_neighs, node,
+                                    te_is_neigh))
+           {
+             uint32_t metric;
+             if (!memcmp (te_is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN))
+               continue;
+             memcpy (&metric, te_is_neigh->te_metric, 3);
+             dist = cost + ntohl (metric << 8);
+             vtype = LSP_PSEUDO_ID (te_is_neigh->neigh_id) ? VTYPE_PSEUDO_TE_IS
+               : VTYPE_NONPSEUDO_TE_IS;
+             process_N (spftree, vtype, (void *) te_is_neigh->neigh_id, dist,
+                        depth + 1, lsp->adj, family);
+           }
+       }
       if (family == AF_INET && lsp->tlv_data.ipv4_int_reachs)
        {
          prefix.family = AF_INET;
@@ -603,6 +643,21 @@ lspfragloop:
                         lsp->adj, family);
            }
        }
+      if (family == AF_INET && lsp->tlv_data.te_ipv4_reachs)
+       {
+         prefix.family = AF_INET;
+         for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.te_ipv4_reachs,
+                                    node, te_ipv4_reach))
+           {
+             dist = cost + ntohl (te_ipv4_reach->te_metric);
+             vtype = VTYPE_IPREACH_TE;
+             prefix.u.prefix4 = newprefix2inaddr (&te_ipv4_reach->prefix_start,
+                                                  te_ipv4_reach->control);
+             prefix.prefixlen = (te_ipv4_reach->control & 0x3F);
+             process_N (spftree, vtype, (void *) &prefix, dist, depth + 1,
+                        lsp->adj, family);
+           }
+       }
 #ifdef HAVE_IPV6
       if (family == AF_INET6 && lsp->tlv_data.ipv6_reachs)
        {
@@ -644,6 +699,7 @@ isis_spf_process_pseudo_lsp (struct isis_spftree *spftree,
 {
   struct listnode *node, *nnode, *fragnode = NULL;
   struct is_neigh *is_neigh;
+  struct te_is_neigh *te_is_neigh;
   enum vertextype vtype;
 
 pseudofragloop:
@@ -655,23 +711,42 @@ pseudofragloop:
       return ISIS_WARNING;
     }
 
-  for (ALL_LIST_ELEMENTS (lsp->tlv_data.is_neighs, node, nnode, is_neigh))
-    {
-      vtype = LSP_PSEUDO_ID (is_neigh->neigh_id) ? VTYPE_PSEUDO_IS
-       : VTYPE_NONPSEUDO_IS;
-      /* Two way connectivity */
-      if (!memcmp (is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN))
-       continue;
-      if (isis_find_vertex
-         (spftree->tents, (void *) is_neigh->neigh_id, vtype) == NULL
-         && isis_find_vertex (spftree->paths, (void *) is_neigh->neigh_id,
+  if (lsp->tlv_data.is_neighs)
+    for (ALL_LIST_ELEMENTS (lsp->tlv_data.is_neighs, node, nnode, is_neigh))
+      {
+       vtype = LSP_PSEUDO_ID (is_neigh->neigh_id) ? VTYPE_PSEUDO_IS
+         : VTYPE_NONPSEUDO_IS;
+       /* Two way connectivity */
+       if (!memcmp (is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN))
+         continue;
+       if (isis_find_vertex
+           (spftree->tents, (void *) is_neigh->neigh_id, vtype) == NULL
+           && isis_find_vertex (spftree->paths, (void *) is_neigh->neigh_id,
                               vtype) == NULL)
-       {
-         /* C.2.5 i) */
-         isis_spf_add2tent (spftree, vtype, is_neigh->neigh_id, lsp->adj,
+         {
+           /* C.2.5 i) */
+           isis_spf_add2tent (spftree, vtype, is_neigh->neigh_id, lsp->adj,
                             cost, depth, family);
-       }
-    }
+         }
+      }
+  if (lsp->tlv_data.te_is_neighs)
+    for (ALL_LIST_ELEMENTS (lsp->tlv_data.te_is_neighs, node, nnode, te_is_neigh))
+      {
+       vtype = LSP_PSEUDO_ID (te_is_neigh->neigh_id) ? VTYPE_PSEUDO_TE_IS
+         : VTYPE_NONPSEUDO_TE_IS;
+       /* Two way connectivity */
+       if (!memcmp (te_is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN))
+         continue;
+       if (isis_find_vertex
+           (spftree->tents, (void *) te_is_neigh->neigh_id, vtype) == NULL
+           && isis_find_vertex (spftree->paths, (void *) te_is_neigh->neigh_id,
+                                vtype) == NULL)
+         {
+           /* C.2.5 i) */
+           isis_spf_add2tent (spftree, vtype, te_is_neigh->neigh_id, lsp->adj,
+                              cost, depth, family);
+         }
+      }
 
   if (fragnode == NULL)
     fragnode = listhead (lsp->lspu.frags);
@@ -777,9 +852,7 @@ isis_spf_preload_tent (struct isis_spftree *spftree,
                {
                case ISIS_SYSTYPE_ES:
                  isis_spf_add_local (spftree, VTYPE_ES, adj->sysid, adj,
-                                     circuit->metrics[level -
-                                                      1].metric_default,
-                                     family);
+                                     circuit->te_metric[level - 1], family);
                  break;
                case ISIS_SYSTYPE_IS:
                case ISIS_SYSTYPE_L1_IS:
@@ -787,9 +860,7 @@ isis_spf_preload_tent (struct isis_spftree *spftree,
                  vertex =
                    isis_spf_add_local (spftree, VTYPE_NONPSEUDO_IS,
                                        adj->sysid, adj,
-                                       circuit->metrics[level -
-                                                        1].metric_default,
-                                       family);
+                                       circuit->te_metric[level - 1], family);
                  memcpy (lsp_id, adj->sysid, ISIS_SYS_ID_LEN);
                  LSP_PSEUDO_ID (lsp_id) = 0;
                  LSP_FRAGMENT (lsp_id) = 0;
@@ -827,9 +898,8 @@ isis_spf_preload_tent (struct isis_spftree *spftree,
            }
          else
            {
-             isis_spf_process_pseudo_lsp
-               (spftree, lsp, circuit->metrics[level - 1].metric_default, 0,
-                family);
+             isis_spf_process_pseudo_lsp (spftree, lsp,
+                                 circuit->te_metric[level - 1], 0, family);
 
            }
        }
@@ -842,17 +912,14 @@ isis_spf_preload_tent (struct isis_spftree *spftree,
            {
            case ISIS_SYSTYPE_ES:
              isis_spf_add_local (spftree, VTYPE_ES, adj->sysid, adj,
-                                 circuit->metrics[level - 1].metric_default,
-                                 family);
+                                 circuit->te_metric[level - 1], family);
              break;
            case ISIS_SYSTYPE_IS:
            case ISIS_SYSTYPE_L1_IS:
            case ISIS_SYSTYPE_L2_IS:
              if (speaks (&adj->nlpids, family))
                isis_spf_add_local (spftree, VTYPE_NONPSEUDO_IS, adj->sysid,
-                                   adj,
-                                   circuit->metrics[level -
-                                                    1].metric_default,
+                                   adj, circuit->te_metric[level - 1],
                                    family);
              break;
            case ISIS_SYSTYPE_UNKNOWN:
index 8912add35934e26aa72a5866b1d7d675352e27c2..6bdab2da6b9382f6b2b7759c4bc15862594c0ef3 100644 (file)
 enum vertextype
 {
   VTYPE_PSEUDO_IS = 1,
+  VTYPE_PSEUDO_TE_IS,
   VTYPE_NONPSEUDO_IS,
+  VTYPE_NONPSEUDO_TE_IS,
   VTYPE_ES,
   VTYPE_IPREACH_INTERNAL,
-  VTYPE_IPREACH_EXTERNAL
+  VTYPE_IPREACH_EXTERNAL,
+  VTYPE_IPREACH_TE
 #ifdef HAVE_IPV6
     ,
   VTYPE_IP6REACH_INTERNAL,