]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/if.c
Merge pull request #254 from donaldsharp/shutdown3
[mirror_frr.git] / lib / if.c
index 646f33354ee1f3fac5499d0ba89b52b904f47159..6ee84e126c5f40ff78acebbc40118bf2760ecfab 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
@@ -34,7 +34,6 @@
 #include "memory.h"
 #include "table.h"
 #include "buffer.h"
-#include "str.h"
 #include "log.h"
 
 DEFINE_MTYPE(       LIB, IF,              "Interface")
@@ -43,6 +42,8 @@ DEFINE_MTYPE_STATIC(LIB, NBR_CONNECTED,   "Neighbor Connected")
 DEFINE_MTYPE(       LIB, CONNECTED_LABEL, "Connected interface label")
 DEFINE_MTYPE_STATIC(LIB, IF_LINK_PARAMS,  "Informational Link Parameters")
 
+DEFINE_QOBJ_TYPE(interface)
+
 /* List of interfaces in only the default VRF */
 int ptm_enable = 0;
 
@@ -149,6 +150,8 @@ if_create_vrf (const char *name, int namelen, vrf_id_t vrf_id)
   /* Enable Link-detection by default */
   SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
 
+  QOBJ_REG (ifp, interface);
+
   if (if_master.if_new_hook)
     (*if_master.if_new_hook) (ifp);
 
@@ -193,6 +196,8 @@ if_delete_retain (struct interface *ifp)
   if (if_master.if_delete_hook)
     (*if_master.if_delete_hook) (ifp);
 
+  QOBJ_UNREG (ifp);
+
   /* Free connected address list */
   list_delete_all_node (ifp->connected);
 
@@ -302,13 +307,11 @@ if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id)
 struct interface *
 if_lookup_by_name_all_vrf (const char *name)
 {
+  struct vrf *vrf;
   struct interface *ifp;
-  struct vrf *vrf = NULL;
-  vrf_iter_t iter;
 
-  for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
     {
-      vrf = vrf_iter2vrf (iter);
       ifp = if_lookup_by_name_vrf (name, vrf->vrf_id);
       if (ifp)
        return ifp;
@@ -371,7 +374,7 @@ if_lookup_exact_address_vrf (void *src, int family, vrf_id_t vrf_id)
                }
              else if (family == AF_INET6)
                {
-                 if (IPV6_ADDR_SAME (&p->u.prefix4, (struct in6_addr *)src))
+                 if (IPV6_ADDR_SAME (&p->u.prefix6, (struct in6_addr *)src))
                    return ifp;
                }
            }
@@ -387,7 +390,7 @@ if_lookup_exact_address (void *src, int family)
 }
 
 /* Lookup interface by IPv4 address. */
-struct interface *
+struct connected *
 if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
 {
   struct listnode *node;
@@ -396,7 +399,7 @@ if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
   struct listnode *cnode;
   struct interface *ifp;
   struct connected *c;
-  struct interface *match;
+  struct connected *match;
 
   if (family == AF_INET)
     {
@@ -422,14 +425,14 @@ if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
              (c->address->prefixlen > bestlen))
            {
              bestlen = c->address->prefixlen;
-             match = ifp;
+             match = c;
            }
        }
     }
   return match;
 }
 
-struct interface *
+struct connected *
 if_lookup_address (void *matchaddr, int family)
 {
   return if_lookup_address_vrf (matchaddr, family, VRF_DEFAULT);
@@ -484,18 +487,16 @@ struct interface *
 if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id, int vty)
 {
   struct interface *ifp;
+  struct vrf *vrf;
   struct listnode *node;
-  struct vrf *vrf = NULL;
-  vrf_iter_t iter;
 
   ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id);
   if (ifp)
     return ifp;
 
   /* Didn't find the interface on that vrf. Defined on a different one? */ 
-  for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
     {
-      vrf = vrf_iter2vrf(iter);
       for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf->vrf_id), node, ifp))
        {
          if (!memcmp(name, ifp->name, namelen) && (ifp->name[namelen] == '\0'))
@@ -660,45 +661,40 @@ if_dump (const struct interface *ifp)
 void
 if_dump_all (void)
 {
-  struct list *intf_list;
+  struct vrf *vrf;
   struct listnode *node;
   void *p;
-  vrf_iter_t iter;
 
-  for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
-    if ((intf_list = vrf_iter2iflist (iter)) != NULL)
-      for (ALL_LIST_ELEMENTS_RO (intf_list, node, p))
+  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
+    if (vrf->iflist != NULL)
+      for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, p))
         if_dump (p);
 }
 
-DEFUN (interface_desc, 
+DEFUN (interface_desc,
        interface_desc_cmd,
        "description LINE...",
        "Interface specific description\n"
        "Characters describing this interface\n")
 {
-  struct interface *ifp;
-
-  if (argc == 1)
-    return CMD_SUCCESS;
+  int idx_line = 1;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
 
-  ifp = vty->index;
   if (ifp->desc)
     XFREE (MTYPE_TMP, ifp->desc);
-  ifp->desc = argv_concat(argv, argc, 1);
+  ifp->desc = argv_concat(argv, argc, idx_line);
 
   return CMD_SUCCESS;
 }
 
-DEFUN (no_interface_desc, 
+DEFUN (no_interface_desc,
        no_interface_desc_cmd,
        "no description",
        NO_STR
        "Interface specific description\n")
 {
-  struct interface *ifp;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
 
-  ifp = vty->index;
   if (ifp->desc)
     XFREE (MTYPE_TMP, ifp->desc);
   ifp->desc = NULL;
@@ -750,13 +746,15 @@ if_sunwzebra_get (const char *name, size_t nlen, vrf_id_t vrf_id)
 
 DEFUN (interface,
        interface_cmd,
-       "interface IFNAME ["VRF_CMD_STR"]",
+       "interface IFNAME [vrf NAME]",
        "Select an interface to configure\n"
        "Interface's name\n"
        VRF_CMD_HELP_STR)
 {
-  const char *ifname = argv[1]->arg;
-  const char *vrfname = (argc > 2) ? argv[3]->arg : NULL;
+  int idx_ifname = 1;
+  int idx_vrf = 3;
+  const char *ifname = argv[idx_ifname]->arg;
+  const char *vrfname = (argc > 2) ? argv[idx_vrf]->arg : NULL;
 
   struct interface *ifp;
   size_t sl;
@@ -786,15 +784,14 @@ DEFUN (interface,
       vty_out (vty, "%% interface %s not in %s%s", ifname, vrfname, VTY_NEWLINE);
       return CMD_WARNING;
     }
-  vty->index = ifp;
-  vty->node = INTERFACE_NODE;
+  VTY_PUSH_CONTEXT (INTERFACE_NODE, ifp);
 
   return CMD_SUCCESS;
 }
 
 DEFUN_NOSH (no_interface,
            no_interface_cmd,
-           "no interface IFNAME [VRF_CMD_STR]",
+           "no interface IFNAME [vrf NAME]",
            NO_STR
            "Delete a pseudo interface's configuration\n"
            "Interface's name\n"
@@ -830,73 +827,27 @@ DEFUN_NOSH (no_interface,
   return CMD_SUCCESS;
 }
 
-DEFUN (vrf,
-       vrf_cmd,
-       "vrf NAME",
-       "Select a VRF to configure\n"
-       "VRF's name\n")
+void
+if_cmd_init (void)
 {
-  const char *vrfname = argv[1]->arg;
+  install_element (CONFIG_NODE, &interface_cmd);
+  install_element (CONFIG_NODE, &no_interface_cmd);
 
-  struct vrf *vrfp;
-  size_t sl;
-
-  if ((sl = strlen(vrfname)) > VRF_NAMSIZ)
-    {
-      vty_out (vty, "%% VRF name %s is invalid: length exceeds "
-                   "%d characters%s",
-              vrfname, VRF_NAMSIZ, VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-
-  vrfp = vrf_get (VRF_UNKNOWN, vrfname);
-
-  vty->index = vrfp;
-  vty->node = VRF_NODE;
-
-  return CMD_SUCCESS;
+  install_default (INTERFACE_NODE);
+  install_element (INTERFACE_NODE, &interface_desc_cmd);
+  install_element (INTERFACE_NODE, &no_interface_desc_cmd);
 }
 
-DEFUN_NOSH (no_vrf,
-           no_vrf_cmd,
-           "no vrf NAME",
-           NO_STR
-           "Delete a pseudo VRF's configuration\n"
-           "VRF's name\n")
-{
-  const char *vrfname = argv[2]->arg;
-
-  struct vrf *vrfp;
-
-  vrfp = vrf_list_lookup_by_name (vrfname);;
-
-  if (vrfp == NULL)
-    {
-      vty_out (vty, "%% VRF %s does not exist%s", vrfname, VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-
-  if (CHECK_FLAG (vrfp->status, VRF_ACTIVE))
-    {
-      vty_out (vty, "%% Only inactive VRFs can be deleted%s",
-             VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-
-  vrf_delete(vrfp);
-
-  return CMD_SUCCESS;
-}
-
-
+#if 0
 /* For debug purpose. */
 DEFUN (show_address,
        show_address_cmd,
-       "show address [VRF_CMD_STR]",
+       "show address [vrf NAME]",
        SHOW_STR
        "address\n"
        VRF_CMD_HELP_STR)
 {
+  int idx_vrf = 3;
   struct listnode *node;
   struct listnode *node2;
   struct interface *ifp;
@@ -905,7 +856,7 @@ DEFUN (show_address,
   vrf_id_t vrf_id = VRF_DEFAULT;
 
   if (argc > 2)
-    VRF_GET_ID (vrf_id, argv[2]->arg);
+    VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
 
   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
     {
@@ -923,29 +874,27 @@ DEFUN (show_address,
 
 DEFUN (show_address_vrf_all,
        show_address_vrf_all_cmd,
-       "show address " VRF_ALL_CMD_STR,
+       "show address vrf all",
        SHOW_STR
        "address\n"
        VRF_ALL_CMD_HELP_STR)
 {
-  struct list *intf_list;
+  struct vrf *vrf;
   struct listnode *node;
   struct listnode *node2;
   struct interface *ifp;
   struct connected *ifc;
   struct prefix *p;
-  vrf_iter_t iter;
 
-  for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
+  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
     {
-      intf_list = vrf_iter2iflist (iter);
-      if (!intf_list || !listcount (intf_list))
+      if (!vrf->iflist || !listcount (vrf->iflist))
         continue;
 
-      vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf_iter2id (iter),
-               VTY_NEWLINE, VTY_NEWLINE);
+      vty_out (vty, "%sVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id, VTY_NEWLINE,
+              VTY_NEWLINE);
 
-      for (ALL_LIST_ELEMENTS_RO (intf_list, node, ifp))
+      for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp))
         {
           for (ALL_LIST_ELEMENTS_RO (ifp->connected, node2, ifc))
             {
@@ -959,6 +908,7 @@ DEFUN (show_address_vrf_all,
     }
   return CMD_SUCCESS;
 }
+#endif
 
 /* Allocate connected structure. */
 struct connected *
@@ -1069,11 +1019,9 @@ connected_same_prefix (struct prefix *p1, struct prefix *p2)
       if (p1->family == AF_INET &&
          IPV4_ADDR_SAME (&p1->u.prefix4, &p2->u.prefix4))
        return 1;
-#ifdef HAVE_IPV6
       if (p1->family == AF_INET6 &&
          IPV6_ADDR_SAME (&p1->u.prefix6, &p2->u.prefix6))
        return 1;
-#endif /* HAVE_IPV6 */
     }
   return 0;
 }
@@ -1165,30 +1113,6 @@ connected_add_by_prefix (struct interface *ifp, struct prefix *p,
   return ifc;
 }
 
-#ifndef HAVE_IF_NAMETOINDEX
-ifindex_t
-if_nametoindex (const char *name)
-{
-  struct interface *ifp;
-
-  return ((ifp = if_lookup_by_name_len(name, strnlen(name, IFNAMSIZ))) != NULL)
-        ? ifp->ifindex : 0;
-}
-#endif
-
-#ifndef HAVE_IF_INDEXTONAME
-char *
-if_indextoname (ifindex_t ifindex, char *name)
-{
-  struct interface *ifp;
-
-  if (!(ifp = if_lookup_by_index(ifindex)))
-    return NULL;
-  strncpy (name, ifp->name, IFNAMSIZ);
-  return ifp->name;
-}
-#endif
-
 #if 0 /* this route_table of struct connected's is unused
        * however, it would be good to use a route_table rather than
        * a list..
@@ -1376,21 +1300,21 @@ if_link_params_get (struct interface *ifp)
                                       sizeof (struct if_link_params));
   if (iflp == NULL) return NULL;
 
-  /* Set TE metric == standard metric */
+  /* Set TE metric equal to standard metric */
   iflp->te_metric = ifp->metric;
 
   /* Compute default bandwidth based on interface */
-  int bw = (float)((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH)
-                   * TE_KILO_BIT / TE_BYTE);
+  iflp->default_bw = ((ifp->bandwidth ? ifp->bandwidth : DEFAULT_BANDWIDTH)
+                     * TE_KILO_BIT / TE_BYTE);
 
   /* Set Max, Reservable and Unreserved Bandwidth */
-  iflp->max_bw = bw;
-  iflp->max_rsv_bw = bw;
+  iflp->max_bw = iflp->default_bw;
+  iflp->max_rsv_bw = iflp->default_bw;
   for (i = 0; i < MAX_CLASS_TYPE; i++)
-    iflp->unrsv_bw[i] = bw;
+    iflp->unrsv_bw[i] = iflp->default_bw;
 
   /* Update Link parameters status */
-  iflp->lp_status = LP_TE | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
+  iflp->lp_status = LP_TE_METRIC | LP_MAX_BW | LP_MAX_RSV_BW | LP_UNRSV_BW;
 
   /* Finally attach newly created Link Parameters */
   ifp->link_params = iflp;