]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/if.c
Merge branch 'frr/pull/236' ("tools: frr-reload.py needs to treat "mpls" as a single...
[mirror_frr.git] / lib / if.c
index e44882a43e9a203456004ef32d79ace25544483d..6ee84e126c5f40ff78acebbc40118bf2760ecfab 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
 #include "memory.h"
 #include "table.h"
 #include "buffer.h"
-#include "str.h"
 #include "log.h"
 
+DEFINE_MTYPE(       LIB, IF,              "Interface")
+DEFINE_MTYPE_STATIC(LIB, CONNECTED,       "Connected")
+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;
 
@@ -143,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);
 
@@ -187,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);
 
@@ -296,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;
@@ -365,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;
                }
            }
@@ -381,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;
@@ -390,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)
     {
@@ -416,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);
@@ -478,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'))
@@ -654,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",
+       "description LINE...",
        "Interface specific description\n"
        "Characters describing this interface\n")
 {
-  struct interface *ifp;
+  int idx_line = 1;
+  VTY_DECLVAR_CONTEXT (interface, ifp);
 
-  if (argc == 0)
-    return CMD_SUCCESS;
-
-  ifp = vty->index;
   if (ifp->desc)
     XFREE (MTYPE_TMP, ifp->desc);
-  ifp->desc = argv_concat(argv, argc, 0);
+  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;
@@ -744,70 +746,72 @@ if_sunwzebra_get (const char *name, size_t nlen, vrf_id_t vrf_id)
 
 DEFUN (interface,
        interface_cmd,
-       "interface IFNAME",
+       "interface IFNAME [vrf NAME]",
        "Select an interface to configure\n"
-       "Interface's name\n")
+       "Interface's name\n"
+       VRF_CMD_HELP_STR)
 {
+  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;
   vrf_id_t vrf_id = VRF_DEFAULT;
 
-  if ((sl = strlen(argv[0])) > INTERFACE_NAMSIZ)
+  if ((sl = strlen(ifname)) > INTERFACE_NAMSIZ)
     {
       vty_out (vty, "%% Interface name %s is invalid: length exceeds "
                    "%d characters%s",
-              argv[0], INTERFACE_NAMSIZ, VTY_NEWLINE);
+              ifname, INTERFACE_NAMSIZ, VTY_NEWLINE);
       return CMD_WARNING;
     }
 
 /*Pending: need proper vrf name based lookup/(possible creation of VRF)
  Imagine forward reference of a vrf by name in this interface config */
-  if (argc > 1)
-    VRF_GET_ID (vrf_id, argv[1]);
+  if (vrfname)
+    VRF_GET_ID (vrf_id, vrfname);
 
 #ifdef SUNOS_5
-  ifp = if_sunwzebra_get (argv[0], sl, vrf_id);
+  ifp = if_sunwzebra_get (ifname, sl, vrf_id);
 #else
-  ifp = if_get_by_name_len_vrf (argv[0], sl, vrf_id, 1);
+  ifp = if_get_by_name_len_vrf (ifname, sl, vrf_id, 1);
 #endif /* SUNOS_5 */
 
   if (!ifp)
     {
-      vty_out (vty, "%% interface %s not in %s%s", argv[0], argv[1], VTY_NEWLINE);
+      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;
 }
 
-ALIAS (interface,
-       interface_vrf_cmd,
-       "interface IFNAME " VRF_CMD_STR,
-       "Select an interface to configure\n"
-       "Interface's name\n"
-       VRF_CMD_HELP_STR)
-
 DEFUN_NOSH (no_interface,
            no_interface_cmd,
-           "no interface IFNAME",
+           "no interface IFNAME [vrf NAME]",
            NO_STR
            "Delete a pseudo interface's configuration\n"
-           "Interface's name\n")
+           "Interface's name\n"
+           VRF_CMD_HELP_STR)
 {
+  const char *ifname = argv[2]->arg;
+  const char *vrfname = (argc > 3) ? argv[3]->arg : NULL;
+
   // deleting interface
   struct interface *ifp;
   vrf_id_t vrf_id = VRF_DEFAULT;
 
-  if (argc > 1)
-    VRF_GET_ID (vrf_id, argv[1]);
+  if (argc > 3)
+    VRF_GET_ID (vrf_id, vrfname);
 
-  ifp = if_lookup_by_name_vrf (argv[0], vrf_id);
+  ifp = if_lookup_by_name_vrf (ifname, vrf_id);
 
   if (ifp == NULL)
     {
-      vty_out (vty, "%% Interface %s does not exist%s", argv[0], VTY_NEWLINE);
+      vty_out (vty, "%% Interface %s does not exist%s", ifname, VTY_NEWLINE);
       return CMD_WARNING;
     }
 
@@ -823,76 +827,27 @@ DEFUN_NOSH (no_interface,
   return CMD_SUCCESS;
 }
 
-ALIAS (no_interface,
-       no_interface_vrf_cmd,
-       "no interface IFNAME " VRF_CMD_STR,
-       NO_STR
-       "Delete a pseudo interface's configuration\n"
-       "Interface's name\n"
-       VRF_CMD_HELP_STR)
-
-DEFUN (vrf,
-       vrf_cmd,
-       "vrf NAME",
-       "Select a VRF to configure\n"
-       "VRF's name\n")
-{
-  struct vrf *vrfp;
-  size_t sl;
-
-  if ((sl = strlen(argv[0])) > VRF_NAMSIZ)
-    {
-      vty_out (vty, "%% VRF name %s is invalid: length exceeds "
-                   "%d characters%s",
-              argv[0], VRF_NAMSIZ, VTY_NEWLINE);
-      return CMD_WARNING;
-    }
-
-  vrfp = vrf_get (VRF_UNKNOWN, argv[0]);
-
-  vty->index = vrfp;
-  vty->node = VRF_NODE;
-
-  return CMD_SUCCESS;
-}
-
-DEFUN_NOSH (no_vrf,
-           no_vrf_cmd,
-           "no vrf NAME",
-           NO_STR
-           "Delete a pseudo VRF's configuration\n"
-           "VRF's name\n")
+void
+if_cmd_init (void)
 {
-  struct vrf *vrfp;
-
-  vrfp = vrf_list_lookup_by_name (argv[0]);
-
-  if (vrfp == NULL)
-    {
-      vty_out (vty, "%% VRF %s does not exist%s", argv[0], VTY_NEWLINE);
-      return CMD_WARNING;
-    }
+  install_element (CONFIG_NODE, &interface_cmd);
+  install_element (CONFIG_NODE, &no_interface_cmd);
 
-  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;
+  install_default (INTERFACE_NODE);
+  install_element (INTERFACE_NODE, &interface_desc_cmd);
+  install_element (INTERFACE_NODE, &no_interface_desc_cmd);
 }
 
-
+#if 0
 /* For debug purpose. */
 DEFUN (show_address,
        show_address_cmd,
-       "show address",
+       "show address [vrf NAME]",
        SHOW_STR
-       "address\n")
+       "address\n"
+       VRF_CMD_HELP_STR)
 {
+  int idx_vrf = 3;
   struct listnode *node;
   struct listnode *node2;
   struct interface *ifp;
@@ -900,8 +855,8 @@ DEFUN (show_address,
   struct prefix *p;
   vrf_id_t vrf_id = VRF_DEFAULT;
 
-  if (argc > 0)
-    VRF_GET_ID (vrf_id, argv[0]);
+  if (argc > 2)
+    VRF_GET_ID (vrf_id, argv[idx_vrf]->arg);
 
   for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp))
     {
@@ -917,38 +872,29 @@ DEFUN (show_address,
   return CMD_SUCCESS;
 }
 
-ALIAS (show_address,
-       show_address_vrf_cmd,
-       "show address " VRF_CMD_STR,
-       SHOW_STR
-       "address\n"
-       VRF_CMD_HELP_STR)
-
 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))
             {
@@ -962,6 +908,7 @@ DEFUN (show_address_vrf_all,
     }
   return CMD_SUCCESS;
 }
+#endif
 
 /* Allocate connected structure. */
 struct connected *
@@ -1072,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;
 }
@@ -1168,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..
@@ -1379,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;