Multiple IPStack Related changes (and other bugfixes)
authorJohn Hodge <[email protected]>
Fri, 19 Nov 2010 15:48:01 +0000 (23:48 +0800)
committerJohn Hodge <[email protected]>
Fri, 19 Nov 2010 15:48:01 +0000 (23:48 +0800)
- Added route determining to arp.c
- Changed route source API to take an interface pointer
- Fixed loopback device behavior ('LOOPBACK' is a special adapter path)
- Required fixing the fifo driver
 > Size on /Defices/fifo directory should be 1, not 0
 > Set default fifo to be blocking
- Slight change to ifconfig to ignore iterfaces that return a -1 type,
  or do not conform to the spec.
- Fixed triple fault when a kernel thread is spawned before init is started
  (caused by a kernel stack being marked as COW, causing an uncatched double
  fault)

Kernel/arch/x86/mm_virt.c
Kernel/arch/x86/proc.asm
Kernel/arch/x86/proc.c
Kernel/drv/fifo.c
Modules/IPStack/arp.c
Modules/IPStack/interface.c
Modules/IPStack/ipstack.h
Modules/IPStack/main.c
Modules/IPStack/routing.c
Usermode/Applications/ifconfig_src/main.c

index 3c893f8..2b2f02c 100644 (file)
@@ -541,37 +541,40 @@ tPAddr MM_Clone(void)
        //LOG("Allocated Directory (%x)", *gpTmpCR3);
        memsetd( gaTmpDir, 0, 1024 );
        
-       // Copy Tables
-       for( i = 0; i < 768; i ++)
-       {
-               // Check if table is allocated
-               if( !(gaPageDir[i] & PF_PRESENT) ) {
-                       gaTmpDir[i] = 0;
-                       page += 1024;
-                       continue;
-               }
-               
-               // Allocate new table
-               gaTmpDir[i] = MM_AllocPhys() | (gaPageDir[i] & 7);
-               INVLPG( &gaTmpTable[page] );
-               // Fill
-               for( j = 0; j < 1024; j ++, page++ )
+       if( Threads_GetPID() != 0 )
+       {       
+               // Copy Tables
+               for( i = 0; i < 768; i ++)
                {
-                       if( !(gaPageTable[page] & PF_PRESENT) ) {
-                               gaTmpTable[page] = 0;
+                       // Check if table is allocated
+                       if( !(gaPageDir[i] & PF_PRESENT) ) {
+                               gaTmpDir[i] = 0;
+                               page += 1024;
                                continue;
                        }
                        
-                       // Refrence old page
-                       MM_RefPhys( gaPageTable[page] & ~0xFFF );
-                       // Add to new table
-                       if(gaPageTable[page] & PF_WRITE) {
-                               gaTmpTable[page] = (gaPageTable[page] & ~PF_WRITE) | PF_COW;
-                               gaPageTable[page] = (gaPageTable[page] & ~PF_WRITE) | PF_COW;
-                               INVLPG( page << 12 );
+                       // Allocate new table
+                       gaTmpDir[i] = MM_AllocPhys() | (gaPageDir[i] & 7);
+                       INVLPG( &gaTmpTable[page] );
+                       // Fill
+                       for( j = 0; j < 1024; j ++, page++ )
+                       {
+                               if( !(gaPageTable[page] & PF_PRESENT) ) {
+                                       gaTmpTable[page] = 0;
+                                       continue;
+                               }
+                               
+                               // Refrence old page
+                               MM_RefPhys( gaPageTable[page] & ~0xFFF );
+                               // Add to new table
+                               if(gaPageTable[page] & PF_WRITE) {
+                                       gaTmpTable[page] = (gaPageTable[page] & ~PF_WRITE) | PF_COW;
+                                       gaPageTable[page] = (gaPageTable[page] & ~PF_WRITE) | PF_COW;
+                                       INVLPG( page << 12 );
+                               }
+                               else
+                                       gaTmpTable[page] = gaPageTable[page];
                        }
-                       else
-                               gaTmpTable[page] = gaPageTable[page];
                }
        }
        
@@ -685,6 +688,7 @@ tVAddr MM_NewWorkerStack()
        __asm__ __volatile__ ("mov %%esp, %0": "=r"(esp));
        __asm__ __volatile__ ("mov %%ebp, %0": "=r"(ebp));
        
+       // TODO: Thread safety
        // Find a free worker stack address
        for(base = giLastUsedWorker; base < NUM_WORKER_STACKS; base++)
        {
@@ -732,6 +736,7 @@ tVAddr MM_NewWorkerStack()
        
        // Mapping Time!
        for( addr = 0; addr < WORKER_STACK_SIZE; addr += 0x1000 )
+       //for( addr = WORKER_STACK_SIZE; addr; addr -= 0x1000 )
        {
                pages[ addr >> 12 ] = MM_AllocPhys();
                gaTmpTable[ (base + addr) >> 12 ] = pages[addr>>12] | 3;
index 732d35f..fd372db 100644 (file)
@@ -238,10 +238,11 @@ Proc_ReturnToUser:
 
 [global GetCPUNum]
 GetCPUNum:     ; TODO: Store in debug registers
-       xor eax, eax
-       str ax
-       sub ax, 0x30
-       shr ax, 3       ; ax /= 8
+;      xor eax, eax
+;      str ax
+;      sub ax, 0x30
+;      shr ax, 3       ; ax /= 8
+       mov eax, dr1
        ret
 
 ; Usermode code exported by the kernel
index 5e9d1bb..ad83c99 100644 (file)
@@ -14,6 +14,7 @@
 
 // === FLAGS ===
 #define DEBUG_TRACE_SWITCH     0
+#define DEBUG_DISABLE_DOUBLEFAULT      1
 
 // === CONSTANTS ===
 #define        SWITCH_MAGIC    0xFF5317C8      // FF SWITCH - There is no code in this area
@@ -286,7 +287,7 @@ void ArchThreads_Init(void)
        MM_FinishVirtualInit();
        #endif
        
-       #if 0
+       #if !DEBUG_DISABLE_DOUBLEFAULT
        // Initialise Double Fault TSS
        gGDT[5].BaseLow = (Uint)&gDoubleFault_TSS & 0xFFFF;
        gGDT[5].BaseMid = (Uint)&gDoubleFault_TSS >> 16;
index 83d1175..cbbd107 100644 (file)
@@ -38,6 +38,7 @@ MODULE_DEFINE(0, 0x0032, FIFO, FIFO_Install, NULL, NULL);
 tDevFS_Driver  gFIFO_DriverInfo = {
        NULL, "fifo",
        {
+       .Size = 1,
        .NumACLs = 1,
        .ACLs = &gVFS_ACL_EveryoneRW,
        .Flags = VFS_FFLAG_DIRECTORY,
@@ -80,6 +81,7 @@ int FIFO_IOCtl(tVFS_Node *Node, int Id, void *Data)
 char *FIFO_ReadDir(tVFS_Node *Node, int Id)
 {
        tPipe   *tmp = gFIFO_NamedPipes;
+       
        // Entry 0 is Anon Pipes
        if(Id == 0)     return strdup("anon");
        
@@ -216,9 +218,12 @@ Uint64 FIFO_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
        while(remaining)
        {
                // Wait for buffer to fill
-               if(pipe->Flags & PF_BLOCKING)
-                       while(pipe->ReadPos == pipe->WritePos)
+               if(pipe->Flags & PF_BLOCKING) {
+                       while(pipe->ReadPos == pipe->WritePos) {
                                Threads_Yield();
+                               //MAGIC_BREAK();
+                       }
+               }
                else
                        if(pipe->ReadPos == pipe->WritePos)
                                return 0;
@@ -325,6 +330,7 @@ tPipe *FIFO_Int_NewPipe(int Size, char *Name)
        memset(ret, 0, allocsize);
        
        ret->Name = Name;
+       ret->Flags = PF_BLOCKING;
        
        // Allocate Buffer
        ret->BufSize = Size;
index fda1b2f..9e92414 100644 (file)
@@ -1,13 +1,14 @@
 /*
  * Acess2 IP Stack
  * - Address Resolution Protocol
+ * - Part of the IPv4 protocol
  */
 #define DEBUG  0
 #include "ipstack.h"
 #include "arp.h"
 #include "link.h"
 
-#define ARPv6  1
+#define ARPv6  0
 #define        ARP_CACHE_SIZE  64
 #define        ARP_MAX_AGE             (60*60*1000)    // 1Hr
 
@@ -76,8 +77,19 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address)
        ENTER("pInterface xAddress", Interface, Address);
        
        // Check routing tables
-       // Replace address with gateway if needed
+       {
+               tRoute  *route = IPStack_FindRoute(4, Interface, &Address);
+               if( route ) {
+                       // If the next hop is defined, use it
+                       // - 0.0.0.0 as the next hop means "no next hop / direct"
+                       if( ((tIPv4*)route->NextHop)->L != 0 ) {
+                               // Recursion: see /Recursion/
+                               return ARP_Resolve4(Interface, *(tIPv4*)route->NextHop);
+                       }
+               }
+       }
        
+       // Check ARP Cache
        Mutex_Acquire( &glARP_Cache4 );
        for( i = 0; i < giARP_Cache4Space; i++ )
        {
index 445e589..c6f55ba 100644 (file)
@@ -52,6 +52,11 @@ tInterface   *gIP_Interfaces = NULL;
 tInterface     *gIP_Interfaces_Last = NULL;
 
 tSocketFile    *gIP_FileTemplates;
+
+tAdapter       gIP_LoopAdapter = {
+       DeviceLen: 8,
+       Device: "LOOPBACK"
+       };
 tMutex glIP_Adapters;
 tAdapter       *gIP_Adapters = NULL;
  int   giIP_NextIfaceId = 1;
@@ -531,6 +536,37 @@ tAdapter *IPStack_GetAdapter(const char *Path)
        
        ENTER("sPath", Path);
        
+       // Check for loopback
+       if( strcmp(Path, "LOOPBACK") == 0 )
+       {
+               // Initialise if required
+               if( gIP_LoopAdapter.DeviceFD == 0 )
+               {
+                       dev = &gIP_LoopAdapter;
+                       
+                       dev->NRef = 1;
+                       dev->DeviceLen = 8;
+                       
+                       dev->DeviceFD = VFS_Open( "/Devices/fifo/anon", VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE );
+                       if( dev->DeviceFD == -1 ) {
+                               Log_Warning("IPStack", "Unable to open FIFO '/Devices/fifo/anon' for loopback");
+                               return NULL;
+                       }
+                       
+                       dev->MacAddr.B[0] = 'A';
+                       dev->MacAddr.B[1] = 'c';
+                       dev->MacAddr.B[2] = 'e';
+                       dev->MacAddr.B[3] = 's';
+                       dev->MacAddr.B[4] = 's';
+                       dev->MacAddr.B[5] = '2';
+                       
+                       // Start watcher
+                       Link_WatchDevice( dev );
+               }
+               LEAVE('p', &gIP_LoopAdapter);
+               return &gIP_LoopAdapter;
+       }
+       
        Mutex_Acquire( &glIP_Adapters );
        
        // Check if this adapter is already open
index db93328..071c62b 100644 (file)
@@ -116,4 +116,6 @@ extern int  IPStack_AddFile(tSocketFile *File);
 extern int     IPStack_GetAddressSize(int AddressType);
 extern int     IPStack_CompareAddress(int AddressType, void *Address1, void *Address2, int CheckBits);
 
+extern tRoute  *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address);
+
 #endif
index 585f8c3..bec82b3 100644 (file)
@@ -71,10 +71,15 @@ int IPStack_Install(char **Arguments)
                        // - <HexStreamAddress> is a condensed hexadecimal stream (in big endian)
                        //      (E.g. 0A000201 for 10.0.2.1 IPv4)
                        // - <Bits> is the number of subnet bits (E.g. 24 for an IPv4 Class C)
+                       // Example: /Devices/ne2k/0,4,0A00020A,24
+                       
+                       // I could also define routes using <Interface>,<HexStreamNetwork>,<Bits>,<HexStreamGateway>
+                       // Example: 1,00000000,0,0A000201
                }
        }
        
-       gIP_LoopInterface.Adapter = IPStack_GetAdapter("/Devices/fifo/anon");
+       // Initialise loopback interface
+       gIP_LoopInterface.Adapter = IPStack_GetAdapter("LOOPBACK");
        
        DevFS_AddDevice( &gIP_DriverInfo );
        
index 51eb6db..381ddf7 100644 (file)
@@ -18,7 +18,7 @@ char  *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos);
 tVFS_Node      *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name);
  int   IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data);
  int   IPStack_Route_Create(const char *InterfaceName);
-tRoute *IPStack_FindRoute(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);
 
@@ -132,7 +132,7 @@ int IPStack_RouteDir_IOCtl(tVFS_Node *Node, int ID, void *Data)
                        if( !CheckMem(Data, sizeof(int) + IPStack_GetAddressSize(data->Type)) )
                                return -1;
                        
-                       rt = IPStack_FindRoute(data->Type, data->Addr);
+                       rt = IPStack_FindRoute(data->Type, NULL, data->Addr);
                        
                        if( !rt )
                                return 0;
@@ -200,15 +200,21 @@ int IPStack_Route_Create(const char *InterfaceName)
 
 /**
  */
-tRoute *IPStack_FindRoute(int AddressType, void *Address)
+tRoute *IPStack_FindRoute(int AddressType, tInterface *Interface, void *Address)
 {
        tRoute  *rt;
        tRoute  *best = NULL;
        
+       if( Interface && AddressType != Interface->Type )       return NULL;
+       
        for( rt = gIP_Routes; rt; rt = rt->Next )
        {
+               // Check interface
+               if( Interface && rt->Interface != Interface )   continue;
+               // Check address type
                if( rt->AddressType != AddressType )    continue;
                
+               // Check if the address matches
                if( !IPStack_CompareAddress(AddressType, rt->Network, Address, rt->SubnetBits) )
                        continue;
                
index 3f7cfc4..b80f6fa 100644 (file)
@@ -134,6 +134,11 @@ void DumpInterface(const char *Name)
        
        type = ioctl(fd, 4, NULL);
        
+       // Ignore -1 values
+       if( type == -1 ) {
+               return ;
+       }
+       
        printf("%s:\t", Name);
        {
                 int    call_num = ioctl(fd, 3, "get_device");
@@ -213,7 +218,7 @@ void AddRoute(const char *Interface, void *Dest, int MaskBits, void *NextHop)
        
        // Create route
        fd = open(IPSTACK_ROOT"/routes", 0);
-       num = ioctl(fd, ioctl(fd, 3, "add_route"), Interface);
+       num = ioctl(fd, ioctl(fd, 3, "add_route"), (char*)Interface);
        close(fd);
        
        // Open route

UCC git Repository :: git.ucc.asn.au