📄 ospf_sysctl.c
字号:
/* control data consists of the interface address that has been * deleted */ sptr_interface_addr = (struct sockaddr *)sptr_ctl_data; if ( sptr_interface_addr == NULL ) return; ospf_sysctl_interfaceAddrDelete( interface_index, sptr_interface_addr ); } break; case RTM_DELEXTRA: break; case RTM_IFINFO: { ulong_t interface_flags; /* the control data consists of the interface flag */ interface_flags = (ulong_t)sptr_ctl_data; ospf_sysctl_interfaceFlagChange( interface_index, interface_flags ); } break; case RTM_LOSING: case RTM_MISS: case RTM_LOCK: case RTM_OLDADD: case RTM_OLDDEL: case RTM_RESOLVE: case RTM_ADDEXTRA: case RTM_CHANGE: case RTM_NEWCHANGE: case RTM_NEWIPROUTE: case RTM_OLDIPROUTE: case RTM_REDIRECT: case RTM_ADD: case RTM_DELETE: default: break; } return;}/********************************************************************************* ospf_sysctl_rtableWalk - retrieve routing table information** This routine retrieve the routing table information. This routine behaves differently* based on the <asCapable>, <redistributeStatic>, <redistributeRIP>, redistributeBGP>* and <redistributeDefault> parameters.** The 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.** The routine will only execute if OSPF is configured as the Autonomous System Border* Router (ASBR) (i.e. the ospfASBdrRtrStatus General Group object in MIB API is set* to true).** RETURNS: OK or ERROR** ERRNO: N/A** NOMANUAL*/STATUS ospf_sysctl_rtableWalk( enum BOOLEAN asCapable, enum BOOLEAN redistributeStatic, enum BOOLEAN redistributeRIP, enum BOOLEAN redistributeBGP, enum BOOLEAN redistributeDefault ){ 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; IP_ROUTE_ENTRY ip_route; /* do nothing if the ospf router is not configured as ASBR */ if ( asCapable == FALSE ) return OK; /* do nothing if no redistribution option is set */ if ( (redistributeStatic == FALSE) && (redistributeRIP == FALSE) && (redistributeBGP == FALSE) && (redistributeDefault == FALSE) ) return OK; /* * 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 (ERROR); } /* estimated routing table size should not be zero */ if ( rtSize == 0 ) return ERROR; /* * 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 ERROR; } 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 (ERROR); } /* * 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 dealing 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; /* SPR 83418 -- Begin */ /* Check if mask is NULL. if it is this could be either a full mask or a * default route if its a full mask set to all ffs */ if((pNetmask == NULL) && (((struct sockaddr_in *)pDstAddr)->sin_addr.s_addr != 0x00000000)) { pNetmask = (struct sockaddr*)table_malloc(1,sizeof(struct sockaddr)); if(pNetmask == NULL) { if ( sysCtlDebug ) { inet_ntoa_b( ((struct sockaddr_in *)pDstAddr)->sin_addr, address); printf("failed to allocate memory for route mask\n"); continue; } ((struct sockaddr_in *)pNetmask)->sin_addr.s_addr = 0xffffffff; ((struct sockaddr_in *)pNetmask)->sin_len = sizeof(struct sockaddr_in); } } /* SPR 83418 -- End */ /* * default route has no netmask. If default route redistribution capability * is turned off, ignore this route. */ if ( (pNetmask == NULL) && (redistributeDefault == FALSE) ) continue; 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; } /* SPR 83418 -- Begin */ if ( (rtm->rtm_flags & RTF_GATEWAY) != RTF_GATEWAY ) /* SPR 83418 -- End */ { /* * route is not gateway and is direct connected route. Sanity check to * determine if the route is also a default route. Default route * has destination address 0.0.0.0, netmask 0.0.0.0, next hop of non-zero * value and rtm flags of 0x101 (RTF_CLONING and RTF_UP). */ if ( rtm->rtm_flags & (RTF_CLONING | RTF_UP) ) { if ( (dstAddr != 0) || (netmask != 0) ) continue; /* ignore the direct connected route */ /* * if the default redistribution capable is turned off, ignore this * route even if it is the default route. */ if ( redistributeDefault == FALSE ) { if ( sysCtlDebug ) { inet_ntoa_b( ((struct sockaddr_in *)pDstAddr)->sin_addr, address); printf("Ignore route %s - Default redistribution not set\n", address); } continue; } } else continue; /* direct connected route with other RTF flags, ignore it */ } if ( routeProto == M2_ipRouteProto_ospf ) continue; else if ( routeProto == M2_ipRouteProto_rip ) { /* * ignore routes added by RIP if the RIP redistribution capability is turned * off */ if ( redistributeRIP == FALSE ) { if ( sysCtlDebug ) { inet_ntoa_b( ((struct sockaddr_in *)pDstAddr)->sin_addr, address); printf("Ignore route %s - RIP redistribution not set\n", address); } continue; } /* * The VxWorks RIP implementation stores the advertised metric * in the (normally unused) rmx_hopcount field of the kernel's * routing table. */ metric = rtm->rtm_rmx.rmx_hopcount; /* * the largest hop count for a RIP route is 15. If the metric value
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -