[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] minios: add lwIP 1.3.0 support



minios: add lwIP 1.3.0 support

This is to be applied on top of the POSIX-time patch

only in patch2:
unchanged:
--- a/extras/mini-os/Makefile   Fri Jan 18 16:43:44 2008 +0000
+++ b/extras/mini-os/Makefile   Fri Jan 18 18:18:12 2008 +0000
@@ -47,6 +47,13 @@ EXTRA_INC =
 # This must be before include minios.mk!
 include $(TARGET_ARCH_DIR)/arch.mk
 
+ifneq ($(LWIPDIR),)
+lwip=y
+DEF_CFLAGS += -DHAVE_LWIP
+DEF_CFLAGS += -I$(LWIPDIR)/src/include
+DEF_CFLAGS += -I$(LWIPDIR)/src/include/ipv4
+endif
+
 # Include common mini-os makerules.
 include minios.mk
 
@@ -90,6 +97,24 @@ arch_lib:
 arch_lib:
        $(MAKE) --directory=$(TARGET_ARCH_DIR) || exit 1;
 
+ifeq ($(lwip),y)
+# lwIP library
+LWC    := $(shell find $(LWIPDIR)/ -type f -name '*.c')
+LWC    := $(filter-out %6.c %ip6_addr.c %ethernetif.c, $(LWC))
+LWC    += lwip-arch.c lwip-net.c
+LWO    := $(patsubst %.c,%.o,$(LWC))
+
+lwip.a: $(LWO)
+       $(RM) $@
+       $(AR) cqs $@ $^
+
+OBJS += lwip.a
+
+OBJS := $(filter-out $(LWO), $(OBJS))
+else
+OBJS := $(filter-out daytime.o lwip%.o, $(OBJS))
+endif
+
 $(TARGET): links $(OBJS) arch_lib
        $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJS) $(LDARCHLIB) -o $@.o
        $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o
@@ -107,6 +132,7 @@ clean:      arch_clean
        done
        rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz
        find . -type l | xargs rm -f
+       $(RM) lwip.a $(LWO)
        rm -f tags TAGS
 
 
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/daytime.c  Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,64 @@
+/* 
+ * daytime.c: a simple network service based on lwIP and mini-os
+ * 
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ */
+
+#include <os.h>
+#include <xmalloc.h>
+#include <console.h>
+#include <netfront.h>
+#include <lwip/api.h>
+
+static char message[29];
+
+void run_server(void *p)
+{
+    struct ip_addr listenaddr = { 0 };
+    struct ip_addr ipaddr = { htonl(0x0a000001) };
+    struct ip_addr netmask = { htonl(0xff000000) };
+    struct ip_addr gw = { 0 };
+    struct netconn *listener;
+    struct netconn *session;
+    struct timeval tv;
+    err_t rc;
+
+    start_networking();
+    networking_set_addr(&ipaddr, &netmask, &gw);
+
+    tprintk("Opening connection\n");
+
+    listener = netconn_new(NETCONN_TCP);
+    tprintk("Connection at %p\n", listener);
+
+    rc = netconn_bind(listener, &listenaddr, 13);
+    if (rc != ERR_OK) {
+        tprintk("Failed to bind connection: %i\n", rc);
+        return;
+    }
+
+    rc = netconn_listen(listener);
+    if (rc != ERR_OK) {
+        tprintk("Failed to listen on connection: %i\n", rc);
+        return;
+    }
+
+    while (1) {
+        session = netconn_accept(listener);
+        if (session == NULL) 
+            continue;
+
+        gettimeofday(&tv, NULL);
+        sprintf(message, "%20lu.%6.6lu\n", tv.tv_sec, tv.tv_usec);
+        (void) netconn_write(session, message, strlen(message), NETCONN_COPY);
+        (void) netconn_disconnect(session);
+        (void) netconn_delete(session);
+    }
+}
+
+
+int app_main(start_info_t *si)
+{
+    create_thread("server", run_server, NULL);
+    return 0;
+}
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/arch/cc.h  Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,83 @@
+/* 
+ * lwip/arch/cc.h
+ *
+ * Compiler-specific types and macros for lwIP running on mini-os 
+ *
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ */
+
+#ifndef __LWIP_ARCH_CC_H__
+#define __LWIP_ARCH_CC_H__
+
+/*   Typedefs for the types used by lwip - */
+#include <os.h>
+#include <types.h>
+#include <time.h>
+typedef  u8  u8_t;
+typedef  s8  s8_t;
+typedef u16 u16_t;
+typedef s16 s16_t;
+typedef u32 u32_t;
+typedef s32 s32_t;
+typedef u64 u64_t;
+typedef s64 s64_t;
+typedef uintptr_t mem_ptr_t;
+
+typedef u16 u_short;
+
+/*   Compiler hints for packing lwip's structures - */
+#define PACK_STRUCT_FIELD(_x)  _x
+#define PACK_STRUCT_STRUCT     __attribute__ ((packed))
+#define PACK_STRUCT_BEGIN 
+#define PACK_STRUCT_END
+
+/*   Platform specific diagnostic output - */
+
+extern void lwip_printk(char *fmt, ...);
+#define LWIP_PLATFORM_DIAG(_x) do { lwip_printk _x ; } while (0)
+
+extern void lwip_die(char *fmt, ...);
+#define LWIP_PLATFORM_ASSERT(_x) do { lwip_die(_x); } while(0)
+
+/*   "lightweight" synchronization mechanisms - */
+/*     SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. */
+/*     SYS_ARCH_PROTECT(x)      - enter protection mode. */
+/*     SYS_ARCH_UNPROTECT(x)    - leave protection mode. */
+
+/*   If the compiler does not provide memset() this file must include a */
+/*   definition of it, or include a file which defines it. */
+#include <lib.h>
+
+/*   This file must either include a system-local <errno.h> which defines */
+/*   the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO */
+/*   to make lwip/arch.h define the codes which are used throughout. */
+#include <errno.h>
+
+/*   Not required by the docs, but needed for network-order calculations */
+#include <endian.h>
+
+#include <inttypes.h>
+#define S16_F PRIi16
+#define U16_F PRIu16
+#define X16_F PRIx16
+#define S32_F PRIi32
+#define U32_F PRIu32
+#define X32_F PRIx32
+
+#if 0
+#ifndef DBG_ON
+#define DBG_ON LWIP_DBG_ON
+#endif
+#define LWIP_DEBUG     DBG_ON
+//#define IP_DEBUG     DBG_ON
+#define TCP_DEBUG      DBG_ON
+#define TCP_INPUT_DEBUG        DBG_ON
+#define TCP_QLEN_DEBUG DBG_ON
+#define TCPIP_DEBUG    DBG_ON
+#define DBG_TYPES_ON   DBG_ON
+#endif
+
+/* TODO: checksum doesn't work fine?! */
+#define CHECKSUM_CHECK_TCP     0
+
+#endif /* __LWIP_ARCH_CC_H__ */
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/arch/perf.h        Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,15 @@
+/* 
+ * lwip/arch/perf.h
+ *
+ * Arch-specific performance measurement for lwIP running on mini-os 
+ *
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ */
+
+#ifndef __LWIP_ARCH_PERF_H__
+#define __LWIP_ARCH_PERF_H__
+
+#define PERF_START    do { } while(0)
+#define PERF_STOP(_x) do { (void)(_x); } while (0)
+
+#endif /* __LWIP_ARCH_PERF_H__ */
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/arch/sys_arch.h    Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,35 @@
+/* 
+ * lwip/arch/sys_arch.h
+ *
+ * Arch-specific semaphores and mailboxes for lwIP running on mini-os 
+ *
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ */
+
+#ifndef __LWIP_ARCH_SYS_ARCH_H__
+#define __LWIP_ARCH_SYS_ARCH_H__
+
+#include <os.h>
+#include <xmalloc.h>
+#include <semaphore.h>
+
+typedef struct semaphore *sys_sem_t;
+#define SYS_SEM_NULL ((sys_sem_t) NULL)
+
+struct mbox {
+    int count;
+    void **messages;
+    struct semaphore read_sem;
+    struct semaphore write_sem;
+    int writer;
+    int reader;
+};
+
+typedef struct mbox *sys_mbox_t;
+#define SYS_MBOX_NULL ((sys_mbox_t) 0)
+
+typedef struct thread *sys_thread_t;
+
+typedef unsigned long sys_prot_t;
+
+#endif /*__LWIP_ARCH_SYS_ARCH_H__ */
only in patch2:
unchanged:
--- a/extras/mini-os/include/console.h  Fri Jan 18 16:43:44 2008 +0000
+++ b/extras/mini-os/include/console.h  Fri Jan 18 18:18:12 2008 +0000
@@ -38,8 +38,11 @@
 
 #include<traps.h>
 
+void print(int direct, const char *fmt, va_list args);
 void printk(const char *fmt, ...);
 void xprintk(const char *fmt, ...);
+
+#define tprintk(_fmt, _args...) printk("[%s] " _fmt, current->name, ##_args) 
 
 void xencons_rx(char *buf, unsigned len, struct pt_regs *regs);
 void xencons_tx(void);
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/lwipopts.h Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,22 @@
+/*
+ * lwipopts.h
+ *
+ * Configuration for lwIP running on mini-os 
+ *
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ */
+
+#ifndef __LWIP_LWIPOPTS_H__
+#define __LWIP_LWIPOPTS_H__
+
+#define SYS_LIGHTWEIGHT_PROT 1
+#define MEM_LIBC_MALLOC 1
+#define LWIP_TIMEVAL_PRIVATE 0
+#define LWIP_DHCP 1
+#define LWIP_COMPAT_SOCKETS 0
+#define LWIP_IGMP 1
+#define MEMP_NUM_SYS_TIMEOUT 10
+#define TCP_SND_BUF 3000
+#define TCP_MSS 1500
+
+#endif /* __LWIP_LWIPOPTS_H__ */
only in patch2:
unchanged:
--- a/extras/mini-os/include/netfront.h Fri Jan 18 16:43:44 2008 +0000
+++ b/extras/mini-os/include/netfront.h Fri Jan 18 18:18:12 2008 +0000
@@ -1,7 +1,19 @@
 #include <wait.h>
+#ifdef HAVE_LWIP
+#include <lwip/netif.h>
+#endif
 struct netfront_dev;
 struct netfront_dev *init_netfront(char *nodename, void (*netif_rx)(unsigned 
char *data, int len), unsigned char rawmac[6]);
 void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len);
 void shutdown_netfront(struct netfront_dev *dev);
 
 extern struct wait_queue_head netfront_queue;
+
+#ifdef HAVE_LWIP
+/* Call this to bring up the netfront interface and the lwIP stack.
+ * N.B. _must_ be called from a thread; it's not safe to call this from 
+ * app_main(). */
+void start_networking(void);
+
+void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, 
struct ip_addr *gw);
+#endif
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/lwip-arch.c        Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,293 @@
+/* 
+ * lwip-arch.c
+ *
+ * Arch-specific semaphores and mailboxes for lwIP running on mini-os 
+ *
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ */
+
+#include <os.h>
+#include <time.h>
+#include <console.h>
+#include <xmalloc.h>
+#include <lwip/sys.h>
+#include <stdarg.h>
+
+/* Is called to initialize the sys_arch layer */
+void sys_init(void)
+{
+}
+
+/* Creates and returns a new semaphore. The "count" argument specifies
+ * the initial state of the semaphore. */
+sys_sem_t sys_sem_new(u8_t count)
+{
+    struct semaphore *sem = xmalloc(struct semaphore);
+    sem->count = count;
+    init_waitqueue_head(&sem->wait);
+    return sem;
+}
+
+/* Deallocates a semaphore. */
+void sys_sem_free(sys_sem_t sem)
+{
+    xfree(sem);
+}
+
+/* Signals a semaphore. */
+void sys_sem_signal(sys_sem_t sem)
+{
+    up(sem);
+}
+
+/* Blocks the thread while waiting for the semaphore to be
+ * signaled. If the "timeout" argument is non-zero, the thread should
+ * only be blocked for the specified time (measured in
+ * milliseconds).
+ * 
+ * If the timeout argument is non-zero, the return value is the number of
+ * milliseconds spent waiting for the semaphore to be signaled. If the
+ * semaphore wasn't signaled within the specified time, the return value is
+ * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
+ * (i.e., it was already signaled), the function may return zero. */
+u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
+{
+    /* Slightly more complicated than the normal minios semaphore:
+     * need to wake on timeout *or* signal */
+    sys_prot_t prot;
+    s64_t then = NOW();
+    s64_t deadline;
+
+    if (timeout == 0)
+       deadline = 0;
+    else
+       deadline = then + MILLISECS(timeout);
+
+    while(1) {
+        wait_event_deadline(sem->wait, (sem->count > 0), deadline);
+
+        prot = sys_arch_protect();
+       /* Atomically check that we can proceed */
+       if (sem->count > 0 || (deadline && NOW() >= deadline))
+           break;
+        sys_arch_unprotect(prot);
+    }
+
+    if (sem->count > 0) {
+        sem->count--;
+        sys_arch_unprotect(prot);
+        return NSEC_TO_MSEC(NOW() - then); 
+    }
+    
+    sys_arch_unprotect(prot);
+    return SYS_ARCH_TIMEOUT;
+}
+
+/* Creates an empty mailbox. */
+sys_mbox_t sys_mbox_new(int size)
+{
+    struct mbox *mbox = xmalloc(struct mbox);
+    if (!size)
+        size = 32;
+    else if (size == 1)
+        size = 2;
+    mbox->count = size;
+    mbox->messages = xmalloc_array(void*, size);
+    init_SEMAPHORE(&mbox->read_sem, 0);
+    mbox->reader = 0;
+    init_SEMAPHORE(&mbox->write_sem, size);
+    mbox->writer = 0;
+    return mbox;
+}
+
+/* Deallocates a mailbox. If there are messages still present in the
+ * mailbox when the mailbox is deallocated, it is an indication of a
+ * programming error in lwIP and the developer should be notified. */
+void sys_mbox_free(sys_mbox_t mbox)
+{
+    ASSERT(mbox->reader == mbox->writer);
+    xfree(mbox->messages);
+    xfree(mbox);
+}
+
+/* Posts the "msg" to the mailbox, internal version that actually does the
+ * post. */
+static void do_mbox_post(sys_mbox_t mbox, void *msg)
+{
+    /* The caller got a semaphore token, so we are now allowed to increment
+     * writer, but we still need to prevent concurrency between writers
+     * (interrupt handler vs main) */
+    sys_prot_t prot = sys_arch_protect();
+    mbox->messages[mbox->writer] = msg;
+    mbox->writer = (mbox->writer + 1) % mbox->count;
+    ASSERT(mbox->reader != mbox->writer);
+    sys_arch_unprotect(prot);
+    up(&mbox->read_sem);
+}
+
+/* Posts the "msg" to the mailbox. */
+void sys_mbox_post(sys_mbox_t mbox, void *msg)
+{
+    if (mbox == SYS_MBOX_NULL)
+        return;
+    down(&mbox->write_sem);
+    do_mbox_post(mbox, msg);
+}
+
+/* Try to post the "msg" to the mailbox. */
+err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg)
+{
+    if (mbox == SYS_MBOX_NULL)
+        return ERR_BUF;
+    if (!trydown(&mbox->write_sem))
+        return ERR_MEM;
+    do_mbox_post(mbox, msg);
+    return ERR_OK;
+}
+
+/*
+ * Fetch a message from a mailbox. Internal version that actually does the
+ * fetch.
+ */
+static void do_mbox_fetch(sys_mbox_t mbox, void **msg)
+{
+    sys_prot_t prot;
+    /* The caller got a semaphore token, so we are now allowed to increment
+     * reader, but we may still need to prevent concurrency between readers.
+     * FIXME: can there be concurrent readers? */
+    prot = sys_arch_protect();
+    ASSERT(mbox->reader != mbox->writer);
+    if (msg != NULL)
+        *msg = mbox->messages[mbox->reader];
+    mbox->reader = (mbox->reader + 1) % mbox->count;
+    sys_arch_unprotect(prot);
+    up(&mbox->write_sem);
+}
+
+/* Blocks the thread until a message arrives in the mailbox, but does
+ * not block the thread longer than "timeout" milliseconds (similar to
+ * the sys_arch_sem_wait() function). The "msg" argument is a result
+ * parameter that is set by the function (i.e., by doing "*msg =
+ * ptr"). The "msg" parameter maybe NULL to indicate that the message
+ * should be dropped.
+ *
+ * The return values are the same as for the sys_arch_sem_wait() function:
+ * Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
+ * timeout. */
+u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
+{
+    u32 rv;
+    if (mbox == SYS_MBOX_NULL)
+        return SYS_ARCH_TIMEOUT;
+
+    rv = sys_arch_sem_wait(&mbox->read_sem, timeout);
+    if ( rv == SYS_ARCH_TIMEOUT )
+        return rv;
+
+    do_mbox_fetch(mbox, msg);
+    return 0;
+}
+
+/* This is similar to sys_arch_mbox_fetch, however if a message is not
+ * present in the mailbox, it immediately returns with the code
+ * SYS_MBOX_EMPTY. On success 0 is returned.
+ *
+ * To allow for efficient implementations, this can be defined as a
+ * function-like macro in sys_arch.h instead of a normal function. For
+ * example, a naive implementation could be:
+ *   #define sys_arch_mbox_tryfetch(mbox,msg) \
+ *     sys_arch_mbox_fetch(mbox,msg,1)
+ * although this would introduce unnecessary delays. */
+
+u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg) {
+    if (mbox == SYS_MBOX_NULL)
+        return SYS_ARCH_TIMEOUT;
+
+    if (!trydown(&mbox->read_sem))
+       return SYS_MBOX_EMPTY;
+
+    do_mbox_fetch(mbox, msg);
+    return 0;
+}
+
+
+/* Returns a pointer to the per-thread sys_timeouts structure. In lwIP,
+ * each thread has a list of timeouts which is repressented as a linked
+ * list of sys_timeout structures. The sys_timeouts structure holds a
+ * pointer to a linked list of timeouts. This function is called by
+ * the lwIP timeout scheduler and must not return a NULL value. 
+ *
+ * In a single threadd sys_arch implementation, this function will
+ * simply return a pointer to a global sys_timeouts variable stored in
+ * the sys_arch module. */
+struct sys_timeouts *sys_arch_timeouts(void) 
+{
+    static struct sys_timeouts timeout;
+    return &timeout;
+}
+
+
+/* Starts a new thread with priority "prio" that will begin its execution in 
the
+ * function "thread()". The "arg" argument will be passed as an argument to the
+ * thread() function. The id of the new thread is returned. Both the id and
+ * the priority are system dependent. */
+static struct thread *lwip_thread;
+sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, 
int stacksize, int prio)
+{
+    struct thread *t;
+    if (stacksize > STACK_SIZE) {
+       printk("Can't start lwIP thread: stack size %d is too large for our 
%d\n", stacksize, STACK_SIZE);
+       do_exit();
+    }
+    lwip_thread = t = create_thread(name, thread, arg);
+    return t;
+}
+
+/* This optional function does a "fast" critical region protection and returns
+ * the previous protection level. This function is only called during very 
short
+ * critical regions. An embedded system which supports ISR-based drivers might
+ * want to implement this function by disabling interrupts. Task-based systems
+ * might want to implement this by using a mutex or disabling tasking. This
+ * function should support recursive calls from the same task or interrupt. In
+ * other words, sys_arch_protect() could be called while already protected. In
+ * that case the return value indicates that it is already protected.
+ *
+ * sys_arch_protect() is only required if your port is supporting an operating
+ * system. */
+sys_prot_t sys_arch_protect(void)
+{
+    unsigned long flags;
+    local_irq_save(flags);
+    return flags;
+}
+
+/* This optional function does a "fast" set of critical region protection to 
the
+ * value specified by pval. See the documentation for sys_arch_protect() for
+ * more information. This function is only required if your port is supporting
+ * an operating system. */
+void sys_arch_unprotect(sys_prot_t pval)
+{
+    local_irq_restore(pval);
+}
+
+/* non-fatal, print a message. */
+void lwip_printk(char *fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    printk("lwIP: ");
+    print(0, fmt, args);
+    va_end(args);
+}
+
+/* fatal, print message and abandon execution. */
+void lwip_die(char *fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    printk("lwIP assertion failed: ");
+    print(0, fmt, args);
+    va_end(args);
+    printk("\n");
+    BUG();
+}
only in patch2:
unchanged:
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/lwip-net.c Fri Jan 18 18:18:12 2008 +0000
@@ -0,0 +1,360 @@
+/* 
+ * lwip-net.c
+ *
+ * interface between lwIP's ethernet and Mini-os's netfront.
+ * For now, support only one network interface, as mini-os does.
+ *
+ * Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>, July 2007
+ * based on lwIP's ethernetif.c skeleton file, copyrights as below.
+ */
+
+
+/*
+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
+ * All rights reserved. 
+ * 
+ * Redistribution and use in source and binary forms, with or without 
modification, 
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 
IMPLIED 
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 
EVENT 
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
PROCUREMENT 
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
ARISING 
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
POSSIBILITY 
+ * OF SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ * 
+ * Author: Adam Dunkels <adam@xxxxxxx>
+ *
+ */
+
+#include <os.h>
+
+#include "lwip/opt.h"
+#include "lwip/def.h"
+#include "lwip/mem.h"
+#include "lwip/pbuf.h"
+#include "lwip/sys.h"
+
+#include <lwip/stats.h>
+#include <lwip/sys.h>
+#include <lwip/mem.h>
+#include <lwip/memp.h>
+#include <lwip/pbuf.h>
+#include <netif/etharp.h>
+#include <lwip/tcpip.h>
+#include <lwip/tcp.h>
+#include <lwip/netif.h>
+#include <lwip/dhcp.h>
+
+#include "netif/etharp.h"
+
+#include <netfront.h>
+
+/* Define those to better describe your network interface. */
+#define IFNAME0 'e'
+#define IFNAME1 'n'
+
+#define IF_IPADDR      0x00000000
+#define IF_NETMASK     0x00000000
+
+/* Only have one network interface at a time. */
+static struct netif *the_interface = NULL;
+
+static unsigned char rawmac[6];
+static struct netfront_dev *dev;
+
+/* Forward declarations. */
+static err_t netfront_output(struct netif *netif, struct pbuf *p,
+             struct ip_addr *ipaddr);
+
+/*
+ * low_level_output():
+ *
+ * Should do the actual transmission of the packet. The packet is
+ * contained in the pbuf that is passed to the function. This pbuf
+ * might be chained.
+ *
+ */
+
+static err_t
+low_level_output(struct netif *netif, struct pbuf *p)
+{
+#ifdef ETH_PAD_SIZE
+  pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
+#endif
+
+  /* Send the data from the pbuf to the interface, one pbuf at a
+     time. The size of the data in each pbuf is kept in the ->len
+     variable. */
+  if (!p->next) {
+    /* Only one fragment, can send it directly */
+      netfront_xmit(dev, p->payload, p->len);
+  } else {
+    unsigned char data[p->tot_len], *cur;
+    struct pbuf *q;
+
+    for(q = p, cur = data; q != NULL; cur += q->len, q = q->next)
+      memcpy(cur, q->payload, q->len);
+    netfront_xmit(dev, data, p->tot_len);
+  }
+
+#if ETH_PAD_SIZE
+  pbuf_header(p, ETH_PAD_SIZE);                        /* reclaim the padding 
word */
+#endif
+  
+  LINK_STATS_INC(link.xmit);
+
+  return ERR_OK;
+}
+
+
+
+/*
+ * netfront_output():
+ *
+ * This function is called by the TCP/IP stack when an IP packet
+ * should be sent. It calls the function called low_level_output() to
+ * do the actual transmission of the packet.
+ *
+ */
+
+static err_t
+netfront_output(struct netif *netif, struct pbuf *p,
+      struct ip_addr *ipaddr)
+{
+  
+ /* resolve hardware address, then send (or queue) packet */
+  return etharp_output(netif, p, ipaddr);
+ 
+}
+
+/*
+ * netfront_input():
+ *
+ * This function should be called when a packet is ready to be read
+ * from the interface. 
+ *
+ */
+
+static void
+netfront_input(struct netif *netif, unsigned char* data, int len)
+{
+  struct eth_hdr *ethhdr;
+  struct pbuf *p, *q;
+
+#if ETH_PAD_SIZE
+  len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
+#endif
+  
+  /* move received packet into a new pbuf */
+  p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
+  if (p == NULL) {
+    LINK_STATS_INC(link.memerr);
+    LINK_STATS_INC(link.drop);
+    return;
+  }
+
+#if ETH_PAD_SIZE
+  pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
+#endif
+  
+  /* We iterate over the pbuf chain until we have read the entire
+   * packet into the pbuf. */
+  for(q = p; q != NULL && len > 0; q = q->next) {
+    /* Read enough bytes to fill this pbuf in the chain. The
+     * available data in the pbuf is given by the q->len
+     * variable. */
+    memcpy(q->payload, data, len < q->len ? len : q->len);
+    data += q->len;
+    len -= q->len;
+  }
+
+#if ETH_PAD_SIZE
+  pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
+#endif
+
+  LINK_STATS_INC(link.recv);
+
+  /* points to packet payload, which starts with an Ethernet header */
+  ethhdr = p->payload;
+
+  ethhdr = p->payload;
+    
+  switch (htons(ethhdr->type)) {
+  /* IP packet? */
+  case ETHTYPE_IP:
+#if 0
+/* CSi disabled ARP table update on ingress IP packets.
+   This seems to work but needs thorough testing. */
+    /* update ARP table */
+    etharp_ip_input(netif, p);
+#endif
+    /* skip Ethernet header */
+    pbuf_header(p, -(s16)sizeof(struct eth_hdr));
+    /* pass to network layer */
+    tcpip_input(p, netif);
+    break;
+      
+  case ETHTYPE_ARP:
+    /* pass p to ARP module  */
+    etharp_arp_input(netif, (struct eth_addr *) netif->hwaddr, p);
+    break;
+  default:
+    pbuf_free(p);
+    p = NULL;
+    break;
+  }
+}
+
+
+/* 
+ * netif_rx(): overrides the default netif_rx behaviour in the netfront driver.
+ * 
+ * Pull received packets into a pbuf queue for the low_level_input() 
+ * function to pass up to lwIP.
+ */
+
+void netif_rx(unsigned char* data, int len)
+{
+  if (the_interface != NULL) {
+    netfront_input(the_interface, data, len);
+    wake_up(&netfront_queue);
+  }
+  /* By returning, we ack the packet and relinquish the RX ring slot */
+}
+
+/*
+ * Set the IP, mask and gateway of the IF
+ */
+void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, 
struct ip_addr *gw)
+{
+  netif_set_ipaddr(the_interface, ipaddr);
+  netif_set_netmask(the_interface, netmask);
+  netif_set_gw(the_interface, gw);
+}
+
+
+static void
+arp_timer(void *arg)
+{
+  etharp_tmr();
+  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
+}
+
+/*
+ * netif_netfront_init():
+ *
+ * Should be called at the beginning of the program to set up the
+ * network interface. It calls the function low_level_init() to do the
+ * actual setup of the hardware.
+ *
+ */
+
+err_t
+netif_netfront_init(struct netif *netif)
+{
+  unsigned char *mac = netif->state;
+
+#if LWIP_SNMP
+  /* ifType ethernetCsmacd(6) @see RFC1213 */
+  netif->link_type = 6;
+  /* your link speed here */
+  netif->link_speed = ;
+  netif->ts = 0;
+  netif->ifinoctets = 0;
+  netif->ifinucastpkts = 0;
+  netif->ifinnucastpkts = 0;
+  netif->ifindiscards = 0;
+  netif->ifoutoctets = 0;
+  netif->ifoutucastpkts = 0;
+  netif->ifoutnucastpkts = 0;
+  netif->ifoutdiscards = 0;
+#endif
+  
+  netif->name[0] = IFNAME0;
+  netif->name[1] = IFNAME1;
+  netif->output = netfront_output;
+  netif->linkoutput = low_level_output;
+  
+  the_interface = netif;
+  
+  /* set MAC hardware address */
+  netif->hwaddr_len = 6;
+  netif->hwaddr[0] = mac[0];
+  netif->hwaddr[1] = mac[1];
+  netif->hwaddr[2] = mac[2];
+  netif->hwaddr[3] = mac[3];
+  netif->hwaddr[4] = mac[4];
+  netif->hwaddr[5] = mac[5];
+
+  /* No interesting per-interface state */
+  netif->state = NULL;
+
+  /* maximum transfer unit */
+  netif->mtu = 1500;
+  
+  /* broadcast capability */
+  netif->flags = NETIF_FLAG_BROADCAST;
+
+  etharp_init();
+
+  sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
+
+  return ERR_OK;
+}
+
+/*
+ * Thread run by netfront: bring up the IP address and fire lwIP timers.
+ */
+static __DECLARE_SEMAPHORE_GENERIC(tcpip_is_up, 0);
+static void tcpip_bringup_finished(void *p)
+{
+  tprintk("TCP/IP bringup ends.\n");
+  up(&tcpip_is_up);
+}
+
+/* 
+ * Utility function to bring the whole lot up.  Call this from app_main() 
+ * or similar -- it starts netfront and have lwIP start its thread,
+ * which calls back to tcpip_bringup_finished(), which 
+ * lets us know it's OK to continue.
+ */
+void start_networking(void)
+{
+  struct netif *netif;
+  struct ip_addr ipaddr = { htonl(IF_IPADDR) };
+  struct ip_addr netmask = { htonl(IF_NETMASK) };
+  struct ip_addr gw = { 0 };
+
+  tprintk("Waiting for network.\n");
+
+  dev = init_netfront(NULL, NULL, rawmac);
+  
+  tprintk("TCP/IP bringup begins.\n");
+  
+  netif = xmalloc(struct netif);
+  tcpip_init(tcpip_bringup_finished, netif);
+    
+  netif_add(netif, &ipaddr, &netmask, &gw, rawmac, 
+            netif_netfront_init, ip_input);
+  netif_set_default(netif);
+  netif_set_up(netif);
+
+  down(&tcpip_is_up);
+
+  tprintk("Network is ready.\n");
+}
only in patch2:
unchanged:
--- a/extras/mini-os/minios.mk  Fri Jan 18 16:43:44 2008 +0000
+++ b/extras/mini-os/minios.mk  Fri Jan 18 18:18:12 2008 +0000
@@ -6,7 +6,7 @@ debug = y
 
 # Define some default flags.
 # NB. '-Wcast-qual' is nasty, so I omitted it.
-DEF_CFLAGS := -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format
+DEF_CFLAGS += -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format
 DEF_CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
 DEF_CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline
 DEF_CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION)

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.