#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;
/* 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);
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);
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;
}
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;
}
}
}
/* 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;
struct listnode *cnode;
struct interface *ifp;
struct connected *c;
- struct interface *match;
+ struct connected *match;
if (family == AF_INET)
{
(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);
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'))
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;
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;
}
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;
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))
{
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))
{
}
return CMD_SUCCESS;
}
+#endif
/* Allocate connected structure. */
struct connected *
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;
}
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..
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;