summaryrefslogtreecommitdiff
path: root/lib/if.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/if.c')
-rw-r--r--lib/if.c271
1 files changed, 117 insertions, 154 deletions
diff --git a/lib/if.c b/lib/if.c
index 9161796160..dc417f8e3c 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -1,10 +1,9 @@
-
/*
* Interface functions.
* Copyright (C) 1997, 98 Kunihiro Ishiguro
*
* This file is part of GNU Zebra.
- *
+ *
* GNU Zebra is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2, or (at your
@@ -15,10 +14,9 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING. If not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
@@ -123,7 +121,7 @@ if_cmp_func (struct interface *ifp1, struct interface *ifp2)
/* Create new interface structure. */
struct interface *
-if_create_vrf (const char *name, int namelen, vrf_id_t vrf_id)
+if_create (const char *name, int namelen, vrf_id_t vrf_id)
{
struct interface *ifp;
struct list *intf_list = vrf_iflist_get (vrf_id);
@@ -136,7 +134,7 @@ if_create_vrf (const char *name, int namelen, vrf_id_t vrf_id)
strncpy (ifp->name, name, namelen);
ifp->name[namelen] = '\0';
ifp->vrf_id = vrf_id;
- if (if_lookup_by_name_vrf (ifp->name, vrf_id) == NULL)
+ if (if_lookup_by_name (ifp->name, vrf_id) == NULL)
listnode_add_sort (intf_list, ifp);
else
zlog_err("if_create(%s): corruption detected -- interface with this "
@@ -158,15 +156,9 @@ if_create_vrf (const char *name, int namelen, vrf_id_t vrf_id)
return ifp;
}
-struct interface *
-if_create (const char *name, int namelen)
-{
- return if_create_vrf (name, namelen, VRF_DEFAULT);
-}
-
/* Create new interface structure. */
void
-if_update_vrf (struct interface *ifp, const char *name, int namelen, vrf_id_t vrf_id)
+if_update (struct interface *ifp, const char *name, int namelen, vrf_id_t vrf_id)
{
struct list *intf_list = vrf_iflist_get (vrf_id);
@@ -179,7 +171,7 @@ if_update_vrf (struct interface *ifp, const char *name, int namelen, vrf_id_t vr
strncpy (ifp->name, name, namelen);
ifp->name[namelen] = '\0';
ifp->vrf_id = vrf_id;
- if (if_lookup_by_name_vrf (ifp->name, vrf_id) == NULL)
+ if (if_lookup_by_name (ifp->name, vrf_id) == NULL)
listnode_add_sort (intf_list, ifp);
else
zlog_err("if_create(%s): corruption detected -- interface with this "
@@ -239,7 +231,7 @@ if_add_hook (int type, int (*func)(struct interface *ifp))
/* Interface existance check by index. */
struct interface *
-if_lookup_by_index_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
+if_lookup_by_index (ifindex_t ifindex, vrf_id_t vrf_id)
{
struct listnode *node;
struct interface *ifp;
@@ -252,45 +244,27 @@ if_lookup_by_index_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
return NULL;
}
-struct interface *
-if_lookup_by_index (ifindex_t ifindex)
-{
- return if_lookup_by_index_vrf (ifindex, VRF_DEFAULT);
-}
-
const char *
-ifindex2ifname_vrf (ifindex_t ifindex, vrf_id_t vrf_id)
+ifindex2ifname (ifindex_t ifindex, vrf_id_t vrf_id)
{
struct interface *ifp;
- return ((ifp = if_lookup_by_index_vrf (ifindex, vrf_id)) != NULL) ?
+ return ((ifp = if_lookup_by_index (ifindex, vrf_id)) != NULL) ?
ifp->name : "unknown";
}
-const char *
-ifindex2ifname (ifindex_t ifindex)
-{
- return ifindex2ifname_vrf (ifindex, VRF_DEFAULT);
-}
-
ifindex_t
-ifname2ifindex_vrf (const char *name, vrf_id_t vrf_id)
+ifname2ifindex (const char *name, vrf_id_t vrf_id)
{
struct interface *ifp;
- return ((ifp = if_lookup_by_name_vrf (name, vrf_id)) != NULL) ? ifp->ifindex
+ return ((ifp = if_lookup_by_name (name, vrf_id)) != NULL) ? ifp->ifindex
: IFINDEX_INTERNAL;
}
-ifindex_t
-ifname2ifindex (const char *name)
-{
- return ifname2ifindex_vrf (name, VRF_DEFAULT);
-}
-
/* Interface existance check by interface name. */
struct interface *
-if_lookup_by_name_vrf (const char *name, vrf_id_t vrf_id)
+if_lookup_by_name (const char *name, vrf_id_t vrf_id)
{
struct listnode *node;
struct interface *ifp;
@@ -312,7 +286,7 @@ if_lookup_by_name_all_vrf (const char *name)
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
{
- ifp = if_lookup_by_name_vrf (name, vrf->vrf_id);
+ ifp = if_lookup_by_name (name, vrf->vrf_id);
if (ifp)
return ifp;
}
@@ -321,13 +295,7 @@ if_lookup_by_name_all_vrf (const char *name)
}
struct interface *
-if_lookup_by_name (const char *name)
-{
- return if_lookup_by_name_vrf (name, VRF_DEFAULT);
-}
-
-struct interface *
-if_lookup_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id)
+if_lookup_by_name_len (const char *name, size_t namelen, vrf_id_t vrf_id)
{
struct listnode *node;
struct interface *ifp;
@@ -343,15 +311,9 @@ if_lookup_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id)
return NULL;
}
-struct interface *
-if_lookup_by_name_len(const char *name, size_t namelen)
-{
- return if_lookup_by_name_len_vrf (name, namelen, VRF_DEFAULT);
-}
-
/* Lookup interface by IPv4 address. */
struct interface *
-if_lookup_exact_address_vrf (void *src, int family, vrf_id_t vrf_id)
+if_lookup_exact_address (void *src, int family, vrf_id_t vrf_id)
{
struct listnode *node;
struct listnode *cnode;
@@ -374,7 +336,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;
}
}
@@ -383,15 +345,9 @@ if_lookup_exact_address_vrf (void *src, int family, vrf_id_t vrf_id)
return NULL;
}
-struct interface *
-if_lookup_exact_address (void *src, int family)
-{
- return if_lookup_exact_address_vrf (src, family, VRF_DEFAULT);
-}
-
/* Lookup interface by IPv4 address. */
struct connected *
-if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
+if_lookup_address (void *matchaddr, int family, vrf_id_t vrf_id)
{
struct listnode *node;
struct prefix addr;
@@ -432,15 +388,9 @@ if_lookup_address_vrf (void *matchaddr, int family, vrf_id_t vrf_id)
return match;
}
-struct connected *
-if_lookup_address (void *matchaddr, int family)
-{
- return if_lookup_address_vrf (matchaddr, family, VRF_DEFAULT);
-}
-
/* Lookup interface by prefix */
struct interface *
-if_lookup_prefix_vrf (struct prefix *prefix, vrf_id_t vrf_id)
+if_lookup_prefix (struct prefix *prefix, vrf_id_t vrf_id)
{
struct listnode *node;
struct listnode *cnode;
@@ -460,37 +410,25 @@ if_lookup_prefix_vrf (struct prefix *prefix, vrf_id_t vrf_id)
return NULL;
}
-struct interface *
-if_lookup_prefix (struct prefix *prefix)
-{
- return if_lookup_prefix_vrf (prefix, VRF_DEFAULT);
-}
-
/* Get interface by name if given name interface doesn't exist create
one. */
struct interface *
-if_get_by_name_vrf (const char *name, vrf_id_t vrf_id)
+if_get_by_name (const char *name, vrf_id_t vrf_id)
{
struct interface *ifp;
- return ((ifp = if_lookup_by_name_vrf (name, vrf_id)) != NULL) ? ifp :
- if_create_vrf (name, strlen(name), vrf_id);
-}
-
-struct interface *
-if_get_by_name (const char *name)
-{
- return if_get_by_name_vrf (name, VRF_DEFAULT);
+ return ((ifp = if_lookup_by_name (name, vrf_id)) != NULL) ? ifp :
+ if_create (name, strlen(name), vrf_id);
}
struct interface *
-if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id, int vty)
+if_get_by_name_len (const char *name, size_t namelen, vrf_id_t vrf_id, int vty)
{
struct interface *ifp;
struct vrf *vrf;
struct listnode *node;
- ifp = if_lookup_by_name_len_vrf (name, namelen, vrf_id);
+ ifp = if_lookup_by_name_len (name, namelen, vrf_id);
if (ifp)
return ifp;
@@ -515,19 +453,13 @@ if_get_by_name_len_vrf (const char *name, size_t namelen, vrf_id_t vrf_id, int v
}
else
{
- if_update_vrf (ifp, name, namelen, vrf_id);
+ if_update (ifp, name, namelen, vrf_id);
return ifp;
}
}
}
}
- return (if_create_vrf (name, namelen, vrf_id));
-}
-
-struct interface *
-if_get_by_name_len (const char *name, size_t namelen)
-{
- return if_get_by_name_len_vrf (name, namelen, VRF_DEFAULT, 0);
+ return (if_create (name, namelen, vrf_id));
}
/* Does interface up ? */
@@ -671,25 +603,23 @@ if_dump_all (void)
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")
{
+ int idx_line = 1;
VTY_DECLVAR_CONTEXT (interface, ifp);
- if (argc == 0)
- return CMD_SUCCESS;
-
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
@@ -731,7 +661,7 @@ if_sunwzebra_get (const char *name, size_t nlen, vrf_id_t vrf_id)
struct interface *ifp;
size_t seppos = 0;
- if ( (ifp = if_lookup_by_name_len_vrf (name, nlen, vrf_id)) != NULL)
+ if ( (ifp = if_lookup_by_name_len (name, nlen, vrf_id)) != NULL)
return ifp;
/* hunt the primary interface name... */
@@ -740,77 +670,80 @@ if_sunwzebra_get (const char *name, size_t nlen, vrf_id_t vrf_id)
/* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */
if (seppos < nlen)
- return if_get_by_name_len_vrf (name, seppos, vrf_id, 1);
+ return if_get_by_name_len (name, seppos, vrf_id, 1);
else
- return if_get_by_name_len_vrf (name, nlen, vrf_id, 1);
+ return if_get_by_name_len (name, nlen, vrf_id, 1);
}
#endif /* SUNOS_5 */
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 (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_PUSH_CONTEXT_COMPAT (INTERFACE_NODE, ifp);
+ 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 (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;
}
@@ -826,21 +759,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)
+void
+if_cmd_init (void)
+{
+ install_element (CONFIG_NODE, &interface_cmd);
+ install_element (CONFIG_NODE, &no_interface_cmd);
+
+ 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;
@@ -848,8 +787,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))
{
@@ -865,16 +804,9 @@ 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)
@@ -908,6 +840,7 @@ DEFUN (show_address_vrf_all,
}
return CMD_SUCCESS;
}
+#endif
/* Allocate connected structure. */
struct connected *
@@ -986,7 +919,7 @@ connected_log (struct connected *connected, char *str)
strncat (logbuf, inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
BUFSIZ - strlen(logbuf));
}
- zlog (NULL, LOG_INFO, "%s", logbuf);
+ zlog_info("%s", logbuf);
}
/* Print if_addr structure. */
@@ -1006,7 +939,7 @@ nbr_connected_log (struct nbr_connected *connected, char *str)
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
p->prefixlen);
- zlog (NULL, LOG_INFO, "%s", logbuf);
+ zlog_info("%s", logbuf);
}
/* If two connected address has same prefix return 1. */
@@ -1018,11 +951,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;
}
@@ -1189,10 +1120,40 @@ ifaddr_ipv4_lookup (struct in_addr *addr, ifindex_t ifindex)
return ifp;
}
else
- return if_lookup_by_index(ifindex);
+ return if_lookup_by_index(ifindex, VRF_DEFAULT);
}
#endif /* ifaddr_ipv4_table */
+static void if_autocomplete(vector comps, struct cmd_token *token)
+{
+ struct interface *ifp;
+ struct listnode *ln;
+ struct vrf *vrf = NULL;
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
+ {
+ for (ALL_LIST_ELEMENTS_RO(vrf->iflist, ln, ifp))
+ vector_set (comps, XSTRDUP (MTYPE_COMPLETION, ifp->name));
+ }
+
+}
+
+static const struct cmd_variable_handler if_var_handlers[] = {
+ {
+ /* "interface NAME" */
+ .varname = "interface",
+ .completions = if_autocomplete
+ }, {
+ .tokenname = "IFNAME",
+ .completions = if_autocomplete
+ }, {
+ .tokenname = "INTERFACE",
+ .completions = if_autocomplete
+ }, {
+ .completions = NULL
+ }
+};
+
/* Initialize interface list. */
void
if_init (struct list **intf_list)
@@ -1203,6 +1164,8 @@ if_init (struct list **intf_list)
#endif /* ifaddr_ipv4_table */
(*intf_list)->cmp = (int (*)(void *, void *))if_cmp_func;
+
+ cmd_variable_handler_register(if_var_handlers);
}
void
@@ -1301,7 +1264,7 @@ 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 */
@@ -1315,7 +1278,7 @@ if_link_params_get (struct interface *ifp)
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;