📄 iflib.c
字号:
* uses the reactivated interface. */ if (pRoute->rt_ifp == pIf) { pRoute->rt_flags &= ~RTF_BLACKHOLE; pNode->rn_flags &= ~RNF_BLACKHOLE; }#endif /* ROUTER_STACK */ return 0; }/********************************************************************************* ifRouteEnable - allow IP forwarding engine to detect routes** This routine clears the RTF_BLACKHOLE flag for all routes which use the* given interface. When set, that flag hides the corresponding route entry* from the search routine used when forwarding packets. This routine executes* when the if_up() routine enables the interface. RFC 1812 requires the* restoration of all static routes through a reactivated interface. The flag* simulates that behavior without the extra processing actual deletion and* addition requires.** RETURNS: N/A*/void ifRouteEnable ( struct ifnet * pIf /* reactivated IP interface */ ) { struct radix_node_head * rnh; if (pIf == NULL) /* Sanity check - can't occur. */ return; /* * Walk through the tree and enable any routes associated * with the interface. */ rnh = rt_tables[AF_INET]; if (rnh) rn_walktree(rnh, routeNodeEnable, (void *)pIf); return; }/********************************************************************************* routeNodeDisable - disable a route associated with the network interface** This routine sets the RTF_BLACKHOLE flag to prevent the IP forwarding* engine from detecting an existing route entry. This behavior mimics the* removal of static route entries which RFC 1812 requires for any disabled* interface. The additional effect of ignoring dynamic routes from other* sources is harmless since the IP output processing will ultimately refuse* to transmit any packets using those routes.** If the route was cloned (to support path MTU discovery), the routine* deletes that route entry. This removal allows the stack to create a* new cloned entry to the same destination based on an alternate route,* if any. To save memory, this routine also deletes any ARP entries through* the interface since the corresponding destinations are no longer reachable.** RETURNS: 0, always, to continue the tree traversal*/LOCAL int routeNodeDisable ( 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; /* * If the current node contains an ARP entry which passes through the * deactivated interface, delete it. Ignore any other ARP entries. */ 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) { if (pRoute->rt_ifp == pIf) {#ifdef ROUTER_STACK /* * An unnumbered interface may create a permanent ARP entry * which must not be deleted if the interface is disabled. */ if (pIf->if_flags & IFF_UNNUMBERED) return (0);#endif /* ROUTER_STACK */ /* * This delete operation does not use the gateway value, * since no duplicate ARP entry exists. */ rtrequest (RTM_DELETE, rt_key (pRoute), 0, rt_mask (pRoute), 0, (struct rtentry **)NULL); } return (0); } /* * Delete any cloned route which uses the deactivated interface and * ignore cloned entries which use a different interface. Since * no duplicate route exists, the gateway value is unused for this * delete operation. */ if (pRoute->rt_flags & RTF_CLONED) { if (pRoute->rt_ifp == pIf) { rtrequest (RTM_DELETE, rt_key (pRoute), 0, rt_mask (pRoute), pRoute->rt_flags, (struct rtentry **)NULL); } return (0); } /* * Set the RTF_BLACKHOLE flag for routes which use the deactivated * interface. The forwarding process will use any duplicate route * (without that flag set) attached to the same point in the tree. */#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 deactivated interface, also set the * RNF_BLACKHOLE flag so that the forwarding process will look for * an alternate route elsewhere in the tree. */ if (pRoute->rt_ifp == pIf) pNode->rn_flags |= RNF_BLACKHOLE;#else /* * Set the RTF_BLACKHOLE and RNF_BLACKHOLE flags if the entry * uses the disabled interface. */ if (pRoute->rt_ifp == pIf) { pRoute->rt_flags |= RTF_BLACKHOLE; pNode->rn_flags |= RNF_BLACKHOLE; }#endif /* ROUTER_STACK */ return 0; }/********************************************************************************* ifRouteDisable - prevent IP forwarding engine from detecting routes** This routine sets the RTF_BLACKHOLE flag for all routes which use the* given interface. That flag hides the corresponding route entry from* the search routine used when forwarding packets. This routine executes* when the if_down() routine disables the interface. RFC 1812 requires* the removal of all static routes through a disabled interface. The flag* simulates that behavior without the extra processing actual deletion* requires. Although RFC 1812 only requires removal of the static routes,* ignoring any routes from other sources is harmless, since the IP output* processing would ultimately refuse to send any packets over those routes.** RETURNS: N/A*/void ifRouteDisable ( struct ifnet * pIf /* disabled IP interface */ ) { struct radix_node_head * rnh; if (pIf == NULL) /* Sanity check - can't occur. */ return; /* * Walk through the tree and disable any routes associated * with the interface. */ rnh = rt_tables[AF_INET]; if (rnh) rn_walktree(rnh, routeNodeDisable, (void *)pIf); return; }/********************************************************************************* routeNodeCleanup - delete a route associated with a disabled interface** This routine deletes any route entry which uses a specific disabled* interface. This cleanup prevents the indefinite existence of unusable* routes when an interface is removed with the ipDetach() routine.** RETURNS: 0, always, to continue the tree traversal*/LOCAL int routeNodeCleanup ( struct radix_node * pNode, /* pointer to the node structure */ void * pArg /* pointer to the interface */ ) { struct ifnet * pIf = pArg; struct rtentry * pRoute; struct sockaddr * pDest; struct sockaddr * pGateway; struct sockaddr * pNetmask; int routeSource;#ifdef ROUTER_STACK ROUTE_ENTRY * pHead; ROUTE_ENTRY * pNext; ROUTE_ENTRY * pNextGroup; ROUTE_ENTRY * pNextRoute;#endif /* ROUTER_STACK */ pRoute = (struct rtentry *)pNode; /* The primary route and any duplicate routes all use the same netmask. */ pNetmask = rt_mask (pRoute);#ifdef ROUTER_STACK /* * The neighboring entries in the duplicate route list will change * after deleting the primary route. That delete operation will * also invalidate the current route node. Therefore, it is more * efficient and simpler to delete any duplicate entries before * deleting the primary route. */ pHead = (ROUTE_ENTRY *)pRoute; pNext = pHead->sameNode.pFrwd; pNextGroup = pHead->diffNode.pFrwd; if (pNext == NULL) { /* * Remove the next group if no duplicate * routes exist in the primary group. */ pHead = pNext = pNextGroup; } while (pHead) { pNextGroup = pHead->diffNode.pFrwd; while (pNext) { /* Save the next route before deleting the current entry. */ pNextRoute = pNext->sameNode.pFrwd; /* * Get the unique gateway IP address. Use the correct local * IP address for the internally generated interface route. */ pGateway = pNext->rtEntry.rt_gateway; if (pGateway->sa_family == AF_LINK) pGateway = pNext->rtEntry.rt_ifa->ifa_addr; /* * Get the source of the route. Ignore any route created with * a dynamic routing protocol. The owners of those routes must * delete them. */ pDest = rt_key (&pNext->rtEntry); routeSource = RT_PROTO_GET (pDest); if (routeSource == M2_ipRouteProto_other || routeSource == M2_ipRouteProto_local || routeSource == M2_ipRouteProto_icmp) { /* * Remove the entry if it uses the targeted interface. * Note: The RTF_BLACKHOLE flag also marks all these * entries, since the interface's IFF_UP flag is not set. */ if (pNext->rtEntry.rt_ifp == pIf) { rtrequestDelEqui (pDest, pNetmask, pGateway, pNext->rtEntry.rt_flags, routeSource, TRUE, TRUE, NULL); } } pNext = pNextRoute; } pHead = pNext = pNextGroup; }#endif /* ROUTER_STACK */ /* * Delete the primary route if it uses the deactivated interface. * Use the local IP address as the gateway value for the internally * generated interface route. Ignore any route created with a * dynamic routing protocol. */ pGateway = pRoute->rt_gateway; if (pGateway->sa_family == AF_LINK) pGateway = pRoute->rt_ifa->ifa_addr; pDest = rt_key (pRoute); routeSource = RT_PROTO_GET (pRoute); if (routeSource == M2_ipRouteProto_other || routeSource == M2_ipRouteProto_local || routeSource == M2_ipRouteProto_icmp) { /* * Remove the entry if it uses the targeted interface. * Note: The RTF_BLACKHOLE flag also marks all these * entries, since the interface's IFF_UP flag is not set. */ if (pRoute->rt_ifp == pIf) { rtrequestDelEqui (pDest, pNetmask, pGateway, pRoute->rt_flags, routeSource, TRUE, TRUE, NULL); } } return 0; }/********************************************************************************* ifRouteCleanup - remove hidden routes which use a disabled interface** This routine removes all route entries with the RTF_BLACKHOLE flag * which use the given interface. That flag hides the corresponding route* entry from the search routine used when forwarding packets. This routine* executes when the ipDetach() routine permanently removes the interface.* It prevents the indefinite existence of unusable hidden routes, which* can't be retrieved with ordinary search methods.** RETURNS: N/A*/void ifRouteCleanup ( struct ifnet * pIf /* disabled IP interface */ ) { struct radix_node_head * rnh; if (pIf == NULL) /* Sanity check - can't occur. */ return; /* * Walk through the tree and delete any static or internally * generated routes associated with the interface. */ rnh = rt_tables[AF_INET]; if (rnh) rn_walktree(rnh, routeNodeCleanup, (void *)pIf); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -