📄 ospf_sysctl.c
字号:
* exceeded the max, ignore this RIP route since RIP will eventually * remove this route when the garbage collection timer kicks in. If * RIP later determines that the route is again reachable, the metric * will be updated and we will receive the route change event via the * routing socket message. */ if ( metric == 0x10 ) continue; } else if ( routeProto == M2_ipRouteProto_bgp ) { /* * ignore routes added by BGP-4 if the BGP redistribution capability is * turned off */ if ( redistributeBGP == FALSE ) { if ( sysCtlDebug ) { inet_ntoa_b( ((struct sockaddr_in *)pDstAddr)->sin_addr, address); printf("Ignore route %s - BGP redistribution not set\n", address); } continue; } /* SPR 83418 -- Begin */ metric = rtm->rtm_rmx.value4; /* SPR 83418 -- End */ } else if ( routeProto == M2_ipRouteProto_local ) { /* ignore routes that are statically added if the static route redistribution * capability is turned off */ if ( redistributeStatic == FALSE) { if ( sysCtlDebug ) { inet_ntoa_b( ((struct sockaddr_in *)pDstAddr)->sin_addr, address); printf("Ignore route %s - Static Redistribution not set\n", address); } continue; } /* SPR 83418 -- Begin */ metric = rtm->rtm_rmx.value4; /* SPR 83418 -- End */ } /* SPR 78250 Start */ else if ( routeProto == M2_ipRouteProto_other ) { metric = rtm->rtm_rmx.weight; } /* SPR 78250 End */ if ( sysCtlDebug ) { printf("Redistribute route: "); inet_ntoa_b( ((struct sockaddr_in *)pDstAddr)->sin_addr, address); printf("dstAddr %s ", address); if ( pNetmask == NULL ) printf("netmask 0.0.0.0 "); else { inet_ntoa_b( ((struct sockaddr_in *)pNetmask)->sin_addr, address); printf("netmask %s ", address); } inet_ntoa_b( ((struct sockaddr_in *)pSin)->sin_addr, address); printf("gateway %s\n", address); printf("routeProto %ld, routeTag %ld, routeFlags 0x%x\n", routeProto, routeTag, rtm->rtm_flags); } /* SPR 83418 -- Begin */ memset( (char *)&ip_route, 0, sizeof(IP_ROUTE_ENTRY) ); ip_route.target = dstAddr; ip_route.mask = netmask; ip_route.gateway = nextHop; ip_route.ipRouteProto = routeProto; ip_route.metric_4 = metric; /* SPR 85050 -- Begin */ /* This is function is called to set the metric type and value */ semTake (ospf_global_mutex, WAIT_FOREVER); /* This is function is called to set the metric type and value */ if (ospf_is_protocol_redistributed (&ip_route) == FAIL) { semGive (ospf_global_mutex); continue; } semGive (ospf_global_mutex); ospf_queue_export_route_to_ospf ( ip_route.target, ip_route.mask, ip_route.metric, ip_route.gateway, routeTag, ip_route.ipRouteProto); /* SPR 83418 -- End */ /* SPR 85050 -- End */ } /* SPR 81808 */ table_free( buffer ); buffer = NULL; return OK; }/********************************************************************************* ospf_compare_sysctl_rtableWalk - retrieve routing table information and* compare if route exists** This routine searches the kernel's routing table for all routes belonging to* the AF_INET family. For every route entry retrieved from the kernel, this* routine checks the rt_flags and action is taken based on the given* redistribution option.** o only route with the RTF_GATEWAY flag set will be processed (unless the route* is a default route).* o route that has the RTF_BLACKHOLE flag set will be ignored.* o route that has the RTF_LLINFO flag set (added by ARP) will be ignored.* o route that has the RTF_HOST flag set (host route) will be ignored.* o self-originated ospf routes will be ignored.* o route added by RIP routing protocol will be redistributed to ospf only if* <redistributeRIP> is set.* o route added by BGP routing protocol will be redistributed to ospf only if* <redistributeBGP> is set.* o static route will be redistributed to ospf only if <redistributeStatic> is* set* o default route will be redistributed to ospf only if <redistributeStatic> is* set** At the time this routine is executed, it is assumed that all the OSPF protocol* data structures have been initialized.** RETURNS: TRUE or FALSE** ERRNO: N/A** NOMANUAL*/enum BOOLEAN ospf_compare_sysctl_rtableWalk ( IP_ROUTE_ENTRY * sptr_ip_route_entry ) { struct rt_msghdr *rtm; struct rt_addrinfo rtInfo; struct sockaddr *pDstAddr = NULL; struct sockaddr *pNetmask = NULL; struct sockaddr *pSin = NULL; char *buffer, *bufptr, *buflimit; size_t rtSize; int request[6], rtlen; char address[32]; long routeProto, routeTag; ulong_t dstAddr, netmask, nextHop, metric; /* * The sysctl_rtable routine provides access to internal networking data * according to the specified operations. The NET_RT_FLAGS operator * has the similar functionality as NET_RT_DUMPS operator except request[2] * specifies an RTF_xxx flag and only routing table entries with this flag * set are returned. The third argument, when non-zero, restricts the search * to a particular unit number. The first argument, when non-zero, limits * the addresses to the specified address family. */ memset( request, 0, sizeof(request) ); request[0] = AF_INET; request[1] = NET_RT_DUMP; request[2] = 0; /* not used for NET_RT_DUMP */ /* * The first call to the routine determines the amount of space needed * for the results. No data is actually copied. */ if (sysctl_rtable(request, 3, NULL, &rtSize, NULL, 0) < 0) { if (sysCtlDebug) printf("Error %x estimating size of routing table buffer\n", errno); return (FALSE); } /* estimated routing table size should not be zero */ if ( rtSize == 0 ) return FALSE; /* * Allocate the required data, and repeat the system call to copy the * actual values. */ /* SPR 81808 */ buffer = table_malloc( 1, rtSize ); if ( buffer == NULL ) { if ( sysCtlDebug ) printf("Error allocating rtable buffer size %ld.\n", (ULONG) rtSize); return FALSE; } if (sysctl_rtable(request, 3, buffer, &rtSize, NULL, 0) < 0) { if (sysCtlDebug) printf("Error %x retrieving routing table buffer.\n", errno); /* SPR 81808 */ table_free( buffer ); buffer = NULL; return (FALSE); } /* * Analyze the retrieved data. The provided buffer now contains a structure * of type rt_msghdr for each entry. */ buflimit = buffer + rtSize; for ( bufptr = buffer; bufptr < buflimit; bufptr += rtlen ) { rtm = (struct rt_msghdr *)bufptr; rtlen = rtm->rtm_msglen; metric = 0; netmask = 0; /* access the address pointer and extract the sockaddr structures into * the rtInfo array */ rtInfo.rti_addrs = rtm->rtm_addrs; rtSockAddrsXtract( (caddr_t)(rtm+1), rtlen + (caddr_t)rtm, &rtInfo ); /* Set the destination, netmask and gateway address pointers */ pDstAddr = RTA_DST_GET(&rtInfo); pSin = RTA_GATEWAY_GET(&rtInfo); pNetmask = RTA_NETMASK_GET(&rtInfo); /* * Test whether the gateway is of type AF_LINK and if so test whether it * is a real arp entry because interface initialized with RTF_CLONE flag * have a dummy gateway of AF_LINK. If it is a real arp entry then skip * to the next entry, we are only deg with gateways of type AF_INET */ if ( pSin->sa_family == AF_LINK ) { if (((struct sockaddr_dl *)pSin)->sdl_alen) pSin = NULL; else pSin = RTA_IFA_GET(&rtInfo); } /* * Ignore the route if it has no destinatin address or nexthop address * pointer */ if ( (pDstAddr == NULL) || (pSin == NULL) ) continue; dstAddr = ntohl( ((struct sockaddr_in *)pDstAddr)->sin_addr.s_addr ); nextHop = ntohl( ((struct sockaddr_in *)pSin)->sin_addr.s_addr ); routeTag = rtm->rtm_rmx.routeTag; if ( pNetmask != NULL) netmask = ntohl(((struct sockaddr_in *)pNetmask)->sin_addr.s_addr); /* * Retrieve the protocol value for the route. Route created by routing * protocols should have the protocol value set correctly. Ignore the * route if the protocol value is 0 (unknown) */ routeProto = RT_PROTO_GET( pDstAddr ); if ( routeProto == 0 ) { if ( sysCtlDebug ) { inet_ntoa_b(((struct sockaddr_in *)pDstAddr)->sin_addr,address); printf("ignore route %s - routeProto value is 0\n", address); } continue; } /* * If entry is added through ioctl() calls on a routing socket by the * link-level protocols such as ARP, ignore the entry */ if ( rtm->rtm_flags & RTF_LLINFO ) { if ( sysCtlDebug ) { inet_ntoa_b(((struct sockaddr_in *)pDstAddr)->sin_addr,address); printf("Ignore route %s - RTF_LLINFO flag set\n", address); } continue; } /* ignore the route entry if it is blackhole since it is not reachable*/ if ( rtm->rtm_flags & RTF_BLACKHOLE ) { if ( sysCtlDebug ) { inet_ntoa_b(((struct sockaddr_in *)pDstAddr)->sin_addr,address); printf("Ignore route %s - RTF_BLACKHOLE flag set\n", address); } continue; } if ( routeProto == M2_ipRouteProto_ospf ) { if ((dstAddr == sptr_ip_route_entry->target) && (netmask == sptr_ip_route_entry->mask) && (nextHop == sptr_ip_route_entry->gateway)) { /* SPR 81808 */ table_free( buffer ); buffer = NULL; return TRUE; } } else continue; } /* SPR 81808 */ table_free( buffer ); buffer = NULL; return FALSE; }#endif /* __RTM_FOR_SYNTH__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -