📄 routeutillib.c
字号:
* * This search also finds the neighboring routes within the matching * group based on any specified weight value. */ for (pTemp = pGroup; pTemp != NULL; pTemp = pTemp->sameNode.pFrwd) { /* * Save the first entry which matches the specified gateway. * The second condition is not strictly necessary, since each * gateway value is unique, but bypasses needless tests once * a match is found. */ if (gatewayFlag && pMatch == NULL) { if (ROUTE_ENTRY_GATEWAY (pTemp)->sa_family == AF_LINK) { /* * The gateway field contains an ARP template. The entry * only matches for a search using the interface's assigned * IP address as the gateway. */ if (SOCKADDR_IN (pTemp->rtEntry.rt_ifa->ifa_addr) == SOCKADDR_IN (pGateway)) { /* Specified route entry exists - save the match. */ pMatch = pTemp; } } else if (SOCKADDR_IN (ROUTE_ENTRY_GATEWAY (pTemp)) == SOCKADDR_IN (pGateway)) { /* Specified route entry exists - save the match. */ pMatch = pTemp; } } if (gatewayFlag == FALSE && pMatch == NULL) { /* Use the initial entry if no gateway is specified. */ pMatch = pGroup; } /* * The delete operation does not provide a weight value. Save * the neighboring route for the add and change operations. */ if (weight && pNext == NULL && weight < pTemp->rtEntry.rt_rmx.weight) { pNext = pTemp; } /* Halt the search after finding the matching entry and location. */ if (pMatch && pNext) break; /* * Save the current route, which eventually stores the last * entry in the list. That value is only needed if the weight * is larger than all existing entries in the group. */ pBack = pTemp; } /* * Save the correct predecessor if the weight does not place the * corresponding route at the end of the list. That value will * equal NULL if the new position is the head of the list. * * Otherwise, the preceding entry already equals the last item in the * list (which occurs when appending a new route with the maximum weight * to an existing group) or remains NULL (if the group does not exist). * No correction is needed in either case. */ if (pNext) { pBack = pNext->sameNode.pBack; } /* * Update the chosen adjacent group, if needed. The results of the * previous search are only valid if the weight value corresponds * to the initial entry in a group, the selected route is not part * of the first group, and the weight is reduced enough to alter * the relative position of the selected group. */ if (pNext == pGroup) { /* * The specified weight corresponds to the initial entry in * a group, so either the weight of the group is reduced or it * corresponds to the first entry in a new group. Update the * neighboring groups selected with the earlier search if needed. */ if (pGroup && pNextGroup == NULL) { /* * The group exists and no successor is assigned, so the * earlier search found a matching group before detecting * a different group with a higher weight than the specified * value. This condition indicates that the reduced weight does * not change the relative location of the matching group. */ pNextGroup = pGroup->diffNode.pFrwd; pLastGroup = pGroup->diffNode.pBack; } } /* * Finish assigning the adjacent group, if needed. The earlier search * only selects an adjacent group when the specified weight value is * less than the weight of the initial entry in the matching group or * is the first entry in a new group. */ if (pNext != pGroup && weight) { /* * Find the correct adjacent group for an unchanged weight or an * increase in the weight value of an entry in an existing group. */ if (pMatch == NULL || pMatch != pGroup) { /* * If the selected route is not the initial entry, it is * not connected to any adjacent groups. */ pLastGroup = pNextGroup = NULL; } else if (weight == pMatch->rtEntry.rt_rmx.weight) { /* * The earlier search only finds an adjacent group when the * weight of the group is reduced. Set the correct adjacent * groups since the location in the group list is unchanged. */ pNextGroup = pGroup->diffNode.pFrwd; pLastGroup = pGroup->diffNode.pBack; } else { /* * The initial entry in the group list uses an increased * weight. Set the correct weight value and find the new * adjacent group. */ pTemp = pMatch->sameNode.pFrwd; nextWeight = weight; /* * Use the weight value of the next initial group entry if * the new weight will change the location of the current * initial entry in the group. */ if (pTemp && weight > pTemp->rtEntry.rt_rmx.weight) nextWeight = pTemp->rtEntry.rt_rmx.weight; if (pMatch->rtEntry.rt_rmx.weight == nextWeight) { /* * The next entry in the list used the same weight * as the initial entry, so the position is unchanged. */ pNextGroup = pGroup->diffNode.pFrwd; pLastGroup = pGroup->diffNode.pBack; } else { /* * The minimum weight of the group increased. Find the * new location. */ for (pTemp = pGroup; pTemp != NULL; pTemp = pTemp->diffNode.pFrwd) { if (nextWeight < pTemp->rtEntry.rt_rmx.weight) { pNextGroup = pTemp; break; } /* * Save the current entry in case the next entry * is the correct successor. */ pLastGroup = pTemp; } /* * Set the preceding group to the correct value if the * increased weight does not change the relative location * of the group. */ if (pLastGroup == pGroup) pLastGroup = pGroup->diffNode.pBack; } } } /* * Correct the adjacent route within the matching group, if needed. * That search places a route after any other entries with the same * weight. This behavior is not correct when the weight of an existing * entry does not change. */ if (pMatch && weight == pMatch->rtEntry.rt_rmx.weight) { pNext = pMatch->sameNode.pFrwd; pBack = pMatch->sameNode.pBack; } /* * Save the initial entry in the group and any adjacent entries in * the supplied parameters. The delete operation does not retrieve * any neighboring routes or specify the weight needed to assign * those values. */ if (ppGroup) *ppGroup = pGroup; if (ppLastGroup) *ppLastGroup = pLastGroup; if (ppNextGroup) *ppNextGroup = pNextGroup; if (ppLast) *ppLast = pBack; if (ppNext) *ppNext = pNext; return (pMatch); }/********************************************************************************* routeDescFill - copies the relevant routing information ** This routine copies routing information from a ROUTE_ENTRY structure* to the corresponding fields in a ROUTE_DESC structure. The callback* messages and the results of the public lookup routine use the resulting* structure. The delete operation provides a <copyAllFlag> parameter of* FALSE since it already assigns the destination and netmask of the given* <pRouteDesc> structure. All other operations set that parameter to TRUE* to get all relevant values from the route entry which the <pRoute>* parameter provides.** RETURNS: N/A** NOMANUAL*/void routeDescFill ( ROUTE_ENTRY * pRouteEntry, /* reference to existing route */ ROUTE_DESC * pRouteDesc, /* buffers for route information */ BOOL copyAllFlag /* copy all information? */ ) { if (copyAllFlag) { if (ROUTE_ENTRY_KEY (pRouteEntry) != NULL) bcopy ( (char*) (ROUTE_ENTRY_KEY (pRouteEntry)), (char*) (pRouteDesc->pDstAddr), sizeof (struct sockaddr)); if ( (ROUTE_ENTRY_MASK (pRouteEntry) != NULL) && (pRouteDesc->pNetmask != 0)) bcopy ( (char*)ROUTE_ENTRY_MASK (pRouteEntry), (char*)pRouteDesc->pNetmask, sizeof (struct sockaddr)); else /* If it is a host route, set netmask to NULL */ pRouteDesc->pNetmask = NULL; } if ( (ROUTE_ENTRY_GATEWAY (pRouteEntry))->sa_family == AF_LINK) { bcopy ( (char*)pRouteEntry->rtEntry.rt_ifa->ifa_addr, (char*)pRouteDesc->pGateway, sizeof (struct sockaddr)); } else { bcopy ( (char*)ROUTE_ENTRY_GATEWAY (pRouteEntry), (char*)pRouteDesc->pGateway, sizeof (struct sockaddr)); } pRouteDesc->flags = ROUTE_ENTRY_FLAGS (pRouteEntry); pRouteDesc->protoId = RT_PROTO_GET (ROUTE_ENTRY_KEY (pRouteEntry)); pRouteDesc->pIf = pRouteEntry->rtEntry.rt_ifp; pRouteDesc->value1 = pRouteEntry->rtEntry.rt_rmx.value1; pRouteDesc->value2 = pRouteEntry->rtEntry.rt_rmx.value2; pRouteDesc->value3 = pRouteEntry->rtEntry.rt_rmx.value3; pRouteDesc->value4 = pRouteEntry->rtEntry.rt_rmx.value4; pRouteDesc->value5 = pRouteEntry->rtEntry.rt_rmx.value5; pRouteDesc->routeTag = pRouteEntry->rtEntry.rt_rmx.routeTag; pRouteDesc->weight = pRouteEntry->rtEntry.rt_rmx.weight; pRouteDesc->primaryRouteFlag = pRouteEntry->primaryRouteFlag; return; }/********************************************************************************* routeMetricsCopy - copies the extra metric information** This routine copies all the additional metric information from* a ROUTE_DESC structure to a ROUTE_ENTRY structure. It completes* the modification of an existing entry and stores the initial data* when creating a new route entry.** RETURNS: N/A** NOMANUAL*/void routeMetricsCopy ( ROUTE_DESC * pRouteDesc, /* buffers with new settings for route */ ROUTE_ENTRY * pRouteEntry /* reference to existing route entry */ ) { pRouteEntry->rtEntry.rt_rmx.value1 = pRouteDesc->value1; pRouteEntry->rtEntry.rt_rmx.value2 = pRouteDesc->value2; pRouteEntry->rtEntry.rt_rmx.value3 = pRouteDesc->value3; pRouteEntry->rtEntry.rt_rmx.value4 = pRouteDesc->value4; pRouteEntry->rtEntry.rt_rmx.value5 = pRouteDesc->value5; pRouteEntry->rtEntry.rt_rmx.routeTag = pRouteDesc->routeTag; pRouteEntry->rtEntry.rt_rmx.weight = pRouteDesc->weight; return; }/********************************************************************************* routeEntryFree - free a ROUTE_ENTRY structure** This routine removes a duplicate route entry. It executes when that* entry is specifically deleted or when a new copy of the entry is* installed as the visible route because of a weight change.** It also executes within the internal rtfree() routine of the kernel.* That usage allows the original code to handle the reference counts* for duplicate and visible route entries. Since the current library* does not permit multiple references to the duplicate routes, this* ability is only important if future versions provide that feature.** When executing within the rtfree() routine, the <countFlag> parameter* is FALSE since that routine decrements the reference count for the* associated interface address. That value is also FALSE when this* routine releases a partial route before the reference count increases.** RETURNS: N/A ** NOMANUAL*/void routeEntryFree ( ROUTE_ENTRY * pRouteEntry, /* existing duplicate route entry */ BOOL countFlag /* decrement interface reference count? */ ) { if (countFlag && pRouteEntry->rtEntry.rt_ifa) pRouteEntry->rtEntry.rt_ifa->ifa_refcnt--; if(pRouteEntry->rtEntry.rt_genmask) KHEAP_FREE( (char *)pRouteEntry->rtEntry.rt_genmask); if(pRouteEntry->rtEntry.rt_nodes[0].rn_u.rn_leaf.rn_Mask) KHEAP_FREE(pRouteEntry->rtEntry.rt_nodes[0].rn_u.rn_leaf.rn_Mask); KHEAP_FREE( (char *)pRouteEntry); }#endif /* ROUTER_STACK */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -