📄 iflib.c
字号:
/******************************************************************************** _routeNodeDelete - delete the route associated with the network interface** This routine deletes the route that has been associated with the* specified interface. Only the following route is deleted:** \ml* \m -* the network route added by us when the interface address is initialized* \m -* the static route added by the administrator that passes through the interface* \me** Routes added by routing protocols are not deleted.** INTERNAL* This function only works for address families AF_INET.** RETURNS:* 0*/LOCAL int _routeNodeDelete ( struct rtentry * pRt, /* pointer to the rtentry structure */ int * pDeleted /* counts # of deleted routes */ ) { FAST struct sockaddr * destAddr = NULL; FAST struct sockaddr * gateAddr; int proto; long mask;#ifdef DEBUG char aStr [INET_ADDR_LEN]; char bStr [INET_ADDR_LEN]; char cStr [INET_ADDR_LEN];#endif /* DEBUG */ destAddr = rt_key(pRt); /* get the destination address */ gateAddr = pRt->rt_gateway; /* get the gateway address */#ifdef DEBUG inet_ntoa_b (((struct sockaddr_in *)destAddr)->sin_addr, aStr); logMsg ("_routeNodeDelete: Called for %s, if=%s%d, proto=%d, type = %s\n", (int)aStr, (int)(pRt->rt_ifp->if_name), pRt->rt_ifp->if_unit, RT_PROTO_GET (destAddr), (int)"NON_ARP", 0); #endif /* DEBUG */ /* * We delete only statically added routes, interface routes and ICMP * routes. All other routes belong to the respective routing protocols * that should be deleting them */ if ((proto = RT_PROTO_GET (destAddr)) != M2_ipRouteProto_other && proto != M2_ipRouteProto_local && proto != M2_ipRouteProto_icmp) return (0); /* If it is an interface route, get the interface address */ if (gateAddr->sa_family == AF_LINK) gateAddr = pRt->rt_ifa->ifa_addr; if (rt_mask (pRt) == NULL) { mask = 0; } else { mask = ((struct sockaddr_in *) rt_mask (pRt))->sin_addr.s_addr; }#ifdef DEBUG inet_ntoa_b (((struct sockaddr_in *)destAddr)->sin_addr, aStr); if (mask) inet_ntoa_b (((struct sockaddr_in *) rt_mask (pRt))->sin_addr, bStr); else bStr[0] = 0; inet_ntoa_b (((struct sockaddr_in *)gateAddr)->sin_addr, cStr); logMsg ("_routeNodeDelete: Deleting following route: dest = %s, nmask = %s," "gate = %s\n", (int)aStr, (int)bStr, (int)cStr, 0, 0, 0);#endif /* DEBUG */ /* Now delete the route */ mRouteEntryDelete (((struct sockaddr_in*)destAddr)->sin_addr.s_addr, ((struct sockaddr_in*)gateAddr)->sin_addr.s_addr, mask, TOS_GET (destAddr), pRt->rt_flags, proto); /* Increment the deletion counter */ ++(*pDeleted); return 0; }/******************************************************************************** ifAllRoutesDelete - delete all routes associated with a network interface** This routine deletes all routes that have been associated with the* specified interface. The routes deleted are:* \ml* \m - * the network route added when the interface address is initialized* \m - * the static routes added by the administrator* \m - * ARP routes passing through the interface* \me* Routes added by routing protocols are not deleted.** INTERNAL* This function only works for address families AF_INET.** RETURNS:* The number of routes deleted, or ERROR if an interface is not specified.*/int ifAllRoutesDelete ( char *ifName, /* name of the interface */ int unit /* unit number for this interface */ ) { FAST struct ifnet *ifp; int deleted; int args[2]; struct radix_node_head * rnh; if (ifName == NULL) return (ERROR); deleted = 0;#ifdef VIRTUAL_STACK for (ifp = _ifnet; ifp; ifp = ifp->if_next)#else for (ifp = ifnet; ifp; ifp = ifp->if_next)#endif /* VIRTUAL_STACK */ { if (ifp->if_unit != unit || strcmp(ifName, ifp->if_name)) continue; /* * Walk through the entire table and delete routes associated * with the interface. */ args[0] = (int)ifp; args[1] = (int)&deleted; rnh = rt_tables[AF_INET]; if (rnh) rn_walktree(rnh, routeNodeDelete, (void *)args); break; } return (deleted); }/********************************************************************************* ifunit - map an interface name to an interface structure pointer** This routine returns a pointer to a network interface structure for <name> or* NULL if no such interface exists. For example:* .CS* struct ifnet *pIf;* ...* pIf = ifunit ("ln0");* .CE* `pIf' points to the data structure that describes the first network interface* device if ln0 is mapped successfully.** RETURNS:* A pointer to the interface structure, or NULL if an interface is not* found.**/struct ifnet *ifunit ( register char *ifname /* name of the interface */ ) { register char *cp; register struct ifnet *ifp; int unit; unsigned len; char *ep, c; char name [IFNAMSIZ]; if (ifname == NULL) return ((struct ifnet *)0); strncpy (name, ifname, IFNAMSIZ); for (cp = name; cp < name + IFNAMSIZ && *cp; cp++) if (*cp >= '0' && *cp <= '9') break; if (*cp == '\0' || cp == name + IFNAMSIZ) return ((struct ifnet *)0); /* * Save first char of unit, and pointer to it, * so we can put a null there to avoid matching * initial substrings of interface names. */ len = cp - name + 1; c = *cp; ep = cp; for (unit = 0; *cp >= '0' && *cp <= '9'; ) unit = unit * 10 + *cp++ - '0'; *ep = 0;#ifdef VIRTUAL_STACK for (ifp = _ifnet; ifp; ifp = ifp->if_next)#else for (ifp = ifnet; ifp; ifp = ifp->if_next)#endif /* VIRTUAL_STACK */ { if (bcmp(ifp->if_name, name, len)) continue; if (unit == ifp->if_unit) break; } *ep = c; return (ifp); }/****************************************************************************** ifNameToIfIndex - returns the interface index given the interface name** This routine returns the interface index for the interface named by the * <ifName> parameter, which proviedes a string describing the full interface * name. For example, "fei0".** RETURNS: The interface index, if the interface could be located, * 0, otherwise. 0 is not a valid value for interface index.*/unsigned short ifNameToIfIndex ( char * ifName /* a string describing the full interface name. */ /* e.g., "fei0" */ ) { FAST struct ifnet * ifp; int s; int ifIndex; /* Call ifunit under splnet protection as it is not protected */ s = splnet (); ifp = ifunit (ifName); ifIndex = (ifp != NULL) ? ifp->if_index : 0; splx (s); return (ifIndex); }/****************************************************************************** ifIndexToIfName - returns the interface name given the interface index** This routine returns the interface name for the interface referenced* by the <ifIndex> parameter. ** \is* \i <ifIndex>* The index for the interface.* \i <ifName>* The location where the interface name is copied* \ie** RETURNS: OK on success, ERROR otherwise.*/STATUS ifIndexToIfName ( unsigned short ifIndex,/* Interface index */ char * ifName /* Where the name is to be stored */ ) { FAST struct ifnet * ifp; int s; if (ifName == NULL) return (ERROR); s = splnet (); if ((ifp = ifIndexToIfp (ifIndex)) == NULL) { splx (s); return (ERROR); } sprintf (ifName, "%s%d", ifp->if_name, ifp->if_unit); splx (s); return (OK); }/********************************************************************************* routeNodeEnable - activate a route associated with the network interface** This routine clears the RTF_BLACKHOLE flag, which allows the IP forwarding* engine to detect an existing route entry. This behavior mimics recreating* static route entries, which RFC 1812 requires for any reactivated interface.* Changing the flag in dynamic routes from other sources has no effect since* the IP output processing will only retrieve the primary route.** If a route was cloned (to support path MTU discovery), this routine* deletes that route entry. This removal allows the stack to create a new* cloned entry to the same destination based on a restored, more specific* route, if any. Otherwise, it will recreate the same cloned entry.** RETURNS: 0, always, to continue the tree traversal*/LOCAL int routeNodeEnable ( struct radix_node * pNode, /* pointer to the node structure */ void * pArg /* pointer to the interface */ ) { struct ifnet * pIf = pArg; struct rtentry * pRoute;#ifdef ROUTER_STACK ROUTE_ENTRY * pHead; ROUTE_ENTRY * pNext;#endif /* ROUTER_STACK */ pRoute = (struct rtentry *)pNode; /* * Ignore any ARP entries, which use other active interfaces. The disable * routine removed all ARP entries which use the reactivated interface. */ if ((pRoute->rt_flags & RTF_HOST) && (pRoute->rt_flags & RTF_LLINFO) && (pRoute->rt_flags & RTF_GATEWAY) == 0 && pRoute->rt_gateway && pRoute->rt_gateway->sa_family == AF_LINK) { return (0); } /* * Delete any other cloned route (which uses a different interface) to * allow use of a more specific route through the reactivated interface. * Since no duplicate routes exist, the gateway value is unused in * this delete operation. */ if (pRoute->rt_flags & RTF_CLONED) { rtrequest (RTM_DELETE, rt_key (pRoute), 0, rt_mask (pRoute), pRoute->rt_flags, (struct rtentry **)NULL); return (0); } /* * Clear the RTF_BLACKHOLE flag for routes which use the enabled * interface. The forwarding process will use any duplicate route * attached to the same point in the tree if the primary route is * not available. */#ifdef ROUTER_STACK pHead = pNext = (ROUTE_ENTRY *)pRoute; while (pHead) { while (pNext) { if (pNext->rtEntry.rt_ifp == pIf) { ((struct rtentry *)pNext)->rt_flags &= ~RTF_BLACKHOLE; } pNext = pNext->sameNode.pFrwd; } pHead = pNext = pHead->diffNode.pFrwd; } /* * If the primary route uses the reactivated interface, also clear the * RNF_BLACKHOLE flag so that the forwarding process will not look * for an alternate route elsewhere in the tree. */ if (pRoute->rt_ifp == pIf) pNode->rn_flags &= ~RNF_BLACKHOLE;#else /* * Clear the RTF_BLACKHOLE and RNF_BLACKHOLE flags if the entry
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -