X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FIPStack%2Frouting.c;h=3153ef269efa016715d173fd5921505ec2b5746f;hb=4c76c235551f3f936a20b17cfe727578644493f1;hp=7173d1f32eba0dc0273806e21ebf55343530ef8b;hpb=51ab5f489bc356940c95cc936fd0508e8f07ea97;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/IPStack/routing.c b/KernelLand/Modules/IPStack/routing.c index 7173d1f3..3153ef26 100644 --- a/KernelLand/Modules/IPStack/routing.c +++ b/KernelLand/Modules/IPStack/routing.c @@ -20,13 +20,14 @@ extern tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const char *Filename); char *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos); tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name); int IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags); - int IPStack_RouteDir_Relink(tVFS_Node *Node, const char *OldName, const char *NewName); + int IPStack_RouteDir_Unlink(tVFS_Node *Node, const char *OldName); tRoute *_Route_FindExactRoute(int Type, void *Network, int Subnet, int Metric); int _Route_ParseRouteName(const char *Name, void *Addr, int *SubnetBits, int *Metric); int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data); // - Route Management tRoute *IPStack_Route_Create(int AddrType, void *Network, int SubnetBits, int Metric); tRoute *IPStack_AddRoute(const char *Interface, void *Network, int SubnetBits, void *NextHop, int Metric); +tRoute *_Route_FindInterfaceRoute(int AddressType, void *Address); tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address); // - Individual Routes int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data); @@ -42,7 +43,7 @@ tVFS_NodeType gIP_RouteDirNodeType = { .ReadDir = IPStack_RouteDir_ReadDir, .FindDir = IPStack_RouteDir_FindDir, .MkNod = IPStack_RouteDir_MkNod, - .Relink = IPStack_RouteDir_Relink, + .Unlink = IPStack_RouteDir_Unlink, .IOCtl = IPStack_RouteDir_IOCtl }; tVFS_Node gIP_RouteNode = { @@ -112,17 +113,25 @@ tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name) rt = IPStack_FindRoute(type, NULL, addrData); if(!rt) return NULL; - if( rt->Interface ) + if( !rt->Interface ) { - // Return the interface node - // - Sure it's hijacking it from inteface.c's area, but it's - // simpler this way - return &rt->Interface->Node; + LOG("Why does this route not have a node? trying to find an iface for the next hop"); + + rt = _Route_FindInterfaceRoute(type, rt->NextHop); + if(!rt) { + Log_Notice("Cannot find route to next hop '%s'", + IPStack_PrintAddress(type, rt->NextHop)); + return NULL; + } } - else - { + if( !rt->Interface ) { + Log_Notice("Routes", "No interface for route %p, what the?", rt); return NULL; } + // Return the interface node + // - Sure it's hijacking it from inteface.c's area, but it's + // simpler this way + return &rt->Interface->Node; } else if( Name[0] == '#' ) { @@ -186,7 +195,7 @@ int IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags) /** * \brief Rename / Delete a route */ -int IPStack_RouteDir_Relink(tVFS_Node *Node, const char *OldName, const char *NewName) +int IPStack_RouteDir_Unlink(tVFS_Node *Node, const char *OldName) { tRoute *rt; @@ -203,29 +212,15 @@ int IPStack_RouteDir_Relink(tVFS_Node *Node, const char *OldName, const char *Ne rt = _Route_FindExactRoute(type, addr, subnet, metric); } - if( NewName == NULL ) - { - // Delete the route - tRoute *prev = NULL; - for(tRoute *r = gIP_Routes; r && r != rt; prev = r, r = r->Next); - - if(prev) - prev->Next = rt->Next; - else - gIP_Routes = rt->Next; - free(rt); - } - else - { - // Change the route - int type = _Route_ParseRouteName(NewName, NULL, NULL, NULL); - if(type <= 0) return -EINVAL; - Uint8 addr[IPStack_GetAddressSize(type)]; - int subnet, metric; - _Route_ParseRouteName(NewName, addr, &subnet, &metric); + // Delete the route + tRoute *prev = NULL; + for(tRoute *r = gIP_Routes; r && r != rt; prev = r, r = r->Next); - return -ENOTIMPL; - } + if(prev) + prev->Next = rt->Next; + else + gIP_Routes = rt->Next; + free(rt); return 0; } @@ -435,13 +430,56 @@ tRoute *IPStack_AddRoute(const char *Interface, void *Network, int SubnetBits, v return rt; } +/** + * \brief Locates what interface should be used to get directly to an address + */ +tRoute *_Route_FindInterfaceRoute(int AddressType, void *Address) +{ + tRoute *best = NULL, *rt; + int addrSize = IPStack_GetAddressSize(AddressType); + for( tInterface *iface = gIP_Interfaces; iface; iface = iface->Next ) + { + if( iface->Type != AddressType ) continue; + + // Check if the address matches + if( !IPStack_CompareAddress(AddressType, iface->Address, Address, iface->SubnetBits) ) + continue; + + rt = &iface->Route; + if( !rt->Interface ) + { + memcpy(rt->Network, iface->Address, addrSize); + memset(rt->NextHop, 0, addrSize); + rt->Metric = DEFAUTL_METRIC; + rt->SubnetBits = iface->SubnetBits; + rt->Interface = iface; + } + + if( best ) { + // More direct routes are preferred + if( best->SubnetBits > rt->SubnetBits ) { + LOG("Skipped - less direct (%i < %i)", rt->SubnetBits, best->SubnetBits); + continue; + } + // If equally direct, choose the best metric + if( best->SubnetBits == rt->SubnetBits && best->Metric < rt->Metric ) { + LOG("Skipped - higher metric (%i > %i)", rt->Metric, best->Metric); + continue; + } + } + + best = rt; + } + + return best; +} + /** */ tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address) { tRoute *rt; tRoute *best = NULL; - tInterface *iface; int addrSize; ENTER("iAddressType pInterface sAddress", @@ -460,7 +498,7 @@ tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address) for( rt = gIP_Routes; rt; rt = rt->Next ) { // Check interface - if( Interface && rt->Interface != Interface ) continue; + if( Interface && rt->Interface && rt->Interface != Interface ) continue; // Check address type if( rt->AddressType != AddressType ) continue; @@ -489,37 +527,7 @@ tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address) // Check against implicit routes if( !best && !Interface ) { - for( iface = gIP_Interfaces; iface; iface = iface->Next ) - { - if( Interface && iface != Interface ) continue; - if( iface->Type != AddressType ) continue; - - - // Check if the address matches - if( !IPStack_CompareAddress(AddressType, iface->Address, Address, iface->SubnetBits) ) - continue; - - if( best ) { - // More direct routes are preferred - if( best->SubnetBits > rt->SubnetBits ) { - LOG("Skipped - less direct (%i < %i)", rt->SubnetBits, best->SubnetBits); - continue; - } - // If equally direct, choose the best metric - if( best->SubnetBits == rt->SubnetBits && best->Metric < rt->Metric ) { - LOG("Skipped - higher metric (%i > %i)", rt->Metric, best->Metric); - continue; - } - } - - rt = &iface->Route; - memcpy(rt->Network, iface->Address, addrSize); - memset(rt->NextHop, 0, addrSize); - rt->Metric = DEFAUTL_METRIC; - rt->SubnetBits = iface->SubnetBits; - - best = rt; - } + best = _Route_FindInterfaceRoute(AddressType, Address); } if( !best && Interface ) { @@ -559,6 +567,8 @@ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data) { tRoute *rt = Node->ImplPtr; int addrSize = IPStack_GetAddressSize(rt->AddressType); + + ENTER("pNode iID pData", Node, ID, Data); switch(ID) { @@ -567,57 +577,57 @@ int IPStack_Route_IOCtl(tVFS_Node *Node, int ID, void *Data) // Get Next Hop case 4: - if( !CheckMem(Data, addrSize) ) return -1; + if( !CheckMem(Data, addrSize) ) LEAVE_RET('i', -1); memcpy(Data, rt->NextHop, addrSize); - return 1; + LEAVE_RET('i', 1); // Set Next Hop case 5: - if( Threads_GetUID() != 0 ) return -1; - if( !CheckMem(Data, addrSize) ) return -1; + if( Threads_GetUID() != 0 ) LEAVE_RET('i', -1); + if( !CheckMem(Data, addrSize) ) LEAVE_RET('i', -1); memcpy(rt->NextHop, Data, addrSize); - return 1; + LEAVE_RET('i', 1); // Get interface name case 6: if( !rt->Interface ) { if(Data && !CheckMem(Data, 1) ) - return -1; + LEAVE_RET('i', -1); if(Data) *(char*)Data = 0; - return 0; + LEAVE_RET('i', 0); } if( Data ) { if( !CheckMem(Data, strlen(rt->Interface->Name) + 1) ) - return -1; + LEAVE_RET('i', -1); strcpy(Data, rt->Interface->Name); } - return strlen(rt->Interface->Name); + LEAVE_RET('i', strlen(rt->Interface->Name)); // Set interface name case 7: if( Threads_GetUID() != 0 ) - return -1; + LEAVE_RET('i', -1); if( !CheckString(Data) ) - return -1; + LEAVE_RET('i', -1); else { tInterface *iface; tVFS_Node *tmp; tmp = IPStack_Root_FindDir(NULL, Data); if(!tmp) - return -1; + LEAVE_RET('i', -1); iface = tmp->ImplPtr; if(tmp->Type->Close) tmp->Type->Close(tmp); if( iface->Type != rt->AddressType ) - return -1; + LEAVE_RET('i', -1); // TODO: Other checks? rt->Interface = iface; } - return 0; + LEAVE_RET('i', 0); default: - return -1; + LEAVE_RET('i', -1); } }