net: hook together all the networking kernel bits into z80pack
authorAlan Cox <alan@linux.intel.com>
Sun, 10 Jan 2016 16:23:58 +0000 (16:23 +0000)
committerAlan Cox <alan@linux.intel.com>
Sun, 10 Jan 2016 16:23:58 +0000 (16:23 +0000)
This doesn't give us anything remotely useful yet but means it's possible
to start testing out the syscall paths a bit and seeing what is needed
to finish the job off

Kernel/include/kdata.h
Kernel/include/netdev.h
Kernel/include/syscall_name.h
Kernel/inode.c
Kernel/kdata.c
Kernel/platform-z80pack/config.h
Kernel/platform-z80pack/fuzix.lnk
Kernel/syscall_net.c

index 31a93bf..de447e7 100644 (file)
@@ -84,7 +84,11 @@ extern struct runload loadavg[];
 
 // the system call dispatch table
 #ifdef CONFIG_LEVEL_2
+#ifdef CONFIG_NET
+#define FUZIX_SYSCALL_COUNT 98
+#else
 #define FUZIX_SYSCALL_COUNT 80
+#endif
 #else
 #define FUZIX_SYSCALL_COUNT 66
 #endif
index fb83084..1e55707 100644 (file)
@@ -21,7 +21,32 @@ struct sockaddr_in {
   uint8_t sin_zero[8];
 };
 
+/* This one is used internally to deal with many argumented net
+   functions */
+struct sockio {
+  uint16_t sio_flags;          /* Keep the order so we can use partial */
+  uint16_t sio_addr_len;       /* structs for simple cases */
+  struct sockaddr_in sio_addr;
+};
+
 #define INADDR_ANY             0L
 #define INADDR_BROADCAST       0xFFFFFFFFUL
 #define INADDR_LOOPBACK                0x7F000001UL
 #define IN_LOOPBACK(a)         (((a) >> 24) == 0x7F)
+
+/* Network layer syscalls */
+extern arg_t _socket(void);
+extern arg_t _listen(void);
+extern arg_t _bind(void);
+extern arg_t _connect(void);
+extern arg_t _accept(void);
+extern arg_t _getsockaddrs(void);
+extern arg_t _sendto(void);
+extern arg_t _recvfrom(void);
+
+/* Hooks for inode.c into the networking */
+extern void sock_close(inoptr ino);
+extern int netd_sock_read(inoptr ino, uint8_t flag);
+extern int is_netd(void);
+extern int sock_write(inoptr ino, uint8_t flag);
+extern bool issocket(inoptr ino);
index 8cd74fb..58c8040 100644 (file)
@@ -1,4 +1,4 @@
-#define NR_SYSCALL 80
+#define NR_SYSCALL 98
 
 #define VARARGS        -1
 
@@ -83,6 +83,24 @@ char *syscall_name[NR_SYSCALL] = {
        "setpgid",
        "setsid",
        "getsid",
+       "_nosys80",
+       "_nosys81",
+       "_nosys82",
+       "_nosys83",
+       "_nosys84",
+       "_nosys85",
+       "_nosys86",
+       "_nosys87",
+       "_nosys88",
+       "_nosys89",
+       "socket",
+       "listen",
+       "_bind",
+       "_connect",
+       "_accept",
+       "_getsockaddrs",
+       "_sendto",
+       "_recvfrom"
 };
 
 int syscall_args[NR_SYSCALL] = {
index efc22ff..db21fc1 100644 (file)
@@ -2,6 +2,7 @@
 #include <kdata.h>
 #include <printf.h>
 #include <tty.h>
+#include <netdev.h>
 
 #if defined(CONFIG_LARGE_IO_DIRECT)
 #define read_direct(flag)              (!udata.u_sysio)
@@ -37,8 +38,10 @@ void readi(inoptr ino, uint8_t flag)
 
         case F_SOCK:
 #ifdef CONFIG_NET
-                if (is_netd())
-                        return netd_sock_read(ino, flag);
+                if (is_netd()) {
+                        udata.u_count = netd_sock_read(ino, flag);
+                        return;
+                }
 #endif
        case F_PIPE:
                ispipe = true;
index 9cfdb30..44ca367 100644 (file)
@@ -1,6 +1,7 @@
 #include <kernel.h>
 #include <version.h>
 #include <kdata.h>
+#include <netdev.h>
 
 p_tab *init_process;
 unsigned char *cmdline = (unsigned char *) CMDLINE;
@@ -116,5 +117,25 @@ const syscall_t syscall_dispatch[FUZIX_SYSCALL_COUNT] = {
        _setpgid,               /* FUZIX system call 77 */
        _setsid,                /* FUZIX system call 78 */
        _getsid,                /* FUZIX system call 79 */
+       _nosys,                 /* 80-89 reserved */
+       _nosys,
+       _nosys,
+       _nosys,
+       _nosys,
+       _nosys,
+       _nosys,
+       _nosys,
+       _nosys,
+       _nosys,
+#if defined(CONFIG_NET)                /* For now require L2 */
+       _socket,                /* FUZIX system call 90 */
+       _listen,                /* FUZIX system call 91 */
+       _bind,                  /* FUZIX system call 92 */
+       _connect,               /* FUZIX system call 93 */
+       _accept,                /* FUZIX system call 94 */
+       _getsockaddrs,          /* FUZIX system call 95 */
+       _sendto,                /* FUZIX system call 96 */
+       _recvfrom,              /* FUZIX system call 97 */
+#endif
 #endif
 };
index d952e86..521e06d 100644 (file)
@@ -19,6 +19,8 @@
 #define MAP_SIZE       0xF000U
 /* Level 2 feature set */
 #define CONFIG_LEVEL_2
+/* Networking (not usable yet but for debug/development) */
+#define CONFIG_NET
 
 /* Banks as reported to user space */
 #define CONFIG_BANKS   1
index bd950cb..f27812e 100644 (file)
@@ -38,5 +38,6 @@ platform-z80pack/devtty.rel
 platform-z80pack/devrtc.rel
 level2.rel
 syscall_level2.rel
+syscall_net.rel
 select.rel
 -e
index dc6079d..7e9181c 100644 (file)
@@ -2,9 +2,11 @@
 #include <kdata.h>
 #include <netdev.h>
 
-#ifndef CONFIG_NET
+#ifdef CONFIG_NET
 
+#ifndef NSOCKET
 #define NSOCKET 8
+#endif
 
 
 struct sockaddrs {
@@ -17,14 +19,17 @@ struct socket
        inoptr s_inode;
        uint8_t s_type;
        uint8_t s_error;
+
        uint8_t s_state;
-#define SS_UNUSED              0
-#define SS_UNCONNECTED         1
-#define SS_BOUND               2
-#define SS_LISTENING           3
-#define SS_CONNECTING          4
-#define SS_CONNECTED           5
-#define SS_ACCEPTWAIT          6
+#define SS_UNUSED              0       /* Free slot */
+#define SS_UNCONNECTED         1       /* Created */
+#define SS_BOUND               2       /* Bind or autobind */
+#define SS_LISTENING           3       /* Listen called */
+#define SS_CONNECTING          4       /* Connect initiated */
+#define SS_CONNECTED           5       /* Connect has completed */
+#define SS_ACCEPTWAIT          6       /* Waiting for accept to harvest */
+#define SS_CLOSED              7       /* Protocol layers done, not close()d */
+       /* FIXME: need state for shutdown handling */
        uint8_t s_data;
        struct sockaddrs s_addr[3];
 #define SADDR_SRC      0
@@ -38,13 +43,70 @@ struct socket sockets[NSOCKET];
 uint32_t our_address;
 static uint16_t nextauto = 5000;
 
-static int is_socket(inoptr ino)
+bool issocket(inoptr ino)
 {
        if ((ino->c_node.i_mode & F_MASK) == F_SOCK)
                return 1;
        return 0;
 }
 
+int is_netd(void)
+{
+       return 0;
+}
+
+int sock_write(inoptr ino, uint8_t flag)
+{
+       struct socket *s = &sockets[ino->c_node.i_nlink];
+       used(flag);
+
+       if (s->s_state != SS_CONNECTED) {
+               /* FIXME: handle shutdown states properly */
+               if (s->s_state == SS_CLOSED) {
+                       ssig(udata.u_ptab, SIGPIPE);
+                       udata.u_error = EPIPE;
+               } else
+                       udata.u_error = EINVAL;
+               return -1;
+       }
+       /* For now */
+       udata.u_error = EINVAL;
+       return -1;
+}
+
+int netd_sock_read(inoptr ino, uint8_t flag)
+{
+       used(ino);
+       used(flag);
+
+       udata.u_error = EINVAL;
+       return -1;
+}
+
+/* Wait to leave a state. This will eventually need interrupt locking etc */
+static int sock_wait_leave(struct socket *s, uint8_t flag, uint8_t state)
+{
+       do {
+               /* FIXME: return EINPROGRESS not EINTR for SS_CONNECTING */
+               if (psleep_flags(s, flag))
+                       return -1;
+               /* Protocol state check */
+       } while (s->s_state == state);
+       return 0;
+}
+
+/* Wait to enter a state. This will eventually need interrupt locking etc */
+static int sock_wait_enter(struct socket *s, uint8_t flag, uint8_t state)
+{
+       do {
+               /* FIXME: return EINPROGRESS not EINTR for SS_CONNECTING */
+               if (psleep_flags(s, flag))
+                       return -1;
+               /* Protocol state check */
+       } while (s->s_state == state);
+       return 0;
+}
+
 static int8_t alloc_socket(void)
 {
        struct socket *s = sockets;
@@ -56,13 +118,22 @@ static int8_t alloc_socket(void)
        return -1;
 }
 
+void sock_close(inoptr ino)
+{
+       /* For the moment */
+       struct socket *s = &sockets[ino->c_node.i_nlink];
+       sock_wait_enter(s, 0, SS_CLOSED);
+       sockets[ino->c_node.i_nlink].s_state = SS_UNUSED;
+}
+
+
 static struct socket *sock_get(int fd, uint8_t *flag)
 {
        struct oft *oftp;
        inoptr ino = getinode(fd);
        if (ino == NULLINODE)
                return NULL;
-       if (!is_socket(ino)) {
+       if (!issocket(ino)) {
                udata.u_error = EINVAL;
                return NULL;
        }
@@ -237,7 +308,7 @@ nooft:
 }
 
 /*******************************************
-socket (af, type, pf)           Function ??
+socket (af, type, pf)            Function 90
 uint16_t af;
 uint16_t type;
 uint16_t pf;
@@ -267,7 +338,7 @@ arg_t _socket(void)
 #undef pf
 
 /*******************************************
-listen(fd, qlen)           Function ??
+listen(fd, qlen)                 Function 91
 int fd;
 int qlen;
 ********************************************/
@@ -294,9 +365,10 @@ arg_t _listen(void)
 #undef qlen
 
 /*******************************************
-bind(fd, addr)           Function ??
+bind(fd, addr, len)              Function 92
 int fd;
 struct sockaddr_*in addr;
+int length;            Unused for now
 ********************************************/
 #define fd   (int16_t)udata.u_argn
 #define uaddr (struct sockaddr_in *)udata.u_argn1
@@ -326,9 +398,10 @@ arg_t _bind(void)
 #undef uaddr
 
 /*******************************************
-connect(fd, addr)           Function ??
+connect(fd, addr, len)           Function 93
 int fd;
 struct sockaddr_*in addr;
+int length;            Unused for now
 ********************************************/
 #define fd   (int16_t)udata.u_argn
 #define uaddr (struct sockaddr_in *)udata.u_argn1
@@ -356,12 +429,9 @@ arg_t _connect(void)
                /* Protocol op to kick off */
        }
 
-       do {
-               /* FIXME: return EINPROGRESS not EINTR for SS_CONNECTING */
-               if (psleep_flags(s, flag))
-                       return -1;
-               /* Protocol state check */
-       } while (s->s_state == SS_CONNECTING);
+       if (sock_wait_leave(s, 0, SS_CONNECTING))
+               return -1;
+       /* FIXME: return EINPROGRESS not EINTR for SS_CONNECTING */
        return sock_error(s);
 }
 
@@ -369,7 +439,7 @@ arg_t _connect(void)
 #undef uaddr
 
 /*******************************************
-accept(fd, addr)           Function ??
+accept(fd, addr)                 Function 94
 int fd;
 struct sockaddr_*in addr;
 ********************************************/
@@ -390,6 +460,7 @@ arg_t _accept(void)
                return -1;
        }
        
+       /* Needs locking versus interrupts */
        while ((n = sock_pending(s)) != -1) {
                if (psleep_flags(s, flag))
                        return -1;
@@ -405,7 +476,7 @@ arg_t _accept(void)
 #undef fd
 
 /*******************************************
-getsockaddrs(fd, addr)           Function ??
+getsockaddrs(fd, addr)           Function 95
 int fd;
 struct sockaddr_*in addr;
 ********************************************/
@@ -433,31 +504,36 @@ arg_t _getsockaddrs(void)
 /* FIXME: do we need the extra arg/flags or can we fake it in user */
 
 /*******************************************
-sendto(fd, buf, len, addr, flags)           Function ??
+sendto(fd, buf, len, addr)       Function 96
 int fd;
 char *buf;
 susize_t len;
-struct sockaddr_*in addr;
-int flags;
+struct sockio *addr;   control buffer
 ********************************************/
 #define d (int16_t)udata.u_argn
 #define buf (char *)udata.u_argn1
 #define nbytes (susize_t)udata.u_argn2
-#define uaddr (struct sockaddr_in *)udata.u_argn3
-#define flags (uint16_t)udata.u_argn4
+#define uaddr ((struct sockio *)udata.u_argn3)
 
 arg_t _sendto(void)
 {
        struct socket *s = sock_get(d, NULL);
        struct sockaddr_in sin;
+       uint16_t flags;
 
        if (s == NULL)
                return -1;
+
+       flags = ugetw(&uaddr->sio_flags);
+       if (flags) {
+               udata.u_error = EINVAL;
+               return -1;
+       }
        /* Save the address and then just do a 'write' */
        if (s->s_type != SOCKTYPE_TCP) {
                /* Use the address in atmp */
                s->s_flag |= SFLAG_ATMP;
-               if (sa_getremote(uaddr, &sin) == -1)
+               if (sa_getremote(&uaddr->sio_addr, &sin) == -1)
                        return -1;
                s->s_addr[SADDR_TMP].addr = sin.sin_addr.s_addr;
                s->s_addr[SADDR_TMP].port = sin.sin_port;
@@ -469,34 +545,39 @@ arg_t _sendto(void)
 #undef buf
 #undef nbytes
 #undef uaddr
-#undef flags
 
 /*******************************************
-recvfrom(fd, buf, len, addr, flags)           Function ??
+recvfrom(fd, buf, len, addr)     Function 97
 int fd;
 char *buf;
 susize_t len;
-struct sockaddr_*in addr;
-int flags
+struct sockio *addr;    control buffer
 ********************************************/
 #define d (int16_t)udata.u_argn
 #define buf (char *)udata.u_argn1
 #define nbytes (susize_t)udata.u_argn2
-#define uaddr (struct sockaddr_in *)udata.u_argn3
-#define flags (uint16_t)udata.u_argn4
+#define uaddr ((struct sockio *)udata.u_argn3)
 
 arg_t _recvfrom(void)
 {
        struct socket *s = sock_get(d, NULL);
        int ret;
+       uint16_t flags;
 
        /* FIXME: will need _read redone for banked syscalls */
        if (s == NULL)
                return -1;
+
+       flags = ugetw(&uaddr->sio_flags);
+       if (flags) {
+               udata.u_error = EINVAL;
+               return -1;
+       }
+
        ret = _read();
        if (ret < 0)
                return ret;
-       if (sa_put(s, SADDR_TMP, uaddr))
+       if (sa_put(s, SADDR_TMP, &uaddr->sio_addr))
                return -1;
        return ret;
 }
@@ -505,6 +586,5 @@ arg_t _recvfrom(void)
 #undef buf
 #undef nbytes
 #undef uaddr
-#undef flags
 
 #endif