📄 interface.c
字号:
/* * Interface function. * Copyright (C) 1997, 1999 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 option) any * later version. * * GNU Zebra is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * 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. */#include <zebra.h>#include "if.h"#include "vty.h"#include "sockunion.h"#include "prefix.h"#include "command.h"#include "memory.h"#include "ioctl.h"#include "connected.h"#include "log.h"#include "zclient.h"#include "zebra/interface.h"#include "zebra/rtadv.h"#include "zebra/rib.h"#include "zebra/zserv.h"#include "zebra/redistribute.h"#include "zebra/debug.h"/* Allocate a new internal interface index * This works done from the top so that %d macros * print a - sign! */static unsigned intif_new_intern_ifindex (void){ /* Start here so that first one assigned is 0xFFFFFFFF */ static unsigned int ifindex = IFINDEX_INTERNBASE + 1; for (;;) { ifindex--; if ( ifindex <= IFINDEX_INTERNBASE ) ifindex = 0xFFFFFFFF; if (if_lookup_by_index(ifindex) == NULL) return ifindex; }}/* Called when new interface is added. */intif_zebra_new_hook (struct interface *ifp){ struct zebra_if *zebra_if; zebra_if = XMALLOC (MTYPE_TMP, sizeof (struct zebra_if)); memset (zebra_if, 0, sizeof (struct zebra_if)); zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC; zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_UNSPEC;#ifdef RTADV { /* Set default router advertise values. */ struct rtadvconf *rtadv; rtadv = &zebra_if->rtadv; rtadv->AdvSendAdvertisements = 0; rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL; rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL; rtadv->AdvIntervalTimer = 0; rtadv->AdvManagedFlag = 0; rtadv->AdvOtherConfigFlag = 0; rtadv->AdvLinkMTU = 0; rtadv->AdvReachableTime = 0; rtadv->AdvRetransTimer = 0; rtadv->AdvCurHopLimit = 0; rtadv->AdvDefaultLifetime = RTADV_ADV_DEFAULT_LIFETIME; rtadv->AdvPrefixList = list_new (); } #endif /* RTADV */ ifp->info = zebra_if; return 0;}/* Called when interface is deleted. */intif_zebra_delete_hook (struct interface *ifp){ if (ifp->info) XFREE (MTYPE_TMP, ifp->info); return 0;}/* Wake up configured address if it is not in current kernel address. */voidif_addr_wakeup (struct interface *ifp){ struct listnode *node; struct connected *ifc; struct prefix *p; int ret; for (node = listhead (ifp->connected); node; nextnode (node)) { ifc = getdata (node); p = ifc->address; if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED) && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) { /* Address check. */ if (p->family == AF_INET) { if (! if_is_up (ifp)) { if_set_flags (ifp, IFF_UP | IFF_RUNNING); if_refresh (ifp); } ret = if_set_prefix (ifp, ifc); if (ret < 0) { zlog_warn ("Can't set interface's address: %s", strerror(errno)); continue; } SET_FLAG (ifc->conf, ZEBRA_IFC_REAL); zebra_interface_address_add_update (ifp, ifc); if (if_is_up(ifp)) connected_up_ipv4 (ifp, ifc); }#ifdef HAVE_IPV6 if (p->family == AF_INET6) { if (! if_is_up (ifp)) { if_set_flags (ifp, IFF_UP | IFF_RUNNING); if_refresh (ifp); } ret = if_prefix_add_ipv6 (ifp, ifc); if (ret < 0) { zlog_warn ("Can't set interface's address: %s", strerror(errno)); continue; } SET_FLAG (ifc->conf, ZEBRA_IFC_REAL); zebra_interface_address_add_update (ifp, ifc); if (if_is_up(ifp)) connected_up_ipv6 (ifp, ifc); }#endif /* HAVE_IPV6 */ } }}/* Handle interface addition */voidif_add_update (struct interface *ifp){ zebra_interface_add_update (ifp); if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) { SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE); if_addr_wakeup (ifp); if (IS_ZEBRA_DEBUG_KERNEL) zlog_info ("interface %s index %d becomes active.", ifp->name, ifp->ifindex); } else { if (IS_ZEBRA_DEBUG_KERNEL) zlog_info ("interface %s index %d is added.", ifp->name, ifp->ifindex); }}/* Handle an interface delete event */void if_delete_update (struct interface *ifp){ struct listnode *node; struct listnode *next; struct connected *ifc; struct prefix *p; if (if_is_up(ifp)) { zlog_err ("interface %s index %d is still up while being deleted.", ifp->name, ifp->ifindex); return; } /* Mark interface as inactive */ UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE); if (IS_ZEBRA_DEBUG_KERNEL) zlog_info ("interface %s index %d is now inactive.", ifp->name, ifp->ifindex); /* Delete connected routes from the kernel. */ if (ifp->connected) { for (node = listhead (ifp->connected); node; node = next) { next = node->next; ifc = getdata (node); p = ifc->address; if (p->family == AF_INET) connected_down_ipv4 (ifp, ifc);#ifdef HAVE_IPV6 else if (p->family == AF_INET6) connected_down_ipv6 (ifp, ifc);#endif /* HAVE_IPV6 */ zebra_interface_address_delete_update (ifp, ifc); UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) { listnode_delete (ifp->connected, ifc); connected_free (ifc); } } } zebra_interface_delete_update (ifp);}/* Interface is up. */voidif_up (struct interface *ifp){ listnode node; listnode next; struct connected *ifc; struct prefix *p; /* Notify the protocol daemons. */ zebra_interface_up_update (ifp); /* Install connected routes to the kernel. */ if (ifp->connected) { for (node = listhead (ifp->connected); node; node = next) { next = node->next; ifc = getdata (node); p = ifc->address; if (p->family == AF_INET) connected_up_ipv4 (ifp, ifc);#ifdef HAVE_IPV6 else if (p->family == AF_INET6) connected_up_ipv6 (ifp, ifc);#endif /* HAVE_IPV6 */ } } /* Examine all static routes. */ rib_update ();}/* Interface goes down. We have to manage different behavior of based OS. */voidif_down (struct interface *ifp){ listnode node; listnode next; struct connected *ifc; struct prefix *p; /* Notify to the protocol daemons. */ zebra_interface_down_update (ifp); /* Delete connected routes from the kernel. */ if (ifp->connected) { for (node = listhead (ifp->connected); node; node = next) { next = node->next; ifc = getdata (node); p = ifc->address; if (p->family == AF_INET) connected_down_ipv4 (ifp, ifc);#ifdef HAVE_IPV6 else if (p->family == AF_INET6) connected_down_ipv6 (ifp, ifc);#endif /* HAVE_IPV6 */ } } /* Examine all static routes which direct to the interface. */ rib_update ();}voidif_refresh (struct interface *ifp){ if (if_is_up (ifp)) { if_get_flags (ifp); if (! if_is_up (ifp)) if_down (ifp); } else { if_get_flags (ifp); if (if_is_up (ifp)) if_up (ifp); }}/* Printout flag information into vty */voidif_flag_dump_vty (struct vty *vty, unsigned long flag){ int separator = 0;#define IFF_OUT_VTY(X, Y) \ if ((X) && (flag & (X))) \ { \ if (separator) \ vty_out (vty, ","); \ else \ separator = 1; \ vty_out (vty, Y); \ } vty_out (vty, "<"); IFF_OUT_VTY (IFF_UP, "UP"); IFF_OUT_VTY (IFF_BROADCAST, "BROADCAST"); IFF_OUT_VTY (IFF_DEBUG, "DEBUG"); IFF_OUT_VTY (IFF_LOOPBACK, "LOOPBACK"); IFF_OUT_VTY (IFF_POINTOPOINT, "POINTOPOINT"); IFF_OUT_VTY (IFF_NOTRAILERS, "NOTRAILERS"); IFF_OUT_VTY (IFF_RUNNING, "RUNNING"); IFF_OUT_VTY (IFF_NOARP, "NOARP"); IFF_OUT_VTY (IFF_PROMISC, "PROMISC"); IFF_OUT_VTY (IFF_ALLMULTI, "ALLMULTI"); IFF_OUT_VTY (IFF_OACTIVE, "OACTIVE"); IFF_OUT_VTY (IFF_SIMPLEX, "SIMPLEX"); IFF_OUT_VTY (IFF_LINK0, "LINK0"); IFF_OUT_VTY (IFF_LINK1, "LINK1"); IFF_OUT_VTY (IFF_LINK2, "LINK2"); IFF_OUT_VTY (IFF_MULTICAST, "MULTICAST"); vty_out (vty, ">");}/* Output prefix string to vty. */intprefix_vty_out (struct vty *vty, struct prefix *p){ char str[INET6_ADDRSTRLEN]; inet_ntop (p->family, &p->u.prefix, str, sizeof (str)); vty_out (vty, "%s", str); return strlen (str);}/* Dump if address information to vty. */voidconnected_dump_vty (struct vty *vty, struct connected *connected){ struct prefix *p; struct interface *ifp; /* Set interface pointer. */ ifp = connected->ifp; /* Print interface address. */ p = connected->address; vty_out (vty, " %s ", prefix_family_str (p)); prefix_vty_out (vty, p); vty_out (vty, "/%d", p->prefixlen); /* If there is destination address, print it. */ p = connected->destination; if (p) { if (p->family == AF_INET) if (ifp->flags & IFF_BROADCAST) { vty_out (vty, " broadcast "); prefix_vty_out (vty, p); } if (ifp->flags & IFF_POINTOPOINT) { vty_out (vty, " pointopoint "); prefix_vty_out (vty, p); } } if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY)) vty_out (vty, " secondary"); if (connected->label) vty_out (vty, " %s", connected->label); vty_out (vty, "%s", VTY_NEWLINE);}#ifdef RTADV/* Dump interface ND information to vty. */voidnd_dump_vty (struct vty *vty, struct interface *ifp){ struct zebra_if *zif; struct rtadvconf *rtadv; zif = (struct zebra_if *) ifp->info; rtadv = &zif->rtadv; if (rtadv->AdvSendAdvertisements) { vty_out (vty, " ND advertised reachable time is %d milliseconds%s", rtadv->AdvReachableTime, VTY_NEWLINE); vty_out (vty, " ND advertised retransmit interval is %d milliseconds%s", rtadv->AdvRetransTimer, VTY_NEWLINE); vty_out (vty, " ND router advertisements are sent every %d seconds%s", rtadv->MaxRtrAdvInterval, VTY_NEWLINE); vty_out (vty, " ND router advertisements live for %d seconds%s", rtadv->AdvDefaultLifetime, VTY_NEWLINE); if (rtadv->AdvManagedFlag) vty_out (vty, " Hosts use DHCP to obtain routable addresses.%s", VTY_NEWLINE); else vty_out (vty, " Hosts use stateless autoconfig for addresses.%s", VTY_NEWLINE); }}#endif /* RTADV */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -