diff options
Diffstat (limited to 'lib/if.c')
| -rw-r--r-- | lib/if.c | 271 |
1 files changed, 117 insertions, 154 deletions
@@ -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; |
